mixdog 0.9.153 → 0.9.154

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. package/package.json +5 -1
  2. package/src/rules/shared/60-verification.md +2 -0
  3. package/src/runtime/agent/orchestrator/session/agent-loop.mjs +0 -1
  4. package/src/runtime/agent/orchestrator/session/compact/handoff.mjs +0 -22
  5. package/src/runtime/agent/orchestrator/session/compact/messages.mjs +2 -2
  6. package/src/runtime/agent/orchestrator/session/compact/runner.mjs +9 -22
  7. package/src/runtime/agent/orchestrator/session/compact/summary.mjs +28 -269
  8. package/src/runtime/agent/orchestrator/session/compact.mjs +0 -6
  9. package/src/runtime/agent/orchestrator/session/loop/recall-fasttrack.mjs +80 -18
  10. package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +5 -66
  11. package/src/runtime/computer-bridge/client.mjs +85 -32
  12. package/src/session-runtime/lifecycle-api.mjs +10 -1
  13. package/src/session-runtime/runtime-core.mjs +6 -5
  14. package/src/standalone/daemon.mjs +17 -0
  15. package/src/standalone/session-runtime-worker.mjs +4 -0
  16. package/scripts/generate-voice-runtime-manifest.test.mjs +0 -135
  17. package/scripts/native-binary-arch.test.mjs +0 -111
  18. package/scripts/patch-replay.test.mjs +0 -94
  19. package/src/headless-exec.test.mjs +0 -539
  20. package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch.test.mjs +0 -378
  21. package/src/runtime/agent/orchestrator/agent-trace-timing.test.mjs +0 -57
  22. package/src/runtime/agent/orchestrator/cache-break-trace.test.mjs +0 -115
  23. package/src/runtime/agent/orchestrator/context/collect-skills.test.mjs +0 -153
  24. package/src/runtime/agent/orchestrator/mcp/cancellation.test.mjs +0 -139
  25. package/src/runtime/agent/orchestrator/mcp/features.test.mjs +0 -66
  26. package/src/runtime/agent/orchestrator/mcp/security.test.mjs +0 -80
  27. package/src/runtime/agent/orchestrator/providers/admission-scheduler-metrics.test.mjs +0 -47
  28. package/src/runtime/agent/orchestrator/providers/anthropic-fast-mode.test.mjs +0 -90
  29. package/src/runtime/agent/orchestrator/providers/anthropic-server-fallback.test.mjs +0 -215
  30. package/src/runtime/agent/orchestrator/providers/antigravity-oauth.test.mjs +0 -165
  31. package/src/runtime/agent/orchestrator/providers/media-parity.test.mjs +0 -201
  32. package/src/runtime/agent/orchestrator/providers/openai-codex-identity.test.mjs +0 -224
  33. package/src/runtime/agent/orchestrator/providers/openai-codex-model.test.mjs +0 -24
  34. package/src/runtime/agent/orchestrator/providers/openai-ws-delta-parity.test.mjs +0 -306
  35. package/src/runtime/agent/orchestrator/providers/provider-replay.test.mjs +0 -288
  36. package/src/runtime/agent/orchestrator/providers/sse-framing.test.mjs +0 -719
  37. package/src/runtime/agent/orchestrator/session/agent-loop.test.mjs +0 -222
  38. package/src/runtime/agent/orchestrator/session/browser-snapshot-supersession.test.mjs +0 -83
  39. package/src/runtime/agent/orchestrator/session/cache/prefetch-cache.test.mjs +0 -40
  40. package/src/runtime/agent/orchestrator/session/compact-policy.test.mjs +0 -288
  41. package/src/runtime/agent/orchestrator/session/compaction-read-reset.test.mjs +0 -192
  42. package/src/runtime/agent/orchestrator/session/context-usage-restart.test.mjs +0 -72
  43. package/src/runtime/agent/orchestrator/session/eager-dispatch.test.mjs +0 -189
  44. package/src/runtime/agent/orchestrator/session/evidence-union.test.mjs +0 -228
  45. package/src/runtime/agent/orchestrator/session/image-strip-recovery.test.mjs +0 -264
  46. package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.test.mjs +0 -28
  47. package/src/runtime/agent/orchestrator/session/lossless-tool-output.test.mjs +0 -125
  48. package/src/runtime/agent/orchestrator/session/manager/ask-session.test.mjs +0 -46
  49. package/src/runtime/agent/orchestrator/session/manager/pending-messages-persistence.test.mjs +0 -325
  50. package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.test.mjs +0 -132
  51. package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.test.mjs +0 -593
  52. package/src/runtime/agent/orchestrator/session/provider-prefix-guard.test.mjs +0 -117
  53. package/src/runtime/agent/orchestrator/session/reduction-metrics.test.mjs +0 -87
  54. package/src/runtime/agent/orchestrator/session/store/serialize.test.mjs +0 -60
  55. package/src/runtime/agent/orchestrator/session/store-live-publication.test.mjs +0 -83
  56. package/src/runtime/agent/orchestrator/session/store-summary-reader.test.mjs +0 -647
  57. package/src/runtime/agent/orchestrator/session/store-summary-visibility.test.mjs +0 -219
  58. package/src/runtime/agent/orchestrator/session/task-wait-control.test.mjs +0 -78
  59. package/src/runtime/agent/orchestrator/tools/builtin/absence-absorption.test.mjs +0 -43
  60. package/src/runtime/agent/orchestrator/tools/builtin/absolute-glob-expand.test.mjs +0 -63
  61. package/src/runtime/agent/orchestrator/tools/builtin/bash-tool-cwd-env.test.mjs +0 -14
  62. package/src/runtime/agent/orchestrator/tools/builtin/edit-encoding-eol.test.mjs +0 -224
  63. package/src/runtime/agent/orchestrator/tools/builtin/edit-sequential-occupation.test.mjs +0 -224
  64. package/src/runtime/agent/orchestrator/tools/builtin/enoent-outside-project.test.mjs +0 -56
  65. package/src/runtime/agent/orchestrator/tools/builtin/find-search-budget.test.mjs +0 -103
  66. package/src/runtime/agent/orchestrator/tools/builtin/git-command-policy.test.mjs +0 -30
  67. package/src/runtime/agent/orchestrator/tools/builtin/git-command-tool.test.mjs +0 -390
  68. package/src/runtime/agent/orchestrator/tools/builtin/git-repo-rw-lock.test.mjs +0 -83
  69. package/src/runtime/agent/orchestrator/tools/builtin/grep-output-budget.test.mjs +0 -31
  70. package/src/runtime/agent/orchestrator/tools/builtin/grep-single-file-rescue.test.mjs +0 -106
  71. package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.test.mjs +0 -102
  72. package/src/runtime/agent/orchestrator/tools/builtin/list-tool-integrity.test.mjs +0 -152
  73. package/src/runtime/agent/orchestrator/tools/builtin/native-search-health.test.mjs +0 -24
  74. package/src/runtime/agent/orchestrator/tools/builtin/native-search-transport.test.mjs +0 -24
  75. package/src/runtime/agent/orchestrator/tools/builtin/noise-dir-visibility.test.mjs +0 -69
  76. package/src/runtime/agent/orchestrator/tools/builtin/read-glob-survey.test.mjs +0 -71
  77. package/src/runtime/agent/orchestrator/tools/builtin/runtime-capabilities.test.mjs +0 -56
  78. package/src/runtime/agent/orchestrator/tools/builtin/search-builders.test.mjs +0 -16
  79. package/src/runtime/agent/orchestrator/tools/builtin/search-glob-top-k.test.mjs +0 -39
  80. package/src/runtime/agent/orchestrator/tools/builtin/write-symlink.test.mjs +0 -153
  81. package/src/runtime/agent/orchestrator/tools/code-graph/aggregate-anchor-relocation.test.mjs +0 -55
  82. package/src/runtime/agent/orchestrator/tools/code-graph/dispatch.test.mjs +0 -88
  83. package/src/runtime/agent/orchestrator/tools/code-graph/loose-file-target.test.mjs +0 -72
  84. package/src/runtime/agent/orchestrator/tools/code-graph/memory-cache.test.mjs +0 -54
  85. package/src/runtime/agent/orchestrator/tools/code-graph/search-references.test.mjs +0 -20
  86. package/src/runtime/agent/orchestrator/tools/code-graph/symbol-search-scope.test.mjs +0 -55
  87. package/src/runtime/agent/orchestrator/tools/code-graph/text-span-mask.test.mjs +0 -268
  88. package/src/runtime/agent/orchestrator/tools/env-scrub.test.mjs +0 -57
  89. package/src/runtime/agent/orchestrator/tools/graph-binary-fetcher.test.mjs +0 -19
  90. package/src/runtime/agent/orchestrator/tools/lib/native-spawn-client.test.mjs +0 -104
  91. package/src/runtime/agent/orchestrator/tools/patch/engine-contract-gate.test.mjs +0 -661
  92. package/src/runtime/agent/orchestrator/tools/patch/patch-codec-eol.test.mjs +0 -552
  93. package/src/runtime/agent/orchestrator/tools/patch/patch-symlink.test.mjs +0 -141
  94. package/src/runtime/agent/orchestrator/tools/patch/v4a-pure-move.test.mjs +0 -57
  95. package/src/runtime/agent/orchestrator/tools/patch/v4a-section-coalesce.test.mjs +0 -81
  96. package/src/runtime/agent/orchestrator/tools/spawn-binary-fetcher.test.mjs +0 -52
  97. package/src/runtime/attachments/store.test.mjs +0 -209
  98. package/src/runtime/bridge-clients.test.mjs +0 -827
  99. package/src/runtime/channels/lib/voice-runtime-fetcher.test.mjs +0 -17
  100. package/src/runtime/channels/lib/webhook/deliveries.test.mjs +0 -18
  101. package/src/runtime/channels/lib/webhook/relay-tunnel.test.mjs +0 -68
  102. package/src/runtime/media/adapters/codex-image.test.mjs +0 -22
  103. package/src/runtime/media/download.test.mjs +0 -52
  104. package/src/runtime/media/renditions.test.mjs +0 -99
  105. package/src/runtime/media/store.test.mjs +0 -159
  106. package/src/runtime/memory/lib/archive-security.test.mjs +0 -128
  107. package/src/runtime/memory/lib/embedding-model-config.test.mjs +0 -33
  108. package/src/runtime/memory/lib/http-wire.test.mjs +0 -15
  109. package/src/runtime/memory/lib/memory-cycle-packets.test.mjs +0 -49
  110. package/src/runtime/memory/lib/memory-cycle2-shared.test.mjs +0 -78
  111. package/src/runtime/memory/lib/memory-embedding-migration.test.mjs +0 -50
  112. package/src/runtime/memory/lib/pg/process.test.mjs +0 -36
  113. package/src/runtime/memory/lib/trace-store.test.mjs +0 -57
  114. package/src/runtime/memory/lib/transcript-ingest.test.mjs +0 -52
  115. package/src/runtime/office/office-assurance.test.mjs +0 -371
  116. package/src/runtime/office/office-live-runtime.test.mjs +0 -819
  117. package/src/runtime/office/office-runtime.test.mjs +0 -2070
  118. package/src/runtime/shared/background-tasks.test.mjs +0 -78
  119. package/src/runtime/shared/bounded-download.test.mjs +0 -41
  120. package/src/runtime/shared/channel-notification-routing.test.mjs +0 -25
  121. package/src/runtime/shared/child-spawn-remote.test.mjs +0 -124
  122. package/src/runtime/shared/remote-intent.test.mjs +0 -40
  123. package/src/runtime/shared/resource-admission.test.mjs +0 -43
  124. package/src/runtime/shared/runtime-root.test.mjs +0 -34
  125. package/src/runtime/shared/schedule-time.test.mjs +0 -29
  126. package/src/runtime/shared/session-runtime-health.test.mjs +0 -83
  127. package/src/runtime/shared/skill-document.test.mjs +0 -81
  128. package/src/runtime/shared/tool-surface.test.mjs +0 -87
  129. package/src/runtime/shared/update-checker.test.mjs +0 -33
  130. package/src/runtime/shared/user-cwd.test.mjs +0 -43
  131. package/src/runtime/shared/webhook-session-run.test.mjs +0 -14
  132. package/src/session-runtime/agent-disable.test.mjs +0 -142
  133. package/src/session-runtime/cwd-plugins.test.mjs +0 -75
  134. package/src/session-runtime/cwd-tool-routing.test.mjs +0 -61
  135. package/src/session-runtime/deferred-tool-delta.test.mjs +0 -40
  136. package/src/session-runtime/global-extensions.test.mjs +0 -28
  137. package/src/session-runtime/global-settings-session-identity.test.mjs +0 -76
  138. package/src/session-runtime/goal-runtime.test.mjs +0 -645
  139. package/src/session-runtime/lifecycle-api.test.mjs +0 -183
  140. package/src/session-runtime/model-settings-persist.test.mjs +0 -105
  141. package/src/session-runtime/notification-bus.test.mjs +0 -148
  142. package/src/session-runtime/plugin-mcp-standard.test.mjs +0 -177
  143. package/src/session-runtime/prewarm.test.mjs +0 -52
  144. package/src/session-runtime/provider-request-snapshot.test.mjs +0 -59
  145. package/src/session-runtime/resource-api-global.test.mjs +0 -109
  146. package/src/session-runtime/session-lifecycle.test.mjs +0 -125
  147. package/src/session-runtime/session-title.test.mjs +0 -36
  148. package/src/session-runtime/skills-api.test.mjs +0 -99
  149. package/src/session-runtime/tool-policy-surface.test.mjs +0 -385
  150. package/src/standalone/agent-tool/helpers.test.mjs +0 -62
  151. package/src/standalone/agent-tool/notify.test.mjs +0 -37
  152. package/src/standalone/agent-tool/spawn-flow.test.mjs +0 -104
  153. package/src/standalone/agent-tool/worker-index.test.mjs +0 -132
  154. package/src/standalone/channel-restart.test.mjs +0 -145
  155. package/src/standalone/channel-session-router.test.mjs +0 -37
  156. package/src/standalone/channel-worker-heartbeat.test.mjs +0 -30
  157. package/src/standalone/hook-bus/handlers.test.mjs +0 -88
  158. package/src/standalone/plugin-admin.test.mjs +0 -173
  159. package/src/standalone/session-runtime-agent-control-client.test.mjs +0 -71
  160. package/src/standalone/session-runtime-dispatch-cancel.test.mjs +0 -139
  161. package/src/standalone/session-runtime-host-factory.test.mjs +0 -31
  162. package/src/standalone/session-runtime-host-health.test.mjs +0 -160
  163. package/src/standalone/session-runtime-inline-host.test.mjs +0 -385
  164. package/src/standalone/session-runtime-provider-cooldown.test.mjs +0 -80
  165. package/src/standalone/session-runtime-shard-host.test.mjs +0 -642
  166. package/src/standalone/session-runtime-shard-router.test.mjs +0 -101
  167. package/src/standalone/session-service-agent-tree.test.mjs +0 -984
  168. package/src/standalone/session-service-goal-recovery.test.mjs +0 -177
  169. package/src/tui/app/live-spinner-visibility.test.mjs +0 -44
  170. package/src/tui/app/panel-epoch.test.mjs +0 -1009
  171. package/src/tui/app/panel-handoff.test.mjs +0 -311
  172. package/src/tui/app/prompt-submit.test.mjs +0 -206
  173. package/src/tui/session/agent-message-source.test.mjs +0 -37
  174. package/src/tui/session/completion-card-restore.test.mjs +0 -161
  175. package/src/tui/session/goal-continuation.test.mjs +0 -203
  176. package/src/tui/session/oauth-flows.test.mjs +0 -134
  177. package/src/tui/session/queue-helpers.test.mjs +0 -46
  178. package/src/tui/session/session-action-surface.test.mjs +0 -190
  179. package/src/tui/session/task-wait-submit.test.mjs +0 -80
  180. package/src/tui/session/tool-result-status.test.mjs +0 -131
  181. package/src/tui/session/tui-steering-persist.test.mjs +0 -104
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mixdog",
3
- "version": "0.9.153",
3
+ "version": "0.9.154",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Standalone mixdog coding-agent CLI/TUI workspace.",
@@ -31,6 +31,7 @@
31
31
  "!scripts/bench/",
