Skip to content

Add agent resource support#17757

Open
tommasodotNET wants to merge 19 commits into
microsoft:mainfrom
tommasodotNET:feature/agent-awareness-17752
Open

Add agent resource support#17757
tommasodotNET wants to merge 19 commits into
microsoft:mainfrom
tommasodotNET:feature/agent-awareness-17752

Conversation

@tommasodotNET
Copy link
Copy Markdown
Contributor

@tommasodotNET tommasodotNET commented May 31, 2026

Description

Adds generic agent awareness for Aspire resources so endpoint-backed compute resources can be marked as agents and surfaced consistently in the dashboard. This enables A2A, OpenAI Responses, AG-UI, and ACP agents to expose protocol-specific URLs and highlighted send-message commands, while MCP server tooling is surfaced through WithMcpServer() instead of being modeled as an agent protocol.

Fixes #17752

User-facing usage

C# AppHost:

var a2aAgent = builder.AddPythonApp("a2a-jsonrpc-agent", "../weather-agent-python", "weather_agent_python.main:app")
    .WithHttpEndpoint(env: "PORT")
    .AsAgent(AgentProtocol.A2AJsonRpc);

var responsesAgent = builder.AddProject<Projects.ResponsesAgent>("responses-agent")
    .WithHttpEndpoint(env: "PORT")
    .AsAgent(AgentProtocol.Responses)
    .WithMcpServer();

var aguiAcpAgent = builder.AddUvicornApp("agui-acp-agent", "../agui-acp-agent-python", "agui_acp_agent.main:app")
    .WithUv()
    .AsAgent(AgentProtocol.AgUi)
    .AsAgent(AgentProtocol.Acp);

builder.AddExecutable("agent-env-dump", "dotnet", ".", "run")
    .WithReference(a2aAgent);

Each AsAgent(...) call configures one protocol/path pair. A resource can expose multiple protocols by calling AsAgent(...) multiple times, which creates multiple agent annotations on the same resource.

The A2A reference injects an agent card URL such as A2A_JSONRPC_AGENT_AGENTCARD_URL into consumers. A2A supports JSON-RPC, HTTP+JSON, and gRPC protocol variants; dashboard send-message commands are added for the HTTP-capable variants. A2A invocation defaults to non-streaming and can opt into streaming with A2AInvocationMode.Streaming.

Protocol mapping SDKs used in the playground

  • A2A JSON-RPC: Python A2A SDK (a2a, from a2a-sdk) for the agent card and JSON-RPC routes, with agent-framework-a2a as the adapter from the in-process agent to A2A.
  • OpenAI Responses: Microsoft.Agents.AI.Hosting.OpenAI for AddOpenAIResponses() and MapOpenAIResponses().
  • AG-UI: agent-framework-ag-ui for add_agent_framework_fastapi_endpoint(...).
  • ACP: acp-sdk for the ACP server and FastAPI app mapping.
  • MCP: ModelContextProtocol.AspNetCore for AddMcpServer(), WithHttpTransport(), and MapMcp(...).

Playground

This adds playground/AspireAgents with Foundry-backed sample agents:

  • a2a-jsonrpc-agent: Python A2A JSON-RPC agent.
  • responses-agent: .NET OpenAI Responses agent, also exposed as an MCP server through WithMcpServer().
  • mcp-agent: .NET MCP server with a model-backed answer_question tool.
  • agui-acp-agent: one Python app exposing both AG-UI and ACP protocols from the same Aspire resource.
  • agent-env-dump: dummy executable resource for checking A2A environment variable injection.

Checklist

  • Is this feature complete?
    • Yes. Ready to ship.
    • No. Follow-up changes expected.
  • Are you including unit tests for the changes and scenario tests if relevant?
    • Yes
    • No
  • Did you add public API?
    • Yes
      • If yes, did you have an API Review for it?
        • Yes
        • No
      • Did you add <remarks /> and <code /> elements on your triple slash comments?
        • Yes
        • No
    • No
  • Does the change make any security assumptions or guarantees?
    • Yes
      • If yes, have you done a threat model and had a security review?
        • Yes
        • No
    • No

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 31, 2026 17:29
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 31, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.sh | bash -s -- 17757

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/microsoft/aspire/main/eng/scripts/get-aspire-cli-pr.ps1) } 17757"

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.

Pull request overview

Adds generic agent-resource support to Aspire Hosting so endpoint-backed compute resources can be marked as A2A/OpenAI Responses agents, surfaced in the dashboard, and referenced by consumers via agent-card environment variables.

Changes:

  • Adds Aspire.Hosting.Agents public APIs for agent protocols, invocation mode, annotations, and AsAgent(...) extensions.
  • Extends WithReference(...) to inject A2A agent-card URLs into consumers.
  • Adds tests, code-generation coverage, and a new playground/AspireAgents sample.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
