Renaming and merging hosting extensions. (#5091)

* Rename AddAgentFrameworkHandler to AddFoundryResponses and add MapFoundryResponses

- Rename extension methods: AddAgentFrameworkHandler -> AddFoundryResponses, MapAgentFrameworkHandler -> MapFoundryResponses
- AddFoundryResponses now calls AddResponsesServer() internally
- Add MapFoundryResponses() extension on IEndpointRouteBuilder
- Update sample and tests to use new API names
- Remove redundant AddResponsesServer() and /ready endpoint from sample

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fixing numbering in sample.

---------

Co-authored-by: alliscode <bentho@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Ben Thomas
2026-04-03 16:35:44 -07:00
committed by GitHub
Unverified
parent eb67379033
commit 23db9569ce
3 changed files with 53 additions and 45 deletions
@@ -2,78 +2,93 @@
using System;
using Azure.AI.AgentServer.Responses;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace Microsoft.Agents.AI.Foundry.Hosting;
/// <summary>
/// Extension methods for <see cref="IServiceCollection"/> to register the agent-framework
/// response handler with the Azure AI Responses Server SDK.
/// Extension methods for registering agent-framework agents as Foundry Hosted Agents
/// using the Azure AI Responses Server SDK.
/// </summary>
public static class AgentFrameworkResponsesServiceCollectionExtensions
public static class FoundryHostingExtensions
{
/// <summary>
/// Registers <see cref="AgentFrameworkResponseHandler"/> as the <see cref="ResponseHandler"/>
/// for the Azure AI Responses Server SDK. Agents are resolved from keyed DI services
/// Registers the Azure AI Responses Server SDK and <see cref="AgentFrameworkResponseHandler"/>
/// as the <see cref="ResponseHandler"/>. Agents are resolved from keyed DI services
/// using the <c>agent.name</c> or <c>metadata["entity_id"]</c> from incoming requests.
/// </summary>
/// <remarks>
/// <para>
/// Call this method <b>after</b> <c>AddResponsesServer()</c> and after registering your
/// <see cref="AIAgent"/> instances (e.g., via <c>AddAIAgent()</c>).
/// This method calls <c>AddResponsesServer()</c> internally, so you do not need to
/// call it separately. Register your <see cref="AIAgent"/> instances before calling this.
/// </para>
/// <para>
/// Example:
/// <code>
/// builder.Services.AddResponsesServer();
/// builder.AddAIAgent("my-agent", ...);
/// builder.Services.AddAgentFrameworkHandler();
/// builder.Services.AddFoundryResponses();
///
/// var app = builder.Build();
/// app.MapResponsesServer();
/// app.MapFoundryResponses();
/// </code>
/// </para>
/// </remarks>
/// <param name="services">The service collection.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddAgentFrameworkHandler(this IServiceCollection services)
public static IServiceCollection AddFoundryResponses(this IServiceCollection services)
{
ArgumentNullException.ThrowIfNull(services);
services.AddResponsesServer();
services.TryAddSingleton<ResponseHandler, AgentFrameworkResponseHandler>();
return services;
}
/// <summary>
/// Registers a specific <see cref="AIAgent"/> as the handler for all incoming requests,
/// regardless of the <c>agent.name</c> in the request.
/// Registers the Azure AI Responses Server SDK and a specific <see cref="AIAgent"/>
/// as the handler for all incoming requests, regardless of the <c>agent.name</c> in the request.
/// </summary>
/// <remarks>
/// <para>
/// Use this overload when hosting a single agent. The provided agent instance is
/// registered both as a keyed service and as the default <see cref="AIAgent"/>.
/// registered as both a keyed service and the default <see cref="AIAgent"/>.
/// This method calls <c>AddResponsesServer()</c> internally.
/// </para>
/// <para>
/// Example:
/// <code>
/// builder.Services.AddResponsesServer();
/// builder.Services.AddAgentFrameworkHandler(myAgent);
/// builder.Services.AddFoundryResponses(myAgent);
///
/// var app = builder.Build();
/// app.MapResponsesServer();
/// app.MapFoundryResponses();
/// </code>
/// </para>
/// </remarks>
/// <param name="services">The service collection.</param>
/// <param name="agent">The agent instance to register.</param>
/// <returns>The service collection for chaining.</returns>
public static IServiceCollection AddAgentFrameworkHandler(this IServiceCollection services, AIAgent agent)
public static IServiceCollection AddFoundryResponses(this IServiceCollection services, AIAgent agent)
{
ArgumentNullException.ThrowIfNull(services);
ArgumentNullException.ThrowIfNull(agent);
services.AddResponsesServer();
services.TryAddSingleton(agent);
services.TryAddSingleton<ResponseHandler, AgentFrameworkResponseHandler>();
return services;
}
/// <summary>
/// Maps the Responses API routes for the agent-framework handler to the endpoint routing pipeline.
/// </summary>
/// <param name="endpoints">The endpoint route builder.</param>
/// <param name="prefix">Optional route prefix (e.g., "/openai/v1"). Default: empty (routes at /responses).</param>
/// <returns>The endpoint route builder for chaining.</returns>
public static IEndpointRouteBuilder MapFoundryResponses(this IEndpointRouteBuilder endpoints, string prefix = "")
{
ArgumentNullException.ThrowIfNull(endpoints);
endpoints.MapResponsesServer(prefix);
return endpoints;
}
}