@code-yeongyu/senpi 2026.7.17 → 2026.7.20-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 (738) hide show
  1. package/CHANGELOG.md +100 -0
  2. package/README.md +5 -2
  3. package/dist/cli/neo/build-argv.d.ts.map +1 -1
  4. package/dist/cli/neo/build-argv.js +2 -0
  5. package/dist/cli/neo/build-argv.js.map +1 -1
  6. package/dist/core/agent-session-services.d.ts.map +1 -1
  7. package/dist/core/agent-session-services.js +11 -4
  8. package/dist/core/agent-session-services.js.map +1 -1
  9. package/dist/core/agent-session.d.ts +37 -0
  10. package/dist/core/agent-session.d.ts.map +1 -1
  11. package/dist/core/agent-session.js +395 -73
  12. package/dist/core/agent-session.js.map +1 -1
  13. package/dist/core/compaction/compaction.d.ts +2 -2
  14. package/dist/core/compaction/compaction.d.ts.map +1 -1
  15. package/dist/core/compaction/compaction.js +59 -15
  16. package/dist/core/compaction/compaction.js.map +1 -1
  17. package/dist/core/dynamic-prompt/build.d.ts +7 -0
  18. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  19. package/dist/core/dynamic-prompt/build.js +5 -0
  20. package/dist/core/dynamic-prompt/build.js.map +1 -1
  21. package/dist/core/dynamic-prompt/workstation.d.ts +35 -0
  22. package/dist/core/dynamic-prompt/workstation.d.ts.map +1 -0
  23. package/dist/core/dynamic-prompt/workstation.js +81 -0
  24. package/dist/core/dynamic-prompt/workstation.js.map +1 -0
  25. package/dist/core/extensions/builtin/compaction/index.d.ts.map +1 -1
  26. package/dist/core/extensions/builtin/compaction/index.js +68 -10
  27. package/dist/core/extensions/builtin/compaction/index.js.map +1 -1
  28. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts +1 -0
  29. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.d.ts.map +1 -1
  30. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js +20 -2
  31. package/dist/core/extensions/builtin/compaction/repair-tool-pairs.js.map +1 -1
  32. package/dist/core/extensions/builtin/compaction/speculative.d.ts +7 -1
  33. package/dist/core/extensions/builtin/compaction/speculative.d.ts.map +1 -1
  34. package/dist/core/extensions/builtin/compaction/speculative.js +29 -11
  35. package/dist/core/extensions/builtin/compaction/speculative.js.map +1 -1
  36. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts +9 -7
  37. package/dist/core/extensions/builtin/compaction/todo-bridge.d.ts.map +1 -1
  38. package/dist/core/extensions/builtin/compaction/todo-bridge.js +34 -9
  39. package/dist/core/extensions/builtin/compaction/todo-bridge.js.map +1 -1
  40. package/dist/core/extensions/builtin/goal/command-registration.d.ts +2 -2
  41. package/dist/core/extensions/builtin/goal/command-registration.d.ts.map +1 -1
  42. package/dist/core/extensions/builtin/goal/command-registration.js +3 -4
  43. package/dist/core/extensions/builtin/goal/command-registration.js.map +1 -1
  44. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  45. package/dist/core/extensions/builtin/goal/index.js +11 -27
  46. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  47. package/dist/core/extensions/builtin/goal/tool-registration.d.ts +2 -2
  48. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  49. package/dist/core/extensions/builtin/goal/tool-registration.js +2 -3
  50. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  51. package/dist/core/extensions/builtin/goal/turn-usage.d.ts +20 -0
  52. package/dist/core/extensions/builtin/goal/turn-usage.d.ts.map +1 -0
  53. package/dist/core/extensions/builtin/goal/turn-usage.js +61 -0
  54. package/dist/core/extensions/builtin/goal/turn-usage.js.map +1 -0
  55. package/dist/core/extensions/builtin/gpt-apply-patch/constants.d.ts +1 -0
  56. package/dist/core/extensions/builtin/gpt-apply-patch/constants.d.ts.map +1 -1
  57. package/dist/core/extensions/builtin/gpt-apply-patch/constants.js +5 -1
  58. package/dist/core/extensions/builtin/gpt-apply-patch/constants.js.map +1 -1
  59. package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts +2 -1
  60. package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts.map +1 -1
  61. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +48 -29
  62. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
  63. package/dist/core/extensions/builtin/gpt-apply-patch/index.d.ts +2 -2
  64. package/dist/core/extensions/builtin/gpt-apply-patch/index.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/gpt-apply-patch/index.js +2 -2
  66. package/dist/core/extensions/builtin/gpt-apply-patch/index.js.map +1 -1
  67. package/dist/core/extensions/builtin/gpt-apply-patch/tool.d.ts +1 -1
  68. package/dist/core/extensions/builtin/gpt-apply-patch/tool.d.ts.map +1 -1
  69. package/dist/core/extensions/builtin/gpt-apply-patch/tool.js +5 -3
  70. package/dist/core/extensions/builtin/gpt-apply-patch/tool.js.map +1 -1
  71. package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts +7 -6
  72. package/dist/core/extensions/builtin/gpt-apply-patch/types.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/gpt-apply-patch/types.js.map +1 -1
  74. package/dist/core/extensions/builtin/hooks/matcher.d.ts.map +1 -1
  75. package/dist/core/extensions/builtin/hooks/matcher.js +1 -0
  76. package/dist/core/extensions/builtin/hooks/matcher.js.map +1 -1
  77. package/dist/core/extensions/builtin/index.d.ts.map +1 -1
  78. package/dist/core/extensions/builtin/index.js +4 -0
  79. package/dist/core/extensions/builtin/index.js.map +1 -1
  80. package/dist/core/extensions/builtin/mcp/config-schema.d.ts +8 -1
  81. package/dist/core/extensions/builtin/mcp/config-schema.d.ts.map +1 -1
  82. package/dist/core/extensions/builtin/mcp/config-schema.js +23 -0
  83. package/dist/core/extensions/builtin/mcp/config-schema.js.map +1 -1
  84. package/dist/core/extensions/builtin/mcp/config.d.ts +13 -0
  85. package/dist/core/extensions/builtin/mcp/config.d.ts.map +1 -1
  86. package/dist/core/extensions/builtin/mcp/config.js +36 -0
  87. package/dist/core/extensions/builtin/mcp/config.js.map +1 -1
  88. package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts +1 -1
  89. package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts.map +1 -1
  90. package/dist/core/extensions/builtin/mcp/expose/native-search.js +1 -1
  91. package/dist/core/extensions/builtin/mcp/expose/native-search.js.map +1 -1
  92. package/dist/core/extensions/builtin/mcp/expose/policy.js +1 -1
  93. package/dist/core/extensions/builtin/mcp/expose/policy.js.map +1 -1
  94. package/dist/core/extensions/builtin/mcp/expose/status.js +1 -1
  95. package/dist/core/extensions/builtin/mcp/expose/status.js.map +1 -1
  96. package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts +3 -3
  97. package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts.map +1 -1
  98. package/dist/core/extensions/builtin/mcp/expose/tier-b.js +10 -10
  99. package/dist/core/extensions/builtin/mcp/expose/tier-b.js.map +1 -1
  100. package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts +3 -3
  101. package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts.map +1 -1
  102. package/dist/core/extensions/builtin/mcp/expose/tool-search.js +14 -14
  103. package/dist/core/extensions/builtin/mcp/expose/tool-search.js.map +1 -1
  104. package/dist/core/extensions/builtin/mcp/index.js +5 -5
  105. package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
  106. package/dist/core/extensions/builtin/mcp/service-snapshot.d.ts.map +1 -1
  107. package/dist/core/extensions/builtin/mcp/service-snapshot.js +1 -0
  108. package/dist/core/extensions/builtin/mcp/service-snapshot.js.map +1 -1
  109. package/dist/core/extensions/builtin/mcp/service-types.d.ts +12 -0
  110. package/dist/core/extensions/builtin/mcp/service-types.d.ts.map +1 -1
  111. package/dist/core/extensions/builtin/mcp/service-types.js.map +1 -1
  112. package/dist/core/extensions/builtin/mcp/service.d.ts +2 -2
  113. package/dist/core/extensions/builtin/mcp/service.d.ts.map +1 -1
  114. package/dist/core/extensions/builtin/mcp/service.js +4 -3
  115. package/dist/core/extensions/builtin/mcp/service.js.map +1 -1
  116. package/dist/core/extensions/builtin/mcp/status.js +1 -0
  117. package/dist/core/extensions/builtin/mcp/status.js.map +1 -1
  118. package/dist/core/extensions/builtin/model-fallback/index.d.ts +4 -0
  119. package/dist/core/extensions/builtin/model-fallback/index.d.ts.map +1 -0
  120. package/dist/core/extensions/builtin/model-fallback/index.js +55 -0
  121. package/dist/core/extensions/builtin/model-fallback/index.js.map +1 -0
  122. package/dist/core/extensions/builtin/model-fallback/settings.d.ts +6 -0
  123. package/dist/core/extensions/builtin/model-fallback/settings.d.ts.map +1 -0
  124. package/dist/core/extensions/builtin/model-fallback/settings.js +11 -0
  125. package/dist/core/extensions/builtin/model-fallback/settings.js.map +1 -0
  126. package/dist/core/extensions/builtin/model-fallback/ui.d.ts +12 -0
  127. package/dist/core/extensions/builtin/model-fallback/ui.d.ts.map +1 -0
  128. package/dist/core/extensions/builtin/model-fallback/ui.js +72 -0
  129. package/dist/core/extensions/builtin/model-fallback/ui.js.map +1 -0
  130. package/dist/core/extensions/builtin/nested-agents-md/index.d.ts.map +1 -1
  131. package/dist/core/extensions/builtin/nested-agents-md/index.js +4 -1
  132. package/dist/core/extensions/builtin/nested-agents-md/index.js.map +1 -1
  133. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.d.ts.map +1 -1
  134. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +5 -1
  135. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
  136. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.d.ts.map +1 -1
  137. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js +5 -1
  138. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js.map +1 -1
  139. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.d.ts.map +1 -1
  140. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js +5 -1
  141. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js.map +1 -1
  142. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.d.ts.map +1 -1
  143. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js +5 -1
  144. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js.map +1 -1
  145. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.d.ts.map +1 -1
  146. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js +5 -1
  147. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js.map +1 -1
  148. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js +2 -2
  149. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js.map +1 -1
  150. package/dist/core/extensions/builtin/prompt-preset/gpt-5.2.js +1 -1
  151. package/dist/core/extensions/builtin/prompt-preset/gpt-5.2.js.map +1 -1
  152. package/dist/core/extensions/builtin/prompt-preset/gpt-5.3-codex.js +1 -1
  153. package/dist/core/extensions/builtin/prompt-preset/gpt-5.3-codex.js.map +1 -1
  154. package/dist/core/extensions/builtin/prompt-preset/gpt-5.4.js +1 -1
  155. package/dist/core/extensions/builtin/prompt-preset/gpt-5.4.js.map +1 -1
  156. package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js +3 -3
  157. package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js.map +1 -1
  158. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +3 -3
  159. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  160. package/dist/core/extensions/builtin/prompt-preset/gpt-5.js +1 -1
  161. package/dist/core/extensions/builtin/prompt-preset/gpt-5.js.map +1 -1
  162. package/dist/core/extensions/builtin/prompt-preset/grok-4.5.d.ts +3 -0
  163. package/dist/core/extensions/builtin/prompt-preset/grok-4.5.d.ts.map +1 -0
  164. package/dist/core/extensions/builtin/prompt-preset/grok-4.5.js +80 -0
  165. package/dist/core/extensions/builtin/prompt-preset/grok-4.5.js.map +1 -0
  166. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js +1 -1
  167. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js.map +1 -1
  168. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +1 -1
  169. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -1
  170. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -1
  171. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +5 -7
  172. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -1
  173. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  174. package/dist/core/extensions/builtin/prompt-preset/presets.js +14 -0
  175. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  176. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  177. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  178. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  179. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  180. package/dist/core/extensions/builtin/rules/index.d.ts.map +1 -1
  181. package/dist/core/extensions/builtin/rules/index.js +4 -1
  182. package/dist/core/extensions/builtin/rules/index.js.map +1 -1
  183. package/dist/core/extensions/builtin/terminal/shared.d.ts +7 -0
  184. package/dist/core/extensions/builtin/terminal/shared.d.ts.map +1 -1
  185. package/dist/core/extensions/builtin/terminal/shared.js +7 -0
  186. package/dist/core/extensions/builtin/terminal/shared.js.map +1 -1
  187. package/dist/core/extensions/builtin/terminal/tools/bash.d.ts.map +1 -1
  188. package/dist/core/extensions/builtin/terminal/tools/bash.js +68 -6
  189. package/dist/core/extensions/builtin/terminal/tools/bash.js.map +1 -1
  190. package/dist/core/extensions/builtin/todotools/commands.d.ts +18 -0
  191. package/dist/core/extensions/builtin/todotools/commands.d.ts.map +1 -0
  192. package/dist/core/extensions/builtin/todotools/commands.js +395 -0
  193. package/dist/core/extensions/builtin/todotools/commands.js.map +1 -0
  194. package/dist/core/extensions/builtin/todotools/index.d.ts +4 -1
  195. package/dist/core/extensions/builtin/todotools/index.d.ts.map +1 -1
  196. package/dist/core/extensions/builtin/todotools/index.js +17 -14
  197. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  198. package/dist/core/extensions/builtin/todotools/markdown.d.ts +13 -0
  199. package/dist/core/extensions/builtin/todotools/markdown.d.ts.map +1 -0
  200. package/dist/core/extensions/builtin/todotools/markdown.js +82 -0
  201. package/dist/core/extensions/builtin/todotools/markdown.js.map +1 -0
  202. package/dist/core/extensions/builtin/todotools/prompt.d.ts +2 -1
  203. package/dist/core/extensions/builtin/todotools/prompt.d.ts.map +1 -1
  204. package/dist/core/extensions/builtin/todotools/prompt.js +50 -153
  205. package/dist/core/extensions/builtin/todotools/prompt.js.map +1 -1
  206. package/dist/core/extensions/builtin/todotools/state.d.ts +67 -14
  207. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  208. package/dist/core/extensions/builtin/todotools/state.js +400 -35
  209. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  210. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts +22 -0
  211. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -0
  212. package/dist/core/extensions/builtin/todotools/tools/todo.js +229 -0
  213. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -0
  214. package/dist/core/extensions/builtin/video-in/index.d.ts +3 -0
  215. package/dist/core/extensions/builtin/video-in/index.d.ts.map +1 -0
  216. package/dist/core/extensions/builtin/video-in/index.js +111 -0
  217. package/dist/core/extensions/builtin/video-in/index.js.map +1 -0
  218. package/dist/core/extensions/builtin/websearch/index.d.ts.map +1 -1
  219. package/dist/core/extensions/builtin/websearch/index.js +20 -3
  220. package/dist/core/extensions/builtin/websearch/index.js.map +1 -1
  221. package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -1
  222. package/dist/core/extensions/builtin/websearch/websearch/renderers.js +13 -4
  223. package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -1
  224. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts +3 -2
  225. package/dist/core/extensions/builtin/websearch/websearch/search.d.ts.map +1 -1
  226. package/dist/core/extensions/builtin/websearch/websearch/search.js +2 -1
  227. package/dist/core/extensions/builtin/websearch/websearch/search.js.map +1 -1
  228. package/dist/core/extensions/builtin/websearch/websearch/tool.d.ts.map +1 -1
  229. package/dist/core/extensions/builtin/websearch/websearch/tool.js +17 -1
  230. package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -1
  231. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +2 -0
  232. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -1
  233. package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -1
  234. package/dist/core/extensions/index.d.ts +1 -0
  235. package/dist/core/extensions/index.d.ts.map +1 -1
  236. package/dist/core/extensions/index.js.map +1 -1
  237. package/dist/core/extensions/loader.d.ts +10 -1
  238. package/dist/core/extensions/loader.d.ts.map +1 -1
  239. package/dist/core/extensions/loader.js +64 -7
  240. package/dist/core/extensions/loader.js.map +1 -1
  241. package/dist/core/extensions/runner.d.ts +6 -2
  242. package/dist/core/extensions/runner.d.ts.map +1 -1
  243. package/dist/core/extensions/runner.js +80 -8
  244. package/dist/core/extensions/runner.js.map +1 -1
  245. package/dist/core/extensions/types.d.ts +116 -18
  246. package/dist/core/extensions/types.d.ts.map +1 -1
  247. package/dist/core/extensions/types.js.map +1 -1
  248. package/dist/core/model-registry.d.ts +5 -1
  249. package/dist/core/model-registry.d.ts.map +1 -1
  250. package/dist/core/model-registry.js +17 -2
  251. package/dist/core/model-registry.js.map +1 -1
  252. package/dist/core/model-runtime.d.ts +12 -1
  253. package/dist/core/model-runtime.d.ts.map +1 -1
  254. package/dist/core/model-runtime.js +51 -9
  255. package/dist/core/model-runtime.js.map +1 -1
  256. package/dist/core/prompt-templates.d.ts +1 -0
  257. package/dist/core/prompt-templates.d.ts.map +1 -1
  258. package/dist/core/prompt-templates.js +4 -4
  259. package/dist/core/prompt-templates.js.map +1 -1
  260. package/dist/core/provider-composer.d.ts +1 -1
  261. package/dist/core/provider-composer.d.ts.map +1 -1
  262. package/dist/core/provider-composer.js +8 -1
  263. package/dist/core/provider-composer.js.map +1 -1
  264. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  265. package/dist/core/remote-catalog-provider.js +16 -3
  266. package/dist/core/remote-catalog-provider.js.map +1 -1
  267. package/dist/core/resource-loader.d.ts +6 -0
  268. package/dist/core/resource-loader.d.ts.map +1 -1
  269. package/dist/core/resource-loader.js +27 -2
  270. package/dist/core/resource-loader.js.map +1 -1
  271. package/dist/core/retry-fallback/chains.d.ts +29 -0
  272. package/dist/core/retry-fallback/chains.d.ts.map +1 -0
  273. package/dist/core/retry-fallback/chains.js +109 -0
  274. package/dist/core/retry-fallback/chains.js.map +1 -0
  275. package/dist/core/retry-fallback/controller.d.ts +77 -0
  276. package/dist/core/retry-fallback/controller.d.ts.map +1 -0
  277. package/dist/core/retry-fallback/controller.js +157 -0
  278. package/dist/core/retry-fallback/controller.js.map +1 -0
  279. package/dist/core/retry-fallback/cooldown.d.ts +21 -0
  280. package/dist/core/retry-fallback/cooldown.d.ts.map +1 -0
  281. package/dist/core/retry-fallback/cooldown.js +49 -0
  282. package/dist/core/retry-fallback/cooldown.js.map +1 -0
  283. package/dist/core/retry-fallback/log.d.ts +10 -0
  284. package/dist/core/retry-fallback/log.d.ts.map +1 -0
  285. package/dist/core/retry-fallback/log.js +128 -0
  286. package/dist/core/retry-fallback/log.js.map +1 -0
  287. package/dist/core/retry-fallback/validate.d.ts +8 -0
  288. package/dist/core/retry-fallback/validate.d.ts.map +1 -0
  289. package/dist/core/retry-fallback/validate.js +63 -0
  290. package/dist/core/retry-fallback/validate.js.map +1 -0
  291. package/dist/core/sdk.d.ts.map +1 -1
  292. package/dist/core/sdk.js +1 -0
  293. package/dist/core/sdk.js.map +1 -1
  294. package/dist/core/session-manager.d.ts +6 -1
  295. package/dist/core/session-manager.d.ts.map +1 -1
  296. package/dist/core/session-manager.js +19 -3
  297. package/dist/core/session-manager.js.map +1 -1
  298. package/dist/core/settings-manager.d.ts +21 -0
  299. package/dist/core/settings-manager.d.ts.map +1 -1
  300. package/dist/core/settings-manager.js +100 -1
  301. package/dist/core/settings-manager.js.map +1 -1
  302. package/dist/core/tools/bash.d.ts.map +1 -1
  303. package/dist/core/tools/bash.js +20 -5
  304. package/dist/core/tools/bash.js.map +1 -1
  305. package/dist/core/tools/read.js +1 -1
  306. package/dist/core/tools/read.js.map +1 -1
  307. package/dist/extensions/index.d.ts +3 -0
  308. package/dist/extensions/index.d.ts.map +1 -0
  309. package/dist/extensions/index.js +3 -0
  310. package/dist/extensions/index.js.map +1 -0
  311. package/dist/extensions/llama/client.d.ts +61 -0
  312. package/dist/extensions/llama/client.d.ts.map +1 -0
  313. package/dist/extensions/llama/client.js +298 -0
  314. package/dist/extensions/llama/client.js.map +1 -0
  315. package/dist/extensions/llama/huggingface.d.ts +23 -0
  316. package/dist/extensions/llama/huggingface.d.ts.map +1 -0
  317. package/dist/extensions/llama/huggingface.js +139 -0
  318. package/dist/extensions/llama/huggingface.js.map +1 -0
  319. package/dist/extensions/llama/index.d.ts +3 -0
  320. package/dist/extensions/llama/index.d.ts.map +1 -0
  321. package/dist/extensions/llama/index.js +208 -0
  322. package/dist/extensions/llama/index.js.map +1 -0
  323. package/dist/extensions/llama/provider.d.ts +10 -0
  324. package/dist/extensions/llama/provider.d.ts.map +1 -0
  325. package/dist/extensions/llama/provider.js +106 -0
  326. package/dist/extensions/llama/provider.js.map +1 -0
  327. package/dist/extensions/llama/ui.d.ts +42 -0
  328. package/dist/extensions/llama/ui.d.ts.map +1 -0
  329. package/dist/extensions/llama/ui.js +400 -0
  330. package/dist/extensions/llama/ui.js.map +1 -0
  331. package/dist/index.d.ts +2 -2
  332. package/dist/index.d.ts.map +1 -1
  333. package/dist/index.js.map +1 -1
  334. package/dist/main.d.ts.map +1 -1
  335. package/dist/main.js +6 -4
  336. package/dist/main.js.map +1 -1
  337. package/dist/modes/interactive/components/assistant-message.d.ts +6 -7
  338. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  339. package/dist/modes/interactive/components/assistant-message.js +154 -114
  340. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  341. package/dist/modes/interactive/components/footer.d.ts +2 -1
  342. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  343. package/dist/modes/interactive/components/footer.js +25 -4
  344. package/dist/modes/interactive/components/footer.js.map +1 -1
  345. package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
  346. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  347. package/dist/modes/interactive/components/settings-selector.js +20 -0
  348. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  349. package/dist/modes/interactive/interactive-mode.d.ts +7 -0
  350. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  351. package/dist/modes/interactive/interactive-mode.js +165 -13
  352. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  353. package/dist/modes/interactive/streaming-reveal.d.ts +35 -0
  354. package/dist/modes/interactive/streaming-reveal.d.ts.map +1 -0
  355. package/dist/modes/interactive/streaming-reveal.js +268 -0
  356. package/dist/modes/interactive/streaming-reveal.js.map +1 -0
  357. package/dist/modes/interactive/tool-args-reveal.d.ts +20 -0
  358. package/dist/modes/interactive/tool-args-reveal.d.ts.map +1 -0
  359. package/dist/modes/interactive/tool-args-reveal.js +153 -0
  360. package/dist/modes/interactive/tool-args-reveal.js.map +1 -0
  361. package/dist/utils/child-process.d.ts +17 -1
  362. package/dist/utils/child-process.d.ts.map +1 -1
  363. package/dist/utils/child-process.js +41 -1
  364. package/dist/utils/child-process.js.map +1 -1
  365. package/docs/AGENTS.md +70 -0
  366. package/docs/custom-provider.md +28 -0
  367. package/docs/extensions.md +111 -5
  368. package/docs/index.md +1 -0
  369. package/docs/llama-cpp.md +99 -0
  370. package/docs/mcp.md +21 -5
  371. package/docs/neo.md +2 -1
  372. package/docs/prompt-templates.md +1 -0
  373. package/docs/providers.md +7 -0
  374. package/docs/settings.md +35 -0
  375. package/docs/tui.md +41 -26
  376. package/docs/usage.md +1 -0
  377. package/examples/AGENTS.md +3 -0
  378. package/examples/extensions/README.md +1 -1
  379. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +74 -0
  380. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  381. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +59 -19
  382. package/node_modules/@code-yeongyu/senpi-codemode/src/kernels/py/prelude.py +0 -1
  383. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +69 -2
  384. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +6 -0
  385. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  386. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js +95 -12
  387. package/node_modules/@earendil-works/pi-agent-core/dist/agent-loop.js.map +1 -1
  388. package/node_modules/@earendil-works/pi-agent-core/dist/agent.d.ts.map +1 -1
  389. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js +26 -1
  390. package/node_modules/@earendil-works/pi-agent-core/dist/agent.js.map +1 -1
  391. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.d.ts.map +1 -1
  392. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js +24 -2
  393. package/node_modules/@earendil-works/pi-agent-core/dist/harness/agent-harness.js.map +1 -1
  394. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.d.ts +3 -1
  395. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.d.ts.map +1 -1
  396. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.js +4 -2
  397. package/node_modules/@earendil-works/pi-agent-core/dist/proxy.js.map +1 -1
  398. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts +5 -0
  399. package/node_modules/@earendil-works/pi-agent-core/dist/types.d.ts.map +1 -1
  400. package/node_modules/@earendil-works/pi-agent-core/dist/types.js.map +1 -1
  401. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  402. package/node_modules/@earendil-works/pi-ai/README.md +1 -1
  403. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  404. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +92 -29
  405. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  406. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts +2 -1
  407. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  408. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +25 -1
  409. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  410. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.d.ts.map +1 -1
  411. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js +105 -61
  412. package/node_modules/@earendil-works/pi-ai/dist/api/transform-messages.js.map +1 -1
  413. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts +1 -0
  414. package/node_modules/@earendil-works/pi-ai/dist/compat.d.ts.map +1 -1
  415. package/node_modules/@earendil-works/pi-ai/dist/compat.js +1 -0
  416. package/node_modules/@earendil-works/pi-ai/dist/compat.js.map +1 -1
  417. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts +15 -0
  418. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.d.ts.map +1 -1
  419. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js +15 -0
  420. package/node_modules/@earendil-works/pi-ai/dist/image-models.generated.js.map +1 -1
  421. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts +1 -0
  422. package/node_modules/@earendil-works/pi-ai/dist/index.d.ts.map +1 -1
  423. package/node_modules/@earendil-works/pi-ai/dist/index.js +1 -0
  424. package/node_modules/@earendil-works/pi-ai/dist/index.js.map +1 -1
  425. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +4263 -22314
  426. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  427. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts +436 -1988
  428. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  429. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js +2 -1892
  430. package/node_modules/@earendil-works/pi-ai/dist/providers/amazon-bedrock.models.js.map +1 -1
  431. package/node_modules/@earendil-works/pi-ai/dist/providers/ant-ling.models.d.ts +10 -80
  432. package/node_modules/@earendil-works/pi-ai/dist/providers/ant-ling.models.d.ts.map +1 -1
  433. package/node_modules/@earendil-works/pi-ai/dist/providers/ant-ling.models.js +2 -57
  434. package/node_modules/@earendil-works/pi-ai/dist/providers/ant-ling.models.js.map +1 -1
  435. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts +43 -267
  436. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.d.ts.map +1 -1
  437. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js +2 -252
  438. package/node_modules/@earendil-works/pi-ai/dist/providers/anthropic.models.js.map +1 -1
  439. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts +184 -883
  440. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
  441. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js +2 -811
  442. package/node_modules/@earendil-works/pi-ai/dist/providers/azure-openai-responses.models.js.map +1 -1
  443. package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.d.ts +10 -60
  444. package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.d.ts.map +1 -1
  445. package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.js +2 -56
  446. package/node_modules/@earendil-works/pi-ai/dist/providers/cerebras.models.js.map +1 -1
  447. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts +168 -884
  448. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  449. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js +2 -755
  450. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  451. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.models.d.ts +40 -286
  452. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.models.d.ts.map +1 -1
  453. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.models.js +2 -236
  454. package/node_modules/@earendil-works/pi-ai/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
  455. package/node_modules/@earendil-works/pi-ai/dist/providers/data/amazon-bedrock.json +1 -0
  456. package/node_modules/@earendil-works/pi-ai/dist/providers/data/ant-ling.json +1 -0
  457. package/node_modules/@earendil-works/pi-ai/dist/providers/data/anthropic.json +1 -0
  458. package/node_modules/@earendil-works/pi-ai/dist/providers/data/azure-openai-responses.json +1 -0
  459. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cerebras.json +1 -0
  460. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-ai-gateway.json +1 -0
  461. package/node_modules/@earendil-works/pi-ai/dist/providers/data/cloudflare-workers-ai.json +1 -0
  462. package/node_modules/@earendil-works/pi-ai/dist/providers/data/deepseek.json +1 -0
  463. package/node_modules/@earendil-works/pi-ai/dist/providers/data/fireworks.json +1 -0
  464. package/node_modules/@earendil-works/pi-ai/dist/providers/data/github-copilot.json +1 -0
  465. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google-vertex.json +1 -0
  466. package/node_modules/@earendil-works/pi-ai/dist/providers/data/google.json +1 -0
  467. package/node_modules/@earendil-works/pi-ai/dist/providers/data/groq.json +1 -0
  468. package/node_modules/@earendil-works/pi-ai/dist/providers/data/huggingface.json +1 -0
  469. package/node_modules/@earendil-works/pi-ai/dist/providers/data/kimi-coding.json +1 -0
  470. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax-cn.json +1 -0
  471. package/node_modules/@earendil-works/pi-ai/dist/providers/data/minimax.json +1 -0
  472. package/node_modules/@earendil-works/pi-ai/dist/providers/data/mistral.json +1 -0
  473. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai-cn.json +1 -0
  474. package/node_modules/@earendil-works/pi-ai/dist/providers/data/moonshotai.json +1 -0
  475. package/node_modules/@earendil-works/pi-ai/dist/providers/data/nvidia.json +1 -0
  476. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai-codex.json +1 -0
  477. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openai.json +1 -0
  478. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode-go.json +1 -0
  479. package/node_modules/@earendil-works/pi-ai/dist/providers/data/opencode.json +1 -0
  480. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -0
  481. package/node_modules/@earendil-works/pi-ai/dist/providers/data/together.json +1 -0
  482. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -0
  483. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xai.json +1 -0
  484. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi-token-plan-ams.json +1 -0
  485. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi-token-plan-cn.json +1 -0
  486. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi-token-plan-sgp.json +1 -0
  487. package/node_modules/@earendil-works/pi-ai/dist/providers/data/xiaomi.json +1 -0
  488. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -0
  489. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -0
  490. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.d.ts +7 -58
  491. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.d.ts.map +1 -1
  492. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.js +2 -40
  493. package/node_modules/@earendil-works/pi-ai/dist/providers/deepseek.models.js.map +1 -1
  494. package/node_modules/@earendil-works/pi-ai/dist/providers/faux.d.ts +1 -0
  495. package/node_modules/@earendil-works/pi-ai/dist/providers/faux.d.ts.map +1 -1
  496. package/node_modules/@earendil-works/pi-ai/dist/providers/faux.js +1 -0
  497. package/node_modules/@earendil-works/pi-ai/dist/providers/faux.js.map +1 -1
  498. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts +49 -362
  499. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.d.ts.map +1 -1
  500. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js +2 -292
  501. package/node_modules/@earendil-works/pi-ai/dist/providers/fireworks.models.js.map +1 -1
  502. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts +85 -760
  503. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.d.ts.map +1 -1
  504. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js +2 -538
  505. package/node_modules/@earendil-works/pi-ai/dist/providers/github-copilot.models.js.map +1 -1
  506. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.models.d.ts +31 -189
  507. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.models.d.ts.map +1 -1
  508. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.models.js +2 -179
  509. package/node_modules/@earendil-works/pi-ai/dist/providers/google-vertex.models.js.map +1 -1
  510. package/node_modules/@earendil-works/pi-ai/dist/providers/google.models.d.ts +49 -309
  511. package/node_modules/@earendil-works/pi-ai/dist/providers/google.models.d.ts.map +1 -1
  512. package/node_modules/@earendil-works/pi-ai/dist/providers/google.models.js +2 -285
  513. package/node_modules/@earendil-works/pi-ai/dist/providers/google.models.js.map +1 -1
  514. package/node_modules/@earendil-works/pi-ai/dist/providers/groq.models.d.ts +22 -118
  515. package/node_modules/@earendil-works/pi-ai/dist/providers/groq.models.d.ts.map +1 -1
  516. package/node_modules/@earendil-works/pi-ai/dist/providers/groq.models.js +2 -122
  517. package/node_modules/@earendil-works/pi-ai/dist/providers/groq.models.js.map +1 -1
  518. package/node_modules/@earendil-works/pi-ai/dist/providers/huggingface.models.d.ts +196 -979
  519. package/node_modules/@earendil-works/pi-ai/dist/providers/huggingface.models.d.ts.map +1 -1
  520. package/node_modules/@earendil-works/pi-ai/dist/providers/huggingface.models.js +2 -884
  521. package/node_modules/@earendil-works/pi-ai/dist/providers/huggingface.models.js.map +1 -1
  522. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts +13 -122
  523. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts.map +1 -1
  524. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js +2 -98
  525. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js.map +1 -1
  526. package/node_modules/@earendil-works/pi-ai/dist/providers/minimax-cn.models.d.ts +10 -48
  527. package/node_modules/@earendil-works/pi-ai/dist/providers/minimax-cn.models.d.ts.map +1 -1
  528. package/node_modules/@earendil-works/pi-ai/dist/providers/minimax-cn.models.js +2 -53
  529. package/node_modules/@earendil-works/pi-ai/dist/providers/minimax-cn.models.js.map +1 -1
  530. package/node_modules/@earendil-works/pi-ai/dist/providers/minimax.models.d.ts +10 -48
  531. package/node_modules/@earendil-works/pi-ai/dist/providers/minimax.models.d.ts.map +1 -1
  532. package/node_modules/@earendil-works/pi-ai/dist/providers/minimax.models.js +2 -53
  533. package/node_modules/@earendil-works/pi-ai/dist/providers/minimax.models.js.map +1 -1
  534. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.d.ts +91 -480
  535. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.d.ts.map +1 -1
  536. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.js +2 -512
  537. package/node_modules/@earendil-works/pi-ai/dist/providers/mistral.models.js.map +1 -1
  538. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.d.ts +31 -257
  539. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
  540. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js +2 -185
  541. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js.map +1 -1
  542. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.d.ts +31 -257
  543. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.d.ts.map +1 -1
  544. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js +2 -185
  545. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js.map +1 -1
  546. package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.d.ts +58 -541
  547. package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.d.ts.map +1 -1
  548. package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.js +2 -382
  549. package/node_modules/@earendil-works/pi-ai/dist/providers/nvidia.models.js.map +1 -1
  550. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts +22 -196
  551. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.d.ts.map +1 -1
  552. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js +2 -139
  553. package/node_modules/@earendil-works/pi-ai/dist/providers/openai-codex.models.js.map +1 -1
  554. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts +184 -954
  555. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.d.ts.map +1 -1
  556. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js +2 -825
  557. package/node_modules/@earendil-works/pi-ai/dist/providers/openai.models.js.map +1 -1
  558. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.d.ts +1 -1
  559. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.d.ts.map +1 -1
  560. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.js +2 -0
  561. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.js.map +1 -1
  562. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts +46 -335
  563. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts.map +1 -1
  564. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js +2 -273
  565. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js.map +1 -1
  566. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts +163 -1185
  567. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.d.ts.map +1 -1
  568. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js +2 -996
  569. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode.models.js.map +1 -1
  570. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +1076 -5750
  571. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
  572. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +2 -4910
  573. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  574. package/node_modules/@earendil-works/pi-ai/dist/providers/together.models.d.ts +49 -579
  575. package/node_modules/@earendil-works/pi-ai/dist/providers/together.models.d.ts.map +1 -1
  576. package/node_modules/@earendil-works/pi-ai/dist/providers/together.models.js +2 -377
  577. package/node_modules/@earendil-works/pi-ai/dist/providers/together.models.js.map +1 -1
  578. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts +752 -3336
  579. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  580. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js +2 -3263
  581. package/node_modules/@earendil-works/pi-ai/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  582. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts +10 -65
  583. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts.map +1 -1
  584. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js +2 -57
  585. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js.map +1 -1
  586. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.d.ts +10 -63
  587. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
  588. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.js +2 -56
  589. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
  590. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.d.ts +10 -63
  591. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
  592. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.js +2 -56
  593. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
  594. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.d.ts +10 -63
  595. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
  596. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.js +2 -56
  597. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
  598. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi.models.d.ts +19 -126
  599. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi.models.d.ts.map +1 -1
  600. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi.models.js +2 -110
  601. package/node_modules/@earendil-works/pi-ai/dist/providers/xiaomi.models.js.map +1 -1
  602. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.d.ts +19 -144
  603. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
  604. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.js +2 -111
  605. package/node_modules/@earendil-works/pi-ai/dist/providers/zai-coding-cn.models.js.map +1 -1
  606. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.d.ts +19 -144
  607. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.d.ts.map +1 -1
  608. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.js +2 -111
  609. package/node_modules/@earendil-works/pi-ai/dist/providers/zai.models.js.map +1 -1
  610. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.d.ts.map +1 -1
  611. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.js +12 -0
  612. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/context-transformer.js.map +1 -1
  613. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts +1 -1
  614. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.d.ts.map +1 -1
  615. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js +4 -2
  616. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/index.js.map +1 -1
  617. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.d.ts +1 -0
  618. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.d.ts.map +1 -1
  619. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.js +1 -1
  620. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/coerce-parameters.js.map +1 -1
  621. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.d.ts +1 -0
  622. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.d.ts.map +1 -1
  623. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.js +1 -1
  624. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/format.js.map +1 -1
  625. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-protocol.d.ts +19 -0
  626. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-protocol.d.ts.map +1 -0
  627. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-protocol.js +8 -0
  628. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-protocol.js.map +1 -0
  629. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.d.ts +11 -0
  630. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.d.ts.map +1 -1
  631. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.js +40 -1
  632. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/invoke-tag-scanner.js.map +1 -1
  633. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.d.ts +2 -0
  634. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.d.ts.map +1 -1
  635. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.js +7 -4
  636. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/parse.js.map +1 -1
  637. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.d.ts +2 -0
  638. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.d.ts.map +1 -1
  639. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.js +104 -15
  640. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/anthropic-xml/stream.js.map +1 -1
  641. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/coerce-parameters.d.ts +15 -0
  642. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/coerce-parameters.d.ts.map +1 -0
  643. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/coerce-parameters.js +198 -0
  644. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/coerce-parameters.js.map +1 -0
  645. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/config.d.ts +3 -0
  646. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/config.d.ts.map +1 -0
  647. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/config.js +8 -0
  648. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/config.js.map +1 -0
  649. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/format.d.ts +6 -0
  650. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/format.d.ts.map +1 -0
  651. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/format.js +33 -0
  652. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/format.js.map +1 -0
  653. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/index.d.ts +6 -0
  654. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/index.d.ts.map +1 -0
  655. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/index.js +6 -0
  656. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/index.js.map +1 -0
  657. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/parse.d.ts +4 -0
  658. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/parse.d.ts.map +1 -0
  659. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/parse.js +6 -0
  660. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/parse.js.map +1 -0
  661. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/repair.d.ts +12 -0
  662. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/repair.d.ts.map +1 -0
  663. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/repair.js +46 -0
  664. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/repair.js.map +1 -0
  665. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/stream.d.ts +4 -0
  666. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/stream.d.ts.map +1 -0
  667. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/stream.js +6 -0
  668. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/antml/stream.js.map +1 -0
  669. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/gemma4.d.ts +8 -1
  670. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/gemma4.d.ts.map +1 -1
  671. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/gemma4.js +129 -27
  672. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/gemma4.js.map +1 -1
  673. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/json-mix.d.ts.map +1 -1
  674. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/json-mix.js +140 -6
  675. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/json-mix.js.map +1 -1
  676. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/morph-xml.d.ts.map +1 -1
  677. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/morph-xml.js +28 -6
  678. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/morph-xml.js.map +1 -1
  679. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/yaml-xml.d.ts.map +1 -1
  680. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/yaml-xml.js +51 -18
  681. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/protocols/yaml-xml.js.map +1 -1
  682. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/stream-wrapper.d.ts.map +1 -1
  683. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/stream-wrapper.js +70 -9
  684. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/stream-wrapper.js.map +1 -1
  685. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.d.ts +6 -2
  686. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.d.ts.map +1 -1
  687. package/node_modules/@earendil-works/pi-ai/dist/tool-call-middleware/types.js.map +1 -1
  688. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +31 -3
  689. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  690. package/node_modules/@earendil-works/pi-ai/dist/types.js +4 -1
  691. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  692. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.d.ts.map +1 -1
  693. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js +6 -1
  694. package/node_modules/@earendil-works/pi-ai/dist/utils/retry.js.map +1 -1
  695. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts +4 -0
  696. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.d.ts.map +1 -0
  697. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js +6 -0
  698. package/node_modules/@earendil-works/pi-ai/dist/utils/stop-details.js.map +1 -0
  699. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-pair-repair.d.ts.map +1 -1
  700. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-pair-repair.js +19 -2
  701. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-pair-repair.js.map +1 -1
  702. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts +19 -0
  703. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts.map +1 -0
  704. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js +215 -0
  705. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js.map +1 -0
  706. package/node_modules/@earendil-works/pi-ai/package.json +2 -2
  707. package/node_modules/@earendil-works/pi-pty/dist/registry-session.d.ts +1 -1
  708. package/node_modules/@earendil-works/pi-pty/dist/registry-session.d.ts.map +1 -1
  709. package/node_modules/@earendil-works/pi-pty/dist/registry-session.js +25 -6
  710. package/node_modules/@earendil-works/pi-pty/dist/registry-session.js.map +1 -1
  711. package/node_modules/@earendil-works/pi-pty/dist/registry-types.d.ts +6 -0
  712. package/node_modules/@earendil-works/pi-pty/dist/registry-types.d.ts.map +1 -1
  713. package/node_modules/@earendil-works/pi-pty/dist/registry-types.js.map +1 -1
  714. package/node_modules/@earendil-works/pi-pty/dist/registry.d.ts +1 -0
  715. package/node_modules/@earendil-works/pi-pty/dist/registry.d.ts.map +1 -1
  716. package/node_modules/@earendil-works/pi-pty/dist/registry.js +9 -1
  717. package/node_modules/@earendil-works/pi-pty/dist/registry.js.map +1 -1
  718. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  719. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts +1 -1
  720. package/node_modules/@earendil-works/pi-tui/dist/index.d.ts.map +1 -1
  721. package/node_modules/@earendil-works/pi-tui/dist/index.js +1 -1
  722. package/node_modules/@earendil-works/pi-tui/dist/index.js.map +1 -1
  723. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +6 -1
  724. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  725. package/node_modules/@earendil-works/pi-tui/dist/tui.js +14 -2
  726. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  727. package/node_modules/@earendil-works/pi-tui/dist/utils.js +1 -1
  728. package/node_modules/@earendil-works/pi-tui/dist/utils.js.map +1 -1
  729. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  730. package/package.json +6 -6
  731. package/dist/core/extensions/builtin/todotools/tools/todoread.d.ts +0 -4
  732. package/dist/core/extensions/builtin/todotools/tools/todoread.d.ts.map +0 -1
  733. package/dist/core/extensions/builtin/todotools/tools/todoread.js +0 -37
  734. package/dist/core/extensions/builtin/todotools/tools/todoread.js.map +0 -1
  735. package/dist/core/extensions/builtin/todotools/tools/todowrite.d.ts +0 -10
  736. package/dist/core/extensions/builtin/todotools/tools/todowrite.d.ts.map +0 -1
  737. package/dist/core/extensions/builtin/todotools/tools/todowrite.js +0 -95
  738. package/dist/core/extensions/builtin/todotools/tools/todowrite.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"speculative.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/speculative.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype AssistantMessage,\n\tisContextOverflow,\n\ttype Message,\n\ttype Model,\n\ttype TextContent,\n} from \"@earendil-works/pi-ai\";\nimport { stream } from \"@earendil-works/pi-ai/compat\";\nimport {\n\ttype CompactionPreparation,\n\ttype CompactionResult,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateContextTokens,\n\testimateTokens,\n\tprepareCompaction,\n\tserializeConversation,\n} from \"../../../compaction/index.ts\";\nimport { convertToLlm } from \"../../../messages.ts\";\nimport type { ModelRegistry } from \"../../../model-registry.ts\";\nimport type { ReadonlySessionManager } from \"../../../session-manager.ts\";\nimport type { ApplyCompactionResult, ContextUsage } from \"../../types.ts\";\nimport { computeEffectiveKeepRecentTokens, computeEffectiveThreshold } from \"./policy.ts\";\nimport { buildPrompt, type MergedCompactionPromptVariant } from \"./prompts.ts\";\nimport * as truncation from \"./tool-truncation.ts\";\n\nconst DEFAULT_CONTEXT_WINDOW = 200_000;\nconst COMPACTION_BUDGET_RATIO = 0.6;\nconst EMERGENCY_CONTEXT_TARGET_RATIO = 0.95;\nconst MAX_SUMMARY_TOKENS = 8192;\nconst SUMMARY_SCHEMA = \"senpi.compaction.summary.v1\";\ntype CompactionProgressCallback = (delta: string) => void;\ntype PruneStep = { messages: AgentMessage[]; removedTokens: number };\n\nexport interface SpeculativeCompactionContext {\n\tmodel: Model<any> | undefined;\n\tsessionManager: ReadonlySessionManager;\n\tmodelRegistry?: ModelRegistry;\n\tgetContextUsage(): ContextUsage | undefined;\n\tgetCompactionSettings?(): CompactionPreparation[\"settings\"];\n\tgetMessageRevision(): number;\n\tapplyCompaction(\n\t\tprecomputed: CompactionResult,\n\t\toptions: { reason: \"extension\"; expectedRevision: number },\n\t): Promise<ApplyCompactionResult>;\n}\n\nexport interface SpeculativeCompactionSnapshot {\n\tgeneration: number;\n\texpectedRevision: number;\n\tmodel: Model<any>;\n\tcontextWindow: number;\n\tpreparation: CompactionPreparation;\n\tpromptVariant: MergedCompactionPromptVariant;\n\tcustomInstructions?: string;\n}\n\nexport type SpeculativeCompactionResult = ApplyCompactionResult | { applied: false; reason: \"unavailable\" };\n\nfunction approxTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\nfunction getSummaryText(message: Message): string {\n\tconst content = Array.isArray(message.content)\n\t\t? message.content\n\t\t: [{ type: \"text\" as const, text: message.content }];\n\treturn content\n\t\t.filter((content): content is TextContent => content.type === \"text\")\n\t\t.map((content) => content.text)\n\t\t.join(\"\\n\")\n\t\t.trim();\n}\n\nfunction isAssistantMessage(message: Message): message is AssistantMessage {\n\treturn message.role === \"assistant\" && \"stopReason\" in message;\n}\n\nasync function generateSummaryMessage(options: {\n\tmessages: AgentMessage[];\n\tonProgress?: CompactionProgressCallback;\n\tprompt: ReturnType<typeof buildPrompt>;\n\tsignal?: AbortSignal;\n\tsnapshot: SpeculativeCompactionSnapshot;\n\tauth: {\n\t\tapiKey: string;\n\t\theaders?: Record<string, string>;\n\t\textraBody?: Record<string, unknown>;\n\t};\n}): Promise<Message | undefined> {\n\tconst conversationText = serializeConversation(convertToLlm(options.messages));\n\tconst responseStream = stream(\n\t\toptions.snapshot.model,\n\t\t{\n\t\t\tsystemPrompt: options.prompt.system,\n\t\t\tmessages: [\n\t\t\t\t{\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: \"text\",\n\t\t\t\t\t\t\ttext: `${options.prompt.user}\\n\\n<conversation>\\n${conversationText}\\n</conversation>`,\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\t{\n\t\t\tapiKey: options.auth.apiKey,\n\t\t\theaders: options.auth.headers,\n\t\t\textraBody: options.auth.extraBody,\n\t\t\tmaxTokens: MAX_SUMMARY_TOKENS,\n\t\t\tsignal: options.signal,\n\t\t},\n\t);\n\tfor await (const event of responseStream) {\n\t\tif (event.type === \"text_delta\" && event.delta) {\n\t\t\toptions.onProgress?.(event.delta);\n\t\t}\n\t}\n\treturn await responseStream.result();\n}\n\nfunction pruneToolResults(messages: AgentMessage[], contextWindow: number): AgentMessage[] {\n\tconst toolResults = messages\n\t\t.filter((message) => message.role === \"toolResult\")\n\t\t.map((message) => ({ content: message.content, details: undefined }));\n\tif (toolResults.length === 0) return messages;\n\n\tconst prunedResults = truncation.prePruneToolOutputsToBudget(toolResults, contextWindow * COMPACTION_BUDGET_RATIO);\n\tlet resultIndex = 0;\n\treturn messages.map((message) => {\n\t\tif (message.role !== \"toolResult\") return message;\n\t\tconst pruned = prunedResults[resultIndex];\n\t\tresultIndex++;\n\t\treturn pruned ? { ...message, content: pruned.content } : message;\n\t});\n}\n\nexport function truncateContextMessages(messages: AgentMessage[]): AgentMessage[] {\n\tconst toolResults = messages\n\t\t.filter((message) => message.role === \"toolResult\")\n\t\t.map((message) => ({ content: message.content, details: undefined }));\n\tif (toolResults.length === 0) return messages;\n\n\tconst truncatedResults = truncation.truncateOversizedToolResults(toolResults);\n\tlet resultIndex = 0;\n\treturn messages.map((message) => {\n\t\tif (message.role !== \"toolResult\") return message;\n\t\tconst truncated = truncatedResults[resultIndex];\n\t\tresultIndex++;\n\t\treturn truncated ? { ...message, content: truncated.content } : message;\n\t});\n}\n\nfunction getToolCallIds(message: AgentMessage): Set<string> {\n\tconst ids = new Set<string>();\n\tif (message.role !== \"assistant\") return ids;\n\tfor (const block of message.content) {\n\t\tif (block.type === \"toolCall\") ids.add(block.id);\n\t}\n\treturn ids;\n}\n\nfunction findLastUserLikeIndex(messages: AgentMessage[]): number {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst role = messages[index]?.role;\n\t\tif (role === \"user\" || role === \"bashExecution\") return index;\n\t}\n\treturn messages.length;\n}\n\nfunction removeAssistantToolPair(messages: AgentMessage[], assistantIndex: number): PruneStep {\n\tconst ids = getToolCallIds(messages[assistantIndex]);\n\tlet removedTokens = 0;\n\tconst pruned = messages.filter((message, index) => {\n\t\tconst remove = index === assistantIndex || (message.role === \"toolResult\" && ids.has(message.toolCallId));\n\t\tif (remove) removedTokens += estimateTokens(message);\n\t\treturn !remove;\n\t});\n\treturn { messages: pruned, removedTokens };\n}\n\nfunction removeFirstOldToolPair(messages: AgentMessage[], boundaryIndex: number): PruneStep | undefined {\n\tfor (let index = 0; index < boundaryIndex; index++) {\n\t\tconst message = messages[index];\n\t\tif (!message) continue;\n\t\tif (message.role === \"assistant\" && getToolCallIds(message).size > 0)\n\t\t\treturn removeAssistantToolPair(messages, index);\n\t\tif (message.role === \"toolResult\") {\n\t\t\treturn {\n\t\t\t\tmessages: messages.filter((_message, candidateIndex) => candidateIndex !== index),\n\t\t\t\tremovedTokens: estimateTokens(message),\n\t\t\t};\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction removeFirstOldMessage(messages: AgentMessage[], boundaryIndex: number): PruneStep | undefined {\n\tfor (let index = 0; index < boundaryIndex; index++) {\n\t\tconst message = messages[index];\n\t\tif (!message || message.role === \"toolResult\") continue;\n\t\tif (message.role === \"assistant\" && getToolCallIds(message).size > 0)\n\t\t\treturn removeAssistantToolPair(messages, index);\n\t\treturn {\n\t\t\tmessages: messages.filter((_candidate, candidateIndex) => candidateIndex !== index),\n\t\t\tremovedTokens: estimateTokens(message),\n\t\t};\n\t}\n\treturn undefined;\n}\n\nfunction pruneOldMessagesToBudget(messages: AgentMessage[], targetTokens: number): AgentMessage[] {\n\tlet pruned = messages;\n\tlet total = estimateTotalTokens(pruned);\n\twhile (total > targetTokens) {\n\t\tconst boundaryIndex = findLastUserLikeIndex(pruned);\n\t\tconst next = removeFirstOldToolPair(pruned, boundaryIndex) ?? removeFirstOldMessage(pruned, boundaryIndex);\n\t\tif (!next || next.messages.length === pruned.length) break;\n\t\tpruned = next.messages;\n\t\ttotal -= next.removedTokens;\n\t}\n\treturn pruned;\n}\n\nfunction removeOldestHistoryItemForOverflowRetry(messages: AgentMessage[]): AgentMessage[] | undefined {\n\tif (messages.length <= 1) return undefined;\n\tconst boundaryIndex = findLastUserLikeIndex(messages);\n\treturn (\n\t\tremoveFirstOldToolPair(messages, boundaryIndex)?.messages ??\n\t\tremoveFirstOldMessage(messages, boundaryIndex)?.messages ??\n\t\t(messages.length > 1 ? messages.slice(1) : undefined)\n\t);\n}\n\nfunction estimateTotalTokens(messages: AgentMessage[]): number {\n\tlet total = 0;\n\tfor (const message of messages) total += estimateTokens(message);\n\treturn total;\n}\n\nexport function hardLimitEmergencyPrune(\n\tmessages: AgentMessage[],\n\tcontextWindow: number,\n): {\n\tmessages: AgentMessage[];\n\tneedsAggressiveCompaction: boolean;\n} {\n\tconst targetTokens = Math.floor(contextWindow * EMERGENCY_CONTEXT_TARGET_RATIO);\n\tif (estimateTotalTokens(messages) <= targetTokens) {\n\t\treturn { messages, needsAggressiveCompaction: false };\n\t}\n\tconst noLlmPruned = truncateContextMessages(pruneToolResults(messages, contextWindow));\n\tif (estimateTotalTokens(noLlmPruned) <= targetTokens) {\n\t\treturn { messages: noLlmPruned, needsAggressiveCompaction: false };\n\t}\n\treturn {\n\t\tmessages: pruneOldMessagesToBudget(noLlmPruned, targetTokens),\n\t\tneedsAggressiveCompaction: true,\n\t};\n}\n\nexport function getPromptVariant(options: {\n\treason: string;\n\tpreparation: { previousSummary?: string; isSplitTurn: boolean };\n}): MergedCompactionPromptVariant {\n\tif (options.reason === \"branch\") return \"branch\";\n\tif (options.preparation.previousSummary) return \"update\";\n\tif (options.preparation.isSplitTurn) return \"turn_prefix\";\n\treturn \"default\";\n}\n\nexport function createSpeculativeCompactionSnapshot(\n\tcontext: SpeculativeCompactionContext,\n\toptions: { customInstructions?: string; generation: number },\n): SpeculativeCompactionSnapshot | undefined {\n\tconst model = context.model;\n\tif (!model) return undefined;\n\n\tconst expectedRevision = context.getMessageRevision();\n\tconst branchEntries = context.sessionManager.getBranch();\n\tconst contextWindow = context.getContextUsage()?.contextWindow ?? model.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n\tconst settings = context.getCompactionSettings?.() ?? DEFAULT_COMPACTION_SETTINGS;\n\tconst thresholdRatio = computeEffectiveThreshold(contextWindow);\n\tconst preparation = prepareCompaction(branchEntries, {\n\t\t...settings,\n\t\tkeepRecentTokens: computeEffectiveKeepRecentTokens(settings.keepRecentTokens, contextWindow, thresholdRatio),\n\t});\n\tif (!preparation) return undefined;\n\n\treturn {\n\t\tgeneration: options.generation,\n\t\texpectedRevision,\n\t\tmodel,\n\t\tcontextWindow,\n\t\tpreparation,\n\t\tpromptVariant: getPromptVariant({ reason: \"extension\", preparation }),\n\t\tcustomInstructions: options.customInstructions,\n\t};\n}\n\nexport async function runExtensionCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot,\n\tsignal?: AbortSignal,\n\tonProgress?: CompactionProgressCallback,\n): Promise<CompactionResult | undefined> {\n\tconst auth = await context.modelRegistry?.getApiKeyAndHeaders(snapshot.model);\n\tif (!auth?.ok || !auth.apiKey) return undefined;\n\n\tlet messages = pruneToolResults(\n\t\t[...snapshot.preparation.messagesToSummarize, ...snapshot.preparation.turnPrefixMessages],\n\t\tsnapshot.contextWindow,\n\t);\n\tconst prompt = buildPrompt({\n\t\tvariant: snapshot.promptVariant,\n\t\tpreviousSummary: snapshot.preparation.previousSummary,\n\t\tcustomInstructions: snapshot.customInstructions,\n\t});\n\n\twhile (true) {\n\t\tconst response = await generateSummaryMessage({\n\t\t\tmessages,\n\t\t\tonProgress,\n\t\t\tprompt,\n\t\t\tsignal,\n\t\t\tsnapshot,\n\t\t\tauth: {\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\theaders: auth.headers,\n\t\t\t\textraBody: auth.extraBody,\n\t\t\t},\n\t\t});\n\t\tif (!response) return undefined;\n\n\t\tif (isAssistantMessage(response) && isContextOverflow(response, snapshot.contextWindow)) {\n\t\t\tconst retryMessages = removeOldestHistoryItemForOverflowRetry(messages);\n\t\t\tif (!retryMessages || retryMessages.length === messages.length) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmessages = retryMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst summary = getSummaryText(response);\n\t\tif (!summary) return undefined;\n\n\t\tconst tokenEstimate = estimateContextTokens(convertToLlm(messages)).tokens + approxTokens(summary);\n\t\tif (tokenEstimate > snapshot.contextWindow * COMPACTION_BUDGET_RATIO) return undefined;\n\n\t\treturn {\n\t\t\tsummary,\n\t\t\tfirstKeptEntryId: snapshot.preparation.firstKeptEntryId,\n\t\t\ttokensBefore: snapshot.preparation.tokensBefore,\n\t\t\tdetails: { schema: SUMMARY_SCHEMA, promptVariant: snapshot.promptVariant, tokenEstimate },\n\t\t};\n\t}\n\n\tthrow new Error(\"Compaction summary request exceeded the context window after retrying with a smaller input\");\n}\n\nexport async function applyGeneratedCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot | undefined,\n\tgetCurrentGeneration: () => number,\n\tcompaction: CompactionResult | undefined,\n): Promise<SpeculativeCompactionResult> {\n\tif (!snapshot || !compaction) return { applied: false, reason: \"unavailable\" };\n\n\tif (snapshot.generation !== getCurrentGeneration() || snapshot.expectedRevision !== context.getMessageRevision()) {\n\t\treturn { applied: false, reason: \"stale\" };\n\t}\n\n\treturn await context.applyCompaction(compaction, {\n\t\treason: \"extension\",\n\t\texpectedRevision: snapshot.expectedRevision,\n\t});\n}\n\nexport async function applySpeculativeCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot | undefined,\n\tgetCurrentGeneration: () => number,\n\tgenerate: () => Promise<CompactionResult | undefined>,\n): Promise<SpeculativeCompactionResult> {\n\tif (!snapshot) return { applied: false, reason: \"unavailable\" };\n\n\tconst compaction = await generate();\n\treturn await applyGeneratedCompaction(context, snapshot, getCurrentGeneration, compaction);\n}\n"]}
