Skip to content

Python: fix Foundry OAuth consent response persistence - #8006

Merged
Eduard van Valkenburg (eavanvalkenburg) merged 3 commits into
microsoft:mainfrom
eavanvalkenburg:fix-foundry-oauth-consent
Sep 2, 2026
Merged

Python: fix Foundry OAuth consent response persistence#8006
Eduard van Valkenburg (eavanvalkenburg) merged 3 commits into
microsoft:mainfrom
eavanvalkenburg:fix-foundry-oauth-consent

Conversation

@eavanvalkenburg

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

Copy link
Copy Markdown
Member

Motivation & Context

Foundry-hosted agents can receive an oauth_consent_request only after an on-behalf-of MCP tool is invoked. ResponsesHostServer currently 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 permits max_output_tokens or content_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

  • What are the major changes? The output tracker now emits mid-run oauth_consent_request items, 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 call emit_incomplete without a reason. Connect-time consent also persists the current Agent Framework session so a retry through previous_response_id preserves state. A hosting-boundary validator rejects unsafe or malformed consent URLs before an action is emitted.
  • What is the impact of these changes? Foundry can persist the incomplete response without an invalid enum value, downstream clients can render safe consent actions, resilient recovery preserves the incomplete state without duplicate prompts, and a follow-up request can retry after consent. The change does not alter the Foundry parser or add workflow-specific resumability behavior.
  • What do you want reviewers to focus on? Please focus on the constrained terminal payload, restoration of persisted consent state, URL validation at both hosting paths, and session load/save behavior around connect-time consent.

Related Issue

Fixes #7658
Fixes #7725

Supersedes #7659. This replacement starts from current main and 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

  • 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]" in the title prefix, before or after a language prefix such as Python: or .NET: — workflows keep the label and the title prefix in sync automatically (see .github/workflows/label-title-prefix.yml and .github/workflows/label-pr.yml).

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>

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.

🟢 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.

@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)): 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
Merged via the queue into microsoft:main with commit b219545 Sep 2, 2026
37 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

python Usage: [Issues, PRs], Target: Python

Projects

None yet

3 participants