@astralyn/pi 1.0.5 → 1.2.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 (436) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/bundle/chunks/anthropic-messages-NVP5OPIM.js +6 -0
  3. package/dist/bundle/chunks/anthropic.js +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-LDW4FGAQ.js → azure-openai-responses-IBTOZ5MH.js} +1 -1
  5. package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
  6. package/dist/bundle/chunks/chunk-4XZYHGVN.js +11 -0
  7. package/dist/bundle/chunks/{chunk-GIG5IHES.js → chunk-5KJH3GGH.js} +1 -1
  8. package/dist/bundle/chunks/chunk-6VYRLG5F.js +2 -0
  9. package/dist/bundle/chunks/{chunk-UCXU7KLO.js → chunk-7HJ6CHUB.js} +1 -1
  10. package/dist/bundle/chunks/chunk-7UBIBLPN.js +2 -0
  11. package/dist/bundle/chunks/{chunk-IE3Z7ESB.js → chunk-A5HU4TE6.js} +418 -362
  12. package/dist/bundle/chunks/{chunk-HDHRZ7GT.js → chunk-B2UOWO4A.js} +1 -1
  13. package/dist/bundle/chunks/chunk-J75WV3FL.js +2 -0
  14. package/dist/bundle/chunks/{chunk-A6ALEEY5.js → chunk-LHSPN2IO.js} +1 -1
  15. package/dist/bundle/chunks/chunk-Q74S7ILH.js +2 -0
  16. package/dist/bundle/chunks/chunk-QDDSFJ35.js +2 -0
  17. package/dist/bundle/chunks/{chunk-IFELM7MW.js → chunk-UQECUCUH.js} +1 -1
  18. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-HGOVFZDC.js +2 -0
  19. package/dist/bundle/chunks/codemode-worker.js +18 -10
  20. package/dist/bundle/chunks/github-copilot.js +1 -1
  21. package/dist/bundle/chunks/{google-generative-ai-S5A5IBU4.js → google-generative-ai-M44TSMAN.js} +1 -1
  22. package/dist/bundle/chunks/{google-vertex-UBRQFDB4.js → google-vertex-3C4OWLFX.js} +1 -1
  23. package/dist/bundle/chunks/image-resize-worker.js +1 -1
  24. package/dist/bundle/chunks/{llama-cpp-classify-R7DQLTQN.js → llama-cpp-classify-H3IZDR5O.js} +2 -2
  25. package/dist/bundle/chunks/mistral-conversations-I5PL4VCZ.js +5 -0
  26. package/dist/bundle/chunks/openai-chatgpt.js +1 -1
  27. package/dist/bundle/chunks/openai-codex-responses-O5EUDL54.js +10 -0
  28. package/dist/bundle/chunks/openai-codex.js +1 -1
  29. package/dist/bundle/chunks/{openai-completions-H4VMO7AU.js → openai-completions-X3SSG5BQ.js} +1 -1
  30. package/dist/bundle/chunks/openai-decisions-TVCDIPZX.js +5 -0
  31. package/dist/bundle/chunks/{openai-responses-G4PGNM2H.js → openai-responses-NYPNKVDV.js} +1 -1
  32. package/dist/bundle/chunks/{openrouter-images-YP3YVB54.js → openrouter-images-TDLJV5N4.js} +1 -1
  33. package/dist/bundle/chunks/{pi-messages-HZZ7GEEW.js → pi-messages-ZXNERWJG.js} +1 -1
  34. package/dist/bundle/chunks/typesafe-system-one-LWPJYTJP.js +2 -0
  35. package/dist/bundle/chunks/{virtual-modules-46MSJGKO.js → virtual-modules-OZTPKGU7.js} +1 -1
  36. package/dist/bundle/cli.js +1 -1
  37. package/dist/bundle/index.js +1 -1
  38. package/dist/bundle/rpc-entry.js +1 -1
  39. package/dist/cli/args.d.ts +1 -1
  40. package/dist/cli/args.d.ts.map +1 -1
  41. package/dist/cli/args.js +13 -1
  42. package/dist/cli/args.js.map +1 -1
  43. package/dist/core/agent-session.d.ts +26 -7
  44. package/dist/core/agent-session.d.ts.map +1 -1
  45. package/dist/core/agent-session.js +190 -183
  46. package/dist/core/agent-session.js.map +1 -1
  47. package/dist/core/auth-storage.d.ts.map +1 -1
  48. package/dist/core/auth-storage.js +20 -13
  49. package/dist/core/auth-storage.js.map +1 -1
  50. package/dist/core/bash-executor.d.ts.map +1 -1
  51. package/dist/core/bash-executor.js +40 -45
  52. package/dist/core/bash-executor.js.map +1 -1
  53. package/dist/core/bug-report.d.ts +9 -1
  54. package/dist/core/bug-report.d.ts.map +1 -1
  55. package/dist/core/compaction/utils.d.ts +6 -0
  56. package/dist/core/compaction/utils.d.ts.map +1 -1
  57. package/dist/core/compaction/utils.js +7 -8
  58. package/dist/core/compaction/utils.js.map +1 -1
  59. package/dist/core/context-snapshot.d.ts +4 -1
  60. package/dist/core/context-snapshot.d.ts.map +1 -1
  61. package/dist/core/context-snapshot.js +45 -0
  62. package/dist/core/context-snapshot.js.map +1 -1
  63. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  64. package/dist/core/export-html/tool-renderer.js +2 -0
  65. package/dist/core/export-html/tool-renderer.js.map +1 -1
  66. package/dist/core/extensions/index.d.ts +1 -1
  67. package/dist/core/extensions/index.d.ts.map +1 -1
  68. package/dist/core/extensions/index.js.map +1 -1
  69. package/dist/core/extensions/runner.d.ts +4 -2
  70. package/dist/core/extensions/runner.d.ts.map +1 -1
  71. package/dist/core/extensions/runner.js +2 -3
  72. package/dist/core/extensions/runner.js.map +1 -1
  73. package/dist/core/extensions/types.d.ts +42 -7
  74. package/dist/core/extensions/types.d.ts.map +1 -1
  75. package/dist/core/extensions/types.js.map +1 -1
  76. package/dist/core/key-id-schema.d.ts +6 -0
  77. package/dist/core/key-id-schema.d.ts.map +1 -0
  78. package/dist/core/key-id-schema.js +16 -0
  79. package/dist/core/key-id-schema.js.map +1 -0
  80. package/dist/core/keybinding-registry.d.ts +4 -3
  81. package/dist/core/keybinding-registry.d.ts.map +1 -1
  82. package/dist/core/keybinding-registry.js +4 -3
  83. package/dist/core/keybinding-registry.js.map +1 -1
  84. package/dist/core/keybindings-schema.d.ts +4 -0
  85. package/dist/core/keybindings-schema.d.ts.map +1 -0
  86. package/dist/core/keybindings-schema.js +16 -0
  87. package/dist/core/keybindings-schema.js.map +1 -0
  88. package/dist/core/keybindings.d.ts +258 -81
  89. package/dist/core/keybindings.d.ts.map +1 -1
  90. package/dist/core/keybindings.js +27 -24
  91. package/dist/core/keybindings.js.map +1 -1
  92. package/dist/core/model-config.d.ts +713 -180
  93. package/dist/core/model-config.d.ts.map +1 -1
  94. package/dist/core/model-config.js +18 -179
  95. package/dist/core/model-config.js.map +1 -1
  96. package/dist/core/model-runtime.d.ts.map +1 -1
  97. package/dist/core/model-runtime.js +13 -7
  98. package/dist/core/model-runtime.js.map +1 -1
  99. package/dist/core/nested-tool-calls.d.ts +1 -0
  100. package/dist/core/nested-tool-calls.d.ts.map +1 -1
  101. package/dist/core/nested-tool-calls.js +1 -0
  102. package/dist/core/nested-tool-calls.js.map +1 -1
  103. package/dist/core/package-manager.d.ts.map +1 -1
  104. package/dist/core/package-manager.js +3 -3
  105. package/dist/core/package-manager.js.map +1 -1
  106. package/dist/core/project-trust.d.ts.map +1 -1
  107. package/dist/core/project-trust.js +2 -1
  108. package/dist/core/project-trust.js.map +1 -1
  109. package/dist/core/remote-catalog-provider.d.ts +12 -1
  110. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  111. package/dist/core/remote-catalog-provider.js +82 -24
  112. package/dist/core/remote-catalog-provider.js.map +1 -1
  113. package/dist/core/resource-loader.d.ts.map +1 -1
  114. package/dist/core/resource-loader.js +7 -2
  115. package/dist/core/resource-loader.js.map +1 -1
  116. package/dist/core/sdk.d.ts +4 -0
  117. package/dist/core/sdk.d.ts.map +1 -1
  118. package/dist/core/sdk.js +17 -5
  119. package/dist/core/sdk.js.map +1 -1
  120. package/dist/core/settings-defaults.d.ts +65 -0
  121. package/dist/core/settings-defaults.d.ts.map +1 -0
  122. package/dist/core/settings-defaults.js +66 -0
  123. package/dist/core/settings-defaults.js.map +1 -0
  124. package/dist/core/settings-manager.d.ts +15 -147
  125. package/dist/core/settings-manager.d.ts.map +1 -1
  126. package/dist/core/settings-manager.js +85 -57
  127. package/dist/core/settings-manager.js.map +1 -1
  128. package/dist/core/settings-schema.d.ts +231 -0
  129. package/dist/core/settings-schema.d.ts.map +1 -0
  130. package/dist/core/settings-schema.js +294 -0
  131. package/dist/core/settings-schema.js.map +1 -0
  132. package/dist/core/tasks/session.d.ts +9 -0
  133. package/dist/core/tasks/session.d.ts.map +1 -1
  134. package/dist/core/tasks/session.js +21 -0
  135. package/dist/core/tasks/session.js.map +1 -1
  136. package/dist/core/tools/render-utils.d.ts +18 -0
  137. package/dist/core/tools/render-utils.d.ts.map +1 -1
  138. package/dist/core/tools/render-utils.js +46 -0
  139. package/dist/core/tools/render-utils.js.map +1 -1
  140. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  141. package/dist/core/tools/renderers/bash.js +21 -45
  142. package/dist/core/tools/renderers/bash.js.map +1 -1
  143. package/dist/core/tools/renderers/edit.js +1 -1
  144. package/dist/core/tools/renderers/edit.js.map +1 -1
  145. package/dist/extensions/btw/keybindings.d.ts +2 -2
  146. package/dist/extensions/btw/keybindings.d.ts.map +1 -1
  147. package/dist/extensions/btw/keybindings.js.map +1 -1
  148. package/dist/extensions/codemode/execute.d.ts.map +1 -1
  149. package/dist/extensions/codemode/execute.js +115 -40
  150. package/dist/extensions/codemode/execute.js.map +1 -1
  151. package/dist/extensions/codemode/index.d.ts.map +1 -1
  152. package/dist/extensions/codemode/index.js +3 -7
  153. package/dist/extensions/codemode/index.js.map +1 -1
  154. package/dist/extensions/codemode/renderer.d.ts +2 -2
  155. package/dist/extensions/codemode/renderer.d.ts.map +1 -1
  156. package/dist/extensions/codemode/renderer.js +9 -3
  157. package/dist/extensions/codemode/renderer.js.map +1 -1
  158. package/dist/extensions/codemode/tool.d.ts +6 -12
  159. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  160. package/dist/extensions/codemode/tool.js +46 -34
  161. package/dist/extensions/codemode/tool.js.map +1 -1
  162. package/dist/extensions/index.js +2 -2
  163. package/dist/extensions/index.js.map +1 -1
  164. package/dist/extensions/list-keybindings.d.ts +2 -2
  165. package/dist/extensions/list-keybindings.d.ts.map +1 -1
  166. package/dist/extensions/list-keybindings.js.map +1 -1
  167. package/dist/extensions/llama/provider.d.ts.map +1 -1
  168. package/dist/extensions/llama/provider.js +34 -11
  169. package/dist/extensions/llama/provider.js.map +1 -1
  170. package/dist/extensions/mcp/cli.js +22 -31
  171. package/dist/extensions/mcp/cli.js.map +1 -1
  172. package/dist/extensions/mcp/index.d.ts.map +1 -1
  173. package/dist/extensions/mcp/index.js +187 -95
  174. package/dist/extensions/mcp/index.js.map +1 -1
  175. package/dist/extensions/mcp/oauth.d.ts +5 -3
  176. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  177. package/dist/extensions/mcp/oauth.js +36 -10
  178. package/dist/extensions/mcp/oauth.js.map +1 -1
  179. package/dist/extensions/mcp/resources.d.ts +0 -6
  180. package/dist/extensions/mcp/resources.d.ts.map +1 -1
  181. package/dist/extensions/mcp/resources.js +1 -1
  182. package/dist/extensions/mcp/resources.js.map +1 -1
  183. package/dist/extensions/mcp/runtime.d.ts +3 -6
  184. package/dist/extensions/mcp/runtime.d.ts.map +1 -1
  185. package/dist/extensions/mcp/runtime.js +4 -39
  186. package/dist/extensions/mcp/runtime.js.map +1 -1
  187. package/dist/extensions/mcp/tools.d.ts +2 -3
  188. package/dist/extensions/mcp/tools.d.ts.map +1 -1
  189. package/dist/extensions/mcp/tools.js +62 -6
  190. package/dist/extensions/mcp/tools.js.map +1 -1
  191. package/dist/extensions/mcp/ui.d.ts +3 -3
  192. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  193. package/dist/extensions/mcp/ui.js +10 -2
  194. package/dist/extensions/mcp/ui.js.map +1 -1
  195. package/dist/extensions/provider/keybindings.d.ts +2 -2
  196. package/dist/extensions/provider/keybindings.d.ts.map +1 -1
  197. package/dist/extensions/provider/keybindings.js.map +1 -1
  198. package/dist/extensions/search/code-search.d.ts +27 -0
  199. package/dist/extensions/search/code-search.d.ts.map +1 -0
  200. package/dist/extensions/search/code-search.js +120 -0
  201. package/dist/extensions/search/code-search.js.map +1 -0
  202. package/dist/extensions/search/command.d.ts +5 -0
  203. package/dist/extensions/search/command.d.ts.map +1 -0
  204. package/dist/extensions/search/command.js +69 -0
  205. package/dist/extensions/search/command.js.map +1 -0
  206. package/dist/extensions/search/credential.d.ts +25 -0
  207. package/dist/extensions/search/credential.d.ts.map +1 -0
  208. package/dist/extensions/search/credential.js +117 -0
  209. package/dist/extensions/search/credential.js.map +1 -0
  210. package/dist/extensions/search/devin.d.ts +34 -0
  211. package/dist/extensions/search/devin.d.ts.map +1 -0
  212. package/dist/extensions/search/devin.js +210 -0
  213. package/dist/extensions/search/devin.js.map +1 -0
  214. package/dist/extensions/search/index.d.ts +5 -0
  215. package/dist/extensions/search/index.d.ts.map +1 -0
  216. package/dist/extensions/search/index.js +113 -0
  217. package/dist/extensions/search/index.js.map +1 -0
  218. package/dist/extensions/search/panel.d.ts +53 -0
  219. package/dist/extensions/search/panel.d.ts.map +1 -0
  220. package/dist/extensions/search/panel.js +157 -0
  221. package/dist/extensions/search/panel.js.map +1 -0
  222. package/dist/extensions/search/prompt.d.ts +14 -0
  223. package/dist/extensions/search/prompt.d.ts.map +1 -0
  224. package/dist/extensions/search/prompt.js +221 -0
  225. package/dist/extensions/search/prompt.js.map +1 -0
  226. package/dist/extensions/search/render.d.ts +28 -0
  227. package/dist/extensions/search/render.d.ts.map +1 -0
  228. package/dist/extensions/search/render.js +86 -0
  229. package/dist/extensions/search/render.js.map +1 -0
  230. package/dist/extensions/search/workspace.d.ts +39 -0
  231. package/dist/extensions/search/workspace.d.ts.map +1 -0
  232. package/dist/extensions/search/workspace.js +363 -0
  233. package/dist/extensions/search/workspace.js.map +1 -0
  234. package/dist/extensions/tool-search/index.d.ts.map +1 -1
  235. package/dist/extensions/tool-search/index.js +1 -6
  236. package/dist/extensions/tool-search/index.js.map +1 -1
  237. package/dist/extensions/tool-search/tool.d.ts +0 -2
  238. package/dist/extensions/tool-search/tool.d.ts.map +1 -1
  239. package/dist/extensions/tool-search/tool.js +2 -4
  240. package/dist/extensions/tool-search/tool.js.map +1 -1
  241. package/dist/index.d.ts +1 -1
  242. package/dist/index.d.ts.map +1 -1
  243. package/dist/index.js.map +1 -1
  244. package/dist/main.js +3 -3
  245. package/dist/main.js.map +1 -1
  246. package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
  247. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  248. package/dist/modes/interactive/components/bash-execution.js +14 -14
  249. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  250. package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
  251. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  252. package/dist/modes/interactive/components/branch-summary-message.js +5 -2
  253. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  254. package/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -1
  255. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  256. package/dist/modes/interactive/components/compaction-summary-message.js +5 -2
  257. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  258. package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
  259. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  260. package/dist/modes/interactive/components/custom-entry.js +7 -2
  261. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  262. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  263. package/dist/modes/interactive/components/custom-message.js +1 -0
  264. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  265. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  266. package/dist/modes/interactive/components/settings-selector.js +4 -3
  267. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  268. package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
  269. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  270. package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
  271. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  272. package/dist/modes/interactive/components/status-indicator.d.ts +1 -1
  273. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  274. package/dist/modes/interactive/components/status-indicator.js +2 -2
  275. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  276. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  277. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  278. package/dist/modes/interactive/interactive-mode.js +63 -64
  279. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  280. package/dist/modes/interactive/program-status-reporter.d.ts +34 -0
  281. package/dist/modes/interactive/program-status-reporter.d.ts.map +1 -0
  282. package/dist/modes/interactive/program-status-reporter.js +107 -0
  283. package/dist/modes/interactive/program-status-reporter.js.map +1 -0
  284. package/dist/modes/interactive/tasks/host-hooks.d.ts +14 -0
  285. package/dist/modes/interactive/tasks/host-hooks.d.ts.map +1 -0
  286. package/dist/modes/interactive/tasks/host-hooks.js +31 -0
  287. package/dist/modes/interactive/tasks/host-hooks.js.map +1 -0
  288. package/dist/modes/interactive/theme/dark.json +1 -1
  289. package/dist/modes/interactive/theme/light.json +1 -1
  290. package/dist/modes/interactive/theme/theme-schema.d.ts +28 -0
  291. package/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  292. package/dist/modes/interactive/theme/theme-schema.js +105 -0
  293. package/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  294. package/dist/modes/interactive/theme/theme-tokens.d.ts +257 -0
  295. package/dist/modes/interactive/theme/theme-tokens.d.ts.map +1 -0
  296. package/dist/modes/interactive/theme/theme-tokens.js +94 -0
  297. package/dist/modes/interactive/theme/theme-tokens.js.map +1 -0
  298. package/dist/modes/interactive/theme/theme.d.ts +13 -16
  299. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  300. package/dist/modes/interactive/theme/theme.js +23 -31
  301. package/dist/modes/interactive/theme/theme.js.map +1 -1
  302. package/dist/modes/interactive/tool-view/tool-execution.d.ts +5 -0
  303. package/dist/modes/interactive/tool-view/tool-execution.d.ts.map +1 -1
  304. package/dist/modes/interactive/tool-view/tool-execution.js +7 -0
  305. package/dist/modes/interactive/tool-view/tool-execution.js.map +1 -1
  306. package/dist/modes/print-mode.d.ts.map +1 -1
  307. package/dist/modes/print-mode.js +4 -0
  308. package/dist/modes/print-mode.js.map +1 -1
  309. package/dist/package-manager-cli.d.ts.map +1 -1
  310. package/dist/package-manager-cli.js +24 -0
  311. package/dist/package-manager-cli.js.map +1 -1
  312. package/dist/utils/ansi.d.ts +8 -0
  313. package/dist/utils/ansi.d.ts.map +1 -1
  314. package/dist/utils/ansi.js +30 -11
  315. package/dist/utils/ansi.js.map +1 -1
  316. package/dist/utils/clipboard.d.ts.map +1 -1
  317. package/dist/utils/clipboard.js +18 -12
  318. package/dist/utils/clipboard.js.map +1 -1
  319. package/dist/utils/image-resize-core.d.ts +12 -0
  320. package/dist/utils/image-resize-core.d.ts.map +1 -1
  321. package/dist/utils/image-resize-core.js +5 -0
  322. package/dist/utils/image-resize-core.js.map +1 -1
  323. package/dist/utils/image-resize-worker.js +3 -2
  324. package/dist/utils/image-resize-worker.js.map +1 -1
  325. package/dist/utils/image-resize.d.ts.map +1 -1
  326. package/dist/utils/image-resize.js +9 -10
  327. package/dist/utils/image-resize.js.map +1 -1
  328. package/docs/bundled/README.md +1 -1
  329. package/docs/bundled/extensions/provider.md +1 -1
  330. package/docs/bundled/extensions/question.md +1 -1
  331. package/docs/bundled/extensions/search.md +51 -0
  332. package/docs/bundled/extensions/statusline.md +15 -41
  333. package/docs/codemode.md +24 -4
  334. package/docs/compaction.md +2 -2
  335. package/docs/docs.json +0 -4
  336. package/docs/environment-variables.md +3 -1
  337. package/docs/extensions.md +15 -5
  338. package/docs/json.md +2 -2
  339. package/docs/keybindings.md +1 -0
  340. package/docs/llama-cpp.md +8 -1
  341. package/docs/mcp.md +1 -1
  342. package/docs/models.md +5 -1
  343. package/docs/providers.md +33 -0
  344. package/docs/rpc.md +6 -3
  345. package/docs/session-format.md +1 -0
  346. package/docs/settings.md +5 -5
  347. package/docs/terminal-setup.md +14 -0
  348. package/docs/themes.md +4 -2
  349. package/docs/tui.md +1 -1
  350. package/docs/usage.md +7 -3
  351. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  352. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  353. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  354. package/examples/extensions/dynamic-resources/dynamic.json +1 -1
  355. package/examples/extensions/gondolin/package-lock.json +2 -2
  356. package/examples/extensions/gondolin/package.json +1 -1
  357. package/examples/extensions/overlay-test.ts +2 -2
  358. package/examples/extensions/plan-mode/index.ts +6 -2
  359. package/examples/extensions/sandbox/package-lock.json +2 -2
  360. package/examples/extensions/sandbox/package.json +1 -1
  361. package/examples/extensions/with-deps/package-lock.json +2 -2
  362. package/examples/extensions/with-deps/package.json +1 -1
  363. package/npm-shrinkwrap.json +54 -102
  364. package/package.json +10 -20
  365. package/schemas/keybindings.schema.json +453 -0
  366. package/schemas/models.schema.json +1157 -0
  367. package/schemas/settings.schema.json +782 -0
  368. package/schemas/theme.schema.json +365 -0
  369. package/dist/bundle/chunks/anthropic-messages-YIOJIMVL.js +0 -6
  370. package/dist/bundle/chunks/chunk-57XI7YJH.js +0 -2
  371. package/dist/bundle/chunks/chunk-JI4WGISU.js +0 -2
  372. package/dist/bundle/chunks/chunk-TCQ4HHQD.js +0 -2
  373. package/dist/bundle/chunks/chunk-TXJO4AJ7.js +0 -11
  374. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-OWU5SM6J.js +0 -2
  375. package/dist/bundle/chunks/mistral-conversations-A2N5FSOV.js +0 -5
  376. package/dist/bundle/chunks/openai-codex-responses-Q6JHCWLE.js +0 -10
  377. package/dist/bundle/chunks/typesafe-system-one-KYKKNU3E.js +0 -2
  378. package/dist/extensions/web-search/auth.d.ts +0 -12
  379. package/dist/extensions/web-search/auth.d.ts.map +0 -1
  380. package/dist/extensions/web-search/auth.js +0 -90
  381. package/dist/extensions/web-search/auth.js.map +0 -1
  382. package/dist/extensions/web-search/constants.d.ts +0 -13
  383. package/dist/extensions/web-search/constants.d.ts.map +0 -1
  384. package/dist/extensions/web-search/constants.js +0 -26
  385. package/dist/extensions/web-search/constants.js.map +0 -1
  386. package/dist/extensions/web-search/execute.d.ts +0 -9
  387. package/dist/extensions/web-search/execute.d.ts.map +0 -1
  388. package/dist/extensions/web-search/execute.js +0 -96
  389. package/dist/extensions/web-search/execute.js.map +0 -1
  390. package/dist/extensions/web-search/format.d.ts +0 -21
  391. package/dist/extensions/web-search/format.d.ts.map +0 -1
  392. package/dist/extensions/web-search/format.js +0 -117
  393. package/dist/extensions/web-search/format.js.map +0 -1
  394. package/dist/extensions/web-search/index.d.ts +0 -6
  395. package/dist/extensions/web-search/index.d.ts.map +0 -1
  396. package/dist/extensions/web-search/index.js +0 -50
  397. package/dist/extensions/web-search/index.js.map +0 -1
  398. package/dist/extensions/web-search/providers/deepseek.d.ts +0 -13
  399. package/dist/extensions/web-search/providers/deepseek.d.ts.map +0 -1
  400. package/dist/extensions/web-search/providers/deepseek.js +0 -110
  401. package/dist/extensions/web-search/providers/deepseek.js.map +0 -1
  402. package/dist/extensions/web-search/providers/http.d.ts +0 -4
  403. package/dist/extensions/web-search/providers/http.d.ts.map +0 -1
  404. package/dist/extensions/web-search/providers/http.js +0 -42
  405. package/dist/extensions/web-search/providers/http.js.map +0 -1
  406. package/dist/extensions/web-search/providers/minimax.d.ts +0 -12
  407. package/dist/extensions/web-search/providers/minimax.d.ts.map +0 -1
  408. package/dist/extensions/web-search/providers/minimax.js +0 -61
  409. package/dist/extensions/web-search/providers/minimax.js.map +0 -1
  410. package/dist/extensions/web-search/render.d.ts +0 -15
  411. package/dist/extensions/web-search/render.d.ts.map +0 -1
  412. package/dist/extensions/web-search/render.js +0 -142
  413. package/dist/extensions/web-search/render.js.map +0 -1
  414. package/dist/extensions/web-search/results.d.ts +0 -35
  415. package/dist/extensions/web-search/results.d.ts.map +0 -1
  416. package/dist/extensions/web-search/results.js +0 -167
  417. package/dist/extensions/web-search/results.js.map +0 -1
  418. package/dist/extensions/web-search/schema.d.ts +0 -10
  419. package/dist/extensions/web-search/schema.d.ts.map +0 -1
  420. package/dist/extensions/web-search/schema.js +0 -36
  421. package/dist/extensions/web-search/schema.js.map +0 -1
  422. package/dist/extensions/web-search/types.d.ts +0 -51
  423. package/dist/extensions/web-search/types.d.ts.map +0 -1
  424. package/dist/extensions/web-search/types.js +0 -5
  425. package/dist/extensions/web-search/types.js.map +0 -1
  426. package/dist/modes/interactive/theme/theme-json.d.ts +0 -85
  427. package/dist/modes/interactive/theme/theme-json.d.ts.map +0 -1
  428. package/dist/modes/interactive/theme/theme-json.js +0 -132
  429. package/dist/modes/interactive/theme/theme-json.js.map +0 -1
  430. package/dist/modes/interactive/theme/theme-schema.json +0 -361
  431. package/docs/bundled/extensions/web-search.md +0 -46
  432. package/examples/plugins/pi-example-plugin/README.md +0 -38
  433. package/examples/plugins/pi-example-plugin/package.json +0 -10
  434. package/examples/plugins/pi-example-plugin/src/contract.ts +0 -13
  435. package/examples/plugins/pi-example-plugin/src/session.ts +0 -24
  436. package/examples/plugins/pi-example-plugin/src/tui.ts +0 -31