src/Aspire.Hosting/Agents/AgentResourceBuilderExtensions.cs Adds agent configuration, dashboard commands, URLs, and request preparation helpers.
src/Aspire.Hosting/Agents/AgentResourceAnnotation.cs Adds metadata annotation for agent protocols and paths.
src/Aspire.Hosting/Agents/AgentProtocol.cs Adds supported agent protocol enum.
src/Aspire.Hosting/Agents/A2AInvocationMode.cs Adds A2A dashboard invocation mode enum.
src/Aspire.Hosting/ResourceBuilderExtensions.cs Adds A2A agent-card env-var injection during references.
src/Aspire.Hosting/api/Aspire.Hosting.cs Updates public API surface for new agent APIs.
tests/Aspire.Hosting.Tests/AgentResourceBuilderExtensionsTests.cs Adds hosting tests for annotations, commands, and reference injection.
tests/Aspire.Hosting.CodeGeneration.TypeScript.Tests/AtsTypeScriptCodeGeneratorTests.cs Adds ATS capability and enum coverage for TypeScript.
tests/Aspire.Hosting.CodeGeneration.Python.Tests/AtsPythonCodeGeneratorTests.cs Adds ATS capability coverage for Python.
tests/Aspire.Hosting.CodeGeneration.Java.Tests/AtsJavaCodeGeneratorTests.cs Adds ATS capability coverage for Java.
tests/Aspire.Hosting.CodeGeneration.Go.Tests/AtsGoCodeGeneratorTests.cs Adds ATS capability coverage for Go.
playground/AspireAgents/AspireAgents.AppHost/AppHost.cs Adds sample AppHost wiring for A2A and Responses agents.
playground/AspireAgents/AspireAgents.AppHost/AspireAgents.AppHost.csproj Adds sample AppHost project configuration.
playground/AspireAgents/AspireAgents.AppHost/Properties/launchSettings.json Pins local dashboard/resource-service endpoints for the sample.
playground/AspireAgents/ResponsesAgent/ResponsesAgent.csproj Adds Responses agent project dependencies.
playground/AspireAgents/ResponsesAgent/Program.cs Implements sample OpenAI Responses weather agent.
playground/AspireAgents/weather-agent-python/weather_agent_python/main.py Implements sample Python A2A weather agent.
playground/AspireAgents/weather-agent-python/weather_agent_python/__init__.py Adds Python package marker/docstring.
playground/AspireAgents/weather-agent-python/pyproject.toml Adds Python sample package metadata and dependencies.
playground/AspireAgents/weather-agent-python/.python-version Pins Python version for the sample.
playground/AspireAgents/aspire.config.json Points Aspire CLI/config tooling at the sample AppHost.

Comment thread src/Aspire.Hosting/ResourceBuilderExtensions.cs Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@davidfowl
Copy link
Copy Markdown
Contributor

Definitely don’t want this in Aspire.Hosting. Also this needs to be proven across more than just MAF since it’s a general abstraction. Make this PR a draft until we do more research

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tommasodotNET tommasodotNET marked this pull request as draft May 31, 2026 21:44
tommasodotNET and others added 6 commits June 1, 2026 00:03
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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.

Pull request overview

Copilot reviewed 45 out of 47 changed files in this pull request and generated 2 comments.

Comment thread src/Aspire.Hosting.Agents/AgentResourceBuilderExtensions.cs Outdated
Comment thread src/Aspire.Hosting/McpServerResourceBuilderExtensions.cs
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tommasodotNET tommasodotNET marked this pull request as ready for review June 4, 2026 10:22
Comment thread src/Aspire.Hosting.Agents/AgentResourceBuilderExtensions.cs Outdated
tommasodotNET and others added 6 commits June 4, 2026 19:26
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tommasodotNET tommasodotNET reopened this Jun 4, 2026
@microsoft-github-policy-service microsoft-github-policy-service Bot added this to the 13.5 milestone Jun 4, 2026
@tommasodotNET tommasodotNET reopened this Jun 4, 2026
tommasodotNET and others added 2 commits June 4, 2026 21:45
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@tommasodotNET
Copy link
Copy Markdown
Contributor Author

tommasodotNET commented Jun 4, 2026

PR Testing Report

PR Information

Overall Result

✅ PR VERIFIED — all tested scenarios passed.

The PR dogfood CLI matches the PR head, CI is green, the AspireAgents-style AppHost starts successfully with the existing Foundry resources, A2A agent-card reference injection works, and the agent custom commands were invoked successfully from the dashboard.

CI Status

  • Status: ✅ Green at final capture
  • Checks captured: 334
  • Non-success/non-skipped checks: 0
  • Checks artifact: /tmp/aspire-pr-test-17757-oLMRlN/agent-playground/final-pr-checks.tsv

