> ## Documentation Index
> Fetch the complete documentation index at: https://arden.timganiev.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Streaming

> Server-Sent Events for real-time agent execution.

## Overview

Arden uses a persistent SSE connection per session. Connect to `GET /chat/events/{session_id}` to receive all events (agent responses, tool calls, background task results). Messages are sent via `POST /chat/message` as fire-and-forget – the response arrives on the SSE stream.

Each event has a `type` field indicating what happened.

## Event envelope

Every chat stream event includes server-owned ordering metadata:

```json theme={null}
{
  "type": "TEXT_MESSAGE_CONTENT",
  "session_id": "20260508_120000_000",
  "run_id": "cool-otter",
  "seq": 12,
  "timestamp": 1778241600000
}
```

The SSE `id` field is the same value as `seq`. Clients should reconnect with `after_seq=<last seen seq>` and ignore events whose sequence is not greater than the last applied sequence for that session.

If `after_seq` is older than the server's checkpoint watermark (events at or below the watermark are persisted to disk and only available via the history endpoint), or points past the server's known stream generation, the server emits `stream_reset`. Desktop responds by reloading session history before applying more events for that session.

A checkpoint advances after every agent step (and at run finish) when the chat service persists messages. The replay buffer itself is *not* cleared at the checkpoint – it grows up to a fixed size and evicts oldest. Cursors at or above the checkpoint can replay from the buffer alone, no history reload needed; this is the fast path for tab-switch / brief disconnects.

While idle, the SSE keepalive comment frame carries the bus's latest emitted sequence: `: seq=<latest>\n\n`. Clients can use this to confirm they are caught up without waiting for a real event.

## Event types

### `thinking`

Agent is processing. Includes a status message.

```json theme={null}
{"type": "thinking", "status": "Searching memory..."}
```

### `TEXT_MESSAGE_START`

Assistant text block started.

```json theme={null}
{"type": "TEXT_MESSAGE_START", "message_id": "msg_abc", "role": "assistant"}
```

### `TEXT_MESSAGE_CONTENT`

Streamed assistant text delta. Only sent when streaming is enabled with `?stream=true`.

```json theme={null}
{"type": "TEXT_MESSAGE_CONTENT", "message_id": "msg_abc", "delta": "Based"}
```

Deltas arrive in order by `seq`. Accumulate them by `message_id`.

### `TEXT_MESSAGE_END`

Assistant text block ended. Includes the cumulative content as a convenience.

```json theme={null}
{"type": "TEXT_MESSAGE_END", "message_id": "msg_abc", "content": "Based on your calendar..."}
```

### `TOOL_CALL_START`

Agent invoked a tool.

```json theme={null}
{
  "type": "TOOL_CALL_START",
  "tool_call_name": "search_facts",
  "tool_call_id": "tc_abc123",
  "depth": 0
}
```

### `TOOL_CALL_ARGS`

Tool arguments. ARDEN currently emits arguments atomically as a JSON string.

```json theme={null}
{"type": "TOOL_CALL_ARGS", "tool_call_id": "tc_abc123", "delta": "{\"query\":\"meeting notes\"}"}
```

### `TOOL_CALL_END`

Tool call input finished.

```json theme={null}
{"type": "TOOL_CALL_END", "tool_call_id": "tc_abc123"}
```

### `TOOL_CALL_RESULT`

Tool execution completed.

```json theme={null}
{
  "type": "TOOL_CALL_RESULT",
  "tool_call_id": "tc_abc123",
  "content": "Found 3 relevant facts...",
  "preview": "3 facts found",
  "duration_ms": 450
}
```

### `approval_needed`

Tool requires user approval before executing.

```json theme={null}
{
  "type": "approval_needed",
  "tool_id": "tc_abc123",
  "name": "send_email",
  "content_preview": "Send email to alice@example.com"
}
```

Respond with `POST /tools/result` to approve or reject.

### `RUN_STARTED`

Run started.

```json theme={null}
{
  "type": "RUN_STARTED",
  "session_id": "abc-123",
  "run_id": "run_abc"
}
```

### `RUN_FINISHED`

Execution complete. Includes token usage.

```json theme={null}
{
  "type": "RUN_FINISHED",
  "run_id": "run_abc",
  "usage": {
    "prompt": 1500,
    "completion": 200,
    "cache_read": 800,
    "cost": 0.012
  }
}
```

### `RUN_ERROR`

An error occurred.

```json theme={null}
{"type": "RUN_ERROR", "run_id": "run_abc", "message": "Rate limit exceeded", "recoverable": false}
```

### `background_task`

A background task changed state (started, completed, failed, or cancelled).

```json theme={null}
{"type": "background_task", "task_id": "bg_abc123", "command": "research(deep): research topic", "status": "completed"}
```

### `run_backgrounded`

A running agent was moved to background mode.

```json theme={null}
{"type": "run_backgrounded", "run_id": "run_abc"}
```

### `run_cancelled`

Worker acknowledged cancellation and reached the terminal cancelled state.

```json theme={null}
{"type": "run_cancelled", "run_id": "run_abc"}
```

Cancellation is asynchronous. `POST /cancel` returns `202` when the run exists and cancellation has been requested. The stream emits `run_cancelled` when the worker acknowledges cancellation and the run reaches its terminal cancelled state.

### `task_started`, `task_progress`, `task_finished`

Sub-agent task lifecycle. These events link child work back to the parent tool row.

```json theme={null}
{
  "type": "task_started",
  "run_id": "run_abc",
  "task_id": "call_research",
  "parent_tool_call_id": "call_research",
  "status": "running",
  "depth": 1
}
```

### `stream_reset`

The requested `after_seq` cursor falls below the server's checkpoint watermark (or is in the future). The client should reload session history and resume from the latest seq.

```json theme={null}
{"type": "stream_reset", "reason": "replay_gap"}
```

## Approval flow

When `approval_needed` is received:

1. Display the tool call to the user
2. Collect their decision (approve/reject)
3. Submit via `POST /tools/result`:

```bash theme={null}
curl -X POST http://localhost:6877/tools/result \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "run_id": "run_abc",
    "tool_id": "tc_abc123",
    "result": "Approved",
    "approved": true
  }'
```

The stream continues after approval.
