Watch
0
0
Fork
You've already forked hyperhive
0

swarm: keep an agent's terminal rows and replay them on attach

swarm-controller now creates `term-main-<agent>` for every live agent, in
the same one-minute pass and with the same config style as
`term-sub-<agent>` (#4897): subjects `$SWARM.term.<agent>` only, max_age
24h, max_bytes 64 MiB, discard Old, max_message_size from the queue's
max_payload. An existing stream is opened as it is. The agent keeps its
plain publish on `$SWARM.term.<agent>` and gets no JetStream subject.

`GET /api/agents/{name}/term/stream` creates an ephemeral push consumer on
that stream starting 100 rows back, so a swarm-ui terminal opens with
recent history and then follows new rows, in order, from one
subscription. Each SSE event carries the row's stream sequence as its id,
and a reconnect's Last-Event-ID resumes after it. Without the stream the
route falls back to the live core subscription it used before.

The stream is `term-main-<agent>`, not `term-<agent>`: an agent may be
named `sub-x`, whose `term-<agent>` would be agent `x`'s subagent stream.
Its one literal subject cannot match `$SWARM.term.<agent>.sub.>`, which
needs more tokens, so the two streams never overlap.

The reader gains `$JS.API.CONSUMER.CREATE.*.*.$SWARM.term.*`, the
extended create form whose last tokens are the consumer's filter. Checked
against nats-server 2.14.4, the trailing `*` also admits a literal `*` or
`>` filter, so a consumer under it reaches any terminal row, main or
subagent; those are rows the reader already subscribes to and reads with
`STREAM.MSG.GET.*`.

Closes #4826
This commit is contained in:
atlas 2026-10-11 12:35:31 +02:00
commit ae9ca4331e
12 changed files with 533 additions and 38 deletions

View file

@ -30,8 +30,9 @@ terminal in the same preview, and **expand** opens it in its own tab, as it
does for the agent. The list refreshes every 10 seconds, so a subagent the
agent spawns shows up once it writes output.
A preview shows rows published while it's open. A subagent terminal has no
turn-state badges.
An agent's terminal opens with its last 100 rows from the past 24 hours, then
follows new ones; a reconnect picks up after the last row it showed. A subagent
terminal shows rows published while it's open, and has no turn-state badges.
### Scheduled prompts
@ -102,6 +103,21 @@ store identity, or no queue address, publishes no subagent terminals.
</details>
<details><summary>Where an agent's terminal history comes from</summary>
The harness publishes the agent's terminal rows on `$SWARM.term.<agent>`, into
a stream named `term-main-<agent>` that swarm-controller creates for every
declared agent, with the same 24 hours or 64 MiB as the subagent stream. That
stream holds this one subject, and the subagent stream holds only subjects
below `$SWARM.term.<agent>.sub`, so they never overlap.
`GET /api/agents/<name>/term/stream` creates a short-lived consumer on it
that starts 100 rows back, so the SSE stream sends those rows and then each
new one. Each event's `id` is the row's stream sequence, and a request with
`Last-Event-ID` resumes after it. Until the stream exists, the route sends
live rows only.
</details>
### Inference settings
The agent's detail panel shows its model and effort under **inference**, each