-
Notifications
You must be signed in to change notification settings - Fork 3
event_system
This document provides a comprehensive overview of the event system in the Multi-Agent Builder, covering type safety, filtering layers, frontend delivery mechanisms, and hierarchical grouping.
The event type system uses a TypeScript Discriminated Union pattern to enforce strict type safety, eliminate unsafe casting, and improve developer experience.
Key Benefits:
-
Type Safety: The compiler guarantees that
event.data.datamatchesevent.type. -
Zero Casting: Removes the need for manual
as Typecasts or helper functions. -
Better IDE Support: Autocomplete works correctly based on the checked
type.
PollingEvent (Backend: event_store.go)
├── id: string
├── type: "tool_call_start" ← Event type discriminator
├── timestamp: ISO string
├── session_id?: string
├── error?: string
└── data: AgentEvent ← Unified payload for Orchestrator & MCP
├── type: "tool_call_start" ← Same as parent
├── timestamp: ISO string
├── event_index: number
├── trace_id?: string
├── hierarchy_level: number
├── correlation_id?: string ← Used for delegation grouping
├── parent_id?: string ← Used for direct parenting
└── data: ToolCallStartEvent ← Actual typed event data
├── tool_name: string
├── tool_params: object
└── server_name: string
Key Insight: Event data is located at event.data.data, not event.data.
The system uses multiple layers of filtering to manage performance, bandwidth, and storage space.
File: agent_go/cmd/server/event_bridge/base_bridge.go
Events in this map are discarded immediately and never reach the memory store or database.
-
Types:
tool_execution,tool_output,tool_response,tool_call_progress, and allcache_*events.
File: agent_go/cmd/server/event_bridge/base_bridge.go
Events in this map are kept in memory (for real-time SSE and polling) but never saved to the database. This saves massive amounts of space and enables "Micro Mode" by default.
-
Types:
step_progress_updated,llm_generation_start,conversation_turn,streaming_chunk. -
CRITICAL EXCEPTION:
llm_generation_endandagent_endare NOT skipped. They are required to clear the "Generating..." state when a session is restored.
File: agent_go/internal/events/event_store.go
Acts as a safety net at the polling layer. It filters out events that might have been stored in the database before SKIP_EVENTS was implemented.
-
Types: Mirrors
SKIP_EVENTS+ ephemeralstreaming_start/chunkevents.
File: agent_go/internal/events/event_store.go & EventHierarchy.tsx
These events reach the frontend and are available in the state (e.g., for token usage calculations) but are hidden from the main event list.
-
Types:
llm_generation_start,agent_start,conversation_start. -
Runtime Filtering:
token_usageevents withcontext: 'conversation_total'are stripped from the main view to reduce UI noise.
The frontend establishes a Server-Sent Events (SSE) connection to receive real-time updates.
-
Store: Events are deduplicated and stored by session in
useChatStore(tabEvents). -
Streaming Chunks:
streaming_chunkevents bypass the database and polling completely. They are delivered exclusively via the SSE buffer for real-time text rendering.
The frontend tracks the highest event_index received per session (tabEventIndices).
- On reconnection, the
SSEConnectionsends this index via theLast-Event-IDheader. - The backend uses this to automatically replay any events missed during the network drop before resuming real-time delivery.
If the SSE connection fails consecutively (e.g., 5 network failures), the frontend ChatArea.tsx orchestration gracefully degrades to HTTP polling (pollEvents) to ensure the session remains responsive.
File: frontend/src/components/events/EventHierarchy.tsx
The UI reconstructs complex multi-agent and workflow executions into an expandable tree using correlation_id and parent_id.
When a sub-agent is spawned, it generates many events. To prevent these from cluttering the main orchestrator's timeline:
- The frontend scans for events with a
correlation_idstarting withdelegation-. - These child events are extracted from the flat timeline.
- They are visually re-parented under the specific
delegation_startnode (rendered as an expandable Sub-Agent Card).
For concurrent workflows, parallel tool calls are parented under their respective orchestrator_agent_start node via correlation_id. This guarantees parallel agent tool executions don't incorrectly merge.
To further reduce noise in the main timeline, consecutive tool-related events (tool_call_start, tool_call_end, token_usage, llm_generation_end) are collapsed into a single + N tool calls inline button.
- Because sub-agent events are removed from the flat list (as described above), they never interfere with or get swallowed by the main agent's tool call groups.
Auto-synced from docs/ on main. Edit there, not here.