Skip to content

Python: Select Foundry hosting conversation history source - #7997

Draft
Eduard van Valkenburg (eavanvalkenburg) wants to merge 4 commits into
microsoft:mainfrom
eavanvalkenburg:foundry-history-source
Draft

Python: Select Foundry hosting conversation history source#7997
Eduard van Valkenburg (eavanvalkenburg) wants to merge 4 commits into
microsoft:mainfrom
eavanvalkenburg:foundry-history-source

Conversation

@eavanvalkenburg

@eavanvalkenburg Eduard van Valkenburg (eavanvalkenburg) commented Sep 1, 2026

Copy link
Copy Markdown
Member

Motivation & Context

Foundry-hosted Responses agents can restore a downstream service conversation ID while also replaying the complete AgentServer response transcript. The model then receives duplicated history, and the duplication compounds on each turn. Always requiring AgentServer history avoids competing sources, but prevents applications from choosing service, session-backed, or external history storage needed for compliance, residency, retention, deletion, encryption, and audit requirements.

This change makes the model-history source explicit while retaining AgentServer response persistence and session storage as independent concerns.

Description & Review Guide

  • What are the major changes? Adds history_source="agent_server" | "agent" to ResponsesHostServer. The default AgentServer mode replays response-provider history, disables downstream storage only for clients that advertise STORES_BY_DEFAULT=True, removes unsupported storage options for other clients, clears stale service IDs, rejects conflicting history/default conversation configuration, and refuses to persist a session if a client still stores downstream. Agent mode passes only current request input and preserves normal Agent history-provider and service-storage behavior. The PR also adds unit and real Foundry integration coverage, package documentation, and ADR 0039 with the considered alternatives.
  • What is the impact of these changes? Existing applications retain AgentServer response history as the default and stop feeding duplicated history to the model. Applications that need service-side storage, InMemoryHistoryProvider persisted through FoundryAgentSessionStore, or an external history provider can explicitly select history_source="agent".
  • What do you want reviewers to focus on? The separation between AgentServer response persistence and model-history ownership, the compatibility behavior for existing sessions containing service_session_id, and whether the two-value API communicates that distinction clearly.

Related Issue

Fixes #7955

The earlier PR #7957 was closed unmerged for design discussion; there is no other open PR for this issue.

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.

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

Copilot-Session: a4c73599-9f66-4c22-bd66-96fe676e0ce6
Copilot AI balanced review requested due to automatic review settings September 1, 2026 15:59
@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 1, 2026
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a4c73599-9f66-4c22-bd66-96fe676e0ce6

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.

Pull request overview

Adds explicit model-history ownership for Python Foundry-hosted response agents, preventing duplicated conversation replay.

Changes:

  • Adds agent_server and agent history-source modes.
  • Enforces stateless downstream calls in AgentServer mode.
  • Adds regression tests, documentation, and ADR 0039.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
_responses.py Implements history-source selection and storage safeguards.
test_responses.py Covers history modes and session persistence.
README.md Documents configuration and behavior.
0039-python-foundry-hosting-history-source.md Records the architectural decision.

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

Comment thread python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py Outdated

@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)): a6ea50e3ab2e
Model: gpt-5.6-sol

Overview

The PR makes model-history ownership explicit and adds strong guards for standard Agent instances: it rejects conflicting providers and defaults, forces downstream storage off, clears stale service IDs, and tests persistence and function-loop behavior. Two gaps remain around the broader SupportsAgentRun contract and reuse of the caller-owned agent: mandatory storage options can be dropped for custom agents, and the transient provider installed by the default mode survives a later switch to agent-managed history.

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

Affected areas: python/packages/foundry_hosting/agent_framework_foundry_hosting/_responses.py

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

Copilot-Session: a4c73599-9f66-4c22-bd66-96fe676e0ce6
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot-Session: a4c73599-9f66-4c22-bd66-96fe676e0ce6
@sachinkahawala

Copy link
Copy Markdown

Reporter of #7955 — ran my repro/upgrade benches from that thread against this branch (default history_source="agent_server"): fresh chains are clean with the store=False override active on every call, and the upgrade sim (turns 1–2 on released 1.0.0b260827 persisting service_session_id="svc-thread-1", turn 3 on this branch) clears the stale id, completes, and shows no duplication. The compatibility behavior the review guide asks about checks out end-to-end. Happy to re-run these against any iteration.

One gap in ADR 0039, though: the STORES_BY_DEFAULT=True override puts FoundryChatClient — i.e. the default hosted-agent configuration — on store=false, and per my measurement on #7955 (comment) the service today adds a consistent ~+4.9s before the final SSE event on every streamed store=false call (med 6.1s vs 1.2s; service-side, no SDK in the measurement). Two questions that would make the ADR complete either way:

  1. Is a service-side fix for that hang in flight? If so, recording it as an accepted temporary regression in the ADR's Consequences would explain the choice; if not, the rejected "clear the service ID but leave downstream storage enabled" option is currently also the only fast option, which feels worth weighing against its retention/cost downsides.
  2. Is history_source="agent" the intended escape for latency-sensitive deployments in the meantime (service-side continuation stays on, only current input passed), accepting the change of history authority that comes with it?

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

3 participants