Step hooks intercept each unit of work inside an execution: every crew task
and every flow method. Use them to inspect or rewrite what goes into a
step, transform what comes out, or trace step-by-step progress — without
touching the level of individual LLM or tool calls.
Overview
Two interception points cover steps:
| Point | When | ctx.payload |
|---|
PRE_STEP | Before a task or flow method runs | step input (see below) |
POST_STEP | After a task or flow method runs | step output (see below) |
What the payload holds depends on ctx.kind:
ctx.kind | PRE_STEP payload | POST_STEP payload |
|---|
"task" | The context string passed to the agent | The TaskOutput object |
"flow_method" | The method’s parameters as a dict | The method’s return value |
For flow methods, positional arguments appear in the params dict under _0,
_1, … keys and keyword arguments under their own names; edits and
replacements are mapped back onto the actual call.
Hook Signature
Context Schema
Both points receive a StepContext:
For task steps, step_name is the task’s name (falling back to its
description). For flow-method steps, it is the method name.
Common Use Cases
Step Tracing
Rewriting Task Context
POST_STEP runs before the task’s output is stored, so rewrites propagate
everywhere the output is used: downstream task context, callbacks, the final
crew output, and the task’s output_file on disk.
Guarding Flow Methods
Filtering by Agent
Step hooks support the same agents= filter as the other points (matched
against the executing agent’s role on task steps):
Aborting a Step
Raising HookAborted in PRE_STEP stops the step before any agent or method
work happens, and the abort propagates out of the execution with its reason —
it is not swallowed. Any other exception raised by a step hook is swallowed
(fail-open), like at every other point.
Managing Hooks in Tests