Session activity streams
While an agent works, Nexus records what it is doing — reply text, reasoning, tool calls, plans —
as ordered agent.update rows. That stream is what makes a session watchable live and replayable
afterwards.
The daemon is a thin pass-through at the stream boundary. It translates the harness’s own session updates and forwards them in order; it does not reinterpret them.
flowchart LR harness[Harness session update] --> engine[AcpEngine translate] engine --> service[Agent service] service --> stream[(mem.stream_events agent.update)] stream --> materialized[(agent_session_* history)] stream --> gateway[Gateway session history]
Event kinds
Section titled “Event kinds”There are seven. Five come straight from the harness stream; two are produced by the daemon, because no harness emits them.
From the harness stream
Section titled “From the harness stream”agent.update.kind |
Carries |
|---|---|
text |
Assistant reply chunks |
thinking |
Reasoning chunks |
tool_call |
Tool call start and update payloads, merged by id by consumers |
plan |
Plan entries |
commands |
The harness’s own slash commands, name and description only |
Anything else the harness sends — mode, config, session-info, and usage bookkeeping — is dropped rather than forwarded. It keeps the stream alive but carries no session content.
Daemon-originated
Section titled “Daemon-originated”agent.update.kind |
Carries |
|---|---|
user_input |
A user-role turn the session received, so an attached terminal and a browser view show the same thing |
turn_end |
The turn is complete. No content; consumers use it to close the streaming row |
turn_end is emitted on every turn, success or failure, so a viewer never streams forever waiting
on a turn that already errored.
Reading the stream
Section titled “Reading the stream”One endpoint serves the stream, in three views:
GET /api/v1/agent-sessions/<session-id>/events?view=nexus|terminalview=nexus returns the normalized Nexus events this page describes; view=terminal returns the
raw terminal bytes. Both are
server-sent event streams. Keep the last cursor you accepted and reconnect with after=<cursor> to
resume inside the bounded replay window; if the server answers with a resync or reports a gap, treat
it as a presentation discontinuity rather than as lost history.
Storage
Section titled “Storage”The raw lane is mem.stream_events, a volatile attached schema rather than a migrated table: it is
boot-scoped, and rows are evicted at turn end once the materializer has folded the turn. The daemon
folds raw rows into compact agent_session_turns and agent_session_messages for durable replay.
The raw stream stays the live and debug source; the materialized rows are the stable history
projection.
Where it lives
Section titled “Where it lives”| Piece | Path |
|---|---|
| Contract event | core/crates/nexus-contracts/src/events.rs |
| Pure transform | core/crates/nexus-acp-stream/src/lib.rs |
| Engine buffering | core/crates/nexus-agent/src/adapter/engine.rs |
| Service write | core/crates/nexus-agent/src/service.rs |
Raw to materialized, and the mem.stream_events eviction |
core/crates/nexus/src/daemon/agent_session_materializer.rs |
agent_session_turns table |
core/migrations/0001_init.sql |
agent_session_messages table |
core/migrations/0001_init.sql |
- Adding a harness for wiring a new harness into this stream
- Debugging for reading session state on a live install