@cortexkit/opencode-magic-context 0.44.2 → 0.44.4
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/{conflict-warning-hook-1msyvb51.js → conflict-warning-hook-hmpzxep6.js} +3 -3
- package/dist/{derive-budgets-gd2270s0.js → derive-budgets-ncwn1jk9.js} +4 -2
- package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/lease.d.ts +1 -1
- package/dist/features/magic-context/dreamer/lease.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts +1 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +8 -4
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +1 -1
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-storage.d.ts +5 -5
- package/dist/features/magic-context/session-project-storage.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts +6 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-embedding-measurements.d.ts.map +1 -1
- package/dist/features/magic-context/v22-deferred-backfill.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts +12 -1
- package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts +2 -1
- package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-types.d.ts +1 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/derive-budgets.d.ts +4 -0
- package/dist/hooks/magic-context/derive-budgets.d.ts.map +1 -1
- package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts +7 -0
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-host-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts +5 -0
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-persist.d.ts +1 -4
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
- package/dist/hooks/magic-context/producer-window-guard.d.ts +4 -1
- package/dist/hooks/magic-context/producer-window-guard.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +4 -2
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +2 -2
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +1 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/storage-busy-refusal.d.ts +6 -0
- package/dist/hooks/magic-context/storage-busy-refusal.d.ts.map +1 -1
- package/dist/hooks/magic-context/tokenizer-calibration.d.ts +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +1 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-r9vkp4n9.js → index-33q7s9y2.js} +1 -1
- package/dist/{index-egkfvhms.js → index-4an2p8qa.js} +80 -14
- package/dist/{index-18tjha8g.js → index-638hf49n.js} +1 -1
- package/dist/{index-gtzcmv90.js → index-mrc0twf3.js} +12 -6
- package/dist/{index-stb5fg12.js → index-msqr3x6m.js} +32 -2
- package/dist/{index-y5145x8k.js → index-n96ag4rk.js} +15 -1
- package/dist/{index-esxfcz5z.js → index-qm36k34q.js} +56 -13
- package/dist/{index-ttdn47aq.js → index-sqp1hz9v.js} +311 -82
- package/dist/{index-40s1xz22.js → index-wprsye9w.js} +1 -1
- package/dist/{index-3x9caerx.js → index-zx7pmr39.js} +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +530 -250
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/{read-session-chunk-wmvgnd24.js → read-session-chunk-339hg90t.js} +3 -3
- package/dist/{recomp-orchestrator-rk40ff15.js → recomp-orchestrator-0ers6smx.js} +7 -7
- package/dist/{send-session-notification-6xsrcxnp.js → send-session-notification-04hvd54c.js} +2 -2
- package/dist/shared/rpc-utils.d.ts +7 -0
- package/dist/shared/rpc-utils.d.ts.map +1 -1
- package/dist/shared/run-token-log.d.ts +13 -0
- package/dist/shared/run-token-log.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +7 -0
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/transcript.d.ts +2 -0
- package/dist/shared/transcript.d.ts.map +1 -1
- package/dist/shared/user-answer.d.ts +4 -0
- package/dist/shared/user-answer.d.ts.map +1 -0
- package/dist/{transform-postprocess-phase-t7xgdhdf.js → transform-postprocess-phase-ttdkrm6r.js} +7 -7
- package/dist/v2/hidden-completion.d.ts +7 -1
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/hidden-terminal-error.d.ts +8 -0
- package/dist/v2/hooks/hidden-terminal-error.d.ts.map +1 -0
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/store.d.ts +1 -1
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/hooks/tools.d.ts +1 -1
- package/dist/v2/hooks/tools.d.ts.map +1 -1
- package/dist/v2/server.js +916 -221
- package/dist/v2/store-reader.d.ts +2 -1
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/{wrapup-orchestrator-h8tr10c6.js → wrapup-orchestrator-x0jvvrqn.js} +8 -8
- package/package.json +1 -1
- package/src/config/latch-permanence-guard.test.ts +4 -0
- package/src/shared/data-path.test.ts +1 -1
- package/src/shared/models-dev-cache.test.ts +30 -1
- package/src/shared/rpc-utils.test.ts +27 -2
- package/src/shared/rpc-utils.ts +44 -15
- package/src/shared/run-token-log.test.ts +65 -0
- package/src/shared/run-token-log.ts +39 -0
- package/src/shared/sqlite-acquisition-routing.test.ts +19 -11
- package/src/shared/sqlite-pass-scope.test.ts +115 -144
- package/src/shared/sqlite.ts +123 -20
- package/src/shared/storage-busy.test.ts +34 -57
- package/src/shared/tag-transcript.ts +4 -1
- package/src/shared/transcript.ts +3 -0
- package/src/shared/user-answer.test.ts +40 -0
- package/src/shared/user-answer.ts +17 -0
- package/src/shared/write-transaction-attribution.test.ts +13 -11
package/dist/index.js
CHANGED
|
@@ -23,6 +23,9 @@ import {
|
|
|
23
23
|
isDreamerRunnable,
|
|
24
24
|
isHistorianRunnable,
|
|
25
25
|
isCompactionEnabled,
|
|
26
|
+
cortexKitUserConfigBasePath,
|
|
27
|
+
cortexKitProjectConfigBasePath,
|
|
28
|
+
resolveLegacyConfigSources,
|
|
26
29
|
migrateMagicContextConfigLocations,
|
|
27
30
|
string,
|
|
28
31
|
unknown,
|
|
@@ -60,6 +63,8 @@ import {
|
|
|
60
63
|
recordHookInitFailure,
|
|
61
64
|
clearHookInitFailure,
|
|
62
65
|
getLastHookInitFailure,
|
|
66
|
+
setHomeProjectPermission,
|
|
67
|
+
shouldSkipHomeProjectMemory,
|
|
63
68
|
ProjectIdentityError,
|
|
64
69
|
resolveProjectIdentityStrict,
|
|
65
70
|
takeDubiousOwnershipProjectIdentityWarning,
|
|
@@ -397,6 +402,8 @@ import {
|
|
|
397
402
|
readGitFileChangeTimesSince,
|
|
398
403
|
verificationFileExists,
|
|
399
404
|
normalizeVerificationFiles,
|
|
405
|
+
runTokenLog,
|
|
406
|
+
formatRunTokenLog,
|
|
400
407
|
resolveHiddenCompletionExecutor,
|
|
401
408
|
createV1HiddenCompletionExecutor,
|
|
402
409
|
USER_MEMORY_CANDIDATE_TTL_MS,
|
|
@@ -452,7 +459,7 @@ import {
|
|
|
452
459
|
snapRangeToCompartments,
|
|
453
460
|
getActiveCompartmentRun,
|
|
454
461
|
startCompartmentAgent
|
|
455
|
-
} from "./index-
|
|
462
|
+
} from "./index-sqp1hz9v.js";
|
|
456
463
|
import"./index-sd3egckz.js";
|
|
457
464
|
import {
|
|
458
465
|
canonicalModelIdentity,
|
|
@@ -476,8 +483,9 @@ import {
|
|
|
476
483
|
deriveTriggerBudget2,
|
|
477
484
|
deriveHistorianChunkTokens2,
|
|
478
485
|
resolveKnownHistorianContextLimit2,
|
|
486
|
+
resolveHistorianProducerLimits2,
|
|
479
487
|
resolveHistorianContextLimit2
|
|
480
|
-
} from "./index-
|
|
488
|
+
} from "./index-msqr3x6m.js";
|
|
481
489
|
import {
|
|
482
490
|
resolveOpenCodeDbPath,
|
|
483
491
|
assertOpenCodeStoreGeneration,
|
|
@@ -491,11 +499,12 @@ import {
|
|
|
491
499
|
claimOpenCodeDbDiagnosticOnce,
|
|
492
500
|
Database,
|
|
493
501
|
getSqliteMemoryStats,
|
|
502
|
+
withSqliteBackgroundWriter,
|
|
494
503
|
withSqliteTransformPass,
|
|
495
504
|
withoutSqliteTransformPass,
|
|
496
505
|
isTransientSqliteError,
|
|
497
506
|
SqliteAcquisitionBusyError,
|
|
498
|
-
|
|
507
|
+
withAsyncPrivilegedWriter,
|
|
499
508
|
closeQuietly,
|
|
500
509
|
openCodeDbExists,
|
|
501
510
|
withReadOnlySessionDb,
|
|
@@ -504,7 +513,7 @@ import {
|
|
|
504
513
|
assistantAwaitingTools,
|
|
505
514
|
latestPersistedMessageForRecovery,
|
|
506
515
|
findLastAssistantModelFromOpenCodeDb
|
|
507
|
-
} from "./index-
|
|
516
|
+
} from "./index-4an2p8qa.js";
|
|
508
517
|
import {
|
|
509
518
|
hasMeaningfulUserText2,
|
|
510
519
|
extractTexts2,
|
|
@@ -549,6 +558,7 @@ import {
|
|
|
549
558
|
buildInMemoryTailRawMessages,
|
|
550
559
|
estimateTrueRawMessageTokens,
|
|
551
560
|
invalidateTrueRawTokenCache,
|
|
561
|
+
toolPartHasUserAnswer,
|
|
552
562
|
DreamTokenBudgetExceeded,
|
|
553
563
|
createDreamTokenBudget,
|
|
554
564
|
recordToolParameters,
|
|
@@ -575,7 +585,7 @@ import {
|
|
|
575
585
|
readRawSessionMessageById2,
|
|
576
586
|
readSessionChunk2,
|
|
577
587
|
readRawSessionSeedTail2
|
|
578
|
-
} from "./index-
|
|
588
|
+
} from "./index-qm36k34q.js";
|
|
579
589
|
import"./index-kwe03yde.js";
|
|
580
590
|
import {
|
|
581
591
|
getErrorMessage,
|
|
@@ -585,17 +595,17 @@ import {
|
|
|
585
595
|
clearIgnoredMessages2,
|
|
586
596
|
observeIgnoredNotificationEvent2,
|
|
587
597
|
sendStatusNotification2
|
|
588
|
-
} from "./index-
|
|
598
|
+
} from "./index-33q7s9y2.js";
|
|
589
599
|
import {
|
|
590
600
|
detectConflicts,
|
|
591
601
|
resolveCompactionForBoot,
|
|
592
602
|
sendConflictWarning2,
|
|
593
603
|
cleanupConflictWarnings2
|
|
594
|
-
} from "./index-
|
|
604
|
+
} from "./index-638hf49n.js";
|
|
595
605
|
import {
|
|
596
606
|
resolveModelCalibration,
|
|
597
607
|
calibrateBuckets
|
|
598
|
-
} from "./index-
|
|
608
|
+
} from "./index-n96ag4rk.js";
|
|
599
609
|
import {
|
|
600
610
|
resolveHistorianModel2,
|
|
601
611
|
resolveOpenCodeAgentOverrides2,
|
|
@@ -672,12 +682,12 @@ import {
|
|
|
672
682
|
abortSessionFailClosed2,
|
|
673
683
|
evaluateEmergencyFailClosed2,
|
|
674
684
|
runPostTransformPhase2
|
|
675
|
-
} from "./index-
|
|
685
|
+
} from "./index-mrc0twf3.js";
|
|
676
686
|
import {
|
|
677
687
|
setRecompStarting2,
|
|
678
688
|
setRecompTerminal2,
|
|
679
689
|
runManagedRecomp2
|
|
680
|
-
} from "./index-
|
|
690
|
+
} from "./index-wprsye9w.js";
|
|
681
691
|
import {
|
|
682
692
|
isValidSemver,
|
|
683
693
|
compareSemverCore,
|
|
@@ -692,7 +702,7 @@ import {
|
|
|
692
702
|
} from "./index-fmsr7v69.js";
|
|
693
703
|
import {
|
|
694
704
|
runManagedWrapup2
|
|
695
|
-
} from "./index-
|
|
705
|
+
} from "./index-zx7pmr39.js";
|
|
696
706
|
import {
|
|
697
707
|
logSlowWriteTransaction
|
|
698
708
|
} from "./index-kr5qehbd.js";
|
|
@@ -9370,7 +9380,7 @@ function countFailures(db) {
|
|
|
9370
9380
|
function classifyBackfillError(error) {
|
|
9371
9381
|
if (error instanceof ProjectIdentityError) {
|
|
9372
9382
|
return {
|
|
9373
|
-
errorClass: error.errorClass === "dubious_ownership" || error.errorClass === "home_project_disabled" || error.errorClass === "git_identity_unavailable" ? "unknown" : error.errorClass,
|
|
9383
|
+
errorClass: error.errorClass === "dubious_ownership" || error.errorClass === "home_project_disabled" || error.errorClass === "git_identity_unavailable" || error.errorClass === "no_commits" ? "unknown" : error.errorClass,
|
|
9374
9384
|
errorMessage: error.message
|
|
9375
9385
|
};
|
|
9376
9386
|
}
|
|
@@ -11244,7 +11254,7 @@ function startLeaseHeartbeat(db, holderId, leaseKey, onLost, intervalOrAcquisiti
|
|
|
11244
11254
|
}
|
|
11245
11255
|
};
|
|
11246
11256
|
beat();
|
|
11247
|
-
const timer = lost ? undefined : setInterval(beat, intervalMs);
|
|
11257
|
+
const timer = lost ? undefined : setInterval(() => withSqliteBackgroundWriter(beat), intervalMs);
|
|
11248
11258
|
return {
|
|
11249
11259
|
stop: () => {
|
|
11250
11260
|
if (timer)
|
|
@@ -12618,8 +12628,10 @@ async function runHiddenSingleShotPrompt(args) {
|
|
|
12618
12628
|
callContext: args.callContext,
|
|
12619
12629
|
fetchOutput: () => args.executor.collect(handle, 50),
|
|
12620
12630
|
validateOutput: (completion) => {
|
|
12631
|
+
const tokens = completion.tokenLog ?? runTokenLog(undefined);
|
|
12632
|
+
sessionLog(args.parentSessionId ?? "dreamer", `${args.callContext} response_chars=${(completion.text ?? completion.reasoning ?? "").length} ${formatRunTokenLog(tokens)}`);
|
|
12621
12633
|
if (completion.lengthCapped) {
|
|
12622
|
-
throw new Error(completion.reasoning && !completion.text ? `${args.callContext} ran out of output budget while reasoning (length-capped at ${completion.usage.output} tokens, no text) — set dreamer.maxTokens or use a low-reasoning model` : `${args.callContext} returned length-capped output`);
|
|
12634
|
+
throw new Error(completion.reasoning && !completion.text ? `${args.callContext} ran out of output budget while reasoning (length-capped at ${completion.usage.output} tokens, no text; ${formatRunTokenLog(tokens)}) — set dreamer.maxTokens or use a low-reasoning model` : `${args.callContext} returned length-capped output; ${formatRunTokenLog(tokens)}`);
|
|
12623
12635
|
}
|
|
12624
12636
|
const text = completion.text;
|
|
12625
12637
|
if (!text && !args.allowEmpty)
|
|
@@ -13273,8 +13285,10 @@ async function classifyOneChunk(args, chunk, anchors, sliceMs, signal) {
|
|
|
13273
13285
|
fetchOutput: () => executor.collect(opened, 50),
|
|
13274
13286
|
validateOutput: (completion) => {
|
|
13275
13287
|
const messages = completion.messages ?? [];
|
|
13288
|
+
const tokens = completion.tokenLog ?? runTokenLog(undefined);
|
|
13289
|
+
sessionLog(args.parentSessionId ?? "dreamer", `dreamer:classify response_chars=${(completion.text ?? completion.reasoning ?? "").length} ${formatRunTokenLog(tokens)}`);
|
|
13276
13290
|
if (completion.lengthCapped) {
|
|
13277
|
-
throw new Error(completion.reasoning && !completion.text ? `classify ran out of output budget while reasoning (length-capped at ${completion.usage.output} tokens, no text) — set dreamer.maxTokens or use a low-reasoning model` :
|
|
13291
|
+
throw new Error(completion.reasoning && !completion.text ? `classify ran out of output budget while reasoning (length-capped at ${completion.usage.output} tokens, no text; ${formatRunTokenLog(tokens)}) — set dreamer.maxTokens or use a low-reasoning model` : `classify returned length-capped output; ${formatRunTokenLog(tokens)}`);
|
|
13278
13292
|
}
|
|
13279
13293
|
const text = completion.text;
|
|
13280
13294
|
if (!text)
|
|
@@ -16307,6 +16321,11 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
16307
16321
|
let agentSessionId = null;
|
|
16308
16322
|
let promptSettled = false;
|
|
16309
16323
|
const startedAt = Date.now();
|
|
16324
|
+
let budgetFinalized = false;
|
|
16325
|
+
const onBudgetUpdate = (state) => {
|
|
16326
|
+
budgetFinalized ||= state.finalizeFired;
|
|
16327
|
+
args.onBudgetUpdate?.(state);
|
|
16328
|
+
};
|
|
16310
16329
|
try {
|
|
16311
16330
|
const prompt = buildMapMemoriesPrompt(args.projectIdentity, batch);
|
|
16312
16331
|
if (args.hiddenCompletionExecutor) {
|
|
@@ -16319,7 +16338,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
16319
16338
|
prompt,
|
|
16320
16339
|
title: "magic-context-dream-map-memories",
|
|
16321
16340
|
callContext: "dreamer:map-memories",
|
|
16322
|
-
metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate
|
|
16341
|
+
metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate },
|
|
16323
16342
|
model: args.model,
|
|
16324
16343
|
fallbackModels: args.fallbackModels,
|
|
16325
16344
|
timeoutMs: sliceMs,
|
|
@@ -16330,9 +16349,12 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
16330
16349
|
status: "completed",
|
|
16331
16350
|
messages: run.completion.messages ?? []
|
|
16332
16351
|
});
|
|
16333
|
-
const outcome = await applyParsedBatchMappings(args, batch, run.validated);
|
|
16352
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
|
|
16334
16353
|
const returnedIds = new Set(run.validated.map((entry) => entry.id));
|
|
16335
|
-
return {
|
|
16354
|
+
return {
|
|
16355
|
+
...outcome,
|
|
16356
|
+
requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
|
|
16357
|
+
};
|
|
16336
16358
|
}
|
|
16337
16359
|
const client = args.client;
|
|
16338
16360
|
if (!client)
|
|
@@ -16362,7 +16384,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
16362
16384
|
}, {
|
|
16363
16385
|
transport: createPromptAsyncTransport(client, agentSessionId, {
|
|
16364
16386
|
tokenBudget: args.tokenBudget,
|
|
16365
|
-
onBudgetUpdate
|
|
16387
|
+
onBudgetUpdate
|
|
16366
16388
|
}),
|
|
16367
16389
|
timeoutMs: sliceMs,
|
|
16368
16390
|
signal,
|
|
@@ -16389,11 +16411,11 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
16389
16411
|
});
|
|
16390
16412
|
promptSettled = true;
|
|
16391
16413
|
recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
|
|
16392
|
-
const outcome = await applyParsedBatchMappings(args, batch, run.validated);
|
|
16414
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
|
|
16393
16415
|
const returnedIds = new Set(run.validated.filter((entry) => batch.some((memory) => memory.id === entry.id)).map((entry) => entry.id));
|
|
16394
16416
|
return {
|
|
16395
16417
|
...outcome,
|
|
16396
|
-
requeue: batch.filter((memory) => !returnedIds.has(memory.id))
|
|
16418
|
+
requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
|
|
16397
16419
|
};
|
|
16398
16420
|
} catch (error) {
|
|
16399
16421
|
const desc = describeError(error);
|
|
@@ -16428,7 +16450,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
16428
16450
|
});
|
|
16429
16451
|
}
|
|
16430
16452
|
}
|
|
16431
|
-
async function applyParsedBatchMappings(args, batch, parsed) {
|
|
16453
|
+
async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = false) {
|
|
16432
16454
|
const batchIds = new Set(batch.map((memory) => memory.id));
|
|
16433
16455
|
const valid = parsed.filter((entry) => batchIds.has(entry.id));
|
|
16434
16456
|
const unknown = parsed.filter((entry) => !batchIds.has(entry.id));
|
|
@@ -16436,9 +16458,12 @@ async function applyParsedBatchMappings(args, batch, parsed) {
|
|
|
16436
16458
|
log(`[dreamer] map-memories warning: dropping ${unknown.length} unknown mapping entr${unknown.length === 1 ? "y" : "ies"} outside the current batch (${unknown.map((entry) => entry.id).join(", ")})`);
|
|
16437
16459
|
}
|
|
16438
16460
|
assertNoDuplicateManifestIds(valid.map((entry) => entry.id), "mappings");
|
|
16439
|
-
if (valid.length * 2 < batch.length) {
|
|
16461
|
+
if (!budgetFinalized && valid.length * 2 < batch.length) {
|
|
16440
16462
|
throw new Error(`mappings manifest covers ${valid.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
16441
16463
|
}
|
|
16464
|
+
if (budgetFinalized && valid.length < batch.length) {
|
|
16465
|
+
log(`[dreamer] map-memories: accepted partial manifest after token budget: ${valid.length}/${batch.length}`);
|
|
16466
|
+
}
|
|
16442
16467
|
if (valid.length === 0)
|
|
16443
16468
|
return { mapped: 0, independent: 0 };
|
|
16444
16469
|
const planned = [];
|
|
@@ -18011,6 +18036,11 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
18011
18036
|
let agentSessionId = null;
|
|
18012
18037
|
let promptSettled = false;
|
|
18013
18038
|
const startedAt = Date.now();
|
|
18039
|
+
let budgetFinalized = false;
|
|
18040
|
+
const onBudgetUpdate = (state) => {
|
|
18041
|
+
budgetFinalized ||= state.finalizeFired;
|
|
18042
|
+
args.onBudgetUpdate?.(state);
|
|
18043
|
+
};
|
|
18014
18044
|
try {
|
|
18015
18045
|
const headAtPrompt = await readGitHead(args.sessionDirectory);
|
|
18016
18046
|
const evidence = !args.forceBroad && batch.every((m) => m.verifiedAt) ? await buildVerifyDiffEvidence(args.sessionDirectory, batch) : null;
|
|
@@ -18025,7 +18055,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
18025
18055
|
prompt,
|
|
18026
18056
|
title: "magic-context-dream-verify",
|
|
18027
18057
|
callContext: "dreamer:verify",
|
|
18028
|
-
metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate
|
|
18058
|
+
metadata: { tokenBudget: args.tokenBudget, onBudgetUpdate },
|
|
18029
18059
|
model: args.model,
|
|
18030
18060
|
fallbackModels: args.fallbackModels,
|
|
18031
18061
|
language: args.language,
|
|
@@ -18042,7 +18072,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
18042
18072
|
status: "completed",
|
|
18043
18073
|
messages: run.completion.messages ?? []
|
|
18044
18074
|
});
|
|
18045
|
-
return applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt);
|
|
18075
|
+
return applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
|
|
18046
18076
|
}
|
|
18047
18077
|
const client = args.client;
|
|
18048
18078
|
if (!client)
|
|
@@ -18072,7 +18102,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
18072
18102
|
}, {
|
|
18073
18103
|
transport: createPromptAsyncTransport(client, agentSessionId, {
|
|
18074
18104
|
tokenBudget: args.tokenBudget,
|
|
18075
|
-
onBudgetUpdate
|
|
18105
|
+
onBudgetUpdate
|
|
18076
18106
|
}),
|
|
18077
18107
|
timeoutMs: sliceMs,
|
|
18078
18108
|
signal,
|
|
@@ -18102,7 +18132,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
18102
18132
|
});
|
|
18103
18133
|
promptSettled = true;
|
|
18104
18134
|
recordInvocation4(args, startedAt, { status: "completed", messages: run.output });
|
|
18105
|
-
return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt);
|
|
18135
|
+
return await applyParsedVerifyManifest(args, batch, run.validated, evidence?.head ?? headAtPrompt, budgetFinalized);
|
|
18106
18136
|
} catch (error) {
|
|
18107
18137
|
const desc = describeError(error);
|
|
18108
18138
|
const providerFailure = error instanceof DreamerProviderOutputFailureError ? error : undefined;
|
|
@@ -18148,7 +18178,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
18148
18178
|
});
|
|
18149
18179
|
}
|
|
18150
18180
|
}
|
|
18151
|
-
async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt) {
|
|
18181
|
+
async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budgetFinalized = false) {
|
|
18152
18182
|
const batchIds = new Set(batch.map((m) => m.id));
|
|
18153
18183
|
const batchById = new Map(batch.map((memory) => [memory.id, memory]));
|
|
18154
18184
|
const valid = {
|
|
@@ -18168,9 +18198,12 @@ async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt) {
|
|
|
18168
18198
|
}
|
|
18169
18199
|
const validIds = [...valid.verified, ...valid.updated, ...valid.archived, ...valid.skipped].map((entry) => entry.id);
|
|
18170
18200
|
assertNoDuplicateManifestIds(validIds, "verify");
|
|
18171
|
-
if (validIds.length * 2 < batch.length) {
|
|
18201
|
+
if (!budgetFinalized && validIds.length * 2 < batch.length) {
|
|
18172
18202
|
throw new Error(`verify manifest covers ${validIds.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
18173
18203
|
}
|
|
18204
|
+
if (budgetFinalized && validIds.length < batch.length) {
|
|
18205
|
+
log(`[dreamer] verify: accepted partial manifest after token budget: ${validIds.length}/${batch.length}`);
|
|
18206
|
+
}
|
|
18174
18207
|
if (validIds.length === 0) {
|
|
18175
18208
|
return { verified: 0, updated: 0, archived: 0, skipped: 0, refused: 0 };
|
|
18176
18209
|
}
|
|
@@ -20050,6 +20083,205 @@ function clearDreamerTickFailure(db) {
|
|
|
20050
20083
|
db.prepare("DELETE FROM schema_migrations_meta WHERE key = ?").run(DREAMER_TICK_FAILURE_KEY);
|
|
20051
20084
|
}
|
|
20052
20085
|
|
|
20086
|
+
// src/hooks/magic-context/lkg-persist.ts
|
|
20087
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
20088
|
+
function parseStringArray(value) {
|
|
20089
|
+
if (typeof value !== "string")
|
|
20090
|
+
return null;
|
|
20091
|
+
let parsed;
|
|
20092
|
+
try {
|
|
20093
|
+
parsed = JSON.parse(value);
|
|
20094
|
+
} catch {
|
|
20095
|
+
return null;
|
|
20096
|
+
}
|
|
20097
|
+
if (!Array.isArray(parsed))
|
|
20098
|
+
return null;
|
|
20099
|
+
const result = [];
|
|
20100
|
+
for (const entry of parsed) {
|
|
20101
|
+
if (typeof entry !== "string" || entry.length === 0)
|
|
20102
|
+
return null;
|
|
20103
|
+
result.push(entry);
|
|
20104
|
+
}
|
|
20105
|
+
return result;
|
|
20106
|
+
}
|
|
20107
|
+
function parseNullableString(value) {
|
|
20108
|
+
if (value === null || value === undefined)
|
|
20109
|
+
return null;
|
|
20110
|
+
return typeof value === "string" ? value : undefined;
|
|
20111
|
+
}
|
|
20112
|
+
function parseNullableInteger(value) {
|
|
20113
|
+
if (value === null || value === undefined)
|
|
20114
|
+
return;
|
|
20115
|
+
return typeof value === "number" && Number.isSafeInteger(value) ? value : undefined;
|
|
20116
|
+
}
|
|
20117
|
+
function parsePersistedLkgSlot(row) {
|
|
20118
|
+
if (!row || typeof row !== "object")
|
|
20119
|
+
return;
|
|
20120
|
+
const record = row;
|
|
20121
|
+
const jsonPrefix = record.json_prefix;
|
|
20122
|
+
const lastInputMessageId = record.last_input_message_id;
|
|
20123
|
+
const capturedAt = record.captured_at;
|
|
20124
|
+
let inputIdsRaw = record.input_id_seq;
|
|
20125
|
+
let piOutputEntryIds;
|
|
20126
|
+
if (typeof inputIdsRaw === "string") {
|
|
20127
|
+
try {
|
|
20128
|
+
const metadata = JSON.parse(inputIdsRaw);
|
|
20129
|
+
if (metadata && !Array.isArray(metadata) && metadata.version === 1 && Array.isArray(metadata.piOutputEntryIds)) {
|
|
20130
|
+
if (!metadata.piOutputEntryIds.every((id) => id === null || typeof id === "string" && id.length > 0))
|
|
20131
|
+
return;
|
|
20132
|
+
piOutputEntryIds = metadata.piOutputEntryIds;
|
|
20133
|
+
inputIdsRaw = JSON.stringify(metadata.inputIds);
|
|
20134
|
+
}
|
|
20135
|
+
} catch {
|
|
20136
|
+
return;
|
|
20137
|
+
}
|
|
20138
|
+
}
|
|
20139
|
+
const inputIdSeq = parseStringArray(inputIdsRaw);
|
|
20140
|
+
const inputContentDigests = parseStringArray(record.input_content_digests);
|
|
20141
|
+
const modelKey = parseNullableString(record.model_key);
|
|
20142
|
+
const providerKey = parseNullableString(record.provider_key);
|
|
20143
|
+
if (typeof jsonPrefix !== "string" || typeof lastInputMessageId !== "string" || lastInputMessageId.length === 0 || typeof capturedAt !== "number" || !Number.isFinite(capturedAt) || inputIdSeq === null || inputContentDigests === null || inputContentDigests.length !== inputIdSeq.length || modelKey === undefined || providerKey === undefined) {
|
|
20144
|
+
return;
|
|
20145
|
+
}
|
|
20146
|
+
if (piOutputEntryIds) {
|
|
20147
|
+
try {
|
|
20148
|
+
const output = JSON.parse(jsonPrefix);
|
|
20149
|
+
const inputs = new Set(inputIdSeq);
|
|
20150
|
+
if (!Array.isArray(output) || output.length !== piOutputEntryIds.length || piOutputEntryIds.some((id) => id !== null && !inputs.has(id)))
|
|
20151
|
+
return;
|
|
20152
|
+
} catch {
|
|
20153
|
+
return;
|
|
20154
|
+
}
|
|
20155
|
+
}
|
|
20156
|
+
let inputContentSignatures;
|
|
20157
|
+
if (record.input_content_signatures !== null && record.input_content_signatures !== undefined) {
|
|
20158
|
+
const parsed = parseStringArray(record.input_content_signatures);
|
|
20159
|
+
if (parsed === null || parsed.length !== inputIdSeq.length)
|
|
20160
|
+
return;
|
|
20161
|
+
inputContentSignatures = parsed;
|
|
20162
|
+
}
|
|
20163
|
+
const slot = {
|
|
20164
|
+
jsonPrefix,
|
|
20165
|
+
inputIdSeq,
|
|
20166
|
+
inputContentDigests,
|
|
20167
|
+
lastInputMessageId,
|
|
20168
|
+
modelKey,
|
|
20169
|
+
providerKey,
|
|
20170
|
+
capturedAt
|
|
20171
|
+
};
|
|
20172
|
+
if (inputContentSignatures)
|
|
20173
|
+
slot.inputContentSignatures = inputContentSignatures;
|
|
20174
|
+
if (piOutputEntryIds)
|
|
20175
|
+
slot.piOutputEntryIds = piOutputEntryIds;
|
|
20176
|
+
const rowVersion = parseNullableInteger(record.row_version);
|
|
20177
|
+
if (rowVersion !== undefined)
|
|
20178
|
+
slot.rowVersion = rowVersion;
|
|
20179
|
+
const captureSequence = parseNullableInteger(record.capture_sequence);
|
|
20180
|
+
if (captureSequence !== undefined)
|
|
20181
|
+
slot.captureSequence = captureSequence;
|
|
20182
|
+
return slot;
|
|
20183
|
+
}
|
|
20184
|
+
var persistedFingerprints = new WeakMap;
|
|
20185
|
+
function saveLkgSlotToDb(db, sessionId, slot) {
|
|
20186
|
+
const fingerprint = createHash10("sha256").update(JSON.stringify([
|
|
20187
|
+
slot.jsonPrefix,
|
|
20188
|
+
slot.inputIdSeq,
|
|
20189
|
+
slot.inputContentDigests,
|
|
20190
|
+
slot.inputContentSignatures,
|
|
20191
|
+
slot.piOutputEntryIds,
|
|
20192
|
+
slot.lastInputMessageId,
|
|
20193
|
+
slot.modelKey,
|
|
20194
|
+
slot.providerKey,
|
|
20195
|
+
slot.rowVersion,
|
|
20196
|
+
slot.captureSequence
|
|
20197
|
+
])).digest("hex");
|
|
20198
|
+
let saved = persistedFingerprints.get(db);
|
|
20199
|
+
if (saved?.get(sessionId) === fingerprint)
|
|
20200
|
+
return true;
|
|
20201
|
+
try {
|
|
20202
|
+
db.prepare(`INSERT INTO lkg_slots (
|
|
20203
|
+
session_id, json_prefix, input_id_seq, input_content_digests,
|
|
20204
|
+
input_content_signatures, last_input_message_id, model_key, provider_key,
|
|
20205
|
+
captured_at, row_version, capture_sequence
|
|
20206
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
20207
|
+
ON CONFLICT(session_id) DO UPDATE SET
|
|
20208
|
+
json_prefix = excluded.json_prefix,
|
|
20209
|
+
input_id_seq = excluded.input_id_seq,
|
|
20210
|
+
input_content_digests = excluded.input_content_digests,
|
|
20211
|
+
input_content_signatures = excluded.input_content_signatures,
|
|
20212
|
+
last_input_message_id = excluded.last_input_message_id,
|
|
20213
|
+
model_key = excluded.model_key,
|
|
20214
|
+
provider_key = excluded.provider_key,
|
|
20215
|
+
captured_at = excluded.captured_at,
|
|
20216
|
+
row_version = excluded.row_version,
|
|
20217
|
+
capture_sequence = excluded.capture_sequence`).run(sessionId, slot.jsonPrefix, JSON.stringify(slot.piOutputEntryIds ? {
|
|
20218
|
+
version: 1,
|
|
20219
|
+
inputIds: slot.inputIdSeq,
|
|
20220
|
+
piOutputEntryIds: slot.piOutputEntryIds
|
|
20221
|
+
} : slot.inputIdSeq), JSON.stringify(slot.inputContentDigests), slot.inputContentSignatures ? JSON.stringify(slot.inputContentSignatures) : null, slot.lastInputMessageId, slot.modelKey, slot.providerKey, slot.capturedAt, slot.rowVersion ?? null, slot.captureSequence ?? null);
|
|
20222
|
+
if (!saved) {
|
|
20223
|
+
saved = new Map;
|
|
20224
|
+
persistedFingerprints.set(db, saved);
|
|
20225
|
+
}
|
|
20226
|
+
if (saved.size >= 1000) {
|
|
20227
|
+
const oldest = saved.keys().next().value;
|
|
20228
|
+
if (oldest !== undefined)
|
|
20229
|
+
saved.delete(oldest);
|
|
20230
|
+
}
|
|
20231
|
+
saved.set(sessionId, fingerprint);
|
|
20232
|
+
return true;
|
|
20233
|
+
} catch (error) {
|
|
20234
|
+
sessionLog(sessionId, "LKG snapshot persistence failed (in-memory slot retained):", error);
|
|
20235
|
+
return false;
|
|
20236
|
+
}
|
|
20237
|
+
}
|
|
20238
|
+
function clearPersistedLkgSlot(db, sessionId) {
|
|
20239
|
+
try {
|
|
20240
|
+
db.prepare("DELETE FROM lkg_slots WHERE session_id = ?").run(sessionId);
|
|
20241
|
+
persistedFingerprints.get(db)?.delete(sessionId);
|
|
20242
|
+
} catch (error) {
|
|
20243
|
+
sessionLog(sessionId, "LKG snapshot durable clear failed:", error);
|
|
20244
|
+
}
|
|
20245
|
+
}
|
|
20246
|
+
function loadPersistedLkgSlot(db, sessionId) {
|
|
20247
|
+
let row;
|
|
20248
|
+
try {
|
|
20249
|
+
row = db.prepare("SELECT * FROM lkg_slots WHERE session_id = ?").get(sessionId);
|
|
20250
|
+
} catch (error) {
|
|
20251
|
+
sessionLog(sessionId, "LKG snapshot durable load failed:", error);
|
|
20252
|
+
return;
|
|
20253
|
+
}
|
|
20254
|
+
if (!row)
|
|
20255
|
+
return;
|
|
20256
|
+
const slot = parsePersistedLkgSlot(row);
|
|
20257
|
+
if (!slot) {
|
|
20258
|
+
clearPersistedLkgSlot(db, sessionId);
|
|
20259
|
+
return;
|
|
20260
|
+
}
|
|
20261
|
+
return slot;
|
|
20262
|
+
}
|
|
20263
|
+
function pruneStaleLkgSlots(db, now = Date.now()) {
|
|
20264
|
+
const previousTimeout = db.prepare("PRAGMA busy_timeout").get();
|
|
20265
|
+
try {
|
|
20266
|
+
db.exec("PRAGMA busy_timeout = 0");
|
|
20267
|
+
const result = db.prepare(`DELETE FROM lkg_slots WHERE captured_at < ? AND NOT EXISTS (
|
|
20268
|
+
SELECT 1 FROM session_projects sp
|
|
20269
|
+
WHERE sp.session_id = lkg_slots.session_id AND sp.updated_at >= ?
|
|
20270
|
+
)`).run(now - 7 * 24 * 60 * 60 * 1000, now - 7 * 24 * 60 * 60 * 1000);
|
|
20271
|
+
if (result.changes)
|
|
20272
|
+
persistedFingerprints.delete(db);
|
|
20273
|
+
return result.changes;
|
|
20274
|
+
} finally {
|
|
20275
|
+
db.exec(`PRAGMA busy_timeout = ${Number(previousTimeout.timeout) || 0}`);
|
|
20276
|
+
}
|
|
20277
|
+
}
|
|
20278
|
+
function createDbLkgPersistence(db) {
|
|
20279
|
+
return {
|
|
20280
|
+
load: (sessionId) => loadPersistedLkgSlot(db, sessionId),
|
|
20281
|
+
clear: (sessionId) => clearPersistedLkgSlot(db, sessionId)
|
|
20282
|
+
};
|
|
20283
|
+
}
|
|
20284
|
+
|
|
20053
20285
|
// src/plugin/dream-timer.ts
|
|
20054
20286
|
var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
|
|
20055
20287
|
var GIT_COMMIT_BACKLOG_DRAIN_MAX_MS = 5 * 60 * 1000;
|
|
@@ -20212,6 +20444,11 @@ function persistTickOutcome(db, failure) {
|
|
|
20212
20444
|
}
|
|
20213
20445
|
}
|
|
20214
20446
|
async function runMessageHistoryMaintenance(db) {
|
|
20447
|
+
try {
|
|
20448
|
+
pruneStaleLkgSlots(db);
|
|
20449
|
+
} catch (error) {
|
|
20450
|
+
log("[magic-context] LKG pruning deferred:", error);
|
|
20451
|
+
}
|
|
20215
20452
|
const cleanup = retryPendingSessionCleanups(db);
|
|
20216
20453
|
if (cleanup.cleared > 0 || cleanup.failedSessionIds.length > 0) {
|
|
20217
20454
|
log(`[message-index] pending session cleanup: cleared=${cleanup.cleared} failed=${cleanup.failedSessionIds.length}`);
|
|
@@ -20489,8 +20726,11 @@ function createDreamTimerModuleClient(moduleClient) {
|
|
|
20489
20726
|
};
|
|
20490
20727
|
}
|
|
20491
20728
|
|
|
20729
|
+
// src/plugin/embedding-bootstrap.ts
|
|
20730
|
+
import { readFileSync as readFileSync7, statSync as statSync4 } from "node:fs";
|
|
20731
|
+
|
|
20492
20732
|
// src/plugin/embedding-bootstrap-helpers.ts
|
|
20493
|
-
import { createHash as
|
|
20733
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
20494
20734
|
var EMBEDDING_AFFECTING_KEYS = new Set([
|
|
20495
20735
|
"embedding.api_key",
|
|
20496
20736
|
"embedding.endpoint",
|
|
@@ -20538,7 +20778,7 @@ var EMBEDDING_WARNING_TERMS = [
|
|
|
20538
20778
|
];
|
|
20539
20779
|
var loggedFailureSignatures = new Map;
|
|
20540
20780
|
function sha256Prefix(value, length = 16) {
|
|
20541
|
-
return
|
|
20781
|
+
return createHash11("sha256").update(value).digest("hex").slice(0, length);
|
|
20542
20782
|
}
|
|
20543
20783
|
function warningLooksEmbeddingRelated(message) {
|
|
20544
20784
|
const lower = message.toLowerCase();
|
|
@@ -20733,12 +20973,41 @@ async function resolveEmbeddingRouting(args) {
|
|
|
20733
20973
|
}
|
|
20734
20974
|
|
|
20735
20975
|
// src/plugin/embedding-bootstrap.ts
|
|
20736
|
-
|
|
20976
|
+
var configCache = new Map;
|
|
20977
|
+
function loadRegistrationConfig(directory) {
|
|
20978
|
+
const legacy = resolveLegacyConfigSources(directory);
|
|
20979
|
+
const paths = [cortexKitUserConfigBasePath(), cortexKitProjectConfigBasePath(directory)].flatMap((base) => [`${base}.jsonc`, `${base}.json`]).concat(legacy.user.map((source) => source.path), legacy.project.map((source) => source.path));
|
|
20980
|
+
const key = paths.map((path) => {
|
|
20981
|
+
const stat = statSync4(path, { throwIfNoEntry: false });
|
|
20982
|
+
return `${path}:${stat?.mtimeMs ?? "missing"}:${stat?.size ?? 0}`;
|
|
20983
|
+
}).join("|");
|
|
20984
|
+
const cached = configCache.get(directory);
|
|
20985
|
+
if (cached?.key === key)
|
|
20986
|
+
return cached.detailed;
|
|
20737
20987
|
const detailed = loadPluginConfigDetailed(directory);
|
|
20988
|
+
const dynamic = paths.some((path) => {
|
|
20989
|
+
try {
|
|
20990
|
+
return /\{(?:env|file):/.test(readFileSync7(path, "utf8"));
|
|
20991
|
+
} catch {
|
|
20992
|
+
return false;
|
|
20993
|
+
}
|
|
20994
|
+
});
|
|
20995
|
+
if (!dynamic) {
|
|
20996
|
+
if (configCache.size >= 64) {
|
|
20997
|
+
const oldest = configCache.keys().next().value;
|
|
20998
|
+
if (oldest !== undefined)
|
|
20999
|
+
configCache.delete(oldest);
|
|
21000
|
+
}
|
|
21001
|
+
configCache.set(directory, { key, detailed });
|
|
21002
|
+
} else
|
|
21003
|
+
configCache.delete(directory);
|
|
21004
|
+
return detailed;
|
|
21005
|
+
}
|
|
21006
|
+
async function ensureProjectRegisteredFromOpenCodeDirectory(directory, db) {
|
|
21007
|
+
const detailed = loadRegistrationConfig(directory);
|
|
20738
21008
|
const projectIdentity = resolveProjectIdentityForSession(directory, detailed.config.allow_home_project);
|
|
20739
21009
|
if (!projectIdentity)
|
|
20740
21010
|
return;
|
|
20741
|
-
invalidateProject(projectIdentity);
|
|
20742
21011
|
if (isConfigLoadUntrusted(detailed)) {
|
|
20743
21012
|
handleUntrustedLoad(db, projectIdentity, directory, detailed);
|
|
20744
21013
|
return;
|
|
@@ -20755,7 +21024,10 @@ async function ensureProjectRegisteredFromOpenCodeDirectory(directory, db) {
|
|
|
20755
21024
|
memoryEnabled: detailed.config.memory.enabled,
|
|
20756
21025
|
gitCommitEnabled: detailed.config.memory.git_commit_indexing.enabled
|
|
20757
21026
|
};
|
|
20758
|
-
|
|
21027
|
+
const before = getProjectEmbeddingSnapshot(projectIdentity);
|
|
21028
|
+
const registered = registerProjectEmbedding(db, projectIdentity, routing.primary, features, directory);
|
|
21029
|
+
if (!before || before.providerIdentity !== registered.providerIdentity || before.runtimeFingerprint !== registered.runtimeFingerprint)
|
|
21030
|
+
invalidateProject(projectIdentity);
|
|
20759
21031
|
if (routing.shadow) {
|
|
20760
21032
|
registerProjectShadowEmbedding(db, projectIdentity, routing.shadow, directory);
|
|
20761
21033
|
} else {
|
|
@@ -21090,6 +21362,12 @@ function resolveSessionId(properties) {
|
|
|
21090
21362
|
}
|
|
21091
21363
|
return;
|
|
21092
21364
|
}
|
|
21365
|
+
function historyBudgetPolicyIdentity(historyBudgetPercentage, executeThresholdPercentage, modelKey, executeThresholdTokens) {
|
|
21366
|
+
if (!historyBudgetPercentage)
|
|
21367
|
+
return "pdefault";
|
|
21368
|
+
const threshold = resolveExecuteThresholdDetail(executeThresholdPercentage ?? 65, modelKey, 65, { tokensConfig: executeThresholdTokens, contextLimit: Number.MAX_SAFE_INTEGER });
|
|
21369
|
+
return `p${historyBudgetPercentage}:${threshold.mode}:${threshold.absoluteTokens ?? threshold.percentage}`;
|
|
21370
|
+
}
|
|
21093
21371
|
|
|
21094
21372
|
// src/features/magic-context/scheduler.ts
|
|
21095
21373
|
var TTL_PATTERN = /^(\d+)([smh])$/;
|
|
@@ -21323,7 +21601,7 @@ async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
|
21323
21601
|
const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
|
|
21324
21602
|
const retainedMessages = fallbackSnapshot ?? messages;
|
|
21325
21603
|
heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
|
|
21326
|
-
indexMessagesAfterOrdinal(db, sessionId, messages, cursor, pageEnd);
|
|
21604
|
+
withSqliteBackgroundWriter(() => indexMessagesAfterOrdinal(db, sessionId, messages, cursor, pageEnd));
|
|
21327
21605
|
const nextCursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
|
|
21328
21606
|
if (nextCursor <= cursor)
|
|
21329
21607
|
break;
|
|
@@ -21349,6 +21627,8 @@ function scheduleReconciliation(db, sessionId, readMessages) {
|
|
|
21349
21627
|
defer(() => {
|
|
21350
21628
|
reconcileSessionIndex(db, sessionId, readMessages).catch((error) => {
|
|
21351
21629
|
logIndexingError(sessionId, "reconciliation", error);
|
|
21630
|
+
if (isDatabaseLockedError(error))
|
|
21631
|
+
setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000).unref();
|
|
21352
21632
|
}).finally(() => {
|
|
21353
21633
|
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
21354
21634
|
});
|
|
@@ -21378,7 +21658,7 @@ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
|
21378
21658
|
return;
|
|
21379
21659
|
}
|
|
21380
21660
|
const wasReconciled = heapHolder.reconciledSessions.delete(sessionId);
|
|
21381
|
-
indexSingleMessage(db, sessionId, message);
|
|
21661
|
+
withSqliteBackgroundWriter(() => indexSingleMessage(db, sessionId, message));
|
|
21382
21662
|
const finalWatermark = getLastIndexedOrdinal(db, sessionId);
|
|
21383
21663
|
if (wasReconciled && isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
|
|
21384
21664
|
heapHolder.reconciledSessions.add(sessionId);
|
|
@@ -21387,6 +21667,8 @@ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
|
21387
21667
|
}).catch((error) => {
|
|
21388
21668
|
heapHolder.reconciledSessions.delete(sessionId);
|
|
21389
21669
|
logIndexingError(sessionId, `incremental index for ${messageId}`, error);
|
|
21670
|
+
if (isDatabaseLockedError(error))
|
|
21671
|
+
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), 1000).unref();
|
|
21390
21672
|
}).finally(() => {
|
|
21391
21673
|
heapHolder.pendingIncrementalKeys.delete(schedulingKey);
|
|
21392
21674
|
});
|
|
@@ -24293,6 +24575,7 @@ function encodeOpenCodeMessagesToCk(messages) {
|
|
|
24293
24575
|
const synthetic = syntheticParts.length > 0 && syntheticParts.every((part) => part !== null && typeof part === "object" && (part.synthetic === true || part.syntheticTodoMarker === true));
|
|
24294
24576
|
const content = [];
|
|
24295
24577
|
const recoveryToolTitles = {};
|
|
24578
|
+
const userAnswerBlocks = [];
|
|
24296
24579
|
for (const partValue of parts) {
|
|
24297
24580
|
if (partValue === null || typeof partValue !== "object")
|
|
24298
24581
|
continue;
|
|
@@ -24340,6 +24623,8 @@ function encodeOpenCodeMessagesToCk(messages) {
|
|
|
24340
24623
|
if (title)
|
|
24341
24624
|
recoveryToolTitles[callId] = title;
|
|
24342
24625
|
const output = typeof state.output === "string" ? state.output : typeof state.error === "string" ? state.error : "";
|
|
24626
|
+
if (toolPartHasUserAnswer(part))
|
|
24627
|
+
userAnswerBlocks.push(content.length);
|
|
24343
24628
|
content.push({
|
|
24344
24629
|
kind: {
|
|
24345
24630
|
type: "tool_result",
|
|
@@ -24371,9 +24656,12 @@ function encodeOpenCodeMessagesToCk(messages) {
|
|
|
24371
24656
|
ck: {
|
|
24372
24657
|
role,
|
|
24373
24658
|
content,
|
|
24374
|
-
...Object.keys(recoveryToolTitles).length > 0 ? {
|
|
24659
|
+
...Object.keys(recoveryToolTitles).length > 0 || userAnswerBlocks.length > 0 ? {
|
|
24375
24660
|
provider_extras: {
|
|
24376
|
-
opencode: {
|
|
24661
|
+
opencode: {
|
|
24662
|
+
...Object.keys(recoveryToolTitles).length > 0 ? { ctx_expand_tool_titles: recoveryToolTitles } : {},
|
|
24663
|
+
...userAnswerBlocks.length > 0 ? { user_answer_block_indices: userAnswerBlocks } : {}
|
|
24664
|
+
}
|
|
24377
24665
|
}
|
|
24378
24666
|
} : {},
|
|
24379
24667
|
meta: {
|
|
@@ -25819,7 +26107,9 @@ function resolveConfigValue(cfg, key, modelKey, defaultValue) {
|
|
|
25819
26107
|
}
|
|
25820
26108
|
function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config, moduleStatus, compactionEnabled = true) {
|
|
25821
26109
|
try {
|
|
25822
|
-
const projectIdentity =
|
|
26110
|
+
const projectIdentity = resolveProjectIdentityForSession(directory);
|
|
26111
|
+
if (projectIdentity === undefined)
|
|
26112
|
+
throw new ProjectIdentityError("git_identity_unavailable", directory, "Memory features paused while project identity is unavailable");
|
|
25823
26113
|
const meta = db.prepare("SELECT * FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
25824
26114
|
const usagePercentage = meta ? Number(meta.last_context_percentage ?? meta.last_usage_percentage ?? 0) : 0;
|
|
25825
26115
|
const inputTokens = meta ? Number(meta.last_input_tokens ?? 0) : 0;
|
|
@@ -26023,11 +26313,16 @@ function buildSidebarSnapshot(db, sessionId, directory, liveSessionState, inject
|
|
|
26023
26313
|
};
|
|
26024
26314
|
return applyStickySnapshotCache(sessionId, fresh);
|
|
26025
26315
|
} catch (err) {
|
|
26026
|
-
|
|
26316
|
+
if (!(err instanceof ProjectIdentityError))
|
|
26317
|
+
log("[rpc] sidebar-snapshot error:", err);
|
|
26027
26318
|
throw err;
|
|
26028
26319
|
}
|
|
26029
26320
|
}
|
|
26030
26321
|
function buildSidebarSnapshotRpcResponse(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config, moduleStatus, compactionEnabled = true) {
|
|
26322
|
+
if (shouldSkipHomeProjectMemory(directory))
|
|
26323
|
+
return { sessionId, disabled: true };
|
|
26324
|
+
if (resolveProjectIdentityForSession(directory) === undefined)
|
|
26325
|
+
return { sessionId, disabled: true, paused: true };
|
|
26031
26326
|
try {
|
|
26032
26327
|
return buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config, moduleStatus, compactionEnabled);
|
|
26033
26328
|
} catch {
|
|
@@ -26044,7 +26339,7 @@ function safeTickFailure(db) {
|
|
|
26044
26339
|
function buildStatusDetail(db, sessionId, directory, modelKey, config, liveSessionState, injectionBudgetTokens, moduleStatus, compactionEnabled = true) {
|
|
26045
26340
|
const base = buildSidebarSnapshot(db, sessionId, directory, liveSessionState, injectionBudgetTokens, config, moduleStatus, compactionEnabled);
|
|
26046
26341
|
const rustMode = config?.transform_mode === "rust";
|
|
26047
|
-
const projectIdentity = rustMode ? resolveProjectIdentity(directory) : null;
|
|
26342
|
+
const projectIdentity = rustMode && !shouldSkipHomeProjectMemory(directory) ? resolveProjectIdentity(directory) : null;
|
|
26048
26343
|
const moduleMemoryAuthority = moduleStatus?.authority?.memories;
|
|
26049
26344
|
const moduleMemoryState = moduleMemoryAuthority?.state;
|
|
26050
26345
|
const moduleFeedHead = moduleStatus?.memory_mirror?.feed_head;
|
|
@@ -26487,6 +26782,10 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
26487
26782
|
rpcServer.handle("status-detail", async (params) => {
|
|
26488
26783
|
const sessionId = String(params.sessionId ?? "");
|
|
26489
26784
|
const dir = String(params.directory ?? directory);
|
|
26785
|
+
if (shouldSkipHomeProjectMemory(dir))
|
|
26786
|
+
return { sessionId, disabled: true };
|
|
26787
|
+
if (resolveProjectIdentityForSession(dir) === undefined)
|
|
26788
|
+
return { sessionId, disabled: true, paused: true };
|
|
26490
26789
|
const modelKey = params.modelKey ? String(params.modelKey) : undefined;
|
|
26491
26790
|
const db = readDatabase();
|
|
26492
26791
|
if (!db || !sessionId)
|
|
@@ -26507,6 +26806,10 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
26507
26806
|
rpcServer.handle("embed-detail", async (params) => {
|
|
26508
26807
|
const sessionId = String(params.sessionId ?? "");
|
|
26509
26808
|
const dir = String(params.directory ?? directory);
|
|
26809
|
+
if (shouldSkipHomeProjectMemory(dir))
|
|
26810
|
+
return { sessionId, disabled: true };
|
|
26811
|
+
if (resolveProjectIdentityForSession(dir) === undefined)
|
|
26812
|
+
return { sessionId, disabled: true, paused: true };
|
|
26510
26813
|
const db = readDatabase();
|
|
26511
26814
|
if (!db || !sessionId)
|
|
26512
26815
|
return { error: "unavailable" };
|
|
@@ -26534,7 +26837,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
26534
26837
|
return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
|
|
26535
26838
|
});
|
|
26536
26839
|
const buildManagedCtx = async (db) => {
|
|
26537
|
-
const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await import("./derive-budgets-
|
|
26840
|
+
const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await import("./derive-budgets-ncwn1jk9.js");
|
|
26538
26841
|
const { resolveHistorianModel } = await import("./model-resolution-dxatzjde.js");
|
|
26539
26842
|
const { userMemoryCollectionEnabled } = await import("./task-config-2bm68628.js");
|
|
26540
26843
|
const DEFAULT_HISTORIAN_TIMEOUT_MS = 600000;
|
|
@@ -26568,8 +26871,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
26568
26871
|
const db = readDatabase();
|
|
26569
26872
|
if (!db)
|
|
26570
26873
|
return { ok: false, error: "db unavailable" };
|
|
26571
|
-
const { runManagedRecomp } = await import("./recomp-orchestrator-
|
|
26572
|
-
const { sendIgnoredMessage } = await import("./send-session-notification-
|
|
26874
|
+
const { runManagedRecomp } = await import("./recomp-orchestrator-0ers6smx.js");
|
|
26875
|
+
const { sendIgnoredMessage } = await import("./send-session-notification-04hvd54c.js");
|
|
26573
26876
|
log(`[rpc] recomp requested for session ${sessionId}`);
|
|
26574
26877
|
const ctx = await buildManagedCtx(db);
|
|
26575
26878
|
runManagedRecomp(ctx, sessionId).then((message) => {
|
|
@@ -26627,7 +26930,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
26627
26930
|
const db = readDatabase();
|
|
26628
26931
|
if (!db)
|
|
26629
26932
|
return { ok: false, error: "db unavailable" };
|
|
26630
|
-
const { runManagedWrapup } = await import("./wrapup-orchestrator-
|
|
26933
|
+
const { runManagedWrapup } = await import("./wrapup-orchestrator-x0jvvrqn.js");
|
|
26631
26934
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
26632
26935
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
26633
26936
|
const ctx = {
|
|
@@ -27493,162 +27796,6 @@ class EmergencyFailClosedError extends Error {
|
|
|
27493
27796
|
}
|
|
27494
27797
|
}
|
|
27495
27798
|
|
|
27496
|
-
// src/hooks/magic-context/lkg-persist.ts
|
|
27497
|
-
function parseStringArray(value) {
|
|
27498
|
-
if (typeof value !== "string")
|
|
27499
|
-
return null;
|
|
27500
|
-
let parsed;
|
|
27501
|
-
try {
|
|
27502
|
-
parsed = JSON.parse(value);
|
|
27503
|
-
} catch {
|
|
27504
|
-
return null;
|
|
27505
|
-
}
|
|
27506
|
-
if (!Array.isArray(parsed))
|
|
27507
|
-
return null;
|
|
27508
|
-
const result = [];
|
|
27509
|
-
for (const entry of parsed) {
|
|
27510
|
-
if (typeof entry !== "string" || entry.length === 0)
|
|
27511
|
-
return null;
|
|
27512
|
-
result.push(entry);
|
|
27513
|
-
}
|
|
27514
|
-
return result;
|
|
27515
|
-
}
|
|
27516
|
-
function parseNullableString(value) {
|
|
27517
|
-
if (value === null || value === undefined)
|
|
27518
|
-
return null;
|
|
27519
|
-
return typeof value === "string" ? value : undefined;
|
|
27520
|
-
}
|
|
27521
|
-
function parseNullableInteger(value) {
|
|
27522
|
-
if (value === null || value === undefined)
|
|
27523
|
-
return;
|
|
27524
|
-
return typeof value === "number" && Number.isSafeInteger(value) ? value : undefined;
|
|
27525
|
-
}
|
|
27526
|
-
function parsePersistedLkgSlot(row) {
|
|
27527
|
-
if (!row || typeof row !== "object")
|
|
27528
|
-
return;
|
|
27529
|
-
const record = row;
|
|
27530
|
-
const jsonPrefix = record.json_prefix;
|
|
27531
|
-
const lastInputMessageId = record.last_input_message_id;
|
|
27532
|
-
const capturedAt = record.captured_at;
|
|
27533
|
-
let inputIdsRaw = record.input_id_seq;
|
|
27534
|
-
let piOutputEntryIds;
|
|
27535
|
-
if (typeof inputIdsRaw === "string") {
|
|
27536
|
-
try {
|
|
27537
|
-
const metadata = JSON.parse(inputIdsRaw);
|
|
27538
|
-
if (metadata && !Array.isArray(metadata) && metadata.version === 1 && Array.isArray(metadata.piOutputEntryIds)) {
|
|
27539
|
-
if (!metadata.piOutputEntryIds.every((id) => id === null || typeof id === "string" && id.length > 0))
|
|
27540
|
-
return;
|
|
27541
|
-
piOutputEntryIds = metadata.piOutputEntryIds;
|
|
27542
|
-
inputIdsRaw = JSON.stringify(metadata.inputIds);
|
|
27543
|
-
}
|
|
27544
|
-
} catch {
|
|
27545
|
-
return;
|
|
27546
|
-
}
|
|
27547
|
-
}
|
|
27548
|
-
const inputIdSeq = parseStringArray(inputIdsRaw);
|
|
27549
|
-
const inputContentDigests = parseStringArray(record.input_content_digests);
|
|
27550
|
-
const modelKey = parseNullableString(record.model_key);
|
|
27551
|
-
const providerKey = parseNullableString(record.provider_key);
|
|
27552
|
-
if (typeof jsonPrefix !== "string" || typeof lastInputMessageId !== "string" || lastInputMessageId.length === 0 || typeof capturedAt !== "number" || !Number.isFinite(capturedAt) || inputIdSeq === null || inputContentDigests === null || inputContentDigests.length !== inputIdSeq.length || modelKey === undefined || providerKey === undefined) {
|
|
27553
|
-
return;
|
|
27554
|
-
}
|
|
27555
|
-
if (piOutputEntryIds) {
|
|
27556
|
-
try {
|
|
27557
|
-
const output = JSON.parse(jsonPrefix);
|
|
27558
|
-
const inputs = new Set(inputIdSeq);
|
|
27559
|
-
if (!Array.isArray(output) || output.length !== piOutputEntryIds.length || piOutputEntryIds.some((id) => id !== null && !inputs.has(id)))
|
|
27560
|
-
return;
|
|
27561
|
-
} catch {
|
|
27562
|
-
return;
|
|
27563
|
-
}
|
|
27564
|
-
}
|
|
27565
|
-
let inputContentSignatures;
|
|
27566
|
-
if (record.input_content_signatures !== null && record.input_content_signatures !== undefined) {
|
|
27567
|
-
const parsed = parseStringArray(record.input_content_signatures);
|
|
27568
|
-
if (parsed === null || parsed.length !== inputIdSeq.length)
|
|
27569
|
-
return;
|
|
27570
|
-
inputContentSignatures = parsed;
|
|
27571
|
-
}
|
|
27572
|
-
const slot = {
|
|
27573
|
-
jsonPrefix,
|
|
27574
|
-
inputIdSeq,
|
|
27575
|
-
inputContentDigests,
|
|
27576
|
-
lastInputMessageId,
|
|
27577
|
-
modelKey,
|
|
27578
|
-
providerKey,
|
|
27579
|
-
capturedAt
|
|
27580
|
-
};
|
|
27581
|
-
if (inputContentSignatures)
|
|
27582
|
-
slot.inputContentSignatures = inputContentSignatures;
|
|
27583
|
-
if (piOutputEntryIds)
|
|
27584
|
-
slot.piOutputEntryIds = piOutputEntryIds;
|
|
27585
|
-
const rowVersion = parseNullableInteger(record.row_version);
|
|
27586
|
-
if (rowVersion !== undefined)
|
|
27587
|
-
slot.rowVersion = rowVersion;
|
|
27588
|
-
const captureSequence = parseNullableInteger(record.capture_sequence);
|
|
27589
|
-
if (captureSequence !== undefined)
|
|
27590
|
-
slot.captureSequence = captureSequence;
|
|
27591
|
-
return slot;
|
|
27592
|
-
}
|
|
27593
|
-
function saveLkgSlotToDb(db, sessionId, slot) {
|
|
27594
|
-
try {
|
|
27595
|
-
db.prepare(`INSERT INTO lkg_slots (
|
|
27596
|
-
session_id, json_prefix, input_id_seq, input_content_digests,
|
|
27597
|
-
input_content_signatures, last_input_message_id, model_key, provider_key,
|
|
27598
|
-
captured_at, row_version, capture_sequence
|
|
27599
|
-
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
27600
|
-
ON CONFLICT(session_id) DO UPDATE SET
|
|
27601
|
-
json_prefix = excluded.json_prefix,
|
|
27602
|
-
input_id_seq = excluded.input_id_seq,
|
|
27603
|
-
input_content_digests = excluded.input_content_digests,
|
|
27604
|
-
input_content_signatures = excluded.input_content_signatures,
|
|
27605
|
-
last_input_message_id = excluded.last_input_message_id,
|
|
27606
|
-
model_key = excluded.model_key,
|
|
27607
|
-
provider_key = excluded.provider_key,
|
|
27608
|
-
captured_at = excluded.captured_at,
|
|
27609
|
-
row_version = excluded.row_version,
|
|
27610
|
-
capture_sequence = excluded.capture_sequence`).run(sessionId, slot.jsonPrefix, JSON.stringify(slot.piOutputEntryIds ? {
|
|
27611
|
-
version: 1,
|
|
27612
|
-
inputIds: slot.inputIdSeq,
|
|
27613
|
-
piOutputEntryIds: slot.piOutputEntryIds
|
|
27614
|
-
} : slot.inputIdSeq), JSON.stringify(slot.inputContentDigests), slot.inputContentSignatures ? JSON.stringify(slot.inputContentSignatures) : null, slot.lastInputMessageId, slot.modelKey, slot.providerKey, slot.capturedAt, slot.rowVersion ?? null, slot.captureSequence ?? null);
|
|
27615
|
-
return true;
|
|
27616
|
-
} catch (error) {
|
|
27617
|
-
sessionLog(sessionId, "LKG snapshot persistence failed (in-memory slot retained):", error);
|
|
27618
|
-
return false;
|
|
27619
|
-
}
|
|
27620
|
-
}
|
|
27621
|
-
function clearPersistedLkgSlot(db, sessionId) {
|
|
27622
|
-
try {
|
|
27623
|
-
db.prepare("DELETE FROM lkg_slots WHERE session_id = ?").run(sessionId);
|
|
27624
|
-
} catch (error) {
|
|
27625
|
-
sessionLog(sessionId, "LKG snapshot durable clear failed:", error);
|
|
27626
|
-
}
|
|
27627
|
-
}
|
|
27628
|
-
function loadPersistedLkgSlot(db, sessionId) {
|
|
27629
|
-
let row;
|
|
27630
|
-
try {
|
|
27631
|
-
row = db.prepare("SELECT * FROM lkg_slots WHERE session_id = ?").get(sessionId);
|
|
27632
|
-
} catch (error) {
|
|
27633
|
-
sessionLog(sessionId, "LKG snapshot durable load failed:", error);
|
|
27634
|
-
return;
|
|
27635
|
-
}
|
|
27636
|
-
if (!row)
|
|
27637
|
-
return;
|
|
27638
|
-
const slot = parsePersistedLkgSlot(row);
|
|
27639
|
-
if (!slot) {
|
|
27640
|
-
clearPersistedLkgSlot(db, sessionId);
|
|
27641
|
-
return;
|
|
27642
|
-
}
|
|
27643
|
-
return slot;
|
|
27644
|
-
}
|
|
27645
|
-
function createDbLkgPersistence(db) {
|
|
27646
|
-
return {
|
|
27647
|
-
load: (sessionId) => loadPersistedLkgSlot(db, sessionId),
|
|
27648
|
-
clear: (sessionId) => clearPersistedLkgSlot(db, sessionId)
|
|
27649
|
-
};
|
|
27650
|
-
}
|
|
27651
|
-
|
|
27652
27799
|
// src/hooks/magic-context/openai-compat-adjacency.ts
|
|
27653
27800
|
function assertOpenAiCompatAdjacency(messages) {
|
|
27654
27801
|
const violations = [];
|
|
@@ -28210,7 +28357,7 @@ function createPassOutcome() {
|
|
|
28210
28357
|
}
|
|
28211
28358
|
|
|
28212
28359
|
// src/hooks/magic-context/rust-mode-transform.ts
|
|
28213
|
-
import { createHash as
|
|
28360
|
+
import { createHash as createHash13, randomUUID as randomUUID6 } from "node:crypto";
|
|
28214
28361
|
|
|
28215
28362
|
// src/features/magic-context/memory/mirror-reembed.ts
|
|
28216
28363
|
async function reembedMirrorInvalidatedMemories(db) {
|
|
@@ -28674,13 +28821,16 @@ class HistorianHostRunner {
|
|
|
28674
28821
|
this.log(`producer window unknown for ${key}: sending unguarded`);
|
|
28675
28822
|
}
|
|
28676
28823
|
const output = provider && parts.length ? getSdkOutputLimit(provider, parts.join("/")) : undefined;
|
|
28677
|
-
const
|
|
28824
|
+
const producerLimits = resolveHistorianProducerLimits2(key);
|
|
28825
|
+
const context = producerLimits.context ?? (producerLimits.input === undefined ? window : undefined);
|
|
28826
|
+
const reserve = historianProducerReserve(context, undefined, output);
|
|
28678
28827
|
const failure = producerPromptFailureReason({
|
|
28679
28828
|
sourceLocal: estimateTokens(claim.user),
|
|
28680
28829
|
systemLocal: estimateTokens(claim.system),
|
|
28681
28830
|
toolsLocal: 0,
|
|
28682
28831
|
modelKey: key,
|
|
28683
|
-
contextLimitTokens:
|
|
28832
|
+
contextLimitTokens: context,
|
|
28833
|
+
inputLimitTokens: producerLimits.input,
|
|
28684
28834
|
maxOutputTokens: reserve
|
|
28685
28835
|
});
|
|
28686
28836
|
if (failure)
|
|
@@ -28790,6 +28940,16 @@ class RawFallbackContextLimitError extends Error {
|
|
|
28790
28940
|
|
|
28791
28941
|
// src/hooks/magic-context/storage-busy-refusal.ts
|
|
28792
28942
|
var STORAGE_BUSY_MESSAGE = "Magic Context's database is busy (another process held it too long); send your message again.";
|
|
28943
|
+
function describeStorageBusyCause(cause) {
|
|
28944
|
+
let original = cause;
|
|
28945
|
+
for (let depth = 0;original instanceof SqliteAcquisitionBusyError && depth < 5; depth++) {
|
|
28946
|
+
original = original.cause;
|
|
28947
|
+
}
|
|
28948
|
+
if (!(original instanceof Error))
|
|
28949
|
+
return String(original);
|
|
28950
|
+
return original.stack ? `${original.message}
|
|
28951
|
+
${original.stack}` : original.message;
|
|
28952
|
+
}
|
|
28793
28953
|
|
|
28794
28954
|
class StorageBusyRefusalError extends Error {
|
|
28795
28955
|
code = "STORAGE_BUSY_REFUSAL";
|
|
@@ -28797,8 +28957,7 @@ class StorageBusyRefusalError extends Error {
|
|
|
28797
28957
|
constructor(cause, stage) {
|
|
28798
28958
|
super(STORAGE_BUSY_MESSAGE, { cause });
|
|
28799
28959
|
this.name = "StorageBusyRefusalError";
|
|
28800
|
-
const
|
|
28801
|
-
const detail = original instanceof Error ? original.stack ?? original.message : String(original);
|
|
28960
|
+
const detail = describeStorageBusyCause(cause);
|
|
28802
28961
|
log(`[magic-context] storage-busy refusal stage=${stage}${cause instanceof SqliteAcquisitionBusyError ? ` acquisition=${cause.stage}` : ""}: ${detail}`);
|
|
28803
28962
|
}
|
|
28804
28963
|
}
|
|
@@ -29087,10 +29246,10 @@ function messageCacheSignature(message) {
|
|
|
29087
29246
|
const parts = Array.isArray(message.parts) ? message.parts : [];
|
|
29088
29247
|
const serializedParts = JSON.stringify(parts) ?? "null";
|
|
29089
29248
|
const serializedMessage = JSON.stringify(message) ?? "null";
|
|
29090
|
-
return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${
|
|
29249
|
+
return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${createHash13("sha256").update(serializedMessage).digest("hex")}`;
|
|
29091
29250
|
}
|
|
29092
29251
|
function advanceWireFingerprint(previous, encoded) {
|
|
29093
|
-
return
|
|
29252
|
+
return createHash13("sha256").update(previous).update("\\0").update(JSON.stringify(encoded) ?? "null").digest("hex");
|
|
29094
29253
|
}
|
|
29095
29254
|
function buildWireFingerprint(encoded) {
|
|
29096
29255
|
let fingerprint = "rust-wire-v1";
|
|
@@ -29446,7 +29605,7 @@ function canonicalizeForChecksum(value) {
|
|
|
29446
29605
|
return Object.fromEntries(Object.keys(value).sort().map((key) => [key, canonicalizeForChecksum(value[key])]));
|
|
29447
29606
|
}
|
|
29448
29607
|
function checksumSeedRows(rows) {
|
|
29449
|
-
return
|
|
29608
|
+
return createHash13("sha256").update(JSON.stringify(rows.map(canonicalizeForChecksum))).digest("hex");
|
|
29450
29609
|
}
|
|
29451
29610
|
function authoritySeedRows(db, projectPath, domain) {
|
|
29452
29611
|
const snapshots = domain === "memories" ? db.prepare("SELECT * FROM memories WHERE project_path = ? ORDER BY id ASC").all(projectPath) : db.prepare(`SELECT n.*
|
|
@@ -29674,13 +29833,15 @@ function resolvedHistorianModelLimits(chain) {
|
|
|
29674
29833
|
return Object.fromEntries(chain.map((key) => {
|
|
29675
29834
|
const [provider, ...parts] = key.split("/");
|
|
29676
29835
|
const output = provider && parts.length ? getSdkOutputLimit(provider, parts.join("/")) : undefined;
|
|
29677
|
-
const
|
|
29836
|
+
const producerLimits = resolveHistorianProducerLimits2(key);
|
|
29837
|
+
const known = producerLimits.input === undefined ? resolveKnownHistorianContextLimit2(key) : undefined;
|
|
29678
29838
|
const learned = provider && parts.length ? getSdkWindowGeometry(provider, parts.join("/"))?.derivation.window : undefined;
|
|
29679
|
-
const context = known === undefined ? learned : learned === undefined ? known : Math.min(known, learned);
|
|
29839
|
+
const context = producerLimits.context ?? (known === undefined ? learned : learned === undefined ? known : Math.min(known, learned));
|
|
29680
29840
|
return [
|
|
29681
29841
|
key,
|
|
29682
29842
|
{
|
|
29683
29843
|
...context !== undefined ? { context } : {},
|
|
29844
|
+
...producerLimits.input !== undefined ? { input: producerLimits.input } : {},
|
|
29684
29845
|
...output !== undefined ? { output } : {}
|
|
29685
29846
|
}
|
|
29686
29847
|
];
|
|
@@ -31083,6 +31244,16 @@ function createRustModeTransform(deps, options) {
|
|
|
31083
31244
|
}
|
|
31084
31245
|
pendingWireCache.nativeOutput = moduleMessages;
|
|
31085
31246
|
if (!replayedFrozenRepresentation) {
|
|
31247
|
+
if (materializedBoundary && !deps.compactionOff) {
|
|
31248
|
+
try {
|
|
31249
|
+
await withAsyncPrivilegedWriter(deps.db, () => {
|
|
31250
|
+
return;
|
|
31251
|
+
});
|
|
31252
|
+
} catch (error) {
|
|
31253
|
+
if (!isTransientSqliteError(error))
|
|
31254
|
+
throw error;
|
|
31255
|
+
}
|
|
31256
|
+
}
|
|
31086
31257
|
const postprocess = runRustModePostprocess2({
|
|
31087
31258
|
db: deps.db,
|
|
31088
31259
|
sessionId,
|
|
@@ -31307,7 +31478,7 @@ function createRustModeTransform(deps, options) {
|
|
|
31307
31478
|
if (mirrorDrain.rowsApplied > 0) {
|
|
31308
31479
|
await reembedMirrorInvalidatedMemories(deps.db);
|
|
31309
31480
|
}
|
|
31310
|
-
await drainSingleStoreEmbeddingWatermarks(deps.db);
|
|
31481
|
+
await withSqliteBackgroundWriter(() => drainSingleStoreEmbeddingWatermarks(deps.db));
|
|
31311
31482
|
if (mirrorDrain.complete) {
|
|
31312
31483
|
state.memoryMirrorProjectionKey = projectionKey;
|
|
31313
31484
|
} else if (mirrorDrain.budgetExhausted) {
|
|
@@ -32255,7 +32426,9 @@ function createTransform(deps) {
|
|
|
32255
32426
|
const persistedUsageFreshForBoundary = persistedUsageBeforeResets && Date.now() - persistedUsageBeforeResets.updatedAt <= 10 * 60 * 1000 && (persistedUsageBeforeResets.lastObservedModelKey === null || currentModelKeyForBoundary === undefined || piModelRefToCanonical(persistedUsageBeforeResets.lastObservedModelKey) === piModelRefToCanonical(currentModelKeyForBoundary)) && (resolvedContextLimit === undefined || persistedUsageBeforeResets.lastUsageContextLimit === 0 || persistedUsageBeforeResets.lastUsageContextLimit === resolvedContextLimit) ? persistedUsageBeforeResets.usage : null;
|
|
32256
32427
|
const boundaryUsageForProtectedTail = persistedUsageFreshForBoundary ?? contextUsageEarly;
|
|
32257
32428
|
const boundaryUsageSource = persistedUsageFreshForBoundary ? "persisted" : "live";
|
|
32258
|
-
const
|
|
32429
|
+
const historyPolicyIdentity = historyBudgetPolicyIdentity(deps.historyBudgetPercentage, deps.executeThresholdPercentage, currentModelKeyForBoundary, deps.executeThresholdTokens);
|
|
32430
|
+
const historyContextLimit = resolvedContextLimit ?? (currentModelKeyForBoundary && persistedUsageBeforeResets?.lastObservedModelKey && piModelRefToCanonical(currentModelKeyForBoundary) === piModelRefToCanonical(persistedUsageBeforeResets.lastObservedModelKey) && persistedUsageBeforeResets.lastUsageContextLimit > 0 ? persistedUsageBeforeResets.lastUsageContextLimit : undefined);
|
|
32431
|
+
const historyBudgetTokens = resolveHistoryBudgetTokens(deps.historyBudgetPercentage, contextUsageEarly, deps.executeThresholdPercentage, deps.getModelKey?.(sessionId), deps.executeThresholdTokens, historyContextLimit);
|
|
32259
32432
|
const emergencyCeilingLimit = thresholdContextLimit ?? 0;
|
|
32260
32433
|
const emergencyCeilingTokens = Number.isFinite(emergencyCeilingLimit) && emergencyCeilingLimit > 0 ? Math.floor(emergencyCeilingLimit * (effectiveExecuteThresholdPercentage / 100)) : undefined;
|
|
32261
32434
|
const schedulerDecision = compactionOff ? "defer" : resolveSchedulerDecision(deps.scheduler, sessionMeta, contextUsageEarly, sessionId, deps.getModelKey?.(sessionId), resolvedContextLimit);
|
|
@@ -32629,6 +32802,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
32629
32802
|
muralEnabled: deps.muralEnabled,
|
|
32630
32803
|
memoryInjectionBudgetTokens: deps.memoryConfig?.injectionBudgetTokens,
|
|
32631
32804
|
historyBudgetTokens,
|
|
32805
|
+
historyBudgetPolicyIdentity: historyPolicyIdentity,
|
|
32632
32806
|
hardSignals: m0HardSignals
|
|
32633
32807
|
}).value;
|
|
32634
32808
|
const protectionCacheBustingPass = !compactionOff && (schedulerDecision === "execute" || isCacheBusting || contextUsage.percentage >= forceMaterializationPercentage || deps.pendingMaterializationSessions.has(sessionId) || canConsumeDeferredLate && deferredMaterializationSessions.has(sessionId) || protectionFoldWillBust);
|
|
@@ -32752,6 +32926,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
32752
32926
|
memoryEnabled: deps.memoryConfig?.enabled,
|
|
32753
32927
|
memoryInjectionBudgetTokens: deps.memoryConfig?.injectionBudgetTokens,
|
|
32754
32928
|
historyBudgetTokens,
|
|
32929
|
+
historyBudgetPolicyIdentity: historyPolicyIdentity,
|
|
32755
32930
|
temporalAwareness: deps.experimentalTemporalAwareness,
|
|
32756
32931
|
hardSignals: m0HardSignals,
|
|
32757
32932
|
muralEnabled: deps.muralEnabled
|
|
@@ -34241,7 +34416,7 @@ function createTextCompleteHandler() {
|
|
|
34241
34416
|
}
|
|
34242
34417
|
|
|
34243
34418
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
34244
|
-
import { createHash as
|
|
34419
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
34245
34420
|
var MAGIC_CONTEXT_MARKER = "## Magic Context";
|
|
34246
34421
|
var SYSTEM_PROMPT_GUIDANCE_SEPARATOR = `
|
|
34247
34422
|
|
|
@@ -34338,7 +34513,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
34338
34513
|
}
|
|
34339
34514
|
const stickyDate = stickyDateBySession.get(sessionId);
|
|
34340
34515
|
const stableCandidate = currentDate && stickyDate && currentDate !== stickyDate ? liveSystemContent.replace(DATE_PATTERN_ALL, stickyDate) : liveSystemContent;
|
|
34341
|
-
const stableCandidateHash =
|
|
34516
|
+
const stableCandidateHash = createHash14("md5").update(promptSurfaceHashMaterial(stableCandidate, promptSurface.preset)).digest("hex");
|
|
34342
34517
|
const contentOrPresetChanged = hasPersistedHash && stableCandidateHash !== previousHash;
|
|
34343
34518
|
const dateMayAdvance = isCacheBusting || contentOrPresetChanged;
|
|
34344
34519
|
if (currentDate && !stickyDate) {
|
|
@@ -34358,7 +34533,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
34358
34533
|
`);
|
|
34359
34534
|
if (!availability.frozen || !modelKey)
|
|
34360
34535
|
return;
|
|
34361
|
-
const currentHash =
|
|
34536
|
+
const currentHash = createHash14("md5").update(promptSurfaceHashMaterial(systemContent, promptSurface.preset)).digest("hex");
|
|
34362
34537
|
if (!sessionMetaEarly) {
|
|
34363
34538
|
return;
|
|
34364
34539
|
}
|
|
@@ -35283,6 +35458,13 @@ function createMessagesTransformHandler(args) {
|
|
|
35283
35458
|
}
|
|
35284
35459
|
})() : null;
|
|
35285
35460
|
try {
|
|
35461
|
+
if (!args.compactionOff && magicContext) {
|
|
35462
|
+
const admissionDb = openDatabase();
|
|
35463
|
+
if (admissionDb)
|
|
35464
|
+
await withAsyncPrivilegedWriter(admissionDb, () => {
|
|
35465
|
+
return;
|
|
35466
|
+
});
|
|
35467
|
+
}
|
|
35286
35468
|
await magicContext?.["experimental.chat.messages.transform"]?.(input, output);
|
|
35287
35469
|
return output.messages;
|
|
35288
35470
|
} catch (error) {
|
|
@@ -37433,7 +37615,7 @@ Keep: user messages (never stamp one for its directive), your own conversation t
|
|
|
37433
37615
|
|
|
37434
37616
|
Look at each tag before stamping it; never blanket-stamp a range like "1-50". Many small targeted stamps beat one sweep. \`drop\` accepts "3-5", "1,2,9", "1-5,8,12-15".`;
|
|
37435
37617
|
// src/tools/ctx-reduce/tools.ts
|
|
37436
|
-
import { createHash as
|
|
37618
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
37437
37619
|
import { tool as tool4 } from "@opencode-ai/plugin";
|
|
37438
37620
|
|
|
37439
37621
|
// src/features/magic-context/range-parser.ts
|
|
@@ -37503,11 +37685,11 @@ function createCtxReduceTool(deps) {
|
|
|
37503
37685
|
const stableId = `oc-${sessionId}-${callId}`;
|
|
37504
37686
|
if (Buffer.byteLength(stableId) <= 128)
|
|
37505
37687
|
return stableId;
|
|
37506
|
-
return `oc-${
|
|
37688
|
+
return `oc-${createHash15("sha256").update(stableId).digest("hex")}`;
|
|
37507
37689
|
}
|
|
37508
37690
|
fallbackCommandSequence += 1;
|
|
37509
37691
|
const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
|
|
37510
|
-
return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${
|
|
37692
|
+
return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash15("sha256").update(monotonicId).digest("hex")}`;
|
|
37511
37693
|
};
|
|
37512
37694
|
return tool4({
|
|
37513
37695
|
description: CTX_REDUCE_DESCRIPTION,
|
|
@@ -38071,7 +38253,7 @@ import {
|
|
|
38071
38253
|
chmodSync as chmodSync2,
|
|
38072
38254
|
mkdirSync as mkdirSync5,
|
|
38073
38255
|
readdirSync as readdirSync2,
|
|
38074
|
-
readFileSync as
|
|
38256
|
+
readFileSync as readFileSync8,
|
|
38075
38257
|
renameSync as renameSync5,
|
|
38076
38258
|
rmSync as rmSync5,
|
|
38077
38259
|
unlinkSync,
|
|
@@ -38218,7 +38400,7 @@ class MagicContextRpcServer {
|
|
|
38218
38400
|
for (const entry of readdirSync2(this.portDir)) {
|
|
38219
38401
|
if (!entry.startsWith("port-") || !entry.endsWith(".json"))
|
|
38220
38402
|
continue;
|
|
38221
|
-
const record = parseRpcPortFile(
|
|
38403
|
+
const record = parseRpcPortFile(readFileSync8(`${this.portDir}/${entry}`, "utf-8"));
|
|
38222
38404
|
if (!record || record.pid === process.pid)
|
|
38223
38405
|
continue;
|
|
38224
38406
|
const processes = await inspectProcessesAsync();
|
|
@@ -38534,8 +38716,8 @@ function hostMediaAsset(data, mediaType) {
|
|
|
38534
38716
|
}
|
|
38535
38717
|
|
|
38536
38718
|
// src/v2/fold/owner.ts
|
|
38537
|
-
import { createHash as
|
|
38538
|
-
var foldDigest = (value) =>
|
|
38719
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
38720
|
+
var foldDigest = (value) => createHash16("sha256").update(value).digest("hex");
|
|
38539
38721
|
|
|
38540
38722
|
class FoldOwner {
|
|
38541
38723
|
storage;
|
|
@@ -38838,7 +39020,7 @@ ${data.output?.output ?? ""}`
|
|
|
38838
39020
|
}
|
|
38839
39021
|
|
|
38840
39022
|
// src/v2/host-service.ts
|
|
38841
|
-
import { readdirSync as readdirSync3, readFileSync as
|
|
39023
|
+
import { readdirSync as readdirSync3, readFileSync as readFileSync9 } from "node:fs";
|
|
38842
39024
|
import { homedir as homedir3 } from "node:os";
|
|
38843
39025
|
import { join as join11 } from "node:path";
|
|
38844
39026
|
|
|
@@ -39009,7 +39191,7 @@ class V2StoreReader {
|
|
|
39009
39191
|
return { rows, cursor: rows.at(-1)?.seq };
|
|
39010
39192
|
});
|
|
39011
39193
|
}
|
|
39012
|
-
messagePage(sessionID, afterOrdinal, limit, finalWatermark) {
|
|
39194
|
+
messagePage(sessionID, afterOrdinal, limit, finalWatermark, after) {
|
|
39013
39195
|
return trackDecodeOperation("messagePage", () => {
|
|
39014
39196
|
if (!Number.isSafeInteger(afterOrdinal) || afterOrdinal < 0)
|
|
39015
39197
|
throw new Error("Invalid raw-message ordinal cursor");
|
|
@@ -39020,6 +39202,14 @@ class V2StoreReader {
|
|
|
39020
39202
|
const pageSize = Math.min(limit, finalWatermark - afterOrdinal);
|
|
39021
39203
|
if (pageSize <= 0)
|
|
39022
39204
|
return [];
|
|
39205
|
+
if (after) {
|
|
39206
|
+
const anchor = this.db.prepare("SELECT seq FROM session_message WHERE session_id = ? AND id = ?").get(sessionID, after.id);
|
|
39207
|
+
if (anchor) {
|
|
39208
|
+
return this.db.prepare(`SELECT id, session_id, type, seq, time_created, data
|
|
39209
|
+
FROM session_message WHERE session_id = ? AND seq > ?
|
|
39210
|
+
AND type IN (${RAW_MESSAGE_TYPE_PARAMETERS}) ORDER BY seq ASC LIMIT ?`).all(sessionID, anchor.seq, ...RAW_MESSAGE_TYPES, pageSize).map(decode);
|
|
39211
|
+
}
|
|
39212
|
+
}
|
|
39023
39213
|
const maximumSeq = Number.MAX_SAFE_INTEGER;
|
|
39024
39214
|
const rows = this.db.prepare(V2_MESSAGE_PAGE_SQL).all(afterOrdinal, sessionID, ...RAW_MESSAGE_TYPES, Math.max(0, afterOrdinal - 1), sessionID, ...RAW_MESSAGE_TYPES, finalWatermark - 1, maximumSeq, sessionID, ...RAW_MESSAGE_TYPES, pageSize);
|
|
39025
39215
|
return rows.map(decode);
|
|
@@ -39254,7 +39444,7 @@ class HostServiceUnavailable extends Error {
|
|
|
39254
39444
|
function parseRegistration(path) {
|
|
39255
39445
|
let text;
|
|
39256
39446
|
try {
|
|
39257
|
-
text =
|
|
39447
|
+
text = readFileSync9(path, "utf8");
|
|
39258
39448
|
} catch {
|
|
39259
39449
|
return;
|
|
39260
39450
|
}
|
|
@@ -39368,8 +39558,8 @@ var POLL_INTERVAL_MS = 200;
|
|
|
39368
39558
|
var REMOVAL_SPACING_MS = 250;
|
|
39369
39559
|
var RETIRED_CHILDREN_LIMIT = 200;
|
|
39370
39560
|
var LEGACY_CLEANUP_BOOT_LIMIT = 5;
|
|
39371
|
-
function hiddenChildrenMetaKey(projectIdentity) {
|
|
39372
|
-
return `${META_PREFIX}${projectIdentity}`;
|
|
39561
|
+
function hiddenChildrenMetaKey(projectIdentity, directory) {
|
|
39562
|
+
return directory === undefined ? `${META_PREFIX}${projectIdentity}` : `${META_PREFIX}${JSON.stringify([projectIdentity, directory])}`;
|
|
39373
39563
|
}
|
|
39374
39564
|
function emptyMeta() {
|
|
39375
39565
|
return { version: 1, active: {}, retired_children: [] };
|
|
@@ -39431,9 +39621,49 @@ function parseMeta(value) {
|
|
|
39431
39621
|
class HiddenChildStateStore {
|
|
39432
39622
|
db;
|
|
39433
39623
|
key;
|
|
39434
|
-
constructor(db, projectIdentity) {
|
|
39624
|
+
constructor(db, projectIdentity, directory) {
|
|
39435
39625
|
this.db = db;
|
|
39436
|
-
this.key = hiddenChildrenMetaKey(projectIdentity);
|
|
39626
|
+
this.key = hiddenChildrenMetaKey(projectIdentity, directory);
|
|
39627
|
+
this.legacyKey = hiddenChildrenMetaKey(projectIdentity);
|
|
39628
|
+
}
|
|
39629
|
+
legacyKey;
|
|
39630
|
+
migrateStale(isStale) {
|
|
39631
|
+
this.db.transaction(() => {
|
|
39632
|
+
const legacyRow = this.db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(this.legacyKey);
|
|
39633
|
+
if (!legacyRow)
|
|
39634
|
+
return;
|
|
39635
|
+
const legacy = parseMeta(legacyRow.value);
|
|
39636
|
+
const scoped = this.read();
|
|
39637
|
+
for (const role of ["historian", "dreamer"]) {
|
|
39638
|
+
const child = legacy.active[role];
|
|
39639
|
+
if (!child || !isStale(child))
|
|
39640
|
+
continue;
|
|
39641
|
+
scoped.retired_children.push({
|
|
39642
|
+
...child,
|
|
39643
|
+
retired_at: Date.now(),
|
|
39644
|
+
reason: "legacy-directory-scope"
|
|
39645
|
+
});
|
|
39646
|
+
delete legacy.active[role];
|
|
39647
|
+
}
|
|
39648
|
+
const remaining = [];
|
|
39649
|
+
for (const child of legacy.retired_children) {
|
|
39650
|
+
if (isStale(child))
|
|
39651
|
+
scoped.retired_children.push(child);
|
|
39652
|
+
else
|
|
39653
|
+
remaining.push(child);
|
|
39654
|
+
}
|
|
39655
|
+
legacy.retired_children = remaining;
|
|
39656
|
+
const excess = scoped.retired_children.length - RETIRED_CHILDREN_LIMIT;
|
|
39657
|
+
if (excess > 0)
|
|
39658
|
+
scoped.retired_children.splice(0, excess);
|
|
39659
|
+
this.db.prepare(`INSERT INTO schema_migrations_meta (key, value) VALUES (?, ?)
|
|
39660
|
+
ON CONFLICT(key) DO UPDATE SET value = excluded.value`).run(this.key, JSON.stringify(scoped));
|
|
39661
|
+
if (Object.keys(legacy.active).length === 0 && legacy.retired_children.length === 0) {
|
|
39662
|
+
this.db.prepare("DELETE FROM schema_migrations_meta WHERE key = ?").run(this.legacyKey);
|
|
39663
|
+
} else {
|
|
39664
|
+
this.db.prepare("UPDATE schema_migrations_meta SET value = ? WHERE key = ?").run(JSON.stringify(legacy), this.legacyKey);
|
|
39665
|
+
}
|
|
39666
|
+
}).immediate();
|
|
39437
39667
|
}
|
|
39438
39668
|
read() {
|
|
39439
39669
|
const row = this.db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(this.key);
|
|
@@ -39660,6 +39890,12 @@ async function sleepUntilPoll(signal, deadline) {
|
|
|
39660
39890
|
}, delay);
|
|
39661
39891
|
});
|
|
39662
39892
|
}
|
|
39893
|
+
function isProviderFailure(error) {
|
|
39894
|
+
if (!error || typeof error !== "object")
|
|
39895
|
+
return false;
|
|
39896
|
+
const type = error.type;
|
|
39897
|
+
return typeof type === "string" && (type.startsWith("provider.") || type.toLowerCase().includes("provider"));
|
|
39898
|
+
}
|
|
39663
39899
|
async function awaitAssistantRow(openReader, readSessionError, stepLimit, childID, afterSeq, deadline, signal) {
|
|
39664
39900
|
for (;; ) {
|
|
39665
39901
|
const { assistant, idle } = withReader(openReader, (reader) => ({
|
|
@@ -39680,7 +39916,7 @@ async function awaitAssistantRow(openReader, readSessionError, stepLimit, childI
|
|
|
39680
39916
|
`terminal_row=${errorText(newIdle)}`,
|
|
39681
39917
|
`session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
|
|
39682
39918
|
];
|
|
39683
|
-
throw sessionError === undefined ? new Error(`Hidden completion failed
|
|
39919
|
+
throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
|
|
39684
39920
|
}
|
|
39685
39921
|
if (outcome === "succeeded" && newAssistant)
|
|
39686
39922
|
return newAssistant;
|
|
@@ -39694,7 +39930,7 @@ async function awaitAssistantRow(openReader, readSessionError, stepLimit, childI
|
|
|
39694
39930
|
`terminal_row=${errorText(newAssistant)}`,
|
|
39695
39931
|
`session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
|
|
39696
39932
|
];
|
|
39697
|
-
throw sessionError === undefined ? new Error(`Hidden completion failed
|
|
39933
|
+
throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
|
|
39698
39934
|
}
|
|
39699
39935
|
if (newAssistant.data.error !== undefined) {
|
|
39700
39936
|
throw new HiddenProviderError(errorText(newAssistant.data.error), {
|
|
@@ -39734,9 +39970,35 @@ function createLateHiddenExecutor(current) {
|
|
|
39734
39970
|
}
|
|
39735
39971
|
async function createV2HiddenCompletionExecutor(host, options) {
|
|
39736
39972
|
const runs = new WeakMap;
|
|
39737
|
-
const store = new HiddenChildStateStore(options.db, options.projectIdentity);
|
|
39973
|
+
const store = new HiddenChildStateStore(options.db, options.projectIdentity, options.directory);
|
|
39738
39974
|
const generation = options.generation ?? "opencode2";
|
|
39739
39975
|
const roleTails = new Map;
|
|
39976
|
+
const legacy = options.db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(hiddenChildrenMetaKey(options.projectIdentity));
|
|
39977
|
+
if (legacy) {
|
|
39978
|
+
const children = parseMeta(legacy.value);
|
|
39979
|
+
const statuses = new Map;
|
|
39980
|
+
for (const child of [...Object.values(children.active), ...children.retired_children]) {
|
|
39981
|
+
if (!child || !host.status)
|
|
39982
|
+
continue;
|
|
39983
|
+
const directory = child.directory ?? options.directory;
|
|
39984
|
+
if (!statuses.has(directory)) {
|
|
39985
|
+
try {
|
|
39986
|
+
statuses.set(directory, await host.status({ directory }));
|
|
39987
|
+
} catch {
|
|
39988
|
+
statuses.set(directory, undefined);
|
|
39989
|
+
}
|
|
39990
|
+
}
|
|
39991
|
+
}
|
|
39992
|
+
store.migrateStale((child) => {
|
|
39993
|
+
const directory = child.directory ?? options.directory;
|
|
39994
|
+
const state = statuses.get(directory);
|
|
39995
|
+
if (host.status && (!state || state[child.id]?.type === "busy" || state[child.id]?.type === "retry"))
|
|
39996
|
+
return false;
|
|
39997
|
+
const last = Math.max(child.created_at, withReader(options.openReader, (reader) => Math.max(reader.latestAssistant(child.id)?.data.time?.created ?? 0, reader.latestIdle(child.id)?.data.time?.created ?? 0)));
|
|
39998
|
+
const staleMs = child.role === "historian" ? historianOrphanStaleMs(20 * 60000, 3) : retrospectiveOrphanStaleMs(undefined);
|
|
39999
|
+
return Date.now() - last > staleMs;
|
|
40000
|
+
});
|
|
40001
|
+
}
|
|
39740
40002
|
const persisted = store.read();
|
|
39741
40003
|
for (const child of [...Object.values(persisted.active), ...persisted.retired_children]) {
|
|
39742
40004
|
if (child)
|
|
@@ -40106,6 +40368,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
|
|
|
40106
40368
|
}
|
|
40107
40369
|
run.completion = {
|
|
40108
40370
|
text,
|
|
40371
|
+
tokenLog: runTokenLog(tokens, run.identity.maxOutputTokens, row.data.finish),
|
|
40109
40372
|
...hiddenToolLoop(run.identity) ? { messages: toolLoopMessages(attempt) } : {},
|
|
40110
40373
|
reasoning: text ? null : assistantReasoning(row),
|
|
40111
40374
|
usage: reportedInput !== undefined || reportedOutput !== undefined ? {
|
|
@@ -40479,10 +40742,19 @@ function startDreamTrigger(context, args) {
|
|
|
40479
40742
|
};
|
|
40480
40743
|
}
|
|
40481
40744
|
|
|
40745
|
+
// src/v2/hooks/hidden-terminal-error.ts
|
|
40746
|
+
function hiddenTerminalError(event) {
|
|
40747
|
+
if (event.type === "session.execution.failed")
|
|
40748
|
+
return event.data?.error;
|
|
40749
|
+
if (event.type === "session.error")
|
|
40750
|
+
return getSessionErrorInfo(event.data)?.error;
|
|
40751
|
+
return;
|
|
40752
|
+
}
|
|
40753
|
+
|
|
40482
40754
|
// src/v2/hooks/lkg-system.ts
|
|
40483
|
-
import { createHash as
|
|
40755
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
40484
40756
|
function identity(slot) {
|
|
40485
|
-
return
|
|
40757
|
+
return createHash17("sha256").update(JSON.stringify({
|
|
40486
40758
|
capturedAt: slot.capturedAt,
|
|
40487
40759
|
captureSequence: slot.captureSequence,
|
|
40488
40760
|
rowVersion: slot.rowVersion,
|
|
@@ -40719,6 +40991,7 @@ function adaptPayload(draft, admittedIDs = new Set) {
|
|
|
40719
40991
|
input: structuredClone(call?.input ?? {}),
|
|
40720
40992
|
status: result ? "completed" : "running",
|
|
40721
40993
|
...result ? { output } : {},
|
|
40994
|
+
...result && (call?.name ?? result.part.name) === "question" ? { metadata: { userAnswer: true } } : {},
|
|
40722
40995
|
...files ? { attachments: contentValueAttachments(files) } : {}
|
|
40723
40996
|
}
|
|
40724
40997
|
};
|
|
@@ -41258,10 +41531,10 @@ function* readV2RawMessagePagesForConversion(openReader, sessionID, pageRows = C
|
|
|
41258
41531
|
function createV2RawMessageReader(openReader) {
|
|
41259
41532
|
const servedBoundaryCache = new Map;
|
|
41260
41533
|
return {
|
|
41261
|
-
readPage: (sessionID, afterOrdinal, limit, finalWatermark) => {
|
|
41534
|
+
readPage: (sessionID, afterOrdinal, limit, finalWatermark, after) => {
|
|
41262
41535
|
const reader = openReader();
|
|
41263
41536
|
try {
|
|
41264
|
-
return rawMessagePage(reader.messagePage(sessionID, afterOrdinal, limit, finalWatermark), afterOrdinal);
|
|
41537
|
+
return rawMessagePage(reader.messagePage(sessionID, afterOrdinal, limit, finalWatermark, after), afterOrdinal);
|
|
41265
41538
|
} finally {
|
|
41266
41539
|
reader.close();
|
|
41267
41540
|
}
|
|
@@ -41355,7 +41628,7 @@ function createV2RawMessageReader(openReader) {
|
|
|
41355
41628
|
}
|
|
41356
41629
|
function createV2RawMessageProvider(reader, sessionID) {
|
|
41357
41630
|
return {
|
|
41358
|
-
readMessagePage: (afterOrdinal, limit, finalWatermark) => reader.readPage(sessionID, afterOrdinal, limit, finalWatermark),
|
|
41631
|
+
readMessagePage: (afterOrdinal, limit, finalWatermark, after) => reader.readPage(sessionID, afterOrdinal, limit, finalWatermark, after),
|
|
41359
41632
|
readMessageById: (messageID) => reader.findById(sessionID, messageID),
|
|
41360
41633
|
readMessagePartsById: (messageID) => reader.findPartsById(sessionID, messageID),
|
|
41361
41634
|
hasMessageById: (messageID) => reader.hasById(sessionID, messageID),
|
|
@@ -41413,6 +41686,10 @@ async function registerTools(context, db, config, rustToolBackends) {
|
|
|
41413
41686
|
input: tool7.schema.toJSONSchema(tool7.schema.object(definition.args)),
|
|
41414
41687
|
options: { codemode: false },
|
|
41415
41688
|
async execute(input, call) {
|
|
41689
|
+
if (name === "ctx_memory" || name === "ctx_note" || name === "ctx_reduce")
|
|
41690
|
+
await withAsyncPrivilegedWriter(db, () => {
|
|
41691
|
+
return;
|
|
41692
|
+
});
|
|
41416
41693
|
const result = await definition.execute(tool7.schema.object(definition.args).parse(input), {
|
|
41417
41694
|
sessionID: call.sessionID,
|
|
41418
41695
|
messageID: call.messageID,
|
|
@@ -41645,6 +41922,7 @@ async function applyV2SystemPrompt(systemPrompt, draft) {
|
|
|
41645
41922
|
async function registerContext(context) {
|
|
41646
41923
|
const directory = context.location.directory;
|
|
41647
41924
|
const config = loadPluginConfigDetailed(directory).config;
|
|
41925
|
+
setHomeProjectPermission(config.allow_home_project);
|
|
41648
41926
|
if (!config.enabled)
|
|
41649
41927
|
return;
|
|
41650
41928
|
const liveConfigReader = pluginConfigReader(directory, config);
|
|
@@ -41753,6 +42031,7 @@ async function registerContext(context) {
|
|
|
41753
42031
|
}, {
|
|
41754
42032
|
db: database,
|
|
41755
42033
|
projectIdentity: resolveProjectIdentityForSession(directory, config.allow_home_project) ?? "",
|
|
42034
|
+
directory,
|
|
41756
42035
|
hook: hiddenChildHook,
|
|
41757
42036
|
keepSubagents: config.keep_subagents === true,
|
|
41758
42037
|
ensureAgent: () => hiddenAgentsReady ??= context.agent.reload(),
|
|
@@ -41955,8 +42234,8 @@ async function registerContext(context) {
|
|
|
41955
42234
|
if (!event.data?.sessionID)
|
|
41956
42235
|
continue;
|
|
41957
42236
|
const sessionID = event.data.sessionID;
|
|
41958
|
-
if (event.type === "session.error") {
|
|
41959
|
-
const error =
|
|
42237
|
+
if (event.type === "session.error" || event.type === "session.execution.failed") {
|
|
42238
|
+
const error = hiddenTerminalError(event);
|
|
41960
42239
|
if (error !== undefined)
|
|
41961
42240
|
hiddenSessionErrors.set(sessionID, error);
|
|
41962
42241
|
continue;
|
|
@@ -42079,7 +42358,7 @@ async function registerContext(context) {
|
|
|
42079
42358
|
try {
|
|
42080
42359
|
const admissionDb = db ?? storage.current();
|
|
42081
42360
|
if (!compactionOff && admissionDb)
|
|
42082
|
-
|
|
42361
|
+
await withAsyncPrivilegedWriter(admissionDb, () => {
|
|
42083
42362
|
return;
|
|
42084
42363
|
});
|
|
42085
42364
|
recordV2ToolDefinitions(draft);
|
|
@@ -42465,14 +42744,14 @@ ${baseline}
|
|
|
42465
42744
|
}
|
|
42466
42745
|
|
|
42467
42746
|
// src/v2/hooks/update-check.ts
|
|
42468
|
-
import { existsSync as existsSync12, readFileSync as
|
|
42747
|
+
import { existsSync as existsSync12, readFileSync as readFileSync10 } from "node:fs";
|
|
42469
42748
|
import { dirname as dirname6, join as join12 } from "node:path";
|
|
42470
42749
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
42471
42750
|
function packageInfo() {
|
|
42472
42751
|
let directory = dirname6(fileURLToPath3(import.meta.url));
|
|
42473
42752
|
for (;; ) {
|
|
42474
42753
|
try {
|
|
42475
|
-
const pkg = JSON.parse(
|
|
42754
|
+
const pkg = JSON.parse(readFileSync10(join12(directory, "package.json"), "utf8"));
|
|
42476
42755
|
if (pkg.name === "@cortexkit/opencode-magic-context" && typeof pkg.version === "string") {
|
|
42477
42756
|
return {
|
|
42478
42757
|
version: pkg.version,
|
|
@@ -42570,6 +42849,7 @@ var server = async (ctx) => {
|
|
|
42570
42849
|
});
|
|
42571
42850
|
const loadedPluginConfig = loadPluginConfigDetailed(ctx.directory);
|
|
42572
42851
|
const pluginConfig = loadedPluginConfig.config;
|
|
42852
|
+
setHomeProjectPermission(pluginConfig.allow_home_project);
|
|
42573
42853
|
const liveConfigReader = pluginConfigReader(ctx.directory, pluginConfig);
|
|
42574
42854
|
const dreamerCap = createDreamerOutputCapSampler(pluginConfig, () => liveConfigReader.poll().effective);
|
|
42575
42855
|
reloadWindowOverlay(pluginConfig.models?.window_overlay_path);
|
|
@@ -42603,7 +42883,7 @@ var server = async (ctx) => {
|
|
|
42603
42883
|
if (hasBannerEntries)
|
|
42604
42884
|
setTimeout(async () => {
|
|
42605
42885
|
try {
|
|
42606
|
-
const { sendStatusNotification } = await import("./send-session-notification-
|
|
42886
|
+
const { sendStatusNotification } = await import("./send-session-notification-04hvd54c.js");
|
|
42607
42887
|
const clientWithSessions = ctx.client;
|
|
42608
42888
|
const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
|
|
42609
42889
|
const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
|
|
@@ -42620,7 +42900,7 @@ var server = async (ctx) => {
|
|
|
42620
42900
|
log(`[magic-context] opencode_db_missing path=${openCodeDbResolution.path} source=${openCodeDbResolution.source}`);
|
|
42621
42901
|
setTimeout(async () => {
|
|
42622
42902
|
try {
|
|
42623
|
-
const { sendStatusNotification } = await import("./send-session-notification-
|
|
42903
|
+
const { sendStatusNotification } = await import("./send-session-notification-04hvd54c.js");
|
|
42624
42904
|
const clientWithSessions = ctx.client;
|
|
42625
42905
|
const sessions = await Promise.resolve(clientWithSessions.session?.list?.()).catch(() => null);
|
|
42626
42906
|
const sessionList = Array.isArray(sessions) ? sessions : sessions?.data;
|
|
@@ -42894,12 +43174,12 @@ var server = async (ctx) => {
|
|
|
42894
43174
|
{
|
|
42895
43175
|
const fence = getSchemaFenceRejection();
|
|
42896
43176
|
if (fence) {
|
|
42897
|
-
import("./conflict-warning-hook-
|
|
43177
|
+
import("./conflict-warning-hook-hmpzxep6.js").then(({ sendSchemaFenceWarning }) => sendSchemaFenceWarning(ctx.client, ctx.directory, fence));
|
|
42898
43178
|
}
|
|
42899
43179
|
}
|
|
42900
43180
|
const serverUrl = ctx.serverUrl;
|
|
42901
43181
|
const serverUrlStr = serverUrl instanceof URL ? serverUrl.toString().replace(/\/$/, "") : typeof serverUrl === "string" ? serverUrl.replace(/\/$/, "") : undefined;
|
|
42902
|
-
import("./send-session-notification-
|
|
43182
|
+
import("./send-session-notification-04hvd54c.js").then(({ setNotificationServerUrl }) => {
|
|
42903
43183
|
setNotificationServerUrl(serverUrlStr);
|
|
42904
43184
|
});
|
|
42905
43185
|
if (conflictResult?.hasConflict) {
|
|
@@ -42922,7 +43202,7 @@ var server = async (ctx) => {
|
|
|
42922
43202
|
}) => {
|
|
42923
43203
|
if (!shouldShowAnnouncement())
|
|
42924
43204
|
return;
|
|
42925
|
-
return import("./conflict-warning-hook-
|
|
43205
|
+
return import("./conflict-warning-hook-hmpzxep6.js").then(({ sendStartupAnnouncement }) => sendStartupAnnouncement(ctx.client, ctx.directory, ANNOUNCEMENT_VERSION, ANNOUNCEMENT_FEATURES, ANNOUNCEMENT_FOOTER, markAnnouncementSeen));
|
|
42926
43206
|
}).catch(() => {});
|
|
42927
43207
|
}, 8000);
|
|
42928
43208
|
}
|
|
@@ -42991,8 +43271,8 @@ var server = async (ctx) => {
|
|
|
42991
43271
|
internalChildSessions: liveSessionState.internalChildSessions,
|
|
42992
43272
|
tryReopenStorage,
|
|
42993
43273
|
onStorageBusyRefusal: async (sessionId, message) => {
|
|
42994
|
-
const { sendStatusNotification } = await import("./send-session-notification-
|
|
42995
|
-
const { abortSessionFailClosed } = await import("./transform-postprocess-phase-
|
|
43274
|
+
const { sendStatusNotification } = await import("./send-session-notification-04hvd54c.js");
|
|
43275
|
+
const { abortSessionFailClosed } = await import("./transform-postprocess-phase-ttdkrm6r.js");
|
|
42996
43276
|
await sendStatusNotification(ctx.client, sessionId, message, {
|
|
42997
43277
|
toastDurationMs: 15000
|
|
42998
43278
|
});
|