refactor(events): remove the agent/stream-chunk mirror of assistant/chunk

The loop recorded every model token delta as a durable `assistant/chunk`
session event AND emitted an identical live `agent/stream-chunk` Cordis event
one line later. Same StreamChunk, same turn/step; the emit added only the live
Agent handle, which the sole consumer discarded. This is the boundary-mirror
duplication the event-domain work removed for turn/step boundaries, applied to
the token stream — a follow-up the boundary RFC explicitly deferred.

The premise is settled: chunk persistence is authoritative (the proposal to
stop persisting chunks was rejected — replay/snapshots depend on it), so
`assistant/chunk` on `session/event` is the load-bearing token stream and
`agent/stream-chunk` is pure redundancy.

- Remove the `agent/stream-chunk` declaration + emit; drop the now-unused
  StreamChunk import from dsh-agent's types.
- Migrate `dsh-ui-stdio` (the only live consumer; ACP already reads
  assistant/chunk off session/event) to render assistant/chunk in its existing
  session/event listener. Consolidating to one listener also makes the
  inReasoning dim-SGR flag deterministic across chunk/boundary events (they no
  longer race across two listeners).
- Repoint the agent-loop tests (cancel/loop) and ui-stdio tests to the
  session/event assistant/chunk feed.
- New RFC (implemented/simplification/2026-07-02-remove-stream-chunk-mirror);
  amend the boundary RFC's retained-list entry to cross-link; update
  architecture, cookbook, event-domain-semantics, the ACP proposal, and the
  regenerated cordis catalog.

Snapshot goldens unchanged (ACP never used the mirror), confirming no
editor-facing transcript change.
This commit is contained in:
Tianyi Cui
2026-07-02 23:42:16 +08:00
parent 2a66b7c4e0
commit b84d4828a8
15 changed files with 116 additions and 89 deletions

View File

@@ -30,7 +30,7 @@ export function apply(ctx: Context) {
## A UI plugin
A UI plugin consumes `agent/stream-chunk` and session events for rendering, and drives input back in via `agent.send()` / `agent.steer()`.
A UI plugin renders from the `session/event` feed (the assistant token stream as `assistant/chunk`, plus turn/step boundaries and tool activity), and drives input back in via `agent.send()` / `agent.steer()`.
```ts
import type { Context } from 'cordis'
@@ -43,8 +43,10 @@ export const name = 'my-ui'
export const inject = ['agents']
export function apply(ctx: Context) {
ctx.on('agent/stream-chunk', (agent, turn, step, chunk) => {
if (chunk.type === 'text-delta') render(chunk.text)
ctx.on('session/event', (_session, event) => {
if (event.type === 'assistant/chunk' && event.data.chunk.type === 'text-delta') {
render(event.data.chunk.text)
}
})
onUserInput(text => ctx.agents.get(AgentId('main'))?.send([{ type: 'text', text }]))
}