Process agent responses, tool calls and results in real-time through streaming or handlers.
ControlFlow provides two ways to process events during task execution:
Both approaches give you access to the same events - which one you choose depends on how you want to integrate with your application.
When you enable streaming, task execution returns an iterator that yields events as they occur. Each iteration provides a tuple of (event, snapshot, delta) representing what just happened in the workflow:
You can focus on specific events using the Stream
enum. Here, we return only content updates:
The available stream filters are:
Stream.ALL
: All events (equivalent to stream=True
)Stream.CONTENT
: Agent content and content deltasStream.TOOLS
: All tool eventsStream.COMPLETION_TOOLS
: Completion tool events (like marking a task successful or failed)Stream.AGENT_TOOLS
: Tools used by agents for any purpose other than completing a taskStream.TASK_EVENTS
: Task lifecycle events (starting, completion, failure, etc)You can combine filters with the |
operator:
For more complex filtering, set stream=True and filter the events manually, or use a handler.
For more complex event processing, or when you want to decouple event handling from your main workflow, use handlers:
Handlers are especially useful for:
Handlers call their on_<event-name>
methods for each event type. For a complete list of available methods, see the Event Details section below.
For asynchronous event processing, use AsyncHandler
:
Here’s a complete example showing both approaches to display content in real-time:
Now that we’ve seen how to process events, let’s look at the types of events you can receive:
Content events give you access to what an agent is saying or writing:
Tool events let you observe when agents use tools and get their results:
Events that mark key points in a task’s lifecycle:
TaskStart
: A task has begun executionTaskSuccess
: A task completed successfully (includes the final result)TaskFailure
: A task failed (includes the error reason)TaskSkipped
: A task was skippedEvents related to orchestrating the overall workflow:
OrchestratorStart
/End
: Workflow orchestration starting/endingAgentTurnStart
/End
: An agent’s turn starting/endingOrchestratorError
: An error occurred during orchestrationEach handler can implement methods for different types of events. The method will be called whenever that type of event occurs. Here are all available handler methods:
Method | Event Type | Description |
---|---|---|
on_event(event) | Any | Called for every event, before any specific handler |
on_agent_message(event) | AgentMessage | Raw LLM output containing both content and tool calls |
on_agent_message_delta(event) | AgentMessageDelta | Incremental updates to raw LLM output |
on_agent_content(event) | AgentContent | Unstructured text output from an agent |
on_agent_content_delta(event) | AgentContentDelta | Incremental updates to agent content |
on_agent_tool_call(event) | AgentToolCall | Tool being called by an agent |
on_agent_tool_call_delta(event) | AgentToolCallDelta | Incremental updates to a tool call |
on_tool_result(event) | ToolResult | Result returned from a tool |
on_orchestrator_start(event) | OrchestratorStart | Workflow orchestration starting |
on_orchestrator_end(event) | OrchestratorEnd | Workflow orchestration completed |
on_agent_turn_start(event) | AgentTurnStart | An agent beginning their turn |
on_agent_turn_end(event) | AgentTurnEnd | An agent completing their turn |
on_orchestrator_error(event) | OrchestratorError | Error during orchestration |
Note that AgentMessage is the “raw” output from the LLM and contains both unstructured content and structured tool calls. When you receive an AgentMessage, you will also receive separate AgentContent and/or AgentToolCall events for any content or tool calls contained in that message. This allows you to:
on_agent_message
on_agent_content
on_agent_tool_call
For streaming cases, the delta events (e.g. AgentMessageDelta, AgentContentDelta) provide incremental updates as the LLM generates its response. Task events, in contrast, are complete events that mark important points in a task’s lifecycle - you can use these to track progress and get results without managing the task object directly..
Process agent responses, tool calls and results in real-time through streaming or handlers.
ControlFlow provides two ways to process events during task execution:
Both approaches give you access to the same events - which one you choose depends on how you want to integrate with your application.
When you enable streaming, task execution returns an iterator that yields events as they occur. Each iteration provides a tuple of (event, snapshot, delta) representing what just happened in the workflow:
You can focus on specific events using the Stream
enum. Here, we return only content updates:
The available stream filters are:
Stream.ALL
: All events (equivalent to stream=True
)Stream.CONTENT
: Agent content and content deltasStream.TOOLS
: All tool eventsStream.COMPLETION_TOOLS
: Completion tool events (like marking a task successful or failed)Stream.AGENT_TOOLS
: Tools used by agents for any purpose other than completing a taskStream.TASK_EVENTS
: Task lifecycle events (starting, completion, failure, etc)You can combine filters with the |
operator:
For more complex filtering, set stream=True and filter the events manually, or use a handler.
For more complex event processing, or when you want to decouple event handling from your main workflow, use handlers:
Handlers are especially useful for:
Handlers call their on_<event-name>
methods for each event type. For a complete list of available methods, see the Event Details section below.
For asynchronous event processing, use AsyncHandler
:
Here’s a complete example showing both approaches to display content in real-time:
Now that we’ve seen how to process events, let’s look at the types of events you can receive:
Content events give you access to what an agent is saying or writing:
Tool events let you observe when agents use tools and get their results:
Events that mark key points in a task’s lifecycle:
TaskStart
: A task has begun executionTaskSuccess
: A task completed successfully (includes the final result)TaskFailure
: A task failed (includes the error reason)TaskSkipped
: A task was skippedEvents related to orchestrating the overall workflow:
OrchestratorStart
/End
: Workflow orchestration starting/endingAgentTurnStart
/End
: An agent’s turn starting/endingOrchestratorError
: An error occurred during orchestrationEach handler can implement methods for different types of events. The method will be called whenever that type of event occurs. Here are all available handler methods:
Method | Event Type | Description |
---|---|---|
on_event(event) | Any | Called for every event, before any specific handler |
on_agent_message(event) | AgentMessage | Raw LLM output containing both content and tool calls |
on_agent_message_delta(event) | AgentMessageDelta | Incremental updates to raw LLM output |
on_agent_content(event) | AgentContent | Unstructured text output from an agent |
on_agent_content_delta(event) | AgentContentDelta | Incremental updates to agent content |
on_agent_tool_call(event) | AgentToolCall | Tool being called by an agent |
on_agent_tool_call_delta(event) | AgentToolCallDelta | Incremental updates to a tool call |
on_tool_result(event) | ToolResult | Result returned from a tool |
on_orchestrator_start(event) | OrchestratorStart | Workflow orchestration starting |
on_orchestrator_end(event) | OrchestratorEnd | Workflow orchestration completed |
on_agent_turn_start(event) | AgentTurnStart | An agent beginning their turn |
on_agent_turn_end(event) | AgentTurnEnd | An agent completing their turn |
on_orchestrator_error(event) | OrchestratorError | Error during orchestration |
Note that AgentMessage is the “raw” output from the LLM and contains both unstructured content and structured tool calls. When you receive an AgentMessage, you will also receive separate AgentContent and/or AgentToolCall events for any content or tool calls contained in that message. This allows you to:
on_agent_message
on_agent_content
on_agent_tool_call
For streaming cases, the delta events (e.g. AgentMessageDelta, AgentContentDelta) provide incremental updates as the LLM generates its response. Task events, in contrast, are complete events that mark important points in a task’s lifecycle - you can use these to track progress and get results without managing the task object directly..