fix(tui,host): pin replayed compaction and correct projection wording
Review follow-ups on the append-origin transcript projection.
The live/replay equivalence claim was stated unconditionally but does not
cover `tool/call`: only replay re-derives call pairing, because a call
event carries no `surfaceOp` of its own and inherits transcript
membership from the `assistant/message` that advertised it — which the
live listener has necessarily just rendered. Narrow the claim in the TUI
README and Agent Note, and record at `rebuildTranscript` why the filter
is replay-only rather than a missing live branch.
Add `surface-replayed-compaction`: the three existing fixtures all come
from the live path, leaving the resume case the bug report leads with
pinned only by a unit test. The new checkpoint mounts with the
replacement already stored and records byte-identical to
`surface-after-compaction-wide`, so the two fixtures now pin the
equivalence they assert. The shared fixture appends move into
`appendPreCompactionLog` / `appendCompactionCheckpoint`.
`MESSAGE_TYPES` is not "human message event types" — it includes
`assistant/message`. Say what the code distinguishes (append-origin
conversation messages vs. model-only replacement copies) at the const,
the `paginate` and `session.history` JSDoc, the apiproxy README, and the
Agent Note.
Also: spell the replace shape as `Extract<SurfaceOp, { op: 'replace' }>`
for symmetry with the module's two other uses; document why
`isCompactCheckpoint` keeps a replacement check that is redundant at both
call sites; say that Ctrl+R toggles reasoning, which rebuilds the
transcript; and qualify "the sole source of derived history" as derived
*model* history now that the transcript is the other projection.
This commit is contained in:
@@ -836,6 +836,12 @@ export function createTuiChat(
|
||||
* surface shadows compacted ranges, so it is not the source here: every
|
||||
* append-origin message stays rendered, and a replacement contributes at most
|
||||
* the compaction marker at its own log position.
|
||||
*
|
||||
* The `tool/call` pairing check has no live counterpart, because only replay
|
||||
* can meet an orphan: `tool/call` carries no `surfaceOp` of its own, so it
|
||||
* inherits transcript membership from the `assistant/message` that advertised
|
||||
* it, which the live listener has necessarily just rendered. A loaded log is a
|
||||
* replay boundary, so the pairing is re-derived here instead of assumed.
|
||||
*/
|
||||
const rebuildTranscript = (populateHistory: boolean): void => {
|
||||
chat.clear()
|
||||
|
||||
Reference in New Issue
Block a user