5.1 KiB
5.1 KiB
Runner Lifecycle
Use this reference for changes to Runner, turn accounting, guardrails, hooks, handoffs, interruptions, cancellation, or streaming and non-streaming behavior.
Turn Boundary
A turn is one logical model invocation plus processing of that response. Tool execution, handoff resolution, session persistence, interruption resume, and retries inside that logical invocation do not independently consume turns.
- Increment the turn counter exactly once when the run loop starts a logical model turn. Transport or provider retries inside
get_new_response()remain part of that turn. - A handoff changes the current agent, but the next turn begins only when the new agent invokes a model.
- Resuming
NextStepInterruptioncontinues the paused turn. Resolve stored approvals and tool work before deciding whether another model call is needed. - Preserve
max_turnsand the current turn inRunState; resume must not reset the budget or charge a turn twice.
Guardrail Ordering
- Input guardrails belong to the starting agent and run only for the initial user input. Do not rerun them after handoffs or when resuming an interruption.
- Sequential input guardrails must finish before model-side effects begin. Parallel input guardrails may overlap the model call, so a tripwire or exception must cancel and await the in-flight model task and sibling guardrail tasks.
- Tool input guardrails run before the approved tool side effect. Tool output guardrails run after local execution and before the output is accepted into the next step.
- Output guardrails run only after a candidate final output exists. Streaming must await them and preserve the same tripwire and exception behavior as non-streaming execution before declaring completion.
- Guardrail results are observable run state. Preserve them across handoffs, error handlers, streamed completion, and
RunStateround-trips.
Step State Machine
SingleStepResult.next_step is the control boundary after one model response and its local side effects:
| Step | Meaning |
|---|---|
NextStepRunAgain |
Continue with the current agent and make another model call |
NextStepHandoff |
Switch the current agent, emit the transition, then continue |
NextStepFinalOutput |
A final candidate exists; finish terminal hooks, output guardrails, persistence, and result construction |
NextStepInterruption |
Persist enough processed state to resume pending approvals without rerunning completed work |
Do not bypass this state machine with path-local completion logic. New terminal or pausable behavior must define non-streaming, streaming, session, tracing, and serialized-resume semantics.
Streaming Parity and Cancellation
- Streaming and non-streaming paths must produce equivalent final output, generated items, current agent, usage, guardrail results, session history, and interruption state for the same model behavior.
- Raw transport events may differ, but semantic
RunItemStreamEventandAgentUpdatedStreamEventemission must follow the same processed items and agent transitions used by the non-streaming result. stream_events()is the stream driver's cleanup boundary. Keep consuming it until exhaustion after normal completion orcancel(), or explicitly close the async iterator; merely breaking after the last visible token does not prove session writes, guardrails, compaction, sandbox cleanup, usage, or terminal errors have settled.- Immediate cancellation marks the result complete and requests task cancellation.
after_turncancellation leaves the current model/tool turn running so it can persist state and usage before the next turn. Preserve this distinction instead of treating both modes as queue shutdown. - Terminal run-loop, guardrail, and max-turn errors must be surfaced from
stream_events()after the required queued events are handled. Preserverun_loop_exceptionas a diagnostic view of the background task, not as a replacement completion primitive. task.cancel()is a request, not cleanup completion. Await cancelled tasks when theirfinallyblocks, exceptions, or owned resources affect run correctness.- Keep lifecycle hooks aligned across both paths, especially model start/end, handoff, tool start/end, and final-output hooks.
Review Checklist
- Identify which turn and which agent own the behavior.
- Trace every
NextStepoutcome, including interruption resume. - Compare streaming and non-streaming side effects and terminal ordering.
- Test guardrail tripwires and exceptions in sequential and parallel modes when relevant.
- Verify normal exhaustion, explicit iterator close, immediate cancellation, and after-turn cancellation leave the documented result and owned resources in a coherent state.
Sources
src/agents/run.pysrc/agents/run_internal/run_loop.pysrc/agents/run_internal/run_steps.pysrc/agents/run_internal/turn_preparation.pysrc/agents/run_internal/turn_resolution.pysrc/agents/run_internal/guardrails.pytests/test_agent_runner.pytests/test_agent_runner_streamed.pytests/test_cancel_streaming.pytests/test_guardrails.pytests/test_run_state.pydocs/streaming.mddocs/results.md