What happened
The renderer's LiveTurnProjection survives a Runtime Host resubscription, but the client projector (RuntimeHostSessionProjector) is rebuilt and reseeds the turn: seedActive sends the in-flight text from offset 0, and seedTerminal / seedStoredTerminal send the terminal completions. The renderer folds these events into its old state instead of replacing it.
After #5658, a completion that is not marked replaced is sliced at the source offset where earlier steering slices of the same step stopped. A rebuilt projector cannot tell whether the Host replaced that step's text before the rebuild, so a reseeded completion never carries replaced.
- If the Host replaced the text, the live slice shows the wrong suffix or an empty string.
- Marking every reseed
replaced does not work either: in the common case it would duplicate the pre-steering text.
The persisted transcript takes over at handoff and corrects the display. If the transcript read fails, the wrong text stays.
How to reproduce
- In one assistant step, stream thinking
AAAA.
- Send a steering message, then stream
BBBB in the same step.
- The Host completes the step with
ABC. It does not extend the streamed prefix, so the Host sends a reset.
- Resubscribe before the renderer consumes the terminal completion.
The slices show AAAA / "" instead of AAAA / ABC. This was reproduced with the built @maka/ui and @maka/runtime-host modules by chaining live events into seedStoredTerminal output.
Proposed fix
Make host_observation_seed authoritative for the turns it covers: the renderer rebuilds each seeded turn's live projection from the seed events instead of merging them into the surviving state. Offset and replacement facts then always come from one projector generation. Once that holds, the known limitation noted in #5658 can be removed.
Environment
main after #5658. Code paths: apps/desktop/src/main/runtime-host-session-observer.ts (#seedTarget, terminal reseed), apps/desktop/src/preload/preload.ts (seed dispatch), packages/ui/src/live-turn-projection.ts (sliceStart).
What happened
The renderer's
LiveTurnProjectionsurvives a Runtime Host resubscription, but the client projector (RuntimeHostSessionProjector) is rebuilt and reseeds the turn:seedActivesends the in-flight text from offset 0, andseedTerminal/seedStoredTerminalsend the terminal completions. The renderer folds these events into its old state instead of replacing it.After #5658, a completion that is not marked
replacedis sliced at the source offset where earlier steering slices of the same step stopped. A rebuilt projector cannot tell whether the Host replaced that step's text before the rebuild, so a reseeded completion never carriesreplaced.replaceddoes not work either: in the common case it would duplicate the pre-steering text.The persisted transcript takes over at handoff and corrects the display. If the transcript read fails, the wrong text stays.
How to reproduce
AAAA.BBBBin the same step.ABC. It does not extend the streamed prefix, so the Host sends areset.The slices show
AAAA / ""instead ofAAAA / ABC. This was reproduced with the built@maka/uiand@maka/runtime-hostmodules by chaining live events intoseedStoredTerminaloutput.Proposed fix
Make
host_observation_seedauthoritative for the turns it covers: the renderer rebuilds each seeded turn's live projection from the seed events instead of merging them into the surviving state. Offset and replacement facts then always come from one projector generation. Once that holds, the known limitation noted in #5658 can be removed.Environment
main after #5658. Code paths:
apps/desktop/src/main/runtime-host-session-observer.ts(#seedTarget, terminal reseed),apps/desktop/src/preload/preload.ts(seed dispatch),packages/ui/src/live-turn-projection.ts(sliceStart).