32
32
  "!scripts/recall-bench-*.txt",
33
33
  "!scripts/*-test.mjs",
34
+ "!scripts/*.test.mjs",
34
35
  "!scripts/*-smoke.mjs",
35
36
  "!scripts/smoke-loop*.mjs",
36
37
  "!scripts/*-bench.mjs",
@@ -40,6 +41,8 @@
40
41
  "!scripts/*.jsx",
41
42
  "src/",
42
43
  "!src/tui/dev",
44
+ "!src/**/*.test.mjs",
45
+ "!src/**/*.test.jsx",
43
46
  "vendor/"
44
47
  ],
45
48
  "scripts": {
@@ -68,6 +71,7 @@
68
71
  "test:spec-advisory": "node scripts/advisory-spec-test.mjs && npm run test:spec-advisory --prefix apps/desktop",
69
72
  "test:session-transport": "node --test scripts/session-transport-test.mjs scripts/daemon-bootstrap-test.mjs src/runtime/shared/child-spawn-remote.test.mjs src/standalone/session-runtime-agent-control-client.test.mjs src/standalone/session-runtime-dispatch-cancel.test.mjs src/standalone/session-runtime-host-factory.test.mjs src/standalone/session-runtime-inline-host.test.mjs src/standalone/session-runtime-provider-cooldown.test.mjs src/standalone/session-runtime-shard-host.test.mjs src/standalone/session-runtime-shard-router.test.mjs",
70
73
  "test:session": "node --test scripts/runtime-turn-contract-test.mjs scripts/session-save-fault-store-test.mjs scripts/turn-review-revert-test.mjs src/runtime/shared/tool-surface.test.mjs src/runtime/bridge-clients.test.mjs",
74
+ "test:quick": "npm run test:session && npm run test:session-transport && npm run test:desktop-main --prefix apps/desktop",
71
75
  "test:office": "node --test src/runtime/office/office-runtime.test.mjs src/runtime/office/office-assurance.test.mjs && npm run test:office-approval --prefix apps/desktop",
72
76
  "test:office:live": "node scripts/run-office-live-tests.mjs",
73
77
  "test:media": "node --test src/runtime/media/store.test.mjs src/runtime/media/renditions.test.mjs src/runtime/media/adapters/codex-image.test.mjs",
@@ -9,6 +9,8 @@
9
9
  buildability invariants. Treat mutable behavior, UX, exact text, snapshots,
10
10
  and implementation shape as advisory specifications; update them when the
11
11
  requested behavior changes instead of preserving obsolete behavior.
12
+ - A new test asserts observable behavior, never source text or implementation
13
+ shape, and never re-asserts a contract another test already owns.
12
14
  - A check runs at the strictness the task requires; never raise a tool's own
13
15
  severity beyond it.
14
16
  - If verification fails, collect all failures, leave Verification, complete all
@@ -27,7 +27,6 @@ import {
27
27
  _intraTurnSig,
28
28
  } from './loop/tool-classify.mjs';
29
29
  import { preDispatchDenyForSession } from './loop/pre-dispatch-deny.mjs';
30
- import { runRecallFastTrackCompact } from './loop/recall-fasttrack.mjs';
31
30
  import { executeTool, _scopedCacheOutcomeForCall, resolveLiveToolCwd } from './loop/tool-exec.mjs';
32
31
 
33
32
  // classifyResultKind is imported from result-classification.mjs at the top of
@@ -239,28 +239,6 @@ export function collectWorkingFileGroups(messages, cap = Number.POSITIVE_INFINIT
239
239
  }, prior, limit, cwd);
