@earendil-works/pi-coding-agent 0.87.1 → 0.99.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 (721) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/bun/cli.d.ts.map +1 -1
  3. package/dist/bun/restore-sandbox-env.d.ts.map +1 -1
  4. package/dist/bun/restore-sandbox-env.js.map +1 -1
  5. package/dist/bun/runtime-setup.d.ts.map +1 -1
  6. package/dist/bun/runtime-setup.js +4 -1
  7. package/dist/bun/runtime-setup.js.map +1 -1
  8. package/dist/bun/sandbox-env-setup.d.ts.map +1 -1
  9. package/dist/bundle/chunks/anthropic-messages-A6EXUBG6.js +6 -0
  10. package/dist/bundle/chunks/anthropic.js +2 -2
  11. package/dist/bundle/chunks/azure-openai-responses-EN5WOBET.js +2 -0
  12. package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
  13. package/dist/bundle/chunks/chunk-4CSSZFEW.js +1435 -0
  14. package/dist/bundle/chunks/chunk-7JGR3GZN.js +11 -0
  15. package/dist/bundle/chunks/chunk-AXPY26X7.js +146 -0
  16. package/dist/bundle/chunks/chunk-EPDRUIU6.js +2 -0
  17. package/dist/bundle/chunks/chunk-GOPCREV2.js +4 -0
  18. package/dist/bundle/chunks/chunk-H3QXYIF7.js +31 -0
  19. package/dist/bundle/chunks/{chunk-S7SZN6Z3.js → chunk-HSPCVFST.js} +1 -1
  20. package/dist/bundle/chunks/chunk-IMTXZUO7.js +82 -0
  21. package/dist/bundle/chunks/chunk-J4CWPC4N.js +2 -0
  22. package/dist/bundle/chunks/chunk-LLMKQWZS.js +21 -0
  23. package/dist/bundle/chunks/{chunk-WIUZI2CJ.js → chunk-LRS5S6EK.js} +3 -3
  24. package/dist/bundle/chunks/chunk-PEHWOV5U.js +187 -0
  25. package/dist/bundle/chunks/{chunk-XDUWOHPL.js → chunk-S3GGRYIO.js} +2 -2
  26. package/dist/bundle/chunks/chunk-UTB4DTYQ.js +2 -0
  27. package/dist/bundle/chunks/{chunk-FUXEF6JQ.js → chunk-W2DOMZSC.js} +1 -1
  28. package/dist/bundle/chunks/cli-AZXNGIZH.js +49 -0
  29. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-XJQQYGGU.js +2 -0
  30. package/dist/bundle/chunks/codemode-worker.js +295 -0
  31. package/dist/bundle/chunks/execute-7XXPZAWW.js +308 -0
  32. package/dist/bundle/chunks/github-copilot.js +1 -1
  33. package/dist/bundle/chunks/google-generative-ai-CQAKKJTA.js +2 -0
  34. package/dist/bundle/chunks/google-vertex-AE36YXJU.js +2 -0
  35. package/dist/bundle/chunks/{lib-HGQMNYVT.js → lib-TEDK3E5I.js} +2 -2
  36. package/dist/bundle/chunks/llama-cpp-classify-PJJYKPLD.js +22 -0
  37. package/dist/bundle/chunks/mistral-conversations-KEYTXJM7.js +5 -0
  38. package/dist/bundle/chunks/{openai-codex-responses-QDSOTBBO.js → openai-codex-responses-JQTCOVEG.js} +2 -2
  39. package/dist/bundle/chunks/openai-codex.js +2 -2
  40. package/dist/bundle/chunks/{openai-completions-OBX42CLD.js → openai-completions-XW2Q5HVC.js} +2 -2
  41. package/dist/bundle/chunks/openai-responses-6AXWFL75.js +3 -0
  42. package/dist/bundle/chunks/{openrouter-images-N4XVVFSD.js → openrouter-images-TPQ4V6OR.js} +1 -1
  43. package/dist/bundle/chunks/openrouter.js +2 -2
  44. package/dist/bundle/chunks/{pi-messages-GFKBWJHZ.js → pi-messages-TM5SOOIW.js} +2 -2
  45. package/dist/bundle/chunks/radius.js +2 -2
  46. package/dist/bundle/chunks/runtime-G5WJPRBM.js +2 -0
  47. package/dist/bundle/chunks/typesafe-system-one-E7A4HNJI.js +2 -0
  48. package/dist/bundle/chunks/virtual-modules-AQ3FLU6H.js +2 -0
  49. package/dist/bundle/cli-runtime.js +1 -1
  50. package/dist/bundle/index.js +1 -1
  51. package/dist/bundle/rpc-entry.js +1 -1
  52. package/dist/cli/args.d.ts.map +1 -1
  53. package/dist/cli/args.js +4 -3
  54. package/dist/cli/args.js.map +1 -1
  55. package/dist/cli/auth-check.d.ts.map +1 -1
  56. package/dist/cli/auth-check.js.map +1 -1
  57. package/dist/cli/auth-command.d.ts.map +1 -1
  58. package/dist/cli/auth-command.js.map +1 -1
  59. package/dist/cli/config-selector.d.ts.map +1 -1
  60. package/dist/cli/config-selector.js.map +1 -1
  61. package/dist/cli/credential-print.d.ts.map +1 -1
  62. package/dist/cli/credential-print.js.map +1 -1
  63. package/dist/cli/file-processor.d.ts.map +1 -1
  64. package/dist/cli/file-processor.js.map +1 -1
  65. package/dist/cli/initial-message.d.ts +1 -1
  66. package/dist/cli/initial-message.d.ts.map +1 -1
  67. package/dist/cli/initial-message.js.map +1 -1
  68. package/dist/cli/list-models.d.ts.map +1 -1
  69. package/dist/cli/list-models.js.map +1 -1
  70. package/dist/cli/project-trust.d.ts.map +1 -1
  71. package/dist/cli/project-trust.js.map +1 -1
  72. package/dist/cli/session-picker.d.ts.map +1 -1
  73. package/dist/cli/session-picker.js.map +1 -1
  74. package/dist/cli/setup.d.ts.map +1 -1
  75. package/dist/cli/setup.js.map +1 -1
  76. package/dist/cli/startup-ui.d.ts.map +1 -1
  77. package/dist/cli/startup-ui.js +38 -30
  78. package/dist/cli/startup-ui.js.map +1 -1
  79. package/dist/cli.d.ts.map +1 -1
  80. package/dist/config.d.ts +18 -4
  81. package/dist/config.d.ts.map +1 -1
  82. package/dist/config.js +30 -4
  83. package/dist/config.js.map +1 -1
  84. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  85. package/dist/core/agent-session-runtime.js +1 -1
  86. package/dist/core/agent-session-runtime.js.map +1 -1
  87. package/dist/core/agent-session-services.d.ts.map +1 -1
  88. package/dist/core/agent-session-services.js +13 -0
  89. package/dist/core/agent-session-services.js.map +1 -1
  90. package/dist/core/agent-session.d.ts +135 -11
  91. package/dist/core/agent-session.d.ts.map +1 -1
  92. package/dist/core/agent-session.js +509 -253
  93. package/dist/core/agent-session.js.map +1 -1
  94. package/dist/core/auth-guidance.d.ts.map +1 -1
  95. package/dist/core/auth-guidance.js.map +1 -1
  96. package/dist/core/auth-storage.d.ts.map +1 -1
  97. package/dist/core/auth-storage.js.map +1 -1
  98. package/dist/core/bash-executor.d.ts.map +1 -1
  99. package/dist/core/bash-executor.js.map +1 -1
  100. package/dist/core/bug-report-upload.d.ts.map +1 -1
  101. package/dist/core/bug-report-upload.js.map +1 -1
  102. package/dist/core/bug-report.d.ts +1 -1
  103. package/dist/core/bug-report.d.ts.map +1 -1
  104. package/dist/core/bug-report.js +1 -1
  105. package/dist/core/bug-report.js.map +1 -1
  106. package/dist/core/cache-stats.d.ts.map +1 -1
  107. package/dist/core/cache-stats.js.map +1 -1
  108. package/dist/core/cache-warmer.d.ts.map +1 -1
  109. package/dist/core/cache-warmer.js.map +1 -1
  110. package/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  111. package/dist/core/compaction/branch-summarization.js.map +1 -1
  112. package/dist/core/compaction/compaction.d.ts.map +1 -1
  113. package/dist/core/compaction/compaction.js +1 -22
  114. package/dist/core/compaction/compaction.js.map +1 -1
  115. package/dist/core/compaction/index.d.ts.map +1 -1
  116. package/dist/core/compaction/utils.d.ts +2 -1
  117. package/dist/core/compaction/utils.d.ts.map +1 -1
  118. package/dist/core/compaction/utils.js +25 -18
  119. package/dist/core/compaction/utils.js.map +1 -1
  120. package/dist/core/crash-log.d.ts.map +1 -1
  121. package/dist/core/crash-log.js +2 -1
  122. package/dist/core/crash-log.js.map +1 -1
  123. package/dist/core/defaults.d.ts.map +1 -1
  124. package/dist/core/diagnostics.d.ts.map +1 -1
  125. package/dist/core/event-bus.d.ts.map +1 -1
  126. package/dist/core/event-bus.js.map +1 -1
  127. package/dist/core/exec.d.ts.map +1 -1
  128. package/dist/core/exec.js.map +1 -1
  129. package/dist/core/experimental.d.ts.map +1 -1
  130. package/dist/core/experimental.js.map +1 -1
  131. package/dist/core/export-html/ansi-to-html.d.ts.map +1 -1
  132. package/dist/core/export-html/ansi-to-html.js.map +1 -1
  133. package/dist/core/export-html/index.d.ts.map +1 -1
  134. package/dist/core/export-html/index.js.map +1 -1
  135. package/dist/core/export-html/template.css +10 -0
  136. package/dist/core/export-html/template.js +66 -17
  137. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  138. package/dist/core/export-html/tool-renderer.js.map +1 -1
  139. package/dist/core/extensions/index.d.ts +1 -1
  140. package/dist/core/extensions/index.d.ts.map +1 -1
  141. package/dist/core/extensions/index.js.map +1 -1
  142. package/dist/core/extensions/jiti-loader.d.ts.map +1 -1
  143. package/dist/core/extensions/jiti-static-loader.d.ts.map +1 -1
  144. package/dist/core/extensions/loader.d.ts.map +1 -1
  145. package/dist/core/extensions/loader.js +55 -5
  146. package/dist/core/extensions/loader.js.map +1 -1
  147. package/dist/core/extensions/runner.d.ts +18 -1
  148. package/dist/core/extensions/runner.d.ts.map +1 -1
  149. package/dist/core/extensions/runner.js +99 -0
  150. package/dist/core/extensions/runner.js.map +1 -1
  151. package/dist/core/extensions/types.d.ts +296 -22
  152. package/dist/core/extensions/types.d.ts.map +1 -1
  153. package/dist/core/extensions/types.js.map +1 -1
  154. package/dist/core/extensions/virtual-modules.d.ts.map +1 -1
  155. package/dist/core/extensions/wrapper.d.ts +2 -2
  156. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  157. package/dist/core/extensions/wrapper.js +3 -3
  158. package/dist/core/extensions/wrapper.js.map +1 -1
  159. package/dist/core/footer-data-provider.d.ts.map +1 -1
  160. package/dist/core/footer-data-provider.js.map +1 -1
  161. package/dist/core/http-dispatcher.d.ts.map +1 -1
  162. package/dist/core/http-dispatcher.js.map +1 -1
  163. package/dist/core/index.d.ts.map +1 -1
  164. package/dist/core/keybindings.d.ts +1 -1
  165. package/dist/core/keybindings.d.ts.map +1 -1
  166. package/dist/core/keybindings.js +1 -1
  167. package/dist/core/keybindings.js.map +1 -1
  168. package/dist/core/mcp-servers.d.ts +98 -0
  169. package/dist/core/mcp-servers.d.ts.map +1 -0
  170. package/dist/core/mcp-servers.js +157 -0
  171. package/dist/core/mcp-servers.js.map +1 -0
  172. package/dist/core/messages.d.ts.map +1 -1
  173. package/dist/core/messages.js.map +1 -1
  174. package/dist/core/model-config.d.ts.map +1 -1
  175. package/dist/core/model-config.js.map +1 -1
  176. package/dist/core/model-registry.d.ts +13 -1
  177. package/dist/core/model-registry.d.ts.map +1 -1
  178. package/dist/core/model-registry.js +25 -0
  179. package/dist/core/model-registry.js.map +1 -1
  180. package/dist/core/model-resolver.d.ts +2 -2
  181. package/dist/core/model-resolver.d.ts.map +1 -1
  182. package/dist/core/model-resolver.js +4 -4
  183. package/dist/core/model-resolver.js.map +1 -1
  184. package/dist/core/model-runtime.d.ts +41 -3
  185. package/dist/core/model-runtime.d.ts.map +1 -1
  186. package/dist/core/model-runtime.js +167 -17
  187. package/dist/core/model-runtime.js.map +1 -1
  188. package/dist/core/models-store.d.ts.map +1 -1
  189. package/dist/core/models-store.js.map +1 -1
  190. package/dist/core/nested-tool-calls.d.ts +102 -0
  191. package/dist/core/nested-tool-calls.d.ts.map +1 -0
  192. package/dist/core/nested-tool-calls.js +178 -0
  193. package/dist/core/nested-tool-calls.js.map +1 -0
  194. package/dist/core/output-guard.d.ts.map +1 -1
  195. package/dist/core/output-guard.js.map +1 -1
  196. package/dist/core/package-manager.d.ts +4 -0
  197. package/dist/core/package-manager.d.ts.map +1 -1
  198. package/dist/core/package-manager.js +59 -12
  199. package/dist/core/package-manager.js.map +1 -1
  200. package/dist/core/pi-manifest.d.ts.map +1 -1
  201. package/dist/core/pi-manifest.js.map +1 -1
  202. package/dist/core/project-trust.d.ts.map +1 -1
  203. package/dist/core/project-trust.js.map +1 -1
  204. package/dist/core/prompt-templates.d.ts.map +1 -1
  205. package/dist/core/prompt-templates.js.map +1 -1
  206. package/dist/core/provider-attribution.d.ts.map +1 -1
  207. package/dist/core/provider-attribution.js.map +1 -1
  208. package/dist/core/provider-composer.d.ts +40 -21
  209. package/dist/core/provider-composer.d.ts.map +1 -1
  210. package/dist/core/provider-composer.js +92 -40
  211. package/dist/core/provider-composer.js.map +1 -1
  212. package/dist/core/radius.d.ts.map +1 -1
  213. package/dist/core/radius.js.map +1 -1
  214. package/dist/core/remote-catalog-provider.d.ts +8 -1
  215. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  216. package/dist/core/remote-catalog-provider.js +18 -3
  217. package/dist/core/remote-catalog-provider.js.map +1 -1
  218. package/dist/core/resolve-config-value.d.ts.map +1 -1
  219. package/dist/core/resolve-config-value.js.map +1 -1
  220. package/dist/core/resource-loader.d.ts +7 -1
  221. package/dist/core/resource-loader.d.ts.map +1 -1
  222. package/dist/core/resource-loader.js +161 -35
  223. package/dist/core/resource-loader.js.map +1 -1
  224. package/dist/core/runtime-credentials.d.ts.map +1 -1
  225. package/dist/core/runtime-credentials.js.map +1 -1
  226. package/dist/core/sdk.d.ts +1 -1
  227. package/dist/core/sdk.d.ts.map +1 -1
  228. package/dist/core/sdk.js +24 -6
  229. package/dist/core/sdk.js.map +1 -1
  230. package/dist/core/session-cwd.d.ts.map +1 -1
  231. package/dist/core/session-cwd.js.map +1 -1
  232. package/dist/core/session-export.d.ts.map +1 -1
  233. package/dist/core/session-export.js.map +1 -1
  234. package/dist/core/session-manager.d.ts +9 -0
  235. package/dist/core/session-manager.d.ts.map +1 -1
  236. package/dist/core/session-manager.js +22 -22
  237. package/dist/core/session-manager.js.map +1 -1
  238. package/dist/core/settings-diagnostics.d.ts.map +1 -1
  239. package/dist/core/settings-diagnostics.js.map +1 -1
  240. package/dist/core/settings-manager.d.ts +31 -1
  241. package/dist/core/settings-manager.d.ts.map +1 -1
  242. package/dist/core/settings-manager.js +72 -2
  243. package/dist/core/settings-manager.js.map +1 -1
  244. package/dist/core/skills.d.ts.map +1 -1
  245. package/dist/core/skills.js.map +1 -1
  246. package/dist/core/slash-commands.d.ts.map +1 -1
  247. package/dist/core/source-info.d.ts +8 -0
  248. package/dist/core/source-info.d.ts.map +1 -1
  249. package/dist/core/source-info.js +16 -0
  250. package/dist/core/source-info.js.map +1 -1
  251. package/dist/core/system-prompt.d.ts.map +1 -1
  252. package/dist/core/system-prompt.js +1 -1
  253. package/dist/core/system-prompt.js.map +1 -1
  254. package/dist/core/telemetry.d.ts.map +1 -1
  255. package/dist/core/telemetry.js.map +1 -1
  256. package/dist/core/timings.d.ts.map +1 -1
  257. package/dist/core/timings.js.map +1 -1
  258. package/dist/core/tools/bash.d.ts +12 -0
  259. package/dist/core/tools/bash.d.ts.map +1 -1
  260. package/dist/core/tools/bash.js +35 -2
  261. package/dist/core/tools/bash.js.map +1 -1
  262. package/dist/core/tools/edit-diff.d.ts.map +1 -1
  263. package/dist/core/tools/edit-diff.js.map +1 -1
  264. package/dist/core/tools/edit.d.ts.map +1 -1
  265. package/dist/core/tools/edit.js.map +1 -1
  266. package/dist/core/tools/file-mutation-queue.d.ts.map +1 -1
  267. package/dist/core/tools/file-mutation-queue.js.map +1 -1
  268. package/dist/core/tools/find.d.ts.map +1 -1
  269. package/dist/core/tools/find.js.map +1 -1
  270. package/dist/core/tools/grep.d.ts.map +1 -1
  271. package/dist/core/tools/grep.js.map +1 -1
  272. package/dist/core/tools/index.d.ts.map +1 -1
  273. package/dist/core/tools/index.js.map +1 -1
  274. package/dist/core/tools/ls.d.ts.map +1 -1
  275. package/dist/core/tools/ls.js.map +1 -1
  276. package/dist/core/tools/output-accumulator.d.ts +11 -0
  277. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  278. package/dist/core/tools/output-accumulator.js +36 -0
  279. package/dist/core/tools/output-accumulator.js.map +1 -1
  280. package/dist/core/tools/path-utils.d.ts.map +1 -1
  281. package/dist/core/tools/path-utils.js.map +1 -1
  282. package/dist/core/tools/powershell.d.ts.map +1 -1
  283. package/dist/core/tools/powershell.js.map +1 -1
  284. package/dist/core/tools/read.d.ts.map +1 -1
  285. package/dist/core/tools/read.js.map +1 -1
  286. package/dist/core/tools/render-utils.d.ts +6 -0
  287. package/dist/core/tools/render-utils.d.ts.map +1 -1
  288. package/dist/core/tools/render-utils.js +26 -0
  289. package/dist/core/tools/render-utils.js.map +1 -1
  290. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  291. package/dist/core/tools/renderers/bash.js +9 -10
  292. package/dist/core/tools/renderers/bash.js.map +1 -1
  293. package/dist/core/tools/renderers/edit.d.ts.map +1 -1
  294. package/dist/core/tools/renderers/edit.js.map +1 -1
  295. package/dist/core/tools/renderers/find.d.ts.map +1 -1
  296. package/dist/core/tools/renderers/find.js.map +1 -1
  297. package/dist/core/tools/renderers/grep.d.ts.map +1 -1
  298. package/dist/core/tools/renderers/grep.js.map +1 -1
  299. package/dist/core/tools/renderers/index.d.ts.map +1 -1
  300. package/dist/core/tools/renderers/index.js.map +1 -1
  301. package/dist/core/tools/renderers/ls.d.ts.map +1 -1
  302. package/dist/core/tools/renderers/ls.js.map +1 -1
  303. package/dist/core/tools/renderers/read.d.ts.map +1 -1
  304. package/dist/core/tools/renderers/read.js +3 -2
  305. package/dist/core/tools/renderers/read.js.map +1 -1
  306. package/dist/core/tools/renderers/write.d.ts.map +1 -1
  307. package/dist/core/tools/renderers/write.js.map +1 -1
  308. package/dist/core/tools/tool-definition-wrapper.d.ts +5 -3
  309. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  310. package/dist/core/tools/tool-definition-wrapper.js +3 -1
  311. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  312. package/dist/core/tools/truncate.d.ts +14 -0
  313. package/dist/core/tools/truncate.d.ts.map +1 -1
  314. package/dist/core/tools/truncate.js +29 -0
  315. package/dist/core/tools/truncate.js.map +1 -1
  316. package/dist/core/tools/write.d.ts.map +1 -1
  317. package/dist/core/tools/write.js.map +1 -1
  318. package/dist/core/trust-manager.d.ts.map +1 -1
  319. package/dist/core/trust-manager.js +1 -0
  320. package/dist/core/trust-manager.js.map +1 -1
  321. package/dist/core/usage-totals.d.ts +2 -0
  322. package/dist/core/usage-totals.d.ts.map +1 -1
  323. package/dist/core/usage-totals.js +23 -0
  324. package/dist/core/usage-totals.js.map +1 -1
  325. package/dist/core/virtual-models.d.ts +115 -0
  326. package/dist/core/virtual-models.d.ts.map +1 -0
  327. package/dist/core/virtual-models.js +117 -0
  328. package/dist/core/virtual-models.js.map +1 -0
  329. package/dist/extensions/codemode/execute.d.ts +16 -0
  330. package/dist/extensions/codemode/execute.d.ts.map +1 -0
  331. package/dist/extensions/codemode/execute.js +390 -0
  332. package/dist/extensions/codemode/execute.js.map +1 -0
  333. package/dist/extensions/codemode/execute.lazy.d.ts +3 -0
  334. package/dist/extensions/codemode/execute.lazy.d.ts.map +1 -0
  335. package/dist/extensions/codemode/execute.lazy.js +3 -0
  336. package/dist/extensions/codemode/execute.lazy.js.map +1 -0
  337. package/dist/extensions/codemode/index.d.ts +21 -0
  338. package/dist/extensions/codemode/index.d.ts.map +1 -0
  339. package/dist/extensions/codemode/index.js +31 -0
  340. package/dist/extensions/codemode/index.js.map +1 -0
  341. package/dist/extensions/codemode/renderer.d.ts +12 -0
  342. package/dist/extensions/codemode/renderer.d.ts.map +1 -0
  343. package/dist/extensions/codemode/renderer.js +119 -0
  344. package/dist/extensions/codemode/renderer.js.map +1 -0
  345. package/dist/extensions/codemode/tool.d.ts +122 -0
  346. package/dist/extensions/codemode/tool.d.ts.map +1 -0
  347. package/dist/extensions/codemode/tool.js +324 -0
  348. package/dist/extensions/codemode/tool.js.map +1 -0
  349. package/dist/extensions/codemode/worker.d.ts +7 -0
  350. package/dist/extensions/codemode/worker.d.ts.map +1 -0
  351. package/dist/extensions/codemode/worker.js +7 -0
  352. package/dist/extensions/codemode/worker.js.map +1 -0
  353. package/dist/extensions/index.d.ts.map +1 -1
  354. package/dist/extensions/index.js +11 -1
  355. package/dist/extensions/index.js.map +1 -1
  356. package/dist/extensions/llama/client.d.ts.map +1 -1
  357. package/dist/extensions/llama/client.js.map +1 -1
  358. package/dist/extensions/llama/huggingface.d.ts.map +1 -1
  359. package/dist/extensions/llama/huggingface.js.map +1 -1
  360. package/dist/extensions/llama/index.d.ts.map +1 -1
  361. package/dist/extensions/llama/index.js.map +1 -1
  362. package/dist/extensions/llama/provider.d.ts +1 -1
  363. package/dist/extensions/llama/provider.d.ts.map +1 -1
  364. package/dist/extensions/llama/provider.js +65 -13
  365. package/dist/extensions/llama/provider.js.map +1 -1
  366. package/dist/extensions/llama/ui.d.ts.map +1 -1
  367. package/dist/extensions/llama/ui.js.map +1 -1
  368. package/dist/extensions/mcp/cli.d.ts +21 -0
  369. package/dist/extensions/mcp/cli.d.ts.map +1 -0
  370. package/dist/extensions/mcp/cli.js +485 -0
  371. package/dist/extensions/mcp/cli.js.map +1 -0
  372. package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
  373. package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
  374. package/dist/extensions/mcp/cli.lazy.js +3 -0
  375. package/dist/extensions/mcp/cli.lazy.js.map +1 -0
  376. package/dist/extensions/mcp/config.d.ts +70 -0
  377. package/dist/extensions/mcp/config.d.ts.map +1 -0
  378. package/dist/extensions/mcp/config.js +146 -0
  379. package/dist/extensions/mcp/config.js.map +1 -0
  380. package/dist/extensions/mcp/index.d.ts +52 -0
  381. package/dist/extensions/mcp/index.d.ts.map +1 -0
  382. package/dist/extensions/mcp/index.js +902 -0
  383. package/dist/extensions/mcp/index.js.map +1 -0
  384. package/dist/extensions/mcp/log.d.ts +16 -0
  385. package/dist/extensions/mcp/log.d.ts.map +1 -0
  386. package/dist/extensions/mcp/log.js +66 -0
  387. package/dist/extensions/mcp/log.js.map +1 -0
  388. package/dist/extensions/mcp/oauth.d.ts +94 -0
  389. package/dist/extensions/mcp/oauth.d.ts.map +1 -0
  390. package/dist/extensions/mcp/oauth.js +333 -0
  391. package/dist/extensions/mcp/oauth.js.map +1 -0
  392. package/dist/extensions/mcp/resources.d.ts +43 -0
  393. package/dist/extensions/mcp/resources.d.ts.map +1 -0
  394. package/dist/extensions/mcp/resources.js +262 -0
  395. package/dist/extensions/mcp/resources.js.map +1 -0
  396. package/dist/extensions/mcp/runtime.d.ts +96 -0
  397. package/dist/extensions/mcp/runtime.d.ts.map +1 -0
  398. package/dist/extensions/mcp/runtime.js +388 -0
  399. package/dist/extensions/mcp/runtime.js.map +1 -0
  400. package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
  401. package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
  402. package/dist/extensions/mcp/runtime.lazy.js +3 -0
  403. package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
  404. package/dist/extensions/mcp/tools.d.ts +83 -0
  405. package/dist/extensions/mcp/tools.d.ts.map +1 -0
  406. package/dist/extensions/mcp/tools.js +233 -0
  407. package/dist/extensions/mcp/tools.js.map +1 -0
  408. package/dist/extensions/mcp/ui.d.ts +60 -0
  409. package/dist/extensions/mcp/ui.d.ts.map +1 -0
  410. package/dist/extensions/mcp/ui.js +172 -0
  411. package/dist/extensions/mcp/ui.js.map +1 -0
  412. package/dist/extensions/tool-search/index.d.ts +12 -0
  413. package/dist/extensions/tool-search/index.d.ts.map +1 -0
  414. package/dist/extensions/tool-search/index.js +15 -0
  415. package/dist/extensions/tool-search/index.js.map +1 -0
  416. package/dist/extensions/tool-search/tool.d.ts +72 -0
  417. package/dist/extensions/tool-search/tool.d.ts.map +1 -0
  418. package/dist/extensions/tool-search/tool.js +210 -0
  419. package/dist/extensions/tool-search/tool.js.map +1 -0
  420. package/dist/index.d.ts +9 -2
  421. package/dist/index.d.ts.map +1 -1
  422. package/dist/index.js +5 -0
  423. package/dist/index.js.map +1 -1
  424. package/dist/main.d.ts.map +1 -1
  425. package/dist/main.js +10 -0
  426. package/dist/main.js.map +1 -1
  427. package/dist/migrations.d.ts.map +1 -1
  428. package/dist/migrations.js.map +1 -1
  429. package/dist/modes/index.d.ts.map +1 -1
  430. package/dist/modes/interactive/bug-report.d.ts.map +1 -1
  431. package/dist/modes/interactive/bug-report.js.map +1 -1
  432. package/dist/modes/interactive/chat-viewport.d.ts.map +1 -1
  433. package/dist/modes/interactive/chat-viewport.js.map +1 -1
  434. package/dist/modes/interactive/components/armin.d.ts.map +1 -1
  435. package/dist/modes/interactive/components/armin.js.map +1 -1
  436. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  437. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  438. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  439. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  440. package/dist/modes/interactive/components/bordered-loader.d.ts.map +1 -1
  441. package/dist/modes/interactive/components/bordered-loader.js.map +1 -1
  442. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  443. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  444. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  445. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  446. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  447. package/dist/modes/interactive/components/config-selector.js +13 -3
  448. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  449. package/dist/modes/interactive/components/countdown-timer.d.ts.map +1 -1
  450. package/dist/modes/interactive/components/countdown-timer.js.map +1 -1
  451. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  452. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  453. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  454. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  455. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  456. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  457. package/dist/modes/interactive/components/daxnuts.d.ts.map +1 -1
  458. package/dist/modes/interactive/components/daxnuts.js.map +1 -1
  459. package/dist/modes/interactive/components/diff.d.ts.map +1 -1
  460. package/dist/modes/interactive/components/diff.js.map +1 -1
  461. package/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  462. package/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  463. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -1
  464. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -1
  465. package/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  466. package/dist/modes/interactive/components/extension-editor.js.map +1 -1
  467. package/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  468. package/dist/modes/interactive/components/extension-input.js.map +1 -1
  469. package/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  470. package/dist/modes/interactive/components/extension-selector.js.map +1 -1
  471. package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
  472. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  473. package/dist/modes/interactive/components/first-time-setup.js +8 -2
  474. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  475. package/dist/modes/interactive/components/footer.d.ts +7 -0
  476. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  477. package/dist/modes/interactive/components/footer.js +43 -3
  478. package/dist/modes/interactive/components/footer.js.map +1 -1
  479. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  480. package/dist/modes/interactive/components/keybinding-hints.d.ts.map +1 -1
  481. package/dist/modes/interactive/components/keybinding-hints.js.map +1 -1
  482. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  483. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  484. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -1
  485. package/dist/modes/interactive/components/markdown-transform.js.map +1 -1
  486. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -1
  487. package/dist/modes/interactive/components/mermaid.js.map +1 -1
  488. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  489. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  490. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  491. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  492. package/dist/modes/interactive/components/pi-logo.d.ts +12 -0
  493. package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -0
  494. package/dist/modes/interactive/components/pi-logo.js +25 -0
  495. package/dist/modes/interactive/components/pi-logo.js.map +1 -0
  496. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  497. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  498. package/dist/modes/interactive/components/session-selector-search.d.ts.map +1 -1
  499. package/dist/modes/interactive/components/session-selector-search.js.map +1 -1
  500. package/dist/modes/interactive/components/session-selector.d.ts.map +1 -1
  501. package/dist/modes/interactive/components/session-selector.js.map +1 -1
  502. package/dist/modes/interactive/components/settings-selector.d.ts +3 -1
  503. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  504. package/dist/modes/interactive/components/settings-selector.js +28 -6
  505. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  506. package/dist/modes/interactive/components/settings-submenu.d.ts.map +1 -1
  507. package/dist/modes/interactive/components/settings-submenu.js.map +1 -1
  508. package/dist/modes/interactive/components/show-images-selector.d.ts.map +1 -1
  509. package/dist/modes/interactive/components/show-images-selector.js.map +1 -1
  510. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  511. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  512. package/dist/modes/interactive/components/status-indicator.d.ts.map +1 -1
  513. package/dist/modes/interactive/components/status-indicator.js.map +1 -1
  514. package/dist/modes/interactive/components/theme-selector.d.ts.map +1 -1
  515. package/dist/modes/interactive/components/theme-selector.js.map +1 -1
  516. package/dist/modes/interactive/components/themed-text.d.ts +17 -0
  517. package/dist/modes/interactive/components/themed-text.d.ts.map +1 -0
  518. package/dist/modes/interactive/components/themed-text.js +29 -0
  519. package/dist/modes/interactive/components/themed-text.js.map +1 -0
  520. package/dist/modes/interactive/components/thinking-selector.d.ts.map +1 -1
  521. package/dist/modes/interactive/components/thinking-selector.js.map +1 -1
  522. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  523. package/dist/modes/interactive/components/tool-execution.js +2 -2
  524. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  525. package/dist/modes/interactive/components/tree-selector.d.ts.map +1 -1
  526. package/dist/modes/interactive/components/tree-selector.js.map +1 -1
  527. package/dist/modes/interactive/components/trust-selector.d.ts.map +1 -1
  528. package/dist/modes/interactive/components/trust-selector.js.map +1 -1
  529. package/dist/modes/interactive/components/user-message-selector.d.ts.map +1 -1
  530. package/dist/modes/interactive/components/user-message-selector.js.map +1 -1
  531. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  532. package/dist/modes/interactive/components/user-message.js.map +1 -1
  533. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  534. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  535. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  536. package/dist/modes/interactive/external-editor.js.map +1 -1
  537. package/dist/modes/interactive/interactive-mode.d.ts +11 -0
  538. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  539. package/dist/modes/interactive/interactive-mode.js +199 -161
  540. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  541. package/dist/modes/interactive/model-catalog-refresh.d.ts.map +1 -1
  542. package/dist/modes/interactive/model-catalog-refresh.js.map +1 -1
  543. package/dist/modes/interactive/model-search.d.ts.map +1 -1
  544. package/dist/modes/interactive/model-search.js.map +1 -1
  545. package/dist/modes/interactive/session-share.d.ts.map +1 -1
  546. package/dist/modes/interactive/session-share.js.map +1 -1
  547. package/dist/modes/interactive/theme/dark.json +59 -72
  548. package/dist/modes/interactive/theme/light.json +57 -69
  549. package/dist/modes/interactive/theme/system-theme.d.ts +54 -0
  550. package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
  551. package/dist/modes/interactive/theme/system-theme.js +535 -0
  552. package/dist/modes/interactive/theme/system-theme.js.map +1 -0
  553. package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
  554. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  555. package/dist/modes/interactive/theme/theme-controller.js +127 -47
  556. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  557. package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
  558. package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -1
  559. package/dist/modes/interactive/theme/theme-json.js +3 -1
  560. package/dist/modes/interactive/theme/theme-json.js.map +1 -1
  561. package/dist/modes/interactive/theme/theme-schema.json +7 -2
  562. package/dist/modes/interactive/theme/theme.d.ts +66 -39
  563. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  564. package/dist/modes/interactive/theme/theme.js +238 -317
  565. package/dist/modes/interactive/theme/theme.js.map +1 -1
  566. package/dist/modes/interactive/tui-renderer.d.ts +2 -1
  567. package/dist/modes/interactive/tui-renderer.d.ts.map +1 -1
  568. package/dist/modes/interactive/tui-renderer.js +1 -0
  569. package/dist/modes/interactive/tui-renderer.js.map +1 -1
  570. package/dist/modes/json-event.d.ts.map +1 -1
  571. package/dist/modes/json-event.js.map +1 -1
  572. package/dist/modes/print-mode.d.ts.map +1 -1
  573. package/dist/modes/print-mode.js.map +1 -1
  574. package/dist/modes/rpc/jsonl.d.ts.map +1 -1
  575. package/dist/modes/rpc/jsonl.js.map +1 -1
  576. package/dist/modes/rpc/rpc-client.d.ts +6 -6
  577. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  578. package/dist/modes/rpc/rpc-client.js +12 -8
  579. package/dist/modes/rpc/rpc-client.js.map +1 -1
  580. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  581. package/dist/modes/rpc/rpc-mode.js +7 -9
  582. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  583. package/dist/modes/rpc/rpc-types.d.ts +10 -1
  584. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  585. package/dist/modes/rpc/rpc-types.js.map +1 -1
  586. package/dist/package-manager-cli.d.ts.map +1 -1
  587. package/dist/package-manager-cli.js +6 -2
  588. package/dist/package-manager-cli.js.map +1 -1
  589. package/dist/rpc-entry.d.ts.map +1 -1
  590. package/dist/rpc-entry.js.map +1 -1
  591. package/dist/utils/abort.d.ts.map +1 -1
  592. package/dist/utils/abort.js.map +1 -1
  593. package/dist/utils/ansi.d.ts.map +1 -1
  594. package/dist/utils/ansi.js.map +1 -1
  595. package/dist/utils/changelog.d.ts.map +1 -1
  596. package/dist/utils/changelog.js.map +1 -1
  597. package/dist/utils/child-process.d.ts.map +1 -1
  598. package/dist/utils/child-process.js.map +1 -1
  599. package/dist/utils/clipboard-command.d.ts.map +1 -1
  600. package/dist/utils/clipboard-command.js.map +1 -1
  601. package/dist/utils/clipboard-image.d.ts.map +1 -1
  602. package/dist/utils/clipboard-image.js +14 -17
  603. package/dist/utils/clipboard-image.js.map +1 -1
  604. package/dist/utils/clipboard.d.ts +2 -0
  605. package/dist/utils/clipboard.d.ts.map +1 -1
  606. package/dist/utils/clipboard.js +5 -0
  607. package/dist/utils/clipboard.js.map +1 -1
  608. package/dist/utils/deprecation.d.ts.map +1 -1
  609. package/dist/utils/deprecation.js.map +1 -1
  610. package/dist/utils/exif-orientation.d.ts.map +1 -1
  611. package/dist/utils/exif-orientation.js.map +1 -1
  612. package/dist/utils/frontmatter.d.ts.map +1 -1
  613. package/dist/utils/frontmatter.js.map +1 -1
  614. package/dist/utils/fs-watch.d.ts.map +1 -1
  615. package/dist/utils/fs-watch.js.map +1 -1
  616. package/dist/utils/git.d.ts.map +1 -1
  617. package/dist/utils/git.js.map +1 -1
  618. package/dist/utils/html.d.ts.map +1 -1
  619. package/dist/utils/html.js.map +1 -1
  620. package/dist/utils/image-convert.d.ts.map +1 -1
  621. package/dist/utils/image-convert.js.map +1 -1
  622. package/dist/utils/image-process.d.ts.map +1 -1
  623. package/dist/utils/image-process.js.map +1 -1
  624. package/dist/utils/image-resize-core.d.ts.map +1 -1
  625. package/dist/utils/image-resize-core.js.map +1 -1
  626. package/dist/utils/image-resize-worker.d.ts.map +1 -1
  627. package/dist/utils/image-resize-worker.js.map +1 -1
  628. package/dist/utils/image-resize.d.ts.map +1 -1
  629. package/dist/utils/image-resize.js.map +1 -1
  630. package/dist/utils/json.d.ts.map +1 -1
  631. package/dist/utils/json.js.map +1 -1
  632. package/dist/utils/management-http.d.ts.map +1 -1
  633. package/dist/utils/management-http.js.map +1 -1
  634. package/dist/utils/mime.d.ts.map +1 -1
  635. package/dist/utils/mime.js.map +1 -1
  636. package/dist/utils/open-browser.d.ts.map +1 -1
  637. package/dist/utils/open-browser.js.map +1 -1
  638. package/dist/utils/paths.d.ts +3 -3
  639. package/dist/utils/paths.d.ts.map +1 -1
  640. package/dist/utils/paths.js +5 -4
  641. package/dist/utils/paths.js.map +1 -1
  642. package/dist/utils/photon.d.ts.map +1 -1
  643. package/dist/utils/photon.js.map +1 -1
  644. package/dist/utils/pi-user-agent.d.ts.map +1 -1
  645. package/dist/utils/pi-user-agent.js.map +1 -1
  646. package/dist/utils/shell.d.ts +1 -3
  647. package/dist/utils/shell.d.ts.map +1 -1
  648. package/dist/utils/shell.js +3 -30
  649. package/dist/utils/shell.js.map +1 -1
  650. package/dist/utils/sleep.d.ts.map +1 -1
  651. package/dist/utils/sleep.js.map +1 -1
  652. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  653. package/dist/utils/syntax-highlight.js +2 -0
  654. package/dist/utils/syntax-highlight.js.map +1 -1
  655. package/dist/utils/text.d.ts.map +1 -1
  656. package/dist/utils/text.js.map +1 -1
  657. package/dist/utils/tool-result-images.d.ts.map +1 -1
  658. package/dist/utils/tool-result-images.js.map +1 -1
  659. package/dist/utils/tools-manager.d.ts.map +1 -1
  660. package/dist/utils/tools-manager.js.map +1 -1
  661. package/dist/utils/version-check.d.ts.map +1 -1
  662. package/dist/utils/version-check.js.map +1 -1
  663. package/dist/utils/windows-self-update.d.ts.map +1 -1
  664. package/dist/utils/windows-self-update.js.map +1 -1
  665. package/dist/utils/wsl.d.ts.map +1 -1
  666. package/dist/utils/wsl.js.map +1 -1
  667. package/dist/utils/zip.d.ts.map +1 -1
  668. package/dist/utils/zip.js.map +1 -1
  669. package/docs/cli.md +64 -3
  670. package/docs/configuration.md +2 -0
  671. package/docs/custom-provider.md +43 -4
  672. package/docs/docs.json +8 -0
  673. package/docs/extensions.md +55 -0
  674. package/docs/keybindings.md +1 -1
  675. package/docs/llama-cpp.md +13 -0
  676. package/docs/mcp.md +188 -0
  677. package/docs/models.md +35 -0
  678. package/docs/packages.md +4 -2
  679. package/docs/providers.md +1 -0
  680. package/docs/rpc-commands.md +9 -3
  681. package/docs/rpc.md +3 -1
  682. package/docs/sdk.md +7 -2
  683. package/docs/security.md +2 -0
  684. package/docs/session-format.md +5 -1
  685. package/docs/settings.md +20 -3
  686. package/docs/themes.md +33 -7
  687. package/docs/tui.md +18 -0
  688. package/docs/virtual-models.md +114 -0
  689. package/docs/windows.md +2 -0
  690. package/examples/README.md +1 -1
  691. package/examples/extensions/README.md +2 -0
  692. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  693. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  694. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  695. package/examples/extensions/custom-provider-gitlab-duo/test.ts +5 -5
  696. package/examples/extensions/debug-provider.ts +90 -0
  697. package/examples/extensions/gondolin/package-lock.json +2 -2
  698. package/examples/extensions/gondolin/package.json +1 -1
  699. package/examples/extensions/jev-router.ts +113 -0
  700. package/examples/extensions/sandbox/package-lock.json +2 -2
  701. package/examples/extensions/sandbox/package.json +1 -1
  702. package/examples/extensions/with-deps/package-lock.json +2 -2
  703. package/examples/extensions/with-deps/package.json +1 -1
  704. package/examples/rpc-client.ts +1 -1
  705. package/examples/rpc-extension-ui.ts +1 -1
  706. package/examples/sdk/14-codemode-mcp.ts +61 -0
  707. package/examples/sdk/README.md +2 -1
  708. package/npm-shrinkwrap.json +89 -39
  709. package/package.json +14 -12
  710. package/dist/bundle/chunks/anthropic-messages-J5WXPPPC.js +0 -6
  711. package/dist/bundle/chunks/azure-openai-responses-HUSQ3GP2.js +0 -2
  712. package/dist/bundle/chunks/chunk-65HAU2C5.js +0 -2
  713. package/dist/bundle/chunks/chunk-6R7UI4IY.js +0 -2
  714. package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
  715. package/dist/bundle/chunks/chunk-OJP47DM6.js +0 -1568
  716. package/dist/bundle/chunks/chunk-RCZIEVGO.js +0 -11
  717. package/dist/bundle/chunks/google-generative-ai-IMS5EK2Y.js +0 -2
  718. package/dist/bundle/chunks/google-vertex-O4YJEQUW.js +0 -2
  719. package/dist/bundle/chunks/mistral-conversations-NOSQHBEY.js +0 -5
  720. package/dist/bundle/chunks/openai-responses-HWEUZ6WZ.js +0 -2
  721. package/dist/bundle/chunks/virtual-modules-VHMJYYWQ.js +0 -2
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import { readFileSync } from "node:fs";
16
16
  import { basename, dirname } from "node:path";
