mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
feature/python-hosting
3 Commits
-
.NET: Bump Azure.AI.Projects to 2.1.0-beta.2 and add agent-endpoint AsAIAgent path (#5899)
* .NET: Bump Azure.AI.Projects to 2.1.0-beta.2 and add agent-endpoint AsAIAgent path Bumps Azure.AI.Projects to 2.1.0-beta.2 with the matching transitive pins (Azure.Core 1.55.0, System.ClientModel 1.11.0). Foundry agent endpoint plumbing: * FoundryAgent now routes the agent-endpoint constructor through the new GetProjectResponsesClientForAgentEndpoint helper. * Adds an internal FoundryAgent ctor that takes an existing AIProjectClient plus a parsed agent endpoint so the public extension does not need to construct a second project client. * Adds public AIProjectClient.AsAIAgent(Uri agentEndpoint, ...) extension. This is the path consumer samples are expected to use for hosted agents because version selection happens server-side. * Trims the dangling "If you want to construct a FoundryAgent against a project endpoint..." sentence from ParseAgentEndpoint. Unit tests: * Four new tests in AzureAIProjectChatClientExtensionsTests cover the AIProjectClient.AsAIAgent(Uri agentEndpoint, ...) overload. 263/263 pass. Consumer samples (Using-Samples): * SimpleAgent and SessionFilesClient now read AZURE_AI_PROJECT_ENDPOINT and AZURE_AI_AGENT_NAME (both required, throw on missing), derive the agent endpoint with new Uri($"{projectEndpoint}/agents/{agentName}/endpoint/protocols/openai"), then call aiProjectClient.AsAIAgent(agentEndpoint, ...). * SessionFilesClient README updated. Contributor samples (responses/*): * New HostedContributorRouteExtensions.MapDevTemporaryLocalAgentEndpoint() wildcard route extension so localhost contributor servers accept the per-agent OpenAI endpoint shape the production Hosted runtime exposes. * All 11 contributor Program.cs files call MapDevTemporaryLocalAgentEndpoint() with a contributor-only warning comment. * Hosted-Files and Hosted-AzureSearchRag were importing Hosted_Shared_Contributor_Setup but never calling AddDevTemporaryLocalContributorSetup(). Both now call it so HostedSessionIsolationKeyProvider resolves correctly in dev. * Hosted-AzureSearchRag, Hosted-Files, Hosted-MemoryAgent csprojs drop stale VersionOverride="2.1.0-beta.1" pins. * Hosted-AzureSearchRag and Hosted-Files csprojs add ProjectReference to Hosted_Shared_Contributor_Setup. * Hosted-Observability/.dockerignore removed the out/ exclusion that was blocking COPY out/ . in Dockerfile.contributor. Verified: * Full solution-scoped build of changed projects: green. * Scoped CI-parity dotnet format via WSL2 + Docker (mcr.microsoft.com/dotnet/sdk:10.0) over every changed csproj: clean. * Foundry unit tests: 263/263. * Contributor docker smoke for 8 hosted samples (publish + docker build + docker run + curl POST to the wildcard route): HTTP 200 / 500 with route matched. * End-to-end smoke against the real Azure Foundry project with a fresh bearer token: Hosted-Files contributor container served HTTP 200, the agent invoked ListBundledFiles, and returned the expected file name. * Address PR review: forward pipeline settings; add UTs - CreateProjectClientOptions also carries RetryPolicy, NetworkTimeout, ClientLoggingOptions, MessageLoggingPolicy (was Transport+UserAgentApplicationId only). - Make CreateProjectClientOptions internal so tests can verify the copy directly. - Add AsAIAgent(Uri) UTs covering tools forwarding to inner ChatOptions and null tools handling. - Add CreateProjectClientOptions UTs covering null caller and full pipeline-settings copy.Roger Barreto ·
2026-05-18 20:20:56 +00:00 -
.NET: Hosted-Files sample + AgentSessionFiles SDK companion + integration test (#5698)
* .NET: Add Hosted-Files sample + alpha AgentSessionFiles SDK companion + integration test Closes #5691 - Hosted-Files server sample (mirrors python 06_files): 3 local tools reading the per-session \C:\Users\rbarreto sandbox volume. - SessionFilesClient REPL companion: code-first equivalent of zd ai agent files upload using the alpha Azure.AI.Projects.AgentSessionFiles SDK (upload/ls/download/rm + session lifecycle with isolation key). - session-files scenario added to the Foundry.Hosting.IntegrationTests multi-scenario harness (PR #5598): SessionFilesHostedAgentFixture + SessionFilesHostedAgentTests.UploadAndAgentReadsFileAsync, end-to-end validating upload then agent-reads-file (agent_session_id pinned via CreateResponseOptions.Patch). Bundled testdata is linked from the sample so there is a single source of truth. * .NET: Hosted-Files: REPL companion now demonstrates file-as-knowledge end-to-end Adds an 'ask <prompt>' command to SessionFilesClient that pins agent_session_id (via CreateResponseOptions.Patch) so the agent invoked from the REPL reads files this REPL just uploaded. Surfaces the file content as agent knowledge in the same in-process loop instead of telling the user to shell out to azd ai agent invoke. * .NET: Reshape Hosted-Files sample - bake files into image, SessionFilesClient becomes thin chat REPL The previous SessionFilesClient leaned on the alpha AgentSessionFiles SDK to upload files at runtime, which made it diverge from the canonical Using-Samples shape (SimpleAgent / SimpleInvocationsAgent: tiny chat REPLs). This change: - Bakes the sample resources/ directory into the published output via a Content Include in HostedFiles.csproj. Inside the container the files live at /app/resources/. Two local function tools (ListFiles, ReadFile) surface them to the model. - Reshapes SessionFilesClient as a thin FoundryAgent chat REPL, identical shape to SimpleAgent. AGENT_ENDPOINT + AGENT_NAME, that is it. - Demo flow: user asks 'Give me the total revenue in the contoso file' and the agent answers with the figure read from its bundled file. Validated end-to-end locally against Hosted-Files on http://localhost:60419. - Bypasses SampleEnvironment alias on optional env vars to avoid stdin prompts when running unattended. The Foundry.Hosting.IntegrationTests session-files scenario continues to validate the alpha AgentSessionFiles SDK end-to-end (upload + agent reads from session HOME) and is unchanged. * .NET: Foundry.Hosting.IntegrationTests TestContainer - constrain session-files tools to $HOME Addresses the path-traversal review comment on the session-files scenario: ResolveSessionPath in TestContainer used to allow absolute paths and .. traversals, which (when chained with indirect prompt injection in an uploaded file) would let the model read or list arbitrary container files via the ReadFile / ListFiles tools. Mirrors the canonicalize + StartsWith(home) pattern from the framework's own FileSystemAgentFileStore.ResolveSafePath: rejects rooted paths, calls Path.GetFullPath, and verifies the result stays under $HOME, throwing ArgumentException otherwise. The Hosted-Files sample is already safe (uses Path.GetFileName which strips any directory component) so no change there. The integration test continues to upload and read 'contoso_q1_2026_report.txt', a single relative filename which passes the new validation unchanged. * .NET: SessionFilesHostedAgentTests - shrink to alpha SDK round-trip The previous test attempted to pin agent_session_id into the /responses payload via JsonPatch so the agent would read the file uploaded through AgentSessionFiles. The Foundry alpha service now consistently rejects the explicit-session-id pin with HTTP 400 conflict on /responses, regardless of whether the session was pre-created via AgentAdministrationClient or left to be auto-provisioned, so the agent leg of the test is no longer reachable from the SDK surface. Reshape the test to exercise what the alpha SDK actually guarantees: create session, upload, list (assert presence + size), download (assert deterministic token), delete (assert removed), cleanup. Everything stays inside Azure.AI.Projects.Agents.AgentSessionFiles. Verified live against tao-foundry-prj: UploadListDownloadAndDeleteAsync passed in 30s. Full Foundry.Hosting.IntegrationTests run: 25 total, 6 passed, 19 skipped (existing placeholders), 0 failed. * .NET: SessionFilesHostedAgentTests - rewrite as upload-then-FoundryAgent.RunAsync e2e Per review feedback the integration test must validate the hosted agent itself: client uploads a file via the alpha AgentSessionFiles SDK, then FoundryAgent.RunAsync invokes the deployed agent and the agent's container-side ReadFile tool surfaces the uploaded file content into the response. Test flow: 1. agent.RunAsync(warmup) - platform provisions a per-session container. 2. AgentAdministrationClient.GetSessionsAsync(latest) - resolve the just-provisioned agent_session_id. 3. AgentSessionFiles.UploadSessionFileAsync - upload contoso file to that session, asserts BytesWritten + GetSessionFiles listing. 4. agent.RunAsync(real prompt, options=PreviousResponseId chain) - chained to warmup so the platform routes back to the same container. 5. Assert response contains '1,482.6' (deterministic token from file). 6. Best-effort cleanup. The test is annotated with [Fact(Skip=...)] right now: the Foundry alpha service consistently returns HTTP 400 conflict on /responses requests that link to a prior session via previous_response_id, conversation_id, or agent_session_id pinning - verified across multiple retries with multiple chaining strategies. Without that link we cannot route the second invocation to the same container the file was uploaded to. When the platform regression is resolved, removing the Skip will exercise the full flow. Full Foundry.Hosting.IntegrationTests run with this change: 25 total, 5 passed, 20 skipped (existing placeholders + this one), 0 failed. * .NET: SessionFilesHostedAgentTests - end-to-end upload-then-FoundryAgent.RunAsync now passes The blocker was a routing problem combined with a platform race: 1. Routing two /responses calls to the same per-session container. - agent_session_id pin in body -> 400 (platform treats it as create) - conversation_id created at project root -> 404 at agent endpoint - previous_response_id chain -> different session The working answer is to create the conversation on a per-agent ProjectOpenAIClient (AgentName option, URL becomes /agents/{name}/endpoint/protocols/openai/conversations) and pass that conversation_id on both calls. Both then resolve to the SAME x-agent-session-id (verified by capturing the response header). 2. Race after AgentSessionFiles upload. The upload mutates session/ conversation revision; a /responses call issued immediately after 400-conflicts with 'modified concurrently. Please retry.' Bounded exponential retry handles it (5 attempts, 2*attempt seconds). Test flow: 1. Create per-agent OpenAI client + ProjectConversationsClient + ProjectResponsesClient. 2. CreateProjectConversationAsync on the per-agent client. 3. Warm-up agent.RunAsync(prompt, ChatOptions { ConversationId = ... }) - captures x-agent-session-id from the response header via a custom pipeline policy. 4. AgentSessionFiles.UploadSessionFileAsync to that session id. 5. ProjectResponsesClient.CreateResponseAsync (raw, retry-on-conflict) with the same conversation_id -> routes back to the same container. 6. Assert response contains '1,482.6' (deterministic token from file). 7. Cleanup: delete file, leave session for TTL. Verified live against tao-foundry-prj: UploadedFile_IsReadByHostedAgentAsync passed in 24.9s. Full Foundry.Hosting.IntegrationTests run: 25 total, 6 passed, 19 skipped (existing placeholders), 0 failed. * .NET: address Copilot PR review findings - agent.manifest.yaml: description + tags now reflect bundled-files agent (image-baked /app/resources), not the obsolete session-sandbox tools the prior shape claimed. - SessionFilesHostedAgentTests: wrap test body in try/finally to call DeleteConversationAsync on the conversation we created (matches HappyPathHostedAgentTests pattern; prevents conversation leakage across runs). - ResponseHeaderCapturePolicy: drop unused LastRequestBody capture left over from diagnosis. Test still passes live (40s). * .NET: Hosted-Files: split into bundled vs session-file tool pairs The previous Hosted-Files agent only exposed bundled (image-baked) file knowledge. The platform also surfaces session-uploaded files at \C:\Users\rbarreto inside the per-session container per container-image-spec.md line 172 (verified live by SessionFilesHostedAgentTests). The sample now teaches both patterns. Two distinct tool pairs, each scoped to its own root: Bundled (image-baked): ListBundledFiles, ReadBundledFile -> /app/resources/ (BUNDLED_FILES_DIR override) Session-uploaded (\C:\Users\rbarreto): ListSessionFiles, ReadSessionFile -> \C:\Users\rbarreto (default /home/session per container spec) Security model -- distinct tools, distinct sandboxes: - Tool input is a fileName, not a path. Schema-level: model cannot request directories or traversals. - Path.GetFileName(input) strips any directory components. - Path.GetFullPath + StartsWith(root) check rejects anything outside the tool's root, mirroring FileSystemAgentFileStore.ResolveSafePath. - Read-only, non-recursive listing. No glob, no '..'. - Failures non-revealing: 'File <name> not found in <scope>.' The two roots are physically isolated (image-baked vs platform-mounted per-session volume). A bundled-root tool can never reach a session file and vice-versa, even if the implementation has a bug. README updated to document both flows, the security pattern, and cite the container-image-spec.md line 172 contract for \C:\Users\rbarreto. Live IT SessionFilesHostedAgentTests.UploadedFile_IsReadByHostedAgentAsync re-passed in 42s after the change (TestContainer is unchanged; the sample-agent split does not affect the IT). * .NET: Hosted-Files README - fix broken relative link to IT (4..5 dots)
Roger Barreto ·
2026-05-11 11:56:58 +00:00 -
.NET [WIP] Foundry Hosted Agents Support (#5312)
* Add Azure AI Foundry Responses hosting adapter Implement Microsoft.Agents.AI.Hosting.AzureAIResponses to host agent-framework AIAgents and workflows within Azure Foundry as hosted agents via the Azure.AI.AgentServer.Responses SDK. - AgentFrameworkResponseHandler: bridges ResponseHandler to AIAgent execution - InputConverter: converts Responses API inputs/history to MEAI ChatMessage - OutputConverter: converts agent response updates to SSE event stream - ServiceCollectionExtensions: DI registration helpers - 336 unit tests across net8.0/net9.0/net10.0 (112 per TFM) - ResponseStreamValidator: SSE protocol validation tool for samples - FoundryResponsesHosting sample app Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump System.ClientModel to 1.10.0 for Azure.Core 1.52.0 compat Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clean up tests and sample formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update Azure.AI.AgentServer packages to 1.0.0-alpha.20260401.5 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add hosted package version suffix (0.9.0-hosted) to distinguish from mainline Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move Foundry Responses hosting into Microsoft.Agents.AI.Foundry package Move source and test files from the standalone Hosting.AzureAIResponses project into the Foundry package under a Hosting/ subfolder. This consolidates the Foundry-specific hosting adapter into the main Foundry package. - Source: Microsoft.Agents.AI.Foundry.Hosting namespace - Tests: merged into Foundry.UnitTests/Hosting/ - Conditionally compiled for .NETCoreApp TFMs only (net8.0+) - Deleted standalone Hosting.AzureAIResponses project and test project - Updated sample and solution references Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump package version to 0.9.0-hosted.260402.2 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump OpenTelemetry packages to fix NU1109 downgrade errors - OpenTelemetry/Api/Exporter.Console/Exporter.InMemory: 1.13.1 -> 1.15.0 - OpenTelemetry.Exporter.OpenTelemetryProtocol: already 1.15.0 - OpenTelemetry.Extensions.Hosting: already 1.14.0 - OpenTelemetry.Instrumentation.AspNetCore/Http: already 1.14.0 - OpenTelemetry.Instrumentation.Runtime: 1.13.0 -> 1.14.0 - Azure.Monitor.OpenTelemetry.Exporter: 1.4.0 -> 1.5.0 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CA1873: guard LogWarning with IsEnabled check Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix model override bug and add client REPL sample - InputConverter: stop propagating request.Model to ChatOptions.ModelId Hosted agents use their own model; client-provided model values like 'hosted-agent' were being passed through and causing server errors. - Add FoundryResponsesRepl sample: interactive CLI client that connects to a Foundry Responses endpoint using ResponsesClient.AsAIAgent() - Bump package version to 0.9.0-hosted.260403.1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Catch agent errors and emit response.failed with real error message Previously, unhandled exceptions from agent execution would bubble up to the SDK orchestrator, which emits a generic 'An internal server error occurred.' message — hiding the actual cause (e.g., 401 auth failures, model not found, etc.). Now AgentFrameworkResponseHandler catches non-cancellation exceptions and emits a proper response.failed event containing the real error message, making it visible to clients and in logs. OperationCanceledException still propagates for proper cancellation handling by the SDK. Also bumps package version to 0.9.0-hosted.260403.2. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * 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> * Address breaking changes in 260408 * Bump hosted internal package version * Add UserAgent middleware tests for Foundry hosting * Hosting Samples update * Hosting Samples update * Hosting Samples update * Hosting Samples update * ChatClientAgent working * Adding SessionStorage and SessionManagement, improving samples to align Consumption vs Hosting * Using updates * Update chat client agent for contributor and devs * Foundry Agent Hosting * Address text rag sample working * Version bump * Adding LocalTools + Workflow samples * Removing extra using samples * Add Hosted-McpTools sample with dual MCP pattern Demonstrates two MCP integration layers in a single hosted agent: - Client-side MCP: McpClient connects to Microsoft Learn, agent handles tool invocations locally (docs_search, code_sample_search, docs_fetch) - Server-side MCP: HostedMcpServerTool delegates tool discovery and invocation to the LLM provider (Responses API), no local connection Includes DevTemporaryTokenCredential for Docker local debugging, Dockerfile.contributor for ProjectReference builds, and the openai/v1 route mapping for AIProjectClient compatibility in Development mode. * .NET: Bump Azure.AI.AgentServer packages to 1.0.0-beta.1/beta.21 and fix br… (#5287) * Bump Azure.AI.AgentServer packages to 1.0.0-beta.1/beta.21 and fix breaking API changes - Azure.AI.AgentServer.Core: 1.0.0-beta.11 -> 1.0.0-beta.21 - Azure.AI.AgentServer.Invocations: 1.0.0-alpha.20260408.4 -> 1.0.0-beta.1 - Azure.AI.AgentServer.Responses: 1.0.0-alpha.20260408.4 -> 1.0.0-beta.1 - Azure.Identity: 1.20.0 -> 1.21.0 (transitive requirement) - Azure.Core: 1.52.0 -> 1.53.0 (transitive requirement) - Remove azure-sdk-for-net dev feed (packages now on nuget.org) - Fix OutputConverter for new builder API (auto-tracked children, split EmitTextDone/EmitDone) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fixing small issues. --------- Co-authored-by: alliscode <bentho@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Azure AI Foundry Responses hosting adapter Implement Microsoft.Agents.AI.Hosting.AzureAIResponses to host agent-framework AIAgents and workflows within Azure Foundry as hosted agents via the Azure.AI.AgentServer.Responses SDK. - AgentFrameworkResponseHandler: bridges ResponseHandler to AIAgent execution - InputConverter: converts Responses API inputs/history to MEAI ChatMessage - OutputConverter: converts agent response updates to SSE event stream - ServiceCollectionExtensions: DI registration helpers - 336 unit tests across net8.0/net9.0/net10.0 (112 per TFM) - ResponseStreamValidator: SSE protocol validation tool for samples - FoundryResponsesHosting sample app Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump System.ClientModel to 1.10.0 for Azure.Core 1.52.0 compat Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clean up tests and sample formatting Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update Azure.AI.AgentServer packages to 1.0.0-alpha.20260401.5 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add hosted package version suffix (0.9.0-hosted) to distinguish from mainline Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Move Foundry Responses hosting into Microsoft.Agents.AI.Foundry package Move source and test files from the standalone Hosting.AzureAIResponses project into the Foundry package under a Hosting/ subfolder. This consolidates the Foundry-specific hosting adapter into the main Foundry package. - Source: Microsoft.Agents.AI.Foundry.Hosting namespace - Tests: merged into Foundry.UnitTests/Hosting/ - Conditionally compiled for .NETCoreApp TFMs only (net8.0+) - Deleted standalone Hosting.AzureAIResponses project and test project - Updated sample and solution references Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump package version to 0.9.0-hosted.260402.2 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump OpenTelemetry packages to fix NU1109 downgrade errors - OpenTelemetry/Api/Exporter.Console/Exporter.InMemory: 1.13.1 -> 1.15.0 - OpenTelemetry.Exporter.OpenTelemetryProtocol: already 1.15.0 - OpenTelemetry.Extensions.Hosting: already 1.14.0 - OpenTelemetry.Instrumentation.AspNetCore/Http: already 1.14.0 - OpenTelemetry.Instrumentation.Runtime: 1.13.0 -> 1.14.0 - Azure.Monitor.OpenTelemetry.Exporter: 1.4.0 -> 1.5.0 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CA1873: guard LogWarning with IsEnabled check Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix model override bug and add client REPL sample - InputConverter: stop propagating request.Model to ChatOptions.ModelId Hosted agents use their own model; client-provided model values like 'hosted-agent' were being passed through and causing server errors. - Add FoundryResponsesRepl sample: interactive CLI client that connects to a Foundry Responses endpoint using ResponsesClient.AsAIAgent() - Bump package version to 0.9.0-hosted.260403.1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Catch agent errors and emit response.failed with real error message Previously, unhandled exceptions from agent execution would bubble up to the SDK orchestrator, which emits a generic 'An internal server error occurred.' message — hiding the actual cause (e.g., 401 auth failures, model not found, etc.). Now AgentFrameworkResponseHandler catches non-cancellation exceptions and emits a proper response.failed event containing the real error message, making it visible to clients and in logs. OperationCanceledException still propagates for proper cancellation handling by the SDK. Also bumps package version to 0.9.0-hosted.260403.2. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * 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> * Address breaking changes in 260408 * Bump hosted internal package version * Add UserAgent middleware tests for Foundry hosting * Hosting Samples update * Hosting Samples update * Hosting Samples update * Hosting Samples update * ChatClientAgent working * Adding SessionStorage and SessionManagement, improving samples to align Consumption vs Hosting * Using updates * Update chat client agent for contributor and devs * Foundry Agent Hosting * Address text rag sample working * Version bump * Adding LocalTools + Workflow samples * Removing extra using samples * Add Hosted-McpTools sample with dual MCP pattern Demonstrates two MCP integration layers in a single hosted agent: - Client-side MCP: McpClient connects to Microsoft Learn, agent handles tool invocations locally (docs_search, code_sample_search, docs_fetch) - Server-side MCP: HostedMcpServerTool delegates tool discovery and invocation to the LLM provider (Responses API), no local connection Includes DevTemporaryTokenCredential for Docker local debugging, Dockerfile.contributor for ProjectReference builds, and the openai/v1 route mapping for AIProjectClient compatibility in Development mode. * Bump Azure.AI.AgentServer packages to 1.0.0-beta.1/beta.21 and fix breaking API changes - Azure.AI.AgentServer.Core: 1.0.0-beta.11 -> 1.0.0-beta.21 - Azure.AI.AgentServer.Invocations: 1.0.0-alpha.20260408.4 -> 1.0.0-beta.1 - Azure.AI.AgentServer.Responses: 1.0.0-alpha.20260408.4 -> 1.0.0-beta.1 - Azure.Identity: 1.20.0 -> 1.21.0 (transitive requirement) - Azure.Core: 1.52.0 -> 1.53.0 (transitive requirement) - Remove azure-sdk-for-net dev feed (packages now on nuget.org) - Fix OutputConverter for new builder API (auto-tracked children, split EmitTextDone/EmitDone) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fixing small issues. * Fix IDE0009: add 'this' qualification in DevTemporaryTokenCredential Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix IDE0009: add 'this' qualification in all HostedAgentsV2 samples Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CHARSET: add UTF-8 BOM to Hosted-LocalTools and Hosted-Workflows Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix dotnet format: add Async suffix to test methods (IDE1006), fix encoding and style Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Register AgentSessionStore in test DI setups Add InMemoryAgentSessionStore registration to all ServiceCollection setups in AgentFrameworkResponseHandlerTests and WorkflowIntegrationTests. This is needed after the AgentSessionStore infrastructure was introduced in the responses-hosting feature. Tests still have NotImplementedException stubs for CreateSessionCoreAsync which will be fixed when the session infrastructure is fully available. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Invocations protocol samples (hosted echo agent + client) (#5278) Add Hosted-Invocations-EchoAgent: a minimal echo agent hosted via the Invocations protocol (POST /invocations) using AddInvocationsServer and MapInvocationsServer, bridged to an Agent Framework AIAgent through a custom InvocationHandler. Add SimpleInvocationsAgent: a console REPL client that wraps HttpClient calls to the /invocations endpoint in a custom InvocationsAIAgent, demonstrating programmatic consumption of the Invocations protocol. Both samples default to port 8088 for consistency with other hosted agent samples. * Restructure FoundryHostedAgents samples into invocations/ and responses/ Align dotnet hosted agent samples with the Python side (PR #5281) by reorganizing the directory structure: - Remove HostedAgentsV1 entirely (old API pattern) - Split HostedAgentsV2 into invocations/ and responses/ based on protocol - Move Using-Samples accordingly (SimpleAgent to responses, SimpleInvocationsAgent to invocations) - Update slnx with new project paths and add previously missing invocations projects - Update README cd paths from HostedAgentsV2 to invocations or responses - Rename .env.local to .env.example to match Python naming convention - Fix format violations in newly included invocations projects * Remove launchSettings, use .env for port configuration - Delete all launchSettings.json files (port 8088 now comes from ASPNETCORE_URLS in .env) - Add DotNetEnv to Hosted-Invocations-EchoAgent so it loads .env like the responses samples - Create .env.example for EchoAgent with ASPNETCORE_URLS and ASPNETCORE_ENVIRONMENT - Add AGENT_NAME to ChatClientAgent and FoundryAgent .env.example (required by those samples) - Add AZURE_BEARER_TOKEN=DefaultAzureCredential to all .env.example files - Update DevTemporaryTokenCredential in all 6 samples to treat the sentinel value as unavailable, allowing ChainedTokenCredential to fall through to DefaultAzureCredential - Update EchoAgent README with Configuration section * Use placeholder for AGENT_NAME in Hosted-FoundryAgent .env.example * Move FoundryResponsesHosting to responses/Hosted-WorkflowHandoff, use GetResponsesClient * Rename Hosted-Workflows to Hosted-Workflow-Simple, Hosted-WorkflowHandoff to Hosted-Workflow-Handoff * Remove FoundryResponsesRepl and empty FoundryResponsesHosting directory * Add Dockerfiles, README, agent yamls and bearer token support to Hosted-Workflow-Handoff - Add Dockerfile and Dockerfile.contributor for Docker-based testing - Add agent.yaml and agent.manifest.yaml with triage-workflow as primary agent - Add README.md following sibling pattern, noting Azure OpenAI vs Foundry endpoint - Add DevTemporaryTokenCredential and ChainedTokenCredential for Docker auth - Register triage-workflow as non-keyed default so azd invoke works without model - Update .env.example with AZURE_BEARER_TOKEN sentinel - Add .gitignore to 04-hosting to suppress VS-generated launchSettings.json - Fix docker run image name in Hosted-Workflow-Simple README * Fix AgentFrameworkResponseHandlerTests: implement session methods in test mock agents * .NET: Auto-instrument resolved AIAgents with OpenTelemetry for Foundry Hosted Agents (#5316) * Auto-instrument resolved AIAgents with OpenTelemetry using Core ResponsesSourceName * Add OTel telemetry capture tests for Foundry hosted agent handler * Net: Prepare Foundry Preview Release (#5336) * Prepare Foundry preview release 1.2.0-preview.* Bump VersionPrefix to 1.2.0 and update the preview stamp date. Invert packaging opt-in so only the Foundry preview set produces NuGet packages: - Microsoft.Agents.AI.Abstractions - Microsoft.Agents.AI - Microsoft.Agents.AI.Workflows - Microsoft.Agents.AI.Workflows.Generators - Microsoft.Agents.AI.Foundry Flip IsReleased=false on the preview set so they pick up the -preview.YYMMDD.N suffix. Gate GeneratePackageOnBuild on IsPackable=true. Remove the global IsPackable=true from nuget-package.props so the repo-level default (false) applies to everything else. * Lower preview VersionPrefix to 0.0.1 Retroactive preview publish: bump VersionPrefix and GitTag from 1.2.0 to 0.0.1 so the 5 Foundry preview packages emit as 0.0.1-preview.260417.1. * Net: Publish all packages as 0.0.1-preview.260417.2 (#5341) Revises the Foundry pre-release approach to publish ALL normally packable src projects as preview packages stamped 0.0.1-preview.260417.2, including projects previously flagged IsReleased=true or with a non-default VersionSuffix (rc/alpha). nuget-package.props: - Collapse the four conditional PackageVersion expressions (IsReleaseCandidate, VersionSuffix, default preview, IsReleased stable) into a single unconditional 0.0.1-preview.260417.2. On this preview-only branch every package ships with the same pre-release stamp regardless of per-project flags. - Restore the global IsPackable=true default (offsetting the repo-wide IsPackable=false in Directory.Build.props). Projects that opt out (Mem0, Declarative) already set IsPackable=false AFTER importing this file so they remain non-packable. - Remove the IsReleased-gated EnablePackageValidation line. Package validation does not apply to a 0.0.1 preview. csproj reverts (Abstractions, Agents.AI, Workflows, Workflows.Generators, Foundry): - Revert the IsPackable=true opt-in block introduced in #5336 (now redundant since the props default is true again). - Restore IsReleased=true to its pre-PR value. The setting is now a no-op because the props no longer branches on it. * Bump preview version to 260420.1 and fix AgentServer package deps (#5367) - Bump PackageVersion to 0.0.1-preview.260420.1 - Bump Azure.AI.AgentServer.Core beta.21 -> beta.22 (required by Azure.AI.AgentServer.Responses beta.3) - Replace AgentHostTelemetry.ResponsesSourceName with local constant (type made internal in AgentServer.Core beta.22) Co-authored-by: alliscode <bentho@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Hosted agents toolbox support (#5368) * feat: Add Foundry Toolbox (MCP) support to AgentFrameworkResponseHandler Adds support for Foundry Toolsets MCP proxy integration in the hosted agent response handler. Toolsets connect at startup via IHostedService, gating the readiness probe per spec §3.1. MCP tools are injected into every request's ChatOptions and OAuth consent errors (-32006) are intercepted and surfaced as mcp_approval_request + incomplete SSE events. New files: - FoundryToolboxOptions.cs: configuration POCO for toolset names and API version - FoundryToolboxBearerTokenHandler.cs: DelegatingHandler with Azure Bearer token auth, Foundry-Features header injection, and 3x exponential backoff on 429/5xx - McpConsentContext.cs: AsyncLocal-based per-request consent state shared between the tool wrapper and the response handler - ConsentAwareMcpClientTool.cs: AIFunction wrapper that catches -32006 errors and signals consent via shared state and linked CancellationTokenSource - FoundryToolboxService.cs: IHostedService that creates McpClient per toolset at startup and exposes cached tools Modified files: - AgentFrameworkResponseHandler.cs: injects toolbox tools into ChatOptions, sets up linked CTS consent interception, emits mcp_approval_request on -32006 - ServiceCollectionExtensions.cs: adds AddFoundryToolboxes(params string[]) extension - Microsoft.Agents.AI.Foundry.csproj: adds ModelContextProtocol and Azure.Identity dependencies under NETCoreApp condition Sample: - Hosted-Toolbox: minimal hosted agent sample using AddFoundryToolboxes * Rename toolset to toolbox in user-facing API; rename ConsentAwareMcpClientTool to ConsentAwareMcpClientAIFunction * Add HostedMcpToolboxAITool for client-selectable Foundry toolboxes Introduces HostedMcpToolboxAITool, a marker tool subclassing HostedMcpServerTool that rides the OpenAI Responses 'mcp' wire format to let clients request a specific Foundry toolbox per request. - New FoundryAITool.CreateHostedMcpToolbox(name, version?) factory. - FoundryToolboxOptions.StrictMode (default true) rejects unregistered toolboxes; set to false to allow lazy-open on first use. - FoundryToolboxService.GetToolboxToolsAsync(name, version?) resolves cached or lazy-opened MCP tools. - AgentFrameworkResponseHandler parses request.Tools for foundry-toolbox://name[?version=v] markers and injects resolved tools per request, merging with pre-registered ones. - Unit tests for marker parsing and strict-mode resolution. * Bump Azure.AI.Projects to 2.1.0-alpha; add ToolboxRecord/ToolboxVersion factory overloads + tests * Fix PR review issues: retry off-by-one, URI encoding, docs, tests, build - Fix off-by-one in FoundryToolboxBearerTokenHandler retry loop (4 attempts → 3) - URI-encode version parameter in HostedMcpToolboxAITool.BuildAddress - Add XML doc clarifying version pinning is reserved for future use - Add comment clarifying AddHostedService deduplication safety - Fix DevTemporaryTokenCredential expiry to use DateTimeOffset.MaxValue - Fix AgentCard ambiguity in A2AServer sample with using alias - Add 18 new unit tests for retry handler and ReadMcpToolboxMarkers Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> Co-authored-by: alliscode <bentho@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Hosted agent adapter (#5371) * Bump preview version to 260420.1 and fix AgentServer package deps - Bump PackageVersion to 0.0.1-preview.260420.1 - Bump Azure.AI.AgentServer.Core beta.21 -> beta.22 (required by Azure.AI.AgentServer.Responses beta.3) - Replace AgentHostTelemetry.ResponsesSourceName with local constant (type made internal in AgentServer.Core beta.22) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CA1873: guard LogError with IsEnabled check in FoundryToolboxService Wrap the LogError call with an IsEnabled(LogLevel.Error) guard to satisfy the CA1873 analyzer rule which flags potentially expensive argument evaluation when logging is disabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: alliscode <bentho@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Hosted agent adapter (#5374) * Bump preview version to 260420.1 and fix AgentServer package deps - Bump PackageVersion to 0.0.1-preview.260420.1 - Bump Azure.AI.AgentServer.Core beta.21 -> beta.22 (required by Azure.AI.AgentServer.Responses beta.3) - Replace AgentHostTelemetry.ResponsesSourceName with local constant (type made internal in AgentServer.Core beta.22) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CA1873: guard LogError with IsEnabled check in FoundryToolboxService Wrap the LogError call with an IsEnabled(LogLevel.Error) guard to satisfy the CA1873 analyzer rule which flags potentially expensive argument evaluation when logging is disabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bumping NuGet version --------- Co-authored-by: alliscode <bentho@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Hosted agent adapter (#5406) * Bump preview version to 260420.1 and fix AgentServer package deps - Bump PackageVersion to 0.0.1-preview.260420.1 - Bump Azure.AI.AgentServer.Core beta.21 -> beta.22 (required by Azure.AI.AgentServer.Responses beta.3) - Replace AgentHostTelemetry.ResponsesSourceName with local constant (type made internal in AgentServer.Core beta.22) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CA1873: guard LogError with IsEnabled check in FoundryToolboxService Wrap the LogError call with an IsEnabled(LogLevel.Error) guard to satisfy the CA1873 analyzer rule which flags potentially expensive argument evaluation when logging is disabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bumping NuGet version * Restore conditional versioning, remove dev feed, bump Azure.AI.Projects to beta.1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: alliscode <bentho@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Hosted agent adapter (#5408) * Bump preview version to 260420.1 and fix AgentServer package deps - Bump PackageVersion to 0.0.1-preview.260420.1 - Bump Azure.AI.AgentServer.Core beta.21 -> beta.22 (required by Azure.AI.AgentServer.Responses beta.3) - Replace AgentHostTelemetry.ResponsesSourceName with local constant (type made internal in AgentServer.Core beta.22) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CA1873: guard LogError with IsEnabled check in FoundryToolboxService Wrap the LogError call with an IsEnabled(LogLevel.Error) guard to satisfy the CA1873 analyzer rule which flags potentially expensive argument evaluation when logging is disabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bumping NuGet version * Restore conditional versioning, remove dev feed, bump Azure.AI.Projects to beta.1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR #5312 review comments - Add comment explaining NU1903 suppression (Microsoft.Bcl.Memory transitive vuln) - Remove NU1903 from sample/test projects where not needed - Fix Dockerfile ENTRYPOINT mismatch in Hosted-Workflow-Simple - Align agent name to 'hosted-workflow-simple' in agent.yaml and README - Fix Hosted-McpTools README: replace GitHub PAT refs with Microsoft Learn - Fix session persistence: only persist when client provides conversation ID - Upgrade IsNullOrEmpty to IsNullOrWhiteSpace for session ID checks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: alliscode <bentho@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Split Foundry into stable V1 and preview Hosting package Extract hosted agent functionality from Microsoft.Agents.AI.Foundry into a new Microsoft.Agents.AI.Foundry.Hosting preview package. This resolves NU5104 build errors caused by the stable Foundry package depending on prerelease Azure SDK packages (Azure.AI.AgentServer.Responses, Azure.AI.Projects beta). Changes: - Create Microsoft.Agents.AI.Foundry.Hosting with VersionSuffix=preview, targeting .NET Core only (net8.0/9.0/10.0) - Move all Hosting/ source files to the new project - Move ToolboxRecord/ToolboxVersion overloads to FoundryAIToolExtensions - Revert Azure.AI.Projects to 2.0.0 in Directory.Packages.props; Hosting uses VersionOverride for 2.1.0-beta.1 - Clean V1 Foundry csproj: remove beta deps, ASP.NET Core ref, hosting conditionals - Update 8 hosted agent sample projects to reference Foundry.Hosting - Split unit tests: ToolboxRecord/ToolboxVersion tests moved to Hosting/ - Add Foundry.Hosting to solution file Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review comments: experimental attrs, doc fixes, token propagation - Add [Experimental(OPENAI001)] to all 7 public Hosting types per reviewer request - Fix McpConsentContext XML doc: 'Thread-static' -> 'Async-local' (AsyncLocal flows with ExecutionContext, not thread-static) - Expand UserAgentMiddleware test regex to match prerelease versions (e.g. 1.0.0-rc.4) - Propagate CancellationToken in AgentFrameworkResponseHandler session save Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove unnecessary MEAI001 suppression from stable Foundry package MEAI001 was a leftover from when Hosting code lived in the same project. The stable V1 Foundry package builds clean without it, and suppressing experimental diagnostics in a released package can hide unintentional exposure of experimental APIs to consumers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Foundry.Hosting to release solution filter Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: alliscode <bentho@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Ben Thomas <ben.thomas@microsoft.com>
Roger Barreto ·
2026-04-21 20:25:10 +00:00