@cortexkit/opencode-magic-context 0.49.19 → 0.49.20

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.
Files changed (271) hide show
  1. package/dist/auto-search-worker.js +48 -9
  2. package/dist/chunk-embedding-write-worker.js +30 -23
  3. package/dist/{compaction-marker-candidates-n4krhat4.js → compaction-marker-candidates-b2q30cft.js} +3 -3
  4. package/dist/compaction-marker-candidates-worker.js +2 -2
  5. package/dist/compartment-chunk-embedding-va090as0.js +65 -0
  6. package/dist/config/schema/magic-context.d.ts +6 -6
  7. package/dist/{conflict-warning-hook-4pmz879v.js → conflict-warning-hook-frp3z2wk.js} +9 -8
  8. package/dist/{context-j31m2dv7.js → context-mkece1db.js} +455 -134
  9. package/dist/{derive-budgets-zn7yzd2d.js → derive-budgets-pqybnx09.js} +2 -2
  10. package/dist/embedding-backfill-gy3p78py.js +25 -0
  11. package/dist/embedding-worker-process.js +2 -2
  12. package/dist/embedding-worker.js +5 -5
  13. package/dist/features/magic-context/chunk-embedding-writer.d.ts.map +1 -1
  14. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +44 -1
  15. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
  17. package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +2 -0
  19. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  20. package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
  21. package/dist/features/magic-context/memory/embedding-local.d.ts +1 -0
  22. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  23. package/dist/features/magic-context/memory/local-embedding-pooling.d.ts +22 -0
  24. package/dist/features/magic-context/memory/local-embedding-pooling.d.ts.map +1 -0
  25. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  26. package/dist/features/magic-context/message-index.d.ts +2 -0
  27. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  28. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  29. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  30. package/dist/features/magic-context/search.d.ts +27 -0
  31. package/dist/features/magic-context/search.d.ts.map +1 -1
  32. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  33. package/dist/features/magic-context/storage-meta-persisted.d.ts +1 -0
  34. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  35. package/dist/features/magic-context/subagent-token-capture.d.ts +20 -0
  36. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
  37. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  38. package/dist/{history-owner-xp3pngv7.js → history-owner-36wp3mkb.js} +2 -2
  39. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  40. package/dist/hooks/magic-context/auto-embed-session.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/auto-search-hint.d.ts +7 -1
  42. package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  44. package/dist/hooks/magic-context/auto-search-worker-client.d.ts +33 -6
  45. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/cache-busting-signals.d.ts +5 -2
  47. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  49. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  50. package/dist/hooks/magic-context/compartment-runner-types.d.ts +5 -0
  51. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  52. package/dist/hooks/magic-context/compartment-trigger.d.ts +1 -1
  53. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  54. package/dist/hooks/magic-context/diagnostic-log-state.d.ts +4 -0
  55. package/dist/hooks/magic-context/diagnostic-log-state.d.ts.map +1 -0
  56. package/dist/hooks/magic-context/execute-reclaim.d.ts +35 -0
  57. package/dist/hooks/magic-context/execute-reclaim.d.ts.map +1 -0
  58. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/hook.d.ts +1 -3
  60. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  61. package/dist/hooks/magic-context/latest-assistant-turn.d.ts +8 -0
  62. package/dist/hooks/magic-context/latest-assistant-turn.d.ts.map +1 -1
  63. package/dist/hooks/magic-context/lkg-recovery-fence.d.ts +5 -0
  64. package/dist/hooks/magic-context/lkg-recovery-fence.d.ts.map +1 -1
  65. package/dist/hooks/magic-context/nudge-evaluation-log.d.ts +3 -0
  66. package/dist/hooks/magic-context/nudge-evaluation-log.d.ts.map +1 -0
  67. package/dist/hooks/magic-context/pending-drop-eligibility.d.ts.map +1 -1
  68. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +4 -0
  69. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  70. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
  71. package/dist/hooks/magic-context/system-date-refresh.d.ts +5 -5
  72. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  73. package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts +10 -0
  74. package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts.map +1 -0
  75. package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
  76. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  77. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  78. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +21 -6
  79. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  80. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  81. package/dist/{index-bjcnntmz.js → index-0wthn7fp.js} +468 -18
  82. package/dist/{index-kq82mtg0.js → index-11zf2wwc.js} +3 -3
  83. package/dist/{index-b5vqckbw.js → index-153r2q6z.js} +314 -127
  84. package/dist/{index-3h4dp9wb.js → index-1pefp8ar.js} +5 -5
  85. package/dist/{index-beht37jy.js → index-1zx2pa5d.js} +1 -1
  86. package/dist/{index-ze7mvk54.js → index-2yhtnfcf.js} +75 -57
  87. package/dist/{index-cf74k5ak.js → index-305y133n.js} +4 -4
  88. package/dist/{index-s734jcsr.js → index-35qc6606.js} +9 -3
  89. package/dist/{index-se4m2g6w.js → index-48stjd56.js} +105 -19
  90. package/dist/{index-4911rn0b.js → index-4n7w9rad.js} +6 -6
  91. package/dist/{index-kee4kn5j.js → index-4pnsgvfk.js} +1 -1
  92. package/dist/{v2/server-8cd2j99z.js → index-5kym00ag.js} +32 -13
  93. package/dist/{index-4s3t0nd0.js → index-616rsjrv.js} +2 -2
  94. package/dist/{index-jhghdnsm.js → index-67nyj0gy.js} +485 -202
  95. package/dist/{index-6x57ar45.js → index-adk2z5d8.js} +3 -3
  96. package/dist/{index-c5pytzne.js → index-b88dwwrh.js} +1 -1
  97. package/dist/{index-rr2bb45z.js → index-c4b76d4t.js} +2 -2
  98. package/dist/{index-nj7yykkx.js → index-c7phnbvk.js} +1 -1
  99. package/dist/index-cpjk5jd2.js +82 -0
  100. package/dist/{index-edmpdxcw.js → index-d6rp4dxh.js} +5 -5
  101. package/dist/{index-dxmq29t1.js → index-dc8hy95c.js} +69 -17
  102. package/dist/{index-j75v2476.js → index-h7tgn49j.js} +12 -15
  103. package/dist/{index-ke416mdc.js → index-j76ah6d7.js} +2 -2
  104. package/dist/{index-c1p88z1y.js → index-jfh3cktr.js} +4 -4
  105. package/dist/{index-a6mc0v4d.js → index-jmycsey7.js} +3 -3
  106. package/dist/{index-24fezq97.js → index-jr5na10t.js} +4 -4
  107. package/dist/{index-s74zqahq.js → index-kc9pn495.js} +4 -4
  108. package/dist/{index-p5y3k4g7.js → index-nda0zgna.js} +2 -1
  109. package/dist/{index-jn12fvvh.js → index-neb2jaed.js} +3 -3
  110. package/dist/{index-63k48rv9.js → index-pnjwa6qa.js} +5 -5
  111. package/dist/{index-jrr131e0.js → index-rmd0069m.js} +11 -11
  112. package/dist/{index-y9f76s3f.js → index-rrv26qjz.js} +1 -1
  113. package/dist/{index-v10f1rjv.js → index-spwjbkc7.js} +1 -1
  114. package/dist/{index-k29z4aqh.js → index-t5pck3ss.js} +1 -1
  115. package/dist/{index-3esx8tkf.js → index-t7hx3qcb.js} +318 -104
  116. package/dist/{index-rpxdjkm0.js → index-v7r4td4c.js} +306 -59
  117. package/dist/{index-2vxtcb95.js → index-vkc1ca9p.js} +2 -2
  118. package/dist/{index-9zcsy3hh.js → index-x4k3f4mf.js} +17 -9
  119. package/dist/{index-bp5083x2.js → index-x9k3mqrf.js} +1 -1
  120. package/dist/{index-n37sebck.js → index-y4a3nhtk.js} +1 -1
  121. package/dist/index.js +52 -49
  122. package/dist/{logger-jm3sqqzr.js → logger-94kew5wm.js} +1 -1
  123. package/dist/{message-fts-rowid-map-17s0dfn4.js → message-fts-rowid-map-22tevnnj.js} +6 -5
  124. package/dist/{message-index-gtpqnj8w.js → message-index-5qxcz6h7.js} +16 -15
  125. package/dist/{message-index-bounded-zyc8h32y.js → message-index-bounded-n0m0t7tv.js} +16 -15
  126. package/dist/{message-time-backfill-73mmm76q.js → message-time-backfill-0myx7fz3.js} +3 -3
  127. package/dist/migration-worker.js +13 -12
  128. package/dist/{model-resolution-nx97z3x7.js → model-resolution-280gmqvd.js} +1 -1
  129. package/dist/plugin/embedding-bootstrap.d.ts +3 -1
  130. package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
  131. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  132. package/dist/plugin/rpc-handlers.d.ts +8 -0
  133. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  134. package/dist/plugin/subagent-tool-policy.d.ts +9 -0
  135. package/dist/plugin/subagent-tool-policy.d.ts.map +1 -1
  136. package/dist/{project-embedding-registry-z74mhqkf.js → project-embedding-registry-s2pqgec9.js} +13 -12
  137. package/dist/raw-ordinal-warmup-worker.js +136 -101
  138. package/dist/{read-session-chunk-jjb48bt9.js → read-session-chunk-0a8vdyqp.js} +11 -10
  139. package/dist/{read-session-raw-rsc8c7qy.js → read-session-raw-y5cszf0b.js} +4 -3
  140. package/dist/recomp-orchestrator-61vyha9j.js +62 -0
  141. package/dist/{safe-notification-target-1szv1k5k.js → safe-notification-target-mkr9yzvr.js} +2 -2
  142. package/dist/{search-archive-6vm0e2f5.js → search-archive-8q9s49p5.js} +12 -11
  143. package/dist/{search-xsqk1bj4.js → search-v1y9ejws.js} +25 -24
  144. package/dist/{send-session-notification-6ve0e8p4.js → send-session-notification-0k6qzydk.js} +7 -6
  145. package/dist/shared/logger.d.ts.map +1 -1
  146. package/dist/shared/model-resolution.d.ts +2 -0
  147. package/dist/shared/model-resolution.d.ts.map +1 -1
  148. package/dist/shared/prompt-async-transport.d.ts +3 -0
  149. package/dist/shared/prompt-async-transport.d.ts.map +1 -1
  150. package/dist/shared/rpc-types.d.ts +7 -0
  151. package/dist/shared/rpc-types.d.ts.map +1 -1
  152. package/dist/shared/sqlite.d.ts +1 -1
  153. package/dist/shared/sqlite.d.ts.map +1 -1
  154. package/dist/shared/subagent-runner.d.ts +2 -0
  155. package/dist/shared/subagent-runner.d.ts.map +1 -1
  156. package/dist/shared/worker-shutdown.d.ts +68 -0
  157. package/dist/shared/worker-shutdown.d.ts.map +1 -0
  158. package/dist/shared/worker-shutdown.fixture.d.ts +2 -0
  159. package/dist/shared/worker-shutdown.fixture.d.ts.map +1 -0
  160. package/dist/{sqlite-zf72c52d.js → sqlite-1rpvw2rj.js} +1 -1
  161. package/dist/{storage-memory-y3qmy00r.js → storage-memory-nm7v82mj.js} +2 -2
  162. package/dist/{storage-tags-r7k9tjcv.js → storage-tags-r6nk29n4.js} +5 -5
  163. package/dist/{task-config-x3qmayd2.js → task-config-t6bpyka7.js} +2 -2
  164. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  165. package/dist/{transform-postprocess-phase-jj99r7z2.js → transform-postprocess-phase-vtrgb7m6.js} +34 -31
  166. package/dist/v2/auto-search-worker.js +48 -9
  167. package/dist/v2/chunk-embedding-write-worker.js +30 -23
  168. package/dist/v2/{compaction-marker-candidates-ebx3388k.js → compaction-marker-candidates-cfab70cs.js} +3 -3
  169. package/dist/v2/compaction-marker-candidates-worker.js +2 -2
  170. package/dist/v2/compartment-chunk-embedding-nbdqx1td.js +64 -0
  171. package/dist/v2/{context-y5yamxak.js → context-cc33tv2z.js} +1189 -386
  172. package/dist/v2/{derive-budgets-2zh4gm2c.js → derive-budgets-knf763tt.js} +3 -3
  173. package/dist/v2/embedding-backfill-yxv2h5mc.js +24 -0
  174. package/dist/v2/embedding-worker-process.js +2 -2
  175. package/dist/v2/embedding-worker.js +5 -5
  176. package/dist/v2/hidden-child-record.d.ts +2 -0
  177. package/dist/v2/hidden-child-record.d.ts.map +1 -1
  178. package/dist/v2/hidden-completion.d.ts +2 -0
  179. package/dist/v2/hidden-completion.d.ts.map +1 -1
  180. package/dist/v2/hidden-model-activity.d.ts +7 -0
  181. package/dist/v2/hidden-model-activity.d.ts.map +1 -0
  182. package/dist/v2/{history-owner-42e16w0n.js → history-owner-ad0crnrn.js} +2 -2
  183. package/dist/v2/hooks/context.d.ts.map +1 -1
  184. package/dist/v2/hooks/generate.d.ts +36 -1
  185. package/dist/v2/hooks/generate.d.ts.map +1 -1
  186. package/dist/v2/hooks/lkg-system.d.ts +35 -4
  187. package/dist/v2/hooks/lkg-system.d.ts.map +1 -1
  188. package/dist/v2/hooks/payload.d.ts +16 -1
  189. package/dist/v2/hooks/payload.d.ts.map +1 -1
  190. package/dist/v2/{logger-7qt02bnb.js → logger-p34mjtja.js} +1 -1
  191. package/dist/v2/{message-fts-rowid-map-wfx67gfd.js → message-fts-rowid-map-dg12wymk.js} +6 -5
  192. package/dist/v2/{message-index-bounded-spd8r7pj.js → message-index-bounded-f4e01xk0.js} +16 -15
  193. package/dist/v2/{message-index-8vz2pq76.js → message-index-ydzrp6y6.js} +16 -15
  194. package/dist/v2/{message-time-backfill-04t0km1z.js → message-time-backfill-ddh8n9gy.js} +3 -3
  195. package/dist/v2/migration-worker.js +13 -12
  196. package/dist/v2/{model-resolution-nx97z3x7.js → model-resolution-280gmqvd.js} +1 -1
  197. package/dist/v2/{project-embedding-registry-gnkj56xp.js → project-embedding-registry-deza9ksw.js} +13 -12
  198. package/dist/v2/raw-ordinal-warmup-worker.js +136 -101
  199. package/dist/v2/{read-session-chunk-cwkxrmns.js → read-session-chunk-8cxfagky.js} +11 -10
  200. package/dist/v2/{read-session-raw-yaegtjzh.js → read-session-raw-1nrrecvx.js} +4 -3
  201. package/dist/v2/recomp-orchestrator-47m4hv5g.js +61 -0
  202. package/dist/v2/{safe-notification-target-qg7n2s77.js → safe-notification-target-khnzg57c.js} +2 -2
  203. package/dist/v2/{search-archive-wve3tq1k.js → search-archive-e80cvc09.js} +12 -11
  204. package/dist/v2/{search-hwg7jfbj.js → search-fjz746zr.js} +25 -24
  205. package/dist/v2/{send-session-notification-3pxn658x.js → send-session-notification-nwvrv34d.js} +7 -6
  206. package/dist/v2/{server-8by8qfec.js → server-0epqaxhd.js} +75 -57
  207. package/dist/v2/{server-pwv4ezb0.js → server-168pb207.js} +1 -1
  208. package/dist/v2/{server-h0410h0v.js → server-1bw1wcbp.js} +1 -1
  209. package/dist/v2/{server-beht37jy.js → server-1zx2pa5d.js} +1 -1
  210. package/dist/v2/{server-a9xqj88f.js → server-230fnbws.js} +4 -4
  211. package/dist/v2/{server-tbe1femw.js → server-29qp8nz4.js} +1 -1
  212. package/dist/v2/{server-tgnbmwah.js → server-3mz2qh5a.js} +1 -1
  213. package/dist/v2/{server-hy3d3vsx.js → server-4nw4fqhr.js} +2 -2
  214. package/dist/v2/{server-45q69hkq.js → server-4sxjs6hn.js} +5 -5
  215. package/dist/v2/{server-34kwfsr4.js → server-53eh1r8r.js} +2 -2
  216. package/dist/v2/{server-xj136kt8.js → server-55rgxfrw.js} +9 -3
  217. package/dist/v2/{server-nj659894.js → server-5arr9ecn.js} +2 -2
  218. package/dist/{index-8cd2j99z.js → v2/server-5kym00ag.js} +32 -13
  219. package/dist/v2/{server-2ar62dyx.js → server-63fqdghs.js} +106 -20
  220. package/dist/v2/{server-f2xf5gcb.js → server-6495nmn9.js} +12 -15
  221. package/dist/v2/{server-qd11g795.js → server-92g7d776.js} +2 -1
  222. package/dist/v2/{server-xq7dfjke.js → server-9x0kmta4.js} +5 -5
  223. package/dist/v2/{server-27gq4mfz.js → server-a3dwxfgd.js} +4 -4
  224. package/dist/v2/{server-6tmj0s7j.js → server-af2pght7.js} +3 -3
  225. package/dist/v2/{server-1wy7b9de.js → server-br1x0tev.js} +3 -3
  226. package/dist/v2/{server-n1prf1g6.js → server-brj8j2gk.js} +2 -2
  227. package/dist/v2/{server-6vdzn1td.js → server-c7dxxsj7.js} +308 -61
  228. package/dist/v2/server-cpjk5jd2.js +82 -0
  229. package/dist/v2/{server-g3qma5c0.js → server-dj7tz4ph.js} +2 -2
  230. package/dist/v2/{server-9hx7g5jp.js → server-ej96a39v.js} +17 -9
  231. package/dist/v2/{server-6pmqg9m4.js → server-gyy4k6mf.js} +1 -1
  232. package/dist/v2/{server-bmymkx73.js → server-hqzyq8n4.js} +11 -11
  233. package/dist/v2/{server-h1v0pyxb.js → server-j4jnp9b5.js} +468 -18
  234. package/dist/v2/{server-da07v4xp.js → server-k3t06fxr.js} +1 -1
  235. package/dist/v2/{server-gsxjv2q2.js → server-m91f9m5s.js} +69 -17
  236. package/dist/v2/{server-rmygf5pn.js → server-ne8arh8t.js} +2 -2
  237. package/dist/v2/{server-hm38q7r0.js → server-vn2nwcv6.js} +5 -5
  238. package/dist/v2/{server-46neh5fa.js → server-wyawsa88.js} +314 -127
  239. package/dist/v2/{server-zzkj2fch.js → server-xsryvyf6.js} +4 -4
  240. package/dist/v2/{server-n37sebck.js → server-y4a3nhtk.js} +1 -1
  241. package/dist/v2/{server-d04vrx0j.js → server-ygtykank.js} +2 -2
  242. package/dist/v2/server.js +6 -6
  243. package/dist/v2/{sqlite-zf72c52d.js → sqlite-1rpvw2rj.js} +1 -1
  244. package/dist/v2/{storage-memory-y3qmy00r.js → storage-memory-nm7v82mj.js} +2 -2
  245. package/dist/v2/{storage-tags-3wdb8zph.js → storage-tags-ss08kj5r.js} +5 -5
  246. package/dist/v2/store-reader.d.ts +8 -0
  247. package/dist/v2/store-reader.d.ts.map +1 -1
  248. package/dist/v2/{task-config-nvz8mapa.js → task-config-7md27rx8.js} +2 -2
  249. package/dist/v2/{wrapup-orchestrator-embdz8gj.js → wrapup-orchestrator-639whfhq.js} +32 -31
  250. package/dist/wrapup-orchestrator-mnvt2g8m.js +49 -0
  251. package/package.json +1 -1
  252. package/src/config/index.test.ts +28 -6
  253. package/src/shared/logger.test.ts +42 -1
  254. package/src/shared/logger.ts +11 -13
  255. package/src/shared/model-resolution.test.ts +67 -12
  256. package/src/shared/model-resolution.ts +43 -16
  257. package/src/shared/model-suggestion-retry.ts +1 -1
  258. package/src/shared/prompt-async-transport.ts +47 -3
  259. package/src/shared/rpc-types.ts +7 -0
  260. package/src/shared/sqlite-busy-budget-review.test.ts +6 -1
  261. package/src/shared/sqlite.ts +4 -2
  262. package/src/shared/subagent-runner.ts +2 -0
  263. package/src/shared/worker-shutdown-fence.test.ts +87 -0
  264. package/src/shared/worker-shutdown.fixture.ts +25 -0
  265. package/src/shared/worker-shutdown.test.ts +127 -0
  266. package/src/shared/worker-shutdown.ts +160 -0
  267. package/dist/embedding-backfill-fmz50tsy.js +0 -24
  268. package/dist/recomp-orchestrator-999jj4bc.js +0 -61
  269. package/dist/v2/embedding-backfill-7c7yr69y.js +0 -23
  270. package/dist/v2/recomp-orchestrator-f6m9jr7p.js +0 -60
  271. package/dist/wrapup-orchestrator-whhbjmaz.js +0 -48
