> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zeus.agentspro.cn/llms.txt
> Use this file to discover all available pages before exploring further.

# Message Queue

> Zeus message queue — user message queueing, conversation rollback, event persistence and concurrency control

The Zeus message queue covers two layers: the **user-facing message queue** that lets users queue messages while the Agent is processing, and the **backend event persistence** system that ensures reliable delivery.

***

## User Message Queue

When the Agent is processing a response, users can continue typing and queue additional messages instead of waiting.

### Behavior

| Scenario                                      | Behavior                                                        |
| --------------------------------------------- | --------------------------------------------------------------- |
| Agent is processing + user sends              | Message is added to the queue (not sent immediately)            |
| Agent completes normally                      | Next queued message is auto-sent after 100 ms                   |
| Agent is stopped (truncated)                  | Queue does **not** auto-consume; user decides what to send next |
| User clicks **Send Now** (↑) on a queued item | Stops current generation (if active), then sends that message   |

### Queue UI

The queue panel appears above the chat input when messages are queued:

* **Edit** (pencil icon) — inline-edit the queued message content
* **Send Now** (↑ arrow icon) — stop current generation and send this message immediately
* **Remove** (trash icon) — delete from queue

### Truncated Context

When a response is stopped mid-stream, the partial AI content is **preserved** in the conversation history and used as context for subsequent messages. It is also **persisted to the database** so it survives page refresh.

***

## Conversation & File Rollback

Users can roll back to any previous conversation turn, similar to Cursor's fork model.

### Conversation Rollback

1. Hover over a user message → click the **Rollback** button (↺)
2. Messages after the rollback point are **dimmed** (40 % opacity), not deleted
3. A fork divider appears with a **Cancel Rollback** option
4. New messages are appended below the divider
5. Chat history sent to the backend only includes messages **up to** the fork point

### File Rollback

When the user rolls back, sandbox files modified after the fork point are restored to their earlier state:

```
handleRollback(forkMessageId)
  → Save current files as preRollbackFiles
  → Collect FileSnapshots for messages after forkMessageId
  → POST /api/sandbox/restore-files (write old versions back)
  → Update trajectoryStore.sandboxFiles
```

Cancel rollback reverses the process, restoring the latest file versions from `preRollbackFiles`.

***

## File Recovery on Refresh

Sandbox files are restored from **database events** — not just the live E2B sandbox — so files persist even after the sandbox expires.

```mermaid theme={null}
flowchart TD
    refresh["Page refresh"]
    events["await loadEventsFromDb"]
    rebuild["rebuildStateFromEvents extracts<br/>sandboxFiles from tool_call_result events"]
    sandbox{"Sandbox still alive?"}
    merge["Merge new sandbox files<br/>(don't overwrite event files)"]
    done["File tree ready"]
    skip["Use event files only"]

    refresh --> events --> rebuild --> sandbox
    sandbox -->|"Yes"| merge --> done
    sandbox -->|"No"| skip --> done
```

Content is **lazy-loaded**: when the user clicks a file tab whose content is empty, the frontend calls `GET /api/sandbox/read-file` to fetch it from the sandbox on demand.

***

## Event Persistence

### RealtimeEventSaver

`RealtimeEventSaver` is responsible for batch-persisting real-time SSE events to the database:

```mermaid theme={null}
flowchart TD
    events["SSE Events arrive"]
    buffer["Event buffer"]
    batch{"Batch threshold reached?"}
    write["Batch write to PostgreSQL"]
    retry{"Write successful?"}
    backoff["Exponential backoff retry"]
    fallback["Fallback: LocalStorage"]
    recover["Replay on next load"]

    events --> buffer --> batch
    batch -->|"3 events or 100ms"| write
    batch -->|"Not reached"| buffer
    write --> retry
    retry -->|"Success"| buffer
    retry -->|"Failure"| backoff
    backoff -->|"≤3 attempts"| write
    backoff -->|">3 attempts"| fallback
    fallback --> recover
```

### Configuration

| Setting        | Value               | Description                                         |
| -------------- | ------------------- | --------------------------------------------------- |
| Batch size     | 3 events            | Triggers a write when the buffer reaches this count |
| Batch interval | 100ms               | Flushes on a timer even if the batch is not full    |
| Retry count    | 3                   | Maximum number of retries                           |
| Retry strategy | Exponential backoff | 1s → 2s → 4s                                        |
| Fallback       | LocalStorage        | Backup storage after all retries are exhausted      |

***

## Message Batching

### Frontend Message Merging

The frontend merges rapid successive text updates to avoid excessive re-rendering:

| Strategy              | Description                                                                     |
| --------------------- | ------------------------------------------------------------------------------- |
| UI batch flush        | Batch updates at \~60fps, merging rapid successive tokens                       |
| Virtual scrolling     | Only renders message cards within the visible viewport                          |
| Selective persistence | Only persists `sessionId` and `messageIds`; message content is loaded on demand |

### Chat History Construction

The frontend loads the current session's message history from the Zustand Store, excludes the message currently being sent, and passes it to the backend. The backend converts it to LangChain message types, limiting to a maximum of **30 messages**.

***

## Concurrency & Isolation

```mermaid theme={null}
graph TD
    subgraph Session1["Session A"]
        s1_agent["Agent"]
        s1_checkpoint["Checkpoint"]
        s1_cache["Context Cache"]
    end

    subgraph Session2["Session B"]
        s2_agent["Agent"]
        s2_checkpoint["Checkpoint"]
        s2_cache["Context Cache"]
    end

    subgraph UserSpace["User Workspace"]
        workspace["CloudDriveBackend<br/>Isolated by user_id"]
    end

    Session1 --> UserSpace
    Session2 --> UserSpace
```

| Isolation Dimension | Mechanism    | Description                                                                              |
| ------------------- | ------------ | ---------------------------------------------------------------------------------------- |
| Session             | `thread_id`  | Each session has its own independent Checkpointer state                                  |
| Context             | `session_id` | Context Cache is isolated by session\_id; resume only restores the corresponding session |
| Tool execution      | LangGraph    | Tools execute serially within the same session, never concurrently                       |
| Workspace           | `user_id`    | User file systems are fully isolated by user\_id                                         |

***

## Session Recovery

The system supports recovery after session interruption:

### Save Triggers

* After a tool call completes
* After a message is sent
* During HITL interruption (via Checkpointer)

### Recovery Flow

```mermaid theme={null}
flowchart TD
    load["Page load"]
    check{"Saved session state exists?"}
    restore["Restore message list + pending tool calls"]
    local{"LocalStorage backup exists?"}
    sync["Replay events to server"]
    ready["Session ready"]
    fresh["New session"]

    load --> check
    check -->|"Yes"| restore --> local
    check -->|"No"| fresh
    local -->|"Yes"| sync --> ready
    local -->|"No"| ready
```

***

## Related Docs

<CardGroup cols={2}>
  <Card title="Messages" icon="comments" href="/en/ai-backend/messages/Messages">
    Complete message flow, request parameters, and state management
  </Card>

  <Card title="Retry Policy" icon="rotate" href="/en/ai-backend/messages/Retry-Policy">
    Error handling, retry strategies, and fallback mechanisms
  </Card>
</CardGroup>
