Skip to content

dotnet-1.28.0

Choose a tag to compare

@dmytrostruk dmytrostruk released this 06 Nov 22:00
924a6e5

[1.28.0] - 2026-11-06

Added

  • Foundry: Add the GA computer tool through FoundryAITool.CreateComputerTool() and carry computer calls and results through Foundry hosting, including batched actions. Add an Azure OpenAI computer-use sample; the Foundry project endpoint still requires the existing preview tool. For non-hosted GA loops, use stored-response continuation: replaying locally retained computer calls with stored output disabled remains affected by an OpenAI SDK serialization limitation (#8756 by Roger Barreto (@rogerbarreto)).
  • Foundry hosting: Add FoundryToolboxOptions.TokenScope for cloud-specific toolbox authentication audiences, retaining https://ai.azure.com/.default as the default (#10100 by Roger Barreto (@rogerbarreto)).

Changed

  • A2A hosting: [BREAKING] Limit built-in server registration to message-based responses while reliable task resumption across hosts is deferred (#10037 by SergeyMenshykh).

    Migration: Remove assignments to the deleted A2AServerRegistrationOptions.AgentRunMode property. The built-in handler now completes the run and returns a message rather than a task; update clients that expect task responses. Task resumption and cancellation are unsupported by this message-only handler. Applications requiring task-based hosting must provide their own handler and task-lifecycle implementation.

  • A2A: [BREAKING] Replace individual identity-parameter overloads with optional A2AAgentOptions when constructing agents or adapting clients (#10113 by SergeyMenshykh).

    Migration: Replace new A2AAgent(client, id: ..., name: ..., description: ...) with new A2AAgent(client, new A2AAgentOptions { Id = ..., Name = ..., Description = ... }). Apply the same options object to client.AsAIAgent(...). Calls that do not customize identity can continue to omit options; supplied options are cloned.

  • A2A: Update A2A, A2A.AspNetCore, and A2A.Grpc to 1.0.0-preview4 and adapt hosting to the updated request-context API (#9995 by SergeyMenshykh).

  • CodeAct: [BREAKING] Redact host-tool exception details by default in Hyperlight and LocalCodeAct while preserving successful results and failure signaling (#9973 by Eduard van Valkenburg (@eavanvalkenburg)).

    Migration: Applications relying on detailed host diagnostics must explicitly set HyperlightCodeActProviderOptions.IncludeDetailedErrors = true or LocalCodeActProviderOptions.IncludeDetailedErrors = true for a trusted channel. This applies to provider and standalone-function usage. The default is false; outer chat-client error settings and sensitive-data logging do not enable these diagnostics. Configure the policy before constructing the provider or function, because it is captured in execution snapshots.

  • GitHub Copilot: [BREAKING] Disable file hooks by default for both new and resumed agent sessions (#10121 by westey (@westey-m)).

    Migration: Set EnableFileHooks = true explicitly in the SessionConfig supplied to GitHubCopilotAgent if the application requires file hooks. An omitted configuration or unset value now resolves to false; explicit values remain respected.

  • Declarative workflows: [BREAKING] Require an explicit HTTP host-and-port allowlist and an application-owned handler factory for workflow HTTP requests (#9841 by Vincent Biret (@baywet)).

    Migration: Replace parameterless, direct-HttpClient, and callback construction with new DefaultHttpRequestHandler(["api.example.com"], handlerFactory, "WorkflowHttp"), where handlerFactory is an IHttpMessageHandlerFactory. Register a named pipeline through AddHttpClient with an HttpClientHandler or supported SocketsHttpHandler whose AllowAutoRedirect and UseCookies are both false, and configure a finite handler lifetime. Empty allowlists deny all requests; entries match exact hosts and ports, with port 443 assumed when omitted. List non-default ports explicitly, such as api.example.com:80; wildcards and implicit subdomains are not supported. The allowlist does not itself enforce HTTPS. Configure headers and origin-bound authentication in delegating handlers, not HttpClient defaults, and ensure those handlers preserve the validated destination without following redirects. Remove handler disposal calls; the application owns the factory and pooled handlers.

  • Declarative MCP: [BREAKING] Create and dispose a separate MCP client for each invocation instead of caching initialized sessions across calls, approval waits, or checkpoint resumes (#9722 by Vincent Biret (@baywet)).

    Migration: Replace parameterless or callback-based construction with new DefaultMcpToolHandler(httpClientFactory, "workflow-mcp"), using an application-owned IHttpClientFactory and a named client registered through AddHttpClient. Configure pooled-handler reuse, a finite handler lifetime, and origin-bound authentication there; each invocation owns its factory-created HTTP client wrapper. Remove await using and DisposeAsync calls on the handler, which no longer implements IAsyncDisposable. The host must bound, cancel, and await active invocations before disposing HTTP infrastructure. Do not rely on implicit server-side session state surviving another call or checkpoint resume: use explicit remote state handles and durable workflow state, or implement an explicitly scoped IMcpToolHandler when session continuity is required. Automatic protocol negotiation remains the default; set the optional init-only ProtocolVersion only when the server's supported version is known.

  • Declarative Foundry: [BREAKING] Rename AzureAgentProvider to FoundryAgentProvider and remove its direct HttpClient property (#10098 by Vincent Biret (@baywet)).

    Migration: Replace AzureAgentProvider references and constructor calls with FoundryAgentProvider. Configure a custom project-client transport through AIProjectClientOptions.Transport instead of assigning the removed provider HttpClient property.

  • Workflow observability: [BREAKING] Align invocation span names and attributes with OpenTelemetry GenAI conventions and propagate application-supplied conversation context (#9899 by Vincent Biret (@baywet)).

    Migration: Update dashboards, exporters, and filters from workflow_invoke to invoke_workflow {workflow name}, or bare invoke_workflow for unnamed workflows, and replace workflow.name with gen_ai.workflow.name. Match gen_ai.operation.name="invoke_workflow" to identify invocations independently of their names. Supply gen_ai.conversation.id through OpenTelemetry baggage or current Activity baggage for correlation; nonblank OpenTelemetry baggage takes precedence. Conversation IDs are not inferred from session.id, which remains unchanged.

  • Workflow observability: [BREAKING] Remove nonstandard workflow payload attributes and deprecate the now-ineffective sensitive-data option (#9994 by Vincent Biret (@baywet)).

    Migration: Stop relying on executor.input, executor.output, and message.content span attributes; they are no longer emitted, even when WorkflowTelemetryOptions.EnableSensitiveData is enabled. Remove that option from workflow configuration: it is now an obsolete no-op scheduled for removal in 1.30.0. Use application-owned instrumentation if payload capture is required. Workflow spans, metadata, runtime events, and agent/chat sensitive-data capture are unchanged.

  • Foundry hosting: Use source-generated logging while preserving log levels, numeric event IDs, templates, structured properties, and exception associations. EventId.Name now contains the generated method name instead of null (#10122 by Roger Barreto (@rogerbarreto)).

  • Samples: Provide explicit do-not-retry reasons when users reject tool approvals, helping models avoid repeatedly requesting the same rejected call (#10095 by westey (@westey-m)).

  • Documentation: Clarify that healthy Foundry toolbox readiness does not guarantee every toolbox is available and that non-cancellation startup discovery failures are deferred to per-request resolution (#10124 by Roger Barreto (@rogerbarreto)).

  • Packages and tooling: Advance .NET release metadata to 1.28.0, promote shipped API baselines, and update .NET coverage-reporting and API-promotion workflow dependencies (#10157 by Vincent Biret (@baywet), #10046 by @maf-ci-automations[bot], #10062 by Dependabot (@dependabot)[bot], #10063 by Dependabot (@dependabot)[bot]).

Fixed

  • Harness: Fall back to the configured default when a restored session's agent mode has been removed or renamed, and persist the corrected mode (#9873 by NingLin Liu (@ninglinLiu)).
  • GitHub Copilot: Preserve reported reasoning-token counts in UsageDetails.ReasoningTokenCount, including zero values (#9773 by ZedingZhang (@ZedingZhang)).
  • Foundry hosting: Preserve paired function calls and results across OAuth consent handoffs so stored conversations can continue without missing-tool-output errors. For store=false, resend the prompt after authorization rather than using the ephemeral response as a replay anchor; existing malformed histories are not migrated (#9738 by Roger Barreto (@rogerbarreto)).
  • OpenAI Responses hosting: Preserve URL, file, file-path, and container-file citations in completed responses and streaming output, including annotations arriving in later updates (#9813 by Roger Barreto (@rogerbarreto)).
  • Hosting: Preserve readable non-ASCII text in OpenAI and Foundry tool payloads while continuing to escape HTML-sensitive characters (#10065 by westey (@westey-m)).
  • Purview: Correct per-message user mapping (#10099 by westey (@westey-m)).
  • Mem0: Reject ClearMemoryAsync with ArgumentException before sending a request when all scope IDs are null, empty, or whitespace, preventing unscoped deletion requests (#10109 by MoustAhmed (@MoustAhmed)).
  • Declarative workflows: Parse PowerFx formulas and convert numeric and temporal values using invariant culture, avoiding locale-dependent failures and incorrect values on hosts such as de-DE and fr-FR (#10069 by Prognosticate X (@Prognosticate-X)).
  • Documentation: Correct spelling in Chat Completions comments, a Cosmos test comment, and WorkflowBuilder XML documentation (#10108 by NingLin Liu (@ninglinLiu), #10153 by JY-M666, #10154 by JY-M666).