@@ -44,6 +44,11 @@ import {
44
44
  HiddenChildHook,
45
45
  parseProviderModel,
46
46
  toModelEntry,
47
+ ModelProducedNoOutputError,
48
+ noteModelActivityMonitored,
49
+ noteModelOutputReceived,
50
+ annotateSubagentInvocationError,
51
+ recordChildInvocation,
47
52
  CTX_NOTE_LIGHT_DESCRIPTION,
48
53
  ACTIVE_TOOL_IDS,
49
54
  createPromptSurfaceRuntime,
@@ -54,7 +59,7 @@ import {
54
59
  rebaseSessionCoordinatesAsync,
55
60
  resolveOpenCodeProtectedTailBoundary,
56
61
  getActiveCompartmentRun
57
- } from "./index-rpxdjkm0.js";
62
+ } from "./index-v7r4td4c.js";
58
63
  import"./index-sd3egckz.js";
59
64
  import {
60
65
  getHarness2
@@ -66,7 +71,7 @@ import {
66
71
  import {
67
72
  log2,
68
73
  sessionLog2
69
- } from "./index-j75v2476.js";
74
+ } from "./index-h7tgn49j.js";
70
75
  import {
71
76
  isSaneLimit,
72
77
  setOutputReserveConfig,
@@ -76,7 +81,7 @@ import {
76
81
  deriveHistorianChunkTokens2,
77
82
  resolveKnownHistorianContextLimit2,
78
83
  resolveHistorianContextLimit2
79
- } from "./index-v10f1rjv.js";
84
+ } from "./index-spwjbkc7.js";
80
85
  import"./index-wgypt3cs.js";
81
86
  import {
82
87
  CANONICAL_DREAM_TASKS,
@@ -86,7 +91,7 @@ import {
86
91
  buildDreamTaskRuntimeConfigs2,
87
92
  userObservationCollectionEnabled2,
88
93
  userObservationsRequested2
89
- } from "./index-p5y3k4g7.js";
94
+ } from "./index-nda0zgna.js";
90
95
  import {
91
96
  logConfigDependencyNotesOnce,
92
97
  runSessionProjectBackfill,
@@ -132,6 +137,8 @@ import {
132
137
  createMessagesTransformHandler,
133
138
  subagentToolRefusal,
134
139
  hideSubagentTools,
140
+ removePrimaryOnlyTools,
141
+ storedSubagentMode,
135
142
  createCtxExpandTools,
136
143
  createCtxMemoryTools,
137
144
  createCtxMemoryListTools,
@@ -143,10 +150,10 @@ import {
143
150
  applyJsonSchemaParameterDescriptions,
144
151
  MagicContextRpcServer,
145
152
  subagentTemperature
146
- } from "./index-3esx8tkf.js";
153
+ } from "./index-t7hx3qcb.js";
147
154
  import {
148
155
  resolveHistorianModel2
149
- } from "./index-8cd2j99z.js";
156
+ } from "./index-5kym00ag.js";
150
157
  import {
151
158
  formatFailClosedBlockingMessage,
152
159
  formatFailClosedBlockingSummary,
@@ -158,12 +165,12 @@ import {
158
165
  openDatabaseAsync,
159
166
  isDatabasePersisted,
160
167
  getDatabasePersistenceError
161
- } from "./index-jrr131e0.js";
168
+ } from "./index-rmd0069m.js";
162
169
  import {
163
170
  setHomeProjectPermission,
164
171
  resolveProjectIdentityForSession,
165
172
  scheduleAfterBootQuiet
166
- } from "./index-2vxtcb95.js";
173
+ } from "./index-vkc1ca9p.js";
167
174
  import {
168
175
  needsBlockedRead,
169
176
  markHostUnservedRow,
@@ -198,31 +205,32 @@ import {
198
205
  cleanUserText2,
199
206
  readRawSessionMessageIdOrdinalsForRange2,
200
207
  readRawSessionMessageOrdinalById2
201
- } from "./index-9zcsy3hh.js";
208
+ } from "./index-x4k3f4mf.js";
202
209
  import {
203
210
  invalidateAutoEmbedSession,
204
211
  clearEmbedSessionState
205
- } from "./index-ze7mvk54.js";
212
+ } from "./index-2yhtnfcf.js";
206
213
  import {
207
214
  hasMeaningfulUserText2,
208
215
  preloadTokenizer,
209
216
  estimateTokens
210
- } from "./index-c5pytzne.js";
211
- import"./index-6x57ar45.js";
217
+ } from "./index-b88dwwrh.js";
218
+ import"./index-adk2z5d8.js";
212
219
  import {
213
220
  inRootAsyncContext2,
214
221
  withSqliteTransformPass2,
215
222
  withoutSqliteTransformPass2,
216
223
  isTransientSqliteError2,
217
224
  withAsyncPrivilegedWriter2
218
- } from "./index-beht37jy.js";
225
+ } from "./index-1zx2pa5d.js";
219
226
  import"./index-v0p37hm2.js";
