@astralyn/pi 0.87.6 → 1.0.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 (924) hide show
  1. package/CHANGELOG.md +69 -9
  2. package/README.md +3 -3
  3. package/dist/bun/runtime-setup.js +4 -1
  4. package/dist/bun/runtime-setup.js.map +1 -1
  5. package/dist/bundle/chunks/anthropic-messages-CG2BSDQS.js +6 -0
  6. package/dist/bundle/chunks/anthropic.js +2 -2
  7. package/dist/bundle/chunks/azure-openai-responses-PBA4QKCM.js +2 -0
  8. package/dist/bundle/chunks/bedrock-converse-stream.js +8 -8
  9. package/dist/bundle/chunks/{chunk-NW5FIDD7.js → chunk-6UFFVA7M.js} +3 -3
  10. package/dist/bundle/chunks/chunk-G4RY3GN7.js +11 -0
  11. package/dist/bundle/chunks/chunk-GCKVOFWP.js +2 -0
  12. package/dist/bundle/chunks/chunk-GIG5IHES.js +2 -0
  13. package/dist/bundle/chunks/{chunk-4W4Q2H6W.js → chunk-HESRDUKO.js} +1000 -625
  14. package/dist/bundle/chunks/chunk-MPDALHNJ.js +2 -0
  15. package/dist/bundle/chunks/chunk-OO6DJ3CL.js +31 -0
  16. package/dist/bundle/chunks/{chunk-LPQCB2VJ.js → chunk-PFZKRUMO.js} +2 -2
  17. package/dist/bundle/chunks/chunk-SGLYRVQL.js +2 -0
  18. package/dist/bundle/chunks/chunk-TRHTWM3C.js +2 -0
  19. package/dist/bundle/chunks/chunk-V66VGGOM.js +2 -0
  20. package/dist/bundle/chunks/chunk-Z2RKSI3O.js +2 -0
  21. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-YB7XPPP4.js +2 -0
  22. package/dist/bundle/chunks/codemode-worker.js +354 -0
  23. package/dist/bundle/chunks/github-copilot.js +1 -1
  24. package/dist/bundle/chunks/google-generative-ai-V5ZM5MCL.js +2 -0
  25. package/dist/bundle/chunks/google-vertex-22THOFP5.js +2 -0
  26. package/dist/bundle/chunks/llama-cpp-classify-R7DQLTQN.js +22 -0
  27. package/dist/bundle/chunks/meta.js +2 -0
  28. package/dist/bundle/chunks/mistral-conversations-WHSCJJWP.js +5 -0
  29. package/dist/bundle/chunks/openai-chatgpt.js +75 -0
  30. package/dist/bundle/chunks/openai-codex-responses-N7GDPBPP.js +10 -0
  31. package/dist/bundle/chunks/openai-codex.js +2 -2
  32. package/dist/bundle/chunks/openai-completions-RGGQK5UW.js +7 -0
  33. package/dist/bundle/chunks/openai-responses-3ZLD5JYI.js +3 -0
  34. package/dist/bundle/chunks/{openrouter-images-6XDE2CEW.js → openrouter-images-YP3YVB54.js} +1 -1
  35. package/dist/bundle/chunks/openrouter.js +2 -2
  36. package/dist/bundle/chunks/{pi-messages-MQMPIPNC.js → pi-messages-HZZ7GEEW.js} +2 -2
  37. package/dist/bundle/chunks/radius.js +2 -2
  38. package/dist/bundle/chunks/typesafe-system-one-RREJAKWB.js +2 -0
  39. package/dist/bundle/chunks/virtual-modules-4RQ2L6W4.js +2 -0
  40. package/dist/bundle/cli.js +1 -1
  41. package/dist/bundle/index.js +1 -1
  42. package/dist/bundle/rpc-entry.js +1 -1
  43. package/dist/cli/args.d.ts.map +1 -1
  44. package/dist/cli/args.js +5 -4
  45. package/dist/cli/args.js.map +1 -1
  46. package/dist/cli/startup-ui.d.ts.map +1 -1
  47. package/dist/cli/startup-ui.js +38 -30
  48. package/dist/cli/startup-ui.js.map +1 -1
  49. package/dist/config.d.ts +15 -4
  50. package/dist/config.d.ts.map +1 -1
  51. package/dist/config.js +33 -4
  52. package/dist/config.js.map +1 -1
  53. package/dist/core/agent-session-runtime.d.ts +1 -1
  54. package/dist/core/agent-session-runtime.d.ts.map +1 -1
  55. package/dist/core/agent-session-runtime.js +13 -13
  56. package/dist/core/agent-session-runtime.js.map +1 -1
  57. package/dist/core/agent-session-services.d.ts +2 -2
  58. package/dist/core/agent-session-services.d.ts.map +1 -1
  59. package/dist/core/agent-session-services.js +14 -1
  60. package/dist/core/agent-session-services.js.map +1 -1
  61. package/dist/core/agent-session.d.ts +121 -36
  62. package/dist/core/agent-session.d.ts.map +1 -1
  63. package/dist/core/agent-session.js +518 -203
  64. package/dist/core/agent-session.js.map +1 -1
  65. package/dist/core/bug-report.js +1 -1
  66. package/dist/core/bug-report.js.map +1 -1
  67. package/dist/core/compaction/compaction.d.ts.map +1 -1
  68. package/dist/core/compaction/compaction.js +1 -22
  69. package/dist/core/compaction/compaction.js.map +1 -1
  70. package/dist/core/compaction/utils.d.ts +2 -1
  71. package/dist/core/compaction/utils.d.ts.map +1 -1
  72. package/dist/core/compaction/utils.js +25 -18
  73. package/dist/core/compaction/utils.js.map +1 -1
  74. package/dist/core/crash-log.d.ts.map +1 -1
  75. package/dist/core/crash-log.js +2 -1
  76. package/dist/core/crash-log.js.map +1 -1
  77. package/dist/core/export-html/template.css +10 -0
  78. package/dist/core/export-html/template.js +66 -17
  79. package/dist/core/extensions/distribution-api.d.ts +1 -1
  80. package/dist/core/extensions/distribution-api.d.ts.map +1 -1
  81. package/dist/core/extensions/distribution-api.js.map +1 -1
  82. package/dist/core/extensions/index.d.ts +2 -2
  83. package/dist/core/extensions/index.d.ts.map +1 -1
  84. package/dist/core/extensions/index.js.map +1 -1
  85. package/dist/core/extensions/loader.d.ts.map +1 -1
  86. package/dist/core/extensions/loader.js +67 -5
  87. package/dist/core/extensions/loader.js.map +1 -1
  88. package/dist/core/extensions/runner.d.ts +22 -3
  89. package/dist/core/extensions/runner.d.ts.map +1 -1
  90. package/dist/core/extensions/runner.js +124 -8
  91. package/dist/core/extensions/runner.js.map +1 -1
  92. package/dist/core/extensions/types.d.ts +310 -25
  93. package/dist/core/extensions/types.d.ts.map +1 -1
  94. package/dist/core/extensions/types.js.map +1 -1
  95. package/dist/core/extensions/wrapper.d.ts +2 -2
  96. package/dist/core/extensions/wrapper.d.ts.map +1 -1
  97. package/dist/core/extensions/wrapper.js +3 -3
  98. package/dist/core/extensions/wrapper.js.map +1 -1
  99. package/dist/core/keybindings.d.ts +70 -5
  100. package/dist/core/keybindings.d.ts.map +1 -1
  101. package/dist/core/keybindings.js +15 -1
  102. package/dist/core/keybindings.js.map +1 -1
  103. package/dist/core/mcp-servers.d.ts +125 -0
  104. package/dist/core/mcp-servers.d.ts.map +1 -0
  105. package/dist/core/mcp-servers.js +199 -0
  106. package/dist/core/mcp-servers.js.map +1 -0
  107. package/dist/core/model-registry.d.ts +15 -1
  108. package/dist/core/model-registry.d.ts.map +1 -1
  109. package/dist/core/model-registry.js +29 -0
  110. package/dist/core/model-registry.js.map +1 -1
  111. package/dist/core/model-resolver.d.ts +2 -2
  112. package/dist/core/model-resolver.d.ts.map +1 -1
  113. package/dist/core/model-resolver.js +5 -5
  114. package/dist/core/model-resolver.js.map +1 -1
  115. package/dist/core/model-runtime.d.ts +47 -3
  116. package/dist/core/model-runtime.d.ts.map +1 -1
  117. package/dist/core/model-runtime.js +189 -35
  118. package/dist/core/model-runtime.js.map +1 -1
  119. package/dist/core/nested-tool-calls.d.ts +102 -0
  120. package/dist/core/nested-tool-calls.d.ts.map +1 -0
  121. package/dist/core/nested-tool-calls.js +177 -0
  122. package/dist/core/nested-tool-calls.js.map +1 -0
  123. package/dist/core/package-manager.d.ts +4 -0
  124. package/dist/core/package-manager.d.ts.map +1 -1
  125. package/dist/core/package-manager.js +58 -12
  126. package/dist/core/package-manager.js.map +1 -1
  127. package/dist/core/provider-composer.d.ts +40 -21
  128. package/dist/core/provider-composer.d.ts.map +1 -1
  129. package/dist/core/provider-composer.js +92 -40
  130. package/dist/core/provider-composer.js.map +1 -1
  131. package/dist/core/radius.d.ts +2 -0
  132. package/dist/core/radius.d.ts.map +1 -1
  133. package/dist/core/radius.js +2 -0
  134. package/dist/core/radius.js.map +1 -1
  135. package/dist/core/remote-catalog-provider.d.ts +8 -1
  136. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  137. package/dist/core/remote-catalog-provider.js +21 -11
  138. package/dist/core/remote-catalog-provider.js.map +1 -1
  139. package/dist/core/resource-loader.d.ts +7 -1
  140. package/dist/core/resource-loader.d.ts.map +1 -1
  141. package/dist/core/resource-loader.js +160 -35
  142. package/dist/core/resource-loader.js.map +1 -1
  143. package/dist/core/sdk.d.ts +3 -3
  144. package/dist/core/sdk.d.ts.map +1 -1
  145. package/dist/core/sdk.js +26 -7
  146. package/dist/core/sdk.js.map +1 -1
  147. package/dist/core/session-manager.d.ts +9 -0
  148. package/dist/core/session-manager.d.ts.map +1 -1
  149. package/dist/core/session-manager.js +22 -22
  150. package/dist/core/session-manager.js.map +1 -1
  151. package/dist/core/settings-manager.d.ts +41 -4
  152. package/dist/core/settings-manager.d.ts.map +1 -1
  153. package/dist/core/settings-manager.js +110 -3
  154. package/dist/core/settings-manager.js.map +1 -1
  155. package/dist/core/slash-commands.d.ts.map +1 -1
  156. package/dist/core/slash-commands.js +1 -0
  157. package/dist/core/slash-commands.js.map +1 -1
  158. package/dist/core/source-info.d.ts +8 -0
  159. package/dist/core/source-info.d.ts.map +1 -1
  160. package/dist/core/source-info.js +16 -0
  161. package/dist/core/source-info.js.map +1 -1
  162. package/dist/core/system-prompt.js +1 -1
  163. package/dist/core/system-prompt.js.map +1 -1
  164. package/dist/core/tasks/delivery.d.ts +40 -0
  165. package/dist/core/tasks/delivery.d.ts.map +1 -0
  166. package/dist/core/tasks/delivery.js +157 -0
  167. package/dist/core/tasks/delivery.js.map +1 -0
  168. package/dist/core/tasks/format.d.ts +7 -0
  169. package/dist/core/tasks/format.d.ts.map +1 -0
  170. package/dist/core/tasks/format.js +14 -0
  171. package/dist/core/tasks/format.js.map +1 -0
  172. package/dist/core/tasks/history.d.ts +4 -0
  173. package/dist/core/tasks/history.d.ts.map +1 -0
  174. package/dist/core/{background → tasks}/history.js +8 -51
  175. package/dist/core/tasks/history.js.map +1 -0
  176. package/dist/core/{background → tasks}/output.d.ts +12 -4
  177. package/dist/core/tasks/output.d.ts.map +1 -0
  178. package/dist/core/{background → tasks}/output.js +30 -11
  179. package/dist/core/tasks/output.js.map +1 -0
  180. package/dist/core/tasks/presentation.d.ts +7 -0
  181. package/dist/core/tasks/presentation.d.ts.map +1 -0
  182. package/dist/core/tasks/presentation.js +226 -0
  183. package/dist/core/tasks/presentation.js.map +1 -0
  184. package/dist/core/tasks/runtime.d.ts +74 -0
  185. package/dist/core/tasks/runtime.d.ts.map +1 -0
  186. package/dist/core/tasks/runtime.js +580 -0
  187. package/dist/core/tasks/runtime.js.map +1 -0
  188. package/dist/core/tasks/session.d.ts +49 -0
  189. package/dist/core/tasks/session.d.ts.map +1 -0
  190. package/dist/core/tasks/session.js +138 -0
  191. package/dist/core/tasks/session.js.map +1 -0
  192. package/dist/core/tasks/store.d.ts +46 -0
  193. package/dist/core/tasks/store.d.ts.map +1 -0
  194. package/dist/core/tasks/store.js +162 -0
  195. package/dist/core/tasks/store.js.map +1 -0
  196. package/dist/core/{background → tasks}/types.d.ts +64 -86
  197. package/dist/core/tasks/types.d.ts.map +1 -0
  198. package/dist/core/tasks/types.js +27 -0
  199. package/dist/core/tasks/types.js.map +1 -0
  200. package/dist/core/tools/bash.d.ts +8 -93
  201. package/dist/core/tools/bash.d.ts.map +1 -1
  202. package/dist/core/tools/bash.js +8 -240
  203. package/dist/core/tools/bash.js.map +1 -1
  204. package/dist/core/tools/grep.d.ts +2 -0
  205. package/dist/core/tools/grep.d.ts.map +1 -1
  206. package/dist/core/tools/grep.js +2 -0
  207. package/dist/core/tools/grep.js.map +1 -1
  208. package/dist/core/tools/index.d.ts +2 -1
  209. package/dist/core/tools/index.d.ts.map +1 -1
  210. package/dist/core/tools/index.js +9 -0
  211. package/dist/core/tools/index.js.map +1 -1
  212. package/dist/core/tools/output-accumulator.d.ts +11 -0
  213. package/dist/core/tools/output-accumulator.d.ts.map +1 -1
  214. package/dist/core/tools/output-accumulator.js +36 -0
  215. package/dist/core/tools/output-accumulator.js.map +1 -1
  216. package/dist/core/tools/powershell.d.ts +6 -2
  217. package/dist/core/tools/powershell.d.ts.map +1 -1
  218. package/dist/core/tools/powershell.js +1 -1
  219. package/dist/core/tools/powershell.js.map +1 -1
  220. package/dist/core/tools/render-utils.d.ts +6 -0
  221. package/dist/core/tools/render-utils.d.ts.map +1 -1
  222. package/dist/core/tools/render-utils.js +26 -0
  223. package/dist/core/tools/render-utils.js.map +1 -1
  224. package/dist/core/tools/renderers/bash.d.ts +1 -1
  225. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  226. package/dist/core/tools/renderers/bash.js +11 -35
  227. package/dist/core/tools/renderers/bash.js.map +1 -1
  228. package/dist/core/tools/renderers/index.d.ts.map +1 -1
  229. package/dist/core/tools/renderers/index.js +5 -7
  230. package/dist/core/tools/renderers/index.js.map +1 -1
  231. package/dist/core/tools/renderers/read.d.ts.map +1 -1
  232. package/dist/core/tools/renderers/read.js +3 -2
  233. package/dist/core/tools/renderers/read.js.map +1 -1
  234. package/dist/core/tools/shell-execution.d.ts +4 -6
  235. package/dist/core/tools/shell-execution.d.ts.map +1 -1
  236. package/dist/core/tools/shell-execution.js +22 -13
  237. package/dist/core/tools/shell-execution.js.map +1 -1
  238. package/dist/core/tools/shell-tool.d.ts +93 -0
  239. package/dist/core/tools/shell-tool.d.ts.map +1 -0
  240. package/dist/core/tools/shell-tool.js +249 -0
  241. package/dist/core/tools/shell-tool.js.map +1 -0
  242. package/dist/core/tools/tasks/actions.d.ts +12 -0
  243. package/dist/core/tools/tasks/actions.d.ts.map +1 -0
  244. package/dist/{extensions/background → core/tools/tasks}/actions.js +44 -29
  245. package/dist/core/tools/tasks/actions.js.map +1 -0
  246. package/dist/core/tools/tasks/constants.d.ts +20 -0
  247. package/dist/core/tools/tasks/constants.d.ts.map +1 -0
  248. package/dist/core/tools/tasks/constants.js +20 -0
  249. package/dist/core/tools/tasks/constants.js.map +1 -0
  250. package/dist/{extensions/background → core/tools/tasks}/schema.d.ts +7 -7
  251. package/dist/core/tools/tasks/schema.d.ts.map +1 -0
  252. package/dist/{extensions/background → core/tools/tasks}/schema.js +21 -20
  253. package/dist/core/tools/tasks/schema.js.map +1 -0
  254. package/dist/core/tools/tasks/types.d.ts +53 -0
  255. package/dist/core/tools/tasks/types.d.ts.map +1 -0
  256. package/dist/core/tools/tasks/types.js +12 -0
  257. package/dist/core/tools/tasks/types.js.map +1 -0
  258. package/dist/core/tools/tasks.d.ts +14 -0
  259. package/dist/core/tools/tasks.d.ts.map +1 -0
  260. package/dist/core/tools/tasks.js +40 -0
  261. package/dist/core/tools/tasks.js.map +1 -0
  262. package/dist/core/tools/tool-definition-wrapper.d.ts +4 -3
  263. package/dist/core/tools/tool-definition-wrapper.d.ts.map +1 -1
  264. package/dist/core/tools/tool-definition-wrapper.js +4 -2
  265. package/dist/core/tools/tool-definition-wrapper.js.map +1 -1
  266. package/dist/core/tools/truncate.d.ts +14 -0
  267. package/dist/core/tools/truncate.d.ts.map +1 -1
  268. package/dist/core/tools/truncate.js +29 -0
  269. package/dist/core/tools/truncate.js.map +1 -1
  270. package/dist/core/trust-manager.d.ts.map +1 -1
  271. package/dist/core/trust-manager.js +1 -0
  272. package/dist/core/trust-manager.js.map +1 -1
  273. package/dist/core/usage-totals.d.ts +5 -3
  274. package/dist/core/usage-totals.d.ts.map +1 -1
  275. package/dist/core/usage-totals.js +27 -4
  276. package/dist/core/usage-totals.js.map +1 -1
  277. package/dist/core/virtual-models.d.ts +117 -0
  278. package/dist/core/virtual-models.d.ts.map +1 -0
  279. package/dist/core/virtual-models.js +124 -0
  280. package/dist/core/virtual-models.js.map +1 -0
  281. package/dist/extensions/btw/agent.d.ts +17 -8
  282. package/dist/extensions/btw/agent.d.ts.map +1 -1
  283. package/dist/extensions/btw/agent.js +74 -76
  284. package/dist/extensions/btw/agent.js.map +1 -1
  285. package/dist/extensions/btw/controller.d.ts +0 -1
  286. package/dist/extensions/btw/controller.d.ts.map +1 -1
  287. package/dist/extensions/btw/controller.js +26 -33
  288. package/dist/extensions/btw/controller.js.map +1 -1
  289. package/dist/extensions/btw/panel.d.ts +13 -14
  290. package/dist/extensions/btw/panel.d.ts.map +1 -1
  291. package/dist/extensions/btw/panel.js +38 -29
  292. package/dist/extensions/btw/panel.js.map +1 -1
  293. package/dist/extensions/codemode/execute.d.ts +16 -0
  294. package/dist/extensions/codemode/execute.d.ts.map +1 -0
  295. package/dist/extensions/codemode/execute.js +536 -0
  296. package/dist/extensions/codemode/execute.js.map +1 -0
  297. package/dist/extensions/codemode/execute.lazy.d.ts +3 -0
  298. package/dist/extensions/codemode/execute.lazy.d.ts.map +1 -0
  299. package/dist/extensions/codemode/execute.lazy.js +3 -0
  300. package/dist/extensions/codemode/execute.lazy.js.map +1 -0
  301. package/dist/extensions/codemode/index.d.ts +21 -0
  302. package/dist/extensions/codemode/index.d.ts.map +1 -0
  303. package/dist/extensions/codemode/index.js +36 -0
  304. package/dist/extensions/codemode/index.js.map +1 -0
  305. package/dist/extensions/codemode/renderer.d.ts +12 -0
  306. package/dist/extensions/codemode/renderer.d.ts.map +1 -0
  307. package/dist/extensions/codemode/renderer.js +137 -0
  308. package/dist/extensions/codemode/renderer.js.map +1 -0
  309. package/dist/extensions/codemode/search.d.ts +33 -0
  310. package/dist/extensions/codemode/search.d.ts.map +1 -0
  311. package/dist/extensions/codemode/search.js +117 -0
  312. package/dist/extensions/codemode/search.js.map +1 -0
  313. package/dist/extensions/codemode/tool.d.ts +123 -0
  314. package/dist/extensions/codemode/tool.d.ts.map +1 -0
  315. package/dist/extensions/codemode/tool.js +268 -0
  316. package/dist/extensions/codemode/tool.js.map +1 -0
  317. package/dist/extensions/codemode/worker.d.ts +7 -0
  318. package/dist/extensions/codemode/worker.d.ts.map +1 -0
  319. package/dist/extensions/codemode/worker.js +7 -0
  320. package/dist/extensions/codemode/worker.js.map +1 -0
  321. package/dist/extensions/deepwiki/schema.d.ts +1 -1
  322. package/dist/extensions/index.js +13 -13
  323. package/dist/extensions/index.js.map +1 -1
  324. package/dist/extensions/llama/provider.d.ts +1 -1
  325. package/dist/extensions/llama/provider.d.ts.map +1 -1
  326. package/dist/extensions/llama/provider.js +65 -13
  327. package/dist/extensions/llama/provider.js.map +1 -1
  328. package/dist/extensions/mcp/cli.d.ts +21 -0
  329. package/dist/extensions/mcp/cli.d.ts.map +1 -0
  330. package/dist/extensions/mcp/cli.js +500 -0
  331. package/dist/extensions/mcp/cli.js.map +1 -0
  332. package/dist/extensions/mcp/cli.lazy.d.ts +3 -0
  333. package/dist/extensions/mcp/cli.lazy.d.ts.map +1 -0
  334. package/dist/extensions/mcp/cli.lazy.js +3 -0
  335. package/dist/extensions/mcp/cli.lazy.js.map +1 -0
  336. package/dist/extensions/mcp/config.d.ts +72 -0
  337. package/dist/extensions/mcp/config.d.ts.map +1 -0
  338. package/dist/extensions/mcp/config.js +158 -0
  339. package/dist/extensions/mcp/config.js.map +1 -0
  340. package/dist/extensions/mcp/index.d.ts +76 -0
  341. package/dist/extensions/mcp/index.d.ts.map +1 -0
  342. package/dist/extensions/mcp/index.js +1078 -0
  343. package/dist/extensions/mcp/index.js.map +1 -0
  344. package/dist/extensions/mcp/log.d.ts +16 -0
  345. package/dist/extensions/mcp/log.d.ts.map +1 -0
  346. package/dist/extensions/mcp/log.js +64 -0
  347. package/dist/extensions/mcp/log.js.map +1 -0
  348. package/dist/extensions/mcp/oauth.d.ts +97 -0
  349. package/dist/extensions/mcp/oauth.d.ts.map +1 -0
  350. package/dist/extensions/mcp/oauth.js +355 -0
  351. package/dist/extensions/mcp/oauth.js.map +1 -0
  352. package/dist/extensions/mcp/resources.d.ts +43 -0
  353. package/dist/extensions/mcp/resources.d.ts.map +1 -0
  354. package/dist/extensions/mcp/resources.js +262 -0
  355. package/dist/extensions/mcp/resources.js.map +1 -0
  356. package/dist/extensions/mcp/runtime.d.ts +98 -0
  357. package/dist/extensions/mcp/runtime.d.ts.map +1 -0
  358. package/dist/extensions/mcp/runtime.js +379 -0
  359. package/dist/extensions/mcp/runtime.js.map +1 -0
  360. package/dist/extensions/mcp/runtime.lazy.d.ts +3 -0
  361. package/dist/extensions/mcp/runtime.lazy.d.ts.map +1 -0
  362. package/dist/extensions/mcp/runtime.lazy.js +3 -0
  363. package/dist/extensions/mcp/runtime.lazy.js.map +1 -0
  364. package/dist/extensions/mcp/tools.d.ts +84 -0
  365. package/dist/extensions/mcp/tools.d.ts.map +1 -0
  366. package/dist/extensions/mcp/tools.js +251 -0
  367. package/dist/extensions/mcp/tools.js.map +1 -0
  368. package/dist/extensions/mcp/ui.d.ts +60 -0
  369. package/dist/extensions/mcp/ui.d.ts.map +1 -0
  370. package/dist/extensions/mcp/ui.js +168 -0
  371. package/dist/extensions/mcp/ui.js.map +1 -0
  372. package/dist/extensions/provider/catalog.d.ts +8 -1
  373. package/dist/extensions/provider/catalog.d.ts.map +1 -1
  374. package/dist/extensions/provider/catalog.js +31 -0
  375. package/dist/extensions/provider/catalog.js.map +1 -1
  376. package/dist/extensions/provider/connection.d.ts +4 -1
  377. package/dist/extensions/provider/connection.d.ts.map +1 -1
  378. package/dist/extensions/provider/connection.js +1 -5
  379. package/dist/extensions/provider/connection.js.map +1 -1
  380. package/dist/extensions/provider/editing.d.ts +36 -0
  381. package/dist/extensions/provider/editing.d.ts.map +1 -0
  382. package/dist/extensions/provider/editing.js +99 -0
  383. package/dist/extensions/provider/editing.js.map +1 -0
  384. package/dist/extensions/provider/json-fields.d.ts +5 -0
  385. package/dist/extensions/provider/json-fields.d.ts.map +1 -0
  386. package/dist/extensions/provider/json-fields.js +31 -0
  387. package/dist/extensions/provider/json-fields.js.map +1 -0
  388. package/dist/extensions/provider/store.d.ts +1 -4
  389. package/dist/extensions/provider/store.d.ts.map +1 -1
  390. package/dist/extensions/provider/store.js +2 -30
  391. package/dist/extensions/provider/store.js.map +1 -1
  392. package/dist/extensions/provider/ui/builtin-data.d.ts +0 -2
  393. package/dist/extensions/provider/ui/builtin-data.d.ts.map +1 -1
  394. package/dist/extensions/provider/ui/builtin-data.js +14 -79
  395. package/dist/extensions/provider/ui/builtin-data.js.map +1 -1
  396. package/dist/extensions/provider/ui/compat.d.ts.map +1 -1
  397. package/dist/extensions/provider/ui/compat.js +6 -9
  398. package/dist/extensions/provider/ui/compat.js.map +1 -1
  399. package/dist/extensions/provider/ui/controls.d.ts +48 -0
  400. package/dist/extensions/provider/ui/controls.d.ts.map +1 -0
  401. package/dist/extensions/provider/ui/controls.js +108 -0
  402. package/dist/extensions/provider/ui/controls.js.map +1 -0
  403. package/dist/extensions/provider/ui/dictionary.d.ts.map +1 -1
  404. package/dist/extensions/provider/ui/dictionary.js +6 -9
  405. package/dist/extensions/provider/ui/dictionary.js.map +1 -1
  406. package/dist/extensions/provider/ui/editor.d.ts +3 -3
  407. package/dist/extensions/provider/ui/editor.d.ts.map +1 -1
  408. package/dist/extensions/provider/ui/editor.js +35 -140
  409. package/dist/extensions/provider/ui/editor.js.map +1 -1
  410. package/dist/extensions/provider/ui/fetch-models.d.ts +0 -3
  411. package/dist/extensions/provider/ui/fetch-models.d.ts.map +1 -1
  412. package/dist/extensions/provider/ui/fetch-models.js +49 -44
  413. package/dist/extensions/provider/ui/fetch-models.js.map +1 -1
  414. package/dist/extensions/provider/ui/model-fields.d.ts.map +1 -1
  415. package/dist/extensions/provider/ui/model-fields.js +11 -14
  416. package/dist/extensions/provider/ui/model-fields.js.map +1 -1
  417. package/dist/extensions/provider/ui/model-options.d.ts +4 -34
  418. package/dist/extensions/provider/ui/model-options.d.ts.map +1 -1
  419. package/dist/extensions/provider/ui/model-options.js +90 -271
  420. package/dist/extensions/provider/ui/model-options.js.map +1 -1
  421. package/dist/extensions/provider/ui/pane.d.ts +4 -18
  422. package/dist/extensions/provider/ui/pane.d.ts.map +1 -1
  423. package/dist/extensions/provider/ui/pane.js.map +1 -1
  424. package/dist/extensions/provider/ui/provider-fields.d.ts +2 -19
  425. package/dist/extensions/provider/ui/provider-fields.d.ts.map +1 -1
  426. package/dist/extensions/provider/ui/provider-fields.js +58 -171
  427. package/dist/extensions/provider/ui/provider-fields.js.map +1 -1
  428. package/dist/extensions/provider/ui/thinking-map.d.ts.map +1 -1
  429. package/dist/extensions/provider/ui/thinking-map.js +6 -9
  430. package/dist/extensions/provider/ui/thinking-map.js.map +1 -1
  431. package/dist/extensions/question/detail-pane.d.ts +7 -2
  432. package/dist/extensions/question/detail-pane.d.ts.map +1 -1
  433. package/dist/extensions/question/detail-pane.js +16 -5
  434. package/dist/extensions/question/detail-pane.js.map +1 -1
  435. package/dist/extensions/question/dialog-view.d.ts +41 -0
  436. package/dist/extensions/question/dialog-view.d.ts.map +1 -0
  437. package/dist/extensions/question/dialog-view.js +329 -0
  438. package/dist/extensions/question/dialog-view.js.map +1 -0
  439. package/dist/extensions/question/dialog.d.ts +3 -3
  440. package/dist/extensions/question/dialog.d.ts.map +1 -1
  441. package/dist/extensions/question/dialog.js +220 -634
  442. package/dist/extensions/question/dialog.js.map +1 -1
  443. package/dist/extensions/question/index.d.ts.map +1 -1
  444. package/dist/extensions/question/index.js +2 -3
  445. package/dist/extensions/question/index.js.map +1 -1
  446. package/dist/extensions/question/render.d.ts.map +1 -1
  447. package/dist/extensions/question/render.js +22 -32
  448. package/dist/extensions/question/render.js.map +1 -1
  449. package/dist/extensions/question/results.d.ts.map +1 -1
  450. package/dist/extensions/question/results.js +56 -12
  451. package/dist/extensions/question/results.js.map +1 -1
  452. package/dist/extensions/question/schema.d.ts +21 -6
  453. package/dist/extensions/question/schema.d.ts.map +1 -1
  454. package/dist/extensions/question/schema.js.map +1 -1
  455. package/dist/extensions/question/state.d.ts +9 -7
  456. package/dist/extensions/question/state.d.ts.map +1 -1
  457. package/dist/extensions/question/state.js +63 -54
  458. package/dist/extensions/question/state.js.map +1 -1
  459. package/dist/extensions/question/types.d.ts +41 -18
  460. package/dist/extensions/question/types.d.ts.map +1 -1
  461. package/dist/extensions/question/types.js.map +1 -1
  462. package/dist/extensions/statusline/index.d.ts +4 -0
  463. package/dist/extensions/statusline/index.d.ts.map +1 -1
  464. package/dist/extensions/statusline/index.js +18 -355
  465. package/dist/extensions/statusline/index.js.map +1 -1
  466. package/dist/extensions/statusline/render.d.ts +19 -0
  467. package/dist/extensions/statusline/render.d.ts.map +1 -0
  468. package/dist/extensions/statusline/render.js +163 -0
  469. package/dist/extensions/statusline/render.js.map +1 -0
  470. package/dist/extensions/statusline/usage.d.ts +12 -0
  471. package/dist/extensions/statusline/usage.d.ts.map +1 -0
  472. package/dist/extensions/statusline/usage.js +36 -0
  473. package/dist/extensions/statusline/usage.js.map +1 -0
  474. package/dist/extensions/tool-search/index.d.ts +12 -0
  475. package/dist/extensions/tool-search/index.d.ts.map +1 -0
  476. package/dist/extensions/tool-search/index.js +20 -0
  477. package/dist/extensions/tool-search/index.js.map +1 -0
  478. package/dist/extensions/tool-search/tool.d.ts +73 -0
  479. package/dist/extensions/tool-search/tool.d.ts.map +1 -0
  480. package/dist/extensions/tool-search/tool.js +187 -0
  481. package/dist/extensions/tool-search/tool.js.map +1 -0
  482. package/dist/extensions/web-search/execute.d.ts +1 -5
  483. package/dist/extensions/web-search/execute.d.ts.map +1 -1
  484. package/dist/extensions/web-search/execute.js +4 -9
  485. package/dist/extensions/web-search/execute.js.map +1 -1
  486. package/dist/extensions/web-search/format.d.ts +12 -3
  487. package/dist/extensions/web-search/format.d.ts.map +1 -1
  488. package/dist/extensions/web-search/format.js +33 -25
  489. package/dist/extensions/web-search/format.js.map +1 -1
  490. package/dist/extensions/web-search/index.d.ts.map +1 -1
  491. package/dist/extensions/web-search/index.js +6 -29
  492. package/dist/extensions/web-search/index.js.map +1 -1
  493. package/dist/extensions/web-search/providers/deepseek.d.ts.map +1 -1
  494. package/dist/extensions/web-search/providers/deepseek.js +0 -1
  495. package/dist/extensions/web-search/providers/deepseek.js.map +1 -1
  496. package/dist/extensions/web-search/providers/http.d.ts +1 -1
  497. package/dist/extensions/web-search/providers/http.d.ts.map +1 -1
  498. package/dist/extensions/web-search/providers/http.js.map +1 -1
  499. package/dist/extensions/web-search/providers/minimax.d.ts.map +1 -1
  500. package/dist/extensions/web-search/providers/minimax.js +0 -1
  501. package/dist/extensions/web-search/providers/minimax.js.map +1 -1
  502. package/dist/extensions/web-search/render.d.ts +7 -2
  503. package/dist/extensions/web-search/render.d.ts.map +1 -1
  504. package/dist/extensions/web-search/render.js +32 -4
  505. package/dist/extensions/web-search/render.js.map +1 -1
  506. package/dist/extensions/web-search/results.d.ts.map +1 -1
  507. package/dist/extensions/web-search/results.js +3 -8
  508. package/dist/extensions/web-search/results.js.map +1 -1
  509. package/dist/extensions/web-search/types.d.ts +4 -2
  510. package/dist/extensions/web-search/types.d.ts.map +1 -1
  511. package/dist/extensions/web-search/types.js.map +1 -1
  512. package/dist/index.d.ts +12 -5
  513. package/dist/index.d.ts.map +1 -1
  514. package/dist/index.js +6 -1
  515. package/dist/index.js.map +1 -1
  516. package/dist/main.d.ts.map +1 -1
  517. package/dist/main.js +16 -0
  518. package/dist/main.js.map +1 -1
  519. package/dist/modes/interactive/components/config-selector.d.ts.map +1 -1
  520. package/dist/modes/interactive/components/config-selector.js +13 -3
  521. package/dist/modes/interactive/components/config-selector.js.map +1 -1
  522. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  523. package/dist/modes/interactive/components/custom-message.js +3 -1
  524. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  525. package/dist/modes/interactive/components/first-time-setup.d.ts +4 -4
  526. package/dist/modes/interactive/components/first-time-setup.d.ts.map +1 -1
  527. package/dist/modes/interactive/components/first-time-setup.js +8 -2
  528. package/dist/modes/interactive/components/first-time-setup.js.map +1 -1
  529. package/dist/modes/interactive/components/footer.d.ts +7 -0
  530. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  531. package/dist/modes/interactive/components/footer.js +42 -3
  532. package/dist/modes/interactive/components/footer.js.map +1 -1
  533. package/dist/modes/interactive/components/oauth-selector.d.ts +8 -2
  534. package/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  535. package/dist/modes/interactive/components/oauth-selector.js +24 -21
  536. package/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  537. package/dist/modes/interactive/components/pi-logo-animation.d.ts +68 -0
  538. package/dist/modes/interactive/components/pi-logo-animation.d.ts.map +1 -0
  539. package/dist/modes/interactive/components/pi-logo-animation.js +1076 -0
  540. package/dist/modes/interactive/components/pi-logo-animation.js.map +1 -0
  541. package/dist/modes/interactive/components/pi-logo-animation.lazy.d.ts +7 -0
  542. package/dist/modes/interactive/components/pi-logo-animation.lazy.d.ts.map +1 -0
  543. package/dist/modes/interactive/components/pi-logo-animation.lazy.js +12 -0
  544. package/dist/modes/interactive/components/pi-logo-animation.lazy.js.map +1 -0
  545. package/dist/modes/interactive/components/pi-logo.d.ts +19 -0
  546. package/dist/modes/interactive/components/pi-logo.d.ts.map +1 -0
  547. package/dist/modes/interactive/components/pi-logo.js +37 -0
  548. package/dist/modes/interactive/components/pi-logo.js.map +1 -0
  549. package/dist/modes/interactive/components/radius-login-selector.d.ts +15 -0
  550. package/dist/modes/interactive/components/radius-login-selector.d.ts.map +1 -0
  551. package/dist/modes/interactive/components/radius-login-selector.js +83 -0
  552. package/dist/modes/interactive/components/radius-login-selector.js.map +1 -0
  553. package/dist/modes/interactive/components/settings-selector.d.ts +6 -4
  554. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  555. package/dist/modes/interactive/components/settings-selector.js +33 -11
  556. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  557. package/dist/modes/interactive/components/status-marker.d.ts +2 -4
  558. package/dist/modes/interactive/components/status-marker.d.ts.map +1 -1
  559. package/dist/modes/interactive/components/status-marker.js +2 -6
  560. package/dist/modes/interactive/components/status-marker.js.map +1 -1
  561. package/dist/modes/interactive/components/themed-text.d.ts +17 -0
  562. package/dist/modes/interactive/components/themed-text.d.ts.map +1 -0
  563. package/dist/modes/interactive/components/themed-text.js +28 -0
  564. package/dist/modes/interactive/components/themed-text.js.map +1 -0
  565. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  566. package/dist/modes/interactive/components/user-message.js +5 -4
  567. package/dist/modes/interactive/components/user-message.js.map +1 -1
  568. package/dist/modes/interactive/components/visual-truncate.d.ts +27 -3
  569. package/dist/modes/interactive/components/visual-truncate.d.ts.map +1 -1
  570. package/dist/modes/interactive/components/visual-truncate.js +36 -6
  571. package/dist/modes/interactive/components/visual-truncate.js.map +1 -1
  572. package/dist/modes/interactive/interactive-mode.d.ts +12 -4
  573. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  574. package/dist/modes/interactive/interactive-mode.js +377 -199
  575. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  576. package/dist/modes/interactive/tasks/completion-render.d.ts +8 -0
  577. package/dist/modes/interactive/tasks/completion-render.d.ts.map +1 -0
  578. package/dist/{extensions/background → modes/interactive/tasks}/completion-render.js +41 -91
  579. package/dist/modes/interactive/tasks/completion-render.js.map +1 -0
  580. package/dist/modes/interactive/tasks/index.d.ts +12 -0
  581. package/dist/modes/interactive/tasks/index.d.ts.map +1 -0
  582. package/dist/modes/interactive/tasks/index.js +102 -0
  583. package/dist/modes/interactive/tasks/index.js.map +1 -0
  584. package/dist/modes/interactive/tasks/inspector.d.ts +35 -0
  585. package/dist/modes/interactive/tasks/inspector.d.ts.map +1 -0
  586. package/dist/modes/interactive/tasks/inspector.js +93 -0
  587. package/dist/modes/interactive/tasks/inspector.js.map +1 -0
  588. package/dist/modes/interactive/tasks/layout.d.ts +40 -0
  589. package/dist/modes/interactive/tasks/layout.d.ts.map +1 -0
  590. package/dist/modes/interactive/tasks/layout.js +212 -0
  591. package/dist/modes/interactive/tasks/layout.js.map +1 -0
  592. package/dist/modes/interactive/tasks/list.d.ts +21 -0
  593. package/dist/modes/interactive/tasks/list.d.ts.map +1 -0
  594. package/dist/modes/interactive/tasks/list.js +96 -0
  595. package/dist/modes/interactive/tasks/list.js.map +1 -0
  596. package/dist/modes/interactive/tasks/manager.d.ts +60 -0
  597. package/dist/modes/interactive/tasks/manager.d.ts.map +1 -0
  598. package/dist/modes/interactive/tasks/manager.js +380 -0
  599. package/dist/modes/interactive/tasks/manager.js.map +1 -0
  600. package/dist/modes/interactive/tasks/model.d.ts +21 -0
  601. package/dist/modes/interactive/tasks/model.d.ts.map +1 -0
  602. package/dist/modes/interactive/tasks/model.js +41 -0
  603. package/dist/modes/interactive/tasks/model.js.map +1 -0
  604. package/dist/modes/interactive/tasks/render.d.ts +28 -0
  605. package/dist/modes/interactive/tasks/render.d.ts.map +1 -0
  606. package/dist/modes/interactive/tasks/render.js +141 -0
  607. package/dist/modes/interactive/tasks/render.js.map +1 -0
  608. package/dist/modes/interactive/tasks/task-view.d.ts +13 -0
  609. package/dist/modes/interactive/tasks/task-view.d.ts.map +1 -0
  610. package/dist/modes/interactive/tasks/task-view.js +20 -0
  611. package/dist/modes/interactive/tasks/task-view.js.map +1 -0
  612. package/dist/modes/interactive/tasks/text.d.ts +6 -0
  613. package/dist/modes/interactive/tasks/text.d.ts.map +1 -0
  614. package/dist/modes/interactive/tasks/text.js +16 -0
  615. package/dist/modes/interactive/tasks/text.js.map +1 -0
  616. package/dist/modes/interactive/tasks/viewport.d.ts +17 -0
  617. package/dist/modes/interactive/tasks/viewport.d.ts.map +1 -0
  618. package/dist/modes/interactive/tasks/viewport.js +59 -0
  619. package/dist/modes/interactive/tasks/viewport.js.map +1 -0
  620. package/dist/modes/interactive/tasks/views.d.ts +9 -0
  621. package/dist/modes/interactive/tasks/views.d.ts.map +1 -0
  622. package/dist/modes/interactive/tasks/views.js +42 -0
  623. package/dist/modes/interactive/tasks/views.js.map +1 -0
  624. package/dist/modes/interactive/theme/dark.json +59 -72
  625. package/dist/modes/interactive/theme/light.json +57 -69
  626. package/dist/modes/interactive/theme/system-theme.d.ts +55 -0
  627. package/dist/modes/interactive/theme/system-theme.d.ts.map +1 -0
  628. package/dist/modes/interactive/theme/system-theme.js +546 -0
  629. package/dist/modes/interactive/theme/system-theme.js.map +1 -0
  630. package/dist/modes/interactive/theme/theme-controller.d.ts +46 -6
  631. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  632. package/dist/modes/interactive/theme/theme-controller.js +125 -47
  633. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  634. package/dist/modes/interactive/theme/theme-json.d.ts +1 -0
  635. package/dist/modes/interactive/theme/theme-json.d.ts.map +1 -1
  636. package/dist/modes/interactive/theme/theme-json.js +3 -1
  637. package/dist/modes/interactive/theme/theme-json.js.map +1 -1
  638. package/dist/modes/interactive/theme/theme-schema.json +7 -2
  639. package/dist/modes/interactive/theme/theme.d.ts +70 -39
  640. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  641. package/dist/modes/interactive/theme/theme.js +247 -313
  642. package/dist/modes/interactive/theme/theme.js.map +1 -1
  643. package/dist/modes/interactive/tool-view/fallback.d.ts +1 -1
  644. package/dist/modes/interactive/tool-view/fallback.d.ts.map +1 -1
  645. package/dist/modes/interactive/tool-view/fallback.js +4 -1
  646. package/dist/modes/interactive/tool-view/fallback.js.map +1 -1
  647. package/dist/modes/interactive/tool-view/tool-execution.js +2 -2
  648. package/dist/modes/interactive/tool-view/tool-execution.js.map +1 -1
  649. package/dist/modes/interactive/tui-renderer.d.ts +2 -1
  650. package/dist/modes/interactive/tui-renderer.d.ts.map +1 -1
  651. package/dist/modes/interactive/tui-renderer.js +1 -0
  652. package/dist/modes/interactive/tui-renderer.js.map +1 -1
  653. package/dist/modes/rpc/rpc-client.d.ts +6 -6
  654. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  655. package/dist/modes/rpc/rpc-client.js +12 -8
  656. package/dist/modes/rpc/rpc-client.js.map +1 -1
  657. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  658. package/dist/modes/rpc/rpc-mode.js +7 -9
  659. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  660. package/dist/modes/rpc/rpc-types.d.ts +10 -1
  661. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  662. package/dist/modes/rpc/rpc-types.js.map +1 -1
  663. package/dist/package-manager-cli.d.ts.map +1 -1
  664. package/dist/package-manager-cli.js +6 -2
  665. package/dist/package-manager-cli.js.map +1 -1
  666. package/dist/utils/clipboard-image.d.ts.map +1 -1
  667. package/dist/utils/clipboard-image.js +14 -17
  668. package/dist/utils/clipboard-image.js.map +1 -1
  669. package/dist/utils/clipboard.d.ts +2 -0
  670. package/dist/utils/clipboard.d.ts.map +1 -1
  671. package/dist/utils/clipboard.js +5 -0
  672. package/dist/utils/clipboard.js.map +1 -1
  673. package/dist/utils/paths.d.ts +3 -3
  674. package/dist/utils/paths.d.ts.map +1 -1
  675. package/dist/utils/paths.js +5 -4
  676. package/dist/utils/paths.js.map +1 -1
  677. package/dist/utils/shell.d.ts +1 -3
  678. package/dist/utils/shell.d.ts.map +1 -1
  679. package/dist/utils/shell.js +3 -30
  680. package/dist/utils/shell.js.map +1 -1
  681. package/docs/bundled/README.md +22 -9
  682. package/docs/bundled/extensions/question.md +2 -2
  683. package/docs/bundled/extensions/statusline.md +26 -17
  684. package/docs/bundled/tasks.md +127 -0
  685. package/docs/bundled/tool-presentation.md +1 -1
  686. package/docs/codemode.md +207 -0
  687. package/docs/custom-provider.md +44 -0
  688. package/docs/docs.json +14 -10
  689. package/docs/environment-variables.md +1 -1
  690. package/docs/extensions.md +94 -93
  691. package/docs/index.md +2 -1
  692. package/docs/keybindings.md +17 -9
  693. package/docs/llama-cpp.md +12 -1
  694. package/docs/mcp.md +248 -0
  695. package/docs/models.md +56 -0
  696. package/docs/packages.md +4 -0
  697. package/docs/providers.md +14 -0
  698. package/docs/rpc.md +5 -3
  699. package/docs/sdk.md +26 -16
  700. package/docs/security.md +4 -0
  701. package/docs/session-format.md +20 -23
  702. package/docs/settings.md +29 -3
  703. package/docs/themes.md +27 -5
  704. package/docs/tui.md +21 -1
  705. package/docs/usage.md +52 -4
  706. package/docs/virtual-models.md +114 -0
  707. package/docs/windows.md +2 -0
  708. package/examples/README.md +2 -2
  709. package/examples/extensions/README.md +3 -2
  710. package/examples/extensions/built-in-tool-renderer.ts +16 -40
  711. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  712. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  713. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  714. package/examples/extensions/custom-provider-gitlab-duo/test.ts +4 -4
  715. package/examples/extensions/debug-provider.ts +90 -0
  716. package/examples/extensions/gondolin/package-lock.json +2 -2
  717. package/examples/extensions/gondolin/package.json +1 -1
  718. package/examples/extensions/jev-router.ts +113 -0
  719. package/examples/extensions/minimal-mode.ts +24 -96
  720. package/examples/extensions/sandbox/package-lock.json +2 -2
  721. package/examples/extensions/sandbox/package.json +1 -1
  722. package/examples/extensions/with-deps/package-lock.json +2 -2
  723. package/examples/extensions/with-deps/package.json +1 -1
  724. package/examples/rpc-client.ts +1 -1
  725. package/examples/rpc-extension-ui.ts +1 -1
  726. package/examples/sdk/14-codemode-mcp.ts +61 -0
  727. package/examples/sdk/README.md +1 -0
  728. package/npm-shrinkwrap.json +420 -423
  729. package/package.json +14 -10
  730. package/dist/bundle/chunks/anthropic-messages-XWFTZP2N.js +0 -6
  731. package/dist/bundle/chunks/azure-openai-responses-HS35BQV6.js +0 -2
  732. package/dist/bundle/chunks/chunk-2IO5GDBS.js +0 -11
  733. package/dist/bundle/chunks/chunk-EDBLK2JQ.js +0 -2
  734. package/dist/bundle/chunks/chunk-I5IVW2WS.js +0 -2
  735. package/dist/bundle/chunks/chunk-IORR2FW4.js +0 -2
  736. package/dist/bundle/chunks/chunk-NUHFSC37.js +0 -25
  737. package/dist/bundle/chunks/chunk-UUSTLCVC.js +0 -2
  738. package/dist/bundle/chunks/google-generative-ai-NOVAJBFC.js +0 -2
  739. package/dist/bundle/chunks/google-vertex-4VHCZJV5.js +0 -2
  740. package/dist/bundle/chunks/mistral-conversations-WC6A2WCJ.js +0 -5
  741. package/dist/bundle/chunks/openai-codex-responses-XCDG75W2.js +0 -10
  742. package/dist/bundle/chunks/openai-completions-SHS3CAEL.js +0 -7
  743. package/dist/bundle/chunks/openai-responses-UT6XFKC7.js +0 -2
  744. package/dist/bundle/chunks/virtual-modules-KUEIEAZN.js +0 -2
  745. package/dist/core/background/history.d.ts +0 -4
  746. package/dist/core/background/history.d.ts.map +0 -1
  747. package/dist/core/background/history.js.map +0 -1
  748. package/dist/core/background/output.d.ts.map +0 -1
  749. package/dist/core/background/output.js.map +0 -1
  750. package/dist/core/background/presentation.d.ts +0 -9
  751. package/dist/core/background/presentation.d.ts.map +0 -1
  752. package/dist/core/background/presentation.js +0 -311
  753. package/dist/core/background/presentation.js.map +0 -1
  754. package/dist/core/background/service.d.ts +0 -68
  755. package/dist/core/background/service.d.ts.map +0 -1
  756. package/dist/core/background/service.js +0 -641
  757. package/dist/core/background/service.js.map +0 -1
  758. package/dist/core/background/session.d.ts +0 -67
  759. package/dist/core/background/session.d.ts.map +0 -1
  760. package/dist/core/background/session.js +0 -248
  761. package/dist/core/background/session.js.map +0 -1
  762. package/dist/core/background/types.d.ts.map +0 -1
  763. package/dist/core/background/types.js +0 -31
  764. package/dist/core/background/types.js.map +0 -1
  765. package/dist/extensions/background/actions.d.ts +0 -11
  766. package/dist/extensions/background/actions.d.ts.map +0 -1
  767. package/dist/extensions/background/actions.js.map +0 -1
  768. package/dist/extensions/background/completion-render.d.ts +0 -8
  769. package/dist/extensions/background/completion-render.d.ts.map +0 -1
  770. package/dist/extensions/background/completion-render.js.map +0 -1
  771. package/dist/extensions/background/constants.d.ts +0 -24
  772. package/dist/extensions/background/constants.d.ts.map +0 -1
  773. package/dist/extensions/background/constants.js +0 -24
  774. package/dist/extensions/background/constants.js.map +0 -1
  775. package/dist/extensions/background/index.d.ts +0 -7
  776. package/dist/extensions/background/index.d.ts.map +0 -1
  777. package/dist/extensions/background/index.js +0 -135
  778. package/dist/extensions/background/index.js.map +0 -1
  779. package/dist/extensions/background/keybindings.d.ts +0 -10
  780. package/dist/extensions/background/keybindings.d.ts.map +0 -1
  781. package/dist/extensions/background/keybindings.js +0 -14
  782. package/dist/extensions/background/keybindings.js.map +0 -1
  783. package/dist/extensions/background/manager.d.ts +0 -80
  784. package/dist/extensions/background/manager.d.ts.map +0 -1
  785. package/dist/extensions/background/manager.js +0 -673
  786. package/dist/extensions/background/manager.js.map +0 -1
  787. package/dist/extensions/background/render.d.ts +0 -42
  788. package/dist/extensions/background/render.d.ts.map +0 -1
  789. package/dist/extensions/background/render.js +0 -225
  790. package/dist/extensions/background/render.js.map +0 -1
  791. package/dist/extensions/background/schema.d.ts.map +0 -1
  792. package/dist/extensions/background/schema.js.map +0 -1
  793. package/dist/extensions/background/task-view.d.ts +0 -53
  794. package/dist/extensions/background/task-view.d.ts.map +0 -1
  795. package/dist/extensions/background/task-view.js +0 -60
  796. package/dist/extensions/background/task-view.js.map +0 -1
  797. package/dist/extensions/background/text.d.ts +0 -12
  798. package/dist/extensions/background/text.d.ts.map +0 -1
  799. package/dist/extensions/background/text.js +0 -39
  800. package/dist/extensions/background/text.js.map +0 -1
  801. package/dist/extensions/background/types.d.ts +0 -85
  802. package/dist/extensions/background/types.d.ts.map +0 -1
  803. package/dist/extensions/background/types.js +0 -17
  804. package/dist/extensions/background/types.js.map +0 -1
  805. package/dist/extensions/subagent/activity.d.ts +0 -34
  806. package/dist/extensions/subagent/activity.d.ts.map +0 -1
  807. package/dist/extensions/subagent/activity.js +0 -192
  808. package/dist/extensions/subagent/activity.js.map +0 -1
  809. package/dist/extensions/subagent/agents-command.d.ts +0 -4
  810. package/dist/extensions/subagent/agents-command.d.ts.map +0 -1
  811. package/dist/extensions/subagent/agents-command.js +0 -230
  812. package/dist/extensions/subagent/agents-command.js.map +0 -1
  813. package/dist/extensions/subagent/agents.d.ts +0 -6
  814. package/dist/extensions/subagent/agents.d.ts.map +0 -1
  815. package/dist/extensions/subagent/agents.js +0 -53
  816. package/dist/extensions/subagent/agents.js.map +0 -1
  817. package/dist/extensions/subagent/budget.d.ts +0 -15
  818. package/dist/extensions/subagent/budget.d.ts.map +0 -1
  819. package/dist/extensions/subagent/budget.js +0 -123
  820. package/dist/extensions/subagent/budget.js.map +0 -1
  821. package/dist/extensions/subagent/cancellation.d.ts +0 -29
  822. package/dist/extensions/subagent/cancellation.d.ts.map +0 -1
  823. package/dist/extensions/subagent/cancellation.js +0 -91
  824. package/dist/extensions/subagent/cancellation.js.map +0 -1
  825. package/dist/extensions/subagent/constants.d.ts +0 -25
  826. package/dist/extensions/subagent/constants.d.ts.map +0 -1
  827. package/dist/extensions/subagent/constants.js +0 -50
  828. package/dist/extensions/subagent/constants.js.map +0 -1
  829. package/dist/extensions/subagent/index.d.ts +0 -3
  830. package/dist/extensions/subagent/index.d.ts.map +0 -1
  831. package/dist/extensions/subagent/index.js +0 -151
  832. package/dist/extensions/subagent/index.js.map +0 -1
  833. package/dist/extensions/subagent/model-selection.d.ts +0 -16
  834. package/dist/extensions/subagent/model-selection.d.ts.map +0 -1
  835. package/dist/extensions/subagent/model-selection.js +0 -51
  836. package/dist/extensions/subagent/model-selection.js.map +0 -1
  837. package/dist/extensions/subagent/render.d.ts +0 -24
  838. package/dist/extensions/subagent/render.d.ts.map +0 -1
  839. package/dist/extensions/subagent/render.js +0 -336
  840. package/dist/extensions/subagent/render.js.map +0 -1
  841. package/dist/extensions/subagent/resolve.d.ts +0 -31
  842. package/dist/extensions/subagent/resolve.d.ts.map +0 -1
  843. package/dist/extensions/subagent/resolve.js +0 -111
  844. package/dist/extensions/subagent/resolve.js.map +0 -1
  845. package/dist/extensions/subagent/runner.d.ts +0 -35
  846. package/dist/extensions/subagent/runner.d.ts.map +0 -1
  847. package/dist/extensions/subagent/runner.js +0 -255
  848. package/dist/extensions/subagent/runner.js.map +0 -1
  849. package/dist/extensions/subagent/schema.d.ts +0 -28
  850. package/dist/extensions/subagent/schema.d.ts.map +0 -1
  851. package/dist/extensions/subagent/schema.js +0 -58
  852. package/dist/extensions/subagent/schema.js.map +0 -1
  853. package/dist/extensions/subagent/sdk-runner.d.ts +0 -33
  854. package/dist/extensions/subagent/sdk-runner.d.ts.map +0 -1
  855. package/dist/extensions/subagent/sdk-runner.js +0 -331
  856. package/dist/extensions/subagent/sdk-runner.js.map +0 -1
  857. package/dist/extensions/subagent/settings.d.ts +0 -8
  858. package/dist/extensions/subagent/settings.d.ts.map +0 -1
  859. package/dist/extensions/subagent/settings.js +0 -206
  860. package/dist/extensions/subagent/settings.js.map +0 -1
  861. package/dist/extensions/subagent/state.d.ts +0 -102
  862. package/dist/extensions/subagent/state.d.ts.map +0 -1
  863. package/dist/extensions/subagent/state.js +0 -383
  864. package/dist/extensions/subagent/state.js.map +0 -1
  865. package/dist/extensions/subagent/text.d.ts +0 -6
  866. package/dist/extensions/subagent/text.d.ts.map +0 -1
  867. package/dist/extensions/subagent/text.js +0 -66
  868. package/dist/extensions/subagent/text.js.map +0 -1
  869. package/dist/extensions/subagent/types.d.ts +0 -91
  870. package/dist/extensions/subagent/types.d.ts.map +0 -1
  871. package/dist/extensions/subagent/types.js +0 -2
  872. package/dist/extensions/subagent/types.js.map +0 -1
  873. package/dist/extensions/subagent/ui/agents-dialog.d.ts +0 -4
  874. package/dist/extensions/subagent/ui/agents-dialog.d.ts.map +0 -1
  875. package/dist/extensions/subagent/ui/agents-dialog.js +0 -84
  876. package/dist/extensions/subagent/ui/agents-dialog.js.map +0 -1
  877. package/dist/extensions/subagent/ui/choice-menu.d.ts +0 -39
  878. package/dist/extensions/subagent/ui/choice-menu.d.ts.map +0 -1
  879. package/dist/extensions/subagent/ui/choice-menu.js +0 -93
  880. package/dist/extensions/subagent/ui/choice-menu.js.map +0 -1
  881. package/dist/extensions/subagent/ui/choices.d.ts +0 -36
  882. package/dist/extensions/subagent/ui/choices.d.ts.map +0 -1
  883. package/dist/extensions/subagent/ui/choices.js +0 -54
  884. package/dist/extensions/subagent/ui/choices.js.map +0 -1
  885. package/dist/extensions/subagent/ui/model-list.d.ts +0 -66
  886. package/dist/extensions/subagent/ui/model-list.d.ts.map +0 -1
  887. package/dist/extensions/subagent/ui/model-list.js +0 -235
  888. package/dist/extensions/subagent/ui/model-list.js.map +0 -1
  889. package/dist/extensions/subagent/ui/model-picker.d.ts +0 -47
  890. package/dist/extensions/subagent/ui/model-picker.d.ts.map +0 -1
  891. package/dist/extensions/subagent/ui/model-picker.js +0 -143
  892. package/dist/extensions/subagent/ui/model-picker.js.map +0 -1
  893. package/dist/extensions/subagent/ui/profile-settings-menu.d.ts +0 -41
  894. package/dist/extensions/subagent/ui/profile-settings-menu.d.ts.map +0 -1
  895. package/dist/extensions/subagent/ui/profile-settings-menu.js +0 -98
  896. package/dist/extensions/subagent/ui/profile-settings-menu.js.map +0 -1
  897. package/dist/extensions/todo/constants.d.ts +0 -16
  898. package/dist/extensions/todo/constants.d.ts.map +0 -1
  899. package/dist/extensions/todo/constants.js +0 -30
  900. package/dist/extensions/todo/constants.js.map +0 -1
  901. package/dist/extensions/todo/index.d.ts +0 -3
  902. package/dist/extensions/todo/index.d.ts.map +0 -1
  903. package/dist/extensions/todo/index.js +0 -98
  904. package/dist/extensions/todo/index.js.map +0 -1
  905. package/dist/extensions/todo/schema.d.ts +0 -60
  906. package/dist/extensions/todo/schema.d.ts.map +0 -1
  907. package/dist/extensions/todo/schema.js +0 -56
  908. package/dist/extensions/todo/schema.js.map +0 -1
  909. package/dist/extensions/todo/state.d.ts +0 -34
  910. package/dist/extensions/todo/state.d.ts.map +0 -1
  911. package/dist/extensions/todo/state.js +0 -425
  912. package/dist/extensions/todo/state.js.map +0 -1
  913. package/dist/extensions/todo/view.d.ts +0 -36
  914. package/dist/extensions/todo/view.d.ts.map +0 -1
  915. package/dist/extensions/todo/view.js +0 -580
  916. package/dist/extensions/todo/view.js.map +0 -1
  917. package/dist/extensions/todo/widget.d.ts +0 -15
  918. package/dist/extensions/todo/widget.d.ts.map +0 -1
  919. package/dist/extensions/todo/widget.js +0 -50
  920. package/dist/extensions/todo/widget.js.map +0 -1
  921. package/docs/bundled/extensions/background.md +0 -132
  922. package/docs/bundled/extensions/subagent.md +0 -148
  923. package/docs/bundled/extensions/todo.md +0 -104
  924. package/examples/extensions/todo.ts +0 -297
