@cortexkit/opencode-magic-context 0.49.25 → 0.49.27
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-search-worker.js +4 -4
- package/dist/chunk-embedding-write-worker.js +7 -7
- package/dist/{compartment-chunk-embedding-eypvn607.js → compartment-chunk-embedding-qgp0tbf7.js} +3 -3
- package/dist/config/schema/magic-context.d.ts +393 -393
- package/dist/{conflict-warning-hook-a27bhggg.js → conflict-warning-hook-tgnw019g.js} +4 -4
- package/dist/{context-keb00be8.js → context-t2k97d6v.js} +116 -116
- package/dist/{embedding-backfill-vddgmem3.js → embedding-backfill-cwnyr4fj.js} +5 -5
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +1 -4
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index.d.ts +1 -28
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/session-retention.fixture.d.ts +4 -0
- package/dist/features/magic-context/session-retention.fixture.d.ts.map +1 -0
- package/dist/features/magic-context/storage-session-tables.d.ts +5 -12
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/hooks/magic-context/caveman-cleanup.d.ts +14 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts +11 -0
- package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/foreign-text-parts.d.ts +47 -0
- package/dist/hooks/magic-context/foreign-text-parts.d.ts.map +1 -0
- package/dist/hooks/magic-context/historian-history-wait.d.ts +10 -0
- package/dist/hooks/magic-context/historian-history-wait.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-recovery-fence.d.ts +0 -5
- package/dist/hooks/magic-context/lkg-recovery-fence.d.ts.map +1 -1
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +0 -10
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +21 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +20 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +15 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/todo-view.d.ts +2 -2
- package/dist/hooks/magic-context/transform.d.ts +7 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-jcr6pe7z.js → index-077ht5cq.js} +1 -1
- package/dist/{index-ebsvmc5s.js → index-31y1mznz.js} +4 -4
- package/dist/{index-q7ywt6xt.js → index-4cpc59jv.js} +5 -5
- package/dist/{index-t6j3qxnd.js → index-4ypqzvhf.js} +1 -1
- package/dist/index-7gbcg8xv.js +559 -0
- package/dist/{index-9q1g3c5q.js → index-7kkphb6c.js} +1 -1
- package/dist/{index-bhyksfyy.js → index-89k1w6x2.js} +3 -3
- package/dist/{index-z05n7702.js → index-a2fz9hpa.js} +1 -1
- package/dist/{index-0s8454t2.js → index-dcqk0y27.js} +1560 -91
- package/dist/{index-n18sch77.js → index-dzfevacx.js} +9 -9
- package/dist/{index-axjgxeww.js → index-fq2p158w.js} +169 -13
- package/dist/{index-3d5wnkq7.js → index-mm93m7y6.js} +1 -1
- package/dist/{index-zzrzjnx5.js → index-n8qmmd7f.js} +3 -3
- package/dist/{index-whcgcfrv.js → index-np3rgfw4.js} +1 -1
- package/dist/{index-y6xpzjzr.js → index-qzbpbnqt.js} +585 -602
- package/dist/{index-7tdtpqrg.js → index-rverk2vz.js} +39 -8
- package/dist/{index-cfaet9cg.js → index-s1n8dd2n.js} +1 -1
- package/dist/{index-z928hmnp.js → index-t3rbb8wr.js} +2 -2
- package/dist/{index-2haxh8h3.js → index-tvzvjggy.js} +1 -1
- package/dist/{index-c9zrgcnt.js → index-v0dhhxsq.js} +1 -1
- package/dist/{index-szf8r0ba.js → index-v15ne3a3.js} +2 -5
- package/dist/{index-x9k3mqrf.js → index-xrnsygfq.js} +1 -1
- package/dist/{index-yrrsp47d.js → index-yzjhx10y.js} +20 -6
- package/dist/index.js +40 -38
- package/dist/{message-fts-rowid-map-9e1getgs.js → message-fts-rowid-map-va36knh4.js} +2 -4
- package/dist/{message-index-bounded-vaeqhp9w.js → message-index-bounded-7ayzb2ah.js} +22 -25
- package/dist/migration-worker.js +6 -6
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/{project-embedding-registry-rstzmb60.js → project-embedding-registry-94nncs5g.js} +4 -4
- package/dist/raw-ordinal-warmup-worker.js +7 -30
- package/dist/{read-session-chunk-z5gnc0zb.js → read-session-chunk-jzb6w9w5.js} +8 -6
- package/dist/{read-session-raw-s4amywnh.js → read-session-raw-b2sd67v4.js} +3 -1
- package/dist/{recomp-orchestrator-qwqeskhq.js → recomp-orchestrator-02sa2ngr.js} +17 -17
- package/dist/{search-archive-mfabzyn2.js → search-archive-q1vw7zg4.js} +7 -7
- package/dist/{search-84zfqeky.js → search-spq6nfyf.js} +14 -15
- package/dist/{send-session-notification-ygj4mja0.js → send-session-notification-afzzqy5b.js} +3 -3
- package/dist/{storage-tags-a77q4v77.js → storage-tags-6hvkk01c.js} +2 -2
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/{transform-postprocess-phase-hr1ntmjj.js → transform-postprocess-phase-6menyyxc.js} +17 -17
- package/dist/v2/auto-search-worker.js +4 -4
- package/dist/v2/chunk-embedding-write-worker.js +7 -7
- package/dist/v2/{compartment-chunk-embedding-tk6g4q80.js → compartment-chunk-embedding-63dzs31c.js} +3 -3
- package/dist/v2/{context-y7wfvdve.js → context-na0esngr.js} +342 -218
- package/dist/v2/{embedding-backfill-w5qp7t28.js → embedding-backfill-rh5dgsva.js} +5 -5
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/{message-fts-rowid-map-pqk3a55v.js → message-fts-rowid-map-78awh03v.js} +2 -4
- package/dist/v2/{message-index-bounded-te303atj.js → message-index-bounded-n09b74vr.js} +21 -24
- package/dist/v2/migration-worker.js +6 -6
- package/dist/v2/{project-embedding-registry-e7zftfvj.js → project-embedding-registry-6pak822h.js} +4 -4
- package/dist/v2/raw-ordinal-warmup-worker.js +7 -30
- package/dist/v2/{read-session-chunk-knvkq1hf.js → read-session-chunk-vpt69tw9.js} +7 -5
- package/dist/v2/{read-session-raw-ppjxnqk4.js → read-session-raw-5x088amc.js} +3 -1
- package/dist/v2/{recomp-orchestrator-e8a4jpvr.js → recomp-orchestrator-txsmbnvw.js} +14 -14
- package/dist/v2/{search-archive-vrwgxv6z.js → search-archive-t9bcz4ht.js} +6 -6
- package/dist/v2/{search-hav4dggf.js → search-dcy9b6gd.js} +13 -14
- package/dist/v2/{send-session-notification-f8scq6ae.js → send-session-notification-vdsgnf4c.js} +1 -1
- package/dist/v2/{server-pw21ypwb.js → server-4sn3at8p.js} +1 -1
- package/dist/v2/{server-8j2e7t31.js → server-6avtp9jp.js} +1 -1
- package/dist/v2/{server-wwaw5npa.js → server-6g98c227.js} +1 -1
- package/dist/v2/{server-swvhxhxz.js → server-6vd2n183.js} +39 -8
- package/dist/v2/{server-wxrdher8.js → server-awr8qa4c.js} +2 -5
- package/dist/v2/{server-7d6m1p2b.js → server-cqjvxyrp.js} +1 -1
- package/dist/v2/{server-e75vag9d.js → server-e3hc93wk.js} +5 -5
- package/dist/v2/{server-7weh65vd.js → server-jj9qye8y.js} +1520 -79
- package/dist/v2/{server-fa7vtp40.js → server-nxas8v1d.js} +1 -1
- package/dist/v2/{server-tfawsj08.js → server-txbc3czn.js} +9 -9
- package/dist/v2/{server-rqebawx1.js → server-v77xa5wj.js} +1 -1
- package/dist/v2/{server-5brp2rfn.js → server-xkvxss5g.js} +19 -5
- package/dist/v2/{server-q5z0gag0.js → server-yqek3s4k.js} +1 -1
- package/dist/v2/server-z2n2xaeh.js +538 -0
- package/dist/v2/{server-9xbbaekh.js → server-z3mk9jdc.js} +2 -2
- package/dist/v2/{server-m6yyn961.js → server-zmcrvpm3.js} +2 -2
- package/dist/v2/server.js +2 -2
- package/dist/v2/{storage-tags-q71rnr9f.js → storage-tags-18nbaanf.js} +2 -2
- package/dist/v2/store-reader.d.ts +0 -2
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/{wrapup-orchestrator-ycs8y6n4.js → wrapup-orchestrator-gjkszser.js} +14 -14
- package/dist/{wrapup-orchestrator-f642w8n3.js → wrapup-orchestrator-n5h5sr1x.js} +18 -18
- package/package.json +1 -1
- package/src/shared/write-transaction-attribution.test.ts +1 -6
- package/dist/index-awcftgmx.js +0 -2251
- package/dist/message-index-3g966xn7.js +0 -61
- package/dist/v2/message-index-fz6b4jeh.js +0 -60
- package/dist/v2/server-6a8pxpxg.js +0 -2220
|
@@ -144,11 +144,11 @@ import {
|
|
|
144
144
|
getDroppedTagsByNumbers2,
|
|
145
145
|
getMaxDroppedTagNumber2,
|
|
146
146
|
getTagById2
|
|
147
|
-
} from "./index-
|
|
147
|
+
} from "./index-np3rgfw4.js";
|
|
148
148
|
import {
|
|
149
149
|
observeTemporalDecisions,
|
|
150
150
|
stableStringify
|
|
151
|
-
} from "./index-
|
|
151
|
+
} from "./index-xrnsygfq.js";
|
|
152
152
|
import {
|
|
153
153
|
withContentLanguageDirective,
|
|
154
154
|
parseCron,
|
|
@@ -169,7 +169,7 @@ import {
|
|
|
169
169
|
buildInMemoryTailRawMessages2,
|
|
170
170
|
RawOrdinalsNotReady2,
|
|
171
171
|
runSessionWarmupWorker
|
|
172
|
-
} from "./index-
|
|
172
|
+
} from "./index-rverk2vz.js";
|
|
173
173
|
import {
|
|
174
174
|
openCodeDbExists,
|
|
175
175
|
withReadOnlySessionDb,
|
|
@@ -177,7 +177,7 @@ import {
|
|
|
177
177
|
latestPersistedMessageForRecovery,
|
|
178
178
|
latestRealUserTurnIdFromOpenCodeDb,
|
|
179
179
|
findLastAssistantModelFromOpenCodeDb
|
|
180
|
-
} from "./index-
|
|
180
|
+
} from "./index-v0dhhxsq.js";
|
|
181
181
|
import {
|
|
182
182
|
expandToolPart,
|
|
183
183
|
askAnswerLines,
|
|
@@ -302,11 +302,11 @@ import {
|
|
|
302
302
|
readRawSessionMessageById2,
|
|
303
303
|
readSessionChunk2,
|
|
304
304
|
readRawSessionSeedTail2
|
|
305
|
-
} from "./index-
|
|
305
|
+
} from "./index-yzjhx10y.js";
|
|
306
306
|
import {
|
|
307
307
|
BoundedSessionMap,
|
|
308
308
|
getMeasuredToolDefinitionTokens
|
|
309
|
-
} from "./index-
|
|
309
|
+
} from "./index-s1n8dd2n.js";
|
|
310
310
|
import {
|
|
311
311
|
isFailClosedBlockingError,
|
|
312
312
|
shouldBypassFailClosedBlock,
|
|
@@ -320,7 +320,7 @@ import {
|
|
|
320
320
|
runSqliteOptimize,
|
|
321
321
|
openDatabase,
|
|
322
322
|
openCurrentDatabase
|
|
323
|
-
} from "./index-
|
|
323
|
+
} from "./index-4cpc59jv.js";
|
|
324
324
|
import {
|
|
325
325
|
registerOwnRpcServerInstance,
|
|
326
326
|
rpcPortDir,
|
|
@@ -339,7 +339,7 @@ import {
|
|
|
339
339
|
resolveStoredPathWorkspaceIdentity,
|
|
340
340
|
storedPathBelongsToWorkspace,
|
|
341
341
|
computeWorkspaceEpochFingerprint
|
|
342
|
-
} from "./index-
|
|
342
|
+
} from "./index-7kkphb6c.js";
|
|
343
343
|
import {
|
|
344
344
|
V2_MEMORY_CATEGORIES,
|
|
345
345
|
CATEGORY_PRIORITY
|
|
@@ -368,6 +368,15 @@ import {
|
|
|
368
368
|
getLastCompartmentEndMessage,
|
|
369
369
|
getLastCompartmentEndMessageId,
|
|
370
370
|
providerResponseFailed,
|
|
371
|
+
LkgRecoveryFenceError,
|
|
372
|
+
lkgServedArrayDigest,
|
|
373
|
+
hasCleanLkgRecoveryFence,
|
|
374
|
+
dirtyLkgRecoveryRevision,
|
|
375
|
+
ownsLkgDirtyFence,
|
|
376
|
+
invalidateCleanLkgRecoveryFence,
|
|
377
|
+
prepareLkgCaptureFence,
|
|
378
|
+
certifyCommittedLkgCapture,
|
|
379
|
+
markLkgRecoveryDirty,
|
|
371
380
|
getOrCreateSessionMeta,
|
|
372
381
|
updateSessionMeta,
|
|
373
382
|
retryPendingSessionCleanups,
|
|
@@ -495,6 +504,7 @@ import {
|
|
|
495
504
|
readCoordinateRebaseNotice,
|
|
496
505
|
formatCoordinateRebaseNotice,
|
|
497
506
|
rebaseSessionCoordinatesAsync,
|
|
507
|
+
shouldWaitForNewHistorianHistory,
|
|
498
508
|
EMPTY_READ_REPLY,
|
|
499
509
|
noteTouchedAt,
|
|
500
510
|
renderGlance,
|
|
@@ -515,7 +525,7 @@ import {
|
|
|
515
525
|
snapRangeToCompartments,
|
|
516
526
|
getActiveCompartmentRun,
|
|
517
527
|
startCompartmentAgent
|
|
518
|
-
} from "./index-
|
|
528
|
+
} from "./index-dcqk0y27.js";
|
|
519
529
|
import {
|
|
520
530
|
embedPauseBySession,
|
|
521
531
|
embedRunStateBySession,
|
|
@@ -543,7 +553,7 @@ import {
|
|
|
543
553
|
embedSessionCompartmentChunks2,
|
|
544
554
|
getEmbeddingCoverageStatus2,
|
|
545
555
|
getAutoEmbeddingSessionCoverage2
|
|
546
|
-
} from "./index-
|
|
556
|
+
} from "./index-a2fz9hpa.js";
|
|
547
557
|
import {
|
|
548
558
|
SubcClient,
|
|
549
559
|
connectionFileExists,
|
|
@@ -553,27 +563,15 @@ import {
|
|
|
553
563
|
SynapseEmbeddingProvider
|
|
554
564
|
} from "./index-wfybj1dw.js";
|
|
555
565
|
import {
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
markLkgRecoveryDirty,
|
|
566
|
-
gaDatabasePath,
|
|
567
|
-
getMessageIndexSourceIdentity2,
|
|
568
|
-
isMessageIndexSourceCurrent2,
|
|
569
|
-
getLastIndexedOrdinal2,
|
|
570
|
-
getMessageIndexReconciliationStartOrdinal2,
|
|
571
|
-
isMessageIndexReconciledThrough2,
|
|
572
|
-
clearIndexedMessages2,
|
|
573
|
-
indexSingleMessage2,
|
|
574
|
-
indexMessagesAfterOrdinal2,
|
|
575
|
-
sweepOrphanedOpenCodeMessageIndexesCooperatively2
|
|
576
|
-
} from "./index-awcftgmx.js";
|
|
566
|
+
getMessageIndexSourceIdentity,
|
|
567
|
+
isMessageIndexSourceCurrent,
|
|
568
|
+
getLastIndexedOrdinal,
|
|
569
|
+
getMessageIndexReconciliationStartOrdinal,
|
|
570
|
+
isMessageIndexReconciledThrough,
|
|
571
|
+
clearIndexedMessages,
|
|
572
|
+
indexSingleMessage,
|
|
573
|
+
indexMessagesAfterOrdinal
|
|
574
|
+
} from "./index-7gbcg8xv.js";
|
|
577
575
|
import {
|
|
578
576
|
renderUserFacingFailure,
|
|
579
577
|
userFacingFailureCode,
|
|
@@ -617,7 +615,7 @@ import {
|
|
|
617
615
|
readGitFileChangeTimesSince,
|
|
618
616
|
verificationFileExists,
|
|
619
617
|
normalizeVerificationFiles
|
|
620
|
-
} from "./index-
|
|
618
|
+
} from "./index-t3rbb8wr.js";
|
|
621
619
|
import {
|
|
622
620
|
registerNotificationSink2,
|
|
623
621
|
pushNotification2,
|
|
@@ -637,7 +635,7 @@ import {
|
|
|
637
635
|
} from "./index-4dhv7mqz.js";
|
|
638
636
|
import {
|
|
639
637
|
cosineSimilarity
|
|
640
|
-
} from "./index-
|
|
638
|
+
} from "./index-4ypqzvhf.js";
|
|
641
639
|
import {
|
|
642
640
|
computeCueContentHash,
|
|
643
641
|
hasMuralCueColumns,
|
|
@@ -683,17 +681,17 @@ import {
|
|
|
683
681
|
resolveMemoriesByIdsForSearch2,
|
|
684
682
|
unifiedSearch2,
|
|
685
683
|
formatSearchResults2
|
|
686
|
-
} from "./index-
|
|
684
|
+
} from "./index-dzfevacx.js";
|
|
687
685
|
import {
|
|
688
686
|
flushIgnoredMessages2,
|
|
689
687
|
clearIgnoredMessages2,
|
|
690
688
|
observeIgnoredNotificationEvent2,
|
|
691
689
|
sendStatusNotification2
|
|
692
|
-
} from "./index-
|
|
690
|
+
} from "./index-077ht5cq.js";
|
|
693
691
|
import {
|
|
694
692
|
setRecompStarting2,
|
|
695
693
|
setRecompTerminal2
|
|
696
|
-
} from "./index-
|
|
694
|
+
} from "./index-n8qmmd7f.js";
|
|
697
695
|
import {
|
|
698
696
|
makeToolCompositeKey,
|
|
699
697
|
searchMessageHistoryOffThread,
|
|
@@ -741,6 +739,7 @@ import {
|
|
|
741
739
|
prewarmTagOwners,
|
|
742
740
|
waitForTagOwners,
|
|
743
741
|
stripStructuralNoise,
|
|
742
|
+
isLegacyForeignTextTag,
|
|
744
743
|
withTransformTimingSummary,
|
|
745
744
|
logTransformTiming,
|
|
746
745
|
hasRecentAssistantCommit,
|
|
@@ -754,7 +753,7 @@ import {
|
|
|
754
753
|
abortSessionFailClosed2,
|
|
755
754
|
evaluateEmergencyFailClosed2,
|
|
756
755
|
runPostTransformPhase2
|
|
757
|
-
} from "./index-
|
|
756
|
+
} from "./index-fq2p158w.js";
|
|
758
757
|
import {
|
|
759
758
|
ANNOUNCEMENT_VERSION2,
|
|
760
759
|
ANNOUNCEMENT_FEATURES2,
|
|
@@ -767,7 +766,7 @@ import {
|
|
|
767
766
|
} from "./index-fmsr7v69.js";
|
|
768
767
|
import {
|
|
769
768
|
renderSearchArchiveOffThread2
|
|
770
|
-
} from "./index-
|
|
769
|
+
} from "./index-89k1w6x2.js";
|
|
771
770
|
import {
|
|
772
771
|
COMPACTION_ENABLED_PATH,
|
|
773
772
|
isDreamerRunnable,
|
|
@@ -9064,6 +9063,21 @@ function verifyAssistantText(messages) {
|
|
|
9064
9063
|
const start = text.lastIndexOf("<verify>");
|
|
9065
9064
|
return start >= 0 ? text.slice(start) : text;
|
|
9066
9065
|
}
|
|
9066
|
+
function validateVerifyCompletion(messages, text, expectedIds, responseText = text) {
|
|
9067
|
+
let parsed;
|
|
9068
|
+
try {
|
|
9069
|
+
parsed = validateVerifyManifest(text, expectedIds);
|
|
9070
|
+
} catch (error) {
|
|
9071
|
+
throw providerOutputFailureFromInvalidManifest(messages, responseText) ?? error;
|
|
9072
|
+
}
|
|
9073
|
+
const ids = [...parsed.verified, ...parsed.updated, ...parsed.archived, ...parsed.skipped].map((entry) => entry.id);
|
|
9074
|
+
if (ids.length !== expectedIds.size || ids.some((id) => !expectedIds.has(id))) {
|
|
9075
|
+
const providerFailure = providerOutputFailureFromInvalidManifest(messages, responseText);
|
|
9076
|
+
if (providerFailure)
|
|
9077
|
+
throw providerFailure;
|
|
9078
|
+
}
|
|
9079
|
+
return parsed;
|
|
9080
|
+
}
|
|
9067
9081
|
var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
|
|
9068
9082
|
var VERIFY_BATCH_FLOOR_MS = 30000;
|
|
9069
9083
|
function computeVerifyBatchSliceMs(remainingMs, _batchesRemaining) {
|
|
@@ -9222,6 +9236,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9222
9236
|
const timer = setTimeout(() => batchController.abort(new Error(`verify slice timed out after ${sliceMs}ms`)), sliceMs);
|
|
9223
9237
|
const batchSignal = batchController.signal;
|
|
9224
9238
|
const tokenBudget = verifyBatchTokenBudget(batch.length, args.tokenBudget);
|
|
9239
|
+
const expectedIds = new Set(batch.map((memory) => memory.id));
|
|
9225
9240
|
let agentSessionId = null;
|
|
9226
9241
|
let hiddenSessionId = null;
|
|
9227
9242
|
let promptSettled = false;
|
|
@@ -9274,13 +9289,10 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9274
9289
|
onBudgetUpdate({ spent: 0, finalizeFired: false, sessionId });
|
|
9275
9290
|
},
|
|
9276
9291
|
parse: (text, completion) => {
|
|
9277
|
-
const providerFailure = providerOutputFailureFromInvalidManifest(completion.messages ?? [], text);
|
|
9278
|
-
if (providerFailure)
|
|
9279
|
-
throw providerFailure;
|
|
9280
9292
|
const manifest = verifyAssistantText(completion.messages ?? []) ?? (text.trim() ? text : null);
|
|
9281
9293
|
if (!manifest)
|
|
9282
9294
|
throw new Error("verify returned no output");
|
|
9283
|
-
return
|
|
9295
|
+
return validateVerifyCompletion(completion.messages ?? [], manifest, expectedIds, text);
|
|
9284
9296
|
}
|
|
9285
9297
|
});
|
|
9286
9298
|
recordInvocation4(args, startedAt, {
|
|
@@ -9342,10 +9354,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9342
9354
|
const text = verifyAssistantText(messages);
|
|
9343
9355
|
if (!text)
|
|
9344
9356
|
throw new Error("verify returned no output");
|
|
9345
|
-
|
|
9346
|
-
if (providerFailure)
|
|
9347
|
-
throw providerFailure;
|
|
9348
|
-
return validateVerifyManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
9357
|
+
return validateVerifyCompletion(messages, text, expectedIds);
|
|
9349
9358
|
}
|
|
9350
9359
|
});
|
|
9351
9360
|
promptSettled = true;
|
|
@@ -11468,471 +11477,92 @@ function clearDreamerTickFailure(db) {
|
|
|
11468
11477
|
db.prepare("DELETE FROM schema_migrations_meta WHERE key = ?").run(DREAMER_TICK_FAILURE_KEY);
|
|
11469
11478
|
}
|
|
11470
11479
|
|
|
11471
|
-
// src/
|
|
11472
|
-
var
|
|
11473
|
-
var
|
|
11474
|
-
var
|
|
11475
|
-
|
|
11476
|
-
|
|
11480
|
+
// src/plugin/dream-timer.ts
|
|
11481
|
+
var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
|
|
11482
|
+
var GIT_COMMIT_BACKLOG_DRAIN_MAX_MS = 5 * 60 * 1000;
|
|
11483
|
+
var BOOT_PROJECT_JITTER_SLOT_MS = 1000;
|
|
11484
|
+
var activeTimer = null;
|
|
11485
|
+
var tickInFlight = false;
|
|
11486
|
+
var startupTickTimer = null;
|
|
11487
|
+
var startupTimers = new Map;
|
|
11488
|
+
var startupJitters = new Map;
|
|
11489
|
+
var nextStartupJitterSlot = 0;
|
|
11490
|
+
function directoryStillExists(directory) {
|
|
11491
|
+
try {
|
|
11492
|
+
return statSync2(directory).isDirectory();
|
|
11493
|
+
} catch {
|
|
11477
11494
|
return false;
|
|
11478
|
-
const e = error;
|
|
11479
|
-
if (typeof e.code === "string") {
|
|
11480
|
-
if (e.code === "SQLITE_BUSY" || e.code === "SQLITE_LOCKED")
|
|
11481
|
-
return true;
|
|
11482
|
-
}
|
|
11483
|
-
if (typeof e.message === "string") {
|
|
11484
|
-
if (/database is locked/i.test(e.message))
|
|
11485
|
-
return true;
|
|
11486
|
-
if (/sqlite_(busy|locked)/i.test(e.message))
|
|
11487
|
-
return true;
|
|
11488
11495
|
}
|
|
11489
|
-
return false;
|
|
11490
|
-
}
|
|
11491
|
-
var INCREMENTAL_DEBOUNCE_MS = 100;
|
|
11492
|
-
var RECONCILIATION_BATCH_SIZE = 100;
|
|
11493
|
-
|
|
11494
|
-
class MagicContextMessageIndexHeapHolder {
|
|
11495
|
-
reconciledSessions = new Set;
|
|
11496
|
-
reconciledSnapshots = new Map;
|
|
11497
|
-
stalledSessions = new Set;
|
|
11498
|
-
reconciliationScheduledSessions = new Set;
|
|
11499
|
-
clearAndReindexScheduledSessions = new Map;
|
|
11500
|
-
sessionLocks = new Map;
|
|
11501
|
-
incrementalTimers = new Map;
|
|
11502
|
-
pendingIncrementalKeys = new Set;
|
|
11503
|
-
completedIncrementalKeys = new Set;
|
|
11504
|
-
activeReconcilerBuffers = new Map;
|
|
11505
11496
|
}
|
|
11506
|
-
|
|
11507
|
-
|
|
11508
|
-
|
|
11509
|
-
|
|
11510
|
-
|
|
11511
|
-
|
|
11497
|
+
function openTimerDatabaseOrNull(context) {
|
|
11498
|
+
let db;
|
|
11499
|
+
try {
|
|
11500
|
+
db = openCurrentDatabase();
|
|
11501
|
+
} catch (error) {
|
|
11502
|
+
log2(`[dreamer] storage fatal; skipping ${context}: ${getErrorMessage(error)}`);
|
|
11503
|
+
return null;
|
|
11512
11504
|
}
|
|
11513
|
-
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
const prepare = source?.prepare;
|
|
11517
|
-
return typeof prepare === "function" ? prepare(sessionId) : true;
|
|
11518
|
-
}
|
|
11519
|
-
function defer(fn) {
|
|
11520
|
-
const immediate = globalThis.setImmediate;
|
|
11521
|
-
if (typeof immediate === "function") {
|
|
11522
|
-
inRootAsyncContext2(() => immediate(fn));
|
|
11523
|
-
return;
|
|
11505
|
+
if (!db) {
|
|
11506
|
+
log2(`[dreamer] storage unavailable; skipping ${context} (the cache schema is newer than this binary supports — restart/upgrade OpenCode/Pi/Magic Context to recover)`);
|
|
11507
|
+
return null;
|
|
11524
11508
|
}
|
|
11525
|
-
|
|
11526
|
-
}
|
|
11527
|
-
function yieldToEventLoop() {
|
|
11528
|
-
return new Promise((resolve) => defer(resolve));
|
|
11509
|
+
return db;
|
|
11529
11510
|
}
|
|
11530
|
-
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
return;
|
|
11534
|
-
}).then(async () => {
|
|
11535
|
-
await operation();
|
|
11536
|
-
});
|
|
11537
|
-
heapHolder.sessionLocks.set(sessionId, run);
|
|
11538
|
-
run.finally(() => {
|
|
11539
|
-
if (heapHolder.sessionLocks.get(sessionId) === run) {
|
|
11540
|
-
heapHolder.sessionLocks.delete(sessionId);
|
|
11541
|
-
}
|
|
11542
|
-
}).catch(() => {
|
|
11511
|
+
var refusedEmptyIdentityDirectories = new Set;
|
|
11512
|
+
function logEmptyIdentityRefusalOnce(directory) {
|
|
11513
|
+
if (refusedEmptyIdentityDirectories.has(directory))
|
|
11543
11514
|
return;
|
|
11544
|
-
|
|
11545
|
-
|
|
11515
|
+
refusedEmptyIdentityDirectories.add(directory);
|
|
11516
|
+
log2(`[dreamer] not registering ${directory}: it has no project identity, so no project-scoped work runs for it`);
|
|
11546
11517
|
}
|
|
11547
|
-
|
|
11548
|
-
|
|
11549
|
-
|
|
11518
|
+
var registeredProjects = new Map;
|
|
11519
|
+
function stopDreamScheduleTimerIfIdle() {
|
|
11520
|
+
if (registeredProjects.size !== 0)
|
|
11550
11521
|
return;
|
|
11522
|
+
const stopped = activeTimer !== null || startupTickTimer !== null;
|
|
11523
|
+
if (activeTimer) {
|
|
11524
|
+
clearInterval(activeTimer);
|
|
11525
|
+
activeTimer = null;
|
|
11551
11526
|
}
|
|
11552
|
-
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
function serializedMessageBytes(messages) {
|
|
11556
|
-
try {
|
|
11557
|
-
return Buffer.byteLength(JSON.stringify(messages));
|
|
11558
|
-
} catch {
|
|
11559
|
-
return 0;
|
|
11527
|
+
if (startupTickTimer) {
|
|
11528
|
+
clearTimeout(startupTickTimer);
|
|
11529
|
+
startupTickTimer = null;
|
|
11560
11530
|
}
|
|
11531
|
+
startupJitters.clear();
|
|
11532
|
+
nextStartupJitterSlot = 0;
|
|
11533
|
+
if (stopped)
|
|
11534
|
+
log2("[dreamer] stopped dream schedule timer (no projects left)");
|
|
11561
11535
|
}
|
|
11562
|
-
function
|
|
11563
|
-
if (
|
|
11536
|
+
async function startDreamScheduleTimer(args) {
|
|
11537
|
+
if (!isUsableProjectIdentity(args.projectIdentity)) {
|
|
11538
|
+
logEmptyIdentityRefusalOnce(args.directory);
|
|
11564
11539
|
return;
|
|
11565
|
-
heapHolder.stalledSessions.add(sessionId);
|
|
11566
|
-
sessionLog2(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
|
|
11567
|
-
}
|
|
11568
|
-
async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
11569
|
-
if (!await sourceReady(readMessages, sessionId)) {
|
|
11570
|
-
logReconciliationStall(sessionId, "raw message reader is not ready");
|
|
11571
|
-
return false;
|
|
11572
11540
|
}
|
|
11573
|
-
|
|
11574
|
-
|
|
11575
|
-
|
|
11576
|
-
let fallbackSnapshot = null;
|
|
11577
|
-
try {
|
|
11578
|
-
const fullReader = typeof readMessages === "function" ? readMessages : null;
|
|
11579
|
-
const revision = readMessages.getRevision?.(sessionId);
|
|
11580
|
-
const previous = heapHolder.reconciledSnapshots.get(sessionId);
|
|
11581
|
-
const finalWatermark = previous && revision === previous.revision ? previous.count : revision !== undefined && readMessages.getCountAfterRevision ? previous && revision > previous.revision ? previous.count + readMessages.getCountAfterRevision(sessionId, previous.revision, revision) : readMessages.getCountAfterRevision(sessionId, -1, revision) : readMessages.getCount ? readMessages.getCount(sessionId) : (fallbackSnapshot = fullReader?.(sessionId) ?? []).length;
|
|
11582
|
-
let cursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
|
|
11583
|
-
let after = cursor === previous?.count ? previous.after : undefined;
|
|
11584
|
-
while (cursor < finalWatermark) {
|
|
11585
|
-
const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
|
|
11586
|
-
const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
|
|
11587
|
-
const retainedMessages = fallbackSnapshot ?? messages;
|
|
11588
|
-
heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
|
|
11589
|
-
withSqliteBackgroundWriter2(() => indexMessagesAfterOrdinal2(db, sessionId, messages, cursor, pageEnd));
|
|
11590
|
-
const nextCursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
|
|
11591
|
-
if (nextCursor <= cursor)
|
|
11592
|
-
break;
|
|
11593
|
-
cursor = nextCursor;
|
|
11594
|
-
const last = messages.at(-1);
|
|
11595
|
-
after = last?.ordinal === cursor && typeof last.createdAt === "number" ? { timeCreated: last.createdAt, id: last.id } : undefined;
|
|
11596
|
-
if (cursor < finalWatermark) {
|
|
11597
|
-
await yieldToEventLoop();
|
|
11598
|
-
}
|
|
11599
|
-
}
|
|
11600
|
-
if (isMessageIndexReconciledThrough2(db, sessionId, finalWatermark)) {
|
|
11601
|
-
heapHolder.reconciledSessions.add(sessionId);
|
|
11602
|
-
if (revision !== undefined) {
|
|
11603
|
-
if (!after && finalWatermark > 0 && readMessages.readPage) {
|
|
11604
|
-
const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
|
|
11605
|
-
if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
|
|
11606
|
-
after = { timeCreated: last.createdAt, id: last.id };
|
|
11607
|
-
}
|
|
11608
|
-
heapHolder.reconciledSnapshots.set(sessionId, {
|
|
11609
|
-
revision,
|
|
11610
|
-
count: finalWatermark,
|
|
11611
|
-
after
|
|
11612
|
-
});
|
|
11613
|
-
}
|
|
11614
|
-
} else {
|
|
11615
|
-
logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
|
|
11616
|
-
}
|
|
11617
|
-
} finally {
|
|
11618
|
-
heapHolder.activeReconcilerBuffers.delete(sessionId);
|
|
11619
|
-
}
|
|
11620
|
-
});
|
|
11621
|
-
return true;
|
|
11622
|
-
}
|
|
11623
|
-
function scheduleReconciliation(db, sessionId, readMessages) {
|
|
11624
|
-
if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
|
|
11541
|
+
beginBootQuietPeriod();
|
|
11542
|
+
const db = openTimerDatabaseOrNull("schedule timer registration");
|
|
11543
|
+
if (!db)
|
|
11625
11544
|
return;
|
|
11545
|
+
const dreamingEnabled = Boolean(args.dreamerConfig && args.dreamerConfig.disable !== true);
|
|
11546
|
+
const embeddingSweepEnabled = args.memoryEnabled === true;
|
|
11547
|
+
const commitIndexingEnabled = args.gitCommitIndexing?.enabled === true;
|
|
11548
|
+
const previousRegistration = registeredProjects.get(args.directory);
|
|
11549
|
+
const isNewRegistration = previousRegistration === undefined;
|
|
11550
|
+
if (previousRegistration && previousRegistration !== args) {
|
|
11551
|
+
const pendingStartup = startupTimers.get(args.directory);
|
|
11552
|
+
if (pendingStartup) {
|
|
11553
|
+
clearTimeout(pendingStartup);
|
|
11554
|
+
startupTimers.delete(args.directory);
|
|
11555
|
+
}
|
|
11626
11556
|
}
|
|
11627
|
-
|
|
11628
|
-
|
|
11629
|
-
|
|
11630
|
-
|
|
11631
|
-
|
|
11632
|
-
|
|
11633
|
-
|
|
11634
|
-
|
|
11635
|
-
|
|
11636
|
-
return;
|
|
11637
|
-
}
|
|
11638
|
-
inRootAsyncContext2(() => setTimeout(() => {
|
|
11639
|
-
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
11640
|
-
scheduleReconciliation(db, sessionId, readMessages);
|
|
11641
|
-
}, PREPARE_RETRY_MS)).unref?.();
|
|
11642
|
-
}).catch((error) => {
|
|
11643
|
-
logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
|
|
11644
|
-
if (isDatabaseLockedError(error))
|
|
11645
|
-
inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
|
|
11646
|
-
}).finally(() => {
|
|
11647
|
-
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
11648
|
-
if (appendedDuringReconciliation)
|
|
11649
|
-
scheduleReconciliation(db, sessionId, readMessages);
|
|
11650
|
-
});
|
|
11651
|
-
});
|
|
11652
|
-
});
|
|
11653
|
-
}
|
|
11654
|
-
function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
11655
|
-
const schedulingKey = `${sessionId}\x00${messageId}`;
|
|
11656
|
-
const epoch = sessionEpochs.get(sessionId) ?? 0;
|
|
11657
|
-
if (heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
11658
|
-
return;
|
|
11659
|
-
const activeTimer = heapHolder.incrementalTimers.get(schedulingKey);
|
|
11660
|
-
if (activeTimer)
|
|
11661
|
-
clearTimeout(activeTimer);
|
|
11662
|
-
const timer = inRootAsyncContext2(() => setTimeout(() => {
|
|
11663
|
-
heapHolder.incrementalTimers.delete(schedulingKey);
|
|
11664
|
-
heapHolder.pendingIncrementalKeys.add(schedulingKey);
|
|
11665
|
-
const indexMessage = async () => {
|
|
11666
|
-
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
11667
|
-
return;
|
|
11668
|
-
const message = typeof messageSource === "function" ? messageSource(sessionId, messageId) : messageSource;
|
|
11669
|
-
if (!message)
|
|
11670
|
-
return;
|
|
11671
|
-
const revisionKey = `${schedulingKey}\x00${getMessageIndexSourceIdentity2(message)}`;
|
|
11672
|
-
if (heapHolder.completedIncrementalKeys.has(revisionKey))
|
|
11673
|
-
return;
|
|
11674
|
-
const currentWatermark = getLastIndexedOrdinal2(db, sessionId);
|
|
11675
|
-
if (message.ordinal <= currentWatermark && isMessageIndexSourceCurrent2(db, sessionId, message)) {
|
|
11676
|
-
heapHolder.completedIncrementalKeys.add(revisionKey);
|
|
11677
|
-
return;
|
|
11678
|
-
}
|
|
11679
|
-
const wasReconciled = heapHolder.reconciledSessions.delete(sessionId);
|
|
11680
|
-
await indexSingleMessageOffThread(db, sessionId, message);
|
|
11681
|
-
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
11682
|
-
return;
|
|
11683
|
-
const finalWatermark = getLastIndexedOrdinal2(db, sessionId);
|
|
11684
|
-
if (wasReconciled && isMessageIndexReconciledThrough2(db, sessionId, finalWatermark)) {
|
|
11685
|
-
heapHolder.reconciledSessions.add(sessionId);
|
|
11686
|
-
}
|
|
11687
|
-
heapHolder.completedIncrementalKeys.add(revisionKey);
|
|
11688
|
-
};
|
|
11689
|
-
sourceReady(messageSource, sessionId).then((ready) => {
|
|
11690
|
-
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
|
|
11691
|
-
return;
|
|
11692
|
-
if (ready)
|
|
11693
|
-
return runWithSessionLock(sessionId, indexMessage);
|
|
11694
|
-
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), PREPARE_RETRY_MS).unref?.();
|
|
11695
|
-
}).catch((error) => {
|
|
11696
|
-
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
|
|
11697
|
-
return;
|
|
11698
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11699
|
-
logIndexingError(sessionId, `incremental index for ${messageId}`, error);
|
|
11700
|
-
if (isDatabaseLockedError(error))
|
|
11701
|
-
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), 1000).unref();
|
|
11702
|
-
}).finally(() => {
|
|
11703
|
-
if ((sessionEpochs.get(sessionId) ?? 0) === epoch)
|
|
11704
|
-
heapHolder.pendingIncrementalKeys.delete(schedulingKey);
|
|
11705
|
-
});
|
|
11706
|
-
}, INCREMENTAL_DEBOUNCE_MS));
|
|
11707
|
-
heapHolder.incrementalTimers.set(schedulingKey, timer);
|
|
11708
|
-
}
|
|
11709
|
-
async function indexSingleMessageOffThread(db, sessionId, message) {
|
|
11710
|
-
const path = getSqliteDatabasePath2(db);
|
|
11711
|
-
if (!path)
|
|
11712
|
-
return withSqliteBackgroundWriter2(() => indexSingleMessage2(db, sessionId, message));
|
|
11713
|
-
const cancellation = new Int32Array(new SharedArrayBuffer(4));
|
|
11714
|
-
const active = indexCancellations.get(sessionId) ?? new Set;
|
|
11715
|
-
active.add(cancellation);
|
|
11716
|
-
indexCancellations.set(sessionId, active);
|
|
11717
|
-
const result = await runSessionWarmupWorker({
|
|
11718
|
-
path,
|
|
11719
|
-
sessionId,
|
|
11720
|
-
indexMessage: message,
|
|
11721
|
-
harness: getHarness2(),
|
|
11722
|
-
indexCancellation: cancellation.buffer,
|
|
11723
|
-
...indexCoordinationInput2()
|
|
11724
|
-
}, {}).finally(() => {
|
|
11725
|
-
active.delete(cancellation);
|
|
11726
|
-
if (active.size === 0)
|
|
11727
|
-
indexCancellations.delete(sessionId);
|
|
11728
|
-
});
|
|
11729
|
-
if (!("inserted" in result))
|
|
11730
|
-
throw new Error("failure" in result ? result.detail : "unexpected indexing worker reply");
|
|
11731
|
-
if (result.measurements) {
|
|
11732
|
-
const sessions = workerMeasurements.get(db) ?? new Map;
|
|
11733
|
-
sessions.set(sessionId, result.measurements);
|
|
11734
|
-
workerMeasurements.set(db, sessions);
|
|
11735
|
-
if (result.measurements.skipped)
|
|
11736
|
-
log2(`[magic-context] incremental FTS skipped oversized source ${message.id} (${result.measurements.sourceBytes} bytes); identity and progress persisted`);
|
|
11737
|
-
}
|
|
11738
|
-
return result.inserted;
|
|
11739
|
-
}
|
|
11740
|
-
async function sweepOrphanedOpenCodeMessageIndexesOffThread(db, openSource, options = {}) {
|
|
11741
|
-
if (getHarness2() === "opencode" || getHarness2() === "opencode2")
|
|
11742
|
-
options = {
|
|
11743
|
-
...options,
|
|
11744
|
-
fenceLockNames: options.fenceLockNames ?? takeLkgRecoveryLockSweepPage()
|
|
11745
|
-
};
|
|
11746
|
-
if (getHarness2() === "opencode2")
|
|
11747
|
-
openSource = () => new Database2(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"), {
|
|
11748
|
-
readonly: true,
|
|
11749
|
-
fileMustExist: true
|
|
11750
|
-
});
|
|
11751
|
-
const path = getSqliteDatabasePath2(db);
|
|
11752
|
-
if (!path || getHarness2() !== "opencode" && getHarness2() !== "opencode2")
|
|
11753
|
-
return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, openSource, options);
|
|
11754
|
-
let source = null;
|
|
11755
|
-
let sourcePath = null;
|
|
11756
|
-
try {
|
|
11757
|
-
source = openSource();
|
|
11758
|
-
if (source)
|
|
11759
|
-
sourcePath = getSqliteDatabasePath2(source);
|
|
11760
|
-
} catch {} finally {
|
|
11761
|
-
if (sourcePath)
|
|
11762
|
-
source?.close();
|
|
11763
|
-
}
|
|
11764
|
-
if (!sourcePath)
|
|
11765
|
-
return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, () => source, options);
|
|
11766
|
-
const reply = await runSessionWarmupWorker({
|
|
11767
|
-
path,
|
|
11768
|
-
sessionId: "",
|
|
11769
|
-
harness: getHarness2(),
|
|
11770
|
-
orphanSweep: { sourcePath, options }
|
|
11771
|
-
}, {});
|
|
11772
|
-
if (!("orphanSweep" in reply))
|
|
11773
|
-
throw new Error("message history orphan sweep worker failed");
|
|
11774
|
-
return reply.orphanSweep;
|
|
11775
|
-
}
|
|
11776
|
-
function scheduleClearAndReindex(db, sessionId, readMessages) {
|
|
11777
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11778
|
-
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
11779
|
-
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
11780
|
-
clearCompletedIncrementalKeys(sessionId);
|
|
11781
|
-
const existing = heapHolder.clearAndReindexScheduledSessions.get(sessionId);
|
|
11782
|
-
if (existing) {
|
|
11783
|
-
existing.source = readMessages;
|
|
11784
|
-
return;
|
|
11785
|
-
}
|
|
11786
|
-
const pending = { source: readMessages };
|
|
11787
|
-
heapHolder.clearAndReindexScheduledSessions.set(sessionId, pending);
|
|
11788
|
-
scheduleAfterBootQuiet(() => {
|
|
11789
|
-
defer(() => {
|
|
11790
|
-
let cleared = false;
|
|
11791
|
-
runWithSessionLock(sessionId, () => {
|
|
11792
|
-
if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) !== pending)
|
|
11793
|
-
return;
|
|
11794
|
-
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
11795
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11796
|
-
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
11797
|
-
clearCompletedIncrementalKeys(sessionId);
|
|
11798
|
-
clearIndexedMessages2(db, sessionId);
|
|
11799
|
-
cleared = true;
|
|
11800
|
-
}).then(() => cleared ? reconcileSessionIndex(db, sessionId, pending.source) : undefined).catch((error) => {
|
|
11801
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11802
|
-
if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) === pending)
|
|
11803
|
-
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
11804
|
-
logIndexingError(sessionId, "clear and reindex", error);
|
|
11805
|
-
});
|
|
11806
|
-
});
|
|
11807
|
-
});
|
|
11808
|
-
}
|
|
11809
|
-
function getMessageIndexQueueHeapStats() {
|
|
11810
|
-
return {
|
|
11811
|
-
queueLength: heapHolder.reconciliationScheduledSessions.size + heapHolder.incrementalTimers.size + heapHolder.pendingIncrementalKeys.size,
|
|
11812
|
-
reconciliationScheduled: heapHolder.reconciliationScheduledSessions.size,
|
|
11813
|
-
incrementalTimers: heapHolder.incrementalTimers.size,
|
|
11814
|
-
pendingIncremental: heapHolder.pendingIncrementalKeys.size,
|
|
11815
|
-
activeSessionLocks: heapHolder.sessionLocks.size,
|
|
11816
|
-
completedIncrementalKeys: heapHolder.completedIncrementalKeys.size,
|
|
11817
|
-
activeBufferMessages: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + messages.length, 0),
|
|
11818
|
-
activeBufferBytes: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + serializedMessageBytes(messages), 0)
|
|
11819
|
-
};
|
|
11820
|
-
}
|
|
11821
|
-
function clearSessionTracking(sessionId) {
|
|
11822
|
-
sessionEpochs.set(sessionId, (sessionEpochs.get(sessionId) ?? 0) + 1);
|
|
11823
|
-
for (const cancellation of indexCancellations.get(sessionId) ?? [])
|
|
11824
|
-
Atomics.store(cancellation, 0, 1);
|
|
11825
|
-
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
11826
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11827
|
-
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
11828
|
-
heapHolder.stalledSessions.delete(sessionId);
|
|
11829
|
-
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
11830
|
-
heapHolder.sessionLocks.delete(sessionId);
|
|
11831
|
-
heapHolder.activeReconcilerBuffers.delete(sessionId);
|
|
11832
|
-
const prefix = `${sessionId}\x00`;
|
|
11833
|
-
for (const [key, timer] of heapHolder.incrementalTimers) {
|
|
11834
|
-
if (key.startsWith(prefix)) {
|
|
11835
|
-
clearTimeout(timer);
|
|
11836
|
-
heapHolder.incrementalTimers.delete(key);
|
|
11837
|
-
}
|
|
11838
|
-
}
|
|
11839
|
-
for (const key of heapHolder.pendingIncrementalKeys) {
|
|
11840
|
-
if (key.startsWith(prefix)) {
|
|
11841
|
-
heapHolder.pendingIncrementalKeys.delete(key);
|
|
11842
|
-
}
|
|
11843
|
-
}
|
|
11844
|
-
for (const key of heapHolder.completedIncrementalKeys) {
|
|
11845
|
-
if (key.startsWith(prefix))
|
|
11846
|
-
heapHolder.completedIncrementalKeys.delete(key);
|
|
11847
|
-
}
|
|
11848
|
-
}
|
|
11849
|
-
|
|
11850
|
-
// src/plugin/dream-timer.ts
|
|
11851
|
-
var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
|
|
11852
|
-
var GIT_COMMIT_BACKLOG_DRAIN_MAX_MS = 5 * 60 * 1000;
|
|
11853
|
-
var BOOT_PROJECT_JITTER_SLOT_MS = 1000;
|
|
11854
|
-
var activeTimer = null;
|
|
11855
|
-
var tickInFlight = false;
|
|
11856
|
-
var startupTickTimer = null;
|
|
11857
|
-
var startupTimers = new Map;
|
|
11858
|
-
var startupJitters = new Map;
|
|
11859
|
-
var nextStartupJitterSlot = 0;
|
|
11860
|
-
function directoryStillExists(directory) {
|
|
11861
|
-
try {
|
|
11862
|
-
return statSync2(directory).isDirectory();
|
|
11863
|
-
} catch {
|
|
11864
|
-
return false;
|
|
11865
|
-
}
|
|
11866
|
-
}
|
|
11867
|
-
function openTimerDatabaseOrNull(context) {
|
|
11868
|
-
let db;
|
|
11869
|
-
try {
|
|
11870
|
-
db = openCurrentDatabase();
|
|
11871
|
-
} catch (error) {
|
|
11872
|
-
log2(`[dreamer] storage fatal; skipping ${context}: ${getErrorMessage(error)}`);
|
|
11873
|
-
return null;
|
|
11874
|
-
}
|
|
11875
|
-
if (!db) {
|
|
11876
|
-
log2(`[dreamer] storage unavailable; skipping ${context} (the cache schema is newer than this binary supports — restart/upgrade OpenCode/Pi/Magic Context to recover)`);
|
|
11877
|
-
return null;
|
|
11878
|
-
}
|
|
11879
|
-
return db;
|
|
11880
|
-
}
|
|
11881
|
-
var refusedEmptyIdentityDirectories = new Set;
|
|
11882
|
-
function logEmptyIdentityRefusalOnce(directory) {
|
|
11883
|
-
if (refusedEmptyIdentityDirectories.has(directory))
|
|
11884
|
-
return;
|
|
11885
|
-
refusedEmptyIdentityDirectories.add(directory);
|
|
11886
|
-
log2(`[dreamer] not registering ${directory}: it has no project identity, so no project-scoped work runs for it`);
|
|
11887
|
-
}
|
|
11888
|
-
var registeredProjects = new Map;
|
|
11889
|
-
function stopDreamScheduleTimerIfIdle() {
|
|
11890
|
-
if (registeredProjects.size !== 0)
|
|
11891
|
-
return;
|
|
11892
|
-
const stopped = activeTimer !== null || startupTickTimer !== null;
|
|
11893
|
-
if (activeTimer) {
|
|
11894
|
-
clearInterval(activeTimer);
|
|
11895
|
-
activeTimer = null;
|
|
11896
|
-
}
|
|
11897
|
-
if (startupTickTimer) {
|
|
11898
|
-
clearTimeout(startupTickTimer);
|
|
11899
|
-
startupTickTimer = null;
|
|
11900
|
-
}
|
|
11901
|
-
startupJitters.clear();
|
|
11902
|
-
nextStartupJitterSlot = 0;
|
|
11903
|
-
if (stopped)
|
|
11904
|
-
log2("[dreamer] stopped dream schedule timer (no projects left)");
|
|
11905
|
-
}
|
|
11906
|
-
async function startDreamScheduleTimer(args) {
|
|
11907
|
-
if (!isUsableProjectIdentity(args.projectIdentity)) {
|
|
11908
|
-
logEmptyIdentityRefusalOnce(args.directory);
|
|
11909
|
-
return;
|
|
11910
|
-
}
|
|
11911
|
-
beginBootQuietPeriod();
|
|
11912
|
-
const db = openTimerDatabaseOrNull("schedule timer registration");
|
|
11913
|
-
if (!db)
|
|
11914
|
-
return;
|
|
11915
|
-
const dreamingEnabled = Boolean(args.dreamerConfig && args.dreamerConfig.disable !== true);
|
|
11916
|
-
const embeddingSweepEnabled = args.memoryEnabled === true;
|
|
11917
|
-
const commitIndexingEnabled = args.gitCommitIndexing?.enabled === true;
|
|
11918
|
-
const previousRegistration = registeredProjects.get(args.directory);
|
|
11919
|
-
const isNewRegistration = previousRegistration === undefined;
|
|
11920
|
-
if (previousRegistration && previousRegistration !== args) {
|
|
11921
|
-
const pendingStartup = startupTimers.get(args.directory);
|
|
11922
|
-
if (pendingStartup) {
|
|
11923
|
-
clearTimeout(pendingStartup);
|
|
11924
|
-
startupTimers.delete(args.directory);
|
|
11925
|
-
}
|
|
11926
|
-
}
|
|
11927
|
-
registeredProjects.set(args.directory, args);
|
|
11928
|
-
if (isNewRegistration) {
|
|
11929
|
-
log2(`[dreamer] registered project ${args.projectIdentity} (dreaming=${dreamingEnabled} embeddings=${embeddingSweepEnabled} commits=${commitIndexingEnabled}; total=${registeredProjects.size})`);
|
|
11930
|
-
}
|
|
11931
|
-
if (!activeTimer) {
|
|
11932
|
-
log2(`[dreamer] started independent schedule timer (every ${DREAM_TIMER_INTERVAL_MS / 60000}m)`);
|
|
11933
|
-
startupTickTimer = scheduleAfterBootQuiet(() => {
|
|
11934
|
-
startupTickTimer = null;
|
|
11935
|
-
runTick("startup");
|
|
11557
|
+
registeredProjects.set(args.directory, args);
|
|
11558
|
+
if (isNewRegistration) {
|
|
11559
|
+
log2(`[dreamer] registered project ${args.projectIdentity} (dreaming=${dreamingEnabled} embeddings=${embeddingSweepEnabled} commits=${commitIndexingEnabled}; total=${registeredProjects.size})`);
|
|
11560
|
+
}
|
|
11561
|
+
if (!activeTimer) {
|
|
11562
|
+
log2(`[dreamer] started independent schedule timer (every ${DREAM_TIMER_INTERVAL_MS / 60000}m)`);
|
|
11563
|
+
startupTickTimer = scheduleAfterBootQuiet(() => {
|
|
11564
|
+
startupTickTimer = null;
|
|
11565
|
+
runTick("startup");
|
|
11936
11566
|
});
|
|
11937
11567
|
const timer = inRootAsyncContext2(() => setInterval(() => runTick("interval"), DREAM_TIMER_INTERVAL_MS));
|
|
11938
11568
|
if (typeof timer === "object" && "unref" in timer) {
|
|
@@ -12042,12 +11672,6 @@ async function runMessageHistoryMaintenance(db) {
|
|
|
12042
11672
|
log2(`[message-index] pending Rust session cleanup: cleared=${rustCleanup.cleared} failed=${rustCleanup.failedSessionIds.length}`);
|
|
12043
11673
|
}
|
|
12044
11674
|
}
|
|
12045
|
-
const sweep = await sweepOrphanedOpenCodeMessageIndexesOffThread(db, openOpenCodeDb);
|
|
12046
|
-
if (sweep.reason)
|
|
12047
|
-
log2(`[message-index] orphan sweep parked: ${sweep.reason}`);
|
|
12048
|
-
if (sweep.deleted > 0) {
|
|
12049
|
-
log2(`[message-index] orphan sweep: scanned=${sweep.scanned} deleted=${sweep.deleted} cursor=${sweep.cursor || "<complete>"}`);
|
|
12050
|
-
}
|
|
12051
11675
|
}
|
|
12052
11676
|
function startupJitterMs(directory) {
|
|
12053
11677
|
const existing = startupJitters.get(directory);
|
|
@@ -13040,104 +12664,447 @@ function createScheduler(config) {
|
|
|
13040
12664
|
} else {
|
|
13041
12665
|
log2(`[magic-context] invalid cache_ttl "${sessionMeta.cacheTtl}"; falling back to default 5m`, error);
|
|
13042
12666
|
}
|
|
13043
|
-
ttlMs = parseCacheTtl("5m");
|
|
12667
|
+
ttlMs = parseCacheTtl("5m");
|
|
12668
|
+
}
|
|
12669
|
+
const elapsedTime = currentTime - sessionMeta.lastResponseTime;
|
|
12670
|
+
if (elapsedTime > ttlMs) {
|
|
12671
|
+
return "execute";
|
|
12672
|
+
}
|
|
12673
|
+
return "defer";
|
|
12674
|
+
}
|
|
12675
|
+
};
|
|
12676
|
+
}
|
|
12677
|
+
function computeHardCacheExpired(cacheTtl, lastResponseTime, now, onInvalid) {
|
|
12678
|
+
let ttlMs;
|
|
12679
|
+
try {
|
|
12680
|
+
ttlMs = parseCacheTtl(cacheTtl);
|
|
12681
|
+
} catch (error) {
|
|
12682
|
+
onInvalid?.(error);
|
|
12683
|
+
ttlMs = 5 * 60 * 1000;
|
|
12684
|
+
}
|
|
12685
|
+
return lastResponseTime > 0 && now - lastResponseTime > ttlMs;
|
|
12686
|
+
}
|
|
12687
|
+
|
|
12688
|
+
// src/features/magic-context/storage-unavailable-reason.ts
|
|
12689
|
+
function describeStorageUnavailability(fallbackCause) {
|
|
12690
|
+
const migration = getMigrationOnOpenRefusal();
|
|
12691
|
+
const blockingProcesses = migration?.blockingProcesses ?? migration?.serverPids.map((pid) => ({ kind: "process", pid })) ?? [];
|
|
12692
|
+
if (migration && (blockingProcesses.length > 0 || migration.unreadableFile)) {
|
|
12693
|
+
return {
|
|
12694
|
+
kind: "migration_guard",
|
|
12695
|
+
persistedVersion: migration.persistedVersion,
|
|
12696
|
+
supportedVersion: migration.supportedVersion,
|
|
12697
|
+
blockingProcesses,
|
|
12698
|
+
...migration.unreadableFile ? { unreadableFile: migration.unreadableFile } : {},
|
|
12699
|
+
...migration.unreadableArm ? { unreadableArm: migration.unreadableArm } : {}
|
|
12700
|
+
};
|
|
12701
|
+
}
|
|
12702
|
+
const fence = getSchemaFenceRejection();
|
|
12703
|
+
if (fence) {
|
|
12704
|
+
return {
|
|
12705
|
+
kind: "schema_fence",
|
|
12706
|
+
persistedVersion: fence.persistedVersion,
|
|
12707
|
+
supportedVersion: fence.supportedVersion
|
|
12708
|
+
};
|
|
12709
|
+
}
|
|
12710
|
+
return { kind: "storage_failure", cause: fallbackCause };
|
|
12711
|
+
}
|
|
12712
|
+
|
|
12713
|
+
// src/plugin/rpc-handlers.ts
|
|
12714
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
12715
|
+
import { once } from "node:events";
|
|
12716
|
+
import { rmSync as rmSync2 } from "node:fs";
|
|
12717
|
+
import { join as join5 } from "node:path";
|
|
12718
|
+
|
|
12719
|
+
// src/features/magic-context/memory/memory-diagnostics.ts
|
|
12720
|
+
function emptyMemoryImportanceHistogram() {
|
|
12721
|
+
return {
|
|
12722
|
+
total: 0,
|
|
12723
|
+
unclassified: 0,
|
|
12724
|
+
bands: {
|
|
12725
|
+
"0-19": 0,
|
|
12726
|
+
"20-39": 0,
|
|
12727
|
+
"40-59": 0,
|
|
12728
|
+
"60-79": 0,
|
|
12729
|
+
"80-100": 0
|
|
12730
|
+
}
|
|
12731
|
+
};
|
|
12732
|
+
}
|
|
12733
|
+
function readHistogramRow(db, projectPath, classifiedColumn) {
|
|
12734
|
+
const unclassified = classifiedColumn ? "SUM(CASE WHEN classified_at IS NULL THEN 1 ELSE 0 END)" : "COUNT(*)";
|
|
12735
|
+
return db.prepare(`SELECT COUNT(*) AS total,
|
|
12736
|
+
${unclassified} AS unclassified,
|
|
12737
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 0 AND 19 THEN 1 ELSE 0 END) AS band_0_19,
|
|
12738
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 20 AND 39 THEN 1 ELSE 0 END) AS band_20_39,
|
|
12739
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 40 AND 59 THEN 1 ELSE 0 END) AS band_40_59,
|
|
12740
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 60 AND 79 THEN 1 ELSE 0 END) AS band_60_79,
|
|
12741
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 80 AND 100 THEN 1 ELSE 0 END) AS band_80_100
|
|
12742
|
+
FROM memories
|
|
12743
|
+
WHERE project_path = ? AND status = 'active'`).get(projectPath);
|
|
12744
|
+
}
|
|
12745
|
+
function getActiveMemoryImportanceHistogram(db, projectPath) {
|
|
12746
|
+
let row;
|
|
12747
|
+
try {
|
|
12748
|
+
row = readHistogramRow(db, projectPath, true);
|
|
12749
|
+
} catch (error) {
|
|
12750
|
+
if (!String(error).includes("no such column: classified_at"))
|
|
12751
|
+
throw error;
|
|
12752
|
+
row = readHistogramRow(db, projectPath, false);
|
|
12753
|
+
}
|
|
12754
|
+
return {
|
|
12755
|
+
total: Number(row.total ?? 0),
|
|
12756
|
+
unclassified: Number(row.unclassified ?? 0),
|
|
12757
|
+
bands: {
|
|
12758
|
+
"0-19": Number(row.band_0_19 ?? 0),
|
|
12759
|
+
"20-39": Number(row.band_20_39 ?? 0),
|
|
12760
|
+
"40-59": Number(row.band_40_59 ?? 0),
|
|
12761
|
+
"60-79": Number(row.band_60_79 ?? 0),
|
|
12762
|
+
"80-100": Number(row.band_80_100 ?? 0)
|
|
12763
|
+
}
|
|
12764
|
+
};
|
|
12765
|
+
}
|
|
12766
|
+
|
|
12767
|
+
// src/features/magic-context/message-index-async.ts
|
|
12768
|
+
var indexCancellations = new Map;
|
|
12769
|
+
var sessionEpochs = new Map;
|
|
12770
|
+
var workerMeasurements = new WeakMap;
|
|
12771
|
+
function isDatabaseLockedError(error) {
|
|
12772
|
+
if (!error || typeof error !== "object")
|
|
12773
|
+
return false;
|
|
12774
|
+
const e = error;
|
|
12775
|
+
if (typeof e.code === "string") {
|
|
12776
|
+
if (e.code === "SQLITE_BUSY" || e.code === "SQLITE_LOCKED")
|
|
12777
|
+
return true;
|
|
12778
|
+
}
|
|
12779
|
+
if (typeof e.message === "string") {
|
|
12780
|
+
if (/database is locked/i.test(e.message))
|
|
12781
|
+
return true;
|
|
12782
|
+
if (/sqlite_(busy|locked)/i.test(e.message))
|
|
12783
|
+
return true;
|
|
12784
|
+
}
|
|
12785
|
+
return false;
|
|
12786
|
+
}
|
|
12787
|
+
var INCREMENTAL_DEBOUNCE_MS = 100;
|
|
12788
|
+
var RECONCILIATION_BATCH_SIZE = 100;
|
|
12789
|
+
|
|
12790
|
+
class MagicContextMessageIndexHeapHolder {
|
|
12791
|
+
reconciledSessions = new Set;
|
|
12792
|
+
reconciledSnapshots = new Map;
|
|
12793
|
+
stalledSessions = new Set;
|
|
12794
|
+
reconciliationScheduledSessions = new Set;
|
|
12795
|
+
clearAndReindexScheduledSessions = new Map;
|
|
12796
|
+
sessionLocks = new Map;
|
|
12797
|
+
incrementalTimers = new Map;
|
|
12798
|
+
pendingIncrementalKeys = new Set;
|
|
12799
|
+
completedIncrementalKeys = new Set;
|
|
12800
|
+
activeReconcilerBuffers = new Map;
|
|
12801
|
+
}
|
|
12802
|
+
var heapHolder = new MagicContextMessageIndexHeapHolder;
|
|
12803
|
+
function clearCompletedIncrementalKeys(sessionId) {
|
|
12804
|
+
const prefix = `${sessionId}\x00`;
|
|
12805
|
+
for (const key of heapHolder.completedIncrementalKeys) {
|
|
12806
|
+
if (key.startsWith(prefix))
|
|
12807
|
+
heapHolder.completedIncrementalKeys.delete(key);
|
|
12808
|
+
}
|
|
12809
|
+
}
|
|
12810
|
+
var PREPARE_RETRY_MS = 60000;
|
|
12811
|
+
async function sourceReady(source, sessionId) {
|
|
12812
|
+
const prepare = source?.prepare;
|
|
12813
|
+
return typeof prepare === "function" ? prepare(sessionId) : true;
|
|
12814
|
+
}
|
|
12815
|
+
function defer(fn) {
|
|
12816
|
+
const immediate = globalThis.setImmediate;
|
|
12817
|
+
if (typeof immediate === "function") {
|
|
12818
|
+
inRootAsyncContext2(() => immediate(fn));
|
|
12819
|
+
return;
|
|
12820
|
+
}
|
|
12821
|
+
inRootAsyncContext2(() => setTimeout(fn, 0));
|
|
12822
|
+
}
|
|
12823
|
+
function yieldToEventLoop() {
|
|
12824
|
+
return new Promise((resolve) => defer(resolve));
|
|
12825
|
+
}
|
|
12826
|
+
function runWithSessionLock(sessionId, operation) {
|
|
12827
|
+
const previous = heapHolder.sessionLocks.get(sessionId) ?? Promise.resolve();
|
|
12828
|
+
const run = previous.catch(() => {
|
|
12829
|
+
return;
|
|
12830
|
+
}).then(async () => {
|
|
12831
|
+
await operation();
|
|
12832
|
+
});
|
|
12833
|
+
heapHolder.sessionLocks.set(sessionId, run);
|
|
12834
|
+
run.finally(() => {
|
|
12835
|
+
if (heapHolder.sessionLocks.get(sessionId) === run) {
|
|
12836
|
+
heapHolder.sessionLocks.delete(sessionId);
|
|
12837
|
+
}
|
|
12838
|
+
}).catch(() => {
|
|
12839
|
+
return;
|
|
12840
|
+
});
|
|
12841
|
+
return run;
|
|
12842
|
+
}
|
|
12843
|
+
function logIndexingError(sessionId, action, error) {
|
|
12844
|
+
if (isDatabaseLockedError(error)) {
|
|
12845
|
+
sessionLog2(sessionId, `message FTS async ${action} skipped (database busy; will retry on next reconciliation)`);
|
|
12846
|
+
return;
|
|
12847
|
+
}
|
|
12848
|
+
sessionLog2(sessionId, `message FTS async ${action} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
12849
|
+
log2(`[message-index-async] ${action} failed for ${sessionId}:`, error);
|
|
12850
|
+
}
|
|
12851
|
+
function serializedMessageBytes(messages) {
|
|
12852
|
+
try {
|
|
12853
|
+
return Buffer.byteLength(JSON.stringify(messages));
|
|
12854
|
+
} catch {
|
|
12855
|
+
return 0;
|
|
12856
|
+
}
|
|
12857
|
+
}
|
|
12858
|
+
function logReconciliationStall(sessionId, reason) {
|
|
12859
|
+
if (heapHolder.stalledSessions.has(sessionId))
|
|
12860
|
+
return;
|
|
12861
|
+
heapHolder.stalledSessions.add(sessionId);
|
|
12862
|
+
sessionLog2(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
|
|
12863
|
+
}
|
|
12864
|
+
async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
12865
|
+
if (!await sourceReady(readMessages, sessionId)) {
|
|
12866
|
+
logReconciliationStall(sessionId, "raw message reader is not ready");
|
|
12867
|
+
return false;
|
|
12868
|
+
}
|
|
12869
|
+
await runWithSessionLock(sessionId, async () => {
|
|
12870
|
+
if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId))
|
|
12871
|
+
return;
|
|
12872
|
+
let fallbackSnapshot = null;
|
|
12873
|
+
try {
|
|
12874
|
+
const fullReader = typeof readMessages === "function" ? readMessages : null;
|
|
12875
|
+
const revision = readMessages.getRevision?.(sessionId);
|
|
12876
|
+
const previous = heapHolder.reconciledSnapshots.get(sessionId);
|
|
12877
|
+
const finalWatermark = previous && revision === previous.revision ? previous.count : revision !== undefined && readMessages.getCountAfterRevision ? previous && revision > previous.revision ? previous.count + readMessages.getCountAfterRevision(sessionId, previous.revision, revision) : readMessages.getCountAfterRevision(sessionId, -1, revision) : readMessages.getCount ? readMessages.getCount(sessionId) : (fallbackSnapshot = fullReader?.(sessionId) ?? []).length;
|
|
12878
|
+
let cursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
|
|
12879
|
+
let after = cursor === previous?.count ? previous.after : undefined;
|
|
12880
|
+
while (cursor < finalWatermark) {
|
|
12881
|
+
const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
|
|
12882
|
+
const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
|
|
12883
|
+
const retainedMessages = fallbackSnapshot ?? messages;
|
|
12884
|
+
heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
|
|
12885
|
+
withSqliteBackgroundWriter2(() => indexMessagesAfterOrdinal(db, sessionId, messages, cursor, pageEnd));
|
|
12886
|
+
const nextCursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
|
|
12887
|
+
if (nextCursor <= cursor)
|
|
12888
|
+
break;
|
|
12889
|
+
cursor = nextCursor;
|
|
12890
|
+
const last = messages.at(-1);
|
|
12891
|
+
after = last?.ordinal === cursor && typeof last.createdAt === "number" ? { timeCreated: last.createdAt, id: last.id } : undefined;
|
|
12892
|
+
if (cursor < finalWatermark) {
|
|
12893
|
+
await yieldToEventLoop();
|
|
12894
|
+
}
|
|
12895
|
+
}
|
|
12896
|
+
if (isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
|
|
12897
|
+
heapHolder.reconciledSessions.add(sessionId);
|
|
12898
|
+
if (revision !== undefined) {
|
|
12899
|
+
if (!after && finalWatermark > 0 && readMessages.readPage) {
|
|
12900
|
+
const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
|
|
12901
|
+
if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
|
|
12902
|
+
after = { timeCreated: last.createdAt, id: last.id };
|
|
12903
|
+
}
|
|
12904
|
+
heapHolder.reconciledSnapshots.set(sessionId, {
|
|
12905
|
+
revision,
|
|
12906
|
+
count: finalWatermark,
|
|
12907
|
+
after
|
|
12908
|
+
});
|
|
12909
|
+
}
|
|
12910
|
+
} else {
|
|
12911
|
+
logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
|
|
12912
|
+
}
|
|
12913
|
+
} finally {
|
|
12914
|
+
heapHolder.activeReconcilerBuffers.delete(sessionId);
|
|
12915
|
+
}
|
|
12916
|
+
});
|
|
12917
|
+
return true;
|
|
12918
|
+
}
|
|
12919
|
+
function scheduleReconciliation(db, sessionId, readMessages) {
|
|
12920
|
+
if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
|
|
12921
|
+
return;
|
|
12922
|
+
}
|
|
12923
|
+
heapHolder.reconciliationScheduledSessions.add(sessionId);
|
|
12924
|
+
scheduleAfterBootQuiet(() => {
|
|
12925
|
+
defer(() => {
|
|
12926
|
+
let appendedDuringReconciliation = false;
|
|
12927
|
+
const previousSnapshot = heapHolder.reconciledSnapshots.get(sessionId);
|
|
12928
|
+
reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
|
|
12929
|
+
if (ran) {
|
|
12930
|
+
const snapshot = heapHolder.reconciledSnapshots.get(sessionId);
|
|
12931
|
+
appendedDuringReconciliation = snapshot !== undefined && snapshot !== previousSnapshot && readMessages.getRevision !== undefined && readMessages.getRevision(sessionId) !== snapshot.revision;
|
|
12932
|
+
return;
|
|
12933
|
+
}
|
|
12934
|
+
inRootAsyncContext2(() => setTimeout(() => {
|
|
12935
|
+
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
12936
|
+
scheduleReconciliation(db, sessionId, readMessages);
|
|
12937
|
+
}, PREPARE_RETRY_MS)).unref?.();
|
|
12938
|
+
}).catch((error) => {
|
|
12939
|
+
logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
|
|
12940
|
+
if (isDatabaseLockedError(error))
|
|
12941
|
+
inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
|
|
12942
|
+
}).finally(() => {
|
|
12943
|
+
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
12944
|
+
if (appendedDuringReconciliation)
|
|
12945
|
+
scheduleReconciliation(db, sessionId, readMessages);
|
|
12946
|
+
});
|
|
12947
|
+
});
|
|
12948
|
+
});
|
|
12949
|
+
}
|
|
12950
|
+
function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
12951
|
+
const schedulingKey = `${sessionId}\x00${messageId}`;
|
|
12952
|
+
const epoch = sessionEpochs.get(sessionId) ?? 0;
|
|
12953
|
+
if (heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
12954
|
+
return;
|
|
12955
|
+
const activeTimer = heapHolder.incrementalTimers.get(schedulingKey);
|
|
12956
|
+
if (activeTimer)
|
|
12957
|
+
clearTimeout(activeTimer);
|
|
12958
|
+
const timer = inRootAsyncContext2(() => setTimeout(() => {
|
|
12959
|
+
heapHolder.incrementalTimers.delete(schedulingKey);
|
|
12960
|
+
heapHolder.pendingIncrementalKeys.add(schedulingKey);
|
|
12961
|
+
const indexMessage = async () => {
|
|
12962
|
+
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
12963
|
+
return;
|
|
12964
|
+
const message = typeof messageSource === "function" ? messageSource(sessionId, messageId) : messageSource;
|
|
12965
|
+
if (!message)
|
|
12966
|
+
return;
|
|
12967
|
+
const revisionKey = `${schedulingKey}\x00${getMessageIndexSourceIdentity(message)}`;
|
|
12968
|
+
if (heapHolder.completedIncrementalKeys.has(revisionKey))
|
|
12969
|
+
return;
|
|
12970
|
+
const currentWatermark = getLastIndexedOrdinal(db, sessionId);
|
|
12971
|
+
if (message.ordinal <= currentWatermark && isMessageIndexSourceCurrent(db, sessionId, message)) {
|
|
12972
|
+
heapHolder.completedIncrementalKeys.add(revisionKey);
|
|
12973
|
+
return;
|
|
13044
12974
|
}
|
|
13045
|
-
const
|
|
13046
|
-
|
|
13047
|
-
|
|
12975
|
+
const wasReconciled = heapHolder.reconciledSessions.delete(sessionId);
|
|
12976
|
+
await indexSingleMessageOffThread(db, sessionId, message);
|
|
12977
|
+
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
12978
|
+
return;
|
|
12979
|
+
const finalWatermark = getLastIndexedOrdinal(db, sessionId);
|
|
12980
|
+
if (wasReconciled && isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
|
|
12981
|
+
heapHolder.reconciledSessions.add(sessionId);
|
|
13048
12982
|
}
|
|
13049
|
-
|
|
13050
|
-
}
|
|
13051
|
-
|
|
12983
|
+
heapHolder.completedIncrementalKeys.add(revisionKey);
|
|
12984
|
+
};
|
|
12985
|
+
sourceReady(messageSource, sessionId).then((ready) => {
|
|
12986
|
+
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
|
|
12987
|
+
return;
|
|
12988
|
+
if (ready)
|
|
12989
|
+
return runWithSessionLock(sessionId, indexMessage);
|
|
12990
|
+
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), PREPARE_RETRY_MS).unref?.();
|
|
12991
|
+
}).catch((error) => {
|
|
12992
|
+
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
|
|
12993
|
+
return;
|
|
12994
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
12995
|
+
logIndexingError(sessionId, `incremental index for ${messageId}`, error);
|
|
12996
|
+
if (isDatabaseLockedError(error))
|
|
12997
|
+
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), 1000).unref();
|
|
12998
|
+
}).finally(() => {
|
|
12999
|
+
if ((sessionEpochs.get(sessionId) ?? 0) === epoch)
|
|
13000
|
+
heapHolder.pendingIncrementalKeys.delete(schedulingKey);
|
|
13001
|
+
});
|
|
13002
|
+
}, INCREMENTAL_DEBOUNCE_MS));
|
|
13003
|
+
heapHolder.incrementalTimers.set(schedulingKey, timer);
|
|
13052
13004
|
}
|
|
13053
|
-
function
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13057
|
-
|
|
13058
|
-
|
|
13059
|
-
|
|
13005
|
+
async function indexSingleMessageOffThread(db, sessionId, message) {
|
|
13006
|
+
const path = getSqliteDatabasePath2(db);
|
|
13007
|
+
if (!path)
|
|
13008
|
+
return withSqliteBackgroundWriter2(() => indexSingleMessage(db, sessionId, message));
|
|
13009
|
+
const cancellation = new Int32Array(new SharedArrayBuffer(4));
|
|
13010
|
+
const active = indexCancellations.get(sessionId) ?? new Set;
|
|
13011
|
+
active.add(cancellation);
|
|
13012
|
+
indexCancellations.set(sessionId, active);
|
|
13013
|
+
const result = await runSessionWarmupWorker({
|
|
13014
|
+
path,
|
|
13015
|
+
sessionId,
|
|
13016
|
+
indexMessage: message,
|
|
13017
|
+
harness: getHarness2(),
|
|
13018
|
+
indexCancellation: cancellation.buffer,
|
|
13019
|
+
...indexCoordinationInput2()
|
|
13020
|
+
}, {}).finally(() => {
|
|
13021
|
+
active.delete(cancellation);
|
|
13022
|
+
if (active.size === 0)
|
|
13023
|
+
indexCancellations.delete(sessionId);
|
|
13024
|
+
});
|
|
13025
|
+
if (!("inserted" in result))
|
|
13026
|
+
throw new Error("failure" in result ? result.detail : "unexpected indexing worker reply");
|
|
13027
|
+
if (result.measurements) {
|
|
13028
|
+
const sessions = workerMeasurements.get(db) ?? new Map;
|
|
13029
|
+
sessions.set(sessionId, result.measurements);
|
|
13030
|
+
workerMeasurements.set(db, sessions);
|
|
13031
|
+
if (result.measurements.skipped)
|
|
13032
|
+
log2(`[magic-context] incremental FTS skipped oversized source ${message.id} (${result.measurements.sourceBytes} bytes); identity and progress persisted`);
|
|
13060
13033
|
}
|
|
13061
|
-
return
|
|
13034
|
+
return result.inserted;
|
|
13062
13035
|
}
|
|
13063
|
-
|
|
13064
|
-
|
|
13065
|
-
|
|
13066
|
-
|
|
13067
|
-
|
|
13068
|
-
|
|
13069
|
-
|
|
13070
|
-
|
|
13071
|
-
|
|
13072
|
-
supportedVersion: migration.supportedVersion,
|
|
13073
|
-
blockingProcesses,
|
|
13074
|
-
...migration.unreadableFile ? { unreadableFile: migration.unreadableFile } : {},
|
|
13075
|
-
...migration.unreadableArm ? { unreadableArm: migration.unreadableArm } : {}
|
|
13076
|
-
};
|
|
13077
|
-
}
|
|
13078
|
-
const fence = getSchemaFenceRejection();
|
|
13079
|
-
if (fence) {
|
|
13080
|
-
return {
|
|
13081
|
-
kind: "schema_fence",
|
|
13082
|
-
persistedVersion: fence.persistedVersion,
|
|
13083
|
-
supportedVersion: fence.supportedVersion
|
|
13084
|
-
};
|
|
13036
|
+
function scheduleClearAndReindex(db, sessionId, readMessages) {
|
|
13037
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
13038
|
+
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
13039
|
+
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
13040
|
+
clearCompletedIncrementalKeys(sessionId);
|
|
13041
|
+
const existing = heapHolder.clearAndReindexScheduledSessions.get(sessionId);
|
|
13042
|
+
if (existing) {
|
|
13043
|
+
existing.source = readMessages;
|
|
13044
|
+
return;
|
|
13085
13045
|
}
|
|
13086
|
-
|
|
13046
|
+
const pending = { source: readMessages };
|
|
13047
|
+
heapHolder.clearAndReindexScheduledSessions.set(sessionId, pending);
|
|
13048
|
+
scheduleAfterBootQuiet(() => {
|
|
13049
|
+
defer(() => {
|
|
13050
|
+
let cleared = false;
|
|
13051
|
+
runWithSessionLock(sessionId, () => {
|
|
13052
|
+
if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) !== pending)
|
|
13053
|
+
return;
|
|
13054
|
+
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
13055
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
13056
|
+
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
13057
|
+
clearCompletedIncrementalKeys(sessionId);
|
|
13058
|
+
clearIndexedMessages(db, sessionId);
|
|
13059
|
+
cleared = true;
|
|
13060
|
+
}).then(() => cleared ? reconcileSessionIndex(db, sessionId, pending.source) : undefined).catch((error) => {
|
|
13061
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
13062
|
+
if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) === pending)
|
|
13063
|
+
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
13064
|
+
logIndexingError(sessionId, "clear and reindex", error);
|
|
13065
|
+
});
|
|
13066
|
+
});
|
|
13067
|
+
});
|
|
13087
13068
|
}
|
|
13088
|
-
|
|
13089
|
-
// src/plugin/rpc-handlers.ts
|
|
13090
|
-
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
13091
|
-
import { once } from "node:events";
|
|
13092
|
-
import { rmSync as rmSync2 } from "node:fs";
|
|
13093
|
-
import { join as join5 } from "node:path";
|
|
13094
|
-
|
|
13095
|
-
// src/features/magic-context/memory/memory-diagnostics.ts
|
|
13096
|
-
function emptyMemoryImportanceHistogram() {
|
|
13069
|
+
function getMessageIndexQueueHeapStats() {
|
|
13097
13070
|
return {
|
|
13098
|
-
|
|
13099
|
-
|
|
13100
|
-
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
}
|
|
13071
|
+
queueLength: heapHolder.reconciliationScheduledSessions.size + heapHolder.incrementalTimers.size + heapHolder.pendingIncrementalKeys.size,
|
|
13072
|
+
reconciliationScheduled: heapHolder.reconciliationScheduledSessions.size,
|
|
13073
|
+
incrementalTimers: heapHolder.incrementalTimers.size,
|
|
13074
|
+
pendingIncremental: heapHolder.pendingIncrementalKeys.size,
|
|
13075
|
+
activeSessionLocks: heapHolder.sessionLocks.size,
|
|
13076
|
+
completedIncrementalKeys: heapHolder.completedIncrementalKeys.size,
|
|
13077
|
+
activeBufferMessages: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + messages.length, 0),
|
|
13078
|
+
activeBufferBytes: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + serializedMessageBytes(messages), 0)
|
|
13107
13079
|
};
|
|
13108
13080
|
}
|
|
13109
|
-
function
|
|
13110
|
-
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
}
|
|
13121
|
-
|
|
13122
|
-
|
|
13123
|
-
|
|
13124
|
-
|
|
13125
|
-
|
|
13126
|
-
if (!String(error).includes("no such column: classified_at"))
|
|
13127
|
-
throw error;
|
|
13128
|
-
row = readHistogramRow(db, projectPath, false);
|
|
13081
|
+
function clearSessionTracking(sessionId) {
|
|
13082
|
+
sessionEpochs.set(sessionId, (sessionEpochs.get(sessionId) ?? 0) + 1);
|
|
13083
|
+
for (const cancellation of indexCancellations.get(sessionId) ?? [])
|
|
13084
|
+
Atomics.store(cancellation, 0, 1);
|
|
13085
|
+
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
13086
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
13087
|
+
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
13088
|
+
heapHolder.stalledSessions.delete(sessionId);
|
|
13089
|
+
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
13090
|
+
heapHolder.sessionLocks.delete(sessionId);
|
|
13091
|
+
heapHolder.activeReconcilerBuffers.delete(sessionId);
|
|
13092
|
+
const prefix = `${sessionId}\x00`;
|
|
13093
|
+
for (const [key, timer] of heapHolder.incrementalTimers) {
|
|
13094
|
+
if (key.startsWith(prefix)) {
|
|
13095
|
+
clearTimeout(timer);
|
|
13096
|
+
heapHolder.incrementalTimers.delete(key);
|
|
13097
|
+
}
|
|
13129
13098
|
}
|
|
13130
|
-
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
bands: {
|
|
13134
|
-
"0-19": Number(row.band_0_19 ?? 0),
|
|
13135
|
-
"20-39": Number(row.band_20_39 ?? 0),
|
|
13136
|
-
"40-59": Number(row.band_40_59 ?? 0),
|
|
13137
|
-
"60-79": Number(row.band_60_79 ?? 0),
|
|
13138
|
-
"80-100": Number(row.band_80_100 ?? 0)
|
|
13099
|
+
for (const key of heapHolder.pendingIncrementalKeys) {
|
|
13100
|
+
if (key.startsWith(prefix)) {
|
|
13101
|
+
heapHolder.pendingIncrementalKeys.delete(key);
|
|
13139
13102
|
}
|
|
13140
|
-
}
|
|
13103
|
+
}
|
|
13104
|
+
for (const key of heapHolder.completedIncrementalKeys) {
|
|
13105
|
+
if (key.startsWith(prefix))
|
|
13106
|
+
heapHolder.completedIncrementalKeys.delete(key);
|
|
13107
|
+
}
|
|
13141
13108
|
}
|
|
13142
13109
|
|
|
13143
13110
|
// src/features/magic-context/session-cache-ttl.ts
|
|
@@ -14237,6 +14204,13 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
14237
14204
|
}
|
|
14238
14205
|
return { shouldFire: false };
|
|
14239
14206
|
}
|
|
14207
|
+
if (tailInfo.boundarySnapshot && shouldWaitForNewHistorianHistory(tailInfo.boundarySnapshot, {
|
|
14208
|
+
usagePercentage: usage.percentage,
|
|
14209
|
+
emergency: getOverflowState(db, sessionId).needsEmergencyRecovery
|
|
14210
|
+
})) {
|
|
14211
|
+
sessionLog2(sessionId, "compartment trigger: waiting for new history after no forward progress");
|
|
14212
|
+
return { shouldFire: false };
|
|
14213
|
+
}
|
|
14240
14214
|
const canClearReasoning = reasoningProjection?.canClearReasoning ?? modelAcceptsEmptyContent(reasoningProjection?.providerID);
|
|
14241
14215
|
const projectedPostDropPercentage = estimateProjectedPostDropPercentage(db, sessionId, usage, preloadedActiveTags ?? getActiveTagsBySession2(db, sessionId), keepReasoningTokens, sessionMeta.clearedReasoningThroughTag, canClearReasoning, reasoningProjection?.budgetCutoff, eligiblePendingDropTagIds);
|
|
14242
14216
|
const relativePostDropTarget = executeThresholdPercentage * POST_DROP_TARGET_RATIO;
|
|
@@ -16480,8 +16454,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
16480
16454
|
const db = readDatabase();
|
|
16481
16455
|
if (!db)
|
|
16482
16456
|
return { ok: false, error: "db unavailable" };
|
|
16483
|
-
const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-
|
|
16484
|
-
const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-
|
|
16457
|
+
const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-02sa2ngr.js"));
|
|
16458
|
+
const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-afzzqy5b.js"));
|
|
16485
16459
|
log2(`[rpc] recomp requested for session ${sessionId}`);
|
|
16486
16460
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
16487
16461
|
return {
|
|
@@ -16565,7 +16539,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
16565
16539
|
const db = readDatabase();
|
|
16566
16540
|
if (!db)
|
|
16567
16541
|
return { ok: false, error: "db unavailable" };
|
|
16568
|
-
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-
|
|
16542
|
+
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-n5h5sr1x.js"));
|
|
16569
16543
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
16570
16544
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
16571
16545
|
const ctx = {
|
|
@@ -24400,6 +24374,7 @@ function createTransform(deps) {
|
|
|
24400
24374
|
const startTime = performance.now();
|
|
24401
24375
|
const historianRun = deps.resolveHistorianRun?.();
|
|
24402
24376
|
const messages = output.messages;
|
|
24377
|
+
const foreignTextParts = deps.transformMode === "rust" ? undefined : deps.collectForeignTextParts?.(messages);
|
|
24403
24378
|
const entryOrderForThinkingFit = messages.slice();
|
|
24404
24379
|
const coveredHostInstructions = takeCoveredInstructionRows(messages);
|
|
24405
24380
|
const passOutcome = createPassOutcome();
|
|
@@ -25064,6 +25039,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
25064
25039
|
}
|
|
25065
25040
|
logTransformTiming(sessionId, "injectTemporalMarkers", tTemporal);
|
|
25066
25041
|
}
|
|
25042
|
+
const replaysCaveman = !reducedMode && !compactionOff && deps.cavemanTextCompression?.enabled === true;
|
|
25067
25043
|
let taggingSucceeded = false;
|
|
25068
25044
|
let recoveryBatch = null;
|
|
25069
25045
|
let recoveryNormalized = false;
|
|
@@ -25076,7 +25052,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
25076
25052
|
skipPrefixInjection: !ctxReduceCallable,
|
|
25077
25053
|
servedMessages: messages,
|
|
25078
25054
|
normalizeRestoredAssistantText: deps.normalizeRestoredAssistantText,
|
|
25079
|
-
refreshSourceContents: deps.refreshSourceContents?.(sessionId)
|
|
25055
|
+
refreshSourceContents: deps.refreshSourceContents?.(sessionId),
|
|
25056
|
+
foreignTextParts,
|
|
25057
|
+
replaysCaveman
|
|
25080
25058
|
});
|
|
25081
25059
|
for (const [number, target] of tagged.targets)
|
|
25082
25060
|
targets.set(number, target);
|
|
@@ -25102,7 +25080,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
25102
25080
|
scopedToolSweep,
|
|
25103
25081
|
servedMessages: messages,
|
|
25104
25082
|
normalizeRestoredAssistantText: deps.normalizeRestoredAssistantText,
|
|
25105
|
-
refreshSourceContents: deps.refreshSourceContents?.(sessionId)
|
|
25083
|
+
refreshSourceContents: deps.refreshSourceContents?.(sessionId),
|
|
25084
|
+
foreignTextParts,
|
|
25085
|
+
replaysCaveman
|
|
25106
25086
|
});
|
|
25107
25087
|
targets = result.targets;
|
|
25108
25088
|
if (thinkingRecovery.restore)
|
|
@@ -25158,7 +25138,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
25158
25138
|
const t3 = performance.now();
|
|
25159
25139
|
const strippedStructuralNoise = canUseEmptySentinels && !compactionOff ? stripStructuralNoise(messages) : 0;
|
|
25160
25140
|
logTransformTiming(sessionId, "stripStructuralNoise", t3, `strippedParts=${strippedStructuralNoise}`);
|
|
25161
|
-
if (
|
|
25141
|
+
if (replaysCaveman) {
|
|
25162
25142
|
const tCavemanReplay = performance.now();
|
|
25163
25143
|
const replayedCaveman = replayCavemanCompression(sessionId, db, targets, activeTags);
|
|
25164
25144
|
if (replayedCaveman > 0) {
|
|
@@ -28607,7 +28587,7 @@ function singleLine(value) {
|
|
|
28607
28587
|
// src/tools/ctx-note/tools.ts
|
|
28608
28588
|
function captureAnchorOrdinal(db, sessionId) {
|
|
28609
28589
|
try {
|
|
28610
|
-
const ordinal =
|
|
28590
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
28611
28591
|
return ordinal > 0 ? ordinal : null;
|
|
28612
28592
|
} catch {
|
|
28613
28593
|
return null;
|
|
@@ -29005,23 +28985,26 @@ function createCtxReduceTool(deps) {
|
|
|
29005
28985
|
dropIds = dropIds.filter((id) => !ctxReduceSelfStampIds.has(id));
|
|
29006
28986
|
const tagStatusMap = new Map(allTags.map((tag) => [tag.tagNumber, tag.status]));
|
|
29007
28987
|
const inertWhitespaceTagNumbers = new Set(getInertWhitespaceAssistantTagsByNumbers2(deps.db, sessionId, dropIds).map((tag) => tag.tagNumber));
|
|
29008
|
-
const
|
|
29009
|
-
|
|
29010
|
-
|
|
29011
|
-
|
|
28988
|
+
const foreignTextTagNumbers = new Set(dropIds.filter((id) => isLegacyForeignTextTag(sessionId, id)));
|
|
28989
|
+
const skippedTagNumbers = new Set([
|
|
28990
|
+
...inertWhitespaceTagNumbers,
|
|
28991
|
+
...foreignTextTagNumbers
|
|
28992
|
+
]);
|
|
28993
|
+
const skippedDropIds = [...new Set(dropIds.filter((id) => skippedTagNumbers.has(id)))];
|
|
28994
|
+
const inertNote = skippedDropIds.length > 0 ? `Skipped: ${skippedDropIds.map((id) => inertWhitespaceTagNumbers.has(id) ? `§${id}§ is provider framing, nothing to reclaim` : `§${id}§ is another plugin's text, nothing to reclaim`).join("; ")}.` : "";
|
|
29012
28995
|
const pendingOps = getPendingOps(deps.db, sessionId);
|
|
29013
28996
|
const pendingMap = new Map(pendingOps.map((op) => [op.tagId, op.operation]));
|
|
29014
28997
|
const conflicts = [];
|
|
29015
28998
|
for (const id of dropIds) {
|
|
29016
|
-
if (tagStatusMap.get(id) === "compacted" && !
|
|
28999
|
+
if (tagStatusMap.get(id) === "compacted" && !skippedTagNumbers.has(id)) {
|
|
29017
29000
|
conflicts.push(`§${id}§ is from before compaction`);
|
|
29018
29001
|
}
|
|
29019
29002
|
}
|
|
29020
29003
|
if (conflicts.length > 0) {
|
|
29021
29004
|
return `Error: Conflicting operations — ${conflicts.join("; ")}.`;
|
|
29022
29005
|
}
|
|
29023
|
-
const stampedCount = new Set(dropIds.filter((id) => !
|
|
29024
|
-
dropIds = dropIds.filter((id) => !
|
|
29006
|
+
const stampedCount = new Set(dropIds.filter((id) => !skippedTagNumbers.has(id))).size;
|
|
29007
|
+
dropIds = dropIds.filter((id) => !skippedTagNumbers.has(id) && tagStatusMap.get(id) !== "dropped" && pendingMap.get(id) !== "drop");
|
|
29025
29008
|
if (dropIds.length === 0) {
|
|
29026
29009
|
const reply = formatCtxReduceReply(stampedCount, ctxReduceSelfStampCount);
|
|
29027
29010
|
if (reply)
|
|
@@ -29788,4 +29771,4 @@ function applyHiddenSubagentTemperature(input, output, log) {
|
|
|
29788
29771
|
output.temperature = temperature;
|
|
29789
29772
|
}
|
|
29790
29773
|
|
|
29791
|
-
export { logConfigDependencyNotesOnce, openOpenCodeDb, DREAMER_SYSTEM_PROMPT, runSessionProjectBackfill, SMART_NOTE_COMPILER_SYSTEM_PROMPT, createLiveSessionState, RETROSPECTIVE_MAX_USER_MESSAGE_CHARS, RETROSPECTIVE_MESSAGE_TRUNCATION_MARKER, OpenCodeRetrospectiveRawProvider, createDreamTaskExecutor, runManualDream, runDueTasksForProject,
|
|
29774
|
+
export { logConfigDependencyNotesOnce, openOpenCodeDb, DREAMER_SYSTEM_PROMPT, runSessionProjectBackfill, SMART_NOTE_COMPILER_SYSTEM_PROMPT, createLiveSessionState, RETROSPECTIVE_MAX_USER_MESSAGE_CHARS, RETROSPECTIVE_MESSAGE_TRUNCATION_MARKER, OpenCodeRetrospectiveRawProvider, createDreamTaskExecutor, runManualDream, runDueTasksForProject, startDreamScheduleTimer, createDreamTimerModuleClient, ensureProjectRegisteredFromOpenCodeDirectory, recordOpenCodeProvenInputFloor, resolveOpenCodeProvenInputFloor, resolveContextWindowGeometry, resolveContextLimit, resolveExecuteThresholdDetail, resolveModelKey, resolveSessionId, createScheduler, describeStorageUnavailability, scheduleClearAndReindex, resolveSessionCacheTtl, runEmbedHistoryDrain, pauseEmbedHistoryDrain, formatEmbedStatusText, getSessionProperties, getSessionCreatedInfo, getMessageUpdatedAssistantInfo, getMessageUpdatedInfo, getSessionErrorInfo, getMessageRemovedInfo, summarizeManualDream, createMagicContextCommandHandler, getLiveNotificationParams, createChatMessageHook, createEventHook, createCommandExecuteBeforeHook, createToolExecuteAfterHook, recordHiddenVariantWarning, buildStatusDetail, isDebugRpcEnabled, registerRpcHandlers, maybeAutoEmbedSessionBackfill, clearTransformDecisionSession, scheduleOpenCodeTransformDecisionWrite, stageOpenCodeV2TransformDecision, bindOpenCodeV2TransformDecision, maybeDeliverChannel2, armLatestThinkingRecovery, armBindingRecoverySafely, armLatestThinkingRecoveryFromError, createM0RenderOptions, lkgReplayLimit, measureLkgReplay, STORAGE_BUSY_MESSAGE, StorageBusyRefusalError, bindSystemDateRequestIdentity, bindSystemDateOutput, registerSystemDateRefresh, rustWrapupHistorianFields, UnmanagedOverWindowError, UnresolvedHistoryBoundaryError, clearMessageTokensCache, createTransform, createSubcModuleClient, createModuleToolBackends, createRustRefusalRecovery, createSystemPromptHashHandler, tryMessagesTransformLkgReplay, createMessagesTransformHandler, primaryOnlyToolIds, subagentToolRefusal, guardSubagentTools, hideSubagentTools, removePrimaryOnlyTools, storedSubagentMode, createCtxExpandTools, CTX_MEMORY_LIST_TOOL_NAME, CTX_MEMORY_ACTIONS, createCtxMemoryTools, createCtxMemoryListTools, CTX_NOTE_DESCRIPTION, withoutSmartNoteText, createCtxNoteTools, createCtxReduceTools, createCtxSearchTools, parameterDescriptionsFor, applyJsonSchemaParameterDescriptions, MagicContextRpcServer, subagentTemperature, applyHiddenSubagentTemperature };
|