220
- import"./index-s734jcsr.js";
221
- import"./index-a6mc0v4d.js";
227
+ import"./index-cpjk5jd2.js";
228
+ import"./index-35qc6606.js";
229
+ import"./index-jmycsey7.js";
222
230
  import {
223
- deleteChunkEmbedBackoffForSession
224
- } from "./index-b5vqckbw.js";
225
- import"./index-nj7yykkx.js";
231
+ deleteChunkEmbedBackoffForSession2
232
+ } from "./index-153r2q6z.js";
233
+ import"./index-c7phnbvk.js";
226
234
  import {
227
235
  BoundedSessionMap,
228
236
  advanceSessionActivity,
@@ -231,29 +239,30 @@ import {
231
239
  RAW_MESSAGE_TYPES,
232
240
  V2StoreReaderPool,
233
241
  V2StoreReader
234
- } from "./index-se4m2g6w.js";
235
- import"./index-bp5083x2.js";
242
+ } from "./index-48stjd56.js";
243
+ import"./index-x9k3mqrf.js";
236
244
  import"./index-1zx87sdm.js";
237
245
  import {
238
246
  stripPersistedAssistantText,
239
247
  currentReclaimableToolOutputCount,
248
+ isRecord,
240
249
  isDroppedToolOutput,
241
250
  evaluateChannel2,
242
251
  buildChannel2Reminder
243
- } from "./index-cf74k5ak.js";
252
+ } from "./index-305y133n.js";
244
253
  import"./index-58e3y90n.js";
245
- import"./index-kq82mtg0.js";
254
+ import"./index-11zf2wwc.js";
246
255
  import {
247
256
  getCurrentToolSetHash,
248
257
  recordToolDefinition
249
- } from "./index-ke416mdc.js";
258
+ } from "./index-j76ah6d7.js";
250
259
  import"./index-fr0wbhdn.js";
