@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
|
@@ -0,0 +1,1142 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getSqliteDatabasePath2,
|
|
3
|
+
releaseIndexOwner2
|
|
4
|
+
} from "./index-kb9nn0a0.js";
|
|
5
|
+
import {
|
|
6
|
+
log2
|
|
7
|
+
} from "./index-8j7gqj40.js";
|
|
8
|
+
|
|
9
|
+
// src/hooks/magic-context/read-session-raw.ts
|
|
10
|
+
import { isMainThread } from "node:worker_threads";
|
|
11
|
+
|
|
12
|
+
// src/hooks/magic-context/raw-ordinal-warmup.ts
|
|
13
|
+
import { Worker } from "node:worker_threads";
|
|
14
|
+
|
|
15
|
+
// src/shared/exit-abort-registry.ts
|
|
16
|
+
var controllers = new Set;
|
|
17
|
+
var listenerRegistered = false;
|
|
18
|
+
function abortAll() {
|
|
19
|
+
for (const controller of controllers) {
|
|
20
|
+
try {
|
|
21
|
+
controller.abort();
|
|
22
|
+
} catch {}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function registerExitAbort(controller) {
|
|
26
|
+
controllers.add(controller);
|
|
27
|
+
if (listenerRegistered)
|
|
28
|
+
return;
|
|
29
|
+
listenerRegistered = true;
|
|
30
|
+
process.once("exit", abortAll);
|
|
31
|
+
}
|
|
32
|
+
function unregisterExitAbort(controller) {
|
|
33
|
+
controllers.delete(controller);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// src/hooks/magic-context/raw-ordinal-warmup.ts
|
|
37
|
+
var ACCEPT_TIMEOUT_MS = 2000;
|
|
38
|
+
var RESULT_TIMEOUT_MS = 10 * 60000;
|
|
39
|
+
var FAILURE_BACKOFF_MS = 5 * 60000;
|
|
40
|
+
var inFlight = new Map;
|
|
41
|
+
var connectionIds = new WeakMap;
|
|
42
|
+
var nextConnectionId = 0;
|
|
43
|
+
var failedAt = new Map;
|
|
44
|
+
var activeWorkers = new Map;
|
|
45
|
+
var failures = new Map;
|
|
46
|
+
var exitHookRegistered = false;
|
|
47
|
+
function stopRawSessionOrdinalWarmups() {
|
|
48
|
+
for (const stop of [...activeWorkers.values()])
|
|
49
|
+
stop("stopped");
|
|
50
|
+
}
|
|
51
|
+
function defaultEntry() {
|
|
52
|
+
return new URL(new URL(import.meta.url).pathname.endsWith(".ts") ? "./raw-ordinal-warmup-worker.ts" : "./raw-ordinal-warmup-worker.js", import.meta.url);
|
|
53
|
+
}
|
|
54
|
+
function ensureExitHook() {
|
|
55
|
+
if (exitHookRegistered)
|
|
56
|
+
return;
|
|
57
|
+
exitHookRegistered = true;
|
|
58
|
+
const controller = new AbortController;
|
|
59
|
+
controller.signal.addEventListener("abort", stopRawSessionOrdinalWarmups, { once: true });
|
|
60
|
+
registerExitAbort(controller);
|
|
61
|
+
}
|
|
62
|
+
function runSessionWarmupWorker(input, options) {
|
|
63
|
+
ensureExitHook();
|
|
64
|
+
return new Promise((resolve) => {
|
|
65
|
+
let worker;
|
|
66
|
+
let deadline;
|
|
67
|
+
let settled = false;
|
|
68
|
+
const finish = (result) => {
|
|
69
|
+
if (settled)
|
|
70
|
+
return;
|
|
71
|
+
settled = true;
|
|
72
|
+
clearTimeout(deadline);
|
|
73
|
+
if (worker) {
|
|
74
|
+
activeWorkers.delete(worker);
|
|
75
|
+
const stopped = worker.terminate();
|
|
76
|
+
worker.unref();
|
|
77
|
+
stopped.finally(() => {
|
|
78
|
+
releaseIndexOwner2(input);
|
|
79
|
+
resolve(result);
|
|
80
|
+
});
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
releaseIndexOwner2(input);
|
|
84
|
+
resolve(result);
|
|
85
|
+
};
|
|
86
|
+
const arm = (failure, ms) => {
|
|
87
|
+
clearTimeout(deadline);
|
|
88
|
+
deadline = setTimeout(() => finish({ failure, detail: `no reply within ${ms} ms` }), ms);
|
|
89
|
+
deadline.unref?.();
|
|
90
|
+
};
|
|
91
|
+
try {
|
|
92
|
+
worker = new Worker(options.entry ?? defaultEntry(), { workerData: input });
|
|
93
|
+
} catch (error) {
|
|
94
|
+
finish({ failure: "start-failed", detail: String(error) });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
worker.unref();
|
|
98
|
+
activeWorkers.set(worker, (failure) => finish({ failure, detail: "stopped" }));
|
|
99
|
+
arm("not-accepted", options.acceptMs ?? ACCEPT_TIMEOUT_MS);
|
|
100
|
+
worker.on("message", (reply) => {
|
|
101
|
+
if (reply.kind === "accepted")
|
|
102
|
+
arm("no-result", options.resultMs ?? RESULT_TIMEOUT_MS);
|
|
103
|
+
else if (reply.kind === "scan")
|
|
104
|
+
finish({ scan: reply.scan });
|
|
105
|
+
else if (reply.kind === "tag-summary")
|
|
106
|
+
finish({ summary: reply.summary });
|
|
107
|
+
else if (reply.kind === "tag-delta")
|
|
108
|
+
finish({ delta: reply.delta });
|
|
109
|
+
else if (reply.kind === "indexed")
|
|
110
|
+
finish({ inserted: reply.inserted, measurements: reply.measurements });
|
|
111
|
+
else
|
|
112
|
+
finish({ failure: "worker-error", detail: reply.error });
|
|
113
|
+
});
|
|
114
|
+
worker.on("error", (error) => finish({ failure: "worker-error", detail: String(error) }));
|
|
115
|
+
worker.on("exit", (code) => finish({ failure: "exited", detail: `exit code ${code}` }));
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
function prewarmRawSessionOrdinalsForDb(db, sessionId, options = {}) {
|
|
119
|
+
if (isRawSessionSummaryWarm2(db, sessionId))
|
|
120
|
+
return Promise.resolve("warm");
|
|
121
|
+
if (!db.prepare("SELECT 1 FROM sqlite_master WHERE name = 'message' AND type IN ('table', 'view')").get())
|
|
122
|
+
return Promise.resolve("warm");
|
|
123
|
+
const path = getSqliteDatabasePath2(db);
|
|
124
|
+
if (!path) {
|
|
125
|
+
countRawSessionMessageOrdinalsFromDb2(db, sessionId);
|
|
126
|
+
return Promise.resolve("warm");
|
|
127
|
+
}
|
|
128
|
+
let connectionId = connectionIds.get(db);
|
|
129
|
+
if (connectionId === undefined) {
|
|
130
|
+
connectionId = ++nextConnectionId;
|
|
131
|
+
connectionIds.set(db, connectionId);
|
|
132
|
+
}
|
|
133
|
+
const key = `${path}\x00${sessionId}\x00${connectionId}`;
|
|
134
|
+
let shared = inFlight.get(key);
|
|
135
|
+
if (!shared) {
|
|
136
|
+
const failed = failedAt.get(key);
|
|
137
|
+
if (failed !== undefined && Date.now() - failed < FAILURE_BACKOFF_MS)
|
|
138
|
+
return Promise.resolve("failed");
|
|
139
|
+
const epoch = getRawSessionSummaryEpoch2(sessionId);
|
|
140
|
+
const started = performance.now();
|
|
141
|
+
const result = runSessionWarmupWorker({ path, sessionId, previous: rawOrdinalSummarySeed2(db, sessionId) }, options).then((outcome) => {
|
|
142
|
+
if ("failure" in outcome)
|
|
143
|
+
recordFailure(key, sessionId, outcome.failure, outcome.detail);
|
|
144
|
+
return outcome;
|
|
145
|
+
}).finally(() => {
|
|
146
|
+
if (inFlight.get(key) === scan)
|
|
147
|
+
inFlight.delete(key);
|
|
148
|
+
});
|
|
149
|
+
const scan = { epoch, started, result };
|
|
150
|
+
inFlight.set(key, scan);
|
|
151
|
+
shared = scan;
|
|
152
|
+
}
|
|
153
|
+
const awaited = shared;
|
|
154
|
+
return awaited.result.then((result) => {
|
|
155
|
+
if (!("scan" in result))
|
|
156
|
+
return "failed";
|
|
157
|
+
try {
|
|
158
|
+
if (installRawSessionSummaryScan2(db, sessionId, result.scan, awaited.epoch, true)) {
|
|
159
|
+
failedAt.delete(key);
|
|
160
|
+
log2(`[magic-context] canonical ordinals of ${sessionId} warmed off-thread (${result.scan.sessionRows} messages, ${Math.round(performance.now() - awaited.started)} ms)`);
|
|
161
|
+
return "warm";
|
|
162
|
+
}
|
|
163
|
+
} catch {}
|
|
164
|
+
recordFailure(key, sessionId, "superseded", `session removed during scan: epoch=${awaited.epoch}/${getRawSessionSummaryEpoch2(sessionId)}`);
|
|
165
|
+
return "failed";
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function recordFailure(key, sessionId, failure, detail) {
|
|
169
|
+
failures.set(failure, (failures.get(failure) ?? 0) + 1);
|
|
170
|
+
if (failure !== "superseded")
|
|
171
|
+
failedAt.set(key, Date.now());
|
|
172
|
+
log2(`[magic-context] WARN canonical ordinal warm-up failed for ${sessionId} (${failure}: ${detail}); counts remain bounded and callers must defer or retry`);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/hooks/magic-context/read-session-raw.ts
|
|
176
|
+
function isStrictGapHealingMessage2(message) {
|
|
177
|
+
if (message.storeType === "synthetic")
|
|
178
|
+
return true;
|
|
179
|
+
let sawTool = false;
|
|
180
|
+
for (const part of message.parts) {
|
|
181
|
+
if (!part || typeof part !== "object" || Array.isArray(part))
|
|
182
|
+
return false;
|
|
183
|
+
const record = part;
|
|
184
|
+
const type = typeof record.type === "string" ? record.type : "";
|
|
185
|
+
if (type === "tool" || type === "tool_use" || type === "tool_result") {
|
|
186
|
+
sawTool = true;
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const text = typeof record.text === "string" ? record.text : typeof record.content === "string" ? record.content : "";
|
|
190
|
+
if (text.trim().length > 0 || type.length > 0)
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
return sawTool;
|
|
194
|
+
}
|
|
195
|
+
var RAW_MESSAGE_PARTS_BY_ID_SQL = "SELECT message_id, data, time_updated FROM part WHERE +session_id = ? AND likelihood(message_id = ?, 0.000001) ORDER BY time_created ASC, id ASC";
|
|
196
|
+
function isRawMessageRow(row) {
|
|
197
|
+
if (row === null || typeof row !== "object")
|
|
198
|
+
return false;
|
|
199
|
+
const candidate = row;
|
|
200
|
+
return typeof candidate.id === "string" && typeof candidate.data === "string";
|
|
201
|
+
}
|
|
202
|
+
function isRawPartRow(row) {
|
|
203
|
+
if (row === null || typeof row !== "object")
|
|
204
|
+
return false;
|
|
205
|
+
const candidate = row;
|
|
206
|
+
return typeof candidate.message_id === "string" && typeof candidate.data === "string";
|
|
207
|
+
}
|
|
208
|
+
function parseJsonRecord(value) {
|
|
209
|
+
try {
|
|
210
|
+
const parsed = JSON.parse(value);
|
|
211
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
return parsed;
|
|
215
|
+
} catch {
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
function isRawCompactionSummaryInfo2(info) {
|
|
220
|
+
if (info === null || typeof info !== "object" || Array.isArray(info))
|
|
221
|
+
return false;
|
|
222
|
+
const candidate = info;
|
|
223
|
+
return candidate.summary === true && candidate.finish === "stop";
|
|
224
|
+
}
|
|
225
|
+
var RAW_METADATA_KEEP_CHARS = 16384;
|
|
226
|
+
var RAW_METADATA_KEPT_KEYS = [
|
|
227
|
+
"description",
|
|
228
|
+
"title",
|
|
229
|
+
"userAnswer",
|
|
230
|
+
"answers",
|
|
231
|
+
"answer",
|
|
232
|
+
"selectedOptions",
|
|
233
|
+
"customInput",
|
|
234
|
+
"results"
|
|
235
|
+
];
|
|
236
|
+
var RAW_PART_DATA_SQL = `CASE
|
|
237
|
+
WHEN json_valid(data) = 1
|
|
238
|
+
AND json_type(data, '$.state.metadata') = 'object'
|
|
239
|
+
AND COALESCE(json_extract(data, '$.state.status'), '') <> 'error'
|
|
240
|
+
AND length(json_extract(data, '$.state.metadata')) > ${RAW_METADATA_KEEP_CHARS}
|
|
241
|
+
THEN json_set(data, '$.state.metadata', json_patch('{}', json_object(${RAW_METADATA_KEPT_KEYS.map((key) => `'${key}', json_extract(data, '$.state.metadata.${key}')`).join(", ")})))
|
|
242
|
+
ELSE data
|
|
243
|
+
END`;
|
|
244
|
+
function parseJsonUnknown(value) {
|
|
245
|
+
try {
|
|
246
|
+
return JSON.parse(value);
|
|
247
|
+
} catch {
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
function attachRawPartVersion(value, timeUpdated) {
|
|
252
|
+
if (value === null || typeof value !== "object" || Array.isArray(value))
|
|
253
|
+
return value;
|
|
254
|
+
if (typeof timeUpdated !== "number")
|
|
255
|
+
return value;
|
|
256
|
+
try {
|
|
257
|
+
Object.defineProperty(value, "__magicContextPartUpdatedAt", {
|
|
258
|
+
value: timeUpdated,
|
|
259
|
+
enumerable: false,
|
|
260
|
+
configurable: true
|
|
261
|
+
});
|
|
262
|
+
} catch {}
|
|
263
|
+
return value;
|
|
264
|
+
}
|
|
265
|
+
function readRawSessionMessagesFromDb2(db, sessionId) {
|
|
266
|
+
const messageRows = db.prepare("SELECT id, data, time_created, time_updated FROM message WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(sessionId).filter(isRawMessageRow);
|
|
267
|
+
const partsByMessageId = new Map;
|
|
268
|
+
const partMessageBatchSize = 128;
|
|
269
|
+
for (let offset = 0;offset < messageRows.length; offset += partMessageBatchSize) {
|
|
270
|
+
const messageIds = messageRows.slice(offset, offset + partMessageBatchSize).map((row) => row.id);
|
|
271
|
+
if (messageIds.length === 0)
|
|
272
|
+
continue;
|
|
273
|
+
const placeholders = messageIds.map(() => "?").join(", ");
|
|
274
|
+
const partRows = db.prepare(`SELECT message_id, ${RAW_PART_DATA_SQL} AS data, time_updated
|
|
275
|
+
FROM part
|
|
276
|
+
WHERE +session_id = ?
|
|
277
|
+
AND likelihood(message_id IN (${placeholders}), 0.000001)
|
|
278
|
+
ORDER BY message_id ASC, time_created ASC, id ASC`).all(sessionId, ...messageIds).filter(isRawPartRow);
|
|
279
|
+
for (const part of partRows) {
|
|
280
|
+
const list = partsByMessageId.get(part.message_id) ?? [];
|
|
281
|
+
list.push(attachRawPartVersion(parseJsonUnknown(part.data), part.time_updated));
|
|
282
|
+
partsByMessageId.set(part.message_id, list);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
const filtered = messageRows.filter((row) => !isRawCompactionSummaryInfo2(parseJsonRecord(row.data)));
|
|
286
|
+
return filtered.flatMap((row, index) => {
|
|
287
|
+
const info = parseJsonRecord(row.data);
|
|
288
|
+
if (!info)
|
|
289
|
+
return [];
|
|
290
|
+
const role = typeof info.role === "string" ? info.role : "unknown";
|
|
291
|
+
return {
|
|
292
|
+
ordinal: index + 1,
|
|
293
|
+
id: row.id,
|
|
294
|
+
role,
|
|
295
|
+
parts: partsByMessageId.get(row.id) ?? [],
|
|
296
|
+
createdAt: row.time_created ?? null,
|
|
297
|
+
version: row.time_updated ?? null
|
|
298
|
+
};
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
function readRawSessionMessagePageFromDb2(db, sessionId, afterOrdinal, limit, finalWatermark = Number.MAX_SAFE_INTEGER, after) {
|
|
302
|
+
const messageRows = readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWatermark, after);
|
|
303
|
+
if (messageRows.length === 0)
|
|
304
|
+
return [];
|
|
305
|
+
const placeholders = messageRows.map(() => "?").join(", ");
|
|
306
|
+
const partRows = db.prepare(`SELECT message_id, ${RAW_PART_DATA_SQL} AS data, time_updated
|
|
307
|
+
FROM part
|
|
308
|
+
WHERE +session_id = ?
|
|
309
|
+
AND likelihood(message_id IN (${placeholders}), 0.000001)
|
|
310
|
+
ORDER BY message_id ASC, time_created ASC, id ASC`).all(sessionId, ...messageRows.map((row) => row.id)).filter(isRawPartRow);
|
|
311
|
+
return assembleRawMessagePage(messageRows, partRows);
|
|
312
|
+
}
|
|
313
|
+
function readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWatermark, after) {
|
|
314
|
+
const remaining = Math.max(0, Math.floor(finalWatermark) - Math.floor(afterOrdinal));
|
|
315
|
+
const pageSize = Math.min(Math.max(1, Math.floor(limit)), remaining);
|
|
316
|
+
if (pageSize === 0)
|
|
317
|
+
return [];
|
|
318
|
+
const parameters = [sessionId];
|
|
319
|
+
if (after)
|
|
320
|
+
parameters.push(after.timeCreated, after.timeCreated, after.timeCreated, after.id);
|
|
321
|
+
parameters.push(pageSize);
|
|
322
|
+
if (!after)
|
|
323
|
+
parameters.push(Math.max(0, Math.floor(afterOrdinal)));
|
|
324
|
+
return db.prepare(`SELECT id, data, time_created, time_updated
|
|
325
|
+
FROM message
|
|
326
|
+
WHERE session_id = ?
|
|
327
|
+
${after ? "AND time_created >= ? AND (time_created > ? OR (time_created = ? AND id > ?))" : ""}
|
|
328
|
+
AND NOT (
|
|
329
|
+
CASE WHEN json_valid(data) = 1
|
|
330
|
+
THEN COALESCE(json_extract(data, '$.summary'), 0)
|
|
331
|
+
ELSE 0 END = 1
|
|
332
|
+
AND CASE WHEN json_valid(data) = 1
|
|
333
|
+
THEN COALESCE(json_extract(data, '$.finish'), '')
|
|
334
|
+
ELSE '' END = 'stop'
|
|
335
|
+
)
|
|
336
|
+
ORDER BY time_created ASC, id ASC
|
|
337
|
+
LIMIT ? ${after ? "" : "OFFSET ?"}`).all(...parameters).filter(isRawMessageRow).map((row, index) => ({
|
|
338
|
+
...row,
|
|
339
|
+
ordinal: Math.floor(afterOrdinal) + index + 1
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
342
|
+
function assembleRawMessagePage(messageRows, partRows) {
|
|
343
|
+
const partsByMessageId = new Map;
|
|
344
|
+
for (const part of partRows) {
|
|
345
|
+
const list = partsByMessageId.get(part.message_id) ?? [];
|
|
346
|
+
list.push(attachRawPartVersion(parseJsonUnknown(part.data), part.time_updated));
|
|
347
|
+
partsByMessageId.set(part.message_id, list);
|
|
348
|
+
}
|
|
349
|
+
return messageRows.map((row) => {
|
|
350
|
+
const info = parseJsonRecord(row.data);
|
|
351
|
+
return {
|
|
352
|
+
ordinal: row.ordinal,
|
|
353
|
+
id: row.id,
|
|
354
|
+
role: typeof info?.role === "string" ? info.role : "unknown",
|
|
355
|
+
parts: partsByMessageId.get(row.id) ?? [],
|
|
356
|
+
createdAt: row.time_created ?? null,
|
|
357
|
+
version: row.time_updated ?? null
|
|
358
|
+
};
|
|
359
|
+
});
|
|
360
|
+
}
|
|
361
|
+
var RAW_SUMMARY_TEXT_MAX_CHARS = 8192;
|
|
362
|
+
var RAW_SUMMARY_ARG_MAX_CHARS = 512;
|
|
363
|
+
var RAW_SUMMARY_TOOL_INPUT_KEYS = [
|
|
364
|
+
"description",
|
|
365
|
+
"filePath",
|
|
366
|
+
"path",
|
|
367
|
+
"pattern",
|
|
368
|
+
"query",
|
|
369
|
+
"symbol",
|
|
370
|
+
"module",
|
|
371
|
+
"action"
|
|
372
|
+
];
|
|
373
|
+
function summaryStringField(jsonPath) {
|
|
374
|
+
return `CASE WHEN json_type(data, '${jsonPath}') = 'text' THEN substr(json_extract(data, '${jsonPath}'), 1, ${RAW_SUMMARY_ARG_MAX_CHARS}) END`;
|
|
375
|
+
}
|
|
376
|
+
var RAW_SUMMARY_PART_DATA_SQL = `CASE
|
|
377
|
+
WHEN json_extract(data, '$.type') = 'text'
|
|
378
|
+
THEN json_set(data, '$.text', substr(json_extract(data, '$.text'), 1, ${RAW_SUMMARY_TEXT_MAX_CHARS}))
|
|
379
|
+
ELSE json_object(
|
|
380
|
+
'type', 'tool',
|
|
381
|
+
'tool', ${summaryStringField("$.tool")},
|
|
382
|
+
'callID', ${summaryStringField("$.callID")},
|
|
383
|
+
'state', json_object(
|
|
384
|
+
'status', ${summaryStringField("$.state.status")},
|
|
385
|
+
'input', json_object(${RAW_SUMMARY_TOOL_INPUT_KEYS.map((key) => `'${key}', ${summaryStringField(`$.state.input.${key}`)}`).join(", ")}),
|
|
386
|
+
'metadata', json_object('description', ${summaryStringField("$.state.metadata.description")})
|
|
387
|
+
)
|
|
388
|
+
)
|
|
389
|
+
END`;
|
|
390
|
+
function readRawSessionMessageSummaryPageFromDb2(db, sessionId, afterOrdinal, limit, finalWatermark = Number.MAX_SAFE_INTEGER, after) {
|
|
391
|
+
const messageRows = readRawMessagePageRows(db, sessionId, afterOrdinal, limit, finalWatermark, after);
|
|
392
|
+
if (messageRows.length === 0)
|
|
393
|
+
return [];
|
|
394
|
+
const placeholders = messageRows.map(() => "?").join(", ");
|
|
395
|
+
const partRows = db.prepare(`SELECT message_id, ${RAW_SUMMARY_PART_DATA_SQL} AS data, time_updated
|
|
396
|
+
FROM part
|
|
397
|
+
WHERE +session_id = ?
|
|
398
|
+
AND likelihood(message_id IN (${placeholders}), 0.000001)
|
|
399
|
+
AND json_valid(data) = 1
|
|
400
|
+
AND json_extract(data, '$.type') IN ('text', 'tool')
|
|
401
|
+
ORDER BY message_id ASC, time_created ASC, id ASC`).all(sessionId, ...messageRows.map((row) => row.id)).filter(isRawPartRow);
|
|
402
|
+
return assembleRawMessagePage(messageRows, partRows);
|
|
403
|
+
}
|
|
404
|
+
function countRawSessionMessageOrdinalsFromDb2(db, sessionId) {
|
|
405
|
+
const indexed = countCanonicalOrdinalsIndexed(db, sessionId, null, null);
|
|
406
|
+
if (indexed !== null)
|
|
407
|
+
return indexed;
|
|
408
|
+
const row = db.prepare(`SELECT COUNT(*) AS count
|
|
409
|
+
FROM message
|
|
410
|
+
WHERE session_id = ?
|
|
411
|
+
AND NOT (
|
|
412
|
+
CASE WHEN json_valid(data) = 1
|
|
413
|
+
THEN COALESCE(json_extract(data, '$.summary'), 0)
|
|
414
|
+
ELSE 0 END = 1
|
|
415
|
+
AND CASE WHEN json_valid(data) = 1
|
|
416
|
+
THEN COALESCE(json_extract(data, '$.finish'), '')
|
|
417
|
+
ELSE '' END = 'stop'
|
|
418
|
+
)`).get(sessionId);
|
|
419
|
+
return typeof row?.count === "number" ? row.count : 0;
|
|
420
|
+
}
|
|
421
|
+
function readRawSessionMessageIdOrdinalsForRangeFromDb2(db, sessionId, fromOrdinal, toOrdinal) {
|
|
422
|
+
const from = Math.max(1, Math.floor(fromOrdinal));
|
|
423
|
+
const to = Math.floor(toOrdinal);
|
|
424
|
+
if (to < from)
|
|
425
|
+
return new Map;
|
|
426
|
+
const rows = db.prepare(`
|
|
427
|
+
SELECT id, data FROM message WHERE session_id = ?
|
|
428
|
+
AND CASE WHEN json_valid(data) THEN NOT (
|
|
429
|
+
COALESCE(json_type(data, '$.summary'), '') = 'true'
|
|
430
|
+
AND COALESCE(json_extract(data, '$.finish'), '') = 'stop'
|
|
431
|
+
) ELSE 1 END
|
|
432
|
+
ORDER BY time_created, id LIMIT ? OFFSET ?
|
|
433
|
+
`).all(sessionId, to - from + 1, from - 1).filter(isRawMessageRow);
|
|
434
|
+
const result = new Map;
|
|
435
|
+
for (const [index, row] of rows.entries()) {
|
|
436
|
+
if (parseJsonRecord(row.data))
|
|
437
|
+
result.set(row.id, from + index);
|
|
438
|
+
}
|
|
439
|
+
return result;
|
|
440
|
+
}
|
|
441
|
+
function readRawSessionMessageOrdinalPageFromDb2(db, sessionId, after, limit) {
|
|
442
|
+
const pageSize = Math.max(1, Math.floor(limit));
|
|
443
|
+
const rows = (after ? db.prepare(`SELECT id, data, time_created
|
|
444
|
+
FROM message
|
|
445
|
+
WHERE session_id = ?
|
|
446
|
+
AND (time_created, id) > (?, ?)
|
|
447
|
+
ORDER BY time_created ASC, id ASC
|
|
448
|
+
LIMIT ?`).all(sessionId, after.timeCreated, after.id, pageSize) : db.prepare(`SELECT id, data, time_created
|
|
449
|
+
FROM message
|
|
450
|
+
WHERE session_id = ?
|
|
451
|
+
ORDER BY time_created ASC, id ASC
|
|
452
|
+
LIMIT ?`).all(sessionId, pageSize)).filter(isRawMessageRow);
|
|
453
|
+
return rows.flatMap((row) => {
|
|
454
|
+
if (typeof row.time_created !== "number")
|
|
455
|
+
return [];
|
|
456
|
+
const info = parseJsonRecord(row.data);
|
|
457
|
+
return {
|
|
458
|
+
id: row.id,
|
|
459
|
+
timeCreated: row.time_created,
|
|
460
|
+
contributesOrdinal: !isRawCompactionSummaryInfo2(info),
|
|
461
|
+
hasValidInfo: info !== null
|
|
462
|
+
};
|
|
463
|
+
});
|
|
464
|
+
}
|
|
465
|
+
function countStoredRawSessionMessagesFromDb2(db, sessionId) {
|
|
466
|
+
const row = db.prepare("SELECT COUNT(*) AS count FROM message WHERE session_id = ?").get(sessionId);
|
|
467
|
+
return typeof row?.count === "number" ? row.count : 0;
|
|
468
|
+
}
|
|
469
|
+
function isAnchorRow(row) {
|
|
470
|
+
return row !== null && typeof row === "object" && typeof row.time_created === "number" && typeof row.id === "string";
|
|
471
|
+
}
|
|
472
|
+
function readRawSessionTailFromDb2(db, sessionId, baseOrdinal, anchorMessageId) {
|
|
473
|
+
const anchorRow = db.prepare("SELECT time_created, id, data FROM message WHERE id = ? AND session_id = ?").get(anchorMessageId, sessionId);
|
|
474
|
+
if (!isAnchorRow(anchorRow))
|
|
475
|
+
return null;
|
|
476
|
+
const anchorInfo = parseJsonRecord(anchorRow.data ?? "");
|
|
477
|
+
if (anchorInfo?.summary === true && anchorInfo?.finish === "stop")
|
|
478
|
+
return null;
|
|
479
|
+
const messageRows = db.prepare(`SELECT id, data, time_created, time_updated FROM message
|
|
480
|
+
WHERE session_id = ?
|
|
481
|
+
AND (time_created > ? OR (time_created = ? AND id >= ?))
|
|
482
|
+
ORDER BY time_created ASC, id ASC`).all(sessionId, anchorRow.time_created, anchorRow.time_created, anchorRow.id).filter(isRawMessageRow);
|
|
483
|
+
const filtered = messageRows.filter((row) => {
|
|
484
|
+
const info = parseJsonRecord(row.data);
|
|
485
|
+
return !(info?.summary === true && info?.finish === "stop");
|
|
486
|
+
});
|
|
487
|
+
const ids = filtered.map((row) => row.id);
|
|
488
|
+
const partsByMessageId = new Map;
|
|
489
|
+
if (ids.length > 0) {
|
|
490
|
+
const CHUNK = 800;
|
|
491
|
+
for (let i = 0;i < ids.length; i += CHUNK) {
|
|
492
|
+
const slice = ids.slice(i, i + CHUNK);
|
|
493
|
+
const placeholders = slice.map(() => "?").join(",");
|
|
494
|
+
const partRows = db.prepare(`SELECT message_id, ${RAW_PART_DATA_SQL} AS data, time_updated FROM part WHERE +session_id = ? AND likelihood(message_id IN (${placeholders}), 0.000001) ORDER BY time_created ASC, id ASC`).all(sessionId, ...slice).filter(isRawPartRow);
|
|
495
|
+
for (const part of partRows) {
|
|
496
|
+
const list = partsByMessageId.get(part.message_id) ?? [];
|
|
497
|
+
list.push(attachRawPartVersion(parseJsonUnknown(part.data), part.time_updated));
|
|
498
|
+
partsByMessageId.set(part.message_id, list);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
const messages = [];
|
|
503
|
+
let ord = baseOrdinal;
|
|
504
|
+
for (const row of filtered) {
|
|
505
|
+
const info = parseJsonRecord(row.data);
|
|
506
|
+
if (!info) {
|
|
507
|
+
ord += 1;
|
|
508
|
+
continue;
|
|
509
|
+
}
|
|
510
|
+
messages.push({
|
|
511
|
+
ordinal: ord,
|
|
512
|
+
id: row.id,
|
|
513
|
+
role: typeof info.role === "string" ? info.role : "unknown",
|
|
514
|
+
parts: partsByMessageId.get(row.id) ?? [],
|
|
515
|
+
createdAt: row.time_created ?? null,
|
|
516
|
+
version: row.time_updated ?? null
|
|
517
|
+
});
|
|
518
|
+
ord += 1;
|
|
519
|
+
}
|
|
520
|
+
return { messages, absoluteMessageCount: Math.max(0, ord - 1) };
|
|
521
|
+
}
|
|
522
|
+
function extractInMemoryMessageViews2(messages) {
|
|
523
|
+
return messages.map((m) => {
|
|
524
|
+
const info = m.info ?? {};
|
|
525
|
+
return {
|
|
526
|
+
id: typeof info.id === "string" ? info.id : "",
|
|
527
|
+
role: typeof info.role === "string" ? info.role : "unknown",
|
|
528
|
+
parts: Array.isArray(m.parts) ? m.parts : [],
|
|
529
|
+
summary: info.summary === true ? true : undefined,
|
|
530
|
+
finish: typeof info.finish === "string" ? info.finish : undefined
|
|
531
|
+
};
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
function buildInMemoryTailRawMessages2(args) {
|
|
535
|
+
const { messages, lastCompartmentEnd, anchorMessageId } = args;
|
|
536
|
+
const filtered = messages.filter((m) => !(m.summary === true && m.finish === "stop"));
|
|
537
|
+
if (filtered.length === 0)
|
|
538
|
+
return null;
|
|
539
|
+
let startIndex = 0;
|
|
540
|
+
let baseOrdinal;
|
|
541
|
+
let anchorFound = false;
|
|
542
|
+
if (anchorMessageId) {
|
|
543
|
+
const anchorIndex = filtered.findIndex((m) => m.id === anchorMessageId);
|
|
544
|
+
if (anchorIndex >= 0) {
|
|
545
|
+
anchorFound = true;
|
|
546
|
+
startIndex = anchorIndex;
|
|
547
|
+
baseOrdinal = lastCompartmentEnd;
|
|
548
|
+
} else {
|
|
549
|
+
baseOrdinal = Math.max(1, lastCompartmentEnd + 1);
|
|
550
|
+
}
|
|
551
|
+
} else {
|
|
552
|
+
baseOrdinal = Math.max(1, lastCompartmentEnd + 1);
|
|
553
|
+
}
|
|
554
|
+
const out = [];
|
|
555
|
+
let ord = baseOrdinal;
|
|
556
|
+
for (let i = startIndex;i < filtered.length; i += 1) {
|
|
557
|
+
const m = filtered[i];
|
|
558
|
+
if (!m.id || typeof m.id !== "string") {
|
|
559
|
+
ord += 1;
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
out.push({
|
|
563
|
+
ordinal: ord,
|
|
564
|
+
id: m.id,
|
|
565
|
+
role: typeof m.role === "string" ? m.role : "unknown",
|
|
566
|
+
parts: m.parts ?? [],
|
|
567
|
+
version: null
|
|
568
|
+
});
|
|
569
|
+
ord += 1;
|
|
570
|
+
}
|
|
571
|
+
return { messages: out, absoluteMessageCount: Math.max(0, ord - 1), anchorFound };
|
|
572
|
+
}
|
|
573
|
+
function readRawSessionMessagePartsByIdFromDb2(db, sessionId, messageId, onQuery) {
|
|
574
|
+
onQuery?.();
|
|
575
|
+
const row = db.prepare("SELECT id, data, time_created, time_updated FROM message WHERE session_id = ? AND id = ?").get(sessionId, messageId);
|
|
576
|
+
if (!row || !isRawMessageRow(row) || typeof row.time_created !== "number")
|
|
577
|
+
return null;
|
|
578
|
+
const info = parseJsonRecord(row.data);
|
|
579
|
+
if (!info || isRawCompactionSummaryInfo2(info))
|
|
580
|
+
return null;
|
|
581
|
+
onQuery?.();
|
|
582
|
+
const partRows = db.prepare(RAW_MESSAGE_PARTS_BY_ID_SQL).all(sessionId, messageId).filter(isRawPartRow);
|
|
583
|
+
return {
|
|
584
|
+
id: row.id,
|
|
585
|
+
role: typeof info.role === "string" ? info.role : "unknown",
|
|
586
|
+
parts: partRows.map((part) => attachRawPartVersion(parseJsonUnknown(part.data), part.time_updated)),
|
|
587
|
+
createdAt: row.time_created,
|
|
588
|
+
version: row.time_updated ?? null
|
|
589
|
+
};
|
|
590
|
+
}
|
|
591
|
+
var ORDINAL_SUMMARY_FLAG_SQL = `(CASE WHEN json_valid(data) = 1
|
|
592
|
+
THEN COALESCE(json_extract(data, '$.summary'), 0)
|
|
593
|
+
ELSE 0 END = 1)`;
|
|
594
|
+
var ORDINAL_STOP_FLAG_SQL = `(CASE WHEN json_valid(data) = 1
|
|
595
|
+
THEN COALESCE(json_extract(data, '$.finish'), '')
|
|
596
|
+
ELSE '' END = 'stop')`;
|
|
597
|
+
function ordinalRangeSql(lowerBound) {
|
|
598
|
+
return `SELECT COUNT(*) AS visited,
|
|
599
|
+
COALESCE(SUM(CASE WHEN ${ORDINAL_SUMMARY_FLAG_SQL} AND ${ORDINAL_STOP_FLAG_SQL}
|
|
600
|
+
THEN 0 ELSE 1 END), 0) AS eligible
|
|
601
|
+
FROM message
|
|
602
|
+
WHERE session_id = ?
|
|
603
|
+
${lowerBound ? "AND (time_created, id) > (?, ?)" : ""}
|
|
604
|
+
AND (time_created, id) <= (?, ?)`;
|
|
605
|
+
}
|
|
606
|
+
var ORDINAL_RANGE_FROM_START_SQL = ordinalRangeSql(false);
|
|
607
|
+
var ORDINAL_RANGE_BETWEEN_SQL = ordinalRangeSql(true);
|
|
608
|
+
function readStoreStamp(db) {
|
|
609
|
+
try {
|
|
610
|
+
const row = db.prepare(`SELECT data_version AS dataVersion, total_changes() AS totalChanges,
|
|
611
|
+
(SELECT schema_version FROM pragma_schema_version) AS schemaVersion
|
|
612
|
+
FROM pragma_data_version`).get();
|
|
613
|
+
if (typeof row?.dataVersion !== "number" || typeof row.totalChanges !== "number" || typeof row.schemaVersion !== "number")
|
|
614
|
+
return null;
|
|
615
|
+
return {
|
|
616
|
+
dataVersion: row.dataVersion,
|
|
617
|
+
totalChanges: row.totalChanges,
|
|
618
|
+
schemaVersion: row.schemaVersion
|
|
619
|
+
};
|
|
620
|
+
} catch {
|
|
621
|
+
return null;
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
function sameStoreStamp(left, right) {
|
|
625
|
+
return left !== null && right !== null && left.dataVersion === right.dataVersion && left.totalChanges === right.totalChanges && left.schemaVersion === right.schemaVersion;
|
|
626
|
+
}
|
|
627
|
+
var ordinalWatermarks = new WeakMap;
|
|
628
|
+
var ordinalWatermarkEpochs = new Map;
|
|
629
|
+
var ordinalRowsVisited = 0;
|
|
630
|
+
var STABLE_STORE_ATTEMPTS = 3;
|
|
631
|
+
function forgetRawSessionOrdinalWatermark2(sessionId) {
|
|
632
|
+
ordinalWatermarkEpochs.set(sessionId, (ordinalWatermarkEpochs.get(sessionId) ?? 0) + 1);
|
|
633
|
+
}
|
|
634
|
+
function compareOrdinalKeys(left, right) {
|
|
635
|
+
if (left.timeCreated !== right.timeCreated)
|
|
636
|
+
return left.timeCreated < right.timeCreated ? -1 : 1;
|
|
637
|
+
if (left.id === right.id)
|
|
638
|
+
return 0;
|
|
639
|
+
return Buffer.compare(Buffer.from(left.id, "utf8"), Buffer.from(right.id, "utf8"));
|
|
640
|
+
}
|
|
641
|
+
function countEligibleOrdinals(db, sessionId, after, through) {
|
|
642
|
+
const indexed = countCanonicalOrdinalsIndexed(db, sessionId, after, through);
|
|
643
|
+
if (indexed !== null)
|
|
644
|
+
return indexed;
|
|
645
|
+
const row = after ? db.prepare(ORDINAL_RANGE_BETWEEN_SQL).get(sessionId, after.timeCreated, after.id, through.timeCreated, through.id) : db.prepare(ORDINAL_RANGE_FROM_START_SQL).get(sessionId, through.timeCreated, through.id);
|
|
646
|
+
const visited = typeof row?.visited === "number" ? row.visited : 0;
|
|
647
|
+
ordinalRowsVisited += visited;
|
|
648
|
+
ordinalJsonRowsRead += visited;
|
|
649
|
+
return typeof row?.eligible === "number" ? row.eligible : 0;
|
|
650
|
+
}
|
|
651
|
+
var EXCLUDED_ROW_SQL = `${ORDINAL_SUMMARY_FLAG_SQL} AND ${ORDINAL_STOP_FLAG_SQL}`;
|
|
652
|
+
var SUMMARY_ANCHOR_SPAN = 256;
|
|
653
|
+
var SUMMARY_ANCHOR_LIMIT = 64;
|
|
654
|
+
var WRITTEN_SUMMARY_ID_LIMIT = 4096;
|
|
655
|
+
var summaryCandidateSets = new WeakMap;
|
|
656
|
+
var summaryCandidateEpochs = new Map;
|
|
657
|
+
var writtenSummaryIds = new Map;
|
|
658
|
+
var indexedCountUnsupported = new WeakSet;
|
|
659
|
+
var ordinalJsonRowsRead = 0;
|
|
660
|
+
var summaryFullScans = 0;
|
|
661
|
+
function forgetRawSessionSummaryRows2(sessionId) {
|
|
662
|
+
summaryCandidateEpochs.set(sessionId, (summaryCandidateEpochs.get(sessionId) ?? 0) + 1);
|
|
663
|
+
writtenSummaryIds.delete(sessionId);
|
|
664
|
+
forgetRawSessionOrdinalWatermark2(sessionId);
|
|
665
|
+
}
|
|
666
|
+
function noteRawSessionSummaryRowWritten2(sessionId, messageId) {
|
|
667
|
+
let ids = writtenSummaryIds.get(sessionId);
|
|
668
|
+
if (!ids) {
|
|
669
|
+
ids = new Set;
|
|
670
|
+
writtenSummaryIds.set(sessionId, ids);
|
|
671
|
+
}
|
|
672
|
+
ids.add(messageId);
|
|
673
|
+
if (ids.size > WRITTEN_SUMMARY_ID_LIMIT)
|
|
674
|
+
forgetRawSessionSummaryRows2(sessionId);
|
|
675
|
+
}
|
|
676
|
+
var ANCHOR_ROWS_SQL = `SELECT rowid AS rid, id, 1 AS kind FROM message
|
|
677
|
+
WHERE rowid > (SELECT MAX(rowid) FROM message) - ${SUMMARY_ANCHOR_SPAN}`;
|
|
678
|
+
var SUMMARY_FULL_SCAN_SQL = `${ANCHOR_ROWS_SQL}
|
|
679
|
+
UNION ALL
|
|
680
|
+
SELECT rowid, id, 2 FROM message WHERE session_id = ? AND ${ORDINAL_SUMMARY_FLAG_SQL}
|
|
681
|
+
UNION ALL
|
|
682
|
+
SELECT COUNT(*), NULL, 4 FROM message WHERE session_id = ?`;
|
|
683
|
+
var SUMMARY_SCAN_AFTER_SQL = `${ANCHOR_ROWS_SQL}
|
|
684
|
+
UNION ALL
|
|
685
|
+
SELECT rowid, id, CASE WHEN ${ORDINAL_SUMMARY_FLAG_SQL} THEN 2 ELSE 3 END
|
|
686
|
+
FROM message WHERE rowid > ? AND +session_id = ?`;
|
|
687
|
+
var ANCHOR_CHECK_SQL = "SELECT rowid AS rid, id FROM message WHERE rowid IN (SELECT value FROM json_each(?))";
|
|
688
|
+
function survivingAnchor(db, set) {
|
|
689
|
+
if (set.anchors.length === 0)
|
|
690
|
+
return null;
|
|
691
|
+
const current = new Map(db.prepare(ANCHOR_CHECK_SQL).all(JSON.stringify(set.anchors.map((anchor) => anchor.rowid))).map((row) => [row.rid, row.id]));
|
|
692
|
+
return set.anchors.find((anchor) => current.get(anchor.rowid) === anchor.id);
|
|
693
|
+
}
|
|
694
|
+
var ordinalCheckpoints = new WeakMap;
|
|
695
|
+
var ordinalSummarySeeds = new WeakMap;
|
|
696
|
+
var ORDINAL_LOOKUP_LIMIT = 512;
|
|
697
|
+
function currentOrdinalCheckpoints(db, sessionId) {
|
|
698
|
+
const cached = ordinalCheckpoints.get(db)?.get(sessionId);
|
|
699
|
+
if (!cached)
|
|
700
|
+
return;
|
|
701
|
+
return withReadSnapshot(db, () => {
|
|
702
|
+
if (!extendOrdinalCheckpoints(db, sessionId, cached.scan, ORDINAL_LOOKUP_LIMIT))
|
|
703
|
+
return;
|
|
704
|
+
cached.epoch = getRawSessionSummaryEpoch2(sessionId);
|
|
705
|
+
return cached;
|
|
706
|
+
});
|
|
707
|
+
}
|
|
708
|
+
function extendOrdinalCheckpoints(db, sessionId, scan, limit) {
|
|
709
|
+
const points = scan.checkpoints ?? [];
|
|
710
|
+
const exists = (point) => Boolean(db.prepare("SELECT 1 FROM message WHERE id=? AND session_id=? AND time_created=?").get(point.id, sessionId, point.timeCreated));
|
|
711
|
+
if (points.length && !exists(points[points.length - 1])) {
|
|
712
|
+
let low = 0;
|
|
713
|
+
let high = points.length;
|
|
714
|
+
while (low < high) {
|
|
715
|
+
const middle = Math.floor((low + high) / 2);
|
|
716
|
+
if (exists(points[middle]))
|
|
717
|
+
low = middle + 1;
|
|
718
|
+
else
|
|
719
|
+
high = middle;
|
|
720
|
+
}
|
|
721
|
+
points.length = low;
|
|
722
|
+
scan.total = points.at(-1)?.ordinal ?? 0;
|
|
723
|
+
scan.sessionRows = points.at(-1)?.storedCount ?? 0;
|
|
724
|
+
}
|
|
725
|
+
const tail = points.at(-1);
|
|
726
|
+
const rows = db.prepare(`SELECT id, time_created AS timeCreated, ${EXCLUDED_ROW_SQL} AS excluded FROM message
|
|
727
|
+
WHERE session_id=?${tail ? " AND (time_created,id) > (?,?)" : ""}
|
|
728
|
+
ORDER BY time_created,id${limit === undefined ? "" : ` LIMIT ${limit + 1}`}`).all(sessionId, ...tail ? [tail.timeCreated, tail.id] : []);
|
|
729
|
+
ordinalJsonRowsRead += rows.length;
|
|
730
|
+
if (limit !== undefined && rows.length > limit)
|
|
731
|
+
return false;
|
|
732
|
+
let total = scan.total ?? 0;
|
|
733
|
+
if (rows.length && tail && (tail.storedCount ?? 0) % 256 !== 0)
|
|
734
|
+
points.pop();
|
|
735
|
+
for (let index = 0;index < rows.length; index++) {
|
|
736
|
+
const row = rows[index];
|
|
737
|
+
if (row.excluded !== 1)
|
|
738
|
+
total++;
|
|
739
|
+
const storedCount = scan.sessionRows + index + 1;
|
|
740
|
+
if (storedCount % 256 === 0 || index === rows.length - 1)
|
|
741
|
+
points.push({ id: row.id, timeCreated: row.timeCreated, ordinal: total, storedCount });
|
|
742
|
+
}
|
|
743
|
+
scan.checkpoints = points;
|
|
744
|
+
scan.sessionRows += rows.length;
|
|
745
|
+
scan.total = total;
|
|
746
|
+
return true;
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
class RawOrdinalsNotReady extends Error {
|
|
750
|
+
constructor() {
|
|
751
|
+
super("canonical ordinals are warming off-thread; retry after preparation");
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
function rawOrdinalSummarySeed2(db, sessionId) {
|
|
755
|
+
const retained = ordinalCheckpoints.get(db)?.get(sessionId);
|
|
756
|
+
if (retained)
|
|
757
|
+
return retained.scan;
|
|
758
|
+
const seed = ordinalSummarySeeds.get(db)?.get(sessionId);
|
|
759
|
+
if (!seed || seed.epoch !== getRawSessionSummaryEpoch2(sessionId))
|
|
760
|
+
return;
|
|
761
|
+
return {
|
|
762
|
+
...seed.scan,
|
|
763
|
+
ids: [...new Set([...seed.scan.ids, ...writtenSummaryIds.get(sessionId) ?? []])]
|
|
764
|
+
};
|
|
765
|
+
}
|
|
766
|
+
function boundedOrdinalPrefix(db, sessionId, through) {
|
|
767
|
+
const cached = currentOrdinalCheckpoints(db, sessionId);
|
|
768
|
+
if (cached && through === null)
|
|
769
|
+
return cached.scan.total ?? 0;
|
|
770
|
+
let floor;
|
|
771
|
+
if (cached && through) {
|
|
772
|
+
const points = cached.scan.checkpoints ?? [];
|
|
773
|
+
let low = 0;
|
|
774
|
+
let high = points.length;
|
|
775
|
+
while (low < high) {
|
|
776
|
+
const middle = Math.floor((low + high) / 2);
|
|
777
|
+
if (compareOrdinalKeys(points[middle], through) <= 0)
|
|
778
|
+
low = middle + 1;
|
|
779
|
+
else
|
|
780
|
+
high = middle;
|
|
781
|
+
}
|
|
782
|
+
floor = points[low - 1];
|
|
783
|
+
if (floor && compareOrdinalKeys(floor, through) === 0)
|
|
784
|
+
return floor.ordinal;
|
|
785
|
+
}
|
|
786
|
+
const bindings = [sessionId];
|
|
787
|
+
if (floor)
|
|
788
|
+
bindings.push(floor.timeCreated, floor.id);
|
|
789
|
+
if (through)
|
|
790
|
+
bindings.push(through.timeCreated, through.id);
|
|
791
|
+
const rows = db.prepare(`SELECT ${EXCLUDED_ROW_SQL} AS excluded FROM message WHERE id IN (
|
|
792
|
+
SELECT id FROM message WHERE session_id = ?${floor ? " AND (time_created, id) > (?, ?)" : ""}${through ? " AND (time_created, id) <= (?, ?)" : ""}
|
|
793
|
+
ORDER BY time_created, id LIMIT ${ORDINAL_LOOKUP_LIMIT + 1})`).all(...bindings);
|
|
794
|
+
ordinalRowsVisited += rows.length;
|
|
795
|
+
ordinalJsonRowsRead += rows.length;
|
|
796
|
+
if (rows.length > ORDINAL_LOOKUP_LIMIT) {
|
|
797
|
+
prewarmRawSessionOrdinalsForDb(db, sessionId);
|
|
798
|
+
throw new RawOrdinalsNotReady;
|
|
799
|
+
}
|
|
800
|
+
return (floor?.ordinal ?? 0) + rows.reduce((sum, row) => sum + (row.excluded === 1 ? 0 : 1), 0);
|
|
801
|
+
}
|
|
802
|
+
function scanRawSessionSummaryRows2(db, sessionId, previous) {
|
|
803
|
+
return withReadSnapshot(db, () => {
|
|
804
|
+
if (previous?.checkpoints) {
|
|
805
|
+
extendOrdinalCheckpoints(db, sessionId, previous);
|
|
806
|
+
return previous;
|
|
807
|
+
}
|
|
808
|
+
if (previous) {
|
|
809
|
+
const sessions = summaryCandidateSets.get(db) ?? new Map;
|
|
810
|
+
sessions.set(sessionId, {
|
|
811
|
+
epoch: getRawSessionSummaryEpoch2(sessionId),
|
|
812
|
+
anchors: previous.anchors,
|
|
813
|
+
ids: new Set(previous.ids)
|
|
814
|
+
});
|
|
815
|
+
summaryCandidateSets.set(db, sessions);
|
|
816
|
+
}
|
|
817
|
+
const incremental = previous && isRawSessionSummaryWarm2(db, sessionId) ? summaryCandidatesOf(db, sessionId) : undefined;
|
|
818
|
+
const rows = incremental ? [] : db.prepare(SUMMARY_FULL_SCAN_SQL).all(sessionId, sessionId);
|
|
819
|
+
const anchors = [];
|
|
820
|
+
const ids = [];
|
|
821
|
+
let sessionRows = 0;
|
|
822
|
+
for (const row of rows) {
|
|
823
|
+
if (row.kind === 1 && typeof row.rid === "number" && typeof row.id === "string")
|
|
824
|
+
anchors.push({ rowid: row.rid, id: row.id });
|
|
825
|
+
else if (row.kind === 2 && typeof row.id === "string")
|
|
826
|
+
ids.push(row.id);
|
|
827
|
+
else if (row.kind === 4 && typeof row.rid === "number")
|
|
828
|
+
sessionRows = row.rid;
|
|
829
|
+
}
|
|
830
|
+
if (incremental) {
|
|
831
|
+
ids.push(...incremental.ids);
|
|
832
|
+
anchors.push(...summaryCandidateSets.get(db)?.get(sessionId)?.anchors ?? []);
|
|
833
|
+
sessionRows = countStoredRawSessionRowsIndexed(db, sessionId);
|
|
834
|
+
}
|
|
835
|
+
anchors.sort((left, right) => right.rowid - left.rowid);
|
|
836
|
+
anchors.length = Math.min(anchors.length, SUMMARY_ANCHOR_LIMIT);
|
|
837
|
+
const keys = db.prepare(`SELECT id, time_created AS timeCreated, ${EXCLUDED_ROW_SQL} AS excluded FROM message WHERE session_id = ?
|
|
838
|
+
ORDER BY time_created, id`).all(sessionId);
|
|
839
|
+
const checkpoints = [];
|
|
840
|
+
let total = 0;
|
|
841
|
+
for (let index = 0;index < keys.length; index++) {
|
|
842
|
+
const key = keys[index];
|
|
843
|
+
if (key.excluded !== 1)
|
|
844
|
+
total++;
|
|
845
|
+
if (index % 256 === 255 || index === keys.length - 1)
|
|
846
|
+
checkpoints.push({
|
|
847
|
+
id: key.id,
|
|
848
|
+
timeCreated: key.timeCreated,
|
|
849
|
+
ordinal: total,
|
|
850
|
+
storedCount: index + 1
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
return { anchors, ids, sessionRows, checkpoints, total };
|
|
854
|
+
});
|
|
855
|
+
}
|
|
856
|
+
function getRawSessionSummaryEpoch2(sessionId) {
|
|
857
|
+
return summaryCandidateEpochs.get(sessionId) ?? 0;
|
|
858
|
+
}
|
|
859
|
+
function installRawSessionSummaryScan2(db, sessionId, scan, epoch, workerPrepared = false) {
|
|
860
|
+
if (epoch !== getRawSessionSummaryEpoch2(sessionId))
|
|
861
|
+
return false;
|
|
862
|
+
const seeds = ordinalSummarySeeds.get(db) ?? new Map;
|
|
863
|
+
seeds.set(sessionId, { epoch, scan });
|
|
864
|
+
ordinalSummarySeeds.set(db, seeds);
|
|
865
|
+
if (scan.checkpoints && workerPrepared) {
|
|
866
|
+
const counts = ordinalCheckpoints.get(db) ?? new Map;
|
|
867
|
+
counts.set(sessionId, { epoch, scan });
|
|
868
|
+
ordinalCheckpoints.set(db, counts);
|
|
869
|
+
} else if (getSqliteDatabasePath2(db) && isMainThread)
|
|
870
|
+
return false;
|
|
871
|
+
if (isRawSessionSummaryWarm2(db, sessionId))
|
|
872
|
+
return true;
|
|
873
|
+
let sessions = summaryCandidateSets.get(db);
|
|
874
|
+
if (!sessions) {
|
|
875
|
+
sessions = new Map;
|
|
876
|
+
summaryCandidateSets.set(db, sessions);
|
|
877
|
+
}
|
|
878
|
+
sessions.set(sessionId, { epoch, anchors: [...scan.anchors], ids: new Set(scan.ids) });
|
|
879
|
+
return isRawSessionSummaryWarm2(db, sessionId);
|
|
880
|
+
}
|
|
881
|
+
function isRawSessionSummaryWarm2(db, sessionId) {
|
|
882
|
+
if (isMainThread && getSqliteDatabasePath2(db)) {
|
|
883
|
+
return Boolean(currentOrdinalCheckpoints(db, sessionId));
|
|
884
|
+
}
|
|
885
|
+
const set = summaryCandidateSets.get(db)?.get(sessionId);
|
|
886
|
+
if (!set || set.epoch !== getRawSessionSummaryEpoch2(sessionId))
|
|
887
|
+
return false;
|
|
888
|
+
try {
|
|
889
|
+
return survivingAnchor(db, set) !== undefined;
|
|
890
|
+
} catch {
|
|
891
|
+
return false;
|
|
892
|
+
}
|
|
893
|
+
}
|
|
894
|
+
function countStoredRawSessionRowsIndexed(db, sessionId) {
|
|
895
|
+
const row = db.prepare("SELECT COUNT(*) AS count FROM message WHERE session_id = ?").get(sessionId);
|
|
896
|
+
return typeof row?.count === "number" ? row.count : 0;
|
|
897
|
+
}
|
|
898
|
+
function summaryCandidatesOf(db, sessionId) {
|
|
899
|
+
let sessions = summaryCandidateSets.get(db);
|
|
900
|
+
if (!sessions) {
|
|
901
|
+
sessions = new Map;
|
|
902
|
+
summaryCandidateSets.set(db, sessions);
|
|
903
|
+
}
|
|
904
|
+
const epoch = getRawSessionSummaryEpoch2(sessionId);
|
|
905
|
+
const cached = sessions.get(sessionId);
|
|
906
|
+
const floor = cached && cached.epoch === epoch ? survivingAnchor(db, cached) : undefined;
|
|
907
|
+
let ids;
|
|
908
|
+
let anchors;
|
|
909
|
+
if (floor === undefined) {
|
|
910
|
+
const scan = scanRawSessionSummaryRows2(db, sessionId);
|
|
911
|
+
summaryFullScans += 1;
|
|
912
|
+
ordinalJsonRowsRead += scan.sessionRows;
|
|
913
|
+
ids = new Set(scan.ids);
|
|
914
|
+
anchors = scan.anchors;
|
|
915
|
+
} else {
|
|
916
|
+
const rows = db.prepare(SUMMARY_SCAN_AFTER_SQL).all(floor?.rowid ?? 0, sessionId);
|
|
917
|
+
ids = cached?.ids ?? new Set;
|
|
918
|
+
anchors = [];
|
|
919
|
+
for (const row of rows) {
|
|
920
|
+
if (row.kind === 1 && typeof row.rid === "number" && typeof row.id === "string")
|
|
921
|
+
anchors.push({ rowid: row.rid, id: row.id });
|
|
922
|
+
else if (row.kind === 2 && typeof row.id === "string")
|
|
923
|
+
ids.add(row.id);
|
|
924
|
+
if (row.kind === 2 || row.kind === 3)
|
|
925
|
+
ordinalJsonRowsRead += 1;
|
|
926
|
+
}
|
|
927
|
+
anchors.sort((left, right) => right.rowid - left.rowid);
|
|
928
|
+
anchors.length = Math.min(anchors.length, SUMMARY_ANCHOR_LIMIT);
|
|
929
|
+
}
|
|
930
|
+
for (const id of writtenSummaryIds.get(sessionId) ?? [])
|
|
931
|
+
ids.add(id);
|
|
932
|
+
sessions.set(sessionId, { epoch, anchors, ids });
|
|
933
|
+
const top = anchors[0];
|
|
934
|
+
return { ids: [...ids], floorRowid: top?.rowid ?? 0, floorId: top?.id ?? null };
|
|
935
|
+
}
|
|
936
|
+
function canonicalCountSql(lower, upper) {
|
|
937
|
+
const range = `${lower ? " AND (time_created, id) > (?, ?)" : ""}${upper ? " AND (time_created, id) <= (?, ?)" : ""}`;
|
|
938
|
+
return `SELECT
|
|
939
|
+
(SELECT COUNT(*) FROM message WHERE session_id = ?${range}) AS stored,
|
|
940
|
+
(SELECT COUNT(*) FROM message
|
|
941
|
+
WHERE id IN (SELECT value FROM json_each(?)) AND +session_id = ?${range}
|
|
942
|
+
AND ${EXCLUDED_ROW_SQL}) AS knownExcluded,
|
|
943
|
+
(SELECT COUNT(*) FROM message
|
|
944
|
+
WHERE rowid > ? AND +session_id = ? AND id NOT IN (SELECT value FROM json_each(?))${range}
|
|
945
|
+
AND ${EXCLUDED_ROW_SQL}) AS newExcluded,
|
|
946
|
+
(SELECT id FROM message WHERE rowid = ?) AS floorId`;
|
|
947
|
+
}
|
|
948
|
+
var CANONICAL_COUNT_SQL = new Map;
|
|
949
|
+
function canonicalCountStatementText(lower, upper) {
|
|
950
|
+
const key = `${lower}:${upper}`;
|
|
951
|
+
let sql = CANONICAL_COUNT_SQL.get(key);
|
|
952
|
+
if (!sql) {
|
|
953
|
+
sql = canonicalCountSql(lower, upper);
|
|
954
|
+
CANONICAL_COUNT_SQL.set(key, sql);
|
|
955
|
+
}
|
|
956
|
+
return sql;
|
|
957
|
+
}
|
|
958
|
+
function countCanonicalOrdinalsIndexed(db, sessionId, after, through) {
|
|
959
|
+
if (isMainThread && getSqliteDatabasePath2(db)) {
|
|
960
|
+
return withReadSnapshot(db, () => boundedOrdinalPrefix(db, sessionId, through) - (after ? boundedOrdinalPrefix(db, sessionId, after) : 0));
|
|
961
|
+
}
|
|
962
|
+
if (indexedCountUnsupported.has(db))
|
|
963
|
+
return null;
|
|
964
|
+
const range = [];
|
|
965
|
+
if (after)
|
|
966
|
+
range.push(after.timeCreated, after.id);
|
|
967
|
+
if (through)
|
|
968
|
+
range.push(through.timeCreated, through.id);
|
|
969
|
+
try {
|
|
970
|
+
return withReadSnapshot(db, () => {
|
|
971
|
+
for (let attempt = 0;attempt < STABLE_STORE_ATTEMPTS; attempt += 1) {
|
|
972
|
+
const view = summaryCandidatesOf(db, sessionId);
|
|
973
|
+
const ids = JSON.stringify(view.ids);
|
|
974
|
+
const row = db.prepare(canonicalCountStatementText(after !== null, through !== null)).get(sessionId, ...range, ids, sessionId, ...range, view.floorRowid, sessionId, ids, ...range, view.floorRowid);
|
|
975
|
+
if (view.floorId !== null && row?.floorId !== view.floorId)
|
|
976
|
+
continue;
|
|
977
|
+
const stored = typeof row?.stored === "number" ? row.stored : 0;
|
|
978
|
+
const excluded = (typeof row?.knownExcluded === "number" ? row.knownExcluded : 0) + (typeof row?.newExcluded === "number" ? row.newExcluded : 0);
|
|
979
|
+
ordinalRowsVisited += stored;
|
|
980
|
+
ordinalJsonRowsRead += view.ids.length;
|
|
981
|
+
return stored - excluded;
|
|
982
|
+
}
|
|
983
|
+
return null;
|
|
984
|
+
});
|
|
985
|
+
} catch (error) {
|
|
986
|
+
if (/no such (column|table|function)|json_each/i.test(String(error))) {
|
|
987
|
+
indexedCountUnsupported.add(db);
|
|
988
|
+
return null;
|
|
989
|
+
}
|
|
990
|
+
throw error;
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
function connectionHasOpenTransaction(db) {
|
|
994
|
+
const state = db;
|
|
995
|
+
return state.inTransaction === true || state.isTransaction === true;
|
|
996
|
+
}
|
|
997
|
+
function withReadSnapshot(db, read) {
|
|
998
|
+
if (connectionHasOpenTransaction(db))
|
|
999
|
+
return read();
|
|
1000
|
+
db.exec("BEGIN");
|
|
1001
|
+
try {
|
|
1002
|
+
return read();
|
|
1003
|
+
} finally {
|
|
1004
|
+
if (connectionHasOpenTransaction(db))
|
|
1005
|
+
db.exec("ROLLBACK");
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
function reusableWatermark(db, sessionId, stamp) {
|
|
1009
|
+
const watermark = ordinalWatermarks.get(db)?.get(sessionId);
|
|
1010
|
+
if (!watermark || watermark.epoch !== (ordinalWatermarkEpochs.get(sessionId) ?? 0) || !sameStoreStamp(watermark.stamp, stamp))
|
|
1011
|
+
return null;
|
|
1012
|
+
return watermark;
|
|
1013
|
+
}
|
|
1014
|
+
function rememberOrdinalWatermark(db, sessionId, key, ordinal, stamp) {
|
|
1015
|
+
let sessions = ordinalWatermarks.get(db);
|
|
1016
|
+
if (!sessions) {
|
|
1017
|
+
sessions = new Map;
|
|
1018
|
+
ordinalWatermarks.set(db, sessions);
|
|
1019
|
+
}
|
|
1020
|
+
const current = sessions.get(sessionId);
|
|
1021
|
+
if (current && sameStoreStamp(current.stamp, stamp) && compareOrdinalKeys(current, key) >= 0)
|
|
1022
|
+
return;
|
|
1023
|
+
sessions.set(sessionId, {
|
|
1024
|
+
timeCreated: key.timeCreated,
|
|
1025
|
+
id: key.id,
|
|
1026
|
+
ordinal,
|
|
1027
|
+
stamp,
|
|
1028
|
+
epoch: ordinalWatermarkEpochs.get(sessionId) ?? 0
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1031
|
+
function canonicalOrdinalOf(db, sessionId, readTarget) {
|
|
1032
|
+
for (let attempt = 1;; attempt += 1) {
|
|
1033
|
+
const before = readStoreStamp(db);
|
|
1034
|
+
const target = readTarget();
|
|
1035
|
+
if (!target)
|
|
1036
|
+
return null;
|
|
1037
|
+
const watermark = attempt < STABLE_STORE_ATTEMPTS ? reusableWatermark(db, sessionId, before) : null;
|
|
1038
|
+
if (!watermark) {
|
|
1039
|
+
const ordinal = countEligibleOrdinals(db, sessionId, null, target);
|
|
1040
|
+
if (before && sameStoreStamp(before, readStoreStamp(db)))
|
|
1041
|
+
rememberOrdinalWatermark(db, sessionId, target, ordinal, before);
|
|
1042
|
+
return { target, ordinal };
|
|
1043
|
+
}
|
|
1044
|
+
const order = compareOrdinalKeys(target, watermark);
|
|
1045
|
+
const ordinal = order === 0 ? watermark.ordinal : order < 0 ? watermark.ordinal - countEligibleOrdinals(db, sessionId, target, watermark) : watermark.ordinal + countEligibleOrdinals(db, sessionId, watermark, target);
|
|
1046
|
+
if (sameStoreStamp(before, readStoreStamp(db))) {
|
|
1047
|
+
rememberOrdinalWatermark(db, sessionId, target, ordinal, before);
|
|
1048
|
+
return { target, ordinal };
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
function readRawSessionMessageOrdinalByIdFromDb2(db, sessionId, messageId) {
|
|
1053
|
+
const counted = canonicalOrdinalOf(db, sessionId, () => {
|
|
1054
|
+
const row = db.prepare(`SELECT id, time_created, ${ORDINAL_SUMMARY_FLAG_SQL} AND ${ORDINAL_STOP_FLAG_SQL} AS excluded
|
|
1055
|
+
FROM message WHERE session_id = ? AND id = ?`).get(sessionId, messageId);
|
|
1056
|
+
if (typeof row?.id !== "string" || typeof row.time_created !== "number")
|
|
1057
|
+
return null;
|
|
1058
|
+
return { id: row.id, timeCreated: row.time_created, excluded: row.excluded === 1 };
|
|
1059
|
+
});
|
|
1060
|
+
if (!counted || counted.target.excluded)
|
|
1061
|
+
return null;
|
|
1062
|
+
return counted.ordinal > 0 ? counted.ordinal : null;
|
|
1063
|
+
}
|
|
1064
|
+
function readRawSessionMessageByIdFromDb2(db, sessionId, messageId) {
|
|
1065
|
+
const counted = canonicalOrdinalOf(db, sessionId, () => {
|
|
1066
|
+
const row = db.prepare("SELECT id, data, time_created, time_updated FROM message WHERE session_id = ? AND id = ?").get(sessionId, messageId);
|
|
1067
|
+
if (!row || !isRawMessageRow(row) || typeof row.time_created !== "number")
|
|
1068
|
+
return null;
|
|
1069
|
+
const parsed = parseJsonRecord(row.data);
|
|
1070
|
+
if (!parsed || isRawCompactionSummaryInfo2(parsed))
|
|
1071
|
+
return null;
|
|
1072
|
+
return { ...row, timeCreated: row.time_created, info: parsed };
|
|
1073
|
+
});
|
|
1074
|
+
if (!counted)
|
|
1075
|
+
return null;
|
|
1076
|
+
const { target: row, ordinal } = counted;
|
|
1077
|
+
const info = row.info;
|
|
1078
|
+
if (ordinal <= 0) {
|
|
1079
|
+
return null;
|
|
1080
|
+
}
|
|
1081
|
+
const partRows = db.prepare(RAW_MESSAGE_PARTS_BY_ID_SQL).all(sessionId, messageId).filter(isRawPartRow);
|
|
1082
|
+
const role = typeof info.role === "string" ? info.role : "unknown";
|
|
1083
|
+
return {
|
|
1084
|
+
ordinal,
|
|
1085
|
+
id: row.id,
|
|
1086
|
+
role,
|
|
1087
|
+
parts: partRows.map((part) => attachRawPartVersion(parseJsonUnknown(part.data), part.time_updated)),
|
|
1088
|
+
createdAt: row.time_created,
|
|
1089
|
+
version: row.time_updated ?? null
|
|
1090
|
+
};
|
|
1091
|
+
}
|
|
1092
|
+
function hasRawSessionMessageByIdFromDb2(db, sessionId, messageId) {
|
|
1093
|
+
const row = db.prepare("SELECT id, data, time_created FROM message WHERE session_id = ? AND id = ?").get(sessionId, messageId);
|
|
1094
|
+
if (!row || !isRawMessageRow(row) || typeof row.time_created !== "number")
|
|
1095
|
+
return false;
|
|
1096
|
+
const info = parseJsonRecord(row.data);
|
|
1097
|
+
if (!info || isRawCompactionSummaryInfo2(info))
|
|
1098
|
+
return false;
|
|
1099
|
+
if (info.summary === 1 && info.finish === "stop")
|
|
1100
|
+
return readRawSessionMessageByIdFromDb2(db, sessionId, messageId) !== null;
|
|
1101
|
+
return true;
|
|
1102
|
+
}
|
|
1103
|
+
function readRawSeedTailFromDb2(db, sessionId, boundaryId) {
|
|
1104
|
+
const rows = db.prepare(`
|
|
1105
|
+
WITH canonical AS (
|
|
1106
|
+
SELECT id, time_created,
|
|
1107
|
+
ROW_NUMBER() OVER (ORDER BY time_created, id) AS ordinal
|
|
1108
|
+
FROM message WHERE session_id = ?
|
|
1109
|
+
AND NOT (CASE WHEN json_valid(data) THEN COALESCE(json_extract(data, '$.summary'), 0) ELSE 0 END = 1
|
|
1110
|
+
AND CASE WHEN json_valid(data) THEN COALESCE(json_extract(data, '$.finish'), '') ELSE '' END = 'stop')
|
|
1111
|
+
)
|
|
1112
|
+
SELECT c.id, m.data, c.time_created, m.time_updated, c.ordinal,
|
|
1113
|
+
p.data AS part_data, p.time_updated AS part_updated
|
|
1114
|
+
FROM canonical c JOIN message m ON m.id = c.id
|
|
1115
|
+
LEFT JOIN part p ON +p.session_id = ? AND likelihood(p.message_id = c.id, 0.000001)
|
|
1116
|
+
WHERE ? IS NULL OR c.ordinal >= (SELECT ordinal FROM canonical WHERE id = ?)
|
|
1117
|
+
ORDER BY c.ordinal, p.time_created, p.id
|
|
1118
|
+
`).all(sessionId, sessionId, boundaryId, boundaryId);
|
|
1119
|
+
const messages = new Map;
|
|
1120
|
+
for (const row of rows) {
|
|
1121
|
+
if (!messages.has(row.id)) {
|
|
1122
|
+
const info = parseJsonRecord(row.data);
|
|
1123
|
+
if (!info)
|
|
1124
|
+
continue;
|
|
1125
|
+
messages.set(row.id, {
|
|
1126
|
+
id: row.id,
|
|
1127
|
+
ordinal: row.ordinal,
|
|
1128
|
+
role: typeof info.role === "string" ? info.role : "unknown",
|
|
1129
|
+
createdAt: row.time_created,
|
|
1130
|
+
version: row.time_updated,
|
|
1131
|
+
parts: []
|
|
1132
|
+
});
|
|
1133
|
+
}
|
|
1134
|
+
if (row.part_data !== null)
|
|
1135
|
+
messages.get(row.id)?.parts.push(attachRawPartVersion(parseJsonUnknown(row.part_data), row.part_updated ?? undefined));
|
|
1136
|
+
}
|
|
1137
|
+
if (boundaryId !== null && !messages.has(boundaryId))
|
|
1138
|
+
throw new Error("state_sync materialized boundary is missing from raw storage");
|
|
1139
|
+
return messages;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
export { registerExitAbort, unregisterExitAbort, isStrictGapHealingMessage2, isRawCompactionSummaryInfo2, readRawSessionMessagesFromDb2, readRawSessionMessagePageFromDb2, readRawSessionMessageSummaryPageFromDb2, countRawSessionMessageOrdinalsFromDb2, readRawSessionMessageIdOrdinalsForRangeFromDb2, readRawSessionMessageOrdinalPageFromDb2, countStoredRawSessionMessagesFromDb2, readRawSessionTailFromDb2, extractInMemoryMessageViews2, buildInMemoryTailRawMessages2, readRawSessionMessagePartsByIdFromDb2, forgetRawSessionOrdinalWatermark2, forgetRawSessionSummaryRows2, noteRawSessionSummaryRowWritten2, rawOrdinalSummarySeed2, scanRawSessionSummaryRows2, getRawSessionSummaryEpoch2, installRawSessionSummaryScan2, isRawSessionSummaryWarm2, readRawSessionMessageOrdinalByIdFromDb2, readRawSessionMessageByIdFromDb2, hasRawSessionMessageByIdFromDb2, readRawSeedTailFromDb2, runSessionWarmupWorker, prewarmRawSessionOrdinalsForDb };
|