Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Runtime Event Bus

The runtime publishes session changes, store writes, automation activity, and config reloads through GET /api/events. Use these events to refresh data in your application.

Chat responses use a separate POST stream with text_delta, tool_call_start, and done messages. See Runtime Server. The event bus reports state changes across sessions; it does not replace authenticated data queries.

Subscribe

This browser example uses the current origin and its hosted session. A cross-origin or bearer-authenticated client needs an appropriate authenticated connection; native EventSource cannot set an Authorization header.

const events = new EventSource('/api/events');
const handleEvent = (message: MessageEvent<string>) => {
  const event = JSON.parse(message.data);
  if (event.type === 'session_created') {
    console.log('Session created:', event.sessionId);
  }
};
 
// Direct runtimes name SSE events, so register a named listener for each
// catalog type the view uses. The hosted event service uses message frames.
events.addEventListener('session_created', handleEvent);
events.addEventListener('message', handleEvent);

Call events.close() when the view is disposed. The server sends a comment heartbeat every 15 seconds.

createLocalServer() mounts this route. An application using createServer() directly must opt in with mountEventsRoute: true. Hosted deployments provide their own event route.

Reconnect-and-resume

EventSource saves the SSE id and sends it as Last-Event-ID on reconnect. Treat this ID as an opaque cursor:

  • A direct runtime uses a process-local sequence and retains 200 events by default. Its cursor and buffer reset when the process restarts.
  • Hosted deployments routed through the event service use Redis stream IDs, with retention configured by the platform. Do not substitute the event payload's seq for this cursor.

The server replays retained events after the cursor, then streams live events. Missing events outside retention cannot be recovered from this subscription. Refresh the underlying data after a reconnect if your view needs a complete state. A gap in numeric seq can also come from filtered event types, so it is not proof of data loss.

Event catalog

Session events

TypeFieldsWhen
session_createdsessionId, agentIdA new session was created (chat, admin, automation).
session_updatedsessionId, agentId, title?, status?, answeredBy?A session was persisted after a message, title change, or metadata update.
session_deletedsessionIdA session was deleted via the API.

Automation events

TypeFieldsWhen
automation_triggeredname, sourceAutomation run starting. source is "cron", "webhook", or "manual".
automation_completedname, durationMsAutomation finished successfully.
automation_failedname, error, durationMsAutomation threw during the agent loop.
automation_startedname, intervalMsA cron automation was registered or resumed by the platform.
automation_stoppednameA cron automation was paused.

Delivery events

TypeFieldsWhen
delivery_succeededautomation, targetType, targetUrl?, httpStatus?, durationMsA delivery target accepted the payload.
delivery_failedautomation, targetType, targetUrl?, httpStatus?, error, attemptsDelivery failed after retries.

Store events

TypeFieldsWhen
store_updatedstoreName, operation, count?A document was written, deleted, or batch-written. operation is "put", "delete", or "batch".

Config events

TypeFieldsWhen
manifest_changedNoneThe agent manifest (connections, skills, automations) was reloaded after a source or deploy change.
files_changedpath?A file in the agent repo changed. Amodal uses this to refresh source-aware views.
reload_failedmessageA bundle reload failed; the runtime keeps serving the previous bundle.

Channel events

TypeWhen
channel_message_receivedAn inbound message arrived on a messaging channel.
channel_reply_sentThe agent's reply was delivered back to the channel.
channel_session_createdA channel conversation started a new session.
channel_auth_rejectedA channel webhook failed authentication.

Tool-call events

tool_call_started, tool_call_completed, and tool_call_failed report execution activity. The core runtime route excludes them by default; add ?include=tool_calls or individual type names to include them. The hosted routes do not apply this core-route filter.

Types

All events carry seq, timestamp, and type fields plus the event-specific payload. The React SDK exports AgentEvent, which accepts runtime event fields as unknown values. Narrow those fields before using them:

import type { AgentEvent } from '@amodalai/react';
 
function handleEvent(event: AgentEvent) {
  if (event.type === 'session_updated' && typeof event['sessionId'] === 'string') {
    console.log(event['sessionId'], event['status']);
  }
}

When to use events vs. polling

Use events to know when to refresh a session list, automation status, or store-backed view. Use the corresponding HTTP API to fetch the current data and enforce the caller's access.

Event delivery and data access have separate boundaries. Do not treat receipt of an event as permission to read the referenced session or store.