@averyyy/pi-coding-agent 0.83.0-piclient.1 → 0.84.1-piclient.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (344) hide show
  1. package/CHANGELOG.md +228 -0
  2. package/README.md +5 -0
  3. package/dist/cli/args.d.ts +2 -0
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +22 -3
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/auth-check.d.ts +19 -0
  8. package/dist/cli/auth-check.d.ts.map +1 -0
  9. package/dist/cli/auth-check.js +50 -0
  10. package/dist/cli/auth-check.js.map +1 -0
  11. package/dist/cli/auth-command.d.ts +24 -0
  12. package/dist/cli/auth-command.d.ts.map +1 -0
  13. package/dist/cli/auth-command.js +102 -0
  14. package/dist/cli/auth-command.js.map +1 -0
  15. package/dist/cli/config-selector.d.ts.map +1 -1
  16. package/dist/cli/config-selector.js +2 -2
  17. package/dist/cli/config-selector.js.map +1 -1
  18. package/dist/cli/credential-print.d.ts +5 -15
  19. package/dist/cli/credential-print.d.ts.map +1 -1
  20. package/dist/cli/credential-print.js +42 -82
  21. package/dist/cli/credential-print.js.map +1 -1
  22. package/dist/cli/experimental/auth.d.ts +16 -0
  23. package/dist/cli/experimental/auth.d.ts.map +1 -0
  24. package/dist/cli/experimental/auth.js +13 -0
  25. package/dist/cli/experimental/auth.js.map +1 -0
  26. package/dist/cli/experimental/cli.d.ts +6 -0
  27. package/dist/cli/experimental/cli.d.ts.map +1 -0
  28. package/dist/cli/experimental/cli.js +5 -0
  29. package/dist/cli/experimental/cli.js.map +1 -0
  30. package/dist/cli/experimental/command-options.d.ts +17 -0
  31. package/dist/cli/experimental/command-options.d.ts.map +1 -0
  32. package/dist/cli/experimental/command-options.js +35 -0
  33. package/dist/cli/experimental/command-options.js.map +1 -0
  34. package/dist/cli/experimental/command.d.ts +63 -0
  35. package/dist/cli/experimental/command.d.ts.map +1 -0
  36. package/dist/cli/experimental/command.js +130 -0
  37. package/dist/cli/experimental/command.js.map +1 -0
  38. package/dist/cli/experimental/commands/client.d.ts +13 -0
  39. package/dist/cli/experimental/commands/client.d.ts.map +1 -0
  40. package/dist/cli/experimental/commands/client.js +25 -0
  41. package/dist/cli/experimental/commands/client.js.map +1 -0
  42. package/dist/cli/experimental/commands/pi.d.ts +15 -0
  43. package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
  44. package/dist/cli/experimental/commands/pi.js +28 -0
  45. package/dist/cli/experimental/commands/pi.js.map +1 -0
  46. package/dist/cli/experimental/commands/server.d.ts +13 -0
  47. package/dist/cli/experimental/commands/server.d.ts.map +1 -0
  48. package/dist/cli/experimental/commands/server.js +25 -0
  49. package/dist/cli/experimental/commands/server.js.map +1 -0
  50. package/dist/cli/experimental/transport-address.d.ts +10 -0
  51. package/dist/cli/experimental/transport-address.d.ts.map +1 -0
  52. package/dist/cli/experimental/transport-address.js +38 -0
  53. package/dist/cli/experimental/transport-address.js.map +1 -0
  54. package/dist/cli/list-models.d.ts +1 -1
  55. package/dist/cli/list-models.d.ts.map +1 -1
  56. package/dist/cli/list-models.js +2 -2
  57. package/dist/cli/list-models.js.map +1 -1
  58. package/dist/cli/startup-ui.d.ts +1 -1
  59. package/dist/cli/startup-ui.d.ts.map +1 -1
  60. package/dist/cli/startup-ui.js +2 -2
  61. package/dist/cli/startup-ui.js.map +1 -1
  62. package/dist/cli.d.ts.map +1 -1
  63. package/dist/cli.js +1 -0
  64. package/dist/cli.js.map +1 -1
  65. package/dist/client/index.d.ts +3 -0
  66. package/dist/client/index.d.ts.map +1 -0
  67. package/dist/client/index.js +3 -0
  68. package/dist/client/index.js.map +1 -0
  69. package/dist/client/remote-session.d.ts +53 -0
  70. package/dist/client/remote-session.d.ts.map +1 -0
  71. package/dist/client/remote-session.js +340 -0
  72. package/dist/client/remote-session.js.map +1 -0
  73. package/dist/client/transcript.d.ts +12 -0
  74. package/dist/client/transcript.d.ts.map +1 -0
  75. package/dist/client/transcript.js +98 -0
  76. package/dist/client/transcript.js.map +1 -0
  77. package/dist/core/agent-session-services.d.ts +1 -0
  78. package/dist/core/agent-session-services.d.ts.map +1 -1
  79. package/dist/core/agent-session-services.js +1 -0
  80. package/dist/core/agent-session-services.js.map +1 -1
  81. package/dist/core/agent-session.d.ts +2 -11
  82. package/dist/core/agent-session.d.ts.map +1 -1
  83. package/dist/core/agent-session.js +61 -59
  84. package/dist/core/agent-session.js.map +1 -1
  85. package/dist/core/auth-storage.d.ts +25 -9
  86. package/dist/core/auth-storage.d.ts.map +1 -1
  87. package/dist/core/auth-storage.js +237 -39
  88. package/dist/core/auth-storage.js.map +1 -1
  89. package/dist/core/extensions/index.d.ts +1 -1
  90. package/dist/core/extensions/index.d.ts.map +1 -1
  91. package/dist/core/extensions/index.js.map +1 -1
  92. package/dist/core/extensions/loader.d.ts.map +1 -1
  93. package/dist/core/extensions/loader.js +43 -20
  94. package/dist/core/extensions/loader.js.map +1 -1
  95. package/dist/core/extensions/runner.d.ts +2 -1
  96. package/dist/core/extensions/runner.d.ts.map +1 -1
  97. package/dist/core/extensions/runner.js +3 -0
  98. package/dist/core/extensions/runner.js.map +1 -1
  99. package/dist/core/extensions/types.d.ts +26 -3
  100. package/dist/core/extensions/types.d.ts.map +1 -1
  101. package/dist/core/extensions/types.js.map +1 -1
  102. package/dist/core/http-dispatcher.d.ts.map +1 -1
  103. package/dist/core/http-dispatcher.js +5 -0
  104. package/dist/core/http-dispatcher.js.map +1 -1
  105. package/dist/core/keybindings.d.ts +44 -4
  106. package/dist/core/keybindings.d.ts.map +1 -1
  107. package/dist/core/model-config.d.ts +29 -5
  108. package/dist/core/model-config.d.ts.map +1 -1
  109. package/dist/core/model-config.js +4 -0
  110. package/dist/core/model-config.js.map +1 -1
  111. package/dist/core/model-registry.d.ts +5 -3
  112. package/dist/core/model-registry.d.ts.map +1 -1
  113. package/dist/core/model-registry.js +13 -10
  114. package/dist/core/model-registry.js.map +1 -1
  115. package/dist/core/model-resolver.d.ts +4 -3
  116. package/dist/core/model-resolver.d.ts.map +1 -1
  117. package/dist/core/model-resolver.js +42 -10
  118. package/dist/core/model-resolver.js.map +1 -1
  119. package/dist/core/model-runtime.d.ts +30 -13
  120. package/dist/core/model-runtime.d.ts.map +1 -1
  121. package/dist/core/model-runtime.js +233 -73
  122. package/dist/core/model-runtime.js.map +1 -1
  123. package/dist/core/models-store.d.ts +12 -7
  124. package/dist/core/models-store.d.ts.map +1 -1
  125. package/dist/core/models-store.js +83 -14
  126. package/dist/core/models-store.js.map +1 -1
  127. package/dist/core/package-manager.d.ts +4 -1
  128. package/dist/core/package-manager.d.ts.map +1 -1
  129. package/dist/core/package-manager.js +63 -36
  130. package/dist/core/package-manager.js.map +1 -1
  131. package/dist/core/pi-manifest.d.ts +8 -0
  132. package/dist/core/pi-manifest.d.ts.map +1 -0
  133. package/dist/core/pi-manifest.js +25 -0
  134. package/dist/core/pi-manifest.js.map +1 -0
  135. package/dist/core/pi-server-client.d.ts +2 -2
  136. package/dist/core/pi-server-client.d.ts.map +1 -1
  137. package/dist/core/pi-server-client.js +2 -0
  138. package/dist/core/pi-server-client.js.map +1 -1
  139. package/dist/core/provider-composer.d.ts +4 -1
  140. package/dist/core/provider-composer.d.ts.map +1 -1
  141. package/dist/core/provider-composer.js +36 -15
  142. package/dist/core/provider-composer.js.map +1 -1
  143. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  144. package/dist/core/remote-catalog-provider.js +73 -67
  145. package/dist/core/remote-catalog-provider.js.map +1 -1
  146. package/dist/core/resource-loader.d.ts.map +1 -1
  147. package/dist/core/resource-loader.js +2 -2
  148. package/dist/core/resource-loader.js.map +1 -1
  149. package/dist/core/runtime-credentials.d.ts +5 -5
  150. package/dist/core/runtime-credentials.d.ts.map +1 -1
  151. package/dist/core/runtime-credentials.js +11 -8
  152. package/dist/core/runtime-credentials.js.map +1 -1
  153. package/dist/core/session-manager.d.ts.map +1 -1
  154. package/dist/core/session-manager.js +3 -1
  155. package/dist/core/session-manager.js.map +1 -1
  156. package/dist/core/settings-manager.d.ts +12 -0
  157. package/dist/core/settings-manager.d.ts.map +1 -1
  158. package/dist/core/settings-manager.js +40 -16
  159. package/dist/core/settings-manager.js.map +1 -1
  160. package/dist/core/tools/bash.d.ts +4 -0
  161. package/dist/core/tools/bash.d.ts.map +1 -1
  162. package/dist/core/tools/bash.js +6 -4
  163. package/dist/core/tools/bash.js.map +1 -1
  164. package/dist/core/tools/edit.d.ts +4 -0
  165. package/dist/core/tools/edit.d.ts.map +1 -1
  166. package/dist/core/tools/edit.js +11 -7
  167. package/dist/core/tools/edit.js.map +1 -1
  168. package/dist/core/tools/find.d.ts +7 -0
  169. package/dist/core/tools/find.d.ts.map +1 -1
  170. package/dist/core/tools/find.js +16 -19
  171. package/dist/core/tools/find.js.map +1 -1
  172. package/dist/core/tools/grep.d.ts +4 -0
  173. package/dist/core/tools/grep.d.ts.map +1 -1
  174. package/dist/core/tools/grep.js +5 -1
  175. package/dist/core/tools/grep.js.map +1 -1
  176. package/dist/core/tools/ls.d.ts +4 -0
  177. package/dist/core/tools/ls.d.ts.map +1 -1
  178. package/dist/core/tools/ls.js +5 -1
  179. package/dist/core/tools/ls.js.map +1 -1
  180. package/dist/core/tools/read.d.ts +4 -0
  181. package/dist/core/tools/read.d.ts.map +1 -1
  182. package/dist/core/tools/read.js +7 -3
  183. package/dist/core/tools/read.js.map +1 -1
  184. package/dist/core/tools/render-utils.d.ts.map +1 -1
  185. package/dist/core/tools/render-utils.js +6 -3
  186. package/dist/core/tools/render-utils.js.map +1 -1
  187. package/dist/core/tools/write.d.ts +4 -0
  188. package/dist/core/tools/write.d.ts.map +1 -1
  189. package/dist/core/tools/write.js +6 -2
  190. package/dist/core/tools/write.js.map +1 -1
  191. package/dist/extensions/llama/index.d.ts.map +1 -1
  192. package/dist/extensions/llama/index.js +11 -2
  193. package/dist/extensions/llama/index.js.map +1 -1
  194. package/dist/extensions/llama/provider.d.ts.map +1 -1
  195. package/dist/extensions/llama/provider.js +21 -7
  196. package/dist/extensions/llama/provider.js.map +1 -1
  197. package/dist/index.d.ts +4 -4
  198. package/dist/index.d.ts.map +1 -1
  199. package/dist/index.js +1 -1
  200. package/dist/index.js.map +1 -1
  201. package/dist/main.d.ts.map +1 -1
  202. package/dist/main.js +70 -25
  203. package/dist/main.js.map +1 -1
  204. package/dist/modes/index.d.ts +1 -0
  205. package/dist/modes/index.d.ts.map +1 -1
  206. package/dist/modes/index.js.map +1 -1
  207. package/dist/modes/interactive/components/assistant-message.d.ts +5 -2
  208. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  209. package/dist/modes/interactive/components/assistant-message.js +13 -4
  210. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  211. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  212. package/dist/modes/interactive/components/custom-editor.js +7 -0
  213. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  214. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  215. package/dist/modes/interactive/components/footer.js +2 -2
  216. package/dist/modes/interactive/components/footer.js.map +1 -1
  217. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  218. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  219. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  220. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  221. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  222. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  223. package/dist/modes/interactive/components/mermaid.js +75 -0
  224. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  225. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  226. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  227. package/dist/modes/interactive/components/model-selector.js +16 -4
  228. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  229. package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
  230. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  231. package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
  232. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  233. package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
  234. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  235. package/dist/modes/interactive/components/settings-selector.js +30 -0
  236. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  237. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  238. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  239. package/dist/modes/interactive/components/user-message.js +9 -2
  240. package/dist/modes/interactive/components/user-message.js.map +1 -1
  241. package/dist/modes/interactive/external-editor.d.ts.map +1 -1
  242. package/dist/modes/interactive/external-editor.js +7 -5
  243. package/dist/modes/interactive/external-editor.js.map +1 -1
  244. package/dist/modes/interactive/interactive-mode.d.ts +36 -2
  245. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  246. package/dist/modes/interactive/interactive-mode.js +462 -145
  247. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  248. package/dist/modes/interactive/theme/dark.json +1 -0
  249. package/dist/modes/interactive/theme/light.json +1 -0
  250. package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
  251. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  252. package/dist/modes/interactive/theme/theme-controller.js +10 -1
  253. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  254. package/dist/modes/interactive/theme/theme-schema.json +5 -1
  255. package/dist/modes/interactive/theme/theme.d.ts +2 -2
  256. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  257. package/dist/modes/interactive/theme/theme.js +24 -6
  258. package/dist/modes/interactive/theme/theme.js.map +1 -1
  259. package/dist/modes/json-event.d.ts +28 -0
  260. package/dist/modes/json-event.d.ts.map +1 -0
  261. package/dist/modes/json-event.js +12 -0
  262. package/dist/modes/json-event.js.map +1 -0
  263. package/dist/modes/print-mode.d.ts.map +1 -1
  264. package/dist/modes/print-mode.js +12 -2
  265. package/dist/modes/print-mode.js.map +1 -1
  266. package/dist/modes/rpc/rpc-client.d.ts +5 -4
  267. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  268. package/dist/modes/rpc/rpc-client.js.map +1 -1
  269. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  270. package/dist/modes/rpc/rpc-mode.js +4 -3
  271. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  272. package/dist/package-manager-cli.d.ts.map +1 -1
  273. package/dist/package-manager-cli.js +11 -9
  274. package/dist/package-manager-cli.js.map +1 -1
  275. package/dist/rpc-entry.d.ts.map +1 -1
  276. package/dist/rpc-entry.js +1 -0
  277. package/dist/rpc-entry.js.map +1 -1
  278. package/dist/server/create-harness.d.ts +26 -0
  279. package/dist/server/create-harness.d.ts.map +1 -0
  280. package/dist/server/create-harness.js +104 -0
  281. package/dist/server/create-harness.js.map +1 -0
  282. package/dist/utils/abort.d.ts +5 -0
  283. package/dist/utils/abort.d.ts.map +1 -0
  284. package/dist/utils/abort.js +48 -0
  285. package/dist/utils/abort.js.map +1 -0
  286. package/dist/utils/clipboard.d.ts +1 -1
  287. package/dist/utils/clipboard.d.ts.map +1 -1
  288. package/dist/utils/clipboard.js +22 -2
  289. package/dist/utils/clipboard.js.map +1 -1
  290. package/dist/utils/management-http.d.ts +23 -0
  291. package/dist/utils/management-http.d.ts.map +1 -0
  292. package/dist/utils/management-http.js +50 -0
  293. package/dist/utils/management-http.js.map +1 -0
  294. package/dist/utils/paths.d.ts +3 -0
  295. package/dist/utils/paths.d.ts.map +1 -1
  296. package/dist/utils/paths.js +23 -1
  297. package/dist/utils/paths.js.map +1 -1
  298. package/dist/utils/tool-result-images.d.ts +19 -0
  299. package/dist/utils/tool-result-images.d.ts.map +1 -0
  300. package/dist/utils/tool-result-images.js +45 -0
  301. package/dist/utils/tool-result-images.js.map +1 -0
  302. package/dist/utils/tools-manager.d.ts.map +1 -1
  303. package/dist/utils/tools-manager.js +4 -6
  304. package/dist/utils/tools-manager.js.map +1 -1
  305. package/dist/utils/version-check.d.ts +4 -0
  306. package/dist/utils/version-check.d.ts.map +1 -1
  307. package/dist/utils/version-check.js +20 -2
  308. package/dist/utils/version-check.js.map +1 -1
  309. package/docs/compaction.md +2 -2
  310. package/docs/custom-provider.md +7 -5
  311. package/docs/extensions.md +30 -5
  312. package/docs/json.md +19 -14
  313. package/docs/keybindings.md +46 -14
  314. package/docs/models.md +24 -3
  315. package/docs/providers.md +9 -1
  316. package/docs/quickstart.md +2 -0
  317. package/docs/rpc.md +13 -11
  318. package/docs/sdk.md +21 -2
  319. package/docs/security.md +1 -1
  320. package/docs/settings.md +4 -1
  321. package/docs/themes.md +5 -3
  322. package/docs/usage.md +7 -0
  323. package/examples/extensions/custom-compaction.ts +1 -16
  324. package/examples/extensions/custom-provider-anthropic/index.ts +2 -1
  325. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  326. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  327. package/examples/extensions/custom-provider-gitlab-duo/index.ts +2 -1
  328. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  329. package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
  330. package/examples/extensions/gondolin/package-lock.json +2 -2
  331. package/examples/extensions/gondolin/package.json +1 -1
  332. package/examples/extensions/handoff.ts +2 -11
  333. package/examples/extensions/qna.ts +3 -7
  334. package/examples/extensions/sandbox/package-lock.json +2 -2
  335. package/examples/extensions/sandbox/package.json +1 -1
  336. package/examples/extensions/summarize.ts +7 -18
  337. package/examples/extensions/with-deps/package-lock.json +2 -2
  338. package/examples/extensions/with-deps/package.json +1 -1
  339. package/examples/rpc-extension-ui.ts +11 -2
  340. package/examples/sdk/02-custom-model.ts +1 -2
  341. package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
  342. package/examples/sdk/12-full-control.ts +1 -1
  343. package/examples/sdk/README.md +1 -1
  344. package/package.json +13 -6
