@cortexkit/opencode-magic-context 0.48.0 → 0.49.1
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/{announcement-fp14dw0n.js → announcement-hdbkt8v5.js} +1 -1
- package/dist/auto-search-worker.js +3 -3
- package/dist/config/{mural-model-deprecation.d.ts → deprecated-config.d.ts} +4 -1
- package/dist/config/deprecated-config.d.ts.map +1 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/project-security.d.ts +2 -2
- package/dist/config/schema/magic-context.d.ts +4 -4
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-w8cykrnf.js → conflict-warning-hook-asnt6hfc.js} +7 -7
- package/dist/{context-m0cy262m.js → context-tfyhtdcs.js} +187 -68
- package/dist/{derive-budgets-sg0xsq7s.js → derive-budgets-j4ry8j8n.js} +2 -2
- package/dist/embedding-backfill-wyc3ykyf.js +21 -0
- package/dist/embedding-worker-process.js +30 -0
- package/dist/embedding-worker.js +6 -6
- package/dist/features/magic-context/dreamer/task-registry.d.ts +2 -3
- package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
- package/dist/features/magic-context/git-commits/search-git-commits.d.ts +2 -0
- package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-worker-client.d.ts +8 -1
- package/dist/features/magic-context/memory/embedding-worker-client.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-worker-process.d.ts +2 -0
- package/dist/features/magic-context/memory/embedding-worker-process.d.ts.map +1 -0
- package/dist/features/magic-context/memory/onnx-telemetry.d.ts +3 -0
- package/dist/features/magic-context/memory/onnx-telemetry.d.ts.map +1 -0
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts +1 -2
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/pi-content-decisions.d.ts +1 -1
- package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -1
- package/dist/features/magic-context/search-rerank.d.ts +35 -0
- package/dist/features/magic-context/search-rerank.d.ts.map +1 -0
- package/dist/features/magic-context/search.d.ts +11 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +13 -2
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta.d.ts +1 -1
- package/dist/features/magic-context/storage-meta.d.ts.map +1 -1
- package/dist/features/magic-context/storage-session-tables.d.ts +2 -0
- package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tag-identity-revision.d.ts +29 -9
- package/dist/features/magic-context/storage-tag-identity-revision.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +9 -0
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -1
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/tagger.d.ts +2 -0
- package/dist/features/magic-context/tagger.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +4 -1
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts +1 -0
- package/dist/features/magic-context/user-memory/storage-user-memory.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-replay.fixture.d.ts +24 -0
- package/dist/hooks/magic-context/auto-search-replay.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts +1 -1
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-worker-client.d.ts +2 -0
- package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +2 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts +28 -0
- package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +1 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-host-runner.d.ts +8 -0
- package/dist/hooks/magic-context/historian-host-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +3 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/latest-thinking-recovery.d.ts +7 -0
- package/dist/hooks/magic-context/latest-thinking-recovery.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-measured-request.d.ts +3 -1
- package/dist/hooks/magic-context/lkg-measured-request.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-persist.d.ts +8 -14
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-recovery-fence.d.ts +62 -0
- package/dist/hooks/magic-context/lkg-recovery-fence.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts +38 -0
- package/dist/hooks/magic-context/lkg-recovery-prefix.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-replay.d.ts +3 -1
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/opaque-thinking.d.ts +12 -0
- package/dist/hooks/magic-context/opaque-thinking.d.ts.map +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts +3 -2
- package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
- package/dist/hooks/magic-context/pending-materialization.d.ts +8 -0
- package/dist/hooks/magic-context/pending-materialization.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts +7 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts +3 -0
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +35 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts +37 -0
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts +8 -1
- package/dist/hooks/magic-context/shared-compartment-boundaries.d.ts.map +1 -1
- package/dist/hooks/magic-context/strict-thinking-prefix.d.ts +8 -0
- package/dist/hooks/magic-context/strict-thinking-prefix.d.ts.map +1 -0
- package/dist/hooks/magic-context/strip-content.d.ts +5 -2
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-date-refresh.d.ts +29 -0
- package/dist/hooks/magic-context/system-date-refresh.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-prompt-dates.d.ts +6 -0
- package/dist/hooks/magic-context/system-prompt-dates.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-prompt-delivery.d.ts +47 -0
- package/dist/hooks/magic-context/system-prompt-delivery.d.ts.map +1 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +4 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +8 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +15 -0
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +7 -0
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-ty64eqcn.js → index-0pjvpfkf.js} +24 -4
- package/dist/{index-db7zwa3v.js → index-1bt88epp.js} +93 -9
- package/dist/{index-2y0s2hep.js → index-4mjhqadz.js} +1 -1
- package/dist/index-6m7rdv7y.js +733 -0
- package/dist/{index-k1xb52kd.js → index-6tfxmc4n.js} +11 -11
- package/dist/{index-fbv1dn35.js → index-7w18gg78.js} +26 -2
- package/dist/{index-7mx8v0pw.js → index-att4bfan.js} +4 -4
- package/dist/{index-mmyh6d8f.js → index-eypn4ba6.js} +11 -6
- package/dist/{index-q2tqeqde.js → index-fdtkt5r1.js} +1229 -78
- package/dist/{index-c43kr12f.js → index-fg00p1cg.js} +42 -40
- package/dist/{v2/server-1bc61ans.js → index-fvnzcnww.js} +44 -1
- package/dist/index-gbmqa9x9.js +1170 -0
- package/dist/{index-knh4y330.js → index-gzky5rva.js} +31 -49
- package/dist/{index-0qhce371.js → index-h2wc01qk.js} +2 -2
- package/dist/{index-dhwzyd54.js → index-h5zfkjyk.js} +160 -25
- package/dist/{index-bhvjj0ys.js → index-k6xvbj2e.js} +255 -1075
- package/dist/{index-0w56v4fm.js → index-mw7c950g.js} +1 -1
- package/dist/{index-8j7gqj40.js → index-nsjyysj0.js} +6 -2
- package/dist/{index-k9nnwad5.js → index-nydv6g8r.js} +44 -7
- package/dist/{index-f0h6xwqm.js → index-p0n5ryq8.js} +304 -960
- package/dist/{index-pg50n748.js → index-p1hnwfd8.js} +4 -4
- package/dist/{index-1qb0z7wa.js → index-qx53vezw.js} +1 -1
- package/dist/{index-5zygecde.js → index-r2zcs71c.js} +8 -6
- package/dist/{index-cb7emxgj.js → index-rafsaxac.js} +336 -6
- package/dist/{index-z8e0psj8.js → index-s7fc0fkn.js} +3 -3
- package/dist/{index-14cjxt20.js → index-sfhndpcb.js} +505 -11
- package/dist/index-sv0bb7vg.js +6972 -0
- package/dist/{index-jcbd3znx.js → index-tqf7yg27.js} +1 -1
- package/dist/{index-72nhv486.js → index-vkbqdnkj.js} +2 -2
- package/dist/{index-pdecwzrd.js → index-w23dh319.js} +18 -259
- package/dist/{index-yq8n9qcb.js → index-xgrwmj82.js} +4 -4
- package/dist/{index-0an7742d.js → index-xnanvj3w.js} +1364 -2278
- package/dist/{index-eeezr5zz.js → index-z1tjp257.js} +1 -1
- package/dist/{index-692jzy0p.js → index-zfzdpeq2.js} +2279 -4061
- package/dist/{index-q7h7csab.js → index-zg8yq4ya.js} +34 -749
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +241 -76
- package/dist/{logger-d3wex3dz.js → logger-ewak5q1s.js} +1 -1
- package/dist/{message-index-bounded-7ezbgddp.js → message-index-bounded-hqktkhdy.js} +15 -14
- package/dist/{message-time-backfill-brbd63hv.js → message-time-backfill-8x06r9kx.js} +2 -2
- package/dist/migration-worker.js +11 -10
- package/dist/plugin/hooks/create-session-hooks.d.ts +5 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/messages-transform.d.ts.map +1 -1
- package/dist/plugin/rpc-handlers.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{project-embedding-registry-7qzptcw7.js → project-embedding-registry-0gv3h6y8.js} +10 -10
- package/dist/raw-ordinal-warmup-worker.js +4 -4
- package/dist/{read-session-chunk-6k83m4fj.js → read-session-chunk-5mh0bh8y.js} +12 -9
- package/dist/{read-session-raw-3g9qy1xa.js → read-session-raw-8sjbc9h0.js} +5 -3
- package/dist/{recomp-orchestrator-d3fp1cy0.js → recomp-orchestrator-kpkhkjhq.js} +28 -27
- package/dist/{safe-notification-target-5ffqq32m.js → safe-notification-target-q0cyrx3x.js} +2 -2
- package/dist/{search-epax1ecv.js → search-p9w39qv4.js} +22 -21
- package/dist/{send-session-notification-erecz4y4.js → send-session-notification-xffh3bbe.js} +5 -5
- package/dist/shared/auto-search-lifecycle.d.ts +14 -0
- package/dist/shared/auto-search-lifecycle.d.ts.map +1 -1
- package/dist/shared/logger.d.ts.map +1 -1
- package/dist/shared/models-dev-cache.d.ts.map +1 -1
- package/dist/shared/models-dev-temperature.d.ts +18 -0
- package/dist/shared/models-dev-temperature.d.ts.map +1 -0
- package/dist/shared/project-directory-key.d.ts +16 -0
- package/dist/shared/project-directory-key.d.ts.map +1 -1
- package/dist/shared/storage-file-mutex.d.ts +9 -0
- package/dist/shared/storage-file-mutex.d.ts.map +1 -0
- package/dist/shared/storage-permissions.d.ts +6 -0
- package/dist/shared/storage-permissions.d.ts.map +1 -1
- package/dist/shared/subagent-temperature.d.ts +46 -0
- package/dist/shared/subagent-temperature.d.ts.map +1 -0
- package/dist/shared/window-geometry.d.ts +9 -66
- package/dist/shared/window-geometry.d.ts.map +1 -1
- package/dist/standalone-plugin-marker.d.ts +8 -0
- package/dist/standalone-plugin-marker.d.ts.map +1 -0
- package/dist/{storage-tags-d3b0v2ss.js → storage-tags-k0pda32s.js} +6 -4
- package/dist/tools/ctx-reduce/constants.d.ts +1 -2
- package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts +1 -1
- package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/types.d.ts +1 -0
- package/dist/tools/ctx-search/types.d.ts.map +1 -1
- package/dist/{transform-postprocess-phase-spcy2qre.js → transform-postprocess-phase-481j5a7z.js} +28 -27
- package/dist/v2/auto-search-worker.js +3 -3
- package/dist/v2/{context-sf98kstd.js → context-gsdtha5v.js} +1619 -3111
- package/dist/v2/{derive-budgets-3vc0y84t.js → derive-budgets-enckmg7y.js} +3 -3
- package/dist/v2/embedding-backfill-dbvjbcmm.js +20 -0
- package/dist/v2/embedding-worker-process.js +29 -0
- package/dist/v2/embedding-worker.js +6 -7
- package/dist/v2/hidden-child-native.d.ts.map +1 -1
- package/dist/v2/hidden-completion.d.ts +7 -0
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/copied-tag-notation.d.ts +19 -0
- package/dist/v2/hooks/copied-tag-notation.d.ts.map +1 -0
- package/dist/v2/hooks/dream-trigger.d.ts +4 -1
- package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
- package/dist/v2/hooks/generate.d.ts +9 -2
- package/dist/v2/hooks/generate.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/system-prompt-response.d.ts +5 -0
- package/dist/v2/hooks/system-prompt-response.d.ts.map +1 -0
- package/dist/v2/{logger-mxd0ym09.js → logger-pj02s7sr.js} +1 -1
- package/dist/v2/{message-index-bounded-dy3s2k1e.js → message-index-bounded-p6v0n8qh.js} +15 -14
- package/dist/v2/{message-time-backfill-gtx1pwk1.js → message-time-backfill-cje68egj.js} +2 -2
- package/dist/v2/migration-worker.js +11 -10
- package/dist/v2/{project-embedding-registry-1tgba5dv.js → project-embedding-registry-nyq7z8y6.js} +11 -12
- package/dist/v2/raw-ordinal-warmup-worker.js +4 -4
- package/dist/v2/{read-session-chunk-rh4khdkv.js → read-session-chunk-fhyfe4qa.js} +12 -9
- package/dist/v2/{read-session-raw-bsbmf0vj.js → read-session-raw-j8dvp7f4.js} +5 -3
- package/dist/v2/recomp-orchestrator-5xy7w136.js +57 -0
- package/dist/v2/{safe-notification-target-73ax1p5v.js → safe-notification-target-y3p1hce9.js} +2 -2
- package/dist/v2/{search-nzkwrc6n.js → search-j7bakcwa.js} +23 -23
- package/dist/v2/{send-session-notification-6km439kn.js → send-session-notification-f6v698r5.js} +5 -5
- package/dist/v2/{server-7wwc2nga.js → server-1fszbabv.js} +32 -32
- package/dist/v2/{server-k228xhjg.js → server-2htmbqbv.js} +26 -2
- package/dist/v2/{server-aan4q8mx.js → server-3t0q2cqx.js} +1 -1
- package/dist/v2/{server-686jg6eb.js → server-4c7jt8gq.js} +68 -7
- package/dist/v2/{server-xxm59eww.js → server-4enr7s6x.js} +4 -4
- package/dist/v2/{server-zxhgvsf9.js → server-676xw7at.js} +1 -1
- package/dist/v2/{server-52awr2mw.js → server-6byqfbqf.js} +93 -9
- package/dist/v2/{server-e0vdaae2.js → server-6tcrjfw8.js} +4 -4
- package/dist/v2/{server-qye6ykf7.js → server-7ekna9zs.js} +2 -2
- package/dist/v2/{server-g5r0n3b6.js → server-7h861yms.js} +160 -25
- package/dist/v2/{server-k8x2rbxc.js → server-7spkq1y6.js} +3457 -5192
- package/dist/v2/{server-8pyt7hev.js → server-7vkj6zhb.js} +34 -749
- package/dist/v2/{server-yczc713m.js → server-8xmq9h3f.js} +31 -49
- package/dist/v2/{server-sggvvzhb.js → server-bgzy0phk.js} +505 -11
- package/dist/v2/server-c7n2ftng.js +6860 -0
- package/dist/v2/server-cvgn49tr.js +733 -0
- package/dist/v2/{server-zm570tr2.js → server-cw6521wn.js} +232 -7
- package/dist/v2/{server-xdfwt6kh.js → server-czb2rkpk.js} +23 -3
- package/dist/v2/{server-x2g40a71.js → server-d6g4whc2.js} +21 -15
- package/dist/{index-1bc61ans.js → v2/server-fvnzcnww.js} +44 -1
- package/dist/v2/{server-4k748ke6.js → server-hb6xhh9q.js} +2 -2
- package/dist/v2/{server-gjcr4w98.js → server-kh958yj8.js} +5 -5
- package/dist/v2/{server-1r6pmz4f.js → server-kzns2hbz.js} +1 -1
- package/dist/v2/{server-psqc7e9n.js → server-mqvtz7wz.js} +1227 -78
- package/dist/v2/{server-vqpf3167.js → server-ras2sxnc.js} +135 -15
- package/dist/v2/{server-ezhze64f.js → server-s2st631p.js} +4 -4
- package/dist/v2/{server-5m3dt5r1.js → server-t4k4qexw.js} +6 -2
- package/dist/v2/{server-z2037m6z.js → server-t528t8qm.js} +2 -2
- package/dist/v2/{server-v06jcv0w.js → server-vb7pbd9p.js} +18 -259
- package/dist/v2/{server-8tqanswc.js → server-zbxjj2mz.js} +331 -4
- package/dist/v2/server.d.ts.map +1 -1
- package/dist/v2/server.js +150 -6
- package/dist/v2/{storage-tags-w4tv77sn.js → storage-tags-5yxrvkaf.js} +6 -4
- package/dist/v2/store-reader.d.ts +8 -2
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/{wrapup-orchestrator-mz7efs7w.js → wrapup-orchestrator-yem5422s.js} +36 -36
- package/dist/wrapup-orchestrator-xvrr27ws.js +45 -0
- package/package.json +4 -4
- package/src/config/{mural-model-deprecation.ts → deprecated-config.ts} +19 -0
- package/src/config/index.test.ts +15 -37
- package/src/config/index.ts +2 -3
- package/src/config/project-security.ts +3 -3
- package/src/config/schema/magic-context.ts +11 -7
- package/src/features/magic-context/dreamer/task-registry.ts +2 -3
- package/src/shared/auto-search-lifecycle.ts +43 -0
- package/src/shared/logger.test.ts +38 -0
- package/src/shared/logger.ts +10 -2
- package/src/shared/models-dev-cache.ts +1 -7
- package/src/shared/models-dev-temperature.ts +107 -0
- package/src/shared/project-directory-key.test.ts +59 -0
- package/src/shared/project-directory-key.ts +20 -0
- package/src/shared/sqlite-640-review.test.ts +5 -1
- package/src/shared/storage-file-mutex-review.test.ts +162 -0
- package/src/shared/storage-file-mutex.ts +130 -0
- package/src/shared/storage-permissions.ts +46 -0
- package/src/shared/subagent-temperature.test.ts +270 -0
- package/src/shared/subagent-temperature.ts +110 -0
- package/src/shared/window-geometry.test.ts +102 -236
- package/src/shared/window-geometry.ts +23 -413
- package/dist/config/mural-model-deprecation.d.ts.map +0 -1
- package/dist/embedding-backfill-9rcm1mfy.js +0 -21
- package/dist/index-bdckkfw6.js +0 -3261
- package/dist/index-mfkzp7qj.js +0 -229
- package/dist/v2/embedding-backfill-vn8g1nh1.js +0 -21
- package/dist/v2/recomp-orchestrator-az61rfcg.js +0 -57
- package/dist/v2/server-2fbhp79z.js +0 -3205
- package/dist/v2/server-mfkzp7qj.js +0 -229
- package/dist/wrapup-orchestrator-amzta1t4.js +0 -44
- package/src/shared/__fixtures__/window-overlay.v1.json +0 -337
- /package/dist/{index-2pp04pmg.js → index-69vas84q.js} +0 -0
- /package/dist/v2/{index-2pp04pmg.js → index-69vas84q.js} +0 -0
|
@@ -1,9 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
+
Priority,
|
|
3
|
+
AdmissionClass,
|
|
4
|
+
SocketClosedError,
|
|
5
|
+
SocketTimeoutError,
|
|
6
|
+
StaleRouteHandleError,
|
|
7
|
+
SubcClient,
|
|
8
|
+
isConsumerReconnectTransient
|
|
9
|
+
} from "./server-hb6xhh9q.js";
|
|
10
|
+
import {
|
|
11
|
+
getHarness2
|
|
12
|
+
} from "./server-pavzsdc6.js";
|
|
13
|
+
import {
|
|
14
|
+
getDataDir,
|
|
2
15
|
log2
|
|
3
|
-
} from "./server-
|
|
16
|
+
} from "./server-t4k4qexw.js";
|
|
4
17
|
import {
|
|
18
|
+
buildCanonicalChunkTextFromFts,
|
|
5
19
|
loadCompartmentChunkEmbeddingsForSearch
|
|
6
|
-
} from "./server-
|
|
20
|
+
} from "./server-s2st631p.js";
|
|
7
21
|
import {
|
|
8
22
|
recordEmbeddingMeasurement,
|
|
9
23
|
saveCommitEmbedding,
|
|
@@ -20,7 +34,7 @@ import {
|
|
|
20
34
|
enqueueShadowEmbeddingItems2,
|
|
21
35
|
getProjectEmbeddingSnapshot2,
|
|
22
36
|
embedItemsForProject2
|
|
23
|
-
} from "./server-
|
|
37
|
+
} from "./server-1fszbabv.js";
|
|
24
38
|
import {
|
|
25
39
|
getProjectEmbeddings2
|
|
26
40
|
} from "./server-4dhv7mqz.js";
|
|
@@ -29,7 +43,7 @@ import {
|
|
|
29
43
|
isEmbeddingEnabled,
|
|
30
44
|
embedText,
|
|
31
45
|
ensureMemoryEmbeddings2
|
|
32
|
-
} from "./server-
|
|
46
|
+
} from "./server-kh958yj8.js";
|
|
33
47
|
import {
|
|
34
48
|
ModuleMemoryAuthorityError2,
|
|
35
49
|
getMemoriesByProject2,
|
|
@@ -39,25 +53,788 @@ import {
|
|
|
39
53
|
import {
|
|
40
54
|
getNotes,
|
|
41
55
|
getActivePrimers,
|
|
56
|
+
USER_FACING_FAILURES,
|
|
42
57
|
relaxedFtsQuery,
|
|
43
58
|
sanitizeFtsQuery,
|
|
44
59
|
searchMemoriesFTS,
|
|
45
60
|
searchMemoriesFTSUnion
|
|
46
|
-
} from "./server-
|
|
61
|
+
} from "./server-zbxjj2mz.js";
|
|
62
|
+
import {
|
|
63
|
+
isRecord
|
|
64
|
+
} from "./server-4c7jt8gq.js";
|
|
47
65
|
import {
|
|
48
66
|
getIndexedMessageCorpusSize
|
|
49
|
-
} from "./server-
|
|
67
|
+
} from "./server-bgzy0phk.js";
|
|
50
68
|
import {
|
|
51
69
|
resolveWorkspaceShareCategories,
|
|
52
70
|
resolveWorkspaceIdentitySet,
|
|
53
71
|
expandWorkspaceIdentitySetWithAliases,
|
|
54
72
|
resolveStoredPathWorkspaceIdentity,
|
|
55
73
|
sourceNameForMemory
|
|
56
|
-
} from "./server-
|
|
74
|
+
} from "./server-6tcrjfw8.js";
|
|
57
75
|
import {
|
|
58
76
|
isKnownAutocommit
|
|
59
77
|
} from "./server-8ajstryz.js";
|
|
60
78
|
|
|
79
|
+
// src/hooks/magic-context/module-transport.ts
|
|
80
|
+
import { realpathSync } from "node:fs";
|
|
81
|
+
import { join } from "node:path";
|
|
82
|
+
|
|
83
|
+
// src/hooks/magic-context/reply-pages.ts
|
|
84
|
+
import { createHash } from "node:crypto";
|
|
85
|
+
var MAX_REPLY_BYTES = 128 * 1024 * 1024;
|
|
86
|
+
var MAX_PAGE_BYTES = 512 * 1024;
|
|
87
|
+
function fail() {
|
|
88
|
+
throw Object.assign(new Error("Incomplete or invalid module reply; abandon this pass"), {
|
|
89
|
+
code: "reply_page_invalid"
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
async function assembleReplyPages(response, fetchPage) {
|
|
93
|
+
if (!isRecord(response) || !("reply_page" in response))
|
|
94
|
+
return response;
|
|
95
|
+
const first = response.reply_page;
|
|
96
|
+
if (!isRecord(first))
|
|
97
|
+
fail();
|
|
98
|
+
const { id, total, bytes } = first;
|
|
99
|
+
if (typeof id !== "string" || !/^[a-f0-9]{64}$/.test(id) || typeof total !== "number" || !Number.isSafeInteger(total) || total < 2 || total > 4096 || typeof bytes !== "number" || !Number.isSafeInteger(bytes) || bytes <= 0 || bytes > MAX_REPLY_BYTES)
|
|
100
|
+
fail();
|
|
101
|
+
const chunks = [];
|
|
102
|
+
let received = 0;
|
|
103
|
+
for (let index = 0;index < total; index += 1) {
|
|
104
|
+
const envelope = index === 0 ? response : await fetchPage(id, index);
|
|
105
|
+
if (!isRecord(envelope) || !isRecord(envelope.reply_page))
|
|
106
|
+
fail();
|
|
107
|
+
const page = envelope.reply_page;
|
|
108
|
+
if (page.id !== id || page.index !== index || page.total !== total || page.bytes !== bytes || typeof page.data !== "string")
|
|
109
|
+
fail();
|
|
110
|
+
if (Buffer.byteLength(JSON.stringify(envelope)) > MAX_PAGE_BYTES)
|
|
111
|
+
fail();
|
|
112
|
+
const chunk = Buffer.from(page.data, "utf8");
|
|
113
|
+
received += chunk.length;
|
|
114
|
+
if (received > bytes)
|
|
115
|
+
fail();
|
|
116
|
+
chunks.push(chunk);
|
|
117
|
+
}
|
|
118
|
+
if (received !== bytes)
|
|
119
|
+
fail();
|
|
120
|
+
const rebuilt = Buffer.concat(chunks, received);
|
|
121
|
+
if (createHash("sha256").update(rebuilt).digest("hex") !== id)
|
|
122
|
+
fail();
|
|
123
|
+
return JSON.parse(rebuilt.toString("utf8"));
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// src/hooks/magic-context/single-store-refusal.ts
|
|
127
|
+
var SINGLE_STORE_MIGRATION_REQUIRED_CODE = "single_store_migration_required";
|
|
128
|
+
function renderSingleStoreMigrationRequiredRefusal() {
|
|
129
|
+
const failure = USER_FACING_FAILURES.single_store_migration_required;
|
|
130
|
+
return `${failure.sentence} ${failure.action} (${failure.code})`;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
class SingleStoreMigrationRequiredError extends Error {
|
|
134
|
+
code = SINGLE_STORE_MIGRATION_REQUIRED_CODE;
|
|
135
|
+
constructor(options) {
|
|
136
|
+
super(renderSingleStoreMigrationRequiredRefusal(), options);
|
|
137
|
+
this.name = "SingleStoreMigrationRequiredError";
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function singleStoreMigrationRequiredFailure(error) {
|
|
141
|
+
let current = error;
|
|
142
|
+
const seen = new Set;
|
|
143
|
+
while (current !== null && typeof current === "object" && !seen.has(current)) {
|
|
144
|
+
seen.add(current);
|
|
145
|
+
if (current instanceof SingleStoreMigrationRequiredError)
|
|
146
|
+
return current;
|
|
147
|
+
const frame = current;
|
|
148
|
+
if (frame.code === SINGLE_STORE_MIGRATION_REQUIRED_CODE || frame.code === "single_store_state_split") {
|
|
149
|
+
return new SingleStoreMigrationRequiredError({ cause: error });
|
|
150
|
+
}
|
|
151
|
+
current = frame.cause;
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
function projectNeedsSingleStoreMigration(db, projectPath) {
|
|
156
|
+
const table = db.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'authority_managed'").get();
|
|
157
|
+
return Boolean(table && db.prepare("SELECT 1 FROM authority_managed WHERE project_path = ?").get(projectPath));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// src/hooks/magic-context/store-ahead-refusal.ts
|
|
161
|
+
var STORE_AHEAD_OF_BINARY_CODE = "store_ahead_of_binary";
|
|
162
|
+
function renderStoreAheadOfBinaryRefusal(versions) {
|
|
163
|
+
const failure = USER_FACING_FAILURES.store_ahead_of_binary;
|
|
164
|
+
const sentence = versions ? `Magic Context refused to start: its store (store.db) is at schema v${versions.dbVersion} but this ck-mc build only knows up to v${versions.binaryMax}.` : failure.sentence;
|
|
165
|
+
return `${sentence} ${failure.action} (${failure.code})`;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
class StoreAheadOfBinaryError extends Error {
|
|
169
|
+
code = STORE_AHEAD_OF_BINARY_CODE;
|
|
170
|
+
versions;
|
|
171
|
+
constructor(versions, options) {
|
|
172
|
+
super(renderStoreAheadOfBinaryRefusal(versions), options);
|
|
173
|
+
this.name = "StoreAheadOfBinaryError";
|
|
174
|
+
this.versions = versions;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function isRecord2(value) {
|
|
178
|
+
return value !== null && typeof value === "object";
|
|
179
|
+
}
|
|
180
|
+
function nonNegativeInteger(value) {
|
|
181
|
+
return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : null;
|
|
182
|
+
}
|
|
183
|
+
function versionsFromDetail(detail) {
|
|
184
|
+
if (!isRecord2(detail))
|
|
185
|
+
return null;
|
|
186
|
+
const dbVersion = nonNegativeInteger(detail.db_version);
|
|
187
|
+
const binaryMax = nonNegativeInteger(detail.binary_max);
|
|
188
|
+
return dbVersion !== null && binaryMax !== null ? { dbVersion, binaryMax } : null;
|
|
189
|
+
}
|
|
190
|
+
function versionsFromMessage(message) {
|
|
191
|
+
if (typeof message !== "string")
|
|
192
|
+
return null;
|
|
193
|
+
const match = /db_version=(\d+) binary_max=(\d+)/.exec(message) ?? /schema v(\d+) but this ck-mc build only knows up to v(\d+)/.exec(message);
|
|
194
|
+
if (!match)
|
|
195
|
+
return null;
|
|
196
|
+
return { dbVersion: Number(match[1]), binaryMax: Number(match[2]) };
|
|
197
|
+
}
|
|
198
|
+
function storeAheadOfBinaryFailure(error) {
|
|
199
|
+
let current = error;
|
|
200
|
+
const seen = new Set;
|
|
201
|
+
while (isRecord2(current) && !seen.has(current)) {
|
|
202
|
+
seen.add(current);
|
|
203
|
+
if (current instanceof StoreAheadOfBinaryError)
|
|
204
|
+
return current;
|
|
205
|
+
if (current.code === STORE_AHEAD_OF_BINARY_CODE) {
|
|
206
|
+
const versions = versionsFromDetail(current.detail) ?? versionsFromMessage(current.message);
|
|
207
|
+
return new StoreAheadOfBinaryError(versions, { cause: error });
|
|
208
|
+
}
|
|
209
|
+
current = current.cause;
|
|
210
|
+
}
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
// src/hooks/magic-context/module-transport.ts
|
|
215
|
+
var DEFAULT_MODULE_ID = "magic-context";
|
|
216
|
+
var CONNECT_BACKOFF_INITIAL_MS = 1000;
|
|
217
|
+
var CONNECT_BACKOFF_MAX_MS = 30000;
|
|
218
|
+
var CONNECT_BACKOFF_WAIT_BUDGET_MS = 12000;
|
|
219
|
+
var CONNECT_BACKOFF_WAIT_JITTER_MS = 100;
|
|
220
|
+
var HANDSHAKE_TIMEOUT_MS = 2000;
|
|
221
|
+
var MODULE_SEND_TIMEOUT_MS = 15000;
|
|
222
|
+
var TRANSFORM_PAGE_UPLOAD_TIMEOUT_MS = 5000;
|
|
223
|
+
var TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MS = 15000;
|
|
224
|
+
var TRANSFORM_COLD_START_EXECUTE_TIMEOUT_PER_MESSAGE_MS = 2;
|
|
225
|
+
var TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MAX_MS = 90000;
|
|
226
|
+
function transformColdStartExecuteTimeoutMs(seedMessageCount) {
|
|
227
|
+
const messages = Number.isSafeInteger(seedMessageCount) ? Math.max(0, seedMessageCount) : 0;
|
|
228
|
+
return Math.min(TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MAX_MS, TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MS + messages * TRANSFORM_COLD_START_EXECUTE_TIMEOUT_PER_MESSAGE_MS);
|
|
229
|
+
}
|
|
230
|
+
var MAX_WRAPUP_REQUEST_BUDGET_MS = 3800000;
|
|
231
|
+
var SERIAL_LANE_MAX_WAITERS = 16;
|
|
232
|
+
var SERIAL_LANE_MAX_WAITERS_PER_SESSION = 8;
|
|
233
|
+
var SERIAL_LANE_MIN_REMAINING_MS = 25;
|
|
234
|
+
var CANONICAL_ROOT_CACHE_MAX_ENTRIES = 256;
|
|
235
|
+
function getDefaultSubcConnectionFile() {
|
|
236
|
+
return join(getDataDir(), "cortexkit", "run", "subc-connection.json");
|
|
237
|
+
}
|
|
238
|
+
function errorChainSome(error, predicate) {
|
|
239
|
+
let current = error;
|
|
240
|
+
const seen = new Set;
|
|
241
|
+
while (isRecord(current) && !seen.has(current)) {
|
|
242
|
+
seen.add(current);
|
|
243
|
+
if (predicate(current))
|
|
244
|
+
return true;
|
|
245
|
+
current = current.cause;
|
|
246
|
+
}
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
function isStaleOrDeadRouteFailure(error) {
|
|
250
|
+
return errorChainSome(error, (current) => {
|
|
251
|
+
const code = typeof current.code === "string" ? current.code : "";
|
|
252
|
+
const name = typeof current.name === "string" ? current.name : "";
|
|
253
|
+
const message = typeof current.message === "string" ? current.message : "";
|
|
254
|
+
return [
|
|
255
|
+
"stale_route_handle",
|
|
256
|
+
"route_closed",
|
|
257
|
+
"unknown_channel",
|
|
258
|
+
"unrecognized_channel",
|
|
259
|
+
"route_gone"
|
|
260
|
+
].includes(code) || name === "StaleRouteHandleError" || /route handle \(\d+,\s*\d+\) is not live on the current connection/i.test(message) || /\b(?:unknown|unrecognized) channel\b/i.test(message);
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
function isDeadlineFailure(error) {
|
|
264
|
+
if (error instanceof SocketTimeoutError)
|
|
265
|
+
return true;
|
|
266
|
+
return errorChainSome(error, (current) => {
|
|
267
|
+
const code = typeof current.code === "string" ? current.code : "";
|
|
268
|
+
return ["ETIMEDOUT", "request_deadline", "deadline_exceeded_no_drop_observed"].includes(code);
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
function isConnectionFailure(error) {
|
|
272
|
+
if (error instanceof SocketClosedError || error instanceof SocketTimeoutError || error instanceof StaleRouteHandleError || isConsumerReconnectTransient(error) || isStaleOrDeadRouteFailure(error)) {
|
|
273
|
+
return true;
|
|
274
|
+
}
|
|
275
|
+
return errorChainSome(error, (current) => {
|
|
276
|
+
const code = typeof current.code === "string" ? current.code : "";
|
|
277
|
+
const message = typeof current.message === "string" ? current.message : "";
|
|
278
|
+
return [
|
|
279
|
+
"ENOENT",
|
|
280
|
+
"ECONNREFUSED",
|
|
281
|
+
"ECONNRESET",
|
|
282
|
+
"EPIPE",
|
|
283
|
+
"ETIMEDOUT",
|
|
284
|
+
"request_deadline",
|
|
285
|
+
"deadline_exceeded_no_drop_observed",
|
|
286
|
+
"connection_dropped",
|
|
287
|
+
"SUBC_CONNECTION_BACKOFF"
|
|
288
|
+
].includes(code) || /\bclient closed\b|\bconnection closed\b|\bclosed the connection\b/i.test(message);
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
function routeOpenWithoutAmbientConsumerIdentity(client, target, identity, options = {}) {
|
|
292
|
+
return client.routeOpen(target, identity, {
|
|
293
|
+
...options,
|
|
294
|
+
consumerIdentity: null
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
function isModuleTransportGenerationChangedResult(value) {
|
|
298
|
+
return isRecord(value) && value.transport_status === "connection_generation_changed" && typeof value.previous_generation === "number" && typeof value.current_generation === "number";
|
|
299
|
+
}
|
|
300
|
+
function moduleRequestBody(body, method) {
|
|
301
|
+
if (!isRecord(body))
|
|
302
|
+
return body;
|
|
303
|
+
const facade = typeof body.name === "string" && isRecord(body.arguments);
|
|
304
|
+
return { ...body, ...facade ? {} : { method }, accept_reply_pages: true };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
class SubcModuleTransport {
|
|
308
|
+
connectionFile;
|
|
309
|
+
moduleId;
|
|
310
|
+
requestTimeoutMs;
|
|
311
|
+
routeSessionPrefix;
|
|
312
|
+
client = null;
|
|
313
|
+
routes = new Map;
|
|
314
|
+
routeOpenings = new Map;
|
|
315
|
+
canonicalRootCache = new Map;
|
|
316
|
+
sessionLanes = new Map;
|
|
317
|
+
queuedLaneWaiters = 0;
|
|
318
|
+
wrapupSessions = new Map;
|
|
319
|
+
nextProbeMs = 0;
|
|
320
|
+
connectionPromise = null;
|
|
321
|
+
backoffMs = CONNECT_BACKOFF_INITIAL_MS;
|
|
322
|
+
connectionGeneration = 0;
|
|
323
|
+
stateSyncCapabilityCache = null;
|
|
324
|
+
getCachedStateSyncCapabilities() {
|
|
325
|
+
const cached = this.stateSyncCapabilityCache;
|
|
326
|
+
if (!cached || cached.generation !== this.connectionGeneration)
|
|
327
|
+
return;
|
|
328
|
+
return cached.capabilities;
|
|
329
|
+
}
|
|
330
|
+
invalidateStateSyncCapabilities() {
|
|
331
|
+
this.stateSyncCapabilityCache = null;
|
|
332
|
+
}
|
|
333
|
+
async stateSyncCapabilities(args) {
|
|
334
|
+
const cached = this.getCachedStateSyncCapabilities();
|
|
335
|
+
if (cached)
|
|
336
|
+
return cached;
|
|
337
|
+
const response = await this.call({
|
|
338
|
+
sessionId: args.sessionId,
|
|
339
|
+
projectRoot: args.projectRoot,
|
|
340
|
+
method: "session.status",
|
|
341
|
+
body: { method: "session.status", v: 1, session_id: args.sessionId }
|
|
342
|
+
});
|
|
343
|
+
const raw = isRecord(response) ? response : {};
|
|
344
|
+
const value = isRecord(raw.result) ? raw.result : raw;
|
|
345
|
+
const epochs = isRecord(value.epochs) ? value.epochs : {};
|
|
346
|
+
const capabilities = {
|
|
347
|
+
state_sync_deltas: epochs.state_sync_deltas === true,
|
|
348
|
+
...epochs.state_sync_resume === true ? { state_sync_resume: true } : {}
|
|
349
|
+
};
|
|
350
|
+
this.stateSyncCapabilityCache = { generation: this.connectionGeneration, capabilities };
|
|
351
|
+
return capabilities;
|
|
352
|
+
}
|
|
353
|
+
constructor(connectionFile, moduleId = DEFAULT_MODULE_ID, requestTimeoutMs = MODULE_SEND_TIMEOUT_MS, routeSessionPrefix = "") {
|
|
354
|
+
this.connectionFile = connectionFile;
|
|
355
|
+
this.moduleId = moduleId;
|
|
356
|
+
this.requestTimeoutMs = requestTimeoutMs;
|
|
357
|
+
this.routeSessionPrefix = routeSessionPrefix;
|
|
358
|
+
}
|
|
359
|
+
deadlineError(detail) {
|
|
360
|
+
const error = new Error(`module transport deadline expired ${detail}`);
|
|
361
|
+
error.code = "ETIMEDOUT";
|
|
362
|
+
return error;
|
|
363
|
+
}
|
|
364
|
+
laneTimeoutError() {
|
|
365
|
+
return this.deadlineError("while queued");
|
|
366
|
+
}
|
|
367
|
+
connectionChangedError(detail) {
|
|
368
|
+
const error = new Error(detail);
|
|
369
|
+
error.code = "ECONNRESET";
|
|
370
|
+
return error;
|
|
371
|
+
}
|
|
372
|
+
async beforeDeadline(operation, deadlineMs, detail) {
|
|
373
|
+
operation.catch(() => {});
|
|
374
|
+
const remainingMs = deadlineMs - Date.now();
|
|
375
|
+
if (remainingMs <= 0)
|
|
376
|
+
throw this.deadlineError(detail);
|
|
377
|
+
let timer;
|
|
378
|
+
try {
|
|
379
|
+
return await Promise.race([
|
|
380
|
+
operation,
|
|
381
|
+
new Promise((_resolve, reject) => {
|
|
382
|
+
timer = setTimeout(() => reject(this.deadlineError(detail)), remainingMs);
|
|
383
|
+
})
|
|
384
|
+
]);
|
|
385
|
+
} finally {
|
|
386
|
+
if (timer)
|
|
387
|
+
clearTimeout(timer);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
cleanupLane(sessionId, lane) {
|
|
391
|
+
if (!lane.active && lane.waiters.length === 0 && this.sessionLanes.get(sessionId) === lane) {
|
|
392
|
+
this.sessionLanes.delete(sessionId);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
laneRelease(sessionId, lane) {
|
|
396
|
+
let released = false;
|
|
397
|
+
return () => {
|
|
398
|
+
if (released)
|
|
399
|
+
return;
|
|
400
|
+
released = true;
|
|
401
|
+
lane.active = false;
|
|
402
|
+
this.dispatchNextLaneWaiter(sessionId, lane);
|
|
403
|
+
};
|
|
404
|
+
}
|
|
405
|
+
dispatchNextLaneWaiter(sessionId, lane) {
|
|
406
|
+
if (lane.active)
|
|
407
|
+
return;
|
|
408
|
+
while (lane.waiters.length > 0) {
|
|
409
|
+
const waiter = lane.waiters.shift();
|
|
410
|
+
if (!waiter)
|
|
411
|
+
continue;
|
|
412
|
+
this.queuedLaneWaiters = Math.max(0, this.queuedLaneWaiters - 1);
|
|
413
|
+
if (waiter.settled)
|
|
414
|
+
continue;
|
|
415
|
+
waiter.settled = true;
|
|
416
|
+
clearTimeout(waiter.timer);
|
|
417
|
+
waiter.signal?.removeEventListener("abort", waiter.onAbort);
|
|
418
|
+
if (waiter.signal?.aborted) {
|
|
419
|
+
waiter.reject(waiter.signal.reason ?? new Error("module transport call aborted"));
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
if (waiter.deadlineMs - Date.now() < SERIAL_LANE_MIN_REMAINING_MS) {
|
|
423
|
+
waiter.reject(this.laneTimeoutError());
|
|
424
|
+
continue;
|
|
425
|
+
}
|
|
426
|
+
lane.active = true;
|
|
427
|
+
waiter.resolve(this.laneRelease(sessionId, lane));
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
this.cleanupLane(sessionId, lane);
|
|
431
|
+
}
|
|
432
|
+
queueFullError() {
|
|
433
|
+
const error = new Error("module transport queue is full");
|
|
434
|
+
error.code = "EBUSY";
|
|
435
|
+
return error;
|
|
436
|
+
}
|
|
437
|
+
acquireCorrectnessLane(sessionId, signal, deadlineMs) {
|
|
438
|
+
if (signal?.aborted) {
|
|
439
|
+
return Promise.reject(signal.reason ?? new Error("module transport call aborted"));
|
|
440
|
+
}
|
|
441
|
+
if (deadlineMs - Date.now() < SERIAL_LANE_MIN_REMAINING_MS) {
|
|
442
|
+
return Promise.reject(this.laneTimeoutError());
|
|
443
|
+
}
|
|
444
|
+
const lane = this.sessionLanes.get(sessionId) ?? { active: false, waiters: [] };
|
|
445
|
+
this.sessionLanes.set(sessionId, lane);
|
|
446
|
+
if (!lane.active && lane.waiters.length === 0) {
|
|
447
|
+
lane.active = true;
|
|
448
|
+
return Promise.resolve(this.laneRelease(sessionId, lane));
|
|
449
|
+
}
|
|
450
|
+
if (this.queuedLaneWaiters >= SERIAL_LANE_MAX_WAITERS || lane.waiters.length >= SERIAL_LANE_MAX_WAITERS_PER_SESSION) {
|
|
451
|
+
return Promise.reject(this.queueFullError());
|
|
452
|
+
}
|
|
453
|
+
return new Promise((resolve, reject) => {
|
|
454
|
+
const waiter = {};
|
|
455
|
+
const removeAndReject = (error) => {
|
|
456
|
+
if (waiter.settled)
|
|
457
|
+
return;
|
|
458
|
+
waiter.settled = true;
|
|
459
|
+
clearTimeout(waiter.timer);
|
|
460
|
+
signal?.removeEventListener("abort", waiter.onAbort);
|
|
461
|
+
const index = lane.waiters.indexOf(waiter);
|
|
462
|
+
if (index >= 0) {
|
|
463
|
+
lane.waiters.splice(index, 1);
|
|
464
|
+
this.queuedLaneWaiters = Math.max(0, this.queuedLaneWaiters - 1);
|
|
465
|
+
}
|
|
466
|
+
reject(error);
|
|
467
|
+
this.cleanupLane(sessionId, lane);
|
|
468
|
+
};
|
|
469
|
+
waiter.signal = signal;
|
|
470
|
+
waiter.deadlineMs = deadlineMs;
|
|
471
|
+
waiter.resolve = resolve;
|
|
472
|
+
waiter.reject = reject;
|
|
473
|
+
waiter.settled = false;
|
|
474
|
+
waiter.onAbort = () => removeAndReject(signal?.reason ?? new Error("module transport call aborted"));
|
|
475
|
+
waiter.timer = setTimeout(() => removeAndReject(this.laneTimeoutError()), Math.max(0, deadlineMs - Date.now()));
|
|
476
|
+
signal?.addEventListener("abort", waiter.onAbort, { once: true });
|
|
477
|
+
lane.waiters.push(waiter);
|
|
478
|
+
this.queuedLaneWaiters += 1;
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
async call(args) {
|
|
482
|
+
const callStartedAt = performance.now();
|
|
483
|
+
const timings = {
|
|
484
|
+
lane: 0,
|
|
485
|
+
route: 0,
|
|
486
|
+
encode: 0,
|
|
487
|
+
issue: 0,
|
|
488
|
+
responseWait: 0,
|
|
489
|
+
settle: 0
|
|
490
|
+
};
|
|
491
|
+
const wrapupInFlight = (this.wrapupSessions.get(args.sessionId) ?? 0) > 0;
|
|
492
|
+
const attemptTimeoutMs = args.timeoutMs ?? (args.method === "session.wrapup" || args.method === "session.status" && wrapupInFlight ? MAX_WRAPUP_REQUEST_BUDGET_MS : args.attemptClass === "transform_series_execute" ? TRANSFORM_COLD_START_EXECUTE_TIMEOUT_MS : args.method === "transform" ? Math.min(this.requestTimeoutMs, TRANSFORM_PAGE_UPLOAD_TIMEOUT_MS) : this.requestTimeoutMs);
|
|
493
|
+
const tracksWrapup = args.method === "session.wrapup";
|
|
494
|
+
if (tracksWrapup) {
|
|
495
|
+
this.wrapupSessions.set(args.sessionId, (this.wrapupSessions.get(args.sessionId) ?? 0) + 1);
|
|
496
|
+
}
|
|
497
|
+
const finishWrapupTracking = () => {
|
|
498
|
+
if (!tracksWrapup)
|
|
499
|
+
return;
|
|
500
|
+
const remaining = (this.wrapupSessions.get(args.sessionId) ?? 1) - 1;
|
|
501
|
+
if (remaining > 0)
|
|
502
|
+
this.wrapupSessions.set(args.sessionId, remaining);
|
|
503
|
+
else
|
|
504
|
+
this.wrapupSessions.delete(args.sessionId);
|
|
505
|
+
};
|
|
506
|
+
const laneDeadlineMs = Date.now() + attemptTimeoutMs;
|
|
507
|
+
let releaseLane = () => {};
|
|
508
|
+
try {
|
|
509
|
+
const outsideSessionOrder = args.method.startsWith("historian.");
|
|
510
|
+
if (!args.bypassSessionLane && !outsideSessionOrder) {
|
|
511
|
+
releaseLane = await this.acquireCorrectnessLane(args.sessionId, args.signal, laneDeadlineMs);
|
|
512
|
+
}
|
|
513
|
+
} catch (error) {
|
|
514
|
+
finishWrapupTracking();
|
|
515
|
+
if (args.method === "state_sync" && isDeadlineFailure(error)) {
|
|
516
|
+
const body = isRecord(args.body) ? args.body : {};
|
|
517
|
+
throw Object.assign(new Error(`state_sync timeout stage=correctness_lane page=${body.seed_batch_index ?? 0}/${body.seed_batch_total ?? 1} series=${body.seed_id ?? "delta"} budget_ms=${attemptTimeoutMs}`), {
|
|
518
|
+
code: "state_sync_timeout",
|
|
519
|
+
stage: "correctness_lane",
|
|
520
|
+
page: body.seed_batch_index ?? 0,
|
|
521
|
+
pages: body.seed_batch_total ?? 1,
|
|
522
|
+
series: body.seed_id ?? null,
|
|
523
|
+
cause: error
|
|
524
|
+
});
|
|
525
|
+
}
|
|
526
|
+
throw error;
|
|
527
|
+
}
|
|
528
|
+
timings.lane = performance.now() - callStartedAt;
|
|
529
|
+
let rejectAbort;
|
|
530
|
+
const aborted = new Promise((_resolve, reject) => {
|
|
531
|
+
rejectAbort = reject;
|
|
532
|
+
});
|
|
533
|
+
aborted.catch(() => {});
|
|
534
|
+
const onAbort = () => rejectAbort(args.signal?.reason ?? new Error("module transport call aborted"));
|
|
535
|
+
args.signal?.addEventListener("abort", onAbort, { once: true });
|
|
536
|
+
try {
|
|
537
|
+
for (let attempt = 0;attempt < 2; attempt += 1) {
|
|
538
|
+
let ensuredRoute = null;
|
|
539
|
+
let initialResponseReceived = false;
|
|
540
|
+
try {
|
|
541
|
+
if (args.signal?.aborted) {
|
|
542
|
+
throw args.signal.reason ?? new Error("module transport call aborted");
|
|
543
|
+
}
|
|
544
|
+
const attemptDeadlineMs = Date.now() + attemptTimeoutMs;
|
|
545
|
+
const routeStartedAt = performance.now();
|
|
546
|
+
ensuredRoute = await this.ensureRoute(args.sessionId, args.projectRoot, attemptDeadlineMs, args.signal);
|
|
547
|
+
if (args.signal?.aborted) {
|
|
548
|
+
throw args.signal.reason ?? new Error("module transport call aborted");
|
|
549
|
+
}
|
|
550
|
+
timings.route += performance.now() - routeStartedAt;
|
|
551
|
+
const encodeStartedAt = performance.now();
|
|
552
|
+
const body = args.body instanceof Uint8Array ? args.body : Buffer.from(JSON.stringify(moduleRequestBody(args.body, args.method)));
|
|
553
|
+
timings.encode += performance.now() - encodeStartedAt;
|
|
554
|
+
const issueStartedAt = performance.now();
|
|
555
|
+
const request = ensuredRoute.client.request(ensuredRoute.route, body, {
|
|
556
|
+
priority: Priority.Background,
|
|
557
|
+
admissionClass: AdmissionClass.Normal,
|
|
558
|
+
timeoutMs: Math.max(1, attemptDeadlineMs - Date.now())
|
|
559
|
+
});
|
|
560
|
+
timings.issue += performance.now() - issueStartedAt;
|
|
561
|
+
const waitStartedAt = performance.now();
|
|
562
|
+
const response = await this.beforeDeadline(Promise.race([request, aborted]), attemptDeadlineMs, "waiting for the module response");
|
|
563
|
+
timings.responseWait += performance.now() - waitStartedAt;
|
|
564
|
+
initialResponseReceived = true;
|
|
565
|
+
if (this.client !== ensuredRoute.client || this.connectionGeneration !== ensuredRoute.generation) {
|
|
566
|
+
throw this.connectionChangedError("subc connection changed while awaiting the module response");
|
|
567
|
+
}
|
|
568
|
+
const pageRoute = ensuredRoute;
|
|
569
|
+
const assembled = await assembleReplyPages(response, async (id, index) => {
|
|
570
|
+
if (args.signal?.aborted)
|
|
571
|
+
throw args.signal.reason;
|
|
572
|
+
const page = await this.beforeDeadline(Promise.race([
|
|
573
|
+
pageRoute.client.request(pageRoute.route, Buffer.from(JSON.stringify({
|
|
574
|
+
method: "reply.page",
|
|
575
|
+
reply_page_id: id,
|
|
576
|
+
reply_page_index: index
|
|
577
|
+
})), {
|
|
578
|
+
priority: Priority.Background,
|
|
579
|
+
admissionClass: AdmissionClass.Normal,
|
|
580
|
+
timeoutMs: Math.max(1, attemptDeadlineMs - Date.now())
|
|
581
|
+
}),
|
|
582
|
+
aborted
|
|
583
|
+
]), attemptDeadlineMs, "waiting for a module reply page");
|
|
584
|
+
if (this.client !== pageRoute.client || this.connectionGeneration !== pageRoute.generation) {
|
|
585
|
+
throw this.connectionChangedError("subc connection changed during reply paging");
|
|
586
|
+
}
|
|
587
|
+
return page;
|
|
588
|
+
});
|
|
589
|
+
return assembled;
|
|
590
|
+
} catch (error) {
|
|
591
|
+
if (args.signal?.aborted)
|
|
592
|
+
throw args.signal.reason ?? error;
|
|
593
|
+
const migration = singleStoreMigrationRequiredFailure(error);
|
|
594
|
+
if (migration)
|
|
595
|
+
throw migration;
|
|
596
|
+
const storeAhead = storeAheadOfBinaryFailure(error);
|
|
597
|
+
if (storeAhead)
|
|
598
|
+
throw storeAhead;
|
|
599
|
+
if (args.method === "state_sync" && isDeadlineFailure(error)) {
|
|
600
|
+
const body = isRecord(args.body) ? args.body : {};
|
|
601
|
+
throw Object.assign(new Error(`state_sync timeout stage=module_ack page=${body.seed_batch_index ?? 0}/${body.seed_batch_total ?? 1} series=${body.seed_id ?? "delta"} budget_ms=${attemptTimeoutMs}`), {
|
|
602
|
+
code: "state_sync_timeout",
|
|
603
|
+
stage: "module_ack",
|
|
604
|
+
page: body.seed_batch_index ?? 0,
|
|
605
|
+
pages: body.seed_batch_total ?? 1,
|
|
606
|
+
series: body.seed_id ?? null,
|
|
607
|
+
cause: error
|
|
608
|
+
});
|
|
609
|
+
}
|
|
610
|
+
if (args.attemptClass === "transform_series_execute" && isDeadlineFailure(error)) {
|
|
611
|
+
throw error;
|
|
612
|
+
}
|
|
613
|
+
if (isConnectionFailure(error)) {
|
|
614
|
+
const previousGeneration = ensuredRoute?.generation ?? this.connectionGeneration;
|
|
615
|
+
if (ensuredRoute) {
|
|
616
|
+
this.dropRoute(ensuredRoute.routeKey, ensuredRoute.route);
|
|
617
|
+
this.invalidateConnection(ensuredRoute.client);
|
|
618
|
+
} else {
|
|
619
|
+
this.invalidateConnection();
|
|
620
|
+
}
|
|
621
|
+
const locallyUnsent = isRecord(error) && error.name === "StaleRouteHandleError" && error.code === "stale_route_handle";
|
|
622
|
+
if (attempt === 0 && ensuredRoute && !initialResponseReceived && locallyUnsent && !args.generationSensitive) {
|
|
623
|
+
continue;
|
|
624
|
+
}
|
|
625
|
+
if (args.method === "transform") {
|
|
626
|
+
if (!ensuredRoute)
|
|
627
|
+
throw error;
|
|
628
|
+
throw Object.assign(new Error("Transform transport interrupted; abandon this pass"), { code: "transform_transport_interrupted", cause: error });
|
|
629
|
+
}
|
|
630
|
+
if (args.generationSensitive && !args.signal?.aborted) {
|
|
631
|
+
return {
|
|
632
|
+
transport_status: "connection_generation_changed",
|
|
633
|
+
previous_generation: previousGeneration,
|
|
634
|
+
current_generation: this.connectionGeneration
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
if (attempt === 0 && !args.signal?.aborted)
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
throw error;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
throw new Error("module transport route retry exhausted");
|
|
644
|
+
} finally {
|
|
645
|
+
args.signal?.removeEventListener("abort", onAbort);
|
|
646
|
+
finishWrapupTracking();
|
|
647
|
+
releaseLane();
|
|
648
|
+
timings.settle = Math.max(0, performance.now() - callStartedAt - timings.lane - timings.route - timings.encode - timings.issue - timings.responseWait);
|
|
649
|
+
args.onTimings?.(timings);
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
async deleteSession(sessionId, projectRoot) {
|
|
653
|
+
await this.call({
|
|
654
|
+
sessionId,
|
|
655
|
+
projectRoot,
|
|
656
|
+
method: "session.delete",
|
|
657
|
+
body: { method: "session.delete", v: 1, session_id: sessionId }
|
|
658
|
+
});
|
|
659
|
+
}
|
|
660
|
+
closeSession(sessionId) {
|
|
661
|
+
const client = this.client;
|
|
662
|
+
const prefix = `${sessionId}\x00`;
|
|
663
|
+
const routes = [...this.routes.entries()].filter(([key]) => key.startsWith(prefix));
|
|
664
|
+
for (const [key, cachedRoute] of routes) {
|
|
665
|
+
this.routes.delete(key);
|
|
666
|
+
if (client) {
|
|
667
|
+
client.closeRoute(cachedRoute.route).catch((error) => {
|
|
668
|
+
if (this.client === client && isConnectionFailure(error)) {
|
|
669
|
+
this.invalidateConnection(client);
|
|
670
|
+
}
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
}
|
|
674
|
+
if (routes.length === 0 && this.sessionLanes.get(sessionId)?.active) {
|
|
675
|
+
this.invalidateConnection(client);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
async ensureRoute(sessionId, rawProjectRoot, deadlineMs = Date.now() + this.requestTimeoutMs, signal) {
|
|
679
|
+
const projectRoot = this.canonicalRoot(rawProjectRoot);
|
|
680
|
+
const routeKey = `${sessionId}\x00${projectRoot}`;
|
|
681
|
+
const client = await this.ensureConnected(signal);
|
|
682
|
+
const generation = this.connectionGeneration;
|
|
683
|
+
const existing = this.routes.get(routeKey);
|
|
684
|
+
if (existing?.generation === generation) {
|
|
685
|
+
return { client, route: existing.route, routeKey, generation };
|
|
686
|
+
}
|
|
687
|
+
if (existing)
|
|
688
|
+
this.routes.delete(routeKey);
|
|
689
|
+
const opening = this.routeOpenings.get(routeKey);
|
|
690
|
+
if (opening?.client === client && opening.generation === generation) {
|
|
691
|
+
return await opening.promise;
|
|
692
|
+
}
|
|
693
|
+
const promise = (async () => {
|
|
694
|
+
const target = { kind: "tool_provider", module_id: this.moduleId };
|
|
695
|
+
const identity = {
|
|
696
|
+
project_root: projectRoot,
|
|
697
|
+
harness: getHarness2(),
|
|
698
|
+
session: `${this.routeSessionPrefix}${sessionId}`
|
|
699
|
+
};
|
|
700
|
+
const route = await this.beforeDeadline(routeOpenWithoutAmbientConsumerIdentity(client, target, identity), deadlineMs, "opening the module route");
|
|
701
|
+
if (this.client !== client || generation !== this.connectionGeneration) {
|
|
702
|
+
await client.closeRoute(route).catch(() => {
|
|
703
|
+
return;
|
|
704
|
+
});
|
|
705
|
+
throw this.connectionChangedError("subc connection changed while opening module route");
|
|
706
|
+
}
|
|
707
|
+
this.routes.set(routeKey, { route, generation });
|
|
708
|
+
return { client, route, routeKey, generation };
|
|
709
|
+
})();
|
|
710
|
+
const routeOpening = { client, generation, promise };
|
|
711
|
+
this.routeOpenings.set(routeKey, routeOpening);
|
|
712
|
+
try {
|
|
713
|
+
return await promise;
|
|
714
|
+
} finally {
|
|
715
|
+
if (this.routeOpenings.get(routeKey) === routeOpening) {
|
|
716
|
+
this.routeOpenings.delete(routeKey);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
dropRoute(routeKey, route) {
|
|
721
|
+
const existing = this.routes.get(routeKey);
|
|
722
|
+
if (!existing || route && existing.route !== route)
|
|
723
|
+
return;
|
|
724
|
+
this.routes.delete(routeKey);
|
|
725
|
+
}
|
|
726
|
+
canonicalRoot(root) {
|
|
727
|
+
const cached = this.canonicalRootCache.get(root);
|
|
728
|
+
if (cached !== undefined) {
|
|
729
|
+
this.canonicalRootCache.delete(root);
|
|
730
|
+
this.canonicalRootCache.set(root, cached);
|
|
731
|
+
return cached;
|
|
732
|
+
}
|
|
733
|
+
let resolved = root;
|
|
734
|
+
try {
|
|
735
|
+
resolved = realpathSync.native(root);
|
|
736
|
+
} catch {}
|
|
737
|
+
this.canonicalRootCache.set(root, resolved);
|
|
738
|
+
while (this.canonicalRootCache.size > CANONICAL_ROOT_CACHE_MAX_ENTRIES) {
|
|
739
|
+
const oldestRoot = this.canonicalRootCache.keys().next().value;
|
|
740
|
+
if (oldestRoot === undefined)
|
|
741
|
+
break;
|
|
742
|
+
this.canonicalRootCache.delete(oldestRoot);
|
|
743
|
+
}
|
|
744
|
+
return resolved;
|
|
745
|
+
}
|
|
746
|
+
connectClient() {
|
|
747
|
+
return SubcClient.connect({
|
|
748
|
+
connectionFile: this.connectionFile,
|
|
749
|
+
handshakeTimeoutMs: HANDSHAKE_TIMEOUT_MS
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
backoffActiveError() {
|
|
753
|
+
const error = new Error(`subc connection backoff active until ${this.nextProbeMs}`);
|
|
754
|
+
error.code = "SUBC_CONNECTION_BACKOFF";
|
|
755
|
+
return error;
|
|
756
|
+
}
|
|
757
|
+
sleepAbortable(durationMs, signal) {
|
|
758
|
+
return new Promise((resolve, reject) => {
|
|
759
|
+
if (signal?.aborted) {
|
|
760
|
+
reject(signal.reason ?? new Error("module transport call aborted"));
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
const onAbort = () => {
|
|
764
|
+
clearTimeout(timer);
|
|
765
|
+
signal?.removeEventListener("abort", onAbort);
|
|
766
|
+
reject(signal?.reason ?? new Error("module transport call aborted"));
|
|
767
|
+
};
|
|
768
|
+
const timer = setTimeout(() => {
|
|
769
|
+
signal?.removeEventListener("abort", onAbort);
|
|
770
|
+
resolve();
|
|
771
|
+
}, Math.max(0, durationMs));
|
|
772
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
773
|
+
});
|
|
774
|
+
}
|
|
775
|
+
async ensureConnected(signal) {
|
|
776
|
+
if (this.client)
|
|
777
|
+
return this.client;
|
|
778
|
+
if (this.connectionPromise)
|
|
779
|
+
return await this.connectionPromise;
|
|
780
|
+
let now = Date.now();
|
|
781
|
+
if (now < this.nextProbeMs) {
|
|
782
|
+
const remainingMs = this.nextProbeMs - now;
|
|
783
|
+
if (remainingMs > CONNECT_BACKOFF_WAIT_BUDGET_MS)
|
|
784
|
+
throw this.backoffActiveError();
|
|
785
|
+
const jitterMs = Math.floor(Math.random() * CONNECT_BACKOFF_WAIT_JITTER_MS);
|
|
786
|
+
await this.sleepAbortable(remainingMs + jitterMs, signal);
|
|
787
|
+
if (this.client)
|
|
788
|
+
return this.client;
|
|
789
|
+
if (this.connectionPromise)
|
|
790
|
+
return await this.connectionPromise;
|
|
791
|
+
now = Date.now();
|
|
792
|
+
if (now < this.nextProbeMs)
|
|
793
|
+
throw this.backoffActiveError();
|
|
794
|
+
}
|
|
795
|
+
const generation = this.connectionGeneration;
|
|
796
|
+
const connecting = (async () => {
|
|
797
|
+
let candidate = null;
|
|
798
|
+
try {
|
|
799
|
+
candidate = await this.connectClient();
|
|
800
|
+
if (generation !== this.connectionGeneration) {
|
|
801
|
+
candidate.close();
|
|
802
|
+
throw this.connectionChangedError("subc connection attempt was superseded");
|
|
803
|
+
}
|
|
804
|
+
this.client = candidate;
|
|
805
|
+
this.routes.clear();
|
|
806
|
+
this.backoffMs = CONNECT_BACKOFF_INITIAL_MS;
|
|
807
|
+
this.nextProbeMs = 0;
|
|
808
|
+
return candidate;
|
|
809
|
+
} catch (error) {
|
|
810
|
+
candidate?.close();
|
|
811
|
+
if (generation === this.connectionGeneration)
|
|
812
|
+
this.invalidateConnection();
|
|
813
|
+
this.nextProbeMs = Date.now() + this.backoffMs;
|
|
814
|
+
this.backoffMs = Math.min(this.backoffMs * 2, CONNECT_BACKOFF_MAX_MS);
|
|
815
|
+
throw error;
|
|
816
|
+
}
|
|
817
|
+
})();
|
|
818
|
+
this.connectionPromise = connecting;
|
|
819
|
+
try {
|
|
820
|
+
return await connecting;
|
|
821
|
+
} finally {
|
|
822
|
+
if (this.connectionPromise === connecting)
|
|
823
|
+
this.connectionPromise = null;
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
invalidateConnection(client = this.client) {
|
|
827
|
+
if (client && this.client !== client)
|
|
828
|
+
return;
|
|
829
|
+
this.connectionGeneration += 1;
|
|
830
|
+
this.invalidateStateSyncCapabilities();
|
|
831
|
+
this.client = null;
|
|
832
|
+
this.routes.clear();
|
|
833
|
+
this.routeOpenings.clear();
|
|
834
|
+
client?.close();
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
61
838
|
// src/features/magic-context/git-commits/git-log-reader.ts
|
|
62
839
|
import { execFile } from "node:child_process";
|
|
63
840
|
import { promisify } from "node:util";
|
|
@@ -438,6 +1215,19 @@ function searchGitCommitsSync(db, projectPath, query, options) {
|
|
|
438
1215
|
for (const row of rows)
|
|
439
1216
|
bySha.set(row.sha, rowToCommit(row));
|
|
440
1217
|
}
|
|
1218
|
+
if (options.captureLanes) {
|
|
1219
|
+
const fts = [...bySha.values()].filter((commit) => ftsScores.has(commit.sha)).map((commit) => ({
|
|
1220
|
+
commit,
|
|
1221
|
+
matchType: "fts",
|
|
1222
|
+
score: (ftsScores.get(commit.sha) ?? 0) * singleSourcePenalty
|
|
1223
|
+
})).sort((a, b) => b.score - a.score || b.commit.committedAtMs - a.commit.committedAtMs).slice(0, 25);
|
|
1224
|
+
const vector = [...bySha.values()].filter((commit) => (semanticScores.get(commit.sha) ?? 0) > 0).map((commit) => ({
|
|
1225
|
+
commit,
|
|
1226
|
+
matchType: "semantic",
|
|
1227
|
+
score: semanticScores.get(commit.sha) ?? 0
|
|
1228
|
+
})).sort((a, b) => b.score - a.score || b.commit.committedAtMs - a.commit.committedAtMs).slice(0, 25);
|
|
1229
|
+
options.captureLanes(fts, vector);
|
|
1230
|
+
}
|
|
441
1231
|
const results = [];
|
|
442
1232
|
for (const [sha, commit] of bySha.entries()) {
|
|
443
1233
|
const sem = semanticScores.get(sha);
|
|
@@ -577,7 +1367,7 @@ function withMessageFtsSessionFilter(db, sessionId, read) {
|
|
|
577
1367
|
}
|
|
578
1368
|
|
|
579
1369
|
// src/features/magic-context/search-measurement.ts
|
|
580
|
-
import { createHash } from "node:crypto";
|
|
1370
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
581
1371
|
function resultId(result) {
|
|
582
1372
|
switch (result.source) {
|
|
583
1373
|
case "memory":
|
|
@@ -664,7 +1454,269 @@ async function recordShadowMeasurement(args) {
|
|
|
664
1454
|
}
|
|
665
1455
|
}
|
|
666
1456
|
function sha256(value) {
|
|
667
|
-
return
|
|
1457
|
+
return createHash2("sha256").update(value).digest("hex");
|
|
1458
|
+
}
|
|
1459
|
+
|
|
1460
|
+
// src/features/magic-context/search-rerank.ts
|
|
1461
|
+
var RERANK_MODEL = "gte-reranker-modernbert-base-f32";
|
|
1462
|
+
var RERANK_LANE_LIMIT = 25;
|
|
1463
|
+
var DEADLINE_MS = 1500;
|
|
1464
|
+
function isProseQuery(query) {
|
|
1465
|
+
const text = query.trim();
|
|
1466
|
+
if (!text || /[\n;]|^["'`]|["'`]$/.test(text))
|
|
1467
|
+
return false;
|
|
1468
|
+
if (/^(?:error\b|cannot\b|failed\b|panic\b|traceback\b|assertion\b|SQLITE_|TypeError\b|ReferenceError\b|SyntaxError\b)/i.test(text))
|
|
1469
|
+
return false;
|
|
1470
|
+
if (/\b(?:[A-Z][A-Z_]+:|\w*(?:Error|Exception):)|\bat\s+\S+\s*\(/.test(text))
|
|
1471
|
+
return false;
|
|
1472
|
+
const words = text.replace(/[?!.]$/, "").split(/\s+/);
|
|
1473
|
+
if (words.length < 3)
|
|
1474
|
+
return false;
|
|
1475
|
+
const plain = words.filter((word) => /^[a-zA-Z]+(?:['’-][a-zA-Z]+)*$/.test(word));
|
|
1476
|
+
if (/^(?:how|why|what|where|when|which|who)\b/i.test(text))
|
|
1477
|
+
return plain.length >= 3;
|
|
1478
|
+
return words.length >= 4 && plain.length >= 3 && !/[\\/]|::|=/.test(text);
|
|
1479
|
+
}
|
|
1480
|
+
function emptySearchLanes() {
|
|
1481
|
+
return {
|
|
1482
|
+
memory_fts: [],
|
|
1483
|
+
memory_vector: [],
|
|
1484
|
+
primer_fts: [],
|
|
1485
|
+
primer_vector: [],
|
|
1486
|
+
message_fts: [],
|
|
1487
|
+
chunk_vector: [],
|
|
1488
|
+
git_fts: [],
|
|
1489
|
+
git_vector: [],
|
|
1490
|
+
notes: []
|
|
1491
|
+
};
|
|
1492
|
+
}
|
|
1493
|
+
function searchResultKey(hit) {
|
|
1494
|
+
switch (hit.source) {
|
|
1495
|
+
case "memory":
|
|
1496
|
+
return `memory:${hit.memoryId}`;
|
|
1497
|
+
case "primer":
|
|
1498
|
+
return `primer:${hit.primerId}`;
|
|
1499
|
+
case "message":
|
|
1500
|
+
return `message:${hit.messageId}`;
|
|
1501
|
+
case "compartment":
|
|
1502
|
+
return `compartment:${hit.compartmentId}`;
|
|
1503
|
+
case "git_commit":
|
|
1504
|
+
return `git_commit:${hit.sha}`;
|
|
1505
|
+
case "note":
|
|
1506
|
+
return `note:${hit.noteId}`;
|
|
1507
|
+
}
|
|
1508
|
+
}
|
|
1509
|
+
function fuseSearchLanes(lanes) {
|
|
1510
|
+
const compartments = lanes.chunk_vector.filter((hit) => hit.source === "compartment");
|
|
1511
|
+
const fused = new Map;
|
|
1512
|
+
for (const [name, lane] of Object.entries(lanes)) {
|
|
1513
|
+
const seen = new Set;
|
|
1514
|
+
lane.slice(0, RERANK_LANE_LIMIT).forEach((original, index) => {
|
|
1515
|
+
const hit = name === "message_fts" && original.source === "message" ? compartments.find((chunk) => original.messageOrdinal >= chunk.startOrdinal && original.messageOrdinal <= chunk.endOrdinal) ?? original : original;
|
|
1516
|
+
const key = searchResultKey(hit);
|
|
1517
|
+
if (seen.has(key))
|
|
1518
|
+
return;
|
|
1519
|
+
seen.add(key);
|
|
1520
|
+
const prior = fused.get(key);
|
|
1521
|
+
const score = 1 / (60 + index + 1);
|
|
1522
|
+
if (prior)
|
|
1523
|
+
prior.score += score;
|
|
1524
|
+
else
|
|
1525
|
+
fused.set(key, { hit, score, order: fused.size });
|
|
1526
|
+
});
|
|
1527
|
+
}
|
|
1528
|
+
return [...fused.values()].sort((a, b) => b.score - a.score || a.order - b.order).slice(0, 20).map((row) => row.hit);
|
|
1529
|
+
}
|
|
1530
|
+
function truncateUtf8(text, bytes) {
|
|
1531
|
+
const buffer = Buffer.from(text);
|
|
1532
|
+
let end = Math.min(buffer.length, bytes);
|
|
1533
|
+
while (end > 0 && end < buffer.length && (buffer[end] & 192) === 128)
|
|
1534
|
+
end--;
|
|
1535
|
+
return buffer.subarray(0, end).toString("utf8");
|
|
1536
|
+
}
|
|
1537
|
+
function candidateText(location, title, body) {
|
|
1538
|
+
const header = `${truncateUtf8(location.replaceAll(`
|
|
1539
|
+
`, " "), 200)}
|
|
1540
|
+
${truncateUtf8(title.replaceAll(`
|
|
1541
|
+
`, " "), 120)}
|
|
1542
|
+
`;
|
|
1543
|
+
return header + truncateUtf8(body, 1024 - Buffer.byteLength(header));
|
|
1544
|
+
}
|
|
1545
|
+
|
|
1546
|
+
class RerankFailure extends Error {
|
|
1547
|
+
reason;
|
|
1548
|
+
constructor(reason) {
|
|
1549
|
+
super(reason);
|
|
1550
|
+
this.reason = reason;
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
function unwrap(value) {
|
|
1554
|
+
if (!value || typeof value !== "object")
|
|
1555
|
+
throw new RerankFailure("validation");
|
|
1556
|
+
const outer = value;
|
|
1557
|
+
const body = outer.result ?? outer;
|
|
1558
|
+
if (!body || typeof body !== "object")
|
|
1559
|
+
throw new RerankFailure("validation");
|
|
1560
|
+
if (body.error) {
|
|
1561
|
+
const error = body.error;
|
|
1562
|
+
throw new RerankFailure(error.code ?? "synapse_error");
|
|
1563
|
+
}
|
|
1564
|
+
return body;
|
|
1565
|
+
}
|
|
1566
|
+
function pinReranker(value) {
|
|
1567
|
+
const body = unwrap(value);
|
|
1568
|
+
const models = body.models;
|
|
1569
|
+
const model = Array.isArray(models) ? models.find((row) => row?.model_id === RERANK_MODEL) : null;
|
|
1570
|
+
if (model?.certified !== true || model.fingerprints?.length !== 1 || typeof model.fingerprints[0] !== "string" || !/^[a-f0-9]{64}$/.test(model.fingerprints[0]) || !Number.isSafeInteger(body.table_epoch))
|
|
1571
|
+
throw new RerankFailure("catalog_validation");
|
|
1572
|
+
return { fingerprint: model.fingerprints[0], tableEpoch: body.table_epoch };
|
|
1573
|
+
}
|
|
1574
|
+
var loggedReasons = new Set;
|
|
1575
|
+
function logRerankFallback(reason) {
|
|
1576
|
+
if (loggedReasons.has(reason))
|
|
1577
|
+
return;
|
|
1578
|
+
loggedReasons.add(reason);
|
|
1579
|
+
log2(`[ctx_search] rerank fallback (${reason}); retaining original ranking`);
|
|
1580
|
+
}
|
|
1581
|
+
function reasonOf(error) {
|
|
1582
|
+
if (error instanceof RerankFailure)
|
|
1583
|
+
return error.reason;
|
|
1584
|
+
if (error && typeof error === "object" && "code" in error) {
|
|
1585
|
+
const code = String(error.code);
|
|
1586
|
+
return ["ENOENT", "ECONNREFUSED"].includes(code) ? "missing_synapse" : code;
|
|
1587
|
+
}
|
|
1588
|
+
return "synapse_error";
|
|
1589
|
+
}
|
|
1590
|
+
async function bounded(promise) {
|
|
1591
|
+
let timer;
|
|
1592
|
+
try {
|
|
1593
|
+
return await Promise.race([
|
|
1594
|
+
promise,
|
|
1595
|
+
new Promise((_, reject) => {
|
|
1596
|
+
timer = setTimeout(() => reject(new RerankFailure("deadline_exceeded")), DEADLINE_MS);
|
|
1597
|
+
})
|
|
1598
|
+
]);
|
|
1599
|
+
} finally {
|
|
1600
|
+
clearTimeout(timer);
|
|
1601
|
+
}
|
|
1602
|
+
}
|
|
1603
|
+
var connections = new Map;
|
|
1604
|
+
async function connect(connectionFile) {
|
|
1605
|
+
let connection = connections.get(connectionFile);
|
|
1606
|
+
if (!connection) {
|
|
1607
|
+
connection = SubcClient.connect({ connectionFile });
|
|
1608
|
+
connections.set(connectionFile, connection);
|
|
1609
|
+
connection.catch(() => connections.delete(connectionFile));
|
|
1610
|
+
}
|
|
1611
|
+
return bounded(connection);
|
|
1612
|
+
}
|
|
1613
|
+
async function prepareReranker(projectRoot, sessionId, connectionFile, injectedClient) {
|
|
1614
|
+
try {
|
|
1615
|
+
if (injectedClient === null)
|
|
1616
|
+
throw new RerankFailure("missing_synapse");
|
|
1617
|
+
const client = injectedClient ?? await connect(connectionFile ?? getDefaultSubcConnectionFile());
|
|
1618
|
+
const identity = {
|
|
1619
|
+
project_root: projectRoot,
|
|
1620
|
+
harness: "magic-context",
|
|
1621
|
+
session: sessionId
|
|
1622
|
+
};
|
|
1623
|
+
const lane = pinReranker(await bounded(client.call("synapse", "models.list", {}, { timeoutMs: DEADLINE_MS, targetKind: "management_surface", identity })));
|
|
1624
|
+
return { client, lane, identity };
|
|
1625
|
+
} catch (error) {
|
|
1626
|
+
logRerankFallback(reasonOf(error));
|
|
1627
|
+
return null;
|
|
1628
|
+
}
|
|
1629
|
+
}
|
|
1630
|
+
async function rerankSearchResults(session, query, baseline, pool, texts, limit) {
|
|
1631
|
+
if (!pool.length)
|
|
1632
|
+
return baseline;
|
|
1633
|
+
try {
|
|
1634
|
+
if (pool.length > 20 || texts.length !== pool.length || texts.some((text) => Buffer.byteLength(text) > 1024))
|
|
1635
|
+
throw new RerankFailure("validation");
|
|
1636
|
+
const body = unwrap(await bounded(session.client.call("synapse", "rerank.score", {
|
|
1637
|
+
model: RERANK_MODEL,
|
|
1638
|
+
query,
|
|
1639
|
+
candidates: texts,
|
|
1640
|
+
required_fingerprint: session.lane.fingerprint,
|
|
1641
|
+
allow_equivalent: false,
|
|
1642
|
+
accept_declared: false,
|
|
1643
|
+
max_queue_ms: 100,
|
|
1644
|
+
deadline_ms: DEADLINE_MS
|
|
1645
|
+
}, {
|
|
1646
|
+
timeoutMs: DEADLINE_MS,
|
|
1647
|
+
targetKind: "management_surface",
|
|
1648
|
+
identity: session.identity
|
|
1649
|
+
})));
|
|
1650
|
+
if (body.fingerprint !== session.lane.fingerprint)
|
|
1651
|
+
throw new RerankFailure("fingerprint_mismatch");
|
|
1652
|
+
if (body.table_epoch !== session.lane.tableEpoch)
|
|
1653
|
+
throw new RerankFailure("epoch_mismatch");
|
|
1654
|
+
if (!Array.isArray(body.scores) || body.scores.length !== pool.length || body.scores.some((score) => typeof score !== "number" || !Number.isFinite(score)))
|
|
1655
|
+
throw new RerankFailure("validation");
|
|
1656
|
+
const scores = body.scores;
|
|
1657
|
+
return pool.map((hit, index) => ({ hit, index, score: scores[index] })).sort((a, b) => b.score - a.score || a.index - b.index).slice(0, limit).map((row) => row.hit);
|
|
1658
|
+
} catch (error) {
|
|
1659
|
+
logRerankFallback(reasonOf(error));
|
|
1660
|
+
return baseline;
|
|
1661
|
+
}
|
|
1662
|
+
}
|
|
1663
|
+
function candidateTexts(db, sessionId, projectPath, pool) {
|
|
1664
|
+
return pool.map((hit) => {
|
|
1665
|
+
const id = searchResultKey(hit).split(":").slice(1).join(":");
|
|
1666
|
+
let location = `${hit.source} ${id} ${projectPath}`;
|
|
1667
|
+
let title = hit.content.split(`
|
|
1668
|
+
`)[0];
|
|
1669
|
+
let body = hit.content;
|
|
1670
|
+
switch (hit.source) {
|
|
1671
|
+
case "memory": {
|
|
1672
|
+
const row = db.prepare("SELECT content FROM memories WHERE id=?").get(hit.memoryId);
|
|
1673
|
+
body = row.content;
|
|
1674
|
+
title = body.split(`
|
|
1675
|
+
`)[0];
|
|
1676
|
+
break;
|
|
1677
|
+
}
|
|
1678
|
+
case "primer": {
|
|
1679
|
+
const row = db.prepare("SELECT question, answer FROM primers WHERE id=?").get(hit.primerId);
|
|
1680
|
+
title = row.question;
|
|
1681
|
+
body = `Q: ${row.question}
|
|
1682
|
+
A: ${row.answer}`;
|
|
1683
|
+
break;
|
|
1684
|
+
}
|
|
1685
|
+
case "git_commit": {
|
|
1686
|
+
const row = db.prepare("SELECT message FROM git_commits WHERE sha=?").get(hit.sha);
|
|
1687
|
+
body = row.message;
|
|
1688
|
+
title = `${hit.shortSha} ${body.split(`
|
|
1689
|
+
`)[0]}`;
|
|
1690
|
+
break;
|
|
1691
|
+
}
|
|
1692
|
+
case "note": {
|
|
1693
|
+
const row = db.prepare("SELECT content, ready_reason AS reason FROM notes WHERE id=?").get(hit.noteId);
|
|
1694
|
+
body = `${row.content}${row.reason ? `
|
|
1695
|
+
Reason: ${row.reason}` : ""}`;
|
|
1696
|
+
title = body.split(`
|
|
1697
|
+
`)[0];
|
|
1698
|
+
break;
|
|
1699
|
+
}
|
|
1700
|
+
case "message": {
|
|
1701
|
+
const mapped = db.prepare(`SELECT f.content FROM message_fts_rowid_map m
|
|
1702
|
+
JOIN message_history_fts f ON f.rowid=m.fts_rowid
|
|
1703
|
+
WHERE m.session_id=? AND m.message_ordinal=? AND f.message_id=?`).get(sessionId, hit.messageOrdinal, hit.messageId);
|
|
1704
|
+
const row = mapped ?? db.prepare("SELECT content FROM message_history_fts WHERE session_id=? AND message_id=? ORDER BY CAST(message_ordinal AS INTEGER) LIMIT 1").get(sessionId, hit.messageId);
|
|
1705
|
+
body = row.content;
|
|
1706
|
+
title = `${hit.role}: ${body.split(`
|
|
1707
|
+
`)[0]}`;
|
|
1708
|
+
location = `message ${hit.messageId} ${sessionId} @${hit.messageOrdinal}`;
|
|
1709
|
+
break;
|
|
1710
|
+
}
|
|
1711
|
+
case "compartment": {
|
|
1712
|
+
title = hit.title;
|
|
1713
|
+
location = `compartment ${hit.compartmentId} ${hit.sessionId} @${hit.startOrdinal}-${hit.endOrdinal}`;
|
|
1714
|
+
body = buildCanonicalChunkTextFromFts(db, hit.sessionId, hit.startOrdinal, hit.endOrdinal) ?? "";
|
|
1715
|
+
break;
|
|
1716
|
+
}
|
|
1717
|
+
}
|
|
1718
|
+
return candidateText(location, title, body);
|
|
1719
|
+
});
|
|
668
1720
|
}
|
|
669
1721
|
|
|
670
1722
|
// src/features/magic-context/search.ts
|
|
@@ -698,6 +1750,7 @@ function createUnifiedSearchDiagnostics2() {
|
|
|
698
1750
|
}
|
|
699
1751
|
function searchMessageHistory2(db, request) {
|
|
700
1752
|
const diagnostics = request.collectDiagnostics ? createUnifiedSearchDiagnostics2() : undefined;
|
|
1753
|
+
const capture = request.captureLimit ? { limit: request.captureLimit, results: [] } : undefined;
|
|
701
1754
|
const results = searchMessages({
|
|
702
1755
|
db,
|
|
703
1756
|
sessionId: request.sessionId,
|
|
@@ -707,10 +1760,12 @@ function searchMessageHistory2(db, request) {
|
|
|
707
1760
|
probes: request.probes,
|
|
708
1761
|
relaxedRecall: request.relaxedRecall,
|
|
709
1762
|
diagnostics,
|
|
710
|
-
dateRange: request.dateRange
|
|
1763
|
+
dateRange: request.dateRange,
|
|
1764
|
+
capture
|
|
711
1765
|
});
|
|
712
1766
|
return {
|
|
713
1767
|
results,
|
|
1768
|
+
laneResults: capture?.results,
|
|
714
1769
|
suppressedLiveMessageMatches: diagnostics?.suppressedLiveMessageMatches ?? 0
|
|
715
1770
|
};
|
|
716
1771
|
}
|
|
@@ -1103,7 +2158,7 @@ function mergeMemoryResults(args) {
|
|
|
1103
2158
|
score = SEMANTIC_WEIGHT * semanticScore + FTS_WEIGHT * ftsScore;
|
|
1104
2159
|
matchType = "hybrid";
|
|
1105
2160
|
} else if (semanticScore !== undefined) {
|
|
1106
|
-
score = semanticScore * SINGLE_SOURCE_PENALTY;
|
|
2161
|
+
score = semanticScore * (args.singleSourcePenalty ?? SINGLE_SOURCE_PENALTY);
|
|
1107
2162
|
matchType = "semantic";
|
|
1108
2163
|
} else if (ftsScore !== undefined) {
|
|
1109
2164
|
score = ftsScore * SINGLE_SOURCE_PENALTY;
|
|
@@ -1171,25 +2226,45 @@ async function searchMemories(args) {
|
|
|
1171
2226
|
queryModelId: args.queryModelId,
|
|
1172
2227
|
workspace: args.workspace
|
|
1173
2228
|
});
|
|
2229
|
+
const sourceNameByMemoryId = sourceNamesForSearchMemories({
|
|
2230
|
+
memories,
|
|
2231
|
+
projectPath: args.projectPath,
|
|
2232
|
+
workspace: args.workspace ?? {
|
|
2233
|
+
identities: [args.projectPath],
|
|
2234
|
+
expandedIdentities: [args.projectPath],
|
|
2235
|
+
namesByIdentity: new Map,
|
|
2236
|
+
canonicalIdentityByStoredPath: new Map([[args.projectPath, args.projectPath]]),
|
|
2237
|
+
ownIdentities: [args.projectPath],
|
|
2238
|
+
shareCategories: null,
|
|
2239
|
+
isWorkspaced: false
|
|
2240
|
+
}
|
|
2241
|
+
});
|
|
2242
|
+
if (args.lanes) {
|
|
2243
|
+
args.lanes.memory_fts = mergeMemoryResults({
|
|
2244
|
+
memories,
|
|
2245
|
+
semanticScores: new Map,
|
|
2246
|
+
ftsScores,
|
|
2247
|
+
sourceNameByMemoryId,
|
|
2248
|
+
limit: 25,
|
|
2249
|
+
visibleMemoryIds: args.visibleMemoryIds
|
|
2250
|
+
}).results;
|
|
2251
|
+
args.lanes.memory_vector = mergeMemoryResults({
|
|
2252
|
+
memories,
|
|
2253
|
+
semanticScores,
|
|
2254
|
+
ftsScores: new Map,
|
|
2255
|
+
sourceNameByMemoryId,
|
|
2256
|
+
singleSourcePenalty: 1,
|
|
2257
|
+
limit: 25,
|
|
2258
|
+
visibleMemoryIds: args.visibleMemoryIds
|
|
2259
|
+
}).results;
|
|
2260
|
+
}
|
|
1174
2261
|
return mergeMemoryResults({
|
|
1175
2262
|
memories,
|
|
1176
2263
|
semanticScores,
|
|
1177
2264
|
ftsScores,
|
|
1178
2265
|
limit: args.limit,
|
|
1179
2266
|
visibleMemoryIds: args.visibleMemoryIds,
|
|
1180
|
-
sourceNameByMemoryId
|
|
1181
|
-
memories,
|
|
1182
|
-
projectPath: args.projectPath,
|
|
1183
|
-
workspace: args.workspace ?? {
|
|
1184
|
-
identities: [args.projectPath],
|
|
1185
|
-
expandedIdentities: [args.projectPath],
|
|
1186
|
-
namesByIdentity: new Map,
|
|
1187
|
-
canonicalIdentityByStoredPath: new Map([[args.projectPath, args.projectPath]]),
|
|
1188
|
-
ownIdentities: [args.projectPath],
|
|
1189
|
-
shareCategories: null,
|
|
1190
|
-
isWorkspaced: false
|
|
1191
|
-
}
|
|
1192
|
-
})
|
|
2267
|
+
sourceNameByMemoryId
|
|
1193
2268
|
});
|
|
1194
2269
|
}
|
|
1195
2270
|
function linearDecayScore(rank, total) {
|
|
@@ -1322,7 +2397,9 @@ function searchMessages(args) {
|
|
|
1322
2397
|
}
|
|
1323
2398
|
function searchMessagesInSnapshot(args, sessionFirst) {
|
|
1324
2399
|
const cutoff = args.maxOrdinal != null && args.maxOrdinal >= 0 ? args.maxOrdinal : null;
|
|
1325
|
-
const
|
|
2400
|
+
const baselineFetchLimit = cutoff !== null ? args.limit * 3 : args.limit;
|
|
2401
|
+
const captureFetchLimit = args.capture ? cutoff !== null ? args.capture.limit * 3 : args.capture.limit : 0;
|
|
2402
|
+
const fetchLimit = Math.max(baselineFetchLimit, captureFetchLimit);
|
|
1326
2403
|
const baseQuery = sanitizeFtsQuery(args.query.trim());
|
|
1327
2404
|
const probes = args.probes ?? [];
|
|
1328
2405
|
if (probes.length === 0) {
|
|
@@ -1342,15 +2419,20 @@ function searchMessagesInSnapshot(args, sessionFirst) {
|
|
|
1342
2419
|
args.diagnostics.suppressedLiveMessageMatches = outcome.suppressedCount;
|
|
1343
2420
|
}
|
|
1344
2421
|
const rows = outcome.rows.length > 0 || !args.relaxedRecall ? outcome.rows : runMessageFtsQuery(args.db, args.sessionId, relaxedFtsQuery(args.query), fetchLimit, cutoff, args.dateRange, sessionFirst);
|
|
1345
|
-
const
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
2422
|
+
const renderRows = (limit) => {
|
|
2423
|
+
const filtered = rows.slice(0, limit);
|
|
2424
|
+
return filtered.map((row, rank) => ({
|
|
2425
|
+
source: "message",
|
|
2426
|
+
content: previewText(row.content),
|
|
2427
|
+
score: linearDecayScore(rank, filtered.length),
|
|
2428
|
+
messageOrdinal: row.messageOrdinal,
|
|
2429
|
+
messageId: row.messageId,
|
|
2430
|
+
role: row.role
|
|
2431
|
+
}));
|
|
2432
|
+
};
|
|
2433
|
+
if (args.capture)
|
|
2434
|
+
args.capture.results = renderRows(args.capture.limit);
|
|
2435
|
+
return renderRows(args.limit);
|
|
1354
2436
|
}
|
|
1355
2437
|
const sanitizedProbes = probes.map((probe) => ({ probe, query: sanitizeFtsQuery(probe) })).filter((entry) => entry.query.length > 0);
|
|
1356
2438
|
const corpusSize = getIndexedMessageCorpusSize(args.db, args.sessionId, cutoff);
|
|
@@ -1390,39 +2472,44 @@ function searchMessagesInSnapshot(args, sessionFirst) {
|
|
|
1390
2472
|
queryLists.push({ rows: rowsByQuery[queryIndex] ?? [], weight });
|
|
1391
2473
|
queryIndex += 1;
|
|
1392
2474
|
});
|
|
1393
|
-
const
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
existing
|
|
1400
|
-
|
|
1401
|
-
|
|
2475
|
+
const rankProbeLists = (rowLimit, resultLimit) => {
|
|
2476
|
+
const fused = new Map;
|
|
2477
|
+
for (const list of queryLists) {
|
|
2478
|
+
list.rows.slice(0, rowLimit).forEach((row, rank) => {
|
|
2479
|
+
const rrf = list.weight / (RRF_K + rank);
|
|
2480
|
+
const existing = fused.get(row.messageId);
|
|
2481
|
+
if (existing) {
|
|
2482
|
+
existing.score += rrf;
|
|
2483
|
+
} else {
|
|
2484
|
+
fused.set(row.messageId, { row, score: rrf });
|
|
2485
|
+
}
|
|
2486
|
+
});
|
|
2487
|
+
}
|
|
2488
|
+
for (const entry of fused.values()) {
|
|
2489
|
+
let best = 0;
|
|
2490
|
+
for (const probe of probes) {
|
|
2491
|
+
const weight = probeWeights.get(probe) ?? 0;
|
|
2492
|
+
if (weight > best && containsProbeVerbatim(entry.row.content, [probe])) {
|
|
2493
|
+
best = weight;
|
|
2494
|
+
}
|
|
1402
2495
|
}
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
for (const entry of fused.values()) {
|
|
1406
|
-
let best = 0;
|
|
1407
|
-
for (const probe of probes) {
|
|
1408
|
-
const weight = probeWeights.get(probe) ?? 0;
|
|
1409
|
-
if (weight > best && containsProbeVerbatim(entry.row.content, [probe])) {
|
|
1410
|
-
best = weight;
|
|
2496
|
+
if (best > 0) {
|
|
2497
|
+
entry.score += best * VERBATIM_RANK_BONUS;
|
|
1411
2498
|
}
|
|
1412
2499
|
}
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
2500
|
+
const ranked = [...fused.values()].sort((a, b) => b.score !== a.score ? b.score - a.score : a.row.messageOrdinal - b.row.messageOrdinal).slice(0, resultLimit);
|
|
2501
|
+
return ranked.map((entry, rank) => ({
|
|
2502
|
+
source: "message",
|
|
2503
|
+
content: previewText(entry.row.content),
|
|
2504
|
+
score: linearDecayScore(rank, ranked.length),
|
|
2505
|
+
messageOrdinal: entry.row.messageOrdinal,
|
|
2506
|
+
messageId: entry.row.messageId,
|
|
2507
|
+
role: entry.row.role
|
|
2508
|
+
}));
|
|
2509
|
+
};
|
|
2510
|
+
if (args.capture)
|
|
2511
|
+
args.capture.results = rankProbeLists(captureFetchLimit, args.capture.limit);
|
|
2512
|
+
return rankProbeLists(baselineFetchLimit, args.limit);
|
|
1426
2513
|
}
|
|
1427
2514
|
var NOTE_SEARCHABLE_STATUSES = ["active", "pending", "ready"];
|
|
1428
2515
|
var MAX_NOTE_KEYWORD_SCORE = 3.5;
|
|
@@ -1692,12 +2779,17 @@ function toGitCommitResult(hit) {
|
|
|
1692
2779
|
function searchGitCommits(args) {
|
|
1693
2780
|
if (args.limit <= 0)
|
|
1694
2781
|
return [];
|
|
2782
|
+
const lanes = args.lanes;
|
|
1695
2783
|
const hits = searchGitCommitsSync(args.db, args.projectPath, args.query, {
|
|
1696
2784
|
limit: args.limit,
|
|
1697
2785
|
queryEmbedding: args.queryEmbedding,
|
|
1698
2786
|
queryModelId: args.queryModelId,
|
|
1699
2787
|
from: args.dateRange?.from,
|
|
1700
|
-
to: args.dateRange?.to
|
|
2788
|
+
to: args.dateRange?.to,
|
|
2789
|
+
captureLanes: lanes ? (fts, vector) => {
|
|
2790
|
+
lanes.git_fts = fts.map(toGitCommitResult);
|
|
2791
|
+
lanes.git_vector = vector.map(toGitCommitResult);
|
|
2792
|
+
} : undefined
|
|
1701
2793
|
});
|
|
1702
2794
|
return hits.map(toGitCommitResult);
|
|
1703
2795
|
}
|
|
@@ -1719,13 +2811,44 @@ function searchPrimers(args) {
|
|
|
1719
2811
|
WHERE primers_fts MATCH ? AND p.project_path = ? AND p.status = 'active'
|
|
1720
2812
|
${args.dateRange === null ? "" : "AND p.created_at BETWEEN ? AND ?"}
|
|
1721
2813
|
ORDER BY rank ASC
|
|
1722
|
-
LIMIT ?`).all(ftsQuery, args.projectPath, ...args.dateRange === null ? [] : [args.dateRange.from, args.dateRange.to], args.limit * 3);
|
|
1723
|
-
rows.
|
|
1724
|
-
|
|
2814
|
+
LIMIT ?`).all(ftsQuery, args.projectPath, ...args.dateRange === null ? [] : [args.dateRange.from, args.dateRange.to], args.lanes ? Math.max(args.limit * 3, 225) : args.limit * 3);
|
|
2815
|
+
const baselineRows = rows.slice(0, args.limit * 3);
|
|
2816
|
+
baselineRows.forEach((row, index) => {
|
|
2817
|
+
ftsRanks.set(row.id, linearDecayScore(index, baselineRows.length));
|
|
1725
2818
|
});
|
|
2819
|
+
if (args.lanes) {
|
|
2820
|
+
const byId = new Map(primers.map((primer) => [primer.id, primer]));
|
|
2821
|
+
args.lanes.primer_fts = rows.flatMap((row, index) => {
|
|
2822
|
+
const primer = byId.get(row.id);
|
|
2823
|
+
return primer ? [
|
|
2824
|
+
{
|
|
2825
|
+
source: "primer",
|
|
2826
|
+
primerId: primer.id,
|
|
2827
|
+
content: previewText(primerText(primer)),
|
|
2828
|
+
question: primer.question,
|
|
2829
|
+
support: primer.totalSupport,
|
|
2830
|
+
lastObservedAt: primer.lastObservedAt,
|
|
2831
|
+
matchType: "fts",
|
|
2832
|
+
score: linearDecayScore(index, rows.length)
|
|
2833
|
+
}
|
|
2834
|
+
] : [];
|
|
2835
|
+
}).slice(0, 25);
|
|
2836
|
+
}
|
|
1726
2837
|
}
|
|
2838
|
+
const vectorResults = [];
|
|
1727
2839
|
const scored = primers.map((primer) => {
|
|
1728
2840
|
const semantic = args.queryEmbedding && primer.questionEmbedding && primer.questionEmbeddingModelId === args.queryModelId ? normalizeCosineScore(cosineSimilarity(args.queryEmbedding, primer.questionEmbedding)) : 0;
|
|
2841
|
+
if (args.lanes && semantic > 0)
|
|
2842
|
+
vectorResults.push({
|
|
2843
|
+
source: "primer",
|
|
2844
|
+
primerId: primer.id,
|
|
2845
|
+
content: previewText(primerText(primer)),
|
|
2846
|
+
question: primer.question,
|
|
2847
|
+
support: primer.totalSupport,
|
|
2848
|
+
lastObservedAt: primer.lastObservedAt,
|
|
2849
|
+
matchType: "semantic",
|
|
2850
|
+
score: semantic
|
|
2851
|
+
});
|
|
1729
2852
|
const fts = ftsRanks.get(primer.id) ?? 0;
|
|
1730
2853
|
if (semantic <= 0 && fts <= 0)
|
|
1731
2854
|
return null;
|
|
@@ -1741,6 +2864,8 @@ function searchPrimers(args) {
|
|
|
1741
2864
|
matchType: semantic > 0 && fts > 0 ? "hybrid" : semantic > 0 ? "semantic" : "fts"
|
|
1742
2865
|
};
|
|
1743
2866
|
}).filter((result) => result !== null).sort((a, b) => b.score - a.score || b.support - a.support || a.primerId - b.primerId).slice(0, args.limit);
|
|
2867
|
+
if (args.lanes)
|
|
2868
|
+
args.lanes.primer_vector = vectorResults.sort((a, b) => b.score - a.score || b.support - a.support || a.primerId - b.primerId).slice(0, 25);
|
|
1744
2869
|
return scored;
|
|
1745
2870
|
}
|
|
1746
2871
|
function resolveSources(sources) {
|
|
@@ -1818,6 +2943,8 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
|
|
|
1818
2943
|
return [];
|
|
1819
2944
|
}
|
|
1820
2945
|
const limit = normalizeLimit(options.limit);
|
|
2946
|
+
const reranker = options.explicitSearch && options.rerank !== false && isProseQuery(trimmedQuery) ? await prepareReranker(projectPath, sessionId, options.rerankConnectionFile, options.rerankClient) : null;
|
|
2947
|
+
const lanes = reranker || options.captureRerankLanes ? emptySearchLanes() : undefined;
|
|
1821
2948
|
const dateRange = normalizeDateRange(options.from, options.to);
|
|
1822
2949
|
const tierLimit = Math.max(limit * 3, DEFAULT_UNIFIED_SEARCH_LIMIT);
|
|
1823
2950
|
if (options.diagnostics) {
|
|
@@ -1855,6 +2982,7 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
|
|
|
1855
2982
|
sessionId,
|
|
1856
2983
|
query: trimmedQuery,
|
|
1857
2984
|
limit: tierLimit,
|
|
2985
|
+
captureLimit: lanes ? 75 : undefined,
|
|
1858
2986
|
maxOrdinal: options.maxMessageOrdinal,
|
|
1859
2987
|
probes: messageProbes,
|
|
1860
2988
|
relaxedRecall: options.explicitSearch,
|
|
@@ -1872,6 +3000,8 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
|
|
|
1872
3000
|
options.diagnostics.suppressedLiveMessageMatches = outcome.suppressedLiveMessageMatches;
|
|
1873
3001
|
}
|
|
1874
3002
|
messageResults = outcome.results;
|
|
3003
|
+
if (lanes)
|
|
3004
|
+
lanes.message_fts = (outcome.laneResults ?? outcome.results).slice(0, 25);
|
|
1875
3005
|
}
|
|
1876
3006
|
const capturedQuery = await queryEmbeddingPromise;
|
|
1877
3007
|
if (options.signal?.aborted)
|
|
@@ -1888,14 +3018,16 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
|
|
|
1888
3018
|
sessionId,
|
|
1889
3019
|
projectPath,
|
|
1890
3020
|
queryEmbedding,
|
|
1891
|
-
limit: tierLimit,
|
|
3021
|
+
limit: lanes ? Math.max(tierLimit, 25) : tierLimit,
|
|
1892
3022
|
maxOrdinal: options.maxMessageOrdinal,
|
|
1893
3023
|
modelId: chunkModelId && chunkModelId !== "off" ? chunkModelId : null,
|
|
1894
3024
|
dateRange
|
|
1895
3025
|
}) : [];
|
|
3026
|
+
if (lanes)
|
|
3027
|
+
lanes.chunk_vector = compartmentResults.slice(0, 25);
|
|
1896
3028
|
const messageLikeResults = mergeMessageAndCompartmentResults({
|
|
1897
3029
|
messages: messageResults,
|
|
1898
|
-
compartments: compartmentResults,
|
|
3030
|
+
compartments: compartmentResults.slice(0, tierLimit),
|
|
1899
3031
|
limit: tierLimit
|
|
1900
3032
|
});
|
|
1901
3033
|
const [memoryOutcome, gitCommitResults, primerResults, noteResults] = await Promise.all([
|
|
@@ -1910,6 +3042,7 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
|
|
|
1910
3042
|
workspace,
|
|
1911
3043
|
visibleMemoryIds: options.visibleMemoryIds,
|
|
1912
3044
|
backfillMemoryEmbeddings: options.backfillMemoryEmbeddings,
|
|
3045
|
+
lanes,
|
|
1913
3046
|
dateRange
|
|
1914
3047
|
}) : Promise.resolve({
|
|
1915
3048
|
results: [],
|
|
@@ -1922,7 +3055,8 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
|
|
|
1922
3055
|
limit: tierLimit,
|
|
1923
3056
|
queryEmbedding,
|
|
1924
3057
|
queryModelId: embeddingModelId && embeddingModelId !== "off" ? embeddingModelId : null,
|
|
1925
|
-
dateRange
|
|
3058
|
+
dateRange,
|
|
3059
|
+
lanes
|
|
1926
3060
|
})) : Promise.resolve([]),
|
|
1927
3061
|
runPrimers ? Promise.resolve(searchPrimers({
|
|
1928
3062
|
db,
|
|
@@ -1931,14 +3065,15 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
|
|
|
1931
3065
|
limit: tierLimit,
|
|
1932
3066
|
queryEmbedding,
|
|
1933
3067
|
queryModelId: embeddingModelId && embeddingModelId !== "off" ? embeddingModelId : null,
|
|
1934
|
-
dateRange
|
|
3068
|
+
dateRange,
|
|
3069
|
+
lanes
|
|
1935
3070
|
})) : Promise.resolve([]),
|
|
1936
3071
|
runNotes ? Promise.resolve(searchNotes({
|
|
1937
3072
|
db,
|
|
1938
3073
|
sessionId,
|
|
1939
3074
|
projectPath,
|
|
1940
3075
|
query: trimmedQuery,
|
|
1941
|
-
limit: tierLimit,
|
|
3076
|
+
limit: lanes ? Math.max(tierLimit, 25) : tierLimit,
|
|
1942
3077
|
probes: messageProbes,
|
|
1943
3078
|
dateRange
|
|
1944
3079
|
})) : Promise.resolve([])
|
|
@@ -1946,23 +3081,37 @@ async function unifiedSearch2(db, sessionId, projectPath, query, options = {}) {
|
|
|
1946
3081
|
if (options.diagnostics) {
|
|
1947
3082
|
options.diagnostics.suppressedVisibleMemoryIds = memoryOutcome.suppressedVisibleIds;
|
|
1948
3083
|
}
|
|
1949
|
-
|
|
3084
|
+
let results = [
|
|
1950
3085
|
...memoryOutcome.results,
|
|
1951
3086
|
...primerResults,
|
|
1952
3087
|
...messageLikeResults,
|
|
1953
3088
|
...gitCommitResults,
|
|
1954
3089
|
...noteResults
|
|
1955
3090
|
].sort(compareUnifiedResults).slice(0, limit);
|
|
3091
|
+
const originalResults = results;
|
|
3092
|
+
const originalLatencyMs = Date.now() - measurementStartedAt;
|
|
3093
|
+
if (lanes) {
|
|
3094
|
+
lanes.notes = noteResults.slice(0, 25);
|
|
3095
|
+
options.captureRerankLanes?.(lanes);
|
|
3096
|
+
}
|
|
3097
|
+
if (reranker && lanes) {
|
|
3098
|
+
const pool = fuseSearchLanes(lanes);
|
|
3099
|
+
try {
|
|
3100
|
+
results = await rerankSearchResults(reranker, trimmedQuery, results, pool, candidateTexts(db, sessionId, projectPath, pool), limit);
|
|
3101
|
+
} catch {
|
|
3102
|
+
logRerankFallback("candidate_validation");
|
|
3103
|
+
}
|
|
3104
|
+
}
|
|
1956
3105
|
if (!options.measurementDisabled) {
|
|
1957
3106
|
recordShadowMeasurement({
|
|
1958
3107
|
db,
|
|
1959
3108
|
sessionId,
|
|
1960
3109
|
projectPath,
|
|
1961
3110
|
query: trimmedQuery,
|
|
1962
|
-
options,
|
|
1963
|
-
primaryResults:
|
|
3111
|
+
options: { ...options, rerank: false, captureRerankLanes: undefined },
|
|
3112
|
+
primaryResults: originalResults,
|
|
1964
3113
|
primaryQuery: queryContract,
|
|
1965
|
-
primaryLatencyMs:
|
|
3114
|
+
primaryLatencyMs: originalLatencyMs,
|
|
1966
3115
|
search: unifiedSearch2
|
|
1967
3116
|
});
|
|
1968
3117
|
}
|
|
@@ -2103,4 +3252,4 @@ ${bodyParts.join(`
|
|
|
2103
3252
|
`)}`;
|
|
2104
3253
|
}
|
|
2105
3254
|
|
|
2106
|
-
export { indexCommitsForProject, embedUnembeddedCommits, createUnifiedSearchDiagnostics2, searchMessageHistory2, parseIdShapedQuery2, resolveMemoriesByIdsForSearch2, unifiedSearch2, formatSearchResults2 };
|
|
3255
|
+
export { renderSingleStoreMigrationRequiredRefusal, SingleStoreMigrationRequiredError, singleStoreMigrationRequiredFailure, projectNeedsSingleStoreMigration, STORE_AHEAD_OF_BINARY_CODE, storeAheadOfBinaryFailure, TRANSFORM_PAGE_UPLOAD_TIMEOUT_MS, transformColdStartExecuteTimeoutMs, getDefaultSubcConnectionFile, isModuleTransportGenerationChangedResult, SubcModuleTransport, indexCommitsForProject, embedUnembeddedCommits, createUnifiedSearchDiagnostics2, searchMessageHistory2, parseIdShapedQuery2, resolveMemoriesByIdsForSearch2, unifiedSearch2, formatSearchResults2 };
|