@code-yeongyu/senpi 2026.9.7 → 2026.9.9-2

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 (470) hide show
  1. package/CHANGELOG.md +122 -3
  2. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  3. package/dist/core/agent-session-runtime.js +2 -0
  4. package/dist/core/agent-session-runtime.js.map +1 -1
  5. package/dist/core/agent-session.d.ts +48 -4
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +192 -40
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/compaction/compaction-execution.d.ts.map +1 -1
  10. package/dist/core/compaction/compaction-execution.js +5 -5
  11. package/dist/core/compaction/compaction-execution.js.map +1 -1
  12. package/dist/core/compaction/compaction-settings.d.ts +2 -0
  13. package/dist/core/compaction/compaction-settings.d.ts.map +1 -1
  14. package/dist/core/compaction/compaction-settings.js.map +1 -1
  15. package/dist/core/compaction/compaction.d.ts +3 -3
  16. package/dist/core/compaction/compaction.d.ts.map +1 -1
  17. package/dist/core/compaction/compaction.js +14 -8
  18. package/dist/core/compaction/compaction.js.map +1 -1
  19. package/dist/core/compaction/stream-watchdog.d.ts +29 -0
  20. package/dist/core/compaction/stream-watchdog.d.ts.map +1 -1
  21. package/dist/core/compaction/stream-watchdog.js +35 -0
  22. package/dist/core/compaction/stream-watchdog.js.map +1 -1
  23. package/dist/core/compaction-settings-access.d.ts +6 -0
  24. package/dist/core/compaction-settings-access.d.ts.map +1 -1
  25. package/dist/core/compaction-settings-access.js.map +1 -1
  26. package/dist/core/compaction-settings-resolver.d.ts +2 -0
  27. package/dist/core/compaction-settings-resolver.d.ts.map +1 -1
  28. package/dist/core/compaction-settings-resolver.js +5 -0
  29. package/dist/core/compaction-settings-resolver.js.map +1 -1
  30. package/dist/core/dynamic-prompt/working-task.js +1 -1
  31. package/dist/core/dynamic-prompt/working-task.js.map +1 -1
  32. package/dist/core/extensions/builtin/cache-keepalive/index.d.ts.map +1 -1
  33. package/dist/core/extensions/builtin/cache-keepalive/index.js +4 -21
  34. package/dist/core/extensions/builtin/cache-keepalive/index.js.map +1 -1
  35. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts +2 -0
  36. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.d.ts.map +1 -1
  37. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js +10 -25
  38. package/dist/core/extensions/builtin/claude-sdk-oauth/account-command.js.map +1 -1
  39. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js +36 -19
  41. package/dist/core/extensions/builtin/claude-sdk-oauth/session-binding.js.map +1 -1
  42. package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js +21 -10
  44. package/dist/core/extensions/builtin/claude-sdk-oauth/session-commit-boundary.js.map +1 -1
  45. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts +4 -17
  46. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js +23 -33
  48. package/dist/core/extensions/builtin/claude-sdk-oauth/session-continuity.js.map +1 -1
  49. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.d.ts.map +1 -1
  50. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js +5 -1
  51. package/dist/core/extensions/builtin/claude-sdk-oauth/session-stream.js.map +1 -1
  52. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.d.ts.map +1 -1
  53. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js +5 -3
  54. package/dist/core/extensions/builtin/claude-sdk-oauth/session-sync.js.map +1 -1
  55. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.d.ts.map +1 -1
  56. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js +8 -3
  57. package/dist/core/extensions/builtin/claude-sdk-oauth/session-turn-attempt.js.map +1 -1
  58. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts +6 -5
  59. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.d.ts.map +1 -1
  60. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js +6 -5
  61. package/dist/core/extensions/builtin/claude-sdk-oauth/tools.js.map +1 -1
  62. package/dist/core/extensions/builtin/compaction/circuit-breaker.d.ts +8 -0
  63. package/dist/core/extensions/builtin/compaction/circuit-breaker.d.ts.map +1 -1
  64. package/dist/core/extensions/builtin/compaction/circuit-breaker.js +8 -0
  65. package/dist/core/extensions/builtin/compaction/circuit-breaker.js.map +1 -1
  66. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts +8 -0
  67. package/dist/core/extensions/builtin/compaction/deterministic-fallback.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js +125 -20
  69. package/dist/core/extensions/builtin/compaction/deterministic-fallback.js.map +1 -1
  70. package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.d.ts +18 -0
  71. package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.d.ts.map +1 -0
  72. package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.js +20 -0
  73. package/dist/core/extensions/builtin/compaction/fallback-failed-turn-normalization.js.map +1 -0
  74. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  75. package/dist/core/extensions/builtin/compaction/index.js +54 -11
  76. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  77. package/dist/core/extensions/builtin/compaction/lane-policy.d.ts +3 -0
  78. package/dist/core/extensions/builtin/compaction/lane-policy.d.ts.map +1 -1
  79. package/dist/core/extensions/builtin/compaction/lane-policy.js +47 -23
  80. package/dist/core/extensions/builtin/compaction/lane-policy.js.map +1 -1
  81. package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts +1 -1
  82. package/dist/core/extensions/builtin/compaction/model-usability-budget.d.ts.map +1 -1
  83. package/dist/core/extensions/builtin/compaction/model-usability-budget.js +23 -3
  84. package/dist/core/extensions/builtin/compaction/model-usability-budget.js.map +1 -1
  85. package/dist/core/extensions/builtin/compaction/resume-admission.d.ts +7 -0
  86. package/dist/core/extensions/builtin/compaction/resume-admission.d.ts.map +1 -0
  87. package/dist/core/extensions/builtin/compaction/resume-admission.js +7 -0
  88. package/dist/core/extensions/builtin/compaction/resume-admission.js.map +1 -0
  89. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts +2 -0
  90. package/dist/core/extensions/builtin/compaction/speculative-summary.d.ts.map +1 -1
  91. package/dist/core/extensions/builtin/compaction/speculative-summary.js +5 -2
  92. package/dist/core/extensions/builtin/compaction/speculative-summary.js.map +1 -1
  93. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  94. package/dist/core/extensions/builtin/compaction/speculative.js +9 -3
  95. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  96. package/dist/core/extensions/builtin/compaction/summarization-retry.d.ts +10 -4
  97. package/dist/core/extensions/builtin/compaction/summarization-retry.d.ts.map +1 -1
  98. package/dist/core/extensions/builtin/compaction/summarization-retry.js +14 -5
  99. package/dist/core/extensions/builtin/compaction/summarization-retry.js.map +1 -1
  100. package/dist/core/extensions/builtin/goal/agent-end-continuation.d.ts.map +1 -1
  101. package/dist/core/extensions/builtin/goal/agent-end-continuation.js +11 -0
  102. package/dist/core/extensions/builtin/goal/agent-end-continuation.js.map +1 -1
  103. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js +6 -4
  104. package/dist/core/extensions/builtin/goal/cache-warm-renderer.js.map +1 -1
  105. package/dist/core/extensions/builtin/goal/cache-warm.d.ts +25 -1
  106. package/dist/core/extensions/builtin/goal/cache-warm.d.ts.map +1 -1
  107. package/dist/core/extensions/builtin/goal/cache-warm.js +29 -10
  108. package/dist/core/extensions/builtin/goal/cache-warm.js.map +1 -1
  109. package/dist/core/extensions/builtin/goal/continuation.d.ts +3 -1
  110. package/dist/core/extensions/builtin/goal/continuation.d.ts.map +1 -1
  111. package/dist/core/extensions/builtin/goal/continuation.js +17 -2
  112. package/dist/core/extensions/builtin/goal/continuation.js.map +1 -1
  113. package/dist/core/extensions/builtin/goal/lifecycle-helpers.d.ts.map +1 -1
  114. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js +1 -0
  115. package/dist/core/extensions/builtin/goal/lifecycle-helpers.js.map +1 -1
  116. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts +1 -1
  117. package/dist/core/extensions/builtin/goal/monitor-continuation.d.ts.map +1 -1
  118. package/dist/core/extensions/builtin/goal/monitor-continuation.js +8 -3
  119. package/dist/core/extensions/builtin/goal/monitor-continuation.js.map +1 -1
  120. package/dist/core/extensions/builtin/gpt-account.d.ts +5 -1
  121. package/dist/core/extensions/builtin/gpt-account.d.ts.map +1 -1
  122. package/dist/core/extensions/builtin/gpt-account.js +9 -26
  123. package/dist/core/extensions/builtin/gpt-account.js.map +1 -1
  124. package/dist/core/extensions/builtin/hooks/plugin-manifest.js +2 -2
  125. package/dist/core/extensions/builtin/hooks/plugin-manifest.js.map +1 -1
  126. package/dist/core/extensions/builtin/hooks/safety.js +2 -2
  127. package/dist/core/extensions/builtin/hooks/safety.js.map +1 -1
  128. package/dist/core/extensions/builtin/imagegen/params.d.ts +36 -0
  129. package/dist/core/extensions/builtin/imagegen/params.d.ts.map +1 -0
  130. package/dist/core/extensions/builtin/imagegen/params.js +55 -0
  131. package/dist/core/extensions/builtin/imagegen/params.js.map +1 -0
  132. package/dist/core/extensions/builtin/imagegen/reference-images.d.ts +11 -0
  133. package/dist/core/extensions/builtin/imagegen/reference-images.d.ts.map +1 -0
  134. package/dist/core/extensions/builtin/imagegen/reference-images.js +55 -0
  135. package/dist/core/extensions/builtin/imagegen/reference-images.js.map +1 -0
  136. package/dist/core/extensions/builtin/imagegen/skill/SKILL.md +47 -4
  137. package/dist/core/extensions/builtin/imagegen/tool.d.ts +10 -19
  138. package/dist/core/extensions/builtin/imagegen/tool.d.ts.map +1 -1
  139. package/dist/core/extensions/builtin/imagegen/tool.js +21 -45
  140. package/dist/core/extensions/builtin/imagegen/tool.js.map +1 -1
  141. package/dist/core/extensions/builtin/monitor-state-event.d.ts +18 -0
  142. package/dist/core/extensions/builtin/monitor-state-event.d.ts.map +1 -1
  143. package/dist/core/extensions/builtin/monitor-state-event.js +23 -0
  144. package/dist/core/extensions/builtin/monitor-state-event.js.map +1 -1
  145. package/dist/core/extensions/builtin/oauth-login-interaction.d.ts +24 -0
  146. package/dist/core/extensions/builtin/oauth-login-interaction.d.ts.map +1 -0
  147. package/dist/core/extensions/builtin/oauth-login-interaction.js +77 -0
  148. package/dist/core/extensions/builtin/oauth-login-interaction.js.map +1 -0
  149. package/dist/core/extensions/builtin/permission-system/external-dir.d.ts.map +1 -1
  150. package/dist/core/extensions/builtin/permission-system/external-dir.js +5 -51
  151. package/dist/core/extensions/builtin/permission-system/external-dir.js.map +1 -1
  152. package/dist/core/extensions/builtin/permission-system/parsers.d.ts.map +1 -1
  153. package/dist/core/extensions/builtin/permission-system/parsers.js +5 -7
  154. package/dist/core/extensions/builtin/permission-system/parsers.js.map +1 -1
  155. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js +1 -1
  156. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5-1.js.map +1 -1
  157. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +1 -1
  158. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
  159. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts +14 -7
  160. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.d.ts.map +1 -1
  161. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js +34 -13
  162. package/dist/core/extensions/builtin/prompt-preset/execution-tooling.js.map +1 -1
  163. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts +6 -10
  164. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.d.ts.map +1 -1
  165. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +14 -9
  166. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  167. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts +15 -15
  168. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.d.ts.map +1 -1
  169. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js +49 -21
  170. package/dist/core/extensions/builtin/prompt-preset/gpt-6-astra.js.map +1 -1
  171. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +1 -1
  172. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
  173. package/dist/core/extensions/builtin/service-tier.d.ts +2 -0
  174. package/dist/core/extensions/builtin/service-tier.d.ts.map +1 -1
  175. package/dist/core/extensions/builtin/service-tier.js +17 -1
  176. package/dist/core/extensions/builtin/service-tier.js.map +1 -1
  177. package/dist/core/extensions/builtin/terminal/durable-command.d.ts.map +1 -1
  178. package/dist/core/extensions/builtin/terminal/durable-command.js +3 -0
  179. package/dist/core/extensions/builtin/terminal/durable-command.js.map +1 -1
  180. package/dist/core/extensions/builtin/terminal/durable-file.d.ts.map +1 -1
  181. package/dist/core/extensions/builtin/terminal/durable-file.js +2 -0
  182. package/dist/core/extensions/builtin/terminal/durable-file.js.map +1 -1
  183. package/dist/core/extensions/builtin/terminal/extension.d.ts.map +1 -1
  184. package/dist/core/extensions/builtin/terminal/extension.js +14 -2
  185. package/dist/core/extensions/builtin/terminal/extension.js.map +1 -1
  186. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
  187. package/dist/core/extensions/builtin/terminal/monitor-notify.js +27 -5
  188. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
  189. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts +17 -0
  190. package/dist/core/extensions/builtin/terminal/monitor-registry.d.ts.map +1 -1
  191. package/dist/core/extensions/builtin/terminal/monitor-registry.js +76 -14
  192. package/dist/core/extensions/builtin/terminal/monitor-registry.js.map +1 -1
  193. package/dist/core/extensions/builtin/terminal/notify.d.ts +2 -0
  194. package/dist/core/extensions/builtin/terminal/notify.d.ts.map +1 -1
  195. package/dist/core/extensions/builtin/terminal/notify.js +6 -1
  196. package/dist/core/extensions/builtin/terminal/notify.js.map +1 -1
  197. package/dist/core/extensions/builtin/terminal/session-bundle.d.ts +3 -1
  198. package/dist/core/extensions/builtin/terminal/session-bundle.d.ts.map +1 -1
  199. package/dist/core/extensions/builtin/terminal/session-bundle.js +13 -0
  200. package/dist/core/extensions/builtin/terminal/session-bundle.js.map +1 -1
  201. package/dist/core/extensions/builtin/terminal/shared.d.ts +13 -2
  202. package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
  203. package/dist/core/extensions/builtin/terminal/shared.js +15 -2
  204. package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
  205. package/dist/core/extensions/builtin/terminal/tools/monitor.d.ts.map +1 -1
  206. package/dist/core/extensions/builtin/terminal/tools/monitor.js +8 -1
  207. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
  208. package/dist/core/extensions/builtin/tool-search/index.d.ts.map +1 -1
  209. package/dist/core/extensions/builtin/tool-search/index.js +1 -0
  210. package/dist/core/extensions/builtin/tool-search/index.js.map +1 -1
  211. package/dist/core/extensions/builtin/tool-search/service.d.ts +4 -0
  212. package/dist/core/extensions/builtin/tool-search/service.d.ts.map +1 -1
  213. package/dist/core/extensions/builtin/tool-search/service.js +11 -0
  214. package/dist/core/extensions/builtin/tool-search/service.js.map +1 -1
  215. package/dist/core/extensions/loader.d.ts +2 -1
  216. package/dist/core/extensions/loader.d.ts.map +1 -1
  217. package/dist/core/extensions/loader.js +17 -8
  218. package/dist/core/extensions/loader.js.map +1 -1
  219. package/dist/core/extensions/runner.d.ts +1 -0
  220. package/dist/core/extensions/runner.d.ts.map +1 -1
  221. package/dist/core/extensions/runner.js +8 -1
  222. package/dist/core/extensions/runner.js.map +1 -1
  223. package/dist/core/extensions/types.d.ts +14 -0
  224. package/dist/core/extensions/types.d.ts.map +1 -1
  225. package/dist/core/extensions/types.js.map +1 -1
  226. package/dist/core/high-reasoning-warning.d.ts.map +1 -1
  227. package/dist/core/high-reasoning-warning.js +4 -6
  228. package/dist/core/high-reasoning-warning.js.map +1 -1
  229. package/dist/core/resource-loader.d.ts +2 -0
  230. package/dist/core/resource-loader.d.ts.map +1 -1
  231. package/dist/core/resource-loader.js +11 -7
  232. package/dist/core/resource-loader.js.map +1 -1
  233. package/dist/core/sdk.d.ts +1 -1
  234. package/dist/core/sdk.d.ts.map +1 -1
  235. package/dist/core/sdk.js +38 -7
  236. package/dist/core/sdk.js.map +1 -1
  237. package/dist/core/session-manager.d.ts.map +1 -1
  238. package/dist/core/session-manager.js +11 -1
  239. package/dist/core/session-manager.js.map +1 -1
  240. package/dist/core/session-write-reservation.d.ts +4 -0
  241. package/dist/core/session-write-reservation.d.ts.map +1 -0
  242. package/dist/core/session-write-reservation.js +12 -0
  243. package/dist/core/session-write-reservation.js.map +1 -0
  244. package/dist/core/settings-manager.js +1 -1
  245. package/dist/core/settings-manager.js.map +1 -1
  246. package/dist/core/settings-shapes.js.map +1 -1
  247. package/dist/core/tools/bounded-realpath.d.ts +28 -0
  248. package/dist/core/tools/bounded-realpath.d.ts.map +1 -0
  249. package/dist/core/tools/bounded-realpath.js +53 -0
  250. package/dist/core/tools/bounded-realpath.js.map +1 -0
  251. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  252. package/dist/core/tools/file-mutation-queue.js +15 -13
  253. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  254. package/dist/core/tools/filesystem-policy.d.ts +7 -0
  255. package/dist/core/tools/filesystem-policy.d.ts.map +1 -1
  256. package/dist/core/tools/filesystem-policy.js +25 -15
  257. package/dist/core/tools/filesystem-policy.js.map +1 -1
  258. package/dist/core/tools/read-classifiers.d.ts +17 -0
  259. package/dist/core/tools/read-classifiers.d.ts.map +1 -0
  260. package/dist/core/tools/read-classifiers.js +26 -0
  261. package/dist/core/tools/read-classifiers.js.map +1 -0
  262. package/dist/core/tools/read.d.ts +5 -1
  263. package/dist/core/tools/read.d.ts.map +1 -1
  264. package/dist/core/tools/read.js +21 -1
  265. package/dist/core/tools/read.js.map +1 -1
  266. package/dist/core/trust-manager.d.ts.map +1 -1
  267. package/dist/core/trust-manager.js +13 -2
  268. package/dist/core/trust-manager.js.map +1 -1
  269. package/dist/index.d.ts +1 -0
  270. package/dist/index.d.ts.map +1 -1
  271. package/dist/index.js +1 -0
  272. package/dist/index.js.map +1 -1
  273. package/dist/main.d.ts +14 -0
  274. package/dist/main.d.ts.map +1 -1
  275. package/dist/main.js +166 -147
  276. package/dist/main.js.map +1 -1
  277. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  278. package/dist/modes/interactive/interactive-mode.js +4 -0
  279. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  280. package/dist/modes/interactive/tips/catalog/memory-tips.d.ts.map +1 -1
  281. package/dist/modes/interactive/tips/catalog/memory-tips.js +6 -0
  282. package/dist/modes/interactive/tips/catalog/memory-tips.js.map +1 -1
  283. package/dist/modes/interactive/tips/catalog/subagent-tips.d.ts.map +1 -1
  284. package/dist/modes/interactive/tips/catalog/subagent-tips.js +6 -0
  285. package/dist/modes/interactive/tips/catalog/subagent-tips.js.map +1 -1
  286. package/dist/modes/rpc/connection-handler.d.ts +2 -0
  287. package/dist/modes/rpc/connection-handler.d.ts.map +1 -1
  288. package/dist/modes/rpc/connection-handler.js +1 -1
  289. package/dist/modes/rpc/connection-handler.js.map +1 -1
  290. package/dist/modes/rpc/host-lifecycle.d.ts.map +1 -1
  291. package/dist/modes/rpc/host-lifecycle.js +31 -5
  292. package/dist/modes/rpc/host-lifecycle.js.map +1 -1
  293. package/dist/modes/rpc/host-watchdog.d.ts +11 -0
  294. package/dist/modes/rpc/host-watchdog.d.ts.map +1 -1
  295. package/dist/modes/rpc/host-watchdog.js +16 -2
  296. package/dist/modes/rpc/host-watchdog.js.map +1 -1
  297. package/dist/modes/rpc/multi-session-host.d.ts +2 -0
  298. package/dist/modes/rpc/multi-session-host.d.ts.map +1 -1
  299. package/dist/modes/rpc/multi-session-host.js +72 -24
  300. package/dist/modes/rpc/multi-session-host.js.map +1 -1
  301. package/dist/modes/rpc/session-binding.d.ts.map +1 -1
  302. package/dist/modes/rpc/session-binding.js +3 -0
  303. package/dist/modes/rpc/session-binding.js.map +1 -1
  304. package/dist/modes/rpc/session-command-router.d.ts +1 -1
  305. package/dist/modes/rpc/session-command-router.d.ts.map +1 -1
  306. package/dist/modes/rpc/session-command-router.js +57 -25
  307. package/dist/modes/rpc/session-command-router.js.map +1 -1
  308. package/dist/modes/rpc/session-event-writer.d.ts +23 -1
  309. package/dist/modes/rpc/session-event-writer.d.ts.map +1 -1
  310. package/dist/modes/rpc/session-event-writer.js +108 -1
  311. package/dist/modes/rpc/session-event-writer.js.map +1 -1
  312. package/dist/modes/rpc/session-registry.d.ts +4 -2
  313. package/dist/modes/rpc/session-registry.d.ts.map +1 -1
  314. package/dist/modes/rpc/session-registry.js +1 -1
  315. package/dist/modes/rpc/session-registry.js.map +1 -1
  316. package/dist/modes/rpc/session-worker-client.d.ts +47 -0
  317. package/dist/modes/rpc/session-worker-client.d.ts.map +1 -0
  318. package/dist/modes/rpc/session-worker-client.js +226 -0
  319. package/dist/modes/rpc/session-worker-client.js.map +1 -0
  320. package/dist/modes/rpc/session-worker-protocol.d.ts +103 -0
  321. package/dist/modes/rpc/session-worker-protocol.d.ts.map +1 -0
  322. package/dist/modes/rpc/session-worker-protocol.js +12 -0
  323. package/dist/modes/rpc/session-worker-protocol.js.map +1 -0
  324. package/dist/modes/rpc/session-worker-requests.d.ts +24 -0
  325. package/dist/modes/rpc/session-worker-requests.d.ts.map +1 -0
  326. package/dist/modes/rpc/session-worker-requests.js +71 -0
  327. package/dist/modes/rpc/session-worker-requests.js.map +1 -0
  328. package/dist/modes/rpc/session-worker.d.ts +2 -0
  329. package/dist/modes/rpc/session-worker.d.ts.map +1 -0
  330. package/dist/modes/rpc/session-worker.js +229 -0
  331. package/dist/modes/rpc/session-worker.js.map +1 -0
  332. package/dist/modes/rpc/socket-ownership.d.ts +46 -0
  333. package/dist/modes/rpc/socket-ownership.d.ts.map +1 -0
  334. package/dist/modes/rpc/socket-ownership.js +178 -0
  335. package/dist/modes/rpc/socket-ownership.js.map +1 -0
  336. package/dist/modes/rpc/worker-session-registry.d.ts +37 -0
  337. package/dist/modes/rpc/worker-session-registry.d.ts.map +1 -0
  338. package/dist/modes/rpc/worker-session-registry.js +207 -0
  339. package/dist/modes/rpc/worker-session-registry.js.map +1 -0
  340. package/dist/utils/fs-watch.d.ts +17 -0
  341. package/dist/utils/fs-watch.d.ts.map +1 -1
  342. package/dist/utils/fs-watch.js +38 -10
  343. package/dist/utils/fs-watch.js.map +1 -1
  344. package/dist/utils/paths.d.ts +33 -0
  345. package/dist/utils/paths.d.ts.map +1 -1
  346. package/dist/utils/paths.js +109 -3
  347. package/dist/utils/paths.js.map +1 -1
  348. package/docs/development.md +3 -2
  349. package/docs/providers.md +5 -1
  350. package/docs/rpc.md +70 -9
  351. package/docs/settings.md +2 -0
  352. package/docs/skills.md +1 -1
  353. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +55 -0
  354. package/node_modules/@code-yeongyu/senpi-codemode/README.md +14 -1
  355. package/node_modules/@code-yeongyu/senpi-codemode/package.json +4 -4
  356. package/node_modules/@code-yeongyu/senpi-codemode/src/bridge/protocol.ts +1 -0
  357. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/runtime-factory.ts +3 -0
  358. package/node_modules/@code-yeongyu/senpi-codemode/src/extension/session-manager.ts +7 -0
  359. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/AGENTS.md +7 -0
  360. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/jl/kernel.ts +4 -0
  361. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/kernel-contract.ts +3 -0
  362. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-core.js +29 -0
  363. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-indirect-eval.js +10 -6
  364. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.d.ts +16 -0
  365. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-shell-capture.js +44 -8
  366. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/js/worker-startup.ts +1 -0
  367. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/kernel-contract.ts +3 -0
  368. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/transport.ts +9 -1
  369. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/rb/kernel.ts +4 -0
  370. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/session-env.ts +56 -0
  371. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-contract.ts +3 -0
  372. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/shared/subprocess-kernel.ts +9 -1
  373. package/node_modules/@code-yeongyu/senpi-codemode/src/output/output-meta.ts +26 -2
  374. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +17 -24
  375. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/image.ts +12 -3
  376. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  377. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +2 -2
  378. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  379. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts +7 -0
  380. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.d.ts.map +1 -1
  381. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js +19 -0
  382. package/node_modules/@earendil-works/pi-agent-core/dist/assistant-terminal-state.js.map +1 -1
  383. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.d.ts.map +1 -1
  384. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js +24 -16
  385. package/node_modules/@earendil-works/pi-agent-core/dist/empty-assistant-recovery.js.map +1 -1
  386. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts +1 -1
  387. package/node_modules/@earendil-works/pi-agent-core/dist/index.d.ts.map +1 -1
  388. package/node_modules/@earendil-works/pi-agent-core/dist/index.js +1 -1
  389. package/node_modules/@earendil-works/pi-agent-core/dist/index.js.map +1 -1
  390. package/node_modules/@earendil-works/pi-agent-core/package.json +3 -3
  391. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  392. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +70 -183
  393. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  394. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts +3 -0
  395. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.d.ts.map +1 -0
  396. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js +260 -0
  397. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-tool-references.js.map +1 -0
  398. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  399. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +1 -0
  400. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  401. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.d.ts +4 -0
  402. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.d.ts.map +1 -0
  403. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.js +11 -0
  404. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-edit.js.map +1 -0
  405. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.d.ts +25 -0
  406. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.d.ts.map +1 -0
  407. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.js +58 -0
  408. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images-params.js.map +1 -0
  409. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts +3 -6
  410. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.d.ts.map +1 -1
  411. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js +15 -33
  412. package/node_modules/@earendil-works/pi-ai/dist/api/openai-images.js.map +1 -1
  413. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.d.ts.map +1 -1
  414. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js +1 -0
  415. package/node_modules/@earendil-works/pi-ai/dist/api/openai-responses.js.map +1 -1
  416. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts +40 -0
  417. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.d.ts.map +1 -0
  418. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js +138 -0
  419. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic-callback-listener.js.map +1 -0
  420. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts +2 -3
  421. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.d.ts.map +1 -1
  422. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js +42 -139
  423. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/anthropic.js.map +1 -1
  424. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts +6 -0
  425. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.d.ts.map +1 -0
  426. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js +29 -0
  427. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/authorization-input.js.map +1 -0
  428. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts +3 -0
  429. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.d.ts.map +1 -0
  430. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js +20 -0
  431. package/node_modules/@earendil-works/pi-ai/dist/auth/oauth/error-details.js.map +1 -0
  432. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +61 -1
  433. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  434. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +61 -1
  435. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  436. package/node_modules/@earendil-works/pi-ai/dist/images.d.ts +1 -0
  437. package/node_modules/@earendil-works/pi-ai/dist/images.d.ts.map +1 -1
  438. package/node_modules/@earendil-works/pi-ai/dist/images.js +1 -0
  439. package/node_modules/@earendil-works/pi-ai/dist/images.js.map +1 -1
  440. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  441. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -1
  442. package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -1
  443. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -1
  444. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -1
  445. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -1
  446. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -1
  447. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -1
  448. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -1
  449. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opengateway.json +1 -1
  450. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  451. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  452. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.d.ts.map +1 -1
  453. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js +16 -1
  454. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/recovery-stream-terminal.js.map +1 -1
  455. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +7 -0
  456. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  457. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  458. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts +1 -1
  459. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.d.ts.map +1 -1
  460. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js +14 -3
  461. package/node_modules/@earendil-works/pi-ai/dist/utils/overflow.js.map +1 -1
  462. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts +2 -1
  463. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.d.ts.map +1 -1
  464. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js +16 -0
  465. package/node_modules/@earendil-works/pi-ai/dist/utils/server-fallback-receipt.js.map +1 -1
  466. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  467. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  468. package/node_modules/@earendil-works/pi-telemetry/package.json +1 -1
  469. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  470. package/package.json +7 -7
