@cortexkit/opencode-magic-context 0.49.19 → 0.49.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (271) hide show
  1. package/dist/auto-search-worker.js +48 -9
  2. package/dist/chunk-embedding-write-worker.js +30 -23
  3. package/dist/{compaction-marker-candidates-n4krhat4.js → compaction-marker-candidates-b2q30cft.js} +3 -3
  4. package/dist/compaction-marker-candidates-worker.js +2 -2
  5. package/dist/compartment-chunk-embedding-va090as0.js +65 -0
  6. package/dist/config/schema/magic-context.d.ts +6 -6
  7. package/dist/{conflict-warning-hook-4pmz879v.js → conflict-warning-hook-frp3z2wk.js} +9 -8
  8. package/dist/{context-j31m2dv7.js → context-mkece1db.js} +455 -134
  9. package/dist/{derive-budgets-zn7yzd2d.js → derive-budgets-pqybnx09.js} +2 -2
  10. package/dist/embedding-backfill-gy3p78py.js +25 -0
  11. package/dist/embedding-worker-process.js +2 -2
  12. package/dist/embedding-worker.js +5 -5
  13. package/dist/features/magic-context/chunk-embedding-writer.d.ts.map +1 -1
  14. package/dist/features/magic-context/compartment-chunk-embedding.d.ts +44 -1
  15. package/dist/features/magic-context/compartment-chunk-embedding.d.ts.map +1 -1
  16. package/dist/features/magic-context/dreamer/hidden-single-shot.d.ts.map +1 -1
  17. package/dist/features/magic-context/dreamer/task-config.d.ts.map +1 -1
  18. package/dist/features/magic-context/dreamer/task-scheduler.d.ts +2 -0
  19. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  20. package/dist/features/magic-context/memory/embedding-identity.d.ts.map +1 -1
  21. package/dist/features/magic-context/memory/embedding-local.d.ts +1 -0
  22. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  23. package/dist/features/magic-context/memory/local-embedding-pooling.d.ts +22 -0
  24. package/dist/features/magic-context/memory/local-embedding-pooling.d.ts.map +1 -0
  25. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  26. package/dist/features/magic-context/message-index.d.ts +2 -0
  27. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  28. package/dist/features/magic-context/mural/compress-cues.d.ts.map +1 -1
  29. package/dist/features/magic-context/project-embedding-registry.d.ts.map +1 -1
  30. package/dist/features/magic-context/search.d.ts +27 -0
  31. package/dist/features/magic-context/search.d.ts.map +1 -1
  32. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  33. package/dist/features/magic-context/storage-meta-persisted.d.ts +1 -0
  34. package/dist/features/magic-context/storage-meta-persisted.d.ts.map +1 -1
  35. package/dist/features/magic-context/subagent-token-capture.d.ts +20 -0
  36. package/dist/features/magic-context/subagent-token-capture.d.ts.map +1 -1
  37. package/dist/features/magic-context/user-memory/review-user-memories.d.ts.map +1 -1
  38. package/dist/{history-owner-xp3pngv7.js → history-owner-36wp3mkb.js} +2 -2
  39. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  40. package/dist/hooks/magic-context/auto-embed-session.d.ts.map +1 -1
  41. package/dist/hooks/magic-context/auto-search-hint.d.ts +7 -1
  42. package/dist/hooks/magic-context/auto-search-hint.d.ts.map +1 -1
  43. package/dist/hooks/magic-context/auto-search-runner.d.ts.map +1 -1
  44. package/dist/hooks/magic-context/auto-search-worker-client.d.ts +33 -6
  45. package/dist/hooks/magic-context/auto-search-worker-client.d.ts.map +1 -1
  46. package/dist/hooks/magic-context/cache-busting-signals.d.ts +5 -2
  47. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  48. package/dist/hooks/magic-context/channel2-delivery.d.ts.map +1 -1
  49. package/dist/hooks/magic-context/compartment-runner-historian.d.ts.map +1 -1
  50. package/dist/hooks/magic-context/compartment-runner-types.d.ts +5 -0
  51. package/dist/hooks/magic-context/compartment-runner-types.d.ts.map +1 -1
  52. package/dist/hooks/magic-context/compartment-trigger.d.ts +1 -1
  53. package/dist/hooks/magic-context/compartment-trigger.d.ts.map +1 -1
  54. package/dist/hooks/magic-context/diagnostic-log-state.d.ts +4 -0
  55. package/dist/hooks/magic-context/diagnostic-log-state.d.ts.map +1 -0
  56. package/dist/hooks/magic-context/execute-reclaim.d.ts +35 -0
  57. package/dist/hooks/magic-context/execute-reclaim.d.ts.map +1 -0
  58. package/dist/hooks/magic-context/hook-handlers.d.ts.map +1 -1
  59. package/dist/hooks/magic-context/hook.d.ts +1 -3
  60. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  61. package/dist/hooks/magic-context/latest-assistant-turn.d.ts +8 -0
  62. package/dist/hooks/magic-context/latest-assistant-turn.d.ts.map +1 -1
  63. package/dist/hooks/magic-context/lkg-recovery-fence.d.ts +5 -0
  64. package/dist/hooks/magic-context/lkg-recovery-fence.d.ts.map +1 -1
  65. package/dist/hooks/magic-context/nudge-evaluation-log.d.ts +3 -0
  66. package/dist/hooks/magic-context/nudge-evaluation-log.d.ts.map +1 -0
  67. package/dist/hooks/magic-context/pending-drop-eligibility.d.ts.map +1 -1
  68. package/dist/hooks/magic-context/protected-tail-boundary.d.ts +4 -0
  69. package/dist/hooks/magic-context/protected-tail-boundary.d.ts.map +1 -1
  70. package/dist/hooks/magic-context/raw-ordinal-warmup.d.ts.map +1 -1
  71. package/dist/hooks/magic-context/system-date-refresh.d.ts +5 -5
  72. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  73. package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts +10 -0
  74. package/dist/hooks/magic-context/system-prompt-sticky-date.d.ts.map +1 -0
  75. package/dist/hooks/magic-context/tag-messages.d.ts +2 -0
  76. package/dist/hooks/magic-context/tag-messages.d.ts.map +1 -1
  77. package/dist/hooks/magic-context/transform-compartment-phase.d.ts.map +1 -1
  78. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +21 -6
  79. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  80. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  81. package/dist/{index-bjcnntmz.js → index-0wthn7fp.js} +468 -18
  82. package/dist/{index-kq82mtg0.js → index-11zf2wwc.js} +3 -3
  83. package/dist/{index-b5vqckbw.js → index-153r2q6z.js} +314 -127
  84. package/dist/{index-3h4dp9wb.js → index-1pefp8ar.js} +5 -5
  85. package/dist/{index-beht37jy.js → index-1zx2pa5d.js} +1 -1
  86. package/dist/{index-ze7mvk54.js → index-2yhtnfcf.js} +75 -57
  87. package/dist/{index-cf74k5ak.js → index-305y133n.js} +4 -4
  88. package/dist/{index-s734jcsr.js → index-35qc6606.js} +9 -3
  89. package/dist/{index-se4m2g6w.js → index-48stjd56.js} +105 -19
  90. package/dist/{index-4911rn0b.js → index-4n7w9rad.js} +6 -6
  91. package/dist/{index-kee4kn5j.js → index-4pnsgvfk.js} +1 -1
  92. package/dist/{v2/server-8cd2j99z.js → index-5kym00ag.js} +32 -13
  93. package/dist/{index-4s3t0nd0.js → index-616rsjrv.js} +2 -2
  94. package/dist/{index-jhghdnsm.js → index-67nyj0gy.js} +485 -202
  95. package/dist/{index-6x57ar45.js → index-adk2z5d8.js} +3 -3
  96. package/dist/{index-c5pytzne.js → index-b88dwwrh.js} +1 -1
  97. package/dist/{index-rr2bb45z.js → index-c4b76d4t.js} +2 -2
  98. package/dist/{index-nj7yykkx.js → index-c7phnbvk.js} +1 -1
  99. package/dist/index-cpjk5jd2.js +82 -0
  100. package/dist/{index-edmpdxcw.js → index-d6rp4dxh.js} +5 -5
  101. package/dist/{index-dxmq29t1.js → index-dc8hy95c.js} +69 -17
  102. package/dist/{index-j75v2476.js → index-h7tgn49j.js} +12 -15
  103. package/dist/{index-ke416mdc.js → index-j76ah6d7.js} +2 -2
  104. package/dist/{index-c1p88z1y.js → index-jfh3cktr.js} +4 -4
  105. package/dist/{index-a6mc0v4d.js → index-jmycsey7.js} +3 -3
  106. package/dist/{index-24fezq97.js → index-jr5na10t.js} +4 -4
  107. package/dist/{index-s74zqahq.js → index-kc9pn495.js} +4 -4
  108. package/dist/{index-p5y3k4g7.js → index-nda0zgna.js} +2 -1
  109. package/dist/{index-jn12fvvh.js → index-neb2jaed.js} +3 -3
  110. package/dist/{index-63k48rv9.js → index-pnjwa6qa.js} +5 -5
  111. package/dist/{index-jrr131e0.js → index-rmd0069m.js} +11 -11
  112. package/dist/{index-y9f76s3f.js → index-rrv26qjz.js} +1 -1
  113. package/dist/{index-v10f1rjv.js → index-spwjbkc7.js} +1 -1
  114. package/dist/{index-k29z4aqh.js → index-t5pck3ss.js} +1 -1
  115. package/dist/{index-3esx8tkf.js → index-t7hx3qcb.js} +318 -104
  116. package/dist/{index-rpxdjkm0.js → index-v7r4td4c.js} +306 -59
  117. package/dist/{index-2vxtcb95.js → index-vkc1ca9p.js} +2 -2
  118. package/dist/{index-9zcsy3hh.js → index-x4k3f4mf.js} +17 -9
  119. package/dist/{index-bp5083x2.js → index-x9k3mqrf.js} +1 -1
  120. package/dist/{index-n37sebck.js → index-y4a3nhtk.js} +1 -1
  121. package/dist/index.js +52 -49
  122. package/dist/{logger-jm3sqqzr.js → logger-94kew5wm.js} +1 -1
  123. package/dist/{message-fts-rowid-map-17s0dfn4.js → message-fts-rowid-map-22tevnnj.js} +6 -5
  124. package/dist/{message-index-gtpqnj8w.js → message-index-5qxcz6h7.js} +16 -15
  125. package/dist/{message-index-bounded-zyc8h32y.js → message-index-bounded-n0m0t7tv.js} +16 -15
  126. package/dist/{message-time-backfill-73mmm76q.js → message-time-backfill-0myx7fz3.js} +3 -3
  127. package/dist/migration-worker.js +13 -12
  128. package/dist/{model-resolution-nx97z3x7.js → model-resolution-280gmqvd.js} +1 -1
  129. package/dist/plugin/embedding-bootstrap.d.ts +3 -1
  130. package/dist/plugin/embedding-bootstrap.d.ts.map +1 -1
  131. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  132. package/dist/plugin/rpc-handlers.d.ts +8 -0
  133. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  134. package/dist/plugin/subagent-tool-policy.d.ts +9 -0
  135. package/dist/plugin/subagent-tool-policy.d.ts.map +1 -1
  136. package/dist/{project-embedding-registry-z74mhqkf.js → project-embedding-registry-s2pqgec9.js} +13 -12
  137. package/dist/raw-ordinal-warmup-worker.js +136 -101
  138. package/dist/{read-session-chunk-jjb48bt9.js → read-session-chunk-0a8vdyqp.js} +11 -10
  139. package/dist/{read-session-raw-rsc8c7qy.js → read-session-raw-y5cszf0b.js} +4 -3
  140. package/dist/recomp-orchestrator-61vyha9j.js +62 -0
  141. package/dist/{safe-notification-target-1szv1k5k.js → safe-notification-target-mkr9yzvr.js} +2 -2
  142. package/dist/{search-archive-6vm0e2f5.js → search-archive-8q9s49p5.js} +12 -11
  143. package/dist/{search-xsqk1bj4.js → search-v1y9ejws.js} +25 -24
  144. package/dist/{send-session-notification-6ve0e8p4.js → send-session-notification-0k6qzydk.js} +7 -6
  145. package/dist/shared/logger.d.ts.map +1 -1
  146. package/dist/shared/model-resolution.d.ts +2 -0
  147. package/dist/shared/model-resolution.d.ts.map +1 -1
  148. package/dist/shared/prompt-async-transport.d.ts +3 -0
  149. package/dist/shared/prompt-async-transport.d.ts.map +1 -1
  150. package/dist/shared/rpc-types.d.ts +7 -0
  151. package/dist/shared/rpc-types.d.ts.map +1 -1
  152. package/dist/shared/sqlite.d.ts +1 -1
  153. package/dist/shared/sqlite.d.ts.map +1 -1
  154. package/dist/shared/subagent-runner.d.ts +2 -0
  155. package/dist/shared/subagent-runner.d.ts.map +1 -1
  156. package/dist/shared/worker-shutdown.d.ts +68 -0
  157. package/dist/shared/worker-shutdown.d.ts.map +1 -0
  158. package/dist/shared/worker-shutdown.fixture.d.ts +2 -0
  159. package/dist/shared/worker-shutdown.fixture.d.ts.map +1 -0
  160. package/dist/{sqlite-zf72c52d.js → sqlite-1rpvw2rj.js} +1 -1
  161. package/dist/{storage-memory-y3qmy00r.js → storage-memory-nm7v82mj.js} +2 -2
  162. package/dist/{storage-tags-r7k9tjcv.js → storage-tags-r6nk29n4.js} +5 -5
  163. package/dist/{task-config-x3qmayd2.js → task-config-t6bpyka7.js} +2 -2
  164. package/dist/tools/ctx-search/tools.d.ts.map +1 -1
  165. package/dist/{transform-postprocess-phase-jj99r7z2.js → transform-postprocess-phase-vtrgb7m6.js} +34 -31
  166. package/dist/v2/auto-search-worker.js +48 -9
  167. package/dist/v2/chunk-embedding-write-worker.js +30 -23
  168. package/dist/v2/{compaction-marker-candidates-ebx3388k.js → compaction-marker-candidates-cfab70cs.js} +3 -3
  169. package/dist/v2/compaction-marker-candidates-worker.js +2 -2
  170. package/dist/v2/compartment-chunk-embedding-nbdqx1td.js +64 -0
  171. package/dist/v2/{context-y5yamxak.js → context-cc33tv2z.js} +1189 -386
  172. package/dist/v2/{derive-budgets-2zh4gm2c.js → derive-budgets-knf763tt.js} +3 -3
  173. package/dist/v2/embedding-backfill-yxv2h5mc.js +24 -0
  174. package/dist/v2/embedding-worker-process.js +2 -2
  175. package/dist/v2/embedding-worker.js +5 -5
  176. package/dist/v2/hidden-child-record.d.ts +2 -0
  177. package/dist/v2/hidden-child-record.d.ts.map +1 -1
  178. package/dist/v2/hidden-completion.d.ts +2 -0
  179. package/dist/v2/hidden-completion.d.ts.map +1 -1
  180. package/dist/v2/hidden-model-activity.d.ts +7 -0
  181. package/dist/v2/hidden-model-activity.d.ts.map +1 -0
  182. package/dist/v2/{history-owner-42e16w0n.js → history-owner-ad0crnrn.js} +2 -2
  183. package/dist/v2/hooks/context.d.ts.map +1 -1
  184. package/dist/v2/hooks/generate.d.ts +36 -1
  185. package/dist/v2/hooks/generate.d.ts.map +1 -1
  186. package/dist/v2/hooks/lkg-system.d.ts +35 -4
  187. package/dist/v2/hooks/lkg-system.d.ts.map +1 -1
  188. package/dist/v2/hooks/payload.d.ts +16 -1
  189. package/dist/v2/hooks/payload.d.ts.map +1 -1
  190. package/dist/v2/{logger-7qt02bnb.js → logger-p34mjtja.js} +1 -1
  191. package/dist/v2/{message-fts-rowid-map-wfx67gfd.js → message-fts-rowid-map-dg12wymk.js} +6 -5
  192. package/dist/v2/{message-index-bounded-spd8r7pj.js → message-index-bounded-f4e01xk0.js} +16 -15
  193. package/dist/v2/{message-index-8vz2pq76.js → message-index-ydzrp6y6.js} +16 -15
  194. package/dist/v2/{message-time-backfill-04t0km1z.js → message-time-backfill-ddh8n9gy.js} +3 -3
  195. package/dist/v2/migration-worker.js +13 -12
  196. package/dist/v2/{model-resolution-nx97z3x7.js → model-resolution-280gmqvd.js} +1 -1
  197. package/dist/v2/{project-embedding-registry-gnkj56xp.js → project-embedding-registry-deza9ksw.js} +13 -12
  198. package/dist/v2/raw-ordinal-warmup-worker.js +136 -101
  199. package/dist/v2/{read-session-chunk-cwkxrmns.js → read-session-chunk-8cxfagky.js} +11 -10
  200. package/dist/v2/{read-session-raw-yaegtjzh.js → read-session-raw-1nrrecvx.js} +4 -3
  201. package/dist/v2/recomp-orchestrator-47m4hv5g.js +61 -0
  202. package/dist/v2/{safe-notification-target-qg7n2s77.js → safe-notification-target-khnzg57c.js} +2 -2
  203. package/dist/v2/{search-archive-wve3tq1k.js → search-archive-e80cvc09.js} +12 -11
  204. package/dist/v2/{search-hwg7jfbj.js → search-fjz746zr.js} +25 -24
  205. package/dist/v2/{send-session-notification-3pxn658x.js → send-session-notification-nwvrv34d.js} +7 -6
  206. package/dist/v2/{server-8by8qfec.js → server-0epqaxhd.js} +75 -57
  207. package/dist/v2/{server-pwv4ezb0.js → server-168pb207.js} +1 -1
  208. package/dist/v2/{server-h0410h0v.js → server-1bw1wcbp.js} +1 -1
  209. package/dist/v2/{server-beht37jy.js → server-1zx2pa5d.js} +1 -1
  210. package/dist/v2/{server-a9xqj88f.js → server-230fnbws.js} +4 -4
  211. package/dist/v2/{server-tbe1femw.js → server-29qp8nz4.js} +1 -1
  212. package/dist/v2/{server-tgnbmwah.js → server-3mz2qh5a.js} +1 -1
  213. package/dist/v2/{server-hy3d3vsx.js → server-4nw4fqhr.js} +2 -2
  214. package/dist/v2/{server-45q69hkq.js → server-4sxjs6hn.js} +5 -5
  215. package/dist/v2/{server-34kwfsr4.js → server-53eh1r8r.js} +2 -2
  216. package/dist/v2/{server-xj136kt8.js → server-55rgxfrw.js} +9 -3
  217. package/dist/v2/{server-nj659894.js → server-5arr9ecn.js} +2 -2
  218. package/dist/{index-8cd2j99z.js → v2/server-5kym00ag.js} +32 -13
  219. package/dist/v2/{server-2ar62dyx.js → server-63fqdghs.js} +106 -20
  220. package/dist/v2/{server-f2xf5gcb.js → server-6495nmn9.js} +12 -15
  221. package/dist/v2/{server-qd11g795.js → server-92g7d776.js} +2 -1
  222. package/dist/v2/{server-xq7dfjke.js → server-9x0kmta4.js} +5 -5
  223. package/dist/v2/{server-27gq4mfz.js → server-a3dwxfgd.js} +4 -4
  224. package/dist/v2/{server-6tmj0s7j.js → server-af2pght7.js} +3 -3
  225. package/dist/v2/{server-1wy7b9de.js → server-br1x0tev.js} +3 -3
  226. package/dist/v2/{server-n1prf1g6.js → server-brj8j2gk.js} +2 -2
  227. package/dist/v2/{server-6vdzn1td.js → server-c7dxxsj7.js} +308 -61
  228. package/dist/v2/server-cpjk5jd2.js +82 -0
  229. package/dist/v2/{server-g3qma5c0.js → server-dj7tz4ph.js} +2 -2
  230. package/dist/v2/{server-9hx7g5jp.js → server-ej96a39v.js} +17 -9
  231. package/dist/v2/{server-6pmqg9m4.js → server-gyy4k6mf.js} +1 -1
  232. package/dist/v2/{server-bmymkx73.js → server-hqzyq8n4.js} +11 -11
  233. package/dist/v2/{server-h1v0pyxb.js → server-j4jnp9b5.js} +468 -18
  234. package/dist/v2/{server-da07v4xp.js → server-k3t06fxr.js} +1 -1
  235. package/dist/v2/{server-gsxjv2q2.js → server-m91f9m5s.js} +69 -17
  236. package/dist/v2/{server-rmygf5pn.js → server-ne8arh8t.js} +2 -2
  237. package/dist/v2/{server-hm38q7r0.js → server-vn2nwcv6.js} +5 -5
  238. package/dist/v2/{server-46neh5fa.js → server-wyawsa88.js} +314 -127
  239. package/dist/v2/{server-zzkj2fch.js → server-xsryvyf6.js} +4 -4
  240. package/dist/v2/{server-n37sebck.js → server-y4a3nhtk.js} +1 -1
  241. package/dist/v2/{server-d04vrx0j.js → server-ygtykank.js} +2 -2
  242. package/dist/v2/server.js +6 -6
  243. package/dist/v2/{sqlite-zf72c52d.js → sqlite-1rpvw2rj.js} +1 -1
  244. package/dist/v2/{storage-memory-y3qmy00r.js → storage-memory-nm7v82mj.js} +2 -2
  245. package/dist/v2/{storage-tags-3wdb8zph.js → storage-tags-ss08kj5r.js} +5 -5
  246. package/dist/v2/store-reader.d.ts +8 -0
  247. package/dist/v2/store-reader.d.ts.map +1 -1
  248. package/dist/v2/{task-config-nvz8mapa.js → task-config-7md27rx8.js} +2 -2
  249. package/dist/v2/{wrapup-orchestrator-embdz8gj.js → wrapup-orchestrator-639whfhq.js} +32 -31
  250. package/dist/wrapup-orchestrator-mnvt2g8m.js +49 -0
  251. package/package.json +1 -1
  252. package/src/config/index.test.ts +28 -6
  253. package/src/shared/logger.test.ts +42 -1
  254. package/src/shared/logger.ts +11 -13
  255. package/src/shared/model-resolution.test.ts +67 -12
  256. package/src/shared/model-resolution.ts +43 -16
  257. package/src/shared/model-suggestion-retry.ts +1 -1
  258. package/src/shared/prompt-async-transport.ts +47 -3
  259. package/src/shared/rpc-types.ts +7 -0
  260. package/src/shared/sqlite-busy-budget-review.test.ts +6 -1
  261. package/src/shared/sqlite.ts +4 -2
  262. package/src/shared/subagent-runner.ts +2 -0
  263. package/src/shared/worker-shutdown-fence.test.ts +87 -0
  264. package/src/shared/worker-shutdown.fixture.ts +25 -0
  265. package/src/shared/worker-shutdown.test.ts +127 -0
  266. package/src/shared/worker-shutdown.ts +160 -0
  267. package/dist/embedding-backfill-fmz50tsy.js +0 -24
  268. package/dist/recomp-orchestrator-999jj4bc.js +0 -61
  269. package/dist/v2/embedding-backfill-7c7yr69y.js +0 -23
  270. package/dist/v2/recomp-orchestrator-f6m9jr7p.js +0 -60
  271. package/dist/wrapup-orchestrator-whhbjmaz.js +0 -48