@@ -1,3 +1,4 @@
1
+ import { createTasksToolDefinition } from "./tools/tasks.js";
1
2
  /**
2
3
  * AgentSession - Core abstraction for agent lifecycle and session management.
3
4
  *
@@ -14,6 +15,7 @@
14
15
  */
15
16
  import { readFileSync } from "node:fs";
16
17
  import { basename, dirname } from "node:path";
18
+ import { runToolCall, } from "@earendil-works/pi-agent-core";
17
19
  import { contentText, getCurrentSystemMessage, getSystemMessageText, retryDelayMs } from "@earendil-works/pi-ai";
18
20
  import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
19
21
  import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
@@ -22,7 +24,6 @@ import { processImage } from "../utils/image-process.js";
22
24
  import { sleep } from "../utils/sleep.js";
23
25
  import { normalizeToolResultImages } from "../utils/tool-result-images.js";
24
26
  import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
25
- import { BackgroundSession } from "./background/session.js";
26
27
  import { executeBashWithOperations } from "./bash-executor.js";
27
28
  import { generateBugReportSummary } from "./bug-report.js";
28
29
  import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateProjectedContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
@@ -33,15 +34,19 @@ import { ExtensionRunner, wrapRegisteredTools, } from "./extensions/index.js";
33
34
  import { emitSessionShutdownEvent } from "./extensions/runner.js";
