@cortexkit/opencode-magic-context 0.49.26 → 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-96ec8a7h.js → compartment-chunk-embedding-qgp0tbf7.js} +3 -3
- package/dist/config/schema/magic-context.d.ts +393 -393
- package/dist/{conflict-warning-hook-dv8fdc2w.js → conflict-warning-hook-tgnw019g.js} +4 -4
- package/dist/{context-pjqa24nd.js → context-t2k97d6v.js} +116 -116
- package/dist/{embedding-backfill-a91rvdf9.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/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/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/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/todo-view.d.ts +2 -2
- package/dist/{index-w55zp7kf.js → index-077ht5cq.js} +1 -1
- package/dist/{index-xyx2ge2y.js → index-31y1mznz.js} +4 -4
- package/dist/{index-6g1zq1sk.js → index-4cpc59jv.js} +5 -5
- package/dist/{index-e5b61ty6.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-zn2n24yr.js → index-89k1w6x2.js} +3 -3
- package/dist/{index-sgchhbvy.js → index-a2fz9hpa.js} +1 -1
- package/dist/{index-hjnrp6vy.js → index-dcqk0y27.js} +1508 -85
- package/dist/{index-r3bteyev.js → index-dzfevacx.js} +9 -9
- package/dist/{index-rp78nqvr.js → index-fq2p158w.js} +10 -10
- package/dist/{index-6tmf87w0.js → index-mm93m7y6.js} +1 -1
- package/dist/{index-va2g2q57.js → index-n8qmmd7f.js} +3 -3
- package/dist/{index-whcgcfrv.js → index-np3rgfw4.js} +1 -1
- package/dist/{index-56tfs78r.js → index-qzbpbnqt.js} +485 -512
- package/dist/{index-m8va3mma.js → index-rverk2vz.js} +0 -2
- package/dist/{index-cfaet9cg.js → index-s1n8dd2n.js} +1 -1
- package/dist/{index-mphkpyap.js → index-t3rbb8wr.js} +2 -2
- package/dist/{index-064v90e8.js → index-tvzvjggy.js} +1 -1
- package/dist/{index-j43m40zd.js → index-v0dhhxsq.js} +1 -1
- package/dist/{index-xbbgcwd2.js → index-v15ne3a3.js} +2 -5
- package/dist/{index-x9k3mqrf.js → index-xrnsygfq.js} +1 -1
- package/dist/{index-dn2ke3b9.js → index-yzjhx10y.js} +5 -5
- package/dist/index.js +38 -38
- package/dist/{message-fts-rowid-map-4ksatb6f.js → message-fts-rowid-map-va36knh4.js} +2 -4
- package/dist/{message-index-bounded-whh5wv4a.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/{project-embedding-registry-t9fx6jwh.js → project-embedding-registry-94nncs5g.js} +4 -4
- package/dist/raw-ordinal-warmup-worker.js +7 -30
- package/dist/{read-session-chunk-mqmkgdx0.js → read-session-chunk-jzb6w9w5.js} +6 -6
- package/dist/{read-session-raw-dy2xxafq.js → read-session-raw-b2sd67v4.js} +1 -1
- package/dist/{recomp-orchestrator-qwcz86r1.js → recomp-orchestrator-02sa2ngr.js} +17 -17
- package/dist/{search-archive-8md3twv2.js → search-archive-q1vw7zg4.js} +7 -7
- package/dist/{search-y2t97tbb.js → search-spq6nfyf.js} +14 -15
- package/dist/{send-session-notification-kzazs7fy.js → send-session-notification-afzzqy5b.js} +3 -3
- package/dist/{storage-tags-a77q4v77.js → storage-tags-6hvkk01c.js} +2 -2
- package/dist/{transform-postprocess-phase-ppm1tfa7.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-5rmrn09z.js → compartment-chunk-embedding-63dzs31c.js} +3 -3
- package/dist/v2/{context-10pj3bwd.js → context-na0esngr.js} +181 -206
- package/dist/v2/{embedding-backfill-r9mzt2eg.js → embedding-backfill-rh5dgsva.js} +5 -5
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/{message-fts-rowid-map-2s3ta05x.js → message-fts-rowid-map-78awh03v.js} +2 -4
- package/dist/v2/{message-index-bounded-f4269d3a.js → message-index-bounded-n09b74vr.js} +21 -24
- package/dist/v2/migration-worker.js +6 -6
- package/dist/v2/{project-embedding-registry-tgtmart7.js → project-embedding-registry-6pak822h.js} +4 -4
- package/dist/v2/raw-ordinal-warmup-worker.js +7 -30
- package/dist/v2/{read-session-chunk-ym5zvexn.js → read-session-chunk-vpt69tw9.js} +5 -5
- package/dist/v2/{read-session-raw-484g8kf2.js → read-session-raw-5x088amc.js} +1 -1
- package/dist/v2/{recomp-orchestrator-b44s2snm.js → recomp-orchestrator-txsmbnvw.js} +14 -14
- package/dist/v2/{search-archive-pmf2c1kb.js → search-archive-t9bcz4ht.js} +6 -6
- package/dist/v2/{search-75tf953m.js → search-dcy9b6gd.js} +13 -14
- package/dist/v2/{send-session-notification-gd21f5rq.js → send-session-notification-vdsgnf4c.js} +1 -1
- package/dist/v2/{server-7dpnt0ys.js → server-4sn3at8p.js} +1 -1
- package/dist/v2/{server-wj8h2q21.js → server-6avtp9jp.js} +1 -1
- package/dist/v2/{server-wwaw5npa.js → server-6g98c227.js} +1 -1
- package/dist/v2/{server-erk2bvdf.js → server-6vd2n183.js} +0 -2
- package/dist/v2/{server-4frtg2z1.js → server-awr8qa4c.js} +2 -5
- package/dist/v2/{server-7d6m1p2b.js → server-cqjvxyrp.js} +1 -1
- package/dist/v2/{server-317f3x9y.js → server-e3hc93wk.js} +5 -5
- package/dist/v2/{server-9zh78t8y.js → server-jj9qye8y.js} +1468 -73
- package/dist/v2/{server-fa7vtp40.js → server-nxas8v1d.js} +1 -1
- package/dist/v2/{server-vjer2jdn.js → server-txbc3czn.js} +9 -9
- package/dist/v2/{server-rqebawx1.js → server-v77xa5wj.js} +1 -1
- package/dist/v2/{server-jcsw05aa.js → server-xkvxss5g.js} +4 -4
- package/dist/v2/{server-hnmm8yzq.js → server-yqek3s4k.js} +1 -1
- package/dist/v2/server-z2n2xaeh.js +538 -0
- package/dist/v2/{server-nmwhe524.js → server-z3mk9jdc.js} +2 -2
- package/dist/v2/{server-w7x9wgm0.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-gwww44st.js → wrapup-orchestrator-gjkszser.js} +14 -14
- package/dist/{wrapup-orchestrator-a9r8r4sk.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-40ma8m0c.js +0 -2251
- package/dist/message-index-ywx53y30.js +0 -61
- package/dist/v2/message-index-v6g8mgn7.js +0 -60
- package/dist/v2/server-k46ec388.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-40ma8m0c.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,
|
|
@@ -755,7 +753,7 @@ import {
|
|
|
755
753
|
abortSessionFailClosed2,
|
|
756
754
|
evaluateEmergencyFailClosed2,
|
|
757
755
|
runPostTransformPhase2
|
|
758
|
-
} from "./index-
|
|
756
|
+
} from "./index-fq2p158w.js";
|
|
759
757
|
import {
|
|
760
758
|
ANNOUNCEMENT_VERSION2,
|
|
761
759
|
ANNOUNCEMENT_FEATURES2,
|
|
@@ -768,7 +766,7 @@ import {
|
|
|
768
766
|
} from "./index-fmsr7v69.js";
|
|
769
767
|
import {
|
|
770
768
|
renderSearchArchiveOffThread2
|
|
771
|
-
} from "./index-
|
|
769
|
+
} from "./index-89k1w6x2.js";
|
|
772
770
|
import {
|
|
773
771
|
COMPACTION_ENABLED_PATH,
|
|
774
772
|
isDreamerRunnable,
|
|
@@ -9065,6 +9063,21 @@ function verifyAssistantText(messages) {
|
|
|
9065
9063
|
const start = text.lastIndexOf("<verify>");
|
|
9066
9064
|
return start >= 0 ? text.slice(start) : text;
|
|
9067
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
|
+
}
|
|
9068
9081
|
var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
|
|
9069
9082
|
var VERIFY_BATCH_FLOOR_MS = 30000;
|
|
9070
9083
|
function computeVerifyBatchSliceMs(remainingMs, _batchesRemaining) {
|
|
@@ -9223,6 +9236,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9223
9236
|
const timer = setTimeout(() => batchController.abort(new Error(`verify slice timed out after ${sliceMs}ms`)), sliceMs);
|
|
9224
9237
|
const batchSignal = batchController.signal;
|
|
9225
9238
|
const tokenBudget = verifyBatchTokenBudget(batch.length, args.tokenBudget);
|
|
9239
|
+
const expectedIds = new Set(batch.map((memory) => memory.id));
|
|
9226
9240
|
let agentSessionId = null;
|
|
9227
9241
|
let hiddenSessionId = null;
|
|
9228
9242
|
let promptSettled = false;
|
|
@@ -9275,13 +9289,10 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9275
9289
|
onBudgetUpdate({ spent: 0, finalizeFired: false, sessionId });
|
|
9276
9290
|
},
|
|
9277
9291
|
parse: (text, completion) => {
|
|
9278
|
-
const providerFailure = providerOutputFailureFromInvalidManifest(completion.messages ?? [], text);
|
|
9279
|
-
if (providerFailure)
|
|
9280
|
-
throw providerFailure;
|
|
9281
9292
|
const manifest = verifyAssistantText(completion.messages ?? []) ?? (text.trim() ? text : null);
|
|
9282
9293
|
if (!manifest)
|
|
9283
9294
|
throw new Error("verify returned no output");
|
|
9284
|
-
return
|
|
9295
|
+
return validateVerifyCompletion(completion.messages ?? [], manifest, expectedIds, text);
|
|
9285
9296
|
}
|
|
9286
9297
|
});
|
|
9287
9298
|
recordInvocation4(args, startedAt, {
|
|
@@ -9343,10 +9354,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9343
9354
|
const text = verifyAssistantText(messages);
|
|
9344
9355
|
if (!text)
|
|
9345
9356
|
throw new Error("verify returned no output");
|
|
9346
|
-
|
|
9347
|
-
if (providerFailure)
|
|
9348
|
-
throw providerFailure;
|
|
9349
|
-
return validateVerifyManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
9357
|
+
return validateVerifyCompletion(messages, text, expectedIds);
|
|
9350
9358
|
}
|
|
9351
9359
|
});
|
|
9352
9360
|
promptSettled = true;
|
|
@@ -11469,471 +11477,92 @@ function clearDreamerTickFailure(db) {
|
|
|
11469
11477
|
db.prepare("DELETE FROM schema_migrations_meta WHERE key = ?").run(DREAMER_TICK_FAILURE_KEY);
|
|
11470
11478
|
}
|
|
11471
11479
|
|
|
11472
|
-
// src/
|
|
11473
|
-
var
|
|
11474
|
-
var
|
|
11475
|
-
var
|
|
11476
|
-
|
|
11477
|
-
|
|
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 {
|
|
11478
11494
|
return false;
|
|
11479
|
-
const e = error;
|
|
11480
|
-
if (typeof e.code === "string") {
|
|
11481
|
-
if (e.code === "SQLITE_BUSY" || e.code === "SQLITE_LOCKED")
|
|
11482
|
-
return true;
|
|
11483
|
-
}
|
|
11484
|
-
if (typeof e.message === "string") {
|
|
11485
|
-
if (/database is locked/i.test(e.message))
|
|
11486
|
-
return true;
|
|
11487
|
-
if (/sqlite_(busy|locked)/i.test(e.message))
|
|
11488
|
-
return true;
|
|
11489
11495
|
}
|
|
11490
|
-
return false;
|
|
11491
|
-
}
|
|
11492
|
-
var INCREMENTAL_DEBOUNCE_MS = 100;
|
|
11493
|
-
var RECONCILIATION_BATCH_SIZE = 100;
|
|
11494
|
-
|
|
11495
|
-
class MagicContextMessageIndexHeapHolder {
|
|
11496
|
-
reconciledSessions = new Set;
|
|
11497
|
-
reconciledSnapshots = new Map;
|
|
11498
|
-
stalledSessions = new Set;
|
|
11499
|
-
reconciliationScheduledSessions = new Set;
|
|
11500
|
-
clearAndReindexScheduledSessions = new Map;
|
|
11501
|
-
sessionLocks = new Map;
|
|
11502
|
-
incrementalTimers = new Map;
|
|
11503
|
-
pendingIncrementalKeys = new Set;
|
|
11504
|
-
completedIncrementalKeys = new Set;
|
|
11505
|
-
activeReconcilerBuffers = new Map;
|
|
11506
11496
|
}
|
|
11507
|
-
|
|
11508
|
-
|
|
11509
|
-
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
|
-
|
|
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;
|
|
11513
11504
|
}
|
|
11514
|
-
|
|
11515
|
-
|
|
11516
|
-
|
|
11517
|
-
const prepare = source?.prepare;
|
|
11518
|
-
return typeof prepare === "function" ? prepare(sessionId) : true;
|
|
11519
|
-
}
|
|
11520
|
-
function defer(fn) {
|
|
11521
|
-
const immediate = globalThis.setImmediate;
|
|
11522
|
-
if (typeof immediate === "function") {
|
|
11523
|
-
inRootAsyncContext2(() => immediate(fn));
|
|
11524
|
-
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;
|
|
11525
11508
|
}
|
|
11526
|
-
|
|
11527
|
-
}
|
|
11528
|
-
function yieldToEventLoop() {
|
|
11529
|
-
return new Promise((resolve) => defer(resolve));
|
|
11509
|
+
return db;
|
|
11530
11510
|
}
|
|
11531
|
-
|
|
11532
|
-
|
|
11533
|
-
|
|
11534
|
-
return;
|
|
11535
|
-
}).then(async () => {
|
|
11536
|
-
await operation();
|
|
11537
|
-
});
|
|
11538
|
-
heapHolder.sessionLocks.set(sessionId, run);
|
|
11539
|
-
run.finally(() => {
|
|
11540
|
-
if (heapHolder.sessionLocks.get(sessionId) === run) {
|
|
11541
|
-
heapHolder.sessionLocks.delete(sessionId);
|
|
11542
|
-
}
|
|
11543
|
-
}).catch(() => {
|
|
11511
|
+
var refusedEmptyIdentityDirectories = new Set;
|
|
11512
|
+
function logEmptyIdentityRefusalOnce(directory) {
|
|
11513
|
+
if (refusedEmptyIdentityDirectories.has(directory))
|
|
11544
11514
|
return;
|
|
11545
|
-
|
|
11546
|
-
|
|
11515
|
+
refusedEmptyIdentityDirectories.add(directory);
|
|
11516
|
+
log2(`[dreamer] not registering ${directory}: it has no project identity, so no project-scoped work runs for it`);
|
|
11547
11517
|
}
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
11518
|
+
var registeredProjects = new Map;
|
|
11519
|
+
function stopDreamScheduleTimerIfIdle() {
|
|
11520
|
+
if (registeredProjects.size !== 0)
|
|
11551
11521
|
return;
|
|
11522
|
+
const stopped = activeTimer !== null || startupTickTimer !== null;
|
|
11523
|
+
if (activeTimer) {
|
|
11524
|
+
clearInterval(activeTimer);
|
|
11525
|
+
activeTimer = null;
|
|
11552
11526
|
}
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
function serializedMessageBytes(messages) {
|
|
11557
|
-
try {
|
|
11558
|
-
return Buffer.byteLength(JSON.stringify(messages));
|
|
11559
|
-
} catch {
|
|
11560
|
-
return 0;
|
|
11527
|
+
if (startupTickTimer) {
|
|
11528
|
+
clearTimeout(startupTickTimer);
|
|
11529
|
+
startupTickTimer = null;
|
|
11561
11530
|
}
|
|
11531
|
+
startupJitters.clear();
|
|
11532
|
+
nextStartupJitterSlot = 0;
|
|
11533
|
+
if (stopped)
|
|
11534
|
+
log2("[dreamer] stopped dream schedule timer (no projects left)");
|
|
11562
11535
|
}
|
|
11563
|
-
function
|
|
11564
|
-
if (
|
|
11536
|
+
async function startDreamScheduleTimer(args) {
|
|
11537
|
+
if (!isUsableProjectIdentity(args.projectIdentity)) {
|
|
11538
|
+
logEmptyIdentityRefusalOnce(args.directory);
|
|
11565
11539
|
return;
|
|
11566
|
-
heapHolder.stalledSessions.add(sessionId);
|
|
11567
|
-
sessionLog2(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
|
|
11568
|
-
}
|
|
11569
|
-
async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
11570
|
-
if (!await sourceReady(readMessages, sessionId)) {
|
|
11571
|
-
logReconciliationStall(sessionId, "raw message reader is not ready");
|
|
11572
|
-
return false;
|
|
11573
11540
|
}
|
|
11574
|
-
|
|
11575
|
-
|
|
11576
|
-
|
|
11577
|
-
let fallbackSnapshot = null;
|
|
11578
|
-
try {
|
|
11579
|
-
const fullReader = typeof readMessages === "function" ? readMessages : null;
|
|
11580
|
-
const revision = readMessages.getRevision?.(sessionId);
|
|
11581
|
-
const previous = heapHolder.reconciledSnapshots.get(sessionId);
|
|
11582
|
-
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;
|
|
11583
|
-
let cursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
|
|
11584
|
-
let after = cursor === previous?.count ? previous.after : undefined;
|
|
11585
|
-
while (cursor < finalWatermark) {
|
|
11586
|
-
const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
|
|
11587
|
-
const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
|
|
11588
|
-
const retainedMessages = fallbackSnapshot ?? messages;
|
|
11589
|
-
heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
|
|
11590
|
-
withSqliteBackgroundWriter2(() => indexMessagesAfterOrdinal2(db, sessionId, messages, cursor, pageEnd));
|
|
11591
|
-
const nextCursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
|
|
11592
|
-
if (nextCursor <= cursor)
|
|
11593
|
-
break;
|
|
11594
|
-
cursor = nextCursor;
|
|
11595
|
-
const last = messages.at(-1);
|
|
11596
|
-
after = last?.ordinal === cursor && typeof last.createdAt === "number" ? { timeCreated: last.createdAt, id: last.id } : undefined;
|
|
11597
|
-
if (cursor < finalWatermark) {
|
|
11598
|
-
await yieldToEventLoop();
|
|
11599
|
-
}
|
|
11600
|
-
}
|
|
11601
|
-
if (isMessageIndexReconciledThrough2(db, sessionId, finalWatermark)) {
|
|
11602
|
-
heapHolder.reconciledSessions.add(sessionId);
|
|
11603
|
-
if (revision !== undefined) {
|
|
11604
|
-
if (!after && finalWatermark > 0 && readMessages.readPage) {
|
|
11605
|
-
const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
|
|
11606
|
-
if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
|
|
11607
|
-
after = { timeCreated: last.createdAt, id: last.id };
|
|
11608
|
-
}
|
|
11609
|
-
heapHolder.reconciledSnapshots.set(sessionId, {
|
|
11610
|
-
revision,
|
|
11611
|
-
count: finalWatermark,
|
|
11612
|
-
after
|
|
11613
|
-
});
|
|
11614
|
-
}
|
|
11615
|
-
} else {
|
|
11616
|
-
logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
|
|
11617
|
-
}
|
|
11618
|
-
} finally {
|
|
11619
|
-
heapHolder.activeReconcilerBuffers.delete(sessionId);
|
|
11620
|
-
}
|
|
11621
|
-
});
|
|
11622
|
-
return true;
|
|
11623
|
-
}
|
|
11624
|
-
function scheduleReconciliation(db, sessionId, readMessages) {
|
|
11625
|
-
if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
|
|
11541
|
+
beginBootQuietPeriod();
|
|
11542
|
+
const db = openTimerDatabaseOrNull("schedule timer registration");
|
|
11543
|
+
if (!db)
|
|
11626
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
|
+
}
|
|
11627
11556
|
}
|
|
11628
|
-
|
|
11629
|
-
|
|
11630
|
-
|
|
11631
|
-
|
|
11632
|
-
|
|
11633
|
-
|
|
11634
|
-
|
|
11635
|
-
|
|
11636
|
-
|
|
11637
|
-
return;
|
|
11638
|
-
}
|
|
11639
|
-
inRootAsyncContext2(() => setTimeout(() => {
|
|
11640
|
-
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
11641
|
-
scheduleReconciliation(db, sessionId, readMessages);
|
|
11642
|
-
}, PREPARE_RETRY_MS)).unref?.();
|
|
11643
|
-
}).catch((error) => {
|
|
11644
|
-
logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
|
|
11645
|
-
if (isDatabaseLockedError(error))
|
|
11646
|
-
inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
|
|
11647
|
-
}).finally(() => {
|
|
11648
|
-
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
11649
|
-
if (appendedDuringReconciliation)
|
|
11650
|
-
scheduleReconciliation(db, sessionId, readMessages);
|
|
11651
|
-
});
|
|
11652
|
-
});
|
|
11653
|
-
});
|
|
11654
|
-
}
|
|
11655
|
-
function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
11656
|
-
const schedulingKey = `${sessionId}\x00${messageId}`;
|
|
11657
|
-
const epoch = sessionEpochs.get(sessionId) ?? 0;
|
|
11658
|
-
if (heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
11659
|
-
return;
|
|
11660
|
-
const activeTimer = heapHolder.incrementalTimers.get(schedulingKey);
|
|
11661
|
-
if (activeTimer)
|
|
11662
|
-
clearTimeout(activeTimer);
|
|
11663
|
-
const timer = inRootAsyncContext2(() => setTimeout(() => {
|
|
11664
|
-
heapHolder.incrementalTimers.delete(schedulingKey);
|
|
11665
|
-
heapHolder.pendingIncrementalKeys.add(schedulingKey);
|
|
11666
|
-
const indexMessage = async () => {
|
|
11667
|
-
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
11668
|
-
return;
|
|
11669
|
-
const message = typeof messageSource === "function" ? messageSource(sessionId, messageId) : messageSource;
|
|
11670
|
-
if (!message)
|
|
11671
|
-
return;
|
|
11672
|
-
const revisionKey = `${schedulingKey}\x00${getMessageIndexSourceIdentity2(message)}`;
|
|
11673
|
-
if (heapHolder.completedIncrementalKeys.has(revisionKey))
|
|
11674
|
-
return;
|
|
11675
|
-
const currentWatermark = getLastIndexedOrdinal2(db, sessionId);
|
|
11676
|
-
if (message.ordinal <= currentWatermark && isMessageIndexSourceCurrent2(db, sessionId, message)) {
|
|
11677
|
-
heapHolder.completedIncrementalKeys.add(revisionKey);
|
|
11678
|
-
return;
|
|
11679
|
-
}
|
|
11680
|
-
const wasReconciled = heapHolder.reconciledSessions.delete(sessionId);
|
|
11681
|
-
await indexSingleMessageOffThread(db, sessionId, message);
|
|
11682
|
-
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
11683
|
-
return;
|
|
11684
|
-
const finalWatermark = getLastIndexedOrdinal2(db, sessionId);
|
|
11685
|
-
if (wasReconciled && isMessageIndexReconciledThrough2(db, sessionId, finalWatermark)) {
|
|
11686
|
-
heapHolder.reconciledSessions.add(sessionId);
|
|
11687
|
-
}
|
|
11688
|
-
heapHolder.completedIncrementalKeys.add(revisionKey);
|
|
11689
|
-
};
|
|
11690
|
-
sourceReady(messageSource, sessionId).then((ready) => {
|
|
11691
|
-
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
|
|
11692
|
-
return;
|
|
11693
|
-
if (ready)
|
|
11694
|
-
return runWithSessionLock(sessionId, indexMessage);
|
|
11695
|
-
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), PREPARE_RETRY_MS).unref?.();
|
|
11696
|
-
}).catch((error) => {
|
|
11697
|
-
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
|
|
11698
|
-
return;
|
|
11699
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11700
|
-
logIndexingError(sessionId, `incremental index for ${messageId}`, error);
|
|
11701
|
-
if (isDatabaseLockedError(error))
|
|
11702
|
-
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), 1000).unref();
|
|
11703
|
-
}).finally(() => {
|
|
11704
|
-
if ((sessionEpochs.get(sessionId) ?? 0) === epoch)
|
|
11705
|
-
heapHolder.pendingIncrementalKeys.delete(schedulingKey);
|
|
11706
|
-
});
|
|
11707
|
-
}, INCREMENTAL_DEBOUNCE_MS));
|
|
11708
|
-
heapHolder.incrementalTimers.set(schedulingKey, timer);
|
|
11709
|
-
}
|
|
11710
|
-
async function indexSingleMessageOffThread(db, sessionId, message) {
|
|
11711
|
-
const path = getSqliteDatabasePath2(db);
|
|
11712
|
-
if (!path)
|
|
11713
|
-
return withSqliteBackgroundWriter2(() => indexSingleMessage2(db, sessionId, message));
|
|
11714
|
-
const cancellation = new Int32Array(new SharedArrayBuffer(4));
|
|
11715
|
-
const active = indexCancellations.get(sessionId) ?? new Set;
|
|
11716
|
-
active.add(cancellation);
|
|
11717
|
-
indexCancellations.set(sessionId, active);
|
|
11718
|
-
const result = await runSessionWarmupWorker({
|
|
11719
|
-
path,
|
|
11720
|
-
sessionId,
|
|
11721
|
-
indexMessage: message,
|
|
11722
|
-
harness: getHarness2(),
|
|
11723
|
-
indexCancellation: cancellation.buffer,
|
|
11724
|
-
...indexCoordinationInput2()
|
|
11725
|
-
}, {}).finally(() => {
|
|
11726
|
-
active.delete(cancellation);
|
|
11727
|
-
if (active.size === 0)
|
|
11728
|
-
indexCancellations.delete(sessionId);
|
|
11729
|
-
});
|
|
11730
|
-
if (!("inserted" in result))
|
|
11731
|
-
throw new Error("failure" in result ? result.detail : "unexpected indexing worker reply");
|
|
11732
|
-
if (result.measurements) {
|
|
11733
|
-
const sessions = workerMeasurements.get(db) ?? new Map;
|
|
11734
|
-
sessions.set(sessionId, result.measurements);
|
|
11735
|
-
workerMeasurements.set(db, sessions);
|
|
11736
|
-
if (result.measurements.skipped)
|
|
11737
|
-
log2(`[magic-context] incremental FTS skipped oversized source ${message.id} (${result.measurements.sourceBytes} bytes); identity and progress persisted`);
|
|
11738
|
-
}
|
|
11739
|
-
return result.inserted;
|
|
11740
|
-
}
|
|
11741
|
-
async function sweepOrphanedOpenCodeMessageIndexesOffThread(db, openSource, options = {}) {
|
|
11742
|
-
if (getHarness2() === "opencode" || getHarness2() === "opencode2")
|
|
11743
|
-
options = {
|
|
11744
|
-
...options,
|
|
11745
|
-
fenceLockNames: options.fenceLockNames ?? takeLkgRecoveryLockSweepPage()
|
|
11746
|
-
};
|
|
11747
|
-
if (getHarness2() === "opencode2")
|
|
11748
|
-
openSource = () => new Database2(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"), {
|
|
11749
|
-
readonly: true,
|
|
11750
|
-
fileMustExist: true
|
|
11751
|
-
});
|
|
11752
|
-
const path = getSqliteDatabasePath2(db);
|
|
11753
|
-
if (!path || getHarness2() !== "opencode" && getHarness2() !== "opencode2")
|
|
11754
|
-
return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, openSource, options);
|
|
11755
|
-
let source = null;
|
|
11756
|
-
let sourcePath = null;
|
|
11757
|
-
try {
|
|
11758
|
-
source = openSource();
|
|
11759
|
-
if (source)
|
|
11760
|
-
sourcePath = getSqliteDatabasePath2(source);
|
|
11761
|
-
} catch {} finally {
|
|
11762
|
-
if (sourcePath)
|
|
11763
|
-
source?.close();
|
|
11764
|
-
}
|
|
11765
|
-
if (!sourcePath)
|
|
11766
|
-
return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, () => source, options);
|
|
11767
|
-
const reply = await runSessionWarmupWorker({
|
|
11768
|
-
path,
|
|
11769
|
-
sessionId: "",
|
|
11770
|
-
harness: getHarness2(),
|
|
11771
|
-
orphanSweep: { sourcePath, options }
|
|
11772
|
-
}, {});
|
|
11773
|
-
if (!("orphanSweep" in reply))
|
|
11774
|
-
throw new Error("message history orphan sweep worker failed");
|
|
11775
|
-
return reply.orphanSweep;
|
|
11776
|
-
}
|
|
11777
|
-
function scheduleClearAndReindex(db, sessionId, readMessages) {
|
|
11778
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11779
|
-
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
11780
|
-
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
11781
|
-
clearCompletedIncrementalKeys(sessionId);
|
|
11782
|
-
const existing = heapHolder.clearAndReindexScheduledSessions.get(sessionId);
|
|
11783
|
-
if (existing) {
|
|
11784
|
-
existing.source = readMessages;
|
|
11785
|
-
return;
|
|
11786
|
-
}
|
|
11787
|
-
const pending = { source: readMessages };
|
|
11788
|
-
heapHolder.clearAndReindexScheduledSessions.set(sessionId, pending);
|
|
11789
|
-
scheduleAfterBootQuiet(() => {
|
|
11790
|
-
defer(() => {
|
|
11791
|
-
let cleared = false;
|
|
11792
|
-
runWithSessionLock(sessionId, () => {
|
|
11793
|
-
if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) !== pending)
|
|
11794
|
-
return;
|
|
11795
|
-
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
11796
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11797
|
-
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
11798
|
-
clearCompletedIncrementalKeys(sessionId);
|
|
11799
|
-
clearIndexedMessages2(db, sessionId);
|
|
11800
|
-
cleared = true;
|
|
11801
|
-
}).then(() => cleared ? reconcileSessionIndex(db, sessionId, pending.source) : undefined).catch((error) => {
|
|
11802
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11803
|
-
if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) === pending)
|
|
11804
|
-
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
11805
|
-
logIndexingError(sessionId, "clear and reindex", error);
|
|
11806
|
-
});
|
|
11807
|
-
});
|
|
11808
|
-
});
|
|
11809
|
-
}
|
|
11810
|
-
function getMessageIndexQueueHeapStats() {
|
|
11811
|
-
return {
|
|
11812
|
-
queueLength: heapHolder.reconciliationScheduledSessions.size + heapHolder.incrementalTimers.size + heapHolder.pendingIncrementalKeys.size,
|
|
11813
|
-
reconciliationScheduled: heapHolder.reconciliationScheduledSessions.size,
|
|
11814
|
-
incrementalTimers: heapHolder.incrementalTimers.size,
|
|
11815
|
-
pendingIncremental: heapHolder.pendingIncrementalKeys.size,
|
|
11816
|
-
activeSessionLocks: heapHolder.sessionLocks.size,
|
|
11817
|
-
completedIncrementalKeys: heapHolder.completedIncrementalKeys.size,
|
|
11818
|
-
activeBufferMessages: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + messages.length, 0),
|
|
11819
|
-
activeBufferBytes: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + serializedMessageBytes(messages), 0)
|
|
11820
|
-
};
|
|
11821
|
-
}
|
|
11822
|
-
function clearSessionTracking(sessionId) {
|
|
11823
|
-
sessionEpochs.set(sessionId, (sessionEpochs.get(sessionId) ?? 0) + 1);
|
|
11824
|
-
for (const cancellation of indexCancellations.get(sessionId) ?? [])
|
|
11825
|
-
Atomics.store(cancellation, 0, 1);
|
|
11826
|
-
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
11827
|
-
heapHolder.reconciledSessions.delete(sessionId);
|
|
11828
|
-
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
11829
|
-
heapHolder.stalledSessions.delete(sessionId);
|
|
11830
|
-
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
11831
|
-
heapHolder.sessionLocks.delete(sessionId);
|
|
11832
|
-
heapHolder.activeReconcilerBuffers.delete(sessionId);
|
|
11833
|
-
const prefix = `${sessionId}\x00`;
|
|
11834
|
-
for (const [key, timer] of heapHolder.incrementalTimers) {
|
|
11835
|
-
if (key.startsWith(prefix)) {
|
|
11836
|
-
clearTimeout(timer);
|
|
11837
|
-
heapHolder.incrementalTimers.delete(key);
|
|
11838
|
-
}
|
|
11839
|
-
}
|
|
11840
|
-
for (const key of heapHolder.pendingIncrementalKeys) {
|
|
11841
|
-
if (key.startsWith(prefix)) {
|
|
11842
|
-
heapHolder.pendingIncrementalKeys.delete(key);
|
|
11843
|
-
}
|
|
11844
|
-
}
|
|
11845
|
-
for (const key of heapHolder.completedIncrementalKeys) {
|
|
11846
|
-
if (key.startsWith(prefix))
|
|
11847
|
-
heapHolder.completedIncrementalKeys.delete(key);
|
|
11848
|
-
}
|
|
11849
|
-
}
|
|
11850
|
-
|
|
11851
|
-
// src/plugin/dream-timer.ts
|
|
11852
|
-
var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
|
|
11853
|
-
var GIT_COMMIT_BACKLOG_DRAIN_MAX_MS = 5 * 60 * 1000;
|
|
11854
|
-
var BOOT_PROJECT_JITTER_SLOT_MS = 1000;
|
|
11855
|
-
var activeTimer = null;
|
|
11856
|
-
var tickInFlight = false;
|
|
11857
|
-
var startupTickTimer = null;
|
|
11858
|
-
var startupTimers = new Map;
|
|
11859
|
-
var startupJitters = new Map;
|
|
11860
|
-
var nextStartupJitterSlot = 0;
|
|
11861
|
-
function directoryStillExists(directory) {
|
|
11862
|
-
try {
|
|
11863
|
-
return statSync2(directory).isDirectory();
|
|
11864
|
-
} catch {
|
|
11865
|
-
return false;
|
|
11866
|
-
}
|
|
11867
|
-
}
|
|
11868
|
-
function openTimerDatabaseOrNull(context) {
|
|
11869
|
-
let db;
|
|
11870
|
-
try {
|
|
11871
|
-
db = openCurrentDatabase();
|
|
11872
|
-
} catch (error) {
|
|
11873
|
-
log2(`[dreamer] storage fatal; skipping ${context}: ${getErrorMessage(error)}`);
|
|
11874
|
-
return null;
|
|
11875
|
-
}
|
|
11876
|
-
if (!db) {
|
|
11877
|
-
log2(`[dreamer] storage unavailable; skipping ${context} (the cache schema is newer than this binary supports — restart/upgrade OpenCode/Pi/Magic Context to recover)`);
|
|
11878
|
-
return null;
|
|
11879
|
-
}
|
|
11880
|
-
return db;
|
|
11881
|
-
}
|
|
11882
|
-
var refusedEmptyIdentityDirectories = new Set;
|
|
11883
|
-
function logEmptyIdentityRefusalOnce(directory) {
|
|
11884
|
-
if (refusedEmptyIdentityDirectories.has(directory))
|
|
11885
|
-
return;
|
|
11886
|
-
refusedEmptyIdentityDirectories.add(directory);
|
|
11887
|
-
log2(`[dreamer] not registering ${directory}: it has no project identity, so no project-scoped work runs for it`);
|
|
11888
|
-
}
|
|
11889
|
-
var registeredProjects = new Map;
|
|
11890
|
-
function stopDreamScheduleTimerIfIdle() {
|
|
11891
|
-
if (registeredProjects.size !== 0)
|
|
11892
|
-
return;
|
|
11893
|
-
const stopped = activeTimer !== null || startupTickTimer !== null;
|
|
11894
|
-
if (activeTimer) {
|
|
11895
|
-
clearInterval(activeTimer);
|
|
11896
|
-
activeTimer = null;
|
|
11897
|
-
}
|
|
11898
|
-
if (startupTickTimer) {
|
|
11899
|
-
clearTimeout(startupTickTimer);
|
|
11900
|
-
startupTickTimer = null;
|
|
11901
|
-
}
|
|
11902
|
-
startupJitters.clear();
|
|
11903
|
-
nextStartupJitterSlot = 0;
|
|
11904
|
-
if (stopped)
|
|
11905
|
-
log2("[dreamer] stopped dream schedule timer (no projects left)");
|
|
11906
|
-
}
|
|
11907
|
-
async function startDreamScheduleTimer(args) {
|
|
11908
|
-
if (!isUsableProjectIdentity(args.projectIdentity)) {
|
|
11909
|
-
logEmptyIdentityRefusalOnce(args.directory);
|
|
11910
|
-
return;
|
|
11911
|
-
}
|
|
11912
|
-
beginBootQuietPeriod();
|
|
11913
|
-
const db = openTimerDatabaseOrNull("schedule timer registration");
|
|
11914
|
-
if (!db)
|
|
11915
|
-
return;
|
|
11916
|
-
const dreamingEnabled = Boolean(args.dreamerConfig && args.dreamerConfig.disable !== true);
|
|
11917
|
-
const embeddingSweepEnabled = args.memoryEnabled === true;
|
|
11918
|
-
const commitIndexingEnabled = args.gitCommitIndexing?.enabled === true;
|
|
11919
|
-
const previousRegistration = registeredProjects.get(args.directory);
|
|
11920
|
-
const isNewRegistration = previousRegistration === undefined;
|
|
11921
|
-
if (previousRegistration && previousRegistration !== args) {
|
|
11922
|
-
const pendingStartup = startupTimers.get(args.directory);
|
|
11923
|
-
if (pendingStartup) {
|
|
11924
|
-
clearTimeout(pendingStartup);
|
|
11925
|
-
startupTimers.delete(args.directory);
|
|
11926
|
-
}
|
|
11927
|
-
}
|
|
11928
|
-
registeredProjects.set(args.directory, args);
|
|
11929
|
-
if (isNewRegistration) {
|
|
11930
|
-
log2(`[dreamer] registered project ${args.projectIdentity} (dreaming=${dreamingEnabled} embeddings=${embeddingSweepEnabled} commits=${commitIndexingEnabled}; total=${registeredProjects.size})`);
|
|
11931
|
-
}
|
|
11932
|
-
if (!activeTimer) {
|
|
11933
|
-
log2(`[dreamer] started independent schedule timer (every ${DREAM_TIMER_INTERVAL_MS / 60000}m)`);
|
|
11934
|
-
startupTickTimer = scheduleAfterBootQuiet(() => {
|
|
11935
|
-
startupTickTimer = null;
|
|
11936
|
-
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");
|
|
11937
11566
|
});
|
|
11938
11567
|
const timer = inRootAsyncContext2(() => setInterval(() => runTick("interval"), DREAM_TIMER_INTERVAL_MS));
|
|
11939
11568
|
if (typeof timer === "object" && "unref" in timer) {
|
|
@@ -12043,12 +11672,6 @@ async function runMessageHistoryMaintenance(db) {
|
|
|
12043
11672
|
log2(`[message-index] pending Rust session cleanup: cleared=${rustCleanup.cleared} failed=${rustCleanup.failedSessionIds.length}`);
|
|
12044
11673
|
}
|
|
12045
11674
|
}
|
|
12046
|
-
const sweep = await sweepOrphanedOpenCodeMessageIndexesOffThread(db, openOpenCodeDb);
|
|
12047
|
-
if (sweep.reason)
|
|
12048
|
-
log2(`[message-index] orphan sweep parked: ${sweep.reason}`);
|
|
12049
|
-
if (sweep.deleted > 0) {
|
|
12050
|
-
log2(`[message-index] orphan sweep: scanned=${sweep.scanned} deleted=${sweep.deleted} cursor=${sweep.cursor || "<complete>"}`);
|
|
12051
|
-
}
|
|
12052
11675
|
}
|
|
12053
11676
|
function startupJitterMs(directory) {
|
|
12054
11677
|
const existing = startupJitters.get(directory);
|
|
@@ -13141,12 +12764,355 @@ function getActiveMemoryImportanceHistogram(db, projectPath) {
|
|
|
13141
12764
|
};
|
|
13142
12765
|
}
|
|
13143
12766
|
|
|
13144
|
-
// src/features/magic-context/
|
|
13145
|
-
|
|
13146
|
-
|
|
13147
|
-
|
|
13148
|
-
|
|
13149
|
-
|
|
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;
|
|
12974
|
+
}
|
|
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);
|
|
12982
|
+
}
|
|
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);
|
|
13004
|
+
}
|
|
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`);
|
|
13033
|
+
}
|
|
13034
|
+
return result.inserted;
|
|
13035
|
+
}
|
|
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;
|
|
13045
|
+
}
|
|
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
|
+
});
|
|
13068
|
+
}
|
|
13069
|
+
function getMessageIndexQueueHeapStats() {
|
|
13070
|
+
return {
|
|
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)
|
|
13079
|
+
};
|
|
13080
|
+
}
|
|
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
|
+
}
|
|
13098
|
+
}
|
|
13099
|
+
for (const key of heapHolder.pendingIncrementalKeys) {
|
|
13100
|
+
if (key.startsWith(prefix)) {
|
|
13101
|
+
heapHolder.pendingIncrementalKeys.delete(key);
|
|
13102
|
+
}
|
|
13103
|
+
}
|
|
13104
|
+
for (const key of heapHolder.completedIncrementalKeys) {
|
|
13105
|
+
if (key.startsWith(prefix))
|
|
13106
|
+
heapHolder.completedIncrementalKeys.delete(key);
|
|
13107
|
+
}
|
|
13108
|
+
}
|
|
13109
|
+
|
|
13110
|
+
// src/features/magic-context/session-cache-ttl.ts
|
|
13111
|
+
function readSessionCacheTtl(db, sessionId) {
|
|
13112
|
+
const saved = readReplayEnvelope(db, sessionId).cacheTtlPolicy;
|
|
13113
|
+
return saved && typeof saved.value === "string" && saved.config !== undefined ? saved : undefined;
|
|
13114
|
+
}
|
|
13115
|
+
function resolveSessionCacheTtl(db, sessionId, config, modelKey, configuredExplicitly) {
|
|
13150
13116
|
const meta = getOrCreateSessionMeta(db, sessionId);
|
|
13151
13117
|
const saved = readSessionCacheTtl(db, sessionId);
|
|
13152
13118
|
const key = modelKey ?? saved?.modelKey;
|
|
@@ -14238,6 +14204,13 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
14238
14204
|
}
|
|
14239
14205
|
return { shouldFire: false };
|
|
14240
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
|
+
}
|
|
14241
14214
|
const canClearReasoning = reasoningProjection?.canClearReasoning ?? modelAcceptsEmptyContent(reasoningProjection?.providerID);
|
|
14242
14215
|
const projectedPostDropPercentage = estimateProjectedPostDropPercentage(db, sessionId, usage, preloadedActiveTags ?? getActiveTagsBySession2(db, sessionId), keepReasoningTokens, sessionMeta.clearedReasoningThroughTag, canClearReasoning, reasoningProjection?.budgetCutoff, eligiblePendingDropTagIds);
|
|
14243
14216
|
const relativePostDropTarget = executeThresholdPercentage * POST_DROP_TARGET_RATIO;
|
|
@@ -16481,8 +16454,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
16481
16454
|
const db = readDatabase();
|
|
16482
16455
|
if (!db)
|
|
16483
16456
|
return { ok: false, error: "db unavailable" };
|
|
16484
|
-
const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-
|
|
16485
|
-
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"));
|
|
16486
16459
|
log2(`[rpc] recomp requested for session ${sessionId}`);
|
|
16487
16460
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
16488
16461
|
return {
|
|
@@ -16566,7 +16539,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
16566
16539
|
const db = readDatabase();
|
|
16567
16540
|
if (!db)
|
|
16568
16541
|
return { ok: false, error: "db unavailable" };
|
|
16569
|
-
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-
|
|
16542
|
+
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-n5h5sr1x.js"));
|
|
16570
16543
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
16571
16544
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
16572
16545
|
const ctx = {
|
|
@@ -28614,7 +28587,7 @@ function singleLine(value) {
|
|
|
28614
28587
|
// src/tools/ctx-note/tools.ts
|
|
28615
28588
|
function captureAnchorOrdinal(db, sessionId) {
|
|
28616
28589
|
try {
|
|
28617
|
-
const ordinal =
|
|
28590
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
28618
28591
|
return ordinal > 0 ? ordinal : null;
|
|
28619
28592
|
} catch {
|
|
28620
28593
|
return null;
|
|
@@ -29798,4 +29771,4 @@ function applyHiddenSubagentTemperature(input, output, log) {
|
|
|
29798
29771
|
output.temperature = temperature;
|
|
29799
29772
|
}
|
|
29800
29773
|
|
|
29801
|
-
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 };
|