Python: Add long-running agents and background responses support#3808
Merged
eavanvalkenburg merged 4 commits intomicrosoft:mainfrom Feb 10, 2026
Merged
Conversation
Member
Contributor
There was a problem hiding this comment.
Pull request overview
Adds Python support for long-running agent operations via OpenAI Responses “background” runs, including continuation token propagation across core response types, OpenAI client polling/resumption paths, telemetry fixes for streaming spans, plus tests and a sample.
Changes:
- Introduces a
ContinuationTokenTypedDict and propagates it throughChatResponse*andAgentResponse*types and mapping/merge logic. - Extends
OpenAIResponsesClientoptions withbackground+continuation_token, enabling non-streaming polling and streaming resumption via retrieve. - Fixes OpenTelemetry streaming span lifecycle handling and adds unit tests + a usage sample + changelog entry.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| python/packages/core/agent_framework/_types.py | Adds ContinuationToken and plumbs continuation_token through response/update types and update processing. |
| python/packages/core/agent_framework/openai/_responses_client.py | Adds background + continuation token support, including polling and stream resumption behavior. |
| python/packages/core/agent_framework/_agents.py | Propagates continuation_token into AgentResponse (non-streaming path). |
| python/packages/core/agent_framework/observability.py | Fixes streaming span detach errors by avoiding context attachment for spans closed in async cleanup. |
| python/packages/core/tests/openai/test_openai_responses_client.py | Adds unit tests covering token serialization/propagation and background status handling. |
| python/samples/concepts/background_responses.py | Adds a sample demonstrating polling and streaming resumption patterns. |
| python/CHANGELOG.md | Documents the new long-running/background responses feature. |
python/packages/core/tests/openai/test_openai_responses_client.py
Outdated
Show resolved
Hide resolved
markwallace-microsoft
approved these changes
Feb 10, 2026
dmytrostruk
reviewed
Feb 10, 2026
dmytrostruk
approved these changes
Feb 10, 2026
dmytrostruk
approved these changes
Feb 10, 2026
7d72bcf to
9571b91
Compare
- Add ContinuationToken TypedDict to core types - Add continuation_token field to ChatResponse, ChatResponseUpdate, AgentResponse, and AgentResponseUpdate - Add background and continuation_token options to OpenAIResponsesOptions - Implement polling via responses.retrieve() and streaming resumption in RawOpenAIResponsesClient - Propagate continuation tokens through agent run() and map_chat_to_agent_update - Fix streaming telemetry 'Failed to detach context' error in both ChatTelemetryLayer and AgentTelemetryLayer by avoiding trace.use_span() context attachment for async-managed spans - Add 14 unit tests for continuation token types and background flows - Add background_responses sample showing polling and stream resumption Fixes microsoft#2478
- Make ContinuationToken provider-agnostic (total=False, optional task_id/context_id fields) - Add background param to A2AAgent.run() controlling token emission - Add poll_task() for single-request task state retrieval - Add resubscribe support via continuation_token param on run() - Extract _updates_from_task() and _map_a2a_stream() for cleaner code - Streamline run()/streaming by removing intermediate _stream_updates wrapper - Update A2A sample to show background=False (default) with link to background_responses sample - Remove stale BareAgent from __all__ - Add 12 new A2A continuation token tests
9571b91 to
80c2c52
Compare
dmytrostruk
approved these changes
Feb 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds support for long-running agent operations and background responses, matching the dotnet implementation pattern adapted to Python conventions.
Fixes #2478
Changes
Core Types (
_types.py)ContinuationTokenTypedDict — a simple JSON-serializable dict withresponse_idfieldcontinuation_token: ContinuationToken | NonetoChatResponse,ChatResponseUpdate,AgentResponse, andAgentResponseUpdatemap_chat_to_agent_updateand_process_updateto propagate tokensOpenAI Responses Client (
_responses_client.py)background: boolandcontinuation_token: ContinuationTokentoOpenAIResponsesOptionsresponses.retrieve(response_id)whencontinuation_tokenis providedresponses.retrieve(response_id, stream=True)whencontinuation_tokenis providedcontinuation_tokenon responses when OpenAI status isin_progressorqueuedAgent Layer (
_agents.py)continuation_tokenfromChatResponse→AgentResponsein non-streaming pathTelemetry Fix (
observability.py)Failed to detach contexterror in bothChatTelemetryLayerandAgentTelemetryLayerstreaming pathstrace.use_span()context was attached synchronously but detached in async cleanup hooks (different async context)start_span()+span.end()for streaming, avoiding context attachmentTests
Sample
samples/concepts/background_responses.pydemonstrating non-streaming polling and streaming resumption patternsUsage