@@ -15,11 +15,12 @@
15
15
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
16
16
  import { basename, dirname } from "node:path";
17
17
  import { contentText } from "@earendil-works/pi-ai";
18
- import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
18
+ import { clampThinkingLevel, cleanupSessionResources, getSupportedThinkingLevels, isContextOverflow, isRecoverableLength, isRetryableAssistantError, modelsAreEqual, resetApiProviders, streamSimple, } from "@earendil-works/pi-ai/compat";
19
19
  import { getThemeByName, theme } from "../modes/interactive/theme/theme.js";
20
20
  import { stripFrontmatter } from "../utils/frontmatter.js";
21
21
  import { resolvePath } from "../utils/paths.js";
22
22
  import { sleep } from "../utils/sleep.js";
23
+ import { normalizeToolResultImages } from "../utils/tool-result-images.js";
23
24
  import { formatNoApiKeyFoundMessage, formatNoModelSelectedMessage } from "./auth-guidance.js";
24
25
  import { executeBashWithOperations } from "./bash-executor.js";
25
26
  import { calculateContextTokens, collectEntriesForBranchSummary, compact, estimateContextTokens, estimateTokens, generateBranchSummary, prepareCompaction, shouldCompact, } from "./compaction/index.js";
@@ -273,7 +274,9 @@ export class AgentSession {
273
274
  throw error;
274
275
  }