@@ -6,7 +6,7 @@ import {
6
6
  resolveLegacyConfigSources,
7
7
  getProtectedTokensTierOverrides,
8
8
  loadPluginConfigDetailed
9
- } from "./server-nj659894.js";
9
+ } from "./server-5arr9ecn.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,
@@ -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-c7dxxsj7.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-hqzyq8n4.js";
311
315
  import {
312
316
  pruneMissingProjectIdentities,
313
317
  setHomeProjectPermission,
@@ -324,7 +328,7 @@ import {
324
328
  storedPathBelongsToIdentity,
325
329
  beginBootQuietPeriod,
326
330
  scheduleAfterBootQuiet
327
- } from "./server-rmygf5pn.js";
331
+ } from "./server-ne8arh8t.js";
328
332
  import {
329
333
  detectLatestTurnThinkingMismatch,
330
334
  isPrefixBoundThinkingModel,
@@ -519,7 +523,7 @@ import {
519
523
  readRawSessionMessageById2,
520
524
  readSessionChunk2,
521
525
  readRawSessionSeedTail2
522
- } from "./server-9hx7g5jp.js";
526
+ } from "./server-ej96a39v.js";
523
527
  import {
524
528
  embedPauseBySession,
525
529
  embedRunStateBySession,
@@ -548,7 +552,7 @@ import {
548
552
  embedSessionCompartmentChunks2,
549
553
  getEmbeddingCoverageStatus2,
550
554
  getAutoEmbeddingSessionCoverage2
551
- } from "./server-8by8qfec.js";
555
+ } from "./server-0epqaxhd.js";
552
556
  import {
553
557
  textMentionsRecentCommit,
554
558
  hasMeaningfulUserText2,
@@ -559,7 +563,7 @@ import {
559
563
  estimateTokens,
560
564
  estimateFixedPromptTokens,
561
565
  normalizeText
562
- } from "./server-tgnbmwah.js";
566
+ } from "./server-3mz2qh5a.js";
563
567
  import {
564
568
  SubcClient,
565
569
  connectionFileExists,
@@ -567,7 +571,7 @@ import {
567
571
  toSynapseLaneDescriptor,
568
572
  formatSynapseLaneDescriptor,
569
573
  SynapseEmbeddingProvider
570
- } from "./server-6tmj0s7j.js";
574
+ } from "./server-af2pght7.js";
571
575
  import {
572
576
  inRootAsyncContext2,
573
577
  getTagIdentityWriteGeneration2,
@@ -581,30 +585,34 @@ import {
581
585
  isTransientSqliteError2,
582
586
  SqliteAcquisitionBusyError2,
583
587
  withAsyncPrivilegedWriter2
584
- } from "./server-beht37jy.js";
588
+ } from "./server-1zx2pa5d.js";
585
589
  import"./server-51779zs2.js";
590
+ import {
591
+ createWorkerShutdown
592
+ } from "./server-cpjk5jd2.js";
586
593
  import {
587
594
  isRawCompactionSummaryInfo2,
588
595
  extractInMemoryMessageViews2,
589
596
  buildInMemoryTailRawMessages2,
590
597
  RawOrdinalsNotReady2,
591
598
  runSessionWarmupWorker
592
- } from "./server-xj136kt8.js";
593
- import"./server-1wy7b9de.js";
599
+ } from "./server-55rgxfrw.js";
600
+ import"./server-br1x0tev.js";
594
601
  import {
595
- deleteChunkEmbedBackoffForSession
596
- } from "./server-46neh5fa.js";
602
+ deleteChunkEmbedBackoffForSession2
603
+ } from "./server-wyawsa88.js";
597
604
  import {
598
605
  registerOwnRpcServerInstance,
599
606
  rpcPortDir,
600
607
  rpcPortFilePath,
601
608
  parseRpcPortFile,
602
609
  inspectProcessesAsync
603
- } from "./server-da07v4xp.js";
610
+ } from "./server-k3t06fxr.js";
604
611
  import {
605
612
  BoundedSessionMap,
606
613
  LkgRecoveryFenceError,
607
614
  lkgServedArrayDigest,
615
+ takeLkgRecoveryLockSweepPage,
608
616
  hasCleanLkgRecoveryFence,
609
617
  dirtyLkgRecoveryRevision,
610
618
  ownsLkgDirtyFence,
@@ -625,7 +633,7 @@ import {
625
633
  isMessageIndexReconciledThrough2,
626
634
  indexMessagesAfterOrdinal2,
627
635
  sweepOrphanedOpenCodeMessageIndexesCooperatively2
628
- } from "./server-2ar62dyx.js";
636
+ } from "./server-63fqdghs.js";
629
637
  import {
630
638
  stableStringify,
631
639
  getTemporalDecisions,
@@ -633,7 +641,7 @@ import {
633
641
  freezeTemporalDecisions,
634
642
  tagRevisionKey,
635
643
  tagIdentityRevisionKey
636
- } from "./server-pwv4ezb0.js";
644
+ } from "./server-168pb207.js";
637
645
  import {
638
646
  resolveModelCalibration,
639
647
  calibrateBuckets,
@@ -728,7 +736,7 @@ import {
728
736
  adoptNullOwnerToolTag2,
729
737
  getCandidateToolOwners2,
730
738
  pickNearestPriorOwner2
731
- } from "./server-27gq4mfz.js";
739
+ } from "./server-a3dwxfgd.js";
732
740
  import {
733
741
  resolveOpenCodeDbPath,
734
742
  assertOpenCodeStoreGeneration,
@@ -744,12 +752,12 @@ import {
744
752
  latestRealUserTurnIdFromOpenCodeDb,
745
753
  getMessageTimesFromOpenCodeDb,
746
754
  findLastAssistantModelFromOpenCodeDb
747
- } from "./server-n1prf1g6.js";
755
+ } from "./server-brj8j2gk.js";
748
756
  import {
749
757
  getCurrentToolSetHash,
750
758
  recordToolDefinition,
751
759
  getMeasuredToolDefinitionTokens
752
- } from "./server-g3qma5c0.js";
760
+ } from "./server-dj7tz4ph.js";
753
761
  import {
754
762
  V2_MEMORY_CATEGORIES,
755
763
  CATEGORY_PRIORITY
@@ -762,7 +770,7 @@ import {
762
770
  resolveStoredPathWorkspaceIdentity,
763
771
  storedPathBelongsToWorkspace,
764
772
  computeWorkspaceEpochFingerprint
765
- } from "./server-xq7dfjke.js";
773
+ } from "./server-9x0kmta4.js";
766
774
  import {
767
775
  configureContextDatabasePragmas2
768
776
  } from "./server-fb3zxn06.js";
@@ -808,15 +816,15 @@ import {
808
816
  readGitFileChangeTimesSince,
809
817
  verificationFileExists,
810
818
  normalizeVerificationFiles
811
- } from "./server-hm38q7r0.js";
819
+ } from "./server-vn2nwcv6.js";
812
820
  import {
813
821
  deriveTriggerBudget2,
814
822
  deriveHistorianChunkTokens2,
815
823
  resolveKnownHistorianContextLimit2,
816
824
  resolveHistorianProducerLimits2,
817
825
  resolveHistorianContextLimit2
818
- } from "./server-34kwfsr4.js";
819
- import"./server-d04vrx0j.js";
826
+ } from "./server-53eh1r8r.js";
827
+ import"./server-ygtykank.js";
820
828
  import {
821
829
  isEmbeddingHostBusy2
822
830
  } from "./server-qt1qqasc.js";
@@ -829,18 +837,20 @@ import {
829
837
  releaseGitSweepLease,
830
838
  recordSessionProjectIdentity,
831
839
  hasRecordedSessionProjectIdentity
832
- } from "./server-hy3d3vsx.js";
840
+ } from "./server-4nw4fqhr.js";
833
841
  import {
834
842
  saveEmbeddingIfHashMatches,
835
843
  invalidateProject2,
836
844
  invalidateMemory2
837
845
  } from "./server-4dhv7mqz.js";
838
846
  import {
847
+ getCachedLocalEmbeddingPooling,
848
+ preflightLocalEmbeddingPooling,
839
849
  getLocalEmbeddingNativeMemoryStats
840
- } from "./server-h1v0pyxb.js";
850
+ } from "./server-j4jnp9b5.js";
841
851
  import {
842
852
  cosineSimilarity
843
- } from "./server-zzkj2fch.js";
853
+ } from "./server-xsryvyf6.js";
844
854
  import {
845
855
  computeCueContentHash,
846
856
  hasMuralCueColumns,
@@ -865,7 +875,7 @@ import {
865
875
  mergeMemoryStats2,
866
876
  archiveMemory2,
867
877
  getMemoryCountsByStatus2
868
- } from "./server-n37sebck.js";
878
+ } from "./server-y4a3nhtk.js";
869
879
  import {
870
880
  registerNotificationSink2,
871
881
  pushNotification2,
@@ -873,11 +883,11 @@ import {
873
883
  drainNotifications2,
874
884
  isTuiConnected2
875
885
  } from "./server-x8a7jmkh.js";
876
- import"./server-h0410h0v.js";
886
+ import"./server-1bw1wcbp.js";
877
887
  import {
878
888
  flushIgnoredMessages2,
879
889
  sendStatusNotification2
880
- } from "./server-a9xqj88f.js";
890
+ } from "./server-230fnbws.js";
881
891
  import {
882
892
  renderSingleStoreMigrationRequiredRefusal,
883
893
  SingleStoreMigrationRequiredError,
@@ -897,14 +907,14 @@ import {
897
907
  resolveMemoriesByIdsForSearch2,
898
908
  unifiedSearch2,
899
909
  formatSearchResults2
900
- } from "./server-gsxjv2q2.js";
910
+ } from "./server-m91f9m5s.js";
901
911
  import {
902
912
  resolvePromptContext2
903
913
  } from "./server-fmsr7v69.js";
904
914
  import"./server-kaqs6h31.js";
905
915
  import {
906
916
  renderSearchArchiveOffThread2
907
- } from "./server-45q69hkq.js";
917
+ } from "./server-4sxjs6hn.js";
908
918
  import {
909
919
  compareSemverCore
910
920
  } from "./server-84w6rvvf.js";
@@ -944,7 +954,7 @@ import {
944
954
  } from "./server-8ajstryz.js";
945
955
  import {
946
956
  logSlowWriteTransaction
947
- } from "./server-6pmqg9m4.js";
957
+ } from "./server-gyy4k6mf.js";
948
958
  import {
949
959
  shouldEnforcePrivateStoragePermissions,
950
960
  ensureStorageDirectorySync,
@@ -3182,7 +3192,7 @@ function dropCompartmentsAfter(db, sessionId, anchor, holderId, activeBranch = f
3182
3192
  if (marker && clearPendingPiCompactionMarkerStateIf(db, sessionId, marker, null))
3183
3193
  clearedMarker = marker;
3184
3194
  }
3185
- deleteChunkEmbedBackoffForSession(db, sessionId);
3195
+ deleteChunkEmbedBackoffForSession2(db, sessionId);
3186
3196
  queueM0Mutation(db, { sessionId, mutationType: "recomp_boundary_change" });
3187
3197
  clearCachedM0M1(db, sessionId);
3188
3198
  db.exec("COMMIT");
@@ -3441,6 +3451,11 @@ function scheduleReconciliation(db, sessionId, readMessages) {
3441
3451
  });
3442
3452
  }
3443
3453
  async function sweepOrphanedOpenCodeMessageIndexesOffThread(db, openSource, options = {}) {
3454
+ if (getHarness2() === "opencode" || getHarness2() === "opencode2")
3455
+ options = {
3456
+ ...options,
3457
+ fenceLockNames: options.fenceLockNames ?? takeLkgRecoveryLockSweepPage()
3458
+ };
3444
3459
  if (getHarness2() === "opencode2")
3445
3460
  openSource = () => new Database2(gaDatabasePath(getDataDir(), process.env.OPENCODE_CHANNEL ?? "latest"), {
3446
3461
  readonly: true,
@@ -4145,7 +4160,8 @@ ${trimmedBody}…
4145
4160
  return wrapped;
4146
4161
  }
4147
4162
  function selectAutoSearchResults(results, threshold) {
4148
- return results.filter((result) => (result.relevanceScore ?? result.score) >= threshold);
4163
+ const relevance = (result) => result.relevanceScore ?? result.score;
4164
+ return results.filter((result) => relevance(result) >= threshold).sort((left, right) => relevance(right) - relevance(left));
4149
4165
  }
4150
4166
 
4151
4167
  // src/hooks/magic-context/auto-search-worker-client.ts
@@ -4238,6 +4254,13 @@ function retryUnpublishedAutoSearchNoHint(db, sessionId, messageId, startedAt) {
4238
4254
  }
4239
4255
  return true;
4240
4256
  }
4257
+
4258
+ class AutoSearchBusyError extends Error {
4259
+ constructor() {
4260
+ super("an earlier auto-search of this session is still running");
4261
+ this.name = "AutoSearchBusyError";
4262
+ }
4263
+ }
4241
4264
  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
4265
  return executeAutoSearchWorker(db, sessionId, projectPath, query, options, entry, "search");
4243
4266
  }
@@ -4246,14 +4269,19 @@ var searchWorkers = new WeakMap;
4246
4269
  var liveSearchWorkers = new Set;
4247
4270
  var MAX_IDLE_SEARCH_WORKERS = 4;
4248
4271
  var SEARCH_WORKER_IDLE_MS = 5 * 60000;
4272
+ var DETACHED_SEARCH_LIMIT_MS = 30000;
4273
+ var AUTO_SEARCH_WORKER_CLOSE_DEADLINE_MS = 2000;
4249
4274
  var workersCreated = 0;
4250
4275
  var workersReused = 0;
