@cortexkit/opencode-magic-context 0.45.0 → 0.46.0

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 (385) hide show
  1. package/README.md +26 -0
  2. package/dist/{announcement-f75t58v9.js → announcement-y35wzg2r.js} +1 -1
  3. package/dist/config/index.d.ts.map +1 -1
  4. package/dist/config/live-run-config.d.ts.map +1 -1
  5. package/dist/config/migrate-config-location.d.ts.map +1 -1
  6. package/dist/config/schema/magic-context.d.ts +10 -4
  7. package/dist/config/schema/magic-context.d.ts.map +1 -1
  8. package/dist/{conflict-warning-hook-5yrz2r24.js → conflict-warning-hook-7fj2b9jw.js} +6 -5
  9. package/dist/context-8dkpszy5.js +4483 -0
  10. package/dist/{derive-budgets-a63zsm5c.js → derive-budgets-7nj7r1rv.js} +2 -2
  11. package/dist/embedding-worker.js +4 -4
  12. package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts +45 -0
  13. package/dist/features/magic-context/checkout-claim-fake-subc.test-support.d.ts.map +1 -0
  14. package/dist/features/magic-context/checkout-claim.d.ts +155 -0
  15. package/dist/features/magic-context/checkout-claim.d.ts.map +1 -0
  16. package/dist/features/magic-context/compaction-marker.d.ts +20 -3
  17. package/dist/features/magic-context/compaction-marker.d.ts.map +1 -1
  18. package/dist/features/magic-context/compartment-storage.d.ts +23 -2
  19. package/dist/features/magic-context/compartment-storage.d.ts.map +1 -1
  20. package/dist/features/magic-context/dreamer/classify.d.ts.map +1 -1
  21. package/dist/features/magic-context/dreamer/evaluate-smart-notes.d.ts.map +1 -1
  22. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts +6 -2
  23. package/dist/features/magic-context/dreamer/provider-output-failure.d.ts.map +1 -1
  24. package/dist/features/magic-context/dreamer/provider-output-failure.test-support.d.ts +30 -0
  25. package/dist/features/magic-context/dreamer/provider-output-failure.test-support.d.ts.map +1 -0
  26. package/dist/features/magic-context/dreamer/storage-dream-runs.d.ts.map +1 -1
  27. package/dist/features/magic-context/dreamer/task-executor.d.ts +9 -0
  28. package/dist/features/magic-context/dreamer/task-executor.d.ts.map +1 -1
  29. package/dist/features/magic-context/dreamer/task-gates.d.ts.map +1 -1
  30. package/dist/features/magic-context/dreamer/task-scheduler.d.ts.map +1 -1
  31. package/dist/features/magic-context/dreamer/verify-diff.d.ts.map +1 -1
  32. package/dist/features/magic-context/dreamer/verify-gate.d.ts.map +1 -1
  33. package/dist/features/magic-context/dreamer/verify.d.ts.map +1 -1
  34. package/dist/features/magic-context/git-commits/search-git-commits.d.ts.map +1 -1
  35. package/dist/features/magic-context/memory/embedding-local.d.ts.map +1 -1
  36. package/dist/features/magic-context/memory/project-identity-cache.d.ts.map +1 -1
  37. package/dist/features/magic-context/memory/storage-memory-verifications.d.ts.map +1 -1
  38. package/dist/features/magic-context/memory/storage-memory.d.ts +3 -0
  39. package/dist/features/magic-context/memory/storage-memory.d.ts.map +1 -1
  40. package/dist/features/magic-context/memory/verification-paths.d.ts +2 -2
  41. package/dist/features/magic-context/memory/verification-paths.d.ts.map +1 -1
  42. package/dist/features/magic-context/merged-reasoning-decisions.d.ts.map +1 -1
  43. package/dist/features/magic-context/message-index-async.d.ts +3 -3
  44. package/dist/features/magic-context/message-index-async.d.ts.map +1 -1
  45. package/dist/features/magic-context/message-index.d.ts +2 -0
  46. package/dist/features/magic-context/message-index.d.ts.map +1 -1
  47. package/dist/features/magic-context/migration-v95-perf-indexes.d.ts +12 -0
  48. package/dist/features/magic-context/migration-v95-perf-indexes.d.ts.map +1 -0
  49. package/dist/features/magic-context/migration-worker-client.d.ts +4 -4
  50. package/dist/features/magic-context/migration-worker-client.d.ts.map +1 -1
  51. package/dist/features/magic-context/migrations.d.ts +1 -0
  52. package/dist/features/magic-context/migrations.d.ts.map +1 -1
  53. package/dist/features/magic-context/mural/render-trigger.d.ts.map +1 -1
  54. package/dist/features/magic-context/mural/resolve-mural.d.ts +15 -4
  55. package/dist/features/magic-context/mural/resolve-mural.d.ts.map +1 -1
  56. package/dist/features/magic-context/mural/source-revision.d.ts +7 -0
  57. package/dist/features/magic-context/mural/source-revision.d.ts.map +1 -0
  58. package/dist/features/magic-context/mural/storage-mural-cues.d.ts.map +1 -1
  59. package/dist/features/magic-context/reclaim-protection.d.ts +15 -10
  60. package/dist/features/magic-context/reclaim-protection.d.ts.map +1 -1
  61. package/dist/features/magic-context/session-cache-ttl.d.ts +4 -2
  62. package/dist/features/magic-context/session-cache-ttl.d.ts.map +1 -1
  63. package/dist/features/magic-context/smart-notes/capabilities.d.ts +3 -0
  64. package/dist/features/magic-context/smart-notes/capabilities.d.ts.map +1 -1
  65. package/dist/features/magic-context/smart-notes/compiler.d.ts.map +1 -1
  66. package/dist/features/magic-context/smart-notes/github-token.d.ts +5 -0
  67. package/dist/features/magic-context/smart-notes/github-token.d.ts.map +1 -0
  68. package/dist/features/magic-context/smart-notes/runner.d.ts +1 -0
  69. package/dist/features/magic-context/smart-notes/runner.d.ts.map +1 -1
  70. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts +12 -0
  71. package/dist/features/magic-context/smart-notes/sandbox-runner.d.ts.map +1 -1
  72. package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts +6 -0
  73. package/dist/features/magic-context/smart-notes/ssrf-guard.d.ts.map +1 -1
  74. package/dist/features/magic-context/smart-notes/storage.d.ts.map +1 -1
  75. package/dist/features/magic-context/smart-notes/types.d.ts +2 -0
  76. package/dist/features/magic-context/smart-notes/types.d.ts.map +1 -1
  77. package/dist/features/magic-context/storage-clone.d.ts.map +1 -1
  78. package/dist/features/magic-context/storage-db.d.ts +6 -9
  79. package/dist/features/magic-context/storage-db.d.ts.map +1 -1
  80. package/dist/features/magic-context/storage-meta-shared.d.ts +1 -1
  81. package/dist/features/magic-context/storage-meta-shared.d.ts.map +1 -1
  82. package/dist/features/magic-context/storage-ops.d.ts +8 -1
  83. package/dist/features/magic-context/storage-ops.d.ts.map +1 -1
  84. package/dist/features/magic-context/storage-replay-document.d.ts +7 -0
  85. package/dist/features/magic-context/storage-replay-document.d.ts.map +1 -1
  86. package/dist/features/magic-context/storage-schema-helpers.d.ts +2 -0
  87. package/dist/features/magic-context/storage-schema-helpers.d.ts.map +1 -1
  88. package/dist/features/magic-context/storage-session-tables.d.ts.map +1 -1
  89. package/dist/features/magic-context/storage-source.d.ts.map +1 -1
  90. package/dist/features/magic-context/storage-tags.d.ts +11 -3
  91. package/dist/features/magic-context/storage-tags.d.ts.map +1 -1
  92. package/dist/features/magic-context/storage.d.ts +2 -2
  93. package/dist/features/magic-context/storage.d.ts.map +1 -1
  94. package/dist/features/magic-context/temporal-decisions.d.ts +10 -0
  95. package/dist/features/magic-context/temporal-decisions.d.ts.map +1 -0
  96. package/dist/features/magic-context/tool-definition-tokens.d.ts +2 -0
  97. package/dist/features/magic-context/tool-definition-tokens.d.ts.map +1 -1
  98. package/dist/features/magic-context/transform-decision-log.d.ts.map +1 -1
  99. package/dist/features/magic-context/types.d.ts +7 -6
  100. package/dist/features/magic-context/types.d.ts.map +1 -1
  101. package/dist/features/magic-context/window-report-ledger.d.ts.map +1 -1
  102. package/dist/hooks/auto-update-checker/index.d.ts.map +1 -1
  103. package/dist/hooks/magic-context/apply-operations.d.ts +8 -0
  104. package/dist/hooks/magic-context/apply-operations.d.ts.map +1 -1
  105. package/dist/hooks/magic-context/cache-busting-signals.d.ts +6 -3
  106. package/dist/hooks/magic-context/cache-busting-signals.d.ts.map +1 -1
  107. package/dist/hooks/magic-context/channel2-cycle.d.ts +2 -0
  108. package/dist/hooks/magic-context/channel2-cycle.d.ts.map +1 -1
  109. package/dist/hooks/magic-context/compaction-marker-manager.d.ts +7 -0
  110. package/dist/hooks/magic-context/compaction-marker-manager.d.ts.map +1 -1
  111. package/dist/hooks/magic-context/compartment-prompt.d.ts +2 -2
  112. package/dist/hooks/magic-context/compartment-prompt.d.ts.map +1 -1
  113. package/dist/hooks/magic-context/compartment-render-epoch.d.ts +8 -0
  114. package/dist/hooks/magic-context/compartment-render-epoch.d.ts.map +1 -1
  115. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts +18 -4
  116. package/dist/hooks/magic-context/compartment-runner-drop-queue.d.ts.map +1 -1
  117. package/dist/hooks/magic-context/compartment-runner-incremental.d.ts.map +1 -1
  118. package/dist/hooks/magic-context/compartment-runner-partial-recomp.d.ts.map +1 -1
  119. package/dist/hooks/magic-context/compartment-runner-recomp.d.ts.map +1 -1
  120. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts +12 -0
  121. package/dist/hooks/magic-context/ctx-reduce-availability.d.ts.map +1 -1
  122. package/dist/hooks/magic-context/decision-calibration.d.ts +3 -0
  123. package/dist/hooks/magic-context/decision-calibration.d.ts.map +1 -1
  124. package/dist/hooks/magic-context/default-protection-pressure.test-support.d.ts +37 -0
  125. package/dist/hooks/magic-context/default-protection-pressure.test-support.d.ts.map +1 -0
  126. package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts +4 -0
  127. package/dist/hooks/magic-context/drop-stale-reduce-calls.d.ts.map +1 -1
  128. package/dist/hooks/magic-context/edit-marker.d.ts.map +1 -1
  129. package/dist/hooks/magic-context/emergency-drop.d.ts +2 -0
  130. package/dist/hooks/magic-context/emergency-drop.d.ts.map +1 -1
  131. package/dist/hooks/magic-context/emergency-fail-closed.d.ts +21 -1
  132. package/dist/hooks/magic-context/emergency-fail-closed.d.ts.map +1 -1
  133. package/dist/hooks/magic-context/event-handler.d.ts +5 -0
  134. package/dist/hooks/magic-context/event-handler.d.ts.map +1 -1
  135. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts +30 -1
  136. package/dist/hooks/magic-context/final-wire-token-estimate.d.ts.map +1 -1
  137. package/dist/hooks/magic-context/heuristic-cleanup.d.ts +2 -0
  138. package/dist/hooks/magic-context/heuristic-cleanup.d.ts.map +1 -1
  139. package/dist/hooks/magic-context/historian-prompt-fit.d.ts +4 -2
  140. package/dist/hooks/magic-context/historian-prompt-fit.d.ts.map +1 -1
  141. package/dist/hooks/magic-context/hook.d.ts +2 -1
  142. package/dist/hooks/magic-context/hook.d.ts.map +1 -1
  143. package/dist/hooks/magic-context/inject-compartments.d.ts +9 -10
  144. package/dist/hooks/magic-context/inject-compartments.d.ts.map +1 -1
  145. package/dist/hooks/magic-context/lkg-measured-request.d.ts +69 -0
  146. package/dist/hooks/magic-context/lkg-measured-request.d.ts.map +1 -0
  147. package/dist/hooks/magic-context/lkg-persist.d.ts +2 -0
  148. package/dist/hooks/magic-context/lkg-persist.d.ts.map +1 -1
  149. package/dist/hooks/magic-context/lkg-replay-fit.d.ts +14 -0
  150. package/dist/hooks/magic-context/lkg-replay-fit.d.ts.map +1 -1
  151. package/dist/hooks/magic-context/lkg-replay.d.ts +10 -1
  152. package/dist/hooks/magic-context/lkg-replay.d.ts.map +1 -1
  153. package/dist/hooks/magic-context/lkg-slot.d.ts +4 -0
  154. package/dist/hooks/magic-context/lkg-slot.d.ts.map +1 -1
  155. package/dist/hooks/magic-context/module-state-sync.d.ts +2 -0
  156. package/dist/hooks/magic-context/module-state-sync.d.ts.map +1 -1
  157. package/dist/hooks/magic-context/module-transport.d.ts.map +1 -1
  158. package/dist/hooks/magic-context/module-wire.d.ts.map +1 -1
  159. package/dist/hooks/magic-context/note-nudger.d.ts +17 -5
  160. package/dist/hooks/magic-context/note-nudger.d.ts.map +1 -1
  161. package/dist/hooks/magic-context/read-session-chunk.d.ts +1 -1
  162. package/dist/hooks/magic-context/read-session-chunk.d.ts.map +1 -1
  163. package/dist/hooks/magic-context/read-session-db.d.ts +1 -0
  164. package/dist/hooks/magic-context/read-session-db.d.ts.map +1 -1
  165. package/dist/hooks/magic-context/read-session-formatting.d.ts +7 -0
  166. package/dist/hooks/magic-context/read-session-formatting.d.ts.map +1 -1
  167. package/dist/hooks/magic-context/read-session-raw.d.ts +4 -0
  168. package/dist/hooks/magic-context/read-session-raw.d.ts.map +1 -1
  169. package/dist/hooks/magic-context/read-session-true-raw-tokens.d.ts.map +1 -1
  170. package/dist/hooks/magic-context/recomp-orchestrator.d.ts +2 -0
  171. package/dist/hooks/magic-context/recomp-orchestrator.d.ts.map +1 -1
  172. package/dist/hooks/magic-context/reference-retrieval.d.ts +27 -17
  173. package/dist/hooks/magic-context/reference-retrieval.d.ts.map +1 -1
  174. package/dist/hooks/magic-context/request-hook-order.d.ts +56 -0
  175. package/dist/hooks/magic-context/request-hook-order.d.ts.map +1 -0
  176. package/dist/hooks/magic-context/rust-mode-transform.d.ts +22 -3
  177. package/dist/hooks/magic-context/rust-mode-transform.d.ts.map +1 -1
  178. package/dist/hooks/magic-context/strip-content.d.ts +4 -2
  179. package/dist/hooks/magic-context/strip-content.d.ts.map +1 -1
  180. package/dist/hooks/magic-context/supersession-reclaim.d.ts +4 -0
  181. package/dist/hooks/magic-context/supersession-reclaim.d.ts.map +1 -1
  182. package/dist/hooks/magic-context/system-prompt-hash.d.ts +7 -0
  183. package/dist/hooks/magic-context/system-prompt-hash.d.ts.map +1 -1
  184. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts +12 -3
  185. package/dist/hooks/magic-context/tail-hygiene-walk.d.ts.map +1 -1
  186. package/dist/hooks/magic-context/temporal-awareness.d.ts +6 -3
  187. package/dist/hooks/magic-context/temporal-awareness.d.ts.map +1 -1
  188. package/dist/hooks/magic-context/temporal-served-projection.d.ts +4 -0
  189. package/dist/hooks/magic-context/temporal-served-projection.d.ts.map +1 -0
  190. package/dist/hooks/magic-context/tool-drop-target.d.ts.map +1 -1
  191. package/dist/hooks/magic-context/tool-reclaim.d.ts +2 -0
  192. package/dist/hooks/magic-context/tool-reclaim.d.ts.map +1 -1
  193. package/dist/hooks/magic-context/transform-message-helpers.d.ts +5 -0
  194. package/dist/hooks/magic-context/transform-message-helpers.d.ts.map +1 -1
  195. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts +41 -17
  196. package/dist/hooks/magic-context/transform-postprocess-phase.d.ts.map +1 -1
  197. package/dist/hooks/magic-context/transform.d.ts +12 -0
  198. package/dist/hooks/magic-context/transform.d.ts.map +1 -1
  199. package/dist/hooks/magic-context/wrapup-orchestrator.d.ts.map +1 -1
  200. package/dist/{index-vvtfyw1z.js → index-0d3g3461.js} +5 -13
  201. package/dist/index-1bc61ans.js +154 -0
  202. package/dist/{index-n96ag4rk.js → index-1zx87sdm.js} +5 -1
  203. package/dist/{index-4krbw8z9.js → index-3h0ybwah.js} +608 -102
  204. package/dist/{index-gd5qx1j9.js → index-5eqk6z3s.js} +62 -1
  205. package/dist/index-5gq3b2ya.js +494 -0
  206. package/dist/{index-75zjgwga.js → index-7qw742ev.js} +1 -1
  207. package/dist/{index-f85teqck.js → index-8da2zjhz.js} +3 -256
  208. package/dist/{index-w9jwmntv.js → index-b35pxds2.js} +9 -1
  209. package/dist/{index-8fgkmxmy.js → index-e2dtv0ra.js} +4 -3
  210. package/dist/{v2/server-a4m2b1yv.js → index-fg34g6a5.js} +55 -1
  211. package/dist/{index-xgt9k6c6.js → index-j7fvnjye.js} +2 -1
  212. package/dist/{index-2aq21j41.js → index-k4404na5.js} +418 -127
  213. package/dist/{index-2ntg5sd4.js → index-k5bdx1bx.js} +9 -5
  214. package/dist/{index-bmzf7zxv.js → index-majxda46.js} +23 -5
  215. package/dist/{index-16ny736w.js → index-p821bjdb.js} +14406 -13726
  216. package/dist/{index-remp7e2g.js → index-q4yp4b52.js} +16 -1
  217. package/dist/index-qr6r7akd.js +28505 -0
  218. package/dist/{index-fr2z4qy8.js → index-r5hmbx3t.js} +132 -169
  219. package/dist/index-sfnj6h8h.js +259 -0
  220. package/dist/index-sj29b3z2.js +30 -0
  221. package/dist/{index-q7yesyk9.js → index-yasgb8ej.js} +23 -24
  222. package/dist/index.d.ts.map +1 -1
  223. package/dist/index.js +1983 -33118
  224. package/dist/{message-time-backfill-an311pmk.js → message-time-backfill-68gj6t3e.js} +2 -2
  225. package/dist/migration-worker.js +12 -7
  226. package/dist/plugin/dream-timer.d.ts +25 -1
  227. package/dist/plugin/dream-timer.d.ts.map +1 -1
  228. package/dist/plugin/hooks/create-session-hooks.d.ts +2 -1
  229. package/dist/plugin/hooks/create-session-hooks.d.ts.map +1 -1
  230. package/dist/plugin/messages-transform.d.ts +13 -0
  231. package/dist/plugin/messages-transform.d.ts.map +1 -1
  232. package/dist/plugin/rpc-handlers.d.ts +4 -0
  233. package/dist/plugin/rpc-handlers.d.ts.map +1 -1
  234. package/dist/plugin/subagent-tool-policy.d.ts +14 -0
  235. package/dist/plugin/subagent-tool-policy.d.ts.map +1 -0
  236. package/dist/plugin/tool-registry.d.ts +1 -0
  237. package/dist/plugin/tool-registry.d.ts.map +1 -1
  238. package/dist/{read-session-chunk-8rxs0tc9.js → read-session-chunk-egz7r68d.js} +8 -8
  239. package/dist/{recomp-orchestrator-nzamtw29.js → recomp-orchestrator-ejq7ex5d.js} +15 -15
  240. package/dist/{send-session-notification-nqpv7cne.js → send-session-notification-dyw42dtr.js} +4 -4
  241. package/dist/shared/announcement.d.ts.map +1 -1
  242. package/dist/shared/cache-ttl-display.d.ts +6 -4
  243. package/dist/shared/cache-ttl-display.d.ts.map +1 -1
  244. package/dist/shared/model-cache-ttl.d.ts +1 -1
  245. package/dist/shared/model-cache-ttl.d.ts.map +1 -1
  246. package/dist/shared/model-suggestion-retry.d.ts +2 -0
  247. package/dist/shared/model-suggestion-retry.d.ts.map +1 -1
  248. package/dist/shared/models-dev-cache.d.ts.map +1 -1
  249. package/dist/shared/protected-tools-policy.d.ts +6 -0
  250. package/dist/shared/protected-tools-policy.d.ts.map +1 -0
  251. package/dist/shared/quota-diagnostic.d.ts +4 -0
  252. package/dist/shared/quota-diagnostic.d.ts.map +1 -0
  253. package/dist/shared/rpc-server.d.ts.map +1 -1
  254. package/dist/shared/sqlite-context-pragmas.d.ts +12 -0
  255. package/dist/shared/sqlite-context-pragmas.d.ts.map +1 -0
  256. package/dist/shared/sqlite-helpers.d.ts +9 -0
  257. package/dist/shared/sqlite-helpers.d.ts.map +1 -1
  258. package/dist/shared/sqlite.d.ts +10 -0
  259. package/dist/shared/sqlite.d.ts.map +1 -1
  260. package/dist/shared/status-summary.d.ts +1 -0
  261. package/dist/shared/status-summary.d.ts.map +1 -1
  262. package/dist/shared/status-view-check.d.ts.map +1 -1
  263. package/dist/shared/status-view.d.ts +4 -0
  264. package/dist/shared/status-view.d.ts.map +1 -1
  265. package/dist/shared/storage-permissions.d.ts +24 -0
  266. package/dist/shared/storage-permissions.d.ts.map +1 -1
  267. package/dist/shared/temporal-upgrade-fixture.d.ts +19 -0
  268. package/dist/shared/temporal-upgrade-fixture.d.ts.map +1 -0
  269. package/dist/shared/user-facing-codes.d.ts +5 -0
  270. package/dist/shared/user-facing-codes.d.ts.map +1 -1
  271. package/dist/shared/write-transaction-timing.d.ts +8 -1
  272. package/dist/shared/write-transaction-timing.d.ts.map +1 -1
  273. package/dist/tools/ctx-expand/render.d.ts.map +1 -1
  274. package/dist/tools/ctx-memory/tools.d.ts.map +1 -1
  275. package/dist/tools/ctx-reduce/constants.d.ts +2 -0
  276. package/dist/tools/ctx-reduce/constants.d.ts.map +1 -1
  277. package/dist/tools/ctx-reduce/tools.d.ts +4 -4
  278. package/dist/tools/ctx-reduce/tools.d.ts.map +1 -1
  279. package/dist/{transform-postprocess-phase-414phndq.js → transform-postprocess-phase-tz3pat2p.js} +15 -15
  280. package/dist/v2/context-8vgtb6sz.js +52166 -0
  281. package/dist/v2/{derive-budgets-v0krf3t7.js → derive-budgets-kdgp4s3r.js} +4 -3
  282. package/dist/v2/embedding-worker.js +6 -5
  283. package/dist/v2/fold/boundary.d.ts +2 -0
  284. package/dist/v2/fold/boundary.d.ts.map +1 -1
  285. package/dist/v2/fold/owner.d.ts.map +1 -1
  286. package/dist/v2/hooks/channel2.d.ts +2 -0
  287. package/dist/v2/hooks/channel2.d.ts.map +1 -1
  288. package/dist/v2/hooks/context.d.ts +2 -2
  289. package/dist/v2/hooks/context.d.ts.map +1 -1
  290. package/dist/v2/hooks/dream-timer.d.ts +39 -0
  291. package/dist/v2/hooks/dream-timer.d.ts.map +1 -0
  292. package/dist/v2/hooks/payload.d.ts.map +1 -1
  293. package/dist/v2/hooks/store.d.ts.map +1 -1
  294. package/dist/v2/hooks/tools.d.ts +1 -1
  295. package/dist/v2/hooks/tools.d.ts.map +1 -1
  296. package/dist/v2/hooks/update-check.d.ts.map +1 -1
  297. package/dist/v2/{message-time-backfill-0n93vrd7.js → message-time-backfill-r6qkem1x.js} +3 -3
  298. package/dist/v2/migration-worker.js +13 -8
  299. package/dist/v2/{read-session-chunk-hjza38hr.js → read-session-chunk-8vjp6581.js} +9 -9
  300. package/dist/v2/recomp-orchestrator-5xj0yzyk.js +39 -0
  301. package/dist/v2/{safe-notification-target-wtj0bbc2.js → safe-notification-target-eb1n1vfb.js} +2 -2
  302. package/dist/v2/{send-session-notification-mq9frrtm.js → send-session-notification-qs0j78v6.js} +6 -6
  303. package/dist/v2/server-14vq4kpm.js +30 -0
  304. package/dist/v2/server-1bc61ans.js +154 -0
  305. package/dist/v2/{server-n96ag4rk.js → server-1zx87sdm.js} +5 -1
  306. package/dist/v2/server-3n4q9xme.js +79 -0
  307. package/dist/v2/server-4663ejam.js +3351 -0
  308. package/dist/v2/{server-rhdgxp1t.js → server-51dv1pr5.js} +63 -2
  309. package/dist/v2/{server-5317ykaf.js → server-6r257mf5.js} +1 -1
  310. package/dist/v2/server-84w6rvvf.js +14 -0
  311. package/dist/v2/{server-qpg6wf72.js → server-ajzeteqw.js} +9 -1
  312. package/dist/{index-a4m2b1yv.js → v2/server-fg34g6a5.js} +55 -1
  313. package/dist/v2/{server-e36nf2p1.js → server-frbm99q5.js} +1595 -1599
  314. package/dist/v2/{server-remp7e2g.js → server-g0fjrkta.js} +16 -1
  315. package/dist/v2/{server-z19x7eqz.js → server-mcfawjgc.js} +4 -4
  316. package/dist/v2/server-p2en78c8.js +3892 -0
  317. package/dist/v2/{server-hfjfbg59.js → server-qp5hx1ad.js} +608 -105
  318. package/dist/v2/{server-c4g2y1z8.js → server-vnh7r35f.js} +2778 -5383
  319. package/dist/v2/server-vs5gpnd4.js +493 -0
  320. package/dist/v2/{server-w99cyt6a.js → server-wvjvfhck.js} +14 -6
  321. package/dist/v2/{server-v5xgft5v.js → server-xtp687da.js} +186 -3533
  322. package/dist/v2/{server-0jqw05sa.js → server-y8maxeft.js} +6 -84
  323. package/dist/v2/server.d.ts.map +1 -1
  324. package/dist/v2/server.js +104 -49288
  325. package/dist/v2/store-reader.d.ts +39 -1
  326. package/dist/v2/store-reader.d.ts.map +1 -1
  327. package/dist/v2/tool-result.d.ts +8 -0
  328. package/dist/v2/tool-result.d.ts.map +1 -0
  329. package/dist/v2/tui/index.d.ts.map +1 -1
  330. package/dist/v2/{wrapup-orchestrator-tbyx78dz.js → wrapup-orchestrator-r5t1pyj8.js} +20 -16
  331. package/dist/wrapup-orchestrator-kw3x3myw.js +26 -0
  332. package/package.json +22 -7
  333. package/src/config/index.ts +21 -4
  334. package/src/config/latch-permanence-guard.test.ts +6 -1
  335. package/src/config/live-run-config.ts +1 -0
  336. package/src/config/migrate-config-location.test.ts +31 -1
  337. package/src/config/migrate-config-location.ts +8 -41
  338. package/src/config/protected-tools.test.ts +70 -0
  339. package/src/config/raw-loader.test.ts +15 -0
  340. package/src/config/raw-loader.ts +1 -1
  341. package/src/config/removed-agent-source-fence.test.ts +10 -1
  342. package/src/config/schema/magic-context.test.ts +20 -1
  343. package/src/config/schema/magic-context.ts +21 -7
  344. package/src/shared/announcement.ts +6 -5
  345. package/src/shared/cache-ttl-display.test.ts +1 -1
  346. package/src/shared/cache-ttl-display.ts +17 -16
  347. package/src/shared/fold-render-lock-fence.test.ts +84 -0
  348. package/src/shared/fold-render-lock-fixtures.test.ts +276 -0
  349. package/src/shared/model-cache-ttl.test.ts +2 -2
  350. package/src/shared/model-cache-ttl.ts +8 -4
  351. package/src/shared/model-suggestion-retry.test.ts +104 -1
  352. package/src/shared/model-suggestion-retry.ts +63 -6
  353. package/src/shared/models-dev-cache.ts +3 -11
  354. package/src/shared/protected-tools-policy.ts +23 -0
  355. package/src/shared/quota-diagnostic.ts +9 -0
  356. package/src/shared/rpc-server.ts +6 -54
  357. package/src/shared/sqlite-context-pragmas.test.ts +105 -0
  358. package/src/shared/sqlite-context-pragmas.ts +24 -0
  359. package/src/shared/sqlite-helpers.ts +17 -0
  360. package/src/shared/sqlite.ts +75 -0
  361. package/src/shared/status-detail-text.test.ts +18 -1
  362. package/src/shared/status-summary.ts +11 -0
  363. package/src/shared/status-view-check.ts +5 -0
  364. package/src/shared/status-view.test.ts +11 -2
  365. package/src/shared/status-view.ts +12 -1
  366. package/src/shared/storage-permissions.test.ts +204 -0
  367. package/src/shared/storage-permissions.ts +192 -0
  368. package/src/shared/temporal-upgrade-fixture.ts +50 -0
  369. package/src/shared/user-facing-codes.ts +6 -0
  370. package/src/shared/write-transaction-timing.test.ts +39 -0
  371. package/src/shared/write-transaction-timing.ts +25 -1
  372. package/src/tui/dialogs/status-dialog-render.test.ts +1 -1
  373. package/src/tui/index.tsx +3 -1
  374. package/src/tui/startup-order.test.ts +16 -0
  375. package/src/tui-compiled/index.tsx +3 -1
  376. package/src/v2/tui/index.ts +9 -2
  377. package/dist/index-anq4nn6f.js +0 -131
  378. package/dist/index-e44zzy84.js +0 -10
  379. package/dist/index-x23gah8c.js +0 -16
  380. package/dist/v2/recomp-orchestrator-1aq7h44c.js +0 -36
  381. package/dist/v2/server-e44zzy84.js +0 -10
  382. package/dist/v2/server-fgmxwrgy.js +0 -16
  383. package/dist/v2/server-r7cmye3k.js +0 -131
  384. package/dist/wrapup-orchestrator-h28bqsy6.js +0 -26
  385. package/dist/v2/{server-ckpc8pxy.js → server-1qbnzc80.js} +8 -8
