mirror of
https://github.com/microsoft/agent-framework.git
synced 2026-06-16 21:04:09 +08:00
feature/python-hosting
960 Commits
-
.NET: Fix/per service input persistence on stream error (#5744)
* .NET: Persist input messages on streaming errors in PerServiceCallChatHistoryPersistingChatClient When the underlying chat service emits an in-stream error (for example a `response.error` SSE event from the OpenAI Responses API on rate limit), the OpenAI client surfaces it as an `ErrorContent` update and ends the stream without throwing. Previously, `PerServiceCallChatHistoryPersistingChatClient` only persisted history when the streaming loop completed successfully and `NotifyProvidersOfNewMessagesAsync` was called at the end. On the in-stream-error path, the input messages handed to that iteration - typically `FunctionResultContent` produced by `FunctionInvokingChatClient` in the previous iteration - were never persisted. The next run would replay session history with a dangling `FunctionCallContent` and the service would reject the request with `No tool output found for function call <id>`. This change: - Adds a `PersistInputOnErrorAsync` helper that persists the input messages (with no response messages) so function-call/function-result pairings are not split across failures. - Calls the helper from every error path: pre-loop enumerator creation, the first `MoveNextAsync`, the in-loop `MoveNextAsync`, and a new `finally` that handles abnormal iterator disposal. - After the streaming loop, scans the assembled response for any `ErrorContent` and, if present, persists the input, notifies providers of failure, and throws `InvalidOperationException` so the error is surfaced to the caller instead of silently corrupting history. - Hardens `InMemoryChatHistoryProvider.StoreChatHistoryAsync` to treat a null `RequestMessages` as empty, since the new error path can invoke it with no response messages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix dropped FunctionResultContent on streaming pipeline early-disposal When a consumer of ChatClientAgent.RunStreamingAsync stops iterating early (e.g. ToolApprovalAgent yields the approval request and then `yield break`), the framework cascades DisposeAsync down the stream. C# async iterators do not auto-dispose IAsyncDisposable locals, so the inner enumerator returned by IChatClient.GetStreamingResponseAsync(...).GetAsyncEnumerator(ct) was left suspended. That suspended FunctionInvokingChatClient downstream, which suspended PerServiceCallChatHistoryPersistingChatClient at its `yield return`, so its finally block never ran and the in-flight FunctionResultContent for the just-completed tool call was not persisted to chat history. The next turn then loaded a session that contained a FunctionCallContent with no matching FunctionResultContent and the model returned HTTP 400 `No tool output found for function call`. Fixes: * ChatClientAgent.RunStreamingAsync: wrap the iteration in try/finally that disposes the inner enumerator. Disposal now cascades through the pipeline and PerService's finally runs on early exit. * PerServiceCallChatHistoryPersistingChatClient: in the streaming path, snapshot input messages with `messages.ToList()` (the caller, FICC, reuses a single mutable buffer across iterations and may mutate it before our finally / error path persists), wrap GetAsyncEnumerator, the first MoveNextAsync, and in-loop MoveNextAsync in try/catch each calling PersistInputOnErrorAsync + NotifyProvidersOfFailureAsync, and add a finally that calls PersistInputOnErrorAsync when the loop did not exit normally so per-iteration FRCs are persisted on early disposal as well as on errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Add tests for PerService streaming error/dispose persistence paths Adds five regression tests covering the new error-path persistence in PerServiceCallChatHistoryPersistingChatClient.GetStreamingResponseInnerAsync: - Persists input messages when GetStreamingResponseAsync throws synchronously. - Persists input messages when the first MoveNextAsync throws. - Persists input messages when a mid-stream MoveNextAsync throws. - Persists input messages when the consumer abandons enumeration early (the ToolApprovalAgent yield-break / disposal-cascade case). - Throws and persists input when the stream emits an in-band ErrorContent. All 66 tests in the class pass on net10.0 and net472. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Address PR feedback on PerService streaming error persistence Two follow-ups from PR #5744 review: 1. Prevent duplicate persistence on the in-loop MoveNextAsync catch path. The inner catch persists input messages, then rethrows, which propagates through the surrounding try/finally where loopExitedNormally is still false, causing the finally to persist again. Introduced an inputPersisted flag that the inner catch sets after persisting; the finally now skips when inputPersisted is true. 2. Use the caller's CancellationToken in the abnormal-exit finally instead of CancellationToken.None, so cleanup remains responsive to cancellation. Fall back to CancellationToken.None only when the caller's token is already canceled (otherwise the persist call would observe the cancellation, throw, and mask the original early-exit reason). Tightened all five new streaming-error tests from Times.AtLeastOnce to Times.Once on the input-persistence matcher to regression-guard against duplicate persistence. All 66 tests in the class still pass (net10.0 + net472). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Scope PerService streaming changes to cooperative early-exit only Per discussion on PR #5744, scope this PR back to fix only the original ToolApprovalAgent dropped-FunctionResultContent bug and address the enumerator-disposal review comment. Specifically: - Remove input-message persistence from the GetAsyncEnumerator and MoveNextAsync error paths. Routing failed service calls through the success notification channel was breaking the provider contract; we will instead rely on inner-agent retries for transient errors. Failure paths still call NotifyProvidersOfFailureAsync as before. - Remove the in-stream ErrorContent detection block (same rationale). - Keep the try/finally that calls the (now narrower) early-exit input notification on cooperative disposal (e.g. ToolApprovalAgent yield break). A new serviceErrorOccurred flag ensures we do NOT renotify on exception paths. - Always DisposeAsync the underlying enumerator on every exit path, addressing the copilot-reviewer comment about leaked HTTP/streams. - Rename PersistInputOnErrorAsync -> NotifyProvidersOfEarlyExitInputAsync to better reflect what it does and when it runs (rogerbarreto nit). - Apply rogerbarreto nit on InMemoryChatHistoryProvider null-coalescing. - Drop the four tests that covered the removed error-path behavior; keep RunStreamingAsync_PersistsInputMessages_WhenConsumerAbandons EnumerationAsync (regression guard for the cooperative-pause path). 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>
Ben Thomas ·
2026-05-11 20:28:14 +00:00 -
.NET: Hosted Agents - RAG Sample with Azure AI Search (#5693) (#5701)
* .NET: Hosted Agents - RAG Sample with Azure AI Search (#5693) Adds a Hosted-AzureSearchRag sample plus a live Foundry.Hosting integration test scenario backed by a real Azure AI Search index. Sample (Hosted-AzureSearchRag): keyword-only Azure AI Search via SearchClient adapter into TextSearchProvider, scope-aware DevTemporaryTokenCredential consuming AZURE_BEARER_TOKEN_FOUNDRY + AZURE_BEARER_TOKEN_SEARCH for local Docker, Dockerfile + contributor Dockerfile mirroring Hosted-TextRag. Integration test: AzureSearchRagHostedAgentFixture extends the PR #5598 HostedAgentFixture with the new azure-search-rag scenario branch in the shared test container; AzureSearchRagHostedAgentTests asserts the model returns canary tokens (TR-CANARY-7821, SHIP-CANARY-4493) that exist only in the seeded documents - real proof the agent grounded its answer in retrieved content rather than training data. * Address PR 5701 Copilot review feedback - Sample README: drop stale 'bootstraps the index on first run' line; index is pre-provisioned out of band - Sample + TestContainer search adapters: propagate CancellationToken to await foreach via .WithCancellation()
Roger Barreto ·
2026-05-11 13:59:42 +00:00 -
Simplify ClientHeadersScope, drop redundant using/Dispose (#5676)
Wesley pointed out (with a clean demo) that AsyncLocal<T> mutations made inside an awaited async method do not leak back to the caller after the method returns - the runtime restores the caller's view automatically. ClientHeadersAgent.RunCoreAsync and RunCoreStreamingAsync are the only callers of the scope, both are async methods awaited by their callers, so the explicit using/Dispose pattern was doing work the runtime already does for us. * ClientHeadersScope collapsed to a single Current { get; set; } property over an AsyncLocal<IReadOnlyDictionary<string,string>?>. Drops Push, the Scope struct, and Dispose. XML doc explains the AsyncLocal natural- restoration semantics so the design intent is self-documenting. * ClientHeadersAgent uses a direct ClientHeadersScope.Current = snapshot before delegating. Drops the local RunAsyncCoreAsync helper and the snapshot-passed-as-parameter dance. * Test 10 renamed to ClientHeadersScope_IsAsyncLocalIsolatedAndAutoRestoresAsync; drops the LIFO claim, keeps the parallel-isolation assertion, and adds a Wesley-style 'set inside async, caller sees null on return' assertion. * Test 12 switches from using ClientHeadersScope.Push to direct Current = ... with try/finally for test isolation. Snapshot deep-copy in TrySnapshot stays - it defends against caller mutating the source Dictionary mid-run, which is independent of the AsyncLocal restoration mechanism.Roger Barreto ·
2026-05-11 13:38:14 +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: Foundry.Hosting IT - eliminate MSBuild parallel-output races (#5725)
* .NET: Foundry.Hosted IT - fix MSBuild parallel-output races Two surgical changes inside the dotnet-foundry-hosted-it job: 1. Replace dotnet build <slnx> -f net10.0 with dotnet build <test.csproj>. The test csproj pins TargetFrameworks=net10.0 and its ProjectReference closure gives MSBuild a single-rooted graph, eliminating the duplicate inner-builds that race on bin/obj. Drops the two New-FilteredSolution.ps1 steps. 2. In it-build-image.ps1, drop the -UsePrebuiltProjectReferences switch and always pass --no-dependencies to dotnet publish. Publish now resolves TestContainer's framework refs by reading prebuilt DLLs and never re-touches them. Replaces the partial-mitigation in PR #5689 with a structural fix. Local validation confirmed published Foundry.dll has identical mtime and bytes as the prebuild output. * .NET: dotnet test - use --project flag for Microsoft Testing Platform
Roger Barreto ·
2026-05-11 09:39:13 +00:00 -
.NET: Add IChatMessageInjector for message injection during function loop (#5679)
* Adding the ability to inject messages during the function call loop * Split message injection functionality * Remove interface, since it is not required not that we split the chat client. * Address conversation id propogation * Fix formatting issue
westey ·
2026-05-08 17:16:03 +00:00 -
.NET: Update FoundryAgent to address HostedAgents strict URL routing (#5677)
* .NET: Foundry agent-endpoint constructor uses ProjectOpenAIClient directly to fix hosted-agent URL routing Fixes the experimental FoundryAgent(Uri agentEndpoint, AuthenticationTokenProvider, ...) constructor so it actually works against Foundry hosted agents. The previous implementation routed through AzureAIProjectChatClient, which internally called aiProjectClient.GetProjectOpenAIClient().GetProjectResponsesClientForAgent(...). For an agent-endpoint URL of the canonical shape https://<host>/api/projects/<project>/agents/<agentName>/endpoint/protocols/openai the chain produced POST https://<host>/api/projects/<project>/openai/v1/responses (project-level path, no /agents/ segment). The Foundry service rejects this with HTTP 400 "Hosted agents can only be called through the agent endpoint: .../agents/<agentName>/endpoint/protocols/openai/responses". The constructor also extracted the agent name via agentEndpoint.Segments[^1].TrimEnd('/'), which returns "openai" (the last segment), not the agent name. What changed - Public ctor signature: clientOptions parameter type changed from AIProjectClientOptions? to ProjectOpenAIClientOptions?. The constructor is fundamentally building a ProjectOpenAIClient; accepting AIProjectClientOptions was a leaky abstraction whose translation silently dropped any pipeline policies the caller added via AddPolicy(...). With the direct type, caller policies pass through to the per-agent traffic verbatim. - Per-agent client construction: `new ProjectOpenAIClient(BearerTokenPolicy, ProjectOpenAIClientOptions)` with Endpoint and AgentName set, then `GetProjectResponsesClient().AsIChatClient()`. The SDK auto-appends ?api-version=v1 when AgentName is set. - New private static ParseAgentEndpoint helper: single source of truth for both agent-name extraction and project-root derivation. Tolerates trailing slash, case variants on /agents/ and the suffix segment, strips query/fragment, and throws ArgumentException with paramName=nameof(agentEndpoint) for malformed input. - Project-level client (used by CreateConversationSessionAsync) is built fresh from the derived project root with primitive properties copied (RetryPolicy/NetworkTimeout/Transport/UserAgentApplicationId) plus MEAI UA. - New GetService<ProjectOpenAIClient>() entry alongside the existing GetService<AIProjectClient>() (the latter returns null in agent-endpoint mode since no AIProjectClient is constructed on that path). - Endpoint and AgentName on caller-supplied ProjectOpenAIClientOptions are overridden by values derived from agentEndpoint. Compatibility - FoundryAgent is [Experimental(OPENAI001)]. No GA surface touched. The Foundry project does not maintain PublicAPI.*.txt baselines so there is no shipped baseline to update. - The Microsoft.Agents.AI.Foundry csproj pins Azure.AI.Projects to VersionOverride 2.1.0-beta.1 (matching what the IT and hosting projects already use); the central pin in Directory.Packages.props stays at 2.0.0. - WireClientHeaders from PR #5652 is invoked on the agent-endpoint path so per-call x-client-* headers behave identically across both ctors. Tests - 23 new unit tests in FoundryAgentTests.cs: - 12 for the agent-endpoint constructor (URL routing for non-streaming and streaming, conversations URL shape, MEAI UA stamping, caller-policy passthrough on the per-agent pipeline, Endpoint/AgentName override semantics, GetService matrix, ProjectOpenAIClient propagation, UserAgentApplicationId propagation, null-arg validation, ID/Name slug) - 9 for ParseAgentEndpoint (standard shape, trailing slash, casing, sovereign-cloud host without /api/projects/ literal prefix, special chars in agent name, query/fragment stripping, three negative cases) - 2 null-arg tests for the public ctor - All 250 Microsoft.Agents.AI.Foundry.UnitTests pass (was 221 baseline plus 29 from PR #5652 plus 23 new in this PR equals 273; pre-existing tests collapsed by the rebase merge keep the total at 250). - All 225 Microsoft.Agents.AI.Foundry.Hosting.UnitTests pass; no behavioral change to the hosting layer. - dotnet build clean across net8/9/10/netstandard2.0/net472 with TreatWarningsAsErrors=true. - dotnet format --verify-no-changes clean for the touched src and test projects. * .NET: Bump central Azure.AI.Projects pin to 2.1.0-beta.1 and flip Microsoft.Agents.AI.Foundry to preview Required to fix the NU1109 downgrade chain that broke CI on the agent-endpoint constructor rewire (#5677). Microsoft.Agents.AI.Foundry now depends on ProjectOpenAIClientOptions.AgentName and the (AuthenticationPolicy, options) constructor that only exist in Azure.AI.Projects 2.1.0-beta.1. Changes: * Directory.Packages.props: Azure.AI.Projects 2.0.0 -> 2.1.0-beta.1. * Microsoft.Agents.AI.Foundry.csproj: drop IsReleased=true so the package ships as preview (matches the beta SDK we now depend on). Add a comment noting the flip is temporary and should revert once Azure.AI.Projects ships a stable 2.1.0. * Drop redundant VersionOverride="2.1.0-beta.1" from the 10 csprojs that had it as a workaround; the central pin now suffices. Verified: * dotnet build agent-framework-dotnet.slnx --warnaserror clean across all TFMs. * Microsoft.Agents.AI.Foundry.UnitTests 250/250 pass. * Microsoft.Agents.AI.Foundry.Hosting.UnitTests 211/211 pass. * dotnet format --verify-no-changes clean for the touched src and test projects.Roger Barreto ·
2026-05-08 14:46:52 +00:00 -
westey ·
2026-05-08 09:28:35 +00:00 -
Jacob Alber ·
2026-05-08 00:17:44 +00:00 -
.NET: Fix function_call_output.output to be a JSON string on the wire (#5705)
* Fix function_call_output.output to be a JSON string on the wire OutputConverter was passing the JSON serialization of complex tool results (e.g. List<TodoItem>) directly into OutputItemFunctionToolCallOutput via BinaryData.FromString. The Responses SDK treats that BinaryData as the *raw JSON value* for the field, so non-string results landed on the wire as an unquoted JSON array (e.g. `"output":[{...}]`) instead of a JSON string. The OpenAI Responses spec requires `function_call_output.output` to be a JSON string. The strict-parsing OpenAI .NET client (FunctionCallOutputResponseItem) consequently failed when threading a follow-up turn that replayed such an item, with: `The JSON value could not be converted... requires an element of type 'String', but the target element has type 'Array'`. Always wrap the payload as a JSON string literal: - string s -> JSON-encode s (quoted, with escapes) - object o -> JSON-serialize o, then JSON-encode the resulting text Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR feedback: JsonElement special-case, symmetric inbound unwrap, tests OutputConverter: extract EncodeFunctionResultAsJsonStringPayload helper that special-cases JsonElement / JsonDocument so a string-kind element does not get double-encoded into "\"value\"". Other JsonElement kinds (object/array/number/bool) round-trip via GetRawText() and are then JSON-string-wrapped, matching the spec. InputConverter: symmetric DecodeFunctionResultPayload added to ConvertFunctionCallOutput and ConvertFunctionToolCallOutput so previously-stored function_call_output items replayed via previous_response_id unwrap back to the original tool result text instead of leaking the JSON-encoded form into FunctionResultContent.Result. Legacy non-conforming raw-JSON-value payloads pass through unchanged. Tests: - Replace ConvertUpdatesToEventsAsync_FunctionResultStringPayload_EmittedAsRawTextAsync with EmittedAsJsonStringAsync asserting the new wire contract ("sunny" -> "\"sunny\""). - Add coverage for object payloads, JsonElement string kind (no double-encoding), and JsonElement array kind (JSON-stringified). - Add InputConverter round-trip tests for spec-compliant JSON-string payloads and legacy raw-JSON-array payloads. All 663 tests pass on net8/net9/net10. Verified end-to-end against the local hosted-harness sample: T1-T4 (incl. TodoList tool replay across turns) all succeed with no SDK parse errors. 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>Ben Thomas ·
2026-05-07 23:27:57 +00:00 -
.NET: Mark Magentic Orchestration Experimental (#5704)
* fix: Mark Magentic Orchestration Experimental * Apply [Experimental] to all public Magentic types and suppress MAAIW001 in project Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/957a07c1-a805-40eb-989d-bd3425d4c0af Co-authored-by: lokitoth <6936551+lokitoth@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: lokitoth <6936551+lokitoth@users.noreply.github.com>
Jacob Alber ·
2026-05-07 22:54:01 +00:00 -
Fix typo:sesionEleme -> sessionElement (#5674)
Co-authored-by: Jacob Alber <jaalber@microsoft.com>
Hao-Xiong ·
2026-05-07 21:05:41 +00:00 -
fix(security): non-thread-safe sequence number generation may cau (#5320)
`SequenceNumber.Increment()` uses `this._sequenceNumber++` without synchronization. In concurrent streaming scenarios, this can produce race conditions and inconsistent sequencing, which may break event ordering guarantees and potentially allow response-mixing or state confusion. Affected files: SequenceNumber.cs Signed-off-by: tuanaiseo <221258316+tuanaiseo@users.noreply.github.com> Co-authored-by: Jacob Alber <jaalber@microsoft.com>
tuanaiseo ·
2026-05-07 20:42:49 +00:00 -
.NET: Python: Add dotnet integration test report to CI (#5515)
* Add dotnet integration test report to CI - Add --report-junit flag to dotnet integration test step to generate JUnit XML alongside TRX, with explicit --results-directory to centralize output in IntegrationTestResults/ - Upload JUnit XML artifacts from each matrix leg (net10.0/ubuntu, net472/windows) as dotnet-test-results-{framework}-{os} - Add dotnet-integration-test-report job that downloads artifacts, runs the existing aggregate.py script, posts markdown to Job Summary, and saves trend history via actions/cache - Refactor aggregate.py to discover JUnit XML files recursively, supporting both pytest (pytest.xml) and xunit (*.junit.xml) layouts - Handle provider name derivation for dotnet artifact naming convention - Fix nodeid collision when same test runs under multiple frameworks by qualifying keys with provider when collisions are detected - Improve module extraction for dotnet C# classnames (recognizes IntegrationTests/UnitTests namespace segments) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: trigger dotnet CI for report validation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: use .junit extension (not .junit.xml) for xunit v3 output xUnit v3 generates files with .junit extension, not .junit.xml. Update upload glob and aggregate.py discovery to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: use deterministic provider-qualified keys for dotnet tests Always prefix dotnet test keys with provider (e.g. net10.0 (ubuntu)::TestName) to ensure stable, comparable counts across runs regardless of file parse order. Also show Executed (passed+failed) instead of Total in summary table. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: match Python report summary format (Total, passed/total, etc.) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: split dotnet report into per-framework tables Dotnet tests run on multiple frameworks (net10.0, net472). Instead of one combined table with unstable totals, show separate sections per framework — each with its own summary row and per-test table. Python reports retain the original single-table format. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Re-enable 7 flaky dotnet integration tests with increased timeouts Increase timeouts to reduce timing-related flakiness in LLM-backed integration tests (issue #4971): - ExternalClientTests: 60s -> 120s default timeout - SamplesValidationBase: 60s -> 120s default timeout - ConsoleAppSamplesValidation: 90s -> 150s for long-running tests - AzureFunctions SamplesValidation: 2min -> 3min orchestration timeout, 60s -> 90s per-step WaitForConditionAsync timeouts Remove all Skip=Flaky annotations and unused SkipFlakyTimingTest constants. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Re-skip LLM non-determinism flaky tests, keep timeout fixes Re-skip SingleAgentOrchestrationHITLSampleValidationAsync and LongRunningToolsSampleValidationAsync - these fail due to LLM producing extra review notifications, not timeouts. Updated skip reasons to accurately describe the root cause. Reverted unnecessary timeout change on the skipped LongRunningTools test. The remaining 5 re-enabled tests with timeout increases are stable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enable Anthropic integration tests in CI Replace hardcoded skip with conditional skip pattern (matching CopilotStudio approach): tests gracefully skip when ANTHROPIC_API_KEY is missing, and run when present. Changes: - AnthropicChatCompletionFixture: try/catch in InitializeAsync with Assert.Skip on missing config (replaces hardcoded SkipReason) - AnthropicSkillsIntegrationTests: same pattern per test method - dotnet-build-and-test.yml: wire up ANTHROPIC_API_KEY, ANTHROPIC_CHAT_MODEL_NAME, and ANTHROPIC_REASONING_MODEL_NAME env vars to the integration test step Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix missing System using in AnthropicSkillsIntegrationTests Add 'using System;' for InvalidOperationException in try/catch blocks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Skip flaky SingleAgentOrchestrationChainingSampleValidationAsync LLM non-determinism causes Assert.NotNull failures on orchestration results. Skip until test logic is hardened against non-deterministic LLM responses. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Re-enable HITL and LongRunningTools tests with timeout and flexibility fixes - Remove Skip attribute from SingleAgentOrchestrationHITLSampleValidationAsync - Remove Skip attribute from LongRunningToolsSampleValidationAsync - Increase timeout from 120s/90s to 180s to accommodate 2+ LLM round-trips - Replace rigid 2-cycle assertion with flexible approval logic that handles extra review cycles from LLM non-determinism Fixes the two failure modes identified in #4971: 1. Timeout: 120s/90s was insufficient for multiple LLM calls under CI load 2. Extra notifications: Assert.Fail on 3rd+ review cycle was too rigid Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Increase AzureFunctions LongRunningTools test timeouts from 90s to 180s The LongRunningToolsSampleValidationAsync test in the AzureFunctions integration tests was failing in CI with TimeoutException at the 'Content published notification is logged' step. The 90-second timeouts are too tight for CI environments where LLM calls and orchestration overhead can be slow. Increased all three WaitForConditionAsync timeouts from 90s to 180s: - Waiting for human feedback notification - Waiting for publish notification (the step that was failing) - Waiting for orchestration completion Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Merge main and fix dotnet report path after flaky_report rename Merge upstream/main which renamed scripts/flaky_report/ to scripts/integration_test_report/ (from Python PR #5454). Update the dotnet-build-and-test workflow to reference the new path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add RetryFact to DurableTask and AzureFunctions integration tests These tests interact with LLMs via stdin/stdout (DurableTask) or HTTP (AzureFunctions) and are inherently non-deterministic. Unlike the Python side which uses pytest-retry, the dotnet tests had no retry mechanism and a single transient failure would fail the entire CI run. Changes: - Switch [Fact] to [RetryFact(2, 5000)] on all LLM-dependent tests across ConsoleAppSamplesValidation, ExternalClientTests, WorkflowConsoleAppSamplesValidation, and AzureFunctions SamplesValidation - Add re-prompt mechanism to LongRunningToolsSampleValidationAsync: if the LLM doesn't invoke the tool within 60s, re-send the prompt (up to 2 retries) instead of burning the full timeout - Reduce LongRunningTools timeout from 240s to 180s (re-prompt makes the extra buffer unnecessary) - Leave simple/deterministic tests as [Fact] (SingleAgent, unit tests) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add persist-credentials: false to Integration Test Report checkout step Matches the convention used by other checkout steps in this workflow to avoid leaving GITHUB_TOKEN credentials in the local git config. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * small fixes * disable anthropic failing tests --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Giles Odigwe ·
2026-05-07 20:39:32 +00:00 -
.NET: Foundry.Hosting IT: avoid MSB3026 in publish; fix telemetry UT flake (#5689)
CI publish step: gate the BuildProjectReferences=false fast-path on an explicit -UsePrebuiltProjectReferences switch (passed by the workflow) instead of marker detection. Adds a preflight error when stale obj/Release/net10.0 outputs would cause CS0579, with actionable recovery instructions. Telemetry UT flake: AgentFrameworkResponseHandlerTelemetryTests was using a plain List<Activity> for OTel's InMemoryExporter. The exporter writes from background Activity completion callbacks while parallel tests on the same global ActivitySource feed every listener, racing against the assertion's enumeration and throwing 'Collection was modified'. Replaced with a small thread-safe ConcurrentActivityList that locks add/enumerate and returns a snapshot for assertions.
Roger Barreto ·
2026-05-07 18:54:46 +00:00 -
.NET: feat: Implement Magentic Orchestration for .NET (#5595)
* feat: Implement Magentic Orchestration for .NET * fixup: Update for review comments * fix: Fix FenceJsonRegexPattern * fix: Format * fix: Updates for PR feedback * fix: Add missing serialized types to source gen for trimming * fix: Address PR Comments
Jacob Alber ·
2026-05-07 18:36:15 +00:00 -
.NET: feat: Update Github Copilot SDK to 1.0.0-beta.2 (#5699)
* feat: Update Github Copilot SDK to 1.0.0-beta.2 * Fix formatting Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * fix: Update for breaking changes in Github.Copilot.SDK * fix sample project * fix: whitespace formatting --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Jacob Alber ·
2026-05-07 19:15:10 +01:00 -
.NET: Support reasoning events in AGUI (#4953)
* Support reasoning * MEAI gives the same MessageId for reasoning and text content because they are part of the same logical model response. Create a new GUID for reasoning messages to be consistent with AGUI protocol and establish no link between reasoning and text messages * When a frontend AG-UI client sends conversation history back in a subsequent POST, any accumulated role: "reasoning" messages fail deserialization in AGUIMessageJsonConverter because the role wasn't handled - causing the request to fail. This adds AGUIReasoningMessage with Content and EncryptedValue properties, registers it in the JSON converter and serializer context, and converts it to TextReasoningContent (with ProtectedData) in AsChatMessages. * Added MapReasoningMessage - converts a ChatMessage containing TextReasoningContent to AGUIReasoningMessage for c# client * review * Support reasoning * MEAI gives the same MessageId for reasoning and text content because they are part of the same logical model response. Create a new GUID for reasoning messages to be consistent with AGUI protocol and establish no link between reasoning and text messages * When a frontend AG-UI client sends conversation history back in a subsequent POST, any accumulated role: "reasoning" messages fail deserialization in AGUIMessageJsonConverter because the role wasn't handled - causing the request to fail. This adds AGUIReasoningMessage with Content and EncryptedValue properties, registers it in the JSON converter and serializer context, and converts it to TextReasoningContent (with ProtectedData) in AsChatMessages. * Added MapReasoningMessage - converts a ChatMessage containing TextReasoningContent to AGUIReasoningMessage for c# client * review * dotnet format * Replace hardcoded string with constant Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: westey <164392973+westey-m@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Jeffin SIby ·
2026-05-07 15:09:04 +00:00 -
.NET: Issue 5662 (#5668)
* Fix dangling function_call on approval response in Foundry hosting (#5662) Make the wire<->AF approval translation in Microsoft.Agents.AI.Foundry.Hosting lossless so the resume turn pairs function_call/function_call_output correctly. Root cause: InputConverter.ConvertMcpApprovalResponse rebuilt FunctionCallContent with CallId set to the FICC-composed AF request id (ficc_<callId>) and Name hardcoded to 'mcp_approval'. This (a) broke Azure Conversations pairing because the persisted function_call had CallId <callId> without prefix, and (b) made FICC unable to invoke the original tool by name on resume. Fix: ToolApprovalIdMap now records the original FunctionCallContent (CallId, Name, Arguments) keyed by wire id at outbound time. InputConverter reconstructs the original FCC on inbound, falling back to the legacy placeholder when no mapping exists. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Suppress orphan function_call items at the wire (#5662) Foundry-Hosting's OutputConverter was emitting FunctionCallContent as wire `function_call` items while dropping the paired FunctionResultContent. The result: every auto-invoked tool call left an orphan `function_call` in the response store. The next turn (chained via previous_response_id or via a workflow that yields after one turn under externalLoop) reloaded that history and submitted it to Azure Conversations, which rejected it with HTTP 400 `No tool output found for function call ...`. Function call/result pairs are entirely internal to the agent's tool-calling loop and have no place on the wire. Approval-required calls already surface separately via ToolApprovalRequestContent → mcp_approval_request, so dropping FCC is safe. FCC's message-close behavior is preserved so pre-tool text doesn't accidentally concatenate with post-tool text under the same MessageId. Existing OutputConverter tests asserting FCC wire emission are updated to assert suppression. Verified end-to-end against the declarative-workflow-menu external_loop bench: three-turn previous_response_id chain (menu → carbonara price → EXIT) now completes, where it previously failed at turn 2 with HTTP 400. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fail fast when no approval mapping is recorded (#5662) The previous best-effort placeholder fallback in InputConverter.ConvertMcpApprovalResponse couldn't actually round-trip — it just delayed and obscured the failure as an HTTP 400 deep inside the agent loop. Throw InvalidOperationException with the wire id and a clear cause hint instead so the failure is local and actionable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Trim narrative comments and exception message (#5662) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Defer FunctionCallContent emission until matched FunctionResultContent (#5662) Replace blanket FCC suppression with deferred emission. FunctionCallContent is buffered (name + serialized arguments) keyed by CallId; the function_call and function_call_output wire items are only flushed once the matching FunctionResultContent arrives. - Auto-invoked FCC/FRC pairs surface as paired wire items so Azure's stored conversation has matched call+output and previous_response_id resume works (closes the orphan-function_call symptom from #5662). - Orphan FCCs (e.g. workflow paused at a checkpoint mid-tool-loop) are dropped so they never poison the response store. - Approval flows are unchanged: TARC still emits mcp_approval_request and the post-approval FRC has no buffered FCC to pair with so it is dropped; the approval round-trip handles its own pairing via mcp_approval_*. - Leaves the door open for future client-side function calling: that pattern would surface an FCC without an FRC, would need to opt out of buffering, but the wire shape is already correct. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Emit FunctionCallContent and FunctionResultContent directly (option B) Replace the deferred-emission/buffer-and-drop strategy with direct emission of both function_call and function_call_output wire items. Rationale: a lone FunctionCallContent in OutputConverter's input can mean two semantically different things, and only the caller knows which: - Auto-invoke (FICC response surface): always paired with a matching FRC; both halves should appear on the wire as historical record. - HITL / port-pause request (typed RequestPort<FunctionCallContent,...> or workflow synthesizing a request): a lone FCC IS the wire signal that the caller must resume by supplying a function_call_output. Buffering+dropping orphans silently swallows the second case. Emitting both directly is the only correct shape for OpenAI Responses semantics. The InputConverter already accepts function_call_output and mcp_approval_response on resume, so the round-trip works for both kinds. The approval-flow round-trip fixes (ToolApprovalIdMap rich ApprovalEntry, fail-fast on missing mapping in ConvertMcpApprovalResponse) remain intact. Tests: updated 7 OutputConverter tests + 1 OutputConverterWorkflow test that asserted the old buffer/drop semantics; all 227 tests pass. Refs #5662 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR #5668 review feedback on TryLoadMap Stop swallowing JsonException in ToolApprovalIdMap.TryLoadMap. The catch block recovered to an empty map and a stale comment claimed the caller would gracefully degrade via a 'wire-id fallback path' — but that path no longer exists: InputConverter.ConvertMcpApprovalResponse fails fast when no entry is found. Letting the JsonException propagate produces an error message that points at the actual cause (a state-bag format incompatibility), instead of converting it into a confusing 'no approval mapping recorded' InvalidOperationException one stack frame later. Refs #5662, PR #5668 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR #5668 review feedback round 2 - OutputConverter FRC: emit string results as raw text (no JSON-quoting), matching the wire contract for function_call_output.output. - OutputConverter FCC: validate non-empty CallId before closing the in-flight text message, so a skipped FCC no longer breaks output-item boundaries. - ToolApprovalIdMap.Record: take pre-serialized arguments JSON (string) and primitive callId/name. Drops [RequiresUnreferencedCode]/[RequiresDynamicCode] so trim/AOT warnings stop propagating to call sites. - ToolApprovalIdMap.Record: no-op when callId or name is empty. - Tests: dedup duplicate ConvertItemsToMessages_McpApprovalResponse no-mapping test; add coverage for empty-CallId boundary, raw-string FRC payload, and Record empty-key no-op. 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>
Ben Thomas ·
2026-05-07 00:30:41 +00:00 -
.NET: Add Foundry.Hosting.IntegrationTests (#5598)
* Foundry.Hosting.IntegrationTests: scaffold project, fixtures, and 24 tests Add a new integration test project for Foundry hosted agents alongside the existing Foundry.IntegrationTests project. The project provisions a real Foundry hosted agent per scenario via AgentAdministrationClient.CreateAgentVersionAsync, points it at a single test container image (built and pushed out of band by scripts/it-build-image.ps1 in a follow up commit), and exercises the agent through AIProjectClient.AsAIAgent. Six scenario fixtures are introduced, each pointing at the same image but selecting behavior via the IT_SCENARIO environment variable on the HostedAgentDefinition: - HappyPathHostedAgentFixture (round trip, multi turn, stored=false flag) - ToolCallingHostedAgentFixture (server side AIFunctions) - ToolCallingApprovalHostedAgentFixture (approval flow) - ToolboxHostedAgentFixture (Foundry toolbox) - McpToolboxHostedAgentFixture (MCP backed toolbox) - CustomStorageHostedAgentFixture (custom storage provider) 24 tests across 6 test classes are scaffolded. All are tagged Skip pending the test container build and the end to end smoke iteration in follow up commits. Once the container is in place the Skip annotations can be removed scenario by scenario. Adds an IT_HOSTED_AGENT_IMAGE constant to the shared TestSettings so every IT project agrees on the env var name the build script emits. * Foundry.Hosting.IntegrationTests: add TestContainer, build script, slnx, README Adds the rest of the integration test infrastructure on top of the previous scaffolding commit: * Foundry.Hosting.IntegrationTests.TestContainer csproj and Program.cs implementing the multi scenario container (one image, IT_SCENARIO env var dispatches between happy-path, tool-calling, tool-calling-approval, toolbox, mcp-toolbox, and custom-storage). The toolbox, mcp-toolbox, and custom-storage branches are placeholders pending API surface stabilization. * Dockerfile and dockerignore in the test container project, using the contributor pattern matching the investigation work (host side dotnet publish, container only does COPY out/). * scripts/it-build-image.ps1 with mandatory Registry parameter (no hardcoded ACR), content hashed tags so unchanged source results in a no op push, and emits IT_HOSTED_AGENT_IMAGE for shells and CI to consume. * slnx entry for both new projects. * README in the IT project covering env vars, image build, scenario table, and current placeholder status. Steps still pending: end to end smoke (step 5) and CI workflow integration (step 6) require a live Foundry deployment and ACR push, so they land in follow up commits. * Foundry.Hosting.IntegrationTests: address PR 5598 review feedback Fix issues raised by Copilot review: * it-build-image.ps1: hash file contents, not the path list, so any source edit produces a fresh tag. Normalize Registry input by stripping scheme and trailing slash before deriving the ACR short name. Validate the short name is non empty. * HostedAgentFixture: route GetAgentAsync through _adminClient (which has the FoundryFeaturesPolicy attached) instead of through _projectClient.AgentAdministrationClient (which does not). * HostedAgentFixture FoundryFeaturesPolicy: replace Headers.Add with Remove plus Add so retries cannot accumulate duplicate headers. * HappyPath, ToolCalling, ToolCallingApproval, CustomStorage tests: create the AgentSession before turn 1 and reuse it for both turns. The previous pattern created the session after turn 1 so turn 2 had no link to turn 1, defeating the multi turn assertion. * .NET: Foundry.Hosting.IntegrationTests: constrain to net10.0 + dotnet format autofix - Set <TargetFrameworks>net10.0</TargetFrameworks>: the project references both Microsoft.Agents.AI.Foundry.Hosting (net8/9/10 only) and AgentConformance.IntegrationTests (net10.0;net472 — inherits the tests-default TFM list). The intersection is net10.0; the previous $(TargetFrameworksCore) triple caused NU1702 + System.Text.Json version conflicts on the net8.0/net9.0 builds because AgentConformance had no matching asset. - Apply `dotnet format` autofix on the test files (IDE0005, IDE0009, IDE0032, IMPORTS). * .NET: Foundry.Hosting.IntegrationTests.TestContainer/Program.cs: add UTF-8 BOM CI's check-format requires charset=utf-8-bom per .editorconfig. * Foundry.Hosting IntegrationTests: wire end-to-end CI flow against hosted agents Make the integration tests usable end-to-end against a live Foundry deployment, including a per-run rebuild of the test container so framework code changes are exercised. Fixture (HostedAgentFixture.cs) * Switch from per-run unique agent names to stable scenario-keyed names (it-happy-path, it-tool-calling, ...). The agent's managed identity carries the Azure AI User role on the project scope, which is required for inbound inference; deleting the agent recycles the MI and breaks that role assignment, so we keep the agent across runs and only churn versions. * Add IT_RUN_ID env var to defeat Foundry's content-addressed version dedup; otherwise a rerun just receives the existing version and Dispose deletes it. * PATCH the per-agent endpoint with AgentEndpointConfig (Responses protocol, version selector at 100% to the new version). Without this, /agents/{name}/endpoint/protocols/ openai/responses returns HTTP 400. * Build a per-agent ProjectOpenAIClient (not the cached projectClient.ProjectOpenAIClient, which is bound to the project-level URL); set AgentName in options so the URL routes through the agent endpoint, and add the Foundry-Features header to the inference pipeline. * Use Versions (which serializes to container_protocol_versions) instead of the deprecated ProtocolVersions; the server now rejects the legacy field. * On Dispose, delete only the version this fixture created. Never delete the agent. Tests * Tag every HostedAgentTests class with [Trait("Category", "FoundryHostedAgents")] so the CI workflow can route them to a separate Foundry project than the rest of the integration suite. CI workflow (.github/workflows/dotnet-build-and-test.yml) * Add a foundryHosting paths-filter covering Microsoft.Agents.AI.Foundry.Hosting and its in-repo dependency chain (Foundry, Agents.AI, Agents.AI.Abstractions), the test container, the test fixture, Directory.Packages.props, the build script, and this workflow file. Skip the costly hosted-agent steps when none of those changed. * Add "Build and push Foundry Hosted Agents test container" step that invokes scripts/it-build-image.ps1 against vars.IT_HOSTED_AGENT_REGISTRY and pipes the resulting IT_HOSTED_AGENT_IMAGE=<tag> into GITHUB_ENV. * Add "Run Foundry Hosted Agents Integration Tests" step that filters in only the new trait, with AZURE_AI_PROJECT_ENDPOINT/AZURE_AI_MODEL_DEPLOYMENT_NAME pointed at IT_HOSTED_AGENT_PROJECT_ENDPOINT/IT_HOSTED_AGENT_MODEL_DEPLOYMENT_NAME (Tao project, East US 2; the SK IT project's region does not yet support hosted agents preview). * Exclude the new trait from the existing "Run Integration Tests" step. * TEMP: drop the != 'pull_request' guard on the new steps and on Azure CLI Login when the paths-filter triggers, so PR #5598 can validate the wiring before promoting to merge queue only. Restore the original guard after one green PR run. Build script (scripts/it-build-image.ps1) * Hash now spans TestContainer source AND its referenced framework projects so any framework code change forces a fresh tag and a real docker push; the previous TestContainer-only hash silently reused stale images on framework edits. Bootstrap script (dotnet/tests/Foundry.Hosting.IntegrationTests/scripts/it-bootstrap-agents.ps1) * New idempotent script that creates the six stable scenario agents and grants Azure AI User on the project scope to each agent's MI. Run once per Foundry project. Includes AAD-graph propagation retries because newly created MIs take time to appear there. README (dotnet/tests/Foundry.Hosting.IntegrationTests/README.md) * Document the bootstrap prerequisite, the regional caveat (East US 2 is the only region we have validated; East US returned "Unsupported region" at the time of writing), the per-run image rebuild, and the CI wiring including the SP RBAC requirements. SDK pin (TEMP) * Bump Microsoft.Agents.AI.Foundry.Hosting's Azure.AI.Projects VersionOverride to 2.1.0-alpha.20260505.1 from the azure-sdk public daily feed (added to nuget.config). This release is the first that builds the per-agent inference URL as /agents/{name}/endpoint/protocols/openai (the 2.1.0-beta.1 release builds .../openai/openai/v1, which the server rejects). Revert both the feed and the override once the URL fix lands in a stable Azure.AI.Projects release. * Foundry.Hosting IntegrationTests: revert alpha SDK pin; move endpoint PATCH to bootstrap The alpha SDK pin (Azure.AI.Projects 2.1.0-alpha.20260505.1 from the azure-sdk public daily feed) was needed only for the URL routing fix and the strongly-typed AgentEndpointConfig/PatchAgentOptions wrapper. We do not need either right now: the fixture stays compatible with the public 2.1.0-beta.1 by moving the one-time endpoint PATCH to the bootstrap script (it sets version_selector to FixedRatio @latest, so each new fixture run becomes the served version automatically without a per-run PATCH from the test code). The hosted-agent invocation path will start working end-to-end once the URL routing fix lands in a stable Azure.AI.Projects release; until then the tests stay [Fact(Skip = ...)] as documented. * Revert dotnet/nuget.config: drop the azure-sdk-for-net public feed. * Revert Microsoft.Agents.AI.Foundry.Hosting.csproj VersionOverride to 2.1.0-beta.1. * Revert Microsoft.Agents.AI.Foundry.UnitTests and Microsoft.Agents.AI.Foundry.Hosting.UnitTests Azure.AI.Projects pin (they had been bumped to align Azure.Core 1.54 transitive). * Drop the AgentEndpointConfig PATCH block from HostedAgentFixture.cs (the type is alpha-only). Replace with a comment pointing at the bootstrap script. * Bootstrap script (it-bootstrap-agents.ps1) now also PATCHes each agent's endpoint with version_selector=@latest if not already set. Idempotent. * Foundry.Hosting IntegrationTests: drop accidentally committed filtered.slnx * Foundry.Hosting IntegrationTests: revert TEMP PR override on Azure CLI Login + IT steps The previous attempt to validate the new hosted-agent IT wiring on PR #5598 failed because the PR is from a fork (rogerbarreto/agent-framework-public). GitHub never passes environment secrets to fork PRs regardless of event-name guards on individual steps, so 'azure/login@v2' fails with 'client-id and tenant-id are not supplied'. Restore the original github.event_name != 'pull_request' guard. The new steps will execute on push to main and on merge_group runs. * Foundry.Hosting IntegrationTests: invoke build-and-push script with absolute path The pwsh shell on the GitHub Actions runner couldn't resolve ./scripts/it-build-image.ps1 when the step had no working-directory set; the step inherits the runner's PWD which is not always the repo root after preceding steps. Use github.workspace explicitly to remove the ambiguity. * Foundry.Hosting IntegrationTests: move it-build-image.ps1 inside the IT project tree The previous location at scripts/it-build-image.ps1 lived outside the sparse-checkout paths the workflow uses (.github, dotnet, python, declarative-agents), so the runner never had the file when the new step tried to invoke it. Move the script next to its sibling it-bootstrap-agents.ps1 inside the IT project tree, and anchor its relative paths to the repo root via so callers can invoke it from any PWD. * Move scripts/it-build-image.ps1 -> dotnet/tests/Foundry.Hosting.IntegrationTests/scripts/it-build-image.ps1 * Add Push-Location to the resolved repo root inside the script (Pop-Location in finally) so the existing relative paths (TestContainerProject, hashed src dirs) keep working no matter where the script is invoked from. * Update the workflow path filter and the step's invocation path to the new location. * Foundry.Hosting IntegrationTests: enable 5 HappyPath tests on the live Foundry endpoint The fixture already constructs ProjectOpenAIClient via the per-agent path that beta.1 supports (new ProjectOpenAIClient(uri, cred, opts { AgentName })), so no SDK pin bump is required to run the smoke tests end-to-end. Un-skip the 5 tests that pass against the live test container. Tests un-skipped (verified passing locally against tao-foundry-prj): * RunAsync_ReturnsNonEmptyTextAsync * RunStreamingAsync_YieldsAtLeastOneUpdateAsync * MultiTurn_WithPreviousResponseId_PreservesContextAsync * StoredFalse_Baseline_DoesNotPersistResponseAsync * Instructions_FromContainerDefinition_AreObeyedAsync Tests still skipped with a more specific reason (4 of 9 in HappyPath plus all ToolCalling*, McpToolbox, Toolbox, CustomStorage) because the test container does not yet emit usable response_id / conversation_id chains, and the placeholder scenarios are not implemented in the test container's Program.cs. These are test container limitations, not infra bugs, and can be un-skipped as the container surfaces stabilize. * Foundry.Hosting IntegrationTests: extract hosted IT into parallel job, add Workflows dep Address Wesley's review feedback on PR #5598: 1. Pull Foundry hosted-agent IT into its own dotnet-foundry-hosted-it job that runs in parallel to dotnet-build and dotnet-test. Same path-filter gate keeps it skipped on unrelated edits. Builds only the filtered solution containing Foundry.Hosting.IntegrationTests and src deps. dotnet-build-and-test-check now waits on it too. 2. Add Microsoft.Agents.AI.Workflows to the foundryHosting paths-filter and to hashedDirs in it-build-image.ps1 since Foundry.Hosting transitively depends on it. TFM constraint on the IT csproj stays at net10.0 because AgentConformance.IntegrationTests targets net10/net472 and is consumed by ~12 other IT projects on net472. --------- Co-authored-by: Roger Barreto <rbarreto@microsoft.com>Roger Barreto ·
2026-05-06 16:08:15 +00:00 -
.NET: Fix flaky declarative test (#5669)
* Fix flaky declarative test * Addressed host gating and guid parsing concerns in test file.
Peter Ibekwe ·
2026-05-06 15:07:23 +00:00 -
.NET: Bump MEAI to 10.5.1 and add Foundry per-call x-client header support (#5652)
* Bump MEAI to 10.5.1 and add per-call x-client header support Replaces the brittle UserAgentResponsesClient subclass with a clean per-call x-client-* header pipeline built on the new Microsoft.Extensions.AI 10.5.1 OpenAIRequestPolicies hook. Public surface (Microsoft.Agents.AI.Foundry, [Experimental(MAAI001)]): * chatOptions.WithClientHeader(name, value) and .WithClientHeaders(IEnumerable) validate the x-client- prefix (case-insensitive), apply all-or-nothing on bulk, and throw InvalidOperationException on foreign-typed slot collision * myAgent.AsBuilder().UseClientHeaders().Build() opts a customer-built agent into the pipeline; idempotent via agent.GetService<ClientHeadersAgent>() * Foundry-built agents (FoundryAgent.Create*) pre-wire automatically Internals: * ClientHeadersAgent decorator snapshots the dict at scope-push time so concurrent runs sharing a ChatOptions reference do not leak headers * ClientHeadersScope is an AsyncLocal<IReadOnlyDictionary<string,string>?> with LIFO push/dispose semantics * ClientHeadersPolicy singleton stamps headers via Headers.Set so per-call values overwrite any same-name header from earlier policies and so duplicate registration is value-stable * OpenAIRequestPoliciesReflection dedups against MEAI's private _entries field and falls back to AddPolicy on any reflection failure; a CI test asserts the field shape on every MEAI bump Hosting cleanup: * Deleted UserAgentResponsesClient and its dummy throwing pipeline * HostedAgentUserAgentPolicy is now registered via OpenAIRequestPolicies in FoundryHostingExtensions.TryApplyUserAgent Tests: * 19 new unit tests in ClientHeadersExtensionsTests.cs covering validation, AsyncLocal isolation, snapshot semantics, end-to-end wire stamping, and shared-chat-client dedup * Updated OpenTelemetryAgentTests for MEAI 10.5.1 changes to web_search serialization and the reduced tool definition payload when sensitive data capture is disabled Microsoft.Extensions.Compliance.Abstractions stays at 10.5.0 because no 10.5.1 release exists on nuget.org. * Address PR review: pre-wire AsAIAgent path and dedup TryApplyUserAgent * FoundryAgent: extract WireClientHeaders helper and call it from the internal (AIProjectClient, ChatClientAgent) constructor used by AzureAIProjectChatClientExtensions.AsAIAgent so those Foundry-built agents also pre-wire the x-client header pipeline. * Foundry.Hosting TryApplyUserAgent: dedup HostedAgentUserAgentPolicy registration per OpenAIRequestPolicies instance via ConditionalWeakTable so per-request resolution does not grow the policy list unboundedly on singleton agents. * Add tests covering AsAIAgent pre-wire and TryApplyUserAgent dedup Backs the PR review fixes from
a4c8f91with regression tests: * ClientHeadersExtensionsTests: AsAIAgent_FoundryAgent_HasPreWiredClientHeadersAgent asserts the FoundryAgent built via AzureAIProjectChatClientExtensions.AsAIAgent contains a ClientHeadersAgent in its delegating chain (catches future regressions of the bypass). * ClientHeadersExtensionsTests: FoundryAgent_PublicConstructor_HasPreWiredClientHeadersAgent covers the public constructor path the same way. * ClientHeadersExtensionsTests: UseClientHeaders_RepeatedRegistrations_OnSameChatClient_OnlyRegistersOnce invokes UseClientHeaders 25 times on a shared chat client and asserts via reflection that OpenAIRequestPolicies._entries length is exactly 1. * HostedTryApplyUserAgentDedupTests: two tests asserting FoundryHostingExtensions.TryApplyUserAgent stays at one entry per OpenAIRequestPolicies instance after 50 calls on the same agent and across distinct agents on different chat clients. * Move tests next to their SUT Removes the dedicated HostedTryApplyUserAgentDedupTests.cs test class. Tests are co-located with the SUT they exercise: * FoundryAgentTests.cs gains the Constructor_PreWiresClientHeadersAgent and Constructor_FromAsAIAgentExtension_PreWiresClientHeadersAgent cases, since FoundryAgent is the SUT for the pre-wire behavior. * HostedOutboundUserAgentTests.cs gains the two TryApplyUserAgent dedup cases, since FoundryHostingExtensions.TryApplyUserAgent is the SUT it already covers. * ClientHeadersExtensionsTests.cs keeps only the UseClientHeaders_RepeatedRegistrations_OnSameChatClient_OnlyRegistersOnce case, which exercises the public ClientHeadersExtensions surface. * Remove redundant WithCancellation on inner streaming call ct is already passed to InnerAgent.RunStreamingAsync, so .WithCancellation(ct) on the resulting IAsyncEnumerable is a no-op. Caught by Sergey on PR review. * Address PR review: surface downstream MEAI experimental ID * Add AIOpenAIRequestPolicies = MEAIExperiments alias to DiagnosticIds.Experiments (matches the existing AIResponseContinuations, AIMcpServers, AIFunctionApprovals pattern). * Mark public ClientHeadersExtensions with [Experimental(AIOpenAIRequestPolicies)] instead of AgentsAIExperiments. Consumers now see the MEAI001 warning, surfacing the dependency on MEAI's experimental OpenAIRequestPolicies hook. * Mark internal OpenAIRequestPoliciesReflection with the same alias to suppress warnings at the source rather than via project-wide NoWarn. * Remove MEAI001 from Foundry csproj NoWarn (kept on Foundry.Hosting where pre-PR usages remain). * Clarify ClientHeadersScope XML doc: AsyncLocal flows values forward but does NOT auto-restore on method return; explicit using/Dispose is what gives stack-style LIFO semantics.Roger Barreto ·
2026-05-06 14:43:08 +00:00 -
.NET: Add hosted agent observability sample (#5660)
* .Net: Add hosted agent observability sample Mirrors the Python sample added in #5608 for Foundry hosted agents. The .NET hosting library already wires OpenTelemetry automatically via Microsoft.Agents.AI.Foundry.Hosting (ApplyOpenTelemetry) plus Azure.AI.AgentServer.Core's AddAgentHostTelemetry, so no framework changes are needed. The sample is documentation plus a runnable artifact that produces an interesting span tree (invoke_agent / agent_invoke / chat / execute_tool). Adds Hosted-Observability under FoundryHostedAgents/responses with two small tools (GetCurrentLocation, GetWeather), agent.yaml / agent.manifest.yaml declaring OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT (the .NET equivalent of Python's ENABLE_SENSITIVE_DATA), Dockerfile + Dockerfile.contributor, .env.example and README explaining the .NET vs Python defaults. Project added to agent-framework-dotnet.slnx. * Address PR feedback: use Random.Shared and add .dockerignore
Roger Barreto ·
2026-05-06 08:33:16 +00:00 -
.NET: Fix YAML block scalar parsing for file skills (#5610)
* Fix YAML block scalar parsing for file skills * Address block scalar parsing review feedback
Teja Kusireddy ·
2026-05-05 16:32:05 +00:00 -
.NET: Fix QuestionExecutor looping after GotoAction re-entry in declarative workflows (#5635)
* Fix QuestionExecutor looping after GotoAction re-entry in declarative workflows * Addressed failing integration test and promptcount
Peter Ibekwe ·
2026-05-05 15:53:31 +00:00 -
Jacob Alber ·
2026-05-05 15:45:49 +00:00 -
fix: JSON Serialization issue with MultiPartyConversation (#5653)
When MultiPartyConversation gets saved during checkpointing, the data for the chat history is not persisted, resulting in failures to deserialize after. The fix is to make the history visible to the source generated serialization code.
Jacob Alber ·
2026-05-05 15:36:05 +00:00 -
.NET: Improve Todo multithreading and inject todos into message list (#5655)
* Improve Todo multithreading and inject todos into message list * Address PR comments
westey ·
2026-05-05 15:21:51 +00:00 -
.NET: Add allow listing for WebBrowsingTool (#5605)
* Add allow listing for WebBrowsingTool * Address PR comments.
westey ·
2026-05-05 15:20:55 +00:00 -
.NET: feat: Implement message filtering to exclude non-portable content typ… (#5410)
* feat: Implement message filtering to exclude non-portable content types before forwarding Co-authored-by: Copilot <copilot@github.com> * Added unit tests to cover forwarded message filtering within AI Agent executors Co-authored-by: Copilot <copilot@github.com> * Update dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/AIAgentHostExecutor.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/AIAgentHostExecutor.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/src/Microsoft.Agents.AI.Workflows/Specialized/AIAgentHostExecutor.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * fix: Disable forwarding of incoming messages in AIAgentHostExecutor tests Co-authored-by: Copilot <copilot@github.com> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Jacob Alber <jaalber@microsoft.com>
Taylor Rockey ·
2026-05-05 14:43:45 +00:00 -
.NET: Add Microsoft.Agents.AI.Hyperlight package for CodeAct integration (.NET) (#5329)
* Add Microsoft.Agents.AI.Hyperlight package for CodeAct integration Introduces a new Microsoft.Agents.AI.Hyperlight package that enables CodeAct-style sandboxed code execution via Hyperlight (hyperlight-sandbox .NET SDK, PR #46) for .NET agents, following the docs/features/code_act/dotnet-implementation.md design and the Python agent_framework_hyperlight reference. Highlights: - HyperlightCodeActProvider (AIContextProvider): injects an execute_code tool and CodeAct guidance per invocation; single-instance-per-agent via a fixed StateKeys value; supports multiple provider-owned tools (exposed inside the sandbox via call_tool), file mounts, and an outbound domain allow-list; snapshot/restore per run. - HyperlightExecuteCodeFunction: standalone AIFunction for manual/static wiring when the sandbox configuration is fixed. - Approval model via CodeActApprovalMode (AlwaysRequire / NeverRequire) with propagation from ApprovalRequiredAIFunction-wrapped tools. - Unit tests (instruction builder, tool bridge, approval computation, provider CRUD, ProvideAIContextAsync snapshot isolation and approval wrapping). - Env-gated integration test (HYPERLIGHT_PYTHON_GUEST_PATH). - Three samples under samples/02-agents/AgentWithCodeAct (interpreter, tool-enabled, manual wiring). Build is not yet runnable: requires .NET SDK 10.0.200 and the not-yet-published HyperlightSandbox.Api 0.1.0-preview NuGet package. Package is marked IsPackable=false until the dependency is available. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR #5329 review feedback for Hyperlight CodeAct provider - A. Build-breakers: drop unused usings, override test TargetFrameworks off net472, drop redundant Microsoft.Extensions.AI.Abstractions PackageRef. - B. API: keep CRUD but rebuild sandbox when config fingerprint changes; add HyperlightCodeActProviderOptions.CreateForWasm/CreateForJavaScript factory methods (Backend/ModulePath now read-only); rename WorkspaceRoot to HostInputDirectory; convert AllowedDomain & FileMount from record to sealed class; drop ToolBridge.Unwrap (ApprovalRequiredAIFunction is invocable as-is). - C. ToolBridge: collapse SerializeResult switch; add comment explaining AOT-driven choice to keep JsonNode.Parse over typed Deserialize. - D. InstructionBuilder: drop language-specific 'Python code' phrasing; strip host filesystem paths from execute_code description. - E. Style polish: ternary expression-body for ComputeApprovalRequired, .Where(x is not null), .ToList() over .ToArray() in IReadOnlyList returns. - F. Samples: add guest-module / KVM-WHP build instructions to Step01; note future Excel-upload sample in Step02. Also adds SandboxExecutorTests covering the new RunSnapshot.ComputeFingerprint used for sandbox-rebuild detection. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Align Hyperlight package id and JS warm-up with merged upstream SDK The .NET SDK in hyperlight-dev/hyperlight-sandbox PR #46 has merged. The published package id is Hyperlight.HyperlightSandbox.Api (the bare HyperlightSandbox.Api remains the assembly/namespace) and the reference CodeExecutionTool uses 'void 0;' as the JavaScript warm-up no-op. Update the package reference, project comment, README, and SandboxExecutor warm-up accordingly. No functional change beyond that — all other public APIs we depend on (SandboxBuilder.With*, Sandbox.Run/RegisterToolAsync/AllowDomain/Snapshot/ Restore, ExecutionResult, SandboxBackend) match the merged shape. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump Hyperlight package to 0.4.0 and fix build/test issues Hyperlight.HyperlightSandbox.Api 0.4.0 is now published on nuget.org. Bump the version reference and address the analyzer/runtime issues that surfaced once restore could complete: - Add HyperlightJsonContext source-generated JsonSerializerContext for the execute_code result + tool error envelopes; route arbitrary AIFunction results through AIJsonUtilities.DefaultOptions to keep IsAotCompatible=true. - Replace explicit ObjectDisposedException throws with ObjectDisposedException.ThrowIf (CA1513). - Use HyperlightSandbox.Api.SandboxBackend in cref docs to disambiguate. - Update tests to match AIContext.Tools being IEnumerable<AITool>, drop ConfigureAwait(false) in xUnit test methods (xUnit1030), use collection expressions for AllowedDomain methods. - Add 'using OpenAI.Chat;' to all three samples so AsAIAgent resolves. - Verified: dotnet build of all four hyperlight projects + samples succeeds on net8/9/10; dotnet test for the unit tests passes 32/32 on net10.0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix CI check failures: file encoding (UTF-8 BOM + LF) and broken markdown link - Convert all new .cs/.csproj files to UTF-8 with BOM and LF line endings to satisfy the dotnet/.editorconfig charset/end_of_line settings enforced by check-format. - Drop unused System.Collections.Generic using in HyperlightCodeActProviderTests. - Add missing using Microsoft.Extensions.AI in CodeActApprovalMode.cs and shorten ApprovalRequiredAIFunction cref (IDE0001). - Fix broken README link to docs/decisions/0024-codeact-integration.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: AIFunction inheritance, packaging, GetService approval check - HyperlightExecuteCodeFunction now inherits AIFunction directly. The AsAIFunction() indirection is gone; instances are accepted anywhere an AIFunction is. Approval requirement is surfaced via GetService<ApprovalRequiredAIFunction>() which lazily exposes a wrapping ApprovalRequiredAIFunction proxy when the effective ApprovalMode/tool stack requires it. - ComputeApprovalRequired now uses GetService<ApprovalRequiredAIFunction>() so approval-required tools nested anywhere in the AITool decorator stack are detected (not just the top-most class). - csproj: drop IsPackable=false (ready to release with the published Hyperlight.HyperlightSandbox.Api 0.4.0 dependency); add PackageReadmeFile and pack README.md at the package root, matching the pattern used by Aspire.Hosting.AgentFramework.DevUI / Microsoft.Agents.AI.DurableTask. - Update Step03 sample and README wording to reflect direct AIFunction usage. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Eduard van Valkenburg ·
2026-05-05 12:56:24 +00:00 -
westey ·
2026-05-05 09:23:36 +00:00 -
.NET: Hosting updates to declarative workflows (#5589)
* Make DeclarativeWorkflowExecutor ChatProtocol-compatible for AsAIAgent hosting Extends the existing DeclarativeWorkflowExecutor<TInput> root executor with additional ChatProtocol-compatible input routes (string, ChatMessage, IEnumerable<ChatMessage>, ChatMessage[], TurnToken) so that workflows built via DeclarativeWorkflowBuilder.Build<TInput>(...) work both for direct invocation and when hosted via Workflow.AsAIAgent(...). - Each input message advances the declarative graph immediately; the TurnToken that the host sends after the message batch is treated as a no-op since the message has already been processed. - Conversation id resolution now prefers persisted workflow system state, then DeclarativeWorkflowOptions.ConversationId, then a newly created conversation. This makes multi-turn invocations reuse the prior conversation rather than creating a fresh one each turn. - The separate DeclarativeChatProtocolStartExecutor and DeclarativeWorkflowBuilder.BuildChatProtocol overloads introduced earlier are removed; callers continue to use Build<TInput>(...). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: use DeclarativeWorkflowContext when reading workflow conversation id GetWorkflowConversation() requires a DeclarativeWorkflowContext (it calls ReadState which dynamic-casts via the DeclarativeContext helper). The chat-protocol auxiliary handlers receive a BoundWorkflowContext, so calling the extension on the raw IWorkflowContext throws `Invalid workflow context: BoundWorkflowContext`. Use the wrapped declarativeContext that we already constructed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: surface ExecutorFailedEvent as ErrorContent in AsAIAgent response WorkflowSession.InvokeStageAsync only converted WorkflowErrorEvent into an ErrorContent payload. ExecutorFailedEvent fell through to the default branch which emits an empty AgentResponseUpdate carrying the event in RawRepresentation. OutputConverter then mapped that to a workflow_action item with status=failed and dropped the exception entirely, so callers got status=completed and error=null even when an executor threw. - WorkflowSession.cs: add ExecutorFailedEvent case mirroring WorkflowErrorEvent. Honors _includeExceptionDetails. - OutputConverter.cs: when an update carries both a WorkflowEvent in RawRepresentation and non-empty Contents, fall through to content processing so the unwrapped error (or any future content payload from a workflow event) is actually emitted. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * improve: walk inner exceptions when surfacing ExecutorFailedEvent DeclarativeActionExecutor wraps inner exceptions in DeclarativeActionException with a generic `Unhandled workflow failure` message, hiding the real cause. Walk InnerException so the response shows the full chain (e.g. the underlying HTTP 400 / auth error). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Surface declarative SendActivity output as chat content SendActivityExecutor now emits AgentResponseEvent in addition to MessageActivityEvent so chat protocols (e.g. AsAIAgent) receive the formatted activity text. The existing MessageActivityEvent is preserved for DevUI/observability. Also extend WorkflowSession.WorkflowOutputEvent handling to accept AgentResponse payloads, mapping them to their constituent ChatMessages. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Persist hosted-agent sessions to disk; fix System.LastMessageText Adds FileSystemAgentSessionStore that writes the serialized AgentSession JSON (which already embeds the workflow's in-memory checkpoint manager) to a per- conversation file under /.checkpoints when running in a Foundry hosted env or {cwd}/.checkpoints locally. Mirrors the python foundry_hosting._responses FileCheckpointStorage pattern so multi-turn workflow state survives process restarts without requiring callers to wire up storage themselves. AddFoundryResponses now defaults to FileSystemAgentSessionStore.CreateDefault() instead of InMemoryAgentSessionStore; callers can still override via DI. Also fixes {System.LastMessageText} resolving empty: DeclarativeWorkflowExecutor .AdvanceAsync was passing the message rehydrated from CreateMessageAsync to SetLastMessageAsync, but ResponseItem -> ChatMessage round-trip drops the .Text extension content. Use the original input ChatMessage (which still has the user-supplied text) and copy the server-assigned MessageId across when present. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Close multi-modal input parity gaps with python foundry_hosting InputConverter now mirrors the python _responses.py content handling: - ComputerScreenshotContent maps to UriContent/HostedFileContent (was dropped). - Plain TextContent and SummaryTextContent map to MEAI TextContent. - MessageContentReasoningTextContent maps to MEAI TextReasoningContent. - input_file with text/* file_data data URIs is decoded inline into TextContent with a [File: name] prefix, matching python _convert_file_data so {System.LastMessageText} surfaces the file body. Non-text data URIs and hosted/url file references preserve filename as AdditionalProperties. Image/file extraction logic is extracted into shared AppendImageContent and AppendFileContent helpers used by both the fresh-input and history-replay switches. Existing 37 InputConverter tests still pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Foundry hosting: round-trip tool-approval (HITL) content as mcp_approval_request/response Closes the gap where Microsoft.Agents.AI.Foundry.Hosting silently dropped MEAI ToolApprovalRequestContent/ToolApprovalResponseContent in both directions. We now serialize them onto the wire as the standard Responses API mcp_approval_request/mcp_approval_response items with server_label='agent_framework', and parse the symmetric inbound shapes back into MEAI content. Wire format: - The Responses API only standardizes mcp_approval_* as the approval primitive. We declare AF as a virtual MCP server via the server_label field, which is honest for AF's server-side tool-call holding pattern. - The SDK enforces a strict {prefix}_{50hex} wire-id format, so we hash the AF RequestId and persist a wireId<->afRequestId mapping in AgentSession.StateBag so a later mcp_approval_response can be matched back to the originating workflow request. Coexists with the existing ConsentAwareMcpClientAIFunction flow (AgentFrameworkResponseHandler.cs) which emits mcp_approval_request from a side-channel, not via OutputConverter's content switch. Known follow-up: python (foundry_hosting/_responses.py) has the same output-side gap (ToolApprovalRequestContent emission). Out of scope here. Tests: +9 unit tests covering both fresh-input and history-replay shapes, StateBag mapping resolution, and the non-FunctionCallContent skip path. Existing 108 converter tests still pass; full suite 370/370. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback for hosted-declarative-dotnet FileSystemAgentSessionStore reliability/scoping: - Bound Sanitize() stackalloc at 256 chars, fall back to ArrayPool for longer ids so a long conversationId can no longer crash the hosting process with StackOverflowException. - Use a Guid-suffixed temp file (\{path}.{guid}.tmp\) so concurrent SaveSessionAsync calls on the same conversation can no longer race on the same temp file. Best-effort temp cleanup on failure. - Bucket session files by agent.Name when set so two keyed agents that happen to share a conversationId no longer overwrite each other's persisted state. Single-agent / unnamed-agent cases keep the original flat layout (Python parity). DeclarativeWorkflowExecutor chat-protocol routing: - ConfigureChatProtocolRoutes uses IsAssignableFrom rather than exact type equality so a broader TInput (object, base interfaces) does not have its inherited inputTransform shadowed by handlers we register here. - HandleChatMessagesAsync / HandleChatMessageArrayAsync now advance through every message in the batch instead of keeping only the trailing one, so multi-message turns and replayed history are no longer silently truncated. AdvanceAsync gains a finalizeTurn flag so only the last message in the batch sends the result. Tests: - New FileSystemAgentSessionStoreTests covering constructor, fresh-session fallback for missing/empty files, root-directory creation, save/get round-trip, agent-Name scoping isolation, long conversationId, invalid-character sanitization, and concurrent-save behavior. - New InputConverterTests covering AppendFileContent: text/* data URI decode (with and without filename prefix), non-text data URI passthrough, malformed data URI fallback, and filename propagation onto UriContent / HostedFileContent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add tests for remaining PR review feedback (C2, D1, E1) C2: InputConverter — add 9 tests covering SDK content types that previously had no coverage: - SdkTextContent → TextContent (input + output paths) - SummaryTextContent → TextContent (input + output paths) - MessageContentReasoningTextContent → TextReasoningContent (input + output) - ComputerScreenshotContent (HTTP URL → UriContent, data: URI → DataContent, output path → UriContent) D1: OutputConverter — add 2 tests for the WorkflowEvent + Contents fall-through: - WorkflowEvent in RawRepresentation with text Contents must flow through the content-processing path (text-delta event emitted). - WorkflowEvent + ErrorContent must produce a failed event rather than be swallowed by the workflow branch. E1: SendActivityExecutor — extend CaptureActivityAsync to assert that the executor emits an AgentResponseEvent carrying the activity text with the correct ExecutorId and ChatRole.Assistant role. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Defense-in-depth: neutralize dot-segments in Sanitize and cap TryDecodeTextDataUri input size Addresses claude-opus-4.6 security review on PR #5589: - FileSystemAgentSessionStore.Sanitize now replaces all-dot segments (., .., ...) with underscores so a developer-controlled agent.Name cannot escape the root directory on Linux (where Path.GetInvalidFileNameChars only contains NUL and '/'). - InputConverter.TryDecodeTextDataUri rejects encoded payloads larger than 16 MiB before calling Convert.FromBase64String, preventing a single oversized data URI from triggering a multi-megabyte allocation. - Adds unit tests covering both fixes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix Linux-only failure in SaveSessionAsync_SanitizesInvalidPathCharactersAsync '?' is in Path.GetInvalidFileNameChars only on Windows, not on Linux/macOS, so the test failed on Ubuntu in CI. Use Path.GetInvalidFileNameChars()[0] (skipping NUL) to pick a guaranteed-invalid character for the running OS, and assert the result no longer contains it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address claude-opus-4.6 security/reliability review feedback WorkflowSession.cs: - ExecutorFailedEvent handler no longer leaks the internal executor ID in error messages. Mirror the WorkflowErrorEvent pattern: surface the exception's Message when _includeExceptionDetails is true, fall back to the generic 'An error occurred while executing the workflow.' otherwise. This also resolves the failing WorkflowHostSmokeTests assertions. FileSystemAgentSessionStore.cs: - GetSessionPath no longer has a write side effect. Directory.CreateDirectory for the per-agent bucket is now performed only on the SaveSessionAsync path, so a read miss on GetSessionAsync no longer leaves an empty directory on disk. - Adds GetSessionAsync_NoExistingFile_DoesNotCreateAgentDirectoryAsync to lock in the no-side-effect-on-read contract. OutputConverterTests.cs: - Strengthen ConvertUpdatesToEventsAsync_ToolApprovalRequest_NonFunctionToolCall_SkippedAsync to assert exactly one event (the terminal ResponseCompletedEvent) so a spurious output-item-added/-done leak would now fail the test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: clean up comments and rename TryParseArguments - Remove Python-codebase references from C# XML docs and inline comments. - Drop fix-history comments referring to previously-resolved issues. - Drop `Defense-in-depth:` prefixes; keep the concrete `what & why`. - Drop `previously we kept only the trailing message` comment in DeclarativeWorkflowExecutor; just describe current loop behavior. - Rename InputConverter.TryParseArguments to ParseFunctionArgumentsObject to make the intent obvious at the call site. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: collision-free Sanitize, MAF-style refactors - FileSystemAgentSessionStore.Sanitize now percent-encodes invalid chars (and `%` itself) instead of replacing them with `_`, eliminating collisions like `foo/bar` vs `foo_bar` mapping to the same bucket. All-dot segments encode every dot so Windows trailing-dot trimming cannot reintroduce a navigable name. - AddFoundryResponses XML doc updated to accurately describe the default store root (/.checkpoints when hosted, {cwd}/.checkpoints locally). - DeclarativeWorkflowExecutor.ConfigureChatProtocolRoutes now uses exact type equality instead of IsAssignableFrom so a broad TInput (e.g. object) does not skip registering IEnumerable<ChatMessage>, which ChatProtocolExtensions.IsChatProtocol requires verbatim. - SendActivityExecutor uses context.YieldOutputAsync(response) instead of manually constructing AgentResponseEvent, so the activity will participate in any future OutputFilter coverage. - WorkflowSession handles AgentResponseEvent in its own switch case, avoiding the second typecheck against output.Data. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(workflows): bridge declarative HITL through Foundry hosting via IExternalRequestEnvelope Introduce a new public interface IExternalRequestEnvelope in Microsoft.Agents.AI.Workflows that lets the runtime peek through a declarative-layer envelope without taking a circular reference back into the declarative package. ExternalInputRequest (declarative) implements it; ExternalInputResponse is constructed via the request's CreateResponse factory. WorkflowSession unwraps inner AIContent on the request side and rewraps the client's ChatMessage reply into an ExternalInputResponse on the response side. PortableValue cannot deserialize directly into an interface, so TryGetRequestEnvelope resolves the concrete type via RequestPortInfo.RequestType (TypeId -> Type.GetType) before casting. Public WorkflowHarness contract preserved: InvokeFunctionToolExecutor and WorkflowActionVisitor are unchanged from upstream, so public InvokeToolWorkflowTest scenarios continue to drive ExternalInputRequest / ExternalInputResponse directly through the harness. AgentFrameworkResponseHandler: skip prior conversation history replay when an existing session is being resumed (workflow checkpoint already holds the prior messages). WorkflowSession: when includeExceptionDetails is opted in, also unwrap DeclarativeActionException so HITL failures are debuggable. 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>
Ben Thomas ·
2026-05-04 22:09:54 +00:00 -
.NET: Harness Feature branch (#5310)
* .NET: Add a TODO AIContextProvider (#5233) * Add a TODO AIContextProvider * Add unit tests * Address PR comments * Address PR comments * Fix test after removing one tool * .NET: Add a ModeProvider for managing agent modes (#5247) * Add a ModeProvider for managing agent modes * Fix typo * Fix typo * Fix typo * Address PR comments * .NET: Add sample to show how to build a harness (#5268) * Add sample to show how to build a harness * Improve sample * Sample max output tokens and model * Fix encoding * Fix model name in readme * Address PR comments * .NET: Add context window size compaction strategy for harness (#5304) * Add context window size compaction strategy for harness * Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Address PR comments --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * .NET: Add a file memory provider (#5315) * Add a file memory provider * Address PR comments * Fix review comments. * Add additional unit tests * Addressing PR comments. * .NET: Harness: Improve prompts and add FileSystem store (#5365) * Harness: Improve prompts and add FileSystem store * Address PR comments * .NET: Harness: Improve path validation (#5404) * Harness: Improve path validation * Address PR comments * .NET: Add always approve helpers, improve sample and fix bug (#5451) * Add always approve helpers, improve sample and fix bug * Address PR comments * .NET: Make Todo, Mode and FileMemory providers more configurable (#5477) * Make Todo, Mode and FileMemory providers more configurable * Address PR comments. * .NET: Add subagents provider and sample (#5518) * Add subagents provider and sample * Addressing PR comments. * .NET: Harness filememory index plus instructions consistency (#5540) * Add FileMemoryProvider index and improve instruction consistency * Address PR comments. * Address PR comments * Address PR comments. * Apply suggestion from @rogerbarreto Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> --------- Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com> * .NET: Refactor harness console to be more extensible and easy to understand with better UX (#5573) * Refactor harness console to be more extensible and easy to understand with better UX. * Fix formatting issues. * Allow multiple clarifications in one response * Address PR comments * .NET: Add FileAccessProvdider and concurrency fix for FileMemoryProvider (#5583) * Add FileAccessProvdider and concurrency fix for FileMemoryProvider * Address PR comments --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
westey ·
2026-05-01 10:52:38 +00:00 -
.NET: Add dedicated Foundry.Hosting UnitTest project (#5592)
* Foundry.Hosting.UnitTests: extract project from Foundry.UnitTests Move all Hosting/* tests, three toolbox TestData JSONs, and the FakeAuthenticationTokenProvider/HttpHandlerAssert/TestDataUtil helpers (trimmed to toolbox getters) into a new Microsoft.Agents.AI.Foundry.Hosting.UnitTests project. Add it to the slnx and grant the new assembly InternalsVisibleTo from Microsoft.Agents.AI.Foundry and Microsoft.Agents.AI.Foundry.Hosting. * Foundry.Hosting.UnitTests: align namespaces to assembly name Rename namespaces from Microsoft.Agents.AI.Foundry.UnitTests(.Hosting) to Microsoft.Agents.AI.Foundry.Hosting.UnitTests across all moved tests, the duplicated helpers, and the trimmed TestDataUtil. Also fixes the prior namespace inconsistency in FoundryToolboxTests. * Foundry.Hosting.UnitTests: split WorkflowIntegrationTests by SUT Replace the WorkflowIntegrationTests file (an IT-named file inside a UT project) with two SUT-focused files plus a shared test-doubles file: - AgentFrameworkResponseHandlerWorkflowTests.cs - the 5 handler-driven tests that exercise AgentFrameworkResponseHandler with a real workflow agent. - OutputConverterWorkflowTests.cs - the 5 OutputConverter tests driven by hand-crafted update sequences mirroring real workflow patterns. - WorkflowTestAgents.cs - StreamingTextAgent and ThrowingStreamingAgent extracted as internal types used by both files. * Foundry.UnitTests: trim Hosting-related conditionals and dead testdata Now that Hosting tests live in their own project: - drop the Compile Remove guard for the Hosting subfolder, - drop the .NETCoreApp-only PackageReferences (Azure.AI.AgentServer.Responses, Microsoft.AspNetCore.TestHost, OpenTelemetry, OpenTelemetry.Exporter.InMemory), - drop the conditional ProjectReference to Microsoft.Agents.AI.Foundry.Hosting, - delete the three Toolbox JSON files and the matching Toolbox getters in TestDataUtil. * Foundry.Hosting.UnitTests: drop redundant 'using Microsoft.Agents.AI.Foundry.Hosting' The new project namespace is Microsoft.Agents.AI.Foundry.Hosting.UnitTests, which already brings the parent Microsoft.Agents.AI.Foundry.Hosting namespace into scope. The explicit using statement is therefore redundant (IDE0005). Caught by 'dotnet format --verify-no-changes' running on Linux against the .NET 10 SDK. * Foundry.Hosting: drop InternalsVisibleTo to Foundry.UnitTests The non-hosting Foundry.UnitTests project no longer holds any Hosting tests after the split, so it doesn't need access to internal types in Microsoft.Agents.AI.Foundry.Hosting. Only Microsoft.Agents.AI.Foundry.Hosting.UnitTests needs it. * Foundry.Hosting: rename DelegatingResponsesClient to UserAgentResponsesClient Address westey-m's review feedback on PR #5453: `Delegating*` is conventionally reserved for inheritable base classes (mirroring `DelegatingHandler`) where consumers override one or two members. This polyfill is sealed and only injects the User-Agent supplement, so the new name reflects its actual purpose. Renamed via `git mv` to preserve history: * `src/Microsoft.Agents.AI.Foundry.Hosting/DelegatingResponsesClient.cs` to `UserAgentResponsesClient.cs` * `tests/Microsoft.Agents.AI.Foundry.Hosting.UnitTests/DelegatingResponsesClientTests.cs` to `UserAgentResponsesClientTests.cs` Class, constructor, and all references updated across: * `src/.../UserAgentResponsesClient.cs` (class + constructor + internal log message) * `src/.../ServiceCollectionExtensions.cs` (cref + type check + instantiation) * `src/.../HostedAgentUserAgentPolicy.cs` (cref) * `tests/Foundry.UnitTests/RequestOptionsExtensionsTests.cs` (comment) * `tests/Foundry.Hosting.UnitTests/UserAgentResponsesClientTests.cs` (class + cref + instantiations)
Roger Barreto ·
2026-04-30 21:09:25 +00:00 -
.NET: dotnet: Add hosted-agent User-Agent supplement to outgoing requests (#5453)
* dotnet: Add hosted-agent User-Agent supplement to outgoing requests When an agent runs inside a Foundry Hosted Agent, the outgoing User-Agent header now includes 'agent-framework-hosted/{version}' alongside the existing 'MEAI/{version}' segment. - Add HostedAgentContext with AsyncLocal<string?> property - MeaiUserAgentPolicy reads the supplement per-call - AgentFrameworkResponseHandler sets/restores the context Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: update hosted UA format to foundry-hosting/agent-framework-dotnet/{version} Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Trying to get UA flowing, no luck yet. * .NET: Polyfill MEAI OpenAIResponsesChatClient to add hosted-agent User-Agent supplement When AgentFrameworkResponseHandler resolves an agent (i.e. we are running in a hosted context), TryApplyUserAgent walks the agent's IChatClient decorator chain to find MEAI's internal OpenAIResponsesChatClient and reflectively swaps its inner _responseClient field with a DelegatingResponsesClient wrapper. The wrapper overrides the public-virtual protocol methods to add a per-call HostedAgentUserAgentPolicy to the RequestOptions and delegate to the inner ResponsesClient. The OpenAI SDK's internal streaming overloads bottom out in calls to the public-virtual non-streaming overloads via virtual dispatch on this, so streaming is covered without overriding any non-virtual member. The wrapper accepts any ResponsesClient-derived inner — both the Foundry ProjectResponsesClient and the native OpenAI ResponsesClient — and preserves the inner client's full pipeline (Transport, RetryPolicy, NetworkTimeout, OrganizationId / ProjectId / UserAgentApplicationId, custom policies). - Add DelegatingResponsesClient + HostedAgentUserAgentPolicy in Microsoft.Agents.AI.Foundry.Hosting. - Add TryApplyUserAgent next to ApplyOpenTelemetry in FoundryHostingExtensions; wire it into AgentFrameworkResponseHandler.GetAgent for both keyed and default-agent paths. - Drop earlier-iteration dead code: AddHostedAgentTelemetry extension, HostedUserAgentPolicy class, HostedAgentContext.cs, and the never-called ToRequestOptions helper. - Revert RequestOptionsExtensions.MeaiUserAgentPolicy to MEAI-only (the supplement is now injected by the polyfill). - Revert unrelated whitespace change in Agent_Step25_ToolboxServerSideTools sample. - Tests cover streaming AND non-streaming, retry policy preservation, OrganizationId/ProjectId/UserAgentApplicationId pass-through, idempotency, native OpenAI ResponsesClient, and reflection guards for MEAI/OpenAI shape drift. * .NET: Address review feedback on hosted-agent User-Agent polyfill - TryApplyUserAgent: replace silent null-return with ArgumentNullException to match the codebase's convention. - Add idempotency test (TryApplyUserAgent_CalledTwiceOnSameAgent_DoesNotDoubleWrap) — runs the polyfill twice on the same agent and asserts the wire UA contains exactly one foundry-hosting segment, proving the 'current is DelegatingResponsesClient' guard prevents nested wrapping. - Add retry-double-append test (Polyfill_RetryWithinCall_DoesNotDuplicateSupplementInUserAgent) — exercises the HostedAgentUserAgentPolicy Contains-guard via a custom retry policy that re-runs the inner pipeline on the same message. - Replace TryApplyUserAgent_NullAgent_ReturnsNullWithoutThrowing with TryApplyUserAgent_NullAgent_ThrowsArgumentNullException to match the new contract. * .NET: Drop null check from TryApplyUserAgent and its now-redundant test The two call sites in AgentFrameworkResponseHandler.GetAgent already null-check the agent before invoking TryApplyUserAgent, so the defensive ArgumentNullException is unreachable. Remove it and the corresponding test. * .NET: Remove unused Microsoft.Shared.Diagnostics import in ServiceCollectionExtensions The Throw.IfNull helper from this namespace was used by the now-removed null check in TryApplyUserAgent. Drop the unused import to satisfy IDE0005 in CI's full-project dotnet format run. --------- Co-authored-by: alliscode <bentho@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>Ben Thomas ·
2026-04-30 16:37:54 +00:00 -
.NET: Add declarative HttpRequestAction sample (#5572)
* Add declarative HttpRequestAction support to workflows * Clean up response body for diagnostics and fix tests. * Fix merge with main. * Remove redundant fallback for request content headers. * Add declarative InvokeHttpRequest sample * Fix solution file and update sample yaml comments * Add final newline to sample class to fix formatting failure
Peter Ibekwe ·
2026-04-29 19:19:31 +00:00 -
.NET: Add HttpRequestAction support to declarative workflows (#5474)
* Add declarative HttpRequestAction support to workflows * Clean up response body for diagnostics and fix tests. * Fix merge with main. * Remove redundant fallback for request content headers.
Peter Ibekwe ·
2026-04-28 21:53:19 +00:00 -
.NET: [Breaking] Support string[] arguments for file-based skill scripts (#5475)
* support arguments of string[] shape for file-based skill scripts * suppress breaking changes errors * address feedback * remove unnecessary usung directive
SergeyMenshykh ·
2026-04-27 15:37:10 +00:00 -
.NET: Support returning durable workflow results from HTTP trigger endpoint (#5321)
* Adding support for "wait for response" when invoking workflow http endpoint. * update changelog. * PR comment fixes. * Address PR review feedback. - Return 404 Not Found when no orchestration with the given ID exists - Return 200 OK for failed workflows (the HTTP operation succeeded; the workflow outcome is conveyed via the response body) - Rename 'status' to 'workflowStatus' in WorkflowRunResponse to avoid inconsistency with AgentRunSuccessResponse which uses integer status - Add optional 'error' field (omitted from JSON when null) to WorkflowRunResponse for failed workflow details
Shyju Krishnankutty ·
2026-04-25 00:55:28 +00:00 -
.NET: Bump OpenTelemetry packages to 1.15.3 (#5478)
* Bump OpenTelemetry packages to 1.15.3 to fix known vulnerabilities Update OpenTelemetry packages from 1.15.0 to 1.15.3 in Directory.Packages.props to resolve NU1902 warnings-as-errors for CVEs GHSA-g94r-2vxg-569j, GHSA-mr8r-92fq-pj8p, and GHSA-q834-8qmm-v933. Add explicit PackageReference for OpenTelemetry.Exporter.OpenTelemetryProtocol in Foundry.Hosting and OpenTelemetry.Api + OpenTelemetry.Exporter.OpenTelemetryProtocol in Hosted-Invocations-EchoAgent to override transitive 1.15.0 resolution in projects with CentralPackageTransitivePinningEnabled=false. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Bump OpenTelemetry Extensions and Instrumentation packages to 1.15.x Align the full OpenTelemetry package set to the 1.15.x family: - OpenTelemetry.Extensions.Hosting: 1.14.0 -> 1.15.3 - OpenTelemetry.Instrumentation.AspNetCore: 1.14.0 -> 1.15.2 - OpenTelemetry.Instrumentation.Http: 1.14.0 -> 1.15.1 - OpenTelemetry.Instrumentation.Runtime: 1.14.0 -> 1.15.1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SergeyMenshykh ·
2026-04-24 21:56:30 +00:00 -
.NET: dotnet: Add server-side Foundry Toolbox support and fix SDK beta.4 br… (#5450)
* dotnet: Add server-side Foundry Toolbox support and fix SDK beta.4 breaking changes Add FoundryToolbox and AIProjectClient extensions to Microsoft.Agents.AI.Foundry.Hosting for server-side toolbox tool integration matching Python's FoundryChatClient.get_toolbox() pattern. Tools are fetched from the Foundry project SDK and passed as server-side tools in the Responses API request. New files: - FoundryToolbox.cs: Core implementation using AgentAdministrationClient SDK - AIProjectClientToolboxExtensions.cs: Extension methods on AIProjectClient - Agent_Step25_ToolboxServerSideTools sample with create helper and combine flow - 19 unit tests covering param validation, conversion, sanitization, and extensions SDK breaking changes (Azure.AI.AgentServer.Responses beta.3 -> beta.4): - FunctionToolCallOutputResource renamed to OutputItemFunctionToolCallOutput - AzureAIAgentServerResponsesModelFactory made internal, replaced with direct constructors - ResponseUsage constructor now requires non-null token details parameters Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: reuse endpoint variable in CreateSampleToolboxAsync Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: pass endpoint through static local functions to avoid capture Static local functions cannot capture top-level variables. Thread the endpoint parameter through Main, CombineToolboxes, and CreateSampleToolboxAsync. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor: remove unused projectClient param from CreateSampleToolboxAsync Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update dotnet/samples/02-agents/AgentsWithFoundry/Agent_Step25_ToolboxServerSideTools/README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update dotnet/samples/02-agents/AgentsWithFoundry/Agent_Step25_ToolboxServerSideTools/Program.cs Co-authored-by: westey <164392973+westey-m@users.noreply.github.com> * Update dotnet/samples/02-agents/AgentsWithFoundry/Agent_Step25_ToolboxServerSideTools/Program.cs Co-authored-by: westey <164392973+westey-m@users.noreply.github.com> * Removing GetToolbocVersion. * Removing tests for GetToolboxVersion * fix: map cached/reasoning token counts in ConvertUsage instead of hardcoding zeros Extract InputTokenDetails.CachedTokenCount and OutputTokenDetails.ReasoningTokenCount from UsageDetails.AdditionalCounts, matching the pattern in AgentResponseExtensions. Also accumulate detail counts when merging with existing usage. 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: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
Ben Thomas ·
2026-04-23 18:52:03 +00:00 -
.NET: Add streaming support to A2A agent handler (#5427)
* update a2a agent to the latest a2a sdk (#5257) * Move A2A samples from 04-hosting to 02-agents (#5267) Move the A2A sample projects (A2AAgent_AsFunctionTools and A2AAgent_PollingForTaskCompletion) from samples/04-hosting/A2A/ to samples/02-agents/A2A/ to better align with the sample directory structure. Update solution file and samples README accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Fix stream reconnection for A2AAgent (#5275) * Add SSE stream reconnection support to A2AAgent Implement automatic reconnection for SSE streams that disconnect mid-task, using the Last-Event-ID header to resume from where the stream left off. Changes: - Add InvokeStreamingWithReconnectAsync method to A2AAgent with configurable max retries and delay between attempts - Add new log messages for reconnection events - Add A2AAgent_StreamReconnection sample demonstrating the feature - Update existing polling sample to use simplified SendMessageAsync API - Add unit tests for stream reconnection logic Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * address comments * Address PR review feedback - Dispose SSE enumerator before GetTaskAsync fallback to release HTTP connection - Wrap StreamWriter in using blocks with leaveOpen:true and explicit UTF-8 encoding - Print update.Text instead of update object in stream reconnection sample Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Use IA2AClientFactory to create A2AClient (#5277) * Refactor A2A extensions to use IA2AClientFactory and add ProtocolSelection sample - Update A2AAgentCardExtensions to accept IA2AClientFactory instead of A2AClientOptions - Update A2ACardResolverExtensions to accept IA2AClientFactory - Update A2AClientExtensions to accept IA2AClientFactory - Update A2AAgent to use IA2AClientFactory for client creation - Add A2AAgent_ProtocolSelection sample demonstrating protocol selection - Add comprehensive unit tests for all changes - Update README files with new sample reference Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Reorder params: options before loggerFactory in A2A extensions Move A2AClientOptions parameter before ILoggerFactory in AsAIAgent and GetAIAgentAsync extension methods to follow the repo convention of keeping LoggerFactory and CancellationToken as the last parameters. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Migrate A2A hosting to A2A SDK v1 (#5363) * .NET: Migrate A2A hosting to A2A SDK v1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * remove unused agent card --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Split A2A endpoint mapping into protocol-specific methods (#5413) * .NET: Refactor A2A hosting registration into A2AServerServiceCollectionExtensions - Rename A2AHostingOptions to A2AServerRegistrationOptions - Move server registration logic from A2AEndpointRouteBuilderExtensions and AIAgentExtensions into new A2AServerServiceCollectionExtensions - Remove A2AProtocolBinding and AIAgentExtensions (consolidated) - Update samples and tests to use the new registration API Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * address copilot comments --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove unnecessary using directive in AgentWebChat.AgentHost Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * restore AsyncEnumerable package version * address copilot initial feedback * address automated code review and formatting issues * fix formatting issues * Add streaming support to A2A agent handler Add HandleNewMessageStreamingAsync to A2AAgentHandler that routes StreamingResponse requests through RunStreamingAsync, enqueuing an A2A Message for each AgentResponseUpdate. Add MessageConverter.ToParts(AgentResponseUpdate) extension to convert streaming update contents to A2A Parts with unsupported-content filtering. Add CreateMessageFromUpdate to map AgentResponseUpdate to A2A Message. Add 16 new tests covering the streaming path and converter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add streaming edge-case tests for A2AAgentHandler Add two tests covering gaps in the streaming path: - ExecuteAsync_Streaming_WhenNoUpdates_EnqueuesNoMessagesAndSavesSessionAsync: Verifies that when RunStreamingAsync yields an empty async enumerable, no messages are enqueued and only SaveSessionAsync runs. - ExecuteAsync_Streaming_CancellationTokenIsPropagatedToRunStreamingAsyncAsync: Verifies that the CancellationToken from ExecuteAsync is propagated through to the inner agent's RunCoreStreamingAsync call. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * address copilot comments --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SergeyMenshykh ·
2026-04-23 18:50:57 +00:00 -
westey ·
2026-04-23 18:26:55 +00:00 -
.NET: Fix off-thread RunStatus race where GetStatusAsync can return Running after ResumeAsync halts (#5412)
* Fix off-thread RunStatus race where GetStatusAsync can return Running after ResumeAsync halts * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Simplify test comment. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Peter Ibekwe ·
2026-04-23 15:27:28 +00:00 -
.NET: Add dynamic tool expansion sample (#5425)
* Add dynamic tool expansion sample * Address PR comments * Remove tool names from tool call response to avoid confusing LLM
westey ·
2026-04-23 15:10:57 +00:00 -
.NET: Update Aspire package to be preview (#5444)
* Update Aspire package to be preview * Also update readme file * Include README.md in pack
westey ·
2026-04-23 15:10:49 +00:00 -
.NET: [Breaking] Migrate A2A agent and hosting to A2A SDK v1 (#5423)
* update a2a agent to the latest a2a sdk (#5257) * Move A2A samples from 04-hosting to 02-agents (#5267) Move the A2A sample projects (A2AAgent_AsFunctionTools and A2AAgent_PollingForTaskCompletion) from samples/04-hosting/A2A/ to samples/02-agents/A2A/ to better align with the sample directory structure. Update solution file and samples README accordingly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Fix stream reconnection for A2AAgent (#5275) * Add SSE stream reconnection support to A2AAgent Implement automatic reconnection for SSE streams that disconnect mid-task, using the Last-Event-ID header to resume from where the stream left off. Changes: - Add InvokeStreamingWithReconnectAsync method to A2AAgent with configurable max retries and delay between attempts - Add new log messages for reconnection events - Add A2AAgent_StreamReconnection sample demonstrating the feature - Update existing polling sample to use simplified SendMessageAsync API - Add unit tests for stream reconnection logic Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * address comments * Address PR review feedback - Dispose SSE enumerator before GetTaskAsync fallback to release HTTP connection - Wrap StreamWriter in using blocks with leaveOpen:true and explicit UTF-8 encoding - Print update.Text instead of update object in stream reconnection sample Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Use IA2AClientFactory to create A2AClient (#5277) * Refactor A2A extensions to use IA2AClientFactory and add ProtocolSelection sample - Update A2AAgentCardExtensions to accept IA2AClientFactory instead of A2AClientOptions - Update A2ACardResolverExtensions to accept IA2AClientFactory - Update A2AClientExtensions to accept IA2AClientFactory - Update A2AAgent to use IA2AClientFactory for client creation - Add A2AAgent_ProtocolSelection sample demonstrating protocol selection - Add comprehensive unit tests for all changes - Update README files with new sample reference Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Reorder params: options before loggerFactory in A2A extensions Move A2AClientOptions parameter before ILoggerFactory in AsAIAgent and GetAIAgentAsync extension methods to follow the repo convention of keeping LoggerFactory and CancellationToken as the last parameters. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Migrate A2A hosting to A2A SDK v1 (#5363) * .NET: Migrate A2A hosting to A2A SDK v1 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * remove unused agent card --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * .NET: Split A2A endpoint mapping into protocol-specific methods (#5413) * .NET: Refactor A2A hosting registration into A2AServerServiceCollectionExtensions - Rename A2AHostingOptions to A2AServerRegistrationOptions - Move server registration logic from A2AEndpointRouteBuilderExtensions and AIAgentExtensions into new A2AServerServiceCollectionExtensions - Remove A2AProtocolBinding and AIAgentExtensions (consolidated) - Update samples and tests to use the new registration API Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * address copilot comments --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove unnecessary using directive in AgentWebChat.AgentHost Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * restore AsyncEnumerable package version * address copilot initial feedback * address automated code review and formatting issues * fix formatting issues * Add DI wiring verification tests for AddA2AServer Add three tests to A2AServerServiceCollectionExtensionsTests that verify custom keyed services are actually wired through to the A2AServer, not just that the server resolves non-null: - Custom IAgentHandler: verifies the keyed handler is invoked when processing a SendMessageRequest instead of the default A2AAgentHandler. - Custom AgentSessionStore (no handler): verifies the keyed session store's GetSessionAsync is called during request processing when no custom handler is registered. - Default stores end-to-end: verifies the InMemoryAgentSessionStore and InMemoryTaskStore defaults successfully process a request. Uses a new CreateAgentMockForRequests helper that includes SerializeSessionCoreAsync setup needed by InMemoryAgentSessionStore. All tests call A2AServer.SendMessageAsync directly (no HTTP layer needed) and use CancellationToken timeouts to guard against hangs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
SergeyMenshykh ·
2026-04-23 07:53:00 +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 -
.NET: Update .NET package version 1.2.0 (#5364)
* release: Update version for .NET (1.2.0) * release: Update preview date tag
Jacob Alber ·
2026-04-21 19:07:44 +00:00