CLI Version Verification

  • Installed CLI: /tmp/aspire-pr-test-17757-oLMRlN/dogfood/pr-17757/bin/aspire
  • Expected Commit: f1579fcb8ce4f05d4f270f4be9ef190281e9e48a
  • Installed Version: 13.5.0-pr.17757.gf1579fcb
  • Status: ✅ Verified — version contains PR head short SHA gf1579fcb.

Test App Setup

  • Workspace: /tmp/aspire-pr-test-17757-oLMRlN/agent-playground/AspireAgentsSmoke
  • AppHost: /tmp/aspire-pr-test-17757-oLMRlN/agent-playground/AspireAgentsSmoke/apphost.cs
  • Pattern: Based on playground/AspireAgents, adapted to the current PR CLI file-based AppHost format.
  • Azure local provisioning config: TenantId=tommasostocchi.dev, SubscriptionId=cabbfb81-4a74-4730-afdb-65bae9448063, Location=swedencentral, ResourceGroup=rg-pr17757-test, AllowResourceGroupCreation=true, CredentialSource=AzureCli.
  • Existing Foundry inputs: account foundry-tstocchi, resource group rg-supp-resources, project tstocchi-project, model deployment gpt41.
  • Run-mode existing resources: used AsExisting for the Foundry account/project.
  • Python tooling: installed user-local uv (uv 0.11.19) so the Python agent installer resources could run.

Resource Startup

Status: ✅ Passed.

All target resources reached up:

