Skip to content

.NET: Features/3768-devui-aspire-integration#3771

Open
tommasodotNET wants to merge 33 commits intomicrosoft:mainfrom
tommasodotNET:features/3768-devui-aspire-integration
Open

.NET: Features/3768-devui-aspire-integration#3771
tommasodotNET wants to merge 33 commits intomicrosoft:mainfrom
tommasodotNET:features/3768-devui-aspire-integration

Conversation

@tommasodotNET
Copy link
Copy Markdown

@tommasodotNET tommasodotNET commented Feb 9, 2026

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 AppHost
  • WithAgentService() fluent API — Connects agent services to the DevUI with optional metadata
  • In-process aggregator — A lightweight Kestrel server running inside the AppHost that:
    • Serves the DevUI frontend from embedded resources (no external container required)
    • Aggregates /v1/entities listings across all configured backends
    • Routes requests to the correct backend based on entity ID prefix
    • Streams SSE responses for real-time agent output

Usage

var writerAgent = builder.AddProject<Projects.WriterAgent>("writer-agent");
var editorAgent = builder.AddProject<Projects.EditorAgent>("editor-agent");

var devui = builder.AddDevUI("devui")
    .WithAgentService(writerAgent)
    .WithAgentService(editorAgent)
    .WaitFor(writerAgent)
    .WaitFor(editorAgent);

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? If yes, add "[BREAKING]" prefix to the title of the PR.

Copilot AI review requested due to automatic review settings February 9, 2026 18:43
@markwallace-microsoft markwallace-microsoft added documentation Improvements or additions to documentation .NET labels Feb 9, 2026
@github-actions github-actions bot changed the title Features/3768-devui-aspire-integration .NET: Features/3768-devui-aspire-integration Feb 9, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@tommasodotNET
Copy link
Copy Markdown
Author

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.

this is not as easy. since the agents are not mapping devui, they don't have a /v1/entities endpoint. i might be wrong here, but i remember is MapDevUI that will make that path available.
dealing with a distributed system, we cannot rely on self discovery and it's easier to let the user map the correct name of the agent to inject the correct agent-id + endpoint in devui.
i've added a comment line to clarify this and also produced a detailed readme for the sample to describe this.

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.

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 (microsoft/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.

Copy link
Copy Markdown
Contributor

@victordibia victordibia left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates, approving this.

One minor thing to keep in mind: the body-swap pattern in DevUIAggregatorHostedService.cs ProxyAndRecordConversationAsync (context.Response.Body = buffer) can silently fail if the response pipeline uses IHttpResponseBodyFeature directly — the conversation ID would never get recorded and routing would fall back to the first backend without any indication. Consider changing the empty catch to log a warning so failures are at least observable.

You seem to have merge conflicts. Test, Fix and I can reapprove as needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation .NET

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Feature]: Add Aspire DevUI Integration

5 participants