275
276
  if (result && (result.auth.apiKey || result.auth.headers)) {
277
+ const requestModel = result.auth.baseUrl ? { ...model, baseUrl: result.auth.baseUrl } : model;
276
278
  return {
279
+ model: requestModel,
277
280
  apiKey: result.auth.apiKey,
278
281
  headers: withoutDeletedHeaders(result.auth.headers),
279
282
  env: result.env,
@@ -293,12 +296,18 @@ export class AgentSession {
293
296
  }
294
297
  try {
295
298
  const result = await this._modelRuntime.getAuth(model);
296
- return result
297
- ? { apiKey: result.auth.apiKey, headers: withoutDeletedHeaders(result.auth.headers), env: result.env }
298
- : {};
299
+ if (!result)
300
+ return { model };
301
+ const requestModel = result.auth.baseUrl ? { ...model, baseUrl: result.auth.baseUrl } : model;
302
+ return {
303
+ model: requestModel,
304
+ apiKey: result.auth.apiKey,
305
+ headers: withoutDeletedHeaders(result.auth.headers),
306
+ env: result.env,
307
+ };
299
308
  }
300
309
  catch {
301
- return {};
310
+ return { model };
302
311
  }
303
312
  }
304
313
  _resetValidationHintState() {
@@ -409,17 +418,21 @@ export class AgentSession {
409
418
  usage: result.usage,
410
419
  })
411
420
  : undefined;
412
- const finalContent = hookResult?.content ?? result.content;
421
+ const content = hookResult?.content ?? result.content ?? [];
422
+ // Runs after the extension hook so images injected or replaced by extensions are normalized too.
423
+ const normalizedContent = await normalizeToolResultImages(content, {
424
+ autoResizeImages: this.settingsManager.getImageAutoResize(),
425
+ });
413
426
  const finalIsError = hookResult?.isError ?? isError;
414
- this._recordValidationToolResult(toolCall.name, args, finalContent, finalIsError);
415
- if (!hookResult) {
427
+ this._recordValidationToolResult(toolCall.name, args, normalizedContent, finalIsError);
428
+ if (!hookResult && normalizedContent === content) {
416
429
  return undefined;
417
430
  }
418
431
  return {
419
- content: hookResult.content,
420
- details: hookResult.details,
421
- isError: hookResult.isError ?? isError,
422
- usage: hookResult.usage,
432
+ content: normalizedContent,
433
+ details: hookResult?.details,
434
+ isError: hookResult?.isError ?? isError,
435
+ usage: hookResult?.usage,
423
436
  };
424
437
  };
425
438
  }
