@earendil-works/pi-coding-agent 0.85.0 → 0.86.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (544) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/README.md +2 -3
  3. package/dist/bun/cli.d.ts +3 -1
  4. package/dist/bun/cli.d.ts.map +1 -1
  5. package/dist/bun/cli.js +3 -12
  6. package/dist/bun/cli.js.map +1 -1
  7. package/dist/bun/sandbox-env-setup.d.ts +2 -0
  8. package/dist/bun/sandbox-env-setup.d.ts.map +1 -0
  9. package/dist/bun/sandbox-env-setup.js +4 -0
  10. package/dist/bun/sandbox-env-setup.js.map +1 -0
  11. package/dist/bundle/chunks/anthropic-messages-MYU5ZMRF.js +6 -0
  12. package/dist/bundle/chunks/azure-openai-responses-HUSQ3GP2.js +2 -0
  13. package/dist/bundle/chunks/bedrock-converse-stream.js +47 -38
  14. package/dist/bundle/chunks/chunk-7IOYH2SY.js +2 -0
  15. package/dist/bundle/chunks/chunk-7YM6BE7Y.js +1561 -0
  16. package/dist/bundle/chunks/chunk-A3JYRWB6.js +2 -0
  17. package/dist/bundle/chunks/chunk-DTD7JQ7Y.js +42 -0
  18. package/dist/bundle/chunks/chunk-FUXEF6JQ.js +44 -0
  19. package/dist/bundle/chunks/{chunk-IDDQWTHI.js → chunk-RCZIEVGO.js} +10 -1
  20. package/dist/bundle/chunks/chunk-S7SZN6Z3.js +2 -0
  21. package/dist/bundle/chunks/chunk-WIUZI2CJ.js +11 -0
  22. package/dist/bundle/chunks/github-copilot.js +1 -1
  23. package/dist/bundle/chunks/google-generative-ai-IMS5EK2Y.js +2 -0
  24. package/dist/bundle/chunks/google-vertex-O4YJEQUW.js +2 -0
  25. package/dist/bundle/chunks/jiti-loader-C3NU2SDH.js +21 -0
  26. package/dist/bundle/chunks/jiti-static-loader-E6ANQD5T.js +2 -0
  27. package/dist/bundle/chunks/mistral-conversations-NOSQHBEY.js +5 -0
  28. package/dist/bundle/chunks/{node-EM5FIVUN.js → node-O3RIBJRH.js} +1 -1
  29. package/dist/bundle/chunks/openai-codex-responses-QDSOTBBO.js +10 -0
  30. package/dist/bundle/chunks/openai-completions-KQPOPEVM.js +7 -0
  31. package/dist/bundle/chunks/openai-responses-HWEUZ6WZ.js +2 -0
  32. package/dist/bundle/chunks/{pi-messages-EGZIFQGG.js → pi-messages-GFKBWJHZ.js} +1 -1
  33. package/dist/bundle/chunks/virtual-modules-XW5APVUE.js +2 -0
  34. package/dist/bundle/cli.js +1 -1
  35. package/dist/bundle/index.js +1 -1
  36. package/dist/bundle/rpc-entry.js +1 -1
  37. package/dist/cli/args.d.ts.map +1 -1
  38. package/dist/cli/args.js +0 -2
  39. package/dist/cli/args.js.map +1 -1
  40. package/dist/cli/session-picker.d.ts +1 -1
  41. package/dist/cli/session-picker.d.ts.map +1 -1
  42. package/dist/cli/session-picker.js.map +1 -1
  43. package/dist/cli/setup.d.ts +2 -0
  44. package/dist/cli/setup.d.ts.map +1 -0
  45. package/dist/cli/setup.js +12 -0
  46. package/dist/cli/setup.js.map +1 -0
  47. package/dist/cli.d.ts.map +1 -1
  48. package/dist/cli.js +3 -25
  49. package/dist/cli.js.map +1 -1
  50. package/dist/config.d.ts.map +1 -1
  51. package/dist/config.js +1 -1
  52. package/dist/config.js.map +1 -1
  53. package/dist/core/agent-session.d.ts +56 -6
  54. package/dist/core/agent-session.d.ts.map +1 -1
  55. package/dist/core/agent-session.js +293 -155
  56. package/dist/core/agent-session.js.map +1 -1
  57. package/dist/core/bug-report-upload.d.ts +12 -0
  58. package/dist/core/bug-report-upload.d.ts.map +1 -0
  59. package/dist/core/bug-report-upload.js +22 -0
  60. package/dist/core/bug-report-upload.js.map +1 -0
  61. package/dist/core/bug-report.d.ts +176 -0
  62. package/dist/core/bug-report.d.ts.map +1 -0
  63. package/dist/core/bug-report.js +292 -0
  64. package/dist/core/bug-report.js.map +1 -0
  65. package/dist/core/cache-stats.d.ts.map +1 -1
  66. package/dist/core/cache-stats.js +12 -1
  67. package/dist/core/cache-stats.js.map +1 -1
  68. package/dist/core/cache-warmer.d.ts +102 -0
  69. package/dist/core/cache-warmer.d.ts.map +1 -0
  70. package/dist/core/cache-warmer.js +342 -0
  71. package/dist/core/cache-warmer.js.map +1 -0
  72. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  73. package/dist/core/compaction/branch-summarization.js +2 -2
  74. package/dist/core/compaction/branch-summarization.js.map +1 -1
  75. package/dist/core/compaction/compaction.d.ts +2 -2
  76. package/dist/core/compaction/compaction.d.ts.map +1 -1
  77. package/dist/core/compaction/compaction.js +11 -12
  78. package/dist/core/compaction/compaction.js.map +1 -1
  79. package/dist/core/crash-log.d.ts +22 -0
  80. package/dist/core/crash-log.d.ts.map +1 -0
  81. package/dist/core/crash-log.js +71 -0
  82. package/dist/core/crash-log.js.map +1 -0
  83. package/dist/core/experimental.d.ts +0 -4
  84. package/dist/core/experimental.d.ts.map +1 -1
  85. package/dist/core/experimental.js +0 -4
  86. package/dist/core/experimental.js.map +1 -1
  87. package/dist/core/extensions/index.d.ts +1 -1
  88. package/dist/core/extensions/index.d.ts.map +1 -1
  89. package/dist/core/extensions/index.js.map +1 -1
  90. package/dist/core/extensions/jiti-loader.d.ts +2 -0
  91. package/dist/core/extensions/jiti-loader.d.ts.map +1 -0
  92. package/dist/core/extensions/jiti-loader.js +4 -0
  93. package/dist/core/extensions/jiti-loader.js.map +1 -0
  94. package/dist/core/extensions/jiti-static-loader.d.ts +2 -0
  95. package/dist/core/extensions/jiti-static-loader.d.ts.map +1 -0
  96. package/dist/core/extensions/jiti-static-loader.js +4 -0
  97. package/dist/core/extensions/jiti-static-loader.js.map +1 -0
  98. package/dist/core/extensions/loader.d.ts.map +1 -1
  99. package/dist/core/extensions/loader.js +38 -51
  100. package/dist/core/extensions/loader.js.map +1 -1
  101. package/dist/core/extensions/runner.d.ts +10 -7
  102. package/dist/core/extensions/runner.d.ts.map +1 -1
  103. package/dist/core/extensions/runner.js +85 -67
  104. package/dist/core/extensions/runner.js.map +1 -1
  105. package/dist/core/extensions/types.d.ts +60 -50
  106. package/dist/core/extensions/types.d.ts.map +1 -1
  107. package/dist/core/extensions/types.js.map +1 -1
  108. package/dist/core/extensions/virtual-modules.d.ts +3 -0
  109. package/dist/core/extensions/virtual-modules.d.ts.map +1 -0
  110. package/dist/core/extensions/virtual-modules.js +38 -0
  111. package/dist/core/extensions/virtual-modules.js.map +1 -0
  112. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  113. package/dist/core/extensions/wrapper.js +1 -20
  114. package/dist/core/extensions/wrapper.js.map +1 -1
  115. package/dist/core/index.d.ts +2 -1
  116. package/dist/core/index.d.ts.map +1 -1
  117. package/dist/core/index.js.map +1 -1
  118. package/dist/core/keybindings.d.ts +6 -1
  119. package/dist/core/keybindings.d.ts.map +1 -1
  120. package/dist/core/keybindings.js +5 -1
  121. package/dist/core/keybindings.js.map +1 -1
  122. package/dist/core/messages.d.ts.map +1 -1
  123. package/dist/core/messages.js +1 -0
  124. package/dist/core/messages.js.map +1 -1
  125. package/dist/core/model-config.d.ts +101 -20
  126. package/dist/core/model-config.d.ts.map +1 -1
  127. package/dist/core/model-config.js +25 -18
  128. package/dist/core/model-config.js.map +1 -1
  129. package/dist/core/model-registry.d.ts +5 -1
  130. package/dist/core/model-registry.d.ts.map +1 -1
  131. package/dist/core/model-registry.js +8 -0
  132. package/dist/core/model-registry.js.map +1 -1
  133. package/dist/core/model-resolver.d.ts.map +1 -1
  134. package/dist/core/model-resolver.js +1 -1
  135. package/dist/core/model-resolver.js.map +1 -1
  136. package/dist/core/model-runtime.d.ts.map +1 -1
  137. package/dist/core/model-runtime.js +5 -3
  138. package/dist/core/model-runtime.js.map +1 -1
  139. package/dist/core/provider-composer.d.ts +3 -2
  140. package/dist/core/provider-composer.d.ts.map +1 -1
  141. package/dist/core/provider-composer.js +2 -0
  142. package/dist/core/provider-composer.js.map +1 -1
  143. package/dist/core/radius.d.ts +3 -0
  144. package/dist/core/radius.d.ts.map +1 -1
  145. package/dist/core/radius.js +6 -0
  146. package/dist/core/radius.js.map +1 -1
  147. package/dist/core/sdk.d.ts.map +1 -1
  148. package/dist/core/sdk.js +60 -38
  149. package/dist/core/sdk.js.map +1 -1
  150. package/dist/core/session-export.d.ts +6 -2
  151. package/dist/core/session-export.d.ts.map +1 -1
  152. package/dist/core/session-export.js +14 -13
  153. package/dist/core/session-export.js.map +1 -1
  154. package/dist/core/session-manager.d.ts +29 -6
  155. package/dist/core/session-manager.d.ts.map +1 -1
  156. package/dist/core/session-manager.js +159 -96
  157. package/dist/core/session-manager.js.map +1 -1
  158. package/dist/core/settings-manager.d.ts +20 -4
  159. package/dist/core/settings-manager.d.ts.map +1 -1
  160. package/dist/core/settings-manager.js +43 -7
  161. package/dist/core/settings-manager.js.map +1 -1
  162. package/dist/core/slash-commands.d.ts.map +1 -1
  163. package/dist/core/slash-commands.js +1 -0
  164. package/dist/core/slash-commands.js.map +1 -1
  165. package/dist/core/system-prompt.d.ts +49 -6
  166. package/dist/core/system-prompt.d.ts.map +1 -1
  167. package/dist/core/system-prompt.js +121 -92
  168. package/dist/core/system-prompt.js.map +1 -1
  169. package/dist/core/tools/bash.d.ts +2 -1
  170. package/dist/core/tools/bash.d.ts.map +1 -1
  171. package/dist/core/tools/bash.js +10 -4
  172. package/dist/core/tools/bash.js.map +1 -1
  173. package/dist/core/tools/edit.d.ts.map +1 -1
  174. package/dist/core/tools/edit.js +1 -2
  175. package/dist/core/tools/edit.js.map +1 -1
  176. package/dist/core/tools/read.d.ts.map +1 -1
  177. package/dist/core/tools/read.js +1 -2
  178. package/dist/core/tools/read.js.map +1 -1
  179. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  180. package/dist/core/tools/renderers/bash.js +9 -1
  181. package/dist/core/tools/renderers/bash.js.map +1 -1
  182. package/dist/core/tools/write.d.ts.map +1 -1
  183. package/dist/core/tools/write.js +1 -2
  184. package/dist/core/tools/write.js.map +1 -1
  185. package/dist/core/usage-totals.d.ts +1 -1
  186. package/dist/core/usage-totals.d.ts.map +1 -1
  187. package/dist/core/usage-totals.js +5 -1
  188. package/dist/core/usage-totals.js.map +1 -1
  189. package/dist/extensions/llama/client.d.ts +2 -0
  190. package/dist/extensions/llama/client.d.ts.map +1 -1
  191. package/dist/extensions/llama/client.js +7 -3
  192. package/dist/extensions/llama/client.js.map +1 -1
  193. package/dist/extensions/llama/provider.d.ts.map +1 -1
  194. package/dist/extensions/llama/provider.js +20 -5
  195. package/dist/extensions/llama/provider.js.map +1 -1
  196. package/dist/index.d.ts +3 -2
  197. package/dist/index.d.ts.map +1 -1
  198. package/dist/index.js.map +1 -1
  199. package/dist/main.d.ts.map +1 -1
  200. package/dist/main.js +13 -131
  201. package/dist/main.js.map +1 -1
  202. package/dist/migrations.d.ts.map +1 -1
  203. package/dist/migrations.js +2 -2
  204. package/dist/migrations.js.map +1 -1
  205. package/dist/modes/interactive/bug-report.d.ts +14 -0
  206. package/dist/modes/interactive/bug-report.d.ts.map +1 -0
  207. package/dist/modes/interactive/bug-report.js +209 -0
  208. package/dist/modes/interactive/bug-report.js.map +1 -0
  209. package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
  210. package/dist/modes/interactive/chat-viewport.js +1 -1
  211. package/dist/modes/interactive/chat-viewport.js.map +1 -1
  212. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  213. package/dist/modes/interactive/components/branch-summary-message.js +12 -5
  214. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  215. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  216. package/dist/modes/interactive/components/compaction-summary-message.js +12 -5
  217. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  218. package/dist/modes/interactive/components/custom-editor.d.ts +3 -3
  219. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  220. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  221. package/dist/modes/interactive/components/extension-input.d.ts +2 -0
  222. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  223. package/dist/modes/interactive/components/extension-input.js +6 -0
  224. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  225. package/dist/modes/interactive/components/extension-selector.d.ts +1 -0
  226. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  227. package/dist/modes/interactive/components/extension-selector.js +4 -0
  228. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  229. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  230. package/dist/modes/interactive/components/footer.js +4 -1
  231. package/dist/modes/interactive/components/footer.js.map +1 -1
  232. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  233. package/dist/modes/interactive/components/model-selector.js +5 -5
  234. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  235. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  236. package/dist/modes/interactive/components/scoped-models-selector.js +8 -8
  237. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  238. package/dist/modes/interactive/components/session-selector.d.ts +5 -5
  239. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  240. package/dist/modes/interactive/components/session-selector.js +74 -48
  241. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  242. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  243. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  244. package/dist/modes/interactive/components/settings-selector.js +11 -0
  245. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  246. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  247. package/dist/modes/interactive/components/skill-invocation-message.js +11 -4
  248. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  249. package/dist/modes/interactive/components/status-indicator.d.ts +2 -2
  250. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  251. package/dist/modes/interactive/components/status-indicator.js +7 -7
  252. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  253. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  254. package/dist/modes/interactive/components/thinking-selector.js +4 -4
  255. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  256. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  257. package/dist/modes/interactive/components/tool-execution.js +18 -9
  258. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  259. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  260. package/dist/modes/interactive/components/tree-selector.js +2 -0
  261. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  262. package/dist/modes/interactive/interactive-mode.d.ts +13 -1
  263. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  264. package/dist/modes/interactive/interactive-mode.js +220 -84
  265. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  266. package/dist/modes/interactive/session-share.d.ts +2 -0
  267. package/dist/modes/interactive/session-share.d.ts.map +1 -1
  268. package/dist/modes/interactive/session-share.js +8 -4
  269. package/dist/modes/interactive/session-share.js.map +1 -1
  270. package/dist/modes/interactive/tui-renderer.d.ts.map +1 -1
  271. package/dist/modes/interactive/tui-renderer.js +2 -2
  272. package/dist/modes/interactive/tui-renderer.js.map +1 -1
  273. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  274. package/dist/modes/rpc/rpc-mode.js +2 -2
  275. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  276. package/dist/utils/clipboard-command.d.ts +7 -0
  277. package/dist/utils/clipboard-command.d.ts.map +1 -0
  278. package/dist/utils/clipboard-command.js +45 -0
  279. package/dist/utils/clipboard-command.js.map +1 -0
  280. package/dist/utils/clipboard-image.d.ts.map +1 -1
  281. package/dist/utils/clipboard-image.js +52 -69
  282. package/dist/utils/clipboard-image.js.map +1 -1
  283. package/dist/utils/clipboard.d.ts.map +1 -1
  284. package/dist/utils/clipboard.js +61 -125
  285. package/dist/utils/clipboard.js.map +1 -1
  286. package/dist/utils/zip.d.ts +7 -0
  287. package/dist/utils/zip.d.ts.map +1 -0
  288. package/dist/utils/zip.js +60 -0
  289. package/dist/utils/zip.js.map +1 -0
  290. package/docs/compaction.md +39 -13
  291. package/docs/containerization.md +45 -0
  292. package/docs/custom-provider.md +22 -13
  293. package/docs/development.md +23 -4
  294. package/docs/docs.json +4 -0
  295. package/docs/environment-variables.md +3 -2
  296. package/docs/extensions.md +57 -43
  297. package/docs/json.md +4 -4
  298. package/docs/keybindings.md +2 -1
  299. package/docs/models.md +34 -3
  300. package/docs/providers.md +2 -2
  301. package/docs/sdk.md +4 -2
  302. package/docs/security.md +1 -1
  303. package/docs/session-format.md +82 -40
  304. package/docs/sessions.md +27 -0
  305. package/docs/settings.md +60 -1
  306. package/docs/termux.md +0 -1
  307. package/docs/tui.md +2 -2
  308. package/docs/usage.md +1 -0
  309. package/examples/extensions/README.md +0 -1
  310. package/examples/extensions/custom-provider-anthropic/index.ts +18 -12
  311. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  312. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  313. package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -2
  314. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  315. package/examples/extensions/gondolin/package-lock.json +2 -2
  316. package/examples/extensions/gondolin/package.json +1 -1
  317. package/examples/extensions/prompt-customizer.ts +19 -67
  318. package/examples/extensions/sandbox/package-lock.json +2 -2
  319. package/examples/extensions/sandbox/package.json +1 -1
  320. package/examples/extensions/with-deps/package-lock.json +2 -2
  321. package/examples/extensions/with-deps/package.json +1 -1
  322. package/npm-shrinkwrap.json +425 -778
  323. package/package.json +22 -27
  324. package/dist/bundle/chunks/anthropic-messages-QAQLEQIY.js +0 -6
  325. package/dist/bundle/chunks/azure-openai-responses-Q7MJBRE6.js +0 -2
  326. package/dist/bundle/chunks/chunk-2KVJKXS2.js +0 -50
  327. package/dist/bundle/chunks/chunk-AXIIZGTV.js +0 -2
  328. package/dist/bundle/chunks/chunk-EQ6DR6XK.js +0 -5
  329. package/dist/bundle/chunks/chunk-GMWCTUPB.js +0 -2
  330. package/dist/bundle/chunks/chunk-LZKJTKCT.js +0 -2
  331. package/dist/bundle/chunks/chunk-OUXLLA64.js +0 -11
  332. package/dist/bundle/chunks/chunk-R7UUJ4C2.js +0 -42
  333. package/dist/bundle/chunks/chunk-UAQELI3K.js +0 -2
  334. package/dist/bundle/chunks/chunk-WBE4J4AU.js +0 -9
  335. package/dist/bundle/chunks/chunk-WZB2R5YO.js +0 -1558
  336. package/dist/bundle/chunks/google-generative-ai-BSMTYDAM.js +0 -2
  337. package/dist/bundle/chunks/google-vertex-5C3HASOJ.js +0 -2
  338. package/dist/bundle/chunks/mistral-conversations-4M6BZBX6.js +0 -5
  339. package/dist/bundle/chunks/openai-codex-responses-YJOO52RW.js +0 -10
  340. package/dist/bundle/chunks/openai-completions-QOT3QX7D.js +0 -7
  341. package/dist/bundle/chunks/openai-responses-U7LNPQN4.js +0 -2
  342. package/dist/bundle/client.js +0 -2
  343. package/dist/bundle/coordinator.js +0 -3
  344. package/dist/cli/experimental/cli.d.ts +0 -10
  345. package/dist/cli/experimental/cli.d.ts.map +0 -1
  346. package/dist/cli/experimental/cli.js +0 -9
  347. package/dist/cli/experimental/cli.js.map +0 -1
  348. package/dist/cli/experimental/command-options.d.ts +0 -28
  349. package/dist/cli/experimental/command-options.d.ts.map +0 -1
  350. package/dist/cli/experimental/command-options.js +0 -84
  351. package/dist/cli/experimental/command-options.js.map +0 -1
  352. package/dist/cli/experimental/command.d.ts +0 -70
  353. package/dist/cli/experimental/command.d.ts.map +0 -1
  354. package/dist/cli/experimental/command.js +0 -144
  355. package/dist/cli/experimental/command.js.map +0 -1
  356. package/dist/cli/experimental/commands/client.d.ts +0 -19
  357. package/dist/cli/experimental/commands/client.d.ts.map +0 -1
  358. package/dist/cli/experimental/commands/client.js +0 -63
  359. package/dist/cli/experimental/commands/client.js.map +0 -1
  360. package/dist/cli/experimental/commands/server.d.ts +0 -17
  361. package/dist/cli/experimental/commands/server.d.ts.map +0 -1
  362. package/dist/cli/experimental/commands/server.js +0 -44
  363. package/dist/cli/experimental/commands/server.js.map +0 -1
  364. package/dist/client/index.d.ts +0 -2
  365. package/dist/client/index.d.ts.map +0 -1
  366. package/dist/client/index.js +0 -2
  367. package/dist/client/index.js.map +0 -1
  368. package/dist/experimental/client-runtime.d.ts +0 -43
  369. package/dist/experimental/client-runtime.d.ts.map +0 -1
  370. package/dist/experimental/client-runtime.js +0 -183
  371. package/dist/experimental/client-runtime.js.map +0 -1
  372. package/dist/experimental/client-tui-chat.d.ts +0 -14
  373. package/dist/experimental/client-tui-chat.d.ts.map +0 -1
  374. package/dist/experimental/client-tui-chat.js +0 -171
  375. package/dist/experimental/client-tui-chat.js.map +0 -1
  376. package/dist/experimental/client-tui.d.ts +0 -37
  377. package/dist/experimental/client-tui.d.ts.map +0 -1
  378. package/dist/experimental/client-tui.js +0 -702
  379. package/dist/experimental/client-tui.js.map +0 -1
  380. package/dist/experimental/client.d.ts +0 -25
  381. package/dist/experimental/client.d.ts.map +0 -1
  382. package/dist/experimental/client.js +0 -99
  383. package/dist/experimental/client.js.map +0 -1
  384. package/dist/experimental/coordinator-entry.d.ts +0 -3
  385. package/dist/experimental/coordinator-entry.d.ts.map +0 -1
  386. package/dist/experimental/coordinator-entry.js +0 -11
  387. package/dist/experimental/coordinator-entry.js.map +0 -1
  388. package/dist/experimental/coordinator.d.ts +0 -38
  389. package/dist/experimental/coordinator.d.ts.map +0 -1
  390. package/dist/experimental/coordinator.js +0 -570
  391. package/dist/experimental/coordinator.js.map +0 -1
  392. package/dist/experimental/mini/main.d.ts +0 -7
  393. package/dist/experimental/mini/main.d.ts.map +0 -1
  394. package/dist/experimental/mini/main.js +0 -21
  395. package/dist/experimental/mini/main.js.map +0 -1
  396. package/dist/experimental/mini/server/entry.d.ts +0 -3
  397. package/dist/experimental/mini/server/entry.d.ts.map +0 -1
  398. package/dist/experimental/mini/server/entry.js +0 -11
  399. package/dist/experimental/mini/server/entry.js.map +0 -1
  400. package/dist/experimental/mini/server/run.d.ts +0 -13
  401. package/dist/experimental/mini/server/run.d.ts.map +0 -1
  402. package/dist/experimental/mini/server/run.js +0 -150
  403. package/dist/experimental/mini/server/run.js.map +0 -1
  404. package/dist/experimental/mini/shared/protocol.d.ts +0 -127
  405. package/dist/experimental/mini/shared/protocol.d.ts.map +0 -1
  406. package/dist/experimental/mini/shared/protocol.js +0 -13
  407. package/dist/experimental/mini/shared/protocol.js.map +0 -1
  408. package/dist/experimental/mini/shared/rpc.d.ts +0 -49
  409. package/dist/experimental/mini/shared/rpc.d.ts.map +0 -1
  410. package/dist/experimental/mini/shared/rpc.js +0 -171
  411. package/dist/experimental/mini/shared/rpc.js.map +0 -1
  412. package/dist/experimental/mini/shared/transport.d.ts +0 -35
  413. package/dist/experimental/mini/shared/transport.d.ts.map +0 -1
  414. package/dist/experimental/mini/shared/transport.js +0 -94
  415. package/dist/experimental/mini/shared/transport.js.map +0 -1
  416. package/dist/experimental/mini/tui/run.d.ts +0 -9
  417. package/dist/experimental/mini/tui/run.d.ts.map +0 -1
  418. package/dist/experimental/mini/tui/run.js +0 -62
  419. package/dist/experimental/mini/tui/run.js.map +0 -1
  420. package/dist/experimental/mini/tui/session.d.ts +0 -26
  421. package/dist/experimental/mini/tui/session.d.ts.map +0 -1
  422. package/dist/experimental/mini/tui/session.js +0 -94
  423. package/dist/experimental/mini/tui/session.js.map +0 -1
  424. package/dist/experimental/mini/tui/view.d.ts +0 -10
  425. package/dist/experimental/mini/tui/view.d.ts.map +0 -1
  426. package/dist/experimental/mini/tui/view.js +0 -459
  427. package/dist/experimental/mini/tui/view.js.map +0 -1
  428. package/dist/experimental/mini/worker/entry.d.ts +0 -3
  429. package/dist/experimental/mini/worker/entry.d.ts.map +0 -1
  430. package/dist/experimental/mini/worker/entry.js +0 -10
  431. package/dist/experimental/mini/worker/entry.js.map +0 -1
  432. package/dist/experimental/mini/worker/lane-service.d.ts +0 -44
  433. package/dist/experimental/mini/worker/lane-service.d.ts.map +0 -1
  434. package/dist/experimental/mini/worker/lane-service.js +0 -97
  435. package/dist/experimental/mini/worker/lane-service.js.map +0 -1
  436. package/dist/experimental/mini/worker/models-service.d.ts +0 -19
  437. package/dist/experimental/mini/worker/models-service.d.ts.map +0 -1
  438. package/dist/experimental/mini/worker/models-service.js +0 -136
  439. package/dist/experimental/mini/worker/models-service.js.map +0 -1
  440. package/dist/experimental/mini/worker/run.d.ts +0 -14
  441. package/dist/experimental/mini/worker/run.d.ts.map +0 -1
  442. package/dist/experimental/mini/worker/run.js +0 -88
  443. package/dist/experimental/mini/worker/run.js.map +0 -1
  444. package/dist/experimental/plugin.d.ts +0 -4
  445. package/dist/experimental/plugin.d.ts.map +0 -1
  446. package/dist/experimental/plugin.js +0 -4
  447. package/dist/experimental/plugin.js.map +0 -1
  448. package/dist/experimental/plugins/bundled.d.ts +0 -7
  449. package/dist/experimental/plugins/bundled.d.ts.map +0 -1
  450. package/dist/experimental/plugins/bundled.js +0 -48
  451. package/dist/experimental/plugins/bundled.js.map +0 -1
  452. package/dist/experimental/plugins/package.d.ts +0 -18
  453. package/dist/experimental/plugins/package.d.ts.map +0 -1
  454. package/dist/experimental/plugins/package.js +0 -113
  455. package/dist/experimental/plugins/package.js.map +0 -1
  456. package/dist/experimental/process.d.ts +0 -20
  457. package/dist/experimental/process.d.ts.map +0 -1
  458. package/dist/experimental/process.js +0 -85
  459. package/dist/experimental/process.js.map +0 -1
  460. package/dist/experimental/radius-auth.d.ts +0 -17
  461. package/dist/experimental/radius-auth.d.ts.map +0 -1
  462. package/dist/experimental/radius-auth.js +0 -52
  463. package/dist/experimental/radius-auth.js.map +0 -1
  464. package/dist/experimental/radius-relay.d.ts +0 -90
  465. package/dist/experimental/radius-relay.d.ts.map +0 -1
  466. package/dist/experimental/radius-relay.js +0 -582
  467. package/dist/experimental/radius-relay.js.map +0 -1
  468. package/dist/experimental/server.d.ts +0 -75
  469. package/dist/experimental/server.d.ts.map +0 -1
  470. package/dist/experimental/server.js +0 -682
  471. package/dist/experimental/server.js.map +0 -1
  472. package/dist/experimental/services/agent-controller-provider.d.ts +0 -4
  473. package/dist/experimental/services/agent-controller-provider.d.ts.map +0 -1
  474. package/dist/experimental/services/agent-controller-provider.js +0 -84
  475. package/dist/experimental/services/agent-controller-provider.js.map +0 -1
  476. package/dist/experimental/services/agent-controller.d.ts +0 -57
  477. package/dist/experimental/services/agent-controller.d.ts.map +0 -1
  478. package/dist/experimental/services/agent-controller.js +0 -3
  479. package/dist/experimental/services/agent-controller.js.map +0 -1
  480. package/dist/experimental/services/connection.d.ts +0 -40
  481. package/dist/experimental/services/connection.d.ts.map +0 -1
  482. package/dist/experimental/services/connection.js +0 -300
  483. package/dist/experimental/services/connection.js.map +0 -1
  484. package/dist/experimental/services/models-provider.d.ts +0 -16
  485. package/dist/experimental/services/models-provider.d.ts.map +0 -1
  486. package/dist/experimental/services/models-provider.js +0 -116
  487. package/dist/experimental/services/models-provider.js.map +0 -1
  488. package/dist/experimental/services/models.d.ts +0 -36
  489. package/dist/experimental/services/models.d.ts.map +0 -1
  490. package/dist/experimental/services/models.js +0 -3
  491. package/dist/experimental/services/models.js.map +0 -1
  492. package/dist/experimental/services/plugins.d.ts +0 -16
  493. package/dist/experimental/services/plugins.d.ts.map +0 -1
  494. package/dist/experimental/services/plugins.js +0 -4
  495. package/dist/experimental/services/plugins.js.map +0 -1
  496. package/dist/experimental/services/presentation-ui.d.ts +0 -13
  497. package/dist/experimental/services/presentation-ui.d.ts.map +0 -1
  498. package/dist/experimental/services/presentation-ui.js +0 -3
  499. package/dist/experimental/services/presentation-ui.js.map +0 -1
  500. package/dist/experimental/services/server.d.ts +0 -19
  501. package/dist/experimental/services/server.d.ts.map +0 -1
  502. package/dist/experimental/services/server.js +0 -104
  503. package/dist/experimental/services/server.js.map +0 -1
  504. package/dist/experimental/services/sessions.d.ts +0 -28
  505. package/dist/experimental/services/sessions.d.ts.map +0 -1
  506. package/dist/experimental/services/sessions.js +0 -4
  507. package/dist/experimental/services/sessions.js.map +0 -1
  508. package/dist/experimental/services/slash-commands-provider.d.ts +0 -14
  509. package/dist/experimental/services/slash-commands-provider.d.ts.map +0 -1
  510. package/dist/experimental/services/slash-commands-provider.js +0 -200
  511. package/dist/experimental/services/slash-commands-provider.js.map +0 -1
  512. package/dist/experimental/services/slash-commands.d.ts +0 -24
  513. package/dist/experimental/services/slash-commands.d.ts.map +0 -1
  514. package/dist/experimental/services/slash-commands.js +0 -3
  515. package/dist/experimental/services/slash-commands.js.map +0 -1
  516. package/dist/experimental/services/transcript-provider.d.ts +0 -12
  517. package/dist/experimental/services/transcript-provider.d.ts.map +0 -1
  518. package/dist/experimental/services/transcript-provider.js +0 -109
  519. package/dist/experimental/services/transcript-provider.js.map +0 -1
  520. package/dist/experimental/services/transcript.d.ts +0 -13
  521. package/dist/experimental/services/transcript.d.ts.map +0 -1
  522. package/dist/experimental/services/transcript.js +0 -3
  523. package/dist/experimental/services/transcript.js.map +0 -1
  524. package/dist/experimental/services/worker.d.ts +0 -28
  525. package/dist/experimental/services/worker.d.ts.map +0 -1
  526. package/dist/experimental/services/worker.js +0 -107
  527. package/dist/experimental/services/worker.js.map +0 -1
  528. package/dist/experimental/session-worker-manager.d.ts +0 -24
  529. package/dist/experimental/session-worker-manager.d.ts.map +0 -1
  530. package/dist/experimental/session-worker-manager.js +0 -691
  531. package/dist/experimental/session-worker-manager.js.map +0 -1
  532. package/dist/experimental/session-worker.d.ts +0 -188
  533. package/dist/experimental/session-worker.d.ts.map +0 -1
  534. package/dist/experimental/session-worker.js +0 -785
  535. package/dist/experimental/session-worker.js.map +0 -1
  536. package/dist/experimental/source-resolver.d.ts +0 -2
  537. package/dist/experimental/source-resolver.d.ts.map +0 -1
  538. package/dist/experimental/source-resolver.js +0 -71
  539. package/dist/experimental/source-resolver.js.map +0 -1
  540. package/dist/utils/clipboard-native.d.ts +0 -11
  541. package/dist/utils/clipboard-native.d.ts.map +0 -1
  542. package/dist/utils/clipboard-native.js +0 -20
  543. package/dist/utils/clipboard-native.js.map +0 -1
  544. package/examples/extensions/kimi-deferred-tools.ts +0 -61
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { readFileSync } from "node:fs";
16
16
  import { basename, dirname } from "node:path";
