The Runner system is the execution engine of the OpenAI Agents SDK. It's responsible for orchestrating agent runs, managing the lifecycle of agent execution, handling tool execution, coordinating handoffs, managing sessions, and ensuring proper error handling. Think of the Runner as the "director" that brings together all the components (agents, tools, guardrails, etc.) and makes them work together in a coordinated way.
Core Classes
Runner
Runner is the main entry point for executing agents. It provides both async and sync interfaces for running agents.
AgentRunner is the internal implementation class that does the actual work. The Runner class is a thin wrapper around AgentRunner that provides a simpler public API.
Location:src/agents/run.py
Key Responsibilities:
Turn management (tracking which turn we're on)
Tool execution coordination
Handoff delegation
Session persistence
Error handling and recovery
Streaming event emission
Tracing integration
Execution Flow
1. Initialization
When you call Runner.run(), the following initialization happens:
Python
Steps:
Context Wrapper Creation - A RunContextWrapper is created to wrap your context object. This wrapper provides:
Approval management (for human-in-the-loop)
Usage tracking
Tool state management
Access to run configuration
Agent Binding - The agent is "bound" to the run. This creates an AgentBindings object that:
Resolves the model to use (from agent, run config, or default)
Resolves model settings (merged from agent and run config)
Prepares the agent for execution
Session Preparation - If a session is provided, the conversation history is loaded and prepared. The session's items are combined with the new input.
Trace Creation - A trace is created for observability. This trace will:
Track all events during the run
Record timing information
Capture inputs and outputs (unless tracing is disabled)
Sandbox Setup - If sandbox configuration is provided, the sandbox session is initialized.
2. Turn Execution
A "turn" is one complete cycle of:
Input preparation
Model call
Tool execution (if needed)
Output processing
The Runner manages multiple turns until:
The agent produces a final output
Max turns is exceeded
An error occurs
A guardrail tripwire is triggered
Turn Lifecycle:
Python
3. Input Preparation
Input preparation converts the user's input into the format expected by the model:
Input Types:
String input - Simple text input
Python
List input - Structured input with multiple items
Python
RunState input - Resume from a paused state
Python
Session Integration:
If a session is provided, the input preparation:
Loads conversation history from the session
Applies the session's input callback (if configured)
Combines history with new input
Respects session limits (e.g., max items to retrieve)
4. Model Call
The Runner coordinates the model call through the model provider:
Python
Model Resolution:
The model is resolved in this priority order:
RunConfig.model (if set)
Agent.model (if set)
Default model (gpt-4.1)
Settings Merging:
Model settings are merged:
Start with agent.model_settings
Override with run_config.model_settings (if provided)
Apply any provider-specific defaults
Hooks:
Before and after the model call, lifecycle hooks are invoked:
on_llm_start - Before the call
on_llm_end - After the call
5. Response Processing
The model's response is processed to extract:
Message content - Text output from the model
Tool calls - Requests to call tools
Handoff calls - Requests to hand off to another agent