251
- import"./index-63k48rv9.js";
260
+ import"./index-pnjwa6qa.js";
252
261
  import"./index-fb3zxn06.js";
253
262
  import {
254
263
  renderUserFacingFailure,
255
264
  userFacingFailureCode
256
- } from "./index-3h4dp9wb.js";
265
+ } from "./index-1pefp8ar.js";
257
266
  import {
258
267
  createTagger,
259
268
  cavemanWordRulesForLanguage,
@@ -262,29 +271,29 @@ import {
262
271
  EmergencyFailClosedError,
263
272
  DegradedPassRefusalError,
264
273
  isSyntheticHeadMessage2
265
- } from "./index-jhghdnsm.js";
266
- import"./index-4s3t0nd0.js";
274
+ } from "./index-67nyj0gy.js";
275
+ import"./index-616rsjrv.js";
267
276
  import"./index-qt1qqasc.js";
268
- import"./index-rr2bb45z.js";
277
+ import"./index-c4b76d4t.js";
269
278
  import"./index-4dhv7mqz.js";
270
- import"./index-bjcnntmz.js";
271
- import"./index-24fezq97.js";
272
- import"./index-n37sebck.js";
279
+ import"./index-0wthn7fp.js";
280
+ import"./index-jr5na10t.js";
281
+ import"./index-y4a3nhtk.js";
273
282
  import {
274
283
  pushNotification2,
275
284
  isTuiConnected2
276
285
  } from "./index-x8a7jmkh.js";
277
- import"./index-y9f76s3f.js";
278
- import"./index-s74zqahq.js";
279
- import"./index-dxmq29t1.js";
280
- import"./index-c1p88z1y.js";
286
+ import"./index-rrv26qjz.js";
287
+ import"./index-kc9pn495.js";
288
+ import"./index-dc8hy95c.js";
289
+ import"./index-jfh3cktr.js";
281
290
  import"./index-gp3kcpc4.js";
282
291
  import {
283
292
  detectConflicts
284
- } from "./index-kee4kn5j.js";
293
+ } from "./index-4pnsgvfk.js";
285
294
  import"./index-fmsr7v69.js";
286
295
  import"./index-kaqs6h31.js";