@@ -1,3 +1,9 @@
1
+ import {
2
+ UNKNOWN_FIT_RATIO,
3
+ resolveDecisionCalibration,
4
+ hasMeasuredDecisionCalibration,
5
+ providerMass
6
+ } from "./index-1zx87sdm.js";
1
7
  import {
2
8
  OMO_INTERNAL_INITIATOR_MARKER,
3
9
  isSystemDirective,
@@ -5,13 +11,16 @@ import {
5
11
  extractTexts2,
6
12
  extractToolResultBodyTokens,
7
13
  extractToolCallSummaries,
14
+ hasTokenizerForFit,
15
+ tokenCountUsesByteBound,
8
16
  estimateTokens,
17
+ createTokenCountMemo,
9
18
  normalizeText,
10
19
  compactRole,
11
20
  formatBlock,
12
21
  compactTextForSummary,
13
22
  mergeCommitHashes
14
- } from "./index-gd5qx1j9.js";
23
+ } from "./index-5eqk6z3s.js";
15
24
  import {
16
25
  getHarness
17
26
  } from "./index-q6hef7fh.js";
@@ -19,32 +28,55 @@ import {
19
28
  sessionLog
20
29
  } from "./index-hybnrwq0.js";
21
30
  import {
22
- renderToolTemplate
23
- } from "./index-remp7e2g.js";
31
+ tagOrderConstraintIndex,
32
+ stableStringify,
33
+ getToolDefinitionMeasurementSignature,
34
+ getLargestMeasuredToolDefinitionTokens,
35
+ getMeasuredToolDefinitionTokens
36
+ } from "./index-5gq3b2ya.js";
37
+ import {
38
+ renderToolTemplate,
39
+ DEFAULT_PROTECTED_TOOLS,
40
+ normalizeProtectedToolName,
41
+ mergeProtectedTools
42
+ } from "./index-q4yp4b52.js";
24
43
  import {
25
44
  openCodeDbExists,
26
45
  withReadOnlySessionDb,
27
46
  getRawSessionMessageCountFromDb,
28
47
  getMessageTimesFromOpenCodeDb
29
- } from "./index-bmzf7zxv.js";
30
- import {
31
- stableStringify,
32
- getLargestMeasuredToolDefinitionTokens,
33
- getMeasuredToolDefinitionTokens
34
- } from "./index-anq4nn6f.js";
35
- import {
36
- UNKNOWN_FIT_RATIO,
37
- resolveDecisionCalibration,
38
- providerMass
39
- } from "./index-n96ag4rk.js";
48
+ } from "./index-majxda46.js";
40
49
  import {
41
50
  canonicalModelIdentity
42
51
  } from "./index-avwt563y.js";