1
+ {"version":3,"file":"speculative.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/speculative.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport {\n\ttype AssistantMessage,\n\tisContextOverflow,\n\ttype Message,\n\ttype Model,\n\ttype TextContent,\n\ttype Tool,\n} from \"@earendil-works/pi-ai\";\nimport { stream } from \"@earendil-works/pi-ai/compat\";\nimport {\n\ttype CompactionPreparation,\n\ttype CompactionResult,\n\tDEFAULT_COMPACTION_SETTINGS,\n\testimateContextTokens,\n\testimateTokens,\n\tprepareCompaction,\n} from \"../../../compaction/index.ts\";\nimport { convertToLlm } from \"../../../messages.ts\";\nimport type { ModelRegistry } from \"../../../model-registry.ts\";\nimport type { ReadonlySessionManager } from \"../../../session-manager.ts\";\nimport type { ApplyCompactionResult, ContextUsage } from \"../../types.ts\";\nimport { computeEffectiveKeepRecentTokens, computeEffectiveThreshold } from \"./policy.ts\";\nimport { buildPrompt, type MergedCompactionPromptVariant } from \"./prompts.ts\";\nimport { repairOrphanedToolResults } from \"./repair-tool-pairs.ts\";\nimport * as truncation from \"./tool-truncation.ts\";\n\nconst DEFAULT_CONTEXT_WINDOW = 200_000;\nconst COMPACTION_BUDGET_RATIO = 0.6;\nconst EMERGENCY_CONTEXT_TARGET_RATIO = 0.95;\nconst MAX_SUMMARY_TOKENS = 8192;\nconst SUMMARY_SCHEMA = \"senpi.compaction.summary.v1\";\ntype CompactionProgressCallback = (delta: string) => void;\ntype PruneStep = { messages: AgentMessage[]; removedTokens: number };\n\nexport interface SpeculativeCompactionContext {\n\tmodel: Model<any> | undefined;\n\tsessionManager: ReadonlySessionManager;\n\tmodelRegistry?: ModelRegistry;\n\tgetContextUsage(): ContextUsage | undefined;\n\tgetCompactionSettings?(): CompactionPreparation[\"settings\"];\n\tgetMessageRevision(): number;\n\tgetSystemPrompt?(): string;\n\tapplyCompaction(\n\t\tprecomputed: CompactionResult,\n\t\toptions: { reason: \"extension\"; expectedRevision: number },\n\t): Promise<ApplyCompactionResult>;\n}\n\nexport interface SpeculativeCompactionSnapshot {\n\tgeneration: number;\n\texpectedRevision: number;\n\tmodel: Model<any>;\n\tcontextWindow: number;\n\tpreparation: CompactionPreparation;\n\tpromptVariant: MergedCompactionPromptVariant;\n\tcustomInstructions?: string;\n\t/** Agent system prompt; used to make the summarization request look like normal agent traffic. */\n\tsystemPrompt?: string;\n\t/** Agent tool definitions; forwarded so the request shape matches normal agent traffic. */\n\ttools?: Tool[];\n}\n\nexport type SpeculativeCompactionResult = ApplyCompactionResult | { applied: false; reason: \"unavailable\" };\n\nfunction approxTokens(text: string): number {\n\treturn Math.ceil(text.length / 4);\n}\n\nfunction getSummaryText(message: Message): string {\n\tconst content = Array.isArray(message.content)\n\t\t? message.content\n\t\t: [{ type: \"text\" as const, text: message.content }];\n\treturn content\n\t\t.filter((content): content is TextContent => content.type === \"text\")\n\t\t.map((content) => content.text)\n\t\t.join(\"\\n\")\n\t\t.trim();\n}\n\nfunction isAssistantMessage(message: Message): message is AssistantMessage {\n\treturn message.role === \"assistant\" && \"stopReason\" in message;\n}\n\nasync function generateSummaryMessage(options: {\n\tmessages: AgentMessage[];\n\tonProgress?: CompactionProgressCallback;\n\tprompt: ReturnType<typeof buildPrompt>;\n\tsignal?: AbortSignal;\n\tsnapshot: SpeculativeCompactionSnapshot;\n\tauth: {\n\t\tapiKey: string;\n\t\theaders?: Record<string, string>;\n\t\textraBody?: Record<string, unknown>;\n\t};\n}): Promise<Message | undefined> {\n\t// Send the conversation as native LLM messages with the summarization\n\t// instruction as a trailing user message, mirroring normal agent traffic.\n\t// A single serialized `<conversation>` text dump of a large session is\n\t// deterministically refused by Anthropic's anti-distillation classifier\n\t// (\"reverse engineering or duplicating model outputs\"), while the same\n\t// content as native blocks with the agent's system prompt and tools passes.\n\tconst conversationMessages = repairOrphanedToolResults(convertToLlm(options.messages));\n\tconst responseStream = stream(\n\t\toptions.snapshot.model,\n\t\t{\n\t\t\tsystemPrompt: options.snapshot.systemPrompt ?? options.prompt.system,\n\t\t\tmessages: [\n\t\t\t\t...conversationMessages,\n\t\t\t\t{\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [{ type: \"text\", text: options.prompt.user }],\n\t\t\t\t\ttimestamp: Date.now(),\n\t\t\t\t},\n\t\t\t],\n\t\t\t...(options.snapshot.tools && options.snapshot.tools.length > 0 ? { tools: options.snapshot.tools } : {}),\n\t\t},\n\t\t{\n\t\t\tapiKey: options.auth.apiKey,\n\t\t\theaders: options.auth.headers,\n\t\t\textraBody: options.auth.extraBody,\n\t\t\tmaxTokens: MAX_SUMMARY_TOKENS,\n\t\t\tsignal: options.signal,\n\t\t},\n\t);\n\tfor await (const event of responseStream) {\n\t\tif (event.type === \"text_delta\" && event.delta) {\n\t\t\toptions.onProgress?.(event.delta);\n\t\t}\n\t}\n\treturn await responseStream.result();\n}\n\nfunction pruneToolResults(messages: AgentMessage[], contextWindow: number): AgentMessage[] {\n\tconst toolResults = messages\n\t\t.filter((message) => message.role === \"toolResult\")\n\t\t.map((message) => ({ content: message.content, details: undefined }));\n\tif (toolResults.length === 0) return messages;\n\n\tconst prunedResults = truncation.prePruneToolOutputsToBudget(toolResults, contextWindow * COMPACTION_BUDGET_RATIO);\n\tlet resultIndex = 0;\n\treturn messages.map((message) => {\n\t\tif (message.role !== \"toolResult\") return message;\n\t\tconst pruned = prunedResults[resultIndex];\n\t\tresultIndex++;\n\t\treturn pruned ? { ...message, content: pruned.content } : message;\n\t});\n}\n\nexport function truncateContextMessages(messages: AgentMessage[]): AgentMessage[] {\n\tconst toolResults = messages\n\t\t.filter((message) => message.role === \"toolResult\")\n\t\t.map((message) => ({ content: message.content, details: undefined }));\n\tif (toolResults.length === 0) return messages;\n\n\tconst truncatedResults = truncation.truncateOversizedToolResults(toolResults);\n\tlet resultIndex = 0;\n\treturn messages.map((message) => {\n\t\tif (message.role !== \"toolResult\") return message;\n\t\tconst truncated = truncatedResults[resultIndex];\n\t\tresultIndex++;\n\t\treturn truncated ? { ...message, content: truncated.content } : message;\n\t});\n}\n\nfunction getToolCallIds(message: AgentMessage): Set<string> {\n\tconst ids = new Set<string>();\n\tif (message.role !== \"assistant\") return ids;\n\tfor (const block of message.content) {\n\t\tif (block.type === \"toolCall\") ids.add(block.id);\n\t}\n\treturn ids;\n}\n\nfunction findLastUserLikeIndex(messages: AgentMessage[]): number {\n\tfor (let index = messages.length - 1; index >= 0; index--) {\n\t\tconst role = messages[index]?.role;\n\t\tif (role === \"user\" || role === \"bashExecution\") return index;\n\t}\n\treturn messages.length;\n}\n\nfunction removeAssistantToolPair(messages: AgentMessage[], assistantIndex: number): PruneStep {\n\tconst ids = getToolCallIds(messages[assistantIndex]);\n\tlet removedTokens = 0;\n\tconst pruned = messages.filter((message, index) => {\n\t\tconst remove = index === assistantIndex || (message.role === \"toolResult\" && ids.has(message.toolCallId));\n\t\tif (remove) removedTokens += estimateTokens(message);\n\t\treturn !remove;\n\t});\n\treturn { messages: pruned, removedTokens };\n}\n\nfunction removeFirstOldToolPair(messages: AgentMessage[], boundaryIndex: number): PruneStep | undefined {\n\tfor (let index = 0; index < boundaryIndex; index++) {\n\t\tconst message = messages[index];\n\t\tif (!message) continue;\n\t\tif (message.role === \"assistant\" && getToolCallIds(message).size > 0)\n\t\t\treturn removeAssistantToolPair(messages, index);\n\t\tif (message.role === \"toolResult\") {\n\t\t\treturn {\n\t\t\t\tmessages: messages.filter((_message, candidateIndex) => candidateIndex !== index),\n\t\t\t\tremovedTokens: estimateTokens(message),\n\t\t\t};\n\t\t}\n\t}\n\treturn undefined;\n}\n\nfunction removeFirstOldMessage(messages: AgentMessage[], boundaryIndex: number): PruneStep | undefined {\n\tfor (let index = 0; index < boundaryIndex; index++) {\n\t\tconst message = messages[index];\n\t\tif (!message || message.role === \"toolResult\") continue;\n\t\tif (message.role === \"assistant\" && getToolCallIds(message).size > 0)\n\t\t\treturn removeAssistantToolPair(messages, index);\n\t\treturn {\n\t\t\tmessages: messages.filter((_candidate, candidateIndex) => candidateIndex !== index),\n\t\t\tremovedTokens: estimateTokens(message),\n\t\t};\n\t}\n\treturn undefined;\n}\n\nfunction pruneOldMessagesToBudget(messages: AgentMessage[], targetTokens: number): AgentMessage[] {\n\tlet pruned = messages;\n\tlet total = estimateTotalTokens(pruned);\n\twhile (total > targetTokens) {\n\t\tconst boundaryIndex = findLastUserLikeIndex(pruned);\n\t\tconst next = removeFirstOldToolPair(pruned, boundaryIndex) ?? removeFirstOldMessage(pruned, boundaryIndex);\n\t\tif (!next || next.messages.length === pruned.length) break;\n\t\tpruned = next.messages;\n\t\ttotal -= next.removedTokens;\n\t}\n\treturn pruned;\n}\n\nfunction removeOldestHistoryItemForOverflowRetry(messages: AgentMessage[]): AgentMessage[] | undefined {\n\tif (messages.length <= 1) return undefined;\n\tconst boundaryIndex = findLastUserLikeIndex(messages);\n\treturn (\n\t\tremoveFirstOldToolPair(messages, boundaryIndex)?.messages ??\n\t\tremoveFirstOldMessage(messages, boundaryIndex)?.messages ??\n\t\t(messages.length > 1 ? messages.slice(1) : undefined)\n\t);\n}\n\nfunction estimateTotalTokens(messages: AgentMessage[]): number {\n\tlet total = 0;\n\tfor (const message of messages) total += estimateTokens(message);\n\treturn total;\n}\n\nexport function hardLimitEmergencyPrune(\n\tmessages: AgentMessage[],\n\tcontextWindow: number,\n): {\n\tmessages: AgentMessage[];\n\tneedsAggressiveCompaction: boolean;\n} {\n\tconst targetTokens = Math.floor(contextWindow * EMERGENCY_CONTEXT_TARGET_RATIO);\n\tif (estimateTotalTokens(messages) <= targetTokens) {\n\t\treturn { messages, needsAggressiveCompaction: false };\n\t}\n\tconst noLlmPruned = truncateContextMessages(pruneToolResults(messages, contextWindow));\n\tif (estimateTotalTokens(noLlmPruned) <= targetTokens) {\n\t\treturn { messages: noLlmPruned, needsAggressiveCompaction: false };\n\t}\n\treturn {\n\t\tmessages: pruneOldMessagesToBudget(noLlmPruned, targetTokens),\n\t\tneedsAggressiveCompaction: true,\n\t};\n}\n\nexport function getPromptVariant(options: {\n\treason: string;\n\tpreparation: { previousSummary?: string; isSplitTurn: boolean };\n}): MergedCompactionPromptVariant {\n\tif (options.reason === \"branch\") return \"branch\";\n\tif (options.preparation.previousSummary) return \"update\";\n\tif (options.preparation.isSplitTurn) return \"turn_prefix\";\n\treturn \"default\";\n}\n\nexport function createSpeculativeCompactionSnapshot(\n\tcontext: SpeculativeCompactionContext,\n\toptions: { customInstructions?: string; generation: number; tools?: Tool[] },\n): SpeculativeCompactionSnapshot | undefined {\n\tconst model = context.model;\n\tif (!model) return undefined;\n\n\tconst expectedRevision = context.getMessageRevision();\n\tconst branchEntries = context.sessionManager.getBranch();\n\tconst contextWindow = context.getContextUsage()?.contextWindow ?? model.contextWindow ?? DEFAULT_CONTEXT_WINDOW;\n\tconst settings = context.getCompactionSettings?.() ?? DEFAULT_COMPACTION_SETTINGS;\n\tconst thresholdRatio = computeEffectiveThreshold(contextWindow);\n\tconst preparation = prepareCompaction(branchEntries, {\n\t\t...settings,\n\t\tkeepRecentTokens: computeEffectiveKeepRecentTokens(settings.keepRecentTokens, contextWindow, thresholdRatio),\n\t});\n\tif (!preparation) return undefined;\n\n\treturn {\n\t\tgeneration: options.generation,\n\t\texpectedRevision,\n\t\tmodel,\n\t\tcontextWindow,\n\t\tpreparation,\n\t\tpromptVariant: getPromptVariant({ reason: \"extension\", preparation }),\n\t\tcustomInstructions: options.customInstructions,\n\t\tsystemPrompt: context.getSystemPrompt?.(),\n\t\ttools: options.tools,\n\t};\n}\n\nexport async function runExtensionCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot,\n\tsignal?: AbortSignal,\n\tonProgress?: CompactionProgressCallback,\n): Promise<CompactionResult | undefined> {\n\tconst auth = await context.modelRegistry?.getApiKeyAndHeaders(snapshot.model);\n\tif (!auth?.ok || !auth.apiKey) return undefined;\n\n\tlet messages = pruneToolResults(\n\t\t[...snapshot.preparation.messagesToSummarize, ...snapshot.preparation.turnPrefixMessages],\n\t\tsnapshot.contextWindow,\n\t);\n\tconst prompt = buildPrompt({\n\t\tvariant: snapshot.promptVariant,\n\t\tpreviousSummary: snapshot.preparation.previousSummary,\n\t\tcustomInstructions: snapshot.customInstructions,\n\t});\n\n\twhile (true) {\n\t\tif (signal?.aborted) return undefined;\n\t\tconst response = await generateSummaryMessage({\n\t\t\tmessages,\n\t\t\tonProgress,\n\t\t\tprompt,\n\t\t\tsignal,\n\t\t\tsnapshot,\n\t\t\tauth: {\n\t\t\t\tapiKey: auth.apiKey,\n\t\t\t\theaders: auth.headers,\n\t\t\t\textraBody: auth.extraBody,\n\t\t\t},\n\t\t});\n\t\tif (!response) return undefined;\n\n\t\tif (isAssistantMessage(response) && isContextOverflow(response, snapshot.contextWindow)) {\n\t\t\tconst retryMessages = removeOldestHistoryItemForOverflowRetry(messages);\n\t\t\tif (!retryMessages || retryMessages.length === messages.length) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmessages = retryMessages;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (isAssistantMessage(response) && response.stopReason === \"aborted\") {\n\t\t\t// A partial summary from an aborted stream must never be applied.\n\t\t\treturn undefined;\n\t\t}\n\n\t\tif (isAssistantMessage(response) && response.stopReason === \"error\") {\n\t\t\t// Surface the real provider failure instead of silently degrading\n\t\t\t// into a generic \"Compaction cancelled\".\n\t\t\tthrow new Error(response.errorMessage || \"Compaction summary request failed\");\n\t\t}\n\n\t\tconst summary = getSummaryText(response);\n\t\tif (!summary) return undefined;\n\n\t\t// Informational only: the core rejects an applied compaction that would\n\t\t// still overflow (_wouldCompactionOverflow). Rejecting here based on the\n\t\t// size of the *discarded* input made large sessions uncompactable.\n\t\tconst tokenEstimate = estimateContextTokens(convertToLlm(messages)).tokens + approxTokens(summary);\n\n\t\treturn {\n\t\t\tsummary,\n\t\t\tfirstKeptEntryId: snapshot.preparation.firstKeptEntryId,\n\t\t\ttokensBefore: snapshot.preparation.tokensBefore,\n\t\t\tdetails: { schema: SUMMARY_SCHEMA, promptVariant: snapshot.promptVariant, tokenEstimate },\n\t\t};\n\t}\n\n\tthrow new Error(\"Compaction summary request exceeded the context window after retrying with a smaller input\");\n}\n\nexport async function applyGeneratedCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot | undefined,\n\tgetCurrentGeneration: () => number,\n\tcompaction: CompactionResult | undefined,\n): Promise<SpeculativeCompactionResult> {\n\tif (!snapshot || !compaction) return { applied: false, reason: \"unavailable\" };\n\n\tif (snapshot.generation !== getCurrentGeneration() || snapshot.expectedRevision !== context.getMessageRevision()) {\n\t\treturn { applied: false, reason: \"stale\" };\n\t}\n\n\treturn await context.applyCompaction(compaction, {\n\t\treason: \"extension\",\n\t\texpectedRevision: snapshot.expectedRevision,\n\t});\n}\n\nexport async function applySpeculativeCompaction(\n\tcontext: SpeculativeCompactionContext,\n\tsnapshot: SpeculativeCompactionSnapshot | undefined,\n\tgetCurrentGeneration: () => number,\n\tgenerate: () => Promise<CompactionResult | undefined>,\n): Promise<SpeculativeCompactionResult> {\n\tif (!snapshot) return { applied: false, reason: \"unavailable\" };\n\n\tconst compaction = await generate();\n\treturn await applyGeneratedCompaction(context, snapshot, getCurrentGeneration, compaction);\n}\n"]}
@@ -1,23 +1,25 @@
1
1
  import type { SessionEntry } from "../../../session-manager.ts";