240
240
  }
241
241
 
242
- export function collectWorkingFiles(messages, cap = Number.POSITIVE_INFINITY, options = {}) {
243
- const groups = collectWorkingFileGroups(messages, cap, options);
244
- return [...groups.modified, ...groups.referenced].map((entry) => entry.path);
245
- }
246
-
247
- export function stripWorkingFileSections(text) {
248
- const out = [];
249
- let skipping = false;
250
- for (const raw of String(text || '').split('\n')) {
251
- const line = raw.trim();
252
- if (line === '## Working files') {
253
- skipping = true;
254
- continue;
255
- }
256
- if (skipping && (/^##\s+/.test(line) || /^<\/?prior-compacted-context>$/.test(line))) {
257
- skipping = false;
258
- }
259
- if (!skipping) out.push(raw);
260
- }
261
- return out.join('\n').replace(/\n{3,}/g, '\n\n');
262
- }
263
-
264
242
  function indexToolResults(messages) {
265
243
  const map = new Map();
266
244
  for (const m of messages || []) {
@@ -43,8 +43,8 @@ export function isProtectedContextUserMessage(m) {
43
43
  // content prefix (the `<skill>` envelope from buildSkillResultEnvelope) so the
44
44
  // check survives even if the synthetic `meta` field is dropped during a tail
45
45
  // rebuild. It is NOT the human's latest prompt and must be excluded from
46
- // "latest human request" selection (deriveCurrentRequest /
47
- // buildRecallFastTrackQuery). The `meta:'skill'` marker is also honoured.
46
+ // "latest human request" selection (deriveCurrentRequest). The `meta:'skill'`
47
+ // marker is also honoured.
48
48
  export function isInjectedSkillBodyMessage(m) {
49
49
  if (m?.role !== 'user') return false;
50
50
  if (m.meta === 'skill') return true;
@@ -717,13 +717,6 @@ function truncateTailToCap(messages, cap) {
717
717
  return estimateMessagesTokens(sanitized) <= cap ? sanitized : [];
718
718
  }
719
719
 
720
- function splitRecallFitInputs(recallText) {
721
- return {
722
- recall: String(recallText || '').trim(),
723
- prior: '',
724
- };
725
- }
726
-
727
720
  function recallTailStartIndex(live, tail) {
728
721
  if (!tail.length) return live.length;
729
722
  const first = tail[0];
@@ -837,9 +830,9 @@ function _recallFastTrackCompactMessages(messages, budgetTokens, opts = {}) {
837
830
  head: recallHead,
838
831
  lastTurnStartIdx = recallHead.length,
839
832
  } = selectRecallPreservedTail(live, recallTailOpts);
840
- const recallFit = splitRecallFitInputs(opts.recallText);
833
+ const recallText = String(opts.recallText || '').trim();
841
834
  if (recallHead.length === 0
842
- && !(recallFit.recall || recallFit.prior || opts.allowEmptyRecall === true)) {
835
+ && !(recallText || opts.allowEmptyRecall === true)) {
843
836
  throw new Error('recallFastTrackCompactMessages: no compactable prior history before preserved tail');
844
837
  }
845
838
 
@@ -851,7 +844,7 @@ function _recallFastTrackCompactMessages(messages, budgetTokens, opts = {}) {
851
844
  }
852
845
  const budgetRaisedBy = Math.max(0, budget - originalBudget);
853
846
 
854
- if (!recallFit.recall && !recallFit.prior && opts.allowEmptyRecall !== true) {
847
+ if (!recallText && opts.allowEmptyRecall !== true) {
855
848
  throw new Error('recallFastTrackCompactMessages: recall text is empty');
856
849
  }
857
850
  const oldHistory = recallHead;
@@ -871,14 +864,14 @@ function _recallFastTrackCompactMessages(messages, budgetTokens, opts = {}) {
871
864
  ? Math.min(recallRoomUncapped, Math.max(512, recallTokenCap - tailTokens))
872
865
  : recallRoomUncapped;
873
866
  const toolLines = collectToolOutcomeLines(recallHead)
874
- .filter((line) => !recallFit.recall.includes(String(line || '').trim()));
867
+ .filter((line) => !recallText.includes(String(line || '').trim()));
875
868
  const workingFiles = collectWorkingFileGroups(recallHead, undefined, {
876
869
  cwd: opts.cwd,
877
870
  previousSummary: '',
878
871
  now: Date.now(),
879
872
  });
880
873
  const conversationLines = excludeTailFromConversation(
881
- conversationLinesFromMemoryText(recallFit.recall),
874
+ conversationLinesFromMemoryText(recallText),
882
875
  recallTail,
883
876
  );
884
877
  const composedRecall = composeRecallHandoff({
@@ -894,7 +887,6 @@ function _recallFastTrackCompactMessages(messages, budgetTokens, opts = {}) {
894
887
  fittedRecall,
895
888
  recallRoom,
896
889
  recallMeta,
897
- '',
898
890
  );
899
891
  if (!summaryMessage) {
900
892
  throw new Error(`recallFastTrackCompactMessages: summary cannot fit remaining budget=${recallRoom}`);
@@ -936,20 +928,15 @@ function _recallFastTrackCompactMessages(messages, budgetTokens, opts = {}) {
936
928
  remainingTokens: budget - mandatoryCost,
937
929
  recallTokenCap: (Number.isFinite(recallTokenCap) && recallTokenCap > 0) ? recallTokenCap : null,
938
930
  recallRoom,
939
- recallChars: recallFit.recall.length,
940
- recallBytes: textByteLength(recallFit.recall),
941
- priorChars: 0,
942
- priorBytes: 0,
931
+ recallChars: recallText.length,
932
+ recallBytes: textByteLength(recallText),
943
933
  summaryMessageChars: summaryContent.length,
944
934
  summaryMessageBytes: textByteLength(summaryContent),
945
- recallEmpty: !recallFit.recall,
946
- priorEmpty: !recallFit.prior,
947
- recallTruncatedInSummary: !!recallFit.recall && !summaryContent.includes(recallFit.recall),
948
- priorTruncatedInSummary: false,
935
+ recallEmpty: !recallText,
936
+ recallTruncatedInSummary: !!recallText && !summaryContent.includes(recallText),
949
937
  tailTruncated: recallTail.some((m) => messageContentHasMarker(m, RECALL_TAIL_TRUNCATION_MARKER) || messageContentHasMarker(m, RECALL_TAIL_SHORT_TRUNCATION_MARKER)),
950
938
  fileReattached: reattach.reattached,
951
939
  tailOptions: recallTailOpts,
952
- previousSummary: false,
953
940
  durationMs: Date.now() - startedAt,
954
941
  };
955
942
  compactDebugLog('recall-fasttrack result', diagnostics);
@@ -346,28 +346,6 @@ function makeSemanticSummaryMessage(oldHistory, summary, semanticMeta = {}, pres
346
346
  return makeSummaryMessage(parts.join('\n\n'));
347
347
  }
348
348
 
349
- export function buildRecallFastTrackQuery(messages, opts = {}) {
350
- const maxChars = Math.max(200, Number(opts.maxChars) || 2_000);
351
- const hints = String(opts.hints || 'current task decisions constraints file paths changed files verification failures next steps').trim();
352
- let latestUser = '';
353
- const recent = [];
354
- const input = Array.isArray(messages) ? messages : [];
355
- for (let i = input.length - 1; i >= 0; i -= 1) {
356
- const m = input[i];
357
- const text = extractText(m).trim();
358
- if (!text) continue;
359
- if (recent.length < 6) recent.unshift(text);
360
- if (!latestUser && m?.role === 'user' && !isProtectedContextUserMessage(m) && !isInjectedSkillBodyMessage(m)) {
361
- latestUser = text;
362
- }
363
- if (latestUser && recent.length >= 6) break;
364
- }
365
- const parts = [latestUser, hints, recent.join('\n')]
366
- .map((s) => String(s || '').trim())
367
- .filter(Boolean);
368
- return truncateMiddle([...new Set(parts)].join('\n'), maxChars);
369
- }
370
-
371
349
  // Fit the structured semantic summary into the remaining token budget WITHOUT
372
350
  // dropping any required section. The incoming `summary` is already schema-valid
373
351
  // (enforceSemanticSummarySchema ran upstream); here we shrink section bodies via
@@ -410,106 +388,15 @@ export function fitSemanticSummaryMessage(oldHistory, summary, remainingTokens,
410
388
  export const RECALL_TAIL_TRUNCATION_MARKER = '[... truncated during recall tail preservation ...]';
411
389
  export const RECALL_TAIL_SHORT_TRUNCATION_MARKER = '[truncated]';
412
390
 
413
- const PRIOR_COMPACTED_CONTEXT_OPEN = '<prior-compacted-context>';
414
- const PRIOR_COMPACTED_CONTEXT_CLOSE = '</prior-compacted-context>';
415
- // Matches ONLY a structural wrapper BOUNDARY line a line whose sole content is
416
- // the open or close tag (optionally surrounded by whitespace). It deliberately
417
- // does NOT match an inline occurrence embedded in real content (e.g. a user note
418
- // like "keep <prior-compacted-context> literal here"), so flattening the wrapper
419
- // can never splice words together or corrupt marker-like text. The production
420
- // wrapper is always emitted on its own line, so boundary-line stripping removes
421
- // every real wrapper while leaving inline literals verbatim.
422
- const PRIOR_COMPACTED_CONTEXT_BOUNDARY_RE = /^[ \t]*<\/?prior-compacted-context>[ \t]*$/;
423
-
424
- // Strip the STRUCTURAL <prior-compacted-context> / </prior-compacted-context>
425
- // boundary lines from prior text so re-wrapping never nests, while preserving
426
- // any inline marker-like text inside real content exactly as written. Returns
427
- // the bare inner content with the blank lines the removed boundary lines leave
428
- // behind collapsed.
429
- export function stripPriorCompactedContextWrappers(text) {
430
- const raw = String(text ?? '');
431
- if (!raw) return '';
432
- // Keep every non-structural byte, including leading/trailing and repeated
433
- // newlines. Removing only the structural line itself (not trim/collapse)
434
- // preserves the layout of all remaining content.
435
- return raw
436
- .split('\n')
437
- .filter((line) => !PRIOR_COMPACTED_CONTEXT_BOUNDARY_RE.test(line))
438
- .join('\n');
439
- }
440
-
441
- // Remove only STRUCTURALLY IDENTICAL blank-line-separated blocks (byte-for-byte
442
- // repeats) so a prior context re-fed across many compaction cycles keeps every
443
- // distinct requirement/fact and cannot grow without bound. The dedupe is
444
- // content-preserving: the key is the block's EXACT text — internal whitespace is
445
- // never collapsed and meaningful block content is never trimmed — so distinct
446
- // strings such as `printf 'a b'` and `printf 'a b'` are BOTH kept verbatim.
447
- // Only an exact repeat of a previously emitted block is dropped; blank
448
- // separators (whitespace-only splits) are skipped, never real content.
449
- function dedupePriorCompactedBlocks(text) {
450
- const raw = String(text ?? '');
451
- if (!raw.trim()) return '';
452
- const seen = new Set();
453
- const parts = raw.split(/(\n{2,})/);
454
- const out = [];
455
- let separator = '';
456
- for (let i = 0; i < parts.length; i += 1) {
457
- const part = parts[i];
458
- if (i % 2 === 1) {
459
- separator += part;
460
- continue;
461
- }
462
- // Whitespace-only parts are layout, not a duplicate candidate.
463
- if (!part.trim()) {
464
- out.push(separator, part);
465
- separator = '';
466
- continue;
467
- }
468
- if (seen.has(part)) {
469
- // Drop only the exact repeated structural block and its preceding
470
- // separator; all retained text and whitespace stay byte-for-byte.
471
- separator = '';
472
- continue;
473
- }
474
- out.push(separator, part);
475
- separator = '';
476
- seen.add(part);
477
- }
478
- out.push(separator);
479
- return out.join('');
480
- }
481
-
482
- // Canonicalize prior compacted context to AT MOST ONE wrapper: flatten any
483
- // nested/duplicated wrappers accumulated by earlier cycles, dedupe repeated
484
- // blocks, then wrap the surviving content exactly once. Repeated compaction can
485
- // therefore never nest or duplicate the prior context, each distinct
486
- // requirement/fact is preserved exactly once, and repeated-cycle token size
487
- // stays bounded.
488
- //
489
- // Optimization-safe empty-prior interpretation: when there is NO prior content
490
- // (empty / blank / boundary-tag-only input) this returns '' so the generated
491
- // summary carries ZERO wrappers instead of an empty
492
- // <prior-compacted-context></prior-compacted-context> pair. The production
493
- // summary body joins only non-empty parts (makeRecall*SummaryMessageParts), so
494
- // an empty wrapper cannot be carried and would only waste tokens. "Exactly one
495
- // wrapper" is thus realized as: exactly one when prior content exists, none when
496
- // it does not — and never more than one, never nested.
497
- export function formatPriorCompactedContextBlock(priorText) {
498
- const flattened = dedupePriorCompactedBlocks(stripPriorCompactedContextWrappers(priorText));
499
- if (!flattened) return '';
500
- return `${PRIOR_COMPACTED_CONTEXT_OPEN}\n${flattened}\n${PRIOR_COMPACTED_CONTEXT_CLOSE}`;
501
- }
502
-
391
+ // Peel the structural summary header off a prior summary body so semantic
392
+ // compaction can feed bare text into its <previous-summary> block. Sessions
393
+ // stored before recall-fasttrack stopped chaining summaries may still carry a
394
+ // <prior-compacted-context> wrapper, so those boundary lines are dropped too.
503
395
  export function stripNestedSummaryHeaderLines(text) {
504
396
  const raw = String(text ?? '');
505
- // A generated recall summary has a canonical, provenance-bearing shape:
506
- // header + "\n\n" + OPEN + "\n" + prior + "\n" + CLOSE + "\n\n" + recall
507
- // Extracting it as lines loses ownership of a run of newlines: in
508
- // `X\n` + join + live `X`, generic block dedupe cannot know that one
509
- // newline belongs to X and must survive dropping the duplicate live X.
510
- // Peel only the emitted wrapper/header/join bytes and retain the inner
511
- // prior slice verbatim. The live recall is dropped only when it is the
512
- // same payload the wrapper already carries.
397
+ // Peel only the emitted wrapper/header/join bytes and keep the inner slice
398
+ // verbatim: splitting into lines would lose ownership of a run of newlines,
399
+ // where one newline belongs to the content and must survive.
513
400
  const openMatch = /^[ \t]*<prior-compacted-context>[ \t]*\n/m.exec(raw);
514
401
  if (openMatch) {
515
402
  const closeRe = /\n[ \t]*<\/prior-compacted-context>[ \t]*(?=\n|$)/g;
@@ -544,10 +431,9 @@ export function stripNestedSummaryHeaderLines(text) {
544
431
  followsStructuralHeader = true;
545
432
  continue;
546
433
  }
547
- // Summary parts are joined with "\n\n". The first empty line after
434
+ // Summary parts are joined with "\n\n". The first empty line after
548
435
  // stripped summary metadata is that join's structural separator, not
549
- // prior content; retaining it makes every refeed gain a newline when
550
- // formatPriorCompactedContextBlock wraps the result again.
436
+ // content.
551
437
  if (followsStructuralHeader && line === '') {
552
438
  followsStructuralHeader = false;
553
439
  continue;
@@ -570,46 +456,19 @@ export function stripNestedSummaryHeaderLines(text) {
570
456
  return out.join('\n');
571
457
  }
572
458
 
573
- function makeRecallFastTrackSummaryMessageParts(oldHistory, recallPart, priorPart, recallMeta = {}) {
459
+ function makeRecallFastTrackSummaryMessageParts(oldHistory, recallPart, recallMeta = {}) {
574
460
  const header = compactHeader(oldHistory);
575
461
  header.push(`compact_type=${COMPACT_TYPE_RECALL_FASTTRACK} source=recall-fasttrack query_sha=${recallMeta.querySha || 'none'}`);
576
462
  const parts = [header.join('\n')];
577
- const priorBlock = formatPriorCompactedContextBlock(priorPart);
578
- if (priorBlock) parts.push(priorBlock);
579
463
  const recall = String(recallPart || '').trim();
580
464
  if (recall) parts.push(recall);
581
465
  return makeSummaryMessage(parts.join('\n\n'));
582
466
  }
583
467
 
584
- export function fitRecallFastTrackSummaryMessage(oldHistory, recallText, remainingTokens, recallMeta = {}, priorPart = '') {
468
+ export function fitRecallFastTrackSummaryMessage(oldHistory, recallText, remainingTokens, recallMeta = {}) {
585
469
  const recall = String(recallText || '').trim();
586
- const prior = String(priorPart || '');
587
-
588
- let fittedPrior = prior;
589
- if (prior) {
590
- let lo = 0;
591
- let hi = prior.length;
592
- let bestPriorLen = 0;
593
- while (lo <= hi) {
594
- const mid = Math.floor((lo + hi) / 2);
595
- const candidate = makeRecallFastTrackSummaryMessageParts(oldHistory, '', prior.slice(0, mid), recallMeta);
596
- if (estimateMessagesTokens([candidate]) <= remainingTokens) {
597
- bestPriorLen = mid;
598
- lo = mid + 1;
599
- } else {
600
- hi = mid - 1;
601
- }
602
- }
603
- fittedPrior = prior.slice(0, bestPriorLen);
604
- if (!fittedPrior && prior) {
605
- const markerOnly = makeRecallFastTrackSummaryMessageParts(oldHistory, '', RECALL_TAIL_TRUNCATION_MARKER, recallMeta);
606
- if (estimateMessagesTokens([markerOnly]) <= remainingTokens) {
607
- fittedPrior = RECALL_TAIL_TRUNCATION_MARKER;
608
- }
609
- }
610
- }
611
470
 
612
- const minimal = makeRecallFastTrackSummaryMessageParts(oldHistory, '', fittedPrior, recallMeta);
471
+ const minimal = makeRecallFastTrackSummaryMessageParts(oldHistory, '', recallMeta);
613
472
  if (estimateMessagesTokens([minimal]) > remainingTokens) return null;
614
473
  if (!recall) return minimal;
615
474
 
@@ -618,14 +477,14 @@ export function fitRecallFastTrackSummaryMessage(oldHistory, recallText, remaini
618
477
  // Root-block granularity fit: drop the OLDEST blocks WHOLE (never cut
619
478
  // a `# chunk` / `# raw_pending` / `# raw_terminal` block mid-entry);
620
479
  // dropping more leading blocks only shrinks the body, so binary-search
621
- // the minimal drop count (mirrors fitRecallRootsMessage).
480
+ // the minimal drop count.
622
481
  let loB = 0;
623
482
  let hiB = blocks.length;
624
483
  let bestLo = -1;
625
484
  while (loB <= hiB) {
626
485
  const midB = Math.floor((loB + hiB) / 2);
627
486
  const body = [preamble, ...blocks.slice(midB)].filter(Boolean).join('\n\n');
628
- const candidate = makeRecallFastTrackSummaryMessageParts(oldHistory, body, fittedPrior, recallMeta);
487
+ const candidate = makeRecallFastTrackSummaryMessageParts(oldHistory, body, recallMeta);
629
488
  if (estimateMessagesTokens([candidate]) <= remainingTokens) {
630
489
  bestLo = midB;
631
490
  hiB = midB - 1;
@@ -635,12 +494,11 @@ export function fitRecallFastTrackSummaryMessage(oldHistory, recallText, remaini
635
494
  }
636
495
  if (bestLo >= 0) {
637
496
  const body = [preamble, ...blocks.slice(bestLo)].filter(Boolean).join('\n\n');
638
- return makeRecallFastTrackSummaryMessageParts(oldHistory, body, fittedPrior, recallMeta);
497
+ return makeRecallFastTrackSummaryMessageParts(oldHistory, body, recallMeta);
639
498
  }
640
- // Even zero blocks (preamble alone) overflows alongside the fitted
641
- // prior - try preamble alone, else the no-recall minimal message.
499
+ // Even the preamble alone overflows: try it, else the minimal message.
642
500
  if (preamble) {
643
- const preambleOnly = makeRecallFastTrackSummaryMessageParts(oldHistory, preamble, fittedPrior, recallMeta);
501
+ const preambleOnly = makeRecallFastTrackSummaryMessageParts(oldHistory, preamble, recallMeta);
644
502
  if (estimateMessagesTokens([preambleOnly]) <= remainingTokens) return preambleOnly;
645
503
  }
646
504
  return minimal;
@@ -654,7 +512,7 @@ export function fitRecallFastTrackSummaryMessage(oldHistory, recallText, remaini
654
512
  let best = minimal;
655
513
  while (lo <= hi) {
656
514
  const mid = Math.floor((lo + hi) / 2);
657
- const candidate = makeRecallFastTrackSummaryMessageParts(oldHistory, recall.slice(0, mid), fittedPrior, recallMeta);
515
+ const candidate = makeRecallFastTrackSummaryMessageParts(oldHistory, recall.slice(0, mid), recallMeta);
658
516
  if (estimateMessagesTokens([candidate]) <= remainingTokens) {
659
517
  best = candidate;
660
518
  lo = mid + 1;
@@ -665,28 +523,23 @@ export function fitRecallFastTrackSummaryMessage(oldHistory, recallText, remaini
665
523
  return best;
666
524
  }
667
525
 
668
- // --- Smart-compact root-based fitting (arrival-time replacement) -----------
526
+ // --- Root-block splitting for the recall digest ----------------------------
669
527
  //
670
- // dump_session_roots (memory/index.mjs dumpSessionRootChunks) renders chunks
671
- // TIME-ORDERED (oldest first; chunks.sort by sourceTurn/ts/id ascending),
672
- // each root/raw block starting with one of:
528
+ // A memory digest renders chunks TIME-ORDERED (oldest first), each root/raw
529
+ // block starting with one of:
673
530
  // # chunk N root=ID[ category=X]
674
531
  // # raw_pending N id=ID
675
532
  // # raw_terminal N id=ID
676
- // and blocks joined by "\n\n". runRecallFastTrackForSession additionally
677
- // prepends a "session_id=..." / cycle1-drain-status preamble before the dump
678
- // text (also "\n\n"-joined) — preserved verbatim as a non-block segment.
533
+ // and blocks joined by "\n\n", after an optional preamble that is kept verbatim
534
+ // as a non-block segment.
679
535
  //
680
- // Unlike fitRecallFastTrackSummaryMessage (character-slice binary search,
681
- // used by the LLM-summary-free but still-mid-turn recall-fasttrack compact
682
- // path), the smart-compact arrival path must never cut a root block
683
- // mid-entry losing half a root's content silently corrupts that entry.
684
- // This splitter finds block boundaries by the label pattern (robust to
685
- // blank lines inside member/raw content, since it anchors on the distinctive
686
- // "# chunk /raw_pending/raw_terminal" line rather than a blank-line split).
536
+ // fitRecallFastTrackSummaryMessage drops whole blocks instead of cutting one
537
+ // mid-entry, since losing half a root's content silently corrupts that entry.
538
+ // Boundaries come from the label pattern, which stays robust to blank lines
539
+ // inside member/raw content.
687
540
  const RECALL_ROOT_BLOCK_HEADER_RE = /^# (?:chunk \d+ root=\d+(?: category=\S+)?|raw_pending \d+ id=\d+|raw_terminal \d+ id=\d+)[ \t]*$/;
688
541
 
689
- export function splitRecallRootBlocks(text) {
542
+ function splitRecallRootBlocks(text) {
690
543
  const value = String(text || '');
691
544
  if (!value.trim()) return { preamble: '', blocks: [] };
692
545
  const re = new RegExp(RECALL_ROOT_BLOCK_HEADER_RE.source, 'gm');
@@ -708,97 +561,3 @@ export function splitRecallRootBlocks(text) {
708
561
  return { preamble, blocks };
709
562
  }
710
563
 
711
- // Minimal-header summary-message wrapper for the smart-compact roots path.
712
- // Keeps the SUMMARY_PREFIX anchor (isSummaryMessage / selectCompactionWindow
713
- // / clear-preserve / TUI all key off startsWith(SUMMARY_PREFIX)) but skips the
714
- // full sha256/roleCounts header line that fitRecallFastTrackSummaryMessage
715
- // computes — smart-arrival replacement is a lightweight prefix swap, not the
716
- // anchored LLM-summary compact, so a heavy per-call header is unneeded cost.
717
- function makeRecallRootsSummaryMessageParts(oldHistory, rootsPart, priorPart, recallMeta = {}) {
718
- const header = `${SUMMARY_PREFIX}\nmessages=${(oldHistory || []).length} compact_type=${COMPACT_TYPE_RECALL_FASTTRACK} source=smart-arrival query_sha=${recallMeta.querySha || 'none'}`;
719
- const parts = [header];
720
- const priorBlock = formatPriorCompactedContextBlock(priorPart);
721
- if (priorBlock) parts.push(priorBlock);
722
- const roots = String(rootsPart || '').trim();
723
- if (roots) parts.push(roots);
724
- return makeSummaryMessage(parts.join('\n\n'));
725
- }
726
-
727
- // Root-block-aware fit for the smart-compact arrival path (Step1). Mirrors
728
- // fitRecallFastTrackSummaryMessage's prior-block binary-search fit, but the
729
- // recall body is fit at ROOT-BLOCK granularity: when the full set of root
730
- // blocks (kept in original time order) exceeds remainingTokens, the OLDEST
731
- // blocks are dropped WHOLE (never character-truncated mid-block) until the
732
- // remaining (newest-biased) suffix fits. Because dropping more leading
733
- // blocks can only shrink (never grow) the serialized size, the minimal-drop
734
- // threshold is found via binary search on the drop count.
735
- export function fitRecallRootsMessage(oldHistory, recallText, remainingTokens, recallMeta = {}, priorPart = '') {
736
- const prior = String(priorPart || '');
737
-
738
- let fittedPrior = prior;
739
- if (prior) {
740
- let lo = 0;
741
- let hi = prior.length;
742
- let bestPriorLen = 0;
743
- while (lo <= hi) {
744
- const mid = Math.floor((lo + hi) / 2);
745
- const candidate = makeRecallRootsSummaryMessageParts(oldHistory, '', prior.slice(0, mid), recallMeta);
746
- if (estimateMessagesTokens([candidate]) <= remainingTokens) {
747
- bestPriorLen = mid;
748
- lo = mid + 1;
749
- } else {
750
- hi = mid - 1;
751
- }
752
- }
753
- fittedPrior = prior.slice(0, bestPriorLen);
754
- if (!fittedPrior && prior) {
755
- const markerOnly = makeRecallRootsSummaryMessageParts(oldHistory, '', RECALL_TAIL_TRUNCATION_MARKER, recallMeta);
756
- if (estimateMessagesTokens([markerOnly]) <= remainingTokens) {
757
- fittedPrior = RECALL_TAIL_TRUNCATION_MARKER;
758
- }
759
- }
760
- }
761
-
762
- const minimal = makeRecallRootsSummaryMessageParts(oldHistory, '', fittedPrior, recallMeta);
763
- if (estimateMessagesTokens([minimal]) > remainingTokens) return null;
764
-
765
- const { preamble, blocks } = splitRecallRootBlocks(recallText);
766
- if (blocks.length === 0) {
767
- // No parseable root-block boundaries (empty / non-dump recallText) —
768
- // degrade to keep-whole-if-it-fits, else drop entirely. Never
769
- // mid-truncates: a non-block body is treated as a single atomic unit.
770
- const whole = String(recallText || '').trim();
771
- if (!whole) return minimal;
772
- const full = makeRecallRootsSummaryMessageParts(oldHistory, whole, fittedPrior, recallMeta);
773
- if (estimateMessagesTokens([full]) <= remainingTokens) return full;
774
- return minimal;
775
- }
776
-
777
- let loB = 0;
778
- let hiB = blocks.length;
779
- let bestLo = -1;
780
- while (loB <= hiB) {
781
- const mid = Math.floor((loB + hiB) / 2);
782
- const kept = blocks.slice(mid);
783
- const body = [preamble, ...kept].filter(Boolean).join('\n\n');
784
- const candidate = makeRecallRootsSummaryMessageParts(oldHistory, body, fittedPrior, recallMeta);
785
- if (estimateMessagesTokens([candidate]) <= remainingTokens) {
786
- bestLo = mid;
787
- hiB = mid - 1;
788
- } else {
789
- loB = mid + 1;
790
- }
791
- }
792
- if (bestLo >= 0) {
793
- const kept = blocks.slice(bestLo);
794
- const body = [preamble, ...kept].filter(Boolean).join('\n\n');
795
- return makeRecallRootsSummaryMessageParts(oldHistory, body, fittedPrior, recallMeta);
796
- }
797
- // Even zero root blocks (preamble alone) overflows alongside the fitted
798
- // prior — try preamble alone, else the no-recall minimal header.
799
- if (preamble) {
800
- const preambleOnly = makeRecallRootsSummaryMessageParts(oldHistory, preamble, fittedPrior, recallMeta);
801
- if (estimateMessagesTokens([preambleOnly]) <= remainingTokens) return preambleOnly;
802
- }
803
- return minimal;
804
- }
@@ -44,12 +44,6 @@ export {
44
44
  pruneToolOutputsUnanchored,
45
45
  } from './compact/budget.mjs';
46
46
 
47
- export {
48
- buildRecallFastTrackQuery,
49
- splitRecallRootBlocks,
50
- fitRecallRootsMessage,
51
- } from './compact/summary.mjs';
52
-
53
47
  export {
54
48
  semanticCompactMessages,
55
49
  recallFastTrackCompactMessages,