17
- import { contentText } from "@earendil-works/pi-ai";
17
+ import { contentText, getCurrentSystemMessage, retryDelayMs } from "@earendil-works/pi-ai";
18
18
  import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
19
19
  import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
20
20
  import { stripFrontmatter } from "../utils/frontmatter.js";
@@ -22,6 +22,7 @@ import { sleep } from "../utils/sleep.js";
22
22
  import { normalizeToolResultImages } from "../utils/tool-result-images.js";
23
23
  import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
24
24
  import { executeBashWithOperations } from "./bash-executor.js";
25
+ import { generateBugReportSummary } from "./bug-report.js";
25
26
  import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
26
27
  import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "./defaults.js";
27
28
  import { exportSessionToHtml } from "./export-html/index.js";
@@ -33,7 +34,7 @@ import { expandPromptTemplate } from "./prompt-templates.js";
33
34
  import { exportSessionToJsonl } from "./session-export.js";
34
35
  import { getLatestCompactionEntry } from "./session-manager.js";
35
36
  import { createSyntheticSourceInfo } from "./source-info.js";
36
- import { buildSystemPrompt } from "./system-prompt.js";
37
+ import { buildSystemPrompt, buildSystemPromptSections, diffSystemPromptSections, normalizeBuildSystemPromptOptions, } from "./system-prompt.js";
37
38
  import { createLocalBashOperations } from "./tools/bash.js";
