compaction: the pure core — cut walk, marker, and the model-facing projection (round 14 slice 1)

- core/compaction.ts: compactionCutIndex (backwards ~20k-token walk, NEVER
  separates a tool result from its call — the cut extends to the call's
  assistant message; a pending pose always survives), estimateTokens
  (chars/4, pi's method), newCompactionMarker (header + summary; details
  carry firstKeptMessageId/tokensBefore/model/at), serializeForSummary
  (labeled text, tool results truncated ~2k), planTreeToText (verbatim
  tree with transcript-derived statuses), buildCompactionPrompt (the four
  ruled sections: learner understanding + evolution, teaching arc, plan
  tree verbatim, current moment)
- toLlmMessages honors the cut: the ACTIVE (newest) marker renders ONCE
  as the head; everything before firstKeptMessageId drops; corrupt cut
  degrades honestly (everything renders, never throw)
- constants: KEEP_RECENT 20k, RESERVE 16k, DEFAULT_THRESHOLD 150k
- 16 test pins
This commit is contained in:
amosblomqvist
2026-10-05 22:06:14 +03:00
parent 0c9f82e027
commit 7e9597d969
5 changed files with 577 additions and 4 deletions
+10
View File
@@ -197,6 +197,16 @@ export const THINKING_LABEL = "Your thinking";
export const CONCLUDE_ACK_TEXT =
"Problem concluded — the composer is free; pose the next problem or wrap up.";
/** The compaction marker's model-facing header (owner round 14,
* 2026-10-05). The marker's content is this header + the summary — the
* single text the provider sees in place of the dropped span. Wording
* law: it must tell the model (a) a cut happened and is routine, (b) the
* summary replaces everything before it, (c) what follows is verbatim
* recent transcript — so the model neither re-asks covered ground nor
* distrusts the seam. */
export const COMPACTED_HISTORY_HEADER =
"[SESSION HISTORY COMPACTED] The transcript before this point was summarized to fit the context window; the summary below replaces it. Everything after this message is the verbatim recent transcript.";
export interface PlanBlockData {
/** Only "full" survives (the 2026-09-11 pivot): the plan renders IN