@cortexkit/opencode-magic-context 0.46.1 → 0.48.0
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/agents/magic-context-prompt.d.ts +1 -1
- package/dist/agents/magic-context-prompt.d.ts.map +1 -1
- package/dist/{announcement-y35wzg2r.js → announcement-fp14dw0n.js} +3 -2
- package/dist/auto-search-worker.js +112 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/live-run-config.d.ts.map +1 -1
- package/dist/config/migrate-config-location.d.ts.map +1 -1
- package/dist/config/mural-model-deprecation.d.ts +15 -0
- package/dist/config/mural-model-deprecation.d.ts.map +1 -0
- package/dist/config/project-security.d.ts +0 -3
- package/dist/config/project-security.d.ts.map +1 -1
- package/dist/config/schema/magic-context.d.ts +21 -9
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-7fj2b9jw.js → conflict-warning-hook-w8cykrnf.js} +12 -9
- package/dist/{context-sh2m2vde.js → context-m0cy262m.js} +1785 -913
- package/dist/{derive-budgets-7nj7r1rv.js → derive-budgets-sg0xsq7s.js} +4 -3
- package/dist/embedding-activity-g1dhes6g.js +10 -0
- package/dist/embedding-backfill-9rcm1mfy.js +21 -0
- package/dist/embedding-cache-mgyr73ef.js +16 -0
- package/dist/embedding-worker.js +11 -9
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts +1 -0
- package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-config.d.ts +3 -3
- package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts +1 -0
- package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-async.d.ts +16 -3
- package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
- package/dist/features/magic-context/message-index-bounded.d.ts +17 -0
- package/dist/features/magic-context/message-index-bounded.d.ts.map +1 -0
- package/dist/features/magic-context/message-index.d.ts +7 -1
- package/dist/features/magic-context/message-index.d.ts.map +1 -1
- package/dist/features/magic-context/mural/render-trigger.d.ts +7 -4
- package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
- package/dist/features/magic-context/overflow-detection.d.ts +2 -0
- package/dist/features/magic-context/overflow-detection.d.ts.map +1 -1
- package/dist/features/magic-context/pi-content-decisions.d.ts +7 -1
- package/dist/features/magic-context/pi-content-decisions.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +7 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/search.d.ts +31 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/session-activity.d.ts.map +1 -1
- package/dist/features/magic-context/session-project-storage.d.ts +8 -2
- package/dist/features/magic-context/session-project-storage.d.ts.map +1 -1
- package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
- package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
- package/dist/features/magic-context/storage-db.d.ts.map +1 -1
- package/dist/features/magic-context/storage-historian-runs.d.ts +2 -5
- package/dist/features/magic-context/storage-historian-runs.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +12 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-session.d.ts +6 -0
- package/dist/features/magic-context/storage-meta-session.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tag-identity-revision.d.ts +30 -0
- package/dist/features/magic-context/storage-tag-identity-revision.d.ts.map +1 -0
- package/dist/features/magic-context/storage-tags.d.ts +148 -3
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/features/magic-context/storage.d.ts +1 -0
- package/dist/features/magic-context/storage.d.ts.map +1 -1
- package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
- package/dist/features/magic-context/transform-decision-log.d.ts +4 -2
- package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
- package/dist/harness-e4avh192.js +10 -0
- package/dist/hooks/magic-context/active-anthropic-turn.d.ts +10 -0
- package/dist/hooks/magic-context/active-anthropic-turn.d.ts.map +1 -0
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-blocking.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/auto-search-blocking.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-deadline.d.ts +7 -0
- package/dist/hooks/magic-context/auto-search-deadline.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-host-review.fixture.d.ts +3 -0
- package/dist/hooks/magic-context/auto-search-host-review.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-lock-review.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/auto-search-lock-review.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-long-lock-review.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/auto-search-long-lock-review.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-omp-host-review.fixture.d.ts +4 -0
- package/dist/hooks/magic-context/auto-search-omp-host-review.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-omp-loader.fixture.d.ts +3 -0
- package/dist/hooks/magic-context/auto-search-omp-loader.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-snapshot.fixture.d.ts +4 -0
- package/dist/hooks/magic-context/auto-search-snapshot.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-worker-client.d.ts +98 -0
- package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-worker.d.ts +2 -0
- package/dist/hooks/magic-context/auto-search-worker.d.ts.map +1 -0
- package/dist/hooks/magic-context/caveman-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/command-handler.d.ts +1 -0
- package/dist/hooks/magic-context/command-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner-incremental.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-types.d.ts +3 -5
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts +2 -1
- package/dist/hooks/magic-context/compartment-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts +3 -1
- package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts +1 -1
- package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/execute-status.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +2 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-drain-gate.d.ts +11 -0
- package/dist/hooks/magic-context/historian-drain-gate.d.ts.map +1 -0
- package/dist/hooks/magic-context/hook.d.ts +3 -2
- 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-assistant-turn.d.ts +25 -0
- package/dist/hooks/magic-context/latest-assistant-turn.d.ts.map +1 -0
- package/dist/hooks/magic-context/latest-thinking-recovery.d.ts +61 -0
- package/dist/hooks/magic-context/latest-thinking-recovery.d.ts.map +1 -0
- package/dist/hooks/magic-context/lkg-persist.d.ts +4 -3
- package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-replay.d.ts +13 -8
- package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
- package/dist/hooks/magic-context/lkg-slot.d.ts +139 -2
- package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
- package/dist/hooks/magic-context/message-search-accepting-silent-worker.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/message-search-accepting-silent-worker.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
- package/dist/hooks/magic-context/oc-stall-r2-warmup-worker.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/oc-stall-r2-warmup-worker.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/oc-stall-search-review.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/oc-stall-search-review.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/opencode-proven-floor.d.ts +6 -0
- package/dist/hooks/magic-context/opencode-proven-floor.d.ts.map +1 -0
- package/dist/hooks/magic-context/opencode1-to-model-messages.fixture.d.ts +63 -0
- package/dist/hooks/magic-context/opencode1-to-model-messages.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/pass-outcome.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/provider-visible-parts.d.ts +45 -0
- package/dist/hooks/magic-context/provider-visible-parts.d.ts.map +1 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup-silent-worker.fixture.d.ts +2 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup-silent-worker.fixture.d.ts.map +1 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup-worker.d.ts +2 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup-worker.d.ts.map +1 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +87 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts +12 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +5 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +83 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
- package/dist/hooks/magic-context/reasoning-budget-status.d.ts +15 -0
- package/dist/hooks/magic-context/reasoning-budget-status.d.ts.map +1 -0
- package/dist/hooks/magic-context/reasoning-budget.d.ts +40 -0
- package/dist/hooks/magic-context/reasoning-budget.d.ts.map +1 -0
- package/dist/hooks/magic-context/reasoning-removal.d.ts +6 -6
- package/dist/hooks/magic-context/reasoning-removal.d.ts.map +1 -1
- package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/sentinel.d.ts +45 -1
- package/dist/hooks/magic-context/sentinel.d.ts.map +1 -1
- package/dist/hooks/magic-context/strip-content.d.ts +21 -5
- package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
- package/dist/hooks/magic-context/system-prompt-hash.d.ts +1 -0
- package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-messages.d.ts +21 -0
- package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
- package/dist/hooks/magic-context/tag-owner-warmup.d.ts +6 -0
- package/dist/hooks/magic-context/tag-owner-warmup.d.ts.map +1 -0
- package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
- package/dist/hooks/magic-context/token-count-exact.d.ts +35 -0
- package/dist/hooks/magic-context/token-count-exact.d.ts.map +1 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts +5 -0
- package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +3 -28
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +28 -6
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +11 -3
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
- package/dist/{index-hpecdzec.js → index-0an7742d.js} +6820 -6587
- package/dist/index-0qhce371.js +120 -0
- package/dist/{index-q6hef7fh.js → index-0sahzkwr.js} +6 -19
- package/dist/{index-k5bdx1bx.js → index-0w56v4fm.js} +3 -5
- package/dist/index-14cjxt20.js +819 -0
- package/dist/{v2/server-51dv1pr5.js → index-1qb0z7wa.js} +301 -27
- package/dist/index-2bvekkfy.js +11 -0
- package/dist/{index-sj29b3z2.js → index-2y0s2hep.js} +3 -3
- package/dist/index-4dhv7mqz.js +131 -0
- package/dist/{index-b35pxds2.js → index-58e3y90n.js} +1 -18
- package/dist/index-5zygecde.js +152 -0
- package/dist/{index-sjthx78w.js → index-692jzy0p.js} +16879 -22907
- package/dist/index-72nhv486.js +2307 -0
- package/dist/index-7jzrrxap.js +931 -0
- package/dist/index-7mx8v0pw.js +3591 -0
- package/dist/index-8ajstryz.js +18 -0
- package/dist/{index-sfpzqvdz.js → index-8cd2j99z.js} +2 -3
- package/dist/{index-hybnrwq0.js → index-8j7gqj40.js} +131 -128
- package/dist/index-bdckkfw6.js +3261 -0
- package/dist/{index-8x2v7gg9.js → index-bhvjj0ys.js} +158 -2455
- package/dist/index-c43kr12f.js +3030 -0
- package/dist/index-cb7emxgj.js +984 -0
- package/dist/index-d9vfe7xq.js +16 -0
- package/dist/{index-5gq3b2ya.js → index-db7zwa3v.js} +147 -209
- package/dist/index-dhwzyd54.js +1142 -0
- package/dist/{index-8da2zjhz.js → index-eeezr5zz.js} +9 -7
- package/dist/{index-pkbcrdqs.js → index-f0h6xwqm.js} +3412 -4552
- package/dist/index-fb3zxn06.js +13 -0
- package/dist/index-fbv1dn35.js +171 -0
- package/dist/index-fr0wbhdn.js +43 -0
- package/dist/{index-mc22ayvf.js → index-ghc9f0n7.js} +11 -9
- package/dist/{index-fzbvakh0.js → index-jcbd3znx.js} +3 -3
- package/dist/{index-5p8jdswx.js → index-k1xb52kd.js} +20 -13
- package/dist/index-k9nnwad5.js +3532 -0
- package/dist/{v2/server-fg34g6a5.js → index-kb9nn0a0.js} +309 -52
- package/dist/index-knh4y330.js +566 -0
- package/dist/{index-q4yp4b52.js → index-mfkzp7qj.js} +28 -28
- package/dist/{index-sgthv3f7.js → index-mmyh6d8f.js} +4 -4
- package/dist/index-pavzsdc6.js +17 -0
- package/dist/{index-0d3g3461.js → index-pdecwzrd.js} +19 -16
- package/dist/index-pg50n748.js +1060 -0
- package/dist/index-q2tqeqde.js +2106 -0
- package/dist/index-q7h7csab.js +3469 -0
- package/dist/index-qt1qqasc.js +22 -0
- package/dist/{index-majxda46.js → index-ty64eqcn.js} +28 -18
- package/dist/{index-7qw742ev.js → index-yq8n9qcb.js} +25 -44
- package/dist/{index-sfnj6h8h.js → index-z8e0psj8.js} +20 -20
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1061 -260
- package/dist/logger-d3wex3dz.js +20 -0
- package/dist/message-index-bounded-7ezbgddp.js +124 -0
- package/dist/{v2/message-time-backfill-r6qkem1x.js → message-time-backfill-brbd63hv.js} +8 -6
- package/dist/migration-worker.js +25 -16
- package/dist/{model-resolution-xhfmyyvy.js → model-resolution-nx97z3x7.js} +1 -1
- package/dist/plugin/dream-timer.d.ts +1 -1
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +3 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/host-stall-profiler-report.d.ts +2 -0
- package/dist/plugin/host-stall-profiler-report.d.ts.map +1 -0
- package/dist/plugin/host-stall-profiler.d.ts +3 -0
- package/dist/plugin/host-stall-profiler.d.ts.map +1 -0
- package/dist/plugin/messages-transform.d.ts +21 -19
- 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 +88 -0
- package/dist/raw-ordinal-warmup-worker.js +60 -0
- package/dist/{read-session-chunk-egz7r68d.js → read-session-chunk-6k83m4fj.js} +15 -9
- package/dist/read-session-raw-3g9qy1xa.js +58 -0
- package/dist/recomp-orchestrator-d3fp1cy0.js +57 -0
- package/dist/{v2/safe-notification-target-eb1n1vfb.js → safe-notification-target-5ffqq32m.js} +4 -2
- package/dist/search-epax1ecv.js +45 -0
- package/dist/{v2/send-session-notification-qs0j78v6.js → send-session-notification-erecz4y4.js} +10 -6
- package/dist/shared/auto-search-lifecycle.d.ts +7 -0
- package/dist/shared/auto-search-lifecycle.d.ts.map +1 -0
- package/dist/shared/conflict-detector.d.ts.map +1 -1
- package/dist/shared/historian-tool-expansions.d.ts +1 -1
- package/dist/shared/historian-tool-expansions.d.ts.map +1 -1
- package/dist/shared/historian-tool-template.d.ts +2 -2
- package/dist/shared/historian-tool-template.d.ts.map +1 -1
- package/dist/shared/host-stall-profiler-bun.d.ts +46 -0
- package/dist/shared/host-stall-profiler-bun.d.ts.map +1 -0
- package/dist/shared/host-stall-profiler-common.d.ts +58 -0
- package/dist/shared/host-stall-profiler-common.d.ts.map +1 -0
- package/dist/shared/host-stall-profiler-node.d.ts +36 -0
- package/dist/shared/host-stall-profiler-node.d.ts.map +1 -0
- package/dist/shared/host-stall-profiler-report.d.ts +68 -0
- package/dist/shared/host-stall-profiler-report.d.ts.map +1 -0
- package/dist/shared/host-stall-profiler.d.ts +5 -0
- package/dist/shared/host-stall-profiler.d.ts.map +1 -0
- package/dist/shared/model-resolution.d.ts +2 -3
- package/dist/shared/model-resolution.d.ts.map +1 -1
- package/dist/shared/sqlite.d.ts +46 -1
- package/dist/shared/sqlite.d.ts.map +1 -1
- package/dist/shared/stable-json.d.ts.map +1 -1
- package/dist/shared/status-view.d.ts.map +1 -1
- package/dist/shared/user-facing-codes.d.ts +0 -5
- package/dist/shared/user-facing-codes.d.ts.map +1 -1
- package/dist/shared/window-geometry.d.ts +4 -0
- package/dist/shared/window-geometry.d.ts.map +1 -1
- package/dist/sqlite-context-pragmas-mv9jqwjh.js +6 -0
- package/dist/sqlite-mhjkerzq.js +46 -0
- package/dist/storage-memory-07fx57k6.js +71 -0
- package/dist/storage-tags-d3b0v2ss.js +131 -0
- package/dist/{task-config-v81k8jvk.js → task-config-cgpg0nvh.js} +2 -2
- package/dist/tools/ctx-expand/render.d.ts.map +1 -1
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-note/constants.d.ts +4 -0
- package/dist/tools/ctx-note/constants.d.ts.map +1 -1
- package/dist/tools/ctx-note/tools.d.ts +1 -0
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/tools/ctx-search/tools.d.ts.map +1 -1
- package/dist/tools/parameter-descriptions.d.ts +2 -2
- package/dist/tools/parameter-descriptions.d.ts.map +1 -1
- package/dist/{transform-postprocess-phase-bqhz6vdr.js → transform-postprocess-phase-spcy2qre.js} +35 -17
- package/dist/transformers-node-wasm.js +18415 -18415
- package/dist/v2/auto-search-worker.js +112 -0
- package/dist/v2/{context-zecmzk5s.js → context-sf98kstd.js} +8378 -8530
- package/dist/v2/{derive-budgets-kdgp4s3r.js → derive-budgets-3vc0y84t.js} +4 -3
- package/dist/v2/embedding-activity-g1dhes6g.js +10 -0
- package/dist/v2/embedding-backfill-vn8g1nh1.js +21 -0
- package/dist/v2/embedding-cache-mgyr73ef.js +16 -0
- package/dist/v2/embedding-worker.js +12 -9
- package/dist/v2/fold/host-media.d.ts +4 -0
- package/dist/v2/fold/host-media.d.ts.map +1 -1
- package/dist/v2/fold/memory-cache.d.ts +70 -0
- package/dist/v2/fold/memory-cache.d.ts.map +1 -0
- package/dist/v2/fold/native-codec.d.ts +10 -0
- package/dist/v2/fold/native-codec.d.ts.map +1 -0
- package/dist/v2/fold/native-replay.d.ts +58 -0
- package/dist/v2/fold/native-replay.d.ts.map +1 -0
- package/dist/v2/fold/policy.d.ts +24 -0
- package/dist/v2/fold/policy.d.ts.map +1 -0
- package/dist/v2/harness-e4avh192.js +10 -0
- package/dist/v2/hidden-completion.d.ts.map +1 -1
- package/dist/v2/hooks/context.d.ts +2 -2
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/dream-manual.d.ts +1 -1
- package/dist/v2/hooks/dream-manual.d.ts.map +1 -1
- package/dist/v2/hooks/dream-timer.d.ts.map +1 -1
- package/dist/v2/hooks/dream-trigger.d.ts +1 -2
- package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
- package/dist/v2/hooks/payload.d.ts.map +1 -1
- package/dist/v2/hooks/tools.d.ts.map +1 -1
- package/dist/v2/hooks/types.d.ts +6 -0
- package/dist/v2/hooks/types.d.ts.map +1 -1
- package/dist/v2/logger-mxd0ym09.js +19 -0
- package/dist/v2/message-index-bounded-dy3s2k1e.js +123 -0
- package/dist/{message-time-backfill-68gj6t3e.js → v2/message-time-backfill-gtx1pwk1.js} +7 -7
- package/dist/v2/migration-worker.js +24 -15
- package/dist/v2/{model-resolution-xhfmyyvy.js → model-resolution-nx97z3x7.js} +1 -1
- package/dist/v2/project-embedding-registry-1tgba5dv.js +86 -0
- package/dist/v2/raw-ordinal-warmup-worker.js +60 -0
- package/dist/v2/{read-session-chunk-8vjp6581.js → read-session-chunk-rh4khdkv.js} +14 -8
- package/dist/v2/read-session-raw-bsbmf0vj.js +57 -0
- package/dist/v2/recomp-orchestrator-az61rfcg.js +57 -0
- package/dist/{safe-notification-target-43r8jsxw.js → v2/safe-notification-target-73ax1p5v.js} +3 -3
- package/dist/v2/search-nzkwrc6n.js +45 -0
- package/dist/{send-session-notification-dyw42dtr.js → v2/send-session-notification-6km439kn.js} +9 -7
- package/dist/{index-5eqk6z3s.js → v2/server-1r6pmz4f.js} +301 -27
- package/dist/v2/server-2bvekkfy.js +11 -0
- package/dist/v2/server-2fbhp79z.js +3205 -0
- package/dist/v2/{server-ajzeteqw.js → server-2ra6pwf3.js} +1 -18
- package/dist/v2/server-4dhv7mqz.js +131 -0
- package/dist/v2/{server-xa4xe3rv.js → server-4k748ke6.js} +11 -1053
- package/dist/v2/{server-vs5gpnd4.js → server-52awr2mw.js} +81 -145
- package/dist/v2/{server-1qbnzc80.js → server-5m3dt5r1.js} +136 -148
- package/dist/v2/server-686jg6eb.js +3508 -0
- package/dist/v2/server-7jzrrxap.js +931 -0
- package/dist/v2/server-7wwc2nga.js +3023 -0
- package/dist/v2/server-8ajstryz.js +18 -0
- package/dist/v2/{server-sfpzqvdz.js → server-8cd2j99z.js} +2 -3
- package/dist/v2/server-8pyt7hev.js +3408 -0
- package/dist/v2/server-8tqanswc.js +984 -0
- package/dist/v2/{server-14vq4kpm.js → server-aan4q8mx.js} +3 -3
- package/dist/v2/server-d9vfe7xq.js +16 -0
- package/dist/v2/server-e0vdaae2.js +3591 -0
- package/dist/v2/server-ezhze64f.js +1048 -0
- package/dist/v2/server-fb3zxn06.js +13 -0
- package/dist/v2/server-fr0wbhdn.js +43 -0
- package/dist/v2/server-g5r0n3b6.js +1137 -0
- package/dist/v2/server-gjcr4w98.js +154 -0
- package/dist/v2/server-k228xhjg.js +171 -0
- package/dist/v2/{server-jc7y02q0.js → server-k8x2rbxc.js} +5119 -10948
- package/dist/{index-fg34g6a5.js → v2/server-kb9nn0a0.js} +309 -52
- package/dist/v2/{server-g0fjrkta.js → server-mfkzp7qj.js} +28 -28
- package/dist/v2/server-pavzsdc6.js +17 -0
- package/dist/v2/server-psqc7e9n.js +2106 -0
- package/dist/v2/server-qt1qqasc.js +22 -0
- package/dist/v2/server-qye6ykf7.js +120 -0
- package/dist/v2/{server-qdjnb2z1.js → server-r5p3b1wy.js} +11 -9
- package/dist/v2/server-sggvvzhb.js +759 -0
- package/dist/v2/{server-y8maxeft.js → server-v06jcv0w.js} +16 -13
- package/dist/v2/server-vqpf3167.js +1048 -0
- package/dist/v2/{server-c5gz8wph.js → server-x2g40a71.js} +2048 -2059
- package/dist/v2/{server-wvjvfhck.js → server-xdfwt6kh.js} +20 -16
- package/dist/v2/{server-mcfawjgc.js → server-xxm59eww.js} +25 -44
- package/dist/v2/server-yczc713m.js +564 -0
- package/dist/v2/{server-3n4q9xme.js → server-z2037m6z.js} +4 -4
- package/dist/v2/{server-e29d7p7c.js → server-zm570tr2.js} +166 -160
- package/dist/v2/{server-6r257mf5.js → server-zxhgvsf9.js} +3 -3
- package/dist/v2/server.js +16 -14
- package/dist/v2/sqlite-context-pragmas-mv9jqwjh.js +6 -0
- package/dist/v2/sqlite-mhjkerzq.js +46 -0
- package/dist/v2/storage-memory-07fx57k6.js +71 -0
- package/dist/v2/storage-tags-w4tv77sn.js +130 -0
- package/dist/v2/store-reader.d.ts +16 -0
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/{task-config-tbndqyny.js → task-config-x0hq3qfd.js} +2 -2
- package/dist/v2/transformers-node-wasm.js +18415 -18415
- package/dist/v2/tui/index.d.ts.map +1 -1
- package/dist/v2/tui/types.d.ts +1 -10
- package/dist/v2/tui/types.d.ts.map +1 -1
- package/dist/v2/{wrapup-orchestrator-0snhvwcv.js → wrapup-orchestrator-mz7efs7w.js} +51 -27
- package/dist/wrapup-orchestrator-amzta1t4.js +44 -0
- package/package.json +4 -3
- package/src/agents/magic-context-prompt.ts +27 -2
- package/src/agents/smart-notes-enabled.test.ts +294 -0
- package/src/agents/smart-notes-on.golden.json +70 -0
- package/src/config/index.test.ts +67 -1
- package/src/config/index.ts +8 -0
- package/src/config/latch-permanence-guard.test.ts +4 -0
- package/src/config/live-run-config.test.ts +37 -1
- package/src/config/live-run-config.ts +28 -0
- package/src/config/migrate-config-location.ts +10 -3
- package/src/config/mural-model-deprecation.ts +24 -0
- package/src/config/project-security.hostile-matrix.test.ts +4 -44
- package/src/config/project-security.test.ts +9 -14
- package/src/config/project-security.ts +13 -55
- package/src/config/schema/magic-context.test.ts +6 -5
- package/src/config/schema/magic-context.ts +34 -16
- package/src/features/magic-context/dreamer/task-registry.ts +6 -0
- package/src/shared/auto-search-lifecycle.ts +27 -0
- package/src/shared/conflict-detector.test.ts +56 -0
- package/src/shared/conflict-detector.ts +16 -5
- package/src/shared/historian-tool-defaults.json +6 -6
- package/src/shared/historian-tool-expansions.ts +65 -8
- package/src/shared/historian-tool-preview-defaults.json +13 -0
- package/src/shared/historian-tool-template.ts +48 -14
- package/src/shared/host-stall-profiler-bun.ts +358 -0
- package/src/shared/host-stall-profiler-common.ts +159 -0
- package/src/shared/host-stall-profiler-node.test.ts +234 -0
- package/src/shared/host-stall-profiler-node.ts +274 -0
- package/src/shared/host-stall-profiler-report.ts +248 -0
- package/src/shared/host-stall-profiler.ts +57 -0
- package/src/shared/model-resolution.test.ts +54 -17
- package/src/shared/model-resolution.ts +6 -17
- package/src/shared/sqlite-640-review-r2.test.ts +136 -0
- package/src/shared/sqlite-640-review.test.ts +183 -0
- package/src/shared/sqlite-acquisition-routing.test.ts +18 -0
- package/src/shared/sqlite.test.ts +52 -0
- package/src/shared/sqlite.ts +423 -37
- package/src/shared/stable-json-linear.test.ts +109 -0
- package/src/shared/stable-json.ts +37 -7
- package/src/shared/status-view.test.ts +6 -1
- package/src/shared/status-view.ts +15 -1
- package/src/shared/tag-transcript.ts +6 -0
- package/src/shared/user-facing-codes.ts +2 -6
- package/src/shared/window-geometry.ts +10 -0
- package/src/shared/write-transaction-attribution.test.ts +2 -2
- package/src/v2/tui/host-contract.test.ts +41 -67
- package/src/v2/tui/index.ts +6 -214
- package/src/v2/tui/types.ts +5 -17
- package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts +0 -45
- package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts.map +0 -1
- package/dist/features/magic-context/checkout-claim.d.ts +0 -155
- package/dist/features/magic-context/checkout-claim.d.ts.map +0 -1
- package/dist/index-3h0ybwah.js +0 -6540
- package/dist/index-r5hmbx3t.js +0 -7773
- package/dist/recomp-orchestrator-y15j0rb9.js +0 -39
- package/dist/v2/recomp-orchestrator-8ejxvrzz.js +0 -39
- package/dist/v2/server-frbm99q5.js +0 -7698
- package/dist/v2/server-qp5hx1ad.js +0 -6366
- package/dist/wrapup-orchestrator-39amhv9s.js +0 -26
- /package/dist/{index-en1k8h8m.js → index-2pp04pmg.js} +0 -0
- /package/dist/v2/{index-en1k8h8m.js → index-2pp04pmg.js} +0 -0
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
|
-
toolTemplateError
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
toolTemplateError
|
|
3
|
+
} from "./index-mfkzp7qj.js";
|
|
4
|
+
import {
|
|
5
|
+
getSynapseLaneIdentity
|
|
6
|
+
} from "./index-72nhv486.js";
|
|
7
|
+
import {
|
|
8
|
+
getHarness2
|
|
9
|
+
} from "./index-pavzsdc6.js";
|
|
6
10
|
import {
|
|
7
|
-
getHarness,
|
|
8
11
|
getMagicContextStorageDir
|
|
9
|
-
} from "./index-
|
|
12
|
+
} from "./index-0sahzkwr.js";
|
|
10
13
|
import {
|
|
11
14
|
importPluginModule,
|
|
12
|
-
|
|
13
|
-
} from "./index-
|
|
15
|
+
log2
|
|
16
|
+
} from "./index-8j7gqj40.js";
|
|
14
17
|
import {
|
|
15
|
-
|
|
16
|
-
} from "./index-
|
|
18
|
+
computeNormalizedHash
|
|
19
|
+
} from "./index-2bvekkfy.js";
|
|
17
20
|
import {
|
|
18
21
|
shouldEnforcePrivateStoragePermissions,
|
|
19
22
|
ensureStorageDirectorySync,
|
|
@@ -21,6 +24,10 @@ import {
|
|
|
21
24
|
writeStorageFileHandleAsync,
|
|
22
25
|
createStorageFileHandleAsync
|
|
23
26
|
} from "./index-1bc61ans.js";
|
|
27
|
+
import {
|
|
28
|
+
DEFAULT_PROTECTED_TOOLS,
|
|
29
|
+
mergeProtectedTools
|
|
30
|
+
} from "./index-d9vfe7xq.js";
|
|
24
31
|
import {
|
|
25
32
|
modelRefLookupOrder
|
|
26
33
|
} from "./index-avwt563y.js";
|
|
@@ -97,13 +104,6 @@ function buildPrimaryLanguageDirective(language) {
|
|
|
97
104
|
return `Use ${target} for your natural-language replies to the user unless the user explicitly asks for another language. Keep code, identifiers, file paths, commands, logs, and quoted text verbatim.`;
|
|
98
105
|
}
|
|
99
106
|
|
|
100
|
-
// src/features/magic-context/memory/embedding-local.ts
|
|
101
|
-
import { readdirSync, statSync } from "node:fs";
|
|
102
|
-
import { stat, unlink } from "node:fs/promises";
|
|
103
|
-
import { dirname, join } from "node:path";
|
|
104
|
-
import { pathToFileURL } from "node:url";
|
|
105
|
-
import { workerData } from "node:worker_threads";
|
|
106
|
-
|
|
107
107
|
// src/config/schema/magic-context.ts
|
|
108
108
|
import { homedir } from "node:os";
|
|
109
109
|
|
|
@@ -5489,7 +5489,7 @@ var HistorianConfigSchema = AgentMetadataSchema.extend({
|
|
|
5489
5489
|
ctx.addIssue({ code: "custom", message: error });
|
|
5490
5490
|
}),
|
|
5491
5491
|
literal(false)
|
|
5492
|
-
])).optional().describe('Readable historian tool expansions, keyed by exact host tool name. Templates override built-in defaults; false disables an expansion. Supports ${input.path}, ${output.path}, bare ${output}, array [N], [*].field, .each("${field}"), .join("separator"), .count and final .truncate(N). Missing fields are empty;
|
|
5492
|
+
])).optional().describe('Readable historian tool expansions, keyed by exact host tool name. Templates override built-in defaults; false disables an expansion. Supports ${input.path}, ${output.path}, bare ${output}, array [N], [*].field, .each("${field}"), .join("separator"), .count and final .truncate(N). Missing fields are empty. Historian text and lists have no implicit caps; explicit .truncate(N) keeps complete sentences and marks omitted characters, or emits only the marker if no sentence fits. When the ctx_expand history-recovery tool is called in verbose mode, its tool-call previews retain their original built-in templates and limits (300 characters per placeholder, 10 list elements, 1000 characters per expansion). Valid in user and project config; never changes the wire or default ctx_expand transcript.'),
|
|
5493
5493
|
opencode: OpenCodeHarnessBlockSchema.optional(),
|
|
5494
5494
|
pi: PiHarnessBlockSchema.optional(),
|
|
5495
5495
|
omp: OmpHarnessBlockSchema.optional(),
|
|
@@ -5610,7 +5610,7 @@ var MagicContextConfigSchema = object({
|
|
|
5610
5610
|
allow_home_project: boolean2().default(false).describe("Allow Magic Context sessions launched from the exact canonical home directory. A non-git home uses its deterministic dir: identity; a home repository uses its git: identity. USER-LEVEL ONLY: project config is ignored. The home identity is excluded from registry seed exports, never resolves descendants by containment, and cannot join a workspace."),
|
|
5611
5611
|
mural: object({
|
|
5612
5612
|
enabled: boolean2().default(false),
|
|
5613
|
-
model:
|
|
5613
|
+
model: unknown().optional().describe("Deprecated: ignored. compress-cues now uses the dreamer model for each harness, like every other dreamer task; override it with dreamer.opencode.tasks.compress-cues.model (or the pi/omp equivalent). Remove this key; it no longer does anything.").meta({ deprecated: true })
|
|
5614
5614
|
}).default({ enabled: false }).describe("Experimental mural: a single deterministically-rendered image of project memories that did not fit the context budget. Cues are compressed per-memory by the compress-cues dreamer task."),
|
|
5615
5615
|
transform_mode: _enum(["ts", "rust"]).default("ts").describe('Experimental: routes the entire Magic Context runtime for the project through the ck-mc Rust module over subc (requires user-level `subc` config); "ts" is the current TypeScript pipeline.'),
|
|
5616
5616
|
auto_update: boolean2().optional().describe("Enable automatic npm self-update checks for the OpenCode plugin. Security: USER-only in config loader, so hostile project configs cannot suppress updates."),
|
|
@@ -5620,8 +5620,9 @@ var MagicContextConfigSchema = object({
|
|
|
5620
5620
|
historian: HistorianConfigSchema.describe("Historian metadata plus independent strict OpenCode, Pi, and OMP execution blocks. Retained metadata stays at historian; model, fallback_models, variant, and thinking_level belong only in historian.opencode, historian.pi, or historian.omp."),
|
|
5621
5621
|
dreamer: DreamerConfigSchema.optional().describe("Dreamer metadata and scheduling plus independent strict OpenCode, Pi, and OMP execution blocks. schedule and promotion_threshold stay at dreamer.tasks; model, fallback_models, variant, thinking_level, and timeout_minutes belong only in the matching harness block."),
|
|
5622
5622
|
smart_notes: object({
|
|
5623
|
+
enabled: boolean2().default(true).describe("Enable smart-note authoring and condition evaluation. User-level only: tool definitions are process-wide. Changes require a host restart and rebuild each session's cached prompt once. Pending notes remain stored and unchecked; already-ready notes still surface."),
|
|
5623
5624
|
retina_handoff: boolean2().default(false).describe("When true, dreamer skips smart notes whose surface conditions compiled to retina provider configs at authoring time. Default false keeps both paths active until the retina consumer is deployed.")
|
|
5624
|
-
}).default({ retina_handoff: false }).describe("Smart-note ownership transition controls."),
|
|
5625
|
+
}).default({ enabled: true, retina_handoff: false }).describe("Smart-note ownership transition controls."),
|
|
5625
5626
|
cache_ttl: union([string(), object({ default: string() }).catchall(string())]).default("5m").describe(`How long Magic Context assumes the provider's cached prefix stays valid. This is MC's own deferral gate — it does not change the provider's actual cache lifetime. String (e.g. "5m", "1h", "30s") or per-model object ({ default: "5m", "provider/model": "1h", "provider/*": "never" }); keys resolve most-specific first (exact provider/model, bare model ID, shorter dash-prefixes, then the provider/* wildcard, then default). User and project settings, including an explicit "5m" or object default, apply on the next pass. Only built-in defaults are frozen per session, including across restarts: when unset, GPT-5.6 and later (including gpt-6*, through any provider prefix) use 30m, other models use 5m. /ctx-status shows the effective TTL and whether it comes from your config or a frozen built-in default. Editing the TTL does not itself rewrite prompt bytes; a lowered TTL rebuilds only after normal idle expiry. OpenAI documents at least 30 minutes since the latest write or reuse: https://developers.openai.com/api/docs/guides/prompt-caching (Cache lifetime and Summary of model differences). Set to "never" to mean MC never assumes expiry (for lanes kept warm externally by a cache-keep tool) — disables the idle-TTL heuristic so MC never initiates a rebuild based on elapsed time. Provider-side extended TTL is a separate request-level concern (cache_control: { ttl } in the request body).`),
|
|
5626
5627
|
prompt_surface: PromptSurfaceConfigSchema.default({ default: "full" }).describe("Prompt-surface presets: default is full; models use bare model IDs, provider/model, or provider/* routing keys. Guidance and tool-description overrides are user-level only. OpenCode 1.x, Pi, and OMP register tool descriptions once per process (they follow the default preset). OpenCode 2 rewrites the five ctx_* descriptions per request from the draft model."),
|
|
5627
5628
|
output_reserve: union([
|
|
@@ -5641,7 +5642,11 @@ var MagicContextConfigSchema = object({
|
|
|
5641
5642
|
}).catchall(number2().min(5000).max(2000000)).optional().describe("Absolute token thresholds per model. When matched, overrides execute_threshold_percentage for that model. Accepts `default` for all models or per-model keys. Values above 90% × context_limit are clamped with a warning log. Min 5_000, max 2_000_000."),
|
|
5642
5643
|
protected_tokens: number2().int().min(PROTECTED_TOKENS_MIN).max(1e6).optional().describe("Positive integer token floor to protect from automatic reclaim (min: 4_000, max: 1_000_000). When omitted, the derived default is clamp(round(0.05 × usableSoft), min(16_000, round(0.08 × usableSoft)), 64_000)."),
|
|
5643
5644
|
protected_tags: unknown().optional().describe("Deprecated: number of recent tags to protect. Ignored for behaviour; use protected_tokens instead.").meta({ deprecated: true }),
|
|
5644
|
-
clear_reasoning_age:
|
|
5645
|
+
clear_reasoning_age: unknown().optional().describe("Deprecated and ignored. Use keep_reasoning_tokens instead.").meta({ deprecated: true }),
|
|
5646
|
+
keep_reasoning_tokens: union([
|
|
5647
|
+
number2().int().min(0).max(1e6),
|
|
5648
|
+
object({ default: number2().int().min(0).max(1e6).optional() }).catchall(number2().int().min(0).max(1e6))
|
|
5649
|
+
]).optional().describe("Reasoning tokens to keep on rebuilding passes. Number or per-model object; exact, shorter model keys, provider/*, then default. Omitted: fixed 10,000. 0 removes all eligible historical reasoning; newest and exempt steps always stay."),
|
|
5645
5650
|
history_budget_percentage: number2().min(0.05).max(0.5).default(DEFAULT_HISTORY_BUDGET_PERCENTAGE).describe("Fraction of usable context (context_limit × execute_threshold) reserved for the session history block (default: 0.15)"),
|
|
5646
5651
|
historian_timeout_ms: number2().min(60000).default(DEFAULT_HISTORIAN_TIMEOUT_MS).describe("Timeout for each historian prompt call in both TypeScript and Rust transform modes, in milliseconds (default: 600000)"),
|
|
5647
5652
|
commit_cluster_trigger: object({
|
|
@@ -5722,7 +5727,6 @@ var MagicContextConfigSchema = object({
|
|
|
5722
5727
|
});
|
|
5723
5728
|
var LIVE_RELOAD_CONFIG_PATHS = [
|
|
5724
5729
|
"cache_ttl",
|
|
5725
|
-
"mural.model",
|
|
5726
5730
|
"toast_duration_ms",
|
|
5727
5731
|
"historian.opencode.model",
|
|
5728
5732
|
"historian.opencode.fallback_models",
|
|
@@ -5793,6 +5797,125 @@ function deriveDefaultProtectedTokens(usableSoft) {
|
|
|
5793
5797
|
return Math.min(64000, Math.max(lowerBound, target));
|
|
5794
5798
|
}
|
|
5795
5799
|
|
|
5800
|
+
// src/features/magic-context/memory/embedding-model-match.ts
|
|
5801
|
+
function parseEmbeddingModel(model) {
|
|
5802
|
+
const lastColon = model.lastIndexOf(":");
|
|
5803
|
+
if (lastColon > model.lastIndexOf("/")) {
|
|
5804
|
+
return { base: model.slice(0, lastColon), tag: model.slice(lastColon + 1) };
|
|
5805
|
+
}
|
|
5806
|
+
return { base: model };
|
|
5807
|
+
}
|
|
5808
|
+
function normalizeEmbeddingModelId(model) {
|
|
5809
|
+
return parseEmbeddingModel(model.trim().toLowerCase()).base;
|
|
5810
|
+
}
|
|
5811
|
+
function matchNormalizedEmbeddingModels(a, b) {
|
|
5812
|
+
if (a.length === 0 || b.length === 0)
|
|
5813
|
+
return true;
|
|
5814
|
+
if (a === b)
|
|
5815
|
+
return true;
|
|
5816
|
+
const longer = a.length >= b.length ? a : b;
|
|
5817
|
+
const shorter = a.length >= b.length ? b : a;
|
|
5818
|
+
const isBoundary = (ch) => ch === "-" || ch === "/";
|
|
5819
|
+
if (longer.startsWith(shorter) && isBoundary(longer.charAt(shorter.length)))
|
|
5820
|
+
return true;
|
|
5821
|
+
if (longer.endsWith(shorter) && isBoundary(longer.charAt(longer.length - shorter.length - 1)))
|
|
5822
|
+
return true;
|
|
5823
|
+
return false;
|
|
5824
|
+
}
|
|
5825
|
+
function embeddingModelsMatch(served, requested) {
|
|
5826
|
+
const servedNormalized = served.trim().toLowerCase();
|
|
5827
|
+
const requestedNormalized = requested.trim().toLowerCase();
|
|
5828
|
+
const servedModel = parseEmbeddingModel(servedNormalized);
|
|
5829
|
+
const requestedModel = parseEmbeddingModel(requestedNormalized);
|
|
5830
|
+
if (servedModel.tag !== undefined && requestedModel.tag !== undefined && servedModel.tag !== requestedModel.tag) {
|
|
5831
|
+
return false;
|
|
5832
|
+
}
|
|
5833
|
+
return matchNormalizedEmbeddingModels(servedModel.base, requestedModel.base);
|
|
5834
|
+
}
|
|
5835
|
+
var QWEN3_QUERY_INSTRUCTION = `Instruct: Given a web search query, retrieve relevant passages that answer the query
|
|
5836
|
+
Query: `;
|
|
5837
|
+
var INSTRUCT_WEB_SEARCH_QUERY_PREFIX = QWEN3_QUERY_INSTRUCTION;
|
|
5838
|
+
var EMBEDDING_MODEL_PREFIX_FAMILIES = [
|
|
5839
|
+
{
|
|
5840
|
+
family: "qwen3-embedding",
|
|
5841
|
+
basenamePattern: /^qwen3-embedding(?:-|$)/,
|
|
5842
|
+
prefixes: { queryPrefix: QWEN3_QUERY_INSTRUCTION, documentPrefix: "" }
|
|
5843
|
+
},
|
|
5844
|
+
{
|
|
5845
|
+
family: "gte-qwen-instruct",
|
|
5846
|
+
basenamePattern: /^gte-qwen.*-instruct(?:-|$)/,
|
|
5847
|
+
prefixes: { queryPrefix: INSTRUCT_WEB_SEARCH_QUERY_PREFIX, documentPrefix: "" }
|
|
5848
|
+
},
|
|
5849
|
+
{
|
|
5850
|
+
family: "e5-instruct",
|
|
5851
|
+
basenamePattern: /^(?:multilingual-)?e5-.*-instruct(?:-|$)/,
|
|
5852
|
+
prefixes: { queryPrefix: INSTRUCT_WEB_SEARCH_QUERY_PREFIX, documentPrefix: "" }
|
|
5853
|
+
},
|
|
5854
|
+
{
|
|
5855
|
+
family: "nomic-embed-text",
|
|
5856
|
+
basenamePattern: /^nomic-embed-text(?:-|$)/,
|
|
5857
|
+
prefixes: { queryPrefix: "search_query: ", documentPrefix: "search_document: " }
|
|
5858
|
+
}
|
|
5859
|
+
];
|
|
5860
|
+
function modelBasename(model) {
|
|
5861
|
+
const normalized = normalizeEmbeddingModelId(model);
|
|
5862
|
+
return normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
5863
|
+
}
|
|
5864
|
+
function resolveEmbeddingTextPrefixes(model, queryInstruction, documentPrefix) {
|
|
5865
|
+
const family = EMBEDDING_MODEL_PREFIX_FAMILIES.find(({ basenamePattern }) => basenamePattern.test(modelBasename(model)));
|
|
5866
|
+
return {
|
|
5867
|
+
queryPrefix: queryInstruction === false ? "" : queryInstruction !== undefined ? queryInstruction : family?.prefixes.queryPrefix ?? "",
|
|
5868
|
+
documentPrefix: documentPrefix ?? family?.prefixes.documentPrefix ?? ""
|
|
5869
|
+
};
|
|
5870
|
+
}
|
|
5871
|
+
|
|
5872
|
+
// src/features/magic-context/memory/embedding-identity.ts
|
|
5873
|
+
function normalizeEndpoint(endpoint) {
|
|
5874
|
+
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
5875
|
+
}
|
|
5876
|
+
var LOCAL_EMBEDDING_RUNTIME_FINGERPRINT = "transformers@4.3.0;onnxruntime-node@1.30.0;onnxruntime-web@1.26.0-dev.20260416-b7804b056c";
|
|
5877
|
+
function getEmbeddingProviderIdentity(config) {
|
|
5878
|
+
if (config.provider === "off") {
|
|
5879
|
+
return "embedding-provider:off";
|
|
5880
|
+
}
|
|
5881
|
+
if (config.provider === "synapse") {
|
|
5882
|
+
const resolved = config;
|
|
5883
|
+
if (!resolved.model || !resolved.synapse_fingerprint)
|
|
5884
|
+
return "synapse:v1:pending";
|
|
5885
|
+
return getSynapseLaneIdentity(resolved.model, resolved.synapse_fingerprint);
|
|
5886
|
+
}
|
|
5887
|
+
if (config.provider !== "local" && config.provider !== "openai-compatible") {
|
|
5888
|
+
throw new Error("Unknown embedding provider");
|
|
5889
|
+
}
|
|
5890
|
+
const truncate = config.provider === "openai-compatible" ? config.truncate?.trim() : undefined;
|
|
5891
|
+
const documentPrefix = config.provider === "openai-compatible" ? resolveEmbeddingTextPrefixes(config.model, config.query_instruction, config.document_prefix).documentPrefix : "";
|
|
5892
|
+
const localDtype = config.provider === "local" && config.local_dtype && config.local_dtype !== "fp32" ? config.local_dtype : undefined;
|
|
5893
|
+
const identityInput = config.provider === "openai-compatible" ? {
|
|
5894
|
+
provider: "openai-compatible",
|
|
5895
|
+
model: config.model.trim(),
|
|
5896
|
+
endpoint: normalizeEndpoint(config.endpoint),
|
|
5897
|
+
apiKeyPresent: Boolean(config.api_key?.trim()),
|
|
5898
|
+
inputType: config.input_type?.trim() || "",
|
|
5899
|
+
...documentPrefix ? { documentPrefix } : {},
|
|
5900
|
+
...truncate ? { truncate } : {}
|
|
5901
|
+
} : {
|
|
5902
|
+
provider: "local",
|
|
5903
|
+
model: config.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
5904
|
+
endpoint: "",
|
|
5905
|
+
apiKeyPresent: false,
|
|
5906
|
+
runtimeFingerprint: LOCAL_EMBEDDING_RUNTIME_FINGERPRINT,
|
|
5907
|
+
...localDtype ? { localDtype } : {}
|
|
5908
|
+
};
|
|
5909
|
+
return `embedding-provider:${computeNormalizedHash(JSON.stringify(identityInput))}`;
|
|
5910
|
+
}
|
|
5911
|
+
|
|
5912
|
+
// src/features/magic-context/memory/embedding-local.ts
|
|
5913
|
+
import { readdirSync, statSync } from "node:fs";
|
|
5914
|
+
import { stat, unlink } from "node:fs/promises";
|
|
5915
|
+
import { dirname, join } from "node:path";
|
|
5916
|
+
import { pathToFileURL } from "node:url";
|
|
5917
|
+
import { workerData } from "node:worker_threads";
|
|
5918
|
+
|
|
5796
5919
|
// src/features/magic-context/memory/embedding-failure.ts
|
|
5797
5920
|
function errorMessage(error) {
|
|
5798
5921
|
return error instanceof Error ? error.message : String(error ?? "unknown error");
|
|
@@ -5888,2426 +6011,6 @@ function dominantEmbeddingFailure(failures) {
|
|
|
5888
6011
|
return dominant?.failure;
|
|
5889
6012
|
}
|
|
5890
6013
|
|
|
5891
|
-
// src/features/magic-context/memory/embedding-model-match.ts
|
|
5892
|
-
function parseEmbeddingModel(model) {
|
|
5893
|
-
const lastColon = model.lastIndexOf(":");
|
|
5894
|
-
if (lastColon > model.lastIndexOf("/")) {
|
|
5895
|
-
return { base: model.slice(0, lastColon), tag: model.slice(lastColon + 1) };
|
|
5896
|
-
}
|
|
5897
|
-
return { base: model };
|
|
5898
|
-
}
|
|
5899
|
-
function normalizeEmbeddingModelId(model) {
|
|
5900
|
-
return parseEmbeddingModel(model.trim().toLowerCase()).base;
|
|
5901
|
-
}
|
|
5902
|
-
function matchNormalizedEmbeddingModels(a, b) {
|
|
5903
|
-
if (a.length === 0 || b.length === 0)
|
|
5904
|
-
return true;
|
|
5905
|
-
if (a === b)
|
|
5906
|
-
return true;
|
|
5907
|
-
const longer = a.length >= b.length ? a : b;
|
|
5908
|
-
const shorter = a.length >= b.length ? b : a;
|
|
5909
|
-
const isBoundary = (ch) => ch === "-" || ch === "/";
|
|
5910
|
-
if (longer.startsWith(shorter) && isBoundary(longer.charAt(shorter.length)))
|
|
5911
|
-
return true;
|
|
5912
|
-
if (longer.endsWith(shorter) && isBoundary(longer.charAt(longer.length - shorter.length - 1)))
|
|
5913
|
-
return true;
|
|
5914
|
-
return false;
|
|
5915
|
-
}
|
|
5916
|
-
function embeddingModelsMatch(served, requested) {
|
|
5917
|
-
const servedNormalized = served.trim().toLowerCase();
|
|
5918
|
-
const requestedNormalized = requested.trim().toLowerCase();
|
|
5919
|
-
const servedModel = parseEmbeddingModel(servedNormalized);
|
|
5920
|
-
const requestedModel = parseEmbeddingModel(requestedNormalized);
|
|
5921
|
-
if (servedModel.tag !== undefined && requestedModel.tag !== undefined && servedModel.tag !== requestedModel.tag) {
|
|
5922
|
-
return false;
|
|
5923
|
-
}
|
|
5924
|
-
return matchNormalizedEmbeddingModels(servedModel.base, requestedModel.base);
|
|
5925
|
-
}
|
|
5926
|
-
var QWEN3_QUERY_INSTRUCTION = `Instruct: Given a web search query, retrieve relevant passages that answer the query
|
|
5927
|
-
Query: `;
|
|
5928
|
-
var INSTRUCT_WEB_SEARCH_QUERY_PREFIX = QWEN3_QUERY_INSTRUCTION;
|
|
5929
|
-
var EMBEDDING_MODEL_PREFIX_FAMILIES = [
|
|
5930
|
-
{
|
|
5931
|
-
family: "qwen3-embedding",
|
|
5932
|
-
basenamePattern: /^qwen3-embedding(?:-|$)/,
|
|
5933
|
-
prefixes: { queryPrefix: QWEN3_QUERY_INSTRUCTION, documentPrefix: "" }
|
|
5934
|
-
},
|
|
5935
|
-
{
|
|
5936
|
-
family: "gte-qwen-instruct",
|
|
5937
|
-
basenamePattern: /^gte-qwen.*-instruct(?:-|$)/,
|
|
5938
|
-
prefixes: { queryPrefix: INSTRUCT_WEB_SEARCH_QUERY_PREFIX, documentPrefix: "" }
|
|
5939
|
-
},
|
|
5940
|
-
{
|
|
5941
|
-
family: "e5-instruct",
|
|
5942
|
-
basenamePattern: /^(?:multilingual-)?e5-.*-instruct(?:-|$)/,
|
|
5943
|
-
prefixes: { queryPrefix: INSTRUCT_WEB_SEARCH_QUERY_PREFIX, documentPrefix: "" }
|
|
5944
|
-
},
|
|
5945
|
-
{
|
|
5946
|
-
family: "nomic-embed-text",
|
|
5947
|
-
basenamePattern: /^nomic-embed-text(?:-|$)/,
|
|
5948
|
-
prefixes: { queryPrefix: "search_query: ", documentPrefix: "search_document: " }
|
|
5949
|
-
}
|
|
5950
|
-
];
|
|
5951
|
-
function modelBasename(model) {
|
|
5952
|
-
const normalized = normalizeEmbeddingModelId(model);
|
|
5953
|
-
return normalized.slice(normalized.lastIndexOf("/") + 1);
|
|
5954
|
-
}
|
|
5955
|
-
function resolveEmbeddingTextPrefixes(model, queryInstruction, documentPrefix) {
|
|
5956
|
-
const family = EMBEDDING_MODEL_PREFIX_FAMILIES.find(({ basenamePattern }) => basenamePattern.test(modelBasename(model)));
|
|
5957
|
-
return {
|
|
5958
|
-
queryPrefix: queryInstruction === false ? "" : queryInstruction !== undefined ? queryInstruction : family?.prefixes.queryPrefix ?? "",
|
|
5959
|
-
documentPrefix: documentPrefix ?? family?.prefixes.documentPrefix ?? ""
|
|
5960
|
-
};
|
|
5961
|
-
}
|
|
5962
|
-
|
|
5963
|
-
// src/features/magic-context/memory/embedding-synapse.ts
|
|
5964
|
-
import { createHash } from "node:crypto";
|
|
5965
|
-
|
|
5966
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.11.1/node_modules/@cortexkit/subc-client/dist/client.js
|
|
5967
|
-
import { promises as fs2 } from "node:fs";
|
|
5968
|
-
import { debuglog } from "node:util";
|
|
5969
|
-
|
|
5970
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.11.1/node_modules/@cortexkit/subc-client/dist/auth.js
|
|
5971
|
-
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
5972
|
-
|
|
5973
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.11.1/node_modules/@cortexkit/subc-client/dist/socket.js
|
|
5974
|
-
import net from "node:net";
|
|
5975
|
-
|
|
5976
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.11.1/node_modules/@cortexkit/subc-client/dist/envelope.js
|
|
5977
|
-
var PROTOCOL_VERSION = 2;
|
|
5978
|
-
var HEADER_LEN = 21;
|
|
5979
|
-
var FROZEN_PREFIX_LEN = 5;
|
|
5980
|
-
var MAX_FRAME_BODY_LEN = 64 * 1024 * 1024;
|
|
5981
|
-
var FrameType;
|
|
5982
|
-
(function(FrameType) {
|
|
5983
|
-
FrameType[FrameType["Request"] = 0] = "Request";
|
|
5984
|
-
FrameType[FrameType["Response"] = 1] = "Response";
|
|
5985
|
-
FrameType[FrameType["Push"] = 2] = "Push";
|
|
5986
|
-
FrameType[FrameType["StreamData"] = 3] = "StreamData";
|
|
5987
|
-
FrameType[FrameType["StreamEnd"] = 4] = "StreamEnd";
|
|
5988
|
-
FrameType[FrameType["Error"] = 5] = "Error";
|
|
5989
|
-
FrameType[FrameType["Cancel"] = 6] = "Cancel";
|
|
5990
|
-
FrameType[FrameType["Ping"] = 7] = "Ping";
|
|
5991
|
-
FrameType[FrameType["Pong"] = 8] = "Pong";
|
|
5992
|
-
FrameType[FrameType["Hello"] = 9] = "Hello";
|
|
5993
|
-
FrameType[FrameType["HelloAck"] = 10] = "HelloAck";
|
|
5994
|
-
FrameType[FrameType["Goodbye"] = 11] = "Goodbye";
|
|
5995
|
-
})(FrameType || (FrameType = {}));
|
|
5996
|
-
var FRAME_TYPE_MAX = FrameType.Goodbye;
|
|
5997
|
-
function isPureHeader(ty) {
|
|
5998
|
-
return ty === FrameType.Cancel || ty === FrameType.Ping || ty === FrameType.Pong || ty === FrameType.Goodbye;
|
|
5999
|
-
}
|
|
6000
|
-
var Priority;
|
|
6001
|
-
(function(Priority) {
|
|
6002
|
-
Priority[Priority["Passive"] = 0] = "Passive";
|
|
6003
|
-
Priority[Priority["Interactive"] = 1] = "Interactive";
|
|
6004
|
-
Priority[Priority["Background"] = 2] = "Background";
|
|
6005
|
-
})(Priority || (Priority = {}));
|
|
6006
|
-
var AdmissionClass;
|
|
6007
|
-
(function(AdmissionClass) {
|
|
6008
|
-
AdmissionClass[AdmissionClass["Normal"] = 0] = "Normal";
|
|
6009
|
-
AdmissionClass[AdmissionClass["Expedite"] = 1] = "Expedite";
|
|
6010
|
-
AdmissionClass[AdmissionClass["Sheddable"] = 2] = "Sheddable";
|
|
6011
|
-
})(AdmissionClass || (AdmissionClass = {}));
|
|
6012
|
-
var FLAG_BINARY = 1;
|
|
6013
|
-
var FLAG_PRIORITY_MASK = 6;
|
|
6014
|
-
var FLAG_PRIORITY_SHIFT = 1;
|
|
6015
|
-
var FLAG_LAST = 8;
|
|
6016
|
-
var FLAG_ADMISSION_MASK = 48;
|
|
6017
|
-
var FLAG_ADMISSION_SHIFT = 4;
|
|
6018
|
-
var FLAG_RESERVED_MASK = 128;
|
|
6019
|
-
function buildFlags(binary, priority, last, admissionClass = AdmissionClass.Normal) {
|
|
6020
|
-
let flags = 0;
|
|
6021
|
-
if (binary)
|
|
6022
|
-
flags |= FLAG_BINARY;
|
|
6023
|
-
flags |= priority << FLAG_PRIORITY_SHIFT;
|
|
6024
|
-
if (last)
|
|
6025
|
-
flags |= FLAG_LAST;
|
|
6026
|
-
flags |= admissionClass << FLAG_ADMISSION_SHIFT;
|
|
6027
|
-
return flags;
|
|
6028
|
-
}
|
|
6029
|
-
function hasBinary(flags) {
|
|
6030
|
-
return (flags & FLAG_BINARY) !== 0;
|
|
6031
|
-
}
|
|
6032
|
-
function encodeHeader(header) {
|
|
6033
|
-
const buffer = new Uint8Array(HEADER_LEN);
|
|
6034
|
-
const view = new DataView(buffer.buffer);
|
|
6035
|
-
view.setUint32(0, header.len, true);
|
|
6036
|
-
buffer[4] = header.ver;
|
|
6037
|
-
buffer[5] = header.ty;
|
|
6038
|
-
buffer[6] = header.flags;
|
|
6039
|
-
view.setUint16(7, header.channel, true);
|
|
6040
|
-
view.setUint32(9, header.epoch, true);
|
|
6041
|
-
view.setBigUint64(13, header.corr, true);
|
|
6042
|
-
return buffer;
|
|
6043
|
-
}
|
|
6044
|
-
|
|
6045
|
-
class DecodeError extends Error {
|
|
6046
|
-
code;
|
|
6047
|
-
constructor(message, code) {
|
|
6048
|
-
super(message);
|
|
6049
|
-
this.code = code;
|
|
6050
|
-
this.name = "DecodeError";
|
|
6051
|
-
}
|
|
6052
|
-
}
|
|
6053
|
-
function validateHeaderFields(header) {
|
|
6054
|
-
const len = header.len >>> 0;
|
|
6055
|
-
const ver = header.ver >>> 0 & 255;
|
|
6056
|
-
const typeByte = header.ty >>> 0 & 255;
|
|
6057
|
-
const flags = header.flags >>> 0 & 255;
|
|
6058
|
-
const channel = header.channel >>> 0 & 65535;
|
|
6059
|
-
const epoch = header.epoch >>> 0;
|
|
6060
|
-
BigInt.asUintN(64, header.corr);
|
|
6061
|
-
if (ver !== PROTOCOL_VERSION)
|
|
6062
|
-
throw new DecodeError(`unsupported envelope version ${ver}`, "unsupported_version");
|
|
6063
|
-
if (typeByte > FRAME_TYPE_MAX)
|
|
6064
|
-
throw new DecodeError(`unknown frame type byte ${typeByte}`, "unknown_frame_type");
|
|
6065
|
-
const ty = typeByte;
|
|
6066
|
-
if ((flags & FLAG_RESERVED_MASK) !== 0) {
|
|
6067
|
-
throw new DecodeError(`reserved flag bits set in flags 0b${flags.toString(2).padStart(8, "0")}`, "reserved_flag_bits");
|
|
6068
|
-
}
|
|
6069
|
-
if ((flags & FLAG_PRIORITY_MASK) >> FLAG_PRIORITY_SHIFT === 3) {
|
|
6070
|
-
throw new DecodeError(`reserved priority bits set in flags 0b${flags.toString(2).padStart(8, "0")}`, "reserved_priority_bits");
|
|
6071
|
-
}
|
|
6072
|
-
const admission = (flags & FLAG_ADMISSION_MASK) >> FLAG_ADMISSION_SHIFT;
|
|
6073
|
-
if (admission === 3) {
|
|
6074
|
-
throw new DecodeError(`reserved admission class set in flags 0b${flags.toString(2).padStart(8, "0")}`, "reserved_admission_class");
|
|
6075
|
-
}
|
|
6076
|
-
if (admission === AdmissionClass.Sheddable && ty !== FrameType.Push && ty !== FrameType.StreamData) {
|
|
6077
|
-
throw new DecodeError(`SHEDDABLE admission class is illegal on ${FrameType[ty]} in flags 0b${flags.toString(2).padStart(8, "0")}`, "sheddable_illegal_frame_type");
|
|
6078
|
-
}
|
|
6079
|
-
if (channel === 0 && epoch !== 0) {
|
|
6080
|
-
throw new DecodeError(`control channel carried nonzero epoch ${epoch}`, "nonzero_epoch_on_control_channel");
|
|
6081
|
-
}
|
|
6082
|
-
if (isPureHeader(ty) && len !== 0) {
|
|
6083
|
-
throw new DecodeError(`pure-header frame ${FrameType[ty]} declared non-zero body length ${len}`, "pure_header_frame_with_body");
|
|
6084
|
-
}
|
|
6085
|
-
}
|
|
6086
|
-
function decodeHeader(bytes) {
|
|
6087
|
-
if (bytes.length < FROZEN_PREFIX_LEN) {
|
|
6088
|
-
throw new DecodeError(`header shorter than frozen prefix: have ${bytes.length} bytes`, "too_short_for_prefix");
|
|
6089
|
-
}
|
|
6090
|
-
const ver = bytes[4];
|
|
6091
|
-
if (ver !== PROTOCOL_VERSION)
|
|
6092
|
-
throw new DecodeError(`unsupported envelope version ${ver}`, "unsupported_version");
|
|
6093
|
-
if (bytes.length < HEADER_LEN) {
|
|
6094
|
-
throw new DecodeError(`header too short for version: have ${bytes.length} bytes, need ${HEADER_LEN}`, "too_short_for_header");
|
|
6095
|
-
}
|
|
6096
|
-
const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
6097
|
-
const len = view.getUint32(0, true);
|
|
6098
|
-
const typeByte = bytes[5];
|
|
6099
|
-
if (typeByte > FRAME_TYPE_MAX)
|
|
6100
|
-
throw new DecodeError(`unknown frame type byte ${typeByte}`, "unknown_frame_type");
|
|
6101
|
-
const ty = typeByte;
|
|
6102
|
-
const flags = bytes[6];
|
|
6103
|
-
if ((flags & FLAG_RESERVED_MASK) !== 0) {
|
|
6104
|
-
throw new DecodeError(`reserved flag bits set in flags 0b${flags.toString(2).padStart(8, "0")}`, "reserved_flag_bits");
|
|
6105
|
-
}
|
|
6106
|
-
if ((flags & FLAG_PRIORITY_MASK) >> FLAG_PRIORITY_SHIFT === 3) {
|
|
6107
|
-
throw new DecodeError(`reserved priority bits set in flags 0b${flags.toString(2).padStart(8, "0")}`, "reserved_priority_bits");
|
|
6108
|
-
}
|
|
6109
|
-
const admission = (flags & FLAG_ADMISSION_MASK) >> FLAG_ADMISSION_SHIFT;
|
|
6110
|
-
if (admission === 3) {
|
|
6111
|
-
throw new DecodeError(`reserved admission class set in flags 0b${flags.toString(2).padStart(8, "0")}`, "reserved_admission_class");
|
|
6112
|
-
}
|
|
6113
|
-
if (admission === AdmissionClass.Sheddable && ty !== FrameType.Push && ty !== FrameType.StreamData) {
|
|
6114
|
-
throw new DecodeError(`SHEDDABLE admission class is illegal on ${FrameType[ty]} in flags 0b${flags.toString(2).padStart(8, "0")}`, "sheddable_illegal_frame_type");
|
|
6115
|
-
}
|
|
6116
|
-
const channel = view.getUint16(7, true);
|
|
6117
|
-
const epoch = view.getUint32(9, true);
|
|
6118
|
-
if (channel === 0 && epoch !== 0) {
|
|
6119
|
-
throw new DecodeError(`control channel carried nonzero epoch ${epoch}`, "nonzero_epoch_on_control_channel");
|
|
6120
|
-
}
|
|
6121
|
-
if (isPureHeader(ty) && len !== 0) {
|
|
6122
|
-
throw new DecodeError(`pure-header frame ${FrameType[ty]} declared non-zero body length ${len}`, "pure_header_frame_with_body");
|
|
6123
|
-
}
|
|
6124
|
-
return { len, ver, ty, flags, channel, epoch, corr: view.getBigUint64(13, true) };
|
|
6125
|
-
}
|
|
6126
|
-
function buildFrame(ty, flags, channel, epoch, corr, body) {
|
|
6127
|
-
return buildFrameWithVersion(PROTOCOL_VERSION, ty, flags, channel, epoch, corr, body);
|
|
6128
|
-
}
|
|
6129
|
-
function buildFrameWithVersion(ver, ty, flags, channel, epoch, corr, body) {
|
|
6130
|
-
if (body.length > MAX_FRAME_BODY_LEN) {
|
|
6131
|
-
throw new DecodeError(`frame body ${body.length} exceeds max ${MAX_FRAME_BODY_LEN}`, "frame_body_too_large");
|
|
6132
|
-
}
|
|
6133
|
-
const header = { len: body.length, ver, ty, flags, channel, epoch, corr };
|
|
6134
|
-
validateHeaderFields(header);
|
|
6135
|
-
return { header, body };
|
|
6136
|
-
}
|
|
6137
|
-
function encodeFrame(frame) {
|
|
6138
|
-
if (frame.header.len !== frame.body.length) {
|
|
6139
|
-
throw new DecodeError(`frame header length ${frame.header.len} does not match body length ${frame.body.length}`, "frame_length_mismatch");
|
|
6140
|
-
}
|
|
6141
|
-
const header = encodeHeader(frame.header);
|
|
6142
|
-
const output = new Uint8Array(header.length + frame.body.length);
|
|
6143
|
-
output.set(header, 0);
|
|
6144
|
-
output.set(frame.body, header.length);
|
|
6145
|
-
return output;
|
|
6146
|
-
}
|
|
6147
|
-
|
|
6148
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.11.1/node_modules/@cortexkit/subc-client/dist/socket.js
|
|
6149
|
-
class SocketClosedError extends Error {
|
|
6150
|
-
}
|
|
6151
|
-
|
|
6152
|
-
class SocketTimeoutError extends Error {
|
|
6153
|
-
}
|
|
6154
|
-
|
|
6155
|
-
class SocketWriteNotQueuedError extends Error {
|
|
6156
|
-
cause;
|
|
6157
|
-
constructor(message, cause) {
|
|
6158
|
-
super(message);
|
|
6159
|
-
this.cause = cause;
|
|
6160
|
-
}
|
|
6161
|
-
}
|
|
6162
|
-
|
|
6163
|
-
class SocketWriteQueuedError extends Error {
|
|
6164
|
-
cause;
|
|
6165
|
-
constructor(message, cause) {
|
|
6166
|
-
super(message);
|
|
6167
|
-
this.cause = cause;
|
|
6168
|
-
}
|
|
6169
|
-
}
|
|
6170
|
-
function toWriteBuffer(bytes) {
|
|
6171
|
-
return Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
6172
|
-
}
|
|
6173
|
-
var WRITE_BORROWED = Symbol("subc.socket.writeBorrowed");
|
|
6174
|
-
var WRITE_TRACKED_BORROWED = Symbol("subc.socket.writeTrackedBorrowed");
|
|
6175
|
-
function writeBorrowed(socket, bytes, deadlineMs) {
|
|
6176
|
-
const borrowed = socket[WRITE_BORROWED];
|
|
6177
|
-
return borrowed ? borrowed.call(socket, bytes, deadlineMs) : socket.write(bytes, deadlineMs);
|
|
6178
|
-
}
|
|
6179
|
-
function writeTrackedBorrowed(socket, bytes, deadlineMs) {
|
|
6180
|
-
const borrowed = socket[WRITE_TRACKED_BORROWED];
|
|
6181
|
-
return borrowed ? borrowed.call(socket, bytes, deadlineMs) : socket.writeTracked(bytes, deadlineMs);
|
|
6182
|
-
}
|
|
6183
|
-
|
|
6184
|
-
class SubcSocket {
|
|
6185
|
-
sock;
|
|
6186
|
-
chunks = [];
|
|
6187
|
-
buffered = 0;
|
|
6188
|
-
waiter = null;
|
|
6189
|
-
closedErr = null;
|
|
6190
|
-
bufferedBytes() {
|
|
6191
|
-
return this.buffered;
|
|
6192
|
-
}
|
|
6193
|
-
constructor(sock) {
|
|
6194
|
-
this.sock = sock;
|
|
6195
|
-
sock.on("data", (chunk) => {
|
|
6196
|
-
this.chunks.push(chunk);
|
|
6197
|
-
this.buffered += chunk.length;
|
|
6198
|
-
this.tryServe();
|
|
6199
|
-
});
|
|
6200
|
-
const fail = (err) => {
|
|
6201
|
-
if (!this.closedErr)
|
|
6202
|
-
this.closedErr = err;
|
|
6203
|
-
this.tryServe();
|
|
6204
|
-
};
|
|
6205
|
-
sock.on("error", (err) => fail(err instanceof Error ? err : new Error(String(err))));
|
|
6206
|
-
sock.on("end", () => fail(new SocketClosedError("subc closed the connection")));
|
|
6207
|
-
sock.on("close", () => fail(new SocketClosedError("subc connection closed")));
|
|
6208
|
-
}
|
|
6209
|
-
localPort() {
|
|
6210
|
-
return this.sock.localPort ?? null;
|
|
6211
|
-
}
|
|
6212
|
-
static connect(host, port, deadlineMs) {
|
|
6213
|
-
return new Promise((resolve, reject) => {
|
|
6214
|
-
const sock = net.connect({ host, port });
|
|
6215
|
-
sock.setNoDelay(true);
|
|
6216
|
-
const timer = setTimeout(() => {
|
|
6217
|
-
sock.destroy();
|
|
6218
|
-
reject(new SocketTimeoutError(`timed out connecting to ${host}:${port}`));
|
|
6219
|
-
}, Math.max(0, deadlineMs - Date.now()));
|
|
6220
|
-
sock.once("connect", () => {
|
|
6221
|
-
clearTimeout(timer);
|
|
6222
|
-
resolve(new SubcSocket(sock));
|
|
6223
|
-
});
|
|
6224
|
-
sock.once("error", (err) => {
|
|
6225
|
-
clearTimeout(timer);
|
|
6226
|
-
reject(err);
|
|
6227
|
-
});
|
|
6228
|
-
});
|
|
6229
|
-
}
|
|
6230
|
-
async readFrame(headerDeadlineMs, bodyDeadline, onHeader) {
|
|
6231
|
-
const prefix = await this.readExact(FROZEN_PREFIX_LEN, headerDeadlineMs);
|
|
6232
|
-
const version = prefix[4];
|
|
6233
|
-
if (version !== PROTOCOL_VERSION)
|
|
6234
|
-
throw new DecodeError(`unsupported envelope version ${version}`, "unsupported_version");
|
|
6235
|
-
const remainder = await this.readExact(HEADER_LEN - FROZEN_PREFIX_LEN, headerDeadlineMs);
|
|
6236
|
-
const headerBytes = new Uint8Array(HEADER_LEN);
|
|
6237
|
-
headerBytes.set(prefix);
|
|
6238
|
-
headerBytes.set(remainder, FROZEN_PREFIX_LEN);
|
|
6239
|
-
const header = decodeHeader(headerBytes);
|
|
6240
|
-
if (header.len > MAX_FRAME_BODY_LEN) {
|
|
6241
|
-
throw new DecodeError(`frame body ${header.len} exceeds max ${MAX_FRAME_BODY_LEN}`, "frame_body_too_large");
|
|
6242
|
-
}
|
|
6243
|
-
onHeader?.();
|
|
6244
|
-
const bodyDeadlineMs = typeof bodyDeadline === "number" ? bodyDeadline : Date.now() + bodyDeadline.afterHeaderMs;
|
|
6245
|
-
const body = header.len === 0 ? new Uint8Array(0) : await this.readExact(header.len, bodyDeadlineMs);
|
|
6246
|
-
return { header, body };
|
|
6247
|
-
}
|
|
6248
|
-
readExact(n, deadlineMs) {
|
|
6249
|
-
if (this.waiter) {
|
|
6250
|
-
return Promise.reject(new Error("concurrent readExact is not supported"));
|
|
6251
|
-
}
|
|
6252
|
-
if (n === 0)
|
|
6253
|
-
return Promise.resolve(new Uint8Array(0));
|
|
6254
|
-
return new Promise((resolve, reject) => {
|
|
6255
|
-
let timer = null;
|
|
6256
|
-
if (Number.isFinite(deadlineMs)) {
|
|
6257
|
-
const remaining = deadlineMs - Date.now();
|
|
6258
|
-
if (remaining <= 0) {
|
|
6259
|
-
reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
|
|
6260
|
-
return;
|
|
6261
|
-
}
|
|
6262
|
-
timer = setTimeout(() => {
|
|
6263
|
-
this.waiter = null;
|
|
6264
|
-
reject(new SocketTimeoutError(`timed out waiting for ${n} bytes`));
|
|
6265
|
-
}, remaining);
|
|
6266
|
-
}
|
|
6267
|
-
this.waiter = { need: n, resolve, reject, timer };
|
|
6268
|
-
this.tryServe();
|
|
6269
|
-
});
|
|
6270
|
-
}
|
|
6271
|
-
async write(bytes, deadlineMs) {
|
|
6272
|
-
await this.writeBuffer(Buffer.from(bytes), deadlineMs);
|
|
6273
|
-
}
|
|
6274
|
-
writeTracked(bytes, deadlineMs) {
|
|
6275
|
-
return this.writeTrackedBuffer(Buffer.from(bytes), deadlineMs);
|
|
6276
|
-
}
|
|
6277
|
-
async[WRITE_BORROWED](bytes, deadlineMs) {
|
|
6278
|
-
await this.writeBuffer(toWriteBuffer(bytes), deadlineMs);
|
|
6279
|
-
}
|
|
6280
|
-
[WRITE_TRACKED_BORROWED](bytes, deadlineMs) {
|
|
6281
|
-
return this.writeTrackedBuffer(toWriteBuffer(bytes), deadlineMs);
|
|
6282
|
-
}
|
|
6283
|
-
async writeBuffer(buffer, deadlineMs) {
|
|
6284
|
-
try {
|
|
6285
|
-
await this.writeTrackedBuffer(buffer, deadlineMs).completed;
|
|
6286
|
-
} catch (err) {
|
|
6287
|
-
if (err instanceof SocketWriteNotQueuedError || err instanceof SocketWriteQueuedError) {
|
|
6288
|
-
throw err.cause ?? err;
|
|
6289
|
-
}
|
|
6290
|
-
throw err;
|
|
6291
|
-
}
|
|
6292
|
-
}
|
|
6293
|
-
writeTrackedBuffer(buffer, deadlineMs) {
|
|
6294
|
-
if (this.closedErr) {
|
|
6295
|
-
return {
|
|
6296
|
-
queued: false,
|
|
6297
|
-
completed: Promise.reject(new SocketWriteNotQueuedError("subc socket was closed before bytes could be queued", this.closedErr))
|
|
6298
|
-
};
|
|
6299
|
-
}
|
|
6300
|
-
let queued = false;
|
|
6301
|
-
let settled = false;
|
|
6302
|
-
let timer = null;
|
|
6303
|
-
const completed = new Promise((resolve, reject) => {
|
|
6304
|
-
const settle = (run) => {
|
|
6305
|
-
if (settled)
|
|
6306
|
-
return;
|
|
6307
|
-
settled = true;
|
|
6308
|
-
if (timer)
|
|
6309
|
-
clearTimeout(timer);
|
|
6310
|
-
run();
|
|
6311
|
-
};
|
|
6312
|
-
const remaining = deadlineMs - Date.now();
|
|
6313
|
-
if (remaining <= 0) {
|
|
6314
|
-
settle(() => reject(new SocketWriteNotQueuedError("timed out before bytes could be queued to subc", new SocketTimeoutError("timed out writing to subc"))));
|
|
6315
|
-
return;
|
|
6316
|
-
}
|
|
6317
|
-
timer = setTimeout(() => {
|
|
6318
|
-
const timeout = new SocketTimeoutError("timed out writing to subc");
|
|
6319
|
-
settle(() => reject(queued ? new SocketWriteQueuedError("timed out after bytes were handed to the subc socket", timeout) : new SocketWriteNotQueuedError("timed out before bytes could be queued to subc", timeout)));
|
|
6320
|
-
}, remaining);
|
|
6321
|
-
try {
|
|
6322
|
-
this.sock.write(buffer, (err) => {
|
|
6323
|
-
settle(() => {
|
|
6324
|
-
if (err) {
|
|
6325
|
-
reject(new SocketWriteQueuedError("subc socket reported a write error after bytes were handed to the socket", err instanceof Error ? err : new Error(String(err))));
|
|
6326
|
-
} else {
|
|
6327
|
-
resolve();
|
|
6328
|
-
}
|
|
6329
|
-
});
|
|
6330
|
-
});
|
|
6331
|
-
queued = true;
|
|
6332
|
-
} catch (err) {
|
|
6333
|
-
settle(() => reject(new SocketWriteNotQueuedError("subc socket write threw before bytes could be queued", err instanceof Error ? err : new Error(String(err)))));
|
|
6334
|
-
}
|
|
6335
|
-
});
|
|
6336
|
-
return { queued, completed };
|
|
6337
|
-
}
|
|
6338
|
-
close() {
|
|
6339
|
-
this.sock.destroy();
|
|
6340
|
-
}
|
|
6341
|
-
tryServe() {
|
|
6342
|
-
const w = this.waiter;
|
|
6343
|
-
if (!w)
|
|
6344
|
-
return;
|
|
6345
|
-
if (this.buffered >= w.need) {
|
|
6346
|
-
const out = this.take(w.need);
|
|
6347
|
-
this.waiter = null;
|
|
6348
|
-
if (w.timer)
|
|
6349
|
-
clearTimeout(w.timer);
|
|
6350
|
-
w.resolve(out);
|
|
6351
|
-
return;
|
|
6352
|
-
}
|
|
6353
|
-
if (this.closedErr) {
|
|
6354
|
-
this.waiter = null;
|
|
6355
|
-
if (w.timer)
|
|
6356
|
-
clearTimeout(w.timer);
|
|
6357
|
-
w.reject(this.closedErr);
|
|
6358
|
-
}
|
|
6359
|
-
}
|
|
6360
|
-
take(n) {
|
|
6361
|
-
const out = Buffer.allocUnsafe(n);
|
|
6362
|
-
let off = 0;
|
|
6363
|
-
while (off < n) {
|
|
6364
|
-
const head = this.chunks[0];
|
|
6365
|
-
const want = n - off;
|
|
6366
|
-
if (head.length <= want) {
|
|
6367
|
-
head.copy(out, off);
|
|
6368
|
-
off += head.length;
|
|
6369
|
-
this.chunks.shift();
|
|
6370
|
-
} else {
|
|
6371
|
-
head.copy(out, off, 0, want);
|
|
6372
|
-
this.chunks[0] = head.subarray(want);
|
|
6373
|
-
off += want;
|
|
6374
|
-
}
|
|
6375
|
-
}
|
|
6376
|
-
this.buffered -= n;
|
|
6377
|
-
return out;
|
|
6378
|
-
}
|
|
6379
|
-
}
|
|
6380
|
-
|
|
6381
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.11.1/node_modules/@cortexkit/subc-client/dist/auth.js
|
|
6382
|
-
var NONCE_LEN = 32;
|
|
6383
|
-
var MAX_AUTH_MESSAGE_LEN = 4096;
|
|
6384
|
-
var SERVER_PROOF_DOMAIN = "subc-server-v1";
|
|
6385
|
-
var CLIENT_AUTH_DOMAIN = "subc-client-v1";
|
|
6386
|
-
var DEFAULT_CLIENT_ROLE = "client";
|
|
6387
|
-
|
|
6388
|
-
class AuthError extends Error {
|
|
6389
|
-
}
|
|
6390
|
-
function computeProof(key, domain, clientNonce, serverNonce, daemonId) {
|
|
6391
|
-
const mac = createHmac("sha256", Buffer.from(key));
|
|
6392
|
-
mac.update(Buffer.from(domain, "utf8"));
|
|
6393
|
-
mac.update(Buffer.from(clientNonce));
|
|
6394
|
-
mac.update(Buffer.from(serverNonce));
|
|
6395
|
-
mac.update(Buffer.from(daemonId));
|
|
6396
|
-
return new Uint8Array(mac.digest());
|
|
6397
|
-
}
|
|
6398
|
-
function constantTimeEq(a, b) {
|
|
6399
|
-
if (a.length !== b.length)
|
|
6400
|
-
return false;
|
|
6401
|
-
return timingSafeEqual(Buffer.from(a), Buffer.from(b));
|
|
6402
|
-
}
|
|
6403
|
-
async function writeMessage(sock, value, deadlineMs) {
|
|
6404
|
-
const json = Buffer.from(JSON.stringify(value), "utf8");
|
|
6405
|
-
if (json.length > MAX_AUTH_MESSAGE_LEN) {
|
|
6406
|
-
throw new AuthError(`auth message too large: ${json.length} > ${MAX_AUTH_MESSAGE_LEN}`);
|
|
6407
|
-
}
|
|
6408
|
-
const lenPrefix = new Uint8Array(4);
|
|
6409
|
-
new DataView(lenPrefix.buffer).setUint32(0, json.length, true);
|
|
6410
|
-
await writeBorrowed(sock, lenPrefix, deadlineMs);
|
|
6411
|
-
await writeBorrowed(sock, json, deadlineMs);
|
|
6412
|
-
}
|
|
6413
|
-
async function readMessage(sock, deadlineMs) {
|
|
6414
|
-
const lenBytes = await sock.readExact(4, deadlineMs);
|
|
6415
|
-
const len = new DataView(lenBytes.buffer, lenBytes.byteOffset, 4).getUint32(0, true);
|
|
6416
|
-
if (len > MAX_AUTH_MESSAGE_LEN) {
|
|
6417
|
-
throw new AuthError(`auth message too large: ${len} > ${MAX_AUTH_MESSAGE_LEN}`);
|
|
6418
|
-
}
|
|
6419
|
-
const body = len === 0 ? new Uint8Array(0) : await sock.readExact(len, deadlineMs);
|
|
6420
|
-
try {
|
|
6421
|
-
return JSON.parse(Buffer.from(body).toString("utf8"));
|
|
6422
|
-
} catch (err) {
|
|
6423
|
-
throw new AuthError(`auth message JSON decode failed: ${String(err)}`);
|
|
6424
|
-
}
|
|
6425
|
-
}
|
|
6426
|
-
function authBytes(value, field) {
|
|
6427
|
-
if (!Array.isArray(value)) {
|
|
6428
|
-
throw new AuthError(`auth field '${field}' must be a byte array`);
|
|
6429
|
-
}
|
|
6430
|
-
for (const byte of value) {
|
|
6431
|
-
if (typeof byte !== "number" || !Number.isInteger(byte) || byte < 0 || byte > 255) {
|
|
6432
|
-
throw new AuthError(`auth field '${field}' has invalid byte ${String(byte)}`);
|
|
6433
|
-
}
|
|
6434
|
-
}
|
|
6435
|
-
return Uint8Array.from(value);
|
|
6436
|
-
}
|
|
6437
|
-
async function authenticateClient(sock, conn, deadlineMs) {
|
|
6438
|
-
const clientNonce = new Uint8Array(randomBytes(NONCE_LEN));
|
|
6439
|
-
await writeMessage(sock, { client_nonce: Array.from(clientNonce), role: DEFAULT_CLIENT_ROLE }, deadlineMs);
|
|
6440
|
-
const proof = await readMessage(sock, deadlineMs);
|
|
6441
|
-
const serverNonce = authBytes(proof.server_nonce, "server_nonce");
|
|
6442
|
-
const daemonId = authBytes(proof.daemon_id, "daemon_id");
|
|
6443
|
-
const serverProof = authBytes(proof.server_proof, "server_proof");
|
|
6444
|
-
const expected = computeProof(conn.key, SERVER_PROOF_DOMAIN, clientNonce, serverNonce, daemonId);
|
|
6445
|
-
if (!constantTimeEq(expected, serverProof)) {
|
|
6446
|
-
throw new AuthError("server proof mismatch — wrong key or impostor daemon");
|
|
6447
|
-
}
|
|
6448
|
-
if (!constantTimeEq(daemonId, conn.daemonId)) {
|
|
6449
|
-
throw new AuthError("daemon id mismatch — connection file points at a different daemon");
|
|
6450
|
-
}
|
|
6451
|
-
const clientAuth = computeProof(conn.key, CLIENT_AUTH_DOMAIN, clientNonce, serverNonce, daemonId);
|
|
6452
|
-
await writeMessage(sock, { client_auth: Array.from(clientAuth) }, deadlineMs);
|
|
6453
|
-
}
|
|
6454
|
-
|
|
6455
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.11.1/node_modules/@cortexkit/subc-client/dist/connection-file.js
|
|
6456
|
-
import { promises as fs } from "node:fs";
|
|
6457
|
-
var SCHEMA_VERSION = 1;
|
|
6458
|
-
var MIN_KEY_LEN = 32;
|
|
6459
|
-
var DAEMON_ID_LEN = 16;
|
|
6460
|
-
|
|
6461
|
-
class ConnectionFileError extends Error {
|
|
6462
|
-
}
|
|
6463
|
-
function toBytes(value, field) {
|
|
6464
|
-
if (!Array.isArray(value)) {
|
|
6465
|
-
throw new ConnectionFileError(`connection file field '${field}' must be a JSON array of bytes`);
|
|
6466
|
-
}
|
|
6467
|
-
for (const byte of value) {
|
|
6468
|
-
if (typeof byte !== "number" || !Number.isInteger(byte) || byte < 0 || byte > 255) {
|
|
6469
|
-
throw new ConnectionFileError(`connection file field '${field}' has invalid byte ${String(byte)}`);
|
|
6470
|
-
}
|
|
6471
|
-
}
|
|
6472
|
-
return Uint8Array.from(value);
|
|
6473
|
-
}
|
|
6474
|
-
function validate(info) {
|
|
6475
|
-
if (info.schema !== SCHEMA_VERSION) {
|
|
6476
|
-
throw new ConnectionFileError(`unsupported connection file schema ${info.schema}; expected ${SCHEMA_VERSION}`);
|
|
6477
|
-
}
|
|
6478
|
-
if (info.endpoints.length === 0) {
|
|
6479
|
-
throw new ConnectionFileError("connection file must include at least one endpoint");
|
|
6480
|
-
}
|
|
6481
|
-
if (info.key.length < MIN_KEY_LEN) {
|
|
6482
|
-
throw new ConnectionFileError(`connection file key is too short: ${info.key.length} bytes, need at least ${MIN_KEY_LEN}`);
|
|
6483
|
-
}
|
|
6484
|
-
if (info.daemonId.length !== DAEMON_ID_LEN) {
|
|
6485
|
-
throw new ConnectionFileError(`connection file daemon_id must be ${DAEMON_ID_LEN} bytes, got ${info.daemonId.length}`);
|
|
6486
|
-
}
|
|
6487
|
-
}
|
|
6488
|
-
async function verifyOwnerOnly(path) {
|
|
6489
|
-
if (process.platform === "win32")
|
|
6490
|
-
return;
|
|
6491
|
-
const stat = await fs.stat(path);
|
|
6492
|
-
const mode = stat.mode & 511;
|
|
6493
|
-
if ((mode & 63) !== 0) {
|
|
6494
|
-
throw new ConnectionFileError(`connection file ${path} has insecure permissions 0o${mode.toString(8)}; expected owner-only 0600`);
|
|
6495
|
-
}
|
|
6496
|
-
}
|
|
6497
|
-
async function readConnectionFile(path) {
|
|
6498
|
-
await verifyOwnerOnly(path);
|
|
6499
|
-
const raw = await fs.readFile(path, "utf8");
|
|
6500
|
-
let parsed;
|
|
6501
|
-
try {
|
|
6502
|
-
parsed = JSON.parse(raw);
|
|
6503
|
-
} catch (err) {
|
|
6504
|
-
throw new ConnectionFileError(`connection file JSON read failed for ${path}: ${String(err)}`);
|
|
6505
|
-
}
|
|
6506
|
-
const wireVersion = parsed.wire_version;
|
|
6507
|
-
if (wireVersion !== undefined && wireVersion !== PROTOCOL_VERSION) {
|
|
6508
|
-
throw new ConnectionFileError(`connection file wire_version ${String(wireVersion)} but this client speaks ${PROTOCOL_VERSION}; the client library must be upgraded`);
|
|
6509
|
-
}
|
|
6510
|
-
const endpointsRaw = parsed.endpoints;
|
|
6511
|
-
if (!Array.isArray(endpointsRaw)) {
|
|
6512
|
-
throw new ConnectionFileError("connection file 'endpoints' must be an array");
|
|
6513
|
-
}
|
|
6514
|
-
const endpoints = endpointsRaw.map((e) => {
|
|
6515
|
-
const ep = e;
|
|
6516
|
-
if (typeof ep.host !== "string" || typeof ep.port !== "number") {
|
|
6517
|
-
throw new ConnectionFileError("connection file endpoint must be { host: string, port: number }");
|
|
6518
|
-
}
|
|
6519
|
-
return { host: ep.host, port: ep.port };
|
|
6520
|
-
});
|
|
6521
|
-
const info = {
|
|
6522
|
-
schema: parsed.schema,
|
|
6523
|
-
endpoints,
|
|
6524
|
-
key: toBytes(parsed.key, "key"),
|
|
6525
|
-
daemonId: toBytes(parsed.daemon_id, "daemon_id"),
|
|
6526
|
-
pid: parsed.pid,
|
|
6527
|
-
daemonVer: parsed.daemon_ver ?? ""
|
|
6528
|
-
};
|
|
6529
|
-
validate(info);
|
|
6530
|
-
return info;
|
|
6531
|
-
}
|
|
6532
|
-
|
|
6533
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.11.1/node_modules/@cortexkit/subc-client/dist/route-handle.js
|
|
6534
|
-
var connectionToken = new WeakMap;
|
|
6535
|
-
|
|
6536
|
-
class RouteHandle {
|
|
6537
|
-
channel;
|
|
6538
|
-
epoch;
|
|
6539
|
-
constructor(channel, epoch, token) {
|
|
6540
|
-
if (!Number.isInteger(channel) || channel <= 0 || channel > 65535) {
|
|
6541
|
-
throw new RangeError(`route channel must be an integer in 1..65535, got ${channel}`);
|
|
6542
|
-
}
|
|
6543
|
-
if (!Number.isInteger(epoch) || epoch <= 0 || epoch > 4294967295) {
|
|
6544
|
-
throw new RangeError(`route epoch must be an integer in 1..4294967295, got ${epoch}`);
|
|
6545
|
-
}
|
|
6546
|
-
this.channel = channel;
|
|
6547
|
-
this.epoch = epoch;
|
|
6548
|
-
connectionToken.set(this, token);
|
|
6549
|
-
Object.freeze(this);
|
|
6550
|
-
}
|
|
6551
|
-
static create(channel, epoch, token) {
|
|
6552
|
-
return new RouteHandle(channel, epoch, token);
|
|
6553
|
-
}
|
|
6554
|
-
}
|
|
6555
|
-
function createRouteHandle(channel, epoch, token) {
|
|
6556
|
-
const factory = RouteHandle;
|
|
6557
|
-
return factory.create(channel, epoch, token);
|
|
6558
|
-
}
|
|
6559
|
-
|
|
6560
|
-
class StaleRouteHandleError extends Error {
|
|
6561
|
-
handle;
|
|
6562
|
-
code = "stale_route_handle";
|
|
6563
|
-
constructor(handle) {
|
|
6564
|
-
super(`route handle (${handle.channel}, ${handle.epoch}) is not live on the current connection`);
|
|
6565
|
-
this.handle = handle;
|
|
6566
|
-
this.name = "StaleRouteHandleError";
|
|
6567
|
-
}
|
|
6568
|
-
}
|
|
6569
|
-
function newConnectionToken() {
|
|
6570
|
-
return Object.freeze({});
|
|
6571
|
-
}
|
|
6572
|
-
function belongsToConnection(handle, token) {
|
|
6573
|
-
return connectionToken.get(handle) === token;
|
|
6574
|
-
}
|
|
6575
|
-
function sameRouteHandle(left, right) {
|
|
6576
|
-
return left === right;
|
|
6577
|
-
}
|
|
6578
|
-
|
|
6579
|
-
// ../../node_modules/.bun/@cortexkit+subc-client@0.11.1/node_modules/@cortexkit/subc-client/dist/client.js
|
|
6580
|
-
var debug = debuglog("subc-client");
|
|
6581
|
-
var DEFAULT_HANDSHAKE_TIMEOUT_MS = 1e4;
|
|
6582
|
-
var DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
6583
|
-
var TIMEOUT_ARBITRATION_GRACE_MS = 50;
|
|
6584
|
-
var LIVENESS_PROBE_WINDOW_MS = 2000;
|
|
6585
|
-
var REQUEST_DEADLINE_MARKER = "request_deadline";
|
|
6586
|
-
var DEADLINE_NO_DROP_CODE = "deadline_exceeded_no_drop_observed";
|
|
6587
|
-
var ROUTE_OPEN_RETRY_DEADLINE_MS = 30000;
|
|
6588
|
-
var BODY_READ_TIMEOUT_MS = 30000;
|
|
6589
|
-
var EMPTY_BODY = new Uint8Array(0);
|
|
6590
|
-
var DEFAULT_MANAGED_TARGET_KIND = "management_surface";
|
|
6591
|
-
var SUBC_MODULE_ID_ENV = "SUBC_MODULE_ID";
|
|
6592
|
-
var SUBC_LAUNCH_NONCE_ENV = "SUBC_LAUNCH_NONCE";
|
|
6593
|
-
var DEFAULT_RECONNECT_BACKOFF = {
|
|
6594
|
-
baseMs: 100,
|
|
6595
|
-
capMs: 2000,
|
|
6596
|
-
maxAttempts: 6
|
|
6597
|
-
};
|
|
6598
|
-
|
|
6599
|
-
class SubcCallError extends Error {
|
|
6600
|
-
kind;
|
|
6601
|
-
code;
|
|
6602
|
-
cause;
|
|
6603
|
-
constructor(kind, message, code, cause) {
|
|
6604
|
-
super(message);
|
|
6605
|
-
this.kind = kind;
|
|
6606
|
-
this.code = code;
|
|
6607
|
-
this.cause = cause;
|
|
6608
|
-
this.name = "SubcCallError";
|
|
6609
|
-
}
|
|
6610
|
-
get detail() {
|
|
6611
|
-
return this.cause instanceof SubcError ? this.cause.detail : undefined;
|
|
6612
|
-
}
|
|
6613
|
-
}
|
|
6614
|
-
|
|
6615
|
-
class SubcError extends Error {
|
|
6616
|
-
code;
|
|
6617
|
-
detail;
|
|
6618
|
-
constructor(message, code, detail) {
|
|
6619
|
-
super(message);
|
|
6620
|
-
this.code = code;
|
|
6621
|
-
this.detail = detail;
|
|
6622
|
-
}
|
|
6623
|
-
}
|
|
6624
|
-
function requireBinaryBody(body) {
|
|
6625
|
-
if (body instanceof Uint8Array)
|
|
6626
|
-
return body;
|
|
6627
|
-
const type = body === null ? "null" : Array.isArray(body) ? "array" : typeof body;
|
|
6628
|
-
throw new SubcError(`binary request body must be a Uint8Array; got ${type}`, "binary_body_required");
|
|
6629
|
-
}
|
|
6630
|
-
class SubcClient {
|
|
6631
|
-
sock;
|
|
6632
|
-
currentConn;
|
|
6633
|
-
opts;
|
|
6634
|
-
nextCorr = 1n;
|
|
6635
|
-
pending = new Map;
|
|
6636
|
-
lateResponses = new Map;
|
|
6637
|
-
routes = new Map;
|
|
6638
|
-
liveRoutes = new Map;
|
|
6639
|
-
connectionToken = newConnectionToken();
|
|
6640
|
-
ingressEpochDropCount = 0;
|
|
6641
|
-
closedErr = null;
|
|
6642
|
-
closeStarted = false;
|
|
6643
|
-
reconnecting = null;
|
|
6644
|
-
generation = 1;
|
|
6645
|
-
readerActive = false;
|
|
6646
|
-
constructor(sock, currentConn, opts) {
|
|
6647
|
-
this.sock = sock;
|
|
6648
|
-
this.currentConn = currentConn;
|
|
6649
|
-
this.opts = opts;
|
|
6650
|
-
this.readLoop(sock, this.generation);
|
|
6651
|
-
}
|
|
6652
|
-
get conn() {
|
|
6653
|
-
return this.currentConn;
|
|
6654
|
-
}
|
|
6655
|
-
static async connect(opts) {
|
|
6656
|
-
const normalized = normalizeConnectOptions(opts);
|
|
6657
|
-
const opened = await SubcClient.openConnection(normalized);
|
|
6658
|
-
return new SubcClient(opened.sock, opened.conn, normalized);
|
|
6659
|
-
}
|
|
6660
|
-
async catalogList(moduleId) {
|
|
6661
|
-
const body = this.encode(moduleId === undefined ? { op: "catalog.list" } : { op: "catalog.list", module_id: moduleId });
|
|
6662
|
-
const reply = await this.controlRpc(body);
|
|
6663
|
-
const parsed = this.parseJson(reply);
|
|
6664
|
-
return parsed.modules ?? [];
|
|
6665
|
-
}
|
|
6666
|
-
async resolveProvider(capability) {
|
|
6667
|
-
const claimants = await this.resolveProviders(capability);
|
|
6668
|
-
if (claimants.length === 0) {
|
|
6669
|
-
throw new SubcError(`no catalog claimant for capability ${capability}`, "capability_unprovided");
|
|
6670
|
-
}
|
|
6671
|
-
if (claimants.length > 1) {
|
|
6672
|
-
throw new SubcError(`multiple catalog claimants for capability ${capability}: ${claimants.join(", ")}`, "capability_ambiguous");
|
|
6673
|
-
}
|
|
6674
|
-
return claimants[0];
|
|
6675
|
-
}
|
|
6676
|
-
async resolveProviders(capability) {
|
|
6677
|
-
if (!isValidCapabilityIdentifier(capability)) {
|
|
6678
|
-
throw new SubcError(`malformed capability identifier ${JSON.stringify(capability)}`, "invalid_capability_identifier");
|
|
6679
|
-
}
|
|
6680
|
-
const modules = await this.catalogList();
|
|
6681
|
-
return modules.filter((module) => module.capabilities?.provides.includes(capability) ?? false).map((module) => module.module_id).sort();
|
|
6682
|
-
}
|
|
6683
|
-
async routeOpen(target, identity, opts = {}) {
|
|
6684
|
-
const consumerIdentity = routeOpenConsumerIdentity(opts);
|
|
6685
|
-
const consumerCapabilities = opts.consumerCapabilities;
|
|
6686
|
-
const body = this.encode({
|
|
6687
|
-
op: "route.open",
|
|
6688
|
-
target,
|
|
6689
|
-
identity,
|
|
6690
|
-
...consumerIdentity ? { consumer_identity: consumerIdentity } : {},
|
|
6691
|
-
...consumerCapabilities !== undefined ? { consumer_capabilities: consumerCapabilities } : {}
|
|
6692
|
-
});
|
|
6693
|
-
let installed = null;
|
|
6694
|
-
const install = (frame) => {
|
|
6695
|
-
if (frame.header.ty !== FrameType.Response)
|
|
6696
|
-
return true;
|
|
6697
|
-
const parsed = this.parseJson(frame);
|
|
6698
|
-
if (typeof parsed.route_channel !== "number" || typeof parsed.route_epoch !== "number") {
|
|
6699
|
-
throw new SubcError(`route.open returned no route handle: ${JSON.stringify(parsed)}`);
|
|
6700
|
-
}
|
|
6701
|
-
installed = this.installRoute(parsed.route_channel, parsed.route_epoch);
|
|
6702
|
-
return true;
|
|
6703
|
-
};
|
|
6704
|
-
const closeLateRoute = (frame) => {
|
|
6705
|
-
if (frame.header.ty !== FrameType.Response)
|
|
6706
|
-
return;
|
|
6707
|
-
try {
|
|
6708
|
-
const parsed = this.parseJson(frame);
|
|
6709
|
-
if (typeof parsed.route_channel !== "number" || typeof parsed.route_epoch !== "number")
|
|
6710
|
-
return;
|
|
6711
|
-
const lateHandle = this.installRoute(parsed.route_channel, parsed.route_epoch);
|
|
6712
|
-
this.failHandle(lateHandle, new SubcError("late route.open was closed", "route_closed"));
|
|
6713
|
-
this.liveRoutes.delete(lateHandle.channel);
|
|
6714
|
-
this.sendRouteGoodbye(lateHandle, true);
|
|
6715
|
-
} catch {
|
|
6716
|
-
this.closeConnectionAfterCleanupFailure();
|
|
6717
|
-
}
|
|
6718
|
-
};
|
|
6719
|
-
await this.controlRpc(body, install, closeLateRoute);
|
|
6720
|
-
if (!installed)
|
|
6721
|
-
throw new SubcError("route.open response was not installed");
|
|
6722
|
-
return installed;
|
|
6723
|
-
}
|
|
6724
|
-
async request(handle, body, opts = {}) {
|
|
6725
|
-
this.assertLiveHandle(handle);
|
|
6726
|
-
const binary = opts.binary ?? false;
|
|
6727
|
-
const bytes = binary ? requireBinaryBody(body) : body instanceof Uint8Array ? body : this.encode(body);
|
|
6728
|
-
const priority = opts.priority ?? Priority.Interactive;
|
|
6729
|
-
const admission = opts.admissionClass ?? AdmissionClass.Normal;
|
|
6730
|
-
const reply = await this.send(handle, bytes, priority, admission, opts.timeoutMs, opts.onProgress, undefined, undefined, binary);
|
|
6731
|
-
return this.decodeReply(reply);
|
|
6732
|
-
}
|
|
6733
|
-
async call(moduleId, method, params, opts = {}) {
|
|
6734
|
-
if (opts.binary) {
|
|
6735
|
-
throw new SubcError("call() builds a JSON body and cannot send a binary request; use callBinary(moduleId, body, opts) with a Uint8Array", "binary_call_requires_call_binary");
|
|
6736
|
-
}
|
|
6737
|
-
const body = params === undefined ? { method } : { method, params };
|
|
6738
|
-
return await this.managedCall(moduleId, body, opts);
|
|
6739
|
-
}
|
|
6740
|
-
async callBinary(moduleId, body, opts = {}) {
|
|
6741
|
-
const bytes = requireBinaryBody(body);
|
|
6742
|
-
return this.managedCall(moduleId, bytes, { ...opts, binary: true });
|
|
6743
|
-
}
|
|
6744
|
-
async managedCall(moduleId, body, opts) {
|
|
6745
|
-
let retriedUnknownChannel = false;
|
|
6746
|
-
for (;; ) {
|
|
6747
|
-
const routeHandle = await this.cachedRouteHandle(moduleId, opts);
|
|
6748
|
-
try {
|
|
6749
|
-
return await this.managedRequest(routeHandle, body, opts);
|
|
6750
|
-
} catch (err) {
|
|
6751
|
-
if (!(err instanceof SubcCallError))
|
|
6752
|
-
throw this.terminalCallError("managed call failed", err);
|
|
6753
|
-
const deadBindCode = err.code === "unknown_channel" || err.code === "stale_route_epoch";
|
|
6754
|
-
if (deadBindCode && !retriedUnknownChannel && !this.closeStarted) {
|
|
6755
|
-
retriedUnknownChannel = true;
|
|
6756
|
-
this.evictRouteHandle(routeHandle);
|
|
6757
|
-
continue;
|
|
6758
|
-
}
|
|
6759
|
-
if (deadBindCode && retriedUnknownChannel) {
|
|
6760
|
-
this.evictRouteHandle(routeHandle);
|
|
6761
|
-
}
|
|
6762
|
-
if (err.kind === "not_sent") {
|
|
6763
|
-
try {
|
|
6764
|
-
await this.reconnectAfterDrop(err);
|
|
6765
|
-
} catch (reconnectErr) {
|
|
6766
|
-
throw this.notSentRecoveryError("managed call was not sent", reconnectErr);
|
|
6767
|
-
}
|
|
6768
|
-
continue;
|
|
6769
|
-
}
|
|
6770
|
-
if (err.kind === "outcome_unknown" && err.code !== DEADLINE_NO_DROP_CODE) {
|
|
6771
|
-
this.scheduleReconnectAfterDrop(err);
|
|
6772
|
-
} else if (err.kind === "outcome_unknown" && err.code === DEADLINE_NO_DROP_CODE) {
|
|
6773
|
-
this.probeLivenessAfterDeadline();
|
|
6774
|
-
}
|
|
6775
|
-
throw err;
|
|
6776
|
-
}
|
|
6777
|
-
}
|
|
6778
|
-
}
|
|
6779
|
-
subscribe(handle, body, onEvent, opts = {}) {
|
|
6780
|
-
this.assertLiveHandle(handle);
|
|
6781
|
-
const bytes = body instanceof Uint8Array ? body : this.encode(body);
|
|
6782
|
-
const priority = opts.priority ?? Priority.Interactive;
|
|
6783
|
-
const admission = opts.admissionClass ?? AdmissionClass.Normal;
|
|
6784
|
-
const corr = this.allocateCorr();
|
|
6785
|
-
const key = pendingKey(handle, corr);
|
|
6786
|
-
let subscriptionPending = null;
|
|
6787
|
-
let resolveClosed = null;
|
|
6788
|
-
const closed = new Promise((resolve, reject) => {
|
|
6789
|
-
if (this.closedErr) {
|
|
6790
|
-
reject(this.closedErr);
|
|
6791
|
-
return;
|
|
6792
|
-
}
|
|
6793
|
-
resolveClosed = resolve;
|
|
6794
|
-
subscriptionPending = {
|
|
6795
|
-
handle,
|
|
6796
|
-
resolve: () => resolve(),
|
|
6797
|
-
reject,
|
|
6798
|
-
onProgress: onEvent,
|
|
6799
|
-
timer: null,
|
|
6800
|
-
subscription: true
|
|
6801
|
-
};
|
|
6802
|
-
this.pending.set(key, subscriptionPending);
|
|
6803
|
-
const frame = buildFrame(FrameType.Request, buildFlags(false, priority, false, admission), handle.channel, handle.epoch, corr, bytes);
|
|
6804
|
-
writeBorrowed(this.sock, encodeFrame(frame), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch((err) => {
|
|
6805
|
-
const pending = this.pending.get(key);
|
|
6806
|
-
if (pending)
|
|
6807
|
-
this.rejectPending(key, pending, err instanceof Error ? err : new SubcError(String(err)));
|
|
6808
|
-
});
|
|
6809
|
-
});
|
|
6810
|
-
let cancelled = false;
|
|
6811
|
-
const unsubscribe = () => {
|
|
6812
|
-
if (cancelled)
|
|
6813
|
-
return;
|
|
6814
|
-
cancelled = true;
|
|
6815
|
-
if (subscriptionPending && resolveClosed)
|
|
6816
|
-
this.settle(key, subscriptionPending, resolveClosed);
|
|
6817
|
-
if (this.isLiveHandle(handle))
|
|
6818
|
-
this.cancel(handle, corr, priority);
|
|
6819
|
-
};
|
|
6820
|
-
return { unsubscribe, closed };
|
|
6821
|
-
}
|
|
6822
|
-
cancel(handle, corr, priority = Priority.Interactive) {
|
|
6823
|
-
this.assertLiveHandle(handle);
|
|
6824
|
-
const cancel = buildFrame(FrameType.Cancel, buildFlags(false, priority, false), handle.channel, handle.epoch, corr, EMPTY_BODY);
|
|
6825
|
-
writeBorrowed(this.sock, encodeFrame(cancel), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS).catch(() => {
|
|
6826
|
-
return;
|
|
6827
|
-
});
|
|
6828
|
-
}
|
|
6829
|
-
async routePoll(handle, kind) {
|
|
6830
|
-
this.assertLiveHandle(handle);
|
|
6831
|
-
const body = this.encode({
|
|
6832
|
-
op: "route.poll",
|
|
6833
|
-
route_channel: handle.channel,
|
|
6834
|
-
route_epoch: handle.epoch,
|
|
6835
|
-
kind
|
|
6836
|
-
});
|
|
6837
|
-
const reply = await this.controlRpc(body, (frame) => {
|
|
6838
|
-
if (frame.header.ty !== FrameType.Response)
|
|
6839
|
-
return true;
|
|
6840
|
-
const parsed = this.parseJson(frame);
|
|
6841
|
-
return parsed.route_channel === handle.channel && parsed.route_epoch === handle.epoch;
|
|
6842
|
-
});
|
|
6843
|
-
return this.parseJson(reply);
|
|
6844
|
-
}
|
|
6845
|
-
async closeRoute(handle, opts = {}) {
|
|
6846
|
-
this.assertLiveHandle(handle);
|
|
6847
|
-
for (const [key, cached] of this.routes) {
|
|
6848
|
-
if (cached.handle && sameRouteHandle(cached.handle, handle)) {
|
|
6849
|
-
cached.closed = true;
|
|
6850
|
-
cached.handle = null;
|
|
6851
|
-
this.routes.delete(key);
|
|
6852
|
-
}
|
|
6853
|
-
}
|
|
6854
|
-
if (opts.drain)
|
|
6855
|
-
await this.drainUnaryOnHandle(handle);
|
|
6856
|
-
this.failHandle(handle, new SubcError("route closed by closeRoute", "route_closed"));
|
|
6857
|
-
if (this.liveRoutes.get(handle.channel) === handle)
|
|
6858
|
-
this.liveRoutes.delete(handle.channel);
|
|
6859
|
-
this.sendRouteGoodbye(handle);
|
|
6860
|
-
}
|
|
6861
|
-
async closeManagedRoute(target, identity, opts = {}) {
|
|
6862
|
-
const key = routeCacheKey(target, identity, routeOpenConsumerIdentity(opts));
|
|
6863
|
-
const cached = this.routes.get(key);
|
|
6864
|
-
if (!cached)
|
|
6865
|
-
return;
|
|
6866
|
-
cached.closed = true;
|
|
6867
|
-
this.routes.delete(key);
|
|
6868
|
-
const handle = cached.handle;
|
|
6869
|
-
cached.handle = null;
|
|
6870
|
-
if (handle)
|
|
6871
|
-
await this.closeRoute(handle, opts);
|
|
6872
|
-
}
|
|
6873
|
-
async closeRouteChannel(handle, opts = {}) {
|
|
6874
|
-
await this.closeRoute(handle, opts);
|
|
6875
|
-
}
|
|
6876
|
-
close() {
|
|
6877
|
-
this.closeStarted = true;
|
|
6878
|
-
this.fail(new SubcError("client closed"));
|
|
6879
|
-
this.sock.close();
|
|
6880
|
-
}
|
|
6881
|
-
drainUnaryOnHandle(handle) {
|
|
6882
|
-
const waiters = [];
|
|
6883
|
-
for (const pending of this.pending.values()) {
|
|
6884
|
-
if (pending.handle === handle && !pending.subscription) {
|
|
6885
|
-
waiters.push(new Promise((resolve) => {
|
|
6886
|
-
const previous = pending.onSettle;
|
|
6887
|
-
pending.onSettle = () => {
|
|
6888
|
-
previous?.();
|
|
6889
|
-
resolve();
|
|
6890
|
-
};
|
|
6891
|
-
}));
|
|
6892
|
-
}
|
|
6893
|
-
}
|
|
6894
|
-
return Promise.all(waiters).then(() => {
|
|
6895
|
-
return;
|
|
6896
|
-
});
|
|
6897
|
-
}
|
|
6898
|
-
sendRouteGoodbye(handle, closeOnQueueFailure = false) {
|
|
6899
|
-
this.assertLiveConnection(handle);
|
|
6900
|
-
if (this.closedErr) {
|
|
6901
|
-
if (closeOnQueueFailure)
|
|
6902
|
-
this.closeConnectionAfterCleanupFailure();
|
|
6903
|
-
return;
|
|
6904
|
-
}
|
|
6905
|
-
const goodbye = buildFrame(FrameType.Goodbye, buildFlags(false, Priority.Interactive, false), handle.channel, handle.epoch, 0n, EMPTY_BODY);
|
|
6906
|
-
const write = writeTrackedBorrowed(this.sock, encodeFrame(goodbye), Date.now() + DEFAULT_REQUEST_TIMEOUT_MS);
|
|
6907
|
-
if (!write.queued && closeOnQueueFailure)
|
|
6908
|
-
this.closeConnectionAfterCleanupFailure();
|
|
6909
|
-
write.completed.catch(() => {
|
|
6910
|
-
if (closeOnQueueFailure && !write.queued)
|
|
6911
|
-
this.closeConnectionAfterCleanupFailure();
|
|
6912
|
-
});
|
|
6913
|
-
}
|
|
6914
|
-
static async openConnection(opts) {
|
|
6915
|
-
const conn = await readConnectionFile(opts.connectionFile);
|
|
6916
|
-
const deadline = Date.now() + (opts.handshakeTimeoutMs ?? DEFAULT_HANDSHAKE_TIMEOUT_MS);
|
|
6917
|
-
const endpoint = conn.endpoints[0];
|
|
6918
|
-
const sock = await SubcSocket.connect(endpoint.host, endpoint.port, deadline);
|
|
6919
|
-
try {
|
|
6920
|
-
await authenticateClient(sock, conn, deadline);
|
|
6921
|
-
} catch (err) {
|
|
6922
|
-
sock.close();
|
|
6923
|
-
throw err;
|
|
6924
|
-
}
|
|
6925
|
-
return { sock, conn };
|
|
6926
|
-
}
|
|
6927
|
-
async controlRpc(body, acceptFrame, onLateResponse) {
|
|
6928
|
-
return this.send(null, body, Priority.Interactive, AdmissionClass.Normal, undefined, undefined, acceptFrame, onLateResponse);
|
|
6929
|
-
}
|
|
6930
|
-
send(handle, body, priority, admission, timeoutMs, onProgress, acceptFrame, onLateResponse, binary = false) {
|
|
6931
|
-
if (handle)
|
|
6932
|
-
this.assertLiveHandle(handle);
|
|
6933
|
-
if (this.closedErr)
|
|
6934
|
-
return Promise.reject(this.closedErr);
|
|
6935
|
-
let corr;
|
|
6936
|
-
try {
|
|
6937
|
-
corr = this.allocateCorr();
|
|
6938
|
-
} catch (error) {
|
|
6939
|
-
return Promise.reject(error);
|
|
6940
|
-
}
|
|
6941
|
-
const key = pendingKey(handle, corr);
|
|
6942
|
-
const channel = handle?.channel ?? 0;
|
|
6943
|
-
const epoch = handle?.epoch ?? 0;
|
|
6944
|
-
const frame = buildFrame(FrameType.Request, buildFlags(binary, priority, false, admission), channel, epoch, corr, body);
|
|
6945
|
-
return new Promise((resolve, reject) => {
|
|
6946
|
-
const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
6947
|
-
const pending = {
|
|
6948
|
-
handle,
|
|
6949
|
-
resolve,
|
|
6950
|
-
reject,
|
|
6951
|
-
onProgress,
|
|
6952
|
-
timer: null,
|
|
6953
|
-
acceptFrame,
|
|
6954
|
-
onLateResponse
|
|
6955
|
-
};
|
|
6956
|
-
pending.timer = setTimeout(() => this.arbitrateTimeout(key, pending, channel, corr, ms), ms);
|
|
6957
|
-
this.pending.set(key, pending);
|
|
6958
|
-
writeBorrowed(this.sock, encodeFrame(frame), Date.now() + ms).catch((error) => {
|
|
6959
|
-
const current = this.pending.get(key);
|
|
6960
|
-
if (current)
|
|
6961
|
-
this.rejectPending(key, current, error instanceof Error ? error : new SubcError(String(error)));
|
|
6962
|
-
});
|
|
6963
|
-
});
|
|
6964
|
-
}
|
|
6965
|
-
arbitrateTimeout(key, pending, channel, corr, ms) {
|
|
6966
|
-
const settleAsTimeout = () => {
|
|
6967
|
-
if (pending.onLateResponse)
|
|
6968
|
-
this.lateResponses.set(key, pending.onLateResponse);
|
|
6969
|
-
this.rejectPending(key, pending, new SubcError(this.timeoutMessage(channel, corr, ms), REQUEST_DEADLINE_MARKER));
|
|
6970
|
-
};
|
|
6971
|
-
const graceDeadline = Date.now() + this.opts.timeoutArbitrationGraceMs;
|
|
6972
|
-
const arbitrate = () => {
|
|
6973
|
-
if (this.pending.get(key) !== pending)
|
|
6974
|
-
return;
|
|
6975
|
-
const readerDraining = this.readerActive || this.sock.bufferedBytes() > 0;
|
|
6976
|
-
if (readerDraining && Date.now() < graceDeadline) {
|
|
6977
|
-
setImmediate(arbitrate);
|
|
6978
|
-
return;
|
|
6979
|
-
}
|
|
6980
|
-
settleAsTimeout();
|
|
6981
|
-
};
|
|
6982
|
-
setImmediate(arbitrate);
|
|
6983
|
-
}
|
|
6984
|
-
async managedRequest(handle, body, opts) {
|
|
6985
|
-
const binary = opts.binary ?? false;
|
|
6986
|
-
const bytes = binary ? requireBinaryBody(body) : body instanceof Uint8Array ? body : this.encode(body);
|
|
6987
|
-
const priority = opts.priority ?? Priority.Interactive;
|
|
6988
|
-
const admission = opts.admissionClass ?? AdmissionClass.Normal;
|
|
6989
|
-
try {
|
|
6990
|
-
const reply = await this.sendManaged(handle, bytes, priority, admission, opts.timeoutMs, opts.onProgress, binary);
|
|
6991
|
-
return this.decodeReply(reply);
|
|
6992
|
-
} catch (error) {
|
|
6993
|
-
if (error instanceof SubcCallError)
|
|
6994
|
-
throw error;
|
|
6995
|
-
throw this.terminalCallError("managed call failed", error);
|
|
6996
|
-
}
|
|
6997
|
-
}
|
|
6998
|
-
sendManaged(handle, body, priority, admission, timeoutMs, onProgress, binary = false) {
|
|
6999
|
-
try {
|
|
7000
|
-
this.assertLiveHandle(handle);
|
|
7001
|
-
} catch (error) {
|
|
7002
|
-
return Promise.reject(this.notSentCallError("request used a stale route handle", error));
|
|
7003
|
-
}
|
|
7004
|
-
if (this.closedErr) {
|
|
7005
|
-
return Promise.reject(this.notSentCallError("request was not sent because the subc connection was already closed", this.closedErr));
|
|
7006
|
-
}
|
|
7007
|
-
let corr;
|
|
7008
|
-
try {
|
|
7009
|
-
corr = this.allocateCorr();
|
|
7010
|
-
} catch (error) {
|
|
7011
|
-
return Promise.reject(this.notSentCallError("request correlation allocator was exhausted", error));
|
|
7012
|
-
}
|
|
7013
|
-
const key = pendingKey(handle, corr);
|
|
7014
|
-
const frame = buildFrame(FrameType.Request, buildFlags(binary, priority, false, admission), handle.channel, handle.epoch, corr, body);
|
|
7015
|
-
let handedToSocket = false;
|
|
7016
|
-
const classifyFailure = (error) => {
|
|
7017
|
-
if (!handedToSocket)
|
|
7018
|
-
return this.notSentCallError("request bytes were not queued to the subc socket", error);
|
|
7019
|
-
if (error instanceof SubcError && error.code === REQUEST_DEADLINE_MARKER) {
|
|
7020
|
-
return new SubcCallError("outcome_unknown", `managed call deadline exceeded after request bytes were queued to the local socket; no terminal response was observed; outcome unknown${causeMessage(error)}`, DEADLINE_NO_DROP_CODE, error);
|
|
7021
|
-
}
|
|
7022
|
-
return this.outcomeUnknownCallError("connection dropped before the managed call returned a response", error);
|
|
7023
|
-
};
|
|
7024
|
-
return new Promise((resolve, reject) => {
|
|
7025
|
-
const ms = timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
7026
|
-
const pending = {
|
|
7027
|
-
handle,
|
|
7028
|
-
resolve,
|
|
7029
|
-
reject,
|
|
7030
|
-
onProgress,
|
|
7031
|
-
timer: null,
|
|
7032
|
-
classifyFailure
|
|
7033
|
-
};
|
|
7034
|
-
pending.timer = setTimeout(() => this.arbitrateTimeout(key, pending, handle.channel, corr, ms), ms);
|
|
7035
|
-
this.pending.set(key, pending);
|
|
7036
|
-
const write = writeTrackedBorrowed(this.sock, encodeFrame(frame), Date.now() + ms);
|
|
7037
|
-
handedToSocket = write.queued;
|
|
7038
|
-
write.completed.catch((error) => {
|
|
7039
|
-
const current = this.pending.get(key);
|
|
7040
|
-
if (current)
|
|
7041
|
-
this.rejectPending(key, current, error instanceof Error ? error : new SubcError(String(error)));
|
|
7042
|
-
});
|
|
7043
|
-
});
|
|
7044
|
-
}
|
|
7045
|
-
async cachedRouteHandle(moduleId, opts) {
|
|
7046
|
-
const identity = opts.identity ?? this.opts.identity;
|
|
7047
|
-
if (!identity) {
|
|
7048
|
-
throw new SubcCallError("terminal", "managed call requires a BindIdentity in SubcClient.connect({ identity }) or call(..., { identity })", "missing_identity");
|
|
7049
|
-
}
|
|
7050
|
-
const target = { kind: opts.targetKind ?? this.opts.targetKind, module_id: moduleId };
|
|
7051
|
-
const consumerIdentity = routeOpenConsumerIdentity(opts);
|
|
7052
|
-
const key = routeCacheKey(target, identity, consumerIdentity);
|
|
7053
|
-
let cached = this.routes.get(key);
|
|
7054
|
-
if (!cached) {
|
|
7055
|
-
cached = {
|
|
7056
|
-
key,
|
|
7057
|
-
moduleId,
|
|
7058
|
-
target,
|
|
7059
|
-
identity,
|
|
7060
|
-
consumerIdentity,
|
|
7061
|
-
handle: null,
|
|
7062
|
-
opening: null
|
|
7063
|
-
};
|
|
7064
|
-
this.routes.set(key, cached);
|
|
7065
|
-
}
|
|
7066
|
-
if (cached.handle && this.isLiveHandle(cached.handle))
|
|
7067
|
-
return cached.handle;
|
|
7068
|
-
if (!cached.opening) {
|
|
7069
|
-
cached.opening = this.openCachedRoute(cached).finally(() => {
|
|
7070
|
-
cached.opening = null;
|
|
7071
|
-
});
|
|
7072
|
-
}
|
|
7073
|
-
return cached.opening;
|
|
7074
|
-
}
|
|
7075
|
-
async openCachedRoute(cached) {
|
|
7076
|
-
const routeRetryDeadline = Date.now() + this.opts.routeOpenRetryDeadlineMs;
|
|
7077
|
-
let routeRetryDelay = this.opts.reconnectBackoff.baseMs;
|
|
7078
|
-
let routeRetryAttempt = 0;
|
|
7079
|
-
for (;; ) {
|
|
7080
|
-
if (cached.closed)
|
|
7081
|
-
throw this.routeClosedDuringOpen();
|
|
7082
|
-
try {
|
|
7083
|
-
await this.ensureConnectedForManaged();
|
|
7084
|
-
} catch (error) {
|
|
7085
|
-
throw this.notSentRecoveryError("route.open could not run because reconnect failed", error);
|
|
7086
|
-
}
|
|
7087
|
-
if (cached.handle && this.isLiveHandle(cached.handle))
|
|
7088
|
-
return cached.handle;
|
|
7089
|
-
try {
|
|
7090
|
-
const handle = await this.routeOpen(cached.target, cached.identity, {
|
|
7091
|
-
consumerIdentity: cached.consumerIdentity ?? null
|
|
7092
|
-
});
|
|
7093
|
-
if (cached.closed) {
|
|
7094
|
-
this.liveRoutes.delete(handle.channel);
|
|
7095
|
-
this.sendRouteGoodbye(handle);
|
|
7096
|
-
throw this.routeClosedDuringOpen();
|
|
7097
|
-
}
|
|
7098
|
-
cached.handle = handle;
|
|
7099
|
-
return handle;
|
|
7100
|
-
} catch (error) {
|
|
7101
|
-
if (error instanceof SubcCallError && error.code === "route_closed")
|
|
7102
|
-
throw error;
|
|
7103
|
-
if (!this.closeStarted && isConsumerReconnectTransient(error)) {
|
|
7104
|
-
try {
|
|
7105
|
-
await this.reconnectAfterDrop(error);
|
|
7106
|
-
} catch (reconnectError) {
|
|
7107
|
-
throw this.notSentRecoveryError("route.open was not sent and reconnect failed", reconnectError);
|
|
7108
|
-
}
|
|
7109
|
-
continue;
|
|
7110
|
-
}
|
|
7111
|
-
if (!this.closeStarted && error instanceof SubcError && isRetryableRouteOpenCode(error.code)) {
|
|
7112
|
-
routeRetryAttempt += 1;
|
|
7113
|
-
if (Date.now() < routeRetryDeadline) {
|
|
7114
|
-
await this.opts.sleep(routeRetryDelay);
|
|
7115
|
-
routeRetryDelay = Math.min(routeRetryDelay * 2, this.opts.reconnectBackoff.capMs);
|
|
7116
|
-
continue;
|
|
7117
|
-
}
|
|
7118
|
-
throw this.notSentCallError(`route.open failed for module ${cached.moduleId}: ${error.code} (retry deadline exhausted after ${routeRetryAttempt} attempts)`, error);
|
|
7119
|
-
}
|
|
7120
|
-
throw this.terminalCallError(`route.open failed for module ${cached.moduleId}`, error);
|
|
7121
|
-
}
|
|
7122
|
-
}
|
|
7123
|
-
}
|
|
7124
|
-
lastInboundAtMs = 0;
|
|
7125
|
-
livenessProbe = null;
|
|
7126
|
-
hasControlPending() {
|
|
7127
|
-
for (const pending of this.pending.values()) {
|
|
7128
|
-
if (pending.handle === null)
|
|
7129
|
-
return true;
|
|
7130
|
-
}
|
|
7131
|
-
return false;
|
|
7132
|
-
}
|
|
7133
|
-
probeLivenessAfterDeadline() {
|
|
7134
|
-
if (this.livenessProbe || this.closeStarted || this.closedErr)
|
|
7135
|
-
return;
|
|
7136
|
-
if (this.hasControlPending())
|
|
7137
|
-
return;
|
|
7138
|
-
const sock = this.sock;
|
|
7139
|
-
const generation = this.generation;
|
|
7140
|
-
let corr;
|
|
7141
|
-
try {
|
|
7142
|
-
corr = this.allocateCorr();
|
|
7143
|
-
} catch {
|
|
7144
|
-
return;
|
|
7145
|
-
}
|
|
7146
|
-
const t0 = Date.now();
|
|
7147
|
-
const ping = buildFrame(FrameType.Ping, buildFlags(false, Priority.Interactive, false, AdmissionClass.Normal), 0, 0, corr, new Uint8Array);
|
|
7148
|
-
const probe = (async () => {
|
|
7149
|
-
await writeBorrowed(sock, encodeFrame(ping), t0 + this.opts.livenessProbeWindowMs).catch(() => {});
|
|
7150
|
-
await this.opts.sleep(this.opts.livenessProbeWindowMs);
|
|
7151
|
-
if (this.sock !== sock || this.generation !== generation || this.closeStarted)
|
|
7152
|
-
return;
|
|
7153
|
-
if (this.lastInboundAtMs >= t0)
|
|
7154
|
-
return;
|
|
7155
|
-
if (this.hasControlPending())
|
|
7156
|
-
return;
|
|
7157
|
-
this.fail(new SocketClosedError(`liveness probe convicted a half-open socket: no inbound frame for ${this.opts.livenessProbeWindowMs}ms after a channel-0 Ping (deadline-no-drop settles preceded this); closing so the next call reconnects`));
|
|
7158
|
-
sock.close();
|
|
7159
|
-
})().finally(() => {
|
|
7160
|
-
this.livenessProbe = null;
|
|
7161
|
-
});
|
|
7162
|
-
this.livenessProbe = probe;
|
|
7163
|
-
}
|
|
7164
|
-
async ensureConnectedForManaged() {
|
|
7165
|
-
if (this.closeStarted)
|
|
7166
|
-
throw new SubcError("client closed");
|
|
7167
|
-
if (this.reconnecting)
|
|
7168
|
-
await this.reconnecting;
|
|
7169
|
-
if (this.closedErr)
|
|
7170
|
-
await this.reconnectAfterDrop(this.closedErr);
|
|
7171
|
-
}
|
|
7172
|
-
scheduleReconnectAfterDrop(err) {
|
|
7173
|
-
if (this.closeStarted || this.reconnecting)
|
|
7174
|
-
return;
|
|
7175
|
-
this.reconnectAfterDrop(err).catch(() => {});
|
|
7176
|
-
}
|
|
7177
|
-
reconnectAfterDrop(trigger) {
|
|
7178
|
-
if (this.closeStarted)
|
|
7179
|
-
return Promise.reject(new SubcError("client closed"));
|
|
7180
|
-
if (this.reconnecting)
|
|
7181
|
-
return this.reconnecting;
|
|
7182
|
-
const promise = this.reconnectWithRetry(trigger).finally(() => {
|
|
7183
|
-
if (this.reconnecting === promise)
|
|
7184
|
-
this.reconnecting = null;
|
|
7185
|
-
});
|
|
7186
|
-
this.reconnecting = promise;
|
|
7187
|
-
return promise;
|
|
7188
|
-
}
|
|
7189
|
-
async reconnectWithRetry(_trigger) {
|
|
7190
|
-
let attempt = 0;
|
|
7191
|
-
let delay = this.opts.reconnectBackoff.baseMs;
|
|
7192
|
-
for (;; ) {
|
|
7193
|
-
if (this.closeStarted)
|
|
7194
|
-
throw new SubcError("client closed");
|
|
7195
|
-
attempt += 1;
|
|
7196
|
-
try {
|
|
7197
|
-
const opened = await SubcClient.openConnection(this.opts);
|
|
7198
|
-
if (this.closeStarted) {
|
|
7199
|
-
opened.sock.close();
|
|
7200
|
-
throw new SubcError("client closed");
|
|
7201
|
-
}
|
|
7202
|
-
this.replaceConnection(opened);
|
|
7203
|
-
await this.reopenCachedRoutes();
|
|
7204
|
-
return;
|
|
7205
|
-
} catch (err) {
|
|
7206
|
-
if (!isConsumerReconnectTransient(err) || attempt >= this.opts.reconnectBackoff.maxAttempts) {
|
|
7207
|
-
if (err instanceof AuthError && attempt > 1) {
|
|
7208
|
-
throw new AuthError(`reconnect gave up after ${attempt} attempts: ${err.message} — the connection file and the daemon's key disagree persistently ` + `(daemon restarting in a loop, split connection-file paths, or a genuinely foreign daemon on this port); ` + `check the daemon, then restart this host app`);
|
|
7209
|
-
}
|
|
7210
|
-
throw err;
|
|
7211
|
-
}
|
|
7212
|
-
await this.opts.sleep(delay);
|
|
7213
|
-
delay = Math.min(delay * 2, this.opts.reconnectBackoff.capMs);
|
|
7214
|
-
}
|
|
7215
|
-
}
|
|
7216
|
-
}
|
|
7217
|
-
replaceConnection(opened) {
|
|
7218
|
-
this.sock.close();
|
|
7219
|
-
this.sock = opened.sock;
|
|
7220
|
-
this.currentConn = opened.conn;
|
|
7221
|
-
this.closedErr = null;
|
|
7222
|
-
this.generation += 1;
|
|
7223
|
-
this.connectionToken = newConnectionToken();
|
|
7224
|
-
this.liveRoutes.clear();
|
|
7225
|
-
this.lateResponses.clear();
|
|
7226
|
-
this.nextCorr = 1n;
|
|
7227
|
-
this.readLoop(opened.sock, this.generation);
|
|
7228
|
-
}
|
|
7229
|
-
async reopenCachedRoutes() {
|
|
7230
|
-
const routeKeys = [...this.routes.keys()];
|
|
7231
|
-
for (const key of routeKeys) {
|
|
7232
|
-
const cached = this.routes.get(key);
|
|
7233
|
-
if (cached)
|
|
7234
|
-
cached.handle = null;
|
|
7235
|
-
}
|
|
7236
|
-
for (const key of routeKeys) {
|
|
7237
|
-
const cached = this.routes.get(key);
|
|
7238
|
-
if (!cached || cached.closed)
|
|
7239
|
-
continue;
|
|
7240
|
-
try {
|
|
7241
|
-
const handle = await this.routeOpen(cached.target, cached.identity, {
|
|
7242
|
-
consumerIdentity: cached.consumerIdentity ?? null
|
|
7243
|
-
});
|
|
7244
|
-
if (cached.closed) {
|
|
7245
|
-
this.liveRoutes.delete(handle.channel);
|
|
7246
|
-
this.sendRouteGoodbye(handle);
|
|
7247
|
-
continue;
|
|
7248
|
-
}
|
|
7249
|
-
cached.handle = handle;
|
|
7250
|
-
} catch (error) {
|
|
7251
|
-
if (isRouteOpenRefusal(error)) {
|
|
7252
|
-
this.routes.delete(key);
|
|
7253
|
-
continue;
|
|
7254
|
-
}
|
|
7255
|
-
throw error;
|
|
7256
|
-
}
|
|
7257
|
-
}
|
|
7258
|
-
}
|
|
7259
|
-
timeoutMessage(channel, corr, ms) {
|
|
7260
|
-
const port = this.sock.localPort();
|
|
7261
|
-
const where = port === null ? "channel" : `local_port=${port} channel`;
|
|
7262
|
-
return `request on ${where} ${channel} corr ${corr} timed out after ${ms}ms`;
|
|
7263
|
-
}
|
|
7264
|
-
routeClosedDuringOpen() {
|
|
7265
|
-
return new SubcCallError("not_sent", "route was closed before route.open completed", "route_closed");
|
|
7266
|
-
}
|
|
7267
|
-
async readLoop(sock, generation) {
|
|
7268
|
-
try {
|
|
7269
|
-
for (;; ) {
|
|
7270
|
-
this.readerActive = false;
|
|
7271
|
-
const frame = await sock.readFrame(Number.POSITIVE_INFINITY, { afterHeaderMs: BODY_READ_TIMEOUT_MS }, () => {
|
|
7272
|
-
this.readerActive = true;
|
|
7273
|
-
});
|
|
7274
|
-
try {
|
|
7275
|
-
if (this.sock === sock && this.generation === generation)
|
|
7276
|
-
this.dispatch(frame);
|
|
7277
|
-
} finally {
|
|
7278
|
-
this.readerActive = false;
|
|
7279
|
-
}
|
|
7280
|
-
}
|
|
7281
|
-
} catch (error) {
|
|
7282
|
-
if (this.sock === sock && this.generation === generation) {
|
|
7283
|
-
this.fail(error instanceof Error ? error : new SubcError(String(error)));
|
|
7284
|
-
}
|
|
7285
|
-
}
|
|
7286
|
-
}
|
|
7287
|
-
dispatch(frame) {
|
|
7288
|
-
this.lastInboundAtMs = Date.now();
|
|
7289
|
-
if (frame.header.channel === 0 && frame.header.ty === FrameType.Push) {
|
|
7290
|
-
const observer = this.opts.onControlPush;
|
|
7291
|
-
if (observer) {
|
|
7292
|
-
let parsed = null;
|
|
7293
|
-
try {
|
|
7294
|
-
const body = this.parseJson(frame);
|
|
7295
|
-
if (body && typeof body.op === "string")
|
|
7296
|
-
parsed = { op: body.op, body };
|
|
7297
|
-
} catch {}
|
|
7298
|
-
if (parsed) {
|
|
7299
|
-
try {
|
|
7300
|
-
observer(parsed);
|
|
7301
|
-
} catch {}
|
|
7302
|
-
}
|
|
7303
|
-
}
|
|
7304
|
-
return;
|
|
7305
|
-
}
|
|
7306
|
-
let handle = null;
|
|
7307
|
-
if (frame.header.channel !== 0) {
|
|
7308
|
-
handle = this.liveRoutes.get(frame.header.channel) ?? null;
|
|
7309
|
-
if (!handle || handle.epoch !== frame.header.epoch) {
|
|
7310
|
-
this.ingressEpochDropCount += 1;
|
|
7311
|
-
return;
|
|
7312
|
-
}
|
|
7313
|
-
}
|
|
7314
|
-
const key = pendingKey(handle, frame.header.corr);
|
|
7315
|
-
const pending = this.pending.get(key);
|
|
7316
|
-
if (pending) {
|
|
7317
|
-
if (pending.acceptFrame && !pending.acceptFrame(frame))
|
|
7318
|
-
return;
|
|
7319
|
-
switch (frame.header.ty) {
|
|
7320
|
-
case FrameType.Push:
|
|
7321
|
-
case FrameType.StreamData:
|
|
7322
|
-
try {
|
|
7323
|
-
pending.onProgress?.(frame.body);
|
|
7324
|
-
} catch {}
|
|
7325
|
-
return;
|
|
7326
|
-
case FrameType.Response:
|
|
7327
|
-
case FrameType.StreamEnd:
|
|
7328
|
-
this.settle(key, pending, () => pending.resolve(frame));
|
|
7329
|
-
return;
|
|
7330
|
-
case FrameType.Error:
|
|
7331
|
-
this.settle(key, pending, () => pending.reject(this.errorFromFrame(frame)));
|
|
7332
|
-
return;
|
|
7333
|
-
default:
|
|
7334
|
-
return;
|
|
7335
|
-
}
|
|
7336
|
-
}
|
|
7337
|
-
const late = this.lateResponses.get(key);
|
|
7338
|
-
if (late && (frame.header.ty === FrameType.Response || frame.header.ty === FrameType.Error)) {
|
|
7339
|
-
this.lateResponses.delete(key);
|
|
7340
|
-
late(frame);
|
|
7341
|
-
return;
|
|
7342
|
-
}
|
|
7343
|
-
if (frame.header.ty === FrameType.Goodbye && handle) {
|
|
7344
|
-
this.failHandle(handle, new SubcError("route closed by subc (GOODBYE)", "route_closed"));
|
|
7345
|
-
if (this.liveRoutes.get(handle.channel) === handle)
|
|
7346
|
-
this.liveRoutes.delete(handle.channel);
|
|
7347
|
-
this.evictRouteHandle(handle);
|
|
7348
|
-
return;
|
|
7349
|
-
}
|
|
7350
|
-
if (frame.header.ty === FrameType.Response || frame.header.ty === FrameType.Error || frame.header.ty === FrameType.StreamEnd) {
|
|
7351
|
-
debug("dropped terminal frame with no waiter: type=%d channel=%d epoch=%d corr=%s port=%s", frame.header.ty, frame.header.channel, frame.header.epoch, frame.header.corr, this.sock.localPort() ?? "?");
|
|
7352
|
-
}
|
|
7353
|
-
}
|
|
7354
|
-
settle(key, pending, run) {
|
|
7355
|
-
if (this.pending.get(key) !== pending)
|
|
7356
|
-
return false;
|
|
7357
|
-
this.pending.delete(key);
|
|
7358
|
-
if (pending.timer)
|
|
7359
|
-
clearTimeout(pending.timer);
|
|
7360
|
-
run();
|
|
7361
|
-
pending.onSettle?.();
|
|
7362
|
-
return true;
|
|
7363
|
-
}
|
|
7364
|
-
rejectPending(key, pending, err) {
|
|
7365
|
-
this.settle(key, pending, () => pending.reject(pending.classifyFailure?.(err) ?? err));
|
|
7366
|
-
}
|
|
7367
|
-
errorFromFrame(frame) {
|
|
7368
|
-
try {
|
|
7369
|
-
const parsed = JSON.parse(Buffer.from(frame.body).toString("utf8"));
|
|
7370
|
-
return new SubcError(parsed.message ?? "subc error", parsed.code, parsed.detail);
|
|
7371
|
-
} catch {
|
|
7372
|
-
return new SubcError(Buffer.from(frame.body).toString("utf8") || "subc error");
|
|
7373
|
-
}
|
|
7374
|
-
}
|
|
7375
|
-
evictRouteHandle(handle) {
|
|
7376
|
-
for (const cached of this.routes.values()) {
|
|
7377
|
-
if (cached.handle && sameRouteHandle(cached.handle, handle))
|
|
7378
|
-
cached.handle = null;
|
|
7379
|
-
}
|
|
7380
|
-
}
|
|
7381
|
-
failHandle(handle, error) {
|
|
7382
|
-
for (const [key, pending] of this.pending) {
|
|
7383
|
-
if (pending.handle && sameRouteHandle(pending.handle, handle))
|
|
7384
|
-
this.rejectPending(key, pending, error);
|
|
7385
|
-
}
|
|
7386
|
-
}
|
|
7387
|
-
fail(err) {
|
|
7388
|
-
if (!this.closedErr)
|
|
7389
|
-
this.closedErr = err;
|
|
7390
|
-
for (const [key, pending] of this.pending) {
|
|
7391
|
-
this.rejectPending(key, pending, err);
|
|
7392
|
-
}
|
|
7393
|
-
}
|
|
7394
|
-
notSentCallError(message, cause) {
|
|
7395
|
-
return new SubcCallError("not_sent", `${message}${causeMessage(cause)}`, errorCode(cause), cause);
|
|
7396
|
-
}
|
|
7397
|
-
outcomeUnknownCallError(message, cause) {
|
|
7398
|
-
return new SubcCallError("outcome_unknown", `${message}${causeMessage(cause)}`, errorCode(cause), cause);
|
|
7399
|
-
}
|
|
7400
|
-
terminalCallError(message, cause) {
|
|
7401
|
-
if (cause instanceof SubcCallError)
|
|
7402
|
-
return cause;
|
|
7403
|
-
return new SubcCallError("terminal", `${message}${causeMessage(cause)}`, errorCode(cause), cause);
|
|
7404
|
-
}
|
|
7405
|
-
notSentRecoveryError(message, cause) {
|
|
7406
|
-
if (cause instanceof SubcCallError)
|
|
7407
|
-
return cause;
|
|
7408
|
-
if (isConsumerReconnectTransient(cause))
|
|
7409
|
-
return this.notSentCallError(message, cause);
|
|
7410
|
-
return this.terminalCallError(message, cause);
|
|
7411
|
-
}
|
|
7412
|
-
get droppedIngressFrames() {
|
|
7413
|
-
return this.ingressEpochDropCount;
|
|
7414
|
-
}
|
|
7415
|
-
installRoute(channel, epoch) {
|
|
7416
|
-
const handle = createRouteHandle(channel, epoch, this.connectionToken);
|
|
7417
|
-
this.liveRoutes.set(channel, handle);
|
|
7418
|
-
return handle;
|
|
7419
|
-
}
|
|
7420
|
-
isLiveHandle(handle) {
|
|
7421
|
-
return belongsToConnection(handle, this.connectionToken) && this.liveRoutes.get(handle.channel) === handle;
|
|
7422
|
-
}
|
|
7423
|
-
assertLiveConnection(handle) {
|
|
7424
|
-
if (!belongsToConnection(handle, this.connectionToken))
|
|
7425
|
-
throw new StaleRouteHandleError(handle);
|
|
7426
|
-
}
|
|
7427
|
-
assertLiveHandle(handle) {
|
|
7428
|
-
if (!this.isLiveHandle(handle))
|
|
7429
|
-
throw new StaleRouteHandleError(handle);
|
|
7430
|
-
}
|
|
7431
|
-
allocateCorr() {
|
|
7432
|
-
const maximum = 0xffffffffffffffffn;
|
|
7433
|
-
if (this.nextCorr > maximum) {
|
|
7434
|
-
const error = new SubcError("channel-0 correlation id allocator exhausted", "corr_exhausted");
|
|
7435
|
-
this.fail(error);
|
|
7436
|
-
this.sock.close();
|
|
7437
|
-
this.scheduleReconnectAfterDrop(error);
|
|
7438
|
-
throw error;
|
|
7439
|
-
}
|
|
7440
|
-
const corr = this.nextCorr;
|
|
7441
|
-
this.nextCorr += 1n;
|
|
7442
|
-
return corr;
|
|
7443
|
-
}
|
|
7444
|
-
closeConnectionAfterCleanupFailure() {
|
|
7445
|
-
const error = new SubcError("late route cleanup could not be queued", "late_route_cleanup_failed");
|
|
7446
|
-
this.fail(error);
|
|
7447
|
-
this.sock.close();
|
|
7448
|
-
this.scheduleReconnectAfterDrop(error);
|
|
7449
|
-
}
|
|
7450
|
-
encode(value) {
|
|
7451
|
-
return Buffer.from(JSON.stringify(value), "utf8");
|
|
7452
|
-
}
|
|
7453
|
-
decodeReply(frame) {
|
|
7454
|
-
return hasBinary(frame.header.flags) ? frame.body : this.parseJson(frame);
|
|
7455
|
-
}
|
|
7456
|
-
parseJson(frame) {
|
|
7457
|
-
const b = frame.body;
|
|
7458
|
-
return JSON.parse(Buffer.from(b.buffer, b.byteOffset, b.byteLength).toString("utf8"));
|
|
7459
|
-
}
|
|
7460
|
-
}
|
|
7461
|
-
function isConsumerReconnectTransient(err) {
|
|
7462
|
-
if (err instanceof SocketClosedError || err instanceof SocketTimeoutError)
|
|
7463
|
-
return true;
|
|
7464
|
-
if (err instanceof SocketWriteNotQueuedError || err instanceof SocketWriteQueuedError)
|
|
7465
|
-
return true;
|
|
7466
|
-
if (err instanceof SubcCallError)
|
|
7467
|
-
return err.kind === "not_sent" || err.kind === "outcome_unknown";
|
|
7468
|
-
if (err instanceof AuthError)
|
|
7469
|
-
return true;
|
|
7470
|
-
if (err instanceof SubcError || err instanceof ConnectionFileError)
|
|
7471
|
-
return false;
|
|
7472
|
-
const code = errorCode(err);
|
|
7473
|
-
return code === "ECONNREFUSED" || code === "ECONNRESET" || code === "EPIPE" || code === "ETIMEDOUT" || code === "ENOENT";
|
|
7474
|
-
}
|
|
7475
|
-
function isRouteOpenRefusal(err) {
|
|
7476
|
-
return err instanceof SubcError && typeof err.code === "string";
|
|
7477
|
-
}
|
|
7478
|
-
function isRetryableRouteOpenCode(code) {
|
|
7479
|
-
if (code === "capability_forbidden")
|
|
7480
|
-
return false;
|
|
7481
|
-
return code === "unknown_module" || code === "module_reloading" || code === "module_warming" || code === "target_unavailable" || code === "module_timeout";
|
|
7482
|
-
}
|
|
7483
|
-
async function connectionFileExists(path) {
|
|
7484
|
-
try {
|
|
7485
|
-
await fs2.access(path);
|
|
7486
|
-
return true;
|
|
7487
|
-
} catch {
|
|
7488
|
-
return false;
|
|
7489
|
-
}
|
|
7490
|
-
}
|
|
7491
|
-
function normalizeConnectOptions(opts) {
|
|
7492
|
-
return {
|
|
7493
|
-
connectionFile: opts.connectionFile,
|
|
7494
|
-
handshakeTimeoutMs: opts.handshakeTimeoutMs,
|
|
7495
|
-
identity: opts.identity,
|
|
7496
|
-
targetKind: opts.targetKind ?? DEFAULT_MANAGED_TARGET_KIND,
|
|
7497
|
-
reconnectBackoff: opts.reconnectBackoff ?? DEFAULT_RECONNECT_BACKOFF,
|
|
7498
|
-
sleep: opts.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms))),
|
|
7499
|
-
routeOpenRetryDeadlineMs: opts.routeOpenRetryDeadlineMs ?? ROUTE_OPEN_RETRY_DEADLINE_MS,
|
|
7500
|
-
timeoutArbitrationGraceMs: opts.timeoutArbitrationGraceMs ?? TIMEOUT_ARBITRATION_GRACE_MS,
|
|
7501
|
-
livenessProbeWindowMs: opts.livenessProbeWindowMs ?? LIVENESS_PROBE_WINDOW_MS,
|
|
7502
|
-
onControlPush: opts.onControlPush
|
|
7503
|
-
};
|
|
7504
|
-
}
|
|
7505
|
-
function isValidCapabilityIdentifier(identifier) {
|
|
7506
|
-
if (/\s/u.test(identifier))
|
|
7507
|
-
return false;
|
|
7508
|
-
const separator = identifier.indexOf("/v");
|
|
7509
|
-
if (separator <= 0 || identifier.indexOf("/v", separator + 1) !== -1)
|
|
7510
|
-
return false;
|
|
7511
|
-
const name = identifier.slice(0, separator);
|
|
7512
|
-
const version = identifier.slice(separator + 2);
|
|
7513
|
-
if (new TextEncoder().encode(name).byteLength > 64 || version.length === 0)
|
|
7514
|
-
return false;
|
|
7515
|
-
if (!/^[a-z][a-z0-9-]*[a-z0-9]$/u.test(name) && !/^[a-z]$/u.test(name))
|
|
7516
|
-
return false;
|
|
7517
|
-
if (name.includes("--"))
|
|
7518
|
-
return false;
|
|
7519
|
-
if (!/^\d+$/u.test(version) || version.length > 1 && version.startsWith("0"))
|
|
7520
|
-
return false;
|
|
7521
|
-
const numericVersion = Number(version);
|
|
7522
|
-
return Number.isSafeInteger(numericVersion) && numericVersion >= 1 && numericVersion <= 4294967295;
|
|
7523
|
-
}
|
|
7524
|
-
function routeCacheKey(target, identity, consumerIdentity) {
|
|
7525
|
-
const consumerPart = consumerIdentity ? `${consumerIdentity.module_id}\x00${consumerIdentity.launch_nonce}` : "";
|
|
7526
|
-
return `${target.kind}\x00${target.module_id}\x00${identity.project_root}\x00${identity.harness}\x00${identity.session}\x00${consumerPart}`;
|
|
7527
|
-
}
|
|
7528
|
-
function routeOpenConsumerIdentity(opts = {}) {
|
|
7529
|
-
if (opts.consumerIdentity !== undefined)
|
|
7530
|
-
return opts.consumerIdentity ?? undefined;
|
|
7531
|
-
const moduleId = process.env[SUBC_MODULE_ID_ENV];
|
|
7532
|
-
const launchNonce = process.env[SUBC_LAUNCH_NONCE_ENV];
|
|
7533
|
-
if (!moduleId || !launchNonce)
|
|
7534
|
-
return;
|
|
7535
|
-
return { module_id: moduleId, launch_nonce: launchNonce };
|
|
7536
|
-
}
|
|
7537
|
-
function errorCode(err) {
|
|
7538
|
-
if (typeof err === "object" && err !== null && "code" in err) {
|
|
7539
|
-
const code = err.code;
|
|
7540
|
-
if (typeof code === "string")
|
|
7541
|
-
return code;
|
|
7542
|
-
}
|
|
7543
|
-
return;
|
|
7544
|
-
}
|
|
7545
|
-
function causeMessage(cause) {
|
|
7546
|
-
if (cause === undefined)
|
|
7547
|
-
return "";
|
|
7548
|
-
return `: ${cause instanceof Error ? cause.message : String(cause)}`;
|
|
7549
|
-
}
|
|
7550
|
-
function pendingKey(handle, corr) {
|
|
7551
|
-
return handle ? `${handle.channel}:${handle.epoch}:${corr}` : `0:0:${corr}`;
|
|
7552
|
-
}
|
|
7553
|
-
// src/features/magic-context/memory/embedding-synapse.ts
|
|
7554
|
-
var SYNAPSE_DEFAULT_MODEL = "gte-modernbert-base-f16";
|
|
7555
|
-
var SYNAPSE_DEFAULT_QUERY_TIMEOUT_MS = 3000;
|
|
7556
|
-
var SYNAPSE_DEFAULT_BATCH_TIMEOUT_MS = 120000;
|
|
7557
|
-
var SYNAPSE_CERTIFICATION_REFUSAL_REASONS = new Set([
|
|
7558
|
-
"not_certified",
|
|
7559
|
-
"probe_required",
|
|
7560
|
-
"migration_required"
|
|
7561
|
-
]);
|
|
7562
|
-
var embeddingRowMetadata = new WeakMap;
|
|
7563
|
-
function isSynapseEmbeddingTruncated(vector) {
|
|
7564
|
-
return embeddingRowMetadata.get(vector)?.truncated === true;
|
|
7565
|
-
}
|
|
7566
|
-
function toSynapseLaneDescriptor(metadata) {
|
|
7567
|
-
const tokenBudget = metadata.recommended_token_budget;
|
|
7568
|
-
return {
|
|
7569
|
-
lane: metadata.model,
|
|
7570
|
-
...metadata.device_class ? { device_class: metadata.device_class } : {},
|
|
7571
|
-
max_tokens: metadata.max_tokens,
|
|
7572
|
-
max_tokens_source: metadata.max_tokens_source,
|
|
7573
|
-
...metadata.bucket_ladder ? { bucket_ladder: [...metadata.bucket_ladder] } : {},
|
|
7574
|
-
...metadata.dims ? { dims: metadata.dims } : {},
|
|
7575
|
-
...metadata.dtype ? { dtype: metadata.dtype } : {},
|
|
7576
|
-
...typeof metadata.certified === "boolean" ? { certified: metadata.certified } : {},
|
|
7577
|
-
...metadata.warm_load_cost_hint_ms !== undefined ? { warm_load_cost_hint_ms: metadata.warm_load_cost_hint_ms } : {},
|
|
7578
|
-
...metadata.recommended_batch ? {
|
|
7579
|
-
recommended_batch: {
|
|
7580
|
-
rows: metadata.recommended_batch,
|
|
7581
|
-
...tokenBudget !== undefined ? { token_budget: tokenBudget } : {}
|
|
7582
|
-
}
|
|
7583
|
-
} : {},
|
|
7584
|
-
warm: metadata.max_tokens_source === "runtime_bucket" || metadata.max_tokens_source === "worker_bucket"
|
|
7585
|
-
};
|
|
7586
|
-
}
|
|
7587
|
-
function formatSynapseLaneDescriptor(descriptor) {
|
|
7588
|
-
const certified = descriptor.certified === undefined ? "unknown" : String(descriptor.certified);
|
|
7589
|
-
return `lane=${descriptor.lane}; device_class=${descriptor.device_class ?? "unknown"}; ` + `max_tokens=${descriptor.max_tokens} (${descriptor.max_tokens_source}); ` + `certified=${certified}; warm=${descriptor.warm ? "yes" : "no"}; ` + `warm_load_cost_hint_ms=${descriptor.warm_load_cost_hint_ms ?? "unknown"}`;
|
|
7590
|
-
}
|
|
7591
|
-
|
|
7592
|
-
class SynapseEmbeddingError extends Error {
|
|
7593
|
-
code;
|
|
7594
|
-
retryAfterMs;
|
|
7595
|
-
permanent;
|
|
7596
|
-
refusalReason;
|
|
7597
|
-
constructor(code, message, options) {
|
|
7598
|
-
super(message, options?.cause === undefined ? undefined : { cause: options.cause });
|
|
7599
|
-
this.name = "SynapseEmbeddingError";
|
|
7600
|
-
this.code = code;
|
|
7601
|
-
this.permanent = options?.permanent ?? isPermanentSynapseCode(code);
|
|
7602
|
-
this.retryAfterMs = options?.retryAfterMs ?? (this.permanent ? undefined : 100);
|
|
7603
|
-
this.refusalReason = options?.refusalReason;
|
|
7604
|
-
}
|
|
7605
|
-
}
|
|
7606
|
-
function isPermanentSynapseCode(code) {
|
|
7607
|
-
return code === "artifact_invalid" || code === "substitution_rejected" || code === "not_certified" || code === "probe_required" || code === "idempotency_conflict" || code === "schema_violation" || code === "certification_refused" || code === "needs_reauth";
|
|
7608
|
-
}
|
|
7609
|
-
function asRecord(value) {
|
|
7610
|
-
return value !== null && typeof value === "object" ? value : null;
|
|
7611
|
-
}
|
|
7612
|
-
function responseBody(value) {
|
|
7613
|
-
const record = asRecord(value);
|
|
7614
|
-
const result = asRecord(record?.result);
|
|
7615
|
-
const payload = asRecord(result?.payload ?? record?.payload);
|
|
7616
|
-
return {
|
|
7617
|
-
...record ?? {},
|
|
7618
|
-
...result ?? {},
|
|
7619
|
-
...payload ?? {}
|
|
7620
|
-
};
|
|
7621
|
-
}
|
|
7622
|
-
function readRetryAfter(value) {
|
|
7623
|
-
const record = asRecord(value);
|
|
7624
|
-
const candidate = record?.retry_after_ms ?? record?.retryAfterMs;
|
|
7625
|
-
if (typeof candidate !== "number" || !Number.isFinite(candidate) || candidate < 0)
|
|
7626
|
-
return;
|
|
7627
|
-
return Math.ceil(candidate);
|
|
7628
|
-
}
|
|
7629
|
-
function readErrorCode(value) {
|
|
7630
|
-
const record = asRecord(value);
|
|
7631
|
-
if (typeof record?.code === "string")
|
|
7632
|
-
return record.code;
|
|
7633
|
-
if (value instanceof Error && "code" in value && typeof value.code === "string") {
|
|
7634
|
-
return value.code;
|
|
7635
|
-
}
|
|
7636
|
-
return;
|
|
7637
|
-
}
|
|
7638
|
-
function readCertificationRefusalReason(value) {
|
|
7639
|
-
if (!(value instanceof SubcCallError))
|
|
7640
|
-
return;
|
|
7641
|
-
const detail = value.detail;
|
|
7642
|
-
if (typeof detail === "string")
|
|
7643
|
-
return detail;
|
|
7644
|
-
const record = asRecord(detail);
|
|
7645
|
-
return typeof record?.reason === "string" ? record.reason : undefined;
|
|
7646
|
-
}
|
|
7647
|
-
function classifyError(value) {
|
|
7648
|
-
if (value instanceof SynapseEmbeddingError)
|
|
7649
|
-
return value;
|
|
7650
|
-
const code = readErrorCode(value) ?? (value instanceof Error ? value.name : "transport");
|
|
7651
|
-
const normalized = code.toLowerCase();
|
|
7652
|
-
const refusalReason = readCertificationRefusalReason(value);
|
|
7653
|
-
let mapped = "transport";
|
|
7654
|
-
if (normalized.includes("queue_full"))
|
|
7655
|
-
mapped = "queue_full";
|
|
7656
|
-
else if (normalized.includes("model_loading"))
|
|
7657
|
-
mapped = "model_loading";
|
|
7658
|
-
else if (normalized.includes("timeout") || normalized.includes("deadline"))
|
|
7659
|
-
mapped = "timeout";
|
|
7660
|
-
else if (normalized.includes("artifact_invalid"))
|
|
7661
|
-
mapped = "artifact_invalid";
|
|
7662
|
-
else if (normalized.includes("substitution"))
|
|
7663
|
-
mapped = "substitution_rejected";
|
|
7664
|
-
else if (normalized === "certification_refused")
|
|
7665
|
-
mapped = "certification_refused";
|
|
7666
|
-
else if (normalized.includes("not_certified"))
|
|
7667
|
-
mapped = "not_certified";
|
|
7668
|
-
else if (normalized.includes("probe_required"))
|
|
7669
|
-
mapped = "probe_required";
|
|
7670
|
-
else if (normalized.includes("idempotency_conflict"))
|
|
7671
|
-
mapped = "idempotency_conflict";
|
|
7672
|
-
else if (normalized.includes("needs_reauth"))
|
|
7673
|
-
mapped = "needs_reauth";
|
|
7674
|
-
else if (normalized.includes("schema"))
|
|
7675
|
-
mapped = "schema_violation";
|
|
7676
|
-
else if (normalized.includes("module_restarted") || normalized.includes("module restarted"))
|
|
7677
|
-
mapped = "module_restarted";
|
|
7678
|
-
const message = value instanceof Error ? value.message : String(value);
|
|
7679
|
-
return new SynapseEmbeddingError(mapped, message, {
|
|
7680
|
-
retryAfterMs: readRetryAfter(value) ?? (isPermanentSynapseCode(mapped) ? undefined : 100),
|
|
7681
|
-
cause: value,
|
|
7682
|
-
refusalReason
|
|
7683
|
-
});
|
|
7684
|
-
}
|
|
7685
|
-
function embeddingFailureFor(error) {
|
|
7686
|
-
const typedReason = error.refusalReason;
|
|
7687
|
-
if (typedReason !== undefined && SYNAPSE_CERTIFICATION_REFUSAL_REASONS.has(typedReason) || error.code === "not_certified" || error.code === "probe_required") {
|
|
7688
|
-
return {
|
|
7689
|
-
class: "certification_refusal",
|
|
7690
|
-
reason: `SYNAPSE certification refused embedding: ${typedReason ?? error.code}`,
|
|
7691
|
-
retryable: false
|
|
7692
|
-
};
|
|
7693
|
-
}
|
|
7694
|
-
if (error.code === "certification_refused") {
|
|
7695
|
-
return {
|
|
7696
|
-
class: "certification_refusal",
|
|
7697
|
-
reason: `SYNAPSE certification refused embedding: ${typedReason ?? "unknown reason"}`,
|
|
7698
|
-
retryable: false
|
|
7699
|
-
};
|
|
7700
|
-
}
|
|
7701
|
-
if (typedReason === "needs_reauth" || typedReason === "needs_reauth_expired") {
|
|
7702
|
-
return {
|
|
7703
|
-
class: "credential_required",
|
|
7704
|
-
reason: "SYNAPSE requires reauthentication",
|
|
7705
|
-
retryable: false
|
|
7706
|
-
};
|
|
7707
|
-
}
|
|
7708
|
-
if (error.code === "substitution_rejected") {
|
|
7709
|
-
return { class: "substitution_rejected", reason: error.message, retryable: false };
|
|
7710
|
-
}
|
|
7711
|
-
if (error.code === "schema_violation" || error.code === "artifact_invalid") {
|
|
7712
|
-
return { class: "invalid_envelope", reason: error.message, retryable: false };
|
|
7713
|
-
}
|
|
7714
|
-
return { class: "transport_error", reason: error.message, retryable: !error.permanent };
|
|
7715
|
-
}
|
|
7716
|
-
function wait(ms) {
|
|
7717
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
7718
|
-
}
|
|
7719
|
-
function sha256(value) {
|
|
7720
|
-
return createHash("sha256").update(value).digest("hex");
|
|
7721
|
-
}
|
|
7722
|
-
function stableJson(value) {
|
|
7723
|
-
if (Array.isArray(value))
|
|
7724
|
-
return `[${value.map(stableJson).join(",")}]`;
|
|
7725
|
-
if (value && typeof value === "object") {
|
|
7726
|
-
return `{${Object.entries(value).sort(([left], [right]) => left.localeCompare(right)).map(([key, entry]) => `${JSON.stringify(key)}:${stableJson(entry)}`).join(",")}}`;
|
|
7727
|
-
}
|
|
7728
|
-
return JSON.stringify(value);
|
|
7729
|
-
}
|
|
7730
|
-
function getSynapseLaneIdentity(model, fingerprint) {
|
|
7731
|
-
return `synapse:v1:${sha256(stableJson({ model, fingerprint }))}`;
|
|
7732
|
-
}
|
|
7733
|
-
function getSynapseBatchRequestKey(args) {
|
|
7734
|
-
return sha256(stableJson({
|
|
7735
|
-
op: "embed.batch",
|
|
7736
|
-
model: args.model,
|
|
7737
|
-
required_fingerprint: args.fingerprint,
|
|
7738
|
-
required_epoch: args.tableEpoch,
|
|
7739
|
-
allow_equivalent: false,
|
|
7740
|
-
accept_declared: false,
|
|
7741
|
-
ids: args.items.map((item) => item.id),
|
|
7742
|
-
content_sha256: args.items.map((item) => item.contentSha256),
|
|
7743
|
-
...args.purpose === "query" ? { purpose: args.purpose } : {}
|
|
7744
|
-
}));
|
|
7745
|
-
}
|
|
7746
|
-
function hashContent(text) {
|
|
7747
|
-
return sha256(text);
|
|
7748
|
-
}
|
|
7749
|
-
function extractCatalogEntries(value) {
|
|
7750
|
-
const body = responseBody(value);
|
|
7751
|
-
const raw = Array.isArray(body.models) ? body.models : Array.isArray(body.entries) ? body.entries : Array.isArray(value) ? value : [];
|
|
7752
|
-
const envelopeEpoch = typeof body.table_epoch === "number" && Number.isInteger(body.table_epoch) ? body.table_epoch : undefined;
|
|
7753
|
-
const maxTokenSources = new Set([
|
|
7754
|
-
"runtime_bucket",
|
|
7755
|
-
"worker_bucket",
|
|
7756
|
-
"catalog",
|
|
7757
|
-
"catalog_unloaded"
|
|
7758
|
-
]);
|
|
7759
|
-
return raw.flatMap((entry) => {
|
|
7760
|
-
const record = asRecord(entry);
|
|
7761
|
-
if (!record)
|
|
7762
|
-
return [];
|
|
7763
|
-
const model = typeof record.model === "string" && record.model.length > 0 ? record.model : typeof record.model_id === "string" ? record.model_id : "";
|
|
7764
|
-
const fingerprint = typeof record.fingerprint === "string" && record.fingerprint.length > 0 ? record.fingerprint : Array.isArray(record.fingerprints) && typeof record.fingerprints[0] === "string" ? record.fingerprints[0] : "";
|
|
7765
|
-
const entryEpoch = record.table_epoch ?? record.tableEpoch;
|
|
7766
|
-
const tableEpoch = typeof entryEpoch === "number" && Number.isInteger(entryEpoch) ? entryEpoch : envelopeEpoch;
|
|
7767
|
-
const maxTokens = record.max_tokens;
|
|
7768
|
-
const maxTokensSource = record.max_tokens_source;
|
|
7769
|
-
if (model.length === 0 || fingerprint.length === 0 || typeof tableEpoch !== "number" || !Number.isInteger(tableEpoch) || typeof maxTokens !== "number" || !Number.isInteger(maxTokens) || maxTokens <= 0 || typeof maxTokensSource !== "string" || !maxTokenSources.has(maxTokensSource)) {
|
|
7770
|
-
return [];
|
|
7771
|
-
}
|
|
7772
|
-
const dims = record.dims ?? record.dimensions;
|
|
7773
|
-
const rawBatch = record.recommended_batch ?? record.recommendedBatch;
|
|
7774
|
-
const batchRecord = asRecord(rawBatch);
|
|
7775
|
-
const recommendedBatch = typeof rawBatch === "number" ? rawBatch : batchRecord ? batchRecord.rows : undefined;
|
|
7776
|
-
const recommendedTokenBudget = batchRecord ? batchRecord.token_budget : undefined;
|
|
7777
|
-
const bucketLadder = Array.isArray(record.bucket_ladder) ? record.bucket_ladder.filter((bucket) => typeof bucket === "number" && Number.isInteger(bucket) && bucket > 0) : undefined;
|
|
7778
|
-
const state = typeof record.state === "string" ? record.state : undefined;
|
|
7779
|
-
const warmLoadCostHint = record.warm_load_cost_hint_ms;
|
|
7780
|
-
return [
|
|
7781
|
-
{
|
|
7782
|
-
model,
|
|
7783
|
-
fingerprint,
|
|
7784
|
-
table_epoch: tableEpoch,
|
|
7785
|
-
max_tokens: maxTokens,
|
|
7786
|
-
max_tokens_source: maxTokensSource,
|
|
7787
|
-
...bucketLadder && bucketLadder.length > 0 ? { bucket_ladder: [...new Set(bucketLadder)].sort((a, b) => a - b) } : {},
|
|
7788
|
-
...typeof dims === "number" && Number.isInteger(dims) && dims > 0 ? { dims } : {},
|
|
7789
|
-
...typeof record.dtype === "string" && record.dtype.length > 0 ? { dtype: record.dtype } : {},
|
|
7790
|
-
...typeof record.device_class === "string" && record.device_class.length > 0 ? { device_class: record.device_class } : {},
|
|
7791
|
-
...typeof recommendedBatch === "number" && recommendedBatch > 0 ? { recommended_batch: Math.floor(recommendedBatch) } : {},
|
|
7792
|
-
...typeof recommendedTokenBudget === "number" && recommendedTokenBudget > 0 ? { recommended_token_budget: Math.floor(recommendedTokenBudget) } : {},
|
|
7793
|
-
...record.provenance !== undefined ? { provenance: record.provenance } : {},
|
|
7794
|
-
...typeof record.certified === "boolean" ? { certified: record.certified } : {},
|
|
7795
|
-
...typeof warmLoadCostHint === "number" && Number.isFinite(warmLoadCostHint) && warmLoadCostHint >= 0 ? { warm_load_cost_hint_ms: warmLoadCostHint } : {},
|
|
7796
|
-
...typeof record.status === "string" ? { status: record.status } : state ? { status: state } : {}
|
|
7797
|
-
}
|
|
7798
|
-
];
|
|
7799
|
-
});
|
|
7800
|
-
}
|
|
7801
|
-
function extractVector(value) {
|
|
7802
|
-
const body = responseBody(value);
|
|
7803
|
-
const item = Array.isArray(body.vectors) ? asRecord(body.vectors[0]) : null;
|
|
7804
|
-
const raw = item?.vector;
|
|
7805
|
-
if (!item || !Array.isArray(raw) || raw.some((component) => typeof component !== "number" || !Number.isFinite(component))) {
|
|
7806
|
-
return null;
|
|
7807
|
-
}
|
|
7808
|
-
const disclosure = Array.isArray(body.truncation_disclosures) ? asRecord(body.truncation_disclosures[0]) : null;
|
|
7809
|
-
return { vector: Float32Array.from(raw), item, disclosure, metadata: body };
|
|
7810
|
-
}
|
|
7811
|
-
function extractBatchItems(value) {
|
|
7812
|
-
const body = responseBody(value);
|
|
7813
|
-
const raw = Array.isArray(body.vectors) ? body.vectors : Array.isArray(body.items) ? body.items : Array.isArray(body.results) ? body.results : [];
|
|
7814
|
-
return raw.flatMap((item) => {
|
|
7815
|
-
const record = asRecord(item);
|
|
7816
|
-
return record ? [record] : [];
|
|
7817
|
-
});
|
|
7818
|
-
}
|
|
7819
|
-
function extractTruncationDisclosures(value) {
|
|
7820
|
-
const body = responseBody(value);
|
|
7821
|
-
if (!Array.isArray(body.truncation_disclosures))
|
|
7822
|
-
return [];
|
|
7823
|
-
return body.truncation_disclosures.map((disclosure) => asRecord(disclosure));
|
|
7824
|
-
}
|
|
7825
|
-
function validateWireRow(item, disclosure, expected) {
|
|
7826
|
-
const submittedSha256 = item.submitted_sha256;
|
|
7827
|
-
const contentSha256 = item.content_sha256;
|
|
7828
|
-
const expectedSubmittedSha256 = hashContent(expected.text);
|
|
7829
|
-
if (typeof submittedSha256 !== "string") {
|
|
7830
|
-
throw new SynapseEmbeddingError("schema_violation", `Synapse item ${expected.id} omitted submitted_sha256`);
|
|
7831
|
-
}
|
|
7832
|
-
if (submittedSha256 !== expectedSubmittedSha256) {
|
|
7833
|
-
throw new SynapseEmbeddingError("schema_violation", `Synapse submitted hash mismatch for item ${expected.id}`);
|
|
7834
|
-
}
|
|
7835
|
-
if (typeof contentSha256 !== "string") {
|
|
7836
|
-
throw new SynapseEmbeddingError("schema_violation", `Synapse item ${expected.id} omitted content_sha256`);
|
|
7837
|
-
}
|
|
7838
|
-
const hashesDiffer = contentSha256 !== submittedSha256;
|
|
7839
|
-
const disclosedTruncation = disclosure?.truncated === true;
|
|
7840
|
-
const effectiveTokens = disclosure?.effective_tokens;
|
|
7841
|
-
if (disclosure && (typeof disclosure.truncated !== "boolean" || typeof effectiveTokens !== "number" || !Number.isInteger(effectiveTokens) || effectiveTokens < 0)) {
|
|
7842
|
-
throw new SynapseEmbeddingError("schema_violation", `Synapse item ${expected.id} returned an invalid truncation disclosure`);
|
|
7843
|
-
}
|
|
7844
|
-
if (hashesDiffer) {
|
|
7845
|
-
if (!disclosedTruncation || typeof effectiveTokens !== "number" || !Number.isInteger(effectiveTokens) || effectiveTokens < 0) {
|
|
7846
|
-
throw new SynapseEmbeddingError("schema_violation", `Synapse item ${expected.id} changed content without a valid truncation disclosure`);
|
|
7847
|
-
}
|
|
7848
|
-
} else if (disclosedTruncation) {
|
|
7849
|
-
throw new SynapseEmbeddingError("schema_violation", `Synapse item ${expected.id} disclosed truncation but returned matching hashes`);
|
|
7850
|
-
}
|
|
7851
|
-
return {
|
|
7852
|
-
truncated: hashesDiffer,
|
|
7853
|
-
submittedSha256,
|
|
7854
|
-
contentSha256,
|
|
7855
|
-
...typeof effectiveTokens === "number" && Number.isInteger(effectiveTokens) && effectiveTokens >= 0 ? { effectiveTokens } : {}
|
|
7856
|
-
};
|
|
7857
|
-
}
|
|
7858
|
-
var sharedClient = null;
|
|
7859
|
-
var sharedClientFile = null;
|
|
7860
|
-
var sharedClientPromise = null;
|
|
7861
|
-
var factoryClients = new WeakMap;
|
|
7862
|
-
async function getSharedClient(options) {
|
|
7863
|
-
if (options.clientFactory) {
|
|
7864
|
-
let promise = factoryClients.get(options.clientFactory);
|
|
7865
|
-
if (!promise) {
|
|
7866
|
-
promise = options.clientFactory();
|
|
7867
|
-
factoryClients.set(options.clientFactory, promise);
|
|
7868
|
-
}
|
|
7869
|
-
return promise;
|
|
7870
|
-
}
|
|
7871
|
-
if (sharedClient && sharedClientFile === options.connectionFile)
|
|
7872
|
-
return sharedClient;
|
|
7873
|
-
if (sharedClientPromise && sharedClientFile === options.connectionFile)
|
|
7874
|
-
return sharedClientPromise;
|
|
7875
|
-
sharedClientFile = options.connectionFile;
|
|
7876
|
-
sharedClientPromise = SubcClient.connect({ connectionFile: options.connectionFile }).then((client) => {
|
|
7877
|
-
sharedClient = client;
|
|
7878
|
-
return client;
|
|
7879
|
-
});
|
|
7880
|
-
return sharedClientPromise;
|
|
7881
|
-
}
|
|
7882
|
-
|
|
7883
|
-
class SynapseEmbeddingProvider {
|
|
7884
|
-
modelId;
|
|
7885
|
-
metadata;
|
|
7886
|
-
get maxInputTokens() {
|
|
7887
|
-
return this.metadata?.max_tokens;
|
|
7888
|
-
}
|
|
7889
|
-
options;
|
|
7890
|
-
client = null;
|
|
7891
|
-
initialized = false;
|
|
7892
|
-
initializing = null;
|
|
7893
|
-
permanentFailure = false;
|
|
7894
|
-
lastFailureReason = null;
|
|
7895
|
-
batchLimit = 16;
|
|
7896
|
-
tokenBudget = null;
|
|
7897
|
-
constructor(options) {
|
|
7898
|
-
this.options = options;
|
|
7899
|
-
const model = options.model || SYNAPSE_DEFAULT_MODEL;
|
|
7900
|
-
const fingerprint = options.fingerprint ?? "";
|
|
7901
|
-
const descriptor = options.descriptor;
|
|
7902
|
-
this.metadata = options.metadata ? {
|
|
7903
|
-
...options.metadata,
|
|
7904
|
-
bucket_ladder: options.metadata.bucket_ladder ? [...options.metadata.bucket_ladder] : undefined
|
|
7905
|
-
} : fingerprint && Number.isInteger(options.tableEpoch) && descriptor ? {
|
|
7906
|
-
model,
|
|
7907
|
-
fingerprint,
|
|
7908
|
-
table_epoch: options.tableEpoch,
|
|
7909
|
-
max_tokens: descriptor.max_tokens,
|
|
7910
|
-
max_tokens_source: descriptor.max_tokens_source,
|
|
7911
|
-
...descriptor.bucket_ladder ? { bucket_ladder: [...descriptor.bucket_ladder] } : {},
|
|
7912
|
-
...options.dims ?? descriptor.dims ? { dims: options.dims ?? descriptor.dims } : {},
|
|
7913
|
-
...descriptor.dtype ? { dtype: descriptor.dtype } : {},
|
|
7914
|
-
...descriptor.device_class ? { device_class: descriptor.device_class } : {},
|
|
7915
|
-
...options.recommendedBatch ?? descriptor.recommended_batch?.rows ? {
|
|
7916
|
-
recommended_batch: Math.max(1, Math.floor(options.recommendedBatch ?? descriptor.recommended_batch?.rows))
|
|
7917
|
-
} : {},
|
|
7918
|
-
...options.recommendedTokenBudget ?? descriptor.recommended_batch?.token_budget ? {
|
|
7919
|
-
recommended_token_budget: Math.max(1, Math.floor(options.recommendedTokenBudget ?? descriptor.recommended_batch?.token_budget))
|
|
7920
|
-
} : {},
|
|
7921
|
-
...options.provenance !== undefined ? { provenance: options.provenance } : {},
|
|
7922
|
-
...typeof descriptor.certified === "boolean" ? { certified: descriptor.certified } : {},
|
|
7923
|
-
...descriptor.warm_load_cost_hint_ms !== undefined ? { warm_load_cost_hint_ms: descriptor.warm_load_cost_hint_ms } : {},
|
|
7924
|
-
laneIdentity: getSynapseLaneIdentity(model, fingerprint)
|
|
7925
|
-
} : null;
|
|
7926
|
-
this.modelId = this.metadata?.laneIdentity ?? "synapse:v1:pending";
|
|
7927
|
-
this.batchLimit = this.metadata?.recommended_batch ?? 16;
|
|
7928
|
-
this.tokenBudget = this.metadata?.recommended_token_budget ?? null;
|
|
7929
|
-
}
|
|
7930
|
-
nextPage(items, start) {
|
|
7931
|
-
const hardEnd = Math.min(items.length, start + this.batchLimit);
|
|
7932
|
-
if (this.tokenBudget === null)
|
|
7933
|
-
return items.slice(start, hardEnd);
|
|
7934
|
-
let end = start;
|
|
7935
|
-
let tokens = 0;
|
|
7936
|
-
while (end < hardEnd) {
|
|
7937
|
-
tokens += estimateTokens(items[end].text);
|
|
7938
|
-
if (tokens > this.tokenBudget && end > start)
|
|
7939
|
-
break;
|
|
7940
|
-
end += 1;
|
|
7941
|
-
}
|
|
7942
|
-
return items.slice(start, Math.max(end, start + 1));
|
|
7943
|
-
}
|
|
7944
|
-
static async discover(options) {
|
|
7945
|
-
const provider = new SynapseEmbeddingProvider(options);
|
|
7946
|
-
if (!await provider.initialize() || !provider.metadata) {
|
|
7947
|
-
throw new SynapseEmbeddingError("not_certified", "Synapse lane is not ready");
|
|
7948
|
-
}
|
|
7949
|
-
return provider.metadata;
|
|
7950
|
-
}
|
|
7951
|
-
async initialize() {
|
|
7952
|
-
if (this.initialized)
|
|
7953
|
-
return true;
|
|
7954
|
-
if (this.permanentFailure)
|
|
7955
|
-
return false;
|
|
7956
|
-
if (this.initializing)
|
|
7957
|
-
return this.initializing;
|
|
7958
|
-
this.initializing = (async () => {
|
|
7959
|
-
try {
|
|
7960
|
-
if (!this.options.clientFactory && !await connectionFileExists(this.options.connectionFile)) {
|
|
7961
|
-
throw new SynapseEmbeddingError("transport", `Synapse connection file is unavailable: ${this.options.connectionFile}`);
|
|
7962
|
-
}
|
|
7963
|
-
this.client = await getSharedClient(this.options);
|
|
7964
|
-
if (!this.metadata) {
|
|
7965
|
-
const discovered = await this.callWithRetry("models.list", {}, this.options.queryTimeoutMs ?? SYNAPSE_DEFAULT_QUERY_TIMEOUT_MS, false);
|
|
7966
|
-
const entries = extractCatalogEntries(discovered);
|
|
7967
|
-
const requested = this.options.model?.trim() || SYNAPSE_DEFAULT_MODEL;
|
|
7968
|
-
const entry = entries.find((candidate) => candidate.model === requested);
|
|
7969
|
-
if (!entry) {
|
|
7970
|
-
throw new SynapseEmbeddingError("artifact_invalid", `Synapse models.list did not return requested model ${requested}`);
|
|
7971
|
-
}
|
|
7972
|
-
if (entry.certified === false || entry.status === "not_certified") {
|
|
7973
|
-
throw new SynapseEmbeddingError("not_certified", `Synapse model ${entry.model} is not certified`);
|
|
7974
|
-
}
|
|
7975
|
-
const metadata = {
|
|
7976
|
-
...entry,
|
|
7977
|
-
laneIdentity: getSynapseLaneIdentity(entry.model, entry.fingerprint)
|
|
7978
|
-
};
|
|
7979
|
-
this.metadata = metadata;
|
|
7980
|
-
this.modelId = metadata.laneIdentity;
|
|
7981
|
-
this.batchLimit = metadata.recommended_batch ?? this.batchLimit;
|
|
7982
|
-
this.tokenBudget = metadata.recommended_token_budget ?? this.tokenBudget;
|
|
7983
|
-
}
|
|
7984
|
-
this.initialized = true;
|
|
7985
|
-
this.recordSuccess();
|
|
7986
|
-
return true;
|
|
7987
|
-
} catch (error) {
|
|
7988
|
-
const classified = classifyError(error);
|
|
7989
|
-
this.recordFailure(classified);
|
|
7990
|
-
if (classified.permanent) {
|
|
7991
|
-
this.permanentFailure = true;
|
|
7992
|
-
log(`[magic-context] Synapse lane disabled: ${classified.code}: ${classified.message}`);
|
|
7993
|
-
} else {
|
|
7994
|
-
log(`[magic-context] Synapse lane unavailable: ${classified.message}`);
|
|
7995
|
-
}
|
|
7996
|
-
this.initialized = false;
|
|
7997
|
-
return false;
|
|
7998
|
-
} finally {
|
|
7999
|
-
this.initializing = null;
|
|
8000
|
-
}
|
|
8001
|
-
})();
|
|
8002
|
-
return this.initializing;
|
|
8003
|
-
}
|
|
8004
|
-
async embed(text, signal, purpose = "passage") {
|
|
8005
|
-
if (!await this.initialize() || signal?.aborted || !this.metadata)
|
|
8006
|
-
return null;
|
|
8007
|
-
if (estimateTokens(text) > this.metadata.max_tokens)
|
|
8008
|
-
return null;
|
|
8009
|
-
try {
|
|
8010
|
-
const id = "query";
|
|
8011
|
-
const value = await this.callWithRetry("embed.query", this.requestConstraints({
|
|
8012
|
-
id,
|
|
8013
|
-
text,
|
|
8014
|
-
purpose,
|
|
8015
|
-
deadline_ms: this.options.queryTimeoutMs ?? SYNAPSE_DEFAULT_QUERY_TIMEOUT_MS
|
|
8016
|
-
}), this.options.queryTimeoutMs ?? SYNAPSE_DEFAULT_QUERY_TIMEOUT_MS, true, signal);
|
|
8017
|
-
const extracted = extractVector(value);
|
|
8018
|
-
if (!extracted) {
|
|
8019
|
-
throw new SynapseEmbeddingError("schema_violation", "Synapse query returned no vector row");
|
|
8020
|
-
}
|
|
8021
|
-
if (extracted.item.id !== id) {
|
|
8022
|
-
throw new SynapseEmbeddingError("schema_violation", `Synapse query returned unexpected item ${String(extracted.item.id)}`);
|
|
8023
|
-
}
|
|
8024
|
-
const rowMetadata = validateWireRow(extracted.item, extracted.disclosure, { id, text });
|
|
8025
|
-
this.validateResponse(extracted.metadata, extracted.vector.length);
|
|
8026
|
-
embeddingRowMetadata.set(extracted.vector, rowMetadata);
|
|
8027
|
-
this.recordSuccess();
|
|
8028
|
-
return extracted.vector;
|
|
8029
|
-
} catch (error) {
|
|
8030
|
-
this.logCallFailure(error, "embed.query");
|
|
8031
|
-
return null;
|
|
8032
|
-
}
|
|
8033
|
-
}
|
|
8034
|
-
async embedBatch(texts, signal, purpose = "passage") {
|
|
8035
|
-
if (texts.length === 0)
|
|
8036
|
-
return [];
|
|
8037
|
-
const items = texts.map((text, index) => ({
|
|
8038
|
-
id: `item:${index}`,
|
|
8039
|
-
text,
|
|
8040
|
-
contentSha256: hashContent(text)
|
|
8041
|
-
}));
|
|
8042
|
-
const map = await this.embedItems(items, signal, purpose);
|
|
8043
|
-
return items.map((item) => map.get(item.id) ?? null);
|
|
8044
|
-
}
|
|
8045
|
-
async embedItems(items, signal, purpose = "passage") {
|
|
8046
|
-
const output = new Map;
|
|
8047
|
-
if (items.length === 0 || !await this.initialize() || !this.metadata || signal?.aborted) {
|
|
8048
|
-
return output;
|
|
8049
|
-
}
|
|
8050
|
-
const maxTokens = this.metadata.max_tokens;
|
|
8051
|
-
const eligibleItems = items.filter((item) => estimateTokens(item.text) <= maxTokens).map((item) => ({ ...item, contentSha256: hashContent(item.text) }));
|
|
8052
|
-
for (let start = 0;start < eligibleItems.length; ) {
|
|
8053
|
-
if (signal?.aborted || this.permanentFailure)
|
|
8054
|
-
break;
|
|
8055
|
-
const page = this.nextPage(eligibleItems, start);
|
|
8056
|
-
start += page.length;
|
|
8057
|
-
try {
|
|
8058
|
-
const requestKey = this.requestKey(page, purpose);
|
|
8059
|
-
let body = {};
|
|
8060
|
-
let restarted = false;
|
|
8061
|
-
for (;; ) {
|
|
8062
|
-
try {
|
|
8063
|
-
body = await this.callWithRetry("embed.batch", this.batchRequest(page, requestKey, purpose), this.options.batchTimeoutMs ?? SYNAPSE_DEFAULT_BATCH_TIMEOUT_MS, true, signal);
|
|
8064
|
-
const first = responseBody(body);
|
|
8065
|
-
const jobId = typeof first.job_id === "string" ? first.job_id : null;
|
|
8066
|
-
if (jobId)
|
|
8067
|
-
body = await this.pollBatch(jobId, requestKey, signal);
|
|
8068
|
-
break;
|
|
8069
|
-
} catch (error) {
|
|
8070
|
-
const classified = classifyError(error);
|
|
8071
|
-
if (classified.code !== "module_restarted" || restarted)
|
|
8072
|
-
throw classified;
|
|
8073
|
-
restarted = true;
|
|
8074
|
-
}
|
|
8075
|
-
}
|
|
8076
|
-
const batchEnvelope = responseBody(body);
|
|
8077
|
-
const disclosures = extractTruncationDisclosures(body);
|
|
8078
|
-
for (const [index, item] of extractBatchItems(body).entries()) {
|
|
8079
|
-
const id = typeof item.id === "string" ? item.id : "";
|
|
8080
|
-
const vector = item.vector ?? item.embedding;
|
|
8081
|
-
if (!id || !Array.isArray(vector) || vector.some((component) => typeof component !== "number" || !Number.isFinite(component))) {
|
|
8082
|
-
throw new SynapseEmbeddingError("schema_violation", "Synapse batch item is malformed");
|
|
8083
|
-
}
|
|
8084
|
-
const expected = page.find((candidate) => candidate.id === id);
|
|
8085
|
-
if (!expected) {
|
|
8086
|
-
throw new SynapseEmbeddingError("schema_violation", `Synapse returned unknown item ${id}`);
|
|
8087
|
-
}
|
|
8088
|
-
const rowMetadata = validateWireRow(item, disclosures[index] ?? null, expected);
|
|
8089
|
-
const vectorArray = Float32Array.from(vector);
|
|
8090
|
-
this.validateResponse({ ...batchEnvelope, ...item }, vectorArray.length);
|
|
8091
|
-
embeddingRowMetadata.set(vectorArray, rowMetadata);
|
|
8092
|
-
output.set(id, vectorArray);
|
|
8093
|
-
this.recordSuccess();
|
|
8094
|
-
}
|
|
8095
|
-
} catch (error) {
|
|
8096
|
-
const classified = classifyError(error);
|
|
8097
|
-
this.logCallFailure(classified, "embed.batch");
|
|
8098
|
-
if (classified.code === "idempotency_conflict" || classified.code === "schema_violation") {
|
|
8099
|
-
throw classified;
|
|
8100
|
-
}
|
|
8101
|
-
if (classified.permanent) {
|
|
8102
|
-
this.permanentFailure = true;
|
|
8103
|
-
this.initialized = false;
|
|
8104
|
-
break;
|
|
8105
|
-
}
|
|
8106
|
-
}
|
|
8107
|
-
}
|
|
8108
|
-
return output;
|
|
8109
|
-
}
|
|
8110
|
-
async dispose() {
|
|
8111
|
-
this.initialized = false;
|
|
8112
|
-
this.client = null;
|
|
8113
|
-
}
|
|
8114
|
-
isLoaded() {
|
|
8115
|
-
return this.initialized;
|
|
8116
|
-
}
|
|
8117
|
-
getLastFailureReason() {
|
|
8118
|
-
return this.lastFailureReason;
|
|
8119
|
-
}
|
|
8120
|
-
requestConstraints(extra) {
|
|
8121
|
-
const metadata = this.metadata;
|
|
8122
|
-
if (!metadata)
|
|
8123
|
-
return extra;
|
|
8124
|
-
return {
|
|
8125
|
-
...extra,
|
|
8126
|
-
model: metadata.model,
|
|
8127
|
-
required_fingerprint: metadata.fingerprint,
|
|
8128
|
-
required_epoch: metadata.table_epoch,
|
|
8129
|
-
allow_equivalent: false,
|
|
8130
|
-
accept_declared: false
|
|
8131
|
-
};
|
|
8132
|
-
}
|
|
8133
|
-
batchRequest(items, requestKey, purpose) {
|
|
8134
|
-
return this.requestConstraints({
|
|
8135
|
-
items: items.map((item) => ({
|
|
8136
|
-
id: item.id,
|
|
8137
|
-
text: item.text,
|
|
8138
|
-
content_sha256: item.contentSha256
|
|
8139
|
-
})),
|
|
8140
|
-
request_key: requestKey,
|
|
8141
|
-
purpose
|
|
8142
|
-
});
|
|
8143
|
-
}
|
|
8144
|
-
requestKey(items, purpose) {
|
|
8145
|
-
if (!this.metadata)
|
|
8146
|
-
throw new SynapseEmbeddingError("transport", "Synapse metadata is unavailable");
|
|
8147
|
-
return getSynapseBatchRequestKey({
|
|
8148
|
-
model: this.metadata.model,
|
|
8149
|
-
fingerprint: this.metadata.fingerprint,
|
|
8150
|
-
tableEpoch: this.metadata.table_epoch,
|
|
8151
|
-
items,
|
|
8152
|
-
purpose
|
|
8153
|
-
});
|
|
8154
|
-
}
|
|
8155
|
-
async pollBatch(jobId, requestKey, signal) {
|
|
8156
|
-
let cursor = null;
|
|
8157
|
-
const allItems = [];
|
|
8158
|
-
const allDisclosures = [];
|
|
8159
|
-
for (;; ) {
|
|
8160
|
-
if (signal?.aborted)
|
|
8161
|
-
return {};
|
|
8162
|
-
const body = await this.callWithRetry("embed.result", this.requestConstraints({
|
|
8163
|
-
job_id: jobId,
|
|
8164
|
-
cursor,
|
|
8165
|
-
request_key: requestKey
|
|
8166
|
-
}), this.options.batchTimeoutMs ?? SYNAPSE_DEFAULT_BATCH_TIMEOUT_MS, true, signal);
|
|
8167
|
-
const parsed = responseBody(body);
|
|
8168
|
-
const items = extractBatchItems(body);
|
|
8169
|
-
const disclosures = extractTruncationDisclosures(body);
|
|
8170
|
-
allItems.push(...items);
|
|
8171
|
-
allDisclosures.push(...items.map((_, index) => disclosures[index] ?? null));
|
|
8172
|
-
const nextCursor = parsed.next_cursor ?? parsed.cursor;
|
|
8173
|
-
const done = parsed.done === true || parsed.complete === true || nextCursor === undefined || nextCursor === null;
|
|
8174
|
-
if (done) {
|
|
8175
|
-
return {
|
|
8176
|
-
...parsed,
|
|
8177
|
-
vectors: allItems,
|
|
8178
|
-
truncation_disclosures: allDisclosures
|
|
8179
|
-
};
|
|
8180
|
-
}
|
|
8181
|
-
cursor = nextCursor;
|
|
8182
|
-
}
|
|
8183
|
-
}
|
|
8184
|
-
async callWithRetry(method, params, timeoutMs, retryEmbeddings, signal) {
|
|
8185
|
-
let attempt = 0;
|
|
8186
|
-
for (;; ) {
|
|
8187
|
-
if (signal?.aborted)
|
|
8188
|
-
throw new SynapseEmbeddingError("transport", "Synapse request aborted");
|
|
8189
|
-
try {
|
|
8190
|
-
if (!this.client)
|
|
8191
|
-
throw new SynapseEmbeddingError("transport", "Synapse client is unavailable");
|
|
8192
|
-
return await this.client.call(this.options.moduleId ?? "synapse", method, params, {
|
|
8193
|
-
timeoutMs,
|
|
8194
|
-
targetKind: "management_surface",
|
|
8195
|
-
identity: {
|
|
8196
|
-
project_root: this.options.projectRoot,
|
|
8197
|
-
harness: getHarness(),
|
|
8198
|
-
session: this.options.session
|
|
8199
|
-
}
|
|
8200
|
-
});
|
|
8201
|
-
} catch (error) {
|
|
8202
|
-
const classified = classifyError(error);
|
|
8203
|
-
if (classified.code === "idempotency_conflict")
|
|
8204
|
-
throw classified;
|
|
8205
|
-
const outcomeUnknown = error instanceof SubcCallError && error.kind === "outcome_unknown";
|
|
8206
|
-
const retryable = !classified.permanent && (retryEmbeddings || !outcomeUnknown);
|
|
8207
|
-
if (!retryable || attempt >= 3)
|
|
8208
|
-
throw classified;
|
|
8209
|
-
const delay = classified.retryAfterMs ?? Math.min(2000, 100 * 2 ** attempt);
|
|
8210
|
-
attempt += 1;
|
|
8211
|
-
await wait(delay);
|
|
8212
|
-
}
|
|
8213
|
-
}
|
|
8214
|
-
}
|
|
8215
|
-
validateResponse(body, dims) {
|
|
8216
|
-
const metadata = this.metadata;
|
|
8217
|
-
if (!metadata) {
|
|
8218
|
-
throw new SynapseEmbeddingError("artifact_invalid", "Synapse lane metadata missing");
|
|
8219
|
-
}
|
|
8220
|
-
if (metadata.dims === undefined) {
|
|
8221
|
-
const envelopeDims = body.dims;
|
|
8222
|
-
if (typeof envelopeDims === "number" && envelopeDims !== dims) {
|
|
8223
|
-
throw new SynapseEmbeddingError("artifact_invalid", `Synapse envelope declares ${envelopeDims} dimensions but the vector has ${dims}`);
|
|
8224
|
-
}
|
|
8225
|
-
metadata.dims = dims;
|
|
8226
|
-
}
|
|
8227
|
-
if (dims !== metadata.dims) {
|
|
8228
|
-
throw new SynapseEmbeddingError("artifact_invalid", `Synapse returned ${dims} dimensions, expected ${metadata.dims}`);
|
|
8229
|
-
}
|
|
8230
|
-
const fingerprint = body.fingerprint ?? body.served_fingerprint;
|
|
8231
|
-
if (typeof fingerprint !== "string") {
|
|
8232
|
-
throw new SynapseEmbeddingError("artifact_invalid", "Synapse response omitted the served fingerprint");
|
|
8233
|
-
}
|
|
8234
|
-
if (fingerprint !== metadata.fingerprint) {
|
|
8235
|
-
throw new SynapseEmbeddingError("substitution_rejected", `Synapse fingerprint changed from ${metadata.fingerprint} to ${fingerprint}`);
|
|
8236
|
-
}
|
|
8237
|
-
const epoch = body.table_epoch ?? body.tableEpoch;
|
|
8238
|
-
if (typeof epoch !== "number") {
|
|
8239
|
-
throw new SynapseEmbeddingError("artifact_invalid", "Synapse response omitted the served table epoch");
|
|
8240
|
-
}
|
|
8241
|
-
if (epoch !== metadata.table_epoch) {
|
|
8242
|
-
throw new SynapseEmbeddingError("substitution_rejected", `Synapse table epoch changed from ${metadata.table_epoch} to ${epoch}`);
|
|
8243
|
-
}
|
|
8244
|
-
}
|
|
8245
|
-
logCallFailure(error, operation) {
|
|
8246
|
-
const classified = classifyError(error);
|
|
8247
|
-
this.recordFailure(classified);
|
|
8248
|
-
if (classified.permanent)
|
|
8249
|
-
this.permanentFailure = true;
|
|
8250
|
-
const suffix = classified.retryAfterMs === undefined ? "" : ` retry_after_ms=${classified.retryAfterMs}`;
|
|
8251
|
-
log(`[magic-context] Synapse ${operation} failed: ${classified.code}${suffix}: ${classified.message}`);
|
|
8252
|
-
}
|
|
8253
|
-
recordFailure(error) {
|
|
8254
|
-
this.lastFailureReason = embeddingFailureFor(error);
|
|
8255
|
-
}
|
|
8256
|
-
recordSuccess() {
|
|
8257
|
-
this.lastFailureReason = null;
|
|
8258
|
-
}
|
|
8259
|
-
}
|
|
8260
|
-
|
|
8261
|
-
// src/features/magic-context/memory/normalize-hash.ts
|
|
8262
|
-
import { createHash as createHash2 } from "node:crypto";
|
|
8263
|
-
function normalizeMemoryContent(content) {
|
|
8264
|
-
return content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
8265
|
-
}
|
|
8266
|
-
function computeNormalizedHash(content) {
|
|
8267
|
-
const normalized = normalizeMemoryContent(content);
|
|
8268
|
-
return createHash2("md5").update(normalized).digest("hex");
|
|
8269
|
-
}
|
|
8270
|
-
|
|
8271
|
-
// src/features/magic-context/memory/embedding-identity.ts
|
|
8272
|
-
function normalizeEndpoint(endpoint) {
|
|
8273
|
-
return endpoint?.trim().replace(/\/+$/, "") ?? "";
|
|
8274
|
-
}
|
|
8275
|
-
var LOCAL_EMBEDDING_RUNTIME_FINGERPRINT = "transformers@4.3.0;onnxruntime-node@1.30.0;onnxruntime-web@1.26.0-dev.20260416-b7804b056c";
|
|
8276
|
-
function getEmbeddingProviderIdentity(config) {
|
|
8277
|
-
if (config.provider === "off") {
|
|
8278
|
-
return "embedding-provider:off";
|
|
8279
|
-
}
|
|
8280
|
-
if (config.provider === "synapse") {
|
|
8281
|
-
const resolved = config;
|
|
8282
|
-
if (!resolved.model || !resolved.synapse_fingerprint)
|
|
8283
|
-
return "synapse:v1:pending";
|
|
8284
|
-
return getSynapseLaneIdentity(resolved.model, resolved.synapse_fingerprint);
|
|
8285
|
-
}
|
|
8286
|
-
if (config.provider !== "local" && config.provider !== "openai-compatible") {
|
|
8287
|
-
throw new Error("Unknown embedding provider");
|
|
8288
|
-
}
|
|
8289
|
-
const truncate = config.provider === "openai-compatible" ? config.truncate?.trim() : undefined;
|
|
8290
|
-
const documentPrefix = config.provider === "openai-compatible" ? resolveEmbeddingTextPrefixes(config.model, config.query_instruction, config.document_prefix).documentPrefix : "";
|
|
8291
|
-
const localDtype = config.provider === "local" && config.local_dtype && config.local_dtype !== "fp32" ? config.local_dtype : undefined;
|
|
8292
|
-
const identityInput = config.provider === "openai-compatible" ? {
|
|
8293
|
-
provider: "openai-compatible",
|
|
8294
|
-
model: config.model.trim(),
|
|
8295
|
-
endpoint: normalizeEndpoint(config.endpoint),
|
|
8296
|
-
apiKeyPresent: Boolean(config.api_key?.trim()),
|
|
8297
|
-
inputType: config.input_type?.trim() || "",
|
|
8298
|
-
...documentPrefix ? { documentPrefix } : {},
|
|
8299
|
-
...truncate ? { truncate } : {}
|
|
8300
|
-
} : {
|
|
8301
|
-
provider: "local",
|
|
8302
|
-
model: config.model?.trim() || DEFAULT_LOCAL_EMBEDDING_MODEL,
|
|
8303
|
-
endpoint: "",
|
|
8304
|
-
apiKeyPresent: false,
|
|
8305
|
-
runtimeFingerprint: LOCAL_EMBEDDING_RUNTIME_FINGERPRINT,
|
|
8306
|
-
...localDtype ? { localDtype } : {}
|
|
8307
|
-
};
|
|
8308
|
-
return `embedding-provider:${computeNormalizedHash(JSON.stringify(identityInput))}`;
|
|
8309
|
-
}
|
|
8310
|
-
|
|
8311
6014
|
// src/features/magic-context/memory/embedding-worker-client.ts
|
|
8312
6015
|
import { Worker } from "node:worker_threads";
|
|
8313
6016
|
class EmbeddingWorkerClient {
|
|
@@ -8355,7 +6058,7 @@ class EmbeddingWorkerClient {
|
|
|
8355
6058
|
request.reject(error);
|
|
8356
6059
|
}
|
|
8357
6060
|
this.pending.clear();
|
|
8358
|
-
|
|
6061
|
+
log2("[magic-context] embedding worker exited unexpectedly:", error);
|
|
8359
6062
|
worker.terminate();
|
|
8360
6063
|
};
|
|
8361
6064
|
worker.on("error", fail);
|
|
@@ -8489,7 +6192,7 @@ async function acquireModelLoadLock(lockPath) {
|
|
|
8489
6192
|
try {
|
|
8490
6193
|
const info = await stat(lockPath);
|
|
8491
6194
|
if (Date.now() - info.mtimeMs > STALE_LOCK_MS) {
|
|
8492
|
-
|
|
6195
|
+
log2(`[magic-context] embedding-load lock stale (>${STALE_LOCK_MS}ms), taking over`);
|
|
8493
6196
|
try {
|
|
8494
6197
|
await unlink(lockPath);
|
|
8495
6198
|
} catch {}
|
|
@@ -8552,7 +6255,7 @@ var importTransformersNodeWasmFallbackForRuntime = async () => {
|
|
|
8552
6255
|
return await importPluginModule(() => import(nodeWasmEntry));
|
|
8553
6256
|
};
|
|
8554
6257
|
var modelCacheDirForRuntime = () => workerData?.magicContextEmbeddingWorker && typeof workerData.modelCacheDir === "string" ? workerData.modelCacheDir : join(getMagicContextStorageDir(), "models");
|
|
8555
|
-
var logForRuntime =
|
|
6258
|
+
var logForRuntime = log2;
|
|
8556
6259
|
var injectWasmOrtForRuntime = injectWasmOrt;
|
|
8557
6260
|
var loadedLocalEmbeddingRuntimes = new Map;
|
|
8558
6261
|
var nextLocalEmbeddingRuntimeId = 1;
|
|
@@ -8609,7 +6312,7 @@ async function injectWasmOrt() {
|
|
|
8609
6312
|
wasmRuntimeInjected = true;
|
|
8610
6313
|
return true;
|
|
8611
6314
|
} catch (error) {
|
|
8612
|
-
|
|
6315
|
+
log2("[magic-context] failed to inject onnxruntime-web:", error instanceof Error ? error.message : String(error));
|
|
8613
6316
|
return false;
|
|
8614
6317
|
}
|
|
8615
6318
|
}
|
|
@@ -8717,7 +6420,7 @@ async function withQuietConsole(fn) {
|
|
|
8717
6420
|
const origError = console.error;
|
|
8718
6421
|
const redirect = (...args) => {
|
|
8719
6422
|
const message = args.map((a) => typeof a === "string" ? a : String(a)).join(" ");
|
|
8720
|
-
|
|
6423
|
+
log2(`[transformers] ${message}`);
|
|
8721
6424
|
};
|
|
8722
6425
|
console.warn = redirect;
|
|
8723
6426
|
console.error = redirect;
|
|
@@ -8769,13 +6472,13 @@ function extractBatchEmbeddings(result, expectedCount) {
|
|
|
8769
6472
|
return data.map((entry) => toFloat32Array(entry));
|
|
8770
6473
|
}
|
|
8771
6474
|
if (!isArrayLikeNumber(data)) {
|
|
8772
|
-
|
|
6475
|
+
log2("[magic-context] embedding batch returned unexpected data shape");
|
|
8773
6476
|
return Array.from({ length: expectedCount }, () => null);
|
|
8774
6477
|
}
|
|
8775
6478
|
const flatData = toFloat32Array(data);
|
|
8776
6479
|
const dimension = result.dims?.at(-1) ?? flatData.length / expectedCount;
|
|
8777
6480
|
if (!Number.isInteger(dimension) || dimension <= 0 || flatData.length !== expectedCount * dimension) {
|
|
8778
|
-
|
|
6481
|
+
log2("[magic-context] embedding batch returned invalid dimensions");
|
|
8779
6482
|
return Array.from({ length: expectedCount }, () => null);
|
|
8780
6483
|
}
|
|
8781
6484
|
const embeddings = [];
|
|
@@ -8811,7 +6514,7 @@ class LocalEmbeddingProvider {
|
|
|
8811
6514
|
magicContextEmbeddingWorker: true,
|
|
8812
6515
|
modelCacheDir: modelCacheDirForRuntime(),
|
|
8813
6516
|
enforcePrivateStoragePermissions: shouldEnforcePrivateStoragePermissions(),
|
|
8814
|
-
harness:
|
|
6517
|
+
harness: getHarness2(),
|
|
8815
6518
|
model,
|
|
8816
6519
|
maxInputTokens,
|
|
8817
6520
|
dtype: this.dtype,
|
|
@@ -8874,7 +6577,7 @@ class LocalEmbeddingProvider {
|
|
|
8874
6577
|
ensureStorageDirectorySync(modelCacheDir);
|
|
8875
6578
|
env.cacheDir = modelCacheDir;
|
|
8876
6579
|
} catch {
|
|
8877
|
-
|
|
6580
|
+
log2("[magic-context] could not create model cache dir, using library default");
|
|
8878
6581
|
}
|
|
8879
6582
|
const createPipeline = transformersModule.pipeline;
|
|
8880
6583
|
const lockPath = join(modelCacheDir, ".load.lock");
|
|
@@ -8903,7 +6606,7 @@ class LocalEmbeddingProvider {
|
|
|
8903
6606
|
break;
|
|
8904
6607
|
}
|
|
8905
6608
|
const delayMs = 300 * attempt + Math.floor(Math.random() * 200);
|
|
8906
|
-
|
|
6609
|
+
log2(`[magic-context] embedding model load attempt ${attempt}/${MAX_ATTEMPTS} failed transiently, retrying in ${delayMs}ms`);
|
|
8907
6610
|
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
8908
6611
|
}
|
|
8909
6612
|
}
|
|
@@ -8918,7 +6621,7 @@ class LocalEmbeddingProvider {
|
|
|
8918
6621
|
externalDeltaAtLoad: memoryAfterLoad.external - memoryBeforeLoad.external,
|
|
8919
6622
|
arrayBuffersDeltaAtLoad: memoryAfterLoad.arrayBuffers - memoryBeforeLoad.arrayBuffers
|
|
8920
6623
|
});
|
|
8921
|
-
|
|
6624
|
+
log2(`[magic-context] embedding model loaded: ${this.model}`);
|
|
8922
6625
|
} else if (this.disposing) {
|
|
8923
6626
|
return;
|
|
8924
6627
|
} else {
|
|
@@ -9103,7 +6806,7 @@ class LocalEmbeddingProvider {
|
|
|
9103
6806
|
try {
|
|
9104
6807
|
await pipelineToDispose.dispose?.();
|
|
9105
6808
|
} catch (error) {
|
|
9106
|
-
|
|
6809
|
+
log2("[magic-context] embedding model dispose failed:", error);
|
|
9107
6810
|
}
|
|
9108
6811
|
})();
|
|
9109
6812
|
return this.disposePromise;
|
|
@@ -9116,4 +6819,4 @@ class LocalEmbeddingProvider {
|
|
|
9116
6819
|
}
|
|
9117
6820
|
}
|
|
9118
6821
|
|
|
9119
|
-
export { isValidLanguageCode, withContentLanguageDirective, buildPrimaryLanguageDirective, string, unknown, array, object, union, tuple, record, parseCron, nextOccurrence, nextDueAtMs, promptSurfaceConfigIdentity, resolveModelConfigValue, resolvePromptSurface, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, PROTECTED_TOKENS_MIN, DEFAULT_LOCAL_EMBEDDING_MODEL, PER_HARNESS_MIGRATION_INVENTORY, PER_HARNESS_MODEL_KEYS, ConfigProfilesSchema, DREAM_TASK_PROMOTION_DEFAULTS, MagicContextConfigSchema, LIVE_RELOAD_CONFIG_PATHS, deriveDefaultProtectedTokens,
|
|
6822
|
+
export { isValidLanguageCode, withContentLanguageDirective, buildPrimaryLanguageDirective, string, unknown, array, object, union, tuple, record, parseCron, nextOccurrence, nextDueAtMs, promptSurfaceConfigIdentity, resolveModelConfigValue, resolvePromptSurface, DEFAULT_EXECUTE_THRESHOLD_PERCENTAGE, DEFAULT_HISTORIAN_TIMEOUT_MS, PROTECTED_TOKENS_MIN, DEFAULT_LOCAL_EMBEDDING_MODEL, PER_HARNESS_MIGRATION_INVENTORY, PER_HARNESS_MODEL_KEYS, ConfigProfilesSchema, DREAM_TASK_PROMOTION_DEFAULTS, MagicContextConfigSchema, LIVE_RELOAD_CONFIG_PATHS, deriveDefaultProtectedTokens, embeddingModelsMatch, resolveEmbeddingTextPrefixes, getEmbeddingProviderIdentity, dominantEmbeddingFailure, resolveLocalEmbeddingWorkerRuntime, getLocalEmbeddingNativeMemoryStats, LocalEmbeddingProvider };
|