@@ -752,26 +765,13 @@ export class AgentSession {
752
765
  }
753
766
  };
754
767
  }
755
- /**
756
- * Temporarily disconnect from agent events.
757
- * User listeners are preserved and will receive events again after resubscribe().
758
- * Used internally during operations that need to pause event processing.
759
- */
768
+ /** Disconnect from agent events during disposal. */
760
769
  _disconnectFromAgent() {
761
770
  if (this._unsubscribeAgent) {
762
771
  this._unsubscribeAgent();
763
772
  this._unsubscribeAgent = undefined;
764
773
  }
765
774
  }
766
- /**
767
- * Reconnect to agent events after _disconnectFromAgent().
768
- * Preserves all existing listeners.
769
- */
770
- _reconnectToAgent() {
771
- if (this._unsubscribeAgent)
772
- return; // Already connected
773
- this._unsubscribeAgent = this.agent.subscribe(this._handleAgentEvent);
774
- }
775
775
  /**
776
776
  * Remove all listeners and disconnect from agent.
777
777
  * Call this when completely done with the session.
@@ -1113,6 +1113,9 @@ export class AgentSession {
1113
1113
  return;
1114
1114
  }
1115
1115
  }
1116
+ if (this._compactionAbortController !== undefined) {
1117
+ throw new Error("Cannot submit a prompt while compaction is in progress. Wait for compaction to finish and retry.");
1118
+ }
1116
1119
  // Emit input event for extension interception (before skill/template expansion)
1117
1120
  let currentText = text;
1118
1121
  let currentImages = options?.images;
@@ -1532,11 +1535,8 @@ export class AgentSession {
1532
1535
  return this._cycleAvailableModel(direction);
1533
1536
  }
1534
1537
  async _cycleScopedModel(direction) {
1535
- const checks = await Promise.all(this._scopedModels.map(async (scoped) => ({
1536
- scoped,
1537
- auth: await this._modelRuntime.checkAuth(scoped.model.provider),
1538
- })));
1539
- const scopedModels = checks.filter(({ auth }) => auth !== undefined).map(({ scoped }) => scoped);
1538
+ const availableIds = new Set(this._modelRuntime.getAvailableSnapshot().map((model) => `${model.provider}\0${model.id}`));
1539
+ const scopedModels = this._scopedModels.filter((scoped) => availableIds.has(`${scoped.model.provider}\0${scoped.model.id}`));
1540
1540
  if (scopedModels.length <= 1)
1541
1541
  return undefined;
1542
1542
  const currentModel = this.model;
@@ -1560,7 +1560,7 @@ export class AgentSession {
1560
1560
  return { model: next.model, thinkingLevel: this.thinkingLevel, isScoped: true };
1561
1561
  }
1562
1562
  async _cycleAvailableModel(direction) {
1563
- const availableModels = await this._modelRuntime.getAvailable();
1563
+ const availableModels = this._modelRuntime.getAvailableSnapshot();
1564
1564
  if (availableModels.length <= 1)
1565
1565
  return undefined;
1566
1566
  const currentModel = this.model;
@@ -1709,7 +1709,6 @@ export class AgentSession {
1709
1709
  * @param customInstructions Optional instructions for the compaction summary
1710
1710
  */