2
2
  import type { ExtensionAPI, ExtensionContext } from "../../types.ts";
3
+ import type { TodoPhase } from "../todotools/state.ts";
3
4
  declare const TODO_SNAPSHOT_SCHEMA = "senpi.compaction.todo-snapshot.v1";
4
5
  export interface TodoEntry {
5
- id: string;
6
+ id?: string;
6
7
  content?: string;
7
8
  text?: string;
8
- status?: "pending" | "in_progress" | "completed" | "cancelled";
9
+ status?: string;
9
10
  }
11
+ export type TodoSnapshotItems = TodoEntry[] | TodoPhase[];
10
12
  export interface TodoSnapshotPayload {
11
13
  schema: typeof TODO_SNAPSHOT_SCHEMA;
12
- todos: TodoEntry[] | SessionEntry[];
14
+ todos: TodoSnapshotItems | SessionEntry[];
13
15
  capturedAt: number;
14
16
  }
15
17
  interface AppendEntryTarget {
16
18
  appendEntry<T = unknown>(customType: string, data?: T): void;
17
19
  }
18
- interface RestoreResult {
20
+ export interface RestoreResult<T extends TodoSnapshotItems = TodoSnapshotItems> {
19
21
  applied: boolean;
20
- restoredTodos: TodoEntry[];
22
+ restoredTodos: T;
21
23
  }
22
24
  export declare function findTodoEntries(ctx: ExtensionContext): SessionEntry[];
23
25
  export declare function findTodoEntries(entries: SessionEntry[], options?: {
@@ -26,8 +28,8 @@ export declare function findTodoEntries(entries: SessionEntry[], options?: {
26
28
  export declare function createTodoSnapshot(ctx: ExtensionContext): TodoSnapshotPayload;
27
29
  export declare function persistTodoSnapshot(pi: AppendEntryTarget, snapshot: TodoSnapshotPayload): void;
28
30
  export declare function captureTodoSnapshot(pi: ExtensionAPI, ctx: ExtensionContext): void;
29
- export declare function captureTodoSnapshot(currentTodos: TodoEntry[], pi: AppendEntryTarget, branchId?: string): void;
31
+ export declare function captureTodoSnapshot(currentTodos: TodoSnapshotItems, pi: AppendEntryTarget, branchId?: string): void;
30
32
  export declare function restoreTodosIfMissing(pi: ExtensionAPI, ctx: ExtensionContext): void;
31
- export declare function restoreTodosIfMissing(snapshot: TodoEntry[], currentTodos: TodoEntry[], pi: AppendEntryTarget): RestoreResult;
33
+ export declare function restoreTodosIfMissing<T extends TodoSnapshotItems>(snapshot: T, currentTodos: T, pi: AppendEntryTarget): RestoreResult<T>;
32
34
  export {};
33
35
  //# sourceMappingURL=todo-bridge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"todo-bridge.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/todo-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAGrE,QAAA,MAAM,oBAAoB,sCAAsC,CAAC;AAEjE,MAAM,WAAW,SAAS;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,WAAW,CAAC;CAC/D;AAED,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,OAAO,oBAAoB,CAAC;IACpC,KAAK,EAAE,SAAS,EAAE,GAAG,YAAY,EAAE,CAAC;IACpC,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IAC1B,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;CAC7D;AASD,UAAU,aAAa;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,SAAS,EAAE,CAAC;CAC3B;AAiCD,wBAAgB,eAAe,CAAC,GAAG,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAAC;AACvE,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EAAE,CAAC;AAevG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,mBAAmB,CAM7E;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,iBAAiB,EAAE,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAE9F;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAAC;AACnF,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;AAmB/G,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAAC;AACrF,wBAAgB,qBAAqB,CACpC,QAAQ,EAAE,SAAS,EAAE,EACrB,YAAY,EAAE,SAAS,EAAE,EACzB,EAAE,EAAE,iBAAiB,GACnB,aAAa,CAAC"}
1
+ {"version":3,"file":"todo-bridge.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/todo-bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAe,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAGvD,QAAA,MAAM,oBAAoB,sCAAsC,CAAC;AAGjE,MAAM,WAAW,SAAS;IACzB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,MAAM,iBAAiB,GAAG,SAAS,EAAE,GAAG,SAAS,EAAE,CAAC;AAE1D,MAAM,WAAW,mBAAmB;IACnC,MAAM,EAAE,OAAO,oBAAoB,CAAC;IACpC,KAAK,EAAE,iBAAiB,GAAG,YAAY,EAAE,CAAC;IAC1C,UAAU,EAAE,MAAM,CAAC;CACnB;AAED,UAAU,iBAAiB;IAC1B,WAAW,CAAC,CAAC,GAAG,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;CAC7D;AASD,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,iBAAiB,GAAG,iBAAiB;IAC7E,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,CAAC,CAAC;CACjB;AA2DD,wBAAgB,eAAe,CAAC,GAAG,EAAE,gBAAgB,GAAG,YAAY,EAAE,CAAC;AACvE,wBAAgB,eAAe,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,EAAE,CAAC;AAevG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,gBAAgB,GAAG,mBAAmB,CAM7E;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,iBAAiB,EAAE,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAE9F;AAED,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAAC;AACnF,wBAAgB,mBAAmB,CAAC,YAAY,EAAE,iBAAiB,EAAE,EAAE,EAAE,iBAAiB,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;AAmBrH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,gBAAgB,GAAG,IAAI,CAAC;AACrF,wBAAgB,qBAAqB,CAAC,CAAC,SAAS,iBAAiB,EAChE,QAAQ,EAAE,CAAC,EACX,YAAY,EAAE,CAAC,EACf,EAAE,EAAE,iBAAiB,GACnB,aAAa,CAAC,CAAC,CAAC,CAAC"}
@@ -1,28 +1,53 @@
1
1
  const TODO_SNAPSHOT_CUSTOM_TYPE = "compaction.todo-snapshot";
2
2
  const TODO_SNAPSHOT_SCHEMA = "senpi.compaction.todo-snapshot.v1";
3
+ const TODO_STATE_ENTRY_TYPE = "senpi.todo-state";
4
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null;
6
+ }
7
+ function isTodoStatus(value) {
8
+ // Legacy todowrite entries carried arbitrary status strings (e.g. "blocked").
9
+ // The bridge is a pass-through snapshot carrier, not a validator: preserve
10
+ // every string-status entry so restore never silently drops legacy todos.
11
+ return value === undefined || typeof value === "string";
12
+ }
13
+ function isTodoEntry(value) {
14
+ if (!isRecord(value))
15
+ return false;
16
+ const hasId = typeof value.id === "string";
17
+ const hasContent = typeof value.content === "string" || typeof value.text === "string";
18
+ return (hasId || hasContent) && isTodoStatus(value.status);
19
+ }
20
+ function isTodoPhase(value) {
21
+ if (!isRecord(value) || typeof value.name !== "string" || !Array.isArray(value.tasks))
22
+ return false;
23
+ return value.tasks.every(isTodoEntry);
24
+ }
3
25
  function isCustomTodoEntry(entry) {
4
- return entry.type === "custom" && entry.customType.startsWith("todowrite");
26
+ return (entry.type === "custom" &&
27
+ (entry.customType.startsWith("todowrite") || entry.customType === TODO_STATE_ENTRY_TYPE));
5
28
  }
6
29
  function isLegacyTodoListEntry(entry) {
7
30
  return entry.type === "custom" && entry.customType === "todo-list";
8
31
  }
9
32
  function readTodosFromEntry(entry) {
10
33
  const data = entry.data;
11
- if (typeof data !== "object" || data === null || !("todos" in data) || !Array.isArray(data.todos)) {
34
+ if (!isRecord(data))
12
35
  return [];
36
+ if (Array.isArray(data.todos))
37
+ return data.todos.filter(isTodoEntry);
38
+ if (Array.isArray(data.phases)) {
39
+ return data.phases.filter(isTodoPhase).flatMap((phase) => phase.tasks);
13
40
  }
14
- return data.todos.filter((todo) => {
15
- return typeof todo === "object" && todo !== null && "id" in todo && typeof todo.id === "string";
16
- });
41
+ return [];
17
42
  }
18
43
  function findLatestTodoSnapshot(ctx) {
19
44
  const entries = ctx.sessionManager.getEntries();
20
- for (let index = entries.length - 1; index >= 0; index--) {
45
+ for (let index = entries.length - 1; index >= 0; index -= 1) {
21
46
  const entry = entries[index];
22
47
  if (entry.type !== "custom" || entry.customType !== TODO_SNAPSHOT_CUSTOM_TYPE)
23
48
  continue;
24
49
  const data = entry.data;
25
- if (typeof data === "object" && data !== null && "schema" in data && data.schema === TODO_SNAPSHOT_SCHEMA) {
50
+ if (isRecord(data) && data.schema === TODO_SNAPSHOT_SCHEMA && Array.isArray(data.todos)) {
26
51
  return data;
27
52
  }
28
53
  }
@@ -31,7 +56,7 @@ function findLatestTodoSnapshot(ctx) {
31
56
  export function findTodoEntries(ctxOrEntries, options) {
32
57
  if (Array.isArray(ctxOrEntries)) {
33
58
  return ctxOrEntries
34
- .filter(isLegacyTodoListEntry)
59
+ .filter((entry) => isLegacyTodoListEntry(entry) || isCustomTodoEntry(entry))
35
60
  .filter((entry) => options?.branchId === undefined || entry.parentId === options.branchId)
36
61
  .flatMap(readTodosFromEntry);
37
62
  }
@@ -75,7 +100,7 @@ export function restoreTodosIfMissing(piOrSnapshot, ctxOrCurrentTodos, _pi) {
75
100
  return;
76
101
  pi.sendMessage({
77
102
  customType: "compaction.todo-restore-request",
78
- content: `Restore missing todowrite todos from snapshot: ${JSON.stringify(snapshot.todos)}`,
103
+ content: `Restore missing todo tasks from snapshot: ${JSON.stringify(snapshot.todos)}`,
79
104
  display: false,
80
105
  details: snapshot,
81
106
  }, { triggerTurn: true, deliverAs: "nextTurn" });
@@ -1 +1 @@
1
- {"version":3,"file":"todo-bridge.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/todo-bridge.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CustomEntry, SessionEntry } from \"../../../session-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\n\nconst TODO_SNAPSHOT_CUSTOM_TYPE = \"compaction.todo-snapshot\";\nconst TODO_SNAPSHOT_SCHEMA = \"senpi.compaction.todo-snapshot.v1\";\n\nexport interface TodoEntry {\n\tid: string;\n\tcontent?: string;\n\ttext?: string;\n\tstatus?: \"pending\" | \"in_progress\" | \"completed\" | \"cancelled\";\n}\n\nexport interface TodoSnapshotPayload {\n\tschema: typeof TODO_SNAPSHOT_SCHEMA;\n\ttodos: TodoEntry[] | SessionEntry[];\n\tcapturedAt: number;\n}\n\ninterface AppendEntryTarget {\n\tappendEntry<T = unknown>(customType: string, data?: T): void;\n}\n\ninterface SendMessageTarget extends AppendEntryTarget {\n\tsendMessage<T = unknown>(\n\t\tmessage: { customType: string; content: string; display: boolean; details?: T },\n\t\toptions?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },\n\t): void;\n}\n\ninterface RestoreResult {\n\tapplied: boolean;\n\trestoredTodos: TodoEntry[];\n}\n\nfunction isCustomTodoEntry(entry: SessionEntry): entry is CustomEntry {\n\treturn entry.type === \"custom\" && entry.customType.startsWith(\"todowrite\");\n}\n\nfunction isLegacyTodoListEntry(entry: SessionEntry): entry is CustomEntry {\n\treturn entry.type === \"custom\" && entry.customType === \"todo-list\";\n}\n\nfunction readTodosFromEntry(entry: CustomEntry): TodoEntry[] {\n\tconst data = entry.data;\n\tif (typeof data !== \"object\" || data === null || !(\"todos\" in data) || !Array.isArray(data.todos)) {\n\t\treturn [];\n\t}\n\treturn data.todos.filter((todo): todo is TodoEntry => {\n\t\treturn typeof todo === \"object\" && todo !== null && \"id\" in todo && typeof todo.id === \"string\";\n\t});\n}\n\nfunction findLatestTodoSnapshot(ctx: ExtensionContext): TodoSnapshotPayload | null {\n\tconst entries = ctx.sessionManager.getEntries();\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry.type !== \"custom\" || entry.customType !== TODO_SNAPSHOT_CUSTOM_TYPE) continue;\n\t\tconst data = entry.data;\n\t\tif (typeof data === \"object\" && data !== null && \"schema\" in data && data.schema === TODO_SNAPSHOT_SCHEMA) {\n\t\t\treturn data as TodoSnapshotPayload;\n\t\t}\n\t}\n\treturn null;\n}\n\nexport function findTodoEntries(ctx: ExtensionContext): SessionEntry[];\nexport function findTodoEntries(entries: SessionEntry[], options?: { branchId?: string }): TodoEntry[];\nexport function findTodoEntries(\n\tctxOrEntries: ExtensionContext | SessionEntry[],\n\toptions?: { branchId?: string },\n): SessionEntry[] | TodoEntry[] {\n\tif (Array.isArray(ctxOrEntries)) {\n\t\treturn ctxOrEntries\n\t\t\t.filter(isLegacyTodoListEntry)\n\t\t\t.filter((entry) => options?.branchId === undefined || entry.parentId === options.branchId)\n\t\t\t.flatMap(readTodosFromEntry);\n\t}\n\n\treturn ctxOrEntries.sessionManager.getEntries().filter(isCustomTodoEntry);\n}\n\nexport function createTodoSnapshot(ctx: ExtensionContext): TodoSnapshotPayload {\n\treturn {\n\t\tschema: TODO_SNAPSHOT_SCHEMA,\n\t\ttodos: findTodoEntries(ctx),\n\t\tcapturedAt: Date.now(),\n\t};\n}\n\nexport function persistTodoSnapshot(pi: AppendEntryTarget, snapshot: TodoSnapshotPayload): void {\n\tpi.appendEntry(TODO_SNAPSHOT_CUSTOM_TYPE, snapshot);\n}\n\nexport function captureTodoSnapshot(pi: ExtensionAPI, ctx: ExtensionContext): void;\nexport function captureTodoSnapshot(currentTodos: TodoEntry[], pi: AppendEntryTarget, branchId?: string): void;\nexport function captureTodoSnapshot(\n\tpiOrTodos: ExtensionAPI | TodoEntry[],\n\tctxOrPi: ExtensionContext | AppendEntryTarget,\n\t_branchId?: string,\n): void {\n\tif (Array.isArray(piOrTodos)) {\n\t\tconst pi = ctxOrPi as AppendEntryTarget;\n\t\tpersistTodoSnapshot(pi, {\n\t\t\tschema: TODO_SNAPSHOT_SCHEMA,\n\t\t\ttodos: piOrTodos,\n\t\t\tcapturedAt: Date.now(),\n\t\t});\n\t\treturn;\n\t}\n\n\tpersistTodoSnapshot(piOrTodos, createTodoSnapshot(ctxOrPi as ExtensionContext));\n}\n\nexport function restoreTodosIfMissing(pi: ExtensionAPI, ctx: ExtensionContext): void;\nexport function restoreTodosIfMissing(\n\tsnapshot: TodoEntry[],\n\tcurrentTodos: TodoEntry[],\n\tpi: AppendEntryTarget,\n): RestoreResult;\nexport function restoreTodosIfMissing(\n\tpiOrSnapshot: ExtensionAPI | TodoEntry[],\n\tctxOrCurrentTodos: ExtensionContext | TodoEntry[],\n\t_pi?: AppendEntryTarget,\n): undefined | RestoreResult {\n\tif (Array.isArray(piOrSnapshot) && Array.isArray(ctxOrCurrentTodos)) {\n\t\tif (ctxOrCurrentTodos.length > 0) {\n\t\t\treturn { applied: false, restoredTodos: ctxOrCurrentTodos };\n\t\t}\n\t\treturn { applied: piOrSnapshot.length > 0, restoredTodos: piOrSnapshot };\n\t}\n\n\tconst pi = piOrSnapshot as SendMessageTarget;\n\tconst ctx = ctxOrCurrentTodos as ExtensionContext;\n\tif (findTodoEntries(ctx).length > 0) return;\n\n\tconst snapshot = findLatestTodoSnapshot(ctx);\n\tif (!snapshot || snapshot.todos.length === 0) return;\n\n\tpi.sendMessage(\n\t\t{\n\t\t\tcustomType: \"compaction.todo-restore-request\",\n\t\t\tcontent: `Restore missing todowrite todos from snapshot: ${JSON.stringify(snapshot.todos)}`,\n\t\t\tdisplay: false,\n\t\t\tdetails: snapshot,\n\t\t},\n\t\t{ triggerTurn: true, deliverAs: \"nextTurn\" },\n\t);\n}\n"]}
1
+ {"version":3,"file":"todo-bridge.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/compaction/todo-bridge.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CustomEntry, SessionEntry } from \"../../../session-manager.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport type { TodoPhase } from \"../todotools/state.ts\";\n\nconst TODO_SNAPSHOT_CUSTOM_TYPE = \"compaction.todo-snapshot\";\nconst TODO_SNAPSHOT_SCHEMA = \"senpi.compaction.todo-snapshot.v1\";\nconst TODO_STATE_ENTRY_TYPE = \"senpi.todo-state\";\n\nexport interface TodoEntry {\n\tid?: string;\n\tcontent?: string;\n\ttext?: string;\n\tstatus?: string;\n}\n\nexport type TodoSnapshotItems = TodoEntry[] | TodoPhase[];\n\nexport interface TodoSnapshotPayload {\n\tschema: typeof TODO_SNAPSHOT_SCHEMA;\n\ttodos: TodoSnapshotItems | SessionEntry[];\n\tcapturedAt: number;\n}\n\ninterface AppendEntryTarget {\n\tappendEntry<T = unknown>(customType: string, data?: T): void;\n}\n\ninterface SendMessageTarget extends AppendEntryTarget {\n\tsendMessage<T = unknown>(\n\t\tmessage: { customType: string; content: string; display: boolean; details?: T },\n\t\toptions?: { triggerTurn?: boolean; deliverAs?: \"steer\" | \"followUp\" | \"nextTurn\" },\n\t): void;\n}\n\nexport interface RestoreResult<T extends TodoSnapshotItems = TodoSnapshotItems> {\n\tapplied: boolean;\n\trestoredTodos: T;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null;\n}\n\nfunction isTodoStatus(value: unknown): value is TodoEntry[\"status\"] {\n\t// Legacy todowrite entries carried arbitrary status strings (e.g. \"blocked\").\n\t// The bridge is a pass-through snapshot carrier, not a validator: preserve\n\t// every string-status entry so restore never silently drops legacy todos.\n\treturn value === undefined || typeof value === \"string\";\n}\n\nfunction isTodoEntry(value: unknown): value is TodoEntry {\n\tif (!isRecord(value)) return false;\n\tconst hasId = typeof value.id === \"string\";\n\tconst hasContent = typeof value.content === \"string\" || typeof value.text === \"string\";\n\treturn (hasId || hasContent) && isTodoStatus(value.status);\n}\n\nfunction isTodoPhase(value: unknown): value is TodoPhase {\n\tif (!isRecord(value) || typeof value.name !== \"string\" || !Array.isArray(value.tasks)) return false;\n\treturn value.tasks.every(isTodoEntry);\n}\n\nfunction isCustomTodoEntry(entry: SessionEntry): entry is CustomEntry {\n\treturn (\n\t\tentry.type === \"custom\" &&\n\t\t(entry.customType.startsWith(\"todowrite\") || entry.customType === TODO_STATE_ENTRY_TYPE)\n\t);\n}\n\nfunction isLegacyTodoListEntry(entry: SessionEntry): entry is CustomEntry {\n\treturn entry.type === \"custom\" && entry.customType === \"todo-list\";\n}\n\nfunction readTodosFromEntry(entry: CustomEntry): TodoEntry[] {\n\tconst data = entry.data;\n\tif (!isRecord(data)) return [];\n\tif (Array.isArray(data.todos)) return data.todos.filter(isTodoEntry);\n\tif (Array.isArray(data.phases)) {\n\t\treturn data.phases.filter(isTodoPhase).flatMap((phase) => phase.tasks);\n\t}\n\treturn [];\n}\n\nfunction findLatestTodoSnapshot(ctx: ExtensionContext): TodoSnapshotPayload | null {\n\tconst entries = ctx.sessionManager.getEntries();\n\tfor (let index = entries.length - 1; index >= 0; index -= 1) {\n\t\tconst entry = entries[index];\n\t\tif (entry.type !== \"custom\" || entry.customType !== TODO_SNAPSHOT_CUSTOM_TYPE) continue;\n\t\tconst data = entry.data;\n\t\tif (isRecord(data) && data.schema === TODO_SNAPSHOT_SCHEMA && Array.isArray(data.todos)) {\n\t\t\treturn data as unknown as TodoSnapshotPayload;\n\t\t}\n\t}\n\treturn null;\n}\n\nexport function findTodoEntries(ctx: ExtensionContext): SessionEntry[];\nexport function findTodoEntries(entries: SessionEntry[], options?: { branchId?: string }): TodoEntry[];\nexport function findTodoEntries(\n\tctxOrEntries: ExtensionContext | SessionEntry[],\n\toptions?: { branchId?: string },\n): SessionEntry[] | TodoEntry[] {\n\tif (Array.isArray(ctxOrEntries)) {\n\t\treturn ctxOrEntries\n\t\t\t.filter((entry) => isLegacyTodoListEntry(entry) || isCustomTodoEntry(entry))\n\t\t\t.filter((entry) => options?.branchId === undefined || entry.parentId === options.branchId)\n\t\t\t.flatMap(readTodosFromEntry);\n\t}\n\n\treturn ctxOrEntries.sessionManager.getEntries().filter(isCustomTodoEntry);\n}\n\nexport function createTodoSnapshot(ctx: ExtensionContext): TodoSnapshotPayload {\n\treturn {\n\t\tschema: TODO_SNAPSHOT_SCHEMA,\n\t\ttodos: findTodoEntries(ctx),\n\t\tcapturedAt: Date.now(),\n\t};\n}\n\nexport function persistTodoSnapshot(pi: AppendEntryTarget, snapshot: TodoSnapshotPayload): void {\n\tpi.appendEntry(TODO_SNAPSHOT_CUSTOM_TYPE, snapshot);\n}\n\nexport function captureTodoSnapshot(pi: ExtensionAPI, ctx: ExtensionContext): void;\nexport function captureTodoSnapshot(currentTodos: TodoSnapshotItems, pi: AppendEntryTarget, branchId?: string): void;\nexport function captureTodoSnapshot(\n\tpiOrTodos: ExtensionAPI | TodoSnapshotItems,\n\tctxOrPi: ExtensionContext | AppendEntryTarget,\n\t_branchId?: string,\n): void {\n\tif (Array.isArray(piOrTodos)) {\n\t\tconst pi = ctxOrPi as AppendEntryTarget;\n\t\tpersistTodoSnapshot(pi, {\n\t\t\tschema: TODO_SNAPSHOT_SCHEMA,\n\t\t\ttodos: piOrTodos,\n\t\t\tcapturedAt: Date.now(),\n\t\t});\n\t\treturn;\n\t}\n\n\tpersistTodoSnapshot(piOrTodos, createTodoSnapshot(ctxOrPi as ExtensionContext));\n}\n\nexport function restoreTodosIfMissing(pi: ExtensionAPI, ctx: ExtensionContext): void;\nexport function restoreTodosIfMissing<T extends TodoSnapshotItems>(\n\tsnapshot: T,\n\tcurrentTodos: T,\n\tpi: AppendEntryTarget,\n): RestoreResult<T>;\nexport function restoreTodosIfMissing(\n\tpiOrSnapshot: ExtensionAPI | TodoSnapshotItems,\n\tctxOrCurrentTodos: ExtensionContext | TodoSnapshotItems,\n\t_pi?: AppendEntryTarget,\n): undefined | RestoreResult {\n\tif (Array.isArray(piOrSnapshot) && Array.isArray(ctxOrCurrentTodos)) {\n\t\tif (ctxOrCurrentTodos.length > 0) {\n\t\t\treturn { applied: false, restoredTodos: ctxOrCurrentTodos };\n\t\t}\n\t\treturn { applied: piOrSnapshot.length > 0, restoredTodos: piOrSnapshot };\n\t}\n\n\tconst pi = piOrSnapshot as SendMessageTarget;\n\tconst ctx = ctxOrCurrentTodos as ExtensionContext;\n\tif (findTodoEntries(ctx).length > 0) return;\n\n\tconst snapshot = findLatestTodoSnapshot(ctx);\n\tif (!snapshot || snapshot.todos.length === 0) return;\n\n\tpi.sendMessage(\n\t\t{\n\t\t\tcustomType: \"compaction.todo-restore-request\",\n\t\t\tcontent: `Restore missing todo tasks from snapshot: ${JSON.stringify(snapshot.todos)}`,\n\t\t\tdisplay: false,\n\t\t\tdetails: snapshot,\n\t\t},\n\t\t{ triggerTurn: true, deliverAs: \"nextTurn\" },\n\t);\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  import type { ExtensionAPI, ExtensionContext } from "../../types.ts";
2
- import type { Goal, GoalAccountingMode, GoalStoreRef, TokenUsageSnapshot } from "./types.ts";
2
+ import type { Goal, GoalAccountingMode, GoalStoreRef } from "./types.ts";
3
3
  export type GoalCommandRegistrationDeps = {
4
4
  readonly goalStoreRef: (ctx: ExtensionContext) => GoalStoreRef;
5
- readonly accountCurrentAgentTurn: (ctx: ExtensionContext, usage: TokenUsageSnapshot, mode: GoalAccountingMode) => Promise<Goal | null>;
5
+ readonly accountCurrentAgentTurn: (ctx: ExtensionContext, mode: GoalAccountingMode) => Promise<Goal | null>;
6
6
  readonly beginAgentGoalAccounting: (goal: Goal) => void;
7
7
  readonly stopAgentGoalAccounting: (goalId: string) => void;
8
8
  readonly clearAgentGoalAccounting: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"command-registration.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/command-registration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIrE,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAQ7F,MAAM,MAAM,2BAA2B,GAAG;IACzC,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,YAAY,CAAC;IAC/D,QAAQ,CAAC,uBAAuB,EAAE,CACjC,GAAG,EAAE,gBAAgB,EACrB,KAAK,EAAE,kBAAkB,EACzB,IAAI,EAAE,kBAAkB,KACpB,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC1B,QAAQ,CAAC,wBAAwB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,wBAAwB,EAAE,MAAM,IAAI,CAAC;IAC9C,QAAQ,CAAC,qBAAqB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9F,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;CAC3E,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,2BAA2B,GAAG,IAAI,CAoD7F"}
1
+ {"version":3,"file":"command-registration.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/command-registration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAIrE,OAAO,KAAK,EAAE,IAAI,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAOzE,MAAM,MAAM,2BAA2B,GAAG;IACzC,QAAQ,CAAC,YAAY,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,YAAY,CAAC;IAC/D,QAAQ,CAAC,uBAAuB,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IAC5G,QAAQ,CAAC,wBAAwB,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACxD,QAAQ,CAAC,uBAAuB,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3D,QAAQ,CAAC,wBAAwB,EAAE,MAAM,IAAI,CAAC;IAC9C,QAAQ,CAAC,qBAAqB,EAAE,CAAC,EAAE,EAAE,YAAY,EAAE,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9F,QAAQ,CAAC,aAAa,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,IAAI,GAAG,IAAI,KAAK,IAAI,CAAC;CAC3E,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,2BAA2B,GAAG,IAAI,CAoD7F"}
@@ -5,7 +5,6 @@ const GOAL_USAGE = "Usage: /goal <objective>";
5
5
  const GOAL_EMPTY_HINT = "No goal is currently set.";
6
6
  const REPLACE_GOAL_CHOICE = "Replace current goal";
7
7
  const CANCEL_REPLACE_GOAL_CHOICE = "Cancel";
8
- const EMPTY_USAGE = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0 };
9
8
  export function registerGoalCommand(pi, deps) {
10
9
  pi.registerCommand("goal", {
11
10
  description: "Set, inspect, pause, resume, or clear the persistent goal",
@@ -25,7 +24,7 @@ export function registerGoalCommand(pi, deps) {
25
24
  }
26
25
  case "setStatus": {
27
26
  if (command.status === "paused") {
28
- await deps.accountCurrentAgentTurn(ctx, EMPTY_USAGE, "active");
27
+ await deps.accountCurrentAgentTurn(ctx, "active");
29
28
  }
30
29
  const goal = await updateGoal(deps.goalStoreRef(ctx), { status: command.status });
31
30
  if (goal.status === "active") {
@@ -40,7 +39,7 @@ export function registerGoalCommand(pi, deps) {
40
39
  return;
41
40
  }
42
41
  case "clear": {
43
- await deps.accountCurrentAgentTurn(ctx, EMPTY_USAGE, "active");
42
+ await deps.accountCurrentAgentTurn(ctx, "active");
44
43
  const cleared = await clearGoal(deps.goalStoreRef(ctx));
45
44
  deps.clearAgentGoalAccounting();
46
45
  deps.refreshGoalUi(ctx, null);
@@ -64,7 +63,7 @@ async function setGoalObjective(pi, ctx, objective, deps) {
64
63
  return;
65
64
  }
66
65
  if (current?.status === "active") {
67
- await deps.accountCurrentAgentTurn(ctx, EMPTY_USAGE, "active");
66
+ await deps.accountCurrentAgentTurn(ctx, "active");
68
67
  }
69
68
  const goal = current === null ? await createGoal(ref, objective) : await updateGoal(ref, { objective });
70
69
  if (goal.status === "active")
@@ -1 +1 @@
1
- {"version":3,"file":"command-registration.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/command-registration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { parseGoalCommand } from \"./command.ts\";\nimport { formatGoalForTool, goalStatusLabel } from \"./format.ts\";\nimport { clearGoal, createGoal, readGoal, updateGoal } from \"./store.ts\";\nimport type { Goal, GoalAccountingMode, GoalStoreRef, TokenUsageSnapshot } from \"./types.ts\";\n\nconst GOAL_USAGE = \"Usage: /goal <objective>\";\nconst GOAL_EMPTY_HINT = \"No goal is currently set.\";\nconst REPLACE_GOAL_CHOICE = \"Replace current goal\";\nconst CANCEL_REPLACE_GOAL_CHOICE = \"Cancel\";\nconst EMPTY_USAGE: TokenUsageSnapshot = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0 };\n\nexport type GoalCommandRegistrationDeps = {\n\treadonly goalStoreRef: (ctx: ExtensionContext) => GoalStoreRef;\n\treadonly accountCurrentAgentTurn: (\n\t\tctx: ExtensionContext,\n\t\tusage: TokenUsageSnapshot,\n\t\tmode: GoalAccountingMode,\n\t) => Promise<Goal | null>;\n\treadonly beginAgentGoalAccounting: (goal: Goal) => void;\n\treadonly stopAgentGoalAccounting: (goalId: string) => void;\n\treadonly clearAgentGoalAccounting: () => void;\n\treadonly queueGoalContinuation: (pi: ExtensionAPI, ctx: ExtensionContext, goal: Goal) => void;\n\treadonly refreshGoalUi: (ctx: ExtensionContext, goal: Goal | null) => void;\n};\n\nexport function registerGoalCommand(pi: ExtensionAPI, deps: GoalCommandRegistrationDeps): void {\n\tpi.registerCommand(\"goal\", {\n\t\tdescription: \"Set, inspect, pause, resume, or clear the persistent goal\",\n\t\thandler: async (rawArgs, ctx) => {\n\t\t\tconst command = parseGoalCommand(rawArgs);\n\t\t\ttry {\n\t\t\t\tswitch (command.kind) {\n\t\t\t\t\tcase \"show\": {\n\t\t\t\t\t\tconst goal = await readGoal(deps.goalStoreRef(ctx));\n\t\t\t\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tgoal === null ? `${GOAL_USAGE}\\n${GOAL_EMPTY_HINT}` : formatGoalForTool(goal),\n\t\t\t\t\t\t\tgoal ? \"info\" : \"warning\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"setObjective\": {\n\t\t\t\t\t\tawait setGoalObjective(pi, ctx, command.objective, deps);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"setStatus\": {\n\t\t\t\t\t\tif (command.status === \"paused\") {\n\t\t\t\t\t\t\tawait deps.accountCurrentAgentTurn(ctx, EMPTY_USAGE, \"active\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst goal = await updateGoal(deps.goalStoreRef(ctx), { status: command.status });\n\t\t\t\t\t\tif (goal.status === \"active\") {\n\t\t\t\t\t\t\tdeps.beginAgentGoalAccounting(goal);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdeps.stopAgentGoalAccounting(goal.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\t\t\t\tctx.ui.notify(`Goal ${goalStatusLabel(goal.status)}\\n${formatGoalForTool(goal)}`, \"info\");\n\t\t\t\t\t\tdeps.queueGoalContinuation(pi, ctx, goal);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"clear\": {\n\t\t\t\t\t\tawait deps.accountCurrentAgentTurn(ctx, EMPTY_USAGE, \"active\");\n\t\t\t\t\t\tconst cleared = await clearGoal(deps.goalStoreRef(ctx));\n\t\t\t\t\t\tdeps.clearAgentGoalAccounting();\n\t\t\t\t\t\tdeps.refreshGoalUi(ctx, null);\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tcleared ? \"Goal cleared\" : \"No goal to clear\\nThis thread does not currently have a goal.\",\n\t\t\t\t\t\t\tcleared ? \"info\" : \"warning\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n\nasync function setGoalObjective(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tobjective: string,\n\tdeps: GoalCommandRegistrationDeps,\n): Promise<void> {\n\tconst ref = deps.goalStoreRef(ctx);\n\tconst current = await readGoal(ref);\n\tif (current !== null) {\n\t\tconst shouldReplace = await confirmReplaceGoal(ctx, objective);\n\t\tif (!shouldReplace) return;\n\t}\n\n\tif (current?.status === \"active\") {\n\t\tawait deps.accountCurrentAgentTurn(ctx, EMPTY_USAGE, \"active\");\n\t}\n\tconst goal = current === null ? await createGoal(ref, objective) : await updateGoal(ref, { objective });\n\tif (goal.status === \"active\") deps.beginAgentGoalAccounting(goal);\n\tdeps.refreshGoalUi(ctx, goal);\n\tctx.ui.notify(`Goal ${goalStatusLabel(goal.status)}\\n${formatGoalForTool(goal)}`, \"info\");\n\tdeps.queueGoalContinuation(pi, ctx, goal);\n}\n\nasync function confirmReplaceGoal(ctx: ExtensionContext, objective: string): Promise<boolean> {\n\tif (!ctx.hasUI) return true;\n\tconst choice = await ctx.ui.select(`Replace goal?\\nNew objective: ${objective}`, [\n\t\tREPLACE_GOAL_CHOICE,\n\t\tCANCEL_REPLACE_GOAL_CHOICE,\n\t]);\n\treturn choice === REPLACE_GOAL_CHOICE;\n}\n"]}
1
+ {"version":3,"file":"command-registration.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/command-registration.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { parseGoalCommand } from \"./command.ts\";\nimport { formatGoalForTool, goalStatusLabel } from \"./format.ts\";\nimport { clearGoal, createGoal, readGoal, updateGoal } from \"./store.ts\";\nimport type { Goal, GoalAccountingMode, GoalStoreRef } from \"./types.ts\";\n\nconst GOAL_USAGE = \"Usage: /goal <objective>\";\nconst GOAL_EMPTY_HINT = \"No goal is currently set.\";\nconst REPLACE_GOAL_CHOICE = \"Replace current goal\";\nconst CANCEL_REPLACE_GOAL_CHOICE = \"Cancel\";\n\nexport type GoalCommandRegistrationDeps = {\n\treadonly goalStoreRef: (ctx: ExtensionContext) => GoalStoreRef;\n\treadonly accountCurrentAgentTurn: (ctx: ExtensionContext, mode: GoalAccountingMode) => Promise<Goal | null>;\n\treadonly beginAgentGoalAccounting: (goal: Goal) => void;\n\treadonly stopAgentGoalAccounting: (goalId: string) => void;\n\treadonly clearAgentGoalAccounting: () => void;\n\treadonly queueGoalContinuation: (pi: ExtensionAPI, ctx: ExtensionContext, goal: Goal) => void;\n\treadonly refreshGoalUi: (ctx: ExtensionContext, goal: Goal | null) => void;\n};\n\nexport function registerGoalCommand(pi: ExtensionAPI, deps: GoalCommandRegistrationDeps): void {\n\tpi.registerCommand(\"goal\", {\n\t\tdescription: \"Set, inspect, pause, resume, or clear the persistent goal\",\n\t\thandler: async (rawArgs, ctx) => {\n\t\t\tconst command = parseGoalCommand(rawArgs);\n\t\t\ttry {\n\t\t\t\tswitch (command.kind) {\n\t\t\t\t\tcase \"show\": {\n\t\t\t\t\t\tconst goal = await readGoal(deps.goalStoreRef(ctx));\n\t\t\t\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tgoal === null ? `${GOAL_USAGE}\\n${GOAL_EMPTY_HINT}` : formatGoalForTool(goal),\n\t\t\t\t\t\t\tgoal ? \"info\" : \"warning\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"setObjective\": {\n\t\t\t\t\t\tawait setGoalObjective(pi, ctx, command.objective, deps);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"setStatus\": {\n\t\t\t\t\t\tif (command.status === \"paused\") {\n\t\t\t\t\t\t\tawait deps.accountCurrentAgentTurn(ctx, \"active\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst goal = await updateGoal(deps.goalStoreRef(ctx), { status: command.status });\n\t\t\t\t\t\tif (goal.status === \"active\") {\n\t\t\t\t\t\t\tdeps.beginAgentGoalAccounting(goal);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdeps.stopAgentGoalAccounting(goal.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdeps.refreshGoalUi(ctx, goal);\n\t\t\t\t\t\tctx.ui.notify(`Goal ${goalStatusLabel(goal.status)}\\n${formatGoalForTool(goal)}`, \"info\");\n\t\t\t\t\t\tdeps.queueGoalContinuation(pi, ctx, goal);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tcase \"clear\": {\n\t\t\t\t\t\tawait deps.accountCurrentAgentTurn(ctx, \"active\");\n\t\t\t\t\t\tconst cleared = await clearGoal(deps.goalStoreRef(ctx));\n\t\t\t\t\t\tdeps.clearAgentGoalAccounting();\n\t\t\t\t\t\tdeps.refreshGoalUi(ctx, null);\n\t\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t\tcleared ? \"Goal cleared\" : \"No goal to clear\\nThis thread does not currently have a goal.\",\n\t\t\t\t\t\t\tcleared ? \"info\" : \"warning\",\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tctx.ui.notify(error instanceof Error ? error.message : String(error), \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n\nasync function setGoalObjective(\n\tpi: ExtensionAPI,\n\tctx: ExtensionContext,\n\tobjective: string,\n\tdeps: GoalCommandRegistrationDeps,\n): Promise<void> {\n\tconst ref = deps.goalStoreRef(ctx);\n\tconst current = await readGoal(ref);\n\tif (current !== null) {\n\t\tconst shouldReplace = await confirmReplaceGoal(ctx, objective);\n\t\tif (!shouldReplace) return;\n\t}\n\n\tif (current?.status === \"active\") {\n\t\tawait deps.accountCurrentAgentTurn(ctx, \"active\");\n\t}\n\tconst goal = current === null ? await createGoal(ref, objective) : await updateGoal(ref, { objective });\n\tif (goal.status === \"active\") deps.beginAgentGoalAccounting(goal);\n\tdeps.refreshGoalUi(ctx, goal);\n\tctx.ui.notify(`Goal ${goalStatusLabel(goal.status)}\\n${formatGoalForTool(goal)}`, \"info\");\n\tdeps.queueGoalContinuation(pi, ctx, goal);\n}\n\nasync function confirmReplaceGoal(ctx: ExtensionContext, objective: string): Promise<boolean> {\n\tif (!ctx.hasUI) return true;\n\tconst choice = await ctx.ui.select(`Replace goal?\\nNew objective: ${objective}`, [\n\t\tREPLACE_GOAL_CHOICE,\n\t\tCANCEL_REPLACE_GOAL_CHOICE,\n\t]);\n\treturn choice === REPLACE_GOAL_CHOICE;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AA2BrE,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAkL5D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,gBAAgB,CAAC;AAsBrE,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA2L5D"}
@@ -8,17 +8,17 @@ import { formatGoalForTool, goalStatusLabel } from "./format.js";
8
8
  import { buildContinuationPrompt } from "./prompt.js";
9
9
  import { accountGoalUsage, readGoal, updateGoal } from "./store.js";
10
10
  import { registerGoalTools } from "./tool-registration.js";
11
- import { isRecord } from "./types.js";
11
+ import { TurnUsageTracker } from "./turn-usage.js";
12
12
  import { updateGoalUi } from "./ui.js";
13
13
  const GOAL_CONTINUATION_MESSAGE_TYPE = "goal-continuation";
14
14
  const RESUME_GOAL_CHOICE = "Resume goal";
15
15
  const LEAVE_GOAL_PAUSED_CHOICE = "Leave paused";
16
- const EMPTY_USAGE = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0 };
17
16
  const STALE_EXTENSION_CONTEXT_ERROR_PREFIX = "This extension ctx is stale after session replacement or reload.";
18
17
  export default function goalExtension(pi) {
19
18
  let agentTurnInProgress = false;
20
19
  let agentGoalAccounting = null;
21
20
  let completedThisTurnGoalId = null;
21
+ const turnUsage = new TurnUsageTracker();
22
22
  const goalTicker = new GoalElapsedTicker({
23
23
  render: (renderCtx, renderGoal, live) => {
24
24
  try {
@@ -66,6 +66,7 @@ export default function goalExtension(pi) {
66
66
  pi.on("agent_start", async (_event, ctx) => {
67
67
  agentTurnInProgress = true;
68
68
  completedThisTurnGoalId = null;
69
+ turnUsage.reset();
69
70
  const goal = await readGoal(goalStoreRef(ctx));
70
71
  if (goal?.status === "active") {
71
72
  beginAgentGoalAccounting(goal);
@@ -74,9 +75,12 @@ export default function goalExtension(pi) {
74
75
  agentGoalAccounting = null;
75
76
  }
76
77
  });
78
+ pi.on("message_end", async (event) => {
79
+ turnUsage.noteMessageEnd(event.message);
80
+ });
77
81
  pi.on("agent_end", async (event, ctx) => {
78
82
  const mode = completedThisTurnGoalId === null ? "active" : "activeOrComplete";
79
- const goal = await accountCurrentAgentTurn(ctx, collectAssistantUsage(event.messages), mode);
83
+ const goal = await accountCurrentAgentTurn(ctx, mode, event.messages);
80
84
  agentTurnInProgress = false;
81
85
  completedThisTurnGoalId = null;
82
86
  if (goal?.status === "active") {
@@ -94,7 +98,7 @@ export default function goalExtension(pi) {
94
98
  });
95
99
  pi.on("session_shutdown", async (_event, ctx) => {
96
100
  if (agentGoalAccounting !== null) {
97
- await accountCurrentAgentTurn(ctx, EMPTY_USAGE, "active");
101
+ await accountCurrentAgentTurn(ctx, "active");
98
102
  }
99
103
  clearAgentGoalAccounting();
100
104
  goalTicker.stop();
@@ -121,6 +125,7 @@ export default function goalExtension(pi) {
121
125
  return;
122
126
  if (agentGoalAccounting?.goalId === goal.id)
123
127
  return;
128
+ turnUsage.discardPending();
124
129
  agentGoalAccounting = { goalId: goal.id, measuredFromMilliseconds: Date.now() };
125
130
  }
126
131
  function markGoalCompletedThisTurn(goal) {
@@ -161,11 +166,12 @@ export default function goalExtension(pi) {
161
166
  throw error;
162
167
  }
163
168
  }
164
- async function accountCurrentAgentTurn(ctx, usage, mode) {
169
+ async function accountCurrentAgentTurn(ctx, mode, agentRunMessages) {
165
170
  const accounting = agentGoalAccounting;
166
171
  const ref = goalStoreRef(ctx);
167
172
  if (accounting === null)
168
173
  return readGoal(ref);
174
+ const usage = agentRunMessages === undefined ? turnUsage.takePending() : turnUsage.takeRemaining(agentRunMessages);
169
175
  const now = Date.now();
170
176
  const elapsedSeconds = Math.max(0, Math.round((now - accounting.measuredFromMilliseconds) / 1000));
171
177
  const goal = await accountGoalUsage(ref, usage, elapsedSeconds, mode, accounting.goalId);
@@ -206,26 +212,4 @@ function goalStoreRef(ctx) {
206
212
  function cwdStoreKey(cwd) {
207
213
  return createHash("sha256").update(cwd).digest("hex").slice(0, 24);
208
214
  }
209
- function collectAssistantUsage(messages) {
210
- const usage = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0 };
211
- for (const message of messages) {
212
- if (!isAssistantUsageMessage(message))
213
- continue;
214
- usage.input += numericUsageField(message.usage, "input");
215
- usage.output += numericUsageField(message.usage, "output");
216
- usage.cacheRead += numericUsageField(message.usage, "cacheRead");
217
- usage.cacheWrite += numericUsageField(message.usage, "cacheWrite");
218
- usage.totalTokens += numericUsageField(message.usage, "totalTokens");
219
- }
220
- return usage;
221
- }
222
- function isAssistantUsageMessage(message) {
223
- if (!isRecord(message))
224
- return false;
225
- return message.role === "assistant" && isRecord(message.usage);
226
- }
227
- function numericUsageField(usage, key) {
228
- const value = usage[key];
229
- return typeof value === "number" && Number.isFinite(value) ? value : 0;
230
- }
231
215
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport { getAgentDir } from \"../../../../config.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { registerGoalCommand } from \"./command-registration.ts\";\nimport { shouldQueueGoalContinuationAfterAgentEnd, shouldQueueGoalContinuationWhenIdle } from \"./continuation.ts\";\nimport { GoalElapsedTicker } from \"./elapsed-ticker.ts\";\nimport { formatGoalForTool, goalStatusLabel } from \"./format.ts\";\nimport { buildContinuationPrompt } from \"./prompt.ts\";\nimport { accountGoalUsage, readGoal, updateGoal } from \"./store.ts\";\nimport { registerGoalTools } from \"./tool-registration.ts\";\nimport type { Goal, GoalAccountingMode, GoalStoreRef, TokenUsageSnapshot } from \"./types.ts\";\nimport { isRecord } from \"./types.ts\";\nimport { updateGoalUi } from \"./ui.ts\";\n\nconst GOAL_CONTINUATION_MESSAGE_TYPE = \"goal-continuation\";\nconst RESUME_GOAL_CHOICE = \"Resume goal\";\nconst LEAVE_GOAL_PAUSED_CHOICE = \"Leave paused\";\nconst EMPTY_USAGE: TokenUsageSnapshot = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0 };\nconst STALE_EXTENSION_CONTEXT_ERROR_PREFIX = \"This extension ctx is stale after session replacement or reload.\";\n\ntype AssistantUsageMessage = {\n\trole: \"assistant\";\n\tusage: Record<string, unknown>;\n};\ntype AgentGoalAccounting = {\n\tgoalId: string;\n\tmeasuredFromMilliseconds: number;\n};\n\nexport default function goalExtension(pi: ExtensionAPI): void {\n\tlet agentTurnInProgress = false;\n\tlet agentGoalAccounting: AgentGoalAccounting | null = null;\n\tlet completedThisTurnGoalId: string | null = null;\n\n\tconst goalTicker = new GoalElapsedTicker({\n\t\trender: (renderCtx, renderGoal, live) => {\n\t\t\ttry {\n\t\t\t\tupdateGoalUi(renderCtx, renderGoal, live);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof Error && error.message.startsWith(STALE_EXTENSION_CONTEXT_ERROR_PREFIX)) return;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t});\n\n\tregisterGoalTools(pi, {\n\t\tgoalStoreRef,\n\t\taccountCurrentAgentTurn,\n\t\tbeginAgentGoalAccounting,\n\t\tmarkGoalCompletedThisTurn,\n\t\trefreshGoalUi,\n\t});\n\tregisterGoalCommand(pi, {\n\t\tgoalStoreRef,\n\t\taccountCurrentAgentTurn,\n\t\tbeginAgentGoalAccounting,\n\t\tstopAgentGoalAccounting,\n\t\tclearAgentGoalAccounting,\n\t\tqueueGoalContinuation,\n\t\trefreshGoalUi,\n\t});\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\trefreshGoalUi(ctx, goal);\n\t\tif (await maybePromptResumePausedGoal(pi, ctx, event.reason, goal)) {\n\t\t\treturn;\n\t\t}\n\t\tif (shouldQueueGoalContinuationWhenIdle(goal, ctx.isIdle(), ctx.hasPendingMessages())) {\n\t\t\tqueueHiddenGoalPrompt(pi, buildContinuationPrompt(goal));\n\t\t}\n\t});\n\n\tpi.on(\"agent_start\", async (_event, ctx) => {\n\t\tagentTurnInProgress = true;\n\t\tcompletedThisTurnGoalId = null;\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tagentGoalAccounting = null;\n\t\t}\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\tconst mode: GoalAccountingMode = completedThisTurnGoalId === null ? \"active\" : \"activeOrComplete\";\n\t\tconst goal = await accountCurrentAgentTurn(ctx, collectAssistantUsage(event.messages), mode);\n\t\tagentTurnInProgress = false;\n\t\tcompletedThisTurnGoalId = null;\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\trefreshGoalUiBestEffort(ctx, goal);\n\t\tif (\n\t\t\tgoal?.status === \"active\" &&\n\t\t\t!ctx.signal?.aborted &&\n\t\t\tshouldQueueGoalContinuationAfterAgentEnd(goal, ctx.hasPendingMessages(), event.messages)\n\t\t) {\n\t\t\tqueueHiddenGoalPrompt(pi, buildContinuationPrompt(goal));\n\t\t}\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tif (agentGoalAccounting !== null) {\n\t\t\tawait accountCurrentAgentTurn(ctx, EMPTY_USAGE, \"active\");\n\t\t}\n\t\tclearAgentGoalAccounting();\n\t\tgoalTicker.stop();\n\t});\n\n\tasync function maybePromptResumePausedGoal(\n\t\tpi: ExtensionAPI,\n\t\tctx: ExtensionContext,\n\t\tsessionStartReason: string,\n\t\tgoal: Goal | null,\n\t): Promise<boolean> {\n\t\tif (!isResumeOfPausedGoal(ctx, sessionStartReason, goal)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst choice = await ctx.ui.select(`Resume paused goal?\\nGoal: ${goal.objective}`, [\n\t\t\tRESUME_GOAL_CHOICE,\n\t\t\tLEAVE_GOAL_PAUSED_CHOICE,\n\t\t]);\n\t\tif (choice !== RESUME_GOAL_CHOICE) return true;\n\n\t\tconst resumed = await updateGoal(goalStoreRef(ctx), { status: \"active\" });\n\t\tbeginAgentGoalAccounting(resumed);\n\t\trefreshGoalUi(ctx, resumed);\n\t\tctx.ui.notify(`Goal ${goalStatusLabel(resumed.status)}\\n${formatGoalForTool(resumed)}`, \"info\");\n\t\tqueueGoalContinuation(pi, ctx, resumed);\n\t\treturn true;\n\t}\n\n\tfunction beginAgentGoalAccounting(goal: Goal): void {\n\t\tif (goal.status !== \"active\") return;\n\t\tif (agentGoalAccounting?.goalId === goal.id) return;\n\t\tagentGoalAccounting = { goalId: goal.id, measuredFromMilliseconds: Date.now() };\n\t}\n\n\tfunction markGoalCompletedThisTurn(goal: Goal): void {\n\t\tif (!agentTurnInProgress) return;\n\t\tcompletedThisTurnGoalId = goal.id;\n\t\tagentGoalAccounting = { goalId: goal.id, measuredFromMilliseconds: Date.now() };\n\t}\n\n\tfunction stopAgentGoalAccounting(goalId: string): void {\n\t\tif (agentGoalAccounting?.goalId === goalId) {\n\t\t\tagentGoalAccounting = null;\n\t\t}\n\t\tif (completedThisTurnGoalId === goalId) {\n\t\t\tcompletedThisTurnGoalId = null;\n\t\t}\n\t}\n\n\tfunction clearAgentGoalAccounting(): void {\n\t\tagentGoalAccounting = null;\n\t\tcompletedThisTurnGoalId = null;\n\t}\n\n\tfunction refreshGoalUi(ctx: ExtensionContext, goal: Goal | null): void {\n\t\tconst accounting = agentGoalAccounting;\n\t\tif (ctx.hasUI && goal?.status === \"active\" && accounting?.goalId === goal.id) {\n\t\t\tgoalTicker.sync(ctx, goal, accounting.measuredFromMilliseconds);\n\t\t\treturn;\n\t\t}\n\t\tgoalTicker.stop();\n\t\tupdateGoalUi(ctx, goal);\n\t}\n\n\tfunction refreshGoalUiBestEffort(ctx: ExtensionContext, goal: Goal | null): void {\n\t\ttry {\n\t\t\trefreshGoalUi(ctx, goal);\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && error.message.startsWith(STALE_EXTENSION_CONTEXT_ERROR_PREFIX)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function accountCurrentAgentTurn(\n\t\tctx: ExtensionContext,\n\t\tusage: TokenUsageSnapshot,\n\t\tmode: GoalAccountingMode,\n\t): Promise<Goal | null> {\n\t\tconst accounting = agentGoalAccounting;\n\t\tconst ref = goalStoreRef(ctx);\n\t\tif (accounting === null) return readGoal(ref);\n\n\t\tconst now = Date.now();\n\t\tconst elapsedSeconds = Math.max(0, Math.round((now - accounting.measuredFromMilliseconds) / 1000));\n\t\tconst goal = await accountGoalUsage(ref, usage, elapsedSeconds, mode, accounting.goalId);\n\t\tif (goal?.id === accounting.goalId) {\n\t\t\tagentGoalAccounting = { goalId: accounting.goalId, measuredFromMilliseconds: now };\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\treturn goal;\n\t}\n}\n\nfunction isResumeOfPausedGoal(ctx: ExtensionContext, sessionStartReason: string, goal: Goal | null): goal is Goal {\n\treturn (\n\t\tsessionStartReason === \"resume\" &&\n\t\tgoal?.status === \"paused\" &&\n\t\tctx.hasUI &&\n\t\tctx.isIdle() &&\n\t\t!ctx.hasPendingMessages()\n\t);\n}\n\nfunction queueGoalContinuation(pi: ExtensionAPI, ctx: ExtensionContext, goal: Goal): void {\n\tif (shouldQueueGoalContinuationWhenIdle(goal, ctx.isIdle(), ctx.hasPendingMessages())) {\n\t\tqueueHiddenGoalPrompt(pi, buildContinuationPrompt(goal));\n\t}\n}\n\nfunction queueHiddenGoalPrompt(pi: ExtensionAPI, content: string): void {\n\tpi.sendMessage(\n\t\t{ customType: GOAL_CONTINUATION_MESSAGE_TYPE, content, display: false },\n\t\t{ triggerTurn: true, deliverAs: \"followUp\" },\n\t);\n}\n\nfunction goalStoreRef(ctx: ExtensionContext): GoalStoreRef {\n\tconst sessionFile = ctx.sessionManager.getSessionFile();\n\tconst baseDir =\n\t\tsessionFile === undefined\n\t\t\t? join(getAgentDir(), \"extensions\", \"goal\", \"no-session\", cwdStoreKey(ctx.cwd))\n\t\t\t: join(ctx.sessionManager.getSessionDir(), \"extensions\", \"goal\");\n\n\treturn {\n\t\tbaseDir,\n\t\tthreadId: ctx.sessionManager.getSessionId(),\n\t};\n}\n\nfunction cwdStoreKey(cwd: string): string {\n\treturn createHash(\"sha256\").update(cwd).digest(\"hex\").slice(0, 24);\n}\n\nfunction collectAssistantUsage(messages: unknown[]): TokenUsageSnapshot {\n\tconst usage: TokenUsageSnapshot = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, totalTokens: 0 };\n\tfor (const message of messages) {\n\t\tif (!isAssistantUsageMessage(message)) continue;\n\t\tusage.input += numericUsageField(message.usage, \"input\");\n\t\tusage.output += numericUsageField(message.usage, \"output\");\n\t\tusage.cacheRead += numericUsageField(message.usage, \"cacheRead\");\n\t\tusage.cacheWrite += numericUsageField(message.usage, \"cacheWrite\");\n\t\tusage.totalTokens += numericUsageField(message.usage, \"totalTokens\");\n\t}\n\treturn usage;\n}\n\nfunction isAssistantUsageMessage(message: unknown): message is AssistantUsageMessage {\n\tif (!isRecord(message)) return false;\n\treturn message.role === \"assistant\" && isRecord(message.usage);\n}\n\nfunction numericUsageField(usage: Record<string, unknown>, key: string): number {\n\tconst value = usage[key];\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : 0;\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/goal/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\nimport { join } from \"node:path\";\nimport { getAgentDir } from \"../../../../config.ts\";\nimport type { ExtensionAPI, ExtensionContext } from \"../../types.ts\";\nimport { registerGoalCommand } from \"./command-registration.ts\";\nimport { shouldQueueGoalContinuationAfterAgentEnd, shouldQueueGoalContinuationWhenIdle } from \"./continuation.ts\";\nimport { GoalElapsedTicker } from \"./elapsed-ticker.ts\";\nimport { formatGoalForTool, goalStatusLabel } from \"./format.ts\";\nimport { buildContinuationPrompt } from \"./prompt.ts\";\nimport { accountGoalUsage, readGoal, updateGoal } from \"./store.ts\";\nimport { registerGoalTools } from \"./tool-registration.ts\";\nimport { TurnUsageTracker } from \"./turn-usage.ts\";\nimport type { Goal, GoalAccountingMode, GoalStoreRef } from \"./types.ts\";\nimport { updateGoalUi } from \"./ui.ts\";\n\nconst GOAL_CONTINUATION_MESSAGE_TYPE = \"goal-continuation\";\nconst RESUME_GOAL_CHOICE = \"Resume goal\";\nconst LEAVE_GOAL_PAUSED_CHOICE = \"Leave paused\";\nconst STALE_EXTENSION_CONTEXT_ERROR_PREFIX = \"This extension ctx is stale after session replacement or reload.\";\n\ntype AgentGoalAccounting = {\n\tgoalId: string;\n\tmeasuredFromMilliseconds: number;\n};\n\nexport default function goalExtension(pi: ExtensionAPI): void {\n\tlet agentTurnInProgress = false;\n\tlet agentGoalAccounting: AgentGoalAccounting | null = null;\n\tlet completedThisTurnGoalId: string | null = null;\n\tconst turnUsage = new TurnUsageTracker();\n\n\tconst goalTicker = new GoalElapsedTicker({\n\t\trender: (renderCtx, renderGoal, live) => {\n\t\t\ttry {\n\t\t\t\tupdateGoalUi(renderCtx, renderGoal, live);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof Error && error.message.startsWith(STALE_EXTENSION_CONTEXT_ERROR_PREFIX)) return;\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t},\n\t});\n\n\tregisterGoalTools(pi, {\n\t\tgoalStoreRef,\n\t\taccountCurrentAgentTurn,\n\t\tbeginAgentGoalAccounting,\n\t\tmarkGoalCompletedThisTurn,\n\t\trefreshGoalUi,\n\t});\n\tregisterGoalCommand(pi, {\n\t\tgoalStoreRef,\n\t\taccountCurrentAgentTurn,\n\t\tbeginAgentGoalAccounting,\n\t\tstopAgentGoalAccounting,\n\t\tclearAgentGoalAccounting,\n\t\tqueueGoalContinuation,\n\t\trefreshGoalUi,\n\t});\n\n\tpi.on(\"session_start\", async (event, ctx) => {\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\trefreshGoalUi(ctx, goal);\n\t\tif (await maybePromptResumePausedGoal(pi, ctx, event.reason, goal)) {\n\t\t\treturn;\n\t\t}\n\t\tif (shouldQueueGoalContinuationWhenIdle(goal, ctx.isIdle(), ctx.hasPendingMessages())) {\n\t\t\tqueueHiddenGoalPrompt(pi, buildContinuationPrompt(goal));\n\t\t}\n\t});\n\n\tpi.on(\"agent_start\", async (_event, ctx) => {\n\t\tagentTurnInProgress = true;\n\t\tcompletedThisTurnGoalId = null;\n\t\tturnUsage.reset();\n\t\tconst goal = await readGoal(goalStoreRef(ctx));\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tagentGoalAccounting = null;\n\t\t}\n\t});\n\n\tpi.on(\"message_end\", async (event) => {\n\t\tturnUsage.noteMessageEnd(event.message);\n\t});\n\n\tpi.on(\"agent_end\", async (event, ctx) => {\n\t\tconst mode: GoalAccountingMode = completedThisTurnGoalId === null ? \"active\" : \"activeOrComplete\";\n\t\tconst goal = await accountCurrentAgentTurn(ctx, mode, event.messages);\n\t\tagentTurnInProgress = false;\n\t\tcompletedThisTurnGoalId = null;\n\t\tif (goal?.status === \"active\") {\n\t\t\tbeginAgentGoalAccounting(goal);\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\trefreshGoalUiBestEffort(ctx, goal);\n\t\tif (\n\t\t\tgoal?.status === \"active\" &&\n\t\t\t!ctx.signal?.aborted &&\n\t\t\tshouldQueueGoalContinuationAfterAgentEnd(goal, ctx.hasPendingMessages(), event.messages)\n\t\t) {\n\t\t\tqueueHiddenGoalPrompt(pi, buildContinuationPrompt(goal));\n\t\t}\n\t});\n\n\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\tif (agentGoalAccounting !== null) {\n\t\t\tawait accountCurrentAgentTurn(ctx, \"active\");\n\t\t}\n\t\tclearAgentGoalAccounting();\n\t\tgoalTicker.stop();\n\t});\n\n\tasync function maybePromptResumePausedGoal(\n\t\tpi: ExtensionAPI,\n\t\tctx: ExtensionContext,\n\t\tsessionStartReason: string,\n\t\tgoal: Goal | null,\n\t): Promise<boolean> {\n\t\tif (!isResumeOfPausedGoal(ctx, sessionStartReason, goal)) {\n\t\t\treturn false;\n\t\t}\n\n\t\tconst choice = await ctx.ui.select(`Resume paused goal?\\nGoal: ${goal.objective}`, [\n\t\t\tRESUME_GOAL_CHOICE,\n\t\t\tLEAVE_GOAL_PAUSED_CHOICE,\n\t\t]);\n\t\tif (choice !== RESUME_GOAL_CHOICE) return true;\n\n\t\tconst resumed = await updateGoal(goalStoreRef(ctx), { status: \"active\" });\n\t\tbeginAgentGoalAccounting(resumed);\n\t\trefreshGoalUi(ctx, resumed);\n\t\tctx.ui.notify(`Goal ${goalStatusLabel(resumed.status)}\\n${formatGoalForTool(resumed)}`, \"info\");\n\t\tqueueGoalContinuation(pi, ctx, resumed);\n\t\treturn true;\n\t}\n\n\tfunction beginAgentGoalAccounting(goal: Goal): void {\n\t\tif (goal.status !== \"active\") return;\n\t\tif (agentGoalAccounting?.goalId === goal.id) return;\n\t\tturnUsage.discardPending();\n\t\tagentGoalAccounting = { goalId: goal.id, measuredFromMilliseconds: Date.now() };\n\t}\n\n\tfunction markGoalCompletedThisTurn(goal: Goal): void {\n\t\tif (!agentTurnInProgress) return;\n\t\tcompletedThisTurnGoalId = goal.id;\n\t\tagentGoalAccounting = { goalId: goal.id, measuredFromMilliseconds: Date.now() };\n\t}\n\n\tfunction stopAgentGoalAccounting(goalId: string): void {\n\t\tif (agentGoalAccounting?.goalId === goalId) {\n\t\t\tagentGoalAccounting = null;\n\t\t}\n\t\tif (completedThisTurnGoalId === goalId) {\n\t\t\tcompletedThisTurnGoalId = null;\n\t\t}\n\t}\n\n\tfunction clearAgentGoalAccounting(): void {\n\t\tagentGoalAccounting = null;\n\t\tcompletedThisTurnGoalId = null;\n\t}\n\n\tfunction refreshGoalUi(ctx: ExtensionContext, goal: Goal | null): void {\n\t\tconst accounting = agentGoalAccounting;\n\t\tif (ctx.hasUI && goal?.status === \"active\" && accounting?.goalId === goal.id) {\n\t\t\tgoalTicker.sync(ctx, goal, accounting.measuredFromMilliseconds);\n\t\t\treturn;\n\t\t}\n\t\tgoalTicker.stop();\n\t\tupdateGoalUi(ctx, goal);\n\t}\n\n\tfunction refreshGoalUiBestEffort(ctx: ExtensionContext, goal: Goal | null): void {\n\t\ttry {\n\t\t\trefreshGoalUi(ctx, goal);\n\t\t} catch (error) {\n\t\t\tif (error instanceof Error && error.message.startsWith(STALE_EXTENSION_CONTEXT_ERROR_PREFIX)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tasync function accountCurrentAgentTurn(\n\t\tctx: ExtensionContext,\n\t\tmode: GoalAccountingMode,\n\t\tagentRunMessages?: unknown[],\n\t): Promise<Goal | null> {\n\t\tconst accounting = agentGoalAccounting;\n\t\tconst ref = goalStoreRef(ctx);\n\t\tif (accounting === null) return readGoal(ref);\n\n\t\tconst usage =\n\t\t\tagentRunMessages === undefined ? turnUsage.takePending() : turnUsage.takeRemaining(agentRunMessages);\n\t\tconst now = Date.now();\n\t\tconst elapsedSeconds = Math.max(0, Math.round((now - accounting.measuredFromMilliseconds) / 1000));\n\t\tconst goal = await accountGoalUsage(ref, usage, elapsedSeconds, mode, accounting.goalId);\n\t\tif (goal?.id === accounting.goalId) {\n\t\t\tagentGoalAccounting = { goalId: accounting.goalId, measuredFromMilliseconds: now };\n\t\t} else {\n\t\t\tclearAgentGoalAccounting();\n\t\t}\n\t\treturn goal;\n\t}\n}\n\nfunction isResumeOfPausedGoal(ctx: ExtensionContext, sessionStartReason: string, goal: Goal | null): goal is Goal {\n\treturn (\n\t\tsessionStartReason === \"resume\" &&\n\t\tgoal?.status === \"paused\" &&\n\t\tctx.hasUI &&\n\t\tctx.isIdle() &&\n\t\t!ctx.hasPendingMessages()\n\t);\n}\n\nfunction queueGoalContinuation(pi: ExtensionAPI, ctx: ExtensionContext, goal: Goal): void {\n\tif (shouldQueueGoalContinuationWhenIdle(goal, ctx.isIdle(), ctx.hasPendingMessages())) {\n\t\tqueueHiddenGoalPrompt(pi, buildContinuationPrompt(goal));\n\t}\n}\n\nfunction queueHiddenGoalPrompt(pi: ExtensionAPI, content: string): void {\n\tpi.sendMessage(\n\t\t{ customType: GOAL_CONTINUATION_MESSAGE_TYPE, content, display: false },\n\t\t{ triggerTurn: true, deliverAs: \"followUp\" },\n\t);\n}\n\nfunction goalStoreRef(ctx: ExtensionContext): GoalStoreRef {\n\tconst sessionFile = ctx.sessionManager.getSessionFile();\n\tconst baseDir =\n\t\tsessionFile === undefined\n\t\t\t? join(getAgentDir(), \"extensions\", \"goal\", \"no-session\", cwdStoreKey(ctx.cwd))\n\t\t\t: join(ctx.sessionManager.getSessionDir(), \"extensions\", \"goal\");\n\n\treturn {\n\t\tbaseDir,\n\t\tthreadId: ctx.sessionManager.getSessionId(),\n\t};\n}\n\nfunction cwdStoreKey(cwd: string): string {\n\treturn createHash(\"sha256\").update(cwd).digest(\"hex\").slice(0, 24);\n}\n"]}