waiting agents-foundry up
�[2mWaiting for resource 'agents-foundry' to be up (running)...�[0m

�[38;5;2m✅�[0m Resource 'agents-foundry' is up (running). (0.0s)
waiting tstocchi-project up
�[2mWaiting for resource 'tstocchi-project' to be up (running)...�[0m

�[38;5;2m✅�[0m Resource 'tstocchi-project' is up (running). (0.0s)
waiting chat up
�[2mWaiting for resource 'chat' to be up (running)...�[0m

�[38;5;2m✅�[0m Resource 'chat' is up (running). (0.0s)
waiting a2a-jsonrpc-agent up
�[2mWaiting for resource 'a2a-jsonrpc-agent' to be up (running)...�[0m

�[38;5;2m✅�[0m Resource 'a2a-jsonrpc-agent' is up (running). (0.1s)
waiting responses-agent up
�[2mWaiting for resource 'responses-agent' to be up (running)...�[0m

�[38;5;2m✅�[0m Resource 'responses-agent' is up (running). (0.0s)
waiting mcp-agent up
�[2mWaiting for resource 'mcp-agent' to be up (running)...�[0m

�[38;5;2m✅�[0m Resource 'mcp-agent' is up (running). (0.0s)
waiting agui-acp-agent up
�[2mWaiting for resource 'agui-acp-agent' to be up (running)...�[0m

�[38;5;2m✅�[0m Resource 'agui-acp-agent' is up (running). (0.0s)
waiting agent-env-dump up
�[2mWaiting for resource 'agent-env-dump' to be up (running)...�[0m

�[38;5;2m✅�[0m Resource 'agent-env-dump' is up (running). (0.0s)

Final resource/command state:

a2a-jsonrpc-agent-installer	Executable	Finished	start
a2a-jsonrpc-agent	Executable	Running	a2a-jsonrpc-agent-a2a-send-message,restart,stop
agent-env-dump	Executable	Running	restart,stop
agents-foundry	FoundryResource	Running	
agents-foundry-roles	AzureRoleAssignmentResource	Running	
agui-acp-agent-installer	Executable	Finished	start
agui-acp-agent	Executable	Running	agui-acp-agent-acp-run,agui-acp-agent-ag-ui-send-message,restart,stop
chat	FoundryDeploymentResource	Running	
foundry-name	Parameter	Running	delete-parameter,set-parameter
foundry-project-name	Parameter	Running	delete-parameter,set-parameter
foundry-resource-group	Parameter	Running	delete-parameter,set-parameter
mcp-agent	Project	Running	mcp-agent-mcp-call-tool,rebuild,restart,stop
responses-agent	Project	Running	rebuild,responses-agent-mcp-call-tool,responses-agent-responses-send-message,restart,stop
tstocchi-project	AzureCognitiveServicesProjectResource	Running	

A2A agent-card reference injection was present in the consumer environment:

�[2mGetting logs...�[0m
�[38;5;137m[agent-env-dump]�[0m Waiting for resource 'a2a-jsonrpc-agent' to enter the 'Running' state.
�[38;5;137m[agent-env-dump]�[0m Waiting for resource ready to execute for 'a2a-jsonrpc-agent'.
�[38;5;137m[agent-env-dump]�[0m Finished waiting for resource 'a2a-jsonrpc-agent'.
�[38;5;137m[agent-env-dump]�[0m [sys] Starting process...: Cmd = /usr/bin/sh, Args = ["-c", "echo 
A2A_JSONRPC_AGENT_AGENTCARD_URL=$A2A_JSONRPC_AGENT_AGENTCARD_URL && sleep 3600"]
�[38;5;137m[agent-env-dump]�[0m A2A_JSONRPC_AGENT_AGENTCARD_URL=https://localhost:41443/.well-known/agent-card.json

Agent Custom Command Validation

Status: ✅ Passed.

Agent/resource Command/protocol Result Evidence
a2a-jsonrpc-agent Invoke A2A ✅ Passed Log shows Successfully executed command after GET agent card, POST /, Foundry Responses 200.
responses-agent Invoke Responses ✅ Passed Confirmed by dashboard invocation; resource remained running.
mcp-agent Invoke MCP ✅ Passed Logs show MCP initialize and tools/list requests completing successfully over /mcp.
responses-agent Invoke MCP ✅ Passed Logs show MCP initialize and tools/list requests completing successfully over /mcp.
agui-acp-agent Invoke AG-UI ✅ Passed Log shows POST /ag-ui 200 and Successfully executed command.
agui-acp-agent Invoke ACP ✅ Passed Confirmed by dashboard invocation; resource remained running.

Representative successful log excerpts:

�[38;5;37m[a2a-jsonrpc-agent]�[0m INFO:azure.identity._credentials.chained:DefaultAzureCredential acquired a token from 
�[38;5;37m[a2a-jsonrpc-agent]�[0m INFO:     127.0.0.1:58824 - "POST / HTTP/1.1" 200 OK
�[38;5;37m[a2a-jsonrpc-agent]�[0m Successfully executed command 'a2a-jsonrpc-agent-a2a-send-message'.
�[38;5;111m[agui-acp-agent]�[0m INFO:     127.0.0.1:53286 - "POST /ag-ui HTTP/1.1" 200 OK
�[38;5;111m[agui-acp-agent]�[0m Successfully executed command 'agui-acp-agent-ag-ui-send-message'.
�[38;5;215m[mcp-agent]�[0m       Server (McpAgent 1.0.0.0), Client (apphost 1.0.0.0) method 'initialize' request handler completed in 
�[38;5;215m[mcp-agent]�[0m       Server (McpAgent 1.0.0.0), Client (apphost 1.0.0.0) method 'tools/list' request handler completed in 
�[38;5;215m[mcp-agent]�[0m       Server (McpAgent 1.0.0.0), Client (apphost 1.0.0.0) method 'initialize' request handler completed in 
�[38;5;215m[mcp-agent]�[0m       Server (McpAgent 1.0.0.0), Client (apphost 1.0.0.0) method 'tools/list' request handler completed in 
�[38;5;215m[mcp-agent]�[0m       Server (McpAgent 1.0.0.0), Client (apphost 1.0.0.0) method 'initialize' request handler completed in 
�[38;5;215m[mcp-agent]�[0m       Server (McpAgent 1.0.0.0), Client (apphost 1.0.0.0) method 'tools/list' request handler completed in 
�[38;5;215m[mcp-agent]�[0m       Server (McpAgent 1.0.0.0), Client (apphost 1.0.0.0) method 'initialize' request handler completed in 
�[38;5;215m[mcp-agent]�[0m       Server (McpAgent 1.0.0.0), Client (apphost 1.0.0.0) method 'tools/list' request handler completed in 

Notes

  • Earlier non-interactive CLI attempts returned InteractionService is not available because these custom commands prompt through dashboard interaction services. That was a test-method limitation, not a PR failure. Dashboard-driven invocation is the correct path for these prompted commands and passed.
  • Earlier PublishAsExisting attempts were also a test setup issue; the final run used AsExisting for run mode.

Artifacts

  • PR install log: /tmp/aspire-pr-test-17757-oLMRlN/install.log
  • Final AppHost source: /tmp/aspire-pr-test-17757-oLMRlN/agent-playground/AspireAgentsSmoke/apphost.cs
  • Final describe JSON: /tmp/aspire-pr-test-17757-oLMRlN/agent-playground/user-confirmed-describe.json
  • Invocation evidence: /tmp/aspire-pr-test-17757-oLMRlN/agent-playground/user-confirmed-invocation-evidence.txt
  • AppHost log: /tmp/aspire-pr-test-17757-oLMRlN/logs/cli_20260604T221849475_detach-child_6662a5dcd53c4a01bce32306d85b3de0.log

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Aspire Agent Awarness

3 participants