38
39
  import { createAllToolDefinitions } from "./tools/index.js";
39
40
  import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
@@ -69,9 +70,6 @@ function estimateMessagesTokens(messages) {
69
70
  return tokens;
70
71
  }
71
72
  // ============================================================================
72
- // Constants
73
- // ============================================================================
74
- // ============================================================================
75
73
  // AgentSession Class
76
74
  // ============================================================================
77
75
  export class AgentSession {
@@ -83,6 +81,7 @@ export class AgentSession {
83
81
  _unsubscribeAgent;
84
82
  _eventListeners = [];
85
83
  _isAgentRunActive = false;
84
+ _agentRunAbortRequested = false;
86
85
  _idleWaitPromise;
87
86
  _resolveIdleWait;
88
87
  /** Tracks pending steering messages for UI display. Removed when delivered. */
@@ -126,15 +125,15 @@ export class AgentSession {
126
125
  _extensionErrorListener;
127
126
  _extensionErrorUnsubscriber;
128
127
  _modelRuntime;
128
+ _cacheWarmer;
129
129
  // Tool registry for extension getTools/setTools
130
130
  _toolRegistry = new Map();
131
131
  _toolDefinitions = new Map();
132
132
  _toolPromptSnippets = new Map();
133
133
  _toolPromptGuidelines = new Map();
134
- // Base system prompt (without extension appends) - used to apply fresh appends each turn
135
- _baseSystemPrompt = "";
136
134
  _baseSystemPromptOptions;
137
- _systemPromptOverride;
135
+ /** Prompt options after before_agent_start mutations for the active run. */
136
+ _runSystemPromptOptions;
138
137
  constructor(config) {
139
138
  this.agent = config.agent;
140
139
  this.sessionManager = config.sessionManager;
@@ -144,6 +143,10 @@ export class AgentSession {
144
143
  this._customTools = config.customTools ?? [];
145
144
  this._cwd = config.cwd;
146
145
  this._modelRuntime = config.modelRuntime;
146
+ this._cacheWarmer = config.cacheWarmer;
147
+ if (this._cacheWarmer) {
148
+ this._cacheWarmer.onWarmed = (entry) => this._emit({ type: "entry_appended", entry });
149
+ }
147
150
  this._extensionRunnerRef = config.extensionRunnerRef;
148
151
  this._initialActiveToolNames = config.initialActiveToolNames;
149
152
  this._allowedToolNames = config.allowedToolNames ? new Set(config.allowedToolNames) : undefined;
@@ -155,18 +158,21 @@ export class AgentSession {
155
158
  this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
156
159
  this._installAgentToolHooks();
157
160
  this._installAgentNextTurnRefresh();
161
+ this._installAgentForcedPromptProjection();
158
162
  this._buildRuntime({
159
163
  activeToolNames: this._initialActiveToolNames,
160
164
  includeAllExtensionTools: true,
161
165
  });
166
+ if (this._initialActiveToolNames === undefined)
167
+ this._restoreToolsFromTranscript();
162
168
  }
163
169
  get modelRuntime() {
164
170
  return this._modelRuntime;
165
171
  }
166
- async _getRequiredRequestAuth(model) {
172
+ async _getRequiredRequestAuth(model, signal) {
167
173
  let result;
168
174
  try {
169
- result = await this._modelRuntime.getAuth(model);
175
+ result = await this._modelRuntime.getAuth(model, { signal });
170
176
  }
171
177
  catch (error) {
172
178
  const cause = error instanceof Error ? error.cause : undefined;
@@ -192,12 +198,12 @@ export class AgentSession {
192
198
  }
193
199
  throw new Error(formatNoApiKeyFoundMessage(model.provider));
194
200
  }
195
- async _getSummarizationRequestAuth(model) {
201
+ async _getSummarizationRequestAuth(model, signal) {
196
202
  if (this.agent.streamFunction === streamSimple) {
197
- return this._getRequiredRequestAuth(model);
203
+ return this._getRequiredRequestAuth(model, signal);
198
204
  }
199
205
  try {
200
- const result = await this._modelRuntime.getAuth(model);
206
+ const result = await this._modelRuntime.getAuth(model, { signal });
201
207
  if (!result)
202
208
  return { model };
203
209
  const requestModel = result.auth.baseUrl ? { ...model, baseUrl: result.auth.baseUrl } : model;
@@ -208,7 +214,9 @@ export class AgentSession {
208
214
  env: result.env,
209
215
  };
210
216
  }
211
- catch {
217
+ catch (error) {
218
+ if (signal?.aborted)
219
+ throw error;
212
220
  return { model };
213
221
  }
214
222
  }
@@ -273,7 +281,7 @@ export class AgentSession {
273
281
  }
274
282
  async _compactBeforeNextAssistantResponse(context) {
275
283
  const model = this.model;
276
- const settings = this.settingsManager.getCompactionSettings();
284
+ const settings = this.settingsManager.getCompactionSettings(model);
277
285
  if (!model ||
278
286
  model.contextWindow <= 0 ||
279
287
  !shouldCompact(estimateContextTokens(context.messages).tokens, model.contextWindow, settings)) {
@@ -294,13 +302,25 @@ export class AgentSession {
294
302
  const context = await this._compactBeforeNextAssistantResponse(turn.context);
295
303
  const previousSnapshot = await previousPrepareNextTurnWithContext?.({ ...turn, context }, signal);
296
304
  const nextContext = previousSnapshot?.context ?? context;
305
+ const runOptions = this._runSystemPromptOptions ?? this._baseSystemPromptOptions;
306
+ const options = normalizeBuildSystemPromptOptions({
307
+ ...runOptions,
308
+ selectedTools: this.getActiveToolNames(),
309
+ toolSnippets: { ...this._baseSystemPromptOptions.toolSnippets, ...runOptions.toolSnippets },
310
+ toolGuidelines: { ...this._baseSystemPromptOptions.toolGuidelines, ...runOptions.toolGuidelines },
311
+ });
312
+ const updateMessage = this._preparePromptAndToolLoadout(options, nextContext.messages);
313
+ // Keep session.systemPrompt and ctx.getSystemPrompt() in step with what the provider sees.
314
+ this._runSystemPromptOptions = options;
297
315
  return {
298
316
  ...previousSnapshot,
299
317
  context: {
300
318
  ...nextContext,
301
- systemPrompt: this._systemPromptOverride ?? this._baseSystemPrompt,
302
319
  tools: this.agent.state.tools.slice(),
303
320
  },
321
+ messages: updateMessage
322
+ ? [...(previousSnapshot?.messages ?? []), updateMessage]
323
+ : previousSnapshot?.messages,
304
324
  model: this.agent.state.model,
305
325
  thinkingLevel: this.agent.state.thinkingLevel,
306
326
  };
@@ -345,6 +365,7 @@ export class AgentSession {
345
365
  resolve();
346
366
  }
347
367
  async _emitAgentSettled() {
368
+ this._cacheWarmer?.onAgentSettled();
348
369
  this._isAgentRunActive = false;
349
370
  try {
350
371
  await this._extensionRunner.emit({ type: "agent_settled" });
@@ -391,7 +412,8 @@ export class AgentSession {
391
412
  // Persist as CustomMessageEntry
392
413
  this.sessionManager.appendCustomMessageEntry(event.message.customType, event.message.content, event.message.display, event.message.details);
393
414
  }
394
- else if (event.message.role === "user" ||
415
+ else if (event.message.role === "system" ||
416
+ event.message.role === "user" ||
395
417
  event.message.role === "assistant" ||
396
418
  event.message.role === "toolResult") {
397
419
  // Regular LLM message - persist as SessionMessageEntry
@@ -427,6 +449,8 @@ export class AgentSession {
427
449
  }
428
450
  };
429
451
  _willRetryAfterAgentEnd(event) {
452
+ if (this._agentRunAbortRequested)
453
+ return false;
430
454
  const settings = this.settingsManager.getRetrySettings();
431
455
  if (!settings.enabled || this._retryAttempt >= settings.maxRetries) {
432
456
  return false;
@@ -595,6 +619,10 @@ export class AgentSession {
595
619
  this._extensionRunner.invalidate("This extension ctx is stale after session replacement or reload. Do not use a captured pi or command ctx after ctx.newSession(), ctx.fork(), ctx.switchSession(), or ctx.reload(). For newSession, fork, and switchSession, move post-replacement work into withSession and use the ctx passed to withSession. For reload, do not use the old ctx after await ctx.reload().");
596
620
  this._disconnectFromAgent();
597
621
  this._eventListeners = [];
622
+ if (this._cacheWarmer) {
623
+ this._cacheWarmer.onWarmed = undefined;
624
+ this._cacheWarmer.cancel();
625
+ }
598
626
  cleanupSessionResources(this.sessionId);
599
627
  }
600
628
  // =========================================================================
@@ -604,6 +632,15 @@ export class AgentSession {
604
632
  get state() {
605
633
  return this.agent.state;
606
634
  }
635
+ /** Current cache-warming state and the policy inputs that produced it. */
636
+ get cacheWarmingStatus() {
637
+ return this._cacheWarmer?.status;
638
+ }
639
+ /** Persist the cache-warming mode and immediately reconcile active warming. */
640
+ setCacheWarmingMode(mode) {
641
+ this.settingsManager.setCacheWarmingMode(mode);
642
+ this._cacheWarmer?.onModeChanged();
643
+ }
607
644
  /** Current model (may be undefined if not yet selected) */
608
645
  get model() {
609
646
  return this.agent.state.model;
@@ -620,9 +657,9 @@ export class AgentSession {
620
657
  get isIdle() {
621
658
  return !this._isAgentRunActive && !this.isCompacting;
622
659
  }
623
- /** Current effective system prompt (includes any per-turn extension modifications) */
660
+ /** Current effective system prompt, including changes not yet sent to the model. */
624
661
  get systemPrompt() {
625
- return this.agent.state.systemPrompt;
662
+ return buildSystemPrompt(this._runSystemPromptOptions ?? this._baseSystemPromptOptions);
626
663
  }
627
664
  /** Current retry attempt (0 if not retrying) */
628
665
  get retryAttempt() {
@@ -667,9 +704,7 @@ export class AgentSession {
667
704
  }
668
705
  }
669
706
  this.agent.state.tools = tools;
670
- // Rebuild base system prompt with new tool set
671
- this._baseSystemPrompt = this._rebuildSystemPrompt(validToolNames);
672
- this.agent.state.systemPrompt = this._systemPromptOverride ?? this._baseSystemPrompt;
707
+ this._rebuildSystemPrompt(validToolNames);
673
708
  }
674
709
  /** Whether compaction or branch summarization is currently running */
675
710
  get isCompacting() {
@@ -738,23 +773,17 @@ export class AgentSession {
738
773
  _rebuildSystemPrompt(toolNames) {
739
774
  const validToolNames = toolNames.filter((name) => this._toolRegistry.has(name));
740
775
  const toolSnippets = {};
741
- const promptGuidelines = [];
742
- for (const name of validToolNames) {
776
+ for (const name of this._toolRegistry.keys()) {
743
777
  const snippet = this._toolPromptSnippets.get(name);
744
- if (snippet) {
778
+ if (snippet)
745
779
  toolSnippets[name] = snippet;
746
- }
747
- const toolGuidelines = this._toolPromptGuidelines.get(name);
748
- if (toolGuidelines) {
749
- promptGuidelines.push(...toolGuidelines);
750
- }
751
780
  }
752
781
  const loaderSystemPrompt = this._resourceLoader.getSystemPrompt();
753
782
  const loaderAppendSystemPrompt = this._resourceLoader.getAppendSystemPrompt();
754
- const appendSystemPrompt = loaderAppendSystemPrompt.length > 0 ? loaderAppendSystemPrompt.join("\n\n") : undefined;
783
+ const appendSystemPrompt = loaderAppendSystemPrompt.length > 0 ? loaderAppendSystemPrompt.join("\n\n") : "";
755
784
  const loadedSkills = this._resourceLoader.getSkills().skills;
756
785
  const loadedContextFiles = this._resourceLoader.getAgentsFiles().agentsFiles;
757
- this._baseSystemPromptOptions = {
786
+ this._baseSystemPromptOptions = normalizeBuildSystemPromptOptions({
758
787
  cwd: this._cwd,
759
788
  skills: loadedSkills,
760
789
  contextFiles: loadedContextFiles,
@@ -762,23 +791,87 @@ export class AgentSession {
762
791
  appendSystemPrompt,
763
792
  selectedTools: validToolNames,
764
793
  toolSnippets,
765
- promptGuidelines,
794
+ toolGuidelines: Object.fromEntries(this._toolPromptGuidelines),
795
+ });
796
+ }
797
+ /**
798
+ * Apply a prompt and tool loadout for the next request. Sets the executable tools and
799
+ * returns a system message patching the prompt sections the model currently has (replayed
800
+ * from `messages`), or undefined when the prompt is unchanged. Tool changes are declared by
801
+ * the agent loop before the request.
802
+ *
803
+ * A forced prompt does not affect the transcript: the structured sections are still diffed
804
+ * and persisted, and the forced text is projected onto the request by
805
+ * {@link _installAgentForcedPromptProjection}.
806
+ */
807
+ _preparePromptAndToolLoadout(options, messages = this.agent.state.messages) {
808
+ options.selectedTools = [...new Set(options.selectedTools)].filter((name) => this._toolRegistry.has(name));
809
+ this.agent.state.tools = options.selectedTools.flatMap((name) => {
810
+ const tool = this._toolRegistry.get(name);
811
+ return tool ? [tool] : [];
812
+ });
813
+ const sections = diffSystemPromptSections(getCurrentSystemMessage(messages)?.sections ?? {}, buildSystemPromptSections(options));
814
+ return sections ? { role: "system", content: "", sections, timestamp: Date.now() } : undefined;
815
+ }
816
+ /**
817
+ * Send a forced prompt as the provider's leading system prompt without recording it.
818
+ *
819
+ * A `before_agent_start` handler that returns `systemPrompt` needs that exact text at the
820
+ * head of the request; a mid-conversation system message would leave the original prompt
821
+ * in place. The forced text is a rendering of the current prompt, so the transcript keeps
822
+ * its structured sections and the request is projected instead: the system messages
823
+ * collapse into one head holding the forced text and the current tools. Runs after the
824
+ * `context` extension handlers.
825
+ */
826
+ _installAgentForcedPromptProjection() {
827
+ const previousTransformContext = this.agent.transformContext;
828
+ this.agent.transformContext = async (messages, signal) => {
829
+ const transformed = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
830
+ const forced = this._runSystemPromptOptions?.forceSystemPrompt;
831
+ if (forced === undefined)
832
+ return transformed;
833
+ const current = getCurrentSystemMessage(transformed);
834
+ const head = {
835
+ role: "system",
836
+ content: forced,
837
+ ...(current?.toolsAdded ? { toolsAdded: current.toolsAdded } : {}),
838
+ timestamp: current?.timestamp ?? Date.now(),
839
+ };
840
+ return [head, ...transformed.filter((message) => message.role !== "system")];
766
841
  };
767
- return buildSystemPrompt(this._baseSystemPromptOptions);
842
+ }
843
+ /** Restore the active tool loadout declared by the session transcript, if it declares one. */
844
+ _restoreToolsFromTranscript() {
845
+ const current = getCurrentSystemMessage(this.sessionManager.buildSessionContext().messages);
846
+ if (!current)
847
+ return;
848
+ const toolNames = (current.toolsAdded ?? [])
849
+ .map((tool) => tool.name)
850
+ .filter((name) => this._toolRegistry.has(name));
851
+ this.agent.state.tools = toolNames.flatMap((name) => {
852
+ const registered = this._toolRegistry.get(name);
853
+ return registered ? [registered] : [];
854
+ });
855
+ this._rebuildSystemPrompt(toolNames);
768
856
  }
769
857
  // =========================================================================
770
858
  // Prompting
771
859
  // =========================================================================
772
860
  async _runAgentPrompt(messages) {
861
+ this._agentRunAbortRequested = false;
773
862
  this._isAgentRunActive = true;
774
863
  try {
775
864
  await this.agent.prompt(messages);
776
865
  while (await this._handlePostAgentRun()) {
866
+ if (this._agentRunAbortRequested)
867
+ break;
777
868
  await this.agent.continue();
778
869
  }
779
870
  }
780
871
  finally {
781
- this._systemPromptOverride = undefined;
872
+ if (this._agentRunAbortRequested)
873
+ this._finishCancelledRetry();
874
+ this._runSystemPromptOptions = undefined;
782
875
  this._flushPendingBashMessages();
783
876
  this._flushPendingCustomMessages();
784
877
  await this._emitAgentSettled();
@@ -787,11 +880,21 @@ export class AgentSession {
787
880
  async _handlePostAgentRun() {
788
881
  const msg = this._lastAssistantMessage;
789
882
  this._lastAssistantMessage = undefined;
883
+ if (this._agentRunAbortRequested) {
884
+ this._finishCancelledRetry();
885
+ return false;
886
+ }
790
887
  if (!msg) {
791
888
  return false;
792
889
  }
793
890
  if (this._isRetryableError(msg) && (await this._prepareRetry(msg))) {
794
- return true;
891
+ if (this._agentRunAbortRequested)
892
+ this._finishCancelledRetry();
893
+ return !this._agentRunAbortRequested;
894
+ }
895
+ if (this._agentRunAbortRequested) {
896
+ this._finishCancelledRetry();
897
+ return false;
795
898
  }
796
899
  if (msg.stopReason === "error" && this._retryAttempt > 0) {
797
900
  this._emit({
@@ -803,11 +906,24 @@ export class AgentSession {
803
906
  this._retryAttempt = 0;
804
907
  }
805
908
  if (await this._checkCompaction(msg)) {
806
- return true;
909
+ return !this._agentRunAbortRequested;
807
910
  }
808
911
  // The agent loop drains both queues before emitting agent_end. Any messages
809
912
  // here were queued by agent_end extension handlers and need a continuation.
810
- return this.agent.hasQueuedMessages();
913
+ return !this._agentRunAbortRequested && this.agent.hasQueuedMessages();
914
+ }
915
+ async _runInputHandlers(text, images, source, streamingBehavior) {
916
+ if (!this._extensionRunner.hasHandlers("input")) {
917
+ return { text, images };
918
+ }
919
+ const inputResult = await this._extensionRunner.emitInput(text, images, source, streamingBehavior);
920
+ if (inputResult.action === "handled") {
921
+ return undefined;
922
+ }
923
+ if (inputResult.action === "transform") {
924
+ return { text: inputResult.text, images: inputResult.images ?? images };
925
+ }
926
+ return { text, images };
811
927
  }
812
928
  /**
813
929
  * Send a prompt to the agent.
@@ -837,19 +953,12 @@ export class AgentSession {
837
953
  throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
838
954
  }
839
955
  // Emit input event for extension interception (before skill/template expansion)
840
- let currentText = text;
841
- let currentImages = options?.images;
842
- if (this._extensionRunner.hasHandlers("input")) {
843
- const inputResult = await this._extensionRunner.emitInput(currentText, currentImages, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
844
- if (inputResult.action === "handled") {
845
- preflightResult?.(true);
846
- return;
847
- }
848
- if (inputResult.action === "transform") {
849
- currentText = inputResult.text;
850
- currentImages = inputResult.images ?? currentImages;
851
- }
956
+ const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
957
+ if (!processedInput) {
958
+ preflightResult?.(true);
959
+ return;
852
960
  }
961
+ const { text: currentText, images: currentImages } = processedInput;
853
962
  // Expand skill commands (/skill:name args) and prompt templates (/template args)
854
963
  let expandedText = currentText;
855
964
  if (expandPromptTemplates) {
@@ -912,31 +1021,30 @@ export class AgentSession {
912
1021
  }
913
1022
  this._pendingNextTurnMessages = [];
914
1023
  // Emit before_agent_start extension event
915
- const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPrompt, this._baseSystemPromptOptions);
916
- // Add all custom messages from extensions
917
- if (result?.messages) {
918
- for (const msg of result.messages) {
919
- messages.push({
920
- role: "custom",
921
- customType: msg.customType,
922
- // Untyped extensions can pass null/missing content; normalize at ingestion.
923
- content: msg.content ?? [],
924
- display: msg.display,
925
- details: msg.details,
926
- timestamp: Date.now(),
927
- });
928
- }
929
- }
930
- // Apply extension-modified system prompt, or reset to base
931
- if (result?.systemPrompt !== undefined) {
932
- this._systemPromptOverride = result.systemPrompt;
933
- this.agent.state.systemPrompt = result.systemPrompt;
934
- }
935
- else {
936
- // Ensure we're using the base prompt (in case previous turn had modifications)
937
- this._systemPromptOverride = undefined;
938
- this.agent.state.systemPrompt = this._baseSystemPrompt;
1024
+ const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
1025
+ const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPromptOptions);
1026
+ // Handlers may edit event.systemPromptOptions.selectedTools or call setActiveTools(),
1027
+ // which updates the live loadout instead. An explicit edit wins; otherwise the live
1028
+ // loadout is authoritative, so a setActiveTools() call is not undone here.
1029
+ const handlerEditedTools = result.systemPromptOptions.selectedTools.length !== selectedToolsBefore.length ||
1030
+ result.systemPromptOptions.selectedTools.some((name, index) => name !== selectedToolsBefore[index]);
1031
+ if (!handlerEditedTools)
1032
+ result.systemPromptOptions.selectedTools = this.getActiveToolNames();
1033
+ for (const msg of result.messages) {
1034
+ messages.push({
1035
+ role: "custom",
1036
+ customType: msg.customType,
1037
+ // Untyped extensions can pass null/missing content; normalize at ingestion.
1038
+ content: msg.content ?? [],
1039
+ display: msg.display,
1040
+ details: msg.details,
1041
+ timestamp: Date.now(),
1042
+ });
939
1043
  }
1044
+ const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
1045
+ this._runSystemPromptOptions = result.systemPromptOptions;
1046
+ if (updateMessage)
1047
+ messages.unshift(updateMessage);
940
1048
  }
941
1049
  catch (error) {
942
1050
  preflightResult?.(false);
@@ -1005,40 +1113,44 @@ export class AgentSession {
1005
1113
  return text; // Return original on error
1006
1114
  }
1007
1115
  }
1116
+ async _queueUserInput(text, images, behavior, source) {
1117
+ if (text.startsWith("/")) {
1118
+ this._throwIfExtensionCommand(text);
1119
+ }
1120
+ const processedInput = await this._runInputHandlers(text, images, source, this.isStreaming ? behavior : undefined);
1121
+ if (!processedInput)
1122
+ return;
1123
+ let expandedText = this._expandSkillCommand(processedInput.text);
1124
+ expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
1125
+ if (behavior === "steer") {
1126
+ await this._queueSteer(expandedText, processedInput.images);
1127
+ }
1128
+ else {
1129
+ await this._queueFollowUp(expandedText, processedInput.images);
1130
+ }
1131
+ }
1008
1132
  /**
1009
1133
  * Queue a steering message while the agent is running.
1010
1134
  * Delivered after the current assistant turn finishes executing its tool calls,
1011
1135
  * before the next LLM call.
1012
1136
  * Expands skill commands and prompt templates. Errors on extension commands.
1013
1137
  * @param images Optional image attachments to include with the message
1138
+ * @param options Input source; defaults to interactive
1014
1139
  * @throws Error if text is an extension command
1015
1140
  */
1016
- async steer(text, images) {
1017
- // Check for extension commands (cannot be queued)
1018
- if (text.startsWith("/")) {
1019
- this._throwIfExtensionCommand(text);
1020
- }
1021
- // Expand skill commands and prompt templates
1022
- let expandedText = this._expandSkillCommand(text);
1023
- expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
1024
- await this._queueSteer(expandedText, images);
1141
+ async steer(text, images, options) {
1142
+ await this._queueUserInput(text, images, "steer", options?.source ?? "interactive");
1025
1143
  }
1026
1144
  /**
1027
1145
  * Queue a follow-up message to be processed after the agent finishes.
1028
1146
  * Delivered only when agent has no more tool calls or steering messages.
1029
1147
  * Expands skill commands and prompt templates. Errors on extension commands.
1030
1148
  * @param images Optional image attachments to include with the message
1149
+ * @param options Input source; defaults to interactive
1031
1150
  * @throws Error if text is an extension command
1032
1151
  */
1033
- async followUp(text, images) {
1034
- // Check for extension commands (cannot be queued)
1035
- if (text.startsWith("/")) {
1036
- this._throwIfExtensionCommand(text);
1037
- }
1038
- // Expand skill commands and prompt templates
1039
- let expandedText = this._expandSkillCommand(text);
1040
- expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
1041
- await this._queueFollowUp(expandedText, images);
1152
+ async followUp(text, images, options) {
1153
+ await this._queueUserInput(text, images, "followUp", options?.source ?? "interactive");
1042
1154
  }
1043
1155
  /**
1044
1156
  * Internal: Queue a steering message (already expanded, no extension command check).
@@ -1220,6 +1332,9 @@ export class AgentSession {
1220
1332
  * Abort current operation and wait for agent to become idle.
1221
1333
  */
1222
1334
  async abort() {
1335
+ if (this._isAgentRunActive) {
1336
+ this._agentRunAbortRequested = true;
1337
+ }
1223
1338
  this.abortRetry();
1224
1339
  this.abortCompaction();
1225
1340
  this.abortBranchSummary();
@@ -1476,13 +1591,15 @@ export class AgentSession {
1476
1591
  this._compactionAbortController = new AbortController();
1477
1592
  this._emit({ type: "compaction_start", reason: "manual" });
1478
1593
  let fromExtension = false;
1594
+ let cancelledByExtension = false;
1479
1595
  try {
1480
- if (!this.model) {
1596
+ const model = this.model;
1597
+ if (!model) {
1481
1598
  throw new Error(formatNoModelSelectedMessage());
1482
1599
  }
1483
- const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model);
1600
+ const settings = this.settingsManager.getCompactionSettings(model);
1601
+ const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, this._compactionAbortController.signal);
1484
1602
  const pathEntries = this.sessionManager.getBranch();
1485
- const settings = this.settingsManager.getCompactionSettings();
1486
1603
  const preparation = prepareCompaction(pathEntries, settings);
1487
1604
  if (!preparation) {
1488
1605
  // Check why we can't compact
@@ -1504,6 +1621,7 @@ export class AgentSession {
1504
1621
  signal: this._compactionAbortController.signal,
1505
1622
  }));
1506
1623
  if (result?.cancel) {
1624
+ cancelledByExtension = true;
1507
1625
  throw new Error("Compaction cancelled");
1508
1626
  }
1509
1627
  if (result?.compaction) {
@@ -1573,7 +1691,7 @@ export class AgentSession {
1573
1691
  }
1574
1692
  catch (error) {
1575
1693
  const message = error instanceof Error ? error.message : String(error);
1576
- const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
1694
+ const aborted = this._compactionAbortController.signal.aborted || cancelledByExtension;
1577
1695
  const errorMessage = aborted ? undefined : `Compaction failed: ${message}`;
1578
1696
  this._clearManualCompactionState();
1579
1697
  this._emit({
@@ -1632,7 +1750,7 @@ export class AgentSession {
1632
1750
  * @returns Whether the post-run loop should call `agent.continue()` for overflow recovery or queued messages
1633
1751
  */
1634
1752
  async _checkCompaction(assistantMessage, skipAbortedCheck = true) {
1635
- const settings = this.settingsManager.getCompactionSettings();
1753
+ const settings = this.settingsManager.getCompactionSettings(this.model);
1636
1754
  if (!settings.enabled)
1637
1755
  return false;
1638
1756
  // Skip if message was aborted (user cancelled) - unless skipAbortedCheck is false
@@ -1737,22 +1855,28 @@ export class AgentSession {
1737
1855
  * @returns Whether the post-run loop should call `agent.continue()`
1738
1856
  */
1739
1857
  async _runAutoCompaction(reason, willRetry) {
1740
- const settings = this.settingsManager.getCompactionSettings();
1858
+ const model = this.model;
1859
+ const settings = this.settingsManager.getCompactionSettings(model);
1860
+ let abortController;
1741
1861
  let started = false;
1742
1862
  let fromExtension = false;
1863
+ let cancelledByExtension = false;
1743
1864
  try {
1744
- if (!this.model) {
1865
+ if (!model) {
1745
1866
  return false;
1746
1867
  }
1747
- const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model);
1748
1868
  const pathEntries = this.sessionManager.getBranch();
1749
1869
  const preparation = prepareCompaction(pathEntries, settings);
1750
1870
  if (!preparation) {
1751
1871
  return false;
1752
1872
  }
1753
- this._emit({ type: "compaction_start", reason });
1754
- this._autoCompactionAbortController = new AbortController();
1873
+ abortController = new AbortController();
1874
+ this._autoCompactionAbortController = abortController;
1755
1875
  started = true;
1876
+ this._emit({ type: "compaction_start", reason });
1877
+ abortController.signal.throwIfAborted();
1878
+ const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, abortController.signal);
1879
+ abortController.signal.throwIfAborted();
1756
1880
  let extensionCompaction;
1757
1881
  if (this._extensionRunner.hasHandlers("session_before_compact")) {
1758
1882
  const extensionResult = (await this._extensionRunner.emit({
@@ -1762,29 +1886,18 @@ export class AgentSession {
1762
1886
  customInstructions: undefined,
1763
1887
  reason,
1764
1888
  willRetry,
1765
- signal: this._autoCompactionAbortController.signal,
1889
+ signal: abortController.signal,
1766
1890
  }));
1767
1891
  if (extensionResult?.cancel) {
1768
- this._emit({
1769
- type: "compaction_end",
1770
- reason,
1771
- result: undefined,
1772
- aborted: true,
1773
- willRetry: false,
1774
- });
1775
- await this._emitSessionCompactFailed({
1776
- reason,
1777
- aborted: true,
1778
- willRetry: false,
1779
- fromExtension: false,
1780
- });
1781
- return false;
1892
+ cancelledByExtension = true;
1893
+ throw new Error("Compaction cancelled");
1782
1894
  }
1783
1895
  if (extensionResult?.compaction) {
1784
1896
  extensionCompaction = extensionResult.compaction;
1785
1897
  fromExtension = true;
1786
1898
  }
1787
1899
  }
1900
+ abortController.signal.throwIfAborted();
1788
1901
  let summary;
1789
1902
  let firstKeptEntryId;
1790
1903
  let tokensBefore;
@@ -1800,29 +1913,14 @@ export class AgentSession {
1800
1913
  }
1801
1914
  else {
1802
1915
  // Shared default summary generator, also used by manual compaction.
1803
- const compactResult = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, undefined, this._autoCompactionAbortController.signal, env, reason);
1916
+ const compactResult = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, undefined, abortController.signal, env, reason);
1804
1917
  summary = compactResult.summary;
1805
1918
  firstKeptEntryId = compactResult.firstKeptEntryId;
1806
1919
  tokensBefore = compactResult.tokensBefore;
1807
1920
  usage = compactResult.usage;
1808
1921
  details = compactResult.details;
1809
1922
  }
1810
- if (this._autoCompactionAbortController.signal.aborted) {
1811
- this._emit({
1812
- type: "compaction_end",
1813
- reason,
1814
- result: undefined,
1815
- aborted: true,
1816
- willRetry: false,
1817
- });
1818
- await this._emitSessionCompactFailed({
1819
- reason,
1820
- aborted: true,
1821
- willRetry: false,
1822
- fromExtension,
1823
- });
1824
- return false;
1825
- }
1923
+ abortController.signal.throwIfAborted();
1826
1924
  this.sessionManager.appendCompaction(summary, firstKeptEntryId, tokensBefore, details, fromExtension, usage);
1827
1925
  const newEntries = this.sessionManager.getEntries();
1828
1926
  const sessionContext = this.sessionManager.buildSessionContext();
@@ -1865,23 +1963,26 @@ export class AgentSession {
1865
1963
  return this.agent.hasQueuedMessages();
1866
1964
  }
1867
1965
  catch (error) {
1868
- const errorMessage = error instanceof Error ? error.message : "compaction failed";
1966
+ const message = error instanceof Error ? error.message : "compaction failed";
1967
+ const aborted = abortController?.signal.aborted === true || cancelledByExtension;
1869
1968
  if (started) {
1870
- const formattedErrorMessage = reason === "overflow"
1871
- ? `Context overflow recovery failed: ${errorMessage}`
1872
- : `Auto-compaction failed: ${errorMessage}`;
1969
+ const errorMessage = aborted
1970
+ ? undefined
1971
+ : reason === "overflow"
1972
+ ? `Context overflow recovery failed: ${message}`
1973
+ : `Auto-compaction failed: ${message}`;
1873
1974
  this._emit({
1874
1975
  type: "compaction_end",
1875
1976
  reason,
1876
1977
  result: undefined,
1877
- aborted: false,
1978
+ aborted,
1878
1979
  willRetry: false,
1879
- errorMessage: formattedErrorMessage,
1980
+ errorMessage,
1880
1981
  });
1881
1982
  await this._emitSessionCompactFailed({
1882
1983
  reason,
1883
- errorMessage: formattedErrorMessage,
1884
- aborted: false,
1984
+ errorMessage,
1985
+ aborted,
1885
1986
  willRetry: false,
1886
1987
  fromExtension,
1887
1988
  });
@@ -1889,7 +1990,9 @@ export class AgentSession {
1889
1990
  return false;
1890
1991
  }
1891
1992
  finally {
1892
- this._autoCompactionAbortController = undefined;
1993
+ if (this._autoCompactionAbortController === abortController) {
1994
+ this._autoCompactionAbortController = undefined;
1995
+ }
1893
1996
  this._resolveIdleWaitIfIdle();
1894
1997
  }
1895
1998
  }
@@ -1940,8 +2043,7 @@ export class AgentSession {
1940
2043
  themePaths: this.buildExtensionResourcePaths(themePaths),
1941
2044
  };
1942
2045
  this._resourceLoader.extendResources(extensionPaths);
1943
- this._baseSystemPrompt = this._rebuildSystemPrompt(this.getActiveToolNames());
1944
- this.agent.state.systemPrompt = this._baseSystemPrompt;
2046
+ this._rebuildSystemPrompt(this.getActiveToolNames());
1945
2047
  }
1946
2048
  buildExtensionResourcePaths(entries) {
1947
2049
  return entries.map((entry) => {
@@ -2279,6 +2381,18 @@ export class AgentSession {
2279
2381
  },
2280
2382
  };
2281
2383
  }
2384
+ _finishCancelledRetry() {
2385
+ if (this._retryAttempt === 0)
2386
+ return;
2387
+ const attempt = this._retryAttempt;
2388
+ this._retryAttempt = 0;
2389
+ this._emit({
2390
+ type: "auto_retry_end",
2391
+ success: false,
2392
+ attempt,
2393
+ finalError: "Retry cancelled",
2394
+ });
2395
+ }
2282
2396
  /**
2283
2397
  * Prepare a retryable error for continuation with exponential backoff.
2284
2398
  * @returns true if the caller should continue the agent, false otherwise
@@ -2294,7 +2408,7 @@ export class AgentSession {
2294
2408
  this._retryAttempt--;
2295
2409
  return false;
2296
2410
  }
2297
- const delayMs = settings.baseDelayMs * 2 ** (this._retryAttempt - 1);
2411
+ const delayMs = retryDelayMs(settings, this._retryAttempt);
2298
2412
  this._emit({
2299
2413
  type: "auto_retry_start",
2300
2414
  attempt: this._retryAttempt,
@@ -2314,14 +2428,7 @@ export class AgentSession {
2314
2428
  }
2315
2429
  catch {
2316
2430
  // Aborted during sleep - emit end event so UI can clean up
2317
- const attempt = this._retryAttempt;
2318
- this._retryAttempt = 0;
2319
- this._emit({
2320
- type: "auto_retry_end",
2321
- success: false,
2322
- attempt,
2323
- finalError: "Retry cancelled",
2324
- });
2431
+ this._finishCancelledRetry();
2325
2432
  return false;
2326
2433
  }
2327
2434
  finally {
@@ -2472,6 +2579,9 @@ export class AgentSession {
2472
2579
  if (this.isStreaming) {
2473
2580
  throw new Error("Wait for the current response to finish before navigating the session tree.");
2474
2581
  }
2582
+ if (this.isCompacting) {
2583
+ throw new Error("Wait for the current compaction or tree navigation to finish before navigating the session tree.");
2584
+ }
2475
2585
  const oldLeafId = this.sessionManager.getLeafId();
2476
2586
  // No-op if already at target
2477
2587
  if (targetId === oldLeafId) {
@@ -2614,6 +2724,7 @@ export class AgentSession {
2614
2724
  // Update agent state
2615
2725
  const sessionContext = this.sessionManager.buildSessionContext();
2616
2726
  this.agent.state.messages = sessionContext.messages;
2727
+ this._restoreToolsFromTranscript();
2617
2728
  // Emit session_tree event
2618
2729
  await this._extensionRunner.emit({
2619
2730
  type: "session_tree",
@@ -2661,7 +2772,10 @@ export class AgentSession {
2661
2772
  let toolCalls = 0;
2662
2773
  const usageTotals = createUsageTotals();
2663
2774
  for (const entry of this.sessionManager.getEntries()) {
2664
- if ((entry.type === "branch_summary" || entry.type === "compaction") && entry.usage) {
2775
+ if (entry.type === "usage") {
2776
+ addUsageToTotals(usageTotals, entry.usage);
2777
+ }
2778
+ else if ((entry.type === "branch_summary" || entry.type === "compaction") && entry.usage) {
2665
2779
  addUsageToTotals(usageTotals, entry.usage);
2666
2780
  }
2667
2781
  if (entry.type !== "message")
@@ -2775,6 +2889,30 @@ export class AgentSession {
2775
2889
  exportToJsonl(outputPath) {
2776
2890
  return exportSessionToJsonl(this.sessionManager, outputPath);
2777
2891
  }
2892
+ /**
2893
+ * Ask the current model to describe what went wrong in this session for a bug report.
2894
+ * Used when the user declines to share the transcript itself.
2895
+ */
2896
+ async summarizeForBugReport(options) {
2897
+ const model = this.model;
2898
+ if (!model) {
2899
+ throw new Error("No model selected");
2900
+ }
2901
+ const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
2902
+ return generateBugReportSummary({
2903
+ messages: this.messages,
2904
+ hint: options.hint,
2905
+ model: requestModel,
2906
+ apiKey,
2907
+ headers,
2908
+ env,
2909
+ signal: options.signal,
2910
+ thinkingLevel: this.thinkingLevel,
2911
+ streamFn: this.agent.streamFunction,
2912
+ retry: this.settingsManager.getRetrySettings(),
2913
+ sessionId: this.sessionId,
2914
+ });
2915
+ }
2778
2916
  // =========================================================================
2779
2917
  // Utilities
2780
2918
  // =========================================================================