287
- import"./index-edmpdxcw.js";
296
+ import"./index-d6rp4dxh.js";
288
297
  import {
289
298
  isDreamerRunnable,
290
299
  isSmartNoteSurfaceAvailable,
@@ -296,7 +305,7 @@ import {
296
305
  import {
297
306
  getErrorMessage
298
307
  } from "./index-y8v6yerm.js";
299
- import"./index-k29z4aqh.js";
308
+ import"./index-t5pck3ss.js";
300
309
 
301
310
  // src/v2/hooks/context.ts
302
311
  import { setTimeout as delay } from "node:timers/promises";
@@ -350,7 +359,7 @@ function dropCompartmentsAfter(db, sessionId, anchor, holderId, activeBranch = f
350
359
  if (marker && clearPendingPiCompactionMarkerStateIf(db, sessionId, marker, null))
351
360
  clearedMarker = marker;
352
361
  }
353
- deleteChunkEmbedBackoffForSession(db, sessionId);
362
+ deleteChunkEmbedBackoffForSession2(db, sessionId);
354
363
  queueM0Mutation(db, { sessionId, mutationType: "recomp_boundary_change" });
355
364
  clearCachedM0M1(db, sessionId);
356
365
  db.exec("COMMIT");
@@ -602,9 +611,9 @@ function trimToRecordedBoundary(db, sessionId, messages) {
602
611
  }
603
612
 
604
613
  // src/v2/fold/host-media.ts
605
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
614
+ var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
606
615
  function isClassInstance(value) {
607
- if (!isRecord(value))
616
+ if (!isRecord2(value))
608
617
  return false;
609
618
  const prototype = Object.getPrototypeOf(value);
610
619
  return prototype !== Object.prototype && prototype !== null;
@@ -623,10 +632,10 @@ function rememberHostMedia(messages) {
623
632
  if (!Array.isArray(content))
624
633
  continue;
625
634
  for (const part of content) {
626
- if (!isRecord(part) || part.type !== "media")
635
+ if (!isRecord2(part) || part.type !== "media")
627
636
  continue;
628
637
  const media = part.media;
629
- if (isClassInstance(media) && isRecord(media.source)) {
638
+ if (isClassInstance(media) && isRecord2(media.source)) {
630
639
  rememberedAssetClass = Object.getPrototypeOf(media).constructor;
631
640
  return;
632
641
  }
@@ -683,7 +692,7 @@ function hostMediaAsset(data, mediaType) {
683
692
  return hostMediaFromEncoded({ source: { type: "base64", data, mediaType } });
684
693
  }
685
694
  function hostMediaFromEncoded(value) {
686
- if (!isRecord(value.source))
695
+ if (!isRecord2(value.source))
687
696
  return "missing Media.Asset source";
688
697
  const encoded = structuredClone(value);
689
698
  if (encoded.source.type === "bytes") {
@@ -1094,18 +1103,56 @@ function containsHostInstance(value) {
1094
1103
  return false;
1095
1104
  }
1096
1105
  function clonePreservingInstances(value) {
1097
- if (isHostInstance(value))
1106
+ return cloneCounting(value, undefined);
1107
+ }
1108
+ function clonePreservingInstancesMeasured(value) {
1109
+ const meter = { bytes: 0 };
1110
+ const copy = cloneCounting(value, meter);
1111
+ return { copy, bytes: meter.bytes };
1112
+ }
1113
+ function cloneCounting(value, meter) {
1114
+ if (isHostInstance(value)) {
1115
+ if (meter)
1116
+ meter.bytes += instanceBytes(value, new WeakSet);
1098
1117
  return value;
1099
- if (Array.isArray(value))
1100
- return value.map(clonePreservingInstances);
1118
+ }
1119
+ if (Array.isArray(value)) {
1120
+ if (meter)
1121
+ meter.bytes += 16 + 8 * value.length;
1122
+ return value.map((entry) => cloneCounting(entry, meter));
1123
+ }
1101
1124
  if (value && typeof value === "object") {
1102
1125
  const copy = {};
1103
- for (const [key, entry] of Object.entries(value))
1104
- copy[key] = clonePreservingInstances(entry);
1126
+ if (meter)
1127
+ meter.bytes += 32;
1128
+ for (const [key, entry] of Object.entries(value)) {
1129
+ if (meter)
1130
+ meter.bytes += 16;
1131
+ copy[key] = cloneCounting(entry, meter);
1132
+ }
1105
1133
  return copy;
1106
1134
  }
1135
+ if (meter)
1136
+ meter.bytes += typeof value === "string" ? 2 * value.length : 8;
1107
1137
  return value;
1108
1138
  }
1139
+ function instanceBytes(value, seen) {
1140
+ if (typeof value === "string")
1141
+ return 2 * value.length;
1142
+ if (!value || typeof value !== "object")
1143
+ return 8;
1144
+ if (seen.has(value))
1145
+ return 0;
1146
+ seen.add(value);
1147
+ if (ArrayBuffer.isView(value))
1148
+ return value.byteLength;
1149
+ if (value instanceof ArrayBuffer)
1150
+ return value.byteLength;
1151
+ let bytes = 32;
1152
+ for (const entry of Object.values(value))
1153
+ bytes += 16 + instanceBytes(entry, seen);
1154
+ return bytes;
1155
+ }
1109
1156
  function contentKey(value) {
1110
1157
  const plain = (entry) => {
1111
1158
  if (ArrayBuffer.isView(entry)) {
@@ -1161,7 +1208,7 @@ function rebuildFileContent(value, output, attachments) {
1161
1208
  rebuilt.unshift({ type: "text", text: output });
1162
1209
  return { type: "content", value: rebuilt };
1163
1210
  }
1164
- function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map) {
1211
+ function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map, hiddenTimes = false) {
1165
1212
  const existingHeads = new Map(draft.messages.filter((m) => HEAD_IDS.some((id) => m.id === id)).map((m) => [m.id, m]));
1166
1213
  const source = draft.messages.filter((m) => !existingHeads.has(m.id));
1167
1214
  const results = new Map;
@@ -1280,6 +1327,16 @@ function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map) {
1280
1327
  },
1281
1328
  parts
1282
1329
  };
1330
+ if (hiddenTimes && mapped.info.time !== undefined) {
1331
+ const time = mapped.info.time;
1332
+ delete mapped.info.time;
1333
+ Object.defineProperty(mapped.info, "time", {
1334
+ value: time,
1335
+ enumerable: false,
1336
+ configurable: true,
1337
+ writable: true
1338
+ });
1339
+ }
1283
1340
  originals.set(mapped, message);
1284
1341
  if (isCoveredInstructionRow(message))
1285
1342
  markCoveredInstructionRow(mapped.info);
@@ -2675,10 +2732,12 @@ function assistantText(row) {
2675
2732
 
2676
2733
  class HiddenProviderError extends Error {
2677
2734
  settled;
2735
+ hostError;
2678
2736
  constructor(detail, options = {}) {
2679
2737
  super(`Hidden completion provider error: ${detail}`);
2680
2738
  this.name = "HiddenProviderError";
2681
2739
  this.settled = options.settled ?? true;
2740
+ this.hostError = options.hostError;
2682
2741
  }
2683
2742
  }
2684
2743
  function requestModel(request, current) {
@@ -2742,7 +2801,9 @@ async function awaitAssistantRow(openReader, readSessionError, localFailure, chi
2742
2801
  `terminal_row=${errorText(newIdle)}`,
2743
2802
  `session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
2744
2803
  ];
2745
- throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
2804
+ throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`, {
2805
+ cause: sessionError
2806
+ }) : new HiddenProviderError(details.join("; "), { hostError: sessionError });
2746
2807
  }
2747
2808
  if (outcome === "succeeded" && newAssistant)
2748
2809
  return newAssistant;
@@ -2756,7 +2817,9 @@ async function awaitAssistantRow(openReader, readSessionError, localFailure, chi
2756
2817
  `terminal_row=${errorText(newAssistant)}`,
2757
2818
  `session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
2758
2819
  ];
2759
- throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
2820
+ throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`, {
2821
+ cause: sessionError
2822
+ }) : new HiddenProviderError(details.join("; "), { hostError: sessionError });
2760
2823
  }
2761
2824
  if (newAssistant.data.error !== undefined) {
2762
2825
  throw new HiddenProviderError(errorText(newAssistant.data.error), {
@@ -2911,7 +2974,13 @@ async function createV2HiddenCompletionExecutor(host, options) {
2911
2974
  const head = await resolveHead(identity);
2912
2975
  const active = await lifecycle.open(identity, role, head);
2913
2976
  openedChild = active;
2914
- const handle = { id: active.id, childSessionId: active.id };
2977
+ const configuredModel = toModelEntry(identity.model);
2978
+ const handle = {
2979
+ id: active.id,
2980
+ childSessionId: active.id,
2981
+ attemptedModel: modelKey(head),
2982
+ ...configuredModel?.sourceConfigKey ? { modelConfigKey: configuredModel.sourceConfigKey } : {}
2983
+ };
2915
2984
  const tokenBudget = identity.metadata?.tokenBudget;
2916
2985
  const run = {
2917
2986
  identity,
@@ -2942,6 +3011,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
2942
3011
  }
2943
3012
  },
2944
3013
  async attempt(handle, request) {
3014
+ const startedAt = Date.now();
2945
3015
  const run = runs.get(handle);
2946
3016
  if (!run)
2947
3017
  throw new Error("Unknown hidden completion run");
@@ -2959,6 +3029,10 @@ async function createV2HiddenCompletionExecutor(host, options) {
2959
3029
  throw new Error("Hidden completion prompt aborted");
2960
3030
  }
2961
3031
  const requested = await validateVariant(requestModel(request, run.child.model));
3032
+ const requestedRef = modelKey(requested);
3033
+ const configuredModel = [run.identity.model, ...run.identity.configuredModels ?? []].map(toModelEntry).find((entry) => entry?.model === requestedRef);
3034
+ handle.attemptedModel = requestedRef;
3035
+ handle.modelConfigKey = configuredModel?.sourceConfigKey ?? handle.modelConfigKey;
2962
3036
  if (run.identity.kind !== "dreamer-task" && request.body.temperature === undefined) {
2963
3037
  const configured = options.historianTemperature?.();
2964
3038
  if (typeof configured === "number" && Number.isFinite(configured))
@@ -3053,6 +3127,22 @@ async function createV2HiddenCompletionExecutor(host, options) {
3053
3127
  abortReject = reject;
3054
3128
  });
3055
3129
  const onAbort = () => {
3130
+ const reason = request.signal?.reason;
3131
+ if (reason instanceof ModelProducedNoOutputError && run.identity.kind === "dreamer-task") {
3132
+ recordChildInvocation({
3133
+ db: options.db,
3134
+ parentSessionId: run.identity.parentSessionId ?? options.projectIdentity,
3135
+ parentInvocationId: run.identity.parentInvocationId,
3136
+ harness: "opencode2",
3137
+ subagent: "dreamer",
3138
+ task: run.identity.title.replace(/^magic-context-dream-/, ""),
3139
+ startedAt,
3140
+ status: "timed_out",
3141
+ error: reason,
3142
+ providerId: requested.providerID,
3143
+ modelId: requested.modelID
3144
+ });
3145
+ }
3056
3146
  interruptAndRetire(run, "prompt-aborted").finally(() => abortReject(new Error("Hidden completion prompt aborted")));
3057
3147
  };
3058
3148
  const deadlineTimer = setTimeout(() => {
@@ -3081,6 +3171,9 @@ async function createV2HiddenCompletionExecutor(host, options) {
3081
3171
  })
3082
3172
  };
3083
3173
  inFlight.add(entry);
3174
+ const stopWatching = host.watchModelActivity?.(run.child.id, () => noteModelOutputReceived(request.signal));
3175
+ if (stopWatching)
3176
+ noteModelActivityMonitored(request.signal);
3084
3177
  try {
3085
3178
  await Promise.race([
3086
3179
  host.prompt({ sessionID: run.child.id, text: marker }),
@@ -3136,12 +3229,20 @@ async function createV2HiddenCompletionExecutor(host, options) {
3136
3229
  usage: reportedUsage ? usage : meter(system, promptText(request), text ?? ""),
3137
3230
  lengthCapped: ["length", "max_tokens"].includes(row.data.finish ?? ""),
3138
3231
  providerId: row.data.model?.providerID ?? requested.providerID,
3139
- modelId: row.data.model?.id ?? requested.modelID
3232
+ modelId: row.data.model?.id ?? requested.modelID,
3233
+ attemptedModel: requestedRef,
3234
+ modelConfigKey: handle.modelConfigKey
3140
3235
  };
3141
3236
  if (!run.child.ever_settled)
3142
3237
  run.child = lifecycle.markEverSettled(run.child);
3143
3238
  } catch (caught) {
3144
3239
  const error = attempt.budgetExceeded ?? attempt.stepLimit ?? attempt.refusal ?? caught;
3240
+ const hostError = error instanceof HiddenProviderError ? error.hostError : error instanceof Error && error.message.startsWith("Hidden completion failed:") ? error.cause : undefined;
3241
+ annotateSubagentInvocationError(error, {
3242
+ attemptedModel: handle.attemptedModel,
3243
+ modelConfigKey: handle.modelConfigKey,
3244
+ ...hostError === undefined ? {} : { hostError }
3245
+ });
3145
3246
  run.failed = true;
3146
3247
  if (!(error instanceof HiddenProviderError)) {
3147
3248
  run.unsettledFailure = true;
@@ -3155,6 +3256,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
3155
3256
  }
3156
3257
  throw error;
3157
3258
  } finally {
3259
+ stopWatching?.();
3158
3260
  clearTimeout(deadlineTimer);
3159
3261
  if (budgetPoll)
3160
3262
  clearInterval(budgetPoll);
@@ -3210,6 +3312,30 @@ async function createV2HiddenCompletionExecutor(host, options) {
3210
3312
  };
3211
3313
  }
3212
3314
 
3315
+ // src/v2/hidden-model-activity.ts
3316
+ class HiddenModelActivity {
3317
+ watchers = new Map;
3318
+ watch(sessionID, onOutput) {
3319
+ this.watchers.set(sessionID, onOutput);
3320
+ return () => {
3321
+ if (this.watchers.get(sessionID) === onOutput)
3322
+ this.watchers.delete(sessionID);
3323
+ };
3324
+ }
3325
+ observe(event) {
3326
+ if (!isRecord(event) || !isRecord(event.data))
3327
+ return;
3328
+ const { sessionID, delta, text } = event.data;
3329
+ if (typeof sessionID !== "string")
3330
+ return;
3331
+ const streamed = ["session.text.delta", "session.reasoning.delta", "session.tool.input.delta"].includes(String(event.type)) && typeof delta === "string" && delta.length > 0;
3332
+ const ended = ["session.text.ended", "session.reasoning.ended"].includes(String(event.type)) && typeof text === "string" && text.length > 0;
3333
+ if (streamed || ended || event.type === "session.tool.input.started") {
3334
+ this.watchers.get(sessionID)?.();
3335
+ }
3336
+ }
3337
+ }
3338
+
3213
3339
  // src/v2/hooks/channel2.ts
3214
3340
  import { randomBytes } from "node:crypto";
3215
3341
  var pendingCandidates = new WeakMap;
@@ -3718,26 +3844,70 @@ function generateReplayAnchor(messages) {
3718
3844
  return;
3719
3845
  return { id, tail: clonePreservingInstances(messages.slice(index + 1)) };
3720
3846
  }
3847
+ var DEFAULT_GENERATE_REPLAY_LIMITS = Object.freeze({
3848
+ maxSessions: 16,
3849
+ sessionMaxBytes: 128 * 1024 * 1024,
3850
+ totalMaxBytes: 256 * 1024 * 1024
3851
+ });
3721
3852
 
3722
3853
  class V2GenerateReplay {
3723
3854
  prefixes = new Map;
3855
+ totalBytes = 0;
3856
+ limits;
3857
+ constructor(limits = DEFAULT_GENERATE_REPLAY_LIMITS) {
3858
+ if (!Number.isSafeInteger(limits.maxSessions) || limits.maxSessions < 1 || !Number.isSafeInteger(limits.sessionMaxBytes) || limits.sessionMaxBytes < 1 || !Number.isSafeInteger(limits.totalMaxBytes) || limits.totalMaxBytes < 1)
3859
+ throw new Error("Generate replay limits must be positive integers");
3860
+ this.limits = { ...limits };
3861
+ }
3724
3862
  capture(draft, anchor) {
3863
+ this.forget(draft.sessionID);
3725
3864
  if (!anchor) {
3726
- this.prefixes.delete(draft.sessionID);
3727
3865
  sessionLog2(draft.sessionID, "generate replay capture skipped: no-anchor");
3728
3866
  return;
3729
3867
  }
3868
+ const parts = {
3869
+ anchor: clonePreservingInstancesMeasured(anchor),
3870
+ system: clonePreservingInstancesMeasured(draft.system),
3871
+ messages: clonePreservingInstancesMeasured(draft.messages),
3872
+ tools: clonePreservingInstancesMeasured(draft.tools)
3873
+ };
3874
+ const bytes = 256 + parts.anchor.bytes + parts.system.bytes + parts.messages.bytes + parts.tools.bytes;
3875
+ if (bytes > this.limits.sessionMaxBytes || bytes > this.limits.totalMaxBytes) {
3876
+ sessionLog2(draft.sessionID, `generate replay capture skipped: over-session-cap (${bytes} > ${Math.min(this.limits.sessionMaxBytes, this.limits.totalMaxBytes)} bytes)`);
3877
+ return;
3878
+ }
3879
+ while (this.prefixes.size > 0 && (this.prefixes.size >= this.limits.maxSessions || this.totalBytes + bytes > this.limits.totalMaxBytes)) {
3880
+ const oldest = this.prefixes.keys().next().value;
3881
+ if (oldest === undefined)
3882
+ break;
3883
+ this.forget(oldest);
3884
+ }
3730
3885
  this.prefixes.set(draft.sessionID, {
3731
- anchor: clonePreservingInstances(anchor),
3886
+ anchor: parts.anchor.copy,
3732
3887
  model: `${draft.model.providerID}/${draft.model.id}`,
3733
3888
  agent: draft.agent,
3734
- system: clonePreservingInstances(draft.system),
3735
- messages: clonePreservingInstances(draft.messages),
3736
- tools: clonePreservingInstances(draft.tools)
3889
+ system: parts.system.copy,
3890
+ messages: parts.messages.copy,
3891
+ tools: parts.tools.copy,
3892
+ bytes
3737
3893
  });
3894
+ this.totalBytes += bytes;
3738
3895
  }
3739
3896
  forget(sessionID) {
3897
+ const prefix = this.prefixes.get(sessionID);
3898
+ if (!prefix)
3899
+ return;
3740
3900
  this.prefixes.delete(sessionID);
3901
+ this.totalBytes -= prefix.bytes;
3902
+ }
3903
+ stats() {
3904
+ return {
3905
+ totalBytes: this.totalBytes,
3906
+ sessions: [...this.prefixes].map(([sessionId, prefix]) => ({
3907
+ sessionId,
3908
+ bytes: prefix.bytes
3909
+ }))
3910
+ };
3741
3911
  }
3742
3912
  apply(draft) {
3743
3913
  const prefix = this.prefixes.get(draft.sessionID);
@@ -3747,6 +3917,8 @@ class V2GenerateReplay {
3747
3917
  };
3748
3918
  if (!prefix)
3749
3919
  return skip("no-prefix");
3920
+ this.prefixes.delete(draft.sessionID);
3921
+ this.prefixes.set(draft.sessionID, prefix);
3750
3922
  if (prefix.model !== `${draft.model.providerID}/${draft.model.id}`)
3751
3923
  return skip("model-mismatch");
3752
3924
  if (prefix.agent !== draft.agent)
@@ -3790,21 +3962,25 @@ function identity(slot) {
3790
3962
 
3791
3963
  class V2LkgSystemReplay {
3792
3964
  systems = new BoundedSessionMap(1000);
3793
- capture(sessionId, slot, input, served) {
3965
+ capture(sessionId, slot, input, served, head) {
3794
3966
  this.systems.set(sessionId, {
3795
3967
  slot: identity(slot),
3796
- input: JSON.stringify(input),
3797
- served: structuredClone(served)
3968
+ input: hostInputKey(input),
3969
+ served: structuredClone(served),
3970
+ head: head ? structuredClone(head) : null
3798
3971
  });
3799
3972
  }
3800
3973
  restore(sessionId, slot, input, target) {
3801
3974
  const saved = this.systems.get(sessionId);
3802
- if (!slot || !saved || saved.slot !== identity(slot) || saved.input !== JSON.stringify(input))
3803
- return false;
3975
+ if (!slot || !saved || saved.slot !== identity(slot) || saved.input !== hostInputKey(input))
3976
+ return;
3804
3977
  target.splice(0, target.length, ...structuredClone(saved.served));
3805
- return true;
3978
+ return { head: saved.head ? structuredClone(saved.head) : null };
3806
3979
  }
3807
3980
  }
3981
+ function hostInputKey(input) {
3982
+ return JSON.stringify({ system: input.system, checkpoint: input.checkpoint });
3983
+ }
3808
3984
 
3809
3985
  // src/v2/hooks/model-limit-cache.ts
3810
3986
  var warmStarted = false;
@@ -4577,6 +4753,26 @@ function persistV2UsageReading(args) {
4577
4753
  // src/v2/hooks/context.ts
4578
4754
  class V2LkgAdmissionReplay extends Error {
4579
4755
  }
4756
+ function applyCheckpointHead(draft, head) {
4757
+ const { checkpoint, submitted } = head;
4758
+ const first = draft.messages.find((message) => message.id === HEAD_IDS[0]);
4759
+ const baseline = first?.content.find((part) => part.type === "text")?.text;
4760
+ if (typeof baseline !== "string")
4761
+ return false;
4762
+ for (const part of checkpoint.content)
4763
+ if (part.type === "text" && typeof part.text === "string") {
4764
+ part.text = part.text.replace(`<summary>
4765
+ ${submitted}
4766
+ </summary>`, `<summary>
4767
+ ${baseline}
4768
+ </summary>`);
4769
+ }
4770
+ const volatile = draft.messages.find((message) => message.id === HEAD_IDS[1]);
4771
+ if (volatile && first)
4772
+ volatile.content.push(...first.content.filter((part) => part.type !== "text"));
4773
+ draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== first));
4774
+ return true;
4775
+ }
4580
4776
  var HIDDEN_SESSION_ERROR_GRACE_MS = 50;
4581
4777
  var STORE_POOL_DISPOSE_WAIT_MS = 1000;
4582
4778
  function isBlockingV2TransformError(error) {
@@ -4809,6 +5005,7 @@ async function registerContext(context) {
4809
5005
  const queriedModels = new Set;
4810
5006
  const rawLimits = new Map;
4811
5007
  const hiddenSessionErrors = new Map;
5008
+ const hiddenModelActivity = new HiddenModelActivity;
4812
5009
  const liveModels = new Map;
4813
5010
  const promptSurfaceRuntime = createPromptSurfaceRuntime({
4814
5011
  harness: "opencode2",
@@ -4903,6 +5100,7 @@ async function registerContext(context) {
4903
5100
  await cleanupLegacyOnce(database);
4904
5101
  return createV2HiddenCompletionExecutor({
4905
5102
  ...context.session,
5103
+ watchModelActivity: (sessionID, onOutput) => hiddenModelActivity.watch(sessionID, onOutput),
4906
5104
  get: async (input) => {
4907
5105
  const session = await context.session.get(input);
4908
5106
  const error = hiddenSessionErrors.get(input.sessionID);
@@ -5244,6 +5442,7 @@ async function registerContext(context) {
5244
5442
  break;
5245
5443
  const event = value;
5246
5444
  try {
5445
+ hiddenModelActivity.observe(event);
5247
5446
  if (event.type === "provider.updated" || event.type === "model.updated") {
5248
5447
  queriedModels.clear();
5249
5448
  continue;
@@ -5278,34 +5477,47 @@ async function registerContext(context) {
5278
5477
  if (event.type === "session.deleted") {
5279
5478
  clearLkgMeasuredRequest(sessionID);
5280
5479
  deletedSessions.add(sessionID);
5281
- transform?.clearSessionLogState(sessionID);
5282
- if (db) {
5283
- markSessionCleanupPending(db, sessionID);
5284
- clearSession(db, sessionID);
5480
+ const failures = [];
5481
+ try {
5482
+ transform?.clearSessionLogState(sessionID);
5483
+ if (db) {
5484
+ markSessionCleanupPending(db, sessionID);
5485
+ clearSession(db, sessionID, false, true);
5486
+ }
5487
+ } catch (error) {
5488
+ failures.push(error);
5285
5489
  }
5286
- rawProviders.get(sessionID)?.();
5287
- rawProviders.delete(sessionID);
5288
- usage.delete(sessionID);
5289
- hiddenSessionErrors.delete(sessionID);
5290
- storageNoticeBySession.delete(sessionID);
5291
- liveModels.delete(sessionID);
5292
- variants.delete(sessionID);
5293
- agents.delete(sessionID);
5294
- channel1.delete(sessionID);
5295
- commitSeenLastPass.delete(sessionID);
5296
- clearEmbedSessionState(sessionID);
5297
- historyRefreshSessions.delete(sessionID);
5298
- clearPendingMaterialization(pendingMaterializationSessions, sessionID);
5299
- lastHeuristicsTurnId.delete(sessionID);
5300
- restoredRows.forget(sessionID);
5301
- if (nativeFoldReplay)
5302
- await nativeFoldReplay.forget(sessionID);
5303
- else
5304
- await forgetNativeFoldProvenance(context.storage, sessionID);
5305
- generateReplay.forget(sessionID);
5306
- systemPromptRefreshSessions.delete(sessionID);
5307
- systemPrompt?.clearSession(sessionID);
5308
- tagger.cleanup(sessionID);
5490
+ try {
5491
+ rawProviders.get(sessionID)?.();
5492
+ rawProviders.delete(sessionID);
5493
+ usage.delete(sessionID);
5494
+ hiddenSessionErrors.delete(sessionID);
5495
+ storageNoticeBySession.delete(sessionID);
5496
+ liveModels.delete(sessionID);
5497
+ variants.delete(sessionID);
5498
+ agents.delete(sessionID);
5499
+ channel1.delete(sessionID);
5500
+ commitSeenLastPass.delete(sessionID);
5501
+ clearEmbedSessionState(sessionID);
5502
+ historyRefreshSessions.delete(sessionID);
5503
+ clearPendingMaterialization(pendingMaterializationSessions, sessionID);
5504
+ lastHeuristicsTurnId.delete(sessionID);
5505
+ restoredRows.forget(sessionID);
5506
+ if (nativeFoldReplay)
5507
+ await nativeFoldReplay.forget(sessionID);
5508
+ else
5509
+ await forgetNativeFoldProvenance(context.storage, sessionID);
5510
+ generateReplay.forget(sessionID);
5511
+ systemPromptRefreshSessions.delete(sessionID);
5512
+ systemPrompt?.clearSession(sessionID);
5513
+ tagger.cleanup(sessionID);
5514
+ } catch (error) {
5515
+ failures.push(error);
5516
+ }
5517
+ if (failures.length === 1)
5518
+ throw failures[0];
5519
+ if (failures.length > 1)
5520
+ throw new AggregateError(failures, "session deletion failed in both the store clear and the in-memory cleanup");
5309
5521
  continue;
5310
5522
  }
5311
5523
  if (event.type !== "session.execution.succeeded")
@@ -5423,6 +5635,42 @@ async function registerContext(context) {
5423
5635
  reader.close();
5424
5636
  }
5425
5637
  });
5638
+ const temporalTimes = config.temporal_awareness === true;
5639
+ const anchorTimesOnly = !temporalTimes && !rustModeModuleClient;
5640
+ const timeIds = (messages) => {
5641
+ if (temporalTimes)
5642
+ return messages.flatMap((message) => message.id ? [message.id] : []);
5643
+ if (!anchorTimesOnly)
5644
+ return [];
5645
+ const ids = [];
5646
+ for (const message of [...messages].reverse()) {
5647
+ if (message.id)
5648
+ ids.push(message.id);
5649
+ if (message.role === "assistant")
5650
+ break;
5651
+ }
5652
+ return ids;
5653
+ };
5654
+ const restoreAfterCheckpoint = (args) => {
5655
+ const { db, reader, draft, cut, boundaryRepair } = args;
5656
+ const moduleBoundaryID = rustModeModuleClient ? getPersistedCompactionMarkerState(db, draft.sessionID)?.boundaryMessageId ?? null : null;
5657
+ const moduleBoundarySeq = moduleBoundaryID ? reader.sequenceForId(draft.sessionID, moduleBoundaryID) : undefined;
5658
+ 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);
5659
+ const servedBoundary = boundaryID ? servedBoundaryRow(reader, draft.sessionID, boundaryID) : null;
5660
+ const boundary = (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;
5661
+ if (moduleBoundarySeq !== undefined)
5662
+ sessionLog2(draft.sessionID, `v2 restore: from the module boundary ${moduleBoundaryID} to the host checkpoint`);
5663
+ const present = new Set(args.messages.map((message) => message.id));
5664
+ const restored = restoredRows.rows(reader, draft.sessionID, boundary, cut.seq).filter((row) => !present.has(row.id)).flatMap((row) => restoreRow(row, draft.model, hostUsesMediaAssets() ? {
5665
+ asset: hostMediaAsset,
5666
+ unavailable: (detail) => sessionLog2(draft.sessionID, `v2 restore: attachment replaced by a note row=${detail.rowID} name=${JSON.stringify(detail.name ?? null)} mediaType=${detail.mediaType} reason=${JSON.stringify(detail.reason)}`)
5667
+ } : undefined));
5668
+ return [
5669
+ ...rustModeModuleClient ? [] : coveredInstructionRows(reader, draft.sessionID, Math.min(boundary, cut.seq), draft.model),
5670
+ ...restored,
5671
+ ...args.messages.filter((message) => message !== args.incoming)
5672
+ ];
5673
+ };
5426
5674
  const runManagedContext = async (draft) => {
5427
5675
  rememberHostMedia(draft.messages);
5428
5676
  if (hiddenChildHook.apply(draft))
@@ -5434,12 +5682,18 @@ async function registerContext(context) {
5434
5682
  return;
5435
5683
  const systemAtEntry = structuredClone(draft.system);
5436
5684
  const slotAtEntry = getSlot(draft.sessionID);
5685
+ let checkpointAtEntry;
5686
+ let replayHead;
5687
+ const hostInput = () => checkpointAtEntry === undefined ? undefined : { system: systemAtEntry, checkpoint: checkpointAtEntry };
5437
5688
  const restoreLkgSystem = () => {
5438
5689
  retirePendingSystemPromptDelivery(draft.sessionID);
5439
- if (!lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), systemAtEntry, draft.system)) {
5690
+ const input = hostInput();
5691
+ const restored = input && lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), input, draft.system);
5692
+ if (!restored) {
5440
5693
  sessionLog2(draft.sessionID, "lkg_system_state_mismatch");
5441
5694
  throw new Error("LKG system identity is unavailable or changed");
5442
5695
  }
5696
+ replayHead = restored.head;
5443
5697
  };
5444
5698
  const isMagicContextSynthetic = (id) => isAdmittedSynthetic(context, draft.sessionID, id);
5445
5699
  const newest = draft.messages.at(-1);
@@ -5448,6 +5702,24 @@ async function registerContext(context) {
5448
5702
  return;
5449
5703
  }
5450
5704
  await dropStorageNotices(draft.messages, isMagicContextSynthetic);
5705
+ const hostMessagesAtEntry = [...draft.messages];
5706
+ const passTimes = new Map;
5707
+ const readTimes = (reader, messages) => {
5708
+ const ids = timeIds(messages);
5709
+ const missing = ids.filter((id) => !passTimes.has(id));
5710
+ if (missing.length > 0) {
5711
+ const read = reader.messageTimes(draft.sessionID, missing);
5712
+ for (const id of missing)
5713
+ passTimes.set(id, read.get(id) ?? null);
5714
+ }
5715
+ const times = new Map;
5716
+ for (const id of ids) {
5717
+ const time = passTimes.get(id);
5718
+ if (time)
5719
+ times.set(id, time);
5720
+ }
5721
+ return times;
5722
+ };
5451
5723
  liveModels.set(draft.sessionID, {
5452
5724
  providerID: draft.model.providerID,
5453
5725
  modelID: draft.model.id
@@ -5459,8 +5731,9 @@ async function registerContext(context) {
5459
5731
  applyV2PromptSurfaceTools(draft, promptSurfaceRuntime, config.prompt_surface, isSmartNoteSurfaceAvailable(config));
5460
5732
  const admissionDb = db ?? storage.current();
5461
5733
  const replayFits = (messages) => {
5462
- const system = structuredClone(draft.system);
5463
- if (!admissionDb || !draft.tools || !lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), draft.system, system))
5734
+ const system = [];
5735
+ const input = hostInput();
5736
+ if (!admissionDb || !draft.tools || !input || !lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), input, system))
5464
5737
  return false;
5465
5738
  const limit = lkgReplayLimit({
5466
5739
  db: admissionDb,
@@ -5495,14 +5768,75 @@ async function registerContext(context) {
5495
5768
  })
5496
5769
  }).fit === "under";
5497
5770
  };
5771
+ const buildReplayInput = async () => {
5772
+ let messages = [...hostMessagesAtEntry];
5773
+ const admitted = new Set;
5774
+ let times;
5775
+ try {
5776
+ const reader = openStoreReader();
5777
+ try {
5778
+ const cut = reader.latestCompaction(draft.sessionID);
5779
+ const localCut = cut && isLocalCheckpoint(cut) ? cut : undefined;
5780
+ const incoming = localCut && messages.find((message) => message.id === localCut.id);
5781
+ if (localCut && !incoming || cut && nativeFoldReplay)
5782
+ return;
5783
+ checkpointAtEntry = incoming || null;
5784
+ const modeDb = db ?? storage.current();
5785
+ const subagent = modeDb ? storedSubagentMode(modeDb, draft.sessionID) : undefined;
5786
+ if (subagent === undefined)
5787
+ return;
5788
+ if (subagent)
5789
+ removePrimaryOnlyTools(draft.tools);
5790
+ if (!rustModeModuleClient) {
5791
+ const candidates = syntheticCandidates(context, draft.sessionID, reader.syntheticMessageIDs(draft.sessionID));
5792
+ for (const message of messages)
5793
+ if (message.id && candidates.has(message.id) && await isAdmittedSynthetic(context, draft.sessionID, message.id))
5794
+ admitted.add(message.id);
5795
+ const replayDb = db ?? storage.current();
5796
+ if (localCut && incoming && replayDb)
5797
+ messages = restoreAfterCheckpoint({
5798
+ db: replayDb,
5799
+ reader,
5800
+ draft,
5801
+ messages,
5802
+ cut: localCut,
5803
+ incoming,
5804
+ boundaryRepair: undefined
5805
+ });
5806
+ else if (localCut)
5807
+ return;
5808
+ times = readTimes(reader, messages);
5809
+ }
5810
+ } finally {
5811
+ reader.close();
5812
+ }
5813
+ } catch (error) {
5814
+ sessionLog2(draft.sessionID, "lkg replay input unavailable", error);
5815
+ return;
5816
+ }
5817
+ const replayDraft = { ...draft, messages };
5818
+ return {
5819
+ draft: replayDraft,
5820
+ mapped: adaptPayload(replayDraft, admitted, times, anchorTimesOnly)
5821
+ };
5822
+ };
5823
+ const adoptReplay = (replayed) => {
5824
+ if (replayed !== draft)
5825
+ draft.messages.splice(0, draft.messages.length, ...replayed.messages);
5826
+ if (replayHead)
5827
+ applyCheckpointHead(draft, replayHead);
5828
+ };
5498
5829
  let postFold = false;
5499
5830
  try {
5500
5831
  if (!compactionOff && admissionDb)
5501
5832
  await withAsyncPrivilegedWriter2(admissionDb, () => {
5502
5833
  return;
5503
5834
  }, {
5504
- beforeRetry: (error) => {
5505
- const mapped = adaptPayload(draft);
5835
+ beforeRetry: async (error) => {
5836
+ const input = await buildReplayInput();
5837
+ if (!input)
5838
+ return;
5839
+ const { mapped } = input;
5506
5840
  if (tryMessagesTransformLkgReplay({
5507
5841
  output: mapped,
5508
5842
  sessionId: draft.sessionID,
@@ -5513,6 +5847,7 @@ async function registerContext(context) {
5513
5847
  onLkgReplay: restoreLkgSystem
5514
5848
  })) {
5515
5849
  mapped.commit();
5850
+ adoptReplay(input.draft);
5516
5851
  throw new V2LkgAdmissionReplay;
5517
5852
  }
5518
5853
  }
@@ -5707,6 +6042,7 @@ async function registerContext(context) {
5707
6042
  postFold = cut !== undefined;
5708
6043
  if (localCut && !incoming)
5709
6044
  throw new Error("The host checkpoint disappeared from the context draft");
6045
+ checkpointAtEntry = incoming || null;
5710
6046
  let nativeRestored;
5711
6047
  if (cut && nativeFoldReplay && await nativeFoldReplay.admits(draft.sessionID, cut, reader)) {
5712
6048
  try {
@@ -5748,22 +6084,17 @@ async function registerContext(context) {
5748
6084
  checkpoint = structuredClone(identity.rendered ?? incoming);
5749
6085
  submitted = identity.rendered ? identity.renderedSummary ?? identity.submitted : cut.data.summary ?? "";
5750
6086
  }
5751
- const moduleBoundaryID = rustModeModuleClient ? getPersistedCompactionMarkerState(db, draft.sessionID)?.boundaryMessageId ?? null : null;
5752
- const moduleBoundarySeq = moduleBoundaryID ? reader.sequenceForId(draft.sessionID, moduleBoundaryID) : undefined;
5753
- 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);
5754
- const servedBoundary = boundaryID ? servedBoundaryRow(reader, draft.sessionID, boundaryID) : null;
5755
- const boundary = (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;
5756
- if (moduleBoundarySeq !== undefined)
5757
- sessionLog2(draft.sessionID, `v2 restore: from the module boundary ${moduleBoundaryID} to the host checkpoint`);
5758
- const present = new Set(draft.messages.map((message) => message.id));
5759
- const restored = restoredRows.rows(reader, draft.sessionID, boundary, cut.seq).filter((row) => !present.has(row.id)).flatMap((row) => restoreRow(row, draft.model, hostUsesMediaAssets() ? {
5760
- asset: hostMediaAsset,
5761
- unavailable: (detail) => sessionLog2(draft.sessionID, `v2 restore: attachment replaced by a note row=${detail.rowID} name=${JSON.stringify(detail.name ?? null)} mediaType=${detail.mediaType} reason=${JSON.stringify(detail.reason)}`)
5762
- } : undefined));
5763
- draft.messages.splice(0, draft.messages.length, ...rustModeModuleClient ? [] : coveredInstructionRows(reader, draft.sessionID, Math.min(boundary, cut.seq), draft.model), ...restored, ...draft.messages.filter((message) => message !== incoming));
6087
+ draft.messages.splice(0, draft.messages.length, ...restoreAfterCheckpoint({
6088
+ db,
6089
+ reader,
6090
+ draft,
6091
+ messages: draft.messages,
6092
+ cut: localCut,
6093
+ incoming,
6094
+ boundaryRepair
6095
+ }));
5764
6096
  }
5765
- if (config.temporal_awareness === true)
5766
- messageTimes = reader.messageTimes(draft.sessionID, draft.messages.flatMap((message) => message.id ? [message.id] : []));
6097
+ messageTimes = readTimes(reader, draft.messages);
5767
6098
  } finally {
5768
6099
  reader.close();
5769
6100
  }
@@ -5780,7 +6111,7 @@ async function registerContext(context) {
5780
6111
  nativeFoldReplay.invalidate(draft.sessionID, true);
5781
6112
  }
5782
6113
  }
5783
- const mapped = adaptPayload(draft, admitted, messageTimes);
6114
+ const mapped = adaptPayload(draft, admitted, messageTimes, anchorTimesOnly);
5784
6115
  bindSystemDateRequestIdentity(mapped, draft);
5785
6116
  await createMessagesTransformHandler({
5786
6117
  magicContext: { "experimental.chat.messages.transform": transform },
@@ -5797,24 +6128,9 @@ async function registerContext(context) {
5797
6128
  if (db) {
5798
6129
  await deliverPendingChannel2(context, db, draft.sessionID, channel1.get(draft.sessionID));
5799
6130
  }
5800
- if (checkpoint && submitted !== undefined) {
5801
- const head = draft.messages.find((message) => message.id === HEAD_IDS[0]);
5802
- const baseline = head?.content.find((part) => part.type === "text")?.text;
5803
- if (typeof baseline === "string") {
5804
- for (const part of checkpoint.content)
5805
- if (part.type === "text" && typeof part.text === "string") {
5806
- part.text = part.text.replace(`<summary>
5807
- ${submitted}
5808
- </summary>`, `<summary>
5809
- ${baseline}
5810
- </summary>`);
5811
- }
5812
- const volatile = draft.messages.find((message) => message.id === HEAD_IDS[1]);
5813
- if (volatile && head)
5814
- volatile.content.push(...head.content.filter((part) => part.type !== "text"));
5815
- draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== head));
5816
- }
5817
- }
6131
+ const head = replayHead !== undefined ? replayHead : checkpoint && submitted !== undefined ? { checkpoint, submitted } : null;
6132
+ const servedHead = head && structuredClone(head);
6133
+ const headApplied = head ? applyCheckpointHead(draft, head) : false;
5818
6134
  if (nativeMessages && !checkpoint) {
5819
6135
  try {
5820
6136
  await nativeFoldReplay?.capture(draft, nativeMessages);
@@ -5825,7 +6141,7 @@ ${baseline}
5825
6141
  }
5826
6142
  const capturedSlot = getSlot(draft.sessionID);
5827
6143
  if (capturedSlot && (!slotAtEntry || capturedSlot.capturedAt !== slotAtEntry.capturedAt || capturedSlot.captureSequence !== slotAtEntry.captureSequence || capturedSlot.jsonPrefix !== slotAtEntry.jsonPrefix)) {
5828
- lkgSystems.capture(draft.sessionID, capturedSlot, systemAtEntry, draft.system);
6144
+ lkgSystems.capture(draft.sessionID, capturedSlot, { system: systemAtEntry, checkpoint: checkpointAtEntry ?? null }, draft.system, headApplied ? servedHead : null);
5829
6145
  }
5830
6146
  } catch (error) {
5831
6147
  if (error instanceof V2LkgAdmissionReplay)
@@ -5834,8 +6150,11 @@ ${baseline}
5834
6150
  throw error;
5835
6151
  if (!compactionOff && (isTransientSqliteError2(error) || error instanceof StorageBusyRefusalError)) {
5836
6152
  if (isTransientSqliteError2(error)) {
5837
- const mapped = adaptPayload(draft);
6153
+ const input = await buildReplayInput();
5838
6154
  try {
6155
+ if (!input)
6156
+ throw new StorageBusyRefusalError(error, "v2-context");
6157
+ const { mapped } = input;
5839
6158
  await createMessagesTransformHandler({
5840
6159
  replayFits,
5841
6160
  onLkgReplay: restoreLkgSystem,
@@ -5847,6 +6166,7 @@ ${baseline}
5847
6166
  }
5848
6167
  })({}, mapped);
5849
6168
  mapped.commit();
6169
+ adoptReplay(input.draft);
5850
6170
  return;
5851
6171
  } catch (replayError) {
5852
6172
  if (!(replayError instanceof StorageBusyRefusalError))
@@ -5928,7 +6248,8 @@ ${baseline}
5928
6248
  return null;
5929
6249
  }
5930
6250
  },
5931
- storageDir
6251
+ storageDir,
6252
+ getDebugMemoryHolders: () => ({ generateReplay: generateReplay.stats() })
5932
6253
  });
5933
6254
  rpcServer.handle("dream", async (params) => {
5934
6255
  const sessionId = String(params.sessionId ?? "");