Commit Graph
582 Commits
Author SHA1 Message Date
40a2dd5cd0 .NET: Restore ambient client-header scope between non-streaming ClientHeadersAgent runs (#6517)
* Restore ambient client-header scope between non-streaming runs (#6516)

Make ClientHeadersAgent.RunCoreAsync async + await so the per-run
ClientHeadersScope is unwound on return, matching the streaming path.

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

* Assert per-run on wire instead of brittle exact request count

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-15 13:21:53 +00:00
0f483fa968 Set ApplicationName on CosmosClientOptions for UserAgent telemetry (#6481)
Added CosmosOptionsHelper (in Microsoft.Agents.AI.CosmosNoSql namespace)
that sets CosmosClientOptions.ApplicationName per component, producing
wire-visible UserAgent suffixes:

- CosmosChatHistoryProvider: Microsoft.Agents.CosmosNoSql.ChatHistory/{version}
- CosmosCheckpointStore: Microsoft.Agents.CosmosNoSql.Checkpoint/{version}

This ensures Cosmos DB requests from the Agent Framework are identifiable
in telemetry, enabling usage tracking and diagnostics queries that can
distinguish between chat history and checkpoint workloads.

Addressed review feedback:
- Truncates ApplicationName to 64 chars (Cosmos SDK max length)
- Moved helper to Microsoft.Agents.AI.CosmosNoSql namespace (scoped ownership)
- Uses StringComparison.Ordinal for IndexOf call

When users provide their own CosmosClient instance, the ApplicationName
is not overridden - users retain full control.

Co-authored-by: TheovanKraay <TheovanKraay@users.noreply.github.com>
2026-06-12 16:32:07 +00:00
westeyandGitHub 3f77c555cf .NET: [BREAKING] Align FileAccess tools with Python; add directory discovery and recursive search (#6474)
* Align FileAccess with python and improve functionality

* Addressing PR comments
2026-06-12 14:28:26 +00:00
Yufeng HeandGitHub 4c1b9efa8c .NET: fix: filter filesystem checkpoint index by session (#6132)
* fix: filter filesystem checkpoint index by session

* fix: filter checkpoint index by parent

* .NET: preserve legacy checkpoint index discovery
2026-06-11 22:35:57 +00:00
8b0405de1b .NET: Fix CopySessionConfig() and CopyResumeSessionConfig() to preserve SessionConfig.Streaming value (#6463)
* Fix CopySessionConfig and CopyResumeSessionConfig ignoring Streaming value (#4732)

CopySessionConfig() and CopyResumeSessionConfig() hardcoded Streaming = true,
ignoring the caller's explicitly set SessionConfig.Streaming value. This made it
impossible to disable streaming when using AsAIAgent() with the GitHub Copilot SDK.

Changed both methods to use source.Streaming ?? true (and source?.Streaming ?? true
for the nullable overload), preserving the caller's value when set while maintaining
backward compatibility by defaulting to true when unset.

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

* Fix non-streaming response path for SessionConfig.Streaming=false (#4732)

The config-copy fix (preserving Streaming=false via null-coalescing) was
already in place, but ConvertToAgentResponseUpdate(AssistantMessageEvent)
always emitted raw AIContent without text—assuming delta events had already
delivered it. When streaming is disabled there are no delta events, so the
assistant's final text was silently dropped.

Changes:
- Add isStreaming parameter to ConvertToAgentResponseUpdate for
  AssistantMessageEvent so it emits TextContent in non-streaming mode.
- Capture the resolved streaming flag in RunCoreStreamingAsync and pass
  it through the event subscription closure.
- Add/update unit tests for both streaming and non-streaming paths.

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

* Add test for null Data path in ConvertToAgentResponseUpdate (#4732)

Add a regression test covering the null-propagation path where
AssistantMessageEvent.Data is null. The production code already handles
this via ?. operators, but no test previously verified the behavior.

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

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-11 18:18:05 +00:00
c9e2a490be Fix AzureFunctions integration tests — set FUNCTIONS_WORKER_RUNTIME (#6425)
Azure Functions Core Tools v4 can no longer auto-detect the worker
runtime when local.settings.json is absent. Add the required
FUNCTIONS_WORKER_RUNTIME=dotnet-isolated environment variable to
both StartFunctionApp helpers and re-enable the skipped tests.

Fixes: https://github.com/microsoft/agent-framework/issues/6402

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-11 15:09:55 +00:00
westeyandGitHub 12ce099165 .NET: Add LoopAgent capability for Harnesses (#6384)
* Add LoopAgent capability for Harnesses

* Address PR comments.

* Add support for returning user messages and response aggregation

* Support fresh context per iteration with input sessions via cloning

* Add ability to receive newly created sessions via callback

* Address PR comments

* Add judge criteria

* Address PR comments
2026-06-11 15:00:01 +00:00
8e1998ddcb .NET: Adds Valkey to chat message history - issue 5445 (#5542)
* Adds Valkey to chat message history

* Address review: switch to Valkey.Glide, add options class, remove context provider

- Switch from StackExchange.Redis to Valkey.Glide 1.1.0 (official Valkey .NET client)
- Extract optional params into ValkeyChatHistoryProviderOptions
- Add JsonSerializerOptions support, remove [RequiresUnreferencedCode]
- Make MaxMessages/MaxMessagesToRetrieve readonly via options
- Remove ValkeyContextProvider (overlaps with ChatHistoryMemoryProvider + MEVD)
- Remove ValkeyProviderScope (only used by context provider)
- Remove connection string constructors (caller manages IConnectionMultiplexer)
- Update samples to use new API and gpt-5.4-mini

* Use type-safe JsonSerializer overloads, remove suppress attributes

Use JsonSerializerOptions.GetTypeInfo() for Serialize/Deserialize calls
to enable NativeAOT/trimming compatibility without suppress attributes.
Default to AgentAbstractionsJsonUtilities.DefaultOptions when no options provided.

Signed-off-by: Matthias Howell <matthias.howell@improving.com>

* Update READMEs: remove context provider references

Remove ValkeyContextProvider and long-term memory references from sample
READMEs since the context provider was removed from this PR. Simplify
Valkey server requirements (no search module needed for chat history).

Signed-off-by: Matthias Howell <matthias.howell@improving.com>

* Apply suggestion from @westey-m

* Fix formatting (dotnet format)

Signed-off-by: Matthias Howell <matthias.howell@improving.com>

* Update dotnet/src/Microsoft.Agents.AI.Valkey/Microsoft.Agents.AI.Valkey.csproj

Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>

---------

Signed-off-by: Matthias Howell <matthias.howell@improving.com>
Co-authored-by: Matthias Howell <matthias.howell@yoppworks.com>
Co-authored-by: westey <164392973+westey-m@users.noreply.github.com>
Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
2026-06-11 13:18:00 +00:00
Peter IbekweGitHubgithub-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
3753d938f5 .NET: Bug fixes for declarative workflows (#6427)
* declarative workflow approval flow fix

* Update mcp handler cache construction

* fix method argument.

* Update dotnet/src/Microsoft.Agents.AI.Workflows.Declarative/ObjectModel/InvokeFunctionToolExecutor.cs

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Fix identation

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-06-10 18:08:32 +00:00
dd29f9aa65 .NET: Hosted Agent Sample - Toolbox with various Auth (#5777) (#6018)
* .NET: Add Hosted-Toolbox-AuthPaths sample and auto-map /readiness with toolbox health gating (#5777)

Add a new hosted agent sample demonstrating five MCP tool authentication paths
(API key, agent MI, project MI, custom OAuth, literal token) via a Foundry Toolbox.

Package changes (Microsoft.Agents.AI.Foundry.Hosting):
- MapFoundryResponses now auto-maps GET /readiness via MapHealthChecks, idempotent
  across Tier 1/2 (AgentHost, already mapped) and Tier 3 (WebApplication, gap filled).
- AddFoundryResponses registers AddHealthChecks() so the pipeline is available.
- AddFoundryToolboxes registers FoundryToolboxHealthCheck on the /readiness aggregate,
  gating readiness on pre-registered toolbox startup outcome (per spec section 3.1).
- FoundryToolboxService now exposes StartupStatus and FailedToolboxNames properties.

New types:
- FoundryToolboxStartupStatus (public enum): Pending, Healthy, Failed, NoEndpoint.
- FoundryToolboxHealthCheck (internal IHealthCheck): adapts startup status to the
  AspNetCore HealthChecks pipeline with failed toolbox names in result data.

Tests:
- 3 new tests for /readiness auto-mapping (Tier 3 default, pre-mapped skip, idempotent).
- 4 new tests for FoundryToolboxHealthCheck (Pending, NoEndpoint, Failed, Healthy).
- 3 enhanced FoundryToolboxServiceTests with StartupStatus assertions.

* .NET: Align FoundryToolboxService with tools-integration-spec (#5777 Part A)

Bring Microsoft.Agents.AI.Foundry.Hosting's toolbox path into compliance with
tools-integration-spec.md sections 2-4, 6.3, and 9. Empirically validated
against tao-foundry-prj: the previous code (reading FOUNDRY_AGENT_TOOLSET_ENDPOINT,
which the platform never injects) silently registered zero tools in production.

Package changes (Microsoft.Agents.AI.Foundry.Hosting):

- FoundryToolboxService.StartAsync now derives the toolbox proxy base URL from
  the platform-injected FOUNDRY_PROJECT_ENDPOINT and constructs the per-toolbox
  URL as {FOUNDRY_PROJECT_ENDPOINT}/toolboxes/{name}/mcp?api-version={ApiVersion}
  per spec sections 2-3. The legacy FOUNDRY_AGENT_TOOLSET_ENDPOINT env var is
  removed outright (preview package, no production consumers).
- FoundryToolboxOptions.ApiVersion default flipped to 'v1' to match spec example.
- FoundryToolboxBearerTokenHandler always sends the mandatory
  Foundry-Features: Toolboxes=V1Preview header per spec section 2, merging any
  additional flags supplied via the FOUNDRY_AGENT_TOOLSET_FEATURES env var.
- FoundryToolboxBearerTokenHandler token scope changed from
  https://cognitiveservices.azure.com/.default to https://ai.azure.com/.default
  per spec section 4.
- FoundryToolboxBearerTokenHandler propagates W3C trace context (traceparent,
  tracestate, baggage) from Activity.Current per spec section 6.3.

Sample changes:

- Hosted-Toolbox-AuthPaths and Hosted-Toolbox Program.cs, README.md, and
  .env.example corrected to describe the actual env-var contract
  (FOUNDRY_PROJECT_ENDPOINT auto-injected; AZURE_AI_PROJECT_ENDPOINT as the
  local-dev fallback). Removes the misleading 'auto-injected by Foundry runtime'
  claims for FOUNDRY_AGENT_TOOLSET_ENDPOINT.
- Hosted-Toolbox-AuthPaths/agent.manifest.yaml declares the toolbox and model
  dependencies under resources[] per the AgentManifest schema so azd ai agent
  init users get them provisioned automatically.

Tests:

- 4 new FoundryToolboxServiceTests covering env-var derivation, EndpointOverride
  precedence, trailing-slash normalization, and the existing NoEndpoint behavior
  under the new env var name.
- 4 new FoundryToolboxBearerTokenHandlerTests covering token scope, mandatory
  feature header always present, header merging with override, no duplicate
  mandatory flag, trace context propagation from Activity.Current, and no
  override of caller-set traceparent.
- New FoundryProjectEndpointEnvFixture xUnit collection definition serializes
  env-var-mutating tests across FoundryToolboxServiceTests and
  FoundryToolboxHealthCheckTests, preventing parallel-execution races.
- FoundryToolboxHealthCheckTests adjusted for the new env var name.

* .NET: Drop ACA prereq from Hosted-Toolbox-AuthPaths README (#5777 Part B)

Empirically verified that any Azure Cognitive Services MCP endpoint already in
the Foundry project (e.g., a Language service MCP) accepts Entra tokens and can
serve Paths 2 and 3 without deploying a separate Azure MCP Server to ACA.

README updates:
- Step 0 rewritten: 'Identify an Entra-authenticated MCP target in your project'
  instead of 'Deploy Azure MCP Server to Azure Container Apps' (the original
  azmcp-foundry-aca-mi setup is now optional, not required).
- Auth-paths matrix updated to describe AAD-based connections targeting a
  Cognitive Services MCP URL (e.g., Language service) instead of an ACA URL.
- Step 2 connections table updated: the Entra ID category is now a single 'AAD'
  authType. The original 'Agent Identity' vs 'Project Managed Identity' as
  selectable connection sub-types is NOT exposed via the ARM control plane
  today; the platform selects the calling principal contextually. Both
  connections in the walkthrough share the same shape and target.
- Added an explicit RBAC note: the agent identity AND project MI must hold the
  required role (typically Cognitive Services User) on the target resource;
  without it the MCP server returns HTTP 401 even though the connection wiring
  is correct.
- Toolbox tool entries renamed lang_entra_agent / lang_entra_project to
  match the new connection names.

Empirical validation supporting these changes is captured in the session
plan.md (Part B addendum).

* .NET: Document correct connection shape for Hosted-Toolbox-AuthPaths Paths 2/3 (#5777)

Updates the sample README with the verified connection shape and RBAC procedure
for Microsoft Entra agent-identity and project-managed-identity MCP authentication:

- Connection authType values: AgenticIdentityToken (agent identity) and
  ProjectManagedIdentity (project MI), both with category=RemoteTool.
- Top-level audience property required; for Cognitive Services targets the value
  is https://cognitiveservices.azure.com.
- Connections created via ARM REST (the Foundry portal wizard does not yet
  expose these authTypes).
- RBAC grants target the project's shared agent identity blueprint principal
  (project.properties.agentIdentity.agentIdentityId) for Path 2 and the
  project's system-assigned MI (project.identity.principalId) for Path 3.
- Troubleshooting table updated with the audience-mismatch symptom and the
  startup-cache behavior of FoundryToolboxService.

* .NET: Drop Path 3 (project MI) and align with new agent model in Hosted-Toolbox-AuthPaths (#5777)

Updates the sample to use only the new Foundry agent object model and removes
the project managed identity path:

- Auth-path matrix reduced to four paths: key, Entra agent identity, custom
  OAuth, inline authorization. Project managed identity is moved into a note
  describing when it applies (multiple agents sharing access) rather than as
  a documented sample path.
- RBAC instructions reference the agent's own instance_identity.principal_id
  from the agent ARM resource (new agent object model) instead of the
  project's shared agent identity blueprint (legacy model).
- Step 2 (connections) creates only the AgenticIdentityToken connection.
- Step 3 (toolbox tools) lists four tool entries instead of five.
- Sample prompts and troubleshooting table updated to match.

* .NET: Restore Path 3 (project MI) to Hosted-Toolbox-AuthPaths matrix (#5777)

The sample's purpose is to enumerate every authentication path a Foundry toolbox
can drive, not to pick one. Path 3 belongs alongside the other four with
explicit guidance for when each path is the right choice.

- Path 3 (project managed identity, authType=ProjectManagedIdentity) restored
  to the matrix with a 'When to pick this' column.
- Step 2 (connections) provisions both lang-mcp-agent-id and lang-mcp-project-mi
  via ARM REST.
- Step 3 (toolbox) lists five tool entries (one per path).
- RBAC instructions cover both the agent's instance identity (Path 2) and the
  project's system-assigned MI (Path 3).
- Sample prompts include all five paths.
- Troubleshooting table updated accordingly.

* .NET: Fix duplicate line in Hosted-Toolbox-AuthPaths README (#5777)

* .NET: Fix broken markdown link to ToolCallingApprovalHostedAgentFixture (#5777)

* .NET: Fix relative path depth in markdown link (#5777)

* .NET: Address Copilot review feedback for #5777

- FoundryToolboxHealthCheck description: rename FOUNDRY_AGENT_TOOLSET_ENDPOINT
  → FOUNDRY_PROJECT_ENDPOINT (stale reference; operator-facing in /readiness body).
- FoundryToolboxStartupStatus.NoEndpoint XML doc: same rename.
- ServiceCollectionExtensions XML docs: same rename + URL shape update.
- Foundry.Hosting.IntegrationTests.TestContainer: remove explicit
  app.MapGet('/readiness') — now redundant + would conflict with the
  auto-mapped readiness route from MapFoundryResponses.
- Hosted-Toolbox-AuthPaths agent.manifest.yaml: parameterize TOOLBOX_NAME via
  {{TOOLBOX_NAME}} template substitution and declare it under parameters with a
  default of 'auth-paths-toolbox' so the README's 'use any name' guidance
  actually works for hosted deployments.

* .NET: Address Copilot review round 2 — fallback env + dedup + naming (#5777)

- FoundryToolboxService.StartAsync: fall back to AZURE_AI_PROJECT_ENDPOINT when
  FOUNDRY_PROJECT_ENDPOINT is absent. Matches the local-dev convention used by
  the samples and resolves the doc/code mismatch flagged in review.
- FoundryToolboxHealthCheck description updated for the fallback.
- AddFoundryToolboxes: guard against duplicate health-check registration via an
  explicit name-uniqueness check on HealthCheckServiceOptions.Registrations.
  AddCheck<T>(name, ...) does not dedupe by name, so repeated AddFoundryToolboxes
  calls would have registered multiple instances.
- FoundryToolboxOptions.EndpointOverride doc: clarify URL becomes
  {EndpointOverride}/toolboxes/{name}/mcp (was missing /toolboxes/ segment).
- Hosted-Toolbox sample (Program.cs + README): switch FOUNDRY_TOOLBOX_NAME to
  TOOLBOX_NAME (the FOUNDRY_* prefix is reserved by the platform), default
  changed from 'my-toolset' to 'my-toolbox', terminology updated from 'Toolset'
  to 'Toolbox'.
- FoundryToolboxServiceTests: 2 test renames to reflect what they actually
  assert (StartupStatus + FailedToolboxNames, not URL shape directly).
- Tests adjusted to clear both env vars in NoEndpoint scenarios.

* .NET: Fix stale NoEndpoint XML doc and misleading test comment (#5777)

Update FoundryToolboxStartupStatus.NoEndpoint XML doc to mention both
FOUNDRY_PROJECT_ENDPOINT and AZURE_AI_PROJECT_ENDPOINT (the service
checks both since the fallback was added).

Fix test comment that claimed URL derivation validation when the test
only asserts on StartupStatus and FailedToolboxNames.

* Remove OAuth consent path from AuthPaths sample, keep four working auth paths

The interactive OAuth identity passthrough path needs a protocol gap closed in the
hosting package (the proprietary oauth_consent_request item is not representable
through the OpenAI/MEAI abstractions), so it is deferred to a separate spike branch.

This strips the OAuth path from the AuthPaths sample, the companion REPL client, the
agent manifest, and the docs, then renumbers the inline Authorization path so the
sample teaches four contiguous paths: API key via connection, Entra agent identity,
Entra project managed identity, and inline Authorization (anti-pattern).

Package code is unchanged; the consent infrastructure already present in main stays
as baseline. Both samples build with --warnaserror and all 246 hosting unit tests pass.

* .NET: Drop project MI auth path and dedicated client from Hosted-Toolbox-AuthPaths (#5777)

Live validation against tao-foundry-prj showed the ProjectManagedIdentity
path failing with an unresolved token audience 401, so the sample now ships
three working auth paths instead of four: connection key, agent managed
identity, and inline Authorization.

Changes:
- Remove the project managed identity path from the AuthPaths sample matrix,
  prerequisites, connections, toolbox table, prompts, Program.cs instructions
  and agent.manifest.yaml.
- Delete the near duplicate Hosted-Toolbox-AuthPaths-Client project and remove
  it from the solution. The README now drives the agent with the shared
  SimpleAgent REPL via AsAIAgent(agentEndpoint).
- Correct the troubleshooting note: the Foundry toolbox tools/list is all or
  nothing, so one bad source returns -32007, fails startup, and returns 424
  for every path. Add the allowed_tools caveat that names must match the
  upstream server.
- Mark the toolbox startup status and health check experimental under
  AgentsAIExperiments (MAAI001) instead of AIOpenAIResponses, and update the
  package NoWarn set accordingly.

* .NET: Address PR review nits for Hosted-Toolbox-AuthPaths (#5777)

- Remove duplicated NU1903 comment in Foundry.Hosting csproj.

- Fix stale 'four-tool' cross-links in Hosted-Toolbox and Hosted-McpTools READMEs to describe the three-path toolbox driven by the shared SimpleAgent REPL.

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

* .NET: Address toolbox startup-status review feedback (#5777)

- Rename FoundryToolboxStartupStatus.Failed to Unhealthy so it is the proper opposite of Healthy, and clarify the doc comment covers the partial-failure case.

- Raise the missing-endpoint toolbox log from Information to Warning, since enabling toolboxes is an explicit opt-in and a silently disabled toolbox warrants a higher-severity signal.

- Update unit tests and the AuthPaths README troubleshooting row accordingly.

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

* .NET: Reword toolbox-wiring comment to avoid hosting-layer internals (#5777)

Address PR review feedback: explain how a Foundry Toolbox is attached using the public API (AddFoundryToolboxes vs the CreateHostedMcpToolbox marker) and observable behavior, instead of naming the internal AgentFrameworkResponseHandler type and FoundryToolboxService.Tools property.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-10 16:49:48 +00:00
a5f4e0078e .NET: Fix .NET Copilot integration tests for SDK v1.0.0 (#6424)
* Fix .NET Copilot integration tests for SDK v1.0.0

- Remove hard-skip in favor of runtime Assert.Skip when COPILOT_GITHUB_TOKEN is not set
- Add [Trait("Category", "Integration")] for CI filtering
- Fix FunctionTool test: use explicit SessionConfig with Tools, OnPermissionRequest, and SystemMessage
- Mark RemoteMcp test as IntegrationDisabled (requires OAuth flow)
- Create explicit sessions in all tests and delete after each (cleanup)
- Remove unused System.Diagnostics import
- Simplify SkipIfCopilotNotConfigured to only check env var

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

* Address review: use try/finally for session cleanup, IsNullOrWhiteSpace

- Wrap act/assert in try/finally so sessions are always deleted even on failure
- Use IsNullOrWhiteSpace instead of IsNullOrEmpty for token check

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

* Add COPILOT_GITHUB_TOKEN to .NET integration test workflow

The Copilot SDK runtime reads this env var directly for authentication.
No Node.js/npm install needed - the SDK downloads the CLI binary at build time.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-10 15:41:48 +00:00
383d551b86 Purview: Parallelize PSPC cold-cache scope refresh (#5832)
* Parallelize Purview PSPC cold cache path

* Cache Purview payment-required state for scope refresh

* Cache Purview payment-required state for scope refresh

* Align Purview policy action dedupe and 402 caching

 Deduplicate combined policy actions by action and restriction action so restriction-only actions are preserved
without duplicating identical entries. Cache tenant-level payment-required state from background scope refresh so
subsequent calls short-circuit consistently.

* .NET: Implement best-effort caching for background job scope retrieval and add unit tests for cache write failures

* Purview - feat: Enhance ScopedContentProcessor to queue ContentActivityJob when no applicable scopes are found and update related tests

* docs: Update purview package README and AGENTS documentation to reflect caching optimizations and policy enforcement scenarios

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-09 18:01:21 +00:00
Hasan GhomiandGitHub 2a345e5d3b .NET: Fix Magentic to share agent replies across team (#6222)
* Fix Magentic to share agent replies across team

The per-round instruction was sent untargeted (fan-out delivered it to
every participant) and replies were never relayed, so a later speaker saw
the prior speaker's instruction but not its response - inverted from
GroupChatHost and the Python reference.

- Target the instruction at the selected speaker only.
- Broadcast each reply to the other participants (buffered, no TurnToken),
  excluding the responder via _currentSpeakerExecutorId, mirroring
  GroupChatHost.
- Persist _currentSpeakerExecutorId across checkpoints.
- Add a regression test.

* Address review feedback: null-guard, explicit checkpoint key, drop vacuous assertion

* Address review feedback: centralize checkpoint keys, clear current speaker

- Move CurrentSpeakerStateKey into MagenticConstants as
  nameof(CurrentSpeakerStateKey)
- Clear _currentSpeakerExecutorId in ResetAndReplanAsync and
  PrepareFinalAnswerAsync so a checkpoint taken in those windows does not
  persist a stale speaker
- Add UTF-8 BOM to RecordingEchoAgent.cs to satisfy the format check.
2026-06-09 17:00:42 +00:00
96d242fa7f .NET: Remove required token params from HarnessAgent, make compaction opt-in (#6409)
* Move token params from HarnessAgent constructor to options

Remove the required maxContextWindowTokens and maxOutputTokens
constructor parameters from HarnessAgent and AsHarnessAgent, replacing
them with optional MaxContextWindowTokens and MaxOutputTokens properties
on HarnessAgentOptions.

When both values are provided, compaction is enabled as before (in-loop
CompactionProvider and chat reducer on the default InMemoryChatHistory
Provider). When either is null, compaction is disabled entirely, making
it opt-in.

New constructor: HarnessAgent(IChatClient, HarnessAgentOptions?,
ILoggerFactory?, IServiceProvider?)

Closes #6333

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

* Improving comments.

* feat: Add custom CompactionStrategy and DisableCompaction to HarnessAgentOptions

Allow users to provide their own CompactionStrategy via options, with
a clear priority system:
1. DisableCompaction=true: no compaction regardless of other settings
2. Custom CompactionStrategy provided: use it (token params ignored)
3. Both MaxContextWindowTokens and MaxOutputTokens set: default strategy
4. Otherwise: no compaction

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

* fix: Address PR review comments on compaction opt-in

- Update chatClient param XML doc to reflect compaction is opt-in
- Strengthen compaction tests to assert ChatReducer is null/not-null
  rather than just asserting construction succeeds

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-09 13:06:00 +00:00
9486c76ef8 .NET: Add Reasoning to ChatClientAgent ChatOptions merging (#5463)
* Add reasoning option to request chat options in ChatClientAgent

* Add tests for ChatOptions reasoning merging in ChatClientAgent

---------

Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
2026-06-09 11:25:31 +00:00
Yufeng HeandGitHub d222079df9 .NET: fix: preserve AG-UI session history (#5904)
* fix: preserve AG-UI session history

* refactor: use static AG-UI provider check
2026-06-09 07:06:13 +00:00
af772997af .NET: [BREAKING] Migrate .NET GitHub Copilot SDK to v1.0.0 (#6381)
* Migrate .NET GitHub Copilot SDK from 1.0.0-beta.2 to 1.0.0

- Update namespace from GitHub.Copilot.SDK to GitHub.Copilot
- Replace PermissionRequestResult/PermissionRequestResultKind with PermissionDecision
- Remove ConnectionState check (StartAsync is now idempotent)
- Rename ConfigDir to ConfigDirectory
- Use SessionConfig.Clone() for CopySessionConfig
- Update Tools type from List<AIFunction> to List<AIFunctionDeclaration>
- Rename UserMessageAttachmentFile to AttachmentFile
- Update usage data types (CacheWriteTokens: long, Duration: TimeSpan)
- Add GHCP001 NoWarn for experimental SDK APIs (matches framework convention)
- Specify type argument on CopilotSession.On<SessionEvent>()

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

* Fix formatting: remove unused using directive

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

* Skip AzureFunctions SamplesValidation tests pending func tools fix

Azure Functions Core Tools v4 can no longer auto-detect the worker
runtime in CI (local.settings.json is gitignored). All 7 active
SamplesValidation tests fail with 'Worker runtime cannot be None'.

Tracked by: https://github.com/microsoft/agent-framework/issues/6402

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

* Skip additional failing integration tests in CI

WorkflowSamplesValidation (5 tests): same func tools issue as #6402.
WorkflowConsoleAppSamplesValidation (4 tests): KeyNotFoundException
during workflow execution, tracked by #6404.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-08 22:34:05 +00:00
westeyandGitHub b343625c1f .NET: Add approval bypassing to harness as the default (#6387)
* Add approval bypassing to harness as a default

* Add tests

* Address PR comments.
2026-06-08 17:50:41 +00:00
westeyandGitHub 6a2efeae7c .NET: [BREAKING] Fix hosting bugs (#6388)
* Fix hosting bugs

* Address PR comments
2026-06-08 16:17:54 +00:00
Peter IbekweandGitHub 331201294b .NET: Fix single-column value unwrap in declarative workflow (#6367)
* Fix single-column value unwrap in declarative workflow

* Added more tests
2026-06-08 11:37:12 +00:00
Yufeng HeandGitHub fa9e086576 fix: preserve foreach record values (#6208) 2026-06-05 22:01:59 +00:00
6bd2cfec03 .NET: [BREAKING] Add auto-approval rules (heuristics) to ToolApprovalAgent (#6335)
* Add support for approving tools via heuristic rules

* Address PR comments

* Address PR comments

* Apply suggestion from @SergeyMenshykh

Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>

---------

Co-authored-by: SergeyMenshykh <68852919+SergeyMenshykh@users.noreply.github.com>
2026-06-05 18:43:07 +01:00
westeyandGitHub ab8ba8fc61 .NET: Allow storage of auto-approved functions (#4950)
* Allow storage of auto-approved functions

* Address PR comments
2026-06-05 18:42:21 +01:00
bb9ed63a34 .NET: Restructure skill script schemas XML and remove resources from body (#6343)
* Restore UTF-8 BOMs and fix BuildScriptSchemasBlock doc comment

- Restore UTF-8 BOM on all changed files to match repo convention
- Fix XML doc: <schema name=...> -> <schema script=...> to match emitted output

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

* Address PR review comments: fix doc remarks and rename tests

- Update script doc remarks to clarify only parameter schemas are included
- Fix grammar: 'arguments format' -> 'argument format'
- Rename misleading test methods to match actual assertions
- Clarify comment about removed wrapper element

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

---------

Co-authored-by: SergeyMenshykh <SergeMenshikh@outlook.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-04 21:15:29 +01:00
westeyandGitHub a982428916 .NET: Bug fixes for AGUI hosting and workflows (#6311)
* Add mcp tool execution fix

* Apply IsolationKeyScopedAgentSessionStore to MapAGUI by default if not yet set and improve comments in samples

* Address PR comments

* Fix formatting
2026-06-03 17:45:58 +00:00
90a3e5de47 .NET: Add ILoggerFactory and IServiceProvider to HarnessAgent constructor (#6273)
* Add ILoggerFactory and IServiceProvider to HarnessAgent constructor

Add optional ILoggerFactory and IServiceProvider parameters to the
HarnessAgent constructor and AsHarnessAgent extension method, passing
them to all downstream components that accept them:

- FunctionInvokingChatClient (via UseFunctionInvocation)
- CompactionProvider
- AgentSkillsProvider
- ChatClientAgent (via BuildAIAgent)
- AIAgentBuilder.Build()

Closes #6103

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

* Improve tests to verify ILoggerFactory and IServiceProvider propagation

- Add test verifying ILoggerFactory.CreateLogger() is called by
  downstream components (CompactionProvider, AgentSkillsProvider)
- Add test verifying IServiceProvider is queried during pipeline build

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-03 09:09:39 +00:00
03e14ca187 .NET: Update hosted agents (#6243)
* Updating to latest Foundry hosting packages.

* Re-applying .gitignore.

* Adding empty line at end of .gitignore

---------

Co-authored-by: Ben Thomas <25218250+alliscode@users.noreply.github.com>
2026-06-01 21:27:29 +00:00
b298113d15 .NET - Fix missing id on function_call_output in Foundry Hosting (#6246)
* Fix missing id on function_call_output in Foundry Hosting

The Foundry storage layer was rejecting responses with
"ID cannot be null or empty (Parameter 'id')" because
function_call_output items emitted by OutputConverter had no id on
the wire.

OutputItemFunctionToolCallOutput's public ctor only sets CallId and
Output; Id is read-only and only the SDK's internal ctor populates
it. OutputItemBuilder<T>.ApplyAutoStamps fills ResponseId and
AgentReference but not Id, so the itemId passed to
AddOutputItem<T>(itemId) was used only for event sequencing and the
serialized item went out with id=null.

Switch to stream.OutputItemFunctionCallOutput(callId, output), the
SDK convenience method that uses the internal ctor and stamps the
id. Add a regression test asserting the added/done events carry a
non-empty matching Id.

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

* ci: free disk space and relocate NuGet cache on ubuntu runners

The ubuntu-latest dotnet-build/test jobs were hitting No space left on device because the runner image only ships ~14 GB free on /. The full multi-TFM build plus the dotnet pack + console-app install-check exhausts that easily.

Add a reusable composite action .github/actions/free-runner-disk-space that runs on Linux runners only and:

* removes pre-installed toolchains we never use here (Android SDK, GHC/Haskell, CodeQL, PyPy, Ruby, Go, boost, vcpkg, etc.), prunes docker images, and disables swap (reclaims ~25-30 GB on /)

* relocates the NuGet package cache to /mnt/nuget via NUGET_PACKAGES env, since /mnt has ~75 GB free on hosted runners

Wire the action into the four ubuntu-touching jobs in dotnet-build-and-test.yml (dotnet-build, dotnet-test, dotnet-foundry-hosted-it, dotnet-test-functions). The action self-guards with runner.os == 'Linux' so the matrix legs that run on windows are unaffected.

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

---------

Co-authored-by: alliscode <25218250+alliscode@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-01 18:43:45 +00:00
edcc786651 .NET: Preserve and propagate CreatedAt through workflows (#3930)
* Preserve per-message CreatedAt attribute if it's available

* Add unit test

---------

Co-authored-by: Sam Chang <changsam@microsoft.com>
Co-authored-by: samchang-msft <samchang.msft@gmail.com>
2026-05-29 21:41:40 +00:00
07a1e83492 .NET: Forward Magentic participant replies to manager (#6156)
MagenticOrchestrator.TakeTurnAsync dropped the `messages` parameter
on subsequent turns, so participant replies never reached the manager's
ChatHistory. The manager kept re-dispatching the same speaker every
round until MaxRounds.

Append the incoming messages to taskContext.ChatHistory before running
the coordination round (matches Python's _handle_response).

Adds RecordingReplayAgent + regression test that asserts the worker's
reply reaches round-2's progress-ledger call.

Co-authored-by: Jacob Alber <jaalber@microsoft.com>
2026-05-29 21:41:25 +00:00
Roger BarretoandGitHub fa2a6af443 Bump Azure.AI.AgentServer.* packages and align Azure.Core/System.ClientModel (#6178)
* Bump Azure.AI.AgentServer.* package versions

* Align Azure.Core/System.ClientModel to AgentServer transitive deps

Bump Azure.Core 1.55->1.56 and System.ClientModel 1.11->1.12 to match Azure.AI.AgentServer.* requirements, and add explicit references in transitive-pinning-off Foundry consumers to avoid CS1705/MSB3277 version conflicts.
2026-05-29 19:42:07 +00:00
Peter IbekweandGitHub 11c8d89ab2 .NET: Fix InvokeMcpTool approval path for declarative workflows (#6177)
* Fix InvokeMcpTool approval path for declarative workflows

* Added more test for coverage.
2026-05-29 19:07:48 +00:00
CopilotGitHubcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>Roger Barreto
6510d6e3c8 .NET: Quarantine flaky DevUI test (#6159)
* Bump Microsoft.Extensions.AI packages to 10.6.0

* Align transitive package versions for Microsoft.Extensions.AI 10.6.0

* Initial plan

* Temporarily skip flaky DevUI keyed/default workflow test

* Revert Microsoft.Extensions.AI package bumps, keep only flaky test quarantine

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
2026-05-29 17:09:12 +00:00
8ed2159c4b .NET: Workflow Outputs Overhaul: Support Tagging, Filtering Agent Outputs (#6045)
* test: reshuffle .NET Workflow tests in preparation for Outputs overhaul

Phase 1 of the .NET Workflows outputs overhaul (see
working/implementation-plan.md). Pure moves/renames in
dotnet/tests/Microsoft.Agents.AI.Workflows.UnitTests; no production code
changes, no new test cases. The split keeps each orchestration mode in
its own source file so the upcoming tag-aware and orchestration-default
test additions land on clean diffs.

Renames:
* WorkflowBuilderSmokeTests.cs -> WorkflowBuilderTests.cs (with class
  rename to match). The scope is no longer "smoke"-only once subsequent
  phases add tag-aware builder tests.
* InputWaiterAndOutputFilterTests.cs -> InputWaiterTests.cs +
  OutputFilterTests.cs. The file already declared the two test classes
  separately; this split simply gives each its own file so the
  output-filter cases have a dedicated home for tag-aware additions.

Split of AgentWorkflowBuilderTests.cs:
* AgentWorkflowBuilderTests.cs is now the outer
  `public static partial class AgentWorkflowBuilderTests` holding the
  shared test helpers (DoubleEchoAgent + session + WithBarrier variant,
  WorkflowRunResult, RunWorkflow* methods) bumped from `private` to
  `internal` so the new top-level GroupChatWorkflowBuilderTests in the
  same assembly can reach them.
* AgentWorkflowBuilder.SequentialTests.cs (nested SequentialTests):
  BuildSequential_InvalidArguments_Throws,
  BuildSequential_AgentsRunInOrderAsync.
* AgentWorkflowBuilder.ConcurrentTests.cs (nested ConcurrentTests):
  BuildConcurrent_InvalidArguments_Throws,
  BuildConcurrent_AgentsRunInParallelAsync.

Sequential and Concurrent are kept as nested classes because they're
modes of the same `AgentWorkflowBuilder` static factory and do not
produce dedicated builder types.

New file:
* GroupChatWorkflowBuilderTests.cs (top-level): the existing
  BuildGroupChat_* and GroupChatManager_* cases moved out of the old
  AgentWorkflowBuilderTests file. They exercise the
  `GroupChatWorkflowBuilder` type (returned by
  `AgentWorkflowBuilder.CreateGroupChatBuilderWith`), so a dedicated
  top-level test class - matching the convention reserved by the plan
  for HandoffWorkflowBuilderTests / MagenticWorkflowBuilderTests - is
  the right home. Cross-class helper references qualify with
  `AgentWorkflowBuilderTests.DoubleEchoAgent` and
  `AgentWorkflowBuilderTests.RunWorkflowAsync`.

The outer partial class is `static` (and nested classes carry the
instance test methods) because the outer holds only static helpers;
this satisfies CA1052 without suppressions and is invisible to xUnit
discovery, which finds tests on the nested classes as
`AgentWorkflowBuilderTests.SequentialTests.*` etc.

Validation: `dotnet build` clean on both target frameworks; all 547
tests in Microsoft.Agents.AI.Workflows.UnitTests pass on net10.0.

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

* feat: introduce OutputTag, Futures, and tag-aware WorkflowBuilder API

Phase 2 of the .NET Workflows outputs overhaul. Additive code change
only - no observable runtime behavior change. The runner still uses the
legacy bypass for AgentResponse / AgentResponseUpdate payloads, and the
new `Futures.EnableAgentResponseOutputTaggingAndFiltering` flag defaults
to false. Phase 3 will wire the flag into the runner; this commit only
introduces the types and the builder API.

New public surface:
* `OutputTag` (readonly struct): wraps a string Value with ordinal
  equality (IEquatable, GetHashCode, == / !=) so it can participate as a
  HashSet element. Internal ctor closes the set. One public singleton:
  `OutputTag.Intermediate`. Terminal / regular outputs carry no tag
  (empty Tags set). JSON-serialized as a bare string via
  [JsonConverter(typeof(OutputTagJsonConverter))], with the converter
  rehydrating to the well-known singleton on read.
* `Futures` (static class): hosts opt-in pre-GA behavior switches.
  First flag is `EnableAgentResponseOutputTaggingAndFiltering`; XML doc
  captures the v2.0.0 obsoletion / v3.0.0 removal lifecycle.
* `WorkflowOutputEvent.Tags`: `HashSet<OutputTag>` exposed directly
  (concrete collection, matches the JSON-serialization convention used
  for `WorkflowInfo.OutputExecutorIds`). Never null; empty for legacy /
  terminal events. New ctors take a single `OutputTag` or
  `IEnumerable<OutputTag>?`; the existing (data, executorId) ctor
  remains and produces an untagged event. `HasTag(OutputTag)` helper.
  `AgentResponseEvent` and `AgentResponseUpdateEvent` gain matching
  tag-accepting ctors forwarding to the base.
* `WorkflowOutputEventExtensions.IsIntermediate(this WorkflowOutputEvent)`:
  extension method returning `evt.HasTag(OutputTag.Intermediate)`. The
  preferred way to ask "is this an intermediate output?" without
  reaching into the Tags set.
* `WorkflowBuilder.WithOutputFrom(IEnumerable<ExecutorBinding>, OutputTag)`
  and `WorkflowBuilder.WithOutputFrom(ExecutorBinding, OutputTag)`:
  forward-looking tagged overloads. The IEnumerable form is the primary
  tagged surface; the single-executor form is a convenience for the
  common one-executor case. Currently usable for the
  `OutputTag.Intermediate` singleton; will become the primary surface
  once the `OutputTag` constructor is opened to user-defined tags in
  a future release. Callers in this release should prefer the
  intent-specific `WithIntermediateOutputFrom` extension for the
  intermediate case. Tags accumulate across repeated calls; same tag
  repeated dedupes via the HashSet.
* `WorkflowBuilderExtensions.WithIntermediateOutputFrom(this WorkflowBuilder, IEnumerable<ExecutorBinding>)`:
  helper that forwards to `WithOutputFrom(executors, OutputTag.Intermediate)`.
  Takes an IEnumerable (matching the tagged WithOutputFrom shape) -
  callers pass collection literals: `builder.WithIntermediateOutputFrom([a, b])`.
  XML doc remarks call out the Futures-flag interaction and the
  AIAgent-payload forwarding contract.

Internal shape changes:
* `WorkflowBuilder._outputExecutors`: HashSet<string> -> Dictionary<
  string, HashSet<OutputTag>>. The value set is empty for executors
  designated only via the untagged WithOutputFrom; contains Intermediate
  (and possibly future tags) otherwise.
* `Workflow.OutputExecutors`: HashSet<string> -> Dictionary<string,
  HashSet<OutputTag>>.
* `OutputFilter.CanOutput`: `Contains(id)` -> `ContainsKey(id)`.
* `WorkflowInfo.OutputExecutorIds`: HashSet<string> -> Dictionary<
  string, HashSet<OutputTag>>, with a custom JsonConverter that reads
  both the new map shape (`{id: ["intermediate", ...]}`) and the legacy
  array shape (`[id1, id2]`, where each id is treated as an untagged
  output). Always writes the map shape. IsMatch updated to compare
  per-id tag sets.

Tests landing in this commit (per the test-with-feature principle):
* `OutputTagTests.cs` (6 tests): KnownValues, EqualityIsOrdinalOnValue,
  DefaultStructValueIsDistinct (default(OutputTag) does not collide
  with the Intermediate singleton in a HashSet),
  GetHashCodeMatchesEquals, JsonConverter_RoundtripsValueAsString,
  ConstructorIsInternal (reflection-based assertion that the (string)
  ctor is `internal`).
* `WorkflowBuilderTests.cs` adds 7 new tests pinning the builder
  API contract: RegistersWithEmptyTagSet, AddsIntermediateTag,
  MultipleExecutorsAllUntagged, ThenIntermediate_AccumulatesTags,
  RepeatedDedupes, OnlyRegistersWithoutPriorWithOutputFrom,
  TracksExecutorBinding.
* `BackwardsCompatibility/JsonCheckpointSerializationTests.cs`
  (new folder + file, 5 tests): event-level ctor contract tests
  (single-tag, no-tag, multi-tag — the last with a custom tag);
  IsIntermediate() asserted; load-bearing JSON BC tests for
  `WorkflowInfo.OutputExecutorIds` -
  `WorkflowOutputExecutorsReadsLegacyArrayShape` (legacy ids map to
  empty tag sets) and `WorkflowOutputExecutorsWritesMapShape`.

The plan's three JSON round-trip tests for `WorkflowOutputEvent.Tags`
were dropped: `WorkflowEvent` is not currently a serialized checkpoint
shape (see the comment in WorkflowsJsonUtilities.cs about events not
being persisted), so there is no real back-compat surface to pin
through JSON. They are substituted with in-process ctor/property
round-trip tests that exercise the `Tags` / `HasTag` / `IsIntermediate`
contract.

Validation: full `Microsoft.Agents.AI.Workflows.UnitTests` suite runs
green on net10.0 (565 passing, 0 failing). Core library builds clean
on net472, netstandard2.0, net8.0, net9.0, and net10.0. Test project
builds clean on net472 + net10.0.

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

* feat: route AgentResponse(Update) through the output filter under a Futures flag

`InProcessRunnerContext.YieldOutputAsync` historically special-cased AgentResponse and
AgentResponseUpdate payloads: it built the typed event subclass and emitted it directly,
bypassing the output filter. Rewrites the method so that:

- When `Futures.EnableAgentResponseOutputTaggingAndFiltering` is `false` (the current
  default), AgentResponse(Update) keep the legacy bypass — emitted as
  AgentResponseEvent / AgentResponseUpdateEvent with no tags. Existing callers see no
  behavior change.
- When the flag is `true`, AIAgent payloads flow through the output filter just like
  every other payload type: undesignated sources are dropped, and the emitted event
  carries the source's tag set (empty for terminal `WithOutputFrom`, `{Intermediate}`
  for `WithIntermediateOutputFrom`, the set union when both designations apply).

Non-AIAgent (POCO) outputs also now carry the source's tag set on the emitted
WorkflowOutputEvent unconditionally — additive, since no existing assertion inspected
Tags. Subclass events (`AgentResponseEvent` / `AgentResponseUpdateEvent`) continue to
be emitted under both modes so `switch (evt) { case AgentResponseEvent: ... }`
consumer code keeps matching.

Adds `OutputFilter.TryGetTags` as the tag-aware lookup used by the runner.
`OutputFilter.CanOutput` is kept (still used by the existing sync tests in
`OutputFilterTests.cs`).

Tests
-----
- `Futures/Futures.AgentResponseOutputFilteringAndTaggingTests.cs` (new): the F1–F13
  matrix from the plan, covering every combination of `(flag on/off) × (designation)
  × (payload shape)`. Uses a `FuturesScope` IDisposable + a `FuturesSerial` xUnit
  collection (DisableParallelization = true) to keep the process-global flag from
  leaking across parallel tests.
- `OutputFilterTests.cs`: four new `Test_OutputFilter_…` cases for the `TryGetTags`
  surface (empty-tag-set for terminal designation, `{Intermediate}` for intermediate
  designation, union for accumulated designation, `false` for unregistered).

582/582 unit tests pass on net10.0 (565 baseline + 17 new).

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

* feat: tag-aware defaults and designation API on orchestration builders

Aligns the .NET orchestration builders with Python's output / intermediate-output
distinction. Each builder either applies a Python-aligned default designation set or
replays the user's explicit `WithOutputFrom` / `WithIntermediateOutputFrom` calls,
never both.

Static `AgentWorkflowBuilder.BuildSequential` / `BuildConcurrent` apply defaults
unconditionally (no user-facing fluent surface to take control through):

- Sequential: terminal `end` + every agent designated intermediate.
- Concurrent: terminal `end` + every agent and per-agent accumulator designated
  intermediate.

The three fluent instance builders memoize agent-typed designation calls in a
`Dictionary<AIAgent, HashSet<OutputTag>>` (empty set = terminal-only, non-empty =
intermediate tag(s)) so repeated calls dedupe naturally. They replay the entries
at `Build()` time, suppressing defaults when any call has been made:

- `HandoffWorkflowBuilder` / `HandoffWorkflowBuilderCore<TBuilder>` (also picked up
  by the obsolete `HandoffsWorkflowBuilder` via inheritance).
  Default: terminal `HandoffEnd` + every handoff agent intermediate.
  (Bug fix: legacy code relied on `WithOutputFrom(end)` to bind `HandoffEnd`. The
  new explicit-designation path bypasses that, so `Build()` now calls
  `BindExecutor(end)` unconditionally to keep validation happy.)
- `GroupChatWorkflowBuilder` — default: terminal host + every participant intermediate.
- `MagenticWorkflowBuilder` — default: terminal orchestrator + every team member
  intermediate.

Designating a non-participant agent throws `InvalidOperationException`.

The bare `WorkflowBuilder` default is unchanged — only the orchestration-style
builders gain implicit defaults, matching the plan's non-goal.

Tests
-----
- `AgentWorkflowBuilder.SequentialTests` / `.ConcurrentTests`: one default-spec
  assertion each.
- `GroupChatWorkflowBuilderTests`: defaults-match-spec, explicit-replaces-defaults,
  non-participant throws.
- `HandoffWorkflowBuilderTests` (new file): same three.
- `MagenticWorkflowBuilderTests` (new file): same three.

593/593 unit tests pass on net10.0 (582 baseline + 11 new).

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

* feat: WorkflowHostAgent forwards AgentResponseEvent unconditionally under Futures-on

Aligns the .NET Workflow-as-Agent surface with Python `as_agent`. Under
`Futures.EnableAgentResponseOutputTaggingAndFiltering = true`,
`WorkflowSession.InvokeStageAsync` now forwards `AgentResponseEvent`
unconditionally — joining `AgentResponseUpdateEvent` in ignoring the host's
`includeWorkflowOutputsInResponse` switch. That switch keeps governing the
generic `WorkflowOutputEvent` path for non-AIAgent payloads, where it is
further short-circuited by an `IsIntermediate()` check (tagged intermediate
outputs always surface).

Under Futures-off the legacy asymmetry is preserved: `AgentResponseUpdateEvent`
always forwarded, `AgentResponseEvent` gated by `includeWorkflowOutputsInResponse`.

Back-compat: with `Futures.EnableAgentResponseOutputTaggingAndFiltering` left at
its default `false`, observable behavior is identical to before.

`Futures` documentation gains a remark explaining the `Workflow.AsAIAgent()`
interaction in both flag states.

Runner fix
----------
`InProcessRunnerContext.YieldOutputAsync` now skips `Executor.CanOutput` for
AgentResponse-shaped payloads under both Futures branches. `AIAgentHostExecutor`
doesn't declare AgentResponse(Update) in its `Yields` set, so the historical
legacy bypass had silently skipped the check; Phase 3's Futures-on path was
running it and would reject AIAgent payloads. AIAgent-shaped payloads are now
always a valid output shape, matching the legacy bypass semantics.

Phase 4 follow-on
-----------------
Switched the three orchestration-builder designation-replay loops to iterate
`Dictionary.Keys` with a value lookup instead of constructing/destructuring
`KeyValuePair<,>`. Cleaner shape and avoids the netstandard2.0 / net472
`KeyValuePair<,>.Deconstruct` unavailability that surfaced when this branch
multi-TFM-built.

Tests
-----
`WorkflowHostSmokeTests.IntermediateForwarding` (new nested class, 6 tests):
- intermediate AgentResponse forwarded past the include-outputs gate (Futures on)
- terminal AgentResponse forwarded unconditionally (Futures on)
- terminal AgentResponse gated by include flag (Futures off, legacy)
- undesignated AIAgent executor emits no AgentResponseEvent under Futures-on
- legacy bypass still emits AgentResponseEvent under Futures-off
- intermediate tag is observable via `update.RawRepresentation`

The class joins the `FuturesSerial` xUnit collection so the process-global flag
is serialized against other Futures-toggling tests.

599/599 unit tests pass on net10.0 (593 baseline + 6 new).

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

* feat: SequentialWorkflowBuilder and ConcurrentWorkflowBuilder, OrchestrationBuilderBase

Promotes the Sequential and Concurrent orchestration shapes to first-class fluent
builder classes, matching Handoff / GroupChat / Magentic. Users can call
`WithOutputFrom(agents)` / `WithIntermediateOutputFrom(agents)` to control which
agents are designated output / intermediate sources; when no designation call is
made, the Python-aligned defaults apply (terminal aggregator output + every agent
intermediate; Concurrent also tags per-agent accumulators).

`AgentWorkflowBuilder.BuildSequential(...)` and `BuildConcurrent(...)` are kept
and now delegate to the new builders; observable behavior unchanged. Five static
factories now mirror each other:

- `AgentWorkflowBuilder.CreateSequentialBuilderWith(params IEnumerable<AIAgent>)`
- `AgentWorkflowBuilder.CreateConcurrentBuilderWith(params IEnumerable<AIAgent>)`
- `AgentWorkflowBuilder.CreateHandoffBuilderWith(AIAgent)`        (already existed)
- `AgentWorkflowBuilder.CreateGroupChatBuilderWith(Func<...>)`    (already existed)
- `AgentWorkflowBuilder.CreateMagenticBuilderWith(AIAgent)`       (new)

OrchestrationBuilderBase
------------------------
New abstract `OrchestrationBuilderBase<TBuilder>` unifies the shared fluent
surface across all five orchestration builders: `WithName`, `WithDescription`,
`WithOutputFrom`, `WithIntermediateOutputFrom`, and the
`ApplyOutputDesignations(builder, agentMap, kind, applyDefaults)` helper that
either replays the user's designations or invokes the orchestration-specific
defaults.

Removes ~150 LOC of duplicated designation-management code from the four
non-Handoff builders, plus the equivalent from `HandoffWorkflowBuilderCore`.

Tests
-----
- New `SequentialWorkflowBuilderTests.cs` / `ConcurrentWorkflowBuilderTests.cs`
  (replace the old `AgentWorkflowBuilder.{Sequential,Concurrent}Tests.cs`
  nested-class files). Method names normalized to
  `Test_<BuilderType>_<Scenario>[Async]`.
- Shared helpers (`DoubleEchoAgent`, `DoubleEchoAgentWithBarrier`,
  `WorkflowRunResult`, `RunWorkflow*`) moved from the old
  `AgentWorkflowBuilderTests` partial class into a new
  `OrchestrationTestHelpers` static class in `OrchestrationTestHelpers.cs`.
  Downstream test files (Group Chat, Handoff, Sequential, Concurrent) updated
  to qualify with `OrchestrationTestHelpers.*`.
- A new `AgentWorkflowBuilderTests.cs` covers the static surface directly:
  `BuildSequential` / `BuildConcurrent` invariants and aggregator wiring, plus
  null-rejection + round-trip checks for every `Create*BuilderWith` factory.
- New AsAgent intermediate-suppression tests on a nested `AsAgentForwarding`
  class for each of Sequential and Concurrent: build with only the terminal
  agent designated via `WithOutputFrom`, run via `AsAIAgent(...)`, assert via
  `AgentResponseUpdate.AuthorName` that intermediate agents do not surface.
  Both join the `FuturesSerial` collection.
- New `Test_<Builder>_WithDescriptionPropagatesToWorkflow` smoke tests on
  Sequential and Concurrent (newly available via the base class).

625/625 unit tests pass on net10.0.

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

* chore: dotnet format

* fixup: encoding

* fixup: charset

* fixup: Updates for PR feedback

* fixup: format

* fixup: merge issue

* Fix intermediate filtering on .AsAgent()

* fix filter logic

* fix: Revert logic change and add comments

---------

Co-authored-by: Jacob Alber <jalber@lokitoth.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-28 21:26:31 +00:00
d2f79930d5 .NET: feat: Update GroupChatManager semantics to match other Orchestration patterns (#6140)
* Refactor group chat workflow to prevent message echoing and enhance checkpointing

- Updated GroupChatWorkflowBuilder to disable forwarding incoming messages to prevent duplicates.
- Enhanced RoundRobinGroupChatManager with checkpointing support to preserve state across executions.
- Modified GroupChatHost to maintain a history of messages and track the current speaker for message broadcasting.
- Implemented broadcasting logic to ensure participants receive messages from others while excluding their own responses.
- Added comprehensive unit tests for group chat orchestration, including scenarios for tool approval and function calls.
- Introduced a new ApprovalHarness for testing tool invocation and approval workflows.

* fixup: format

* Add JSON serialization support for GroupChatManagerState and RoundRobinGroupChatManagerState

---------

Co-authored-by: Jacob Alber <jalber@lokitoth.com>
2026-05-28 18:40:48 +00:00
3ee1bb4f9f .NET: [Breaking] Refactor AgentFileSkillsSource for depth-based discovery and predicate filters (#6109)
* Refactor AgentFileSkillsSource to use filter predicates and add AgentFileSkillFilterContext

- Replace hardcoded script/resource directory lists with configurable ScriptFilter and ResourceFilter predicates
- Add AgentFileSkillFilterContext class to provide contextual file information to filter predicates
- Replace MaxSearchDepth constant with configurable SearchDepth option
- Update AgentFileSkillsSourceOptions with new filter and search depth properties
- Update tests to reflect the new filtering approach

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

* Log '(none)' instead of empty string for missing file extensions in debug output

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-28 18:14:57 +00:00
945647a065 .NET: feat: Bring Handoff Orchestration to parity with Python (#6138)
* feat: implement autonomous mode and termination conditions in handoff workflow

* fixup: format

* feat: enhance autonomous mode with per-agent configurations and add unit tests

* fixup: remove empty file

---------

Co-authored-by: Jacob Alber <jalber@lokitoth.com>
2026-05-28 18:04:15 +00:00
Jacob AlberGitHublokitothcopilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
401a552735 .NET: Support ClaimsIdentity-based scoping of agent sessions (#5696)
* feat: Add DelegatingAgentSessionStore

Add helper for decorator pattern for AgentSessionStore

* feat: Add UserIdentityScopedSessionStore

Add support for using the ASP.Net Core ambient `ClaimsIdentity` User, along with a user-specified claim type to scope the session store based on authenticated identity.

* fix: Harden scope mapping

* fix: Add UserIdentityScopeSessionStoreOptions to avoid future breaking changes

* Split UserIdentityScopedSessionStore into a separate IsolationKeyProvider and IsolationKeyScopedSessionStore

* Add GetService<>() capabilities to interrogate AgentSessionStore delegation chain

* Harden default for A2A hosting by using an IsolationKeyScopedAgentSessionStore when no store is available.

* Pipe isolation through Hosting helper extension methods

* Add comment to samples about adding SessionIsolationKeyProvider

* Fix isolation key provider nullability semantics

* fix A2A defaults

* fixup

* remove unneeded keyProvider requirement test

* Add trust-model XML docs to AgentSessionStore, InMemoryAgentSessionStore, MapAGUI, A2A entry points

Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/e466c53a-faad-40a8-8b5f-83cf0dce0b1d

Co-authored-by: lokitoth <6936551+lokitoth@users.noreply.github.com>

* fix: Switch ClaimsBasedIsolationKeyProvider to be Singleton

   * matches HttpContextAccessor and related MAF services

* release: Ensure new project is in the release filter

* fixup: Integraitaon tests

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: lokitoth <6936551+lokitoth@users.noreply.github.com>
2026-05-28 17:43:18 +00:00
af787569b3 Python: Align c# and python TodoProvider tool names (#6107)
* Align c# and python TodoProvider tool names

* Potential fix for pull request finding

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

* Address PR review: remove __slots__ and add typed schemas for tool params

- Remove __slots__ from TodoItem, TodoInput, and TodoCompleteInput classes
  (not needed for low-instance-count objects and hinders dev scenarios)
- Add _TodoAddItemSchema and _TodoCompleteItemSchema TypedDicts to provide
  proper JSON schema for todos_add and todos_complete tool parameters
- Use typing_extensions for Python 3.10 compatibility

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

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-28 08:40:13 +00:00
5d8dd4ea4b .NET: [BREAKING] Remove Support for Code-Gen in Declarative Workflows (#6095)
* Removed

* Remove sample

* Remove orphaned code-gen related code path

* Remove remaining references to code gen.

---------

Co-authored-by: Chris Rickman <crickman@microsoft.com>
Co-authored-by: Chris <66376200+crickman@users.noreply.github.com>
2026-05-27 20:14:38 +00:00
1d301af7d2 .NET: Add MCP-based skills support (skill-md type) (#6108)
* Add MCP-based skills support

- Add AgentMcpSkill, AgentMcpSkillResource, AgentMcpSkillsSource, and McpSkillIndex to Microsoft.Agents.AI.Mcp
- Add AgentSkillsProviderBuilderMcpExtensions for DI integration
- Add Agent_Step06_McpBasedSkills sample project
- Add unit tests for AgentMcpSkillsSource
- Update solution file and project references

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

* Remove unnecessary [Experimental] attributes from MCP package

The package is already alpha, so the [Experimental] attribute is redundant.
Removed from both AgentSkillsProviderBuilderMcpExtensions and
AgentMcpSkillsSource classes.

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

* Make Agent_Step06_McpBasedSkills self-contained and add to verify-samples

Embed an internal MCP server (launched via --server flag as a child process)
that serves skill://index.json and skill://unit-converter/SKILL.md resources,
replacing the external MCP_SKILLS_ENDPOINT dependency. The sample now uses
StdioClientTransport and a fixed prompt instead of an interactive loop.

Added SampleDefinition to AgentsSamples.cs for automated verification.

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

* Sort usings

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-27 18:38:57 +00:00
Peter IbekweandGitHub 08697f8037 Persist ForeachExecutor iteration state across checkpoints (#6051) 2026-05-26 18:26:12 +00:00
westeyandGitHub bd4fc64b4d Python: Align ModeProvider tool names and instructions (#6071)
* Align ModeProvider tool names and instructions

* Address PR comments
2026-05-26 14:37:34 +00:00
08541ee5a9 .NET: [Breaking] Refactor AgentSkill API to async resource and script lookup (#6030)
* .NET: Refactor AgentSkill API to async resource and script lookup

Replace property-based AgentSkill.Content, Resources, and Scripts with
async-by-name lookup methods plus boolean availability flags:

- Content (string getter) -> GetContentAsync(CancellationToken)
- Resources (full list) -> HasResources + GetResourceAsync(name, ct)
- Scripts (full list) -> HasScripts + GetScriptAsync(name, ct)

This makes the API friendlier for sources like MCP where enumerating all
resources up front is expensive or impossible, and allows skill implementations
to fetch content lazily.

Subclass changes:
- AgentFileSkill and AgentInlineSkill implement the new async API while
  preserving content caching.
- AgentClassSkill<TSelf> keeps virtual Resources/Scripts properties for
  reflection-based discovery and seals the new HasResources/HasScripts/
  GetResourceAsync/GetScriptAsync overrides. Its previously non-thread-safe
  lazy initialization is replaced with Lazy<T> (default thread-safety) wired
  up in a new protected constructor, so concurrent first-access from multiple
  threads is safe.
- AgentSkillsProvider calls the new async API and exposes 
ead_skill_resource
  / load_skill / 
un_skill_script tools that await the per-name lookups.

Includes baseline CompatibilitySuppressions.xml entries for the removed
property getters.

Tests:
- Direct coverage for HasResources, HasScripts, GetResourceAsync, and
  GetScriptAsync on all three skill implementations (positive, missing-name,
  and no-resources/no-scripts cases).
- Thread-safety regression test for AgentClassSkill<TSelf> that exercises
  concurrent first-access to Resources, Scripts, and GetContentAsync from
  many tasks and asserts all observers see the same cached instance.
- Provider-level coverage for the 
ead_skill_resource tool (invocation +
  error paths) and for the previously untested error paths of load_skill
  and 
un_skill_script (empty names, skill/resource/script not found).

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

* Address PR review comments

- Move GetScriptAsync inside try/catch in RunSkillScriptAsync for error-handling parity
- Remove dead _reflectedResources branch from AgentSkillTestExtensions
- Fix XML docs to reference virtual Resources/Scripts properties (not sealed methods)
- Add Async suffix to async test methods per naming convention
- Make no-await tests synchronous to eliminate CS1998

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

* Fix formatting: add UTF-8 BOM and remove unused using

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

* Fix XML cref: Resources/Scripts are on AgentClassSkill<TSelf>

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

* Remove HasResources and HasScripts properties from AgentSkill

Drop the virtual HasResources and HasScripts properties from AgentSkill
and all concrete subclasses (AgentFileSkill, AgentInlineSkill,
AgentClassSkill). AgentSkillsProvider now always includes all three
tools (load_skill, read_skill_resource, run_skill_script) and both
instruction blocks, since the tools already handle missing
resources/scripts gracefully.

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

* Add blank line for readability in file-based skills sample

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

* Fix HostedAgentSkillsPatternTests for always-included tools

Update assertions to expect read_skill_resource and run_skill_script
tools are always present, matching the new behavior.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-25 17:16:03 +00:00
dc4bafbc1e .NET: Add Hosted-AgentSkills sample with Foundry Skills integration (#6013)
* .NET: Add Hosted-AgentSkills sample for Foundry Skills integration

Add a new hosted agent sample that demonstrates how to load behavioral
guidelines from Foundry Skills at startup using AgentSkillsProvider and
the progressive disclosure pattern (advertise -> load on demand).

The sample:
- Downloads SKILL.md files from Foundry via ProjectAgentSkills SDK
- Extracts ZIP archives with zip-slip protection
- Wires skills into AgentSkillsProvider as an AIContextProvider
- Hosts the agent via the Responses protocol

Ships two Contoso Outdoors skills matching the Python sample (PR #5822):
- support-style: tone, formatting, signature guidelines
- escalation-policy: when and how to escalate tickets

Includes convenience provisioning gated behind PROVISION_SAMPLE_SKILLS
env var, clearly documented as NOT a production pattern.

Closes #5776

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

* .NET: Add unit tests and integration test for Hosted-AgentSkills

Unit tests (14 tests, all passing):
- ZIP extraction with zip-slip guard (valid archive, traversal attack,
  sibling-prefix attack, directory entries)
- Skill name validation (rejects dots, separators, traversal patterns)
- AgentSkillsProvider with downloaded skills (advertises both skills,
  load_skill returns canary tokens, unknown skill returns error)

Container integration test:
- New 'agent-skills' scenario in the test container that creates
  Contoso Outdoors skills on disk and wires AgentSkillsProvider
- AgentSkillsHostedAgentFixture + 4 integration tests verifying:
  - Routine questions load support-style skill (STYLE-CANARY-3318)
  - Escalation triggers load escalation-policy (ESC-CANARY-7742)
  - Skills are advertised in system prompt
  - load_skill tool is invoked via FunctionCallContent

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

* .NET: Add smoke test, bootstrap, and docs for agent-skills integration

- Add scripts/smoke.ps1 for local Docker smoke testing: builds the
  contributor image, runs the container, verifies both skills are loaded
  via canary tokens (STYLE-CANARY-3318, ESC-CANARY-7742)
- Add 'agent-skills' to the bootstrap script scenario list
- Add agent-skills row to the integration test README scenarios table
- Exclude HostedAgentSkillsPatternTests from net472 (uses net8.0+ APIs)

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

* .NET: Update commented-out package versions to latest across all hosted samples

Update the end-user PackageReference versions (in the commented-out
sections) from 1.0.0 to the current latest NuGet versions:

- Microsoft.Agents.AI: 1.6.1
- Microsoft.Agents.AI.Foundry: 1.6.1-preview.260514.1
- Microsoft.Agents.AI.Foundry.Hosting: 1.6.1-preview.260514.1
- Microsoft.Agents.AI.Hosting: 1.6.1-preview.260514.1
- Microsoft.Agents.AI.OpenAI: 1.6.1
- Microsoft.Agents.AI.Workflows: 1.6.1

Also adds explicit versions to Hosted-Workflow-Handoff which had bare
PackageReference entries without Version attributes.

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

* .NET: Fix broken markdown links in Hosted-AgentSkills README

Remove references to non-existent ../../README.md. Replace with
inline instructions matching other hosted samples that don't have
a parent README.

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

* .NET: Use OS-appropriate string comparison in zip-slip guard

Use Ordinal on Unix (case-sensitive FS) and OrdinalIgnoreCase on
Windows to prevent case-based path bypass on Linux containers.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-25 09:32:04 +00:00
de6d0267f2 .NET: fix parallel tool call rendering in AGUI translation layer (#6009)
Fix three interlocked bugs that prevent parallel tool calls from rendering
correctly in AG-UI protocol clients:

Bug #1: Scope synthetic MessageId fallback to text events only. The shared
streamingMessageId was leaking into ToolCallStartEvent.ParentMessageId,
causing all parallel tool calls to collapse into one FE card.

Bug #2: Make ToolCallResultEvent.MessageId deterministically unique using
result-{CallId} format. MEAI's FunctionInvokingChatClient batches all
results with a shared MessageId, collapsing them in FE reconciliation.

Bug #3: Coalesce consecutive assistant-tool-call messages in AsChatMessages.
Once Bug #1 is fixed, the FE produces separate AGUIAssistantMessage per
tool call. On multi-turn replay these become consecutive assistant messages
without intervening tool results, triggering HTTP 400 from Azure OpenAI.

Remove the now-dead ContainsToolResult helper introduced by PR #5800.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-25 09:31:29 +00:00
Peter IbekweandGitHub 793403f3db .NET: Add MCP long-running task support for MCP client tools (#5994)
* Add MCP long-running task support for MCP client tools

* Fixed project file formatting issue.

* Removed experimentation tag from MCP alpha project.

* Addressed PR comments
2026-05-22 19:09:54 +00:00
abc9b60ec9 fix: populate MessageId from TaskStatusUpdateEvent.Status.Message (#6043)
When A2AAgent receives a TaskStatusUpdateEvent during streaming,
ConvertToAgentResponseUpdate now sets AgentResponseUpdate.MessageId
from Status.Message.MessageId when the message is present.

This fixes the missing message correlation metadata reported in
microsoft/agent-framework#4987.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-22 18:15:06 +00:00
b559545fa4 .NET: Fix declarative workflow regressions for hosted agents (#5905)
* Fix declarative workflow regressions for hosted agents

Three regressions surfaced when running a declarative workflow as a
Foundry hosted agent. Together they caused every condition group to fall
through to elseActions and the raw agent JSON to leak to the caller.

1. AgentProviderExtensions.InvokeAgentAsync forced autoSend to true
   whenever the agent ran on the workflow conversation, which overrode
   the explicit autoSend: false declared in workflow.yaml and streamed
   the raw structured-output JSON straight to the user. Honor the
   caller-supplied autoSend instead.

2. IWorkflowContextExtensions.ReadState / QueueStateUpdateAsync /
   QueueStateResetAsync took the variable name and namespace alias
   directly from PropertyPath.VariableName / NamespaceAlias. Against
   Microsoft.Agents.ObjectModel 2026.2.4.1 those properties return null
   for a dotted reference such as `Local.Triage` even when
   SegmentCount == 2 and IsValid == true, so every assignment threw
   ArgumentNullException via Throw.IfNull. Fall back to Segments() to
   reconstruct the name and alias when the parser returns null.

3. The same ObjectModel version no longer recognizes the user-facing
   `Local` scope alias: VariableScopeNames.IsValidName(`Local`)
   returns false and GetNamespaceFromName(`Local`) returns Unknown, so
   the declarative interpreter's IsManagedScope check fails and the
   State.Set call is silently skipped. Translate the `Local` alias to
   its canonical `Topic` form before forwarding to
   QueueStateUpdateAsync; WorkflowFormulaState.Bind continues to expose
   it as `Local` to PowerFx.

Verified end-to-end against a deployed Foundry hosted agent: the
declarative triage workflow now routes Technical / Billing / General
inputs correctly and only the autoSend-eligible messages reach the
caller.

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

* Hosted-agent HITL: persist session across previous_response_id chains; run approved local AIFunctions

Two regressions hit declarative workflows that use require_approval=true when
the client chains turns via previous_response_id (no conversation_id):

1. AgentFrameworkResponseHandler keyed the AgentSession store solely on
   conversation_id, so when only previous_response_id was present the
   StateBag (which holds ToolApprovalIdMap) was discarded after each turn.
   The next turn then threw 'No approval mapping recorded for wire id ...'
   in InputConverter.ConvertMcpApprovalResponse.

   Fix: fall back to previous_response_id on load and to context.ResponseId
   on save so the response-id chain becomes a valid session key. Conversation
   id remains preferred when present.

2. InvokeFunctionToolExecutor.CaptureResponseAsync only acted on
   FunctionResultContent. In the hosted Foundry path the approval response
   arrives as a ToolApprovalResponseContent with no FunctionResultContent,
   so the local AIFunction never ran and downstream PropertyPath/SendActivity
   consumers (e.g. {Local.RefundResult}) saw empty values.

   Fix: when no FunctionResultContent matches but an approved
   ToolApprovalResponseContent does, look up the registered AIFunction by
   name on agentProvider.Functions and invoke it with the evaluated
   arguments, surfacing the result through the existing assignment path.

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

* Apply PropertyPath workaround to initialization path; share + tidy helpers

Address PR #5905 review feedback:

* Move the PropertyPath VariableName/NamespaceAlias fallback and 'Local'
  -> 'Topic' scope remap into a shared internal PropertyPathExtensions
  helper. Materializes Segments() once, names the magic 'Local' alias
  as a const, and carries a TODO referencing the tracking issue.

* Apply the same helper in WorkflowDiagnostics.InitializeDefaults so a
  declared default for a dotted variable like 'Local.Triage' is no
  longer silently skipped at workflow startup (closes the gap flagged
  by the reviewer: runtime ReadState/QueueStateUpdateAsync worked but
  state.Initialize did not).

* Restore the previous strict failure mode on namespace alias by
  wrapping GetNamespaceAlias() in Throw.IfNull at call sites so a
  malformed single-segment path keeps failing fast rather than
  silently passing null to State.Get/Set.

All 821 unit tests pass.

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

* Add tests for AgentProviderExtensions.InvokeAgentAsync autoSend behavior

Covers the autoSend regression fix: when the agent runs on the workflow conversation with autoSend=false, no AgentResponseUpdateEvent or AgentResponseEvent is added to the context. Also covers autoSend=true (events emitted) and autoSend=false on a non-workflow conversation.

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

* Surface SendActivity output via AgentResponseUpdateEvent

SendActivityExecutor previously only emitted the activity text via YieldOutputAsync, which the runtime converts to an AgentResponseEvent. WorkflowSession gates AgentResponseEvent behind includeWorkflowOutputsInResponse, so when a host opts out of summary outputs (the default for AsAIAgent) the SendActivity reply is silently dropped.

Mirror the pattern used by AgentProviderExtensions for autoSend agent invocations: also emit an AgentResponseUpdateEvent, which WorkflowSession yields unconditionally. This makes SendActivity reliably reach chat-protocol clients without requiring includeWorkflowOutputsInResponse = true (which would also duplicate autoSend agent output).

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

* Revert previous_response_id session-key fallback

The fallback let a session be keyed by an unbroken previous_response_id chain,
but conversation_id is the right way to thread state across turns: it survives
shared/branched chains (e.g. when another agent generates a response in between)
and is the documented model for stateful clients. Restore conversation_id as the
sole session key and rely on the client to thread it. The InvokeFunctionTool
approval/local-function half of 1baf4af4d remains.

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

* Set Foundry ProductContext per-executor instead of via PropertyPath workaround

ObjectModel 2026.2.4.1 resolves PropertyPath.VariableName / NamespaceAlias and VariableScopeNames.IsValidName against AsyncLocal<ProductContext> at access time. In hosted-agent scenarios each HTTP request runs on a fresh async context where that AsyncLocal is default, so dotted refs like Local.Triage returned null and the Local scope alias was rejected.

Replace the PropertyPathExtensions helper (which papered over both symptoms) with a single WorkflowDiagnostics.SetFoundryProduct() call at the entry of DeclarativeActionExecutor.HandleAsync. The set writes to the request's logical async context before any code reads PropertyPath, letting the existing parser and scope resolver work as designed.

Validated: 824/824 declarative unit tests pass; technical/billing/general routes all dispatch correctly against a deployed Foundry hosted agent.

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

* Address review feedback on InvokeFunctionToolExecutor

- Surface registered-function lookup failures and invocation exceptions via FunctionResultContent.Exception instead of returning the error text as a successful Result, so downstream {Local.X} assignments can distinguish failures from successes.

- Use AIJsonUtilities.DefaultOptions to JSON-serialize non-string function results (matching FunctionInvokingChatClient / ToolBridge), so complex types stay consumable by PropertyPath consumers instead of degrading to Object.ToString().

- Drop the explicit System. prefix on StringComparison / Exception now that the file imports System.

- Add AutoSendTrueOnExternalConversationEmitsResponseEventsAndCopiesMessagesAsync to cover the (autoSend: true, external conversation) quadrant, asserting that response events are emitted and that messages are mirrored to the workflow conversation.

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

* Honor AutoSendIsDefaultValue when computing autoSend

AzureAgentOutput.AutoSend and InvokeToolOutput.AutoSend in
Microsoft.Agents.ObjectModel 2026.2.4.1 are never null — they
return a literal-false default when the YAML omits the field.
The previous null check in Get/AutoSendValue therefore always
fell through to evaluating the literal false, so every action
whose YAML had any output block but no explicit autoSend was
treated as autoSend = false. This was previously masked by
`autoSend |= isWorkflowConversation` in AgentProviderExtensions
(removed earlier in this PR to honor explicit autoSend: false),
which silently re-enabled autoSend on the workflow conversation.

Use AutoSendIsDefaultValue to distinguish an explicit autoSend
value from the implicit default and treat the implicit default
as true, restoring the historical behavior for ValidateCaseAsync
InvokeAgent.yaml (3 InvokeAzureAgent actions, last one captures
to Local.RatingResponse via output.messages with no autoSend
specified) while keeping the hosted-agent fix that honors an
explicit autoSend: false.

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

---------

Co-authored-by: Ben Thomas <25218250+alliscode@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-22 01:06:38 +00:00
afd2739e38 .NET: Surface x-ms-served-model header as ChatResponse.ModelId for Foundry agents (#5979)
* .NET: Surface x-ms-served-model header as ChatResponse.ModelId for Foundry agents

Mirrors Python PR #5910. Adds an internal SCM PipelinePolicy that reads the x-ms-served-model HTTP response header on Azure OpenAI Responses calls and writes it into an AsyncLocal box. A DelegatingChatClient sits between OpenTelemetry and the MEAI OpenAIResponsesChatClient and overwrites ChatResponse.ModelId with the served snapshot so OTel spans report the actual model rather than the deployment alias. Wired through all AsAIAgent paths in Microsoft.Agents.AI.Foundry.

* .NET: Fix line endings and BOM on ResponsesAgentServedModelTests

* .NET: Address Copilot review on Foundry served-model PR

- Restore previous ServedModelScope in finally to avoid AsyncLocal leak into caller execution context.
- Make served-model integration test assertion robust to deployment names that already match the snapshot pattern.
- Broaden UnitTests csproj comment to cover all conditional removals (net8.0+ requirement).

* .NET: Split ServedModelTests into per-SUT files with regions

Split the combined ServedModelTests.cs into one test class per SUT:

- ServedModelScopeTests.cs (AsyncLocal carrier)
- ServedModelPolicyTests.cs (SCM pipeline policy)
- ServedModelChatClientTests.cs (delegating client, with regions for Non-streaming / Streaming / End-to-end)

Shared helpers and fake clients moved into ServedModelTestHelpers.cs.

Csproj net8.0+ exclusion list updated accordingly.

* .NET: Consolidate served-model logic into FoundryChatClient

Move x-ms-served-model header capture from the standalone ServedModelChatClient
decorator directly into FoundryChatClient, eliminating a separate wrapper that
had to be applied at every Foundry entry point via WireServedModel().

- Register ServedModelPolicy in FoundryChatClient constructors (alongside the
  existing AgentFrameworkUserAgentPolicy registration)
- Add StrongBox push/read logic to FoundryChatClient.GetResponseAsync and
  GetStreamingResponseAsync
- Delete ServedModelChatClient.cs and its unit tests
- Remove WireServedModel() from FoundryAgent and AIProjectClientExtensions
- Update ServedModelPolicy/Scope XML docs to reference FoundryChatClient
- Simplify ServedModelTestHelpers to use FoundryChatClient directly

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-05-21 21:26:42 +00:00