@cortexkit/opencode-magic-context 0.49.5 → 0.49.7
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 +10 -7
- package/dist/{compaction-marker-candidates-dd638ypn.js → compaction-marker-candidates-a0edbqrr.js} +2 -2
- package/dist/compaction-marker-candidates-worker.js +2 -2
- package/dist/{conflict-warning-hook-ae8nmv7c.js → conflict-warning-hook-myk5hbt9.js} +5 -5
- package/dist/{context-yg023c5r.js → context-ffr7e0g7.js} +46 -34
- package/dist/{embedding-backfill-aj488s8x.js → embedding-backfill-re16xncd.js} +6 -6
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts +6 -3
- package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts +7 -1
- package/dist/features/magic-context/dreamer/map-memories-prompt.d.ts.map +1 -1
- 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/primer-seed.d.ts +2 -0
- package/dist/features/magic-context/dreamer/primer-seed.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts +2 -2
- package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +10 -3
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-replay-document.d.ts +4 -0
- package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -1
- package/dist/hooks/magic-context/apply-operations.d.ts +7 -0
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/history-boundary-repair.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
- package/dist/hooks/magic-context/note-nudger.d.ts +5 -3
- package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
- package/dist/hooks/magic-context/postprocess-read-cache.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +7 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/replay-committed-drops.d.ts +9 -0
- package/dist/hooks/magic-context/replay-committed-drops.d.ts.map +1 -0
- package/dist/hooks/magic-context/rust-lkg-freeze-registry.d.ts +2 -2
- package/dist/hooks/magic-context/rust-lkg-freeze-registry.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +3 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-served-raw.d.ts +29 -0
- package/dist/hooks/magic-context/rust-served-raw.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-content.d.ts +23 -24
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tool-drop-target.d.ts +2 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/{index-m4p77myp.js → index-0gyq3djm.js} +1 -1
- package/dist/{index-jpm52v9x.js → index-37q80veb.js} +1 -1
- package/dist/{index-znzgze2v.js → index-4btknbqh.js} +9 -8
- package/dist/{index-v4bqjy56.js → index-5tbvdff4.js} +59 -28
- package/dist/{index-7jzrrxap.js → index-9yyqq3mm.js} +1 -1
- package/dist/{index-qvr78ej6.js → index-a8acx4gc.js} +2 -2
- package/dist/{index-gcdb3rqw.js → index-ax2jhztn.js} +1 -1
- package/dist/{index-2mqps3c1.js → index-ebnngykq.js} +145 -94
- package/dist/{index-41gqa557.js → index-g8qbdb03.js} +1 -1
- package/dist/{index-fst3t0d9.js → index-j58gqrn2.js} +65 -65
- package/dist/{index-xfbfrngb.js → index-j5hce1ab.js} +2 -2
- package/dist/{index-kb9nn0a0.js → index-j8epsc0g.js} +35 -14
- package/dist/{index-7zg9dvx0.js → index-n5a170gs.js} +227 -38
- package/dist/{index-fjtgekd4.js → index-n7kwfw2r.js} +4 -4
- package/dist/{index-dd18gej8.js → index-rwmpkss5.js} +3 -3
- package/dist/{index-7w18gg78.js → index-rzmjkdd6.js} +1 -1
- package/dist/{index-c0b01zrc.js → index-sf94at64.js} +3 -3
- package/dist/{index-yxawqmdd.js → index-sh91t19a.js} +1 -1
- package/dist/{index-x3y1np1h.js → index-tagss15p.js} +857 -125
- package/dist/{index-yqps2zsv.js → index-tmtty2x5.js} +1 -1
- package/dist/{index-bhk710rw.js → index-vt4sf4ep.js} +1 -1
- package/dist/{index-6m7rdv7y.js → index-w4mw92w3.js} +1 -1
- package/dist/{index-7ndnvw7a.js → index-w6bd03dc.js} +1 -1
- package/dist/{index-p2hs3rps.js → index-w6vr754t.js} +4 -4
- package/dist/{index-3wckxwfp.js → index-wq16ahsn.js} +5 -5
- package/dist/index.js +36 -36
- package/dist/{message-index-bounded-pv6ct15d.js → message-index-bounded-04rycpx4.js} +9 -9
- package/dist/{message-index-jqa7qd0s.js → message-index-rqtse28y.js} +9 -9
- package/dist/{message-time-backfill-8x06r9kx.js → message-time-backfill-a5ytnp53.js} +1 -1
- package/dist/migration-worker.js +6 -6
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/{project-embedding-registry-fcmszatg.js → project-embedding-registry-k0sd9k7v.js} +5 -5
- package/dist/raw-ordinal-warmup-worker.js +17 -15
- package/dist/{read-session-chunk-cwgjwjd0.js → read-session-chunk-h1btx938.js} +7 -5
- package/dist/{read-session-raw-z38cn0as.js → read-session-raw-vdf4wh78.js} +2 -2
- package/dist/{recomp-orchestrator-xw9wt5bm.js → recomp-orchestrator-trcgmm23.js} +20 -20
- package/dist/{search-v1t47s2q.js → search-3rbdx6hw.js} +16 -16
- package/dist/{send-session-notification-yp9m5g4p.js → send-session-notification-2tp44tfa.js} +4 -4
- package/dist/shared/processed-image-eligibility.d.ts +22 -0
- package/dist/shared/processed-image-eligibility.d.ts.map +1 -0
- package/dist/shared/recovery-reasoning-prefix.d.ts +9 -0
- package/dist/shared/recovery-reasoning-prefix.d.ts.map +1 -0
- package/dist/shared/sqlite.d.ts +1 -1
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/tag-transcript.d.ts +9 -0
- package/dist/shared/tag-transcript.d.ts.map +1 -1
- package/dist/{sqlite-mhjkerzq.js → sqlite-j3tvg8r0.js} +1 -1
- package/dist/{storage-memory-07fx57k6.js → storage-memory-8168bgef.js} +2 -2
- package/dist/{storage-tags-0ssbmzg9.js → storage-tags-61z5j2f9.js} +2 -2
- package/dist/tools/ctx-expand/search-archive.d.ts +4 -0
- package/dist/tools/ctx-expand/search-archive.d.ts.map +1 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/{transform-postprocess-phase-ttra554y.js → transform-postprocess-phase-7qts7h54.js} +20 -20
- package/dist/v2/auto-search-worker.js +10 -7
- package/dist/v2/{compaction-marker-candidates-1s21e2fz.js → compaction-marker-candidates-6nypjkpf.js} +2 -2
- package/dist/v2/compaction-marker-candidates-worker.js +2 -2
- package/dist/v2/{context-6en6a8ar.js → context-xq4rtywr.js} +1019 -233
- package/dist/v2/{embedding-backfill-9hbkfvnz.js → embedding-backfill-xd9ygzgd.js} +6 -6
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/{message-index-h8ssgq3q.js → message-index-8e5z2xx8.js} +9 -9
- package/dist/v2/{message-index-bounded-c0810p5w.js → message-index-bounded-5vh1h2g7.js} +9 -9
- package/dist/v2/{message-time-backfill-cje68egj.js → message-time-backfill-2z365239.js} +1 -1
- package/dist/v2/migration-worker.js +6 -6
- package/dist/v2/{project-embedding-registry-42th7k1z.js → project-embedding-registry-b77awytr.js} +5 -5
- package/dist/v2/raw-ordinal-warmup-worker.js +17 -15
- package/dist/v2/{read-session-chunk-n86v9xfg.js → read-session-chunk-4sat83cx.js} +7 -5
- package/dist/v2/{read-session-raw-3b3ehga4.js → read-session-raw-a3hw9jsp.js} +2 -2
- package/dist/v2/{recomp-orchestrator-krvsbnds.js → recomp-orchestrator-n11zv1f1.js} +19 -19
- package/dist/v2/{search-048v8y02.js → search-mvgqtkkz.js} +16 -16
- package/dist/v2/{send-session-notification-a4h2azxa.js → send-session-notification-ppgc8qdz.js} +4 -4
- package/dist/v2/{server-cvgn49tr.js → server-1rfgbjfn.js} +1 -1
- package/dist/v2/{server-3bc6k4k4.js → server-7srtwsa4.js} +5 -5
- package/dist/v2/{server-7jzrrxap.js → server-9yyqq3mm.js} +1 -1
- package/dist/v2/{server-2htmbqbv.js → server-brhj8qtd.js} +1 -1
- package/dist/v2/{server-3dqjhchy.js → server-dd0nja67.js} +1 -1
- package/dist/v2/{server-8wcf79fe.js → server-fpqe39as.js} +1 -1
- package/dist/v2/{server-cjz51jm2.js → server-fw31krgq.js} +3 -3
- package/dist/v2/{server-4n2tknpc.js → server-gtv9wbhq.js} +227 -38
- package/dist/v2/{server-8pqnnmf9.js → server-hcvcxzx7.js} +2 -2
- package/dist/v2/{server-kb9nn0a0.js → server-j8epsc0g.js} +35 -14
- package/dist/v2/{server-rygvffsf.js → server-jdwd03ep.js} +4 -4
- package/dist/v2/{server-q6j5dasr.js → server-kdrezdy0.js} +1 -1
- package/dist/v2/{server-e2v4m8xe.js → server-mv1w7t6z.js} +61 -30
- package/dist/v2/{server-hetyb88z.js → server-nfan6zb6.js} +65 -65
- package/dist/v2/{server-4enr7s6x.js → server-qcw43339.js} +1 -1
- package/dist/v2/{server-5zrpr764.js → server-sy4b1sra.js} +1 -1
- package/dist/v2/{server-9a6v0wth.js → server-v4fwha43.js} +9 -8
- package/dist/v2/{server-pcygfdbs.js → server-w3zeywp1.js} +1 -1
- package/dist/v2/{server-czb2rkpk.js → server-wkdgjjch.js} +1 -1
- package/dist/v2/{server-9290a1mb.js → server-x08d1xf3.js} +1 -1
- package/dist/v2/server.js +4 -4
- package/dist/v2/{sqlite-mhjkerzq.js → sqlite-j3tvg8r0.js} +1 -1
- package/dist/v2/{storage-memory-07fx57k6.js → storage-memory-8168bgef.js} +2 -2
- package/dist/v2/{storage-tags-3a4cavqb.js → storage-tags-j2fzq3sw.js} +2 -2
- package/dist/v2/{wrapup-orchestrator-r2v7kgy3.js → wrapup-orchestrator-s92ebfzv.js} +19 -19
- package/dist/{wrapup-orchestrator-z7agncp8.js → wrapup-orchestrator-df61jmz9.js} +21 -21
- package/package.json +3 -3
- package/src/shared/processed-image-eligibility.test.ts +68 -0
- package/src/shared/processed-image-eligibility.ts +41 -0
- package/src/shared/processed-image-position-review.json +20 -0
- package/src/shared/processed-image-position-review.test.ts +19 -0
- package/src/shared/recovery-reasoning-prefix.test.ts +34 -0
- package/src/shared/recovery-reasoning-prefix.ts +35 -0
- package/src/shared/sqlite-acquisition-routing.test.ts +4 -3
- package/src/shared/sqlite-foreground-wait.test.ts +140 -0
- package/src/shared/sqlite-pass-scope.test.ts +4 -4
- package/src/shared/sqlite-writer-diagnostics.test.ts +31 -0
- package/src/shared/sqlite.ts +64 -23
- package/src/shared/tag-transcript.ts +118 -0
|
@@ -109,6 +109,8 @@ import {
|
|
|
109
109
|
resolveLkgModelKeys,
|
|
110
110
|
createLkgEntryProjector,
|
|
111
111
|
captureLkgSlot,
|
|
112
|
+
validateAnthropicReasoningRuns,
|
|
113
|
+
validateLkgSeam,
|
|
112
114
|
replayLkg,
|
|
113
115
|
coldStartRawServedIndex,
|
|
114
116
|
coldStartUncapturedReplay,
|
|
@@ -263,7 +265,7 @@ import {
|
|
|
263
265
|
startCompartmentAgent,
|
|
264
266
|
setRecompStarting2,
|
|
265
267
|
setRecompTerminal2
|
|
266
|
-
} from "./server-
|
|
268
|
+
} from "./server-mv1w7t6z.js";
|
|
267
269
|
import {
|
|
268
270
|
CANONICAL_DREAM_TASKS,
|
|
269
271
|
DREAM_TASK_CAPABILITIES,
|
|
@@ -301,7 +303,7 @@ import {
|
|
|
301
303
|
openDatabaseAsync,
|
|
302
304
|
isDatabasePersisted,
|
|
303
305
|
getDatabasePersistenceError
|
|
304
|
-
} from "./server-
|
|
306
|
+
} from "./server-v4fwha43.js";
|
|
305
307
|
import {
|
|
306
308
|
setHomeProjectPermission,
|
|
307
309
|
shouldSkipHomeProjectMemory,
|
|
@@ -317,7 +319,7 @@ import {
|
|
|
317
319
|
storedPathBelongsToIdentity,
|
|
318
320
|
beginBootQuietPeriod,
|
|
319
321
|
scheduleAfterBootQuiet
|
|
320
|
-
} from "./server-
|
|
322
|
+
} from "./server-kdrezdy0.js";
|
|
321
323
|
import {
|
|
322
324
|
detectLatestTurnThinkingMismatch,
|
|
323
325
|
isPrefixBoundThinkingModel,
|
|
@@ -346,6 +348,8 @@ import {
|
|
|
346
348
|
sessionDecisionCalibration,
|
|
347
349
|
transitionSessionHygieneUnits,
|
|
348
350
|
getProtectionWindowForSession,
|
|
351
|
+
withReplayEnvelopeSnapshot,
|
|
352
|
+
invalidateReplayEnvelopeSnapshot,
|
|
349
353
|
isRustMarkerAdmissionFenced,
|
|
350
354
|
setRustMarkerAdmissionFence,
|
|
351
355
|
ReplayDocumentError,
|
|
@@ -415,6 +419,7 @@ import {
|
|
|
415
419
|
getStaleReduceStrippedIds,
|
|
416
420
|
addStaleReduceStrippedIds,
|
|
417
421
|
getProcessedImageStrippedIds,
|
|
422
|
+
getProcessedImageMarkers,
|
|
418
423
|
addProcessedImageStrippedIds,
|
|
419
424
|
getPendingCompactionMarkerState,
|
|
420
425
|
getCompactionMarkerHealth,
|
|
@@ -424,6 +429,7 @@ import {
|
|
|
424
429
|
clearPendingCompactionMarkerStateIf,
|
|
425
430
|
getPendingPiCompactionMarkerState,
|
|
426
431
|
clearPendingPiCompactionMarkerStateIf,
|
|
432
|
+
logPiCompactionMarkerClear,
|
|
427
433
|
setSessionWorkMetrics,
|
|
428
434
|
getObservedEpochFloor,
|
|
429
435
|
resolveEpochFloorForPass,
|
|
@@ -458,6 +464,7 @@ import {
|
|
|
458
464
|
stripReasoningFromAssistantIds,
|
|
459
465
|
findMergedReasoningStripDecisions,
|
|
460
466
|
stripReasoningFromMergedAssistants,
|
|
467
|
+
getEmptyImageParts,
|
|
461
468
|
stripProcessedImages,
|
|
462
469
|
projectOpencodeReasoningBudgetCutoff,
|
|
463
470
|
DEFAULT_KEEP_REASONING_TOKENS,
|
|
@@ -483,6 +490,7 @@ import {
|
|
|
483
490
|
withRawSessionMessageCache2,
|
|
484
491
|
readRawSessionMessages2,
|
|
485
492
|
visitRawSessionMessages2,
|
|
493
|
+
visitRawSessionMessagesAsync2,
|
|
486
494
|
prepareRawSessionOrdinals2,
|
|
487
495
|
primeTailRawMessageCache2,
|
|
488
496
|
primeInMemoryTailRawMessageCache2,
|
|
@@ -495,7 +503,7 @@ import {
|
|
|
495
503
|
readRawSessionMessageById2,
|
|
496
504
|
readSessionChunk2,
|
|
497
505
|
readRawSessionSeedTail2
|
|
498
|
-
} from "./server-
|
|
506
|
+
} from "./server-gtv9wbhq.js";
|
|
499
507
|
import {
|
|
500
508
|
textMentionsRecentCommit,
|
|
501
509
|
hasMeaningfulUserText2,
|
|
@@ -527,21 +535,21 @@ import {
|
|
|
527
535
|
isTransientSqliteError2,
|
|
528
536
|
SqliteAcquisitionBusyError2,
|
|
529
537
|
withAsyncPrivilegedWriter2
|
|
530
|
-
} from "./server-
|
|
538
|
+
} from "./server-j8epsc0g.js";
|
|
531
539
|
import {
|
|
532
540
|
sameProjectDirectory,
|
|
533
541
|
canonicalProjectDirectory
|
|
534
|
-
} from "./server-
|
|
542
|
+
} from "./server-brhj8qtd.js";
|
|
535
543
|
import {
|
|
536
544
|
deleteChunkEmbedBackoffForSession
|
|
537
|
-
} from "./server-
|
|
545
|
+
} from "./server-fpqe39as.js";
|
|
538
546
|
import {
|
|
539
547
|
registerOwnRpcServerInstance,
|
|
540
548
|
rpcPortDir,
|
|
541
549
|
rpcPortFilePath,
|
|
542
550
|
parseRpcPortFile,
|
|
543
551
|
inspectProcessesAsync
|
|
544
|
-
} from "./server-
|
|
552
|
+
} from "./server-1rfgbjfn.js";
|
|
545
553
|
import {
|
|
546
554
|
BoundedSessionMap,
|
|
547
555
|
LkgRecoveryFenceError,
|
|
@@ -560,7 +568,7 @@ import {
|
|
|
560
568
|
isMessageIndexReconciledThrough2,
|
|
561
569
|
indexMessagesAfterOrdinal2,
|
|
562
570
|
sweepOrphanedOpenCodeMessageIndexes2
|
|
563
|
-
} from "./server-
|
|
571
|
+
} from "./server-7srtwsa4.js";
|
|
564
572
|
import {
|
|
565
573
|
stableStringify,
|
|
566
574
|
getTemporalDecisions,
|
|
@@ -659,14 +667,14 @@ import {
|
|
|
659
667
|
adoptNullOwnerToolTag2,
|
|
660
668
|
getCandidateToolOwners2,
|
|
661
669
|
pickNearestPriorOwner2
|
|
662
|
-
} from "./server-
|
|
670
|
+
} from "./server-w3zeywp1.js";
|
|
663
671
|
import"./server-51779zs2.js";
|
|
664
672
|
import {
|
|
665
673
|
isRawCompactionSummaryInfo2,
|
|
666
674
|
extractInMemoryMessageViews2,
|
|
667
675
|
buildInMemoryTailRawMessages2,
|
|
668
676
|
runSessionWarmupWorker
|
|
669
|
-
} from "./server-
|
|
677
|
+
} from "./server-dd0nja67.js";
|
|
670
678
|
import {
|
|
671
679
|
resolveOpenCodeDbPath,
|
|
672
680
|
assertOpenCodeStoreGeneration,
|
|
@@ -682,7 +690,7 @@ import {
|
|
|
682
690
|
latestRealUserTurnIdFromOpenCodeDb,
|
|
683
691
|
getMessageTimesFromOpenCodeDb,
|
|
684
692
|
findLastAssistantModelFromOpenCodeDb
|
|
685
|
-
} from "./server-
|
|
693
|
+
} from "./server-wkdgjjch.js";
|
|
686
694
|
import {
|
|
687
695
|
getCurrentToolSetHash,
|
|
688
696
|
recordToolDefinition,
|
|
@@ -700,7 +708,7 @@ import {
|
|
|
700
708
|
resolveStoredPathWorkspaceIdentity,
|
|
701
709
|
storedPathBelongsToWorkspace,
|
|
702
710
|
computeWorkspaceEpochFingerprint
|
|
703
|
-
} from "./server-
|
|
711
|
+
} from "./server-hcvcxzx7.js";
|
|
704
712
|
import {
|
|
705
713
|
GIT_SWEEP_LEASE_RENEWAL_MS,
|
|
706
714
|
acquireGitSweepLease,
|
|
@@ -727,7 +735,7 @@ import {
|
|
|
727
735
|
drainCommitBacklogForProject2,
|
|
728
736
|
embedSessionCompartmentChunks2,
|
|
729
737
|
getEmbeddingCoverageStatus2
|
|
730
|
-
} from "./server-
|
|
738
|
+
} from "./server-fw31krgq.js";
|
|
731
739
|
import"./server-fb3zxn06.js";
|
|
732
740
|
import {
|
|
733
741
|
SESSION_NOTE_CONDITION_ERROR,
|
|
@@ -771,7 +779,7 @@ import {
|
|
|
771
779
|
readGitFileChangeTimesSince,
|
|
772
780
|
verificationFileExists,
|
|
773
781
|
normalizeVerificationFiles
|
|
774
|
-
} from "./server-
|
|
782
|
+
} from "./server-jdwd03ep.js";
|
|
775
783
|
import {
|
|
776
784
|
deriveTriggerBudget2,
|
|
777
785
|
deriveHistorianChunkTokens2,
|
|
@@ -779,7 +787,7 @@ import {
|
|
|
779
787
|
resolveHistorianProducerLimits2,
|
|
780
788
|
resolveHistorianContextLimit2
|
|
781
789
|
} from "./server-t528t8qm.js";
|
|
782
|
-
import"./server-
|
|
790
|
+
import"./server-x08d1xf3.js";
|
|
783
791
|
import {
|
|
784
792
|
isEmbeddingHostBusy2
|
|
785
793
|
} from "./server-qt1qqasc.js";
|
|
@@ -793,7 +801,7 @@ import {
|
|
|
793
801
|
} from "./server-ras2sxnc.js";
|
|
794
802
|
import {
|
|
795
803
|
cosineSimilarity
|
|
796
|
-
} from "./server-
|
|
804
|
+
} from "./server-sy4b1sra.js";
|
|
797
805
|
import {
|
|
798
806
|
computeCueContentHash,
|
|
799
807
|
hasMuralCueColumns,
|
|
@@ -818,7 +826,7 @@ import {
|
|
|
818
826
|
mergeMemoryStats2,
|
|
819
827
|
archiveMemory2,
|
|
820
828
|
getMemoryCountsByStatus2
|
|
821
|
-
} from "./server-
|
|
829
|
+
} from "./server-9yyqq3mm.js";
|
|
822
830
|
import {
|
|
823
831
|
registerNotificationSink2,
|
|
824
832
|
pushNotification2,
|
|
@@ -830,7 +838,7 @@ import"./server-676xw7at.js";
|
|
|
830
838
|
import {
|
|
831
839
|
flushIgnoredMessages2,
|
|
832
840
|
sendStatusNotification2
|
|
833
|
-
} from "./server-
|
|
841
|
+
} from "./server-qcw43339.js";
|
|
834
842
|
import {
|
|
835
843
|
renderSingleStoreMigrationRequiredRefusal,
|
|
836
844
|
SingleStoreMigrationRequiredError,
|
|
@@ -845,12 +853,13 @@ import {
|
|
|
845
853
|
SubcModuleTransport,
|
|
846
854
|
indexCommitsForProject,
|
|
847
855
|
embedUnembeddedCommits,
|
|
856
|
+
withMessageFtsSessionFilter,
|
|
848
857
|
createUnifiedSearchDiagnostics2,
|
|
849
858
|
parseIdShapedQuery2,
|
|
850
859
|
resolveMemoriesByIdsForSearch2,
|
|
851
860
|
unifiedSearch2,
|
|
852
861
|
formatSearchResults2
|
|
853
|
-
} from "./server-
|
|
862
|
+
} from "./server-nfan6zb6.js";
|
|
854
863
|
import {
|
|
855
864
|
resolvePromptContext2
|
|
856
865
|
} from "./server-fmsr7v69.js";
|
|
@@ -2782,6 +2791,7 @@ function forgetCachedPrefix(sessionId) {
|
|
|
2782
2791
|
function dropCompartmentsAfter(db, sessionId, anchor, holderId, activeBranch = false, onRetire) {
|
|
2783
2792
|
db.exec("BEGIN IMMEDIATE");
|
|
2784
2793
|
let finished = false;
|
|
2794
|
+
let clearedMarker = null;
|
|
2785
2795
|
try {
|
|
2786
2796
|
if (!isCompartmentLeaseHeld(db, sessionId, holderId)) {
|
|
2787
2797
|
db.exec("ROLLBACK");
|
|
@@ -2798,14 +2808,16 @@ function dropCompartmentsAfter(db, sessionId, anchor, holderId, activeBranch = f
|
|
|
2798
2808
|
if (activeBranch) {
|
|
2799
2809
|
db.prepare("UPDATE session_meta SET prior_boundary_ordinal = ? WHERE session_id = ?").run((anchor?.endMessage ?? 0) + 1, sessionId);
|
|
2800
2810
|
const marker = getPendingPiCompactionMarkerState(db, sessionId);
|
|
2801
|
-
if (marker)
|
|
2802
|
-
|
|
2811
|
+
if (marker && clearPendingPiCompactionMarkerStateIf(db, sessionId, marker, null))
|
|
2812
|
+
clearedMarker = marker;
|
|
2803
2813
|
}
|
|
2804
2814
|
deleteChunkEmbedBackoffForSession(db, sessionId);
|
|
2805
2815
|
queueM0Mutation(db, { sessionId, mutationType: "recomp_boundary_change" });
|
|
2806
2816
|
clearCachedM0M1(db, sessionId);
|
|
2807
2817
|
db.exec("COMMIT");
|
|
2808
2818
|
finished = true;
|
|
2819
|
+
if (clearedMarker)
|
|
2820
|
+
logPiCompactionMarkerClear(sessionId, clearedMarker, "active-branch-retired");
|
|
2809
2821
|
return dropped.map((row) => row.sequence);
|
|
2810
2822
|
} finally {
|
|
2811
2823
|
if (!finished) {
|
|
@@ -6483,21 +6495,40 @@ function buildReplacementContent(tagId) {
|
|
|
6483
6495
|
return `[dropped §${tagId}§]`;
|
|
6484
6496
|
}
|
|
6485
6497
|
function applyNewToolDrop(target, options) {
|
|
6486
|
-
if (
|
|
6498
|
+
if (options.persist && (target?.prepareDrop?.() ?? target?.canDrop?.()) === false) {
|
|
6499
|
+
return { result: "incomplete", mode: "full" };
|
|
6500
|
+
}
|
|
6501
|
+
if (!target) {
|
|
6502
|
+
options.persist?.("full");
|
|
6487
6503
|
return { result: "absent", mode: "full" };
|
|
6488
|
-
|
|
6504
|
+
}
|
|
6505
|
+
if (options.inWindow && hasSmallToolInput(target) || options.keepSkeleton === true || target.cannotRemove?.() === true || target.wouldStrandConversationEnd?.() === true) {
|
|
6489
6506
|
const strip = target.hasAttachments?.() === true;
|
|
6507
|
+
options.persist?.(strip ? "skeleton_stripped" : "skeleton_real");
|
|
6490
6508
|
return {
|
|
6491
6509
|
result: (strip ? target.skeletonStripped?.() : target.skeletonReal?.()) ?? "absent",
|
|
6492
6510
|
mode: strip ? "skeleton_stripped" : "skeleton_real"
|
|
6493
6511
|
};
|
|
6494
6512
|
}
|
|
6513
|
+
options.persist?.("full");
|
|
6495
6514
|
const result = target.drop?.() ?? "absent";
|
|
6496
6515
|
if (result === "truncated" && target.hasAttachments?.() === true) {
|
|
6497
6516
|
return { result: target.skeletonStripped?.() ?? "absent", mode: "skeleton_stripped" };
|
|
6498
6517
|
}
|
|
6499
6518
|
return { result, mode: result === "truncated" ? "skeleton_real" : "full" };
|
|
6500
6519
|
}
|
|
6520
|
+
function applyPersistedToolDrop(db, sessionId, tagNumber, target, options, afterWrite) {
|
|
6521
|
+
return applyNewToolDrop(target, {
|
|
6522
|
+
...options,
|
|
6523
|
+
persist: (mode) => {
|
|
6524
|
+
db.transaction(() => {
|
|
6525
|
+
updateTagDropMode2(db, sessionId, tagNumber, mode);
|
|
6526
|
+
updateTagStatus2(db, sessionId, tagNumber, "dropped");
|
|
6527
|
+
afterWrite?.();
|
|
6528
|
+
}).immediate();
|
|
6529
|
+
}
|
|
6530
|
+
});
|
|
6531
|
+
}
|
|
6501
6532
|
function hasSmallToolInput(target) {
|
|
6502
6533
|
const bytes = target?.inputStringBytes?.() ?? null;
|
|
6503
6534
|
return bytes !== null && bytes <= SKELETON_REAL_INPUT_MAX_BYTES;
|
|
@@ -6577,11 +6608,11 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
6577
6608
|
diagnostics.reasons[reason] = (diagnostics.reasons[reason] ?? 0) + 1;
|
|
6578
6609
|
};
|
|
6579
6610
|
let admitted = false;
|
|
6580
|
-
let startedAt = 0;
|
|
6581
6611
|
try {
|
|
6582
6612
|
db.transaction(() => {
|
|
6583
6613
|
admitted = true;
|
|
6584
|
-
|
|
6614
|
+
}).immediate();
|
|
6615
|
+
{
|
|
6585
6616
|
const pendingOps = preloadedPendingOps ?? getPendingOps(db, sessionId);
|
|
6586
6617
|
const tags = preloadedTags ?? getTagsByNumbers2(db, sessionId, [
|
|
6587
6618
|
...new Set([
|
|
@@ -6633,10 +6664,31 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
6633
6664
|
continue;
|
|
6634
6665
|
}
|
|
6635
6666
|
}
|
|
6667
|
+
const persistDrop = (mode) => {
|
|
6668
|
+
let startedAt = 0;
|
|
6669
|
+
try {
|
|
6670
|
+
db.transaction(() => {
|
|
6671
|
+
startedAt = performance.now();
|
|
6672
|
+
if (mode)
|
|
6673
|
+
updateTagDropMode2(db, sessionId, pendingOp.tagId, mode);
|
|
6674
|
+
updateTagStatus2(db, sessionId, pendingOp.tagId, "dropped");
|
|
6675
|
+
if (!synthetic)
|
|
6676
|
+
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
6677
|
+
}).immediate();
|
|
6678
|
+
} finally {
|
|
6679
|
+
if (startedAt)
|
|
6680
|
+
logSlowWriteTransaction("apply_pending_operation", startedAt);
|
|
6681
|
+
}
|
|
6682
|
+
};
|
|
6636
6683
|
let shouldPersistDrop = false;
|
|
6637
6684
|
if (isToolTag) {
|
|
6638
6685
|
if (editMarkerTagIds.has(pendingOp.tagId)) {
|
|
6639
6686
|
const strip = target?.hasAttachments?.() === true;
|
|
6687
|
+
if (target?.canDrop?.() === false || target?.prepareDrop?.() === false || !target) {
|
|
6688
|
+
reject("edit_marker_incomplete");
|
|
6689
|
+
continue;
|
|
6690
|
+
}
|
|
6691
|
+
persistDrop(strip ? "edit_marker_stripped" : "edit_marker");
|
|
6640
6692
|
const markResult = (strip ? target?.editMarkerStripped?.() : target?.editMarker?.()) ?? "absent";
|
|
6641
6693
|
if (markResult === "incomplete" || markResult === "absent") {
|
|
6642
6694
|
reject(`edit_marker_${markResult}`);
|
|
@@ -6645,11 +6697,11 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
6645
6697
|
didMutateMessage = true;
|
|
6646
6698
|
operationMutated = true;
|
|
6647
6699
|
onTagReduced?.({ tagNumber: pendingOp.tagId, mode: "edit_marker" });
|
|
6648
|
-
updateTagDropMode2(db, sessionId, pendingOp.tagId, strip ? "edit_marker_stripped" : "edit_marker");
|
|
6649
6700
|
shouldPersistDrop = true;
|
|
6650
6701
|
} else {
|
|
6651
6702
|
const { result: dropResult, mode: appliedMode } = applyNewToolDrop(target, {
|
|
6652
|
-
inWindow: skeletonWindow.has(pendingOp.tagId)
|
|
6703
|
+
inWindow: skeletonWindow.has(pendingOp.tagId),
|
|
6704
|
+
persist: persistDrop
|
|
6653
6705
|
});
|
|
6654
6706
|
if (dropResult === "incomplete" || synthetic && dropResult !== "removed" && dropResult !== "truncated") {
|
|
6655
6707
|
reject(`drop_${dropResult}`);
|
|
@@ -6665,12 +6717,12 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
6665
6717
|
} else {
|
|
6666
6718
|
reject(`drop_${dropResult}`);
|
|
6667
6719
|
}
|
|
6668
|
-
updateTagDropMode2(db, sessionId, pendingOp.tagId, appliedMode);
|
|
6669
6720
|
shouldPersistDrop = true;
|
|
6670
6721
|
}
|
|
6671
6722
|
} else if (target) {
|
|
6672
6723
|
const replacement = buildReplacementContent(pendingOp.tagId);
|
|
6673
6724
|
const priorContent = target.getContent?.();
|
|
6725
|
+
persistDrop();
|
|
6674
6726
|
const changed = target.setContent(replacement);
|
|
6675
6727
|
if (changed) {
|
|
6676
6728
|
didMutateMessage = true;
|
|
@@ -6687,30 +6739,25 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
|
|
|
6687
6739
|
shouldPersistDrop = true;
|
|
6688
6740
|
} else if (!synthetic) {
|
|
6689
6741
|
reject("target_absent");
|
|
6742
|
+
persistDrop();
|
|
6690
6743
|
shouldPersistDrop = true;
|
|
6691
6744
|
}
|
|
6692
6745
|
if (!shouldPersistDrop) {
|
|
6693
6746
|
reject("not_persisted");
|
|
6694
6747
|
continue;
|
|
6695
6748
|
}
|
|
6696
|
-
updateTagStatus2(db, sessionId, pendingOp.tagId, "dropped");
|
|
6697
|
-
if (!synthetic)
|
|
6698
|
-
removePendingOp(db, sessionId, pendingOp.tagId);
|
|
6699
6749
|
if (operationMutated)
|
|
6700
6750
|
diagnostics.mutated += 1;
|
|
6701
6751
|
else
|
|
6702
6752
|
diagnostics.persistedWithoutMutation += 1;
|
|
6703
6753
|
}
|
|
6704
|
-
}
|
|
6754
|
+
}
|
|
6705
6755
|
} catch (error) {
|
|
6706
6756
|
if (!admitted && /database (?:table )?is locked|sqlite_(busy|locked)/i.test(String(error))) {
|
|
6707
6757
|
sessionLog2(sessionId, "pending operations write admission busy; retaining prior bytes for retry");
|
|
6708
6758
|
return false;
|
|
6709
6759
|
}
|
|
6710
6760
|
throw error;
|
|
6711
|
-
} finally {
|
|
6712
|
-
if (admitted)
|
|
6713
|
-
logSlowWriteTransaction("apply_pending_operations", startedAt);
|
|
6714
6761
|
}
|
|
6715
6762
|
if (diagnostics) {
|
|
6716
6763
|
onBatchComplete?.(diagnostics);
|
|
@@ -7208,31 +7255,27 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
7208
7255
|
if (plan.shouldDrop) {
|
|
7209
7256
|
const toDrop = new Set(plan.tagNumbers);
|
|
7210
7257
|
const newestEmergencyTags = recentTags;
|
|
7211
|
-
|
|
7212
|
-
|
|
7213
|
-
|
|
7214
|
-
|
|
7215
|
-
|
|
7216
|
-
|
|
7217
|
-
|
|
7218
|
-
|
|
7219
|
-
|
|
7220
|
-
|
|
7221
|
-
|
|
7258
|
+
for (const tag of tags) {
|
|
7259
|
+
if (!toDrop.has(tag.tagNumber))
|
|
7260
|
+
continue;
|
|
7261
|
+
if (tag.status !== "active" || tag.type !== "tool")
|
|
7262
|
+
continue;
|
|
7263
|
+
const target = targets.get(tag.tagNumber);
|
|
7264
|
+
const recent = (emergency.usagePercentage ?? 0) < 95 && newestEmergencyTags.has(tag.tagNumber);
|
|
7265
|
+
const { result } = applyPersistedToolDrop(db, sessionId, tag.tagNumber, target, {
|
|
7266
|
+
inWindow: recent,
|
|
7267
|
+
keepSkeleton: target?.requiresToolArcSkeleton === true
|
|
7268
|
+
});
|
|
7269
|
+
if (result === "removed" || result === "truncated") {
|
|
7270
|
+
droppedTools++;
|
|
7271
|
+
emergencyDroppedTools++;
|
|
7272
|
+
droppedTokenReductions.push({
|
|
7273
|
+
tagNumber: tag.tagNumber,
|
|
7274
|
+
mode: result === "removed" ? "full" : "truncated"
|
|
7222
7275
|
});
|
|
7223
|
-
|
|
7224
|
-
updateTagStatus2(db, sessionId, tag.tagNumber, "dropped");
|
|
7225
|
-
updateTagDropMode2(db, sessionId, tag.tagNumber, mode);
|
|
7226
|
-
droppedTools++;
|
|
7227
|
-
emergencyDroppedTools++;
|
|
7228
|
-
droppedTokenReductions.push({
|
|
7229
|
-
tagNumber: tag.tagNumber,
|
|
7230
|
-
mode: result === "removed" ? "full" : "truncated"
|
|
7231
|
-
});
|
|
7232
|
-
emergencyReclaimedTokens += estimateEmergencyDropReclaimTokens(measuredByTag.get(tag.tagNumber) ?? tag);
|
|
7233
|
-
}
|
|
7276
|
+
emergencyReclaimedTokens += estimateEmergencyDropReclaimTokens(measuredByTag.get(tag.tagNumber) ?? tag);
|
|
7234
7277
|
}
|
|
7235
|
-
}
|
|
7278
|
+
}
|
|
7236
7279
|
sessionLog2(sessionId, `emergency tiered drop: ${plan.reason}`);
|
|
7237
7280
|
} else {
|
|
7238
7281
|
sessionLog2(sessionId, `emergency tiered drop skipped: ${plan.reason}`);
|
|
@@ -7313,35 +7356,33 @@ function applyHeuristicCleanup(sessionId, db, targets, messageTagNumbers, config
|
|
|
7313
7356
|
group.push(tag);
|
|
7314
7357
|
fingerprintGroups.set(fingerprint, group);
|
|
7315
7358
|
}
|
|
7316
|
-
|
|
7317
|
-
|
|
7318
|
-
|
|
7359
|
+
for (const [, group] of fingerprintGroups) {
|
|
7360
|
+
if (group.length <= 1)
|
|
7361
|
+
continue;
|
|
7362
|
+
group.sort((a, b) => a.tagNumber - b.tagNumber);
|
|
7363
|
+
for (let i = 0;i < group.length - 1; i++) {
|
|
7364
|
+
const tag = group[i];
|
|
7365
|
+
if (config.protectedTagNumbers.has(tag.tagNumber))
|
|
7319
7366
|
continue;
|
|
7320
|
-
|
|
7321
|
-
|
|
7322
|
-
|
|
7323
|
-
|
|
7324
|
-
|
|
7325
|
-
|
|
7326
|
-
|
|
7327
|
-
|
|
7328
|
-
|
|
7329
|
-
|
|
7330
|
-
|
|
7331
|
-
|
|
7332
|
-
|
|
7333
|
-
|
|
7334
|
-
|
|
7335
|
-
|
|
7336
|
-
deduplicatedTools++;
|
|
7337
|
-
droppedTokenReductions.push({
|
|
7338
|
-
tagNumber: tag.tagNumber,
|
|
7339
|
-
mode: result === "removed" ? "full" : "truncated"
|
|
7340
|
-
});
|
|
7341
|
-
}
|
|
7367
|
+
const target = targets.get(tag.tagNumber);
|
|
7368
|
+
if (protectedTools.has(tag.tagNumber))
|
|
7369
|
+
continue;
|
|
7370
|
+
if (target?.canDrop?.() === false)
|
|
7371
|
+
continue;
|
|
7372
|
+
const { result } = applyPersistedToolDrop(db, sessionId, tag.tagNumber, target, {
|
|
7373
|
+
inWindow: false
|
|
7374
|
+
});
|
|
7375
|
+
if (result === "incomplete")
|
|
7376
|
+
continue;
|
|
7377
|
+
if (result === "removed" || result === "truncated") {
|
|
7378
|
+
deduplicatedTools++;
|
|
7379
|
+
droppedTokenReductions.push({
|
|
7380
|
+
tagNumber: tag.tagNumber,
|
|
7381
|
+
mode: result === "removed" ? "full" : "truncated"
|
|
7382
|
+
});
|
|
7342
7383
|
}
|
|
7343
7384
|
}
|
|
7344
|
-
}
|
|
7385
|
+
}
|
|
7345
7386
|
}
|
|
7346
7387
|
if (droppedTools > 0 || deduplicatedTools > 0 || droppedInjections > 0) {
|
|
7347
7388
|
sessionLog2(sessionId, `heuristic cleanup: dropped ${droppedTools} tool tags, deduplicated ${deduplicatedTools} tool calls, dropped ${droppedInjections} system injections`);
|
|
@@ -7515,6 +7556,7 @@ function postprocessReplaySnapshot(db, sessionId) {
|
|
|
7515
7556
|
...replay,
|
|
7516
7557
|
staleReduceStrippedIds: new Set(replay.staleReduceStrippedIds),
|
|
7517
7558
|
processedImageStrippedIds: new Set(replay.processedImageStrippedIds),
|
|
7559
|
+
processedImageMarkers: new Map(replay.processedImageMarkers),
|
|
7518
7560
|
strippedPlaceholderIds: new Set(replay.strippedPlaceholderIds),
|
|
7519
7561
|
hiddenSeamPlaceholderIds: new Set(replay.hiddenSeamPlaceholderIds),
|
|
7520
7562
|
mergedReasoningStrippedIds: new Set(replay.mergedReasoningStrippedIds),
|
|
@@ -8820,11 +8862,6 @@ function runRustModePostprocess(args) {
|
|
|
8820
8862
|
for (const anchor of getNoteNudgeAnchors(args.db, args.sessionId)) {
|
|
8821
8863
|
appendReminderToUserMessageById(args.messages, anchor.messageId, anchor.text);
|
|
8822
8864
|
}
|
|
8823
|
-
for (const decision of getAutoSearchHintDecisions(args.db, args.sessionId)) {
|
|
8824
|
-
if (decision.decision === "hint" && getUnpublishedAutoSearchNoHint(args.sessionId, decision.messageId) === undefined) {
|
|
8825
|
-
appendReminderToUserMessageById(args.messages, decision.messageId, decision.text);
|
|
8826
|
-
}
|
|
8827
|
-
}
|
|
8828
8865
|
const trailingBlankDecisions = new Map;
|
|
8829
8866
|
const visibleAssistantIds = args.messages.filter((message) => message.info.role === "assistant").map((message) => message.info.id).filter((id) => typeof id === "string");
|
|
8830
8867
|
if (modelAcceptsEmptyContent(args.resolvedProviderID)) {
|
|
@@ -8862,7 +8899,7 @@ function runRustModePostprocess(args) {
|
|
|
8862
8899
|
userMessageIds: args.messages.filter((m) => m.info.role === "user" && typeof m.info.id === "string").map((m) => m.info.id),
|
|
8863
8900
|
anchorMessageId: currentUserMessageId,
|
|
8864
8901
|
isLiveTail: args.messages.at(-1)?.info.id === currentUserMessageId,
|
|
8865
|
-
|
|
8902
|
+
prefixRewriteCoversAnchor: false
|
|
8866
8903
|
});
|
|
8867
8904
|
const noteReadStillVisible = hasVisibleNoteReadCall(args.messages);
|
|
8868
8905
|
const deferredNoteText = peekNoteNudgeText(args.db, args.sessionId, currentUserMessageId, args.projectPath, noteReadStillVisible, eligibility);
|
|
@@ -8879,6 +8916,11 @@ function runRustModePostprocess(args) {
|
|
|
8879
8916
|
sessionLog2(args.sessionId, `rust note-nudge delivery skipped wire append: ${outcome.kind}`);
|
|
8880
8917
|
}
|
|
8881
8918
|
}
|
|
8919
|
+
for (const decision of getAutoSearchHintDecisions(args.db, args.sessionId)) {
|
|
8920
|
+
if (decision.decision === "hint" && getUnpublishedAutoSearchNoHint(args.sessionId, decision.messageId) === undefined) {
|
|
8921
|
+
appendReminderToUserMessageById(args.messages, decision.messageId, decision.text);
|
|
8922
|
+
}
|
|
8923
|
+
}
|
|
8882
8924
|
const { thinkingBindingRecovery, proactiveThinkingStrip } = applyRustModeThinkingStrips(args, noteNudgeAppended || servedMarkerRecord() !== servedMarkerBefore);
|
|
8883
8925
|
const marker = getPersistedCompactionMarkerState(args.db, args.sessionId);
|
|
8884
8926
|
return {
|
|
@@ -9737,15 +9779,32 @@ async function runPostTransformPhase(args) {
|
|
|
9737
9779
|
sessionLog2(args.sessionId, "transform failed dropping stale ctx_reduce calls:", error);
|
|
9738
9780
|
}
|
|
9739
9781
|
}
|
|
9740
|
-
if (
|
|
9782
|
+
if (!compactionOff && replaySnapshot) {
|
|
9741
9783
|
try {
|
|
9742
9784
|
const tImg = performance.now();
|
|
9785
|
+
const imageWatermark = canEditWholePrefix ? Math.max(args.watermark, getMaxDroppedTagNumber2(args.db, args.sessionId)) : args.watermark;
|
|
9743
9786
|
const frozenImageIds = replaySnapshot.processedImageStrippedIds;
|
|
9787
|
+
const frozenMarkers = replaySnapshot.processedImageMarkers;
|
|
9788
|
+
const replacementText = canUseEmptySentinels ? "" : "[image stripped]";
|
|
9744
9789
|
stripProcessedImages(args.messages, frozenImageIds, {
|
|
9745
|
-
detect: canEditWholePrefix &&
|
|
9746
|
-
watermark:
|
|
9790
|
+
detect: canEditWholePrefix && imageWatermark > 0,
|
|
9791
|
+
watermark: imageWatermark,
|
|
9747
9792
|
messageTagNumbers: args.messageTagNumbers,
|
|
9748
|
-
|
|
9793
|
+
protectedCutoff: args.protectedCutoff,
|
|
9794
|
+
contextPercentage: args.contextUsage.percentage,
|
|
9795
|
+
replacementText,
|
|
9796
|
+
frozenMarkers,
|
|
9797
|
+
protectedMessageIds: new Set([
|
|
9798
|
+
...args.tags.filter((tag) => protectedToolTags.has(tag.tagNumber)).map((tag) => tag.toolOwnerMessageId ?? tag.messageId)
|
|
9799
|
+
]),
|
|
9800
|
+
persistNewIds: (ids, markers) => {
|
|
9801
|
+
if (!addProcessedImageStrippedIds(args.db, args.sessionId, ids, markers))
|
|
9802
|
+
return false;
|
|
9803
|
+
const committed = getProcessedImageMarkers(args.db, args.sessionId);
|
|
9804
|
+
for (const id of ids)
|
|
9805
|
+
frozenMarkers.set(id, committed.get(id) ?? replacementText);
|
|
9806
|
+
return true;
|
|
9807
|
+
},
|
|
9749
9808
|
onFirstApplication: recordFirstApplicationAt
|
|
9750
9809
|
});
|
|
9751
9810
|
logTransformTiming(args.sessionId, "stripProcessedImages", tImg);
|
|
@@ -9873,16 +9932,6 @@ async function runPostTransformPhase(args) {
|
|
|
9873
9932
|
logTransformTiming(args.sessionId, "pp.placeholderNeutralize", tPlaceholder);
|
|
9874
9933
|
}
|
|
9875
9934
|
const tNudgeBlock = performance.now();
|
|
9876
|
-
if (args.fullFeatureMode && !compactionOff && replaySnapshot) {
|
|
9877
|
-
for (const anchor of replaySnapshot.noteNudgeAnchors) {
|
|
9878
|
-
appendReminderToUserMessageById(args.messages, anchor.messageId, anchor.text);
|
|
9879
|
-
}
|
|
9880
|
-
for (const decision of replaySnapshot.autoSearchHintDecisions) {
|
|
9881
|
-
if (decision.decision === "hint") {
|
|
9882
|
-
appendReminderToUserMessageById(args.messages, decision.messageId, decision.text);
|
|
9883
|
-
}
|
|
9884
|
-
}
|
|
9885
|
-
}
|
|
9886
9935
|
logTransformTiming(args.sessionId, "pp.nudgeAndSticky", tNudgeBlock);
|
|
9887
9936
|
const tMarker = performance.now();
|
|
9888
9937
|
const explicitRebuildHappened = args.historyRefreshExplicitBeforePrepare && args.rebuiltHistoryFromInitialPrepare;
|
|
@@ -9958,13 +10007,15 @@ async function runPostTransformPhase(args) {
|
|
|
9958
10007
|
const noteReadStillVisible = args.fullFeatureMode ? hasVisibleNoteReadCall(args.messages) : false;
|
|
9959
10008
|
let noteNudgeAppendedThisPass = false;
|
|
9960
10009
|
const noteNudgeUserMessageId = findNoteNudgeUserMessageId(args.messages);
|
|
10010
|
+
const lastServedForNote = canEditWholePrefix && (m0RematerializedThisPass || historyWasConsumedThisPass) ? args.readLastServedMessages?.() : null;
|
|
10011
|
+
const rewrittenHeadCoversNote = !!lastServedForNote && args.messages.slice(0, prependedMessageCount).some((message, index) => isSyntheticHeadMessage(message) && index < lastServedForNote.length && servedMessageKey(message, args.resolvedProviderID) !== servedMessageKey(lastServedForNote[index], args.resolvedProviderID));
|
|
9961
10012
|
const noteNudgeEligibility = args.fullFeatureMode ? observeNoteNudgeServe({
|
|
9962
10013
|
db: args.db,
|
|
9963
10014
|
sessionId: args.sessionId,
|
|
9964
10015
|
userMessageIds: args.messages.filter((m) => m.info.role === "user" && typeof m.info.id === "string").map((m) => m.info.id),
|
|
9965
10016
|
anchorMessageId: noteNudgeUserMessageId,
|
|
9966
10017
|
isLiveTail: args.messages.at(-1)?.info.id === noteNudgeUserMessageId,
|
|
9967
|
-
|
|
10018
|
+
prefixRewriteCoversAnchor: canEditWholePrefix && rewrittenHeadCoversNote
|
|
9968
10019
|
}) : undefined;
|
|
9969
10020
|
const deferredNoteText = args.fullFeatureMode ? peekNoteNudgeText(args.db, args.sessionId, noteNudgeUserMessageId, args.projectPath, noteReadStillVisible, noteNudgeEligibility) : null;
|
|
9970
10021
|
if (deferredNoteText) {
|
|
@@ -9981,6 +10032,16 @@ async function runPostTransformPhase(args) {
|
|
|
9981
10032
|
sessionLog2(args.sessionId, `note-nudge delivery skipped wire append: ${outcome.kind}`);
|
|
9982
10033
|
}
|
|
9983
10034
|
}
|
|
10035
|
+
if (args.fullFeatureMode && !compactionOff && replaySnapshot) {
|
|
10036
|
+
for (const anchor of replaySnapshot.noteNudgeAnchors) {
|
|
10037
|
+
appendReminderToUserMessageById(args.messages, anchor.messageId, anchor.text);
|
|
10038
|
+
}
|
|
10039
|
+
for (const decision of replaySnapshot.autoSearchHintDecisions) {
|
|
10040
|
+
if (decision.decision === "hint") {
|
|
10041
|
+
appendReminderToUserMessageById(args.messages, decision.messageId, decision.text);
|
|
10042
|
+
}
|
|
10043
|
+
}
|
|
10044
|
+
}
|
|
9984
10045
|
let todoAnchorMovedThisPass = false;
|
|
9985
10046
|
if (args.fullFeatureMode && !compactionOff) {
|
|
9986
10047
|
const todoAnchorBefore = replaySnapshot ? replaySnapshot.todoSyntheticAnchor : getPersistedTodoSyntheticAnchor(args.db, args.sessionId);
|
|
@@ -11180,7 +11241,7 @@ function createPassOutcome() {
|
|
|
11180
11241
|
}
|
|
11181
11242
|
|
|
11182
11243
|
// src/hooks/magic-context/rust-mode-transform.ts
|
|
11183
|
-
import { createHash as
|
|
11244
|
+
import { createHash as createHash5, randomUUID as randomUUID2 } from "node:crypto";
|
|
11184
11245
|
|
|
11185
11246
|
// src/features/magic-context/memory/single-store-embedding-drain.ts
|
|
11186
11247
|
function isWatermarkRow(row) {
|
|
@@ -13627,13 +13688,235 @@ function resolveRustLkgReplayParticipant(sessionId) {
|
|
|
13627
13688
|
return latest;
|
|
13628
13689
|
return alive.length === 1 ? alive[0] : undefined;
|
|
13629
13690
|
}
|
|
13630
|
-
function noteExternalLkgReplay(participant, sessionId,
|
|
13691
|
+
function noteExternalLkgReplay(participant, sessionId, inputMessages, servedMessages) {
|
|
13631
13692
|
if (!participant)
|
|
13632
13693
|
return;
|
|
13633
|
-
participant.enterFreezeFromExternalServe(sessionId,
|
|
13694
|
+
participant.enterFreezeFromExternalServe(sessionId, inputMessages, servedMessages);
|
|
13634
13695
|
sessionLog2(sessionId, "lkg_external_replay_froze_rust_adapter");
|
|
13635
13696
|
}
|
|
13636
13697
|
|
|
13698
|
+
// src/hooks/magic-context/rust-served-raw.ts
|
|
13699
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
13700
|
+
class RustServedRawConflict extends EmergencyFailClosedError {
|
|
13701
|
+
reason;
|
|
13702
|
+
messageIds;
|
|
13703
|
+
firstBlockId;
|
|
13704
|
+
constructor(reason, messageIds, firstBlockId) {
|
|
13705
|
+
super(`Rust served-raw conflict: ${reason} at ${firstBlockId}`);
|
|
13706
|
+
this.reason = reason;
|
|
13707
|
+
this.messageIds = messageIds;
|
|
13708
|
+
this.firstBlockId = firstBlockId;
|
|
13709
|
+
}
|
|
13710
|
+
}
|
|
13711
|
+
function partDigest(part) {
|
|
13712
|
+
const serialized = JSON.stringify(part);
|
|
13713
|
+
return createHash4("sha256").update(stableStringify(serialized === undefined ? undefined : JSON.parse(serialized))).digest("hex");
|
|
13714
|
+
}
|
|
13715
|
+
function records(doc) {
|
|
13716
|
+
if (doc.rustServedRaw === undefined)
|
|
13717
|
+
return [];
|
|
13718
|
+
if (!Array.isArray(doc.rustServedRaw))
|
|
13719
|
+
throw new EmergencyFailClosedError("Invalid Rust served-raw evidence");
|
|
13720
|
+
for (const row of doc.rustServedRaw) {
|
|
13721
|
+
if (!row || typeof row.messageId !== "string" || !Number.isSafeInteger(row.index) || row.index < 0 || row.partId !== undefined && typeof row.partId !== "string" || typeof row.digest !== "string" || !/^[a-f0-9]{64}$/.test(row.digest) || !Array.isArray(row.blockIds) || !row.blockIds.every((id) => typeof id === "string")) {
|
|
13722
|
+
throw new EmergencyFailClosedError("Invalid Rust served-raw part");
|
|
13723
|
+
}
|
|
13724
|
+
}
|
|
13725
|
+
return doc.rustServedRaw;
|
|
13726
|
+
}
|
|
13727
|
+
function rustRawRebuild(db, sessionId) {
|
|
13728
|
+
const value = readReplayEnvelope(db, sessionId).rustRawRebuild;
|
|
13729
|
+
if (value === undefined)
|
|
13730
|
+
return;
|
|
13731
|
+
if (!value || typeof value.identity !== "string" || !/^[a-f0-9]{64}$/.test(value.identity) || !["source_removed", "source_changed", "candidate_loss", "candidate_conflict"].includes(value.reason) || !Array.isArray(value.messageIds) || !value.messageIds.every((id) => typeof id === "string") || typeof value.firstBlockId !== "string" || typeof value.pending !== "boolean") {
|
|
13732
|
+
throw new EmergencyFailClosedError("Invalid Rust raw-rebuild request");
|
|
13733
|
+
}
|
|
13734
|
+
return value;
|
|
13735
|
+
}
|
|
13736
|
+
function servedRawBlockIds(db, sessionId) {
|
|
13737
|
+
return records(readReplayEnvelope(db, sessionId)).flatMap((row) => row.blockIds);
|
|
13738
|
+
}
|
|
13739
|
+
function sourcePart(row, message) {
|
|
13740
|
+
return row.partId === undefined ? message?.parts[row.index] : message?.parts.find((part) => part?.id === row.partId);
|
|
13741
|
+
}
|
|
13742
|
+
function conflict(row, reason) {
|
|
13743
|
+
return new RustServedRawConflict(reason, [row.messageId], row.blockIds[0] ?? `${row.messageId}#0`);
|
|
13744
|
+
}
|
|
13745
|
+
function checkRustServedRawIngress(db, sessionId, input) {
|
|
13746
|
+
const rows = records(readReplayEnvelope(db, sessionId));
|
|
13747
|
+
if (!rows.length)
|
|
13748
|
+
return;
|
|
13749
|
+
const byId = new Map(input.map((message) => [message.info.id, message]));
|
|
13750
|
+
const changed = rows.filter((row) => partDigest(sourcePart(row, byId.get(row.messageId))) !== row.digest);
|
|
13751
|
+
const first = changed[0];
|
|
13752
|
+
if (!first)
|
|
13753
|
+
return;
|
|
13754
|
+
throw new RustServedRawConflict(sourcePart(first, byId.get(first.messageId)) === undefined ? "source_removed" : "source_changed", [...new Set(changed.map((row) => row.messageId))], first.blockIds[0] ?? `${first.messageId}#0`);
|
|
13755
|
+
}
|
|
13756
|
+
function requestRustRawRebuild(db, sessionId, error) {
|
|
13757
|
+
if (!updateReplayDocument(db, sessionId, (doc) => {
|
|
13758
|
+
const previous = doc.rustRawRebuild;
|
|
13759
|
+
if (previous?.pending && previous.reason === error.reason && previous.firstBlockId === error.firstBlockId && error.messageIds.every((id) => previous.messageIds.includes(id)))
|
|
13760
|
+
return false;
|
|
13761
|
+
const messageIds = [
|
|
13762
|
+
...new Set([
|
|
13763
|
+
...previous?.pending ? previous.messageIds : [],
|
|
13764
|
+
...error.messageIds
|
|
13765
|
+
])
|
|
13766
|
+
];
|
|
13767
|
+
const identity = partDigest([
|
|
13768
|
+
previous?.identity ?? "",
|
|
13769
|
+
error.reason,
|
|
13770
|
+
messageIds,
|
|
13771
|
+
error.firstBlockId
|
|
13772
|
+
]);
|
|
13773
|
+
doc.version = 2;
|
|
13774
|
+
doc.rustRawRebuild = {
|
|
13775
|
+
identity,
|
|
13776
|
+
reason: error.reason,
|
|
13777
|
+
messageIds,
|
|
13778
|
+
firstBlockId: error.firstBlockId,
|
|
13779
|
+
pending: true
|
|
13780
|
+
};
|
|
13781
|
+
return true;
|
|
13782
|
+
}))
|
|
13783
|
+
throw new EmergencyFailClosedError("Cannot persist Rust raw-rebuild request");
|
|
13784
|
+
}
|
|
13785
|
+
function noteRustServedRaw(db, sessionId, input, served) {
|
|
13786
|
+
const additions = [];
|
|
13787
|
+
const byId = new Map(served.filter((message) => typeof message?.info?.id === "string").map((message) => [message.info.id, message]));
|
|
13788
|
+
for (const message of input) {
|
|
13789
|
+
const visible = byId.get(message.info.id);
|
|
13790
|
+
if (!visible)
|
|
13791
|
+
continue;
|
|
13792
|
+
let offset = 0;
|
|
13793
|
+
for (const [index, value] of message.parts.entries()) {
|
|
13794
|
+
if (!value || typeof value !== "object")
|
|
13795
|
+
continue;
|
|
13796
|
+
const part = value;
|
|
13797
|
+
const count = encodeOpenCodeMessagesToCk([{ ...message, parts: [part] }])[0].ck.content.length;
|
|
13798
|
+
const actual = typeof part.id === "string" ? visible.parts.find((candidate) => candidate?.id === part.id) : visible.parts[index];
|
|
13799
|
+
const status = part.state?.status;
|
|
13800
|
+
const reachesProvider = !(part.type === "text" && part.ignored === true) && ![
|
|
13801
|
+
"compaction",
|
|
13802
|
+
"step-start",
|
|
13803
|
+
"step-finish",
|
|
13804
|
+
"snapshot",
|
|
13805
|
+
"patch",
|
|
13806
|
+
"agent",
|
|
13807
|
+
"retry"
|
|
13808
|
+
].includes(String(part.type)) && (part.type !== "tool" || status === "completed" || status === "error");
|
|
13809
|
+
if (reachesProvider && count > 0) {
|
|
13810
|
+
const digest = partDigest(part);
|
|
13811
|
+
if (actual === part || partDigest(actual) === digest) {
|
|
13812
|
+
additions.push({
|
|
13813
|
+
messageId: message.info.id,
|
|
13814
|
+
index,
|
|
13815
|
+
...typeof part.id === "string" ? { partId: part.id } : {},
|
|
13816
|
+
digest,
|
|
13817
|
+
blockIds: Array.from({ length: count }, (_, i) => `${message.info.id}#${offset + i}`)
|
|
13818
|
+
});
|
|
13819
|
+
}
|
|
13820
|
+
}
|
|
13821
|
+
offset += count;
|
|
13822
|
+
}
|
|
13823
|
+
}
|
|
13824
|
+
if (!additions.length)
|
|
13825
|
+
return;
|
|
13826
|
+
if (!updateReplayDocument(db, sessionId, (doc) => {
|
|
13827
|
+
const rows = records(doc);
|
|
13828
|
+
const key = (row) => stableStringify([row.messageId, row.partId ?? row.index]);
|
|
13829
|
+
const merged = new Map(rows.map((row) => [key(row), row]));
|
|
13830
|
+
for (const row of additions)
|
|
13831
|
+
merged.set(key(row), row);
|
|
13832
|
+
const next = [...merged.values()];
|
|
13833
|
+
if (stableStringify(rows) === stableStringify(next))
|
|
13834
|
+
return false;
|
|
13835
|
+
doc.version = 2;
|
|
13836
|
+
doc.rustServedRaw = next;
|
|
13837
|
+
return true;
|
|
13838
|
+
}))
|
|
13839
|
+
throw new EmergencyFailClosedError("Cannot persist Rust served-raw evidence");
|
|
13840
|
+
}
|
|
13841
|
+
function preserveRustServedRaw(db, sessionId, output, input = output, reconstruct = new Set, covered = new Set) {
|
|
13842
|
+
const rows = records(readReplayEnvelope(db, sessionId));
|
|
13843
|
+
if (!rows.length)
|
|
13844
|
+
return false;
|
|
13845
|
+
const sources = new Map(input.map((message) => [message.info.id, message]));
|
|
13846
|
+
const byId = new Map(output.map((message) => [message.info.id, message]));
|
|
13847
|
+
let repaired = false;
|
|
13848
|
+
for (const row of rows) {
|
|
13849
|
+
if (covered.has(row.messageId))
|
|
13850
|
+
continue;
|
|
13851
|
+
const original = sources.get(row.messageId);
|
|
13852
|
+
const source = sourcePart(row, original);
|
|
13853
|
+
if (!original || !source)
|
|
13854
|
+
throw conflict(row, "source_removed");
|
|
13855
|
+
if (partDigest(source) !== row.digest)
|
|
13856
|
+
throw conflict(row, "source_changed");
|
|
13857
|
+
let message = byId.get(row.messageId);
|
|
13858
|
+
if (!message) {
|
|
13859
|
+
if (!reconstruct.has(row.messageId))
|
|
13860
|
+
throw conflict(row, "candidate_loss");
|
|
13861
|
+
const sourceIndex = input.indexOf(original);
|
|
13862
|
+
const next = output.findIndex((candidate) => input.findIndex((entry) => entry.info.id === candidate.info.id) > sourceIndex);
|
|
13863
|
+
message = structuredClone(original);
|
|
13864
|
+
output.splice(next < 0 ? output.length : next, 0, message);
|
|
13865
|
+
byId.set(row.messageId, message);
|
|
13866
|
+
repaired = true;
|
|
13867
|
+
}
|
|
13868
|
+
const parts = message.parts;
|
|
13869
|
+
if (row.partId === undefined) {
|
|
13870
|
+
const candidate = parts[row.index];
|
|
13871
|
+
if (partDigest(candidate) === row.digest)
|
|
13872
|
+
continue;
|
|
13873
|
+
const reversibleTag = source.type === "text" && typeof source.text === "string" && typeof candidate?.text === "string" && /^§\d+§ /.test(candidate.text) && candidate.text.replace(/^§\d+§ /, "") === source.text && partDigest({ ...candidate, text: source.text }) === row.digest;
|
|
13874
|
+
if (!reversibleTag) {
|
|
13875
|
+
if (!reconstruct.has(row.messageId))
|
|
13876
|
+
throw conflict(row, "candidate_conflict");
|
|
13877
|
+
message.parts = structuredClone(original.parts);
|
|
13878
|
+
repaired = true;
|
|
13879
|
+
continue;
|
|
13880
|
+
}
|
|
13881
|
+
parts[row.index] = structuredClone(source);
|
|
13882
|
+
continue;
|
|
13883
|
+
}
|
|
13884
|
+
const matches = parts.flatMap((part, i) => part.id === row.partId ? [i] : []);
|
|
13885
|
+
if (matches.length > 1)
|
|
13886
|
+
throw conflict(row, "candidate_conflict");
|
|
13887
|
+
const index = matches[0];
|
|
13888
|
+
if (index !== undefined) {
|
|
13889
|
+
if (partDigest(parts[index]) !== row.digest)
|
|
13890
|
+
parts[index] = structuredClone(source);
|
|
13891
|
+
} else if (["reasoning", "thinking", "redacted_thinking"].includes(String(source.type)) || reconstruct.has(row.messageId)) {
|
|
13892
|
+
parts.splice(row.index, 0, structuredClone(source));
|
|
13893
|
+
repaired = true;
|
|
13894
|
+
} else
|
|
13895
|
+
throw conflict(row, "candidate_loss");
|
|
13896
|
+
}
|
|
13897
|
+
return repaired;
|
|
13898
|
+
}
|
|
13899
|
+
function releaseRustServedRaw(db, sessionId, output, rebuiltIdentity) {
|
|
13900
|
+
const snapshot = readReplayEnvelope(db, sessionId);
|
|
13901
|
+
if (!records(snapshot).length && !snapshot.rustRawRebuild?.pending)
|
|
13902
|
+
return;
|
|
13903
|
+
const byId = new Map(output.map((message) => [message.info.id, message]));
|
|
13904
|
+
if (!updateReplayDocument(db, sessionId, (doc) => {
|
|
13905
|
+
const rows = records(doc);
|
|
13906
|
+
const kept = rows.filter((row) => partDigest(sourcePart(row, byId.get(row.messageId))) === row.digest);
|
|
13907
|
+
const recovery = doc.rustRawRebuild;
|
|
13908
|
+
const acknowledged = recovery?.pending && recovery.identity === rebuiltIdentity;
|
|
13909
|
+
if (kept.length === rows.length && !acknowledged)
|
|
13910
|
+
return false;
|
|
13911
|
+
doc.version = 2;
|
|
13912
|
+
doc.rustServedRaw = kept;
|
|
13913
|
+
if (acknowledged)
|
|
13914
|
+
doc.rustRawRebuild = { ...recovery, pending: false };
|
|
13915
|
+
return true;
|
|
13916
|
+
}))
|
|
13917
|
+
throw new EmergencyFailClosedError("Cannot release Rust served-raw evidence");
|
|
13918
|
+
}
|
|
13919
|
+
|
|
13637
13920
|
// src/hooks/magic-context/transform-context-state.ts
|
|
13638
13921
|
function loadPersistedUsageWatermark(db, sessionId) {
|
|
13639
13922
|
const result = db.prepare("SELECT last_response_time FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
@@ -13912,10 +14195,10 @@ function messageCacheSignature(message) {
|
|
|
13912
14195
|
const parts = Array.isArray(message.parts) ? message.parts : [];
|
|
13913
14196
|
const serializedParts = JSON.stringify(parts) ?? "null";
|
|
13914
14197
|
const serializedMessage = JSON.stringify(message) ?? "null";
|
|
13915
|
-
return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${
|
|
14198
|
+
return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${createHash5("sha256").update(serializedMessage).digest("hex")}`;
|
|
13916
14199
|
}
|
|
13917
14200
|
function advanceWireFingerprint(previous, encoded) {
|
|
13918
|
-
return
|
|
14201
|
+
return createHash5("sha256").update(previous).update("\\0").update(JSON.stringify(encoded) ?? "null").digest("hex");
|
|
13919
14202
|
}
|
|
13920
14203
|
function buildWireFingerprint(encoded) {
|
|
13921
14204
|
let fingerprint = "rust-wire-v1";
|
|
@@ -14445,7 +14728,8 @@ function buildTransformBody(args) {
|
|
|
14445
14728
|
args.providerId ? `provider:${args.providerId}` : "",
|
|
14446
14729
|
args.modelKey ? `model:${args.modelKey}` : "",
|
|
14447
14730
|
args.variant ? `variant:${args.variant}` : "",
|
|
14448
|
-
args.systemPromptHash ? `system:${args.systemPromptHash}` : ""
|
|
14731
|
+
args.systemPromptHash ? `system:${args.systemPromptHash}` : "",
|
|
14732
|
+
args.rawRebuild ? `raw_replay:${args.rawRebuild.identity}` : ""
|
|
14449
14733
|
].filter(Boolean).join("|"),
|
|
14450
14734
|
system_prompt_hash: args.systemPromptHash,
|
|
14451
14735
|
adopted_system_prompt_hash: args.passInputs.adopted_system_prompt_hash,
|
|
@@ -14453,6 +14737,14 @@ function buildTransformBody(args) {
|
|
|
14453
14737
|
is_subagent: args.passInputs.is_subagent === true,
|
|
14454
14738
|
messages: args.input,
|
|
14455
14739
|
native_messages: args.nativeMessages,
|
|
14740
|
+
served_raw_block_ids: args.servedRawBlockIds ?? [],
|
|
14741
|
+
...args.rawRebuild?.pending ? {
|
|
14742
|
+
raw_replay_rebuild: {
|
|
14743
|
+
identity: args.rawRebuild.identity,
|
|
14744
|
+
reason: args.rawRebuild.reason,
|
|
14745
|
+
message_ids: args.rawRebuild.messageIds
|
|
14746
|
+
}
|
|
14747
|
+
} : {},
|
|
14456
14748
|
tool_input_key_orders: args.toolInputKeyOrders ?? toolInputKeyOrders(args.input),
|
|
14457
14749
|
...args.fullArrayFingerprint ? { full_array_fingerprint: args.fullArrayFingerprint } : {},
|
|
14458
14750
|
...args.tailDelta ? {
|
|
@@ -14643,6 +14935,7 @@ function createRustModeTransform(deps, options) {
|
|
|
14643
14935
|
throw error;
|
|
14644
14936
|
} finally {
|
|
14645
14937
|
clock.clearTimeout(timer);
|
|
14938
|
+
invalidateReplayEnvelopeSnapshot(deps.db, args.sessionId);
|
|
14646
14939
|
}
|
|
14647
14940
|
};
|
|
14648
14941
|
const callTransformWithStallProbe = async (args, attemptTimeoutMs) => {
|
|
@@ -14751,6 +15044,24 @@ function createRustModeTransform(deps, options) {
|
|
|
14751
15044
|
logTransformTiming(sessionId, "rust.ordinal_rebuild", startedAt, detail);
|
|
14752
15045
|
}
|
|
14753
15046
|
};
|
|
15047
|
+
const recordRawConflict = (sessionId, error) => {
|
|
15048
|
+
requestRustRawRebuild(deps.db, sessionId, error);
|
|
15049
|
+
dropSlot(sessionId, `raw_replay_${error.reason}`);
|
|
15050
|
+
const state = ensureState(states, sessionId);
|
|
15051
|
+
state.forceFullWire = true;
|
|
15052
|
+
state.parked = false;
|
|
15053
|
+
sessionLog2(sessionId, `raw_replay_rebuild_requested reason=${error.reason} first_changed=${error.firstBlockId}`);
|
|
15054
|
+
};
|
|
15055
|
+
const observeRawReplay = (sessionId, input, served) => {
|
|
15056
|
+
try {
|
|
15057
|
+
checkRustServedRawIngress(deps.db, sessionId, input);
|
|
15058
|
+
noteRustServedRaw(deps.db, sessionId, input, served);
|
|
15059
|
+
} catch (error) {
|
|
15060
|
+
if (error instanceof RustServedRawConflict)
|
|
15061
|
+
recordRawConflict(sessionId, error);
|
|
15062
|
+
throw error;
|
|
15063
|
+
}
|
|
15064
|
+
};
|
|
14754
15065
|
const replayLastGood = (sessionId, currentMessages, output, systemPromptTokens) => {
|
|
14755
15066
|
try {
|
|
14756
15067
|
if (states.get(sessionId)?.markerAdmissionFenced || isRustMarkerAdmissionFenced(deps.db, sessionId))
|
|
@@ -14837,6 +15148,7 @@ function createRustModeTransform(deps, options) {
|
|
|
14837
15148
|
ownDirtyRevision: lkgDirtyRevision(sessionId)
|
|
14838
15149
|
}));
|
|
14839
15150
|
const replayInputCount = currentMessages.length;
|
|
15151
|
+
observeRawReplay(sessionId, currentMessages, replay.messages);
|
|
14840
15152
|
replaceMessagesInPlace(output, replay.messages);
|
|
14841
15153
|
ensureState(states, sessionId).lkgLatestServedDigest = lkgServedArrayDigest(JSON.stringify(replay.messages));
|
|
14842
15154
|
enterLkgReplayFreeze(ensureState(states, sessionId), replayInputCount);
|
|
@@ -14900,7 +15212,10 @@ function createRustModeTransform(deps, options) {
|
|
|
14900
15212
|
const passStampBySession = new Map;
|
|
14901
15213
|
const replayParticipant = {
|
|
14902
15214
|
lastPassStamp: (sessionId) => states.has(sessionId) ? passStampBySession.get(sessionId) : undefined,
|
|
14903
|
-
enterFreezeFromExternalServe: (sessionId,
|
|
15215
|
+
enterFreezeFromExternalServe: (sessionId, inputMessages, servedMessages) => {
|
|
15216
|
+
observeRawReplay(sessionId, inputMessages, servedMessages);
|
|
15217
|
+
enterLkgReplayFreeze(ensureState(states, sessionId), inputMessages.length);
|
|
15218
|
+
},
|
|
14904
15219
|
replayFits: (sessionId, messages, inputMessages) => {
|
|
14905
15220
|
try {
|
|
14906
15221
|
const fit = lkgReplayFits({
|
|
@@ -15046,6 +15361,24 @@ function createRustModeTransform(deps, options) {
|
|
|
15046
15361
|
bindSystemDateRequest(output, dateRequest);
|
|
15047
15362
|
const passObservedAtMs = Date.now();
|
|
15048
15363
|
const state = ensureState(states, sessionId);
|
|
15364
|
+
let rawRebuild;
|
|
15365
|
+
let rawReadError;
|
|
15366
|
+
try {
|
|
15367
|
+
rawRebuild = rustRawRebuild(deps.db, sessionId);
|
|
15368
|
+
try {
|
|
15369
|
+
checkRustServedRawIngress(deps.db, sessionId, messages);
|
|
15370
|
+
} catch (error) {
|
|
15371
|
+
if (!(error instanceof RustServedRawConflict) || !rawRebuild?.pending)
|
|
15372
|
+
throw error;
|
|
15373
|
+
requestRustRawRebuild(deps.db, sessionId, error);
|
|
15374
|
+
rawRebuild = rustRawRebuild(deps.db, sessionId);
|
|
15375
|
+
}
|
|
15376
|
+
} catch (error) {
|
|
15377
|
+
if (error instanceof RustServedRawConflict)
|
|
15378
|
+
throw error;
|
|
15379
|
+
rawReadError = error;
|
|
15380
|
+
}
|
|
15381
|
+
const reconstructRaw = new Set(rawRebuild?.messageIds ?? []);
|
|
15049
15382
|
let entrySlot = getSlot(sessionId);
|
|
15050
15383
|
try {
|
|
15051
15384
|
entrySlot = loadPersistedLkgSlot(deps.db, sessionId, true) ?? entrySlot;
|
|
@@ -15084,6 +15417,7 @@ function createRustModeTransform(deps, options) {
|
|
|
15084
15417
|
let decision = "error";
|
|
15085
15418
|
let materializeReason = "none";
|
|
15086
15419
|
let frozenReleaseReason = null;
|
|
15420
|
+
let frozenReleaseFirstChanged = "unknown";
|
|
15087
15421
|
let schedulerDecision;
|
|
15088
15422
|
let responseCommitted;
|
|
15089
15423
|
let responsePrefixBustPermitted;
|
|
@@ -15109,7 +15443,7 @@ function createRustModeTransform(deps, options) {
|
|
|
15109
15443
|
let recoveryProjectRoot = options.projectRoot ?? deps.directory ?? "";
|
|
15110
15444
|
const passUsageSnapshot = loadContextUsage(deps.contextUsageMap, deps.db, sessionId);
|
|
15111
15445
|
requestInputTokens = Math.max(0, Math.floor(passUsageSnapshot.inputTokens));
|
|
15112
|
-
let preflightError;
|
|
15446
|
+
let preflightError = rawReadError;
|
|
15113
15447
|
let markerAdmissionRecovery = state.markerAdmissionFenced;
|
|
15114
15448
|
try {
|
|
15115
15449
|
markerAdmissionRecovery ||= isRustMarkerAdmissionFenced(deps.db, sessionId);
|
|
@@ -15303,7 +15637,7 @@ function createRustModeTransform(deps, options) {
|
|
|
15303
15637
|
decision,
|
|
15304
15638
|
committed: responseCommitted,
|
|
15305
15639
|
prefixBustPermitted: responsePrefixBustPermitted,
|
|
15306
|
-
reason: materializeReason,
|
|
15640
|
+
reason: applied && served && frozenReleaseReason ? `lkg_frozen_release:${frozenReleaseReason};first_changed=${frozenReleaseFirstChanged};materialize_reason=${materializeReason}` : materializeReason,
|
|
15307
15641
|
schedulerDecision,
|
|
15308
15642
|
schedulerDeferReason,
|
|
15309
15643
|
historianNoFire,
|
|
@@ -15325,7 +15659,7 @@ function createRustModeTransform(deps, options) {
|
|
|
15325
15659
|
materializeReason: materializeReason === "none" ? null : materializeReason,
|
|
15326
15660
|
inputTokens: requestInputTokens,
|
|
15327
15661
|
tsMs: passObservedAtMs,
|
|
15328
|
-
lkgFrozenReleaseReason: applied && served
|
|
15662
|
+
lkgFrozenReleaseReason: applied && served && frozenReleaseReason ? `${frozenReleaseReason};first_changed=${frozenReleaseFirstChanged}` : undefined
|
|
15329
15663
|
});
|
|
15330
15664
|
}
|
|
15331
15665
|
};
|
|
@@ -15360,7 +15694,7 @@ function createRustModeTransform(deps, options) {
|
|
|
15360
15694
|
sessionLog2(sessionId, `rust module stages (slow pass): ${detail}`);
|
|
15361
15695
|
}
|
|
15362
15696
|
};
|
|
15363
|
-
if (state.parked) {
|
|
15697
|
+
if (state.parked && !preflightError) {
|
|
15364
15698
|
state.passesSincePark += 1;
|
|
15365
15699
|
if (!emergencyFailClosed && passUsageSnapshot.percentage < RUST_PARK_PROBE_PRESSURE_BYPASS_PCT && state.passCount % RUST_PARK_RETRY_INTERVAL !== 0) {
|
|
15366
15700
|
decision = "parked";
|
|
@@ -15645,7 +15979,7 @@ function createRustModeTransform(deps, options) {
|
|
|
15645
15979
|
const id = messageIdOf(message) ?? `index:${todoStart + offset}`;
|
|
15646
15980
|
const parts = message.parts?.filter((part) => isRecord4(part) && part.type === "tool" && part.tool === "todowrite");
|
|
15647
15981
|
if (parts?.length) {
|
|
15648
|
-
todoCalls.set(id,
|
|
15982
|
+
todoCalls.set(id, createHash5("sha256").update(JSON.stringify(parts)).digest("hex"));
|
|
15649
15983
|
} else {
|
|
15650
15984
|
todoCalls.delete(id);
|
|
15651
15985
|
}
|
|
@@ -15791,6 +16125,8 @@ function createRustModeTransform(deps, options) {
|
|
|
15791
16125
|
};
|
|
15792
16126
|
let body = buildTransformBody({
|
|
15793
16127
|
sessionId,
|
|
16128
|
+
rawRebuild,
|
|
16129
|
+
servedRawBlockIds: servedRawBlockIds(deps.db, sessionId),
|
|
15794
16130
|
input: encodedInput,
|
|
15795
16131
|
nativeMessages: wireDelta ? messages.slice(wireDelta.rawStart) : messages,
|
|
15796
16132
|
toolInputKeyOrders: toolInputKeyOrders(encodedInput),
|
|
@@ -15990,6 +16326,8 @@ function createRustModeTransform(deps, options) {
|
|
|
15990
16326
|
const retryWireBuildStartedAt = performance.now();
|
|
15991
16327
|
body = buildTransformBody({
|
|
15992
16328
|
sessionId,
|
|
16329
|
+
rawRebuild,
|
|
16330
|
+
servedRawBlockIds: servedRawBlockIds(deps.db, sessionId),
|
|
15993
16331
|
input: retryEncodedInput,
|
|
15994
16332
|
nativeMessages: messages,
|
|
15995
16333
|
toolInputKeyOrders: toolInputKeyOrders(retryEncodedInput),
|
|
@@ -16049,6 +16387,13 @@ function createRustModeTransform(deps, options) {
|
|
|
16049
16387
|
sessionLog2(sessionId, `signed thinking reset fence: ${fenced.length} assistant(s) [${fenced.join(",")}]`);
|
|
16050
16388
|
}
|
|
16051
16389
|
const cacheBustingPass = moduleDecisionBusts;
|
|
16390
|
+
if (rawRebuild?.pending && !moduleDecisionBusts) {
|
|
16391
|
+
throw new EmergencyFailClosedError("Rust raw-rebuild request was not authorized by the module");
|
|
16392
|
+
}
|
|
16393
|
+
if (rawRebuild?.pending) {
|
|
16394
|
+
frozenReleaseReason = `raw_replay_${rawRebuild.reason}`;
|
|
16395
|
+
frozenReleaseFirstChanged = rawRebuild.firstBlockId;
|
|
16396
|
+
}
|
|
16052
16397
|
let frozenReplayReleased = false;
|
|
16053
16398
|
if (markerAdmissionRecovery && !moduleDecisionBusts)
|
|
16054
16399
|
throw new RustTransformProtocolError("rust marker admission recovery: supported prefix_bust_permitted=true required; upgrade ck-mc if unsupported");
|
|
@@ -16080,6 +16425,7 @@ function createRustModeTransform(deps, options) {
|
|
|
16080
16425
|
let appliedMessages = moduleMessages;
|
|
16081
16426
|
let markerStrategyFailure;
|
|
16082
16427
|
let replayedFrozenRepresentation = false;
|
|
16428
|
+
let reconstructedRaw = false;
|
|
16083
16429
|
const boundaryId = response.boundary_id;
|
|
16084
16430
|
if (typeof boundaryId === "string" && boundaryId.length > 0) {
|
|
16085
16431
|
assertNativeBoundary(moduleMessages, sessionId, boundaryId);
|
|
@@ -16124,7 +16470,7 @@ function createRustModeTransform(deps, options) {
|
|
|
16124
16470
|
}
|
|
16125
16471
|
if (recoveryFenceRebuild) {
|
|
16126
16472
|
frozenReplayReleased = true;
|
|
16127
|
-
frozenReleaseReason
|
|
16473
|
+
frozenReleaseReason ??= "lkg_recovery_fence_unproven";
|
|
16128
16474
|
frozenReleaseLastServed = { messages: null, proven: false };
|
|
16129
16475
|
}
|
|
16130
16476
|
if (state.lkgRepresentationFrozen && !shouldAdoptModuleAfterFreeze(moduleDecisionBusts, frozenReplayReleased)) {
|
|
@@ -16189,6 +16535,10 @@ function createRustModeTransform(deps, options) {
|
|
|
16189
16535
|
if (!replayedFrozenRepresentation) {
|
|
16190
16536
|
const outputCloneStartedAt = performance.now();
|
|
16191
16537
|
appliedMessages = cloneModuleNativeOutput(moduleMessages);
|
|
16538
|
+
if (!moduleDecisionBusts || rawRebuild?.pending && rawRebuild.reason.startsWith("candidate")) {
|
|
16539
|
+
const covered = moduleDecisionBusts && typeof response.coverage_ordinal === "number" ? new Set([...state.idOrdinalMemo].filter(([, ordinal]) => ordinal <= Number(response.coverage_ordinal)).map(([id]) => id)) : new Set;
|
|
16540
|
+
reconstructedRaw = preserveRustServedRaw(deps.db, sessionId, appliedMessages, messages, reconstructRaw, covered);
|
|
16541
|
+
}
|
|
16192
16542
|
timings.outputClone += performance.now() - outputCloneStartedAt;
|
|
16193
16543
|
}
|
|
16194
16544
|
pendingWireCache.nativeOutput = moduleMessages;
|
|
@@ -16247,7 +16597,7 @@ function createRustModeTransform(deps, options) {
|
|
|
16247
16597
|
prefixPermissionSupported: permissionSupported,
|
|
16248
16598
|
moduleReasoningTrimOnly: response.reasoning_trim_only === true,
|
|
16249
16599
|
moduleSignedThinkingReset: response.signed_thinking_reset === true,
|
|
16250
|
-
...
|
|
16600
|
+
...moduleDecisionBusts && (passStartedFrozen || frozenReleaseReason || coldStartLastServed) ? { frozenReleaseLastServed } : {},
|
|
16251
16601
|
trailingBlankSourceDecisions,
|
|
16252
16602
|
trailingBlankNewestAssistantId: typeof trailingBlankNewestAssistantId === "string" ? trailingBlankNewestAssistantId : undefined,
|
|
16253
16603
|
tagger: deps.tagger,
|
|
@@ -16258,6 +16608,23 @@ function createRustModeTransform(deps, options) {
|
|
|
16258
16608
|
if (markerStrategyFailure)
|
|
16259
16609
|
throw markerStrategyFailure;
|
|
16260
16610
|
}
|
|
16611
|
+
if (!moduleDecisionBusts && !replayedFrozenRepresentation) {
|
|
16612
|
+
reconstructedRaw = preserveRustServedRaw(deps.db, sessionId, appliedMessages, messages, reconstructRaw) || reconstructedRaw;
|
|
16613
|
+
replayRustModeBindingMismatchStrips({
|
|
16614
|
+
db: deps.db,
|
|
16615
|
+
sessionId,
|
|
16616
|
+
messages: appliedMessages,
|
|
16617
|
+
resolvedProviderID: model?.providerID
|
|
16618
|
+
});
|
|
16619
|
+
if (servedRawBlockIds(deps.db, sessionId).length > 0 && (!validateLkgSeam([], appliedMessages, model?.providerID ?? null) || model?.providerID === "anthropic" && !validateAnthropicReasoningRuns(appliedMessages.map((message) => ({
|
|
16620
|
+
...message,
|
|
16621
|
+
parts: message.parts.filter((part) => !isRecord4(part) || !["text", "reasoning"].includes(String(part.type)) || part.text !== "")
|
|
16622
|
+
}))))) {
|
|
16623
|
+
throw new RustServedRawConflict("candidate_conflict", [
|
|
16624
|
+
...new Set(servedRawBlockIds(deps.db, sessionId).map((id) => id.replace(/#\d+$/, "")))
|
|
16625
|
+
], servedRawBlockIds(deps.db, sessionId)[0] ?? "unknown");
|
|
16626
|
+
}
|
|
16627
|
+
}
|
|
16261
16628
|
if (typeof boundaryId === "string" && boundaryId.length > 0) {
|
|
16262
16629
|
assertNativeBoundary(appliedMessages, sessionId, boundaryId);
|
|
16263
16630
|
}
|
|
@@ -16293,6 +16660,24 @@ function createRustModeTransform(deps, options) {
|
|
|
16293
16660
|
}
|
|
16294
16661
|
}
|
|
16295
16662
|
logStage(sessionId, "apply", applyStartedAt, timings);
|
|
16663
|
+
if (frozenReleaseReason && frozenReleaseLastServed.messages && [...frozenReleaseLastServed.messages, ...appliedMessages].every((message) => isRecord4(message) && isRecord4(message.info) && Array.isArray(message.parts))) {
|
|
16664
|
+
frozenReleaseFirstChanged = "none";
|
|
16665
|
+
const byId = new Map(appliedMessages.map((message) => [message.info.id, message]));
|
|
16666
|
+
for (const before of frozenReleaseLastServed.messages) {
|
|
16667
|
+
const after = byId.get(before.info.id);
|
|
16668
|
+
const index = before.parts.findIndex((part, i) => JSON.stringify(part) !== JSON.stringify(after?.parts[i]));
|
|
16669
|
+
if (!after || index >= 0) {
|
|
16670
|
+
const blockIndex = index > 0 ? encodeOpenCodeMessagesToCk([
|
|
16671
|
+
{ ...before, parts: before.parts.slice(0, index) }
|
|
16672
|
+
])[0].ck.content.length : 0;
|
|
16673
|
+
frozenReleaseFirstChanged = `${before.info.id}#${blockIndex}`;
|
|
16674
|
+
break;
|
|
16675
|
+
}
|
|
16676
|
+
}
|
|
16677
|
+
}
|
|
16678
|
+
if (replayedFrozenRepresentation || reconstructedRaw) {
|
|
16679
|
+
noteRustServedRaw(deps.db, sessionId, messages, appliedMessages);
|
|
16680
|
+
}
|
|
16296
16681
|
const lkgInputIds = messages.map((message) => message.info.id);
|
|
16297
16682
|
const lkgInputKeys = resolveLkgModelKeys(messages);
|
|
16298
16683
|
const applyReplaceStartedAt = performance.now();
|
|
@@ -16550,6 +16935,9 @@ function createRustModeTransform(deps, options) {
|
|
|
16550
16935
|
}
|
|
16551
16936
|
}
|
|
16552
16937
|
}
|
|
16938
|
+
if (moduleDecisionBusts) {
|
|
16939
|
+
releaseRustServedRaw(deps.db, sessionId, output.messages, rawRebuild?.identity);
|
|
16940
|
+
}
|
|
16553
16941
|
} catch (error) {
|
|
16554
16942
|
if (markerDefinitelyNoCut) {
|
|
16555
16943
|
try {
|
|
@@ -16687,7 +17075,12 @@ function createRustModeTransform(deps, options) {
|
|
|
16687
17075
|
const adapter = {
|
|
16688
17076
|
run: async (sessionId, messages, output, sessionMeta) => {
|
|
16689
17077
|
try {
|
|
16690
|
-
await withSqliteTransformPass2(() => run(sessionId, messages, output, sessionMeta));
|
|
17078
|
+
await withReplayEnvelopeSnapshot(deps.db, sessionId, () => withSqliteTransformPass2(() => run(sessionId, messages, output, sessionMeta)));
|
|
17079
|
+
} catch (error) {
|
|
17080
|
+
if (error instanceof RustServedRawConflict) {
|
|
17081
|
+
recordRawConflict(sessionId, error);
|
|
17082
|
+
}
|
|
17083
|
+
throw error;
|
|
16691
17084
|
} finally {
|
|
16692
17085
|
try {
|
|
16693
17086
|
withoutSqliteTransformPass2(() => resolveHostRunner()?.pump(sessionId));
|
|
@@ -18603,6 +18996,114 @@ function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, execu
|
|
|
18603
18996
|
}) / 100) * historyBudgetPercentage);
|
|
18604
18997
|
}
|
|
18605
18998
|
|
|
18999
|
+
// src/shared/recovery-reasoning-prefix.ts
|
|
19000
|
+
function recoveryReasoningPrefixes(messages, partsKey) {
|
|
19001
|
+
const prefixes = [];
|
|
19002
|
+
for (let index = 0;index < messages.length; index++) {
|
|
19003
|
+
const message = messages[index];
|
|
19004
|
+
const parts = message?.[partsKey];
|
|
19005
|
+
if (!Array.isArray(parts))
|
|
19006
|
+
continue;
|
|
19007
|
+
for (let p = 0;p < parts.length; p++) {
|
|
19008
|
+
const type = parts[p]?.type;
|
|
19009
|
+
if (type !== "thinking" && type !== "reasoning" && type !== "redactedThinking" && type !== "redacted_thinking")
|
|
19010
|
+
continue;
|
|
19011
|
+
prefixes.push(JSON.stringify([
|
|
19012
|
+
...messages.slice(0, index),
|
|
19013
|
+
{ ...message, [partsKey]: parts.slice(0, p + 1) }
|
|
19014
|
+
]));
|
|
19015
|
+
}
|
|
19016
|
+
}
|
|
19017
|
+
return prefixes;
|
|
19018
|
+
}
|
|
19019
|
+
|
|
19020
|
+
// src/hooks/magic-context/replay-committed-drops.ts
|
|
19021
|
+
function replayCommittedDrops(db, sessionId, messages) {
|
|
19022
|
+
const original = messages;
|
|
19023
|
+
const reasoningPrefixes = recoveryReasoningPrefixes(messages, "parts");
|
|
19024
|
+
if (reasoningPrefixes.length)
|
|
19025
|
+
messages = structuredClone(messages);
|
|
19026
|
+
const tags = getTagsBySession2(db, sessionId).filter((tag) => tag.status === "dropped");
|
|
19027
|
+
const toolTags = new Map(tags.filter((tag) => tag.type === "tool").map((tag) => [makeToolCompositeKey(tag.toolOwnerMessageId ?? "", tag.messageId), tag]));
|
|
19028
|
+
const textTags = new Map(tags.filter((tag) => tag.type !== "tool").map((tag) => [tag.messageId, tag]));
|
|
19029
|
+
const byNumber = new Map(tags.map((tag) => [tag.tagNumber, tag]));
|
|
19030
|
+
const index = new Map;
|
|
19031
|
+
const owners = new Map;
|
|
19032
|
+
const resolvedOwners = new Map;
|
|
19033
|
+
const ambiguousCalls = new Set;
|
|
19034
|
+
const targets = new Map;
|
|
19035
|
+
let precedingThinking = [];
|
|
19036
|
+
const toolThinking = new Map;
|
|
19037
|
+
const batch = new ToolMutationBatch(messages);
|
|
19038
|
+
for (const message of messages) {
|
|
19039
|
+
if (message.info.role === "user")
|
|
19040
|
+
precedingThinking = [];
|
|
19041
|
+
const thinking = message.parts.filter(isThinkingPart);
|
|
19042
|
+
for (let p = 0;p < message.parts.length; p++) {
|
|
19043
|
+
const part = message.parts[p];
|
|
19044
|
+
const observation = extractToolCallObservation(part);
|
|
19045
|
+
if (observation) {
|
|
19046
|
+
const { callId, kind } = observation;
|
|
19047
|
+
const pending = owners.get(callId) ?? [];
|
|
19048
|
+
if (pending.length > 1)
|
|
19049
|
+
ambiguousCalls.add(callId);
|
|
19050
|
+
const hostingKey = makeToolCompositeKey(message.info.id ?? "", callId);
|
|
19051
|
+
const owner = kind === "invocation" || part.type === "tool" || toolTags.has(hostingKey) ? message.info.id ?? "" : pending.shift() ?? resolvedOwners.get(callId) ?? message.info.id ?? "";
|
|
19052
|
+
if (kind === "invocation")
|
|
19053
|
+
pending.push(owner);
|
|
19054
|
+
else
|
|
19055
|
+
resolvedOwners.set(callId, owner);
|
|
19056
|
+
owners.set(callId, pending);
|
|
19057
|
+
const key = makeToolCompositeKey(owner, callId);
|
|
19058
|
+
if (message.info.role === "tool" && !toolThinking.has(key))
|
|
19059
|
+
toolThinking.set(key, precedingThinking);
|
|
19060
|
+
const entry = index.get(key) ?? { occurrences: [], hasResult: false };
|
|
19061
|
+
entry.occurrences.push({ message, part, kind });
|
|
19062
|
+
entry.hasResult ||= kind === "result" && partHasCompletedResult(part);
|
|
19063
|
+
index.set(key, entry);
|
|
19064
|
+
} else {
|
|
19065
|
+
const prefix = isTextPart(part) ? /^§(\d+)§\s/.exec(part.text) : null;
|
|
19066
|
+
const tag = (prefix ? byNumber.get(Number(prefix[1])) : undefined) ?? textTags.get(`${message.info.id}:p${p}`) ?? textTags.get(`${message.info.id}:file${p}`);
|
|
19067
|
+
if (tag && tag.type !== "tool")
|
|
19068
|
+
targets.set(tag.tagNumber, {
|
|
19069
|
+
message,
|
|
19070
|
+
setContent(content) {
|
|
19071
|
+
if (isTextPart(part)) {
|
|
19072
|
+
if (part.text === content)
|
|
19073
|
+
return false;
|
|
19074
|
+
part.text = content;
|
|
19075
|
+
} else
|
|
19076
|
+
message.parts[p] = { type: "text", text: content };
|
|
19077
|
+
return true;
|
|
19078
|
+
}
|
|
19079
|
+
});
|
|
19080
|
+
}
|
|
19081
|
+
}
|
|
19082
|
+
if (message.info.role === "assistant" && !message.parts.some(isTextPart))
|
|
19083
|
+
precedingThinking = thinking;
|
|
19084
|
+
}
|
|
19085
|
+
const arcsByCall = new Map;
|
|
19086
|
+
for (const entry of index.values()) {
|
|
19087
|
+
const callId = extractToolCallObservation(entry.occurrences[0]?.part)?.callId ?? "";
|
|
19088
|
+
arcsByCall.set(callId, (arcsByCall.get(callId) ?? 0) + 1);
|
|
19089
|
+
}
|
|
19090
|
+
for (const [key, entry] of index) {
|
|
19091
|
+
const callId = extractToolCallObservation(entry.occurrences[0]?.part)?.callId ?? "";
|
|
19092
|
+
if (ambiguousCalls.has(callId))
|
|
19093
|
+
continue;
|
|
19094
|
+
const tag = toolTags.get(key) ?? (arcsByCall.get(callId) === 1 ? toolTags.get(makeToolCompositeKey("", callId)) : undefined);
|
|
19095
|
+
if (tag)
|
|
19096
|
+
targets.set(tag.tagNumber, createToolDropTarget(key, toolThinking.get(key) ?? [], index, batch, tag.tagNumber));
|
|
19097
|
+
}
|
|
19098
|
+
applyFlushedStatuses(sessionId, db, targets, tags);
|
|
19099
|
+
batch.finalize();
|
|
19100
|
+
if (JSON.stringify(recoveryReasoningPrefixes(messages, "parts")) !== JSON.stringify(reasoningPrefixes))
|
|
19101
|
+
return false;
|
|
19102
|
+
if (messages !== original)
|
|
19103
|
+
original.splice(0, original.length, ...messages);
|
|
19104
|
+
return true;
|
|
19105
|
+
}
|
|
19106
|
+
|
|
18606
19107
|
// src/plugin/messages-transform.ts
|
|
18607
19108
|
var ASSISTANT_TERMINAL_RETRY_MESSAGE = "The conversation ends with a completed assistant response and cannot be resubmitted as-is — send a new message to continue.";
|
|
18608
19109
|
|
|
@@ -18745,7 +19246,6 @@ function tryMessagesTransformLkgReplay(args) {
|
|
|
18745
19246
|
sessionLog2(sessionId, "lkg_emergency_armed");
|
|
18746
19247
|
} else {
|
|
18747
19248
|
const inputMessages = output.messages;
|
|
18748
|
-
const inputCount = inputMessages.length;
|
|
18749
19249
|
const keys = resolveLkgModelKeys(inputMessages);
|
|
18750
19250
|
const replay = replayLkg({
|
|
18751
19251
|
sessionId,
|
|
@@ -18764,6 +19264,10 @@ function tryMessagesTransformLkgReplay(args) {
|
|
|
18764
19264
|
sessionLog2(sessionId, "lkg_restart_rebuild_required");
|
|
18765
19265
|
return false;
|
|
18766
19266
|
}
|
|
19267
|
+
if (replay.ok && !rust && !replayCommittedDrops(db, sessionId, replay.messages)) {
|
|
19268
|
+
sessionLog2(sessionId, "lkg_reasoning_prefix_changed");
|
|
19269
|
+
return false;
|
|
19270
|
+
}
|
|
18767
19271
|
let tsFit = true;
|
|
18768
19272
|
if (replay.ok && !rust && keys.providerKey && keys.modelKey) {
|
|
18769
19273
|
const model = {
|
|
@@ -18813,8 +19317,8 @@ function tryMessagesTransformLkgReplay(args) {
|
|
|
18813
19317
|
return false;
|
|
18814
19318
|
retirePendingSystemPromptDelivery(sessionId);
|
|
18815
19319
|
args.onLkgReplay?.();
|
|
19320
|
+
noteExternalLkgReplay(rust, sessionId, inputMessages, replay.messages);
|
|
18816
19321
|
replaceMessagesInPlace2(output, replay.messages);
|
|
18817
|
-
noteExternalLkgReplay(rust, sessionId, inputCount);
|
|
18818
19322
|
sessionLog2(sessionId, "lkg_replay_served");
|
|
18819
19323
|
return true;
|
|
18820
19324
|
} else {
|
|
@@ -20124,7 +20628,7 @@ function computeOpenCodeWorkMetricsIncremental(openCodeDb, sessionId, carry) {
|
|
|
20124
20628
|
import { readFileSync, statSync } from "node:fs";
|
|
20125
20629
|
|
|
20126
20630
|
// src/plugin/embedding-bootstrap-helpers.ts
|
|
20127
|
-
import { createHash as
|
|
20631
|
+
import { createHash as createHash6 } from "node:crypto";
|
|
20128
20632
|
var EMBEDDING_AFFECTING_KEYS = new Set([
|
|
20129
20633
|
"embedding.api_key",
|
|
20130
20634
|
"embedding.endpoint",
|
|
@@ -20172,7 +20676,7 @@ var EMBEDDING_WARNING_TERMS = [
|
|
|
20172
20676
|
];
|
|
20173
20677
|
var loggedFailureSignatures = new Map;
|
|
20174
20678
|
function sha256Prefix(value, length = 16) {
|
|
20175
|
-
return
|
|
20679
|
+
return createHash6("sha256").update(value).digest("hex").slice(0, length);
|
|
20176
20680
|
}
|
|
20177
20681
|
function warningLooksEmbeddingRelated(message) {
|
|
20178
20682
|
const lower = message.toLowerCase();
|
|
@@ -21662,8 +22166,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
21662
22166
|
const db = readDatabase();
|
|
21663
22167
|
if (!db)
|
|
21664
22168
|
return { ok: false, error: "db unavailable" };
|
|
21665
|
-
const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-
|
|
21666
|
-
const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-
|
|
22169
|
+
const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-n11zv1f1.js"));
|
|
22170
|
+
const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-ppgc8qdz.js"));
|
|
21667
22171
|
log2(`[rpc] recomp requested for session ${sessionId}`);
|
|
21668
22172
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
21669
22173
|
return {
|
|
@@ -21732,7 +22236,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
21732
22236
|
const db = readDatabase();
|
|
21733
22237
|
if (!db)
|
|
21734
22238
|
return { ok: false, error: "db unavailable" };
|
|
21735
|
-
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-
|
|
22239
|
+
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-s92ebfzv.js"));
|
|
21736
22240
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
21737
22241
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
21738
22242
|
const ctx = {
|
|
@@ -22721,8 +23225,8 @@ function hostMediaFromEncoded(value) {
|
|
|
22721
23225
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
22722
23226
|
|
|
22723
23227
|
// src/v2/fold/owner.ts
|
|
22724
|
-
import { createHash as
|
|
22725
|
-
var foldDigest = (value) =>
|
|
23228
|
+
import { createHash as createHash7 } from "node:crypto";
|
|
23229
|
+
var foldDigest = (value) => createHash7("sha256").update(value).digest("hex");
|
|
22726
23230
|
|
|
22727
23231
|
class FoldOwner {
|
|
22728
23232
|
storage;
|
|
@@ -23063,12 +23567,12 @@ function placeCacheHint(content, hint) {
|
|
|
23063
23567
|
const index = lastText >= 0 ? lastText : content.length - 1;
|
|
23064
23568
|
content[index] = { ...content[index], cache: hint };
|
|
23065
23569
|
}
|
|
23066
|
-
function removeEmptyTextParts(content, rendered) {
|
|
23570
|
+
function removeEmptyTextParts(content, rendered, mayRemove) {
|
|
23067
23571
|
let hint;
|
|
23068
23572
|
let removed = 0;
|
|
23069
23573
|
for (let index = content.length - 1;index >= 0; index -= 1) {
|
|
23070
23574
|
const part = content[index];
|
|
23071
|
-
if (part?.type !== "text" || part.text !== "")
|
|
23575
|
+
if (part?.type !== "text" || part.text !== "" || !mayRemove(part))
|
|
23072
23576
|
continue;
|
|
23073
23577
|
if (hint === undefined)
|
|
23074
23578
|
hint = part.cache;
|
|
@@ -23144,12 +23648,14 @@ function contentValueAttachments(value) {
|
|
|
23144
23648
|
...typeof item.name === "string" ? { filename: item.name } : {}
|
|
23145
23649
|
}));
|
|
23146
23650
|
}
|
|
23147
|
-
function rebuildFileContent(value, output) {
|
|
23651
|
+
function rebuildFileContent(value, output, attachments) {
|
|
23148
23652
|
if (isDroppedToolOutput(output))
|
|
23149
23653
|
return { type: "text", value: output };
|
|
23150
23654
|
const rebuilt = [];
|
|
23151
23655
|
let placed = false;
|
|
23152
23656
|
for (const item of value) {
|
|
23657
|
+
if (item?.type === "file" && Array.isArray(attachments) && !attachments.some((attachment) => attachment?.url === item.uri && attachment?.mime === item.mime))
|
|
23658
|
+
continue;
|
|
23153
23659
|
if (item?.type !== "text") {
|
|
23154
23660
|
rebuilt.push(item);
|
|
23155
23661
|
continue;
|
|
@@ -23292,14 +23798,16 @@ function adaptPayload(draft, admittedIDs = new Set) {
|
|
|
23292
23798
|
let head = 0;
|
|
23293
23799
|
const rendered = [];
|
|
23294
23800
|
const emptyTextGuard = modelAcceptsEmptyContent(draft.model.providerID);
|
|
23801
|
+
const imageOmissions = getEmptyImageParts(messages);
|
|
23295
23802
|
let omitted = 0;
|
|
23296
23803
|
let emptyTextParts = 0;
|
|
23297
23804
|
for (const message of messages) {
|
|
23298
23805
|
const original = originals.get(message) ?? (typeof message.info.id === "string" ? originalsByID.get(message.info.id) : undefined);
|
|
23299
23806
|
const id = message.info.syntheticHead ? HEAD_IDS[head++] : original?.id;
|
|
23300
23807
|
const content = [];
|
|
23808
|
+
const emptyImages = new Set;
|
|
23301
23809
|
const following = [];
|
|
23302
|
-
for (const candidate of message.parts) {
|
|
23810
|
+
for (const [partIndex, candidate] of message.parts.entries()) {
|
|
23303
23811
|
const part = candidate;
|
|
23304
23812
|
const bridge = bridges.get(part) ?? (part.type === "tool" && typeof part.callID === "string" ? bridgesFor(message)?.get(part.callID) : undefined);
|
|
23305
23813
|
if (!bridge) {
|
|
@@ -23355,7 +23863,10 @@ function adaptPayload(draft, admittedIDs = new Set) {
|
|
|
23355
23863
|
}
|
|
23356
23864
|
const { synthetic: _synthetic, ...clean } = part;
|
|
23357
23865
|
const original = hostPartTypes.has(clean.type) && !containsHostInstance(clean) ? hostParts.get(contentKey(clean)) : undefined;
|
|
23358
|
-
|
|
23866
|
+
const projected = original ?? clean;
|
|
23867
|
+
if (imageOmissions.get(message.info.id ?? "")?.has(partIndex))
|
|
23868
|
+
emptyImages.add(projected);
|
|
23869
|
+
content.push(projected);
|
|
23359
23870
|
continue;
|
|
23360
23871
|
}
|
|
23361
23872
|
const state = part.state;
|
|
@@ -23387,7 +23898,7 @@ function adaptPayload(draft, admittedIDs = new Set) {
|
|
|
23387
23898
|
if (bridge.result && bridge.resultMessage) {
|
|
23388
23899
|
const result = {
|
|
23389
23900
|
...bridge.result,
|
|
23390
|
-
result: state.output === bridge.output ? bridge.result.result : bridge.files && typeof state.output === "string" ? rebuildFileContent(bridge.files, state.output) : {
|
|
23901
|
+
result: state.output === bridge.output ? bridge.result.result : bridge.files && typeof state.output === "string" ? rebuildFileContent(bridge.files, state.output, state.attachments) : {
|
|
23391
23902
|
type: state.status === "error" ? "error" : "text",
|
|
23392
23903
|
value: state.output
|
|
23393
23904
|
}
|
|
@@ -23398,7 +23909,7 @@ function adaptPayload(draft, admittedIDs = new Set) {
|
|
|
23398
23909
|
following.push({ ...bridge.resultMessage, content: [result] });
|
|
23399
23910
|
}
|
|
23400
23911
|
}
|
|
23401
|
-
const guarded =
|
|
23912
|
+
const guarded = removeEmptyTextParts(content, rendered, (part) => emptyTextGuard || emptyImages.has(part));
|
|
23402
23913
|
if (content.length || !original?.content.length && guarded === 0) {
|
|
23403
23914
|
const value = {
|
|
23404
23915
|
...original,
|
|
@@ -23408,7 +23919,7 @@ function adaptPayload(draft, admittedIDs = new Set) {
|
|
|
23408
23919
|
};
|
|
23409
23920
|
const existing = id ? existingHeads.get(id) : undefined;
|
|
23410
23921
|
rendered.push(existing ? Object.assign(existing, { content }) : value);
|
|
23411
|
-
} else if (emptyTextGuard) {
|
|
23922
|
+
} else if (emptyTextGuard || guarded > 0) {
|
|
23412
23923
|
omitted += 1;
|
|
23413
23924
|
}
|
|
23414
23925
|
emptyTextParts += guarded;
|
|
@@ -23416,7 +23927,7 @@ function adaptPayload(draft, admittedIDs = new Set) {
|
|
|
23416
23927
|
}
|
|
23417
23928
|
if (omitted + emptyTextParts > 0 && !emptyTextOmissionLogged.has(draft.sessionID)) {
|
|
23418
23929
|
emptyTextOmissionLogged.add(draft.sessionID);
|
|
23419
|
-
sessionLog2(draft.sessionID, `v2 payload: left out ${omitted} emptied messages and ${emptyTextParts} empty text parts, because Anthropic rejects an empty text block (logged once per session)`);
|
|
23930
|
+
sessionLog2(draft.sessionID, `v2 payload: left out ${omitted} emptied messages and ${emptyTextParts} empty text parts, ${emptyTextGuard ? "because Anthropic rejects an empty text block" : "to replay frozen image omissions"} (logged once per session)`);
|
|
23420
23931
|
}
|
|
23421
23932
|
draft.messages.splice(0, draft.messages.length, ...rendered);
|
|
23422
23933
|
}
|
|
@@ -25316,11 +25827,11 @@ class DeletedSessionTombstones {
|
|
|
25316
25827
|
}
|
|
25317
25828
|
|
|
25318
25829
|
// src/features/magic-context/dreamer/task-executor.ts
|
|
25319
|
-
import { createHash as
|
|
25830
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
25320
25831
|
import { existsSync as existsSync7, readFileSync as readFileSync8 } from "node:fs";
|
|
25321
25832
|
|
|
25322
25833
|
// src/features/magic-context/mural/compress-cues.ts
|
|
25323
|
-
import { createHash as
|
|
25834
|
+
import { createHash as createHash8 } from "node:crypto";
|
|
25324
25835
|
|
|
25325
25836
|
// src/features/magic-context/dreamer/storage-dream-state.ts
|
|
25326
25837
|
var getDreamStateStatements = new WeakMap;
|
|
@@ -26050,7 +26561,7 @@ async function applyCuesThroughModule(args, chunk, manifestText, signal) {
|
|
|
26050
26561
|
log2(`[dreamer] compress-cues: skipped cue for memory ${entry.id} (${failure.reason}; rejection ${rejectionCount}/${CUE_REJECTION_LATCH_THRESHOLD})`);
|
|
26051
26562
|
}
|
|
26052
26563
|
}
|
|
26053
|
-
const commandId = `mural-cues:${route.moduleCommandId}:${
|
|
26564
|
+
const commandId = `mural-cues:${route.moduleCommandId}:${createHash8("sha256").update(chunk.map((candidate) => candidate.memory.id).join(",")).digest("hex").slice(0, 24)}`;
|
|
26054
26565
|
let response;
|
|
26055
26566
|
try {
|
|
26056
26567
|
response = await route.moduleClient.call({
|
|
@@ -26149,6 +26660,25 @@ async function runHiddenSingleShotPrompt(args) {
|
|
|
26149
26660
|
});
|
|
26150
26661
|
promptSettled = true;
|
|
26151
26662
|
return { validated: run.validated, completion: run.output, childSessionId: handle.id };
|
|
26663
|
+
} catch (error) {
|
|
26664
|
+
if (args.onFailureOutput) {
|
|
26665
|
+
let timer;
|
|
26666
|
+
try {
|
|
26667
|
+
const completion = await Promise.race([
|
|
26668
|
+
args.executor.collect(handle, 200),
|
|
26669
|
+
new Promise((resolve) => {
|
|
26670
|
+
timer = setTimeout(() => resolve(null), 5000);
|
|
26671
|
+
})
|
|
26672
|
+
]);
|
|
26673
|
+
if (completion)
|
|
26674
|
+
args.onFailureOutput(completion);
|
|
26675
|
+
} catch (readError) {
|
|
26676
|
+
log2(`${args.callContext}: failed to collect interrupted output: ${String(readError)}`);
|
|
26677
|
+
} finally {
|
|
26678
|
+
clearTimeout(timer);
|
|
26679
|
+
}
|
|
26680
|
+
}
|
|
26681
|
+
throw error;
|
|
26152
26682
|
} finally {
|
|
26153
26683
|
await args.executor.close(handle, {
|
|
26154
26684
|
promptSettled,
|
|
@@ -26619,7 +27149,7 @@ function applyReviewVerdict(args, leaseKey, parsed, result) {
|
|
|
26619
27149
|
}
|
|
26620
27150
|
|
|
26621
27151
|
// src/features/magic-context/dreamer/classify.ts
|
|
26622
|
-
import { createHash as
|
|
27152
|
+
import { createHash as createHash9 } from "node:crypto";
|
|
26623
27153
|
|
|
26624
27154
|
// src/plugin/rust-tool-backends.ts
|
|
26625
27155
|
function isRustAuthorityDrainingError(error) {
|
|
@@ -27056,7 +27586,7 @@ async function runClassifyThroughModule(args, chunk, anchors, signal, runOnHost)
|
|
|
27056
27586
|
if (entry.qualifier)
|
|
27057
27587
|
modelVariants[entry.model] = entry.qualifier;
|
|
27058
27588
|
}
|
|
27059
|
-
const commandId = `classify:${args.moduleCommandId ?? Date.now()}:${
|
|
27589
|
+
const commandId = `classify:${args.moduleCommandId ?? Date.now()}:${createHash9("sha256").update(chunk.map((candidate) => candidate.id).join(",")).digest("hex").slice(0, 24)}`;
|
|
27060
27590
|
const runTask = (hostCompletion) => args.moduleClient?.call({
|
|
27061
27591
|
sessionId: args.moduleSessionId,
|
|
27062
27592
|
projectRoot: args.moduleProjectRoot,
|
|
@@ -27331,7 +27861,7 @@ function takeCurateSafetyRefusalCount(sessionId) {
|
|
|
27331
27861
|
|
|
27332
27862
|
// src/features/magic-context/dreamer/docs-proposals.ts
|
|
27333
27863
|
import { execFileSync } from "node:child_process";
|
|
27334
|
-
import { createHash as
|
|
27864
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
27335
27865
|
import {
|
|
27336
27866
|
existsSync as existsSync4,
|
|
27337
27867
|
mkdirSync,
|
|
@@ -27346,7 +27876,7 @@ import {
|
|
|
27346
27876
|
import { tmpdir } from "node:os";
|
|
27347
27877
|
import { join as join7 } from "node:path";
|
|
27348
27878
|
var FILES = ["ARCHITECTURE.md", "STRUCTURE.md"];
|
|
27349
|
-
var hash = (text) =>
|
|
27879
|
+
var hash = (text) => createHash10("sha256").update(text).digest("hex");
|
|
27350
27880
|
var proposalDir = (projectDir) => join7(projectDir, ".cortexkit/magic-context/docs-update-proposals");
|
|
27351
27881
|
function docsBaseHashes(projectDir) {
|
|
27352
27882
|
return Object.fromEntries(FILES.map((name) => [
|
|
@@ -27882,7 +28412,7 @@ function throwIfAborted2(signal) {
|
|
|
27882
28412
|
}
|
|
27883
28413
|
|
|
27884
28414
|
// src/features/magic-context/smart-notes/compiler.ts
|
|
27885
|
-
import { createHash as
|
|
28415
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
27886
28416
|
|
|
27887
28417
|
// src/features/magic-context/smart-notes/compiler-prompt.ts
|
|
27888
28418
|
var SMART_NOTE_COMPILER_SYSTEM_PROMPT = `You are the Magic Context smart-note compiler for the magic-context system.
|
|
@@ -28213,7 +28743,7 @@ function manifestAdvisoryWarnings(code, manifest) {
|
|
|
28213
28743
|
return warnings;
|
|
28214
28744
|
}
|
|
28215
28745
|
function hashCheck(surfaceCondition, compiledCheck, manifest, checkCron) {
|
|
28216
|
-
return
|
|
28746
|
+
return createHash11("sha256").update(surfaceCondition ?? "").update("\x00").update(compiledCheck).update("\x00").update(JSON.stringify(manifest)).update("\x00").update(checkCron).digest("hex");
|
|
28217
28747
|
}
|
|
28218
28748
|
function extractJsonObject(output) {
|
|
28219
28749
|
const fenced = output.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
@@ -28979,34 +29509,36 @@ function snapshotMaintainDocsFiles(docsDir) {
|
|
|
28979
29509
|
}
|
|
28980
29510
|
|
|
28981
29511
|
// src/features/magic-context/dreamer/map-memories.ts
|
|
28982
|
-
import { createHash as
|
|
29512
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
28983
29513
|
|
|
28984
29514
|
// src/features/magic-context/dreamer/map-memories-prompt.ts
|
|
29515
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
28985
29516
|
import { existsSync as existsSync6, statSync as statSync3 } from "node:fs";
|
|
28986
29517
|
import path4 from "node:path";
|
|
29518
|
+
import { promisify as promisify2 } from "node:util";
|
|
28987
29519
|
var MAP_MEMORIES_SYSTEM_PROMPT = `You are a memory mapper for the magic-context system. You map project memories to the repository files that back them.
|
|
28988
29520
|
|
|
28989
29521
|
A memory's BACKING FILES are the file(s) whose code the memory makes a claim about — the files you would open to check whether the memory is accurate. You do NOT judge accuracy, rewrite, or remove anything. You only LOCATE backing files.
|
|
28990
29522
|
|
|
28991
|
-
Tools (read-only): read, grep, glob.
|
|
29523
|
+
Tools (read-only): read, grep, glob. Use at most 3 tool calls per memory, including searches and reads. Never read the same file twice in a batch; reuse what you already learned. Never repeat an identical search or use broad searches such as "fn " or ".*". Request one useful line range, not repeated slices. Each memory may come with "Likely files" from paths it names or a literal identifier search, confirmed to exist — confirm those FIRST (cheap) instead of searching. Use search/grep to FIND code only when no likely files are given. Do not guess — confirm a file exists and genuinely backs the memory before listing it. You are locating code, not exhaustively verifying the claim. If the call budget runs out before you can decide, leave that id unmapped and move on; uncertainty is not evidence of file-independence.
|
|
28992
29524
|
|
|
28993
29525
|
For each memory decide ONE of:
|
|
28994
|
-
- Backing files found → the
|
|
29526
|
+
- Backing files found → the specific repo-relative paths whose code the memory is about; do not chase every caller or related implementation.
|
|
28995
29527
|
- File-independent → the memory describes EXTERNAL behavior (a provider / API / platform / protocol limit, e.g. "Anthropic returns 400 on empty content"), or a pure process / workflow / philosophy rule, with NO specific local file that backs it. A BEHAVIORAL claim (when to act, how to work, who decides, or tool-usage discipline) is file-independent even when it cites file paths or commands as examples: a named file is not the file backing the rule.
|
|
28996
29528
|
|
|
28997
|
-
Output ONE XML manifest
|
|
29529
|
+
Output ONE XML manifest and NOTHING else — no narration, no per-memory commentary, no reasoning. Open <mappings> before investigating. Emit each <memory> element as soon as you decide its mapping, before investigating the next memory, so an interruption cannot lose completed work. Close </mappings> when finished:
|
|
28998
29530
|
<mappings>
|
|
28999
29531
|
<memory id="N" files="path/a.ts,path/b.ts"/>
|
|
29000
29532
|
<memory id="M" independent="true"/>
|
|
29001
29533
|
</mappings>
|
|
29002
29534
|
|
|
29003
29535
|
Rules:
|
|
29004
|
-
- Every input memory id MUST appear exactly once.
|
|
29536
|
+
- Every decided input memory id MUST appear exactly once. Omit uncertain ids rather than inventing backing files or declaring them independent.
|
|
29005
29537
|
- files: repo-relative, comma-separated, no spaces inside a path. Only files that actually exist and genuinely back the memory.
|
|
29006
29538
|
- A BACKING FILE is CODE that implements or handles the claim — not a file that merely mentions it. A path named inside a process directive is an action target or example, not evidence that the file backs the directive. A markdown doc (.md), a PARITY/notes file, or a test that only DESCRIBES an external fact is NOT a backing file. If the only place a memory's fact appears is prose/docs/a test (no code implements or handles it), mark it independent="true".
|
|
29007
29539
|
- Many CONSTRAINTS are HYBRID: "external system does X, and OUR code handles it here." Map those to the HANDLING code (you can verify the handling, even though you can't verify the external behavior). Only mark independent when there is NO local code that implements or handles the fact.
|
|
29008
29540
|
- Prefer the most specific file(s); do not pad with tangential files. Most memories map to one file; some to a few.
|
|
29009
|
-
-
|
|
29541
|
+
- Mark independent="true" only for the file-independent cases above; an investigation that runs out of calls stays unmapped.`;
|
|
29010
29542
|
var MAX_SEED_PATHS_PER_MEMORY = 3;
|
|
29011
29543
|
var PATH_PATTERN = "`?((?:[\\w.-]+\\/)+[\\w.-]+\\.(?:ts|tsx|js|jsx|mjs|cjs|rs|go|py|json|jsonc|sql|toml|sh))`?";
|
|
29012
29544
|
function extractMemoryCandidatePaths(content, repoDir) {
|
|
@@ -29028,10 +29560,65 @@ function extractMemoryCandidatePaths(content, repoDir) {
|
|
|
29028
29560
|
}
|
|
29029
29561
|
return [...found];
|
|
29030
29562
|
}
|
|
29563
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
29564
|
+
async function seedIdentifierCandidates(memories, repoDir) {
|
|
29565
|
+
const identifiers = new Map(memories.filter((memory) => memory.candidates.length === 0).map((memory) => [
|
|
29566
|
+
memory.id,
|
|
29567
|
+
[
|
|
29568
|
+
...new Set(memory.content.match(/\b(?:[A-Z][A-Za-z0-9_]{3,}|[a-z][a-z0-9]*[A-Z][A-Za-z0-9_]*|[a-z][a-z0-9]*_[A-Za-z0-9_]{2,})\b/g) ?? [])
|
|
29569
|
+
].slice(0, 3)
|
|
29570
|
+
]));
|
|
29571
|
+
const terms = [...new Set([...identifiers.values()].flat())];
|
|
29572
|
+
if (terms.length === 0)
|
|
29573
|
+
return memories;
|
|
29574
|
+
let stdout;
|
|
29575
|
+
try {
|
|
29576
|
+
const result = await execFileAsync2("git", [
|
|
29577
|
+
"-c",
|
|
29578
|
+
"core.quotePath=false",
|
|
29579
|
+
"grep",
|
|
29580
|
+
"--no-color",
|
|
29581
|
+
"-n",
|
|
29582
|
+
"-I",
|
|
29583
|
+
"-F",
|
|
29584
|
+
...terms.flatMap((term) => ["-e", term]),
|
|
29585
|
+
"--",
|
|
29586
|
+
...["ts", "tsx", "js", "jsx", "mjs", "cjs", "rs", "go", "py", "sql", "sh"].map((extension) => `*.${extension}`)
|
|
29587
|
+
], {
|
|
29588
|
+
cwd: repoDir,
|
|
29589
|
+
encoding: "utf8",
|
|
29590
|
+
timeout: 2000,
|
|
29591
|
+
maxBuffer: 256 * 1024,
|
|
29592
|
+
windowsHide: true,
|
|
29593
|
+
killSignal: "SIGKILL"
|
|
29594
|
+
});
|
|
29595
|
+
stdout = result.stdout;
|
|
29596
|
+
} catch {
|
|
29597
|
+
return memories;
|
|
29598
|
+
}
|
|
29599
|
+
const matches = stdout.split(`
|
|
29600
|
+
`).flatMap((line) => {
|
|
29601
|
+
const match = line.match(/^([^:]+):\d+:(.*)$/);
|
|
29602
|
+
return match ? [{ file: match[1], text: match[2] }] : [];
|
|
29603
|
+
});
|
|
29604
|
+
return memories.map((memory) => {
|
|
29605
|
+
const names = identifiers.get(memory.id);
|
|
29606
|
+
if (!names?.length)
|
|
29607
|
+
return memory;
|
|
29608
|
+
const files = new Map;
|
|
29609
|
+
for (const match of matches) {
|
|
29610
|
+
const score = names.filter((name) => match.text.includes(name)).length;
|
|
29611
|
+
if (score)
|
|
29612
|
+
files.set(match.file, Math.max(files.get(match.file) ?? 0, score));
|
|
29613
|
+
}
|
|
29614
|
+
const candidates = [...files].sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0])).slice(0, MAX_SEED_PATHS_PER_MEMORY).map(([file]) => file);
|
|
29615
|
+
return candidates.length ? { ...memory, candidates } : memory;
|
|
29616
|
+
});
|
|
29617
|
+
}
|
|
29031
29618
|
function buildMapMemoriesPrompt(projectPath, memories) {
|
|
29032
29619
|
const list = memories.map((m) => {
|
|
29033
29620
|
const seed = m.candidates.length ? `
|
|
29034
|
-
Likely files (
|
|
29621
|
+
Likely files (candidate paths, confirmed to exist): ${m.candidates.join(", ")}` : "";
|
|
29035
29622
|
return `[${m.id}] ${m.category}
|
|
29036
29623
|
${m.content}${seed}`;
|
|
29037
29624
|
}).join(`
|
|
@@ -29041,13 +29628,13 @@ ${m.content}${seed}`;
|
|
|
29041
29628
|
|
|
29042
29629
|
Project: ${projectPath}
|
|
29043
29630
|
|
|
29044
|
-
For each memory below, find the repo file(s) it makes a claim about, or mark it file-independent. Behavioral process/workflow directives stay file-independent even when they name files. When "Likely files" are listed, those paths
|
|
29631
|
+
For each memory below, find the repo file(s) it makes a claim about, or mark it file-independent. Behavioral process/workflow directives stay file-independent even when they name files. When "Likely files" are listed, those paths either occur in the memory or match its identifiers in a bounded literal source search — START there only for code claims: confirm each actually backs the claim (a quick read/outline), drop any that don't, add others only if genuinely needed. Search from scratch only when no likely files are given. Use at most 3 tool calls per memory, reuse prior reads, and emit each decided mapping immediately in ONE <mappings> manifest. Leave uncertain ids unmapped and move on.
|
|
29045
29632
|
|
|
29046
29633
|
<memories>
|
|
29047
29634
|
${list}
|
|
29048
29635
|
</memories>`;
|
|
29049
29636
|
}
|
|
29050
|
-
var MEMORY_ELEMENT_PATTERN = "<memory\\b([
|
|
29637
|
+
var MEMORY_ELEMENT_PATTERN = "<memory\\b([^<>]*)(?:\\/>|>([\\s\\S]*?)<\\/memory>)";
|
|
29051
29638
|
var NESTED_FILE_PATTERN = "<file\\b([^>]*)\\/?>";
|
|
29052
29639
|
function extractNestedFilePaths(inner) {
|
|
29053
29640
|
const files = [];
|
|
@@ -29105,12 +29692,78 @@ function validateMapMemoriesManifest(text, expectedIds) {
|
|
|
29105
29692
|
assertNoDuplicateManifestIds(parsed.filter((entry) => expectedIds.has(entry.id)).map((entry) => entry.id), "mappings");
|
|
29106
29693
|
return parsed;
|
|
29107
29694
|
}
|
|
29695
|
+
function parsePartialMapMemoriesManifest(text, expectedIds) {
|
|
29696
|
+
const start = text.indexOf("<mappings>");
|
|
29697
|
+
if (start < 0)
|
|
29698
|
+
return [];
|
|
29699
|
+
const entries = new Map;
|
|
29700
|
+
const conflicts = new Set;
|
|
29701
|
+
for (const match of text.slice(start).matchAll(new RegExp(MEMORY_ELEMENT_PATTERN, "gi"))) {
|
|
29702
|
+
try {
|
|
29703
|
+
const entry = parseMapMemoriesManifest(`<mappings>${match[0]}</mappings>`)[0];
|
|
29704
|
+
if (!entry || !expectedIds.has(entry.id) || conflicts.has(entry.id))
|
|
29705
|
+
continue;
|
|
29706
|
+
const previous = entries.get(entry.id);
|
|
29707
|
+
if (previous && JSON.stringify(previous) !== JSON.stringify(entry)) {
|
|
29708
|
+
entries.delete(entry.id);
|
|
29709
|
+
conflicts.add(entry.id);
|
|
29710
|
+
} else {
|
|
29711
|
+
entries.set(entry.id, entry);
|
|
29712
|
+
}
|
|
29713
|
+
} catch {}
|
|
29714
|
+
}
|
|
29715
|
+
return [...entries.values()];
|
|
29716
|
+
}
|
|
29108
29717
|
|
|
29109
29718
|
// src/features/magic-context/dreamer/map-memories.ts
|
|
29110
|
-
var MAP_BATCH_SIZE =
|
|
29719
|
+
var MAP_BATCH_SIZE = 5;
|
|
29111
29720
|
var MAP_BATCH_FLOOR_MS = 240000;
|
|
29112
29721
|
var CONSECUTIVE_TIMEOUT_LIMIT2 = 2;
|
|
29113
29722
|
var MAX_INDEPENDENT_REQUEUE_PER_RUN = MAP_BATCH_SIZE;
|
|
29723
|
+
function retryKey(project) {
|
|
29724
|
+
return `map-memories:retry:${project}`;
|
|
29725
|
+
}
|
|
29726
|
+
function readRetries(db, project) {
|
|
29727
|
+
try {
|
|
29728
|
+
const parsed = JSON.parse(getDreamState(db, retryKey(project)) ?? "{}");
|
|
29729
|
+
if (!isRecord(parsed))
|
|
29730
|
+
return {};
|
|
29731
|
+
const retries = {};
|
|
29732
|
+
for (const [id, value] of Object.entries(parsed)) {
|
|
29733
|
+
if (isRecord(value) && typeof value.content === "string" && typeof value.failures === "number" && typeof value.deferUntil === "number") {
|
|
29734
|
+
retries[id] = {
|
|
29735
|
+
content: value.content,
|
|
29736
|
+
failures: value.failures,
|
|
29737
|
+
deferUntil: value.deferUntil
|
|
29738
|
+
};
|
|
29739
|
+
}
|
|
29740
|
+
}
|
|
29741
|
+
return retries;
|
|
29742
|
+
} catch {
|
|
29743
|
+
return {};
|
|
29744
|
+
}
|
|
29745
|
+
}
|
|
29746
|
+
function contentKey2(memory) {
|
|
29747
|
+
return createHash12("sha256").update(`${memory.category}
|
|
29748
|
+
${memory.content}`).digest("hex");
|
|
29749
|
+
}
|
|
29750
|
+
function isDeferred(memory, retries) {
|
|
29751
|
+
const retry = retries[memory.id];
|
|
29752
|
+
return !!retry && retry.content === contentKey2(memory) && retry.deferUntil > Date.now();
|
|
29753
|
+
}
|
|
29754
|
+
function assistantText2(messages) {
|
|
29755
|
+
return messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).map((message) => extractLatestAssistantText([message]) ?? (isRecord(message) && Array.isArray(message.content) ? message.content.filter(isRecord).filter((part) => part.type === "text" && typeof part.text === "string").map((part) => part.text).join(`
|
|
29756
|
+
`) : "")).join(`
|
|
29757
|
+
`);
|
|
29758
|
+
}
|
|
29759
|
+
function currentManifest(text) {
|
|
29760
|
+
const start = text.lastIndexOf("<mappings>");
|
|
29761
|
+
return start < 0 ? text : text.slice(start);
|
|
29762
|
+
}
|
|
29763
|
+
function logBatchUsage(messages, committed, startedAt) {
|
|
29764
|
+
const steps = messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).length;
|
|
29765
|
+
log2(`[dreamer] map-memories batch: steps=${steps} committed=${committed} steps_per_memory=${committed ? (steps / committed).toFixed(2) : "n/a"} elapsed_ms=${Date.now() - startedAt}`);
|
|
29766
|
+
}
|
|
29114
29767
|
function computeMapBatchSliceMs(remainingMs, batchesRemaining) {
|
|
29115
29768
|
return Math.min(remainingMs, Math.max(MAP_BATCH_FLOOR_MS, Math.floor(remainingMs / batchesRemaining)));
|
|
29116
29769
|
}
|
|
@@ -29132,7 +29785,7 @@ function toMapInput(memory, repoDir) {
|
|
|
29132
29785
|
candidates: extractMemoryCandidatePaths(memory.content, repoDir)
|
|
29133
29786
|
};
|
|
29134
29787
|
}
|
|
29135
|
-
function selectMapMemoryInputs(db, projectIdentity, repoDir) {
|
|
29788
|
+
function selectMapMemoryInputs(db, projectIdentity, repoDir, includeDeferred = false) {
|
|
29136
29789
|
const active = getMemoriesByProject2(db, projectIdentity);
|
|
29137
29790
|
const activeIds = active.map((m) => m.id);
|
|
29138
29791
|
const unmapped = new Set(getUnmappedMemoryIds(db, activeIds));
|
|
@@ -29151,7 +29804,8 @@ function selectMapMemoryInputs(db, projectIdentity, repoDir) {
|
|
|
29151
29804
|
if (requeue.length >= MAX_INDEPENDENT_REQUEUE_PER_RUN)
|
|
29152
29805
|
break;
|
|
29153
29806
|
}
|
|
29154
|
-
|
|
29807
|
+
const retries = readRetries(db, projectIdentity);
|
|
29808
|
+
return [...unmappedInputs, ...requeue].filter((memory) => includeDeferred || !isDeferred(memory, retries));
|
|
29155
29809
|
}
|
|
29156
29810
|
async function mapMemories(args) {
|
|
29157
29811
|
const result = {
|
|
@@ -29161,14 +29815,21 @@ async function mapMemories(args) {
|
|
|
29161
29815
|
remaining: 0,
|
|
29162
29816
|
complete: true
|
|
29163
29817
|
};
|
|
29164
|
-
const
|
|
29818
|
+
const allInputs = selectMapMemoryInputs(args.db, args.projectIdentity, args.sessionDirectory, true);
|
|
29819
|
+
const retries = readRetries(args.db, args.projectIdentity);
|
|
29820
|
+
const activeIds = new Set(allInputs.map((memory) => String(memory.id)));
|
|
29821
|
+
for (const id of Object.keys(retries))
|
|
29822
|
+
if (!activeIds.has(id))
|
|
29823
|
+
delete retries[id];
|
|
29824
|
+
const inputs = allInputs.filter((memory) => !isDeferred(memory, retries));
|
|
29825
|
+
result.remaining = allInputs.length;
|
|
29826
|
+
result.complete = result.remaining === 0;
|
|
29165
29827
|
if (inputs.length === 0)
|
|
29166
29828
|
return result;
|
|
29167
29829
|
const batches = [];
|
|
29168
29830
|
for (let i = 0;i < inputs.length; i += MAP_BATCH_SIZE) {
|
|
29169
29831
|
batches.push({ inputs: inputs.slice(i, i + MAP_BATCH_SIZE), isOmissionRetry: false });
|
|
29170
29832
|
}
|
|
29171
|
-
result.remaining = inputs.length;
|
|
29172
29833
|
const abortController = new AbortController;
|
|
29173
29834
|
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, (reason) => abortController.abort(new Error(reason)), args.leaseAcquisition);
|
|
29174
29835
|
try {
|
|
@@ -29191,6 +29852,24 @@ async function mapMemories(args) {
|
|
|
29191
29852
|
break;
|
|
29192
29853
|
const outcome = await mapOneBatch(args, batch.inputs, sliceMs, abortController.signal);
|
|
29193
29854
|
const committed = outcome.mapped + outcome.independent;
|
|
29855
|
+
runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
|
|
29856
|
+
const committedIds = new Set(outcome.committedIds);
|
|
29857
|
+
for (const memory of batch.inputs) {
|
|
29858
|
+
if (committedIds.has(memory.id)) {
|
|
29859
|
+
delete retries[memory.id];
|
|
29860
|
+
continue;
|
|
29861
|
+
}
|
|
29862
|
+
const content = contentKey2(memory);
|
|
29863
|
+
const prior = retries[memory.id];
|
|
29864
|
+
const failures = (prior?.content === content ? prior.failures : 0) + 1;
|
|
29865
|
+
retries[memory.id] = {
|
|
29866
|
+
content,
|
|
29867
|
+
failures,
|
|
29868
|
+
deferUntil: failures < 2 ? 0 : Date.now() + Math.min(24, 2 ** (failures - 2)) * 3600000
|
|
29869
|
+
};
|
|
29870
|
+
}
|
|
29871
|
+
setDreamState(args.db, retryKey(args.projectIdentity), JSON.stringify(retries));
|
|
29872
|
+
});
|
|
29194
29873
|
result.mapped += outcome.mapped;
|
|
29195
29874
|
result.independent += outcome.independent;
|
|
29196
29875
|
result.remaining -= committed;
|
|
@@ -29200,8 +29879,8 @@ async function mapMemories(args) {
|
|
|
29200
29879
|
}
|
|
29201
29880
|
if (outcome.requeue?.length) {
|
|
29202
29881
|
if (!batch.isOmissionRetry) {
|
|
29203
|
-
batches.
|
|
29204
|
-
inputs: outcome.requeue,
|
|
29882
|
+
batches.push({
|
|
29883
|
+
inputs: outcome.requeue.filter((memory) => !isDeferred(memory, retries)),
|
|
29205
29884
|
isOmissionRetry: true
|
|
29206
29885
|
});
|
|
29207
29886
|
log2(`[dreamer] map-memories: committed ${committed}/${batch.inputs.length} mapping(s); requeueing ${outcome.requeue.length} omitted id(s) in a targeted retry`);
|
|
@@ -29209,12 +29888,12 @@ async function mapMemories(args) {
|
|
|
29209
29888
|
log2(`[dreamer] map-memories: targeted retry still omitted ${outcome.requeue.length} id(s); leaving them unmapped for the next run`);
|
|
29210
29889
|
}
|
|
29211
29890
|
}
|
|
29212
|
-
if (outcome.failure?.class === "timeout") {
|
|
29891
|
+
if (outcome.failure?.class === "timeout" && committed === 0) {
|
|
29213
29892
|
consecutiveTimeouts += 1;
|
|
29214
29893
|
timeoutStreakElapsedMs.push(outcome.failure.elapsedMs);
|
|
29215
29894
|
if (consecutiveTimeouts >= CONSECUTIVE_TIMEOUT_LIMIT2) {
|
|
29216
29895
|
result.stopReason = "timeout-circuit-breaker";
|
|
29217
|
-
log2(`[dreamer] map-memories starvation: circuit breaker tripped after ${consecutiveTimeouts} consecutive batch timeouts
|
|
29896
|
+
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`);
|
|
29218
29897
|
break;
|
|
29219
29898
|
}
|
|
29220
29899
|
} else {
|
|
@@ -29234,12 +29913,13 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
29234
29913
|
let promptSettled = false;
|
|
29235
29914
|
const startedAt = Date.now();
|
|
29236
29915
|
let budgetFinalized = false;
|
|
29916
|
+
let failedCompletion;
|
|
29237
29917
|
const onBudgetUpdate = (state) => {
|
|
29238
29918
|
budgetFinalized ||= state.finalizeFired;
|
|
29239
29919
|
args.onBudgetUpdate?.(state);
|
|
29240
29920
|
};
|
|
29241
29921
|
try {
|
|
29242
|
-
const prompt = buildMapMemoriesPrompt(args.projectIdentity, batch);
|
|
29922
|
+
const prompt = buildMapMemoriesPrompt(args.projectIdentity, await seedIdentifierCandidates(batch, args.sessionDirectory));
|
|
29243
29923
|
if (args.hiddenCompletionExecutor) {
|
|
29244
29924
|
const run = await runHiddenSingleShotPrompt({
|
|
29245
29925
|
executor: args.hiddenCompletionExecutor,
|
|
@@ -29255,14 +29935,18 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
29255
29935
|
fallbackModels: args.fallbackModels,
|
|
29256
29936
|
timeoutMs: sliceMs,
|
|
29257
29937
|
signal,
|
|
29258
|
-
|
|
29938
|
+
onFailureOutput: (completion) => {
|
|
29939
|
+
failedCompletion = completion;
|
|
29940
|
+
},
|
|
29941
|
+
parse: (text, completion) => validateMapMemoriesManifest(currentManifest(assistantText2(completion.messages ?? []) || text), new Set(batch.map((memory) => memory.id)))
|
|
29259
29942
|
});
|
|
29260
29943
|
recordInvocation2(args, startedAt, {
|
|
29261
29944
|
status: "completed",
|
|
29262
29945
|
messages: run.completion.messages ?? []
|
|
29263
29946
|
});
|
|
29264
|
-
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
|
|
29265
|
-
|
|
29947
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
|
|
29948
|
+
logBatchUsage(run.completion.messages ?? [], outcome.mapped + outcome.independent, startedAt);
|
|
29949
|
+
const returnedIds = new Set(outcome.committedIds);
|
|
29266
29950
|
return {
|
|
29267
29951
|
...outcome,
|
|
29268
29952
|
requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
|
|
@@ -29305,7 +29989,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
29305
29989
|
fetchOutput: async () => {
|
|
29306
29990
|
const messagesResponse = await client.session.messages({
|
|
29307
29991
|
path: { id: agentSessionId },
|
|
29308
|
-
query: { directory: args.sessionDirectory, limit:
|
|
29992
|
+
query: { directory: args.sessionDirectory, limit: 200 }
|
|
29309
29993
|
});
|
|
29310
29994
|
return normalizeSDKResponse(messagesResponse, [], {
|
|
29311
29995
|
preferResponseOnMissingData: true
|
|
@@ -29315,7 +29999,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
29315
29999
|
if (hasLengthCappedOutput(messages)) {
|
|
29316
30000
|
throw new Error("map-memories returned length-capped output");
|
|
29317
30001
|
}
|
|
29318
|
-
const text =
|
|
30002
|
+
const text = currentManifest(assistantText2(messages));
|
|
29319
30003
|
if (!text)
|
|
29320
30004
|
throw new Error("map-memories returned no output");
|
|
29321
30005
|
return validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
@@ -29323,8 +30007,9 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
29323
30007
|
});
|
|
29324
30008
|
promptSettled = true;
|
|
29325
30009
|
recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
|
|
29326
|
-
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
|
|
29327
|
-
|
|
30010
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
|
|
30011
|
+
logBatchUsage(run.output, outcome.mapped + outcome.independent, startedAt);
|
|
30012
|
+
const returnedIds = new Set(outcome.committedIds);
|
|
29328
30013
|
return {
|
|
29329
30014
|
...outcome,
|
|
29330
30015
|
requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
|
|
@@ -29332,18 +30017,23 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
29332
30017
|
} catch (error) {
|
|
29333
30018
|
const desc = describeError(error);
|
|
29334
30019
|
log2(`[dreamer] map-memories batch failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
30020
|
+
const messages = failedCompletion?.messages ?? await readFailedChildMessages(args.client, agentSessionId, args.sessionDirectory) ?? [];
|
|
29335
30021
|
recordInvocation2(args, startedAt, {
|
|
29336
30022
|
status: failedInvocationStatus(error),
|
|
29337
30023
|
error,
|
|
29338
|
-
messages
|
|
30024
|
+
messages
|
|
29339
30025
|
});
|
|
29340
|
-
if (error instanceof DreamerModuleFailureError
|
|
30026
|
+
if (error instanceof DreamerModuleFailureError)
|
|
29341
30027
|
throw error;
|
|
29342
30028
|
if (signal.aborted)
|
|
29343
30029
|
throw error;
|
|
30030
|
+
const recovered = parsePartialMapMemoriesManifest(assistantText2(messages) || failedCompletion?.text || "", new Set(batch.map((memory) => memory.id)));
|
|
30031
|
+
const outcome = await applyParsedBatchMappings(args, batch, recovered, budgetFinalized, true);
|
|
30032
|
+
logBatchUsage(messages, outcome.mapped + outcome.independent, startedAt);
|
|
30033
|
+
if (error instanceof DreamTokenBudgetExceeded)
|
|
30034
|
+
throw error;
|
|
29344
30035
|
return {
|
|
29345
|
-
|
|
29346
|
-
independent: 0,
|
|
30036
|
+
...outcome,
|
|
29347
30037
|
failure: {
|
|
29348
30038
|
class: isTimeoutClassError2(error) ? "timeout" : "other",
|
|
29349
30039
|
elapsedMs: Date.now() - startedAt
|
|
@@ -29362,7 +30052,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
29362
30052
|
});
|
|
29363
30053
|
}
|
|
29364
30054
|
}
|
|
29365
|
-
async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = false) {
|
|
30055
|
+
async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = false, allowPartial = false) {
|
|
29366
30056
|
const batchIds = new Set(batch.map((memory) => memory.id));
|
|
29367
30057
|
const valid = parsed.filter((entry) => batchIds.has(entry.id));
|
|
29368
30058
|
const unknown = parsed.filter((entry) => !batchIds.has(entry.id));
|
|
@@ -29370,14 +30060,14 @@ async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = f
|
|
|
29370
30060
|
log2(`[dreamer] map-memories warning: dropping ${unknown.length} unknown mapping entr${unknown.length === 1 ? "y" : "ies"} outside the current batch (${unknown.map((entry) => entry.id).join(", ")})`);
|
|
29371
30061
|
}
|
|
29372
30062
|
assertNoDuplicateManifestIds(valid.map((entry) => entry.id), "mappings");
|
|
29373
|
-
if (!budgetFinalized && valid.length * 2 < batch.length) {
|
|
30063
|
+
if (!allowPartial && !budgetFinalized && valid.length * 2 < batch.length) {
|
|
29374
30064
|
throw new Error(`mappings manifest covers ${valid.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
29375
30065
|
}
|
|
29376
30066
|
if (budgetFinalized && valid.length < batch.length) {
|
|
29377
30067
|
log2(`[dreamer] map-memories: accepted partial manifest after token budget: ${valid.length}/${batch.length}`);
|
|
29378
30068
|
}
|
|
29379
30069
|
if (valid.length === 0)
|
|
29380
|
-
return { mapped: 0, independent: 0 };
|
|
30070
|
+
return { mapped: 0, independent: 0, committedIds: [] };
|
|
29381
30071
|
const planned = [];
|
|
29382
30072
|
const batchById = new Map(batch.map((memory) => [memory.id, memory]));
|
|
29383
30073
|
for (const p of valid) {
|
|
@@ -29426,9 +30116,10 @@ async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = f
|
|
|
29426
30116
|
});
|
|
29427
30117
|
}
|
|
29428
30118
|
if (planned.length === 0)
|
|
29429
|
-
return { mapped: 0, independent: 0 };
|
|
30119
|
+
return { mapped: 0, independent: 0, committedIds: [] };
|
|
29430
30120
|
let mapped = 0;
|
|
29431
30121
|
let independent = 0;
|
|
30122
|
+
const committedIds = [];
|
|
29432
30123
|
if (args.moduleRoute) {
|
|
29433
30124
|
const identities = getModuleMemoryIdentities(args.db, args.projectIdentity, planned.map((item) => item.id));
|
|
29434
30125
|
const rows = planned.map((item) => {
|
|
@@ -29452,7 +30143,7 @@ async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = f
|
|
|
29452
30143
|
name: "memory.set_mapping",
|
|
29453
30144
|
arguments: {
|
|
29454
30145
|
memory_project: args.projectIdentity,
|
|
29455
|
-
command_id: `${args.moduleRoute.moduleCommandId}:${
|
|
30146
|
+
command_id: `${args.moduleRoute.moduleCommandId}:${createHash12("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
|
|
29456
30147
|
rows
|
|
29457
30148
|
}
|
|
29458
30149
|
}
|
|
@@ -29466,19 +30157,22 @@ async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = f
|
|
|
29466
30157
|
const accepted = new Set(result.accepted.filter((id) => typeof id === "number"));
|
|
29467
30158
|
for (const item of planned) {
|
|
29468
30159
|
const identity = identities.get(item.id);
|
|
29469
|
-
if (identity && accepted.has(identity.moduleId))
|
|
30160
|
+
if (identity && accepted.has(identity.moduleId)) {
|
|
29470
30161
|
item.independent ? independent += 1 : mapped += 1;
|
|
30162
|
+
committedIds.push(item.id);
|
|
30163
|
+
}
|
|
29471
30164
|
}
|
|
29472
|
-
return { mapped, independent };
|
|
30165
|
+
return { mapped, independent, committedIds };
|
|
29473
30166
|
}
|
|
29474
30167
|
const now = Date.now();
|
|
29475
30168
|
runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
|
|
29476
30169
|
for (const item of planned) {
|
|
29477
30170
|
recordMemoryMapping(args.db, item.id, item.files, now, item.mappingOrigin);
|
|
29478
30171
|
item.independent ? independent += 1 : mapped += 1;
|
|
30172
|
+
committedIds.push(item.id);
|
|
29479
30173
|
}
|
|
29480
30174
|
});
|
|
29481
|
-
return { mapped, independent };
|
|
30175
|
+
return { mapped, independent, committedIds };
|
|
29482
30176
|
}
|
|
29483
30177
|
function recordInvocation2(args, startedAt, params) {
|
|
29484
30178
|
if (!args.parentSessionId)
|
|
@@ -29746,32 +30440,41 @@ async function promotePrimers(args) {
|
|
|
29746
30440
|
// src/features/magic-context/dreamer/primer-seed.ts
|
|
29747
30441
|
var PRIMER_SEED_CAP_TOKENS = 4000;
|
|
29748
30442
|
function renderUserAndToolOrientation(sessionId, startOrdinal, endOrdinal, capTokens) {
|
|
30443
|
+
const renderer = orientationRenderer(capTokens);
|
|
30444
|
+
visitRawSessionMessages2(sessionId, startOrdinal, endOrdinal, renderer.visit, {
|
|
30445
|
+
summary: true
|
|
30446
|
+
});
|
|
30447
|
+
return renderer.result();
|
|
30448
|
+
}
|
|
30449
|
+
function orientationRenderer(capTokens) {
|
|
29749
30450
|
const lines = [];
|
|
29750
30451
|
let tokens = 0;
|
|
29751
30452
|
let sawMessage = false;
|
|
29752
|
-
|
|
29753
|
-
|
|
29754
|
-
|
|
29755
|
-
|
|
29756
|
-
|
|
29757
|
-
|
|
29758
|
-
|
|
29759
|
-
|
|
29760
|
-
|
|
29761
|
-
|
|
29762
|
-
|
|
29763
|
-
const
|
|
29764
|
-
|
|
29765
|
-
|
|
29766
|
-
|
|
30453
|
+
return {
|
|
30454
|
+
visit: (msg) => {
|
|
30455
|
+
sawMessage = true;
|
|
30456
|
+
const out = [];
|
|
30457
|
+
if (msg.role === "user" && hasMeaningfulUserText2(msg.parts)) {
|
|
30458
|
+
const text = extractTexts2(msg.parts).map((t) => cleanUserText2(t)).map(normalizeText).filter((t) => t.length > 0).join(" / ");
|
|
30459
|
+
if (text)
|
|
30460
|
+
out.push(`U: ${text}`);
|
|
30461
|
+
}
|
|
30462
|
+
for (const tc of extractToolCallSummaries(msg.parts))
|
|
30463
|
+
out.push(tc);
|
|
30464
|
+
for (const line of out) {
|
|
30465
|
+
const lineTokens = estimateTokens(line);
|
|
30466
|
+
if (tokens + lineTokens > capTokens && lines.length > 0) {
|
|
30467
|
+
lines.push("… (orientation truncated; investigate the current source directly)");
|
|
30468
|
+
return false;
|
|
30469
|
+
}
|
|
30470
|
+
lines.push(line);
|
|
30471
|
+
tokens += lineTokens;
|
|
29767
30472
|
}
|
|
29768
|
-
|
|
29769
|
-
|
|
29770
|
-
|
|
29771
|
-
|
|
29772
|
-
}
|
|
29773
|
-
return sawMessage ? lines.join(`
|
|
29774
|
-
`) : null;
|
|
30473
|
+
return true;
|
|
30474
|
+
},
|
|
30475
|
+
result: () => sawMessage ? lines.join(`
|
|
30476
|
+
`) : null
|
|
30477
|
+
};
|
|
29775
30478
|
}
|
|
29776
30479
|
function selectPrimerOriginCandidate(db, primer) {
|
|
29777
30480
|
return getPrimerCandidatesByIds(db, primer.sourceCandidateIds).filter((candidate) => candidate.projectPath === primer.projectPath).sort((a, b) => b.sourceMessageTime - a.sourceMessageTime || b.id - a.id)[0];
|
|
@@ -29805,16 +30508,37 @@ function closedBookOriginP1(db, sessionId, originStartMessage) {
|
|
|
29805
30508
|
return { orientation, sessionId };
|
|
29806
30509
|
}
|
|
29807
30510
|
function buildPrimerSeed(db, primer) {
|
|
30511
|
+
return buildPrimerSeedUsing(db, selectPrimerOriginCandidate(db, primer), renderUserAndToolOrientation);
|
|
30512
|
+
}
|
|
30513
|
+
async function buildPrimerSeedAsync(db, primer) {
|
|
29808
30514
|
const mostRecent = selectPrimerOriginCandidate(db, primer);
|
|
30515
|
+
let orientation = null;
|
|
30516
|
+
if (mostRecent && typeof mostRecent.sourceCompartmentStart === "number" && typeof mostRecent.sourceCompartmentEnd === "number") {
|
|
30517
|
+
try {
|
|
30518
|
+
const renderer = orientationRenderer(PRIMER_SEED_CAP_TOKENS);
|
|
30519
|
+
await visitRawSessionMessagesAsync2(mostRecent.sessionId, mostRecent.sourceCompartmentStart, mostRecent.sourceCompartmentEnd, renderer.visit, { summary: true });
|
|
30520
|
+
orientation = renderer.result();
|
|
30521
|
+
} catch {
|
|
30522
|
+
orientation = null;
|
|
30523
|
+
}
|
|
30524
|
+
}
|
|
30525
|
+
return buildPrimerSeedUsing(db, mostRecent, () => orientation);
|
|
30526
|
+
}
|
|
30527
|
+
function buildPrimerSeedUsing(db, mostRecent, render) {
|
|
29809
30528
|
if (!mostRecent || typeof mostRecent.sourceCompartmentStart !== "number" || typeof mostRecent.sourceCompartmentEnd !== "number") {
|
|
29810
|
-
return {
|
|
30529
|
+
return {
|
|
30530
|
+
kind: "closed-book",
|
|
30531
|
+
orientation: "",
|
|
30532
|
+
prePost: "",
|
|
30533
|
+
sessionId: null
|
|
30534
|
+
};
|
|
29811
30535
|
}
|
|
29812
30536
|
const sessionId = mostRecent.sessionId;
|
|
29813
30537
|
const start = mostRecent.sourceCompartmentStart;
|
|
29814
30538
|
const end = mostRecent.sourceCompartmentEnd;
|
|
29815
30539
|
let orientation = null;
|
|
29816
30540
|
try {
|
|
29817
|
-
orientation =
|
|
30541
|
+
orientation = render(sessionId, start, end, PRIMER_SEED_CAP_TOKENS);
|
|
29818
30542
|
} catch {
|
|
29819
30543
|
orientation = null;
|
|
29820
30544
|
}
|
|
@@ -29945,14 +30669,14 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
29945
30669
|
provider = null;
|
|
29946
30670
|
}
|
|
29947
30671
|
}
|
|
29948
|
-
const seed =
|
|
30672
|
+
const seed = await (async () => {
|
|
29949
30673
|
const unregister = provider && originSessionId ? setRawMessageProvider2(originSessionId, provider) : null;
|
|
29950
30674
|
try {
|
|
29951
|
-
return buildPrimerSeed(args.db, primer);
|
|
30675
|
+
return provider?.iterateMessageRangeAsync ? await buildPrimerSeedAsync(args.db, primer) : withRawSessionMessageCache2(() => buildPrimerSeed(args.db, primer));
|
|
29952
30676
|
} finally {
|
|
29953
30677
|
unregister?.();
|
|
29954
30678
|
}
|
|
29955
|
-
});
|
|
30679
|
+
})();
|
|
29956
30680
|
let agentSessionId = null;
|
|
29957
30681
|
let promptSettled = false;
|
|
29958
30682
|
const startedAt = Date.now();
|
|
@@ -29968,7 +30692,10 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
29968
30692
|
prompt,
|
|
29969
30693
|
title: "magic-context-dream-refresh-primers",
|
|
29970
30694
|
callContext: "dreamer:refresh-primers",
|
|
29971
|
-
metadata: {
|
|
30695
|
+
metadata: {
|
|
30696
|
+
tokenBudget: args.tokenBudget,
|
|
30697
|
+
onBudgetUpdate: args.onBudgetUpdate
|
|
30698
|
+
},
|
|
29972
30699
|
model: args.model,
|
|
29973
30700
|
fallbackModels: args.fallbackModels,
|
|
29974
30701
|
language: args.language,
|
|
@@ -30034,7 +30761,10 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
30034
30761
|
validateOutput: (messages) => parseAnswer(messages, primer.answer)
|
|
30035
30762
|
});
|
|
30036
30763
|
promptSettled = true;
|
|
30037
|
-
recordInvocation3(args, startedAt, {
|
|
30764
|
+
recordInvocation3(args, startedAt, {
|
|
30765
|
+
status: "completed",
|
|
30766
|
+
messages: run.output
|
|
30767
|
+
});
|
|
30038
30768
|
const answer = run.validated.trim();
|
|
30039
30769
|
if (!answer)
|
|
30040
30770
|
return false;
|
|
@@ -30049,7 +30779,10 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
30049
30779
|
} catch (error) {
|
|
30050
30780
|
const desc = describeError(error);
|
|
30051
30781
|
log2(`[dreamer] refresh-primers failed (primer #${primer.id}): ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
30052
|
-
recordInvocation3(args, startedAt, {
|
|
30782
|
+
recordInvocation3(args, startedAt, {
|
|
30783
|
+
status: failedInvocationStatus(error),
|
|
30784
|
+
error
|
|
30785
|
+
});
|
|
30053
30786
|
throw error;
|
|
30054
30787
|
} finally {
|
|
30055
30788
|
if (agentSessionId && args.client)
|
|
@@ -30687,12 +31420,12 @@ function insertDreamRun(db, run) {
|
|
|
30687
31420
|
}
|
|
30688
31421
|
|
|
30689
31422
|
// src/features/magic-context/dreamer/verify.ts
|
|
30690
|
-
import { createHash as
|
|
31423
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
30691
31424
|
|
|
30692
31425
|
// src/features/magic-context/dreamer/verify-diff.ts
|
|
30693
|
-
import { execFile as
|
|
30694
|
-
import { promisify as
|
|
30695
|
-
var exec =
|
|
31426
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
31427
|
+
import { promisify as promisify3 } from "node:util";
|
|
31428
|
+
var exec = promisify3(execFile3);
|
|
30696
31429
|
var VERIFY_DIFF_BUDGET_TOKENS = 12000;
|
|
30697
31430
|
var MAX_DIFF_BYTES = 4 * 1024 * 1024;
|
|
30698
31431
|
async function git2(root, args) {
|
|
@@ -31431,7 +32164,7 @@ async function applyParsedVerifyManifest(args, batch, parsed, headAtPrompt, budg
|
|
|
31431
32164
|
name: "memory.set_verification",
|
|
31432
32165
|
arguments: {
|
|
31433
32166
|
memory_project: args.projectIdentity,
|
|
31434
|
-
command_id: `${args.moduleRoute.moduleCommandId}:${
|
|
32167
|
+
command_id: `${args.moduleRoute.moduleCommandId}:${createHash13("sha256").update(rows.map((row) => row.memory_id).join(",")).digest("hex").slice(0, 16)}`,
|
|
31435
32168
|
rows
|
|
31436
32169
|
}
|
|
31437
32170
|
}
|
|
@@ -32237,7 +32970,7 @@ function parseFrictionGateVerdict(verdict) {
|
|
|
32237
32970
|
}
|
|
32238
32971
|
function computeRetrospectiveWindowKey(flagged) {
|
|
32239
32972
|
const anchors = flagged.map((message) => `${message.sessionId}:${message.ts}`).sort().join("|");
|
|
32240
|
-
return
|
|
32973
|
+
return createHash14("sha256").update(anchors).digest("hex").slice(0, 32);
|
|
32241
32974
|
}
|
|
32242
32975
|
function renderFrictionWindow(messages, flaggedOrdinals, radius = 2) {
|
|
32243
32976
|
const flagged = new Set(flaggedOrdinals);
|
|
@@ -34191,9 +34924,9 @@ function hiddenTerminalError(event) {
|
|
|
34191
34924
|
}
|
|
34192
34925
|
|
|
34193
34926
|
// src/v2/hooks/lkg-system.ts
|
|
34194
|
-
import { createHash as
|
|
34927
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
34195
34928
|
function identity(slot) {
|
|
34196
|
-
return
|
|
34929
|
+
return createHash15("sha256").update(JSON.stringify({
|
|
34197
34930
|
capturedAt: slot.capturedAt,
|
|
34198
34931
|
captureSequence: slot.captureSequence,
|
|
34199
34932
|
rowVersion: slot.rowVersion,
|
|
@@ -47010,7 +47743,7 @@ function resolveCtxExpandMode(args, domain) {
|
|
|
47010
47743
|
}
|
|
47011
47744
|
|
|
47012
47745
|
// src/tools/ctx-expand/render.ts
|
|
47013
|
-
import { createHash as
|
|
47746
|
+
import { createHash as createHash16 } from "node:crypto";
|
|
47014
47747
|
function isRecord6(value) {
|
|
47015
47748
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
47016
47749
|
}
|
|
@@ -47234,11 +47967,61 @@ function renderItemByTag(db, sessionId, number, textIndexDomain = "part") {
|
|
|
47234
47967
|
const index = scoped ? Number(scoped[2]) : 0;
|
|
47235
47968
|
const piText = message.parts.filter((part) => isRecord6(part) && part.type === "text");
|
|
47236
47969
|
const part = message.parts[index];
|
|
47237
|
-
const matching = derived ? piText.filter((part) => isRecord6(part) && typeof part.text === "string" &&
|
|
47970
|
+
const matching = derived ? piText.filter((part) => isRecord6(part) && typeof part.text === "string" && createHash16("sha256").update(part.text).digest("hex") === derived[3]) : [];
|
|
47238
47971
|
const selected = derived ? matching[Number(derived[4])] : textIndexDomain === "text" ? piText[index] : part;
|
|
47239
47972
|
return selected ? renderPartFull(selected) ?? "" : `Tag ${number}'s original text part is no longer in stored history.`;
|
|
47240
47973
|
}
|
|
47241
47974
|
|
|
47975
|
+
// src/tools/ctx-expand/search-archive.ts
|
|
47976
|
+
function renderSearchArchive(db, sessionId, start, end, tokenBudget, archiveOnly = false) {
|
|
47977
|
+
return withMessageFtsSessionFilter(db, sessionId, (sessionFirst) => {
|
|
47978
|
+
let rawIds;
|
|
47979
|
+
const rows = db.prepare(sessionFirst ? `SELECT f.message_ordinal AS ordinal, f.message_id AS id, f.role, f.content
|
|
47980
|
+
FROM message_fts_rowid_map AS m
|
|
47981
|
+
JOIN message_history_fts AS f ON f.rowid = m.fts_rowid
|
|
47982
|
+
WHERE m.session_id = ?1 AND m.message_ordinal BETWEEN ?2 AND ?3
|
|
47983
|
+
AND f.session_id = ?1 AND f.message_ordinal BETWEEN ?2 AND ?3
|
|
47984
|
+
ORDER BY m.message_ordinal` : `SELECT message_ordinal AS ordinal, message_id AS id, role, content
|
|
47985
|
+
FROM message_history_fts
|
|
47986
|
+
WHERE session_id = ?1 AND message_ordinal BETWEEN ?2 AND ?3
|
|
47987
|
+
ORDER BY CAST(message_ordinal AS INTEGER)`);
|
|
47988
|
+
const blocks = [];
|
|
47989
|
+
let tokens = 0;
|
|
47990
|
+
let lastOrdinal = start - 1;
|
|
47991
|
+
let truncated = false;
|
|
47992
|
+
for (const row of rows.iterate(sessionId, start, end)) {
|
|
47993
|
+
if (!row.content)
|
|
47994
|
+
continue;
|
|
47995
|
+
if (!archiveOnly) {
|
|
47996
|
+
rawIds ??= readRawSessionMessageIdOrdinalsForRange2(sessionId, start, end);
|
|
47997
|
+
if (rawIds.get(row.id) === row.ordinal)
|
|
47998
|
+
continue;
|
|
47999
|
+
}
|
|
48000
|
+
const block = `[${row.ordinal}] ${row.role === "user" ? "U" : "A"}: ${row.content}`;
|
|
48001
|
+
const cost = estimateTokens(block);
|
|
48002
|
+
if (blocks.length > 0 && tokens + cost > tokenBudget) {
|
|
48003
|
+
truncated = true;
|
|
48004
|
+
break;
|
|
48005
|
+
}
|
|
48006
|
+
blocks.push(block);
|
|
48007
|
+
tokens += cost;
|
|
48008
|
+
lastOrdinal = row.ordinal;
|
|
48009
|
+
}
|
|
48010
|
+
if (blocks.length === 0)
|
|
48011
|
+
return null;
|
|
48012
|
+
const text = [
|
|
48013
|
+
"From the search archive: indexed text only; no surrounding messages or tool output.",
|
|
48014
|
+
"",
|
|
48015
|
+
...blocks
|
|
48016
|
+
];
|
|
48017
|
+
if (truncated) {
|
|
48018
|
+
text.push("", `Truncated at message ${lastOrdinal} (budget: ~${tokenBudget} tokens). Call ctx_expand(start=${lastOrdinal + 1}, end=${end}) for more archived text.`);
|
|
48019
|
+
}
|
|
48020
|
+
return text.join(`
|
|
48021
|
+
`);
|
|
48022
|
+
});
|
|
48023
|
+
}
|
|
48024
|
+
|
|
47242
48025
|
// src/tools/ctx-expand/tools.ts
|
|
47243
48026
|
var ctxExpandArgsShape = {
|
|
47244
48027
|
tag: tool.schema.union([tool.schema.number(), tool.schema.string()]).optional().describe("Tag number from a §N§ tag or a [dropped §N§] placeholder, not a message ordinal. Returns that one item in full. Use alone."),
|
|
@@ -47272,7 +48055,7 @@ function createCtxExpandTool(deps) {
|
|
|
47272
48055
|
return renderItemByTag(deps.db, sessionId, mode.tag);
|
|
47273
48056
|
}
|
|
47274
48057
|
if (mode.kind === "message") {
|
|
47275
|
-
return renderMessageByOrdinal(sessionId, mode.message);
|
|
48058
|
+
return renderSearchArchive(deps.db, sessionId, mode.message, mode.message, CTX_EXPAND_TOKEN_BUDGET) ?? renderMessageByOrdinal(sessionId, mode.message);
|
|
47276
48059
|
}
|
|
47277
48060
|
const { start, end, verbose } = mode;
|
|
47278
48061
|
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
@@ -47280,6 +48063,9 @@ function createCtxExpandTool(deps) {
|
|
|
47280
48063
|
return `Range ${start}-${end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`;
|
|
47281
48064
|
}
|
|
47282
48065
|
const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(end, lastCompartmentEnd) : end;
|
|
48066
|
+
const archived = renderSearchArchive(deps.db, sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET);
|
|
48067
|
+
if (archived)
|
|
48068
|
+
return archived;
|
|
47283
48069
|
if (verbose) {
|
|
47284
48070
|
const v = renderVerboseRange(sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET, deps.expandTools);
|
|
47285
48071
|
if (!v.text) {
|
|
@@ -48106,9 +48892,9 @@ function isMissingError(error) {
|
|
|
48106
48892
|
}
|
|
48107
48893
|
|
|
48108
48894
|
// ../retina-local-fs/src/provider.ts
|
|
48109
|
-
import { execFile as
|
|
48110
|
-
import { promisify as
|
|
48111
|
-
var
|
|
48895
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
48896
|
+
import { promisify as promisify4 } from "node:util";
|
|
48897
|
+
var execFileAsync3 = promisify4(execFile4);
|
|
48112
48898
|
function parseSemver(value) {
|
|
48113
48899
|
const match = /^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z.-]+))?(?:\+[0-9A-Za-z.-]+)?$/.exec(value);
|
|
48114
48900
|
if (!match) {
|
|
@@ -48757,7 +49543,7 @@ function formatCtxReduceReply(stampedCount, selfStampCount = 0) {
|
|
|
48757
49543
|
return parts.join(" ");
|
|
48758
49544
|
}
|
|
48759
49545
|
// src/tools/ctx-reduce/tools.ts
|
|
48760
|
-
import { createHash as
|
|
49546
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
48761
49547
|
|
|
48762
49548
|
// src/features/magic-context/range-parser.ts
|
|
48763
49549
|
function parseRangeString(input) {
|
|
@@ -48820,11 +49606,11 @@ function createCtxReduceTool(deps) {
|
|
|
48820
49606
|
const stableId = `oc-${sessionId}-${callId}`;
|
|
48821
49607
|
if (Buffer.byteLength(stableId) <= 128)
|
|
48822
49608
|
return stableId;
|
|
48823
|
-
return `oc-${
|
|
49609
|
+
return `oc-${createHash17("sha256").update(stableId).digest("hex")}`;
|
|
48824
49610
|
}
|
|
48825
49611
|
fallbackCommandSequence += 1;
|
|
48826
49612
|
const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
|
|
48827
|
-
return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${
|
|
49613
|
+
return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash17("sha256").update(monotonicId).digest("hex")}`;
|
|
48828
49614
|
};
|
|
48829
49615
|
return tool({
|
|
48830
49616
|
description: CTX_REDUCE_DESCRIPTION,
|