@cortexkit/opencode-magic-context 0.49.6 → 0.49.8
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-worker.js +2 -2
- package/dist/{compaction-marker-candidates-cz72pm1t.js → compaction-marker-candidates-xxz35vwp.js} +3 -3
- package/dist/{conflict-warning-hook-1jq1rxx7.js → conflict-warning-hook-w3crzrar.js} +8 -8
- package/dist/{context-ae3gxdye.js → context-x0ccfv0f.js} +88 -53
- package/dist/{derive-budgets-j4ry8j8n.js → derive-budgets-3nbxsyss.js} +2 -2
- package/dist/embedding-backfill-3h2m5n0q.js +21 -0
- package/dist/embedding-worker-process.js +6 -2
- package/dist/embedding-worker.js +6 -5
- package/dist/features/magic-context/compaction-marker-candidates.d.ts.map +1 -1
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/cron.d.ts +2 -0
- package/dist/features/magic-context/dreamer/cron.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/provider-output-failure.d.ts +1 -0
- package/dist/features/magic-context/dreamer/provider-output-failure.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/refresh-primers.d.ts +2 -2
- package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-worker-client.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/migration-worker-client.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/wake-plane.d.ts.map +1 -1
- 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/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/history-owner-ty29fz0f.js +244 -0
- package/dist/hooks/auto-update-checker/checker.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/auto-search-worker-client.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/edit-marker.d.ts +2 -0
- package/dist/hooks/magic-context/edit-marker.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/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
- package/dist/hooks/magic-context/module-transport.d.ts +1 -0
- package/dist/hooks/magic-context/module-transport.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/raw-ordinal-warmup.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +15 -4
- 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 +4 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-refusal-recovery.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/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/unresolved-history-boundary.d.ts +5 -1
- package/dist/hooks/magic-context/unresolved-history-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/{index-g9exahnx.js → index-0jz47061.js} +6 -3
- package/dist/{index-4mjhqadz.js → index-150zz6fh.js} +1 -1
- package/dist/{index-ch08qwgd.js → index-2rw244rh.js} +88 -81
- package/dist/{index-6q5h70h2.js → index-4hb8nt93.js} +3 -3
- package/dist/{index-j55vn694.js → index-7bjgyaj1.js} +4 -4
- package/dist/{index-h2wc01qk.js → index-8kk7yh6m.js} +2 -2
- package/dist/{index-vztbgcdk.js → index-9g1c4bt9.js} +304 -92
- package/dist/{index-7q1m1qjk.js → index-a43xq1pg.js} +5 -5
- package/dist/{index-tqf7yg27.js → index-a4b0gbyg.js} +1 -1
- package/dist/{index-vnjhmkwk.js → index-angx1s0k.js} +4 -3
- package/dist/{index-1xaw2pq8.js → index-b4gcb3rk.js} +8 -8
- package/dist/{index-z1tjp257.js → index-b64n4d0h.js} +1 -1
- package/dist/{index-1bt88epp.js → index-bd9cjab3.js} +1 -1
- package/dist/{index-gbmqa9x9.js → index-bmwfzz28.js} +9 -6
- package/dist/{index-qx53vezw.js → index-gjvjh960.js} +1 -1
- package/dist/{index-zgzdm6dg.js → index-gzg9ekc1.js} +155 -103
- package/dist/{index-vh3e2mvr.js → index-hxrvx6cy.js} +121 -51
- package/dist/{index-w23dh319.js → index-jw4gbfkv.js} +1 -1
- package/dist/index-knvkbfvh.js +25 -0
- package/dist/{index-vkbqdnkj.js → index-kvw6xew3.js} +6 -3
- package/dist/{index-bg5qqene.js → index-mp2kghkv.js} +3 -27
- package/dist/{index-nsjyysj0.js → index-mvvephtj.js} +5 -1
- package/dist/{index-cm4hmxyk.js → index-n78avt2p.js} +1 -1
- package/dist/{index-hr64sth2.js → index-pgy3h49n.js} +4 -4
- package/dist/{index-a796ct3s.js → index-pjgzdezw.js} +13 -9
- package/dist/{index-9m7bn21d.js → index-q28hsbpg.js} +15 -3
- package/dist/{index-ab3bgm2m.js → index-q76br5zn.js} +3 -3
- package/dist/{index-xqyj5c85.js → index-qgp5vnt4.js} +5 -5
- package/dist/{index-9s58tq95.js → index-rg1cezmj.js} +22 -22
- package/dist/{index-f3dnvnw6.js → index-s178h9z8.js} +4 -3
- package/dist/{index-mj1fgfrk.js → index-w1ejb9qr.js} +939 -160
- package/dist/{index-k6xvbj2e.js → index-w28y7d0z.js} +2 -0
- package/dist/{index-0nnd4bry.js → index-wafzvyhg.js} +63 -19
- package/dist/{index-ck6y3td2.js → index-xf6k8szp.js} +4 -4
- package/dist/{index-1j8jcjpa.js → index-xpn05jxq.js} +4 -4
- package/dist/{index-s0gsmthp.js → index-ydjgz36f.js} +7 -7
- package/dist/{index-besxhcsh.js → index-zf9nydbd.js} +50 -39
- package/dist/index.js +53 -52
- package/dist/{logger-ewak5q1s.js → logger-wn328tfg.js} +1 -1
- package/dist/{message-index-bounded-630j53ps.js → message-index-bounded-hxjp56qk.js} +16 -16
- package/dist/{message-index-c84wm2g0.js → message-index-zs882h8e.js} +16 -16
- package/dist/{message-time-backfill-8kj57qe3.js → message-time-backfill-nb5hhnrt.js} +3 -3
- package/dist/migration-worker.js +11 -11
- package/dist/plugin/boot-quiet.d.ts.map +1 -1
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts +2 -0
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/{project-embedding-registry-vv59t7ah.js → project-embedding-registry-vy7sv9jt.js} +11 -11
- package/dist/raw-ordinal-warmup-worker.js +17 -15
- package/dist/{read-session-chunk-t3vjd0h0.js → read-session-chunk-t9r7r0sg.js} +13 -11
- package/dist/{read-session-raw-gf7eytnm.js → read-session-raw-gm6xj30v.js} +3 -3
- package/dist/recomp-orchestrator-gr36zvd2.js +60 -0
- package/dist/{safe-notification-target-q0cyrx3x.js → safe-notification-target-jdynm677.js} +2 -2
- package/dist/{search-kth2p6cc.js → search-qjen1pmz.js} +24 -24
- package/dist/{send-session-notification-3j6krd4w.js → send-session-notification-q8ngbap3.js} +6 -6
- package/dist/shared/history-owner.d.ts +12 -0
- package/dist/shared/history-owner.d.ts.map +1 -0
- package/dist/shared/off-thread-migration-clock.d.ts +8 -1
- package/dist/shared/off-thread-migration-clock.d.ts.map +1 -1
- 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/redaction.d.ts.map +1 -1
- package/dist/shared/rpc-server.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +3 -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/shared/user-facing-codes.d.ts +2 -2
- package/dist/{sqlite-d7edbk1s.js → sqlite-4pqyynrs.js} +3 -1
- package/dist/{storage-memory-af5zdz98.js → storage-memory-j3v3hc83.js} +2 -2
- package/dist/{storage-tags-dyj7mmbq.js → storage-tags-a513rkj3.js} +5 -5
- 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-bv3kb5s1.js → transform-postprocess-phase-yv463b7y.js} +30 -30
- package/dist/v2/auto-search-worker.js +10 -7
- package/dist/v2/{compaction-marker-candidates-6gqp5wrc.js → compaction-marker-candidates-a15w3mqh.js} +3 -3
- package/dist/v2/compaction-marker-candidates-worker.js +2 -2
- package/dist/v2/{context-p8f2shp1.js → context-wd82v9z6.js} +1133 -278
- package/dist/v2/{derive-budgets-enckmg7y.js → derive-budgets-0rmpmxjw.js} +3 -3
- package/dist/v2/embedding-backfill-vr7wdtrf.js +20 -0
- package/dist/v2/embedding-worker-process.js +6 -2
- package/dist/v2/embedding-worker.js +6 -5
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/history-owner-2cr9py37.js +243 -0
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/store.d.ts +1 -0
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/{logger-pj02s7sr.js → logger-te6e1j72.js} +1 -1
- package/dist/v2/{message-index-bounded-yzxmf6vp.js → message-index-bounded-madg2kfr.js} +16 -16
- package/dist/v2/{message-index-3ws17x1g.js → message-index-yd94vt9n.js} +16 -16
- package/dist/v2/{message-time-backfill-5nf10c65.js → message-time-backfill-rz1pnpaj.js} +3 -3
- package/dist/v2/migration-worker.js +11 -11
- package/dist/v2/{project-embedding-registry-rsnf2263.js → project-embedding-registry-ja23aygk.js} +11 -11
- package/dist/v2/raw-ordinal-warmup-worker.js +17 -15
- package/dist/v2/{read-session-chunk-vtb0w2kd.js → read-session-chunk-7qs791f3.js} +13 -11
- package/dist/v2/{read-session-raw-gpcddemt.js → read-session-raw-h4azh85b.js} +3 -3
- package/dist/v2/recomp-orchestrator-ee91r9s6.js +59 -0
- package/dist/v2/{safe-notification-target-y3p1hce9.js → safe-notification-target-936374xx.js} +2 -2
- package/dist/v2/search-pn15rr52.js +46 -0
- package/dist/v2/{send-session-notification-5aj2j7vf.js → send-session-notification-6n7chhyp.js} +6 -6
- package/dist/v2/{server-09g9pkvx.js → server-08k4zkfk.js} +50 -39
- package/dist/v2/{server-ras2sxnc.js → server-44ryn9rb.js} +9 -6
- package/dist/v2/{server-158ehmk2.js → server-4easnf78.js} +19 -19
- package/dist/v2/{server-ww9nr8pe.js → server-4gz0xkrc.js} +5 -5
- package/dist/v2/{server-d6g4whc2.js → server-4qr18rfg.js} +3 -3
- package/dist/v2/{server-f9py7s7a.js → server-4rs8sm06.js} +5 -5
- package/dist/v2/{server-yezz0cp2.js → server-63ha7f0f.js} +3 -27
- package/dist/v2/{server-3t0q2cqx.js → server-7dv9wt9r.js} +1 -1
- package/dist/v2/{server-cw6521wn.js → server-7e087rvk.js} +2 -0
- package/dist/v2/{server-hb6xhh9q.js → server-988cqjme.js} +6 -3
- package/dist/v2/{server-keswwkvv.js → server-9a6bwc12.js} +4 -4
- package/dist/v2/{server-t4k4qexw.js → server-9e5r8y60.js} +5 -1
- package/dist/v2/{server-7ekna9zs.js → server-adfte03x.js} +2 -2
- package/dist/v2/{server-9zqewm6g.js → server-ak7w74j9.js} +4 -4
- package/dist/v2/{server-387vkhjq.js → server-bx59ezg6.js} +4 -3
- package/dist/v2/{server-676xw7at.js → server-ckrb5rm8.js} +1 -1
- package/dist/v2/{server-wrem2nmz.js → server-cxsr0ng6.js} +15 -3
- package/dist/v2/{server-t528t8qm.js → server-hn9fb3v0.js} +2 -2
- package/dist/v2/{server-qn23p4h7.js → server-j3dm74ey.js} +9 -9
- package/dist/v2/{server-yd01snxq.js → server-jjsf29aq.js} +4 -4
- package/dist/v2/server-knvkbfvh.js +25 -0
- package/dist/v2/{server-cm4hmxyk.js → server-n78avt2p.js} +1 -1
- package/dist/v2/{server-btgnsv7w.js → server-njnx39q2.js} +6 -3
- package/dist/v2/{server-6a9mxnb2.js → server-npm52h2q.js} +4 -3
- package/dist/v2/{server-vb7pbd9p.js → server-nveratm5.js} +1 -1
- package/dist/v2/{server-7skbfb81.js → server-q360kdb8.js} +121 -51
- package/dist/v2/{server-kzns2hbz.js → server-s6jqh8bj.js} +1 -1
- package/dist/v2/{server-6byqfbqf.js → server-shme41gj.js} +1 -1
- package/dist/v2/{server-0nnd4bry.js → server-wafzvyhg.js} +63 -19
- package/dist/v2/{server-fby0cxbq.js → server-xj4mewze.js} +304 -92
- package/dist/v2/{server-aa9w15cs.js → server-y5g32dhq.js} +88 -81
- package/dist/v2/{server-x2r63c0x.js → server-yak3sxya.js} +7 -7
- package/dist/v2/{server-4tn95znb.js → server-zrwaj29a.js} +2 -2
- package/dist/v2/server.js +9 -8
- package/dist/v2/{sqlite-d7edbk1s.js → sqlite-4pqyynrs.js} +3 -1
- package/dist/v2/{storage-memory-af5zdz98.js → storage-memory-j3v3hc83.js} +2 -2
- package/dist/v2/{storage-tags-d47bpaqa.js → storage-tags-spa92sgj.js} +5 -5
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/{wrapup-orchestrator-cahk37n7.js → wrapup-orchestrator-5wxy1ggv.js} +38 -35
- package/dist/wrapup-orchestrator-gv08c6f9.js +47 -0
- package/package.json +3 -3
- package/src/config/compaction-accessor-guard.test.ts +3 -0
- package/src/features/magic-context/dreamer/cron.ts +8 -0
- package/src/shared/history-owner.test.ts +60 -0
- package/src/shared/history-owner.ts +43 -0
- package/src/shared/host-stall-profiler-node.ts +3 -1
- package/src/shared/host-stall-profiler.ts +3 -1
- package/src/shared/off-thread-migration-clock.test.ts +80 -10
- package/src/shared/off-thread-migration-clock.ts +37 -13
- 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/redaction.test.ts +16 -0
- package/src/shared/redaction.ts +8 -1
- package/src/shared/root-async-context.probe.mjs +36 -0
- package/src/shared/root-async-context.test.ts +49 -0
- package/src/shared/rpc-server.ts +27 -23
- package/src/shared/sqlite-busy-budget-review.test.ts +291 -0
- package/src/shared/sqlite-foreground-wait.test.ts +253 -1
- package/src/shared/sqlite-writer-diagnostics.test.ts +31 -0
- package/src/shared/sqlite.ts +112 -30
- package/src/shared/tag-transcript.ts +118 -0
- package/src/shared/user-facing-codes.ts +2 -2
- package/dist/embedding-backfill-dtjmyktb.js +0 -21
- package/dist/recomp-orchestrator-1d08g57a.js +0 -60
- package/dist/v2/embedding-backfill-cg4rv90f.js +0 -20
- package/dist/v2/recomp-orchestrator-v64r4s4r.js +0 -59
- package/dist/v2/search-bpa4fxq1.js +0 -46
- package/dist/wrapup-orchestrator-mqp0v195.js +0 -47
|
@@ -15,7 +15,7 @@ import {
|
|
|
15
15
|
log2,
|
|
16
16
|
sessionLog2,
|
|
17
17
|
getLoggerDiagnostics2
|
|
18
|
-
} from "./index-
|
|
18
|
+
} from "./index-mvvephtj.js";
|
|
19
19
|
import {
|
|
20
20
|
resolveOpenCodeDbPath,
|
|
21
21
|
assertOpenCodeStoreGeneration,
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
claimOpenCodeDbDiagnosticOnce
|
|
29
29
|
} from "./index-58e3y90n.js";
|
|
30
30
|
import {
|
|
31
|
+
inRootAsyncContext2,
|
|
31
32
|
Database2,
|
|
32
33
|
getSqliteDatabasePath2,
|
|
33
34
|
getSqliteMemoryStats2,
|
|
@@ -38,7 +39,7 @@ import {
|
|
|
38
39
|
SqliteAcquisitionBusyError2,
|
|
39
40
|
withAsyncPrivilegedWriter2,
|
|
40
41
|
indexCoordinationInput2
|
|
41
|
-
} from "./index-
|
|
42
|
+
} from "./index-wafzvyhg.js";
|
|
42
43
|
import {
|
|
43
44
|
shouldSkipHomeProjectMemory,
|
|
44
45
|
ProjectIdentityError,
|
|
@@ -53,7 +54,7 @@ import {
|
|
|
53
54
|
storedPathBelongsToIdentity,
|
|
54
55
|
beginBootQuietPeriod,
|
|
55
56
|
scheduleAfterBootQuiet
|
|
56
|
-
} from "./index-
|
|
57
|
+
} from "./index-0jz47061.js";
|
|
57
58
|
import {
|
|
58
59
|
recordSessionProjectIdentity,
|
|
59
60
|
hasRecordedSessionProjectIdentity,
|
|
@@ -80,7 +81,7 @@ import {
|
|
|
80
81
|
drainCommitBacklogForProject2,
|
|
81
82
|
embedSessionCompartmentChunks2,
|
|
82
83
|
getEmbeddingCoverageStatus2
|
|
83
|
-
} from "./index-
|
|
84
|
+
} from "./index-rg1cezmj.js";
|
|
84
85
|
import {
|
|
85
86
|
hasTrustedAbsoluteWall,
|
|
86
87
|
applyProvenInputFloor,
|
|
@@ -92,7 +93,7 @@ import {
|
|
|
92
93
|
deriveTriggerBudget2,
|
|
93
94
|
resolveKnownHistorianContextLimit2,
|
|
94
95
|
resolveHistorianProducerLimits2
|
|
95
|
-
} from "./index-
|
|
96
|
+
} from "./index-jw4gbfkv.js";
|
|
96
97
|
import {
|
|
97
98
|
resolveModelCalibration,
|
|
98
99
|
calibrateBuckets,
|
|
@@ -106,10 +107,11 @@ import {
|
|
|
106
107
|
estimateTokens,
|
|
107
108
|
estimateFixedPromptTokens,
|
|
108
109
|
normalizeText
|
|
109
|
-
} from "./index-
|
|
110
|
+
} from "./index-gjvjh960.js";
|
|
110
111
|
import {
|
|
111
112
|
protectedToolTokenCount,
|
|
112
113
|
peelLeadingMcTagNotation,
|
|
114
|
+
isThinkingPart,
|
|
113
115
|
isRecord,
|
|
114
116
|
contentTagOwnerMessageId,
|
|
115
117
|
normalizeTodoStateJson,
|
|
@@ -142,10 +144,11 @@ import {
|
|
|
142
144
|
getDroppedTagsByNumbers2,
|
|
143
145
|
getMaxDroppedTagNumber2,
|
|
144
146
|
getTagById2
|
|
145
|
-
} from "./index-
|
|
147
|
+
} from "./index-xpn05jxq.js";
|
|
146
148
|
import {
|
|
147
|
-
observeTemporalDecisions
|
|
148
|
-
|
|
149
|
+
observeTemporalDecisions,
|
|
150
|
+
stableStringify
|
|
151
|
+
} from "./index-bd9cjab3.js";
|
|
149
152
|
import {
|
|
150
153
|
withContentLanguageDirective,
|
|
151
154
|
parseCron,
|
|
@@ -158,13 +161,13 @@ import {
|
|
|
158
161
|
DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
159
162
|
DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
160
163
|
DREAM_TASK_PROMOTION_DEFAULTS
|
|
161
|
-
} from "./index-
|
|
164
|
+
} from "./index-w28y7d0z.js";
|
|
162
165
|
import {
|
|
163
166
|
isRawCompactionSummaryInfo2,
|
|
164
167
|
extractInMemoryMessageViews2,
|
|
165
168
|
buildInMemoryTailRawMessages2,
|
|
166
169
|
runSessionWarmupWorker
|
|
167
|
-
} from "./index-
|
|
170
|
+
} from "./index-angx1s0k.js";
|
|
168
171
|
import {
|
|
169
172
|
openCodeDbExists,
|
|
170
173
|
withReadOnlySessionDb,
|
|
@@ -172,10 +175,11 @@ import {
|
|
|
172
175
|
latestPersistedMessageForRecovery,
|
|
173
176
|
latestRealUserTurnIdFromOpenCodeDb,
|
|
174
177
|
findLastAssistantModelFromOpenCodeDb
|
|
175
|
-
} from "./index-
|
|
178
|
+
} from "./index-q76br5zn.js";
|
|
176
179
|
import {
|
|
177
180
|
expandToolPart,
|
|
178
181
|
estimateTrueRawMessageTokens,
|
|
182
|
+
isTextPart,
|
|
179
183
|
toolPartHasUserAnswer,
|
|
180
184
|
DreamTokenBudgetExceeded,
|
|
181
185
|
isEditTool,
|
|
@@ -185,6 +189,8 @@ import {
|
|
|
185
189
|
sessionDecisionCalibration,
|
|
186
190
|
getProtectionWindowForSession,
|
|
187
191
|
ensureSessionMetaRow,
|
|
192
|
+
withReplayEnvelopeSnapshot,
|
|
193
|
+
invalidateReplayEnvelopeSnapshot,
|
|
188
194
|
isRustMarkerAdmissionFenced,
|
|
189
195
|
setRustMarkerAdmissionFence,
|
|
190
196
|
readReplayEnvelope,
|
|
@@ -268,11 +274,16 @@ import {
|
|
|
268
274
|
createFinalWireUsageTracker,
|
|
269
275
|
estimateFinalWireInputTokens,
|
|
270
276
|
estimateAppendedWireTokens,
|
|
277
|
+
partHasCompletedResult,
|
|
278
|
+
extractToolCallObservation,
|
|
279
|
+
ToolMutationBatch,
|
|
280
|
+
createToolDropTarget,
|
|
271
281
|
setRawMessageProvider2,
|
|
272
282
|
cleanUserText2,
|
|
273
283
|
withRawSessionMessageCache2,
|
|
274
284
|
readRawSessionMessages2,
|
|
275
285
|
visitRawSessionMessages2,
|
|
286
|
+
visitRawSessionMessagesAsync2,
|
|
276
287
|
prepareRawSessionOrdinals2,
|
|
277
288
|
primeTailRawMessageCache2,
|
|
278
289
|
primeInMemoryTailRawMessageCache2,
|
|
@@ -281,13 +292,14 @@ import {
|
|
|
281
292
|
readRawSessionMessageIdOrdinalsForRange2,
|
|
282
293
|
readRawSessionMessagePartsById2,
|
|
283
294
|
readRawSessionBoundaryEndpoints2,
|
|
295
|
+
hasRawSessionMessageById2,
|
|
284
296
|
readRawSessionMessageById2,
|
|
285
297
|
readSessionChunk2,
|
|
286
298
|
readRawSessionSeedTail2
|
|
287
|
-
} from "./index-
|
|
299
|
+
} from "./index-9g1c4bt9.js";
|
|
288
300
|
import {
|
|
289
301
|
getMeasuredToolDefinitionTokens
|
|
290
|
-
} from "./index-
|
|
302
|
+
} from "./index-8kk7yh6m.js";
|
|
291
303
|
import {
|
|
292
304
|
CANONICAL_DREAM_TASKS,
|
|
293
305
|
DREAM_TASK_CAPABILITIES,
|
|
@@ -315,20 +327,17 @@ import {
|
|
|
315
327
|
runSqliteOptimize,
|
|
316
328
|
openDatabase,
|
|
317
329
|
openCurrentDatabase
|
|
318
|
-
} from "./index-
|
|
330
|
+
} from "./index-zf9nydbd.js";
|
|
319
331
|
import {
|
|
320
332
|
registerOwnRpcServerInstance,
|
|
321
333
|
rpcPortDir,
|
|
322
334
|
rpcPortFilePath,
|
|
323
335
|
parseRpcPortFile,
|
|
324
336
|
inspectProcessesAsync
|
|
325
|
-
} from "./index-
|
|
337
|
+
} from "./index-q28hsbpg.js";
|
|
326
338
|
import {
|
|
327
339
|
configureContextDatabasePragmas2
|
|
328
340
|
} from "./index-fb3zxn06.js";
|
|
329
|
-
import {
|
|
330
|
-
canonicalProjectDirectory
|
|
331
|
-
} from "./index-bg5qqene.js";
|
|
332
341
|
import {
|
|
333
342
|
unescapeXml,
|
|
334
343
|
resolveWorkspaceShareCategories,
|
|
@@ -337,7 +346,7 @@ import {
|
|
|
337
346
|
resolveStoredPathWorkspaceIdentity,
|
|
338
347
|
storedPathBelongsToWorkspace,
|
|
339
348
|
computeWorkspaceEpochFingerprint
|
|
340
|
-
} from "./index-
|
|
349
|
+
} from "./index-qgp5vnt4.js";
|
|
341
350
|
import {
|
|
342
351
|
V2_MEMORY_CATEGORIES,
|
|
343
352
|
CATEGORY_PRIORITY
|
|
@@ -394,6 +403,8 @@ import {
|
|
|
394
403
|
resolveLkgModelKeys,
|
|
395
404
|
createLkgEntryProjector,
|
|
396
405
|
captureLkgSlot,
|
|
406
|
+
validateAnthropicReasoningRuns,
|
|
407
|
+
validateLkgSeam,
|
|
397
408
|
replayLkg,
|
|
398
409
|
coldStartRawServedIndex,
|
|
399
410
|
coldStartUncapturedReplay,
|
|
@@ -509,7 +520,7 @@ import {
|
|
|
509
520
|
snapRangeToCompartments,
|
|
510
521
|
getActiveCompartmentRun,
|
|
511
522
|
startCompartmentAgent
|
|
512
|
-
} from "./index-
|
|
523
|
+
} from "./index-hxrvx6cy.js";
|
|
513
524
|
import {
|
|
514
525
|
SubcClient,
|
|
515
526
|
connectionFileExists,
|
|
@@ -517,7 +528,7 @@ import {
|
|
|
517
528
|
toSynapseLaneDescriptor,
|
|
518
529
|
formatSynapseLaneDescriptor,
|
|
519
530
|
SynapseEmbeddingProvider
|
|
520
|
-
} from "./index-
|
|
531
|
+
} from "./index-kvw6xew3.js";
|
|
521
532
|
import {
|
|
522
533
|
BoundedSessionMap,
|
|
523
534
|
LkgRecoveryFenceError,
|
|
@@ -538,7 +549,7 @@ import {
|
|
|
538
549
|
indexSingleMessage2,
|
|
539
550
|
indexMessagesAfterOrdinal2,
|
|
540
551
|
sweepOrphanedOpenCodeMessageIndexes2
|
|
541
|
-
} from "./index-
|
|
552
|
+
} from "./index-b4gcb3rk.js";
|
|
542
553
|
import {
|
|
543
554
|
renderUserFacingFailure,
|
|
544
555
|
userFacingFailureCode,
|
|
@@ -582,7 +593,7 @@ import {
|
|
|
582
593
|
readGitFileChangeTimesSince,
|
|
583
594
|
verificationFileExists,
|
|
584
595
|
normalizeVerificationFiles
|
|
585
|
-
} from "./index-
|
|
596
|
+
} from "./index-ydjgz36f.js";
|
|
586
597
|
import {
|
|
587
598
|
registerNotificationSink2,
|
|
588
599
|
pushNotification2,
|
|
@@ -592,7 +603,7 @@ import {
|
|
|
592
603
|
} from "./index-x8a7jmkh.js";
|
|
593
604
|
import {
|
|
594
605
|
getLocalEmbeddingNativeMemoryStats
|
|
595
|
-
} from "./index-
|
|
606
|
+
} from "./index-bmwfzz28.js";
|
|
596
607
|
import {
|
|
597
608
|
saveEmbeddingIfHashMatches,
|
|
598
609
|
invalidateProject2,
|
|
@@ -600,7 +611,7 @@ import {
|
|
|
600
611
|
} from "./index-4dhv7mqz.js";
|
|
601
612
|
import {
|
|
602
613
|
cosineSimilarity
|
|
603
|
-
} from "./index-
|
|
614
|
+
} from "./index-a43xq1pg.js";
|
|
604
615
|
import {
|
|
605
616
|
computeCueContentHash,
|
|
606
617
|
hasMuralCueColumns,
|
|
@@ -625,7 +636,7 @@ import {
|
|
|
625
636
|
mergeMemoryStats2,
|
|
626
637
|
archiveMemory2,
|
|
627
638
|
getMemoryCountsByStatus2
|
|
628
|
-
} from "./index-
|
|
639
|
+
} from "./index-n78avt2p.js";
|
|
629
640
|
import {
|
|
630
641
|
renderSingleStoreMigrationRequiredRefusal,
|
|
631
642
|
SingleStoreMigrationRequiredError,
|
|
@@ -641,23 +652,25 @@ import {
|
|
|
641
652
|
SubcModuleTransport,
|
|
642
653
|
indexCommitsForProject,
|
|
643
654
|
embedUnembeddedCommits,
|
|
655
|
+
withMessageFtsSessionFilter,
|
|
644
656
|
createUnifiedSearchDiagnostics2,
|
|
645
657
|
parseIdShapedQuery2,
|
|
646
658
|
resolveMemoriesByIdsForSearch2,
|
|
647
659
|
unifiedSearch2,
|
|
648
660
|
formatSearchResults2
|
|
649
|
-
} from "./index-
|
|
661
|
+
} from "./index-2rw244rh.js";
|
|
650
662
|
import {
|
|
651
663
|
flushIgnoredMessages2,
|
|
652
664
|
clearIgnoredMessages2,
|
|
653
665
|
observeIgnoredNotificationEvent2,
|
|
654
666
|
sendStatusNotification2
|
|
655
|
-
} from "./index-
|
|
667
|
+
} from "./index-pgy3h49n.js";
|
|
656
668
|
import {
|
|
657
669
|
setRecompStarting2,
|
|
658
670
|
setRecompTerminal2
|
|
659
|
-
} from "./index-
|
|
671
|
+
} from "./index-xf6k8szp.js";
|
|
660
672
|
import {
|
|
673
|
+
makeToolCompositeKey,
|
|
661
674
|
searchMessageHistoryOffThread,
|
|
662
675
|
findSessionId,
|
|
663
676
|
findLastUserMessageId,
|
|
@@ -706,7 +719,7 @@ import {
|
|
|
706
719
|
abortSessionFailClosed2,
|
|
707
720
|
evaluateEmergencyFailClosed2,
|
|
708
721
|
runPostTransformPhase2
|
|
709
|
-
} from "./index-
|
|
722
|
+
} from "./index-gzg9ekc1.js";
|
|
710
723
|
import {
|
|
711
724
|
ANNOUNCEMENT_VERSION2,
|
|
712
725
|
ANNOUNCEMENT_FEATURES2,
|
|
@@ -723,6 +736,9 @@ import {
|
|
|
723
736
|
import {
|
|
724
737
|
computeNormalizedHash
|
|
725
738
|
} from "./index-2bvekkfy.js";
|
|
739
|
+
import {
|
|
740
|
+
canonicalProjectDirectory
|
|
741
|
+
} from "./index-knvkbfvh.js";
|
|
726
742
|
import {
|
|
727
743
|
getErrorMessage,
|
|
728
744
|
describeError
|
|
@@ -745,7 +761,7 @@ import {
|
|
|
745
761
|
} from "./index-8ajstryz.js";
|
|
746
762
|
import {
|
|
747
763
|
logSlowWriteTransaction
|
|
748
|
-
} from "./index-
|
|
764
|
+
} from "./index-150zz6fh.js";
|
|
749
765
|
|
|
750
766
|
// src/features/magic-context/dreamer/open-opencode-db.ts
|
|
751
767
|
function openOpenCodeDb() {
|
|
@@ -1510,7 +1526,7 @@ function startLeaseHeartbeat(db, holderId, leaseKey, onLost, intervalOrAcquisiti
|
|
|
1510
1526
|
}
|
|
1511
1527
|
};
|
|
1512
1528
|
beat();
|
|
1513
|
-
const timer = lost ? undefined : setInterval(() => withSqliteBackgroundWriter2(beat), intervalMs);
|
|
1529
|
+
const timer = lost ? undefined : inRootAsyncContext2(() => setInterval(() => withSqliteBackgroundWriter2(beat), intervalMs));
|
|
1514
1530
|
return {
|
|
1515
1531
|
stop: () => {
|
|
1516
1532
|
if (timer)
|
|
@@ -2797,6 +2813,25 @@ async function runHiddenSingleShotPrompt(args) {
|
|
|
2797
2813
|
});
|
|
2798
2814
|
promptSettled = true;
|
|
2799
2815
|
return { validated: run.validated, completion: run.output, childSessionId: handle.id };
|
|
2816
|
+
} catch (error) {
|
|
2817
|
+
if (args.onFailureOutput) {
|
|
2818
|
+
let timer;
|
|
2819
|
+
try {
|
|
2820
|
+
const completion = await Promise.race([
|
|
2821
|
+
args.executor.collect(handle, 200),
|
|
2822
|
+
new Promise((resolve) => {
|
|
2823
|
+
timer = setTimeout(() => resolve(null), 5000);
|
|
2824
|
+
})
|
|
2825
|
+
]);
|
|
2826
|
+
if (completion)
|
|
2827
|
+
args.onFailureOutput(completion);
|
|
2828
|
+
} catch (readError) {
|
|
2829
|
+
log2(`${args.callContext}: failed to collect interrupted output: ${String(readError)}`);
|
|
2830
|
+
} finally {
|
|
2831
|
+
clearTimeout(timer);
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
throw error;
|
|
2800
2835
|
} finally {
|
|
2801
2836
|
await args.executor.close(handle, {
|
|
2802
2837
|
promptSettled,
|
|
@@ -5951,10 +5986,10 @@ async function probeWakePlaneCatalog() {
|
|
|
5951
5986
|
if (!await connectionFileExists(file)) {
|
|
5952
5987
|
throw new Error("subc connection is not configured");
|
|
5953
5988
|
}
|
|
5954
|
-
const client = await SubcClient.connect({
|
|
5989
|
+
const client = await inRootAsyncContext2(() => SubcClient.connect({
|
|
5955
5990
|
connectionFile: file,
|
|
5956
5991
|
handshakeTimeoutMs: WAKE_PLANE_HANDSHAKE_TIMEOUT_MS
|
|
5957
|
-
});
|
|
5992
|
+
}));
|
|
5958
5993
|
try {
|
|
5959
5994
|
return await client.catalogList();
|
|
5960
5995
|
} finally {
|
|
@@ -6626,31 +6661,33 @@ function snapshotMaintainDocsFiles(docsDir) {
|
|
|
6626
6661
|
import { createHash as createHash5 } from "node:crypto";
|
|
6627
6662
|
|
|
6628
6663
|
// src/features/magic-context/dreamer/map-memories-prompt.ts
|
|
6664
|
+
import { execFile as execFile2 } from "node:child_process";
|
|
6629
6665
|
import { existsSync as existsSync4, statSync } from "node:fs";
|
|
6630
6666
|
import path3 from "node:path";
|
|
6667
|
+
import { promisify as promisify2 } from "node:util";
|
|
6631
6668
|
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.
|
|
6632
6669
|
|
|
6633
6670
|
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.
|
|
6634
6671
|
|
|
6635
|
-
Tools (read-only): read, grep, glob.
|
|
6672
|
+
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.
|
|
6636
6673
|
|
|
6637
6674
|
For each memory decide ONE of:
|
|
6638
|
-
- Backing files found → the
|
|
6675
|
+
- Backing files found → the specific repo-relative paths whose code the memory is about; do not chase every caller or related implementation.
|
|
6639
6676
|
- 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.
|
|
6640
6677
|
|
|
6641
|
-
Output ONE XML manifest
|
|
6678
|
+
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:
|
|
6642
6679
|
<mappings>
|
|
6643
6680
|
<memory id="N" files="path/a.ts,path/b.ts"/>
|
|
6644
6681
|
<memory id="M" independent="true"/>
|
|
6645
6682
|
</mappings>
|
|
6646
6683
|
|
|
6647
6684
|
Rules:
|
|
6648
|
-
- Every input memory id MUST appear exactly once.
|
|
6685
|
+
- Every decided input memory id MUST appear exactly once. Omit uncertain ids rather than inventing backing files or declaring them independent.
|
|
6649
6686
|
- files: repo-relative, comma-separated, no spaces inside a path. Only files that actually exist and genuinely back the memory.
|
|
6650
6687
|
- 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".
|
|
6651
6688
|
- 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.
|
|
6652
6689
|
- Prefer the most specific file(s); do not pad with tangential files. Most memories map to one file; some to a few.
|
|
6653
|
-
-
|
|
6690
|
+
- Mark independent="true" only for the file-independent cases above; an investigation that runs out of calls stays unmapped.`;
|
|
6654
6691
|
var MAX_SEED_PATHS_PER_MEMORY = 3;
|
|
6655
6692
|
var PATH_PATTERN = "`?((?:[\\w.-]+\\/)+[\\w.-]+\\.(?:ts|tsx|js|jsx|mjs|cjs|rs|go|py|json|jsonc|sql|toml|sh))`?";
|
|
6656
6693
|
function extractMemoryCandidatePaths(content, repoDir) {
|
|
@@ -6672,10 +6709,65 @@ function extractMemoryCandidatePaths(content, repoDir) {
|
|
|
6672
6709
|
}
|
|
6673
6710
|
return [...found];
|
|
6674
6711
|
}
|
|
6712
|
+
var execFileAsync2 = promisify2(execFile2);
|
|
6713
|
+
async function seedIdentifierCandidates(memories, repoDir) {
|
|
6714
|
+
const identifiers = new Map(memories.filter((memory) => memory.candidates.length === 0).map((memory) => [
|
|
6715
|
+
memory.id,
|
|
6716
|
+
[
|
|
6717
|
+
...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) ?? [])
|
|
6718
|
+
].slice(0, 3)
|
|
6719
|
+
]));
|
|
6720
|
+
const terms = [...new Set([...identifiers.values()].flat())];
|
|
6721
|
+
if (terms.length === 0)
|
|
6722
|
+
return memories;
|
|
6723
|
+
let stdout;
|
|
6724
|
+
try {
|
|
6725
|
+
const result = await execFileAsync2("git", [
|
|
6726
|
+
"-c",
|
|
6727
|
+
"core.quotePath=false",
|
|
6728
|
+
"grep",
|
|
6729
|
+
"--no-color",
|
|
6730
|
+
"-n",
|
|
6731
|
+
"-I",
|
|
6732
|
+
"-F",
|
|
6733
|
+
...terms.flatMap((term) => ["-e", term]),
|
|
6734
|
+
"--",
|
|
6735
|
+
...["ts", "tsx", "js", "jsx", "mjs", "cjs", "rs", "go", "py", "sql", "sh"].map((extension) => `*.${extension}`)
|
|
6736
|
+
], {
|
|
6737
|
+
cwd: repoDir,
|
|
6738
|
+
encoding: "utf8",
|
|
6739
|
+
timeout: 2000,
|
|
6740
|
+
maxBuffer: 256 * 1024,
|
|
6741
|
+
windowsHide: true,
|
|
6742
|
+
killSignal: "SIGKILL"
|
|
6743
|
+
});
|
|
6744
|
+
stdout = result.stdout;
|
|
6745
|
+
} catch {
|
|
6746
|
+
return memories;
|
|
6747
|
+
}
|
|
6748
|
+
const matches = stdout.split(`
|
|
6749
|
+
`).flatMap((line) => {
|
|
6750
|
+
const match = line.match(/^([^:]+):\d+:(.*)$/);
|
|
6751
|
+
return match ? [{ file: match[1], text: match[2] }] : [];
|
|
6752
|
+
});
|
|
6753
|
+
return memories.map((memory) => {
|
|
6754
|
+
const names = identifiers.get(memory.id);
|
|
6755
|
+
if (!names?.length)
|
|
6756
|
+
return memory;
|
|
6757
|
+
const files = new Map;
|
|
6758
|
+
for (const match of matches) {
|
|
6759
|
+
const score = names.filter((name) => match.text.includes(name)).length;
|
|
6760
|
+
if (score)
|
|
6761
|
+
files.set(match.file, Math.max(files.get(match.file) ?? 0, score));
|
|
6762
|
+
}
|
|
6763
|
+
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);
|
|
6764
|
+
return candidates.length ? { ...memory, candidates } : memory;
|
|
6765
|
+
});
|
|
6766
|
+
}
|
|
6675
6767
|
function buildMapMemoriesPrompt(projectPath, memories) {
|
|
6676
6768
|
const list = memories.map((m) => {
|
|
6677
6769
|
const seed = m.candidates.length ? `
|
|
6678
|
-
Likely files (
|
|
6770
|
+
Likely files (candidate paths, confirmed to exist): ${m.candidates.join(", ")}` : "";
|
|
6679
6771
|
return `[${m.id}] ${m.category}
|
|
6680
6772
|
${m.content}${seed}`;
|
|
6681
6773
|
}).join(`
|
|
@@ -6685,13 +6777,13 @@ ${m.content}${seed}`;
|
|
|
6685
6777
|
|
|
6686
6778
|
Project: ${projectPath}
|
|
6687
6779
|
|
|
6688
|
-
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
|
|
6780
|
+
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.
|
|
6689
6781
|
|
|
6690
6782
|
<memories>
|
|
6691
6783
|
${list}
|
|
6692
6784
|
</memories>`;
|
|
6693
6785
|
}
|
|
6694
|
-
var MEMORY_ELEMENT_PATTERN = "<memory\\b([
|
|
6786
|
+
var MEMORY_ELEMENT_PATTERN = "<memory\\b([^<>]*)(?:\\/>|>([\\s\\S]*?)<\\/memory>)";
|
|
6695
6787
|
var NESTED_FILE_PATTERN = "<file\\b([^>]*)\\/?>";
|
|
6696
6788
|
function extractNestedFilePaths(inner) {
|
|
6697
6789
|
const files = [];
|
|
@@ -6749,12 +6841,78 @@ function validateMapMemoriesManifest(text, expectedIds) {
|
|
|
6749
6841
|
assertNoDuplicateManifestIds(parsed.filter((entry) => expectedIds.has(entry.id)).map((entry) => entry.id), "mappings");
|
|
6750
6842
|
return parsed;
|
|
6751
6843
|
}
|
|
6844
|
+
function parsePartialMapMemoriesManifest(text, expectedIds) {
|
|
6845
|
+
const start = text.indexOf("<mappings>");
|
|
6846
|
+
if (start < 0)
|
|
6847
|
+
return [];
|
|
6848
|
+
const entries = new Map;
|
|
6849
|
+
const conflicts = new Set;
|
|
6850
|
+
for (const match of text.slice(start).matchAll(new RegExp(MEMORY_ELEMENT_PATTERN, "gi"))) {
|
|
6851
|
+
try {
|
|
6852
|
+
const entry = parseMapMemoriesManifest(`<mappings>${match[0]}</mappings>`)[0];
|
|
6853
|
+
if (!entry || !expectedIds.has(entry.id) || conflicts.has(entry.id))
|
|
6854
|
+
continue;
|
|
6855
|
+
const previous = entries.get(entry.id);
|
|
6856
|
+
if (previous && JSON.stringify(previous) !== JSON.stringify(entry)) {
|
|
6857
|
+
entries.delete(entry.id);
|
|
6858
|
+
conflicts.add(entry.id);
|
|
6859
|
+
} else {
|
|
6860
|
+
entries.set(entry.id, entry);
|
|
6861
|
+
}
|
|
6862
|
+
} catch {}
|
|
6863
|
+
}
|
|
6864
|
+
return [...entries.values()];
|
|
6865
|
+
}
|
|
6752
6866
|
|
|
6753
6867
|
// src/features/magic-context/dreamer/map-memories.ts
|
|
6754
|
-
var MAP_BATCH_SIZE =
|
|
6868
|
+
var MAP_BATCH_SIZE = 5;
|
|
6755
6869
|
var MAP_BATCH_FLOOR_MS = 240000;
|
|
6756
6870
|
var CONSECUTIVE_TIMEOUT_LIMIT2 = 2;
|
|
6757
6871
|
var MAX_INDEPENDENT_REQUEUE_PER_RUN = MAP_BATCH_SIZE;
|
|
6872
|
+
function retryKey(project) {
|
|
6873
|
+
return `map-memories:retry:${project}`;
|
|
6874
|
+
}
|
|
6875
|
+
function readRetries(db, project) {
|
|
6876
|
+
try {
|
|
6877
|
+
const parsed = JSON.parse(getDreamState(db, retryKey(project)) ?? "{}");
|
|
6878
|
+
if (!isRecord(parsed))
|
|
6879
|
+
return {};
|
|
6880
|
+
const retries = {};
|
|
6881
|
+
for (const [id, value] of Object.entries(parsed)) {
|
|
6882
|
+
if (isRecord(value) && typeof value.content === "string" && typeof value.failures === "number" && typeof value.deferUntil === "number") {
|
|
6883
|
+
retries[id] = {
|
|
6884
|
+
content: value.content,
|
|
6885
|
+
failures: value.failures,
|
|
6886
|
+
deferUntil: value.deferUntil
|
|
6887
|
+
};
|
|
6888
|
+
}
|
|
6889
|
+
}
|
|
6890
|
+
return retries;
|
|
6891
|
+
} catch {
|
|
6892
|
+
return {};
|
|
6893
|
+
}
|
|
6894
|
+
}
|
|
6895
|
+
function contentKey(memory) {
|
|
6896
|
+
return createHash5("sha256").update(`${memory.category}
|
|
6897
|
+
${memory.content}`).digest("hex");
|
|
6898
|
+
}
|
|
6899
|
+
function isDeferred(memory, retries) {
|
|
6900
|
+
const retry = retries[memory.id];
|
|
6901
|
+
return !!retry && retry.content === contentKey(memory) && retry.deferUntil > Date.now();
|
|
6902
|
+
}
|
|
6903
|
+
function assistantText(messages) {
|
|
6904
|
+
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(`
|
|
6905
|
+
`) : "")).join(`
|
|
6906
|
+
`);
|
|
6907
|
+
}
|
|
6908
|
+
function currentManifest(text) {
|
|
6909
|
+
const start = text.lastIndexOf("<mappings>");
|
|
6910
|
+
return start < 0 ? text : text.slice(start);
|
|
6911
|
+
}
|
|
6912
|
+
function logBatchUsage(messages, committed, startedAt) {
|
|
6913
|
+
const steps = messages.filter((message) => isRecord(message) && (message.role === "assistant" || isRecord(message.info) && message.info.role === "assistant")).length;
|
|
6914
|
+
log2(`[dreamer] map-memories batch: steps=${steps} committed=${committed} steps_per_memory=${committed ? (steps / committed).toFixed(2) : "n/a"} elapsed_ms=${Date.now() - startedAt}`);
|
|
6915
|
+
}
|
|
6758
6916
|
function computeMapBatchSliceMs(remainingMs, batchesRemaining) {
|
|
6759
6917
|
return Math.min(remainingMs, Math.max(MAP_BATCH_FLOOR_MS, Math.floor(remainingMs / batchesRemaining)));
|
|
6760
6918
|
}
|
|
@@ -6776,7 +6934,7 @@ function toMapInput(memory, repoDir) {
|
|
|
6776
6934
|
candidates: extractMemoryCandidatePaths(memory.content, repoDir)
|
|
6777
6935
|
};
|
|
6778
6936
|
}
|
|
6779
|
-
function selectMapMemoryInputs(db, projectIdentity, repoDir) {
|
|
6937
|
+
function selectMapMemoryInputs(db, projectIdentity, repoDir, includeDeferred = false) {
|
|
6780
6938
|
const active = getMemoriesByProject2(db, projectIdentity);
|
|
6781
6939
|
const activeIds = active.map((m) => m.id);
|
|
6782
6940
|
const unmapped = new Set(getUnmappedMemoryIds(db, activeIds));
|
|
@@ -6795,7 +6953,8 @@ function selectMapMemoryInputs(db, projectIdentity, repoDir) {
|
|
|
6795
6953
|
if (requeue.length >= MAX_INDEPENDENT_REQUEUE_PER_RUN)
|
|
6796
6954
|
break;
|
|
6797
6955
|
}
|
|
6798
|
-
|
|
6956
|
+
const retries = readRetries(db, projectIdentity);
|
|
6957
|
+
return [...unmappedInputs, ...requeue].filter((memory) => includeDeferred || !isDeferred(memory, retries));
|
|
6799
6958
|
}
|
|
6800
6959
|
async function mapMemories(args) {
|
|
6801
6960
|
const result = {
|
|
@@ -6805,14 +6964,21 @@ async function mapMemories(args) {
|
|
|
6805
6964
|
remaining: 0,
|
|
6806
6965
|
complete: true
|
|
6807
6966
|
};
|
|
6808
|
-
const
|
|
6967
|
+
const allInputs = selectMapMemoryInputs(args.db, args.projectIdentity, args.sessionDirectory, true);
|
|
6968
|
+
const retries = readRetries(args.db, args.projectIdentity);
|
|
6969
|
+
const activeIds = new Set(allInputs.map((memory) => String(memory.id)));
|
|
6970
|
+
for (const id of Object.keys(retries))
|
|
6971
|
+
if (!activeIds.has(id))
|
|
6972
|
+
delete retries[id];
|
|
6973
|
+
const inputs = allInputs.filter((memory) => !isDeferred(memory, retries));
|
|
6974
|
+
result.remaining = allInputs.length;
|
|
6975
|
+
result.complete = result.remaining === 0;
|
|
6809
6976
|
if (inputs.length === 0)
|
|
6810
6977
|
return result;
|
|
6811
6978
|
const batches = [];
|
|
6812
6979
|
for (let i = 0;i < inputs.length; i += MAP_BATCH_SIZE) {
|
|
6813
6980
|
batches.push({ inputs: inputs.slice(i, i + MAP_BATCH_SIZE), isOmissionRetry: false });
|
|
6814
6981
|
}
|
|
6815
|
-
result.remaining = inputs.length;
|
|
6816
6982
|
const abortController = new AbortController;
|
|
6817
6983
|
const heartbeat = startLeaseHeartbeat(args.db, args.holderId, args.leaseKey, (reason) => abortController.abort(new Error(reason)), args.leaseAcquisition);
|
|
6818
6984
|
try {
|
|
@@ -6835,6 +7001,24 @@ async function mapMemories(args) {
|
|
|
6835
7001
|
break;
|
|
6836
7002
|
const outcome = await mapOneBatch(args, batch.inputs, sliceMs, abortController.signal);
|
|
6837
7003
|
const committed = outcome.mapped + outcome.independent;
|
|
7004
|
+
runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
|
|
7005
|
+
const committedIds = new Set(outcome.committedIds);
|
|
7006
|
+
for (const memory of batch.inputs) {
|
|
7007
|
+
if (committedIds.has(memory.id)) {
|
|
7008
|
+
delete retries[memory.id];
|
|
7009
|
+
continue;
|
|
7010
|
+
}
|
|
7011
|
+
const content = contentKey(memory);
|
|
7012
|
+
const prior = retries[memory.id];
|
|
7013
|
+
const failures = (prior?.content === content ? prior.failures : 0) + 1;
|
|
7014
|
+
retries[memory.id] = {
|
|
7015
|
+
content,
|
|
7016
|
+
failures,
|
|
7017
|
+
deferUntil: failures < 2 ? 0 : Date.now() + Math.min(24, 2 ** (failures - 2)) * 3600000
|
|
7018
|
+
};
|
|
7019
|
+
}
|
|
7020
|
+
setDreamState(args.db, retryKey(args.projectIdentity), JSON.stringify(retries));
|
|
7021
|
+
});
|
|
6838
7022
|
result.mapped += outcome.mapped;
|
|
6839
7023
|
result.independent += outcome.independent;
|
|
6840
7024
|
result.remaining -= committed;
|
|
@@ -6844,8 +7028,8 @@ async function mapMemories(args) {
|
|
|
6844
7028
|
}
|
|
6845
7029
|
if (outcome.requeue?.length) {
|
|
6846
7030
|
if (!batch.isOmissionRetry) {
|
|
6847
|
-
batches.
|
|
6848
|
-
inputs: outcome.requeue,
|
|
7031
|
+
batches.push({
|
|
7032
|
+
inputs: outcome.requeue.filter((memory) => !isDeferred(memory, retries)),
|
|
6849
7033
|
isOmissionRetry: true
|
|
6850
7034
|
});
|
|
6851
7035
|
log2(`[dreamer] map-memories: committed ${committed}/${batch.inputs.length} mapping(s); requeueing ${outcome.requeue.length} omitted id(s) in a targeted retry`);
|
|
@@ -6853,12 +7037,12 @@ async function mapMemories(args) {
|
|
|
6853
7037
|
log2(`[dreamer] map-memories: targeted retry still omitted ${outcome.requeue.length} id(s); leaving them unmapped for the next run`);
|
|
6854
7038
|
}
|
|
6855
7039
|
}
|
|
6856
|
-
if (outcome.failure?.class === "timeout") {
|
|
7040
|
+
if (outcome.failure?.class === "timeout" && committed === 0) {
|
|
6857
7041
|
consecutiveTimeouts += 1;
|
|
6858
7042
|
timeoutStreakElapsedMs.push(outcome.failure.elapsedMs);
|
|
6859
7043
|
if (consecutiveTimeouts >= CONSECUTIVE_TIMEOUT_LIMIT2) {
|
|
6860
7044
|
result.stopReason = "timeout-circuit-breaker";
|
|
6861
|
-
log2(`[dreamer] map-memories starvation: circuit breaker tripped after ${consecutiveTimeouts} consecutive batch timeouts
|
|
7045
|
+
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`);
|
|
6862
7046
|
break;
|
|
6863
7047
|
}
|
|
6864
7048
|
} else {
|
|
@@ -6878,12 +7062,13 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
6878
7062
|
let promptSettled = false;
|
|
6879
7063
|
const startedAt = Date.now();
|
|
6880
7064
|
let budgetFinalized = false;
|
|
7065
|
+
let failedCompletion;
|
|
6881
7066
|
const onBudgetUpdate = (state) => {
|
|
6882
7067
|
budgetFinalized ||= state.finalizeFired;
|
|
6883
7068
|
args.onBudgetUpdate?.(state);
|
|
6884
7069
|
};
|
|
6885
7070
|
try {
|
|
6886
|
-
const prompt = buildMapMemoriesPrompt(args.projectIdentity, batch);
|
|
7071
|
+
const prompt = buildMapMemoriesPrompt(args.projectIdentity, await seedIdentifierCandidates(batch, args.sessionDirectory));
|
|
6887
7072
|
if (args.hiddenCompletionExecutor) {
|
|
6888
7073
|
const run = await runHiddenSingleShotPrompt({
|
|
6889
7074
|
executor: args.hiddenCompletionExecutor,
|
|
@@ -6899,14 +7084,18 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
6899
7084
|
fallbackModels: args.fallbackModels,
|
|
6900
7085
|
timeoutMs: sliceMs,
|
|
6901
7086
|
signal,
|
|
6902
|
-
|
|
7087
|
+
onFailureOutput: (completion) => {
|
|
7088
|
+
failedCompletion = completion;
|
|
7089
|
+
},
|
|
7090
|
+
parse: (text, completion) => validateMapMemoriesManifest(currentManifest(assistantText(completion.messages ?? []) || text), new Set(batch.map((memory) => memory.id)))
|
|
6903
7091
|
});
|
|
6904
7092
|
recordInvocation2(args, startedAt, {
|
|
6905
7093
|
status: "completed",
|
|
6906
7094
|
messages: run.completion.messages ?? []
|
|
6907
7095
|
});
|
|
6908
|
-
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
|
|
6909
|
-
|
|
7096
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
|
|
7097
|
+
logBatchUsage(run.completion.messages ?? [], outcome.mapped + outcome.independent, startedAt);
|
|
7098
|
+
const returnedIds = new Set(outcome.committedIds);
|
|
6910
7099
|
return {
|
|
6911
7100
|
...outcome,
|
|
6912
7101
|
requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
|
|
@@ -6949,7 +7138,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
6949
7138
|
fetchOutput: async () => {
|
|
6950
7139
|
const messagesResponse = await client.session.messages({
|
|
6951
7140
|
path: { id: agentSessionId },
|
|
6952
|
-
query: { directory: args.sessionDirectory, limit:
|
|
7141
|
+
query: { directory: args.sessionDirectory, limit: 200 }
|
|
6953
7142
|
});
|
|
6954
7143
|
return normalizeSDKResponse(messagesResponse, [], {
|
|
6955
7144
|
preferResponseOnMissingData: true
|
|
@@ -6959,7 +7148,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
6959
7148
|
if (hasLengthCappedOutput(messages)) {
|
|
6960
7149
|
throw new Error("map-memories returned length-capped output");
|
|
6961
7150
|
}
|
|
6962
|
-
const text =
|
|
7151
|
+
const text = currentManifest(assistantText(messages));
|
|
6963
7152
|
if (!text)
|
|
6964
7153
|
throw new Error("map-memories returned no output");
|
|
6965
7154
|
return validateMapMemoriesManifest(text, new Set(batch.map((memory) => memory.id)));
|
|
@@ -6967,8 +7156,9 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
6967
7156
|
});
|
|
6968
7157
|
promptSettled = true;
|
|
6969
7158
|
recordInvocation2(args, startedAt, { status: "completed", messages: run.output });
|
|
6970
|
-
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized);
|
|
6971
|
-
|
|
7159
|
+
const outcome = await applyParsedBatchMappings(args, batch, run.validated, budgetFinalized, true);
|
|
7160
|
+
logBatchUsage(run.output, outcome.mapped + outcome.independent, startedAt);
|
|
7161
|
+
const returnedIds = new Set(outcome.committedIds);
|
|
6972
7162
|
return {
|
|
6973
7163
|
...outcome,
|
|
6974
7164
|
requeue: budgetFinalized ? [] : batch.filter((memory) => !returnedIds.has(memory.id))
|
|
@@ -6976,18 +7166,23 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
6976
7166
|
} catch (error) {
|
|
6977
7167
|
const desc = describeError(error);
|
|
6978
7168
|
log2(`[dreamer] map-memories batch failed: ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
7169
|
+
const messages = failedCompletion?.messages ?? await readFailedChildMessages(args.client, agentSessionId, args.sessionDirectory) ?? [];
|
|
6979
7170
|
recordInvocation2(args, startedAt, {
|
|
6980
7171
|
status: failedInvocationStatus(error),
|
|
6981
7172
|
error,
|
|
6982
|
-
messages
|
|
7173
|
+
messages
|
|
6983
7174
|
});
|
|
6984
|
-
if (error instanceof DreamerModuleFailureError
|
|
7175
|
+
if (error instanceof DreamerModuleFailureError)
|
|
6985
7176
|
throw error;
|
|
6986
7177
|
if (signal.aborted)
|
|
6987
7178
|
throw error;
|
|
7179
|
+
const recovered = parsePartialMapMemoriesManifest(assistantText(messages) || failedCompletion?.text || "", new Set(batch.map((memory) => memory.id)));
|
|
7180
|
+
const outcome = await applyParsedBatchMappings(args, batch, recovered, budgetFinalized, true);
|
|
7181
|
+
logBatchUsage(messages, outcome.mapped + outcome.independent, startedAt);
|
|
7182
|
+
if (error instanceof DreamTokenBudgetExceeded)
|
|
7183
|
+
throw error;
|
|
6988
7184
|
return {
|
|
6989
|
-
|
|
6990
|
-
independent: 0,
|
|
7185
|
+
...outcome,
|
|
6991
7186
|
failure: {
|
|
6992
7187
|
class: isTimeoutClassError2(error) ? "timeout" : "other",
|
|
6993
7188
|
elapsedMs: Date.now() - startedAt
|
|
@@ -7006,7 +7201,7 @@ async function mapOneBatch(args, batch, sliceMs, signal) {
|
|
|
7006
7201
|
});
|
|
7007
7202
|
}
|
|
7008
7203
|
}
|
|
7009
|
-
async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = false) {
|
|
7204
|
+
async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = false, allowPartial = false) {
|
|
7010
7205
|
const batchIds = new Set(batch.map((memory) => memory.id));
|
|
7011
7206
|
const valid = parsed.filter((entry) => batchIds.has(entry.id));
|
|
7012
7207
|
const unknown = parsed.filter((entry) => !batchIds.has(entry.id));
|
|
@@ -7014,14 +7209,14 @@ async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = f
|
|
|
7014
7209
|
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(", ")})`);
|
|
7015
7210
|
}
|
|
7016
7211
|
assertNoDuplicateManifestIds(valid.map((entry) => entry.id), "mappings");
|
|
7017
|
-
if (!budgetFinalized && valid.length * 2 < batch.length) {
|
|
7212
|
+
if (!allowPartial && !budgetFinalized && valid.length * 2 < batch.length) {
|
|
7018
7213
|
throw new Error(`mappings manifest covers ${valid.length}/${batch.length} batch ids after filtering unknown entries; rejecting mostly-wrong manifest`);
|
|
7019
7214
|
}
|
|
7020
7215
|
if (budgetFinalized && valid.length < batch.length) {
|
|
7021
7216
|
log2(`[dreamer] map-memories: accepted partial manifest after token budget: ${valid.length}/${batch.length}`);
|
|
7022
7217
|
}
|
|
7023
7218
|
if (valid.length === 0)
|
|
7024
|
-
return { mapped: 0, independent: 0 };
|
|
7219
|
+
return { mapped: 0, independent: 0, committedIds: [] };
|
|
7025
7220
|
const planned = [];
|
|
7026
7221
|
const batchById = new Map(batch.map((memory) => [memory.id, memory]));
|
|
7027
7222
|
for (const p of valid) {
|
|
@@ -7070,9 +7265,10 @@ async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = f
|
|
|
7070
7265
|
});
|
|
7071
7266
|
}
|
|
7072
7267
|
if (planned.length === 0)
|
|
7073
|
-
return { mapped: 0, independent: 0 };
|
|
7268
|
+
return { mapped: 0, independent: 0, committedIds: [] };
|
|
7074
7269
|
let mapped = 0;
|
|
7075
7270
|
let independent = 0;
|
|
7271
|
+
const committedIds = [];
|
|
7076
7272
|
if (args.moduleRoute) {
|
|
7077
7273
|
const identities = getModuleMemoryIdentities(args.db, args.projectIdentity, planned.map((item) => item.id));
|
|
7078
7274
|
const rows = planned.map((item) => {
|
|
@@ -7110,19 +7306,22 @@ async function applyParsedBatchMappings(args, batch, parsed, budgetFinalized = f
|
|
|
7110
7306
|
const accepted = new Set(result.accepted.filter((id) => typeof id === "number"));
|
|
7111
7307
|
for (const item of planned) {
|
|
7112
7308
|
const identity = identities.get(item.id);
|
|
7113
|
-
if (identity && accepted.has(identity.moduleId))
|
|
7309
|
+
if (identity && accepted.has(identity.moduleId)) {
|
|
7114
7310
|
item.independent ? independent += 1 : mapped += 1;
|
|
7311
|
+
committedIds.push(item.id);
|
|
7312
|
+
}
|
|
7115
7313
|
}
|
|
7116
|
-
return { mapped, independent };
|
|
7314
|
+
return { mapped, independent, committedIds };
|
|
7117
7315
|
}
|
|
7118
7316
|
const now = Date.now();
|
|
7119
7317
|
runLeaseGuardedWrite(args.db, args.holderId, args.leaseKey, () => {
|
|
7120
7318
|
for (const item of planned) {
|
|
7121
7319
|
recordMemoryMapping(args.db, item.id, item.files, now, item.mappingOrigin);
|
|
7122
7320
|
item.independent ? independent += 1 : mapped += 1;
|
|
7321
|
+
committedIds.push(item.id);
|
|
7123
7322
|
}
|
|
7124
7323
|
});
|
|
7125
|
-
return { mapped, independent };
|
|
7324
|
+
return { mapped, independent, committedIds };
|
|
7126
7325
|
}
|
|
7127
7326
|
function recordInvocation2(args, startedAt, params) {
|
|
7128
7327
|
if (!args.parentSessionId)
|
|
@@ -7390,32 +7589,41 @@ async function promotePrimers(args) {
|
|
|
7390
7589
|
// src/features/magic-context/dreamer/primer-seed.ts
|
|
7391
7590
|
var PRIMER_SEED_CAP_TOKENS = 4000;
|
|
7392
7591
|
function renderUserAndToolOrientation(sessionId, startOrdinal, endOrdinal, capTokens) {
|
|
7592
|
+
const renderer = orientationRenderer(capTokens);
|
|
7593
|
+
visitRawSessionMessages2(sessionId, startOrdinal, endOrdinal, renderer.visit, {
|
|
7594
|
+
summary: true
|
|
7595
|
+
});
|
|
7596
|
+
return renderer.result();
|
|
7597
|
+
}
|
|
7598
|
+
function orientationRenderer(capTokens) {
|
|
7393
7599
|
const lines = [];
|
|
7394
7600
|
let tokens = 0;
|
|
7395
7601
|
let sawMessage = false;
|
|
7396
|
-
|
|
7397
|
-
|
|
7398
|
-
|
|
7399
|
-
|
|
7400
|
-
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
const
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7602
|
+
return {
|
|
7603
|
+
visit: (msg) => {
|
|
7604
|
+
sawMessage = true;
|
|
7605
|
+
const out = [];
|
|
7606
|
+
if (msg.role === "user" && hasMeaningfulUserText2(msg.parts)) {
|
|
7607
|
+
const text = extractTexts2(msg.parts).map((t) => cleanUserText2(t)).map(normalizeText).filter((t) => t.length > 0).join(" / ");
|
|
7608
|
+
if (text)
|
|
7609
|
+
out.push(`U: ${text}`);
|
|
7610
|
+
}
|
|
7611
|
+
for (const tc of extractToolCallSummaries(msg.parts))
|
|
7612
|
+
out.push(tc);
|
|
7613
|
+
for (const line of out) {
|
|
7614
|
+
const lineTokens = estimateTokens(line);
|
|
7615
|
+
if (tokens + lineTokens > capTokens && lines.length > 0) {
|
|
7616
|
+
lines.push("… (orientation truncated; investigate the current source directly)");
|
|
7617
|
+
return false;
|
|
7618
|
+
}
|
|
7619
|
+
lines.push(line);
|
|
7620
|
+
tokens += lineTokens;
|
|
7411
7621
|
}
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
}
|
|
7417
|
-
return sawMessage ? lines.join(`
|
|
7418
|
-
`) : null;
|
|
7622
|
+
return true;
|
|
7623
|
+
},
|
|
7624
|
+
result: () => sawMessage ? lines.join(`
|
|
7625
|
+
`) : null
|
|
7626
|
+
};
|
|
7419
7627
|
}
|
|
7420
7628
|
function selectPrimerOriginCandidate(db, primer) {
|
|
7421
7629
|
return getPrimerCandidatesByIds(db, primer.sourceCandidateIds).filter((candidate) => candidate.projectPath === primer.projectPath).sort((a, b) => b.sourceMessageTime - a.sourceMessageTime || b.id - a.id)[0];
|
|
@@ -7449,16 +7657,37 @@ function closedBookOriginP1(db, sessionId, originStartMessage) {
|
|
|
7449
7657
|
return { orientation, sessionId };
|
|
7450
7658
|
}
|
|
7451
7659
|
function buildPrimerSeed(db, primer) {
|
|
7660
|
+
return buildPrimerSeedUsing(db, selectPrimerOriginCandidate(db, primer), renderUserAndToolOrientation);
|
|
7661
|
+
}
|
|
7662
|
+
async function buildPrimerSeedAsync(db, primer) {
|
|
7452
7663
|
const mostRecent = selectPrimerOriginCandidate(db, primer);
|
|
7664
|
+
let orientation = null;
|
|
7665
|
+
if (mostRecent && typeof mostRecent.sourceCompartmentStart === "number" && typeof mostRecent.sourceCompartmentEnd === "number") {
|
|
7666
|
+
try {
|
|
7667
|
+
const renderer = orientationRenderer(PRIMER_SEED_CAP_TOKENS);
|
|
7668
|
+
await visitRawSessionMessagesAsync2(mostRecent.sessionId, mostRecent.sourceCompartmentStart, mostRecent.sourceCompartmentEnd, renderer.visit, { summary: true });
|
|
7669
|
+
orientation = renderer.result();
|
|
7670
|
+
} catch {
|
|
7671
|
+
orientation = null;
|
|
7672
|
+
}
|
|
7673
|
+
}
|
|
7674
|
+
return buildPrimerSeedUsing(db, mostRecent, () => orientation);
|
|
7675
|
+
}
|
|
7676
|
+
function buildPrimerSeedUsing(db, mostRecent, render) {
|
|
7453
7677
|
if (!mostRecent || typeof mostRecent.sourceCompartmentStart !== "number" || typeof mostRecent.sourceCompartmentEnd !== "number") {
|
|
7454
|
-
return {
|
|
7678
|
+
return {
|
|
7679
|
+
kind: "closed-book",
|
|
7680
|
+
orientation: "",
|
|
7681
|
+
prePost: "",
|
|
7682
|
+
sessionId: null
|
|
7683
|
+
};
|
|
7455
7684
|
}
|
|
7456
7685
|
const sessionId = mostRecent.sessionId;
|
|
7457
7686
|
const start = mostRecent.sourceCompartmentStart;
|
|
7458
7687
|
const end = mostRecent.sourceCompartmentEnd;
|
|
7459
7688
|
let orientation = null;
|
|
7460
7689
|
try {
|
|
7461
|
-
orientation =
|
|
7690
|
+
orientation = render(sessionId, start, end, PRIMER_SEED_CAP_TOKENS);
|
|
7462
7691
|
} catch {
|
|
7463
7692
|
orientation = null;
|
|
7464
7693
|
}
|
|
@@ -7589,14 +7818,14 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
7589
7818
|
provider = null;
|
|
7590
7819
|
}
|
|
7591
7820
|
}
|
|
7592
|
-
const seed =
|
|
7821
|
+
const seed = await (async () => {
|
|
7593
7822
|
const unregister = provider && originSessionId ? setRawMessageProvider2(originSessionId, provider) : null;
|
|
7594
7823
|
try {
|
|
7595
|
-
return buildPrimerSeed(args.db, primer);
|
|
7824
|
+
return provider?.iterateMessageRangeAsync ? await buildPrimerSeedAsync(args.db, primer) : withRawSessionMessageCache2(() => buildPrimerSeed(args.db, primer));
|
|
7596
7825
|
} finally {
|
|
7597
7826
|
unregister?.();
|
|
7598
7827
|
}
|
|
7599
|
-
});
|
|
7828
|
+
})();
|
|
7600
7829
|
let agentSessionId = null;
|
|
7601
7830
|
let promptSettled = false;
|
|
7602
7831
|
const startedAt = Date.now();
|
|
@@ -7612,7 +7841,10 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
7612
7841
|
prompt,
|
|
7613
7842
|
title: "magic-context-dream-refresh-primers",
|
|
7614
7843
|
callContext: "dreamer:refresh-primers",
|
|
7615
|
-
metadata: {
|
|
7844
|
+
metadata: {
|
|
7845
|
+
tokenBudget: args.tokenBudget,
|
|
7846
|
+
onBudgetUpdate: args.onBudgetUpdate
|
|
7847
|
+
},
|
|
7616
7848
|
model: args.model,
|
|
7617
7849
|
fallbackModels: args.fallbackModels,
|
|
7618
7850
|
language: args.language,
|
|
@@ -7678,7 +7910,10 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
7678
7910
|
validateOutput: (messages) => parseAnswer(messages, primer.answer)
|
|
7679
7911
|
});
|
|
7680
7912
|
promptSettled = true;
|
|
7681
|
-
recordInvocation3(args, startedAt, {
|
|
7913
|
+
recordInvocation3(args, startedAt, {
|
|
7914
|
+
status: "completed",
|
|
7915
|
+
messages: run.output
|
|
7916
|
+
});
|
|
7682
7917
|
const answer = run.validated.trim();
|
|
7683
7918
|
if (!answer)
|
|
7684
7919
|
return false;
|
|
@@ -7693,7 +7928,10 @@ async function refreshOnePrimer(args, primer, sliceMs, signal) {
|
|
|
7693
7928
|
} catch (error) {
|
|
7694
7929
|
const desc = describeError(error);
|
|
7695
7930
|
log2(`[dreamer] refresh-primers failed (primer #${primer.id}): ${desc.brief}`, desc.stackHead ? { stackHead: desc.stackHead } : undefined);
|
|
7696
|
-
recordInvocation3(args, startedAt, {
|
|
7931
|
+
recordInvocation3(args, startedAt, {
|
|
7932
|
+
status: failedInvocationStatus(error),
|
|
7933
|
+
error
|
|
7934
|
+
});
|
|
7697
7935
|
throw error;
|
|
7698
7936
|
} finally {
|
|
7699
7937
|
if (agentSessionId && args.client)
|
|
@@ -8210,9 +8448,9 @@ function evaluateTaskGate(task, ctx) {
|
|
|
8210
8448
|
import { createHash as createHash6 } from "node:crypto";
|
|
8211
8449
|
|
|
8212
8450
|
// src/features/magic-context/dreamer/verify-diff.ts
|
|
8213
|
-
import { execFile as
|
|
8214
|
-
import { promisify as
|
|
8215
|
-
var exec =
|
|
8451
|
+
import { execFile as execFile3 } from "node:child_process";
|
|
8452
|
+
import { promisify as promisify3 } from "node:util";
|
|
8453
|
+
var exec = promisify3(execFile3);
|
|
8216
8454
|
var VERIFY_DIFF_BUDGET_TOKENS = 12000;
|
|
8217
8455
|
var MAX_DIFF_BYTES = 4 * 1024 * 1024;
|
|
8218
8456
|
async function git2(root, args) {
|
|
@@ -10884,10 +11122,10 @@ async function sourceReady(source, sessionId) {
|
|
|
10884
11122
|
function defer(fn) {
|
|
10885
11123
|
const immediate = globalThis.setImmediate;
|
|
10886
11124
|
if (typeof immediate === "function") {
|
|
10887
|
-
immediate(fn);
|
|
11125
|
+
inRootAsyncContext2(() => immediate(fn));
|
|
10888
11126
|
return;
|
|
10889
11127
|
}
|
|
10890
|
-
setTimeout(fn, 0);
|
|
11128
|
+
inRootAsyncContext2(() => setTimeout(fn, 0));
|
|
10891
11129
|
}
|
|
10892
11130
|
function yieldToEventLoop() {
|
|
10893
11131
|
return new Promise((resolve) => defer(resolve));
|
|
@@ -10971,14 +11209,14 @@ function scheduleReconciliation(db, sessionId, readMessages) {
|
|
|
10971
11209
|
reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
|
|
10972
11210
|
if (ran)
|
|
10973
11211
|
return;
|
|
10974
|
-
setTimeout(() => {
|
|
11212
|
+
inRootAsyncContext2(() => setTimeout(() => {
|
|
10975
11213
|
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
10976
11214
|
scheduleReconciliation(db, sessionId, readMessages);
|
|
10977
|
-
}, PREPARE_RETRY_MS).unref?.();
|
|
11215
|
+
}, PREPARE_RETRY_MS)).unref?.();
|
|
10978
11216
|
}).catch((error) => {
|
|
10979
11217
|
logIndexingError(sessionId, "reconciliation", error);
|
|
10980
11218
|
if (isDatabaseLockedError(error))
|
|
10981
|
-
setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000).unref();
|
|
11219
|
+
inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
|
|
10982
11220
|
}).finally(() => {
|
|
10983
11221
|
heapHolder.reconciliationScheduledSessions.delete(sessionId);
|
|
10984
11222
|
});
|
|
@@ -10993,7 +11231,7 @@ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
|
10993
11231
|
const activeTimer = heapHolder.incrementalTimers.get(schedulingKey);
|
|
10994
11232
|
if (activeTimer)
|
|
10995
11233
|
clearTimeout(activeTimer);
|
|
10996
|
-
const timer = setTimeout(() => {
|
|
11234
|
+
const timer = inRootAsyncContext2(() => setTimeout(() => {
|
|
10997
11235
|
heapHolder.incrementalTimers.delete(schedulingKey);
|
|
10998
11236
|
heapHolder.pendingIncrementalKeys.add(schedulingKey);
|
|
10999
11237
|
const indexMessage = async () => {
|
|
@@ -11037,7 +11275,7 @@ function scheduleIncrementalIndex(db, sessionId, messageId, messageSource) {
|
|
|
11037
11275
|
if ((sessionEpochs.get(sessionId) ?? 0) === epoch)
|
|
11038
11276
|
heapHolder.pendingIncrementalKeys.delete(schedulingKey);
|
|
11039
11277
|
});
|
|
11040
|
-
}, INCREMENTAL_DEBOUNCE_MS);
|
|
11278
|
+
}, INCREMENTAL_DEBOUNCE_MS));
|
|
11041
11279
|
heapHolder.incrementalTimers.set(schedulingKey, timer);
|
|
11042
11280
|
}
|
|
11043
11281
|
async function indexSingleMessageOffThread(db, sessionId, message) {
|
|
@@ -11254,7 +11492,7 @@ async function startDreamScheduleTimer(args) {
|
|
|
11254
11492
|
startupTickTimer = null;
|
|
11255
11493
|
runTick("startup");
|
|
11256
11494
|
});
|
|
11257
|
-
const timer = setInterval(() => runTick("interval"), DREAM_TIMER_INTERVAL_MS);
|
|
11495
|
+
const timer = inRootAsyncContext2(() => setInterval(() => runTick("interval"), DREAM_TIMER_INTERVAL_MS));
|
|
11258
11496
|
if (typeof timer === "object" && "unref" in timer) {
|
|
11259
11497
|
timer.unref();
|
|
11260
11498
|
}
|
|
@@ -11550,7 +11788,7 @@ async function runCompiledSmartNoteSweep(reg, db) {
|
|
|
11550
11788
|
}
|
|
11551
11789
|
}
|
|
11552
11790
|
function startGitSweepLeaseRenewal(db, projectIdentity, holderId) {
|
|
11553
|
-
const timer = setInterval(() => {
|
|
11791
|
+
const timer = inRootAsyncContext2(() => setInterval(() => {
|
|
11554
11792
|
try {
|
|
11555
11793
|
if (!renewGitSweepLease(db, projectIdentity, holderId)) {
|
|
11556
11794
|
log2(`[git-commits] sweep lease renewal failed for ${projectIdentity}`);
|
|
@@ -11558,7 +11796,7 @@ function startGitSweepLeaseRenewal(db, projectIdentity, holderId) {
|
|
|
11558
11796
|
} catch (error) {
|
|
11559
11797
|
log2(`[git-commits] sweep lease renewal errored for ${projectIdentity}: ${error instanceof Error ? error.message : String(error)}`);
|
|
11560
11798
|
}
|
|
11561
|
-
}, GIT_SWEEP_LEASE_RENEWAL_MS);
|
|
11799
|
+
}, GIT_SWEEP_LEASE_RENEWAL_MS));
|
|
11562
11800
|
timer.unref?.();
|
|
11563
11801
|
return () => clearInterval(timer);
|
|
11564
11802
|
}
|
|
@@ -15599,7 +15837,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
15599
15837
|
const sessionId = String(params.sessionId ?? "");
|
|
15600
15838
|
if (!sessionId)
|
|
15601
15839
|
return { owner: false };
|
|
15602
|
-
const sessionDirectory =
|
|
15840
|
+
const sessionDirectory = args.readSessionDirectory ? await args.readSessionDirectory(sessionId) : await readHostSessionDirectory(args.client, sessionId) ?? liveSessionState.sessionDirectoryBySession.get(sessionId);
|
|
15603
15841
|
if (!sessionDirectory)
|
|
15604
15842
|
return { owner: false };
|
|
15605
15843
|
return {
|
|
@@ -15670,7 +15908,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
15670
15908
|
return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
|
|
15671
15909
|
});
|
|
15672
15910
|
const buildManagedCtx = async (db) => {
|
|
15673
|
-
const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-
|
|
15911
|
+
const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-3nbxsyss.js"));
|
|
15674
15912
|
const { resolveHistorianModel } = await importPluginModule(() => import("./model-resolution-nx97z3x7.js"));
|
|
15675
15913
|
const { userMemoryCollectionEnabled } = await importPluginModule(() => import("./task-config-cgpg0nvh.js"));
|
|
15676
15914
|
const DEFAULT_HISTORIAN_TIMEOUT_MS = 10 * 60 * 1000;
|
|
@@ -15685,6 +15923,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
15685
15923
|
directory,
|
|
15686
15924
|
historianChunkTokens: deriveHistorianChunkTokens(resolveHistorianContextLimit(historianModel.primary?.model)),
|
|
15687
15925
|
historianTimeoutMs: runConfig.historian_timeout_ms ?? DEFAULT_HISTORIAN_TIMEOUT_MS,
|
|
15926
|
+
historianMaxOutputTokens: runConfig.historian?.maxTokens,
|
|
15688
15927
|
memoryEnabled: config.memory?.enabled ?? true,
|
|
15689
15928
|
autoPromote: runConfig.memory?.auto_promote ?? true,
|
|
15690
15929
|
historianModel: historianModel.primary,
|
|
@@ -15699,6 +15938,20 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
15699
15938
|
const sessionId = String(params.sessionId ?? "");
|
|
15700
15939
|
if (!sessionId)
|
|
15701
15940
|
return { ok: false, error: "no session" };
|
|
15941
|
+
const readDirectory = args.readSessionDirectory;
|
|
15942
|
+
if (readDirectory) {
|
|
15943
|
+
const { handoffHistoryWork } = await import("./history-owner-ty29fz0f.js");
|
|
15944
|
+
const handed = await handoffHistoryWork({
|
|
15945
|
+
storageDir: args.storageDir ?? getMagicContextStorageDir(),
|
|
15946
|
+
directory,
|
|
15947
|
+
sessionId,
|
|
15948
|
+
method: "recomp",
|
|
15949
|
+
params,
|
|
15950
|
+
readDirectory: () => readDirectory(sessionId)
|
|
15951
|
+
});
|
|
15952
|
+
if (handed)
|
|
15953
|
+
return handed;
|
|
15954
|
+
}
|
|
15702
15955
|
const dir = String(params.directory ?? directory);
|
|
15703
15956
|
if (config.transform_mode === "rust") {
|
|
15704
15957
|
return executeRustRecompRpc(rustModeModuleClient, sessionId, dir);
|
|
@@ -15706,8 +15959,8 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
15706
15959
|
const db = readDatabase();
|
|
15707
15960
|
if (!db)
|
|
15708
15961
|
return { ok: false, error: "db unavailable" };
|
|
15709
|
-
const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-
|
|
15710
|
-
const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-
|
|
15962
|
+
const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-gr36zvd2.js"));
|
|
15963
|
+
const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-q8ngbap3.js"));
|
|
15711
15964
|
log2(`[rpc] recomp requested for session ${sessionId}`);
|
|
15712
15965
|
if (!args.client && !args.hiddenCompletionExecutor) {
|
|
15713
15966
|
return {
|
|
@@ -15763,6 +16016,21 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
15763
16016
|
return { ok: true, message };
|
|
15764
16017
|
});
|
|
15765
16018
|
rpcServer.handle("wrapup", async (params) => {
|
|
16019
|
+
const readDirectory = args.readSessionDirectory;
|
|
16020
|
+
if (readDirectory && params.sessionId) {
|
|
16021
|
+
const { handoffHistoryWork } = await import("./history-owner-ty29fz0f.js");
|
|
16022
|
+
const sessionId = String(params.sessionId);
|
|
16023
|
+
const handed = await handoffHistoryWork({
|
|
16024
|
+
storageDir: args.storageDir ?? getMagicContextStorageDir(),
|
|
16025
|
+
directory,
|
|
16026
|
+
sessionId,
|
|
16027
|
+
method: "wrapup",
|
|
16028
|
+
params,
|
|
16029
|
+
readDirectory: () => readDirectory(sessionId)
|
|
16030
|
+
});
|
|
16031
|
+
if (handed)
|
|
16032
|
+
return handed;
|
|
16033
|
+
}
|
|
15766
16034
|
const sessionId = String(params.sessionId ?? "");
|
|
15767
16035
|
if (!sessionId)
|
|
15768
16036
|
return { ok: false, error: "no session" };
|
|
@@ -15776,7 +16044,7 @@ function registerRpcHandlers(rpcServer, args) {
|
|
|
15776
16044
|
const db = readDatabase();
|
|
15777
16045
|
if (!db)
|
|
15778
16046
|
return { ok: false, error: "db unavailable" };
|
|
15779
|
-
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-
|
|
16047
|
+
const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-gv08c6f9.js"));
|
|
15780
16048
|
const model = liveSessionState.liveModelBySession.get(sessionId);
|
|
15781
16049
|
const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
|
|
15782
16050
|
const ctx = {
|
|
@@ -15967,7 +16235,7 @@ function scheduleOpenCodeTransformDecisionWrite(args) {
|
|
|
15967
16235
|
lastBoundMessageIdBySession.set(args.sessionId, args.messageId);
|
|
15968
16236
|
pendingDecisionBySession.delete(args.sessionId);
|
|
15969
16237
|
const token = addScheduledWriteToken(args.sessionId);
|
|
15970
|
-
setTimeout(() => {
|
|
16238
|
+
inRootAsyncContext2(() => setTimeout(() => {
|
|
15971
16239
|
try {
|
|
15972
16240
|
if (!hasScheduledWriteToken(args.sessionId, token))
|
|
15973
16241
|
return;
|
|
@@ -15981,7 +16249,7 @@ function scheduleOpenCodeTransformDecisionWrite(args) {
|
|
|
15981
16249
|
} finally {
|
|
15982
16250
|
deleteScheduledWriteToken(args.sessionId, token);
|
|
15983
16251
|
}
|
|
15984
|
-
}, 0);
|
|
16252
|
+
}, 0));
|
|
15985
16253
|
return true;
|
|
15986
16254
|
}
|
|
15987
16255
|
function addScheduledWriteToken(sessionId) {
|
|
@@ -16215,11 +16483,11 @@ function clone(value) {
|
|
|
16215
16483
|
return value;
|
|
16216
16484
|
return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, clone(item)]));
|
|
16217
16485
|
}
|
|
16218
|
-
function
|
|
16486
|
+
function isThinkingPart2(part) {
|
|
16219
16487
|
return isRecord(part) && ["thinking", "reasoning", "redacted_thinking"].includes(String(part.type));
|
|
16220
16488
|
}
|
|
16221
16489
|
function replayableOriginal(part) {
|
|
16222
|
-
if (!
|
|
16490
|
+
if (!isThinkingPart2(part) || !isRecord(part))
|
|
16223
16491
|
return false;
|
|
16224
16492
|
const metadata = isRecord(part.metadata) && isRecord(part.metadata.anthropic) ? part.metadata.anthropic : {};
|
|
16225
16493
|
const signature = part.signature ?? part.thinkingSignature ?? metadata.signature ?? part.data ?? metadata.redactedData;
|
|
@@ -16527,7 +16795,7 @@ function createPassOutcome() {
|
|
|
16527
16795
|
}
|
|
16528
16796
|
|
|
16529
16797
|
// src/hooks/magic-context/rust-mode-transform.ts
|
|
16530
|
-
import { createHash as
|
|
16798
|
+
import { createHash as createHash12, randomUUID as randomUUID6 } from "node:crypto";
|
|
16531
16799
|
|
|
16532
16800
|
// src/features/magic-context/memory/single-store-embedding-drain.ts
|
|
16533
16801
|
function isWatermarkRow(row) {
|
|
@@ -19059,13 +19327,235 @@ function resolveRustLkgReplayParticipant(sessionId) {
|
|
|
19059
19327
|
return latest;
|
|
19060
19328
|
return alive.length === 1 ? alive[0] : undefined;
|
|
19061
19329
|
}
|
|
19062
|
-
function noteExternalLkgReplay(participant, sessionId,
|
|
19330
|
+
function noteExternalLkgReplay(participant, sessionId, inputMessages, servedMessages) {
|
|
19063
19331
|
if (!participant)
|
|
19064
19332
|
return;
|
|
19065
|
-
participant.enterFreezeFromExternalServe(sessionId,
|
|
19333
|
+
participant.enterFreezeFromExternalServe(sessionId, inputMessages, servedMessages);
|
|
19066
19334
|
sessionLog2(sessionId, "lkg_external_replay_froze_rust_adapter");
|
|
19067
19335
|
}
|
|
19068
19336
|
|
|
19337
|
+
// src/hooks/magic-context/rust-served-raw.ts
|
|
19338
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
19339
|
+
class RustServedRawConflict extends EmergencyFailClosedError {
|
|
19340
|
+
reason;
|
|
19341
|
+
messageIds;
|
|
19342
|
+
firstBlockId;
|
|
19343
|
+
constructor(reason, messageIds, firstBlockId) {
|
|
19344
|
+
super(`Rust served-raw conflict: ${reason} at ${firstBlockId}`);
|
|
19345
|
+
this.reason = reason;
|
|
19346
|
+
this.messageIds = messageIds;
|
|
19347
|
+
this.firstBlockId = firstBlockId;
|
|
19348
|
+
}
|
|
19349
|
+
}
|
|
19350
|
+
function partDigest(part) {
|
|
19351
|
+
const serialized = JSON.stringify(part);
|
|
19352
|
+
return createHash11("sha256").update(stableStringify(serialized === undefined ? undefined : JSON.parse(serialized))).digest("hex");
|
|
19353
|
+
}
|
|
19354
|
+
function records(doc) {
|
|
19355
|
+
if (doc.rustServedRaw === undefined)
|
|
19356
|
+
return [];
|
|
19357
|
+
if (!Array.isArray(doc.rustServedRaw))
|
|
19358
|
+
throw new EmergencyFailClosedError("Invalid Rust served-raw evidence");
|
|
19359
|
+
for (const row of doc.rustServedRaw) {
|
|
19360
|
+
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")) {
|
|
19361
|
+
throw new EmergencyFailClosedError("Invalid Rust served-raw part");
|
|
19362
|
+
}
|
|
19363
|
+
}
|
|
19364
|
+
return doc.rustServedRaw;
|
|
19365
|
+
}
|
|
19366
|
+
function rustRawRebuild(db, sessionId) {
|
|
19367
|
+
const value = readReplayEnvelope(db, sessionId).rustRawRebuild;
|
|
19368
|
+
if (value === undefined)
|
|
19369
|
+
return;
|
|
19370
|
+
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") {
|
|
19371
|
+
throw new EmergencyFailClosedError("Invalid Rust raw-rebuild request");
|
|
19372
|
+
}
|
|
19373
|
+
return value;
|
|
19374
|
+
}
|
|
19375
|
+
function servedRawBlockIds(db, sessionId) {
|
|
19376
|
+
return records(readReplayEnvelope(db, sessionId)).flatMap((row) => row.blockIds);
|
|
19377
|
+
}
|
|
19378
|
+
function sourcePart(row, message) {
|
|
19379
|
+
return row.partId === undefined ? message?.parts[row.index] : message?.parts.find((part) => part?.id === row.partId);
|
|
19380
|
+
}
|
|
19381
|
+
function conflict(row, reason) {
|
|
19382
|
+
return new RustServedRawConflict(reason, [row.messageId], row.blockIds[0] ?? `${row.messageId}#0`);
|
|
19383
|
+
}
|
|
19384
|
+
function checkRustServedRawIngress(db, sessionId, input) {
|
|
19385
|
+
const rows = records(readReplayEnvelope(db, sessionId));
|
|
19386
|
+
if (!rows.length)
|
|
19387
|
+
return;
|
|
19388
|
+
const byId = new Map(input.map((message) => [message.info.id, message]));
|
|
19389
|
+
const changed = rows.filter((row) => partDigest(sourcePart(row, byId.get(row.messageId))) !== row.digest);
|
|
19390
|
+
const first = changed[0];
|
|
19391
|
+
if (!first)
|
|
19392
|
+
return;
|
|
19393
|
+
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`);
|
|
19394
|
+
}
|
|
19395
|
+
function requestRustRawRebuild(db, sessionId, error) {
|
|
19396
|
+
if (!updateReplayDocument(db, sessionId, (doc) => {
|
|
19397
|
+
const previous = doc.rustRawRebuild;
|
|
19398
|
+
if (previous?.pending && previous.reason === error.reason && previous.firstBlockId === error.firstBlockId && error.messageIds.every((id) => previous.messageIds.includes(id)))
|
|
19399
|
+
return false;
|
|
19400
|
+
const messageIds = [
|
|
19401
|
+
...new Set([
|
|
19402
|
+
...previous?.pending ? previous.messageIds : [],
|
|
19403
|
+
...error.messageIds
|
|
19404
|
+
])
|
|
19405
|
+
];
|
|
19406
|
+
const identity = partDigest([
|
|
19407
|
+
previous?.identity ?? "",
|
|
19408
|
+
error.reason,
|
|
19409
|
+
messageIds,
|
|
19410
|
+
error.firstBlockId
|
|
19411
|
+
]);
|
|
19412
|
+
doc.version = 2;
|
|
19413
|
+
doc.rustRawRebuild = {
|
|
19414
|
+
identity,
|
|
19415
|
+
reason: error.reason,
|
|
19416
|
+
messageIds,
|
|
19417
|
+
firstBlockId: error.firstBlockId,
|
|
19418
|
+
pending: true
|
|
19419
|
+
};
|
|
19420
|
+
return true;
|
|
19421
|
+
}))
|
|
19422
|
+
throw new EmergencyFailClosedError("Cannot persist Rust raw-rebuild request");
|
|
19423
|
+
}
|
|
19424
|
+
function noteRustServedRaw(db, sessionId, input, served) {
|
|
19425
|
+
const additions = [];
|
|
19426
|
+
const byId = new Map(served.filter((message) => typeof message?.info?.id === "string").map((message) => [message.info.id, message]));
|
|
19427
|
+
for (const message of input) {
|
|
19428
|
+
const visible = byId.get(message.info.id);
|
|
19429
|
+
if (!visible)
|
|
19430
|
+
continue;
|
|
19431
|
+
let offset = 0;
|
|
19432
|
+
for (const [index, value] of message.parts.entries()) {
|
|
19433
|
+
if (!value || typeof value !== "object")
|
|
19434
|
+
continue;
|
|
19435
|
+
const part = value;
|
|
19436
|
+
const count = encodeOpenCodeMessagesToCk([{ ...message, parts: [part] }])[0].ck.content.length;
|
|
19437
|
+
const actual = typeof part.id === "string" ? visible.parts.find((candidate) => candidate?.id === part.id) : visible.parts[index];
|
|
19438
|
+
const status = part.state?.status;
|
|
19439
|
+
const reachesProvider = !(part.type === "text" && part.ignored === true) && ![
|
|
19440
|
+
"compaction",
|
|
19441
|
+
"step-start",
|
|
19442
|
+
"step-finish",
|
|
19443
|
+
"snapshot",
|
|
19444
|
+
"patch",
|
|
19445
|
+
"agent",
|
|
19446
|
+
"retry"
|
|
19447
|
+
].includes(String(part.type)) && (part.type !== "tool" || status === "completed" || status === "error");
|
|
19448
|
+
if (reachesProvider && count > 0) {
|
|
19449
|
+
const digest = partDigest(part);
|
|
19450
|
+
if (actual === part || partDigest(actual) === digest) {
|
|
19451
|
+
additions.push({
|
|
19452
|
+
messageId: message.info.id,
|
|
19453
|
+
index,
|
|
19454
|
+
...typeof part.id === "string" ? { partId: part.id } : {},
|
|
19455
|
+
digest,
|
|
19456
|
+
blockIds: Array.from({ length: count }, (_, i) => `${message.info.id}#${offset + i}`)
|
|
19457
|
+
});
|
|
19458
|
+
}
|
|
19459
|
+
}
|
|
19460
|
+
offset += count;
|
|
19461
|
+
}
|
|
19462
|
+
}
|
|
19463
|
+
if (!additions.length)
|
|
19464
|
+
return;
|
|
19465
|
+
if (!updateReplayDocument(db, sessionId, (doc) => {
|
|
19466
|
+
const rows = records(doc);
|
|
19467
|
+
const key = (row) => stableStringify([row.messageId, row.partId ?? row.index]);
|
|
19468
|
+
const merged = new Map(rows.map((row) => [key(row), row]));
|
|
19469
|
+
for (const row of additions)
|
|
19470
|
+
merged.set(key(row), row);
|
|
19471
|
+
const next = [...merged.values()];
|
|
19472
|
+
if (stableStringify(rows) === stableStringify(next))
|
|
19473
|
+
return false;
|
|
19474
|
+
doc.version = 2;
|
|
19475
|
+
doc.rustServedRaw = next;
|
|
19476
|
+
return true;
|
|
19477
|
+
}))
|
|
19478
|
+
throw new EmergencyFailClosedError("Cannot persist Rust served-raw evidence");
|
|
19479
|
+
}
|
|
19480
|
+
function preserveRustServedRaw(db, sessionId, output, input = output, reconstruct = new Set, covered = new Set) {
|
|
19481
|
+
const rows = records(readReplayEnvelope(db, sessionId));
|
|
19482
|
+
if (!rows.length)
|
|
19483
|
+
return false;
|
|
19484
|
+
const sources = new Map(input.map((message) => [message.info.id, message]));
|
|
19485
|
+
const byId = new Map(output.map((message) => [message.info.id, message]));
|
|
19486
|
+
let repaired = false;
|
|
19487
|
+
for (const row of rows) {
|
|
19488
|
+
if (covered.has(row.messageId))
|
|
19489
|
+
continue;
|
|
19490
|
+
const original = sources.get(row.messageId);
|
|
19491
|
+
const source = sourcePart(row, original);
|
|
19492
|
+
if (!original || !source)
|
|
19493
|
+
throw conflict(row, "source_removed");
|
|
19494
|
+
if (partDigest(source) !== row.digest)
|
|
19495
|
+
throw conflict(row, "source_changed");
|
|
19496
|
+
let message = byId.get(row.messageId);
|
|
19497
|
+
if (!message) {
|
|
19498
|
+
if (!reconstruct.has(row.messageId))
|
|
19499
|
+
throw conflict(row, "candidate_loss");
|
|
19500
|
+
const sourceIndex = input.indexOf(original);
|
|
19501
|
+
const next = output.findIndex((candidate) => input.findIndex((entry) => entry.info.id === candidate.info.id) > sourceIndex);
|
|
19502
|
+
message = structuredClone(original);
|
|
19503
|
+
output.splice(next < 0 ? output.length : next, 0, message);
|
|
19504
|
+
byId.set(row.messageId, message);
|
|
19505
|
+
repaired = true;
|
|
19506
|
+
}
|
|
19507
|
+
const parts = message.parts;
|
|
19508
|
+
if (row.partId === undefined) {
|
|
19509
|
+
const candidate = parts[row.index];
|
|
19510
|
+
if (partDigest(candidate) === row.digest)
|
|
19511
|
+
continue;
|
|
19512
|
+
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;
|
|
19513
|
+
if (!reversibleTag) {
|
|
19514
|
+
if (!reconstruct.has(row.messageId))
|
|
19515
|
+
throw conflict(row, "candidate_conflict");
|
|
19516
|
+
message.parts = structuredClone(original.parts);
|
|
19517
|
+
repaired = true;
|
|
19518
|
+
continue;
|
|
19519
|
+
}
|
|
19520
|
+
parts[row.index] = structuredClone(source);
|
|
19521
|
+
continue;
|
|
19522
|
+
}
|
|
19523
|
+
const matches = parts.flatMap((part, i) => part.id === row.partId ? [i] : []);
|
|
19524
|
+
if (matches.length > 1)
|
|
19525
|
+
throw conflict(row, "candidate_conflict");
|
|
19526
|
+
const index = matches[0];
|
|
19527
|
+
if (index !== undefined) {
|
|
19528
|
+
if (partDigest(parts[index]) !== row.digest)
|
|
19529
|
+
parts[index] = structuredClone(source);
|
|
19530
|
+
} else if (["reasoning", "thinking", "redacted_thinking"].includes(String(source.type)) || reconstruct.has(row.messageId)) {
|
|
19531
|
+
parts.splice(row.index, 0, structuredClone(source));
|
|
19532
|
+
repaired = true;
|
|
19533
|
+
} else
|
|
19534
|
+
throw conflict(row, "candidate_loss");
|
|
19535
|
+
}
|
|
19536
|
+
return repaired;
|
|
19537
|
+
}
|
|
19538
|
+
function releaseRustServedRaw(db, sessionId, output, rebuiltIdentity) {
|
|
19539
|
+
const snapshot = readReplayEnvelope(db, sessionId);
|
|
19540
|
+
if (!records(snapshot).length && !snapshot.rustRawRebuild?.pending)
|
|
19541
|
+
return;
|
|
19542
|
+
const byId = new Map(output.map((message) => [message.info.id, message]));
|
|
19543
|
+
if (!updateReplayDocument(db, sessionId, (doc) => {
|
|
19544
|
+
const rows = records(doc);
|
|
19545
|
+
const kept = rows.filter((row) => partDigest(sourcePart(row, byId.get(row.messageId))) === row.digest);
|
|
19546
|
+
const recovery = doc.rustRawRebuild;
|
|
19547
|
+
const acknowledged = recovery?.pending && recovery.identity === rebuiltIdentity;
|
|
19548
|
+
if (kept.length === rows.length && !acknowledged)
|
|
19549
|
+
return false;
|
|
19550
|
+
doc.version = 2;
|
|
19551
|
+
doc.rustServedRaw = kept;
|
|
19552
|
+
if (acknowledged)
|
|
19553
|
+
doc.rustRawRebuild = { ...recovery, pending: false };
|
|
19554
|
+
return true;
|
|
19555
|
+
}))
|
|
19556
|
+
throw new EmergencyFailClosedError("Cannot release Rust served-raw evidence");
|
|
19557
|
+
}
|
|
19558
|
+
|
|
19069
19559
|
// src/hooks/magic-context/storage-busy-refusal.ts
|
|
19070
19560
|
var STORAGE_BUSY_MESSAGE = "Magic Context's database is busy (another process held it too long); send your message again.";
|
|
19071
19561
|
function describeStorageBusyCause(cause) {
|
|
@@ -19469,16 +19959,19 @@ function rustCaptureDigests(inputs, prior, acceptedInputs) {
|
|
|
19469
19959
|
} : undefined);
|
|
19470
19960
|
return { ...incremental, inputContentSignatures };
|
|
19471
19961
|
}
|
|
19962
|
+
var contentSnapshotFieldVisitObserverForTests;
|
|
19472
19963
|
function messageMatchesContentSnapshot(message, snapshot) {
|
|
19473
19964
|
let fieldIndex = 0;
|
|
19474
19965
|
const matched = visitMessageContentFields(contentSnapshotValue(message), {
|
|
19475
19966
|
field(value) {
|
|
19967
|
+
contentSnapshotFieldVisitObserverForTests?.();
|
|
19476
19968
|
if (!Object.is(value, snapshot.fields[fieldIndex]))
|
|
19477
19969
|
return false;
|
|
19478
19970
|
fieldIndex += 1;
|
|
19479
19971
|
return true;
|
|
19480
19972
|
},
|
|
19481
19973
|
beginObject() {
|
|
19974
|
+
contentSnapshotFieldVisitObserverForTests?.();
|
|
19482
19975
|
const expectedCount = snapshot.fields[fieldIndex];
|
|
19483
19976
|
if (typeof expectedCount !== "number")
|
|
19484
19977
|
return;
|
|
@@ -19505,10 +19998,10 @@ function messageCacheSignature(message) {
|
|
|
19505
19998
|
const parts = Array.isArray(message.parts) ? message.parts : [];
|
|
19506
19999
|
const serializedParts = JSON.stringify(parts) ?? "null";
|
|
19507
20000
|
const serializedMessage = JSON.stringify(message) ?? "null";
|
|
19508
|
-
return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${
|
|
20001
|
+
return `${messageIdOf(message) ?? ""}:${parts.length}:${Buffer.byteLength(serializedParts)}:${createHash12("sha256").update(serializedMessage).digest("hex")}`;
|
|
19509
20002
|
}
|
|
19510
20003
|
function advanceWireFingerprint(previous, encoded) {
|
|
19511
|
-
return
|
|
20004
|
+
return createHash12("sha256").update(previous).update("\\0").update(JSON.stringify(encoded) ?? "null").digest("hex");
|
|
19512
20005
|
}
|
|
19513
20006
|
function buildWireFingerprint(encoded) {
|
|
19514
20007
|
let fingerprint = "rust-wire-v1";
|
|
@@ -20048,7 +20541,8 @@ function buildTransformBody(args) {
|
|
|
20048
20541
|
args.providerId ? `provider:${args.providerId}` : "",
|
|
20049
20542
|
args.modelKey ? `model:${args.modelKey}` : "",
|
|
20050
20543
|
args.variant ? `variant:${args.variant}` : "",
|
|
20051
|
-
args.systemPromptHash ? `system:${args.systemPromptHash}` : ""
|
|
20544
|
+
args.systemPromptHash ? `system:${args.systemPromptHash}` : "",
|
|
20545
|
+
args.rawRebuild ? `raw_replay:${args.rawRebuild.identity}` : ""
|
|
20052
20546
|
].filter(Boolean).join("|"),
|
|
20053
20547
|
system_prompt_hash: args.systemPromptHash,
|
|
20054
20548
|
adopted_system_prompt_hash: args.passInputs.adopted_system_prompt_hash,
|
|
@@ -20056,6 +20550,14 @@ function buildTransformBody(args) {
|
|
|
20056
20550
|
is_subagent: args.passInputs.is_subagent === true,
|
|
20057
20551
|
messages: args.input,
|
|
20058
20552
|
native_messages: args.nativeMessages,
|
|
20553
|
+
served_raw_block_ids: args.servedRawBlockIds ?? [],
|
|
20554
|
+
...args.rawRebuild?.pending ? {
|
|
20555
|
+
raw_replay_rebuild: {
|
|
20556
|
+
identity: args.rawRebuild.identity,
|
|
20557
|
+
reason: args.rawRebuild.reason,
|
|
20558
|
+
message_ids: args.rawRebuild.messageIds
|
|
20559
|
+
}
|
|
20560
|
+
} : {},
|
|
20059
20561
|
tool_input_key_orders: args.toolInputKeyOrders ?? toolInputKeyOrders(args.input),
|
|
20060
20562
|
...args.fullArrayFingerprint ? { full_array_fingerprint: args.fullArrayFingerprint } : {},
|
|
20061
20563
|
...args.tailDelta ? {
|
|
@@ -20246,6 +20748,7 @@ function createRustModeTransform(deps, options) {
|
|
|
20246
20748
|
throw error;
|
|
20247
20749
|
} finally {
|
|
20248
20750
|
clock.clearTimeout(timer);
|
|
20751
|
+
invalidateReplayEnvelopeSnapshot(deps.db, args.sessionId);
|
|
20249
20752
|
}
|
|
20250
20753
|
};
|
|
20251
20754
|
const callTransformWithStallProbe = async (args, attemptTimeoutMs) => {
|
|
@@ -20354,6 +20857,24 @@ function createRustModeTransform(deps, options) {
|
|
|
20354
20857
|
logTransformTiming(sessionId, "rust.ordinal_rebuild", startedAt, detail);
|
|
20355
20858
|
}
|
|
20356
20859
|
};
|
|
20860
|
+
const recordRawConflict = (sessionId, error) => {
|
|
20861
|
+
requestRustRawRebuild(deps.db, sessionId, error);
|
|
20862
|
+
dropSlot(sessionId, `raw_replay_${error.reason}`);
|
|
20863
|
+
const state = ensureState(states, sessionId);
|
|
20864
|
+
state.forceFullWire = true;
|
|
20865
|
+
state.parked = false;
|
|
20866
|
+
sessionLog2(sessionId, `raw_replay_rebuild_requested reason=${error.reason} first_changed=${error.firstBlockId}`);
|
|
20867
|
+
};
|
|
20868
|
+
const observeRawReplay = (sessionId, input, served) => {
|
|
20869
|
+
try {
|
|
20870
|
+
checkRustServedRawIngress(deps.db, sessionId, input);
|
|
20871
|
+
noteRustServedRaw(deps.db, sessionId, input, served);
|
|
20872
|
+
} catch (error) {
|
|
20873
|
+
if (error instanceof RustServedRawConflict)
|
|
20874
|
+
recordRawConflict(sessionId, error);
|
|
20875
|
+
throw error;
|
|
20876
|
+
}
|
|
20877
|
+
};
|
|
20357
20878
|
const replayLastGood = (sessionId, currentMessages, output, systemPromptTokens) => {
|
|
20358
20879
|
try {
|
|
20359
20880
|
if (states.get(sessionId)?.markerAdmissionFenced || isRustMarkerAdmissionFenced(deps.db, sessionId))
|
|
@@ -20440,6 +20961,7 @@ function createRustModeTransform(deps, options) {
|
|
|
20440
20961
|
ownDirtyRevision: lkgDirtyRevision(sessionId)
|
|
20441
20962
|
}));
|
|
20442
20963
|
const replayInputCount = currentMessages.length;
|
|
20964
|
+
observeRawReplay(sessionId, currentMessages, replay.messages);
|
|
20443
20965
|
replaceMessagesInPlace(output, replay.messages);
|
|
20444
20966
|
ensureState(states, sessionId).lkgLatestServedDigest = lkgServedArrayDigest(JSON.stringify(replay.messages));
|
|
20445
20967
|
enterLkgReplayFreeze(ensureState(states, sessionId), replayInputCount);
|
|
@@ -20503,7 +21025,10 @@ function createRustModeTransform(deps, options) {
|
|
|
20503
21025
|
const passStampBySession = new Map;
|
|
20504
21026
|
const replayParticipant = {
|
|
20505
21027
|
lastPassStamp: (sessionId) => states.has(sessionId) ? passStampBySession.get(sessionId) : undefined,
|
|
20506
|
-
enterFreezeFromExternalServe: (sessionId,
|
|
21028
|
+
enterFreezeFromExternalServe: (sessionId, inputMessages, servedMessages) => {
|
|
21029
|
+
observeRawReplay(sessionId, inputMessages, servedMessages);
|
|
21030
|
+
enterLkgReplayFreeze(ensureState(states, sessionId), inputMessages.length);
|
|
21031
|
+
},
|
|
20507
21032
|
replayFits: (sessionId, messages, inputMessages) => {
|
|
20508
21033
|
try {
|
|
20509
21034
|
const fit = lkgReplayFits({
|
|
@@ -20649,6 +21174,24 @@ function createRustModeTransform(deps, options) {
|
|
|
20649
21174
|
bindSystemDateRequest(output, dateRequest);
|
|
20650
21175
|
const passObservedAtMs = Date.now();
|
|
20651
21176
|
const state = ensureState(states, sessionId);
|
|
21177
|
+
let rawRebuild;
|
|
21178
|
+
let rawReadError;
|
|
21179
|
+
try {
|
|
21180
|
+
rawRebuild = rustRawRebuild(deps.db, sessionId);
|
|
21181
|
+
try {
|
|
21182
|
+
checkRustServedRawIngress(deps.db, sessionId, messages);
|
|
21183
|
+
} catch (error) {
|
|
21184
|
+
if (!(error instanceof RustServedRawConflict) || !rawRebuild?.pending)
|
|
21185
|
+
throw error;
|
|
21186
|
+
requestRustRawRebuild(deps.db, sessionId, error);
|
|
21187
|
+
rawRebuild = rustRawRebuild(deps.db, sessionId);
|
|
21188
|
+
}
|
|
21189
|
+
} catch (error) {
|
|
21190
|
+
if (error instanceof RustServedRawConflict)
|
|
21191
|
+
throw error;
|
|
21192
|
+
rawReadError = error;
|
|
21193
|
+
}
|
|
21194
|
+
const reconstructRaw = new Set(rawRebuild?.messageIds ?? []);
|
|
20652
21195
|
let entrySlot = getSlot(sessionId);
|
|
20653
21196
|
try {
|
|
20654
21197
|
entrySlot = loadPersistedLkgSlot(deps.db, sessionId, true) ?? entrySlot;
|
|
@@ -20687,6 +21230,7 @@ function createRustModeTransform(deps, options) {
|
|
|
20687
21230
|
let decision = "error";
|
|
20688
21231
|
let materializeReason = "none";
|
|
20689
21232
|
let frozenReleaseReason = null;
|
|
21233
|
+
let frozenReleaseFirstChanged = "unknown";
|
|
20690
21234
|
let schedulerDecision;
|
|
20691
21235
|
let responseCommitted;
|
|
20692
21236
|
let responsePrefixBustPermitted;
|
|
@@ -20712,7 +21256,7 @@ function createRustModeTransform(deps, options) {
|
|
|
20712
21256
|
let recoveryProjectRoot = options.projectRoot ?? deps.directory ?? "";
|
|
20713
21257
|
const passUsageSnapshot = loadContextUsage(deps.contextUsageMap, deps.db, sessionId);
|
|
20714
21258
|
requestInputTokens = Math.max(0, Math.floor(passUsageSnapshot.inputTokens));
|
|
20715
|
-
let preflightError;
|
|
21259
|
+
let preflightError = rawReadError;
|
|
20716
21260
|
let markerAdmissionRecovery = state.markerAdmissionFenced;
|
|
20717
21261
|
try {
|
|
20718
21262
|
markerAdmissionRecovery ||= isRustMarkerAdmissionFenced(deps.db, sessionId);
|
|
@@ -20906,7 +21450,7 @@ function createRustModeTransform(deps, options) {
|
|
|
20906
21450
|
decision,
|
|
20907
21451
|
committed: responseCommitted,
|
|
20908
21452
|
prefixBustPermitted: responsePrefixBustPermitted,
|
|
20909
|
-
reason: materializeReason,
|
|
21453
|
+
reason: applied && served && frozenReleaseReason ? `lkg_frozen_release:${frozenReleaseReason};first_changed=${frozenReleaseFirstChanged};materialize_reason=${materializeReason}` : materializeReason,
|
|
20910
21454
|
schedulerDecision,
|
|
20911
21455
|
schedulerDeferReason,
|
|
20912
21456
|
historianNoFire,
|
|
@@ -20928,7 +21472,7 @@ function createRustModeTransform(deps, options) {
|
|
|
20928
21472
|
materializeReason: materializeReason === "none" ? null : materializeReason,
|
|
20929
21473
|
inputTokens: requestInputTokens,
|
|
20930
21474
|
tsMs: passObservedAtMs,
|
|
20931
|
-
lkgFrozenReleaseReason: applied && served
|
|
21475
|
+
lkgFrozenReleaseReason: applied && served && frozenReleaseReason ? `${frozenReleaseReason};first_changed=${frozenReleaseFirstChanged}` : undefined
|
|
20932
21476
|
});
|
|
20933
21477
|
}
|
|
20934
21478
|
};
|
|
@@ -20963,7 +21507,7 @@ function createRustModeTransform(deps, options) {
|
|
|
20963
21507
|
sessionLog2(sessionId, `rust module stages (slow pass): ${detail}`);
|
|
20964
21508
|
}
|
|
20965
21509
|
};
|
|
20966
|
-
if (state.parked) {
|
|
21510
|
+
if (state.parked && !preflightError) {
|
|
20967
21511
|
state.passesSincePark += 1;
|
|
20968
21512
|
if (!emergencyFailClosed && passUsageSnapshot.percentage < RUST_PARK_PROBE_PRESSURE_BYPASS_PCT && state.passCount % RUST_PARK_RETRY_INTERVAL !== 0) {
|
|
20969
21513
|
decision = "parked";
|
|
@@ -21248,7 +21792,7 @@ function createRustModeTransform(deps, options) {
|
|
|
21248
21792
|
const id = messageIdOf(message) ?? `index:${todoStart + offset}`;
|
|
21249
21793
|
const parts = message.parts?.filter((part) => isRecord3(part) && part.type === "tool" && part.tool === "todowrite");
|
|
21250
21794
|
if (parts?.length) {
|
|
21251
|
-
todoCalls.set(id,
|
|
21795
|
+
todoCalls.set(id, createHash12("sha256").update(JSON.stringify(parts)).digest("hex"));
|
|
21252
21796
|
} else {
|
|
21253
21797
|
todoCalls.delete(id);
|
|
21254
21798
|
}
|
|
@@ -21394,6 +21938,8 @@ function createRustModeTransform(deps, options) {
|
|
|
21394
21938
|
};
|
|
21395
21939
|
let body = buildTransformBody({
|
|
21396
21940
|
sessionId,
|
|
21941
|
+
rawRebuild,
|
|
21942
|
+
servedRawBlockIds: servedRawBlockIds(deps.db, sessionId),
|
|
21397
21943
|
input: encodedInput,
|
|
21398
21944
|
nativeMessages: wireDelta ? messages.slice(wireDelta.rawStart) : messages,
|
|
21399
21945
|
toolInputKeyOrders: toolInputKeyOrders(encodedInput),
|
|
@@ -21593,6 +22139,8 @@ function createRustModeTransform(deps, options) {
|
|
|
21593
22139
|
const retryWireBuildStartedAt = performance.now();
|
|
21594
22140
|
body = buildTransformBody({
|
|
21595
22141
|
sessionId,
|
|
22142
|
+
rawRebuild,
|
|
22143
|
+
servedRawBlockIds: servedRawBlockIds(deps.db, sessionId),
|
|
21596
22144
|
input: retryEncodedInput,
|
|
21597
22145
|
nativeMessages: messages,
|
|
21598
22146
|
toolInputKeyOrders: toolInputKeyOrders(retryEncodedInput),
|
|
@@ -21652,6 +22200,13 @@ function createRustModeTransform(deps, options) {
|
|
|
21652
22200
|
sessionLog2(sessionId, `signed thinking reset fence: ${fenced.length} assistant(s) [${fenced.join(",")}]`);
|
|
21653
22201
|
}
|
|
21654
22202
|
const cacheBustingPass = moduleDecisionBusts;
|
|
22203
|
+
if (rawRebuild?.pending && !moduleDecisionBusts) {
|
|
22204
|
+
throw new EmergencyFailClosedError("Rust raw-rebuild request was not authorized by the module");
|
|
22205
|
+
}
|
|
22206
|
+
if (rawRebuild?.pending) {
|
|
22207
|
+
frozenReleaseReason = `raw_replay_${rawRebuild.reason}`;
|
|
22208
|
+
frozenReleaseFirstChanged = rawRebuild.firstBlockId;
|
|
22209
|
+
}
|
|
21655
22210
|
let frozenReplayReleased = false;
|
|
21656
22211
|
if (markerAdmissionRecovery && !moduleDecisionBusts)
|
|
21657
22212
|
throw new RustTransformProtocolError("rust marker admission recovery: supported prefix_bust_permitted=true required; upgrade ck-mc if unsupported");
|
|
@@ -21683,6 +22238,7 @@ function createRustModeTransform(deps, options) {
|
|
|
21683
22238
|
let appliedMessages = moduleMessages;
|
|
21684
22239
|
let markerStrategyFailure;
|
|
21685
22240
|
let replayedFrozenRepresentation = false;
|
|
22241
|
+
let reconstructedRaw = false;
|
|
21686
22242
|
const boundaryId = response.boundary_id;
|
|
21687
22243
|
if (typeof boundaryId === "string" && boundaryId.length > 0) {
|
|
21688
22244
|
assertNativeBoundary(moduleMessages, sessionId, boundaryId);
|
|
@@ -21727,7 +22283,7 @@ function createRustModeTransform(deps, options) {
|
|
|
21727
22283
|
}
|
|
21728
22284
|
if (recoveryFenceRebuild) {
|
|
21729
22285
|
frozenReplayReleased = true;
|
|
21730
|
-
frozenReleaseReason
|
|
22286
|
+
frozenReleaseReason ??= "lkg_recovery_fence_unproven";
|
|
21731
22287
|
frozenReleaseLastServed = { messages: null, proven: false };
|
|
21732
22288
|
}
|
|
21733
22289
|
if (state.lkgRepresentationFrozen && !shouldAdoptModuleAfterFreeze(moduleDecisionBusts, frozenReplayReleased)) {
|
|
@@ -21792,6 +22348,10 @@ function createRustModeTransform(deps, options) {
|
|
|
21792
22348
|
if (!replayedFrozenRepresentation) {
|
|
21793
22349
|
const outputCloneStartedAt = performance.now();
|
|
21794
22350
|
appliedMessages = cloneModuleNativeOutput(moduleMessages);
|
|
22351
|
+
if (!moduleDecisionBusts || rawRebuild?.pending && rawRebuild.reason.startsWith("candidate")) {
|
|
22352
|
+
const covered = moduleDecisionBusts && typeof response.coverage_ordinal === "number" ? new Set([...state.idOrdinalMemo].filter(([, ordinal]) => ordinal <= Number(response.coverage_ordinal)).map(([id]) => id)) : new Set;
|
|
22353
|
+
reconstructedRaw = preserveRustServedRaw(deps.db, sessionId, appliedMessages, messages, reconstructRaw, covered);
|
|
22354
|
+
}
|
|
21795
22355
|
timings.outputClone += performance.now() - outputCloneStartedAt;
|
|
21796
22356
|
}
|
|
21797
22357
|
pendingWireCache.nativeOutput = moduleMessages;
|
|
@@ -21850,7 +22410,7 @@ function createRustModeTransform(deps, options) {
|
|
|
21850
22410
|
prefixPermissionSupported: permissionSupported,
|
|
21851
22411
|
moduleReasoningTrimOnly: response.reasoning_trim_only === true,
|
|
21852
22412
|
moduleSignedThinkingReset: response.signed_thinking_reset === true,
|
|
21853
|
-
...
|
|
22413
|
+
...moduleDecisionBusts && (passStartedFrozen || frozenReleaseReason || coldStartLastServed) ? { frozenReleaseLastServed } : {},
|
|
21854
22414
|
trailingBlankSourceDecisions,
|
|
21855
22415
|
trailingBlankNewestAssistantId: typeof trailingBlankNewestAssistantId === "string" ? trailingBlankNewestAssistantId : undefined,
|
|
21856
22416
|
tagger: deps.tagger,
|
|
@@ -21861,6 +22421,23 @@ function createRustModeTransform(deps, options) {
|
|
|
21861
22421
|
if (markerStrategyFailure)
|
|
21862
22422
|
throw markerStrategyFailure;
|
|
21863
22423
|
}
|
|
22424
|
+
if (!moduleDecisionBusts && !replayedFrozenRepresentation) {
|
|
22425
|
+
reconstructedRaw = preserveRustServedRaw(deps.db, sessionId, appliedMessages, messages, reconstructRaw) || reconstructedRaw;
|
|
22426
|
+
replayRustModeBindingMismatchStrips2({
|
|
22427
|
+
db: deps.db,
|
|
22428
|
+
sessionId,
|
|
22429
|
+
messages: appliedMessages,
|
|
22430
|
+
resolvedProviderID: model?.providerID
|
|
22431
|
+
});
|
|
22432
|
+
if (servedRawBlockIds(deps.db, sessionId).length > 0 && (!validateLkgSeam([], appliedMessages, model?.providerID ?? null) || model?.providerID === "anthropic" && !validateAnthropicReasoningRuns(appliedMessages.map((message) => ({
|
|
22433
|
+
...message,
|
|
22434
|
+
parts: message.parts.filter((part) => !isRecord3(part) || !["text", "reasoning"].includes(String(part.type)) || part.text !== "")
|
|
22435
|
+
}))))) {
|
|
22436
|
+
throw new RustServedRawConflict("candidate_conflict", [
|
|
22437
|
+
...new Set(servedRawBlockIds(deps.db, sessionId).map((id) => id.replace(/#\d+$/, "")))
|
|
22438
|
+
], servedRawBlockIds(deps.db, sessionId)[0] ?? "unknown");
|
|
22439
|
+
}
|
|
22440
|
+
}
|
|
21864
22441
|
if (typeof boundaryId === "string" && boundaryId.length > 0) {
|
|
21865
22442
|
assertNativeBoundary(appliedMessages, sessionId, boundaryId);
|
|
21866
22443
|
}
|
|
@@ -21896,6 +22473,24 @@ function createRustModeTransform(deps, options) {
|
|
|
21896
22473
|
}
|
|
21897
22474
|
}
|
|
21898
22475
|
logStage(sessionId, "apply", applyStartedAt, timings);
|
|
22476
|
+
if (frozenReleaseReason && frozenReleaseLastServed.messages && [...frozenReleaseLastServed.messages, ...appliedMessages].every((message) => isRecord3(message) && isRecord3(message.info) && Array.isArray(message.parts))) {
|
|
22477
|
+
frozenReleaseFirstChanged = "none";
|
|
22478
|
+
const byId = new Map(appliedMessages.map((message) => [message.info.id, message]));
|
|
22479
|
+
for (const before of frozenReleaseLastServed.messages) {
|
|
22480
|
+
const after = byId.get(before.info.id);
|
|
22481
|
+
const index = before.parts.findIndex((part, i) => JSON.stringify(part) !== JSON.stringify(after?.parts[i]));
|
|
22482
|
+
if (!after || index >= 0) {
|
|
22483
|
+
const blockIndex = index > 0 ? encodeOpenCodeMessagesToCk([
|
|
22484
|
+
{ ...before, parts: before.parts.slice(0, index) }
|
|
22485
|
+
])[0].ck.content.length : 0;
|
|
22486
|
+
frozenReleaseFirstChanged = `${before.info.id}#${blockIndex}`;
|
|
22487
|
+
break;
|
|
22488
|
+
}
|
|
22489
|
+
}
|
|
22490
|
+
}
|
|
22491
|
+
if (replayedFrozenRepresentation || reconstructedRaw) {
|
|
22492
|
+
noteRustServedRaw(deps.db, sessionId, messages, appliedMessages);
|
|
22493
|
+
}
|
|
21899
22494
|
const lkgInputIds = messages.map((message) => message.info.id);
|
|
21900
22495
|
const lkgInputKeys = resolveLkgModelKeys(messages);
|
|
21901
22496
|
const applyReplaceStartedAt = performance.now();
|
|
@@ -22153,6 +22748,9 @@ function createRustModeTransform(deps, options) {
|
|
|
22153
22748
|
}
|
|
22154
22749
|
}
|
|
22155
22750
|
}
|
|
22751
|
+
if (moduleDecisionBusts) {
|
|
22752
|
+
releaseRustServedRaw(deps.db, sessionId, output.messages, rawRebuild?.identity);
|
|
22753
|
+
}
|
|
22156
22754
|
} catch (error) {
|
|
22157
22755
|
if (markerDefinitelyNoCut) {
|
|
22158
22756
|
try {
|
|
@@ -22290,7 +22888,12 @@ function createRustModeTransform(deps, options) {
|
|
|
22290
22888
|
const adapter = {
|
|
22291
22889
|
run: async (sessionId, messages, output, sessionMeta) => {
|
|
22292
22890
|
try {
|
|
22293
|
-
await withSqliteTransformPass2(() => run(sessionId, messages, output, sessionMeta));
|
|
22891
|
+
await withReplayEnvelopeSnapshot(deps.db, sessionId, () => withSqliteTransformPass2(() => run(sessionId, messages, output, sessionMeta)));
|
|
22892
|
+
} catch (error) {
|
|
22893
|
+
if (error instanceof RustServedRawConflict) {
|
|
22894
|
+
recordRawConflict(sessionId, error);
|
|
22895
|
+
}
|
|
22896
|
+
throw error;
|
|
22294
22897
|
} finally {
|
|
22295
22898
|
try {
|
|
22296
22899
|
withoutSqliteTransformPass2(() => resolveHostRunner()?.pump(sessionId));
|
|
@@ -22714,15 +23317,27 @@ class UnmanagedOverWindowError extends Error {
|
|
|
22714
23317
|
}
|
|
22715
23318
|
|
|
22716
23319
|
// src/hooks/magic-context/unresolved-history-boundary.ts
|
|
23320
|
+
function storedHistoryBoundaryPresence(db, sessionId) {
|
|
23321
|
+
try {
|
|
23322
|
+
const row = db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id = ?").get(sessionId);
|
|
23323
|
+
return row?.id ? hasRawSessionMessageById2(sessionId, row.id) : undefined;
|
|
23324
|
+
} catch {
|
|
23325
|
+
return;
|
|
23326
|
+
}
|
|
23327
|
+
}
|
|
23328
|
+
|
|
22717
23329
|
class UnresolvedHistoryBoundaryError extends Error {
|
|
22718
23330
|
estimatedTokens;
|
|
22719
23331
|
contextLimitTokens;
|
|
23332
|
+
boundaryPresent;
|
|
22720
23333
|
code = "UNRESOLVED_HISTORY_BOUNDARY";
|
|
22721
23334
|
recoverable = true;
|
|
22722
|
-
constructor(estimatedTokens, contextLimitTokens) {
|
|
22723
|
-
|
|
23335
|
+
constructor(estimatedTokens, contextLimitTokens, boundaryPresent) {
|
|
23336
|
+
const reason = boundaryPresent === true ? "The boundary row is present in the host store but out of order relative to the loaded history. " : boundaryPresent === false ? "The boundary row is missing from the host store. " : "";
|
|
23337
|
+
super(reason + renderUserFacingFailure("history_boundary_unresolved", "plain"));
|
|
22724
23338
|
this.estimatedTokens = estimatedTokens;
|
|
22725
23339
|
this.contextLimitTokens = contextLimitTokens;
|
|
23340
|
+
this.boundaryPresent = boundaryPresent;
|
|
22726
23341
|
this.name = "UnresolvedHistoryBoundaryError";
|
|
22727
23342
|
}
|
|
22728
23343
|
}
|
|
@@ -23888,7 +24503,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
|
|
|
23888
24503
|
});
|
|
23889
24504
|
if (untrimmed.tokens > boundaryContextLimit) {
|
|
23890
24505
|
sessionLog2(sessionId, `history boundary unresolved: prefix trim refused and the untrimmed request estimate ${untrimmed.tokens} (trusted=${untrimmed.trusted}) exceeds the context limit ${boundaryContextLimit}; not sending it`);
|
|
23891
|
-
throw new UnresolvedHistoryBoundaryError(untrimmed.tokens, boundaryContextLimit);
|
|
24506
|
+
throw new UnresolvedHistoryBoundaryError(untrimmed.tokens, boundaryContextLimit, storedHistoryBoundaryPresence(db, sessionId));
|
|
23892
24507
|
}
|
|
23893
24508
|
}
|
|
23894
24509
|
if (unmanagedOverWindowPass) {
|
|
@@ -24286,12 +24901,12 @@ function createRustRefusalRecovery(options) {
|
|
|
24286
24901
|
watchers.delete(sessionId);
|
|
24287
24902
|
};
|
|
24288
24903
|
const schedule = (sessionId, watcher) => {
|
|
24289
|
-
watcher.timer = setTimeout(() => void poll(sessionId, watcher), pollIntervalMs);
|
|
24904
|
+
watcher.timer = inRootAsyncContext2(() => setTimeout(() => void poll(sessionId, watcher), pollIntervalMs));
|
|
24290
24905
|
};
|
|
24291
24906
|
const probe = async (watcher, sessionId) => {
|
|
24292
24907
|
const controller = new AbortController;
|
|
24293
24908
|
const timeoutError = new Error("rust refusal recovery probe timed out");
|
|
24294
|
-
const timer = setTimeout(() => controller.abort(timeoutError), probeTimeoutMs);
|
|
24909
|
+
const timer = inRootAsyncContext2(() => setTimeout(() => controller.abort(timeoutError), probeTimeoutMs));
|
|
24295
24910
|
try {
|
|
24296
24911
|
await Promise.race([
|
|
24297
24912
|
options.moduleClient.call({
|
|
@@ -24394,7 +25009,7 @@ function createRustRefusalRecovery(options) {
|
|
|
24394
25009
|
}
|
|
24395
25010
|
|
|
24396
25011
|
// src/hooks/magic-context/system-prompt-hash.ts
|
|
24397
|
-
import { createHash as
|
|
25012
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
24398
25013
|
|
|
24399
25014
|
// src/hooks/magic-context/system-prompt-dates.ts
|
|
24400
25015
|
function replaceHostDates(prompt, replace) {
|
|
@@ -24507,7 +25122,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
24507
25122
|
const dates = systemPromptDates(liveSystemContent, stickyDate);
|
|
24508
25123
|
const currentDate = dates.live;
|
|
24509
25124
|
const stableCandidate = dates.stable;
|
|
24510
|
-
const stableCandidateHash =
|
|
25125
|
+
const stableCandidateHash = createHash13("md5").update(promptSurfaceHashMaterial(stableCandidate, promptSurface.preset)).digest("hex");
|
|
24511
25126
|
const contentOrPresetChanged = hasPersistedHash && stableCandidateHash !== previousHash;
|
|
24512
25127
|
const rewritePermission = systemDateRefreshPermission(deps.historyRefreshSessions, dateRequest);
|
|
24513
25128
|
let deferredDateRefresh = false;
|
|
@@ -24521,7 +25136,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
24521
25136
|
try {
|
|
24522
25137
|
const content = liveElements.join(`
|
|
24523
25138
|
`);
|
|
24524
|
-
const hash =
|
|
25139
|
+
const hash = createHash13("md5").update(promptSurfaceHashMaterial(content, promptSurface.preset)).digest("hex");
|
|
24525
25140
|
updateSessionMeta(deps.db, sessionId, {
|
|
24526
25141
|
systemPromptHash: hash,
|
|
24527
25142
|
cachedM0SystemHash: hash,
|
|
@@ -24561,7 +25176,7 @@ function createSystemPromptHashHandler(deps) {
|
|
|
24561
25176
|
`);
|
|
24562
25177
|
if (!availability.frozen || !modelKey)
|
|
24563
25178
|
return;
|
|
24564
|
-
const currentHash =
|
|
25179
|
+
const currentHash = createHash13("md5").update(promptSurfaceHashMaterial(systemContent, promptSurface.preset)).digest("hex");
|
|
24565
25180
|
recordSystemPromptForRequest(sessionId, currentLkgRequestIdentity(sessionId), currentHash, deps.db, previousHash !== currentHash ? !deps.historyRefreshSessions.has(sessionId) : undefined, deps.historyRefreshSessions, deps.pendingMaterializationSessions);
|
|
24566
25181
|
if (!sessionMetaEarly) {
|
|
24567
25182
|
return;
|
|
@@ -24621,6 +25236,114 @@ function createSystemPromptHashHandler(deps) {
|
|
|
24621
25236
|
};
|
|
24622
25237
|
}
|
|
24623
25238
|
|
|
25239
|
+
// src/shared/recovery-reasoning-prefix.ts
|
|
25240
|
+
function recoveryReasoningPrefixes(messages, partsKey) {
|
|
25241
|
+
const prefixes = [];
|
|
25242
|
+
for (let index = 0;index < messages.length; index++) {
|
|
25243
|
+
const message = messages[index];
|
|
25244
|
+
const parts = message?.[partsKey];
|
|
25245
|
+
if (!Array.isArray(parts))
|
|
25246
|
+
continue;
|
|
25247
|
+
for (let p = 0;p < parts.length; p++) {
|
|
25248
|
+
const type = parts[p]?.type;
|
|
25249
|
+
if (type !== "thinking" && type !== "reasoning" && type !== "redactedThinking" && type !== "redacted_thinking")
|
|
25250
|
+
continue;
|
|
25251
|
+
prefixes.push(JSON.stringify([
|
|
25252
|
+
...messages.slice(0, index),
|
|
25253
|
+
{ ...message, [partsKey]: parts.slice(0, p + 1) }
|
|
25254
|
+
]));
|
|
25255
|
+
}
|
|
25256
|
+
}
|
|
25257
|
+
return prefixes;
|
|
25258
|
+
}
|
|
25259
|
+
|
|
25260
|
+
// src/hooks/magic-context/replay-committed-drops.ts
|
|
25261
|
+
function replayCommittedDrops(db, sessionId, messages) {
|
|
25262
|
+
const original = messages;
|
|
25263
|
+
const reasoningPrefixes = recoveryReasoningPrefixes(messages, "parts");
|
|
25264
|
+
if (reasoningPrefixes.length)
|
|
25265
|
+
messages = structuredClone(messages);
|
|
25266
|
+
const tags = getTagsBySession2(db, sessionId).filter((tag) => tag.status === "dropped");
|
|
25267
|
+
const toolTags = new Map(tags.filter((tag) => tag.type === "tool").map((tag) => [makeToolCompositeKey(tag.toolOwnerMessageId ?? "", tag.messageId), tag]));
|
|
25268
|
+
const textTags = new Map(tags.filter((tag) => tag.type !== "tool").map((tag) => [tag.messageId, tag]));
|
|
25269
|
+
const byNumber = new Map(tags.map((tag) => [tag.tagNumber, tag]));
|
|
25270
|
+
const index = new Map;
|
|
25271
|
+
const owners = new Map;
|
|
25272
|
+
const resolvedOwners = new Map;
|
|
25273
|
+
const ambiguousCalls = new Set;
|
|
25274
|
+
const targets = new Map;
|
|
25275
|
+
let precedingThinking = [];
|
|
25276
|
+
const toolThinking = new Map;
|
|
25277
|
+
const batch = new ToolMutationBatch(messages);
|
|
25278
|
+
for (const message of messages) {
|
|
25279
|
+
if (message.info.role === "user")
|
|
25280
|
+
precedingThinking = [];
|
|
25281
|
+
const thinking = message.parts.filter(isThinkingPart);
|
|
25282
|
+
for (let p = 0;p < message.parts.length; p++) {
|
|
25283
|
+
const part = message.parts[p];
|
|
25284
|
+
const observation = extractToolCallObservation(part);
|
|
25285
|
+
if (observation) {
|
|
25286
|
+
const { callId, kind } = observation;
|
|
25287
|
+
const pending = owners.get(callId) ?? [];
|
|
25288
|
+
if (pending.length > 1)
|
|
25289
|
+
ambiguousCalls.add(callId);
|
|
25290
|
+
const hostingKey = makeToolCompositeKey(message.info.id ?? "", callId);
|
|
25291
|
+
const owner = kind === "invocation" || part.type === "tool" || toolTags.has(hostingKey) ? message.info.id ?? "" : pending.shift() ?? resolvedOwners.get(callId) ?? message.info.id ?? "";
|
|
25292
|
+
if (kind === "invocation")
|
|
25293
|
+
pending.push(owner);
|
|
25294
|
+
else
|
|
25295
|
+
resolvedOwners.set(callId, owner);
|
|
25296
|
+
owners.set(callId, pending);
|
|
25297
|
+
const key = makeToolCompositeKey(owner, callId);
|
|
25298
|
+
if (message.info.role === "tool" && !toolThinking.has(key))
|
|
25299
|
+
toolThinking.set(key, precedingThinking);
|
|
25300
|
+
const entry = index.get(key) ?? { occurrences: [], hasResult: false };
|
|
25301
|
+
entry.occurrences.push({ message, part, kind });
|
|
25302
|
+
entry.hasResult ||= kind === "result" && partHasCompletedResult(part);
|
|
25303
|
+
index.set(key, entry);
|
|
25304
|
+
} else {
|
|
25305
|
+
const prefix = isTextPart(part) ? /^§(\d+)§\s/.exec(part.text) : null;
|
|
25306
|
+
const tag = (prefix ? byNumber.get(Number(prefix[1])) : undefined) ?? textTags.get(`${message.info.id}:p${p}`) ?? textTags.get(`${message.info.id}:file${p}`);
|
|
25307
|
+
if (tag && tag.type !== "tool")
|
|
25308
|
+
targets.set(tag.tagNumber, {
|
|
25309
|
+
message,
|
|
25310
|
+
setContent(content) {
|
|
25311
|
+
if (isTextPart(part)) {
|
|
25312
|
+
if (part.text === content)
|
|
25313
|
+
return false;
|
|
25314
|
+
part.text = content;
|
|
25315
|
+
} else
|
|
25316
|
+
message.parts[p] = { type: "text", text: content };
|
|
25317
|
+
return true;
|
|
25318
|
+
}
|
|
25319
|
+
});
|
|
25320
|
+
}
|
|
25321
|
+
}
|
|
25322
|
+
if (message.info.role === "assistant" && !message.parts.some(isTextPart))
|
|
25323
|
+
precedingThinking = thinking;
|
|
25324
|
+
}
|
|
25325
|
+
const arcsByCall = new Map;
|
|
25326
|
+
for (const entry of index.values()) {
|
|
25327
|
+
const callId = extractToolCallObservation(entry.occurrences[0]?.part)?.callId ?? "";
|
|
25328
|
+
arcsByCall.set(callId, (arcsByCall.get(callId) ?? 0) + 1);
|
|
25329
|
+
}
|
|
25330
|
+
for (const [key, entry] of index) {
|
|
25331
|
+
const callId = extractToolCallObservation(entry.occurrences[0]?.part)?.callId ?? "";
|
|
25332
|
+
if (ambiguousCalls.has(callId))
|
|
25333
|
+
continue;
|
|
25334
|
+
const tag = toolTags.get(key) ?? (arcsByCall.get(callId) === 1 ? toolTags.get(makeToolCompositeKey("", callId)) : undefined);
|
|
25335
|
+
if (tag)
|
|
25336
|
+
targets.set(tag.tagNumber, createToolDropTarget(key, toolThinking.get(key) ?? [], index, batch, tag.tagNumber));
|
|
25337
|
+
}
|
|
25338
|
+
applyFlushedStatuses(sessionId, db, targets, tags);
|
|
25339
|
+
batch.finalize();
|
|
25340
|
+
if (JSON.stringify(recoveryReasoningPrefixes(messages, "parts")) !== JSON.stringify(reasoningPrefixes))
|
|
25341
|
+
return false;
|
|
25342
|
+
if (messages !== original)
|
|
25343
|
+
original.splice(0, original.length, ...messages);
|
|
25344
|
+
return true;
|
|
25345
|
+
}
|
|
25346
|
+
|
|
24624
25347
|
// src/plugin/messages-transform.ts
|
|
24625
25348
|
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.";
|
|
24626
25349
|
|
|
@@ -24763,7 +25486,6 @@ function tryMessagesTransformLkgReplay(args) {
|
|
|
24763
25486
|
sessionLog2(sessionId, "lkg_emergency_armed");
|
|
24764
25487
|
} else {
|
|
24765
25488
|
const inputMessages = output.messages;
|
|
24766
|
-
const inputCount = inputMessages.length;
|
|
24767
25489
|
const keys = resolveLkgModelKeys(inputMessages);
|
|
24768
25490
|
const replay = replayLkg({
|
|
24769
25491
|
sessionId,
|
|
@@ -24782,6 +25504,10 @@ function tryMessagesTransformLkgReplay(args) {
|
|
|
24782
25504
|
sessionLog2(sessionId, "lkg_restart_rebuild_required");
|
|
24783
25505
|
return false;
|
|
24784
25506
|
}
|
|
25507
|
+
if (replay.ok && !rust && !replayCommittedDrops(db, sessionId, replay.messages)) {
|
|
25508
|
+
sessionLog2(sessionId, "lkg_reasoning_prefix_changed");
|
|
25509
|
+
return false;
|
|
25510
|
+
}
|
|
24785
25511
|
let tsFit = true;
|
|
24786
25512
|
if (replay.ok && !rust && keys.providerKey && keys.modelKey) {
|
|
24787
25513
|
const model = {
|
|
@@ -24831,8 +25557,8 @@ function tryMessagesTransformLkgReplay(args) {
|
|
|
24831
25557
|
return false;
|
|
24832
25558
|
retirePendingSystemPromptDelivery(sessionId);
|
|
24833
25559
|
args.onLkgReplay?.();
|
|
25560
|
+
noteExternalLkgReplay(rust, sessionId, inputMessages, replay.messages);
|
|
24834
25561
|
replaceMessagesInPlace2(output, replay.messages);
|
|
24835
|
-
noteExternalLkgReplay(rust, sessionId, inputCount);
|
|
24836
25562
|
sessionLog2(sessionId, "lkg_replay_served");
|
|
24837
25563
|
return true;
|
|
24838
25564
|
} else {
|
|
@@ -25228,7 +25954,7 @@ function resolveCtxExpandMode(args, domain) {
|
|
|
25228
25954
|
}
|
|
25229
25955
|
|
|
25230
25956
|
// src/tools/ctx-expand/render.ts
|
|
25231
|
-
import { createHash as
|
|
25957
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
25232
25958
|
function isRecord4(value) {
|
|
25233
25959
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
25234
25960
|
}
|
|
@@ -25452,11 +26178,61 @@ function renderItemByTag(db, sessionId, number, textIndexDomain = "part") {
|
|
|
25452
26178
|
const index = scoped ? Number(scoped[2]) : 0;
|
|
25453
26179
|
const piText = message.parts.filter((part) => isRecord4(part) && part.type === "text");
|
|
25454
26180
|
const part = message.parts[index];
|
|
25455
|
-
const matching = derived ? piText.filter((part) => isRecord4(part) && typeof part.text === "string" &&
|
|
26181
|
+
const matching = derived ? piText.filter((part) => isRecord4(part) && typeof part.text === "string" && createHash14("sha256").update(part.text).digest("hex") === derived[3]) : [];
|
|
25456
26182
|
const selected = derived ? matching[Number(derived[4])] : textIndexDomain === "text" ? piText[index] : part;
|
|
25457
26183
|
return selected ? renderPartFull(selected) ?? "" : `Tag ${number}'s original text part is no longer in stored history.`;
|
|
25458
26184
|
}
|
|
25459
26185
|
|
|
26186
|
+
// src/tools/ctx-expand/search-archive.ts
|
|
26187
|
+
function renderSearchArchive(db, sessionId, start, end, tokenBudget, archiveOnly = false) {
|
|
26188
|
+
return withMessageFtsSessionFilter(db, sessionId, (sessionFirst) => {
|
|
26189
|
+
let rawIds;
|
|
26190
|
+
const rows = db.prepare(sessionFirst ? `SELECT f.message_ordinal AS ordinal, f.message_id AS id, f.role, f.content
|
|
26191
|
+
FROM message_fts_rowid_map AS m
|
|
26192
|
+
JOIN message_history_fts AS f ON f.rowid = m.fts_rowid
|
|
26193
|
+
WHERE m.session_id = ?1 AND m.message_ordinal BETWEEN ?2 AND ?3
|
|
26194
|
+
AND f.session_id = ?1 AND f.message_ordinal BETWEEN ?2 AND ?3
|
|
26195
|
+
ORDER BY m.message_ordinal` : `SELECT message_ordinal AS ordinal, message_id AS id, role, content
|
|
26196
|
+
FROM message_history_fts
|
|
26197
|
+
WHERE session_id = ?1 AND message_ordinal BETWEEN ?2 AND ?3
|
|
26198
|
+
ORDER BY CAST(message_ordinal AS INTEGER)`);
|
|
26199
|
+
const blocks = [];
|
|
26200
|
+
let tokens = 0;
|
|
26201
|
+
let lastOrdinal = start - 1;
|
|
26202
|
+
let truncated = false;
|
|
26203
|
+
for (const row of rows.iterate(sessionId, start, end)) {
|
|
26204
|
+
if (!row.content)
|
|
26205
|
+
continue;
|
|
26206
|
+
if (!archiveOnly) {
|
|
26207
|
+
rawIds ??= readRawSessionMessageIdOrdinalsForRange2(sessionId, start, end);
|
|
26208
|
+
if (rawIds.get(row.id) === row.ordinal)
|
|
26209
|
+
continue;
|
|
26210
|
+
}
|
|
26211
|
+
const block = `[${row.ordinal}] ${row.role === "user" ? "U" : "A"}: ${row.content}`;
|
|
26212
|
+
const cost = estimateTokens(block);
|
|
26213
|
+
if (blocks.length > 0 && tokens + cost > tokenBudget) {
|
|
26214
|
+
truncated = true;
|
|
26215
|
+
break;
|
|
26216
|
+
}
|
|
26217
|
+
blocks.push(block);
|
|
26218
|
+
tokens += cost;
|
|
26219
|
+
lastOrdinal = row.ordinal;
|
|
26220
|
+
}
|
|
26221
|
+
if (blocks.length === 0)
|
|
26222
|
+
return null;
|
|
26223
|
+
const text = [
|
|
26224
|
+
"From the search archive: indexed text only; no surrounding messages or tool output.",
|
|
26225
|
+
"",
|
|
26226
|
+
...blocks
|
|
26227
|
+
];
|
|
26228
|
+
if (truncated) {
|
|
26229
|
+
text.push("", `Truncated at message ${lastOrdinal} (budget: ~${tokenBudget} tokens). Call ctx_expand(start=${lastOrdinal + 1}, end=${end}) for more archived text.`);
|
|
26230
|
+
}
|
|
26231
|
+
return text.join(`
|
|
26232
|
+
`);
|
|
26233
|
+
});
|
|
26234
|
+
}
|
|
26235
|
+
|
|
25460
26236
|
// src/tools/ctx-expand/tools.ts
|
|
25461
26237
|
var ctxExpandArgsShape = {
|
|
25462
26238
|
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."),
|
|
@@ -25490,7 +26266,7 @@ function createCtxExpandTool(deps) {
|
|
|
25490
26266
|
return renderItemByTag(deps.db, sessionId, mode.tag);
|
|
25491
26267
|
}
|
|
25492
26268
|
if (mode.kind === "message") {
|
|
25493
|
-
return renderMessageByOrdinal(sessionId, mode.message);
|
|
26269
|
+
return renderSearchArchive(deps.db, sessionId, mode.message, mode.message, CTX_EXPAND_TOKEN_BUDGET) ?? renderMessageByOrdinal(sessionId, mode.message);
|
|
25494
26270
|
}
|
|
25495
26271
|
const { start, end, verbose } = mode;
|
|
25496
26272
|
const lastCompartmentEnd = getLastCompartmentEndMessage(deps.db, sessionId);
|
|
@@ -25498,6 +26274,9 @@ function createCtxExpandTool(deps) {
|
|
|
25498
26274
|
return `Range ${start}-${end} is entirely within the live tail (after the last compacted message ${lastCompartmentEnd}); those messages are already visible in context.`;
|
|
25499
26275
|
}
|
|
25500
26276
|
const effectiveEnd = lastCompartmentEnd >= 0 ? Math.min(end, lastCompartmentEnd) : end;
|
|
26277
|
+
const archived = renderSearchArchive(deps.db, sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET);
|
|
26278
|
+
if (archived)
|
|
26279
|
+
return archived;
|
|
25501
26280
|
if (verbose) {
|
|
25502
26281
|
const v = renderVerboseRange(sessionId, start, effectiveEnd, CTX_EXPAND_TOKEN_BUDGET, deps.expandTools);
|
|
25503
26282
|
if (!v.text) {
|
|
@@ -26353,9 +27132,9 @@ function isMissingError(error) {
|
|
|
26353
27132
|
}
|
|
26354
27133
|
|
|
26355
27134
|
// ../retina-local-fs/src/provider.ts
|
|
26356
|
-
import { execFile as
|
|
26357
|
-
import { promisify as
|
|
26358
|
-
var
|
|
27135
|
+
import { execFile as execFile4 } from "node:child_process";
|
|
27136
|
+
import { promisify as promisify4 } from "node:util";
|
|
27137
|
+
var execFileAsync3 = promisify4(execFile4);
|
|
26359
27138
|
function parseSemver(value) {
|
|
26360
27139
|
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);
|
|
26361
27140
|
if (!match) {
|
|
@@ -27004,7 +27783,7 @@ function formatCtxReduceReply(stampedCount, selfStampCount = 0) {
|
|
|
27004
27783
|
return parts.join(" ");
|
|
27005
27784
|
}
|
|
27006
27785
|
// src/tools/ctx-reduce/tools.ts
|
|
27007
|
-
import { createHash as
|
|
27786
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
27008
27787
|
import { tool as tool4 } from "@opencode-ai/plugin";
|
|
27009
27788
|
|
|
27010
27789
|
// src/features/magic-context/range-parser.ts
|
|
@@ -27068,11 +27847,11 @@ function createCtxReduceTool(deps) {
|
|
|
27068
27847
|
const stableId = `oc-${sessionId}-${callId}`;
|
|
27069
27848
|
if (Buffer.byteLength(stableId) <= 128)
|
|
27070
27849
|
return stableId;
|
|
27071
|
-
return `oc-${
|
|
27850
|
+
return `oc-${createHash15("sha256").update(stableId).digest("hex")}`;
|
|
27072
27851
|
}
|
|
27073
27852
|
fallbackCommandSequence += 1;
|
|
27074
27853
|
const monotonicId = `oc-${sessionId}-${fallbackCommandSequence}`;
|
|
27075
|
-
return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${
|
|
27854
|
+
return Buffer.byteLength(monotonicId) <= 128 ? monotonicId : `oc-${createHash15("sha256").update(monotonicId).digest("hex")}`;
|
|
27076
27855
|
};
|
|
27077
27856
|
return tool4({
|
|
27078
27857
|
description: CTX_REDUCE_DESCRIPTION,
|
|
@@ -27532,7 +28311,7 @@ class MagicContextRpcServer {
|
|
|
27532
28311
|
}
|
|
27533
28312
|
this.startedAt = Date.now();
|
|
27534
28313
|
const self = this;
|
|
27535
|
-
const server = Bun.serve({
|
|
28314
|
+
const server = inRootAsyncContext2(() => Bun.serve({
|
|
27536
28315
|
port: 0,
|
|
27537
28316
|
hostname: "127.0.0.1",
|
|
27538
28317
|
fetch(req, srv) {
|
|
@@ -27555,7 +28334,7 @@ class MagicContextRpcServer {
|
|
|
27555
28334
|
self.sockets.delete(ws);
|
|
27556
28335
|
}
|
|
27557
28336
|
}
|
|
27558
|
-
});
|
|
28337
|
+
}));
|
|
27559
28338
|
this.server = server;
|
|
27560
28339
|
this.port = server.port ?? 0;
|
|
27561
28340
|
try {
|