@cortexkit/opencode-magic-context 0.49.26 → 0.49.28
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-dxfztzsd.js} +116 -116
- package/dist/{embedding-backfill-a91rvdf9.js → embedding-backfill-cwnyr4fj.js} +5 -5
- package/dist/features/magic-context/dreamer/map-memories.d.ts +2 -2
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/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-56tfs78r.js → index-k9jx7ma9.js} +598 -610
- 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-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-0qhz1nnj.js} +199 -209
- 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,
|
|
@@ -7186,8 +7184,8 @@ async function mapMemories(args) {
|
|
|
7186
7184
|
result.failureStage = outcome.failure.stage;
|
|
7187
7185
|
}
|
|
7188
7186
|
const committed = outcome.mapped + outcome.independent;
|
|
7187
|
+
const committedIds = new Set(outcome.committedIds);
|
|
7189
7188
|
runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
|
|
7190
|
-
const committedIds = new Set(outcome.committedIds);
|
|
7191
7189
|
for (const memory of batch.inputs) {
|
|
7192
7190
|
if (committedIds.has(memory.id)) {
|
|
7193
7191
|
delete retries[memory.id];
|
|
@@ -7222,7 +7220,22 @@ async function mapMemories(args) {
|
|
|
7222
7220
|
log2(`[dreamer] map-memories: targeted retry still omitted ${outcome.requeue.length} id(s); leaving them unmapped for the next run`);
|
|
7223
7221
|
}
|
|
7224
7222
|
}
|
|
7225
|
-
if (outcome.failure?.class === "timeout" &&
|
|
7223
|
+
if (outcome.failure?.class === "timeout" && batch.inputs.length > 1) {
|
|
7224
|
+
const unmapped = batch.inputs.filter((memory) => !committedIds.has(memory.id));
|
|
7225
|
+
const splitSize = Math.floor(batch.inputs.length / 2);
|
|
7226
|
+
const splits = [];
|
|
7227
|
+
for (let offset = 0;offset < unmapped.length; offset += splitSize) {
|
|
7228
|
+
splits.push({
|
|
7229
|
+
inputs: unmapped.slice(offset, offset + splitSize),
|
|
7230
|
+
isOmissionRetry: batch.isOmissionRetry
|
|
7231
|
+
});
|
|
7232
|
+
}
|
|
7233
|
+
if (splits.length > 0) {
|
|
7234
|
+
batches.splice(i + 1, 0, ...splits);
|
|
7235
|
+
log2(`[dreamer] map-memories: splitting batch [${batch.inputs.map((memory) => memory.id).join(",")}] into ${splits.map((split) => split.inputs.length).join("+")} after timeout; retrying ${unmapped.length} uncommitted mapping(s)`);
|
|
7236
|
+
}
|
|
7237
|
+
}
|
|
7238
|
+
if (outcome.failure?.class === "timeout" && batch.inputs.length === 1 && committed === 0) {
|
|
7226
7239
|
consecutiveTimeouts += 1;
|
|
7227
7240
|
timeoutStreakElapsedMs.push(outcome.failure.elapsedMs);
|
|
7228
7241
|
if (consecutiveTimeouts >= CONSECUTIVE_TIMEOUT_LIMIT2) {
|
|
@@ -7230,7 +7243,7 @@ async function mapMemories(args) {
|
|
|
7230
7243
|
log2(`[dreamer] map-memories starvation: circuit breaker tripped after ${consecutiveTimeouts} consecutive batch timeouts with no committed mappings (investigation made no durable progress); per-batch elapsed [${timeoutStreakElapsedMs.join("ms, ")}ms] vs ${sliceMs}ms slice; stopping with ${result.remaining} mapping(s) remaining`);
|
|
7231
7244
|
break;
|
|
7232
7245
|
}
|
|
7233
|
-
} else {
|
|
7246
|
+
} else if (committed > 0 || outcome.failure?.class !== "timeout") {
|
|
7234
7247
|
consecutiveTimeouts = 0;
|
|
7235
7248
|
timeoutStreakElapsedMs = [];
|
|
7236
7249
|
}
|
|
@@ -9065,6 +9078,21 @@ function verifyAssistantText(messages) {
|
|
|
9065
9078
|
const start = text.lastIndexOf("<verify>");
|
|
9066
9079
|
return start >= 0 ? text.slice(start) : text;
|
|
9067
9080
|
}
|
|
9081
|
+
function validateVerifyCompletion(messages, text, expectedIds, responseText = text) {
|
|
9082
|
+
let parsed;
|
|
9083
|
+
try {
|
|
9084
|
+
parsed = validateVerifyManifest(text, expectedIds);
|
|
9085
|
+
} catch (error) {
|
|
9086
|
+
throw providerOutputFailureFromInvalidManifest(messages, responseText) ?? error;
|
|
9087
|
+
}
|
|
9088
|
+
const ids = [...parsed.verified, ...parsed.updated, ...parsed.archived, ...parsed.skipped].map((entry) => entry.id);
|
|
9089
|
+
if (ids.length !== expectedIds.size || ids.some((id) => !expectedIds.has(id))) {
|
|
9090
|
+
const providerFailure = providerOutputFailureFromInvalidManifest(messages, responseText);
|
|
9091
|
+
if (providerFailure)
|
|
9092
|
+
throw providerFailure;
|
|
9093
|
+
}
|
|
9094
|
+
return parsed;
|
|
9095
|
+
}
|
|
9068
9096
|
var IDENTICAL_PROVIDER_FAILURE_BATCH_LIMIT = 2;
|
|
9069
9097
|
var VERIFY_BATCH_FLOOR_MS = 30000;
|
|
9070
9098
|
function computeVerifyBatchSliceMs(remainingMs, _batchesRemaining) {
|
|
@@ -9223,6 +9251,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9223
9251
|
const timer = setTimeout(() => batchController.abort(new Error(`verify slice timed out after ${sliceMs}ms`)), sliceMs);
|
|
9224
9252
|
const batchSignal = batchController.signal;
|
|
9225
9253
|
const tokenBudget = verifyBatchTokenBudget(batch.length, args.tokenBudget);
|
|
9254
|
+
const expectedIds = new Set(batch.map((memory) => memory.id));
|
|
9226
9255
|
let agentSessionId = null;
|
|
9227
9256
|
let hiddenSessionId = null;
|
|
9228
9257
|
let promptSettled = false;
|
|
@@ -9275,13 +9304,10 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9275
9304
|
onBudgetUpdate({ spent: 0, finalizeFired: false, sessionId });
|
|
9276
9305
|
},
|
|
9277
9306
|
parse: (text, completion) => {
|
|
9278
|
-
const providerFailure = providerOutputFailureFromInvalidManifest(completion.messages ?? [], text);
|
|
9279
|
-
if (providerFailure)
|
|
9280
|
-
throw providerFailure;
|
|
9281
9307
|
const manifest = verifyAssistantText(completion.messages ?? []) ?? (text.trim() ? text : null);
|
|
9282
9308
|
if (!manifest)
|
|
9283
9309
|
throw new Error("verify returned no output");
|
|
9284
|
-
return
|
|
9310
|
+
return validateVerifyCompletion(completion.messages ?? [], manifest, expectedIds, text);
|
|
9285
9311
|
}
|
|
9286
9312
|
});
|
|
9287
9313
|
recordInvocation4(args, startedAt, {
|
|
@@ -9343,10 +9369,7 @@ async function verifyOneBatch(args, batch, sliceMs, signal) {
|
|
|
9343
9369
|
const text = verifyAssistantText(messages);
|
|
9344
9370
|
if (!text)
|
|
9345
9371
|
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)));
|
|
9372
|
+
return validateVerifyCompletion(messages, text, expectedIds);
|
|
9350
9373
|
}
|
|
9351
9374
|
});
|
|
9352
9375
|
promptSettled = true;
|
|
@@ -11469,494 +11492,115 @@ function clearDreamerTickFailure(db) {
|
|
|
11469
11492
|
db.prepare("DELETE FROM schema_migrations_meta WHERE key = ?").run(DREAMER_TICK_FAILURE_KEY);
|
|
11470
11493
|
}
|
|
11471
11494
|
|
|
11472
|
-
// src/
|
|
11473
|
-
var
|
|
11474
|
-
var
|
|
11475
|
-
var
|
|
11476
|
-
|
|
11477
|
-
|
|
11495
|
+
// src/plugin/dream-timer.ts
|
|
11496
|
+
var DREAM_TIMER_INTERVAL_MS = 15 * 60 * 1000;
|
|
11497
|
+
var GIT_COMMIT_BACKLOG_DRAIN_MAX_MS = 5 * 60 * 1000;
|
|
11498
|
+
var BOOT_PROJECT_JITTER_SLOT_MS = 1000;
|
|
11499
|
+
var activeTimer = null;
|
|
11500
|
+
var tickInFlight = false;
|
|
11501
|
+
var startupTickTimer = null;
|
|
11502
|
+
var startupTimers = new Map;
|
|
11503
|
+
var startupJitters = new Map;
|
|
11504
|
+
var nextStartupJitterSlot = 0;
|
|
11505
|
+
function directoryStillExists(directory) {
|
|
11506
|
+
try {
|
|
11507
|
+
return statSync2(directory).isDirectory();
|
|
11508
|
+
} catch {
|
|
11478
11509
|
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
11510
|
}
|
|
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
11511
|
}
|
|
11507
|
-
|
|
11508
|
-
|
|
11509
|
-
|
|
11510
|
-
|
|
11511
|
-
|
|
11512
|
-
|
|
11512
|
+
function openTimerDatabaseOrNull(context) {
|
|
11513
|
+
let db;
|
|
11514
|
+
try {
|
|
11515
|
+
db = openCurrentDatabase();
|
|
11516
|
+
} catch (error) {
|
|
11517
|
+
log2(`[dreamer] storage fatal; skipping ${context}: ${getErrorMessage(error)}`);
|
|
11518
|
+
return null;
|
|
11513
11519
|
}
|
|
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;
|
|
11520
|
+
if (!db) {
|
|
11521
|
+
log2(`[dreamer] storage unavailable; skipping ${context} (the cache schema is newer than this binary supports — restart/upgrade OpenCode/Pi/Magic Context to recover)`);
|
|
11522
|
+
return null;
|
|
11525
11523
|
}
|
|
11526
|
-
|
|
11527
|
-
}
|
|
11528
|
-
function yieldToEventLoop() {
|
|
11529
|
-
return new Promise((resolve) => defer(resolve));
|
|
11524
|
+
return db;
|
|
11530
11525
|
}
|
|
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(() => {
|
|
11526
|
+
var refusedEmptyIdentityDirectories = new Set;
|
|
11527
|
+
function logEmptyIdentityRefusalOnce(directory) {
|
|
11528
|
+
if (refusedEmptyIdentityDirectories.has(directory))
|
|
11544
11529
|
return;
|
|
11545
|
-
|
|
11546
|
-
|
|
11530
|
+
refusedEmptyIdentityDirectories.add(directory);
|
|
11531
|
+
log2(`[dreamer] not registering ${directory}: it has no project identity, so no project-scoped work runs for it`);
|
|
11547
11532
|
}
|
|
11548
|
-
|
|
11549
|
-
|
|
11550
|
-
|
|
11533
|
+
var registeredProjects = new Map;
|
|
11534
|
+
function stopDreamScheduleTimerIfIdle() {
|
|
11535
|
+
if (registeredProjects.size !== 0)
|
|
11551
11536
|
return;
|
|
11537
|
+
const stopped = activeTimer !== null || startupTickTimer !== null;
|
|
11538
|
+
if (activeTimer) {
|
|
11539
|
+
clearInterval(activeTimer);
|
|
11540
|
+
activeTimer = null;
|
|
11552
11541
|
}
|
|
11553
|
-
|
|
11554
|
-
|
|
11555
|
-
|
|
11556
|
-
function serializedMessageBytes(messages) {
|
|
11557
|
-
try {
|
|
11558
|
-
return Buffer.byteLength(JSON.stringify(messages));
|
|
11559
|
-
} catch {
|
|
11560
|
-
return 0;
|
|
11542
|
+
if (startupTickTimer) {
|
|
11543
|
+
clearTimeout(startupTickTimer);
|
|
11544
|
+
startupTickTimer = null;
|
|
11561
11545
|
}
|
|
11546
|
+
startupJitters.clear();
|
|
11547
|
+
nextStartupJitterSlot = 0;
|
|
11548
|
+
if (stopped)
|
|
11549
|
+
log2("[dreamer] stopped dream schedule timer (no projects left)");
|
|
11562
11550
|
}
|
|
11563
|
-
function
|
|
11564
|
-
if (
|
|
11551
|
+
async function startDreamScheduleTimer(args) {
|
|
11552
|
+
if (!isUsableProjectIdentity(args.projectIdentity)) {
|
|
11553
|
+
logEmptyIdentityRefusalOnce(args.directory);
|
|
11565
11554
|
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
11555
|
}
|
|
11574
|
-
|
|
11575
|
-
|
|
11556
|
+
beginBootQuietPeriod();
|
|
11557
|
+
const db = openTimerDatabaseOrNull("schedule timer registration");
|
|
11558
|
+
if (!db)
|
|
11559
|
+
return;
|
|
11560
|
+
const dreamingEnabled = Boolean(args.dreamerConfig && args.dreamerConfig.disable !== true);
|
|
11561
|
+
const embeddingSweepEnabled = args.memoryEnabled === true;
|
|
11562
|
+
const commitIndexingEnabled = args.gitCommitIndexing?.enabled === true;
|
|
11563
|
+
const previousRegistration = registeredProjects.get(args.directory);
|
|
11564
|
+
const isNewRegistration = previousRegistration === undefined;
|
|
11565
|
+
if (previousRegistration && previousRegistration !== args) {
|
|
11566
|
+
const pendingStartup = startupTimers.get(args.directory);
|
|
11567
|
+
if (pendingStartup) {
|
|
11568
|
+
clearTimeout(pendingStartup);
|
|
11569
|
+
startupTimers.delete(args.directory);
|
|
11570
|
+
}
|
|
11571
|
+
}
|
|
11572
|
+
registeredProjects.set(args.directory, args);
|
|
11573
|
+
if (isNewRegistration) {
|
|
11574
|
+
log2(`[dreamer] registered project ${args.projectIdentity} (dreaming=${dreamingEnabled} embeddings=${embeddingSweepEnabled} commits=${commitIndexingEnabled}; total=${registeredProjects.size})`);
|
|
11575
|
+
}
|
|
11576
|
+
if (!activeTimer) {
|
|
11577
|
+
log2(`[dreamer] started independent schedule timer (every ${DREAM_TIMER_INTERVAL_MS / 60000}m)`);
|
|
11578
|
+
startupTickTimer = scheduleAfterBootQuiet(() => {
|
|
11579
|
+
startupTickTimer = null;
|
|
11580
|
+
runTick("startup");
|
|
11581
|
+
});
|
|
11582
|
+
const timer = inRootAsyncContext2(() => setInterval(() => runTick("interval"), DREAM_TIMER_INTERVAL_MS));
|
|
11583
|
+
if (typeof timer === "object" && "unref" in timer) {
|
|
11584
|
+
timer.unref();
|
|
11585
|
+
}
|
|
11586
|
+
activeTimer = timer;
|
|
11587
|
+
} else if (isNewRegistration || previousRegistration !== args) {
|
|
11588
|
+
scheduleInitialProjectRun(args, db);
|
|
11589
|
+
}
|
|
11590
|
+
return () => {
|
|
11591
|
+
if (registeredProjects.get(args.directory) !== args) {
|
|
11592
|
+
stopDreamScheduleTimerIfIdle();
|
|
11576
11593
|
return;
|
|
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
11594
|
}
|
|
11621
|
-
|
|
11622
|
-
|
|
11623
|
-
|
|
11624
|
-
|
|
11625
|
-
|
|
11626
|
-
|
|
11627
|
-
|
|
11628
|
-
|
|
11629
|
-
|
|
11630
|
-
defer(() => {
|
|
11631
|
-
let appendedDuringReconciliation = false;
|
|
11632
|
-
const previousSnapshot = heapHolder.reconciledSnapshots.get(sessionId);
|
|
11633
|
-
reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
|
|
11634
|
-
if (ran) {
|
|
11635
|
-
const snapshot = heapHolder.reconciledSnapshots.get(sessionId);
|
|
11636
|
-
appendedDuringReconciliation = snapshot !== undefined && snapshot !== previousSnapshot && readMessages.getRevision !== undefined && readMessages.getRevision(sessionId) !== snapshot.revision;
|
|
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");
|
|
11937
|
-
});
|
|
11938
|
-
const timer = inRootAsyncContext2(() => setInterval(() => runTick("interval"), DREAM_TIMER_INTERVAL_MS));
|
|
11939
|
-
if (typeof timer === "object" && "unref" in timer) {
|
|
11940
|
-
timer.unref();
|
|
11941
|
-
}
|
|
11942
|
-
activeTimer = timer;
|
|
11943
|
-
} else if (isNewRegistration || previousRegistration !== args) {
|
|
11944
|
-
scheduleInitialProjectRun(args, db);
|
|
11945
|
-
}
|
|
11946
|
-
return () => {
|
|
11947
|
-
if (registeredProjects.get(args.directory) !== args) {
|
|
11948
|
-
stopDreamScheduleTimerIfIdle();
|
|
11949
|
-
return;
|
|
11950
|
-
}
|
|
11951
|
-
registeredProjects.delete(args.directory);
|
|
11952
|
-
const startupTimer = startupTimers.get(args.directory);
|
|
11953
|
-
if (startupTimer) {
|
|
11954
|
-
clearTimeout(startupTimer);
|
|
11955
|
-
startupTimers.delete(args.directory);
|
|
11956
|
-
}
|
|
11957
|
-
log2(`[dreamer] unregistered project ${args.projectIdentity} (remaining=${registeredProjects.size})`);
|
|
11958
|
-
stopDreamScheduleTimerIfIdle();
|
|
11959
|
-
};
|
|
11595
|
+
registeredProjects.delete(args.directory);
|
|
11596
|
+
const startupTimer = startupTimers.get(args.directory);
|
|
11597
|
+
if (startupTimer) {
|
|
11598
|
+
clearTimeout(startupTimer);
|
|
11599
|
+
startupTimers.delete(args.directory);
|
|
11600
|
+
}
|
|
11601
|
+
log2(`[dreamer] unregistered project ${args.projectIdentity} (remaining=${registeredProjects.size})`);
|
|
11602
|
+
stopDreamScheduleTimerIfIdle();
|
|
11603
|
+
};
|
|
11960
11604
|
}
|
|
11961
11605
|
var tickStages = {
|
|
11962
11606
|
runMessageHistoryMaintenance,
|
|
@@ -12043,12 +11687,6 @@ async function runMessageHistoryMaintenance(db) {
|
|
|
12043
11687
|
log2(`[message-index] pending Rust session cleanup: cleared=${rustCleanup.cleared} failed=${rustCleanup.failedSessionIds.length}`);
|
|
12044
11688
|
}
|
|
12045
11689
|
}
|
|
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
11690
|
}
|
|
12053
11691
|
function startupJitterMs(directory) {
|
|
12054
11692
|
const existing = startupJitters.get(directory);
|
|
@@ -13049,96 +12687,439 @@ function createScheduler(config) {
|
|
|
13049
12687
|
}
|
|
13050
12688
|
return "defer";
|
|
13051
12689
|
}
|
|
13052
|
-
};
|
|
12690
|
+
};
|
|
12691
|
+
}
|
|
12692
|
+
function computeHardCacheExpired(cacheTtl, lastResponseTime, now, onInvalid) {
|
|
12693
|
+
let ttlMs;
|
|
12694
|
+
try {
|
|
12695
|
+
ttlMs = parseCacheTtl(cacheTtl);
|
|
12696
|
+
} catch (error) {
|
|
12697
|
+
onInvalid?.(error);
|
|
12698
|
+
ttlMs = 5 * 60 * 1000;
|
|
12699
|
+
}
|
|
12700
|
+
return lastResponseTime > 0 && now - lastResponseTime > ttlMs;
|
|
12701
|
+
}
|
|
12702
|
+
|
|
12703
|
+
// src/features/magic-context/storage-unavailable-reason.ts
|
|
12704
|
+
function describeStorageUnavailability(fallbackCause) {
|
|
12705
|
+
const migration = getMigrationOnOpenRefusal();
|
|
12706
|
+
const blockingProcesses = migration?.blockingProcesses ?? migration?.serverPids.map((pid) => ({ kind: "process", pid })) ?? [];
|
|
12707
|
+
if (migration && (blockingProcesses.length > 0 || migration.unreadableFile)) {
|
|
12708
|
+
return {
|
|
12709
|
+
kind: "migration_guard",
|
|
12710
|
+
persistedVersion: migration.persistedVersion,
|
|
12711
|
+
supportedVersion: migration.supportedVersion,
|
|
12712
|
+
blockingProcesses,
|
|
12713
|
+
...migration.unreadableFile ? { unreadableFile: migration.unreadableFile } : {},
|
|
12714
|
+
...migration.unreadableArm ? { unreadableArm: migration.unreadableArm } : {}
|
|
12715
|
+
};
|
|
12716
|
+
}
|
|
12717
|
+
const fence = getSchemaFenceRejection();
|
|
12718
|
+
if (fence) {
|
|
12719
|
+
return {
|
|
12720
|
+
kind: "schema_fence",
|
|
12721
|
+
persistedVersion: fence.persistedVersion,
|
|
12722
|
+
supportedVersion: fence.supportedVersion
|
|
12723
|
+
};
|
|
12724
|
+
}
|
|
12725
|
+
return { kind: "storage_failure", cause: fallbackCause };
|
|
12726
|
+
}
|
|
12727
|
+
|
|
12728
|
+
// src/plugin/rpc-handlers.ts
|
|
12729
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
12730
|
+
import { once } from "node:events";
|
|
12731
|
+
import { rmSync as rmSync2 } from "node:fs";
|
|
12732
|
+
import { join as join5 } from "node:path";
|
|
12733
|
+
|
|
12734
|
+
// src/features/magic-context/memory/memory-diagnostics.ts
|
|
12735
|
+
function emptyMemoryImportanceHistogram() {
|
|
12736
|
+
return {
|
|
12737
|
+
total: 0,
|
|
12738
|
+
unclassified: 0,
|
|
12739
|
+
bands: {
|
|
12740
|
+
"0-19": 0,
|
|
12741
|
+
"20-39": 0,
|
|
12742
|
+
"40-59": 0,
|
|
12743
|
+
"60-79": 0,
|
|
12744
|
+
"80-100": 0
|
|
12745
|
+
}
|
|
12746
|
+
};
|
|
12747
|
+
}
|
|
12748
|
+
function readHistogramRow(db, projectPath, classifiedColumn) {
|
|
12749
|
+
const unclassified = classifiedColumn ? "SUM(CASE WHEN classified_at IS NULL THEN 1 ELSE 0 END)" : "COUNT(*)";
|
|
12750
|
+
return db.prepare(`SELECT COUNT(*) AS total,
|
|
12751
|
+
${unclassified} AS unclassified,
|
|
12752
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 0 AND 19 THEN 1 ELSE 0 END) AS band_0_19,
|
|
12753
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 20 AND 39 THEN 1 ELSE 0 END) AS band_20_39,
|
|
12754
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 40 AND 59 THEN 1 ELSE 0 END) AS band_40_59,
|
|
12755
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 60 AND 79 THEN 1 ELSE 0 END) AS band_60_79,
|
|
12756
|
+
SUM(CASE WHEN COALESCE(importance, 50) BETWEEN 80 AND 100 THEN 1 ELSE 0 END) AS band_80_100
|
|
12757
|
+
FROM memories
|
|
12758
|
+
WHERE project_path = ? AND status = 'active'`).get(projectPath);
|
|
12759
|
+
}
|
|
12760
|
+
function getActiveMemoryImportanceHistogram(db, projectPath) {
|
|
12761
|
+
let row;
|
|
12762
|
+
try {
|
|
12763
|
+
row = readHistogramRow(db, projectPath, true);
|
|
12764
|
+
} catch (error) {
|
|
12765
|
+
if (!String(error).includes("no such column: classified_at"))
|
|
12766
|
+
throw error;
|
|
12767
|
+
row = readHistogramRow(db, projectPath, false);
|
|
12768
|
+
}
|
|
12769
|
+
return {
|
|
12770
|
+
total: Number(row.total ?? 0),
|
|
12771
|
+
unclassified: Number(row.unclassified ?? 0),
|
|
12772
|
+
bands: {
|
|
12773
|
+
"0-19": Number(row.band_0_19 ?? 0),
|
|
12774
|
+
"20-39": Number(row.band_20_39 ?? 0),
|
|
12775
|
+
"40-59": Number(row.band_40_59 ?? 0),
|
|
12776
|
+
"60-79": Number(row.band_60_79 ?? 0),
|
|
12777
|
+
"80-100": Number(row.band_80_100 ?? 0)
|
|
12778
|
+
}
|
|
12779
|
+
};
|
|
12780
|
+
}
|
|
12781
|
+
|
|
12782
|
+
// src/features/magic-context/message-index-async.ts
|
|
12783
|
+
var indexCancellations = new Map;
|
|
12784
|
+
var sessionEpochs = new Map;
|
|
12785
|
+
var workerMeasurements = new WeakMap;
|
|
12786
|
+
function isDatabaseLockedError(error) {
|
|
12787
|
+
if (!error || typeof error !== "object")
|
|
12788
|
+
return false;
|
|
12789
|
+
const e = error;
|
|
12790
|
+
if (typeof e.code === "string") {
|
|
12791
|
+
if (e.code === "SQLITE_BUSY" || e.code === "SQLITE_LOCKED")
|
|
12792
|
+
return true;
|
|
12793
|
+
}
|
|
12794
|
+
if (typeof e.message === "string") {
|
|
12795
|
+
if (/database is locked/i.test(e.message))
|
|
12796
|
+
return true;
|
|
12797
|
+
if (/sqlite_(busy|locked)/i.test(e.message))
|
|
12798
|
+
return true;
|
|
12799
|
+
}
|
|
12800
|
+
return false;
|
|
12801
|
+
}
|
|
12802
|
+
var INCREMENTAL_DEBOUNCE_MS = 100;
|
|
12803
|
+
var RECONCILIATION_BATCH_SIZE = 100;
|
|
12804
|
+
|
|
12805
|
+
class MagicContextMessageIndexHeapHolder {
|
|
12806
|
+
reconciledSessions = new Set;
|
|
12807
|
+
reconciledSnapshots = new Map;
|
|
12808
|
+
stalledSessions = new Set;
|
|
12809
|
+
reconciliationScheduledSessions = new Set;
|
|
12810
|
+
clearAndReindexScheduledSessions = new Map;
|
|
12811
|
+
sessionLocks = new Map;
|
|
12812
|
+
incrementalTimers = new Map;
|
|
12813
|
+
pendingIncrementalKeys = new Set;
|
|
12814
|
+
completedIncrementalKeys = new Set;
|
|
12815
|
+
activeReconcilerBuffers = new Map;
|
|
12816
|
+
}
|
|
12817
|
+
var heapHolder = new MagicContextMessageIndexHeapHolder;
|
|
12818
|
+
function clearCompletedIncrementalKeys(sessionId) {
|
|
12819
|
+
const prefix = `${sessionId}\x00`;
|
|
12820
|
+
for (const key of heapHolder.completedIncrementalKeys) {
|
|
12821
|
+
if (key.startsWith(prefix))
|
|
12822
|
+
heapHolder.completedIncrementalKeys.delete(key);
|
|
12823
|
+
}
|
|
12824
|
+
}
|
|
12825
|
+
var PREPARE_RETRY_MS = 60000;
|
|
12826
|
+
async function sourceReady(source, sessionId) {
|
|
12827
|
+
const prepare = source?.prepare;
|
|
12828
|
+
return typeof prepare === "function" ? prepare(sessionId) : true;
|
|
12829
|
+
}
|
|
12830
|
+
function defer(fn) {
|
|
12831
|
+
const immediate = globalThis.setImmediate;
|
|
12832
|
+
if (typeof immediate === "function") {
|
|
12833
|
+
inRootAsyncContext2(() => immediate(fn));
|
|
12834
|
+
return;
|
|
12835
|
+
}
|
|
12836
|
+
inRootAsyncContext2(() => setTimeout(fn, 0));
|
|
12837
|
+
}
|
|
12838
|
+
function yieldToEventLoop() {
|
|
12839
|
+
return new Promise((resolve) => defer(resolve));
|
|
12840
|
+
}
|
|
12841
|
+
function runWithSessionLock(sessionId, operation) {
|
|
12842
|
+
const previous = heapHolder.sessionLocks.get(sessionId) ?? Promise.resolve();
|
|
12843
|
+
const run = previous.catch(() => {
|
|
12844
|
+
return;
|
|
12845
|
+
}).then(async () => {
|
|
12846
|
+
await operation();
|
|
12847
|
+
});
|
|
12848
|
+
heapHolder.sessionLocks.set(sessionId, run);
|
|
12849
|
+
run.finally(() => {
|
|
12850
|
+
if (heapHolder.sessionLocks.get(sessionId) === run) {
|
|
12851
|
+
heapHolder.sessionLocks.delete(sessionId);
|
|
12852
|
+
}
|
|
12853
|
+
}).catch(() => {
|
|
12854
|
+
return;
|
|
12855
|
+
});
|
|
12856
|
+
return run;
|
|
12857
|
+
}
|
|
12858
|
+
function logIndexingError(sessionId, action, error) {
|
|
12859
|
+
if (isDatabaseLockedError(error)) {
|
|
12860
|
+
sessionLog2(sessionId, `message FTS async ${action} skipped (database busy; will retry on next reconciliation)`);
|
|
12861
|
+
return;
|
|
12862
|
+
}
|
|
12863
|
+
sessionLog2(sessionId, `message FTS async ${action} failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
12864
|
+
log2(`[message-index-async] ${action} failed for ${sessionId}:`, error);
|
|
12865
|
+
}
|
|
12866
|
+
function serializedMessageBytes(messages) {
|
|
12867
|
+
try {
|
|
12868
|
+
return Buffer.byteLength(JSON.stringify(messages));
|
|
12869
|
+
} catch {
|
|
12870
|
+
return 0;
|
|
12871
|
+
}
|
|
12872
|
+
}
|
|
12873
|
+
function logReconciliationStall(sessionId, reason) {
|
|
12874
|
+
if (heapHolder.stalledSessions.has(sessionId))
|
|
12875
|
+
return;
|
|
12876
|
+
heapHolder.stalledSessions.add(sessionId);
|
|
12877
|
+
sessionLog2(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
|
|
12878
|
+
}
|
|
12879
|
+
async function reconcileSessionIndex(db, sessionId, readMessages) {
|
|
12880
|
+
if (!await sourceReady(readMessages, sessionId)) {
|
|
12881
|
+
logReconciliationStall(sessionId, "raw message reader is not ready");
|
|
12882
|
+
return false;
|
|
12883
|
+
}
|
|
12884
|
+
await runWithSessionLock(sessionId, async () => {
|
|
12885
|
+
if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId))
|
|
12886
|
+
return;
|
|
12887
|
+
let fallbackSnapshot = null;
|
|
12888
|
+
try {
|
|
12889
|
+
const fullReader = typeof readMessages === "function" ? readMessages : null;
|
|
12890
|
+
const revision = readMessages.getRevision?.(sessionId);
|
|
12891
|
+
const previous = heapHolder.reconciledSnapshots.get(sessionId);
|
|
12892
|
+
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;
|
|
12893
|
+
let cursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
|
|
12894
|
+
let after = cursor === previous?.count ? previous.after : undefined;
|
|
12895
|
+
while (cursor < finalWatermark) {
|
|
12896
|
+
const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
|
|
12897
|
+
const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
|
|
12898
|
+
const retainedMessages = fallbackSnapshot ?? messages;
|
|
12899
|
+
heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
|
|
12900
|
+
withSqliteBackgroundWriter2(() => indexMessagesAfterOrdinal(db, sessionId, messages, cursor, pageEnd));
|
|
12901
|
+
const nextCursor = getMessageIndexReconciliationStartOrdinal(db, sessionId);
|
|
12902
|
+
if (nextCursor <= cursor)
|
|
12903
|
+
break;
|
|
12904
|
+
cursor = nextCursor;
|
|
12905
|
+
const last = messages.at(-1);
|
|
12906
|
+
after = last?.ordinal === cursor && typeof last.createdAt === "number" ? { timeCreated: last.createdAt, id: last.id } : undefined;
|
|
12907
|
+
if (cursor < finalWatermark) {
|
|
12908
|
+
await yieldToEventLoop();
|
|
12909
|
+
}
|
|
12910
|
+
}
|
|
12911
|
+
if (isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
|
|
12912
|
+
heapHolder.reconciledSessions.add(sessionId);
|
|
12913
|
+
if (revision !== undefined) {
|
|
12914
|
+
if (!after && finalWatermark > 0 && readMessages.readPage) {
|
|
12915
|
+
const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
|
|
12916
|
+
if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
|
|
12917
|
+
after = { timeCreated: last.createdAt, id: last.id };
|
|
12918
|
+
}
|
|
12919
|
+
heapHolder.reconciledSnapshots.set(sessionId, {
|
|
12920
|
+
revision,
|
|
12921
|
+
count: finalWatermark,
|
|
12922
|
+
after
|
|
12923
|
+
});
|
|
12924
|
+
}
|
|
12925
|
+
} else {
|
|
12926
|
+
logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
|
|
12927
|
+
}
|
|
12928
|
+
} finally {
|
|
12929
|
+
heapHolder.activeReconcilerBuffers.delete(sessionId);
|
|
12930
|
+
}
|
|
12931
|
+
});
|
|
12932
|
+
return true;
|
|
13053
12933
|
}
|
|
13054
|
-
function
|
|
13055
|
-
|
|
13056
|
-
|
|
13057
|
-
ttlMs = parseCacheTtl(cacheTtl);
|
|
13058
|
-
} catch (error) {
|
|
13059
|
-
onInvalid?.(error);
|
|
13060
|
-
ttlMs = 5 * 60 * 1000;
|
|
12934
|
+
function scheduleReconciliation(db, sessionId, readMessages) {
|
|
12935
|
+
if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
|
|
12936
|
+
return;
|
|
13061
12937
|
}
|
|
13062
|
-
|
|
12938
|
+
heapHolder.reconciliationScheduledSessions.add(sessionId);
|
|
12939
|
+
scheduleAfterBootQuiet(() => {
|
|
12940
|
+
defer(() => {
|
|
12941
|
+
let appendedDuringReconciliation = false;
|
|
12942
|
+
const previousSnapshot = heapHolder.reconciledSnapshots.get(sessionId);
|
|
12943
|
+
reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
|
|
12944
|
+
if (ran) {
|
|
12945
|
+
const snapshot = heapHolder.reconciledSnapshots.get(sessionId);
|
|
12946
|
+
appendedDuringReconciliation = snapshot !== undefined && snapshot !== previousSnapshot && readMessages.getRevision !== undefined && readMessages.getRevision(sessionId) !== snapshot.revision;
|
|
12947
|
+
return;
|
|
12948
|
+
}
|
|
12949
|
+
inRootAsyncContext2(() => setTimeout(() => {
|
|
12950
|
+
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
12951
|
+
scheduleReconciliation(db, sessionId, readMessages);
|
|
12952
|
+
}, PREPARE_RETRY_MS)).unref?.();
|
|
12953
|
+
}).catch((error) => {
|
|
12954
|
+
logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
|
|
12955
|
+
if (isDatabaseLockedError(error))
|
|
12956
|
+
inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
|
|
12957
|
+
}).finally(() => {
|
|
12958
|
+
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
12959
|
+
if (appendedDuringReconciliation)
|
|
12960
|
+
scheduleReconciliation(db, sessionId, readMessages);
|
|
12961
|
+
});
|
|
12962
|
+
});
|
|
12963
|
+
});
|
|
13063
12964
|
}
|
|
13064
|
-
|
|
13065
|
-
|
|
13066
|
-
|
|
13067
|
-
|
|
13068
|
-
|
|
13069
|
-
|
|
13070
|
-
|
|
13071
|
-
|
|
13072
|
-
|
|
13073
|
-
|
|
13074
|
-
|
|
13075
|
-
|
|
13076
|
-
|
|
12965
|
+
function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
12966
|
+
const schedulingKey = `${sessionId}\x00${messageId}`;
|
|
12967
|
+
const epoch = sessionEpochs.get(sessionId) ?? 0;
|
|
12968
|
+
if (heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
12969
|
+
return;
|
|
12970
|
+
const activeTimer = heapHolder.incrementalTimers.get(schedulingKey);
|
|
12971
|
+
if (activeTimer)
|
|
12972
|
+
clearTimeout(activeTimer);
|
|
12973
|
+
const timer = inRootAsyncContext2(() => setTimeout(() => {
|
|
12974
|
+
heapHolder.incrementalTimers.delete(schedulingKey);
|
|
12975
|
+
heapHolder.pendingIncrementalKeys.add(schedulingKey);
|
|
12976
|
+
const indexMessage = async () => {
|
|
12977
|
+
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
12978
|
+
return;
|
|
12979
|
+
const message = typeof messageSource === "function" ? messageSource(sessionId, messageId) : messageSource;
|
|
12980
|
+
if (!message)
|
|
12981
|
+
return;
|
|
12982
|
+
const revisionKey = `${schedulingKey}\x00${getMessageIndexSourceIdentity(message)}`;
|
|
12983
|
+
if (heapHolder.completedIncrementalKeys.has(revisionKey))
|
|
12984
|
+
return;
|
|
12985
|
+
const currentWatermark = getLastIndexedOrdinal(db, sessionId);
|
|
12986
|
+
if (message.ordinal <= currentWatermark && isMessageIndexSourceCurrent(db, sessionId, message)) {
|
|
12987
|
+
heapHolder.completedIncrementalKeys.add(revisionKey);
|
|
12988
|
+
return;
|
|
12989
|
+
}
|
|
12990
|
+
const wasReconciled = heapHolder.reconciledSessions.delete(sessionId);
|
|
12991
|
+
await indexSingleMessageOffThread(db, sessionId, message);
|
|
12992
|
+
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch || !heapHolder.pendingIncrementalKeys.has(schedulingKey))
|
|
12993
|
+
return;
|
|
12994
|
+
const finalWatermark = getLastIndexedOrdinal(db, sessionId);
|
|
12995
|
+
if (wasReconciled && isMessageIndexReconciledThrough(db, sessionId, finalWatermark)) {
|
|
12996
|
+
heapHolder.reconciledSessions.add(sessionId);
|
|
12997
|
+
}
|
|
12998
|
+
heapHolder.completedIncrementalKeys.add(revisionKey);
|
|
13077
12999
|
};
|
|
13000
|
+
sourceReady(messageSource, sessionId).then((ready) => {
|
|
13001
|
+
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
|
|
13002
|
+
return;
|
|
13003
|
+
if (ready)
|
|
13004
|
+
return runWithSessionLock(sessionId, indexMessage);
|
|
13005
|
+
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), PREPARE_RETRY_MS).unref?.();
|
|
13006
|
+
}).catch((error) => {
|
|
13007
|
+
if ((sessionEpochs.get(sessionId) ?? 0) !== epoch)
|
|
13008
|
+
return;
|
|
13009
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
13010
|
+
logIndexingError(sessionId, `incremental index for ${messageId}`, error);
|
|
13011
|
+
if (isDatabaseLockedError(error))
|
|
13012
|
+
setTimeout(() => scheduleIncrementalIndex(db, sessionId, messageId, messageSource), 1000).unref();
|
|
13013
|
+
}).finally(() => {
|
|
13014
|
+
if ((sessionEpochs.get(sessionId) ?? 0) === epoch)
|
|
13015
|
+
heapHolder.pendingIncrementalKeys.delete(schedulingKey);
|
|
13016
|
+
});
|
|
13017
|
+
}, INCREMENTAL_DEBOUNCE_MS));
|
|
13018
|
+
heapHolder.incrementalTimers.set(schedulingKey, timer);
|
|
13019
|
+
}
|
|
13020
|
+
async function indexSingleMessageOffThread(db, sessionId, message) {
|
|
13021
|
+
const path = getSqliteDatabasePath2(db);
|
|
13022
|
+
if (!path)
|
|
13023
|
+
return withSqliteBackgroundWriter2(() => indexSingleMessage(db, sessionId, message));
|
|
13024
|
+
const cancellation = new Int32Array(new SharedArrayBuffer(4));
|
|
13025
|
+
const active = indexCancellations.get(sessionId) ?? new Set;
|
|
13026
|
+
active.add(cancellation);
|
|
13027
|
+
indexCancellations.set(sessionId, active);
|
|
13028
|
+
const result = await runSessionWarmupWorker({
|
|
13029
|
+
path,
|
|
13030
|
+
sessionId,
|
|
13031
|
+
indexMessage: message,
|
|
13032
|
+
harness: getHarness2(),
|
|
13033
|
+
indexCancellation: cancellation.buffer,
|
|
13034
|
+
...indexCoordinationInput2()
|
|
13035
|
+
}, {}).finally(() => {
|
|
13036
|
+
active.delete(cancellation);
|
|
13037
|
+
if (active.size === 0)
|
|
13038
|
+
indexCancellations.delete(sessionId);
|
|
13039
|
+
});
|
|
13040
|
+
if (!("inserted" in result))
|
|
13041
|
+
throw new Error("failure" in result ? result.detail : "unexpected indexing worker reply");
|
|
13042
|
+
if (result.measurements) {
|
|
13043
|
+
const sessions = workerMeasurements.get(db) ?? new Map;
|
|
13044
|
+
sessions.set(sessionId, result.measurements);
|
|
13045
|
+
workerMeasurements.set(db, sessions);
|
|
13046
|
+
if (result.measurements.skipped)
|
|
13047
|
+
log2(`[magic-context] incremental FTS skipped oversized source ${message.id} (${result.measurements.sourceBytes} bytes); identity and progress persisted`);
|
|
13078
13048
|
}
|
|
13079
|
-
|
|
13080
|
-
|
|
13081
|
-
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13085
|
-
|
|
13049
|
+
return result.inserted;
|
|
13050
|
+
}
|
|
13051
|
+
function scheduleClearAndReindex(db, sessionId, readMessages) {
|
|
13052
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
13053
|
+
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
13054
|
+
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
13055
|
+
clearCompletedIncrementalKeys(sessionId);
|
|
13056
|
+
const existing = heapHolder.clearAndReindexScheduledSessions.get(sessionId);
|
|
13057
|
+
if (existing) {
|
|
13058
|
+
existing.source = readMessages;
|
|
13059
|
+
return;
|
|
13086
13060
|
}
|
|
13087
|
-
|
|
13061
|
+
const pending = { source: readMessages };
|
|
13062
|
+
heapHolder.clearAndReindexScheduledSessions.set(sessionId, pending);
|
|
13063
|
+
scheduleAfterBootQuiet(() => {
|
|
13064
|
+
defer(() => {
|
|
13065
|
+
let cleared = false;
|
|
13066
|
+
runWithSessionLock(sessionId, () => {
|
|
13067
|
+
if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) !== pending)
|
|
13068
|
+
return;
|
|
13069
|
+
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
13070
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
13071
|
+
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
13072
|
+
clearCompletedIncrementalKeys(sessionId);
|
|
13073
|
+
clearIndexedMessages(db, sessionId);
|
|
13074
|
+
cleared = true;
|
|
13075
|
+
}).then(() => cleared ? reconcileSessionIndex(db, sessionId, pending.source) : undefined).catch((error) => {
|
|
13076
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
13077
|
+
if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) === pending)
|
|
13078
|
+
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
13079
|
+
logIndexingError(sessionId, "clear and reindex", error);
|
|
13080
|
+
});
|
|
13081
|
+
});
|
|
13082
|
+
});
|
|
13088
13083
|
}
|
|
13089
|
-
|
|
13090
|
-
// src/plugin/rpc-handlers.ts
|
|
13091
|
-
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
13092
|
-
import { once } from "node:events";
|
|
13093
|
-
import { rmSync as rmSync2 } from "node:fs";
|
|
13094
|
-
import { join as join5 } from "node:path";
|
|
13095
|
-
|
|
13096
|
-
// src/features/magic-context/memory/memory-diagnostics.ts
|
|
13097
|
-
function emptyMemoryImportanceHistogram() {
|
|
13084
|
+
function getMessageIndexQueueHeapStats() {
|
|
13098
13085
|
return {
|
|
13099
|
-
|
|
13100
|
-
|
|
13101
|
-
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13107
|
-
}
|
|
13086
|
+
queueLength: heapHolder.reconciliationScheduledSessions.size + heapHolder.incrementalTimers.size + heapHolder.pendingIncrementalKeys.size,
|
|
13087
|
+
reconciliationScheduled: heapHolder.reconciliationScheduledSessions.size,
|
|
13088
|
+
incrementalTimers: heapHolder.incrementalTimers.size,
|
|
13089
|
+
pendingIncremental: heapHolder.pendingIncrementalKeys.size,
|
|
13090
|
+
activeSessionLocks: heapHolder.sessionLocks.size,
|
|
13091
|
+
completedIncrementalKeys: heapHolder.completedIncrementalKeys.size,
|
|
13092
|
+
activeBufferMessages: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + messages.length, 0),
|
|
13093
|
+
activeBufferBytes: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + serializedMessageBytes(messages), 0)
|
|
13108
13094
|
};
|
|
13109
13095
|
}
|
|
13110
|
-
function
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13115
|
-
|
|
13116
|
-
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13121
|
-
}
|
|
13122
|
-
|
|
13123
|
-
|
|
13124
|
-
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
if (!String(error).includes("no such column: classified_at"))
|
|
13128
|
-
throw error;
|
|
13129
|
-
row = readHistogramRow(db, projectPath, false);
|
|
13096
|
+
function clearSessionTracking(sessionId) {
|
|
13097
|
+
sessionEpochs.set(sessionId, (sessionEpochs.get(sessionId) ?? 0) + 1);
|
|
13098
|
+
for (const cancellation of indexCancellations.get(sessionId) ?? [])
|
|
13099
|
+
Atomics.store(cancellation, 0, 1);
|
|
13100
|
+
heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
|
|
13101
|
+
heapHolder.reconciledSessions.delete(sessionId);
|
|
13102
|
+
heapHolder.reconciledSnapshots.delete(sessionId);
|
|
13103
|
+
heapHolder.stalledSessions.delete(sessionId);
|
|
13104
|
+
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
13105
|
+
heapHolder.sessionLocks.delete(sessionId);
|
|
13106
|
+
heapHolder.activeReconcilerBuffers.delete(sessionId);
|
|
13107
|
+
const prefix = `${sessionId}\x00`;
|
|
13108
|
+
for (const [key, timer] of heapHolder.incrementalTimers) {
|
|
13109
|
+
if (key.startsWith(prefix)) {
|
|
13110
|
+
clearTimeout(timer);
|
|
13111
|
+
heapHolder.incrementalTimers.delete(key);
|
|
13112
|
+
}
|
|
13130
13113
|
}
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
|
|
13134
|
-
bands: {
|
|
13135
|
-
"0-19": Number(row.band_0_19 ?? 0),
|
|
13136
|
-
"20-39": Number(row.band_20_39 ?? 0),
|
|
13137
|
-
"40-59": Number(row.band_40_59 ?? 0),
|
|
13138
|
-
"60-79": Number(row.band_60_79 ?? 0),
|
|
13139
|
-
"80-100": Number(row.band_80_100 ?? 0)
|
|
13114
|
+
for (const key of heapHolder.pendingIncrementalKeys) {
|
|
13115
|
+
if (key.startsWith(prefix)) {
|
|
13116
|
+
heapHolder.pendingIncrementalKeys.delete(key);
|
|
13140
13117
|
}
|
|
13141
|
-
}
|
|
13118
|
+
}
|
|
13119
|
+
for (const key of heapHolder.completedIncrementalKeys) {
|
|
13120
|
+
if (key.startsWith(prefix))
|
|
13121
|
+
heapHolder.completedIncrementalKeys.delete(key);
|
|
13122
|
+
}
|
|
13142
13123
|
}
|
|
13143
13124
|
|
|
13144
13125
|
// src/features/magic-context/session-cache-ttl.ts
|
|
@@ -14238,6 +14219,13 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
|
|
|
14238
14219
|
}
|
|
14239
14220
|
return { shouldFire: false };
|
|
14240
14221
|
}
|
|
14222
|
+
if (tailInfo.boundarySnapshot && shouldWaitForNewHistorianHistory(tailInfo.boundarySnapshot, {
|
|
14223
|
+
usagePercentage: usage.percentage,
|
|
14224
|
+
emergency: getOverflowState(db, sessionId).needsEmergencyRecovery
|
|
14225
|
+
})) {
|
|
14226
|
+
sessionLog2(sessionId, "compartment trigger: waiting for new history after no forward progress");
|
|
14227
|
+
return { shouldFire: false };
|
|
14228
|
+
}
|
|
14241
14229
|
const canClearReasoning = reasoningProjection?.canClearReasoning ?? modelAcceptsEmptyContent(reasoningProjection?.providerID);
|
|
14242
14230
|
const projectedPostDropPercentage = estimateProjectedPostDropPercentage(db, sessionId, usage, preloadedActiveTags ?? getActiveTagsBySession2(db, sessionId), keepReasoningTokens, sessionMeta.clearedReasoningThroughTag, canClearReasoning, reasoningProjection?.budgetCutoff, eligiblePendingDropTagIds);
|
|
14243
14231
|
const relativePostDropTarget = executeThresholdPercentage * POST_DROP_TARGET_RATIO;
|
|
@@ -16481,8 +16469,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
16481
16469
|
const db = readDatabase();
|
|
16482
16470
|
if (!db)
|
|
16483
16471
|
return { ok: false, error: "db unavailable" };
|
|
16484
|
-
const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-
|
|
16485
|
-
const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-
|
|
16472
|
+
const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-02sa2ngr.js"));
|
|
16473
|
+
const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-afzzqy5b.js"));
|
|
16486
16474
|
log2(`[rpc] recomp requested for session ${sessionId}`);
|
|
16487
16475
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
16488
16476
|
return {
|
|
@@ -16566,7 +16554,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
16566
16554
|
const db = readDatabase();
|
|
16567
16555
|
if (!db)
|
|
16568
16556
|
return { ok: false, error: "db unavailable" };
|
|
16569
|
-
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-
|
|
16557
|
+
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-n5h5sr1x.js"));
|
|
16570
16558
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
16571
16559
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
16572
16560
|
const ctx = {
|
|
@@ -28614,7 +28602,7 @@ function singleLine(value) {
|
|
|
28614
28602
|
// src/tools/ctx-note/tools.ts
|
|
28615
28603
|
function captureAnchorOrdinal(db, sessionId) {
|
|
28616
28604
|
try {
|
|
28617
|
-
const ordinal =
|
|
28605
|
+
const ordinal = getLastIndexedOrdinal(db, sessionId);
|
|
28618
28606
|
return ordinal > 0 ? ordinal : null;
|
|
28619
28607
|
} catch {
|
|
28620
28608
|
return null;
|
|
@@ -29798,4 +29786,4 @@ function applyHiddenSubagentTemperature(input, output, log) {
|
|
|
29798
29786
|
output.temperature = temperature;
|
|
29799
29787
|
}
|
|
29800
29788
|
|
|
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,
|
|
29789
|
+
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 };
|