self.complete(...). After a subagent’s last step, its on_exit moves the call on.
Add Steps
List a subagent’s steps insteps. Each answer is a dataclass, and a tool ends the step with self.complete(...).
Callers often answer ahead. If your tool completes a later step early, the answer is kept and that step isn’t asked.
Steps Without Subagents
If one agent does the whole call, give the agent its steps withworkflow=. Its own tools finish them with self.complete(...).
workflow= or subagents=, not both. Subagents with no steps don’t need a workflow at all: each transfer_to is a plain agent handoff, and any runtime runs it.
Read Answers
Use the step’sid on self.workflow. For another subagent’s step, add its name. A step with no answer reads as None.
Optional and Conditional Steps
Addoptional=True to let the caller decline a step. The model skips it for you.
Add a condition to run a step only for some callers:
<step>.<key> from the same subagent, or userdata.<key> from the call’s metadata. You can use eq, ne, in, not_in, or exists, and combine them with all, any, and not.
Retry a Step
Setmax_attempts to limit retries. Each {"error": ...} from a subagent’s tool counts as one attempt. At the limit, on_step_failed runs:
Change an Answer
Usego_to_step when the caller changes their mind. Use "<subagent>.<step>" to go back to another subagent’s step.
go_to_step: call self.complete(...) with it. The finished step is updated and the call carries on from where it was.
Track Progress
Events tell your code what just happened on the call, so you can log progress or save answers to your own systems. They stay in your agent: the model doesn’t see them, and they aren’t sent to the room.result is the answer as a dict. progress lists that subagent’s steps as done, skipped, and to_do. A skipped step has no event of its own, so look for it in progress.
Listen on your agent:
@on_workflow on a subagent. It hears every subagent’s events, so check data["agent"] if you only want its own.
What’s Next
Subagents
Roles, hooks, and moving the call.
Clinic Example
A full call with retries, corrections, and events.