@@ -30,6 +30,35 @@ export declare const DEFAULT_SUMMARIZATION_IDLE_TIMEOUT_MS = 300000;
30
30
  * budget per attempt.
31
31
  */
32
32
  export declare const DEFAULT_SUMMARIZATION_MAX_DURATION_MS = 120000;
33
+ /**
34
+ * How much the wall-clock budget grows per estimated input token.
35
+ *
36
+ * The 120s floor covers healthy summaries. Large sessions summarize hundreds of
37
+ * thousands of tokens: a 257k-token input already exceeds 120s on slower
38
+ * providers while still streaming (#1068), so the budget scales with the amount
39
+ * being summarized. 2ms/token assumes a worst-case sustained throughput of ~500
40
+ * tokens/second; faster providers simply finish well inside the budget.
41
+ */
42
+ export declare const SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS = 2;
43
+ /**
44
+ * Absolute ceiling for one summarization attempt. The wall-clock budget exists
45
+ * to stop a slow-but-alive stream from holding the session forever; it must stay
46
+ * a bound, so size-scaled budgets are clamped here instead of growing linearly
47
+ * without limit.
48
+ */
49
+ export declare const SUMMARIZATION_MAX_DURATION_CAP_MS = 1800000;
50
+ /**
51
+ * Total time one summarization attempt may hold the session, sized to its input.
52
+ *
53
+ * The budget never shrinks below {@link DEFAULT_SUMMARIZATION_MAX_DURATION_MS};
54
+ * inputs small enough that `2ms/token` stays under that floor keep the exact
55
+ * 120s contract. Above ~60k estimated tokens the budget grows by
56
+ * {@link SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS} per token and is clamped to
57
+ * {@link SUMMARIZATION_MAX_DURATION_CAP_MS}. An explicit positive `overrideMs`
58
+ * (e.g. the `compaction.summarizationMaxDurationMs` setting) replaces the
59
+ * computed budget; non-finite and non-positive values are ignored.
60
+ */
61
+ export declare function summarizationMaxDurationMs(estimatedInputTokens: number, overrideMs?: number): number;
33
62
  export interface ConsumeStreamWithIdleTimeoutOptions<T> {
34
63
  /** Silence budget per read; the timer resets on every event. */
35
64
  readonly idleTimeoutMs: number;
@@ -1 +1 @@
1
- {"version":3,"file":"stream-watchdog.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/stream-watchdog.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,qBAAa,sBAAuB,SAAQ,KAAK;IAChD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBACnB,aAAa,EAAE,MAAM;CAKjC;AAED;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IACnD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBACnB,aAAa,EAAE,MAAM;CAOjC;AAED,2EAA2E;AAC3E,eAAO,MAAM,qCAAqC,SAAU,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,qCAAqC,SAAU,CAAC;AAE7D,MAAM,WAAW,mCAAmC,CAAC,CAAC;IACrD,gEAAgE;IAChE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,gFAAgF;IAChF,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACtC,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAMD;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,CAAC,EACnD,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EACxD,OAAO,EAAE,mCAAmC,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAmFf"}
1
+ {"version":3,"file":"stream-watchdog.d.ts","sourceRoot":"","sources":["../../../src/core/compaction/stream-watchdog.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,qBAAa,sBAAuB,SAAQ,KAAK;IAChD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBACnB,aAAa,EAAE,MAAM;CAKjC;AAED;;;;;GAKG;AACH,qBAAa,yBAA0B,SAAQ,KAAK;IACnD,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBACnB,aAAa,EAAE,MAAM;CAOjC;AAED,2EAA2E;AAC3E,eAAO,MAAM,qCAAqC,SAAU,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,qCAAqC,SAAU,CAAC;AAE7D;;;;;;;;GAQG;AACH,eAAO,MAAM,uCAAuC,IAAI,CAAC;AAEzD;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,UAAY,CAAC;AAE3D;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,oBAAoB,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAMpG;AAED,MAAM,WAAW,mCAAmC,CAAC,CAAC;IACrD,gEAAgE;IAChE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,gFAAgF;IAChF,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,6EAA6E;IAC7E,QAAQ,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,IAAI,CAAC;IACtC,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;CAC9B;AAMD;;;;GAIG;AACH,wBAAsB,4BAA4B,CAAC,CAAC,EACnD,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EACxD,OAAO,EAAE,mCAAmC,CAAC,CAAC,CAAC,GAC7C,OAAO,CAAC,IAAI,CAAC,CAmFf"}
@@ -36,6 +36,41 @@ export const DEFAULT_SUMMARIZATION_IDLE_TIMEOUT_MS = 300_000;
36
36
  * budget per attempt.
37
37
  */
38
38
  export const DEFAULT_SUMMARIZATION_MAX_DURATION_MS = 120_000;
39
+ /**
40
+ * How much the wall-clock budget grows per estimated input token.
41
+ *
42
+ * The 120s floor covers healthy summaries. Large sessions summarize hundreds of
43
+ * thousands of tokens: a 257k-token input already exceeds 120s on slower
44
+ * providers while still streaming (#1068), so the budget scales with the amount
45
+ * being summarized. 2ms/token assumes a worst-case sustained throughput of ~500
46
+ * tokens/second; faster providers simply finish well inside the budget.
47
+ */
48
+ export const SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS = 2;
49
+ /**
50
+ * Absolute ceiling for one summarization attempt. The wall-clock budget exists
51
+ * to stop a slow-but-alive stream from holding the session forever; it must stay
52
+ * a bound, so size-scaled budgets are clamped here instead of growing linearly
53
+ * without limit.
54
+ */
55
+ export const SUMMARIZATION_MAX_DURATION_CAP_MS = 1_800_000;
56
+ /**
57
+ * Total time one summarization attempt may hold the session, sized to its input.
58
+ *
59
+ * The budget never shrinks below {@link DEFAULT_SUMMARIZATION_MAX_DURATION_MS};
60
+ * inputs small enough that `2ms/token` stays under that floor keep the exact
61
+ * 120s contract. Above ~60k estimated tokens the budget grows by
62
+ * {@link SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS} per token and is clamped to
63
+ * {@link SUMMARIZATION_MAX_DURATION_CAP_MS}. An explicit positive `overrideMs`
64
+ * (e.g. the `compaction.summarizationMaxDurationMs` setting) replaces the
65
+ * computed budget; non-finite and non-positive values are ignored.
66
+ */
67
+ export function summarizationMaxDurationMs(estimatedInputTokens, overrideMs) {
68
+ if (overrideMs !== undefined && Number.isFinite(overrideMs) && overrideMs > 0) {
69
+ return Math.min(SUMMARIZATION_MAX_DURATION_CAP_MS, overrideMs);
70
+ }
71
+ const scaled = estimatedInputTokens * SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS;
72
+ return Math.min(SUMMARIZATION_MAX_DURATION_CAP_MS, Math.max(DEFAULT_SUMMARIZATION_MAX_DURATION_MS, scaled));
73
+ }
39
74
  const IDLE_TRIP = "idle-trip";
40
75
  const BUDGET_TRIP = "budget-trip";
41
76
  const CALLER_ABORTED = "caller-aborted";
@@ -1 +1 @@
1
- {"version":3,"file":"stream-watchdog.js","sourceRoot":"","sources":["../../../src/core/compaction/stream-watchdog.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Idle watchdog for compaction summarization streams.\n *\n * A provider connection can stall — open but silent — for far longer than any\n * user will wait, and compaction previously had no bound at all: the session\n * sat on \"Compacting…\" until ESC aborted it. The agent loop's main-turn\n * reader already has this shape of protection (`StreamIdleTimeoutError` in\n * packages/agent); this brings the same guarantee to summarization requests.\n */\n\nexport class StreamIdleTimeoutError extends Error {\n\treadonly idleTimeoutMs: number;\n\tconstructor(idleTimeoutMs: number) {\n\t\tsuper(`Summarization stream stalled: no provider events for ${idleTimeoutMs}ms; treating the request as dead`);\n\t\tthis.name = \"StreamIdleTimeoutError\";\n\t\tthis.idleTimeoutMs = idleTimeoutMs;\n\t}\n}\n\n/**\n * A stream that keeps trickling events never trips the idle watchdog, yet the\n * summarization it feeds is serialized on the session's agent-event queue: a\n * slow-but-alive request holds tool results at the batch barrier and keeps typed\n * input queued until the user aborts. The wall-clock budget bounds that class.\n */\nexport class StreamDurationBudgetError extends Error {\n\treadonly maxDurationMs: number;\n\tconstructor(maxDurationMs: number) {\n\t\tsuper(\n\t\t\t`Summarization stream exceeded its ${maxDurationMs}ms wall-clock budget; treating the request as too slow to keep the session waiting`,\n\t\t);\n\t\tthis.name = \"StreamDurationBudgetError\";\n\t\tthis.maxDurationMs = maxDurationMs;\n\t}\n}\n\n/** Matches the agent stream idle-timeout default (`httpIdleTimeoutMs`). */\nexport const DEFAULT_SUMMARIZATION_IDLE_TIMEOUT_MS = 300_000;\n\n/**\n * Total time one summarization attempt may hold the session. Well above healthy\n * summarizations (tens of seconds) and below the idle budget, so a live-but-slow\n * provider fails fast enough to keep the session interactive. Retries apply this\n * budget per attempt.\n */\nexport const DEFAULT_SUMMARIZATION_MAX_DURATION_MS = 120_000;\n\nexport interface ConsumeStreamWithIdleTimeoutOptions<T> {\n\t/** Silence budget per read; the timer resets on every event. */\n\treadonly idleTimeoutMs: number;\n\t/** Total wall-clock budget for the whole stream; omit to leave it unbounded. */\n\treadonly maxDurationMs?: number;\n\t/** Tear down the underlying request (abort the request-local controller). */\n\treadonly abort: () => void;\n\treadonly onEvent?: (event: T) => void;\n\t/** Caller cancellation; an abort here ends the wait without an idle error. */\n\treadonly signal?: AbortSignal;\n}\n\nconst IDLE_TRIP = \"idle-trip\" as const;\nconst BUDGET_TRIP = \"budget-trip\" as const;\nconst CALLER_ABORTED = \"caller-aborted\" as const;\n\n/**\n * Drain an event stream, failing with {@link StreamIdleTimeoutError} when no\n * event arrives within `idleTimeoutMs`. Caller aborts propagate as the\n * stream's own abort outcome, never masked as an idle timeout.\n */\nexport async function consumeStreamWithIdleTimeout<T>(\n\tstream: AsyncIterable<T> | PromiseLike<AsyncIterable<T>>,\n\toptions: ConsumeStreamWithIdleTimeoutOptions<T>,\n): Promise<void> {\n\tconst { idleTimeoutMs, maxDurationMs, abort, onEvent, signal } = options;\n\tlet iterator: AsyncIterator<T> | undefined;\n\tlet removeAbortListener: (() => void) | undefined;\n\tlet callerAbortPromise: Promise<typeof CALLER_ABORTED> | undefined;\n\tif (signal?.aborted) {\n\t\treturn;\n\t}\n\t// One absolute deadline for the whole stream, not a per-read budget. Created\n\t// only after the already-aborted early return so no timer is ever leaked.\n\tlet budgetPromise: Promise<typeof BUDGET_TRIP> | undefined;\n\tlet budgetTimer: ReturnType<typeof setTimeout> | undefined;\n\tlet budgetMs = 0;\n\tif (maxDurationMs !== undefined) {\n\t\tbudgetMs = maxDurationMs;\n\t\tconst { promise, resolve } = Promise.withResolvers<typeof BUDGET_TRIP>();\n\t\tbudgetTimer = setTimeout(() => resolve(BUDGET_TRIP), budgetMs);\n\t\tbudgetTimer.unref?.();\n\t\tbudgetPromise = promise;\n\t}\n\tif (signal !== undefined) {\n\t\tconst { promise, resolve } = Promise.withResolvers<typeof CALLER_ABORTED>();\n\t\tconst onAbort = () => resolve(CALLER_ABORTED);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tremoveAbortListener = () => signal.removeEventListener(\"abort\", onAbort);\n\t\tcallerAbortPromise = promise;\n\t}\n\ttry {\n\t\tlet resolvedStream: AsyncIterable<T>;\n\t\tif (Symbol.asyncIterator in stream) {\n\t\t\tresolvedStream = stream;\n\t\t} else {\n\t\t\tconst streamContenders: Array<Promise<AsyncIterable<T> | typeof BUDGET_TRIP | typeof CALLER_ABORTED>> = [\n\t\t\t\tPromise.resolve(stream),\n\t\t\t];\n\t\t\tif (callerAbortPromise) streamContenders.push(callerAbortPromise);\n\t\t\tif (budgetPromise) streamContenders.push(budgetPromise);\n\t\t\tconst resolution = await Promise.race(streamContenders);\n\t\t\tif (resolution === BUDGET_TRIP) {\n\t\t\t\tabort();\n\t\t\t\tthrow new StreamDurationBudgetError(budgetMs);\n\t\t\t}\n\t\t\tif (resolution === CALLER_ABORTED) return;\n\t\t\tresolvedStream = resolution;\n\t\t}\n\t\titerator = resolvedStream[Symbol.asyncIterator]();\n\n\t\twhile (true) {\n\t\t\tconst { promise: idlePromise, resolve: resolveIdle } = Promise.withResolvers<typeof IDLE_TRIP>();\n\t\t\tconst timer = setTimeout(() => resolveIdle(IDLE_TRIP), idleTimeoutMs);\n\t\t\ttimer.unref?.();\n\t\t\tconst contenders: Array<\n\t\t\t\tPromise<IteratorResult<T> | typeof IDLE_TRIP | typeof BUDGET_TRIP | typeof CALLER_ABORTED>\n\t\t\t> = [iterator.next(), idlePromise];\n\t\t\tif (callerAbortPromise) contenders.push(callerAbortPromise);\n\t\t\tif (budgetPromise) contenders.push(budgetPromise);\n\t\t\tlet result: IteratorResult<T> | typeof IDLE_TRIP | typeof BUDGET_TRIP | typeof CALLER_ABORTED;\n\t\t\ttry {\n\t\t\t\tresult = await Promise.race(contenders);\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tif (result === IDLE_TRIP) {\n\t\t\t\tabort();\n\t\t\t\tvoid iterator?.return?.();\n\t\t\t\tthrow new StreamIdleTimeoutError(idleTimeoutMs);\n\t\t\t}\n\t\t\tif (result === BUDGET_TRIP) {\n\t\t\t\tabort();\n\t\t\t\tvoid iterator?.return?.();\n\t\t\t\tthrow new StreamDurationBudgetError(budgetMs);\n\t\t\t}\n\t\t\tif (result === CALLER_ABORTED) {\n\t\t\t\tvoid iterator?.return?.();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result.done) return;\n\t\t\tonEvent?.(result.value);\n\t\t}\n\t} finally {\n\t\tremoveAbortListener?.();\n\t\tif (budgetTimer !== undefined) clearTimeout(budgetTimer);\n\t}\n}\n"]}
1
+ {"version":3,"file":"stream-watchdog.js","sourceRoot":"","sources":["../../../src/core/compaction/stream-watchdog.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Idle watchdog for compaction summarization streams.\n *\n * A provider connection can stall — open but silent — for far longer than any\n * user will wait, and compaction previously had no bound at all: the session\n * sat on \"Compacting…\" until ESC aborted it. The agent loop's main-turn\n * reader already has this shape of protection (`StreamIdleTimeoutError` in\n * packages/agent); this brings the same guarantee to summarization requests.\n */\n\nexport class StreamIdleTimeoutError extends Error {\n\treadonly idleTimeoutMs: number;\n\tconstructor(idleTimeoutMs: number) {\n\t\tsuper(`Summarization stream stalled: no provider events for ${idleTimeoutMs}ms; treating the request as dead`);\n\t\tthis.name = \"StreamIdleTimeoutError\";\n\t\tthis.idleTimeoutMs = idleTimeoutMs;\n\t}\n}\n\n/**\n * A stream that keeps trickling events never trips the idle watchdog, yet the\n * summarization it feeds is serialized on the session's agent-event queue: a\n * slow-but-alive request holds tool results at the batch barrier and keeps typed\n * input queued until the user aborts. The wall-clock budget bounds that class.\n */\nexport class StreamDurationBudgetError extends Error {\n\treadonly maxDurationMs: number;\n\tconstructor(maxDurationMs: number) {\n\t\tsuper(\n\t\t\t`Summarization stream exceeded its ${maxDurationMs}ms wall-clock budget; treating the request as too slow to keep the session waiting`,\n\t\t);\n\t\tthis.name = \"StreamDurationBudgetError\";\n\t\tthis.maxDurationMs = maxDurationMs;\n\t}\n}\n\n/** Matches the agent stream idle-timeout default (`httpIdleTimeoutMs`). */\nexport const DEFAULT_SUMMARIZATION_IDLE_TIMEOUT_MS = 300_000;\n\n/**\n * Total time one summarization attempt may hold the session. Well above healthy\n * summarizations (tens of seconds) and below the idle budget, so a live-but-slow\n * provider fails fast enough to keep the session interactive. Retries apply this\n * budget per attempt.\n */\nexport const DEFAULT_SUMMARIZATION_MAX_DURATION_MS = 120_000;\n\n/**\n * How much the wall-clock budget grows per estimated input token.\n *\n * The 120s floor covers healthy summaries. Large sessions summarize hundreds of\n * thousands of tokens: a 257k-token input already exceeds 120s on slower\n * providers while still streaming (#1068), so the budget scales with the amount\n * being summarized. 2ms/token assumes a worst-case sustained throughput of ~500\n * tokens/second; faster providers simply finish well inside the budget.\n */\nexport const SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS = 2;\n\n/**\n * Absolute ceiling for one summarization attempt. The wall-clock budget exists\n * to stop a slow-but-alive stream from holding the session forever; it must stay\n * a bound, so size-scaled budgets are clamped here instead of growing linearly\n * without limit.\n */\nexport const SUMMARIZATION_MAX_DURATION_CAP_MS = 1_800_000;\n\n/**\n * Total time one summarization attempt may hold the session, sized to its input.\n *\n * The budget never shrinks below {@link DEFAULT_SUMMARIZATION_MAX_DURATION_MS};\n * inputs small enough that `2ms/token` stays under that floor keep the exact\n * 120s contract. Above ~60k estimated tokens the budget grows by\n * {@link SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS} per token and is clamped to\n * {@link SUMMARIZATION_MAX_DURATION_CAP_MS}. An explicit positive `overrideMs`\n * (e.g. the `compaction.summarizationMaxDurationMs` setting) replaces the\n * computed budget; non-finite and non-positive values are ignored.\n */\nexport function summarizationMaxDurationMs(estimatedInputTokens: number, overrideMs?: number): number {\n\tif (overrideMs !== undefined && Number.isFinite(overrideMs) && overrideMs > 0) {\n\t\treturn Math.min(SUMMARIZATION_MAX_DURATION_CAP_MS, overrideMs);\n\t}\n\tconst scaled = estimatedInputTokens * SUMMARIZATION_MAX_DURATION_PER_TOKEN_MS;\n\treturn Math.min(SUMMARIZATION_MAX_DURATION_CAP_MS, Math.max(DEFAULT_SUMMARIZATION_MAX_DURATION_MS, scaled));\n}\n\nexport interface ConsumeStreamWithIdleTimeoutOptions<T> {\n\t/** Silence budget per read; the timer resets on every event. */\n\treadonly idleTimeoutMs: number;\n\t/** Total wall-clock budget for the whole stream; omit to leave it unbounded. */\n\treadonly maxDurationMs?: number;\n\t/** Tear down the underlying request (abort the request-local controller). */\n\treadonly abort: () => void;\n\treadonly onEvent?: (event: T) => void;\n\t/** Caller cancellation; an abort here ends the wait without an idle error. */\n\treadonly signal?: AbortSignal;\n}\n\nconst IDLE_TRIP = \"idle-trip\" as const;\nconst BUDGET_TRIP = \"budget-trip\" as const;\nconst CALLER_ABORTED = \"caller-aborted\" as const;\n\n/**\n * Drain an event stream, failing with {@link StreamIdleTimeoutError} when no\n * event arrives within `idleTimeoutMs`. Caller aborts propagate as the\n * stream's own abort outcome, never masked as an idle timeout.\n */\nexport async function consumeStreamWithIdleTimeout<T>(\n\tstream: AsyncIterable<T> | PromiseLike<AsyncIterable<T>>,\n\toptions: ConsumeStreamWithIdleTimeoutOptions<T>,\n): Promise<void> {\n\tconst { idleTimeoutMs, maxDurationMs, abort, onEvent, signal } = options;\n\tlet iterator: AsyncIterator<T> | undefined;\n\tlet removeAbortListener: (() => void) | undefined;\n\tlet callerAbortPromise: Promise<typeof CALLER_ABORTED> | undefined;\n\tif (signal?.aborted) {\n\t\treturn;\n\t}\n\t// One absolute deadline for the whole stream, not a per-read budget. Created\n\t// only after the already-aborted early return so no timer is ever leaked.\n\tlet budgetPromise: Promise<typeof BUDGET_TRIP> | undefined;\n\tlet budgetTimer: ReturnType<typeof setTimeout> | undefined;\n\tlet budgetMs = 0;\n\tif (maxDurationMs !== undefined) {\n\t\tbudgetMs = maxDurationMs;\n\t\tconst { promise, resolve } = Promise.withResolvers<typeof BUDGET_TRIP>();\n\t\tbudgetTimer = setTimeout(() => resolve(BUDGET_TRIP), budgetMs);\n\t\tbudgetTimer.unref?.();\n\t\tbudgetPromise = promise;\n\t}\n\tif (signal !== undefined) {\n\t\tconst { promise, resolve } = Promise.withResolvers<typeof CALLER_ABORTED>();\n\t\tconst onAbort = () => resolve(CALLER_ABORTED);\n\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\tremoveAbortListener = () => signal.removeEventListener(\"abort\", onAbort);\n\t\tcallerAbortPromise = promise;\n\t}\n\ttry {\n\t\tlet resolvedStream: AsyncIterable<T>;\n\t\tif (Symbol.asyncIterator in stream) {\n\t\t\tresolvedStream = stream;\n\t\t} else {\n\t\t\tconst streamContenders: Array<Promise<AsyncIterable<T> | typeof BUDGET_TRIP | typeof CALLER_ABORTED>> = [\n\t\t\t\tPromise.resolve(stream),\n\t\t\t];\n\t\t\tif (callerAbortPromise) streamContenders.push(callerAbortPromise);\n\t\t\tif (budgetPromise) streamContenders.push(budgetPromise);\n\t\t\tconst resolution = await Promise.race(streamContenders);\n\t\t\tif (resolution === BUDGET_TRIP) {\n\t\t\t\tabort();\n\t\t\t\tthrow new StreamDurationBudgetError(budgetMs);\n\t\t\t}\n\t\t\tif (resolution === CALLER_ABORTED) return;\n\t\t\tresolvedStream = resolution;\n\t\t}\n\t\titerator = resolvedStream[Symbol.asyncIterator]();\n\n\t\twhile (true) {\n\t\t\tconst { promise: idlePromise, resolve: resolveIdle } = Promise.withResolvers<typeof IDLE_TRIP>();\n\t\t\tconst timer = setTimeout(() => resolveIdle(IDLE_TRIP), idleTimeoutMs);\n\t\t\ttimer.unref?.();\n\t\t\tconst contenders: Array<\n\t\t\t\tPromise<IteratorResult<T> | typeof IDLE_TRIP | typeof BUDGET_TRIP | typeof CALLER_ABORTED>\n\t\t\t> = [iterator.next(), idlePromise];\n\t\t\tif (callerAbortPromise) contenders.push(callerAbortPromise);\n\t\t\tif (budgetPromise) contenders.push(budgetPromise);\n\t\t\tlet result: IteratorResult<T> | typeof IDLE_TRIP | typeof BUDGET_TRIP | typeof CALLER_ABORTED;\n\t\t\ttry {\n\t\t\t\tresult = await Promise.race(contenders);\n\t\t\t} finally {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\tif (result === IDLE_TRIP) {\n\t\t\t\tabort();\n\t\t\t\tvoid iterator?.return?.();\n\t\t\t\tthrow new StreamIdleTimeoutError(idleTimeoutMs);\n\t\t\t}\n\t\t\tif (result === BUDGET_TRIP) {\n\t\t\t\tabort();\n\t\t\t\tvoid iterator?.return?.();\n\t\t\t\tthrow new StreamDurationBudgetError(budgetMs);\n\t\t\t}\n\t\t\tif (result === CALLER_ABORTED) {\n\t\t\t\tvoid iterator?.return?.();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result.done) return;\n\t\t\tonEvent?.(result.value);\n\t\t}\n\t} finally {\n\t\tremoveAbortListener?.();\n\t\tif (budgetTimer !== undefined) clearTimeout(budgetTimer);\n\t}\n}\n"]}
@@ -12,6 +12,12 @@ export interface CompactionSettings extends IdealCompactionSettings {
12
12
  restorationMaxTotalTokens?: number;
13
13
  restorationContextRatio?: number;
14
14
  idleCompactionEnabled?: boolean;
15
+ /**
16
+ * Optional override for one summarization attempt's wall-clock budget.
17
+ * Default: size-adaptive (120s floor, 2ms per estimated input token, 30min
18
+ * cap); see `core/compaction/stream-watchdog.ts`.
19
+ */
20
+ summarizationMaxDurationMs?: number;
15
21
  }
16
22
  export declare function compactionEnabled(settings?: CompactionSettings): boolean;
17
23
  export declare function compactionReserveTokens(settings?: CompactionSettings): number;
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-settings-access.d.ts","sourceRoot":"","sources":["../../src/core/compaction-settings-access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AAEzF,MAAM,WAAW,kBAAmB,SAAQ,uBAAuB;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CAChC;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAExE;AACD,wBAAgB,uBAAuB,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAE7E;AACD,wBAAgB,0BAA0B,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAEhF"}
1
+ {"version":3,"file":"compaction-settings-access.d.ts","sourceRoot":"","sources":["../../src/core/compaction-settings-access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,2CAA2C,CAAC;AAEzF,MAAM,WAAW,kBAAmB,SAAQ,uBAAuB;IAClE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAC;IACrC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC;;;;OAIG;IACH,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAExE;AACD,wBAAgB,uBAAuB,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAE7E;AACD,wBAAgB,0BAA0B,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAEhF"}
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-settings-access.js","sourceRoot":"","sources":["../../src/core/compaction-settings-access.ts"],"names":[],"mappings":"AAiBA,MAAM,UAAU,iBAAiB,CAAC,QAA6B;IAC9D,OAAO,QAAQ,EAAE,OAAO,IAAI,IAAI,CAAC;AAClC,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAC,QAA6B;IACpE,OAAO,QAAQ,EAAE,aAAa,IAAI,KAAK,CAAC;AACzC,CAAC;AACD,MAAM,UAAU,0BAA0B,CAAC,QAA6B;IACvE,OAAO,QAAQ,EAAE,gBAAgB,IAAI,KAAK,CAAC;AAC5C,CAAC","sourcesContent":["import type { IdealCompactionSettings } from \"./compaction/ideal-compaction-settings.ts\";\n\nexport interface CompactionSettings extends IdealCompactionSettings {\n\tenabled?: boolean; // default: true\n\treserveTokens?: number; // default: 16384\n\tkeepRecentTokens?: number; // default: 20000\n\tspeculativeEnabled?: boolean; // default: true\n\tspeculativeFraction?: number; // default: 0.75\n\tspeculativeCooldownMs?: number; // default: 30000\n\trestorationEnabled?: boolean; // default: true\n\trestorationMaxItems?: number; // default: 10\n\trestorationMaxTokensPerItem?: number; // default: 5000\n\trestorationMaxTotalTokens?: number; // default: 50000\n\trestorationContextRatio?: number; // default: 0.15\n\tidleCompactionEnabled?: boolean; // default: true\n}\n\nexport function compactionEnabled(settings?: CompactionSettings): boolean {\n\treturn settings?.enabled ?? true;\n}\nexport function compactionReserveTokens(settings?: CompactionSettings): number {\n\treturn settings?.reserveTokens ?? 16384;\n}\nexport function compactionKeepRecentTokens(settings?: CompactionSettings): number {\n\treturn settings?.keepRecentTokens ?? 20000;\n}\n"]}
1
+ {"version":3,"file":"compaction-settings-access.js","sourceRoot":"","sources":["../../src/core/compaction-settings-access.ts"],"names":[],"mappings":"AAuBA,MAAM,UAAU,iBAAiB,CAAC,QAA6B;IAC9D,OAAO,QAAQ,EAAE,OAAO,IAAI,IAAI,CAAC;AAClC,CAAC;AACD,MAAM,UAAU,uBAAuB,CAAC,QAA6B;IACpE,OAAO,QAAQ,EAAE,aAAa,IAAI,KAAK,CAAC;AACzC,CAAC;AACD,MAAM,UAAU,0BAA0B,CAAC,QAA6B;IACvE,OAAO,QAAQ,EAAE,gBAAgB,IAAI,KAAK,CAAC;AAC5C,CAAC","sourcesContent":["import type { IdealCompactionSettings } from \"./compaction/ideal-compaction-settings.ts\";\n\nexport interface CompactionSettings extends IdealCompactionSettings {\n\tenabled?: boolean; // default: true\n\treserveTokens?: number; // default: 16384\n\tkeepRecentTokens?: number; // default: 20000\n\tspeculativeEnabled?: boolean; // default: true\n\tspeculativeFraction?: number; // default: 0.75\n\tspeculativeCooldownMs?: number; // default: 30000\n\trestorationEnabled?: boolean; // default: true\n\trestorationMaxItems?: number; // default: 10\n\trestorationMaxTokensPerItem?: number; // default: 5000\n\trestorationMaxTotalTokens?: number; // default: 50000\n\trestorationContextRatio?: number; // default: 0.15\n\tidleCompactionEnabled?: boolean; // default: true\n\t/**\n\t * Optional override for one summarization attempt's wall-clock budget.\n\t * Default: size-adaptive (120s floor, 2ms per estimated input token, 30min\n\t * cap); see `core/compaction/stream-watchdog.ts`.\n\t */\n\tsummarizationMaxDurationMs?: number;\n}\n\nexport function compactionEnabled(settings?: CompactionSettings): boolean {\n\treturn settings?.enabled ?? true;\n}\nexport function compactionReserveTokens(settings?: CompactionSettings): number {\n\treturn settings?.reserveTokens ?? 16384;\n}\nexport function compactionKeepRecentTokens(settings?: CompactionSettings): number {\n\treturn settings?.keepRecentTokens ?? 20000;\n}\n"]}
@@ -17,6 +17,8 @@ export interface ResolvedCompactionSettings {
17
17
  reminderEnabled: boolean;
18
18
  reserveScalingEnabled: boolean;
19
19
  speculativeLeadTokens?: number;
20
+ /** Positive finite number, or undefined for the size-adaptive default. */
21
+ summarizationMaxDurationMs?: number;
20
22
  }
21
23
  export declare function resolveCompactionSettings(settings?: CompactionSettings): ResolvedCompactionSettings;
22
24
  //# sourceMappingURL=compaction-settings-resolver.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-settings-resolver.d.ts","sourceRoot":"","sources":["../../src/core/compaction-settings-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,MAAM,WAAW,0BAA0B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,2BAA2B,EAAE,MAAM,CAAC;IACpC,yBAAyB,EAAE,MAAM,CAAC;IAClC,uBAAuB,EAAE,MAAM,CAAC;IAChC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAyBD,wBAAgB,yBAAyB,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,0BAA0B,CA6BnG"}
1
+ {"version":3,"file":"compaction-settings-resolver.d.ts","sourceRoot":"","sources":["../../src/core/compaction-settings-resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,MAAM,WAAW,0BAA0B;IAC1C,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC;IACzB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,2BAA2B,EAAE,MAAM,CAAC;IACpC,yBAAyB,EAAE,MAAM,CAAC;IAClC,uBAAuB,EAAE,MAAM,CAAC;IAChC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,oBAAoB,EAAE,OAAO,CAAC;IAC9B,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,0EAA0E;IAC1E,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACpC;AAyBD,wBAAgB,yBAAyB,CAAC,QAAQ,CAAC,EAAE,kBAAkB,GAAG,0BAA0B,CAmCnG"}
@@ -41,6 +41,11 @@ export function resolveCompactionSettings(settings) {
41
41
  speculativeLeadTokens: typeof raw?.speculativeLeadTokens === "number" && Number.isFinite(raw.speculativeLeadTokens)
42
42
  ? Math.max(0, raw.speculativeLeadTokens)
43
43
  : undefined,
44
+ summarizationMaxDurationMs: typeof raw?.summarizationMaxDurationMs === "number" &&
45
+ Number.isFinite(raw.summarizationMaxDurationMs) &&
46
+ raw.summarizationMaxDurationMs > 0
47
+ ? raw.summarizationMaxDurationMs
48
+ : undefined,
44
49
  };
45
50
  }
46
51
  //# sourceMappingURL=compaction-settings-resolver.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compaction-settings-resolver.js","sourceRoot":"","sources":["../../src/core/compaction-settings-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CompactionSettings } from \"./compaction-settings-access.ts\";\n\nexport interface ResolvedCompactionSettings {\n\tenabled: boolean;\n\treserveTokens: number;\n\tkeepRecentTokens: number;\n\tspeculativeEnabled: boolean;\n\tspeculativeFraction: number;\n\tspeculativeCooldownMs: number;\n\trestorationEnabled: boolean;\n\trestorationMaxItems: number;\n\trestorationMaxTokensPerItem: number;\n\trestorationMaxTotalTokens: number;\n\trestorationContextRatio: number;\n\tidleCompactionEnabled: boolean;\n\tgraceBandEnabled: boolean;\n\ttoolAdmissionEnabled: boolean;\n\treminderEnabled: boolean;\n\treserveScalingEnabled: boolean;\n\tspeculativeLeadTokens?: number;\n}\n\nconst DEFAULTS = {\n\tenabled: true,\n\treserveTokens: 16384,\n\tkeepRecentTokens: 20000,\n\tspeculativeEnabled: true,\n\tspeculativeFraction: 0.75,\n\tspeculativeCooldownMs: 30000,\n\trestorationEnabled: true,\n\trestorationMaxItems: 10,\n\trestorationMaxTokensPerItem: 5000,\n\trestorationMaxTotalTokens: 50_000,\n\trestorationContextRatio: 0.15,\n\tidleCompactionEnabled: true,\n\tgraceBandEnabled: true,\n\ttoolAdmissionEnabled: true,\n\treminderEnabled: true,\n\treserveScalingEnabled: true,\n} as const;\n\nfunction finiteNumber(value: unknown, fallback: number, minimum = 0): number {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? Math.max(minimum, value) : fallback;\n}\n\nexport function resolveCompactionSettings(settings?: CompactionSettings): ResolvedCompactionSettings {\n\tconst raw = settings as Record<string, unknown> | undefined;\n\treturn {\n\t\tenabled: typeof raw?.enabled === \"boolean\" ? raw.enabled : DEFAULTS.enabled,\n\t\treserveTokens: finiteNumber(raw?.reserveTokens, DEFAULTS.reserveTokens),\n\t\tkeepRecentTokens: finiteNumber(raw?.keepRecentTokens, DEFAULTS.keepRecentTokens),\n\t\tspeculativeEnabled:\n\t\t\ttypeof raw?.speculativeEnabled === \"boolean\" ? raw.speculativeEnabled : DEFAULTS.speculativeEnabled,\n\t\tspeculativeFraction: finiteNumber(raw?.speculativeFraction, DEFAULTS.speculativeFraction),\n\t\tspeculativeCooldownMs: finiteNumber(raw?.speculativeCooldownMs, DEFAULTS.speculativeCooldownMs),\n\t\trestorationEnabled:\n\t\t\ttypeof raw?.restorationEnabled === \"boolean\" ? raw.restorationEnabled : DEFAULTS.restorationEnabled,\n\t\trestorationMaxItems: finiteNumber(raw?.restorationMaxItems, DEFAULTS.restorationMaxItems),\n\t\trestorationMaxTokensPerItem: finiteNumber(raw?.restorationMaxTokensPerItem, DEFAULTS.restorationMaxTokensPerItem),\n\t\trestorationMaxTotalTokens: finiteNumber(raw?.restorationMaxTotalTokens, DEFAULTS.restorationMaxTotalTokens),\n\t\trestorationContextRatio: finiteNumber(raw?.restorationContextRatio, DEFAULTS.restorationContextRatio),\n\t\tidleCompactionEnabled:\n\t\t\ttypeof raw?.idleCompactionEnabled === \"boolean\" ? raw.idleCompactionEnabled : DEFAULTS.idleCompactionEnabled,\n\t\tgraceBandEnabled: typeof raw?.graceBandEnabled === \"boolean\" ? raw.graceBandEnabled : DEFAULTS.graceBandEnabled,\n\t\ttoolAdmissionEnabled:\n\t\t\ttypeof raw?.toolAdmissionEnabled === \"boolean\" ? raw.toolAdmissionEnabled : DEFAULTS.toolAdmissionEnabled,\n\t\treminderEnabled: typeof raw?.reminderEnabled === \"boolean\" ? raw.reminderEnabled : DEFAULTS.reminderEnabled,\n\t\treserveScalingEnabled:\n\t\t\ttypeof raw?.reserveScalingEnabled === \"boolean\" ? raw.reserveScalingEnabled : DEFAULTS.reserveScalingEnabled,\n\t\tspeculativeLeadTokens:\n\t\t\ttypeof raw?.speculativeLeadTokens === \"number\" && Number.isFinite(raw.speculativeLeadTokens)\n\t\t\t\t? Math.max(0, raw.speculativeLeadTokens)\n\t\t\t\t: undefined,\n\t};\n}\n"]}
1
+ {"version":3,"file":"compaction-settings-resolver.js","sourceRoot":"","sources":["../../src/core/compaction-settings-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CompactionSettings } from \"./compaction-settings-access.ts\";\n\nexport interface ResolvedCompactionSettings {\n\tenabled: boolean;\n\treserveTokens: number;\n\tkeepRecentTokens: number;\n\tspeculativeEnabled: boolean;\n\tspeculativeFraction: number;\n\tspeculativeCooldownMs: number;\n\trestorationEnabled: boolean;\n\trestorationMaxItems: number;\n\trestorationMaxTokensPerItem: number;\n\trestorationMaxTotalTokens: number;\n\trestorationContextRatio: number;\n\tidleCompactionEnabled: boolean;\n\tgraceBandEnabled: boolean;\n\ttoolAdmissionEnabled: boolean;\n\treminderEnabled: boolean;\n\treserveScalingEnabled: boolean;\n\tspeculativeLeadTokens?: number;\n\t/** Positive finite number, or undefined for the size-adaptive default. */\n\tsummarizationMaxDurationMs?: number;\n}\n\nconst DEFAULTS = {\n\tenabled: true,\n\treserveTokens: 16384,\n\tkeepRecentTokens: 20000,\n\tspeculativeEnabled: true,\n\tspeculativeFraction: 0.75,\n\tspeculativeCooldownMs: 30000,\n\trestorationEnabled: true,\n\trestorationMaxItems: 10,\n\trestorationMaxTokensPerItem: 5000,\n\trestorationMaxTotalTokens: 50_000,\n\trestorationContextRatio: 0.15,\n\tidleCompactionEnabled: true,\n\tgraceBandEnabled: true,\n\ttoolAdmissionEnabled: true,\n\treminderEnabled: true,\n\treserveScalingEnabled: true,\n} as const;\n\nfunction finiteNumber(value: unknown, fallback: number, minimum = 0): number {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? Math.max(minimum, value) : fallback;\n}\n\nexport function resolveCompactionSettings(settings?: CompactionSettings): ResolvedCompactionSettings {\n\tconst raw = settings as Record<string, unknown> | undefined;\n\treturn {\n\t\tenabled: typeof raw?.enabled === \"boolean\" ? raw.enabled : DEFAULTS.enabled,\n\t\treserveTokens: finiteNumber(raw?.reserveTokens, DEFAULTS.reserveTokens),\n\t\tkeepRecentTokens: finiteNumber(raw?.keepRecentTokens, DEFAULTS.keepRecentTokens),\n\t\tspeculativeEnabled:\n\t\t\ttypeof raw?.speculativeEnabled === \"boolean\" ? raw.speculativeEnabled : DEFAULTS.speculativeEnabled,\n\t\tspeculativeFraction: finiteNumber(raw?.speculativeFraction, DEFAULTS.speculativeFraction),\n\t\tspeculativeCooldownMs: finiteNumber(raw?.speculativeCooldownMs, DEFAULTS.speculativeCooldownMs),\n\t\trestorationEnabled:\n\t\t\ttypeof raw?.restorationEnabled === \"boolean\" ? raw.restorationEnabled : DEFAULTS.restorationEnabled,\n\t\trestorationMaxItems: finiteNumber(raw?.restorationMaxItems, DEFAULTS.restorationMaxItems),\n\t\trestorationMaxTokensPerItem: finiteNumber(raw?.restorationMaxTokensPerItem, DEFAULTS.restorationMaxTokensPerItem),\n\t\trestorationMaxTotalTokens: finiteNumber(raw?.restorationMaxTotalTokens, DEFAULTS.restorationMaxTotalTokens),\n\t\trestorationContextRatio: finiteNumber(raw?.restorationContextRatio, DEFAULTS.restorationContextRatio),\n\t\tidleCompactionEnabled:\n\t\t\ttypeof raw?.idleCompactionEnabled === \"boolean\" ? raw.idleCompactionEnabled : DEFAULTS.idleCompactionEnabled,\n\t\tgraceBandEnabled: typeof raw?.graceBandEnabled === \"boolean\" ? raw.graceBandEnabled : DEFAULTS.graceBandEnabled,\n\t\ttoolAdmissionEnabled:\n\t\t\ttypeof raw?.toolAdmissionEnabled === \"boolean\" ? raw.toolAdmissionEnabled : DEFAULTS.toolAdmissionEnabled,\n\t\treminderEnabled: typeof raw?.reminderEnabled === \"boolean\" ? raw.reminderEnabled : DEFAULTS.reminderEnabled,\n\t\treserveScalingEnabled:\n\t\t\ttypeof raw?.reserveScalingEnabled === \"boolean\" ? raw.reserveScalingEnabled : DEFAULTS.reserveScalingEnabled,\n\t\tspeculativeLeadTokens:\n\t\t\ttypeof raw?.speculativeLeadTokens === \"number\" && Number.isFinite(raw.speculativeLeadTokens)\n\t\t\t\t? Math.max(0, raw.speculativeLeadTokens)\n\t\t\t\t: undefined,\n\t\tsummarizationMaxDurationMs:\n\t\t\ttypeof raw?.summarizationMaxDurationMs === \"number\" &&\n\t\t\tNumber.isFinite(raw.summarizationMaxDurationMs) &&\n\t\t\traw.summarizationMaxDurationMs > 0\n\t\t\t\t? raw.summarizationMaxDurationMs\n\t\t\t\t: undefined,\n\t};\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  export function buildWorkingTaskSection() {
2
2
  return `## Working the Task
3
3
 
4
- Fire independent tool calls as one parallel wave - reads, searches, listings, diagnostics - and bias toward breadth when context is thin: pull in anything even loosely relevant now instead of serially later. Wasted reads cost almost nothing; stale assumptions cost the turn. Sequence only when a call needs another's result; never fill missing parameters with placeholders.
4
+ Fire independent tool calls as one parallel wave - reads, searches, listings, diagnostics - and bias toward breadth when context is thin: pull in anything even loosely relevant now instead of serially later. Wasted reads cost almost nothing; stale assumptions cost the turn. Edits and result-dependent calls go one at a time, each compared with the state you meant to produce; when the result must be seen rather than read, render after each change and look before the next. Never fill missing parameters with placeholders.
5
5
 
6
6
  Memory of file contents is unreliable - read before claiming, re-read before editing. Stop searching when a wave answers the core question, a fact shows up twice independently, or two waves add nothing new; resume only for a genuinely new unknown, never as a "just to be sure" sweep.
7
7
 
@@ -1 +1 @@
1
- {"version":3,"file":"working-task.js","sourceRoot":"","sources":["../../../src/core/dynamic-prompt/working-task.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,uBAAuB;IACtC,OAAO;;;;;;waAMga,CAAC;AACza,CAAC","sourcesContent":["export function buildWorkingTaskSection(): string {\n\treturn `## Working the Task\n\nFire independent tool calls as one parallel wave - reads, searches, listings, diagnostics - and bias toward breadth when context is thin: pull in anything even loosely relevant now instead of serially later. Wasted reads cost almost nothing; stale assumptions cost the turn. Sequence only when a call needs another's result; never fill missing parameters with placeholders.\n\nMemory of file contents is unreliable - read before claiming, re-read before editing. Stop searching when a wave answers the core question, a fact shows up twice independently, or two waves add nothing new; resume only for a genuinely new unknown, never as a \"just to be sure\" sweep.\n\nMake one reasonable plan and execute it; reopen it only when new evidence contradicts it. Do not re-derive facts already established in the conversation or re-litigate decisions the user has made. When weighing a choice, give a recommendation, not a survey. When a delegation tool is available, hand sizeable independent tracks to subagents and keep working while they run; keep work you can finish in a few calls yourself.`;\n}\n"]}
1
+ {"version":3,"file":"working-task.js","sourceRoot":"","sources":["../../../src/core/dynamic-prompt/working-task.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,uBAAuB;IACtC,OAAO;;;;;;waAMga,CAAC;AACza,CAAC","sourcesContent":["export function buildWorkingTaskSection(): string {\n\treturn `## Working the Task\n\nFire independent tool calls as one parallel wave - reads, searches, listings, diagnostics - and bias toward breadth when context is thin: pull in anything even loosely relevant now instead of serially later. Wasted reads cost almost nothing; stale assumptions cost the turn. Edits and result-dependent calls go one at a time, each compared with the state you meant to produce; when the result must be seen rather than read, render after each change and look before the next. Never fill missing parameters with placeholders.\n\nMemory of file contents is unreliable - read before claiming, re-read before editing. Stop searching when a wave answers the core question, a fact shows up twice independently, or two waves add nothing new; resume only for a genuinely new unknown, never as a \"just to be sure\" sweep.\n\nMake one reasonable plan and execute it; reopen it only when new evidence contradicts it. Do not re-derive facts already established in the conversation or re-litigate decisions the user has made. When weighing a choice, give a recommendation, not a survey. When a delegation tool is available, hand sizeable independent tracks to subagents and keep working while they run; keep work you can finish in a few calls yourself.`;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cache-keepalive/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,OAAO,EAEZ,KAAK,KAAK,EAGV,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAE1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,aAAa,EAAkC,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAItG,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AAEvD,UAAU,YAAY;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC1B;AAED,UAAU,SAAS;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACxC;AAED,UAAU,YAAY;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACxC;AAED,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,SAAS,GAAG,YAAY,CAAC;AAE9E,KAAK,iBAAiB,GAAG,CACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,sBAAsB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpC,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,uBAAuB,CAS3E,CAAC;AAEH,wBAAgB,6BAA6B,CAC5C,YAAY,GAAE;IAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,iBAAiB,CAAA;CAAO,GACjE,gBAAgB,CAwNlB;;AAgED,wBAA+C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cache-keepalive/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,KAAK,OAAO,EAEZ,KAAK,KAAK,EAGV,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAE1B,MAAM,uBAAuB,CAAC;AAG/B,OAAO,KAAK,EAAE,aAAa,EAAkC,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGtG,eAAO,MAAM,0BAA0B,oBAAoB,CAAC;AAC5D,eAAO,MAAM,qBAAqB,oBAAoB,CAAC;AAEvD,UAAU,YAAY;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC1B;AAED,UAAU,SAAS;IAClB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACxC;AAED,UAAU,YAAY;IACrB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,sBAAsB,EAAE,MAAM,CAAC;CACxC;AAED,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,SAAS,GAAG,YAAY,CAAC;AAE9E,KAAK,iBAAiB,GAAG,CACxB,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EACjB,OAAO,EAAE,OAAO,EAChB,OAAO,CAAC,EAAE,sBAAsB,KAC5B,OAAO,CAAC,qBAAqB,CAAC,CAAC;AAEpC,eAAO,MAAM,yBAAyB,EAAE,aAAa,CAAC,uBAAuB,CAS3E,CAAC;AAEH,wBAAgB,6BAA6B,CAC5C,YAAY,GAAE;IAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,iBAAiB,CAAA;CAAO,GACjE,gBAAgB,CA+MlB;;AAuDD,wBAA+C"}
@@ -2,7 +2,6 @@ import { isAnthropicApiBaseUrl, resolvePromptCacheTtlSeconds, warmPromptCache, }
2
2
  import { convertToLlm, filterContextExcludedMessages } from "../../../messages.js";
3
3
  import { noticeEntryRenderer } from "../../notice/index.js";
4
4
  import { formatWarmTokenCount } from "../goal/cache-warm.js";
5
- import { GOAL_CONTINUATION_TIMER_STATE_EVENT } from "../goal/monitor-continuation.js";
6
5
  export const CACHE_KEEPALIVE_ENTRY_TYPE = "cache-keepalive";
7
6
  export const CACHE_WARM_PING_EVENT = "cache_warm_ping";
8
7
  export const renderCacheKeepAliveEntry = noticeEntryRenderer((entry) => {
@@ -24,20 +23,16 @@ export function createCacheKeepAliveExtension(dependencies = {}) {
24
23
  let inFlight = false;
25
24
  let generation = 0;
26
25
  let active = false;
27
- let goalTimerArmed = false;
28
26
  let attempts = 0;
29
27
  let cumulativeEstimatedUsd = 0;
30
28
  let lastCompletedAtMs;
31
29
  let lastMessages = [];
32
30
  let lastUsage;
33
31
  pi.registerEntryRenderer(CACHE_KEEPALIVE_ENTRY_TYPE, renderCacheKeepAliveEntry);
34
- const unsubscribeGoalTimer = pi.events?.on(GOAL_CONTINUATION_TIMER_STATE_EVENT, (data) => {
35
- if (!isGoalTimerState(data))
36
- return;
37
- goalTimerArmed = data.armed;
38
- if (data.armed)
39
- stop("goal-timer-armed");
40
- });
32
+ // No goal-timer coupling: an armed goal continuation timer issues no
33
+ // provider request until it fires, and `promptCache.goalBackstopMaxSeconds`
34
+ // may place that past the TTL, so it cannot be relied on to refresh the
35
+ // prompt cache on this loop's behalf.
41
36
  function append(data) {
42
37
  pi.appendEntry(CACHE_KEEPALIVE_ENTRY_TYPE, data);
43
38
  }
@@ -74,10 +69,6 @@ export function createCacheKeepAliveExtension(dependencies = {}) {
74
69
  stop("pending-messages");
75
70
  return;
76
71
  }
77
- if (goalTimerArmed) {
78
- stop("goal-timer-armed");
79
- return;
80
- }
81
72
  const safeWaitSeconds = current.getPromptCacheSafeWaitSeconds?.();
82
73
  if (safeWaitSeconds === undefined || !Number.isFinite(safeWaitSeconds))
83
74
  return;
@@ -113,7 +104,6 @@ export function createCacheKeepAliveExtension(dependencies = {}) {
113
104
  !isWarmSupportedModel(current.model) ||
114
105
  !current.isIdle() ||
115
106
  current.hasPendingMessages() ||
116
- goalTimerArmed ||
117
107
  attempts >= Math.max(0, settings.maxRequestsPerSession) ||
118
108
  cumulativeEstimatedUsd + projectedPingCost(current.model, lastUsage) >
119
109
  Math.max(0, settings.maxCostUsdPerSession)) {
@@ -225,7 +215,6 @@ export function createCacheKeepAliveExtension(dependencies = {}) {
225
215
  pi.on("input", () => stop("user-input"));
226
216
  pi.on("session_shutdown", () => {
227
217
  stop("session-dispose");
228
- unsubscribeGoalTimer?.();
229
218
  ctx = undefined;
230
219
  });
231
220
  };
@@ -271,11 +260,5 @@ function finiteTokens(value) {
271
260
  function formatUsd(value) {
272
261
  return `$${value.toFixed(3)}`;
273
262
  }
274
- function isGoalTimerState(value) {
275
- return (typeof value === "object" &&
276
- value !== null &&
277
- typeof value.armed === "boolean" &&
278
- typeof value.kind === "string");
279
- }
280
263
  export default createCacheKeepAliveExtension();
281
264
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cache-keepalive/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype Context,\n\tisAnthropicApiBaseUrl,\n\ttype Model,\n\tresolvePromptCacheTtlSeconds,\n\ttype Tool,\n\ttype WarmPromptCacheOptions,\n\ttype WarmPromptCacheResult,\n\twarmPromptCache,\n} from \"@earendil-works/pi-ai\";\nimport { convertToLlm, filterContextExcludedMessages } from \"../../../messages.ts\";\nimport { noticeEntryRenderer } from \"../../notice/index.ts\";\nimport type { EntryRenderer, ExtensionAPI, ExtensionContext, ExtensionFactory } from \"../../types.ts\";\nimport { formatWarmTokenCount } from \"../goal/cache-warm.ts\";\nimport { GOAL_CONTINUATION_TIMER_STATE_EVENT } from \"../goal/monitor-continuation.ts\";\n\nexport const CACHE_KEEPALIVE_ENTRY_TYPE = \"cache-keepalive\";\nexport const CACHE_WARM_PING_EVENT = \"cache_warm_ping\";\n\ninterface StartedEntry {\n\treadonly phase: \"started\";\n}\n\ninterface PingEntry {\n\treadonly phase: \"ping\";\n\treadonly iteration: number;\n\treadonly cacheRead: number;\n\treadonly cacheWrite: number;\n\treadonly estimatedCostUsd: number;\n\treadonly cumulativeEstimatedUsd: number;\n}\n\ninterface StoppedEntry {\n\treadonly phase: \"stopped\";\n\treadonly iterations: number;\n\treadonly stopReason: string;\n\treadonly cumulativeEstimatedUsd: number;\n}\n\nexport type CacheKeepAliveEntryData = StartedEntry | PingEntry | StoppedEntry;\n\ntype WarmPromptCacheFn = (\n\tmodel: Model<any>,\n\tcontext: Context,\n\toptions?: WarmPromptCacheOptions,\n) => Promise<WarmPromptCacheResult>;\n\nexport const renderCacheKeepAliveEntry: EntryRenderer<CacheKeepAliveEntryData> = noticeEntryRenderer((entry) => {\n\tconst data = entry.data;\n\tif (data?.phase !== \"ping\") return undefined;\n\tconst refreshed = data.cacheRead + data.cacheWrite;\n\treturn {\n\t\ttitle: `⚡ Warm ping #${data.iteration} · ~${formatWarmTokenCount(refreshed)} tokens refreshed · ${formatUsd(data.estimatedCostUsd)}`,\n\t\twhy: \"Refreshed the active Anthropic prompt cache while the session was idle.\",\n\t\texpandedLine: `cache read ${data.cacheRead} · cache write ${data.cacheWrite} · session total ${formatUsd(data.cumulativeEstimatedUsd)}`,\n\t};\n});\n\nexport function createCacheKeepAliveExtension(\n\tdependencies: { readonly warmPromptCache?: WarmPromptCacheFn } = {},\n): ExtensionFactory {\n\tconst warm = dependencies.warmPromptCache ?? warmPromptCache;\n\treturn (pi: ExtensionAPI) => {\n\t\tlet ctx: ExtensionContext | undefined;\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet inFlight = false;\n\t\tlet generation = 0;\n\t\tlet active = false;\n\t\tlet goalTimerArmed = false;\n\t\tlet attempts = 0;\n\t\tlet cumulativeEstimatedUsd = 0;\n\t\tlet lastCompletedAtMs: number | undefined;\n\t\tlet lastMessages: AgentMessage[] = [];\n\t\tlet lastUsage: { input: number; cacheRead: number; cacheWrite: number } | undefined;\n\n\t\tpi.registerEntryRenderer(CACHE_KEEPALIVE_ENTRY_TYPE, renderCacheKeepAliveEntry);\n\n\t\tconst unsubscribeGoalTimer = pi.events?.on(GOAL_CONTINUATION_TIMER_STATE_EVENT, (data) => {\n\t\t\tif (!isGoalTimerState(data)) return;\n\t\t\tgoalTimerArmed = data.armed;\n\t\t\tif (data.armed) stop(\"goal-timer-armed\");\n\t\t});\n\n\t\tfunction append(data: CacheKeepAliveEntryData): void {\n\t\t\tpi.appendEntry(CACHE_KEEPALIVE_ENTRY_TYPE, data);\n\t\t}\n\n\t\tfunction stop(reason: string, forceEntry = false): void {\n\t\t\tconst shouldAppend = active || inFlight || timer !== undefined || forceEntry;\n\t\t\tgeneration += 1;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tactive = false;\n\t\t\tif (shouldAppend) {\n\t\t\t\tappend({\n\t\t\t\t\tphase: \"stopped\",\n\t\t\t\t\titerations: attempts,\n\t\t\t\t\tstopReason: reason,\n\t\t\t\t\tcumulativeEstimatedUsd,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction arm(): void {\n\t\t\tif (timer !== undefined || inFlight) return;\n\t\t\tconst current = ctx;\n\t\t\tconst settings = current?.getPromptCacheKeepAliveSettings?.();\n\t\t\tif (!settings?.enabled || current?.model === undefined || lastCompletedAtMs === undefined) return;\n\t\t\tif (!isWarmSupportedModel(current.model)) return;\n\t\t\tif (!current.isIdle()) {\n\t\t\t\tstop(\"agent-busy\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (current.hasPendingMessages()) {\n\t\t\t\tstop(\"pending-messages\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (goalTimerArmed) {\n\t\t\t\tstop(\"goal-timer-armed\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst safeWaitSeconds = current.getPromptCacheSafeWaitSeconds?.();\n\t\t\tif (safeWaitSeconds === undefined || !Number.isFinite(safeWaitSeconds)) return;\n\t\t\tif (attempts >= Math.max(0, settings.maxRequestsPerSession)) {\n\t\t\t\tstop(\"max-requests\", true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst projectedUsd = projectedPingCost(current.model, lastUsage);\n\t\t\tif (cumulativeEstimatedUsd + projectedUsd > Math.max(0, settings.maxCostUsdPerSession)) {\n\t\t\t\tstop(\"cost-cap\", true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!active) {\n\t\t\t\tactive = true;\n\t\t\t\tappend({ phase: \"started\" });\n\t\t\t}\n\t\t\tconst intervalMs = Math.max(0, safeWaitSeconds - Math.max(0, settings.marginSeconds)) * 1000;\n\t\t\tconst delayMs = Math.max(0, lastCompletedAtMs + intervalMs - Date.now());\n\t\t\tconst scheduledGeneration = generation;\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\ttimer = undefined;\n\t\t\t\tvoid ping(scheduledGeneration);\n\t\t\t}, delayMs);\n\t\t}\n\n\t\tasync function ping(scheduledGeneration: number): Promise<void> {\n\t\t\tif (scheduledGeneration !== generation) return;\n\t\t\tconst current = ctx;\n\t\t\tconst settings = current?.getPromptCacheKeepAliveSettings?.();\n\t\t\tif (\n\t\t\t\tcurrent === undefined ||\n\t\t\t\tsettings?.enabled !== true ||\n\t\t\t\tcurrent.model === undefined ||\n\t\t\t\t!isWarmSupportedModel(current.model) ||\n\t\t\t\t!current.isIdle() ||\n\t\t\t\tcurrent.hasPendingMessages() ||\n\t\t\t\tgoalTimerArmed ||\n\t\t\t\tattempts >= Math.max(0, settings.maxRequestsPerSession) ||\n\t\t\t\tcumulativeEstimatedUsd + projectedPingCost(current.model, lastUsage) >\n\t\t\t\t\tMath.max(0, settings.maxCostUsdPerSession)\n\t\t\t) {\n\t\t\t\tarm();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tinFlight = true;\n\t\t\tattempts += 1;\n\t\t\tconst iteration = attempts;\n\t\t\tconst pingGeneration = generation;\n\t\t\ttry {\n\t\t\t\tconst preparation = await current.prepareProviderRequest?.(lastMessages);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst preparedMessages = preparation?.messages ?? lastMessages;\n\t\t\t\tconst activeToolNames = new Set(pi.getActiveTools());\n\t\t\t\tconst tools: Tool[] = pi\n\t\t\t\t\t.getAllTools()\n\t\t\t\t\t.filter((tool) => activeToolNames.has(tool.name))\n\t\t\t\t\t.map(({ name, description, parameters }) => ({ name, description, parameters }));\n\t\t\t\tconst auth = await current.modelRegistry.getApiKeyAndHeaders(current.model);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!auth.ok) throw new Error(auth.error);\n\t\t\t\tconst authHeaders = auth.headers ?? {};\n\t\t\t\tconst headers = preparation ? await preparation.transformHeaders(authHeaders) : authHeaders;\n\t\t\t\tconst result = await warm(\n\t\t\t\t\tcurrent.model,\n\t\t\t\t\t{\n\t\t\t\t\t\tsystemPrompt: current.getSystemPrompt(),\n\t\t\t\t\t\tmessages: convertToLlm(filterContextExcludedMessages(preparedMessages)),\n\t\t\t\t\t\t...(tools.length > 0 ? { tools } : {}),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tsessionId: current.sessionManager.getSessionId(),\n\t\t\t\t\t\tcacheRetention: current.model.cacheRetention,\n\t\t\t\t\t\tonPayload: preparation ? async (payload) => await preparation.transformPayload(payload) : undefined,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!result.supported) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tstop(\"unsupported-model\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst estimatedCostUsd = actualPingCost(current.model, result.usage);\n\t\t\t\tcumulativeEstimatedUsd += estimatedCostUsd;\n\t\t\t\tlastCompletedAtMs = Date.now();\n\t\t\t\tconst cachedTokens = result.usage.cacheRead + result.usage.cacheWrite;\n\t\t\t\tconst ttlSeconds = resolvePromptCacheTtlSeconds(current.model) ?? 0;\n\t\t\t\tpi.events?.emit(CACHE_WARM_PING_EVENT, { iteration, cachedTokens, ttlSeconds, estimatedCostUsd });\n\t\t\t\tappend({\n\t\t\t\t\tphase: \"ping\",\n\t\t\t\t\titeration,\n\t\t\t\t\tcacheRead: result.usage.cacheRead,\n\t\t\t\t\tcacheWrite: result.usage.cacheWrite,\n\t\t\t\t\testimatedCostUsd,\n\t\t\t\t\tcumulativeEstimatedUsd,\n\t\t\t\t});\n\t\t\t\tinFlight = false;\n\t\t\t\tarm();\n\t\t\t} catch {\n\t\t\t\tinFlight = false;\n\t\t\t\tif (pingGeneration === generation) stop(\"provider-error\");\n\t\t\t\telse arm();\n\t\t\t}\n\t\t}\n\n\t\tpi.on(\"session_start\", (_event, nextCtx) => {\n\t\t\tstop(\"session-restart\");\n\t\t\tctx = nextCtx;\n\t\t\tattempts = 0;\n\t\t\tcumulativeEstimatedUsd = 0;\n\t\t\tlastMessages = nextCtx.sessionManager.buildSessionContext().messages;\n\t\t\tconst usage = lastAssistantUsage(lastMessages);\n\t\t\tlastUsage = usage;\n\t\t\tlastCompletedAtMs = lastAssistantTimestamp(lastMessages);\n\t\t\tarm();\n\t\t});\n\n\t\tpi.on(\"agent_end\", (event, nextCtx) => {\n\t\t\tctx = nextCtx;\n\t\t\tconst usage = lastAssistantUsage(event.messages);\n\t\t\tif (usage?.stopReason === \"error\") {\n\t\t\t\tstop(\"provider-error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlastMessages = [...event.messages];\n\t\t\tlastUsage = usage;\n\t\t\tlastCompletedAtMs = Date.now();\n\t\t\tarm();\n\t\t});\n\n\t\tpi.on(\"model_select\", (_event, nextCtx) => {\n\t\t\tctx = nextCtx;\n\t\t\tstop(\"model-changed\");\n\t\t\tarm();\n\t\t});\n\t\tpi.on(\"agent_start\", () => stop(\"agent-busy\"));\n\t\tpi.on(\"input\", () => stop(\"user-input\"));\n\t\tpi.on(\"session_shutdown\", () => {\n\t\t\tstop(\"session-dispose\");\n\t\t\tunsubscribeGoalTimer?.();\n\t\t\tctx = undefined;\n\t\t});\n\t};\n}\n\nfunction isWarmSupportedModel(model: Model<any>): model is Model<\"anthropic-messages\"> {\n\treturn model.api === \"anthropic-messages\" && isAnthropicApiBaseUrl(model.baseUrl);\n}\n\nfunction lastAssistantUsage(\n\tmessages: readonly AgentMessage[],\n): { input: number; cacheRead: number; cacheWrite: number; stopReason?: string } | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message.role !== \"assistant\") continue;\n\t\treturn {\n\t\t\tinput: finiteTokens(message.usage.input),\n\t\t\tcacheRead: finiteTokens(message.usage.cacheRead),\n\t\t\tcacheWrite: finiteTokens(message.usage.cacheWrite),\n\t\t\tstopReason: message.stopReason,\n\t\t};\n\t}\n\treturn undefined;\n}\n\nfunction lastAssistantTimestamp(messages: readonly AgentMessage[]): number | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message.role === \"assistant\" && Number.isFinite(message.timestamp)) return message.timestamp;\n\t}\n\treturn undefined;\n}\n\nfunction projectedPingCost(\n\tmodel: Model<any>,\n\tusage: { input: number; cacheRead: number; cacheWrite: number } | undefined,\n): number {\n\tconst promptTokens = (usage?.input ?? 0) + (usage?.cacheRead ?? 0) + (usage?.cacheWrite ?? 0);\n\treturn (promptTokens * Math.max(model.cost.cacheRead, model.cost.cacheWrite)) / 1_000_000;\n}\n\nfunction actualPingCost(model: Model<any>, usage: { input: number; cacheRead: number; cacheWrite: number }): number {\n\treturn (\n\t\t(usage.cacheRead * model.cost.cacheRead +\n\t\t\tusage.cacheWrite * model.cost.cacheWrite +\n\t\t\tusage.input * model.cost.input) /\n\t\t1_000_000\n\t);\n}\n\nfunction finiteTokens(value: number): number {\n\treturn Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nfunction formatUsd(value: number): string {\n\treturn `$${value.toFixed(3)}`;\n}\n\nfunction isGoalTimerState(value: unknown): value is { armed: boolean; kind: string } {\n\treturn (\n\t\ttypeof value === \"object\" &&\n\t\tvalue !== null &&\n\t\ttypeof (value as { armed?: unknown }).armed === \"boolean\" &&\n\t\ttypeof (value as { kind?: unknown }).kind === \"string\"\n\t);\n}\n\nexport default createCacheKeepAliveExtension();\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/cache-keepalive/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype Context,\n\tisAnthropicApiBaseUrl,\n\ttype Model,\n\tresolvePromptCacheTtlSeconds,\n\ttype Tool,\n\ttype WarmPromptCacheOptions,\n\ttype WarmPromptCacheResult,\n\twarmPromptCache,\n} from \"@earendil-works/pi-ai\";\nimport { convertToLlm, filterContextExcludedMessages } from \"../../../messages.ts\";\nimport { noticeEntryRenderer } from \"../../notice/index.ts\";\nimport type { EntryRenderer, ExtensionAPI, ExtensionContext, ExtensionFactory } from \"../../types.ts\";\nimport { formatWarmTokenCount } from \"../goal/cache-warm.ts\";\n\nexport const CACHE_KEEPALIVE_ENTRY_TYPE = \"cache-keepalive\";\nexport const CACHE_WARM_PING_EVENT = \"cache_warm_ping\";\n\ninterface StartedEntry {\n\treadonly phase: \"started\";\n}\n\ninterface PingEntry {\n\treadonly phase: \"ping\";\n\treadonly iteration: number;\n\treadonly cacheRead: number;\n\treadonly cacheWrite: number;\n\treadonly estimatedCostUsd: number;\n\treadonly cumulativeEstimatedUsd: number;\n}\n\ninterface StoppedEntry {\n\treadonly phase: \"stopped\";\n\treadonly iterations: number;\n\treadonly stopReason: string;\n\treadonly cumulativeEstimatedUsd: number;\n}\n\nexport type CacheKeepAliveEntryData = StartedEntry | PingEntry | StoppedEntry;\n\ntype WarmPromptCacheFn = (\n\tmodel: Model<any>,\n\tcontext: Context,\n\toptions?: WarmPromptCacheOptions,\n) => Promise<WarmPromptCacheResult>;\n\nexport const renderCacheKeepAliveEntry: EntryRenderer<CacheKeepAliveEntryData> = noticeEntryRenderer((entry) => {\n\tconst data = entry.data;\n\tif (data?.phase !== \"ping\") return undefined;\n\tconst refreshed = data.cacheRead + data.cacheWrite;\n\treturn {\n\t\ttitle: `⚡ Warm ping #${data.iteration} · ~${formatWarmTokenCount(refreshed)} tokens refreshed · ${formatUsd(data.estimatedCostUsd)}`,\n\t\twhy: \"Refreshed the active Anthropic prompt cache while the session was idle.\",\n\t\texpandedLine: `cache read ${data.cacheRead} · cache write ${data.cacheWrite} · session total ${formatUsd(data.cumulativeEstimatedUsd)}`,\n\t};\n});\n\nexport function createCacheKeepAliveExtension(\n\tdependencies: { readonly warmPromptCache?: WarmPromptCacheFn } = {},\n): ExtensionFactory {\n\tconst warm = dependencies.warmPromptCache ?? warmPromptCache;\n\treturn (pi: ExtensionAPI) => {\n\t\tlet ctx: ExtensionContext | undefined;\n\t\tlet timer: ReturnType<typeof setTimeout> | undefined;\n\t\tlet inFlight = false;\n\t\tlet generation = 0;\n\t\tlet active = false;\n\t\tlet attempts = 0;\n\t\tlet cumulativeEstimatedUsd = 0;\n\t\tlet lastCompletedAtMs: number | undefined;\n\t\tlet lastMessages: AgentMessage[] = [];\n\t\tlet lastUsage: { input: number; cacheRead: number; cacheWrite: number } | undefined;\n\n\t\tpi.registerEntryRenderer(CACHE_KEEPALIVE_ENTRY_TYPE, renderCacheKeepAliveEntry);\n\n\t\t// No goal-timer coupling: an armed goal continuation timer issues no\n\t\t// provider request until it fires, and `promptCache.goalBackstopMaxSeconds`\n\t\t// may place that past the TTL, so it cannot be relied on to refresh the\n\t\t// prompt cache on this loop's behalf.\n\t\tfunction append(data: CacheKeepAliveEntryData): void {\n\t\t\tpi.appendEntry(CACHE_KEEPALIVE_ENTRY_TYPE, data);\n\t\t}\n\n\t\tfunction stop(reason: string, forceEntry = false): void {\n\t\t\tconst shouldAppend = active || inFlight || timer !== undefined || forceEntry;\n\t\t\tgeneration += 1;\n\t\t\tif (timer !== undefined) clearTimeout(timer);\n\t\t\ttimer = undefined;\n\t\t\tactive = false;\n\t\t\tif (shouldAppend) {\n\t\t\t\tappend({\n\t\t\t\t\tphase: \"stopped\",\n\t\t\t\t\titerations: attempts,\n\t\t\t\t\tstopReason: reason,\n\t\t\t\t\tcumulativeEstimatedUsd,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction arm(): void {\n\t\t\tif (timer !== undefined || inFlight) return;\n\t\t\tconst current = ctx;\n\t\t\tconst settings = current?.getPromptCacheKeepAliveSettings?.();\n\t\t\tif (!settings?.enabled || current?.model === undefined || lastCompletedAtMs === undefined) return;\n\t\t\tif (!isWarmSupportedModel(current.model)) return;\n\t\t\tif (!current.isIdle()) {\n\t\t\t\tstop(\"agent-busy\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (current.hasPendingMessages()) {\n\t\t\t\tstop(\"pending-messages\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst safeWaitSeconds = current.getPromptCacheSafeWaitSeconds?.();\n\t\t\tif (safeWaitSeconds === undefined || !Number.isFinite(safeWaitSeconds)) return;\n\t\t\tif (attempts >= Math.max(0, settings.maxRequestsPerSession)) {\n\t\t\t\tstop(\"max-requests\", true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst projectedUsd = projectedPingCost(current.model, lastUsage);\n\t\t\tif (cumulativeEstimatedUsd + projectedUsd > Math.max(0, settings.maxCostUsdPerSession)) {\n\t\t\t\tstop(\"cost-cap\", true);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!active) {\n\t\t\t\tactive = true;\n\t\t\t\tappend({ phase: \"started\" });\n\t\t\t}\n\t\t\tconst intervalMs = Math.max(0, safeWaitSeconds - Math.max(0, settings.marginSeconds)) * 1000;\n\t\t\tconst delayMs = Math.max(0, lastCompletedAtMs + intervalMs - Date.now());\n\t\t\tconst scheduledGeneration = generation;\n\t\t\ttimer = setTimeout(() => {\n\t\t\t\ttimer = undefined;\n\t\t\t\tvoid ping(scheduledGeneration);\n\t\t\t}, delayMs);\n\t\t}\n\n\t\tasync function ping(scheduledGeneration: number): Promise<void> {\n\t\t\tif (scheduledGeneration !== generation) return;\n\t\t\tconst current = ctx;\n\t\t\tconst settings = current?.getPromptCacheKeepAliveSettings?.();\n\t\t\tif (\n\t\t\t\tcurrent === undefined ||\n\t\t\t\tsettings?.enabled !== true ||\n\t\t\t\tcurrent.model === undefined ||\n\t\t\t\t!isWarmSupportedModel(current.model) ||\n\t\t\t\t!current.isIdle() ||\n\t\t\t\tcurrent.hasPendingMessages() ||\n\t\t\t\tattempts >= Math.max(0, settings.maxRequestsPerSession) ||\n\t\t\t\tcumulativeEstimatedUsd + projectedPingCost(current.model, lastUsage) >\n\t\t\t\t\tMath.max(0, settings.maxCostUsdPerSession)\n\t\t\t) {\n\t\t\t\tarm();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tinFlight = true;\n\t\t\tattempts += 1;\n\t\t\tconst iteration = attempts;\n\t\t\tconst pingGeneration = generation;\n\t\t\ttry {\n\t\t\t\tconst preparation = await current.prepareProviderRequest?.(lastMessages);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst preparedMessages = preparation?.messages ?? lastMessages;\n\t\t\t\tconst activeToolNames = new Set(pi.getActiveTools());\n\t\t\t\tconst tools: Tool[] = pi\n\t\t\t\t\t.getAllTools()\n\t\t\t\t\t.filter((tool) => activeToolNames.has(tool.name))\n\t\t\t\t\t.map(({ name, description, parameters }) => ({ name, description, parameters }));\n\t\t\t\tconst auth = await current.modelRegistry.getApiKeyAndHeaders(current.model);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!auth.ok) throw new Error(auth.error);\n\t\t\t\tconst authHeaders = auth.headers ?? {};\n\t\t\t\tconst headers = preparation ? await preparation.transformHeaders(authHeaders) : authHeaders;\n\t\t\t\tconst result = await warm(\n\t\t\t\t\tcurrent.model,\n\t\t\t\t\t{\n\t\t\t\t\t\tsystemPrompt: current.getSystemPrompt(),\n\t\t\t\t\t\tmessages: convertToLlm(filterContextExcludedMessages(preparedMessages)),\n\t\t\t\t\t\t...(tools.length > 0 ? { tools } : {}),\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\t\t\theaders,\n\t\t\t\t\t\tsessionId: current.sessionManager.getSessionId(),\n\t\t\t\t\t\tcacheRetention: current.model.cacheRetention,\n\t\t\t\t\t\tonPayload: preparation ? async (payload) => await preparation.transformPayload(payload) : undefined,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t\tif (pingGeneration !== generation) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tarm();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif (!result.supported) {\n\t\t\t\t\tinFlight = false;\n\t\t\t\t\tstop(\"unsupported-model\");\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tconst estimatedCostUsd = actualPingCost(current.model, result.usage);\n\t\t\t\tcumulativeEstimatedUsd += estimatedCostUsd;\n\t\t\t\tlastCompletedAtMs = Date.now();\n\t\t\t\tconst cachedTokens = result.usage.cacheRead + result.usage.cacheWrite;\n\t\t\t\tconst ttlSeconds = resolvePromptCacheTtlSeconds(current.model) ?? 0;\n\t\t\t\tpi.events?.emit(CACHE_WARM_PING_EVENT, { iteration, cachedTokens, ttlSeconds, estimatedCostUsd });\n\t\t\t\tappend({\n\t\t\t\t\tphase: \"ping\",\n\t\t\t\t\titeration,\n\t\t\t\t\tcacheRead: result.usage.cacheRead,\n\t\t\t\t\tcacheWrite: result.usage.cacheWrite,\n\t\t\t\t\testimatedCostUsd,\n\t\t\t\t\tcumulativeEstimatedUsd,\n\t\t\t\t});\n\t\t\t\tinFlight = false;\n\t\t\t\tarm();\n\t\t\t} catch {\n\t\t\t\tinFlight = false;\n\t\t\t\tif (pingGeneration === generation) stop(\"provider-error\");\n\t\t\t\telse arm();\n\t\t\t}\n\t\t}\n\n\t\tpi.on(\"session_start\", (_event, nextCtx) => {\n\t\t\tstop(\"session-restart\");\n\t\t\tctx = nextCtx;\n\t\t\tattempts = 0;\n\t\t\tcumulativeEstimatedUsd = 0;\n\t\t\tlastMessages = nextCtx.sessionManager.buildSessionContext().messages;\n\t\t\tconst usage = lastAssistantUsage(lastMessages);\n\t\t\tlastUsage = usage;\n\t\t\tlastCompletedAtMs = lastAssistantTimestamp(lastMessages);\n\t\t\tarm();\n\t\t});\n\n\t\tpi.on(\"agent_end\", (event, nextCtx) => {\n\t\t\tctx = nextCtx;\n\t\t\tconst usage = lastAssistantUsage(event.messages);\n\t\t\tif (usage?.stopReason === \"error\") {\n\t\t\t\tstop(\"provider-error\");\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tlastMessages = [...event.messages];\n\t\t\tlastUsage = usage;\n\t\t\tlastCompletedAtMs = Date.now();\n\t\t\tarm();\n\t\t});\n\n\t\tpi.on(\"model_select\", (_event, nextCtx) => {\n\t\t\tctx = nextCtx;\n\t\t\tstop(\"model-changed\");\n\t\t\tarm();\n\t\t});\n\t\tpi.on(\"agent_start\", () => stop(\"agent-busy\"));\n\t\tpi.on(\"input\", () => stop(\"user-input\"));\n\t\tpi.on(\"session_shutdown\", () => {\n\t\t\tstop(\"session-dispose\");\n\t\t\tctx = undefined;\n\t\t});\n\t};\n}\n\nfunction isWarmSupportedModel(model: Model<any>): model is Model<\"anthropic-messages\"> {\n\treturn model.api === \"anthropic-messages\" && isAnthropicApiBaseUrl(model.baseUrl);\n}\n\nfunction lastAssistantUsage(\n\tmessages: readonly AgentMessage[],\n): { input: number; cacheRead: number; cacheWrite: number; stopReason?: string } | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message.role !== \"assistant\") continue;\n\t\treturn {\n\t\t\tinput: finiteTokens(message.usage.input),\n\t\t\tcacheRead: finiteTokens(message.usage.cacheRead),\n\t\t\tcacheWrite: finiteTokens(message.usage.cacheWrite),\n\t\t\tstopReason: message.stopReason,\n\t\t};\n\t}\n\treturn undefined;\n}\n\nfunction lastAssistantTimestamp(messages: readonly AgentMessage[]): number | undefined {\n\tfor (let index = messages.length - 1; index >= 0; index -= 1) {\n\t\tconst message = messages[index];\n\t\tif (message.role === \"assistant\" && Number.isFinite(message.timestamp)) return message.timestamp;\n\t}\n\treturn undefined;\n}\n\nfunction projectedPingCost(\n\tmodel: Model<any>,\n\tusage: { input: number; cacheRead: number; cacheWrite: number } | undefined,\n): number {\n\tconst promptTokens = (usage?.input ?? 0) + (usage?.cacheRead ?? 0) + (usage?.cacheWrite ?? 0);\n\treturn (promptTokens * Math.max(model.cost.cacheRead, model.cost.cacheWrite)) / 1_000_000;\n}\n\nfunction actualPingCost(model: Model<any>, usage: { input: number; cacheRead: number; cacheWrite: number }): number {\n\treturn (\n\t\t(usage.cacheRead * model.cost.cacheRead +\n\t\t\tusage.cacheWrite * model.cost.cacheWrite +\n\t\t\tusage.input * model.cost.input) /\n\t\t1_000_000\n\t);\n}\n\nfunction finiteTokens(value: number): number {\n\treturn Number.isFinite(value) && value > 0 ? value : 0;\n}\n\nfunction formatUsd(value: number): string {\n\treturn `$${value.toFixed(3)}`;\n}\n\nexport default createCacheKeepAliveExtension();\n"]}
@@ -4,6 +4,8 @@ type CommandEnvironment = (name: string) => string | undefined;
4
4
  export interface ClaudeAccountCommandDeps {
5
5
  loadSettings?: (cwd: string) => ClaudeSdkOauthProviderSettings;
6
6
  environment?: CommandEnvironment;
7
+ /** Browser launcher for the OAuth authorize URL; tests inject a recorder. */
8
+ openBrowser?: ((url: string) => void) | undefined;
7
9
  }
8
10
  export declare function getSessionClaudeAccountPin(sessionId: string | undefined): string | undefined;
9
11
  /** CLI pins are request-local overrides; settings and stored pins remain fallback choices. */
@@ -1 +1 @@
1
- {"version":3,"file":"account-command.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/account-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;AAK5E,OAAO,EAAE,KAAK,8BAA8B,EAA8C,MAAM,eAAe,CAAC;AAIhH,KAAK,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAE/D,MAAM,WAAW,wBAAwB;IACxC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,8BAA8B,CAAC;IAC/D,WAAW,CAAC,EAAE,kBAAkB,CAAC;CACjC;AAgDD,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE5F;AAED,8FAA8F;AAC9F,wBAAgB,uBAAuB,CACtC,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,qBAAqB,EAAE,MAAM,GAAG,SAAS,EACzC,mBAAmB,EAAE,MAAM,GAAG,SAAS,GACrC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,GAAE,wBAA6B,GAAG,IAAI,CA8CxG"}
1
+ {"version":3,"file":"account-command.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/claude-sdk-oauth/account-command.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAA2B,MAAM,gBAAgB,CAAC;AAM5E,OAAO,EAAE,KAAK,8BAA8B,EAA8C,MAAM,eAAe,CAAC;AAIhH,KAAK,kBAAkB,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC;AAE/D,MAAM,WAAW,wBAAwB;IACxC,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,8BAA8B,CAAC;IAC/D,WAAW,CAAC,EAAE,kBAAkB,CAAC;IACjC,6EAA6E;IAC7E,WAAW,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAClD;AAsCD,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAE5F;AAED,8FAA8F;AAC9F,wBAAgB,uBAAuB,CACtC,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,qBAAqB,EAAE,MAAM,GAAG,SAAS,EACzC,mBAAmB,EAAE,MAAM,GAAG,SAAS,GACrC,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,4BAA4B,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,GAAE,wBAA6B,GAAG,IAAI,CA8CxG"}
@@ -1,9 +1,11 @@
1
+ import { createExtensionLoginInteraction, LOGIN_CANCELLED_MESSAGE } from "../oauth-login-interaction.js";
1
2
  import { emitProviderAccountsChanged } from "./account-events.js";
2
3
  import { CLAUDE_SDK_OAUTH_PROVIDER_ID, pinProviderAccount, removeProviderAccount } from "./account-management.js";
3
4
  import { emptyCredential, listAccounts } from "./accounts.js";
4
5
  import { selectAccount } from "./affinity.js";
5
6
  import { loadClaudeSdkOauthProviderSettingsFromDisk } from "./settings.js";
6
7
  const cliPinsBySession = new Map();
8
+ const CLAUDE_SDK_OAUTH_PROVIDER_LABEL = "Claude SDK OAuth";
7
9
  function asCredential(value) {
8
10
  return value?.type === "oauth" ? value : undefined;
9
11
  }
@@ -28,18 +30,6 @@ function accountError(ctx, name) {
28
30
  function parseArgs(rawArgs) {
29
31
  return rawArgs.trim().split(/\s+/).filter(Boolean);
30
32
  }
31
- function authEventMessage(event) {
32
- if (event === null || typeof event !== "object")
33
- return "Claude SDK OAuth authentication update.";
34
- const value = event;
35
- if (value.type === "auth_url" && typeof value.url === "string") {
36
- return `Open this URL to authorize Claude SDK OAuth:\n${value.url}`;
37
- }
38
- if (value.type === "device_code" && typeof value.verificationUri === "string") {
39
- return `Open this URL to authorize Claude SDK OAuth:\n${value.verificationUri}`;
40
- }
41
- return typeof value.message === "string" ? value.message : "Claude SDK OAuth authentication update.";
42
- }
43
33
  export function getSessionClaudeAccountPin(sessionId) {
44
34
  return sessionId === undefined ? undefined : cliPinsBySession.get(sessionId);
45
35
  }
@@ -76,7 +66,7 @@ export function registerClaudeAccountCommand(pi, deps = {}) {
76
66
  return;
77
67
  }
78
68
  if (action === "add") {
79
- await addAccount(ctx);
69
+ await addAccount(ctx, deps);
80
70
  return;
81
71
  }
82
72
  if (action === "remove") {
@@ -128,29 +118,24 @@ function showAccounts(ctx, settings, environment) {
128
118
  lines.push(`Affinity pick: ${affinityPick ?? (affinityError ? `unavailable - ${affinityError}` : "none")}`);
129
119
  ctx.ui.notify(lines.join("\n"), "info");
130
120
  }
131
- async function addAccount(ctx) {
121
+ async function addAccount(ctx, deps) {
132
122
  if (!ctx.hasUI) {
133
123
  ctx.ui.notify("/claude-account add requires an interactive UI.", "error");
134
124
  return;
135
125
  }
136
126
  try {
137
- await ctx.modelRegistry.modelRuntime.login(CLAUDE_SDK_OAUTH_PROVIDER_ID, "oauth", {
138
- signal: ctx.signal,
139
- prompt: async (prompt) => {
140
- const answer = await ctx.ui.input(prompt.message);
141
- if (answer === undefined)
142
- throw new Error("Login cancelled");
143
- return answer;
144
- },
145
- notify: (event) => ctx.ui.notify(authEventMessage(event), "info"),
146
- });
127
+ await ctx.modelRegistry.modelRuntime.login(CLAUDE_SDK_OAUTH_PROVIDER_ID, "oauth", createExtensionLoginInteraction(ctx, {
128
+ providerLabel: CLAUDE_SDK_OAUTH_PROVIDER_LABEL,
129
+ openBrowser: deps.openBrowser,
130
+ }));
147
131
  emitProviderAccountsChanged(CLAUDE_SDK_OAUTH_PROVIDER_ID);
148
132
  ctx.ui.notify("Claude SDK OAuth account added.", "info");
149
133
  }
150
134
  catch (error) {
151
135
  const message = error instanceof Error ? error.message : String(error);
152
- if (message !== "Login cancelled")
136
+ if (message !== LOGIN_CANCELLED_MESSAGE) {
153
137
  ctx.ui.notify(`Failed to add Claude SDK OAuth account: ${message}`, "error");
138
+ }
154
139
  }
155
140
  }
156
141
  async function removeNamedAccount(ctx, name, environment) {