1711
1711
  async compact(customInstructions) {
1712
- this._disconnectFromAgent();
1713
1712
  await this.abort();
1714
1713
  this._compactionAbortController = new AbortController();
1715
1714
  this._emit({ type: "compaction_start", reason: "manual" });
@@ -1717,10 +1716,10 @@ export class AgentSession {
1717
1716
  if (!this.model) {
1718
1717
  throw new Error(formatNoModelSelectedMessage());
1719
1718
  }
1720
- const { apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model);
1719
+ const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model);
1721
1720
  if (isPiServerMode()) {
1722
1721
  this._detachPiServerTerminalAssistantFailure();
1723
- const piServerResult = await compactPiServer(this.model, {
1722
+ const piServerResult = await compactPiServer(requestModel, {
1724
1723
  systemPrompt: this.systemPrompt,
1725
1724
  messages: this.agent.state.messages,
1726
1725
  tools: this.agent.state.tools,
@@ -1792,7 +1791,7 @@ export class AgentSession {
1792
1791
  }
1793
1792
  else {
1794
1793
  // Generate compaction result
1795
- const result = await compact(preparation, this.model, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason: "manual" }));
1794
+ const result = await compact(preparation, requestModel, apiKey, headers, customInstructions, this._compactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason: "manual" }));
1796
1795
  summary = result.summary;
1797
1796
  firstKeptEntryId = result.firstKeptEntryId;
1798
1797
  tokensBefore = result.tokensBefore;
@@ -1826,6 +1825,8 @@ export class AgentSession {
1826
1825
  usage,
1827
1826
  details,
1828
1827
  };
1828
+ // compaction_end listeners may submit queued prompts, so expose idle state before notifying them.
1829
+ this._compactionAbortController = undefined;
1829
1830
  this._emit({
1830
1831
  type: "compaction_end",
1831
1832
  reason: "manual",
@@ -1838,6 +1839,7 @@ export class AgentSession {
1838
1839
  catch (error) {
1839
1840
  const message = error instanceof Error ? error.message : String(error);
1840
1841
  const aborted = message === "Compaction cancelled" || (error instanceof Error && error.name === "AbortError");
1842
+ this._compactionAbortController = undefined;
1841
1843
  this._emit({
1842
1844
  type: "compaction_end",
1843
1845
  reason: "manual",
@@ -1850,7 +1852,6 @@ export class AgentSession {
1850
1852
  }
1851
1853
  finally {
1852
1854
  this._compactionAbortController = undefined;
1853
- this._reconnectToAgent();
1854
1855
  }
1855
1856
  }
1856
1857
  /**
@@ -1871,7 +1872,8 @@ export class AgentSession {
1871
1872
  * Called after agent_end and before prompt submission.
1872
1873
  *
1873
1874
  * Two cases:
1874
- * 1. Overflow: LLM returned context overflow error, remove error message from agent state, compact, auto-retry
1875
+ * 1. Recoverable failure: LLM returned context overflow or stopped below its desired output limit;
1876
+ * remove the assistant message, compact, and auto-retry once
1875
1877
  * 2. Threshold: Context over threshold, compact, NO auto-retry (user continues manually)
1876
1878
  *
1877
1879
  * @param assistantMessage The assistant message to check
@@ -1900,11 +1902,13 @@ export class AgentSession {
1900
1902
  if (assistantIsFromBeforeCompaction) {
1901
1903
  return false;
1902
1904
  }
1903
- // Case 1: Overflow - LLM returned context overflow error, or reported usage exceeded
1904
- // the configured window. A successful response over the configured window should compact
1905
- // but must not retry: the assistant answer already completed and agent.continue() cannot
1906
- // continue from an assistant message.
1907
- if (sameModel && isContextOverflow(assistantMessage, contextWindow)) {
1905
+ // Case 1: Recoverable failure. Explicit/silent context overflow still uses context metadata.
1906
+ // A length stop is recoverable when output ended below the model's original desired limit,
1907
+ // independent of the configured context size or any context-clamped provider request limit.
1908
+ // A successful response over the configured window should compact but must not retry: the
1909
+ // assistant answer already completed and agent.continue() cannot continue from an assistant.
1910
+ const recoverableLength = sameModel && isRecoverableLength(assistantMessage, this.model?.maxTokens ?? 0);
1911
+ if (sameModel && (isContextOverflow(assistantMessage, contextWindow) || recoverableLength)) {
1908
1912
  const willRetry = assistantMessage.stopReason !== "stop";
1909
1913
  if (!willRetry) {
1910
1914
  return await this._runAutoCompaction("overflow", false);
@@ -1977,21 +1981,13 @@ export class AgentSession {
1977
1981
  if (!this.model) {
1978
1982
  return false;
1979
1983
  }
1980
- let apiKey;
1981
- let headers;
1982
- let env;
1983
- if (this.agent.streamFunction === streamSimple) {
1984
- ({ apiKey, headers, env } = await this._getRequiredRequestAuth(this.model));
1985
- }
1986
- else {
1987
- ({ apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model));
1988
- }
1984
+ const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(this.model);
1989
1985
  if (isPiServerMode()) {
1990
1986
  this._emit({ type: "compaction_start", reason });
1991
1987
  this._autoCompactionAbortController = new AbortController();
1992
1988
  started = true;
1993
1989
  const signal = this._autoCompactionAbortController.signal;
1994
- const piServerResult = await compactPiServer(this.model, {
1990
+ const piServerResult = await compactPiServer(requestModel, {
1995
1991
  systemPrompt: this.systemPrompt,
1996
1992
  messages: this.agent.state.messages,
1997
1993
  tools: this.agent.state.tools,
@@ -2061,7 +2057,7 @@ export class AgentSession {
2061
2057
  }
2062
2058
  else {
2063
2059
  // Generate compaction result
2064
- const compactResult = await compact(preparation, this.model, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }));
2060
+ const compactResult = await compact(preparation, requestModel, apiKey, headers, undefined, this._autoCompactionAbortController.signal, this.thinkingLevel, this.agent.streamFunction, env, this.settingsManager.getRetrySettings(), this._summarizationRetryCallbacks({ source: "compaction", reason }));
2065
2061
  summary = compactResult.summary;
2066
2062
  firstKeptEntryId = compactResult.firstKeptEntryId;
2067
2063
  tokensBefore = compactResult.tokensBefore;
@@ -2106,7 +2102,11 @@ export class AgentSession {
2106
2102
  if (willRetry) {
2107
2103
  const messages = this.agent.state.messages;
2108
2104
  const lastMsg = messages[messages.length - 1];
2109
- if (lastMsg?.role === "assistant" && lastMsg.stopReason === "error") {
2105
+ // The overflow response was persisted on message_end before _checkCompaction() removed it
2106
+ // from agent state. Rebuilding state from the new compaction can restore that kept entry,
2107
+ // leaving an assistant as the final message. agent.continue() rejects that state, so remove
2108
+ // the retriable error or truncated-length response again before continuing the interrupted turn.
2109
+ if (lastMsg?.role === "assistant" && (lastMsg.stopReason === "error" || lastMsg.stopReason === "length")) {
2110
2110
  this.agent.state.messages = messages.slice(0, -1);
2111
2111
  }
2112
2112
  return true;
@@ -2511,8 +2511,10 @@ export class AgentSession {
2511
2511
  });
2512
2512
  }
2513
2513
  async reload(options) {
2514
- const previousFlagValues = this._extensionRunner.getFlagValues();
2515
- await emitSessionShutdownEvent(this._extensionRunner, { type: "session_shutdown", reason: "reload" });
2514
+ const oldRunner = this._extensionRunner;
2515
+ const previousFlagValues = oldRunner.getFlagValues();
2516
+ await emitSessionShutdownEvent(oldRunner, { type: "session_shutdown", reason: "reload" });
2517
+ oldRunner.invalidate();
2516
2518
  await this.settingsManager.reload();
2517
2519
  this.syncQueueModesFromSettings();
2518
2520
  resetApiProviders();
@@ -2858,10 +2860,10 @@ export class AgentSession {
2858
2860
  let summaryUsage;
2859
2861
  if (options.summarize && entriesToSummarize.length > 0 && !extensionSummary) {
2860
2862
  const model = this.model;
2861
- const { apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
2863
+ const { model: requestModel, apiKey, headers, env } = await this._getSummarizationRequestAuth(model);
2862
2864
  const branchSummarySettings = this.settingsManager.getBranchSummarySettings();
2863
2865
  const result = await generateBranchSummary(entriesToSummarize, {
2864
- model,
2866
+ model: requestModel,
2865
2867
  apiKey,
2866
2868
  headers,
2867
2869
  env,