17
+ import { runToolCall, } from "@earendil-works/pi-agent-core";
17
18
  import { contentText, getCurrentSystemMessage, retryDelayMs } from "@earendil-works/pi-ai";
18
19
  import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
19
20
  import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
@@ -32,15 +33,17 @@ import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
32
33
  import { emitSessionShutdownEvent } from "./extensions/runner.js";
33
34
  import { convertToLlm } from "./messages.js";
34
35
  import { ModelRegistry } from "./model-registry.js";
36
+ import { NestedToolCallRunner } from "./nested-tool-calls.js";
35
37
  import { expandPromptTemplate } from "./prompt-templates.js";
36
38
  import { exportSessionToJsonl } from "./session-export.js";
37
39
  import { getLatestCompactionEntry, SessionManager, } from "./session-manager.js";
38
- import { createSyntheticSourceInfo } from "./source-info.js";
40
+ import { BUILTIN_PATH_PREFIX, createSyntheticSourceInfo, isSyntheticPath } from "./source-info.js";
39
41
  import { buildSystemPrompt, buildSystemPromptSections, diffSystemPromptSections, normalizeBuildSystemPromptOptions, } from "./system-prompt.js";
40
42
  import { createLocalBashOperations } from "./tools/bash.js";
41
43
  import { createAllToolDefinitions } from "./tools/index.js";