@@ -16,7 +16,7 @@ import { createTasksToolDefinition } from "./tools/tasks.js";
16
16
  import { readFileSync } from "node:fs";
17
17
  import { basename, dirname } from "node:path";
18
18
  import { runToolCall, } from "@earendil-works/pi-agent-core";
19
- import { contentText, getCurrentSystemMessage, getSystemMessageText, retryDelayMs } from "@earendil-works/pi-ai";
19
+ import { contentText, getCurrentSystemMessage, retryDelayMs } from "@earendil-works/pi-ai";
20
20
  import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
21
21
  import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
22
22
  import { stripFrontmatter } from "../utils/frontmatter.js";
@@ -27,6 +27,7 @@ import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth
27
27
  import { executeBashWithOperations } from "./bash-executor.js";
28
28
  import { generateBugReportSummary } from "./bug-report.js";
29
29
  import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateProjectedContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
30
+ import { captureContextSnapshot } from "./context-snapshot.js";
30
31
  import { DEFAULT_THINKING_LEVEL, THINKING_LEVEL_OPTIONS } from "./defaults.js";
31
32
  import { exportSessionToHtml } from "./export-html/index.js";
32
33
  import { createToolHtmlRenderer } from "./export-html/tool-renderer.js";
@@ -39,7 +40,7 @@ import { NestedToolCallRunner } from "./nested-tool-calls.js";
39
40
  import { expandPromptTemplate } from "./prompt-templates.js";
