@cortexkit/opencode-magic-context 0.49.33 → 0.49.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auto-search-worker.js +11 -6
- package/dist/chunk-embedding-write-worker.js +16 -14
- package/dist/{compaction-marker-candidates-31h86ph0.js → compaction-marker-candidates-g0p67ced.js} +3 -2
- package/dist/compaction-marker-candidates-worker.js +1 -1
- package/dist/{compartment-chunk-embedding-5q5gj67r.js → compartment-chunk-embedding-y4136are.js} +8 -7
- package/dist/{conflict-warning-hook-xgskea1v.js → conflict-warning-hook-hhw8z5ak.js} +9 -8
- package/dist/{context-jyzkstnr.js → context-fk8e3h9p.js} +1400 -701
- package/dist/{derive-budgets-pqybnx09.js → derive-budgets-htj16n4x.js} +3 -2
- package/dist/embedding-backfill-q6n72sy0.js +27 -0
- package/dist/embedding-worker-process.js +2 -1
- package/dist/embedding-worker.js +5 -4
- package/dist/expand-attachments-h33jbgyz.js +21 -0
- package/dist/features/magic-context/auto-search-diagnostics.d.ts +21 -0
- package/dist/features/magic-context/auto-search-diagnostics.d.ts.map +1 -0
- package/dist/features/magic-context/compaction-marker.d.ts +22 -6
- package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
- 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/search.d.ts +4 -0
- package/dist/features/magic-context/search.d.ts.map +1 -1
- package/dist/features/magic-context/storage-meta-persisted.d.ts +7 -0
- package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
- package/dist/features/magic-context/store-generation-rebase-labels.d.ts +6 -0
- package/dist/features/magic-context/store-generation-rebase-labels.d.ts.map +1 -0
- package/dist/features/magic-context/store-generation-rebase.d.ts.map +1 -1
- package/dist/{history-owner-36wp3mkb.js → history-owner-0z620wgz.js} +3 -2
- package/dist/hooks/magic-context/apply-operations.d.ts +20 -3
- package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-observation.d.ts +13 -0
- package/dist/hooks/magic-context/auto-search-observation.d.ts.map +1 -0
- package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
- package/dist/hooks/magic-context/auto-search-worker-client.d.ts +5 -1
- package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts +5 -5
- package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
- package/dist/hooks/magic-context/compaction-marker-publication.d.ts +9 -0
- package/dist/hooks/magic-context/compaction-marker-publication.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-commit-hashes.d.ts +4 -0
- package/dist/hooks/magic-context/compartment-commit-hashes.d.ts.map +1 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts +1 -0
- package/dist/hooks/magic-context/compartment-runner-validation.d.ts.map +1 -1
- package/dist/hooks/magic-context/event-resolvers.d.ts.map +1 -1
- package/dist/hooks/magic-context/final-wire-completeness.d.ts +15 -0
- package/dist/hooks/magic-context/final-wire-completeness.d.ts.map +1 -0
- package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
- package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts +1 -0
- package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-chunk.d.ts +11 -0
- package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
- package/dist/hooks/magic-context/read-session-formatting.d.ts +2 -0
- package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
- package/dist/hooks/magic-context/transform.d.ts.map +1 -1
- package/dist/{index-as2amvn3.js → index-0c7p8mq5.js} +6 -531
- package/dist/{index-51rdvtkz.js → index-1rhgxqs8.js} +2 -2
- package/dist/index-2amn2s73.js +123 -0
- package/dist/{index-c7phnbvk.js → index-2p37txes.js} +1 -1
- package/dist/index-2qbtqg1w.js +529 -0
- package/dist/{index-waktfbjy.js → index-2v6nvy3k.js} +4 -4
- package/dist/{index-dq5xzeb9.js → index-3d3872c6.js} +7 -5
- package/dist/{index-qr2mb02j.js → index-3j9t1v4n.js} +55 -21
- package/dist/{index-2xh37qn5.js → index-4bgk5ztz.js} +576 -5524
- package/dist/{index-b88dwwrh.js → index-4xyjr62e.js} +1 -1
- package/dist/index-66a50f3e.js +777 -0
- package/dist/{index-94ef0qe2.js → index-87ctnzz9.js} +33 -5
- package/dist/{index-xrnsygfq.js → index-9wnbnx8f.js} +1 -1
- package/dist/{index-3fkk2gwj.js → index-b6xz3qbe.js} +246 -420
- package/dist/{index-0fe4q77z.js → index-brg2w6qc.js} +146 -134
- package/dist/{index-spwjbkc7.js → index-dnqqqc5f.js} +1 -1
- package/dist/index-dy7w6wm4.js +194 -0
- package/dist/{index-3jmx3fae.js → index-ezv6dz3y.js} +37 -7
- package/dist/index-f297z1n8.js +4557 -0
- package/dist/{index-qgh1qwjj.js → index-f9b3vtt1.js} +1 -1
- package/dist/{index-v15ne3a3.js → index-faxb7mck.js} +2 -2
- package/dist/{index-rrv26qjz.js → index-fw42ms3m.js} +1 -1
- package/dist/{index-t5pck3ss.js → index-fxbk7gk3.js} +1 -1
- package/dist/{index-wfybj1dw.js → index-g4t7850m.js} +2 -2
- package/dist/{index-hbt0sbv2.js → index-gyaa159j.js} +18 -276
- package/dist/{index-4pnsgvfk.js → index-hacf2tyx.js} +1 -1
- package/dist/{index-s1n8dd2n.js → index-jkanybgq.js} +2 -2
- package/dist/{index-2743x98y.js → index-jn0ddrhp.js} +29 -138
- package/dist/{index-h7tgn49j.js → index-jrfre9ah.js} +5 -222
- package/dist/{index-kfyb3k6n.js → index-jz5bk7xd.js} +2 -2
- package/dist/{index-np3rgfw4.js → index-ksv0a31x.js} +3 -3
- package/dist/{index-7kkphb6c.js → index-nj360hcs.js} +4 -4
- package/dist/{index-gkee6p4g.js → index-p56dszfp.js} +3 -3
- package/dist/{index-4s4zq97n.js → index-pq0dpwrc.js} +4 -4
- package/dist/{index-rfxzazzy.js → index-pswsyf1w.js} +4 -4
- package/dist/{index-y1qwzvxn.js → index-pztqab6k.js} +2 -2
- package/dist/{index-rverk2vz.js → index-qncw9hey.js} +1 -1
- package/dist/index-qx8j6kds.js +270 -0
- package/dist/{index-kq5w68dp.js → index-txs8tce6.js} +1 -1
- package/dist/index-vzhhr1ht.js +532 -0
- package/dist/index-wh9fxds5.js +265 -0
- package/dist/{index-b7w46fp2.js → index-x2mrq5xv.js} +170 -48
- package/dist/{index-43vqx0za.js → index-xwwsbsd3.js} +15 -13
- package/dist/index-z4p0ry94.js +222 -0
- package/dist/index-z9zygwse.js +89 -0
- package/dist/{index-v7287tzq.js → index-zhqwda72.js} +19 -8
- package/dist/index.js +83 -72
- package/dist/{logger-94kew5wm.js → logger-qwnbcfj9.js} +2 -1
- package/dist/{message-fts-rowid-map-va36knh4.js → message-fts-rowid-map-xg7hr0mk.js} +5 -4
- package/dist/{message-index-bounded-zq7a5nm6.js → message-index-bounded-narw7bnz.js} +12 -11
- package/dist/{message-time-backfill-4qva0b4f.js → message-time-backfill-39bm498k.js} +3 -2
- package/dist/migration-worker.js +13 -11
- package/dist/{project-embedding-registry-6yex0r9f.js → project-embedding-registry-tdz7985n.js} +13 -11
- package/dist/raw-ordinal-warmup-worker.js +12 -7
- package/dist/{read-session-chunk-1ndphmb8.js → read-session-chunk-vmg1zjg0.js} +15 -10
- package/dist/{read-session-raw-b2sd67v4.js → read-session-raw-mncmzbm9.js} +3 -2
- package/dist/recomp-orchestrator-qyyhnc9b.js +68 -0
- package/dist/render-c5p0k846.js +43 -0
- package/dist/{safe-notification-target-mkr9yzvr.js → safe-notification-target-wztd7bgk.js} +3 -2
- package/dist/{search-archive-sr07c6aj.js → search-archive-0ny7p3bw.js} +13 -11
- package/dist/{search-040pac3a.js → search-f6hwvcxk.js} +26 -23
- package/dist/{send-session-notification-vz86nt79.js → send-session-notification-0gwcz3fw.js} +7 -6
- package/dist/{storage-tags-6hvkk01c.js → storage-tags-zx1023km.js} +5 -4
- package/dist/store-620rjzt9.js +21 -0
- package/dist/store-reader-yh19h38c.js +14 -0
- package/dist/tools/ctx-expand/render.d.ts +5 -3
- package/dist/tools/ctx-expand/render.d.ts.map +1 -1
- package/dist/tools/ctx-expand/search-archive.d.ts.map +1 -1
- package/dist/tools/ctx-expand/tools.d.ts +2 -0
- package/dist/tools/ctx-expand/tools.d.ts.map +1 -1
- package/dist/tools/ctx-expand/v2-archive-reader.d.ts +33 -0
- package/dist/tools/ctx-expand/v2-archive-reader.d.ts.map +1 -0
- package/dist/{transform-postprocess-phase-zx1peqma.js → transform-postprocess-phase-807ff6t2.js} +36 -30
- package/dist/v2/auto-search-worker.js +11 -6
- package/dist/v2/chunk-embedding-write-worker.js +16 -14
- package/dist/v2/{compaction-marker-candidates-m4vmye3w.js → compaction-marker-candidates-t1aq6gsj.js} +3 -2
- package/dist/v2/compaction-marker-candidates-worker.js +1 -1
- package/dist/v2/{compartment-chunk-embedding-rc31e6md.js → compartment-chunk-embedding-ncsk0r9e.js} +8 -7
- package/dist/v2/{context-3c4z2wj5.js → context-znqfkap4.js} +1725 -1095
- package/dist/v2/{derive-budgets-knf763tt.js → derive-budgets-sa0v7bz0.js} +4 -3
- package/dist/v2/embedding-backfill-11j425e0.js +26 -0
- package/dist/v2/embedding-worker-process.js +2 -1
- package/dist/v2/embedding-worker.js +5 -4
- package/dist/v2/expand-attachments-h33jbgyz.js +21 -0
- package/dist/v2/fold/idle.d.ts +15 -0
- package/dist/v2/fold/idle.d.ts.map +1 -0
- package/dist/v2/fold/native-replay-v3.d.ts +68 -0
- package/dist/v2/fold/native-replay-v3.d.ts.map +1 -0
- package/dist/v2/fold/native-replay.d.ts +58 -2
- package/dist/v2/fold/native-replay.d.ts.map +1 -1
- package/dist/v2/fold/policy.d.ts +2 -1
- package/dist/v2/fold/policy.d.ts.map +1 -1
- package/dist/v2/{history-owner-ad0crnrn.js → history-owner-fpka43cn.js} +3 -2
- package/dist/v2/hooks/context.d.ts.map +1 -1
- package/dist/v2/hooks/expand-attachments.d.ts +8 -0
- package/dist/v2/hooks/expand-attachments.d.ts.map +1 -0
- package/dist/v2/hooks/overflow-recovery.d.ts +45 -0
- package/dist/v2/hooks/overflow-recovery.d.ts.map +1 -0
- package/dist/v2/hooks/store.d.ts +7 -2
- package/dist/v2/hooks/store.d.ts.map +1 -1
- package/dist/v2/{logger-p34mjtja.js → logger-4cj6d03m.js} +2 -1
- package/dist/v2/{message-fts-rowid-map-78awh03v.js → message-fts-rowid-map-rmk571mb.js} +5 -4
- package/dist/v2/{message-index-bounded-jvgz7vk9.js → message-index-bounded-620bppw7.js} +12 -11
- package/dist/v2/{message-time-backfill-zvthw6xb.js → message-time-backfill-0c4h7sg6.js} +3 -2
- package/dist/v2/migration-worker.js +13 -11
- package/dist/v2/ordinal-range.fixture.d.ts +7 -0
- package/dist/v2/ordinal-range.fixture.d.ts.map +1 -0
- package/dist/v2/{project-embedding-registry-1x5qe2fy.js → project-embedding-registry-bm5fe1a8.js} +13 -11
- package/dist/v2/raw-ordinal-warmup-worker.js +12 -7
- package/dist/v2/{read-session-chunk-djzgm4jg.js → read-session-chunk-qfwv1k71.js} +15 -10
- package/dist/v2/{read-session-raw-5x088amc.js → read-session-raw-q294t8xs.js} +3 -2
- package/dist/v2/recomp-orchestrator-fcnjref7.js +67 -0
- package/dist/v2/render-98a1qv0b.js +42 -0
- package/dist/v2/{safe-notification-target-khnzg57c.js → safe-notification-target-gphhast7.js} +3 -2
- package/dist/v2/{search-archive-n3dhns4r.js → search-archive-r0y1bafr.js} +13 -11
- package/dist/v2/{search-q3wkpe8t.js → search-z1zqzsmh.js} +25 -22
- package/dist/v2/{send-session-notification-x5nzy34v.js → send-session-notification-fst6hkg7.js} +7 -6
- package/dist/v2/{server-rb8m4vry.js → server-1xesqm5h.js} +146 -134
- package/dist/v2/server-2amn2s73.js +123 -0
- package/dist/v2/{server-6g98c227.js → server-3schkz95.js} +4 -4
- package/dist/v2/server-468mya5v.js +209 -0
- package/dist/v2/server-55v5hpth.js +270 -0
- package/dist/v2/server-5jp38p98.js +532 -0
- package/dist/v2/{server-qjvk4a9t.js → server-69m30b21.js} +1 -1
- package/dist/v2/{server-d01pe8q5.js → server-7ccxt4nq.js} +14 -216
- package/dist/v2/{server-3mz2qh5a.js → server-969cdpmg.js} +1 -1
- package/dist/v2/{server-835q39kd.js → server-9k0mjef7.js} +2 -2
- package/dist/v2/{server-qc915kw2.js → server-bez34e60.js} +4 -4
- package/dist/v2/{server-nxas8v1d.js → server-bpvsvtph.js} +3 -3
- package/dist/v2/{server-ab8017gw.js → server-bxpz2dcn.js} +29 -138
- package/dist/v2/{server-bsgd4dk1.js → server-dcws5831.js} +2 -2
- package/dist/v2/server-ef1mskas.js +777 -0
- package/dist/v2/{server-1bw1wcbp.js → server-f0j864ma.js} +1 -1
- package/dist/v2/{server-aqbm9c8d.js → server-fqj6ddpr.js} +632 -5540
- package/dist/v2/{server-rr4cbkr0.js → server-hnknwaz8.js} +37 -7
- package/dist/v2/{server-h1byrhwx.js → server-hsf0qsn5.js} +19 -8
- package/dist/v2/{server-6495nmn9.js → server-jb6tjyeb.js} +5 -222
- package/dist/v2/{server-2aasmpsp.js → server-kkxzwa6w.js} +4 -4
- package/dist/v2/{server-a7x00tw8.js → server-mfn1yf9d.js} +1 -1
- package/dist/v2/{server-tkdabx8q.js → server-q0z2q2dx.js} +5 -530
- package/dist/v2/{server-n14edf07.js → server-qa74bj91.js} +77 -17
- package/dist/v2/server-qf2kzsh2.js +4513 -0
- package/dist/v2/{server-gyy4k6mf.js → server-qmmkhz2z.js} +1 -1
- package/dist/v2/{server-29qp8nz4.js → server-qxzbmtqt.js} +1 -1
- package/dist/v2/{server-hwag0khr.js → server-r3chnxs5.js} +4 -4
- package/dist/v2/{server-vr4szghm.js → server-rktnzs89.js} +2 -2
- package/dist/v2/{server-6vd2n183.js → server-s9xgyyj9.js} +1 -1
- package/dist/v2/{server-53eh1r8r.js → server-sd8hvzte.js} +2 -2
- package/dist/v2/{server-k3t06fxr.js → server-sefxj8k1.js} +1 -1
- package/dist/v2/{server-v77xa5wj.js → server-tpt7bwq8.js} +1 -1
- package/dist/v2/{server-awr8qa4c.js → server-ws5exe6q.js} +2 -2
- package/dist/v2/server-x4m6xcn4.js +194 -0
- package/dist/v2/{server-806rzhs6.js → server-xbtw0p9t.js} +1 -1
- package/dist/v2/{server-cqjvxyrp.js → server-xy7w7hrd.js} +2 -2
- package/dist/v2/server-ypf1ap0v.js +529 -0
- package/dist/v2/server-z4p0ry94.js +222 -0
- package/dist/v2/server-z9zygwse.js +89 -0
- package/dist/v2/{server-ab1g0wn9.js → server-zzgtgqmd.js} +2 -2
- package/dist/v2/server.js +6 -5
- package/dist/v2/{storage-tags-18nbaanf.js → storage-tags-19s0ebf0.js} +5 -4
- package/dist/v2/store-reader-cgx47zkp.js +14 -0
- package/dist/v2/store-reader.d.ts +9 -2
- package/dist/v2/store-reader.d.ts.map +1 -1
- package/dist/v2/store-vdm8v3jd.js +21 -0
- package/dist/v2/v2-archive-reader-t2c0eypn.js +11 -0
- package/dist/v2/{wrapup-orchestrator-ga5vfmwr.js → wrapup-orchestrator-aqpqsveg.js} +46 -39
- package/dist/v2-archive-reader-tm2eayp2.js +11 -0
- package/dist/wrapup-orchestrator-k5yp19a6.js +55 -0
- package/package.json +1 -1
- package/src/shared/sqlite-transaction-mode-guard.test.ts +4 -0
- package/dist/embedding-backfill-0jgtqxen.js +0 -25
- package/dist/recomp-orchestrator-skqzzvby.js +0 -62
- package/dist/v2/embedding-backfill-f43hd8y6.js +0 -24
- package/dist/v2/recomp-orchestrator-qfqdvbta.js +0 -61
- package/dist/wrapup-orchestrator-dy8r3gp8.js +0 -49
|
@@ -6,34 +6,6 @@ import {
|
|
|
6
6
|
dreamerRunConfig,
|
|
7
7
|
pluginConfigReader,
|
|
8
8
|
withLiveDreamerOutputCap,
|
|
9
|
-
advanceSessionActivity,
|
|
10
|
-
backfillSessionActivity,
|
|
11
|
-
acquireCompartmentLease,
|
|
12
|
-
releaseCompartmentLeaseBestEffort,
|
|
13
|
-
isCompartmentLeaseHeld,
|
|
14
|
-
queueM0Mutation,
|
|
15
|
-
getUncoveredCompartmentEndsThrough,
|
|
16
|
-
providerResponseFailed,
|
|
17
|
-
isSuccessfulProviderCompletion,
|
|
18
|
-
gaDatabasePath,
|
|
19
|
-
RAW_MESSAGE_TYPES,
|
|
20
|
-
V2StoreReaderPool,
|
|
21
|
-
V2StoreReader,
|
|
22
|
-
getOrCreateSessionMeta,
|
|
23
|
-
updateSessionMeta,
|
|
24
|
-
markSessionCleanupPending,
|
|
25
|
-
clearSession,
|
|
26
|
-
requestPendingMaterialization,
|
|
27
|
-
clearPendingMaterialization,
|
|
28
|
-
bindSystemPromptResponse,
|
|
29
|
-
retirePendingSystemPromptDelivery,
|
|
30
|
-
lkgProviderInputTotal,
|
|
31
|
-
beginV2LkgRequest,
|
|
32
|
-
currentLkgRequestIdentity,
|
|
33
|
-
noteLkgProviderResponse,
|
|
34
|
-
clearLkgMeasuredRequest,
|
|
35
|
-
getSlot,
|
|
36
|
-
copySessionStateForClone,
|
|
37
9
|
HiddenCompletionRefusal,
|
|
38
10
|
HIDDEN_HISTORIAN_AGENT,
|
|
39
11
|
HIDDEN_DREAMER_AGENT,
|
|
@@ -65,7 +37,7 @@ import {
|
|
|
65
37
|
rebaseSessionCoordinatesAsync,
|
|
66
38
|
resolveOpenCodeProtectedTailBoundary,
|
|
67
39
|
getActiveCompartmentRun
|
|
68
|
-
} from "./index-
|
|
40
|
+
} from "./index-4bgk5ztz.js";
|
|
69
41
|
import"./index-sd3egckz.js";
|
|
70
42
|
import {
|
|
71
43
|
getHarness2
|
|
@@ -74,10 +46,11 @@ import {
|
|
|
74
46
|
getDataDir,
|
|
75
47
|
getMagicContextStorageDir
|
|
76
48
|
} from "./index-g2q4htwp.js";
|
|
49
|
+
import"./index-z4p0ry94.js";
|
|
77
50
|
import {
|
|
78
51
|
log2,
|
|
79
52
|
sessionLog2
|
|
80
|
-
} from "./index-
|
|
53
|
+
} from "./index-jrfre9ah.js";
|
|
81
54
|
import {
|
|
82
55
|
isSaneLimit,
|
|
83
56
|
setOutputReserveConfig,
|
|
@@ -87,7 +60,7 @@ import {
|
|
|
87
60
|
deriveHistorianChunkTokens2,
|
|
88
61
|
resolveKnownHistorianContextLimit2,
|
|
89
62
|
resolveHistorianContextLimit2
|
|
90
|
-
} from "./index-
|
|
63
|
+
} from "./index-dnqqqc5f.js";
|
|
91
64
|
import"./index-nxrsns5x.js";
|
|
92
65
|
import {
|
|
93
66
|
CANONICAL_DREAM_TASKS,
|
|
@@ -112,7 +85,9 @@ import {
|
|
|
112
85
|
ensureProjectRegisteredFromOpenCodeDirectory,
|
|
113
86
|
resolveContextLimit,
|
|
114
87
|
resolveModelKey,
|
|
88
|
+
parseCacheTtl,
|
|
115
89
|
createScheduler,
|
|
90
|
+
computeHardCacheExpired,
|
|
116
91
|
describeStorageUnavailability,
|
|
117
92
|
getSessionErrorInfo,
|
|
118
93
|
summarizeManualDream,
|
|
@@ -156,7 +131,7 @@ import {
|
|
|
156
131
|
applyJsonSchemaParameterDescriptions,
|
|
157
132
|
MagicContextRpcServer,
|
|
158
133
|
subagentTemperature
|
|
159
|
-
} from "./index-
|
|
134
|
+
} from "./index-b6xz3qbe.js";
|
|
160
135
|
import {
|
|
161
136
|
resolveHistorianModel2
|
|
162
137
|
} from "./index-5kym00ag.js";
|
|
@@ -164,19 +139,13 @@ import {
|
|
|
164
139
|
formatFailClosedBlockingMessage,
|
|
165
140
|
formatFailClosedBlockingSummary,
|
|
166
141
|
createFailClosedBlockingError,
|
|
167
|
-
isFailClosedBlockingError
|
|
168
|
-
|
|
169
|
-
BOOT_SQLITE_BUSY_TIMEOUT_MS,
|
|
170
|
-
openCurrentDatabase,
|
|
171
|
-
openDatabaseAsync,
|
|
172
|
-
isDatabasePersisted,
|
|
173
|
-
getDatabasePersistenceError
|
|
174
|
-
} from "./index-hbt0sbv2.js";
|
|
142
|
+
isFailClosedBlockingError
|
|
143
|
+
} from "./index-wh9fxds5.js";
|
|
175
144
|
import {
|
|
176
145
|
setHomeProjectPermission,
|
|
177
146
|
resolveProjectIdentityForSession,
|
|
178
147
|
scheduleAfterBootQuiet
|
|
179
|
-
} from "./index-
|
|
148
|
+
} from "./index-txs8tce6.js";
|
|
180
149
|
import"./index-v0p37hm2.js";
|
|
181
150
|
import {
|
|
182
151
|
inRootAsyncContext2,
|
|
@@ -186,7 +155,7 @@ import {
|
|
|
186
155
|
withAsyncPrivilegedWriter2
|
|
187
156
|
} from "./index-gzy5w8ya.js";
|
|
188
157
|
import"./index-cpjk5jd2.js";
|
|
189
|
-
import"./index-
|
|
158
|
+
import"./index-qncw9hey.js";
|
|
190
159
|
import"./index-1zx87sdm.js";
|
|
191
160
|
import {
|
|
192
161
|
stripPersistedAssistantText,
|
|
@@ -195,22 +164,19 @@ import {
|
|
|
195
164
|
isDroppedToolOutput,
|
|
196
165
|
evaluateChannel2,
|
|
197
166
|
buildChannel2Reminder
|
|
198
|
-
} from "./index-
|
|
167
|
+
} from "./index-ksv0a31x.js";
|
|
199
168
|
import {
|
|
200
169
|
hasMeaningfulUserText2,
|
|
201
170
|
preloadTokenizer,
|
|
202
171
|
estimateTokens
|
|
203
|
-
} from "./index-
|
|
172
|
+
} from "./index-4xyjr62e.js";
|
|
204
173
|
import {
|
|
205
174
|
getTableColumnNames
|
|
206
|
-
} from "./index-
|
|
175
|
+
} from "./index-9wnbnx8f.js";
|
|
207
176
|
import"./index-58e3y90n.js";
|
|
208
|
-
import"./index-
|
|
177
|
+
import"./index-pztqab6k.js";
|
|
209
178
|
import {
|
|
210
179
|
needsBlockedRead,
|
|
211
|
-
markHostUnservedRow,
|
|
212
|
-
markCoveredInstructionRow,
|
|
213
|
-
isCoveredInstructionRow,
|
|
214
180
|
DreamTokenBudgetExceeded,
|
|
215
181
|
createDreamTokenBudget,
|
|
216
182
|
recordToolParameters,
|
|
@@ -241,34 +207,71 @@ import {
|
|
|
241
207
|
cleanUserText2,
|
|
242
208
|
readRawSessionMessageIdOrdinalsForRange2,
|
|
243
209
|
readRawSessionMessageOrdinalById2
|
|
244
|
-
} from "./index-
|
|
210
|
+
} from "./index-brg2w6qc.js";
|
|
245
211
|
import {
|
|
246
212
|
BoundedSessionMap,
|
|
247
213
|
recordToolDefinitionSet,
|
|
248
214
|
getCurrentToolSetHash
|
|
249
|
-
} from "./index-
|
|
250
|
-
import"./index-
|
|
251
|
-
import"./index-
|
|
215
|
+
} from "./index-jkanybgq.js";
|
|
216
|
+
import"./index-pq0dpwrc.js";
|
|
217
|
+
import"./index-faxb7mck.js";
|
|
252
218
|
import {
|
|
253
219
|
scheduleClearAndReindex
|
|
254
|
-
} from "./index-
|
|
220
|
+
} from "./index-87ctnzz9.js";
|
|
255
221
|
import {
|
|
256
222
|
invalidateAutoEmbedSession,
|
|
257
|
-
clearEmbedSessionState
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
import"./index-wfybj1dw.js";
|
|
223
|
+
clearEmbedSessionState
|
|
224
|
+
} from "./index-2amn2s73.js";
|
|
225
|
+
import"./index-g4t7850m.js";
|
|
261
226
|
import {
|
|
262
227
|
deleteChunkEmbedBackoffForSession2
|
|
263
|
-
} from "./index-
|
|
264
|
-
import"./index-
|
|
228
|
+
} from "./index-zhqwda72.js";
|
|
229
|
+
import"./index-2p37txes.js";
|
|
230
|
+
import {
|
|
231
|
+
advanceSessionActivity,
|
|
232
|
+
backfillSessionActivity,
|
|
233
|
+
acquireCompartmentLease,
|
|
234
|
+
releaseCompartmentLeaseBestEffort,
|
|
235
|
+
isCompartmentLeaseHeld,
|
|
236
|
+
queueM0Mutation,
|
|
237
|
+
getUncoveredCompartmentEndsThrough,
|
|
238
|
+
providerResponseFailed,
|
|
239
|
+
isSuccessfulProviderCompletion,
|
|
240
|
+
readSessionMeta,
|
|
241
|
+
getOrCreateSessionMeta,
|
|
242
|
+
updateSessionMeta,
|
|
243
|
+
markSessionCleanupPending,
|
|
244
|
+
clearSession,
|
|
245
|
+
requestPendingMaterialization,
|
|
246
|
+
clearPendingMaterialization,
|
|
247
|
+
bindSystemPromptResponse,
|
|
248
|
+
retirePendingSystemPromptDelivery,
|
|
249
|
+
lkgProviderInputTotal,
|
|
250
|
+
beginV2LkgRequest,
|
|
251
|
+
currentLkgRequestIdentity,
|
|
252
|
+
noteLkgProviderResponse,
|
|
253
|
+
clearLkgMeasuredRequest,
|
|
254
|
+
getSlot,
|
|
255
|
+
copySessionStateForClone
|
|
256
|
+
} from "./index-f297z1n8.js";
|
|
257
|
+
import {
|
|
258
|
+
startBootDeadline,
|
|
259
|
+
BOOT_SQLITE_BUSY_TIMEOUT_MS,
|
|
260
|
+
openCurrentDatabase,
|
|
261
|
+
openDatabaseAsync,
|
|
262
|
+
isDatabasePersisted,
|
|
263
|
+
getDatabasePersistenceError
|
|
264
|
+
} from "./index-gyaa159j.js";
|
|
265
265
|
import"./index-fr0wbhdn.js";
|
|
266
|
-
import"./index-
|
|
267
|
-
import"./index-fb3zxn06.js";
|
|
266
|
+
import"./index-nj360hcs.js";
|
|
268
267
|
import {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
268
|
+
gaDatabasePath2,
|
|
269
|
+
RAW_MESSAGE_TYPES2,
|
|
270
|
+
V2StoreReaderPool2,
|
|
271
|
+
V2StoreReader2
|
|
272
|
+
} from "./index-66a50f3e.js";
|
|
273
|
+
import"./index-fb3zxn06.js";
|
|
274
|
+
import"./index-2qbtqg1w.js";
|
|
272
275
|
import {
|
|
273
276
|
createTagger,
|
|
274
277
|
cavemanWordRulesForLanguage,
|
|
@@ -277,41 +280,71 @@ import {
|
|
|
277
280
|
EmergencyFailClosedError,
|
|
278
281
|
DegradedPassRefusalError,
|
|
279
282
|
isSyntheticHeadMessage2
|
|
280
|
-
} from "./index-
|
|
281
|
-
import"./index-
|
|
283
|
+
} from "./index-x2mrq5xv.js";
|
|
284
|
+
import"./index-f9b3vtt1.js";
|
|
282
285
|
import"./index-qt1qqasc.js";
|
|
283
|
-
import
|
|
286
|
+
import {
|
|
287
|
+
retainProjectEmbedding2
|
|
288
|
+
} from "./index-jn0ddrhp.js";
|
|
289
|
+
import"./index-jz5bk7xd.js";
|
|
284
290
|
import"./index-4dhv7mqz.js";
|
|
285
|
-
import"./index-
|
|
286
|
-
import"./index-
|
|
291
|
+
import"./index-1rhgxqs8.js";
|
|
292
|
+
import"./index-pswsyf1w.js";
|
|
287
293
|
import"./index-jjvbk92s.js";
|
|
294
|
+
import {
|
|
295
|
+
renderUserFacingFailure,
|
|
296
|
+
userFacingFailureCode
|
|
297
|
+
} from "./index-0c7p8mq5.js";
|
|
288
298
|
import {
|
|
289
299
|
pushNotification2,
|
|
290
300
|
isTuiConnected2
|
|
291
301
|
} from "./index-x8a7jmkh.js";
|
|
292
|
-
import"./index-
|
|
293
|
-
import"./index-
|
|
294
|
-
import"./index-
|
|
295
|
-
import"./index-
|
|
302
|
+
import"./index-fw42ms3m.js";
|
|
303
|
+
import"./index-2v6nvy3k.js";
|
|
304
|
+
import"./index-3j9t1v4n.js";
|
|
305
|
+
import"./index-3d3872c6.js";
|
|
296
306
|
import"./index-gp3kcpc4.js";
|
|
297
307
|
import {
|
|
298
308
|
detectConflicts
|
|
299
|
-
} from "./index-
|
|
309
|
+
} from "./index-hacf2tyx.js";
|
|
310
|
+
import {
|
|
311
|
+
STORAGE_NOTICE_PREFIX,
|
|
312
|
+
formatStorageRefusalNotice,
|
|
313
|
+
formatStorageRecoveryNotice,
|
|
314
|
+
hasStorageNoticeShape,
|
|
315
|
+
dropStorageNotices,
|
|
316
|
+
restoreRow,
|
|
317
|
+
isToolError,
|
|
318
|
+
toolErrorText,
|
|
319
|
+
toolStateContent,
|
|
320
|
+
servedBoundaryRow2,
|
|
321
|
+
resolveV2BoundaryUserMessage2,
|
|
322
|
+
readAllV2RawMessagesForConversion2,
|
|
323
|
+
readV2RawMessagePagesForConversion2,
|
|
324
|
+
createV2RawMessageReader2,
|
|
325
|
+
createV2RawMessageProvider2
|
|
326
|
+
} from "./index-vzhhr1ht.js";
|
|
300
327
|
import"./index-fmsr7v69.js";
|
|
328
|
+
import"./index-qx8j6kds.js";
|
|
301
329
|
import"./index-kaqs6h31.js";
|
|
302
|
-
import"./index-
|
|
330
|
+
import"./index-dy7w6wm4.js";
|
|
331
|
+
import"./index-ezv6dz3y.js";
|
|
303
332
|
import {
|
|
304
333
|
isDreamerRunnable,
|
|
305
334
|
isSmartNoteSurfaceAvailable,
|
|
306
335
|
isCompactionEnabled
|
|
307
336
|
} from "./index-ksdyrrav.js";
|
|
337
|
+
import {
|
|
338
|
+
markCoveredInstructionRow,
|
|
339
|
+
isCoveredInstructionRow
|
|
340
|
+
} from "./index-z9zygwse.js";
|
|
308
341
|
import {
|
|
309
342
|
sameProjectDirectory
|
|
310
343
|
} from "./index-knvkbfvh.js";
|
|
311
344
|
import {
|
|
312
345
|
getErrorMessage
|
|
313
346
|
} from "./index-y8v6yerm.js";
|
|
314
|
-
import"./index-
|
|
347
|
+
import"./index-fxbk7gk3.js";
|
|
315
348
|
|
|
316
349
|
// src/v2/hooks/context.ts
|
|
317
350
|
import { setTimeout as delay } from "node:timers/promises";
|
|
@@ -748,6 +781,60 @@ function hostMediaFromEncoded(value) {
|
|
|
748
781
|
return `${first}; ${second}`;
|
|
749
782
|
}
|
|
750
783
|
|
|
784
|
+
// src/v2/fold/idle.ts
|
|
785
|
+
class HostFoldIdle {
|
|
786
|
+
fold;
|
|
787
|
+
now;
|
|
788
|
+
timers;
|
|
789
|
+
windows = new Map;
|
|
790
|
+
constructor(fold, now = Date.now, timers = { setTimeout, clearTimeout }) {
|
|
791
|
+
this.fold = fold;
|
|
792
|
+
this.now = now;
|
|
793
|
+
this.timers = timers;
|
|
794
|
+
}
|
|
795
|
+
active(sessionID) {
|
|
796
|
+
const window = this.windows.get(sessionID);
|
|
797
|
+
if (window?.timer)
|
|
798
|
+
this.timers.clearTimeout(window.timer);
|
|
799
|
+
this.windows.delete(sessionID);
|
|
800
|
+
}
|
|
801
|
+
idle(sessionID, cacheTtl, lastResponseTime) {
|
|
802
|
+
this.active(sessionID);
|
|
803
|
+
let ttl;
|
|
804
|
+
try {
|
|
805
|
+
ttl = parseCacheTtl(cacheTtl);
|
|
806
|
+
} catch {
|
|
807
|
+
ttl = 5 * 60 * 1000;
|
|
808
|
+
}
|
|
809
|
+
if (!Number.isFinite(ttl) || lastResponseTime <= 0)
|
|
810
|
+
return;
|
|
811
|
+
const window = { cacheTtl, lastResponseTime };
|
|
812
|
+
this.windows.set(sessionID, window);
|
|
813
|
+
const eligible = () => this.windows.get(sessionID) === window && computeHardCacheExpired(window.cacheTtl, window.lastResponseTime, this.now());
|
|
814
|
+
const wake = () => {
|
|
815
|
+
if (this.windows.get(sessionID) !== window)
|
|
816
|
+
return;
|
|
817
|
+
if (eligible()) {
|
|
818
|
+
window.timer = undefined;
|
|
819
|
+
const release = () => {
|
|
820
|
+
if (this.windows.get(sessionID) === window)
|
|
821
|
+
this.windows.delete(sessionID);
|
|
822
|
+
};
|
|
823
|
+
this.fold(sessionID, eligible).then(release, release);
|
|
824
|
+
return;
|
|
825
|
+
}
|
|
826
|
+
const remaining = Math.max(1, lastResponseTime + ttl - this.now() + 1);
|
|
827
|
+
window.timer = this.timers.setTimeout(wake, Math.min(remaining, 2147483647));
|
|
828
|
+
window.timer.unref?.();
|
|
829
|
+
};
|
|
830
|
+
wake();
|
|
831
|
+
}
|
|
832
|
+
dispose() {
|
|
833
|
+
for (const sessionID of this.windows.keys())
|
|
834
|
+
this.active(sessionID);
|
|
835
|
+
}
|
|
836
|
+
}
|
|
837
|
+
|
|
751
838
|
// src/v2/fold/memory-cache.ts
|
|
752
839
|
import { randomUUID } from "node:crypto";
|
|
753
840
|
|
|
@@ -1077,39 +1164,6 @@ function nativeFoldCache(db, budget) {
|
|
|
1077
1164
|
return new NativeFoldCache(typeof db === "function" ? db : () => db, budget);
|
|
1078
1165
|
}
|
|
1079
1166
|
|
|
1080
|
-
// src/v2/tool-result.ts
|
|
1081
|
-
function isToolError(part) {
|
|
1082
|
-
const result = part.result;
|
|
1083
|
-
return part.resultType === "error" || result?.type === "error" || result !== null && typeof result === "object" && "error" in result;
|
|
1084
|
-
}
|
|
1085
|
-
function toolErrorText(result) {
|
|
1086
|
-
const value = result.value === undefined ? result : result.value;
|
|
1087
|
-
return typeof value === "string" ? value : JSON.stringify(value);
|
|
1088
|
-
}
|
|
1089
|
-
function toolStateContent(state) {
|
|
1090
|
-
if (typeof state.output === "string")
|
|
1091
|
-
return state.output;
|
|
1092
|
-
if (state.status === "error")
|
|
1093
|
-
return toolErrorText({ error: state.error, content: state.content ?? [] });
|
|
1094
|
-
if (typeof state.content === "string")
|
|
1095
|
-
return state.content;
|
|
1096
|
-
if (!Array.isArray(state.content))
|
|
1097
|
-
return "";
|
|
1098
|
-
return state.content.map((part) => {
|
|
1099
|
-
if (typeof part === "string")
|
|
1100
|
-
return part;
|
|
1101
|
-
if (!part || typeof part !== "object")
|
|
1102
|
-
return "";
|
|
1103
|
-
const value = part;
|
|
1104
|
-
if (typeof value.text === "string")
|
|
1105
|
-
return value.text;
|
|
1106
|
-
if (typeof value.value === "string")
|
|
1107
|
-
return value.value;
|
|
1108
|
-
return "";
|
|
1109
|
-
}).filter(Boolean).join(`
|
|
1110
|
-
`);
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
1167
|
// src/v2/hooks/copied-tag-notation.ts
|
|
1114
1168
|
function stripCopiedTagNotation(text, acceptsEmpty = true) {
|
|
1115
1169
|
return text.includes("§") ? stripPersistedAssistantText(text, acceptsEmpty) : text;
|
|
@@ -1608,239 +1662,177 @@ function reviveNative(messages) {
|
|
|
1608
1662
|
return result;
|
|
1609
1663
|
}
|
|
1610
1664
|
|
|
1611
|
-
// src/v2/fold/
|
|
1612
|
-
|
|
1665
|
+
// src/v2/fold/native-replay-v3.ts
|
|
1666
|
+
var IMPORTED_MC_SUMMARY = "[Compacted by magic-context — session history is managed by the plugin]";
|
|
1667
|
+
var MAX_CONTROL_BYTES = 128 * 1024;
|
|
1668
|
+
var efforts = new Set(["none", "minimal", "low", "medium", "high", "xhigh", "max"]);
|
|
1613
1669
|
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1670
|
+
class ControlMetadataUnavailable extends Error {
|
|
1671
|
+
}
|
|
1672
|
+
var object = (value) => !!value && typeof value === "object" && !Array.isArray(value);
|
|
1673
|
+
var keys = (value, allowed) => Object.keys(value).every((key) => allowed.includes(key));
|
|
1674
|
+
var identity = (value) => typeof value === "string" && value.length > 0 && Buffer.byteLength(value) <= 1024;
|
|
1675
|
+
var digest = (value) => typeof value === "string" && /^[a-f0-9]{64}$/.test(value);
|
|
1676
|
+
function validReplayState(value) {
|
|
1677
|
+
if (!object(value) || !keys(value, ["floor", "controls", "blocked", "upgrade", "withoutRecentContext"]))
|
|
1678
|
+
return false;
|
|
1679
|
+
const floor = value.floor;
|
|
1680
|
+
const upgrade = value.upgrade;
|
|
1681
|
+
return object(floor) && keys(floor, ["kind", "id", "seq", "after", "digest"]) && ["start", "summary", "checkpoint", "host-checkpoint"].includes(floor.kind) && identity(floor.id) && typeof floor.seq === "number" && typeof floor.after === "number" && Number.isSafeInteger(floor.seq) && Number.isSafeInteger(floor.after) && floor.after === (floor.kind === "start" || floor.kind === "host-checkpoint" ? floor.seq - 1 : floor.seq) && digest(floor.digest) && validControls(value.controls) && (value.blocked === undefined || typeof value.blocked === "boolean") && (value.withoutRecentContext === undefined || typeof value.withoutRecentContext === "boolean") && (upgrade === undefined || object(upgrade) && keys(upgrade, ["admissionID", "mode"]) && identity(upgrade.admissionID) && ["bounded", "host-checkpoint", "source-repair"].includes(upgrade.mode));
|
|
1624
1682
|
}
|
|
1625
|
-
function
|
|
1626
|
-
if (
|
|
1683
|
+
function validAdmissionV3(value) {
|
|
1684
|
+
if (!object(value) || !keys(value, ["version", "proof", "replay"]) || value.version !== 3 || !object(value.proof))
|
|
1627
1685
|
return false;
|
|
1628
|
-
|
|
1686
|
+
const proof = value.proof;
|
|
1687
|
+
return keys(proof, [
|
|
1688
|
+
"sourceDigest",
|
|
1689
|
+
"sessionID",
|
|
1690
|
+
"admissionID",
|
|
1691
|
+
"summaryDigest",
|
|
1692
|
+
"historyDigest"
|
|
1693
|
+
]) && identity(proof.sessionID) && identity(proof.admissionID) && digest(proof.sourceDigest) && digest(proof.summaryDigest) && digest(proof.historyDigest) && validReplayState(value.replay);
|
|
1694
|
+
}
|
|
1695
|
+
function encodeAdmissionV3(value) {
|
|
1696
|
+
if (!validAdmissionV3(value))
|
|
1697
|
+
throw new Error("Unsupported native fold admission metadata");
|
|
1698
|
+
return JSON.stringify(value);
|
|
1699
|
+
}
|
|
1700
|
+
function validCapturedReplayV3(value) {
|
|
1701
|
+
return object(value) && keys(value, ["version", "sessionID", "sourceDigest", "through", "replay"]) && value.version === 3 && identity(value.sessionID) && digest(value.sourceDigest) && Number.isSafeInteger(value.through) && validReplayState(value.replay);
|
|
1702
|
+
}
|
|
1703
|
+
function floorFor(row, kind) {
|
|
1704
|
+
return {
|
|
1705
|
+
kind,
|
|
1706
|
+
id: row.id,
|
|
1707
|
+
seq: row.seq,
|
|
1708
|
+
after: inclusiveFloor(kind) ? row.seq - 1 : row.seq,
|
|
1709
|
+
digest: foldDigest(JSON.stringify(row))
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
function validFloor(reader, sessionID, value) {
|
|
1713
|
+
if (!value || !["checkpoint", "summary", "start", "host-checkpoint"].includes(value.kind) || !Number.isSafeInteger(value.seq) || !Number.isSafeInteger(value.after) || value.after !== (inclusiveFloor(value.kind) ? value.seq - 1 : value.seq))
|
|
1629
1714
|
return false;
|
|
1630
|
-
const
|
|
1631
|
-
return
|
|
1715
|
+
const row = reader.range(sessionID, value.seq - 1, value.seq).find((candidate) => candidate.id === value.id && candidate.seq === value.seq);
|
|
1716
|
+
return !!row && row.session_id === sessionID && foldDigest(JSON.stringify(row)) === value.digest;
|
|
1632
1717
|
}
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
for (const message of messages) {
|
|
1636
|
-
if (!hasStorageNoticeShape(message))
|
|
1637
|
-
continue;
|
|
1638
|
-
if (await isAdmittedSynthetic(message.id))
|
|
1639
|
-
drop.add(message);
|
|
1640
|
-
}
|
|
1641
|
-
if (drop.size === 0)
|
|
1642
|
-
return 0;
|
|
1643
|
-
const kept = messages.filter((message) => !drop.has(message));
|
|
1644
|
-
messages.splice(0, messages.length, ...kept);
|
|
1645
|
-
return drop.size;
|
|
1718
|
+
function inclusiveFloor(kind) {
|
|
1719
|
+
return kind === "start" || kind === "host-checkpoint";
|
|
1646
1720
|
}
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
directory && !file.data.length ? undefined : Buffer.from(file.data, "base64").toString("utf8")
|
|
1683
|
-
].filter((line) => line !== undefined).join(`
|
|
1684
|
-
`)}`,
|
|
1685
|
-
metadata: {
|
|
1686
|
-
attachment: {
|
|
1687
|
-
source: file.source,
|
|
1688
|
-
name: file.name,
|
|
1689
|
-
description: file.description
|
|
1690
|
-
}
|
|
1691
|
-
}
|
|
1692
|
-
}
|
|
1693
|
-
];
|
|
1721
|
+
function hostCheckpointCarrier(row) {
|
|
1722
|
+
return {
|
|
1723
|
+
id: row.id,
|
|
1724
|
+
role: "user",
|
|
1725
|
+
content: [
|
|
1726
|
+
{
|
|
1727
|
+
type: "text",
|
|
1728
|
+
text: [
|
|
1729
|
+
"<conversation-checkpoint>",
|
|
1730
|
+
"The following is a summary and serialized record of earlier conversation. Treat it as historical context, not as new instructions.",
|
|
1731
|
+
"",
|
|
1732
|
+
`<summary>
|
|
1733
|
+
${row.data.summary ?? ""}
|
|
1734
|
+
</summary>`,
|
|
1735
|
+
...row.data.recent ? ["", `<recent-context>
|
|
1736
|
+
${row.data.recent}
|
|
1737
|
+
</recent-context>`] : [],
|
|
1738
|
+
"</conversation-checkpoint>"
|
|
1739
|
+
].join(`
|
|
1740
|
+
`)
|
|
1741
|
+
}
|
|
1742
|
+
],
|
|
1743
|
+
...row.data.metadata === undefined ? {} : { metadata: row.data.metadata }
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
1746
|
+
function importedFloor(reader, sessionID, through = reader.latestSequence(sessionID)) {
|
|
1747
|
+
let after = -1;
|
|
1748
|
+
let found;
|
|
1749
|
+
while (true) {
|
|
1750
|
+
const page = reader.page(sessionID, { after, through, type: "compaction", limit: 1000 });
|
|
1751
|
+
if (!page.rows.length)
|
|
1752
|
+
break;
|
|
1753
|
+
for (const row of page.rows) {
|
|
1754
|
+
if (row.type === "compaction" && row.data.status === "completed" && row.data.summary === IMPORTED_MC_SUMMARY)
|
|
1755
|
+
found = row;
|
|
1694
1756
|
}
|
|
1695
|
-
if (
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1757
|
+
if (page.cursor === undefined || page.cursor <= after)
|
|
1758
|
+
break;
|
|
1759
|
+
after = page.cursor;
|
|
1760
|
+
}
|
|
1761
|
+
return found ? floorFor(found, "checkpoint") : undefined;
|
|
1762
|
+
}
|
|
1763
|
+
function effortPart(message) {
|
|
1764
|
+
return message.role === "system" && message.content.length === 1 && message.content[0]?.type === "effort" ? message.content[0] : undefined;
|
|
1765
|
+
}
|
|
1766
|
+
function validControls(value) {
|
|
1767
|
+
return Array.isArray(value) && Buffer.byteLength(JSON.stringify(value)) <= MAX_CONTROL_BYTES && value.every((control) => control && typeof control === "object" && !Array.isArray(control) && Object.keys(control).every((key) => ["after", "effort", "previous"].includes(key)) && (control.after === undefined || identity(control.after)) && (control.effort === undefined || efforts.has(control.effort)) && (control.previous === undefined || efforts.has(control.previous)));
|
|
1768
|
+
}
|
|
1769
|
+
function captureControls(draft, coordinate, visibleIDs) {
|
|
1770
|
+
let after;
|
|
1771
|
+
const controls = [];
|
|
1772
|
+
for (const message of draft.messages) {
|
|
1773
|
+
const part = effortPart(message);
|
|
1774
|
+
if (part) {
|
|
1775
|
+
const control = {
|
|
1776
|
+
after,
|
|
1777
|
+
effort: part.effort,
|
|
1778
|
+
previous: part.previous
|
|
1779
|
+
};
|
|
1780
|
+
if (!validControls([control]))
|
|
1781
|
+
throw new ControlMetadataUnavailable("unsupported host effort control");
|
|
1782
|
+
controls.push(control);
|
|
1783
|
+
} else {
|
|
1784
|
+
const id = coordinate(message);
|
|
1785
|
+
if (id && visibleIDs.has(id))
|
|
1786
|
+
after = id;
|
|
1717
1787
|
}
|
|
1718
|
-
|
|
1719
|
-
|
|
1788
|
+
}
|
|
1789
|
+
if (!validControls(controls))
|
|
1790
|
+
throw new ControlMetadataUnavailable("host effort controls exceed replay metadata budget");
|
|
1791
|
+
return controls;
|
|
1720
1792
|
}
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
...metadata === undefined ? {} : { metadata }
|
|
1793
|
+
var controlCoordinates = new WeakMap;
|
|
1794
|
+
function controlKey(control) {
|
|
1795
|
+
return JSON.stringify({
|
|
1796
|
+
after: control.after,
|
|
1797
|
+
effort: control.effort,
|
|
1798
|
+
previous: control.previous
|
|
1728
1799
|
});
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
})
|
|
1741
|
-
] : [];
|
|
1742
|
-
}
|
|
1743
|
-
if (row.type === "system")
|
|
1744
|
-
return [{ role: "system", content: [{ type: "text", text: data.text ?? "" }] }];
|
|
1745
|
-
if (row.type === "synthetic" && isStorageNoticeText(data.text))
|
|
1746
|
-
return [];
|
|
1747
|
-
if (["synthetic", "skill"].includes(row.type))
|
|
1748
|
-
return [make("user", [{ type: "text", text: data.text ?? "" }])];
|
|
1749
|
-
if (row.type === "location-switched")
|
|
1750
|
-
return [
|
|
1751
|
-
make("user", [
|
|
1800
|
+
}
|
|
1801
|
+
function rememberedControlKey(message) {
|
|
1802
|
+
return controlCoordinates.get(message);
|
|
1803
|
+
}
|
|
1804
|
+
function insertControls(messages, controls, coordinate) {
|
|
1805
|
+
const remaining = new Set(controls);
|
|
1806
|
+
const emit = (control) => {
|
|
1807
|
+
remaining.delete(control);
|
|
1808
|
+
const message = {
|
|
1809
|
+
role: "system",
|
|
1810
|
+
content: [
|
|
1752
1811
|
{
|
|
1753
|
-
type: "
|
|
1754
|
-
|
|
1812
|
+
type: "effort",
|
|
1813
|
+
...control.effort === undefined ? {} : { effort: control.effort },
|
|
1814
|
+
...control.previous === undefined ? {} : { previous: control.previous }
|
|
1755
1815
|
}
|
|
1756
|
-
]
|
|
1757
|
-
];
|
|
1758
|
-
if (row.type === "shell")
|
|
1759
|
-
return data.metadata?.background === true ? [] : [
|
|
1760
|
-
make("user", [
|
|
1761
|
-
{
|
|
1762
|
-
type: "text",
|
|
1763
|
-
text: `The following shell command was executed by the user:
|
|
1764
|
-
|
|
1765
|
-
Command:
|
|
1766
|
-
${data.command}
|
|
1767
|
-
|
|
1768
|
-
Output:
|
|
1769
|
-
${data.output?.output ?? ""}`
|
|
1770
|
-
}
|
|
1771
|
-
])
|
|
1772
|
-
];
|
|
1773
|
-
if (row.type !== "assistant")
|
|
1774
|
-
return [];
|
|
1775
|
-
const previousModel = data.model;
|
|
1776
|
-
const sameProvider = previousModel?.providerID === model.providerID;
|
|
1777
|
-
const sameModel = sameProvider && previousModel?.id === model.id;
|
|
1778
|
-
const reuse = sameModel && data.error === undefined;
|
|
1779
|
-
const metadata = (state) => state === undefined ? undefined : { [model.providerID]: state };
|
|
1780
|
-
const reasoningInterrupted = data.content?.some((part) => part.type === "reasoning" && part.time !== undefined && part.time.completed === undefined);
|
|
1781
|
-
const content = [];
|
|
1782
|
-
const results = [];
|
|
1783
|
-
for (const part of data.content ?? []) {
|
|
1784
|
-
let native = "native" in part ? part.native : part.type === "tool" ? part.providerState : part.state;
|
|
1785
|
-
if (part.type === "tool" && part.providerResultState !== null && typeof part.providerResultState === "object" && !Array.isArray(part.providerResultState))
|
|
1786
|
-
native = {
|
|
1787
|
-
...native !== null && typeof native === "object" && !Array.isArray(native) ? native : {},
|
|
1788
|
-
...part.providerResultState
|
|
1789
|
-
};
|
|
1790
|
-
if (part.type === "text") {
|
|
1791
|
-
if (part.text !== "")
|
|
1792
|
-
content.push({
|
|
1793
|
-
type: "text",
|
|
1794
|
-
text: part.text,
|
|
1795
|
-
providerMetadata: reuse ? metadata(native) : undefined
|
|
1796
|
-
});
|
|
1797
|
-
continue;
|
|
1798
|
-
}
|
|
1799
|
-
if (part.type === "reasoning") {
|
|
1800
|
-
if (part.text !== "" || reuse && !reasoningInterrupted && native !== undefined)
|
|
1801
|
-
content.push({
|
|
1802
|
-
type: data.error === undefined && !reasoningInterrupted ? "reasoning" : "text",
|
|
1803
|
-
text: part.text,
|
|
1804
|
-
providerMetadata: reuse && !reasoningInterrupted ? metadata(native) : undefined
|
|
1805
|
-
});
|
|
1806
|
-
continue;
|
|
1807
|
-
}
|
|
1808
|
-
const state = part.state;
|
|
1809
|
-
const completed = state.status === "completed" || state.status === "error";
|
|
1810
|
-
const toolReuse = reuse || sameModel && part.executed === true && completed;
|
|
1811
|
-
let input = state.input;
|
|
1812
|
-
if (state.status === "streaming" && typeof input === "string") {
|
|
1813
|
-
try {
|
|
1814
|
-
input = JSON.parse(input);
|
|
1815
|
-
} catch {}
|
|
1816
|
-
}
|
|
1817
|
-
content.push({
|
|
1818
|
-
type: "tool-call",
|
|
1819
|
-
id: part.id,
|
|
1820
|
-
name: part.name,
|
|
1821
|
-
input,
|
|
1822
|
-
providerExecuted: part.executed,
|
|
1823
|
-
providerMetadata: toolReuse ? metadata(native) : undefined
|
|
1824
|
-
});
|
|
1825
|
-
if (!completed)
|
|
1826
|
-
continue;
|
|
1827
|
-
const toolContent = state.content ?? [];
|
|
1828
|
-
const single = toolContent.length === 1 ? toolContent[0] : undefined;
|
|
1829
|
-
const result = {
|
|
1830
|
-
type: "tool-result",
|
|
1831
|
-
id: part.id,
|
|
1832
|
-
name: part.name,
|
|
1833
|
-
providerExecuted: part.executed,
|
|
1834
|
-
providerMetadata: (part.executed === true ? sameProvider : reuse) ? metadata(native) : undefined,
|
|
1835
|
-
result: state.status === "error" ? { error: state.error, content: toolContent } : single?.type === "text" ? { type: "text", value: single.text } : { type: "content", value: toolContent },
|
|
1836
|
-
...state.status === "error" ? { resultType: "error" } : {}
|
|
1816
|
+
]
|
|
1837
1817
|
};
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1818
|
+
controlCoordinates.set(message, controlKey(control));
|
|
1819
|
+
return message;
|
|
1820
|
+
};
|
|
1821
|
+
const ids = new Set(messages.flatMap((message) => coordinate(message) ?? []));
|
|
1822
|
+
const output = controls.filter((control) => !control.after || !ids.has(control.after)).map(emit);
|
|
1823
|
+
for (const message of messages) {
|
|
1824
|
+
output.push(message);
|
|
1825
|
+
const id = coordinate(message);
|
|
1826
|
+
if (id) {
|
|
1827
|
+
for (const control of remaining)
|
|
1828
|
+
if (control.after === id)
|
|
1829
|
+
output.push(emit(control));
|
|
1830
|
+
}
|
|
1842
1831
|
}
|
|
1843
|
-
return
|
|
1832
|
+
return output;
|
|
1833
|
+
}
|
|
1834
|
+
function controlsThrough(controls, reader, sessionID, through) {
|
|
1835
|
+
return controls.filter((control) => !control.after || (reader.sequenceForId(sessionID, control.after) ?? Infinity) <= through);
|
|
1844
1836
|
}
|
|
1845
1837
|
|
|
1846
1838
|
// src/v2/fold/native-replay.ts
|
|
@@ -1848,6 +1840,9 @@ var coordinates = new WeakMap;
|
|
|
1848
1840
|
function nativeRowID(message) {
|
|
1849
1841
|
return coordinates.get(message) ?? message.id;
|
|
1850
1842
|
}
|
|
1843
|
+
function bindNativeRowID(message, id) {
|
|
1844
|
+
coordinates.set(message, id);
|
|
1845
|
+
}
|
|
1851
1846
|
function copyNativeInput(messages) {
|
|
1852
1847
|
const copies = reviveNative(encodeNative(messages));
|
|
1853
1848
|
copies.forEach((copy, i) => {
|
|
@@ -1874,9 +1869,10 @@ function isAdmittedLocalCheckpoint(storage, sessionID, cut) {
|
|
|
1874
1869
|
return false;
|
|
1875
1870
|
}
|
|
1876
1871
|
}
|
|
1877
|
-
var conversational = (row) =>
|
|
1878
|
-
var historyDigest = (reader, sessionID, through) => foldDigest(JSON.stringify(reader.range(sessionID,
|
|
1872
|
+
var conversational = (row) => RAW_MESSAGE_TYPES2.includes(row.type) || row.type === "location-switched";
|
|
1873
|
+
var historyDigest = (reader, sessionID, through, after = -1) => foldDigest(JSON.stringify(reader.range(sessionID, after, through).filter(conversational)));
|
|
1879
1874
|
var admissionKey = (sessionID) => `native-fold/v2/${encodeURIComponent(sessionID)}`;
|
|
1875
|
+
var capturedReplayKey = (sessionID) => `native-fold-state/v3/${encodeURIComponent(sessionID)}`;
|
|
1880
1876
|
async function forgetNativeFoldProvenance(storage, sessionID, legacyOnly = false) {
|
|
1881
1877
|
const remove = async (key) => {
|
|
1882
1878
|
if (storage.remove)
|
|
@@ -1884,8 +1880,11 @@ async function forgetNativeFoldProvenance(storage, sessionID, legacyOnly = false
|
|
|
1884
1880
|
else
|
|
1885
1881
|
await storage.set(key, null);
|
|
1886
1882
|
};
|
|
1887
|
-
if (!legacyOnly)
|
|
1883
|
+
if (!legacyOnly) {
|
|
1888
1884
|
await remove(admissionKey(sessionID));
|
|
1885
|
+
await remove(`native-fold/v3/${encodeURIComponent(sessionID)}`);
|
|
1886
|
+
await remove(capturedReplayKey(sessionID));
|
|
1887
|
+
}
|
|
1889
1888
|
if (!storage.scan)
|
|
1890
1889
|
return;
|
|
1891
1890
|
let after;
|
|
@@ -1903,18 +1902,25 @@ class NativeFoldReplay {
|
|
|
1903
1902
|
storage;
|
|
1904
1903
|
openReader;
|
|
1905
1904
|
admissions;
|
|
1905
|
+
options;
|
|
1906
1906
|
changed = new Set;
|
|
1907
1907
|
dirty = new Set;
|
|
1908
1908
|
unavailable = new Set;
|
|
1909
1909
|
metadata = new Map;
|
|
1910
1910
|
metadataThrough = new Map;
|
|
1911
|
+
metadataAfter = new Map;
|
|
1912
|
+
stampMRU;
|
|
1911
1913
|
loaded = new Map;
|
|
1912
1914
|
sources = new Map;
|
|
1913
1915
|
staleHeads = new Set;
|
|
1914
|
-
|
|
1916
|
+
unprovenControls = new Set;
|
|
1917
|
+
editedAdmissions = new Map;
|
|
1918
|
+
legacyUpgrades = new Map;
|
|
1919
|
+
constructor(storage, openReader, admissions, options = {}) {
|
|
1915
1920
|
this.storage = storage;
|
|
1916
1921
|
this.openReader = openReader;
|
|
1917
1922
|
this.admissions = admissions;
|
|
1923
|
+
this.options = options;
|
|
1918
1924
|
storage.onEvict((sessionID) => this.clear(sessionID));
|
|
1919
1925
|
}
|
|
1920
1926
|
account(sessionID) {
|
|
@@ -1938,6 +1944,8 @@ class NativeFoldReplay {
|
|
|
1938
1944
|
this.invalidate(sessionID);
|
|
1939
1945
|
}
|
|
1940
1946
|
invalidate(sessionID, suppressNomination = false) {
|
|
1947
|
+
if (this.stampMRU?.sessionID === sessionID)
|
|
1948
|
+
this.stampMRU = undefined;
|
|
1941
1949
|
if (suppressNomination)
|
|
1942
1950
|
this.unavailable.add(sessionID);
|
|
1943
1951
|
this.dirty.add(sessionID);
|
|
@@ -1954,7 +1962,290 @@ class NativeFoldReplay {
|
|
|
1954
1962
|
return this.tail(sessionID)?.baseline;
|
|
1955
1963
|
}
|
|
1956
1964
|
admissionKey(sessionID) {
|
|
1957
|
-
return admissionKey(sessionID);
|
|
1965
|
+
return this.options.protocol === 3 ? `native-fold/v3/${encodeURIComponent(sessionID)}` : admissionKey(sessionID);
|
|
1966
|
+
}
|
|
1967
|
+
report(sessionID, reason) {
|
|
1968
|
+
try {
|
|
1969
|
+
this.options.log?.(sessionID, `v3 host fold: ${reason}`);
|
|
1970
|
+
} catch {}
|
|
1971
|
+
}
|
|
1972
|
+
async floorState(sessionID, reader, boundary, served, preferCapture = false) {
|
|
1973
|
+
const retained = this.tail(sessionID)?.replay;
|
|
1974
|
+
const controlsKnown = (replay) => replay.controls.every((control) => !control.after || reader.sequenceForId(sessionID, control.after) !== undefined);
|
|
1975
|
+
const memory = retained && validReplayState(retained) && controlsKnown(retained) && validFloor(reader, sessionID, retained.floor) ? retained : undefined;
|
|
1976
|
+
const cut = reader.latestCompaction(sessionID);
|
|
1977
|
+
const saved = await this.readV3(sessionID);
|
|
1978
|
+
const durable = saved && saved.proof.sourceDigest === foldDigest(reader.hostIdentity()) && (!cut || saved.proof.admissionID === cut.id) && controlsKnown(saved.replay) && validFloor(reader, sessionID, saved.replay.floor) ? saved.replay : undefined;
|
|
1979
|
+
const imported = importedFloor(reader, sessionID, cut?.seq);
|
|
1980
|
+
const captured = await this.readCapturedReplay(sessionID, reader);
|
|
1981
|
+
const existing = preferCapture ? captured ?? memory ?? durable : memory ?? durable ?? captured;
|
|
1982
|
+
if (preferCapture && !existing && !served)
|
|
1983
|
+
return;
|
|
1984
|
+
let floor = existing?.floor ?? imported;
|
|
1985
|
+
if (imported && (!floor || imported.after > floor.after))
|
|
1986
|
+
floor = imported;
|
|
1987
|
+
if (cut) {
|
|
1988
|
+
const meta = readSessionMeta(this.storage.db, sessionID);
|
|
1989
|
+
const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
|
|
1990
|
+
const bound = this.storage.db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(sessionID);
|
|
1991
|
+
const seq = bound?.id ? reader.sequenceForId(sessionID, bound.id) : undefined;
|
|
1992
|
+
if (meta.cachedM0Bytes && max.id <= (meta.cachedM0MaxMutationId ?? 0) && seq !== undefined && (!floor || seq > floor.after)) {
|
|
1993
|
+
const row = reader.range(sessionID, seq - 1, seq).find((row) => row.id === bound?.id);
|
|
1994
|
+
if (row)
|
|
1995
|
+
floor = floorFor(row, "summary");
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
const baseline = served ? this.servedBaseline(served) : undefined;
|
|
1999
|
+
if (boundary && baseline === boundary.summary) {
|
|
2000
|
+
const seq = reader.sequenceForId(sessionID, boundary.id);
|
|
2001
|
+
if (seq !== undefined && (!floor || seq > floor.after)) {
|
|
2002
|
+
const row = reader.range(sessionID, seq - 1, seq).find((row) => row.id === boundary.id);
|
|
2003
|
+
if (row)
|
|
2004
|
+
floor = floorFor(row, "summary");
|
|
2005
|
+
}
|
|
2006
|
+
}
|
|
2007
|
+
if (!floor && !cut) {
|
|
2008
|
+
const row = reader.page(sessionID, { limit: 1 }).rows[0];
|
|
2009
|
+
if (row)
|
|
2010
|
+
floor = floorFor(row, "start");
|
|
2011
|
+
}
|
|
2012
|
+
return floor ? { ...existing, floor, controls: existing?.controls ?? [], blocked: existing?.blocked } : undefined;
|
|
2013
|
+
}
|
|
2014
|
+
async readV3(sessionID) {
|
|
2015
|
+
const saved = await this.admissions?.get(this.admissionKey(sessionID));
|
|
2016
|
+
if (typeof saved?.payload !== "string" || saved.digest !== foldDigest(saved.payload))
|
|
2017
|
+
return;
|
|
2018
|
+
try {
|
|
2019
|
+
const value = JSON.parse(saved.payload);
|
|
2020
|
+
return validAdmissionV3(value) && value.proof.sessionID === sessionID ? value : undefined;
|
|
2021
|
+
} catch {
|
|
2022
|
+
return;
|
|
2023
|
+
}
|
|
2024
|
+
}
|
|
2025
|
+
async readCapturedReplay(sessionID, reader) {
|
|
2026
|
+
const saved = await this.admissions?.get(capturedReplayKey(sessionID));
|
|
2027
|
+
if (typeof saved?.payload !== "string" || saved.digest !== foldDigest(saved.payload))
|
|
2028
|
+
return;
|
|
2029
|
+
try {
|
|
2030
|
+
const value = JSON.parse(saved.payload);
|
|
2031
|
+
return validCapturedReplayV3(value) && value.sessionID === sessionID && value.sourceDigest === foldDigest(reader.hostIdentity()) && value.through <= reader.latestSequence(sessionID) && validFloor(reader, sessionID, value.replay.floor) && value.replay.controls.every((control) => !control.after || reader.sequenceForId(sessionID, control.after) !== undefined) ? value.replay : undefined;
|
|
2032
|
+
} catch {
|
|
2033
|
+
return;
|
|
2034
|
+
}
|
|
2035
|
+
}
|
|
2036
|
+
async saveCapturedReplay(sessionID, replay, reader) {
|
|
2037
|
+
const value = {
|
|
2038
|
+
version: 3,
|
|
2039
|
+
sessionID,
|
|
2040
|
+
sourceDigest: foldDigest(reader.hostIdentity()),
|
|
2041
|
+
through: reader.latestSequence(sessionID),
|
|
2042
|
+
replay
|
|
2043
|
+
};
|
|
2044
|
+
if (!validCapturedReplayV3(value))
|
|
2045
|
+
throw new Error("Unsupported captured native replay metadata");
|
|
2046
|
+
const payload = JSON.stringify(value);
|
|
2047
|
+
try {
|
|
2048
|
+
await this.admissions?.set(capturedReplayKey(sessionID), {
|
|
2049
|
+
payload,
|
|
2050
|
+
digest: foldDigest(payload)
|
|
2051
|
+
});
|
|
2052
|
+
this.unprovenControls.delete(sessionID);
|
|
2053
|
+
} catch (error) {
|
|
2054
|
+
this.unprovenControls.add(sessionID);
|
|
2055
|
+
throw error;
|
|
2056
|
+
}
|
|
2057
|
+
}
|
|
2058
|
+
servedBaseline(draft) {
|
|
2059
|
+
const identified = draft.messages.find((message) => message.id === HEAD_IDS[0])?.content.find((part) => part.type === "text")?.text;
|
|
2060
|
+
if (typeof identified === "string")
|
|
2061
|
+
return identified;
|
|
2062
|
+
if (this.options.protocol !== 3)
|
|
2063
|
+
return;
|
|
2064
|
+
const cached = readSessionMeta(this.storage.db, draft.sessionID).cachedM0Bytes?.toString("utf8");
|
|
2065
|
+
const checkpointID = this.tail(draft.sessionID)?.replay?.floor.kind === "host-checkpoint" ? this.tail(draft.sessionID)?.replay?.floor.id : undefined;
|
|
2066
|
+
return cached && draft.messages.some((message) => message.content.some((part) => part.type === "text" && (part.text === cached || message.id === checkpointID && typeof part.text === "string" && part.text.includes(`<summary>
|
|
2067
|
+
${cached}
|
|
2068
|
+
</summary>`)))) ? cached : undefined;
|
|
2069
|
+
}
|
|
2070
|
+
async retainReplay(sessionID, replay, model, sourceSeq) {
|
|
2071
|
+
const tail = this.tail(sessionID) ?? { model, sourceSeq };
|
|
2072
|
+
await this.storage.saveTail(sessionID, JSON.stringify({ ...tail, replay }), []);
|
|
2073
|
+
if (!this.storage.tail(sessionID))
|
|
2074
|
+
await this.storage.saveTail(sessionID, JSON.stringify({ model, sourceSeq, replay }), []);
|
|
2075
|
+
}
|
|
2076
|
+
async canFold(sessionID, reader) {
|
|
2077
|
+
if (this.options.protocol !== 3) {
|
|
2078
|
+
const future = await this.admissions?.get(`native-fold/v3/${encodeURIComponent(sessionID)}`);
|
|
2079
|
+
if (future) {
|
|
2080
|
+
this.report(sessionID, "refused: unsupported admission version");
|
|
2081
|
+
return false;
|
|
2082
|
+
}
|
|
2083
|
+
return true;
|
|
2084
|
+
}
|
|
2085
|
+
if (await this.admissions?.get(admissionKey(sessionID)) && !await this.readV3(sessionID)) {
|
|
2086
|
+
this.report(sessionID, "fold refused: V2 upgrade has not completed a rebuilding pass");
|
|
2087
|
+
return false;
|
|
2088
|
+
}
|
|
2089
|
+
if (this.unprovenControls.has(sessionID)) {
|
|
2090
|
+
this.report(sessionID, "fold refused: capture controls have not been persisted");
|
|
2091
|
+
return false;
|
|
2092
|
+
}
|
|
2093
|
+
const replay = await this.floorState(sessionID, reader, undefined, undefined, true);
|
|
2094
|
+
if (!replay || replay.blocked) {
|
|
2095
|
+
this.report(sessionID, "refused: no usable host replay boundary; waiting for a permitted rebuild");
|
|
2096
|
+
return false;
|
|
2097
|
+
}
|
|
2098
|
+
return true;
|
|
2099
|
+
}
|
|
2100
|
+
async restorationFloor(sessionID, _cut, reader) {
|
|
2101
|
+
if (this.options.protocol !== 3)
|
|
2102
|
+
return;
|
|
2103
|
+
const replay = await this.floorState(sessionID, reader);
|
|
2104
|
+
if (replay)
|
|
2105
|
+
return replay.floor.after;
|
|
2106
|
+
const current = await this.admissions?.get(this.admissionKey(sessionID));
|
|
2107
|
+
const legacy = await this.admissions?.get(admissionKey(sessionID));
|
|
2108
|
+
if (current || legacy?.payload) {
|
|
2109
|
+
this.report(sessionID, "replay refused: no usable host checkpoint boundary");
|
|
2110
|
+
throw new NativeReplayUnavailable("Host checkpoint replay boundary is unavailable");
|
|
2111
|
+
}
|
|
2112
|
+
return;
|
|
2113
|
+
}
|
|
2114
|
+
async prepareLegacyUpgrade(args) {
|
|
2115
|
+
const { draft, cut, reader } = args;
|
|
2116
|
+
const admissions = this.admissions;
|
|
2117
|
+
if (this.options.protocol !== 3 || !admissions || !isLocalCheckpoint(cut))
|
|
2118
|
+
return false;
|
|
2119
|
+
if (await this.readV3(draft.sessionID))
|
|
2120
|
+
return false;
|
|
2121
|
+
this.legacyUpgrades.delete(draft.sessionID);
|
|
2122
|
+
const started = performance.now();
|
|
2123
|
+
const receipt = await this.admissions?.get(admissionKey(draft.sessionID));
|
|
2124
|
+
if (!receipt?.payload || receipt.digest !== foldDigest(receipt.payload))
|
|
2125
|
+
return false;
|
|
2126
|
+
let legacy;
|
|
2127
|
+
try {
|
|
2128
|
+
legacy = JSON.parse(receipt.payload);
|
|
2129
|
+
} catch {
|
|
2130
|
+
return false;
|
|
2131
|
+
}
|
|
2132
|
+
if (legacy.sourceDigest !== foldDigest(reader.hostIdentity()) || legacy.sessionID !== draft.sessionID || legacy.admissionID !== cut.id || legacy.summaryDigest !== foldDigest(cut.data.summary ?? "") || !/^[a-f0-9]{64}$/.test(legacy.historyDigest))
|
|
2133
|
+
return false;
|
|
2134
|
+
const rows = reader.range(draft.sessionID, -1, cut.seq - 1).filter(conversational);
|
|
2135
|
+
if (foldDigest(JSON.stringify(rows)) !== legacy.historyDigest)
|
|
2136
|
+
return false;
|
|
2137
|
+
let floor;
|
|
2138
|
+
if (!floor) {
|
|
2139
|
+
const candidate = await this.floorState(draft.sessionID, reader);
|
|
2140
|
+
const cached = readSessionMeta(this.storage.db, draft.sessionID).cachedM0Bytes?.toString("utf8");
|
|
2141
|
+
if (candidate && (candidate.floor.kind === "checkpoint" || candidate.floor.kind === "summary" && cached === cut.data.summary))
|
|
2142
|
+
floor = candidate.floor;
|
|
2143
|
+
}
|
|
2144
|
+
const mode = floor ? "bounded" : "source-repair";
|
|
2145
|
+
floor ??= rows[0] ? floorFor(rows[0], "start") : floorFor(cut, "checkpoint");
|
|
2146
|
+
let controls = [];
|
|
2147
|
+
let blocked = false;
|
|
2148
|
+
try {
|
|
2149
|
+
controls = captureControls(draft, nativeRowID, new Set(draft.messages.flatMap((message) => nativeRowID(message) ?? [])));
|
|
2150
|
+
} catch (error) {
|
|
2151
|
+
if (!(error instanceof ControlMetadataUnavailable))
|
|
2152
|
+
throw error;
|
|
2153
|
+
blocked = true;
|
|
2154
|
+
}
|
|
2155
|
+
const replay = {
|
|
2156
|
+
floor,
|
|
2157
|
+
controls,
|
|
2158
|
+
...blocked ? { blocked } : {},
|
|
2159
|
+
upgrade: { admissionID: cut.id, mode }
|
|
2160
|
+
};
|
|
2161
|
+
const value = {
|
|
2162
|
+
version: 3,
|
|
2163
|
+
replay,
|
|
2164
|
+
proof: {
|
|
2165
|
+
sourceDigest: legacy.sourceDigest,
|
|
2166
|
+
sessionID: draft.sessionID,
|
|
2167
|
+
admissionID: cut.id,
|
|
2168
|
+
summaryDigest: legacy.summaryDigest,
|
|
2169
|
+
historyDigest: foldDigest(JSON.stringify(rows.filter((row) => row.seq > floor.after)))
|
|
2170
|
+
}
|
|
2171
|
+
};
|
|
2172
|
+
this.legacyUpgrades.set(draft.sessionID, { value, rows, started });
|
|
2173
|
+
await this.retainReplay(draft.sessionID, replay, `${draft.model.providerID}/${draft.model.id}`, cut.seq - 1);
|
|
2174
|
+
return true;
|
|
2175
|
+
}
|
|
2176
|
+
legacyUpgradeInput(sessionID, model) {
|
|
2177
|
+
const pending = this.legacyUpgrades.get(sessionID);
|
|
2178
|
+
if (!pending)
|
|
2179
|
+
return;
|
|
2180
|
+
return pending.rows.filter((row) => row.seq > pending.value.replay.floor.after).flatMap((row) => {
|
|
2181
|
+
const messages = this.rendered(structuredClone(row), model);
|
|
2182
|
+
for (const message of messages)
|
|
2183
|
+
coordinates.set(message, row.id);
|
|
2184
|
+
return messages;
|
|
2185
|
+
});
|
|
2186
|
+
}
|
|
2187
|
+
async commitLegacyUpgrade(sessionID, prefixMutationPermitted) {
|
|
2188
|
+
if (!prefixMutationPermitted)
|
|
2189
|
+
return false;
|
|
2190
|
+
const pending = this.legacyUpgrades.get(sessionID);
|
|
2191
|
+
const admissions = this.admissions;
|
|
2192
|
+
if (!pending || !admissions)
|
|
2193
|
+
return false;
|
|
2194
|
+
const replay = this.tail(sessionID)?.replay ?? pending.value.replay;
|
|
2195
|
+
if (replay.blocked)
|
|
2196
|
+
return false;
|
|
2197
|
+
const value = {
|
|
2198
|
+
...pending.value,
|
|
2199
|
+
replay,
|
|
2200
|
+
proof: {
|
|
2201
|
+
...pending.value.proof,
|
|
2202
|
+
historyDigest: foldDigest(JSON.stringify(pending.rows.filter((row) => row.seq > replay.floor.after)))
|
|
2203
|
+
}
|
|
2204
|
+
};
|
|
2205
|
+
const payload = encodeAdmissionV3(value);
|
|
2206
|
+
await admissions.set(this.admissionKey(sessionID), {
|
|
2207
|
+
payload,
|
|
2208
|
+
digest: foldDigest(payload)
|
|
2209
|
+
});
|
|
2210
|
+
this.legacyUpgrades.delete(sessionID);
|
|
2211
|
+
this.report(sessionID, `V2 upgrade-state HARD mode=${replay.upgrade?.mode} rows_read=${pending.rows.length} duration_ms=${Math.round(performance.now() - pending.started)} floor=${replay.floor.id}:${replay.floor.after}`);
|
|
2212
|
+
return true;
|
|
2213
|
+
}
|
|
2214
|
+
cancelLegacyUpgrade(sessionID) {
|
|
2215
|
+
this.legacyUpgrades.delete(sessionID);
|
|
2216
|
+
}
|
|
2217
|
+
async checkpointForReplay(sessionID, reader) {
|
|
2218
|
+
if (this.options.protocol !== 3)
|
|
2219
|
+
return;
|
|
2220
|
+
const replay = await this.floorState(sessionID, reader);
|
|
2221
|
+
if (replay?.floor.kind !== "host-checkpoint")
|
|
2222
|
+
return;
|
|
2223
|
+
const row = reader.range(sessionID, replay.floor.seq - 1, replay.floor.seq).find((row) => row.id === replay.floor.id && row.type === "compaction");
|
|
2224
|
+
if (!row || !isLocalCheckpoint(row))
|
|
2225
|
+
return;
|
|
2226
|
+
const rendered = hostCheckpointCarrier(row);
|
|
2227
|
+
if (replay.withoutRecentContext)
|
|
2228
|
+
stripCheckpointRecentContext(rendered, row.data.summary ?? "");
|
|
2229
|
+
return { row, rendered, submitted: row.data.summary ?? "" };
|
|
2230
|
+
}
|
|
2231
|
+
async checkpointCovered(sessionID, checkpointID) {
|
|
2232
|
+
const admissions = this.admissions;
|
|
2233
|
+
if (!admissions)
|
|
2234
|
+
return;
|
|
2235
|
+
const pending = this.legacyUpgrades.get(sessionID);
|
|
2236
|
+
const value = await this.readV3(sessionID) ?? pending?.value;
|
|
2237
|
+
if (value?.replay.floor.kind !== "host-checkpoint" || value.replay.floor.id !== checkpointID || value.replay.withoutRecentContext)
|
|
2238
|
+
return;
|
|
2239
|
+
value.replay.withoutRecentContext = true;
|
|
2240
|
+
const payload = encodeAdmissionV3(value);
|
|
2241
|
+
if (!pending)
|
|
2242
|
+
await admissions.set(this.admissionKey(sessionID), {
|
|
2243
|
+
payload,
|
|
2244
|
+
digest: foldDigest(payload)
|
|
2245
|
+
});
|
|
2246
|
+
const tail = this.tail(sessionID);
|
|
2247
|
+
if (tail)
|
|
2248
|
+
await this.retainReplay(sessionID, value.replay, tail.model, tail.sourceSeq);
|
|
1958
2249
|
}
|
|
1959
2250
|
async removeAdmission(key) {
|
|
1960
2251
|
if (this.admissions?.remove)
|
|
@@ -1967,6 +2258,46 @@ class NativeFoldReplay {
|
|
|
1967
2258
|
await forgetNativeFoldProvenance(this.admissions, sessionID, true);
|
|
1968
2259
|
}
|
|
1969
2260
|
async admits(sessionID, cut, reader) {
|
|
2261
|
+
if (this.options.protocol === 3) {
|
|
2262
|
+
const saved = await this.readV3(sessionID);
|
|
2263
|
+
if (!saved || !isLocalCheckpoint(cut) || cut.session_id !== sessionID)
|
|
2264
|
+
return false;
|
|
2265
|
+
const proof = saved.proof;
|
|
2266
|
+
if (proof.sourceDigest !== foldDigest(reader.hostIdentity()) || proof.admissionID !== cut.id || proof.summaryDigest !== foldDigest(cut.data.summary ?? "")) {
|
|
2267
|
+
this.report(sessionID, "replay refused: invalid checkpoint floor or provenance");
|
|
2268
|
+
return false;
|
|
2269
|
+
}
|
|
2270
|
+
let replay = saved.replay;
|
|
2271
|
+
if (!validFloor(reader, sessionID, replay.floor)) {
|
|
2272
|
+
const floor = replay.floor;
|
|
2273
|
+
const anchor = floor?.kind === "start" && Number.isSafeInteger(floor.seq) && floor.after === floor.seq - 1 ? reader.range(sessionID, floor.seq - 1, floor.seq).find((row) => row.id === floor.id && row.session_id === sessionID && conversational(row)) : undefined;
|
|
2274
|
+
if (!anchor) {
|
|
2275
|
+
this.report(sessionID, "replay refused: invalid checkpoint floor or provenance");
|
|
2276
|
+
return false;
|
|
2277
|
+
}
|
|
2278
|
+
replay = { ...replay, floor: floorFor(anchor, "start") };
|
|
2279
|
+
this.editedAdmissions.set(sessionID, { original: saved, replay });
|
|
2280
|
+
this.staleHeads.add(sessionID);
|
|
2281
|
+
this.invalidate(sessionID);
|
|
2282
|
+
await this.retainReplay(sessionID, replay, this.tail(sessionID)?.model ?? "", cut.seq - 1);
|
|
2283
|
+
return false;
|
|
2284
|
+
}
|
|
2285
|
+
await this.retainReplay(sessionID, saved.replay, this.tail(sessionID)?.model ?? "", cut.seq - 1);
|
|
2286
|
+
if (proof.historyDigest !== historyDigest(reader, sessionID, cut.seq - 1, saved.replay.floor.after)) {
|
|
2287
|
+
this.staleHeads.add(sessionID);
|
|
2288
|
+
this.invalidate(sessionID);
|
|
2289
|
+
this.editedAdmissions.set(sessionID, { original: saved, replay });
|
|
2290
|
+
await this.retainReplay(sessionID, saved.replay, this.tail(sessionID)?.model ?? "", cut.seq - 1);
|
|
2291
|
+
return false;
|
|
2292
|
+
}
|
|
2293
|
+
await this.storage.supply(sessionID, cut.id, JSON.stringify({
|
|
2294
|
+
source: this.storage.sourceID,
|
|
2295
|
+
sessionID,
|
|
2296
|
+
admissionID: cut.id,
|
|
2297
|
+
summary: cut.data.summary
|
|
2298
|
+
}));
|
|
2299
|
+
return true;
|
|
2300
|
+
}
|
|
1970
2301
|
if (!isLocalCheckpoint(cut) || cut.session_id !== sessionID)
|
|
1971
2302
|
return false;
|
|
1972
2303
|
if (isAdmittedLocalCheckpoint(this.storage, sessionID, cut))
|
|
@@ -1998,6 +2329,121 @@ class NativeFoldReplay {
|
|
|
1998
2329
|
return false;
|
|
1999
2330
|
}
|
|
2000
2331
|
}
|
|
2332
|
+
async commitEditedAdmission(sessionID) {
|
|
2333
|
+
const pending = this.editedAdmissions.get(sessionID);
|
|
2334
|
+
const admissions = this.admissions;
|
|
2335
|
+
if (!pending || !admissions)
|
|
2336
|
+
return false;
|
|
2337
|
+
const current = await this.readV3(sessionID);
|
|
2338
|
+
if (JSON.stringify(current) !== JSON.stringify(pending.original))
|
|
2339
|
+
return false;
|
|
2340
|
+
const reader = this.openReader(sessionID);
|
|
2341
|
+
try {
|
|
2342
|
+
const cut = reader.latestCompaction(sessionID);
|
|
2343
|
+
const proof = pending.original.proof;
|
|
2344
|
+
const replay = this.tail(sessionID)?.replay ?? pending.replay;
|
|
2345
|
+
if (!cut || cut.id !== proof.admissionID || !isLocalCheckpoint(cut) || proof.sourceDigest !== foldDigest(reader.hostIdentity()) || proof.summaryDigest !== foldDigest(cut.data.summary ?? "") || !validFloor(reader, sessionID, replay.floor))
|
|
2346
|
+
return false;
|
|
2347
|
+
const value = {
|
|
2348
|
+
...pending.original,
|
|
2349
|
+
replay: {
|
|
2350
|
+
...replay,
|
|
2351
|
+
controls: controlsThrough(replay.controls, reader, sessionID, cut.seq - 1)
|
|
2352
|
+
},
|
|
2353
|
+
proof: {
|
|
2354
|
+
...proof,
|
|
2355
|
+
historyDigest: historyDigest(reader, sessionID, cut.seq - 1, replay.floor.after)
|
|
2356
|
+
}
|
|
2357
|
+
};
|
|
2358
|
+
const payload = encodeAdmissionV3(value);
|
|
2359
|
+
await admissions.set(this.admissionKey(sessionID), {
|
|
2360
|
+
payload,
|
|
2361
|
+
digest: foldDigest(payload)
|
|
2362
|
+
});
|
|
2363
|
+
this.editedAdmissions.delete(sessionID);
|
|
2364
|
+
return true;
|
|
2365
|
+
} finally {
|
|
2366
|
+
reader.close();
|
|
2367
|
+
}
|
|
2368
|
+
}
|
|
2369
|
+
cancelEditedAdmission(sessionID) {
|
|
2370
|
+
this.editedAdmissions.delete(sessionID);
|
|
2371
|
+
}
|
|
2372
|
+
async replayAdmission(sessionID, cut, reader) {
|
|
2373
|
+
if (this.options.protocol === 3) {
|
|
2374
|
+
const saved = await this.readV3(sessionID);
|
|
2375
|
+
if (!saved)
|
|
2376
|
+
return "legacy";
|
|
2377
|
+
if (saved.proof.admissionID !== cut.id)
|
|
2378
|
+
return "legacy";
|
|
2379
|
+
return saved.proof.sourceDigest === foldDigest(reader.hostIdentity()) && saved.proof.summaryDigest === foldDigest(cut.data.summary ?? "") && validFloor(reader, sessionID, saved.replay.floor) && saved.proof.historyDigest === historyDigest(reader, sessionID, cut.seq - 1, saved.replay.floor.after) ? "native" : undefined;
|
|
2380
|
+
}
|
|
2381
|
+
if (!isLocalCheckpoint(cut) || cut.session_id !== sessionID)
|
|
2382
|
+
return;
|
|
2383
|
+
try {
|
|
2384
|
+
const source = reader.hostIdentity();
|
|
2385
|
+
const observed = this.sources.get(sessionID);
|
|
2386
|
+
if (observed && observed !== source)
|
|
2387
|
+
return;
|
|
2388
|
+
if (observed === source && isAdmittedLocalCheckpoint(this.storage, sessionID, cut))
|
|
2389
|
+
return "native";
|
|
2390
|
+
const saved = await this.admissions?.get(this.admissionKey(sessionID));
|
|
2391
|
+
if (!saved)
|
|
2392
|
+
return "legacy";
|
|
2393
|
+
if (!saved.payload || saved.digest !== foldDigest(saved.payload))
|
|
2394
|
+
return;
|
|
2395
|
+
const snapshot = JSON.parse(saved.payload);
|
|
2396
|
+
if (snapshot.admissionID !== cut.id)
|
|
2397
|
+
return "legacy";
|
|
2398
|
+
if (snapshot.sourceDigest !== foldDigest(source) || snapshot.sessionID !== sessionID || snapshot.summaryDigest !== foldDigest(cut.data.summary ?? "") || snapshot.historyDigest !== historyDigest(reader, sessionID, cut.seq - 1))
|
|
2399
|
+
return;
|
|
2400
|
+
return "native";
|
|
2401
|
+
} catch {
|
|
2402
|
+
return;
|
|
2403
|
+
}
|
|
2404
|
+
}
|
|
2405
|
+
replayInput(args, replayOverride) {
|
|
2406
|
+
const { sessionID, cut, model, reader } = args;
|
|
2407
|
+
if (!isLocalCheckpoint(cut) || cut.session_id !== sessionID)
|
|
2408
|
+
return;
|
|
2409
|
+
let after = -1;
|
|
2410
|
+
if (this.options.protocol === 3) {
|
|
2411
|
+
const replay = replayOverride ?? this.tail(sessionID)?.replay;
|
|
2412
|
+
if (!replay || !validFloor(reader, sessionID, replay.floor))
|
|
2413
|
+
return;
|
|
2414
|
+
after = replay.floor.after;
|
|
2415
|
+
} else if (args.bounded && !this.changed.has(sessionID)) {
|
|
2416
|
+
const state = readSessionMeta(this.storage.db, sessionID);
|
|
2417
|
+
const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
|
|
2418
|
+
const boundary = this.storage.db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(sessionID)?.id;
|
|
2419
|
+
if (max.id <= (state.cachedM0MaxMutationId ?? 0) && boundary)
|
|
2420
|
+
after = reader.sequenceForId(sessionID, boundary) ?? -1;
|
|
2421
|
+
}
|
|
2422
|
+
const through = cut.seq - 1;
|
|
2423
|
+
const metadata = (this.metadataThrough.get(sessionID) ?? -1) >= through ? this.metadata.get(sessionID) : undefined;
|
|
2424
|
+
const required = (metadata ?? reader.rowStampsThrough(sessionID, through, this.options.protocol === 3 ? after : undefined)).filter(conversational).filter((row) => row.seq > after && row.seq <= through);
|
|
2425
|
+
const tail = this.tail(sessionID);
|
|
2426
|
+
let records;
|
|
2427
|
+
if (!this.dirty.has(sessionID) && tail?.model === `${model.providerID}/${model.id}` && this.storage.containsRows(sessionID, required.map((row) => row.id))) {
|
|
2428
|
+
records = this.storage.rows(sessionID, after, through);
|
|
2429
|
+
} else {
|
|
2430
|
+
records = reader.range(sessionID, after, through).filter(conversational).map((row) => this.record(row, this.rendered(row, model)));
|
|
2431
|
+
const restored = new Set(records.map((row) => row.id));
|
|
2432
|
+
if (required.some((row) => !restored.has(row.id)))
|
|
2433
|
+
return;
|
|
2434
|
+
}
|
|
2435
|
+
const projected = records.flatMap((row) => {
|
|
2436
|
+
const messages = reviveNative(JSON.parse(row.data));
|
|
2437
|
+
for (const message of messages)
|
|
2438
|
+
coordinates.set(message, row.id);
|
|
2439
|
+
return messages;
|
|
2440
|
+
});
|
|
2441
|
+
return this.options.protocol === 3 ? insertControls(projected, controlsThrough((replayOverride ?? this.tail(sessionID)?.replay)?.controls ?? [], reader, sessionID, through), nativeRowID) : projected;
|
|
2442
|
+
}
|
|
2443
|
+
async projectReplay(args) {
|
|
2444
|
+
const replay = this.options.protocol === 3 ? await this.floorState(args.sessionID, args.reader) : undefined;
|
|
2445
|
+
return this.replayInput(args, replay);
|
|
2446
|
+
}
|
|
2001
2447
|
rendered(row, model) {
|
|
2002
2448
|
return restoreRow(row, model, hostUsesMediaAssets() ? {
|
|
2003
2449
|
asset: hostMediaAsset,
|
|
@@ -2008,15 +2454,31 @@ class NativeFoldReplay {
|
|
|
2008
2454
|
const data = JSON.stringify(encodeNative(messages));
|
|
2009
2455
|
return { id: row.id, type: row.type, seq: row.seq, data, digest: foldDigest(data) };
|
|
2010
2456
|
}
|
|
2011
|
-
records(sessionID, native, reader) {
|
|
2012
|
-
let metadata = this.metadata.get(sessionID);
|
|
2457
|
+
records(sessionID, native, reader, after) {
|
|
2013
2458
|
const through = reader.latestSequence(sessionID);
|
|
2459
|
+
const retained = this.stampMRU;
|
|
2460
|
+
let metadata = this.metadata.get(sessionID);
|
|
2461
|
+
if (!metadata && retained?.sessionID === sessionID && retained.source === reader.hostIdentity() && retained.after === after && retained.through === through) {
|
|
2462
|
+
metadata = retained.rows;
|
|
2463
|
+
this.metadata.set(sessionID, metadata);
|
|
2464
|
+
this.metadataThrough.set(sessionID, through);
|
|
2465
|
+
this.metadataAfter.set(sessionID, after);
|
|
2466
|
+
}
|
|
2014
2467
|
const known = new Set(metadata?.map((row) => row.id));
|
|
2015
|
-
if (!metadata || (this.metadataThrough.get(sessionID) ?? -1) < through || native.some((message) => message.id && !known.has(message.id))) {
|
|
2016
|
-
metadata = reader.rowStampsThrough(sessionID, through).filter(conversational);
|
|
2468
|
+
if (!metadata || this.metadataAfter.get(sessionID) !== after || (this.metadataThrough.get(sessionID) ?? -1) < through || native.some((message) => message.id && !known.has(message.id))) {
|
|
2469
|
+
metadata = reader.rowStampsThrough(sessionID, through, after).filter(conversational);
|
|
2017
2470
|
this.metadata.set(sessionID, metadata);
|
|
2018
2471
|
this.metadataThrough.set(sessionID, through);
|
|
2472
|
+
this.metadataAfter.set(sessionID, after);
|
|
2019
2473
|
}
|
|
2474
|
+
if (this.options.protocol === 3)
|
|
2475
|
+
this.stampMRU = {
|
|
2476
|
+
sessionID,
|
|
2477
|
+
source: reader.hostIdentity(),
|
|
2478
|
+
through,
|
|
2479
|
+
after,
|
|
2480
|
+
rows: metadata
|
|
2481
|
+
};
|
|
2020
2482
|
const byID = new Map(metadata.map((row) => [row.id, row]));
|
|
2021
2483
|
const grouped = new Map;
|
|
2022
2484
|
const anchorIndex = native.findIndex((message) => {
|
|
@@ -2033,6 +2495,14 @@ class NativeFoldReplay {
|
|
|
2033
2495
|
let owner;
|
|
2034
2496
|
for (const message of native) {
|
|
2035
2497
|
let id = nativeRowID(message);
|
|
2498
|
+
if (this.options.protocol === 3 && !id && message.role === "system") {
|
|
2499
|
+
const text = message.content.filter((part) => part.type === "text").map((part) => part.text).join(`
|
|
2500
|
+
`);
|
|
2501
|
+
const source = metadata.filter((row) => row.type === "system" && row.seq > cursor).find((row) => reader.range(sessionID, row.seq - 1, row.seq).some((stored) => stored.id === row.id && stored.data.text === text));
|
|
2502
|
+
id = source?.id;
|
|
2503
|
+
if (!id)
|
|
2504
|
+
continue;
|
|
2505
|
+
}
|
|
2036
2506
|
if (!id && message.role === "system") {
|
|
2037
2507
|
if (leadingIDs.has(message)) {
|
|
2038
2508
|
id = leadingIDs.get(message);
|
|
@@ -2056,15 +2526,65 @@ class NativeFoldReplay {
|
|
|
2056
2526
|
}
|
|
2057
2527
|
return [...grouped].map(([row, messages]) => this.record(row, messages));
|
|
2058
2528
|
}
|
|
2059
|
-
async capture(draft, native) {
|
|
2529
|
+
async capture(draft, native, boundary) {
|
|
2060
2530
|
const release = this.storage.hold(draft.sessionID);
|
|
2531
|
+
let replay;
|
|
2532
|
+
let sourceSeq = -1;
|
|
2061
2533
|
try {
|
|
2062
2534
|
rememberHostMedia(native);
|
|
2063
2535
|
const reader = this.openReader(draft.sessionID);
|
|
2064
2536
|
try {
|
|
2065
|
-
|
|
2066
|
-
|
|
2537
|
+
let captured = native;
|
|
2538
|
+
if (this.options.protocol === 3) {
|
|
2539
|
+
replay = await this.floorState(draft.sessionID, reader, boundary, draft);
|
|
2540
|
+
if (!replay)
|
|
2541
|
+
throw new NativeReplayUnavailable("No usable host replay boundary");
|
|
2542
|
+
replay = { ...replay, blocked: false };
|
|
2543
|
+
const replayAfter = replay.floor.after;
|
|
2544
|
+
const replayStart = replay.floor.kind === "start";
|
|
2545
|
+
captured = native.filter((message) => {
|
|
2546
|
+
if (effortPart(message))
|
|
2547
|
+
return false;
|
|
2548
|
+
const id = nativeRowID(message);
|
|
2549
|
+
if (HEAD_IDS.some((head) => head === id))
|
|
2550
|
+
return false;
|
|
2551
|
+
const baseline = this.servedBaseline(draft);
|
|
2552
|
+
if (!id)
|
|
2553
|
+
return !(baseline && message.role === "user" && message.content.some((part) => part.type === "text" && part.text === baseline));
|
|
2554
|
+
if (replayStart)
|
|
2555
|
+
return true;
|
|
2556
|
+
const seq = reader.sequenceForId(draft.sessionID, id);
|
|
2557
|
+
return seq === undefined || seq > replayAfter;
|
|
2558
|
+
});
|
|
2559
|
+
}
|
|
2560
|
+
let rows = this.records(draft.sessionID, captured, reader, replay?.floor.after);
|
|
2561
|
+
if (replay) {
|
|
2562
|
+
const identities = new Map;
|
|
2563
|
+
for (const row of rows.filter((row) => row.type === "system")) {
|
|
2564
|
+
for (const message of reviveNative(JSON.parse(row.data))) {
|
|
2565
|
+
const key = JSON.stringify(message.content);
|
|
2566
|
+
const found = identities.get(key) ?? [];
|
|
2567
|
+
found.push(row.id);
|
|
2568
|
+
identities.set(key, found);
|
|
2569
|
+
}
|
|
2570
|
+
}
|
|
2571
|
+
const ids = new Set(rows.map((row) => row.id));
|
|
2572
|
+
replay = {
|
|
2573
|
+
...replay,
|
|
2574
|
+
blocked: false,
|
|
2575
|
+
controls: captureControls(draft, (message) => nativeRowID(message) ?? (message.role === "system" ? identities.get(JSON.stringify(message.content))?.shift() : undefined), ids)
|
|
2576
|
+
};
|
|
2577
|
+
}
|
|
2578
|
+
const baseline = this.servedBaseline(draft);
|
|
2067
2579
|
const through = Math.max(-1, ...rows.map((row) => row.seq));
|
|
2580
|
+
sourceSeq = through;
|
|
2581
|
+
if (boundary && baseline === boundary.summary) {
|
|
2582
|
+
const after = reader.sequenceForId(draft.sessionID, boundary.id);
|
|
2583
|
+
if (after !== undefined) {
|
|
2584
|
+
rows = rows.filter((row) => row.seq > after);
|
|
2585
|
+
this.storage.replaceRows(draft.sessionID, through, rows);
|
|
2586
|
+
}
|
|
2587
|
+
}
|
|
2068
2588
|
const tail = {
|
|
2069
2589
|
model: `${draft.model.providerID}/${draft.model.id}`,
|
|
2070
2590
|
sourceSeq: through,
|
|
@@ -2079,13 +2599,48 @@ class NativeFoldReplay {
|
|
|
2079
2599
|
} finally {
|
|
2080
2600
|
reader.close();
|
|
2081
2601
|
}
|
|
2082
|
-
} catch {
|
|
2602
|
+
} catch (error) {
|
|
2083
2603
|
this.unavailable.add(draft.sessionID);
|
|
2084
2604
|
this.invalidate(draft.sessionID);
|
|
2605
|
+
if (replay)
|
|
2606
|
+
replay = { ...replay, blocked: true };
|
|
2607
|
+
if (this.options.protocol === 3)
|
|
2608
|
+
this.report(draft.sessionID, `capture unavailable: ${String(error)}`);
|
|
2085
2609
|
} finally {
|
|
2086
2610
|
this.account(draft.sessionID);
|
|
2087
2611
|
release();
|
|
2088
2612
|
}
|
|
2613
|
+
if (replay) {
|
|
2614
|
+
await this.retainReplay(draft.sessionID, replay, `${draft.model.providerID}/${draft.model.id}`, sourceSeq);
|
|
2615
|
+
const reader = this.openReader(draft.sessionID);
|
|
2616
|
+
try {
|
|
2617
|
+
await this.saveCapturedReplay(draft.sessionID, replay, reader);
|
|
2618
|
+
const saved = await this.readV3(draft.sessionID);
|
|
2619
|
+
const cut = reader.latestCompaction(draft.sessionID);
|
|
2620
|
+
if (saved && !this.editedAdmissions.has(draft.sessionID) && cut?.id === saved.proof.admissionID && replay.floor.after > saved.replay.floor.after && boundary && this.servedBaseline(draft) === boundary.summary) {
|
|
2621
|
+
const value = {
|
|
2622
|
+
...saved,
|
|
2623
|
+
replay: {
|
|
2624
|
+
...replay,
|
|
2625
|
+
controls: controlsThrough(replay.controls, reader, draft.sessionID, cut.seq - 1)
|
|
2626
|
+
},
|
|
2627
|
+
proof: {
|
|
2628
|
+
...saved.proof,
|
|
2629
|
+
historyDigest: historyDigest(reader, draft.sessionID, cut.seq - 1, replay.floor.after)
|
|
2630
|
+
}
|
|
2631
|
+
};
|
|
2632
|
+
const payload = encodeAdmissionV3(value);
|
|
2633
|
+
await this.admissions?.set(this.admissionKey(draft.sessionID), {
|
|
2634
|
+
payload,
|
|
2635
|
+
digest: foldDigest(payload)
|
|
2636
|
+
});
|
|
2637
|
+
}
|
|
2638
|
+
} catch (error) {
|
|
2639
|
+
this.report(draft.sessionID, `capture provenance update unavailable: ${String(error)}`);
|
|
2640
|
+
} finally {
|
|
2641
|
+
reader.close();
|
|
2642
|
+
}
|
|
2643
|
+
}
|
|
2089
2644
|
}
|
|
2090
2645
|
async canReplay(sessionID, _reader) {
|
|
2091
2646
|
return !this.unavailable.has(sessionID) && typeof await this.baseline(sessionID) === "string";
|
|
@@ -2101,20 +2656,62 @@ class NativeFoldReplay {
|
|
|
2101
2656
|
}
|
|
2102
2657
|
async supplyHeld(args) {
|
|
2103
2658
|
const { draft, reader, summary } = args;
|
|
2659
|
+
if (this.options.protocol === 3) {
|
|
2660
|
+
if (this.unprovenControls.has(draft.sessionID))
|
|
2661
|
+
return false;
|
|
2662
|
+
if (await this.admissions?.get(admissionKey(draft.sessionID)) && !await this.readV3(draft.sessionID))
|
|
2663
|
+
return false;
|
|
2664
|
+
const running = reader.latestRunningCompaction(draft.sessionID);
|
|
2665
|
+
const replay = await this.floorState(draft.sessionID, reader, undefined, undefined, true);
|
|
2666
|
+
if (!running || !replay || replay.blocked) {
|
|
2667
|
+
this.report(draft.sessionID, "fold refused: no usable host checkpoint boundary");
|
|
2668
|
+
return false;
|
|
2669
|
+
}
|
|
2670
|
+
const model = `${draft.model.providerID}/${draft.model.id}`;
|
|
2671
|
+
if (this.tail(draft.sessionID)?.model !== model)
|
|
2672
|
+
this.storage.replaceRows(draft.sessionID, reader.latestSequence(draft.sessionID), []);
|
|
2673
|
+
await this.retainReplay(draft.sessionID, replay, model, reader.latestSequence(draft.sessionID));
|
|
2674
|
+
await this.storage.supply(draft.sessionID, running.id, JSON.stringify({
|
|
2675
|
+
source: this.storage.sourceID,
|
|
2676
|
+
sessionID: draft.sessionID,
|
|
2677
|
+
admissionID: running.id,
|
|
2678
|
+
summary
|
|
2679
|
+
}));
|
|
2680
|
+
const value = {
|
|
2681
|
+
version: 3,
|
|
2682
|
+
replay,
|
|
2683
|
+
proof: {
|
|
2684
|
+
sourceDigest: foldDigest(reader.hostIdentity()),
|
|
2685
|
+
sessionID: draft.sessionID,
|
|
2686
|
+
admissionID: running.id,
|
|
2687
|
+
summaryDigest: foldDigest(summary),
|
|
2688
|
+
historyDigest: historyDigest(reader, draft.sessionID, running.seq - 1, replay.floor.after)
|
|
2689
|
+
}
|
|
2690
|
+
};
|
|
2691
|
+
const payload = encodeAdmissionV3(value);
|
|
2692
|
+
await this.admissions?.set(this.admissionKey(draft.sessionID), {
|
|
2693
|
+
payload,
|
|
2694
|
+
digest: foldDigest(payload)
|
|
2695
|
+
});
|
|
2696
|
+
return true;
|
|
2697
|
+
}
|
|
2104
2698
|
const tail = this.tail(draft.sessionID);
|
|
2105
2699
|
const running = reader.latestRunningCompaction(draft.sessionID);
|
|
2106
2700
|
const id = running?.id;
|
|
2107
|
-
|
|
2701
|
+
const model = `${draft.model.providerID}/${draft.model.id}`;
|
|
2702
|
+
if (!id || tail && tail.model !== model)
|
|
2108
2703
|
return false;
|
|
2109
2704
|
const through = reader.latestSequence(draft.sessionID);
|
|
2110
|
-
const after = this.dirty.has(draft.sessionID) ? -1 : tail
|
|
2111
|
-
const fresh = reader.range(draft.sessionID, after, through).filter(conversational);
|
|
2705
|
+
const after = this.dirty.has(draft.sessionID) ? -1 : tail?.sourceSeq ?? through;
|
|
2706
|
+
const fresh = tail ? reader.range(draft.sessionID, after, through).filter(conversational) : [];
|
|
2112
2707
|
const records = fresh.map((row) => this.record(row, this.rendered(row, draft.model)));
|
|
2113
2708
|
if (this.dirty.has(draft.sessionID))
|
|
2114
2709
|
this.storage.replaceRows(draft.sessionID, through, records);
|
|
2115
2710
|
await this.storage.saveTail(draft.sessionID, JSON.stringify({
|
|
2116
2711
|
...tail,
|
|
2117
|
-
|
|
2712
|
+
model,
|
|
2713
|
+
baseline: tail?.baseline ?? summary,
|
|
2714
|
+
sourceSeq: Math.max(tail?.sourceSeq ?? through, ...fresh.map((row) => row.seq))
|
|
2118
2715
|
}), records);
|
|
2119
2716
|
this.dirty.delete(draft.sessionID);
|
|
2120
2717
|
this.metadata.delete(draft.sessionID);
|
|
@@ -2145,13 +2742,36 @@ class NativeFoldReplay {
|
|
|
2145
2742
|
return true;
|
|
2146
2743
|
}
|
|
2147
2744
|
async restore(sessionID, cut, model, options = {}) {
|
|
2745
|
+
let replay;
|
|
2746
|
+
let controls = [];
|
|
2747
|
+
if (this.options.protocol === 3) {
|
|
2748
|
+
const reader = this.openReader(sessionID);
|
|
2749
|
+
try {
|
|
2750
|
+
replay = await this.floorState(sessionID, reader);
|
|
2751
|
+
if (replay)
|
|
2752
|
+
controls = controlsThrough(replay.controls, reader, sessionID, cut.seq - 1);
|
|
2753
|
+
} finally {
|
|
2754
|
+
reader.close();
|
|
2755
|
+
}
|
|
2756
|
+
if (!replay) {
|
|
2757
|
+
this.report(sessionID, "replay refused: missing usable checkpoint boundary");
|
|
2758
|
+
throw new NativeReplayUnavailable("Host checkpoint replay boundary is unavailable");
|
|
2759
|
+
}
|
|
2760
|
+
options = { ...options, bounded: false, after: replay.floor.after };
|
|
2761
|
+
}
|
|
2148
2762
|
const release = this.storage.hold(sessionID);
|
|
2763
|
+
let result;
|
|
2149
2764
|
try {
|
|
2150
|
-
|
|
2765
|
+
result = await this.restoreHeld(sessionID, cut, model, options);
|
|
2151
2766
|
} finally {
|
|
2152
2767
|
this.account(sessionID);
|
|
2153
2768
|
release();
|
|
2154
2769
|
}
|
|
2770
|
+
if (replay) {
|
|
2771
|
+
await this.retainReplay(sessionID, replay, model, cut.seq - 1);
|
|
2772
|
+
return result && insertControls(result, controls, nativeRowID);
|
|
2773
|
+
}
|
|
2774
|
+
return result;
|
|
2155
2775
|
}
|
|
2156
2776
|
async restoreHeld(sessionID, cut, model, options) {
|
|
2157
2777
|
if (!isLocalCheckpoint(cut))
|
|
@@ -2161,23 +2781,24 @@ class NativeFoldReplay {
|
|
|
2161
2781
|
id: model.slice(model.indexOf("/") + 1)
|
|
2162
2782
|
};
|
|
2163
2783
|
const tail = this.tail(sessionID);
|
|
2164
|
-
if (tail && tail.model !== model)
|
|
2784
|
+
if (tail && tail.model !== model && !(this.options.protocol === 3 && tail.model === ""))
|
|
2165
2785
|
this.invalidate(sessionID);
|
|
2166
2786
|
let after = options.after ?? -1;
|
|
2167
|
-
if (options.bounded && options.after === undefined && !this.changed.has(sessionID)) {
|
|
2168
|
-
const state = getOrCreateSessionMeta(this.storage.db, sessionID);
|
|
2169
|
-
const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
|
|
2170
|
-
const boundary = this.storage.db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(sessionID)?.id;
|
|
2171
|
-
if (max.id <= (state.cachedM0MaxMutationId ?? 0) && boundary)
|
|
2172
|
-
after = this.storage.sequenceForID(sessionID, boundary) ?? -1;
|
|
2173
|
-
}
|
|
2174
|
-
const through = cut.seq - 1;
|
|
2175
2787
|
let reader;
|
|
2176
2788
|
try {
|
|
2789
|
+
if (options.bounded && options.after === undefined && !this.changed.has(sessionID)) {
|
|
2790
|
+
const state = getOrCreateSessionMeta(this.storage.db, sessionID);
|
|
2791
|
+
const max = this.storage.db.prepare("SELECT COALESCE(MAX(id),0) AS id FROM m0_mutation_log WHERE session_id=?").get(sessionID);
|
|
2792
|
+
const boundary = this.storage.db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(sessionID)?.id;
|
|
2793
|
+
if (max.id <= (state.cachedM0MaxMutationId ?? 0) && boundary) {
|
|
2794
|
+
after = this.storage.sequenceForID(sessionID, boundary) ?? (reader = this.openReader(sessionID)).sequenceForId(sessionID, boundary) ?? -1;
|
|
2795
|
+
}
|
|
2796
|
+
}
|
|
2797
|
+
const through = cut.seq - 1;
|
|
2177
2798
|
let metadata = this.metadata.get(sessionID);
|
|
2178
2799
|
if (!metadata || (this.metadataThrough.get(sessionID) ?? -1) < through) {
|
|
2179
|
-
reader
|
|
2180
|
-
metadata = reader.rowStampsThrough(sessionID, through).filter(conversational);
|
|
2800
|
+
reader ??= this.openReader(sessionID);
|
|
2801
|
+
metadata = reader.rowStampsThrough(sessionID, through, this.options.protocol === 3 ? after : undefined).filter(conversational);
|
|
2181
2802
|
this.metadata.set(sessionID, metadata);
|
|
2182
2803
|
this.metadataThrough.set(sessionID, through);
|
|
2183
2804
|
}
|
|
@@ -2213,26 +2834,34 @@ class NativeFoldReplay {
|
|
|
2213
2834
|
async restoreRead(sessionID, cut, model) {
|
|
2214
2835
|
const reader = this.openReader(sessionID);
|
|
2215
2836
|
try {
|
|
2216
|
-
|
|
2837
|
+
const replay = this.options.protocol === 3 ? await this.floorState(sessionID, reader) : undefined;
|
|
2838
|
+
if (this.options.protocol === 3 && !replay) {
|
|
2839
|
+
this.report(sessionID, "replay refused: missing usable checkpoint boundary");
|
|
2840
|
+
throw new NativeReplayUnavailable("Host checkpoint replay boundary is unavailable");
|
|
2841
|
+
}
|
|
2842
|
+
const messages = reader.range(sessionID, replay?.floor.after ?? -1, cut.seq - 1).filter(conversational).flatMap((row) => {
|
|
2217
2843
|
const messages = this.rendered(row, model);
|
|
2218
2844
|
for (const message of messages)
|
|
2219
2845
|
coordinates.set(message, row.id);
|
|
2220
2846
|
return messages;
|
|
2221
2847
|
});
|
|
2848
|
+
return replay ? insertControls(messages, controlsThrough(replay.controls, reader, sessionID, cut.seq - 1), nativeRowID) : messages;
|
|
2222
2849
|
} finally {
|
|
2223
2850
|
reader.close();
|
|
2224
2851
|
}
|
|
2225
2852
|
}
|
|
2226
2853
|
sourceChanged(sessionID) {
|
|
2227
|
-
return this.changed.has(sessionID);
|
|
2854
|
+
return this.changed.has(sessionID) || this.editedAdmissions.has(sessionID);
|
|
2228
2855
|
}
|
|
2229
2856
|
needsHeadRebuild(sessionID) {
|
|
2230
|
-
return this.staleHeads.has(sessionID);
|
|
2857
|
+
return this.staleHeads.has(sessionID) || this.editedAdmissions.has(sessionID);
|
|
2231
2858
|
}
|
|
2232
2859
|
clear(sessionID) {
|
|
2233
2860
|
this.sources.delete(sessionID);
|
|
2234
2861
|
this.metadata.delete(sessionID);
|
|
2235
2862
|
this.metadataThrough.delete(sessionID);
|
|
2863
|
+
this.metadataAfter.delete(sessionID);
|
|
2864
|
+
this.metadataAfter.delete(sessionID);
|
|
2236
2865
|
this.loaded.delete(sessionID);
|
|
2237
2866
|
this.unavailable.delete(sessionID);
|
|
2238
2867
|
this.dirty.delete(sessionID);
|
|
@@ -2240,6 +2869,11 @@ class NativeFoldReplay {
|
|
|
2240
2869
|
this.staleHeads.delete(sessionID);
|
|
2241
2870
|
}
|
|
2242
2871
|
async forget(sessionID) {
|
|
2872
|
+
if (this.stampMRU?.sessionID === sessionID)
|
|
2873
|
+
this.stampMRU = undefined;
|
|
2874
|
+
this.unprovenControls.delete(sessionID);
|
|
2875
|
+
this.cancelLegacyUpgrade(sessionID);
|
|
2876
|
+
this.cancelEditedAdmission(sessionID);
|
|
2243
2877
|
if (this.admissions)
|
|
2244
2878
|
await forgetNativeFoldProvenance(this.admissions, sessionID);
|
|
2245
2879
|
await this.storage.forget(sessionID);
|
|
@@ -2258,9 +2892,9 @@ class HostFoldPolicy {
|
|
|
2258
2892
|
owned(sessionID, cut, id) {
|
|
2259
2893
|
return cut.id === id && isAdmittedLocalCheckpoint(this.deps.storage, sessionID, cut);
|
|
2260
2894
|
}
|
|
2261
|
-
async idle(sessionID) {
|
|
2895
|
+
async idle(sessionID, eligible = () => true) {
|
|
2262
2896
|
const { storage, session, threshold } = this.deps;
|
|
2263
|
-
if (!Number.isSafeInteger(threshold) || threshold <= 0 || typeof session.compact !== "function" || this.active.has(sessionID))
|
|
2897
|
+
if (!Number.isSafeInteger(threshold) || threshold <= 0 || typeof session.compact !== "function" || !eligible() || this.active.has(sessionID))
|
|
2264
2898
|
return;
|
|
2265
2899
|
this.active.add(sessionID);
|
|
2266
2900
|
const now = this.deps.now ?? Date.now;
|
|
@@ -2279,8 +2913,11 @@ class HostFoldPolicy {
|
|
|
2279
2913
|
}
|
|
2280
2914
|
const after = cut?.seq ?? -1;
|
|
2281
2915
|
const before = reader.storedRowsAfter(sessionID, after);
|
|
2282
|
-
if (before < threshold
|
|
2916
|
+
if (before < threshold)
|
|
2917
|
+
return;
|
|
2918
|
+
if (this.deps.canFold && !await this.deps.canFold(sessionID, reader))
|
|
2283
2919
|
return;
|
|
2920
|
+
const capture = await this.deps.canReplay(sessionID, reader);
|
|
2284
2921
|
const retry = old?.after === after ? old.attempt + (previous?.status === "failed" || previous?.status === "coalesced" ? 1 : 0) : 0;
|
|
2285
2922
|
const id = old?.after === after && previous?.status === "pending" ? old.id : `msg_mc_fold_${foldDigest(`${storage.sourceID}/${sessionID}/${after}/${retry}`).slice(0, 24)}`;
|
|
2286
2923
|
attempt = {
|
|
@@ -2289,7 +2926,8 @@ class HostFoldPolicy {
|
|
|
2289
2926
|
watermark: reader.latestSequence(sessionID),
|
|
2290
2927
|
attempt: retry,
|
|
2291
2928
|
id,
|
|
2292
|
-
started: now()
|
|
2929
|
+
started: now(),
|
|
2930
|
+
capture
|
|
2293
2931
|
};
|
|
2294
2932
|
claimed = await storage.claim(sessionID, id, JSON.stringify(attempt), this.owner, now());
|
|
2295
2933
|
if (!claimed)
|
|
@@ -2297,6 +2935,10 @@ class HostFoldPolicy {
|
|
|
2297
2935
|
} finally {
|
|
2298
2936
|
reader.close();
|
|
2299
2937
|
}
|
|
2938
|
+
if (!eligible()) {
|
|
2939
|
+
await storage.finish(sessionID, attempt.id, this.owner, "coalesced", now());
|
|
2940
|
+
return;
|
|
2941
|
+
}
|
|
2300
2942
|
const admitted = await session.compact({
|
|
2301
2943
|
sessionID,
|
|
2302
2944
|
id: attempt.id,
|
|
@@ -2313,7 +2955,7 @@ class HostFoldPolicy {
|
|
|
2313
2955
|
}
|
|
2314
2956
|
const after = settled.storedRowsAfter(sessionID, cut.seq);
|
|
2315
2957
|
if (await storage.finish(sessionID, attempt.id, this.owner, "completed", now()))
|
|
2316
|
-
this.deps.log(sessionID, `v2 host fold: rows_before=${attempt.before} rows_after=${after} duration_ms=${now() - attempt.started} reason=row_threshold id=${cut.id} status=completed`);
|
|
2958
|
+
this.deps.log(sessionID, `v2 host fold: rows_before=${attempt.before} rows_after=${after} duration_ms=${now() - attempt.started} reason=row_threshold id=${cut.id} capture=${attempt.capture ? "present" : "absent"} status=completed`);
|
|
2317
2959
|
} finally {
|
|
2318
2960
|
settled.close();
|
|
2319
2961
|
}
|
|
@@ -2336,7 +2978,7 @@ class HostFoldPolicy {
|
|
|
2336
2978
|
}
|
|
2337
2979
|
|
|
2338
2980
|
// src/v2/fork-inheritance.ts
|
|
2339
|
-
var RAW_TYPES = new Set(
|
|
2981
|
+
var RAW_TYPES = new Set(RAW_MESSAGE_TYPES2);
|
|
2340
2982
|
function forkBoundarySeq(origin, sequenceForId) {
|
|
2341
2983
|
const seq = sequenceForId(origin.parentSessionID, origin.boundary.messageID);
|
|
2342
2984
|
if (seq === undefined)
|
|
@@ -3801,7 +4443,7 @@ class V2RetrospectiveRawProvider {
|
|
|
3801
4443
|
contextDb;
|
|
3802
4444
|
openReader;
|
|
3803
4445
|
reader;
|
|
3804
|
-
constructor(contextDb, openReader = () => new
|
|
4446
|
+
constructor(contextDb, openReader = () => new V2StoreReader2(gaDatabasePath2(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"))) {
|
|
3805
4447
|
this.contextDb = contextDb;
|
|
3806
4448
|
this.openReader = openReader;
|
|
3807
4449
|
}
|
|
@@ -4002,7 +4644,7 @@ function startDreamTrigger(context, args) {
|
|
|
4002
4644
|
if (!db)
|
|
4003
4645
|
continue;
|
|
4004
4646
|
try {
|
|
4005
|
-
const reader = args.openReader?.() ?? new
|
|
4647
|
+
const reader = args.openReader?.() ?? new V2StoreReader2(gaDatabasePath2(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
|
|
4006
4648
|
try {
|
|
4007
4649
|
const activity = reader.rootSessionActivity([event.data.sessionID]).get(event.data.sessionID);
|
|
4008
4650
|
if (activity !== undefined)
|
|
@@ -4206,7 +4848,7 @@ function hiddenTerminalError(event) {
|
|
|
4206
4848
|
|
|
4207
4849
|
// src/v2/hooks/lkg-system.ts
|
|
4208
4850
|
import { createHash as createHash2 } from "node:crypto";
|
|
4209
|
-
function
|
|
4851
|
+
function identity2(slot) {
|
|
4210
4852
|
return createHash2("sha256").update(JSON.stringify({
|
|
4211
4853
|
capturedAt: slot.capturedAt,
|
|
4212
4854
|
captureSequence: slot.captureSequence,
|
|
@@ -4222,7 +4864,7 @@ class V2LkgSystemReplay {
|
|
|
4222
4864
|
systems = new BoundedSessionMap(1000);
|
|
4223
4865
|
capture(sessionId, slot, input, served, head) {
|
|
4224
4866
|
this.systems.set(sessionId, {
|
|
4225
|
-
slot:
|
|
4867
|
+
slot: identity2(slot),
|
|
4226
4868
|
input: hostInputKey(input),
|
|
4227
4869
|
served: structuredClone(served),
|
|
4228
4870
|
head: head ? structuredClone(head) : null
|
|
@@ -4230,7 +4872,7 @@ class V2LkgSystemReplay {
|
|
|
4230
4872
|
}
|
|
4231
4873
|
restore(sessionId, slot, input, target) {
|
|
4232
4874
|
const saved = this.systems.get(sessionId);
|
|
4233
|
-
if (!slot || !saved || saved.slot !==
|
|
4875
|
+
if (!slot || !saved || saved.slot !== identity2(slot) || saved.input !== hostInputKey(input))
|
|
4234
4876
|
return;
|
|
4235
4877
|
target.splice(0, target.length, ...structuredClone(saved.served));
|
|
4236
4878
|
return { head: saved.head ? structuredClone(saved.head) : null };
|
|
@@ -4286,6 +4928,112 @@ async function warmModelLimitCacheFromCatalog(context, options = {}) {
|
|
|
4286
4928
|
}
|
|
4287
4929
|
}
|
|
4288
4930
|
|
|
4931
|
+
// src/v2/hooks/overflow-recovery.ts
|
|
4932
|
+
function isRateLimit(error) {
|
|
4933
|
+
const pending = [error];
|
|
4934
|
+
const seen = new Set;
|
|
4935
|
+
for (let i = 0;pending.length && i < 16; i++) {
|
|
4936
|
+
const value = pending.shift();
|
|
4937
|
+
if (seen.has(value))
|
|
4938
|
+
continue;
|
|
4939
|
+
seen.add(value);
|
|
4940
|
+
if (typeof value === "string") {
|
|
4941
|
+
try {
|
|
4942
|
+
pending.push(JSON.parse(value));
|
|
4943
|
+
} catch {}
|
|
4944
|
+
} else if (value && typeof value === "object") {
|
|
4945
|
+
const p = value;
|
|
4946
|
+
if (p.status === 429 || p.statusCode === 429 || [p.type, p.name, p.code, p._tag].some((tag) => typeof tag === "string" && /rate[_ .-]?limit|throttl/i.test(tag)))
|
|
4947
|
+
return true;
|
|
4948
|
+
pending.push(p.data, p.error, p.cause);
|
|
4949
|
+
}
|
|
4950
|
+
}
|
|
4951
|
+
return false;
|
|
4952
|
+
}
|
|
4953
|
+
|
|
4954
|
+
class V2OverflowRecovery {
|
|
4955
|
+
deps;
|
|
4956
|
+
requests = new BoundedSessionMap(1000);
|
|
4957
|
+
constructor(deps) {
|
|
4958
|
+
this.deps = deps;
|
|
4959
|
+
}
|
|
4960
|
+
begin(input) {
|
|
4961
|
+
if (input.kind !== "primary" || this.deps.isHidden(input.sessionID))
|
|
4962
|
+
return;
|
|
4963
|
+
const prior = this.requests.get(input.sessionID);
|
|
4964
|
+
if (input.assistantMessageID && prior?.assistantMessageID === input.assistantMessageID && prior.model.providerID === input.model.providerID && prior.model.id === input.model.id)
|
|
4965
|
+
return;
|
|
4966
|
+
this.requests.set(input.sessionID, {
|
|
4967
|
+
model: { ...input.model },
|
|
4968
|
+
assistantMessageID: input.assistantMessageID,
|
|
4969
|
+
observed: false
|
|
4970
|
+
});
|
|
4971
|
+
}
|
|
4972
|
+
forget(sessionID) {
|
|
4973
|
+
this.requests.delete(sessionID);
|
|
4974
|
+
}
|
|
4975
|
+
observeTerminal(event, readStep) {
|
|
4976
|
+
if (!["session.step.failed", "session.execution.failed", "session.error"].includes(event.type ?? ""))
|
|
4977
|
+
return;
|
|
4978
|
+
const sessionID = event.data?.sessionID;
|
|
4979
|
+
if (!sessionID || this.deps.isHidden(sessionID))
|
|
4980
|
+
return;
|
|
4981
|
+
const error = event.type === "session.step.failed" ? event.data?.error : hiddenTerminalError(event);
|
|
4982
|
+
if (error === undefined)
|
|
4983
|
+
return;
|
|
4984
|
+
const prior = this.requests.get(sessionID);
|
|
4985
|
+
if (prior?.observed || isRateLimit(error) || !detectOverflow(error).isOverflow)
|
|
4986
|
+
return;
|
|
4987
|
+
const messageID = event.data?.assistantMessageID;
|
|
4988
|
+
const step = readStep(sessionID, messageID);
|
|
4989
|
+
if (!step)
|
|
4990
|
+
return;
|
|
4991
|
+
if (!messageID && (!step?.error || !detectOverflow(step.error).isOverflow))
|
|
4992
|
+
return;
|
|
4993
|
+
if (!prior && step.model)
|
|
4994
|
+
this.begin({
|
|
4995
|
+
sessionID,
|
|
4996
|
+
kind: "primary",
|
|
4997
|
+
model: step.model,
|
|
4998
|
+
assistantMessageID: step.id
|
|
4999
|
+
});
|
|
5000
|
+
const request = this.requests.get(sessionID);
|
|
5001
|
+
if (!request)
|
|
5002
|
+
return;
|
|
5003
|
+
this.observe({
|
|
5004
|
+
sessionID,
|
|
5005
|
+
error,
|
|
5006
|
+
model: step?.model ?? request.model,
|
|
5007
|
+
assistantMessageID: messageID ?? step?.id
|
|
5008
|
+
});
|
|
5009
|
+
}
|
|
5010
|
+
observe(input) {
|
|
5011
|
+
if (!this.requests.has(input.sessionID) && input.kind === "primary")
|
|
5012
|
+
this.begin({ ...input, kind: "primary" });
|
|
5013
|
+
const request = this.requests.get(input.sessionID);
|
|
5014
|
+
if (!request || request.observed || this.deps.isHidden(input.sessionID) || request.model.providerID !== input.model.providerID || request.model.id !== input.model.id || input.assistantMessageID && request.assistantMessageID && input.assistantMessageID !== request.assistantMessageID)
|
|
5015
|
+
return;
|
|
5016
|
+
if (input.status === 429 || isRateLimit(input.error))
|
|
5017
|
+
return;
|
|
5018
|
+
const detection = detectOverflow(input.error);
|
|
5019
|
+
if (!detection.isOverflow)
|
|
5020
|
+
return;
|
|
5021
|
+
const db = this.deps.database();
|
|
5022
|
+
if (!db)
|
|
5023
|
+
return;
|
|
5024
|
+
const modelKey = `${input.model.providerID}/${input.model.id}`;
|
|
5025
|
+
if (this.deps.compactionOff) {
|
|
5026
|
+
if (detection.reportedLimit)
|
|
5027
|
+
recordDetectedContextLimit(db, input.sessionID, detection.reportedLimit, modelKey, detection.reportedLimitProvenance);
|
|
5028
|
+
} else {
|
|
5029
|
+
recordOverflowDetected(db, input.sessionID, detection.reportedLimit, modelKey, "provider_overflow", detection.reportedLimitProvenance, detection.reportedInputTokens);
|
|
5030
|
+
}
|
|
5031
|
+
request.observed = true;
|
|
5032
|
+
if (!this.deps.compactionOff && detection.reportedInputTokens)
|
|
5033
|
+
this.deps.onInputTokens?.(input.sessionID, detection.reportedInputTokens, getOverflowState(db, input.sessionID, modelKey).detectedContextLimit);
|
|
5034
|
+
}
|
|
5035
|
+
}
|
|
5036
|
+
|
|
4289
5037
|
// src/v2/hooks/refusal.ts
|
|
4290
5038
|
class V2ContextRefusal extends Error {
|
|
4291
5039
|
constructor(message = "Context full — /ctx-flush or /clear to continue.", options) {
|
|
@@ -4519,257 +5267,6 @@ async function probeV2StorageAtBoot(storage, timeoutMs = 15000) {
|
|
|
4519
5267
|
}
|
|
4520
5268
|
}
|
|
4521
5269
|
|
|
4522
|
-
// src/v2/hooks/store.ts
|
|
4523
|
-
var rawMessageTypes = new Set(RAW_MESSAGE_TYPES);
|
|
4524
|
-
var isRawRow = (row) => rawMessageTypes.has(row.type);
|
|
4525
|
-
var NO_MODEL = { providerID: "", id: "" };
|
|
4526
|
-
function hostServesRowById(row) {
|
|
4527
|
-
return isRawRow(row) && restoreRow(row, NO_MODEL).some((message) => message.id === row.id);
|
|
4528
|
-
}
|
|
4529
|
-
function projectRawMessages(rows, ordinalFor) {
|
|
4530
|
-
return rows.filter(isRawRow).map((row, index) => {
|
|
4531
|
-
const message = {
|
|
4532
|
-
id: row.id,
|
|
4533
|
-
ordinal: ordinalFor(row, index),
|
|
4534
|
-
role: row.type === "assistant" ? "assistant" : row.type === "system" ? "system" : "user",
|
|
4535
|
-
createdAt: row.time_created ?? row.data.time?.created,
|
|
4536
|
-
parts: row.type === "assistant" ? (row.data.content ?? []).map((part) => {
|
|
4537
|
-
if (part.type !== "tool")
|
|
4538
|
-
return { ...part };
|
|
4539
|
-
const state = part.state;
|
|
4540
|
-
const content = state.content;
|
|
4541
|
-
return {
|
|
4542
|
-
type: "tool",
|
|
4543
|
-
tool: part.name,
|
|
4544
|
-
callID: part.id,
|
|
4545
|
-
state: {
|
|
4546
|
-
...state,
|
|
4547
|
-
output: state.status === "error" ? toolStateContent(state) : content?.filter((p) => p.type === "text").map((p) => p.text).join(`
|
|
4548
|
-
`) ?? ""
|
|
4549
|
-
}
|
|
4550
|
-
};
|
|
4551
|
-
}) : [{ type: "text", text: row.data.text ?? "" }]
|
|
4552
|
-
};
|
|
4553
|
-
Object.defineProperty(message, "storeType", { value: row.type, enumerable: false });
|
|
4554
|
-
if (!hostServesRowById(row))
|
|
4555
|
-
markHostUnservedRow(message);
|
|
4556
|
-
return message;
|
|
4557
|
-
});
|
|
4558
|
-
}
|
|
4559
|
-
function rawMessages(rows, history = rows) {
|
|
4560
|
-
const ordinals = new Map(history.filter(isRawRow).map((row, index) => [row.id, index + 1]));
|
|
4561
|
-
return projectRawMessages(rows, (row) => {
|
|
4562
|
-
return ordinals.get(row.id) ?? 0;
|
|
4563
|
-
});
|
|
4564
|
-
}
|
|
4565
|
-
function rawMessagePage(rows, afterOrdinal) {
|
|
4566
|
-
return projectRawMessages(rows, (_row, index) => afterOrdinal + index + 1);
|
|
4567
|
-
}
|
|
4568
|
-
var SERVED_BOUNDARY_PAGE = 50;
|
|
4569
|
-
function servedBoundaryRow(reader, sessionID, messageID) {
|
|
4570
|
-
const boundary = reader.messageById(sessionID, messageID);
|
|
4571
|
-
if (!boundary)
|
|
4572
|
-
return null;
|
|
4573
|
-
if (hostServesRowById(boundary))
|
|
4574
|
-
return boundary;
|
|
4575
|
-
let through = boundary.seq - 1;
|
|
4576
|
-
for (;; ) {
|
|
4577
|
-
const rows = reader.rawRowsThrough(sessionID, through, SERVED_BOUNDARY_PAGE);
|
|
4578
|
-
const served = rows.find(hostServesRowById);
|
|
4579
|
-
if (served)
|
|
4580
|
-
return served;
|
|
4581
|
-
const oldest = rows.at(-1);
|
|
4582
|
-
if (rows.length < SERVED_BOUNDARY_PAGE || !oldest)
|
|
4583
|
-
return null;
|
|
4584
|
-
through = oldest.seq - 1;
|
|
4585
|
-
}
|
|
4586
|
-
}
|
|
4587
|
-
function resolveV2BoundaryUserMessage(reader, sessionID, endMessageID) {
|
|
4588
|
-
const end = reader.messageById(sessionID, endMessageID);
|
|
4589
|
-
if (!end || !isRawRow(end))
|
|
4590
|
-
return null;
|
|
4591
|
-
let through = end.seq;
|
|
4592
|
-
for (;; ) {
|
|
4593
|
-
const rows = reader.rawRowsThrough(sessionID, through, SERVED_BOUNDARY_PAGE);
|
|
4594
|
-
const user = rows.find((row) => row.type !== "assistant");
|
|
4595
|
-
if (user)
|
|
4596
|
-
return rawMessagePage([user], 0)[0] ?? null;
|
|
4597
|
-
const oldest = rows.at(-1);
|
|
4598
|
-
if (rows.length < SERVED_BOUNDARY_PAGE || !oldest)
|
|
4599
|
-
return null;
|
|
4600
|
-
through = oldest.seq - 1;
|
|
4601
|
-
}
|
|
4602
|
-
}
|
|
4603
|
-
function readAllV2RawMessagesForConversion(openReader, sessionID) {
|
|
4604
|
-
const reader = openReader();
|
|
4605
|
-
try {
|
|
4606
|
-
return rawMessages(reader.history(sessionID));
|
|
4607
|
-
} finally {
|
|
4608
|
-
reader.close();
|
|
4609
|
-
}
|
|
4610
|
-
}
|
|
4611
|
-
var CONVERSION_PAGE_ROWS = 1000;
|
|
4612
|
-
function* readV2RawMessagePagesForConversion(openReader, sessionID, pageRows = CONVERSION_PAGE_ROWS) {
|
|
4613
|
-
const reader = openReader();
|
|
4614
|
-
try {
|
|
4615
|
-
let after = -1;
|
|
4616
|
-
let ordinal = 0;
|
|
4617
|
-
for (;; ) {
|
|
4618
|
-
const page = reader.page(sessionID, { after, limit: pageRows });
|
|
4619
|
-
const messages = rawMessagePage(page.rows, ordinal);
|
|
4620
|
-
ordinal += messages.length;
|
|
4621
|
-
if (messages.length > 0)
|
|
4622
|
-
yield messages;
|
|
4623
|
-
if (page.rows.length < pageRows || page.cursor === undefined)
|
|
4624
|
-
return;
|
|
4625
|
-
after = page.cursor;
|
|
4626
|
-
}
|
|
4627
|
-
} finally {
|
|
4628
|
-
reader.close();
|
|
4629
|
-
}
|
|
4630
|
-
}
|
|
4631
|
-
function createV2RawMessageReader(openReader) {
|
|
4632
|
-
const servedBoundaryCache = new Map;
|
|
4633
|
-
return {
|
|
4634
|
-
getRevision: (sessionID) => {
|
|
4635
|
-
const reader = openReader();
|
|
4636
|
-
try {
|
|
4637
|
-
return reader.latestSequence(sessionID);
|
|
4638
|
-
} finally {
|
|
4639
|
-
reader.close();
|
|
4640
|
-
}
|
|
4641
|
-
},
|
|
4642
|
-
getCountAfterRevision: (sessionID, after, through) => {
|
|
4643
|
-
const reader = openReader();
|
|
4644
|
-
try {
|
|
4645
|
-
return reader.messageCountAfterSequence(sessionID, after, through);
|
|
4646
|
-
} finally {
|
|
4647
|
-
reader.close();
|
|
4648
|
-
}
|
|
4649
|
-
},
|
|
4650
|
-
readPage: (sessionID, afterOrdinal, limit, finalWatermark, after) => {
|
|
4651
|
-
const reader = openReader();
|
|
4652
|
-
try {
|
|
4653
|
-
return rawMessagePage(reader.messagePage(sessionID, afterOrdinal, limit, finalWatermark, after), afterOrdinal);
|
|
4654
|
-
} finally {
|
|
4655
|
-
reader.close();
|
|
4656
|
-
}
|
|
4657
|
-
},
|
|
4658
|
-
findById: (sessionID, messageID) => {
|
|
4659
|
-
const reader = openReader();
|
|
4660
|
-
try {
|
|
4661
|
-
const ordinal = reader.messageOrdinalById(sessionID, messageID);
|
|
4662
|
-
const row = reader.messageById(sessionID, messageID);
|
|
4663
|
-
if (ordinal === null || row === null)
|
|
4664
|
-
return null;
|
|
4665
|
-
return rawMessagePage([row], ordinal - 1)[0] ?? null;
|
|
4666
|
-
} finally {
|
|
4667
|
-
reader.close();
|
|
4668
|
-
}
|
|
4669
|
-
},
|
|
4670
|
-
findPartsById: (sessionID, messageID) => {
|
|
4671
|
-
const reader = openReader();
|
|
4672
|
-
try {
|
|
4673
|
-
const row = reader.messageById(sessionID, messageID);
|
|
4674
|
-
return row ? rawMessagePage([row], 0)[0] ?? null : null;
|
|
4675
|
-
} finally {
|
|
4676
|
-
reader.close();
|
|
4677
|
-
}
|
|
4678
|
-
},
|
|
4679
|
-
hasById: (sessionID, messageID) => {
|
|
4680
|
-
const reader = openReader();
|
|
4681
|
-
try {
|
|
4682
|
-
return reader.messageExistsById(sessionID, messageID);
|
|
4683
|
-
} finally {
|
|
4684
|
-
reader.close();
|
|
4685
|
-
}
|
|
4686
|
-
},
|
|
4687
|
-
ordinalOf: (sessionID, messageID) => {
|
|
4688
|
-
const reader = openReader();
|
|
4689
|
-
try {
|
|
4690
|
-
return reader.messageOrdinalById(sessionID, messageID);
|
|
4691
|
-
} finally {
|
|
4692
|
-
reader.close();
|
|
4693
|
-
}
|
|
4694
|
-
},
|
|
4695
|
-
orderOf: (sessionID, messageID) => {
|
|
4696
|
-
const reader = openReader();
|
|
4697
|
-
try {
|
|
4698
|
-
return reader.sequenceForId(sessionID, messageID) ?? null;
|
|
4699
|
-
} finally {
|
|
4700
|
-
reader.close();
|
|
4701
|
-
}
|
|
4702
|
-
},
|
|
4703
|
-
ordinalMapForRange: (sessionID, fromOrdinal, toOrdinal) => {
|
|
4704
|
-
const reader = openReader();
|
|
4705
|
-
try {
|
|
4706
|
-
return reader.messageIdOrdinals(sessionID, fromOrdinal, toOrdinal);
|
|
4707
|
-
} finally {
|
|
4708
|
-
reader.close();
|
|
4709
|
-
}
|
|
4710
|
-
},
|
|
4711
|
-
readOrdinalPage: (sessionID, after, limit) => {
|
|
4712
|
-
const reader = openReader();
|
|
4713
|
-
try {
|
|
4714
|
-
return reader.messageOrdinalPage(sessionID, after, limit);
|
|
4715
|
-
} finally {
|
|
4716
|
-
reader.close();
|
|
4717
|
-
}
|
|
4718
|
-
},
|
|
4719
|
-
getCount: (sessionID) => {
|
|
4720
|
-
const reader = openReader();
|
|
4721
|
-
try {
|
|
4722
|
-
return reader.messageCount(sessionID);
|
|
4723
|
-
} finally {
|
|
4724
|
-
reader.close();
|
|
4725
|
-
}
|
|
4726
|
-
},
|
|
4727
|
-
getStoredCount: (sessionID) => {
|
|
4728
|
-
const reader = openReader();
|
|
4729
|
-
try {
|
|
4730
|
-
return reader.storedMessageCount(sessionID);
|
|
4731
|
-
} finally {
|
|
4732
|
-
reader.close();
|
|
4733
|
-
}
|
|
4734
|
-
},
|
|
4735
|
-
servedBoundaryIdOf: (sessionID, messageID) => {
|
|
4736
|
-
const key = `${sessionID}\x00${messageID}`;
|
|
4737
|
-
if (servedBoundaryCache.has(key))
|
|
4738
|
-
return servedBoundaryCache.get(key) ?? null;
|
|
4739
|
-
const reader = openReader();
|
|
4740
|
-
try {
|
|
4741
|
-
const served = servedBoundaryRow(reader, sessionID, messageID)?.id ?? null;
|
|
4742
|
-
if (servedBoundaryCache.size >= 1000)
|
|
4743
|
-
servedBoundaryCache.clear();
|
|
4744
|
-
if (served !== null)
|
|
4745
|
-
servedBoundaryCache.set(key, served);
|
|
4746
|
-
return served;
|
|
4747
|
-
} finally {
|
|
4748
|
-
reader.close();
|
|
4749
|
-
}
|
|
4750
|
-
}
|
|
4751
|
-
};
|
|
4752
|
-
}
|
|
4753
|
-
function createV2RawMessageProvider(reader, sessionID) {
|
|
4754
|
-
return {
|
|
4755
|
-
readMessagePage: (afterOrdinal, limit, finalWatermark, after) => reader.readPage(sessionID, afterOrdinal, limit, finalWatermark, after),
|
|
4756
|
-
readMessageById: (messageID) => reader.findById(sessionID, messageID),
|
|
4757
|
-
readMessagePartsById: (messageID) => reader.findPartsById(sessionID, messageID),
|
|
4758
|
-
hasMessageById: (messageID) => reader.hasById(sessionID, messageID),
|
|
4759
|
-
readMessageOrdinalById: (messageID) => reader.ordinalOf(sessionID, messageID),
|
|
4760
|
-
...reader.orderOf ? {
|
|
4761
|
-
readMessageOrderById: (messageID) => reader.orderOf?.(sessionID, messageID) ?? null
|
|
4762
|
-
} : {},
|
|
4763
|
-
readMessageIdOrdinalsForRange: (fromOrdinal, toOrdinal) => reader.ordinalMapForRange(sessionID, fromOrdinal, toOrdinal),
|
|
4764
|
-
readMessageOrdinalPage: (after, limit) => reader.readOrdinalPage(sessionID, after, limit),
|
|
4765
|
-
getMessageCount: () => reader.getCount(sessionID),
|
|
4766
|
-
getStoredMessageCount: () => reader.getStoredCount(sessionID),
|
|
4767
|
-
...reader.servedBoundaryIdOf ? {
|
|
4768
|
-
readServedBoundaryId: (messageID) => reader.servedBoundaryIdOf?.(sessionID, messageID) ?? null
|
|
4769
|
-
} : {}
|
|
4770
|
-
};
|
|
4771
|
-
}
|
|
4772
|
-
|
|
4773
5270
|
// src/v2/hooks/system-prompt-response.ts
|
|
4774
5271
|
function bindV2SystemPromptResponse(sessionId, reader) {
|
|
4775
5272
|
const request = currentLkgRequestIdentity(sessionId);
|
|
@@ -5035,8 +5532,10 @@ function applyCheckpointHead(draft, head) {
|
|
|
5035
5532
|
const { checkpoint, submitted } = head;
|
|
5036
5533
|
const first = draft.messages.find((message) => message.id === HEAD_IDS[0]);
|
|
5037
5534
|
const baseline = first?.content.find((part) => part.type === "text")?.text;
|
|
5038
|
-
if (typeof baseline !== "string")
|
|
5039
|
-
|
|
5535
|
+
if (typeof baseline !== "string") {
|
|
5536
|
+
draft.messages.unshift(checkpoint);
|
|
5537
|
+
return true;
|
|
5538
|
+
}
|
|
5040
5539
|
for (const part of checkpoint.content)
|
|
5041
5540
|
if (part.type === "text" && typeof part.text === "string") {
|
|
5042
5541
|
part.text = part.text.replace(`<summary>
|
|
@@ -5051,6 +5550,105 @@ ${baseline}
|
|
|
5051
5550
|
draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== first));
|
|
5052
5551
|
return true;
|
|
5053
5552
|
}
|
|
5553
|
+
function bindKeptInstructionCoordinates(messages, incoming, reader, sessionID) {
|
|
5554
|
+
const rows = reader.instructionRowsThrough(sessionID, reader.latestSequence(sessionID));
|
|
5555
|
+
let previous;
|
|
5556
|
+
let pending = [];
|
|
5557
|
+
const bind = (next) => {
|
|
5558
|
+
if (!pending.length)
|
|
5559
|
+
return;
|
|
5560
|
+
const candidates = rows.filter((row) => (previous === undefined || row.seq > previous) && (next === undefined || row.seq < next));
|
|
5561
|
+
const selected = previous === undefined ? candidates.slice(-pending.length) : next === undefined ? candidates.slice(0, pending.length) : candidates;
|
|
5562
|
+
if (selected.length === pending.length && selected.every((row, index) => {
|
|
5563
|
+
const message = pending[index];
|
|
5564
|
+
return message?.role === "system" && message.content.length === 1 && message.content[0]?.type === "text" && message.content[0].text === row.data.text;
|
|
5565
|
+
})) {
|
|
5566
|
+
selected.forEach((row, index) => {
|
|
5567
|
+
const message = pending[index];
|
|
5568
|
+
if (message)
|
|
5569
|
+
bindNativeRowID(message, row.id);
|
|
5570
|
+
});
|
|
5571
|
+
}
|
|
5572
|
+
pending = [];
|
|
5573
|
+
};
|
|
5574
|
+
for (const message of messages) {
|
|
5575
|
+
if (message === incoming || effortPart(message))
|
|
5576
|
+
continue;
|
|
5577
|
+
const id = nativeRowID(message);
|
|
5578
|
+
const seq = id ? reader.sequenceForId(sessionID, id) : undefined;
|
|
5579
|
+
if (seq !== undefined) {
|
|
5580
|
+
bind(seq);
|
|
5581
|
+
previous = seq;
|
|
5582
|
+
} else if (!id && message.role === "system")
|
|
5583
|
+
pending.push(message);
|
|
5584
|
+
}
|
|
5585
|
+
bind();
|
|
5586
|
+
}
|
|
5587
|
+
function controlSuffixKeys(messages, skip) {
|
|
5588
|
+
const keys = new Map;
|
|
5589
|
+
let before;
|
|
5590
|
+
let occurrence = 0;
|
|
5591
|
+
for (let index = messages.length - 1;index >= 0; index--) {
|
|
5592
|
+
const message = messages[index];
|
|
5593
|
+
if (!message || message === skip)
|
|
5594
|
+
continue;
|
|
5595
|
+
const part = effortPart(message);
|
|
5596
|
+
if (part) {
|
|
5597
|
+
if (before)
|
|
5598
|
+
keys.set(message, JSON.stringify({
|
|
5599
|
+
before,
|
|
5600
|
+
occurrence: occurrence++,
|
|
5601
|
+
effort: part.effort,
|
|
5602
|
+
previous: part.previous
|
|
5603
|
+
}));
|
|
5604
|
+
} else {
|
|
5605
|
+
before = nativeRowID(message);
|
|
5606
|
+
occurrence = 0;
|
|
5607
|
+
}
|
|
5608
|
+
}
|
|
5609
|
+
return keys;
|
|
5610
|
+
}
|
|
5611
|
+
function restoreNativeCheckpointInput(messages, incoming, restored, reader, sessionID) {
|
|
5612
|
+
bindKeptInstructionCoordinates(messages, incoming, reader, sessionID);
|
|
5613
|
+
const present = new Set(messages.flatMap((message) => nativeRowID(message) ?? []));
|
|
5614
|
+
const currentControls = new Map;
|
|
5615
|
+
const currentSuffixKeys = controlSuffixKeys(messages, incoming);
|
|
5616
|
+
const restoredSuffixKeys = controlSuffixKeys(restored);
|
|
5617
|
+
const leadingControls = new Set;
|
|
5618
|
+
let after;
|
|
5619
|
+
for (const message of messages) {
|
|
5620
|
+
const part = effortPart(message);
|
|
5621
|
+
if (part) {
|
|
5622
|
+
const suffixKey = currentSuffixKeys.get(message);
|
|
5623
|
+
if (!after && suffixKey) {
|
|
5624
|
+
leadingControls.add(suffixKey);
|
|
5625
|
+
continue;
|
|
5626
|
+
}
|
|
5627
|
+
const key = controlKey({
|
|
5628
|
+
after,
|
|
5629
|
+
effort: part.effort,
|
|
5630
|
+
previous: part.previous
|
|
5631
|
+
});
|
|
5632
|
+
currentControls.set(key, (currentControls.get(key) ?? 0) + 1);
|
|
5633
|
+
} else if (message !== incoming && nativeRowID(message))
|
|
5634
|
+
after = nativeRowID(message);
|
|
5635
|
+
}
|
|
5636
|
+
const hidden = restored.filter((message) => {
|
|
5637
|
+
const suffixKey = restoredSuffixKeys.get(message);
|
|
5638
|
+
if (suffixKey && leadingControls.delete(suffixKey))
|
|
5639
|
+
return false;
|
|
5640
|
+
const key = rememberedControlKey(message);
|
|
5641
|
+
const count = key ? currentControls.get(key) ?? 0 : 0;
|
|
5642
|
+
if (key && count > 0) {
|
|
5643
|
+
currentControls.set(key, count - 1);
|
|
5644
|
+
return false;
|
|
5645
|
+
}
|
|
5646
|
+
const id = nativeRowID(message);
|
|
5647
|
+
return !id || !present.has(id);
|
|
5648
|
+
});
|
|
5649
|
+
const at = messages.indexOf(incoming);
|
|
5650
|
+
return [...messages.slice(0, at), ...hidden, ...messages.slice(at + 1)];
|
|
5651
|
+
}
|
|
5054
5652
|
function estimateCheckpointRequest(draft) {
|
|
5055
5653
|
let toolDefinitionTokens = 0;
|
|
5056
5654
|
for (const tool of Object.values(draft.tools)) {
|
|
@@ -5307,8 +5905,11 @@ async function registerContext(context) {
|
|
|
5307
5905
|
}
|
|
5308
5906
|
const embeddings = createV2EmbeddingScope(resolveProjectIdentityForSession(directory, config.allow_home_project));
|
|
5309
5907
|
const folds = new FoldOwner(context.storage);
|
|
5310
|
-
const nativeFoldMemory =
|
|
5311
|
-
const nativeFoldReplay = nativeFoldMemory ? new NativeFoldReplay(nativeFoldMemory, () => openStoreReader(), context.storage
|
|
5908
|
+
const nativeFoldMemory = compactionOff ? undefined : nativeFoldCache(() => storage.require());
|
|
5909
|
+
const nativeFoldReplay = nativeFoldMemory ? new NativeFoldReplay(nativeFoldMemory, () => openStoreReader(), context.storage, {
|
|
5910
|
+
protocol: 3,
|
|
5911
|
+
log: sessionLog2
|
|
5912
|
+
}) : undefined;
|
|
5312
5913
|
setOutputReserveConfig(config.output_reserve);
|
|
5313
5914
|
const queriedModels = new Set;
|
|
5314
5915
|
const rawLimits = new Map;
|
|
@@ -5362,34 +5963,38 @@ async function registerContext(context) {
|
|
|
5362
5963
|
memorySyncRequestedSessions: rustMemorySyncRequestedSessions
|
|
5363
5964
|
}) : undefined;
|
|
5364
5965
|
const hiddenChildHook = new HiddenChildHook;
|
|
5365
|
-
await context.session.hook("http.request", (draft) => hiddenChildHook.cacheRequest(draft));
|
|
5366
|
-
const tools = db && isDatabasePersisted(db) ? await registerTools(context, db, config, moduleToolBackends?.backends, (id) => hiddenChildHook.owns(id), embeddings.ensureRegistered) : undefined;
|
|
5367
5966
|
const usage = new Map;
|
|
5967
|
+
const overflowRecovery = new V2OverflowRecovery({
|
|
5968
|
+
database: () => db ?? null,
|
|
5969
|
+
compactionOff,
|
|
5970
|
+
isHidden: (sessionID) => hiddenChildHook.owns(sessionID),
|
|
5971
|
+
onInputTokens: (sessionID, inputTokens, limit) => usage.set(sessionID, {
|
|
5972
|
+
usage: { inputTokens, percentage: limit > 0 ? inputTokens / limit * 100 : 100 },
|
|
5973
|
+
hasUsageTokens: true,
|
|
5974
|
+
updatedAt: Date.now()
|
|
5975
|
+
})
|
|
5976
|
+
});
|
|
5977
|
+
await context.session.hook("http.request", async (draft) => {
|
|
5978
|
+
await hiddenChildHook.cacheRequest(draft);
|
|
5979
|
+
if (draft.kind !== "primary" || hiddenChildHook.owns(draft.sessionID))
|
|
5980
|
+
return;
|
|
5981
|
+
const selectedModel = liveModels.get(draft.sessionID);
|
|
5982
|
+
if (selectedModel)
|
|
5983
|
+
overflowRecovery.begin({
|
|
5984
|
+
...draft,
|
|
5985
|
+
model: { providerID: selectedModel.providerID, id: selectedModel.modelID }
|
|
5986
|
+
});
|
|
5987
|
+
});
|
|
5988
|
+
const tools = db && isDatabasePersisted(db) ? await registerTools(context, db, config, moduleToolBackends?.backends, (id) => hiddenChildHook.owns(id), embeddings.ensureRegistered) : undefined;
|
|
5368
5989
|
const generateReplay = new V2GenerateReplay;
|
|
5369
5990
|
await context.session.hook("http.response", async (draft) => {
|
|
5370
5991
|
if (!db || draft.kind !== "primary" || draft.response.ok)
|
|
5371
5992
|
return;
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
if (detection.reportedLimit)
|
|
5378
|
-
recordDetectedContextLimit(db, draft.sessionID, detection.reportedLimit, modelKey, detection.reportedLimitProvenance);
|
|
5379
|
-
} else {
|
|
5380
|
-
recordOverflowDetected(db, draft.sessionID, detection.reportedLimit, modelKey, "provider_overflow", detection.reportedLimitProvenance, detection.reportedInputTokens);
|
|
5381
|
-
if (detection.reportedInputTokens) {
|
|
5382
|
-
const provenLimit = getOverflowState(db, draft.sessionID, modelKey).detectedContextLimit;
|
|
5383
|
-
usage.set(draft.sessionID, {
|
|
5384
|
-
usage: {
|
|
5385
|
-
inputTokens: detection.reportedInputTokens,
|
|
5386
|
-
percentage: provenLimit > 0 ? detection.reportedInputTokens / provenLimit * 100 : 100
|
|
5387
|
-
},
|
|
5388
|
-
hasUsageTokens: true,
|
|
5389
|
-
updatedAt: Date.now()
|
|
5390
|
-
});
|
|
5391
|
-
}
|
|
5392
|
-
}
|
|
5993
|
+
overflowRecovery.observe({
|
|
5994
|
+
...draft,
|
|
5995
|
+
error: await draft.response.clone().text(),
|
|
5996
|
+
status: draft.response.status
|
|
5997
|
+
});
|
|
5393
5998
|
});
|
|
5394
5999
|
await registerHiddenChildAgents(context.agent);
|
|
5395
6000
|
await context.tool.hook("execute.before", (draft) => {
|
|
@@ -5403,9 +6008,9 @@ async function registerContext(context) {
|
|
|
5403
6008
|
throw new HiddenCompletionRefusal("hidden_prompt_unrecognized", refusal, true);
|
|
5404
6009
|
});
|
|
5405
6010
|
let hiddenAgentsReady;
|
|
5406
|
-
const readerPool = new
|
|
6011
|
+
const readerPool = new V2StoreReaderPool2;
|
|
5407
6012
|
const messageTimesCache = new V2MessageTimesCache;
|
|
5408
|
-
const openStoreReader = () => readerPool.open(
|
|
6013
|
+
const openStoreReader = () => readerPool.open(gaDatabasePath2(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
|
|
5409
6014
|
const createHiddenExecutor = async (database) => {
|
|
5410
6015
|
await cleanupLegacyOnce(database);
|
|
5411
6016
|
return createV2HiddenCompletionExecutor({
|
|
@@ -5565,10 +6170,10 @@ async function registerContext(context) {
|
|
|
5565
6170
|
log2("[magic-context] v2 Channel 2 delivery deferred", error);
|
|
5566
6171
|
}
|
|
5567
6172
|
});
|
|
5568
|
-
const pagedRead =
|
|
6173
|
+
const pagedRead = createV2RawMessageReader2(openStoreReader, gaDatabasePath2(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"));
|
|
5569
6174
|
const prepareHistorySession = (sessionID) => {
|
|
5570
6175
|
if (!rawProviders.has(sessionID))
|
|
5571
|
-
rawProviders.set(sessionID, setBoundedRawMessageProvider2(sessionID,
|
|
6176
|
+
rawProviders.set(sessionID, setBoundedRawMessageProvider2(sessionID, createV2RawMessageProvider2(pagedRead, sessionID)));
|
|
5572
6177
|
};
|
|
5573
6178
|
if (db && isDatabasePersisted(db)) {
|
|
5574
6179
|
const backfillDb = db;
|
|
@@ -5583,7 +6188,7 @@ async function registerContext(context) {
|
|
|
5583
6188
|
})).catch((error) => log2("[session-project-backfill] OpenCode 2 backfill failed:", error));
|
|
5584
6189
|
});
|
|
5585
6190
|
}
|
|
5586
|
-
const readAllForConversion = (sessionID) =>
|
|
6191
|
+
const readAllForConversion = (sessionID) => readAllV2RawMessagesForConversion2(openStoreReader, sessionID);
|
|
5587
6192
|
const readRowsFrom = (sessionID, messageID) => {
|
|
5588
6193
|
const reader = openStoreReader();
|
|
5589
6194
|
try {
|
|
@@ -5737,9 +6342,11 @@ async function registerContext(context) {
|
|
|
5737
6342
|
storage: nativeFoldMemory,
|
|
5738
6343
|
openReader: openStoreReader,
|
|
5739
6344
|
canReplay: (sessionID, reader) => nativeFoldReplay.canReplay(sessionID, reader),
|
|
6345
|
+
canFold: (sessionID, reader) => nativeFoldReplay.canFold(sessionID, reader),
|
|
5740
6346
|
threshold: Number(process.env.MC_OC2_HOST_FOLD_ROWS ?? 1000),
|
|
5741
6347
|
log: sessionLog2
|
|
5742
6348
|
}) : undefined;
|
|
6349
|
+
const hostFoldIdle = hostFolds ? new HostFoldIdle((sessionID, eligible) => hostFolds.idle(sessionID, eligible)) : undefined;
|
|
5743
6350
|
const usageController = new AbortController;
|
|
5744
6351
|
const usageDone = (async () => {
|
|
5745
6352
|
let retry = 0;
|
|
@@ -5761,10 +6368,26 @@ async function registerContext(context) {
|
|
|
5761
6368
|
if (!event.data?.sessionID)
|
|
5762
6369
|
continue;
|
|
5763
6370
|
const sessionID = event.data.sessionID;
|
|
6371
|
+
overflowRecovery.observeTerminal(event, (id, messageID) => {
|
|
6372
|
+
const reader = openStoreReader();
|
|
6373
|
+
try {
|
|
6374
|
+
const latest = reader.latestAssistant(id);
|
|
6375
|
+
if (messageID && latest?.id !== messageID)
|
|
6376
|
+
return;
|
|
6377
|
+
const row = messageID ? reader.messageById(id, messageID) : latest;
|
|
6378
|
+
return row ? { id: row.id, model: row.data.model, error: row.data.error } : undefined;
|
|
6379
|
+
} finally {
|
|
6380
|
+
reader.close();
|
|
6381
|
+
}
|
|
6382
|
+
});
|
|
5764
6383
|
if (db && event.type === "session.revert.committed") {
|
|
5765
6384
|
const indexDb = db;
|
|
5766
6385
|
withoutSqliteTransformPass2(() => scheduleClearAndReindex(indexDb, sessionID, pagedRead));
|
|
5767
6386
|
}
|
|
6387
|
+
if (event.type === "session.execution.started" || event.type === "session.execution.interrupted") {
|
|
6388
|
+
hostFoldIdle?.active(sessionID);
|
|
6389
|
+
continue;
|
|
6390
|
+
}
|
|
5768
6391
|
if (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated") {
|
|
5769
6392
|
nativeFoldReplay?.onEvent(event);
|
|
5770
6393
|
restoredRows.forget(sessionID);
|
|
@@ -5776,6 +6399,7 @@ async function registerContext(context) {
|
|
|
5776
6399
|
messageTimesCache.deleteMessage(sessionID, messageID);
|
|
5777
6400
|
}
|
|
5778
6401
|
if (event.type === "session.error" || event.type === "session.execution.failed") {
|
|
6402
|
+
hostFoldIdle?.active(sessionID);
|
|
5779
6403
|
const error = hiddenTerminalError(event);
|
|
5780
6404
|
if (error !== undefined)
|
|
5781
6405
|
hiddenSessionErrors.set(sessionID, error);
|
|
@@ -5796,6 +6420,8 @@ async function registerContext(context) {
|
|
|
5796
6420
|
continue;
|
|
5797
6421
|
}
|
|
5798
6422
|
if (event.type === "session.deleted") {
|
|
6423
|
+
overflowRecovery.forget(sessionID);
|
|
6424
|
+
hostFoldIdle?.active(sessionID);
|
|
5799
6425
|
clearLkgMeasuredRequest(sessionID);
|
|
5800
6426
|
deletedSessions.add(sessionID);
|
|
5801
6427
|
const failures = [];
|
|
@@ -5850,8 +6476,12 @@ async function registerContext(context) {
|
|
|
5850
6476
|
sessionID,
|
|
5851
6477
|
model: { providerID: model.providerID, id: model.modelID }
|
|
5852
6478
|
});
|
|
5853
|
-
if (!compactionOff
|
|
5854
|
-
|
|
6479
|
+
if (!compactionOff) {
|
|
6480
|
+
if (db) {
|
|
6481
|
+
const meta = getOrCreateSessionMeta(db, sessionID);
|
|
6482
|
+
hostFoldIdle?.idle(sessionID, meta.cacheTtl, meta.lastResponseTime);
|
|
6483
|
+
}
|
|
6484
|
+
}
|
|
5855
6485
|
}
|
|
5856
6486
|
} catch (error) {
|
|
5857
6487
|
log2(`[magic-context] v2 event handler failed (type=${event.type ?? "unknown"}, session=${event.data?.sessionID ?? "none"})`, error);
|
|
@@ -5923,18 +6553,16 @@ async function registerContext(context) {
|
|
|
5923
6553
|
const source = !rustModeModuleClient ? "typescript" : moduleBaseline === null ? "typescript_fallback" : "module";
|
|
5924
6554
|
if (nativeFoldReplay) {
|
|
5925
6555
|
try {
|
|
5926
|
-
|
|
5927
|
-
|
|
5928
|
-
|
|
5929
|
-
|
|
5930
|
-
|
|
5931
|
-
|
|
5932
|
-
|
|
5933
|
-
|
|
5934
|
-
}
|
|
5935
|
-
|
|
5936
|
-
return;
|
|
5937
|
-
}
|
|
6556
|
+
const state = getOrCreateSessionMeta(storage.require(), draft.sessionID);
|
|
6557
|
+
const summary = moduleBaseline ?? await nativeFoldReplay.baseline(draft.sessionID) ?? state.cachedM0Bytes?.toString("utf8") ?? "<session-history></session-history>";
|
|
6558
|
+
if (await nativeFoldReplay.supply({
|
|
6559
|
+
draft,
|
|
6560
|
+
reader,
|
|
6561
|
+
previousCut: reader.latestCompaction(draft.sessionID),
|
|
6562
|
+
summary
|
|
6563
|
+
})) {
|
|
6564
|
+
draft.result = { summary, metadata: { keepID: undefined } };
|
|
6565
|
+
return;
|
|
5938
6566
|
}
|
|
5939
6567
|
} catch (error) {
|
|
5940
6568
|
nativeFoldReplay.invalidate(draft.sessionID, true);
|
|
@@ -5974,13 +6602,14 @@ async function registerContext(context) {
|
|
|
5974
6602
|
}
|
|
5975
6603
|
return ids;
|
|
5976
6604
|
};
|
|
5977
|
-
const restoreAfterCheckpoint = (args) => {
|
|
6605
|
+
const restoreAfterCheckpoint = async (args) => {
|
|
5978
6606
|
const { db, reader, draft, cut, boundaryRepair } = args;
|
|
5979
6607
|
const moduleBoundaryID = rustModeModuleClient ? getPersistedCompactionMarkerState(db, draft.sessionID)?.boundaryMessageId ?? null : null;
|
|
5980
6608
|
const moduleBoundarySeq = moduleBoundaryID ? reader.sequenceForId(draft.sessionID, moduleBoundaryID) : undefined;
|
|
5981
6609
|
const boundaryID = db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id = ?").get(draft.sessionID)?.id ?? (boundaryRepair?.kind === "repaired" || boundaryRepair?.kind === "baseline-reset" ? boundaryRepair.anchorEndMessageId : null);
|
|
5982
|
-
const servedBoundary = boundaryID ?
|
|
5983
|
-
const
|
|
6610
|
+
const servedBoundary = boundaryID ? servedBoundaryRow2(reader, draft.sessionID, boundaryID) : null;
|
|
6611
|
+
const nativeFloor = await nativeFoldReplay?.restorationFloor(draft.sessionID, cut, reader);
|
|
6612
|
+
const boundary = Math.max(nativeFloor ?? -Infinity, (nativeFoldReplay?.sourceChanged(draft.sessionID) && !rustModeModuleClient ? (reader.earliestSequence(draft.sessionID) ?? 0) - 1 : undefined) ?? (moduleBoundarySeq !== undefined ? moduleBoundarySeq - 1 : undefined) ?? servedBoundary?.seq ?? reader.sequenceForId(draft.sessionID, boundaryID) ?? (reader.earliestSequence(draft.sessionID) ?? 0) - 1);
|
|
5984
6613
|
if (moduleBoundarySeq !== undefined)
|
|
5985
6614
|
sessionLog2(draft.sessionID, `v2 restore: from the module boundary ${moduleBoundaryID} to the host checkpoint`);
|
|
5986
6615
|
const present = new Set(args.messages.map((message) => message.id));
|
|
@@ -5996,6 +6625,7 @@ async function registerContext(context) {
|
|
|
5996
6625
|
};
|
|
5997
6626
|
const checkpointPassPermissions = new Map;
|
|
5998
6627
|
const checkpointInputEstimates = new Map;
|
|
6628
|
+
const admissionRebuildPasses = new Set;
|
|
5999
6629
|
const initializeTransform = (database) => transform ??= createTransform({
|
|
6000
6630
|
...createV2TransformFeatureDeps(config, compactionOff, directory, embeddings.ensureRegistered),
|
|
6001
6631
|
cacheTtlConfig: config.cache_ttl,
|
|
@@ -6065,7 +6695,7 @@ async function registerContext(context) {
|
|
|
6065
6695
|
compactionMarkerStrategy: rustModeModuleClient ? createV2RustCompactionMarkerStrategy((sessionID, endMessageID) => {
|
|
6066
6696
|
const reader = openStoreReader();
|
|
6067
6697
|
try {
|
|
6068
|
-
return
|
|
6698
|
+
return resolveV2BoundaryUserMessage2(reader, sessionID, endMessageID);
|
|
6069
6699
|
} finally {
|
|
6070
6700
|
reader.close();
|
|
6071
6701
|
}
|
|
@@ -6123,6 +6753,7 @@ async function registerContext(context) {
|
|
|
6123
6753
|
providerID: draft.model.providerID,
|
|
6124
6754
|
modelID: draft.model.id
|
|
6125
6755
|
});
|
|
6756
|
+
overflowRecovery.begin({ sessionID: draft.sessionID, kind: "primary", model: draft.model });
|
|
6126
6757
|
variants.set(draft.sessionID, draft.model.variant);
|
|
6127
6758
|
if (!modelLimitCacheWarm())
|
|
6128
6759
|
withoutSqliteTransformPass2(() => warmModelLimitCacheFromCatalog(context));
|
|
@@ -6177,7 +6808,7 @@ async function registerContext(context) {
|
|
|
6177
6808
|
const cut = reader.latestCompaction(draft.sessionID);
|
|
6178
6809
|
const localCut = cut && isLocalCheckpoint(cut) ? cut : undefined;
|
|
6179
6810
|
const incoming = localCut && messages.find((message) => message.id === localCut.id);
|
|
6180
|
-
if (localCut && !incoming
|
|
6811
|
+
if (localCut && !incoming)
|
|
6181
6812
|
return;
|
|
6182
6813
|
checkpointAtEntry = incoming || null;
|
|
6183
6814
|
const modeDb = db ?? storage.current();
|
|
@@ -6192,17 +6823,33 @@ async function registerContext(context) {
|
|
|
6192
6823
|
if (message.id && candidates.has(message.id) && await isAdmittedSynthetic(context, draft.sessionID, message.id))
|
|
6193
6824
|
admitted.add(message.id);
|
|
6194
6825
|
const replayDb = db ?? storage.current();
|
|
6195
|
-
if (localCut && incoming && replayDb)
|
|
6196
|
-
|
|
6197
|
-
|
|
6198
|
-
|
|
6199
|
-
|
|
6200
|
-
|
|
6201
|
-
|
|
6202
|
-
|
|
6203
|
-
|
|
6204
|
-
|
|
6205
|
-
|
|
6826
|
+
if (localCut && incoming && replayDb) {
|
|
6827
|
+
const admission = nativeFoldReplay ? await nativeFoldReplay.replayAdmission(draft.sessionID, localCut, reader) : "legacy";
|
|
6828
|
+
if (admission === undefined)
|
|
6829
|
+
return;
|
|
6830
|
+
if (admission === "native" && nativeFoldReplay) {
|
|
6831
|
+
const restored = await nativeFoldReplay.projectReplay({
|
|
6832
|
+
sessionID: draft.sessionID,
|
|
6833
|
+
cut: localCut,
|
|
6834
|
+
model: draft.model,
|
|
6835
|
+
reader,
|
|
6836
|
+
bounded: true
|
|
6837
|
+
});
|
|
6838
|
+
if (!restored)
|
|
6839
|
+
return;
|
|
6840
|
+
messages = restoreNativeCheckpointInput(messages, incoming, restored, reader, draft.sessionID);
|
|
6841
|
+
} else {
|
|
6842
|
+
messages = await restoreAfterCheckpoint({
|
|
6843
|
+
db: replayDb,
|
|
6844
|
+
reader,
|
|
6845
|
+
draft,
|
|
6846
|
+
messages,
|
|
6847
|
+
cut: localCut,
|
|
6848
|
+
incoming,
|
|
6849
|
+
boundaryRepair: undefined
|
|
6850
|
+
});
|
|
6851
|
+
}
|
|
6852
|
+
} else if (localCut)
|
|
6206
6853
|
return;
|
|
6207
6854
|
times = readTimes(reader, messages);
|
|
6208
6855
|
}
|
|
@@ -6283,7 +6930,7 @@ async function registerContext(context) {
|
|
|
6283
6930
|
sessionId: draft.sessionID,
|
|
6284
6931
|
generation: "v2",
|
|
6285
6932
|
readMessages: readAllForConversion,
|
|
6286
|
-
readMessagePages: (sessionID) =>
|
|
6933
|
+
readMessagePages: (sessionID) => readV2RawMessagePagesForConversion2(openStoreReader, sessionID)
|
|
6287
6934
|
});
|
|
6288
6935
|
} catch (error) {
|
|
6289
6936
|
sessionLog2(draft.sessionID, "store projection rebase failed before system prompt (retrying in transform):", error);
|
|
@@ -6342,6 +6989,7 @@ async function registerContext(context) {
|
|
|
6342
6989
|
const reader = openStoreReader();
|
|
6343
6990
|
let checkpoint;
|
|
6344
6991
|
let submitted;
|
|
6992
|
+
let upgradeCheckpointSequence;
|
|
6345
6993
|
try {
|
|
6346
6994
|
const candidates = syntheticCandidates(context, draft.sessionID, reader.syntheticMessageIDs(draft.sessionID));
|
|
6347
6995
|
for (const message of draft.messages) {
|
|
@@ -6362,8 +7010,31 @@ async function registerContext(context) {
|
|
|
6362
7010
|
if (localCut && !incoming)
|
|
6363
7011
|
throw new Error("The host checkpoint disappeared from the context draft");
|
|
6364
7012
|
checkpointAtEntry = incoming || null;
|
|
6365
|
-
|
|
6366
|
-
|
|
7013
|
+
if (localCut && nativeFoldReplay) {
|
|
7014
|
+
await nativeFoldReplay.prepareLegacyUpgrade({
|
|
7015
|
+
draft,
|
|
7016
|
+
cut: localCut,
|
|
7017
|
+
reader
|
|
7018
|
+
});
|
|
7019
|
+
const carrier = await nativeFoldReplay.checkpointForReplay(draft.sessionID, reader);
|
|
7020
|
+
if (carrier) {
|
|
7021
|
+
const identity = await folds.observe({
|
|
7022
|
+
sessionID: draft.sessionID,
|
|
7023
|
+
cutSeq: carrier.row.seq,
|
|
7024
|
+
summary: carrier.submitted,
|
|
7025
|
+
rendered: carrier.rendered,
|
|
7026
|
+
onHard: () => {
|
|
7027
|
+
historyRefreshSessions.add(draft.sessionID);
|
|
7028
|
+
requestPendingMaterialization(pendingMaterializationSessions, draft.sessionID, "host_compaction");
|
|
7029
|
+
}
|
|
7030
|
+
});
|
|
7031
|
+
checkpoint = structuredClone(identity.rendered ?? carrier.rendered);
|
|
7032
|
+
submitted = identity.renderedSummary ?? carrier.submitted;
|
|
7033
|
+
upgradeCheckpointSequence = carrier.row.seq;
|
|
7034
|
+
}
|
|
7035
|
+
}
|
|
7036
|
+
let nativeRestored = localCut ? nativeFoldReplay?.legacyUpgradeInput(draft.sessionID, draft.model) : undefined;
|
|
7037
|
+
if (nativeRestored === undefined && cut && nativeFoldReplay && await nativeFoldReplay.admits(draft.sessionID, cut, reader)) {
|
|
6367
7038
|
try {
|
|
6368
7039
|
nativeRestored = await nativeFoldReplay.restore(draft.sessionID, cut, `${draft.model.providerID}/${draft.model.id}`, { bounded: !rustModeModuleClient });
|
|
6369
7040
|
} catch (error) {
|
|
@@ -6381,14 +7052,10 @@ async function registerContext(context) {
|
|
|
6381
7052
|
requestPendingMaterialization(pendingMaterializationSessions, draft.sessionID, "host_history_change");
|
|
6382
7053
|
}
|
|
6383
7054
|
if (cut && incoming && nativeRestored) {
|
|
6384
|
-
|
|
6385
|
-
const hidden = nativeRestored.filter((message) => {
|
|
6386
|
-
const id = nativeRowID(message);
|
|
6387
|
-
return !id || !present.has(id);
|
|
6388
|
-
});
|
|
6389
|
-
draft.messages.splice(0, draft.messages.length, ...hidden, ...draft.messages.filter((message) => message !== incoming));
|
|
7055
|
+
draft.messages.splice(0, draft.messages.length, ...restoreNativeCheckpointInput(draft.messages, incoming, nativeRestored, reader, draft.sessionID));
|
|
6390
7056
|
} else if (localCut && cut && incoming) {
|
|
6391
|
-
|
|
7057
|
+
const legacy = await folds.read(draft.sessionID);
|
|
7058
|
+
if (legacy?.cutSeq === cut.seq && legacy.submittedSha === foldDigest(cut.data.summary ?? "")) {
|
|
6392
7059
|
const identity = await folds.observe({
|
|
6393
7060
|
sessionID: draft.sessionID,
|
|
6394
7061
|
cutSeq: cut.seq,
|
|
@@ -6403,7 +7070,7 @@ async function registerContext(context) {
|
|
|
6403
7070
|
checkpoint = structuredClone(identity.rendered ?? incoming);
|
|
6404
7071
|
submitted = identity.rendered ? identity.renderedSummary ?? identity.submitted : cut.data.summary ?? "";
|
|
6405
7072
|
}
|
|
6406
|
-
draft.messages.splice(0, draft.messages.length, ...restoreAfterCheckpoint({
|
|
7073
|
+
draft.messages.splice(0, draft.messages.length, ...await restoreAfterCheckpoint({
|
|
6407
7074
|
db,
|
|
6408
7075
|
reader,
|
|
6409
7076
|
draft,
|
|
@@ -6459,9 +7126,28 @@ async function registerContext(context) {
|
|
|
6459
7126
|
checkpointPassPermissions.delete(draft.sessionID);
|
|
6460
7127
|
checkpointInputEstimates.delete(draft.sessionID);
|
|
6461
7128
|
if (checkpoint?.id && checkpointPermission && replayHead === undefined) {
|
|
6462
|
-
|
|
6463
|
-
if (
|
|
6464
|
-
|
|
7129
|
+
let covered = upgradeCheckpointSequence === undefined;
|
|
7130
|
+
if (upgradeCheckpointSequence !== undefined) {
|
|
7131
|
+
const boundary = db.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(draft.sessionID);
|
|
7132
|
+
const source = openStoreReader();
|
|
7133
|
+
try {
|
|
7134
|
+
const through = upgradeCheckpointSequence - 1;
|
|
7135
|
+
const last = source.rowStampsThrough(draft.sessionID, through).filter((row) => RAW_MESSAGE_TYPES2.includes(row.type)).at(-1)?.seq;
|
|
7136
|
+
const end = boundary?.id ? source.sequenceForId(draft.sessionID, boundary.id) : undefined;
|
|
7137
|
+
covered = last === undefined || end !== undefined && end >= last;
|
|
7138
|
+
} finally {
|
|
7139
|
+
source.close();
|
|
7140
|
+
}
|
|
7141
|
+
}
|
|
7142
|
+
if (covered) {
|
|
7143
|
+
const checkpointID = checkpoint.id;
|
|
7144
|
+
const stripped = await folds.stripRecentContext(draft.sessionID, checkpointID);
|
|
7145
|
+
if (stripped?.rendered) {
|
|
7146
|
+
checkpoint = structuredClone(stripped.rendered);
|
|
7147
|
+
if (upgradeCheckpointSequence !== undefined)
|
|
7148
|
+
await nativeFoldReplay?.checkpointCovered(draft.sessionID, checkpointID);
|
|
7149
|
+
}
|
|
7150
|
+
}
|
|
6465
7151
|
}
|
|
6466
7152
|
stageOpenCodeV2TransformDecision({
|
|
6467
7153
|
sessionId: draft.sessionID,
|
|
@@ -6473,14 +7159,18 @@ async function registerContext(context) {
|
|
|
6473
7159
|
const head = replayHead !== undefined ? replayHead : checkpoint && submitted !== undefined ? { checkpoint, submitted } : null;
|
|
6474
7160
|
const servedHead = head && structuredClone(head);
|
|
6475
7161
|
const headApplied = head ? applyCheckpointHead(draft, head) : false;
|
|
6476
|
-
if (nativeMessages && !checkpoint) {
|
|
7162
|
+
if (nativeMessages && (!checkpoint || upgradeCheckpointSequence !== undefined)) {
|
|
6477
7163
|
try {
|
|
6478
|
-
|
|
7164
|
+
const state = db && getOrCreateSessionMeta(db, draft.sessionID);
|
|
7165
|
+
const boundary = db?.prepare("SELECT cached_m0_last_baseline_end_message_id AS id FROM session_meta WHERE session_id=?").get(draft.sessionID);
|
|
7166
|
+
await nativeFoldReplay?.capture(draft, nativeMessages, boundary?.id && state?.cachedM0Bytes ? { id: boundary.id, summary: state.cachedM0Bytes.toString("utf8") } : undefined);
|
|
6479
7167
|
} catch (error) {
|
|
6480
7168
|
nativeFoldReplay?.invalidate(draft.sessionID, true);
|
|
6481
7169
|
sessionLog2(draft.sessionID, "v2 host fold: optional capture unavailable", error);
|
|
6482
7170
|
}
|
|
6483
7171
|
}
|
|
7172
|
+
if (checkpointPermission === true && replayHead === undefined)
|
|
7173
|
+
admissionRebuildPasses.add(draft.sessionID);
|
|
6484
7174
|
const capturedSlot = getSlot(draft.sessionID);
|
|
6485
7175
|
if (capturedSlot && (!slotAtEntry || capturedSlot.capturedAt !== slotAtEntry.capturedAt || capturedSlot.captureSequence !== slotAtEntry.captureSequence || capturedSlot.jsonPrefix !== slotAtEntry.jsonPrefix)) {
|
|
6486
7176
|
lkgSystems.capture(draft.sessionID, capturedSlot, { system: systemAtEntry, checkpoint: checkpointAtEntry ?? null }, draft.system, headApplied ? servedHead : null);
|
|
@@ -6561,12 +7251,20 @@ async function registerContext(context) {
|
|
|
6561
7251
|
throw new V2ContextRefusal("Magic Context refused an oversized host checkpoint.");
|
|
6562
7252
|
};
|
|
6563
7253
|
await context.session.hook("context", (draft) => withSqliteTransformPass2(async () => {
|
|
7254
|
+
hostFoldIdle?.active(draft.sessionID);
|
|
6564
7255
|
const anchor = generateReplayAnchor(draft.messages);
|
|
6565
7256
|
try {
|
|
6566
7257
|
await runManagedContext(draft);
|
|
6567
7258
|
if (!compactionOff)
|
|
6568
7259
|
await refuseOversizedCheckpoint(draft);
|
|
7260
|
+
if (!deletedSessions.has(draft.sessionID) && admissionRebuildPasses.has(draft.sessionID)) {
|
|
7261
|
+
await nativeFoldReplay?.commitLegacyUpgrade(draft.sessionID, true);
|
|
7262
|
+
await nativeFoldReplay?.commitEditedAdmission(draft.sessionID);
|
|
7263
|
+
}
|
|
6569
7264
|
} finally {
|
|
7265
|
+
admissionRebuildPasses.delete(draft.sessionID);
|
|
7266
|
+
nativeFoldReplay?.cancelLegacyUpgrade(draft.sessionID);
|
|
7267
|
+
nativeFoldReplay?.cancelEditedAdmission(draft.sessionID);
|
|
6570
7268
|
checkpointInputEstimates.delete(draft.sessionID);
|
|
6571
7269
|
checkpointPassPermissions.delete(draft.sessionID);
|
|
6572
7270
|
}
|
|
@@ -6695,6 +7393,7 @@ async function registerContext(context) {
|
|
|
6695
7393
|
return {
|
|
6696
7394
|
async dispose() {
|
|
6697
7395
|
messageTimesCache.clear();
|
|
7396
|
+
hostFoldIdle?.dispose();
|
|
6698
7397
|
usageController.abort();
|
|
6699
7398
|
await hiddenCompletionExecutor?.dispose();
|
|
6700
7399
|
await usageDone;
|