43
52
 
44
53
  // src/features/magic-context/reclaim-protection.ts
45
- var CTX_REDUCE_KEEP = 3;
46
- function newestCtxReduceTagNumbers(tags) {
47
- return new Set(tags.filter((tag) => tag.toolName === "ctx_reduce").sort((left, right) => right.tagNumber - left.tagNumber).slice(0, CTX_REDUCE_KEEP).map((tag) => tag.tagNumber));
54
+ var CTX_REDUCE_KEEP = DEFAULT_PROTECTED_TOOLS.ctx_reduce;
55
+ function adoptedProtectedToolsPolicy(current, previous, rebuilding, hasBaseline) {
56
+ if (rebuilding || !hasBaseline)
57
+ return mergeProtectedTools(current);
58
+ return { ...previous ?? { todowrite: 0, ctx_reduce: 3 } };
59
+ }
60
+ function protectedToolTagNumbers(tags, protectedTools) {
61
+ const counts = mergeProtectedTools(protectedTools);
62
+ const protectedTags = new Set;
63
+ for (const tag of [...tags].sort((left, right) => right.tagNumber - left.tagNumber)) {
64
+ if (tag.status !== undefined && tag.status !== "active")
65
+ continue;
66
+ if (tag.type !== undefined && tag.type !== "tool")
67
+ continue;
68
+ const name = normalizeProtectedToolName(tag.toolName);
69
+ if (!Object.hasOwn(counts, name) || counts[name] <= 0)
70
+ continue;
71
+ protectedTags.add(tag.tagNumber);
72
+ counts[name] -= 1;
73
+ }
74
+ return protectedTags;
75
+ }
76
+ function protectedToolTokenCount(tags, counts, calibration) {
77
+ const protectedTags = protectedToolTagNumbers(tags, counts);
78
+ const tokens = tags.reduce((sum, tag) => sum + (protectedTags.has(tag.tagNumber) ? tag.tokenCount ?? 0 : 0), 0);
79
+ return calibration && hasMeasuredDecisionCalibration(calibration) ? providerMass({ tools: tokens }, calibration) : 0;
48
80
  }
49
81
 
50
82
  // src/hooks/magic-context/tag-content-primitives.ts
@@ -441,6 +473,7 @@ function isTodoItem(value) {
441
473
  var MAX_CONTENT_MEMO_ENTRIES = 1e5;
442
474
  var MAX_CONTENT_MEMO_BYTES = 64 * 1024 * 1024;
443
475
  var contentMemo = new Map;
476
+ var contentMemoOrder = new Set;
444
477
  var contentMemoBytes = 0;
445
478
  var FNV1A_32_OFFSET = 2166136261;
446
479
  var FNV1A_32_PRIME = 16777619;
@@ -462,25 +495,38 @@ function fnv1a32(value) {
462
495
  return hash.toString(16).padStart(8, "0");
463
496
  }
464
497
  function memoizedContent(kind, content) {
465
- const key = `${kind}\x00${content}`;
466
- const cached = contentMemo.get(key);
498
+ let byContent = contentMemo.get(kind);
499
+ if (!byContent) {
500
+ byContent = new Map;
501
+ contentMemo.set(kind, byContent);
502
+ }
503
+ const cached = byContent.get(content);
467
504
  if (cached)
468
505
  return cached;
506
+ let hash = FNV1A_32_OFFSET;
507
+ for (const segment of [kind, "\x00", content]) {
508
+ for (let index = 0;index < segment.length; index += 1) {
509
+ hash ^= segment.charCodeAt(index);
510
+ hash = Math.imul(hash, FNV1A_32_PRIME) >>> 0;
511
+ }
512
+ }
469
513
  const measured = {
470
- hash: fnv1a32(key),
514
+ hash: hash.toString(16).padStart(8, "0"),
471
515
  tokens: kind === "excluded" ? 0 : undefined,
472
- keyBytes: key.length * 2 + 32
516
+ keyBytes: (kind.length + 1 + content.length) * 2 + 32,
517
+ kind,
518
+ content
473
519
  };
474
- contentMemo.set(key, measured);
520
+ byContent.set(content, measured);
521
+ contentMemoOrder.add(measured);
475
522
  contentMemoBytes += measured.keyBytes;
476
- while (contentMemo.size > MAX_CONTENT_MEMO_ENTRIES || contentMemoBytes > MAX_CONTENT_MEMO_BYTES) {
477
- const oldest = contentMemo.keys().next().value;
478
- if (typeof oldest !== "string")
523
+ while (contentMemoOrder.size > MAX_CONTENT_MEMO_ENTRIES || contentMemoBytes > MAX_CONTENT_MEMO_BYTES) {
524
+ const oldest = contentMemoOrder.values().next().value;
525
+ if (!oldest)
479
526
  break;
480
- const removed = contentMemo.get(oldest);
481
- if (removed)
482
- contentMemoBytes -= removed.keyBytes;
483
- contentMemo.delete(oldest);
527
+ contentMemoBytes -= oldest.keyBytes;
528
+ contentMemo.get(oldest.kind)?.delete(oldest.content);
529
+ contentMemoOrder.delete(oldest);
484
530
  }
485
531
  return measured;
486
532
  }
@@ -652,9 +698,9 @@ function messageIdForTag(tag) {
652
698
  return tag.toolOwnerMessageId;
653
699
  return contentTagOwnerMessageId(tag.messageId);
654
700
  }
655
- function resolveProtectedTagNumbers(tags, protectedTagNumbersInput) {
701
+ function resolveProtectedTagNumbers(tags, protectedTagNumbersInput, protectedToolTags) {
656
702
  const protectedNumbers = new Set(protectedTagNumbersInput);
657
- const protectedCtxReduceTags = newestCtxReduceTagNumbers(tags.filter((tag) => tag.status === "active" && tag.type === "tool"));
703
+ const protectedCtxReduceTags = protectedToolTags ?? protectedToolTagNumbers(tags);
658
704
  for (const tagNumber of protectedCtxReduceTags)
659
705
  protectedNumbers.add(tagNumber);
660
706
  return protectedNumbers;
@@ -677,7 +723,7 @@ function neighborhoodConsistent(args) {
677
723
  return args.orphanTagNumber >= previousMax && args.orphanTagNumber <= nextMin;
678
724
  }
679
725
  function buildTagAttribution(args) {
680
- const protectedNumbers = resolveProtectedTagNumbers(args.tags, args.protectedTagNumbers);
726
+ const protectedNumbers = resolveProtectedTagNumbers(args.tags, args.protectedTagNumbers, args.protectedToolTags);
681
727
  const messageTags = new Map;
682
728
  const exactToolTags = new Map;
683
729
  const orphanTagsByCall = new Map;
@@ -836,19 +882,34 @@ function sameTailHygieneStructuralSignature(expected, actual) {
836
882
  return expected.partCounts.every((count, index) => count === actual.partCounts[index]);
837
883
  }
838
884
  function measureTailHygiene(input) {
885
+ return measureWithReplay(input);
886
+ }
887
+ function measureWithReplay(input, replay) {
839
888
  const pendingDropTagNumbers = input.pendingDropTagNumbers ?? new Set;
889
+ const unchanged = input.messages.map((message, index) => {
890
+ const previous = replay?.messages[index];
891
+ return previous !== undefined && sameReplayMessage(previous, message);
892
+ });
840
893
  const toolIdentities = collectToolPartIdentities(input.messages);
841
894
  const attribution = buildTagAttribution({
842
895
  messages: input.messages,
843
896
  tags: input.tags,
844
897
  toolIdentities,
845
- protectedTagNumbers: input.protectedTagNumbers
898
+ protectedTagNumbers: input.protectedTagNumbers,
899
+ protectedToolTags: input.protectedToolTags
900
+ });
901
+ const toolOutputs = input.messages.map((message, index) => message.parts.map((part, partIndex) => unchanged[index] ? replay?.measured.toolOutputs[index][partIndex] ?? null : isRecord(part) ? toolOutputText(part) : null));
902
+ const outputByPart = new Map;
903
+ input.messages.forEach((message, index) => {
904
+ message.parts.forEach((part, partIndex) => {
905
+ outputByPart.set(part, toolOutputs[index][partIndex]);
906
+ });
846
907
  });
847
908
  const droppedToolOwners = new Set;
848
909
  for (const [part, identity] of toolIdentities) {
849
910
  if (!isRecord(part))
850
911
  continue;
851
- const output = toolOutputText(part);
912
+ const output = outputByPart.get(part) ?? null;
852
913
  if (output !== null && isDropSentinel(output)) {
853
914
  droppedToolOwners.add(`${identity.ownerMessageId}\x00${identity.callId}`);
854
915
  }
@@ -857,11 +918,47 @@ function measureTailHygiene(input) {
857
918
  let t = 0;
858
919
  let u = 0;
859
920
  let newestMessagePartStart = 0;
921
+ const messagePartStarts = [];
860
922
  for (let messageIndex = 0;messageIndex < input.messages.length; messageIndex += 1) {
861
923
  const message = input.messages[messageIndex];
924
+ messagePartStarts.push(parts.length);
862
925
  if (messageIndex === input.messages.length - 1)
863
926
  newestMessagePartStart = parts.length;
864
927
  const messageKey = messageIdentity(message, messageIndex);
928
+ const priorMessage = replay?.messages[messageIndex];
929
+ const reusable = unchanged[messageIndex] && priorMessage && message.parts.every((part, index) => {
930
+ const current = toolIdentities.get(part);
931
+ const prior = replay?.measured.toolOwners.get(priorMessage.parts[index]);
932
+ if (!current || !prior)
933
+ return current === prior;
934
+ const currentKey = `${current.ownerMessageId}\x00${current.callId}`;
935
+ const priorKey = `${prior.ownerMessageId}\x00${prior.callId}`;
936
+ return currentKey === priorKey && droppedToolOwners.has(currentKey) === replay?.measured.droppedToolOwners.has(priorKey);
937
+ });
938
+ if (reusable && replay) {
939
+ const start = replay.measured.messagePartStarts[messageIndex];
940
+ const end = replay.measured.messagePartStarts[messageIndex + 1] ?? replay.measured.parts.length;
941
+ for (let index = start;index < end; index += 1) {
942
+ const prior = replay.measured.parts[index];
943
+ const partIndex = Number(prior.key.slice(messageKey.length + 1).split("\x00")[0]);
944
+ const tag = prior.kind === "text" ? attribution.messageTags.get(`${message.info.id}:p${partIndex}`) : prior.kind === "file" ? attribution.messageTags.get(`${message.info.id}:file${partIndex}`) : prior.kind === "toolInput" || prior.kind === "toolOutput" ? attribution.toolTagsByPart.get(message.parts[partIndex]) : undefined;
945
+ const protectedPart = tag ? attribution.protectedNumbers.has(tag.tagNumber) : false;
946
+ const queuedForDrop = tag ? pendingDropTagNumbers.has(tag.tagNumber) : false;
947
+ const uTokens = tag?.status === "active" && !protectedPart && !queuedForDrop && prior.kind !== "excluded" ? prior.tokens : 0;
948
+ const measured = prior.tagNumber === (tag?.tagNumber ?? null) && prior.tagStatus === (tag?.status ?? null) && prior.protected === protectedPart && prior.queuedForDrop === queuedForDrop && prior.uTokens === uTokens ? prior : {
949
+ ...prior,
950
+ tagNumber: tag?.tagNumber ?? null,
951
+ tagStatus: tag?.status ?? null,
952
+ protected: protectedPart,
953
+ queuedForDrop,
954
+ uTokens
955
+ };
956
+ parts.push(measured);
957
+ t += measured.tokens;
958
+ u += measured.uTokens;
959
+ }
960
+ continue;
961
+ }
865
962
  const messageSynthetic = isSyntheticMessage(message);
866
963
  for (let partIndex = 0;partIndex < message.parts.length; partIndex += 1) {
867
964
  const part = message.parts[partIndex];
@@ -943,7 +1040,7 @@ function measureTailHygiene(input) {
943
1040
  t += measured.tokens;
944
1041
  u += measured.uTokens;
945
1042
  }
946
- const rawOutput = toolOutputText(part);
1043
+ const rawOutput = outputByPart.get(part) ?? null;
947
1044
  if (rawOutput !== null) {
948
1045
  const output = stripChannel1ReminderSpans(rawOutput);
949
1046
  if (isDropSentinel(output)) {
@@ -977,7 +1074,11 @@ function measureTailHygiene(input) {
977
1074
  t: Math.max(0, t),
978
1075
  contentSignature: contentSignature(parts),
979
1076
  parts,
980
- newestMessagePartStart
1077
+ newestMessagePartStart,
1078
+ messagePartStarts,
1079
+ toolOutputs,
1080
+ toolOwners: toolIdentities,
1081
+ droppedToolOwners
981
1082
  };
982
1083
  }
983
1084
  function messageIdFromPartKey(key) {
@@ -1084,6 +1185,20 @@ function sameReplayValue(before, after) {
1084
1185
  }
1085
1186
  return true;
1086
1187
  }
1188
+ function copyReplayValue(value) {
1189
+ if (Array.isArray(value))
1190
+ return value.map(copyReplayValue);
1191
+ if (value !== null && typeof value === "object") {
1192
+ const prototype = Object.getPrototypeOf(value);
1193
+ if (prototype !== Object.prototype && prototype !== null)
1194
+ return structuredClone(value);
1195
+ const copy = Object.create(prototype);
1196
+ for (const key of Object.keys(value))
1197
+ copy[key] = copyReplayValue(value[key]);
1198
+ return copy;
1199
+ }
1200
+ return value;
1201
+ }
1087
1202
  function sameNumbers(before, after) {
1088
1203
  if (before.size !== after.size)
1089
1204
  return false;
@@ -1092,19 +1207,22 @@ function sameNumbers(before, after) {
1092
1207
  return false;
1093
1208
  return true;
1094
1209
  }
1210
+ function sameReplayMessage(left, right) {
1211
+ return left.info.id === right.info.id && left.info.role === right.info.role && left.info.summary === right.info.summary && sameReplayValue(left.parts, right.parts);
1212
+ }
1095
1213
  function sameReplayMessages(before, after) {
1096
1214
  if (before.length !== after.length)
1097
1215
  return false;
1098
1216
  for (let index = 0;index < before.length; index += 1) {
1099
1217
  const left = before[index];
1100
1218
  const right = after[index];
1101
- if (left.info.id !== right.info.id || left.info.role !== right.info.role || left.info.summary !== right.info.summary || !sameReplayValue(left.parts, right.parts))
1219
+ if (!sameReplayMessage(left, right))
1102
1220
  return false;
1103
1221
  }
1104
1222
  return true;
1105
1223
  }
1106
1224
  var baselineMeasurementMemo = new Map;
1107
- var MAX_BASELINE_MEMO_SIZE = 32 * 1024 * 1024;
1225
+ var MAX_BASELINE_MEMO_SIZE = 128 * 1024 * 1024;
1108
1226
  var baselineMemoSize = 0;
1109
1227
  function retainBaselineMeasurement(key, memo) {
1110
1228
  const previous = baselineMeasurementMemo.get(key);
@@ -1149,10 +1267,17 @@ function freezeTailHygieneMeasurement(measured) {
1149
1267
  };
1150
1268
  }
1151
1269
  function refreshTailHygieneBaseline(input) {
1270
+ const protectedToolsPolicy = adoptedProtectedToolsPolicy(input.protectedTools, input.previous?.protectedToolsPolicy, input.cacheBusting, !!input.previous);
1271
+ const protectedToolTags = protectedToolTagNumbers(input.tags, protectedToolsPolicy);
1272
+ input = {
1273
+ ...input,
1274
+ protectedToolTags,
1275
+ protectedTagNumbers: new Set([...input.protectedTagNumbers, ...protectedToolTags])
1276
+ };
1152
1277
  const pendingDropTagNumbers = input.pendingDropTagNumbers ?? new Set;
1153
1278
  const cached = input.previous ? baselineMeasurementMemo.get(input.previous.baselineParts) : undefined;
1154
1279
  const hit = !input.cacheBusting && cached && sameReplayMessages(cached.messages, input.messages) && sameReplayValue(cached.tags, input.tags) && sameNumbers(cached.protectedTagNumbers, input.protectedTagNumbers) && sameNumbers(cached.pendingDropTagNumbers, pendingDropTagNumbers);
1155
- const rawMeasured = hit ? cached.measured : measureTailHygiene(input);
1280
+ const rawMeasured = hit ? cached.measured : measureWithReplay(input, cached);
1156
1281
  const frozenCalibration = !input.cacheBusting && input.previous ? {
1157
1282
  toolsRatio: input.previous.toolsRatio,
1158
1283
  proseRatio: input.previous.proseRatio,
@@ -1171,26 +1296,38 @@ function refreshTailHygieneBaseline(input) {
1171
1296
  })
1172
1297
  };
1173
1298
  const memo = hit ? cached : {
1174
- messages: structuredClone(input.messages.map((message) => ({
1299
+ messages: input.messages.map((message, index) => cached?.messages[index] && sameReplayMessage(cached.messages[index], message) ? cached.messages[index] : {
1175
1300
  info: {
1176
1301
  id: message.info.id,
1177
1302
  role: message.info.role,
1178
1303
  summary: message.info.summary
1179
1304
  },
1180
- parts: message.parts
1181
- }))),
1305
+ parts: copyReplayValue(message.parts)
1306
+ }),
1182
1307
  tags: structuredClone(input.tags),
1183
1308
  protectedTagNumbers: new Set(input.protectedTagNumbers),
1184
1309
  pendingDropTagNumbers: new Set(pendingDropTagNumbers),
1185
1310
  measured: rawMeasured,
1186
1311
  size: 2 * structuralSize(input.messages) + 512 * input.tags.length
1187
1312
  };
1313
+ if (!hit) {
1314
+ const owners = new Map;
1315
+ input.messages.forEach((message, index) => {
1316
+ message.parts.forEach((part, partIndex) => {
1317
+ const identity = rawMeasured.toolOwners.get(part);
1318
+ if (identity)
1319
+ owners.set(memo.messages[index].parts[partIndex], identity);
1320
+ });
1321
+ });
1322
+ rawMeasured.toolOwners = owners;
1323
+ }
1188
1324
  const now = input.now ?? Date.now();
1189
1325
  const refrozen = (mismatch) => {
1190
1326
  const frozen = freezeTailHygieneMeasurement(measured);
1191
1327
  retainBaselineMeasurement(frozen.baselineParts, memo);
1192
1328
  return {
1193
1329
  ...frozen,
1330
+ protectedToolsPolicy,
1194
1331
  hygieneUnitsVersion: frozenCalibration.hygieneUnitsVersion,
1195
1332
  toolsRatio: frozenCalibration.toolsRatio,
1196
1333
  proseRatio: frozenCalibration.proseRatio,
@@ -1219,6 +1356,7 @@ function refreshTailHygieneBaseline(input) {
1219
1356
  }
1220
1357
  return {
1221
1358
  ...input.previous,
1359
+ protectedToolsPolicy,
1222
1360
  turnDeltaU,
1223
1361
  turnDeltaT,
1224
1362
  evaluable: true,
@@ -1238,6 +1376,11 @@ function assertTailHygieneContentUnchanged(input) {
1238
1376
  throw new Error(`tail hygiene walk was not the last byte-affecting operation: expected ${input.expectedSignature}, got ${actual}`);
1239
1377
  }
1240
1378
  }
1379
+ function assertTailHygieneContentUnchangedIfEnabled(input) {
1380
+ if (process.env.MAGIC_CONTEXT_DEBUG_ASSERTIONS === "1") {
1381
+ assertTailHygieneContentUnchanged(input);
1382
+ }
1383
+ }
1241
1384
 
1242
1385
  // src/hooks/magic-context/ctx-reduce-nudge.ts
1243
1386
  var CHANNEL1_SENTINEL = "<system-reminder>";
@@ -1627,7 +1770,7 @@ function planEmergencyDrop(input) {
1627
1770
  reserved.add(nums[i]);
1628
1771
  }
1629
1772
  }
1630
- const protectedCtxReduceTags = newestCtxReduceTagNumbers(floorTags.filter((tag) => tag.status === "active" && tag.type === "tool"));
1773
+ const protectedTags = input.protectedToolTags ?? protectedToolTagNumbers(floorTags, input.protectedTools);
1631
1774
  const byTier = { 1: [], 2: [], 3: [] };
1632
1775
  for (const tag of tags) {
1633
1776
  if (tag.status !== "active" || tag.type !== "tool")
@@ -1638,7 +1781,7 @@ function planEmergencyDrop(input) {
1638
1781
  continue;
1639
1782
  }
1640
1783
  }
1641
- if (protectedCtxReduceTags.has(tag.tagNumber))
1784
+ if (protectedTags.has(tag.tagNumber))
1642
1785
  continue;
1643
1786
  const tier = resolveToolTier(tag.toolName);
1644
1787
  if ((tier === 1 || tier === 2) && reserved.has(tag.tagNumber))
@@ -1683,6 +1826,124 @@ function measureEmergencyTag(tag, target, calibration, skeleton) {
1683
1826
  return { ...tag, servedTokens: served, reclaimableTokens: 0 };
1684
1827
  }
1685
1828
 
1829
+ // src/features/magic-context/storage-ops.ts
1830
+ var queuePendingOpStatements = new WeakMap;
1831
+ var queueUnchangedDropStatements = new WeakMap;
1832
+ var getPendingOpsStatements = new WeakMap;
1833
+ var getPendingOpsCountStatements = new WeakMap;
1834
+ var hasPendingDropOpsStatements = new WeakMap;
1835
+ var clearPendingOpsStatements = new WeakMap;
1836
+ var removePendingOpStatements = new WeakMap;
1837
+ function getQueuePendingOpStatement(db) {
1838
+ let stmt = queuePendingOpStatements.get(db);
1839
+ if (!stmt) {
1840
+ stmt = db.prepare(`INSERT INTO pending_ops (session_id, tag_id, operation, queued_at, harness)
1841
+ SELECT ?, ?, ?, ?, ? WHERE NOT EXISTS (
1842
+ SELECT 1 FROM pending_ops WHERE session_id = ? AND tag_id = ? AND operation = ?
1843
+ )`);
1844
+ queuePendingOpStatements.set(db, stmt);
1845
+ }
1846
+ return stmt;
1847
+ }
1848
+ function getPendingOpsStatement(db) {
1849
+ let stmt = getPendingOpsStatements.get(db);
1850
+ if (!stmt) {
1851
+ stmt = db.prepare("SELECT id, session_id, tag_id, operation, queued_at FROM pending_ops WHERE session_id = ? ORDER BY queued_at ASC, id ASC");
1852
+ getPendingOpsStatements.set(db, stmt);
1853
+ }
1854
+ return stmt;
1855
+ }
1856
+ function getClearPendingOpsStatement(db) {
1857
+ let stmt = clearPendingOpsStatements.get(db);
1858
+ if (!stmt) {
1859
+ stmt = db.prepare("DELETE FROM pending_ops WHERE session_id = ?");
1860
+ clearPendingOpsStatements.set(db, stmt);
1861
+ }
1862
+ return stmt;
1863
+ }
1864
+ function getRemovePendingOpStatement(db) {
1865
+ let stmt = removePendingOpStatements.get(db);
1866
+ if (!stmt) {
1867
+ stmt = db.prepare("DELETE FROM pending_ops WHERE session_id = ? AND tag_id = ?");
1868
+ removePendingOpStatements.set(db, stmt);
1869
+ }
1870
+ return stmt;
1871
+ }
1872
+ function isPendingOpRow(row) {
1873
+ if (row === null || typeof row !== "object")
1874
+ return false;
1875
+ const r = row;
1876
+ return typeof r.id === "number" && typeof r.session_id === "string" && typeof r.tag_id === "number" && typeof r.operation === "string" && typeof r.queued_at === "number";
1877
+ }
1878
+ function toPendingOp(row) {
1879
+ if (row.operation !== "drop") {
1880
+ sessionLog(row.session_id, `unknown pending operation "${row.operation}"; ignoring`);
1881
+ return null;
1882
+ }
1883
+ return {
1884
+ id: row.id,
1885
+ sessionId: row.session_id,
1886
+ tagId: row.tag_id,
1887
+ operation: row.operation,
1888
+ queuedAt: row.queued_at
1889
+ };
1890
+ }
1891
+ function queuePendingOp(db, sessionId, tagId, operation, queuedAt = Date.now()) {
1892
+ getQueuePendingOpStatement(db).run(sessionId, tagId, operation, queuedAt, getHarness(), sessionId, tagId, operation);
1893
+ }
1894
+ function queuePendingDropForUnchangedTag(db, sessionId, tag) {
1895
+ let statement = queueUnchangedDropStatements.get(db);
1896
+ if (!statement) {
1897
+ statement = db.prepare(`INSERT INTO pending_ops (session_id, tag_id, operation, queued_at, harness)
1898
+ SELECT session_id, tag_number, 'drop', ?, ? FROM tags
1899
+ WHERE id = ? AND session_id = ? AND tag_number = ? AND message_id = ?
1900
+ AND type = ? AND tool_owner_message_id IS ? AND status = 'active'
1901
+ AND NOT EXISTS (
1902
+ SELECT 1 FROM pending_ops WHERE session_id = tags.session_id
1903
+ AND tag_id = tags.tag_number AND operation = 'drop'
1904
+ )`);
1905
+ queueUnchangedDropStatements.set(db, statement);
1906
+ }
1907
+ return statement.run(Date.now(), getHarness(), tag.id ?? null, sessionId, tag.tagNumber, tag.messageId, tag.type, tag.toolOwnerMessageId).changes > 0;
1908
+ }
1909
+ function getPendingOps(db, sessionId) {
1910
+ const rows = getPendingOpsStatement(db).all(sessionId).filter(isPendingOpRow);
1911
+ return rows.map(toPendingOp).filter((op) => op !== null);
1912
+ }
1913
+ function hasPendingDropOps(db, sessionId) {
1914
+ let statement = hasPendingDropOpsStatements.get(db);
1915
+ if (!statement) {
1916
+ statement = db.prepare(`SELECT EXISTS (
1917
+ SELECT 1 FROM pending_ops WHERE session_id = ? AND operation = 'drop'
1918
+ AND typeof(id) IN ('integer', 'real')
1919
+ AND typeof(session_id) = 'text'
1920
+ AND typeof(tag_id) IN ('integer', 'real')
1921
+ AND typeof(queued_at) IN ('integer', 'real')
1922
+ ) AS present`);
1923
+ hasPendingDropOpsStatements.set(db, statement);
1924
+ }
1925
+ return statement.get(sessionId).present === 1;
1926
+ }
1927
+ function getPendingOpsCount(db, sessionId) {
1928
+ try {
1929
+ let statement = getPendingOpsCountStatements.get(db);
1930
+ if (!statement) {
1931
+ statement = db.prepare("SELECT COUNT(*) AS count FROM pending_ops WHERE session_id = ?");
1932
+ getPendingOpsCountStatements.set(db, statement);
1933
+ }
1934
+ const row = statement.get(sessionId);
1935
+ return typeof row?.count === "number" && Number.isFinite(row.count) ? row.count : null;
1936
+ } catch {
1937
+ return null;
1938
+ }
1939
+ }
1940
+ function clearPendingOps(db, sessionId) {
1941
+ getClearPendingOpsStatement(db).run(sessionId);
1942
+ }
1943
+ function removePendingOp(db, sessionId, tagId) {
1944
+ getRemovePendingOpStatement(db).run(sessionId, tagId);
1945
+ }
1946
+
1686
1947
  // src/features/magic-context/storage-tags.ts
1687
1948
  var insertTagStatements = new WeakMap;
1688
1949
  var updateTagStatusStatements = new WeakMap;
@@ -1828,8 +2089,7 @@ function getActiveToolTagsForAgeReclaim(db, sessionId) {
1828
2089
  reclaimableTokens: outputTokens === null && inputTokens === null ? null : (outputTokens ?? 0) + (inputTokens ?? 0)
1829
2090
  };
1830
2091
  });
1831
- const protectedCtxReduceTags = newestCtxReduceTagNumbers(tags);
1832
- return tags.filter((tag) => !protectedCtxReduceTags.has(tag.tagNumber));
2092
+ return tags;
1833
2093
  }
1834
2094
  function getTriggerTagTokenUpperBound(db, sessionId, floor = 0) {
1835
2095
  const sql = floor > 0 ? `SELECT
@@ -1844,13 +2104,43 @@ function getTriggerTagTokenUpperBound(db, sessionId, floor = 0) {
1844
2104
  const row = floor > 0 ? db.prepare(sql).get(sessionId, floor) : db.prepare(sql).get(sessionId);
1845
2105
  return { bound: row?.bound ?? 0, nullCount: row?.null_count ?? 0 };
1846
2106
  }
1847
- function getActiveTagTokenTotalsByMessage(db, sessionId) {
1848
- const rows = db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
2107
+ var scopedActiveTokenTotalStatements = new WeakMap;
2108
+ function getActiveTagTokenTotalsByMessage(db, sessionId, messageIds) {
2109
+ if (messageIds?.length === 0)
2110
+ return new Map;
2111
+ const fields = "id, tag_number, type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count".split(", ").map((field) => `tags.${field}`).join(", ");
2112
+ let scoped = scopedActiveTokenTotalStatements.get(db);
2113
+ if (messageIds && !scoped) {
2114
+ scoped = db.prepare(`
2115
+ SELECT ${fields} FROM json_each(?) AS owners
2116
+ CROSS JOIN tags INDEXED BY idx_tags_session_message_id
2117
+ WHERE session_id = ? AND tags.type != 'tool' AND +status = 'active'
2118
+ AND message_id >= owners.value || ':' AND message_id < owners.value || ';'
2119
+ UNION
2120
+ SELECT ${fields} FROM tags INDEXED BY idx_tags_session_message_id
2121
+ WHERE session_id = ? AND type != 'tool' AND +status = 'active'
2122
+ AND message_id IN (SELECT value FROM json_each(?))
2123
+ UNION
2124
+ SELECT ${fields} FROM tags INDEXED BY idx_tags_pi_fallback_tool_owner
2125
+ WHERE session_id = ? AND type = 'tool' AND +status = 'active'
2126
+ AND tool_owner_message_id IN (SELECT value FROM json_each(?))
2127
+ UNION
2128
+ SELECT ${fields} FROM tags INDEXED BY idx_tags_session_message_id
2129
+ WHERE session_id = ? AND type = 'tool' AND +status = 'active'
2130
+ AND tool_owner_message_id IS NULL AND message_id IN (SELECT value FROM json_each(?))
2131
+ ORDER BY tag_number, id`);
2132
+ scopedActiveTokenTotalStatements.set(db, scoped);
2133
+ }
2134
+ const owners = messageIds ? new Set(messageIds) : undefined;
2135
+ const encoded = owners ? JSON.stringify([...owners]) : "";
2136
+ const rows = messageIds && scoped ? scoped.all(encoded, sessionId, sessionId, encoded, sessionId, encoded, sessionId, encoded) : db.prepare(`SELECT type, message_id, tool_owner_message_id, token_count, input_token_count, reasoning_token_count
1849
2137
  FROM tags
1850
2138
  WHERE session_id = ? AND status = 'active'`).all(sessionId);
1851
2139
  const out = new Map;
1852
2140
  for (const row of rows) {
1853
2141
  const owner = ownerMessageIdForTagRow(row);
2142
+ if (owners && !owners.has(owner))
2143
+ continue;
1854
2144
  let entry = out.get(owner);
1855
2145
  if (!entry) {
1856
2146
  entry = { conversation: 0, toolCall: 0, toolOutput: 0, hasNull: false };
@@ -1946,7 +2236,7 @@ function getMaxTagNumberBySessionStatement(db) {
1946
2236
  function getTagNumberByMessageIdStatement(db) {
1947
2237
  let stmt = getTagNumberByMessageIdStatements.get(db);
1948
2238
  if (!stmt) {
1949
- stmt = db.prepare("SELECT tag_number FROM tags WHERE session_id = ? AND message_id = ? ORDER BY tag_number ASC LIMIT 1");
2239
+ stmt = db.prepare("SELECT tag_number FROM tags INDEXED BY idx_tags_session_message_id WHERE session_id = ? AND message_id = ? ORDER BY tag_number ASC LIMIT 1");
1950
2240
  getTagNumberByMessageIdStatements.set(db, stmt);
1951
2241
  }
1952
2242
  return stmt;
@@ -2025,20 +2315,24 @@ function markWhitespaceAssistantTagInert(db, sessionId, tagNumber, contentId) {
2025
2315
  entry_fingerprint = ?
2026
2316
  WHERE session_id = ? AND tag_number = ? AND type = 'message'`).run(`${WHITESPACE_ASSISTANT_INERT_MESSAGE_PREFIX}${tagNumber}`, `${WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX}${contentId}`, sessionId, tagNumber);
2027
2317
  }
2318
+ var inertWhitespaceStatements = new WeakMap;
2028
2319
  function getInertWhitespaceAssistantTags(db, sessionId, messageIds) {
2029
2320
  if (messageIds) {
2030
- const statement = db.prepare(`SELECT tag_number AS tagNumber, entry_fingerprint AS entryFingerprint
2031
- FROM tags
2032
- WHERE session_id = ? AND type = 'message' AND status = 'compacted'
2033
- AND entry_fingerprint >= ? AND entry_fingerprint < ?`);
2034
- return [...new Set(messageIds)].flatMap((messageId) => {
2035
- const prefix = `${WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX}${messageId}:p`;
2036
- const rows = statement.all(sessionId, prefix, `${prefix.slice(0, -1)}q`);
2037
- return rows.map((row) => ({
2038
- tagNumber: row.tagNumber,
2039
- contentId: row.entryFingerprint.slice(WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX.length)
2040
- }));
2041
- });
2321
+ let statement = inertWhitespaceStatements.get(db);
2322
+ if (!statement) {
2323
+ statement = db.prepare(`SELECT tag_number AS tagNumber, entry_fingerprint AS entryFingerprint
2324
+ FROM json_each(?) AS owners CROSS JOIN tags
2325
+ WHERE tags.session_id = ? AND tags.type = 'message' AND tags.status = 'compacted'
2326
+ AND entry_fingerprint >= ? || owners.value || ':p'
2327
+ AND entry_fingerprint < ? || owners.value || ':q'
2328
+ ORDER BY CAST(owners.key AS INTEGER), entry_fingerprint, tags.id`);
2329
+ inertWhitespaceStatements.set(db, statement);
2330
+ }
2331
+ const rows = statement.all(JSON.stringify([...new Set(messageIds)]), sessionId, WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX, WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX);
2332
+ return rows.map((row) => ({
2333
+ tagNumber: row.tagNumber,
2334
+ contentId: row.entryFingerprint.slice(WHITESPACE_ASSISTANT_INERT_FINGERPRINT_PREFIX.length)
2335
+ }));
2042
2336
  }
2043
2337
  const rows = db.prepare(`SELECT tag_number AS tagNumber, entry_fingerprint AS entryFingerprint
2044
2338
  FROM tags
@@ -2248,9 +2542,9 @@ function foldShrunkPartTags(db, sessionId, messages) {
2248
2542
  result.foldedTagNumbers.sort((a, b) => a - b);
2249
2543
  return result;
2250
2544
  }
2251
- function markTagsCompactedByMessageIds(db, sessionId, messageIds) {
2545
+ function markTagsCompactedByMessageIds(db, sessionId, messageIds, eligibleTagNumbers) {
2252
2546
  const ids = new Set(messageIds);
2253
- if (ids.size === 0)
2547
+ if (ids.size === 0 || eligibleTagNumbers?.size === 0)
2254
2548
  return 0;
2255
2549
  const asciiLower = (value) => value.replace(/[A-Z]/g, (char) => char.toLowerCase());
2256
2550
  const foldedIds = new Set(Array.from(ids, asciiLower));
@@ -2276,7 +2570,7 @@ function markTagsCompactedByMessageIds(db, sessionId, messageIds) {
2276
2570
  const rows = db.prepare(`WITH ids AS MATERIALIZED (
2277
2571
  SELECT value AS source_id, lower(value) AS folded_id FROM json_each(?)
2278
2572
  )
2279
- SELECT id, message_id, tool_owner_message_id FROM tags INDEXED BY idx_tags_session_tag_number
2573
+ SELECT id, tag_number, message_id, tool_owner_message_id FROM tags INDEXED BY ${tagOrderConstraintIndex(db)}
2280
2574
  WHERE session_id = ? AND status IN ('active', 'dropped') AND (
2281
2575
  message_id IN (SELECT source_id FROM ids)
2282
2576
  OR tool_owner_message_id IN (SELECT source_id FROM ids)
@@ -2287,14 +2581,14 @@ function markTagsCompactedByMessageIds(db, sessionId, messageIds) {
2287
2581
  OR (? AND instr(message_id, ':') > 0)
2288
2582
  OR ?
2289
2583
  )`).all(JSON.stringify(Array.from(ids)), sessionId, Array.from(ids).some((id) => id.includes(":")) ? 1 : 0, nulPrefixes.size > 0 ? 1 : 0);
2290
- const candidates = rows.filter((row) => matches(row.message_id, row.tool_owner_message_id));
2584
+ const candidates = rows.filter((row) => (eligibleTagNumbers === undefined || eligibleTagNumbers.has(row.tag_number)) && matches(row.message_id, row.tool_owner_message_id));
2291
2585
  if (candidates.length === 0)
2292
2586
  return 0;
2293
2587
  const update = db.prepare(`UPDATE tags SET status = 'compacted'
2294
2588
  WHERE id = ? AND session_id = ?
2295
2589
  AND status IN ('active', 'dropped')
2296
2590
  AND message_id IS ? AND tool_owner_message_id IS ?
2297
- RETURNING id`);
2591
+ RETURNING tag_number`);
2298
2592
  let cursor = 0;
2299
2593
  let changed = 0;
2300
2594
  const batch = db.transaction(() => {
@@ -2302,8 +2596,11 @@ function markTagsCompactedByMessageIds(db, sessionId, messageIds) {
2302
2596
  let processed = 0;
2303
2597
  do {
2304
2598
  const row = candidates[cursor++];
2305
- if (update.get(row.id, sessionId, row.message_id, row.tool_owner_message_id))
2599
+ const retired = update.get(row.id, sessionId, row.message_id, row.tool_owner_message_id);
2600
+ if (retired) {
2601
+ removePendingOp(db, sessionId, retired.tag_number);
2306
2602
  changed++;
2603
+ }
2307
2604
  processed++;
2308
2605
  } while (cursor < candidates.length && processed < 128 && performance.now() - start < 8);
2309
2606
  });
@@ -2480,6 +2777,25 @@ function getTagsByNumbers(db, sessionId, tagNumbers) {
2480
2777
  const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND tag_number IN (${placeholders}) ORDER BY tag_number ASC, id ASC`).all(sessionId, ...tagNumbers).filter(isTagRow);
2481
2778
  return rows.map(toTagEntry);
2482
2779
  }
2780
+ var newestToolTagNumberStatements = new WeakMap;
2781
+ function getNewestToolTagNumbers(db, sessionId, limit) {
2782
+ if (limit <= 0)
2783
+ return [];
2784
+ let statement = newestToolTagNumberStatements.get(db);
2785
+ if (!statement) {
2786
+ statement = db.prepare(`SELECT tag_number FROM tags
2787
+ WHERE session_id = ? AND type = 'tool'
2788
+ AND typeof(message_id) = 'text'
2789
+ AND typeof(status) = 'text'
2790
+ AND typeof(byte_size) IN ('integer', 'real')
2791
+ AND typeof(tag_number) IN ('integer', 'real')
2792
+ ORDER BY tag_number DESC
2793
+ LIMIT ?`);
2794
+ newestToolTagNumberStatements.set(db, statement);
2795
+ }
2796
+ return statement.all(sessionId, limit).map((row) => row.tag_number);
2797
+ }
2798
+ var droppedNumberStatements = new WeakMap;
2483
2799
  function getDroppedTagsByNumbers(db, sessionId, tagNumbers) {
2484
2800
  if (tagNumbers.length === 0)
2485
2801
  return [];
@@ -2490,16 +2806,26 @@ function getDroppedTagsByNumbers(db, sessionId, tagNumbers) {
2490
2806
  }
2491
2807
  return all;
2492
2808
  }
2493
- const placeholders = tagNumbers.map(() => "?").join(",");
2494
- const rows = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND status = 'dropped' AND tag_number IN (${placeholders}) ORDER BY tag_number ASC, id ASC`).all(sessionId, ...tagNumbers).filter(isTagRow);
2809
+ let statement = droppedNumberStatements.get(db);
2810
+ if (!statement) {
2811
+ statement = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND status = 'dropped' AND tag_number IN (SELECT value FROM json_each(?)) ORDER BY tag_number ASC, id ASC`);
2812
+ droppedNumberStatements.set(db, statement);
2813
+ }
2814
+ const rows = statement.all(sessionId, JSON.stringify(tagNumbers)).filter(isTagRow);
2495
2815
  return rows.map(toTagEntry);
2496
2816
  }
2497
2817
  function getMaxDroppedTagNumber(db, sessionId) {
2498
2818
  const row = getMaxDroppedTagNumberStatement(db).get(sessionId);
2499
2819
  return isMaxTagNumberRow(row) ? row.max_tag_number : 0;
2500
2820
  }
2821
+ var tagByIdStatements = new WeakMap;
2501
2822
  function getTagById(db, sessionId, tagId) {
2502
- const result = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND tag_number = ?`).get(sessionId, tagId);
2823
+ let statement = tagByIdStatements.get(db);
2824
+ if (!statement) {
2825
+ statement = db.prepare(`SELECT ${TAG_SELECT_COLUMNS} FROM tags WHERE session_id = ? AND tag_number = ?`);
2826
+ tagByIdStatements.set(db, statement);
2827
+ }
2828
+ const result = statement.get(sessionId, tagId);
2503
2829
  if (!isTagRow(result)) {
2504
2830
  return null;
2505
2831
  }
@@ -2932,19 +3258,25 @@ function countRawSessionMessageOrdinalsFromDb(db, sessionId) {
2932
3258
  )`).get(sessionId);
2933
3259
  return typeof row?.count === "number" ? row.count : 0;
2934
3260
  }
2935
- function readRawSessionMessageIdOrdinalsFromDb(db, sessionId) {
2936
- const messageRows = db.prepare("SELECT id, data FROM message WHERE session_id = ? ORDER BY time_created ASC, id ASC").all(sessionId).filter(isRawMessageRow);
2937
- const ordinalById = new Map;
2938
- let ordinal = 0;
2939
- for (const row of messageRows) {
2940
- const info = parseJsonRecord(row.data);
2941
- if (isRawCompactionSummaryInfo(info))
2942
- continue;
2943
- ordinal += 1;
2944
- if (info)
2945
- ordinalById.set(row.id, ordinal);
3261
+ function readRawSessionMessageIdOrdinalsForRangeFromDb(db, sessionId, fromOrdinal, toOrdinal) {
3262
+ const from = Math.max(1, Math.floor(fromOrdinal));
3263
+ const to = Math.floor(toOrdinal);
3264
+ if (to < from)
3265
+ return new Map;
3266
+ const rows = db.prepare(`
3267
+ SELECT id, data FROM message WHERE session_id = ?
3268
+ AND CASE WHEN json_valid(data) THEN NOT (
3269
+ COALESCE(json_type(data, '$.summary'), '') = 'true'
3270
+ AND COALESCE(json_extract(data, '$.finish'), '') = 'stop'
3271
+ ) ELSE 1 END
3272
+ ORDER BY time_created, id LIMIT ? OFFSET ?
3273
+ `).all(sessionId, to - from + 1, from - 1).filter(isRawMessageRow);
3274
+ const result = new Map;
3275
+ for (const [index, row] of rows.entries()) {
3276
+ if (parseJsonRecord(row.data))
3277
+ result.set(row.id, from + index);
2946
3278
  }
2947
- return ordinalById;
3279
+ return result;
2948
3280
  }
2949
3281
  function readRawSessionMessageOrdinalPageFromDb(db, sessionId, after, limit) {
2950
3282
  const pageSize = Math.max(1, Math.floor(limit));
@@ -3153,6 +3485,17 @@ function readRawSessionMessageByIdFromDb(db, sessionId, messageId) {
3153
3485
  version: row.time_updated ?? null
3154
3486
  };
3155
3487
  }
3488
+ function hasRawSessionMessageByIdFromDb(db, sessionId, messageId) {
3489
+ const row = db.prepare("SELECT id, data, time_created FROM message WHERE session_id = ? AND id = ?").get(sessionId, messageId);
3490
+ if (!row || !isRawMessageRow(row) || typeof row.time_created !== "number")
3491
+ return false;
3492
+ const info = parseJsonRecord(row.data);
3493
+ if (!info || isRawCompactionSummaryInfo(info))
3494
+ return false;
3495
+ if (info.summary === 1 && info.finish === "stop")
3496
+ return readRawSessionMessageByIdFromDb(db, sessionId, messageId) !== null;
3497
+ return true;
3498
+ }
3156
3499
  function readRawSeedTailFromDb(db, sessionId, boundaryId) {
3157
3500
  const rows = db.prepare(`
3158
3501
  WITH canonical AS (
@@ -3201,6 +3544,7 @@ var MAX_MESSAGE_CACHE_KEY_BYTES = 64 * 1024 * 1024;
3201
3544
  var FNV1A_32_OFFSET2 = 2166136261;
3202
3545
  var FNV1A_32_PRIME2 = 16777619;
3203
3546
  var messageEstimateCache = new Map;
3547
+ var messageEstimateKeysByField = new Map;
3204
3548
  var messageEstimateCacheBytes = 0;
3205
3549
  var EMPTY_BREAKDOWN = {
3206
3550
  text: 0,
@@ -3408,16 +3752,33 @@ function setCachedEstimate(key, breakdown) {
3408
3752
  const existing = messageEstimateCache.get(key);
3409
3753
  if (existing)
3410
3754
  messageEstimateCacheBytes -= existing.keyEstimateBytes;
3755
+ else {
3756
+ for (const field of new Set(key.split("\x00").slice(1, -1))) {
3757
+ const keys = messageEstimateKeysByField.get(field) ?? new Set;
3758
+ keys.add(key);
3759
+ messageEstimateKeysByField.set(field, keys);
3760
+ }
3761
+ }
3411
3762
  messageEstimateCache.set(key, { breakdown, keyEstimateBytes });
3412
3763
  messageEstimateCacheBytes += keyEstimateBytes;
3413
3764
  while (messageEstimateCache.size > MAX_MESSAGE_CACHE_ENTRIES || messageEstimateCacheBytes > MAX_MESSAGE_CACHE_KEY_BYTES) {
3414
3765
  const first = messageEstimateCache.keys().next().value;
3415
3766
  if (typeof first !== "string")
3416
3767
  break;
3417
- const removed = messageEstimateCache.get(first);
3418
- if (removed)
3419
- messageEstimateCacheBytes -= removed.keyEstimateBytes;
3420
- messageEstimateCache.delete(first);
3768
+ deleteCachedEstimate(first);
3769
+ }
3770
+ }
3771
+ function deleteCachedEstimate(key) {
3772
+ const removed = messageEstimateCache.get(key);
3773
+ if (!removed)
3774
+ return;
3775
+ messageEstimateCacheBytes -= removed.keyEstimateBytes;
3776
+ messageEstimateCache.delete(key);
3777
+ for (const field of new Set(key.split("\x00").slice(1, -1))) {
3778
+ const keys = messageEstimateKeysByField.get(field);
3779
+ keys?.delete(key);
3780
+ if (keys?.size === 0)
3781
+ messageEstimateKeysByField.delete(field);
3421
3782
  }
3422
3783
  }
3423
3784
  function cloneBreakdown(value) {
@@ -3716,12 +4077,12 @@ function computeRawRangeFingerprint(messages, startInclusive, endExclusive) {
3716
4077
  function invalidateTrueRawTokenCache(args) {
3717
4078
  const sessionNeedle = args.sessionId ? `${args.sessionId}` : null;
3718
4079
  const messageNeedle = args.messageId ? `\x00${args.messageId}\x00` : null;
3719
- for (const [key, value] of messageEstimateCache) {
4080
+ const keys = args.messageId && !args.messageId.includes("\x00") ? messageEstimateKeysByField.get(args.messageId) ?? [] : messageEstimateCache.keys();
4081
+ for (const key of keys) {
3720
4082
  const sessionMatches = sessionNeedle === null || key.includes(sessionNeedle);
3721
4083
  const messageMatches = messageNeedle === null || key.includes(messageNeedle);
3722
4084
  if (sessionMatches && messageMatches) {
3723
- messageEstimateCache.delete(key);
3724
- messageEstimateCacheBytes -= value.keyEstimateBytes;
4085
+ deleteCachedEstimate(key);
3725
4086
  }
3726
4087
  }
3727
4088
  args.reason;
@@ -4176,9 +4537,12 @@ function serializedText(value) {
4176
4537
  return "";
4177
4538
  return (typeof value === "string" ? value : JSON.stringify(value)) ?? "";
4178
4539
  }
4179
- function serializedTokens(value) {
4540
+ var wireTextTokens = createTokenCountMemo(1e5, 128 * 1024 * 1024);
4541
+ function serializedTokens(value, bounded = false) {
4180
4542
  const serialized = serializedText(value);
4181
- return serialized ? estimateTokens(serialized) : 0;
4543
+ if (bounded && tokenCountUsesByteBound(serialized))
4544
+ return Buffer.byteLength(serialized);
4545
+ return serialized ? wireTextTokens(serialized) : 0;
4182
4546
  }
4183
4547
  function visitWireContent(message, visit) {
4184
4548
  for (const part of message.parts) {
@@ -4238,11 +4602,11 @@ function visitWireContent(message, visit) {
4238
4602
  }
4239
4603
  }
4240
4604
  }
4241
- function estimateMessageTokens(message) {
4605
+ function estimateMessageTokens(message, bounded = false) {
4242
4606
  const total = { conversation: 0, toolCall: 0 };
4243
4607
  visitWireContent(message, {
4244
4608
  text: (bucket, value) => {
4245
- total[bucket] += serializedTokens(value);
4609
+ total[bucket] += serializedTokens(value, bounded);
4246
4610
  },
4247
4611
  image: (bucket, tokens) => {
4248
4612
  total[bucket] += tokens;
@@ -4270,9 +4634,99 @@ function wireContentBytes(messages, abortAboveBytes, bytesPerToken) {
4270
4634
  }
4271
4635
  return { bytes, aborted: false };
4272
4636
  }
4637
+ function createFinalWireUsageTracker() {
4638
+ const served = new Map;
4639
+ const wireRows = (input) => input.messages.filter((message) => message.parts.some((part) => !part || typeof part !== "object" || !["step-start", "step-finish"].includes(String(part.type))));
4640
+ const rowBytes = (message) => JSON.stringify({ id: message.info.id, role: message.info.role, parts: message.parts });
4641
+ const envelopeFor = (input) => {
4642
+ if (!input.providerID || !input.modelID || !input.systemPromptHash)
4643
+ return;
4644
+ const tools = getToolDefinitionMeasurementSignature(input.providerID, input.modelID, input.agentName);
4645
+ if (!tools)
4646
+ return;
4647
+ return JSON.stringify([
4648
+ input.providerID,
4649
+ input.modelID,
4650
+ input.agentName,
4651
+ input.systemPromptHash,
4652
+ input.systemPromptTokens,
4653
+ tools
4654
+ ]);
4655
+ };
4656
+ return {
4657
+ estimate(sessionId, input, limit) {
4658
+ let measuredPrefix;
4659
+ try {
4660
+ const previous = served.get(sessionId);
4661
+ const rows = wireRows(input);
4662
+ if (previous && previous.envelope === envelopeFor(input) && rows.length > previous.prefix.length && previous.prefix.every((bytes, i) => rowBytes(rows[i]) === bytes)) {
4663
+ const reply = rows[previous.prefix.length]?.info;
4664
+ const tokens = reply.tokens;
4665
+ const time = reply.time;
4666
+ const counts = [tokens?.input, tokens?.cache?.read, tokens?.cache?.write];
4667
+ if (reply.role === "assistant" && reply.parentID === previous.parent && reply.providerID === input.providerID && reply.modelID === input.modelID && ["stop", "tool-calls", "length"].includes(String(reply.finish)) && !reply.error && typeof time?.completed === "number" && time.completed >= previous.at && counts.every((n) => typeof n === "number" && Number.isSafeInteger(n) && n >= 0)) {
4668
+ const inputTokens = counts.reduce((sum, n) => sum + (n ?? 0), 0);
4669
+ if (inputTokens > 0)
4670
+ measuredPrefix = {
4671
+ inputTokens,
4672
+ appendedMessages: rows.slice(previous.prefix.length)
4673
+ };
4674
+ }
4675
+ }
4676
+ } catch {}
4677
+ return estimateOutgoingWireForRefusal({ ...input, measuredPrefix }, limit);
4678
+ },
4679
+ capture(sessionId, input) {
4680
+ served.delete(sessionId);
4681
+ try {
4682
+ const envelope = envelopeFor(input);
4683
+ const rows = wireRows(input);
4684
+ const parent = [...rows].reverse().find((row) => row.info.role === "user")?.info.id;
4685
+ if (!envelope || typeof parent !== "string" || !rows.every(hasCountableParts))
4686
+ return;
4687
+ const prefix = rows.map(rowBytes);
4688
+ if (prefix.reduce((sum, text) => sum + text.length, 0) > 4 * 1024 * 1024)
4689
+ return;
4690
+ if (served.size >= 16)
4691
+ served.delete(served.keys().next().value);
4692
+ served.set(sessionId, { envelope, prefix, parent, at: Date.now() });
4693
+ } catch {}
4694
+ }
4695
+ };
4696
+ }
4697
+ function estimateOutgoingWireForRefusal(input, limit) {
4698
+ if (typeof limit === "number" && Number.isFinite(limit) && limit > 0) {
4699
+ const measured = input.measuredPrefix;
4700
+ const baseline = measured?.inputTokens ?? 0;
4701
+ const pricedMessages = measured?.appendedMessages ?? input.messages;
4702
+ const bytes = wireContentBytes(pricedMessages, Math.max(0, limit - baseline) * 4, 4);
4703
+ if (bytes) {
4704
+ const lower = baseline + Math.ceil(bytes.bytes / 4);
4705
+ const calibration = resolveDecisionCalibration(input.providerID, input.modelID);
4706
+ const tools = input.providerID && input.modelID ? getMeasuredToolDefinitionTokens(input.providerID, input.modelID, input.agentName) : undefined;
4707
+ const envelope = measured ? baseline : tools !== undefined && Number.isFinite(input.systemPromptTokens) && input.systemPromptTokens > 0 ? providerMass({ system: input.systemPromptTokens, tools }, calibration, true) : undefined;
4708
+ const upper = envelope === undefined ? undefined : envelope + Math.ceil(bytes.bytes * Math.max(UNKNOWN_FIT_RATIO, calibration.toolsRatio, calibration.proseRatio));
4709
+ if (bytes.aborted || lower > limit || upper !== undefined && upper <= limit) {
4710
+ const over = bytes.aborted || lower > limit;
4711
+ return {
4712
+ tokens: over ? lower : upper,
4713
+ trusted: !over,
4714
+ refusalGrade: over && envelope !== undefined,
4715
+ refusalTokens: over ? lower : undefined,
4716
+ refusalBasis: "byte-bound",
4717
+ messageTokens: { conversation: 0, toolCall: 0 },
4718
+ systemTokens: input.systemPromptTokens,
4719
+ toolDefinitionTokens: tools,
4720
+ toolDefinitionsMeasured: tools !== undefined
4721
+ };
4722
+ }
4723
+ }
4724
+ }
4725
+ return estimateFinalWireInputTokens({ ...input, boundedTokenization: true });
4726
+ }
4273
4727
  function estimateFinalWireInputTokens(input) {
4274
4728
  const messageTokens = input.messages.reduce((total, message) => {
4275
- const next = estimateMessageTokens(message);
4729
+ const next = estimateMessageTokens(message, input.boundedTokenization);
4276
4730
  total.conversation += next.conversation;
4277
4731
  total.toolCall += next.toolCall;
4278
4732
  return total;
@@ -4288,11 +4742,25 @@ function estimateFinalWireInputTokens(input) {
4288
4742
  };
4289
4743
  const tokens = providerMass(rawComponents, calibration, true);
4290
4744
  const complete = Number.isFinite(tokens) && tokens > 0 && Number.isFinite(input.systemPromptTokens) && input.systemPromptTokens > 0 && toolDefinitions !== undefined && input.messages.every(hasCountableParts);
4745
+ const refusalGrade = complete && hasTokenizerForFit() && measuredToolDefinitions !== undefined && hasMeasuredDecisionCalibration(calibration) && input.messages.every(hasRefusalCountableParts);
4746
+ const measured = input.measuredPrefix;
4747
+ const useMeasured = refusalGrade && measured && Number.isSafeInteger(measured.inputTokens) && measured.inputTokens > 0 && measured.appendedMessages.every(hasCountableParts);
4748
+ const tail = useMeasured ? measured.appendedMessages.reduce((sum, message) => {
4749
+ const next = estimateMessageTokens(message, input.boundedTokenization);
4750
+ return {
4751
+ conversation: sum.conversation + next.conversation,
4752
+ toolCall: sum.toolCall + next.toolCall
4753
+ };
4754
+ }, { conversation: 0, toolCall: 0 }) : undefined;
4755
+ const refusalTokens = refusalGrade ? tail && measured ? measured.inputTokens + providerMass({ tools: tail.toolCall, prose: tail.conversation }, calibration) : providerMass(rawComponents, calibration) : undefined;
4291
4756
  const systemTokens = Math.round(Math.max(0, input.systemPromptTokens) * calibration.systemRatio);
4292
4757
  const toolDefinitionTokens = toolDefinitions === undefined ? undefined : Math.round(toolDefinitions * (calibration.seeded ? calibration.toolsRatio : UNKNOWN_FIT_RATIO));
4293
4758
  return {
4294
4759
  tokens,
4295
4760
  trusted: complete,
4761
+ refusalGrade,
4762
+ refusalTokens,
4763
+ refusalBasis: refusalGrade ? useMeasured ? "provider-prefix" : "calibrated" : undefined,
4296
4764
  rawTokens: rawComponents.system + rawComponents.tools + rawComponents.prose,
4297
4765
  rawComponents,
4298
4766
  completeness: complete ? "complete" : "partial",
@@ -4303,6 +4771,33 @@ function estimateFinalWireInputTokens(input) {
4303
4771
  toolDefinitionsMeasured: measuredToolDefinitions !== undefined
4304
4772
  };
4305
4773
  }
4774
+ function hasRefusalCountableParts(message) {
4775
+ let exact = true;
4776
+ visitWireContent(message, {
4777
+ text: (_bucket, value) => {
4778
+ if (tokenCountUsesByteBound(serializedText(value)))
4779
+ exact = false;
4780
+ },
4781
+ image: () => {}
4782
+ });
4783
+ return exact;
4784
+ }
4785
+ function estimateAppendedWireTokens(input) {
4786
+ const messageTokens = input.messages.reduce((total, message) => {
4787
+ const next = estimateMessageTokens(message);
4788
+ total.conversation += next.conversation;
4789
+ total.toolCall += next.toolCall;
4790
+ return total;
4791
+ }, { conversation: 0, toolCall: 0 });
4792
+ const tokens = providerMass({ prose: messageTokens.conversation, tools: messageTokens.toolCall }, resolveDecisionCalibration(input.providerID, input.modelID), true);
4793
+ return {
4794
+ tokens,
4795
+ trusted: hasTokenizerForFit() && Number.isFinite(tokens) && tokens >= 0 && input.messages.every(hasCountableParts),
4796
+ messageTokens,
4797
+ systemTokens: 0,
4798
+ toolDefinitionTokens: 0
4799
+ };
4800
+ }
4306
4801
  function hasCountableParts(message) {
4307
4802
  return message.parts.every((part) => {
4308
4803
  if (!part || typeof part !== "object")
@@ -4950,12 +5445,15 @@ class ToolMutationBatch {
4950
5445
  }
4951
5446
  const scopedSweep = this.resolveScopedSweep();
4952
5447
  const removed = new Set;
4953
- for (let i = this.messages.length - 1;i >= 0; i -= 1) {
5448
+ let writeIndex = 0;
5449
+ for (let i = 0;i < this.messages.length; i += 1) {
4954
5450
  if ((!scopedSweep || this.affectedMessages.has(this.messages[i])) && !this.messages[i].parts.some(hasMeaningfulPart)) {
4955
5451
  removed.add(this.messages[i]);
4956
- this.messages.splice(i, 1);
5452
+ } else {
5453
+ this.messages[writeIndex++] = this.messages[i];
4957
5454
  }
4958
5455
  }
5456
+ this.messages.length = writeIndex;
4959
5457
  this.pruneServedRows(removed);
4960
5458
  this.partsToRemove.clear();
4961
5459
  this.affectedMessages.clear();
@@ -5272,17 +5770,17 @@ function readRawSessionMessages2(sessionId) {
5272
5770
  }
5273
5771
  return readRawSessionMessagesFromSource(sessionId);
5274
5772
  }
5275
- function readRawSessionMessagePage2(sessionId, afterOrdinal, limit, finalWatermark) {
5773
+ function readRawSessionMessagePage2(sessionId, afterOrdinal, limit, finalWatermark, after) {
5276
5774
  const provider = sessionProviders.get(sessionId)?.provider;
5277
5775
  if (provider?.readMessagePage) {
5278
- return provider.readMessagePage(afterOrdinal, limit, finalWatermark);
5776
+ return provider.readMessagePage(afterOrdinal, limit, finalWatermark, after);
5279
5777
  }
5280
5778
  if (provider) {
5281
5779
  return provider.readMessages().filter((message) => message.ordinal > afterOrdinal && message.ordinal <= finalWatermark).slice(0, limit);
5282
5780
  }
5283
5781
  if (!openCodeDbExists())
5284
5782
  return [];
5285
- return withReadOnlySessionDb((db) => readRawSessionMessagePageFromDb(db, sessionId, afterOrdinal, limit, finalWatermark));
5783
+ return withReadOnlySessionDb((db) => readRawSessionMessagePageFromDb(db, sessionId, afterOrdinal, limit, finalWatermark, after));
5286
5784
  }
5287
5785
  function getRawSessionMessageOrdinalCount2(sessionId) {
5288
5786
  const provider = sessionProviders.get(sessionId)?.provider;
@@ -5495,7 +5993,10 @@ function readRawSessionMessageIdOrdinalsForRange2(sessionId, fromOrdinal, toOrdi
5495
5993
  if (provider?.readMessageIdOrdinalsForRange) {
5496
5994
  return provider.readMessageIdOrdinalsForRange(from, to);
5497
5995
  }
5498
- const all = provider?.readMessageIdOrdinals ? provider.readMessageIdOrdinals() : provider ? new Map(provider.readMessages().map((message) => [message.id, message.ordinal])) : !openCodeDbExists() ? new Map : withReadOnlySessionDb((db) => readRawSessionMessageIdOrdinalsFromDb(db, sessionId));
5996
+ if (!provider) {
5997
+ return !openCodeDbExists() ? new Map : withReadOnlySessionDb((db) => readRawSessionMessageIdOrdinalsForRangeFromDb(db, sessionId, from, to));
5998
+ }
5999
+ const all = provider?.readMessageIdOrdinals ? provider.readMessageIdOrdinals() : new Map(provider.readMessages().map((message) => [message.id, message.ordinal]));
5499
6000
  return new Map([...all].filter(([, ordinal]) => ordinal >= from && ordinal <= to));
5500
6001
  }
5501
6002
  function readRawSessionMessageIdOrdinals2(sessionId) {
@@ -5519,6 +6020,8 @@ function hasRawSessionMessageById2(sessionId, messageId) {
5519
6020
  const provider = sessionProviders.get(sessionId)?.provider;
5520
6021
  if (provider?.hasMessageById)
5521
6022
  return provider.hasMessageById(messageId);
6023
+ if (!provider)
6024
+ return openCodeDbExists() && withReadOnlySessionDb((db) => hasRawSessionMessageByIdFromDb(db, sessionId, messageId));
5522
6025
  return readRawSessionMessageById2(sessionId, messageId) !== null;
5523
6026
  }
5524
6027
  function readRawSessionMessageOrdinalById2(sessionId, messageId) {
@@ -5662,8 +6165,9 @@ async function getRawSessionTagKeysThrough2(sessionId, upToMessageIndex, options
5662
6165
  };
5663
6166
  const firstOrdinal = Number.isFinite(options.fromMessageIndex) ? Math.max(1, Math.floor(options.fromMessageIndex ?? 1)) : 1;
5664
6167
  let afterOrdinal = firstOrdinal - 1;
6168
+ let after;
5665
6169
  while (afterOrdinal < finalWatermark) {
5666
- const messages = readRawSessionMessages2.readPage(sessionId, afterOrdinal, pageSize, finalWatermark);
6170
+ const messages = readRawSessionMessages2.readPage(sessionId, afterOrdinal, pageSize, finalWatermark, after);
5667
6171
  if (messages.length === 0)
5668
6172
  break;
5669
6173
  let nextOrdinal = afterOrdinal;
@@ -5705,6 +6209,8 @@ async function getRawSessionTagKeysThrough2(sessionId, upToMessageIndex, options
5705
6209
  if (nextOrdinal <= afterOrdinal)
5706
6210
  break;
5707
6211
  afterOrdinal = nextOrdinal;
6212
+ const last = messages.at(-1);
6213
+ after = last ? { timeCreated: last.createdAt ?? 0, id: last.id } : undefined;
5708
6214
  if (afterOrdinal < finalWatermark)
5709
6215
  await yieldToEventLoop();
5710
6216
  }
@@ -6031,4 +6537,4 @@ function readRawSessionSeedTail2(sessionId, boundaryId, onQuery) {
6031
6537
  });
6032
6538
  }
6033
6539
 
6034
- export { CTX_REDUCE_KEEP, newestCtxReduceTagNumbers, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isThinkingPart, isRecord, contentTagOwnerMessageId, estimateImageTokensFromDataUrl, estimateToolAttachmentImageTokens, normalizeTodoStateJson, buildSyntheticTodoPart, computeSyntheticCallId, isSyntheticTodoPart, countRealUserMessages, tailHygieneStructuralSignature, sameTailHygieneStructuralSignature, formatTailHygienePrefixMismatch, refreshTailHygieneBaseline, effectiveTailHygiene, assertTailHygieneContentUnchanged, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, isDroppedToolOutput, toolOutputTokens, decideChannel1, evaluateChannel2, formatChannel1Evaluation, formatChannel2Evaluation, reclaimableToolOutputCount, buildChannel2Reminder, buildChannel1Reminder, estimateEmergencyDropReclaimTokens, planEmergencyDrop, measureEmergencyTag, getRecentTagOwnerMessageIds, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, getAllStatusTagTokenTotalsFlat, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, markWhitespaceAssistantTagInert, getInertWhitespaceAssistantTags, updateTagDropMode, updateCavemanDepth, updateTagMessageId, foldShrunkPartTags, markTagsCompactedByMessageIds, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, getAssignableTagNumberByMessageId, deriveTagLoadFloor, TAG_SELECT_COLUMNS, getTagsBySession, getActiveTagsBySession, getTailHygieneTags, getDroppedTagsBySession, getTagsByNumbers, getDroppedTagsByNumbers, getMaxDroppedTagNumber, getTagById, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, expandToolPart, markHostUnservedRow, retreatPastHostUnservedRows, snapTerminalCompartmentToServedRow, isHostRenderedSystemMessage, isStrictGapHealingMessage, isRawCompactionSummaryInfo, extractInMemoryMessageViews, buildInMemoryTailRawMessages, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForCompletedToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripSystemInjection, isTextPart, isToolPartWithOutput, isFilePart, buildFileSourceContent, toolPartHasUserAnswer, DreamTokenBudgetExceeded, TOKEN_BUDGET_FINALIZE_MESSAGE, registerBudgetFinalizeChild, releaseBudgetFinalizeChild, createDreamTokenBudget, recordToolParameters, createDroppedInputGuard, assertExecutableToolInput, createDroppedInputToolExecuteBeforeHook, isEditTool, describeFinalWireTail, estimateMessageTokens, wireContentBytes, estimateFinalWireInputTokens, detectThinkingBindingMismatch, isPrefixBoundThinkingModel, detectOverflow, modelAcceptsEmptyContent, isAnthropicFamilyRoute, neutralizeDroppedReasoningPart, restoreNeutralizedReasoningPart, isNeutralizedReasoningPart, variantChangeBustsProviderCache, makeSentinel, makeWholeMessageSentinel, isSentinel, replaySentinelByMessageIds, SKELETON_REAL_INPUT_MAX_BYTES, partHasCompletedResult, extractToolCallObservation, ToolMutationBatch, createToolDropTarget, resolveHostServedBoundaryId2, hasRawMessageProvider2, setRawMessageProvider2, setBoundedRawMessageProvider2, withRawMessageProvider2, cleanUserText2, withRawSessionMessageCache2, readRawSessionMessages2, readRawSessionMessagePage2, getRawSessionMessageOrdinalCount2, RAW_MESSAGE_VISIT_PAGE_SIZE2, visitRawSessionMessages2, readRawSessionMessageRange2, primeTailRawMessageCache2, getCachedAbsoluteMessageCount2, primeInMemoryTailRawMessageCache2, readRawSessionMessageOrdinalPage2, getRawSessionStoredMessageCount2, readRawSessionMessageIdOrdinalsForRange2, readRawSessionMessageIdOrdinals2, readRawSessionMessagePartsById2, hasRawSessionMessageById2, readRawSessionMessageOrdinalById2, compareRawSessionMessageOrder2, readRawSessionMessageById2, getRawSessionMessageCount2, RAW_SESSION_TAG_KEY_PAGE_SIZE2, getRawSessionTagKeysThrough2, getLegacyProtectedTailStartOrdinal2, getProtectedTailStartOrdinal2, readSessionChunk2, getRawSessionMessageIdsThrough2, readRawSessionSeedTail2 };
6540
+ export { protectedToolTagNumbers, protectedToolTokenCount, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isThinkingPart, isRecord, contentTagOwnerMessageId, estimateImageTokensFromDataUrl, estimateToolAttachmentImageTokens, normalizeTodoStateJson, buildSyntheticTodoPart, computeSyntheticCallId, isSyntheticTodoPart, countRealUserMessages, tailHygieneStructuralSignature, sameTailHygieneStructuralSignature, formatTailHygienePrefixMismatch, refreshTailHygieneBaseline, effectiveTailHygiene, assertTailHygieneContentUnchangedIfEnabled, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, isDroppedToolOutput, toolOutputTokens, decideChannel1, evaluateChannel2, formatChannel1Evaluation, formatChannel2Evaluation, reclaimableToolOutputCount, buildChannel2Reminder, buildChannel1Reminder, estimateEmergencyDropReclaimTokens, planEmergencyDrop, measureEmergencyTag, queuePendingOp, queuePendingDropForUnchangedTag, getPendingOps, hasPendingDropOps, getPendingOpsCount, clearPendingOps, removePendingOp, getRecentTagOwnerMessageIds, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, getActiveTagTokenTotalsByMessage, getAllStatusTagTokenTotalsFlat, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, markWhitespaceAssistantTagInert, getInertWhitespaceAssistantTags, updateTagDropMode, updateCavemanDepth, updateTagMessageId, foldShrunkPartTags, markTagsCompactedByMessageIds, deleteTagsByMessageId, getMaxTagNumberBySession, getTagNumberByMessageId, getAssignableTagNumberByMessageId, deriveTagLoadFloor, TAG_SELECT_COLUMNS, getTagsBySession, getActiveTagsBySession, getTailHygieneTags, getDroppedTagsBySession, getTagsByNumbers, getNewestToolTagNumbers, getDroppedTagsByNumbers, getMaxDroppedTagNumber, getTagById, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, getCandidateToolOwners, pickNearestPriorOwner, expandToolPart, markHostUnservedRow, retreatPastHostUnservedRows, snapTerminalCompartmentToServedRow, isHostRenderedSystemMessage, isStrictGapHealingMessage, isRawCompactionSummaryInfo, extractInMemoryMessageViews, buildInMemoryTailRawMessages, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForCompletedToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripSystemInjection, isTextPart, isToolPartWithOutput, isFilePart, buildFileSourceContent, toolPartHasUserAnswer, DreamTokenBudgetExceeded, TOKEN_BUDGET_FINALIZE_MESSAGE, registerBudgetFinalizeChild, releaseBudgetFinalizeChild, createDreamTokenBudget, recordToolParameters, createDroppedInputGuard, assertExecutableToolInput, createDroppedInputToolExecuteBeforeHook, isEditTool, describeFinalWireTail, estimateMessageTokens, wireContentBytes, createFinalWireUsageTracker, estimateFinalWireInputTokens, estimateAppendedWireTokens, detectThinkingBindingMismatch, isPrefixBoundThinkingModel, detectOverflow, modelAcceptsEmptyContent, isAnthropicFamilyRoute, neutralizeDroppedReasoningPart, restoreNeutralizedReasoningPart, isNeutralizedReasoningPart, variantChangeBustsProviderCache, makeSentinel, makeWholeMessageSentinel, isSentinel, replaySentinelByMessageIds, SKELETON_REAL_INPUT_MAX_BYTES, partHasCompletedResult, extractToolCallObservation, ToolMutationBatch, createToolDropTarget, resolveHostServedBoundaryId2, hasRawMessageProvider2, setRawMessageProvider2, setBoundedRawMessageProvider2, withRawMessageProvider2, cleanUserText2, withRawSessionMessageCache2, readRawSessionMessages2, readRawSessionMessagePage2, getRawSessionMessageOrdinalCount2, RAW_MESSAGE_VISIT_PAGE_SIZE2, visitRawSessionMessages2, readRawSessionMessageRange2, primeTailRawMessageCache2, getCachedAbsoluteMessageCount2, primeInMemoryTailRawMessageCache2, readRawSessionMessageOrdinalPage2, getRawSessionStoredMessageCount2, readRawSessionMessageIdOrdinalsForRange2, readRawSessionMessageIdOrdinals2, readRawSessionMessagePartsById2, hasRawSessionMessageById2, readRawSessionMessageOrdinalById2, compareRawSessionMessageOrder2, readRawSessionMessageById2, getRawSessionMessageCount2, RAW_SESSION_TAG_KEY_PAGE_SIZE2, getRawSessionTagKeysThrough2, getLegacyProtectedTailStartOrdinal2, getProtectedTailStartOrdinal2, readSessionChunk2, getRawSessionMessageIdsThrough2, readRawSessionSeedTail2 };