@cortexkit/opencode-magic-context 0.49.8 → 0.49.9

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 (105) hide show
  1. package/dist/agents/hidden-agent-registrations.d.ts +5 -3
  2. package/dist/agents/hidden-agent-registrations.d.ts.map +1 -1
  3. package/dist/auto-search-worker.js +1 -1
  4. package/dist/config/schema/agent-overrides.d.ts +13 -13
  5. package/dist/config/schema/magic-context.d.ts +500 -500
  6. package/dist/{context-x0ccfv0f.js → context-ey3ap3cc.js} +29 -24
  7. package/dist/features/magic-context/primer-clustering.d.ts.map +1 -1
  8. package/dist/features/magic-context/smart-notes/compiler-prompt.d.ts +1 -1
  9. package/dist/features/magic-context/smart-notes/compiler-prompt.d.ts.map +1 -1
  10. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  11. package/dist/hooks/magic-context/__fixtures__/tail-hygiene-refresh.d.ts +34 -0
  12. package/dist/hooks/magic-context/__fixtures__/tail-hygiene-refresh.d.ts.map +1 -0
  13. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  14. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +1 -0
  15. package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
  16. package/dist/hooks/magic-context/dropped-input-guard.d.ts.map +1 -1
  17. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +2 -0
  18. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  19. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  20. package/dist/hooks/magic-context/provider-visible-parts.d.ts +10 -4
  21. package/dist/hooks/magic-context/provider-visible-parts.d.ts.map +1 -1
  22. package/dist/hooks/magic-context/supersession-reclaim.d.ts +5 -3
  23. package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
  24. package/dist/hooks/magic-context/tail-hygiene-output-count.d.ts +18 -0
  25. package/dist/hooks/magic-context/tail-hygiene-output-count.d.ts.map +1 -0
  26. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +5 -1
  27. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  28. package/dist/hooks/magic-context/tool-reclaim.d.ts +5 -2
  29. package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -1
  30. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +1 -0
  31. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  32. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  33. package/dist/{index-b4gcb3rk.js → index-0x9cn9w1.js} +2 -2
  34. package/dist/{index-ydjgz36f.js → index-16vwdyy5.js} +1 -1
  35. package/dist/{index-xf6k8szp.js → index-21919gcq.js} +3 -3
  36. package/dist/{index-hxrvx6cy.js → index-3403gbzj.js} +129 -103
  37. package/dist/{index-gzg9ekc1.js → index-6k86es2p.js} +129 -15
  38. package/dist/{index-8kk7yh6m.js → index-9jvab89d.js} +1 -1
  39. package/dist/{index-qgp5vnt4.js → index-a865mj02.js} +1 -1
  40. package/dist/{index-xpn05jxq.js → index-f8cn4xqa.js} +287 -58
  41. package/dist/{index-2rw244rh.js → index-ffa8x2as.js} +4 -4
  42. package/dist/{index-bd9cjab3.js → index-g7jkrz0x.js} +35 -15
  43. package/dist/{index-pjgzdezw.js → index-nenz4gpb.js} +3 -3
  44. package/dist/{index-zf9nydbd.js → index-swgpe402.js} +4 -4
  45. package/dist/{index-9g1c4bt9.js → index-wpwpn7nj.js} +88 -8
  46. package/dist/{index-w1ejb9qr.js → index-x57ep4fp.js} +33 -19
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +50 -46
  49. package/dist/{message-index-zs882h8e.js → message-index-6r1x9cqh.js} +5 -5
  50. package/dist/{message-index-bounded-hxjp56qk.js → message-index-bounded-fskdyc81.js} +5 -5
  51. package/dist/migration-worker.js +4 -4
  52. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  53. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  54. package/dist/raw-ordinal-warmup-worker.js +3 -3
  55. package/dist/{read-session-chunk-t9r7r0sg.js → read-session-chunk-zgpvs423.js} +4 -4
  56. package/dist/{recomp-orchestrator-gr36zvd2.js → recomp-orchestrator-77xc8wpe.js} +10 -10
  57. package/dist/{search-qjen1pmz.js → search-72fkjwk2.js} +8 -8
  58. package/dist/shared/hidden-zen-read.d.ts +24 -0
  59. package/dist/shared/hidden-zen-read.d.ts.map +1 -0
  60. package/dist/shared/reclaim-distance.d.ts +33 -0
  61. package/dist/shared/reclaim-distance.d.ts.map +1 -0
  62. package/dist/shared/stable-json.d.ts +7 -0
  63. package/dist/shared/stable-json.d.ts.map +1 -1
  64. package/dist/shared/tail-hygiene-json.d.ts +22 -0
  65. package/dist/shared/tail-hygiene-json.d.ts.map +1 -0
  66. package/dist/shared/transcript.d.ts +5 -0
  67. package/dist/shared/transcript.d.ts.map +1 -1
  68. package/dist/{storage-tags-a513rkj3.js → storage-tags-35m4gms2.js} +2 -2
  69. package/dist/{transform-postprocess-phase-yv463b7y.js → transform-postprocess-phase-r8d406j0.js} +10 -10
  70. package/dist/v2/auto-search-worker.js +1 -1
  71. package/dist/v2/{context-wd82v9z6.js → context-z2yagwy4.js} +168 -35
  72. package/dist/v2/hidden-completion.d.ts.map +1 -1
  73. package/dist/v2/hooks/hidden-child.d.ts +2 -2
  74. package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
  75. package/dist/v2/{message-index-yd94vt9n.js → message-index-9ezq6wze.js} +5 -5
  76. package/dist/v2/{message-index-bounded-madg2kfr.js → message-index-bounded-rqc603f2.js} +5 -5
  77. package/dist/v2/migration-worker.js +4 -4
  78. package/dist/v2/raw-ordinal-warmup-worker.js +3 -3
  79. package/dist/v2/{read-session-chunk-7qs791f3.js → read-session-chunk-7f87tg2q.js} +4 -4
  80. package/dist/v2/{recomp-orchestrator-ee91r9s6.js → recomp-orchestrator-s5tdpsbs.js} +9 -9
  81. package/dist/v2/{search-pn15rr52.js → search-2td1b1wy.js} +8 -8
  82. package/dist/v2/{server-08k4zkfk.js → server-23znwjqk.js} +4 -4
  83. package/dist/v2/{server-y5g32dhq.js → server-2hxypdx5.js} +4 -4
  84. package/dist/v2/{server-yak3sxya.js → server-4zwx20yg.js} +1 -1
  85. package/dist/v2/{server-shme41gj.js → server-89fcbe37.js} +35 -15
  86. package/dist/v2/{server-q360kdb8.js → server-c9w52qss.js} +30 -13
  87. package/dist/v2/{server-4gz0xkrc.js → server-f27he3j1.js} +1 -1
  88. package/dist/v2/{server-xj4mewze.js → server-gc8x2xdb.js} +66 -8
  89. package/dist/v2/{server-jjsf29aq.js → server-kmapq3v0.js} +286 -57
  90. package/dist/v2/{server-adfte03x.js → server-xqf2d2mg.js} +1 -1
  91. package/dist/v2/{server-j3dm74ey.js → server-z0rjemg1.js} +2 -2
  92. package/dist/v2/server.js +2 -2
  93. package/dist/v2/{storage-tags-spa92sgj.js → storage-tags-c4zfcxv4.js} +2 -2
  94. package/dist/v2/{wrapup-orchestrator-5wxy1ggv.js → wrapup-orchestrator-wg8dmmm9.js} +9 -9
  95. package/dist/{wrapup-orchestrator-gv08c6f9.js → wrapup-orchestrator-b1z99yg5.js} +11 -11
  96. package/package.json +1 -1
  97. package/src/agents/hidden-agent-registrations.ts +22 -4
  98. package/src/shared/hidden-zen-read.test.ts +99 -0
  99. package/src/shared/hidden-zen-read.ts +88 -0
  100. package/src/shared/reclaim-distance.test.ts +111 -0
  101. package/src/shared/reclaim-distance.ts +91 -0
  102. package/src/shared/stable-json.ts +56 -14
  103. package/src/shared/tail-hygiene-json.test.ts +117 -0
  104. package/src/shared/tail-hygiene-json.ts +217 -0
  105. package/src/shared/transcript.ts +7 -0
