.agents/references/conversation-state-ownership.md
Use this reference for changes involving multi-turn input, sessions, conversation_id, previous_response_id, auto_previous_response_id, compaction, retries, call_model_input_filter, or RunState resume.
The state owner determines what the next model request should contain.
| Strategy | State owner | Next-turn input |
|---|---|---|
Explicit replay with result.to_input_list() | Application | Replay-ready history plus the new turn |
| SDK session | Application storage plus the SDK | The same session plus the new turn |
conversation_id | OpenAI Conversations API | The same conversation ID plus only the new turn |
previous_response_id or auto_previous_response_id | OpenAI Responses API | The previous response ID plus only the new turn |
RunState resume | Serialized Agents SDK run | Resume the same interrupted run; this is not a new conversation strategy |
In normal use, select one conversation strategy. Mixing client-managed replay or sessions with server-managed continuation can duplicate context unless the implementation explicitly reconciles both owners. Read Session persistence for the client-managed storage contract.
OpenAIServerConversationTracker in src/agents/run_internal/oai_conversation.py owns delta calculation for conversation_id, previous_response_id, and auto_previous_response_id.previous_response_id from the most recent response that actually has an ID. Do not erase a valid chain because an adjacent provider response lacks one.validate_session_conversation_settings() rejects a session with conversation_id, previous_response_id, or auto_previous_response_id; do not add a second history writer without defining reconciliation and dedupe semantics.conversation_id and previous_response_id / auto_previous_response_id chaining as mutually exclusive state owners.call_model_input_filter runs on the prepared model payload. With server-managed continuation, that payload may already be a new-turn delta rather than full history.ModelInputData with list input. Mark exactly the returned list as sent immediately before the request so nested preparation cannot add unsent items, rewind that tracking before retrying a failed request, and preserve it after success.RunState persists conversation identifiers and reconstructs tracker knowledge for resumed runs. Resume must not replay acknowledged input, lose unsent tool outputs, or increment the turn count without a model call.RunState resume continues a paused run. Do not substitute one mechanism for the other.compaction_mode="previous_response_id" depends on a usable stored response chain.compaction_mode="input" rebuilds from client-held items and is the fallback when the server chain is unavailable or store=False prevents later response lookup.Handoff.input_filter and RunConfig.handoff_input_filter should raise instead of rewriting a history the server already owns.nest_handoff_history is a client-history transformation. When server-managed continuation is active, disable it with a warning and continue with delta-only input.src/agents/run_internal/oai_conversation.pysrc/agents/run_internal/run_loop.pysrc/agents/run_internal/session_persistence.pysrc/agents/run_state.pydocs/running_agents.mddocs/sessions/index.mdRecheck the official API reference with $openai-knowledge before changing server-managed continuation behavior.