34
35
  import { convertToLlm } from "./messages.js";
35
36
  import { ModelRegistry } from "./model-registry.js";
37
+ import { NestedToolCallRunner } from "./nested-tool-calls.js";
36
38
  import { expandPromptTemplate } from "./prompt-templates.js";
37
39
  import { exportSessionToJsonl } from "./session-export.js";
38
40
  import { getLatestCompactionEntry, SessionManager, } from "./session-manager.js";
39
- import { createSyntheticSourceInfo } from "./source-info.js";
41
+ import { DEFAULT_TOOL_NAMES } from "./settings-manager.js";
42
+ import { BUILTIN_PATH_PREFIX, createSyntheticSourceInfo, isSyntheticPath } from "./source-info.js";
40
43
  import { buildSystemPrompt, buildSystemPromptSections, diffSystemPromptSections, normalizeBuildSystemPromptOptions, } from "./system-prompt.js";
44
+ import { TaskSession } from "./tasks/session.js";
41
45
  import { createLocalBashOperations } from "./tools/bash.js";
42
46
  import { createAllToolDefinitions } from "./tools/index.js";
43
47
  import { createToolDefinitionFromAgentTool } from "./tools/tool-definition-wrapper.js";
44
- import { addUsageToTotals, createUsageTotals, getAccountedUsages } from "./usage-totals.js";
48
+ import { addUsageToTotals, combineUsage, createUsageTotals, getAccountedUsages } from "./usage-totals.js";
49
+ import { findLatestResponse, getBranchSelection, getVirtualModelState, isVirtualModel, VIRTUAL_MODEL_STATE_ENTRY, } from "./virtual-models.js";
45
50
  /**
46
51
  * Parse a skill block from message text.
47
52
  * Returns null if the text doesn't contain a skill block.
@@ -110,16 +115,39 @@ export class AgentSession {
110
115
  this._isEmittingAgentSettled = false;
111
116
  this._deferredSettledActions = [];
112
117
  this._baseToolDefinitions = new Map();
118
+ /**
119
+ * Tools of the restored or reloaded loadout that are not registered yet, such as tools of MCP
120
+ * servers that are still connecting. They are activated when they are registered, and dropped when
121
+ * `setActiveToolsByName()` deactivates a tool or the next agent run starts.
122
+ */
123
+ this._pendingToolNames = new Set();
113
124
  this._extensionMode = "print";
