Principle:Openai Openai agents python Execution Resumption
Overview
After processing approval decisions on an interrupted agent run, the RunState is passed back to Runner.run() to resume execution from where it was paused. This completes the human-in-the-loop cycle: configure approval, run, interrupt, decide, and resume.
Core Theory
RunState as Input to Runner.run()
The Runner.run() method has a polymorphic input parameter that accepts three types:
str: A plain text user message for starting a new runlist[TResponseInputItem]: A list of structured input items for starting a new runRunState[TContext]: A serialized state snapshot for resuming an interrupted run
When a RunState is provided, the runner restores the execution context from the state rather than creating a new one. The agent, input, generated items, model responses, approval decisions, and turn counter are all recovered from the state, and execution continues from the exact point of interruption.
Turn Counter Preservation
A critical design property of resumption is that resuming does not increment the turn counter. The turn counter only advances when an actual model call is made. Processing approval decisions and resuming execution are considered administrative operations, not turns. This ensures that the turn budget (controlled by max_turns) accurately reflects the number of model invocations, not the number of interruption-resume cycles.
This behavior is explicitly documented in the SDK's runtime guidelines: "Resuming an interruption from RunState must not increment the turn counter; only actual model calls advance turns."
Approved Tool Execution
When the run resumes and encounters an approved tool call, the tool is executed normally. The tool receives the same parameters that were originally passed by the model, and its output is fed back to the model as if the interruption never occurred. The model then continues its reasoning with the tool's output.
Rejected Tool Handling
When a tool call has been rejected, the run does not execute the tool. Instead, it constructs an error response message and sends it back to the model. This message informs the LLM that the requested tool call was denied. The model can then:
- Attempt an alternative approach that does not require the rejected tool
- Ask the user for modified instructions
- Produce a final output explaining that it could not complete the task
This design preserves the conversational flow and gives the model an opportunity to adapt.
Iterative Approval Workflows
A resumed run may produce further interruptions if additional tool calls require approval. This creates an iterative approval loop:
- Run produces interruptions
- Human approves/rejects
- Run resumes and may produce new interruptions
- Repeat until no more interruptions
This pattern is natural for complex workflows where an agent needs to execute a sequence of sensitive operations. Each operation is individually reviewed as it arises, rather than requiring all operations to be predicted and approved upfront.
The Resumption Loop Pattern
The canonical pattern for handling iterative approvals is a while loop that checks for interruptions:
result = await Runner.run(agent, "Do something")
while result.interruptions:
state = result.to_state()
for item in state.get_interruptions():
state.approve(item) # or state.reject(item)
result = await Runner.run(agent, state)
print(result.final_output)
This pattern is complete and handles all cases: runs with no interruptions skip the loop entirely, runs with a single interruption execute the loop once, and runs with cascading interruptions execute the loop multiple times.
Consistency Guarantees
The resumption mechanism maintains several consistency guarantees:
- Context preservation: The same
RunContextWrapperis used throughout, accumulating approval decisions, usage statistics, and other metadata across all resume cycles - Item continuity: Generated items from before the interruption are preserved and included when constructing the model's input on resumption
- Agent identity: The same agent instance that was active at interruption continues handling the conversation
- Conversation tracking: Server-managed conversation IDs and response IDs are preserved across resume cycles
Key Source References
src/agents/run.pylines 154-231:Runner.run()acceptingRunStateas input
Related Concepts
- Implementation:Openai_Openai_agents_python_Runner_Resume_Pattern
- Tool Approval Definition for configuring tools to require approval
- RunState Serialization for capturing run state
- Approval Processing for recording approval decisions