From 1432d0ac312990d3ebb20195b9ace5b859afe73e Mon Sep 17 00:00:00 2001 From: Chris Dai <67849861+chrisdaiii@users.noreply.github.com> Date: Thu, 22 Jan 2026 15:36:40 +0800 Subject: [PATCH] Update AGUIEndpointRouteBuilderExtensions.cs Extend agent dynamic creation support --- .../AGUIEndpointRouteBuilderExtensions.cs | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/dotnet/src/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore/AGUIEndpointRouteBuilderExtensions.cs b/dotnet/src/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore/AGUIEndpointRouteBuilderExtensions.cs index e20d1ab448..52b015eb52 100644 --- a/dotnet/src/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore/AGUIEndpointRouteBuilderExtensions.cs +++ b/dotnet/src/Microsoft.Agents.AI.Hosting.AGUI.AspNetCore/AGUIEndpointRouteBuilderExtensions.cs @@ -80,4 +80,66 @@ public static IEndpointConventionBuilder MapAGUI( return new AGUIServerSentEventsResult(events, sseLogger); }); } + + /// + /// Maps an AG-UI agent endpoint. + /// + /// The endpoint route builder. + /// The URL pattern for the endpoint. + /// The factory that creates agent instance. + /// An for the mapped endpoint. + public static IEndpointConventionBuilder MapAGUI( + this IEndpointRouteBuilder endpoints, + [StringSyntax("route")] string pattern, + Func aiAgentFactory) + { + return endpoints.MapPost(pattern, async ([FromBody] RunAgentInput? input, HttpContext context, CancellationToken cancellationToken) => + { + if (input is null) + { + return Results.BadRequest(); + } + + var jsonOptions = context.RequestServices.GetRequiredService>(); + var jsonSerializerOptions = jsonOptions.Value.SerializerOptions; + + var messages = input.Messages.AsChatMessages(jsonSerializerOptions); + var clientTools = input.Tools?.AsAITools().ToList(); + + // Create run options with AG-UI context in AdditionalProperties + var runOptions = new ChatClientAgentRunOptions + { + ChatOptions = new ChatOptions + { + Tools = clientTools, + AdditionalProperties = new AdditionalPropertiesDictionary + { + ["ag_ui_state"] = input.State, + ["ag_ui_context"] = input.Context?.Select(c => new KeyValuePair(c.Description, c.Value)).ToArray(), + ["ag_ui_forwarded_properties"] = input.ForwardedProperties, + ["ag_ui_thread_id"] = input.ThreadId, + ["ag_ui_run_id"] = input.RunId + } + } + }; + + var aiAgent = aiAgentFactory(context); + + // Run the agent and convert to AG-UI events + var events = aiAgent.RunStreamingAsync( + messages, + options: runOptions, + cancellationToken: cancellationToken) + .AsChatResponseUpdatesAsync() + .FilterServerToolsFromMixedToolInvocationsAsync(clientTools, cancellationToken) + .AsAGUIEventStreamAsync( + input.ThreadId, + input.RunId, + jsonSerializerOptions, + cancellationToken); + + var sseLogger = context.RequestServices.GetRequiredService>(); + return new AGUIServerSentEventsResult(events, sseLogger); + }); + } }