@cortexkit/opencode-magic-context 0.36.1 → 0.38.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/README.md +2 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +2 -1
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +10 -0
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-mt0ttc4x.js → conflict-warning-hook-an4fxhwf.js} +3 -3
- package/dist/{derive-budgets-88mxk2w1.js → derive-budgets-da4yg3tz.js} +3 -2
- package/dist/features/magic-context/context-authority.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify-prompt.d.ts +5 -1
- package/dist/features/magic-context/dreamer/classify-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/manifest-parser.d.ts +8 -0
- package/dist/features/magic-context/dreamer/manifest-parser.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts +7 -1
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts +18 -0
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +5 -0
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts +5 -1
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/fail-closed-block.d.ts +6 -1
- package/dist/features/magic-context/fail-closed-block.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts +3 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +6 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/migrations.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/reclaim-protection.d.ts +13 -0
- package/dist/features/magic-context/reclaim-protection.d.ts.map +1 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/wake-plane.d.ts +21 -0
- package/dist/features/magic-context/smart-notes/wake-plane.d.ts.map +1 -0
- package/dist/features/magic-context/storage-db.d.ts +19 -3
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +23 -0
- 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.map +1 -1
- package/dist/features/magic-context/storage-primers.d.ts +11 -0
- package/dist/features/magic-context/storage-primers.d.ts.map +1 -1
- package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +13 -5
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +7 -0
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/features/magic-context/window-report-ledger.d.ts +70 -0
- package/dist/features/magic-context/window-report-ledger.d.ts.map +1 -0
- package/dist/hooks/auto-update-checker/checker.d.ts +8 -1
- package/dist/hooks/auto-update-checker/checker.d.ts.map +1 -1
- package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
- package/dist/hooks/magic-context/channel2-cycle.d.ts +16 -0
- package/dist/hooks/magic-context/channel2-cycle.d.ts.map +1 -0
- package/dist/hooks/magic-context/channel2-delivery.d.ts +3 -9
- package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +2 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts +33 -103
- package/dist/hooks/magic-context/ctx-reduce-nudge.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +4 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/execute-status.d.ts +3 -1
- package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/fold-execution-gate.d.ts +2 -0
- package/dist/hooks/magic-context/fold-execution-gate.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/live-session-state.d.ts +3 -0
- package/dist/hooks/magic-context/live-session-state.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 +20 -0
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-state-sync.d.ts +8 -0
- package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts +6 -1
- package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +21 -2
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +27 -0
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +78 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +14 -3
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +10 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/{index-nsx2n9eg.js → index-4cz5nfxf.js} +3 -3
- package/dist/{index-f1tnb3vm.js → index-8pqfcghm.js} +21 -9
- package/dist/index-9zhhvr4w.js +733 -0
- package/dist/{index-zp6x6s6a.js → index-cae89eas.js} +25 -6
- package/dist/index-cgyfn1s2.js +53 -0
- package/dist/{index-3zqcdwqr.js → index-crke4z5j.js} +7 -4
- package/dist/{index-1skzp4dc.js → index-mmvhrqqb.js} +1991 -274
- package/dist/{index-tsgs7td8.js → index-pck9vadr.js} +1 -1
- package/dist/{index-3tnkymva.js → index-sw8gnq34.js} +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1714 -988
- package/dist/plugin/hooks/create-session-hooks.d.ts +3 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +2 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/{recomp-orchestrator-a0g9b52q.js → recomp-orchestrator-jsde4ygw.js} +7 -6
- package/dist/{safe-notification-target-c11fdda2.js → safe-notification-target-b693f9x3.js} +2 -2
- package/dist/{send-session-notification-bgtf4853.js → send-session-notification-dxske5zm.js} +3 -3
- package/dist/shared/conflict-detector.d.ts +63 -0
- package/dist/shared/conflict-detector.d.ts.map +1 -1
- package/dist/shared/harness-provider-map.d.ts +8 -0
- package/dist/shared/harness-provider-map.d.ts.map +1 -1
- package/dist/shared/logger.d.ts +8 -0
- package/dist/shared/logger.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts +7 -0
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/prompt-surface-runtime.d.ts.map +1 -1
- package/dist/shared/prompt-surface.d.ts +2 -0
- package/dist/shared/prompt-surface.d.ts.map +1 -1
- package/dist/shared/rpc-client.d.ts.map +1 -1
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/rpc-types.d.ts +29 -0
- package/dist/shared/rpc-types.d.ts.map +1 -1
- package/dist/shared/rpc-utils.d.ts +28 -9
- package/dist/shared/rpc-utils.d.ts.map +1 -1
- package/dist/shared/tail-hygiene-status.d.ts +15 -0
- package/dist/shared/tail-hygiene-status.d.ts.map +1 -0
- package/dist/shared/window-geometry.d.ts +90 -0
- package/dist/shared/window-geometry.d.ts.map +1 -0
- package/dist/{storage-meta-session-df9tstzr.js → storage-meta-session-mk4gsnke.js} +4 -3
- package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tui/data/context-db.d.ts.map +1 -1
- package/dist/tui-compiled/data/context-db.d.ts.map +1 -1
- package/package.json +3 -1
- package/src/config/index.ts +2 -0
- package/src/config/latch-permanence-guard.test.ts +218 -0
- package/src/config/project-security.ts +10 -1
- package/src/config/schema/magic-context.ts +12 -2
- package/src/shared/__fixtures__/window-overlay.v1.json +337 -0
- package/src/shared/conflict-detector.test.ts +176 -1
- package/src/shared/conflict-detector.ts +126 -3
- package/src/shared/harness-provider-map.test.ts +20 -0
- package/src/shared/harness-provider-map.ts +19 -0
- package/src/shared/logger.test.ts +119 -0
- package/src/shared/logger.ts +33 -15
- package/src/shared/models-dev-cache.test.ts +42 -0
- package/src/shared/models-dev-cache.ts +62 -9
- package/src/shared/prompt-surface-runtime.ts +5 -3
- package/src/shared/prompt-surface.test.ts +38 -0
- package/src/shared/prompt-surface.ts +15 -2
- package/src/shared/rpc-client.ts +4 -2
- package/src/shared/rpc-server.ts +1 -0
- package/src/shared/rpc-types.ts +30 -0
- package/src/shared/rpc-utils.test.ts +162 -13
- package/src/shared/rpc-utils.ts +224 -31
- package/src/shared/tail-hygiene-status.ts +57 -0
- package/src/shared/window-geometry.test.ts +342 -0
- package/src/shared/window-geometry.ts +626 -0
- package/src/tui/data/context-db.ts +5 -0
- package/src/tui/index.tsx +33 -1
- package/src/tui/slots/sidebar-content.tsx +17 -5
- package/src/tui-compiled/data/context-db.ts +5 -0
- package/src/tui-compiled/index.tsx +359 -273
- package/src/tui-compiled/slots/sidebar-content.tsx +316 -287
- package/dist/index-wgvxkqpx.js +0 -342
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
deriveTriggerBudget,
|
|
3
3
|
modelSupportsVision,
|
|
4
|
-
piModelRefToCanonical,
|
|
5
4
|
shouldEnforcePrivateStoragePermissions
|
|
6
|
-
} from "./index-
|
|
5
|
+
} from "./index-9zhhvr4w.js";
|
|
7
6
|
import {
|
|
8
7
|
parseProviderModel
|
|
9
8
|
} from "./index-td9depx5.js";
|
|
@@ -11,10 +10,11 @@ import {
|
|
|
11
10
|
describeError,
|
|
12
11
|
getErrorMessage,
|
|
13
12
|
sendIgnoredMessage
|
|
14
|
-
} from "./index-
|
|
13
|
+
} from "./index-4cz5nfxf.js";
|
|
15
14
|
import {
|
|
16
15
|
buildToolArcs,
|
|
17
16
|
buildTrueRawTokenIndex,
|
|
17
|
+
byteSize,
|
|
18
18
|
clearCachedM0M1,
|
|
19
19
|
clearCompressionDepth,
|
|
20
20
|
clearCompressionDepthRange,
|
|
@@ -35,13 +35,17 @@ import {
|
|
|
35
35
|
readSessionChunk,
|
|
36
36
|
stableStringify,
|
|
37
37
|
updateSessionMeta
|
|
38
|
-
} from "./index-
|
|
38
|
+
} from "./index-crke4z5j.js";
|
|
39
|
+
import {
|
|
40
|
+
modelRefLookupOrder,
|
|
41
|
+
piModelRefToCanonical
|
|
42
|
+
} from "./index-cgyfn1s2.js";
|
|
39
43
|
import {
|
|
40
44
|
Database,
|
|
41
45
|
closeQuietly,
|
|
42
46
|
getMessageTimesFromOpenCodeDb,
|
|
43
47
|
withPrivilegedWriter
|
|
44
|
-
} from "./index-
|
|
48
|
+
} from "./index-sw8gnq34.js";
|
|
45
49
|
import {
|
|
46
50
|
detectConfigFile
|
|
47
51
|
} from "./index-8mtsfhyg.js";
|
|
@@ -51,7 +55,7 @@ import {
|
|
|
51
55
|
import {
|
|
52
56
|
log,
|
|
53
57
|
sessionLog
|
|
54
|
-
} from "./index-
|
|
58
|
+
} from "./index-8pqfcghm.js";
|
|
55
59
|
import {
|
|
56
60
|
ensureCortexKitArtifactGitignore,
|
|
57
61
|
getDataDir,
|
|
@@ -414,24 +418,44 @@ function isMagicContextHiddenAgentName(agent) {
|
|
|
414
418
|
return false;
|
|
415
419
|
}
|
|
416
420
|
var MAX_FORMATTED_BLOCKING_PROCESSES = 8;
|
|
421
|
+
function normalizeFailClosedProcessKind(process2) {
|
|
422
|
+
switch (process2.kind) {
|
|
423
|
+
case "OpenCode server":
|
|
424
|
+
case "OpenCode instance (TUI/CLI)":
|
|
425
|
+
case "Pi":
|
|
426
|
+
case "process":
|
|
427
|
+
return process2.kind;
|
|
428
|
+
}
|
|
429
|
+
switch (process2.harness?.trim().toLowerCase()) {
|
|
430
|
+
case "opencode server":
|
|
431
|
+
return "OpenCode server";
|
|
432
|
+
case "opencode instance (tui/cli)":
|
|
433
|
+
case "opencode instance":
|
|
434
|
+
return "OpenCode instance (TUI/CLI)";
|
|
435
|
+
case "pi":
|
|
436
|
+
case "pi harness":
|
|
437
|
+
case "omp":
|
|
438
|
+
return "Pi";
|
|
439
|
+
default:
|
|
440
|
+
return "process";
|
|
441
|
+
}
|
|
442
|
+
}
|
|
417
443
|
function formatFailClosedBlockingProcesses(processes) {
|
|
418
444
|
const uniqueProcesses = new Map;
|
|
419
445
|
for (const process2 of processes) {
|
|
420
|
-
if (!
|
|
446
|
+
if (!Number.isInteger(process2.pid) || process2.pid <= 0)
|
|
421
447
|
continue;
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
pid: process2.pid
|
|
425
|
-
});
|
|
448
|
+
const kind = normalizeFailClosedProcessKind(process2);
|
|
449
|
+
uniqueProcesses.set(`${kind}\x00${process2.pid}`, { kind, pid: process2.pid });
|
|
426
450
|
}
|
|
427
451
|
const entries = [...uniqueProcesses.values()];
|
|
428
452
|
const visible = entries.slice(0, MAX_FORMATTED_BLOCKING_PROCESSES);
|
|
429
|
-
const rendered = visible.map(({
|
|
453
|
+
const rendered = visible.map(({ kind, pid }) => `${kind} (PID ${pid})`);
|
|
430
454
|
const omitted = entries.length - visible.length;
|
|
431
455
|
if (omitted > 0)
|
|
432
456
|
rendered.push(`${omitted} more blocking process(es)`);
|
|
433
457
|
if (rendered.length === 0)
|
|
434
|
-
return "a live
|
|
458
|
+
return "a live process";
|
|
435
459
|
if (rendered.length === 1)
|
|
436
460
|
return rendered[0];
|
|
437
461
|
const last = rendered.pop();
|
|
@@ -441,9 +465,9 @@ function formatFailClosedBlockingMessage(reason) {
|
|
|
441
465
|
if (reason.kind === "migration_guard") {
|
|
442
466
|
if (reason.unreadableFile) {
|
|
443
467
|
const arm = reason.unreadableArm ?? "io";
|
|
444
|
-
const recovery = arm === "io" ? `If
|
|
468
|
+
const recovery = arm === "io" ? `If none of these processes are running, it is safe to delete ${reason.unreadableFile} and retry.` : `The file may be a recent incomplete write; retry after the file is older than the ten-minute grace window, or stop the relevant process before deleting it.`;
|
|
445
469
|
return [
|
|
446
|
-
`Magic Context cannot migrate the shared database because RPC discovery file ${reason.unreadableFile} is uncertain (${arm} arm), so the absence of a live
|
|
470
|
+
`Magic Context cannot migrate the shared database because RPC discovery file ${reason.unreadableFile} is uncertain (${arm} arm), so the absence of a live process cannot be proven.`,
|
|
447
471
|
recovery,
|
|
448
472
|
`Recovery: ${FAIL_CLOSED_DOCTOR_COMMAND}`
|
|
449
473
|
].join(" ");
|
|
@@ -566,7 +590,7 @@ import {
|
|
|
566
590
|
statSync as statSync2,
|
|
567
591
|
unlinkSync
|
|
568
592
|
} from "node:fs";
|
|
569
|
-
import { basename, dirname, join as join3 } from "node:path";
|
|
593
|
+
import { basename, dirname, join as join3, resolve } from "node:path";
|
|
570
594
|
|
|
571
595
|
// src/plugin/boot-quiet.ts
|
|
572
596
|
var BOOT_QUIET_MS = 120000;
|
|
@@ -602,20 +626,24 @@ function rpcPortFilePath(storageDir, directory, pid = process.pid, instanceId) {
|
|
|
602
626
|
}
|
|
603
627
|
function isPidAlive(pid) {
|
|
604
628
|
if (!Number.isInteger(pid) || pid <= 0)
|
|
605
|
-
return
|
|
629
|
+
return "dead";
|
|
630
|
+
if (rpcIdentityPlatform === "win32")
|
|
631
|
+
return readWindowsProcess(pid).state;
|
|
606
632
|
try {
|
|
607
|
-
|
|
608
|
-
return
|
|
609
|
-
} catch (
|
|
610
|
-
return
|
|
633
|
+
rpcIdentityProcessKill(pid, 0);
|
|
634
|
+
return "alive";
|
|
635
|
+
} catch (error) {
|
|
636
|
+
return error.code === "ESRCH" ? "dead" : "inconclusive";
|
|
611
637
|
}
|
|
612
638
|
}
|
|
613
639
|
var RPC_IDENTITY_SKEW_TOLERANCE_MS = 120000;
|
|
614
640
|
var LINUX_CLOCK_TICKS_PER_SECOND = 100;
|
|
615
641
|
var PS_PROBE_TIMEOUT_MS = 1000;
|
|
616
642
|
var OPEN_CODE_COMMAND_MARKERS = ["opencode", "node", "bun", "electron"];
|
|
643
|
+
var TASKLIST_NO_TASKS_PATTERN = /^INFO:\s+No tasks are running which match the specified criteria\.?$/im;
|
|
617
644
|
var rpcIdentityReadFileSync = readFileSync;
|
|
618
645
|
var rpcIdentityExecFileSync = execFileSync;
|
|
646
|
+
var rpcIdentityProcessKill = process.kill;
|
|
619
647
|
var rpcProcessListExecFileSync = execFileSync;
|
|
620
648
|
var rpcIdentityPlatform = process.platform;
|
|
621
649
|
var rpcIdentityNowMs = () => Date.now();
|
|
@@ -645,7 +673,8 @@ function readPsProcessStartTime(pid) {
|
|
|
645
673
|
try {
|
|
646
674
|
const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "lstart="], {
|
|
647
675
|
encoding: "utf8",
|
|
648
|
-
timeout: PS_PROBE_TIMEOUT_MS
|
|
676
|
+
timeout: PS_PROBE_TIMEOUT_MS,
|
|
677
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
649
678
|
});
|
|
650
679
|
const processStartTime = Date.parse(String(output).trim());
|
|
651
680
|
return Number.isFinite(processStartTime) ? processStartTime : null;
|
|
@@ -653,6 +682,70 @@ function readPsProcessStartTime(pid) {
|
|
|
653
682
|
return null;
|
|
654
683
|
}
|
|
655
684
|
}
|
|
685
|
+
function parseCsvLine(line) {
|
|
686
|
+
const fields = [];
|
|
687
|
+
let field = "";
|
|
688
|
+
let quoted = false;
|
|
689
|
+
for (let index = 0;index < line.length; index += 1) {
|
|
690
|
+
const character = line[index];
|
|
691
|
+
if (character === '"') {
|
|
692
|
+
if (quoted && line[index + 1] === '"') {
|
|
693
|
+
field += '"';
|
|
694
|
+
index += 1;
|
|
695
|
+
} else {
|
|
696
|
+
quoted = !quoted;
|
|
697
|
+
}
|
|
698
|
+
} else if (character === "," && !quoted) {
|
|
699
|
+
fields.push(field);
|
|
700
|
+
field = "";
|
|
701
|
+
} else {
|
|
702
|
+
field += character;
|
|
703
|
+
}
|
|
704
|
+
}
|
|
705
|
+
if (quoted)
|
|
706
|
+
return null;
|
|
707
|
+
fields.push(field);
|
|
708
|
+
return fields;
|
|
709
|
+
}
|
|
710
|
+
function parseTasklistOutput(output) {
|
|
711
|
+
const entries = [];
|
|
712
|
+
let sawHeader = false;
|
|
713
|
+
for (const rawLine of output.split(/\r?\n/)) {
|
|
714
|
+
const line = rawLine.trim();
|
|
715
|
+
if (!line)
|
|
716
|
+
continue;
|
|
717
|
+
if (TASKLIST_NO_TASKS_PATTERN.test(line))
|
|
718
|
+
return [];
|
|
719
|
+
const fields = parseCsvLine(line);
|
|
720
|
+
if (!fields)
|
|
721
|
+
continue;
|
|
722
|
+
if (fields[1]?.trim().toLowerCase() === "pid") {
|
|
723
|
+
sawHeader = true;
|
|
724
|
+
continue;
|
|
725
|
+
}
|
|
726
|
+
const pid = Number(fields[1]);
|
|
727
|
+
if (!Number.isInteger(pid) || pid <= 0 || !fields[0])
|
|
728
|
+
continue;
|
|
729
|
+
entries.push({ pid, command: fields[0] });
|
|
730
|
+
}
|
|
731
|
+
return entries.length > 0 || sawHeader ? entries : null;
|
|
732
|
+
}
|
|
733
|
+
function readWindowsProcess(pid) {
|
|
734
|
+
try {
|
|
735
|
+
const output = rpcIdentityExecFileSync("tasklist", ["/FO", "CSV", "/FI", `PID eq ${pid}`], {
|
|
736
|
+
encoding: "utf8",
|
|
737
|
+
timeout: PS_PROBE_TIMEOUT_MS,
|
|
738
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
739
|
+
});
|
|
740
|
+
const entries = parseTasklistOutput(String(output));
|
|
741
|
+
if (entries === null)
|
|
742
|
+
return { state: "inconclusive" };
|
|
743
|
+
const process2 = entries.find((entry) => entry.pid === pid);
|
|
744
|
+
return process2 ? { state: "alive", command: process2.command } : { state: "dead" };
|
|
745
|
+
} catch {
|
|
746
|
+
return { state: "inconclusive" };
|
|
747
|
+
}
|
|
748
|
+
}
|
|
656
749
|
function readLinuxProcessCommand(pid) {
|
|
657
750
|
try {
|
|
658
751
|
return String(rpcIdentityReadFileSync(`/proc/${pid}/cmdline`, "utf8"));
|
|
@@ -664,40 +757,86 @@ function readPsProcessCommand(pid) {
|
|
|
664
757
|
try {
|
|
665
758
|
const output = rpcIdentityExecFileSync("ps", ["-p", String(pid), "-o", "command="], {
|
|
666
759
|
encoding: "utf8",
|
|
667
|
-
timeout: PS_PROBE_TIMEOUT_MS
|
|
760
|
+
timeout: PS_PROBE_TIMEOUT_MS,
|
|
761
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
668
762
|
});
|
|
669
763
|
return String(output);
|
|
670
764
|
} catch {
|
|
671
765
|
return null;
|
|
672
766
|
}
|
|
673
767
|
}
|
|
768
|
+
function readProcessCommand(pid) {
|
|
769
|
+
if (!Number.isInteger(pid) || pid <= 0)
|
|
770
|
+
return null;
|
|
771
|
+
return rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(pid).command ?? null : readPsProcessCommand(pid);
|
|
772
|
+
}
|
|
773
|
+
function executableName(token) {
|
|
774
|
+
return (token ?? "").replace(/^['"]|['"]$/g, "").split("/").at(-1) ?? "";
|
|
775
|
+
}
|
|
776
|
+
function commandTokens(command) {
|
|
777
|
+
return command.toLowerCase().replaceAll("\\", "/").replaceAll("\x00", " ").split(/\s+/).map((token) => token.replace(/^['"]|['"]$/g, "")).filter(Boolean);
|
|
778
|
+
}
|
|
779
|
+
function commandHasOpenCodeExecutable(tokens) {
|
|
780
|
+
return tokens.findIndex((token) => {
|
|
781
|
+
const executable = executableName(token).replace(/\.(?:exe|cmd)$/, "");
|
|
782
|
+
return executable === "opencode" || executable.endsWith("/opencode");
|
|
783
|
+
});
|
|
784
|
+
}
|
|
785
|
+
function commandHasPiExecutable(tokens) {
|
|
786
|
+
for (let index = 0;index < tokens.length; index += 1) {
|
|
787
|
+
const executable = executableName(tokens[index]).replace(/\.(?:exe|cmd)$/, "");
|
|
788
|
+
if (["pi", "omp", "oh-my-pi"].includes(executable))
|
|
789
|
+
return true;
|
|
790
|
+
if (["node", "bun", "deno"].includes(executable)) {
|
|
791
|
+
const script = executableName(tokens[index + 1]).replace(/\.(?:exe|cmd)$/, "");
|
|
792
|
+
if (["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script) || tokens[index + 1]?.includes("pi-coding-agent")) {
|
|
793
|
+
return true;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
return false;
|
|
798
|
+
}
|
|
799
|
+
function classifyProcessKind(command) {
|
|
800
|
+
if (!command)
|
|
801
|
+
return "process";
|
|
802
|
+
const tokens = commandTokens(command);
|
|
803
|
+
const openCodeIndex = commandHasOpenCodeExecutable(tokens);
|
|
804
|
+
if (openCodeIndex >= 0) {
|
|
805
|
+
const args = tokens.slice(openCodeIndex + 1);
|
|
806
|
+
if (args.some((token) => token === "serve" || token === "--serve" || token.startsWith("--serve="))) {
|
|
807
|
+
return "OpenCode server";
|
|
808
|
+
}
|
|
809
|
+
return "OpenCode instance (TUI/CLI)";
|
|
810
|
+
}
|
|
811
|
+
return commandHasPiExecutable(tokens) ? "Pi" : "process";
|
|
812
|
+
}
|
|
674
813
|
function commandLooksLikeOpenCode(command) {
|
|
675
814
|
const normalized = command.toLowerCase();
|
|
676
815
|
return OPEN_CODE_COMMAND_MARKERS.some((marker) => normalized.includes(marker));
|
|
677
816
|
}
|
|
678
817
|
function isPidIdentityPlausible(record) {
|
|
679
818
|
if (!Number.isInteger(record.pid) || record.pid <= 0)
|
|
680
|
-
return
|
|
819
|
+
return "implausible";
|
|
681
820
|
if (Number.isFinite(record.started_at) && record.started_at > 0) {
|
|
682
|
-
const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record.pid) : readPsProcessStartTime(record.pid);
|
|
821
|
+
const processStartTime = rpcIdentityPlatform === "linux" ? readLinuxProcessStartTime(record.pid) : rpcIdentityPlatform === "win32" ? null : readPsProcessStartTime(record.pid);
|
|
683
822
|
if (processStartTime === null)
|
|
684
|
-
return
|
|
685
|
-
return processStartTime <= record.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS;
|
|
823
|
+
return "inconclusive";
|
|
824
|
+
return processStartTime <= record.started_at + RPC_IDENTITY_SKEW_TOLERANCE_MS ? "plausible" : "implausible";
|
|
686
825
|
}
|
|
687
|
-
const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record.pid) : readPsProcessCommand(record.pid);
|
|
826
|
+
const command = rpcIdentityPlatform === "linux" ? readLinuxProcessCommand(record.pid) : rpcIdentityPlatform === "win32" ? readWindowsProcess(record.pid).command ?? null : readPsProcessCommand(record.pid);
|
|
688
827
|
if (command === null)
|
|
689
|
-
return
|
|
690
|
-
return commandLooksLikeOpenCode(command);
|
|
828
|
+
return "inconclusive";
|
|
829
|
+
return commandLooksLikeOpenCode(command) ? "plausible" : "implausible";
|
|
691
830
|
}
|
|
692
831
|
function commandLooksLikePi(command) {
|
|
693
832
|
const normalized = command.trim().toLowerCase().replaceAll("\\", "/");
|
|
694
833
|
const tokens = normalized.split(/\s+/).filter(Boolean);
|
|
695
|
-
const
|
|
696
|
-
const first =
|
|
834
|
+
const executableName2 = (token) => (token ?? "").split("/").at(-1) ?? "";
|
|
835
|
+
const first = executableName2(tokens[0]).replace(/\.exe$/, "");
|
|
697
836
|
if (["pi", "pi.cmd", "omp", "oh-my-pi"].includes(first))
|
|
698
837
|
return true;
|
|
699
838
|
if (["node", "bun", "deno"].includes(first)) {
|
|
700
|
-
const script =
|
|
839
|
+
const script = executableName2(tokens[1]);
|
|
701
840
|
return ["pi", "pi.js", "pi.mjs", "pi.cjs"].includes(script) || normalized.includes("pi-coding-agent");
|
|
702
841
|
}
|
|
703
842
|
return false;
|
|
@@ -705,20 +844,39 @@ function commandLooksLikePi(command) {
|
|
|
705
844
|
function inspectLivePiProcesses() {
|
|
706
845
|
if (false) {}
|
|
707
846
|
try {
|
|
708
|
-
const
|
|
847
|
+
const isWindows = rpcIdentityPlatform === "win32";
|
|
848
|
+
const output = String(rpcProcessListExecFileSync(isWindows ? "tasklist" : "ps", isWindows ? ["/FO", "CSV"] : ["-axo", "pid=,command="], {
|
|
709
849
|
encoding: "utf8",
|
|
710
|
-
timeout: PS_PROBE_TIMEOUT_MS
|
|
850
|
+
timeout: PS_PROBE_TIMEOUT_MS,
|
|
851
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
711
852
|
}));
|
|
712
853
|
const pids = new Set;
|
|
713
|
-
|
|
714
|
-
const
|
|
715
|
-
if (
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
854
|
+
if (isWindows) {
|
|
855
|
+
const entries = parseTasklistOutput(output);
|
|
856
|
+
if (entries === null) {
|
|
857
|
+
return {
|
|
858
|
+
state: "unreadable",
|
|
859
|
+
processIds: [],
|
|
860
|
+
error: "tasklist output unavailable"
|
|
861
|
+
};
|
|
862
|
+
}
|
|
863
|
+
for (const entry of entries) {
|
|
864
|
+
if (entry.pid === process.pid)
|
|
865
|
+
continue;
|
|
866
|
+
if (commandLooksLikePi(entry.command))
|
|
867
|
+
pids.add(entry.pid);
|
|
868
|
+
}
|
|
869
|
+
} else {
|
|
870
|
+
for (const line of output.split(/\r?\n/)) {
|
|
871
|
+
const match = /^\s*(\d+)\s+(.+)$/.exec(line);
|
|
872
|
+
if (!match)
|
|
873
|
+
continue;
|
|
874
|
+
const pid = Number(match[1]);
|
|
875
|
+
if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid)
|
|
876
|
+
continue;
|
|
877
|
+
if (commandLooksLikePi(match[2]))
|
|
878
|
+
pids.add(pid);
|
|
879
|
+
}
|
|
722
880
|
}
|
|
723
881
|
return { state: "known", processIds: [...pids].sort((left, right) => left - right) };
|
|
724
882
|
} catch (error) {
|
|
@@ -729,9 +887,6 @@ function inspectLivePiProcesses() {
|
|
|
729
887
|
};
|
|
730
888
|
}
|
|
731
889
|
}
|
|
732
|
-
function discoverLivePiProcessIds() {
|
|
733
|
-
return inspectLivePiProcesses().processIds;
|
|
734
|
-
}
|
|
735
890
|
function parseRpcPortFile(content, fallbackPid = 0) {
|
|
736
891
|
const trimmed = content.trim();
|
|
737
892
|
if (!trimmed)
|
|
@@ -748,6 +903,8 @@ function parseRpcPortFile(content, fallbackPid = 0) {
|
|
|
748
903
|
port: port2,
|
|
749
904
|
pid,
|
|
750
905
|
started_at: Number.isFinite(startedAt) ? startedAt : 0,
|
|
906
|
+
kind: typeof parsed.kind === "string" ? parsed.kind : undefined,
|
|
907
|
+
harness: typeof parsed.harness === "string" ? parsed.harness : undefined,
|
|
751
908
|
token: typeof parsed.token === "string" ? parsed.token : undefined,
|
|
752
909
|
instance_id: typeof parsed.instance_id === "string" ? parsed.instance_id : undefined
|
|
753
910
|
};
|
|
@@ -1415,6 +1572,7 @@ function prepareMirrorPageStatements(db) {
|
|
|
1415
1572
|
return {
|
|
1416
1573
|
identityByModule: db.prepare("SELECT context_row_id FROM mirror_identity WHERE domain = ? AND module_project = ? AND module_row_id = ?"),
|
|
1417
1574
|
insertIdentity: db.prepare("INSERT OR IGNORE INTO mirror_identity(domain, module_project, module_row_id, context_row_id) VALUES (?, ?, ?, ?)"),
|
|
1575
|
+
deleteIdentityByContext: db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND context_row_id = ?"),
|
|
1418
1576
|
deleteLiveMemory: db.prepare("DELETE FROM mirror_live_memory_rows WHERE module_project = ? AND module_row_id = ?"),
|
|
1419
1577
|
deletePendingReferencesForMemory: db.prepare("DELETE FROM mirror_pending_references WHERE domain = ? AND module_project = ? AND (module_row_id = ? OR target_module_row_id = ?)"),
|
|
1420
1578
|
deleteIdentity: db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND module_project = ? AND module_row_id = ?"),
|
|
@@ -1466,7 +1624,7 @@ function prepareMirrorPageStatements(db) {
|
|
|
1466
1624
|
check_quarantined_until = ?, check_next_due_at = ?, check_compiled_at = ?, check_false_since_at = ?,
|
|
1467
1625
|
check_last_liveness_at = ?, last_checked_at = ?, check_status = ?, check_version = ?,
|
|
1468
1626
|
policy_version = ?, anchor_block_id = ?, anchor_ordinal = ?, created_at = ?, updated_at = ? WHERE id = ?`),
|
|
1469
|
-
upsertNoteRevision: db.prepare("INSERT INTO mirror_note_revisions(module_project, module_row_id, context_row_id, status_version) VALUES (?, ?, ?, ?)
|
|
1627
|
+
upsertNoteRevision: db.prepare("INSERT OR REPLACE INTO mirror_note_revisions(module_project, module_row_id, context_row_id, status_version) VALUES (?, ?, ?, ?)"),
|
|
1470
1628
|
translateMemoryReferences: db.prepare(`UPDATE memories
|
|
1471
1629
|
SET superseded_by_memory_id = (
|
|
1472
1630
|
SELECT target.context_row_id
|
|
@@ -1551,6 +1709,9 @@ function rememberIdentity(db, domain, moduleProject, moduleRowId, contextRowId,
|
|
|
1551
1709
|
const existing = mirrorIdentity(db, domain, moduleProject, moduleRowId, statements);
|
|
1552
1710
|
if (existing)
|
|
1553
1711
|
return;
|
|
1712
|
+
if (domain === "notes") {
|
|
1713
|
+
(statements?.deleteIdentityByContext ?? db.prepare("DELETE FROM mirror_identity WHERE domain = ? AND context_row_id = ?")).run(domain, contextRowId);
|
|
1714
|
+
}
|
|
1554
1715
|
(statements?.insertIdentity ?? db.prepare("INSERT OR IGNORE INTO mirror_identity(domain, module_project, module_row_id, context_row_id) VALUES (?, ?, ?, ?)")).run(domain, moduleProject, moduleRowId, contextRowId);
|
|
1555
1716
|
}
|
|
1556
1717
|
function contextMemoryId(db, domain, moduleProject, row, moduleRowId, statements) {
|
|
@@ -2133,6 +2294,8 @@ function healAllNullColumns(db) {
|
|
|
2133
2294
|
["stripped_placeholder_ids", ""],
|
|
2134
2295
|
["stale_reduce_stripped_ids", ""],
|
|
2135
2296
|
["processed_image_stripped_ids", ""],
|
|
2297
|
+
["merged_reasoning_stripped_ids", ""],
|
|
2298
|
+
["trailing_blank_decisions", ""],
|
|
2136
2299
|
["memory_block_cache", ""],
|
|
2137
2300
|
["memory_block_ids", ""],
|
|
2138
2301
|
["compaction_marker_state", ""],
|
|
@@ -2244,6 +2407,7 @@ import path from "node:path";
|
|
|
2244
2407
|
var GIT_TIMEOUT_MS = 5000;
|
|
2245
2408
|
var TRANSIENT_FAILURE_COOLDOWN_MS = 5 * 60 * 1000;
|
|
2246
2409
|
var identityCache = new Map;
|
|
2410
|
+
var linkedGitWorktreeCache = new Map;
|
|
2247
2411
|
var lastKnownGitIdentityCache = new Map;
|
|
2248
2412
|
var directoryFallbackCache = new Map;
|
|
2249
2413
|
var transientFailureCooldown = new Map;
|
|
@@ -2458,7 +2622,12 @@ function takeDubiousOwnershipProjectIdentityWarning(directory) {
|
|
|
2458
2622
|
return formatDubiousOwnershipWarning(canonical);
|
|
2459
2623
|
}
|
|
2460
2624
|
function canonicalUserHomeDirectory() {
|
|
2461
|
-
|
|
2625
|
+
const homeDirectory = userHomeDirectoryForIdentity();
|
|
2626
|
+
try {
|
|
2627
|
+
return realpathSync.native(homeDirectory);
|
|
2628
|
+
} catch {
|
|
2629
|
+
return homeDirectory;
|
|
2630
|
+
}
|
|
2462
2631
|
}
|
|
2463
2632
|
function isUserHomeDirectory(directory) {
|
|
2464
2633
|
try {
|
|
@@ -2592,6 +2761,27 @@ function normalizeStoredProjectPath(rawOrStored) {
|
|
|
2592
2761
|
function storedPathBelongsToIdentity(storedProjectPath, projectIdentity) {
|
|
2593
2762
|
return storedProjectPath === projectIdentity || normalizeStoredProjectPath(storedProjectPath) === projectIdentity;
|
|
2594
2763
|
}
|
|
2764
|
+
function isLinkedGitWorktree(directory) {
|
|
2765
|
+
const resolvedDirectory = path.resolve(directory);
|
|
2766
|
+
const cached = linkedGitWorktreeCache.get(resolvedDirectory);
|
|
2767
|
+
if (cached !== undefined)
|
|
2768
|
+
return cached;
|
|
2769
|
+
let linked = false;
|
|
2770
|
+
try {
|
|
2771
|
+
const output = execFileSyncForIdentity("git", ["rev-parse", "--path-format=absolute", "--git-dir", "--git-common-dir"], {
|
|
2772
|
+
cwd: resolvedDirectory,
|
|
2773
|
+
encoding: "utf8",
|
|
2774
|
+
timeout: GIT_TIMEOUT_MS,
|
|
2775
|
+
windowsHide: true
|
|
2776
|
+
});
|
|
2777
|
+
const [gitDir, commonDir] = String(output).split(/\r?\n/u).map((line) => line.trim()).filter(Boolean);
|
|
2778
|
+
linked = Boolean(gitDir && commonDir && path.resolve(gitDir) !== path.resolve(commonDir));
|
|
2779
|
+
} catch {
|
|
2780
|
+
linked = hasGitDir(resolvedDirectory);
|
|
2781
|
+
}
|
|
2782
|
+
linkedGitWorktreeCache.set(resolvedDirectory, linked);
|
|
2783
|
+
return linked;
|
|
2784
|
+
}
|
|
2595
2785
|
// src/features/magic-context/workspaces.ts
|
|
2596
2786
|
var VALID_SHARE_CATEGORIES = new Set(V2_MEMORY_CATEGORIES);
|
|
2597
2787
|
var DEFAULT_WORKSPACE_SHARE_CATEGORIES = ["CONSTRAINTS"];
|
|
@@ -3083,6 +3273,7 @@ var MIGRATIONS = [
|
|
|
3083
3273
|
status TEXT NOT NULL DEFAULT 'active',
|
|
3084
3274
|
promoted_at INTEGER NOT NULL,
|
|
3085
3275
|
source_candidate_ids TEXT DEFAULT '[]',
|
|
3276
|
+
source_candidate_provenance TEXT,
|
|
3086
3277
|
created_at INTEGER NOT NULL,
|
|
3087
3278
|
updated_at INTEGER NOT NULL
|
|
3088
3279
|
);
|
|
@@ -4109,6 +4300,7 @@ var MIGRATIONS = [
|
|
|
4109
4300
|
last_observed_at INTEGER,
|
|
4110
4301
|
answer_refreshed_at INTEGER,
|
|
4111
4302
|
source_candidate_ids TEXT NOT NULL DEFAULT '[]',
|
|
4303
|
+
source_candidate_provenance TEXT,
|
|
4112
4304
|
created_at INTEGER NOT NULL,
|
|
4113
4305
|
updated_at INTEGER NOT NULL
|
|
4114
4306
|
);
|
|
@@ -4918,6 +5110,37 @@ var MIGRATIONS = [
|
|
|
4918
5110
|
ensureColumn(db, "notes", "compiled_at", "INTEGER");
|
|
4919
5111
|
ensureColumn(db, "notes", "compile_status", "TEXT CHECK(compile_status IN ('compiled', 'plain', 'refused'))");
|
|
4920
5112
|
}
|
|
5113
|
+
},
|
|
5114
|
+
{
|
|
5115
|
+
version: 77,
|
|
5116
|
+
description: "persist scoped provenance for promoted user memories and primers",
|
|
5117
|
+
up(db) {
|
|
5118
|
+
if (tableExists2(db, "user_memories")) {
|
|
5119
|
+
ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
|
|
5120
|
+
}
|
|
5121
|
+
if (tableExists2(db, "primers")) {
|
|
5122
|
+
ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
|
|
5123
|
+
}
|
|
5124
|
+
}
|
|
5125
|
+
},
|
|
5126
|
+
{
|
|
5127
|
+
version: 78,
|
|
5128
|
+
description: "add migration_pending journal for crash-safe cross-harness session migration",
|
|
5129
|
+
up(db) {
|
|
5130
|
+
db.exec(`
|
|
5131
|
+
CREATE TABLE IF NOT EXISTS migration_pending (
|
|
5132
|
+
migration_key TEXT PRIMARY KEY,
|
|
5133
|
+
source_session_id TEXT NOT NULL,
|
|
5134
|
+
target_harness TEXT NOT NULL,
|
|
5135
|
+
pi_session_id TEXT NOT NULL,
|
|
5136
|
+
final_path TEXT NOT NULL,
|
|
5137
|
+
stage_path TEXT NOT NULL,
|
|
5138
|
+
content_sha256 TEXT NOT NULL,
|
|
5139
|
+
phase TEXT NOT NULL CHECK (phase IN ('staged', 'db_committed')),
|
|
5140
|
+
created_at INTEGER NOT NULL
|
|
5141
|
+
);
|
|
5142
|
+
`);
|
|
5143
|
+
}
|
|
4921
5144
|
}
|
|
4922
5145
|
];
|
|
4923
5146
|
var LATEST_MIGRATION_VERSION = MIGRATIONS.reduce((max, m) => Math.max(max, m.version), 0);
|
|
@@ -5385,7 +5608,7 @@ function getSchemaFenceRejection() {
|
|
|
5385
5608
|
function getMigrationOnOpenRefusal() {
|
|
5386
5609
|
return lastMigrationOnOpenRefusal;
|
|
5387
5610
|
}
|
|
5388
|
-
var LATEST_SUPPORTED_VERSION =
|
|
5611
|
+
var LATEST_SUPPORTED_VERSION = 78;
|
|
5389
5612
|
var PERMISSIONS_ENFORCEABLE = process.platform !== "win32";
|
|
5390
5613
|
var defaultStoragePermissionFs = { chmodSync, mkdirSync };
|
|
5391
5614
|
var storagePermissionFs = defaultStoragePermissionFs;
|
|
@@ -5532,6 +5755,28 @@ function invalidDiscoveryReason(raw) {
|
|
|
5532
5755
|
}
|
|
5533
5756
|
return "parse-invalid";
|
|
5534
5757
|
}
|
|
5758
|
+
function classifyDiscoveryRecordKind(record) {
|
|
5759
|
+
for (const value of [record.kind, record.harness]) {
|
|
5760
|
+
const normalized = value?.trim().toLowerCase();
|
|
5761
|
+
if (!normalized)
|
|
5762
|
+
continue;
|
|
5763
|
+
if (normalized === "process")
|
|
5764
|
+
return "process";
|
|
5765
|
+
if (normalized === "opencode server" || normalized === "server") {
|
|
5766
|
+
return "OpenCode server";
|
|
5767
|
+
}
|
|
5768
|
+
if (normalized === "opencode instance" || normalized === "opencode instance (tui/cli)" || normalized === "opencode" || normalized === "tui" || normalized === "cli") {
|
|
5769
|
+
return "OpenCode instance (TUI/CLI)";
|
|
5770
|
+
}
|
|
5771
|
+
if (normalized === "pi" || normalized === "pi harness" || normalized === "omp" || normalized === "oh-my-pi") {
|
|
5772
|
+
return "Pi";
|
|
5773
|
+
}
|
|
5774
|
+
}
|
|
5775
|
+
return null;
|
|
5776
|
+
}
|
|
5777
|
+
function classifyRpcProcess(record) {
|
|
5778
|
+
return classifyDiscoveryRecordKind(record) ?? classifyProcessKind(readProcessCommand(record.pid));
|
|
5779
|
+
}
|
|
5535
5780
|
function classifyJunkDiscovery(portFile, raw, staleFiles) {
|
|
5536
5781
|
let mtimeMs;
|
|
5537
5782
|
try {
|
|
@@ -5584,7 +5829,9 @@ function inspectRpcServerDiscovery(storageDir) {
|
|
|
5584
5829
|
return { state: "absent", serverPids: [], staleFiles: [] };
|
|
5585
5830
|
}
|
|
5586
5831
|
const pids = new Set;
|
|
5832
|
+
const processByPid = new Map;
|
|
5587
5833
|
const staleFiles = [];
|
|
5834
|
+
const inconclusivePids = new Set;
|
|
5588
5835
|
for (const portFile of portFiles) {
|
|
5589
5836
|
let raw;
|
|
5590
5837
|
try {
|
|
@@ -5604,10 +5851,23 @@ function inspectRpcServerDiscovery(storageDir) {
|
|
|
5604
5851
|
return junk;
|
|
5605
5852
|
continue;
|
|
5606
5853
|
}
|
|
5607
|
-
|
|
5854
|
+
const liveness = isPidAlive(record.pid);
|
|
5855
|
+
const identity = liveness === "dead" ? "implausible" : isPidIdentityPlausible(record);
|
|
5856
|
+
if (liveness === "alive" && identity === "plausible") {
|
|
5608
5857
|
pids.add(record.pid);
|
|
5609
|
-
|
|
5858
|
+
const detected = {
|
|
5859
|
+
kind: classifyRpcProcess(record),
|
|
5860
|
+
pid: record.pid
|
|
5861
|
+
};
|
|
5862
|
+
const previous = processByPid.get(record.pid);
|
|
5863
|
+
if (!previous || previous.kind === "process" && detected.kind !== "process") {
|
|
5864
|
+
processByPid.set(record.pid, detected);
|
|
5865
|
+
}
|
|
5866
|
+
} else if (liveness === "dead" || identity === "implausible") {
|
|
5610
5867
|
staleFiles.push(portFile);
|
|
5868
|
+
} else {
|
|
5869
|
+
inconclusivePids.add(record.pid);
|
|
5870
|
+
}
|
|
5611
5871
|
}
|
|
5612
5872
|
for (const staleFile of staleFiles) {
|
|
5613
5873
|
try {
|
|
@@ -5618,10 +5878,55 @@ function inspectRpcServerDiscovery(storageDir) {
|
|
|
5618
5878
|
}
|
|
5619
5879
|
const serverPids = [...pids].sort((a, b) => a - b);
|
|
5620
5880
|
if (serverPids.length > 0) {
|
|
5621
|
-
return {
|
|
5881
|
+
return {
|
|
5882
|
+
state: "live",
|
|
5883
|
+
serverPids,
|
|
5884
|
+
serverProcesses: serverPids.map((pid) => processByPid.get(pid) ?? { kind: "process", pid }),
|
|
5885
|
+
staleFiles
|
|
5886
|
+
};
|
|
5887
|
+
}
|
|
5888
|
+
const uncertainPids = [...inconclusivePids].sort((a, b) => a - b);
|
|
5889
|
+
if (uncertainPids.length > 0) {
|
|
5890
|
+
return {
|
|
5891
|
+
state: "inconclusive",
|
|
5892
|
+
serverPids: [],
|
|
5893
|
+
staleFiles,
|
|
5894
|
+
inconclusivePids: uncertainPids
|
|
5895
|
+
};
|
|
5622
5896
|
}
|
|
5623
5897
|
return { state: "stale", serverPids: [], staleFiles };
|
|
5624
5898
|
}
|
|
5899
|
+
function formatInconclusiveOpenCodeMigrationWarning(dbPath, pids) {
|
|
5900
|
+
return `[magic-context] storage warning: continuing migration for ${dbPath}; OpenCode server PID ${pids.join(", ")} was not confirmed because its liveness or identity check could not run. This commonly means an OS sandbox denied kill(0) or ps. No live OpenCode server was confirmed.`;
|
|
5901
|
+
}
|
|
5902
|
+
function logInconclusiveMigrationProbes(dbPath, discovery, piProbeState) {
|
|
5903
|
+
const uncertainPids = discovery.inconclusivePids ?? [];
|
|
5904
|
+
if (uncertainPids.length > 0) {
|
|
5905
|
+
log(formatInconclusiveOpenCodeMigrationWarning(dbPath, uncertainPids));
|
|
5906
|
+
}
|
|
5907
|
+
if (piProbeState === "unreadable") {
|
|
5908
|
+
log(`[magic-context] storage warning: continuing migration for ${dbPath}; the Pi/OMP process-list probe could not run, which commonly means an OS sandbox denied ps. No live Pi harness was confirmed.`);
|
|
5909
|
+
}
|
|
5910
|
+
}
|
|
5911
|
+
function isDefaultSharedDatabasePath(dbPath) {
|
|
5912
|
+
if (!process.env.XDG_DATA_HOME && (process.env.MAGIC_CONTEXT_TEST_DATA_DIR || false)) {
|
|
5913
|
+
return false;
|
|
5914
|
+
}
|
|
5915
|
+
return resolve(dbPath) === resolve(join3(getMagicContextStorageDir(), "context.db"));
|
|
5916
|
+
}
|
|
5917
|
+
function migrationBlockingPiPids(dbPath, discovery, discoveredPiPids) {
|
|
5918
|
+
if (isDefaultSharedDatabasePath(dbPath))
|
|
5919
|
+
return [...discoveredPiPids];
|
|
5920
|
+
const sameDataDirPids = new Set(discovery.serverPids);
|
|
5921
|
+
return discoveredPiPids.filter((pid) => sameDataDirPids.has(pid));
|
|
5922
|
+
}
|
|
5923
|
+
function formatLiveProcessMigrationRefusal(dbPath, persistedVersion, latestSupportedVersion, serverPids, piPids) {
|
|
5924
|
+
const blockers = [
|
|
5925
|
+
...serverPids.map((pid) => `confirmed OpenCode server PID ${pid}`),
|
|
5926
|
+
...piPids.map((pid) => `confirmed Pi harness PID ${pid}`)
|
|
5927
|
+
];
|
|
5928
|
+
return `[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} while ${blockers.join(", ")} still use the old plugin build. Restart the blocking harness, then retry this process.`;
|
|
5929
|
+
}
|
|
5625
5930
|
function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion) {
|
|
5626
5931
|
const persistedVersion = getPersistedSchemaVersion(db);
|
|
5627
5932
|
if (persistedVersion >= latestSupportedVersion) {
|
|
@@ -5629,9 +5934,16 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
|
|
|
5629
5934
|
return true;
|
|
5630
5935
|
}
|
|
5631
5936
|
const discovery = inspectRpcServerDiscovery(dbDir);
|
|
5632
|
-
const
|
|
5633
|
-
|
|
5937
|
+
const piDiscovery = inspectLivePiProcesses();
|
|
5938
|
+
const piPids = migrationBlockingPiPids(dbPath, discovery, piDiscovery.processIds);
|
|
5939
|
+
const serverProcesses = discovery.serverProcesses ?? (discovery.state === "live" ? discovery.serverPids.map((pid) => ({ kind: "process", pid })) : []);
|
|
5940
|
+
const blockingProcesses = [
|
|
5941
|
+
...serverProcesses,
|
|
5942
|
+
...piPids.map((pid) => ({ kind: "Pi", pid }))
|
|
5943
|
+
];
|
|
5944
|
+
if ((discovery.state === "absent" || discovery.state === "stale" || discovery.state === "inconclusive") && piPids.length === 0) {
|
|
5634
5945
|
lastMigrationOnOpenRefusal = null;
|
|
5946
|
+
logInconclusiveMigrationProbes(dbPath, discovery, piDiscovery.state);
|
|
5635
5947
|
return true;
|
|
5636
5948
|
}
|
|
5637
5949
|
const blockingPids = [...new Set([...discovery.serverPids, ...piPids])].sort((left, right) => left - right);
|
|
@@ -5639,6 +5951,7 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
|
|
|
5639
5951
|
persistedVersion,
|
|
5640
5952
|
supportedVersion: latestSupportedVersion,
|
|
5641
5953
|
serverPids: blockingPids,
|
|
5954
|
+
blockingProcesses,
|
|
5642
5955
|
...discovery.unreadableFile ? { unreadableFile: discovery.unreadableFile } : {},
|
|
5643
5956
|
...discovery.unreadableArm ? { unreadableArm: discovery.unreadableArm } : {}
|
|
5644
5957
|
};
|
|
@@ -5648,11 +5961,7 @@ function enforceMigrationOnOpenGuard(db, dbPath, dbDir, latestSupportedVersion)
|
|
|
5648
5961
|
const recovery = arm === "io" ? `If no OpenCode server is running, it is safe to delete ${unreadableFile} and retry.` : `Retry after the file is older than the ten-minute grace window, or stop OpenCode before deleting it.`;
|
|
5649
5962
|
log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} because RPC discovery file ${unreadableFile} is uncertain (${arm} arm), so the absence of a live OpenCode server cannot be proven. ${recovery}`);
|
|
5650
5963
|
} else {
|
|
5651
|
-
|
|
5652
|
-
...discovery.serverPids.map((pid) => `OpenCode server PID ${pid}`),
|
|
5653
|
-
...piPids.map((pid) => `Pi harness PID ${pid}`)
|
|
5654
|
-
];
|
|
5655
|
-
log(`[magic-context] storage fatal: refusing to migrate ${dbPath} from upstream migration v${persistedVersion} to v${latestSupportedVersion} while ${blockers.join(", ")} may still use the old plugin build. Restart the blocking harness, then retry this process.`);
|
|
5964
|
+
log(formatLiveProcessMigrationRefusal(dbPath, persistedVersion, latestSupportedVersion, discovery.serverPids, piPids));
|
|
5656
5965
|
}
|
|
5657
5966
|
return false;
|
|
5658
5967
|
}
|
|
@@ -5876,6 +6185,7 @@ function initializeDatabase(db) {
|
|
|
5876
6185
|
last_observed_at INTEGER,
|
|
5877
6186
|
answer_refreshed_at INTEGER,
|
|
5878
6187
|
source_candidate_ids TEXT NOT NULL DEFAULT '[]',
|
|
6188
|
+
source_candidate_provenance TEXT,
|
|
5879
6189
|
created_at INTEGER NOT NULL,
|
|
5880
6190
|
updated_at INTEGER NOT NULL
|
|
5881
6191
|
);
|
|
@@ -6511,6 +6821,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
6511
6821
|
ensureColumn(db, "primer_candidates", "question_embedding", "BLOB");
|
|
6512
6822
|
ensureColumn(db, "primer_candidates", "question_embedding_model_id", "TEXT");
|
|
6513
6823
|
ensureColumn(db, "primers", "question_embedding_model_id", "TEXT");
|
|
6824
|
+
ensureColumn(db, "primers", "source_candidate_provenance", "TEXT");
|
|
6825
|
+
const hasUserMemoriesTable = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'user_memories'").get();
|
|
6826
|
+
if (hasUserMemoriesTable) {
|
|
6827
|
+
ensureColumn(db, "user_memories", "source_candidate_provenance", "TEXT");
|
|
6828
|
+
}
|
|
6514
6829
|
db.exec(`
|
|
6515
6830
|
CREATE UNIQUE INDEX IF NOT EXISTS idx_primer_candidates_occurrence
|
|
6516
6831
|
ON primer_candidates(project_path, harness, session_id, source_start_message_id, source_end_message_id);
|
|
@@ -6584,6 +6899,8 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
6584
6899
|
ensureColumn(db, "session_meta", "stripped_placeholder_ids", "TEXT DEFAULT ''");
|
|
6585
6900
|
ensureColumn(db, "session_meta", "stale_reduce_stripped_ids", "TEXT DEFAULT ''");
|
|
6586
6901
|
ensureColumn(db, "session_meta", "processed_image_stripped_ids", "TEXT DEFAULT ''");
|
|
6902
|
+
ensureColumn(db, "session_meta", "merged_reasoning_stripped_ids", "TEXT DEFAULT ''");
|
|
6903
|
+
ensureColumn(db, "session_meta", "trailing_blank_decisions", "TEXT DEFAULT ''");
|
|
6587
6904
|
ensureColumn(db, "compartments", "start_message_id", "TEXT DEFAULT ''");
|
|
6588
6905
|
ensureColumn(db, "compartments", "end_message_id", "TEXT DEFAULT ''");
|
|
6589
6906
|
ensureColumn(db, "memory_embeddings", "model_id", "TEXT");
|
|
@@ -6802,11 +7119,11 @@ CREATE INDEX IF NOT EXISTS idx_dream_queue_pending ON dream_queue(started_at, en
|
|
|
6802
7119
|
ensureColumn(db, "message_history_index", "harness", "TEXT NOT NULL DEFAULT 'opencode'");
|
|
6803
7120
|
ensureColumn(db, "workspaces", "share_categories", `TEXT NOT NULL DEFAULT '["CONSTRAINTS"]'`);
|
|
6804
7121
|
}
|
|
6805
|
-
var CHANNEL2_CLAIM_TTL_MS =
|
|
7122
|
+
var CHANNEL2_CLAIM_TTL_MS = 10 * 60000;
|
|
6806
7123
|
function healWedgedChannel2Claims(db) {
|
|
6807
7124
|
try {
|
|
6808
7125
|
const staleBefore = Date.now() - CHANNEL2_CLAIM_TTL_MS;
|
|
6809
|
-
db.prepare("UPDATE session_meta SET channel2_nudge_state = '
|
|
7126
|
+
db.prepare("UPDATE session_meta SET channel2_nudge_state = '', channel2_nudge_claimed_at = 0, channel2_nudge_claim_token = '' WHERE channel2_nudge_state = 'claimed' AND (channel2_nudge_claimed_at IS NULL OR channel2_nudge_claimed_at = 0 OR channel2_nudge_claimed_at <= ?)").run(staleBefore);
|
|
6810
7127
|
} catch {}
|
|
6811
7128
|
}
|
|
6812
7129
|
function openDatabase(dbPathOrOptions) {
|
|
@@ -8205,7 +8522,7 @@ function clearHistorianFailureState(db, sessionId) {
|
|
|
8205
8522
|
})();
|
|
8206
8523
|
}
|
|
8207
8524
|
function normalizeDetectedLimitModelKey(modelKey) {
|
|
8208
|
-
return typeof modelKey === "string" && modelKey.length > 0 ? modelKey : null;
|
|
8525
|
+
return typeof modelKey === "string" && modelKey.length > 0 ? piModelRefToCanonical(modelKey) : null;
|
|
8209
8526
|
}
|
|
8210
8527
|
function normalizeEmergencyRecoveryOrigin(value) {
|
|
8211
8528
|
return value === "provider_overflow" || value === "proactive_model_shrink" ? value : null;
|
|
@@ -8356,6 +8673,96 @@ function removeStrippedPlaceholderId(db, sessionId, messageId) {
|
|
|
8356
8673
|
applyStrippedPlaceholderDelta(db, sessionId, { remove: [messageId] });
|
|
8357
8674
|
return true;
|
|
8358
8675
|
}
|
|
8676
|
+
function getMergedReasoningStrippedIds(db, sessionId) {
|
|
8677
|
+
const row = db.prepare("SELECT merged_reasoning_stripped_ids FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
8678
|
+
return new Set(parseStrippedBlob(row?.merged_reasoning_stripped_ids));
|
|
8679
|
+
}
|
|
8680
|
+
function addMergedReasoningStrippedIds(db, sessionId, ids) {
|
|
8681
|
+
const add = [...ids];
|
|
8682
|
+
if (add.length === 0)
|
|
8683
|
+
return true;
|
|
8684
|
+
ensureSessionMetaRow(db, sessionId);
|
|
8685
|
+
for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
|
|
8686
|
+
const row = db.prepare("SELECT merged_reasoning_stripped_ids FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
8687
|
+
const rawStored = row ? row.merged_reasoning_stripped_ids ?? null : null;
|
|
8688
|
+
const current = new Set(parseStrippedBlob(rawStored));
|
|
8689
|
+
let changed = false;
|
|
8690
|
+
for (const id of add) {
|
|
8691
|
+
if (!current.has(id)) {
|
|
8692
|
+
current.add(id);
|
|
8693
|
+
changed = true;
|
|
8694
|
+
}
|
|
8695
|
+
}
|
|
8696
|
+
if (!changed)
|
|
8697
|
+
return true;
|
|
8698
|
+
const nextBlob = JSON.stringify([...current]);
|
|
8699
|
+
const result = db.prepare("UPDATE session_meta SET merged_reasoning_stripped_ids = ? WHERE session_id = ? AND merged_reasoning_stripped_ids IS ?").run(nextBlob, sessionId, rawStored);
|
|
8700
|
+
if (result.changes > 0)
|
|
8701
|
+
return true;
|
|
8702
|
+
}
|
|
8703
|
+
sessionLog(sessionId, `merged_reasoning_stripped_ids CAS: ${CAS_RETRY_LIMIT} retries exhausted`);
|
|
8704
|
+
return false;
|
|
8705
|
+
}
|
|
8706
|
+
function isPersistedTrailingBlankDecision(value) {
|
|
8707
|
+
if (value === "keep" || value === "strip")
|
|
8708
|
+
return true;
|
|
8709
|
+
if (typeof value !== "string" || !value.startsWith("keep:"))
|
|
8710
|
+
return false;
|
|
8711
|
+
const countText = value.slice("keep:".length);
|
|
8712
|
+
if (!/^[1-9]\d*$/.test(countText))
|
|
8713
|
+
return false;
|
|
8714
|
+
const count = Number(countText);
|
|
8715
|
+
return Number.isSafeInteger(count) && count > 1 && count <= 1e4;
|
|
8716
|
+
}
|
|
8717
|
+
function parseTrailingBlankDecisions(raw) {
|
|
8718
|
+
if (!raw)
|
|
8719
|
+
return new Map;
|
|
8720
|
+
try {
|
|
8721
|
+
const parsed = JSON.parse(raw);
|
|
8722
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
8723
|
+
return new Map;
|
|
8724
|
+
const decisions = new Map;
|
|
8725
|
+
for (const [id, decision] of Object.entries(parsed)) {
|
|
8726
|
+
if (id.length > 0 && isPersistedTrailingBlankDecision(decision)) {
|
|
8727
|
+
decisions.set(id, decision);
|
|
8728
|
+
}
|
|
8729
|
+
}
|
|
8730
|
+
return decisions;
|
|
8731
|
+
} catch {
|
|
8732
|
+
return new Map;
|
|
8733
|
+
}
|
|
8734
|
+
}
|
|
8735
|
+
function getTrailingBlankDecisions(db, sessionId) {
|
|
8736
|
+
const row = db.prepare("SELECT trailing_blank_decisions FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
8737
|
+
return parseTrailingBlankDecisions(row?.trailing_blank_decisions);
|
|
8738
|
+
}
|
|
8739
|
+
function addTrailingBlankDecisions(db, sessionId, additions, options) {
|
|
8740
|
+
const add = [...additions];
|
|
8741
|
+
if (add.length === 0)
|
|
8742
|
+
return true;
|
|
8743
|
+
ensureSessionMetaRow(db, sessionId);
|
|
8744
|
+
for (let attempt = 0;attempt < CAS_RETRY_LIMIT; attempt += 1) {
|
|
8745
|
+
const row = db.prepare("SELECT trailing_blank_decisions FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
8746
|
+
const rawStored = row ? row.trailing_blank_decisions ?? null : null;
|
|
8747
|
+
const current = parseTrailingBlankDecisions(rawStored);
|
|
8748
|
+
let changed = false;
|
|
8749
|
+
for (const [id, decision] of add) {
|
|
8750
|
+
const currentDecision = current.get(id);
|
|
8751
|
+
if (currentDecision === undefined || id === options?.overwriteMessageId && currentDecision !== decision) {
|
|
8752
|
+
current.set(id, decision);
|
|
8753
|
+
changed = true;
|
|
8754
|
+
}
|
|
8755
|
+
}
|
|
8756
|
+
if (!changed)
|
|
8757
|
+
return true;
|
|
8758
|
+
const nextBlob = JSON.stringify(Object.fromEntries(current));
|
|
8759
|
+
const result = db.prepare("UPDATE session_meta SET trailing_blank_decisions = ? WHERE session_id = ? AND trailing_blank_decisions IS ?").run(nextBlob, sessionId, rawStored);
|
|
8760
|
+
if (result.changes > 0)
|
|
8761
|
+
return true;
|
|
8762
|
+
}
|
|
8763
|
+
sessionLog(sessionId, `trailing_blank_decisions CAS: ${CAS_RETRY_LIMIT} retries exhausted`);
|
|
8764
|
+
return false;
|
|
8765
|
+
}
|
|
8359
8766
|
function getStaleReduceStrippedIds(db, sessionId) {
|
|
8360
8767
|
const row = db.prepare("SELECT stale_reduce_stripped_ids FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
8361
8768
|
return new Set(parseStrippedBlob(row?.stale_reduce_stripped_ids));
|
|
@@ -8803,6 +9210,76 @@ function parseCandidateIds(raw) {
|
|
|
8803
9210
|
return [];
|
|
8804
9211
|
}
|
|
8805
9212
|
}
|
|
9213
|
+
function parsePrimerSourceProvenance(raw) {
|
|
9214
|
+
if (raw === null)
|
|
9215
|
+
return null;
|
|
9216
|
+
try {
|
|
9217
|
+
const parsed = JSON.parse(raw);
|
|
9218
|
+
if (!Array.isArray(parsed))
|
|
9219
|
+
return null;
|
|
9220
|
+
const provenance = [];
|
|
9221
|
+
for (const value of parsed) {
|
|
9222
|
+
if (!value || typeof value !== "object")
|
|
9223
|
+
return null;
|
|
9224
|
+
const source = value;
|
|
9225
|
+
if (typeof source.candidate_id !== "number" || !Number.isFinite(source.candidate_id) || typeof source.project_path !== "string" || typeof source.harness !== "string" || typeof source.session_id !== "string" || source.source_compartment_start !== null && typeof source.source_compartment_start !== "number" || source.source_compartment_end !== null && typeof source.source_compartment_end !== "number" || typeof source.source_start_message_id !== "string" || typeof source.source_end_message_id !== "string") {
|
|
9226
|
+
return null;
|
|
9227
|
+
}
|
|
9228
|
+
provenance.push({
|
|
9229
|
+
candidateId: source.candidate_id,
|
|
9230
|
+
projectPath: source.project_path,
|
|
9231
|
+
harness: source.harness,
|
|
9232
|
+
sessionId: source.session_id,
|
|
9233
|
+
sourceCompartmentStart: source.source_compartment_start,
|
|
9234
|
+
sourceCompartmentEnd: source.source_compartment_end,
|
|
9235
|
+
sourceStartMessageId: source.source_start_message_id,
|
|
9236
|
+
sourceEndMessageId: source.source_end_message_id
|
|
9237
|
+
});
|
|
9238
|
+
}
|
|
9239
|
+
return provenance;
|
|
9240
|
+
} catch {
|
|
9241
|
+
return null;
|
|
9242
|
+
}
|
|
9243
|
+
}
|
|
9244
|
+
function loadPrimerSourceProvenance(db, candidateIds) {
|
|
9245
|
+
const ids = [...new Set(candidateIds)].sort((a, b) => a - b);
|
|
9246
|
+
if (ids.length === 0)
|
|
9247
|
+
return [];
|
|
9248
|
+
const placeholders3 = ids.map(() => "?").join(",");
|
|
9249
|
+
const rows = db.prepare(`SELECT id, project_path, harness, session_id,
|
|
9250
|
+
source_compartment_start, source_compartment_end,
|
|
9251
|
+
source_start_message_id, source_end_message_id
|
|
9252
|
+
FROM primer_candidates
|
|
9253
|
+
WHERE id IN (${placeholders3})
|
|
9254
|
+
ORDER BY id ASC`).all(...ids);
|
|
9255
|
+
return rows.map((row) => ({
|
|
9256
|
+
candidateId: row.id,
|
|
9257
|
+
projectPath: row.project_path,
|
|
9258
|
+
harness: row.harness,
|
|
9259
|
+
sessionId: row.session_id,
|
|
9260
|
+
sourceCompartmentStart: row.source_compartment_start,
|
|
9261
|
+
sourceCompartmentEnd: row.source_compartment_end,
|
|
9262
|
+
sourceStartMessageId: row.source_start_message_id,
|
|
9263
|
+
sourceEndMessageId: row.source_end_message_id
|
|
9264
|
+
}));
|
|
9265
|
+
}
|
|
9266
|
+
function serializePrimerSourceProvenance(provenance, sourceCandidateIds) {
|
|
9267
|
+
if (provenance.length === 0 && sourceCandidateIds.length > 0)
|
|
9268
|
+
return null;
|
|
9269
|
+
return JSON.stringify(provenance.map((source) => ({
|
|
9270
|
+
candidate_id: source.candidateId,
|
|
9271
|
+
project_path: source.projectPath,
|
|
9272
|
+
harness: source.harness,
|
|
9273
|
+
session_id: source.sessionId,
|
|
9274
|
+
source_compartment_start: source.sourceCompartmentStart,
|
|
9275
|
+
source_compartment_end: source.sourceCompartmentEnd,
|
|
9276
|
+
source_start_message_id: source.sourceStartMessageId,
|
|
9277
|
+
source_end_message_id: source.sourceEndMessageId
|
|
9278
|
+
})));
|
|
9279
|
+
}
|
|
9280
|
+
function normalizedCandidateIds(candidateIds) {
|
|
9281
|
+
return [...new Set(candidateIds)].sort((a, b) => a - b);
|
|
9282
|
+
}
|
|
8806
9283
|
function toCandidate(row) {
|
|
8807
9284
|
return {
|
|
8808
9285
|
id: row.id,
|
|
@@ -8835,6 +9312,7 @@ function toPrimer(row) {
|
|
|
8835
9312
|
lastObservedAt: row.last_observed_at,
|
|
8836
9313
|
answerRefreshedAt: row.answer_refreshed_at,
|
|
8837
9314
|
sourceCandidateIds: parseCandidateIds(row.source_candidate_ids),
|
|
9315
|
+
sourceProvenance: parsePrimerSourceProvenance(row.source_candidate_provenance),
|
|
8838
9316
|
createdAt: row.created_at,
|
|
8839
9317
|
updatedAt: row.updated_at
|
|
8840
9318
|
};
|
|
@@ -8906,23 +9384,43 @@ function getActivePrimers(db, projectPath) {
|
|
|
8906
9384
|
return rows.map(toPrimer);
|
|
8907
9385
|
}
|
|
8908
9386
|
function createPrimer(db, input) {
|
|
8909
|
-
|
|
8910
|
-
|
|
8911
|
-
|
|
8912
|
-
|
|
8913
|
-
|
|
8914
|
-
|
|
8915
|
-
|
|
9387
|
+
return db.transaction(() => {
|
|
9388
|
+
const now = input.now ?? Date.now();
|
|
9389
|
+
const sourceCandidateIds = normalizedCandidateIds(input.sourceCandidateIds);
|
|
9390
|
+
const sourceProvenance = loadPrimerSourceProvenance(db, sourceCandidateIds);
|
|
9391
|
+
const info = db.prepare(`INSERT INTO primers (
|
|
9392
|
+
project_path, question, question_embedding, question_embedding_model_id, answer,
|
|
9393
|
+
status, total_support, last_observed_at, answer_refreshed_at,
|
|
9394
|
+
source_candidate_ids, source_candidate_provenance, created_at, updated_at
|
|
9395
|
+
) VALUES (?, ?, ?, ?, ?, 'active', ?, ?, NULL, ?, ?, ?, ?)`).run(input.projectPath, input.question, vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.answer ?? "", input.totalSupport, input.lastObservedAt, JSON.stringify(sourceCandidateIds), serializePrimerSourceProvenance(sourceProvenance, sourceCandidateIds), now, now);
|
|
9396
|
+
return Number(info.lastInsertRowid);
|
|
9397
|
+
})();
|
|
8916
9398
|
}
|
|
8917
9399
|
function updatePrimerSupport(db, input) {
|
|
8918
|
-
db.
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
|
|
8922
|
-
|
|
8923
|
-
|
|
8924
|
-
|
|
8925
|
-
|
|
9400
|
+
db.transaction(() => {
|
|
9401
|
+
const sourceCandidateIds = normalizedCandidateIds(input.sourceCandidateIds);
|
|
9402
|
+
const allowedIds = new Set(sourceCandidateIds);
|
|
9403
|
+
const existingRow = db.prepare("SELECT source_candidate_provenance FROM primers WHERE id = ?").get(input.primerId);
|
|
9404
|
+
const provenanceByCandidateId = new Map;
|
|
9405
|
+
for (const source of parsePrimerSourceProvenance(existingRow?.source_candidate_provenance ?? null) ?? []) {
|
|
9406
|
+
if (allowedIds.has(source.candidateId)) {
|
|
9407
|
+
provenanceByCandidateId.set(source.candidateId, source);
|
|
9408
|
+
}
|
|
9409
|
+
}
|
|
9410
|
+
for (const source of loadPrimerSourceProvenance(db, sourceCandidateIds)) {
|
|
9411
|
+
provenanceByCandidateId.set(source.candidateId, source);
|
|
9412
|
+
}
|
|
9413
|
+
const sourceProvenance = [...provenanceByCandidateId.values()].sort((a, b) => a.candidateId - b.candidateId);
|
|
9414
|
+
db.prepare(`UPDATE primers
|
|
9415
|
+
SET question_embedding = COALESCE(?, question_embedding),
|
|
9416
|
+
question_embedding_model_id = COALESCE(?, question_embedding_model_id),
|
|
9417
|
+
total_support = ?,
|
|
9418
|
+
last_observed_at = ?,
|
|
9419
|
+
source_candidate_ids = ?,
|
|
9420
|
+
source_candidate_provenance = ?,
|
|
9421
|
+
updated_at = ?
|
|
9422
|
+
WHERE id = ?`).run(vectorBlob(input.questionEmbedding), input.questionEmbeddingModelId ?? null, input.totalSupport, input.lastObservedAt, JSON.stringify(sourceCandidateIds), serializePrimerSourceProvenance(sourceProvenance, sourceCandidateIds), input.now ?? Date.now(), input.primerId);
|
|
9423
|
+
})();
|
|
8926
9424
|
}
|
|
8927
9425
|
function updatePrimerAnswer(db, primerId, answer, refreshedAt = Date.now()) {
|
|
8928
9426
|
db.prepare("UPDATE primers SET answer = ?, answer_refreshed_at = ?, updated_at = ? WHERE id = ?").run(answer, refreshedAt, refreshedAt, primerId);
|
|
@@ -9026,6 +9524,1097 @@ function getLatestHistorianInvocationId(db, sessionId) {
|
|
|
9026
9524
|
return null;
|
|
9027
9525
|
}
|
|
9028
9526
|
}
|
|
9527
|
+
// src/features/magic-context/reclaim-protection.ts
|
|
9528
|
+
var CTX_REDUCE_KEEP = 3;
|
|
9529
|
+
function newestCtxReduceTagNumbers(tags) {
|
|
9530
|
+
return new Set(tags.filter((tag) => tag.toolName === "ctx_reduce").sort((left, right) => right.tagNumber - left.tagNumber).slice(0, CTX_REDUCE_KEEP).map((tag) => tag.tagNumber));
|
|
9531
|
+
}
|
|
9532
|
+
|
|
9533
|
+
// src/hooks/magic-context/image-token-estimate.ts
|
|
9534
|
+
var IMAGE_TOKEN_DIVISOR = 750;
|
|
9535
|
+
var IMAGE_FALLBACK_TOKENS = 1200;
|
|
9536
|
+
var IMAGE_TOKEN_CAP = 4500;
|
|
9537
|
+
function estimateImageTokensFromDataUrl(url) {
|
|
9538
|
+
const comma = url.indexOf(",");
|
|
9539
|
+
if (comma < 0)
|
|
9540
|
+
return IMAGE_FALLBACK_TOKENS;
|
|
9541
|
+
const header = url.slice(0, comma);
|
|
9542
|
+
const payload = url.slice(comma + 1);
|
|
9543
|
+
const sliceLen = Math.min(512, payload.length);
|
|
9544
|
+
const preview = payload.slice(0, sliceLen);
|
|
9545
|
+
let bytes;
|
|
9546
|
+
try {
|
|
9547
|
+
bytes = base64Decode(preview);
|
|
9548
|
+
} catch {
|
|
9549
|
+
return IMAGE_FALLBACK_TOKENS;
|
|
9550
|
+
}
|
|
9551
|
+
if (header.includes("image/png")) {
|
|
9552
|
+
const dims = parsePngDimensions(bytes);
|
|
9553
|
+
if (dims)
|
|
9554
|
+
return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
|
|
9555
|
+
} else if (header.includes("image/jpeg") || header.includes("image/jpg")) {
|
|
9556
|
+
const dims = parseJpegDimensions(bytes);
|
|
9557
|
+
if (dims)
|
|
9558
|
+
return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
|
|
9559
|
+
} else if (header.includes("image/webp")) {
|
|
9560
|
+
const dims = parseWebpDimensions(bytes);
|
|
9561
|
+
if (dims)
|
|
9562
|
+
return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
|
|
9563
|
+
} else if (header.includes("image/gif")) {
|
|
9564
|
+
const dims = parseGifDimensions(bytes);
|
|
9565
|
+
if (dims)
|
|
9566
|
+
return clampImageTokens(Math.ceil(dims.w * dims.h / IMAGE_TOKEN_DIVISOR));
|
|
9567
|
+
}
|
|
9568
|
+
return IMAGE_FALLBACK_TOKENS;
|
|
9569
|
+
}
|
|
9570
|
+
function clampImageTokens(n) {
|
|
9571
|
+
if (n < 1)
|
|
9572
|
+
return 1;
|
|
9573
|
+
if (n > IMAGE_TOKEN_CAP)
|
|
9574
|
+
return IMAGE_TOKEN_CAP;
|
|
9575
|
+
return n;
|
|
9576
|
+
}
|
|
9577
|
+
function base64Decode(b64) {
|
|
9578
|
+
const pad = b64.length % 4;
|
|
9579
|
+
const padded = pad === 0 ? b64 : b64 + "=".repeat(4 - pad);
|
|
9580
|
+
const binary = atob(padded);
|
|
9581
|
+
const out = new Uint8Array(binary.length);
|
|
9582
|
+
for (let i = 0;i < binary.length; i++)
|
|
9583
|
+
out[i] = binary.charCodeAt(i);
|
|
9584
|
+
return out;
|
|
9585
|
+
}
|
|
9586
|
+
function parsePngDimensions(b) {
|
|
9587
|
+
if (b.length < 24)
|
|
9588
|
+
return null;
|
|
9589
|
+
if (b[0] !== 137 || b[1] !== 80 || b[2] !== 78 || b[3] !== 71 || b[4] !== 13 || b[5] !== 10 || b[6] !== 26 || b[7] !== 10)
|
|
9590
|
+
return null;
|
|
9591
|
+
const w = readUint32BE(b, 16);
|
|
9592
|
+
const h = readUint32BE(b, 20);
|
|
9593
|
+
if (!w || !h)
|
|
9594
|
+
return null;
|
|
9595
|
+
return { w, h };
|
|
9596
|
+
}
|
|
9597
|
+
function parseJpegDimensions(b) {
|
|
9598
|
+
if (b.length < 4 || b[0] !== 255 || b[1] !== 216)
|
|
9599
|
+
return null;
|
|
9600
|
+
let i = 2;
|
|
9601
|
+
while (i < b.length - 8) {
|
|
9602
|
+
if (b[i] !== 255) {
|
|
9603
|
+
i++;
|
|
9604
|
+
continue;
|
|
9605
|
+
}
|
|
9606
|
+
const marker = b[i + 1];
|
|
9607
|
+
if (marker === undefined)
|
|
9608
|
+
break;
|
|
9609
|
+
if (isSofMarker(marker)) {
|
|
9610
|
+
const h = b[i + 5] << 8 | b[i + 6];
|
|
9611
|
+
const w = b[i + 7] << 8 | b[i + 8];
|
|
9612
|
+
if (w && h)
|
|
9613
|
+
return { w, h };
|
|
9614
|
+
return null;
|
|
9615
|
+
}
|
|
9616
|
+
if (marker === 216 || marker === 217 || marker === 1) {
|
|
9617
|
+
i += 2;
|
|
9618
|
+
continue;
|
|
9619
|
+
}
|
|
9620
|
+
const segLen = b[i + 2] << 8 | b[i + 3];
|
|
9621
|
+
if (segLen < 2)
|
|
9622
|
+
return null;
|
|
9623
|
+
i += 2 + segLen;
|
|
9624
|
+
}
|
|
9625
|
+
return null;
|
|
9626
|
+
}
|
|
9627
|
+
function isSofMarker(m) {
|
|
9628
|
+
if (m >= 192 && m <= 195)
|
|
9629
|
+
return true;
|
|
9630
|
+
if (m >= 197 && m <= 199)
|
|
9631
|
+
return true;
|
|
9632
|
+
if (m >= 201 && m <= 203)
|
|
9633
|
+
return true;
|
|
9634
|
+
if (m >= 205 && m <= 207)
|
|
9635
|
+
return true;
|
|
9636
|
+
return false;
|
|
9637
|
+
}
|
|
9638
|
+
function parseWebpDimensions(b) {
|
|
9639
|
+
if (b.length < 30)
|
|
9640
|
+
return null;
|
|
9641
|
+
if (b[0] !== 82 || b[1] !== 73 || b[2] !== 70 || b[3] !== 70)
|
|
9642
|
+
return null;
|
|
9643
|
+
if (b[8] !== 87 || b[9] !== 69 || b[10] !== 66 || b[11] !== 80)
|
|
9644
|
+
return null;
|
|
9645
|
+
const variant = String.fromCharCode(b[12], b[13], b[14], b[15]);
|
|
9646
|
+
if (variant === "VP8 ") {
|
|
9647
|
+
const w = (b[26] | b[27] << 8) & 16383;
|
|
9648
|
+
const h = (b[28] | b[29] << 8) & 16383;
|
|
9649
|
+
if (w && h)
|
|
9650
|
+
return { w, h };
|
|
9651
|
+
} else if (variant === "VP8L") {
|
|
9652
|
+
const b0 = b[21];
|
|
9653
|
+
const b1 = b[22];
|
|
9654
|
+
const b2 = b[23];
|
|
9655
|
+
const b3 = b[24];
|
|
9656
|
+
const w = 1 + ((b0 | b1 << 8) & 16383);
|
|
9657
|
+
const h = 1 + ((b1 >> 6 | b2 << 2 | b3 << 10) & 16383);
|
|
9658
|
+
if (w && h)
|
|
9659
|
+
return { w, h };
|
|
9660
|
+
} else if (variant === "VP8X") {
|
|
9661
|
+
const w = 1 + (b[24] | b[25] << 8 | b[26] << 16);
|
|
9662
|
+
const h = 1 + (b[27] | b[28] << 8 | b[29] << 16);
|
|
9663
|
+
if (w && h)
|
|
9664
|
+
return { w, h };
|
|
9665
|
+
}
|
|
9666
|
+
return null;
|
|
9667
|
+
}
|
|
9668
|
+
function parseGifDimensions(b) {
|
|
9669
|
+
if (b.length < 10)
|
|
9670
|
+
return null;
|
|
9671
|
+
if (b[0] !== 71 || b[1] !== 73 || b[2] !== 70)
|
|
9672
|
+
return null;
|
|
9673
|
+
const w = b[6] | b[7] << 8;
|
|
9674
|
+
const h = b[8] | b[9] << 8;
|
|
9675
|
+
if (!w || !h)
|
|
9676
|
+
return null;
|
|
9677
|
+
return { w, h };
|
|
9678
|
+
}
|
|
9679
|
+
function readUint32BE(b, offset) {
|
|
9680
|
+
return (b[offset] << 24 | b[offset + 1] << 16 | b[offset + 2] << 8 | b[offset + 3]) >>> 0;
|
|
9681
|
+
}
|
|
9682
|
+
|
|
9683
|
+
// src/hooks/magic-context/todo-view.ts
|
|
9684
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
9685
|
+
var TODO_STATUS_PENDING = "pending";
|
|
9686
|
+
var TODO_STATUS_IN_PROGRESS = "in_progress";
|
|
9687
|
+
var TODO_STATUS_COMPLETED = "completed";
|
|
9688
|
+
var TODO_STATUS_CANCELLED = "cancelled";
|
|
9689
|
+
var TODO_PRIORITY_HIGH = "high";
|
|
9690
|
+
var TODO_PRIORITY_MEDIUM = "medium";
|
|
9691
|
+
var TODO_PRIORITY_LOW = "low";
|
|
9692
|
+
var TODO_STATUSES = [
|
|
9693
|
+
TODO_STATUS_PENDING,
|
|
9694
|
+
TODO_STATUS_IN_PROGRESS,
|
|
9695
|
+
TODO_STATUS_COMPLETED,
|
|
9696
|
+
TODO_STATUS_CANCELLED
|
|
9697
|
+
];
|
|
9698
|
+
var TODO_PRIORITIES = [
|
|
9699
|
+
TODO_PRIORITY_HIGH,
|
|
9700
|
+
TODO_PRIORITY_MEDIUM,
|
|
9701
|
+
TODO_PRIORITY_LOW
|
|
9702
|
+
];
|
|
9703
|
+
var TODO_STATUS_SET = new Set(TODO_STATUSES);
|
|
9704
|
+
var TODO_PRIORITY_SET = new Set(TODO_PRIORITIES);
|
|
9705
|
+
var TERMINAL_STATUSES = new Set([
|
|
9706
|
+
TODO_STATUS_COMPLETED,
|
|
9707
|
+
TODO_STATUS_CANCELLED
|
|
9708
|
+
]);
|
|
9709
|
+
var TITLE_DONE_STATUSES = new Set([TODO_STATUS_COMPLETED]);
|
|
9710
|
+
var SYNTHETIC_CALL_ID_PREFIX = "mc_synthetic_todo_";
|
|
9711
|
+
function normalizeTodoStateJson(todos) {
|
|
9712
|
+
if (!Array.isArray(todos))
|
|
9713
|
+
return null;
|
|
9714
|
+
const normalized = [];
|
|
9715
|
+
for (const todo of todos) {
|
|
9716
|
+
if (!isTodoItem(todo))
|
|
9717
|
+
return null;
|
|
9718
|
+
normalized.push({
|
|
9719
|
+
content: todo.content,
|
|
9720
|
+
status: todo.status,
|
|
9721
|
+
priority: todo.priority ?? TODO_PRIORITY_MEDIUM
|
|
9722
|
+
});
|
|
9723
|
+
}
|
|
9724
|
+
return JSON.stringify(normalized);
|
|
9725
|
+
}
|
|
9726
|
+
function buildSyntheticTodoPart(stateJson) {
|
|
9727
|
+
const todos = parseTodoState(stateJson);
|
|
9728
|
+
if (todos === null || todos.length === 0)
|
|
9729
|
+
return null;
|
|
9730
|
+
if (todos.every((t) => TERMINAL_STATUSES.has(t.status)))
|
|
9731
|
+
return null;
|
|
9732
|
+
const callID = computeSyntheticCallId(stateJson);
|
|
9733
|
+
const activeCount = todos.filter((t) => !TITLE_DONE_STATUSES.has(t.status)).length;
|
|
9734
|
+
const output = JSON.stringify(todos, null, 2);
|
|
9735
|
+
const ts = 0;
|
|
9736
|
+
return {
|
|
9737
|
+
type: "tool",
|
|
9738
|
+
callID,
|
|
9739
|
+
tool: "todowrite",
|
|
9740
|
+
state: {
|
|
9741
|
+
status: "completed",
|
|
9742
|
+
input: { todos },
|
|
9743
|
+
output,
|
|
9744
|
+
title: `${activeCount} todos`,
|
|
9745
|
+
metadata: { todos, truncated: false },
|
|
9746
|
+
time: { start: ts, end: ts }
|
|
9747
|
+
},
|
|
9748
|
+
syntheticTodoMarker: true
|
|
9749
|
+
};
|
|
9750
|
+
}
|
|
9751
|
+
function computeSyntheticCallId(stateJson) {
|
|
9752
|
+
const hash = createHash8("sha256").update(stateJson).digest("hex").slice(0, 16);
|
|
9753
|
+
return `${SYNTHETIC_CALL_ID_PREFIX}${hash}`;
|
|
9754
|
+
}
|
|
9755
|
+
function isSyntheticTodoPart(part) {
|
|
9756
|
+
if (part === null || typeof part !== "object")
|
|
9757
|
+
return false;
|
|
9758
|
+
const p = part;
|
|
9759
|
+
if (p.syntheticTodoMarker === true)
|
|
9760
|
+
return true;
|
|
9761
|
+
return p.type === "tool" && p.tool === "todowrite" && typeof p.callID === "string" && p.callID.startsWith(SYNTHETIC_CALL_ID_PREFIX);
|
|
9762
|
+
}
|
|
9763
|
+
function parseTodoState(stateJson) {
|
|
9764
|
+
if (stateJson.length === 0)
|
|
9765
|
+
return null;
|
|
9766
|
+
try {
|
|
9767
|
+
const parsed = JSON.parse(stateJson);
|
|
9768
|
+
if (!Array.isArray(parsed))
|
|
9769
|
+
return null;
|
|
9770
|
+
const result = [];
|
|
9771
|
+
for (const item of parsed) {
|
|
9772
|
+
if (!isTodoItem(item))
|
|
9773
|
+
return null;
|
|
9774
|
+
result.push({
|
|
9775
|
+
content: item.content,
|
|
9776
|
+
status: item.status,
|
|
9777
|
+
priority: item.priority ?? TODO_PRIORITY_MEDIUM
|
|
9778
|
+
});
|
|
9779
|
+
}
|
|
9780
|
+
return result;
|
|
9781
|
+
} catch {
|
|
9782
|
+
return null;
|
|
9783
|
+
}
|
|
9784
|
+
}
|
|
9785
|
+
function isTodoStatus(value) {
|
|
9786
|
+
return typeof value === "string" && TODO_STATUS_SET.has(value);
|
|
9787
|
+
}
|
|
9788
|
+
function isTodoPriority(value) {
|
|
9789
|
+
return typeof value === "string" && TODO_PRIORITY_SET.has(value);
|
|
9790
|
+
}
|
|
9791
|
+
function isTodoItem(value) {
|
|
9792
|
+
if (value === null || typeof value !== "object")
|
|
9793
|
+
return false;
|
|
9794
|
+
const todo = value;
|
|
9795
|
+
return typeof todo.content === "string" && isTodoStatus(todo.status) && (todo.priority === undefined || isTodoPriority(todo.priority));
|
|
9796
|
+
}
|
|
9797
|
+
|
|
9798
|
+
// src/hooks/magic-context/tail-hygiene-walk.ts
|
|
9799
|
+
var MAX_CONTENT_MEMO_ENTRIES = 1e5;
|
|
9800
|
+
var MAX_CONTENT_MEMO_BYTES = 64 * 1024 * 1024;
|
|
9801
|
+
var contentMemo = new Map;
|
|
9802
|
+
var contentMemoBytes = 0;
|
|
9803
|
+
var FNV1A_32_OFFSET = 2166136261;
|
|
9804
|
+
var FNV1A_32_PRIME = 16777619;
|
|
9805
|
+
var TAG_PREFIX = /^§\d+§\s*/;
|
|
9806
|
+
var DROP_PREFIXES = ["[dropped", "[truncated"];
|
|
9807
|
+
var CHANNEL1_REMINDER_OPEN = `
|
|
9808
|
+
|
|
9809
|
+
<system-reminder>
|
|
9810
|
+
`;
|
|
9811
|
+
var CHANNEL1_REMINDER_CLOSE = `
|
|
9812
|
+
</system-reminder>`;
|
|
9813
|
+
var TODO_HEAD_ANCHOR_ID = "__magic_context_todo_head__";
|
|
9814
|
+
function fnv1a32(value) {
|
|
9815
|
+
let hash = FNV1A_32_OFFSET;
|
|
9816
|
+
for (let index = 0;index < value.length; index += 1) {
|
|
9817
|
+
hash ^= value.charCodeAt(index);
|
|
9818
|
+
hash = Math.imul(hash, FNV1A_32_PRIME) >>> 0;
|
|
9819
|
+
}
|
|
9820
|
+
return hash.toString(16).padStart(8, "0");
|
|
9821
|
+
}
|
|
9822
|
+
function memoizedContent(kind, content) {
|
|
9823
|
+
const key = `${kind}\x00${content}`;
|
|
9824
|
+
const cached = contentMemo.get(key);
|
|
9825
|
+
if (cached)
|
|
9826
|
+
return cached;
|
|
9827
|
+
const measured = {
|
|
9828
|
+
hash: fnv1a32(key),
|
|
9829
|
+
tokens: kind === "excluded" ? 0 : estimateTokens(content),
|
|
9830
|
+
keyBytes: key.length * 2 + 32
|
|
9831
|
+
};
|
|
9832
|
+
contentMemo.set(key, measured);
|
|
9833
|
+
contentMemoBytes += measured.keyBytes;
|
|
9834
|
+
while (contentMemo.size > MAX_CONTENT_MEMO_ENTRIES || contentMemoBytes > MAX_CONTENT_MEMO_BYTES) {
|
|
9835
|
+
const oldest = contentMemo.keys().next().value;
|
|
9836
|
+
if (typeof oldest !== "string")
|
|
9837
|
+
break;
|
|
9838
|
+
const removed = contentMemo.get(oldest);
|
|
9839
|
+
if (removed)
|
|
9840
|
+
contentMemoBytes -= removed.keyBytes;
|
|
9841
|
+
contentMemo.delete(oldest);
|
|
9842
|
+
}
|
|
9843
|
+
return measured;
|
|
9844
|
+
}
|
|
9845
|
+
function safeStableStringify(value) {
|
|
9846
|
+
if (value === undefined || value === null)
|
|
9847
|
+
return "";
|
|
9848
|
+
if (typeof value === "string")
|
|
9849
|
+
return value;
|
|
9850
|
+
try {
|
|
9851
|
+
return stableStringify(value);
|
|
9852
|
+
} catch {
|
|
9853
|
+
return String(value);
|
|
9854
|
+
}
|
|
9855
|
+
}
|
|
9856
|
+
function firstString(record, fields) {
|
|
9857
|
+
for (const field of fields) {
|
|
9858
|
+
const value = record[field];
|
|
9859
|
+
if (typeof value === "string")
|
|
9860
|
+
return value;
|
|
9861
|
+
}
|
|
9862
|
+
return "";
|
|
9863
|
+
}
|
|
9864
|
+
function callIdFromPart(part) {
|
|
9865
|
+
const direct = firstString(part, ["callID", "callId", "toolCallId", "tool_call_id", "id"]);
|
|
9866
|
+
if (direct)
|
|
9867
|
+
return direct;
|
|
9868
|
+
const state2 = isRecord(part.state) ? part.state : null;
|
|
9869
|
+
return state2 ? firstString(state2, ["callID", "callId", "toolCallId", "tool_call_id", "id"]) : "";
|
|
9870
|
+
}
|
|
9871
|
+
function toolResultCallId(part) {
|
|
9872
|
+
return firstString(part, ["tool_use_id", "toolUseId", "callID", "callId"]);
|
|
9873
|
+
}
|
|
9874
|
+
function messageIdentity(message, messageIndex) {
|
|
9875
|
+
return typeof message.info.id === "string" ? message.info.id : `ordinal:${messageIndex}:${message.info.role ?? "unknown"}`;
|
|
9876
|
+
}
|
|
9877
|
+
function collectToolPartIdentities(messages) {
|
|
9878
|
+
const identities = new Map;
|
|
9879
|
+
const pendingOwners = new Map;
|
|
9880
|
+
for (let messageIndex = 0;messageIndex < messages.length; messageIndex += 1) {
|
|
9881
|
+
const message = messages[messageIndex];
|
|
9882
|
+
const currentOwner = messageIdentity(message, messageIndex);
|
|
9883
|
+
for (const part of message.parts) {
|
|
9884
|
+
if (!isRecord(part))
|
|
9885
|
+
continue;
|
|
9886
|
+
if (part.type === "tool-invocation" || part.type === "tool_use") {
|
|
9887
|
+
const callId = callIdFromPart(part);
|
|
9888
|
+
if (!callId)
|
|
9889
|
+
continue;
|
|
9890
|
+
const owners = pendingOwners.get(callId) ?? [];
|
|
9891
|
+
owners.push(currentOwner);
|
|
9892
|
+
pendingOwners.set(callId, owners);
|
|
9893
|
+
identities.set(part, {
|
|
9894
|
+
callId,
|
|
9895
|
+
ownerMessageId: currentOwner,
|
|
9896
|
+
messageIndex,
|
|
9897
|
+
kind: "invocation"
|
|
9898
|
+
});
|
|
9899
|
+
continue;
|
|
9900
|
+
}
|
|
9901
|
+
if (part.type === "tool_result") {
|
|
9902
|
+
const callId = toolResultCallId(part);
|
|
9903
|
+
if (!callId)
|
|
9904
|
+
continue;
|
|
9905
|
+
const owners = pendingOwners.get(callId);
|
|
9906
|
+
const ownerMessageId = owners?.shift() ?? currentOwner;
|
|
9907
|
+
identities.set(part, {
|
|
9908
|
+
callId,
|
|
9909
|
+
ownerMessageId,
|
|
9910
|
+
messageIndex,
|
|
9911
|
+
kind: "result"
|
|
9912
|
+
});
|
|
9913
|
+
continue;
|
|
9914
|
+
}
|
|
9915
|
+
if (part.type === "tool") {
|
|
9916
|
+
const callId = callIdFromPart(part);
|
|
9917
|
+
if (!callId)
|
|
9918
|
+
continue;
|
|
9919
|
+
identities.set(part, {
|
|
9920
|
+
callId,
|
|
9921
|
+
ownerMessageId: currentOwner,
|
|
9922
|
+
messageIndex,
|
|
9923
|
+
kind: "native"
|
|
9924
|
+
});
|
|
9925
|
+
}
|
|
9926
|
+
}
|
|
9927
|
+
}
|
|
9928
|
+
return identities;
|
|
9929
|
+
}
|
|
9930
|
+
function isSyntheticMessage(message) {
|
|
9931
|
+
const structuralHead = message.info.id === undefined && message.info.role === "user" && message.parts.length > 0 && message.parts.every((part) => isRecord(part) && part.synthetic === true);
|
|
9932
|
+
return structuralHead || message.info.summary === true || message.info.id === TODO_HEAD_ANCHOR_ID;
|
|
9933
|
+
}
|
|
9934
|
+
function isSyntheticPart(part) {
|
|
9935
|
+
return isRecord(part) && part.synthetic === true || isSyntheticTodoPart(part);
|
|
9936
|
+
}
|
|
9937
|
+
function stripChannel1ReminderSpans(output) {
|
|
9938
|
+
let stripped = output;
|
|
9939
|
+
while (stripped.endsWith(CHANNEL1_REMINDER_CLOSE)) {
|
|
9940
|
+
const opener = stripped.lastIndexOf(CHANNEL1_REMINDER_OPEN);
|
|
9941
|
+
if (opener < 0)
|
|
9942
|
+
break;
|
|
9943
|
+
stripped = stripped.slice(0, opener);
|
|
9944
|
+
}
|
|
9945
|
+
return stripped;
|
|
9946
|
+
}
|
|
9947
|
+
function isDropSentinel(content) {
|
|
9948
|
+
const stripped = content.trimStart().replace(TAG_PREFIX, "").trimStart().toLowerCase();
|
|
9949
|
+
return DROP_PREFIXES.some((prefix) => stripped.startsWith(prefix));
|
|
9950
|
+
}
|
|
9951
|
+
function toolOutputText(part) {
|
|
9952
|
+
if (part.type === "tool") {
|
|
9953
|
+
const state2 = isRecord(part.state) ? part.state : null;
|
|
9954
|
+
if (!state2)
|
|
9955
|
+
return null;
|
|
9956
|
+
if (state2.output !== undefined)
|
|
9957
|
+
return safeStableStringify(state2.output);
|
|
9958
|
+
if (state2.error !== undefined)
|
|
9959
|
+
return safeStableStringify(state2.error);
|
|
9960
|
+
if (state2.result !== undefined)
|
|
9961
|
+
return safeStableStringify(state2.result);
|
|
9962
|
+
return null;
|
|
9963
|
+
}
|
|
9964
|
+
if (part.type === "tool_result") {
|
|
9965
|
+
const value = part.content ?? part.output ?? part.result;
|
|
9966
|
+
return value === undefined ? null : safeStableStringify(value);
|
|
9967
|
+
}
|
|
9968
|
+
return null;
|
|
9969
|
+
}
|
|
9970
|
+
function toolInputText(part) {
|
|
9971
|
+
if (part.type === "tool") {
|
|
9972
|
+
const state2 = isRecord(part.state) ? part.state : null;
|
|
9973
|
+
if (!state2 || state2.input === undefined)
|
|
9974
|
+
return null;
|
|
9975
|
+
return safeStableStringify(state2.input);
|
|
9976
|
+
}
|
|
9977
|
+
if (part.type === "tool-invocation") {
|
|
9978
|
+
const value = part.args ?? part.input;
|
|
9979
|
+
return value === undefined ? null : safeStableStringify(value);
|
|
9980
|
+
}
|
|
9981
|
+
if (part.type === "tool_use") {
|
|
9982
|
+
return part.input === undefined ? null : safeStableStringify(part.input);
|
|
9983
|
+
}
|
|
9984
|
+
return null;
|
|
9985
|
+
}
|
|
9986
|
+
function messageIdForTag(tag) {
|
|
9987
|
+
if (tag.type === "tool")
|
|
9988
|
+
return tag.toolOwnerMessageId;
|
|
9989
|
+
return tag.messageId.replace(/:(?:p|file)\d+$/, "");
|
|
9990
|
+
}
|
|
9991
|
+
function protectedTagNumbers(tags, protectedTags) {
|
|
9992
|
+
const active = Array.from(new Set(tags.filter((tag) => tag.status === "active").map((tag) => tag.tagNumber))).sort((left, right) => right - left).slice(0, Math.max(0, protectedTags));
|
|
9993
|
+
const protectedNumbers = new Set(active);
|
|
9994
|
+
const protectedCtxReduceTags = newestCtxReduceTagNumbers(tags.filter((tag) => tag.status === "active" && tag.type === "tool"));
|
|
9995
|
+
for (const tagNumber of protectedCtxReduceTags)
|
|
9996
|
+
protectedNumbers.add(tagNumber);
|
|
9997
|
+
return protectedNumbers;
|
|
9998
|
+
}
|
|
9999
|
+
function neighborhoodConsistent(args) {
|
|
10000
|
+
let previousMax = null;
|
|
10001
|
+
for (let index = 0;index <= args.messageIndex; index += 1) {
|
|
10002
|
+
const bound = args.boundsByMessageIndex.get(index);
|
|
10003
|
+
if (bound)
|
|
10004
|
+
previousMax = previousMax === null ? bound.max : Math.max(previousMax, bound.max);
|
|
10005
|
+
}
|
|
10006
|
+
let nextMin = null;
|
|
10007
|
+
for (let index = args.messageIndex + 1;index < args.messageCount; index += 1) {
|
|
10008
|
+
const bound = args.boundsByMessageIndex.get(index);
|
|
10009
|
+
if (bound)
|
|
10010
|
+
nextMin = nextMin === null ? bound.min : Math.min(nextMin, bound.min);
|
|
10011
|
+
}
|
|
10012
|
+
if (previousMax === null || nextMin === null)
|
|
10013
|
+
return false;
|
|
10014
|
+
return args.orphanTagNumber >= previousMax && args.orphanTagNumber <= nextMin;
|
|
10015
|
+
}
|
|
10016
|
+
function buildTagAttribution(args) {
|
|
10017
|
+
const protectedNumbers = protectedTagNumbers(args.tags, args.protectedTags);
|
|
10018
|
+
const messageTags = new Map;
|
|
10019
|
+
const exactToolTags = new Map;
|
|
10020
|
+
const orphanTagsByCall = new Map;
|
|
10021
|
+
const messageIndexById = new Map;
|
|
10022
|
+
for (let index = 0;index < args.messages.length; index += 1) {
|
|
10023
|
+
const id = args.messages[index].info.id;
|
|
10024
|
+
if (typeof id === "string")
|
|
10025
|
+
messageIndexById.set(id, index);
|
|
10026
|
+
}
|
|
10027
|
+
const boundsByMessageIndex = new Map;
|
|
10028
|
+
for (const tag of args.tags) {
|
|
10029
|
+
if (tag.type === "tool") {
|
|
10030
|
+
if (tag.toolOwnerMessageId === null) {
|
|
10031
|
+
const rows = orphanTagsByCall.get(tag.messageId) ?? [];
|
|
10032
|
+
rows.push(tag);
|
|
10033
|
+
orphanTagsByCall.set(tag.messageId, rows);
|
|
10034
|
+
} else {
|
|
10035
|
+
exactToolTags.set(`${tag.toolOwnerMessageId}\x00${tag.messageId}`, tag);
|
|
10036
|
+
}
|
|
10037
|
+
} else {
|
|
10038
|
+
messageTags.set(tag.messageId, tag);
|
|
10039
|
+
}
|
|
10040
|
+
const ownerId = messageIdForTag(tag);
|
|
10041
|
+
const index = ownerId === null ? undefined : messageIndexById.get(ownerId);
|
|
10042
|
+
if (index === undefined)
|
|
10043
|
+
continue;
|
|
10044
|
+
const existing = boundsByMessageIndex.get(index);
|
|
10045
|
+
boundsByMessageIndex.set(index, {
|
|
10046
|
+
min: existing ? Math.min(existing.min, tag.tagNumber) : tag.tagNumber,
|
|
10047
|
+
max: existing ? Math.max(existing.max, tag.tagNumber) : tag.tagNumber
|
|
10048
|
+
});
|
|
10049
|
+
}
|
|
10050
|
+
const toolTagsByPart = new Map;
|
|
10051
|
+
const orphanCandidateOwners = new Map;
|
|
10052
|
+
for (const [part, identity] of args.toolIdentities) {
|
|
10053
|
+
const exact = exactToolTags.get(`${identity.ownerMessageId}\x00${identity.callId}`);
|
|
10054
|
+
if (exact) {
|
|
10055
|
+
toolTagsByPart.set(part, exact);
|
|
10056
|
+
continue;
|
|
10057
|
+
}
|
|
10058
|
+
const orphans = orphanTagsByCall.get(identity.callId);
|
|
10059
|
+
if (orphans?.length !== 1)
|
|
10060
|
+
continue;
|
|
10061
|
+
if (!neighborhoodConsistent({
|
|
10062
|
+
orphanTagNumber: orphans[0].tagNumber,
|
|
10063
|
+
messageIndex: identity.messageIndex,
|
|
10064
|
+
boundsByMessageIndex,
|
|
10065
|
+
messageCount: args.messages.length
|
|
10066
|
+
})) {
|
|
10067
|
+
continue;
|
|
10068
|
+
}
|
|
10069
|
+
const byOwner = orphanCandidateOwners.get(identity.callId) ?? new Map;
|
|
10070
|
+
const ownerParts = byOwner.get(identity.ownerMessageId) ?? [];
|
|
10071
|
+
ownerParts.push(identity);
|
|
10072
|
+
byOwner.set(identity.ownerMessageId, ownerParts);
|
|
10073
|
+
orphanCandidateOwners.set(identity.callId, byOwner);
|
|
10074
|
+
}
|
|
10075
|
+
for (const [callId, byOwner] of orphanCandidateOwners) {
|
|
10076
|
+
if (byOwner.size !== 1)
|
|
10077
|
+
continue;
|
|
10078
|
+
const orphan = orphanTagsByCall.get(callId)?.[0];
|
|
10079
|
+
if (!orphan)
|
|
10080
|
+
continue;
|
|
10081
|
+
const ownerId = byOwner.keys().next().value;
|
|
10082
|
+
if (typeof ownerId !== "string")
|
|
10083
|
+
continue;
|
|
10084
|
+
for (const [part, identity] of args.toolIdentities) {
|
|
10085
|
+
if (identity.callId === callId && identity.ownerMessageId === ownerId) {
|
|
10086
|
+
toolTagsByPart.set(part, orphan);
|
|
10087
|
+
}
|
|
10088
|
+
}
|
|
10089
|
+
}
|
|
10090
|
+
return { protectedNumbers, messageTags, toolTagsByPart };
|
|
10091
|
+
}
|
|
10092
|
+
function snapshot(args) {
|
|
10093
|
+
const memo = memoizedContent(args.kind, args.content);
|
|
10094
|
+
const tag = args.tag;
|
|
10095
|
+
const isProtected = tag ? args.protectedNumbers.has(tag.tagNumber) : false;
|
|
10096
|
+
const uTokens = tag?.status === "active" && !isProtected && args.kind !== "excluded" ? args.tokens : 0;
|
|
10097
|
+
return {
|
|
10098
|
+
key: args.key,
|
|
10099
|
+
contentHash: memo.hash,
|
|
10100
|
+
kind: args.kind,
|
|
10101
|
+
tokens: args.tokens,
|
|
10102
|
+
uTokens,
|
|
10103
|
+
tagNumber: tag?.tagNumber ?? null,
|
|
10104
|
+
tagStatus: tag?.status ?? null,
|
|
10105
|
+
protected: isProtected
|
|
10106
|
+
};
|
|
10107
|
+
}
|
|
10108
|
+
function excludedSnapshot(key, part) {
|
|
10109
|
+
const content = safeStableStringify(part);
|
|
10110
|
+
return snapshot({
|
|
10111
|
+
key,
|
|
10112
|
+
kind: "excluded",
|
|
10113
|
+
content,
|
|
10114
|
+
tokens: 0,
|
|
10115
|
+
tag: undefined,
|
|
10116
|
+
protectedNumbers: new Set
|
|
10117
|
+
});
|
|
10118
|
+
}
|
|
10119
|
+
function fileContentAndTokens(part) {
|
|
10120
|
+
const mime = typeof part.mime === "string" ? part.mime : "";
|
|
10121
|
+
const type = typeof part.type === "string" ? part.type.toLowerCase() : "";
|
|
10122
|
+
const url = typeof part.url === "string" ? part.url : "";
|
|
10123
|
+
if (mime.startsWith("image/") || type.includes("image")) {
|
|
10124
|
+
return {
|
|
10125
|
+
content: url,
|
|
10126
|
+
tokens: url.startsWith("data:") ? estimateImageTokensFromDataUrl(url) : 1200
|
|
10127
|
+
};
|
|
10128
|
+
}
|
|
10129
|
+
const content = firstString(part, ["content", "text", "source", "url"]);
|
|
10130
|
+
const memo = memoizedContent("file", content);
|
|
10131
|
+
return { content, tokens: memo.tokens };
|
|
10132
|
+
}
|
|
10133
|
+
function contentSignature(parts) {
|
|
10134
|
+
return fnv1a32(parts.map((part) => `${part.key}:${part.contentHash}`).join("\x00"));
|
|
10135
|
+
}
|
|
10136
|
+
function tailHygieneStructuralSignature(messages) {
|
|
10137
|
+
const partCounts = [];
|
|
10138
|
+
let totalBytes = 0;
|
|
10139
|
+
for (const message of messages) {
|
|
10140
|
+
partCounts.push(message.parts.length);
|
|
10141
|
+
totalBytes += byteSize(JSON.stringify(message) ?? "");
|
|
10142
|
+
}
|
|
10143
|
+
return { messageCount: messages.length, partCounts, totalBytes };
|
|
10144
|
+
}
|
|
10145
|
+
function sameTailHygieneStructuralSignature(expected, actual) {
|
|
10146
|
+
if (expected.messageCount !== actual.messageCount || expected.totalBytes !== actual.totalBytes || expected.partCounts.length !== actual.partCounts.length) {
|
|
10147
|
+
return false;
|
|
10148
|
+
}
|
|
10149
|
+
return expected.partCounts.every((count, index) => count === actual.partCounts[index]);
|
|
10150
|
+
}
|
|
10151
|
+
function measureTailHygiene(input) {
|
|
10152
|
+
const toolIdentities = collectToolPartIdentities(input.messages);
|
|
10153
|
+
const attribution = buildTagAttribution({
|
|
10154
|
+
messages: input.messages,
|
|
10155
|
+
tags: input.tags,
|
|
10156
|
+
toolIdentities,
|
|
10157
|
+
protectedTags: input.protectedTags
|
|
10158
|
+
});
|
|
10159
|
+
const droppedToolOwners = new Set;
|
|
10160
|
+
for (const [part, identity] of toolIdentities) {
|
|
10161
|
+
if (!isRecord(part))
|
|
10162
|
+
continue;
|
|
10163
|
+
const output = toolOutputText(part);
|
|
10164
|
+
if (output !== null && isDropSentinel(output)) {
|
|
10165
|
+
droppedToolOwners.add(`${identity.ownerMessageId}\x00${identity.callId}`);
|
|
10166
|
+
}
|
|
10167
|
+
}
|
|
10168
|
+
const parts = [];
|
|
10169
|
+
let t = 0;
|
|
10170
|
+
let u = 0;
|
|
10171
|
+
for (let messageIndex = 0;messageIndex < input.messages.length; messageIndex += 1) {
|
|
10172
|
+
const message = input.messages[messageIndex];
|
|
10173
|
+
const messageKey = messageIdentity(message, messageIndex);
|
|
10174
|
+
const messageSynthetic = isSyntheticMessage(message);
|
|
10175
|
+
for (let partIndex = 0;partIndex < message.parts.length; partIndex += 1) {
|
|
10176
|
+
const part = message.parts[partIndex];
|
|
10177
|
+
const key = `${messageKey}\x00${partIndex}`;
|
|
10178
|
+
if (messageSynthetic || isSyntheticPart(part) || !isRecord(part)) {
|
|
10179
|
+
parts.push(excludedSnapshot(`${key}\x00excluded`, part));
|
|
10180
|
+
continue;
|
|
10181
|
+
}
|
|
10182
|
+
const type = typeof part.type === "string" ? part.type : "";
|
|
10183
|
+
if (type === "reasoning" || type === "thinking" || type === "redacted_thinking" || type === "signature") {
|
|
10184
|
+
parts.push(excludedSnapshot(`${key}\x00excluded`, part));
|
|
10185
|
+
continue;
|
|
10186
|
+
}
|
|
10187
|
+
if (type === "text") {
|
|
10188
|
+
const content = firstString(part, ["text", "content"]);
|
|
10189
|
+
if (!content || isDropSentinel(content)) {
|
|
10190
|
+
parts.push(excludedSnapshot(`${key}\x00excluded`, part));
|
|
10191
|
+
continue;
|
|
10192
|
+
}
|
|
10193
|
+
const memo = memoizedContent("text", content);
|
|
10194
|
+
const tag = attribution.messageTags.get(`${message.info.id}:p${partIndex}`);
|
|
10195
|
+
const measured = snapshot({
|
|
10196
|
+
key: `${key}\x00text`,
|
|
10197
|
+
kind: "text",
|
|
10198
|
+
content,
|
|
10199
|
+
tokens: memo.tokens,
|
|
10200
|
+
tag,
|
|
10201
|
+
protectedNumbers: attribution.protectedNumbers
|
|
10202
|
+
});
|
|
10203
|
+
parts.push(measured);
|
|
10204
|
+
t += measured.tokens;
|
|
10205
|
+
u += measured.uTokens;
|
|
10206
|
+
continue;
|
|
10207
|
+
}
|
|
10208
|
+
if (type === "file" || type.includes("image") || type === "source") {
|
|
10209
|
+
const file = fileContentAndTokens(part);
|
|
10210
|
+
if (!file.content || isDropSentinel(file.content)) {
|
|
10211
|
+
parts.push(excludedSnapshot(`${key}\x00excluded`, part));
|
|
10212
|
+
continue;
|
|
10213
|
+
}
|
|
10214
|
+
const tag = attribution.messageTags.get(`${message.info.id}:file${partIndex}`);
|
|
10215
|
+
const measured = snapshot({
|
|
10216
|
+
key: `${key}\x00file`,
|
|
10217
|
+
kind: "file",
|
|
10218
|
+
content: file.content,
|
|
10219
|
+
tokens: file.tokens,
|
|
10220
|
+
tag,
|
|
10221
|
+
protectedNumbers: attribution.protectedNumbers
|
|
10222
|
+
});
|
|
10223
|
+
parts.push(measured);
|
|
10224
|
+
t += measured.tokens;
|
|
10225
|
+
u += measured.uTokens;
|
|
10226
|
+
continue;
|
|
10227
|
+
}
|
|
10228
|
+
const toolIdentity = toolIdentities.get(part);
|
|
10229
|
+
if (toolIdentity) {
|
|
10230
|
+
const ownerKey = `${toolIdentity.ownerMessageId}\x00${toolIdentity.callId}`;
|
|
10231
|
+
if (droppedToolOwners.has(ownerKey)) {
|
|
10232
|
+
parts.push(excludedSnapshot(`${key}\x00excluded`, part));
|
|
10233
|
+
continue;
|
|
10234
|
+
}
|
|
10235
|
+
const tag = attribution.toolTagsByPart.get(part);
|
|
10236
|
+
const inputText = toolInputText(part);
|
|
10237
|
+
if (inputText !== null) {
|
|
10238
|
+
const memo = memoizedContent("toolInput", inputText);
|
|
10239
|
+
const measured = snapshot({
|
|
10240
|
+
key: `${key}\x00toolInput`,
|
|
10241
|
+
kind: "toolInput",
|
|
10242
|
+
content: inputText,
|
|
10243
|
+
tokens: memo.tokens,
|
|
10244
|
+
tag,
|
|
10245
|
+
protectedNumbers: attribution.protectedNumbers
|
|
10246
|
+
});
|
|
10247
|
+
parts.push(measured);
|
|
10248
|
+
t += measured.tokens;
|
|
10249
|
+
u += measured.uTokens;
|
|
10250
|
+
}
|
|
10251
|
+
const rawOutput = toolOutputText(part);
|
|
10252
|
+
if (rawOutput !== null) {
|
|
10253
|
+
const output = stripChannel1ReminderSpans(rawOutput);
|
|
10254
|
+
if (isDropSentinel(output)) {
|
|
10255
|
+
parts.push(excludedSnapshot(`${key}\x00excludedOutput`, output));
|
|
10256
|
+
} else {
|
|
10257
|
+
const memo = memoizedContent("toolOutput", output);
|
|
10258
|
+
const measured = snapshot({
|
|
10259
|
+
key: `${key}\x00toolOutput`,
|
|
10260
|
+
kind: "toolOutput",
|
|
10261
|
+
content: output,
|
|
10262
|
+
tokens: memo.tokens,
|
|
10263
|
+
tag,
|
|
10264
|
+
protectedNumbers: attribution.protectedNumbers
|
|
10265
|
+
});
|
|
10266
|
+
parts.push(measured);
|
|
10267
|
+
t += measured.tokens;
|
|
10268
|
+
u += measured.uTokens;
|
|
10269
|
+
}
|
|
10270
|
+
}
|
|
10271
|
+
if (inputText === null && rawOutput === null) {
|
|
10272
|
+
parts.push(excludedSnapshot(`${key}\x00excluded`, part));
|
|
10273
|
+
}
|
|
10274
|
+
continue;
|
|
10275
|
+
}
|
|
10276
|
+
parts.push(excludedSnapshot(`${key}\x00excluded`, part));
|
|
10277
|
+
}
|
|
10278
|
+
}
|
|
10279
|
+
return {
|
|
10280
|
+
u: Math.min(Math.max(0, u), Math.max(0, t)),
|
|
10281
|
+
t: Math.max(0, t),
|
|
10282
|
+
contentSignature: contentSignature(parts),
|
|
10283
|
+
parts
|
|
10284
|
+
};
|
|
10285
|
+
}
|
|
10286
|
+
function sameMeasuredPrefix(baseline, current) {
|
|
10287
|
+
if (current.length < baseline.length)
|
|
10288
|
+
return { valid: false, boundaryAdvanceU: 0 };
|
|
10289
|
+
let boundaryAdvanceU = 0;
|
|
10290
|
+
for (let index = 0;index < baseline.length; index += 1) {
|
|
10291
|
+
const before = baseline[index];
|
|
10292
|
+
const after = current[index];
|
|
10293
|
+
if (before.key !== after.key || before.contentHash !== after.contentHash || before.kind !== after.kind || before.tokens !== after.tokens || before.tagNumber !== after.tagNumber || before.tagStatus !== after.tagStatus) {
|
|
10294
|
+
return { valid: false, boundaryAdvanceU: 0 };
|
|
10295
|
+
}
|
|
10296
|
+
if (!before.protected && after.protected)
|
|
10297
|
+
return { valid: false, boundaryAdvanceU: 0 };
|
|
10298
|
+
if (before.protected && !after.protected) {
|
|
10299
|
+
if (after.tagStatus !== "active")
|
|
10300
|
+
return { valid: false, boundaryAdvanceU: 0 };
|
|
10301
|
+
boundaryAdvanceU += after.tokens;
|
|
10302
|
+
} else if (before.uTokens !== after.uTokens) {
|
|
10303
|
+
return { valid: false, boundaryAdvanceU: 0 };
|
|
10304
|
+
}
|
|
10305
|
+
}
|
|
10306
|
+
return { valid: true, boundaryAdvanceU };
|
|
10307
|
+
}
|
|
10308
|
+
function refreshTailHygieneBaseline(input) {
|
|
10309
|
+
const measured = measureTailHygiene(input);
|
|
10310
|
+
const now = input.now ?? Date.now();
|
|
10311
|
+
if (!input.cacheBusting && input.previous?.generationInvalidated) {
|
|
10312
|
+
return { ...input.previous, contentSignature: measured.contentSignature };
|
|
10313
|
+
}
|
|
10314
|
+
if (input.cacheBusting || !input.previous) {
|
|
10315
|
+
return {
|
|
10316
|
+
baselineU: measured.u,
|
|
10317
|
+
baselineT: measured.t,
|
|
10318
|
+
turnDeltaU: 0,
|
|
10319
|
+
turnDeltaT: 0,
|
|
10320
|
+
baselineGeneration: (input.previous?.baselineGeneration ?? 0) + 1,
|
|
10321
|
+
computedAt: now,
|
|
10322
|
+
evaluable: true,
|
|
10323
|
+
generationInvalidated: false,
|
|
10324
|
+
baselineParts: measured.parts,
|
|
10325
|
+
contentSignature: measured.contentSignature
|
|
10326
|
+
};
|
|
10327
|
+
}
|
|
10328
|
+
const prefix = sameMeasuredPrefix(input.previous.baselineParts, measured.parts);
|
|
10329
|
+
if (!prefix.valid) {
|
|
10330
|
+
return {
|
|
10331
|
+
...input.previous,
|
|
10332
|
+
evaluable: false,
|
|
10333
|
+
generationInvalidated: true,
|
|
10334
|
+
contentSignature: measured.contentSignature
|
|
10335
|
+
};
|
|
10336
|
+
}
|
|
10337
|
+
let turnDeltaT = 0;
|
|
10338
|
+
let turnDeltaU = prefix.boundaryAdvanceU;
|
|
10339
|
+
for (let index = input.previous.baselineParts.length;index < measured.parts.length; index += 1) {
|
|
10340
|
+
const part = measured.parts[index];
|
|
10341
|
+
turnDeltaT += part.tokens;
|
|
10342
|
+
if (part.kind !== "toolOutput")
|
|
10343
|
+
turnDeltaU += part.uTokens;
|
|
10344
|
+
}
|
|
10345
|
+
return {
|
|
10346
|
+
...input.previous,
|
|
10347
|
+
turnDeltaU,
|
|
10348
|
+
turnDeltaT,
|
|
10349
|
+
evaluable: true,
|
|
10350
|
+
generationInvalidated: false,
|
|
10351
|
+
contentSignature: measured.contentSignature
|
|
10352
|
+
};
|
|
10353
|
+
}
|
|
10354
|
+
function effectiveTailHygiene(baseline) {
|
|
10355
|
+
const t = Math.max(0, baseline.baselineT + baseline.turnDeltaT);
|
|
10356
|
+
const u = Math.min(t, Math.max(0, baseline.baselineU + baseline.turnDeltaU));
|
|
10357
|
+
return { u, t };
|
|
10358
|
+
}
|
|
10359
|
+
function assertTailHygieneContentUnchanged(input) {
|
|
10360
|
+
const actual = measureTailHygiene(input).contentSignature;
|
|
10361
|
+
if (actual !== input.expectedSignature) {
|
|
10362
|
+
throw new Error(`tail hygiene walk was not the last byte-affecting operation: expected ${input.expectedSignature}, got ${actual}`);
|
|
10363
|
+
}
|
|
10364
|
+
}
|
|
10365
|
+
|
|
10366
|
+
// src/hooks/magic-context/ctx-reduce-nudge.ts
|
|
10367
|
+
var CHANNEL1_SENTINEL = "<system-reminder>";
|
|
10368
|
+
var TOKENS_PER_BYTE = 0.25;
|
|
10369
|
+
var CHANNEL1_MIN_TOKENS = 60000;
|
|
10370
|
+
var CHANNEL1_FLOOR_TOKENS = 25000;
|
|
10371
|
+
var CHANNEL1_REFIRE_FLOOR_TOKENS = 25000;
|
|
10372
|
+
var S_GENTLE = 0.2;
|
|
10373
|
+
var S_FIRM = 0.4;
|
|
10374
|
+
var S_URGENT = 0.6;
|
|
10375
|
+
var LEVEL_RANK = { gentle: 1, firm: 2, urgent: 3 };
|
|
10376
|
+
function channel1RefireTokens(tailTokens) {
|
|
10377
|
+
const scaled = Math.round(0.08 * Math.max(0, tailTokens));
|
|
10378
|
+
return Math.max(CHANNEL1_REFIRE_FLOOR_TOKENS, scaled);
|
|
10379
|
+
}
|
|
10380
|
+
function toolOutputTokens(output) {
|
|
10381
|
+
return estimateTokens(stripChannel1ReminderSpans(output));
|
|
10382
|
+
}
|
|
10383
|
+
function decideChannel1(input) {
|
|
10384
|
+
const tailTokens = Math.max(0, input.baselineT + input.turnDeltaT);
|
|
10385
|
+
const undroppedTokens = Math.min(tailTokens, Math.max(0, input.baselineU + input.turnDeltaU));
|
|
10386
|
+
const severity = Math.min(1, Math.max(0, undroppedTokens / Math.max(tailTokens, 1)));
|
|
10387
|
+
const resetCycle = input.hasRecentReduce || undroppedTokens < input.lastNudgeUndropped;
|
|
10388
|
+
const lastNudge = resetCycle ? 0 : input.lastNudgeUndropped;
|
|
10389
|
+
const lastLevel = resetCycle ? "" : input.lastNudgeLevel;
|
|
10390
|
+
const quiet = () => ({
|
|
10391
|
+
fire: false,
|
|
10392
|
+
level: "gentle",
|
|
10393
|
+
undroppedTokens,
|
|
10394
|
+
tailTokens,
|
|
10395
|
+
severity,
|
|
10396
|
+
nextLastNudge: lastNudge,
|
|
10397
|
+
nextLastNudgeLevel: lastLevel
|
|
10398
|
+
});
|
|
10399
|
+
if (input.evaluable === false || input.generationInvalidated === true)
|
|
10400
|
+
return quiet();
|
|
10401
|
+
if (input.hasRecentReduce)
|
|
10402
|
+
return quiet();
|
|
10403
|
+
if (tailTokens < CHANNEL1_MIN_TOKENS)
|
|
10404
|
+
return quiet();
|
|
10405
|
+
if (undroppedTokens < CHANNEL1_FLOOR_TOKENS || undroppedTokens === 0)
|
|
10406
|
+
return quiet();
|
|
10407
|
+
if (severity < S_GENTLE)
|
|
10408
|
+
return quiet();
|
|
10409
|
+
let level;
|
|
10410
|
+
if (severity >= S_URGENT)
|
|
10411
|
+
level = "urgent";
|
|
10412
|
+
else if (severity >= S_FIRM)
|
|
10413
|
+
level = "firm";
|
|
10414
|
+
else
|
|
10415
|
+
level = "gentle";
|
|
10416
|
+
const escalated = lastLevel === "" || LEVEL_RANK[level] > LEVEL_RANK[lastLevel];
|
|
10417
|
+
const cadenceReached = lastLevel !== "" && undroppedTokens - lastNudge >= channel1RefireTokens(tailTokens);
|
|
10418
|
+
if (!escalated && !cadenceReached)
|
|
10419
|
+
return quiet();
|
|
10420
|
+
return {
|
|
10421
|
+
fire: true,
|
|
10422
|
+
level,
|
|
10423
|
+
undroppedTokens,
|
|
10424
|
+
tailTokens,
|
|
10425
|
+
severity,
|
|
10426
|
+
nextLastNudge: undroppedTokens,
|
|
10427
|
+
nextLastNudgeLevel: level
|
|
10428
|
+
};
|
|
10429
|
+
}
|
|
10430
|
+
var CHANNEL2_SEVERITY_THRESHOLD = 0.75;
|
|
10431
|
+
var CHANNEL2_FLOOR_TOKENS = 50000;
|
|
10432
|
+
function evaluateChannel2(input) {
|
|
10433
|
+
const values = input ? [input.baselineU, input.baselineT, input.turnDeltaU, input.turnDeltaT] : [];
|
|
10434
|
+
if (input?.evaluable !== true || input.generationInvalidated === true || values.some((value) => !Number.isFinite(value))) {
|
|
10435
|
+
return {
|
|
10436
|
+
evaluable: false,
|
|
10437
|
+
shouldTrigger: false,
|
|
10438
|
+
reclaimableTokens: 0,
|
|
10439
|
+
tailTokens: 0,
|
|
10440
|
+
severity: 0
|
|
10441
|
+
};
|
|
10442
|
+
}
|
|
10443
|
+
const tailTokens = Math.max(0, input.baselineT + input.turnDeltaT);
|
|
10444
|
+
const reclaimableTokens = Math.min(tailTokens, Math.max(0, input.baselineU + input.turnDeltaU));
|
|
10445
|
+
const severity = Math.min(1, Math.max(0, reclaimableTokens / Math.max(tailTokens, 1)));
|
|
10446
|
+
return {
|
|
10447
|
+
evaluable: true,
|
|
10448
|
+
shouldTrigger: tailTokens >= CHANNEL1_MIN_TOKENS && reclaimableTokens >= CHANNEL2_FLOOR_TOKENS && severity >= CHANNEL2_SEVERITY_THRESHOLD,
|
|
10449
|
+
reclaimableTokens,
|
|
10450
|
+
tailTokens,
|
|
10451
|
+
severity
|
|
10452
|
+
};
|
|
10453
|
+
}
|
|
10454
|
+
function approxThousands(tokens) {
|
|
10455
|
+
return `${Math.round(tokens / 1000)}k`;
|
|
10456
|
+
}
|
|
10457
|
+
function formatOldestReclaimableHint(hint) {
|
|
10458
|
+
if (!hint || hint.length === 0)
|
|
10459
|
+
return "";
|
|
10460
|
+
const rendered = hint.slice(0, 4).map((tag) => `§${tag.tagNumber}§ ${tag.toolName ?? "tool"}`).join(" · ");
|
|
10461
|
+
return rendered.length > 0 ? `
|
|
10462
|
+
oldest reclaimable: ${rendered}.` : "";
|
|
10463
|
+
}
|
|
10464
|
+
function buildChannel2Reminder(undroppedTokens, hint) {
|
|
10465
|
+
const amount = approxThousands(undroppedTokens);
|
|
10466
|
+
const hintText = formatOldestReclaimableHint(hint);
|
|
10467
|
+
return `<system-reminder>
|
|
10468
|
+
` + `Routine context housekeeping is near: a large span of this session will be comparted soon, ` + `and ~${amount} tokens of tool output remain unreduced. Drop spent outputs with ctx_reduce ` + `first so the archived span is the part that matters.${hintText}
|
|
10469
|
+
` + `</system-reminder>`;
|
|
10470
|
+
}
|
|
10471
|
+
function buildChannel1Reminder(level, undroppedTokens, hint) {
|
|
10472
|
+
const amount = approxThousands(undroppedTokens);
|
|
10473
|
+
const hintText = formatOldestReclaimableHint(hint);
|
|
10474
|
+
let body;
|
|
10475
|
+
switch (level) {
|
|
10476
|
+
case "gentle":
|
|
10477
|
+
body = `You have ~${amount} tokens of content you have not reduced. ` + `When you are done with earlier outputs, dropping them with ctx_reduce keeps context lean.`;
|
|
10478
|
+
break;
|
|
10479
|
+
case "firm":
|
|
10480
|
+
body = `~${amount} tokens of unreduced content has built up. ` + `At your next natural stopping point, consider dropping what you have already processed with ctx_reduce.`;
|
|
10481
|
+
break;
|
|
10482
|
+
case "urgent":
|
|
10483
|
+
body = `~${amount} tokens of unreduced content remain across most of the live tail. ` + `Consider dropping spent outputs with ctx_reduce so the archived span is the part that matters.`;
|
|
10484
|
+
break;
|
|
10485
|
+
}
|
|
10486
|
+
return `
|
|
10487
|
+
|
|
10488
|
+
<system-reminder>
|
|
10489
|
+
${body}${hintText}
|
|
10490
|
+
</system-reminder>`;
|
|
10491
|
+
}
|
|
10492
|
+
|
|
10493
|
+
// src/hooks/magic-context/emergency-drop.ts
|
|
10494
|
+
var TARGET_FRACTION = 0.3;
|
|
10495
|
+
var TIER_RECENCY_RESERVE = 0.2;
|
|
10496
|
+
var EMERGENCY_REARM_MIN_TOKENS = 2000;
|
|
10497
|
+
var T1_TOOLS = new Set(["read", "todowrite", "task", "aft_outline", "aft_zoom"]);
|
|
10498
|
+
var T2_TOOLS = new Set(["edit", "write", "apply_patch", "grep", "glob", "aft_search"]);
|
|
10499
|
+
function normalizeToolName(toolName) {
|
|
10500
|
+
if (!toolName)
|
|
10501
|
+
return "";
|
|
10502
|
+
let name = toolName.toLowerCase();
|
|
10503
|
+
if (name.startsWith("mcp_"))
|
|
10504
|
+
name = name.slice(4);
|
|
10505
|
+
return name;
|
|
10506
|
+
}
|
|
10507
|
+
function resolveToolTier(toolName) {
|
|
10508
|
+
const name = normalizeToolName(toolName);
|
|
10509
|
+
if (T1_TOOLS.has(name))
|
|
10510
|
+
return 1;
|
|
10511
|
+
if (T2_TOOLS.has(name))
|
|
10512
|
+
return 2;
|
|
10513
|
+
return 3;
|
|
10514
|
+
}
|
|
10515
|
+
function tagReclaimBytes(tag) {
|
|
10516
|
+
return tag.byteSize + tag.inputByteSize + tag.reasoningByteSize;
|
|
10517
|
+
}
|
|
10518
|
+
function estimateEmergencyDropReclaimTokens(tag) {
|
|
10519
|
+
return Math.round(tagReclaimBytes(tag) * TOKENS_PER_BYTE);
|
|
10520
|
+
}
|
|
10521
|
+
function planEmergencyDrop(input) {
|
|
10522
|
+
const {
|
|
10523
|
+
tags,
|
|
10524
|
+
floorTags,
|
|
10525
|
+
maxTag,
|
|
10526
|
+
protectedTags,
|
|
10527
|
+
currentTotalInputTokens,
|
|
10528
|
+
ceilingTokens,
|
|
10529
|
+
priorInputSample,
|
|
10530
|
+
hasPriorDrop
|
|
10531
|
+
} = input;
|
|
10532
|
+
const noop = (reason) => ({
|
|
10533
|
+
shouldDrop: false,
|
|
10534
|
+
tagNumbers: [],
|
|
10535
|
+
reclaimTokens: 0,
|
|
10536
|
+
reason
|
|
10537
|
+
});
|
|
10538
|
+
if (!Number.isFinite(ceilingTokens) || ceilingTokens <= 0) {
|
|
10539
|
+
return noop("unknown-ceiling");
|
|
10540
|
+
}
|
|
10541
|
+
if (!Number.isFinite(currentTotalInputTokens) || currentTotalInputTokens <= 0) {
|
|
10542
|
+
return noop("unknown-usage");
|
|
10543
|
+
}
|
|
10544
|
+
if (hasPriorDrop && currentTotalInputTokens === priorInputSample) {
|
|
10545
|
+
return noop("same-input-sample (awaiting fresh usage after prior drop)");
|
|
10546
|
+
}
|
|
10547
|
+
let tailTokens = 0;
|
|
10548
|
+
for (const tag of floorTags) {
|
|
10549
|
+
if (tag.status !== "active")
|
|
10550
|
+
continue;
|
|
10551
|
+
tailTokens += estimateEmergencyDropReclaimTokens(tag);
|
|
10552
|
+
}
|
|
10553
|
+
const fixedFloor = Math.max(currentTotalInputTokens - tailTokens, 0);
|
|
10554
|
+
const workingSpan = Math.max(ceilingTokens - fixedFloor, 0);
|
|
10555
|
+
const target = fixedFloor + TARGET_FRACTION * workingSpan;
|
|
10556
|
+
const reclaimTokens = Math.round(currentTotalInputTokens - target);
|
|
10557
|
+
if (reclaimTokens <= EMERGENCY_REARM_MIN_TOKENS) {
|
|
10558
|
+
return noop(`reclaim<=min (${reclaimTokens} <= ${EMERGENCY_REARM_MIN_TOKENS})`);
|
|
10559
|
+
}
|
|
10560
|
+
const protectedCutoff = maxTag - protectedTags;
|
|
10561
|
+
const tierActive = { 1: [], 2: [] };
|
|
10562
|
+
for (const tag of tags) {
|
|
10563
|
+
if (tag.status !== "active" || tag.type !== "tool")
|
|
10564
|
+
continue;
|
|
10565
|
+
const tier = resolveToolTier(tag.toolName);
|
|
10566
|
+
if (tier === 1 || tier === 2)
|
|
10567
|
+
tierActive[tier].push(tag.tagNumber);
|
|
10568
|
+
}
|
|
10569
|
+
const reserved = new Set;
|
|
10570
|
+
for (const tier of [1, 2]) {
|
|
10571
|
+
const nums = tierActive[tier];
|
|
10572
|
+
if (nums.length === 0)
|
|
10573
|
+
continue;
|
|
10574
|
+
nums.sort((a, b) => b - a);
|
|
10575
|
+
const reserveCount = Math.ceil(TIER_RECENCY_RESERVE * nums.length);
|
|
10576
|
+
for (let i = 0;i < reserveCount && i < nums.length; i++) {
|
|
10577
|
+
reserved.add(nums[i]);
|
|
10578
|
+
}
|
|
10579
|
+
}
|
|
10580
|
+
const protectedCtxReduceTags = newestCtxReduceTagNumbers(floorTags.filter((tag) => tag.status === "active" && tag.type === "tool"));
|
|
10581
|
+
const byTier = { 1: [], 2: [], 3: [] };
|
|
10582
|
+
for (const tag of tags) {
|
|
10583
|
+
if (tag.status !== "active" || tag.type !== "tool")
|
|
10584
|
+
continue;
|
|
10585
|
+
if (tag.tagNumber > protectedCutoff)
|
|
10586
|
+
continue;
|
|
10587
|
+
if (protectedCtxReduceTags.has(tag.tagNumber))
|
|
10588
|
+
continue;
|
|
10589
|
+
const tier = resolveToolTier(tag.toolName);
|
|
10590
|
+
if ((tier === 1 || tier === 2) && reserved.has(tag.tagNumber))
|
|
10591
|
+
continue;
|
|
10592
|
+
byTier[tier].push(tag);
|
|
10593
|
+
}
|
|
10594
|
+
const selected = [];
|
|
10595
|
+
let reclaimed = 0;
|
|
10596
|
+
outer:
|
|
10597
|
+
for (const tier of [3, 2, 1]) {
|
|
10598
|
+
const group = byTier[tier];
|
|
10599
|
+
group.sort((a, b) => a.tagNumber - b.tagNumber);
|
|
10600
|
+
for (const tag of group) {
|
|
10601
|
+
selected.push(tag.tagNumber);
|
|
10602
|
+
reclaimed += estimateEmergencyDropReclaimTokens(tag);
|
|
10603
|
+
if (reclaimed >= reclaimTokens)
|
|
10604
|
+
break outer;
|
|
10605
|
+
}
|
|
10606
|
+
}
|
|
10607
|
+
if (selected.length === 0) {
|
|
10608
|
+
return noop("no-candidates");
|
|
10609
|
+
}
|
|
10610
|
+
return {
|
|
10611
|
+
shouldDrop: true,
|
|
10612
|
+
tagNumbers: selected,
|
|
10613
|
+
reclaimTokens,
|
|
10614
|
+
reason: `tiered drop: ${selected.length} tags, reclaim≈${reclaimed}/${reclaimTokens} tokens (floor≈${fixedFloor}, ceiling=${Math.round(ceilingTokens)})`
|
|
10615
|
+
};
|
|
10616
|
+
}
|
|
10617
|
+
|
|
9029
10618
|
// src/features/magic-context/storage-tags.ts
|
|
9030
10619
|
var insertTagStatements = new WeakMap;
|
|
9031
10620
|
var updateTagStatusStatements = new WeakMap;
|
|
@@ -9069,32 +10658,23 @@ function ownerMessageIdForTagRow(row) {
|
|
|
9069
10658
|
}
|
|
9070
10659
|
return row.message_id.replace(CONTENT_ID_SUFFIX, "");
|
|
9071
10660
|
}
|
|
9072
|
-
|
|
9073
|
-
|
|
9074
|
-
|
|
9075
|
-
|
|
9076
|
-
|
|
9077
|
-
|
|
9078
|
-
|
|
9079
|
-
|
|
9080
|
-
|
|
9081
|
-
|
|
9082
|
-
${toolOutputExpr} AS tool_output,
|
|
9083
|
-
COALESCE(SUM(CASE WHEN token_count IS NULL THEN 1 ELSE 0 END), 0) AS null_count
|
|
9084
|
-
FROM tags
|
|
9085
|
-
WHERE session_id = ? AND status = 'active'`;
|
|
9086
|
-
const params = protectedTags > 0 ? [sessionId, protectedTags - 1, sessionId] : [sessionId];
|
|
9087
|
-
const row = db.prepare(sql).get(...params);
|
|
9088
|
-
return {
|
|
9089
|
-
conversation: row?.conversation ?? 0,
|
|
9090
|
-
toolCall: row?.tool_call ?? 0,
|
|
9091
|
-
toolOutput: row?.tool_output ?? 0,
|
|
9092
|
-
nullCount: row?.null_count ?? 0
|
|
9093
|
-
};
|
|
9094
|
-
}
|
|
9095
|
-
var RECLAIM_HINT_EXCLUDED_TOOLS = ["todowrite"];
|
|
10661
|
+
var RECLAIM_HINT_EXCLUDED_TOOLS = new Set([
|
|
10662
|
+
"ask",
|
|
10663
|
+
"bash_kill",
|
|
10664
|
+
"bash_status",
|
|
10665
|
+
"board",
|
|
10666
|
+
"task",
|
|
10667
|
+
"todoread",
|
|
10668
|
+
"todowrite",
|
|
10669
|
+
"work"
|
|
10670
|
+
]);
|
|
9096
10671
|
var AGE_RECLAIM_MIN_TOKENS = 250;
|
|
9097
|
-
|
|
10672
|
+
function isReclaimHintExcludedTool(toolName) {
|
|
10673
|
+
if (!toolName)
|
|
10674
|
+
return false;
|
|
10675
|
+
const normalized = toolName.toLowerCase().replace(/^mcp_/, "");
|
|
10676
|
+
return normalized.startsWith("ctx_") || RECLAIM_HINT_EXCLUDED_TOOLS.has(normalized);
|
|
10677
|
+
}
|
|
9098
10678
|
function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, limit = 4) {
|
|
9099
10679
|
if (limit <= 0)
|
|
9100
10680
|
return [];
|
|
@@ -9104,24 +10684,21 @@ function getOldestActiveUnprotectedToolTags(db, sessionId, protectedTags = 0, li
|
|
|
9104
10684
|
WHERE session_id = ? AND status = 'active'
|
|
9105
10685
|
ORDER BY tag_number DESC LIMIT 1 OFFSET ?
|
|
9106
10686
|
)` : "";
|
|
9107
|
-
const excludeStateTools = RECLAIM_HINT_EXCLUDED_LIST ? `AND (tool_name IS NULL OR tool_name NOT IN (${RECLAIM_HINT_EXCLUDED_LIST}))` : "";
|
|
9108
10687
|
const valueFloor = `AND (
|
|
9109
10688
|
(token_count IS NULL AND input_token_count IS NULL)
|
|
9110
10689
|
OR (COALESCE(token_count, 0) + COALESCE(input_token_count, 0)) >= ?
|
|
9111
10690
|
)`;
|
|
9112
|
-
const params = protectedTags > 0 ? [sessionId, AGE_RECLAIM_MIN_TOKENS, sessionId, protectedTags - 1
|
|
10691
|
+
const params = protectedTags > 0 ? [sessionId, AGE_RECLAIM_MIN_TOKENS, sessionId, protectedTags - 1] : [sessionId, AGE_RECLAIM_MIN_TOKENS];
|
|
9113
10692
|
const rows = db.prepare(`SELECT tag_number, tool_name
|
|
9114
10693
|
FROM tags
|
|
9115
10694
|
WHERE session_id = ? AND status = 'active' AND type = 'tool'
|
|
9116
|
-
${excludeStateTools}
|
|
9117
10695
|
${valueFloor}
|
|
9118
10696
|
${whereProtected}
|
|
9119
|
-
ORDER BY tag_number ASC, id ASC
|
|
9120
|
-
LIMIT ?`).all(...params);
|
|
10697
|
+
ORDER BY tag_number ASC, id ASC`).all(...params);
|
|
9121
10698
|
return rows.filter((row) => typeof row.tag_number === "number").map((row) => ({
|
|
9122
10699
|
tagNumber: row.tag_number,
|
|
9123
10700
|
toolName: typeof row.tool_name === "string" ? row.tool_name : null
|
|
9124
|
-
}));
|
|
10701
|
+
})).filter((tag) => !isReclaimHintExcludedTool(tag.toolName)).sort((left, right) => resolveToolTier(right.toolName) - resolveToolTier(left.toolName) || left.tagNumber - right.tagNumber).slice(0, boundedLimit);
|
|
9125
10702
|
}
|
|
9126
10703
|
var getActiveToolTagsForAgeReclaimStatements = new WeakMap;
|
|
9127
10704
|
function getActiveToolTagsForAgeReclaim(db, sessionId) {
|
|
@@ -9134,7 +10711,7 @@ function getActiveToolTagsForAgeReclaim(db, sessionId) {
|
|
|
9134
10711
|
getActiveToolTagsForAgeReclaimStatements.set(db, stmt);
|
|
9135
10712
|
}
|
|
9136
10713
|
const rows = stmt.all(sessionId);
|
|
9137
|
-
|
|
10714
|
+
const tags = rows.filter((row) => typeof row.tag_number === "number").map((row) => {
|
|
9138
10715
|
const outputTokens = typeof row.token_count === "number" ? row.token_count : null;
|
|
9139
10716
|
const inputTokens = typeof row.input_token_count === "number" ? row.input_token_count : null;
|
|
9140
10717
|
return {
|
|
@@ -9143,6 +10720,8 @@ function getActiveToolTagsForAgeReclaim(db, sessionId) {
|
|
|
9143
10720
|
reclaimableTokens: outputTokens === null && inputTokens === null ? null : (outputTokens ?? 0) + (inputTokens ?? 0)
|
|
9144
10721
|
};
|
|
9145
10722
|
});
|
|
10723
|
+
const protectedCtxReduceTags = newestCtxReduceTagNumbers(tags);
|
|
10724
|
+
return tags.filter((tag) => !protectedCtxReduceTags.has(tag.tagNumber));
|
|
9146
10725
|
}
|
|
9147
10726
|
function getTriggerTagTokenUpperBound(db, sessionId, floor = 0) {
|
|
9148
10727
|
const sql = floor > 0 ? `SELECT
|
|
@@ -9297,8 +10876,8 @@ function isMaxTagNumberRow(row) {
|
|
|
9297
10876
|
function escapeLikePattern(value) {
|
|
9298
10877
|
return value.replaceAll("\\", "\\\\").replaceAll("%", "\\%").replaceAll("_", "\\_");
|
|
9299
10878
|
}
|
|
9300
|
-
function insertTag(db, sessionId, messageId, type,
|
|
9301
|
-
getInsertTagStatement(db).run(sessionId, messageId, type,
|
|
10879
|
+
function insertTag(db, sessionId, messageId, type, byteSize2, tagNumber, reasoningByteSize = 0, toolName = null, inputByteSize = 0, toolOwnerMessageId = null, entryFingerprint = null, tokenCounts = null) {
|
|
10880
|
+
getInsertTagStatement(db).run(sessionId, messageId, type, byteSize2, reasoningByteSize, tagNumber, toolName, inputByteSize, getHarness(), toolOwnerMessageId, entryFingerprint, tokenCounts?.tokenCount ?? null, tokenCounts?.inputTokenCount ?? null, tokenCounts?.reasoningTokenCount ?? null);
|
|
9302
10881
|
return tagNumber;
|
|
9303
10882
|
}
|
|
9304
10883
|
function updateTagStatus(db, sessionId, tagId, status) {
|
|
@@ -9403,6 +10982,7 @@ function getTagsBySession(db, sessionId) {
|
|
|
9403
10982
|
return rows.map(toTagEntry);
|
|
9404
10983
|
}
|
|
9405
10984
|
var getActiveTagsBySessionStatements = new WeakMap;
|
|
10985
|
+
var getNullOwnerToolTagsBySessionStatements = new WeakMap;
|
|
9406
10986
|
var getDroppedTagsBySessionStatements = new WeakMap;
|
|
9407
10987
|
var getMaxDroppedTagNumberStatements = new WeakMap;
|
|
9408
10988
|
function getActiveTagsBySessionStatement(db) {
|
|
@@ -9433,6 +11013,24 @@ function getActiveTagsBySession(db, sessionId) {
|
|
|
9433
11013
|
const rows = getActiveTagsBySessionStatement(db).all(sessionId).filter(isTagRow);
|
|
9434
11014
|
return rows.map(toTagEntry);
|
|
9435
11015
|
}
|
|
11016
|
+
function getTailHygieneTags(db, sessionId) {
|
|
11017
|
+
const active = getActiveTagsBySession(db, sessionId);
|
|
11018
|
+
let orphanStatement = getNullOwnerToolTagsBySessionStatements.get(db);
|
|
11019
|
+
if (!orphanStatement) {
|
|
11020
|
+
orphanStatement = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags
|
|
11021
|
+
WHERE session_id = ? AND type = 'tool' AND tool_owner_message_id IS NULL
|
|
11022
|
+
ORDER BY tag_number ASC, id ASC`);
|
|
11023
|
+
getNullOwnerToolTagsBySessionStatements.set(db, orphanStatement);
|
|
11024
|
+
}
|
|
11025
|
+
const seen = new Set(active.map((tag) => `${tag.tagNumber}\x00${tag.messageId}\x00${tag.type}`));
|
|
11026
|
+
for (const row of orphanStatement.all(sessionId).filter(isTagRow)) {
|
|
11027
|
+
const orphan = toTagEntry(row);
|
|
11028
|
+
const key = `${orphan.tagNumber}\x00${orphan.messageId}\x00${orphan.type}`;
|
|
11029
|
+
if (!seen.has(key))
|
|
11030
|
+
active.push(orphan);
|
|
11031
|
+
}
|
|
11032
|
+
return active;
|
|
11033
|
+
}
|
|
9436
11034
|
function getDroppedTagsBySession(db, sessionId) {
|
|
9437
11035
|
const rows = getDroppedTagsBySessionStatement(db).all(sessionId).filter(isTagRow);
|
|
9438
11036
|
return rows.map(toTagEntry);
|
|
@@ -9651,7 +11249,7 @@ var LIMIT_EXTRACTION_PATTERNS = [
|
|
|
9651
11249
|
pattern: /too large for model with (\d+) maximum context length/i,
|
|
9652
11250
|
provenance: "combined"
|
|
9653
11251
|
},
|
|
9654
|
-
{ pattern: /context size
|
|
11252
|
+
{ pattern: /context size[^0-9]{0,40}(\d{4,})\s*tokens?/i, provenance: "combined" },
|
|
9655
11253
|
{ pattern: /exceeds? the context length of (\d+)/i, provenance: "combined" },
|
|
9656
11254
|
{
|
|
9657
11255
|
pattern: />\s*(\d+)\s*(?:tokens?\s*)?(?:maximum|max|limit)\b/i,
|
|
@@ -9823,7 +11421,7 @@ async function abortChildRun(client, sessionId) {
|
|
|
9823
11421
|
try {
|
|
9824
11422
|
await Promise.race([
|
|
9825
11423
|
client.session.abort({ path: { id: sessionId } }),
|
|
9826
|
-
new Promise((
|
|
11424
|
+
new Promise((resolve2) => setTimeout(resolve2, ABORT_CALL_TIMEOUT_MS))
|
|
9827
11425
|
]);
|
|
9828
11426
|
} catch (error) {
|
|
9829
11427
|
log(`[model-retry] child session abort failed for ${sessionId}: ${String(error)}`);
|
|
@@ -10052,16 +11650,25 @@ function modelKeyLookupOrder(modelKey) {
|
|
|
10052
11650
|
return [];
|
|
10053
11651
|
const provider = modelKey.slice(0, slash);
|
|
10054
11652
|
let modelID = modelKey.slice(slash + 1);
|
|
11653
|
+
const providerRefs = modelRefLookupOrder(`${provider}/${modelID}`);
|
|
10055
11654
|
const candidates = [];
|
|
10056
11655
|
while (modelID.length > 0) {
|
|
10057
|
-
|
|
11656
|
+
for (const providerRef of providerRefs) {
|
|
11657
|
+
const providerSlash = providerRef.indexOf("/");
|
|
11658
|
+
const providerPrefix = providerRef.slice(0, providerSlash);
|
|
11659
|
+
candidates.push({ key: `${providerPrefix}/${modelID}`, source: "exact" });
|
|
11660
|
+
}
|
|
10058
11661
|
candidates.push({ key: modelID, source: "bare" });
|
|
10059
11662
|
const lastDash = modelID.lastIndexOf("-");
|
|
10060
11663
|
if (lastDash <= 0)
|
|
10061
11664
|
break;
|
|
10062
11665
|
modelID = modelID.slice(0, lastDash);
|
|
10063
11666
|
}
|
|
10064
|
-
|
|
11667
|
+
for (const providerRef of providerRefs) {
|
|
11668
|
+
const providerSlash = providerRef.indexOf("/");
|
|
11669
|
+
const providerPrefix = providerRef.slice(0, providerSlash);
|
|
11670
|
+
candidates.push({ key: `${providerPrefix}/*`, source: "wildcard" });
|
|
11671
|
+
}
|
|
10065
11672
|
const seen = new Set;
|
|
10066
11673
|
return candidates.filter((candidate) => {
|
|
10067
11674
|
if (seen.has(candidate.key))
|
|
@@ -10094,7 +11701,7 @@ function resolveModelConfigOrDefault(values, modelKey, fallback) {
|
|
|
10094
11701
|
}
|
|
10095
11702
|
// src/shared/prompt-surface-runtime.ts
|
|
10096
11703
|
import { existsSync as existsSync5, readFileSync as readFileSync5, statSync as statSync5 } from "node:fs";
|
|
10097
|
-
import { dirname as dirname3, isAbsolute as isAbsolute2, resolve } from "node:path";
|
|
11704
|
+
import { dirname as dirname3, isAbsolute as isAbsolute2, resolve as resolve2 } from "node:path";
|
|
10098
11705
|
|
|
10099
11706
|
// src/config/migrate-config-location.ts
|
|
10100
11707
|
import {
|
|
@@ -10505,7 +12112,7 @@ function promptSurfaceHashMaterial(systemContent, preset = "full") {
|
|
|
10505
12112
|
var PROMPT_SURFACE_TOOL_ID_SET = new Set(ACTIVE_TOOL_IDS);
|
|
10506
12113
|
function resolveUserConfigDirectory(options) {
|
|
10507
12114
|
if (options.userConfigDirectory)
|
|
10508
|
-
return
|
|
12115
|
+
return resolve2(options.userConfigDirectory);
|
|
10509
12116
|
const sharedBase = cortexKitUserConfigBasePath();
|
|
10510
12117
|
const shared = detectConfigFile(sharedBase);
|
|
10511
12118
|
if (shared.format !== "none")
|
|
@@ -10532,7 +12139,7 @@ function createPromptSurfaceRuntime(options) {
|
|
|
10532
12139
|
const readGuidanceOverride = (configuredPath) => {
|
|
10533
12140
|
if (!configuredPath)
|
|
10534
12141
|
return;
|
|
10535
|
-
const path3 = isAbsolute2(configuredPath) ? configuredPath :
|
|
12142
|
+
const path3 = isAbsolute2(configuredPath) ? configuredPath : resolve2(userConfigDirectory, configuredPath);
|
|
10536
12143
|
let content;
|
|
10537
12144
|
try {
|
|
10538
12145
|
if (!statSync5(path3).isFile()) {
|
|
@@ -10592,12 +12199,13 @@ function createPromptSurfaceGuidanceEpochCache(runtime) {
|
|
|
10592
12199
|
const epochs = new Map;
|
|
10593
12200
|
return {
|
|
10594
12201
|
resolve(sessionId, config, modelKey) {
|
|
12202
|
+
const canonicalModelKey = modelKey ? piModelRefToCanonical(modelKey) : undefined;
|
|
10595
12203
|
const cached = epochs.get(sessionId);
|
|
10596
|
-
if (cached && cached.config === config && cached.modelKey ===
|
|
12204
|
+
if (cached && cached.config === config && cached.modelKey === canonicalModelKey) {
|
|
10597
12205
|
return cached.selection;
|
|
10598
12206
|
}
|
|
10599
|
-
const selection = runtime.resolveGuidance(config,
|
|
10600
|
-
epochs.set(sessionId, { config, modelKey, selection });
|
|
12207
|
+
const selection = runtime.resolveGuidance(config, canonicalModelKey);
|
|
12208
|
+
epochs.set(sessionId, { config, modelKey: canonicalModelKey, selection });
|
|
10601
12209
|
return selection;
|
|
10602
12210
|
},
|
|
10603
12211
|
clear(sessionId) {
|
|
@@ -10703,13 +12311,44 @@ function pruneExpiredUserMemoryCandidates(db, ttlMs, now = Date.now()) {
|
|
|
10703
12311
|
const result = db.prepare("DELETE FROM user_memory_candidates WHERE created_at < ?").run(cutoff);
|
|
10704
12312
|
return Number(result.changes ?? 0);
|
|
10705
12313
|
}
|
|
12314
|
+
function loadUserMemorySourceProvenance(db, candidateIds) {
|
|
12315
|
+
const ids = [...new Set(candidateIds)].sort((a, b) => a - b);
|
|
12316
|
+
if (ids.length === 0)
|
|
12317
|
+
return [];
|
|
12318
|
+
const placeholders3 = ids.map(() => "?").join(",");
|
|
12319
|
+
const rows = db.prepare(`SELECT id, session_id, source_compartment_start, source_compartment_end
|
|
12320
|
+
FROM user_memory_candidates
|
|
12321
|
+
WHERE id IN (${placeholders3})
|
|
12322
|
+
ORDER BY id ASC`).all(...ids);
|
|
12323
|
+
return rows.map((row) => ({
|
|
12324
|
+
candidateId: row.id,
|
|
12325
|
+
sessionId: row.session_id,
|
|
12326
|
+
sourceCompartmentStart: row.source_compartment_start,
|
|
12327
|
+
sourceCompartmentEnd: row.source_compartment_end
|
|
12328
|
+
}));
|
|
12329
|
+
}
|
|
12330
|
+
function serializeUserMemorySourceProvenance(provenance, sourceCandidateIds) {
|
|
12331
|
+
if (provenance.length === 0 && sourceCandidateIds.length > 0)
|
|
12332
|
+
return null;
|
|
12333
|
+
return JSON.stringify(provenance.map((source) => ({
|
|
12334
|
+
candidate_id: source.candidateId,
|
|
12335
|
+
session_id: source.sessionId,
|
|
12336
|
+
source_compartment_start: source.sourceCompartmentStart,
|
|
12337
|
+
source_compartment_end: source.sourceCompartmentEnd
|
|
12338
|
+
})));
|
|
12339
|
+
}
|
|
10706
12340
|
function insertUserMemory(db, content, sourceCandidateIds) {
|
|
10707
|
-
|
|
10708
|
-
|
|
10709
|
-
|
|
12341
|
+
return db.transaction(() => {
|
|
12342
|
+
const now = Date.now();
|
|
12343
|
+
const sourceProvenance = loadUserMemorySourceProvenance(db, sourceCandidateIds);
|
|
12344
|
+
const result = db.prepare(`INSERT INTO user_memories
|
|
12345
|
+
(content, status, promoted_at, source_candidate_ids, source_candidate_provenance, created_at, updated_at)
|
|
12346
|
+
VALUES (?, 'active', ?, ?, ?, ?, ?)`).run(content, now, JSON.stringify(sourceCandidateIds), serializeUserMemorySourceProvenance(sourceProvenance, sourceCandidateIds), now, now);
|
|
12347
|
+
return Number(result.lastInsertRowid);
|
|
12348
|
+
})();
|
|
10710
12349
|
}
|
|
10711
12350
|
function getActiveUserMemories(db) {
|
|
10712
|
-
const rows = db.prepare("SELECT id, content, status, promoted_at, source_candidate_ids, created_at, updated_at FROM user_memories WHERE status = 'active' ORDER BY promoted_at ASC, id ASC").all();
|
|
12351
|
+
const rows = db.prepare("SELECT id, content, status, promoted_at, source_candidate_ids, source_candidate_provenance, created_at, updated_at FROM user_memories WHERE status = 'active' ORDER BY promoted_at ASC, id ASC").all();
|
|
10713
12352
|
return rows.map(parseUserMemoryRow);
|
|
10714
12353
|
}
|
|
10715
12354
|
function updateUserMemoryContent(db, id, content) {
|
|
@@ -10718,26 +12357,58 @@ function updateUserMemoryContent(db, id, content) {
|
|
|
10718
12357
|
function dismissUserMemory(db, id) {
|
|
10719
12358
|
db.prepare("UPDATE user_memories SET status = 'dismissed', updated_at = ? WHERE id = ?").run(Date.now(), id);
|
|
10720
12359
|
}
|
|
10721
|
-
function
|
|
10722
|
-
let candidateIds = [];
|
|
12360
|
+
function parseCandidateIds2(raw) {
|
|
10723
12361
|
try {
|
|
10724
|
-
|
|
10725
|
-
|
|
12362
|
+
const parsed = JSON.parse(raw);
|
|
12363
|
+
return Array.isArray(parsed) ? parsed.filter((id) => typeof id === "number" && Number.isFinite(id)) : [];
|
|
12364
|
+
} catch {
|
|
12365
|
+
return [];
|
|
12366
|
+
}
|
|
12367
|
+
}
|
|
12368
|
+
function parseUserMemorySourceProvenance(raw) {
|
|
12369
|
+
if (raw === null)
|
|
12370
|
+
return null;
|
|
12371
|
+
try {
|
|
12372
|
+
const parsed = JSON.parse(raw);
|
|
12373
|
+
if (!Array.isArray(parsed))
|
|
12374
|
+
return null;
|
|
12375
|
+
const provenance = [];
|
|
12376
|
+
for (const value of parsed) {
|
|
12377
|
+
if (!value || typeof value !== "object")
|
|
12378
|
+
return null;
|
|
12379
|
+
const source = value;
|
|
12380
|
+
if (typeof source.candidate_id !== "number" || !Number.isFinite(source.candidate_id) || typeof source.session_id !== "string" || source.source_compartment_start !== null && typeof source.source_compartment_start !== "number" || source.source_compartment_end !== null && typeof source.source_compartment_end !== "number") {
|
|
12381
|
+
return null;
|
|
12382
|
+
}
|
|
12383
|
+
provenance.push({
|
|
12384
|
+
candidateId: source.candidate_id,
|
|
12385
|
+
sessionId: source.session_id,
|
|
12386
|
+
sourceCompartmentStart: source.source_compartment_start,
|
|
12387
|
+
sourceCompartmentEnd: source.source_compartment_end
|
|
12388
|
+
});
|
|
12389
|
+
}
|
|
12390
|
+
return provenance;
|
|
12391
|
+
} catch {
|
|
12392
|
+
return null;
|
|
12393
|
+
}
|
|
12394
|
+
}
|
|
12395
|
+
function parseUserMemoryRow(row) {
|
|
10726
12396
|
return {
|
|
10727
12397
|
id: row.id,
|
|
10728
12398
|
content: row.content,
|
|
10729
12399
|
status: row.status === "dismissed" ? "dismissed" : "active",
|
|
10730
12400
|
promotedAt: row.promoted_at,
|
|
10731
|
-
sourceCandidateIds:
|
|
12401
|
+
sourceCandidateIds: parseCandidateIds2(row.source_candidate_ids),
|
|
12402
|
+
sourceProvenance: parseUserMemorySourceProvenance(row.source_candidate_provenance),
|
|
10732
12403
|
createdAt: row.created_at,
|
|
10733
12404
|
updatedAt: row.updated_at
|
|
10734
12405
|
};
|
|
10735
12406
|
}
|
|
10736
12407
|
|
|
10737
12408
|
// src/features/magic-context/mural/storage-mural-cues.ts
|
|
10738
|
-
import { createHash as
|
|
12409
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
10739
12410
|
function computeCueContentHash(content) {
|
|
10740
|
-
return
|
|
12411
|
+
return createHash9("sha256").update(content).digest("hex");
|
|
10741
12412
|
}
|
|
10742
12413
|
var muralCueColumnCache = new WeakMap;
|
|
10743
12414
|
var muralCueRejectionColumnCache = new WeakMap;
|
|
@@ -10935,13 +12606,13 @@ function invalidateMemory(projectPath, memoryId) {
|
|
|
10935
12606
|
}
|
|
10936
12607
|
|
|
10937
12608
|
// src/features/magic-context/memory/normalize-hash.ts
|
|
10938
|
-
import { createHash as
|
|
12609
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
10939
12610
|
function normalizeMemoryContent(content) {
|
|
10940
12611
|
return content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
10941
12612
|
}
|
|
10942
12613
|
function computeNormalizedHash(content) {
|
|
10943
12614
|
const normalized = normalizeMemoryContent(content);
|
|
10944
|
-
return
|
|
12615
|
+
return createHash10("md5").update(normalized).digest("hex");
|
|
10945
12616
|
}
|
|
10946
12617
|
|
|
10947
12618
|
// src/features/magic-context/memory/visibility.ts
|
|
@@ -11910,7 +13581,7 @@ async function runMemoryMigration(deps) {
|
|
|
11910
13581
|
}
|
|
11911
13582
|
|
|
11912
13583
|
// src/features/magic-context/compartment-chunk-embedding.ts
|
|
11913
|
-
import { createHash as
|
|
13584
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
11914
13585
|
|
|
11915
13586
|
// src/features/magic-context/recursive-text-splitter.ts
|
|
11916
13587
|
var DEFAULT_SEPARATORS = [`
|
|
@@ -12195,7 +13866,7 @@ function parseCanonicalLineRange(line) {
|
|
|
12195
13866
|
return { start, end };
|
|
12196
13867
|
}
|
|
12197
13868
|
function hashChunkText(text) {
|
|
12198
|
-
return
|
|
13869
|
+
return createHash11("sha256").update(text).digest("hex");
|
|
12199
13870
|
}
|
|
12200
13871
|
function vectorBlob2(vector) {
|
|
12201
13872
|
return new Uint8Array(vector.buffer, vector.byteOffset, vector.byteLength);
|
|
@@ -12586,7 +14257,7 @@ function countSessionCompartmentEmbedCoverage(db, projectPath, sessionId, modelI
|
|
|
12586
14257
|
}
|
|
12587
14258
|
|
|
12588
14259
|
// src/features/magic-context/project-embedding-registry.ts
|
|
12589
|
-
import { createHash as
|
|
14260
|
+
import { createHash as createHash13, randomUUID as randomUUID2 } from "node:crypto";
|
|
12590
14261
|
|
|
12591
14262
|
// src/config/schema/magic-context.ts
|
|
12592
14263
|
import { homedir as homedir3 } from "node:os";
|
|
@@ -27252,7 +28923,10 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
27252
28923
|
output_reserve: exports_external.union([
|
|
27253
28924
|
exports_external.number().min(0),
|
|
27254
28925
|
exports_external.object({ default: exports_external.number().min(0) }).catchall(exports_external.number().min(0))
|
|
27255
|
-
]).optional().describe('User-only output-token reservation override. Number or per-model object ({ default: 16384, "provider/model": 8192 }); 0 disables reservation. When unset, Magic Context reserves the catalog output limit (capped at 25% of context) for shared-window providers and keeps proven separate-quota Google/Gemini windows unchanged.'),
|
|
28926
|
+
]).optional().describe('User-only output-token reservation override. Number or per-model object ({ default: 16384, "provider/model": 8192 }); 0 disables reservation. Takes precedence over every derived source: an explicit value here always wins against catalog output limits, provider window-geometry facts, and the 25%-of-context fallback (usable window = context window minus this reserve). When unset, Magic Context reserves the catalog output limit (capped at 25% of context) for shared-window providers and keeps proven separate-quota Google/Gemini windows unchanged.'),
|
|
28927
|
+
models: exports_external.object({
|
|
28928
|
+
window_overlay_path: exports_external.string().trim().min(1).optional()
|
|
28929
|
+
}).optional().describe("User-only Fusiform window-overlay settings. The path defaults to <dataDir>/fusiform/window-overlay.json."),
|
|
27256
28930
|
toast_duration_ms: exports_external.number().min(0).max(60000).default(5000).describe("TUI toast lifetime in milliseconds for Magic Context notifications. Set to 0 to disable Magic Context toasts entirely (min: 0, max: 60000, default: 5000)"),
|
|
27257
28931
|
execute_threshold_percentage: exports_external.union([
|
|
27258
28932
|
exports_external.number().min(20).max(90, EXECUTE_THRESHOLD_CAP_MESSAGE),
|
|
@@ -27304,7 +28978,7 @@ var MagicContextConfigSchema = exports_external.object({
|
|
|
27304
28978
|
overlay: exports_external.boolean().default(true).describe("Pi only: show the persistent todo overlay above the editor while tasks are active.")
|
|
27305
28979
|
}).default({ enabled: true, overlay: true }).describe("Pi-only todowrite tool and overlay controls. Pi registers tools and widgets at extension boot, so changing this after /cd requires /reload or restart."),
|
|
27306
28980
|
pi: PiConfigSchema.describe("Pi-only child-process extension controls. This setting is user-level only; project configuration cannot choose which extensions a user's subagent children load."),
|
|
27307
|
-
smart_drops: exports_external.boolean().default(false).describe("Content-aware reclaim of provably-superseded tool output, layered on the existing execute-pass auto-drop. When on: superseded todowrite (keep newest 1), spent ctx_reduce (keep newest
|
|
28981
|
+
smart_drops: exports_external.boolean().default(false).describe("Content-aware reclaim of provably-superseded tool output, layered on the existing execute-pass auto-drop. When on: superseded todowrite (keep newest 1), spent ctx_reduce (keep newest 3), and zero-value meta (bash_status, bash_kill, ctx_note read/dismiss) outputs are dropped; older edits to a file are compressed to a filePath-preserving marker while the newest edit per file stays full. Only acts on passes already busting the cache, so it never originates a cache bust. Honors the protected-tag reserve. Experimental: opt-in, default off until cache stability is proven; when off the wire is byte-identical to the positional-only reclaim. Requires a restart."),
|
|
27308
28982
|
caveman_text_compression: exports_external.object({
|
|
27309
28983
|
enabled: exports_external.boolean().default(false).describe("Apply deterministic caveman-style text compression to old conversation text. Active for primary sessions when enabled; never for subagents. Compresses user/assistant text in oldest-first tiers: ultra (oldest 20%), full, lite, untouched (newest 40%)."),
|
|
27310
28984
|
min_chars: exports_external.number().min(100).max(1e4).default(500).describe("Text parts shorter than this (characters) stay untouched. Min 100, max 10000. Default: 500.")
|
|
@@ -27656,7 +29330,7 @@ function releaseGitSweepLease(db, projectPath, holderId) {
|
|
|
27656
29330
|
}
|
|
27657
29331
|
|
|
27658
29332
|
// src/features/magic-context/memory/embedding-synapse.ts
|
|
27659
|
-
import { createHash as
|
|
29333
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
27660
29334
|
|
|
27661
29335
|
// ../../node_modules/.bun/@cortexkit+subc-client@0.4.1/node_modules/@cortexkit/subc-client/dist/client.js
|
|
27662
29336
|
import { promises as fs2 } from "node:fs";
|
|
@@ -28030,7 +29704,7 @@ class SubcSocket {
|
|
|
28030
29704
|
return this.sock.localPort ?? null;
|
|
28031
29705
|
}
|
|
28032
29706
|
static connect(host, port, deadlineMs) {
|
|
28033
|
-
return new Promise((
|
|
29707
|
+
return new Promise((resolve3, reject) => {
|
|
28034
29708
|
const sock = net.connect({ host, port });
|
|
28035
29709
|
sock.setNoDelay(true);
|
|
28036
29710
|
const timer = setTimeout(() => {
|
|
@@ -28039,7 +29713,7 @@ class SubcSocket {
|
|
|
28039
29713
|
}, Math.max(0, deadlineMs - Date.now()));
|
|
28040
29714
|
sock.once("connect", () => {
|
|
28041
29715
|
clearTimeout(timer);
|
|
28042
|
-
|
|
29716
|
+
resolve3(new SubcSocket(sock));
|
|
28043
29717
|
});
|
|
28044
29718
|
sock.once("error", (err) => {
|
|
28045
29719
|
clearTimeout(timer);
|
|
@@ -28071,7 +29745,7 @@ class SubcSocket {
|
|
|
28071
29745
|
}
|
|
28072
29746
|
if (n === 0)
|
|
28073
29747
|
return Promise.resolve(new Uint8Array(0));
|
|
28074
|
-
return new Promise((
|
|
29748
|
+
return new Promise((resolve3, reject) => {
|
|
28075
29749
|
let timer = null;
|
|
28076
29750
|
if (Number.isFinite(deadlineMs)) {
|
|
28077
29751
|
const remaining = deadlineMs - Date.now();
|
|
@@ -28084,7 +29758,7 @@ class SubcSocket {
|
|
|
28084
29758
|
reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
|
|
28085
29759
|
}, remaining);
|
|
28086
29760
|
}
|
|
28087
|
-
this.waiter = { need: n, resolve:
|
|
29761
|
+
this.waiter = { need: n, resolve: resolve3, reject, timer };
|
|
28088
29762
|
this.tryServe();
|
|
28089
29763
|
});
|
|
28090
29764
|
}
|
|
@@ -28108,7 +29782,7 @@ class SubcSocket {
|
|
|
28108
29782
|
let queued = false;
|
|
28109
29783
|
let settled = false;
|
|
28110
29784
|
let timer = null;
|
|
28111
|
-
const completed = new Promise((
|
|
29785
|
+
const completed = new Promise((resolve3, reject) => {
|
|
28112
29786
|
const settle = (run) => {
|
|
28113
29787
|
if (settled)
|
|
28114
29788
|
return;
|
|
@@ -28132,7 +29806,7 @@ class SubcSocket {
|
|
|
28132
29806
|
if (err) {
|
|
28133
29807
|
reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
|
|
28134
29808
|
} else {
|
|
28135
|
-
|
|
29809
|
+
resolve3();
|
|
28136
29810
|
}
|
|
28137
29811
|
});
|
|
28138
29812
|
});
|
|
@@ -28348,14 +30022,14 @@ class SubcClient {
|
|
|
28348
30022
|
const admission = opts.admissionClass ?? AdmissionClass.Normal;
|
|
28349
30023
|
const corr = this.allocateCorr();
|
|
28350
30024
|
const key = pendingKey(handle, corr);
|
|
28351
|
-
const closed = new Promise((
|
|
30025
|
+
const closed = new Promise((resolve3, reject) => {
|
|
28352
30026
|
if (this.closedErr) {
|
|
28353
30027
|
reject(this.closedErr);
|
|
28354
30028
|
return;
|
|
28355
30029
|
}
|
|
28356
30030
|
this.pending.set(key, {
|
|
28357
30031
|
handle,
|
|
28358
|
-
resolve: () =>
|
|
30032
|
+
resolve: () => resolve3(),
|
|
28359
30033
|
reject,
|
|
28360
30034
|
onProgress: onEvent,
|
|
28361
30035
|
timer: null,
|
|
@@ -28440,11 +30114,11 @@ class SubcClient {
|
|
|
28440
30114
|
const waiters = [];
|
|
28441
30115
|
for (const pending of this.pending.values()) {
|
|
28442
30116
|
if (pending.handle === handle && !pending.subscription) {
|
|
28443
|
-
waiters.push(new Promise((
|
|
30117
|
+
waiters.push(new Promise((resolve3) => {
|
|
28444
30118
|
const previous = pending.onSettle;
|
|
28445
30119
|
pending.onSettle = () => {
|
|
28446
30120
|
previous?.();
|
|
28447
|
-
|
|
30121
|
+
resolve3();
|
|
28448
30122
|
};
|
|
28449
30123
|
}));
|
|
28450
30124
|
}
|
|
@@ -28500,11 +30174,11 @@ class SubcClient {
|
|
|
28500
30174
|
const channel = handle?.channel ?? 0;
|
|
28501
30175
|
const epoch = handle?.epoch ?? 0;
|
|
28502
30176
|
const frame = buildFrame(FrameType.Request, buildFlags(false, priority, false, admission), channel, epoch, corr, body);
|
|
28503
|
-
return new Promise((
|
|
30177
|
+
return new Promise((resolve3, reject) => {
|
|
28504
30178
|
const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
28505
30179
|
const pending = {
|
|
28506
30180
|
handle,
|
|
28507
|
-
resolve:
|
|
30181
|
+
resolve: resolve3,
|
|
28508
30182
|
reject,
|
|
28509
30183
|
onProgress,
|
|
28510
30184
|
timer: null,
|
|
@@ -28578,11 +30252,11 @@ class SubcClient {
|
|
|
28578
30252
|
}
|
|
28579
30253
|
return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", error51);
|
|
28580
30254
|
};
|
|
28581
|
-
return new Promise((
|
|
30255
|
+
return new Promise((resolve3, reject) => {
|
|
28582
30256
|
const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
28583
30257
|
const pending = {
|
|
28584
30258
|
handle,
|
|
28585
|
-
resolve:
|
|
30259
|
+
resolve: resolve3,
|
|
28586
30260
|
reject,
|
|
28587
30261
|
onProgress,
|
|
28588
30262
|
timer: null,
|
|
@@ -28970,7 +30644,7 @@ function normalizeConnectOptions(opts) {
|
|
|
28970
30644
|
identity: opts.identity,
|
|
28971
30645
|
targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
|
|
28972
30646
|
reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
|
|
28973
|
-
sleep: opts.sleep ?? ((ms) => new Promise((
|
|
30647
|
+
sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
|
|
28974
30648
|
timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS
|
|
28975
30649
|
};
|
|
28976
30650
|
}
|
|
@@ -29027,8 +30701,8 @@ class AsyncPermitPool {
|
|
|
29027
30701
|
this.available -= 1;
|
|
29028
30702
|
return this.releaseOnce();
|
|
29029
30703
|
}
|
|
29030
|
-
await new Promise((
|
|
29031
|
-
this.waiters.push(
|
|
30704
|
+
await new Promise((resolve3) => {
|
|
30705
|
+
this.waiters.push(resolve3);
|
|
29032
30706
|
});
|
|
29033
30707
|
return this.releaseOnce();
|
|
29034
30708
|
}
|
|
@@ -29084,8 +30758,8 @@ class SubcProvider {
|
|
|
29084
30758
|
this.currentConn = currentConn;
|
|
29085
30759
|
this.opts = opts;
|
|
29086
30760
|
this.storage = storage;
|
|
29087
|
-
this.closed = new Promise((
|
|
29088
|
-
this.resolveClosed =
|
|
30761
|
+
this.closed = new Promise((resolve3) => {
|
|
30762
|
+
this.resolveClosed = resolve3;
|
|
29089
30763
|
});
|
|
29090
30764
|
this.readLoop(sock, this.generation);
|
|
29091
30765
|
this.enqueueConnectionState({ state: "connected", epoch: this.connectionEpoch });
|
|
@@ -29105,13 +30779,13 @@ class SubcProvider {
|
|
|
29105
30779
|
const key = routeKey(handle, corr);
|
|
29106
30780
|
const timeoutMs = opts.timeoutMs ?? WRITE_TIMEOUT_MS;
|
|
29107
30781
|
const frame = buildFrame(FrameType.Request, buildFlags(false, opts.priority ?? Priority.Interactive, false, opts.admissionClass ?? AdmissionClass.Normal), handle.channel, handle.epoch, corr, body);
|
|
29108
|
-
return await new Promise((
|
|
30782
|
+
return await new Promise((resolve3, reject) => {
|
|
29109
30783
|
const timer = setTimeout(() => {
|
|
29110
30784
|
if (this.pending.delete(key))
|
|
29111
30785
|
reject(new SubcProviderError("reverse request timed out", "request_timeout"));
|
|
29112
30786
|
}, timeoutMs);
|
|
29113
30787
|
this.pending.set(key, {
|
|
29114
|
-
resolve: (response) =>
|
|
30788
|
+
resolve: (response) => resolve3(response.body),
|
|
29115
30789
|
reject,
|
|
29116
30790
|
timer
|
|
29117
30791
|
});
|
|
@@ -29583,7 +31257,7 @@ function normalizeProviderConnectOptions(opts) {
|
|
|
29583
31257
|
onBound: opts.onBound,
|
|
29584
31258
|
onRouteGone: opts.onRouteGone,
|
|
29585
31259
|
reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
|
|
29586
|
-
sleep: opts.sleep ?? ((ms) => new Promise((
|
|
31260
|
+
sleep: opts.sleep ?? ((ms) => new Promise((resolve3) => setTimeout(resolve3, ms))),
|
|
29587
31261
|
restoredDebounceMs: opts.restoredDebounceMs ?? DEFAULT_RESTORED_DEBOUNCE_MS,
|
|
29588
31262
|
onConnectionState: opts.onConnectionState,
|
|
29589
31263
|
launchNonce: opts.launchNonce
|
|
@@ -29628,7 +31302,7 @@ function errorCode2(err) {
|
|
|
29628
31302
|
return;
|
|
29629
31303
|
}
|
|
29630
31304
|
async function pauseBeforeStateRetry() {
|
|
29631
|
-
await new Promise((
|
|
31305
|
+
await new Promise((resolve3) => setTimeout(resolve3, 0));
|
|
29632
31306
|
}
|
|
29633
31307
|
function controlFlags() {
|
|
29634
31308
|
return buildFlags(false, Priority.Passive, false);
|
|
@@ -29866,10 +31540,10 @@ function classifyError(value) {
|
|
|
29866
31540
|
});
|
|
29867
31541
|
}
|
|
29868
31542
|
function wait(ms) {
|
|
29869
|
-
return new Promise((
|
|
31543
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
29870
31544
|
}
|
|
29871
31545
|
function sha256(value) {
|
|
29872
|
-
return
|
|
31546
|
+
return createHash12("sha256").update(value).digest("hex");
|
|
29873
31547
|
}
|
|
29874
31548
|
function stableJson(value) {
|
|
29875
31549
|
if (Array.isArray(value))
|
|
@@ -30375,7 +32049,7 @@ async function acquireModelLoadLock(lockPath) {
|
|
|
30375
32049
|
if (Date.now() - waitStart > MAX_LOCK_WAIT_MS) {
|
|
30376
32050
|
throw new Error(`[magic-context] embedding-load lock wait exceeded ${MAX_LOCK_WAIT_MS}ms; another process is still loading the model. Skipping this init attempt to avoid an unsynchronized native load.`);
|
|
30377
32051
|
}
|
|
30378
|
-
await new Promise((
|
|
32052
|
+
await new Promise((resolve3) => setTimeout(resolve3, LOCK_POLL_MS));
|
|
30379
32053
|
}
|
|
30380
32054
|
}
|
|
30381
32055
|
}
|
|
@@ -30580,7 +32254,7 @@ class LocalEmbeddingProvider {
|
|
|
30580
32254
|
}
|
|
30581
32255
|
const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
|
|
30582
32256
|
log(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
|
|
30583
|
-
await new Promise((
|
|
32257
|
+
await new Promise((resolve3) => setTimeout(resolve3, delayMs));
|
|
30584
32258
|
}
|
|
30585
32259
|
}
|
|
30586
32260
|
if (this.pipeline) {
|
|
@@ -30613,8 +32287,8 @@ class LocalEmbeddingProvider {
|
|
|
30613
32287
|
if (this.inFlight === 0) {
|
|
30614
32288
|
return Promise.resolve();
|
|
30615
32289
|
}
|
|
30616
|
-
return new Promise((
|
|
30617
|
-
this.inFlightWaiters.push(
|
|
32290
|
+
return new Promise((resolve3) => {
|
|
32291
|
+
this.inFlightWaiters.push(resolve3);
|
|
30618
32292
|
});
|
|
30619
32293
|
}
|
|
30620
32294
|
finishInFlight() {
|
|
@@ -30769,9 +32443,14 @@ function blockedEmbeddingEndpointReason(endpoint) {
|
|
|
30769
32443
|
function normalizeEndpoint2(endpoint) {
|
|
30770
32444
|
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
30771
32445
|
}
|
|
30772
|
-
function
|
|
30773
|
-
const
|
|
30774
|
-
|
|
32446
|
+
function parseEmbeddingModel(model) {
|
|
32447
|
+
const lastColon = model.lastIndexOf(":");
|
|
32448
|
+
if (lastColon > model.lastIndexOf("/")) {
|
|
32449
|
+
return { base: model.slice(0, lastColon), tag: model.slice(lastColon + 1) };
|
|
32450
|
+
}
|
|
32451
|
+
return { base: model };
|
|
32452
|
+
}
|
|
32453
|
+
function matchNormalizedEmbeddingModels(a, b) {
|
|
30775
32454
|
if (a.length === 0 || b.length === 0)
|
|
30776
32455
|
return true;
|
|
30777
32456
|
if (a === b)
|
|
@@ -30785,6 +32464,16 @@ function embeddingModelsMatch(served, requested) {
|
|
|
30785
32464
|
return true;
|
|
30786
32465
|
return false;
|
|
30787
32466
|
}
|
|
32467
|
+
function embeddingModelsMatch(served, requested) {
|
|
32468
|
+
const a = served.trim().toLowerCase();
|
|
32469
|
+
const b = requested.trim().toLowerCase();
|
|
32470
|
+
const servedModel = parseEmbeddingModel(a);
|
|
32471
|
+
const requestedModel = parseEmbeddingModel(b);
|
|
32472
|
+
if (servedModel.tag !== undefined && requestedModel.tag !== undefined && servedModel.tag !== requestedModel.tag) {
|
|
32473
|
+
return false;
|
|
32474
|
+
}
|
|
32475
|
+
return matchNormalizedEmbeddingModels(servedModel.base, requestedModel.base);
|
|
32476
|
+
}
|
|
30788
32477
|
var FAILURE_THRESHOLD = 3;
|
|
30789
32478
|
var FAILURE_WINDOW_MS = 60000;
|
|
30790
32479
|
var OPEN_DURATION_MS = 5 * 60000;
|
|
@@ -30915,7 +32604,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
30915
32604
|
const servedModel = typeof body.model === "string" ? body.model : "";
|
|
30916
32605
|
if (this.model && servedModel && !embeddingModelsMatch(servedModel, this.model)) {
|
|
30917
32606
|
if (!this.modelMismatchLogged) {
|
|
30918
|
-
log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}".
|
|
32607
|
+
log(`[magic-context] embedding endpoint served a DIFFERENT model than requested — refusing the substituted vectors (they have the wrong dimensions/space). requested="${this.model}" served="${servedModel}". Check that the endpoint serves the requested model; variant suffixes and vendor prefixes are matched automatically.`);
|
|
30919
32608
|
this.modelMismatchLogged = true;
|
|
30920
32609
|
}
|
|
30921
32610
|
this.recordFailure(isProbe);
|
|
@@ -31302,10 +32991,10 @@ function stableStringify2(value) {
|
|
|
31302
32991
|
return JSON.stringify(value);
|
|
31303
32992
|
}
|
|
31304
32993
|
function sha256Prefix(value, length = 16) {
|
|
31305
|
-
return
|
|
32994
|
+
return createHash13("sha256").update(value).digest("hex").slice(0, length);
|
|
31306
32995
|
}
|
|
31307
32996
|
function contentSha256(value) {
|
|
31308
|
-
return
|
|
32997
|
+
return createHash13("sha256").update(value).digest("hex");
|
|
31309
32998
|
}
|
|
31310
32999
|
function getRuntimeFingerprint(config2) {
|
|
31311
33000
|
if (config2.provider === "off") {
|
|
@@ -31505,14 +33194,14 @@ function hasStaleEmbeddingRows(db, scope, projectIdentity, modelId) {
|
|
|
31505
33194
|
LIMIT 1`).get(projectIdentity, modelId));
|
|
31506
33195
|
}
|
|
31507
33196
|
function sweepStaleEmbeddingIdentitiesForProject(db, projectIdentity, now = Date.now()) {
|
|
31508
|
-
const
|
|
33197
|
+
const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
|
|
31509
33198
|
const result = {
|
|
31510
33199
|
memoryRowsDeleted: 0,
|
|
31511
33200
|
commitRowsDeleted: 0,
|
|
31512
33201
|
chunkRowsDeleted: 0,
|
|
31513
33202
|
trackingRowsDeleted: 0
|
|
31514
33203
|
};
|
|
31515
|
-
if (!
|
|
33204
|
+
if (!snapshot2)
|
|
31516
33205
|
return result;
|
|
31517
33206
|
if (untrustedLoadProjects.has(projectIdentity))
|
|
31518
33207
|
return result;
|
|
@@ -31520,25 +33209,25 @@ function sweepStaleEmbeddingIdentitiesForProject(db, projectIdentity, now = Date
|
|
|
31520
33209
|
const deleteTracking = getDeleteActiveIdentityStatement(db);
|
|
31521
33210
|
const shadow = shadowRegistrations.get(projectIdentity);
|
|
31522
33211
|
const protectedModels = {
|
|
31523
|
-
memory: new Set([
|
|
31524
|
-
commit: new Set([
|
|
31525
|
-
chunk: new Set([
|
|
33212
|
+
memory: new Set([snapshot2.modelId, ...shadow ? [shadow.modelId] : []]),
|
|
33213
|
+
commit: new Set([snapshot2.modelId, ...shadow ? [shadow.modelId] : []]),
|
|
33214
|
+
chunk: new Set([snapshot2.chunkModelId, ...shadow ? [shadow.chunkModelId] : []])
|
|
31526
33215
|
};
|
|
31527
33216
|
const scopes = [
|
|
31528
33217
|
{
|
|
31529
33218
|
scope: "memory",
|
|
31530
|
-
enabled:
|
|
31531
|
-
currentModelId:
|
|
33219
|
+
enabled: snapshot2.enabled && snapshot2.modelId !== "off",
|
|
33220
|
+
currentModelId: snapshot2.modelId
|
|
31532
33221
|
},
|
|
31533
33222
|
{
|
|
31534
33223
|
scope: "commit",
|
|
31535
|
-
enabled:
|
|
31536
|
-
currentModelId:
|
|
33224
|
+
enabled: snapshot2.gitCommitEnabled && snapshot2.modelId !== "off",
|
|
33225
|
+
currentModelId: snapshot2.modelId
|
|
31537
33226
|
},
|
|
31538
33227
|
{
|
|
31539
33228
|
scope: "chunk",
|
|
31540
|
-
enabled:
|
|
31541
|
-
currentModelId:
|
|
33229
|
+
enabled: snapshot2.enabled && snapshot2.chunkModelId !== "off",
|
|
33230
|
+
currentModelId: snapshot2.chunkModelId
|
|
31542
33231
|
}
|
|
31543
33232
|
];
|
|
31544
33233
|
let remainingBudget = STALE_EMBEDDING_GC_BATCH_SIZE;
|
|
@@ -31994,7 +33683,7 @@ async function runShadowWorker() {
|
|
|
31994
33683
|
}
|
|
31995
33684
|
processed += item.ids.length;
|
|
31996
33685
|
processedBytes += itemBytes;
|
|
31997
|
-
await new Promise((
|
|
33686
|
+
await new Promise((resolve3) => setTimeout(resolve3, 0));
|
|
31998
33687
|
}
|
|
31999
33688
|
}
|
|
32000
33689
|
function registerProjectInObservationMode(db, projectIdentity, sourceDirectory, failedConfig, failureSummary) {
|
|
@@ -32177,11 +33866,11 @@ function getLoadUnembeddedMemoriesStatement(db) {
|
|
|
32177
33866
|
return stmt;
|
|
32178
33867
|
}
|
|
32179
33868
|
async function embedUnembeddedMemoriesForProject(db, projectIdentity, batchSize = 10) {
|
|
32180
|
-
const
|
|
32181
|
-
if (!
|
|
33869
|
+
const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
|
|
33870
|
+
if (!snapshot2?.enabled)
|
|
32182
33871
|
return 0;
|
|
32183
33872
|
const normalizedBatchSize = Math.max(1, Math.floor(batchSize));
|
|
32184
|
-
const memories = getLoadUnembeddedMemoriesStatement(db).all(
|
|
33873
|
+
const memories = getLoadUnembeddedMemoriesStatement(db).all(snapshot2.modelId, projectIdentity, normalizedBatchSize).filter(isUnembeddedMemoryRow);
|
|
32185
33874
|
if (memories.length === 0)
|
|
32186
33875
|
return 0;
|
|
32187
33876
|
try {
|
|
@@ -32211,10 +33900,10 @@ async function embedUnembeddedMemoriesForProject(db, projectIdentity, batchSize
|
|
|
32211
33900
|
}
|
|
32212
33901
|
}
|
|
32213
33902
|
async function embedCommitBatch(db, projectIdentity, batchSize) {
|
|
32214
|
-
const
|
|
32215
|
-
if (!
|
|
33903
|
+
const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
|
|
33904
|
+
if (!snapshot2?.gitCommitEnabled)
|
|
32216
33905
|
return 0;
|
|
32217
|
-
const commits = loadUnembeddedCommits(db, projectIdentity,
|
|
33906
|
+
const commits = loadUnembeddedCommits(db, projectIdentity, snapshot2.modelId, Math.max(1, Math.floor(batchSize)));
|
|
32218
33907
|
if (commits.length === 0)
|
|
32219
33908
|
return 0;
|
|
32220
33909
|
const result = await embedItemsForProject(projectIdentity, commits.map((commit) => ({
|
|
@@ -32238,8 +33927,8 @@ async function embedCommitBatch(db, projectIdentity, batchSize) {
|
|
|
32238
33927
|
return embeddedCount;
|
|
32239
33928
|
}
|
|
32240
33929
|
async function drainCommitBacklogForProject(db, projectIdentity, deadline) {
|
|
32241
|
-
const
|
|
32242
|
-
if (!
|
|
33930
|
+
const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
|
|
33931
|
+
if (!snapshot2?.gitCommitEnabled)
|
|
32243
33932
|
return 0;
|
|
32244
33933
|
const holderId = `embed-sweep-${randomUUID2()}`;
|
|
32245
33934
|
const lease = acquireGitSweepLease(db, projectIdentity, holderId, { ignoreCooldown: true });
|
|
@@ -32355,7 +34044,7 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
32355
34044
|
if (Date.now() - attemptStart >= EMBED_SLOW_FAILURE_NO_RETRY_MS)
|
|
32356
34045
|
break;
|
|
32357
34046
|
if (attempt < EMBED_SLICE_RETRY_ATTEMPTS - 1) {
|
|
32358
|
-
await new Promise((
|
|
34047
|
+
await new Promise((resolve3) => setTimeout(resolve3, EMBED_SLICE_RETRY_BASE_MS * 2 ** attempt));
|
|
32359
34048
|
}
|
|
32360
34049
|
}
|
|
32361
34050
|
embedded += persistedIds.size;
|
|
@@ -32369,12 +34058,12 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
32369
34058
|
return { embedded, noWork, failed };
|
|
32370
34059
|
}
|
|
32371
34060
|
async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, options) {
|
|
32372
|
-
const
|
|
32373
|
-
if (!
|
|
34061
|
+
const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
|
|
34062
|
+
if (!snapshot2?.enabled || snapshot2.chunkModelId === "off") {
|
|
32374
34063
|
return { status: "disabled", embedded: 0, total: 0 };
|
|
32375
34064
|
}
|
|
32376
34065
|
recordSessionProjectIdentity(db, sessionId, projectIdentity);
|
|
32377
|
-
const total = countUnembeddedSessionCompartments(db, projectIdentity, sessionId,
|
|
34066
|
+
const total = countUnembeddedSessionCompartments(db, projectIdentity, sessionId, snapshot2.chunkModelId);
|
|
32378
34067
|
if (total === 0)
|
|
32379
34068
|
return { status: "nothing", embedded: 0, total: 0 };
|
|
32380
34069
|
const holderId = `session-embed-${randomUUID2()}`;
|
|
@@ -32411,14 +34100,14 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
32411
34100
|
aborted2 = true;
|
|
32412
34101
|
break;
|
|
32413
34102
|
}
|
|
32414
|
-
const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId,
|
|
34103
|
+
const candidates = loadUnembeddedSessionChunkCandidates(db, projectIdentity, sessionId, snapshot2.chunkModelId, batchSize, [...skipIds, ...failedIds]);
|
|
32415
34104
|
if (candidates.length === 0)
|
|
32416
34105
|
break;
|
|
32417
34106
|
const {
|
|
32418
34107
|
embedded: n,
|
|
32419
34108
|
noWork,
|
|
32420
34109
|
failed
|
|
32421
|
-
} = await embedCandidateChunkBatch(db, projectIdentity,
|
|
34110
|
+
} = await embedCandidateChunkBatch(db, projectIdentity, snapshot2.chunkModelId, candidates, drainAbort.signal);
|
|
32422
34111
|
if (leaseLost || !renewGitSweepLease(db, projectIdentity, holderId)) {
|
|
32423
34112
|
leaseLost = true;
|
|
32424
34113
|
drainAbort.abort();
|
|
@@ -32440,7 +34129,7 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
32440
34129
|
}
|
|
32441
34130
|
embedded += n;
|
|
32442
34131
|
options?.onProgress?.({ embedded: Math.min(embedded, total), total });
|
|
32443
|
-
await new Promise((
|
|
34132
|
+
await new Promise((resolve3) => setTimeout(resolve3, 0));
|
|
32444
34133
|
}
|
|
32445
34134
|
} finally {
|
|
32446
34135
|
clearInterval(renewal);
|
|
@@ -32454,7 +34143,7 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
32454
34143
|
if (aborted2)
|
|
32455
34144
|
return { status: "aborted", embedded, total, failed: failedIds.length };
|
|
32456
34145
|
if (providerDown || failedIds.length > 0) {
|
|
32457
|
-
const remaining = Math.max(0, countUnembeddedSessionCompartments(db, projectIdentity, sessionId,
|
|
34146
|
+
const remaining = Math.max(0, countUnembeddedSessionCompartments(db, projectIdentity, sessionId, snapshot2.chunkModelId) - skipIds.length);
|
|
32458
34147
|
if (remaining > 0) {
|
|
32459
34148
|
return { status: "stalled", embedded, total, remaining, failed: failedIds.length };
|
|
32460
34149
|
}
|
|
@@ -32462,29 +34151,29 @@ async function embedSessionCompartmentChunks(db, projectIdentity, sessionId, opt
|
|
|
32462
34151
|
return { status: "done", embedded, total, failed: failedIds.length };
|
|
32463
34152
|
}
|
|
32464
34153
|
function getEmbeddingCoverageStatus(db, projectIdentity, sessionId) {
|
|
32465
|
-
const
|
|
32466
|
-
if (!
|
|
34154
|
+
const snapshot2 = getProjectEmbeddingSnapshot(projectIdentity);
|
|
34155
|
+
if (!snapshot2?.enabled || snapshot2.chunkModelId === "off") {
|
|
32467
34156
|
return {
|
|
32468
34157
|
enabled: false,
|
|
32469
|
-
model:
|
|
32470
|
-
provider:
|
|
34158
|
+
model: snapshot2?.model ?? "off",
|
|
34159
|
+
provider: snapshot2?.provider ?? "off",
|
|
32471
34160
|
session: { embedded: 0, total: 0 },
|
|
32472
34161
|
memories: { embedded: 0, total: 0 },
|
|
32473
34162
|
commits: { embedded: 0, total: 0, gitEnabled: false }
|
|
32474
34163
|
};
|
|
32475
34164
|
}
|
|
32476
|
-
const session = countSessionCompartmentEmbedCoverage(db, projectIdentity, sessionId,
|
|
32477
|
-
const memories = getMemoryEmbedCoverage(db, projectIdentity,
|
|
32478
|
-
const gitEnabled =
|
|
34165
|
+
const session = countSessionCompartmentEmbedCoverage(db, projectIdentity, sessionId, snapshot2.chunkModelId);
|
|
34166
|
+
const memories = getMemoryEmbedCoverage(db, projectIdentity, snapshot2.modelId);
|
|
34167
|
+
const gitEnabled = snapshot2.gitCommitEnabled;
|
|
32479
34168
|
const commits = gitEnabled ? {
|
|
32480
|
-
embedded: countEmbeddedCommits(db, projectIdentity,
|
|
34169
|
+
embedded: countEmbeddedCommits(db, projectIdentity, snapshot2.modelId),
|
|
32481
34170
|
total: getCommitCount(db, projectIdentity),
|
|
32482
34171
|
gitEnabled: true
|
|
32483
34172
|
} : { embedded: 0, total: 0, gitEnabled: false };
|
|
32484
34173
|
return {
|
|
32485
34174
|
enabled: true,
|
|
32486
|
-
model:
|
|
32487
|
-
provider:
|
|
34175
|
+
model: snapshot2.model,
|
|
34176
|
+
provider: snapshot2.provider,
|
|
32488
34177
|
session,
|
|
32489
34178
|
memories,
|
|
32490
34179
|
commits
|
|
@@ -32672,8 +34361,8 @@ async function embedText(text, signal) {
|
|
|
32672
34361
|
}
|
|
32673
34362
|
// src/features/magic-context/memory/embedding-backfill.ts
|
|
32674
34363
|
async function ensureMemoryEmbeddings(args) {
|
|
32675
|
-
const
|
|
32676
|
-
if (!
|
|
34364
|
+
const snapshot2 = getProjectEmbeddingSnapshot(args.projectIdentity);
|
|
34365
|
+
if (!snapshot2?.enabled) {
|
|
32677
34366
|
return args.existingEmbeddings;
|
|
32678
34367
|
}
|
|
32679
34368
|
const missingMemories = args.memories.filter((memory) => !args.existingEmbeddings.has(memory.id));
|
|
@@ -33145,7 +34834,7 @@ function tallyFactsByCategory(facts) {
|
|
|
33145
34834
|
import { join as join7 } from "node:path";
|
|
33146
34835
|
|
|
33147
34836
|
// src/features/magic-context/compaction-marker.ts
|
|
33148
|
-
import { createHash as
|
|
34837
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
33149
34838
|
import { existsSync as existsSync7 } from "node:fs";
|
|
33150
34839
|
import { join as join6 } from "node:path";
|
|
33151
34840
|
var BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
@@ -33153,7 +34842,7 @@ var ID_PREFIX_HEX_LENGTH = 12;
|
|
|
33153
34842
|
var ID_SUFFIX_LENGTH = 14;
|
|
33154
34843
|
var ID_PREFIX_MASK = (1n << BigInt(ID_PREFIX_HEX_LENGTH * 4)) - 1n;
|
|
33155
34844
|
function deterministicBase62(seed, length) {
|
|
33156
|
-
let value = BigInt(`0x${
|
|
34845
|
+
let value = BigInt(`0x${createHash14("sha256").update(seed).digest("hex")}`);
|
|
33157
34846
|
const chars = Array(length);
|
|
33158
34847
|
for (let index = length - 1;index >= 0; index -= 1) {
|
|
33159
34848
|
chars[index] = BASE62_CHARS[Number(value % 62n)];
|
|
@@ -35473,8 +37162,8 @@ function isTransientHistorianPromptError(message) {
|
|
|
35473
37162
|
].some((token) => normalized.includes(token));
|
|
35474
37163
|
}
|
|
35475
37164
|
function sleep(ms) {
|
|
35476
|
-
return new Promise((
|
|
35477
|
-
setTimeout(
|
|
37165
|
+
return new Promise((resolve3) => {
|
|
37166
|
+
setTimeout(resolve3, ms);
|
|
35478
37167
|
});
|
|
35479
37168
|
}
|
|
35480
37169
|
function cleanupHistorianDump(sessionId, dumpPath) {
|
|
@@ -35519,7 +37208,7 @@ function sanitizeDumpName(value) {
|
|
|
35519
37208
|
import { Buffer as Buffer3 } from "node:buffer";
|
|
35520
37209
|
|
|
35521
37210
|
// src/features/magic-context/mural/render-trigger.ts
|
|
35522
|
-
import { createHash as
|
|
37211
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
35523
37212
|
|
|
35524
37213
|
// src/features/magic-context/mural/mural-selection.ts
|
|
35525
37214
|
var DEFAULT_MURAL_MEMORY_BUDGET = 8000;
|
|
@@ -36145,7 +37834,7 @@ function ensureMuralRendered(db, projectIdentity, budgetTokens = DEFAULT_MURAL_M
|
|
|
36145
37834
|
return { hasMural: false, rerendered: false };
|
|
36146
37835
|
}
|
|
36147
37836
|
const rendered = renderMural(entries);
|
|
36148
|
-
const textHash =
|
|
37837
|
+
const textHash = createHash15("sha256").update(rendered.sha256Input).digest("hex");
|
|
36149
37838
|
const existing = getMural(db, projectIdentity);
|
|
36150
37839
|
if (existing && existing.contentHash === textHash && existing.width === rendered.width && existing.height === rendered.height) {
|
|
36151
37840
|
return {
|
|
@@ -36710,11 +38399,15 @@ function trimMemoriesToBudget(sessionId, memories, budgetTokens) {
|
|
|
36710
38399
|
}
|
|
36711
38400
|
function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, projectPath, injectionBudgetTokens, temporalAwareness) {
|
|
36712
38401
|
const cached2 = injectionCache.get(sessionId);
|
|
36713
|
-
if (
|
|
36714
|
-
|
|
38402
|
+
if (cached2 && cached2.db !== db) {
|
|
38403
|
+
clearInjectionCache(sessionId);
|
|
38404
|
+
}
|
|
38405
|
+
const usableCached = cached2?.db === db ? cached2 : undefined;
|
|
38406
|
+
if (!isCacheBusting && usableCached) {
|
|
38407
|
+
if (usableCached.kind === "empty") {
|
|
36715
38408
|
return null;
|
|
36716
38409
|
}
|
|
36717
|
-
const prepared =
|
|
38410
|
+
const prepared = usableCached.injection;
|
|
36718
38411
|
if (prepared.compartmentEndMessageId === null) {
|
|
36719
38412
|
sessionLog(sessionId, "compartment injection cache in degraded mode (null boundary), forcing rebuild");
|
|
36720
38413
|
} else {
|
|
@@ -36761,6 +38454,7 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
36761
38454
|
}
|
|
36762
38455
|
if (compartments.length === 0 && facts.length === 0 && !memoryBlock) {
|
|
36763
38456
|
injectionCache.set(sessionId, {
|
|
38457
|
+
db,
|
|
36764
38458
|
kind: "empty",
|
|
36765
38459
|
compartmentEndMessageId: "",
|
|
36766
38460
|
renderedBytes: 0
|
|
@@ -36800,7 +38494,7 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
36800
38494
|
memoryCount,
|
|
36801
38495
|
rebuiltFromDb: true
|
|
36802
38496
|
};
|
|
36803
|
-
injectionCache.set(sessionId, { kind: "populated", injection: result2 });
|
|
38497
|
+
injectionCache.set(sessionId, { db, kind: "populated", injection: result2 });
|
|
36804
38498
|
return result2;
|
|
36805
38499
|
}
|
|
36806
38500
|
const lastCompartment = compartments[compartments.length - 1];
|
|
@@ -36832,7 +38526,7 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
36832
38526
|
memoryCount,
|
|
36833
38527
|
rebuiltFromDb: true
|
|
36834
38528
|
};
|
|
36835
|
-
injectionCache.set(sessionId, { kind: "populated", injection: result2 });
|
|
38529
|
+
injectionCache.set(sessionId, { db, kind: "populated", injection: result2 });
|
|
36836
38530
|
return result2;
|
|
36837
38531
|
}
|
|
36838
38532
|
let skippedVisibleMessages = 0;
|
|
@@ -36893,7 +38587,7 @@ function prepareCompartmentInjection(db, sessionId, messages, isCacheBusting, pr
|
|
|
36893
38587
|
if (needsFreshMaterialization) {
|
|
36894
38588
|
result.needsFreshMaterialization = true;
|
|
36895
38589
|
}
|
|
36896
|
-
injectionCache.set(sessionId, { kind: "populated", injection: result });
|
|
38590
|
+
injectionCache.set(sessionId, { db, kind: "populated", injection: result });
|
|
36897
38591
|
return result;
|
|
36898
38592
|
}
|
|
36899
38593
|
function readCachedBaselineState(db, sessionId) {
|
|
@@ -37255,7 +38949,7 @@ function readCurrentM0SnapshotMarkersUncached(args) {
|
|
|
37255
38949
|
upgradeState: getUpgradeState(args.db, args.sessionId),
|
|
37256
38950
|
compartmentRenderEpoch: COMPARTMENT_RENDER_EPOCH,
|
|
37257
38951
|
systemHash: hard.systemHash,
|
|
37258
|
-
modelKey: hard.modelKey,
|
|
38952
|
+
modelKey: piModelRefToCanonical(hard.modelKey),
|
|
37259
38953
|
projectIdentity: args.projectPath ?? null,
|
|
37260
38954
|
muralEnabled: args.muralEnabled === true,
|
|
37261
38955
|
renderBudgetIdentity: renderBudgetIdentity(args.memoryInjectionBudgetTokens, args.historyBudgetTokens)
|
|
@@ -37358,7 +39052,9 @@ function mustMaterialize(args) {
|
|
|
37358
39052
|
if (cachedUpgradeIdentity.muralEnabled !== null && cachedUpgradeIdentity.muralEnabled !== current.muralEnabled || cachedUpgradeIdentity.renderBudgetIdentity !== null && cachedUpgradeIdentity.renderBudgetIdentity !== current.renderBudgetIdentity) {
|
|
37359
39053
|
return { value: true, reason: "render_config" };
|
|
37360
39054
|
}
|
|
37361
|
-
|
|
39055
|
+
const canonicalHardModelKey = piModelRefToCanonical(hard.modelKey);
|
|
39056
|
+
const canonicalCachedModelKey = piModelRefToCanonical(args.state.cachedM0ModelKey ?? "");
|
|
39057
|
+
if (canonicalHardModelKey !== "" && canonicalHardModelKey !== canonicalCachedModelKey) {
|
|
37362
39058
|
return { value: true, reason: "model_change" };
|
|
37363
39059
|
}
|
|
37364
39060
|
if (hard.systemHash !== "" && hard.systemHash !== (args.state.cachedM0SystemHash ?? "")) {
|
|
@@ -38102,7 +39798,7 @@ function markersFromCachedRow(row) {
|
|
|
38102
39798
|
};
|
|
38103
39799
|
}
|
|
38104
39800
|
function cachedRowMatchesState(row, state2) {
|
|
38105
|
-
return bufferEqualsNullable(row.cached_m0_bytes, state2.cachedM0Bytes) && (row.cached_m0_mural_data_url ?? null) === (state2.cachedM0MuralDataUrl ?? null) && (row.cached_m0_mural_hash ?? null) === (state2.cachedM0MuralHash ?? null) && row.cached_m0_project_memory_epoch === state2.cachedM0ProjectMemoryEpoch && (row.cached_m0_workspace_fingerprint ?? null) === (state2.cachedM0WorkspaceFingerprint ?? null) && row.cached_m0_project_user_profile_version === state2.cachedM0ProjectUserProfileVersion && row.cached_m0_max_compartment_seq === state2.cachedM0MaxCompartmentSeq && row.cached_m0_max_memory_id === state2.cachedM0MaxMemoryId && row.cached_m0_max_mutation_id === state2.cachedM0MaxMutationId && row.cached_m0_max_memory_mutation_id === state2.cachedM0MaxMemoryMutationId && row.cached_m0_materialized_at === state2.cachedM0MaterializedAt && row.cached_m0_session_facts_version === state2.cachedM0SessionFactsVersion && (row.cached_m0_upgrade_state ?? null) === (state2.cachedM0UpgradeState ?? null) && (row.cached_m0_system_hash ?? "") === (state2.cachedM0SystemHash ?? "") && (row.cached_m0_model_key ?? "") === (state2.cachedM0ModelKey ?? "") && (row.cached_m0_project_identity ?? null) === (state2.cachedM0ProjectIdentity ?? null);
|
|
39801
|
+
return bufferEqualsNullable(row.cached_m0_bytes, state2.cachedM0Bytes) && (row.cached_m0_mural_data_url ?? null) === (state2.cachedM0MuralDataUrl ?? null) && (row.cached_m0_mural_hash ?? null) === (state2.cachedM0MuralHash ?? null) && row.cached_m0_project_memory_epoch === state2.cachedM0ProjectMemoryEpoch && (row.cached_m0_workspace_fingerprint ?? null) === (state2.cachedM0WorkspaceFingerprint ?? null) && row.cached_m0_project_user_profile_version === state2.cachedM0ProjectUserProfileVersion && row.cached_m0_max_compartment_seq === state2.cachedM0MaxCompartmentSeq && row.cached_m0_max_memory_id === state2.cachedM0MaxMemoryId && row.cached_m0_max_mutation_id === state2.cachedM0MaxMutationId && row.cached_m0_max_memory_mutation_id === state2.cachedM0MaxMemoryMutationId && row.cached_m0_materialized_at === state2.cachedM0MaterializedAt && row.cached_m0_session_facts_version === state2.cachedM0SessionFactsVersion && (row.cached_m0_upgrade_state ?? null) === (state2.cachedM0UpgradeState ?? null) && (row.cached_m0_system_hash ?? "") === (state2.cachedM0SystemHash ?? "") && piModelRefToCanonical(row.cached_m0_model_key ?? "") === piModelRefToCanonical(state2.cachedM0ModelKey ?? "") && (row.cached_m0_project_identity ?? null) === (state2.cachedM0ProjectIdentity ?? null);
|
|
38106
39802
|
}
|
|
38107
39803
|
function applyCachedRowToState(state2, row) {
|
|
38108
39804
|
const markers = markersFromCachedRow(row);
|
|
@@ -38559,13 +40255,13 @@ function force80PerRunCap(usable, N) {
|
|
|
38559
40255
|
function force95PerRunCap(usable, N) {
|
|
38560
40256
|
return Math.min(FORCE95_MAX_CAP, Math.max(4 * N, Math.min(Math.round(0.5 * usable), 250000)));
|
|
38561
40257
|
}
|
|
38562
|
-
function selectPerRunCap(
|
|
38563
|
-
const usable = Math.max(1, Math.round(
|
|
38564
|
-
if (
|
|
38565
|
-
return force95PerRunCap(usable,
|
|
38566
|
-
if (
|
|
38567
|
-
return force80PerRunCap(usable,
|
|
38568
|
-
return nonEmergencyPerRunCap(usable,
|
|
40258
|
+
function selectPerRunCap(snapshot2) {
|
|
40259
|
+
const usable = Math.max(1, Math.round(snapshot2.contextLimit * snapshot2.executeThresholdPercentage / 100));
|
|
40260
|
+
if (snapshot2.usagePercentage >= 95)
|
|
40261
|
+
return force95PerRunCap(usable, snapshot2.N);
|
|
40262
|
+
if (snapshot2.usagePercentage >= 80)
|
|
40263
|
+
return force80PerRunCap(usable, snapshot2.N);
|
|
40264
|
+
return nonEmergencyPerRunCap(usable, snapshot2.N);
|
|
38569
40265
|
}
|
|
38570
40266
|
function boundaryMessageId(index, ordinal) {
|
|
38571
40267
|
if (ordinal < 1 || ordinal > index.rawMessageCount)
|
|
@@ -38977,7 +40673,7 @@ function resolveWrapupProtectedTailBoundary(args) {
|
|
|
38977
40673
|
});
|
|
38978
40674
|
const eligibleEndOrdinal = Math.min(head.eligibleEndOrdinal, targetProtectedTailStart);
|
|
38979
40675
|
const rawRangeFingerprint = computeRawRangeFingerprint(messages, offset, eligibleEndOrdinal);
|
|
38980
|
-
const
|
|
40676
|
+
const snapshot2 = {
|
|
38981
40677
|
sessionId: ctx.sessionId,
|
|
38982
40678
|
mode: "manual-wrapup",
|
|
38983
40679
|
offset,
|
|
@@ -39007,7 +40703,7 @@ function resolveWrapupProtectedTailBoundary(args) {
|
|
|
39007
40703
|
boundaryReason
|
|
39008
40704
|
};
|
|
39009
40705
|
return {
|
|
39010
|
-
snapshot,
|
|
40706
|
+
snapshot: snapshot2,
|
|
39011
40707
|
rawMessagesAboveLastCompartment,
|
|
39012
40708
|
anchorRawMessageCount,
|
|
39013
40709
|
targetProtectedTailStart,
|
|
@@ -39026,46 +40722,46 @@ function getRawHistoryEligibility(db, sessionId) {
|
|
|
39026
40722
|
hasRawBeyondLastCompartment: rawMessageCount >= offset
|
|
39027
40723
|
};
|
|
39028
40724
|
}
|
|
39029
|
-
function hasRunnableCompartmentWindow(
|
|
39030
|
-
if (
|
|
40725
|
+
function hasRunnableCompartmentWindow(snapshot2) {
|
|
40726
|
+
if (snapshot2.offset >= snapshot2.protectedTailStart)
|
|
39031
40727
|
return false;
|
|
39032
|
-
const forceMaterializationPercentage = escalationBands(
|
|
39033
|
-
if (
|
|
39034
|
-
return
|
|
40728
|
+
const forceMaterializationPercentage = escalationBands(snapshot2.executeThresholdPercentage).forceMaterializationPercentage;
|
|
40729
|
+
if (snapshot2.usagePercentage >= forceMaterializationPercentage || snapshot2.emergencyTailScale) {
|
|
40730
|
+
return snapshot2.trueRawEligibleTokens >= deriveMinForceEligibleTokens(snapshot2.N) || snapshot2.eligibleEndOrdinal > snapshot2.offset;
|
|
39035
40731
|
}
|
|
39036
|
-
return
|
|
40732
|
+
return snapshot2.eligibleEndOrdinal > snapshot2.offset;
|
|
39037
40733
|
}
|
|
39038
40734
|
function validateBoundarySnapshot(args) {
|
|
39039
|
-
const { snapshot } = args;
|
|
39040
|
-
if (args.currentContextLimit && args.currentContextLimit !==
|
|
40735
|
+
const { snapshot: snapshot2 } = args;
|
|
40736
|
+
if (args.currentContextLimit && args.currentContextLimit !== snapshot2.contextLimit) {
|
|
39041
40737
|
return {
|
|
39042
40738
|
ok: false,
|
|
39043
40739
|
reason: "model_or_limit_changed",
|
|
39044
|
-
detail: `context limit changed from ${
|
|
40740
|
+
detail: `context limit changed from ${snapshot2.contextLimit} to ${args.currentContextLimit}`
|
|
39045
40741
|
};
|
|
39046
40742
|
}
|
|
39047
|
-
const messages = readRawSessionMessages(
|
|
40743
|
+
const messages = readRawSessionMessages(snapshot2.sessionId);
|
|
39048
40744
|
const currentRawMessageCount = messages.reduce((max, message) => Math.max(max, message.ordinal), messages.length);
|
|
39049
|
-
if (
|
|
40745
|
+
if (snapshot2.rawMessageCountAtTrigger > currentRawMessageCount) {
|
|
39050
40746
|
return { ok: false, reason: "stale_snapshot", detail: "raw message count shrank" };
|
|
39051
40747
|
}
|
|
39052
40748
|
const idsByOrdinal = new Map(messages.map((message) => [message.ordinal, message.id]));
|
|
39053
40749
|
const idAt = (ordinal) => idsByOrdinal.get(ordinal) ?? null;
|
|
39054
40750
|
const checks3 = [
|
|
39055
|
-
[
|
|
39056
|
-
[
|
|
40751
|
+
[snapshot2.offset, snapshot2.offsetMessageId, "offset"],
|
|
40752
|
+
[snapshot2.rawMessageCountAtTrigger, snapshot2.rawLastMessageIdAtTrigger, "last"]
|
|
39057
40753
|
];
|
|
39058
|
-
if (
|
|
40754
|
+
if (snapshot2.protectedTailStart <= snapshot2.rawMessageCountAtTrigger) {
|
|
39059
40755
|
checks3.push([
|
|
39060
|
-
|
|
39061
|
-
|
|
40756
|
+
snapshot2.protectedTailStart,
|
|
40757
|
+
snapshot2.protectedTailStartMessageId,
|
|
39062
40758
|
"protectedTailStart"
|
|
39063
40759
|
]);
|
|
39064
40760
|
}
|
|
39065
|
-
if (
|
|
40761
|
+
if (snapshot2.eligibleEndOrdinal > snapshot2.offset) {
|
|
39066
40762
|
checks3.push([
|
|
39067
|
-
|
|
39068
|
-
|
|
40763
|
+
snapshot2.eligibleEndOrdinal - 1,
|
|
40764
|
+
snapshot2.eligibleEndMessageId,
|
|
39069
40765
|
"eligibleEnd"
|
|
39070
40766
|
]);
|
|
39071
40767
|
}
|
|
@@ -39078,26 +40774,26 @@ function validateBoundarySnapshot(args) {
|
|
|
39078
40774
|
};
|
|
39079
40775
|
}
|
|
39080
40776
|
}
|
|
39081
|
-
const expectedOffset = Math.max(1, getLastCompartmentEndMessage(args.db,
|
|
39082
|
-
if (expectedOffset !==
|
|
40777
|
+
const expectedOffset = Math.max(1, getLastCompartmentEndMessage(args.db, snapshot2.sessionId) + 1);
|
|
40778
|
+
if (expectedOffset !== snapshot2.offset) {
|
|
39083
40779
|
return {
|
|
39084
40780
|
ok: false,
|
|
39085
40781
|
reason: "stale_snapshot",
|
|
39086
|
-
detail: `last compartment moved: offset ${
|
|
40782
|
+
detail: `last compartment moved: offset ${snapshot2.offset} -> ${expectedOffset}`
|
|
39087
40783
|
};
|
|
39088
40784
|
}
|
|
39089
|
-
const fingerprint = computeRawRangeFingerprint(messages,
|
|
39090
|
-
if (fingerprint !==
|
|
40785
|
+
const fingerprint = computeRawRangeFingerprint(messages, snapshot2.offset, snapshot2.eligibleEndOrdinal);
|
|
40786
|
+
if (fingerprint !== snapshot2.rawRangeFingerprint) {
|
|
39091
40787
|
return { ok: false, reason: "stale_snapshot", detail: "raw range fingerprint changed" };
|
|
39092
40788
|
}
|
|
39093
40789
|
return { ok: true };
|
|
39094
40790
|
}
|
|
39095
|
-
function recordHighPressureNoEligibleHead(db,
|
|
39096
|
-
const forceMaterializationPercentage = escalationBands(
|
|
39097
|
-
if (
|
|
40791
|
+
function recordHighPressureNoEligibleHead(db, snapshot2) {
|
|
40792
|
+
const forceMaterializationPercentage = escalationBands(snapshot2.executeThresholdPercentage).forceMaterializationPercentage;
|
|
40793
|
+
if (snapshot2.usagePercentage < forceMaterializationPercentage && !snapshot2.emergencyTailScale) {
|
|
39098
40794
|
return 0;
|
|
39099
40795
|
}
|
|
39100
|
-
return recordProtectedTailNoEligibleHead(db,
|
|
40796
|
+
return recordProtectedTailNoEligibleHead(db, snapshot2.sessionId);
|
|
39101
40797
|
}
|
|
39102
40798
|
|
|
39103
40799
|
// src/hooks/magic-context/reference-seeds.generated.ts
|
|
@@ -42257,7 +43953,7 @@ async function executeContextRecomp(deps, options = {}) {
|
|
|
42257
43953
|
}
|
|
42258
43954
|
|
|
42259
43955
|
// src/hooks/magic-context/lkg-slot.ts
|
|
42260
|
-
import { createHash as
|
|
43956
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
42261
43957
|
var LKG_TOTAL_BYTES = 64 * 1024 * 1024;
|
|
42262
43958
|
var LKG_SINGLE_SLOT_BYTES = 24 * 1024 * 1024;
|
|
42263
43959
|
var LKG_METADATA_BYTES = 256;
|
|
@@ -42319,13 +44015,32 @@ function lkgContentFields(value) {
|
|
|
42319
44015
|
}
|
|
42320
44016
|
}
|
|
42321
44017
|
function lkgContentDigestFromFields(fields) {
|
|
42322
|
-
const hash2 =
|
|
44018
|
+
const hash2 = createHash16("sha256");
|
|
42323
44019
|
for (const field of fields) {
|
|
42324
44020
|
const value = typeof field === "symbol" ? field.description ?? "" : String(field);
|
|
42325
44021
|
hash2.update(`${typeof field}:${value.length}:`).update(value).update("\x00");
|
|
42326
44022
|
}
|
|
42327
44023
|
return hash2.digest("base64url");
|
|
42328
44024
|
}
|
|
44025
|
+
function incrementalLkgContentDigests(entries, prior) {
|
|
44026
|
+
const aligned = prior !== undefined && prior.ids.length === prior.signatures.length && prior.signatures.length === prior.digests.length;
|
|
44027
|
+
let reusedPrefix = 0;
|
|
44028
|
+
if (aligned && prior) {
|
|
44029
|
+
while (reusedPrefix < entries.length && reusedPrefix < prior.ids.length && entries[reusedPrefix]?.id === prior.ids[reusedPrefix] && entries[reusedPrefix]?.signature === prior.signatures[reusedPrefix]) {
|
|
44030
|
+
reusedPrefix += 1;
|
|
44031
|
+
}
|
|
44032
|
+
}
|
|
44033
|
+
const digests = [];
|
|
44034
|
+
if (aligned && prior) {
|
|
44035
|
+
for (let index = 0;index < reusedPrefix; index += 1) {
|
|
44036
|
+
digests.push(prior.digests[index]);
|
|
44037
|
+
}
|
|
44038
|
+
}
|
|
44039
|
+
for (let index = reusedPrefix;index < entries.length; index += 1) {
|
|
44040
|
+
digests.push(lkgContentDigestFromFields(entries[index]?.fields ?? []));
|
|
44041
|
+
}
|
|
44042
|
+
return { digests, reusedPrefix };
|
|
44043
|
+
}
|
|
42329
44044
|
function lkgContentDigest(message) {
|
|
42330
44045
|
const fields = lkgContentFields(message);
|
|
42331
44046
|
return fields ? lkgContentDigestFromFields(fields) : null;
|
|
@@ -42335,7 +44050,7 @@ function touch(sessionId, entry) {
|
|
|
42335
44050
|
slots.set(sessionId, entry);
|
|
42336
44051
|
}
|
|
42337
44052
|
function captureSlot(sessionId, slot) {
|
|
42338
|
-
if (slot.inputContentDigests.length !== slot.inputIdSeq.length || slot.inputContentDigests.some((digest) => digest.length === 0)) {
|
|
44053
|
+
if (slot.inputContentDigests.length !== slot.inputIdSeq.length || slot.inputContentDigests.some((digest) => digest.length === 0) || slot.inputContentSignatures !== undefined && (slot.inputContentSignatures.length !== slot.inputIdSeq.length || slot.inputContentSignatures.some((signature) => signature.length === 0))) {
|
|
42339
44054
|
return false;
|
|
42340
44055
|
}
|
|
42341
44056
|
const bytes = slotBytes(slot);
|
|
@@ -42368,7 +44083,8 @@ function captureSlot(sessionId, slot) {
|
|
|
42368
44083
|
slot: {
|
|
42369
44084
|
...slot,
|
|
42370
44085
|
inputIdSeq: [...slot.inputIdSeq],
|
|
42371
|
-
inputContentDigests: [...slot.inputContentDigests]
|
|
44086
|
+
inputContentDigests: [...slot.inputContentDigests],
|
|
44087
|
+
inputContentSignatures: slot.inputContentSignatures ? [...slot.inputContentSignatures] : undefined
|
|
42372
44088
|
},
|
|
42373
44089
|
bytes
|
|
42374
44090
|
};
|
|
@@ -42384,7 +44100,8 @@ function getSlot(sessionId) {
|
|
|
42384
44100
|
return {
|
|
42385
44101
|
...entry.slot,
|
|
42386
44102
|
inputIdSeq: [...entry.slot.inputIdSeq],
|
|
42387
|
-
inputContentDigests: [...entry.slot.inputContentDigests]
|
|
44103
|
+
inputContentDigests: [...entry.slot.inputContentDigests],
|
|
44104
|
+
inputContentSignatures: entry.slot.inputContentSignatures ? [...entry.slot.inputContentSignatures] : undefined
|
|
42388
44105
|
};
|
|
42389
44106
|
}
|
|
42390
44107
|
function dropSlot(sessionId, _reason) {
|
|
@@ -42654,4 +44371,4 @@ async function runUpgradeMemoryMigration(ctx, sessionId, migrationDirectory) {
|
|
|
42654
44371
|
}
|
|
42655
44372
|
}
|
|
42656
44373
|
|
|
42657
|
-
export { withContentLanguageDirective, buildPrimaryLanguageDirective, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, resolveLegacyConfigSources, resolveLegacyConfigSourcesForHarness, migrateMagicContextConfigLocations, exports_external, DEFAULT_PROTECTED_TAGS, parseCron, nextOccurrence, nextDueAtMs, promptSurfaceConfigIdentity, resolvePromptSurface, resolveModelConfigOrDefault, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, DEFAULT_LOCAL_EMBEDDING_MODEL, MagicContextConfigSchema, getOpenCodeDbPath, removeMcOwnedCompactionMarkers, isFailClosedBlockingError, shouldBypassFailClosedBlock, resolveAgentNameFromMessages, createFailClosedController, recordHookInitFailure, clearHookInitFailure, getLastHookInitFailure, ProjectIdentityError, resolveProjectIdentityStrict, takeDubiousOwnershipProjectIdentityWarning, resolveProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, recordSessionProjectIdentity, beginBootQuietPeriod, bootQuietRemainingMs, scheduleAfterBootQuiet, rpcPortDir, rpcPortFilePath, isPidAlive, parseRpcPortFile, registerModuleNoteEvaluationBridge, getModuleNoteEvaluationBridge, getContextStoreUuid, ensureContextStoreUuid, getAuthorityManagedMarker, reconcileAuthorityProject, checksumAuthoritySeedRows, prepareAuthority, drainAuthority, getMirrorCursor, applyMirroredNoteCompileFields, applyMirrorPage, pullMemoryMirrorOnce, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, computeWorkspaceEpochFingerprint, recordToolDefinition, getMeasuredToolDefinitionTokens, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, runSqliteOptimize, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, clearRecompStaging, recordEmbeddingMeasurement, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, isEmergencyRecoveryArmed, isProviderOverflowReconfirmed, getEmergencyRecoveryArmedAt, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, getPersistedReasoningWatermark, setPersistedReasoningWatermark, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, getNoteNudgeAnchors, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, removeNoteNudgeAnchorByMessageId, removeAutoSearchHintDecisionByMessageId, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, setNoteLastReadAt, getHistorianFailureState, clearHistorianFailureState, getOverflowState, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, removeStrippedPlaceholderId, getStaleReduceStrippedIds, addStaleReduceStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, getSessionsWithPendingMarker, setSessionWorkMetrics, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNote, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectMemoryEpoch, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, getActiveTagTokenAggregate, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, updateTagMessageId, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getDroppedTagsBySession, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, createChildSessionWithFence, detectOverflow, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, extractLatestAssistantText, hasLengthCappedOutput, setKeepSubagents, shouldKeepSubagents, recordChildInvocation, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, Priority, AdmissionClass, StaleRouteHandleError, SocketClosedError, SocketTimeoutError, SubcClient, isConsumerReconnectTransient, getCompartmentEvents, loadCompartmentChunkEmbeddingsForSearch, cosineSimilarity, SYNAPSE_DEFAULT_MODEL, SynapseEmbeddingProvider, computeNormalizedHash, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitTimeMs, enforceProjectCap, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, saveEmbeddingIfHashMatches, getProjectEmbeddings, peekProjectEmbeddings, invalidateProject, invalidateMemory, markProjectLoadUntrusted, contentSha256, sweepStaleEmbeddingIdentitiesForProject, registerProjectEmbedding, registerProjectShadowEmbedding, getShadowEmbeddingMeasurementCohort, getPrimaryEmbeddingMeasurementCohort, embedShadowTextForProject, enqueueShadowEmbeddingItems, registerProjectInObservationMode, getProjectEmbeddingSnapshot, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, isEmbeddingEnabled, embedText, ensureMemoryEmbeddings, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, buildWorkspaceMemorySqlFilter, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, setMemoryClassification, supersededMemory, mergeMemoryStats, archiveMemory, getMemoryCountsByStatus, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, getMural, BoundedSessionMap, extractM0Block, formatDate, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, prepareCompartmentInjection, renderCompartmentInjection, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, injectM0M1, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, RECOVERY_NO_HEAD_LIMIT, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, snapRangeToCompartments, LKG_SNAPSHOT_ARRAY, LKG_SNAPSHOT_OBJECT, LKG_SNAPSHOT_KEY, LKG_SNAPSHOT_STRING, LKG_SNAPSHOT_NUMBER, LKG_SNAPSHOT_BOOLEAN, LKG_SNAPSHOT_NULL, LKG_SNAPSHOT_UNDEFINED, lkgContentDigestFromFields, lkgContentDigest, captureSlot, getSlot, dropSlot, noteEntry, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, isRecompFailure, isRecompSkip, isRecompComplete, extractRecompReason, contextualizeUpgradeReason, setRecompStarting, setRecompNote, setRecompTerminal, runManagedRecomp, runManagedUpgrade };
|
|
44374
|
+
export { withContentLanguageDirective, buildPrimaryLanguageDirective, cortexKitUserConfigBasePath, cortexKitProjectConfigBasePath, resolveLegacyConfigSources, resolveLegacyConfigSourcesForHarness, migrateMagicContextConfigLocations, exports_external, DEFAULT_PROTECTED_TAGS, parseCron, nextOccurrence, nextDueAtMs, promptSurfaceConfigIdentity, resolvePromptSurface, resolveModelConfigOrDefault, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, DEFAULT_LOCAL_EMBEDDING_MODEL, MagicContextConfigSchema, getOpenCodeDbPath, removeMcOwnedCompactionMarkers, isFailClosedBlockingError, shouldBypassFailClosedBlock, resolveAgentNameFromMessages, createFailClosedController, recordHookInitFailure, clearHookInitFailure, getLastHookInitFailure, ProjectIdentityError, resolveProjectIdentityStrict, takeDubiousOwnershipProjectIdentityWarning, resolveProjectIdentity, resolveProjectIdentityForSession, normalizeStoredProjectPath, storedPathBelongsToIdentity, isLinkedGitWorktree, recordSessionProjectIdentity, beginBootQuietPeriod, bootQuietRemainingMs, scheduleAfterBootQuiet, rpcPortDir, rpcPortFilePath, isPidAlive, parseRpcPortFile, registerModuleNoteEvaluationBridge, getModuleNoteEvaluationBridge, getContextStoreUuid, ensureContextStoreUuid, getAuthorityManagedMarker, reconcileAuthorityProject, checksumAuthoritySeedRows, prepareAuthority, drainAuthority, getMirrorCursor, applyMirroredNoteCompileFields, applyMirrorPage, pullMemoryMirrorOnce, V2_MEMORY_CATEGORIES, CATEGORY_PRIORITY, resolveWorkspaceShareCategories, resolveWorkspaceIdentitySet, expandWorkspaceIdentitySetWithAliases, resolveStoredPathWorkspaceIdentity, storedPathBelongsToWorkspace, sourceNameForMemory, computeWorkspaceEpochFingerprint, recordToolDefinition, getMeasuredToolDefinitionTokens, getSchemaFenceRejection, getMigrationOnOpenRefusal, LATEST_SUPPORTED_VERSION, getDatabasePath, getPersistedSchemaVersion, setSqlitePragmaConfig, runSqliteOptimize, openDatabase, openDatabaseAsync, isDatabasePersisted, getDatabasePersistenceError, COMPARTMENT_LEASE_RENEWAL_MS, acquireCompartmentLease, renewCompartmentLease, releaseCompartmentLease, getCompartments, getLastCompartmentEndMessage, getLastCompartmentEndMessageId, clearRecompStaging, recordEmbeddingMeasurement, getMaxM0MutationId, queueMemoryMutation, getMemoryMutationsForRenderByProjects, getMaxMemoryMutationIdForProjects, MAX_EXECUTE_THRESHOLD, escalationBands, isEmergencyRecoveryArmed, isProviderOverflowReconfirmed, getEmergencyRecoveryArmedAt, loadPersistedUsage, loadProtectedTailMeta, resetProtectedTailNoEligibleHead, getWrapupInProgressState, acquireWrapupInProgress, updateWrapupInProgress, releaseWrapupInProgress, resolveCompactionModeRecord, getCompactionModeRecord, setCompactionModeRecord, getPersistedReasoningWatermark, setPersistedReasoningWatermark, clearPersistedReasoningWatermark, getEmergencyInputSample, setEmergencyDropSample, clearEmergencyDropSample, getLastNudgeUndropped, setLastNudgeUndropped, getLastNudgeLevel, setLastNudgeLevel, resetLastNudgeCycle, resetLastNudgeCycleIfTailShrank, getChannel2NudgeState, getChannel2NudgeClaim, setChannel2NudgeState, casChannel2NudgeState, claimChannel2NudgeState, casChannel2NudgeClaim, getPersistedNoteNudge, getNoteNudgeAnchors, getAutoSearchHintDecisions, appendAutoSearchHintDecision, pruneNoteNudgeAnchors, pruneAutoSearchHintDecisions, removeNoteNudgeAnchorByMessageId, removeAutoSearchHintDecisionByMessageId, getPersistedTodoPermissionDenied, setPersistedTodoPermissionDenied, getPersistedTodoSyntheticAnchor, setPersistedTodoSyntheticAnchor, clearPersistedTodoSyntheticAnchor, setNoteLastReadAt, getHistorianFailureState, clearHistorianFailureState, getOverflowState, recordOverflowDetected, recordDetectedContextLimit, clearEmergencyRecovery, clearDetectedContextLimit, getPersistedCompactionMarkerState, setPersistedCompactionMarkerState, getStrippedPlaceholderIds, applyStrippedPlaceholderDelta, removeStrippedPlaceholderId, getMergedReasoningStrippedIds, addMergedReasoningStrippedIds, getTrailingBlankDecisions, addTrailingBlankDecisions, getStaleReduceStrippedIds, addStaleReduceStrippedIds, getProcessedImageStrippedIds, addProcessedImageStrippedIds, getPendingCompactionMarkerState, clearPendingCompactionMarkerStateIf, peekDeferredExecutePending, setDeferredExecutePendingIfAbsent, clearDeferredExecutePendingIfMatches, getSessionsWithPendingMarker, setSessionWorkMetrics, getNotes, addNote, getSessionNotes, getPendingSmartNotes, getReadySmartNotes, updateNote, dismissNote, markNoteReady, markNoteChecked, queuePendingOp, getPendingOps, clearPendingOps, removePendingOp, PRIMER_CANDIDATE_TTL_MS, PRIMER_CANDIDATE_MAX_AGE_MS, primerOccurrenceKey, primerOccurrenceUtcDay, updatePrimerCandidateEmbedding, getPrimerCandidatesByIds, getPrimerCandidatesForPromotion, countPrimerCandidatesForProject, getActivePrimers, createPrimer, updatePrimerSupport, updatePrimerAnswer, GLOBAL_USER_PROFILE_PROJECT_PATH, getProjectState, bumpProjectMemoryEpoch, bumpProjectUserProfileVersion, saveSourceContent, replaceSourceContent, getSourceContents, CTX_REDUCE_KEEP, estimateImageTokensFromDataUrl, normalizeTodoStateJson, buildSyntheticTodoPart, computeSyntheticCallId, isSyntheticTodoPart, tailHygieneStructuralSignature, sameTailHygieneStructuralSignature, refreshTailHygieneBaseline, effectiveTailHygiene, assertTailHygieneContentUnchanged, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, toolOutputTokens, decideChannel1, evaluateChannel2, buildChannel2Reminder, buildChannel1Reminder, estimateEmergencyDropReclaimTokens, planEmergencyDrop, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, updateTagDropMode, updateCavemanDepth, updateTagMessageId, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, deriveTagLoadFloor, getTagsBySession, getActiveTagsBySession, getTailHygieneTags, getDroppedTagsBySession, getTagsByNumbers, getMaxDroppedTagNumber, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, createChildSessionWithFence, detectOverflow, promptSyncWithValidatedOutputRetry, normalizeSDKResponse, promptSurfaceHashMaterial, createPromptSurfaceRuntime, createPromptSurfaceGuidanceEpochCache, extractLatestAssistantText, hasLengthCappedOutput, setKeepSubagents, shouldKeepSubagents, recordChildInvocation, COMPARTMENT_AGENT_SYSTEM_PROMPT, HISTORIAN_EDITOR_SYSTEM_PROMPT, COMPARTMENT_STRUCTURAL_SYSTEM_PROMPT, Priority, AdmissionClass, StaleRouteHandleError, SocketClosedError, SocketTimeoutError, SubcClient, isConsumerReconnectTransient, connectionFileExists, getCompartmentEvents, loadCompartmentChunkEmbeddingsForSearch, cosineSimilarity, SYNAPSE_DEFAULT_MODEL, SynapseEmbeddingProvider, computeNormalizedHash, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitTimeMs, enforceProjectCap, GIT_SWEEP_LEASE_RENEWAL_MS, acquireGitSweepLease, renewGitSweepLease, markGitSweepSuccessAndRelease, parkGitSweepNonIndexable, releaseGitSweepLease, saveEmbeddingIfHashMatches, getProjectEmbeddings, peekProjectEmbeddings, invalidateProject, invalidateMemory, markProjectLoadUntrusted, contentSha256, sweepStaleEmbeddingIdentitiesForProject, registerProjectEmbedding, registerProjectShadowEmbedding, getShadowEmbeddingMeasurementCohort, getPrimaryEmbeddingMeasurementCohort, embedShadowTextForProject, enqueueShadowEmbeddingItems, registerProjectInObservationMode, getProjectEmbeddingSnapshot, embedTextForProject, embedBatchForProject, embedItemsForProject, embedUnembeddedMemoriesForProject, drainCommitBacklogForProject, embedSessionCompartmentChunks, getEmbeddingCoverageStatus, isEmbeddingEnabled, embedText, ensureMemoryEmbeddings, computeCueContentHash, hasMuralCueColumns, getMuralCueState, memoryNeedsCue, setMuralCue, recordMuralCueRejection, hasMemoryShareableColumn, hasMemoryClassifiedAtColumn, getUnclassifiedMemoryIds, ModuleMemoryAuthorityError, insertMemory, insertMemoryIdempotent, getMemoryByHash, getMemoriesByProject, buildWorkspaceMemorySqlFilter, getMemoriesByProjects, getMaxMemoryIdForProjects, readNewMemoriesForM1Union, getMemoryById, getMemoriesByIds, updateMemorySeenCount, updateMemoryRetrievalCount, setMemoryClassification, supersededMemory, mergeMemoryStats, archiveMemory, getMemoryCountsByStatus, sanitizeFtsQuery, searchMemoriesFTS, searchMemoriesFTSUnion, recordMemoryMapping, recordMemoryVerifications, getUnmappedMemoryIds, clearMemoryVerifications, getMemoryVerifications, resolveGitTopLevel, readGitHead, readGitChangedFilesSince, readGitFileChangeTimesSince, verificationFileExists, normalizeVerificationFiles, USER_MEMORY_CANDIDATE_TTL_MS, insertUserMemoryCandidates, getUserMemoryCandidates, deleteUserMemoryCandidates, pruneExpiredUserMemoryCandidates, insertUserMemory, getActiveUserMemories, updateUserMemoryContent, dismissUserMemory, MARKER_SUMMARY_TEXT, applyDeferredCompactionMarker, removeCompactionMarkerForSession, checkCompactionMarkerConsistency, getMural, resolveMuralWire, BoundedSessionMap, extractM0Block, formatDate, injectTemporalMarkers, clearInjectionCache, getVisibleMemoryIds, prepareCompartmentInjection, renderCompartmentInjection, mustMaterialize, trimMemoriesToBudgetV2, renderMemoryBlockV2, injectM0M1, onNoteTrigger, peekNoteNudgeText, markNoteNudgeDelivered, clearNoteNudgeTriggerAndCooldown, resetNoteNudgeCooldownOnly, clearNoteNudgeTriggerOnly, RECOVERY_NO_HEAD_LIMIT, resolveOpenCodeProtectedTailBoundary, resolveWrapupProtectedTailBoundary, getRawHistoryEligibility, hasRunnableCompartmentWindow, recordHighPressureNoEligibleHead, runCompartmentAgent, snapRangeToCompartments, LKG_SNAPSHOT_ARRAY, LKG_SNAPSHOT_OBJECT, LKG_SNAPSHOT_KEY, LKG_SNAPSHOT_STRING, LKG_SNAPSHOT_NUMBER, LKG_SNAPSHOT_BOOLEAN, LKG_SNAPSHOT_NULL, LKG_SNAPSHOT_UNDEFINED, incrementalLkgContentDigests, lkgContentDigest, captureSlot, getSlot, dropSlot, noteEntry, getActiveCompartmentRun, markActiveCompartmentRunPublished, registerActiveCompartmentRun, startCompartmentAgent, isRecompFailure, isRecompSkip, isRecompComplete, extractRecompReason, contextualizeUpgradeReason, setRecompStarting, setRecompNote, setRecompTerminal, runManagedRecomp, runManagedUpgrade };
|