42
44
  import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
43
- import { addUsageToTotals, createUsageTotals } from "./usage-totals.js";
45
+ import { addUsageToTotals, combineUsage, createUsageTotals } from "./usage-totals.js";
46
+ import { findLatestResponse, getBranchSelection, getVirtualModelState, isVirtualModel, VIRTUAL_MODEL_STATE_ENTRY, } from "./virtual-models.js";
44
47
  /**
45
48
  * Parse a skill block from message text.
46
49
  * Returns null if the text doesn't contain a skill block.
@@ -103,6 +106,11 @@ export class AgentSession {
103
106
  // Retry state
104
107
  _retryAbortController = undefined;
105
108
  _retryAttempt = 0;
109
+ /**
110
+ * Failed response that the next request repeats, set by auto-retry and overflow recovery. The
111
+ * retry is routed with it as `failed`, since the context no longer contains it.
112
+ */
113
+ _failedResponse;
106
114
  // Bash execution state
107
115
  _bashAbortControllers = new Set();
108
116
  _pendingBashMessages = [];
@@ -139,6 +147,10 @@ export class AgentSession {
139
147
  _cacheWarmer;
140
148
  // Tool registry for extension getTools/setTools
141
149
  _toolRegistry = new Map();
150
+ /** Created on the first `ctx.executeTool()` call. */
151
+ _nestedToolCalls;
152
+ /** Declared tools whose declarations requests leave out, from `prepareLoadout` hooks. */
153
+ _hiddenDeclarations = new Set();
142
154
  _toolDefinitions = new Map();
143
155
  _toolPromptSnippets = new Map();
144
156
  _toolPromptGuidelines = new Map();
@@ -171,6 +183,7 @@ export class AgentSession {
171
183
  this._installAgentNextTurnRefresh();
172
184
  this._installAgentRequestProjection();
173
185
  this._installAgentBoundaryHooks();
186
+ this._installHiddenDeclarationsProjection();
174
187
  this._installAgentForcedPromptProjection();
175
188
  this._buildRuntime({
176
189
  activeToolNames: this._initialActiveToolNames,
@@ -211,28 +224,71 @@ export class AgentSession {
211
224
  }
212
225
  throw new Error(formatNoApiKeyFoundMessage(model.provider));
213
226
  }
214
- async _getSummarizationRequestAuth(model, signal) {
227
+ async _getSummarizationRequestAuth(selectedModel, signal) {
228
+ // Route a virtual model first: summaries size their input and output from the model they get.
229
+ const { model, thinkingLevel } = isVirtualModel(selectedModel)
230
+ ? await this._modelRuntime.resolveModel(selectedModel, convertToLlm(this.messages), {
231
+ reason: "direct",
232
+ thinkingLevel: this.thinkingLevel,
233
+ signal,
234
+ })
235
+ : { model: selectedModel, thinkingLevel: this.thinkingLevel };
215
236
  if (this.agent.streamFunction === streamSimple) {
216
- return this._getRequiredRequestAuth(model, signal);
237
+ return { ...(await this._getRequiredRequestAuth(model, signal)), thinkingLevel };
217
238
  }
218
239
  try {
219
240
  const result = await this._modelRuntime.getAuth(model, { signal });
220
241
  if (!result)
221
- return { model };
242
+ return { model, thinkingLevel };
222
243
  const requestModel = result.auth.baseUrl ? { ...model, baseUrl: result.auth.baseUrl } : model;
223
244
  return {
224
245
  model: requestModel,
225
246
  apiKey: result.auth.apiKey,
226
247
  headers: withoutDeletedHeaders(result.auth.headers),
227
248
  env: result.env,
249
+ thinkingLevel,
228
250
  };
229
251
  }
230
252
  catch (error) {
231
253
  if (signal?.aborted)
232
254
  throw error;
233
- return { model };
255
+ return { model, thinkingLevel };
234
256
  }
235
257
  }
258
+ /**
259
+ * The model whose limits apply to `message`, or undefined when the message came from another
260
+ * model. Under a virtual selection, that is the physical model that produced it.
261
+ */
262
+ _modelForMessage(message) {
263
+ const model = this.model;
264
+ if (model && isVirtualModel(model))
265
+ return this._modelRuntime.getPhysicalModel(message.provider, message.model);
266
+ return model?.provider === message.provider && model.id === message.model ? model : undefined;
267
+ }
268
+ /**
269
+ * Record the selection on the current branch when the branch implies another one, so a resume
270
+ * restores it. Tree navigation can leave the latest `model_change` on another branch; responses
271
+ * cannot record a virtual selection because they name physical models. Responses do record a
272
+ * physical selection unless the branch holds a virtual one; checking a physical selection against
273
+ * responses would record it on every prompt while `prepareRequest` redirects to another model.
274
+ */
275
+ _recordSelection() {
276
+ const model = this.model;
277
+ if (!model)
278
+ return;
279
+ const getModel = (provider, modelId) => this._modelRuntime.getModel(provider, modelId);
280
+ const recorded = getBranchSelection(this.sessionManager.getBranch(), getModel);
281
+ if (!recorded || (recorded.provider === model.provider && recorded.modelId === model.id))
282
+ return;
283
+ const recordedModel = getModel(recorded.provider, recorded.modelId);
284
+ if (!isVirtualModel(model) && !(recordedModel && isVirtualModel(recordedModel)))
285
+ return;
286
+ this.sessionManager.appendModelChange(model.provider, model.id);
287
+ }
288
+ /** The model whose limits apply to the conversation. */
289
+ _limitsModel() {
290
+ return this.routedModel?.model ?? this.model;
291
+ }
236
292
  /**
237
293
  * Install tool hooks once on the Agent instance.
238
294
  *
@@ -242,65 +298,112 @@ export class AgentSession {
242
298
  * happens here instead of in wrappers.
243
299
  */
244
300
  _installAgentToolHooks() {
245
- this.agent.beforeToolCall = async ({ toolCall, args }) => {
246
- const runner = this._extensionRunner;
247
- if (!runner.hasHandlers("tool_call")) {
248
- return undefined;
249
- }
250
- try {
251
- return await runner.emitToolCall({
252
- type: "tool_call",
253
- toolName: toolCall.name,
254
- toolCallId: toolCall.id,
255
- input: args,
256
- });
257
- }
258
- catch (err) {
259
- if (err instanceof Error) {
260
- throw err;
261
- }
262
- throw new Error(`Extension failed, blocking execution: ${String(err)}`);
263
- }
264
- };
265
- this.agent.afterToolCall = async ({ toolCall, args, result, isError }) => {
266
- const runner = this._extensionRunner;
267
- const hookResult = runner.hasHandlers("tool_result")
268
- ? await runner.emitToolResult({
269
- type: "tool_result",
270
- toolName: toolCall.name,
271
- toolCallId: toolCall.id,
272
- input: args,
273
- content: result.content,
274
- details: result.details,
275
- isError,
276
- usage: result.usage,
277
- })
278
- : undefined;
279
- const content = hookResult?.content ?? result.content ?? [];
280
- // Runs after the extension hook so images injected or replaced by extensions are normalized too.
281
- const resizeOptions = this.model?.inputLimits?.images?.resize;
282
- const normalizedContent = await normalizeToolResultImages(content, {
283
- autoResizeImages: this.settingsManager.getImageAutoResize(),
284
- ...(resizeOptions ? { resizeOptions } : {}),
301
+ this.agent.beforeToolCall = (context) => this._beforeToolCall(context);
302
+ this.agent.afterToolCall = (context) => this._afterToolCall(context);
303
+ }
304
+ /** `tool_call` handlers. `parentToolCallId` is set for calls another tool made. */
305
+ async _beforeToolCall({ toolCall, args }, parentToolCallId) {
306
+ const runner = this._extensionRunner;
307
+ if (!runner.hasHandlers("tool_call")) {
308
+ return undefined;
309
+ }
310
+ try {
311
+ return await runner.emitToolCall({
312
+ type: "tool_call",
313
+ toolName: toolCall.name,
314
+ toolCallId: toolCall.id,
315
+ ...(parentToolCallId ? { parentToolCallId } : {}),
316
+ input: args,
285
317
  });
286
- if (!hookResult && normalizedContent === content) {
287
- return undefined;
318
+ }
319
+ catch (err) {
320
+ if (err instanceof Error) {
321
+ throw err;
288
322
  }
289
- return {
290
- content: normalizedContent,
291
- details: hookResult?.details,
292
- isError: hookResult?.isError ?? isError,
293
- usage: hookResult?.usage,
294
- };
323
+ throw new Error(`Extension failed, blocking execution: ${String(err)}`);
324
+ }
325
+ }
326
+ /** `tool_result` handlers and image normalization. `parentToolCallId` is set for calls another tool made. */
327
+ async _afterToolCall({ toolCall, args, result, isError }, parentToolCallId) {
328
+ const runner = this._extensionRunner;
329
+ const hookResult = runner.hasHandlers("tool_result")
330
+ ? await runner.emitToolResult({
331
+ type: "tool_result",
332
+ toolName: toolCall.name,
333
+ toolCallId: toolCall.id,
334
+ ...(parentToolCallId ? { parentToolCallId } : {}),
335
+ input: args,
336
+ content: result.content,
337
+ details: result.details,
338
+ ...(result.structuredContent === undefined ? {} : { structuredContent: result.structuredContent }),
339
+ isError,
340
+ usage: result.usage,
341
+ })
342
+ : undefined;
343
+ const content = hookResult?.content ?? result.content ?? [];
344
+ // Runs after the extension hook so images injected or replaced by extensions are normalized too.
345
+ const resizeOptions = this._limitsModel()?.inputLimits?.images?.resize;
346
+ const normalizedContent = await normalizeToolResultImages(content, {
347
+ autoResizeImages: this.settingsManager.getImageAutoResize(),
348
+ ...(resizeOptions ? { resizeOptions } : {}),
349
+ });
350
+ if (!hookResult && normalizedContent === content) {
351
+ return undefined;
352
+ }
353
+ // The hook result already dropped structured content that replaced content no longer matches.
354
+ return {
355
+ content: normalizedContent,
356
+ details: hookResult?.details,
357
+ structuredContent: hookResult ? hookResult.structuredContent : result.structuredContent,
358
+ isError: hookResult?.isError ?? isError,
359
+ usage: hookResult?.usage,
295
360
  };
296
361
  }
362
+ /**
363
+ * Run a call that the tool call `parentToolCallId` made through `ctx.executeTool()`. It goes
364
+ * through the agent's tool pipeline with the session's hooks, against the callable tools.
365
+ */
366
+ async _executeNestedToolCall(parentToolCallId, name, args, options) {
367
+ this._nestedToolCalls ??= new NestedToolCallRunner({
368
+ getTools: () => this._getCallableTools(),
369
+ isSequential: () => this.agent.toolExecution === "sequential",
370
+ runToolCall: (toolCall, parentId, signal, onUpdate) => {
371
+ const assistantMessage = this._findLastAssistantMessage();
372
+ if (!assistantMessage) {
373
+ return Promise.resolve({
374
+ toolCall,
375
+ result: { content: [{ type: "text", text: "No assistant message issued this call" }], details: {} },
376
+ isError: true,
377
+ });
378
+ }
379
+ return runToolCall(toolCall, {
380
+ tools: this._getCallableTools(),
381
+ assistantMessage,
382
+ context: { messages: this.agent.state.messages, tools: this.agent.state.tools },
383
+ beforeToolCall: (context) => this._beforeToolCall(context, parentId),
384
+ afterToolCall: (context) => this._afterToolCall(context, parentId),
385
+ signal,
386
+ onUpdate,
387
+ });
388
+ },
389
+ emit: async (event) => {
390
+ await this._extensionRunner.emit(event);
391
+ this._emit(event);
392
+ },
393
+ });
394
+ return this._nestedToolCalls.execute(parentToolCallId, name, args, options);
395
+ }
396
+ /** Whether `projection`, the current session projection, exceeds the compaction threshold of `model`. */
397
+ _exceedsCompactionThreshold(model, projection) {
398
+ if (model.contextWindow <= 0)
399
+ return false;
400
+ return shouldCompact(estimateProjectedContextTokens(projection, this.sessionManager.getBranch()).tokens, model.contextWindow, this.settingsManager.getCompactionSettings(this.model));
401
+ }
297
402
  async _compactBeforeNextAssistantResponse(context) {
298
- const model = this.model;
299
- const settings = this.settingsManager.getCompactionSettings(model);
300
403
  const projection = this.sessionManager.buildSessionProjection();
301
- if (!model ||
302
- model.contextWindow <= 0 ||
303
- !shouldCompact(estimateProjectedContextTokens(projection, this.sessionManager.getBranch()).tokens, model.contextWindow, settings)) {
404
+ // A virtual selection is checked in prepareRequest, against the model the request is routed to.
405
+ const model = this.model;
406
+ if (!model || isVirtualModel(model) || !this._exceedsCompactionThreshold(model, projection)) {
304
407
  return { ...context, messages: projection.messages };
305
408
  }
306
409
  await this._runAutoCompaction("threshold", false);
@@ -309,24 +412,55 @@ export class AgentSession {
309
412
  _installAgentRequestProjection() {
310
413
  const previousPrepareRequest = this.agent.prepareRequest;
311
414
  this.agent.prepareRequest = async (request, signal) => {
312
- const canonicalContext = {
313
- ...request.context,
314
- messages: this.sessionManager.buildSessionProjection().messages,
315
- // Messages declare the provider-visible loadout; context.tools keeps executable implementations.
316
- tools: this.agent.state.tools.slice(),
317
- };
318
- const previous = await previousPrepareRequest?.({
319
- ...request,
320
- context: canonicalContext,
321
- model: this.agent.state.model,
322
- thinkingLevel: this.agent.state.thinkingLevel,
323
- }, signal);
324
- return {
325
- ...previous,
326
- context: previous?.context ?? canonicalContext,
327
- model: previous?.model ?? this.agent.state.model,
328
- thinkingLevel: previous?.thinkingLevel ?? this.agent.state.thinkingLevel,
415
+ const failed = this._failedResponse;
416
+ this._failedResponse = undefined;
417
+ const prepare = async () => {
418
+ const projection = this.sessionManager.buildSessionProjection();
419
+ const canonicalContext = {
420
+ ...request.context,
421
+ messages: projection.messages,
422
+ // Messages declare the provider-visible loadout; context.tools keeps executable implementations.
423
+ tools: this.agent.state.tools.slice(),
424
+ };
425
+ const previous = await previousPrepareRequest?.({
426
+ ...request,
427
+ context: canonicalContext,
428
+ model: this.agent.state.model,
429
+ thinkingLevel: this.agent.state.thinkingLevel,
430
+ }, signal);
431
+ return { previous, context: previous?.context ?? canonicalContext, projection };
329
432
  };
433
+ let { previous, context, projection } = await prepare();
434
+ const model = previous?.model ?? this.agent.state.model;
435
+ const thinkingLevel = previous?.thinkingLevel ?? this.agent.state.thinkingLevel;
436
+ if (!isVirtualModel(model))
437
+ return { ...previous, context, model, thinkingLevel };
438
+ // The selection stays in agent state; only this request uses the routed model. A routing
439
+ // failure rejects, which ends the run with an error response. Only messages the user wrote
440
+ // start a turn; extension messages can follow them, e.g. from before_agent_start.
441
+ const lastResponse = context.messages.findLastIndex((message) => message.role === "assistant");
442
+ const userTurn = context.messages.slice(lastResponse + 1).some((message) => message.role === "user");
443
+ const state = getVirtualModelState(this.sessionManager.getBranch(), model.provider, model.id);
444
+ const route = await this._modelRuntime.resolveModel(model, convertToLlm(context.messages), {
445
+ reason: failed ? "retry" : userTurn ? "user" : "continuation",
446
+ thinkingLevel,
447
+ signal,
448
+ failed,
449
+ state,
450
+ });
451
+ if (route.state !== undefined && route.state !== state) {
452
+ const data = { provider: model.provider, modelId: model.id, state: route.state };
453
+ const entry = this.sessionManager.getEntry(this.sessionManager.appendCustomEntry(VIRTUAL_MODEL_STATE_ENTRY, data));
454
+ if (entry)
455
+ this._emit({ type: "entry_appended", entry });
456
+ }
457
+ // The route stands: the router already decided this request. The state entry does not change
458
+ // the projection.
459
+ if (this._exceedsCompactionThreshold(route.model, projection)) {
460
+ await this._runAutoCompaction("threshold", false);
461
+ ({ previous, context } = await prepare());
462
+ }
463
+ return { ...previous, context, model: route.model, thinkingLevel: route.thinkingLevel };
330
464
  };
331
465
  }
332
466
  async _dispatchTurnEndBoundary(message, toolResults) {
@@ -382,10 +516,7 @@ export class AgentSession {
382
516
  ? async (_turn, signal) => await this.agent.prepareNextTurn?.(signal)
383
517
  : undefined);
384
518
  this.agent.prepareNextTurnWithContext = async (turn, signal) => {
385
- const context = await this._compactBeforeNextAssistantResponse({
386
- ...turn.context,
387
- messages: this.sessionManager.buildSessionProjection().messages,
388
- });
519
+ const context = await this._compactBeforeNextAssistantResponse(turn.context);
389
520
  const previousSnapshot = await previousPrepareNextTurnWithContext?.({ ...turn, context }, signal);
390
521
  const nextContext = previousSnapshot?.context ?? context;
391
522
  const runOptions = this._runSystemPromptOptions ?? this._baseSystemPromptOptions;
@@ -554,6 +685,21 @@ export class AgentSession {
554
685
  }
555
686
  /** Internal handler for agent events - shared by subscribe and reconnect */
556
687
  _handleAgentEvent = async (event) => {
688
+ // Record the calls a tool made through ctx.executeTool() and their usage on its result message.
689
+ if (this._nestedToolCalls) {
690
+ if (event.type === "message_start" && event.message.role === "toolResult") {
691
+ const message = event.message;
692
+ const summary = this._nestedToolCalls.takeRecord(message.toolCallId);
693
+ if (summary?.calls)
694
+ message.nestedCalls = summary.calls;
695
+ if (summary?.usage) {
696
+ message.usage = message.usage ? combineUsage(message.usage, summary.usage) : summary.usage;
697
+ }
698
+ }
699
+ else if (event.type === "agent_end") {
700
+ this._nestedToolCalls.clear();
701
+ }
702
+ }
557
703
  // When a user message starts, check if it's from either queue and remove it BEFORE emitting
558
704
  // This ensures the UI sees the updated queue state
559
705
  if (event.type === "message_start" && event.message.role === "user") {
@@ -867,6 +1013,14 @@ export class AgentSession {
867
1013
  get thinkingLevel() {
868
1014
  return this.agent.state.thinkingLevel;
869
1015
  }
1016
+ /** Under a virtual selection, the physical model and thinking level of the latest successful response. */
1017
+ get routedModel() {
1018
+ if (!this.model || !isVirtualModel(this.model))
1019
+ return undefined;
1020
+ const latest = findLatestResponse(this.agent.state.messages);
1021
+ const model = latest && this._modelRuntime.getPhysicalModel(latest.provider, latest.model);
1022
+ return model && { model, thinkingLevel: latest?.thinkingLevel };
1023
+ }
870
1024
  /** Whether the session is currently processing an agent run or post-run continuation. */
871
1025
  get isStreaming() {
872
1026
  return this._isAgentRunActive;
@@ -884,12 +1038,16 @@ export class AgentSession {
884
1038
  return this._retryAttempt;
885
1039
  }
886
1040
  /**
887
- * Get the names of currently active tools.
888
- * Returns the names of tools currently set on the agent.
1041
+ * Get the names of currently active tools, which are the tools declared to the model.
1042
+ * Tools with `codemode` or `deferred` exposure are callable from other tools without being active.
889
1043
  */
890
1044
  getActiveToolNames() {
891
1045
  return this.agent.state.tools.map((t) => t.name);
892
1046
  }
1047
+ /** Get the names of the tools that tools can call through `ctx.executeTool()`. */
1048
+ getCallableToolNames() {
1049
+ return this._getCallableTools().map((t) => t.name);
1050
+ }
893
1051
  /**
894
1052
  * Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.
895
1053
  */
@@ -899,6 +1057,9 @@ export class AgentSession {
899
1057
  description: definition.description,
900
1058
  parameters: definition.parameters,
901
1059
  promptGuidelines: definition.promptGuidelines,
1060
+ exposure: this._getToolExposure(definition.name),
1061
+ ...(definition.namespace ? { namespace: definition.namespace } : {}),
1062
+ ...(definition.annotations ? { annotations: { ...definition.annotations } } : {}),
902
1063
  sourceInfo,
903
1064
  }));
904
1065
  }
@@ -907,22 +1068,79 @@ export class AgentSession {
907
1068
  }
908
1069
  /**
909
1070
  * Set active tools by name.
910
- * Only tools in the registry can be enabled. Unknown tool names are ignored.
1071
+ * Only tools in the registry can be enabled. Unknown and hidden tool names are ignored.
911
1072
  * Also rebuilds the system prompt to reflect the new tool set.
912
1073
  * Changes take effect on the next agent turn.
913
1074
  */
914
1075
  setActiveToolsByName(toolNames) {
915
- const tools = [];
916
- const validToolNames = [];
917
- for (const name of toolNames) {
1076
+ const tools = this._applyToolLoadout(toolNames);
1077
+ this._rebuildSystemPrompt(tools.map((tool) => tool.name));
1078
+ }
1079
+ _getToolExposure(name) {
1080
+ return this._toolDefinitions.get(name)?.definition.exposure ?? "direct";
1081
+ }
1082
+ /**
1083
+ * Tools callable through `ctx.executeTool()`: the active `direct` tools and every registered
1084
+ * `codemode` or `deferred` tool.
1085
+ */
1086
+ _getCallableTools(active = new Set(this.getActiveToolNames())) {
1087
+ return [...this._toolRegistry.values()].filter((tool) => {
1088
+ const exposure = this._getToolExposure(tool.name);
1089
+ return exposure === "codemode" || exposure === "deferred" || (exposure === "direct" && active.has(tool.name));
1090
+ });
1091
+ }
1092
+ /**
1093
+ * Set the agent's tools for the given active tool names and return them. The active tools are
1094
+ * the registered, non-hidden ones; they are declared to the model. Active tools with a
1095
+ * `prepareLoadout` hook can change the declared descriptions and hide declarations from
1096
+ * requests (see {@link _installHiddenDeclarationsProjection}).
1097
+ */
1098
+ _applyToolLoadout(toolNames) {
1099
+ const tools = [...new Set(toolNames)].flatMap((name) => {
918
1100
  const tool = this._toolRegistry.get(name);
919
- if (tool) {
920
- tools.push(tool);
921
- validToolNames.push(name);
1101
+ return tool && this._getToolExposure(name) !== "hidden" ? [tool] : [];
1102
+ });
1103
+ const hooks = tools.flatMap((tool) => {
1104
+ const entry = this._toolDefinitions.get(tool.name);
1105
+ return entry?.definition.prepareLoadout ? [entry] : [];
1106
+ });
1107
+ const hidden = new Set();
1108
+ let declared = tools;
1109
+ if (hooks.length > 0) {
1110
+ const loadout = {
1111
+ declared: tools,
1112
+ callable: this._getCallableTools(new Set(tools.map((tool) => tool.name))),
1113
+ registered: [...this._toolRegistry.values()],
1114
+ getExposure: (name) => this._getToolExposure(name),
1115
+ getNamespace: (name) => this._toolDefinitions.get(name)?.definition.namespace,
1116
+ };
1117
+ const descriptions = new Map();
1118
+ for (const { definition, sourceInfo } of hooks) {
1119
+ try {
1120
+ const changes = definition.prepareLoadout?.(loadout);
1121
+ for (const [name, description] of Object.entries(changes?.descriptions ?? {})) {
1122
+ descriptions.set(name, description);
1123
+ }
1124
+ for (const name of changes?.hiddenDeclarations ?? [])
1125
+ hidden.add(name);
1126
+ }
1127
+ catch (error) {
1128
+ this._extensionRunner.emitError({
1129
+ extensionPath: sourceInfo.path,
1130
+ event: "prepare_loadout",
1131
+ error: error instanceof Error ? error.message : String(error),
1132
+ stack: error instanceof Error ? error.stack : undefined,
1133
+ });
1134
+ }
922
1135
  }
1136
+ declared = tools.map((tool) => {
1137
+ const description = descriptions.get(tool.name);
1138
+ return description === undefined ? tool : { ...tool, description };
1139
+ });
923
1140
  }
924
- this.agent.state.tools = tools;
925
- this._rebuildSystemPrompt(validToolNames);
1141
+ this._hiddenDeclarations = hidden;
1142
+ this.agent.state.tools = declared;
1143
+ return declared;
926
1144
  }
927
1145
  /** Whether compaction or branch summarization is currently running */
928
1146
  get isCompacting() {
@@ -1023,11 +1241,7 @@ export class AgentSession {
1023
1241
  * {@link _installAgentForcedPromptProjection}.
1024
1242
  */
1025
1243
  _preparePromptAndToolLoadout(options, messages = this.agent.state.messages) {
1026
- options.selectedTools = [...new Set(options.selectedTools)].filter((name) => this._toolRegistry.has(name));
1027
- this.agent.state.tools = options.selectedTools.flatMap((name) => {
1028
- const tool = this._toolRegistry.get(name);
1029
- return tool ? [tool] : [];
1030
- });
1244
+ options.selectedTools = this._applyToolLoadout(options.selectedTools).map((tool) => tool.name);
1031
1245
  const sections = diffSystemPromptSections(getCurrentSystemMessage(messages)?.sections ?? {}, buildSystemPromptSections(options));
1032
1246
  return sections ? { role: "system", content: "", sections, timestamp: Date.now() } : undefined;
1033
1247
  }
@@ -1041,6 +1255,32 @@ export class AgentSession {
1041
1255
  * collapse into one head holding the forced text and the current tools. Runs after the
1042
1256
  * `context` extension handlers.
1043
1257
  */
1258
+ /**
1259
+ * Remove the declarations that `prepareLoadout` hooks hide from every request. The whole
1260
+ * transcript is filtered with the current set, so the projected declarations stay consistent
1261
+ * across requests and only change when the loadout does.
1262
+ */
1263
+ _installHiddenDeclarationsProjection() {
1264
+ const previousTransformContext = this.agent.transformContext;
1265
+ this.agent.transformContext = async (messages, signal) => {
1266
+ const transformed = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
1267
+ const hidden = this._hiddenDeclarations;
1268
+ if (hidden.size === 0)
1269
+ return transformed;
1270
+ return transformed.map((message) => {
1271
+ if (message.role !== "system" || (!message.toolsAdded && !message.toolsRemoved))
1272
+ return message;
1273
+ const { toolsAdded, toolsRemoved, ...rest } = message;
1274
+ const added = toolsAdded?.filter((tool) => !hidden.has(tool.name)) ?? [];
1275
+ const removed = toolsRemoved?.filter((tool) => !hidden.has(tool.name)) ?? [];
1276
+ return {
1277
+ ...rest,
1278
+ ...(added.length > 0 ? { toolsAdded: added } : {}),
1279
+ ...(removed.length > 0 ? { toolsRemoved: removed } : {}),
1280
+ };
1281
+ });
1282
+ };
1283
+ }
1044
1284
  _installAgentForcedPromptProjection() {
1045
1285
  const previousTransformContext = this.agent.transformContext;
1046
1286
  this.agent.transformContext = async (messages, signal) => {
@@ -1058,25 +1298,25 @@ export class AgentSession {
1058
1298
  return [head, ...transformed.filter((message) => message.role !== "system")];
1059
1299
  };
1060
1300
  }
1061
- /** Restore the active tool loadout declared by the session transcript, if it declares one. */
1301
+ /**
1302
+ * Restore the active tool loadout declared by the session transcript, if it declares one.
1303
+ * Tools reachable only from other tools are never declared, but they do not depend on the active
1304
+ * set, so the transcript's declarations are the whole loadout.
1305
+ */
1062
1306
  _restoreToolsFromTranscript() {
1063
1307
  const current = getCurrentSystemMessage(this.sessionManager.buildSessionContext().messages);
1064
1308
  if (!current)
1065
1309
  return;
1066
- const toolNames = (current.toolsAdded ?? [])
1067
- .map((tool) => tool.name)
1068
- .filter((name) => this._toolRegistry.has(name));
1069
- this.agent.state.tools = toolNames.flatMap((name) => {
1070
- const registered = this._toolRegistry.get(name);
1071
- return registered ? [registered] : [];
1072
- });
1073
- this._rebuildSystemPrompt(toolNames);
1310
+ this.setActiveToolsByName((current.toolsAdded ?? []).map((tool) => tool.name));
1074
1311
  }
1075
1312
  // =========================================================================
1076
1313
  // Prompting
1077
1314
  // =========================================================================
1078
1315
  async _runAgentPrompt(messages) {
1079
1316
  this._agentRunAbortRequested = false;
1317
+ // Compaction before the prompt may have scheduled a retry; the new prompt replaces it.
1318
+ this._failedResponse = undefined;
1319
+ this._recordSelection();
1080
1320
  this._isAgentRunActive = true;
1081
1321
  try {
1082
1322
  await this.agent.prompt(messages);
@@ -1097,6 +1337,7 @@ export class AgentSession {
1097
1337
  finally {
1098
1338
  if (this._agentRunAbortRequested)
1099
1339
  this._finishCancelledRetry();
1340
+ this._failedResponse = undefined;
1100
1341
  this._runSystemPromptOptions = undefined;
1101
1342
  this._flushPendingBashMessages();
1102
1343
  this._flushPendingCustomMessages();
@@ -1117,6 +1358,7 @@ export class AgentSession {
1117
1358
  if (this._isRetryableError(message) && (await this._prepareRetry(message))) {
1118
1359
  if (this._agentRunAbortRequested)
1119
1360
  this._finishCancelledRetry();
1361
+ this._failedResponse = message;
1120
1362
  return !this._agentRunAbortRequested;
1121
1363
  }
1122
1364
  if (this._agentRunAbortRequested) {
@@ -1184,7 +1426,7 @@ export class AgentSession {
1184
1426
  for (const image of images) {
1185
1427
  const processed = await processImage(Buffer.from(image.data, "base64"), image.mimeType, {
1186
1428
  autoResizeImages: this.settingsManager.getImageAutoResize(),
1187
- resizeOptions: this.model?.inputLimits?.images?.resize,
1429
+ resizeOptions: this._limitsModel()?.inputLimits?.images?.resize,
1188
1430
  });
1189
1431
  if (!processed.ok) {
1190
1432
  hints.push(processed.message);
@@ -1211,123 +1453,113 @@ export class AgentSession {
1211
1453
  }
1212
1454
  const expandPromptTemplates = options?.expandPromptTemplates ?? true;
1213
1455
  const preflightResult = options?.preflightResult;
1214
- let messages;
1215
- try {
1216
- // Handle extension commands first (execute immediately, even during streaming)
1217
- // Extension commands manage their own LLM interaction via pi.sendMessage()
1218
- if (expandPromptTemplates && text.startsWith("/")) {
1219
- const handled = await this._tryExecuteExtensionCommand(text);
1220
- if (handled) {
1221
- // Extension command executed, no prompt to send
1222
- preflightResult?.(true);
1223
- return;
1224
- }
1225
- }
1226
- if (this._compactionAbortController !== undefined) {
1227
- throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
1228
- }
1229
- // Emit input event for extension interception (before skill/template expansion)
1230
- const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
1231
- if (!processedInput) {
1232
- preflightResult?.(true);
1456
+ // Handle extension commands first (execute immediately, even during streaming)
1457
+ // Extension commands manage their own LLM interaction via pi.sendMessage()
1458
+ if (expandPromptTemplates && text.startsWith("/")) {
1459
+ const handled = await this._tryExecuteExtensionCommand(text);
1460
+ if (handled) {
1461
+ // Extension command executed, no prompt to send
1462
+ preflightResult?.("handled");
1233
1463
  return;
1234
1464
  }
1235
- const { text: currentText, images: currentImages } = processedInput;
1236
- // Expand skill commands (/skill:name args) and prompt templates (/template args)
1237
- let expandedText = currentText;
1238
- if (expandPromptTemplates) {
1239
- expandedText = this._expandSkillCommand(expandedText);
1240
- expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
1241
- }
1242
- // If streaming, queue via steer() or followUp() based on option
1243
- if (this.isStreaming) {
1244
- if (!options?.streamingBehavior) {
1245
- throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");
1246
- }
1247
- if (options.streamingBehavior === "followUp") {
1248
- await this._queueFollowUp(expandedText, currentImages);
1249
- }
1250
- else {
1251
- await this._queueSteer(expandedText, currentImages);
1252
- }
1253
- preflightResult?.(true);
1254
- return;
1465
+ }
1466
+ if (this._compactionAbortController !== undefined) {
1467
+ throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
1468
+ }
1469
+ // Emit input event for extension interception (before skill/template expansion)
1470
+ const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
1471
+ if (!processedInput) {
1472
+ preflightResult?.("handled");
1473
+ return;
1474
+ }
1475
+ const { text: currentText, images: currentImages } = processedInput;
1476
+ // Expand skill commands (/skill:name args) and prompt templates (/template args)
1477
+ let expandedText = currentText;
1478
+ if (expandPromptTemplates) {
1479
+ expandedText = this._expandSkillCommand(expandedText);
1480
+ expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
1481
+ }
1482
+ // If streaming, queue via steer() or followUp() based on option
1483
+ if (this.isStreaming) {
1484
+ if (!options?.streamingBehavior) {
1485
+ throw new Error("Agent is already processing. Specify streamingBehavior ('steer' or 'followUp') to queue the message.");
1255
1486
  }
1256
- // Flush any pending bash and custom messages before the new prompt
1257
- this._flushPendingBashMessages();
1258
- this._flushPendingCustomMessages();
1259
- // Validate model
1260
- if (!this.model) {
1261
- throw new Error(formatNoModelSelectedMessage());
1487
+ if (options.streamingBehavior === "followUp") {
1488
+ await this._queueFollowUp(expandedText, currentImages);
1262
1489
  }
1263
- const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
1264
- (await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
1265
- if (!hasConfiguredAuth) {
1266
- const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
1267
- if (isOAuth) {
1268
- throw new Error(`Authentication failed for "${this.model.provider}". ` +
1269
- `Credentials may have expired or network is unavailable. ` +
1270
- `Run '/login ${this.model.provider}' to re-authenticate.`);
1271
- }
1272
- throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
1273
- }
1274
- // Check if we need to compact before sending (catches aborted responses).
1275
- // The user's new prompt is sent below, so do not call agent.continue() here.
1276
- const lastAssistant = this._findLastAssistantMessage();
1277
- if (lastAssistant) {
1278
- await this._checkCompaction(lastAssistant, false);
1279
- }
1280
- // Emit before_agent_start before normalizing images so extension-driven model
1281
- // selection determines the resize profile used for the request and history.
1282
- const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
1283
- const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPromptOptions);
1284
- // Handlers may edit event.systemPromptOptions.selectedTools or call setActiveTools(),
1285
- // which updates the live loadout instead. An explicit edit wins; otherwise the live
1286
- // loadout is authoritative, so a setActiveTools() call is not undone here.
1287
- const handlerEditedTools = result.systemPromptOptions.selectedTools.length !== selectedToolsBefore.length ||
1288
- result.systemPromptOptions.selectedTools.some((name, index) => name !== selectedToolsBefore[index]);
1289
- if (!handlerEditedTools)
1290
- result.systemPromptOptions.selectedTools = this.getActiveToolNames();
1291
- const normalized = await this._normalizePromptImages(currentImages);
1292
- const userText = normalized.hints.length > 0 ? `${expandedText}\n\n${normalized.hints.join("\n")}` : expandedText;
1293
- // Build messages only after hooks and image normalization have completed.
1294
- messages = [];
1295
- const userContent = [{ type: "text", text: userText }];
1296
- userContent.push(...normalized.images);
1297
- messages.push({
1298
- role: "user",
1299
- content: userContent,
1300
- timestamp: Date.now(),
1301
- });
1302
- // Inject any pending "nextTurn" messages as context alongside the user message
1303
- for (const msg of this._pendingNextTurnMessages) {
1304
- messages.push(msg);
1305
- }
1306
- this._pendingNextTurnMessages = [];
1307
- for (const msg of result.messages) {
1308
- messages.push({
1309
- role: "custom",
1310
- customType: msg.customType,
1311
- // Untyped extensions can pass null/missing content; normalize at ingestion.
1312
- content: msg.content ?? [],
1313
- display: msg.display,
1314
- details: msg.details,
1315
- timestamp: Date.now(),
1316
- });
1490
+ else {
1491
+ await this._queueSteer(expandedText, currentImages);
1317
1492
  }
1318
- const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
1319
- this._runSystemPromptOptions = result.systemPromptOptions;
1320
- if (updateMessage)
1321
- messages.unshift(updateMessage);
1493
+ preflightResult?.("queued");
1494
+ return;
1322
1495
  }
1323
- catch (error) {
1324
- preflightResult?.(false);
1325
- throw error;
1496
+ // Flush any pending bash and custom messages before the new prompt
1497
+ this._flushPendingBashMessages();
1498
+ this._flushPendingCustomMessages();
1499
+ // Validate model
1500
+ if (!this.model) {
1501
+ throw new Error(formatNoModelSelectedMessage());
1502
+ }
1503
+ const hasConfiguredAuth = this._modelRuntime.hasConfiguredAuth(this.model.provider) ||
1504
+ (await this._modelRuntime.checkAuth(this.model.provider)) !== undefined;
1505
+ if (!hasConfiguredAuth) {
1506
+ const isOAuth = this._modelRuntime.isUsingOAuth(this.model.provider);
1507
+ if (isOAuth) {
1508
+ throw new Error(`Authentication failed for "${this.model.provider}". ` +
1509
+ `Credentials may have expired or network is unavailable. ` +
1510
+ `Run '/login ${this.model.provider}' to re-authenticate.`);
1511
+ }
1512
+ throw new Error(formatNoApiKeyFoundMessage(this.model.provider));
1513
+ }
1514
+ // Check if we need to compact before sending (catches aborted responses).
1515
+ // The user's new prompt is sent below, so do not call agent.continue() here.
1516
+ const lastAssistant = this._findLastAssistantMessage();
1517
+ if (lastAssistant) {
1518
+ await this._checkCompaction(lastAssistant, false);
1519
+ }
1520
+ // Emit before_agent_start before normalizing images so extension-driven model
1521
+ // selection determines the resize profile used for the request and history.
1522
+ const selectedToolsBefore = this._baseSystemPromptOptions.selectedTools;
1523
+ const result = await this._extensionRunner.emitBeforeAgentStart(expandedText, currentImages, this._baseSystemPromptOptions);
1524
+ // Handlers may edit event.systemPromptOptions.selectedTools or call setActiveTools(),
1525
+ // which updates the live loadout instead. An explicit edit wins; otherwise the live
1526
+ // loadout is authoritative, so a setActiveTools() call is not undone here.
1527
+ const handlerEditedTools = result.systemPromptOptions.selectedTools.length !== selectedToolsBefore.length ||
1528
+ result.systemPromptOptions.selectedTools.some((name, index) => name !== selectedToolsBefore[index]);
1529
+ if (!handlerEditedTools)
1530
+ result.systemPromptOptions.selectedTools = this.getActiveToolNames();
1531
+ const normalized = await this._normalizePromptImages(currentImages);
1532
+ const userText = normalized.hints.length > 0 ? `${expandedText}\n\n${normalized.hints.join("\n")}` : expandedText;
1533
+ // Build messages only after hooks and image normalization have completed.
1534
+ const messages = [];
1535
+ const userContent = [{ type: "text", text: userText }];
1536
+ userContent.push(...normalized.images);
1537
+ messages.push({
1538
+ role: "user",
1539
+ content: userContent,
1540
+ timestamp: Date.now(),
1541
+ });
1542
+ // Inject any pending "nextTurn" messages as context alongside the user message
1543
+ for (const msg of this._pendingNextTurnMessages) {
1544
+ messages.push(msg);
1326
1545
  }
1327
- if (!messages) {
1328
- return;
1546
+ this._pendingNextTurnMessages = [];
1547
+ for (const msg of result.messages) {
1548
+ messages.push({
1549
+ role: "custom",
1550
+ customType: msg.customType,
1551
+ // Untyped extensions can pass null/missing content; normalize at ingestion.
1552
+ content: msg.content ?? [],
1553
+ display: msg.display,
1554
+ details: msg.details,
1555
+ timestamp: Date.now(),
1556
+ });
1329
1557
  }
1330
- preflightResult?.(true);
1558
+ const updateMessage = this._preparePromptAndToolLoadout(result.systemPromptOptions);
1559
+ this._runSystemPromptOptions = result.systemPromptOptions;
1560
+ if (updateMessage)
1561
+ messages.unshift(updateMessage);
1562
+ preflightResult?.("started");
1331
1563
  await this._runAgentPrompt(messages);
1332
1564
  }
1333
1565
  /**
@@ -1393,7 +1625,7 @@ export class AgentSession {
1393
1625
  }
1394
1626
  const processedInput = await this._runInputHandlers(text, images, source, this.isStreaming ? behavior : undefined);
1395
1627
  if (!processedInput)
1396
- return;
1628
+ return "handled";
1397
1629
  let expandedText = this._expandSkillCommand(processedInput.text);
1398
1630
  expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
1399
1631
  if (behavior === "steer") {
@@ -1402,6 +1634,7 @@ export class AgentSession {
1402
1634
  else {
1403
1635
  await this._queueFollowUp(expandedText, processedInput.images);
1404
1636
  }
1637
+ return "queued";
1405
1638
  }
1406
1639
  /**
1407
1640
  * Queue a steering message while the agent is running.
@@ -1413,7 +1646,7 @@ export class AgentSession {
1413
1646
  * @throws Error if text is an extension command
1414
1647
  */
1415
1648
  async steer(text, images, options) {
1416
- await this._queueUserInput(text, images, "steer", options?.source ?? "interactive");
1649
+ return this._queueUserInput(text, images, "steer", options?.source ?? "interactive");
1417
1650
  }
1418
1651
  /**
1419
1652
  * Queue a follow-up message to be processed after the agent finishes.
@@ -1424,7 +1657,7 @@ export class AgentSession {
1424
1657
  * @throws Error if text is an extension command
1425
1658
  */
1426
1659
  async followUp(text, images, options) {
1427
- await this._queueUserInput(text, images, "followUp", options?.source ?? "interactive");
1660
+ return this._queueUserInput(text, images, "followUp", options?.source ?? "interactive");
1428
1661
  }
1429
1662
  /**
1430
1663
  * Internal: Queue a steering message (already expanded, no extension command check).
@@ -1840,8 +2073,10 @@ export class AgentSession {
1840
2073
  // Compaction
1841
2074
  // =========================================================================
1842
2075
  /** Generate Pi's built-in compaction summary for manual and automatic compaction. */
1843
- async _runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, signal, env, reason) {
1844
- return compact(preparation, requestModel, apiKey, headers, customInstructions, signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined);
2076
+ async _runDefaultCompaction(preparation, model, customInstructions, signal, reason) {
2077
+ // Resolve the request only when Pi summarizes itself: routing may call models or fail.
2078
+ const request = await this._getSummarizationRequestAuth(model, signal);
2079
+ return compact(preparation, request.model, request.apiKey, request.headers, customInstructions, signal, request.thinkingLevel, this.agent.streamFunction, request.env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined);
1845
2080
  }
1846
2081
  _clearManualCompactionState() {
1847
2082
  this._compactionAbortController = undefined;
@@ -1874,7 +2109,6 @@ export class AgentSession {
1874
2109
  throw new Error(formatNoModelSelectedMessage());
1875
2110
  }
1876
2111
  const settings = this.settingsManager.getCompactionSettings(model);
1877
- const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, this._compactionAbortController.signal);
1878
2112
  const pathEntries = this.sessionManager.getBranch();
1879
2113
  const preparation = prepareCompaction(pathEntries, settings);
1880
2114
  if (!preparation) {
@@ -1920,7 +2154,7 @@ export class AgentSession {
1920
2154
  }
1921
2155
  else {
1922
2156
  // Shared default summary generator, also used by automatic compaction.
1923
- const result = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, env, "manual");
2157
+ const result = await this._runDefaultCompaction(preparation, model, customInstructions, this._compactionAbortController.signal, "manual");
1924
2158
  summary = result.summary;
1925
2159
  firstKeptEntryId = result.firstKeptEntryId;
1926
2160
  tokensBefore = result.tokensBefore;
@@ -2031,12 +2265,14 @@ export class AgentSession {
2031
2265
  // Skip if message was aborted (user cancelled) - unless skipAbortedCheck is false
2032
2266
  if (skipAbortedCheck && assistantMessage.stopReason === "aborted")
2033
2267
  return false;
2034
- const contextWindow = this.model?.contextWindow ?? 0;
2035
2268
  // Skip overflow check if the message came from a different model.
2036
2269
  // This handles the case where user switched from a smaller-context model (e.g. opus)
2037
2270
  // to a larger-context model (e.g. codex) - the overflow error from the old model
2038
- // shouldn't trigger compaction for the new model.
2039
- const sameModel = this.model && assistantMessage.provider === this.model.provider && assistantMessage.model === this.model.id;
2271
+ // shouldn't trigger compaction for the new model. Under a virtual selection, the
2272
+ // physical model that produced the message supplies the limits.
2273
+ const messageModel = this._modelForMessage(assistantMessage);
2274
+ const sameModel = messageModel !== undefined;
2275
+ const contextWindow = (messageModel ?? this.model)?.contextWindow ?? 0;
2040
2276
  // Skip compaction checks if this assistant message is older than the latest
2041
2277
  // compaction boundary. This prevents a stale pre-compaction usage/error
2042
2278
  // from retriggering compaction on the first prompt after compaction.
@@ -2068,7 +2304,7 @@ export class AgentSession {
2068
2304
  const contextOverflow = sameModel &&
2069
2305
  ((explicitOverflow && assistantRetainedForExplicitRecovery) ||
2070
2306
  (assistantUsageMatchesProjection && isContextOverflow(assistantMessage, contextWindow)));
2071
- const recoverableLength = sameModel && assistantIsProjected && isRecoverableLength(assistantMessage, this.model?.maxTokens ?? 0);
2307
+ const recoverableLength = sameModel && assistantIsProjected && isRecoverableLength(assistantMessage, messageModel.maxTokens);
2072
2308
  if (contextOverflow || recoverableLength) {
2073
2309
  const willRetry = assistantMessage.stopReason !== "stop";
2074
2310
  // Case 2: the response completed successfully. Compact, but do not retry because
@@ -2100,7 +2336,10 @@ export class AgentSession {
2100
2336
  // Persistently omit the selected final attempt before post-run recovery compaction.
2101
2337
  this._overflowRecoveryAttempted = true;
2102
2338
  this._omitRecoveryAttempt(assistantMessage, toolResults);
2103
- return await this._runAutoCompaction("overflow", willRetry);
2339
+ const retry = await this._runAutoCompaction("overflow", willRetry);
2340
+ if (retry)
2341
+ this._failedResponse = assistantMessage;
2342
+ return retry;
2104
2343
  }
2105
2344
  // Case 3: threshold compaction without retry.
2106
2345
  // For error messages or all-zero usage messages, estimate from the last valid response.
@@ -2170,8 +2409,6 @@ export class AgentSession {
2170
2409
  started = true;
2171
2410
  this._emit({ type: "compaction_start", reason });
2172
2411
  abortController.signal.throwIfAborted();
2173
- const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, abortController.signal);
2174
- abortController.signal.throwIfAborted();
2175
2412
  let extensionCompaction;
2176
2413
  if (this._extensionRunner.hasHandlers("session_before_compact")) {
2177
2414
  const extensionResult = (await this._extensionRunner.emit({
@@ -2208,7 +2445,7 @@ export class AgentSession {
2208
2445
  }
2209
2446
  else {
2210
2447
  // Shared default summary generator, also used by manual compaction.
2211
- const compactResult = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, undefined, abortController.signal, env, reason);
2448
+ const compactResult = await this._runDefaultCompaction(preparation, model, undefined, abortController.signal, reason);
2212
2449
  summary = compactResult.summary;
2213
2450
  firstKeptEntryId = compactResult.firstKeptEntryId;
2214
2451
  tokensBefore = compactResult.tokensBefore;
@@ -2311,6 +2548,7 @@ export class AgentSession {
2311
2548
  }
2312
2549
  this._applyExtensionBindings(this._extensionRunner);
2313
2550
  await this._extensionRunner.emit(this._sessionStartEvent);
2551
+ this._extensionRunner.reportUnhandledMcpServers();
2314
2552
  await this.extendResourcesFromExtensions(this._sessionStartEvent.reason === "reload" ? "reload" : "startup");
2315
2553
  }
2316
2554
  async extendResourcesFromExtensions(reason) {
@@ -2332,7 +2570,7 @@ export class AgentSession {
2332
2570
  buildExtensionResourcePaths(entries) {
2333
2571
  return entries.map((entry) => {
2334
2572
  const source = this.getExtensionSourceLabel(entry.extensionPath);
2335
- const baseDir = entry.extensionPath.startsWith("<") ? undefined : dirname(entry.extensionPath);
2573
+ const baseDir = isSyntheticPath(entry.extensionPath) ? undefined : dirname(entry.extensionPath);
2336
2574
  return {
2337
2575
  path: entry.path,
2338
2576
  metadata: {
@@ -2345,7 +2583,7 @@ export class AgentSession {
2345
2583
  });
2346
2584
  }
2347
2585
  getExtensionSourceLabel(extensionPath) {
2348
- if (extensionPath.startsWith("<")) {
2586
+ if (isSyntheticPath(extensionPath)) {
2349
2587
  return `extension:${extensionPath.replace(/[<>]/g, "")}`;
2350
2588
  }
2351
2589
  const base = basename(extensionPath);
@@ -2430,6 +2668,7 @@ export class AgentSession {
2430
2668
  },
2431
2669
  getActiveTools: () => this.getActiveToolNames(),
2432
2670
  getAllTools: () => this.getAllTools(),
2671
+ getSettings: () => this.settingsManager.getSettings(),
2433
2672
  setActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),
2434
2673
  refreshTools: () => this._refreshToolRegistry(),
2435
2674
  getCommands,
@@ -2473,6 +2712,8 @@ export class AgentSession {
2473
2712
  },
2474
2713
  getSystemPrompt: () => this.systemPrompt,
2475
2714
  getSystemPromptOptions: () => this._baseSystemPromptOptions,
2715
+ executeTool: (callerId, name, args, options) => this._executeNestedToolCall(callerId, name, args, options),
2716
+ getCallableTools: () => this._getCallableTools(),
2476
2717
  }, {
2477
2718
  registerProvider: (name, config) => {
2478
2719
  this._modelRuntime.registerProvider(name, config);
@@ -2486,10 +2727,20 @@ export class AgentSession {
2486
2727
  this._modelRuntime.unregisterProvider(name);
2487
2728
  this._refreshCurrentModelFromRegistry();
2488
2729
  },
2730
+ registerVirtualModel: (definition) => {
2731
+ this._modelRuntime.registerVirtualModel(definition);
2732
+ this._refreshCurrentModelFromRegistry();
2733
+ },
2734
+ unregisterVirtualModel: (provider, id) => {
2735
+ this._modelRuntime.unregisterVirtualModel(provider, id);
2736
+ this._refreshCurrentModelFromRegistry();
2737
+ },
2489
2738
  });
2490
2739
  }
2491
2740
  _refreshToolRegistry(options) {
2492
- const previousRegistryNames = new Set(this._toolRegistry.keys());
2741
+ // Tools that were already activated on registration. A tool whose exposure changes to
2742
+ // `direct` or `model-only` (for example from `hidden`) is activated like a new tool.
2743
+ const previousActivatedOnRegistration = new Set([...this._toolRegistry.keys()].filter((name) => this._isActivatedOnRegistration(name)));
2493
2744
  const previousActiveToolNames = this.getActiveToolNames();
2494
2745
  const allowedToolNames = this._allowedToolNames;
2495
2746
  const excludedToolNames = this._excludedToolNames;
@@ -2508,7 +2759,7 @@ export class AgentSession {
2508
2759
  name,
2509
2760
  {
2510
2761
  definition,
2511
- sourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, { source: "builtin" }),
2762
+ sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${name}`, { source: "builtin" }),
2512
2763
  },
2513
2764
  ]));
2514
2765
  for (const tool of allCustomTools) {
@@ -2536,7 +2787,9 @@ export class AgentSession {
2536
2787
  .filter((definition) => isAllowedTool(definition.name))
2537
2788
  .map((definition) => ({
2538
2789
  definition,
2539
- sourceInfo: createSyntheticSourceInfo(`<builtin:${definition.name}>`, { source: "builtin" }),
2790
+ sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${definition.name}`, {
2791
+ source: "builtin",
2792
+ }),
2540
2793
  })), runner);
2541
2794
  const toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));
2542
2795
  for (const tool of wrappedExtensionTools) {
@@ -2546,25 +2799,36 @@ export class AgentSession {
2546
2799
  const nextActiveToolNames = (options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]).filter((name) => isAllowedTool(name));
2547
2800
  if (allowedToolNames) {
2548
2801
  for (const toolName of this._toolRegistry.keys()) {
2549
- if (allowedToolNames.has(toolName)) {
2802
+ // Naming a tool activates it even when it is not active by default.
2803
+ if (allowedToolNames.has(toolName) && this._isDeclarable(toolName)) {
2550
2804
  nextActiveToolNames.push(toolName);
2551
2805
  }
2552
2806
  }
2553
2807
  }
2554
2808
  else if (options?.includeAllExtensionTools) {
2555
2809
  for (const tool of wrappedExtensionTools) {
2556
- nextActiveToolNames.push(tool.name);
2810
+ if (this._isActivatedOnRegistration(tool.name))
2811
+ nextActiveToolNames.push(tool.name);
2557
2812
  }
2558
2813
  }
2559
2814
  else if (!options?.activeToolNames) {
2560
2815
  for (const toolName of this._toolRegistry.keys()) {
2561
- if (!previousRegistryNames.has(toolName)) {
2816
+ if (!previousActivatedOnRegistration.has(toolName) && this._isActivatedOnRegistration(toolName)) {
2562
2817
  nextActiveToolNames.push(toolName);
2563
2818
  }
2564
2819
  }
2565
2820
  }
2566
2821
  this.setActiveToolsByName([...new Set(nextActiveToolNames)]);
2567
2822
  }
2823
+ /** Whether activating the tool declares it to the model. */
2824
+ _isDeclarable(name) {
2825
+ const exposure = this._getToolExposure(name);
2826
+ return exposure === "direct" || exposure === "model-only";
2827
+ }
2828
+ /** Whether registering the tool activates it, which declares it to the model. */
2829
+ _isActivatedOnRegistration(name) {
2830
+ return this._isDeclarable(name) && this._toolDefinitions.get(name)?.definition.defaultActive !== false;
2831
+ }
2568
2832
  _buildRuntime(options) {
2569
2833
  const autoResizeImages = this.settingsManager.getImageAutoResize();
2570
2834
  const shellCommandPrefix = this.settingsManager.getShellCommandPrefix();
@@ -2621,6 +2885,7 @@ export class AgentSession {
2621
2885
  if (hasBindings) {
2622
2886
  await options?.beforeSessionStart?.();
2623
2887
  await this._extensionRunner.emit({ type: "session_start", reason: "reload" });
2888
+ this._extensionRunner.reportUnhandledMcpServers();
2624
2889
  await this.extendResourcesFromExtensions("reload");
2625
2890
  }
2626
2891
  }
@@ -2633,7 +2898,7 @@ export class AgentSession {
2633
2898
  */
2634
2899
  _isRetryableError(message) {
2635
2900
  // Context overflow is handled by compaction, not retry.
2636
- if (isContextOverflow(message, this.model?.contextWindow ?? 0))
2901
+ if (isContextOverflow(message, (this._modelForMessage(message) ?? this.model)?.contextWindow ?? 0))
2637
2902
  return false;
2638
2903
  return isRetryableAssistantError(message);
2639
2904
  }
@@ -2923,15 +3188,11 @@ export class AgentSession {
2923
3188
  let summaryDetails;
2924
3189
  let summaryUsage;
2925
3190
  if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
2926
- const model = this.model;
2927
- const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
3191
+ const signal = this._branchSummaryAbortController.signal;
2928
3192
  const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
2929
3193
  const result = await generateBranchSummary(entriesToSummarize, {
2930
- model: requestModel,
2931
- apiKey,
2932
- headers,
2933
- env,
2934
- signal: this._branchSummaryAbortController.signal,
3194
+ ...(await this._getSummarizationRequestAuth(this.model, signal)),
3195
+ signal,
2935
3196
  customInstructions,
2936
3197
  replaceInstructions,
2937
3198
  reserveTokens: branchSummarySettings.reserveTokens,
@@ -3096,7 +3357,7 @@ export class AgentSession {
3096
3357
  };
3097
3358
  }
3098
3359
  getContextUsage() {
3099
- const model = this.model;
3360
+ const model = this._limitsModel();
3100
3361
  if (!model)
3101
3362
  return undefined;
3102
3363
  const contextWindow = model.contextWindow ?? 0;
@@ -3168,16 +3429,11 @@ export class AgentSession {
3168
3429
  if (!model) {
3169
3430
  throw new Error("No model selected");
3170
3431
  }
3171
- const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
3172
3432
  return generateBugReportSummary({
3433
+ ...(await this._getSummarizationRequestAuth(model, options.signal)),
3173
3434
  messages: this.messages,
3174
3435
  hint: options.hint,
3175
- model: requestModel,
3176
- apiKey,
3177
- headers,
3178
- env,
3179
3436
  signal: options.signal,
3180
- thinkingLevel: this.thinkingLevel,
3181
3437
  streamFn: this.agent.streamFunction,
3182
3438
  retry: this.settingsManager.getRetrySettings(),
3183
3439
  sessionId: this.sessionId,