4276
+ var searchesSkippedBusy = 0;
4251
4277
  async function acquireSearchWorker(db, key, entry, input, signal) {
4252
4278
  const pool = searchWorkers.get(db) ?? new Map;
4253
4279
  searchWorkers.set(db, pool);
4254
4280
  while (!signal.aborted) {
4255
4281
  let slot = pool.get(key);
4256
4282
  if (slot?.busy) {
4283
+ if (input.job === "search" && (slot.detached || slot.busySessionId === input.sessionId))
4284
+ return "busy";
4257
4285
  const current = slot;
4258
4286
  await new Promise((resolve) => {
4259
4287
  const done = () => {
@@ -4262,6 +4290,8 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
4262
4290
  };
4263
4291
  signal.addEventListener("abort", done, { once: true });
4264
4292
  current.busy?.then(done);
4293
+ if (!current.detached)
4294
+ current.detachedSignal?.then(done);
4265
4295
  if (signal.aborted)
4266
4296
  done();
4267
4297
  });
@@ -4270,14 +4300,16 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
4270
4300
  const fresh = !slot;
4271
4301
  if (!slot) {
4272
4302
  const worker = inRootAsyncContext2(() => new Worker(entry, { workerData: { ...input, persistent: true } }));
4303
+ const shutdown = createWorkerShutdown(worker, "auto-search", AUTO_SEARCH_WORKER_CLOSE_DEADLINE_MS);
4273
4304
  slot = {
4274
4305
  worker,
4275
4306
  dispose() {
4307
+ this.disposed = true;
4276
4308
  clearTimeout(this.idleTimer);
4277
4309
  if (pool.get(key) === this)
4278
4310
  pool.delete(key);
4279
4311
  liveSearchWorkers.delete(this);
4280
- worker.terminate();
4312
+ shutdown.close();
4281
4313
  worker.unref();
4282
4314
  }
4283
4315
  };
@@ -4291,9 +4323,14 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
4291
4323
  workersReused++;
4292
4324
  clearTimeout(slot.idleTimer);
4293
4325
  const current = slot;
4326
+ current.busySessionId = input.sessionId;
4327
+ current.detached = false;
4294
4328
  current.busy = new Promise((resolve) => {
4295
4329
  current.release = resolve;
4296
4330
  });
4331
+ current.detachedSignal = new Promise((resolve) => {
4332
+ current.markDetached = resolve;
4333
+ });
4297
4334
  current.worker.ref();
4298
4335
  return { slot: current, fresh };
4299
4336
  }
@@ -4302,6 +4339,9 @@ async function acquireSearchWorker(db, key, entry, input, signal) {
4302
4339
  function queueAutoSearchBackfill(db, sessionId, projectPath, query) {
4303
4340
  if (isEmbeddingHostBusy2())
4304
4341
  return Promise.resolve();
4342
+ const snapshot = getProjectEmbeddingSnapshot2(projectPath);
4343
+ if (!snapshot?.enabled || !snapshot.features.memoryEnabled)
4344
+ return Promise.resolve();
4305
4345
  const key = `${sessionId}\x00${projectPath}`;
4306
4346
  const pending = pendingBackfills.get(db) ?? new Map;
4307
4347
  pendingBackfills.set(db, pending);
@@ -4349,6 +4389,7 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4349
4389
  signal: deadlineSignal,
4350
4390
  readMessages: _readMessages,
4351
4391
  searchMessageHistory: _searchMessageHistory,
4392
+ stepTimings: _stepTimings,
4352
4393
  ...serializable
4353
4394
  } = options;
4354
4395
  const lifecycle = registerAutoSearchWork(sessionId);
@@ -4384,30 +4425,55 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4384
4425
  lifecycle.done();
4385
4426
  return [];
4386
4427
  }
4428
+ if (lease === "busy") {
4429
+ lifecycle.done();
4430
+ searchesSkippedBusy++;
4431
+ throw new AutoSearchBusyError;
4432
+ }
4387
4433
  const { slot, fresh } = lease;
4388
4434
  const worker = slot.worker;
4435
+ const detachable = job === "search" && entry.href === defaultAutoSearchWorkerEntry().href;
4436
+ const startedAt = performance.now();
4437
+ let detachedAt;
4438
+ let ownerVectorMs;
4439
+ let abandonTimer;
4389
4440
  return new Promise((resolve, reject) => {
4390
4441
  let settled = false;
4391
- const finish = (results, error) => {
4442
+ let released = false;
4443
+ const settle = (results, error) => {
4392
4444
  if (settled)
4393
4445
  return;
4394
4446
  settled = true;
4447
+ if (error)
4448
+ reject(error);
4449
+ else
4450
+ resolve(results);
4451
+ };
4452
+ const release = (dispose) => {
4453
+ if (released)
4454
+ return;
4455
+ released = true;
4456
+ clearTimeout(abandonTimer);
4395
4457
  signal?.removeEventListener("abort", abort);
4396
4458
  lifecycle.signal.removeEventListener("abort", abort);
4397
4459
  lifecycle.done();
4398
4460
  worker.off("message", onMessage);
4399
4461
  worker.off("error", onError);
4400
4462
  worker.off("exit", onExit);
4401
- if (error || signal.aborted || entry.href !== defaultAutoSearchWorkerEntry().href)
4463
+ if (dispose || !detachable)
4402
4464
  slot.dispose();
4403
- else {
4465
+ else if (!slot.disposed) {
4404
4466
  slot.idleTimer = setTimeout(() => slot.dispose(), SEARCH_WORKER_IDLE_MS);
4405
4467
  slot.idleTimer.unref?.();
4406
4468
  }
4407
- const release = slot.release;
4469
+ const free = slot.release;
4408
4470
  slot.busy = undefined;
4409
4471
  slot.release = undefined;
4410
- release?.();
4472
+ slot.busySessionId = undefined;
4473
+ slot.detached = false;
4474
+ slot.detachedSignal = undefined;
4475
+ slot.markDetached = undefined;
4476
+ free?.();
4411
4477
  const reusable = liveSearchWorkers.delete(slot);
4412
4478
  if (reusable)
4413
4479
  liveSearchWorkers.add(slot);
@@ -4415,51 +4481,82 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4415
4481
  for (const prior of idle.slice(0, Math.max(0, idle.length - MAX_IDLE_SEARCH_WORKERS)))
4416
4482
  prior.dispose();
4417
4483
  worker.unref();
4418
- if (error)
4419
- reject(error);
4420
- else
4421
- resolve(results);
4422
4484
  };
4423
- const abort = () => finish([]);
4485
+ const finish = (results, error) => {
4486
+ settle(results, error);
4487
+ release(Boolean(error) || signal.aborted);
4488
+ };
4489
+ const abort = () => {
4490
+ if (lifecycle.signal.aborted || !detachable) {
4491
+ finish([]);
4492
+ return;
4493
+ }
4494
+ if (settled)
4495
+ return;
4496
+ detachedAt = performance.now();
4497
+ slot.detached = true;
4498
+ slot.markDetached?.();
4499
+ settle([]);
4500
+ abandonTimer = setTimeout(() => {
4501
+ log2(`[auto-search] session ${sessionId}: search still running ${DETACHED_SEARCH_LIMIT_MS} ms after its deadline; disposing its worker (owner vector wait ${formatMs(ownerVectorMs)})`);
4502
+ release(true);
4503
+ }, DETACHED_SEARCH_LIMIT_MS);
4504
+ abandonTimer.unref?.();
4505
+ };
4424
4506
  signal?.addEventListener("abort", abort, { once: true });
4425
4507
  lifecycle.signal.addEventListener("abort", abort, { once: true });
4426
4508
  const onError = (error) => finish([], error);
4427
4509
  const onExit = (code) => finish([], new Error(`auto-search worker exited (${code})`));
4428
4510
  const onMessage = async (reply) => {
4429
- if (settled)
4511
+ if (released)
4430
4512
  return;
4431
- if (reply.kind === "result") {
4513
+ if (reply.kind === "result" || reply.kind === "error") {
4514
+ if (detachedAt !== undefined) {
4515
+ logLateSearch(sessionId, performance.now() - detachedAt, detachedAt - startedAt, ownerVectorMs, reply.kind === "result" ? reply.timings : undefined, reply.kind === "error");
4516
+ release(reply.kind === "error");
4517
+ return;
4518
+ }
4519
+ if (reply.kind === "error") {
4520
+ finish([], new Error(reply.error));
4521
+ return;
4522
+ }
4432
4523
  if (snapshot && getProjectEmbeddingSnapshot2(projectPath)?.generation !== snapshot.generation)
4433
4524
  finish([]);
4434
4525
  else
4435
4526
  finish(reply.results);
4436
4527
  return;
4437
4528
  }
4438
- if (reply.kind === "error") {
4439
- finish([], new Error(reply.error));
4440
- return;
4441
- }
4442
4529
  if (reply.kind === "messages" || reply.kind === "accepted")
4443
4530
  return;
4444
4531
  const response = { id: reply.id };
4445
- try {
4532
+ if (!signal.aborted) {
4533
+ const requestedAt = performance.now();
4534
+ try {
4535
+ if (reply.kind === "query")
4536
+ response.result = await (job === "backfill" ? embedTextForProject2(projectPath, reply.text, signal, "query") : boundedHintEmbedding(embedQuery, reply.text, signal)) ?? null;
4537
+ else {
4538
+ const passage = await embedBatchForProject2(projectPath, reply.texts, signal, reply.purpose);
4539
+ const current = getProjectEmbeddingSnapshot2(projectPath);
4540
+ response.passage = passage && current ? {
4541
+ ...passage,
4542
+ providerIdentity: current.providerIdentity,
4543
+ runtimeFingerprint: current.runtimeFingerprint,
4544
+ dimensions: passage.vectors.find((vector) => vector !== null)?.length ?? null
4545
+ } : null;
4546
+ }
4547
+ } catch (error) {
4548
+ response.error = error instanceof Error ? error.message : String(error);
4549
+ }
4446
4550
  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;
4551
+ ownerVectorMs = performance.now() - requestedAt;
4552
+ if (signal.aborted) {
4553
+ response.result = undefined;
4554
+ response.passage = undefined;
4555
+ response.error = undefined;
4457
4556
  }
4458
- } catch (error) {
4459
- response.error = error instanceof Error ? error.message : String(error);
4460
4557
  }
4461
4558
  response.embeddingHostBusy = isEmbeddingHostBusy2();
4462
- if (!settled && !signal?.aborted) {
4559
+ if (!released) {
4463
4560
  try {
4464
4561
  worker.postMessage(response);
4465
4562
  } catch (error) {
@@ -4481,6 +4578,15 @@ async function executeAutoSearchWorker(db, sessionId, projectPath, query, option
4481
4578
  }
4482
4579
  });
4483
4580
  }
4581
+ function formatMs(value) {
4582
+ return value === undefined ? "n/a" : `${Math.round(value)} ms`;
4583
+ }
4584
+ function logLateSearch(sessionId, lateMs, waitedMs, ownerVectorMs, timings, failed) {
4585
+ const steps = timings?.steps;
4586
+ const warm = timings?.lastPoolWarm;
4587
+ 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";
4588
+ 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}`);
4589
+ }
4484
4590
  async function boundedHintEmbedding(embed, text, signal) {
4485
4591
  const controller = new AbortController;
4486
4592
  const combined = AbortSignal.any([signal, controller.signal]);
@@ -4504,6 +4610,7 @@ function defaultAutoSearchWorkerEntry() {
4504
4610
  }
4505
4611
  var MESSAGE_WORKER_ACCEPT_TIMEOUT_MS = 400;
4506
4612
  var MESSAGE_WORKER_RESULT_TIMEOUT_MS = 30000;
4613
+ var MESSAGE_SEARCH_WORKER_CLOSE_DEADLINE_MS = 2000;
4507
4614
  var messageSearchWorkerFallbacks = new Map;
4508
4615
  function searchMessageHistoryOffThread(db, request, entry = defaultAutoSearchWorkerEntry(), deadlines = {}) {
4509
4616
  const fallback = (reason, detail) => {
@@ -4531,6 +4638,7 @@ function searchMessageHistoryOffThread(db, request, entry = defaultAutoSearchWor
4531
4638
  return new Promise((resolve) => {
4532
4639
  let settled = false;
4533
4640
  let worker;
4641
+ let shutdown;
4534
4642
  let deadline;
4535
4643
  const finish = (outcome, reason, detail) => {
4536
4644
  if (settled)
@@ -4539,7 +4647,7 @@ function searchMessageHistoryOffThread(db, request, entry = defaultAutoSearchWor
4539
4647
  clearTimeout(deadline);
4540
4648
  if (reason)
4541
4649
  fallback(reason, detail);
4542
- worker?.terminate();
4650
+ shutdown?.close();
4543
4651
  worker?.unref();
4544
4652
  resolve(outcome);
4545
4653
  };
@@ -4550,6 +4658,7 @@ function searchMessageHistoryOffThread(db, request, entry = defaultAutoSearchWor
4550
4658
  };
4551
4659
  try {
4552
4660
  worker = inRootAsyncContext2(() => new Worker(entry, { workerData: input }));
4661
+ shutdown = createWorkerShutdown(worker, "message-search", MESSAGE_SEARCH_WORKER_CLOSE_DEADLINE_MS);
4553
4662
  } catch (error) {
4554
4663
  finish(null, "start-failed", error);
4555
4664
  return;
@@ -4818,7 +4927,8 @@ async function runAutoSearchHint(args) {
4818
4927
  },
4819
4928
  isEmbeddingRuntimeEnabled: () => embeddingEnabled === true,
4820
4929
  visibleMemoryIds: options.visibleMemoryIds ?? null,
4821
- sources: ["memory", "message", "git_commit"]
4930
+ sources: ["memory", "message", "git_commit"],
4931
+ chunkPoolWarmOnly: true
4822
4932
  };
4823
4933
  return searchAutoHint(db, sessionId, options.projectPath, rawPrompt, {
4824
4934
  ...searchOptions,
@@ -4829,6 +4939,11 @@ async function runAutoSearchHint(args) {
4829
4939
  } catch (error) {
4830
4940
  if (lifecycleSignal.aborted)
4831
4941
  return AUTO_SEARCH_OK;
4942
+ if (error instanceof AutoSearchBusyError) {
4943
+ sessionLog2(sessionId, "auto-search: an earlier search of this session is still running, skipping hint for this turn");
4944
+ persistAutoSearchSkip(db, sessionId, userMsgId);
4945
+ return { ok: false, kind: "timeout" };
4946
+ }
4832
4947
  log2(`[auto-search] unified search failed for session ${sessionId} (no-hint frozen for this turn): ${error instanceof Error ? error.message : String(error)}`);
4833
4948
  const outcome = await writeNoHintAndReconcile("error");
4834
4949
  return outcome.ok ? { ok: false, kind: "search-failure" } : outcome;
@@ -4878,7 +4993,7 @@ ${hintText}`;
4878
4993
  if (outcome.decision.decision === "hint") {
4879
4994
  appendReminderToUserMessageById(messages, userMsgId, outcome.decision.text);
4880
4995
  }
4881
- sessionLog2(sessionId, `auto-search: attached hint to ${userMsgId} (${results.length} fragments, top score ${results[0].score.toFixed(3)})`);
4996
+ sessionLog2(sessionId, `auto-search: attached hint to ${userMsgId} (${results.length} fragments, top relevance ${(results[0].relevanceScore ?? results[0].score).toFixed(3)})`);
4882
4997
  return AUTO_SEARCH_OK;
4883
4998
  } finally {
4884
4999
  if (!lifecycleSignal.aborted && results !== null)
@@ -4935,6 +5050,30 @@ function getSessionErrorInfo(properties) {
4935
5050
  };
4936
5051
  }
4937
5052
 
5053
+ // src/hooks/magic-context/diagnostic-log-state.ts
5054
+ var states = new BoundedSessionMap(1000);
5055
+ var scope = (sessionId) => `${getMagicContextStorageDir()}\x00${getHarness2()}\x00${sessionId}`;
5056
+ function diagnosticStateChanged(sessionId, category, state) {
5057
+ const key = scope(sessionId);
5058
+ const previous = states.get(key) ?? new Map;
5059
+ if (previous.get(category) === state)
5060
+ return false;
5061
+ previous.set(category, state);
5062
+ states.set(key, previous);
5063
+ return true;
5064
+ }
5065
+ function clearDiagnosticLogState(sessionId) {
5066
+ states.delete(scope(sessionId));
5067
+ }
5068
+
5069
+ // src/hooks/magic-context/nudge-evaluation-log.ts
5070
+ function logNudgeEvaluation(sessionId, phase, line) {
5071
+ const category = `${phase}:${line.split(":", 1)[0]}`;
5072
+ const state = line.split(" ").filter((field) => /^(ctx_reduce|band|dampening|verdict|reason|lease)=/.test(field)).join(" ");
5073
+ if (diagnosticStateChanged(sessionId, category, state))
5074
+ sessionLog2(sessionId, line);
5075
+ }
5076
+
4938
5077
  // src/features/magic-context/dreamer/storage-task-schedule.ts
4939
5078
  function toRow(r) {
4940
5079
  return {
@@ -5811,7 +5950,7 @@ function canConsumeDeferredOnThisPass(args) {
5811
5950
  return args.schedulerDecision === "execute" || args.contextPercentage >= (args.forceMaterializationPercentage ?? escalationBands(65).forceMaterializationPercentage);
5812
5951
  }
5813
5952
  function hasReclaimRide(signals) {
5814
- return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true;
5953
+ return signals.hardFold || signals.force || signals.explicitFlush || signals.publishedHistory || signals.subagentExecute === true || signals.executeReclaim === true;
5815
5954
  }
5816
5955
  function prefixMutationPermitted(gate) {
5817
5956
  return !gate.signedThinkingHold || gate.firstRender || gate.idleExpiry || gate.emergency;
@@ -5824,13 +5963,233 @@ var RECLAIM_RIDE_NAMES = [
5824
5963
  "force",
5825
5964
  "explicitFlush",
5826
5965
  "publishedHistory",
5827
- "subagentExecute"
5966
+ "subagentExecute",
5967
+ "executeReclaim"
5828
5968
  ];
5829
5969
  function reclaimRideLabel(signals) {
5830
5970
  const active = RECLAIM_RIDE_NAMES.filter((name) => signals[name]);
5831
5971
  return `ride=${active.length > 0 ? active.join("+") : "none"}`;
5832
5972
  }
5833
5973
 
5974
+ // src/hooks/magic-context/pending-drop-eligibility.ts
5975
+ function pendingDropVeto(tagNumber, target, protectedTagIds) {
5976
+ if (protectedTagIds.has(tagNumber))
5977
+ return "protected";
5978
+ if (target?.thinkingDropProtected)
5979
+ return "active_thinking";
5980
+ return null;
5981
+ }
5982
+ function capturePendingDropEligibility(targets, protectedTagIds) {
5983
+ const eligible = new Set;
5984
+ for (const [number, target] of targets) {
5985
+ if (pendingDropVeto(number, target, protectedTagIds))
5986
+ continue;
5987
+ if (target.drop) {
5988
+ if (target.canDrop?.() === true)
5989
+ eligible.add(number);
5990
+ } else {
5991
+ const content = target.getContent?.();
5992
+ const replacement = `[dropped §${number}§]`;
5993
+ if (typeof content === "string" && content.length > replacement.length && target.canSetContent?.(replacement) !== false)
5994
+ eligible.add(number);
5995
+ }
5996
+ }
5997
+ return eligible;
5998
+ }
5999
+ function pendingDropEligibilityKey(db, sessionId, input, protectionInputs) {
6000
+ const digests = input.map((message) => message.contentDigest?.() ?? null);
6001
+ if (digests.some((digest) => digest === null))
6002
+ return null;
6003
+ const revision = db.prepare("SELECT value FROM schema_migrations_meta WHERE key = ?").get(tagRevisionKey(sessionId));
6004
+ if (!revision?.value)
6005
+ return null;
6006
+ return JSON.stringify([
6007
+ input.map((message, index) => [
6008
+ message.id,
6009
+ message.role,
6010
+ message.synthetic,
6011
+ digests[index]
6012
+ ]),
6013
+ revision.value,
6014
+ readEpochFloorSnapshot(db, sessionId),
6015
+ sessionDecisionCalibration(db, sessionId).toolsRatio,
6016
+ loadProtectedTailMeta(db, sessionId),
6017
+ [...getMergedReasoningStrippedIds(db, sessionId)].sort(),
6018
+ [...getReasoningRemovalState(db, sessionId).messageIds].sort(),
6019
+ protectionInputs
6020
+ ]);
6021
+ }
6022
+ function createPendingDropEligibilityCache() {
6023
+ const sessions = new Map;
6024
+ return {
6025
+ read(sessionId, key) {
6026
+ const previous = sessions.get(sessionId);
6027
+ if (key === null || previous?.key !== key) {
6028
+ sessions.delete(sessionId);
6029
+ return;
6030
+ }
6031
+ return previous.eligible;
6032
+ },
6033
+ record(sessionId, key, eligible) {
6034
+ sessions.delete(sessionId);
6035
+ if (key === null)
6036
+ return;
6037
+ const oldest = sessions.keys().next().value;
6038
+ if (sessions.size >= 64 && oldest !== undefined)
6039
+ sessions.delete(oldest);
6040
+ sessions.set(sessionId, { key, eligible: new Set(eligible) });
6041
+ }
6042
+ };
6043
+ }
6044
+
6045
+ // src/hooks/magic-context/postprocess-read-cache.ts
6046
+ var connections = new WeakMap;
6047
+ function snapshot(db, sessionId) {
6048
+ const transaction = db;
6049
+ try {
6050
+ if (transaction.inTransaction || transaction.isTransaction) {
6051
+ connections.delete(db);
6052
+ return { version: -1, changes: -1 };
6053
+ }
6054
+ } catch {
6055
+ connections.delete(db);
6056
+ return { version: -1, changes: -1 };
6057
+ }
6058
+ let connection = connections.get(db);
6059
+ if (!connection) {
6060
+ connection = {
6061
+ stamp: db.prepare("SELECT total_changes() AS changes, data_version AS version FROM pragma_data_version"),
6062
+ sessions: new BoundedSessionMap(100)
6063
+ };
6064
+ connections.set(db, connection);
6065
+ }
6066
+ const stamp = connection.stamp.get();
6067
+ const previous = connection.sessions.get(sessionId);
6068
+ if (previous?.version === stamp.version && previous.changes === stamp.changes) {
6069
+ return previous;
6070
+ }
6071
+ const value = { ...stamp };
6072
+ connection.sessions.set(sessionId, value);
6073
+ return value;
6074
+ }
6075
+ function postprocessTailTags(db, sessionId) {
6076
+ const state = snapshot(db, sessionId);
6077
+ return state.tags ??= getTailHygieneTags2(db, sessionId);
6078
+ }
6079
+ function postprocessOldestTags(db, sessionId, protectedNumbers) {
6080
+ const state = snapshot(db, sessionId);
6081
+ const hints = state.hints;
6082
+ if (hints && hints.protectedNumbers.size === protectedNumbers.size && [...protectedNumbers].every((number) => hints.protectedNumbers.has(number))) {
6083
+ return hints.value;
6084
+ }
6085
+ const value = getOldestActiveUnprotectedToolTags2(db, sessionId, protectedNumbers);
6086
+ state.hints = { protectedNumbers: new Set(protectedNumbers), value };
6087
+ return value;
6088
+ }
6089
+ function postprocessReplaySnapshot(db, sessionId) {
6090
+ const state = snapshot(db, sessionId);
6091
+ const replay = state.replay ??= loadPostprocessReplaySnapshot(db, sessionId);
6092
+ return {
6093
+ ...replay,
6094
+ staleReduceStrippedIds: new Set(replay.staleReduceStrippedIds),
6095
+ processedImageStrippedIds: new Set(replay.processedImageStrippedIds),
6096
+ processedImageMarkers: new Map(replay.processedImageMarkers),
6097
+ strippedPlaceholderIds: new Set(replay.strippedPlaceholderIds),
6098
+ hiddenSeamPlaceholderIds: new Set(replay.hiddenSeamPlaceholderIds),
6099
+ mergedReasoningStrippedIds: new Set(replay.mergedReasoningStrippedIds),
6100
+ trailingBlankDecisions: new Map(replay.trailingBlankDecisions),
6101
+ noteNudgeAnchors: structuredClone(replay.noteNudgeAnchors),
6102
+ autoSearchHintDecisions: structuredClone(replay.autoSearchHintDecisions),
6103
+ todoSyntheticAnchor: structuredClone(replay.todoSyntheticAnchor),
6104
+ pendingCompactionMarker: structuredClone(replay.pendingCompactionMarker),
6105
+ compactionMarker: structuredClone(replay.compactionMarker)
6106
+ };
6107
+ }
6108
+
6109
+ // src/hooks/magic-context/execute-reclaim.ts
6110
+ var NAMESPACE = "executeReclaim";
6111
+ var failedWrites = new WeakMap;
6112
+ function readExecuteReclaimState(db, sessionId) {
6113
+ return parseState(postprocessReplaySnapshot(db, sessionId).executeReclaim);
6114
+ }
6115
+ function parseState(lane) {
6116
+ const value = lane;
6117
+ return {
6118
+ heldPasses: typeof value?.heldPasses === "number" ? Math.max(0, value.heldPasses) : 0,
6119
+ floorOrdinal: typeof value?.floorOrdinal === "number" ? value.floorOrdinal : null,
6120
+ floorPromptId: typeof value?.floorPromptId === "string" ? value.floorPromptId : null
6121
+ };
6122
+ }
6123
+ function writeExecuteReclaimState(db, sessionId, patch) {
6124
+ if (failedWrites.get(db)?.has(sessionId))
6125
+ return false;
6126
+ try {
6127
+ const current = readExecuteReclaimState(db, sessionId);
6128
+ if (JSON.stringify(current) === JSON.stringify({ ...current, ...patch }))
6129
+ return true;
6130
+ if (!updateReplayDocument(db, sessionId, (doc) => {
6131
+ const previous = parseState(doc[NAMESPACE]);
6132
+ const state = { ...previous, ...patch };
6133
+ if (JSON.stringify(previous) === JSON.stringify(state))
6134
+ return false;
6135
+ doc.version = 2;
6136
+ doc[NAMESPACE] = state;
6137
+ return true;
6138
+ }))
6139
+ throw new Error("Could not persist execute reclaim state");
6140
+ return true;
6141
+ } catch (error) {
6142
+ let failed = failedWrites.get(db);
6143
+ if (!failed)
6144
+ failedWrites.set(db, failed = new Set);
6145
+ failed.add(sessionId);
6146
+ sessionLog2(sessionId, `execute reclaim state persistence failed; retaining existing policy: ${String(error)}`);
6147
+ return false;
6148
+ }
6149
+ }
6150
+ function clearExecuteReclaimState(db, sessionId) {
6151
+ writeExecuteReclaimState(db, sessionId, {
6152
+ heldPasses: 0,
6153
+ floorOrdinal: null,
6154
+ floorPromptId: null
6155
+ });
6156
+ }
6157
+ function maintainExecuteFloorMark(db, sessionId, promptId, belowExecute) {
6158
+ failedWrites.get(db)?.delete(sessionId);
6159
+ const state = readExecuteReclaimState(db, sessionId);
6160
+ if (state.floorOrdinal !== null && (belowExecute || promptId !== null && promptId !== state.floorPromptId)) {
6161
+ writeExecuteReclaimState(db, sessionId, { floorOrdinal: null, floorPromptId: null });
6162
+ }
6163
+ }
6164
+ function estimateExecuteReclaimTokens(args) {
6165
+ const eligible = capturePendingDropEligibility(args.targets, args.protectedTagIds);
6166
+ const queued = new Set(args.pendingOps.filter((op) => op.operation === "drop").map((op) => op.tagId));
6167
+ const candidates = args.tags.filter((tag) => tag.status === "active" && queued.has(tag.tagNumber) && eligible.has(tag.tagNumber));
6168
+ const preparationTargets = new Map;
6169
+ for (const tag of candidates) {
6170
+ const target = args.targets.get(tag.tagNumber);
6171
+ if (target?.prepareDrop)
6172
+ preparationTargets.set(tag.tagNumber, target);
6173
+ }
6174
+ const prepared = preparationTargets.size === 0 ? new Set : args.probePreparation?.(preparationTargets) ?? new Set([...preparationTargets].filter(([, target]) => target.prepareDrop?.() !== false).map(([number]) => number));
6175
+ const seed = sessionDecisionCalibration(args.db, args.sessionId);
6176
+ return candidates.reduce((total, tag) => {
6177
+ if (preparationTargets.has(tag.tagNumber) && !prepared.has(tag.tagNumber))
6178
+ return total;
6179
+ const ratio = tag.type === "tool" ? seed.toolsRatio : seed.proseRatio;
6180
+ return total + Math.max(0, (tag.tokenCount ?? Math.ceil(tag.byteSize / 4)) * ratio);
6181
+ }, 0);
6182
+ }
6183
+ function originateExecuteReclaim(args) {
6184
+ if (failedWrites.get(args.db)?.has(args.sessionId))
6185
+ return false;
6186
+ const state = readExecuteReclaimState(args.db, args.sessionId);
6187
+ const heldPasses = args.primaryExecute && args.reclaimableTokens > 0 && !args.alreadyBusting ? state.heldPasses + 1 : 0;
6188
+ if (!writeExecuteReclaimState(args.db, args.sessionId, { heldPasses }))
6189
+ return false;
6190
+ return args.primaryExecute && !args.alreadyBusting && !args.summaryCanCome && args.reclaimableTokens > 0 && (args.usableWindow > 0 && args.reclaimableTokens >= args.usableWindow * 0.02 || heldPasses >= 3);
6191
+ }
6192
+
5834
6193
  // src/hooks/magic-context/historian-drain-gate.ts
5835
6194
  var loggedWindows = new WeakMap;
5836
6195
  function isHistorianDrainBudgetSpent(args) {
@@ -5982,7 +6341,7 @@ function resolveBoundaryContextLimit(usage, fallbackContextLimit) {
5982
6341
  }
5983
6342
  return 128000;
5984
6343
  }
5985
- function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor = 0) {
6344
+ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, inMemoryTail, taggerFloor = 0, liftLivePromptFloor = false) {
5986
6345
  return withRawSessionMessageCache2(() => {
5987
6346
  try {
5988
6347
  const memoryPrimed = inMemoryTail ? primeInMemoryTailRawMessageCache2({
@@ -6012,7 +6371,8 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
6012
6371
  executeThresholdPercentage,
6013
6372
  usage,
6014
6373
  usageSource: "live",
6015
- taggerFloor
6374
+ taggerFloor,
6375
+ liftLivePromptFloor
6016
6376
  });
6017
6377
  const hasProtectedEligibleHead = boundary.offset < Math.min(boundary.protectedTailStart, boundary.eligibleEndOrdinal);
6018
6378
  if (!hasProtectedEligibleHead) {
@@ -6048,7 +6408,10 @@ function getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThr
6048
6408
  function formatProjectedPostDropPercentage(value) {
6049
6409
  return value === null ? "none" : `${value.toFixed(1)}%`;
6050
6410
  }
6051
- function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide, eligiblePendingDropTagIds) {
6411
+ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPercentage, executeThresholdPercentage, triggerBudget, keepReasoningTokens, commitClusterTrigger, preloadedActiveTags, contextLimit, inMemoryTail, taggerFloorOverride, reasoningProjection, reclaimRide, eligiblePendingDropTagIds, primaryExecute = false) {
6412
+ if (usage.percentage < executeThresholdPercentage) {
6413
+ writeExecuteReclaimState(db, sessionId, { floorOrdinal: null, floorPromptId: null });
6414
+ }
6052
6415
  if (sessionMeta.compartmentInProgress) {
6053
6416
  sessionLog2(sessionId, `compartment trigger: skipped — historian already in progress (usage=${usage.percentage.toFixed(1)}%)`);
6054
6417
  return { shouldFire: false };
@@ -6101,7 +6464,22 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
6101
6464
  resolvedInMemoryTail = undefined;
6102
6465
  }
6103
6466
  }
6104
- const tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor);
6467
+ let tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor);
6468
+ const markState = readExecuteReclaimState(db, sessionId);
6469
+ const mark = markState.floorOrdinal;
6470
+ const livePromptOrdinal = tailInfo.boundarySnapshot?.diagnostics?.livePromptFloor.ordinal;
6471
+ let consumedFloorMark = false;
6472
+ if (mark !== null) {
6473
+ const consumed = writeExecuteReclaimState(db, sessionId, {
6474
+ floorOrdinal: null,
6475
+ floorPromptId: null
6476
+ });
6477
+ if (consumed && mark === livePromptOrdinal && markState.floorPromptId === tailInfo.boundarySnapshot?.diagnostics?.livePromptFloor.messageId && usage.percentage >= executeThresholdPercentage) {
6478
+ consumedFloorMark = true;
6479
+ sessionLog2(sessionId, `compartment trigger: live-prompt floor mark consumed at ${mark}`);
6480
+ tailInfo = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor, true);
6481
+ }
6482
+ }
6105
6483
  if (!tailInfo.hasNewRawHistory) {
6106
6484
  try {
6107
6485
  const lastCompartmentEnd = getLastCompartmentEndMessage(db, sessionId);
@@ -6185,7 +6563,21 @@ function checkCompartmentTrigger(db, sessionId, sessionMeta, usage, _previousPer
6185
6563
  return { shouldFire: false };
6186
6564
  }
6187
6565
  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`);
6566
+ let floorOnly = false;
6567
+ const boundary = tailInfo.boundarySnapshot;
6568
+ const floor = boundary?.diagnostics?.livePromptFloor;
6569
+ if (!consumedFloorMark && floor?.ordinal && floor.from > floor.to) {
6570
+ const withoutFloor = getUnsummarizedTailInfo(db, sessionId, triggerBudget, usage, executeThresholdPercentage, contextLimit, resolvedInMemoryTail, taggerFloor, true);
6571
+ floorOnly = withoutFloor.hasProtectedEligibleHead && withoutFloor.isMeaningful;
6572
+ if (floorOnly && primaryExecute && usage.percentage >= executeThresholdPercentage && writeExecuteReclaimState(db, sessionId, {
6573
+ floorOrdinal: floor.ordinal,
6574
+ floorPromptId: floor.messageId ?? null
6575
+ })) {
6576
+ sessionLog2(sessionId, `compartment trigger: live-prompt floor mark set at ${floor.ordinal}`);
6577
+ }
6578
+ }
6579
+ const refusal = floorOnly ? `no eligible head (live-prompt floor at ${floor?.ordinal})` : tailInfo.hasProtectedEligibleHead ? "below meaningfulness" : "no eligible head";
6580
+ 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
6581
  return { shouldFire: false };
6190
6582
  }
6191
6583
  sessionLog2(sessionId, `compartment trigger: proactive fire at ${usage.percentage.toFixed(1)}% (floor=${proactiveTriggerPercentage}% projected post-drop=${formatProjectedPostDropPercentage(projectedPostDropPercentage)} target=${relativePostDropTarget.toFixed(1)}%)`);
@@ -6438,7 +6830,7 @@ function maybeInjectChannel1Nudge(args, sessionId, tool, output) {
6438
6830
  evaluable: state.evaluable,
6439
6831
  generationInvalidated: state.generationInvalidated
6440
6832
  });
6441
- sessionLog2(sessionId, formatChannel1Evaluation(decision));
6833
+ logNudgeEvaluation(sessionId, "tool-completion", formatChannel1Evaluation(decision));
6442
6834
  setLastNudgeUndropped(args.db, sessionId, decision.nextLastNudge);
6443
6835
  const nextNudgeState = {
6444
6836
  ...nudgeState,
@@ -6695,6 +7087,9 @@ function latestAssistantTurnStart(messages) {
6695
7087
  function latestAssistantTurnMessages(messages) {
6696
7088
  return new Set(messages.slice(latestAssistantTurnStart(messages)));
6697
7089
  }
7090
+ function isAnthropicThinkingPart(part, familyRoute) {
7091
+ return isRecord(part) && THINKING_TYPES.has(String(part.type ?? part.kind)) && (familyRoute || isRecord(part.metadata) && isRecord(part.metadata.anthropic));
7092
+ }
6698
7093
  function hasActiveAnthropicThinkingTurn(messages, provider, model) {
6699
7094
  const familyRoute = isAnthropicFamilyRoute(provider, model);
6700
7095
  for (const message of messages.slice(latestAssistantTurnStart(messages))) {
@@ -6703,7 +7098,7 @@ function hasActiveAnthropicThinkingTurn(messages, provider, model) {
6703
7098
  const parts = content(message);
6704
7099
  if (!Array.isArray(parts))
6705
7100
  continue;
6706
- if (parts.some((part) => isRecord(part) && THINKING_TYPES.has(String(part.type ?? part.kind)) && (familyRoute || isRecord(part.metadata) && isRecord(part.metadata.anthropic))))
7101
+ if (parts.some((part) => isAnthropicThinkingPart(part, familyRoute)))
6707
7102
  return true;
6708
7103
  }
6709
7104
  return false;
@@ -7040,96 +7435,26 @@ function resolveHistoryBudgetTokens(historyBudgetPercentage, contextUsage, execu
7040
7435
  }
7041
7436
 
7042
7437
  // src/features/magic-context/storage-host-instruction-retention.ts
7043
- var NAMESPACE = "hostInstructionRetention";
7438
+ var NAMESPACE2 = "hostInstructionRetention";
7044
7439
  var enabled = true;
7045
7440
  function hostInstructionRetentionEnabled() {
7046
7441
  return enabled;
7047
7442
  }
7048
7443
  function isHostInstructionRetentionOn(db, sessionId) {
7049
- const lane = readReplayEnvelope(db, sessionId)[NAMESPACE];
7444
+ const lane = readReplayEnvelope(db, sessionId)[NAMESPACE2];
7050
7445
  return typeof lane === "object" && lane !== null && lane.on === true;
7051
7446
  }
7052
7447
  function markHostInstructionRetention(db, sessionId) {
7053
7448
  return updateReplayDocument(db, sessionId, (doc) => {
7054
- const lane = doc[NAMESPACE];
7449
+ const lane = doc[NAMESPACE2];
7055
7450
  if (typeof lane === "object" && lane !== null && lane.on === true)
7056
7451
  return false;
7057
7452
  doc.version = 2;
7058
- doc[NAMESPACE] = { on: true };
7453
+ doc[NAMESPACE2] = { on: true };
7059
7454
  return true;
7060
7455
  });
7061
7456
  }
7062
7457
 
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
7458
  // src/hooks/magic-context/apply-operations.ts
7134
7459
  var RECENT_TOOL_SKELETON_WINDOW = 20;
7135
7460
  function buildReplacementContent(tagId) {
@@ -7415,12 +7740,16 @@ function applyPendingOperations(sessionId, db, targets, protectedTagIds, preload
7415
7740
  }
7416
7741
  } else if (target) {
7417
7742
  const replacement = buildReplacementContent(pendingOp.tagId);
7743
+ if (target.canSetContent?.(replacement) === false) {
7744
+ reject("content_unchanged");
7745
+ continue;
7746
+ }
7418
7747
  persistDrop();
7419
7748
  mutations.push(() => {
7420
7749
  const priorContent = target.getContent?.();
7421
7750
  const changed = target.setContent(replacement);
7422
- record(changed);
7423
7751
  if (changed) {
7752
+ record(true);
7424
7753
  const originalCharacters = typeof priorContent === "string" ? priorContent.length : tagById.get(pendingOp.tagId)?.byteSize ?? replacement.length;
7425
7754
  onTagReduced?.({
7426
7755
  tagNumber: pendingOp.tagId,
@@ -7683,14 +8012,14 @@ function foldExecutesThisPass(foldDue, materialized) {
7683
8012
  }
7684
8013
 
7685
8014
  // src/features/magic-context/storage-caveman-rules.ts
7686
- var NAMESPACE2 = "caveman";
8015
+ var NAMESPACE3 = "caveman";
7687
8016
  var CURRENT_RULES_VERSION = 2;
7688
8017
  var ORIGINAL_RULES = {
7689
8018
  currentRules: false,
7690
8019
  englishWordRules: true,
7691
8020
  legacyReasoningTags: new Set
7692
8021
  };
7693
- function parseState(lane) {
8022
+ function parseState2(lane) {
7694
8023
  if (!isRecord(lane) || lane.rules !== CURRENT_RULES_VERSION)
7695
8024
  return ORIGINAL_RULES;
7696
8025
  const tags = Array.isArray(lane.legacyReasoningTags) ? lane.legacyReasoningTags : [];
@@ -7702,7 +8031,7 @@ function parseState(lane) {
7702
8031
  }
7703
8032
  function getCavemanReplayState(db, sessionId) {
7704
8033
  try {
7705
- return parseState(readReplayEnvelope(db, sessionId)[NAMESPACE2]);
8034
+ return parseState2(readReplayEnvelope(db, sessionId)[NAMESPACE3]);
7706
8035
  } catch (error) {
7707
8036
  if (error instanceof ReplayDocumentError)
7708
8037
  return ORIGINAL_RULES;
@@ -7712,11 +8041,11 @@ function getCavemanReplayState(db, sessionId) {
7712
8041
  function recordCavemanCurrentRules(db, sessionId, englishWordRules, legacyReasoningTags) {
7713
8042
  const tags = [...new Set(legacyReasoningTags)].sort((a, b) => a - b);
7714
8043
  const persisted = updateReplayDocument(db, sessionId, (doc) => {
7715
- const current = parseState(doc[NAMESPACE2]);
8044
+ const current = parseState2(doc[NAMESPACE3]);
7716
8045
  if (current.currentRules && current.englishWordRules === englishWordRules)
7717
8046
  return false;
7718
8047
  doc.version = 2;
7719
- doc[NAMESPACE2] = {
8048
+ doc[NAMESPACE3] = {
7720
8049
  rules: CURRENT_RULES_VERSION,
7721
8050
  legacyReasoningTags: current.currentRules ? [...current.legacyReasoningTags].sort((a, b) => a - b) : tags,
7722
8051
  ...englishWordRules ? {} : { englishWordRules: false }
@@ -8200,70 +8529,6 @@ function isVisibleNoteReadPart(part) {
8200
8529
  return false;
8201
8530
  }
8202
8531
 
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
8532
  // src/hooks/magic-context/strict-thinking-prefix.ts
8268
8533
  function servedPrefixMatches(args) {
8269
8534
  const heads = args.messages?.slice(0, 2);
@@ -9135,6 +9400,10 @@ function tagMessages(sessionId, messages, tagger, db, options = {}) {
9135
9400
  dropReasoningParts: thinkingParts,
9136
9401
  mutationParts: [{ message, part: textPart }],
9137
9402
  textPrefix: skipPrefixInjection ? "" : prependTag(tagId, ""),
9403
+ canSetContent: (content) => {
9404
+ const partialEnd = messageId ? getPartialEnds().get(messageId) : undefined;
9405
+ return textPart.text !== content && (partialEnd === undefined || partIndex <= partialEnd);
9406
+ },
9138
9407
  setContent: (content, options) => {
9139
9408
  if (textPart.text === content)
9140
9409
  return false;
@@ -9437,6 +9706,25 @@ function proactiveStripStartIndex(args) {
9437
9706
  return divergence;
9438
9707
  return divergence ?? lastServed.messages.length;
9439
9708
  }
9709
+ function servesThinkingBlock(messages, providerID, modelID) {
9710
+ const familyRoute = isAnthropicFamilyRoute(providerID, modelID);
9711
+ for (const message of messages) {
9712
+ if (message.info.role !== "assistant")
9713
+ continue;
9714
+ for (const part of message.parts) {
9715
+ if (!isAnthropicThinkingPart(part, familyRoute) || part.ignored === true)
9716
+ continue;
9717
+ if (part.type === "redacted_thinking")
9718
+ return true;
9719
+ if (typeof part.text === "string" && part.text !== "")
9720
+ return true;
9721
+ const records = isRecord(part.metadata) ? Object.values(part.metadata) : [];
9722
+ if (records.some((record) => isRecord(record) && record.redactedData !== undefined))
9723
+ return true;
9724
+ }
9725
+ }
9726
+ return false;
9727
+ }
9440
9728
  function isPartDroppedBeforeWire(part, providerID) {
9441
9729
  if (!modelAcceptsEmptyContent(providerID) || !isRecord(part))
9442
9730
  return false;
@@ -10039,6 +10327,8 @@ async function runPostTransformPhase(args) {
10039
10327
  if (stripOffWire)
10040
10328
  for (const id of stripped.strip?.messageIds ?? [])
10041
10329
  compactionOffFrozenThinking.add(id);
10330
+ for (const id of stripped.strip?.messageIds ?? [])
10331
+ bindingThinking.add(id);
10042
10332
  retainedThinking.clear();
10043
10333
  protectedThinkingMessages.clear();
10044
10334
  activeThinkingTurn = false;
@@ -10051,6 +10341,10 @@ async function runPostTransformPhase(args) {
10051
10341
  if (args.forceSignedRebuildForFit && (activeThinkingPrefixHold || activeThinkingTurn && args.thinkingBindingRecoveryEnabledForModel === true)) {
10052
10342
  releaseThinkingForRewrite(true);
10053
10343
  }
10344
+ if (args.compactionModeTransition === true && args.thinkingBindingRecoveryEnabledForModel === true) {
10345
+ sessionLog2(args.sessionId, "compaction mode switch: stripping signed thinking");
10346
+ releaseThinkingForRewrite(false, true);
10347
+ }
10054
10348
  const foldDueDecision = m0M1EnabledForFold && args.m0M1 && !freezeM0M1 ? mustMaterialize({
10055
10349
  db: args.db,
10056
10350
  sessionId: args.sessionId,
@@ -10090,6 +10384,7 @@ async function runPostTransformPhase(args) {
10090
10384
  };
10091
10385
  if ((foldDueDecision.value || softRefreshOpportunity || firstRenderBust && activeThinkingPrefixHold) && m0M1EnabledForFold && args.m0M1) {
10092
10386
  let committedFoldBustsServedPrefix;
10387
+ let committedFoldChangesHead;
10093
10388
  try {
10094
10389
  const previousM1 = args.sessionMeta.cachedM1Bytes?.toString("utf8");
10095
10390
  const foldResult = injectM0M1({
@@ -10119,6 +10414,12 @@ async function runPostTransformPhase(args) {
10119
10414
  m1Text: rendered.m1Bytes.toString(),
10120
10415
  muralDataUrl: rendered.muralDataUrl
10121
10416
  }) : foldBustsServedPrefix(foldDueDecision.reason, servedPrefixBeforeFold, rendered);
10417
+ committedFoldChangesHead = firstRenderBust ? !servedPrefixMatches({
10418
+ messages: servedBeforeFirstRender,
10419
+ m0Text: rendered.m0Bytes.toString(),
10420
+ m1Text: rendered.m1Bytes.toString(),
10421
+ muralDataUrl: rendered.muralDataUrl
10422
+ }) : foldChangesServedPrefix(servedPrefixBeforeFold, rendered);
10122
10423
  if (bustsPrefix) {
10123
10424
  if (!conversions.isCurrent(db)) {
10124
10425
  throw new MaterializeContentionError({
@@ -10137,6 +10438,9 @@ async function runPostTransformPhase(args) {
10137
10438
  preparedPrefix = foldResult;
10138
10439
  if (activeThinkingPrefixHold && firstRenderBust && committedFoldBustsServedPrefix) {
10139
10440
  releaseThinkingForRewrite(false, true);
10441
+ } else if (compactionOff && !activeThinkingPrefixHold && args.thinkingBindingRecoveryEnabledForModel === true && committedFoldChangesHead) {
10442
+ sessionLog2(args.sessionId, "compaction-off fold changed the head: stripping signed thinking");
10443
+ releaseThinkingForRewrite(false, true);
10140
10444
  }
10141
10445
  prefixPreflightFailed = foldResult.materializationContentionRetryExhausted === true;
10142
10446
  foldExecutedThisPass = foldExecutesThisPass(foldDueDecision.value || softRefreshOpportunity, foldResult.m0RematerializedThisPass);
@@ -10194,12 +10498,30 @@ async function runPostTransformPhase(args) {
10194
10498
  const heldIdleExpiryRebuild = activeThinkingPrefixHold && args.m0M1?.hardSignals?.cacheExpired === true;
10195
10499
  const idleExpiryRebuild = (!freezeM0M1 || activeThinkingPrefixHold) && args.m0M1?.hardSignals?.cacheExpired === true;
10196
10500
  const rideSignals = {
10501
+ executeReclaim: false,
10197
10502
  subagentExecute: !args.fullFeatureMode && args.schedulerDecision === "execute",
10198
10503
  hardFold: rewritingSignedPrefix || foldBustsServedPrefixThisPass || firstRenderBust || idleExpiryRebuild,
10199
10504
  force: emergencyDropEligible && (args.contextUsage.percentage >= 95 || args.contextUsageFromEstimate !== true && getEmergencyInputSample(args.db, args.sessionId) === 0),
10200
10505
  explicitFlush: isExplicitFlush && hasPendingMaterializationOrigin(args.pendingMaterializationSessions, args.sessionId, "user_flush"),
10201
10506
  publishedHistory: !prefixPreflightFailed && (publishedM1RefreshedThisPass || !m0M1EnabledForFold && (args.pendingCompartmentInjection?.compartmentCount ?? 0) > 0 && legacyPublishedHeadChanged(args))
10202
10507
  };
10508
+ const protectedToolTags = protectedToolTagNumbers(args.tags, args.protectedTools);
10509
+ rideSignals.executeReclaim = !compactionOff && originateExecuteReclaim({
10510
+ db: args.db,
10511
+ sessionId: args.sessionId,
10512
+ primaryExecute: args.fullFeatureMode && args.schedulerDecision === "execute" && args.contextUsage.percentage < args.forceMaterializationPercentage,
10513
+ alreadyBusting: Object.values(rideSignals).some(Boolean) || args.historyRebuiltThisPass,
10514
+ 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,
10515
+ reclaimableTokens: estimateExecuteReclaimTokens({
10516
+ db: args.db,
10517
+ sessionId: args.sessionId,
10518
+ pendingOps,
10519
+ tags: args.tags,
10520
+ targets: newTargets,
10521
+ protectedTagIds: new Set([...args.protectedTagIds, ...protectedToolTags])
10522
+ }),
10523
+ usableWindow: args.usableWindow
10524
+ });
10203
10525
  const publishedWorkDrainAllowed = !compactionOff && reclaimRidePermitted(rideSignals, {
10204
10526
  signedThinkingHold: activeThinkingPrefixHold,
10205
10527
  firstRender: firstRenderBust,
@@ -10207,7 +10529,7 @@ async function runPostTransformPhase(args) {
10207
10529
  emergency: emergencyDropEligible
10208
10530
  });
10209
10531
  const shouldApplyPendingOps = publishedWorkDrainAllowed;
10210
- const shouldRunHeuristics = publishedWorkDrainAllowed && (rideSignals.publishedHistory || materializationRequested || forceMaterialization || foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
10532
+ const shouldRunHeuristics = publishedWorkDrainAllowed && (rideSignals.publishedHistory || rideSignals.executeReclaim || materializationRequested || forceMaterialization || foldBustsServedPrefixThisPass || firstRenderBust || heldIdleExpiryRebuild || emergencyDropEligible || args.schedulerDecision === "execute" && (!alreadyRanThisTurn || !args.fullFeatureMode));
10211
10533
  const isCacheBustingPass = publishedWorkDrainAllowed;
10212
10534
  let unheldSignedTurnBust = false;
10213
10535
  if (isCacheBustingPass && !activeThinkingPrefixHold && activeThinkingTurn && args.thinkingBindingRecoveryEnabledForModel === true) {
@@ -10299,17 +10621,28 @@ async function runPostTransformPhase(args) {
10299
10621
  throw new EmergencyFailClosedError("Magic Context could not read its saved reasoning-removal state for this session", { cause: error });
10300
10622
  }
10301
10623
  }
10624
+ const heuristicsLogChanged = diagnosticStateChanged(args.sessionId, "heuristics", JSON.stringify([
10625
+ args.currentTurnId,
10626
+ shouldRunHeuristics,
10627
+ shouldRunHeuristics ? null : args.schedulerDeferReason
10628
+ ]));
10629
+ const pendingLogChanged = diagnosticStateChanged(args.sessionId, "pending-ops", JSON.stringify([
10630
+ args.currentTurnId,
10631
+ shouldApplyPendingOps,
10632
+ shouldApplyPendingOps ? null : args.schedulerDeferReason,
10633
+ shouldApplyPendingOps ? null : (getPendingOpsCount(args.db, args.sessionId) ?? 0) > 0
10634
+ ]));
10302
10635
  if (shouldRunHeuristics) {
10303
10636
  const subagentRerun = !args.fullFeatureMode && alreadyRanThisTurn && args.schedulerDecision === "execute" && !isExplicitFlush && !forceMaterialization;
10304
10637
  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
10638
  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) {
10639
+ } else if (heuristicsLogChanged && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
10307
10640
  sessionLog2(args.sessionId, `heuristics WILL NOT RUN — reason=${args.schedulerDeferReason}`);
10308
10641
  }
10309
10642
  if (alreadyRanThisTurn && args.schedulerDecision === "execute" && !materializationRequested && args.fullFeatureMode) {
10310
10643
  sessionLog2(args.sessionId, `transform: skipping heuristics (already ran for turn ${args.currentTurnId})`);
10311
10644
  }
10312
- if (!shouldApplyPendingOps && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
10645
+ if (!shouldApplyPendingOps && pendingLogChanged && args.schedulerDeferReason !== undefined && args.schedulerDeferReason !== null) {
10313
10646
  sessionLog2(args.sessionId, `pending ops WILL NOT APPLY — reason=${args.schedulerDeferReason} pendingOps=${formatPendingOpsDepth()} context=${args.contextUsage.percentage.toFixed(1)}%`);
10314
10647
  }
10315
10648
  if (hasPendingUserOps && !shouldApplyPendingOps) {
@@ -10318,7 +10651,6 @@ async function runPostTransformPhase(args) {
10318
10651
  let explicitMaterializedSuccessfully = false;
10319
10652
  let deferredMaterializedSuccessfully = false;
10320
10653
  let pendingOpsDidMutate = false;
10321
- const protectedToolTags = protectedToolTagNumbers(args.tags, args.protectedTools);
10322
10654
  const firstApplicationEdits = { any: false, beforeNewerThinking: false };
10323
10655
  const recordFirstApplicationWireEdit = (beforeNewerThinking) => {
10324
10656
  firstApplicationEdits.any = true;
@@ -11399,6 +11731,8 @@ async function runPostTransformPhase(args) {
11399
11731
  });
11400
11732
  }
11401
11733
  logTransformTiming(args.sessionId, "pp.tailGuard", tTailGuard);
11734
+ if (bustedThisPass)
11735
+ clearExecuteReclaimState(args.db, args.sessionId);
11402
11736
  return {
11403
11737
  explicitMaterializedSuccessfully,
11404
11738
  deferredMaterializedSuccessfully,
@@ -11419,8 +11753,7 @@ async function runPostTransformPhase(args) {
11419
11753
  prefixTrimStatus: deliveredPrefix?.prefixTrimStatus ?? null,
11420
11754
  thinkingBindingRecovery,
11421
11755
  proactiveThinkingStrip,
11422
- thinkingReleasedForFit,
11423
- openTurnSignedThinkingKept: args.thinkingBindingRecoveryEnabledForModel === true && activeThinkingTurn && !rewritingSignedPrefix
11756
+ thinkingReleasedForFit
11424
11757
  };
11425
11758
  }
11426
11759
  function checkM0MutationDriftAndSignal(args) {
@@ -11520,6 +11853,35 @@ function describeSystemPromptChange(previous, current) {
11520
11853
  return `presetChanged=${previous ? previous.preset !== current.preset : "unknown"} elements=[${elements.join("; ")}]`;
11521
11854
  }
11522
11855
 
11856
+ // src/hooks/magic-context/system-prompt-sticky-date.ts
11857
+ var STICKY_DATE_KEY = "systemPromptStickyDate";
11858
+ function readPersistedSystemPromptStickyDate(db, sessionId) {
11859
+ try {
11860
+ const saved = readReplayEnvelope(db, sessionId, "read")[STICKY_DATE_KEY];
11861
+ return typeof saved === "string" && saved.length > 0 ? saved : undefined;
11862
+ } catch (error) {
11863
+ sessionLog2(sessionId, "system prompt sticky date record unreadable:", error);
11864
+ return;
11865
+ }
11866
+ }
11867
+ function persistSystemPromptStickyDate(db, sessionId, stickyDate) {
11868
+ try {
11869
+ const written = updateReplayDocument(db, sessionId, (doc) => {
11870
+ if (doc[STICKY_DATE_KEY] === stickyDate)
11871
+ return false;
11872
+ doc.version = 2;
11873
+ doc[STICKY_DATE_KEY] = stickyDate;
11874
+ return true;
11875
+ });
11876
+ if (!written)
11877
+ sessionLog2(sessionId, "system prompt sticky date record not written");
11878
+ return written;
11879
+ } catch (error) {
11880
+ sessionLog2(sessionId, "system prompt sticky date record write failed:", error);
11881
+ return false;
11882
+ }
11883
+ }
11884
+
11523
11885
  // src/hooks/magic-context/system-date-refresh.ts
11524
11886
  var channels = new WeakMap;
11525
11887
  var outputUpdates = new WeakMap;
@@ -11683,6 +12045,15 @@ function createSystemPromptHashHandler(deps) {
11683
12045
  });
11684
12046
  const guidanceEpochs = createPromptSurfaceGuidanceEpochCache(promptSurfaceRuntime);
11685
12047
  const stickyDateBySession = new Map;
12048
+ const recordedStickyDateBySession = new Map;
12049
+ const recordedStickyDate = (sessionId) => {
12050
+ let recorded = recordedStickyDateBySession.get(sessionId);
12051
+ if (recorded === undefined) {
12052
+ recorded = readPersistedSystemPromptStickyDate(deps.db, sessionId) ?? null;
12053
+ recordedStickyDateBySession.set(sessionId, recorded);
12054
+ }
12055
+ return recorded ?? undefined;
12056
+ };
11686
12057
  const diagnosticPrompts = new Map;
11687
12058
  const processSystemPrompt = async (input, output) => {
11688
12059
  const sessionId = input.sessionID;
@@ -11750,9 +12121,34 @@ function createSystemPromptHashHandler(deps) {
11750
12121
  return;
11751
12122
  const previousHash = sessionMetaEarly?.systemPromptHash ?? "";
11752
12123
  const hasPersistedHash = previousHash !== "" && previousHash !== "0";
11753
- if (!hasPersistedHash)
11754
- stickyDateBySession.delete(sessionId);
11755
- const stickyDate = stickyDateBySession.get(sessionId);
12124
+ const prefixBoundModel = isPrefixBoundThinkingModel(liveModel?.providerID, liveModel?.modelID);
12125
+ let stickyDate = stickyDateBySession.get(sessionId);
12126
+ if (!hasPersistedHash) {
12127
+ const previous = stickyDate ?? recordedStickyDate(sessionId);
12128
+ const live = systemPromptDates(liveSystemContent).live;
12129
+ const fieldCount = (dates) => dates === undefined ? 0 : JSON.parse(dates).length;
12130
+ stickyDate = (!modelKey || prefixBoundModel) && previous !== undefined && live !== undefined && fieldCount(previous) === fieldCount(live) ? previous : undefined;
12131
+ if (stickyDate === undefined)
12132
+ stickyDateBySession.delete(sessionId);
12133
+ else
12134
+ stickyDateBySession.set(sessionId, stickyDate);
12135
+ }
12136
+ if (stickyDate === undefined && hasPersistedHash) {
12137
+ const recorded = recordedStickyDate(sessionId);
12138
+ const live = systemPromptDates(liveSystemContent).live;
12139
+ if (recorded !== undefined && live !== undefined && recorded !== live && systemPromptFingerprint(systemPromptDates(liveSystemContent, recorded).stable, promptSurface.preset) === previousHash) {
12140
+ stickyDate = recorded;
12141
+ stickyDateBySession.set(sessionId, recorded);
12142
+ sessionLog2(sessionId, `system prompt date restored after restart: real=${live}, using=${recorded}`);
12143
+ }
12144
+ }
12145
+ const setStickyDate = (value) => {
12146
+ stickyDateBySession.set(sessionId, value);
12147
+ if (value !== recordedStickyDate(sessionId)) {
12148
+ if (persistSystemPromptStickyDate(deps.db, sessionId, value))
12149
+ recordedStickyDateBySession.set(sessionId, value);
12150
+ }
12151
+ };
11756
12152
  const dates = systemPromptDates(liveSystemContent, stickyDate);
11757
12153
  const currentDate = dates.live;
11758
12154
  const stableCandidate = dates.stable;
@@ -11760,13 +12156,12 @@ function createSystemPromptHashHandler(deps) {
11760
12156
  const contentOrPresetChanged = hasPersistedHash && stableCandidateHash !== previousHash;
11761
12157
  const rewritePermission = systemDateRefreshPermission(deps.historyRefreshSessions, dateRequest);
11762
12158
  const signedThinkingKept = systemDateSignedThinkingKept(deps.historyRefreshSessions, dateRequest);
11763
- const idleDateMayAdvance = idleCacheExpired && signedThinkingKept !== true;
11764
- const prefixBoundModel = isPrefixBoundThinkingModel(liveModel?.providerID, liveModel?.modelID);
12159
+ const systemDateMayMove = (rewrite, keptSignedThinking) => (rewrite || idleCacheExpired) && keptSignedThinking !== true;
11765
12160
  let deferredDateRefresh = false;
11766
12161
  if (currentDate && stickyDate && currentDate !== stickyDate && (idleCacheExpired ? prefixBoundModel : isCacheBusting) && !contentOrPresetChanged && !requestMessagesFinal) {
11767
12162
  const liveElements = [...output.system];
11768
12163
  deferredDateRefresh = waitForSystemDateRefresh(deps.historyRefreshSessions, dateRequest, (permitted, keptSignedThinking) => {
11769
- if (!permitted && !(idleCacheExpired && keptSignedThinking !== true)) {
12164
+ if (!systemDateMayMove(permitted, keptSignedThinking)) {
11770
12165
  deps.systemPromptRefreshSessions.add(sessionId);
11771
12166
  return;
11772
12167
  }
@@ -11779,7 +12174,7 @@ function createSystemPromptHashHandler(deps) {
11779
12174
  cachedM0SystemHash: hash,
11780
12175
  systemPromptTokens: estimateTokens(content)
11781
12176
  });
11782
- stickyDateBySession.set(sessionId, currentDate);
12177
+ setStickyDate(currentDate);
11783
12178
  output.system.splice(0, output.system.length, ...liveElements);
11784
12179
  publishSystemDateOutput(output.system);
11785
12180
  deps.systemPromptRefreshSessions.delete(sessionId);
@@ -11790,12 +12185,12 @@ function createSystemPromptHashHandler(deps) {
11790
12185
  }
11791
12186
  });
11792
12187
  }
11793
- const dateMayAdvance = idleDateMayAdvance && !deferredDateRefresh || contentOrPresetChanged || isCacheBusting && !deferredDateRefresh && (dateRequest ? rewritePermission === true : rewritePermission !== false);
12188
+ const dateMayAdvance = contentOrPresetChanged || !deferredDateRefresh && systemDateMayMove(isCacheBusting && (dateRequest ? rewritePermission === true : rewritePermission !== false), signedThinkingKept);
11794
12189
  if (currentDate && !stickyDate) {
11795
- stickyDateBySession.set(sessionId, currentDate);
12190
+ setStickyDate(currentDate);
11796
12191
  } else if (currentDate && stickyDate && currentDate !== stickyDate) {
11797
12192
  if (dateMayAdvance) {
11798
- stickyDateBySession.set(sessionId, currentDate);
12193
+ setStickyDate(currentDate);
11799
12194
  sessionLog2(sessionId, `system prompt date updated: ${stickyDate} → ${currentDate} (cache-busting pass)`);
11800
12195
  } else {
11801
12196
  let offset = 0;
@@ -11853,7 +12248,7 @@ function createSystemPromptHashHandler(deps) {
11853
12248
  sessionLog2(sessionId, "system prompt meta persist failed (fail-open):", error);
11854
12249
  }
11855
12250
  }
11856
- if (isCacheBusting && !deferredDateRefresh && (contentOrPresetChanged || !currentDate || currentDate === stickyDate || !dateRequest || rewritePermission === true)) {
12251
+ if (isCacheBusting && !deferredDateRefresh && (contentOrPresetChanged || !currentDate || currentDate === stickyDate || !dateRequest || rewritePermission === true && signedThinkingKept !== true)) {
11857
12252
  deps.systemPromptRefreshSessions.delete(sessionId);
11858
12253
  }
11859
12254
  };
@@ -11868,6 +12263,7 @@ function createSystemPromptHashHandler(deps) {
11868
12263
  handler,
11869
12264
  clearSession: (sessionId) => {
11870
12265
  diagnosticPrompts.delete(sessionId);
12266
+ recordedStickyDateBySession.delete(sessionId);
11871
12267
  clearSystemDateRefresh(deps.historyRefreshSessions, sessionId);
11872
12268
  guidanceEpochs.clear(sessionId);
11873
12269
  clearSystemPromptHashSession(sessionId, {
@@ -18349,8 +18745,8 @@ async function runCompartmentPhaseImpl(args) {
18349
18745
  }
18350
18746
  return "completed";
18351
18747
  }
18352
- if (!historianRunnable && args.sessionMeta.compartmentInProgress) {
18353
- sessionLog2(args.sessionId, "transform: historian disabled; clearing stale compartmentInProgress flag");
18748
+ if ((!historianRunnable || !args.canRunCompartments && !getActiveCompartmentRun(args.sessionId)) && args.sessionMeta.compartmentInProgress) {
18749
+ sessionLog2(args.sessionId, "transform: historian unavailable; clearing stale compartmentInProgress flag");
18354
18750
  updateSessionMeta(args.db, args.sessionId, { compartmentInProgress: false });
18355
18751
  compartmentInProgress = false;
18356
18752
  }
@@ -18601,8 +18997,10 @@ function createTransform(deps) {
18601
18997
  const loadedSessions = new Set;
18602
18998
  const prefixHoldLogTurnIds = new Map;
18603
18999
  const thinkingFitRetries = new Set;
19000
+ const compactionModeTransitionPending = new Set;
18604
19001
  const clearSessionLogState = (sessionId) => {
18605
19002
  prefixHoldLogTurnIds.delete(sessionId);
19003
+ clearDiagnosticLogState(sessionId);
18606
19004
  };
18607
19005
  const unmanagedOverWindowSessions = new Set;
18608
19006
  const rustModeTransform = deps.transformMode === "rust" && deps.rustModeModuleClient ? createRustModeTransform(deps, {
@@ -18743,6 +19141,7 @@ function createTransform(deps) {
18743
19141
  const hasTransitionEffects = transition.recordToWrite !== null || transition.notice !== null || transition.invalidatedM0Baseline || transition.clearedCompartmentInProgress || transition.historianCatchUpSignaled;
18744
19142
  if (hasTransitionEffects) {
18745
19143
  if (transition.invalidatedM0Baseline) {
19144
+ compactionModeTransitionPending.add(sessionId);
18746
19145
  sessionMeta = {
18747
19146
  ...sessionMeta,
18748
19147
  cachedM0Bytes: null,
@@ -19075,6 +19474,8 @@ function createTransform(deps) {
19075
19474
  contextLimit: boundaryContextLimit
19076
19475
  });
19077
19476
  let _boundarySnapshotCache;
19477
+ if (fullFeatureMode && !compactionOff)
19478
+ maintainExecuteFloorMark(db, sessionId, currentTurnId, boundaryUsageForProtectedTail.percentage < boundaryExecuteThreshold);
19078
19479
  const getRunnableBoundaryForCompartment = (emergencyTailScale) => {
19079
19480
  if (!canRunCompartments)
19080
19481
  return null;
@@ -19200,8 +19601,9 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19200
19601
  recordedSessionProjectIdentity.set(sessionId, sessionIdentityForBinding);
19201
19602
  }
19202
19603
  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`);
19604
+ const tagFloorMode = compactionOff || messages.length === 0 ? "inactive" : taggerFloor === 0 ? "fallback" : "scoped";
19605
+ if (diagnosticStateChanged(sessionId, "tag-floor", tagFloorMode) && tagFloorMode !== "inactive") {
19606
+ 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
19607
  }
19206
19608
  const ownerRatio = sessionDecisionCalibration(db, sessionId).proseRatio;
19207
19609
  noteTransformPassForExactOrdinalReads(sessionId);
@@ -19238,7 +19640,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19238
19640
  idleExpiry: false,
19239
19641
  emergency: contextUsageEarly.percentage >= forceMaterializationPercentage
19240
19642
  }
19241
- }, pendingDropEligibility.read(sessionId, dropProjectionKey()));
19643
+ }, pendingDropEligibility.read(sessionId, dropProjectionKey()), schedulerDecision === "execute");
19242
19644
  if (triggerResult.shouldFire) {
19243
19645
  sessionLog2(sessionId, `compartment trigger: firing (reason=${triggerResult.reason})`);
19244
19646
  updateSessionMeta(db, sessionId, { compartmentInProgress: true });
@@ -19609,6 +20011,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19609
20011
  activeThinkingPrefixHold,
19610
20012
  directoryPrefixHold: unresolvedDirectoryHold,
19611
20013
  forceSignedRebuildForFit: thinkingFitRetries.has(sessionId) || !!recovery.rebuildReason,
20014
+ compactionModeTransition: compactionModeTransitionPending.has(sessionId),
19612
20015
  readLastServedMessages: () => {
19613
20016
  const slot = getInMemorySlot(sessionId) ?? loadPersistedLkgSlot(db, sessionId);
19614
20017
  try {
@@ -19666,6 +20069,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19666
20069
  hardSignals: m0HardSignals
19667
20070
  }
19668
20071
  });
20072
+ compactionModeTransitionPending.delete(sessionId);
19669
20073
  if (recovery.prefix && !recoveryNormalized) {
19670
20074
  const priorIds = new Set(recovery.prefix.inputs.map((input) => input.id));
19671
20075
  const newIds = new Set(lkgInput.flatMap((input) => input.id && !priorIds.has(input.id) ? [input.id] : []));
@@ -19843,7 +20247,8 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
19843
20247
  if (JSON.stringify([...new Set(stillUntagged)].sort()) !== JSON.stringify([...new Set(persistedUntaggedInputIds)].sort()) && !persistLkgUntaggedInputIds(db, sessionId, stillUntagged))
19844
20248
  throw new Error("Cannot persist the last-good untagged-message record");
19845
20249
  }
19846
- finishSystemDateRefresh(deps.historyRefreshSessions, dateRequest, postTransformResult.bustedThisPass && !activeThinkingPrefixHold && postTransformResult.openTurnSignedThinkingKept !== true || postTransformResult.thinkingReleasedForFit === true, postTransformResult.openTurnSignedThinkingKept === true);
20250
+ const signedThinkingServed = isPrefixBoundThinkingModel(modelForBudget?.providerID, modelForBudget?.modelID) && servesThinkingBlock(messages, modelForBudget?.providerID, modelForBudget?.modelID);
20251
+ finishSystemDateRefresh(deps.historyRefreshSessions, dateRequest, postTransformResult.bustedThisPass && !activeThinkingPrefixHold && !signedThinkingServed || postTransformResult.thinkingReleasedForFit === true, signedThinkingServed);
19847
20252
  if (activeThinkingPrefixHold && !postTransformResult.thinkingReleasedForFit && sessionMeta.cachedM0Bytes != null && sessionMeta.cachedM1Bytes != null) {
19848
20253
  recordHeldHeadForRequest(sessionId, currentLkgRequestIdentity(sessionId), (ownsHistory) => deferDeliveredSystemRefresh(deps, sessionId, ownsHistory));
19849
20254
  }
@@ -20001,7 +20406,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
20001
20406
  postReduceGraceBaselineU: channel1State.postReduceGraceBaselineU,
20002
20407
  postReduceGracePreLevel: channel1State.postReduceGracePreLevel
20003
20408
  });
20004
- sessionLog2(sessionId, formatChannel1Evaluation(channel1Decision));
20409
+ logNudgeEvaluation(sessionId, "transform", formatChannel1Evaluation(channel1Decision));
20005
20410
  const channel2Evaluation = evaluateChannel2(channelBaseline);
20006
20411
  const leaseBefore = getChannel2NudgeState(db, sessionId);
20007
20412
  if (channelBaseline.evaluable && !channelBaseline.generationInvalidated && !channelBaseline.reducedSinceRefresh) {
@@ -20012,7 +20417,7 @@ Historian previously failed ${historianFailureState.failureCount} time(s), so Ma
20012
20417
  }
20013
20418
  }
20014
20419
  const leaseAfter = getChannel2NudgeState(db, sessionId);
20015
- sessionLog2(sessionId, formatChannel2Evaluation(channel2Evaluation, {
20420
+ logNudgeEvaluation(sessionId, "transform", formatChannel2Evaluation(channel2Evaluation, {
20016
20421
  leaseBefore,
20017
20422
  leaseAfter,
20018
20423
  gateHoldReason: channelBaseline.reducedSinceRefresh ? "recent-reduce-refresh" : undefined
@@ -21981,7 +22386,7 @@ function loadRegistrationConfig(directory) {
21981
22386
  configCache.delete(directory);
21982
22387
  return detailed;
21983
22388
  }
21984
- async function ensureProjectRegisteredFromOpenCodeDirectory(directory, db) {
22389
+ async function ensureProjectRegisteredFromOpenCodeDirectory(directory, db, options = {}) {
21985
22390
  const detailed = loadRegistrationConfig(directory);
21986
22391
  const projectIdentity = resolveProjectIdentityForSession(directory, detailed.config.allow_home_project);
21987
22392
  if (!projectIdentity)
@@ -22002,6 +22407,9 @@ async function ensureProjectRegisteredFromOpenCodeDirectory(directory, db) {
22002
22407
  memoryEnabled: detailed.config.memory.enabled,
22003
22408
  gitCommitEnabled: detailed.config.memory.git_commit_indexing.enabled
22004
22409
  };
22410
+ if (options.preflightLocalPooling && routing.primary.provider === "local") {
22411
+ await preflightLocalEmbeddingPooling(routing.primary.model ?? "Xenova/all-MiniLM-L6-v2");
22412
+ }
22005
22413
  const before = getProjectEmbeddingSnapshot2(projectIdentity);
22006
22414
  const registered = registerProjectEmbedding2(db, projectIdentity, routing.primary, features, directory);
22007
22415
  if (!before || before.providerIdentity !== registered.providerIdentity || before.runtimeFingerprint !== registered.runtimeFingerprint)
@@ -22932,6 +23340,7 @@ function buildDebugMemoryUsage(runtimeHolders = {}) {
22932
23340
  const lkg = getLkgSlotHeapStats();
22933
23341
  const tagger = runtimeHolders.taggerCache ?? EMPTY_TAGGER_HEAP_STATS;
22934
23342
  const wire = runtimeHolders.wireCache ?? EMPTY_WIRE_HEAP_STATS;
23343
+ const replay = runtimeHolders.generateReplay ?? { totalBytes: 0, sessions: [] };
22935
23344
  const messageIndexQueue = getMessageIndexQueueHeapStats();
22936
23345
  const sessions = new Map;
22937
23346
  const session = (sessionId) => {
@@ -22945,7 +23354,8 @@ function buildDebugMemoryUsage(runtimeHolders = {}) {
22945
23354
  wireRawMessages: 0,
22946
23355
  wireMessages: 0,
22947
23356
  wireContentSnapshots: 0,
22948
- wireEstimatedBytes: 0
23357
+ wireEstimatedBytes: 0,
23358
+ generateReplayBytes: 0
22949
23359
  };
22950
23360
  sessions.set(sessionId, current);
22951
23361
  }
@@ -22965,6 +23375,8 @@ function buildDebugMemoryUsage(runtimeHolders = {}) {
22965
23375
  target.wireContentSnapshots += entry.rawContentSnapshots;
22966
23376
  target.wireEstimatedBytes += entry.estimatedBytes;
22967
23377
  }
23378
+ for (const entry of replay.sessions)
23379
+ session(entry.sessionId).generateReplayBytes += entry.bytes;
22968
23380
  return {
22969
23381
  pid: process.pid,
22970
23382
  bunVersion: typeof Bun !== "undefined" && typeof Bun.version === "string" ? Bun.version : "unavailable",
@@ -22995,6 +23407,10 @@ function buildDebugMemoryUsage(runtimeHolders = {}) {
22995
23407
  estimatedBytes: wire.estimatedBytes
22996
23408
  },
22997
23409
  compartmentMirrors: { entries: 0 },
23410
+ generateReplay: {
23411
+ sessionCount: replay.sessions.length,
23412
+ estimatedBytes: replay.totalBytes
23413
+ },
22998
23414
  messageIndexQueue,
22999
23415
  sessions: [...sessions.values()].sort((a, b) => a.sessionId.localeCompare(b.sessionId))
23000
23416
  }
@@ -23211,9 +23627,9 @@ function registerRpcHandlers(rpcServer, args) {
23211
23627
  return { count: buildCompartmentCount(db, sessionId, moduleStatus) };
23212
23628
  });
23213
23629
  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"));
23630
+ const { deriveHistorianChunkTokens, resolveHistorianContextLimit } = await importPluginModule(() => import("./derive-budgets-knf763tt.js"));
23631
+ const { resolveHistorianModel } = await importPluginModule(() => import("./model-resolution-280gmqvd.js"));
23632
+ const { userObservationCollectionEnabled, userObservationsRequested } = await importPluginModule(() => import("./task-config-7md27rx8.js"));
23217
23633
  const DEFAULT_HISTORIAN_TIMEOUT_MS = 10 * 60 * 1000;
23218
23634
  const runConfig = historianRunConfig(config, currentPluginConfigReader(directory)?.poll().effective ?? config);
23219
23635
  const historianModel = resolveHistorianModel(runConfig, "opencode");
@@ -23244,7 +23660,7 @@ function registerRpcHandlers(rpcServer, args) {
23244
23660
  return { ok: false, error: "no session" };
23245
23661
  const readDirectory = args.readSessionDirectory;
23246
23662
  if (readDirectory) {
23247
- const { handoffHistoryWork } = await import("./history-owner-42e16w0n.js");
23663
+ const { handoffHistoryWork } = await import("./history-owner-ad0crnrn.js");
23248
23664
  const handed = await handoffHistoryWork({
23249
23665
  storageDir: args.storageDir ?? getMagicContextStorageDir(),
23250
23666
  directory,
@@ -23263,8 +23679,8 @@ function registerRpcHandlers(rpcServer, args) {
23263
23679
  const db = readDatabase();
23264
23680
  if (!db)
23265
23681
  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"));
23682
+ const { runManagedRecomp } = await importPluginModule(() => import("./recomp-orchestrator-47m4hv5g.js"));
23683
+ const { sendIgnoredMessage } = await importPluginModule(() => import("./send-session-notification-nwvrv34d.js"));
23268
23684
  log2(`[rpc] recomp requested for session ${sessionId}`);
23269
23685
  if (!args.client && !args.hiddenCompletionExecutor) {
23270
23686
  return {
@@ -23322,7 +23738,7 @@ function registerRpcHandlers(rpcServer, args) {
23322
23738
  rpcServer.handle("wrapup", async (params) => {
23323
23739
  const readDirectory = args.readSessionDirectory;
23324
23740
  if (readDirectory && params.sessionId) {
23325
- const { handoffHistoryWork } = await import("./history-owner-42e16w0n.js");
23741
+ const { handoffHistoryWork } = await import("./history-owner-ad0crnrn.js");
23326
23742
  const sessionId = String(params.sessionId);
23327
23743
  const handed = await handoffHistoryWork({
23328
23744
  storageDir: args.storageDir ?? getMagicContextStorageDir(),
@@ -23348,7 +23764,7 @@ function registerRpcHandlers(rpcServer, args) {
23348
23764
  const db = readDatabase();
23349
23765
  if (!db)
23350
23766
  return { ok: false, error: "db unavailable" };
23351
- const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-embdz8gj.js"));
23767
+ const { runManagedWrapup } = await importPluginModule(() => import("./wrapup-orchestrator-639whfhq.js"));
23352
23768
  const model = liveSessionState.liveModelBySession.get(sessionId);
23353
23769
  const contextLimit = model ? resolveContextLimit(model.providerID, model.modelID, { db, sessionID: sessionId }) : 128000;
23354
23770
  const ctx = {
@@ -23433,8 +23849,17 @@ function subagentToolRefusal(db, toolId, sessionId, isInternalChild = () => fals
23433
23849
  function hideSubagentTools(draft, db) {
23434
23850
  if (!getOrCreateSessionMeta(db, draft.sessionID).isSubagent)
23435
23851
  return;
23852
+ removePrimaryOnlyTools(draft.tools);
23853
+ }
23854
+ function removePrimaryOnlyTools(tools) {
23436
23855
  for (const id of PRIMARY_ONLY_TOOLS)
23437
- delete draft.tools[id];
23856
+ delete tools[id];
23857
+ }
23858
+ function storedSubagentMode(db, sessionId) {
23859
+ const row = db.prepare("SELECT is_subagent FROM session_meta WHERE session_id = ?").get(sessionId);
23860
+ if (!row || typeof row.is_subagent !== "number")
23861
+ return;
23862
+ return row.is_subagent === 1;
23438
23863
  }
23439
23864
 
23440
23865
  // src/shared/conflict-detector.ts
@@ -24783,18 +25208,56 @@ function containsHostInstance(value) {
24783
25208
  return false;
24784
25209
  }
24785
25210
  function clonePreservingInstances(value) {
24786
- if (isHostInstance(value))
25211
+ return cloneCounting(value, undefined);
25212
+ }
25213
+ function clonePreservingInstancesMeasured(value) {
25214
+ const meter = { bytes: 0 };
25215
+ const copy = cloneCounting(value, meter);
25216
+ return { copy, bytes: meter.bytes };
25217
+ }
25218
+ function cloneCounting(value, meter) {
25219
+ if (isHostInstance(value)) {
25220
+ if (meter)
25221
+ meter.bytes += instanceBytes(value, new WeakSet);
24787
25222
  return value;
24788
- if (Array.isArray(value))
24789
- return value.map(clonePreservingInstances);
25223
+ }
25224
+ if (Array.isArray(value)) {
25225
+ if (meter)
25226
+ meter.bytes += 16 + 8 * value.length;
25227
+ return value.map((entry) => cloneCounting(entry, meter));
25228
+ }
24790
25229
  if (value && typeof value === "object") {
24791
25230
  const copy = {};
24792
- for (const [key, entry] of Object.entries(value))
24793
- copy[key] = clonePreservingInstances(entry);
25231
+ if (meter)
25232
+ meter.bytes += 32;
25233
+ for (const [key, entry] of Object.entries(value)) {
25234
+ if (meter)
25235
+ meter.bytes += 16;
25236
+ copy[key] = cloneCounting(entry, meter);
25237
+ }
24794
25238
  return copy;
24795
25239
  }
25240
+ if (meter)
25241
+ meter.bytes += typeof value === "string" ? 2 * value.length : 8;
24796
25242
  return value;
24797
25243
  }
25244
+ function instanceBytes(value, seen) {
25245
+ if (typeof value === "string")
25246
+ return 2 * value.length;
25247
+ if (!value || typeof value !== "object")
25248
+ return 8;
25249
+ if (seen.has(value))
25250
+ return 0;
25251
+ seen.add(value);
25252
+ if (ArrayBuffer.isView(value))
25253
+ return value.byteLength;
25254
+ if (value instanceof ArrayBuffer)
25255
+ return value.byteLength;
25256
+ let bytes = 32;
25257
+ for (const entry of Object.values(value))
25258
+ bytes += 16 + instanceBytes(entry, seen);
25259
+ return bytes;
25260
+ }
24798
25261
  function contentKey(value) {
24799
25262
  const plain = (entry) => {
24800
25263
  if (ArrayBuffer.isView(entry)) {
@@ -24850,7 +25313,7 @@ function rebuildFileContent(value, output, attachments) {
24850
25313
  rebuilt.unshift({ type: "text", text: output });
24851
25314
  return { type: "content", value: rebuilt };
24852
25315
  }
24853
- function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map) {
25316
+ function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map, hiddenTimes = false) {
24854
25317
  const existingHeads = new Map(draft.messages.filter((m) => HEAD_IDS.some((id) => m.id === id)).map((m) => [m.id, m]));
24855
25318
  const source = draft.messages.filter((m) => !existingHeads.has(m.id));
24856
25319
  const results = new Map;
@@ -24969,6 +25432,16 @@ function adaptPayload(draft, admittedIDs = new Set, messageTimes = new Map) {
24969
25432
  },
24970
25433
  parts
24971
25434
  };
25435
+ if (hiddenTimes && mapped.info.time !== undefined) {
25436
+ const time = mapped.info.time;
25437
+ delete mapped.info.time;
25438
+ Object.defineProperty(mapped.info, "time", {
25439
+ value: time,
25440
+ enumerable: false,
25441
+ configurable: true,
25442
+ writable: true
25443
+ });
25444
+ }
24972
25445
  originals.set(mapped, message);
24973
25446
  if (isCoveredInstructionRow(message))
24974
25447
  markCoveredInstructionRow(mapped.info);
@@ -26469,10 +26942,12 @@ function assistantText(row) {
26469
26942
 
26470
26943
  class HiddenProviderError extends Error {
26471
26944
  settled;
26945
+ hostError;
26472
26946
  constructor(detail, options = {}) {
26473
26947
  super(`Hidden completion provider error: ${detail}`);
26474
26948
  this.name = "HiddenProviderError";
26475
26949
  this.settled = options.settled ?? true;
26950
+ this.hostError = options.hostError;
26476
26951
  }
26477
26952
  }
26478
26953
  function requestModel(request, current) {
@@ -26536,7 +27011,9 @@ async function awaitAssistantRow(openReader, readSessionError, localFailure, chi
26536
27011
  `terminal_row=${errorText(newIdle)}`,
26537
27012
  `session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
26538
27013
  ];
26539
- throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
27014
+ throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`, {
27015
+ cause: sessionError
27016
+ }) : new HiddenProviderError(details.join("; "), { hostError: sessionError });
26540
27017
  }
26541
27018
  if (outcome === "succeeded" && newAssistant)
26542
27019
  return newAssistant;
@@ -26550,7 +27027,9 @@ async function awaitAssistantRow(openReader, readSessionError, localFailure, chi
26550
27027
  `terminal_row=${errorText(newAssistant)}`,
26551
27028
  `session_error=${sessionError === undefined ? "unavailable" : errorText(sessionError)}`
26552
27029
  ];
26553
- throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`) : new HiddenProviderError(details.join("; "));
27030
+ throw sessionError === undefined || !isProviderFailure(sessionError) ? new Error(`Hidden completion failed: ${details.join("; ")}`, {
27031
+ cause: sessionError
27032
+ }) : new HiddenProviderError(details.join("; "), { hostError: sessionError });
26554
27033
  }
26555
27034
  if (newAssistant.data.error !== undefined) {
26556
27035
  throw new HiddenProviderError(errorText(newAssistant.data.error), {
@@ -26705,7 +27184,13 @@ async function createV2HiddenCompletionExecutor(host, options) {
26705
27184
  const head = await resolveHead(identity);
26706
27185
  const active = await lifecycle.open(identity, role, head);
26707
27186
  openedChild = active;
26708
- const handle = { id: active.id, childSessionId: active.id };
27187
+ const configuredModel = toModelEntry(identity.model);
27188
+ const handle = {
27189
+ id: active.id,
27190
+ childSessionId: active.id,
27191
+ attemptedModel: modelKey(head),
27192
+ ...configuredModel?.sourceConfigKey ? { modelConfigKey: configuredModel.sourceConfigKey } : {}
27193
+ };
26709
27194
  const tokenBudget = identity.metadata?.tokenBudget;
26710
27195
  const run = {
26711
27196
  identity,
@@ -26736,6 +27221,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
26736
27221
  }
26737
27222
  },
26738
27223
  async attempt(handle, request) {
27224
+ const startedAt = Date.now();
26739
27225
  const run = runs.get(handle);
26740
27226
  if (!run)
26741
27227
  throw new Error("Unknown hidden completion run");
@@ -26753,6 +27239,10 @@ async function createV2HiddenCompletionExecutor(host, options) {
26753
27239
  throw new Error("Hidden completion prompt aborted");
26754
27240
  }
26755
27241
  const requested = await validateVariant(requestModel(request, run.child.model));
27242
+ const requestedRef = modelKey(requested);
27243
+ const configuredModel = [run.identity.model, ...run.identity.configuredModels ?? []].map(toModelEntry).find((entry) => entry?.model === requestedRef);
27244
+ handle.attemptedModel = requestedRef;
27245
+ handle.modelConfigKey = configuredModel?.sourceConfigKey ?? handle.modelConfigKey;
26756
27246
  if (run.identity.kind !== "dreamer-task" && request.body.temperature === undefined) {
26757
27247
  const configured = options.historianTemperature?.();
26758
27248
  if (typeof configured === "number" && Number.isFinite(configured))
@@ -26847,6 +27337,22 @@ async function createV2HiddenCompletionExecutor(host, options) {
26847
27337
  abortReject = reject;
26848
27338
  });
26849
27339
  const onAbort = () => {
27340
+ const reason = request.signal?.reason;
27341
+ if (reason instanceof ModelProducedNoOutputError && run.identity.kind === "dreamer-task") {
27342
+ recordChildInvocation({
27343
+ db: options.db,
27344
+ parentSessionId: run.identity.parentSessionId ?? options.projectIdentity,
27345
+ parentInvocationId: run.identity.parentInvocationId,
27346
+ harness: "opencode2",
27347
+ subagent: "dreamer",
27348
+ task: run.identity.title.replace(/^magic-context-dream-/, ""),
27349
+ startedAt,
27350
+ status: "timed_out",
27351
+ error: reason,
27352
+ providerId: requested.providerID,
27353
+ modelId: requested.modelID
27354
+ });
27355
+ }
26850
27356
  interruptAndRetire(run, "prompt-aborted").finally(() => abortReject(new Error("Hidden completion prompt aborted")));
26851
27357
  };
26852
27358
  const deadlineTimer = setTimeout(() => {
@@ -26875,6 +27381,9 @@ async function createV2HiddenCompletionExecutor(host, options) {
26875
27381
  })
26876
27382
  };
26877
27383
  inFlight.add(entry);
27384
+ const stopWatching = host.watchModelActivity?.(run.child.id, () => noteModelOutputReceived(request.signal));
27385
+ if (stopWatching)
27386
+ noteModelActivityMonitored(request.signal);
26878
27387
  try {
26879
27388
  await Promise.race([
26880
27389
  host.prompt({ sessionID: run.child.id, text: marker }),
@@ -26930,12 +27439,20 @@ async function createV2HiddenCompletionExecutor(host, options) {
26930
27439
  usage: reportedUsage ? usage : meter(system, promptText(request), text ?? ""),
26931
27440
  lengthCapped: ["length", "max_tokens"].includes(row.data.finish ?? ""),
26932
27441
  providerId: row.data.model?.providerID ?? requested.providerID,
26933
- modelId: row.data.model?.id ?? requested.modelID
27442
+ modelId: row.data.model?.id ?? requested.modelID,
27443
+ attemptedModel: requestedRef,
27444
+ modelConfigKey: handle.modelConfigKey
26934
27445
  };
26935
27446
  if (!run.child.ever_settled)
26936
27447
  run.child = lifecycle.markEverSettled(run.child);
26937
27448
  } catch (caught) {
26938
27449
  const error = attempt.budgetExceeded ?? attempt.stepLimit ?? attempt.refusal ?? caught;
27450
+ const hostError = error instanceof HiddenProviderError ? error.hostError : error instanceof Error && error.message.startsWith("Hidden completion failed:") ? error.cause : undefined;
27451
+ annotateSubagentInvocationError(error, {
27452
+ attemptedModel: handle.attemptedModel,
27453
+ modelConfigKey: handle.modelConfigKey,
27454
+ ...hostError === undefined ? {} : { hostError }
27455
+ });
26939
27456
  run.failed = true;
26940
27457
  if (!(error instanceof HiddenProviderError)) {
26941
27458
  run.unsettledFailure = true;
@@ -26949,6 +27466,7 @@ async function createV2HiddenCompletionExecutor(host, options) {
26949
27466
  }
26950
27467
  throw error;
26951
27468
  } finally {
27469
+ stopWatching?.();
26952
27470
  clearTimeout(deadlineTimer);
26953
27471
  if (budgetPoll)
26954
27472
  clearInterval(budgetPoll);
@@ -27004,6 +27522,30 @@ async function createV2HiddenCompletionExecutor(host, options) {
27004
27522
  };
27005
27523
  }
27006
27524
 
27525
+ // src/v2/hidden-model-activity.ts
27526
+ class HiddenModelActivity {
27527
+ watchers = new Map;
27528
+ watch(sessionID, onOutput) {
27529
+ this.watchers.set(sessionID, onOutput);
27530
+ return () => {
27531
+ if (this.watchers.get(sessionID) === onOutput)
27532
+ this.watchers.delete(sessionID);
27533
+ };
27534
+ }
27535
+ observe(event) {
27536
+ if (!isRecord(event) || !isRecord(event.data))
27537
+ return;
27538
+ const { sessionID, delta, text } = event.data;
27539
+ if (typeof sessionID !== "string")
27540
+ return;
27541
+ const streamed = ["session.text.delta", "session.reasoning.delta", "session.tool.input.delta"].includes(String(event.type)) && typeof delta === "string" && delta.length > 0;
27542
+ const ended = ["session.text.ended", "session.reasoning.ended"].includes(String(event.type)) && typeof text === "string" && text.length > 0;
27543
+ if (streamed || ended || event.type === "session.tool.input.started") {
27544
+ this.watchers.get(sessionID)?.();
27545
+ }
27546
+ }
27547
+ }
27548
+
27007
27549
  // src/v2/hooks/channel2.ts
27008
27550
  import { randomBytes as randomBytes2 } from "node:crypto";
27009
27551
  var pendingCandidates = new WeakMap;
@@ -27869,7 +28411,9 @@ async function compressOneChunk(args, chunk, sliceMs, signal) {
27869
28411
  status: "completed",
27870
28412
  tokens: run.output.usage,
27871
28413
  providerId: run.output.providerId,
27872
- modelId: run.output.modelId
28414
+ modelId: run.output.modelId,
28415
+ attemptedModel: args.model,
28416
+ configuredModels: args.fallbackModels
27873
28417
  });
27874
28418
  }
27875
28419
  stage = "apply";
@@ -28061,6 +28605,7 @@ async function runHiddenSingleShotPrompt(args) {
28061
28605
  });
28062
28606
  }).catch(() => {});
28063
28607
  const handle = await raceWithSignal(opening, args.signal);
28608
+ let completion;
28064
28609
  args.onOpened?.(handle.id);
28065
28610
  let promptSettled = false;
28066
28611
  try {
@@ -28082,7 +28627,10 @@ async function runHiddenSingleShotPrompt(args) {
28082
28627
  ...args.signal ? { signal: args.signal } : {},
28083
28628
  fallbackModels: args.fallbackModels,
28084
28629
  callContext: args.callContext,
28085
- fetchOutput: () => args.executor.collect(handle, 50),
28630
+ fetchOutput: async () => {
28631
+ completion = await args.executor.collect(handle, 50);
28632
+ return completion;
28633
+ },
28086
28634
  validateOutput: (completion) => {
28087
28635
  const tokens = completion.tokenLog ?? runTokenLog(undefined);
28088
28636
  sessionLog2(args.parentSessionId ?? "dreamer", `${args.callContext} response_chars=${(completion.text ?? completion.reasoning ?? "").length} ${formatRunTokenLog(tokens)}`);
@@ -28098,6 +28646,12 @@ async function runHiddenSingleShotPrompt(args) {
28098
28646
  promptSettled = true;
28099
28647
  return { validated: run.validated, completion: run.output, childSessionId: handle.id };
28100
28648
  } catch (error) {
28649
+ const configuredModel = toModelEntry(args.model);
28650
+ annotateSubagentInvocationError(error, {
28651
+ attemptedModel: completion?.attemptedModel ?? handle.attemptedModel ?? configuredModel?.model,
28652
+ modelConfigKey: completion?.modelConfigKey ?? handle.modelConfigKey ?? configuredModel?.sourceConfigKey,
28653
+ ...completion?.hostError === undefined ? {} : { hostError: completion.hostError }
28654
+ });
28101
28655
  if (args.onFailureOutput) {
28102
28656
  let timer;
28103
28657
  try {
@@ -28425,6 +28979,8 @@ If no promotions are warranted, return empty arrays. Always consume reviewed can
28425
28979
  startedAt,
28426
28980
  status: params.status,
28427
28981
  messages: params.messages,
28982
+ attemptedModel: args.model,
28983
+ configuredModels: args.fallbackModels,
28428
28984
  error: params.error
28429
28985
  });
28430
28986
  };
@@ -29212,6 +29768,8 @@ function recordInvocation(args, startedAt, params) {
29212
29768
  startedAt,
29213
29769
  status: params.status,
29214
29770
  messages: params.messages,
29771
+ attemptedModel: args.model,
29772
+ configuredModels: args.fallbackModels,
29215
29773
  ...params.completion && !params.completion.messages ? {
29216
29774
  tokens: params.completion.usage,
29217
29775
  providerId: params.completion.providerId,
@@ -29937,6 +30495,8 @@ Remember: output only the JSON object described by the system prompt.`;
29937
30495
  startedAt,
29938
30496
  status: params.status,
29939
30497
  messages: params.messages,
30498
+ attemptedModel: args.model,
30499
+ configuredModels: args.fallbackModels,
29940
30500
  error: params.error
29941
30501
  });
29942
30502
  };
@@ -30741,6 +31301,8 @@ async function confirmReadOnly(args, noteId, content, surfaceCondition, leaseSig
30741
31301
  startedAt,
30742
31302
  status: params.status,
30743
31303
  messages: params.messages,
31304
+ attemptedModel: args.model,
31305
+ configuredModels: args.fallbackModels,
30744
31306
  error: params.error
30745
31307
  });
30746
31308
  };
@@ -31655,12 +32217,14 @@ function recordInvocation2(args, startedAt, params) {
31655
32217
  recordChildInvocation({
31656
32218
  db: args.db,
31657
32219
  parentSessionId: args.parentSessionId,
31658
- harness: "opencode",
32220
+ harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
31659
32221
  subagent: "dreamer",
31660
32222
  task: "map-memories",
31661
32223
  startedAt,
31662
32224
  status: params.status,
31663
32225
  messages: params.messages,
32226
+ attemptedModel: args.model,
32227
+ configuredModels: args.fallbackModels,
31664
32228
  error: params.error
31665
32229
  });
31666
32230
  }
@@ -32285,12 +32849,14 @@ function recordInvocation3(args, startedAt, params) {
32285
32849
  recordChildInvocation({
32286
32850
  db: args.db,
32287
32851
  parentSessionId: args.parentSessionId,
32288
- harness: "opencode",
32852
+ harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
32289
32853
  subagent: "dreamer",
32290
32854
  task: "refresh-primers",
32291
32855
  startedAt,
32292
32856
  status: params.status,
32293
32857
  messages: params.messages,
32858
+ attemptedModel: args.model,
32859
+ configuredModels: args.fallbackModels,
32294
32860
  error: params.error
32295
32861
  });
32296
32862
  }
@@ -33891,12 +34457,14 @@ function recordInvocation4(args, startedAt, params) {
33891
34457
  recordChildInvocation({
33892
34458
  db: args.db,
33893
34459
  parentSessionId: args.parentSessionId,
33894
- harness: "opencode",
34460
+ harness: args.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
33895
34461
  subagent: "dreamer",
33896
34462
  task: args.forceBroad ? "verify-broad" : "verify",
33897
34463
  startedAt,
33898
34464
  status: params.status,
33899
34465
  messages: params.messages,
34466
+ attemptedModel: args.model,
34467
+ configuredModels: args.fallbackModels,
33900
34468
  error: params.error
33901
34469
  });
33902
34470
  }
@@ -34772,6 +35340,25 @@ async function runRetrospectiveTask(config, ctx, helpers) {
34772
35340
  let childSessionId = null;
34773
35341
  let hiddenHandle = null;
34774
35342
  let promptSettled = false;
35343
+ let invocationRecorded = false;
35344
+ const recordInvocation = (status, messages, error) => {
35345
+ if (!parent || !childSessionId || invocationRecorded)
35346
+ return;
35347
+ invocationRecorded = true;
35348
+ recordChildInvocation({
35349
+ db,
35350
+ parentSessionId: parent,
35351
+ harness: deps.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
35352
+ subagent: "dreamer",
35353
+ task: config.task,
35354
+ startedAt: helpers.invocationStartedAt,
35355
+ status,
35356
+ messages,
35357
+ attemptedModel: config.model,
35358
+ configuredModels: config.fallbackModels,
35359
+ error
35360
+ });
35361
+ };
34775
35362
  try {
34776
35363
  if (deps.hiddenCompletionExecutor) {
34777
35364
  hiddenHandle = await deps.hiddenCompletionExecutor.open({
@@ -34856,18 +35443,8 @@ async function runRetrospectiveTask(config, ctx, helpers) {
34856
35443
  return { ...run, output };
34857
35444
  };
34858
35445
  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
- }
35446
+ if (run)
35447
+ recordInvocation("completed", run.output);
34871
35448
  return completedWindow(watermark);
34872
35449
  };
34873
35450
  const userLines = renderGateUserLines(messages);
@@ -34960,6 +35537,7 @@ async function runRetrospectiveTask(config, ctx, helpers) {
34960
35537
  log2(`[dreamer] retrospective: flagged=${flagged.length} learnings=${learnings.length} memory=${applied.memoryWritten} observations=${applied.observationsInserted} dropped=${applied.observationsDropped} rejected=${applied.rejected.length}`);
34961
35538
  return finish(deepenRun, scan.maxScannedTs);
34962
35539
  } catch (error) {
35540
+ recordInvocation(abortController.signal.aborted ? "aborted" : failedInvocationStatus(error), undefined, error);
34963
35541
  if (!detectOverflow(error).isOverflow)
34964
35542
  throw error;
34965
35543
  const failures = (activeOverflow?.failures ?? 0) + 1;
@@ -35031,6 +35609,25 @@ async function runAgenticTask(config, ctx, helpers) {
35031
35609
  let childSessionId = null;
35032
35610
  let promptSettled = false;
35033
35611
  let expiredArchived = 0;
35612
+ let invocationRecorded = false;
35613
+ const recordInvocation = (status, messages, error) => {
35614
+ if (!parent || !childSessionId || invocationRecorded)
35615
+ return;
35616
+ invocationRecorded = true;
35617
+ recordChildInvocation({
35618
+ db,
35619
+ parentSessionId: parent,
35620
+ harness: deps.hiddenCompletionExecutor?.capabilities.harness ?? "opencode",
35621
+ subagent: "dreamer",
35622
+ task,
35623
+ startedAt: invocationStartedAt,
35624
+ status,
35625
+ messages,
35626
+ attemptedModel: config.model,
35627
+ configuredModels: config.fallbackModels,
35628
+ error
35629
+ });
35630
+ };
35034
35631
  try {
35035
35632
  let curateMemories;
35036
35633
  let curateCategory;
@@ -35119,6 +35716,9 @@ async function runAgenticTask(config, ctx, helpers) {
35119
35716
  callContext: `dreamer:${task}`,
35120
35717
  metadata: { tokenBudget: config.tokenBudget, onBudgetUpdate },
35121
35718
  allowEmpty: task === "curate",
35719
+ onOpened: (sessionId) => {
35720
+ childSessionId = sessionId;
35721
+ },
35122
35722
  model: config.model,
35123
35723
  fallbackModels: config.fallbackModels,
35124
35724
  language: task === "curate" ? config.language ?? deps.language : undefined,
@@ -35234,18 +35834,7 @@ async function runAgenticTask(config, ctx, helpers) {
35234
35834
  helpers.reportProgress(curateRefused, curateRefused);
35235
35835
  log2(`[dreamer] curate safety summary: refused=${curateRefused}`);
35236
35836
  }
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
- }
35837
+ recordInvocation("completed", run.output);
35249
35838
  if (task === "maintain-docs" && docsHashes && changes) {
35250
35839
  try {
35251
35840
  if (run.validated === "[]") {
@@ -35299,6 +35888,9 @@ async function runAgenticTask(config, ctx, helpers) {
35299
35888
  }
35300
35889
  } : {}
35301
35890
  };
35891
+ } catch (error) {
35892
+ recordInvocation(abortController.signal.aborted ? "aborted" : failedInvocationStatus(error), undefined, error);
35893
+ throw error;
35302
35894
  } finally {
35303
35895
  heartbeat.stop();
35304
35896
  if (childSessionId)
@@ -36561,26 +37153,70 @@ function generateReplayAnchor(messages) {
36561
37153
  return;
36562
37154
  return { id, tail: clonePreservingInstances(messages.slice(index + 1)) };
36563
37155
  }
37156
+ var DEFAULT_GENERATE_REPLAY_LIMITS = Object.freeze({
37157
+ maxSessions: 16,
37158
+ sessionMaxBytes: 128 * 1024 * 1024,
37159
+ totalMaxBytes: 256 * 1024 * 1024
37160
+ });
36564
37161
 
36565
37162
  class V2GenerateReplay {
36566
37163
  prefixes = new Map;
37164
+ totalBytes = 0;
37165
+ limits;
37166
+ constructor(limits = DEFAULT_GENERATE_REPLAY_LIMITS) {
37167
+ if (!Number.isSafeInteger(limits.maxSessions) || limits.maxSessions < 1 || !Number.isSafeInteger(limits.sessionMaxBytes) || limits.sessionMaxBytes < 1 || !Number.isSafeInteger(limits.totalMaxBytes) || limits.totalMaxBytes < 1)
37168
+ throw new Error("Generate replay limits must be positive integers");
37169
+ this.limits = { ...limits };
37170
+ }
36567
37171
  capture(draft, anchor) {
37172
+ this.forget(draft.sessionID);
36568
37173
  if (!anchor) {
36569
- this.prefixes.delete(draft.sessionID);
36570
37174
  sessionLog2(draft.sessionID, "generate replay capture skipped: no-anchor");
36571
37175
  return;
36572
37176
  }
37177
+ const parts = {
37178
+ anchor: clonePreservingInstancesMeasured(anchor),
37179
+ system: clonePreservingInstancesMeasured(draft.system),
37180
+ messages: clonePreservingInstancesMeasured(draft.messages),
37181
+ tools: clonePreservingInstancesMeasured(draft.tools)
37182
+ };
37183
+ const bytes = 256 + parts.anchor.bytes + parts.system.bytes + parts.messages.bytes + parts.tools.bytes;
37184
+ if (bytes > this.limits.sessionMaxBytes || bytes > this.limits.totalMaxBytes) {
37185
+ sessionLog2(draft.sessionID, `generate replay capture skipped: over-session-cap (${bytes} > ${Math.min(this.limits.sessionMaxBytes, this.limits.totalMaxBytes)} bytes)`);
37186
+ return;
37187
+ }
37188
+ while (this.prefixes.size > 0 && (this.prefixes.size >= this.limits.maxSessions || this.totalBytes + bytes > this.limits.totalMaxBytes)) {
37189
+ const oldest = this.prefixes.keys().next().value;
37190
+ if (oldest === undefined)
37191
+ break;
37192
+ this.forget(oldest);
37193
+ }
36573
37194
  this.prefixes.set(draft.sessionID, {
36574
- anchor: clonePreservingInstances(anchor),
37195
+ anchor: parts.anchor.copy,
36575
37196
  model: `${draft.model.providerID}/${draft.model.id}`,
36576
37197
  agent: draft.agent,
36577
- system: clonePreservingInstances(draft.system),
36578
- messages: clonePreservingInstances(draft.messages),
36579
- tools: clonePreservingInstances(draft.tools)
37198
+ system: parts.system.copy,
37199
+ messages: parts.messages.copy,
37200
+ tools: parts.tools.copy,
37201
+ bytes
36580
37202
  });
37203
+ this.totalBytes += bytes;
36581
37204
  }
36582
37205
  forget(sessionID) {
37206
+ const prefix = this.prefixes.get(sessionID);
37207
+ if (!prefix)
37208
+ return;
36583
37209
  this.prefixes.delete(sessionID);
37210
+ this.totalBytes -= prefix.bytes;
37211
+ }
37212
+ stats() {
37213
+ return {
37214
+ totalBytes: this.totalBytes,
37215
+ sessions: [...this.prefixes].map(([sessionId, prefix]) => ({
37216
+ sessionId,
37217
+ bytes: prefix.bytes
37218
+ }))
37219
+ };
36584
37220
  }
36585
37221
  apply(draft) {
36586
37222
  const prefix = this.prefixes.get(draft.sessionID);
@@ -36590,6 +37226,8 @@ class V2GenerateReplay {
36590
37226
  };
36591
37227
  if (!prefix)
36592
37228
  return skip("no-prefix");
37229
+ this.prefixes.delete(draft.sessionID);
37230
+ this.prefixes.set(draft.sessionID, prefix);
36593
37231
  if (prefix.model !== `${draft.model.providerID}/${draft.model.id}`)
36594
37232
  return skip("model-mismatch");
36595
37233
  if (prefix.agent !== draft.agent)
@@ -36633,21 +37271,25 @@ function identity(slot) {
36633
37271
 
36634
37272
  class V2LkgSystemReplay {
36635
37273
  systems = new BoundedSessionMap(1000);
36636
- capture(sessionId, slot, input, served) {
37274
+ capture(sessionId, slot, input, served, head) {
36637
37275
  this.systems.set(sessionId, {
36638
37276
  slot: identity(slot),
36639
- input: JSON.stringify(input),
36640
- served: structuredClone(served)
37277
+ input: hostInputKey(input),
37278
+ served: structuredClone(served),
37279
+ head: head ? structuredClone(head) : null
36641
37280
  });
36642
37281
  }
36643
37282
  restore(sessionId, slot, input, target) {
36644
37283
  const saved = this.systems.get(sessionId);
36645
- if (!slot || !saved || saved.slot !== identity(slot) || saved.input !== JSON.stringify(input))
36646
- return false;
37284
+ if (!slot || !saved || saved.slot !== identity(slot) || saved.input !== hostInputKey(input))
37285
+ return;
36647
37286
  target.splice(0, target.length, ...structuredClone(saved.served));
36648
- return true;
37287
+ return { head: saved.head ? structuredClone(saved.head) : null };
36649
37288
  }
36650
37289
  }
37290
+ function hostInputKey(input) {
37291
+ return JSON.stringify({ system: input.system, checkpoint: input.checkpoint });
37292
+ }
36651
37293
 
36652
37294
  // src/v2/hooks/model-limit-cache.ts
36653
37295
  var warmStarted = false;
@@ -51281,7 +51923,7 @@ function createCtxReduceTool(deps) {
51281
51923
  args = unwrapImitatedReducedArgs(args, ["drop"], { drop: "string" });
51282
51924
  const sessionId = toolContext.sessionID;
51283
51925
  if (!args.drop) {
51284
- return "Error: 'drop' must be provided.";
51926
+ return `Error: 'drop' must be provided as a string of tag numbers, for example {"drop": "3-5,8"}.`;
51285
51927
  }
51286
51928
  const rustReduce = deps.rustToolBackends?.reduce;
51287
51929
  if (rustReduce) {
@@ -51566,6 +52208,7 @@ function createCtxSearchTool(deps) {
51566
52208
  explicitSearch: true,
51567
52209
  rerankConnectionFile: deps.rerankConnectionFile,
51568
52210
  searchMessageHistory: (request) => searchMessageHistoryOffThread(deps.db, request),
52211
+ signal: toolContext.abort,
51569
52212
  ...dateRange
51570
52213
  });
51571
52214
  return formatSearchResults2(query, results, toolContext.sessionID, diagnostics);
@@ -51684,6 +52327,13 @@ function bindV2TransformDecision(args) {
51684
52327
  }
51685
52328
 
51686
52329
  // src/hooks/magic-context/auto-embed-session.ts
52330
+ function localPoolingPreflightPending(projectIdentity) {
52331
+ const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
52332
+ if (snapshot?.provider !== "local")
52333
+ return false;
52334
+ const metadata = getCachedLocalEmbeddingPooling(snapshot.model);
52335
+ return !metadata || metadata.status === "unresolved";
52336
+ }
51687
52337
  function embeddingIdentity(projectIdentity) {
51688
52338
  const snapshot = getProjectEmbeddingSnapshot2(projectIdentity);
51689
52339
  return JSON.stringify([
@@ -51704,7 +52354,8 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51704
52354
  invalidateAutoEmbedSession(sessionId);
51705
52355
  autoEmbedIdentityBySession.set(sessionId, identity);
51706
52356
  }
51707
- if (autoEmbedAttemptedBySession.has(sessionId) || embedPauseBySession.has(sessionId) || embedRunStateBySession.has(sessionId) || Date.now() < (autoEmbedRetryAfterBySession.get(sessionId) ?? 0))
52357
+ const poolingPreflightPending = localPoolingPreflightPending(deps.projectIdentity);
52358
+ if (embedPauseBySession.has(sessionId) || embedRunStateBySession.has(sessionId) || Date.now() < (autoEmbedRetryAfterBySession.get(sessionId) ?? 0) || autoEmbedAttemptedBySession.has(sessionId) && !poolingPreflightPending)
51708
52359
  return;
51709
52360
  const controller = new AbortController;
51710
52361
  embedRunStateBySession.set(sessionId, controller);
@@ -51714,6 +52365,7 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51714
52365
  let started = false;
51715
52366
  let reason = "error";
51716
52367
  let registeredIdentity = identity;
52368
+ let poolingPendingAfterRegistration = poolingPreflightPending;
51717
52369
  try {
51718
52370
  await new Promise((resolve) => setTimeout(resolve, 0));
51719
52371
  if (controller.signal.aborted)
@@ -51721,6 +52373,7 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51721
52373
  await deps.ensureRegistered();
51722
52374
  if (controller.signal.aborted)
51723
52375
  return;
52376
+ poolingPendingAfterRegistration = localPoolingPreflightPending(deps.projectIdentity);
51724
52377
  markActive();
51725
52378
  registeredIdentity = embeddingIdentity(deps.projectIdentity);
51726
52379
  autoEmbedIdentityBySession.set(sessionId, registeredIdentity);
@@ -51728,7 +52381,9 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51728
52381
  if (controller.signal.aborted || !coverage.enabled)
51729
52382
  return;
51730
52383
  if (coverage.embedded === coverage.total) {
51731
- complete = true;
52384
+ complete = !poolingPendingAfterRegistration;
52385
+ if (!complete)
52386
+ retryDelay = 60000;
51732
52387
  return;
51733
52388
  }
51734
52389
  const model = getProjectEmbeddingSnapshot2(deps.projectIdentity)?.model;
@@ -51737,8 +52392,11 @@ function maybeAutoEmbedSessionBackfill(deps, sessionId) {
51737
52392
  const outcome = await embedSessionCompartmentChunks2(deps.db, deps.projectIdentity, sessionId, { signal: controller.signal, automatic: true });
51738
52393
  reason = outcome.status;
51739
52394
  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") {
52395
+ complete = after.enabled && after.embedded === after.total && !poolingPendingAfterRegistration;
52396
+ if (poolingPendingAfterRegistration) {
52397
+ retryDelay = 60000;
52398
+ reason = "pooling metadata unavailable";
52399
+ } else if (!complete && outcome.status !== "busy" && outcome.status !== "aborted") {
51742
52400
  retryDelay = 60000;
51743
52401
  if (outcome.status === "nothing" || outcome.status === "done")
51744
52402
  reason = "deferred";
@@ -51894,6 +52552,26 @@ function persistV2UsageReading(args) {
51894
52552
  // src/v2/hooks/context.ts
51895
52553
  class V2LkgAdmissionReplay extends Error {
51896
52554
  }
52555
+ function applyCheckpointHead(draft, head) {
52556
+ const { checkpoint, submitted } = head;
52557
+ const first = draft.messages.find((message) => message.id === HEAD_IDS[0]);
52558
+ const baseline = first?.content.find((part) => part.type === "text")?.text;
52559
+ if (typeof baseline !== "string")
52560
+ return false;
52561
+ for (const part of checkpoint.content)
52562
+ if (part.type === "text" && typeof part.text === "string") {
52563
+ part.text = part.text.replace(`<summary>
52564
+ ${submitted}
52565
+ </summary>`, `<summary>
52566
+ ${baseline}
52567
+ </summary>`);
52568
+ }
52569
+ const volatile = draft.messages.find((message) => message.id === HEAD_IDS[1]);
52570
+ if (volatile && first)
52571
+ volatile.content.push(...first.content.filter((part) => part.type !== "text"));
52572
+ draft.messages.splice(0, draft.messages.length, checkpoint, ...draft.messages.filter((message) => message !== first));
52573
+ return true;
52574
+ }
51897
52575
  var HIDDEN_SESSION_ERROR_GRACE_MS = 50;
51898
52576
  var STORE_POOL_DISPOSE_WAIT_MS = 1000;
51899
52577
  function isBlockingV2TransformError(error) {
@@ -52126,6 +52804,7 @@ async function registerContext(context) {
52126
52804
  const queriedModels = new Set;
52127
52805
  const rawLimits = new Map;
52128
52806
  const hiddenSessionErrors = new Map;
52807
+ const hiddenModelActivity = new HiddenModelActivity;
52129
52808
  const liveModels = new Map;
52130
52809
  const promptSurfaceRuntime = createPromptSurfaceRuntime({
52131
52810
  harness: "opencode2",
@@ -52220,6 +52899,7 @@ async function registerContext(context) {
52220
52899
  await cleanupLegacyOnce(database);
52221
52900
  return createV2HiddenCompletionExecutor({
52222
52901
  ...context.session,
52902
+ watchModelActivity: (sessionID, onOutput) => hiddenModelActivity.watch(sessionID, onOutput),
52223
52903
  get: async (input) => {
52224
52904
  const session = await context.session.get(input);
52225
52905
  const error = hiddenSessionErrors.get(input.sessionID);
@@ -52561,6 +53241,7 @@ async function registerContext(context) {
52561
53241
  break;
52562
53242
  const event = value;
52563
53243
  try {
53244
+ hiddenModelActivity.observe(event);
52564
53245
  if (event.type === "provider.updated" || event.type === "model.updated") {
52565
53246
  queriedModels.clear();
52566
53247
  continue;
@@ -52595,34 +53276,47 @@ async function registerContext(context) {
52595
53276
  if (event.type === "session.deleted") {
52596
53277
  clearLkgMeasuredRequest(sessionID);
52597
53278
  deletedSessions.add(sessionID);
52598
- transform?.clearSessionLogState(sessionID);
52599
- if (db) {
52600
- markSessionCleanupPending(db, sessionID);
52601
- clearSession(db, sessionID);
53279
+ const failures = [];
53280
+ try {
53281
+ transform?.clearSessionLogState(sessionID);
53282
+ if (db) {
53283
+ markSessionCleanupPending(db, sessionID);
53284
+ clearSession(db, sessionID, false, true);
53285
+ }
53286
+ } catch (error) {
53287
+ failures.push(error);
52602
53288
  }
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);
53289
+ try {
53290
+ rawProviders.get(sessionID)?.();
53291
+ rawProviders.delete(sessionID);
53292
+ usage.delete(sessionID);
53293
+ hiddenSessionErrors.delete(sessionID);
53294
+ storageNoticeBySession.delete(sessionID);
53295
+ liveModels.delete(sessionID);
53296
+ variants.delete(sessionID);
53297
+ agents.delete(sessionID);
53298
+ channel1.delete(sessionID);
53299
+ commitSeenLastPass.delete(sessionID);
53300
+ clearEmbedSessionState(sessionID);
53301
+ historyRefreshSessions.delete(sessionID);
53302
+ clearPendingMaterialization(pendingMaterializationSessions, sessionID);
53303
+ lastHeuristicsTurnId.delete(sessionID);
53304
+ restoredRows.forget(sessionID);
53305
+ if (nativeFoldReplay)
53306
+ await nativeFoldReplay.forget(sessionID);
53307
+ else
53308
+ await forgetNativeFoldProvenance(context.storage, sessionID);
53309
+ generateReplay.forget(sessionID);
53310
+ systemPromptRefreshSessions.delete(sessionID);
53311
+ systemPrompt?.clearSession(sessionID);
53312
+ tagger.cleanup(sessionID);
53313
+ } catch (error) {
53314
+ failures.push(error);
53315
+ }
53316
+ if (failures.length === 1)
53317
+ throw failures[0];
53318
+ if (failures.length > 1)
53319
+ throw new AggregateError(failures, "session deletion failed in both the store clear and the in-memory cleanup");
52626
53320
  continue;
52627
53321
  }
52628
53322
  if (event.type !== "session.execution.succeeded")
@@ -52740,6 +53434,42 @@ async function registerContext(context) {
52740
53434
  reader.close();
52741
53435
  }
52742
53436
  });
53437
+ const temporalTimes = config.temporal_awareness === true;
53438
+ const anchorTimesOnly = !temporalTimes && !rustModeModuleClient;
53439
+ const timeIds = (messages) => {
53440
+ if (temporalTimes)
53441
+ return messages.flatMap((message) => message.id ? [message.id] : []);
53442
+ if (!anchorTimesOnly)
53443
+ return [];
53444
+ const ids = [];
53445
+ for (const message of [...messages].reverse()) {
53446
+ if (message.id)
53447
+ ids.push(message.id);
53448
+ if (message.role === "assistant")
53449
+ break;
53450
+ }
53451
+ return ids;
53452
+ };
53453
+ const restoreAfterCheckpoint = (args) => {
53454
+ const { db, reader, draft, cut, boundaryRepair } = args;
53455
+ const moduleBoundaryID = rustModeModuleClient ? getPersistedCompactionMarkerState(db, draft.sessionID)?.boundaryMessageId ?? null : null;
53456
+ const moduleBoundarySeq = moduleBoundaryID ? reader.sequenceForId(draft.sessionID, moduleBoundaryID) : undefined;
53457
+ 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);
53458
+ const servedBoundary = boundaryID ? servedBoundaryRow(reader, draft.sessionID, boundaryID) : null;
53459
+ 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;
53460
+ if (moduleBoundarySeq !== undefined)
53461
+ sessionLog2(draft.sessionID, `v2 restore: from the module boundary ${moduleBoundaryID} to the host checkpoint`);
53462
+ const present = new Set(args.messages.map((message) => message.id));
53463
+ const restored = restoredRows.rows(reader, draft.sessionID, boundary, cut.seq).filter((row) => !present.has(row.id)).flatMap((row) => restoreRow(row, draft.model, hostUsesMediaAssets() ? {
53464
+ asset: hostMediaAsset,
53465
+ 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)}`)
53466
+ } : undefined));
53467
+ return [
53468
+ ...rustModeModuleClient ? [] : coveredInstructionRows(reader, draft.sessionID, Math.min(boundary, cut.seq), draft.model),
53469
+ ...restored,
53470
+ ...args.messages.filter((message) => message !== args.incoming)
53471
+ ];
53472
+ };
52743
53473
  const runManagedContext = async (draft) => {
52744
53474
  rememberHostMedia(draft.messages);
52745
53475
  if (hiddenChildHook.apply(draft))
@@ -52751,12 +53481,18 @@ async function registerContext(context) {
52751
53481
  return;
52752
53482
  const systemAtEntry = structuredClone(draft.system);
52753
53483
  const slotAtEntry = getSlot(draft.sessionID);
53484
+ let checkpointAtEntry;
53485
+ let replayHead;
53486
+ const hostInput = () => checkpointAtEntry === undefined ? undefined : { system: systemAtEntry, checkpoint: checkpointAtEntry };
52754
53487
  const restoreLkgSystem = () => {
52755
53488
  retirePendingSystemPromptDelivery(draft.sessionID);
52756
- if (!lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), systemAtEntry, draft.system)) {
53489
+ const input = hostInput();
53490
+ const restored = input && lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), input, draft.system);
53491
+ if (!restored) {
52757
53492
  sessionLog2(draft.sessionID, "lkg_system_state_mismatch");
52758
53493
  throw new Error("LKG system identity is unavailable or changed");
52759
53494
  }
53495
+ replayHead = restored.head;
52760
53496
  };
52761
53497
  const isMagicContextSynthetic = (id) => isAdmittedSynthetic(context, draft.sessionID, id);
52762
53498
  const newest = draft.messages.at(-1);
@@ -52765,6 +53501,24 @@ async function registerContext(context) {
52765
53501
  return;
52766
53502
  }
52767
53503
  await dropStorageNotices(draft.messages, isMagicContextSynthetic);
53504
+ const hostMessagesAtEntry = [...draft.messages];
53505
+ const passTimes = new Map;
53506
+ const readTimes = (reader, messages) => {
53507
+ const ids = timeIds(messages);
53508
+ const missing = ids.filter((id) => !passTimes.has(id));
53509
+ if (missing.length > 0) {
53510
+ const read = reader.messageTimes(draft.sessionID, missing);
53511
+ for (const id of missing)
53512
+ passTimes.set(id, read.get(id) ?? null);
53513
+ }
53514
+ const times = new Map;
53515
+ for (const id of ids) {
53516
+ const time = passTimes.get(id);
53517
+ if (time)
53518
+ times.set(id, time);
53519
+ }
53520
+ return times;
53521
+ };
52768
53522
  liveModels.set(draft.sessionID, {
52769
53523
  providerID: draft.model.providerID,
52770
53524
  modelID: draft.model.id
@@ -52776,8 +53530,9 @@ async function registerContext(context) {
52776
53530
  applyV2PromptSurfaceTools(draft, promptSurfaceRuntime, config.prompt_surface, isSmartNoteSurfaceAvailable(config));
52777
53531
  const admissionDb = db ?? storage.current();
52778
53532
  const replayFits = (messages) => {
52779
- const system = structuredClone(draft.system);
52780
- if (!admissionDb || !draft.tools || !lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), draft.system, system))
53533
+ const system = [];
53534
+ const input = hostInput();
53535
+ if (!admissionDb || !draft.tools || !input || !lkgSystems.restore(draft.sessionID, getSlot(draft.sessionID), input, system))
52781
53536
  return false;
52782
53537
  const limit = lkgReplayLimit({
52783
53538
  db: admissionDb,
@@ -52812,14 +53567,75 @@ async function registerContext(context) {
52812
53567
  })
52813
53568
  }).fit === "under";
52814
53569
  };
53570
+ const buildReplayInput = async () => {
53571
+ let messages = [...hostMessagesAtEntry];
53572
+ const admitted = new Set;
53573
+ let times;
53574
+ try {
53575
+ const reader = openStoreReader();
53576
+ try {
53577
+ const cut = reader.latestCompaction(draft.sessionID);
53578
+ const localCut = cut && isLocalCheckpoint(cut) ? cut : undefined;
53579
+ const incoming = localCut && messages.find((message) => message.id === localCut.id);
53580
+ if (localCut && !incoming || cut && nativeFoldReplay)
53581
+ return;
53582
+ checkpointAtEntry = incoming || null;
53583
+ const modeDb = db ?? storage.current();
53584
+ const subagent = modeDb ? storedSubagentMode(modeDb, draft.sessionID) : undefined;
53585
+ if (subagent === undefined)
53586
+ return;
53587
+ if (subagent)
53588
+ removePrimaryOnlyTools(draft.tools);
53589
+ if (!rustModeModuleClient) {
53590
+ const candidates = syntheticCandidates(context, draft.sessionID, reader.syntheticMessageIDs(draft.sessionID));
53591
+ for (const message of messages)
53592
+ if (message.id && candidates.has(message.id) && await isAdmittedSynthetic(context, draft.sessionID, message.id))
53593
+ admitted.add(message.id);
53594
+ const replayDb = db ?? storage.current();
53595
+ if (localCut && incoming && replayDb)
53596
+ messages = restoreAfterCheckpoint({
53597
+ db: replayDb,
53598
+ reader,
53599
+ draft,
53600
+ messages,
53601
+ cut: localCut,
53602
+ incoming,
53603
+ boundaryRepair: undefined
53604
+ });
53605
+ else if (localCut)
53606
+ return;
53607
+ times = readTimes(reader, messages);
53608
+ }
53609
+ } finally {
53610
+ reader.close();
53611
+ }
53612
+ } catch (error) {
53613
+ sessionLog2(draft.sessionID, "lkg replay input unavailable", error);
53614
+ return;
53615
+ }
53616
+ const replayDraft = { ...draft, messages };
53617
+ return {
53618
+ draft: replayDraft,
53619
+ mapped: adaptPayload(replayDraft, admitted, times, anchorTimesOnly)
53620
+ };
53621
+ };
53622
+ const adoptReplay = (replayed) => {
53623
+ if (replayed !== draft)
53624
+ draft.messages.splice(0, draft.messages.length, ...replayed.messages);
53625
+ if (replayHead)
53626
+ applyCheckpointHead(draft, replayHead);
53627
+ };
52815
53628
  let postFold = false;
52816
53629
  try {
52817
53630
  if (!compactionOff && admissionDb)
52818
53631
  await withAsyncPrivilegedWriter2(admissionDb, () => {
52819
53632
  return;
52820
53633
  }, {
52821
- beforeRetry: (error) => {
52822
- const mapped = adaptPayload(draft);
53634
+ beforeRetry: async (error) => {
53635
+ const input = await buildReplayInput();
53636
+ if (!input)
53637
+ return;
53638
+ const { mapped } = input;
52823
53639
  if (tryMessagesTransformLkgReplay({
52824
53640
  output: mapped,
52825
53641
  sessionId: draft.sessionID,
@@ -52830,6 +53646,7 @@ async function registerContext(context) {
52830
53646
  onLkgReplay: restoreLkgSystem
52831
53647
  })) {
52832
53648
  mapped.commit();
53649
+ adoptReplay(input.draft);
52833
53650
  throw new V2LkgAdmissionReplay;
52834
53651
  }
52835
53652
  }
@@ -53024,6 +53841,7 @@ async function registerContext(context) {
53024
53841
  postFold = cut !== undefined;
53025
53842
  if (localCut && !incoming)
53026
53843
  throw new Error("The host checkpoint disappeared from the context draft");
53844
+ checkpointAtEntry = incoming || null;
53027
53845
  let nativeRestored;
53028
53846
  if (cut && nativeFoldReplay && await nativeFoldReplay.admits(draft.sessionID, cut, reader)) {
53029
53847
  try {
@@ -53065,22 +53883,17 @@ async function registerContext(context) {
53065
53883
  checkpoint = structuredClone(identity.rendered ?? incoming);
53066
53884
  submitted = identity.rendered ? identity.renderedSummary ?? identity.submitted : cut.data.summary ?? "";
53067
53885
  }
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] : []));
53886
+ draft.messages.splice(0, draft.messages.length, ...restoreAfterCheckpoint({
53887
+ db,
53888
+ reader,
53889
+ draft,
53890
+ messages: draft.messages,
53891
+ cut: localCut,
53892
+ incoming,
53893
+ boundaryRepair
53894
+ }));
53895
+ }
53896
+ messageTimes = readTimes(reader, draft.messages);
53084
53897
  } finally {
53085
53898
  reader.close();
53086
53899
  }
@@ -53097,7 +53910,7 @@ async function registerContext(context) {
53097
53910
  nativeFoldReplay.invalidate(draft.sessionID, true);
53098
53911
  }
53099
53912
  }
53100
- const mapped = adaptPayload(draft, admitted, messageTimes);
53913
+ const mapped = adaptPayload(draft, admitted, messageTimes, anchorTimesOnly);
53101
53914
  bindSystemDateRequestIdentity(mapped, draft);
53102
53915
  await createMessagesTransformHandler({
53103
53916
  magicContext: { "experimental.chat.messages.transform": transform },
@@ -53114,24 +53927,9 @@ async function registerContext(context) {
53114
53927
  if (db) {
53115
53928
  await deliverPendingChannel2(context, db, draft.sessionID, channel1.get(draft.sessionID));
53116
53929
  }
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
- }
53930
+ const head = replayHead !== undefined ? replayHead : checkpoint && submitted !== undefined ? { checkpoint, submitted } : null;
53931
+ const servedHead = head && structuredClone(head);
53932
+ const headApplied = head ? applyCheckpointHead(draft, head) : false;
53135
53933
  if (nativeMessages && !checkpoint) {
53136
53934
  try {
53137
53935
  await nativeFoldReplay?.capture(draft, nativeMessages);
@@ -53142,7 +53940,7 @@ ${baseline}
53142
53940
  }
53143
53941
  const capturedSlot = getSlot(draft.sessionID);
53144
53942
  if (capturedSlot && (!slotAtEntry || capturedSlot.capturedAt !== slotAtEntry.capturedAt || capturedSlot.captureSequence !== slotAtEntry.captureSequence || capturedSlot.jsonPrefix !== slotAtEntry.jsonPrefix)) {
53145
- lkgSystems.capture(draft.sessionID, capturedSlot, systemAtEntry, draft.system);
53943
+ lkgSystems.capture(draft.sessionID, capturedSlot, { system: systemAtEntry, checkpoint: checkpointAtEntry ?? null }, draft.system, headApplied ? servedHead : null);
53146
53944
  }
53147
53945
  } catch (error) {
53148
53946
  if (error instanceof V2LkgAdmissionReplay)
@@ -53151,8 +53949,11 @@ ${baseline}
53151
53949
  throw error;
53152
53950
  if (!compactionOff && (isTransientSqliteError2(error) || error instanceof StorageBusyRefusalError)) {
53153
53951
  if (isTransientSqliteError2(error)) {
53154
- const mapped = adaptPayload(draft);
53952
+ const input = await buildReplayInput();
53155
53953
  try {
53954
+ if (!input)
53955
+ throw new StorageBusyRefusalError(error, "v2-context");
53956
+ const { mapped } = input;
53156
53957
  await createMessagesTransformHandler({
53157
53958
  replayFits,
53158
53959
  onLkgReplay: restoreLkgSystem,
@@ -53164,6 +53965,7 @@ ${baseline}
53164
53965
  }
53165
53966
  })({}, mapped);
53166
53967
  mapped.commit();
53968
+ adoptReplay(input.draft);
53167
53969
  return;
53168
53970
  } catch (replayError) {
53169
53971
  if (!(replayError instanceof StorageBusyRefusalError))
@@ -53245,7 +54047,8 @@ ${baseline}
53245
54047
  return null;
53246
54048
  }
53247
54049
  },
53248
- storageDir
54050
+ storageDir,
54051
+ getDebugMemoryHolders: () => ({ generateReplay: generateReplay.stats() })
53249
54052
  });
53250
54053
  rpcServer.handle("dream", async (params) => {
53251
54054
  const sessionId = String(params.sessionId ?? "");