40
41
  import { exportSessionToJsonl } from "./session-export.js";
41
42
  import { getLatestCompactionEntry, SessionManager, } from "./session-manager.js";
42
- import { DEFAULT_TOOL_NAMES } from "./settings-manager.js";
43
+ import { applyToolModifiers, DEFAULT_TOOL_NAMES, } from "./settings-manager.js";
43
44
  import { BUILTIN_PATH_PREFIX, createSyntheticSourceInfo, isSyntheticPath } from "./source-info.js";
44
45
  import { buildSystemPrompt, buildSystemPromptSections, diffSystemPromptSections, normalizeBuildSystemPromptOptions, } from "./system-prompt.js";
45
46
  import { TaskSession } from "./tasks/session.js";
@@ -139,6 +140,10 @@ export class AgentSession {
139
140
  this._handleAgentEvent = async (event) => {
140
141
  if (event.type === "message_start")
141
142
  this._tasksHost.delivery.messageStarted(event.message);
143
+ // An abort requested while the run was starting, e.g. during before_agent_start, stops it
144
+ // here. agent_start is awaited before the first request.
145
+ if (event.type === "agent_start" && this._agentRunAbortRequested)
146
+ this.agent.abort();
142
147
  // Record the calls a tool made through ctx.executeTool() and their usage on its result message.
143
148
  if (this._nestedToolCalls) {
144
149
  if (event.type === "message_start" && event.message.role === "toolResult") {
@@ -248,8 +253,9 @@ export class AgentSession {
248
253
  this.agent.steer(message);
249
254
  return waitForPersistence();
250
255
  }
251
- // Completion turns skip before_agent_start, but consume nextTurn context.
252
- return this._runAgentPrompt([message, ...this._pendingNextTurnMessages]);
256
+ // An idle delivery starts its own custom-message run, which consumes the
257
+ // pending nextTurn context in _prepareRun.
258
+ return this._startRun({ messageType: "custom", message });
253
259
  },
254
260
  onEntry: (entry) => this._emit({ type: "entry_appended", entry }),
255
261
  onError: (event, error) => this._extensionRunner?.emitError({ extensionPath: "<background>", event, error }),
@@ -267,6 +273,7 @@ export class AgentSession {
267
273
  this._extensionRunnerRef = config.extensionRunnerRef;
268
274
  this._initialActiveToolNames = config.initialActiveToolNames;
269
275
  this._usesDefaultTools = config.usesDefaultTools ?? false;
276
+ this._defaultToolModifiers = config.defaultToolModifiers ?? [];
270
277
  if (config.allowedToolNames) {
271
278
  this._allowedTools = createToolNameMatcher(config.allowedToolNames);
272
279
  this._allowlistFiltersMcp =
@@ -297,6 +304,10 @@ export class AgentSession {
297
304
  get quarantinedTaskSettlements() {
298
305
  return this._tasksHost.quarantinedSettlements;
299
306
  }
307
+ /** Running tasks that navigating to `targetId` would cancel, so a host can confirm first. */
308
+ tasksStoppedByTreeNavigation(targetId) {
309
+ return this._tasksHost.stoppedByTreeNavigation(targetId);
310
+ }
300
311
  /** Pause delivery across asynchronous lifecycle/preflight gaps. Nestable. */
301
312
  pauseTaskNotifications() {
302
313
  return this._tasksHost.delivery.pause();
@@ -322,48 +333,8 @@ export class AgentSession {
322
333
  return this._modelRuntime;
323
334
  }
324
335
  /** Capture stable state before any asynchronous context preparation. Never includes a partial stream. */
325
- async getContextSnapshot() {
326
- const model = this.model;
327
- if (!model)
328
- throw new Error("No model selected");
329
- const requestOptions = {
330
- sessionId: this.agent.sessionId ?? this.sessionManager.getSessionId(),
331
- transport: this.agent.transport,
332
- thinkingBudgets: structuredClone(this.agent.thinkingBudgets),
333
- maxRetryDelayMs: this.agent.maxRetryDelayMs,
334
- onPayload: this.agent.onPayload,
335
- onResponse: this.agent.onResponse,
336
- };
337
- const snapshot = {
338
- capturedAt: Date.now(),
339
- sessionId: this.sessionManager.getSessionId(),
340
- leafId: this.sessionManager.getLeafId(),
341
- model: structuredClone(model),
342
- thinkingLevel: this.thinkingLevel,
343
- tools: this.agent.state.tools.map(({ name, description, parameters, constrainedSampling }) => ({
344
- name,
345
- description,
346
- parameters: structuredClone(parameters),
347
- ...(constrainedSampling === undefined ? {} : { constrainedSampling: structuredClone(constrainedSampling) }),
348
- })),
349
- streamOptions: this._contextSource?.resolveStreamOptions(model, requestOptions) ?? requestOptions,
350
- };
351
- const currentSystemPrompt = this.systemPrompt;
352
- // The canonical projection is what the next request converts; the inspection cache may lag it.
353
- const messages = structuredClone(this.sessionManager.buildSessionProjection().messages);
354
- const convert = this.agent.convertToLlm;
355
- const transform = this.agent.transformContext;
356
- const prepared = this._contextSource
357
- ? await this._contextSource.prepareMessages(messages)
358
- : await convert(transform ? await transform(messages) : messages);
359
- // The prepared transcript declares the prompt the provider received, including a forced
360
- // prompt projected for the last request; before the first request there is none yet.
361
- const declared = getCurrentSystemMessage(prepared);
362
- return {
363
- ...snapshot,
364
- systemPrompt: declared ? getSystemMessageText(declared) : currentSystemPrompt,
365
- messages: structuredClone(prepared),
366
- };
336
+ getContextSnapshot() {
337
+ return captureContextSnapshot(this, this._contextSource);
367
338
  }
368
339
  async _getRequiredRequestAuth(model, signal) {
369
340
  let result;
@@ -841,8 +812,9 @@ export class AgentSession {
841
812
  this._isAgentRunActive = false;
842
813
  this._isEmittingAgentSettled = true;
843
814
  try {
844
- await this._extensionRunner.emit({ type: "agent_settled" });
845
- this._emit({ type: "agent_settled" });
815
+ const aborted = this._agentRunAbortRequested;
816
+ await this._extensionRunner.emit({ type: "agent_settled", aborted });
817
+ this._emit({ type: "agent_settled", aborted });
846
818
  }
847
819
  finally {
848
820
  this._isEmittingAgentSettled = false;
@@ -1036,6 +1008,7 @@ export class AgentSession {
1036
1008
  toolName: event.toolName,
1037
1009
  result: event.result,
1038
1010
  isError: event.isError,
1011
+ ...(event.durationMs === undefined ? {} : { durationMs: event.durationMs }),
1039
1012
  };
1040
1013
  await this._extensionRunner.emit(extensionEvent);
1041
1014
  }
@@ -1162,6 +1135,7 @@ export class AgentSession {
1162
1135
  exposure: this._getToolExposure(definition.name),
1163
1136
  ...(definition.namespace ? { namespace: definition.namespace } : {}),
1164
1137
  ...(definition.annotations ? { annotations: { ...definition.annotations } } : {}),
1138
+ ...(definition.reachesTools ? { reachesTools: definition.reachesTools } : {}),
1165
1139
  sourceInfo,
1166
1140
  }));
1167
1141
  }
@@ -1455,15 +1429,37 @@ export class AgentSession {
1455
1429
  // =========================================================================
1456
1430
  // Prompting
1457
1431
  // =========================================================================
1458
- async _runAgentPrompt(messages) {
1432
+ /**
1433
+ * Start a run from a user or custom message. The session counts as busy from here on, so
1434
+ * messages sent while before_agent_start handlers run are queued into this run instead of
1435
+ * starting another, and an abort requested meanwhile aborts the run as soon as it exists.
1436
+ * @param onStarted Called once the run's messages are prepared, before the first request.
1437
+ */
1438
+ async _startRun(trigger, onStarted) {
1439
+ this._isAgentRunActive = true;
1459
1440
  this._agentRunAbortRequested = false;
1441
+ let messages;
1442
+ try {
1443
+ messages = await this._prepareRun(trigger);
1444
+ }
1445
+ catch (error) {
1446
+ this._isAgentRunActive = false;
1447
+ this._flushPendingBashMessages();
1448
+ this._flushPendingCustomMessages();
1449
+ this._resolveIdleWaitIfIdle();
1450
+ throw error;
1451
+ }
1452
+ // Messages held while the run was starting go before its starting messages, as they would
1453
+ // have while idle. No run exists yet, so they cannot split a tool call from its result.
1454
+ this._flushPendingBashMessages();
1455
+ this._flushPendingCustomMessages();
1456
+ onStarted?.();
1460
1457
  // Compaction before the prompt may have scheduled a retry; the new prompt replaces it.
1461
1458
  this._failedResponse = undefined;
1462
1459
  this._recordSelection();
1463
1460
  // The run records the loadout in the transcript; restored tools that did not register by now
1464
1461
  // are dropped, so a tool that never registers does not stay pending.
1465
1462
  this._pendingToolNames.clear();
1466
- this._isAgentRunActive = true;
1467
1463
  try {
1468
1464
  await this.agent.prompt(messages);
1469
1465
  while (!this._agentRunAbortRequested) {
@@ -1490,6 +1486,64 @@ export class AgentSession {
1490
1486
  await this._emitAgentSettled();
1491
1487
  }
1492
1488
  }
1489
+ /**
1490
+ * Prepare a run and return its starting messages: compact first when needed, emit
1491
+ * before_agent_start, apply the run's prompt options and tool loadout, and build the starting
1492
+ * message followed by pending nextTurn messages (consumed here) and handler messages, with a
1493
+ * system patch first when the prompt changed.
1494
+ */
1495
+ async _prepareRun(trigger) {
1496
+ // Check if we need to compact before sending (catches aborted responses).
1497
+ // The starting message is sent below, so do not call agent.continue() here.
1498
+ const lastAssistant = this._findLastAssistantMessage();
1499
+ if (lastAssistant) {
1500
+ await this._checkCompaction(lastAssistant, false);
1501
+ }
1502
+ const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
1503
+ const result = await this._extensionRunner.emitBeforeAgentStart(trigger, this._baseSystemPromptOptions);
1504
+ // Handlers may edit event.systemPromptOptions.selectedTools or call setActiveTools(),
1505
+ // which updates the live loadout instead. An explicit edit wins; otherwise the live
1506
+ // loadout is authoritative, so a setActiveTools() call is not undone here.
1507
+ const handlerEditedTools = result.systemPromptOptions.selectedTools.length !== selectedToolsBefore.length ||
1508
+ result.systemPromptOptions.selectedTools.some((name, index) => name !== selectedToolsBefore[index]);
1509
+ if (!handlerEditedTools)
1510
+ result.systemPromptOptions.selectedTools = this.getActiveToolNames();
1511
+ const messages = [];
1512
+ if (trigger.messageType === "custom") {
1513
+ messages.push(trigger.message);
1514
+ }
1515
+ else {
1516
+ // Normalize images after before_agent_start so extension-driven model selection
1517
+ // determines the resize profile used for the request and history.
1518
+ const normalized = await this._normalizePromptImages(trigger.images);
1519
+ const text = normalized.hints.length > 0 ? `${trigger.prompt}\n\n${normalized.hints.join("\n")}` : trigger.prompt;
1520
+ messages.push({
1521
+ role: "user",
1522
+ content: [{ type: "text", text }, ...normalized.images],
1523
+ timestamp: Date.now(),
1524
+ });
1525
+ }
1526
+ // Inject any pending "nextTurn" messages as context alongside the starting message. Each
1527
+ // stays queued until _messagePersisted confirms its persistence, so a run that fails
1528
+ // before persisting it carries it into the next attempt.
1529
+ messages.push(...this._pendingNextTurnMessages);
1530
+ for (const msg of result.messages) {
1531
+ messages.push({
1532
+ role: "custom",
1533
+ customType: msg.customType,
1534
+ // Untyped extensions can pass null/missing content; normalize at ingestion.
1535
+ content: msg.content ?? [],
1536
+ display: msg.display,
1537
+ details: msg.details,
1538
+ timestamp: Date.now(),
1539
+ });
1540
+ }
1541
+ const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
1542
+ this._runSystemPromptOptions = result.systemPromptOptions;
1543
+ if (updateMessage)
1544
+ messages.unshift(updateMessage);
1545
+ return messages;
1546
+ }
1493
1547
  async _handlePostAgentRun() {
1494
1548
  const message = this._lastAssistantMessage;
1495
1549
  const toolResults = this._lastAssistantToolResults;
@@ -1593,133 +1647,98 @@ export class AgentSession {
1593
1647
  * @throws Error if no model selected or no API key available (when not streaming)
1594
1648
  */
1595
1649
  async prompt(text, options) {
1650
+ // A deferred prompt re-enters here after the settled handlers finish.
1651
+ if (this._isEmittingAgentSettled)
1652
+ return this._promptBody(text, options);
1653
+ // A user-initiated prompt is the recovery point for failed completion deliveries.
1654
+ this.retryTaskNotifications();
1655
+ // Extension commands may stay open indefinitely; only model input holds the preflight pause,
1656
+ // released once the prompt is handled, queued, or started.
1657
+ if (this._isExtensionCommandPrompt(text, options))
1658
+ return this._promptBody(text, options);
1659
+ const resumeBackground = this.pauseTaskNotifications();
1660
+ try {
1661
+ await this._promptBody(text, {
1662
+ ...options,
1663
+ preflightResult: (result) => {
1664
+ resumeBackground();
1665
+ options?.preflightResult?.(result);
1666
+ },
1667
+ });
1668
+ }
1669
+ finally {
1670
+ resumeBackground();
1671
+ }
1672
+ }
1673
+ _isExtensionCommandPrompt(text, options) {
1674
+ if (!(options?.expandPromptTemplates ?? true) || !text.startsWith("/"))
1675
+ return false;
1676
+ const spaceIndex = text.indexOf(" ");
1677
+ return (this._extensionRunner.getCommand(spaceIndex === -1 ? text.slice(1) : text.slice(1, spaceIndex)) !== undefined);
1678
+ }
1679
+ async _promptBody(text, options) {
1596
1680
  if (this._isEmittingAgentSettled) {
1597
1681
  this._deferredSettledActions.push(async () => await this.prompt(text, options));
1598
1682
  return;
1599
1683
  }
1600
- // A user-initiated prompt is the recovery point for failed completion deliveries.
1601
- this.retryTaskNotifications();
1602
1684
  const expandPromptTemplates = options?.expandPromptTemplates ?? true;
1603
1685
  const preflightResult = options?.preflightResult;
1604
- let messages;
1605
- let resumeBackground;
1606
- try {
1607
- // Handle extension commands first (execute immediately, even during streaming)
1608
- // Extension commands manage their own LLM interaction via pi.sendMessage()
1609
- if (expandPromptTemplates && text.startsWith("/")) {
1610
- const handled = await this._tryExecuteExtensionCommand(text);
1611
- if (handled) {
1612
- // Extension command executed, no prompt to send
1613
- preflightResult?.("handled");
1614
- return;
1615
- }
1616
- }
1617
- // Observer commands above may stay open indefinitely; only real model input owns
1618
- // the preflight pause, released once the user message is established.
1619
- resumeBackground = this.pauseTaskNotifications();
1620
- if (this._compactionAbortController !== undefined) {
1621
- throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
1622
- }
1623
- // Emit input event for extension interception (before skill/template expansion)
1624
- const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
1625
- if (!processedInput) {
1686
+ // Handle extension commands first (execute immediately, even during streaming)
1687
+ // Extension commands manage their own LLM interaction via pi.sendMessage()
1688
+ if (expandPromptTemplates && text.startsWith("/")) {
1689
+ const handled = await this._tryExecuteExtensionCommand(text);
1690
+ if (handled) {
1691
+ // Extension command executed, no prompt to send
1626
1692
  preflightResult?.("handled");
1627
1693
  return;
1628
1694
  }
1629
- const { text: currentText, images: currentImages } = processedInput;
1630
- // Expand skill commands (/skill:name args) and prompt templates (/template args)
1631
- let expandedText = currentText;
1632
- if (expandPromptTemplates) {
1633
- expandedText = this._expandSkillCommand(expandedText);
1634
- expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
1635
- }
1636
- // If streaming, queue via steer() or followUp() based on option
1637
- if (this.isStreaming) {
1638
- if (!options?.streamingBehavior) {
1639
- throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");
1640
- }
1641
- if (options.streamingBehavior === "followUp") {
1642
- await this._queueFollowUp(expandedText, currentImages);
1643
- }
1644
- else {
1645
- await this._queueSteer(expandedText, currentImages);
1646
- }
1647
- preflightResult?.("queued");
1648
- return;
1695
+ }
1696
+ if (this._compactionAbortController !== undefined) {
1697
+ throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
1698
+ }
1699
+ // Emit input event for extension interception (before skill/template expansion)
1700
+ const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
1701
+ if (!processedInput) {
1702
+ preflightResult?.("handled");
1703
+ return;
1704
+ }
1705
+ const { text: currentText, images: currentImages } = processedInput;
1706
+ // Expand skill commands (/skill:name args) and prompt templates (/template args)
1707
+ let expandedText = currentText;
1708
+ if (expandPromptTemplates) {
1709
+ expandedText = this._expandSkillCommand(expandedText);
1710
+ expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
1711
+ }
1712
+ // If streaming, queue via steer() or followUp() based on option
1713
+ if (this.isStreaming) {
1714
+ if (!options?.streamingBehavior) {
1715
+ throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");
1649
1716
  }
1650
- // Flush any pending bash and custom messages before the new prompt
1651
- this._flushPendingBashMessages();
1652
- this._flushPendingCustomMessages();
1653
- // Validate model
1654
- if (!this.model) {
1655
- throw new Error(formatNoModelSelectedMessage());
1717
+ if (options.streamingBehavior === "followUp") {
1718
+ await this._queueFollowUp(expandedText, currentImages);
1656
1719
  }
1657
- const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
1658
- (await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
1659
- if (!hasConfiguredAuth) {
1660
- const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
1661
- if (isOAuth) {
1662
- throw new Error(`Authentication failed for "${this.model.provider}". ` +
1663
- `Credentials may have expired or network is unavailable. ` +
1664
- `Run '/login ${this.model.provider}' to re-authenticate.`);
1665
- }
1666
- throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
1667
- }
1668
- // Check if we need to compact before sending (catches aborted responses).
1669
- // The user's new prompt is sent below, so do not call agent.continue() here.
1670
- const lastAssistant = this._findLastAssistantMessage();
1671
- if (lastAssistant) {
1672
- await this._checkCompaction(lastAssistant, false);
1673
- }
1674
- // Emit before_agent_start before normalizing images so extension-driven model
1675
- // selection determines the resize profile used for the request and history.
1676
- const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
1677
- const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPromptOptions);
1678
- // Handlers may edit event.systemPromptOptions.selectedTools or call setActiveTools(),
1679
- // which updates the live loadout instead. An explicit edit wins; otherwise the live
1680
- // loadout is authoritative, so a setActiveTools() call is not undone here.
1681
- const handlerEditedTools = result.systemPromptOptions.selectedTools.length !== selectedToolsBefore.length ||
1682
- result.systemPromptOptions.selectedTools.some((name, index) => name !== selectedToolsBefore[index]);
1683
- if (!handlerEditedTools)
1684
- result.systemPromptOptions.selectedTools = this.getActiveToolNames();
1685
- const normalized = await this._normalizePromptImages(currentImages);
1686
- const userText = normalized.hints.length > 0 ? `${expandedText}\n\n${normalized.hints.join("\n")}` : expandedText;
1687
- // Build messages only after hooks and image normalization have completed.
1688
- messages = [];
1689
- const userContent = [{ type: "text", text: userText }];
1690
- userContent.push(...normalized.images);
1691
- messages.push({
1692
- role: "user",
1693
- content: userContent,
1694
- timestamp: Date.now(),
1695
- });
1696
- // Inject any pending "nextTurn" messages as context alongside the user message
1697
- for (const msg of this._pendingNextTurnMessages) {
1698
- messages.push(msg);
1699
- }
1700
- for (const msg of result.messages) {
1701
- messages.push({
1702
- role: "custom",
1703
- customType: msg.customType,
1704
- // Untyped extensions can pass null/missing content; normalize at ingestion.
1705
- content: msg.content ?? [],
1706
- display: msg.display,
1707
- details: msg.details,
1708
- timestamp: Date.now(),
1709
- });
1720
+ else {
1721
+ await this._queueSteer(expandedText, currentImages);
1710
1722
  }
1711
- const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
1712
- this._runSystemPromptOptions = result.systemPromptOptions;
1713
- if (updateMessage)
1714
- messages.unshift(updateMessage);
1723
+ preflightResult?.("queued");
1724
+ return;
1715
1725
  }
1716
- finally {
1717
- resumeBackground?.();
1726
+ // Validate model
1727
+ if (!this.model) {
1728
+ throw new Error(formatNoModelSelectedMessage());
1718
1729
  }
1719
- if (!messages)
1720
- return;
1721
- preflightResult?.("started");
1722
- await this._runAgentPrompt(messages);
1730
+ const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
1731
+ (await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
1732
+ if (!hasConfiguredAuth) {
1733
+ const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
1734
+ if (isOAuth) {
1735
+ throw new Error(`Authentication failed for "${this.model.provider}". ` +
1736
+ `Credentials may have expired or network is unavailable. ` +
1737
+ `Run '/login ${this.model.provider}' to re-authenticate.`);
1738
+ }
1739
+ throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
1740
+ }
1741
+ await this._startRun({ messageType: "user", prompt: expandedText, images: currentImages }, () => preflightResult?.("started"));
1723
1742
  }
1724
1743
  /**
1725
1744
  * Try to execute an extension command. Returns true if command was found and executed.
@@ -1893,10 +1912,10 @@ export class AgentSession {
1893
1912
  }
1894
1913
  else if (options?.triggerTurn) {
1895
1914
  if (this._isEmittingAgentSettled) {
1896
- this._deferredSettledActions.push(async () => await this._runAgentPrompt(appMessage));
1915
+ this._deferredSettledActions.push(async () => await this.sendCustomMessage(message, options));
1897
1916
  return;
1898
1917
  }
1899
- await this._runAgentPrompt(appMessage);
1918
+ await this._startRun({ messageType: "custom", message: appMessage });
1900
1919
  }
1901
1920
  else if (this.isStreaming) {
1902
1921
  // Appending now would put the message between an assistant tool call and its
@@ -3059,7 +3078,10 @@ export class AgentSession {
3059
3078
  await Promise.all([this.tasks.shutdown(), this.abort()]);
3060
3079
  await emitSessionShutdownEvent(oldRunner, { type: "session_shutdown", reason: "reload" });
3061
3080
  oldRunner.invalidate();
3062
- const previousDefaultTools = new Set(this._usesDefaultTools ? (this.settingsManager.getDefaultTools() ?? DEFAULT_TOOL_NAMES) : []);
3081
+ const getDefaultTools = () => this._usesDefaultTools
3082
+ ? applyToolModifiers(this.settingsManager.getDefaultTools() ?? DEFAULT_TOOL_NAMES, this._defaultToolModifiers)
3083
+ : [];
3084
+ const previousDefaultTools = new Set(getDefaultTools());
3063
3085
  await this.settingsManager.reload();
3064
3086
  this.syncQueueModesFromSettings();
3065
3087
  resetApiProviders();
@@ -3067,9 +3089,7 @@ export class AgentSession {
3067
3089
  this._tasksHost.replaceService();
3068
3090
  // Activate tools newly added to defaultTools. Removed ones stay active, and tools disabled
3069
3091
  // during the session stay disabled unless the setting newly adds them.
3070
- const addedDefaultTools = this._usesDefaultTools
3071
- ? (this.settingsManager.getDefaultTools() ?? DEFAULT_TOOL_NAMES).filter((name) => !previousDefaultTools.has(name))
3072
- : [];
3092
+ const addedDefaultTools = getDefaultTools().filter((name) => !previousDefaultTools.has(name));
3073
3093
  // Tools the new extensions register later, such as MCP tools, are pending until then.
3074
3094
  for (const name of this.getActiveToolNames())
3075
3095
  this._pendingToolNames.add(name);
@@ -3318,19 +3338,6 @@ export class AgentSession {
3318
3338
  * @param options.label Label to attach to the branch summary entry
3319
3339
  * @returns Result with editorText (if user message) and cancelled status
3320
3340
  */
3321
- /**
3322
- * Running tasks that navigating to `targetId` would cancel, so a host can confirm first.
3323
- * Mirrors navigateTree's destination: selecting a user or custom message moves the leaf to its parent.
3324
- */
3325
- tasksStoppedByTreeNavigation(targetId) {
3326
- const target = this.sessionManager.getEntry(targetId);
3327
- if (!target)
3328
- return [];
3329
- const leafId = (target.type === "message" && target.message.role === "user") || target.type === "custom_message"
3330
- ? target.parentId
3331
- : targetId;
3332
- return this.tasks.activeOutsideBranch(new Set(leafId === null ? [] : this.sessionManager.getBranch(leafId).map((entry) => entry.id)));
3333
- }
3334
3341
  async navigateTree(targetId, options = {}) {
3335
3342
  if (this.isStreaming) {
3336
3343
  throw new Error("Wait for the current response to finish before navigating the session tree.");
@@ -3450,7 +3457,7 @@ export class AgentSession {
3450
3457
  // Non-user message: leaf = selected node
3451
3458
  newLeafId = targetId;
3452
3459
  }
3453
- await this.tasks.cancelOutsideBranch(new Set(newLeafId === null ? [] : this.sessionManager.getBranch(newLeafId).map((entry) => entry.id)));
3460
+ await this._tasksHost.cancelOutsideBranch(newLeafId);
3454
3461
  // Switch leaf (with or without summary)
3455
3462
  // Summary is attached at the navigation target position (newLeafId), not the old branch
3456
3463
  let summaryEntry;