@retaw106/mmc-oc 2.4.0 → 2.6.0
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.
- package/dist/{context-c72brxe5.js → context-cfbjrr0n.js} +1636 -513
- package/dist/features/magic-context/compaction-marker.d.ts +34 -6
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +6 -2
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +0 -26
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +5 -1
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-decision-calibration.d.ts.map +1 -1
- package/dist/features/magic-context/session-retention.fixture.d.ts +4 -0
- package/dist/features/magic-context/session-retention.fixture.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts +2 -0
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-host-instruction-retention.d.ts +4 -0
- package/dist/features/magic-context/storage-host-instruction-retention.d.ts.map +1 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts +21 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-shared.d.ts +2 -2
- package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
- package/dist/features/magic-context/storage-native-replay.d.ts +2 -0
- package/dist/features/magic-context/storage-native-replay.d.ts.map +1 -1
- package/dist/features/magic-context/storage-session-tables.d.ts +5 -4
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/features/magic-context/tool-definition-tokens.d.ts +113 -58
- package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
- package/dist/features/magic-context/work-metrics.d.ts +5 -3
- package/dist/features/magic-context/work-metrics.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +32 -0
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/ask-answer-notice.d.ts +25 -0
- package/dist/hooks/magic-context/ask-answer-notice.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts +3 -0
- package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +5 -5
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-publication.d.ts +14 -0
- package/dist/hooks/magic-context/compaction-marker-publication.d.ts.map +1 -0
- package/dist/hooks/magic-context/compaction-off-transition.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -2
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +11 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/diagnostic-log-state.d.ts +4 -0
- package/dist/hooks/magic-context/diagnostic-log-state.d.ts.map +1 -0
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/file-token-coverage.d.ts +11 -0
- package/dist/hooks/magic-context/file-token-coverage.d.ts.map +1 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +11 -3
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-history-wait.d.ts +16 -0
- package/dist/hooks/magic-context/historian-history-wait.d.ts.map +1 -0
- package/dist/hooks/magic-context/history-boundary-repair.d.ts +1 -1
- package/dist/hooks/magic-context/history-boundary-repair.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/host-served-rows.d.ts +10 -0
- package/dist/hooks/magic-context/host-served-rows.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-measured-request.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-recovery-fence.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts +3 -1
- package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +3 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/nudge-evaluation-log.d.ts +3 -0
- package/dist/hooks/magic-context/nudge-evaluation-log.d.ts.map +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts +2 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
- package/dist/hooks/magic-context/pending-drop-eligibility.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +2 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +8 -2
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +20 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +3 -3
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/signed-thinking-fit-snapshot.d.ts +42 -0
- package/dist/hooks/magic-context/signed-thinking-fit-snapshot.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-date-refresh.d.ts +3 -2
- package/dist/hooks/magic-context/system-date-refresh.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts +4 -0
- package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts.map +1 -0
- package/dist/hooks/magic-context/tag-content-primitives.d.ts +1 -1
- package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +17 -2
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/text-complete.d.ts +1 -1
- package/dist/hooks/magic-context/text-complete.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +3 -2
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +1 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +6 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-stage-logger.d.ts +3 -0
- package/dist/hooks/magic-context/transform-stage-logger.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +4 -2
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-27ddyx39.js → index-1np16gxq.js} +1 -1
- package/dist/{index-ykq24x1n.js → index-8rmt6s4f.js} +78 -32
- package/dist/{index-dwh99z66.js → index-pte3cfs9.js} +194 -5
- package/dist/{index-r7s7d350.js → index-s3ebcy63.js} +1 -1
- package/dist/{index-48e9znrc.js → index-t0zx3tgz.js} +481 -109
- package/dist/{index-kahkxcqw.js → index-xk1dz6q9.js} +870 -315
- package/dist/index.js +2 -2
- package/dist/{message-time-backfill-j96x1sab.js → message-time-backfill-g9py24yt.js} +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/subagent-tool-policy.d.ts +4 -0
- package/dist/plugin/subagent-tool-policy.d.ts.map +1 -1
- package/dist/{read-session-chunk-t8bg6wkz.js → read-session-chunk-2s8x6xps.js} +3 -3
- package/dist/{recomp-orchestrator-k760qy1n.js → recomp-orchestrator-51xyaexp.js} +6 -6
- package/dist/{send-session-notification-njjf3b4s.js → send-session-notification-vdppp5x6.js} +3 -3
- package/dist/shared/model-suggestion-retry.d.ts +2 -0
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/rpc-discovery-cleanup.d.ts +3 -0
- package/dist/shared/rpc-discovery-cleanup.d.ts.map +1 -0
- package/dist/shared/rpc-server.d.ts +2 -0
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/search-text.d.ts +8 -0
- package/dist/shared/search-text.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +6 -1
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/storage-file-mutex.d.ts.map +1 -1
- package/dist/shared/system-directive.d.ts +2 -0
- package/dist/shared/system-directive.d.ts.map +1 -1
- package/dist/shared/tag-transcript.d.ts +2 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/shared/transcript.d.ts +3 -1
- package/dist/shared/transcript.d.ts.map +1 -1
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/parameter-descriptions.d.ts +6 -6
- package/dist/tools/parameter-descriptions.d.ts.map +1 -1
- package/dist/v2/fold/native-replay.d.ts +11 -2
- package/dist/v2/fold/native-replay.d.ts.map +1 -1
- package/dist/v2/fold/policy.d.ts.map +1 -1
- package/dist/v2/fold/restore.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts +4 -0
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/generate.d.ts +36 -1
- package/dist/v2/hooks/generate.d.ts.map +1 -1
- package/dist/v2/hooks/lkg-system.d.ts +35 -4
- package/dist/v2/hooks/lkg-system.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts +10 -1
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/store.d.ts +2 -0
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/hooks/types.d.ts +12 -0
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/message-times.d.ts +17 -0
- package/dist/v2/message-times.d.ts.map +1 -0
- package/dist/v2/server.js +4692 -2394
- package/dist/v2/store-reader.d.ts +21 -0
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/web/main.js +307 -12
- package/dist/{wrapup-orchestrator-b2gswatj.js → wrapup-orchestrator-g0mww1h4.js} +6 -6
- package/package.json +1 -1
- package/src/config/latch-permanence-guard.test.ts +4 -5
- package/src/shared/model-suggestion-retry.test.ts +52 -0
- package/src/shared/model-suggestion-retry.ts +8 -3
- package/src/shared/prompt-surface-a1-golden.md +6 -7
- package/src/shared/rpc-discovery-cleanup.test.ts +125 -0
- package/src/shared/rpc-discovery-cleanup.ts +57 -0
- package/src/shared/rpc-server.ts +36 -13
- package/src/shared/search-text.test.ts +30 -0
- package/src/shared/search-text.ts +62 -0
- package/src/shared/sqlite-transaction-mode-guard.test.ts +2 -0
- package/src/shared/sqlite-turn-deadline.test.ts +286 -0
- package/src/shared/sqlite.ts +237 -9
- package/src/shared/storage-file-mutex.test.ts +51 -2
- package/src/shared/storage-file-mutex.ts +11 -1
- package/src/shared/system-directive.test.ts +37 -0
- package/src/shared/system-directive.ts +19 -1
- package/src/shared/tag-transcript.ts +63 -8
- package/src/shared/transcript.ts +1 -1
- package/src/shared/write-transaction-attribution.test.ts +1 -6
- package/dist/features/magic-context/message-index-sweep.d.ts +0 -11
- package/dist/features/magic-context/message-index-sweep.d.ts.map +0 -1
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import { removeNestedBlocks, removeSystemReminders } from "./system-directive";
|
|
3
|
+
|
|
4
|
+
describe("removeSystemReminders", () => {
|
|
5
|
+
test("removes nested reminders without leaking the outer tail", () => {
|
|
6
|
+
expect(
|
|
7
|
+
removeSystemReminders(
|
|
8
|
+
"before <system-reminder>outer <system-reminder>inner</system-reminder> tail</system-reminder> after",
|
|
9
|
+
),
|
|
10
|
+
).toBe("before after");
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
test("removes unclosed reminders through the end", () => {
|
|
14
|
+
expect(
|
|
15
|
+
removeSystemReminders(
|
|
16
|
+
" keep <system-reminder>hidden <system-reminder>nested</system-reminder> tail",
|
|
17
|
+
),
|
|
18
|
+
).toBe("keep");
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("handles attributes, case, self-closing tags and adjacent blocks", () => {
|
|
22
|
+
expect(
|
|
23
|
+
removeSystemReminders(
|
|
24
|
+
'a<SYSTEM-REMINDER id="x">hidden</SYSTEM-REMINDER><system-reminder/>b<system-reminder>hidden</system-reminder>c',
|
|
25
|
+
),
|
|
26
|
+
).toBe("abc");
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
test("preserves ordinary content and other tags", () => {
|
|
30
|
+
expect(removeSystemReminders(" <other>visible</other> ")).toBe("<other>visible</other>");
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test("removeNestedBlocks tracks multiple tag names and only closes the matching top", () => {
|
|
35
|
+
expect(removeNestedBlocks("a<one>x<two>y</one>z</two>tail</one>b", ["one", "two"])).toBe("ab");
|
|
36
|
+
expect(removeNestedBlocks(" a<one/>b ", ["one"])).toBe(" ab ");
|
|
37
|
+
});
|
|
@@ -5,5 +5,23 @@ export function isSystemDirective(text: string): boolean {
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
export function removeSystemReminders(text: string): string {
|
|
8
|
-
return text
|
|
8
|
+
return removeNestedBlocks(text, ["system-reminder"]).trim();
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
/** Remove matching tagged regions, including nested regions and regions with no closing tag. */
|
|
12
|
+
export function removeNestedBlocks(text: string, names: readonly string[]): string {
|
|
13
|
+
const tags = new RegExp(`<(/?)(${names.join("|")})(?:\\s[^<>]*?)?\\s*(/?)>`, "gi");
|
|
14
|
+
const stack: string[] = [];
|
|
15
|
+
let end = 0;
|
|
16
|
+
let result = "";
|
|
17
|
+
for (const match of text.matchAll(tags)) {
|
|
18
|
+
if (stack.length === 0) result += text.slice(end, match.index);
|
|
19
|
+
const name = match[2].toLowerCase();
|
|
20
|
+
if (match[1]) {
|
|
21
|
+
if (stack[stack.length - 1] === name) stack.pop();
|
|
22
|
+
} else if (!match[3]) stack.push(name);
|
|
23
|
+
end = match.index + match[0].length;
|
|
24
|
+
}
|
|
25
|
+
if (stack.length === 0) result += text.slice(end);
|
|
26
|
+
return result;
|
|
9
27
|
}
|
|
@@ -75,6 +75,8 @@ import type { Transcript, TranscriptMessage, TranscriptPart } from "./transcript
|
|
|
75
75
|
export { TEXT_TAG_IDENTITY_MARKER };
|
|
76
76
|
|
|
77
77
|
export interface TagTranscriptOptions {
|
|
78
|
+
/** Independently validated text sources; does not authorize tool accounting reuse. */
|
|
79
|
+
reuseTextMessageIds?: ReadonlySet<string>;
|
|
78
80
|
/**
|
|
79
81
|
* When true, skip injecting `§N§` prefix into visible text. Tags
|
|
80
82
|
* still get assigned in the DB so historian/drops can reference
|
|
@@ -305,6 +307,12 @@ interface ToolAggregate {
|
|
|
305
307
|
maxByteSize: number;
|
|
306
308
|
/** Token count paired with maxByteSize (the same output occurrence). */
|
|
307
309
|
maxTokenCount: number;
|
|
310
|
+
/**
|
|
311
|
+
* Whether maxTokenCount is a real count. Legacy rows can store bytes with a
|
|
312
|
+
* NULL token_count; seeding 0 from that must not look like a stored count,
|
|
313
|
+
* or unchanged results would never be recounted.
|
|
314
|
+
*/
|
|
315
|
+
tokenCountKnown: boolean;
|
|
308
316
|
/** Tool name from the first occurrence we see one on. */
|
|
309
317
|
toolName: string | null;
|
|
310
318
|
/** Input byte size from the invocation occurrence (for storage projection). */
|
|
@@ -417,7 +425,10 @@ export function tagTranscript(
|
|
|
417
425
|
targets,
|
|
418
426
|
skipPrefixInjection,
|
|
419
427
|
entryFingerprint: options.entryFingerprintByMessageId?.get(messageId) ?? null,
|
|
420
|
-
reuseIdentity:
|
|
428
|
+
reuseIdentity:
|
|
429
|
+
reuseIdentity ||
|
|
430
|
+
options.reuseTextMessageIds?.has(messageId) === true ||
|
|
431
|
+
contentDerivedTextIds !== undefined,
|
|
421
432
|
timing,
|
|
422
433
|
textIdentitySourceCache: options.textIdentitySourceCache,
|
|
423
434
|
textTokenCache: options.textTokenCache,
|
|
@@ -508,6 +519,13 @@ export function tagTranscript(
|
|
|
508
519
|
timing,
|
|
509
520
|
options.toolTokenCache,
|
|
510
521
|
tokenCacheKey,
|
|
522
|
+
{
|
|
523
|
+
byteSize: existing.maxByteSize,
|
|
524
|
+
tokenCount: existing.tokenCountKnown
|
|
525
|
+
? existing.maxTokenCount
|
|
526
|
+
: null,
|
|
527
|
+
inputTokenCount: existing.inputTokenCount,
|
|
528
|
+
},
|
|
511
529
|
);
|
|
512
530
|
text = accounting.text;
|
|
513
531
|
if (part.kind === "tool_result") {
|
|
@@ -596,6 +614,7 @@ export function tagTranscript(
|
|
|
596
614
|
// genuinely larger folded result can still bump accounting.
|
|
597
615
|
maxByteSize: reusableAccounting.byteSize,
|
|
598
616
|
maxTokenCount: reusableAccounting.tokenCount ?? 0,
|
|
617
|
+
tokenCountKnown: reusableAccounting.tokenCount !== null,
|
|
599
618
|
toolName: null,
|
|
600
619
|
inputByteSize: reusableAccounting.inputByteSize,
|
|
601
620
|
inputTokenCount: reusableAccounting.inputTokenCount,
|
|
@@ -623,6 +642,7 @@ export function tagTranscript(
|
|
|
623
642
|
timing,
|
|
624
643
|
options.toolTokenCache,
|
|
625
644
|
tokenCacheKey,
|
|
645
|
+
tagger.getToolTagAccounting(sessionId, callId, messageId),
|
|
626
646
|
);
|
|
627
647
|
text = accounting.text;
|
|
628
648
|
const outputByteSize = part.kind === "tool_result" ? accounting.byteSize : 0;
|
|
@@ -657,6 +677,11 @@ export function tagTranscript(
|
|
|
657
677
|
occurrences: [{ message, part, kind: part.kind }],
|
|
658
678
|
maxByteSize: persistedAccounting?.byteSize ?? outputByteSize,
|
|
659
679
|
maxTokenCount: persistedAccounting?.tokenCount ?? outputTokenCount,
|
|
680
|
+
// A fresh allocation just wrote outputTokenCount (0 for an
|
|
681
|
+
// invocation); an existing row keeps its NULL as unknown.
|
|
682
|
+
tokenCountKnown: persistedAccounting
|
|
683
|
+
? persistedAccounting.tokenCount !== null
|
|
684
|
+
: true,
|
|
660
685
|
toolName: accounting.toolName,
|
|
661
686
|
inputByteSize:
|
|
662
687
|
persistedAccounting?.inputByteSize ??
|
|
@@ -745,7 +770,9 @@ function syncToolAggregateAccounting(
|
|
|
745
770
|
): void {
|
|
746
771
|
tagger.setToolTagAccounting(sessionId, aggregate.tagId, {
|
|
747
772
|
byteSize: aggregate.maxByteSize,
|
|
748
|
-
|
|
773
|
+
// Unknown stays unknown so the next occurrence/pass recounts instead of
|
|
774
|
+
// caching a fabricated 0 for a legacy row.
|
|
775
|
+
tokenCount: aggregate.tokenCountKnown ? aggregate.maxTokenCount : null,
|
|
749
776
|
inputByteSize: aggregate.inputByteSize,
|
|
750
777
|
inputTokenCount: aggregate.inputTokenCount,
|
|
751
778
|
});
|
|
@@ -770,6 +797,7 @@ function applyGrownToolResultAccounting(args: GrownToolResultAccountingArgs): vo
|
|
|
770
797
|
}
|
|
771
798
|
args.aggregate.maxByteSize = args.byteSize;
|
|
772
799
|
args.aggregate.maxTokenCount = tokenCount;
|
|
800
|
+
args.aggregate.tokenCountKnown = true;
|
|
773
801
|
updateTagByteSize(args.db, args.sessionId, args.aggregate.tagId, args.byteSize);
|
|
774
802
|
updateTagTokenCount(args.db, args.sessionId, args.aggregate.tagId, tokenCount);
|
|
775
803
|
syncToolAggregateAccounting(args.tagger, args.sessionId, args.aggregate);
|
|
@@ -780,12 +808,22 @@ function readAggregateToolAccounting(
|
|
|
780
808
|
timing: TagTranscriptTiming | undefined,
|
|
781
809
|
tokenCache?: Map<string, { text: string; tokenCount: number }>,
|
|
782
810
|
tokenCacheKey?: string,
|
|
811
|
+
persisted?: { byteSize: number; tokenCount: number | null; inputTokenCount: number | null },
|
|
783
812
|
): AggregateToolAccounting {
|
|
784
813
|
const text = part.getText() ?? "";
|
|
785
814
|
const byteSize = getToolPartByteSize(part, text);
|
|
786
|
-
|
|
815
|
+
// Persisted tool-result accounting tracks the largest byte size seen. Skip
|
|
816
|
+
// output tokenization when that size has not grown and a count is stored;
|
|
817
|
+
// known input counts also need no tokenization. Growth and missing counts still take
|
|
818
|
+
// the original counting path, even when the identity was not reusable.
|
|
819
|
+
const metadata = part.getToolMetadata({
|
|
820
|
+
skipInputTokenCount: persisted?.inputTokenCount != null,
|
|
821
|
+
});
|
|
787
822
|
let tokenCount = 0;
|
|
788
|
-
if (
|
|
823
|
+
if (
|
|
824
|
+
part.kind === "tool_result" &&
|
|
825
|
+
(!persisted || persisted.tokenCount === null || byteSize > persisted.byteSize)
|
|
826
|
+
) {
|
|
789
827
|
const tokenStart = timing ? performance.now() : 0;
|
|
790
828
|
tokenCount = getCachedToolPartTokenCount(part, text, tokenCache, tokenCacheKey);
|
|
791
829
|
if (timing) timing.tokenCounting += performance.now() - tokenStart;
|
|
@@ -835,12 +873,17 @@ class ConversationEndGuard {
|
|
|
835
873
|
}
|
|
836
874
|
}
|
|
837
875
|
|
|
838
|
-
wouldStrand(
|
|
876
|
+
wouldStrand(
|
|
877
|
+
occurrences: readonly ToolOccurrence[],
|
|
878
|
+
plannedRemovals?: ReadonlySet<unknown>,
|
|
879
|
+
): boolean {
|
|
839
880
|
const end = this.end;
|
|
840
881
|
if (!end || !occurrences.some((occ) => occ.message === end)) return false;
|
|
841
882
|
const leaving = new Set(occurrences.map((occ) => partKey(occ.part)));
|
|
842
883
|
const survives = (part: TranscriptPart) =>
|
|
843
|
-
!leaving.has(partKey(part)) &&
|
|
884
|
+
!leaving.has(partKey(part)) &&
|
|
885
|
+
!this.removed.has(partKey(part)) &&
|
|
886
|
+
!plannedRemovals?.has(partKey(part));
|
|
844
887
|
return end.info.role === "assistant"
|
|
845
888
|
? !end.parts.some((part) => part.kind === "tool_result" && survives(part))
|
|
846
889
|
: !end.parts.some((part) => partHasContent(part) && survives(part));
|
|
@@ -1379,8 +1422,11 @@ function buildAggregateTarget(
|
|
|
1379
1422
|
}
|
|
1380
1423
|
return null;
|
|
1381
1424
|
},
|
|
1382
|
-
wouldStrandConversationEnd(): boolean {
|
|
1383
|
-
return conversationEnd?.wouldStrand(occurrences) ?? false;
|
|
1425
|
+
wouldStrandConversationEnd(plannedRemovals): boolean {
|
|
1426
|
+
return conversationEnd?.wouldStrand(occurrences, plannedRemovals) ?? false;
|
|
1427
|
+
},
|
|
1428
|
+
notePlannedRemoval(plannedRemovals): void {
|
|
1429
|
+
for (const occ of occurrences) plannedRemovals.add(partKey(occ.part));
|
|
1384
1430
|
},
|
|
1385
1431
|
editMarker(): "truncated" | "absent" {
|
|
1386
1432
|
// Edit-marker: preserve the tool_use input's filePath + a region
|
|
@@ -1406,6 +1452,11 @@ function buildAggregateTarget(
|
|
|
1406
1452
|
},
|
|
1407
1453
|
// Open invocations still belong to the current turn; only complete arcs reclaim.
|
|
1408
1454
|
prepareDrop: () => !occurrences.some((occ) => occ.part.canRemove?.() === "defer"),
|
|
1455
|
+
prepareReplayDrop: () => {
|
|
1456
|
+
if (complete() && !requiresToolArcSkeleton) {
|
|
1457
|
+
for (const occ of occurrences) occ.part.canRemove?.();
|
|
1458
|
+
}
|
|
1459
|
+
},
|
|
1409
1460
|
canDrop: () => complete() && !occurrences.some((occ) => occ.part.hasUserAnswer?.()),
|
|
1410
1461
|
requiresToolArcSkeleton,
|
|
1411
1462
|
// Non-mutating read of the invocation input (the tool_use occurrence
|
|
@@ -1443,6 +1494,10 @@ function buildTextTarget(
|
|
|
1443
1494
|
return {
|
|
1444
1495
|
mutationParts: [{ message: { info: message.info, parts: [] }, part }],
|
|
1445
1496
|
textPrefix,
|
|
1497
|
+
canSetContent(content): boolean {
|
|
1498
|
+
const current = part.getText();
|
|
1499
|
+
return typeof current === "string" && current !== content;
|
|
1500
|
+
},
|
|
1446
1501
|
setContent(content: string): boolean {
|
|
1447
1502
|
return part.setText(content);
|
|
1448
1503
|
},
|
package/src/shared/transcript.ts
CHANGED
|
@@ -132,7 +132,7 @@ export interface TranscriptPart {
|
|
|
132
132
|
*
|
|
133
133
|
* For non-tool parts both byte fields are undefined/0.
|
|
134
134
|
*/
|
|
135
|
-
getToolMetadata(): {
|
|
135
|
+
getToolMetadata(options?: { skipInputTokenCount?: boolean }): {
|
|
136
136
|
toolName: string | undefined;
|
|
137
137
|
inputByteSize: number;
|
|
138
138
|
inputTokenCount: number;
|
|
@@ -14,11 +14,7 @@ const fencedSources: Array<{ path: string; sites: string[]; reporterCalls?: stri
|
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
16
|
path: "packages/plugin/src/features/magic-context/message-index.ts",
|
|
17
|
-
sites: [
|
|
18
|
-
"message_index_incremental",
|
|
19
|
-
"message_index_reconcile",
|
|
20
|
-
"message_index_orphan_sweep",
|
|
21
|
-
],
|
|
17
|
+
sites: ["message_index_incremental", "message_index_reconcile"],
|
|
22
18
|
},
|
|
23
19
|
{
|
|
24
20
|
path: "packages/plugin/src/features/magic-context/storage-meta-persisted.ts",
|
|
@@ -101,7 +97,6 @@ const newlyCoveredSites = [
|
|
|
101
97
|
"opencode_soft_refresh_cache",
|
|
102
98
|
"message_index_incremental",
|
|
103
99
|
"message_index_reconcile",
|
|
104
|
-
"message_index_orphan_sweep",
|
|
105
100
|
"message_index_clear",
|
|
106
101
|
"message_fts_rowid_backfill",
|
|
107
102
|
"storage_meta_wrapup_expiry_cleanup",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import type { Database } from "../../shared/sqlite";
|
|
2
|
-
import { type MessageHistoryOrphanSweepOptions, type MessageHistoryOrphanSweepResult } from "./message-index";
|
|
3
|
-
/**
|
|
4
|
-
* Scope wrapper for the background sweep. It lives beside `message-index` rather
|
|
5
|
-
* than inside it: importing the transform-pass scope helpers into
|
|
6
|
-
* `message-index.ts` itself changes the bundled module graph in a way that hits
|
|
7
|
-
* a Bun 1.4.2 packaging bug (a top-level `__promiseAll` init call is emitted
|
|
8
|
-
* without its definition, which crashes node hosts at import time).
|
|
9
|
-
*/
|
|
10
|
-
export declare function sweepOrphanedOpenCodeMessageIndexes(db: Database, openReadableOpenCodeDb: () => Database | null, options?: MessageHistoryOrphanSweepOptions): MessageHistoryOrphanSweepResult;
|
|
11
|
-
//# sourceMappingURL=message-index-sweep.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"message-index-sweep.d.ts","sourceRoot":"","sources":["../../../src/features/magic-context/message-index-sweep.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,OAAO,EACH,KAAK,gCAAgC,EACrC,KAAK,+BAA+B,EAEvC,MAAM,iBAAiB,CAAC;AAEzB;;;;;;GAMG;AACH,wBAAgB,mCAAmC,CAC/C,EAAE,EAAE,QAAQ,EACZ,sBAAsB,EAAE,MAAM,QAAQ,GAAG,IAAI,EAC7C,OAAO,GAAE,gCAAqC,GAC/C,+BAA+B,CAMjC"}
|