Repository navigation
Python: Support Responses API server-side compaction with store=false - #8891
Dineshsuriya D (droideronline) wants to merge 8 commits into
Conversation
Add a core compaction content type and teach the OpenAI Responses client (inherited by FoundryChatClient) to preserve compaction output items in streaming and non-streaming responses. For stateless requests the latest compaction item is replayed as an input item and the history before it, other than system/developer messages, is no longer sent. With service-side storage the item is not re-sent and nothing is pruned. context_management is now a typed option. Fixes microsoft#8890
…paction-store-false
|
Fixed the failing "Test Typing Checks" job in 97decb4: the compaction agent test now declares its options as |
Eduard van Valkenburg (eavanvalkenburg)
left a comment
There was a problem hiding this comment.
Dineshsuriya D (@droideronline) I don't think we should merge this as a separate OpenAI-specific compaction path yet. Core already exposes provider-neutral compaction through CompactionStrategy, the chat client's compaction_strategy, and CompactionProvider, while this adds a second "compaction" concept: a public Content type/factory whose actual contract is an OpenAI Responses encrypted item, with pruning and replay implemented only in the OpenAI client. That leaves callers and future providers with two compaction models that do not compose, and makes the core contract difficult to evolve beyond OpenAI's current wire shape. Could we step back and propose how server-side compaction dovetails with the existing compaction abstraction—particularly how client-side strategies, provider-owned opaque continuation state, and non-OpenAI providers compose—before fixing the public Content contract? At minimum, the new Content.from_compaction surface and content type need to be staged as experimental under the core feature-lifecycle rules until that design is settled.
Add ExperimentalFeature.SERVER_COMPACTION and mark Content.from_compaction and ContextManagementOptions with it, and document the staged surface in core AGENTS.md and PACKAGE_STATUS.md, until the design for composing server-side compaction with CompactionStrategy is settled.
|
Eduard van Valkenburg (@eavanvalkenburg) thanks, agreed that this shouldn't add a second compaction model. I've staged the new surface as experimental in 572feb2: new 1. Server compaction is expressed with the existing exclusion/summary annotations When a provider returns a compaction item, the client records it the same way a
Pruning then comes from the generic 2. The opaque payload stays provider-owned continuation state The compaction content is just the carrier for the provider's opaque state ( 3. Composition with client-side strategies
4. Non-OpenAI providers and switching providers Anthropic's context management returns comparable compaction blocks, so the same annotations would fit there. The open trade-off is switching providers mid-conversation: a provider that can't read the opaque state gets neither it nor the excluded history. Options are (a) accept that, as with encrypted reasoning today, or (b) have the projection re-include Questions
If this direction works, I'll rework the PR to drop the OpenAI-specific pruning and implement (1) and (2), keeping everything under |
…paction-store-false
|
Merged latest main (a5173fd). The previous |
…paction-store-false # Conflicts: # python/packages/openai/agent_framework_openai/_chat_client.py
|
/review |
There was a problem hiding this comment.
MAF Automated Review — Iteration 1
Result: Findings reported
Scope: full PR (7 commit(s)): ef81873c944a, 97decb470796, 8f4148e75d20, 572feb2b8cb1, a5173fd3c2d9, c0a3518c76ff, 975c0874cb1b
Model: gpt-5.6-sol
Overview
The change consistently parses and serializes compaction items across streaming, non-streaming, OpenAI, and Foundry paths, with tests covering continuation mode, stateless replay, instruction preservation, and reasoning-group validation. The residual correctness risk is that pruning recognizes a compaction marker more broadly than serialization does, so malformed persisted or caller-created content can silently remove usable history without supplying replacement state.
Reviewed the supplied pull-request change set across correctness, security/reliability, architecture, and failure behavior.
1 verified finding remained after source verification (1 medium) across 1 file. Details are attached to the affected lines below.
Affected areas: python/packages/openai/agent_framework_openai/_chat_client.py
…g it Ignore compaction content without a replayable payload when choosing the boundary.
|
Dineshsuriya D (@droideronline) Thanks for the work here. Before merging, we want to spec this out further: server-side Responses compaction is currently an OpenAI service-specific capability, and we need to be careful about the Agent Framework abstraction and portability contract. Please hold further implementation changes while we work through the design on #8890. |
Motivation & Context
The Responses API supports server-side compaction via
context_management, including withstore=false. When the context crossescompact_threshold, the service emits an encryptedcompactionoutput item. In stateless (input-array) mode the caller replays that item on the next request and can drop the items before it.OpenAIChatClientandFoundryChatClientalready forwardedcontext_managementto the service, but dropped the compaction item as unparsed output. Withstore=falseevery later turn resent the full uncompacted history, so compaction saved no tokens.Description & Review Guide
"compaction"content type andContent.from_compaction(protected_data=..., id=...). The encrypted payload lives inprotected_data(like encrypted reasoning), so it round-trips through history serialization.FoundryChatClient):response.output_item.donestream events.{"type": "compaction", "encrypted_content", "id"}input item, and messages before the message that contains it are dropped, except system/developer messages. Pruning is per message so tool calls stay paired with their results, and it runs before the stateless reasoning-group validation.previous_response_id/ conversation continuation, the compaction item is not re-sent and nothing is pruned, as the docs require.context_managementis declared onOpenAIChatOptions(and thereforeFoundryChatOptions).store=falseconversations usingcontext_managementnow carry the compacted state forward and send much smaller requests after compaction. Behavior without compaction items is unchanged. Other providers skip the new content type like any unsupported content.Not included: a wrapper for the standalone
responses.compactendpoint, and surfacing the streamingresponse.compaction.compactingprogress event.Related Issue
Fixes #8890
Contribution Checklist
breaking changelabel (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.