@@ -18,8 +18,9 @@ import {
18
18
  import {
19
19
  tagIdentityRevisionKey,
20
20
  tagOrderConstraintIndex,
21
- stableStringify
22
- } from "./index-bd9cjab3.js";
21
+ stableStringify,
22
+ stableStringifyHash
23
+ } from "./index-g7jkrz0x.js";
23
24
  import {
24
25
  DEFAULT_PROTECTED_TOOLS,
25
26
  normalizeProtectedToolName,
@@ -127,6 +128,22 @@ function isThinkingPart(part) {
127
128
  return candidate.type === "thinking" || candidate.type === "reasoning";
128
129
  }
129
130
 
131
+ // src/hooks/magic-context/tail-hygiene-output-count.ts
132
+ var CURRENT_OUTPUT_COUNT = Symbol.for("magic-context.current-reclaimable-tool-output-count");
133
+ function countReclaimableToolOutputs(parts) {
134
+ return parts.filter((part) => part.kind === "toolOutput" && part.uTokens > 0).length;
135
+ }
136
+ function rememberCurrentToolOutputCount(baseline, measurement) {
137
+ return Object.assign(baseline, {
138
+ [CURRENT_OUTPUT_COUNT]: countReclaimableToolOutputs(measurement.parts)
139
+ });
140
+ }
141
+ function currentReclaimableToolOutputCount(baseline) {
142
+ if (!baseline || !Object.hasOwn(baseline, CURRENT_OUTPUT_COUNT))
143
+ return 0;
144
+ return baseline[CURRENT_OUTPUT_COUNT];
145
+ }
146
+
130
147
  // src/shared/tag-owner-id.ts
131
148
  var TEXT_TAG_IDENTITY_MARKER = ":mc-text-v1:";
132
149
  var PI_FALLBACK_PREFIXES_JSON = JSON.stringify([..."pi-msg-"].reduce((prefixes, char) => prefixes.flatMap((prefix) => /[a-z]/.test(char) ? [prefix + char, prefix + char.toUpperCase()] : [prefix + char]), [""]));
@@ -142,6 +159,127 @@ function contentTagOwnerMessageId(contentId) {
142
159
  return contentId;
143
160
  }
144
161
 
162
+ // src/shared/tail-hygiene-json.ts
163
+ var MAX_MEMO_BYTES = 64 * 1024 * 1024;
164
+ var MAX_MEMO_ENTRIES = 1e4;
165
+
166
+ class TailHygieneJsonMemo {
167
+ entries = new Map;
168
+ bytes = 0;
169
+ passText = new WeakMap;
170
+ passHash = new WeakMap;
171
+ beginPass() {
172
+ this.passText = new WeakMap;
173
+ this.passHash = new WeakMap;
174
+ }
175
+ get(key, value, compute, fingerprint = false) {
176
+ const pass = fingerprint ? this.passHash : this.passText;
177
+ const object = value !== null && typeof value === "object" ? value : undefined;
178
+ const local = object ? pass.get(object) : undefined;
179
+ if (local !== undefined)
180
+ return local;
181
+ const previous = this.entries.get(key);
182
+ if (previous && sameJson(previous.snapshot, value)) {
183
+ if (object)
184
+ pass.set(object, previous.result);
185
+ return previous.result;
186
+ }
187
+ const result = compute();
188
+ if (previous) {
189
+ this.bytes -= previous.bytes;
190
+ this.entries.delete(key);
191
+ }
192
+ try {
193
+ const copy = copyJson(value);
194
+ const bytes = copy.bytes + (key.length + result.length) * 2;
195
+ if (bytes <= MAX_MEMO_BYTES) {
196
+ this.entries.set(key, { snapshot: copy.value, result, bytes });
197
+ this.bytes += bytes;
198
+ if (object)
199
+ pass.set(object, result);
200
+ }
201
+ } catch {}
202
+ while (this.bytes > MAX_MEMO_BYTES || this.entries.size > MAX_MEMO_ENTRIES) {
203
+ const oldest = this.entries.entries().next().value;
204
+ if (!oldest)
205
+ break;
206
+ this.bytes -= oldest[1].bytes;
207
+ this.entries.delete(oldest[0]);
208
+ }
209
+ return result;
210
+ }
211
+ }
212
+ function copyJson(value) {
213
+ const seen = new Map;
214
+ let bytes = 0;
215
+ const copy = (current) => {
216
+ bytes += 16;
217
+ if (typeof current === "string")
218
+ bytes += current.length * 2;
219
+ if (bytes > MAX_MEMO_BYTES)
220
+ throw new Error("memo capacity");
221
+ if (current === null || typeof current !== "object") {
222
+ if (["function", "symbol", "bigint"].includes(typeof current))
223
+ throw new Error("exotic");
224
+ return current;
225
+ }
226
+ if (seen.has(current))
227
+ return seen.get(current);
228
+ const prototype = Object.getPrototypeOf(current);
229
+ if (!Array.isArray(current) && prototype !== Object.prototype && prototype !== null)
230
+ throw new Error("exotic");
231
+ const result = Array.isArray(current) ? new Array(current.length) : Object.create(prototype);
232
+ seen.set(current, result);
233
+ for (const key of Object.keys(current)) {
234
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
235
+ if (!descriptor || !("value" in descriptor))
236
+ throw new Error("accessor");
237
+ bytes += key.length * 2 + 16;
238
+ if (key === "__proto__") {
239
+ Object.defineProperty(result, key, {
240
+ value: copy(descriptor.value),
241
+ enumerable: true,
242
+ writable: true,
243
+ configurable: true
244
+ });
245
+ } else
246
+ result[key] = copy(descriptor.value);
247
+ }
248
+ return result;
249
+ };
250
+ return { value: copy(value), bytes };
251
+ }
252
+ function sameJson(before, after) {
253
+ const forward = new Map;
254
+ const reverse = new Set;
255
+ const same = (left, right) => {
256
+ if (left === null || right === null || typeof left !== "object" || typeof right !== "object")
257
+ return Object.is(left, right);
258
+ if (forward.has(left))
259
+ return forward.get(left) === right;
260
+ if (reverse.has(right) || Object.getPrototypeOf(left) !== Object.getPrototypeOf(right))
261
+ return false;
262
+ forward.set(left, right);
263
+ reverse.add(right);
264
+ if (Array.isArray(left) && (!Array.isArray(right) || left.length !== right.length))
265
+ return false;
266
+ const keys = Object.keys(left);
267
+ const otherKeys = Object.keys(right);
268
+ if (keys.length !== otherKeys.length)
269
+ return false;
270
+ for (let index = 0;index < keys.length; index++) {
271
+ const key = keys[index];
272
+ if (key !== otherKeys[index])
273
+ return false;
274
+ const descriptor = Object.getOwnPropertyDescriptor(right, key);
275
+ if (!descriptor || !("value" in descriptor) || !same(left[key], descriptor.value))
276
+ return false;
277
+ }
278
+ return true;
279
+ };
280
+ return same(before, after);
281
+ }
282
+
145
283
  // src/hooks/magic-context/image-token-estimate.ts
146
284
  var IMAGE_TOKEN_DIVISOR = 750;
147
285
  var IMAGE_FALLBACK_TOKENS = 1200;
@@ -347,6 +485,70 @@ var KEPT_TOOL_STATE_FIELDS = new Set([
347
485
  "content"
348
486
  ]);
349
487
  var KEPT_TOOL_STATE_TIME_FIELD = "compacted";
488
+ function tailProviderVisibleToolState(state, openCode1) {
489
+ const view = {};
490
+ for (const key of Object.keys(state)) {
491
+ if (tailToolStateFieldIsKept(key, openCode1)) {
492
+ view[key] = state[key];
493
+ } else if (key === "time" && openCode1) {
494
+ const value = state.time;
495
+ if (isRecord2(value)) {
496
+ view.time = value[KEPT_TOOL_STATE_TIME_FIELD] === undefined ? {} : { [KEPT_TOOL_STATE_TIME_FIELD]: value[KEPT_TOOL_STATE_TIME_FIELD] };
497
+ }
498
+ } else if (key === "metadata" && openCode1 && state.status === "error") {
499
+ const metadata = state.metadata;
500
+ if (isRecord2(metadata) && metadata.interrupted === true) {
501
+ const output = metadata.output;
502
+ if (typeof output === "string")
503
+ view.metadata = { interrupted: true, output };
504
+ }
505
+ }
506
+ }
507
+ return view;
508
+ }
509
+ function tailToolStateFieldIsKept(key, openCode1) {
510
+ return KEPT_TOOL_STATE_FIELDS.has(key) && (key !== "content" || !openCode1);
511
+ }
512
+ function tailToolStateIsReduced(state, openCode1) {
513
+ for (const key of Object.keys(state)) {
514
+ if (tailToolStateFieldIsKept(key, openCode1))
515
+ continue;
516
+ return false;
517
+ }
518
+ return true;
519
+ }
520
+ function providerVisiblePart(part) {
521
+ if (!isRecord2(part) || part.type !== "tool" || !isRecord2(part.state))
522
+ return part;
523
+ if (toolStateIsReduced(part.state))
524
+ return part;
525
+ return { ...part, state: providerVisibleToolState(part.state) };
526
+ }
527
+ function providerVisiblePartForTailHygiene(part) {
528
+ return providerVisiblePartForHost(part, true);
529
+ }
530
+ function providerVisiblePartForOpenCode2(part) {
531
+ return providerVisiblePartForHost(part, false);
532
+ }
533
+ function providerVisiblePartForHost(part, openCode1) {
534
+ if (!isRecord2(part))
535
+ return part;
536
+ if (part.type !== "tool") {
537
+ if (!Object.hasOwn(part, "state"))
538
+ return part;
539
+ const view = {};
540
+ for (const key of Object.keys(part)) {
541
+ if (key !== "state")
542
+ view[key] = part[key];
543
+ }
544
+ return view;
545
+ }
546
+ if (!isRecord2(part.state))
547
+ return part;
548
+ if (tailToolStateIsReduced(part.state, openCode1))
549
+ return part;
550
+ return { ...part, state: tailProviderVisibleToolState(part.state, openCode1) };
551
+ }
350
552
  var KEPT_ERROR_METADATA_FIELDS = ["interrupted", "output"];
351
553
  function providerVisibleToolState(state) {
352
554
  const view = {};
@@ -389,20 +591,22 @@ function toolStateIsReduced(state) {
389
591
  }
390
592
  return true;
391
593
  }
392
- function providerVisiblePart(part) {
393
- if (!isRecord2(part) || part.type !== "tool" || !isRecord2(part.state))
394
- return part;
395
- if (toolStateIsReduced(part.state))
396
- return part;
397
- return { ...part, state: providerVisibleToolState(part.state) };
398
- }
399
594
  function providerVisibleMessage(message) {
595
+ return projectMessage(message, providerVisiblePart);
596
+ }
597
+ function providerVisibleMessageForTailHygiene(message) {
598
+ return projectMessage(message, providerVisiblePartForTailHygiene);
599
+ }
600
+ function providerVisibleMessageForOpenCode2(message) {
601
+ return projectMessage(message, providerVisiblePartForOpenCode2);
602
+ }
603
+ function projectMessage(message, projectPart) {
400
604
  if (!isRecord2(message) || !Array.isArray(message.parts))
401
605
  return message;
402
606
  let parts;
403
607
  for (let index = 0;index < message.parts.length; index += 1) {
404
608
  const part = message.parts[index];
405
- const view = providerVisiblePart(part);
609
+ const view = projectPart(part);
406
610
  if (view !== part) {
407
611
  parts ??= message.parts.slice(0, index);
408
612
  parts.push(view);
@@ -720,38 +924,40 @@ function isDropSentinel(content) {
720
924
  stripped = stripped.slice(tag[0].length).trimStart();
721
925
  return DROP_PREFIXES.some((prefix) => stripped.slice(0, prefix.length).toLowerCase() === prefix);
722
926
  }
723
- function toolOutputText(part) {
927
+ function toolOutputText(part, key) {
928
+ const serialize = (value) => partJsonMemo.get(key, value, () => safeStableStringify(value));
724
929
  if (part.type === "tool") {
725
930
  const state = isRecord(part.state) ? part.state : null;
726
931
  if (!state)
727
932
  return null;
728
933
  if (state.output !== undefined)
729
- return safeStableStringify(state.output);
934
+ return serialize(state.output);
730
935
  if (state.error !== undefined)
731
- return safeStableStringify(state.error);
936
+ return serialize(state.error);
732
937
  if (state.result !== undefined)
733
- return safeStableStringify(state.result);
938
+ return serialize(state.result);
734
939
  return null;
735
940
  }
736
941
  if (part.type === "tool_result") {
737
942
  const value = part.content ?? part.output ?? part.result;
738
- return value === undefined ? null : safeStableStringify(value);
943
+ return value === undefined ? null : serialize(value);
739
944
  }
740
945
  return null;
741
946
  }
742
- function toolInputText(part) {
947
+ function toolInputText(part, key) {
948
+ const serialize = (value) => partJsonMemo.get(key, value, () => safeStableStringify(value));
743
949
  if (part.type === "tool") {
744
950
  const state = isRecord(part.state) ? part.state : null;
745
951
  if (!state || state.input === undefined)
746
952
  return null;
747
- return safeStableStringify(state.input);
953
+ return serialize(state.input);
748
954
  }
749
955
  if (part.type === "tool-invocation") {
750
956
  const value = part.args ?? part.input;
751
- return value === undefined ? null : safeStableStringify(value);
957
+ return value === undefined ? null : serialize(value);
752
958
  }
753
959
  if (part.type === "tool_use") {
754
- return part.input === undefined ? null : safeStableStringify(part.input);
960
+ return part.input === undefined ? null : serialize(part.input);
755
961
  }
756
962
  return null;
757
963
  }
@@ -878,17 +1084,28 @@ function snapshot(args) {
878
1084
  queuedForDrop
879
1085
  };
880
1086
  }
1087
+ var partJsonMemo = new TailHygieneJsonMemo;
881
1088
  function excludedSnapshot(key, part) {
882
- const content = safeStableStringify(part);
883
- return snapshot({
1089
+ const contentHash = partJsonMemo.get(key, part, () => {
1090
+ if (part === null || part === undefined || typeof part === "string")
1091
+ return memoizedContent("excluded", safeStableStringify(part)).hash;
1092
+ try {
1093
+ return stableStringifyHash(part, "excluded\x00");
1094
+ } catch {
1095
+ return memoizedContent("excluded", String(part)).hash;
1096
+ }
1097
+ }, true);
1098
+ return {
884
1099
  key,
1100
+ contentHash,
885
1101
  kind: "excluded",
886
- content,
887
1102
  tokens: 0,
888
- tag: undefined,
889
- protectedNumbers: new Set,
890
- pendingDropTagNumbers: new Set
891
- });
1103
+ uTokens: 0,
1104
+ tagNumber: null,
1105
+ tagStatus: null,
1106
+ protected: false,
1107
+ queuedForDrop: false
1108
+ };
892
1109
  }
893
1110
  function fileContentAndTokens(part) {
894
1111
  const mime = typeof part.mime === "string" ? part.mime : "";
@@ -928,12 +1145,12 @@ function structuralSize(value) {
928
1145
  }
929
1146
  return 0;
930
1147
  }
931
- function tailHygieneStructuralSignature(messages) {
1148
+ function tailHygieneStructuralSignature(messages, opencode2 = false) {
932
1149
  const partCounts = [];
933
1150
  let totalBytes = 0;
934
1151
  for (const message of messages) {
935
1152
  partCounts.push(message.parts.length);
936
- totalBytes += structuralSize(providerVisibleMessage(message));
1153
+ totalBytes += structuralSize(opencode2 ? providerVisibleMessageForOpenCode2(message) : providerVisibleMessageForTailHygiene(message));
937
1154
  }
938
1155
  return { messageCount: messages.length, partCounts, totalBytes };
939
1156
  }
@@ -947,10 +1164,22 @@ function measureTailHygiene(input) {
947
1164
  return measureWithReplay(input);
948
1165
  }
949
1166
  function measureWithReplay(input, replay) {
1167
+ partJsonMemo.beginPass();
1168
+ const projectPart = input.opencode2 ? providerVisiblePartForOpenCode2 : providerVisiblePartForTailHygiene;
1169
+ const views = new WeakMap;
1170
+ const excluded = (key, part) => {
1171
+ let view = part !== null && typeof part === "object" ? views.get(part) : undefined;
1172
+ if (view === undefined) {
1173
+ view = projectPart(part);
1174
+ if (part !== null && typeof part === "object")
1175
+ views.set(part, view);
1176
+ }
1177
+ return excludedSnapshot(key, view);
1178
+ };
950
1179
  const pendingDropTagNumbers = input.pendingDropTagNumbers ?? new Set;
951
1180
  const unchanged = input.messages.map((message, index) => {
952
1181
  const previous = replay?.messages[index];
953
- return previous !== undefined && sameReplayMessage(previous, message);
1182
+ return previous !== undefined && sameReplayMessage(previous, message, projectPart);
954
1183
  });
955
1184
  const toolIdentities = collectToolPartIdentities(input.messages);
956
1185
  const attribution = buildTagAttribution({
@@ -960,7 +1189,7 @@ function measureWithReplay(input, replay) {
960
1189
  protectedTagNumbers: input.protectedTagNumbers,
961
1190
  protectedToolTags: input.protectedToolTags
962
1191
  });
963
- const toolOutputs = input.messages.map((message, index) => message.parts.map((part, partIndex) => unchanged[index] ? replay?.measured.toolOutputs[index][partIndex] ?? null : isRecord(part) ? toolOutputText(part) : null));
1192
+ const toolOutputs = input.messages.map((message, index) => message.parts.map((part, partIndex) => unchanged[index] ? replay?.measured.toolOutputs[index][partIndex] ?? null : isRecord(part) ? toolOutputText(part, `${messageIdentity(message, index)}\x00${partIndex}\x00output`) : null));
964
1193
  const outputByPart = new Map;
965
1194
  input.messages.forEach((message, index) => {
966
1195
  message.parts.forEach((part, partIndex) => {
@@ -1026,19 +1255,19 @@ function measureWithReplay(input, replay) {
1026
1255
  const part = message.parts[partIndex];
1027
1256
  const key = `${messageKey}\x00${partIndex}`;
1028
1257
  if (messageSynthetic || isSyntheticPart(part) || !isRecord(part)) {
1029
- parts.push(excludedSnapshot(`${key}\x00excluded`, part));
1258
+ parts.push(excluded(`${key}\x00excluded`, part));
1030
1259
  continue;
1031
1260
  }
1032
1261
  const type = typeof part.type === "string" ? part.type : "";
1033
1262
  if (type === "reasoning" || type === "thinking" || type === "redacted_thinking" || type === "signature") {
1034
- parts.push(excludedSnapshot(`${key}\x00excluded`, part));
1263
+ parts.push(excluded(`${key}\x00excluded`, part));
1035
1264
  continue;
1036
1265
  }
1037
1266
  if (type === "text") {
1038
1267
  const rawContent = firstString(part, ["text", "content"]);
1039
1268
  const content = rawContent === null ? null : stripChannel1ReminderSpans(rawContent);
1040
1269
  if (!content || isDropSentinel(content)) {
1041
- parts.push(excludedSnapshot(`${key}\x00excluded`, part));
1270
+ parts.push(excluded(`${key}\x00excluded`, part));
1042
1271
  continue;
1043
1272
  }
1044
1273
  const tokens = memoizedTokens("text", content);
@@ -1060,7 +1289,7 @@ function measureWithReplay(input, replay) {
1060
1289
  if (type === "file" || type.includes("image") || type === "source") {
1061
1290
  const file = fileContentAndTokens(part);
1062
1291
  if (!file.content || isDropSentinel(file.content)) {
1063
- parts.push(excludedSnapshot(`${key}\x00excluded`, part));
1292
+ parts.push(excluded(`${key}\x00excluded`, part));
1064
1293
  continue;
1065
1294
  }
1066
1295
  const tag = attribution.messageTags.get(`${message.info.id}:file${partIndex}`);
@@ -1082,11 +1311,11 @@ function measureWithReplay(input, replay) {
1082
1311
  if (toolIdentity) {
1083
1312
  const ownerKey = `${toolIdentity.ownerMessageId}\x00${toolIdentity.callId}`;
1084
1313
  if (droppedToolOwners.has(ownerKey)) {
1085
- parts.push(excludedSnapshot(`${key}\x00excluded`, part));
1314
+ parts.push(excluded(`${key}\x00excluded`, part));
1086
1315
  continue;
1087
1316
  }
1088
1317
  const tag = attribution.toolTagsByPart.get(part);
1089
- const inputText = toolInputText(part);
1318
+ const inputText = toolInputText(part, `${key}\x00input`);
1090
1319
  if (inputText !== null) {
1091
1320
  const tokens = memoizedTokens("toolInput", inputText);
1092
1321
  const measured = snapshot({
@@ -1106,7 +1335,7 @@ function measureWithReplay(input, replay) {
1106
1335
  if (rawOutput !== null) {
1107
1336
  const output = stripChannel1ReminderSpans(rawOutput);
1108
1337
  if (isDropSentinel(output)) {
1109
- parts.push(excludedSnapshot(`${key}\x00excludedOutput`, output));
1338
+ parts.push(excluded(`${key}\x00excludedOutput`, output));
1110
1339
  } else {
1111
1340
  const tokens = memoizedTokens("toolOutput", output) + (part.type === "tool" ? estimateToolAttachmentImageTokens(part.state) : 0);
1112
1341
  const measured = snapshot({
@@ -1124,11 +1353,11 @@ function measureWithReplay(input, replay) {
1124
1353
  }
1125
1354
  }
1126
1355
  if (inputText === null && rawOutput === null) {
1127
- parts.push(excludedSnapshot(`${key}\x00excluded`, part));
1356
+ parts.push(excluded(`${key}\x00excluded`, part));
1128
1357
  }
1129
1358
  continue;
1130
1359
  }
1131
- parts.push(excludedSnapshot(`${key}\x00excluded`, part));
1360
+ parts.push(excluded(`${key}\x00excluded`, part));
1132
1361
  }
1133
1362
  }
1134
1363
  return {
@@ -1269,19 +1498,19 @@ function sameNumbers(before, after) {
1269
1498
  return false;
1270
1499
  return true;
1271
1500
  }
1272
- function sameReplayMessage(left, right) {
1273
- return left.info.id === right.info.id && left.info.role === right.info.role && left.info.summary === right.info.summary && sameReplayValue(left.parts, right.parts.map(providerVisiblePart));
1501
+ function sameReplayMessage(left, right, projectPart = providerVisiblePartForTailHygiene) {
1502
+ return left.info.id === right.info.id && left.info.role === right.info.role && left.info.summary === right.info.summary && sameReplayValue(left.parts, right.parts.map(projectPart));
1274
1503
  }
1275
- function replaySnapshotParts(parts) {
1276
- return copyReplayValue(parts.map(providerVisiblePart));
1504
+ function replaySnapshotParts(parts, projectPart = providerVisiblePartForTailHygiene) {
1505
+ return copyReplayValue(parts.map(projectPart));
1277
1506
  }
1278
- function sameReplayMessages(before, after) {
1507
+ function sameReplayMessages(before, after, projectPart = providerVisiblePartForTailHygiene) {
1279
1508
  if (before.length !== after.length)
1280
1509
  return false;
1281
1510
  for (let index = 0;index < before.length; index += 1) {
1282
1511
  const left = before[index];
1283
1512
  const right = after[index];
1284
- if (!sameReplayMessage(left, right))
1513
+ if (!sameReplayMessage(left, right, projectPart))
1285
1514
  return false;
1286
1515
  }
1287
1516
  return true;
@@ -1340,8 +1569,10 @@ function refreshTailHygieneBaseline(input) {
1340
1569
  protectedTagNumbers: new Set([...input.protectedTagNumbers, ...protectedToolTags])
1341
1570
  };
1342
1571
  const pendingDropTagNumbers = input.pendingDropTagNumbers ?? new Set;
1343
- const cached = input.previous ? baselineMeasurementMemo.get(input.previous.baselineParts) : undefined;
1344
- const hit = !input.cacheBusting && cached && sameReplayMessages(cached.messages, input.messages) && sameReplayValue(cached.tags, input.tags) && sameNumbers(cached.protectedTagNumbers, input.protectedTagNumbers) && sameNumbers(cached.pendingDropTagNumbers, pendingDropTagNumbers);
1572
+ const priorMemo = input.previous ? baselineMeasurementMemo.get(input.previous.baselineParts) : undefined;
1573
+ const cached = priorMemo?.opencode2 === !!input.opencode2 ? priorMemo : undefined;
1574
+ const projectPart = input.opencode2 ? providerVisiblePartForOpenCode2 : providerVisiblePartForTailHygiene;
1575
+ const hit = !input.cacheBusting && cached && sameReplayMessages(cached.messages, input.messages, projectPart) && sameReplayValue(cached.tags, input.tags) && sameNumbers(cached.protectedTagNumbers, input.protectedTagNumbers) && sameNumbers(cached.pendingDropTagNumbers, pendingDropTagNumbers);
1345
1576
  const rawMeasured = hit ? cached.measured : measureWithReplay(input, cached);
1346
1577
  const frozenCalibration = !input.cacheBusting && input.previous ? {
1347
1578
  toolsRatio: input.previous.toolsRatio,
@@ -1361,19 +1592,20 @@ function refreshTailHygieneBaseline(input) {
1361
1592
  })
1362
1593
  };
1363
1594
  const memo = hit ? cached : {
1364
- messages: input.messages.map((message, index) => cached?.messages[index] && sameReplayMessage(cached.messages[index], message) ? cached.messages[index] : {
1595
+ opencode2: !!input.opencode2,
1596
+ messages: input.messages.map((message, index) => cached?.messages[index] && sameReplayMessage(cached.messages[index], message, projectPart) ? cached.messages[index] : {
1365
1597
  info: {
1366
1598
  id: message.info.id,
1367
1599
  role: message.info.role,
1368
1600
  summary: message.info.summary
1369
1601
  },
1370
- parts: replaySnapshotParts(message.parts)
1602
+ parts: replaySnapshotParts(message.parts, projectPart)
1371
1603
  }),
1372
1604
  tags: structuredClone(input.tags),
1373
1605
  protectedTagNumbers: new Set(input.protectedTagNumbers),
1374
1606
  pendingDropTagNumbers: new Set(pendingDropTagNumbers),
1375
1607
  measured: rawMeasured,
1376
- size: 2 * structuralSize(input.messages.map(providerVisibleMessage)) + 512 * input.tags.length
1608
+ size: 2 * structuralSize(input.messages.map(input.opencode2 ? providerVisibleMessageForOpenCode2 : providerVisibleMessageForTailHygiene)) + 512 * input.tags.length
1377
1609
  };
1378
1610
  if (!hit) {
1379
1611
  const owners = new Map;
@@ -1390,7 +1622,7 @@ function refreshTailHygieneBaseline(input) {
1390
1622
  const refrozen = (mismatch) => {
1391
1623
  const frozen = freezeTailHygieneMeasurement(measured);
1392
1624
  retainBaselineMeasurement(frozen.baselineParts, memo);
1393
- return {
1625
+ return rememberCurrentToolOutputCount({
1394
1626
  ...frozen,
1395
1627
  protectedToolsPolicy,
1396
1628
  hygieneUnitsVersion: frozenCalibration.hygieneUnitsVersion,
@@ -1403,7 +1635,7 @@ function refreshTailHygieneBaseline(input) {
1403
1635
  contentSignature: measured.contentSignature,
1404
1636
  channel1PostReduceGrace: input.previous?.channel1PostReduceGrace,
1405
1637
  lastPrefixMismatch: mismatch
1406
- };
1638
+ }, measured);
1407
1639
  };
1408
1640
  if (input.cacheBusting || !input.previous)
1409
1641
  return refrozen();
@@ -1419,7 +1651,7 @@ function refreshTailHygieneBaseline(input) {
1419
1651
  if (part.kind !== "toolOutput" || !part.protected)
1420
1652
  turnDeltaU += part.uTokens;
1421
1653
  }
1422
- return {
1654
+ return rememberCurrentToolOutputCount({
1423
1655
  ...input.previous,
1424
1656
  protectedToolsPolicy,
1425
1657
  turnDeltaU,
@@ -1428,7 +1660,7 @@ function refreshTailHygieneBaseline(input) {
1428
1660
  generationInvalidated: false,
1429
1661
  contentSignature: measured.contentSignature,
1430
1662
  lastPrefixMismatch: undefined
1431
- };
1663
+ }, measured);
1432
1664
  }
1433
1665
  function effectiveTailHygiene(baseline) {
1434
1666
  const t = Math.ceil(Math.max(0, baseline.baselineT + baseline.turnDeltaT));
@@ -1699,9 +1931,6 @@ function formatOldestReclaimableHint(hint) {
1699
1931
  return rendered.length > 0 ? `
1700
1932
  oldest reclaimable: ${rendered}.` : "";
1701
1933
  }
1702
- function reclaimableToolOutputCount(parts) {
1703
- return parts.filter((part) => part.kind === "toolOutput" && part.uTokens > 0).length;
1704
- }
1705
1934
  function formatReclaimableOutputSummary(count, tokens) {
1706
1935
  const outputCount = Math.max(0, Math.floor(count));
1707
1936
  const outputs = outputCount === 0 ? "spent tool outputs" : `${outputCount} spent tool output${outputCount === 1 ? "" : "s"}`;
@@ -3604,4 +3833,4 @@ function deleteToolTagsByOwner(db, sessionId, ownerMsgId) {
3604
3833
  return getDeleteToolTagsByOwnerStatement(db).all(sessionId, ownerMsgId).length;
3605
3834
  }
3606
3835
 
3607
- export { protectedToolTagNumbers, protectedToolTokenCount, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isThinkingPart, isRecord, contentTagOwnerMessageId, estimateImageTokensFromDataUrl, estimateToolAttachmentImageTokens, providerVisiblePart, providerVisibleMessage, normalizeTodoStateJson, buildSyntheticTodoPart, computeSyntheticCallId, isSyntheticTodoPart, countRealUserMessages, tailHygieneStructuralSignature, sameTailHygieneStructuralSignature, formatTailHygienePrefixMismatch, refreshTailHygieneBaseline, effectiveTailHygiene, assertTailHygieneContentUnchangedIfEnabled, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, isDroppedToolOutput, toolOutputTokens, decideChannel1, evaluateChannel2, formatChannel1Evaluation, formatChannel2Evaluation, reclaimableToolOutputCount, buildChannel2Reminder, buildChannel1Reminder, estimateEmergencyDropReclaimTokens, planEmergencyDrop, measureEmergencyTag, queuePendingOp, queuePendingDropForUnchangedTag, getPendingOps, hasPendingDropOps, getPendingOpsCount, clearPendingOps, removePendingOp, getRecentTagOwnerMessageIds2, getActiveTagTokenAggregate2, AGE_RECLAIM_MIN_TOKENS2, getOldestActiveUnprotectedToolTags2, getActiveToolTagsForAgeReclaim2, getTriggerTagTokenUpperBound2, getActiveTagTokenTotalsByMessage2, getPersistedToolTagAccounting2, getAllStatusTagTokenTotalsFlat2, getReasoningTokenEstimatesByMessage2, tryGetReasoningTokenEstimatesByMessage2, getMaxTagNumberByOwnerMessage2, scanTagOwnerSummary2, cachedTagOwnerRatios2, tagOwnerWarmupState2, scanTagOwnerDelta2, installTagOwnerDelta2, installTagOwnerSummary2, isTagOwnerSummaryReady2, tagTokenCountIsNull2, backfillTagTokenCounts2, insertTag2, updateTagStatus2, markWhitespaceAssistantTagInert2, getInertWhitespaceAssistantTags2, getInertWhitespaceAssistantTagsByNumbers2, updateTagDropMode2, updateCavemanDepth2, updateTagMessageId2, hasPiFallbackMessageTags2, findAdoptableFallbackTags2, adoptFallbackTagMessageId2, foldShrunkPartTags2, hasPiFallbackToolOwnerTags2, findPiFallbackToolOwnerTags2, adoptPiFallbackToolOwnerTag2, adoptPiFallbackMessageTag2, markTagsCompactedByMessageIds2, deleteTagsByMessageId2, getMaxTagNumberBySession2, getTagNumberByMessageId2, getAssignableTagNumberByMessageId2, getMinMessageTagNumberForRawId2, deriveTagLoadFloor2, TAG_SELECT_COLUMNS2, getTagsBySession2, getActiveTagsBySession2, getTailHygieneTags2, getDroppedTagsBySession2, getTagsForPendingOperations2, getTagsByNumbers2, getNewestToolTagNumbers2, getDroppedTagsByNumbers2, getMaxDroppedTagNumber2, getTagById2, getTopNBySize2, getToolTagNumberByOwner2, getNullOwnerToolTag2, adoptNullOwnerToolTag2, getCandidateToolOwners2, pickNearestPriorOwner2 };
3836
+ export { protectedToolTagNumbers, protectedToolTokenCount, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isThinkingPart, currentReclaimableToolOutputCount, isRecord, contentTagOwnerMessageId, estimateImageTokensFromDataUrl, estimateToolAttachmentImageTokens, providerVisiblePart, providerVisibleMessage, normalizeTodoStateJson, buildSyntheticTodoPart, computeSyntheticCallId, isSyntheticTodoPart, countRealUserMessages, tailHygieneStructuralSignature, sameTailHygieneStructuralSignature, formatTailHygienePrefixMismatch, refreshTailHygieneBaseline, effectiveTailHygiene, assertTailHygieneContentUnchangedIfEnabled, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, isDroppedToolOutput, toolOutputTokens, decideChannel1, evaluateChannel2, formatChannel1Evaluation, formatChannel2Evaluation, buildChannel2Reminder, buildChannel1Reminder, estimateEmergencyDropReclaimTokens, planEmergencyDrop, measureEmergencyTag, queuePendingOp, queuePendingDropForUnchangedTag, getPendingOps, hasPendingDropOps, getPendingOpsCount, clearPendingOps, removePendingOp, getRecentTagOwnerMessageIds2, getActiveTagTokenAggregate2, AGE_RECLAIM_MIN_TOKENS2, getOldestActiveUnprotectedToolTags2, getActiveToolTagsForAgeReclaim2, getTriggerTagTokenUpperBound2, getActiveTagTokenTotalsByMessage2, getPersistedToolTagAccounting2, getAllStatusTagTokenTotalsFlat2, getReasoningTokenEstimatesByMessage2, tryGetReasoningTokenEstimatesByMessage2, getMaxTagNumberByOwnerMessage2, scanTagOwnerSummary2, cachedTagOwnerRatios2, tagOwnerWarmupState2, scanTagOwnerDelta2, installTagOwnerDelta2, installTagOwnerSummary2, isTagOwnerSummaryReady2, tagTokenCountIsNull2, backfillTagTokenCounts2, insertTag2, updateTagStatus2, markWhitespaceAssistantTagInert2, getInertWhitespaceAssistantTags2, getInertWhitespaceAssistantTagsByNumbers2, updateTagDropMode2, updateCavemanDepth2, updateTagMessageId2, hasPiFallbackMessageTags2, findAdoptableFallbackTags2, adoptFallbackTagMessageId2, foldShrunkPartTags2, hasPiFallbackToolOwnerTags2, findPiFallbackToolOwnerTags2, adoptPiFallbackToolOwnerTag2, adoptPiFallbackMessageTag2, markTagsCompactedByMessageIds2, deleteTagsByMessageId2, getMaxTagNumberBySession2, getTagNumberByMessageId2, getAssignableTagNumberByMessageId2, getMinMessageTagNumberForRawId2, deriveTagLoadFloor2, TAG_SELECT_COLUMNS2, getTagsBySession2, getActiveTagsBySession2, getTailHygieneTags2, getDroppedTagsBySession2, getTagsForPendingOperations2, getTagsByNumbers2, getNewestToolTagNumbers2, getDroppedTagsByNumbers2, getMaxDroppedTagNumber2, getTagById2, getTopNBySize2, getToolTagNumberByOwner2, getNullOwnerToolTag2, adoptNullOwnerToolTag2, getCandidateToolOwners2, pickNearestPriorOwner2 };
@@ -63,20 +63,20 @@ import {
63
63
  sanitizeFtsQuery,
64
64
  searchMemoriesFTS,
65
65
  searchMemoriesFTSUnion
66
- } from "./index-ydjgz36f.js";
66
+ } from "./index-16vwdyy5.js";
67
67
  import {
68
68
  isRecord
69
- } from "./index-xpn05jxq.js";
69
+ } from "./index-f8cn4xqa.js";
70
70
  import {
71
71
  getIndexedMessageCorpusSize2
72
- } from "./index-b4gcb3rk.js";
72
+ } from "./index-0x9cn9w1.js";
73
73
  import {
74
74
  resolveWorkspaceShareCategories,
75
75
  resolveWorkspaceIdentitySet,
76
76
  expandWorkspaceIdentitySetWithAliases,
77
77
  resolveStoredPathWorkspaceIdentity,
78
78
  sourceNameForMemory
79
- } from "./index-qgp5vnt4.js";
79
+ } from "./index-a865mj02.js";
80
80
  import {
81
81
  isKnownAutocommit
82
82
  } from "./index-8ajstryz.js";