@cortexkit/pi-magic-context 0.49.12 → 0.49.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-search-worker.js +3 -3
- package/dist/chunk-embedding-write-worker.js +87 -0
- package/dist/{embedding-backfill-14tqcfrn.js → embedding-backfill-7kj16fh9.js} +5 -4
- package/dist/embedding-worker.js +1 -1
- package/dist/historian-calibration-extension.js +1 -1
- package/dist/index-1mrvw9en.js +225 -0
- package/dist/{index-af9nb5db.js → index-7qc73yk5.js} +60 -3
- package/dist/{index-xpsht877.js → index-7wagp5jp.js} +2 -2
- package/dist/{index-zapgkmp7.js → index-aypx5h57.js} +34 -45
- package/dist/{index-f6e8jsrh.js → index-nwbhe6qv.js} +188 -241
- package/dist/{index-z5ftst3e.js → index-t27xk4r7.js} +1 -1
- package/dist/{index-6hex51s9.js → index-vv1j5cak.js} +1 -1
- package/dist/{index-gykw2zhn.js → index-wp9q91kn.js} +4 -4
- package/dist/{index-xmdkde4v.js → index-y29y2j2w.js} +12 -1
- package/dist/index.js +523 -175
- package/dist/{message-index-dfs6k35a.js → message-index-7w179p64.js} +2 -2
- package/dist/{message-index-bounded-ws37m1nt.js → message-index-bounded-80n96ehp.js} +2 -2
- package/dist/migration-worker.js +1 -1
- package/dist/{project-embedding-registry-ymvne11v.js → project-embedding-registry-52zwmtbn.js} +4 -3
- package/dist/raw-ordinal-warmup-worker.js +2 -2
- package/dist/{search-85e21wb8.js → search-hffb8xht.js} +7 -6
- package/dist/subagent-entry.js +9 -8
- package/package.json +2 -2
- /package/dist/{index-j24916mq.js → index-9jvktm7k.js} +0 -0
- /package/dist/{index-69vas84q.js → index-e6xnpach.js} +0 -0
package/dist/index.js
CHANGED
|
@@ -55,12 +55,6 @@ import {
|
|
|
55
55
|
advanceToolReclaimWatermark,
|
|
56
56
|
retryPendingSessionCleanups,
|
|
57
57
|
retryPendingRustSessionCleanupsForProject,
|
|
58
|
-
embedPauseBySession,
|
|
59
|
-
embedRunStateBySession,
|
|
60
|
-
autoEmbedAttemptedBySession,
|
|
61
|
-
autoEmbedIdentityBySession,
|
|
62
|
-
invalidateAutoEmbedSession,
|
|
63
|
-
getEmbedDrainUiStatus,
|
|
64
58
|
COMPARTMENT_LEASE_RENEWAL_MS,
|
|
65
59
|
acquireCompartmentLease,
|
|
66
60
|
renewCompartmentLease,
|
|
@@ -253,7 +247,7 @@ import {
|
|
|
253
247
|
registerTodoStateLifecycle,
|
|
254
248
|
syncCtxMemoryToolEnabled,
|
|
255
249
|
registerMagicContextTools
|
|
256
|
-
} from "./index-
|
|
250
|
+
} from "./index-aypx5h57.js";
|
|
257
251
|
import {
|
|
258
252
|
canonicalModelIdentity,
|
|
259
253
|
piModelRefToCanonical,
|
|
@@ -293,7 +287,7 @@ import {
|
|
|
293
287
|
openCurrentDatabase,
|
|
294
288
|
openDatabaseAsync,
|
|
295
289
|
closeDatabase
|
|
296
|
-
} from "./index-
|
|
290
|
+
} from "./index-t27xk4r7.js";
|
|
297
291
|
import {
|
|
298
292
|
setHomeProjectPermission,
|
|
299
293
|
ProjectIdentityError,
|
|
@@ -626,7 +620,7 @@ import {
|
|
|
626
620
|
indexSingleMessage2,
|
|
627
621
|
indexMessagesAfterOrdinal2,
|
|
628
622
|
sweepOrphanedOpenCodeMessageIndexes2
|
|
629
|
-
} from "./index-
|
|
623
|
+
} from "./index-vv1j5cak.js";
|
|
630
624
|
import {
|
|
631
625
|
formatSynapseLaneDescriptor
|
|
632
626
|
} from "./index-6dz2ed1v.js";
|
|
@@ -642,7 +636,7 @@ import {
|
|
|
642
636
|
replaceCompartmentChunkEmbeddings,
|
|
643
637
|
deleteChunkEmbedBackoffForSession,
|
|
644
638
|
chunkWindowSourceKey
|
|
645
|
-
} from "./index-
|
|
639
|
+
} from "./index-7qc73yk5.js";
|
|
646
640
|
import {
|
|
647
641
|
recordSessionProjectIdentity,
|
|
648
642
|
GIT_SWEEP_LEASE_RENEWAL_MS,
|
|
@@ -650,7 +644,17 @@ import {
|
|
|
650
644
|
renewGitSweepLease,
|
|
651
645
|
markGitSweepSuccessAndRelease,
|
|
652
646
|
parkGitSweepNonIndexable,
|
|
653
|
-
releaseGitSweepLease
|
|
647
|
+
releaseGitSweepLease
|
|
648
|
+
} from "./index-1mrvw9en.js";
|
|
649
|
+
import {
|
|
650
|
+
embedPauseBySession,
|
|
651
|
+
embedRunStateBySession,
|
|
652
|
+
activeEmbeddingSessions,
|
|
653
|
+
autoEmbedAttemptedBySession,
|
|
654
|
+
autoEmbedIdentityBySession,
|
|
655
|
+
autoEmbedRetryAfterBySession,
|
|
656
|
+
invalidateAutoEmbedSession,
|
|
657
|
+
getEmbedDrainUiStatus,
|
|
654
658
|
describeShadowBackfillWriteRefusal2,
|
|
655
659
|
contentSha2562,
|
|
656
660
|
drainProjectEmbeddingIdentityMaintenance2,
|
|
@@ -667,7 +671,7 @@ import {
|
|
|
667
671
|
embedSessionCompartmentChunks2,
|
|
668
672
|
getEmbeddingCoverageStatus2,
|
|
669
673
|
getAutoEmbeddingSessionCoverage2
|
|
670
|
-
} from "./index-
|
|
674
|
+
} from "./index-nwbhe6qv.js";
|
|
671
675
|
import {
|
|
672
676
|
rememberV1HiddenRun
|
|
673
677
|
} from "./index-6x556c2q.js";
|
|
@@ -732,7 +736,7 @@ import {
|
|
|
732
736
|
normalizeVerificationFiles,
|
|
733
737
|
indexCommitsForProject,
|
|
734
738
|
embedUnembeddedCommits
|
|
735
|
-
} from "./index-
|
|
739
|
+
} from "./index-wp9q91kn.js";
|
|
736
740
|
import {
|
|
737
741
|
setEmbeddingSessionBusy2,
|
|
738
742
|
isEmbeddingHostBusy2
|
|
@@ -763,18 +767,19 @@ import {
|
|
|
763
767
|
import {
|
|
764
768
|
pushNotification2
|
|
765
769
|
} from "./index-q1yc6bs0.js";
|
|
766
|
-
import"./index-
|
|
770
|
+
import"./index-9jvktm7k.js";
|
|
767
771
|
import {
|
|
768
772
|
cosineSimilarity
|
|
769
|
-
} from "./index-
|
|
773
|
+
} from "./index-7wagp5jp.js";
|
|
770
774
|
import"./index-46q4e104.js";
|
|
771
775
|
import {
|
|
776
|
+
DREAMER_PRIMER_INVESTIGATOR_ALLOWED_TOOLS,
|
|
772
777
|
buildHiddenAgentRegistrations,
|
|
773
778
|
logTemperatureDecision,
|
|
774
779
|
subagentStepCap,
|
|
775
780
|
SubagentTelemetry,
|
|
776
781
|
readHostSystemPrompt
|
|
777
|
-
} from "./index-
|
|
782
|
+
} from "./index-y29y2j2w.js";
|
|
778
783
|
import"./index-f18ec69t.js";
|
|
779
784
|
import {
|
|
780
785
|
__toESM
|
|
@@ -3494,7 +3499,7 @@ function startHostStallProfilerSwitch() {
|
|
|
3494
3499
|
// package.json
|
|
3495
3500
|
var package_default = {
|
|
3496
3501
|
name: "@cortexkit/pi-magic-context",
|
|
3497
|
-
version: "0.49.
|
|
3502
|
+
version: "0.49.13",
|
|
3498
3503
|
type: "module",
|
|
3499
3504
|
description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
|
|
3500
3505
|
main: "dist/index.js",
|
|
@@ -3523,7 +3528,7 @@ var package_default = {
|
|
|
3523
3528
|
],
|
|
3524
3529
|
"//": "The build intentionally bundles typebox (no --external typebox) and keeps it a regular dependency. OMP's extension loader rewrites every bare `typebox` import to its own omptype-based shim, whose schemas are callable objects rather than JSON Schema; they fail structuredClone during tool registration, so an external typebox import stops Magic Context loading on OMP. src/typebox-bundling.test.ts guards this.",
|
|
3525
3530
|
scripts: {
|
|
3526
|
-
build: "bun ../../scripts/check-bun.mjs && tsc -p ../retina-local-fs/tsconfig.build.json && bun ../../scripts/clean-dist-chunks.mjs dist index.js subagent-entry.js historian-calibration-extension.js embedding-worker-process.js raw-ordinal-warmup-worker.js transformers-web.js transformers-node-wasm.js && bun build ../plugin/src/features/magic-context/memory/transformers-web-entry.ts --outfile dist/transformers-web.js --target browser --format esm --external onnxruntime-web && bun ../plugin/scripts/build-transformers-node-wasm.ts dist && bun build src/index.ts src/subagent-entry.ts src/historian-calibration-extension.ts ../plugin/src/features/magic-context/memory/embedding-worker.ts ../plugin/src/features/magic-context/memory/embedding-worker-process.ts ../plugin/src/features/magic-context/migration-worker.ts ../plugin/src/hooks/magic-context/auto-search-worker.ts ../plugin/src/hooks/magic-context/raw-ordinal-warmup-worker.ts ../plugin/src/features/magic-context/compaction-marker-candidates-worker.ts --outdir dist --entry-naming '[name].[ext]' --target node --format esm --splitting --external @earendil-works/pi-coding-agent --external @oh-my-pi/pi-coding-agent --external @earendil-works/pi-tui --external onnxruntime-node --external onnxruntime-web --external sharp --external bun:ffi --external node:sqlite",
|
|
3531
|
+
build: "bun ../../scripts/check-bun.mjs && tsc -p ../retina-local-fs/tsconfig.build.json && bun ../../scripts/clean-dist-chunks.mjs dist index.js subagent-entry.js historian-calibration-extension.js embedding-worker-process.js raw-ordinal-warmup-worker.js transformers-web.js transformers-node-wasm.js && bun build ../plugin/src/features/magic-context/memory/transformers-web-entry.ts --outfile dist/transformers-web.js --target browser --format esm --external onnxruntime-web && bun ../plugin/scripts/build-transformers-node-wasm.ts dist && bun build src/index.ts src/subagent-entry.ts src/historian-calibration-extension.ts ../plugin/src/features/magic-context/memory/embedding-worker.ts ../plugin/src/features/magic-context/memory/embedding-worker-process.ts ../plugin/src/features/magic-context/migration-worker.ts ../plugin/src/hooks/magic-context/auto-search-worker.ts ../plugin/src/hooks/magic-context/raw-ordinal-warmup-worker.ts ../plugin/src/features/magic-context/compaction-marker-candidates-worker.ts ../plugin/src/features/magic-context/chunk-embedding-write-worker.ts --outdir dist --entry-naming '[name].[ext]' --target node --format esm --splitting --external @earendil-works/pi-coding-agent --external @oh-my-pi/pi-coding-agent --external @earendil-works/pi-tui --external onnxruntime-node --external onnxruntime-web --external sharp --external bun:ffi --external node:sqlite",
|
|
3527
3532
|
"build:e2e-argv": `bun ../../scripts/clean-dist-chunks.mjs ../../tests/docker/.generated subagent-runner-e2e.mjs && bun build src/subagent-runner.ts --outdir ../../tests/docker/.generated --entry-naming 'subagent-runner-e2e.mjs' --splitting --target node --format esm --external node:sqlite && node --input-type=module -e 'const { __test } = await import("../../tests/docker/.generated/subagent-runner-e2e.mjs"); if (typeof __test.buildArgs !== "function" || typeof __test.resolvePiInvocation !== "function") throw new Error("argv renderer exports missing"); console.log("Node argv renderer: 2 exports loaded")'`,
|
|
3528
3533
|
typecheck: "tsc -p ../retina-local-fs/tsconfig.build.json && tsc --noEmit",
|
|
3529
3534
|
test: "bun ../../scripts/check-bun.mjs && bun install --frozen-lockfile && BUN_JSC_useOMGJIT=0 bun test --parallel=4 --timeout 30000",
|
|
@@ -4425,6 +4430,14 @@ var DREAMER_AGENT = "dreamer";
|
|
|
4425
4430
|
var DREAMER_RETROSPECTIVE_AGENT = "dreamer-retrospective";
|
|
4426
4431
|
var DREAMER_PRIMER_INVESTIGATOR_AGENT = "dreamer-primer-investigator";
|
|
4427
4432
|
var DREAMER_MEMORY_MAPPER_AGENT = "dreamer-memory-mapper";
|
|
4433
|
+
var DREAMER_MEMORY_MAPPER_ALLOWED_TOOLS = [
|
|
4434
|
+
"read",
|
|
4435
|
+
"grep",
|
|
4436
|
+
"glob",
|
|
4437
|
+
"aft_outline",
|
|
4438
|
+
"aft_zoom",
|
|
4439
|
+
"aft_search"
|
|
4440
|
+
];
|
|
4428
4441
|
var DREAMER_CLASSIFIER_AGENT = "dreamer-classifier";
|
|
4429
4442
|
var DREAMER_DOCS_AGENT = "dreamer-docs";
|
|
4430
4443
|
var DREAMER_REVIEWER_AGENT = "dreamer-reviewer";
|
|
@@ -4654,13 +4667,12 @@ function providerOutputFailureFromInvalidManifest(messages, responseText, now =
|
|
|
4654
4667
|
var HIDDEN_HISTORIAN_AGENT = "historian";
|
|
4655
4668
|
var HIDDEN_DREAMER_AGENT = "dreamer-classifier";
|
|
4656
4669
|
var HIDDEN_CURATE_AGENT = DREAMER_AGENT;
|
|
4657
|
-
var READ_TOOLS = ["read", "grep", "glob"];
|
|
4658
4670
|
var AGENT_TOOLS = {
|
|
4659
4671
|
[HIDDEN_HISTORIAN_AGENT]: [],
|
|
4660
4672
|
[HIDDEN_DREAMER_AGENT]: [],
|
|
4661
4673
|
[HIDDEN_CURATE_AGENT]: ["ctx_memory"],
|
|
4662
|
-
[DREAMER_MEMORY_MAPPER_AGENT]:
|
|
4663
|
-
[DREAMER_PRIMER_INVESTIGATOR_AGENT]:
|
|
4674
|
+
[DREAMER_MEMORY_MAPPER_AGENT]: DREAMER_MEMORY_MAPPER_ALLOWED_TOOLS,
|
|
4675
|
+
[DREAMER_PRIMER_INVESTIGATOR_AGENT]: DREAMER_PRIMER_INVESTIGATOR_ALLOWED_TOOLS,
|
|
4664
4676
|
[DREAMER_RETROSPECTIVE_AGENT]: ["ctx_search"]
|
|
4665
4677
|
};
|
|
4666
4678
|
var AGENT_STEPS = {
|
|
@@ -4867,6 +4879,21 @@ function externalAbortMessage(signal) {
|
|
|
4867
4879
|
const reason = signal.reason;
|
|
4868
4880
|
return `prompt aborted by external signal${reason instanceof Error && /^lease_(?:lost|expired):/.test(reason.message) ? `: ${reason.message}` : ""}`;
|
|
4869
4881
|
}
|
|
4882
|
+
function raceWithSignal(work, signal) {
|
|
4883
|
+
work = Promise.resolve(work);
|
|
4884
|
+
if (!signal)
|
|
4885
|
+
return work;
|
|
4886
|
+
return new Promise((resolve, reject) => {
|
|
4887
|
+
const abort = () => reject(new Error(externalAbortMessage(signal)));
|
|
4888
|
+
if (signal.aborted) {
|
|
4889
|
+
work.catch(() => {});
|
|
4890
|
+
abort();
|
|
4891
|
+
return;
|
|
4892
|
+
}
|
|
4893
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
4894
|
+
work.then(resolve, reject).finally(() => signal.removeEventListener("abort", abort));
|
|
4895
|
+
});
|
|
4896
|
+
}
|
|
4870
4897
|
async function promptWithTimeout(client, args, timeoutMs, signal, transport) {
|
|
4871
4898
|
if (signal?.aborted) {
|
|
4872
4899
|
throw new Error(externalAbortMessage(signal));
|
|
@@ -4878,11 +4905,11 @@ async function promptWithTimeout(client, args, timeoutMs, signal, transport) {
|
|
|
4878
4905
|
try {
|
|
4879
4906
|
const request = { ...args, signal: controller.signal };
|
|
4880
4907
|
if (transport)
|
|
4881
|
-
await transport(request);
|
|
4908
|
+
await raceWithSignal(transport(request), controller.signal);
|
|
4882
4909
|
else {
|
|
4883
4910
|
if (!client)
|
|
4884
4911
|
throw new Error("Hidden completion transport is unavailable");
|
|
4885
|
-
await client.session.prompt(request);
|
|
4912
|
+
await raceWithSignal(client.session.prompt(request), controller.signal);
|
|
4886
4913
|
}
|
|
4887
4914
|
} catch (error) {
|
|
4888
4915
|
if (signal?.aborted) {
|
|
@@ -5084,7 +5111,7 @@ async function attemptAndValidate(client, args, timeoutMs, signal, callContext,
|
|
|
5084
5111
|
}
|
|
5085
5112
|
let output;
|
|
5086
5113
|
try {
|
|
5087
|
-
output = await options.fetchOutput(args, attempt);
|
|
5114
|
+
output = await raceWithSignal(options.fetchOutput(args, attempt), options.signal);
|
|
5088
5115
|
} catch (error) {
|
|
5089
5116
|
throw {
|
|
5090
5117
|
error,
|
|
@@ -5382,10 +5409,20 @@ function createPromptAsyncTransport(client, childSessionId, options = {}) {
|
|
|
5382
5409
|
if (!readChildTokenBudget || !session?.prompt)
|
|
5383
5410
|
return;
|
|
5384
5411
|
return Object.assign(async (request) => {
|
|
5385
|
-
|
|
5386
|
-
const
|
|
5387
|
-
if (
|
|
5388
|
-
|
|
5412
|
+
const previous = readChildTokenBudget(childSessionId);
|
|
5413
|
+
const remaining = options.tokenBudget === undefined ? undefined : options.tokenBudget - (previous?.spent ?? 0);
|
|
5414
|
+
if (remaining !== undefined && remaining <= 0 || previous?.finalizeFired)
|
|
5415
|
+
throw new DreamTokenBudgetExceeded(childSessionId, previous?.spent ?? 0);
|
|
5416
|
+
try {
|
|
5417
|
+
await session.prompt?.({
|
|
5418
|
+
...request,
|
|
5419
|
+
...remaining === undefined ? {} : { tokenBudget: remaining }
|
|
5420
|
+
});
|
|
5421
|
+
} finally {
|
|
5422
|
+
const state = readChildTokenBudget(childSessionId);
|
|
5423
|
+
if (state)
|
|
5424
|
+
options.onBudgetUpdate?.({ ...state, sessionId: childSessionId });
|
|
5425
|
+
}
|
|
5389
5426
|
}, { childSessionId });
|
|
5390
5427
|
}
|
|
5391
5428
|
const budgetGuard = options.tokenBudget ? createDreamTokenBudget(options.tokenBudget) : undefined;
|
|
@@ -10117,9 +10154,12 @@ async function runCompressCues(args) {
|
|
|
10117
10154
|
let timeoutStreakElapsedMs = [];
|
|
10118
10155
|
for (let i = 0;i < chunks.length; i += 1) {
|
|
10119
10156
|
const remainingMs = Math.max(0, args.deadline - Date.now());
|
|
10120
|
-
if (remainingMs <= 0)
|
|
10157
|
+
if (remainingMs <= 0) {
|
|
10158
|
+
result.stopReason = "deadline";
|
|
10121
10159
|
break;
|
|
10160
|
+
}
|
|
10122
10161
|
if (remainingMs < CHUNK_TIMEOUT_FLOOR_MS) {
|
|
10162
|
+
result.stopReason = "deadline";
|
|
10123
10163
|
log2(`[dreamer] compress-cues: stopping before chunk ${i + 1}/${chunks.length} — remaining budget ${remainingMs}ms is below the ${CHUNK_TIMEOUT_FLOOR_MS}ms chunk floor; banking ${result.compressed} compressed cue(s)`);
|
|
10124
10164
|
break;
|
|
10125
10165
|
}
|
|
@@ -10128,6 +10168,10 @@ async function runCompressCues(args) {
|
|
|
10128
10168
|
if (!chunk)
|
|
10129
10169
|
break;
|
|
10130
10170
|
const outcome = await compressOneChunk(args, chunk, sliceMs, abortController.signal);
|
|
10171
|
+
if (outcome.failure) {
|
|
10172
|
+
result.failure = outcome.failure.error;
|
|
10173
|
+
result.failureStage = outcome.failure.stage;
|
|
10174
|
+
}
|
|
10131
10175
|
result.compressed += outcome.compressed;
|
|
10132
10176
|
result.skipped += outcome.skipped;
|
|
10133
10177
|
result.remaining -= outcome.compressed;
|
|
@@ -10137,6 +10181,7 @@ async function runCompressCues(args) {
|
|
|
10137
10181
|
consecutiveTimeouts += 1;
|
|
10138
10182
|
timeoutStreakElapsedMs.push(outcome.failure.elapsedMs);
|
|
10139
10183
|
if (consecutiveTimeouts >= CONSECUTIVE_TIMEOUT_LIMIT) {
|
|
10184
|
+
result.stopReason = "timeout-circuit-breaker";
|
|
10140
10185
|
log2(`[dreamer] compress-cues: circuit breaker tripped — ${consecutiveTimeouts} consecutive chunk timeouts (model too slow for its time slice); per-chunk elapsed [${timeoutStreakElapsedMs.join("ms, ")}ms] vs ${sliceMs}ms slice; stopping run incomplete with ${chunks.length - i - 1} chunk(s) unattempted`);
|
|
10141
10186
|
break;
|
|
10142
10187
|
}
|
|
@@ -10153,7 +10198,7 @@ async function runCompressCues(args) {
|
|
|
10153
10198
|
}
|
|
10154
10199
|
}
|
|
10155
10200
|
function isTimeoutClassError(error) {
|
|
10156
|
-
return error
|
|
10201
|
+
return isPromptTimeoutError(error) || getPromptFailureDetail(error)?.failureClass === "provider_timeout";
|
|
10157
10202
|
}
|
|
10158
10203
|
async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
10159
10204
|
let agentSessionId = null;
|
|
@@ -10161,6 +10206,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
10161
10206
|
const executor = resolveHiddenCompletionExecutor(args.hiddenCompletionExecutor, args.client, args.db, args.sessionDirectory, "compress-cues");
|
|
10162
10207
|
let promptSettled = false;
|
|
10163
10208
|
const startedAt = Date.now();
|
|
10209
|
+
let stage = "child-start";
|
|
10164
10210
|
try {
|
|
10165
10211
|
const prompt = buildCompressCuesPrompt({
|
|
10166
10212
|
projectPath: args.projectIdentity,
|
|
@@ -10181,6 +10227,7 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
10181
10227
|
agentSessionId = handle.id || null;
|
|
10182
10228
|
if (!agentSessionId)
|
|
10183
10229
|
throw new Error("Could not create compress-cues session.");
|
|
10230
|
+
stage = "prompt";
|
|
10184
10231
|
const opened = handle;
|
|
10185
10232
|
const run = await promptSyncWithValidatedOutputRetry(args.client, {
|
|
10186
10233
|
path: { id: agentSessionId },
|
|
@@ -10232,16 +10279,19 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
|
|
|
10232
10279
|
modelId: run.output.modelId
|
|
10233
10280
|
});
|
|
10234
10281
|
}
|
|
10282
|
+
stage = "apply";
|
|
10235
10283
|
return args.moduleRoute ? await applyCuesThroughModule(args, chunk, run.validated, signal) : applyCues(args, chunk, run.validated);
|
|
10236
10284
|
} catch (error) {
|
|
10237
10285
|
const desc = describeError(error);
|
|
10238
10286
|
log2(`[dreamer] compress-cues chunk failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
10239
|
-
if (signal.aborted || error instanceof HiddenCompletionRefusal || error instanceof DreamerProviderOutputFailureError)
|
|
10287
|
+
if (signal.aborted || error instanceof DreamerModuleFailureError || error instanceof HiddenCompletionRefusal || error instanceof DreamerProviderOutputFailureError)
|
|
10240
10288
|
throw error;
|
|
10241
10289
|
return {
|
|
10242
10290
|
compressed: 0,
|
|
10243
10291
|
skipped: 0,
|
|
10244
10292
|
failure: {
|
|
10293
|
+
error,
|
|
10294
|
+
stage,
|
|
10245
10295
|
class: isTimeoutClassError(error) ? "timeout" : "other",
|
|
10246
10296
|
brief: desc.brief,
|
|
10247
10297
|
elapsedMs: Date.now() - startedAt
|
|
@@ -10395,7 +10445,7 @@ async function applyCuesThroughModule(args, chunk, manifestText, signal) {
|
|
|
10395
10445
|
// ../plugin/src/features/magic-context/dreamer/hidden-single-shot.ts
|
|
10396
10446
|
async function runHiddenSingleShotPrompt(args) {
|
|
10397
10447
|
const system = withContentLanguageDirective(args.system, args.language);
|
|
10398
|
-
const
|
|
10448
|
+
const opening = args.executor.open({
|
|
10399
10449
|
parentSessionId: args.parentSessionId,
|
|
10400
10450
|
agent: args.agent,
|
|
10401
10451
|
kind: "dreamer-task",
|
|
@@ -10407,6 +10457,17 @@ async function runHiddenSingleShotPrompt(args) {
|
|
|
10407
10457
|
directory: args.sessionDirectory,
|
|
10408
10458
|
...args.metadata ? { metadata: args.metadata } : {}
|
|
10409
10459
|
});
|
|
10460
|
+
opening.then((handle) => {
|
|
10461
|
+
if (args.signal?.aborted)
|
|
10462
|
+
return args.executor.close(handle, {
|
|
10463
|
+
promptSettled: false,
|
|
10464
|
+
privacySensitive: args.privacySensitive ?? true,
|
|
10465
|
+
context: `[dreamer] ${args.callContext}`,
|
|
10466
|
+
log: log2
|
|
10467
|
+
});
|
|
10468
|
+
}).catch(() => {});
|
|
10469
|
+
const handle = await raceWithSignal(opening, args.signal);
|
|
10470
|
+
args.onOpened?.(handle.id);
|
|
10410
10471
|
let promptSettled = false;
|
|
10411
10472
|
try {
|
|
10412
10473
|
if (!handle.id)
|
|
@@ -10461,12 +10522,16 @@ async function runHiddenSingleShotPrompt(args) {
|
|
|
10461
10522
|
}
|
|
10462
10523
|
throw error;
|
|
10463
10524
|
} finally {
|
|
10464
|
-
|
|
10525
|
+
const close = args.executor.close(handle, {
|
|
10465
10526
|
promptSettled,
|
|
10466
10527
|
privacySensitive: args.privacySensitive ?? true,
|
|
10467
10528
|
context: `[dreamer] ${args.callContext}`,
|
|
10468
10529
|
log: log2
|
|
10469
10530
|
});
|
|
10531
|
+
if (args.signal?.aborted)
|
|
10532
|
+
close.catch(() => {});
|
|
10533
|
+
else
|
|
10534
|
+
await raceWithSignal(close, args.signal);
|
|
10470
10535
|
}
|
|
10471
10536
|
}
|
|
10472
10537
|
|
|
@@ -12628,7 +12693,7 @@ function getAsyncModule() {
|
|
|
12628
12693
|
await beforeModuleLoad();
|
|
12629
12694
|
const [{ default: singlefileAsyncifyVariant }, { newQuickJSAsyncWASMModuleFromVariant }] = await importPluginModule(() => Promise.all([
|
|
12630
12695
|
import("./index-e7vx3byk.js").then((m)=>__toESM(m.default,1)),
|
|
12631
|
-
import("./index-
|
|
12696
|
+
import("./index-e6xnpach.js")
|
|
12632
12697
|
]));
|
|
12633
12698
|
const module = await newQuickJSAsyncWASMModuleFromVariant(singlefileAsyncifyVariant);
|
|
12634
12699
|
return module;
|
|
@@ -14294,14 +14359,28 @@ function isDeferred(memory, retries) {
|
|
|
14294
14359
|
return !!retry && retry.content === contentKey(memory) && retry.deferUntil > Date.now();
|
|
14295
14360
|
}
|
|
14296
14361
|
function assistantText(messages) {
|
|
14297
|
-
|
|
14362
|
+
const joined = messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).map((message) => extractLatestAssistantText([message]) ?? (isRecord(message) && Array.isArray(message.content) ? message.content.filter(isRecord).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join(`
|
|
14298
14363
|
`) : "")).join(`
|
|
14299
14364
|
`);
|
|
14365
|
+
return joined.trim() ? joined : null;
|
|
14300
14366
|
}
|
|
14301
14367
|
function currentManifest(text) {
|
|
14302
14368
|
const start = text.lastIndexOf("<mappings>");
|
|
14303
14369
|
return start < 0 ? text : text.slice(start);
|
|
14304
14370
|
}
|
|
14371
|
+
function parseMapMemoriesCompletion(text, completion, expectedIds) {
|
|
14372
|
+
return validateMapMemoriesManifest(currentManifest(assistantText(completion.messages ?? []) || text), expectedIds);
|
|
14373
|
+
}
|
|
14374
|
+
function validateClientMapMemories(messages, expectedIds) {
|
|
14375
|
+
if (hasLengthCappedOutput(messages)) {
|
|
14376
|
+
throw new Error("map-memories returned length-capped output");
|
|
14377
|
+
}
|
|
14378
|
+
const raw = assistantText(messages);
|
|
14379
|
+
if (raw == null) {
|
|
14380
|
+
throw new Error("map-memories returned no output");
|
|
14381
|
+
}
|
|
14382
|
+
return validateMapMemoriesManifest(currentManifest(raw), expectedIds);
|
|
14383
|
+
}
|
|
14305
14384
|
function logBatchUsage(messages, committed, startedAt) {
|
|
14306
14385
|
const steps = messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).length;
|
|
14307
14386
|
log2(`[dreamer] map-memories batch: steps=${steps} committed=${committed} steps_per_memory=${committed ? (steps / committed).toFixed(2) : "n/a"} elapsed_ms=${Date.now() - startedAt}`);
|
|
@@ -14366,8 +14445,11 @@ async function mapMemories(args) {
|
|
|
14366
14445
|
const inputs = allInputs.filter((memory) => !isDeferred(memory, retries));
|
|
14367
14446
|
result.remaining = allInputs.length;
|
|
14368
14447
|
result.complete = result.remaining === 0;
|
|
14369
|
-
if (inputs.length === 0)
|
|
14448
|
+
if (inputs.length === 0) {
|
|
14449
|
+
if (allInputs.length > 0)
|
|
14450
|
+
result.deferred = true;
|
|
14370
14451
|
return result;
|
|
14452
|
+
}
|
|
14371
14453
|
const batches = [];
|
|
14372
14454
|
for (let i = 0;i < inputs.length; i += MAP_BATCH_SIZE) {
|
|
14373
14455
|
batches.push({ inputs: inputs.slice(i, i + MAP_BATCH_SIZE), isOmissionRetry: false });
|
|
@@ -14393,6 +14475,10 @@ async function mapMemories(args) {
|
|
|
14393
14475
|
if (!batch)
|
|
14394
14476
|
break;
|
|
14395
14477
|
const outcome = await mapOneBatch(args, batch.inputs, sliceMs, abortController.signal);
|
|
14478
|
+
if (outcome.failure) {
|
|
14479
|
+
result.failure = outcome.failure.error;
|
|
14480
|
+
result.failureStage = outcome.failure.stage;
|
|
14481
|
+
}
|
|
14396
14482
|
const committed = outcome.mapped + outcome.independent;
|
|
14397
14483
|
runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
|
|
14398
14484
|
const committedIds = new Set(outcome.committedIds);
|
|
@@ -14456,6 +14542,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
14456
14542
|
const startedAt = Date.now();
|
|
14457
14543
|
let budgetFinalized = false;
|
|
14458
14544
|
let failedCompletion;
|
|
14545
|
+
let stage = "child-start";
|
|
14459
14546
|
const onBudgetUpdate = (state) => {
|
|
14460
14547
|
budgetFinalized ||= state.finalizeFired;
|
|
14461
14548
|
args.onBudgetUpdate?.(state);
|
|
@@ -14477,15 +14564,19 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
14477
14564
|
fallbackModels: args.fallbackModels,
|
|
14478
14565
|
timeoutMs: sliceMs,
|
|
14479
14566
|
signal,
|
|
14567
|
+
onOpened: () => {
|
|
14568
|
+
stage = "prompt";
|
|
14569
|
+
},
|
|
14480
14570
|
onFailureOutput: (completion) => {
|
|
14481
14571
|
failedCompletion = completion;
|
|
14482
14572
|
},
|
|
14483
|
-
parse: (text, completion) =>
|
|
14573
|
+
parse: (text, completion) => parseMapMemoriesCompletion(text, completion, new Set(batch.map((memory) => memory.id)))
|
|
14484
14574
|
});
|
|
14485
14575
|
recordInvocation2(args, startedAt, {
|
|
14486
14576
|
status: "completed",
|
|
14487
14577
|
messages: run.completion.messages ?? []
|
|
14488
14578
|
});
|
|
14579
|
+
stage = "apply";
|
|
14489
14580
|
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
|
|
14490
14581
|
logBatchUsage(run.completion.messages ?? [], outcome.mapped + outcome.independent, startedAt);
|
|
14491
14582
|
const returnedIds = new Set(outcome.committedIds);
|
|
@@ -14510,6 +14601,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
14510
14601
|
agentSessionId = typeof created?.id === "string" ? created.id : null;
|
|
14511
14602
|
if (!agentSessionId)
|
|
14512
14603
|
throw new Error("Could not create map-memories session.");
|
|
14604
|
+
stage = "prompt";
|
|
14513
14605
|
const run = await promptSyncWithValidatedOutputRetry(client, {
|
|
14514
14606
|
path: { id: agentSessionId },
|
|
14515
14607
|
query: { directory: args.sessionDirectory },
|
|
@@ -14537,18 +14629,11 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
14537
14629
|
preferResponseOnMissingData: true
|
|
14538
14630
|
});
|
|
14539
14631
|
},
|
|
14540
|
-
validateOutput: (messages) =>
|
|
14541
|
-
if (hasLengthCappedOutput(messages)) {
|
|
14542
|
-
throw new Error("map-memories returned length-capped output");
|
|
14543
|
-
}
|
|
14544
|
-
const text = currentManifest(assistantText(messages));
|
|
14545
|
-
if (!text)
|
|
14546
|
-
throw new Error("map-memories returned no output");
|
|
14547
|
-
return validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
14548
|
-
}
|
|
14632
|
+
validateOutput: (messages) => validateClientMapMemories(messages, new Set(batch.map((memory) => memory.id)))
|
|
14549
14633
|
});
|
|
14550
14634
|
promptSettled = true;
|
|
14551
14635
|
recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
|
|
14636
|
+
stage = "apply";
|
|
14552
14637
|
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
|
|
14553
14638
|
logBatchUsage(run.output, outcome.mapped + outcome.independent, startedAt);
|
|
14554
14639
|
const returnedIds = new Set(outcome.committedIds);
|
|
@@ -14577,6 +14662,8 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
14577
14662
|
return {
|
|
14578
14663
|
...outcome,
|
|
14579
14664
|
failure: {
|
|
14665
|
+
error,
|
|
14666
|
+
stage,
|
|
14580
14667
|
class: isTimeoutClassError2(error) ? "timeout" : "other",
|
|
14581
14668
|
elapsedMs: Date.now() - startedAt
|
|
14582
14669
|
}
|
|
@@ -15701,10 +15788,28 @@ async function readRetrospectiveScanWindow(provider, projectIdentity, watermarkM
|
|
|
15701
15788
|
}
|
|
15702
15789
|
function readOpenCodeMessagesSince(db, sessionId, sinceMs, capPerSession) {
|
|
15703
15790
|
const limit = Math.max(1, Math.floor(capPerSession));
|
|
15704
|
-
const rows = db.prepare(`SELECT id, data, time_created
|
|
15705
|
-
|
|
15706
|
-
|
|
15707
|
-
|
|
15791
|
+
const rows = db.prepare(`SELECT current.id, current.data, current.time_created,
|
|
15792
|
+
EXISTS (
|
|
15793
|
+
SELECT 1 FROM message assistant_reply
|
|
15794
|
+
WHERE assistant_reply.session_id = current.session_id
|
|
15795
|
+
AND json_valid(assistant_reply.data)
|
|
15796
|
+
AND json_extract(assistant_reply.data, '$.role') = 'assistant'
|
|
15797
|
+
AND (assistant_reply.time_created < current.time_created
|
|
15798
|
+
OR (assistant_reply.time_created = current.time_created
|
|
15799
|
+
AND assistant_reply.id < current.id))
|
|
15800
|
+
AND EXISTS (
|
|
15801
|
+
SELECT 1 FROM message prior_user
|
|
15802
|
+
WHERE prior_user.session_id = current.session_id
|
|
15803
|
+
AND json_valid(prior_user.data)
|
|
15804
|
+
AND json_extract(prior_user.data, '$.role') = 'user'
|
|
15805
|
+
AND (prior_user.time_created < assistant_reply.time_created
|
|
15806
|
+
OR (prior_user.time_created = assistant_reply.time_created
|
|
15807
|
+
AND prior_user.id < assistant_reply.id))
|
|
15808
|
+
)
|
|
15809
|
+
) AS has_prior_assistant_reply
|
|
15810
|
+
FROM message current
|
|
15811
|
+
WHERE current.session_id = ? AND current.time_created > ?
|
|
15812
|
+
ORDER BY current.time_created ASC, current.id ASC
|
|
15708
15813
|
LIMIT ?`).all(sessionId, sinceMs, limit + 1);
|
|
15709
15814
|
const truncated = rows.length > limit;
|
|
15710
15815
|
const kept = truncated ? rows.slice(0, limit) : rows;
|
|
@@ -15808,7 +15913,8 @@ function normalizeOpenCodeRows(db, sessionId, rows) {
|
|
|
15808
15913
|
ordinal,
|
|
15809
15914
|
role,
|
|
15810
15915
|
parts,
|
|
15811
|
-
ts: row.time_created
|
|
15916
|
+
ts: row.time_created,
|
|
15917
|
+
followsAssistantReply: row.has_prior_assistant_reply === 1
|
|
15812
15918
|
});
|
|
15813
15919
|
});
|
|
15814
15920
|
}
|
|
@@ -15822,7 +15928,8 @@ function normalizeOpenCodeMessage(args) {
|
|
|
15822
15928
|
ordinal: args.ordinal,
|
|
15823
15929
|
role: "user",
|
|
15824
15930
|
text,
|
|
15825
|
-
ts: args.ts
|
|
15931
|
+
ts: args.ts,
|
|
15932
|
+
...args.followsAssistantReply ? { followsAssistantReply: true } : {}
|
|
15826
15933
|
});
|
|
15827
15934
|
}
|
|
15828
15935
|
}
|
|
@@ -16193,7 +16300,7 @@ var VERIFY_SYSTEM_PROMPT = `You are a memory verifier for the magic-context syst
|
|
|
16193
16300
|
|
|
16194
16301
|
Each memory below comes with its backing file(s) — the code it makes a claim about. For EACH memory: use the provided git diff as evidence when present. If no diff is supplied, read its backing files (you may read more if needed) and decide whether the memory is still accurate.
|
|
16195
16302
|
|
|
16196
|
-
Tools (read-only): read, grep, glob. Request line ranges
|
|
16303
|
+
Tools (read-only): read, grep, glob, plus any available AFT navigation tools. Use at most 3 tool calls per memory, including searches and reads. Start with the backing files and likely identifier matches. Never read the same file twice in a batch; reuse evidence. Request short useful line ranges unless the claim concerns the file as a whole. If evidence is insufficient when the call budget runs out, SKIP that memory; uncertainty never justifies archival. You change nothing.
|
|
16197
16304
|
|
|
16198
16305
|
Decide ONE of four outcomes per memory:
|
|
16199
16306
|
- VERIFIED — still accurate. Keep it as-is.
|
|
@@ -16205,7 +16312,7 @@ UPDATE and ARCHIVE are ONLY for claims a repository file can falsify, such as an
|
|
|
16205
16312
|
|
|
16206
16313
|
BE CONSERVATIVE ABOUT ARCHIVING. Wrong archival of a TRUE memory is the worst possible outcome — far worse than leaving a slightly-stale memory. If you cannot find the code, or you are unsure, or it might still be true somewhere you didn't look: mark it VERIFIED or SKIPPED, never archived. Archive ONLY when you have positive evidence the code contradicts a code fact.
|
|
16207
16314
|
|
|
16208
|
-
Output ONE XML manifest
|
|
16315
|
+
Output ONE XML manifest and NOTHING else — no narration or reasoning. Open <verify> before investigating and emit each complete verdict immediately before investigating the next memory, so interruption preserves finished work. Close </verify> when done:
|
|
16209
16316
|
<verify>
|
|
16210
16317
|
<verified id="N" files="path/a.ts,path/b.ts"/>
|
|
16211
16318
|
<update id="M" files="path/c.ts">corrected present-tense content</update>
|
|
@@ -16218,17 +16325,24 @@ Rules:
|
|
|
16218
16325
|
- Every input memory id MUST appear exactly once, in exactly one of verified/update/archive/skip.
|
|
16219
16326
|
- files = the COMPLETE current backing set (repo-relative, comma-separated). It may differ from the given mapping if a file moved — record what you actually verified against.
|
|
16220
16327
|
- Default to VERIFIED. skip when code cannot decide the claim. update and archive are the exceptions, not the norm.`;
|
|
16328
|
+
async function seedVerifyCandidates(memories, directory) {
|
|
16329
|
+
const seeded = await seedIdentifierCandidates(memories.map((m) => ({ ...m, candidates: [] })), directory);
|
|
16330
|
+
return memories.map((m, i) => ({ ...m, candidates: seeded[i].candidates }));
|
|
16331
|
+
}
|
|
16221
16332
|
function buildVerifyPrompt(projectPath, memories, evidence) {
|
|
16222
16333
|
const list = memories.map((m) => `[${m.id}] ${m.category}
|
|
16223
16334
|
Content: ${m.content}
|
|
16224
|
-
Backing files: ${m.mappedFiles.join(", ")}
|
|
16335
|
+
Backing files: ${m.mappedFiles.join(", ")}${m.candidates?.length ? `
|
|
16336
|
+
Likely files (identifier matches, confirm before using): ${m.candidates.join(", ")}` : ""}`).join(`
|
|
16225
16337
|
|
|
16226
16338
|
`);
|
|
16227
16339
|
return `## Verify these memories against the code
|
|
16228
16340
|
|
|
16229
16341
|
Project: ${projectPath}
|
|
16230
16342
|
|
|
16231
|
-
|
|
16343
|
+
When available in this session, use aft_outline to outline the backing file and aft_zoom on the claimed symbol (or aft_search to locate it), instead of paging through whole files. Read a whole file only when the claim is about the file as a whole. Otherwise use the available read-only tools.
|
|
16344
|
+
|
|
16345
|
+
${evidence ? "The git diff below is the evidence. If changed hunks do not touch a claim, mark it verified without opening files. Open files only when a diff suggests the claim may have changed. A rename or deletion requires an update or archive when positively supported; do not archive on uncertainty." : "Check each memory's claim against its backing files."} Decide verified / update / archive / skip (default verified; behavioral directives only permit verified or skip), then output ONE <verify> manifest covering every id.
|
|
16232
16346
|
|
|
16233
16347
|
<memories>
|
|
16234
16348
|
${list}
|
|
@@ -16305,13 +16419,57 @@ function validateVerifyManifest(text, expectedIds) {
|
|
|
16305
16419
|
assertNoDuplicateManifestIds(ids.filter((id) => expectedIds.has(id)), "verify");
|
|
16306
16420
|
return parsed;
|
|
16307
16421
|
}
|
|
16422
|
+
function parsePartialVerifyManifest(text, expectedIds) {
|
|
16423
|
+
const out = { verified: [], updated: [], archived: [], skipped: [] };
|
|
16424
|
+
const start = text.lastIndexOf("<verify>");
|
|
16425
|
+
if (start < 0)
|
|
16426
|
+
return out;
|
|
16427
|
+
const entries = new Map;
|
|
16428
|
+
const conflicts = new Set;
|
|
16429
|
+
for (const match of text.slice(start).matchAll(/<(?:verified|archive|skip)\b[^<>]*\/>|<update\b[^<>]*>[\s\S]*?<\/update>/g)) {
|
|
16430
|
+
try {
|
|
16431
|
+
const parsed = parseVerifyManifest(`<verify>${match[0]}</verify>`);
|
|
16432
|
+
const id = verifyIds(parsed)[0];
|
|
16433
|
+
if (!expectedIds.has(id) || conflicts.has(id))
|
|
16434
|
+
continue;
|
|
16435
|
+
const previous = entries.get(id);
|
|
16436
|
+
if (previous && JSON.stringify(previous) !== JSON.stringify(parsed)) {
|
|
16437
|
+
entries.delete(id);
|
|
16438
|
+
conflicts.add(id);
|
|
16439
|
+
} else
|
|
16440
|
+
entries.set(id, parsed);
|
|
16441
|
+
} catch {}
|
|
16442
|
+
}
|
|
16443
|
+
for (const parsed of entries.values()) {
|
|
16444
|
+
out.verified.push(...parsed.verified);
|
|
16445
|
+
out.updated.push(...parsed.updated);
|
|
16446
|
+
out.archived.push(...parsed.archived);
|
|
16447
|
+
out.skipped.push(...parsed.skipped);
|
|
16448
|
+
}
|
|
16449
|
+
return out;
|
|
16450
|
+
}
|
|
16308
16451
|
|
|
16309
16452
|
// ../plugin/src/features/magic-context/dreamer/verify.ts
|
|
16310
|
-
var VERIFY_BATCH_SIZE =
|
|
16453
|
+
var VERIFY_BATCH_SIZE = 5;
|
|
16454
|
+
var VERIFY_TOKENS_PER_MEMORY = 1e5;
|
|
16455
|
+
var VERIFY_RUN_TOKEN_BUDGET = 2500000;
|
|
16456
|
+
var VERIFY_RUN_SLICE_MS = 240000;
|
|
16457
|
+
function verifyBatchTokenBudget(size, configured) {
|
|
16458
|
+
return Math.min(configured ?? Number.MAX_SAFE_INTEGER, size * VERIFY_TOKENS_PER_MEMORY);
|
|
16459
|
+
}
|
|
16460
|
+
function verifyAssistantText(messages) {
|
|
16461
|
+
const text = messages.filter((m) => isRecord(m) && (m.role === "assistant" || isRecord(m.info) && m.info.role === "assistant")).map((m) => extractLatestAssistantText([m]) || (isRecord(m) && Array.isArray(m.content) ? m.content.filter(isRecord).filter((p) => p.type === "text").map((p) => p.text).join(`
|
|
16462
|
+
`) : "")).join(`
|
|
16463
|
+
`);
|
|
16464
|
+
if (!text.trim())
|
|
16465
|
+
return null;
|
|
16466
|
+
const start = text.lastIndexOf("<verify>");
|
|
16467
|
+
return start >= 0 ? text.slice(start) : text;
|
|
16468
|
+
}
|
|
16311
16469
|
var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
|
|
16312
|
-
var VERIFY_BATCH_FLOOR_MS =
|
|
16313
|
-
function computeVerifyBatchSliceMs(remainingMs,
|
|
16314
|
-
return Math.min(remainingMs,
|
|
16470
|
+
var VERIFY_BATCH_FLOOR_MS = 30000;
|
|
16471
|
+
function computeVerifyBatchSliceMs(remainingMs, _batchesRemaining) {
|
|
16472
|
+
return Math.min(remainingMs, VERIFY_RUN_SLICE_MS);
|
|
16315
16473
|
}
|
|
16316
16474
|
function closeBroadCycle(args, cycleStartAt) {
|
|
16317
16475
|
if (!args.forceBroad || cycleStartAt === undefined)
|
|
@@ -16335,6 +16493,7 @@ async function runVerify(args) {
|
|
|
16335
16493
|
}
|
|
16336
16494
|
async function runVerifyWithCooldown(args) {
|
|
16337
16495
|
const runStartedAt = Date.now();
|
|
16496
|
+
const sliceDeadline = runStartedAt + VERIFY_RUN_SLICE_MS;
|
|
16338
16497
|
const result = {
|
|
16339
16498
|
verified: 0,
|
|
16340
16499
|
updated: 0,
|
|
@@ -16377,16 +16536,31 @@ async function runVerifyWithCooldown(args) {
|
|
|
16377
16536
|
let consecutiveProviderFailures = 0;
|
|
16378
16537
|
let priorProviderFailureFingerprint = null;
|
|
16379
16538
|
let lastProviderFailure = null;
|
|
16539
|
+
let runSpent = 0;
|
|
16540
|
+
const runTokenBudget = Math.min(args.tokenBudget ?? VERIFY_RUN_TOKEN_BUDGET, VERIFY_RUN_TOKEN_BUDGET);
|
|
16380
16541
|
try {
|
|
16381
16542
|
for (let i = 0;i < batches.length; i += 1) {
|
|
16382
|
-
const remainingMs = Math.max(0, args.deadline - Date.now());
|
|
16543
|
+
const remainingMs = Math.max(0, Math.min(args.deadline, sliceDeadline) - Date.now());
|
|
16383
16544
|
if (remainingMs < VERIFY_BATCH_FLOOR_MS) {
|
|
16384
16545
|
result.stopReason = "deadline";
|
|
16385
16546
|
log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: stopping before batch ${i + 1}/${batches.length} — remaining budget ${remainingMs}ms is below the ${VERIFY_BATCH_FLOOR_MS}ms batch floor`);
|
|
16386
16547
|
break;
|
|
16387
16548
|
}
|
|
16388
16549
|
const sliceMs = computeVerifyBatchSliceMs(remainingMs, batches.length - i);
|
|
16389
|
-
|
|
16550
|
+
if (runSpent >= runTokenBudget) {
|
|
16551
|
+
result.stopReason = "token-budget";
|
|
16552
|
+
break;
|
|
16553
|
+
}
|
|
16554
|
+
let batchSpent = 0;
|
|
16555
|
+
const counts = await verifyOneBatch({
|
|
16556
|
+
...args,
|
|
16557
|
+
tokenBudget: runTokenBudget - runSpent,
|
|
16558
|
+
onBudgetUpdate: (state) => {
|
|
16559
|
+
runSpent += Math.max(0, state.spent - batchSpent);
|
|
16560
|
+
batchSpent = Math.max(batchSpent, state.spent);
|
|
16561
|
+
args.onBudgetUpdate?.(state);
|
|
16562
|
+
}
|
|
16563
|
+
}, batches[i], sliceMs, abortController.signal);
|
|
16390
16564
|
result.verified += counts.verified;
|
|
16391
16565
|
result.updated += counts.updated;
|
|
16392
16566
|
result.archived += counts.archived;
|
|
@@ -16396,6 +16570,10 @@ async function runVerifyWithCooldown(args) {
|
|
|
16396
16570
|
result.remaining -= batchProcessed;
|
|
16397
16571
|
result.batches += 1;
|
|
16398
16572
|
args.onProgress?.(result.verified + result.updated + result.archived + result.skipped + result.refused, result.refused);
|
|
16573
|
+
if (counts.tokenLimited) {
|
|
16574
|
+
result.stopReason = "token-budget";
|
|
16575
|
+
break;
|
|
16576
|
+
}
|
|
16399
16577
|
if (counts.timedOut) {
|
|
16400
16578
|
result.stopReason = "batch-timeout";
|
|
16401
16579
|
log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: batch ${i + 1}/${batches.length} timed out after its ${sliceMs}ms slice; stopping with ${result.remaining} remaining`);
|
|
@@ -16430,18 +16608,41 @@ async function runVerifyWithCooldown(args) {
|
|
|
16430
16608
|
}
|
|
16431
16609
|
}
|
|
16432
16610
|
async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
16611
|
+
const batchController = new AbortController;
|
|
16612
|
+
const abort = () => batchController.abort(signal.reason);
|
|
16613
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
16614
|
+
if (signal.aborted)
|
|
16615
|
+
abort();
|
|
16616
|
+
const timer = setTimeout(() => batchController.abort(new Error(`verify slice timed out after ${sliceMs}ms`)), sliceMs);
|
|
16617
|
+
const batchSignal = batchController.signal;
|
|
16618
|
+
const tokenBudget = verifyBatchTokenBudget(batch.length, args.tokenBudget);
|
|
16433
16619
|
let agentSessionId = null;
|
|
16620
|
+
let hiddenSessionId = null;
|
|
16434
16621
|
let promptSettled = false;
|
|
16435
16622
|
const startedAt = Date.now();
|
|
16436
16623
|
let budgetFinalized = false;
|
|
16624
|
+
let failedCompletion;
|
|
16625
|
+
let headAtPrompt = null;
|
|
16437
16626
|
const onBudgetUpdate = (state) => {
|
|
16438
16627
|
budgetFinalized ||= state.finalizeFired;
|
|
16439
|
-
args.onBudgetUpdate?.(
|
|
16628
|
+
args.onBudgetUpdate?.({
|
|
16629
|
+
...state,
|
|
16630
|
+
...hiddenSessionId ? { sessionId: hiddenSessionId } : {}
|
|
16631
|
+
});
|
|
16632
|
+
};
|
|
16633
|
+
const reportUsage = (messages, sessionId, fallbackSpent = 0) => {
|
|
16634
|
+
const usage = sumTokensFromChildMessages(messages);
|
|
16635
|
+
onBudgetUpdate({
|
|
16636
|
+
spent: Math.max(fallbackSpent, usage.input + usage.cacheRead + usage.cacheWrite),
|
|
16637
|
+
finalizeFired: budgetFinalized,
|
|
16638
|
+
...sessionId ? { sessionId } : {}
|
|
16639
|
+
});
|
|
16440
16640
|
};
|
|
16441
16641
|
try {
|
|
16442
|
-
|
|
16443
|
-
const evidence = !args.forceBroad && batch.every((m) => m.verifiedAt) ? await buildVerifyDiffEvidence(args.sessionDirectory, batch) : null;
|
|
16444
|
-
const prompt = buildVerifyPrompt(args.projectIdentity, batch, evidence);
|
|
16642
|
+
headAtPrompt = await raceWithSignal(readGitHead(args.sessionDirectory), batchSignal);
|
|
16643
|
+
const evidence = !args.forceBroad && batch.every((m) => m.verifiedAt) ? await raceWithSignal(buildVerifyDiffEvidence(args.sessionDirectory, batch), batchSignal) : null;
|
|
16644
|
+
const prompt = buildVerifyPrompt(args.projectIdentity, await raceWithSignal(seedVerifyCandidates(batch, args.sessionDirectory), batchSignal), evidence);
|
|
16645
|
+
batchSignal.throwIfAborted();
|
|
16445
16646
|
if (args.hiddenCompletionExecutor) {
|
|
16446
16647
|
const run = await runHiddenSingleShotPrompt({
|
|
16447
16648
|
executor: args.hiddenCompletionExecutor,
|
|
@@ -16452,41 +16653,53 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
16452
16653
|
prompt,
|
|
16453
16654
|
title: "magic-context-dream-verify",
|
|
16454
16655
|
callContext: "dreamer:verify",
|
|
16455
|
-
metadata: { tokenBudget
|
|
16656
|
+
metadata: { tokenBudget, onBudgetUpdate },
|
|
16456
16657
|
model: args.model,
|
|
16457
16658
|
fallbackModels: args.fallbackModels,
|
|
16458
16659
|
language: args.language,
|
|
16459
16660
|
timeoutMs: sliceMs,
|
|
16460
|
-
signal,
|
|
16661
|
+
signal: batchSignal,
|
|
16662
|
+
onFailureOutput: (completion) => {
|
|
16663
|
+
failedCompletion = completion;
|
|
16664
|
+
},
|
|
16665
|
+
onOpened: (sessionId) => {
|
|
16666
|
+
hiddenSessionId = sessionId;
|
|
16667
|
+
onBudgetUpdate({ spent: 0, finalizeFired: false, sessionId });
|
|
16668
|
+
},
|
|
16461
16669
|
parse: (text, completion) => {
|
|
16462
16670
|
const providerFailure = providerOutputFailureFromInvalidManifest(completion.messages ?? [], text);
|
|
16463
16671
|
if (providerFailure)
|
|
16464
16672
|
throw providerFailure;
|
|
16465
|
-
|
|
16673
|
+
const manifest = verifyAssistantText(completion.messages ?? []) ?? (text.trim() ? text : null);
|
|
16674
|
+
if (!manifest)
|
|
16675
|
+
throw new Error("verify returned no output");
|
|
16676
|
+
return validateVerifyManifest(manifest, new Set(batch.map((memory) => memory.id)));
|
|
16466
16677
|
}
|
|
16467
16678
|
});
|
|
16468
16679
|
recordInvocation4(args, startedAt, {
|
|
16469
16680
|
status: "completed",
|
|
16470
16681
|
messages: run.completion.messages ?? []
|
|
16471
16682
|
});
|
|
16472
|
-
|
|
16683
|
+
reportUsage(run.completion.messages ?? [], run.childSessionId, run.completion.usage.input + (run.completion.usage.cacheRead ?? 0) + (run.completion.usage.cacheWrite ?? 0));
|
|
16684
|
+
return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
|
|
16473
16685
|
}
|
|
16474
16686
|
const client = args.client;
|
|
16475
16687
|
if (!client)
|
|
16476
16688
|
throw new Error("verify requires a client or hidden completion executor");
|
|
16477
|
-
const createResponse = await createChildSessionWithFence({
|
|
16689
|
+
const createResponse = await raceWithSignal(createChildSessionWithFence({
|
|
16478
16690
|
client,
|
|
16479
16691
|
db: args.db,
|
|
16480
16692
|
parentSessionId: args.parentSessionId,
|
|
16481
16693
|
title: args.forceBroad ? "magic-context-dream-verify-broad" : "magic-context-dream-verify",
|
|
16482
16694
|
directory: args.sessionDirectory
|
|
16483
|
-
});
|
|
16695
|
+
}), batchSignal);
|
|
16484
16696
|
const created = normalizeSDKResponse(createResponse, null, {
|
|
16485
16697
|
preferResponseOnMissingData: true
|
|
16486
16698
|
});
|
|
16487
16699
|
agentSessionId = typeof created?.id === "string" ? created.id : null;
|
|
16488
16700
|
if (!agentSessionId)
|
|
16489
16701
|
throw new Error("Could not create verify session.");
|
|
16702
|
+
onBudgetUpdate({ spent: 0, finalizeFired: false, sessionId: agentSessionId });
|
|
16490
16703
|
const run = await promptSyncWithValidatedOutputRetry(client, {
|
|
16491
16704
|
path: { id: agentSessionId },
|
|
16492
16705
|
query: { directory: args.sessionDirectory },
|
|
@@ -16498,11 +16711,11 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
16498
16711
|
}
|
|
16499
16712
|
}, {
|
|
16500
16713
|
transport: createPromptAsyncTransport(client, agentSessionId, {
|
|
16501
|
-
tokenBudget
|
|
16714
|
+
tokenBudget,
|
|
16502
16715
|
onBudgetUpdate
|
|
16503
16716
|
}),
|
|
16504
16717
|
timeoutMs: sliceMs,
|
|
16505
|
-
signal,
|
|
16718
|
+
signal: batchSignal,
|
|
16506
16719
|
fallbackModels: args.fallbackModels,
|
|
16507
16720
|
callContext: "dreamer:verify",
|
|
16508
16721
|
fetchOutput: async () => {
|
|
@@ -16518,7 +16731,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
16518
16731
|
if (hasLengthCappedOutput(messages)) {
|
|
16519
16732
|
throw new Error("verify returned length-capped output");
|
|
16520
16733
|
}
|
|
16521
|
-
const text =
|
|
16734
|
+
const text = verifyAssistantText(messages);
|
|
16522
16735
|
if (!text)
|
|
16523
16736
|
throw new Error("verify returned no output");
|
|
16524
16737
|
const providerFailure = providerOutputFailureFromInvalidManifest(messages, text);
|
|
@@ -16529,27 +16742,31 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
16529
16742
|
});
|
|
16530
16743
|
promptSettled = true;
|
|
16531
16744
|
recordInvocation4(args, startedAt, { status: "completed", messages: run.output });
|
|
16745
|
+
reportUsage(run.output, agentSessionId);
|
|
16532
16746
|
return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
|
|
16533
16747
|
} catch (error) {
|
|
16534
16748
|
const desc = describeError(error);
|
|
16535
16749
|
const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
|
|
16536
16750
|
const promptFailure = getPromptFailureDetail(error);
|
|
16537
16751
|
log2(`[dreamer] verify batch ${providerFailure ? "provider failure" : "failed"}: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
16752
|
+
const messages = failedCompletion?.messages ?? await readFailedChildMessages(args.client, agentSessionId, args.sessionDirectory) ?? [];
|
|
16753
|
+
reportUsage(messages, hiddenSessionId ?? agentSessionId, failedCompletion?.usage.input ?? 0);
|
|
16538
16754
|
recordInvocation4(args, startedAt, {
|
|
16539
16755
|
status: failedInvocationStatus(error),
|
|
16540
16756
|
error,
|
|
16541
|
-
messages
|
|
16757
|
+
messages
|
|
16542
16758
|
});
|
|
16543
|
-
if (error instanceof DreamerModuleFailureError ||
|
|
16759
|
+
if (error instanceof DreamerModuleFailureError || signal.aborted)
|
|
16544
16760
|
throw error;
|
|
16545
|
-
|
|
16761
|
+
const interrupted = batchSignal.aborted || error instanceof DreamTokenBudgetExceeded || promptFailure?.failureClass === "provider_timeout" || isPromptTimeoutError(error);
|
|
16762
|
+
if (interrupted) {
|
|
16763
|
+
const text = verifyAssistantText(messages) ?? failedCompletion?.text ?? "";
|
|
16764
|
+
const recovered = parsePartialVerifyManifest(text, new Set(batch.map((m) => m.id)));
|
|
16765
|
+
const counts = await applyParsedVerifyManifest(args, batch, recovered, headAtPrompt, true);
|
|
16546
16766
|
return {
|
|
16547
|
-
|
|
16548
|
-
|
|
16549
|
-
|
|
16550
|
-
skipped: 0,
|
|
16551
|
-
refused: 0,
|
|
16552
|
-
timedOut: true
|
|
16767
|
+
...counts,
|
|
16768
|
+
timedOut: !(error instanceof DreamTokenBudgetExceeded),
|
|
16769
|
+
tokenLimited: error instanceof DreamTokenBudgetExceeded
|
|
16553
16770
|
};
|
|
16554
16771
|
}
|
|
16555
16772
|
if (promptFailure !== null && promptFailure.failureClass !== "parse_failed" && !providerFailure)
|
|
@@ -16564,7 +16781,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
16564
16781
|
};
|
|
16565
16782
|
} finally {
|
|
16566
16783
|
if (agentSessionId && args.client)
|
|
16567
|
-
await teardownChildSession({
|
|
16784
|
+
await raceWithSignal(teardownChildSession({
|
|
16568
16785
|
client: args.client,
|
|
16569
16786
|
sessionId: agentSessionId,
|
|
16570
16787
|
sessionDirectory: args.sessionDirectory,
|
|
@@ -16572,7 +16789,9 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
16572
16789
|
privacySensitive: true,
|
|
16573
16790
|
context: "[dreamer] verify",
|
|
16574
16791
|
log: log2
|
|
16575
|
-
});
|
|
16792
|
+
}), batchSignal).catch(() => {});
|
|
16793
|
+
clearTimeout(timer);
|
|
16794
|
+
signal.removeEventListener("abort", abort);
|
|
16576
16795
|
}
|
|
16577
16796
|
}
|
|
16578
16797
|
async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budgetFinalized = false) {
|
|
@@ -16599,7 +16818,7 @@ async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budg
|
|
|
16599
16818
|
throw new Error(`verify manifest covers ${validIds.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
16600
16819
|
}
|
|
16601
16820
|
if (budgetFinalized && validIds.length < batch.length) {
|
|
16602
|
-
log2(`[dreamer] verify: accepted partial manifest after
|
|
16821
|
+
log2(`[dreamer] verify: accepted partial manifest after investigation stop: ${validIds.length}/${batch.length}`);
|
|
16603
16822
|
}
|
|
16604
16823
|
if (validIds.length === 0) {
|
|
16605
16824
|
return { verified: 0, updated: 0, archived: 0, skipped: 0, refused: 0 };
|
|
@@ -16834,10 +17053,10 @@ function dreamRunFailureDetail(error) {
|
|
|
16834
17053
|
child_session_id: null
|
|
16835
17054
|
};
|
|
16836
17055
|
}
|
|
16837
|
-
const localRefusal = error instanceof HiddenCompletionRefusal;
|
|
17056
|
+
const localRefusal = error instanceof HiddenCompletionRefusal || error instanceof DreamerModuleFailureError;
|
|
16838
17057
|
const providerFailure = error instanceof Error && error.name === "DreamerProviderOutputFailureError";
|
|
16839
17058
|
return {
|
|
16840
|
-
failure_class: localRefusal ? "local_refusal" : providerFailure ? "provider_error" : /no models?|model chain is empty/i.test(message) ? "no_models" : "unknown",
|
|
17059
|
+
failure_class: localRefusal ? "local_refusal" : providerFailure ? "provider_error" : /lease_(?:lost|expired)|Dream lease (?:lost|unavailable)/i.test(message) ? "child_aborted" : /no models?|model chain is empty/i.test(message) ? "no_models" : "unknown",
|
|
16841
17060
|
model_attempted: null,
|
|
16842
17061
|
models_tried: [],
|
|
16843
17062
|
provider_error: providerFailure ? sanitizeDiagnosticText(message).slice(0, 500) : null,
|
|
@@ -16848,6 +17067,10 @@ function dreamRunFailureDetail(error) {
|
|
|
16848
17067
|
} : {}
|
|
16849
17068
|
};
|
|
16850
17069
|
}
|
|
17070
|
+
function incompleteFailure(error, fallback = "parse_failed") {
|
|
17071
|
+
const detail = dreamRunFailureDetail(error);
|
|
17072
|
+
return detail.failure_class === "unknown" ? { ...detail, failure_class: fallback } : detail;
|
|
17073
|
+
}
|
|
16851
17074
|
function classifyFailure(error) {
|
|
16852
17075
|
const described = describeError(error);
|
|
16853
17076
|
const brief = described.brief;
|
|
@@ -17007,6 +17230,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
17007
17230
|
const { db, projectIdentity, holderId, leaseKey } = ctx;
|
|
17008
17231
|
deps.client?.resetDreamTokenBudget?.(config.task);
|
|
17009
17232
|
const startedAt = Date.now();
|
|
17233
|
+
const effectiveTokenBudget = config.task === "verify" || config.task === "verify-broad" ? Math.min(config.tokenBudget ?? VERIFY_RUN_TOKEN_BUDGET, VERIFY_RUN_TOKEN_BUDGET) : config.tokenBudget;
|
|
17010
17234
|
const leaseAcquisition = ctx.leaseAcquisition ?? acquireLeaseWithAcquisition(db, holderId, leaseKey) ?? (() => {
|
|
17011
17235
|
throw new Error("Dream lease unavailable during executor setup");
|
|
17012
17236
|
})();
|
|
@@ -17054,7 +17278,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
17054
17278
|
if (state.sessionId) {
|
|
17055
17279
|
const previous = childSpending.get(state.sessionId) ?? 0;
|
|
17056
17280
|
budgetSpent += Math.max(0, state.spent - previous);
|
|
17057
|
-
childSpending.set(state.sessionId, state.spent);
|
|
17281
|
+
childSpending.set(state.sessionId, Math.max(previous, state.spent));
|
|
17058
17282
|
} else
|
|
17059
17283
|
budgetSpent = Math.max(budgetSpent, state.spent);
|
|
17060
17284
|
budgetFinalized ||= state.finalizeFired;
|
|
@@ -17081,9 +17305,15 @@ function createDreamTaskExecutor(deps) {
|
|
|
17081
17305
|
failure: extra?.failure ?? dreamRunFailureDetail(error ?? "unknown dreamer failure")
|
|
17082
17306
|
} : {},
|
|
17083
17307
|
...extra?.progress ? { progress: extra.progress } : {},
|
|
17084
|
-
...
|
|
17308
|
+
...childSpending.size ? {
|
|
17309
|
+
children: [...childSpending].map(([sessionId, promptTokens]) => ({
|
|
17310
|
+
sessionId,
|
|
17311
|
+
promptTokens
|
|
17312
|
+
}))
|
|
17313
|
+
} : {},
|
|
17314
|
+
...effectiveTokenBudget ? {
|
|
17085
17315
|
tokenBudget: {
|
|
17086
|
-
budget:
|
|
17316
|
+
budget: effectiveTokenBudget,
|
|
17087
17317
|
spent: budgetSpent,
|
|
17088
17318
|
finalizeFired: budgetFinalized,
|
|
17089
17319
|
banked: extra?.banked ?? processedDreamTaskItems(backlogAtStart.pending, (extra?.backlogAfter ?? getDreamTaskBacklog(db, projectIdentity, config.task)).pending)
|
|
@@ -17172,8 +17402,13 @@ function createDreamTaskExecutor(deps) {
|
|
|
17172
17402
|
});
|
|
17173
17403
|
log2(`[dreamer] compress-cues: compressed=${result.compressed} skipped=${result.skipped} chunks=${result.chunks} remaining=${result.remaining}`);
|
|
17174
17404
|
if (!result.complete) {
|
|
17175
|
-
|
|
17176
|
-
|
|
17405
|
+
if (result.stopReason === "deadline" && result.chunks === 0)
|
|
17406
|
+
return skip("compress-cues: insufficient time to start a chunk");
|
|
17407
|
+
const error = `${incompleteMessage(result.remaining)}; ${result.failureStage ? `${result.failureStage}: ` : ""}${result.failure ? describeError(result.failure).brief : `${result.skipped} cues rejected by validation`}`;
|
|
17408
|
+
recordRun("failed", error, {
|
|
17409
|
+
banked: result.compressed,
|
|
17410
|
+
failure: incompleteFailure(result.failure, result.failureStage === "child-start" ? "local_refusal" : result.stopReason === "timeout-circuit-breaker" ? "provider_timeout" : "parse_failed")
|
|
17411
|
+
});
|
|
17177
17412
|
return { status: "failed", transient: true, error };
|
|
17178
17413
|
}
|
|
17179
17414
|
recordRun("completed", null);
|
|
@@ -17219,9 +17454,15 @@ function createDreamTaskExecutor(deps) {
|
|
|
17219
17454
|
});
|
|
17220
17455
|
log2(`[dreamer] map-memories: committed=${result.mapped + result.independent} mapped=${result.mapped} independent=${result.independent} batches=${result.batches} remaining=${result.remaining} complete=${result.complete}${result.stopReason ? ` stop_reason=${result.stopReason}` : ""}`);
|
|
17221
17456
|
if (!result.complete) {
|
|
17457
|
+
if (result.deferred)
|
|
17458
|
+
return skip("map-memories: all pending mappings are in content-keyed retry backoff; no child started");
|
|
17459
|
+
if (result.stopReason === "deadline" && result.batches === 0 && !result.failure)
|
|
17460
|
+
return skip("map-memories: insufficient time to start a batch");
|
|
17222
17461
|
if (result.stopReason === "timeout-circuit-breaker") {
|
|
17223
17462
|
const error = `map-memories starvation: timeout circuit breaker stopped the run with ${result.remaining} remain`;
|
|
17224
|
-
recordRun("failed", error
|
|
17463
|
+
recordRun("failed", error, {
|
|
17464
|
+
failure: incompleteFailure(result.failure, "provider_timeout")
|
|
17465
|
+
});
|
|
17225
17466
|
return { status: "failed", transient: true, error };
|
|
17226
17467
|
}
|
|
17227
17468
|
const processed = result.mapped + result.independent;
|
|
@@ -17230,8 +17471,10 @@ function createDreamTaskExecutor(deps) {
|
|
|
17230
17471
|
recordRun("completed", null, { progress });
|
|
17231
17472
|
return { status: "completed" };
|
|
17232
17473
|
}
|
|
17233
|
-
const error = incompleteMessage(result.remaining);
|
|
17234
|
-
recordRun("failed", error
|
|
17474
|
+
const error = `${incompleteMessage(result.remaining)}; ${result.failureStage ? `${result.failureStage}: ` : ""}${result.failure ? describeError(result.failure).brief : "manifest returned no accepted mapping decisions"}`;
|
|
17475
|
+
recordRun("failed", error, {
|
|
17476
|
+
failure: incompleteFailure(result.failure, result.failureStage === "child-start" ? "local_refusal" : "parse_failed")
|
|
17477
|
+
});
|
|
17235
17478
|
return { status: "failed", transient: true, error };
|
|
17236
17479
|
}
|
|
17237
17480
|
recordRun("completed", null);
|
|
@@ -17261,25 +17504,27 @@ function createDreamTaskExecutor(deps) {
|
|
|
17261
17504
|
});
|
|
17262
17505
|
const processed = result.verified + result.updated + result.archived + result.skipped + result.refused;
|
|
17263
17506
|
const verificationProgress = `${config.task}${config.task === "verify-broad" ? ` cycle ${result.broadCycleStartAt ?? "open"}` : ""}: processed ${processed} (verified ${result.verified}, updated ${result.updated}, archived ${result.archived}, skipped ${result.skipped}, refused ${result.refused}); ${result.remaining} remain`;
|
|
17264
|
-
const broadProgress = config.task === "verify-broad" ? verificationProgress : null;
|
|
17265
17507
|
const backlogAfter = config.task === "verify-broad" ? { pending: result.remaining, total: backlogAtStart.total } : undefined;
|
|
17266
17508
|
if (!result.complete) {
|
|
17267
|
-
if (
|
|
17509
|
+
if (processed > 0) {
|
|
17268
17510
|
recordRun("completed", null, {
|
|
17269
|
-
progress:
|
|
17511
|
+
progress: verificationProgress,
|
|
17270
17512
|
memoryChanges: computeMemoryDelta(memoryBefore),
|
|
17271
17513
|
backlogAfter,
|
|
17272
17514
|
banked: result.verified + result.updated + result.archived
|
|
17273
17515
|
});
|
|
17274
17516
|
return { status: "completed" };
|
|
17275
17517
|
}
|
|
17518
|
+
if (result.stopReason === "deadline")
|
|
17519
|
+
return skip(`${config.task}: insufficient time to start a batch`);
|
|
17276
17520
|
const batchTimedOut = result.stopReason === "batch-timeout";
|
|
17277
17521
|
const error = batchTimedOut ? `${config.task}: a batch timed out within its time slice; ${result.remaining} remain` : incompleteMessage(result.remaining);
|
|
17278
17522
|
recordRun("failed", error, {
|
|
17279
17523
|
progress: verificationProgress,
|
|
17280
17524
|
memoryChanges: computeMemoryDelta(memoryBefore),
|
|
17281
17525
|
backlogAfter,
|
|
17282
|
-
banked: result.verified + result.updated + result.archived
|
|
17526
|
+
banked: result.verified + result.updated + result.archived,
|
|
17527
|
+
failure: incompleteFailure(error, batchTimedOut ? "provider_timeout" : result.stopReason === "token-budget" ? "token_budget" : "parse_failed")
|
|
17283
17528
|
});
|
|
17284
17529
|
return { status: "failed", transient: !batchTimedOut, error };
|
|
17285
17530
|
}
|
|
@@ -17403,6 +17648,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
17403
17648
|
if (retro.skipReason)
|
|
17404
17649
|
return skip(retro.skipReason);
|
|
17405
17650
|
recordRun("completed", null, {
|
|
17651
|
+
progress: retro.noOpReason,
|
|
17406
17652
|
memoryChanges: computeMemoryDelta(memoryBefore),
|
|
17407
17653
|
backlogAfter: retro.retrospectiveWatermarkMs == null ? undefined : getDreamTaskBacklog(db, projectIdentity, "retrospective", {
|
|
17408
17654
|
retrospectiveWatermarkMs: retro.retrospectiveWatermarkMs
|
|
@@ -17410,6 +17656,7 @@ function createDreamTaskExecutor(deps) {
|
|
|
17410
17656
|
});
|
|
17411
17657
|
return {
|
|
17412
17658
|
status: "completed",
|
|
17659
|
+
...retro.noOpReason ? { detail: retro.noOpReason } : {},
|
|
17413
17660
|
schedulePatch: retro.retrospectiveWatermarkMs != null || retro.taskStateJson !== undefined ? {
|
|
17414
17661
|
...retro.retrospectiveWatermarkMs != null ? {
|
|
17415
17662
|
retrospectiveWatermarkMs: retro.retrospectiveWatermarkMs
|
|
@@ -17609,20 +17856,28 @@ async function runRetrospectiveTask(config, ctx, helpers) {
|
|
|
17609
17856
|
const recencyCutoffMs = helpers.invocationStartedAt - recencyDays * RETROSPECTIVE_DAY_MS;
|
|
17610
17857
|
const scan = await readRetrospectiveScanWindow(provider, projectIdentity, watermarkMs, RETROSPECTIVE_OVERLAP_USER_LINES, { usableInputTokens, recencyCutoffMs });
|
|
17611
17858
|
const clearedTaskStateJson = activeOverflow ? writeRetrospectiveOverflowState(taskState.root, null) : undefined;
|
|
17612
|
-
const completedWindow = (retrospectiveWatermarkMs) => ({
|
|
17859
|
+
const completedWindow = (retrospectiveWatermarkMs, noOpReason) => ({
|
|
17613
17860
|
retrospectiveWatermarkMs,
|
|
17614
|
-
...clearedTaskStateJson ? { taskStateJson: clearedTaskStateJson } : {}
|
|
17861
|
+
...clearedTaskStateJson ? { taskStateJson: clearedTaskStateJson } : {},
|
|
17862
|
+
...noOpReason ? { noOpReason } : {}
|
|
17615
17863
|
});
|
|
17616
17864
|
const messages = withGlobalOrdinals(scan.messages);
|
|
17617
17865
|
const userMessages = messages.filter((message) => message.role === "user" && message.text.trim().length > 0);
|
|
17618
17866
|
if (userMessages.length === 0) {
|
|
17619
|
-
|
|
17620
|
-
|
|
17867
|
+
const noOpReason = "no reply-following user lines";
|
|
17868
|
+
log2(`[dreamer] retrospective: ${noOpReason}`);
|
|
17869
|
+
return completedWindow(scan.maxScannedTs, noOpReason);
|
|
17621
17870
|
}
|
|
17622
|
-
const
|
|
17623
|
-
if (
|
|
17871
|
+
const newUserOrdinals = new Set(userMessages.filter((message) => message.ts > watermarkMs).map((message) => message.ordinal));
|
|
17872
|
+
if (newUserOrdinals.size === 0) {
|
|
17624
17873
|
log2("[dreamer] retrospective: only overlap lines, nothing new");
|
|
17625
|
-
return completedWindow(scan.maxScannedTs);
|
|
17874
|
+
return completedWindow(scan.maxScannedTs, "only overlap lines, nothing new");
|
|
17875
|
+
}
|
|
17876
|
+
const postWatermarkOrdinals = new Set(userMessages.filter((message) => message.ts > watermarkMs && message.followsAssistantReply === true).map((message) => message.ordinal));
|
|
17877
|
+
if (postWatermarkOrdinals.size === 0) {
|
|
17878
|
+
const noOpReason = "no reply-following user lines";
|
|
17879
|
+
log2(`[dreamer] retrospective: ${noOpReason}`);
|
|
17880
|
+
return completedWindow(scan.maxScannedTs, noOpReason);
|
|
17626
17881
|
}
|
|
17627
17882
|
const abortController = new AbortController;
|
|
17628
17883
|
let leaseLost = false;
|
|
@@ -19574,31 +19829,6 @@ function emptyPiModelChainsKey(chains) {
|
|
|
19574
19829
|
return chains.map((chain) => `${chain.owner}=${chain.dropped.map((dropped) => dropped.model).join("|")}`).join(";");
|
|
19575
19830
|
}
|
|
19576
19831
|
|
|
19577
|
-
// src/subagent-runner.ts
|
|
19578
|
-
import * as childProcess from "node:child_process";
|
|
19579
|
-
import {
|
|
19580
|
-
existsSync as existsSync10,
|
|
19581
|
-
mkdtempSync as mkdtempSync2,
|
|
19582
|
-
readFileSync as readFileSync9,
|
|
19583
|
-
realpathSync as realpathSync3,
|
|
19584
|
-
rmSync as rmSync2,
|
|
19585
|
-
statSync as statSync4,
|
|
19586
|
-
writeFileSync as writeFileSync4
|
|
19587
|
-
} from "node:fs";
|
|
19588
|
-
import { createRequire } from "node:module";
|
|
19589
|
-
import { homedir, tmpdir as tmpdir2 } from "node:os";
|
|
19590
|
-
import {
|
|
19591
|
-
basename,
|
|
19592
|
-
dirname as dirname2,
|
|
19593
|
-
isAbsolute,
|
|
19594
|
-
join as join10,
|
|
19595
|
-
resolve as resolvePath,
|
|
19596
|
-
sep
|
|
19597
|
-
} from "node:path";
|
|
19598
|
-
import { createInterface } from "node:readline";
|
|
19599
|
-
import { StringDecoder } from "node:string_decoder";
|
|
19600
|
-
import { fileURLToPath } from "node:url";
|
|
19601
|
-
|
|
19602
19832
|
// src/pi-zen-free-tier.ts
|
|
19603
19833
|
var ZEN_FREE_TIER_FAILURE = "opencode_zen_free_tier";
|
|
19604
19834
|
function isZenModel(model) {
|
|
@@ -19631,6 +19861,29 @@ function classifyZenFreeTierFailure(result, model, agent, harness) {
|
|
|
19631
19861
|
}
|
|
19632
19862
|
|
|
19633
19863
|
// src/subagent-runner.ts
|
|
19864
|
+
import * as childProcess from "node:child_process";
|
|
19865
|
+
import {
|
|
19866
|
+
existsSync as existsSync10,
|
|
19867
|
+
mkdtempSync as mkdtempSync2,
|
|
19868
|
+
readFileSync as readFileSync9,
|
|
19869
|
+
realpathSync as realpathSync3,
|
|
19870
|
+
rmSync as rmSync2,
|
|
19871
|
+
statSync as statSync4,
|
|
19872
|
+
writeFileSync as writeFileSync4
|
|
19873
|
+
} from "node:fs";
|
|
19874
|
+
import { createRequire } from "node:module";
|
|
19875
|
+
import { homedir, tmpdir as tmpdir2 } from "node:os";
|
|
19876
|
+
import {
|
|
19877
|
+
basename,
|
|
19878
|
+
dirname as dirname2,
|
|
19879
|
+
isAbsolute,
|
|
19880
|
+
join as join10,
|
|
19881
|
+
resolve as resolvePath,
|
|
19882
|
+
sep
|
|
19883
|
+
} from "node:path";
|
|
19884
|
+
import { createInterface } from "node:readline";
|
|
19885
|
+
import { StringDecoder } from "node:string_decoder";
|
|
19886
|
+
import { fileURLToPath } from "node:url";
|
|
19634
19887
|
var PI_CODING_AGENT_MODULE = "@earendil-works/pi-coding-agent";
|
|
19635
19888
|
var PI_CODING_AGENT_PACKAGE_NAMES = new Set([
|
|
19636
19889
|
PI_CODING_AGENT_MODULE,
|
|
@@ -21765,8 +22018,17 @@ class PiRetrospectiveRawProvider {
|
|
|
21765
22018
|
}
|
|
21766
22019
|
const entries = this.deps.loadEntriesFromFile ? await this.deps.loadEntriesFromFile(filePath) : asyncSessionEntries(filePath);
|
|
21767
22020
|
let ordinal = 0;
|
|
22021
|
+
let sawUserMessage = false;
|
|
22022
|
+
let sawAssistantReply = false;
|
|
21768
22023
|
for await (const entry of entries) {
|
|
21769
|
-
|
|
22024
|
+
ordinal++;
|
|
22025
|
+
let row = null;
|
|
22026
|
+
if (isPiUserEntry(entry)) {
|
|
22027
|
+
row = normalizePiUserEntry(entry, sessionId, ordinal, sawUserMessage && sawAssistantReply);
|
|
22028
|
+
sawUserMessage = true;
|
|
22029
|
+
} else if (sawUserMessage && isPiAssistantEntry(entry)) {
|
|
22030
|
+
sawAssistantReply = true;
|
|
22031
|
+
}
|
|
21770
22032
|
if (!row || !eligible(row.ts))
|
|
21771
22033
|
continue;
|
|
21772
22034
|
kept.push(row);
|
|
@@ -21784,7 +22046,7 @@ class PiRetrospectiveRawProvider {
|
|
|
21784
22046
|
return kept;
|
|
21785
22047
|
}
|
|
21786
22048
|
}
|
|
21787
|
-
function normalizePiUserEntry(entry, sessionId, ordinal) {
|
|
22049
|
+
function normalizePiUserEntry(entry, sessionId, ordinal, followsAssistantReply) {
|
|
21788
22050
|
const e = entry;
|
|
21789
22051
|
if (!e || typeof e !== "object" || e.type !== "message")
|
|
21790
22052
|
return null;
|
|
@@ -21801,9 +22063,23 @@ function normalizePiUserEntry(entry, sessionId, ordinal) {
|
|
|
21801
22063
|
ordinal,
|
|
21802
22064
|
role: "user",
|
|
21803
22065
|
text,
|
|
21804
|
-
ts: message.timestamp
|
|
22066
|
+
ts: message.timestamp,
|
|
22067
|
+
...followsAssistantReply ? { followsAssistantReply: true } : {}
|
|
21805
22068
|
};
|
|
21806
22069
|
}
|
|
22070
|
+
function isPiUserEntry(entry) {
|
|
22071
|
+
return piMessageRole(entry) === "user";
|
|
22072
|
+
}
|
|
22073
|
+
function isPiAssistantEntry(entry) {
|
|
22074
|
+
return piMessageRole(entry) === "assistant";
|
|
22075
|
+
}
|
|
22076
|
+
function piMessageRole(entry) {
|
|
22077
|
+
const e = entry;
|
|
22078
|
+
if (!e || typeof e !== "object" || e.type !== "message")
|
|
22079
|
+
return null;
|
|
22080
|
+
const message = e.message;
|
|
22081
|
+
return message && typeof message === "object" ? message.role : null;
|
|
22082
|
+
}
|
|
21807
22083
|
function extractPiTextContent(content) {
|
|
21808
22084
|
if (typeof content === "string")
|
|
21809
22085
|
return content;
|
|
@@ -22097,6 +22373,8 @@ function createPiDreamerClient(opts, onAdjunctsRefreshNeeded = opts.onAdjunctsRe
|
|
|
22097
22373
|
accountingSubagent: "dreamer",
|
|
22098
22374
|
accountingTask: accountingTaskFromTitle(dreamSession.title),
|
|
22099
22375
|
tokenBudget: (() => {
|
|
22376
|
+
if (args.tokenBudget !== undefined)
|
|
22377
|
+
return args.tokenBudget;
|
|
22100
22378
|
const task = accountingTaskFromTitle(dreamSession.title);
|
|
22101
22379
|
if (!task)
|
|
22102
22380
|
return;
|
|
@@ -22107,8 +22385,15 @@ function createPiDreamerClient(opts, onAdjunctsRefreshNeeded = opts.onAdjunctsRe
|
|
|
22107
22385
|
try {
|
|
22108
22386
|
const result = await runPromise;
|
|
22109
22387
|
const budget = result.meta?.tokenBudget;
|
|
22110
|
-
if (budget)
|
|
22111
|
-
childBudgetStates.
|
|
22388
|
+
if (budget) {
|
|
22389
|
+
const prior = childBudgetStates.get(sessionId);
|
|
22390
|
+
childBudgetStates.set(sessionId, {
|
|
22391
|
+
...budget,
|
|
22392
|
+
budget: prior?.budget ?? budget.budget,
|
|
22393
|
+
spent: (prior?.spent ?? 0) + budget.spent,
|
|
22394
|
+
finalizeFired: (prior?.finalizeFired ?? false) || budget.finalizeFired
|
|
22395
|
+
});
|
|
22396
|
+
}
|
|
22112
22397
|
const budgetTask = accountingTaskFromTitle(dreamSession.title);
|
|
22113
22398
|
if (budgetTask && budget && typeof budget.spent === "number") {
|
|
22114
22399
|
const prior = budgetStates.get(budgetTask);
|
|
@@ -22119,8 +22404,15 @@ function createPiDreamerClient(opts, onAdjunctsRefreshNeeded = opts.onAdjunctsRe
|
|
|
22119
22404
|
}
|
|
22120
22405
|
assertRegistrationOwnerActive();
|
|
22121
22406
|
const mappingMessages = result.meta?.mappingMessages;
|
|
22122
|
-
|
|
22407
|
+
const isVerification = budgetTask === "verify" || budgetTask === "verify-broad";
|
|
22408
|
+
const hasMemoryDecisions = (budgetTask === "map-memories" || isVerification) && result.meta?.failureClass !== ZEN_FREE_TIER_FAILURE && Array.isArray(mappingMessages);
|
|
22409
|
+
if (hasMemoryDecisions) {
|
|
22123
22410
|
dreamSession.messages = mappingMessages.filter(isRecord).filter((message) => message.role === "assistant").map((message) => makeMessage("assistant", Array.isArray(message.content) ? message.content.filter(isRecord).flatMap((part) => part.type === "text" && typeof part.text === "string" ? [{ type: "text", text: part.text }] : part.type === "toolCall" ? syntheticToolParts(1) : []) : []));
|
|
22411
|
+
if (result.ok && result.assistantText?.trim() && !dreamSession.messages.some((message) => extractLatestAssistantText([message])?.trim())) {
|
|
22412
|
+
dreamSession.messages.push(makeMessage("assistant", [
|
|
22413
|
+
{ type: "text", text: result.assistantText }
|
|
22414
|
+
]));
|
|
22415
|
+
}
|
|
22124
22416
|
}
|
|
22125
22417
|
if (!result.ok) {
|
|
22126
22418
|
if (result.reason === "token_budget") {
|
|
@@ -22135,7 +22427,7 @@ function createPiDreamerClient(opts, onAdjunctsRefreshNeeded = opts.onAdjunctsRe
|
|
|
22135
22427
|
}
|
|
22136
22428
|
throw error;
|
|
22137
22429
|
}
|
|
22138
|
-
if (!
|
|
22430
|
+
if (!hasMemoryDecisions)
|
|
22139
22431
|
dreamSession.messages = [
|
|
22140
22432
|
makeMessage("user", [{ type: "text", text: userMessage }]),
|
|
22141
22433
|
makeMessage("assistant", [
|
|
@@ -22534,6 +22826,85 @@ Unknown task "${requested}".`,
|
|
|
22534
22826
|
});
|
|
22535
22827
|
}
|
|
22536
22828
|
|
|
22829
|
+
// ../plugin/src/hooks/magic-context/auto-embed-session.ts
|
|
22830
|
+
function embeddingIdentity(projectIdentity) {
|
|
22831
|
+
const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
|
|
22832
|
+
return JSON.stringify([
|
|
22833
|
+
projectIdentity,
|
|
22834
|
+
snapshot?.providerIdentity,
|
|
22835
|
+
snapshot?.chunkModelId,
|
|
22836
|
+
snapshot?.runtimeFingerprint
|
|
22837
|
+
]);
|
|
22838
|
+
}
|
|
22839
|
+
function maybeAutoEmbedSessionBackfill(deps, sessionId) {
|
|
22840
|
+
const markActive = () => activeEmbeddingSessions.set(sessionId, {
|
|
22841
|
+
project: deps.projectIdentity,
|
|
22842
|
+
model: getProjectEmbeddingSnapshot2(deps.projectIdentity)?.chunkModelId ?? "off"
|
|
22843
|
+
});
|
|
22844
|
+
markActive();
|
|
22845
|
+
const identity = embeddingIdentity(deps.projectIdentity);
|
|
22846
|
+
if (autoEmbedIdentityBySession.get(sessionId) !== identity) {
|
|
22847
|
+
invalidateAutoEmbedSession(sessionId);
|
|
22848
|
+
autoEmbedIdentityBySession.set(sessionId, identity);
|
|
22849
|
+
}
|
|
22850
|
+
if (autoEmbedAttemptedBySession.has(sessionId) || embedPauseBySession.has(sessionId) || embedRunStateBySession.has(sessionId) || Date.now() < (autoEmbedRetryAfterBySession.get(sessionId) ?? 0))
|
|
22851
|
+
return;
|
|
22852
|
+
const controller = new AbortController;
|
|
22853
|
+
embedRunStateBySession.set(sessionId, controller);
|
|
22854
|
+
(async () => {
|
|
22855
|
+
let complete = false;
|
|
22856
|
+
let retryDelay = 1000;
|
|
22857
|
+
let started = false;
|
|
22858
|
+
let reason = "error";
|
|
22859
|
+
let registeredIdentity = identity;
|
|
22860
|
+
try {
|
|
22861
|
+
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
22862
|
+
if (controller.signal.aborted)
|
|
22863
|
+
return;
|
|
22864
|
+
await deps.ensureRegistered();
|
|
22865
|
+
if (controller.signal.aborted)
|
|
22866
|
+
return;
|
|
22867
|
+
markActive();
|
|
22868
|
+
registeredIdentity = embeddingIdentity(deps.projectIdentity);
|
|
22869
|
+
autoEmbedIdentityBySession.set(sessionId, registeredIdentity);
|
|
22870
|
+
const coverage = await getAutoEmbeddingSessionCoverage2(deps.db, deps.projectIdentity, sessionId);
|
|
22871
|
+
if (controller.signal.aborted || !coverage.enabled)
|
|
22872
|
+
return;
|
|
22873
|
+
if (coverage.embedded === coverage.total) {
|
|
22874
|
+
complete = true;
|
|
22875
|
+
return;
|
|
22876
|
+
}
|
|
22877
|
+
const model = getProjectEmbeddingSnapshot2(deps.projectIdentity)?.model;
|
|
22878
|
+
log2(`[magic-context] session backfill start session=${sessionId} missing=${coverage.total - coverage.embedded} model=${model}`);
|
|
22879
|
+
started = true;
|
|
22880
|
+
const outcome = await embedSessionCompartmentChunks2(deps.db, deps.projectIdentity, sessionId, { signal: controller.signal, automatic: true });
|
|
22881
|
+
reason = outcome.status;
|
|
22882
|
+
const after = await getAutoEmbeddingSessionCoverage2(deps.db, deps.projectIdentity, sessionId);
|
|
22883
|
+
complete = after.enabled && after.embedded === after.total;
|
|
22884
|
+
if (!complete && outcome.status !== "busy" && outcome.status !== "aborted") {
|
|
22885
|
+
retryDelay = 60000;
|
|
22886
|
+
if (outcome.status === "nothing" || outcome.status === "done")
|
|
22887
|
+
reason = "deferred";
|
|
22888
|
+
}
|
|
22889
|
+
} catch (error) {
|
|
22890
|
+
log2("[magic-context] auto-embed drain failed:", error);
|
|
22891
|
+
retryDelay = 60000;
|
|
22892
|
+
} finally {
|
|
22893
|
+
if (started)
|
|
22894
|
+
log2(`[magic-context] session backfill ${complete ? "complete" : "stop"} session=${sessionId} reason=${reason}`);
|
|
22895
|
+
if (embedRunStateBySession.get(sessionId) === controller) {
|
|
22896
|
+
embedRunStateBySession.delete(sessionId);
|
|
22897
|
+
}
|
|
22898
|
+
if (!controller.signal.aborted && autoEmbedIdentityBySession.get(sessionId) === registeredIdentity && embeddingIdentity(deps.projectIdentity) === registeredIdentity) {
|
|
22899
|
+
if (complete)
|
|
22900
|
+
autoEmbedAttemptedBySession.add(sessionId);
|
|
22901
|
+
else
|
|
22902
|
+
autoEmbedRetryAfterBySession.set(sessionId, Date.now() + retryDelay);
|
|
22903
|
+
}
|
|
22904
|
+
}
|
|
22905
|
+
})();
|
|
22906
|
+
}
|
|
22907
|
+
|
|
22537
22908
|
// ../plugin/src/hooks/magic-context/format-embed-failure.ts
|
|
22538
22909
|
function formatEmbedFailureSummary(embedded, remaining, failure, style = "markdown") {
|
|
22539
22910
|
const historyBlocks = `history block${embedded === 1 ? "" : "s"}`;
|
|
@@ -22591,6 +22962,7 @@ function formatEmbedStatusText(coverage, drain) {
|
|
|
22591
22962
|
var EMBED_PROGRESS_COMPARTMENT_STEP = 8;
|
|
22592
22963
|
var EMBED_PROGRESS_MIN_INTERVAL_MS = 1e4;
|
|
22593
22964
|
function clearPiEmbedSessionState(sessionId) {
|
|
22965
|
+
activeEmbeddingSessions.delete(sessionId);
|
|
22594
22966
|
embedPauseBySession.delete(sessionId);
|
|
22595
22967
|
const ctrl = embedRunStateBySession.get(sessionId);
|
|
22596
22968
|
if (ctrl) {
|
|
@@ -22779,35 +23151,11 @@ ${statusText}`,
|
|
|
22779
23151
|
function maybeAutoEmbedPiSession(deps, sessionId, projectDir, projectIdentity) {
|
|
22780
23152
|
if (!isUsableProjectIdentity(projectIdentity))
|
|
22781
23153
|
return;
|
|
22782
|
-
|
|
22783
|
-
|
|
22784
|
-
|
|
22785
|
-
|
|
22786
|
-
|
|
22787
|
-
]) : "off";
|
|
22788
|
-
if (autoEmbedIdentityBySession.get(sessionId) !== embedIdentity)
|
|
22789
|
-
invalidateAutoEmbedSession(sessionId);
|
|
22790
|
-
if (autoEmbedAttemptedBySession.has(sessionId))
|
|
22791
|
-
return;
|
|
22792
|
-
if (embedPauseBySession.has(sessionId))
|
|
22793
|
-
return;
|
|
22794
|
-
autoEmbedAttemptedBySession.add(sessionId);
|
|
22795
|
-
autoEmbedIdentityBySession.set(sessionId, embedIdentity);
|
|
22796
|
-
(async () => {
|
|
22797
|
-
try {
|
|
22798
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
22799
|
-
await ensureProjectRegisteredFromPiDirectory(projectDir, deps.db);
|
|
22800
|
-
const coverage = await getAutoEmbeddingSessionCoverage2(deps.db, projectIdentity, sessionId);
|
|
22801
|
-
if (!coverage.enabled) {
|
|
22802
|
-
invalidateAutoEmbedSession(sessionId);
|
|
22803
|
-
return;
|
|
22804
|
-
}
|
|
22805
|
-
const remaining = coverage.total - coverage.embedded;
|
|
22806
|
-
if (remaining <= 0)
|
|
22807
|
-
return;
|
|
22808
|
-
await runEmbedDrain(deps.db, projectIdentity, sessionId);
|
|
22809
|
-
} catch {}
|
|
22810
|
-
})();
|
|
23154
|
+
maybeAutoEmbedSessionBackfill({
|
|
23155
|
+
db: deps.db,
|
|
23156
|
+
projectIdentity,
|
|
23157
|
+
ensureRegistered: () => ensureProjectRegisteredFromPiDirectory(projectDir, deps.db)
|
|
23158
|
+
}, sessionId);
|
|
22811
23159
|
}
|
|
22812
23160
|
|
|
22813
23161
|
// ../plugin/src/hooks/magic-context/execute-flush.ts
|
|
@@ -38802,7 +39150,7 @@ class PiThinkingBindingRecoveryRefusal extends EmergencyFailClosedError {
|
|
|
38802
39150
|
function applyPiThinkingBindingRecovery(args) {
|
|
38803
39151
|
const protectedMessages = latestAssistantTurnMessages(args.messages);
|
|
38804
39152
|
const frozenEntryIds = frozenBindingEntryIds(args.db, args.sessionId);
|
|
38805
|
-
const flagTargetCandidate = isPrefixBoundThinkingModel(args.provider, args.model) ? getThinkingBindingRecoveryTarget(args.db, args.sessionId) : null;
|
|
39153
|
+
const flagTargetCandidate = !args.replayOnly && isPrefixBoundThinkingModel(args.provider, args.model) ? getThinkingBindingRecoveryTarget(args.db, args.sessionId) : null;
|
|
38806
39154
|
const flagTarget = flagTargetCandidate?.startsWith(LATEST_THINKING_RESTORE) ? null : flagTargetCandidate;
|
|
38807
39155
|
let applied = null;
|
|
38808
39156
|
if (flagTarget) {
|
|
@@ -42239,6 +42587,7 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
42239
42587
|
const scheduler = schedulerFor(options);
|
|
42240
42588
|
lkgCompactionOff = options.compactionOff === true;
|
|
42241
42589
|
const projectIdentity = resolveProjectIdentityForSession(projectDirectory, options.allowHomeProject) ?? "";
|
|
42590
|
+
withoutSqliteTransformPass2(() => options.maybeAutoEmbedSession?.(sessionId, projectDirectory, projectIdentity));
|
|
42242
42591
|
logTransformTiming(sessionId, "findSessionId", tFindSession, `messages=${event.messages.length}`);
|
|
42243
42592
|
budget.stage = "branch projection";
|
|
42244
42593
|
const tEntryBranch = performance.now();
|
|
@@ -42973,14 +43322,15 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
42973
43322
|
hostEditBeforeNewestThinking = stickyBefore === null || [...stickyAfter].some((key) => !stickyBefore.has(key)) || JSON.stringify(getPersistedTodoSyntheticAnchor(options.db, sessionId)) !== todoAnchorBefore;
|
|
42974
43323
|
} catch {}
|
|
42975
43324
|
const outputEntryIds = resolvePiLkgOutputEntryIds(outputMessages, result.syntheticLeadingCount, (message) => result.lkgEntryIdByRef.get(message) ?? result.postCommitEntryIdByRef.get(message) ?? bindingEntryIdByRef.get(message)).map((entryId) => entryId ?? undefined);
|
|
42976
|
-
const thinkingBindingRecoveryApplied = bindingStripOrder === "end"
|
|
43325
|
+
const thinkingBindingRecoveryApplied = bindingStripOrder === "end" ? applyPiThinkingBindingRecovery({
|
|
42977
43326
|
db: options.db,
|
|
42978
43327
|
sessionId,
|
|
42979
43328
|
messages: outputMessages,
|
|
42980
43329
|
entryIds: outputEntryIds,
|
|
42981
43330
|
provider: lkgProviderKey ?? undefined,
|
|
42982
43331
|
model: ctx.model?.id,
|
|
42983
|
-
endOfPassOrder: true
|
|
43332
|
+
endOfPassOrder: true,
|
|
43333
|
+
replayOnly: result.signedPrefixRewritten && result.prefixBustPermitted
|
|
42984
43334
|
}) : startOfPassBindingRecovery;
|
|
42985
43335
|
if (shouldRunPiProactiveThinkingStrip({
|
|
42986
43336
|
compactionOff: options.compactionOff === true,
|
|
@@ -43135,8 +43485,6 @@ function registerPiContextHandler(pi, baseOptions) {
|
|
|
43135
43485
|
logTransformTiming(sessionId, "stableIdSchemePersist", tStableIdSchemePersist);
|
|
43136
43486
|
logTransformTiming(sessionId, "postTransformPhase", tPostTransform);
|
|
43137
43487
|
clearLastTransformErrorIfSet(options.db, sessionId, sessionMeta.lastTransformError);
|
|
43138
|
-
if (budget.remainingWork() > PI_CONTEXT_BUDGET.completionReserveMs)
|
|
43139
|
-
withoutSqliteTransformPass2(() => options.maybeAutoEmbedSession?.(sessionId, projectDirectory, projectIdentity));
|
|
43140
43488
|
logTransformTiming(sessionId, "postPipelineTotal", postPipelineStart);
|
|
43141
43489
|
const transformElapsedMs = performance.now() - transformStartTime;
|
|
43142
43490
|
recordPiTransformTiming({
|
|
@@ -44566,7 +44914,7 @@ async function runPipeline(args) {
|
|
|
44566
44914
|
...message,
|
|
44567
44915
|
parts: message.parts
|
|
44568
44916
|
}));
|
|
44569
|
-
const recoveryNormalized = !!args.recoveryPrefix && (
|
|
44917
|
+
const recoveryNormalized = !!args.recoveryPrefix && (isCacheBustingPass || identityRebuild);
|
|
44570
44918
|
const taggingView = args.recoveryPrefix && !recoveryNormalized ? mutationView.filter((message) => !args.recoveryPrefix?.untaggedInputIds.has(message.info.id ?? "")) : mutationView;
|
|
44571
44919
|
let tagTextTokenCache = piTagTextTokenCacheBySession.get(args.sessionId);
|
|
44572
44920
|
if (!tagTextTokenCache) {
|