Commit Graph

647 Commits

Author SHA1 Message Date
Peter Ibekwe 3f4ffc6c2c .NET: Fix declarative InvokeAzureAgent failing on non-object JSON agent output (#7002)
* Fix declarative InvokeAzureAgent failing on non-object JSON agent output

* Fix PR comments.
2026-07-09 17:10:51 +00:00
westey 76f2c1a0c9 .NET: [BREAKING] Graduate per-service-call persistence and approval-not-required function bypassing (#6970)
* Remove experimental flags for RequirePerServiceCallChatHistoryPersistence and DisableApprovalNotRequiredFunctionBypassing

* Address PR comments

* Fix failing test
2026-07-08 09:31:33 +00:00
Evan Mattson 12b029858e Build(deps): consolidate Dependabot dependency updates (#6984)
* Consolidate Dependabot dependency updates

* Restore method assignment suppression
2026-07-08 09:09:03 +00:00
Javier Calvarro Nelson 3d17615b6e .NET: Replace MAF AG-UI abstractions with the AG-UI C# SDK abstractions (#6653)
* .NET: Replace internal AG-UI implementation with external ag-ui packages

Remove the in-tree Microsoft.Agents.AI.AGUI sources and consume the external
AG-UI .NET SDK packages (AGUI.Abstractions, AGUI.Formatting, AGUI.Protobuf,
AGUI.Client, AGUI.Server) at 0.1.0-preview instead.

- Microsoft.Agents.AI.Hosting.AGUI.AspNetCore keeps its own ASP.NET glue
  (MapAGUI / AddAGUI / SSE result) layered over the framework-agnostic
  AGUI.Server primitives (ToChatRequestContext / AsAGUIEventStreamAsync).
- Migrate call sites to the options-based AGUIChatClient constructor and recover
  the originating AG-UI input via ChatOptions.TryGetRunAgentInput.
- Multi-turn continuation flows through parentRunId + threadId on
  RawRepresentationFactory; shared state flows through RunAgentInput.State and is
  surfaced as StateSnapshotEvent raw representations.
- Update samples, hosting/unit/integration tests, and central package versions.

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

* Add migration README for removed Microsoft.Agents.AI.AGUI package

Keep the package folder in place with a README explaining that the in-tree AG-UI protocol abstractions moved to the external AGUI.* NuGet packages, with a mapping of old namespaces to the new packages and a migration guide.

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Roger Barreto <19890735+rogerbarreto@users.noreply.github.com>
2026-07-07 20:09:53 +00:00
westey 757a832dbf .NET: Add OpenTelemetry Chat Client to harness stack (#6961)
* Add OpenTelemetry Chat Client to harness stack

* Address PR comments
2026-07-07 14:14:26 +00:00
Tamir Dresher cc20093da1 .NET: fix: bump GitHub.Copilot.SDK to 1.0.5 to resolve strong-naming mismatch (#6949)
* fix: bump GitHub.Copilot.SDK to 1.0.5 to resolve strong-naming mismatch

SDK 1.0.5 introduced strong-naming (PublicKeyToken=cc7b13ffcd2ddd51).
The adapter was compiled against the unsigned SDK (PublicKeyToken=null),
causing CS0012 for any consumer referencing both packages.

Fixes #6948

* fix: update tests and extension for SDK 1.0.5 namespace changes

- Add 'using GitHub.Copilot;' to CopilotClientExtensions.cs
- Change extension namespace to Microsoft.Agents.AI.GitHub.Copilot
- Update test files for new SDK types and removed APIs
- Add #pragma to suppress GHCP001 experimental warnings in tests
- All 45 tests pass across net8.0, net9.0, net10.0

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

* style: run dotnet format to fix linting issues

Remove unnecessary using directives (IDE0005) and fix file encoding (CHARSET).

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

* fix: revert CopilotClientExtensions namespace to GitHub.Copilot

Per reviewer feedback, extension methods should live in the namespace
of the type they extend (CopilotClient). This follows .NET team guidance.
The original namespace was GitHub.Copilot.SDK which was renamed to
GitHub.Copilot in SDK 1.0.5.

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

* refactor: narrow tools parameter from AITool to AIFunctionDeclaration

Since SessionConfig.Tools only accepts AIFunctionDeclaration, change the
constructor and extension method parameters to accept IList<AIFunctionDeclaration>
instead of the more general IList<AITool>. This makes the API honest about what
it actually uses and avoids silently discarding non-AIFunctionDeclaration tools.

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

* fix: sync Directory.Packages.props with upstream main

Take upstream's package versions (including MessagePack 3.1.7 pin
that fixes NU1902/NU1903 vulnerability warnings) while keeping
GitHub.Copilot.SDK at 1.0.5 which is the purpose of this PR.

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

---------

Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-07 14:09:28 +00:00
Tao Chen 5ac5038545 .NET: Add defense-in-depth for MCP cross origin request (#6871)
* Add defense-in-depth for MCP cross origin request

* Address comments
2026-07-06 17:37:36 +00:00
Roger Barreto c09408cbd6 .NET: Fix flaky OpenTelemetryAgentTests via thread-safe activity collector (#6935)
* .NET: Fix flaky OpenTelemetryAgentTests via thread-safe activity collector

The Ctor_NullOrWhitespaceSourceName test subscribed a process-global TracerProvider to the shared default source Experimental.Microsoft.Agents.AI and exported into a plain List<Activity>. That source is also used by CompactionTelemetry, and xUnit runs the Compaction test classes in parallel, so a compaction span could be appended from another thread mid-assertion, throwing 'Collection was modified'.

Add a thread-safe ConcurrentActivityList collector (locked Add plus snapshot enumeration) for all InMemoryExporter collectors in the file, and scope the shared-source test to its own invoke_agent TraceId after ForceFlush so parallel compaction spans cannot affect the count or source-name checks.

* .NET: Assert ForceFlush result in OpenTelemetryAgentTests default-source test

Assert the boolean returned by TracerProvider.ForceFlush(timeout) so a flush timeout surfaces as a clear test failure instead of silently snapshotting incomplete activities.
2026-07-06 16:11:11 +00:00
westey ccba1fbbef .NET: [BREAKING] Align ShellPolicy allow/deny semantics with Python (#6906)
* Align dotnet shell policy with python implementation to support deny if not allowed semantics.

* Address PR comments.

* Address PR comments
2026-07-03 18:09:35 +00:00
Roger Barreto 2c7aadce4e .NET: Validate Foundry toolbox name is a single path segment before building the proxy URL (#6890)
* Validate Foundry toolbox name is a single path segment before building the proxy URL

Reject toolbox name/identifier inputs that carry path separators or relative-path segments (including their percent-encoded forms) before they are interpolated into the toolbox MCP proxy request URL, so a caller-influenced marker cannot alter the request target. Validation runs both at per-request marker resolution and at the shared open choke point, and is covered by red-to-green unit tests.

* Reject residual percent-encoding in toolbox name validation

After the bounded percent-decode loop, also reject a name that still contains a percent sign, so encoding nested deeper than the decode cap cannot survive validation. Dispose the service via await using in the rejection test. Adds a deeply-encoded coverage case.

* Validate toolbox name by request-target effect instead of a character list

Replace the character/decoding checks with an effect-based check: build the proxy URL and confirm the name resolves to a single, intact path segment between 'toolboxes' and 'mcp' with the scheme, authority, path shape, and fragment unchanged, and that the segment round-trips back to the name. This forgives characters that stay inside the segment (for example ':' , '@' , parentheses) while still rejecting names that would move the request target, including '?' and '#' and their percent-encoded forms. Adds coverage for the delimiter cases and for the newly-allowed names.
2026-07-03 17:00:26 +00:00
Roger Barreto 8be157e2a1 Return 404 for a response created against a nonexistent conversation (#6892)
When a create-response request references a conversation id that does not
exist, validate its existence up front and return a clean not-found error
mapped to HTTP 404, consistent with the Conversations API, instead of failing
mid-execution and surfacing a generic server error.

Centralize the responses validation error codes and their HTTP status mapping
in a single ResponseErrorCodes type so handlers translate a code to a 404 or
400 without ad-hoc string comparisons. Add unit and HTTP integration tests.
2026-07-03 17:00:00 +00:00
SergeyMenshykh 331d17c5a1 .NET: fix: Require explicit TokenCredential in AddFoundryToolboxes (#6877)
* fix: require explicit TokenCredential in AddFoundryToolboxes

The AddFoundryToolboxes extension methods now require callers to
pass a TokenCredential explicitly rather than relying on an
internally-created default credential. This makes the credential
choice intentional and avoids non-deterministic credential probing
in production environments.

Breaking change (experimental API):
- AddFoundryToolboxes(IServiceCollection, params string[]) becomes
  AddFoundryToolboxes(IServiceCollection, TokenCredential, params string[])
- AddFoundryToolboxes(IServiceCollection, Action?, params string[]) becomes
  AddFoundryToolboxes(IServiceCollection, TokenCredential, Action?, params string[])
- Azure.Identity package dependency removed from Foundry.Hosting library.

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

* fix: simplify redundant generic type argument (IDE0001)

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

* fix: avoid duplicate FoundryToolboxService registration

Inject the AddFoundryToolboxes credential directly into the
FoundryToolboxService factory and fail early if the service was
already registered. This avoids registering TokenCredential in the
host DI container while preserving a single toolbox service instance
for both request handling and hosted startup.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-02 15:44:56 +00:00
westey 48436f8ab6 .NET: Make default-approval harness features configurable + customizable shell tool (#6880)
* Dotnet: Allow devs to opt-out of file-access approvals

* Address PR comments
2026-07-02 14:57:59 +00:00
Roger Barreto 551b44f04f .NET: Bump Azure.AI.Projects to 2.1.0-beta.4 (#6795)
* .NET: Bump Azure.AI.Projects to 2.1.0-alpha.20260629.1

Bumps Azure.AI.Projects beta.3 to alpha.20260629.1 and aligns transitive deps (System.ClientModel 1.14.0, Azure.Core 1.59.0, Msal 4.84.2). Adapts to renamed AgentSessionFiles APIs (Upload/GetAll/Delete, scoped GetAgentSessionFiles, SizeInBytes), AgentToolboxes (CreateVersion/Delete), and strongly typed toolbox tools (WebSearchToolboxTool, MCPToolboxTool). Adds azure-sdk public dev feed for prerelease restore.

* Use positional arg for AgentSessionFiles.DeleteAsync cleanup

* Move to Azure.AI.Projects 2.1.0-beta.4 (released beta)

Swaps the alpha daily build for the published 2.1.0-beta.4. Drops the azure-sdk public dev feed since beta.4 and its deps are on nuget.org. Beta.4 requires Azure.Core 1.60.0, which cascades the 10.0.8 servicing packages (Microsoft.Bcl.AsyncInterfaces, System.Diagnostics.DiagnosticSource, System.Text.Json, System.Threading.Channels, Microsoft.Extensions.DependencyInjection.Abstractions, Microsoft.Extensions.Logging.Abstractions) to 10.0.9.

* Reconcile Azure.Core 1.60.0 bump with merged main

Reverts the over-eager System.Threading.Channels 10.0.9 bump back to 10.0.8 (it was not part of the Azure.Core 1.60.0 cascade and caused a net472 MSB3277 conflict against the 10.0.8 that Microsoft.Extensions.AI pulls). Drops the now-obsolete Azure.Core VersionOverride=1.59.0 in HostedWorkflowHandoff (added on main to satisfy AgentServer while the central pin was lower); the central pin is now 1.60.0 which already satisfies the >=1.59.0 floor, and the override was downgrading this project below sibling projects (CS1705).
2026-07-02 14:40:03 +00:00
Roger Barreto 62f0024707 .NET: Foundry Hosting gracefully tolerates lacking user identity when run locally (#6870)
* .NET: Make Foundry Hosting resilient to missing user identity in local runs

AgentFrameworkResponseHandler threw InvalidOperationException (surfaced as a
500 on every request) when the isolation-key provider returned null, which
always happens locally because the platform x-agent-user-id header is absent.
Running a hosted image outside Foundry therefore failed out of the box.

The handler now branches on FoundryEnvironment.IsHosted: hosted stays strict
(null identity is still a hard error), but non-hosted (local docker run /
dotnet run) tolerates a null identity - per-user isolation is simply not
triggered, the request proceeds with userId null (no partition), and no
hosted context is stamped or validated.

Because local runs no longer need a fallback, the sample-side
DevTemporaryLocalUserIdProvider and AddDevTemporaryLocalContributorSetup are
removed from Hosted_Shared_Contributor_Setup and all sample Program.cs files.
To simulate distinct users locally, send an x-agent-user-id request header;
the default provider reads it exactly as it reads the platform-injected value.
The Memory sample smoke script now drives alice/bob against one container via
that header. AGENT_NAME defaults added to Hosted-ChatClientAgent and
Hosted-MemoryAgent so a hosted deploy (where AGENT_* is a reserved env var)
does not crash at startup.

Updates the two affected unit tests to assert the local-success path and
amends ADR 0031.

* Address review: correct isolation-guarantee and Memory-sample local docs

- AgentFrameworkResponseHandler: note the null/local case is unscoped/shared,
  not fully partitioned per user.
- HostedSessionIsolationKeyProvider XML docs: phrase the non-null UserId rule as
  a constraint on the returned-context case, since null is now allowed locally.
- Hosted-MemoryAgent: the PerUser() memory scope requires a resolved user, so a
  local run needs an x-agent-user-id header; corrected the Program.cs comment
  and README (removed the inaccurate "shared bucket locally" claim).
- Test: assert absence of any u-* per-user directory via a wildcard search
  rather than checking for a literal "u-" directory.
2026-07-02 09:32:22 +00:00
westey 300dfa7e36 .NET: [BREAKING] Refactor OpenAI Hosting OptionsMapping to disallow passing options by default (#6855)
* Refactor OptionsMapping to disallow passing options by default

* Address PR comments

* Address PR comment
2026-07-01 15:05:53 +00:00
westey e56f34c521 .NET: [BREAKING] Add file editing tools and align FileAccess/FileMemory store API (#6807)
* Add support for editing to file access and memory plus renames

* Address PR comments

* Address PR comments
2026-07-01 13:35:48 +00:00
SergeyMenshykh 51c05fc862 .NET: Add skill approval options (#6843)
* .NET: Add skill approval options

Add per-tool options for disabling approval on skills provider tools and cover the behavior with unit tests.

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

* .NET: Document mixed approval behavior

Document the non-approval bypass requirement and update tests to avoid file-discovery dependency.

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

---------

Co-authored-by: SergeyMenshykh <SergeMenshikh@outlook.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
2026-07-01 12:46:08 +00:00
SergeyMenshykh b7fc23c61f .NET: Consolidate skill-source caching and make skill sources disposable (#6827)
* .NET: Consolidate skill-source caching and make skill sources disposable

Move all caching into the generic CachingAgentSkillsSource decorator and
remove the duplicate inline cache from AgentMcpSkillsSource, so a single
cache layer governs skill fetching. Add RefreshInterval-based expiry to
CachingAgentSkillsSourceOptions.

Make AgentSkillsSource (and its decorators) IDisposable so pipelines can
release owned resources, and give AgentSkillsProvider an ownsSource flag
controlling whether it disposes the source it wraps. Provider convenience
constructors and the builder set ownsSource: true.

Serialize ArchiveEntryLoader's reconcile/extract/read of the shared on-disk
directory with a per-instance lock to prevent concurrent corruption.

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

* .NET: Fix IDE0032 by using an auto-property in test source

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

* .NET: Make cancellation cache test deterministic

Ensure the first caller owns the fetch before the second caller queues, so
the cancellation-restart assertion is no longer race-prone.

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

* .NET: Throw ObjectDisposedException from CachingAgentSkillsSource after disposal

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

* .NET: Document AgentSkillsProviderBuilder source ownership and single-build contract

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

* .NET: Update API compatibility suppressions for AgentSkillsProvider ctor change

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

* .NET: Add test asserting archive skill updates are observed after reconcile

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-07-01 12:46:07 +00:00
Roger Barreto f9b2fbb676 .NET: Foundry Hosting per-user session isolation and Responses v2 protocol fast-fail (#6832)
* Add per-agent and per-user session storage isolation for Foundry Hosting

Partitions hosted session and checkpoint files as {root}/a-{agentName}/u-{userId}/c-{contextId}.json so a container that serves multiple agents and multiple users cannot leak state across tenants. The user layer collapses to a-{agent}/c-{conv}.json when no x-agent-user-id is present (raw local). Adds a reject-style path-traversal guard (CWE-22) for the untrusted user id plus a resolve-and-assert-under-root containment check, and keeps the strict-resume 403 identity check as a second defense layer.

AgentSessionStore.GetSessionAsync/SaveSessionAsync take a required (nullable) userId so a caller can never silently persist a session unscoped; the handler resolves the user id before loading the session and threads it to both. Tool approvals ride in the session checkpoint (ToolApprovalIdMap to AgentSessionStateBag), so the partitioned path covers them and no separate approval store is needed. Renames the sample HOSTED_USER_ISOLATION_KEY env var to HOSTED_USER_ID and DevTemporaryLocalSessionIsolationKeyProvider to DevTemporaryLocalUserIdProvider. Documents the design in ADR 0031. Adds handler-driven multi-agent/multi-user file-system tests and store-level traversal/isolation tests.

* Fail fast with a clear 501 when hosted container is served responses protocol 1.0.0

A 2.0.0-only hosted image served container protocol 1.0.0 (no x-agent-foundry-call-id
header) previously threw and surfaced an opaque 500 on every request. It now returns a
clear 501 "unsupported_container_protocol_version" naming the required protocol.

* HostedProtocolCompatibility gate keyed on FoundryEnvironment.IsHosted plus
  PlatformContext.CallId (the 2.0.0 exclusive marker); invoked before isolation resolution
* HostedProtocolCompatibilityTests unit coverage; AgentFrameworkResponseHandlerTests note
  clarifies the non-hosted path
* UnsupportedProtocolHostedAgentTests integration test deploys a dedicated
  it-unsupported-protocol agent as 1.0.0 and asserts the 501 (validated live on cace)
* TestContainer recognizes the unsupported-protocol scenario
* it-bootstrap-agents.ps1 placeholder default raised to responses 2.0.0 and adds the
  it-unsupported-protocol agent; HostedAgentFixture protocol version is overridable

* Address PR review: whitespace protocol gate and InMemory store agent keying

* HostedProtocolCompatibility treats a whitespace-only x-agent-foundry-call-id as
  absent (IsNullOrWhiteSpace) so a proxy injecting whitespace cannot bypass the gate;
  unit test covers empty, spaces and tab
* InMemoryAgentSessionStore keys sessions by agent.Name (omitting the agent segment
  when Name is unset), mirroring FileSystemAgentSessionStore, so session continuity
  survives a recreated or transient agent rather than keying on the per-instance agent.Id
2026-06-30 19:30:46 +00:00
SergeyMenshykh 09fbccfb20 .NET: Add AgentSkillsSourceContext to AgentSkillsSource.GetSkillsAsync (#6797)
* Add AgentSkillsSourceContext to AgentSkillsSource.GetSkillsAsync

Pass agent/session context through the skills retrieval pipeline so
sources, filters, and caching can make context-aware decisions.

- AgentSkillsSourceContext (Agent, Session) is built by AgentSkillsProvider
  from the InvokingContext and flows through all sources and decorators.
- FilteringAgentSkillsSource predicate now receives an AgentSkillFilterContext
  bundling the skill and the source context.
- CachingAgentSkillsSource supports per-key isolation via
  CachingAgentSkillsSourceOptions.CacheIsolationKeySelector; a null selector
  preserves the shared-cache behavior.

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

* Make AgentSkillsSourceContext constructor public and harden cache key

- Make the AgentSkillsSourceContext constructor public so external callers
  can invoke AgentSkillsSource.GetSkillsAsync directly; drop the
  Mcp.UnitTests InternalsVisibleTo entry it required.
- Use a dedicated sentinel cache key for the shared bucket so an isolation
  selector returning an empty string gets its own bucket.
- Document cache-key cardinality guidance and baseline the experimental
  API breaking changes in CompatibilitySuppressions.xml.

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

* Drop AgentSkillFilterContext in favor of a two-argument filter predicate

Replace the AgentSkillFilterContext bundle with a
Func<AgentSkill, AgentSkillsSourceContext, bool> predicate in
FilteringAgentSkillsSource and AgentSkillsProviderBuilder.UseFilter, and
update the tests accordingly.

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-30 13:01:51 +01:00
Roger Barreto 0d53d11bc6 .NET: [BREAKING] Bump Azure.AI.AgentServer to 2.0.0 protocol and migrate Foundry.Hosting (#6800)
* .NET: Bump Azure.AI.AgentServer to 2.0.0 protocol and migrate Foundry.Hosting

Bumps Core .25->.26, Invocations .4->.5, Responses .5->.6 and adopts the 2.0.0 container protocol.

Breaking change: IsolationContext (UserIsolationKey + ChatIsolationKey) is replaced by PlatformContext (UserIdKey from x-agent-user-id, CallId from x-agent-foundry-call-id). The per-chat key is gone; HostedSessionContext is now user-only and the per-request CallId is forwarded outbound to Foundry first-party services (toolbox/MCP).

Also fixes a real call-id egress bug: AsyncLocal writes inside the streaming response iterator are reverted across yield boundaries, so the call id was dropped before the toolbox/MCP egress ran. The handler now re-applies HostedCallContext.CallId before each egress point.

Adds HostedConversationKey to map a request to a stable MAF AgentSession via conversation_id, else the partition key embedded in previous_response_id, else the minted response id. This keeps store=false previous_response_id chains and conversation_id forks on a single hosted MAF session without using the container session id.

Sample manifests bump the responses protocol to 2.0.0 (invocations stays 1.0.0). Integration tests split store/session semantics into HostedResponsesStoreConfigTests with its own scenario, read stored responses through the per-agent endpoint client, and inject the model deployment into the container.

* Pin Azure.Core 1.59.0 for Hosted-Workflow-Handoff sample

AgentServer 1.0.0-beta.26 (pulled transitively via Foundry.Hosting) requires Azure.Core 1.59.0. This sample disables transitive pinning and references Azure.Core directly, so override just this project to the SDK-required version without moving the solution-wide central pin.

* Add guard test for request-scoped call-id cleanup

Asserts HostedCallContext.CallId does not leak into the caller's execution context after CreateAsync's stream completes, while confirming the agent run still observed the call id. Documents the request-scoped contract and guards against stale-header leakage across requests handled on the same thread.

* Refresh hosting READMEs for AgentServer 2.0 migration

Updates stale docs to match the shipped code: the MemoryAgent README now describes the x-agent-user-id user-identity header (chat isolation key removed) feeding HostedSessionContext.UserId; the IntegrationTests README corrects the scenario count (six to eleven), adds the missing memory scenario row, and stops claiming all scenarios are skipped now that several are validated and active.

* Add ADR 0030 superseding 0026 for AgentServer 2.0 platform context

Documents the migration from ResponseContext.Isolation (UserIsolationKey/ChatIsolationKey) to ResponseContext.PlatformContext (UserIdKey/CallId): user-only HostedSessionContext, the request-scoped HostedCallContext call-id forwarded on egress, HostedConversationKey session keying, and removal of the PerChat/PerUserAndChat memory scopes. Marks ADR 0026 as superseded.

* Add breaking-change v2.0-only disclaimer to package metadata

Augments the package Description and adds PackageReleaseNotes stating this release targets the Foundry Responses container protocol v2.0 only, is not compatible with v1, and directs consumers to a previous release for the v1 protocol definition.

* Address review comments: dead chat-key surface and weak test assertions

Fixes the automated review findings: the MemoryAgent/AgentSkills .env.example now say one variable (only HOSTED_USER_ISOLATION_KEY remains); the MemoryAgent smoke script drops the unused ChatKey parameter and its call-site arguments; HostedConversationKey null test now exercises a real null (and whitespace); and the reuse-one-session test asserts an exact SessionCount of 1 instead of <= 1.
2026-06-29 16:39:54 -07:00
SergeyMenshykh cb8cef3ef6 .NET: Improve proxy target validation in DevUI aggregator (#6771)
* Improve proxy target validation in DevUI aggregator

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

* Fail closed on malformed proxy target URIs

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

* Add direct coverage for proxy target validation

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

* Apply arrange-act-assert structure to aggregator tests

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

* Fix formatting in aggregator tests

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-28 18:32:01 +00:00
Giles Odigwe d5c5fb9d3d .NET: Enforce ApprovalRequiredAIFunction in GitHub Copilot provider via OnPreToolUse hook (#6674)
* .NET: Enforce ApprovalRequiredAIFunction in GitHub Copilot provider

The GitHub Copilot SDK owns the tool-calling loop and invokes registered
custom functions directly, so the standard FunctionInvokingChatClient
approval round-trip never runs for this provider. As a result a tool wrapped
in ApprovalRequiredAIFunction (only a marker) could execute without any
Agent Framework approval.

Add an agent-level onFunctionApproval callback and wrap approval-required
tools in an ApprovalGatedAIFunction that enforces approval before invoking
the underlying function. Secure-by-default: with no callback, or when the
callback denies or throws, execution is denied. The gate forwards tool
metadata (including the Copilot skip_permission flag) so it stays
transparent to the SDK. This mirrors the Python provider's behavior.

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

* .NET: Propagate cancellation from GitHub Copilot approval callback

Let OperationCanceledException propagate from the approval callback instead
of swallowing it into a denial, so cooperative cancellation is honored.
Other callback failures still deny by default. Added a unit test.

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

* .NET: Enforce ApprovalRequiredAIFunction via Copilot SDK OnPreToolUse hook

Replace the custom approval enforcement (ApprovalGatedAIFunction wrapper +
onFunctionApproval callback) with the GitHub Copilot SDK's native OnPreToolUse
hook, which the SDK already provides for pre-execution gating.

When a tool wrapped in ApprovalRequiredAIFunction is registered and the caller
hasn't supplied their own OnPreToolUse hook, the agent installs a default hook
that returns "ask" for those tools (routing the decision to OnPermissionRequest)
and defers (null) for all other tools, preserving today's behavior for
non-approval tools. If the caller supplies their own OnPreToolUse hook, it takes
precedence and they own approval handling; the agent logs a warning naming any
approval-required tool that will not be auto-gated, and the behavior is
documented. Adds an optional ILoggerFactory parameter for the warning.

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

* .NET: Address PR review feedback on GitHub Copilot approval hook

- Build the approval-required tool-name HashSet directly instead of via an
  intermediate List.
- Remove the redundant MEAI001 NoWarn suppression (tests already suppress it via
  .editorconfig and the source project builds clean without it).

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-27 01:22:47 +00:00
SergeyMenshykh 846c963e85 .NET: Add description attribute to resource and script elements in skill body (#6759)
Include the optional description attribute on <resource> and <script>
elements within <available_resources> and <available_scripts> blocks,
aligning .NET with the Python implementation. The description is emitted
only when non-null/non-empty and is XML-escaped.

Co-authored-by: Marco Minerva <marco.minerva@gmail.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 22:46:56 +00:00
SergeyMenshykh e0274b764e .NET: Extract caching from AgentSkillsProvider into CachingAgentSkillsSource (#6768)
Move the cache-once-then-replay logic out of AgentSkillsProvider into a
new CachingAgentSkillsSource decorator following the DelegatingAgentSkillsSource
pattern used by DeduplicatingAgentSkillsSource and FilteringAgentSkillsSource.

- Add internal CachingAgentSkillsSource (lock-free, thread-safe; clears on failure)
- AgentSkillsProviderBuilder applies caching after aggregation, before filter/dedup
- Add builder DisableCaching() opt-out method
- Convenience constructors wrap with CachingAgentSkillsSource before dedup
- Remove DisableCaching from AgentSkillsProviderOptions
- Add CachingAgentSkillsSourceTests

Co-authored-by: SergeyMenshykh <SergeMenshikh@outlook.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 22:29:35 +00:00
SergeyMenshykh d09451408f Disable failing DurableTask and AzureFunctions integration tests (#6774)
Skip the following tests that are persistently failing in CI:

DurableTask - AgentEntityTests:
- EntityNamePrefixAsync
- RunAgentMethodNamesAllWorkAsync
- OrchestrationIdSetDuringOrchestrationAsync

DurableTask - ExternalClientTests:
- SimplePromptAsync
- CallFunctionToolsAsync
- CallLongRunningFunctionToolsAsync

DurableTask - WorkflowConsoleAppSamplesValidation:
- ConcurrentWorkflowSampleValidationAsync
- WorkflowAndAgentsSampleValidationAsync

DurableTask - ConsoleAppSamplesValidation:
- SingleAgentSampleValidationAsync
- SingleAgentOrchestrationChainingSampleValidationAsync
- MultiAgentConcurrencySampleValidationAsync
- MultiAgentConditionalSampleValidationAsync

AzureFunctions - SamplesValidation:
- SingleAgentSampleValidationAsync
- MultiAgentOrchestrationConcurrentSampleValidationAsync
- MultiAgentOrchestrationConditionalsSampleValidationAsync
- LongRunningToolsSampleValidationAsync
- AgentAsMcpToolAsync

AzureFunctions - WorkflowSamplesValidation:
- WorkflowAndAgentsSampleValidationAsync
- ConcurrentWorkflowSampleValidationAsync

Related to: microsoft/agent-framework#6732

Co-authored-by: SergeyMenshykh <SergeMenshikh@outlook.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 21:31:08 +00:00
Tommaso Stocchi daac8c15f3 .NET: Prefer HTTPS backends in Aspire DevUI (#6772)
Prefer allocated HTTPS endpoints when resolving Aspire DevUI backends and fall back to HTTP for existing services. Update the DevUI Aspire sample so WriterAgent exercises HTTPS redirection.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-26 18:15:51 +00:00
Roger Barreto 231b35da55 .NET: Foundry hosted-agent toolbox OAuth consent support (#6718)
* .NET: Foundry hosted-agent toolbox OAuth consent support

Add per-user OAuth (MCP CONSENT_REQUIRED) support for Foundry hosted agents.

* Defer hard toolbox startup failures so a per-user OAuth-gated toolbox no
  longer bricks the container at startup (new Degraded status, retried per
  request). The container stays routable and surfaces consent on the first
  user request.
* Emit the platform-canonical oauth_consent_request output item (instead of
  mcp_approval_request) for toolbox OAuth consent, matching the Python
  implementation and how the Foundry platform heads render consent.
* Parse the toolbox CONSENT_REQUIRED (-32006) error and surface the consent
  link; resume by re-sending the prompt with no reply item needed.
* Add the Hosted-Toolbox-AuthPaths OAuth consent REPL client sample that
  detects oauth_consent_request, prints the consent link, and re-sends.
* Add tests for the consent parser, startup deferral, and oauth_consent_request
  emission.

Fixes #6562

* .NET: Address review feedback on toolbox OAuth consent

* Make RecomputeStatus the single source that refreshes ConsentRequiredToolboxNames
  from the pending-consent set, so a per-request marker that records consent via
  GetToolboxToolsAsync no longer leaves ConsentRequiredToolboxNames stale (which
  made ResolvePendingConsentsAsync skip surfacing it).
* Surface lazy / per-request marker consent in the same request: after resolving
  markers the handler now emits oauth_consent_request + incomplete when a marker
  hit CONSENT_REQUIRED, instead of silently running without that toolbox.
* Add FoundryToolboxService.GetPendingConsents() snapshot accessor.
* Fix stale ToolboxConsentParser doc comment (mcp_approval_request -> oauth_consent_request).

* .NET: Harden toolbox consent paths from code review

* Thread-safety: GetPendingConsents() now returns an immutable snapshot rebuilt
  in RecomputeStatus under the lock, instead of enumerating the live
  _pendingConsents dictionary off-lock (which could throw under concurrent requests).
* Resource leak: OpenToolboxAsync builds the endpoint Uri before allocating the
  HttpClient and now disposes the HttpClient when McpClient.CreateAsync throws
  (the unreachable/deferred case retried per request), not only when ListToolsAsync fails.
* StrictMode now gates on the pre-registered ToolboxNames set rather than the
  opened-toolbox cache, so a registered-but-deferred toolbox is no longer rejected
  as unknown.
* Sample REPL: the legacy approval-args consent fallback only reads the explicit
  consent_url key, so a normal function-tool approval carrying a URL argument is
  not misread as an OAuth consent request.

* .NET: Scope per-request toolbox marker consent to the request

Addresses review feedback that a marker-originated toolbox could leak into global
scope after consent. GetToolboxToolsAsync now returns a request-scoped
ToolboxResolution (tools or consent requirements) instead of recording marker
consent in the container-global _pendingConsents and appending resolved tools to
the service-wide Tools list.

* Marker consent is surfaced as oauth_consent_request for the requesting turn only
  and collected in the handler's marker loop; it no longer injects tools into, or
  raises a consent prompt on, a later request that did not reference the marker.
* Marker resolution no longer flips the container StartupStatus to ConsentRequired
  (per-request markers must not affect readiness, per the StartupStatus contract).
* Remove the now-unused GetPendingConsents()/snapshot path; _pendingConsents is once
  again exclusively the pre-registered/startup consent set.

* .NET: Add consent request-scoping UTs and an OAuth consent integration test

Unit tests (Microsoft.Agents.AI.Foundry.Hosting.UnitTests):
* New FoundryToolboxMarkerScopingTests proves per-request marker resolution is
  request-scoped: a marker consent is returned to the caller without mutating
  ConsentRequiredToolboxNames, StartupStatus, or the service-wide Tools cache, and
  marker-resolved tools are returned to the caller rather than injected globally
  (so a request with no marker sees neither the tools nor the consent).
* Adds a test-only ToolboxOpener seam on FoundryToolboxService so the consent/tools
  resolution can be exercised without a live MCP proxy. Makes ToolboxOpenResult and
  CachedToolbox internal (CachedToolbox.Client nullable, guarded at dispose).

Integration test (Foundry.Hosting.IntegrationTests):
* New toolbox-oauth-consent scenario wired into the TestContainer (pre-registers a
  Foundry toolbox via AddFoundryToolboxes from IT_TOOLBOX_NAME), a
  ToolboxOAuthConsentHostedAgentFixture, and a ToolboxOAuthConsentHostedAgentTests
  that invokes the deployed agent and asserts the consumer captures an
  oauth_consent_request consent link (container stays routable, no 424). Skipped by
  default per the IT convention; documents the consent-gated toolbox prerequisite.
* Adds the scenario to it-bootstrap-agents.ps1 and the README scenario table.
2026-06-26 13:07:23 +00:00
westey 772c6fd921 .NET: Add BackgroundTaskCompletionLoopEvaluator for harness background agents (#6736)
* Add background agent loop evaluator

* Address PR comments
2026-06-26 14:24:20 +01:00
SergeyMenshykh e3b64fdc47 .NET: [BREAKING] Make all AgentSkillsProvider tools require approval by default (#6729)
* Make all AgentSkillsProvider tools require approval by default

- Wrap all tools (load_skill, read_skill_resource, run_skill_script) with
  ApprovalRequiredAIFunction unconditionally
- Add ReadOnlyToolsAutoApprovalRule and AllToolsAutoApprovalRule static
  properties following the FileAccessProvider pattern
- Remove ScriptApproval from AgentSkillsProviderOptions and
  UseScriptApproval from AgentSkillsProviderBuilder
- Add Agent_Step07_SkillsAutoApproval sample

Closes #6727

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

* Add UseToolApproval to hosted AgentSkills scenarios

Wire AllToolsAutoApprovalRule into the integration test container and
the Hosted-AgentSkills sample so skill tools execute without blocking
on approval when no interactive approval handler is configured.

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

* Add API compatibility suppressions for removed ScriptApproval members

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-25 20:44:12 +00:00
Peter Ibekwe 3a5bbb5f8e .NET: Add DeclarativeWorkflowJsonOptions for AOT-safe declarative workflow checkpointing (#6745)
* Add experimental DeclarativeWorkflowJsonOptions for AOT-safe declarative workflow checkpointing

* Address PR comments
2026-06-25 19:57:22 +00:00
Peter Ibekwe a7332d69a8 .NET: Fix issue with resuming checkpoint after package version upgrade (#6670)
* Fix issue with resuming checkpoint after package version upgrade

* Address PR comments

* Fix changelog encoding
2026-06-25 18:32:22 +00:00
SergeyMenshykh d0be98d649 Remove {resource_instructions} and {script_instructions} placeholder mechanism (#6706)
Embed resource and script instruction text directly in the default
prompt template instead of using placeholder substitution. Custom
templates now only need the {skills} placeholder.

Co-authored-by: SergeyMenshykh <SergeMenshikh@outlook.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-25 15:19:35 +00:00
SergeyMenshykh 802fe13053 Disable failing durable function integration tests (#6731)
Skip LongRunningToolsSampleValidationAsync and ReliableStreamingSampleValidationAsync
tests that are persistently failing in CI.

Co-authored-by: SergeyMenshykh <SergeMenshikh@outlook.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-25 14:42:34 +00:00
Roger Barreto 0283fd00a1 .NET: Fix hosted agent crash after tool call by rooting session store under $HOME (#6231) (#6714)
* .NET: Fix hosted agent crash after tool call by rooting session store under $HOME

FileSystemAgentSessionStore.CreateDefault rooted the hosted session store at the
filesystem root "/.checkpoints", which is read-only inside a Foundry hosted
container. After a local tool call the response handler persists the session, so
the write to "/.checkpoints" threw IOException and tore down the container, which
the platform surfaced as "mount: /app: mount failed: No such file or directory.".

Root the hosted store at $HOME (default /home/session), the only writable and
durable location per the container image spec. Persistence failures stay fatal but
are now wrapped in a clear, actionable IOException instead of the opaque raw error.

Add unit tests covering hosted and local path resolution plus the clear error, and
enable the ToolCalling Foundry Hosted Agents integration tests (verified live).

Fixes #6231

* .NET: Harden hosted session store against a filesystem-root HOME

Address review feedback on #6714: a misconfigured HOME pointing at a filesystem
root (e.g. "/") resolved back to "/.checkpoints" and would reintroduce the original
read-only-root crash. CreateDefault now falls back to the default session-data
directory (/home/session) when HOME is missing, blank, a filesystem root, or an
unnormalizable path. Adds a unit test locking in the "never the filesystem root"
behavior for a hosted HOME of "/".

Related #6231
2026-06-24 18:55:08 +00:00
Roger Barreto a9e5f6d798 .NET: .NET Foundry: add CreateMcpTool projectConnectionId overload (#6703)
* .NET Foundry: add CreateMcpTool projectConnectionId overload

Adds FoundryAITool.CreateMcpTool(serverLabel, serverUri, projectConnectionId, ...)
so hosted MCP tools can authenticate through a Foundry project connection, matching
the Python FoundryChatClient.get_mcp_tool(..., project_connection_id=...) factory.

The connection id is applied via the McpTool.ProjectConnectionId extension that ships
in Azure.AI.Projects.Agents (patches project_connection_id), already referenced by the
Foundry package. Includes unit tests and sample/README guidance plus the existing
FromResponseTool workaround.

* Fold projectConnectionId into existing CreateMcpTool overload

Replaces the separate project-connection overload with an optional
projectConnectionId parameter on the existing serverUri CreateMcpTool, so all
settings (authorizationToken, headers, allowedTools, ...) stay available and there
is no positional overload ambiguity. Adds tests for the default (no connection)
path and for preserving other settings. Sample/README now show only the supported
overload.
2026-06-24 12:40:47 +00:00
SergeyMenshykh ea7ae1cc00 .NET: [BREAKING] Support archive-type skills in AgentMcpSkillsSource (#6631)
* NET: Support archive-type skills in AgentMcpSkillsSource

Add archive-type skill discovery to the MCP skills source. Index entries
are dispatched to per-type loaders (skill-md and archive) via a new
IMcpSkillEntryLoader strategy. The archive loader downloads, safely
unpacks, and serves packaged skills through an internal file skills
source, while ensuring MCP-delivered scripts are never executed.

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

* Fix CS0121 ambiguity in UseSource null test

Cast null! to AgentSkillsSource to disambiguate from the new
Func<ILoggerFactory?, AgentSkillsSource> overload.

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

* Address PR review: fix misleading comment and catch UnauthorizedAccessException in Dispose

- Remove hardcoded '50' from test comment; it now says 'default cap'
  without citing a specific number that can drift from the constant.
- Catch UnauthorizedAccessException alongside IOException in test
  Dispose for robust cleanup.

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

* Decouple shared refresh from per-caller cancellation

Use CancellationToken.None for the shared refresh so one caller's
cancellation does not abort work for all concurrent waiters. Waiters
use WaitAsync(cancellationToken) to cancel independently. The refresh
owner checks its own token after publishing the result.

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

* Fix file encoding: add UTF-8 BOM to archive tests

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

* Fix file encoding: add UTF-8 BOM to ArchiveFormat.cs

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

* Clarify pruning doc: covers non-actionable entries too

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

* Add branch-coverage tests and drop [Experimental] attribute

- Add 5 unit tests covering FilterValidEntries/download condition branches
  (missing name, invalid name chars, missing url, unsupported format, text-only blob)
- Remove [Experimental] attribute from AgentMcpSkillsSourceOptions (alpha package suffices)

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-24 13:12:08 +01:00
SergeyMenshykh e049bb5691 .NET: Add IncludeDetailedErrors option for skill script execution (#6680)
* fix: propagate skill script/resource exceptions instead of swallowing them

Stop catching and returning generic error strings in RunSkillScriptAsync and
ReadSkillResourceAsync. Exceptions are now logged and rethrown so that
FunctionInvokingChatClient can decide whether to surface details to the model
via its existing IncludeDetailedErrors option (default: safe generic message).

Fixes microsoft/agent-framework#6304

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

* Add IncludeDetailedErrors option for skill script execution

Add an IncludeDetailedErrors option to AgentSkillsProviderOptions. When enabled,
RunSkillScriptAsync appends the exception message to the error returned to the
model so it can self-correct (e.g. retry with different arguments). When
disabled (default), the exception is logged and rethrown, letting
FunctionInvokingChatClient apply its own IncludeDetailedErrors policy.

ReadSkillResourceAsync now logs and rethrows as well, since resources take no
arguments and a generic swallowed error is not actionable by the model.

Fixes microsoft/agent-framework#6304

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

* Add prompt-injection caution to IncludeDetailedErrors doc

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-24 11:59:55 +01:00
SergeyMenshykh dd4b7ff475 .NET: Fix SearchDirectoriesForSkills to stop recursing after finding SKILL.md (#6686)
* Fix SearchDirectoriesForSkills to stop recursing after finding SKILL.md

When a directory contains SKILL.md, subdirectories are part of that skill
and should not be treated as independent skill roots. Add a return after
adding the directory to results to prevent incorrect recursion.

Also adds a regression test verifying nested SKILL.md files are not
discovered as separate skills.

Fixes microsoft/agent-framework#6683

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

* Fix test: use matching directory name so nested SKILL.md would pass validation

The child skill's frontmatter name must match its directory name,
otherwise it gets rejected by validation regardless of the recursion fix.
This ensures the test actually validates the stop-recursing behavior.

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-24 08:35:11 +00:00
Taisir Hassan d5c15f2fe1 .NET/Python: Purview: prefer token principal for user identity (#6693)
* Purview: prefer token principal for user identity

Align Purview middleware identity resolution so user-token principals are preferred before supplied message identities, while app-token flows continue to use validated fallback user IDs. Also fix the content activities user route and add regression coverage for identity precedence and route construction.

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

* .NET: Fix user ID resolution logic in ScopedContentProcessor and add unit test for empty token user ID

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-24 00:16:44 +00:00
SergeyMenshykh e4b89373f1 .NET: Explicitly emit available_resources and available_scripts in skill content (#6672)
* .NET: Explicitly emit available_resources and available_scripts in skill content

AgentInlineSkillContentBuilder now always emits <available_resources> and
<available_scripts> elements, using self-closing tags when a skill has no
resources or scripts. This signals to the model exactly what is callable so it
does not hallucinate non-existent resource or script names. Script parameter
schemas are wrapped in a nested <parameters_schema> element.

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

* .NET: Emit available_resources block for file-backed skills

Align AgentFileSkill with inline/class skills by surfacing discovered
resources in the loaded skill content. AgentFileSkill.GetContentAsync now
appends an <available_resources> block (before <available_scripts>) listing
resource names so the model has an authoritative list and does not
hallucinate resource names. Extracted a reusable BuildAvailableResourcesBlock
helper in AgentInlineSkillContentBuilder.

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-23 09:51:10 +00:00
SergeyMenshykh 88f0b23fb0 .NET: Change A2A default session store to NoopAgentSessionStore (#6635)
* Change A2A default session store to NoopAgentSessionStore

Align the A2A hosting layer default session store with the AG-UI
sibling by using NoopAgentSessionStore, making persistence an explicit
opt-in choice.

Update samples to document how to register a persistent session store
for multi-turn conversations.

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

* Clarify test name to specify session store default

Rename test to FallsBackToNoopSessionStoreDefaultAsync to avoid
implying all stores default to noop (task store still uses InMemory).

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-23 08:55:59 +00:00
Roger Barreto 09791533cf .NET: Emit execute_tool spans by placing OpenTelemetry below FunctionInvokingChatClient (#6667)
OpenTelemetryAgent auto-wired OpenTelemetryChatClient above FICC, producing
OTel(FICC(leaf)). FICC resolved its ActivitySource at construction time as null,
so execute_tool spans were never emitted for tool-calling agents.

This repositions OTel below FICC, producing FICC(OTel(leaf)), via a deferred
NoOp slot pre-placed as the innermost decorator in WithDefaultAgentMiddleware
and activated once at the agent level.

- Add internal DeferredOpenTelemetryChatClient: inert DelegatingChatClient whose
  Activate(sourceName) swaps its target to inner.AsBuilder().UseOpenTelemetry().Build().
- WithDefaultAgentMiddleware always registers the slot innermost so it lands below FICC.
- OpenTelemetryAgent activates the slot once in its constructor and forwards run
  options straight through, removing the per-run ChatClientFactory outer wrap.
- Add and update unit tests, including a proof that execute_tool spans are emitted
  on the agent source and parented under invoke_agent.
2026-06-22 15:09:29 -07:00
Giles Odigwe dc60722cee .NET: Project ToolExecution events as FunctionCallContent/FunctionResultContent in GitHubCopilotAgent streaming (#6228)
* Project ToolExecution events as FunctionCallContent/FunctionResultContent

GitHubCopilotAgent's event-dispatch switch previously had no case for
ToolExecutionStartEvent or ToolExecutionCompleteEvent. Both fell through
to the default case and were wrapped as opaque AIContent with
RawRepresentation, preventing downstream consumers and models from
recognizing tool call results.

Add explicit cases that project:
- ToolExecutionStartEvent → FunctionCallContent (role: Assistant)
- ToolExecutionCompleteEvent → FunctionResultContent (role: Tool)

This mirrors the Python fix already shipped in #4734/#4814/#4828.

Fixes #5897

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

* fix(#5897): Address review feedback for ParseArguments robustness

- Handle non-generic IDictionary variants (Hashtable, etc.) that don't
  match IDictionary<string, object?> due to generic invariance
- Return null for empty/whitespace string arguments instead of wrapping
  them in a spurious { value = "" } dictionary, aligning with
  ParseFunctionArgumentsObject convention elsewhere in the repo
- Add test coverage for Dictionary, Hashtable, and JsonElement argument
  types
- Add edge-case test for Success=true with null Result

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

* Fix non-generic IDictionary key handling in ParseArguments (#5897)

Use direct (string) cast for dictionary keys instead of ToString()
coercion, matching the established pattern in ObjectExtensions and
PortableValueExtensions. This validates keys are actually strings
rather than silently accepting and coercing non-string keys.

Add test verifying non-string dictionary keys throw InvalidCastException.

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

* Fix missing 'using System' in ToolExecutionEventProjectionTests

Add the missing 'using System' directive needed for InvalidCastException
reference at line 375 of ToolExecutionEventProjectionTests.cs.

Fixes #5897

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

* Use source-generated JsonTypeInfo for AOT-safe argument deserialization

Replace reflection-based JsonSerializer.Deserialize<T>() calls with the
JsonTypeInfo overload that uses source-generated metadata, eliminating
IL2026/IL3050 trimming and AOT warnings without suppressions.

Changes:
- Register Dictionary<string, object?> in GitHubCopilotJsonUtilities JsonContext
- Add JsonSerializerOptions constructor parameter (defaults to
  GitHubCopilotJsonUtilities.DefaultOptions)
- Use GetTypeInfo()-based Deserialize overload in ParseArguments
- Remove [UnconditionalSuppressMessage] attributes

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

* Fix dotnet format: add 'this.' qualification to instance method call

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

* Adapt to GitHub.Copilot.SDK 1.0.0 API after merge with main

- Update ToolExecutionEventProjectionTests: Arguments is now JsonElement?
  (not object?), remove tests for string/Dictionary/Hashtable arguments
- Remove AutoStart option (removed in 1.0.0)
- Simplify ParseArguments to handle JsonElement primarily
- Add tests for empty object and nested JSON arguments

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-22 16:45:03 +00:00
Peter Ibekwe 2f5a76ab1d Fix issue with resuming checkpoint after package version upgrade (#6636) 2026-06-22 15:18:22 +00:00
Copilot ad3c1535c4 fix: propagate EnableSensitiveData to auto-wired inner OpenTelemetryChatClient (#6096)
When _autoWireChatClient=true and the caller sets EnableSensitiveData=true on
the outer OpenTelemetryAgent, the auto-wired inner OpenTelemetryChatClient now
also has EnableSensitiveData propagated, so the inner chat span correctly
captures message content (gen_ai.input.messages / gen_ai.output.messages).

Red test added first to reproduce the bug, then the fix applied (green).

Fixes #5873

Agent-Logs-Url: https://github.com/microsoft/agent-framework/sessions/fda69dd4-9576-4f3f-b954-514321652ea9

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: rogerbarreto <19890735+rogerbarreto@users.noreply.github.com>
2026-06-22 10:27:13 +00:00
安妮的心动录 10b7d08bff .NET: fix(hosting): emit url_citation annotation events from streamed AI Search responses (#6649)
* fix(hosting): emit url_citation annotation events from streamed AI Search responses

OutputConverter.ConvertUpdatesToEventsAsync accumulated text content deltas but
silently dropped CitationAnnotation metadata from TextContent.Annotations. As a
result, hosted agents that use CreateAzureAISearchTool emitted citation markers in
text (e.g. 【5:0†source】) but produced empty annotations arrays and no
response.output_text.annotation.added SSE events.

The fix accumulates UrlCitationBody SDK annotations across all TextContent updates
for a message and emits them via TextContentBuilder.EmitAnnotationAdded after
EmitTextDone (as required by the SDK lifecycle) and before EmitDone. Non-citation
and region-less annotations are silently skipped, matching the existing OpenAI
ChatCompletions path in AgentResponseExtensions.

Adds 7 unit tests (N-01–N-07) covering: basic emission, ordering constraints,
multiple annotations, multi-update accumulation, and skip conditions.

Fixes #6641

* test: convert annotation test comments to XmlDoc and group in region

* fix: remove redundant long casts on annotation region indices

* test: assert done events carry url_citation annotation metadata

---------

Co-authored-by: Roger Barreto <19890735+RogerBarreto@users.noreply.github.com>
2026-06-22 10:10:02 +00:00
Peter Ibekwe c815902344 .NET: InProcessRunnerContext bugfix for workflows (#6551)
* workfllow bugfix

* Update exception message

* Fix unit test.
2026-06-19 14:09:36 +00:00
Peter Ibekwe 074ac68a6c .NET: Harden fan-in barrier checkpoint state and extend resume coverage (#6574)
* Harden fan-in barrier checkpoint state and extend resume coverage

* Address PR comment
2026-06-19 13:33:26 +00:00