In plain terms
The event bus is a mailbox. When something happens (“run started”, “tool used”, “run finished”), Agentium drops a note in the mailbox. You can listen. You watch with the bus. You steer with hooks.
Trying to “approve a tool” by emitting on the bus will not work. Approval has its own API. See Approval.
The smallest example
agent.events is the same object as agent.eventBus.
Listen to everything — onAny
Best attachment point for tracers. You don’t have to list every event name.
One bus for the whole process
By default each agent/team/workflow gets its own bus. A tracer on agent A will not see agent B. Share one:EventBus.resetShared() exists for tests.
Events that actually fire
Prefer this short list (LIFECYCLE_EVENTS):
AgentEventMap only lists events that actually fire. A typo in an event name is a type error. Voice and browser events live on the same map but are not in LIFECYCLE_EVENTS.
Payloads
cost.tracked is a replacement run total. Do not sum successive events. For durable totals and incomplete prices, query the accounting store. See cost tracking.
Voice: voice.connected, voice.audio, voice.transcript, voice.tool.call, voice.tool.result, voice.error, voice.disconnected. Browser: browser.screenshot, browser.action, browser.step, browser.done, browser.error.
Import the list:
Methods
Every method is chainable exceptemit (returns whether anyone heard it).
Observability
@agentium/observability already listens to the bus. You usually just call instrument(agent). See Observability.
Observer failures
Named andonAny listeners are observers: their thrown errors or rejected promises do not alter Agent/tool results or skip later observers. Configure onObserverError and maxObserverDiagnostics on EventBus for bounded diagnostics. Use getObserverDiagnostics() to inspect total, reported, and suppressed failures. Control hooks, policy, and approval retain their deliberate control semantics.