Skip to content

Python: reuse Foundry session-store client within each response - #8785

Closed
Harsheet Shah (harsheet-shah) wants to merge 1 commit into
microsoft:mainfrom
harsheet-shah:perf/request-scoped-foundry-session-store
Closed

Harsheet Shah (harsheet-shah) wants to merge 1 commit into
microsoft:mainfrom
harsheet-shah:perf/request-scoped-foundry-session-store

Conversation

@harsheet-shah

Copy link
Copy Markdown
Contributor

Motivation & Context

The default Foundry agent-session store resolves a new backing store for each load and save. A warm Responses request consequently performs a second store-metadata lookup and rebuilds the client before persisting the updated session.

Reuse the backing client only within that request, retaining awaited session persistence and deterministic cleanup without introducing a cross-request cache.

Description & Review Guide

  • What are the major changes? Add a private, lazy request scope to FoundryAgentSessionStore and enter it through the Responses host's existing request-owned exit stack. Load/save share one initialized backing client. Initialization is single-flight, unsuccessful initialization is not cached, and the client is closed when the request unwinds. Both normal execution and the existing consent-response session-preservation path use the scope.
  • What is the impact of these changes? A warm request resolves the store once rather than twice. No session contents are cached, no client is shared across requests, and item operations continue forwarding their request's call ID. Standalone store operations and other SessionStore implementations retain their existing lifecycle. The scope is lazy, so a new session does not acquire storage earlier than before.
  • What do you want reviewers to focus on? Request-owned cleanup before the terminal event, failures/cancellation, preservation of custom-store behavior, and the narrower lifecycle than Python: perf(foundry-hosting): cache FoundryStateStore in FoundryAgentSessionStore #8281. Regression coverage includes streaming/non-streaming request reuse, fresh clients across requests, concurrent initialization, failure cleanup, and unchanged standalone operations. No production latency improvement is claimed by this PR.

Related Issue

Partially addresses #8280.

This is an intentionally narrower alternative to #8281, which caches backing clients across requests for the event-loop lifetime. This PR retains per-request ownership and removes only the redundant initialization within each request. It does not modify or supersede #8281 automatically; the approaches should not be merged together unchanged.

Contribution Checklist

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 6e2efa47-2c75-4226-9544-174e3163a924
Copilot AI balanced review requested due to automatic review settings September 28, 2026 03:16
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python labels Sep 28, 2026

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

🟡 Changes recommended

Store cleanup failures can escape before the buffered terminal response event is emitted.

Review effort: Balanced
Findings: 1 High severity

Open (1)
What changed in this PR

Adds request-scoped reuse of the Foundry session-store client while preserving per-request ownership.

Changes:

  • Adds lazy, concurrency-safe client reuse and cleanup.
  • Integrates the scope into normal and consent response paths.
  • Adds lifecycle tests and documentation.
File Description
_state_store.py Implements request-scoped client reuse.
_responses.py Connects store lifecycle to response handling.
test_state_store.py Tests reuse, concurrency, failure, and cleanup.
test_responses.py Tests per-response client isolation.
README.md Documents the new lifecycle.

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

Comment on lines +756 to +759
if isinstance(session_storage, FoundryAgentSessionStore):
await resources.enter_async_context(
session_storage._request_scope() # pyright: ignore[reportPrivateUsage]
)
@eavanvalkenburg

Copy link
Copy Markdown
Member

Harsheet Shah (@harsheet-shah) This branch currently conflicts with main. Please merge or rebase current main and resolve the conflicts before requesting another review.

@eavanvalkenburg

Copy link
Copy Markdown
Member

Harsheet Shah (@harsheet-shah) GitHub could not merge current main into this branch automatically because the branch has conflicts. Please merge or rebase main, preserve the request-scoped ownership approach, address the open terminal-event cleanup finding, and re-request review.

@eavanvalkenburg

Copy link
Copy Markdown
Member

Harsheet Shah (@harsheet-shah) Thanks for the work here. The branch still conflicts with main, and the terminal-event cleanup concern remains outstanding with no update since September 28. I’m closing this for now; please reopen once those items are resolved and the PR is ready for review.

This branch was previously deployed

1 inactive deployment
github-app-auth — 8fe30868 Deployed Sep 28, 2026 by harsheet-shah via team_check #5323
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants