@cortexkit/opencode-magic-context 0.49.19 → 0.49.21

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 (323) 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-31h86ph0.js} +3 -3
  4. package/dist/compaction-marker-candidates-worker.js +2 -2
  5. package/dist/compartment-chunk-embedding-he60aaa2.js +65 -0
  6. package/dist/config/project-security.d.ts.map +1 -1
  7. package/dist/config/schema/magic-context.d.ts +43 -9
  8. package/dist/config/schema/magic-context.d.ts.map +1 -1
  9. package/dist/{conflict-warning-hook-4pmz879v.js → conflict-warning-hook-2r32hyx6.js} +9 -8
  10. package/dist/{context-j31m2dv7.js → context-j7hp43a0.js} +576 -185
  11. package/dist/{derive-budgets-zn7yzd2d.js → derive-budgets-pqybnx09.js} +2 -2
  12. package/dist/embedding-backfill-dtke6tck.js +25 -0
  13. package/dist/embedding-worker-process.js +2 -2
  14. package/dist/embedding-worker.js +6 -6
  15. package/dist/features/magic-context/chunk-embedding-writer.d.ts.map +1 -1
  16. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +44 -1
  17. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/docs-proposals.d.ts +1 -0
  19. package/dist/features/magic-context/dreamer/docs-proposals.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
  21. package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  23. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +2 -0
  24. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  25. package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
  26. package/dist/features/magic-context/memory/embedding-local.d.ts +1 -0
  27. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  28. package/dist/features/magic-context/memory/embedding-synapse.d.ts.map +1 -1
  29. package/dist/features/magic-context/memory/embedding-worker-client.d.ts +7 -1
  30. package/dist/features/magic-context/memory/embedding-worker-client.d.ts.map +1 -1
  31. package/dist/features/magic-context/memory/local-embedding-pooling.d.ts +22 -0
  32. package/dist/features/magic-context/memory/local-embedding-pooling.d.ts.map +1 -0
  33. package/dist/features/magic-context/message-index-async.d.ts +7 -2
  34. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  35. package/dist/features/magic-context/message-index.d.ts +2 -0
  36. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  37. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  38. package/dist/features/magic-context/project-embedding-registry.d.ts +2 -0
  39. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  40. package/dist/features/magic-context/search-rerank.d.ts +9 -2
  41. package/dist/features/magic-context/search-rerank.d.ts.map +1 -1
  42. package/dist/features/magic-context/search.d.ts +29 -0
  43. package/dist/features/magic-context/search.d.ts.map +1 -1
  44. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  45. package/dist/features/magic-context/storage-db.d.ts +2 -0
  46. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  47. package/dist/features/magic-context/storage-meta-persisted.d.ts +2 -0
  48. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  49. package/dist/features/magic-context/subagent-token-capture.d.ts +20 -0
  50. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
  51. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  52. package/dist/{history-owner-xp3pngv7.js → history-owner-36wp3mkb.js} +2 -2
  53. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  54. package/dist/hooks/magic-context/auto-embed-session.d.ts.map +1 -1
  55. package/dist/hooks/magic-context/auto-search-hint.d.ts +7 -1
  56. package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
  57. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  58. package/dist/hooks/magic-context/auto-search-worker-client.d.ts +33 -6
  59. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
  60. package/dist/hooks/magic-context/cache-busting-signals.d.ts +6 -2
  61. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  62. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  63. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  64. package/dist/hooks/magic-context/compartment-runner-types.d.ts +5 -0
  65. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  66. package/dist/hooks/magic-context/compartment-trigger.d.ts +1 -1
  67. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  68. package/dist/hooks/magic-context/diagnostic-log-state.d.ts +4 -0
  69. package/dist/hooks/magic-context/diagnostic-log-state.d.ts.map +1 -0
  70. package/dist/hooks/magic-context/execute-reclaim.d.ts +35 -0
  71. package/dist/hooks/magic-context/execute-reclaim.d.ts.map +1 -0
  72. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  73. package/dist/hooks/magic-context/hook.d.ts +1 -3
  74. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  75. package/dist/hooks/magic-context/latest-assistant-turn.d.ts +8 -0
  76. package/dist/hooks/magic-context/latest-assistant-turn.d.ts.map +1 -1
  77. package/dist/hooks/magic-context/lkg-recovery-fence.d.ts +5 -0
  78. package/dist/hooks/magic-context/lkg-recovery-fence.d.ts.map +1 -1
  79. package/dist/hooks/magic-context/nudge-evaluation-log.d.ts +3 -0
  80. package/dist/hooks/magic-context/nudge-evaluation-log.d.ts.map +1 -0
  81. package/dist/hooks/magic-context/pending-drop-eligibility.d.ts.map +1 -1
  82. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +4 -0
  83. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  84. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
  85. package/dist/hooks/magic-context/served-shape-repair.d.ts +19 -0
  86. package/dist/hooks/magic-context/served-shape-repair.d.ts.map +1 -0
  87. package/dist/hooks/magic-context/strip-content.d.ts +4 -2
  88. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  89. package/dist/hooks/magic-context/system-date-refresh.d.ts +5 -5
  90. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  91. package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts +10 -0
  92. package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts.map +1 -0
  93. package/dist/hooks/magic-context/tag-content-primitives.d.ts +1 -1
  94. package/dist/hooks/magic-context/tag-content-primitives.d.ts.map +1 -1
  95. package/dist/hooks/magic-context/tag-messages.d.ts +4 -1
  96. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  97. package/dist/hooks/magic-context/text-complete.d.ts +1 -1
  98. package/dist/hooks/magic-context/text-complete.d.ts.map +1 -1
  99. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  100. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +21 -6
  101. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  102. package/dist/hooks/magic-context/transform.d.ts +2 -2
  103. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  104. package/dist/{index-3esx8tkf.js → index-11gzxvf4.js} +394 -125
  105. package/dist/{index-jn12fvvh.js → index-1gtfne2c.js} +3 -3
  106. package/dist/{index-jhghdnsm.js → index-1kbznkft.js} +521 -214
  107. package/dist/{index-3h4dp9wb.js → index-3svaejkh.js} +5 -5
  108. package/dist/{index-kee4kn5j.js → index-4pnsgvfk.js} +1 -1
  109. package/dist/{index-bjcnntmz.js → index-51rdvtkz.js} +501 -20
  110. package/dist/{v2/server-8cd2j99z.js → index-5kym00ag.js} +32 -13
  111. package/dist/{index-s74zqahq.js → index-66eby7hx.js} +4 -4
  112. package/dist/{index-63k48rv9.js → index-9q1g3c5q.js} +5 -5
  113. package/dist/{index-jrr131e0.js → index-a9zvn5fe.js} +29 -15
  114. package/dist/{index-c5pytzne.js → index-b88dwwrh.js} +1 -1
  115. package/dist/{index-nj7yykkx.js → index-c7phnbvk.js} +1 -1
  116. package/dist/index-cpjk5jd2.js +82 -0
  117. package/dist/{index-c1p88z1y.js → index-ffzhwfzy.js} +4 -4
  118. package/dist/{v2/server-beht37jy.js → index-gzy5w8ya.js} +194 -5
  119. package/dist/{index-j75v2476.js → index-h7tgn49j.js} +12 -15
  120. package/dist/{index-edmpdxcw.js → index-j32jj2t8.js} +5 -5
  121. package/dist/{index-ke416mdc.js → index-j76ah6d7.js} +2 -2
  122. package/dist/{index-s734jcsr.js → index-jfem3dgz.js} +9 -3
  123. package/dist/{index-n37sebck.js → index-jjvbk92s.js} +1 -1
  124. package/dist/{index-4911rn0b.js → index-jmq8kfe7.js} +6 -6
  125. package/dist/{index-rr2bb45z.js → index-kfyb3k6n.js} +2 -2
  126. package/dist/{index-2vxtcb95.js → index-kq5w68dp.js} +2 -2
  127. package/dist/{index-kq82mtg0.js → index-ksq50rg0.js} +3 -3
  128. package/dist/{index-b5vqckbw.js → index-m32esgmj.js} +314 -127
  129. package/dist/{index-9zcsy3hh.js → index-mnhcdfxg.js} +161 -13
  130. package/dist/{index-se4m2g6w.js → index-mnnkgq0q.js} +111 -19
  131. package/dist/{index-p5y3k4g7.js → index-nda0zgna.js} +2 -1
  132. package/dist/{index-wgypt3cs.js → index-nxrsns5x.js} +2466 -1290
  133. package/dist/{index-4s3t0nd0.js → index-qgh1qwjj.js} +2 -2
  134. package/dist/{index-y9f76s3f.js → index-rrv26qjz.js} +1 -1
  135. package/dist/{index-24fezq97.js → index-rxqr723x.js} +5 -5
  136. package/dist/{index-v10f1rjv.js → index-spwjbkc7.js} +1 -1
  137. package/dist/{index-dxmq29t1.js → index-syaazvy2.js} +182 -47
  138. package/dist/{index-k29z4aqh.js → index-t5pck3ss.js} +1 -1
  139. package/dist/{index-6x57ar45.js → index-wfybj1dw.js} +4 -6
  140. package/dist/{index-cf74k5ak.js → index-whcgcfrv.js} +9 -6
  141. package/dist/{index-a6mc0v4d.js → index-x6cbrv9h.js} +3 -3
  142. package/dist/{index-bp5083x2.js → index-x9k3mqrf.js} +1 -1
  143. package/dist/{index-rpxdjkm0.js → index-y76rhsnr.js} +319 -61
  144. package/dist/{index-ze7mvk54.js → index-zy67whjr.js} +95 -59
  145. package/dist/index.js +58 -54
  146. package/dist/{logger-jm3sqqzr.js → logger-94kew5wm.js} +1 -1
  147. package/dist/{message-fts-rowid-map-17s0dfn4.js → message-fts-rowid-map-e79b7b6x.js} +6 -5
  148. package/dist/{message-index-gtpqnj8w.js → message-index-4q8ek2fc.js} +17 -16
  149. package/dist/{message-index-bounded-zyc8h32y.js → message-index-bounded-rydsg9r5.js} +17 -16
  150. package/dist/{message-time-backfill-73mmm76q.js → message-time-backfill-4qva0b4f.js} +3 -3
  151. package/dist/migration-worker.js +13 -12
  152. package/dist/{model-resolution-nx97z3x7.js → model-resolution-280gmqvd.js} +1 -1
  153. package/dist/plugin/embedding-bootstrap.d.ts +4 -1
  154. package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
  155. package/dist/plugin/hooks/create-session-hooks.d.ts +1 -0
  156. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  157. package/dist/plugin/rpc-handlers.d.ts +8 -0
  158. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  159. package/dist/plugin/subagent-tool-policy.d.ts +9 -0
  160. package/dist/plugin/subagent-tool-policy.d.ts.map +1 -1
  161. package/dist/plugin/tool-registry.d.ts.map +1 -1
  162. package/dist/{project-embedding-registry-z74mhqkf.js → project-embedding-registry-hn529988.js} +16 -13
  163. package/dist/raw-ordinal-warmup-worker.js +136 -101
  164. package/dist/{read-session-chunk-jjb48bt9.js → read-session-chunk-t039f0m5.js} +12 -11
  165. package/dist/{read-session-raw-rsc8c7qy.js → read-session-raw-aw6jgvwg.js} +4 -3
  166. package/dist/recomp-orchestrator-hbm53jj5.js +62 -0
  167. package/dist/{safe-notification-target-1szv1k5k.js → safe-notification-target-mkr9yzvr.js} +2 -2
  168. package/dist/search-archive-weh164mh.js +26 -0
  169. package/dist/search-hea079d7.js +50 -0
  170. package/dist/{send-session-notification-6ve0e8p4.js → send-session-notification-gqzkz7da.js} +7 -6
  171. package/dist/shared/logger.d.ts.map +1 -1
  172. package/dist/shared/model-resolution.d.ts +2 -0
  173. package/dist/shared/model-resolution.d.ts.map +1 -1
  174. package/dist/shared/prompt-async-transport.d.ts +3 -0
  175. package/dist/shared/prompt-async-transport.d.ts.map +1 -1
  176. package/dist/shared/rpc-types.d.ts +7 -0
  177. package/dist/shared/rpc-types.d.ts.map +1 -1
  178. package/dist/shared/sqlite.d.ts +6 -1
  179. package/dist/shared/sqlite.d.ts.map +1 -1
  180. package/dist/shared/subagent-runner.d.ts +2 -0
  181. package/dist/shared/subagent-runner.d.ts.map +1 -1
  182. package/dist/shared/tag-transcript.d.ts +2 -0
  183. package/dist/shared/tag-transcript.d.ts.map +1 -1
  184. package/dist/shared/worker-shutdown.d.ts +68 -0
  185. package/dist/shared/worker-shutdown.d.ts.map +1 -0
  186. package/dist/shared/worker-shutdown.fixture.d.ts +2 -0
  187. package/dist/shared/worker-shutdown.fixture.d.ts.map +1 -0
  188. package/dist/{sqlite-zf72c52d.js → sqlite-zdgm52sv.js} +5 -1
  189. package/dist/{storage-memory-y3qmy00r.js → storage-memory-e6a7mb0k.js} +2 -2
  190. package/dist/{storage-tags-r7k9tjcv.js → storage-tags-a77q4v77.js} +5 -5
  191. package/dist/{task-config-x3qmayd2.js → task-config-t6bpyka7.js} +2 -2
  192. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  193. package/dist/tools/ctx-search/types.d.ts +1 -0
  194. package/dist/tools/ctx-search/types.d.ts.map +1 -1
  195. package/dist/{transform-postprocess-phase-jj99r7z2.js → transform-postprocess-phase-0b04tm1p.js} +35 -32
  196. package/dist/v2/auto-search-worker.js +48 -9
  197. package/dist/v2/chunk-embedding-write-worker.js +30 -23
  198. package/dist/v2/{compaction-marker-candidates-ebx3388k.js → compaction-marker-candidates-m4vmye3w.js} +3 -3
  199. package/dist/v2/compaction-marker-candidates-worker.js +2 -2
  200. package/dist/v2/compartment-chunk-embedding-8jjmcgeg.js +64 -0
  201. package/dist/v2/{context-y5yamxak.js → context-ea3x7smm.js} +1797 -810
  202. package/dist/v2/{derive-budgets-2zh4gm2c.js → derive-budgets-knf763tt.js} +3 -3
  203. package/dist/v2/embedding-backfill-5e74ae0m.js +24 -0
  204. package/dist/v2/embedding-worker-process.js +2 -2
  205. package/dist/v2/embedding-worker.js +6 -6
  206. package/dist/v2/hidden-child-record.d.ts +2 -0
  207. package/dist/v2/hidden-child-record.d.ts.map +1 -1
  208. package/dist/v2/hidden-completion.d.ts +2 -0
  209. package/dist/v2/hidden-completion.d.ts.map +1 -1
  210. package/dist/v2/hidden-model-activity.d.ts +7 -0
  211. package/dist/v2/hidden-model-activity.d.ts.map +1 -0
  212. package/dist/v2/{history-owner-42e16w0n.js → history-owner-ad0crnrn.js} +2 -2
  213. package/dist/v2/hooks/context.d.ts.map +1 -1
  214. package/dist/v2/hooks/copied-tag-notation.d.ts +1 -1
  215. package/dist/v2/hooks/copied-tag-notation.d.ts.map +1 -1
  216. package/dist/v2/hooks/dream-timer.d.ts +2 -0
  217. package/dist/v2/hooks/dream-timer.d.ts.map +1 -1
  218. package/dist/v2/hooks/embedding-lifecycle.d.ts +7 -0
  219. package/dist/v2/hooks/embedding-lifecycle.d.ts.map +1 -0
  220. package/dist/v2/hooks/generate.d.ts +36 -1
  221. package/dist/v2/hooks/generate.d.ts.map +1 -1
  222. package/dist/v2/hooks/lkg-system.d.ts +35 -4
  223. package/dist/v2/hooks/lkg-system.d.ts.map +1 -1
  224. package/dist/v2/hooks/payload.d.ts +16 -1
  225. package/dist/v2/hooks/payload.d.ts.map +1 -1
  226. package/dist/v2/hooks/store.d.ts +2 -0
  227. package/dist/v2/hooks/store.d.ts.map +1 -1
  228. package/dist/v2/hooks/tools.d.ts +2 -1
  229. package/dist/v2/hooks/tools.d.ts.map +1 -1
  230. package/dist/v2/hooks/transform-features.d.ts +2 -2
  231. package/dist/v2/hooks/transform-features.d.ts.map +1 -1
  232. package/dist/v2/{logger-7qt02bnb.js → logger-p34mjtja.js} +1 -1
  233. package/dist/v2/{message-fts-rowid-map-wfx67gfd.js → message-fts-rowid-map-n8fdg2ja.js} +6 -5
  234. package/dist/v2/{message-index-bounded-spd8r7pj.js → message-index-bounded-8rcd7qq9.js} +17 -16
  235. package/dist/v2/{message-index-8vz2pq76.js → message-index-qz9wdp82.js} +17 -16
  236. package/dist/v2/{message-time-backfill-04t0km1z.js → message-time-backfill-zvthw6xb.js} +3 -3
  237. package/dist/v2/migration-worker.js +13 -12
  238. package/dist/v2/{model-resolution-nx97z3x7.js → model-resolution-280gmqvd.js} +1 -1
  239. package/dist/v2/{project-embedding-registry-gnkj56xp.js → project-embedding-registry-v38q4xd5.js} +16 -13
  240. package/dist/v2/raw-ordinal-warmup-worker.js +136 -101
  241. package/dist/v2/{read-session-chunk-cwkxrmns.js → read-session-chunk-wazfyxcg.js} +12 -11
  242. package/dist/v2/{read-session-raw-yaegtjzh.js → read-session-raw-b70cpwzj.js} +4 -3
  243. package/dist/v2/recomp-orchestrator-b12zaptj.js +61 -0
  244. package/dist/v2/{safe-notification-target-qg7n2s77.js → safe-notification-target-khnzg57c.js} +2 -2
  245. package/dist/v2/search-archive-x64rtz1z.js +25 -0
  246. package/dist/v2/search-hza9x72a.js +49 -0
  247. package/dist/v2/{send-session-notification-3pxn658x.js → send-session-notification-8eqe259v.js} +7 -6
  248. package/dist/v2/{server-45q69hkq.js → server-132h8twc.js} +5 -5
  249. package/dist/v2/{server-h0410h0v.js → server-1bw1wcbp.js} +1 -1
  250. package/dist/v2/{server-271qxsf5.js → server-24g8r2d0.js} +2466 -1290
  251. package/dist/v2/{server-tbe1femw.js → server-29qp8nz4.js} +1 -1
  252. package/dist/v2/{server-gsxjv2q2.js → server-33nqbqkw.js} +182 -47
  253. package/dist/v2/{server-tgnbmwah.js → server-3mz2qh5a.js} +1 -1
  254. package/dist/v2/{server-n1prf1g6.js → server-3vhxy2k5.js} +2 -2
  255. package/dist/v2/{server-xj136kt8.js → server-4kjmrjn4.js} +9 -3
  256. package/dist/v2/{server-34kwfsr4.js → server-53eh1r8r.js} +2 -2
  257. package/dist/{index-8cd2j99z.js → v2/server-5kym00ag.js} +32 -13
  258. package/dist/v2/{server-46neh5fa.js → server-62g58aaz.js} +314 -127
  259. package/dist/v2/{server-f2xf5gcb.js → server-6495nmn9.js} +12 -15
  260. package/dist/v2/{server-a9xqj88f.js → server-6v3cdzsx.js} +4 -4
  261. package/dist/v2/{server-d04vrx0j.js → server-806rzhs6.js} +2 -2
  262. package/dist/v2/{server-qd11g795.js → server-92g7d776.js} +2 -1
  263. package/dist/v2/{server-nj659894.js → server-94wk1ey3.js} +14 -3
  264. package/dist/v2/{server-6tmj0s7j.js → server-ab1g0wn9.js} +4 -6
  265. package/dist/v2/{server-8by8qfec.js → server-ad18djzs.js} +95 -59
  266. package/dist/v2/{server-hy3d3vsx.js → server-bsgd4dk1.js} +2 -2
  267. package/dist/v2/server-cpjk5jd2.js +82 -0
  268. package/dist/v2/{server-g3qma5c0.js → server-d1dzgvwd.js} +2 -2
  269. package/dist/v2/{server-hm38q7r0.js → server-d48x3m4x.js} +5 -5
  270. package/dist/v2/{server-1wy7b9de.js → server-dtp8hcjh.js} +3 -3
  271. package/dist/v2/{server-27gq4mfz.js → server-fa7vtp40.js} +9 -6
  272. package/dist/v2/{server-6pmqg9m4.js → server-gyy4k6mf.js} +1 -1
  273. package/dist/{index-beht37jy.js → v2/server-gzy5w8ya.js} +194 -5
  274. package/dist/v2/{server-bmymkx73.js → server-j8h7bsca.js} +29 -15
  275. package/dist/v2/{server-n37sebck.js → server-jjvbk92s.js} +1 -1
  276. package/dist/v2/{server-da07v4xp.js → server-k3t06fxr.js} +1 -1
  277. package/dist/v2/{server-9hx7g5jp.js → server-m4bfaevz.js} +1197 -1049
  278. package/dist/v2/{server-2ar62dyx.js → server-ppcd1qxh.js} +191 -99
  279. package/dist/v2/{server-rmygf5pn.js → server-qjvk4a9t.js} +2 -2
  280. package/dist/v2/{server-zzkj2fch.js → server-qteg2kt9.js} +5 -5
  281. package/dist/v2/{server-pwv4ezb0.js → server-rqebawx1.js} +2 -2
  282. package/dist/v2/{server-h1v0pyxb.js → server-vr4szghm.js} +501 -20
  283. package/dist/v2/{server-xq7dfjke.js → server-wwaw5npa.js} +5 -5
  284. package/dist/v2/{server-6vdzn1td.js → server-zg5y109h.js} +323 -76
  285. package/dist/v2/server.js +8 -8
  286. package/dist/v2/{sqlite-zf72c52d.js → sqlite-zdgm52sv.js} +5 -1
  287. package/dist/v2/{storage-memory-y3qmy00r.js → storage-memory-e6a7mb0k.js} +2 -2
  288. package/dist/v2/{storage-tags-3wdb8zph.js → storage-tags-q71rnr9f.js} +5 -5
  289. package/dist/v2/store-reader.d.ts +10 -0
  290. package/dist/v2/store-reader.d.ts.map +1 -1
  291. package/dist/v2/{task-config-nvz8mapa.js → task-config-7md27rx8.js} +2 -2
  292. package/dist/v2/{wrapup-orchestrator-embdz8gj.js → wrapup-orchestrator-3ssd5yy1.js} +33 -32
  293. package/dist/wrapup-orchestrator-5vpcd1zx.js +49 -0
  294. package/package.json +2 -2
  295. package/src/config/index.test.ts +72 -6
  296. package/src/config/project-security.ts +15 -0
  297. package/src/config/rerank.test.ts +60 -0
  298. package/src/config/schema/magic-context.ts +57 -0
  299. package/src/shared/logger.test.ts +42 -1
  300. package/src/shared/logger.ts +11 -13
  301. package/src/shared/model-resolution.test.ts +67 -12
  302. package/src/shared/model-resolution.ts +43 -16
  303. package/src/shared/model-suggestion-retry.ts +2 -2
  304. package/src/shared/prompt-async-transport.ts +47 -3
  305. package/src/shared/rpc-types.ts +7 -0
  306. package/src/shared/sqlite-busy-budget-review.test.ts +6 -1
  307. package/src/shared/sqlite-turn-deadline.test.ts +270 -0
  308. package/src/shared/sqlite.ts +239 -9
  309. package/src/shared/subagent-runner.ts +2 -0
  310. package/src/shared/tag-transcript.ts +9 -1
  311. package/src/shared/worker-shutdown-fence.test.ts +87 -0
  312. package/src/shared/worker-shutdown.fixture.ts +25 -0
  313. package/src/shared/worker-shutdown.test.ts +127 -0
  314. package/src/shared/worker-shutdown.ts +160 -0
  315. package/dist/embedding-backfill-fmz50tsy.js +0 -24
  316. package/dist/recomp-orchestrator-999jj4bc.js +0 -61
  317. package/dist/search-archive-6vm0e2f5.js +0 -25
  318. package/dist/search-xsqk1bj4.js +0 -49
  319. package/dist/v2/embedding-backfill-7c7yr69y.js +0 -23
  320. package/dist/v2/recomp-orchestrator-f6m9jr7p.js +0 -60
  321. package/dist/v2/search-archive-wve3tq1k.js +0 -24
  322. package/dist/v2/search-hwg7jfbj.js +0 -48
  323. package/dist/wrapup-orchestrator-whhbjmaz.js +0 -48
@@ -6,7 +6,7 @@ import {
6
6
  resolveLegacyConfigSources,
7
7
  getProtectedTokensTierOverrides,
8
8
  loadPluginConfigDetailed
9
- } from "./server-nj659894.js";
9
+ } from "./server-94wk1ey3.js";
10
10
  import {
11
11
  getHarness2,
12
12
  harnessOwnsOpenCodeStore2
@@ -21,7 +21,7 @@ import {
21
21
  log2,
22
22
  sessionLog2,
23
23
  getLoggerDiagnostics2
24
- } from "./server-f2xf5gcb.js";
24
+ } from "./server-6495nmn9.js";
25
25
  import {
26
26
  hasTrustedAbsoluteWall,
27
27
  applyProvenInputFloor,
@@ -33,7 +33,7 @@ import {
33
33
  getSdkContextLimit,
34
34
  getSdkOutputLimit,
35
35
  getModelsDevCacheState
36
- } from "./server-tbe1femw.js";
36
+ } from "./server-29qp8nz4.js";
37
37
  import {
38
38
  isValidLanguageCode,
39
39
  withContentLanguageDirective,
@@ -46,7 +46,7 @@ import {
46
46
  DEFAULT_HISTORIAN_TIMEOUT_MS,
47
47
  DEFAULT_LOCAL_EMBEDDING_MODEL,
48
48
  DREAM_TASK_PROMOTION_DEFAULTS
49
- } from "./server-271qxsf5.js";
49
+ } from "./server-24g8r2d0.js";
50
50
  import {
51
51
  CANONICAL_DREAM_TASKS,
52
52
  DREAM_TASK_CAPABILITIES,
@@ -64,7 +64,7 @@ import {
64
64
  userMemoryCollectionEnabled2,
65
65
  userObservationCollectionEnabled2,
66
66
  userObservationsRequested2
67
- } from "./server-qd11g795.js";
67
+ } from "./server-92g7d776.js";
68
68
  import {
69
69
  historianRunConfig,
70
70
  dreamerRunConfig,
@@ -205,11 +205,15 @@ import {
205
205
  parseProviderModel,
206
206
  modelBodyField,
207
207
  toModelEntry,
208
+ ModelProducedNoOutputError,
209
+ noteModelActivityMonitored,
210
+ noteModelOutputReceived,
208
211
  isPromptTimeoutError,
209
212
  getPromptFailureDetail,
210
213
  raceWithSignal,
211
214
  promptSyncWithValidatedOutputRetry,
212
215
  normalizeSDKResponse,
216
+ annotateSubagentInvocationError,
213
217
  failedInvocationStatus,
214
218
  sumTokensFromChildMessages,
215
219
  recordChildInvocation,
@@ -282,10 +286,10 @@ import {
282
286
  startCompartmentAgent,
283
287
  setRecompStarting2,
284
288
  setRecompTerminal2
285
- } from "./server-6vdzn1td.js";
289
+ } from "./server-zg5y109h.js";
286
290
  import {
287
291
  resolveHistorianModel2
288
- } from "./server-8cd2j99z.js";
292
+ } from "./server-5kym00ag.js";
289
293
  import {
290
294
  formatFailClosedBlockingMessage,
291
295
  formatFailClosedBlockingSummary,
@@ -307,7 +311,7 @@ import {
307
311
  openDatabaseAsync,
308
312
  isDatabasePersisted,
309
313
  getDatabasePersistenceError
310
- } from "./server-bmymkx73.js";
314
+ } from "./server-j8h7bsca.js";
311
315
  import {
312
316
  pruneMissingProjectIdentities,
313
317
  setHomeProjectPermission,
@@ -324,14 +328,197 @@ import {
324
328
  storedPathBelongsToIdentity,
325
329
  beginBootQuietPeriod,
326
330
  scheduleAfterBootQuiet
327
- } from "./server-rmygf5pn.js";
331
+ } from "./server-qjvk4a9t.js";
332
+ import {
333
+ registerOwnRpcServerInstance,
334
+ rpcPortDir,
335
+ rpcPortFilePath,
336
+ parseRpcPortFile,
337
+ inspectProcessesAsync
338
+ } from "./server-k3t06fxr.js";
339
+ import {
340
+ BoundedSessionMap,
341
+ LkgRecoveryFenceError,
342
+ lkgServedArrayDigest,
343
+ takeLkgRecoveryLockSweepPage,
344
+ hasCleanLkgRecoveryFence,
345
+ dirtyLkgRecoveryRevision,
346
+ ownsLkgDirtyFence,
347
+ invalidateCleanLkgRecoveryFence,
348
+ prepareLkgCaptureFence,
349
+ certifyCommittedLkgCapture,
350
+ markLkgRecoveryDirty,
351
+ gaDatabasePath,
352
+ RAW_MESSAGE_TYPES,
353
+ V2StoreReaderPool,
354
+ V2StoreReader,
355
+ cleanSearchText,
356
+ matchedSearchSnippet,
357
+ advanceSessionActivity,
358
+ backfillSessionActivity,
359
+ getLastIndexedOrdinal2,
360
+ getMessageIndexReconciliationStartOrdinal2,
361
+ isMessageIndexReconciledThrough2,
362
+ clearIndexedMessages2,
363
+ indexMessagesAfterOrdinal2,
364
+ sweepOrphanedOpenCodeMessageIndexesCooperatively2
365
+ } from "./server-ppcd1qxh.js";
366
+ import"./server-51779zs2.js";
367
+ import {
368
+ inRootAsyncContext2,
369
+ getTagIdentityWriteGeneration2,
370
+ Database2,
371
+ getSqliteDatabasePath2,
372
+ getSqliteMemoryStats2,
373
+ withSqliteBackgroundWriter2,
374
+ withSqliteTransformPass2,
375
+ withoutSqliteTransformPass2,
376
+ assertTransformWrite2,
377
+ isTransientSqliteError2,
378
+ SqliteAcquisitionBusyError2,
379
+ withAsyncPrivilegedWriter2
380
+ } from "./server-gzy5w8ya.js";
381
+ import {
382
+ createWorkerShutdown
383
+ } from "./server-cpjk5jd2.js";
384
+ import {
385
+ isRawCompactionSummaryInfo2,
386
+ extractInMemoryMessageViews2,
387
+ buildInMemoryTailRawMessages2,
388
+ RawOrdinalsNotReady2,
389
+ runSessionWarmupWorker
390
+ } from "./server-4kjmrjn4.js";
391
+ import {
392
+ resolveOpenCodeDbPath,
393
+ assertOpenCodeStoreGeneration,
394
+ openCodeDbPathExists,
395
+ recordOpenCodeDbReadFailure,
396
+ clearOpenCodeDbReadFailure,
397
+ claimOpenCodeDbDiagnosticOnce
398
+ } from "./server-2ra6pwf3.js";
399
+ import {
400
+ resolveModelCalibration,
401
+ calibrateBuckets,
402
+ resolveDecisionCalibration
403
+ } from "./server-1zx87sdm.js";
404
+ import {
405
+ protectedToolTagNumbers,
406
+ protectedToolTokenCount,
407
+ stripPersistedAssistantText,
408
+ byteSize,
409
+ stripTagPrefix,
410
+ peelLeadingMcTagNotation,
411
+ prependTag,
412
+ isThinkingPart,
413
+ currentReclaimableToolOutputCount,
414
+ isRecord,
415
+ contentTagOwnerMessageId,
416
+ estimateImageTokensFromDataUrl,
417
+ estimateToolAttachmentImageTokens,
418
+ providerVisiblePart,
419
+ normalizeTodoStateJson,
420
+ buildSyntheticTodoPart,
421
+ computeSyntheticCallId,
422
+ isSyntheticTodoPart,
423
+ countRealUserMessages,
424
+ tailHygieneStructuralSignature,
425
+ sameTailHygieneStructuralSignature,
426
+ formatTailHygienePrefixMismatch,
427
+ refreshTailHygieneBaseline,
428
+ effectiveTailHygiene,
429
+ assertTailHygieneContentUnchangedIfEnabled,
430
+ CHANNEL1_SENTINEL,
431
+ CHANNEL1_FLOOR_TOKENS,
432
+ isDroppedToolOutput,
433
+ toolOutputTokens,
434
+ decideChannel1,
435
+ evaluateChannel2,
436
+ formatChannel1Evaluation,
437
+ formatChannel2Evaluation,
438
+ buildChannel2Reminder,
439
+ buildChannel1Reminder,
440
+ estimateEmergencyDropReclaimTokens,
441
+ planEmergencyDrop,
442
+ measureEmergencyTag,
443
+ queuePendingOp,
444
+ getPendingOps,
445
+ hasPendingDropOps,
446
+ getPendingOpsCount,
447
+ clearPendingOps,
448
+ removePendingOp,
449
+ updateTagByteSize2,
450
+ getRecentTagOwnerMessageIds2,
451
+ AGE_RECLAIM_MIN_TOKENS2,
452
+ getOldestActiveUnprotectedToolTags2,
453
+ getActiveToolTagsForAgeReclaim2,
454
+ getTriggerTagTokenUpperBound2,
455
+ getActiveTagTokenTotalsByMessage2,
456
+ updateTagTokenCount2,
457
+ tryGetReasoningTokenEstimatesByMessage2,
458
+ cachedTagOwnerRatios2,
459
+ tagOwnerWarmupState2,
460
+ installTagOwnerDelta2,
461
+ installTagOwnerSummary2,
462
+ isTagOwnerSummaryReady2,
463
+ tagTokenCountIsNull2,
464
+ backfillTagTokenCounts2,
465
+ insertTag2,
466
+ updateTagStatus2,
467
+ markTagDropped2,
468
+ markWhitespaceAssistantTagInert2,
469
+ getInertWhitespaceAssistantTags2,
470
+ getInertWhitespaceAssistantTagsByNumbers2,
471
+ updateTagDropMode2,
472
+ updateCavemanDepth2,
473
+ updateTagMessageId2,
474
+ markTagsCompactedByMessageIds2,
475
+ getMaxTagNumberBySession2,
476
+ getTagNumberByMessageId2,
477
+ getAssignableTagNumberByMessageId2,
478
+ deriveTagLoadFloor2,
479
+ getTagsBySession2,
480
+ getActiveTagsBySession2,
481
+ getTailHygieneTags2,
482
+ getDroppedTagsBySession2,
483
+ getTagsByNumbers2,
484
+ getNewestToolTagNumbers2,
485
+ getDroppedTagsByNumbers2,
486
+ getMaxDroppedTagNumber2,
487
+ getTagById2,
488
+ getToolTagNumberByOwner2,
489
+ getNullOwnerToolTag2,
490
+ adoptNullOwnerToolTag2,
491
+ getCandidateToolOwners2,
492
+ pickNearestPriorOwner2
493
+ } from "./server-fa7vtp40.js";
494
+ import {
495
+ textMentionsRecentCommit,
496
+ hasMeaningfulUserText2,
497
+ extractTexts2,
498
+ extractToolCallSummaries,
499
+ getTokenizerNativeMemoryStats,
500
+ preloadTokenizer,
501
+ estimateTokens,
502
+ estimateFixedPromptTokens,
503
+ normalizeText
504
+ } from "./server-3mz2qh5a.js";
505
+ import {
506
+ stableStringify,
507
+ getTemporalDecisions,
508
+ observeTemporalDecisions,
509
+ freezeTemporalDecisions,
510
+ tagRevisionKey,
511
+ tagIdentityRevisionKey
512
+ } from "./server-rqebawx1.js";
513
+ import {
514
+ openCodeDbExists,
515
+ withReadOnlySessionDb,
516
+ latestPersistedMessageForRecovery,
517
+ latestRealUserTurnIdFromOpenCodeDb,
518
+ getMessageTimesFromOpenCodeDb,
519
+ findLastAssistantModelFromOpenCodeDb
520
+ } from "./server-3vhxy2k5.js";
328
521
  import {
329
- detectLatestTurnThinkingMismatch,
330
- isPrefixBoundThinkingModel,
331
- detectOverflow,
332
- ensureSessionMetaRow,
333
- clearCachedM0M1,
334
- clearCachedM0,
335
522
  expandToolPart,
336
523
  markHostUnservedRow,
337
524
  markCoveredInstructionRow,
@@ -359,6 +546,9 @@ import {
359
546
  transitionSessionHygieneUnits,
360
547
  readEpochFloorSnapshot,
361
548
  getProtectionWindowForSession,
549
+ ensureSessionMetaRow,
550
+ clearCachedM0M1,
551
+ clearCachedM0,
362
552
  withReplayEnvelopeSnapshot,
363
553
  invalidateReplayEnvelopeSnapshot,
364
554
  isRustMarkerAdmissionFenced,
@@ -449,6 +639,9 @@ import {
449
639
  getReasoningRemovalState,
450
640
  addRemovedReasoningIds,
451
641
  markDropLeavesReasoning,
642
+ detectLatestTurnThinkingMismatch,
643
+ isPrefixBoundThinkingModel,
644
+ detectOverflow,
452
645
  modelAcceptsEmptyContent,
453
646
  isAnthropicFamilyRoute,
454
647
  neutralizeDroppedReasoningPart,
@@ -462,12 +655,15 @@ import {
462
655
  isInActiveAnthropicTurn,
463
656
  activeAnthropicTurnStart,
464
657
  hasAnthropicReasoning,
658
+ markServedShapeRepair,
659
+ prepareServedShapeRepair,
465
660
  stripSystemInjectedMessages,
466
661
  stripDroppedPlaceholderMessages,
467
662
  replayClearedReasoning,
468
663
  replayStrippedInlineThinking,
469
664
  clearOldReasoning,
470
665
  stripClearedReasoning,
666
+ captureInlineThinkingRepairs,
471
667
  stripInlineThinking,
472
668
  findReasoningBearingAssistantIds,
473
669
  findLatestAssistantReasoningMutationExemptMessage,
@@ -519,7 +715,24 @@ import {
519
715
  readRawSessionMessageById2,
520
716
  readSessionChunk2,
521
717
  readRawSessionSeedTail2
522
- } from "./server-9hx7g5jp.js";
718
+ } from "./server-m4bfaevz.js";
719
+ import {
720
+ getCurrentToolSetHash,
721
+ recordToolDefinition,
722
+ getMeasuredToolDefinitionTokens
723
+ } from "./server-d1dzgvwd.js";
724
+ import"./server-dtp8hcjh.js";
725
+ import {
726
+ SubcClient,
727
+ connectionFileExists,
728
+ SYNAPSE_DEFAULT_MODEL,
729
+ toSynapseLaneDescriptor,
730
+ formatSynapseLaneDescriptor,
731
+ SynapseEmbeddingProvider
732
+ } from "./server-ab1g0wn9.js";
733
+ import {
734
+ deleteChunkEmbedBackoffForSession2
735
+ } from "./server-62g58aaz.js";
523
736
  import {
524
737
  embedPauseBySession,
525
738
  embedRunStateBySession,
@@ -531,6 +744,7 @@ import {
531
744
  getEmbedDrainUiStatus,
532
745
  clearEmbedSessionState,
533
746
  describeShadowBackfillWriteRefusal2,
747
+ retainProjectEmbedding2,
534
748
  markProjectLoadUntrusted2,
535
749
  drainProjectEmbeddingIdentityMaintenance2,
536
750
  drainStaleEmbeddingIdentitiesForProject2,
@@ -548,208 +762,7 @@ import {
548
762
  embedSessionCompartmentChunks2,
549
763
  getEmbeddingCoverageStatus2,
550
764
  getAutoEmbeddingSessionCoverage2
551
- } from "./server-8by8qfec.js";
552
- import {
553
- textMentionsRecentCommit,
554
- hasMeaningfulUserText2,
555
- extractTexts2,
556
- extractToolCallSummaries,
557
- getTokenizerNativeMemoryStats,
558
- preloadTokenizer,
559
- estimateTokens,
560
- estimateFixedPromptTokens,
561
- normalizeText
562
- } from "./server-tgnbmwah.js";
563
- import {
564
- SubcClient,
565
- connectionFileExists,
566
- SYNAPSE_DEFAULT_MODEL,
567
- toSynapseLaneDescriptor,
568
- formatSynapseLaneDescriptor,
569
- SynapseEmbeddingProvider
570
- } from "./server-6tmj0s7j.js";
571
- import {
572
- inRootAsyncContext2,
573
- getTagIdentityWriteGeneration2,
574
- Database2,
575
- getSqliteDatabasePath2,
576
- getSqliteMemoryStats2,
577
- withSqliteBackgroundWriter2,
578
- withSqliteTransformPass2,
579
- withoutSqliteTransformPass2,
580
- assertTransformWrite2,
581
- isTransientSqliteError2,
582
- SqliteAcquisitionBusyError2,
583
- withAsyncPrivilegedWriter2
584
- } from "./server-beht37jy.js";
585
- import"./server-51779zs2.js";
586
- import {
587
- isRawCompactionSummaryInfo2,
588
- extractInMemoryMessageViews2,
589
- buildInMemoryTailRawMessages2,
590
- RawOrdinalsNotReady2,
591
- runSessionWarmupWorker
592
- } from "./server-xj136kt8.js";
593
- import"./server-1wy7b9de.js";
594
- import {
595
- deleteChunkEmbedBackoffForSession
596
- } from "./server-46neh5fa.js";
597
- import {
598
- registerOwnRpcServerInstance,
599
- rpcPortDir,
600
- rpcPortFilePath,
601
- parseRpcPortFile,
602
- inspectProcessesAsync
603
- } from "./server-da07v4xp.js";
604
- import {
605
- BoundedSessionMap,
606
- LkgRecoveryFenceError,
607
- lkgServedArrayDigest,
608
- hasCleanLkgRecoveryFence,
609
- dirtyLkgRecoveryRevision,
610
- ownsLkgDirtyFence,
611
- invalidateCleanLkgRecoveryFence,
612
- prepareLkgCaptureFence,
613
- certifyCommittedLkgCapture,
614
- markLkgRecoveryDirty,
615
- cleanSearchText,
616
- matchedSearchSnippet,
617
- gaDatabasePath,
618
- RAW_MESSAGE_TYPES,
619
- V2StoreReaderPool,
620
- V2StoreReader,
621
- advanceSessionActivity,
622
- backfillSessionActivity,
623
- getLastIndexedOrdinal2,
624
- getMessageIndexReconciliationStartOrdinal2,
625
- isMessageIndexReconciledThrough2,
626
- indexMessagesAfterOrdinal2,
627
- sweepOrphanedOpenCodeMessageIndexesCooperatively2
628
- } from "./server-2ar62dyx.js";
629
- import {
630
- stableStringify,
631
- getTemporalDecisions,
632
- observeTemporalDecisions,
633
- freezeTemporalDecisions,
634
- tagRevisionKey,
635
- tagIdentityRevisionKey
636
- } from "./server-pwv4ezb0.js";
637
- import {
638
- resolveModelCalibration,
639
- calibrateBuckets,
640
- resolveDecisionCalibration
641
- } from "./server-1zx87sdm.js";
642
- import {
643
- protectedToolTagNumbers,
644
- protectedToolTokenCount,
645
- stripPersistedAssistantText,
646
- byteSize,
647
- stripTagPrefix,
648
- peelLeadingMcTagNotation,
649
- prependTag,
650
- isThinkingPart,
651
- currentReclaimableToolOutputCount,
652
- isRecord,
653
- contentTagOwnerMessageId,
654
- estimateImageTokensFromDataUrl,
655
- estimateToolAttachmentImageTokens,
656
- providerVisiblePart,
657
- normalizeTodoStateJson,
658
- buildSyntheticTodoPart,
659
- computeSyntheticCallId,
660
- isSyntheticTodoPart,
661
- countRealUserMessages,
662
- tailHygieneStructuralSignature,
663
- sameTailHygieneStructuralSignature,
664
- formatTailHygienePrefixMismatch,
665
- refreshTailHygieneBaseline,
666
- effectiveTailHygiene,
667
- assertTailHygieneContentUnchangedIfEnabled,
668
- CHANNEL1_SENTINEL,
669
- CHANNEL1_FLOOR_TOKENS,
670
- isDroppedToolOutput,
671
- toolOutputTokens,
672
- decideChannel1,
673
- evaluateChannel2,
674
- formatChannel1Evaluation,
675
- formatChannel2Evaluation,
676
- buildChannel2Reminder,
677
- buildChannel1Reminder,
678
- estimateEmergencyDropReclaimTokens,
679
- planEmergencyDrop,
680
- measureEmergencyTag,
681
- queuePendingOp,
682
- getPendingOps,
683
- hasPendingDropOps,
684
- getPendingOpsCount,
685
- clearPendingOps,
686
- removePendingOp,
687
- updateTagByteSize2,
688
- getRecentTagOwnerMessageIds2,
689
- AGE_RECLAIM_MIN_TOKENS2,
690
- getOldestActiveUnprotectedToolTags2,
691
- getActiveToolTagsForAgeReclaim2,
692
- getTriggerTagTokenUpperBound2,
693
- getActiveTagTokenTotalsByMessage2,
694
- updateTagTokenCount2,
695
- tryGetReasoningTokenEstimatesByMessage2,
696
- cachedTagOwnerRatios2,
697
- tagOwnerWarmupState2,
698
- installTagOwnerDelta2,
699
- installTagOwnerSummary2,
700
- isTagOwnerSummaryReady2,
701
- tagTokenCountIsNull2,
702
- backfillTagTokenCounts2,
703
- insertTag2,
704
- updateTagStatus2,
705
- markTagDropped2,
706
- markWhitespaceAssistantTagInert2,
707
- getInertWhitespaceAssistantTags2,
708
- getInertWhitespaceAssistantTagsByNumbers2,
709
- updateTagDropMode2,
710
- updateCavemanDepth2,
711
- updateTagMessageId2,
712
- markTagsCompactedByMessageIds2,
713
- getMaxTagNumberBySession2,
714
- getTagNumberByMessageId2,
715
- getAssignableTagNumberByMessageId2,
716
- deriveTagLoadFloor2,
717
- getTagsBySession2,
718
- getActiveTagsBySession2,
719
- getTailHygieneTags2,
720
- getDroppedTagsBySession2,
721
- getTagsByNumbers2,
722
- getNewestToolTagNumbers2,
723
- getDroppedTagsByNumbers2,
724
- getMaxDroppedTagNumber2,
725
- getTagById2,
726
- getToolTagNumberByOwner2,
727
- getNullOwnerToolTag2,
728
- adoptNullOwnerToolTag2,
729
- getCandidateToolOwners2,
730
- pickNearestPriorOwner2
731
- } from "./server-27gq4mfz.js";
732
- import {
733
- resolveOpenCodeDbPath,
734
- assertOpenCodeStoreGeneration,
735
- openCodeDbPathExists,
736
- recordOpenCodeDbReadFailure,
737
- clearOpenCodeDbReadFailure,
738
- claimOpenCodeDbDiagnosticOnce
739
- } from "./server-2ra6pwf3.js";
740
- import {
741
- openCodeDbExists,
742
- withReadOnlySessionDb,
743
- latestPersistedMessageForRecovery,
744
- latestRealUserTurnIdFromOpenCodeDb,
745
- getMessageTimesFromOpenCodeDb,
746
- findLastAssistantModelFromOpenCodeDb
747
- } from "./server-n1prf1g6.js";
748
- import {
749
- getCurrentToolSetHash,
750
- recordToolDefinition,
751
- getMeasuredToolDefinitionTokens
752
- } from "./server-g3qma5c0.js";
765
+ } from "./server-ad18djzs.js";
753
766
  import {
754
767
  V2_MEMORY_CATEGORIES,
755
768
  CATEGORY_PRIORITY
@@ -762,7 +775,7 @@ import {
762
775
  resolveStoredPathWorkspaceIdentity,
763
776
  storedPathBelongsToWorkspace,
764
777
  computeWorkspaceEpochFingerprint
765
- } from "./server-xq7dfjke.js";
778
+ } from "./server-wwaw5npa.js";
766
779
  import {
767
780
  configureContextDatabasePragmas2
768
781
  } from "./server-fb3zxn06.js";
@@ -808,15 +821,15 @@ import {
808
821
  readGitFileChangeTimesSince,
809
822
  verificationFileExists,
810
823
  normalizeVerificationFiles
811
- } from "./server-hm38q7r0.js";
824
+ } from "./server-d48x3m4x.js";
812
825
  import {
813
826
  deriveTriggerBudget2,
814
827
  deriveHistorianChunkTokens2,
815
828
  resolveKnownHistorianContextLimit2,
816
829
  resolveHistorianProducerLimits2,
817
830
  resolveHistorianContextLimit2
818
- } from "./server-34kwfsr4.js";
819
- import"./server-d04vrx0j.js";
831
+ } from "./server-53eh1r8r.js";
832
+ import"./server-806rzhs6.js";
820
833
  import {
821
834
  isEmbeddingHostBusy2
822
835
  } from "./server-qt1qqasc.js";
@@ -829,18 +842,20 @@ import {
829
842
  releaseGitSweepLease,
830
843
  recordSessionProjectIdentity,
831
844
  hasRecordedSessionProjectIdentity
832
- } from "./server-hy3d3vsx.js";
845
+ } from "./server-bsgd4dk1.js";
833
846
  import {
834
847
  saveEmbeddingIfHashMatches,
835
848
  invalidateProject2,
836
849
  invalidateMemory2
837
850
  } from "./server-4dhv7mqz.js";
838
851
  import {
852
+ getCachedLocalEmbeddingPooling,
853
+ preflightLocalEmbeddingPooling,
839
854
  getLocalEmbeddingNativeMemoryStats
840
- } from "./server-h1v0pyxb.js";
855
+ } from "./server-vr4szghm.js";
841
856
  import {
842
857
  cosineSimilarity
843
- } from "./server-zzkj2fch.js";
858
+ } from "./server-qteg2kt9.js";
844
859
  import {
845
860
  computeCueContentHash,
846
861
  hasMuralCueColumns,
@@ -865,7 +880,7 @@ import {
865
880
  mergeMemoryStats2,
866
881
  archiveMemory2,
867
882
  getMemoryCountsByStatus2
868
- } from "./server-n37sebck.js";
883
+ } from "./server-jjvbk92s.js";
869
884
  import {
870
885
  registerNotificationSink2,
871
886
  pushNotification2,
@@ -873,11 +888,11 @@ import {
873
888
  drainNotifications2,
874
889
  isTuiConnected2
875
890
  } from "./server-x8a7jmkh.js";
876
- import"./server-h0410h0v.js";
891
+ import"./server-1bw1wcbp.js";
877
892
  import {
878
893
  flushIgnoredMessages2,
879
894
  sendStatusNotification2
880
- } from "./server-a9xqj88f.js";
895
+ } from "./server-6v3cdzsx.js";
881
896
  import {
882
897
  renderSingleStoreMigrationRequiredRefusal,
883
898
  SingleStoreMigrationRequiredError,
@@ -897,14 +912,14 @@ import {
897
912
  resolveMemoriesByIdsForSearch2,
898
913
  unifiedSearch2,
899
914
  formatSearchResults2
900
- } from "./server-gsxjv2q2.js";
915
+ } from "./server-33nqbqkw.js";
901
916
  import {
902
917
  resolvePromptContext2
903
918
  } from "./server-fmsr7v69.js";
904
919
  import"./server-kaqs6h31.js";
905
920
  import {
906
921
  renderSearchArchiveOffThread2
907
- } from "./server-45q69hkq.js";
922
+ } from "./server-132h8twc.js";
908
923
  import {
909
924
  compareSemverCore
910
925
  } from "./server-84w6rvvf.js";
@@ -944,7 +959,7 @@ import {
944
959
  } from "./server-8ajstryz.js";
945
960
  import {
946
961
  logSlowWriteTransaction
947
- } from "./server-6pmqg9m4.js";
962
+ } from "./server-gyy4k6mf.js";
948
963
  import {
949
964
  shouldEnforcePrivateStoragePermissions,
950
965
  ensureStorageDirectorySync,
@@ -1720,6 +1735,270 @@ function summarizeManualDream(summary) {
1720
1735
  `);
1721
1736
  }
1722
1737
 
1738
+ // src/features/magic-context/message-index-async.ts
1739
+ var indexCancellations = new Map;
1740
+ var sessionEpochs = new Map;
1741
+ var workerMeasurements = new WeakMap;
1742
+ function isDatabaseLockedError(error) {
1743
+ if (!error || typeof error !== "object")
1744
+ return false;
1745
+ const e = error;
1746
+ if (typeof e.code === "string") {
1747
+ if (e.code === "SQLITE_BUSY" || e.code === "SQLITE_LOCKED")
1748
+ return true;
1749
+ }
1750
+ if (typeof e.message === "string") {
1751
+ if (/database is locked/i.test(e.message))
1752
+ return true;
1753
+ if (/sqlite_(busy|locked)/i.test(e.message))
1754
+ return true;
1755
+ }
1756
+ return false;
1757
+ }
1758
+ var RECONCILIATION_BATCH_SIZE = 100;
1759
+
1760
+ class MagicContextMessageIndexHeapHolder {
1761
+ reconciledSessions = new Set;
1762
+ reconciledSnapshots = new Map;
1763
+ stalledSessions = new Set;
1764
+ reconciliationScheduledSessions = new Set;
1765
+ clearAndReindexScheduledSessions = new Map;
1766
+ sessionLocks = new Map;
1767
+ incrementalTimers = new Map;
1768
+ pendingIncrementalKeys = new Set;
1769
+ completedIncrementalKeys = new Set;
1770
+ activeReconcilerBuffers = new Map;
1771
+ }
1772
+ var heapHolder = new MagicContextMessageIndexHeapHolder;
1773
+ function clearCompletedIncrementalKeys(sessionId) {
1774
+ const prefix = `${sessionId}\x00`;
1775
+ for (const key of heapHolder.completedIncrementalKeys) {
1776
+ if (key.startsWith(prefix))
1777
+ heapHolder.completedIncrementalKeys.delete(key);
1778
+ }
1779
+ }
1780
+ var PREPARE_RETRY_MS = 60000;
1781
+ async function sourceReady(source, sessionId) {
1782
+ const prepare = source?.prepare;
1783
+ return typeof prepare === "function" ? prepare(sessionId) : true;
1784
+ }
1785
+ function defer(fn) {
1786
+ const immediate = globalThis.setImmediate;
1787
+ if (typeof immediate === "function") {
1788
+ inRootAsyncContext2(() => immediate(fn));
1789
+ return;
1790
+ }
1791
+ inRootAsyncContext2(() => setTimeout(fn, 0));
1792
+ }
1793
+ function yieldToEventLoop() {
1794
+ return new Promise((resolve) => defer(resolve));
1795
+ }
1796
+ function runWithSessionLock(sessionId, operation) {
1797
+ const previous = heapHolder.sessionLocks.get(sessionId) ?? Promise.resolve();
1798
+ const run = previous.catch(() => {
1799
+ return;
1800
+ }).then(async () => {
1801
+ await operation();
1802
+ });
1803
+ heapHolder.sessionLocks.set(sessionId, run);
1804
+ run.finally(() => {
1805
+ if (heapHolder.sessionLocks.get(sessionId) === run) {
1806
+ heapHolder.sessionLocks.delete(sessionId);
1807
+ }
1808
+ }).catch(() => {
1809
+ return;
1810
+ });
1811
+ return run;
1812
+ }
1813
+ function logIndexingError(sessionId, action, error) {
1814
+ if (isDatabaseLockedError(error)) {
1815
+ sessionLog2(sessionId, `message FTS async ${action} skipped (database busy; will retry on next reconciliation)`);
1816
+ return;
1817
+ }
1818
+ sessionLog2(sessionId, `message FTS async ${action} failed: ${error instanceof Error ? error.message : String(error)}`);
1819
+ log2(`[message-index-async] ${action} failed for ${sessionId}:`, error);
1820
+ }
1821
+ function serializedMessageBytes(messages) {
1822
+ try {
1823
+ return Buffer.byteLength(JSON.stringify(messages));
1824
+ } catch {
1825
+ return 0;
1826
+ }
1827
+ }
1828
+ function logReconciliationStall(sessionId, reason) {
1829
+ if (heapHolder.stalledSessions.has(sessionId))
1830
+ return;
1831
+ heapHolder.stalledSessions.add(sessionId);
1832
+ sessionLog2(sessionId, `message FTS reconciliation stalled: ${reason}; will retry`);
1833
+ }
1834
+ async function reconcileSessionIndex(db, sessionId, readMessages) {
1835
+ if (!await sourceReady(readMessages, sessionId)) {
1836
+ logReconciliationStall(sessionId, "raw message reader is not ready");
1837
+ return false;
1838
+ }
1839
+ await runWithSessionLock(sessionId, async () => {
1840
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId))
1841
+ return;
1842
+ let fallbackSnapshot = null;
1843
+ try {
1844
+ const fullReader = typeof readMessages === "function" ? readMessages : null;
1845
+ const revision = readMessages.getRevision?.(sessionId);
1846
+ const previous = heapHolder.reconciledSnapshots.get(sessionId);
1847
+ const finalWatermark = previous && revision === previous.revision ? previous.count : revision !== undefined && readMessages.getCountAfterRevision ? previous && revision > previous.revision ? previous.count + readMessages.getCountAfterRevision(sessionId, previous.revision, revision) : readMessages.getCountAfterRevision(sessionId, -1, revision) : readMessages.getCount ? readMessages.getCount(sessionId) : (fallbackSnapshot = fullReader?.(sessionId) ?? []).length;
1848
+ let cursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
1849
+ let after = cursor === previous?.count ? previous.after : undefined;
1850
+ while (cursor < finalWatermark) {
1851
+ const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
1852
+ const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
1853
+ const retainedMessages = fallbackSnapshot ?? messages;
1854
+ heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
1855
+ withSqliteBackgroundWriter2(() => indexMessagesAfterOrdinal2(db, sessionId, messages, cursor, pageEnd));
1856
+ const nextCursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
1857
+ if (nextCursor <= cursor)
1858
+ break;
1859
+ cursor = nextCursor;
1860
+ const last = messages.at(-1);
1861
+ after = last?.ordinal === cursor && typeof last.createdAt === "number" ? { timeCreated: last.createdAt, id: last.id } : undefined;
1862
+ if (cursor < finalWatermark) {
1863
+ await yieldToEventLoop();
1864
+ }
1865
+ }
1866
+ if (isMessageIndexReconciledThrough2(db, sessionId, finalWatermark)) {
1867
+ heapHolder.reconciledSessions.add(sessionId);
1868
+ if (revision !== undefined) {
1869
+ if (!after && finalWatermark > 0 && readMessages.readPage) {
1870
+ const last = readMessages.readPage(sessionId, finalWatermark - 1, 1, finalWatermark).at(-1);
1871
+ if (last?.ordinal === finalWatermark && typeof last.createdAt === "number")
1872
+ after = { timeCreated: last.createdAt, id: last.id };
1873
+ }
1874
+ heapHolder.reconciledSnapshots.set(sessionId, {
1875
+ revision,
1876
+ count: finalWatermark,
1877
+ after
1878
+ });
1879
+ }
1880
+ } else {
1881
+ logReconciliationStall(sessionId, `gap after ordinal ${cursor} (store count ${finalWatermark})`);
1882
+ }
1883
+ } finally {
1884
+ heapHolder.activeReconcilerBuffers.delete(sessionId);
1885
+ }
1886
+ });
1887
+ return true;
1888
+ }
1889
+ function scheduleReconciliation(db, sessionId, readMessages) {
1890
+ if (!readMessages.getRevision && heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
1891
+ return;
1892
+ }
1893
+ heapHolder.reconciliationScheduledSessions.add(sessionId);
1894
+ scheduleAfterBootQuiet(() => {
1895
+ defer(() => {
1896
+ let appendedDuringReconciliation = false;
1897
+ const previousSnapshot = heapHolder.reconciledSnapshots.get(sessionId);
1898
+ reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
1899
+ if (ran) {
1900
+ const snapshot = heapHolder.reconciledSnapshots.get(sessionId);
1901
+ appendedDuringReconciliation = snapshot !== undefined && snapshot !== previousSnapshot && readMessages.getRevision !== undefined && readMessages.getRevision(sessionId) !== snapshot.revision;
1902
+ return;
1903
+ }
1904
+ inRootAsyncContext2(() => setTimeout(() => {
1905
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
1906
+ scheduleReconciliation(db, sessionId, readMessages);
1907
+ }, PREPARE_RETRY_MS)).unref?.();
1908
+ }).catch((error) => {
1909
+ logReconciliationStall(sessionId, error instanceof Error ? error.message : String(error));
1910
+ if (isDatabaseLockedError(error))
1911
+ inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
1912
+ }).finally(() => {
1913
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
1914
+ if (appendedDuringReconciliation)
1915
+ scheduleReconciliation(db, sessionId, readMessages);
1916
+ });
1917
+ });
1918
+ });
1919
+ }
1920
+ async function sweepOrphanedOpenCodeMessageIndexesOffThread(db, openSource, options = {}) {
1921
+ if (getHarness2() === "opencode" || getHarness2() === "opencode2")
1922
+ options = {
1923
+ ...options,
1924
+ fenceLockNames: options.fenceLockNames ?? takeLkgRecoveryLockSweepPage()
1925
+ };
1926
+ if (getHarness2() === "opencode2")
1927
+ openSource = () => new Database2(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"), {
1928
+ readonly: true,
1929
+ fileMustExist: true
1930
+ });
1931
+ const path = getSqliteDatabasePath2(db);
1932
+ if (!path || getHarness2() !== "opencode" && getHarness2() !== "opencode2")
1933
+ return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, openSource, options);
1934
+ let source = null;
1935
+ let sourcePath = null;
1936
+ try {
1937
+ source = openSource();
1938
+ if (source)
1939
+ sourcePath = getSqliteDatabasePath2(source);
1940
+ } catch {} finally {
1941
+ if (sourcePath)
1942
+ source?.close();
1943
+ }
1944
+ if (!sourcePath)
1945
+ return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, () => source, options);
1946
+ const reply = await runSessionWarmupWorker({
1947
+ path,
1948
+ sessionId: "",
1949
+ harness: getHarness2(),
1950
+ orphanSweep: { sourcePath, options }
1951
+ }, {});
1952
+ if (!("orphanSweep" in reply))
1953
+ throw new Error("message history orphan sweep worker failed");
1954
+ return reply.orphanSweep;
1955
+ }
1956
+ function scheduleClearAndReindex(db, sessionId, readMessages) {
1957
+ heapHolder.reconciledSessions.delete(sessionId);
1958
+ heapHolder.reconciledSnapshots.delete(sessionId);
1959
+ heapHolder.reconciliationScheduledSessions.delete(sessionId);
1960
+ clearCompletedIncrementalKeys(sessionId);
1961
+ const existing = heapHolder.clearAndReindexScheduledSessions.get(sessionId);
1962
+ if (existing) {
1963
+ existing.source = readMessages;
1964
+ return;
1965
+ }
1966
+ const pending = { source: readMessages };
1967
+ heapHolder.clearAndReindexScheduledSessions.set(sessionId, pending);
1968
+ scheduleAfterBootQuiet(() => {
1969
+ defer(() => {
1970
+ let cleared = false;
1971
+ runWithSessionLock(sessionId, () => {
1972
+ if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) !== pending)
1973
+ return;
1974
+ heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
1975
+ heapHolder.reconciledSessions.delete(sessionId);
1976
+ heapHolder.reconciledSnapshots.delete(sessionId);
1977
+ clearCompletedIncrementalKeys(sessionId);
1978
+ clearIndexedMessages2(db, sessionId);
1979
+ cleared = true;
1980
+ }).then(() => cleared ? reconcileSessionIndex(db, sessionId, pending.source) : undefined).catch((error) => {
1981
+ heapHolder.reconciledSessions.delete(sessionId);
1982
+ if (heapHolder.clearAndReindexScheduledSessions.get(sessionId) === pending)
1983
+ heapHolder.clearAndReindexScheduledSessions.delete(sessionId);
1984
+ logIndexingError(sessionId, "clear and reindex", error);
1985
+ });
1986
+ });
1987
+ });
1988
+ }
1989
+ function getMessageIndexQueueHeapStats() {
1990
+ return {
1991
+ queueLength: heapHolder.reconciliationScheduledSessions.size + heapHolder.incrementalTimers.size + heapHolder.pendingIncrementalKeys.size,
1992
+ reconciliationScheduled: heapHolder.reconciliationScheduledSessions.size,
1993
+ incrementalTimers: heapHolder.incrementalTimers.size,
1994
+ pendingIncremental: heapHolder.pendingIncrementalKeys.size,
1995
+ activeSessionLocks: heapHolder.sessionLocks.size,
1996
+ completedIncrementalKeys: heapHolder.completedIncrementalKeys.size,
1997
+ activeBufferMessages: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + messages.length, 0),
1998
+ activeBufferBytes: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + serializedMessageBytes(messages), 0)
1999
+ };
2000
+ }
2001
+
1723
2002
  // src/shared/model-cache-ttl.ts
1724
2003
  var MODEL_CACHE_LIFETIMES = [
1725
2004
  {
@@ -3182,7 +3461,7 @@ function dropCompartmentsAfter(db, sessionId, anchor, holderId, activeBranch = f
3182
3461
  if (marker && clearPendingPiCompactionMarkerStateIf(db, sessionId, marker, null))
3183
3462
  clearedMarker = marker;
3184
3463
  }
3185
- deleteChunkEmbedBackoffForSession(db, sessionId);
3464
+ deleteChunkEmbedBackoffForSession2(db, sessionId);
3186
3465
  queueM0Mutation(db, { sessionId, mutationType: "recomp_boundary_change" });
3187
3466
  clearCachedM0M1(db, sessionId);
3188
3467
  db.exec("COMMIT");
@@ -3298,192 +3577,6 @@ function capDreamerReadOutput(input, output) {
3298
3577
  return true;
3299
3578
  }
3300
3579
 
3301
- // src/features/magic-context/message-index-async.ts
3302
- var indexCancellations = new Map;
3303
- var sessionEpochs = new Map;
3304
- var workerMeasurements = new WeakMap;
3305
- function isDatabaseLockedError(error) {
3306
- if (!error || typeof error !== "object")
3307
- return false;
3308
- const e = error;
3309
- if (typeof e.code === "string") {
3310
- if (e.code === "SQLITE_BUSY" || e.code === "SQLITE_LOCKED")
3311
- return true;
3312
- }
3313
- if (typeof e.message === "string") {
3314
- if (/database is locked/i.test(e.message))
3315
- return true;
3316
- if (/sqlite_(busy|locked)/i.test(e.message))
3317
- return true;
3318
- }
3319
- return false;
3320
- }
3321
- var RECONCILIATION_BATCH_SIZE = 100;
3322
-
3323
- class MagicContextMessageIndexHeapHolder {
3324
- reconciledSessions = new Set;
3325
- reconciliationScheduledSessions = new Set;
3326
- clearAndReindexScheduledSessions = new Map;
3327
- sessionLocks = new Map;
3328
- incrementalTimers = new Map;
3329
- pendingIncrementalKeys = new Set;
3330
- completedIncrementalKeys = new Set;
3331
- activeReconcilerBuffers = new Map;
3332
- }
3333
- var heapHolder = new MagicContextMessageIndexHeapHolder;
3334
- var PREPARE_RETRY_MS = 60000;
3335
- async function sourceReady(source, sessionId) {
3336
- const prepare = source?.prepare;
3337
- return typeof prepare === "function" ? prepare(sessionId) : true;
3338
- }
3339
- function defer(fn) {
3340
- const immediate = globalThis.setImmediate;
3341
- if (typeof immediate === "function") {
3342
- inRootAsyncContext2(() => immediate(fn));
3343
- return;
3344
- }
3345
- inRootAsyncContext2(() => setTimeout(fn, 0));
3346
- }
3347
- function yieldToEventLoop() {
3348
- return new Promise((resolve) => defer(resolve));
3349
- }
3350
- function runWithSessionLock(sessionId, operation) {
3351
- const previous = heapHolder.sessionLocks.get(sessionId) ?? Promise.resolve();
3352
- const run = previous.catch(() => {
3353
- return;
3354
- }).then(async () => {
3355
- await operation();
3356
- });
3357
- heapHolder.sessionLocks.set(sessionId, run);
3358
- run.finally(() => {
3359
- if (heapHolder.sessionLocks.get(sessionId) === run) {
3360
- heapHolder.sessionLocks.delete(sessionId);
3361
- }
3362
- }).catch(() => {
3363
- return;
3364
- });
3365
- return run;
3366
- }
3367
- function logIndexingError(sessionId, action, error) {
3368
- if (isDatabaseLockedError(error)) {
3369
- sessionLog2(sessionId, `message FTS async ${action} skipped (database busy; will retry on next reconciliation)`);
3370
- return;
3371
- }
3372
- sessionLog2(sessionId, `message FTS async ${action} failed: ${error instanceof Error ? error.message : String(error)}`);
3373
- log2(`[message-index-async] ${action} failed for ${sessionId}:`, error);
3374
- }
3375
- function serializedMessageBytes(messages) {
3376
- try {
3377
- return Buffer.byteLength(JSON.stringify(messages));
3378
- } catch {
3379
- return 0;
3380
- }
3381
- }
3382
- async function reconcileSessionIndex(db, sessionId, readMessages) {
3383
- if (!await sourceReady(readMessages, sessionId))
3384
- return false;
3385
- await runWithSessionLock(sessionId, async () => {
3386
- if (heapHolder.reconciledSessions.has(sessionId))
3387
- return;
3388
- let fallbackSnapshot = null;
3389
- try {
3390
- const fullReader = typeof readMessages === "function" ? readMessages : null;
3391
- const finalWatermark = readMessages.getCount ? readMessages.getCount(sessionId) : (fallbackSnapshot = fullReader?.(sessionId) ?? []).length;
3392
- let cursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
3393
- let after;
3394
- while (cursor < finalWatermark) {
3395
- const pageEnd = Math.min(finalWatermark, cursor + RECONCILIATION_BATCH_SIZE);
3396
- const messages = readMessages.readPage ? readMessages.readPage(sessionId, cursor, RECONCILIATION_BATCH_SIZE, finalWatermark, after) : (fallbackSnapshot ?? []).filter((message) => message.ordinal > cursor && message.ordinal <= pageEnd);
3397
- const retainedMessages = fallbackSnapshot ?? messages;
3398
- heapHolder.activeReconcilerBuffers.set(sessionId, retainedMessages);
3399
- withSqliteBackgroundWriter2(() => indexMessagesAfterOrdinal2(db, sessionId, messages, cursor, pageEnd));
3400
- const nextCursor = getMessageIndexReconciliationStartOrdinal2(db, sessionId);
3401
- if (nextCursor <= cursor)
3402
- break;
3403
- cursor = nextCursor;
3404
- const last = messages.at(-1);
3405
- after = last?.ordinal === cursor && typeof last.createdAt === "number" ? { timeCreated: last.createdAt, id: last.id } : undefined;
3406
- if (cursor < finalWatermark) {
3407
- await yieldToEventLoop();
3408
- }
3409
- }
3410
- if (isMessageIndexReconciledThrough2(db, sessionId, finalWatermark)) {
3411
- heapHolder.reconciledSessions.add(sessionId);
3412
- }
3413
- } finally {
3414
- heapHolder.activeReconcilerBuffers.delete(sessionId);
3415
- }
3416
- });
3417
- return true;
3418
- }
3419
- function scheduleReconciliation(db, sessionId, readMessages) {
3420
- if (heapHolder.reconciledSessions.has(sessionId) || heapHolder.reconciliationScheduledSessions.has(sessionId)) {
3421
- return;
3422
- }
3423
- heapHolder.reconciliationScheduledSessions.add(sessionId);
3424
- scheduleAfterBootQuiet(() => {
3425
- defer(() => {
3426
- reconcileSessionIndex(db, sessionId, readMessages).then((ran) => {
3427
- if (ran)
3428
- return;
3429
- inRootAsyncContext2(() => setTimeout(() => {
3430
- heapHolder.reconciliationScheduledSessions.delete(sessionId);
3431
- scheduleReconciliation(db, sessionId, readMessages);
3432
- }, PREPARE_RETRY_MS)).unref?.();
3433
- }).catch((error) => {
3434
- logIndexingError(sessionId, "reconciliation", error);
3435
- if (isDatabaseLockedError(error))
3436
- inRootAsyncContext2(() => setTimeout(() => scheduleReconciliation(db, sessionId, readMessages), 1000)).unref();
3437
- }).finally(() => {
3438
- heapHolder.reconciliationScheduledSessions.delete(sessionId);
3439
- });
3440
- });
3441
- });
3442
- }
3443
- async function sweepOrphanedOpenCodeMessageIndexesOffThread(db, openSource, options = {}) {
3444
- if (getHarness2() === "opencode2")
3445
- openSource = () => new Database2(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"), {
3446
- readonly: true,
3447
- fileMustExist: true
3448
- });
3449
- const path = getSqliteDatabasePath2(db);
3450
- if (!path || getHarness2() !== "opencode" && getHarness2() !== "opencode2")
3451
- return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, openSource, options);
3452
- let source = null;
3453
- let sourcePath = null;
3454
- try {
3455
- source = openSource();
3456
- if (source)
3457
- sourcePath = getSqliteDatabasePath2(source);
3458
- } catch {} finally {
3459
- if (sourcePath)
3460
- source?.close();
3461
- }
3462
- if (!sourcePath)
3463
- return sweepOrphanedOpenCodeMessageIndexesCooperatively2(db, () => source, options);
3464
- const reply = await runSessionWarmupWorker({
3465
- path,
3466
- sessionId: "",
3467
- harness: getHarness2(),
3468
- orphanSweep: { sourcePath, options }
3469
- }, {});
3470
- if (!("orphanSweep" in reply))
3471
- throw new Error("message history orphan sweep worker failed");
3472
- return reply.orphanSweep;
3473
- }
3474
- function getMessageIndexQueueHeapStats() {
3475
- return {
3476
- queueLength: heapHolder.reconciliationScheduledSessions.size + heapHolder.incrementalTimers.size + heapHolder.pendingIncrementalKeys.size,
3477
- reconciliationScheduled: heapHolder.reconciliationScheduledSessions.size,
3478
- incrementalTimers: heapHolder.incrementalTimers.size,
3479
- pendingIncremental: heapHolder.pendingIncrementalKeys.size,
3480
- activeSessionLocks: heapHolder.sessionLocks.size,
3481
- completedIncrementalKeys: heapHolder.completedIncrementalKeys.size,
3482
- activeBufferMessages: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + messages.length, 0),
3483
- activeBufferBytes: [...heapHolder.activeReconcilerBuffers.values()].reduce((sum, messages) => sum + serializedMessageBytes(messages), 0)
3484
- };
3485
- }
3486
-
3487
3580
  // src/plugin/sidebar-snapshot-cache.ts
3488
3581
  var MAX_CACHED_SESSIONS = 100;
3489
3582
  var STALE_SNAPSHOT_AGE_MS = 5 * 60 * 1000;
@@ -4145,7 +4238,8 @@ ${trimmedBody}…
4145
4238
  return wrapped;
4146
4239
  }
4147
4240
  function selectAutoSearchResults(results, threshold) {
4148
- return results.filter((result) => (result.relevanceScore ?? result.score) >= threshold);
4241
+ const relevance = (result) => result.relevanceScore ?? result.score;
4242
+ return results.filter((result) => relevance(result) >= threshold).sort((left, right) => relevance(right) - relevance(left));
4149
4243
  }
4150
4244
 
4151
4245
  // src/hooks/magic-context/auto-search-worker-client.ts
@@ -4238,22 +4332,42 @@ function retryUnpublishedAutoSearchNoHint(db, sessionId, messageId, startedAt) {
4238
4332
  }
4239
4333
  return true;
4240
4334
  }
4335
+
4336
+ class AutoSearchBusyError extends Error {
4337
+ constructor() {
4338
+ super("an earlier auto-search of this session is still running");
4339
+ this.name = "AutoSearchBusyError";
4340
+ }
4341
+ }
4241
4342
  async function searchAutoHint(db, sessionId, projectPath, query, options, entry = new URL(new URL(import.meta.url).pathname.endsWith(".ts") ? "./auto-search-worker.ts" : "./auto-search-worker.js", import.meta.url)) {
4242
- return executeAutoSearchWorker(db, sessionId, projectPath, query, options, entry, "search");
4343
+ const {
4344
+ rerankConfig: _rerankConfig,
4345
+ rerankClient: _rerankClient,
4346
+ rerankConnectionFile: _rerankConnectionFile,
4347
+ onRerankSkipped: _onRerankSkipped,
4348
+ captureRerankLanes: _captureRerankLanes,
4349
+ ...hintOptions
4350
+ } = options;
4351
+ return executeAutoSearchWorker(db, sessionId, projectPath, query, { ...hintOptions, explicitSearch: false, rerank: false }, entry, "search");
4243
4352
  }
4244
4353
  var pendingBackfills = new WeakMap;
4245
4354
  var searchWorkers = new WeakMap;
4246
4355
  var liveSearchWorkers = new Set;
4247
4356
  var MAX_IDLE_SEARCH_WORKERS = 4;
4248
4357
  var SEARCH_WORKER_IDLE_MS = 5 * 60000;
4358
+ var DETACHED_SEARCH_LIMIT_MS = 30000;
4359
+ var AUTO_SEARCH_WORKER_CLOSE_DEADLINE_MS = 2000;
4249
4360
  var workersCreated = 0;
4250
4361
  var workersReused = 0;
4362
+ var searchesSkippedBusy = 0;
4251
4363
  async function acquireSearchWorker(db, key, entry, input, signal) {
4252
4364
  const pool = searchWorkers.get(db) ?? new Map;
4253
4365
  searchWorkers.set(db, pool);
4254
4366
  while (!signal.aborted) {
4255
4367
  let slot = pool.get(key);
4256
4368
  if (slot?.busy) {
4369
+ if (input.job === "search" && (slot.detached || slot.busySessionId === input.sessionId))
4370
+ return "busy";
4257
4371
  const current = slot;
4258
4372
  await new Promise((resolve) => {
4259
4373
  const done = () => {
@@ -4262,6 +4376,8 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
4262
4376
  };
4263
4377
  signal.addEventListener("abort", done, { once: true });
4264
4378
  current.busy?.then(done);
4379
+ if (!current.detached)
4380
+ current.detachedSignal?.then(done);
4265
4381
  if (signal.aborted)
4266
4382
  done();
4267
4383
  });
@@ -4270,14 +4386,16 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
4270
4386
  const fresh = !slot;
4271
4387
  if (!slot) {
4272
4388
  const worker = inRootAsyncContext2(() => new Worker(entry, { workerData: { ...input, persistent: true } }));
4389
+ const shutdown = createWorkerShutdown(worker, "auto-search", AUTO_SEARCH_WORKER_CLOSE_DEADLINE_MS);
4273
4390
  slot = {
4274
4391
  worker,
4275
4392
  dispose() {
4393
+ this.disposed = true;
4276
4394
  clearTimeout(this.idleTimer);
4277
4395
  if (pool.get(key) === this)
4278
4396
  pool.delete(key);
4279
4397
  liveSearchWorkers.delete(this);
4280
- worker.terminate();
4398
+ shutdown.close();
4281
4399
  worker.unref();
4282
4400
  }
4283
4401
  };
@@ -4291,9 +4409,14 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
4291
4409
  workersReused++;
4292
4410
  clearTimeout(slot.idleTimer);
4293
4411
  const current = slot;
4412
+ current.busySessionId = input.sessionId;
4413
+ current.detached = false;
4294
4414
  current.busy = new Promise((resolve) => {
4295
4415
  current.release = resolve;
4296
4416
  });
4417
+ current.detachedSignal = new Promise((resolve) => {
4418
+ current.markDetached = resolve;
4419
+ });
4297
4420
  current.worker.ref();
4298
4421
  return { slot: current, fresh };
4299
4422
  }
@@ -4302,6 +4425,9 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
4302
4425
  function queueAutoSearchBackfill(db, sessionId, projectPath, query) {
4303
4426
  if (isEmbeddingHostBusy2())
4304
4427
  return Promise.resolve();
4428
+ const snapshot = getProjectEmbeddingSnapshot2(projectPath);
4429
+ if (!snapshot?.enabled || !snapshot.features.memoryEnabled)
4430
+ return Promise.resolve();
4305
4431
  const key = `${sessionId}\x00${projectPath}`;
4306
4432
  const pending = pendingBackfills.get(db) ?? new Map;
4307
4433
  pendingBackfills.set(db, pending);
@@ -4349,6 +4475,7 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4349
4475
  signal: deadlineSignal,
4350
4476
  readMessages: _readMessages,
4351
4477
  searchMessageHistory: _searchMessageHistory,
4478
+ stepTimings: _stepTimings,
4352
4479
  ...serializable
4353
4480
  } = options;
4354
4481
  const lifecycle = registerAutoSearchWork(sessionId);
@@ -4384,30 +4511,55 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4384
4511
  lifecycle.done();
4385
4512
  return [];
4386
4513
  }
4514
+ if (lease === "busy") {
4515
+ lifecycle.done();
4516
+ searchesSkippedBusy++;
4517
+ throw new AutoSearchBusyError;
4518
+ }
4387
4519
  const { slot, fresh } = lease;
4388
4520
  const worker = slot.worker;
4521
+ const detachable = job === "search" && entry.href === defaultAutoSearchWorkerEntry().href;
4522
+ const startedAt = performance.now();
4523
+ let detachedAt;
4524
+ let ownerVectorMs;
4525
+ let abandonTimer;
4389
4526
  return new Promise((resolve, reject) => {
4390
4527
  let settled = false;
4391
- const finish = (results, error) => {
4528
+ let released = false;
4529
+ const settle = (results, error) => {
4392
4530
  if (settled)
4393
4531
  return;
4394
4532
  settled = true;
4533
+ if (error)
4534
+ reject(error);
4535
+ else
4536
+ resolve(results);
4537
+ };
4538
+ const release = (dispose) => {
4539
+ if (released)
4540
+ return;
4541
+ released = true;
4542
+ clearTimeout(abandonTimer);
4395
4543
  signal?.removeEventListener("abort", abort);
4396
4544
  lifecycle.signal.removeEventListener("abort", abort);
4397
4545
  lifecycle.done();
4398
4546
  worker.off("message", onMessage);
4399
4547
  worker.off("error", onError);
4400
4548
  worker.off("exit", onExit);
4401
- if (error || signal.aborted || entry.href !== defaultAutoSearchWorkerEntry().href)
4549
+ if (dispose || !detachable)
4402
4550
  slot.dispose();
4403
- else {
4551
+ else if (!slot.disposed) {
4404
4552
  slot.idleTimer = setTimeout(() => slot.dispose(), SEARCH_WORKER_IDLE_MS);
4405
4553
  slot.idleTimer.unref?.();
4406
4554
  }
4407
- const release = slot.release;
4555
+ const free = slot.release;
4408
4556
  slot.busy = undefined;
4409
4557
  slot.release = undefined;
4410
- release?.();
4558
+ slot.busySessionId = undefined;
4559
+ slot.detached = false;
4560
+ slot.detachedSignal = undefined;
4561
+ slot.markDetached = undefined;
4562
+ free?.();
4411
4563
  const reusable = liveSearchWorkers.delete(slot);
4412
4564
  if (reusable)
4413
4565
  liveSearchWorkers.add(slot);
@@ -4415,51 +4567,82 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4415
4567
  for (const prior of idle.slice(0, Math.max(0, idle.length - MAX_IDLE_SEARCH_WORKERS)))
4416
4568
  prior.dispose();
4417
4569
  worker.unref();
4418
- if (error)
4419
- reject(error);
4420
- else
4421
- resolve(results);
4422
4570
  };
4423
- const abort = () => finish([]);
4571
+ const finish = (results, error) => {
4572
+ settle(results, error);
4573
+ release(Boolean(error) || signal.aborted);
4574
+ };
4575
+ const abort = () => {
4576
+ if (lifecycle.signal.aborted || !detachable) {
4577
+ finish([]);
4578
+ return;
4579
+ }
4580
+ if (settled)
4581
+ return;
4582
+ detachedAt = performance.now();
4583
+ slot.detached = true;
4584
+ slot.markDetached?.();
4585
+ settle([]);
4586
+ abandonTimer = setTimeout(() => {
4587
+ log2(`[auto-search] session ${sessionId}: search still running ${DETACHED_SEARCH_LIMIT_MS} ms after its deadline; disposing its worker (owner vector wait ${formatMs(ownerVectorMs)})`);
4588
+ release(true);
4589
+ }, DETACHED_SEARCH_LIMIT_MS);
4590
+ abandonTimer.unref?.();
4591
+ };
4424
4592
  signal?.addEventListener("abort", abort, { once: true });
4425
4593
  lifecycle.signal.addEventListener("abort", abort, { once: true });
4426
4594
  const onError = (error) => finish([], error);
4427
4595
  const onExit = (code) => finish([], new Error(`auto-search worker exited (${code})`));
4428
4596
  const onMessage = async (reply) => {
4429
- if (settled)
4597
+ if (released)
4430
4598
  return;
4431
- if (reply.kind === "result") {
4599
+ if (reply.kind === "result" || reply.kind === "error") {
4600
+ if (detachedAt !== undefined) {
4601
+ logLateSearch(sessionId, performance.now() - detachedAt, detachedAt - startedAt, ownerVectorMs, reply.kind === "result" ? reply.timings : undefined, reply.kind === "error");
4602
+ release(reply.kind === "error");
4603
+ return;
4604
+ }
4605
+ if (reply.kind === "error") {
4606
+ finish([], new Error(reply.error));
4607
+ return;
4608
+ }
4432
4609
  if (snapshot && getProjectEmbeddingSnapshot2(projectPath)?.generation !== snapshot.generation)
4433
4610
  finish([]);
4434
4611
  else
4435
4612
  finish(reply.results);
4436
4613
  return;
4437
4614
  }
4438
- if (reply.kind === "error") {
4439
- finish([], new Error(reply.error));
4440
- return;
4441
- }
4442
4615
  if (reply.kind === "messages" || reply.kind === "accepted")
4443
4616
  return;
4444
4617
  const response = { id: reply.id };
4445
- try {
4618
+ if (!signal.aborted) {
4619
+ const requestedAt = performance.now();
4620
+ try {
4621
+ if (reply.kind === "query")
4622
+ response.result = await (job === "backfill" ? embedTextForProject2(projectPath, reply.text, signal, "query") : boundedHintEmbedding(embedQuery, reply.text, signal)) ?? null;
4623
+ else {
4624
+ const passage = await embedBatchForProject2(projectPath, reply.texts, signal, reply.purpose);
4625
+ const current = getProjectEmbeddingSnapshot2(projectPath);
4626
+ response.passage = passage && current ? {
4627
+ ...passage,
4628
+ providerIdentity: current.providerIdentity,
4629
+ runtimeFingerprint: current.runtimeFingerprint,
4630
+ dimensions: passage.vectors.find((vector) => vector !== null)?.length ?? null
4631
+ } : null;
4632
+ }
4633
+ } catch (error) {
4634
+ response.error = error instanceof Error ? error.message : String(error);
4635
+ }
4446
4636
  if (reply.kind === "query")
4447
- response.result = await (job === "backfill" ? embedTextForProject2(projectPath, reply.text, signal, "query") : boundedHintEmbedding(embedQuery, reply.text, signal)) ?? null;
4448
- else {
4449
- const passage = await embedBatchForProject2(projectPath, reply.texts, signal, reply.purpose);
4450
- const current = getProjectEmbeddingSnapshot2(projectPath);
4451
- response.passage = passage && current ? {
4452
- ...passage,
4453
- providerIdentity: current.providerIdentity,
4454
- runtimeFingerprint: current.runtimeFingerprint,
4455
- dimensions: passage.vectors.find((vector) => vector !== null)?.length ?? null
4456
- } : null;
4637
+ ownerVectorMs = performance.now() - requestedAt;
4638
+ if (signal.aborted) {
4639
+ response.result = undefined;
4640
+ response.passage = undefined;
4641
+ response.error = undefined;
4457
4642
  }
4458
- } catch (error) {
4459
- response.error = error instanceof Error ? error.message : String(error);
4460
4643
  }
4461
4644
  response.embeddingHostBusy = isEmbeddingHostBusy2();
4462
- if (!settled && !signal?.aborted) {
4645
+ if (!released) {
4463
4646
  try {
4464
4647
  worker.postMessage(response);
4465
4648
  } catch (error) {
@@ -4481,6 +4664,15 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4481
4664
  }
4482
4665
  });
4483
4666
  }
4667
+ function formatMs(value) {
4668
+ return value === undefined ? "n/a" : `${Math.round(value)} ms`;
4669
+ }
4670
+ function logLateSearch(sessionId, lateMs, waitedMs, ownerVectorMs, timings, failed) {
4671
+ const steps = timings?.steps;
4672
+ const warm = timings?.lastPoolWarm;
4673
+ const pool = warm ? `last pool refresh ${warm.outcome} in ${formatMs(warm.totalMs)} (probe ${formatMs(warm.probeMs)}, read ${formatMs(warm.readMs)}, decode ${formatMs(warm.decodeMs)}, ${warm.probedRows} rows probed, ${warm.decodedRows} decoded)` : "no pool refresh yet";
4674
+ log2(`[auto-search] session ${sessionId}: deadline passed after ${formatMs(waitedMs)}; the search ${failed ? "failed" : "finished"} ${formatMs(lateMs)} later. Steps: message FTS ${formatMs(steps?.messageMs)}, vector wait ${formatMs(steps?.vectorWaitMs)} (owner embedding ${formatMs(ownerVectorMs)}), chunk lane ${formatMs(steps?.chunkMs)} (pool ${steps?.chunkPool ?? "n/a"}), other lanes ${formatMs(steps?.otherLanesMs)}, job ${formatMs(timings?.jobMs)}; ${pool}`);
4675
+ }
4484
4676
  async function boundedHintEmbedding(embed, text, signal) {
4485
4677
  const controller = new AbortController;
4486
4678
  const combined = AbortSignal.any([signal, controller.signal]);
@@ -4504,6 +4696,7 @@ function defaultAutoSearchWorkerEntry() {
4504
4696
  }
4505
4697
  var MESSAGE_WORKER_ACCEPT_TIMEOUT_MS = 400;
4506
4698
  var MESSAGE_WORKER_RESULT_TIMEOUT_MS = 30000;
4699
+ var MESSAGE_SEARCH_WORKER_CLOSE_DEADLINE_MS = 2000;
4507
4700
  var messageSearchWorkerFallbacks = new Map;
4508
4701
  function searchMessageHistoryOffThread(db, request, entry = defaultAutoSearchWorkerEntry(), deadlines = {}) {
4509
4702
  const fallback = (reason, detail) => {
@@ -4531,6 +4724,7 @@ function searchMessageHistoryOffThread(db, request, entry = defaultAutoSearchWor
4531
4724
  return new Promise((resolve) => {
4532
4725
  let settled = false;
4533
4726
  let worker;
4727
+ let shutdown;
4534
4728
  let deadline;
4535
4729
  const finish = (outcome, reason, detail) => {
4536
4730
  if (settled)
@@ -4539,7 +4733,7 @@ function searchMessageHistoryOffThread(db, request, entry = defaultAutoSearchWor
4539
4733
  clearTimeout(deadline);
4540
4734
  if (reason)
4541
4735
  fallback(reason, detail);
4542
- worker?.terminate();
4736
+ shutdown?.close();
4543
4737
  worker?.unref();
4544
4738
  resolve(outcome);
4545
4739
  };
@@ -4550,6 +4744,7 @@ function searchMessageHistoryOffThread(db, request, entry = defaultAutoSearchWor
4550
4744
  };
4551
4745
  try {
4552
4746
  worker = inRootAsyncContext2(() => new Worker(entry, { workerData: input }));
4747
+ shutdown = createWorkerShutdown(worker, "message-search", MESSAGE_SEARCH_WORKER_CLOSE_DEADLINE_MS);
4553
4748
  } catch (error) {
4554
4749
  finish(null, "start-failed", error);
4555
4750
  return;
@@ -4818,7 +5013,8 @@ async function runAutoSearchHint(args) {
4818
5013
  },
4819
5014
  isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
4820
5015
  visibleMemoryIds: options.visibleMemoryIds ?? null,
4821
- sources: ["memory", "message", "git_commit"]
5016
+ sources: ["memory", "message", "git_commit"],
5017
+ chunkPoolWarmOnly: true
4822
5018
  };
4823
5019
  return searchAutoHint(db, sessionId, options.projectPath, rawPrompt, {
4824
5020
  ...searchOptions,
@@ -4829,6 +5025,11 @@ async function runAutoSearchHint(args) {
4829
5025
  } catch (error) {
4830
5026
  if (lifecycleSignal.aborted)
4831
5027
  return AUTO_SEARCH_OK;
5028
+ if (error instanceof AutoSearchBusyError) {
5029
+ sessionLog2(sessionId, "auto-search: an earlier search of this session is still running, skipping hint for this turn");
5030
+ persistAutoSearchSkip(db, sessionId, userMsgId);
5031
+ return { ok: false, kind: "timeout" };
5032
+ }
4832
5033
  log2(`[auto-search] unified search failed for session ${sessionId} (no-hint frozen for this turn): ${error instanceof Error ? error.message : String(error)}`);
4833
5034
  const outcome = await writeNoHintAndReconcile("error");
4834
5035
  return outcome.ok ? { ok: false, kind: "search-failure" } : outcome;
@@ -4878,7 +5079,7 @@ ${hintText}`;
4878
5079
  if (outcome.decision.decision === "hint") {
4879
5080
  appendReminderToUserMessageById(messages, userMsgId, outcome.decision.text);
4880
5081
  }
4881
- sessionLog2(sessionId, `auto-search: attached hint to ${userMsgId} (${results.length} fragments, top score ${results[0].score.toFixed(3)})`);
5082
+ sessionLog2(sessionId, `auto-search: attached hint to ${userMsgId} (${results.length} fragments, top relevance ${(results[0].relevanceScore ?? results[0].score).toFixed(3)})`);
4882
5083
  return AUTO_SEARCH_OK;
4883
5084
  } finally {
4884
5085
  if (!lifecycleSignal.aborted && results !== null)
@@ -4935,6 +5136,30 @@ function getSessionErrorInfo(properties) {
4935
5136
  };
4936
5137
  }
4937
5138
 
5139
+ // src/hooks/magic-context/diagnostic-log-state.ts
5140
+ var states = new BoundedSessionMap(1000);
5141
+ var scope = (sessionId) => `${getMagicContextStorageDir()}\x00${getHarness2()}\x00${sessionId}`;
5142
+ function diagnosticStateChanged(sessionId, category, state) {
5143
+ const key = scope(sessionId);
5144
+ const previous = states.get(key) ?? new Map;
5145
+ if (previous.get(category) === state)
5146
+ return false;
5147
+ previous.set(category, state);
5148
+ states.set(key, previous);
5149
+ return true;
5150
+ }
5151
+ function clearDiagnosticLogState(sessionId) {
5152
+ states.delete(scope(sessionId));
5153
+ }
5154
+
5155
+ // src/hooks/magic-context/nudge-evaluation-log.ts
5156
+ function logNudgeEvaluation(sessionId, phase, line) {
5157
+ const category = `${phase}:${line.split(":", 1)[0]}`;
5158
+ const state = line.split(" ").filter((field) => /^(ctx_reduce|band|dampening|verdict|reason|lease)=/.test(field)).join(" ");
5159
+ if (diagnosticStateChanged(sessionId, category, state))
5160
+ sessionLog2(sessionId, line);
5161
+ }
5162
+
4938
5163
  // src/features/magic-context/dreamer/storage-task-schedule.ts
4939
5164
  function toRow(r) {
4940
5165
  return {
@@ -5811,7 +6036,7 @@ function canConsumeDeferredOnThisPass(args) {
5811
6036
  return args.schedulerDecision === "execute" || args.contextPercentage >= (args.forceMaterializationPercentage ?? escalationBands(65).forceMaterializationPercentage);
5812
6037
  }
5813
6038
  function hasReclaimRide(signals) {
5814
- return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true;
6039
+ return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true || signals.executeReclaim === true || signals.servedShapeRepair === true;
5815
6040
  }
5816
6041
  function prefixMutationPermitted(gate) {
5817
6042
  return !gate.signedThinkingHold || gate.firstRender || gate.idleExpiry || gate.emergency;
@@ -5824,13 +6049,234 @@ var RECLAIM_RIDE_NAMES = [
5824
6049
  "force",
5825
6050
  "explicitFlush",
5826
6051
  "publishedHistory",
5827
- "subagentExecute"
6052
+ "subagentExecute",
6053
+ "executeReclaim",
6054
+ "servedShapeRepair"
5828
6055
  ];
5829
6056
  function reclaimRideLabel(signals) {
5830
6057
  const active = RECLAIM_RIDE_NAMES.filter((name) => signals[name]);
5831
6058
  return `ride=${active.length > 0 ? active.join("+") : "none"}`;
5832
6059
  }
5833
6060
 
6061
+ // src/hooks/magic-context/pending-drop-eligibility.ts
6062
+ function pendingDropVeto(tagNumber, target, protectedTagIds) {
6063
+ if (protectedTagIds.has(tagNumber))
6064
+ return "protected";
6065
+ if (target?.thinkingDropProtected)
6066
+ return "active_thinking";
6067
+ return null;
6068
+ }
6069
+ function capturePendingDropEligibility(targets, protectedTagIds) {
6070
+ const eligible = new Set;
6071
+ for (const [number, target] of targets) {
6072
+ if (pendingDropVeto(number, target, protectedTagIds))
6073
+ continue;
6074
+ if (target.drop) {
6075
+ if (target.canDrop?.() === true)
6076
+ eligible.add(number);
6077
+ } else {
6078
+ const content = target.getContent?.();
6079
+ const replacement = `[dropped §${number}§]`;
6080
+ if (typeof content === "string" && content.length > replacement.length && target.canSetContent?.(replacement) !== false)
6081
+ eligible.add(number);
6082
+ }
6083
+ }
6084
+ return eligible;
6085
+ }
6086
+ function pendingDropEligibilityKey(db, sessionId, input, protectionInputs) {
6087
+ const digests = input.map((message) => message.contentDigest?.() ?? null);
6088
+ if (digests.some((digest) => digest === null))
6089
+ return null;
6090
+ const revision = db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(tagRevisionKey(sessionId));
6091
+ if (!revision?.value)
6092
+ return null;
6093
+ return JSON.stringify([
6094
+ input.map((message, index) => [
6095
+ message.id,
6096
+ message.role,
6097
+ message.synthetic,
6098
+ digests[index]
6099
+ ]),
6100
+ revision.value,
6101
+ readEpochFloorSnapshot(db, sessionId),
6102
+ sessionDecisionCalibration(db, sessionId).toolsRatio,
6103
+ loadProtectedTailMeta(db, sessionId),
6104
+ [...getMergedReasoningStrippedIds(db, sessionId)].sort(),
6105
+ [...getReasoningRemovalState(db, sessionId).messageIds].sort(),
6106
+ protectionInputs
6107
+ ]);
6108
+ }
6109
+ function createPendingDropEligibilityCache() {
6110
+ const sessions = new Map;
6111
+ return {
6112
+ read(sessionId, key) {
6113
+ const previous = sessions.get(sessionId);
6114
+ if (key === null || previous?.key !== key) {
6115
+ sessions.delete(sessionId);
6116
+ return;
6117
+ }
6118
+ return previous.eligible;
6119
+ },
6120
+ record(sessionId, key, eligible) {
6121
+ sessions.delete(sessionId);
6122
+ if (key === null)
6123
+ return;
6124
+ const oldest = sessions.keys().next().value;
6125
+ if (sessions.size >= 64 && oldest !== undefined)
6126
+ sessions.delete(oldest);
6127
+ sessions.set(sessionId, { key, eligible: new Set(eligible) });
6128
+ }
6129
+ };
6130
+ }
6131
+
6132
+ // src/hooks/magic-context/postprocess-read-cache.ts
6133
+ var connections = new WeakMap;
6134
+ function snapshot(db, sessionId) {
6135
+ const transaction = db;
6136
+ try {
6137
+ if (transaction.inTransaction || transaction.isTransaction) {
6138
+ connections.delete(db);
6139
+ return { version: -1, changes: -1 };
6140
+ }
6141
+ } catch {
6142
+ connections.delete(db);
6143
+ return { version: -1, changes: -1 };
6144
+ }
6145
+ let connection = connections.get(db);
6146
+ if (!connection) {
6147
+ connection = {
6148
+ stamp: db.prepare("SELECT total_changes() AS changes, data_version AS version FROM pragma_data_version"),
6149
+ sessions: new BoundedSessionMap(100)
6150
+ };
6151
+ connections.set(db, connection);
6152
+ }
6153
+ const stamp = connection.stamp.get();
6154
+ const previous = connection.sessions.get(sessionId);
6155
+ if (previous?.version === stamp.version && previous.changes === stamp.changes) {
6156
+ return previous;
6157
+ }
6158
+ const value = { ...stamp };
6159
+ connection.sessions.set(sessionId, value);
6160
+ return value;
6161
+ }
6162
+ function postprocessTailTags(db, sessionId) {
6163
+ const state = snapshot(db, sessionId);
6164
+ return state.tags ??= getTailHygieneTags2(db, sessionId);
6165
+ }
6166
+ function postprocessOldestTags(db, sessionId, protectedNumbers) {
6167
+ const state = snapshot(db, sessionId);
6168
+ const hints = state.hints;
6169
+ if (hints && hints.protectedNumbers.size === protectedNumbers.size && [...protectedNumbers].every((number) => hints.protectedNumbers.has(number))) {
6170
+ return hints.value;
6171
+ }
6172
+ const value = getOldestActiveUnprotectedToolTags2(db, sessionId, protectedNumbers);
6173
+ state.hints = { protectedNumbers: new Set(protectedNumbers), value };
6174
+ return value;
6175
+ }
6176
+ function postprocessReplaySnapshot(db, sessionId) {
6177
+ const state = snapshot(db, sessionId);
6178
+ const replay = state.replay ??= loadPostprocessReplaySnapshot(db, sessionId);
6179
+ return {
6180
+ ...replay,
6181
+ staleReduceStrippedIds: new Set(replay.staleReduceStrippedIds),
6182
+ processedImageStrippedIds: new Set(replay.processedImageStrippedIds),
6183
+ processedImageMarkers: new Map(replay.processedImageMarkers),
6184
+ strippedPlaceholderIds: new Set(replay.strippedPlaceholderIds),
6185
+ hiddenSeamPlaceholderIds: new Set(replay.hiddenSeamPlaceholderIds),
6186
+ mergedReasoningStrippedIds: new Set(replay.mergedReasoningStrippedIds),
6187
+ trailingBlankDecisions: new Map(replay.trailingBlankDecisions),
6188
+ noteNudgeAnchors: structuredClone(replay.noteNudgeAnchors),
6189
+ autoSearchHintDecisions: structuredClone(replay.autoSearchHintDecisions),
6190
+ todoSyntheticAnchor: structuredClone(replay.todoSyntheticAnchor),
6191
+ pendingCompactionMarker: structuredClone(replay.pendingCompactionMarker),
6192
+ compactionMarker: structuredClone(replay.compactionMarker)
6193
+ };
6194
+ }
6195
+
6196
+ // src/hooks/magic-context/execute-reclaim.ts
6197
+ var NAMESPACE = "executeReclaim";
6198
+ var failedWrites = new WeakMap;
6199
+ function readExecuteReclaimState(db, sessionId) {
6200
+ return parseState(postprocessReplaySnapshot(db, sessionId).executeReclaim);
6201
+ }
6202
+ function parseState(lane) {
6203
+ const value = lane;
6204
+ return {
6205
+ heldPasses: typeof value?.heldPasses === "number" ? Math.max(0, value.heldPasses) : 0,
6206
+ floorOrdinal: typeof value?.floorOrdinal === "number" ? value.floorOrdinal : null,
6207
+ floorPromptId: typeof value?.floorPromptId === "string" ? value.floorPromptId : null
6208
+ };
6209
+ }
6210
+ function writeExecuteReclaimState(db, sessionId, patch) {
6211
+ if (failedWrites.get(db)?.has(sessionId))
6212
+ return false;
6213
+ try {
6214
+ const current = readExecuteReclaimState(db, sessionId);
6215
+ if (JSON.stringify(current) === JSON.stringify({ ...current, ...patch }))
6216
+ return true;
6217
+ if (!updateReplayDocument(db, sessionId, (doc) => {
6218
+ const previous = parseState(doc[NAMESPACE]);
6219
+ const state = { ...previous, ...patch };
6220
+ if (JSON.stringify(previous) === JSON.stringify(state))
6221
+ return false;
6222
+ doc.version = 2;
6223
+ doc[NAMESPACE] = state;
6224
+ return true;
6225
+ }))
6226
+ throw new Error("Could not persist execute reclaim state");
6227
+ return true;
6228
+ } catch (error) {
6229
+ let failed = failedWrites.get(db);
6230
+ if (!failed)
6231
+ failedWrites.set(db, failed = new Set);
6232
+ failed.add(sessionId);
6233
+ sessionLog2(sessionId, `execute reclaim state persistence failed; retaining existing policy: ${String(error)}`);
6234
+ return false;
6235
+ }
6236
+ }
6237
+ function clearExecuteReclaimState(db, sessionId) {
6238
+ writeExecuteReclaimState(db, sessionId, {
6239
+ heldPasses: 0,
6240
+ floorOrdinal: null,
6241
+ floorPromptId: null
6242
+ });
6243
+ }
6244
+ function maintainExecuteFloorMark(db, sessionId, promptId, belowExecute) {
6245
+ failedWrites.get(db)?.delete(sessionId);
6246
+ const state = readExecuteReclaimState(db, sessionId);
6247
+ if (state.floorOrdinal !== null && (belowExecute || promptId !== null && promptId !== state.floorPromptId)) {
6248
+ writeExecuteReclaimState(db, sessionId, { floorOrdinal: null, floorPromptId: null });
6249
+ }
6250
+ }
6251
+ function estimateExecuteReclaimTokens(args) {
6252
+ const eligible = capturePendingDropEligibility(args.targets, args.protectedTagIds);
6253
+ const queued = new Set(args.pendingOps.filter((op) => op.operation === "drop").map((op) => op.tagId));
6254
+ const candidates = args.tags.filter((tag) => tag.status === "active" && queued.has(tag.tagNumber) && eligible.has(tag.tagNumber));
6255
+ const preparationTargets = new Map;
6256
+ for (const tag of candidates) {
6257
+ const target = args.targets.get(tag.tagNumber);
6258
+ if (target?.prepareDrop)
6259
+ preparationTargets.set(tag.tagNumber, target);
6260
+ }
6261
+ const prepared = preparationTargets.size === 0 ? new Set : args.probePreparation?.(preparationTargets) ?? new Set([...preparationTargets].filter(([, target]) => target.prepareDrop?.() !== false).map(([number]) => number));
6262
+ const seed = sessionDecisionCalibration(args.db, args.sessionId);
6263
+ return candidates.reduce((total, tag) => {
6264
+ if (preparationTargets.has(tag.tagNumber) && !prepared.has(tag.tagNumber))
6265
+ return total;
6266
+ const ratio = tag.type === "tool" ? seed.toolsRatio : seed.proseRatio;
6267
+ return total + Math.max(0, (tag.tokenCount ?? Math.ceil(tag.byteSize / 4)) * ratio);
6268
+ }, 0);
6269
+ }
6270
+ function originateExecuteReclaim(args) {
6271
+ if (failedWrites.get(args.db)?.has(args.sessionId))
6272
+ return false;
6273
+ const state = readExecuteReclaimState(args.db, args.sessionId);
6274
+ const heldPasses = args.primaryExecute && args.reclaimableTokens > 0 && !args.alreadyBusting ? state.heldPasses + 1 : 0;
6275
+ if (!writeExecuteReclaimState(args.db, args.sessionId, { heldPasses }))
6276
+ return false;
6277
+ return args.primaryExecute && !args.alreadyBusting && !args.summaryCanCome && args.reclaimableTokens > 0 && (args.usableWindow > 0 && args.reclaimableTokens >= args.usableWindow * 0.02 || heldPasses >= 3);
6278
+ }
6279
+
5834
6280
  // src/hooks/magic-context/historian-drain-gate.ts
5835
6281
  var loggedWindows = new WeakMap;
5836
6282
  function isHistorianDrainBudgetSpent(args) {
@@ -5982,7 +6428,7 @@ function resolveBoundaryContextLimit(usage, fallbackContextLimit) {
5982
6428
  }
5983
6429
  return 128000;
5984
6430
  }
5985
- function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor = 0) {
6431
+ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor = 0, liftLivePromptFloor = false) {
5986
6432
  return withRawSessionMessageCache2(() => {
5987
6433
  try {
5988
6434
  const memoryPrimed = inMemoryTail ? primeInMemoryTailRawMessageCache2({
@@ -6012,7 +6458,8 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
6012
6458
  executeThresholdPercentage,
6013
6459
  usage,
6014
6460
  usageSource: "live",
6015
- taggerFloor
6461
+ taggerFloor,
6462
+ liftLivePromptFloor
6016
6463
  });
6017
6464
  const hasProtectedEligibleHead = boundary.offset < Math.min(boundary.protectedTailStart, boundary.eligibleEndOrdinal);
6018
6465
  if (!hasProtectedEligibleHead) {
@@ -6048,7 +6495,10 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
6048
6495
  function formatProjectedPostDropPercentage(value) {
6049
6496
  return value === null ? "none" : `${value.toFixed(1)}%`;
6050
6497
  }
6051
- function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide, eligiblePendingDropTagIds) {
6498
+ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide, eligiblePendingDropTagIds, primaryExecute = false) {
6499
+ if (usage.percentage < executeThresholdPercentage) {
6500
+ writeExecuteReclaimState(db, sessionId, { floorOrdinal: null, floorPromptId: null });
6501
+ }
6052
6502
  if (sessionMeta.compartmentInProgress) {
6053
6503
  sessionLog2(sessionId, `compartment trigger: skipped — historian already in progress (usage=${usage.percentage.toFixed(1)}%)`);
6054
6504
  return { shouldFire: false };
@@ -6101,7 +6551,22 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
6101
6551
  resolvedInMemoryTail = undefined;
6102
6552
  }
6103
6553
  }
6104
- const tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor);
6554
+ let tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor);
6555
+ const markState = readExecuteReclaimState(db, sessionId);
6556
+ const mark = markState.floorOrdinal;
6557
+ const livePromptOrdinal = tailInfo.boundarySnapshot?.diagnostics?.livePromptFloor.ordinal;
6558
+ let consumedFloorMark = false;
6559
+ if (mark !== null) {
6560
+ const consumed = writeExecuteReclaimState(db, sessionId, {
6561
+ floorOrdinal: null,
6562
+ floorPromptId: null
6563
+ });
6564
+ if (consumed && mark === livePromptOrdinal && markState.floorPromptId === tailInfo.boundarySnapshot?.diagnostics?.livePromptFloor.messageId && usage.percentage >= executeThresholdPercentage) {
6565
+ consumedFloorMark = true;
6566
+ sessionLog2(sessionId, `compartment trigger: live-prompt floor mark consumed at ${mark}`);
6567
+ tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor, true);
6568
+ }
6569
+ }
6105
6570
  if (!tailInfo.hasNewRawHistory) {
6106
6571
  try {
6107
6572
  const lastCompartmentEnd = getLastCompartmentEndMessage(db, sessionId);
@@ -6185,7 +6650,21 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
6185
6650
  return { shouldFire: false };
6186
6651
  }
6187
6652
  if (!tailInfo.hasProtectedEligibleHead || !tailInfo.isMeaningful) {
6188
- sessionLog2(sessionId, `compartment trigger: not firing at ${usage.percentage.toFixed(1)}% because unsummarized tail from ${tailInfo.nextStartOrdinal} is too small`);
6653
+ let floorOnly = false;
6654
+ const boundary = tailInfo.boundarySnapshot;
6655
+ const floor = boundary?.diagnostics?.livePromptFloor;
6656
+ if (!consumedFloorMark && floor?.ordinal && floor.from > floor.to) {
6657
+ const withoutFloor = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor, true);
6658
+ floorOnly = withoutFloor.hasProtectedEligibleHead && withoutFloor.isMeaningful;
6659
+ if (floorOnly && primaryExecute && usage.percentage >= executeThresholdPercentage && writeExecuteReclaimState(db, sessionId, {
6660
+ floorOrdinal: floor.ordinal,
6661
+ floorPromptId: floor.messageId ?? null
6662
+ })) {
6663
+ sessionLog2(sessionId, `compartment trigger: live-prompt floor mark set at ${floor.ordinal}`);
6664
+ }
6665
+ }
6666
+ const refusal = floorOnly ? `no eligible head (live-prompt floor at ${floor?.ordinal})` : tailInfo.hasProtectedEligibleHead ? "below meaningfulness" : "no eligible head";
6667
+ sessionLog2(sessionId, `compartment trigger: not firing at ${usage.percentage.toFixed(1)}% — ${refusal}; offset=${tailInfo.nextStartOrdinal} protectedStart=${boundary?.protectedTailStart ?? "none"} eligibleEnd=${boundary?.eligibleEndOrdinal ?? "none"} rawTokens=${tailInfo.trueRawEligibleTokens} chunkTokens=${tailInfo.tokenEstimate}`);
6189
6668
  return { shouldFire: false };
6190
6669
  }
6191
6670
  sessionLog2(sessionId, `compartment trigger: proactive fire at ${usage.percentage.toFixed(1)}% (floor=${proactiveTriggerPercentage}% projected post-drop=${formatProjectedPostDropPercentage(projectedPostDropPercentage)} target=${relativePostDropTarget.toFixed(1)}%)`);
@@ -6438,7 +6917,7 @@ function maybeInjectChannel1Nudge(args, sessionId, tool, output) {
6438
6917
  evaluable: state.evaluable,
6439
6918
  generationInvalidated: state.generationInvalidated
6440
6919
  });
6441
- sessionLog2(sessionId, formatChannel1Evaluation(decision));
6920
+ logNudgeEvaluation(sessionId, "tool-completion", formatChannel1Evaluation(decision));
6442
6921
  setLastNudgeUndropped(args.db, sessionId, decision.nextLastNudge);
6443
6922
  const nextNudgeState = {
6444
6923
  ...nudgeState,
@@ -6695,6 +7174,9 @@ function latestAssistantTurnStart(messages) {
6695
7174
  function latestAssistantTurnMessages(messages) {
6696
7175
  return new Set(messages.slice(latestAssistantTurnStart(messages)));
6697
7176
  }
7177
+ function isAnthropicThinkingPart(part, familyRoute) {
7178
+ return isRecord(part) && THINKING_TYPES.has(String(part.type ?? part.kind)) && (familyRoute || isRecord(part.metadata) && isRecord(part.metadata.anthropic));
7179
+ }
6698
7180
  function hasActiveAnthropicThinkingTurn(messages, provider, model) {
6699
7181
  const familyRoute = isAnthropicFamilyRoute(provider, model);
6700
7182
  for (const message of messages.slice(latestAssistantTurnStart(messages))) {
@@ -6703,7 +7185,7 @@ function hasActiveAnthropicThinkingTurn(messages, provider, model) {
6703
7185
  const parts = content(message);
6704
7186
  if (!Array.isArray(parts))
6705
7187
  continue;
6706
- if (parts.some((part) => isRecord(part) && THINKING_TYPES.has(String(part.type ?? part.kind)) && (familyRoute || isRecord(part.metadata) && isRecord(part.metadata.anthropic))))
7188
+ if (parts.some((part) => isAnthropicThinkingPart(part, familyRoute)))
6707
7189
  return true;
6708
7190
  }
6709
7191
  return false;
@@ -7040,96 +7522,26 @@ function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, execu
7040
7522
  }
7041
7523
 
7042
7524
  // src/features/magic-context/storage-host-instruction-retention.ts
7043
- var NAMESPACE = "hostInstructionRetention";
7525
+ var NAMESPACE2 = "hostInstructionRetention";
7044
7526
  var enabled = true;
7045
7527
  function hostInstructionRetentionEnabled() {
7046
7528
  return enabled;
7047
7529
  }
7048
7530
  function isHostInstructionRetentionOn(db, sessionId) {
7049
- const lane = readReplayEnvelope(db, sessionId)[NAMESPACE];
7531
+ const lane = readReplayEnvelope(db, sessionId)[NAMESPACE2];
7050
7532
  return typeof lane === "object" && lane !== null && lane.on === true;
7051
7533
  }
7052
7534
  function markHostInstructionRetention(db, sessionId) {
7053
7535
  return updateReplayDocument(db, sessionId, (doc) => {
7054
- const lane = doc[NAMESPACE];
7536
+ const lane = doc[NAMESPACE2];
7055
7537
  if (typeof lane === "object" && lane !== null && lane.on === true)
7056
7538
  return false;
7057
7539
  doc.version = 2;
7058
- doc[NAMESPACE] = { on: true };
7540
+ doc[NAMESPACE2] = { on: true };
7059
7541
  return true;
7060
7542
  });
7061
7543
  }
7062
7544
 
7063
- // src/hooks/magic-context/pending-drop-eligibility.ts
7064
- function pendingDropVeto(tagNumber, target, protectedTagIds) {
7065
- if (protectedTagIds.has(tagNumber))
7066
- return "protected";
7067
- if (target?.thinkingDropProtected)
7068
- return "active_thinking";
7069
- return null;
7070
- }
7071
- function capturePendingDropEligibility(targets, protectedTagIds) {
7072
- const eligible = new Set;
7073
- for (const [number, target] of targets) {
7074
- if (pendingDropVeto(number, target, protectedTagIds))
7075
- continue;
7076
- if (target.drop) {
7077
- if (target.canDrop?.() === true)
7078
- eligible.add(number);
7079
- } else {
7080
- const content = target.getContent?.();
7081
- if (typeof content === "string" && content.length > `[dropped §${number}§]`.length)
7082
- eligible.add(number);
7083
- }
7084
- }
7085
- return eligible;
7086
- }
7087
- function pendingDropEligibilityKey(db, sessionId, input, protectionInputs) {
7088
- const digests = input.map((message) => message.contentDigest?.() ?? null);
7089
- if (digests.some((digest) => digest === null))
7090
- return null;
7091
- const revision = db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(tagRevisionKey(sessionId));
7092
- if (!revision?.value)
7093
- return null;
7094
- return JSON.stringify([
7095
- input.map((message, index) => [
7096
- message.id,
7097
- message.role,
7098
- message.synthetic,
7099
- digests[index]
7100
- ]),
7101
- revision.value,
7102
- readEpochFloorSnapshot(db, sessionId),
7103
- sessionDecisionCalibration(db, sessionId).toolsRatio,
7104
- loadProtectedTailMeta(db, sessionId),
7105
- [...getMergedReasoningStrippedIds(db, sessionId)].sort(),
7106
- [...getReasoningRemovalState(db, sessionId).messageIds].sort(),
7107
- protectionInputs
7108
- ]);
7109
- }
7110
- function createPendingDropEligibilityCache() {
7111
- const sessions = new Map;
7112
- return {
7113
- read(sessionId, key) {
7114
- const previous = sessions.get(sessionId);
7115
- if (key === null || previous?.key !== key) {
7116
- sessions.delete(sessionId);
7117
- return;
7118
- }
7119
- return previous.eligible;
7120
- },
7121
- record(sessionId, key, eligible) {
7122
- sessions.delete(sessionId);
7123
- if (key === null)
7124
- return;
7125
- const oldest = sessions.keys().next().value;
7126
- if (sessions.size >= 64 && oldest !== undefined)
7127
- sessions.delete(oldest);
7128
- sessions.set(sessionId, { key, eligible: new Set(eligible) });
7129
- }
7130
- };
7131
- }
7132
-
7133
7545
  // src/hooks/magic-context/apply-operations.ts
7134
7546
  var RECENT_TOOL_SKELETON_WINDOW = 20;
7135
7547
  function buildReplacementContent(tagId) {
@@ -7415,12 +7827,16 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
7415
7827
  }
7416
7828
  } else if (target) {
7417
7829
  const replacement = buildReplacementContent(pendingOp.tagId);
7830
+ if (target.canSetContent?.(replacement) === false) {
7831
+ reject("content_unchanged");
7832
+ continue;
7833
+ }
7418
7834
  persistDrop();
7419
7835
  mutations.push(() => {
7420
7836
  const priorContent = target.getContent?.();
7421
7837
  const changed = target.setContent(replacement);
7422
- record(changed);
7423
7838
  if (changed) {
7839
+ record(true);
7424
7840
  const originalCharacters = typeof priorContent === "string" ? priorContent.length : tagById.get(pendingOp.tagId)?.byteSize ?? replacement.length;
7425
7841
  onTagReduced?.({
7426
7842
  tagNumber: pendingOp.tagId,
@@ -7683,14 +8099,14 @@ function foldExecutesThisPass(foldDue, materialized) {
7683
8099
  }
7684
8100
 
7685
8101
  // src/features/magic-context/storage-caveman-rules.ts
7686
- var NAMESPACE2 = "caveman";
8102
+ var NAMESPACE3 = "caveman";
7687
8103
  var CURRENT_RULES_VERSION = 2;
7688
8104
  var ORIGINAL_RULES = {
7689
8105
  currentRules: false,
7690
8106
  englishWordRules: true,
7691
8107
  legacyReasoningTags: new Set
7692
8108
  };
7693
- function parseState(lane) {
8109
+ function parseState2(lane) {
7694
8110
  if (!isRecord(lane) || lane.rules !== CURRENT_RULES_VERSION)
7695
8111
  return ORIGINAL_RULES;
7696
8112
  const tags = Array.isArray(lane.legacyReasoningTags) ? lane.legacyReasoningTags : [];
@@ -7702,7 +8118,7 @@ function parseState(lane) {
7702
8118
  }
7703
8119
  function getCavemanReplayState(db, sessionId) {
7704
8120
  try {
7705
- return parseState(readReplayEnvelope(db, sessionId)[NAMESPACE2]);
8121
+ return parseState2(readReplayEnvelope(db, sessionId)[NAMESPACE3]);
7706
8122
  } catch (error) {
7707
8123
  if (error instanceof ReplayDocumentError)
7708
8124
  return ORIGINAL_RULES;
@@ -7712,11 +8128,11 @@ function getCavemanReplayState(db, sessionId) {
7712
8128
  function recordCavemanCurrentRules(db, sessionId, englishWordRules, legacyReasoningTags) {
7713
8129
  const tags = [...new Set(legacyReasoningTags)].sort((a, b) => a - b);
7714
8130
  const persisted = updateReplayDocument(db, sessionId, (doc) => {
7715
- const current = parseState(doc[NAMESPACE2]);
8131
+ const current = parseState2(doc[NAMESPACE3]);
7716
8132
  if (current.currentRules && current.englishWordRules === englishWordRules)
7717
8133
  return false;
7718
8134
  doc.version = 2;
7719
- doc[NAMESPACE2] = {
8135
+ doc[NAMESPACE3] = {
7720
8136
  rules: CURRENT_RULES_VERSION,
7721
8137
  legacyReasoningTags: current.currentRules ? [...current.legacyReasoningTags].sort((a, b) => a - b) : tags,
7722
8138
  ...englishWordRules ? {} : { englishWordRules: false }
@@ -8200,70 +8616,6 @@ function isVisibleNoteReadPart(part) {
8200
8616
  return false;
8201
8617
  }
8202
8618
 
8203
- // src/hooks/magic-context/postprocess-read-cache.ts
8204
- var connections = new WeakMap;
8205
- function snapshot(db, sessionId) {
8206
- const transaction = db;
8207
- try {
8208
- if (transaction.inTransaction || transaction.isTransaction) {
8209
- connections.delete(db);
8210
- return { version: -1, changes: -1 };
8211
- }
8212
- } catch {
8213
- connections.delete(db);
8214
- return { version: -1, changes: -1 };
8215
- }
8216
- let connection = connections.get(db);
8217
- if (!connection) {
8218
- connection = {
8219
- stamp: db.prepare("SELECT total_changes() AS changes, data_version AS version FROM pragma_data_version"),
8220
- sessions: new BoundedSessionMap(100)
8221
- };
8222
- connections.set(db, connection);
8223
- }
8224
- const stamp = connection.stamp.get();
8225
- const previous = connection.sessions.get(sessionId);
8226
- if (previous?.version === stamp.version && previous.changes === stamp.changes) {
8227
- return previous;
8228
- }
8229
- const value = { ...stamp };
8230
- connection.sessions.set(sessionId, value);
8231
- return value;
8232
- }
8233
- function postprocessTailTags(db, sessionId) {
8234
- const state = snapshot(db, sessionId);
8235
- return state.tags ??= getTailHygieneTags2(db, sessionId);
8236
- }
8237
- function postprocessOldestTags(db, sessionId, protectedNumbers) {
8238
- const state = snapshot(db, sessionId);
8239
- const hints = state.hints;
8240
- if (hints && hints.protectedNumbers.size === protectedNumbers.size && [...protectedNumbers].every((number) => hints.protectedNumbers.has(number))) {
8241
- return hints.value;
8242
- }
8243
- const value = getOldestActiveUnprotectedToolTags2(db, sessionId, protectedNumbers);
8244
- state.hints = { protectedNumbers: new Set(protectedNumbers), value };
8245
- return value;
8246
- }
8247
- function postprocessReplaySnapshot(db, sessionId) {
8248
- const state = snapshot(db, sessionId);
8249
- const replay = state.replay ??= loadPostprocessReplaySnapshot(db, sessionId);
8250
- return {
8251
- ...replay,
8252
- staleReduceStrippedIds: new Set(replay.staleReduceStrippedIds),
8253
- processedImageStrippedIds: new Set(replay.processedImageStrippedIds),
8254
- processedImageMarkers: new Map(replay.processedImageMarkers),
8255
- strippedPlaceholderIds: new Set(replay.strippedPlaceholderIds),
8256
- hiddenSeamPlaceholderIds: new Set(replay.hiddenSeamPlaceholderIds),
8257
- mergedReasoningStrippedIds: new Set(replay.mergedReasoningStrippedIds),
8258
- trailingBlankDecisions: new Map(replay.trailingBlankDecisions),
8259
- noteNudgeAnchors: structuredClone(replay.noteNudgeAnchors),
8260
- autoSearchHintDecisions: structuredClone(replay.autoSearchHintDecisions),
8261
- todoSyntheticAnchor: structuredClone(replay.todoSyntheticAnchor),
8262
- pendingCompactionMarker: structuredClone(replay.pendingCompactionMarker),
8263
- compactionMarker: structuredClone(replay.compactionMarker)
8264
- };
8265
- }
8266
-
8267
8619
  // src/hooks/magic-context/strict-thinking-prefix.ts
8268
8620
  function servedPrefixMatches(args) {
8269
8621
  const heads = args.messages?.slice(0, 2);
@@ -9054,7 +9406,7 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
9054
9406
  const textPart = part;
9055
9407
  const thinkingParts = messageThinkingParts;
9056
9408
  const contentId = `${messageId}:p${partIndex}`;
9057
- const whitespaceOnlyAssistant = message.info.role === "assistant" && stripTagPrefix(textPart.text).trim().length === 0;
9409
+ const whitespaceOnlyAssistant = message.info.role === "assistant" && (stripTagPrefix(textPart.text).trim().length === 0 || textPart.text.includes("§") && stripPersistedAssistantText(textPart.text).length === 0);
9058
9410
  let existingTagId;
9059
9411
  if (whitespaceOnlyAssistant) {
9060
9412
  const persistedWhitespaceTag = getTagNumberByMessageId2(db, sessionId, contentId);
@@ -9106,7 +9458,7 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
9106
9458
  accAssignTag += performance.now() - _tAssignText;
9107
9459
  const persistedSource = sourceContents.get(tagId);
9108
9460
  if (persistedSource !== undefined && !options.refreshSourceContents) {
9109
- textPart.text = options.normalizeRestoredAssistantText && message.info.role === "assistant" ? options.normalizeRestoredAssistantText(persistedSource) : persistedSource;
9461
+ textPart.text = options.normalizeRestoredAssistantText && message.info.role === "assistant" ? options.normalizeRestoredAssistantText(persistedSource, message.info.providerID) : persistedSource;
9110
9462
  } else {
9111
9463
  const sourceContent = stripTagPrefix(textPart.text);
9112
9464
  if (sourceContent.trim().length > 0 || options.refreshSourceContents) {
@@ -9135,6 +9487,10 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
9135
9487
  dropReasoningParts: thinkingParts,
9136
9488
  mutationParts: [{ message, part: textPart }],
9137
9489
  textPrefix: skipPrefixInjection ? "" : prependTag(tagId, ""),
9490
+ canSetContent: (content) => {
9491
+ const partialEnd = messageId ? getPartialEnds().get(messageId) : undefined;
9492
+ return textPart.text !== content && (partialEnd === undefined || partIndex <= partialEnd);
9493
+ },
9138
9494
  setContent: (content, options) => {
9139
9495
  if (textPart.text === content)
9140
9496
  return false;
@@ -9437,6 +9793,25 @@ function proactiveStripStartIndex(args) {
9437
9793
  return divergence;
9438
9794
  return divergence ?? lastServed.messages.length;
9439
9795
  }
9796
+ function servesThinkingBlock(messages, providerID, modelID) {
9797
+ const familyRoute = isAnthropicFamilyRoute(providerID, modelID);
9798
+ for (const message of messages) {
9799
+ if (message.info.role !== "assistant")
9800
+ continue;
9801
+ for (const part of message.parts) {
9802
+ if (!isAnthropicThinkingPart(part, familyRoute) || part.ignored === true)
9803
+ continue;
9804
+ if (part.type === "redacted_thinking")
9805
+ return true;
9806
+ if (typeof part.text === "string" && part.text !== "")
9807
+ return true;
9808
+ const records = isRecord(part.metadata) ? Object.values(part.metadata) : [];
9809
+ if (records.some((record) => isRecord(record) && record.redactedData !== undefined))
9810
+ return true;
9811
+ }
9812
+ }
9813
+ return false;
9814
+ }
9440
9815
  function isPartDroppedBeforeWire(part, providerID) {
9441
9816
  if (!modelAcceptsEmptyContent(providerID) || !isRecord(part))
9442
9817
  return false;
@@ -9966,6 +10341,9 @@ async function runPostTransformPhase(args) {
9966
10341
  }
9967
10342
  };
9968
10343
  const trailingBlankSourceDecisions = args.trailingBlankSourceDecisions ?? snapshotTrailingBlankSourceDecisions(args.messages);
10344
+ if (!modelAcceptsEmptyContent(args.resolvedProviderID) && !compactionOff)
10345
+ captureInlineThinkingRepairs(args.messages, args.messageTagNumbers, args.sessionMeta?.clearedReasoningThroughTag ?? 0);
10346
+ const servedShapeRepair = prepareServedShapeRepair(args.db, args.sessionId, args.messages, args.readLastServedMessages, compactionOff ? undefined : postprocessReplaySnapshot(args.db, args.sessionId));
9969
10347
  let trailingBlankNewestAssistant;
9970
10348
  for (let index = args.messages.length - 1;index >= 0; index -= 1) {
9971
10349
  const message = args.messages[index];
@@ -9995,8 +10373,8 @@ async function runPostTransformPhase(args) {
9995
10373
  }
9996
10374
  const activeCompartmentRun = args.canRunCompartments ? getActiveCompartmentRun(args.sessionId) : undefined;
9997
10375
  const compartmentRunning = args.canRunCompartments && !args.awaitedCompartmentRun && activeCompartmentRun !== undefined;
9998
- let deferredMaterialize = args.canConsumeDeferredLate && deferredMaterializationWasPending;
9999
- let materializationRequested = isExplicitFlush || deferredMaterialize;
10376
+ let deferredMaterialize = (args.canConsumeDeferredLate || servedShapeRepair.needsRebuild) && deferredMaterializationWasPending;
10377
+ let materializationRequested = isExplicitFlush || deferredMaterialize || servedShapeRepair.needsRebuild;
10000
10378
  const m0M1EnabledForFold = args.m0M1 !== undefined && (!!args.m0M1.projectPath || !!args.m0M1.projectDirectory) && (args.fullFeatureMode || compactionOff);
10001
10379
  const frozenThinking = new Set(args.activeThinkingTurn || compactionOff ? getMergedReasoningStrippedIds(args.db, args.sessionId) : []);
10002
10380
  const compactionOffFrozenThinking = compactionOff ? compactionOffFrozenThinkingIds(frozenThinking) : new Set;
@@ -10039,6 +10417,8 @@ async function runPostTransformPhase(args) {
10039
10417
  if (stripOffWire)
10040
10418
  for (const id of stripped.strip?.messageIds ?? [])
10041
10419
  compactionOffFrozenThinking.add(id);
10420
+ for (const id of stripped.strip?.messageIds ?? [])
10421
+ bindingThinking.add(id);
10042
10422
  retainedThinking.clear();
10043
10423
  protectedThinkingMessages.clear();
10044
10424
  activeThinkingTurn = false;
@@ -10048,9 +10428,15 @@ async function runPostTransformPhase(args) {
10048
10428
  rewritingSignedPrefix = true;
10049
10429
  thinkingReleasedForFit ||= forFit;
10050
10430
  };
10431
+ if (servedShapeRepair.needsRebuild && activeThinkingTurn)
10432
+ releaseThinkingForRewrite(false, true);
10051
10433
  if (args.forceSignedRebuildForFit && (activeThinkingPrefixHold || activeThinkingTurn && args.thinkingBindingRecoveryEnabledForModel === true)) {
10052
10434
  releaseThinkingForRewrite(true);
10053
10435
  }
10436
+ if (args.compactionModeTransition === true && args.thinkingBindingRecoveryEnabledForModel === true) {
10437
+ sessionLog2(args.sessionId, "compaction mode switch: stripping signed thinking");
10438
+ releaseThinkingForRewrite(false, true);
10439
+ }
10054
10440
  const foldDueDecision = m0M1EnabledForFold && args.m0M1 && !freezeM0M1 ? mustMaterialize({
10055
10441
  db: args.db,
10056
10442
  sessionId: args.sessionId,
@@ -10075,7 +10461,7 @@ async function runPostTransformPhase(args) {
10075
10461
  let foldBustsServedPrefixThisPass = false;
10076
10462
  let publishedM1RefreshedThisPass = false;
10077
10463
  let prefixPreflightFailed = false;
10078
- const softRefreshOpportunity = !freezeM0M1 && (args.schedulerDecision === "execute" || deferredMaterialize);
10464
+ const softRefreshOpportunity = !freezeM0M1 && (args.schedulerDecision === "execute" || deferredMaterialize || servedShapeRepair.needsRebuild);
10079
10465
  let m0RematerializedThisPass = false;
10080
10466
  const m0CoverageBeforeFold = args.sessionMeta.cachedM0Bytes === null ? -1 : args.sessionMeta.cachedM0MaxCompartmentSeq;
10081
10467
  let m0MaterializeReason = null;
@@ -10090,6 +10476,7 @@ async function runPostTransformPhase(args) {
10090
10476
  };
10091
10477
  if ((foldDueDecision.value || softRefreshOpportunity || firstRenderBust && activeThinkingPrefixHold) && m0M1EnabledForFold && args.m0M1) {
10092
10478
  let committedFoldBustsServedPrefix;
10479
+ let committedFoldChangesHead;
10093
10480
  try {
10094
10481
  const previousM1 = args.sessionMeta.cachedM1Bytes?.toString("utf8");
10095
10482
  const foldResult = injectM0M1({
@@ -10119,6 +10506,12 @@ async function runPostTransformPhase(args) {
10119
10506
  m1Text: rendered.m1Bytes.toString(),
10120
10507
  muralDataUrl: rendered.muralDataUrl
10121
10508
  }) : foldBustsServedPrefix(foldDueDecision.reason, servedPrefixBeforeFold, rendered);
10509
+ committedFoldChangesHead = firstRenderBust ? !servedPrefixMatches({
10510
+ messages: servedBeforeFirstRender,
10511
+ m0Text: rendered.m0Bytes.toString(),
10512
+ m1Text: rendered.m1Bytes.toString(),
10513
+ muralDataUrl: rendered.muralDataUrl
10514
+ }) : foldChangesServedPrefix(servedPrefixBeforeFold, rendered);
10122
10515
  if (bustsPrefix) {
10123
10516
  if (!conversions.isCurrent(db)) {
10124
10517
  throw new MaterializeContentionError({
@@ -10137,6 +10530,9 @@ async function runPostTransformPhase(args) {
10137
10530
  preparedPrefix = foldResult;
10138
10531
  if (activeThinkingPrefixHold && firstRenderBust && committedFoldBustsServedPrefix) {
10139
10532
  releaseThinkingForRewrite(false, true);
10533
+ } else if (compactionOff && !activeThinkingPrefixHold && args.thinkingBindingRecoveryEnabledForModel === true && committedFoldChangesHead) {
10534
+ sessionLog2(args.sessionId, "compaction-off fold changed the head: stripping signed thinking");
10535
+ releaseThinkingForRewrite(false, true);
10140
10536
  }
10141
10537
  prefixPreflightFailed = foldResult.materializationContentionRetryExhausted === true;
10142
10538
  foldExecutedThisPass = foldExecutesThisPass(foldDueDecision.value || softRefreshOpportunity, foldResult.m0RematerializedThisPass);
@@ -10194,21 +10590,43 @@ async function runPostTransformPhase(args) {
10194
10590
  const heldIdleExpiryRebuild = activeThinkingPrefixHold && args.m0M1?.hardSignals?.cacheExpired === true;
10195
10591
  const idleExpiryRebuild = (!freezeM0M1 || activeThinkingPrefixHold) && args.m0M1?.hardSignals?.cacheExpired === true;
10196
10592
  const rideSignals = {
10593
+ servedShapeRepair: servedShapeRepair.needsRebuild,
10594
+ executeReclaim: false,
10197
10595
  subagentExecute: !args.fullFeatureMode && args.schedulerDecision === "execute",
10198
10596
  hardFold: rewritingSignedPrefix || foldBustsServedPrefixThisPass || firstRenderBust || idleExpiryRebuild,
10199
10597
  force: emergencyDropEligible && (args.contextUsage.percentage >= 95 || args.contextUsageFromEstimate !== true && getEmergencyInputSample(args.db, args.sessionId) === 0),
10200
10598
  explicitFlush: isExplicitFlush && hasPendingMaterializationOrigin(args.pendingMaterializationSessions, args.sessionId, "user_flush"),
10201
10599
  publishedHistory: !prefixPreflightFailed && (publishedM1RefreshedThisPass || !m0M1EnabledForFold && (args.pendingCompartmentInjection?.compartmentCount ?? 0) > 0 && legacyPublishedHeadChanged(args))
10202
10600
  };
10203
- const publishedWorkDrainAllowed = !compactionOff && reclaimRidePermitted(rideSignals, {
10601
+ const protectedToolTags = protectedToolTagNumbers(args.tags, args.protectedTools);
10602
+ rideSignals.executeReclaim = !compactionOff && originateExecuteReclaim({
10603
+ db: args.db,
10604
+ sessionId: args.sessionId,
10605
+ primaryExecute: args.fullFeatureMode && args.schedulerDecision === "execute" && args.contextUsage.percentage < args.forceMaterializationPercentage,
10606
+ alreadyBusting: Object.values(rideSignals).some(Boolean) || args.historyRebuiltThisPass,
10607
+ summaryCanCome: compartmentRunning || args.sessionMeta.compartmentInProgress || (prefixPreflightFailed || freezeM0M1 || activeThinkingPrefixHold) && (args.deferredHistoryRefreshSessions.has(args.sessionId) || args.deferredMaterializationSessions.has(args.sessionId) || args.historyRefreshSessions?.has(args.sessionId) === true) || readExecuteReclaimState(args.db, args.sessionId).floorOrdinal !== null,
10608
+ reclaimableTokens: estimateExecuteReclaimTokens({
10609
+ db: args.db,
10610
+ sessionId: args.sessionId,
10611
+ pendingOps,
10612
+ tags: args.tags,
10613
+ targets: newTargets,
10614
+ protectedTagIds: new Set([...args.protectedTagIds, ...protectedToolTags])
10615
+ }),
10616
+ usableWindow: args.usableWindow
10617
+ });
10618
+ const publishedWorkDrainAllowed = (!compactionOff || servedShapeRepair.needsRebuild) && reclaimRidePermitted(rideSignals, {
10204
10619
  signedThinkingHold: activeThinkingPrefixHold,
10205
10620
  firstRender: firstRenderBust,
10206
10621
  idleExpiry: idleExpiryRebuild,
10207
10622
  emergency: emergencyDropEligible
10208
10623
  });
10209
- const shouldApplyPendingOps = publishedWorkDrainAllowed;
10210
- const shouldRunHeuristics = publishedWorkDrainAllowed && (rideSignals.publishedHistory || materializationRequested || forceMaterialization || foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
10624
+ const shouldApplyPendingOps = !compactionOff && publishedWorkDrainAllowed;
10625
+ const shouldRunHeuristics = !compactionOff && publishedWorkDrainAllowed && (rideSignals.publishedHistory || rideSignals.executeReclaim || rideSignals.servedShapeRepair || materializationRequested || forceMaterialization || foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
10211
10626
  const isCacheBustingPass = publishedWorkDrainAllowed;
10627
+ if (servedShapeRepair.needsRebuild && !isCacheBustingPass)
10628
+ throw new Error("Served-shape repair requires a rebuilding pass");
10629
+ servedShapeRepair.apply(isCacheBustingPass);
10212
10630
  let unheldSignedTurnBust = false;
10213
10631
  if (isCacheBustingPass && !activeThinkingPrefixHold && activeThinkingTurn && args.thinkingBindingRecoveryEnabledForModel === true) {
10214
10632
  if (foldBustsServedPrefixThisPass || firstRenderBust || publishedM1RefreshedThisPass)
@@ -10299,17 +10717,28 @@ async function runPostTransformPhase(args) {
10299
10717
  throw new EmergencyFailClosedError("Magic Context could not read its saved reasoning-removal state for this session", { cause: error });
10300
10718
  }
10301
10719
  }
10720
+ const heuristicsLogChanged = diagnosticStateChanged(args.sessionId, "heuristics", JSON.stringify([
10721
+ args.currentTurnId,
10722
+ shouldRunHeuristics,
10723
+ shouldRunHeuristics ? null : args.schedulerDeferReason
10724
+ ]));
10725
+ const pendingLogChanged = diagnosticStateChanged(args.sessionId, "pending-ops", JSON.stringify([
10726
+ args.currentTurnId,
10727
+ shouldApplyPendingOps,
10728
+ shouldApplyPendingOps ? null : args.schedulerDeferReason,
10729
+ shouldApplyPendingOps ? null : (getPendingOpsCount(args.db, args.sessionId) ?? 0) > 0
10730
+ ]));
10302
10731
  if (shouldRunHeuristics) {
10303
10732
  const subagentRerun = !args.fullFeatureMode && alreadyRanThisTurn && args.schedulerDecision === "execute" && !isExplicitFlush && !forceMaterialization;
10304
10733
  const reason = isExplicitFlush ? `pending_materialization origin=${pendingOrigin}` : deferredMaterialize ? "deferred_materialization" : forceMaterialization ? `force_materialization (${args.contextUsage.percentage.toFixed(1)}% >= ${args.forceMaterializationPercentage}%)` : foldBustsServedPrefixThisPass && args.schedulerDecision !== "execute" ? `m0_hard_fold (drain folded into executed m[0] bust, scheduler=${args.schedulerDecision})` : subagentRerun ? `${reclaimRideLabel(rideSignals)} subagent_rerun (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})` : `${reclaimRideLabel(rideSignals)} (pendingOps=${pendingOps.length}, scheduler=${args.schedulerDecision})`;
10305
10734
  sessionLog2(args.sessionId, `heuristics WILL RUN — reason=${reason}, context=${args.contextUsage.percentage.toFixed(1)}%, turn=${args.currentTurnId}`);
10306
- } else if (args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
10735
+ } else if (heuristicsLogChanged && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
10307
10736
  sessionLog2(args.sessionId, `heuristics WILL NOT RUN — reason=${args.schedulerDeferReason}`);
10308
10737
  }
10309
10738
  if (alreadyRanThisTurn && args.schedulerDecision === "execute" && !materializationRequested && args.fullFeatureMode) {
10310
10739
  sessionLog2(args.sessionId, `transform: skipping heuristics (already ran for turn ${args.currentTurnId})`);
10311
10740
  }
10312
- if (!shouldApplyPendingOps && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
10741
+ if (!shouldApplyPendingOps && pendingLogChanged && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
10313
10742
  sessionLog2(args.sessionId, `pending ops WILL NOT APPLY — reason=${args.schedulerDeferReason} pendingOps=${formatPendingOpsDepth()} context=${args.contextUsage.percentage.toFixed(1)}%`);
10314
10743
  }
10315
10744
  if (hasPendingUserOps && !shouldApplyPendingOps) {
@@ -10318,7 +10747,6 @@ async function runPostTransformPhase(args) {
10318
10747
  let explicitMaterializedSuccessfully = false;
10319
10748
  let deferredMaterializedSuccessfully = false;
10320
10749
  let pendingOpsDidMutate = false;
10321
- const protectedToolTags = protectedToolTagNumbers(args.tags, args.protectedTools);
10322
10750
  const firstApplicationEdits = { any: false, beforeNewerThinking: false };
10323
10751
  const recordFirstApplicationWireEdit = (beforeNewerThinking) => {
10324
10752
  firstApplicationEdits.any = true;
@@ -10326,6 +10754,8 @@ async function runPostTransformPhase(args) {
10326
10754
  };
10327
10755
  if (temporalFirstApplication)
10328
10756
  recordFirstApplicationWireEdit(true);
10757
+ if (servedShapeRepair.needsRebuild)
10758
+ recordFirstApplicationWireEdit(true);
10329
10759
  const firstApplicationLocations = new Map;
10330
10760
  const recordFirstApplicationAt = (message, partIndex) => {
10331
10761
  recordFirstApplicationWireEdit(false);
@@ -10468,11 +10898,12 @@ async function runPostTransformPhase(args) {
10468
10898
  if (routineCleanupApplied && canUseEmptySentinels) {
10469
10899
  stripClearedReasoning(args.messages);
10470
10900
  }
10471
- const strippedInline = routineCleanupApplied && ageLaneAllowed ? stripInlineThinking(args.messages, args.messageTagNumbers, budgetCutoff) : 0;
10901
+ const strippedInline = routineCleanupApplied && ageLaneAllowed ? stripInlineThinking(args.messages, args.messageTagNumbers, budgetCutoff, !canUseEmptySentinels) : 0;
10472
10902
  const persistedInlineWatermark = args.sessionMeta?.clearedReasoningThroughTag ?? 0;
10473
10903
  if (routineCleanupApplied && persistedInlineWatermark > 0 && !compactionOff) {
10474
- replayStrippedInlineThinking(args.messages, args.messageTagNumbers, persistedInlineWatermark);
10904
+ replayStrippedInlineThinking(args.messages, args.messageTagNumbers, persistedInlineWatermark, !canUseEmptySentinels);
10475
10905
  }
10906
+ servedShapeRepair.apply(isCacheBustingPass);
10476
10907
  let removedReasoningMessages = 0;
10477
10908
  if (routineCleanupApplied && !prefixBoundModel && reasoningRemovalSelectable && reasoningRemovalReadable) {
10478
10909
  const newIds = selectReasoningRemovals({
@@ -10799,7 +11230,7 @@ async function runPostTransformPhase(args) {
10799
11230
  }
10800
11231
  }
10801
11232
  if (isCacheBustingPass) {
10802
- const droppedResult = stripDroppedPlaceholderMessages(args.messages, args.resolvedProviderID, recordFirstApplicationAt);
11233
+ const droppedResult = stripDroppedPlaceholderMessages(args.messages.filter((message) => !servedShapeRepair.messageIDs.has(message.info.id ?? "")), args.resolvedProviderID, recordFirstApplicationAt);
10803
11234
  const protectedTailStart = Math.max(0, args.messages.length - SYSTEM_INJECTION_ACTIONABLE_TAIL_MESSAGES);
10804
11235
  const systemInjectedResult = stripSystemInjectedMessages(args.messages, protectedTailStart, args.resolvedProviderID, recordFirstApplicationAt);
10805
11236
  const hiddenMessages = args.hiddenMessagesAtCompactionSeam ?? [];
@@ -11399,6 +11830,8 @@ async function runPostTransformPhase(args) {
11399
11830
  });
11400
11831
  }
11401
11832
  logTransformTiming(args.sessionId, "pp.tailGuard", tTailGuard);
11833
+ if (bustedThisPass)
11834
+ clearExecuteReclaimState(args.db, args.sessionId);
11402
11835
  return {
11403
11836
  explicitMaterializedSuccessfully,
11404
11837
  deferredMaterializedSuccessfully,
@@ -11419,8 +11852,7 @@ async function runPostTransformPhase(args) {
11419
11852
  prefixTrimStatus: deliveredPrefix?.prefixTrimStatus ?? null,
11420
11853
  thinkingBindingRecovery,
11421
11854
  proactiveThinkingStrip,
11422
- thinkingReleasedForFit,
11423
- openTurnSignedThinkingKept: args.thinkingBindingRecoveryEnabledForModel === true && activeThinkingTurn && !rewritingSignedPrefix
11855
+ thinkingReleasedForFit
11424
11856
  };
11425
11857
  }
11426
11858
  function checkM0MutationDriftAndSignal(args) {
@@ -11520,6 +11952,35 @@ function describeSystemPromptChange(previous, current) {
11520
11952
  return `presetChanged=${previous ? previous.preset !== current.preset : "unknown"} elements=[${elements.join("; ")}]`;
11521
11953
  }
11522
11954
 
11955
+ // src/hooks/magic-context/system-prompt-sticky-date.ts
11956
+ var STICKY_DATE_KEY = "systemPromptStickyDate";
11957
+ function readPersistedSystemPromptStickyDate(db, sessionId) {
11958
+ try {
11959
+ const saved = readReplayEnvelope(db, sessionId, "read")[STICKY_DATE_KEY];
11960
+ return typeof saved === "string" && saved.length > 0 ? saved : undefined;
11961
+ } catch (error) {
11962
+ sessionLog2(sessionId, "system prompt sticky date record unreadable:", error);
11963
+ return;
11964
+ }
11965
+ }
11966
+ function persistSystemPromptStickyDate(db, sessionId, stickyDate) {
11967
+ try {
11968
+ const written = updateReplayDocument(db, sessionId, (doc) => {
11969
+ if (doc[STICKY_DATE_KEY] === stickyDate)
11970
+ return false;
11971
+ doc.version = 2;
11972
+ doc[STICKY_DATE_KEY] = stickyDate;
11973
+ return true;
11974
+ });
11975
+ if (!written)
11976
+ sessionLog2(sessionId, "system prompt sticky date record not written");
11977
+ return written;
11978
+ } catch (error) {
11979
+ sessionLog2(sessionId, "system prompt sticky date record write failed:", error);
11980
+ return false;
11981
+ }
11982
+ }
11983
+
11523
11984
  // src/hooks/magic-context/system-date-refresh.ts
11524
11985
  var channels = new WeakMap;
11525
11986
  var outputUpdates = new WeakMap;
@@ -11683,6 +12144,15 @@ function createSystemPromptHashHandler(deps) {
11683
12144
  });
11684
12145
  const guidanceEpochs = createPromptSurfaceGuidanceEpochCache(promptSurfaceRuntime);
11685
12146
  const stickyDateBySession = new Map;
12147
+ const recordedStickyDateBySession = new Map;
12148
+ const recordedStickyDate = (sessionId) => {
12149
+ let recorded = recordedStickyDateBySession.get(sessionId);
12150
+ if (recorded === undefined) {
12151
+ recorded = readPersistedSystemPromptStickyDate(deps.db, sessionId) ?? null;
12152
+ recordedStickyDateBySession.set(sessionId, recorded);
12153
+ }
12154
+ return recorded ?? undefined;
12155
+ };
11686
12156
  const diagnosticPrompts = new Map;
11687
12157
  const processSystemPrompt = async (input, output) => {
11688
12158
  const sessionId = input.sessionID;
@@ -11750,9 +12220,34 @@ function createSystemPromptHashHandler(deps) {
11750
12220
  return;
11751
12221
  const previousHash = sessionMetaEarly?.systemPromptHash ?? "";
11752
12222
  const hasPersistedHash = previousHash !== "" && previousHash !== "0";
11753
- if (!hasPersistedHash)
11754
- stickyDateBySession.delete(sessionId);
11755
- const stickyDate = stickyDateBySession.get(sessionId);
12223
+ const prefixBoundModel = isPrefixBoundThinkingModel(liveModel?.providerID, liveModel?.modelID);
12224
+ let stickyDate = stickyDateBySession.get(sessionId);
12225
+ if (!hasPersistedHash) {
12226
+ const previous = stickyDate ?? recordedStickyDate(sessionId);
12227
+ const live = systemPromptDates(liveSystemContent).live;
12228
+ const fieldCount = (dates) => dates === undefined ? 0 : JSON.parse(dates).length;
12229
+ stickyDate = (!modelKey || prefixBoundModel) && previous !== undefined && live !== undefined && fieldCount(previous) === fieldCount(live) ? previous : undefined;
12230
+ if (stickyDate === undefined)
12231
+ stickyDateBySession.delete(sessionId);
12232
+ else
12233
+ stickyDateBySession.set(sessionId, stickyDate);
12234
+ }
12235
+ if (stickyDate === undefined && hasPersistedHash) {
12236
+ const recorded = recordedStickyDate(sessionId);
12237
+ const live = systemPromptDates(liveSystemContent).live;
12238
+ if (recorded !== undefined && live !== undefined && recorded !== live && systemPromptFingerprint(systemPromptDates(liveSystemContent, recorded).stable, promptSurface.preset) === previousHash) {
12239
+ stickyDate = recorded;
12240
+ stickyDateBySession.set(sessionId, recorded);
12241
+ sessionLog2(sessionId, `system prompt date restored after restart: real=${live}, using=${recorded}`);
12242
+ }
12243
+ }
12244
+ const setStickyDate = (value) => {
12245
+ stickyDateBySession.set(sessionId, value);
12246
+ if (value !== recordedStickyDate(sessionId)) {
12247
+ if (persistSystemPromptStickyDate(deps.db, sessionId, value))
12248
+ recordedStickyDateBySession.set(sessionId, value);
12249
+ }
12250
+ };
11756
12251
  const dates = systemPromptDates(liveSystemContent, stickyDate);
11757
12252
  const currentDate = dates.live;
11758
12253
  const stableCandidate = dates.stable;
@@ -11760,13 +12255,12 @@ function createSystemPromptHashHandler(deps) {
11760
12255
  const contentOrPresetChanged = hasPersistedHash && stableCandidateHash !== previousHash;
11761
12256
  const rewritePermission = systemDateRefreshPermission(deps.historyRefreshSessions, dateRequest);
11762
12257
  const signedThinkingKept = systemDateSignedThinkingKept(deps.historyRefreshSessions, dateRequest);
11763
- const idleDateMayAdvance = idleCacheExpired && signedThinkingKept !== true;
11764
- const prefixBoundModel = isPrefixBoundThinkingModel(liveModel?.providerID, liveModel?.modelID);
12258
+ const systemDateMayMove = (rewrite, keptSignedThinking) => (rewrite || idleCacheExpired) && keptSignedThinking !== true;
11765
12259
  let deferredDateRefresh = false;
11766
12260
  if (currentDate && stickyDate && currentDate !== stickyDate && (idleCacheExpired ? prefixBoundModel : isCacheBusting) && !contentOrPresetChanged && !requestMessagesFinal) {
11767
12261
  const liveElements = [...output.system];
11768
12262
  deferredDateRefresh = waitForSystemDateRefresh(deps.historyRefreshSessions, dateRequest, (permitted, keptSignedThinking) => {
11769
- if (!permitted && !(idleCacheExpired && keptSignedThinking !== true)) {
12263
+ if (!systemDateMayMove(permitted, keptSignedThinking)) {
11770
12264
  deps.systemPromptRefreshSessions.add(sessionId);
11771
12265
  return;
11772
12266
  }
@@ -11779,7 +12273,7 @@ function createSystemPromptHashHandler(deps) {
11779
12273
  cachedM0SystemHash: hash,
11780
12274
  systemPromptTokens: estimateTokens(content)
11781
12275
  });
11782
- stickyDateBySession.set(sessionId, currentDate);
12276
+ setStickyDate(currentDate);
11783
12277
  output.system.splice(0, output.system.length, ...liveElements);
11784
12278
  publishSystemDateOutput(output.system);
11785
12279
  deps.systemPromptRefreshSessions.delete(sessionId);
@@ -11790,12 +12284,12 @@ function createSystemPromptHashHandler(deps) {
11790
12284
  }
11791
12285
  });
11792
12286
  }
11793
- const dateMayAdvance = idleDateMayAdvance && !deferredDateRefresh || contentOrPresetChanged || isCacheBusting && !deferredDateRefresh && (dateRequest ? rewritePermission === true : rewritePermission !== false);
12287
+ const dateMayAdvance = contentOrPresetChanged || !deferredDateRefresh && systemDateMayMove(isCacheBusting && (dateRequest ? rewritePermission === true : rewritePermission !== false), signedThinkingKept);
11794
12288
  if (currentDate && !stickyDate) {
11795
- stickyDateBySession.set(sessionId, currentDate);
12289
+ setStickyDate(currentDate);
11796
12290
  } else if (currentDate && stickyDate && currentDate !== stickyDate) {
11797
12291
  if (dateMayAdvance) {
11798
- stickyDateBySession.set(sessionId, currentDate);
12292
+ setStickyDate(currentDate);
11799
12293
  sessionLog2(sessionId, `system prompt date updated: ${stickyDate} → ${currentDate} (cache-busting pass)`);
11800
12294
  } else {
11801
12295
  let offset = 0;
@@ -11853,7 +12347,7 @@ function createSystemPromptHashHandler(deps) {
11853
12347
  sessionLog2(sessionId, "system prompt meta persist failed (fail-open):", error);
11854
12348
  }
11855
12349
  }
11856
- if (isCacheBusting && !deferredDateRefresh && (contentOrPresetChanged || !currentDate || currentDate === stickyDate || !dateRequest || rewritePermission === true)) {
12350
+ if (isCacheBusting && !deferredDateRefresh && (contentOrPresetChanged || !currentDate || currentDate === stickyDate || !dateRequest || rewritePermission === true && signedThinkingKept !== true)) {
11857
12351
  deps.systemPromptRefreshSessions.delete(sessionId);
11858
12352
  }
11859
12353
  };
@@ -11868,6 +12362,7 @@ function createSystemPromptHashHandler(deps) {
11868
12362
  handler,
11869
12363
  clearSession: (sessionId) => {
11870
12364
  diagnosticPrompts.delete(sessionId);
12365
+ recordedStickyDateBySession.delete(sessionId);
11871
12366
  clearSystemDateRefresh(deps.historyRefreshSessions, sessionId);
11872
12367
  guidanceEpochs.clear(sessionId);
11873
12368
  clearSystemPromptHashSession(sessionId, {
@@ -18349,8 +18844,8 @@ async function runCompartmentPhaseImpl(args) {
18349
18844
  }
18350
18845
  return "completed";
18351
18846
  }
18352
- if (!historianRunnable && args.sessionMeta.compartmentInProgress) {
18353
- sessionLog2(args.sessionId, "transform: historian disabled; clearing stale compartmentInProgress flag");
18847
+ if ((!historianRunnable || !args.canRunCompartments && !getActiveCompartmentRun(args.sessionId)) && args.sessionMeta.compartmentInProgress) {
18848
+ sessionLog2(args.sessionId, "transform: historian unavailable; clearing stale compartmentInProgress flag");
18354
18849
  updateSessionMeta(args.db, args.sessionId, { compartmentInProgress: false });
18355
18850
  compartmentInProgress = false;
18356
18851
  }
@@ -18601,8 +19096,10 @@ function createTransform(deps) {
18601
19096
  const loadedSessions = new Set;
18602
19097
  const prefixHoldLogTurnIds = new Map;
18603
19098
  const thinkingFitRetries = new Set;
19099
+ const compactionModeTransitionPending = new Set;
18604
19100
  const clearSessionLogState = (sessionId) => {
18605
19101
  prefixHoldLogTurnIds.delete(sessionId);
19102
+ clearDiagnosticLogState(sessionId);
18606
19103
  };
18607
19104
  const unmanagedOverWindowSessions = new Set;
18608
19105
  const rustModeTransform = deps.transformMode === "rust" && deps.rustModeModuleClient ? createRustModeTransform(deps, {
@@ -18696,7 +19193,7 @@ function createTransform(deps) {
18696
19193
  failPass("store-generation-rebase-failure", error);
18697
19194
  }
18698
19195
  }
18699
- if (deps.client !== undefined) {
19196
+ if (deps.client !== undefined || deps.hostMessageReconciliationSource !== undefined) {
18700
19197
  withoutSqliteTransformPass2(() => scheduleReconciliation(db, sessionId, host.hostMessageReconciliationSource));
18701
19198
  }
18702
19199
  const tUserMsg = performance.now();
@@ -18743,6 +19240,7 @@ function createTransform(deps) {
18743
19240
  const hasTransitionEffects = transition.recordToWrite !== null || transition.notice !== null || transition.invalidatedM0Baseline || transition.clearedCompartmentInProgress || transition.historianCatchUpSignaled;
18744
19241
  if (hasTransitionEffects) {
18745
19242
  if (transition.invalidatedM0Baseline) {
19243
+ compactionModeTransitionPending.add(sessionId);
18746
19244
  sessionMeta = {
18747
19245
  ...sessionMeta,
18748
19246
  cachedM0Bytes: null,
@@ -19075,6 +19573,8 @@ function createTransform(deps) {
19075
19573
  contextLimit: boundaryContextLimit
19076
19574
  });
19077
19575
  let _boundarySnapshotCache;
19576
+ if (fullFeatureMode && !compactionOff)
19577
+ maintainExecuteFloorMark(db, sessionId, currentTurnId, boundaryUsageForProtectedTail.percentage < boundaryExecuteThreshold);
19078
19578
  const getRunnableBoundaryForCompartment = (emergencyTailScale) => {
19079
19579
  if (!canRunCompartments)
19080
19580
  return null;
@@ -19200,8 +19700,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19200
19700
  recordedSessionProjectIdentity.set(sessionId, sessionIdentityForBinding);
19201
19701
  }
19202
19702
  const taggerFloor = compactionOff ? 0 : deriveTaggerLoadFloor(messages, sessionId, db);
19203
- if (!compactionOff && taggerFloor === 0 && messages.length > 0) {
19204
- sessionLog2(sessionId, `tag floor: 0 (full-scan fallback) — no leading wire message resolved a tag across ${messages.length} msgs`);
19703
+ const tagFloorMode = compactionOff || messages.length === 0 ? "inactive" : taggerFloor === 0 ? "fallback" : "scoped";
19704
+ if (diagnosticStateChanged(sessionId, "tag-floor", tagFloorMode) && tagFloorMode !== "inactive") {
19705
+ sessionLog2(sessionId, taggerFloor === 0 ? `tag floor: 0 (full-scan fallback) — no scoped floor above the safety margin across ${messages.length} msgs` : `tag floor: ${taggerFloor} (scoped load)`);
19205
19706
  }
19206
19707
  const ownerRatio = sessionDecisionCalibration(db, sessionId).proseRatio;
19207
19708
  noteTransformPassForExactOrdinalReads(sessionId);
@@ -19238,7 +19739,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19238
19739
  idleExpiry: false,
19239
19740
  emergency: contextUsageEarly.percentage >= forceMaterializationPercentage
19240
19741
  }
19241
- }, pendingDropEligibility.read(sessionId, dropProjectionKey()));
19742
+ }, pendingDropEligibility.read(sessionId, dropProjectionKey()), schedulerDecision === "execute");
19242
19743
  if (triggerResult.shouldFire) {
19243
19744
  sessionLog2(sessionId, `compartment trigger: firing (reason=${triggerResult.reason})`);
19244
19745
  updateSessionMeta(db, sessionId, { compartmentInProgress: true });
@@ -19392,7 +19893,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19392
19893
  if (persistedReasoningWatermark > 0 && !compactionOff) {
19393
19894
  const tReplay = performance.now();
19394
19895
  const replayed = canUseEmptySentinels ? replayClearedReasoning(messages, reasoningByMessage, messageTagNumbers, persistedReasoningWatermark) : 0;
19395
- const replayedInline = replayStrippedInlineThinking(messages, messageTagNumbers, persistedReasoningWatermark);
19896
+ const replayedInline = replayStrippedInlineThinking(messages, messageTagNumbers, persistedReasoningWatermark, !canUseEmptySentinels);
19396
19897
  if (replayed > 0 || replayedInline > 0) {
19397
19898
  sessionLog2(sessionId, `reasoning replay: cleared=${replayed} inlineStripped=${replayedInline} (watermark=${persistedReasoningWatermark})`);
19398
19899
  }
@@ -19609,6 +20110,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19609
20110
  activeThinkingPrefixHold,
19610
20111
  directoryPrefixHold: unresolvedDirectoryHold,
19611
20112
  forceSignedRebuildForFit: thinkingFitRetries.has(sessionId) || !!recovery.rebuildReason,
20113
+ compactionModeTransition: compactionModeTransitionPending.has(sessionId),
19612
20114
  readLastServedMessages: () => {
19613
20115
  const slot = getInMemorySlot(sessionId) ?? loadPersistedLkgSlot(db, sessionId);
19614
20116
  try {
@@ -19666,6 +20168,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19666
20168
  hardSignals: m0HardSignals
19667
20169
  }
19668
20170
  });
20171
+ compactionModeTransitionPending.delete(sessionId);
19669
20172
  if (recovery.prefix && !recoveryNormalized) {
19670
20173
  const priorIds = new Set(recovery.prefix.inputs.map((input) => input.id));
19671
20174
  const newIds = new Set(lkgInput.flatMap((input) => input.id && !priorIds.has(input.id) ? [input.id] : []));
@@ -19843,7 +20346,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19843
20346
  if (JSON.stringify([...new Set(stillUntagged)].sort()) !== JSON.stringify([...new Set(persistedUntaggedInputIds)].sort()) && !persistLkgUntaggedInputIds(db, sessionId, stillUntagged))
19844
20347
  throw new Error("Cannot persist the last-good untagged-message record");
19845
20348
  }
19846
- finishSystemDateRefresh(deps.historyRefreshSessions, dateRequest, postTransformResult.bustedThisPass && !activeThinkingPrefixHold && postTransformResult.openTurnSignedThinkingKept !== true || postTransformResult.thinkingReleasedForFit === true, postTransformResult.openTurnSignedThinkingKept === true);
20349
+ const signedThinkingServed = isPrefixBoundThinkingModel(modelForBudget?.providerID, modelForBudget?.modelID) && servesThinkingBlock(messages, modelForBudget?.providerID, modelForBudget?.modelID);
20350
+ finishSystemDateRefresh(deps.historyRefreshSessions, dateRequest, postTransformResult.bustedThisPass && !activeThinkingPrefixHold && !signedThinkingServed || postTransformResult.thinkingReleasedForFit === true, signedThinkingServed);
19847
20351
  if (activeThinkingPrefixHold && !postTransformResult.thinkingReleasedForFit && sessionMeta.cachedM0Bytes != null && sessionMeta.cachedM1Bytes != null) {
19848
20352
  recordHeldHeadForRequest(sessionId, currentLkgRequestIdentity(sessionId), (ownsHistory) => deferDeliveredSystemRefresh(deps, sessionId, ownsHistory));
19849
20353
  }
@@ -20001,7 +20505,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
20001
20505
  postReduceGraceBaselineU: channel1State.postReduceGraceBaselineU,
20002
20506
  postReduceGracePreLevel: channel1State.postReduceGracePreLevel
20003
20507
  });
20004
- sessionLog2(sessionId, formatChannel1Evaluation(channel1Decision));
20508
+ logNudgeEvaluation(sessionId, "transform", formatChannel1Evaluation(channel1Decision));
20005
20509
  const channel2Evaluation = evaluateChannel2(channelBaseline);
20006
20510
  const leaseBefore = getChannel2NudgeState(db, sessionId);
20007
20511
  if (channelBaseline.evaluable && !channelBaseline.generationInvalidated && !channelBaseline.reducedSinceRefresh) {
@@ -20012,7 +20516,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
20012
20516
  }
20013
20517
  }
20014
20518
  const leaseAfter = getChannel2NudgeState(db, sessionId);
20015
- sessionLog2(sessionId, formatChannel2Evaluation(channel2Evaluation, {
20519
+ logNudgeEvaluation(sessionId, "transform", formatChannel2Evaluation(channel2Evaluation, {
20016
20520
  leaseBefore,
20017
20521
  leaseAfter,
20018
20522
  gateHoldReason: channelBaseline.reducedSinceRefresh ? "recent-reduce-refresh" : undefined
@@ -21981,7 +22485,7 @@ function loadRegistrationConfig(directory) {
21981
22485
  configCache.delete(directory);
21982
22486
  return detailed;
21983
22487
  }
21984
- async function ensureProjectRegisteredFromOpenCodeDirectory(directory, db) {
22488
+ async function ensureProjectRegisteredFromOpenCodeDirectory(directory, db, options = {}) {
21985
22489
  const detailed = loadRegistrationConfig(directory);
21986
22490
  const projectIdentity = resolveProjectIdentityForSession(directory, detailed.config.allow_home_project);
21987
22491
  if (!projectIdentity)
@@ -22002,6 +22506,9 @@ async function ensureProjectRegisteredFromOpenCodeDirectory(directory, db) {
22002
22506
  memoryEnabled: detailed.config.memory.enabled,
22003
22507
  gitCommitEnabled: detailed.config.memory.git_commit_indexing.enabled
22004
22508
  };
22509
+ if (options.preflightLocalPooling && routing.primary.provider === "local") {
22510
+ await preflightLocalEmbeddingPooling(routing.primary.model ?? "Xenova/all-MiniLM-L6-v2");
22511
+ }
22005
22512
  const before = getProjectEmbeddingSnapshot2(projectIdentity);
22006
22513
  const registered = registerProjectEmbedding2(db, projectIdentity, routing.primary, features, directory);
22007
22514
  if (!before || before.providerIdentity !== registered.providerIdentity || before.runtimeFingerprint !== registered.runtimeFingerprint)
@@ -22011,6 +22518,7 @@ async function ensureProjectRegisteredFromOpenCodeDirectory(directory, db) {
22011
22518
  } else {
22012
22519
  unregisterProjectShadowEmbedding2(projectIdentity);
22013
22520
  }
22521
+ options.onRegistered?.(projectIdentity);
22014
22522
  }
22015
22523
 
22016
22524
  // src/hooks/magic-context/format-embed-failure.ts
@@ -22932,6 +23440,7 @@ function buildDebugMemoryUsage(runtimeHolders = {}) {
22932
23440
  const lkg = getLkgSlotHeapStats();
22933
23441
  const tagger = runtimeHolders.taggerCache ?? EMPTY_TAGGER_HEAP_STATS;
22934
23442
  const wire = runtimeHolders.wireCache ?? EMPTY_WIRE_HEAP_STATS;
23443
+ const replay = runtimeHolders.generateReplay ?? { totalBytes: 0, sessions: [] };
22935
23444
  const messageIndexQueue = getMessageIndexQueueHeapStats();
22936
23445
  const sessions = new Map;
22937
23446
  const session = (sessionId) => {
@@ -22945,7 +23454,8 @@ function buildDebugMemoryUsage(runtimeHolders = {}) {
22945
23454
  wireRawMessages: 0,
22946
23455
  wireMessages: 0,
22947
23456
  wireContentSnapshots: 0,
22948
- wireEstimatedBytes: 0
23457
+ wireEstimatedBytes: 0,
23458
+ generateReplayBytes: 0
22949
23459
  };
22950
23460
  sessions.set(sessionId, current);
22951
23461
  }
@@ -22965,6 +23475,8 @@ function buildDebugMemoryUsage(runtimeHolders = {}) {
22965
23475
  target.wireContentSnapshots += entry.rawContentSnapshots;
22966
23476
  target.wireEstimatedBytes += entry.estimatedBytes;
22967
23477
  }
23478
+ for (const entry of replay.sessions)
23479
+ session(entry.sessionId).generateReplayBytes += entry.bytes;
22968
23480
  return {
22969
23481
  pid: process.pid,
22970
23482
  bunVersion: typeof Bun !== "undefined" && typeof Bun.version === "string" ? Bun.version : "unavailable",
@@ -22995,6 +23507,10 @@ function buildDebugMemoryUsage(runtimeHolders = {}) {
22995
23507
  estimatedBytes: wire.estimatedBytes
22996
23508
  },
22997
23509
  compartmentMirrors: { entries: 0 },
23510
+ generateReplay: {
23511
+ sessionCount: replay.sessions.length,
23512
+ estimatedBytes: replay.totalBytes
23513
+ },
22998
23514
  messageIndexQueue,
22999
23515
  sessions: [...sessions.values()].sort((a, b) => a.sessionId.localeCompare(b.sessionId))
23000
23516
  }
@@ -23211,9 +23727,9 @@ function registerRpcHandlers(rpcServer, args) {
23211
23727
  return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
23212
23728
  });
23213
23729
  const buildManagedCtx = async (db) => {
23214
- const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-2zh4gm2c.js"));
23215
- const { resolveHistorianModel } = await importPluginModule(() => import("./model-resolution-nx97z3x7.js"));
23216
- const { userObservationCollectionEnabled, userObservationsRequested } = await importPluginModule(() => import("./task-config-nvz8mapa.js"));
23730
+ const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-knf763tt.js"));
23731
+ const { resolveHistorianModel } = await importPluginModule(() => import("./model-resolution-280gmqvd.js"));
23732
+ const { userObservationCollectionEnabled, userObservationsRequested } = await importPluginModule(() => import("./task-config-7md27rx8.js"));
23217
23733
  const DEFAULT_HISTORIAN_TIMEOUT_MS = 10 * 60 * 1000;
23218
23734
  const runConfig = historianRunConfig(config, currentPluginConfigReader(directory)?.poll().effective ?? config);
23219
23735
  const historianModel = resolveHistorianModel(runConfig, "opencode");
@@ -23244,7 +23760,7 @@ function registerRpcHandlers(rpcServer, args) {
23244
23760
  return { ok: false, error: "no session" };
23245
23761
  const readDirectory = args.readSessionDirectory;
23246
23762
  if (readDirectory) {
23247
- const { handoffHistoryWork } = await import("./history-owner-42e16w0n.js");
23763
+ const { handoffHistoryWork } = await import("./history-owner-ad0crnrn.js");
23248
23764
  const handed = await handoffHistoryWork({
23249
23765
  storageDir: args.storageDir ?? getMagicContextStorageDir(),
23250
23766
  directory,
@@ -23263,8 +23779,8 @@ function registerRpcHandlers(rpcServer, args) {
23263
23779
  const db = readDatabase();
23264
23780
  if (!db)
23265
23781
  return { ok: false, error: "db unavailable" };
23266
- const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-f6m9jr7p.js"));
23267
- const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-3pxn658x.js"));
23782
+ const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-b12zaptj.js"));
23783
+ const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-8eqe259v.js"));
23268
23784
  log2(`[rpc] recomp requested for session ${sessionId}`);
23269
23785
  if (!args.client && !args.hiddenCompletionExecutor) {
23270
23786
  return {
@@ -23322,7 +23838,7 @@ function registerRpcHandlers(rpcServer, args) {
23322
23838
  rpcServer.handle("wrapup", async (params) => {
23323
23839
  const readDirectory = args.readSessionDirectory;
23324
23840
  if (readDirectory && params.sessionId) {
23325
- const { handoffHistoryWork } = await import("./history-owner-42e16w0n.js");
23841
+ const { handoffHistoryWork } = await import("./history-owner-ad0crnrn.js");
23326
23842
  const sessionId = String(params.sessionId);
23327
23843
  const handed = await handoffHistoryWork({
23328
23844
  storageDir: args.storageDir ?? getMagicContextStorageDir(),
@@ -23348,7 +23864,7 @@ function registerRpcHandlers(rpcServer, args) {
23348
23864
  const db = readDatabase();
23349
23865
  if (!db)
23350
23866
  return { ok: false, error: "db unavailable" };
23351
- const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-embdz8gj.js"));
23867
+ const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-3ssd5yy1.js"));
23352
23868
  const model = liveSessionState.liveModelBySession.get(sessionId);
23353
23869
  const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
23354
23870
  const ctx = {
@@ -23433,8 +23949,17 @@ function subagentToolRefusal(db, toolId, sessionId, isInternalChild = () => fals
23433
23949
  function hideSubagentTools(draft, db) {
23434
23950
  if (!getOrCreateSessionMeta(db, draft.sessionID).isSubagent)
23435
23951
  return;
23952
+ removePrimaryOnlyTools(draft.tools);
23953
+ }
23954
+ function removePrimaryOnlyTools(tools) {
23436
23955
  for (const id of PRIMARY_ONLY_TOOLS)
23437
- delete draft.tools[id];
23956
+ delete tools[id];
23957
+ }
23958
+ function storedSubagentMode(db, sessionId) {
23959
+ const row = db.prepare("SELECT is_subagent FROM session_meta WHERE session_id = ?").get(sessionId);
23960
+ if (!row || typeof row.is_subagent !== "number")
23961
+ return;
23962
+ return row.is_subagent === 1;
23438
23963
  }
23439
23964
 
23440
23965
  // src/shared/conflict-detector.ts
@@ -24715,8 +25240,8 @@ function toolStateContent(state) {
24715
25240
  }
24716
25241
 
24717
25242
  // src/v2/hooks/copied-tag-notation.ts
24718
- function stripCopiedTagNotation(text) {
24719
- return text.includes("§") ? stripPersistedAssistantText(text) : text;
25243
+ function stripCopiedTagNotation(text, acceptsEmpty = true) {
25244
+ return text.includes("§") ? stripPersistedAssistantText(text, acceptsEmpty) : text;
24720
25245
  }
24721
25246
 
24722
25247
  // src/v2/hooks/payload.ts
@@ -24783,18 +25308,56 @@ function containsHostInstance(value) {
24783
25308
  return false;
24784
25309
  }
24785
25310
  function clonePreservingInstances(value) {
24786
- if (isHostInstance(value))
25311
+ return cloneCounting(value, undefined);
25312
+ }
25313
+ function clonePreservingInstancesMeasured(value) {
25314
+ const meter = { bytes: 0 };
25315
+ const copy = cloneCounting(value, meter);
25316
+ return { copy, bytes: meter.bytes };
25317
+ }
25318
+ function cloneCounting(value, meter) {
25319
+ if (isHostInstance(value)) {
25320
+ if (meter)
25321
+ meter.bytes += instanceBytes(value, new WeakSet);
24787
25322
  return value;
24788
- if (Array.isArray(value))
24789
- return value.map(clonePreservingInstances);
25323
+ }
25324
+ if (Array.isArray(value)) {
25325
+ if (meter)
25326
+ meter.bytes += 16 + 8 * value.length;
25327
+ return value.map((entry) => cloneCounting(entry, meter));
25328
+ }
24790
25329
  if (value && typeof value === "object") {
24791
25330
  const copy = {};
24792
- for (const [key, entry] of Object.entries(value))
24793
- copy[key] = clonePreservingInstances(entry);
25331
+ if (meter)
25332
+ meter.bytes += 32;
25333
+ for (const [key, entry] of Object.entries(value)) {
25334
+ if (meter)
25335
+ meter.bytes += 16;
25336
+ copy[key] = cloneCounting(entry, meter);
25337
+ }
24794
25338
  return copy;
24795
25339
  }
25340
+ if (meter)
25341
+ meter.bytes += typeof value === "string" ? 2 * value.length : 8;
24796
25342
  return value;
24797
25343
  }
25344
+ function instanceBytes(value, seen) {
25345
+ if (typeof value === "string")
25346
+ return 2 * value.length;
25347
+ if (!value || typeof value !== "object")
25348
+ return 8;
25349
+ if (seen.has(value))
25350
+ return 0;
25351
+ seen.add(value);
25352
+ if (ArrayBuffer.isView(value))
25353
+ return value.byteLength;
25354
+ if (value instanceof ArrayBuffer)
25355
+ return value.byteLength;
25356
+ let bytes = 32;
25357
+ for (const entry of Object.values(value))
25358
+ bytes += 16 + instanceBytes(entry, seen);
25359
+ return bytes;
25360
+ }
24798
25361
  function contentKey(value) {
24799
25362
  const plain = (entry) => {
24800
25363
  if (ArrayBuffer.isView(entry)) {
@@ -24850,7 +25413,7 @@ function rebuildFileContent(value, output, attachments) {
24850
25413
  rebuilt.unshift({ type: "text", text: output });
24851
25414
  return { type: "content", value: rebuilt };
24852
25415
  }
24853
- function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map) {
25416
+ function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map, hiddenTimes = false) {
24854
25417
  const existingHeads = new Map(draft.messages.filter((m) => HEAD_IDS.some((id) => m.id === id)).map((m) => [m.id, m]));
24855
25418
  const source = draft.messages.filter((m) => !existingHeads.has(m.id));
24856
25419
  const results = new Map;
@@ -24933,12 +25496,16 @@ function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map) {
24933
25496
  const messages = [];
24934
25497
  for (const message of source) {
24935
25498
  const parts = [];
25499
+ const copiedTagOnly = [];
24936
25500
  for (const content of message.content) {
24937
25501
  if (paired.has(content))
24938
25502
  continue;
24939
25503
  const part = callParts.get(content) ?? (content.type === "tool-result" ? nativeTool(undefined, { part: content, message }) : clonePreservingInstances(content));
24940
- if (message.role === "assistant" && part.type === "text" && typeof part.text === "string")
24941
- part.text = stripCopiedTagNotation(part.text);
25504
+ if (message.role === "assistant" && part.type === "text" && typeof part.text === "string") {
25505
+ if (!modelAcceptsEmptyContent(draft.model.providerID) && part.text.trim().length > 0 && stripCopiedTagNotation(part.text).trim().length === 0)
25506
+ copiedTagOnly.push({ index: parts.length, text: part.text });
25507
+ part.text = stripCopiedTagNotation(part.text, modelAcceptsEmptyContent(draft.model.providerID));
25508
+ }
24942
25509
  if (message.id && admittedIDs.has(message.id))
24943
25510
  part.synthetic = true;
24944
25511
  parts.push(part);
@@ -24969,7 +25536,18 @@ function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map) {
24969
25536
  },
24970
25537
  parts
24971
25538
  };
25539
+ if (hiddenTimes && mapped.info.time !== undefined) {
25540
+ const time = mapped.info.time;
25541
+ delete mapped.info.time;
25542
+ Object.defineProperty(mapped.info, "time", {
25543
+ value: time,
25544
+ enumerable: false,
25545
+ configurable: true,
25546
+ writable: true
25547
+ });
25548
+ }
24972
25549
  originals.set(mapped, message);
25550
+ markServedShapeRepair(mapped.info, copiedTagOnly);
24973
25551
  if (isCoveredInstructionRow(message))
24974
25552
  markCoveredInstructionRow(mapped.info);
24975
25553
  if (typeof message.id !== "string")
@@ -26469,10 +27047,12 @@ function assistantText(row) {
26469
27047
 
26470
27048
  class HiddenProviderError extends Error {
26471
27049
  settled;
27050
+ hostError;
26472
27051
  constructor(detail, options = {}) {
26473
27052
  super(`Hidden completion provider error: ${detail}`);
26474
27053
  this.name = "HiddenProviderError";
26475
27054
  this.settled = options.settled ?? true;
27055
+ this.hostError = options.hostError;
26476
27056
  }
26477
27057
  }
26478
27058
  function requestModel(request, current) {
@@ -26536,7 +27116,9 @@ async function awaitAssistantRow(openReader, readSessionError, localFailure, chi
26536
27116
  `terminal_row=${errorText(newIdle)}`,
26537
27117
  `session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
26538
27118
  ];
26539
- throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
27119
+ throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`, {
27120
+ cause: sessionError
27121
+ }) : new HiddenProviderError(details.join("; "), { hostError: sessionError });
26540
27122
  }
26541
27123
  if (outcome === "succeeded" && newAssistant)
26542
27124
  return newAssistant;
@@ -26550,7 +27132,9 @@ async function awaitAssistantRow(openReader, readSessionError, localFailure, chi
26550
27132
  `terminal_row=${errorText(newAssistant)}`,
26551
27133
  `session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
26552
27134
  ];
26553
- throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
27135
+ throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`, {
27136
+ cause: sessionError
27137
+ }) : new HiddenProviderError(details.join("; "), { hostError: sessionError });
26554
27138
  }
26555
27139
  if (newAssistant.data.error !== undefined) {
26556
27140
  throw new HiddenProviderError(errorText(newAssistant.data.error), {
@@ -26705,7 +27289,13 @@ async function createV2HiddenCompletionExecutor(host, options) {
26705
27289
  const head = await resolveHead(identity);
26706
27290
  const active = await lifecycle.open(identity, role, head);
26707
27291
  openedChild = active;
26708
- const handle = { id: active.id, childSessionId: active.id };
27292
+ const configuredModel = toModelEntry(identity.model);
27293
+ const handle = {
27294
+ id: active.id,
27295
+ childSessionId: active.id,
27296
+ attemptedModel: modelKey(head),
27297
+ ...configuredModel?.sourceConfigKey ? { modelConfigKey: configuredModel.sourceConfigKey } : {}
27298
+ };
26709
27299
  const tokenBudget = identity.metadata?.tokenBudget;
26710
27300
  const run = {
26711
27301
  identity,
@@ -26736,6 +27326,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
26736
27326
  }
26737
27327
  },
26738
27328
  async attempt(handle, request) {
27329
+ const startedAt = Date.now();
26739
27330
  const run = runs.get(handle);
26740
27331
  if (!run)
26741
27332
  throw new Error("Unknown hidden completion run");
@@ -26753,6 +27344,10 @@ async function createV2HiddenCompletionExecutor(host, options) {
26753
27344
  throw new Error("Hidden completion prompt aborted");
26754
27345
  }
26755
27346
  const requested = await validateVariant(requestModel(request, run.child.model));
27347
+ const requestedRef = modelKey(requested);
27348
+ const configuredModel = [run.identity.model, ...run.identity.configuredModels ?? []].map(toModelEntry).find((entry) => entry?.model === requestedRef);
27349
+ handle.attemptedModel = requestedRef;
27350
+ handle.modelConfigKey = configuredModel?.sourceConfigKey ?? handle.modelConfigKey;
26756
27351
  if (run.identity.kind !== "dreamer-task" && request.body.temperature === undefined) {
26757
27352
  const configured = options.historianTemperature?.();
26758
27353
  if (typeof configured === "number" && Number.isFinite(configured))
@@ -26847,6 +27442,22 @@ async function createV2HiddenCompletionExecutor(host, options) {
26847
27442
  abortReject = reject;
26848
27443
  });
26849
27444
  const onAbort = () => {
27445
+ const reason = request.signal?.reason;
27446
+ if (reason instanceof ModelProducedNoOutputError && run.identity.kind === "dreamer-task") {
27447
+ recordChildInvocation({
27448
+ db: options.db,
27449
+ parentSessionId: run.identity.parentSessionId ?? options.projectIdentity,
27450
+ parentInvocationId: run.identity.parentInvocationId,
27451
+ harness: "opencode2",
27452
+ subagent: "dreamer",
27453
+ task: run.identity.title.replace(/^magic-context-dream-/, ""),
27454
+ startedAt,
27455
+ status: "timed_out",
27456
+ error: reason,
27457
+ providerId: requested.providerID,
27458
+ modelId: requested.modelID
27459
+ });
27460
+ }
26850
27461
  interruptAndRetire(run, "prompt-aborted").finally(() => abortReject(new Error("Hidden completion prompt aborted")));
26851
27462
  };
26852
27463
  const deadlineTimer = setTimeout(() => {
@@ -26875,6 +27486,9 @@ async function createV2HiddenCompletionExecutor(host, options) {
26875
27486
  })
26876
27487
  };
26877
27488
  inFlight.add(entry);
27489
+ const stopWatching = host.watchModelActivity?.(run.child.id, () => noteModelOutputReceived(request.signal));
27490
+ if (stopWatching)
27491
+ noteModelActivityMonitored(request.signal);
26878
27492
  try {
26879
27493
  await Promise.race([
26880
27494
  host.prompt({ sessionID: run.child.id, text: marker }),
@@ -26930,12 +27544,20 @@ async function createV2HiddenCompletionExecutor(host, options) {
26930
27544
  usage: reportedUsage ? usage : meter(system, promptText(request), text ?? ""),
26931
27545
  lengthCapped: ["length", "max_tokens"].includes(row.data.finish ?? ""),
26932
27546
  providerId: row.data.model?.providerID ?? requested.providerID,
26933
- modelId: row.data.model?.id ?? requested.modelID
27547
+ modelId: row.data.model?.id ?? requested.modelID,
27548
+ attemptedModel: requestedRef,
27549
+ modelConfigKey: handle.modelConfigKey
26934
27550
  };
26935
27551
  if (!run.child.ever_settled)
26936
27552
  run.child = lifecycle.markEverSettled(run.child);
26937
27553
  } catch (caught) {
26938
27554
  const error = attempt.budgetExceeded ?? attempt.stepLimit ?? attempt.refusal ?? caught;
27555
+ const hostError = error instanceof HiddenProviderError ? error.hostError : error instanceof Error && error.message.startsWith("Hidden completion failed:") ? error.cause : undefined;
27556
+ annotateSubagentInvocationError(error, {
27557
+ attemptedModel: handle.attemptedModel,
27558
+ modelConfigKey: handle.modelConfigKey,
27559
+ ...hostError === undefined ? {} : { hostError }
27560
+ });
26939
27561
  run.failed = true;
26940
27562
  if (!(error instanceof HiddenProviderError)) {
26941
27563
  run.unsettledFailure = true;
@@ -26949,6 +27571,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
26949
27571
  }
26950
27572
  throw error;
26951
27573
  } finally {
27574
+ stopWatching?.();
26952
27575
  clearTimeout(deadlineTimer);
26953
27576
  if (budgetPoll)
26954
27577
  clearInterval(budgetPoll);
@@ -27004,6 +27627,30 @@ async function createV2HiddenCompletionExecutor(host, options) {
27004
27627
  };
27005
27628
  }
27006
27629
 
27630
+ // src/v2/hidden-model-activity.ts
27631
+ class HiddenModelActivity {
27632
+ watchers = new Map;
27633
+ watch(sessionID, onOutput) {
27634
+ this.watchers.set(sessionID, onOutput);
27635
+ return () => {
27636
+ if (this.watchers.get(sessionID) === onOutput)
27637
+ this.watchers.delete(sessionID);
27638
+ };
27639
+ }
27640
+ observe(event) {
27641
+ if (!isRecord(event) || !isRecord(event.data))
27642
+ return;
27643
+ const { sessionID, delta, text } = event.data;
27644
+ if (typeof sessionID !== "string")
27645
+ return;
27646
+ const streamed = ["session.text.delta", "session.reasoning.delta", "session.tool.input.delta"].includes(String(event.type)) && typeof delta === "string" && delta.length > 0;
27647
+ const ended = ["session.text.ended", "session.reasoning.ended"].includes(String(event.type)) && typeof text === "string" && text.length > 0;
27648
+ if (streamed || ended || event.type === "session.tool.input.started") {
27649
+ this.watchers.get(sessionID)?.();
27650
+ }
27651
+ }
27652
+ }
27653
+
27007
27654
  // src/v2/hooks/channel2.ts
27008
27655
  import { randomBytes as randomBytes2 } from "node:crypto";
27009
27656
  var pendingCandidates = new WeakMap;
@@ -27869,7 +28516,9 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
27869
28516
  status: "completed",
27870
28517
  tokens: run.output.usage,
27871
28518
  providerId: run.output.providerId,
27872
- modelId: run.output.modelId
28519
+ modelId: run.output.modelId,
28520
+ attemptedModel: args.model,
28521
+ configuredModels: args.fallbackModels
27873
28522
  });
27874
28523
  }
27875
28524
  stage = "apply";
@@ -28061,6 +28710,7 @@ async function runHiddenSingleShotPrompt(args) {
28061
28710
  });
28062
28711
  }).catch(() => {});
28063
28712
  const handle = await raceWithSignal(opening, args.signal);
28713
+ let completion;
28064
28714
  args.onOpened?.(handle.id);
28065
28715
  let promptSettled = false;
28066
28716
  try {
@@ -28082,7 +28732,10 @@ async function runHiddenSingleShotPrompt(args) {
28082
28732
  ...args.signal ? { signal: args.signal } : {},
28083
28733
  fallbackModels: args.fallbackModels,
28084
28734
  callContext: args.callContext,
28085
- fetchOutput: () => args.executor.collect(handle, 50),
28735
+ fetchOutput: async () => {
28736
+ completion = await args.executor.collect(handle, 50);
28737
+ return completion;
28738
+ },
28086
28739
  validateOutput: (completion) => {
28087
28740
  const tokens = completion.tokenLog ?? runTokenLog(undefined);
28088
28741
  sessionLog2(args.parentSessionId ?? "dreamer", `${args.callContext} response_chars=${(completion.text ?? completion.reasoning ?? "").length} ${formatRunTokenLog(tokens)}`);
@@ -28098,6 +28751,12 @@ async function runHiddenSingleShotPrompt(args) {
28098
28751
  promptSettled = true;
28099
28752
  return { validated: run.validated, completion: run.output, childSessionId: handle.id };
28100
28753
  } catch (error) {
28754
+ const configuredModel = toModelEntry(args.model);
28755
+ annotateSubagentInvocationError(error, {
28756
+ attemptedModel: completion?.attemptedModel ?? handle.attemptedModel ?? configuredModel?.model,
28757
+ modelConfigKey: completion?.modelConfigKey ?? handle.modelConfigKey ?? configuredModel?.sourceConfigKey,
28758
+ ...completion?.hostError === undefined ? {} : { hostError: completion.hostError }
28759
+ });
28101
28760
  if (args.onFailureOutput) {
28102
28761
  let timer;
28103
28762
  try {
@@ -28425,6 +29084,8 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
28425
29084
  startedAt,
28426
29085
  status: params.status,
28427
29086
  messages: params.messages,
29087
+ attemptedModel: args.model,
29088
+ configuredModels: args.fallbackModels,
28428
29089
  error: params.error
28429
29090
  });
28430
29091
  };
@@ -29212,6 +29873,8 @@ function recordInvocation(args, startedAt, params) {
29212
29873
  startedAt,
29213
29874
  status: params.status,
29214
29875
  messages: params.messages,
29876
+ attemptedModel: args.model,
29877
+ configuredModels: args.fallbackModels,
29215
29878
  ...params.completion && !params.completion.messages ? {
29216
29879
  tokens: params.completion.usage,
29217
29880
  providerId: params.completion.providerId,
@@ -29527,28 +30190,35 @@ function diff(name, before, after) {
29527
30190
  rmSync2(dir, { recursive: true, force: true });
29528
30191
  }
29529
30192
  }
29530
- function validateDocsProposal(projectDir, output, budget, expected) {
29531
- if (Object.entries(expected).some(([name, value]) => docsBaseHashes(projectDir)[name] !== value))
29532
- throw new Error("base drifted");
30193
+ function parseDocsProposalOutput(output) {
29533
30194
  const match = output.match(/```json\s*([\s\S]*?)```/);
29534
30195
  const parsed = JSON.parse(match?.[1] ?? output);
29535
30196
  if (!Array.isArray(parsed))
29536
30197
  throw new Error("proposal must be a JSON array");
29537
30198
  const changes = parsed;
29538
- if (!changes.length)
29539
- throw new Error("empty proposal");
29540
30199
  if (changes.some((item) => !item || !FILES.includes(item.file)))
29541
30200
  throw new Error("unknown proposal file");
30201
+ const seen = new Set;
30202
+ for (const change of changes) {
30203
+ const key = `${change.file}:${change.heading}`;
30204
+ if (!["replace", "add", "remove"].includes(change.action) || typeof change.heading !== "string" || !/^#{1,6} [^\r\n]+$/.test(change.heading) || typeof change.text !== "string" || typeof change.reason !== "string" || !change.reason.trim() || /[\r\n]/.test(change.reason) || seen.has(key))
30205
+ throw new Error(`invalid section change in ${change.file}`);
30206
+ seen.add(key);
30207
+ }
30208
+ return changes;
30209
+ }
30210
+ function validateDocsProposal(projectDir, output, budget, expected) {
30211
+ if (Object.entries(expected).some(([name, value]) => docsBaseHashes(projectDir)[name] !== value))
30212
+ throw new Error("base drifted");
30213
+ const changes = parseDocsProposalOutput(output);
30214
+ if (!changes.length)
30215
+ throw new Error("empty proposal");
29542
30216
  let tokens = 0;
29543
30217
  let diffs = "";
29544
30218
  for (const file of FILES) {
29545
30219
  const before = existsSync4(join8(projectDir, file)) ? readFileSync6(join8(projectDir, file), "utf8") : "";
29546
30220
  let after = before;
29547
- const seen = new Set;
29548
30221
  for (const change of changes.filter((item) => item.file === file)) {
29549
- if (!["replace", "add", "remove"].includes(change.action) || typeof change.heading !== "string" || !/^#{1,6} [^\r\n]+$/.test(change.heading) || typeof change.text !== "string" || typeof change.reason !== "string" || !change.reason.trim() || /[\r\n]/.test(change.reason) || seen.has(change.heading))
29550
- throw new Error(`invalid section change in ${file}`);
29551
- seen.add(change.heading);
29552
30222
  const section = sections(after).find((item) => item.heading === change.heading);
29553
30223
  if (change.action === "add") {
29554
30224
  if (section || !change.text.startsWith(`${change.heading}
@@ -29937,6 +30607,8 @@ Remember: output only the JSON object described by the system prompt.`;
29937
30607
  startedAt,
29938
30608
  status: params.status,
29939
30609
  messages: params.messages,
30610
+ attemptedModel: args.model,
30611
+ configuredModels: args.fallbackModels,
29940
30612
  error: params.error
29941
30613
  });
29942
30614
  };
@@ -30741,6 +31413,8 @@ async function confirmReadOnly(args, noteId, content, surfaceCondition, leaseSig
30741
31413
  startedAt,
30742
31414
  status: params.status,
30743
31415
  messages: params.messages,
31416
+ attemptedModel: args.model,
31417
+ configuredModels: args.fallbackModels,
30744
31418
  error: params.error
30745
31419
  });
30746
31420
  };
@@ -31655,12 +32329,14 @@ function recordInvocation2(args, startedAt, params) {
31655
32329
  recordChildInvocation({
31656
32330
  db: args.db,
31657
32331
  parentSessionId: args.parentSessionId,
31658
- harness: "opencode",
32332
+ harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
31659
32333
  subagent: "dreamer",
31660
32334
  task: "map-memories",
31661
32335
  startedAt,
31662
32336
  status: params.status,
31663
32337
  messages: params.messages,
32338
+ attemptedModel: args.model,
32339
+ configuredModels: args.fallbackModels,
31664
32340
  error: params.error
31665
32341
  });
31666
32342
  }
@@ -32285,12 +32961,14 @@ function recordInvocation3(args, startedAt, params) {
32285
32961
  recordChildInvocation({
32286
32962
  db: args.db,
32287
32963
  parentSessionId: args.parentSessionId,
32288
- harness: "opencode",
32964
+ harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
32289
32965
  subagent: "dreamer",
32290
32966
  task: "refresh-primers",
32291
32967
  startedAt,
32292
32968
  status: params.status,
32293
32969
  messages: params.messages,
32970
+ attemptedModel: args.model,
32971
+ configuredModels: args.fallbackModels,
32294
32972
  error: params.error
32295
32973
  });
32296
32974
  }
@@ -33891,12 +34569,14 @@ function recordInvocation4(args, startedAt, params) {
33891
34569
  recordChildInvocation({
33892
34570
  db: args.db,
33893
34571
  parentSessionId: args.parentSessionId,
33894
- harness: "opencode",
34572
+ harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
33895
34573
  subagent: "dreamer",
33896
34574
  task: args.forceBroad ? "verify-broad" : "verify",
33897
34575
  startedAt,
33898
34576
  status: params.status,
33899
34577
  messages: params.messages,
34578
+ attemptedModel: args.model,
34579
+ configuredModels: args.fallbackModels,
33900
34580
  error: params.error
33901
34581
  });
33902
34582
  }
@@ -34772,6 +35452,25 @@ async function runRetrospectiveTask(config, ctx, helpers) {
34772
35452
  let childSessionId = null;
34773
35453
  let hiddenHandle = null;
34774
35454
  let promptSettled = false;
35455
+ let invocationRecorded = false;
35456
+ const recordInvocation = (status, messages, error) => {
35457
+ if (!parent || !childSessionId || invocationRecorded)
35458
+ return;
35459
+ invocationRecorded = true;
35460
+ recordChildInvocation({
35461
+ db,
35462
+ parentSessionId: parent,
35463
+ harness: deps.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
35464
+ subagent: "dreamer",
35465
+ task: config.task,
35466
+ startedAt: helpers.invocationStartedAt,
35467
+ status,
35468
+ messages,
35469
+ attemptedModel: config.model,
35470
+ configuredModels: config.fallbackModels,
35471
+ error
35472
+ });
35473
+ };
34775
35474
  try {
34776
35475
  if (deps.hiddenCompletionExecutor) {
34777
35476
  hiddenHandle = await deps.hiddenCompletionExecutor.open({
@@ -34856,18 +35555,8 @@ async function runRetrospectiveTask(config, ctx, helpers) {
34856
35555
  return { ...run, output };
34857
35556
  };
34858
35557
  const finish = (run, watermark) => {
34859
- if (parent && run) {
34860
- recordChildInvocation({
34861
- db,
34862
- parentSessionId: parent,
34863
- harness: "opencode",
34864
- subagent: "dreamer",
34865
- task: config.task,
34866
- startedAt: helpers.invocationStartedAt,
34867
- status: "completed",
34868
- messages: run.output
34869
- });
34870
- }
35558
+ if (run)
35559
+ recordInvocation("completed", run.output);
34871
35560
  return completedWindow(watermark);
34872
35561
  };
34873
35562
  const userLines = renderGateUserLines(messages);
@@ -34960,6 +35649,7 @@ async function runRetrospectiveTask(config, ctx, helpers) {
34960
35649
  log2(`[dreamer] retrospective: flagged=${flagged.length} learnings=${learnings.length} memory=${applied.memoryWritten} observations=${applied.observationsInserted} dropped=${applied.observationsDropped} rejected=${applied.rejected.length}`);
34961
35650
  return finish(deepenRun, scan.maxScannedTs);
34962
35651
  } catch (error) {
35652
+ recordInvocation(abortController.signal.aborted ? "aborted" : failedInvocationStatus(error), undefined, error);
34963
35653
  if (!detectOverflow(error).isOverflow)
34964
35654
  throw error;
34965
35655
  const failures = (activeOverflow?.failures ?? 0) + 1;
@@ -35031,6 +35721,25 @@ async function runAgenticTask(config, ctx, helpers) {
35031
35721
  let childSessionId = null;
35032
35722
  let promptSettled = false;
35033
35723
  let expiredArchived = 0;
35724
+ let invocationRecorded = false;
35725
+ const recordInvocation = (status, messages, error) => {
35726
+ if (!parent || !childSessionId || invocationRecorded)
35727
+ return;
35728
+ invocationRecorded = true;
35729
+ recordChildInvocation({
35730
+ db,
35731
+ parentSessionId: parent,
35732
+ harness: deps.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
35733
+ subagent: "dreamer",
35734
+ task,
35735
+ startedAt: invocationStartedAt,
35736
+ status,
35737
+ messages,
35738
+ attemptedModel: config.model,
35739
+ configuredModels: config.fallbackModels,
35740
+ error
35741
+ });
35742
+ };
35034
35743
  try {
35035
35744
  let curateMemories;
35036
35745
  let curateCategory;
@@ -35119,12 +35828,17 @@ async function runAgenticTask(config, ctx, helpers) {
35119
35828
  callContext: `dreamer:${task}`,
35120
35829
  metadata: { tokenBudget: config.tokenBudget, onBudgetUpdate },
35121
35830
  allowEmpty: task === "curate",
35831
+ onOpened: (sessionId) => {
35832
+ childSessionId = sessionId;
35833
+ },
35122
35834
  model: config.model,
35123
35835
  fallbackModels: config.fallbackModels,
35124
35836
  language: task === "curate" ? config.language ?? deps.language : undefined,
35125
35837
  timeoutMs: Math.min(Math.max(0, deadline - Date.now()), config.timeoutMinutes * 60 * 1000),
35126
35838
  signal: abortController.signal,
35127
35839
  parse: (text, completion) => {
35840
+ if (task === "maintain-docs")
35841
+ parseDocsProposalOutput(text);
35128
35842
  if (task !== "curate")
35129
35843
  return text;
35130
35844
  const memoryOperations = inspectCurateMemoryOperations(completion.messages);
@@ -35188,6 +35902,8 @@ async function runAgenticTask(config, ctx, helpers) {
35188
35902
  if (task !== "curate") {
35189
35903
  if (!text)
35190
35904
  throw new Error("Dreamer returned no assistant output.");
35905
+ if (task === "maintain-docs")
35906
+ parseDocsProposalOutput(text);
35191
35907
  return text;
35192
35908
  }
35193
35909
  const memoryOperations = inspectCurateMemoryOperations(messages);
@@ -35234,21 +35950,10 @@ async function runAgenticTask(config, ctx, helpers) {
35234
35950
  helpers.reportProgress(curateRefused, curateRefused);
35235
35951
  log2(`[dreamer] curate safety summary: refused=${curateRefused}`);
35236
35952
  }
35237
- if (parent) {
35238
- recordChildInvocation({
35239
- db,
35240
- parentSessionId: parent,
35241
- harness: "opencode",
35242
- subagent: "dreamer",
35243
- task,
35244
- startedAt: invocationStartedAt,
35245
- status: "completed",
35246
- messages: run.output
35247
- });
35248
- }
35953
+ recordInvocation("completed", run.output);
35249
35954
  if (task === "maintain-docs" && docsHashes && changes) {
35250
35955
  try {
35251
- if (run.validated === "[]") {
35956
+ if (parseDocsProposalOutput(String(run.validated)).length === 0) {
35252
35957
  helpers.recordRun("completed", null, { progress: "no corrections proposed" });
35253
35958
  return {
35254
35959
  status: "completed",
@@ -35299,6 +36004,9 @@ async function runAgenticTask(config, ctx, helpers) {
35299
36004
  }
35300
36005
  } : {}
35301
36006
  };
36007
+ } catch (error) {
36008
+ recordInvocation(abortController.signal.aborted ? "aborted" : failedInvocationStatus(error), undefined, error);
36009
+ throw error;
35302
36010
  } finally {
35303
36011
  heartbeat.stop();
35304
36012
  if (childSessionId)
@@ -36454,7 +37162,7 @@ function registerV2DreamScheduleTimer(args) {
36454
37162
  since_days: gitCommitIndexing.since_days,
36455
37163
  max_commits: gitCommitIndexing.max_commits
36456
37164
  } : undefined,
36457
- ensureRegistered: ensureProjectRegisteredFromOpenCodeDirectory
37165
+ ensureRegistered: args.ensureRegistered ?? ensureProjectRegisteredFromOpenCodeDirectory
36458
37166
  }).catch((error) => {
36459
37167
  log2(`[magic-context] v2 dream timer registration failed (continuing without it): ${error}`);
36460
37168
  return;
@@ -36549,6 +37257,41 @@ function startDreamTrigger(context, args) {
36549
37257
  };
36550
37258
  }
36551
37259
 
37260
+ // src/v2/hooks/embedding-lifecycle.ts
37261
+ function createV2EmbeddingScope(initialProject) {
37262
+ const releases = new Map;
37263
+ const pending = new Set;
37264
+ let disposed = false;
37265
+ let disposal;
37266
+ const claim = (project) => {
37267
+ if (!releases.has(project))
37268
+ releases.set(project, retainProjectEmbedding2(project));
37269
+ };
37270
+ if (initialProject)
37271
+ claim(initialProject);
37272
+ return {
37273
+ ensureRegistered(directory, db) {
37274
+ if (disposed)
37275
+ return Promise.resolve();
37276
+ const registration = ensureProjectRegisteredFromOpenCodeDirectory(directory, db, {
37277
+ onRegistered: claim
37278
+ });
37279
+ pending.add(registration);
37280
+ return registration.finally(() => pending.delete(registration));
37281
+ },
37282
+ dispose() {
37283
+ disposed = true;
37284
+ disposal ??= (async () => {
37285
+ await Promise.allSettled([...pending]);
37286
+ for (const release of releases.values())
37287
+ release();
37288
+ releases.clear();
37289
+ })();
37290
+ return disposal;
37291
+ }
37292
+ };
37293
+ }
37294
+
36552
37295
  // src/v2/hooks/generate.ts
36553
37296
  function generateReplayAnchor(messages) {
36554
37297
  let index = messages.length - 1;
@@ -36561,26 +37304,70 @@ function generateReplayAnchor(messages) {
36561
37304
  return;
36562
37305
  return { id, tail: clonePreservingInstances(messages.slice(index + 1)) };
36563
37306
  }
37307
+ var DEFAULT_GENERATE_REPLAY_LIMITS = Object.freeze({
37308
+ maxSessions: 16,
37309
+ sessionMaxBytes: 128 * 1024 * 1024,
37310
+ totalMaxBytes: 256 * 1024 * 1024
37311
+ });
36564
37312
 
36565
37313
  class V2GenerateReplay {
36566
37314
  prefixes = new Map;
37315
+ totalBytes = 0;
37316
+ limits;
37317
+ constructor(limits = DEFAULT_GENERATE_REPLAY_LIMITS) {
37318
+ if (!Number.isSafeInteger(limits.maxSessions) || limits.maxSessions < 1 || !Number.isSafeInteger(limits.sessionMaxBytes) || limits.sessionMaxBytes < 1 || !Number.isSafeInteger(limits.totalMaxBytes) || limits.totalMaxBytes < 1)
37319
+ throw new Error("Generate replay limits must be positive integers");
37320
+ this.limits = { ...limits };
37321
+ }
36567
37322
  capture(draft, anchor) {
37323
+ this.forget(draft.sessionID);
36568
37324
  if (!anchor) {
36569
- this.prefixes.delete(draft.sessionID);
36570
37325
  sessionLog2(draft.sessionID, "generate replay capture skipped: no-anchor");
36571
37326
  return;
36572
37327
  }
37328
+ const parts = {
37329
+ anchor: clonePreservingInstancesMeasured(anchor),
37330
+ system: clonePreservingInstancesMeasured(draft.system),
37331
+ messages: clonePreservingInstancesMeasured(draft.messages),
37332
+ tools: clonePreservingInstancesMeasured(draft.tools)
37333
+ };
37334
+ const bytes = 256 + parts.anchor.bytes + parts.system.bytes + parts.messages.bytes + parts.tools.bytes;
37335
+ if (bytes > this.limits.sessionMaxBytes || bytes > this.limits.totalMaxBytes) {
37336
+ sessionLog2(draft.sessionID, `generate replay capture skipped: over-session-cap (${bytes} > ${Math.min(this.limits.sessionMaxBytes, this.limits.totalMaxBytes)} bytes)`);
37337
+ return;
37338
+ }
37339
+ while (this.prefixes.size > 0 && (this.prefixes.size >= this.limits.maxSessions || this.totalBytes + bytes > this.limits.totalMaxBytes)) {
37340
+ const oldest = this.prefixes.keys().next().value;
37341
+ if (oldest === undefined)
37342
+ break;
37343
+ this.forget(oldest);
37344
+ }
36573
37345
  this.prefixes.set(draft.sessionID, {
36574
- anchor: clonePreservingInstances(anchor),
37346
+ anchor: parts.anchor.copy,
36575
37347
  model: `${draft.model.providerID}/${draft.model.id}`,
36576
37348
  agent: draft.agent,
36577
- system: clonePreservingInstances(draft.system),
36578
- messages: clonePreservingInstances(draft.messages),
36579
- tools: clonePreservingInstances(draft.tools)
37349
+ system: parts.system.copy,
37350
+ messages: parts.messages.copy,
37351
+ tools: parts.tools.copy,
37352
+ bytes
36580
37353
  });
37354
+ this.totalBytes += bytes;
36581
37355
  }
36582
37356
  forget(sessionID) {
37357
+ const prefix = this.prefixes.get(sessionID);
37358
+ if (!prefix)
37359
+ return;
36583
37360
  this.prefixes.delete(sessionID);
37361
+ this.totalBytes -= prefix.bytes;
37362
+ }
37363
+ stats() {
37364
+ return {
37365
+ totalBytes: this.totalBytes,
37366
+ sessions: [...this.prefixes].map(([sessionId, prefix]) => ({
37367
+ sessionId,
37368
+ bytes: prefix.bytes
37369
+ }))
37370
+ };
36584
37371
  }
36585
37372
  apply(draft) {
36586
37373
  const prefix = this.prefixes.get(draft.sessionID);
@@ -36590,6 +37377,8 @@ class V2GenerateReplay {
36590
37377
  };
36591
37378
  if (!prefix)
36592
37379
  return skip("no-prefix");
37380
+ this.prefixes.delete(draft.sessionID);
37381
+ this.prefixes.set(draft.sessionID, prefix);
36593
37382
  if (prefix.model !== `${draft.model.providerID}/${draft.model.id}`)
36594
37383
  return skip("model-mismatch");
36595
37384
  if (prefix.agent !== draft.agent)
@@ -36633,21 +37422,25 @@ function identity(slot) {
36633
37422
 
36634
37423
  class V2LkgSystemReplay {
36635
37424
  systems = new BoundedSessionMap(1000);
36636
- capture(sessionId, slot, input, served) {
37425
+ capture(sessionId, slot, input, served, head) {
36637
37426
  this.systems.set(sessionId, {
36638
37427
  slot: identity(slot),
36639
- input: JSON.stringify(input),
36640
- served: structuredClone(served)
37428
+ input: hostInputKey(input),
37429
+ served: structuredClone(served),
37430
+ head: head ? structuredClone(head) : null
36641
37431
  });
36642
37432
  }
36643
37433
  restore(sessionId, slot, input, target) {
36644
37434
  const saved = this.systems.get(sessionId);
36645
- if (!slot || !saved || saved.slot !== identity(slot) || saved.input !== JSON.stringify(input))
36646
- return false;
37435
+ if (!slot || !saved || saved.slot !== identity(slot) || saved.input !== hostInputKey(input))
37436
+ return;
36647
37437
  target.splice(0, target.length, ...structuredClone(saved.served));
36648
- return true;
37438
+ return { head: saved.head ? structuredClone(saved.head) : null };
36649
37439
  }
36650
37440
  }
37441
+ function hostInputKey(input) {
37442
+ return JSON.stringify({ system: input.system, checkpoint: input.checkpoint });
37443
+ }
36651
37444
 
36652
37445
  // src/v2/hooks/model-limit-cache.ts
36653
37446
  var warmStarted = false;
@@ -37537,6 +38330,22 @@ function* readV2RawMessagePagesForConversion(openReader, sessionID, pageRows = C
37537
38330
  function createV2RawMessageReader(openReader) {
37538
38331
  const servedBoundaryCache = new Map;
37539
38332
  return {
38333
+ getRevision: (sessionID) => {
38334
+ const reader = openReader();
38335
+ try {
38336
+ return reader.latestSequence(sessionID);
38337
+ } finally {
38338
+ reader.close();
38339
+ }
38340
+ },
38341
+ getCountAfterRevision: (sessionID, after, through) => {
38342
+ const reader = openReader();
38343
+ try {
38344
+ return reader.messageCountAfterSequence(sessionID, after, through);
38345
+ } finally {
38346
+ reader.close();
38347
+ }
38348
+ },
37540
38349
  readPage: (sessionID, afterOrdinal, limit, finalWatermark, after) => {
37541
38350
  const reader = openReader();
37542
38351
  try {
@@ -51281,7 +52090,7 @@ function createCtxReduceTool(deps) {
51281
52090
  args = unwrapImitatedReducedArgs(args, ["drop"], { drop: "string" });
51282
52091
  const sessionId = toolContext.sessionID;
51283
52092
  if (!args.drop) {
51284
- return "Error: 'drop' must be provided.";
52093
+ return `Error: 'drop' must be provided as a string of tag numbers, for example {"drop": "3-5,8"}.`;
51285
52094
  }
51286
52095
  const rustReduce = deps.rustToolBackends?.reduce;
51287
52096
  if (rustReduce) {
@@ -51547,6 +52356,7 @@ function createCtxSearchTool(deps) {
51547
52356
  return formatSearchResults2(query, idResults ?? [], toolContext.sessionID, diagnostics);
51548
52357
  }
51549
52358
  }
52359
+ let rerankSkipped = "";
51550
52360
  const results = await unifiedSearch2(deps.db, toolContext.sessionID, projectPath, query, {
51551
52361
  limit: normalizeLimit2(args.limit),
51552
52362
  memoryEnabled,
@@ -51565,10 +52375,16 @@ function createCtxSearchTool(deps) {
51565
52375
  gitRepositoryAvailable: typeof toolContext.directory === "string" ? directoryHasGitMetadata(toolContext.directory) : undefined,
51566
52376
  explicitSearch: true,
51567
52377
  rerankConnectionFile: deps.rerankConnectionFile,
52378
+ rerankConfig: deps.rerankConfig,
52379
+ onRerankSkipped: (line) => {
52380
+ rerankSkipped = line;
52381
+ },
51568
52382
  searchMessageHistory: (request) => searchMessageHistoryOffThread(deps.db, request),
52383
+ signal: toolContext.abort,
51569
52384
  ...dateRange
51570
52385
  });
51571
- return formatSearchResults2(query, results, toolContext.sessionID, diagnostics);
52386
+ return formatSearchResults2(query, results, toolContext.sessionID, diagnostics) + (rerankSkipped ? `
52387
+ ${rerankSkipped}` : "");
51572
52388
  }
51573
52389
  });
51574
52390
  }
@@ -51578,13 +52394,13 @@ function createCtxSearchTools(deps) {
51578
52394
  };
51579
52395
  }
51580
52396
  // src/v2/hooks/tools.ts
51581
- async function registerTools(context, db, config, rustToolBackends, isInternalChild) {
52397
+ async function registerTools(context, db, config, rustToolBackends, isInternalChild, ensureProjectRegistered = ensureProjectRegisteredFromOpenCodeDirectory) {
51582
52398
  const compaction = isCompactionEnabled(config);
51583
52399
  setCtxReduceRegisteredGlobally(compaction);
51584
52400
  const project = {
51585
52401
  db,
51586
52402
  resolveProjectPath: (directory) => resolveProjectIdentityForSession(directory, config.allow_home_project),
51587
- ensureProjectRegistered: ensureProjectRegisteredFromOpenCodeDirectory
52403
+ ensureProjectRegistered
51588
52404
  };
51589
52405
  const definitions = {
51590
52406
  ...compaction ? createCtxReduceTools({
@@ -51604,7 +52420,11 @@ async function registerTools(context, db, config, rustToolBackends, isInternalCh
51604
52420
  smartNotesEnabled: config.smart_notes.enabled,
51605
52421
  ...rustToolBackends ? { rustToolBackends } : {}
51606
52422
  }),
51607
- ...createCtxSearchTools({ ...project, rerankConnectionFile: config.subc?.connection_file }),
52423
+ ...createCtxSearchTools({
52424
+ ...project,
52425
+ rerankConnectionFile: config.subc?.connection_file,
52426
+ rerankConfig: config.rerank
52427
+ }),
51608
52428
  ...config.memory.enabled ? {
51609
52429
  ...createCtxMemoryTools({
51610
52430
  ...project,
@@ -51684,6 +52504,13 @@ function bindV2TransformDecision(args) {
51684
52504
  }
51685
52505
 
51686
52506
  // src/hooks/magic-context/auto-embed-session.ts
52507
+ function localPoolingPreflightPending(projectIdentity) {
52508
+ const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
52509
+ if (snapshot?.provider !== "local")
52510
+ return false;
52511
+ const metadata = getCachedLocalEmbeddingPooling(snapshot.model);
52512
+ return !metadata || metadata.status === "unresolved";
52513
+ }
51687
52514
  function embeddingIdentity(projectIdentity) {
51688
52515
  const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
51689
52516
  return JSON.stringify([
@@ -51704,7 +52531,8 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51704
52531
  invalidateAutoEmbedSession(sessionId);
51705
52532
  autoEmbedIdentityBySession.set(sessionId, identity);
51706
52533
  }
51707
- if (autoEmbedAttemptedBySession.has(sessionId) || embedPauseBySession.has(sessionId) || embedRunStateBySession.has(sessionId) || Date.now() < (autoEmbedRetryAfterBySession.get(sessionId) ?? 0))
52534
+ const poolingPreflightPending = localPoolingPreflightPending(deps.projectIdentity);
52535
+ if (embedPauseBySession.has(sessionId) || embedRunStateBySession.has(sessionId) || Date.now() < (autoEmbedRetryAfterBySession.get(sessionId) ?? 0) || autoEmbedAttemptedBySession.has(sessionId) && !poolingPreflightPending)
51708
52536
  return;
51709
52537
  const controller = new AbortController;
51710
52538
  embedRunStateBySession.set(sessionId, controller);
@@ -51714,6 +52542,7 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51714
52542
  let started = false;
51715
52543
  let reason = "error";
51716
52544
  let registeredIdentity = identity;
52545
+ let poolingPendingAfterRegistration = poolingPreflightPending;
51717
52546
  try {
51718
52547
  await new Promise((resolve) => setTimeout(resolve, 0));
51719
52548
  if (controller.signal.aborted)
@@ -51721,6 +52550,7 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51721
52550
  await deps.ensureRegistered();
51722
52551
  if (controller.signal.aborted)
51723
52552
  return;
52553
+ poolingPendingAfterRegistration = localPoolingPreflightPending(deps.projectIdentity);
51724
52554
  markActive();
51725
52555
  registeredIdentity = embeddingIdentity(deps.projectIdentity);
51726
52556
  autoEmbedIdentityBySession.set(sessionId, registeredIdentity);
@@ -51728,7 +52558,9 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51728
52558
  if (controller.signal.aborted || !coverage.enabled)
51729
52559
  return;
51730
52560
  if (coverage.embedded === coverage.total) {
51731
- complete = true;
52561
+ complete = !poolingPendingAfterRegistration;
52562
+ if (!complete)
52563
+ retryDelay = 60000;
51732
52564
  return;
51733
52565
  }
51734
52566
  const model = getProjectEmbeddingSnapshot2(deps.projectIdentity)?.model;
@@ -51737,8 +52569,11 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51737
52569
  const outcome = await embedSessionCompartmentChunks2(deps.db, deps.projectIdentity, sessionId, { signal: controller.signal, automatic: true });
51738
52570
  reason = outcome.status;
51739
52571
  const after = await getAutoEmbeddingSessionCoverage2(deps.db, deps.projectIdentity, sessionId);
51740
- complete = after.enabled && after.embedded === after.total;
51741
- if (!complete && outcome.status !== "busy" && outcome.status !== "aborted") {
52572
+ complete = after.enabled && after.embedded === after.total && !poolingPendingAfterRegistration;
52573
+ if (poolingPendingAfterRegistration) {
52574
+ retryDelay = 60000;
52575
+ reason = "pooling metadata unavailable";
52576
+ } else if (!complete && outcome.status !== "busy" && outcome.status !== "aborted") {
51742
52577
  retryDelay = 60000;
51743
52578
  if (outcome.status === "nothing" || outcome.status === "done")
51744
52579
  reason = "deferred";
@@ -51763,7 +52598,7 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51763
52598
  }
51764
52599
 
51765
52600
  // src/v2/hooks/transform-features.ts
51766
- function createV2TransformFeatureDeps(config, compactionOff, directory) {
52601
+ function createV2TransformFeatureDeps(config, compactionOff, directory, ensureProjectRegistered = ensureProjectRegisteredFromOpenCodeDirectory) {
51767
52602
  return {
51768
52603
  protectedTools: config.protected_tools,
51769
52604
  commitClusterTrigger: config.commit_cluster_trigger,
@@ -51774,7 +52609,7 @@ function createV2TransformFeatureDeps(config, compactionOff, directory) {
51774
52609
  injectionBudgetTokens: config.memory.injection_budget_tokens,
51775
52610
  autoPromote: config.memory.auto_promote
51776
52611
  },
51777
- ensureProjectRegistered: ensureProjectRegisteredFromOpenCodeDirectory,
52612
+ ensureProjectRegistered,
51778
52613
  historyBudgetPercentage: config.history_budget_percentage,
51779
52614
  experimentalUserMemories: userObservationCollectionEnabled2(config.dreamer),
51780
52615
  userObservationsRequested: userObservationsRequested2(config.dreamer),
@@ -51785,7 +52620,7 @@ function createV2TransformFeatureDeps(config, compactionOff, directory) {
51785
52620
  scoreThreshold: config.memory.auto_search?.score_threshold ?? 0.6,
51786
52621
  minPromptChars: config.memory.auto_search?.min_prompt_chars ?? 20,
51787
52622
  directory,
51788
- ensureProjectRegistered: ensureProjectRegisteredFromOpenCodeDirectory,
52623
+ ensureProjectRegistered,
51789
52624
  wordRules: cavemanWordRulesForLanguage(config.language)
51790
52625
  },
51791
52626
  cavemanTextCompression: compactionOff ? undefined : config.caveman_text_compression?.enabled === true ? {
@@ -51795,7 +52630,7 @@ function createV2TransformFeatureDeps(config, compactionOff, directory) {
51795
52630
  } : undefined
51796
52631
  };
51797
52632
  }
51798
- function createV2AutoEmbedSession(deps) {
52633
+ function createV2AutoEmbedSession(deps, ensureProjectRegistered = ensureProjectRegisteredFromOpenCodeDirectory) {
51799
52634
  return (sessionId) => {
51800
52635
  const directory = deps.resolveDirectory(sessionId);
51801
52636
  const projectIdentity = resolveProjectIdentityForSession(directory, deps.allowHomeProject);
@@ -51805,7 +52640,7 @@ function createV2AutoEmbedSession(deps) {
51805
52640
  db: deps.db,
51806
52641
  projectIdentity,
51807
52642
  ensureRegistered: async () => {
51808
- await ensureProjectRegisteredFromOpenCodeDirectory(directory, deps.db);
52643
+ await ensureProjectRegistered(directory, deps.db);
51809
52644
  deps.onDirectoryResolved?.(sessionId, directory);
51810
52645
  }
51811
52646
  }, sessionId);
@@ -51894,6 +52729,26 @@ function persistV2UsageReading(args) {
51894
52729
  // src/v2/hooks/context.ts
51895
52730
  class V2LkgAdmissionReplay extends Error {
51896
52731
  }
52732
+ function applyCheckpointHead(draft, head) {
52733
+ const { checkpoint, submitted } = head;
52734
+ const first = draft.messages.find((message) => message.id === HEAD_IDS[0]);
52735
+ const baseline = first?.content.find((part) => part.type === "text")?.text;
52736
+ if (typeof baseline !== "string")
52737
+ return false;
52738
+ for (const part of checkpoint.content)
52739
+ if (part.type === "text" && typeof part.text === "string") {
52740
+ part.text = part.text.replace(`<summary>
52741
+ ${submitted}
52742
+ </summary>`, `<summary>
52743
+ ${baseline}
52744
+ </summary>`);
52745
+ }
52746
+ const volatile = draft.messages.find((message) => message.id === HEAD_IDS[1]);
52747
+ if (volatile && first)
52748
+ volatile.content.push(...first.content.filter((part) => part.type !== "text"));
52749
+ draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== first));
52750
+ return true;
52751
+ }
51897
52752
  var HIDDEN_SESSION_ERROR_GRACE_MS = 50;
51898
52753
  var STORE_POOL_DISPOSE_WAIT_MS = 1000;
51899
52754
  function isBlockingV2TransformError(error) {
@@ -52119,6 +52974,7 @@ async function registerContext(context) {
52119
52974
  console.warn(`[magic-context] v2 setup disabled by conflicting context hooks: ${conflicts.reasons.join("; ")}`);
52120
52975
  return;
52121
52976
  }
52977
+ const embeddings = createV2EmbeddingScope(resolveProjectIdentityForSession(directory, config.allow_home_project));
52122
52978
  const folds = new FoldOwner(context.storage);
52123
52979
  const nativeFoldMemory = !compactionOff && process.env.MC_OC2_INVISIBLE_FOLD === "1" ? nativeFoldCache(() => storage.require()) : undefined;
52124
52980
  const nativeFoldReplay = nativeFoldMemory ? new NativeFoldReplay(nativeFoldMemory, () => openStoreReader(), context.storage) : undefined;
@@ -52126,6 +52982,7 @@ async function registerContext(context) {
52126
52982
  const queriedModels = new Set;
52127
52983
  const rawLimits = new Map;
52128
52984
  const hiddenSessionErrors = new Map;
52985
+ const hiddenModelActivity = new HiddenModelActivity;
52129
52986
  const liveModels = new Map;
52130
52987
  const promptSurfaceRuntime = createPromptSurfaceRuntime({
52131
52988
  harness: "opencode2",
@@ -52174,7 +53031,7 @@ async function registerContext(context) {
52174
53031
  }) : undefined;
52175
53032
  const hiddenChildHook = new HiddenChildHook;
52176
53033
  await context.session.hook("http.request", (draft) => hiddenChildHook.cacheRequest(draft));
52177
- const tools = db && isDatabasePersisted(db) ? await registerTools(context, db, config, moduleToolBackends?.backends, (id) => hiddenChildHook.owns(id)) : undefined;
53034
+ const tools = db && isDatabasePersisted(db) ? await registerTools(context, db, config, moduleToolBackends?.backends, (id) => hiddenChildHook.owns(id), embeddings.ensureRegistered) : undefined;
52178
53035
  const usage = new Map;
52179
53036
  const generateReplay = new V2GenerateReplay;
52180
53037
  await context.session.hook("http.response", async (draft) => {
@@ -52220,6 +53077,7 @@ async function registerContext(context) {
52220
53077
  await cleanupLegacyOnce(database);
52221
53078
  return createV2HiddenCompletionExecutor({
52222
53079
  ...context.session,
53080
+ watchModelActivity: (sessionID, onOutput) => hiddenModelActivity.watch(sessionID, onOutput),
52223
53081
  get: async (input) => {
52224
53082
  const session = await context.session.get(input);
52225
53083
  const error = hiddenSessionErrors.get(input.sessionID);
@@ -52295,7 +53153,8 @@ async function registerContext(context) {
52295
53153
  liveConfig: () => liveConfigReader.poll().effective,
52296
53154
  executor: withLiveDreamerOutputCap(lateHiddenExecutor, config, () => liveConfigReader.poll().effective),
52297
53155
  openReader: openStoreReader,
52298
- rustModeModuleClient
53156
+ rustModeModuleClient,
53157
+ ensureRegistered: embeddings.ensureRegistered
52299
53158
  });
52300
53159
  };
52301
53160
  if (db && isDatabasePersisted(db))
@@ -52561,6 +53420,7 @@ async function registerContext(context) {
52561
53420
  break;
52562
53421
  const event = value;
52563
53422
  try {
53423
+ hiddenModelActivity.observe(event);
52564
53424
  if (event.type === "provider.updated" || event.type === "model.updated") {
52565
53425
  queriedModels.clear();
52566
53426
  continue;
@@ -52568,6 +53428,10 @@ async function registerContext(context) {
52568
53428
  if (!event.data?.sessionID)
52569
53429
  continue;
52570
53430
  const sessionID = event.data.sessionID;
53431
+ if (db && event.type === "session.revert.committed") {
53432
+ const indexDb = db;
53433
+ withoutSqliteTransformPass2(() => scheduleClearAndReindex(indexDb, sessionID, pagedRead));
53434
+ }
52571
53435
  if (event.type?.startsWith("session.revert.") || event.type === "session.message.content.updated") {
52572
53436
  nativeFoldReplay?.onEvent(event);
52573
53437
  restoredRows.forget(sessionID);
@@ -52595,34 +53459,47 @@ async function registerContext(context) {
52595
53459
  if (event.type === "session.deleted") {
52596
53460
  clearLkgMeasuredRequest(sessionID);
52597
53461
  deletedSessions.add(sessionID);
52598
- transform?.clearSessionLogState(sessionID);
52599
- if (db) {
52600
- markSessionCleanupPending(db, sessionID);
52601
- clearSession(db, sessionID);
53462
+ const failures = [];
53463
+ try {
53464
+ transform?.clearSessionLogState(sessionID);
53465
+ if (db) {
53466
+ markSessionCleanupPending(db, sessionID);
53467
+ clearSession(db, sessionID, false, true);
53468
+ }
53469
+ } catch (error) {
53470
+ failures.push(error);
52602
53471
  }
52603
- rawProviders.get(sessionID)?.();
52604
- rawProviders.delete(sessionID);
52605
- usage.delete(sessionID);
52606
- hiddenSessionErrors.delete(sessionID);
52607
- storageNoticeBySession.delete(sessionID);
52608
- liveModels.delete(sessionID);
52609
- variants.delete(sessionID);
52610
- agents.delete(sessionID);
52611
- channel1.delete(sessionID);
52612
- commitSeenLastPass.delete(sessionID);
52613
- clearEmbedSessionState(sessionID);
52614
- historyRefreshSessions.delete(sessionID);
52615
- clearPendingMaterialization(pendingMaterializationSessions, sessionID);
52616
- lastHeuristicsTurnId.delete(sessionID);
52617
- restoredRows.forget(sessionID);
52618
- if (nativeFoldReplay)
52619
- await nativeFoldReplay.forget(sessionID);
52620
- else
52621
- await forgetNativeFoldProvenance(context.storage, sessionID);
52622
- generateReplay.forget(sessionID);
52623
- systemPromptRefreshSessions.delete(sessionID);
52624
- systemPrompt?.clearSession(sessionID);
52625
- tagger.cleanup(sessionID);
53472
+ try {
53473
+ rawProviders.get(sessionID)?.();
53474
+ rawProviders.delete(sessionID);
53475
+ usage.delete(sessionID);
53476
+ hiddenSessionErrors.delete(sessionID);
53477
+ storageNoticeBySession.delete(sessionID);
53478
+ liveModels.delete(sessionID);
53479
+ variants.delete(sessionID);
53480
+ agents.delete(sessionID);
53481
+ channel1.delete(sessionID);
53482
+ commitSeenLastPass.delete(sessionID);
53483
+ clearEmbedSessionState(sessionID);
53484
+ historyRefreshSessions.delete(sessionID);
53485
+ clearPendingMaterialization(pendingMaterializationSessions, sessionID);
53486
+ lastHeuristicsTurnId.delete(sessionID);
53487
+ restoredRows.forget(sessionID);
53488
+ if (nativeFoldReplay)
53489
+ await nativeFoldReplay.forget(sessionID);
53490
+ else
53491
+ await forgetNativeFoldProvenance(context.storage, sessionID);
53492
+ generateReplay.forget(sessionID);
53493
+ systemPromptRefreshSessions.delete(sessionID);
53494
+ systemPrompt?.clearSession(sessionID);
53495
+ tagger.cleanup(sessionID);
53496
+ } catch (error) {
53497
+ failures.push(error);
53498
+ }
53499
+ if (failures.length === 1)
53500
+ throw failures[0];
53501
+ if (failures.length > 1)
53502
+ throw new AggregateError(failures, "session deletion failed in both the store clear and the in-memory cleanup");
52626
53503
  continue;
52627
53504
  }
52628
53505
  if (event.type !== "session.execution.succeeded")
@@ -52670,7 +53547,7 @@ async function registerContext(context) {
52670
53547
  }) || draft.model.limit?.context || (state.lastObservedModelKey === modelKey ? state.lastUsageContextLimit : undefined);
52671
53548
  return materializeM0({
52672
53549
  ...createM0RenderOptions({
52673
- ...createV2TransformFeatureDeps(config, compactionOff, directory),
53550
+ ...createV2TransformFeatureDeps(config, compactionOff, directory, embeddings.ensureRegistered),
52674
53551
  ...createV2ThresholdDeps(config)
52675
53552
  }, usage.get(draft.sessionID)?.usage ?? { percentage: 0, inputTokens: 0 }, modelKey, contextLimit, resolveProjectIdentityForSession(directory, config.allow_home_project)),
52676
53553
  db,
@@ -52740,6 +53617,42 @@ async function registerContext(context) {
52740
53617
  reader.close();
52741
53618
  }
52742
53619
  });
53620
+ const temporalTimes = config.temporal_awareness === true;
53621
+ const anchorTimesOnly = !temporalTimes && !rustModeModuleClient;
53622
+ const timeIds = (messages) => {
53623
+ if (temporalTimes)
53624
+ return messages.flatMap((message) => message.id ? [message.id] : []);
53625
+ if (!anchorTimesOnly)
53626
+ return [];
53627
+ const ids = [];
53628
+ for (const message of [...messages].reverse()) {
53629
+ if (message.id)
53630
+ ids.push(message.id);
53631
+ if (message.role === "assistant")
53632
+ break;
53633
+ }
53634
+ return ids;
53635
+ };
53636
+ const restoreAfterCheckpoint = (args) => {
53637
+ const { db, reader, draft, cut, boundaryRepair } = args;
53638
+ const moduleBoundaryID = rustModeModuleClient ? getPersistedCompactionMarkerState(db, draft.sessionID)?.boundaryMessageId ?? null : null;
53639
+ const moduleBoundarySeq = moduleBoundaryID ? reader.sequenceForId(draft.sessionID, moduleBoundaryID) : undefined;
53640
+ 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);
53641
+ const servedBoundary = boundaryID ? servedBoundaryRow(reader, draft.sessionID, boundaryID) : null;
53642
+ 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;
53643
+ if (moduleBoundarySeq !== undefined)
53644
+ sessionLog2(draft.sessionID, `v2 restore: from the module boundary ${moduleBoundaryID} to the host checkpoint`);
53645
+ const present = new Set(args.messages.map((message) => message.id));
53646
+ const restored = restoredRows.rows(reader, draft.sessionID, boundary, cut.seq).filter((row) => !present.has(row.id)).flatMap((row) => restoreRow(row, draft.model, hostUsesMediaAssets() ? {
53647
+ asset: hostMediaAsset,
53648
+ 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)}`)
53649
+ } : undefined));
53650
+ return [
53651
+ ...rustModeModuleClient ? [] : coveredInstructionRows(reader, draft.sessionID, Math.min(boundary, cut.seq), draft.model),
53652
+ ...restored,
53653
+ ...args.messages.filter((message) => message !== args.incoming)
53654
+ ];
53655
+ };
52743
53656
  const runManagedContext = async (draft) => {
52744
53657
  rememberHostMedia(draft.messages);
52745
53658
  if (hiddenChildHook.apply(draft))
@@ -52751,12 +53664,18 @@ async function registerContext(context) {
52751
53664
  return;
52752
53665
  const systemAtEntry = structuredClone(draft.system);
52753
53666
  const slotAtEntry = getSlot(draft.sessionID);
53667
+ let checkpointAtEntry;
53668
+ let replayHead;
53669
+ const hostInput = () => checkpointAtEntry === undefined ? undefined : { system: systemAtEntry, checkpoint: checkpointAtEntry };
52754
53670
  const restoreLkgSystem = () => {
52755
53671
  retirePendingSystemPromptDelivery(draft.sessionID);
52756
- if (!lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), systemAtEntry, draft.system)) {
53672
+ const input = hostInput();
53673
+ const restored = input && lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), input, draft.system);
53674
+ if (!restored) {
52757
53675
  sessionLog2(draft.sessionID, "lkg_system_state_mismatch");
52758
53676
  throw new Error("LKG system identity is unavailable or changed");
52759
53677
  }
53678
+ replayHead = restored.head;
52760
53679
  };
52761
53680
  const isMagicContextSynthetic = (id) => isAdmittedSynthetic(context, draft.sessionID, id);
52762
53681
  const newest = draft.messages.at(-1);
@@ -52765,6 +53684,24 @@ async function registerContext(context) {
52765
53684
  return;
52766
53685
  }
52767
53686
  await dropStorageNotices(draft.messages, isMagicContextSynthetic);
53687
+ const hostMessagesAtEntry = [...draft.messages];
53688
+ const passTimes = new Map;
53689
+ const readTimes = (reader, messages) => {
53690
+ const ids = timeIds(messages);
53691
+ const missing = ids.filter((id) => !passTimes.has(id));
53692
+ if (missing.length > 0) {
53693
+ const read = reader.messageTimes(draft.sessionID, missing);
53694
+ for (const id of missing)
53695
+ passTimes.set(id, read.get(id) ?? null);
53696
+ }
53697
+ const times = new Map;
53698
+ for (const id of ids) {
53699
+ const time = passTimes.get(id);
53700
+ if (time)
53701
+ times.set(id, time);
53702
+ }
53703
+ return times;
53704
+ };
52768
53705
  liveModels.set(draft.sessionID, {
52769
53706
  providerID: draft.model.providerID,
52770
53707
  modelID: draft.model.id
@@ -52776,8 +53713,9 @@ async function registerContext(context) {
52776
53713
  applyV2PromptSurfaceTools(draft, promptSurfaceRuntime, config.prompt_surface, isSmartNoteSurfaceAvailable(config));
52777
53714
  const admissionDb = db ?? storage.current();
52778
53715
  const replayFits = (messages) => {
52779
- const system = structuredClone(draft.system);
52780
- if (!admissionDb || !draft.tools || !lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), draft.system, system))
53716
+ const system = [];
53717
+ const input = hostInput();
53718
+ if (!admissionDb || !draft.tools || !input || !lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), input, system))
52781
53719
  return false;
52782
53720
  const limit = lkgReplayLimit({
52783
53721
  db: admissionDb,
@@ -52812,14 +53750,75 @@ async function registerContext(context) {
52812
53750
  })
52813
53751
  }).fit === "under";
52814
53752
  };
53753
+ const buildReplayInput = async () => {
53754
+ let messages = [...hostMessagesAtEntry];
53755
+ const admitted = new Set;
53756
+ let times;
53757
+ try {
53758
+ const reader = openStoreReader();
53759
+ try {
53760
+ const cut = reader.latestCompaction(draft.sessionID);
53761
+ const localCut = cut && isLocalCheckpoint(cut) ? cut : undefined;
53762
+ const incoming = localCut && messages.find((message) => message.id === localCut.id);
53763
+ if (localCut && !incoming || cut && nativeFoldReplay)
53764
+ return;
53765
+ checkpointAtEntry = incoming || null;
53766
+ const modeDb = db ?? storage.current();
53767
+ const subagent = modeDb ? storedSubagentMode(modeDb, draft.sessionID) : undefined;
53768
+ if (subagent === undefined)
53769
+ return;
53770
+ if (subagent)
53771
+ removePrimaryOnlyTools(draft.tools);
53772
+ if (!rustModeModuleClient) {
53773
+ const candidates = syntheticCandidates(context, draft.sessionID, reader.syntheticMessageIDs(draft.sessionID));
53774
+ for (const message of messages)
53775
+ if (message.id && candidates.has(message.id) && await isAdmittedSynthetic(context, draft.sessionID, message.id))
53776
+ admitted.add(message.id);
53777
+ const replayDb = db ?? storage.current();
53778
+ if (localCut && incoming && replayDb)
53779
+ messages = restoreAfterCheckpoint({
53780
+ db: replayDb,
53781
+ reader,
53782
+ draft,
53783
+ messages,
53784
+ cut: localCut,
53785
+ incoming,
53786
+ boundaryRepair: undefined
53787
+ });
53788
+ else if (localCut)
53789
+ return;
53790
+ times = readTimes(reader, messages);
53791
+ }
53792
+ } finally {
53793
+ reader.close();
53794
+ }
53795
+ } catch (error) {
53796
+ sessionLog2(draft.sessionID, "lkg replay input unavailable", error);
53797
+ return;
53798
+ }
53799
+ const replayDraft = { ...draft, messages };
53800
+ return {
53801
+ draft: replayDraft,
53802
+ mapped: adaptPayload(replayDraft, admitted, times, anchorTimesOnly)
53803
+ };
53804
+ };
53805
+ const adoptReplay = (replayed) => {
53806
+ if (replayed !== draft)
53807
+ draft.messages.splice(0, draft.messages.length, ...replayed.messages);
53808
+ if (replayHead)
53809
+ applyCheckpointHead(draft, replayHead);
53810
+ };
52815
53811
  let postFold = false;
52816
53812
  try {
52817
53813
  if (!compactionOff && admissionDb)
52818
53814
  await withAsyncPrivilegedWriter2(admissionDb, () => {
52819
53815
  return;
52820
53816
  }, {
52821
- beforeRetry: (error) => {
52822
- const mapped = adaptPayload(draft);
53817
+ beforeRetry: async (error) => {
53818
+ const input = await buildReplayInput();
53819
+ if (!input)
53820
+ return;
53821
+ const { mapped } = input;
52823
53822
  if (tryMessagesTransformLkgReplay({
52824
53823
  output: mapped,
52825
53824
  sessionId: draft.sessionID,
@@ -52830,6 +53829,7 @@ async function registerContext(context) {
52830
53829
  onLkgReplay: restoreLkgSystem
52831
53830
  })) {
52832
53831
  mapped.commit();
53832
+ adoptReplay(input.draft);
52833
53833
  throw new V2LkgAdmissionReplay;
52834
53834
  }
52835
53835
  }
@@ -52919,7 +53919,7 @@ async function registerContext(context) {
52919
53919
  await cacheV2SessionDirectory(context.session, draft.sessionID, sessionDirectories);
52920
53920
  prepareHistorySession(draft.sessionID);
52921
53921
  transform ??= createTransform({
52922
- ...createV2TransformFeatureDeps(config, compactionOff, directory),
53922
+ ...createV2TransformFeatureDeps(config, compactionOff, directory, embeddings.ensureRegistered),
52923
53923
  cacheTtlConfig: config.cache_ttl,
52924
53924
  cacheTtlConfigured: config.cacheTtlConfigured,
52925
53925
  sampleCacheTtlConfig: () => liveConfigReader.poll().effective,
@@ -52929,7 +53929,7 @@ async function registerContext(context) {
52929
53929
  contextUsageMap: usage,
52930
53930
  compactionOff,
52931
53931
  storeGeneration: "v2",
52932
- normalizeRestoredAssistantText: stripCopiedTagNotation,
53932
+ normalizeRestoredAssistantText: (text, providerID) => stripCopiedTagNotation(text, providerID === "anthropic"),
52933
53933
  refreshSourceContents: (sessionID) => nativeFoldReplay?.needsHeadRebuild(sessionID) ?? false,
52934
53934
  hostCleanupCompactionMarkers: () => ({
52935
53935
  verified: true,
@@ -52966,7 +53966,7 @@ async function registerContext(context) {
52966
53966
  resolveDirectory: (sessionID) => sessionDirectories.get(sessionID) ?? directory,
52967
53967
  allowHomeProject: config.allow_home_project,
52968
53968
  recompProgressBySession: new Map
52969
- }),
53969
+ }, embeddings.ensureRegistered),
52970
53970
  hiddenCompletionExecutor,
52971
53971
  historianRunnable: !compactionOff && hiddenCompletionExecutor !== undefined && config.historian?.disable !== true,
52972
53972
  historianModel: historianModels.primary,
@@ -53024,6 +54024,7 @@ async function registerContext(context) {
53024
54024
  postFold = cut !== undefined;
53025
54025
  if (localCut && !incoming)
53026
54026
  throw new Error("The host checkpoint disappeared from the context draft");
54027
+ checkpointAtEntry = incoming || null;
53027
54028
  let nativeRestored;
53028
54029
  if (cut && nativeFoldReplay && await nativeFoldReplay.admits(draft.sessionID, cut, reader)) {
53029
54030
  try {
@@ -53065,22 +54066,17 @@ async function registerContext(context) {
53065
54066
  checkpoint = structuredClone(identity.rendered ?? incoming);
53066
54067
  submitted = identity.rendered ? identity.renderedSummary ?? identity.submitted : cut.data.summary ?? "";
53067
54068
  }
53068
- const moduleBoundaryID = rustModeModuleClient ? getPersistedCompactionMarkerState(db, draft.sessionID)?.boundaryMessageId ?? null : null;
53069
- const moduleBoundarySeq = moduleBoundaryID ? reader.sequenceForId(draft.sessionID, moduleBoundaryID) : undefined;
53070
- 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);
53071
- const servedBoundary = boundaryID ? servedBoundaryRow(reader, draft.sessionID, boundaryID) : null;
53072
- 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;
53073
- if (moduleBoundarySeq !== undefined)
53074
- sessionLog2(draft.sessionID, `v2 restore: from the module boundary ${moduleBoundaryID} to the host checkpoint`);
53075
- const present = new Set(draft.messages.map((message) => message.id));
53076
- const restored = restoredRows.rows(reader, draft.sessionID, boundary, cut.seq).filter((row) => !present.has(row.id)).flatMap((row) => restoreRow(row, draft.model, hostUsesMediaAssets() ? {
53077
- asset: hostMediaAsset,
53078
- 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)}`)
53079
- } : undefined));
53080
- 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));
53081
- }
53082
- if (config.temporal_awareness === true)
53083
- messageTimes = reader.messageTimes(draft.sessionID, draft.messages.flatMap((message) => message.id ? [message.id] : []));
54069
+ draft.messages.splice(0, draft.messages.length, ...restoreAfterCheckpoint({
54070
+ db,
54071
+ reader,
54072
+ draft,
54073
+ messages: draft.messages,
54074
+ cut: localCut,
54075
+ incoming,
54076
+ boundaryRepair
54077
+ }));
54078
+ }
54079
+ messageTimes = readTimes(reader, draft.messages);
53084
54080
  } finally {
53085
54081
  reader.close();
53086
54082
  }
@@ -53097,7 +54093,7 @@ async function registerContext(context) {
53097
54093
  nativeFoldReplay.invalidate(draft.sessionID, true);
53098
54094
  }
53099
54095
  }
53100
- const mapped = adaptPayload(draft, admitted, messageTimes);
54096
+ const mapped = adaptPayload(draft, admitted, messageTimes, anchorTimesOnly);
53101
54097
  bindSystemDateRequestIdentity(mapped, draft);
53102
54098
  await createMessagesTransformHandler({
53103
54099
  magicContext: { "experimental.chat.messages.transform": transform },
@@ -53114,24 +54110,9 @@ async function registerContext(context) {
53114
54110
  if (db) {
53115
54111
  await deliverPendingChannel2(context, db, draft.sessionID, channel1.get(draft.sessionID));
53116
54112
  }
53117
- if (checkpoint && submitted !== undefined) {
53118
- const head = draft.messages.find((message) => message.id === HEAD_IDS[0]);
53119
- const baseline = head?.content.find((part) => part.type === "text")?.text;
53120
- if (typeof baseline === "string") {
53121
- for (const part of checkpoint.content)
53122
- if (part.type === "text" && typeof part.text === "string") {
53123
- part.text = part.text.replace(`<summary>
53124
- ${submitted}
53125
- </summary>`, `<summary>
53126
- ${baseline}
53127
- </summary>`);
53128
- }
53129
- const volatile = draft.messages.find((message) => message.id === HEAD_IDS[1]);
53130
- if (volatile && head)
53131
- volatile.content.push(...head.content.filter((part) => part.type !== "text"));
53132
- draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== head));
53133
- }
53134
- }
54113
+ const head = replayHead !== undefined ? replayHead : checkpoint && submitted !== undefined ? { checkpoint, submitted } : null;
54114
+ const servedHead = head && structuredClone(head);
54115
+ const headApplied = head ? applyCheckpointHead(draft, head) : false;
53135
54116
  if (nativeMessages && !checkpoint) {
53136
54117
  try {
53137
54118
  await nativeFoldReplay?.capture(draft, nativeMessages);
@@ -53142,7 +54123,7 @@ ${baseline}
53142
54123
  }
53143
54124
  const capturedSlot = getSlot(draft.sessionID);
53144
54125
  if (capturedSlot && (!slotAtEntry || capturedSlot.capturedAt !== slotAtEntry.capturedAt || capturedSlot.captureSequence !== slotAtEntry.captureSequence || capturedSlot.jsonPrefix !== slotAtEntry.jsonPrefix)) {
53145
- lkgSystems.capture(draft.sessionID, capturedSlot, systemAtEntry, draft.system);
54126
+ lkgSystems.capture(draft.sessionID, capturedSlot, { system: systemAtEntry, checkpoint: checkpointAtEntry ?? null }, draft.system, headApplied ? servedHead : null);
53146
54127
  }
53147
54128
  } catch (error) {
53148
54129
  if (error instanceof V2LkgAdmissionReplay)
@@ -53151,8 +54132,11 @@ ${baseline}
53151
54132
  throw error;
53152
54133
  if (!compactionOff && (isTransientSqliteError2(error) || error instanceof StorageBusyRefusalError)) {
53153
54134
  if (isTransientSqliteError2(error)) {
53154
- const mapped = adaptPayload(draft);
54135
+ const input = await buildReplayInput();
53155
54136
  try {
54137
+ if (!input)
54138
+ throw new StorageBusyRefusalError(error, "v2-context");
54139
+ const { mapped } = input;
53156
54140
  await createMessagesTransformHandler({
53157
54141
  replayFits,
53158
54142
  onLkgReplay: restoreLkgSystem,
@@ -53164,6 +54148,7 @@ ${baseline}
53164
54148
  }
53165
54149
  })({}, mapped);
53166
54150
  mapped.commit();
54151
+ adoptReplay(input.draft);
53167
54152
  return;
53168
54153
  } catch (replayError) {
53169
54154
  if (!(replayError instanceof StorageBusyRefusalError))
@@ -53245,7 +54230,8 @@ ${baseline}
53245
54230
  return null;
53246
54231
  }
53247
54232
  },
53248
- storageDir
54233
+ storageDir,
54234
+ getDebugMemoryHolders: () => ({ generateReplay: generateReplay.stats() })
53249
54235
  });
53250
54236
  rpcServer.handle("dream", async (params) => {
53251
54237
  const sessionId = String(params.sessionId ?? "");
@@ -53330,6 +54316,7 @@ ${baseline}
53330
54316
  deletedSessions.clear();
53331
54317
  await dreamTrigger?.dispose();
53332
54318
  await maintenanceTimer?.dispose();
54319
+ await embeddings.dispose();
53333
54320
  for (const release of rawProviders.values())
53334
54321
  release();
53335
54322
  rawProviders.clear();