.NET: Features/3768-devui-aspire-integration#3771
.NET: Features/3768-devui-aspire-integration#3771tommasodotNET wants to merge 25 commits intomicrosoft:mainfrom
Conversation
…ommasodotNET/agent-framework into features/3768-devui-aspire-integration
…es for TargetFrameworks support
…pport in DevUIIntegration samples
…torHostedServiceTests
victordibia
left a comment
There was a problem hiding this comment.
Nice work — clean architecture, idiomatic Aspire API. I tested routing with mock backends and found a couple of things worth flagging:
Conversation routing for non-first backends
When a conversation is created on the second backend (e.g., editor-agent) via POST with agent_id context, the routing works perfectly. But when the frontend later does GET /v1/conversations/{id} or GET /v1/conversations/{id}/items to load history, there's no agent_id in the query string and no request body (it's a GET), so the aggregator falls through to the first backend at the backendUrl ??= this.ResolveBackends().Values.FirstOrDefault() fallback in DevUIAggregatorHostedService.cs around line 525. That backend doesn't have the conversation, so it returns a 404.
Suggested fix: An in-memory ConcurrentDictionary<string, string> mapping conversationId → backendPrefix, populated when the aggregator proxies POST /v1/conversations. On subsequent GETs, look up the conversation ID to route to the right backend before falling through to FirstOrDefault(). This avoids rewriting conversation IDs (which flow through responses, items, and checkpoints) and is consistent with the existing InMemoryAgentConversationIndex pattern in the .NET backend. The "lost on restart" trade-off is fine for a dev-only tool.
Default agent naming when agents: is omitted
In AgentFrameworkBuilderExtensions.cs line 175, agents ??= [new AgentEntityInfo(agentService.Resource.Name)] uses the Aspire resource name (e.g., "writer-agent") as the agent ID. But the backend typically registers the agent with a different name (e.g., builder.AddAIAgent("writer", ...)). So the aggregator sends entity_id="writer-agent" but the backend only knows "writer".
The sample works fine because it explicitly passes agents: [new("writer")], but someone following the API without reading the sample might hit this.
Suggested fix: When agents isn't provided, query /v1/entities from the backend at startup instead of defaulting to the resource name. The runtime discovery path already exists in AggregateEntitiesAsync — just reuse that fallback. Alternatively, make agents required so the intent is always explicit.
Minor things (not blocking)
DevUIAggregatorHostedService.cs~line 221 —TryServeResourceAsynccallsAssembly.Load()+GetManifestResourceStream()on each request. The existingDevUIMiddlewarecaches the content bytes at startup in aFrozenDictionary. Might be nice to align these, though it's fine for dev-only usage..csprojline 11 — TheVSTHRD002warning suppression is project-wide; could be scoped to just the shutdown handler inAgentFrameworkBuilderExtensions.cslines 104-107.- The sample app hangs on "Provisioning foundry-roles..." during Azure RBAC provisioning, which can be slow or fail silently. Might be worth adding a note in the sample README about Azure prereqs, or providing a local-only configuration that doesn't require Foundry.
Overall, looks good
this is not as easy. since the agents are not mapping devui, they don't have a
when it comes to foundry, the apphost explicitly states that the resources are waiting for foundry to be ready. unexpected behaviours on aspire foundry integrations are known to aspire users, and the integration itself is being refactored (dotnet/aspire#14149). that being said, i've updated the apphost to explain foundry behaviour and make it easier for aspire to provision aspire for you, instead of connecting to an existing one. |
Motivation and Context
Adds a new Aspire hosting library that provides a DevUI resource for testing and debugging AI agents built with Microsoft Agent Framework.
Closes #3768
Description
This PR introduces
Aspire.Hosting.AgentFramework— an extension library that enables Aspire AppHost projects to spin up a unified DevUI for interacting with multiple agent services during development.Key Features
AddDevUI()extension method — Registers a DevUI resource in the Aspire AppHostWithAgentService()fluent API — Connects agent services to the DevUI with optional metadata/v1/entitieslistings across all configured backendsUsage
Contribution Checklist