Skip to content

chimera.events

chimera.events is the loop’s observability surface: every meaningful state change emits a typed Event to a shared EventBus, and you can subscribe with @bus.on(type) or @bus.on("*").

from chimera.events import EventBus
from chimera.events.types import (
# Core
ToolCallEvent, ToolResultEvent, StepEvent, TextDeltaEvent, ErrorEvent,
LoopDetectedEvent, PermissionEvent, SessionEvent, StepCostEvent,
# Lifecycle (added in pi-mono)
AgentStartEvent, AgentEndEvent,
TurnStartEvent, TurnEndEvent,
StreamStartEvent, StreamEndEvent,
ModelRequestEvent, ModelResponseEvent,
# Advanced
CompactionEvent, CriticEvent,
ExternalAgentStartEvent, ExternalAgentCompleteEvent, ExternalAgentToolCallEvent,
SecurityEvent, SteeringEvent, CancellationEvent,
)

26 event types are emitted; the table below lists the lifecycle subset added during pi-mono adoption (the others — ToolCallEvent, etc. — are unchanged).

ClasstypeKey fields
AgentStartEventagent_startmax_steps
AgentEndEventagent_endsteps, success, total_cost
TurnStartEventturn_startturn_number
TurnEndEventturn_endturn_number, tool_calls_count
StreamStartEventstream_startmodel
StreamEndEventstream_endtotal_tokens
ModelRequestEventmodel_requestmodel, message_count, tool_count
ModelResponseEventmodel_responsemodel, content_length, tool_calls_count, input_tokens, output_tokens
SteeringEventsteeringcontent
CancellationEventcancellationat_step

All ten are exported from chimera.events.types and included in __all__.

from chimera.events import EventBus
bus = EventBus()
@bus.on("tool_call")
def on_tool(event):
print(f"[call] {event.tool_name}")
@bus.on("*") # subscribe to everything
def on_any(event):
print(f"[{event.type}] {event}")
bus.emit(ToolCallEvent(...)) # usually called by the loop, not user code
MethodPurpose
on(type_or_star)Decorator that registers a listener.
emit(event)Dispatch an event to listeners.
add_middleware(mw)Insert middleware that can transform events before dispatch (used by RedactionMiddleware from chimera.secrets).
clear()Drop all listeners (test helper).
from chimera import Agent, DEFAULT_TOOLS, EventBus, LoopConfig, ReAct, create_provider
bus = EventBus()
config = LoopConfig(event_bus=bus)
loop = ReAct(max_steps=30, config=config)
agent = Agent(provider=create_provider(model="glm-5"),
tools=list(DEFAULT_TOOLS), loop=loop)