Python: fix Foundry OAuth consent response persistence - #8006
Conversation
Surface mid-run OAuth consent items without writing a free-form incomplete reason, and persist session state so consent retries can continue through previous_response_id. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟢 Approval recommended
The implementation addresses the persistence contract and includes focused coverage for the affected paths.
Pull request overview
Fixes Foundry-hosted OAuth consent persistence and surfacing.
Changes:
- Emits deduplicated mid-run OAuth consent items.
- Removes invalid incomplete reasons.
- Preserves sessions for consent retries.
File summaries
| File | Description |
|---|---|
_responses.py |
Adds consent emission, deduplication, status handling, and session persistence. |
test_responses.py |
Covers streaming, persistence, retry, and session preservation. |
Review details
- Files reviewed: 2/2 changed files
- Comments generated: 0
- Review effort level: Balanced
💡 Add a code-review agent skill for context-aware, tailored reviews. Learn more in the docs.
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: Findings reported
Scope: full PR (1 commit(s)): 2621c3e7b192
Model: gpt-5.6-sol
Overview
The change correctly removes the unsupported incomplete reason, snapshots non-workflow sessions for connect-time consent, and emits deduplicated structured consent items from mid-run output. The focused tests cover fresh streaming and non-streaming retries, but resilient workflow recovery does not restore the tracker's consent state, and the new mid-run path forwards action URLs without enforcing a safe URL policy.
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
Restore consent tracking from persisted response output and reject unsafe consent URLs at both Foundry hosting boundaries. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: bdeb2e8a-4d41-4d14-9589-1637f33003dd
Cast the event stream response to its generated ResponseObject type before constructing the recovered stream fixture. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: bdeb2e8a-4d41-4d14-9589-1637f33003dd
Motivation & Context
Foundry-hosted agents can receive an
oauth_consent_requestonly after an on-behalf-of MCP tool is invoked.ResponsesHostServercurrently drops that mid-run content, so clients never receive the structured consent action.The existing connect-time path has a second contract violation: it marks the response incomplete with a free-form sentence in
incomplete_details.reason. The Responses contract only permitsmax_output_tokensorcontent_filter; Foundry persistence rejects the unknown value, turning an otherwise actionable consent response into correlated HTTP 400 and 500 failures before Teams can render it.Description & Review Guide
oauth_consent_requestitems, preserves the consent link and server label, suppresses exact duplicates, and restores consent state from persisted response output during recovery. Both connect-time and mid-run consent responses callemit_incompletewithout a reason. Connect-time consent also persists the current Agent Framework session so a retry throughprevious_response_idpreserves state. A hosting-boundary validator rejects unsafe or malformed consent URLs before an action is emitted.Related Issue
Fixes #7658
Fixes #7725
Supersedes #7659. This replacement starts from current
mainand keeps the fix in Foundry hosting instead of carrying the prior PR's core validator, parser rewrite, and workflow-specific behavior. #7659 is closed in favor of this PR.Contribution Checklist
breaking changelabel (or add "[BREAKING]" in the title prefix, before or after a language prefix such asPython:or.NET:— workflows keep the label and the title prefix in sync automatically (see.github/workflows/label-title-prefix.ymland.github/workflows/label-pr.yml).