114
125
  // Tool registry for extension getTools/setTools
115
126
  this._toolRegistry = new Map();
127
+ /** Declared tools whose declarations requests leave out, from `prepareLoadout` hooks. */
128
+ this._hiddenDeclarations = new Set();
116
129
  this._toolDefinitions = new Map();
117
130
  this._toolPromptSnippets = new Map();
118
131
  this._toolPromptGuidelines = new Map();
119
132
  /** Internal handler for agent events - shared by subscribe and reconnect */
120
133
  this._handleAgentEvent = async (event) => {
121
134
  if (event.type === "message_start")
122
- this._backgroundHost.messageStarted(event.message);
135
+ this._tasksHost.delivery.messageStarted(event.message);
136
+ // Record the calls a tool made through ctx.executeTool() and their usage on its result message.
137
+ if (this._nestedToolCalls) {
138
+ if (event.type === "message_start" && event.message.role === "toolResult") {
139
+ const message = event.message;
140
+ const summary = this._nestedToolCalls.takeRecord(message.toolCallId);
141
+ if (summary?.calls)
142
+ message.nestedCalls = summary.calls;
143
+ if (summary?.usage) {
144
+ message.usage = message.usage ? combineUsage(message.usage, summary.usage) : summary.usage;
145
+ }
146
+ }
147
+ else if (event.type === "agent_end") {
148
+ this._nestedToolCalls.clear();
149
+ }
150
+ }
123
151
  // When a user message starts, check if it's from either queue and remove it BEFORE emitting
124
152
  // This ensures the UI sees the updated queue state
125
153
  if (event.type === "message_start" && event.message.role === "user") {
@@ -193,14 +221,14 @@ export class AgentSession {
193
221
  this._flushPendingCustomMessages();
194
222
  }
195
223
  if (event.type === "agent_end")
196
- this._backgroundHost.agentEnded();
224
+ this._tasksHost.delivery.agentEnded();
197
225
  };
198
226
  this.agent = config.agent;
199
227
  this.sessionManager = config.sessionManager;
200
228
  this.settingsManager = config.settingsManager;
201
- this._backgroundHost = new BackgroundSession({
229
+ this._tasksHost = new TaskSession({
202
230
  manager: this.sessionManager,
203
- role: config.executionRole ?? "main",
231
+ backgroundAllowed: config.backgroundAllowed,
204
232
  canDeliver: () => {
205
233
  if (this.model === undefined || this.isCompacting)
206
234
  return false;
@@ -232,6 +260,7 @@ export class AgentSession {
232
260
  }
233
261
  this._extensionRunnerRef = config.extensionRunnerRef;
234
262
  this._initialActiveToolNames = config.initialActiveToolNames;
263
+ this._usesDefaultTools = config.usesDefaultTools ?? false;
235
264
  this._allowedToolNames = config.allowedToolNames ? new Set(config.allowedToolNames) : undefined;
236
265
  this._excludedToolNames = config.excludedToolNames ? new Set(config.excludedToolNames) : undefined;
237
266
  this._baseToolsOverride = config.baseToolsOverride;
@@ -243,6 +272,7 @@ export class AgentSession {
243
272
  this._installAgentNextTurnRefresh();
244
273
  this._installAgentRequestProjection();
245
274
  this._installAgentBoundaryHooks();
275
+ this._installHiddenDeclarationsProjection();
246
276
  this._installAgentForcedPromptProjection();
247
277
  this._buildRuntime({
248
278
  activeToolNames: this._initialActiveToolNames,
@@ -251,26 +281,26 @@ export class AgentSession {
251
281
  if (this._initialActiveToolNames === undefined)
252
282
  this._restoreToolsFromTranscript();
253
283
  }
254
- get background() {
255
- return this._backgroundHost.service;
284
+ get tasks() {
285
+ return this._tasksHost.service;
256
286
  }
257
- get quarantinedBackgroundSettlements() {
258
- return this._backgroundHost.quarantinedSettlements;
287
+ get quarantinedTaskSettlements() {
288
+ return this._tasksHost.quarantinedSettlements;
259
289
  }
260
290
  /** Pause delivery across asynchronous lifecycle/preflight gaps. Nestable. */
261
- pauseBackgroundNotifications() {
262
- return this._backgroundHost.pause();
291
+ pauseTaskNotifications() {
292
+ return this._tasksHost.delivery.pause();
263
293
  }
264
294
  /** Explicit retry after a host delivery failure; never spins on a timer by itself. */
265
- retryBackgroundNotifications() {
266
- this._backgroundHost.retry();
295
+ retryTaskNotifications() {
296
+ this._tasksHost.delivery.retry();
267
297
  }
268
298
  /**
269
299
  * Run a lifecycle operation with delivery paused across its asynchronous gaps.
270
300
  * Lifecycle methods are thin shells over upstream bodies so those keep upstream's shape.
271
301
  */
272
- async _withBackgroundPaused(operation) {
273
- const resumeBackground = this.pauseBackgroundNotifications();
302
+ async _withTasksPaused(operation) {
303
+ const resumeBackground = this.pauseTaskNotifications();
274
304
  try {
275
305
  return await operation();
276
306
  }
@@ -354,28 +384,71 @@ export class AgentSession {
354
384
  }
355
385
  throw new Error(formatNoApiKeyFoundMessage(model.provider));
356
386
  }
357
- async _getSummarizationRequestAuth(model, signal) {
387
+ async _getSummarizationRequestAuth(selectedModel, signal) {
388
+ // Route a virtual model first: summaries size their input and output from the model they get.
389
+ const { model, thinkingLevel } = isVirtualModel(selectedModel)
390
+ ? await this._modelRuntime.resolveModel(selectedModel, convertToLlm(this.messages), {
391
+ reason: "direct",
392
+ thinkingLevel: this.thinkingLevel,
393
+ signal,
394
+ })
395
+ : { model: selectedModel, thinkingLevel: this.thinkingLevel };
358
396
  if (this.agent.streamFunction === streamSimple) {
359
- return this._getRequiredRequestAuth(model, signal);
397
+ return { ...(await this._getRequiredRequestAuth(model, signal)), thinkingLevel };
360
398
  }
361
399
  try {
362
400
  const result = await this._modelRuntime.getAuth(model, { signal });
363
401
  if (!result)
364
- return { model };
402
+ return { model, thinkingLevel };
365
403
  const requestModel = result.auth.baseUrl ? { ...model, baseUrl: result.auth.baseUrl } : model;
366
404
  return {
367
405
  model: requestModel,
368
406
  apiKey: result.auth.apiKey,
369
407
  headers: withoutDeletedHeaders(result.auth.headers),
370
408
  env: result.env,
409
+ thinkingLevel,
371
410
  };
372
411
  }
373
412
  catch (error) {
374
413
  if (signal?.aborted)
375
414
  throw error;
376
- return { model };
415
+ return { model, thinkingLevel };
377
416
  }
378
417
  }
418
+ /**
419
+ * The model whose limits apply to `message`, or undefined when the message came from another
420
+ * model. Under a virtual selection, that is the physical model that produced it.
421
+ */
422
+ _modelForMessage(message) {
423
+ const model = this.model;
424
+ if (model && isVirtualModel(model))
425
+ return this._modelRuntime.getPhysicalModel(message.provider, message.model);
426
+ return model?.provider === message.provider && model.id === message.model ? model : undefined;
427
+ }
428
+ /**
429
+ * Record the selection on the current branch when the branch implies another one, so a resume
430
+ * restores it. Tree navigation can leave the latest `model_change` on another branch; responses
431
+ * cannot record a virtual selection because they name physical models. Responses do record a
432
+ * physical selection unless the branch holds a virtual one; checking a physical selection against
433
+ * responses would record it on every prompt while `prepareRequest` redirects to another model.
434
+ */
435
+ _recordSelection() {
436
+ const model = this.model;
437
+ if (!model)
438
+ return;
439
+ const getModel = (provider, modelId) => this._modelRuntime.getModel(provider, modelId);
440
+ const recorded = getBranchSelection(this.sessionManager.getBranch(), getModel);
441
+ if (!recorded || (recorded.provider === model.provider && recorded.modelId === model.id))
442
+ return;
443
+ const recordedModel = getModel(recorded.provider, recorded.modelId);
444
+ if (!isVirtualModel(model) && !(recordedModel && isVirtualModel(recordedModel)))
445
+ return;
446
+ this.sessionManager.appendModelChange(model.provider, model.id);
447
+ }
448
+ /** The model whose limits apply to the conversation. */
449
+ _limitsModel() {
450
+ return this.routedModel?.model ?? this.model;
451
+ }
379
452
  /**
380
453
  * Install tool hooks once on the Agent instance.
381
454
  *
@@ -385,65 +458,112 @@ export class AgentSession {
385
458
  * happens here instead of in wrappers.
386
459
  */
387
460
  _installAgentToolHooks() {
388
- this.agent.beforeToolCall = async ({ toolCall, args }) => {
389
- const runner = this._extensionRunner;
390
- if (!runner.hasHandlers("tool_call")) {
391
- return undefined;
392
- }
393
- try {
394
- return await runner.emitToolCall({
395
- type: "tool_call",
396
- toolName: toolCall.name,
397
- toolCallId: toolCall.id,
398
- input: args,
399
- });
400
- }
401
- catch (err) {
402
- if (err instanceof Error) {
403
- throw err;
404
- }
405
- throw new Error(`Extension failed, blocking execution: ${String(err)}`);
406
- }
407
- };
408
- this.agent.afterToolCall = async ({ toolCall, args, result, isError }) => {
409
- const runner = this._extensionRunner;
410
- const hookResult = runner.hasHandlers("tool_result")
411
- ? await runner.emitToolResult({
412
- type: "tool_result",
413
- toolName: toolCall.name,
414
- toolCallId: toolCall.id,
415
- input: args,
416
- content: result.content,
417
- details: result.details,
418
- isError,
419
- usage: result.usage,
420
- })
421
- : undefined;
422
- const content = hookResult?.content ?? result.content ?? [];
423
- // Runs after the extension hook so images injected or replaced by extensions are normalized too.
424
- const resizeOptions = this.model?.inputLimits?.images?.resize;
425
- const normalizedContent = await normalizeToolResultImages(content, {
426
- autoResizeImages: this.settingsManager.getImageAutoResize(),
427
- ...(resizeOptions ? { resizeOptions } : {}),
461
+ this.agent.beforeToolCall = (context) => this._beforeToolCall(context);
462
+ this.agent.afterToolCall = (context) => this._afterToolCall(context);
463
+ }
464
+ /** `tool_call` handlers. `parentToolCallId` is set for calls another tool made. */
465
+ async _beforeToolCall({ toolCall, args }, parentToolCallId) {
466
+ const runner = this._extensionRunner;
467
+ if (!runner.hasHandlers("tool_call")) {
468
+ return undefined;
469
+ }
470
+ try {
471
+ return await runner.emitToolCall({
472
+ type: "tool_call",
473
+ toolName: toolCall.name,
474
+ toolCallId: toolCall.id,
475
+ ...(parentToolCallId ? { parentToolCallId } : {}),
476
+ input: args,
428
477
  });
429
- if (!hookResult && normalizedContent === content) {
430
- return undefined;
478
+ }
479
+ catch (err) {
480
+ if (err instanceof Error) {
481
+ throw err;
431
482
  }
432
- return {
433
- content: normalizedContent,
434
- details: hookResult?.details,
435
- isError: hookResult?.isError ?? isError,
436
- usage: hookResult?.usage,
437
- };
483
+ throw new Error(`Extension failed, blocking execution: ${String(err)}`);
484
+ }
485
+ }
486
+ /** `tool_result` handlers and image normalization. `parentToolCallId` is set for calls another tool made. */
487
+ async _afterToolCall({ toolCall, args, result, isError }, parentToolCallId) {
488
+ const runner = this._extensionRunner;
489
+ const hookResult = runner.hasHandlers("tool_result")
490
+ ? await runner.emitToolResult({
491
+ type: "tool_result",
492
+ toolName: toolCall.name,
493
+ toolCallId: toolCall.id,
494
+ ...(parentToolCallId ? { parentToolCallId } : {}),
495
+ input: args,
496
+ content: result.content,
497
+ details: result.details,
498
+ ...(result.structuredContent === undefined ? {} : { structuredContent: result.structuredContent }),
499
+ isError,
500
+ usage: result.usage,
501
+ })
502
+ : undefined;
503
+ const content = hookResult?.content ?? result.content ?? [];
504
+ // Runs after the extension hook so images injected or replaced by extensions are normalized too.
505
+ const resizeOptions = this._limitsModel()?.inputLimits?.images?.resize;
506
+ const normalizedContent = await normalizeToolResultImages(content, {
507
+ autoResizeImages: this.settingsManager.getImageAutoResize(),
508
+ ...(resizeOptions ? { resizeOptions } : {}),
509
+ });
510
+ if (!hookResult && normalizedContent === content) {
511
+ return undefined;
512
+ }
513
+ // The hook result already dropped structured content that replaced content no longer matches.
514
+ return {
515
+ content: normalizedContent,
516
+ details: hookResult?.details,
517
+ structuredContent: hookResult ? hookResult.structuredContent : result.structuredContent,
518
+ isError: hookResult?.isError ?? isError,
519
+ usage: hookResult?.usage,
438
520
  };
439
521
  }
522
+ /**
523
+ * Run a call that the tool call `parentToolCallId` made through `ctx.executeTool()`. It goes
524
+ * through the agent's tool pipeline with the session's hooks, against the callable tools.
525
+ */
526
+ async _executeNestedToolCall(parentToolCallId, name, args, options) {
527
+ this._nestedToolCalls ??= new NestedToolCallRunner({
528
+ getTools: () => this._getCallableTools(),
529
+ isSequential: () => this.agent.toolExecution === "sequential",
530
+ runToolCall: (toolCall, parentId, signal, onUpdate) => {
531
+ const assistantMessage = this._findLastAssistantMessage();
532
+ if (!assistantMessage) {
533
+ return Promise.resolve({
534
+ toolCall,
535
+ result: { content: [{ type: "text", text: "No assistant message issued this call" }], details: {} },
536
+ isError: true,
537
+ });
538
+ }
539
+ return runToolCall(toolCall, {
540
+ tools: this._getCallableTools(),
541
+ assistantMessage,
542
+ context: { messages: this.agent.state.messages, tools: this.agent.state.tools },
543
+ beforeToolCall: (context) => this._beforeToolCall(context, parentId),
544
+ afterToolCall: (context) => this._afterToolCall(context, parentId),
545
+ signal,
546
+ onUpdate,
547
+ });
548
+ },
549
+ emit: async (event) => {
550
+ await this._extensionRunner.emit(event);
551
+ this._emit(event);
552
+ },
553
+ });
554
+ return this._nestedToolCalls.execute(parentToolCallId, name, args, options);
555
+ }
556
+ /** Whether `projection`, the current session projection, exceeds the compaction threshold of `model`. */
557
+ _exceedsCompactionThreshold(model, projection) {
558
+ if (model.contextWindow <= 0)
559
+ return false;
560
+ return shouldCompact(estimateProjectedContextTokens(projection, this.sessionManager.getBranch()).tokens, model.contextWindow, this.settingsManager.getCompactionSettings(model));
561
+ }
440
562
  async _compactBeforeNextAssistantResponse(context) {
441
- const model = this.model;
442
- const settings = this.settingsManager.getCompactionSettings(model);
443
563
  const projection = this.sessionManager.buildSessionProjection();
444
- if (!model ||
445
- model.contextWindow <= 0 ||
446
- !shouldCompact(estimateProjectedContextTokens(projection, this.sessionManager.getBranch()).tokens, model.contextWindow, settings)) {
564
+ // A virtual selection is checked in prepareRequest, against the model the request is routed to.
565
+ const model = this.model;
566
+ if (!model || isVirtualModel(model) || !this._exceedsCompactionThreshold(model, projection)) {
447
567
  return { ...context, messages: projection.messages };
448
568
  }
449
569
  await this._runAutoCompaction("threshold", false);
@@ -452,24 +572,55 @@ export class AgentSession {
452
572
  _installAgentRequestProjection() {
453
573
  const previousPrepareRequest = this.agent.prepareRequest;
454
574
  this.agent.prepareRequest = async (request, signal) => {
455
- const canonicalContext = {
456
- ...request.context,
457
- messages: this.sessionManager.buildSessionProjection().messages,
458
- // Messages declare the provider-visible loadout; context.tools keeps executable implementations.
459
- tools: this.agent.state.tools.slice(),
460
- };
461
- const previous = await previousPrepareRequest?.({
462
- ...request,
463
- context: canonicalContext,
464
- model: this.agent.state.model,
465
- thinkingLevel: this.agent.state.thinkingLevel,
466
- }, signal);
467
- return {
468
- ...previous,
469
- context: previous?.context ?? canonicalContext,
470
- model: previous?.model ?? this.agent.state.model,
471
- thinkingLevel: previous?.thinkingLevel ?? this.agent.state.thinkingLevel,
575
+ const failed = this._failedResponse;
576
+ this._failedResponse = undefined;
577
+ const prepare = async () => {
578
+ const projection = this.sessionManager.buildSessionProjection();
579
+ const canonicalContext = {
580
+ ...request.context,
581
+ messages: projection.messages,
582
+ // Messages declare the provider-visible loadout; context.tools keeps executable implementations.
583
+ tools: this.agent.state.tools.slice(),
584
+ };
585
+ const previous = await previousPrepareRequest?.({
586
+ ...request,
587
+ context: canonicalContext,
588
+ model: this.agent.state.model,
589
+ thinkingLevel: this.agent.state.thinkingLevel,
590
+ }, signal);
591
+ return { previous, context: previous?.context ?? canonicalContext, projection };
472
592
  };
593
+ let { previous, context, projection } = await prepare();
594
+ const model = previous?.model ?? this.agent.state.model;
595
+ const thinkingLevel = previous?.thinkingLevel ?? this.agent.state.thinkingLevel;
596
+ if (!isVirtualModel(model))
597
+ return { ...previous, context, model, thinkingLevel };
598
+ // The selection stays in agent state; only this request uses the routed model. A routing
599
+ // failure rejects, which ends the run with an error response. Only messages the user wrote
600
+ // start a turn; extension messages can follow them, e.g. from before_agent_start.
601
+ const lastResponse = context.messages.findLastIndex((message) => message.role === "assistant");
602
+ const userTurn = context.messages.slice(lastResponse + 1).some((message) => message.role === "user");
603
+ const state = getVirtualModelState(this.sessionManager.getBranch(), model.provider, model.id);
604
+ const route = await this._modelRuntime.resolveModel(model, convertToLlm(context.messages), {
605
+ reason: failed ? "retry" : userTurn ? "user" : "continuation",
606
+ thinkingLevel,
607
+ signal,
608
+ failed,
609
+ state,
610
+ });
611
+ if (route.state !== undefined && route.state !== state) {
612
+ const data = { provider: model.provider, modelId: model.id, state: route.state };
613
+ const entry = this.sessionManager.getEntry(this.sessionManager.appendCustomEntry(VIRTUAL_MODEL_STATE_ENTRY, data));
614
+ if (entry)
615
+ this._emit({ type: "entry_appended", entry });
616
+ }
617
+ // The route stands: the router already decided this request. The state entry does not change
618
+ // the projection.
619
+ if (this._exceedsCompactionThreshold(route.model, projection)) {
620
+ await this._runAutoCompaction("threshold", false);
621
+ ({ previous, context } = await prepare());
622
+ }
623
+ return { ...previous, context, model: route.model, thinkingLevel: route.thinkingLevel };
473
624
  };
474
625
  }
475
626
  async _dispatchTurnEndBoundary(message, toolResults) {
@@ -525,10 +676,7 @@ export class AgentSession {
525
676
  ? async (_turn, signal) => await this.agent.prepareNextTurn?.(signal)
526
677
  : undefined);
527
678
  this.agent.prepareNextTurnWithContext = async (turn, signal) => {
528
- const context = await this._compactBeforeNextAssistantResponse({
529
- ...turn.context,
530
- messages: this.sessionManager.buildSessionProjection().messages,
531
- });
679
+ const context = await this._compactBeforeNextAssistantResponse(turn.context);
532
680
  const previousSnapshot = await previousPrepareNextTurnWithContext?.({ ...turn, context }, signal);
533
681
  const nextContext = previousSnapshot?.context ?? context;
534
682
  const runOptions = this._runSystemPromptOptions ?? this._baseSystemPromptOptions;
@@ -676,7 +824,7 @@ export class AgentSession {
676
824
  * so a deferred prompt never races a delivery for the same idle gap.
677
825
  */
678
826
  async _emitAgentSettled() {
679
- return this._withBackgroundPaused(() => this._emitAgentSettledBody());
827
+ return this._withTasksPaused(() => this._emitAgentSettledBody());
680
828
  }
681
829
  async _emitAgentSettledBody() {
682
830
  this._cacheWarmer?.onAgentSettled();
@@ -712,7 +860,7 @@ export class AgentSession {
712
860
  if (pendingIndex !== -1)
713
861
  this._pendingNextTurnMessages.splice(pendingIndex, 1);
714
862
  }
715
- this._backgroundHost.messagePersisted(message);
863
+ this._tasksHost.delivery.messagePersisted(message);
716
864
  }
717
865
  _willRetryAfterAgentEnd(event) {
718
866
  if (this._agentRunAbortRequested)
@@ -909,7 +1057,7 @@ export class AgentSession {
909
1057
  * Call this when completely done with the session.
910
1058
  */
911
1059
  dispose() {
912
- this._backgroundHost.dispose();
1060
+ this._tasksHost.dispose();
913
1061
  try {
914
1062
  this.abortRetry();
915
1063
  this.abortCompaction();
@@ -957,6 +1105,14 @@ export class AgentSession {
957
1105
  get thinkingLevel() {
958
1106
  return this.agent.state.thinkingLevel;
959
1107
  }
1108
+ /** Under a virtual selection, the physical model and thinking level of the latest successful response. */
1109
+ get routedModel() {
1110
+ if (!this.model || !isVirtualModel(this.model))
1111
+ return undefined;
1112
+ const latest = findLatestResponse(this.agent.state.messages);
1113
+ const model = latest && this._modelRuntime.getPhysicalModel(latest.provider, latest.model);
1114
+ return model && { model, thinkingLevel: latest?.thinkingLevel };
1115
+ }
960
1116
  /** Whether the session is currently processing an agent run or post-run continuation. */
961
1117
  get isStreaming() {
962
1118
  return this._isAgentRunActive;
@@ -974,12 +1130,16 @@ export class AgentSession {
974
1130
  return this._retryAttempt;
975
1131
  }
976
1132
  /**
977
- * Get the names of currently active tools.
978
- * Returns the names of tools currently set on the agent.
1133
+ * Get the names of currently active tools, which are the tools declared to the model.
1134
+ * Tools with `codemode` or `deferred` exposure are callable from other tools without being active.
979
1135
  */
980
1136
  getActiveToolNames() {
981
1137
  return this.agent.state.tools.map((t) => t.name);
982
1138
  }
1139
+ /** Get the names of the tools that tools can call through `ctx.executeTool()`. */
1140
+ getCallableToolNames() {
1141
+ return this._getCallableTools().map((t) => t.name);
1142
+ }
983
1143
  /**
984
1144
  * Get all configured tools with name, description, parameter schema, prompt guidelines, and source metadata.
985
1145
  */
@@ -989,6 +1149,9 @@ export class AgentSession {
989
1149
  description: definition.description,
990
1150
  parameters: definition.parameters,
991
1151
  promptGuidelines: definition.promptGuidelines,
1152
+ exposure: this._getToolExposure(definition.name),
1153
+ ...(definition.namespace ? { namespace: definition.namespace } : {}),
1154
+ ...(definition.annotations ? { annotations: { ...definition.annotations } } : {}),
992
1155
  sourceInfo,
993
1156
  }));
994
1157
  }
@@ -997,22 +1160,93 @@ export class AgentSession {
997
1160
  }
998
1161
  /**
999
1162
  * Set active tools by name.
1000
- * Only tools in the registry can be enabled. Unknown tool names are ignored.
1163
+ * Only tools in the registry can be enabled. Unknown and hidden tool names are ignored.
1001
1164
  * Also rebuilds the system prompt to reflect the new tool set.
1002
1165
  * Changes take effect on the next agent turn.
1003
1166
  */
1004
1167
  setActiveToolsByName(toolNames) {
1005
- const tools = [];
1006
- const validToolNames = [];
1007
- for (const name of toolNames) {
1168
+ const previous = this.getActiveToolNames();
1169
+ this._setActiveTools(toolNames);
1170
+ // A loadout that deactivates a tool replaces the restored one, whose pending tools are dropped.
1171
+ // One that only adds tools, like activating tool_search, keeps them.
1172
+ const active = new Set(this.getActiveToolNames());
1173
+ if (previous.some((name) => !active.has(name)))
1174
+ this._pendingToolNames.clear();
1175
+ }
1176
+ _setActiveTools(toolNames) {
1177
+ const tools = this._applyToolLoadout(toolNames);
1178
+ for (const tool of tools)
1179
+ this._pendingToolNames.delete(tool.name);
1180
+ this._rebuildSystemPrompt(tools.map((tool) => tool.name));
1181
+ }
1182
+ _isAllowedTool(name) {
1183
+ return (!this._allowedToolNames || this._allowedToolNames.has(name)) && !this._excludedToolNames?.has(name);
1184
+ }
1185
+ _getToolExposure(name) {
1186
+ return this._toolDefinitions.get(name)?.definition.exposure ?? "direct";
1187
+ }
1188
+ /**
1189
+ * Tools callable through `ctx.executeTool()`: the active `direct` tools and every registered
1190
+ * `codemode` or `deferred` tool.
1191
+ */
1192
+ _getCallableTools(active = new Set(this.getActiveToolNames())) {
1193
+ return [...this._toolRegistry.values()].filter((tool) => {
1194
+ const exposure = this._getToolExposure(tool.name);
1195
+ return exposure === "codemode" || exposure === "deferred" || (exposure === "direct" && active.has(tool.name));
1196
+ });
1197
+ }
1198
+ /**
1199
+ * Set the agent's tools for the given active tool names and return them. The active tools are
1200
+ * the registered, non-hidden ones; they are declared to the model. Active tools with a
1201
+ * `prepareLoadout` hook can change the declared descriptions and hide declarations from
1202
+ * requests (see {@link _installHiddenDeclarationsProjection}).
1203
+ */
1204
+ _applyToolLoadout(toolNames) {
1205
+ const tools = [...new Set(toolNames)].flatMap((name) => {
1008
1206
  const tool = this._toolRegistry.get(name);
1009
- if (tool) {
1010
- tools.push(tool);
1011
- validToolNames.push(name);
1207
+ return tool && this._getToolExposure(name) !== "hidden" ? [tool] : [];
1208
+ });
1209
+ const hooks = tools.flatMap((tool) => {
1210
+ const entry = this._toolDefinitions.get(tool.name);
1211
+ return entry?.definition.prepareLoadout ? [entry] : [];
1212
+ });
1213
+ const hidden = new Set();
1214
+ let declared = tools;
1215
+ if (hooks.length > 0) {
1216
+ const loadout = {
1217
+ declared: tools,
1218
+ callable: this._getCallableTools(new Set(tools.map((tool) => tool.name))),
1219
+ registered: [...this._toolRegistry.values()],
1220
+ getExposure: (name) => this._getToolExposure(name),
1221
+ getNamespace: (name) => this._toolDefinitions.get(name)?.definition.namespace,
1222
+ };
1223
+ const descriptions = new Map();
1224
+ for (const { definition, sourceInfo } of hooks) {
1225
+ try {
1226
+ const changes = definition.prepareLoadout?.(loadout);
1227
+ for (const [name, description] of Object.entries(changes?.descriptions ?? {})) {
1228
+ descriptions.set(name, description);
1229
+ }
1230
+ for (const name of changes?.hiddenDeclarations ?? [])
1231
+ hidden.add(name);
1232
+ }
1233
+ catch (error) {
1234
+ this._extensionRunner.emitError({
1235
+ extensionPath: sourceInfo.path,
1236
+ event: "prepare_loadout",
1237
+ error: error instanceof Error ? error.message : String(error),
1238
+ stack: error instanceof Error ? error.stack : undefined,
1239
+ });
1240
+ }
1012
1241
  }
1242
+ declared = tools.map((tool) => {
1243
+ const description = descriptions.get(tool.name);
1244
+ return description === undefined ? tool : { ...tool, description };
1245
+ });
1013
1246
  }
1014
- this.agent.state.tools = tools;
1015
- this._rebuildSystemPrompt(validToolNames);
1247
+ this._hiddenDeclarations = hidden;
1248
+ this.agent.state.tools = declared;
1249
+ return declared;
1016
1250
  }
1017
1251
  /** Whether compaction or branch summarization is currently running */
1018
1252
  get isCompacting() {
@@ -1083,7 +1317,8 @@ export class AgentSession {
1083
1317
  const toolSnippets = {};
1084
1318
  for (const name of this._toolRegistry.keys()) {
1085
1319
  const snippet = this._toolPromptSnippets.get(name);
1086
- if (snippet)
1320
+ // Tools without a snippet are not listed. Hidden tools are only callable through another tool.
1321
+ if (snippet && !this._hiddenDeclarations.has(name))
1087
1322
  toolSnippets[name] = snippet;
1088
1323
  }
1089
1324
  const loaderSystemPrompt = this._resourceLoader.getSystemPrompt();
@@ -1113,11 +1348,9 @@ export class AgentSession {
1113
1348
  * {@link _installAgentForcedPromptProjection}.
1114
1349
  */
1115
1350
  _preparePromptAndToolLoadout(options, messages = this.agent.state.messages) {
1116
- options.selectedTools = [...new Set(options.selectedTools)].filter((name) => this._toolRegistry.has(name));
1117
- this.agent.state.tools = options.selectedTools.flatMap((name) => {
1118
- const tool = this._toolRegistry.get(name);
1119
- return tool ? [tool] : [];
1120
- });
1351
+ options.selectedTools = this._applyToolLoadout(options.selectedTools).map((tool) => tool.name);
1352
+ // The tool list must match the declarations the request carries, so hidden tools are not listed.
1353
+ options.toolSnippets = Object.fromEntries(Object.entries(options.toolSnippets).filter(([name]) => !this._hiddenDeclarations.has(name)));
1121
1354
  const sections = diffSystemPromptSections(getCurrentSystemMessage(messages)?.sections ?? {}, buildSystemPromptSections(options));
1122
1355
  return sections ? { role: "system", content: "", sections, timestamp: Date.now() } : undefined;
1123
1356
  }
@@ -1131,6 +1364,32 @@ export class AgentSession {
1131
1364
  * collapse into one head holding the forced text and the current tools. Runs after the
1132
1365
  * `context` extension handlers.
1133
1366
  */
1367
+ /**
1368
+ * Remove the declarations that `prepareLoadout` hooks hide from every request. The whole
1369
+ * transcript is filtered with the current set, so the projected declarations stay consistent
1370
+ * across requests and only change when the loadout does.
1371
+ */
1372
+ _installHiddenDeclarationsProjection() {
1373
+ const previousTransformContext = this.agent.transformContext;
1374
+ this.agent.transformContext = async (messages, signal) => {
1375
+ const transformed = previousTransformContext ? await previousTransformContext(messages, signal) : messages;
1376
+ const hidden = this._hiddenDeclarations;
1377
+ if (hidden.size === 0)
1378
+ return transformed;
1379
+ return transformed.map((message) => {
1380
+ if (message.role !== "system" || (!message.toolsAdded && !message.toolsRemoved))
1381
+ return message;
1382
+ const { toolsAdded, toolsRemoved, ...rest } = message;
1383
+ const added = toolsAdded?.filter((tool) => !hidden.has(tool.name)) ?? [];
1384
+ const removed = toolsRemoved?.filter((tool) => !hidden.has(tool.name)) ?? [];
1385
+ return {
1386
+ ...rest,
1387
+ ...(added.length > 0 ? { toolsAdded: added } : {}),
1388
+ ...(removed.length > 0 ? { toolsRemoved: removed } : {}),
1389
+ };
1390
+ });
1391
+ };
1392
+ }
1134
1393
  _installAgentForcedPromptProjection() {
1135
1394
  const previousTransformContext = this.agent.transformContext;
1136
1395
  this.agent.transformContext = async (messages, signal) => {
@@ -1148,25 +1407,31 @@ export class AgentSession {
1148
1407
  return [head, ...transformed.filter((message) => message.role !== "system")];
1149
1408
  };
1150
1409
  }
1151
- /** Restore the active tool loadout declared by the session transcript, if it declares one. */
1410
+ /**
1411
+ * Restore the active tool loadout declared by the session transcript, if it declares one.
1412
+ * Tools reachable only from other tools are never declared, but they do not depend on the active
1413
+ * set, so the transcript's declarations are the whole loadout.
1414
+ */
1152
1415
  _restoreToolsFromTranscript() {
1416
+ this._pendingToolNames.clear();
1153
1417
  const current = getCurrentSystemMessage(this.sessionManager.buildSessionContext().messages);
1154
1418
  if (!current)
1155
1419
  return;
1156
- const toolNames = (current.toolsAdded ?? [])
1157
- .map((tool) => tool.name)
1158
- .filter((name) => this._toolRegistry.has(name));
1159
- this.agent.state.tools = toolNames.flatMap((name) => {
1160
- const registered = this._toolRegistry.get(name);
1161
- return registered ? [registered] : [];
1162
- });
1163
- this._rebuildSystemPrompt(toolNames);
1420
+ const names = (current.toolsAdded ?? []).map((tool) => tool.name);
1421
+ this._pendingToolNames = new Set(names.filter((name) => this._isAllowedTool(name)));
1422
+ this._setActiveTools(names);
1164
1423
  }
1165
1424
  // =========================================================================
1166
1425
  // Prompting
1167
1426
  // =========================================================================
1168
1427
  async _runAgentPrompt(messages) {
1169
1428
  this._agentRunAbortRequested = false;
1429
+ // Compaction before the prompt may have scheduled a retry; the new prompt replaces it.
1430
+ this._failedResponse = undefined;
1431
+ this._recordSelection();
1432
+ // The run records the loadout in the transcript; restored tools that did not register by now
1433
+ // are dropped, so a tool that never registers does not stay pending.
1434
+ this._pendingToolNames.clear();
1170
1435
  this._isAgentRunActive = true;
1171
1436
  try {
1172
1437
  await this.agent.prompt(messages);
@@ -1187,6 +1452,7 @@ export class AgentSession {
1187
1452
  finally {
1188
1453
  if (this._agentRunAbortRequested)
1189
1454
  this._finishCancelledRetry();
1455
+ this._failedResponse = undefined;
1190
1456
  this._runSystemPromptOptions = undefined;
1191
1457
  this._flushPendingBashMessages();
1192
1458
  this._flushPendingCustomMessages();
@@ -1207,6 +1473,7 @@ export class AgentSession {
1207
1473
  if (this._isRetryableError(message) && (await this._prepareRetry(message))) {
1208
1474
  if (this._agentRunAbortRequested)
1209
1475
  this._finishCancelledRetry();
1476
+ this._failedResponse = message;
1210
1477
  return !this._agentRunAbortRequested;
1211
1478
  }
1212
1479
  if (this._agentRunAbortRequested) {
@@ -1274,7 +1541,7 @@ export class AgentSession {
1274
1541
  for (const image of images) {
1275
1542
  const processed = await processImage(Buffer.from(image.data, "base64"), image.mimeType, {
1276
1543
  autoResizeImages: this.settingsManager.getImageAutoResize(),
1277
- resizeOptions: this.model?.inputLimits?.images?.resize,
1544
+ resizeOptions: this._limitsModel()?.inputLimits?.images?.resize,
1278
1545
  });
1279
1546
  if (!processed.ok) {
1280
1547
  hints.push(processed.message);
@@ -1300,7 +1567,7 @@ export class AgentSession {
1300
1567
  return;
1301
1568
  }
1302
1569
  // A user-initiated prompt is the recovery point for failed completion deliveries.
1303
- this.retryBackgroundNotifications();
1570
+ this.retryTaskNotifications();
1304
1571
  const expandPromptTemplates = options?.expandPromptTemplates ?? true;
1305
1572
  const preflightResult = options?.preflightResult;
1306
1573
  let messages;
@@ -1312,20 +1579,20 @@ export class AgentSession {
1312
1579
  const handled = await this._tryExecuteExtensionCommand(text);
1313
1580
  if (handled) {
1314
1581
  // Extension command executed, no prompt to send
1315
- preflightResult?.(true);
1582
+ preflightResult?.("handled");
1316
1583
  return;
1317
1584
  }
1318
1585
  }
1319
1586
  // Observer commands above may stay open indefinitely; only real model input owns
1320
1587
  // the preflight pause, released once the user message is established.
1321
- resumeBackground = this.pauseBackgroundNotifications();
1588
+ resumeBackground = this.pauseTaskNotifications();
1322
1589
  if (this._compactionAbortController !== undefined) {
1323
1590
  throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
1324
1591
  }
1325
1592
  // Emit input event for extension interception (before skill/template expansion)
1326
1593
  const processedInput = await this._runInputHandlers(text, options?.images, options?.source ?? "interactive", this.isStreaming ? options?.streamingBehavior : undefined);
1327
1594
  if (!processedInput) {
1328
- preflightResult?.(true);
1595
+ preflightResult?.("handled");
1329
1596
  return;
1330
1597
  }
1331
1598
  const { text: currentText, images: currentImages } = processedInput;
@@ -1346,7 +1613,7 @@ export class AgentSession {
1346
1613
  else {
1347
1614
  await this._queueSteer(expandedText, currentImages);
1348
1615
  }
1349
- preflightResult?.(true);
1616
+ preflightResult?.("queued");
1350
1617
  return;
1351
1618
  }
1352
1619
  // Flush any pending bash and custom messages before the new prompt
@@ -1396,7 +1663,6 @@ export class AgentSession {
1396
1663
  timestamp: Date.now(),
1397
1664
  });
1398
1665
  // Inject any pending "nextTurn" messages as context alongside the user message
1399
- // They stay queued until _messagePersisted() confirms the append.
1400
1666
  for (const msg of this._pendingNextTurnMessages) {
1401
1667
  messages.push(msg);
1402
1668
  }
@@ -1416,18 +1682,12 @@ export class AgentSession {
1416
1682
  if (updateMessage)
1417
1683
  messages.unshift(updateMessage);
1418
1684
  }
1419
- catch (error) {
1420
- preflightResult?.(false);
1421
- throw error;
1422
- }
1423
1685
  finally {
1424
- // Delivery is timer-scheduled, so a completion cannot start before the run below does.
1425
1686
  resumeBackground?.();
1426
1687
  }
1427
- if (!messages) {
1688
+ if (!messages)
1428
1689
  return;
1429
- }
1430
- preflightResult?.(true);
1690
+ preflightResult?.("started");
1431
1691
  await this._runAgentPrompt(messages);
1432
1692
  }
1433
1693
  /**
@@ -1493,7 +1753,7 @@ export class AgentSession {
1493
1753
  }
1494
1754
  const processedInput = await this._runInputHandlers(text, images, source, this.isStreaming ? behavior : undefined);
1495
1755
  if (!processedInput)
1496
- return;
1756
+ return "handled";
1497
1757
  let expandedText = this._expandSkillCommand(processedInput.text);
1498
1758
  expandedText = expandPromptTemplate(expandedText, [...this.promptTemplates]);
1499
1759
  if (behavior === "steer") {
@@ -1502,6 +1762,7 @@ export class AgentSession {
1502
1762
  else {
1503
1763
  await this._queueFollowUp(expandedText, processedInput.images);
1504
1764
  }
1765
+ return "queued";
1505
1766
  }
1506
1767
  /**
1507
1768
  * Queue a steering message while the agent is running.
@@ -1513,7 +1774,7 @@ export class AgentSession {
1513
1774
  * @throws Error if text is an extension command
1514
1775
  */
1515
1776
  async steer(text, images, options) {
1516
- await this._queueUserInput(text, images, "steer", options?.source ?? "interactive");
1777
+ return this._queueUserInput(text, images, "steer", options?.source ?? "interactive");
1517
1778
  }
1518
1779
  /**
1519
1780
  * Queue a follow-up message to be processed after the agent finishes.
@@ -1524,7 +1785,7 @@ export class AgentSession {
1524
1785
  * @throws Error if text is an extension command
1525
1786
  */
1526
1787
  async followUp(text, images, options) {
1527
- await this._queueUserInput(text, images, "followUp", options?.source ?? "interactive");
1788
+ return this._queueUserInput(text, images, "followUp", options?.source ?? "interactive");
1528
1789
  }
1529
1790
  /**
1530
1791
  * Internal: Queue a steering message (already expanded, no extension command check).
@@ -1685,7 +1946,7 @@ export class AgentSession {
1685
1946
  this._steeringMessages = [];
1686
1947
  this._followUpMessages = [];
1687
1948
  this.agent.clearAllQueues();
1688
- this._backgroundHost.queueCleared();
1949
+ this._tasksHost.delivery.queueCleared();
1689
1950
  this._emitQueueUpdate();
1690
1951
  return { steering, followUp };
1691
1952
  }
@@ -1942,8 +2203,10 @@ export class AgentSession {
1942
2203
  // Compaction
1943
2204
  // =========================================================================
1944
2205
  /** Generate Pi's built-in compaction summary for manual and automatic compaction. */
1945
- async _runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, signal, env, reason) {
1946
- return compact(preparation, requestModel, apiKey, headers, customInstructions, signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }), undefined);
2206
+ async _runDefaultCompaction(preparation, model, customInstructions, signal, reason) {
2207
+ // Resolve the request only when Pi summarizes itself: routing may call models or fail.
2208
+ const request = await this._getSummarizationRequestAuth(model, signal);
2209
+ 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);
1947
2210
  }
1948
2211
  _clearManualCompactionState() {
1949
2212
  this._compactionAbortController = undefined;
@@ -1965,7 +2228,7 @@ export class AgentSession {
1965
2228
  * @param customInstructions Optional instructions for the compaction summary
1966
2229
  */
1967
2230
  async compact(customInstructions) {
1968
- return this._withBackgroundPaused(() => this._compactBody(customInstructions));
2231
+ return this._withTasksPaused(() => this._compactBody(customInstructions));
1969
2232
  }
1970
2233
  async _compactBody(customInstructions) {
1971
2234
  await this.abort();
@@ -1978,8 +2241,7 @@ export class AgentSession {
1978
2241
  if (!model) {
1979
2242
  throw new Error(formatNoModelSelectedMessage());
1980
2243
  }
1981
- const settings = this.settingsManager.getCompactionSettings(model);
1982
- const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, this._compactionAbortController.signal);
2244
+ const settings = this.settingsManager.getCompactionSettings(this.routedModel?.model ?? model);
1983
2245
  const pathEntries = this.sessionManager.getBranch();
1984
2246
  const preparation = prepareCompaction(pathEntries, settings);
1985
2247
  if (!preparation) {
@@ -2025,7 +2287,7 @@ export class AgentSession {
2025
2287
  }
2026
2288
  else {
2027
2289
  // Shared default summary generator, also used by automatic compaction.
2028
- const result = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, env, "manual");
2290
+ const result = await this._runDefaultCompaction(preparation, model, customInstructions, this._compactionAbortController.signal, "manual");
2029
2291
  summary = result.summary;
2030
2292
  firstKeptEntryId = result.firstKeptEntryId;
2031
2293
  tokensBefore = result.tokensBefore;
@@ -2130,18 +2392,20 @@ export class AgentSession {
2130
2392
  * @returns Whether the post-run loop should call `agent.continue()` for overflow recovery or queued messages
2131
2393
  */
2132
2394
  async _checkCompaction(assistantMessage, skipAbortedCheck = true, toolResults = []) {
2133
- const settings = this.settingsManager.getCompactionSettings(this.model);
2395
+ const settings = this.settingsManager.getCompactionSettings(this._modelForMessage(assistantMessage) ?? this.model);
2134
2396
  if (!settings.enabled)
2135
2397
  return false;
2136
2398
  // Skip if message was aborted (user cancelled) - unless skipAbortedCheck is false
2137
2399
  if (skipAbortedCheck && assistantMessage.stopReason === "aborted")
2138
2400
  return false;
2139
- const contextWindow = this.model?.contextWindow ?? 0;
2140
2401
  // Skip overflow check if the message came from a different model.
2141
2402
  // This handles the case where user switched from a smaller-context model (e.g. opus)
2142
2403
  // to a larger-context model (e.g. codex) - the overflow error from the old model
2143
- // shouldn't trigger compaction for the new model.
2144
- const sameModel = this.model && assistantMessage.provider === this.model.provider && assistantMessage.model === this.model.id;
2404
+ // shouldn't trigger compaction for the new model. Under a virtual selection, the
2405
+ // physical model that produced the message supplies the limits.
2406
+ const messageModel = this._modelForMessage(assistantMessage);
2407
+ const sameModel = messageModel !== undefined;
2408
+ const contextWindow = (messageModel ?? this.model)?.contextWindow ?? 0;
2145
2409
  // Skip compaction checks if this assistant message is older than the latest
2146
2410
  // compaction boundary. This prevents a stale pre-compaction usage/error
2147
2411
  // from retriggering compaction on the first prompt after compaction.
@@ -2173,7 +2437,7 @@ export class AgentSession {
2173
2437
  const contextOverflow = sameModel &&
2174
2438
  ((explicitOverflow && assistantRetainedForExplicitRecovery) ||
2175
2439
  (assistantUsageMatchesProjection && isContextOverflow(assistantMessage, contextWindow)));
2176
- const recoverableLength = sameModel && assistantIsProjected && isRecoverableLength(assistantMessage, this.model?.maxTokens ?? 0);
2440
+ const recoverableLength = sameModel && assistantIsProjected && isRecoverableLength(assistantMessage, messageModel.maxTokens);
2177
2441
  if (contextOverflow || recoverableLength) {
2178
2442
  const willRetry = assistantMessage.stopReason !== "stop";
2179
2443
  // Case 2: the response completed successfully. Compact, but do not retry because
@@ -2205,7 +2469,10 @@ export class AgentSession {
2205
2469
  // Persistently omit the selected final attempt before post-run recovery compaction.
2206
2470
  this._overflowRecoveryAttempted = true;
2207
2471
  this._omitRecoveryAttempt(assistantMessage, toolResults);
2208
- return await this._runAutoCompaction("overflow", willRetry);
2472
+ const retry = await this._runAutoCompaction("overflow", willRetry);
2473
+ if (retry)
2474
+ this._failedResponse = assistantMessage;
2475
+ return retry;
2209
2476
  }
2210
2477
  // Case 3: threshold compaction without retry.
2211
2478
  // For error messages or all-zero usage messages, estimate from the last valid response.
@@ -2255,11 +2522,11 @@ export class AgentSession {
2255
2522
  * @returns Whether the post-run loop should call `agent.continue()`
2256
2523
  */
2257
2524
  async _runAutoCompaction(reason, willRetry) {
2258
- return this._withBackgroundPaused(() => this._runAutoCompactionBody(reason, willRetry));
2525
+ return this._withTasksPaused(() => this._runAutoCompactionBody(reason, willRetry));
2259
2526
  }
2260
2527
  async _runAutoCompactionBody(reason, willRetry) {
2261
2528
  const model = this.model;
2262
- const settings = this.settingsManager.getCompactionSettings(model);
2529
+ const settings = this.settingsManager.getCompactionSettings(this.routedModel?.model ?? model);
2263
2530
  let abortController;
2264
2531
  let started = false;
2265
2532
  let fromExtension = false;
@@ -2278,8 +2545,6 @@ export class AgentSession {
2278
2545
  started = true;
2279
2546
  this._emit({ type: "compaction_start", reason });
2280
2547
  abortController.signal.throwIfAborted();
2281
- const { model: requestModel, apiKey, headers, env, } = await this._getSummarizationRequestAuth(model, abortController.signal);
2282
- abortController.signal.throwIfAborted();
2283
2548
  let extensionCompaction;
2284
2549
  if (this._extensionRunner.hasHandlers("session_before_compact")) {
2285
2550
  const extensionResult = (await this._extensionRunner.emit({
@@ -2316,7 +2581,7 @@ export class AgentSession {
2316
2581
  }
2317
2582
  else {
2318
2583
  // Shared default summary generator, also used by manual compaction.
2319
- const compactResult = await this._runDefaultCompaction(preparation, requestModel, apiKey, headers, undefined, abortController.signal, env, reason);
2584
+ const compactResult = await this._runDefaultCompaction(preparation, model, undefined, abortController.signal, reason);
2320
2585
  summary = compactResult.summary;
2321
2586
  firstKeptEntryId = compactResult.firstKeptEntryId;
2322
2587
  tokensBefore = compactResult.tokensBefore;
@@ -2399,11 +2664,12 @@ export class AgentSession {
2399
2664
  return this.settingsManager.getCompactionEnabled();
2400
2665
  }
2401
2666
  async bindExtensions(bindings) {
2402
- return this._withBackgroundPaused(() => this._bindExtensionsBody(bindings));
2667
+ return this._withTasksPaused(() => this._bindExtensionsBody(bindings));
2403
2668
  }
2404
2669
  async _bindExtensionsBody(bindings) {
2405
- if (bindings.backgroundEnabled !== undefined) {
2406
- this._backgroundHost.setEnabled(bindings.backgroundEnabled);
2670
+ if (bindings.tasksEnabled !== undefined) {
2671
+ this._tasksHost.setEnabled(bindings.tasksEnabled);
2672
+ this._refreshToolRegistry();
2407
2673
  }
2408
2674
  if (bindings.uiContext !== undefined) {
2409
2675
  this._extensionUIContext = bindings.uiContext;
@@ -2425,6 +2691,7 @@ export class AgentSession {
2425
2691
  }
2426
2692
  this._applyExtensionBindings(this._extensionRunner);
2427
2693
  await this._extensionRunner.emit(this._sessionStartEvent);
2694
+ this._extensionRunner.reportUnhandledMcpServers();
2428
2695
  await this.extendResourcesFromExtensions(this._sessionStartEvent.reason === "reload" ? "reload" : "startup");
2429
2696
  }
2430
2697
  async extendResourcesFromExtensions(reason) {
@@ -2446,7 +2713,7 @@ export class AgentSession {
2446
2713
  buildExtensionResourcePaths(entries) {
2447
2714
  return entries.map((entry) => {
2448
2715
  const source = this.getExtensionSourceLabel(entry.extensionPath);
2449
- const baseDir = entry.extensionPath.startsWith("<") ? undefined : dirname(entry.extensionPath);
2716
+ const baseDir = isSyntheticPath(entry.extensionPath) ? undefined : dirname(entry.extensionPath);
2450
2717
  return {
2451
2718
  path: entry.path,
2452
2719
  metadata: {
@@ -2459,7 +2726,7 @@ export class AgentSession {
2459
2726
  });
2460
2727
  }
2461
2728
  getExtensionSourceLabel(extensionPath) {
2462
- if (extensionPath.startsWith("<")) {
2729
+ if (isSyntheticPath(extensionPath)) {
2463
2730
  return `extension:${extensionPath.replace(/[<>]/g, "")}`;
2464
2731
  }
2465
2732
  const base = basename(extensionPath);
@@ -2544,6 +2811,7 @@ export class AgentSession {
2544
2811
  },
2545
2812
  getActiveTools: () => this.getActiveToolNames(),
2546
2813
  getAllTools: () => this.getAllTools(),
2814
+ getSettings: () => this.settingsManager.getSettings(),
2547
2815
  setActiveTools: (toolNames) => this.setActiveToolsByName(toolNames),
2548
2816
  refreshTools: () => this._refreshToolRegistry(),
2549
2817
  getCommands,
@@ -2556,7 +2824,9 @@ export class AgentSession {
2556
2824
  getThinkingLevel: () => this.thinkingLevel,
2557
2825
  setThinkingLevel: (level) => this.setThinkingLevel(level),
2558
2826
  }, {
2559
- getBackground: () => this.background,
2827
+ getTasks: () => this.tasks,
2828
+ getExtensionSettings: (namespace) => this.settingsManager.getExtensionSettings(namespace),
2829
+ setExtensionSettings: (namespace, value) => this.settingsManager.setExtensionSettings(namespace, value),
2560
2830
  getModel: () => this.model,
2561
2831
  getScopedModels: () => this._scopedModels,
2562
2832
  isIdle: () => this.isIdle,
@@ -2589,6 +2859,8 @@ export class AgentSession {
2589
2859
  },
2590
2860
  getSystemPrompt: () => this.systemPrompt,
2591
2861
  getSystemPromptOptions: () => this._baseSystemPromptOptions,
2862
+ executeTool: (callerId, name, args, options) => this._executeNestedToolCall(callerId, name, args, options),
2863
+ getCallableTools: () => this._getCallableTools(),
2592
2864
  }, {
2593
2865
  registerProvider: (name, config) => {
2594
2866
  this._modelRuntime.registerProvider(name, config);
@@ -2602,14 +2874,22 @@ export class AgentSession {
2602
2874
  this._modelRuntime.unregisterProvider(name);
2603
2875
  this._refreshCurrentModelFromRegistry();
2604
2876
  },
2877
+ registerVirtualModel: (definition) => {
2878
+ this._modelRuntime.registerVirtualModel(definition);
2879
+ this._refreshCurrentModelFromRegistry();
2880
+ },
2881
+ unregisterVirtualModel: (provider, id) => {
2882
+ this._modelRuntime.unregisterVirtualModel(provider, id);
2883
+ this._refreshCurrentModelFromRegistry();
2884
+ },
2605
2885
  });
2606
2886
  }
2607
2887
  _refreshToolRegistry(options) {
2608
- const previousRegistryNames = new Set(this._toolRegistry.keys());
2888
+ // Tools that were already activated on registration. A tool whose exposure changes to
2889
+ // `direct` or `model-only` (for example from `hidden`) is activated like a new tool.
2890
+ const previousActivatedOnRegistration = new Set([...this._toolRegistry.keys()].filter((name) => this._isActivatedOnRegistration(name)));
2609
2891
  const previousActiveToolNames = this.getActiveToolNames();
2610
2892
  const allowedToolNames = this._allowedToolNames;
2611
- const excludedToolNames = this._excludedToolNames;
2612
- const isAllowedTool = (name) => (!allowedToolNames || allowedToolNames.has(name)) && !excludedToolNames?.has(name);
2613
2893
  const registeredTools = this._extensionRunner.getAllRegisteredTools();
2614
2894
  const allCustomTools = [
2615
2895
  ...registeredTools,
@@ -2617,14 +2897,14 @@ export class AgentSession {
2617
2897
  definition,
2618
2898
  sourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: "sdk" }),
2619
2899
  })),
2620
- ].filter((tool) => isAllowedTool(tool.definition.name));
2900
+ ].filter((tool) => this._isAllowedTool(tool.definition.name));
2621
2901
  const definitionRegistry = new Map(Array.from(this._baseToolDefinitions.entries())
2622
- .filter(([name]) => isAllowedTool(name))
2902
+ .filter(([name]) => this._isAllowedTool(name))
2623
2903
  .map(([name, definition]) => [
2624
2904
  name,
2625
2905
  {
2626
2906
  definition,
2627
- sourceInfo: createSyntheticSourceInfo(`<builtin:${name}>`, { source: "builtin" }),
2907
+ sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${name}`, { source: "builtin" }),
2628
2908
  },
2629
2909
  ]));
2630
2910
  for (const tool of allCustomTools) {
@@ -2649,37 +2929,57 @@ export class AgentSession {
2649
2929
  const runner = this._extensionRunner;
2650
2930
  const wrappedExtensionTools = wrapRegisteredTools(allCustomTools, runner);
2651
2931
  const wrappedBuiltInTools = wrapRegisteredTools(Array.from(this._baseToolDefinitions.values())
2652
- .filter((definition) => isAllowedTool(definition.name))
2932
+ .filter((definition) => this._isAllowedTool(definition.name))
2653
2933
  .map((definition) => ({
2654
2934
  definition,
2655
- sourceInfo: createSyntheticSourceInfo(`<builtin:${definition.name}>`, { source: "builtin" }),
2935
+ sourceInfo: createSyntheticSourceInfo(`${BUILTIN_PATH_PREFIX}${definition.name}`, {
2936
+ source: "builtin",
2937
+ }),
2656
2938
  })), runner);
2657
2939
  const toolRegistry = new Map(wrappedBuiltInTools.map((tool) => [tool.name, tool]));
2658
2940
  for (const tool of wrappedExtensionTools) {
2659
2941
  toolRegistry.set(tool.name, tool);
2660
2942
  }
2661
2943
  this._toolRegistry = toolRegistry;
2662
- const nextActiveToolNames = (options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]).filter((name) => isAllowedTool(name));
2944
+ const nextActiveToolNames = (options?.activeToolNames ? [...options.activeToolNames] : [...previousActiveToolNames]).filter((name) => this._isAllowedTool(name));
2663
2945
  if (allowedToolNames) {
2664
2946
  for (const toolName of this._toolRegistry.keys()) {
2665
- if (allowedToolNames.has(toolName)) {
2947
+ // Naming a tool activates it even when it is not active by default.
2948
+ if (allowedToolNames.has(toolName) && this._isDeclarable(toolName)) {
2666
2949
  nextActiveToolNames.push(toolName);
2667
2950
  }
2668
2951
  }
2669
2952
  }
2670
2953
  else if (options?.includeAllExtensionTools) {
2671
2954
  for (const tool of wrappedExtensionTools) {
2672
- nextActiveToolNames.push(tool.name);
2955
+ if (this._isActivatedOnRegistration(tool.name))
2956
+ nextActiveToolNames.push(tool.name);
2673
2957
  }
2674
2958
  }
2675
2959
  else if (!options?.activeToolNames) {
2676
2960
  for (const toolName of this._toolRegistry.keys()) {
2677
- if (!previousRegistryNames.has(toolName)) {
2961
+ if (!previousActivatedOnRegistration.has(toolName) && this._isActivatedOnRegistration(toolName)) {
2678
2962
  nextActiveToolNames.push(toolName);
2679
2963
  }
2680
2964
  }
2681
2965
  }
2682
- this.setActiveToolsByName([...new Set(nextActiveToolNames)]);
2966
+ // Pending tools that are registered now become active.
2967
+ nextActiveToolNames.push(...this._pendingToolNames);
2968
+ if (this.tasks.enabled &&
2969
+ this._initialActiveToolNames?.length !== 0 &&
2970
+ this._toolRegistry.has("tasks") &&
2971
+ this._isAllowedTool("tasks"))
2972
+ nextActiveToolNames.push("tasks");
2973
+ this._setActiveTools([...new Set(nextActiveToolNames)]);
2974
+ }
2975
+ /** Whether activating the tool declares it to the model. */
2976
+ _isDeclarable(name) {
2977
+ const exposure = this._getToolExposure(name);
2978
+ return exposure === "direct" || exposure === "model-only";
2979
+ }
2980
+ /** Whether registering the tool activates it, which declares it to the model. */
2981
+ _isActivatedOnRegistration(name) {
2982
+ return this._isDeclarable(name) && this._toolDefinitions.get(name)?.definition.defaultActive !== false;
2683
2983
  }
2684
2984
  _buildRuntime(options) {
2685
2985
  const autoResizeImages = this.settingsManager.getImageAutoResize();
@@ -2695,6 +2995,7 @@ export class AgentSession {
2695
2995
  bash: { commandPrefix: shellCommandPrefix, shellPath },
2696
2996
  });
2697
2997
  this._baseToolDefinitions = new Map(Object.entries(baseToolDefinitions).map(([name, tool]) => [name, tool]));
2998
+ this._baseToolDefinitions.set("tasks", createTasksToolDefinition((callId, taskId) => this._tasksHost.delivery.prepareWait(callId, taskId)));
2698
2999
  const extensionsResult = this._resourceLoader.getExtensions();
2699
3000
  if (options.flagValues) {
2700
3001
  for (const [name, value] of options.flagValues) {
@@ -2717,26 +3018,35 @@ export class AgentSession {
2717
3018
  });
2718
3019
  }
2719
3020
  async reload(options) {
2720
- return this._withBackgroundPaused(() => this._reloadBody(options));
3021
+ return this._withTasksPaused(() => this._reloadBody(options));
2721
3022
  }
2722
3023
  async _reloadBody(options) {
2723
3024
  const oldRunner = this._extensionRunner;
2724
3025
  const previousFlagValues = oldRunner.getFlagValues();
2725
- this.background.close();
2726
- await Promise.all([this.background.shutdown(), this.abort()]);
3026
+ this.tasks.close();
3027
+ await Promise.all([this.tasks.shutdown(), this.abort()]);
2727
3028
  await emitSessionShutdownEvent(oldRunner, { type: "session_shutdown", reason: "reload" });
2728
3029
  oldRunner.invalidate();
3030
+ const previousDefaultTools = new Set(this._usesDefaultTools ? (this.settingsManager.getDefaultTools() ?? DEFAULT_TOOL_NAMES) : []);
2729
3031
  await this.settingsManager.reload();
2730
3032
  this.syncQueueModesFromSettings();
2731
3033
  resetApiProviders();
2732
3034
  await this._resourceLoader.reload();
2733
- this._backgroundHost.replaceService();
3035
+ this._tasksHost.replaceService();
3036
+ // Activate tools newly added to defaultTools. Removed ones stay active, and tools disabled
3037
+ // during the session stay disabled unless the setting newly adds them.
3038
+ const addedDefaultTools = this._usesDefaultTools
3039
+ ? (this.settingsManager.getDefaultTools() ?? DEFAULT_TOOL_NAMES).filter((name) => !previousDefaultTools.has(name))
3040
+ : [];
3041
+ // Tools the new extensions register later, such as MCP tools, are pending until then.
3042
+ for (const name of this.getActiveToolNames())
3043
+ this._pendingToolNames.add(name);
2734
3044
  this._buildRuntime({
2735
- activeToolNames: this.getActiveToolNames(),
3045
+ activeToolNames: [...this.getActiveToolNames(), ...addedDefaultTools],
2736
3046
  flagValues: previousFlagValues,
2737
3047
  includeAllExtensionTools: true,
2738
3048
  });
2739
- const hasBindings = this.background.enabled ||
3049
+ const hasBindings = this.tasks.enabled ||
2740
3050
  this._extensionUIContext ||
2741
3051
  this._extensionCommandContextActions ||
2742
3052
  this._extensionShutdownHandler ||
@@ -2744,6 +3054,7 @@ export class AgentSession {
2744
3054
  if (hasBindings) {
2745
3055
  await options?.beforeSessionStart?.();
2746
3056
  await this._extensionRunner.emit({ type: "session_start", reason: "reload" });
3057
+ this._extensionRunner.reportUnhandledMcpServers();
2747
3058
  await this.extendResourcesFromExtensions("reload");
2748
3059
  }
2749
3060
  }
@@ -2756,7 +3067,7 @@ export class AgentSession {
2756
3067
  */
2757
3068
  _isRetryableError(message) {
2758
3069
  // Context overflow is handled by compaction, not retry.
2759
- if (isContextOverflow(message, this.model?.contextWindow ?? 0))
3070
+ if (isContextOverflow(message, (this._modelForMessage(message) ?? this.model)?.contextWindow ?? 0))
2760
3071
  return false;
2761
3072
  return isRetryableAssistantError(message);
2762
3073
  }
@@ -2975,6 +3286,19 @@ export class AgentSession {
2975
3286
  * @param options.label Label to attach to the branch summary entry
2976
3287
  * @returns Result with editorText (if user message) and cancelled status
2977
3288
  */
3289
+ /**
3290
+ * Running tasks that navigating to `targetId` would cancel, so a host can confirm first.
3291
+ * Mirrors navigateTree's destination: selecting a user or custom message moves the leaf to its parent.
3292
+ */
3293
+ tasksStoppedByTreeNavigation(targetId) {
3294
+ const target = this.sessionManager.getEntry(targetId);
3295
+ if (!target)
3296
+ return [];
3297
+ const leafId = (target.type === "message" && target.message.role === "user") || target.type === "custom_message"
3298
+ ? target.parentId
3299
+ : targetId;
3300
+ return this.tasks.activeOutsideBranch(new Set(leafId === null ? [] : this.sessionManager.getBranch(leafId).map((entry) => entry.id)));
3301
+ }
2978
3302
  async navigateTree(targetId, options = {}) {
2979
3303
  if (this.isStreaming) {
2980
3304
  throw new Error("Wait for the current response to finish before navigating the session tree.");
@@ -3011,7 +3335,7 @@ export class AgentSession {
3011
3335
  replaceInstructions,
3012
3336
  label,
3013
3337
  };
3014
- const resumeBackground = this.pauseBackgroundNotifications();
3338
+ const resumeBackground = this.pauseTaskNotifications();
3015
3339
  // Set up abort controller for summarization
3016
3340
  this._branchSummaryAbortController = new AbortController();
3017
3341
  try {
@@ -3047,15 +3371,11 @@ export class AgentSession {
3047
3371
  let summaryDetails;
3048
3372
  let summaryUsage;
3049
3373
  if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
3050
- const model = this.model;
3051
- const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
3374
+ const signal = this._branchSummaryAbortController.signal;
3052
3375
  const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
3053
3376
  const result = await generateBranchSummary(entriesToSummarize, {
3054
- model: requestModel,
3055
- apiKey,
3056
- headers,
3057
- env,
3058
- signal: this._branchSummaryAbortController.signal,
3377
+ ...(await this._getSummarizationRequestAuth(this.model, signal)),
3378
+ signal,
3059
3379
  customInstructions,
3060
3380
  replaceInstructions,
3061
3381
  reserveTokens: branchSummarySettings.reserveTokens,
@@ -3098,7 +3418,7 @@ export class AgentSession {
3098
3418
  // Non-user message: leaf = selected node
3099
3419
  newLeafId = targetId;
3100
3420
  }
3101
- await this.background.cancelOutsideBranch(new Set(newLeafId === null ? [] : this.sessionManager.getBranch(newLeafId).map((entry) => entry.id)));
3421
+ await this.tasks.cancelOutsideBranch(new Set(newLeafId === null ? [] : this.sessionManager.getBranch(newLeafId).map((entry) => entry.id)));
3102
3422
  // Switch leaf (with or without summary)
3103
3423
  // Summary is attached at the navigation target position (newLeafId), not the old branch
3104
3424
  let summaryEntry;
@@ -3123,7 +3443,7 @@ export class AgentSession {
3123
3443
  if (label && !summaryText) {
3124
3444
  this.sessionManager.appendLabelChange(targetId, label);
3125
3445
  }
3126
- this._backgroundHost.restoreHistory();
3446
+ this._tasksHost.restoreHistory();
3127
3447
  // Update finalized context from the canonical session projection.
3128
3448
  this._refreshFinalizedContext();
3129
3449
  this._restoreToolsFromTranscript();
@@ -3216,7 +3536,7 @@ export class AgentSession {
3216
3536
  };
3217
3537
  }
3218
3538
  getContextUsage() {
3219
- const model = this.model;
3539
+ const model = this._limitsModel();
3220
3540
  if (!model)
3221
3541
  return undefined;
3222
3542
  const contextWindow = model.contextWindow ?? 0;
@@ -3288,16 +3608,11 @@ export class AgentSession {
3288
3608
  if (!model) {
3289
3609
  throw new Error("No model selected");
3290
3610
  }
3291
- const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
3292
3611
  return generateBugReportSummary({
3612
+ ...(await this._getSummarizationRequestAuth(model, options.signal)),
3293
3613
  messages: this.messages,
3294
3614
  hint: options.hint,
3295
- model: requestModel,
3296
- apiKey,
3297
- headers,
3298
- env,
3299
3615
  signal: options.signal,
3300
- thinkingLevel: this.thinkingLevel,
3301
3616
  streamFn: this.agent.streamFunction,
3302
3617
  retry: this.settingsManager.getRetrySettings(),
3303
3618
  sessionId: this.sessionId,