Streaming replies
Follow a run live with Server-Sent Events:
GET /agent-runs/{runId}/eventsIn a browser, use EventSource with credentials:
ts
const es = new EventSource(`https://api.lexcetha.com/api/v1/agent-runs/${runId}/events`, { withCredentials: true });
let reply = '';
es.addEventListener('assistant.delta', (e) => { reply += JSON.parse(e.data).text; render(reply); });
es.addEventListener('approval.required', (e) => askUser(JSON.parse(e.data)));
es.addEventListener('run.completed', (e) => { render(JSON.parse(e.data).output); es.close(); });
es.addEventListener('run.failed', (e) => { showError(JSON.parse(e.data).message); es.close(); });
es.addEventListener('run.cancelled', () => es.close());From a server, read the stream with any SSE client and the Authorization: Bearer header.
Events
Each event has an increasing id, a name and a JSON data payload.
| Event | Data | When |
|---|---|---|
run.started | { mode, botId } | The run begins |
assistant.delta | { text } | The next piece of the reply. Append it. |
tool.proposed | { callId, toolSlug, arguments } | The bot wants to use a tool (arguments are redacted) |
approval.required | { approvalId, callId, toolSlug, risk, summary, expiresAt } | The tool needs your approval, see Approvals |
run.waiting | { approvals: [approvalId] } | The run is paused until those are decided |
tool.started | { callId, toolSlug } | The tool is running |
tool.completed | { callId, toolSlug, status, result? } | status is succeeded (with result), failed, denied, rejected, expired, connection_required or duplicate |
run.completed | { output, stopReason } | Done. output is the full reply. |
run.failed | { code, message } | Stopped with an error |
run.cancelled | {} | Cancelled |
run.completed, run.failed and run.cancelled are final: close the stream after them.
stopReason is needs_setup when the bot is asking you to connect or install something you tagged; see Attachments & tags.
Reconnecting
Connections drop. Reconnect with the last event id and the stream continues from there, without repeating or losing anything:
EventSourcesendsLast-Event-IDfor you automatically.- Other clients can send the
Last-Event-IDheader, or?after={id}.
The server sends a comment every 15 seconds to keep the connection alive, and closes a stream after 30 minutes; reconnecting picks up where it left off.
