Skip to content

Python: fix(python): preserve CostControl budget failures in hosted Responses - #8488

Draft
banibrata-de wants to merge 1 commit into
microsoft:mainfrom
banibrata-de:costcontrol-budget-failure-propagation
Draft

banibrata-de wants to merge 1 commit into
microsoft:mainfrom
banibrata-de:costcontrol-budget-failure-propagation

Conversation

@banibrata-de

Copy link
Copy Markdown

Motivation & Context

Foundry-hosted Responses agents currently lose CostControl budget classification when a streaming model response ends with an error event. The raw response headers identify budget_exceeded, but the OpenAI SDK raises a generic stream APIError, and the hosting adapter emits response.failed with server_error.

Description & Review Guide

  • What are the major changes?
    • Preserve raw response headers when wrapping OpenAI streaming and non-streaming failures.
    • Detect allowlisted CostControl headers across the exception chain.
    • Emit response.failed.error.code as budget_exceeded.
    • Attach the allowlisted headers as compact JSON in response.metadata.costControl.
  • What is the impact of these changes?
    • Responses clients can distinguish budget blocks from generic server failures for both streaming and non-streaming requests.
    • Other failures retain the existing server_error behavior.
  • What do you want reviewers to focus on?
    • The exception-header lifetime across the raw streaming response boundary.
    • The CostControl allowlist and metadata size bound.

Related Issue

Fixes #8487

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.
  • 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 title prefix in sync automatically.

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

Copilot-Session: 99113cf0-df56-4e0f-979a-a7d39a173e4d
Copilot AI balanced review requested due to automatic review settings September 17, 2026 22:19
@banibrata-de
banibrata-de deployed to github-app-auth September 17, 2026 22:19 — with GitHub Actions Active
@banibrata-de
banibrata-de deployed to github-app-auth September 17, 2026 22:19 — with GitHub Actions Active

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 encountered an error: Your billing is not configured or you have Copilot licenses from multiple standalone organizations or enterprises. To use premium requests, select a billing entity via the GitHub site, under Settings > Copilot > Features.

@banibrata-de
banibrata-de deployed to github-app-auth September 17, 2026 22:19 — with GitHub Actions Active
@banibrata-de
banibrata-de deployed to github-app-auth September 17, 2026 22:20 — with GitHub Actions Active
@agent-framework-automation agent-framework-automation Bot added the python Usage: [Issues, PRs], Target: Python label Sep 17, 2026
@github-actions github-actions Bot changed the title fix(python): preserve CostControl budget failures in hosted Responses Python: fix(python): preserve CostControl budget failures in hosted Responses Sep 17, 2026

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.

Could we preserve headers from the wrapped raw response before entering _open_event_stream? With Azure GenAI tracing enabled, raw_create_response is an AsyncStreamWrapper with no headers; the headers remain on its stream_async_iter, so _chat_client.py:940 records None and a later budget SSE error is still wrapped without x-ms-budget-cause. The hosted adapter then emits server_error instead of budget_exceeded. Could header extraction inspect the same inner raw response that _open_event_stream unwraps, and apply that to the retrieve path at _chat_client.py:880 too?

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

Development

Successfully merging this pull request may close these issues.

Python: Hosted Responses lose CostControl budget failure metadata

4 participants