Commit Graph

2822 Commits

Author SHA1 Message Date
Tao Chen 5fcf7ea757 Rewording 2026-08-20 13:28:40 -07:00
Tao Chen dce1deb638 Fix typing 2026-08-19 11:41:02 -07:00
Tao Chen 6f05df4815 Merge branch 'main' into issue-7657 2026-08-19 11:00:18 -07:00
King Star 26b9200c21 Python: Preserve AG-UI tool message IDs across snapshots (#7510)
* fix(ag-ui): preserve streamed tool message IDs

* fix(ag-ui): align approval and MCP tool message IDs

* fix(ag-ui): ensure unique tool segment IDs

* fix(ag-ui): keep tool and text snapshot IDs unique

---------

Co-authored-by: Evan Mattson <evan.mattson@microsoft.com>
2026-08-19 17:43:53 +00:00
Javier Calvarro Nelson e2938f4531 .NET: Remove AGUI history special cases (#7741)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-08-19 16:50:46 +00:00
SergeyMenshykh b1377fad52 .NET: Suppress Swagger UI CodeQL alert in sample (#7764)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 1b565023-c86e-496f-a1a1-be59b4d89cb7
2026-08-19 15:13:44 +00:00
Javier Calvarro Nelson 064751c5f3 .NET: Upgrade AG-UI SDK packages to 0.0.5 (#7742)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 425c405b-1fd3-4ba6-b332-a195598374b4
2026-08-19 10:53:56 +00:00
MohammadHaroonAbuomar 10bf8d7d9e .NET: agent-hooks interception contract as a first-class experimental feature (#7564)
* feat(dotnet): agent-hooks interception contract as an experimental package

Add Microsoft.Agents.AI.AgentHooks, implementing the AGENT-HOOKS-0.1
control contract on the framework's native decorator seams, mirroring
the merged Python feature (#7515) in .NET idiom:

- One public factory (CreateAIAgentWithAgentHooks, per-run and
  host-owned-session overloads) composes agent, chat and function
  seams as one indivisible unit; the seam decorators are internal, so
  partial installs are impossible by construction.
- All eight interception points: input/output at the agent seam,
  pre/post_model_call below the function-invocation loop (every model
  service call bracketed individually), pre/post_tool_call via the
  function-invocation middleware seam, agent_startup/agent_shutdown
  bracketing each run.
- Fail-closed enforcement throughout: transforms write back into the
  native messages/arguments/results or throw; rich content is
  preserved as AIContent objects; interceptor crashes surface as
  host_error denies; enforcement-layer failures halt the run through
  FunctionInvocationContext.Terminate (the loop's only loud escape).
- Streaming is fully buffered per spec buffered_output semantics: a
  deny releases zero updates; transformed responses re-derive the
  released updates so egress never diverges from verdicted content.
- Verdict-before-durability: end-of-run history and context-provider
  writes defer behind the output verdict via gating provider wrappers
  (flushed post-transform with verdicted-message substitution for
  streams, dropped on deny); per-service-call persistence sits above
  the chat seam and is covered by its own post_model_call verdict;
  per-run history-provider overrides in run options are wrapped too;
  nested guarded sub-agents persist inline at their own boundaries.
- Opt-in dependency: ResponsibleAI.AgentHooks 0.1.0-alpha.4 (bundles
  native runtimes) referenced only by the new package; no existing
  framework source is modified.
- 58 tests: deny-before-execution and transform write-back per seam,
  rich-content preservation, streaming ordering with zero egress on
  deny, error bracketing, concurrency isolation, host-owned sessions,
  evaluate_only, approval-seam lift, persistence gating, misuse
  fail-closed paths, and codec units.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(dotnet): close structural bypasses at the ChatClientAgent boundary

Address both reviewers' probe-confirmed findings; the runtime
enforcement held everywhere, every fix is at the structural boundary:

- Gate the implicit default ChatHistoryProvider: with no provider
  configured, ChatClientAgent creates an InMemoryChatHistoryProvider
  the factory never saw, so denied output became durable session
  history and replayed to the model on the zero-config path (both
  stream modes). The factory now materializes and gates the default,
  setting the history-conflict flags to mimic implicit-default
  semantics for service-managed-history agents.
- Wrap per-run provider overrides on BOTH dictionaries: base
  AgentRunOptions.AdditionalProperties is merged into the chat options
  with precedence, so a base-level override bypassed (and displaced)
  the wrapped ChatOptions-level entry. Plain AgentRunOptions is
  covered too, and the wrap is copy-on-write — the caller's options
  and dictionaries are never mutated.
- Reject per-run ChatClientFactory on guarded agents (fail closed): it
  would replace the guarded chat pipeline and the tool-wrapping stage
  riding it, silently removing the chat and tool seams.
- Reject a supplied client already containing a
  FunctionInvokingChatClient: it would execute tools below the chat
  seam, before any post_model_call verdict and outside the tool seam.
- Run wire projections inside the guarded blocks at the chat and
  function seams: a poisoned value whose serialization throws now
  fails the run closed (function seam: host_error halt; chat seam:
  gated persistence refused before the failure propagates).
- Suppress provider failure notifications once a run-level deny or
  halt stands, so the denied turn's request messages never reach
  provider code.
- Document the deferred-OpenTelemetry observer channel (request-side
  spans capture pre-transform content under sensitive-data telemetry).
- Rename the factory to AsAIAgentWithAgentHooks per repo convention.

10 new boundary regression tests mined from the review probes
(default-provider durability in both stream modes with session-replay
assertions, both override dictionaries incl. the displacement shape,
plain-run-options override, copy-on-write, factory and supplied-FICC
rejections, poisoned-projection fail-closed); 68 total, all green.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(dotnet): redact denied-run failure notifications for both provider kinds

The deny/halt handling of provider failure notifications only covered
the chat-history wrapper; a context provider still received the denied
turn's request messages on its failure notification. Both gating
wrappers now REDACT instead of suppress: the notification is forwarded
with empty request messages and the original exception, preserving the
documented failure-cleanup contract (providers releasing per-run
resources on the failure signal keep working) while the denied turn's
request messages never reach provider code.

Regression tests assert both provider kinds receive the redacted
notification (zero request messages) on a denied run and full
notifications on ordinary, verdict-free failures. 70 tests total.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(dotnet): address Copilot review on the agent-hooks PR

- Run options: always clone chat-typed run options (the framework's
  function-invocation middleware chains its per-run factory onto the
  instance it receives, so forwarding the caller's instance leaked
  that factory into it — reuse tripped the rejection, concurrent
  reuse raced), and recognize the framework middleware's own factory
  as legitimate: it wraps the guarded pipeline (tool rewriting), so
  outer function-middleware composition now works, while its chained
  factories are walked so a caller-supplied factory cannot ride in
  unnoticed.
- Streaming: re-derived (transformed) updates preserve the response's
  ContinuationToken (ToAgentResponseUpdates does not project it), so
  transformed background streaming responses remain resumable; a
  message-less response releases a metadata-only update carrying it.
- Codecs: transformed tool calls are validated for complete shape and
  uniqueness before reconciliation (non-empty string id and name,
  object-valued args, distinct ids) — malformed shapes fail closed
  instead of becoming invalid native calls. Deliberately stricter
  than the merged Python codec, which coerces added-call shapes.
- Role defaulting in message write-backs is confirmed exact Python
  parity (user/assistant defaults per the merged codecs) and is now
  locked by tests rather than changed.
- ADR 0035 records the seam order, persistence gating, fail-closed
  behavior, alternatives and known limitations.

14 new tests (options reuse, outer function-middleware composition,
smuggled-factory rejection, continuation-token preservation, 8
malformed tool-call shapes, 2 role-default parity); 84 total, green.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* feat(dotnet): project the per-call tool set on pre_model_call emissions

Context providers can register additional tools during run preparation,
after agent_startup has been emitted, so tools_registered is inherently
a run-start snapshot and can be a partial view of the tools eventually
offered to the model.

- Emit the spec's optional pre_model_call tools field ({name,
  description?}) from the per-call effective ChatOptions.Tools — the
  completed set for each call, including provider-added tools.
- Document tools_registered as the run-start snapshot on the agent
  seam (dynamic registrations surface per call and are bracketed by
  the tool seam when invoked).
- Probe-confirm enforcement completeness for provider-added tools:
  they flow through the guarded pipeline's tool-wrapping stage, emit
  pre/post_tool_call, and a pre_tool_call deny blocks their
  invocation exactly like constructor-registered tools.

Two new tests (bracketing + audit projections, deny-blocks); 86
total, green.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* refactor(dotnet): one artifact per file; rewrap foreign gating wrappers

Per review:
- Split the three multi-type files (AgentHooksGatingProviders.cs,
  AgentHooksRunState.cs, AgentHooksWireCodecs.cs) into one type per
  file, file name matching the type name, per repo convention. No
  behavior changes; namespaces and access levels unchanged.
- Close a validation asymmetry at the provider gate: the per-run
  override wrap skipped any gating wrapper, including one owned by a
  DIFFERENT agent-hooks installation — which runs inline under this
  run's state (its own gate is not covering here), so a denied run's
  history could persist straight through it. Overrides are now
  re-wrapped unless the wrapper belongs to this installation
  (reference-equal configuration). The provider seam's inline
  behavior for foreign/absent state is otherwise deliberate: inline
  is the safe direction there (content of unguarded or differently
  guarded runs is covered by its own verdicts or none), and throwing
  would break the legitimate double-wrap flush flow.

One new regression test (foreign wrapper as per-run override on a
denied run persists nothing); 87 total, green.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* refactor(dotnet): accept params IEnumerable for agent-hooks interceptors

Per review: the constructor only iterates the interceptors, so widen
the parameter from params IInterceptor[] to the C# 13 params
IEnumerable<IInterceptor>. The sequence is enumerated exactly once
into the internal registration list (sequences may be
single-enumeration); per-item null validation and the factory's
at-least-one-interceptor check are unchanged, and an explicit null
sequence now throws ArgumentNullException. Params-form call sites are
source-compatible.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* build(dotnet): ship Microsoft.Agents.AI.AgentHooks as a preview package

Per maintainer review on the PR:

- Add the project to agent-framework-release.slnf and import the
  shared packaging props so the package ships. Version follows the
  repo default for unmarked packages (preview suffix), matching the
  package's [Experimental] surface and alpha upstream dependency:
  1.17.0-preview.<date>.1.
- Package metadata: sibling-style title, fuller description, tags;
  shared icon and NUGET.md readme via the packaging props. Verified
  dotnet pack locally: ResponsibleAI.AgentHooks 0.1.0-alpha.4 flows
  as a normal dependency and the project references become 1.17.0
  package dependencies.
- Update ADR 0035: shipping as preview per maintainer decision
  replaces the build-only-pending-maturity stance.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* build(dotnet): version the agent-hooks package as alpha

Per maintainer review: the package's maturity marker follows the
ResponsibleAI.AgentHooks dependency it is built on (alpha), rather
than the repo's default preview suffix. Packs as
1.17.0-alpha.260804.1; ADR 0035 updated.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* refactor(dotnet): group agent-hooks internals into Core and Codecs folders

Per review: only the public surface (the factory extensions and
options) stays at the project root; the internal seam decorators, run
state and gating providers move to Core/, and the wire projection
codecs to Codecs/. Pure file moves — namespaces stay flat per the
core package's folder convention (ChatClient/, Memory/); no content
changes.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* docs(dotnet): clarify session scoping and name the sessionId argument

Per review:
- Name the AgentContextBuilder arguments at the run-state factory so
  the GUID reads as what it is (the per-run agent-hooks session id).
- Document both branches of CreateRunState: session-scoped means the
  host owns the emitter/builder and the session boundaries (one
  session spanning runs, no agent_startup/agent_shutdown emitted by
  the agent); the default is one session per run with a fresh
  emitter, fresh sequence and isolated record trail, which is what
  keeps concurrent runs' emissions from interleaving.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(dotnet): harden agent-hooks factory and input projection per review

- Input projection returns (payload, content, role) as one typed
  result so the emission site never re-reads payload properties by
  name: the both-fields-exist invariant holds by construction. (The
  previous reads were fail-closed even hypothetically — JsonObject's
  indexer yields null, and a null content is rejected by the SDK's
  envelope validation — but reading back what we just produced was
  needlessly fragile-looking.)
- Reject UseProvidedChatClientAsIs on the factory: it signals a fully
  custom, do-not-touch client stack, which is incompatible with a
  factory whose job is to decorate the supplied client and rely on
  the agent's default pipeline above the chat seam. Honoring it would
  silently change where (and whether) the seams sit.
- Log swallowed agent_shutdown emission failures (logger resolved the
  same way the agent resolves its own: services, then the chat
  client, then null) so incomplete session trails are trackable;
  OutOfMemoryException stays unswallowed. The swallow remains
  correct: the run's own outcome is already propagating and the
  trail closure is best-effort by contract.

89th test: UseProvidedChatClientAsIs rejection.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* build(dotnet): attribute the Agent-Hooks protocol in the package identity

Per review:
- Title per suggestion: 'Microsoft Agent Framework - Responsible AI
  Agent-Hooks Protocol Support'; description names the protocol
  precisely (AGENT-HOOKS-0.1, maintained by the Responsible AI
  project at github.com/responsibleai/agent-hooks) so the package
  reads as protocol support, not a MAF-owned feature; tags aligned.
- Drop the [Experimental] attributes: per repo convention the
  attribute gates unstable surface inside released packages
  (Harness, core), while pre-release packages (Valkey and Mcp at
  alpha, Mem0 and LocalCodeAct at preview) carry none — the version
  suffix is the maturity signal.
- Drop the describing comment on the central package version entry.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* refactor(dotnet): split agent-hooks test fixtures into Support files

Per review: one type per file under Support/ (mock client, guards,
recording providers, helpers), matching the src-side convention; pure
mechanical split, flat namespace.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

---------

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>
2026-08-19 10:48:13 +00:00
Giles Odigwe 8be7c93063 Python: Preserve structured instructions when merging chat options (#7730)
* Python: Preserve structured instructions when merging chat options

`instructions` is declared as `str` on `ChatOptions`, but chat clients may widen it
to a provider-native structured form. Three merge paths combined it with an f-string,
which coerced any non-string value to its `repr`, turning structured metadata into
literal text before any client could see it:

- `merge_chat_options` (`_types.py`)
- `_merge_options` (`_agents.py`, agent defaults + per-run options)
- provider-contributed instructions in `_prepare_session_and_messages` (`_agents.py`)

The last of these is the reported case: once any context provider (for example
`SkillsProvider`) contributes instructions, structured instructions were replaced by
their `repr`, so the model received Python dict syntax as its system prompt and
Anthropic prompt caching silently stopped working.

Add a shared `_append_instructions` helper that concatenates strings as before and
otherwise extends element-wise, always appending so the leading portion stays
unchanged for providers that treat it as a stable, structure-sensitive prefix. A lone
mapping is treated as a single element rather than iterated into its keys.

On the Anthropic side, `_extract_structured_instructions` now normalizes bare strings
into text blocks, since appended instructions arrive alongside caller-supplied blocks.

Fixes #7700

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f428b149-a306-484a-b423-4e9de69f0b90

* Python: address review feedback on structured instructions fix

Parameterize the Anthropic regression test over both the with- and
without-SkillsProvider configurations so the structure-preserving behavior
is asserted in the baseline case too.

Normalize structured instructions in `_get_instructions_from_options` so
telemetry records the instruction text for provider-native block shapes,
extracting only `text` values to keep provider metadata out of spans.

Use `cast` for the structured `default_options` in both regression tests so
the test type checkers resolve the client options type correctly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: f428b149-a306-484a-b423-4e9de69f0b90

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
Copilot-Session: f428b149-a306-484a-b423-4e9de69f0b90
2026-08-19 10:25:54 +00:00
Evan Mattson c527d61ac7 Update Python codeowners (#7762) 2026-08-19 10:00:30 +00:00
Manjunath Janardhan ec407cf56f Python: fix: preserve Agent additional_properties in HandoffBuilder clones (#7755)
HandoffAgentExecutor clones each participant agent to attach handoff
tools, but the clone rebuilt the Agent without forwarding
additional_properties, so middleware and integrations observing
context.agent.additional_properties during handoff runs saw an empty
dict while the original agent retained its configuration.

Pass a deepcopy of the original agent's additional_properties into the
clone so handoff-executed agents keep their configured metadata and the
original agent stays untouched.

Fixes #7750
2026-08-19 09:57:32 +00:00
Roger Barreto 0f583ec8a3 .NET: Migrate remaining Foundry hosted samples to source deployment (#7668)
* .NET: Migrate 6 hosted-agent samples to source (ZIP) deploy

Extend the source (ZIP) deploy pattern established for Hosted-ChatClientAgent to Hosted-LocalTools, Hosted-Workflow-Simple, Hosted-TextRag, Hosted-Observability, Hosted-Files and Hosted-FoundryAgent. Each gains an azure.yaml (codeConfiguration/remote_build, ASPNETCORE_URLS, model env) and the canonical .agentignore, a self-contained csproj (single target, CPM opt-out, explicit published package versions, AgentFrameworkVersion), a Program.cs that drops the shared contributor scaffolding for DefaultAzureCredential, an updated .env.example and README, and drops the container-mode files (agent.yaml, agent.manifest.yaml, Dockerfile, Dockerfile.contributor). LocalTools, Workflow-Simple, TextRag, Observability and Files were verified deploying live via remote_build; Workflow-Simple returns a workflow runtime error at invoke that is unrelated to the deploy mode.

* .NET: Migrate Hosted-Invocations-EchoAgent and Hosted-LocalCodeAct to source (ZIP) deploy

EchoAgent (Invocations protocol) and LocalCodeAct migrated to the zip/code-deploy pattern (azure.yaml, .agentignore, self-contained csproj, README, container files removed). EchoAgent maps /readiness explicitly because the Invocations SDK does not auto-map it. Both verified live via remote_build on a Foundry project; LocalCodeAct's execute_code ran server-side (compute 21+21 -> 42).

* .NET: Migrate remaining hosted-agent samples to source (ZIP) deploy

Migrate Hosted-McpTools, Hosted-MemoryAgent, Hosted-AgentSkills, Hosted-AzureSearchRag, Hosted-Toolbox, Hosted-Toolbox-AuthPaths and Hosted-ToolboxMcpSkills to the zip/code-deploy pattern (azure.yaml with codeConfiguration + sample-specific env passthrough, canonical .agentignore, self-contained csproj, Program.cs dropping the shared contributor scaffolding for DefaultAzureCredential, updated .env.example and README, container files removed). Also restore the Hosted-Invocations-EchoAgent csproj filename the solution references. McpTools verified live via remote_build against the public Microsoft Learn MCP server; the memory/search/toolbox/skills samples build locally and deploy via remote_build but need their external resources (memory store, search index, toolbox connections, skills) provisioned to exercise end to end.

* .NET: Migrate Hosted-Workflow-Handoff to source (ZIP) deploy

Migrate the triage handoff workflow sample to the zip/code-deploy pattern (azure.yaml with codeConfiguration and Azure OpenAI env passthrough, canonical .agentignore, self-contained csproj using AgentFrameworkVersion for Foundry/Foundry.Hosting/Hosting, Program.cs dropping the shared contributor scaffolding for DefaultAzureCredential, updated .env.example and README, container files removed). Builds via remote_build; live needs an Azure OpenAI resource (AZURE_OPENAI_ENDPOINT/AZURE_OPENAI_DEPLOYMENT).

* .NET: Copy Hosted-AgentSkills skills/ into build output

The startup provisioning helper reads SKILL.md files from AppContext.BaseDirectory/skills, but the project did not copy the skills/ folder to the build/publish output, so at runtime the source directory did not exist and provisioning was silently skipped. Add a Content include (PreserveNewest), matching the resources/ pattern already used by Hosted-Files.

* .NET: Suppress OPENAI001 in Hosted-Workflow-Handoff for standalone ZIP build

The repo-wide Directory.Build.props suppresses OPENAI001, but that file does
not travel in the code/ZIP deploy package. The standalone dotnet publish the
Foundry code deploy runs then fails with error OPENAI001 on the experimental
GetResponsesClient().AsIChatClient() call. Add OPENAI001 to the project NoWarn
so the sample builds in the code-deploy pipeline, matching SimpleAgent.csproj.

* .NET: Document live-verified idiosyncrasies in Foundry hosted sample READMEs

Align every FoundryHostedAgents sample README with the documented azd flow and
add the idiosyncrasies found while live-testing each sample on a Foundry project:

- All samples: 'azd down' reports success but does not delete the hosted agent;
  document the explicit REST DELETE needed to remove it.
- Hosted-Workflow-Handoff: it builds its own AzureOpenAIClient (data-plane), so
  the agent identity needs the 'Cognitive Services OpenAI User' role on the
  Azure OpenAI account. azd only grants 'Foundry User' on the project, so add a
  step to grant the data-plane role and explain the triage-step failure without it.
- Hosted-Toolbox / Toolbox-AuthPaths / ToolboxMcpSkills: the toolbox must already
  exist and the agent identity must be able to read it; toolboxes with OAuth-gated
  tools return an oauth_consent_request and response.incomplete on first invoke.

* .NET: Address Foundry hosted sample review feedback

Make sample configuration reject blank azd substitutions and document every required environment value inside the scaffolded project flow.

Separate the hosted endpoint name from the Foundry managed prompt-agent name, fix standalone MemoryAgent diagnostics, and complete the contributor local package feed for Hosting, LocalCodeAct, and MCP.

Use azd for agent invocation and az rest for authenticated administration without exposing tokens. Add native MCP approval handling to the toolbox consent client and make its local path target the standard responses endpoint.

Validated all changed samples locally, the contributor flow in PowerShell and Bash, and the supported live scenarios on the TAO cace project.

* .NET: Fix advanced hosted sample project access

Document and validate the Foundry User grant required by hosted version identities that access project data plane APIs.

Add the Skills preview feature header and use a writable temporary directory for downloaded skills because source deployments mount the application directory read only.

Update AgentSkills, MemoryAgent, FoundryAgent, and ToolboxMcpSkills deployment guides with the post deploy identity grant. All four scenarios passed live on the TAO cace project.
2026-08-19 09:43:14 +00:00
Daniel Roth 9917bddc2b .NET: Update AG-UI samples for latest MAF + AG-UI SDK and align with docs (#7295)
* Simplify AG-UI Step04 human-in-the-loop sample to idiomatic pattern

The Step04 sample previously wrapped both the server and client agents in
custom ServerFunctionApproval*Agent middleware (~470 lines across two files)
to marshal a bespoke approval protocol over AG-UI. This is no longer needed:
MapAGUIServer natively emits the tool-approval interrupt when the model calls
an ApprovalRequiredAIFunction, and AGUIChatClient natively transports the
client's ToolApprovalResponseContent decision back to resume the run.

Changes:
- Server: map the ChatClientAgent directly with MapAGUIServer; remove the
  ServerFunctionApprovalAgent wrapper, the JsonOptions plumbing, and the
  ApprovalJsonContext registration.
- Client: use the AGUIChatClient-backed agent directly; the existing loop
  already handles ToolApprovalRequestContent -> CreateResponse idiomatically.
- Delete ServerFunctionApprovalServerAgent.cs and
  ServerFunctionApprovalClientAgent.cs.

Verified end-to-end (approval request -> approve -> tool executes -> final
response) against GitHub Models. Both projects build with 0 warnings.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1

* Update AG-UI Step04 README to describe native approval flow

The Step04 human-in-the-loop sample no longer uses the custom ServerFunctionApprovalServerAgent / ServerFunctionApprovalClientAgent wrappers. Update the README so it describes the idiomatic native flow: the server maps a plain agent with MapAGUIServer and relies on ApprovalRequiredAIFunction to raise the approval interrupt, and the client handles ToolApprovalRequestContent and replies with ToolApprovalResponseContent.

* Fix AG-UI Step04 README server port to match client default

The Step04 client defaults to http://localhost:5100 (and the server launchSettings also uses 5100), but the README told users to run the server on port 8888, so the client could not reach it. Align the Step04 server run command to 5100. Other steps intentionally keep 8888 because their clients default to that port.

* Update AG-UI .NET samples for latest MAF + AG-UI SDK and align with docs

- Bump AGUI.* packages 0.0.3 to 0.0.4 (Directory.Packages.props)
- Step01/02/03: drop AddHttpClient().AddLogging() server noise and simplify the
  client run-started output to match the getting-started doc (no thread plumbing)
- Step04 (HITL): remove HTTP body logging and MEAI001 pragmas, give the approval
  tool an explicit name, and align the resume decision message with the doc
- Step05 (state): replace the custom SharedStateAgent/StatefulAgent DataContent
  pattern (dropped by released AGUI.Server) with declarative
  AGUIStreamOptions.MapResultAsStateSnapshot plus a thin RecipeStateAgent that
  reads RunAgentInput.State, and align the Recipe models with the docs
- Refresh README to the shipped API (MapAGUIServer, ApprovalRequiredAIFunction,
  declarative state)

Verified: all 10 sample projects build; Step04 approval/resume and Step05 state
snapshot round-trip run end-to-end against GitHub Models.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1

* Name the Step02 backend tool search_restaurants to match the docs

Give the SearchRestaurants tool an explicit "search_restaurants" name so the
client displays an accurate tool name (not a compiler-mangled local-function
name) and stays aligned with the backend-tool-rendering doc.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1

* Add UTF-8 BOM to Step05 sample files to satisfy check-format

The check-format CI job enforces the repository's utf-8-bom charset rule via
dotnet format. The Step05 files added in this PR were saved without a BOM.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1

* Fix AG-UI sample conversation history

Let AgentSession own prior messages so clients send only each new turn, and give the frontend location tool a stable protocol name.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com>
Copilot-Session: eeb2168d-2ecc-4f8d-9830-c287072eb7e1
2026-08-19 09:41:31 +00:00
pratik wayase da11daebe5 Python: fix: prevent superlinear history growth by deduplicating messages in save_messages (#7242)
* fix: prevent superlinear history growth by deduplicating messages in save_messages

* fix: address review feedback for history deduplication

* fix: Prevent superlinear history growth by deduplicating messages

* fix: add list[Message] type hints

* fix(sessions): resolve deduplication churn and collapsing of identical message

* fix(sessions): replace uuid/seen-set dedup with sequence aware filtering

* fix: use forward-scan sequence alignment in filter_new_messages

* fix(core): annotate new_msgs type to resolve pyright errors

---------

Co-authored-by: Eduard van Valkenburg <eavanvalkenburg@users.noreply.github.com>
Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
2026-08-19 04:40:16 +00:00
NekoPunch e74ac4613c fix(python): coerce JSON workflow resume payloads (#7684)
AG-UI clients send plain JSON, but structured response types were only
accepted as already-built instances, and core's coercion stopped at the
outer object, letting raw dicts sit inside typed fields. Coercion now
walks declared annotations and returns the input untouched whenever it
cannot satisfy them.
2026-08-19 04:20:24 +00:00
Tao Chen 6680646510 Fix typing 2026-08-18 17:58:33 -07:00
Tao Chen 71b98caf01 Fix tests 2026-08-18 17:38:22 -07:00
Tao Chen 511fef1dec Merge branch 'main' into issue-7657 2026-08-18 17:16:33 -07:00
Tao Chen fc28d26f74 Address copilot comments 2026-08-18 16:47:20 -07:00
Evan Mattson 1f738cdeb7 .NET: Python: Clarify PR review comment resolution (#7746)
* Clarify PR review comment resolution

* Sync PR review resolution guidance
2026-08-18 23:27:10 +00:00
Evan Mattson e6536fb459 Python: Align AG-UI run continuity (#7662)
* Python: Align AG-UI run continuity

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92

* Python: Refine AG-UI continuation ownership

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92

* Python: Persist AG-UI checkpoint ownership

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92

---------

Copilot-Session: aadad05d-2646-405f-8c62-a7a223abfc92
2026-08-18 22:53:09 +00:00
MohammadHaroonAbuomar 58da0cc253 Python: add MiddlewareFailure, a first-class fatal signal for function middleware (#7562)
* feat(core): first-class fatal signal (MiddlewareFailure) for function middleware

The function-invocation loop converts every exception raised by
function middleware into a tool-error result and keeps looping, so
middleware that needs fail-closed semantics (enforcement layers,
guardrails) had no loud escape: the agent-hooks feature simulated one
by mutating shared run state, raising MiddlewareTermination, and
re-raising the real failure two hops away at the run boundary.

Introduce MiddlewareFailure (a MiddlewareException sibling of
MiddlewareTermination) as the loop's explicit fail-closed escape:

- _auto_invoke_function re-raises it (both the direct and the
  pipeline path) instead of absorbing it into a tool-error result;
  ordinary exceptions keep the absorb-and-continue contract.
- A failing call fails the whole parallel batch: in-flight sibling
  tool tasks are cancelled and awaited before the failure propagates.
- Every existing MiddlewareTermination absorb site (agent/chat
  pipelines, _execute_single_function_call, harness loop, purview)
  passes it through untouched by construction, and agent/chat
  middleware exceptions already propagate, so one exception type
  gives uniform fail-loud semantics across all three categories.

Migrate the agent-hooks feature to the new signal: delete the
_RunState.halted back-channel and its three run-boundary re-raise
checks, drop the halted arm of the termination special case in the
function middleware (the approval-request pass-through moves to the
single approval check on the normal path), and fail partial installs
loudly. Tool-seam host_error blocks keep surfacing as
InterceptionBlocked at the run boundary via the exception cause chain
(one deny surface at every seam, pinned by tests).

Spec 004 gains the middleware-failure invariants and matrix rows.

Closes #7522

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(core): harden tool-seam unwrap and pin review findings

Review round follow-ups for the MiddlewareFailure feature:

- Only agent-hooks' own tagged tool-seam halts (_ToolSeamBlockFailure)
  authorize re-raising the chained InterceptionBlocked at the run
  boundary; a third-party MiddlewareFailure with a crafted
  InterceptionBlocked cause now propagates as raised instead of
  laundering an attacker-shaped interception record into the feature's
  deny surface (regression test added, verified by mutation).
- Document that middleware must not catch MiddlewareFailure (docstring
  and spec 004): swallowing it converts a fail-closed abort back into
  a running, possibly unguarded loop.
- Pin the trailing termination re-raise in the agent-hooks function
  middleware: an inner short-circuit is bracketed and still propagates,
  skipping outer middleware post-code (test fails with the re-raise
  removed).

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(core): acyclic tool-seam unwrap chain; document cooperative batch cancellation

Address two automated-review findings on the MiddlewareFailure PR,
both confirmed empirically:

- _reraise_tool_seam_block created a two-object exception-chain cycle
  (block.__cause__ -> wrapper -> block) by re-raising the chained
  InterceptionBlocked `from` its transport wrapper. Detach the
  wrapper's back-links and re-raise bare, recording the wrapper as
  the block's __context__ — acyclic, both exceptions still visible in
  tracebacks. Regression test walks the chain and pins finiteness
  (verified to fail against the cyclic re-raise).

- Batch cancellation is cooperative: a synchronous tool body already
  running in a worker thread (asyncio.to_thread) cannot be interrupted
  by task cancellation and may complete its side effects after the
  failure reached the caller; its result is discarded either way and
  propagation is not delayed behind it. Narrow the stated contract
  (MiddlewareFailure docstring, loop comment, spec 004) and pin it
  with a blocking-sync-sibling regression test.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(core): settle dangling calls on service-managed conversations on abort

Address maintainer review on the MiddlewareFailure PR:

- A MiddlewareFailure escaping a tool batch on a service-managed
  conversation left the hosted thread ending in unresolved
  function_call items: _update_continuation_state persists
  session.service_session_id when the model turn completes (before
  tool execution), and probe-verified the next run sends only the new
  user message against that conversation — OpenAI-style continuations
  reject such a request, so a routine policy abort left the session
  permanently stuck. Both loops now settle the thread before
  propagating: one error function_result per dangling call, submitted
  with tool_choice="none" in a single extra request whose response is
  discarded; a settlement failure never masks the abort, and runs
  without a service-managed conversation make no extra request.
  Pinned by three regression tests (non-streaming, streaming, and the
  no-conversation no-cost case); spec 004 and the MiddlewareFailure
  docstring updated.

- Make the three tool-bracket escape tuples in the agent-hooks
  function middleware identical (MiddlewareTermination,
  MiddlewareFailure, CancelledError): a MiddlewareFailure raised
  inside the post/error-bracket emit bodies is unreachable today, but
  the uniform tuples remove the need to reason about why they would
  differ, and preserve the exact exception (including the private
  tool-seam tag) if the emitter ever surfaces one.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

* fix(core): advance settled continuation; settle approved-replay aborts

Address maintainer review on the MiddlewareFailure settlement path,
both probe-verified (branch rebased onto current main first):

- Advance the persisted continuation to the settlement response. For
  response-ID continuations (OpenAI Responses store=True, where the
  response id is the continuation handle) the settlement response is
  the first endpoint whose chain includes the synthetic tool outputs;
  leaving session.service_session_id on the pre-settlement response
  made the settlement ineffective — the next run would continue from
  the still-unresolved turn. The settlement response now runs through
  _update_function_invocation_continuation_state (a no-op for stable
  conversation-object ids). Pinned by a regression test that fails
  with the advance removed.

- Cover the approval-resolution phase: a MiddlewareFailure raised
  while an approved tool is replayed escapes loudly (probe-verified,
  already the case) but executed before the loops' settlement seams,
  leaving the original — already service-persisted — call unresolved.
  _resolve_approval_responses now takes a settle_dangling_calls
  callback invoked with the approved batch on abort; the settlement
  helper became a layer method taking explicit calls
  (approval-response wrappers unwrap to their underlying calls,
  hosted-tool approvals are left to their provider protocol) and
  carries its own best-effort containment. Pinned by deny-during-
  replay regression tests in both response modes, mutation-verified.

Spec 004 invariants and matrix rows updated accordingly.

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>

---------

Signed-off-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>
2026-08-18 22:33:52 +00:00
Tao Chen 46e7300638 Fix tests and typing 2026-08-18 13:52:56 -07:00
Tao Chen 3ae7e717d4 Further constraint v1.26.0 attrs 2026-08-18 13:22:07 -07:00
Tao Chen 55886b0c26 Refinement 2026-08-18 12:04:58 -07:00
Giles Odigwe 2213ef8493 Add es-metadata.yml for Engineering System inventory (#7740)
Registers the repository with Engineering System inventory via the
InventoryAsCode provider, mapping it to its Service Tree service and
routing compliance work items to the owning team.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 05291438-8e37-49d6-84b6-5ffb7814abb8
2026-08-18 18:20:13 +00:00
westey f330457042 .NET: Pass IServiceProvider to ChatClientAgent in AddAIAgent overloads (#7737)
All four AddAIAgent overloads in AgentHostingServiceCollectionExtensions
created a ChatClientAgent without forwarding the IServiceProvider, so the
FunctionInvokingChatClient in the agent's pipeline had no service provider
and tools could not resolve their dependencies at invocation time.

Fixes #4453

Co-authored-by: Max Montes Soza <max-montes@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-18 18:19:01 +00:00
Copilot e33e78127f .NET: Fix snake_case argument names in Harness file tool descriptions (#7731)
* Initial plan

* Fix snake_case argument names in Harness file tool descriptions

Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: westey-m <164392973+westey-m@users.noreply.github.com>
2026-08-18 18:05:09 +00:00
Tao Chen 0f54a9ce27 Address comments 2026-08-18 10:56:35 -07:00
westey 4be584cc53 .NET: Add session-persisted chat client routing (#7641)
* Add RoutePersistingRoutingChatClient

* Address PR comments

* Address PR comments
2026-08-18 17:45:43 +00:00
SergeyMenshykh 4ce2804db0 .NET: Fix release build analyzer failures (#7721)
Guard the hosted storage error log before evaluating the agent name and update the SDK to the servicing release containing the net9 ILLink analyzer fix.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: e3a6cce8-e1e8-4cf2-9cf4-3c0c8f3ed6d8
dotnet-1.18.0
2026-08-18 13:17:22 +00:00
SergeyMenshykh 1b45c15749 .NET: Update version for 1.18.0 release (#7713)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 0acc90aa-5690-41e6-b546-16083fc1c8b5
2026-08-18 10:01:07 +00:00
badhope 00d7102c54 Python: fix(workflows): preserve all trace contexts in FanInEdgeRunner aggregation (#7557)
* fix(workflows): preserve all trace contexts in FanInEdgeRunner aggregation

FanInEdgeRunner collected trace contexts and source span IDs using the
singular backward-compat properties (msg.trace_context / msg.source_span_id),
which return only the first element of the plural lists. When a message
arriving at a fan-in already carries multiple trace contexts (e.g. from
a prior fan-in aggregation), all but the first were silently dropped.

Iterate over the plural fields (trace_contexts / source_span_ids) and
extend the aggregated lists so every trace context and source span ID
from every source message is preserved. This keeps distributed tracing
links intact for nested fan-in topologies.

Added test_fan_in_preserves_multiple_trace_contexts_per_message that
sends a message with two trace contexts through a fan-in and asserts
all three contexts (2 + 1) reach the target executor.

* fix: address Copilot review comments on trace context aggregation

1. Pair trace_contexts and source_span_ids per-message (via zip) instead
   of flattening independently. This prevents misalignment when a message
   has mismatched counts — orphans are dropped per-message rather than
   shifting all subsequent pairs out of alignment.

2. Remove TraceCapturingAggregator's override of Executor.execute()
   (documented as "do not override"). Capture trace data from the
   WorkflowContext passed to the handler instead.

---------

Co-authored-by: weed33834 <weed33834@users.noreply.github.com>
Co-authored-by: Evan Mattson <35585003+moonbox3@users.noreply.github.com>
2026-08-18 04:26:04 +00:00
Evan Mattson d80c340a06 Clarify function-loop spec update guidance (#7706) 2026-08-18 02:11:10 +00:00
Evan Mattson af4347a61d Python: Restrict workflow type deserialization (#7500)
Resolve request-info type names only from exact caller-provided mappings or already-loaded module namespaces. Remove payload-selected imports and add focused regression coverage for both request and response type fields.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a53fe20b-c3f0-4583-badc-d5deac7c1049
2026-08-18 02:08:21 +00:00
dependabot[bot] a445e4815d Bump ty from 0.0.64 to 0.0.70 in /python (#7644)
Bumps [ty](https://github.com/astral-sh/ty) from 0.0.64 to 0.0.70.
- [Release notes](https://github.com/astral-sh/ty/releases)
- [Changelog](https://github.com/astral-sh/ty/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ty/compare/0.0.64...0.0.70)

---
updated-dependencies:
- dependency-name: ty
  dependency-version: 0.0.69
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-17 23:30:52 +00:00
dependabot[bot] 8b8fbbba03 Bump flit from 3.12.0 to 4.0.2 in /python (#7645)
Bumps [flit](https://github.com/pypa/flit) from 3.12.0 to 4.0.2.
- [Changelog](https://github.com/pypa/flit/blob/main/doc/history.rst)
- [Commits](https://github.com/pypa/flit/compare/3.12.0...4.0.2)

---
updated-dependencies:
- dependency-name: flit
  dependency-version: 4.0.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-08-17 23:30:33 +00:00
Ruiming Zhao 925d722acf Python: clarify skill script argument guidance (#7695)
* Python: clarify skill script argument guidance

* test: harden skill argument guidance coverage
2026-08-17 21:38:58 +00:00
Peter Ibekwe 6001c12cd3 .NET: Fix declarative workflows deep research sample (#7674)
* Fix declarative workflows deep research sample

* Address PR comments
2026-08-17 19:50:16 +00:00
Tao Chen 6a3633e54a Python: Add a global workflow checkpoint type registry (#7636)
* Add a glocal checkpoint type registry

* Update samples

* Revert uv.lock

* Address comments

* Revert uv.lock

* Revert uv.lock
2026-08-17 18:33:01 +00:00
LeoZhaoo 648a31ade6 Python: Surface A2A preview consent URLs (#7606)
* fix(foundry-hosting): surface A2A consent URLs

* Use non-hashing membership

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Tao Chen <williamchan444307762@hotmail.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Tao Chen <taochen@microsoft.com>
2026-08-17 18:31:02 +00:00
Ilia Sokolov c6584ffaad .NET: Add Cosmos chat history retrieval API (#7412)
* .NET: Add Cosmos chat history retrieval API

* Clarify Cosmos message ordering semantics
2026-08-17 17:45:02 +00:00
Roger Barreto 74808cb6c7 .NET: Add Foundry hosted session and user identity pass-through (#7648)
* .NET: Add Foundry session and user identity pass-through

Let user agents pin hosted agent_session_id on AgentSession and
send x-ms-user-identity per call for Foundry hosted agents.

* .NET: Add live ITs for Foundry session and user identity

Cover service-managed and admin-pinned hosted sandboxes, sticky
hosted session id, and per-call x-ms-user-identity isolation with
separate AgentSessions sharing one sandbox. Echo container avoids
model quota for identity assertions.

* .NET: Reject Foundry hosted session switch when sticky

Persist sticky id in finally, clone run options before factory wrap,
validate whitespace pin on CreateHostedSessionAsync, and throw on
unexpected hosted session id change in the response. Docs: distinct
AgentSessions per user identity may share one sandbox.

* .NET: Clear nested user identity and preserve run options

Always assign UserIdentityScope including null so nested runs do not
inherit a parent identity. When upgrading plain AgentRunOptions, keep
background, format, and additional properties on the specialized clone.

* .NET: Clarify previous_response_id user binding in docs

Align WithUserIdentity guidance with Foundry Learn multiplex docs:
response chains are bound to the creating user even inside a shared
hosted sandbox.

* refactor(foundry): clarify hosted agent APIs
2026-08-17 17:28:31 +00:00
Roger Barreto 11592495db docs: fix Agent Lightning installation link (#7693) 2026-08-17 16:49:12 +00:00
ump45nose 047ec7eaff .NET: Allow agents to opt into concurrent tool invocation (#7650)
* .NET: allow agents to opt into concurrent tool invocation

* .NET: address concurrent invocation review feedback
2026-08-17 11:15:27 +00:00
Chinedum Echeta 9c3a1a4af7 Python: Enhance _OutputItemTracker to prevent duplicate function call streaming (#7486)
* Python: Enhance _OutputItemTracker to prevent duplicate function call streaming

* Handle empty function call metadata arguments

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: 9b232bff-6a8c-4b02-addd-89de57a82f6a

* Python: Refactor _OutputItemTracker to manage outstanding function calls and update tests for call ID reuse

---------

Copilot-Session: 9b232bff-6a8c-4b02-addd-89de57a82f6a
2026-08-16 16:22:30 +00:00
Atharva Vichare 228754d7fa Python: Fix AG-UI url source dropping attachments when the URL is in source.value (#7655)
The ag-ui-protocol `InputContentUrlSource` carries the URL in `source.value`,
but `_extract_multimodal_source_fields` only read `source.url`/`source.uri`
for url-typed sources, so attachments sent in the spec shape were dropped
during the AG-UI to MAF conversion. The base64 branch already read
`source.value` correctly.

Read `source.value` first, keeping `url`/`uri` as fallbacks for the non-spec
shape. Adds tests for both.

Fixes #7653
2026-08-16 16:12:17 +00:00
Chinedum Echeta 8461667fe4 fix: deduplicate streamed DevUI tool calls (#7652)
Refs #7651

🐛 - Generated by Copilot
2026-08-16 16:11:28 +00:00
Tao Chen 8c42918969 Consolidate OTel GenAI Semantic Conventions versions 2026-08-14 21:23:44 +00:00
Roger Barreto 12621e0a74 .NET: Fix IDE0039 by using local functions in samples (#7666)
Replace Func lambda assignments with local functions so
dotnet format --verify-no-changes passes on the agent and RAG samples.
2026-08-14 15:32:54 +00:00