Skip to content

.NET: Isolate Foundry toolbox response cache - #8848

Draft
Roger Barreto (rogerbarreto) wants to merge 3 commits into
mainfrom
i816r542-toolbox-cache-isolation
Draft

Roger Barreto (rogerbarreto) wants to merge 3 commits into
mainfrom
i816r542-toolbox-cache-isolation

Conversation

@rogerbarreto

Copy link
Copy Markdown
Member

Motivation & Context

Foundry toolbox clients opened while serving a response were retained by the singleton toolbox service under the toolbox name. That lifetime allowed later responses to reuse client and tool state created under a different request context.

This change aligns request-opened toolbox ownership with the response lifetime while preserving safe reuse for clients opened during container startup.

Description & Review Guide

  • What are the major changes? Add an opaque response cache scope, keep lazy, deferred, and consent retry results inside that scope, and dispose scoped MCP and HTTP clients when the response completes or exits early. Add service-level and handler-level regression coverage for concurrent responses, reuse, isolation, streaming context continuity, and cleanup.
  • What is the impact of these changes? Startup-opened toolboxes remain shared. Toolboxes opened during request handling are reused only within that response and are independently opened for other responses.
  • What do you want reviewers to focus on? Please review the response-scope lifecycle in AgentFrameworkResponseHandler, the separation between startup and request caches in FoundryToolboxService, and cleanup across normal and exceptional exits.

Related Issue

N/A. This change is tracked in a restricted incident record, so no GitHub issue is created.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR is linked to an issue and there is no other open PR for this issue (see Related Issue above).
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and the title prefix in sync automatically.

Request-opened toolbox clients must not outlive the response context that created them. Keep startup cache reuse while disposing scoped clients on every response exit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟢 Approval recommended

The scoped lifecycle is consistently implemented and covered across concurrent, successful, and exceptional response paths.

Review effort: Balanced
Findings: None

What changed in this PR

Introduces response-scoped Foundry toolbox caching to prevent cross-request client reuse while preserving startup cache sharing.

Changes:

  • Adds opaque response scopes with deterministic client cleanup.
  • Separates startup and request-specific tools and consent state.
  • Adds concurrency, isolation, reuse, failure, and disposal coverage.
File Description
FoundryToolboxService.cs Implements scoped caches and disposal.
AgentFrameworkResponseHandler.cs Manages toolbox scope across response streaming.
HostedCallContext.cs Carries the response scope through async execution.
FoundryToolboxServiceTests.cs Covers scoped reuse, isolation, and cleanup.
FoundryToolboxResponseScopeTests.cs Adds end-to-end response lifecycle tests.
FoundryToolboxMarkerScopingTests.cs Updates marker tests with request identities.

💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MAF Automated Review — Iteration 1

Result: Findings reported
Scope: full PR (1 commit(s)): a877c87e32ae
Model: gpt-5.6-sol-fast

Overview

The PR correctly separates startup-owned toolbox state from response-owned clients, uses opaque scope IDs, reapplies ambient scope across streaming yields, and disposes scoped resources on normal and exceptional response exits. The new per-response ownership model nevertheless permits unbounded process-wide client retention while responses remain active, serializes independent network opens behind a singleton semaphore, and can abandon resources after a disposal exception.

Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
3 verified findings remained after source verification (1 high, 2 medium) across 1 file. Details are attached to the affected lines below.

Affected areas: dotnet/src/Microsoft.Agents.AI.Foundry.Hosting/FoundryToolboxService.cs

@github-code-quality

github-code-quality Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: C#

C# / code-coverage/dotnet

The overall line coverage in commit 9df5264 in the i816r542-toolbox-cac... branch is 85%. Line coverage data for the main branch is not yet available.

Show a line coverage summary of the most covered files.
File main i816r542-toolbox-cac... 9df5264 +/-
/home/runner/wo...valConverter.cs — 100% —
/home/runner/wo...entsProvider.cs — 99% —
/home/runner/wo...egatingAgent.cs — 99% —
/home/runner/wo...nticAnalyzer.cs — 94% —
/home/runner/wo...putConverter.cs — 90% —
/home/runner/wo...kflowBuilder.cs — 90% —
/home/runner/wo...SkillsSource.cs — 89% —
/home/runner/wo...onExtensions.cs — 81% —
/home/runner/wo...CopilotAgent.cs — 76% —
/home/runner/wo...ctionVisitor.cs — 75% —

Updated September 29, 2026 15:23 UTC

Allow independent response scopes to open concurrently. Cleanup attempts every scoped resource, preserves response outcomes, and aggregates failures only during service shutdown.
return new FoundryToolboxService.ToolboxOpenResult(
new FoundryToolboxService.CachedToolbox(
Client: null,
new HttpClient(handler),
return new FoundryToolboxService.ToolboxOpenResult(
new FoundryToolboxService.CachedToolbox(
Client: null,
new HttpClient(handler),
new FoundryToolboxService.ToolboxOpenResult(
new FoundryToolboxService.CachedToolbox(
Client: null,
new HttpClient(handler),

This branch was successfully deployed

2 active deployments
github-app-auth — 9df52640 Deployed Sep 29, 2026 by rogerbarreto via add_label #24004
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

.NET Usage: [Issues, PRs], Target: .Net

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants