@cortexkit/opencode-magic-context 0.49.11 → 0.49.13
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/README.md +1 -1
- package/dist/agents/smart-notes-dreamer-gate.fixture.d.ts +28 -0
- package/dist/agents/smart-notes-dreamer-gate.fixture.d.ts.map +1 -0
- package/dist/{announcement-hdbkt8v5.js → announcement-g789dmt6.js} +2 -2
- package/dist/auto-search-worker.js +4 -4
- package/dist/chunk-embedding-write-worker.js +89 -0
- package/dist/{compaction-marker-candidates-xxz35vwp.js → compaction-marker-candidates-v5c6997n.js} +3 -3
- package/dist/compaction-marker-candidates-worker.js +1 -1
- package/dist/config/agent-disable.d.ts +14 -0
- package/dist/config/agent-disable.d.ts.map +1 -1
- package/dist/config/dependency-notes.d.ts +34 -0
- package/dist/config/dependency-notes.d.ts.map +1 -0
- package/dist/config/schema/agent-overrides.d.ts +12 -12
- package/dist/config/schema/magic-context.d.ts +88 -88
- package/dist/config/schema/magic-context.d.ts.map +1 -1
- package/dist/{conflict-warning-hook-xwkfncav.js → conflict-warning-hook-mgq17yr3.js} +8 -8
- package/dist/{context-twz3s0cg.js → context-azqk0vfd.js} +121 -145
- package/dist/{derive-budgets-3nbxsyss.js → derive-budgets-zn7yzd2d.js} +3 -3
- package/dist/embedding-backfill-5e1t5wha.js +22 -0
- package/dist/embedding-worker-process.js +2 -2
- package/dist/embedding-worker.js +6 -6
- package/dist/features/magic-context/chunk-embedding-write-worker.d.ts +2 -0
- package/dist/features/magic-context/chunk-embedding-write-worker.d.ts.map +1 -0
- package/dist/features/magic-context/chunk-embedding-writer.d.ts +48 -0
- package/dist/features/magic-context/chunk-embedding-writer.d.ts.map +1 -0
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts +1 -1
- package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts +3 -2
- package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts +8 -1
- package/dist/features/magic-context/dreamer/map-memories.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts +2 -0
- package/dist/features/magic-context/dreamer/retrospective-raw-provider.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts +5 -0
- package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-config.d.ts +22 -4
- package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-registry.d.ts +22 -0
- package/dist/features/magic-context/dreamer/task-registry.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts +4 -1
- package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts +6 -1
- package/dist/features/magic-context/dreamer/verify-prompt.d.ts.map +1 -1
- package/dist/features/magic-context/dreamer/verify.d.ts +25 -11
- package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
- package/dist/features/magic-context/memory/embedding-openai.d.ts +32 -0
- package/dist/features/magic-context/memory/embedding-openai.d.ts.map +1 -1
- package/dist/features/magic-context/memory/project-identity.d.ts +1 -0
- package/dist/features/magic-context/memory/project-identity.d.ts.map +1 -1
- package/dist/features/magic-context/memory/unborn-head.d.ts +34 -0
- package/dist/features/magic-context/memory/unborn-head.d.ts.map +1 -0
- package/dist/features/magic-context/mural/compress-cues.d.ts +3 -0
- package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
- package/dist/features/magic-context/project-embedding-registry.d.ts +5 -0
- package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
- package/dist/features/magic-context/storage-tags.d.ts +2 -0
- package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
- package/dist/{history-owner-ty29fz0f.js → history-owner-xp3pngv7.js} +3 -3
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-embed-session.d.ts +10 -0
- package/dist/hooks/magic-context/auto-embed-session.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-prompt.d.ts +6 -0
- package/dist/hooks/magic-context/compartment-prompt.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-types.d.ts +3 -0
- package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
- package/dist/hooks/magic-context/compartment-trigger-error.d.ts +12 -0
- package/dist/hooks/magic-context/compartment-trigger-error.d.ts.map +1 -0
- package/dist/hooks/magic-context/embed-session-state.d.ts +8 -1
- package/dist/hooks/magic-context/embed-session-state.d.ts.map +1 -1
- package/dist/hooks/magic-context/historian-prompt-fit.d.ts +2 -0
- package/dist/hooks/magic-context/historian-prompt-fit.d.ts.map +1 -1
- package/dist/hooks/magic-context/hook.d.ts +3 -1
- package/dist/hooks/magic-context/hook.d.ts.map +1 -1
- package/dist/hooks/magic-context/pending-materialization.d.ts +2 -0
- package/dist/hooks/magic-context/pending-materialization.d.ts.map +1 -1
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts +12 -0
- package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
- package/dist/hooks/magic-context/raw-exact-ordinal-read.d.ts +58 -0
- package/dist/hooks/magic-context/raw-exact-ordinal-read.d.ts.map +1 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +7 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-raw.d.ts +19 -0
- package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts +2 -0
- package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts +2 -0
- package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts +4 -0
- 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-bzp9s8z2.js → index-1d289pq2.js} +2 -2
- package/dist/{index-w28y7d0z.js → index-1sarmj9z.js} +15 -15
- package/dist/{index-z7avx6rw.js → index-2jr1smmh.js} +280 -160
- package/dist/{index-4ccdr7yw.js → index-3kdm78zp.js} +5 -5
- package/dist/{index-9159kk15.js → index-3kx0kg0f.js} +64 -7
- package/dist/{index-0jz47061.js → index-a8bvhwqs.js} +190 -30
- package/dist/{index-84j7jq8a.js → index-aw1bh90w.js} +10 -10
- package/dist/{index-qr1mkc2y.js → index-b16gpywn.js} +9 -9
- package/dist/{index-g7jkrz0x.js → index-bp5083x2.js} +1 -1
- package/dist/{index-yhrrx7qa.js → index-bxdg2nbt.js} +3 -3
- package/dist/{index-0abg88h2.js → index-dgs16axy.js} +4 -4
- package/dist/{index-mp2kghkv.js → index-dyvbsvga.js} +1 -1
- package/dist/{index-bmwfzz28.js → index-e20m7284.js} +4 -4
- package/dist/{index-4jkhhpn1.js → index-e4dsjj1p.js} +3 -3
- package/dist/{index-s178h9z8.js → index-f71thw8j.js} +1 -1
- package/dist/{index-kvw6xew3.js → index-fkx2qnvw.js} +2 -2
- package/dist/{index-f8cn4xqa.js → index-fwefky9w.js} +18 -5
- package/dist/{index-0sahzkwr.js → index-g2q4htwp.js} +46 -2
- package/dist/{index-mw7c950g.js → index-gp3kcpc4.js} +1 -1
- package/dist/{index-g40wgxxt.js → index-hnm8raee.js} +4 -4
- package/dist/{index-gjvjh960.js → index-hqkczed7.js} +1 -1
- package/dist/{index-mvvephtj.js → index-j75v2476.js} +1 -1
- package/dist/{index-150zz6fh.js → index-k29z4aqh.js} +1 -1
- package/dist/{index-b64n4d0h.js → index-kee4kn5j.js} +1 -1
- package/dist/index-ksdyrrav.js +52 -0
- package/dist/{index-angx1s0k.js → index-mmfa86mt.js} +16 -6
- package/dist/{index-9jvab89d.js → index-n6m03s3n.js} +2 -2
- package/dist/{index-q28hsbpg.js → index-nj7yykkx.js} +1 -1
- package/dist/{index-ghc9f0n7.js → index-p5y3k4g7.js} +29 -1
- package/dist/{index-xztdf9t7.js → index-qkd9zz0p.js} +17 -17
- package/dist/index-saews2s3.js +229 -0
- package/dist/{index-kkvxnbt8.js → index-sj89f3b0.js} +62 -33
- package/dist/{index-jw4gbfkv.js → index-v10f1rjv.js} +5 -5
- package/dist/{index-0j6crjgh.js → index-v13skev1.js} +13 -13
- package/dist/{index-hqnggmxn.js → index-wj6ht7nm.js} +547 -179
- package/dist/{index-a865mj02.js → index-wk0n1cgt.js} +4 -4
- package/dist/{index-q3qck7j2.js → index-wz6mzzb1.js} +6 -5
- package/dist/{index-se1w3v2m.js → index-y1qysm3q.js} +332 -256
- package/dist/{index-a4b0gbyg.js → index-y9f76s3f.js} +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +119 -129
- package/dist/{logger-wn328tfg.js → logger-jm3sqqzr.js} +2 -2
- package/dist/{message-index-bounded-0rbbg9rd.js → message-index-bounded-vm64mqpq.js} +16 -16
- package/dist/{message-index-ct5x2kwa.js → message-index-seaqpb7c.js} +16 -16
- package/dist/{message-time-backfill-nb5hhnrt.js → message-time-backfill-qjge9044.js} +3 -3
- package/dist/migration-worker.js +11 -11
- package/dist/plugin/dream-timer.d.ts.map +1 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
- package/dist/plugin/tool-registry.d.ts.map +1 -1
- package/dist/{project-embedding-registry-ft9gh2e2.js → project-embedding-registry-x45bv3qr.js} +12 -11
- package/dist/raw-ordinal-warmup-worker.js +12 -7
- package/dist/{read-session-chunk-y3hhsbzw.js → read-session-chunk-ax05f7gr.js} +11 -11
- package/dist/{read-session-raw-gm6xj30v.js → read-session-raw-m56hc7v2.js} +7 -3
- package/dist/recomp-orchestrator-dmbeadwt.js +61 -0
- package/dist/{safe-notification-target-jdynm677.js → safe-notification-target-1szv1k5k.js} +3 -3
- package/dist/{search-jd8xh721.js → search-5yd5ytzs.js} +25 -24
- package/dist/{send-session-notification-vzhj8bsg.js → send-session-notification-24r4esbh.js} +6 -6
- package/dist/shared/data-path.d.ts +4 -0
- package/dist/shared/data-path.d.ts.map +1 -1
- package/dist/shared/model-suggestion-retry.d.ts +2 -0
- package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
- package/dist/shared/prompt-async-transport.d.ts.map +1 -1
- package/dist/{storage-tags-35m4gms2.js → storage-tags-yygfb9c8.js} +7 -5
- package/dist/{task-config-cgpg0nvh.js → task-config-x3qmayd2.js} +6 -2
- package/dist/tools/ctx-note/tools.d.ts.map +1 -1
- package/dist/{transform-postprocess-phase-pmqxfq4q.js → transform-postprocess-phase-72v86syx.js} +32 -31
- package/dist/v2/auto-search-worker.js +4 -4
- package/dist/v2/chunk-embedding-write-worker.js +88 -0
- package/dist/v2/{compaction-marker-candidates-a15w3mqh.js → compaction-marker-candidates-1vqwr3s5.js} +2 -2
- package/dist/v2/compaction-marker-candidates-worker.js +1 -1
- package/dist/v2/{context-p1zfcw41.js → context-w055w17c.js} +628 -255
- package/dist/v2/{derive-budgets-0rmpmxjw.js → derive-budgets-2zh4gm2c.js} +3 -3
- package/dist/v2/embedding-backfill-jmaf8zrr.js +21 -0
- package/dist/v2/embedding-worker-process.js +1 -1
- package/dist/v2/embedding-worker.js +5 -5
- package/dist/v2/{history-owner-2cr9py37.js → history-owner-42e16w0n.js} +2 -2
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/dream-manual.d.ts.map +1 -1
- package/dist/v2/hooks/dream-trigger.d.ts +1 -1
- package/dist/v2/hooks/dream-trigger.d.ts.map +1 -1
- package/dist/v2/hooks/hidden-child.d.ts.map +1 -1
- package/dist/v2/hooks/transform-features.d.ts +3 -2
- package/dist/v2/hooks/transform-features.d.ts.map +1 -1
- package/dist/v2/{logger-te6e1j72.js → logger-7qt02bnb.js} +1 -1
- package/dist/v2/{message-index-bounded-7wcbp975.js → message-index-bounded-wepg5723.js} +15 -15
- package/dist/v2/{message-index-cjhv92m2.js → message-index-gcmd0ng0.js} +15 -15
- package/dist/v2/{message-time-backfill-rz1pnpaj.js → message-time-backfill-bsteyc4d.js} +2 -2
- package/dist/v2/migration-worker.js +10 -10
- package/dist/v2/{project-embedding-registry-g34gcf74.js → project-embedding-registry-0msp56p8.js} +11 -10
- package/dist/v2/raw-ordinal-warmup-worker.js +12 -7
- package/dist/v2/{read-session-chunk-8d3v87vr.js → read-session-chunk-hr3w5bjk.js} +10 -10
- package/dist/v2/{read-session-raw-h4azh85b.js → read-session-raw-b3tf6ra1.js} +6 -2
- package/dist/v2/recomp-orchestrator-ca7qt75a.js +60 -0
- package/dist/v2/retrospective-raw-provider.d.ts.map +1 -1
- package/dist/v2/{safe-notification-target-936374xx.js → safe-notification-target-qg7n2s77.js} +2 -2
- package/dist/v2/{search-a1acjwf8.js → search-c86dcv14.js} +24 -23
- package/dist/v2/{send-session-notification-z5mcjdea.js → send-session-notification-8ghn9tnv.js} +5 -5
- package/dist/v2/{server-npm52h2q.js → server-05xjtq6c.js} +1 -1
- package/dist/v2/{server-s6jqh8bj.js → server-0ppsweh6.js} +1 -1
- package/dist/v2/server-0s95v3en.js +49 -0
- package/dist/v2/{server-hn9fb3v0.js → server-34kwfsr4.js} +2 -2
- package/dist/v2/server-4gn3z5an.js +229 -0
- package/dist/v2/{server-kn7skz9r.js → server-6cdy4rc0.js} +3 -3
- package/dist/v2/{server-7dv9wt9r.js → server-6pmqg9m4.js} +1 -1
- package/dist/v2/{server-7fvmt15t.js → server-b81w6sw3.js} +273 -107
- package/dist/v2/{server-kmapq3v0.js → server-bxpwy6fy.js} +18 -5
- package/dist/v2/{server-d6t16r89.js → server-d8tj10db.js} +1 -1
- package/dist/v2/{server-cxsr0ng6.js → server-da07v4xp.js} +1 -1
- package/dist/v2/{server-rxcq4t50.js → server-ef89gdsx.js} +5 -5
- package/dist/v2/{server-9e5r8y60.js → server-f2xf5gcb.js} +46 -2
- package/dist/v2/{server-83d71zab.js → server-g10mdym6.js} +3 -3
- package/dist/v2/{server-njnx39q2.js → server-gvkm8xaj.js} +189 -29
- package/dist/v2/{server-ckrb5rm8.js → server-h0410h0v.js} +1 -1
- package/dist/v2/{server-sg68np13.js → server-hek6z3w6.js} +330 -254
- package/dist/v2/{server-f27he3j1.js → server-k2bzedxk.js} +4 -4
- package/dist/v2/{server-wkhfyzpg.js → server-m97brnat.js} +9 -9
- package/dist/v2/{server-erfp0xb6.js → server-n8ch9683.js} +16 -16
- package/dist/v2/{server-bx59ezg6.js → server-prg55b7k.js} +16 -6
- package/dist/v2/{server-89fcbe37.js → server-pwv4ezb0.js} +1 -1
- package/dist/v2/{server-r5p3b1wy.js → server-qd11g795.js} +29 -1
- package/dist/v2/{server-ewqshbs8.js → server-qhfvvfxj.js} +64 -7
- package/dist/v2/{server-988cqjme.js → server-rrqpvwqd.js} +2 -2
- package/dist/v2/{server-d3f4g62c.js → server-t4prcjc1.js} +13 -13
- package/dist/v2/{server-nveratm5.js → server-tbe1femw.js} +4 -4
- package/dist/v2/{server-jc8v585p.js → server-th4y11y7.js} +15 -15
- package/dist/v2/{server-h3wc20sv.js → server-vbe4se57.js} +4 -4
- package/dist/v2/{server-pbpp8r8h.js → server-xh7jar6k.js} +9 -9
- package/dist/v2/{server-63ha7f0f.js → server-yrvqaswb.js} +1 -1
- package/dist/v2/{server-5x7kmyz8.js → server-zc3e54vy.js} +10 -51
- package/dist/v2/{server-xqf2d2mg.js → server-zs8d0s3b.js} +2 -2
- package/dist/v2/server.d.ts.map +1 -1
- package/dist/v2/server.js +18 -10
- package/dist/v2/{storage-tags-c4zfcxv4.js → storage-tags-a2gq6dw7.js} +6 -4
- package/dist/v2/store-reader.d.ts +1 -0
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/{task-config-x0hq3qfd.js → task-config-nvz8mapa.js} +6 -2
- package/dist/v2/{wrapup-orchestrator-87q9d5e2.js → wrapup-orchestrator-e1a2w6jh.js} +31 -29
- package/dist/wrapup-orchestrator-2051r6qm.js +48 -0
- package/package.json +6 -5
- package/src/agents/smart-notes-dreamer-gate.fixture.ts +171 -0
- package/src/agents/smart-notes-dreamer-gate.golden.json +245 -0
- package/src/agents/smart-notes-dreamer-gate.test.ts +161 -0
- package/src/config/agent-disable.ts +13 -0
- package/src/config/dependency-notes.test.ts +114 -0
- package/src/config/dependency-notes.ts +80 -0
- package/src/config/schema/magic-context.ts +23 -14
- package/src/features/magic-context/dreamer/task-registry.ts +40 -0
- package/src/shared/data-path.test.ts +35 -1
- package/src/shared/data-path.ts +57 -1
- package/src/shared/model-suggestion-retry.test.ts +34 -0
- package/src/shared/model-suggestion-retry.ts +23 -3
- package/src/shared/prompt-async-transport.test.ts +1 -1
- package/src/shared/prompt-async-transport.ts +16 -3
- package/dist/embedding-backfill-fjbfh1dt.js +0 -21
- package/dist/recomp-orchestrator-67k45s0b.js +0 -60
- package/dist/v2/embedding-backfill-xcw3t6hp.js +0 -20
- package/dist/v2/recomp-orchestrator-n0pq36f0.js +0 -59
- package/dist/wrapup-orchestrator-jqapepw0.js +0 -47
- /package/dist/{index-e6xnpach.js → index-b7p25tm0.js} +0 -0
- /package/dist/v2/{index-e6xnpach.js → index-b7p25tm0.js} +0 -0
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
inRootAsyncContext2,
|
|
3
|
+
getSqliteDatabasePath2,
|
|
3
4
|
withSqliteBackgroundWriter2,
|
|
4
5
|
withoutSqliteTransformPass2,
|
|
5
6
|
isTransientSqliteError2
|
|
6
7
|
} from "./server-wafzvyhg.js";
|
|
7
8
|
import {
|
|
8
9
|
DEFAULT_LOCAL_EMBEDDING_MODEL
|
|
9
|
-
} from "./server-
|
|
10
|
+
} from "./server-th4y11y7.js";
|
|
10
11
|
import {
|
|
11
|
-
isUserHomeDirectory,
|
|
12
12
|
setBootQuietPeriodForTests
|
|
13
|
-
} from "./server-
|
|
13
|
+
} from "./server-gvkm8xaj.js";
|
|
14
14
|
import {
|
|
15
15
|
isEmbeddingHostBusy2
|
|
16
16
|
} from "./server-qt1qqasc.js";
|
|
@@ -20,17 +20,18 @@ import {
|
|
|
20
20
|
import {
|
|
21
21
|
sanitizeDiagnosticText,
|
|
22
22
|
log2
|
|
23
|
-
} from "./server-
|
|
24
|
-
import {
|
|
25
|
-
estimateTokens
|
|
26
|
-
} from "./server-s6jqh8bj.js";
|
|
23
|
+
} from "./server-f2xf5gcb.js";
|
|
27
24
|
import {
|
|
28
25
|
SYNAPSE_DEFAULT_MODEL,
|
|
29
26
|
isSynapseEmbeddingTruncated,
|
|
30
27
|
getSynapseBatchRequestKey,
|
|
31
28
|
SynapseEmbeddingProvider
|
|
32
|
-
} from "./server-
|
|
29
|
+
} from "./server-rrqpvwqd.js";
|
|
33
30
|
import {
|
|
31
|
+
estimateTokens
|
|
32
|
+
} from "./server-0ppsweh6.js";
|
|
33
|
+
import {
|
|
34
|
+
DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS,
|
|
34
35
|
CHUNK_WINDOW_SAFETY_RATIO,
|
|
35
36
|
normalizeCompartmentChunkMaxInputTokens,
|
|
36
37
|
buildCanonicalChunkTextFromFts,
|
|
@@ -46,7 +47,15 @@ import {
|
|
|
46
47
|
countSessionCompartmentEmbedCoverage,
|
|
47
48
|
countSessionCompartmentEmbedCoveragePolite,
|
|
48
49
|
countUnembeddedSessionCompartmentsPolite
|
|
49
|
-
} from "./server-
|
|
50
|
+
} from "./server-qhfvvfxj.js";
|
|
51
|
+
import {
|
|
52
|
+
acquireGitSweepLease,
|
|
53
|
+
renewGitSweepLease,
|
|
54
|
+
releaseGitSweepLease,
|
|
55
|
+
findMisScopedCompartmentChunkEmbeddingIdsForProject,
|
|
56
|
+
recordSessionProjectIdentity,
|
|
57
|
+
repairMisScopedCompartmentChunkEmbeddingsForProject
|
|
58
|
+
} from "./server-4gn3z5an.js";
|
|
50
59
|
import {
|
|
51
60
|
saveEmbeddingIfHashMatches,
|
|
52
61
|
getMemoryEmbedCoverage,
|
|
@@ -58,10 +67,48 @@ import {
|
|
|
58
67
|
resolveEmbeddingTextPrefixes,
|
|
59
68
|
getEmbeddingProviderIdentity,
|
|
60
69
|
LocalEmbeddingProvider
|
|
61
|
-
} from "./server-
|
|
70
|
+
} from "./server-g10mdym6.js";
|
|
62
71
|
import {
|
|
63
72
|
logSlowWriteTransaction
|
|
64
|
-
} from "./server-
|
|
73
|
+
} from "./server-6pmqg9m4.js";
|
|
74
|
+
|
|
75
|
+
// src/hooks/magic-context/embed-session-state.ts
|
|
76
|
+
var embedPauseBySession = new Set;
|
|
77
|
+
var embedRunStateBySession = new Map;
|
|
78
|
+
var activeEmbeddingSessions = new Map;
|
|
79
|
+
var autoEmbedAttemptedBySession = new Set;
|
|
80
|
+
var autoEmbedIdentityBySession = new Map;
|
|
81
|
+
var autoEmbedRetryAfterBySession = new Map;
|
|
82
|
+
function invalidateAutoEmbedSession(sessionId) {
|
|
83
|
+
autoEmbedAttemptedBySession.delete(sessionId);
|
|
84
|
+
autoEmbedIdentityBySession.delete(sessionId);
|
|
85
|
+
autoEmbedRetryAfterBySession.delete(sessionId);
|
|
86
|
+
}
|
|
87
|
+
function getEmbedDrainUiStatus(sessionId, progress) {
|
|
88
|
+
if (embedPauseBySession.has(sessionId)) {
|
|
89
|
+
return { status: "paused" };
|
|
90
|
+
}
|
|
91
|
+
const activeRun = embedRunStateBySession.get(sessionId);
|
|
92
|
+
if (activeRun && !activeRun.signal.aborted || progress?.kind === "embed" && progress.phase === "recomp") {
|
|
93
|
+
return { status: "running" };
|
|
94
|
+
}
|
|
95
|
+
if (progress?.kind === "embed" && (progress.phase === "failed" || progress.phase === "skipped") && progress.message) {
|
|
96
|
+
if (/provider/i.test(progress.message)) {
|
|
97
|
+
return { status: "stopped", detail: progress.message };
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return { status: "idle" };
|
|
101
|
+
}
|
|
102
|
+
function clearEmbedSessionState(sessionId) {
|
|
103
|
+
activeEmbeddingSessions.delete(sessionId);
|
|
104
|
+
embedPauseBySession.delete(sessionId);
|
|
105
|
+
const ctrl = embedRunStateBySession.get(sessionId);
|
|
106
|
+
if (ctrl) {
|
|
107
|
+
ctrl.abort();
|
|
108
|
+
embedRunStateBySession.delete(sessionId);
|
|
109
|
+
}
|
|
110
|
+
invalidateAutoEmbedSession(sessionId);
|
|
111
|
+
}
|
|
65
112
|
|
|
66
113
|
// src/shared/background-batch-drain.ts
|
|
67
114
|
async function drainBackgroundBatches(step, options = {}) {
|
|
@@ -142,7 +189,85 @@ function pruneSynapseBatchLedgerForProject(db, projectIdentity, ttlMs = SYNAPSE_
|
|
|
142
189
|
}
|
|
143
190
|
|
|
144
191
|
// src/features/magic-context/project-embedding-registry.ts
|
|
145
|
-
import { createHash as
|
|
192
|
+
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
193
|
+
|
|
194
|
+
// src/features/magic-context/chunk-embedding-writer.ts
|
|
195
|
+
import { Worker } from "node:worker_threads";
|
|
196
|
+
function createChunkEmbeddingWriter(db) {
|
|
197
|
+
const path = getSqliteDatabasePath2(db);
|
|
198
|
+
if (!path)
|
|
199
|
+
return null;
|
|
200
|
+
if (path.startsWith("file:"))
|
|
201
|
+
throw new Error("chunk embedding writer requires a filesystem path");
|
|
202
|
+
const entry = new URL(import.meta.url.endsWith(".ts") ? "./chunk-embedding-write-worker.ts" : "./chunk-embedding-write-worker.js", import.meta.url);
|
|
203
|
+
const timeout = db.prepare("PRAGMA busy_timeout").get().timeout;
|
|
204
|
+
const worker = inRootAsyncContext2(() => new Worker(entry, { workerData: { path, harness: getHarness2(), timeout } }));
|
|
205
|
+
let pending;
|
|
206
|
+
let failure;
|
|
207
|
+
let deadline;
|
|
208
|
+
worker.on("message", (reply) => {
|
|
209
|
+
clearTimeout(deadline);
|
|
210
|
+
const request = pending;
|
|
211
|
+
pending = undefined;
|
|
212
|
+
if (reply.error)
|
|
213
|
+
request?.reject(new Error(reply.error));
|
|
214
|
+
else
|
|
215
|
+
request?.resolve(reply.value);
|
|
216
|
+
});
|
|
217
|
+
const fail = (error) => {
|
|
218
|
+
clearTimeout(deadline);
|
|
219
|
+
failure = error;
|
|
220
|
+
pending?.reject(error);
|
|
221
|
+
pending = undefined;
|
|
222
|
+
};
|
|
223
|
+
worker.on("error", fail);
|
|
224
|
+
worker.on("exit", (code) => fail(new Error(`chunk embedding writer exited (${code})`)));
|
|
225
|
+
worker.unref();
|
|
226
|
+
let queue = Promise.resolve();
|
|
227
|
+
const request = (message) => {
|
|
228
|
+
const result = queue.then(() => {
|
|
229
|
+
if (failure)
|
|
230
|
+
throw failure;
|
|
231
|
+
return new Promise((resolve, reject) => {
|
|
232
|
+
pending = { resolve, reject };
|
|
233
|
+
deadline = inRootAsyncContext2(() => setTimeout(() => {
|
|
234
|
+
fail(new Error("chunk embedding database operation timed out; coverage will be rechecked"));
|
|
235
|
+
worker.terminate();
|
|
236
|
+
}, 30000));
|
|
237
|
+
deadline.unref();
|
|
238
|
+
worker.postMessage(message);
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
queue = result.catch(() => {});
|
|
242
|
+
return result;
|
|
243
|
+
};
|
|
244
|
+
return {
|
|
245
|
+
async replace(rows, sourceKey) {
|
|
246
|
+
if (rows.some((row) => isSynapseEmbeddingTruncated(row.vector)))
|
|
247
|
+
return;
|
|
248
|
+
await request({ kind: "replace", rows, sourceKey });
|
|
249
|
+
},
|
|
250
|
+
project: (project, session) => request({ kind: "project", project, session }),
|
|
251
|
+
count: (project, session, model, tokens) => request({ kind: "count", project, session, model, tokens }),
|
|
252
|
+
candidates: (project, session, model, limit, excluded, tokens) => request({
|
|
253
|
+
kind: "candidates",
|
|
254
|
+
project,
|
|
255
|
+
session,
|
|
256
|
+
model,
|
|
257
|
+
limit,
|
|
258
|
+
excluded,
|
|
259
|
+
tokens
|
|
260
|
+
}),
|
|
261
|
+
backoff: (candidate, project, model) => request({ kind: "backoff", candidate, project, model }),
|
|
262
|
+
acquire: (project, holder) => request({ kind: "acquire", project, holder }),
|
|
263
|
+
renew: (project, holder) => request({ kind: "renew", project, holder }),
|
|
264
|
+
release: (project, holder) => request({ kind: "release", project, holder }),
|
|
265
|
+
async close() {
|
|
266
|
+
clearTimeout(deadline);
|
|
267
|
+
await worker.terminate();
|
|
268
|
+
}
|
|
269
|
+
};
|
|
270
|
+
}
|
|
146
271
|
|
|
147
272
|
// src/features/magic-context/git-commits/storage-git-commit-embeddings.ts
|
|
148
273
|
var saveStatements = new WeakMap;
|
|
@@ -326,141 +451,8 @@ function enforceProjectCap(db, projectPath, maxCommits) {
|
|
|
326
451
|
return evicted;
|
|
327
452
|
}
|
|
328
453
|
|
|
329
|
-
// src/features/magic-context/
|
|
330
|
-
|
|
331
|
-
var GIT_SWEEP_LEASE_TTL_MS = 5 * 60 * 1000;
|
|
332
|
-
var GIT_SWEEP_NON_INDEXABLE_REPROBE_MS = 24 * 60 * 60 * 1000;
|
|
333
|
-
var GIT_SWEEP_LEASE_RENEWAL_MS = 60 * 1000;
|
|
334
|
-
function runImmediate(db, body) {
|
|
335
|
-
db.exec("BEGIN IMMEDIATE");
|
|
336
|
-
const transactionStartedAt = performance.now();
|
|
337
|
-
let committed = false;
|
|
338
|
-
try {
|
|
339
|
-
const result = body();
|
|
340
|
-
db.exec("COMMIT");
|
|
341
|
-
committed = true;
|
|
342
|
-
logSlowWriteTransaction("git_sweep_lease", transactionStartedAt);
|
|
343
|
-
return result;
|
|
344
|
-
} finally {
|
|
345
|
-
if (!committed) {
|
|
346
|
-
try {
|
|
347
|
-
db.exec("ROLLBACK");
|
|
348
|
-
} catch {}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
function rowToState(row) {
|
|
353
|
-
return {
|
|
354
|
-
projectPath: row.project_path,
|
|
355
|
-
leaseHolder: row.lease_holder,
|
|
356
|
-
leaseExpiresAt: row.lease_expires_at,
|
|
357
|
-
lastSweptAt: row.last_swept_at
|
|
358
|
-
};
|
|
359
|
-
}
|
|
360
|
-
function getGitSweepCoordinatorState(db, projectPath) {
|
|
361
|
-
const row = db.prepare(`SELECT project_path, lease_holder, lease_expires_at, last_swept_at
|
|
362
|
-
FROM git_sweep_coordinator
|
|
363
|
-
WHERE project_path = ?`).get(projectPath);
|
|
364
|
-
return row ? rowToState(row) : null;
|
|
365
|
-
}
|
|
366
|
-
function acquireGitSweepLease(db, projectPath, holderId, options = {}) {
|
|
367
|
-
const cooldownMs = options.cooldownMs ?? GIT_SWEEP_COOLDOWN_MS;
|
|
368
|
-
const leaseTtlMs = options.leaseTtlMs ?? GIT_SWEEP_LEASE_TTL_MS;
|
|
369
|
-
return runImmediate(db, () => {
|
|
370
|
-
const now = Date.now();
|
|
371
|
-
const row = getGitSweepCoordinatorState(db, projectPath);
|
|
372
|
-
if (row?.leaseHolder && row.leaseExpiresAt !== null && row.leaseExpiresAt > now) {
|
|
373
|
-
return {
|
|
374
|
-
acquired: false,
|
|
375
|
-
projectPath,
|
|
376
|
-
reason: "lease_active",
|
|
377
|
-
leaseHolder: row.leaseHolder,
|
|
378
|
-
leaseExpiresAt: row.leaseExpiresAt,
|
|
379
|
-
lastSweptAt: row.lastSweptAt,
|
|
380
|
-
nextAllowedAt: null
|
|
381
|
-
};
|
|
382
|
-
}
|
|
383
|
-
if (!options.ignoreCooldown && row?.lastSweptAt !== null && row?.lastSweptAt !== undefined) {
|
|
384
|
-
const nextAllowedAt = row.lastSweptAt + cooldownMs;
|
|
385
|
-
if (nextAllowedAt > now) {
|
|
386
|
-
return {
|
|
387
|
-
acquired: false,
|
|
388
|
-
projectPath,
|
|
389
|
-
reason: "cooldown_active",
|
|
390
|
-
leaseHolder: row.leaseHolder,
|
|
391
|
-
leaseExpiresAt: row.leaseExpiresAt,
|
|
392
|
-
lastSweptAt: row.lastSweptAt,
|
|
393
|
-
nextAllowedAt
|
|
394
|
-
};
|
|
395
|
-
}
|
|
396
|
-
}
|
|
397
|
-
const leaseExpiresAt = now + leaseTtlMs;
|
|
398
|
-
db.prepare(`INSERT INTO git_sweep_coordinator (
|
|
399
|
-
project_path,
|
|
400
|
-
lease_holder,
|
|
401
|
-
lease_expires_at,
|
|
402
|
-
last_swept_at
|
|
403
|
-
) VALUES (?, ?, ?, NULL)
|
|
404
|
-
ON CONFLICT(project_path) DO UPDATE SET
|
|
405
|
-
lease_holder = excluded.lease_holder,
|
|
406
|
-
lease_expires_at = excluded.lease_expires_at`).run(projectPath, holderId, leaseExpiresAt);
|
|
407
|
-
return {
|
|
408
|
-
acquired: true,
|
|
409
|
-
projectPath,
|
|
410
|
-
holderId,
|
|
411
|
-
acquiredAt: now,
|
|
412
|
-
leaseExpiresAt
|
|
413
|
-
};
|
|
414
|
-
});
|
|
415
|
-
}
|
|
416
|
-
function renewGitSweepLease(db, projectPath, holderId, leaseTtlMs = GIT_SWEEP_LEASE_TTL_MS) {
|
|
417
|
-
return runImmediate(db, () => {
|
|
418
|
-
const now = Date.now();
|
|
419
|
-
const leaseExpiresAt = now + leaseTtlMs;
|
|
420
|
-
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
421
|
-
SET lease_expires_at = ?
|
|
422
|
-
WHERE project_path = ?
|
|
423
|
-
AND lease_holder = ?
|
|
424
|
-
AND lease_expires_at > ?`).run(leaseExpiresAt, projectPath, holderId, now);
|
|
425
|
-
return result.changes === 1;
|
|
426
|
-
});
|
|
427
|
-
}
|
|
428
|
-
function markGitSweepSuccessAndRelease(db, projectPath, holderId) {
|
|
429
|
-
return runImmediate(db, () => {
|
|
430
|
-
const now = Date.now();
|
|
431
|
-
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
432
|
-
SET lease_holder = NULL,
|
|
433
|
-
lease_expires_at = NULL,
|
|
434
|
-
last_swept_at = ?
|
|
435
|
-
WHERE project_path = ?
|
|
436
|
-
AND lease_holder = ?
|
|
437
|
-
AND lease_expires_at > ?`).run(now, projectPath, holderId, now);
|
|
438
|
-
return result.changes === 1;
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
function parkGitSweepNonIndexable(db, projectPath, holderId, reprobeMs = GIT_SWEEP_NON_INDEXABLE_REPROBE_MS) {
|
|
442
|
-
return runImmediate(db, () => {
|
|
443
|
-
const now = Date.now();
|
|
444
|
-
const sweptAt = now + reprobeMs - GIT_SWEEP_COOLDOWN_MS;
|
|
445
|
-
const result = db.prepare(`UPDATE git_sweep_coordinator
|
|
446
|
-
SET lease_holder = NULL,
|
|
447
|
-
lease_expires_at = NULL,
|
|
448
|
-
last_swept_at = ?
|
|
449
|
-
WHERE project_path = ?
|
|
450
|
-
AND lease_holder = ?
|
|
451
|
-
AND lease_expires_at > ?`).run(sweptAt, projectPath, holderId, now);
|
|
452
|
-
return result.changes === 1;
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
function releaseGitSweepLease(db, projectPath, holderId) {
|
|
456
|
-
runImmediate(db, () => {
|
|
457
|
-
db.prepare(`UPDATE git_sweep_coordinator
|
|
458
|
-
SET lease_holder = NULL,
|
|
459
|
-
lease_expires_at = NULL
|
|
460
|
-
WHERE project_path = ?
|
|
461
|
-
AND lease_holder = ?`).run(projectPath, holderId);
|
|
462
|
-
});
|
|
463
|
-
}
|
|
454
|
+
// src/features/magic-context/memory/embedding-openai.ts
|
|
455
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
464
456
|
|
|
465
457
|
// src/features/magic-context/memory/embedding-ssrf.ts
|
|
466
458
|
var METADATA_HOSTNAMES = new Set(["metadata.google.internal", "metadata.goog"]);
|
|
@@ -561,6 +553,55 @@ var FAILURE_THRESHOLD = 3;
|
|
|
561
553
|
var FAILURE_WINDOW_MS = 60000;
|
|
562
554
|
var OPEN_DURATION_MS = 5 * 60000;
|
|
563
555
|
var FETCH_TIMEOUT_MS = 30000;
|
|
556
|
+
var RETRY_AFTER_CAP_MS = 60000;
|
|
557
|
+
var RATE_LIMIT_BACKOFF_BASE_MS = 1000;
|
|
558
|
+
var RATE_LIMIT_BACKOFF_CAP_MS = 30000;
|
|
559
|
+
var RATE_LIMIT_BACKOFF_JITTER = 0.25;
|
|
560
|
+
var rateLimitStates = new Map;
|
|
561
|
+
function rateLimitStateKey(endpoint, apiKey) {
|
|
562
|
+
const keyHash = apiKey ? createHash2("sha256").update(apiKey).digest("hex").slice(0, 16) : "";
|
|
563
|
+
return `${endpoint}\x00${keyHash}`;
|
|
564
|
+
}
|
|
565
|
+
function parseRetryAfterMs(value, nowMs) {
|
|
566
|
+
const trimmed = value?.trim() ?? "";
|
|
567
|
+
if (!trimmed)
|
|
568
|
+
return null;
|
|
569
|
+
let delayMs;
|
|
570
|
+
if (/^\d+(?:\.\d+)?$/.test(trimmed)) {
|
|
571
|
+
delayMs = Number(trimmed) * 1000;
|
|
572
|
+
} else {
|
|
573
|
+
const at = Date.parse(trimmed);
|
|
574
|
+
if (!Number.isFinite(at))
|
|
575
|
+
return null;
|
|
576
|
+
delayMs = at - nowMs;
|
|
577
|
+
}
|
|
578
|
+
if (!(delayMs > 0))
|
|
579
|
+
return null;
|
|
580
|
+
return Math.min(Math.ceil(delayMs), RETRY_AFTER_CAP_MS);
|
|
581
|
+
}
|
|
582
|
+
function rateLimitBackoffMs(consecutive, random = Math.random) {
|
|
583
|
+
const exponent = Math.min(Math.max(0, Math.floor(consecutive)), 30);
|
|
584
|
+
const nominal = Math.min(RATE_LIMIT_BACKOFF_CAP_MS, RATE_LIMIT_BACKOFF_BASE_MS * 2 ** exponent);
|
|
585
|
+
const jitter = Math.min(1, Math.max(0, random())) * RATE_LIMIT_BACKOFF_JITTER;
|
|
586
|
+
return Math.min(RATE_LIMIT_BACKOFF_CAP_MS, Math.round(nominal * (1 + jitter)));
|
|
587
|
+
}
|
|
588
|
+
function sleepUnlessAborted(ms, signal) {
|
|
589
|
+
if (signal?.aborted)
|
|
590
|
+
return Promise.resolve(false);
|
|
591
|
+
return new Promise((resolve) => {
|
|
592
|
+
const onAbort = () => {
|
|
593
|
+
clearTimeout(timer);
|
|
594
|
+
resolve(false);
|
|
595
|
+
};
|
|
596
|
+
const timer = setTimeout(() => {
|
|
597
|
+
signal?.removeEventListener("abort", onAbort);
|
|
598
|
+
resolve(true);
|
|
599
|
+
}, ms);
|
|
600
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
601
|
+
});
|
|
602
|
+
}
|
|
603
|
+
var RATE_LIMITED = Symbol("rate-limited");
|
|
604
|
+
var maxInputTokensWarnings = new Set;
|
|
564
605
|
|
|
565
606
|
class OpenAICompatibleEmbeddingProvider {
|
|
566
607
|
modelId;
|
|
@@ -581,6 +622,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
581
622
|
lastFailureReason = null;
|
|
582
623
|
halfOpenProbeInFlight = false;
|
|
583
624
|
queryTruncationLogged = false;
|
|
625
|
+
rateLimitKey;
|
|
584
626
|
constructor(options) {
|
|
585
627
|
this.endpoint = normalizeEndpoint(options.endpoint);
|
|
586
628
|
this.model = options.model?.trim() ?? "";
|
|
@@ -591,7 +633,16 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
591
633
|
this.queryPrefix = prefixes.queryPrefix;
|
|
592
634
|
this.documentPrefix = prefixes.documentPrefix;
|
|
593
635
|
this.truncate = options.truncate?.trim() ?? "";
|
|
594
|
-
this.
|
|
636
|
+
this.rateLimitKey = rateLimitStateKey(this.endpoint, this.apiKey);
|
|
637
|
+
const maxInputTokensSet = typeof options.maxInputTokens === "number" && Number.isFinite(options.maxInputTokens);
|
|
638
|
+
this.maxInputTokens = maxInputTokensSet ? Math.max(1, Math.floor(options.maxInputTokens)) : DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS;
|
|
639
|
+
if (!maxInputTokensSet && this.endpoint && this.model) {
|
|
640
|
+
const warningKey = `${this.endpoint}\x00${this.model}`;
|
|
641
|
+
if (!maxInputTokensWarnings.has(warningKey)) {
|
|
642
|
+
maxInputTokensWarnings.add(warningKey);
|
|
643
|
+
log2(`[magic-context] embedding.max_input_tokens is not set for openai-compatible model "${sanitizeDiagnosticText(this.model)}"; chunk embeddings use the ${DEFAULT_COMPARTMENT_CHUNK_MAX_INPUT_TOKENS}-token default, which is sized for the bundled local model and splits history into small pieces. Set embedding.max_input_tokens to the model's input limit (changing it re-embeds stored chunks once).`);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
595
646
|
this.modelId = getEmbeddingProviderIdentity({
|
|
596
647
|
provider: "openai-compatible",
|
|
597
648
|
endpoint: this.endpoint,
|
|
@@ -649,6 +700,23 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
649
700
|
if (signal?.aborted) {
|
|
650
701
|
return Array.from({ length: texts.length }, () => null);
|
|
651
702
|
}
|
|
703
|
+
const isQuery = purpose === "query";
|
|
704
|
+
for (;; ) {
|
|
705
|
+
if (Date.now() < this.rateLimit.until) {
|
|
706
|
+
if (isQuery)
|
|
707
|
+
return Array.from({ length: texts.length }, () => null);
|
|
708
|
+
if (!await this.waitForRateLimitCooldown(signal)) {
|
|
709
|
+
return Array.from({ length: texts.length }, () => null);
|
|
710
|
+
}
|
|
711
|
+
}
|
|
712
|
+
const outcome = await this.requestOnce(texts, requestTexts, signal, purpose);
|
|
713
|
+
if (outcome !== RATE_LIMITED)
|
|
714
|
+
return outcome;
|
|
715
|
+
if (isQuery)
|
|
716
|
+
return Array.from({ length: texts.length }, () => null);
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
async requestOnce(texts, requestTexts, signal, purpose) {
|
|
652
720
|
let isProbe = false;
|
|
653
721
|
let internalController;
|
|
654
722
|
let timeoutHandle;
|
|
@@ -681,9 +749,14 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
681
749
|
redirect: "error",
|
|
682
750
|
signal: internalController.signal
|
|
683
751
|
});
|
|
752
|
+
if (response.status === 429) {
|
|
753
|
+
await response.text().catch(() => "");
|
|
754
|
+
this.noteRateLimit(response.headers.get("retry-after"));
|
|
755
|
+
return RATE_LIMITED;
|
|
756
|
+
}
|
|
684
757
|
if (!response.ok) {
|
|
685
758
|
const excerpt = await response.text().catch(() => "");
|
|
686
|
-
const failure = this.failure("http_error", `HTTP ${response.status} from endpoint${this.bodyExcerpt(excerpt)}`, response.status >= 500 || response.status === 408
|
|
759
|
+
const failure = this.failure("http_error", `HTTP ${response.status} from endpoint${this.bodyExcerpt(excerpt)}`, response.status >= 500 || response.status === 408);
|
|
687
760
|
log2(`[magic-context] openai-compatible embedding request failed: ${failure.reason}`);
|
|
688
761
|
this.recordFailure(isProbe, failure);
|
|
689
762
|
return Array.from({ length: texts.length }, () => null);
|
|
@@ -782,6 +855,36 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
782
855
|
isLoaded() {
|
|
783
856
|
return this.initialized;
|
|
784
857
|
}
|
|
858
|
+
get rateLimit() {
|
|
859
|
+
let state = rateLimitStates.get(this.rateLimitKey);
|
|
860
|
+
if (!state) {
|
|
861
|
+
state = { until: 0, consecutive: 0 };
|
|
862
|
+
rateLimitStates.set(this.rateLimitKey, state);
|
|
863
|
+
}
|
|
864
|
+
return state;
|
|
865
|
+
}
|
|
866
|
+
async waitForRateLimitCooldown(signal) {
|
|
867
|
+
for (;; ) {
|
|
868
|
+
const remaining = this.rateLimit.until - Date.now();
|
|
869
|
+
if (remaining <= 0)
|
|
870
|
+
return true;
|
|
871
|
+
if (!await sleepUnlessAborted(remaining, signal))
|
|
872
|
+
return false;
|
|
873
|
+
}
|
|
874
|
+
}
|
|
875
|
+
noteRateLimit(retryAfter) {
|
|
876
|
+
const state = this.rateLimit;
|
|
877
|
+
const now = Date.now();
|
|
878
|
+
const headerDelayMs = parseRetryAfterMs(retryAfter, now);
|
|
879
|
+
const delayMs = headerDelayMs ?? rateLimitBackoffMs(state.consecutive);
|
|
880
|
+
state.consecutive += 1;
|
|
881
|
+
const alreadyCoolingDown = now < state.until;
|
|
882
|
+
state.until = Math.max(state.until, now + delayMs);
|
|
883
|
+
const seconds = Math.ceil(delayMs / 1000);
|
|
884
|
+
if (!alreadyCoolingDown) {
|
|
885
|
+
log2(`[magic-context] openai-compatible embedding rate limited (HTTP 429): pausing requests for ${seconds}s (${headerDelayMs !== null ? "Retry-After" : "backoff"}); background embedding resumes after the pause and searches run lexical-only until then`);
|
|
886
|
+
}
|
|
887
|
+
}
|
|
785
888
|
claimProbeOrShortCircuit() {
|
|
786
889
|
if (this.circuitOpenUntil === 0) {
|
|
787
890
|
return "allow";
|
|
@@ -836,6 +939,7 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
836
939
|
this.circuitOpenUntil = 0;
|
|
837
940
|
this.openLogged = false;
|
|
838
941
|
this.lastFailureReason = null;
|
|
942
|
+
this.rateLimit.consecutive = 0;
|
|
839
943
|
}
|
|
840
944
|
getLastFailureReason() {
|
|
841
945
|
return this.lastFailureReason;
|
|
@@ -851,6 +955,9 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
851
955
|
_getFailureCount() {
|
|
852
956
|
return this.failureTimes.length;
|
|
853
957
|
}
|
|
958
|
+
_getRateLimitedUntil() {
|
|
959
|
+
return this.rateLimit.until;
|
|
960
|
+
}
|
|
854
961
|
_resetCircuit() {
|
|
855
962
|
this.failureTimes = [];
|
|
856
963
|
this.circuitOpenUntil = 0;
|
|
@@ -860,88 +967,6 @@ class OpenAICompatibleEmbeddingProvider {
|
|
|
860
967
|
}
|
|
861
968
|
}
|
|
862
969
|
|
|
863
|
-
// src/features/magic-context/session-project-storage.ts
|
|
864
|
-
var SESSION_CHUNK_REPAIR_BATCH_SIZE = 100;
|
|
865
|
-
var upsertSessionProjectStatements = new WeakMap;
|
|
866
|
-
var repairSessionChunkProjectStatements = new WeakMap;
|
|
867
|
-
var misScopedProjectChunkStatements = new WeakMap;
|
|
868
|
-
var MIS_SCOPED_PROJECT_CHUNK_IDS_SQL = `
|
|
869
|
-
SELECT e.id FROM compartment_chunk_embeddings e
|
|
870
|
-
JOIN session_projects sp ON sp.session_id = e.session_id AND sp.harness = e.harness
|
|
871
|
-
WHERE e.project_path = ? AND sp.project_path <> e.project_path
|
|
872
|
-
UNION ALL
|
|
873
|
-
SELECT e.id FROM session_projects sp
|
|
874
|
-
JOIN compartment_chunk_embeddings e ON e.session_id = sp.session_id
|
|
875
|
-
WHERE sp.project_path = ? AND e.harness = sp.harness AND e.project_path <> sp.project_path`;
|
|
876
|
-
function getUpsertSessionProjectStatement(db) {
|
|
877
|
-
let stmt = upsertSessionProjectStatements.get(db);
|
|
878
|
-
if (!stmt) {
|
|
879
|
-
stmt = db.prepare(`INSERT INTO session_projects (session_id, harness, project_path, updated_at)
|
|
880
|
-
VALUES (?, ?, ?, ?)
|
|
881
|
-
ON CONFLICT(session_id, harness) DO UPDATE SET
|
|
882
|
-
project_path = excluded.project_path,
|
|
883
|
-
updated_at = excluded.updated_at
|
|
884
|
-
WHERE session_projects.project_path <> excluded.project_path`);
|
|
885
|
-
upsertSessionProjectStatements.set(db, stmt);
|
|
886
|
-
}
|
|
887
|
-
return stmt;
|
|
888
|
-
}
|
|
889
|
-
function getRepairSessionChunkProjectStatement(db) {
|
|
890
|
-
let stmt = repairSessionChunkProjectStatements.get(db);
|
|
891
|
-
if (!stmt) {
|
|
892
|
-
stmt = db.prepare(`UPDATE compartment_chunk_embeddings
|
|
893
|
-
SET project_path = ?
|
|
894
|
-
WHERE id IN (
|
|
895
|
-
SELECT id
|
|
896
|
-
FROM compartment_chunk_embeddings
|
|
897
|
-
WHERE session_id = ?
|
|
898
|
-
AND harness = ?
|
|
899
|
-
AND project_path <> ?
|
|
900
|
-
LIMIT ?
|
|
901
|
-
)`);
|
|
902
|
-
repairSessionChunkProjectStatements.set(db, stmt);
|
|
903
|
-
}
|
|
904
|
-
return stmt;
|
|
905
|
-
}
|
|
906
|
-
function findMisScopedCompartmentChunkEmbeddingIdsForProject(db, projectPath) {
|
|
907
|
-
return db.prepare(`SELECT id FROM (${MIS_SCOPED_PROJECT_CHUNK_IDS_SQL}) LIMIT 25`).all(projectPath, projectPath).map(({ id }) => id);
|
|
908
|
-
}
|
|
909
|
-
function recordSessionProjectIdentity(db, sessionId, projectPath) {
|
|
910
|
-
if (!sessionId || !projectPath)
|
|
911
|
-
return;
|
|
912
|
-
if (!projectPath.startsWith("git:") && !projectPath.startsWith("dir:") && isUserHomeDirectory(projectPath))
|
|
913
|
-
return;
|
|
914
|
-
const harness = getHarness2();
|
|
915
|
-
const now = Date.now();
|
|
916
|
-
let previousProjectPath;
|
|
917
|
-
db.transaction(() => {
|
|
918
|
-
const existing = db.prepare("SELECT project_path FROM session_projects WHERE session_id = ? AND harness = ?").get(sessionId, harness);
|
|
919
|
-
previousProjectPath = existing?.project_path;
|
|
920
|
-
getUpsertSessionProjectStatement(db).run(sessionId, harness, projectPath, now);
|
|
921
|
-
getRepairSessionChunkProjectStatement(db).run(projectPath, sessionId, harness, projectPath, SESSION_CHUNK_REPAIR_BATCH_SIZE);
|
|
922
|
-
}).immediate();
|
|
923
|
-
return previousProjectPath === projectPath ? undefined : { previousProjectPath, projectPath };
|
|
924
|
-
}
|
|
925
|
-
function hasRecordedSessionProjectIdentity(db, sessionId) {
|
|
926
|
-
const row = db.prepare("SELECT 1 AS found FROM session_projects WHERE session_id = ? AND harness = ?").get(sessionId, getHarness2());
|
|
927
|
-
return row?.found === 1;
|
|
928
|
-
}
|
|
929
|
-
function repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectPath, ids = findMisScopedCompartmentChunkEmbeddingIdsForProject(db, projectPath)) {
|
|
930
|
-
if (!projectPath || ids.length === 0)
|
|
931
|
-
return 0;
|
|
932
|
-
return db.prepare(`UPDATE compartment_chunk_embeddings
|
|
933
|
-
SET project_path = (SELECT sp.project_path FROM session_projects sp
|
|
934
|
-
WHERE sp.session_id = compartment_chunk_embeddings.session_id
|
|
935
|
-
AND sp.harness = compartment_chunk_embeddings.harness)
|
|
936
|
-
WHERE id IN (${ids.map(() => "?").join(",")}) AND EXISTS (
|
|
937
|
-
SELECT 1 FROM session_projects sp
|
|
938
|
-
WHERE sp.session_id = compartment_chunk_embeddings.session_id
|
|
939
|
-
AND sp.harness = compartment_chunk_embeddings.harness
|
|
940
|
-
AND sp.project_path <> compartment_chunk_embeddings.project_path
|
|
941
|
-
AND (sp.project_path = ? OR compartment_chunk_embeddings.project_path = ?)
|
|
942
|
-
)`).run(...ids, projectPath, projectPath).changes;
|
|
943
|
-
}
|
|
944
|
-
|
|
945
970
|
// src/features/magic-context/shadow-backfill-state.ts
|
|
946
971
|
var SHADOW_BACKFILL_PROVENANCE_KEY = "_magicContextShadowBackfill";
|
|
947
972
|
function parseJsonRecord(value) {
|
|
@@ -1305,10 +1330,10 @@ function stableStringify(value) {
|
|
|
1305
1330
|
return JSON.stringify(value);
|
|
1306
1331
|
}
|
|
1307
1332
|
function sha256Prefix(value, length = 16) {
|
|
1308
|
-
return
|
|
1333
|
+
return createHash3("sha256").update(value).digest("hex").slice(0, length);
|
|
1309
1334
|
}
|
|
1310
1335
|
function contentSha2562(value) {
|
|
1311
|
-
return
|
|
1336
|
+
return createHash3("sha256").update(value).digest("hex");
|
|
1312
1337
|
}
|
|
1313
1338
|
function getRuntimeFingerprint(config) {
|
|
1314
1339
|
if (config.provider === "off") {
|
|
@@ -2632,22 +2657,31 @@ async function drainCommitBacklogForProject2(db, projectIdentity, deadline) {
|
|
|
2632
2657
|
}
|
|
2633
2658
|
return total;
|
|
2634
2659
|
}
|
|
2635
|
-
async function embedCompartmentChunkBatch(db, projectIdentity, batchSize) {
|
|
2660
|
+
async function embedCompartmentChunkBatch(db, projectIdentity, batchSize, signal) {
|
|
2636
2661
|
const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
|
|
2637
2662
|
if (!snapshot?.historyEnabled || snapshot.chunkModelId === "off")
|
|
2638
2663
|
return 0;
|
|
2639
2664
|
repairMisScopedCompartmentChunkEmbeddingsForProject(db, projectIdentity);
|
|
2640
|
-
const
|
|
2665
|
+
const priorModels = db.prepare(`SELECT COUNT(*) AS total,
|
|
2666
|
+
COALESCE(MAX(model_id = ?), 0) AS current
|
|
2667
|
+
FROM compartment_chunk_embeddings WHERE compartment_id = ?`);
|
|
2668
|
+
const candidates = await loadUnembeddedCompartmentChunkCandidatesPolite(db, projectIdentity, snapshot.chunkModelId, batchSize, getProjectEmbeddingMaxInputTokens2(projectIdentity), true, (candidate) => {
|
|
2669
|
+
const activity = activeEmbeddingSessions.get(candidate.sessionId);
|
|
2670
|
+
if (activity?.project === projectIdentity && activity.model === snapshot.chunkModelId && !embedPauseBySession.has(candidate.sessionId))
|
|
2671
|
+
return true;
|
|
2672
|
+
const prior = priorModels.get(snapshot.chunkModelId, candidate.id);
|
|
2673
|
+
return prior.total === 0 || prior.current !== 0;
|
|
2674
|
+
});
|
|
2641
2675
|
if (candidates.length === 0)
|
|
2642
2676
|
return 0;
|
|
2643
|
-
const { embedded } = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates);
|
|
2677
|
+
const { embedded } = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, signal);
|
|
2644
2678
|
return embedded;
|
|
2645
2679
|
}
|
|
2646
2680
|
function getLastEmbeddingFailureForProject(projectIdentity) {
|
|
2647
2681
|
const registration = projectRegistrations.get(projectIdentity);
|
|
2648
2682
|
return registration?.provider?.getLastFailureReason?.() ?? null;
|
|
2649
2683
|
}
|
|
2650
|
-
async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates, signal) {
|
|
2684
|
+
async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates, signal, writer) {
|
|
2651
2685
|
const noWork = [];
|
|
2652
2686
|
const failed = [];
|
|
2653
2687
|
const failureReasons = [];
|
|
@@ -2662,7 +2696,10 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
2662
2696
|
continue;
|
|
2663
2697
|
const canonicalText = mappedText || buildCompartmentSummaryFallbackText(db, candidate.id);
|
|
2664
2698
|
if (canonicalText.length === 0) {
|
|
2665
|
-
|
|
2699
|
+
if (writer)
|
|
2700
|
+
await writer.backoff(candidate, projectIdentity, modelId);
|
|
2701
|
+
else
|
|
2702
|
+
recordChunkEmbedBackoff(db, candidate, projectIdentity, modelId);
|
|
2666
2703
|
noWork.push(candidate.id);
|
|
2667
2704
|
continue;
|
|
2668
2705
|
}
|
|
@@ -2719,6 +2756,8 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
2719
2756
|
if (result) {
|
|
2720
2757
|
let writeSliceStarted = performance.now();
|
|
2721
2758
|
for (const item of slice) {
|
|
2759
|
+
if (signal?.aborted || getProjectChunkEmbeddingModelId2(projectIdentity) !== modelId)
|
|
2760
|
+
break;
|
|
2722
2761
|
if (persistedIds.has(item.candidate.id))
|
|
2723
2762
|
continue;
|
|
2724
2763
|
const vectors = item.windows.map((window) => result.vectors.get(`chunk:${item.candidate.id}:${window.windowIndex}`));
|
|
@@ -2733,7 +2772,10 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
2733
2772
|
modelId,
|
|
2734
2773
|
vector: vectors[index]
|
|
2735
2774
|
}));
|
|
2736
|
-
|
|
2775
|
+
if (writer)
|
|
2776
|
+
await writer.replace(rows, item.windowSourceKey);
|
|
2777
|
+
else
|
|
2778
|
+
replaceCompartmentChunkEmbeddings(db, rows, item.windowSourceKey);
|
|
2737
2779
|
persistedIds.add(item.candidate.id);
|
|
2738
2780
|
enqueueShadowEmbeddingItems2(projectIdentity, "chunk", [
|
|
2739
2781
|
String(item.candidate.id)
|
|
@@ -2758,7 +2800,10 @@ async function embedCandidateChunkBatch(db, projectIdentity, modelId, candidates
|
|
|
2758
2800
|
if (!signal?.aborted) {
|
|
2759
2801
|
for (const item of slice) {
|
|
2760
2802
|
if (!persistedIds.has(item.candidate.id)) {
|
|
2761
|
-
|
|
2803
|
+
if (writer)
|
|
2804
|
+
await writer.backoff(item.candidate, projectIdentity, modelId);
|
|
2805
|
+
else
|
|
2806
|
+
recordChunkEmbedBackoff(db, item.candidate, projectIdentity, modelId);
|
|
2762
2807
|
failed.push(item.candidate.id);
|
|
2763
2808
|
}
|
|
2764
2809
|
}
|
|
@@ -2777,6 +2822,9 @@ async function drainCompartmentChunkBacklogForProject(db, projectIdentity, deadl
|
|
|
2777
2822
|
}
|
|
2778
2823
|
let total = 0;
|
|
2779
2824
|
let leaseLost = false;
|
|
2825
|
+
const drainAbort = new AbortController;
|
|
2826
|
+
const deadlineTimer = setTimeout(() => drainAbort.abort(), Math.max(0, deadline - Date.now()));
|
|
2827
|
+
deadlineTimer.unref?.();
|
|
2780
2828
|
const renewal = inRootAsyncContext2(() => setInterval(() => {
|
|
2781
2829
|
try {
|
|
2782
2830
|
if (!renewGitSweepLease(db, projectIdentity, holderId))
|
|
@@ -2785,8 +2833,8 @@ async function drainCompartmentChunkBacklogForProject(db, projectIdentity, deadl
|
|
|
2785
2833
|
}, SESSION_EMBED_LEASE_RENEWAL_MS));
|
|
2786
2834
|
renewal.unref?.();
|
|
2787
2835
|
try {
|
|
2788
|
-
while (!leaseLost && !isEmbeddingHostBusy2() && Date.now() < deadline && total < CHUNK_DRAIN_MAX_PER_SWEEP) {
|
|
2789
|
-
const embedded = await embedCompartmentChunkBatch(db, projectIdentity, CHUNK_DRAIN_BATCH_SIZE);
|
|
2836
|
+
while (!leaseLost && !drainAbort.signal.aborted && !isEmbeddingHostBusy2() && Date.now() < deadline && total < CHUNK_DRAIN_MAX_PER_SWEEP) {
|
|
2837
|
+
const embedded = await embedCompartmentChunkBatch(db, projectIdentity, CHUNK_DRAIN_BATCH_SIZE, drainAbort.signal);
|
|
2790
2838
|
if (!renewGitSweepLease(db, projectIdentity, holderId))
|
|
2791
2839
|
leaseLost = true;
|
|
2792
2840
|
if (leaseLost || embedded === 0)
|
|
@@ -2796,6 +2844,7 @@ async function drainCompartmentChunkBacklogForProject(db, projectIdentity, deadl
|
|
|
2796
2844
|
break;
|
|
2797
2845
|
}
|
|
2798
2846
|
} finally {
|
|
2847
|
+
clearTimeout(deadlineTimer);
|
|
2799
2848
|
clearInterval(renewal);
|
|
2800
2849
|
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
2801
2850
|
}
|
|
@@ -2809,11 +2858,28 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
|
|
|
2809
2858
|
if (!snapshot?.historyEnabled || snapshot.chunkModelId === "off") {
|
|
2810
2859
|
return { status: "disabled", embedded: 0, total: 0 };
|
|
2811
2860
|
}
|
|
2812
|
-
|
|
2861
|
+
if (options?.automatic && !options.databaseWorker) {
|
|
2862
|
+
const worker = createChunkEmbeddingWriter(db);
|
|
2863
|
+
if (worker) {
|
|
2864
|
+
try {
|
|
2865
|
+
return await embedSessionCompartmentChunks2(db, projectIdentity, sessionId, {
|
|
2866
|
+
...options,
|
|
2867
|
+
databaseWorker: worker
|
|
2868
|
+
});
|
|
2869
|
+
} finally {
|
|
2870
|
+
await worker.close();
|
|
2871
|
+
}
|
|
2872
|
+
}
|
|
2873
|
+
}
|
|
2874
|
+
const writer = options?.databaseWorker ?? null;
|
|
2875
|
+
if (writer)
|
|
2876
|
+
await writer.project(projectIdentity, sessionId);
|
|
2877
|
+
else
|
|
2878
|
+
recordSessionProjectIdentity(db, sessionId, projectIdentity);
|
|
2813
2879
|
const maxInputTokens = getProjectEmbeddingMaxInputTokens2(projectIdentity);
|
|
2814
|
-
const total = await countUnembeddedSessionCompartmentsPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens);
|
|
2880
|
+
const total = writer ? await writer.count(projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens) : await countUnembeddedSessionCompartmentsPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens);
|
|
2815
2881
|
const holderId = `session-embed-${randomUUID()}`;
|
|
2816
|
-
const lease = acquireGitSweepLease(db, projectIdentity, holderId, { ignoreCooldown: true });
|
|
2882
|
+
const lease = writer ? await writer.acquire(projectIdentity, holderId) : acquireGitSweepLease(db, projectIdentity, holderId, { ignoreCooldown: true });
|
|
2817
2883
|
if (!lease.acquired)
|
|
2818
2884
|
return { status: "busy", embedded: 0, total };
|
|
2819
2885
|
let leaseLost = false;
|
|
@@ -2823,9 +2889,9 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
|
|
|
2823
2889
|
drainAbort.abort();
|
|
2824
2890
|
else
|
|
2825
2891
|
options?.signal?.addEventListener("abort", forwardCallerAbort, { once: true });
|
|
2826
|
-
const renewal = inRootAsyncContext2(() => setInterval(() => {
|
|
2892
|
+
const renewal = inRootAsyncContext2(() => setInterval(async () => {
|
|
2827
2893
|
try {
|
|
2828
|
-
if (!renewGitSweepLease(db, projectIdentity, holderId)) {
|
|
2894
|
+
if (!(writer ? await writer.renew(projectIdentity, holderId) : renewGitSweepLease(db, projectIdentity, holderId))) {
|
|
2829
2895
|
leaseLost = true;
|
|
2830
2896
|
drainAbort.abort();
|
|
2831
2897
|
}
|
|
@@ -2843,11 +2909,18 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
|
|
|
2843
2909
|
try {
|
|
2844
2910
|
options?.onProgress?.({ embedded, total });
|
|
2845
2911
|
for (;; ) {
|
|
2846
|
-
if (leaseLost || drainAbort.signal.aborted || isEmbeddingHostBusy2()) {
|
|
2912
|
+
if (leaseLost || drainAbort.signal.aborted || !options?.automatic && isEmbeddingHostBusy2() || getProjectEmbeddingSnapshot2(projectIdentity)?.generation !== snapshot.generation) {
|
|
2847
2913
|
aborted = true;
|
|
2848
2914
|
break;
|
|
2849
2915
|
}
|
|
2850
|
-
|
|
2916
|
+
if (options?.automatic && isEmbeddingHostBusy2()) {
|
|
2917
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
2918
|
+
if (drainAbort.signal.aborted) {
|
|
2919
|
+
aborted = true;
|
|
2920
|
+
break;
|
|
2921
|
+
}
|
|
2922
|
+
}
|
|
2923
|
+
const candidates = writer ? await writer.candidates(projectIdentity, sessionId, snapshot.chunkModelId, batchSize, [...skipIds, ...failedIds], maxInputTokens) : await loadUnembeddedSessionChunkCandidatesPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, batchSize, [...skipIds, ...failedIds], maxInputTokens, true);
|
|
2851
2924
|
if (candidates.length === 0)
|
|
2852
2925
|
break;
|
|
2853
2926
|
const {
|
|
@@ -2855,8 +2928,8 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
|
|
|
2855
2928
|
noWork,
|
|
2856
2929
|
failed,
|
|
2857
2930
|
failureReasons: batchFailureReasons
|
|
2858
|
-
} = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, drainAbort.signal);
|
|
2859
|
-
if (leaseLost || !renewGitSweepLease(db, projectIdentity, holderId)) {
|
|
2931
|
+
} = await embedCandidateChunkBatch(db, projectIdentity, snapshot.chunkModelId, candidates, drainAbort.signal, writer);
|
|
2932
|
+
if (leaseLost || !(writer ? await writer.renew(projectIdentity, holderId) : renewGitSweepLease(db, projectIdentity, holderId))) {
|
|
2860
2933
|
leaseLost = true;
|
|
2861
2934
|
drainAbort.abort();
|
|
2862
2935
|
aborted = true;
|
|
@@ -2884,7 +2957,10 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
|
|
|
2884
2957
|
clearInterval(renewal);
|
|
2885
2958
|
options?.signal?.removeEventListener("abort", forwardCallerAbort);
|
|
2886
2959
|
try {
|
|
2887
|
-
|
|
2960
|
+
if (writer)
|
|
2961
|
+
await writer.release(projectIdentity, holderId);
|
|
2962
|
+
else
|
|
2963
|
+
releaseGitSweepLease(db, projectIdentity, holderId);
|
|
2888
2964
|
} catch (error) {
|
|
2889
2965
|
log2("[magic-context] embed drain: lease release failed (will TTL-expire):", error);
|
|
2890
2966
|
}
|
|
@@ -2894,7 +2970,7 @@ async function embedSessionCompartmentChunks2(db, projectIdentity, sessionId, op
|
|
|
2894
2970
|
if (aborted)
|
|
2895
2971
|
return { status: "aborted", embedded, total, failed: failedIds.length };
|
|
2896
2972
|
if (providerDown || failedIds.length > 0) {
|
|
2897
|
-
const remaining = Math.max(failedIds.length, await countUnembeddedSessionCompartmentsPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens) - skipIds.length);
|
|
2973
|
+
const remaining = Math.max(failedIds.length, (writer ? await writer.count(projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens) : await countUnembeddedSessionCompartmentsPolite(db, projectIdentity, sessionId, snapshot.chunkModelId, maxInputTokens)) - skipIds.length);
|
|
2898
2974
|
if (remaining > 0) {
|
|
2899
2975
|
return {
|
|
2900
2976
|
status: "stalled",
|
|
@@ -3029,4 +3105,4 @@ function _resetProjectEmbeddingRegistryForTests2() {
|
|
|
3029
3105
|
setBootQuietPeriodForTests(null);
|
|
3030
3106
|
}
|
|
3031
3107
|
|
|
3032
|
-
export {
|
|
3108
|
+
export { embedPauseBySession, embedRunStateBySession, activeEmbeddingSessions, autoEmbedAttemptedBySession, autoEmbedIdentityBySession, autoEmbedRetryAfterBySession, invalidateAutoEmbedSession, getEmbedDrainUiStatus, clearEmbedSessionState, drainBackgroundBatches, recordEmbeddingMeasurement, saveCommitEmbedding, loadProjectCommitEmbeddings, loadUnembeddedCommits, countEmbeddedCommits, upsertCommits, getLatestIndexedCommitSha, enforceProjectCap, OpenAICompatibleEmbeddingProvider, describeShadowBackfillWriteRefusal2, listShadowBackfillStalls2, getShadowBackfillStopReason2, markProjectLoadUntrusted2, contentSha2562, drainProjectEmbeddingIdentityMaintenance2, drainStaleEmbeddingIdentitiesForProject2, registerProjectEmbedding2, registerProjectShadowEmbedding2, getShadowEmbeddingMeasurementCohort2, getPrimaryEmbeddingMeasurementCohort2, embedShadowTextForProject2, enqueueShadowEmbeddingItems2, getShadowBackfillRemaining2, flushShadowEmbeddingBacklog2, registerProjectInObservationMode2, unregisterProjectShadowEmbedding2, unregisterProjectEmbedding2, getProjectEmbeddingSnapshot2, installProjectEmbeddingSearchBridge2, getProjectChunkEmbeddingModelId2, getProjectEmbeddingMaxInputTokens2, embedTextForProject2, embedBatchForProject2, embedItemsForProject2, embedUnembeddedMemoriesForProject2, embedUnembeddedMemoriesForProjectOutcome2, drainCommitBacklogForProject2, embedUnembeddedCompartmentChunksForProject2, embedSessionCompartmentChunks2, getEmbeddingCoverageStatus2, getAutoEmbeddingSessionCoverage2, sweepAllRegisteredProjects2, _setTestProviderFactoryForProject2, _resetProjectEmbeddingRegistryForTests2 };
|