gsd-pi 2.70.1 → 2.71.0-dev.246c32d

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 (541) hide show
  1. package/README.md +57 -17
  2. package/dist/cli.js +29 -3
  3. package/dist/headless-events.d.ts +2 -0
  4. package/dist/headless-events.js +7 -0
  5. package/dist/headless.js +16 -3
  6. package/dist/mcp-server.js +40 -17
  7. package/dist/provider-migrations.d.ts +10 -0
  8. package/dist/provider-migrations.js +12 -0
  9. package/dist/resource-loader.js +139 -13
  10. package/dist/resources/GSD-WORKFLOW.md +1 -1
  11. package/dist/resources/agents/debugger.md +58 -0
  12. package/dist/resources/agents/doc-writer.md +43 -0
  13. package/dist/resources/agents/git-ops.md +56 -0
  14. package/dist/resources/agents/javascript-pro.md +46 -271
  15. package/dist/resources/agents/planner.md +55 -0
  16. package/dist/resources/agents/refactorer.md +47 -0
  17. package/dist/resources/agents/reviewer.md +48 -0
  18. package/dist/resources/agents/security.md +59 -0
  19. package/dist/resources/agents/tester.md +50 -0
  20. package/dist/resources/agents/typescript-pro.md +41 -235
  21. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +242 -40
  22. package/dist/resources/extensions/get-secrets-from-user.js +17 -1
  23. package/dist/resources/extensions/gsd/auto/infra-errors.js +34 -0
  24. package/dist/resources/extensions/gsd/auto/loop.js +32 -1
  25. package/dist/resources/extensions/gsd/auto/phases.js +5 -1
  26. package/dist/resources/extensions/gsd/auto/session.js +11 -0
  27. package/dist/resources/extensions/gsd/auto-dashboard.js +22 -16
  28. package/dist/resources/extensions/gsd/auto-model-selection.js +10 -2
  29. package/dist/resources/extensions/gsd/auto-prompts.js +88 -33
  30. package/dist/resources/extensions/gsd/auto-start.js +37 -18
  31. package/dist/resources/extensions/gsd/auto-tool-tracking.js +1 -1
  32. package/dist/resources/extensions/gsd/auto-worktree.js +1 -1
  33. package/dist/resources/extensions/gsd/auto.js +56 -0
  34. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +3 -3
  35. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +6 -0
  36. package/dist/resources/extensions/gsd/bootstrap/register-shortcuts.js +63 -51
  37. package/dist/resources/extensions/gsd/bootstrap/system-context.js +6 -0
  38. package/dist/resources/extensions/gsd/commands/context.js +15 -6
  39. package/dist/resources/extensions/gsd/commands/dispatcher.js +12 -2
  40. package/dist/resources/extensions/gsd/commands/handlers/auto.js +10 -33
  41. package/dist/resources/extensions/gsd/commands/handlers/core.js +56 -11
  42. package/dist/resources/extensions/gsd/commands/handlers/notifications-handler.js +15 -6
  43. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +4 -10
  44. package/dist/resources/extensions/gsd/custom-workflow-engine.js +16 -12
  45. package/dist/resources/extensions/gsd/dashboard-overlay.js +8 -3
  46. package/dist/resources/extensions/gsd/dispatch-guard.js +18 -1
  47. package/dist/resources/extensions/gsd/doctor-providers.js +23 -0
  48. package/dist/resources/extensions/gsd/error-classifier.js +5 -2
  49. package/dist/resources/extensions/gsd/file-lock.js +60 -0
  50. package/dist/resources/extensions/gsd/forensics.js +19 -6
  51. package/dist/resources/extensions/gsd/gate-registry.js +208 -0
  52. package/dist/resources/extensions/gsd/gsd-db.js +41 -0
  53. package/dist/resources/extensions/gsd/guided-flow.js +17 -20
  54. package/dist/resources/extensions/gsd/init-wizard.js +3 -11
  55. package/dist/resources/extensions/gsd/metrics.js +1 -0
  56. package/dist/resources/extensions/gsd/milestone-actions.js +10 -4
  57. package/dist/resources/extensions/gsd/milestone-validation-gates.js +11 -12
  58. package/dist/resources/extensions/gsd/notification-overlay.js +42 -13
  59. package/dist/resources/extensions/gsd/notification-store.js +56 -5
  60. package/dist/resources/extensions/gsd/notification-widget.js +5 -13
  61. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +8 -3
  62. package/dist/resources/extensions/gsd/pre-execution-checks.js +35 -2
  63. package/dist/resources/extensions/gsd/prompt-validation.js +126 -0
  64. package/dist/resources/extensions/gsd/prompts/complete-slice.md +5 -3
  65. package/dist/resources/extensions/gsd/prompts/discuss.md +33 -13
  66. package/dist/resources/extensions/gsd/prompts/execute-task.md +22 -19
  67. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  68. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
  69. package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/queue.md +3 -2
  71. package/dist/resources/extensions/gsd/prompts/system.md +1 -0
  72. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
  73. package/dist/resources/extensions/gsd/session-model-override.js +25 -0
  74. package/dist/resources/extensions/gsd/shortcut-defs.js +40 -0
  75. package/dist/resources/extensions/gsd/state.js +241 -332
  76. package/dist/resources/extensions/gsd/tools/complete-slice.js +52 -1
  77. package/dist/resources/extensions/gsd/tools/complete-task.js +51 -1
  78. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +38 -1
  79. package/dist/resources/extensions/gsd/workflow-events.js +25 -13
  80. package/dist/resources/extensions/gsd/workflow-mcp-auto-prep.js +56 -0
  81. package/dist/resources/extensions/gsd/workflow-mcp.js +1 -1
  82. package/dist/resources/extensions/ollama/index.js +13 -5
  83. package/dist/resources/extensions/shared/gsd-phase-state.js +35 -0
  84. package/dist/resources/extensions/subagent/agents.js +8 -0
  85. package/dist/resources/extensions/subagent/index.js +17 -0
  86. package/dist/resources/skills/create-skill/SKILL.md +2 -0
  87. package/dist/startup-model-validation.d.ts +0 -1
  88. package/dist/startup-model-validation.js +6 -2
  89. package/dist/web/standalone/.next/BUILD_ID +1 -1
  90. package/dist/web/standalone/.next/app-path-routes-manifest.json +19 -19
  91. package/dist/web/standalone/.next/build-manifest.json +4 -4
  92. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  93. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  94. package/dist/web/standalone/.next/required-server-files.json +4 -4
  95. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  96. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  106. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  108. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  109. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  110. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  112. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  122. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/experimental/route.js +2 -2
  134. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  154. package/dist/web/standalone/.next/server/app/api/notifications/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +2 -2
  164. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  170. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  186. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  190. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/index.html +1 -1
  200. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  201. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  202. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  203. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  205. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app/page.js +2 -2
  207. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  208. package/dist/web/standalone/.next/server/app-paths-manifest.json +19 -19
  209. package/dist/web/standalone/.next/server/chunks/63.js +3 -3
  210. package/dist/web/standalone/.next/server/chunks/6897.js +1 -1
  211. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  213. package/dist/web/standalone/.next/server/middleware.js +2 -2
  214. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  215. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  216. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  217. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  218. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  219. package/dist/web/standalone/.next/static/chunks/2826.dd3dc8bbd3025fa5.js +9 -0
  220. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  221. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  222. package/dist/web/standalone/.next/static/chunks/app/page-f1e30ab6bb269149.js +1 -0
  223. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  224. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/{webpack-6e4d7e9a4f57bed4.js → webpack-b868033a5834586d.js} +1 -1
  226. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  227. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  228. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  229. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  230. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  231. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  232. package/dist/web/standalone/server.js +1 -1
  233. package/package.json +1 -1
  234. package/packages/mcp-server/dist/env-writer.d.ts +39 -0
  235. package/packages/mcp-server/dist/env-writer.d.ts.map +1 -0
  236. package/packages/mcp-server/dist/env-writer.js +158 -0
  237. package/packages/mcp-server/dist/env-writer.js.map +1 -0
  238. package/packages/mcp-server/dist/server.d.ts +23 -3
  239. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  240. package/packages/mcp-server/dist/server.js +192 -44
  241. package/packages/mcp-server/dist/server.js.map +1 -1
  242. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  243. package/packages/mcp-server/dist/workflow-tools.js +22 -12
  244. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  245. package/packages/mcp-server/src/env-writer.test.ts +280 -0
  246. package/packages/mcp-server/src/env-writer.ts +183 -0
  247. package/packages/mcp-server/src/secure-env-collect.test.ts +265 -0
  248. package/packages/mcp-server/src/server.ts +247 -41
  249. package/packages/mcp-server/src/workflow-tools.test.ts +110 -0
  250. package/packages/mcp-server/src/workflow-tools.ts +32 -12
  251. package/packages/pi-ai/dist/providers/amazon-bedrock.js +11 -2
  252. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  253. package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts +2 -0
  254. package/packages/pi-ai/dist/providers/anthropic-auth.test.d.ts.map +1 -0
  255. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +20 -0
  256. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -0
  257. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +4 -1
  258. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  259. package/packages/pi-ai/dist/providers/anthropic-shared.js +8 -3
  260. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  261. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +44 -1
  262. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
  263. package/packages/pi-ai/dist/providers/anthropic.d.ts +2 -1
  264. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  265. package/packages/pi-ai/dist/providers/anthropic.js +7 -4
  266. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  267. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  268. package/packages/pi-ai/dist/providers/openai-completions.js +11 -0
  269. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  270. package/packages/pi-ai/src/providers/amazon-bedrock.ts +13 -1
  271. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +32 -0
  272. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +55 -1
  273. package/packages/pi-ai/src/providers/anthropic-shared.ts +14 -3
  274. package/packages/pi-ai/src/providers/anthropic.ts +8 -4
  275. package/packages/pi-ai/src/providers/openai-completions.ts +14 -0
  276. package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts +2 -0
  277. package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.d.ts.map +1 -0
  278. package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js +61 -0
  279. package/packages/pi-coding-agent/dist/core/agent-session-renderable-tools.test.js.map +1 -0
  280. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/agent-session.js +2 -1
  282. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +10 -0
  284. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/auth-storage.js +27 -0
  286. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +85 -0
  288. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.d.ts +2 -0
  290. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.d.ts.map +1 -0
  291. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +388 -0
  292. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -0
  293. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +2 -0
  294. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts +2 -0
  297. package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.d.ts.map +1 -0
  298. package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js +64 -0
  299. package/packages/pi-coding-agent/dist/core/model-resolver-initial-model-auth.test.js.map +1 -0
  300. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  301. package/packages/pi-coding-agent/dist/core/model-resolver.js +22 -18
  302. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts +8 -0
  304. package/packages/pi-coding-agent/dist/core/model-resolver.test.d.ts.map +1 -0
  305. package/packages/pi-coding-agent/dist/core/model-resolver.test.js +75 -0
  306. package/packages/pi-coding-agent/dist/core/model-resolver.test.js.map +1 -0
  307. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts +5 -0
  308. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/retry-handler.js +55 -1
  310. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +57 -0
  312. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/core/sdk.d.ts +11 -0
  314. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  315. package/packages/pi-coding-agent/dist/core/sdk.js +38 -5
  316. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/core/sdk.test.d.ts +2 -0
  318. package/packages/pi-coding-agent/dist/core/sdk.test.d.ts.map +1 -0
  319. package/packages/pi-coding-agent/dist/core/sdk.test.js +71 -0
  320. package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -0
  321. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  322. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/index.js +1 -1
  324. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts +2 -0
  326. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.d.ts.map +1 -0
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js +13 -0
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/login-dialog.test.js.map +1 -0
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts +19 -2
  330. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.d.ts.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js +50 -1
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts +1 -0
  334. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  335. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js +1 -0
  336. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-input.js.map +1 -1
  337. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +4 -0
  338. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  339. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +24 -2
  340. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  341. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  342. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +9 -2
  343. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +4 -0
  345. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  346. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +43 -0
  347. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  349. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +175 -25
  350. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  351. package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.d.ts.map +1 -1
  352. package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js +6 -1
  353. package/packages/pi-coding-agent/dist/modes/interactive/controllers/model-controller.js.map +1 -1
  354. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
  355. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  356. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  357. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +6 -0
  358. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  359. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +62 -5
  360. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  361. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +4 -2
  362. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  363. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +1 -1
  364. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  365. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +1 -0
  366. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  367. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  368. package/packages/pi-coding-agent/package.json +1 -1
  369. package/packages/pi-coding-agent/src/core/agent-session-renderable-tools.test.ts +70 -0
  370. package/packages/pi-coding-agent/src/core/agent-session.ts +2 -1
  371. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +108 -0
  372. package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -0
  373. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +468 -0
  374. package/packages/pi-coding-agent/src/core/extensions/types.ts +2 -0
  375. package/packages/pi-coding-agent/src/core/model-resolver-initial-model-auth.test.ts +78 -0
  376. package/packages/pi-coding-agent/src/core/model-resolver.test.ts +85 -0
  377. package/packages/pi-coding-agent/src/core/model-resolver.ts +22 -18
  378. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +83 -0
  379. package/packages/pi-coding-agent/src/core/retry-handler.ts +60 -1
  380. package/packages/pi-coding-agent/src/core/sdk.test.ts +89 -0
  381. package/packages/pi-coding-agent/src/core/sdk.ts +45 -9
  382. package/packages/pi-coding-agent/src/index.ts +1 -0
  383. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/login-dialog.test.ts +24 -0
  384. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.ts +58 -2
  385. package/packages/pi-coding-agent/src/modes/interactive/components/extension-input.ts +2 -0
  386. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +30 -2
  387. package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +15 -6
  388. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +47 -0
  389. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +205 -31
  390. package/packages/pi-coding-agent/src/modes/interactive/controllers/model-controller.ts +6 -1
  391. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -0
  392. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +70 -5
  393. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +4 -2
  394. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +1 -1
  395. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +1 -0
  396. package/packages/pi-tui/dist/components/__tests__/input.test.js +9 -0
  397. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  398. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.d.ts +2 -0
  399. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.d.ts.map +1 -0
  400. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +66 -0
  401. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -0
  402. package/packages/pi-tui/dist/components/input.d.ts +2 -0
  403. package/packages/pi-tui/dist/components/input.d.ts.map +1 -1
  404. package/packages/pi-tui/dist/components/input.js +7 -4
  405. package/packages/pi-tui/dist/components/input.js.map +1 -1
  406. package/packages/pi-tui/dist/components/markdown.d.ts +3 -0
  407. package/packages/pi-tui/dist/components/markdown.d.ts.map +1 -1
  408. package/packages/pi-tui/dist/components/markdown.js +17 -1
  409. package/packages/pi-tui/dist/components/markdown.js.map +1 -1
  410. package/packages/pi-tui/src/components/__tests__/input.test.ts +11 -0
  411. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +75 -0
  412. package/packages/pi-tui/src/components/input.ts +7 -4
  413. package/packages/pi-tui/src/components/markdown.ts +22 -1
  414. package/pkg/package.json +1 -1
  415. package/src/resources/GSD-WORKFLOW.md +1 -1
  416. package/src/resources/agents/debugger.md +58 -0
  417. package/src/resources/agents/doc-writer.md +43 -0
  418. package/src/resources/agents/git-ops.md +56 -0
  419. package/src/resources/agents/javascript-pro.md +46 -271
  420. package/src/resources/agents/planner.md +55 -0
  421. package/src/resources/agents/refactorer.md +47 -0
  422. package/src/resources/agents/reviewer.md +48 -0
  423. package/src/resources/agents/security.md +59 -0
  424. package/src/resources/agents/tester.md +50 -0
  425. package/src/resources/agents/typescript-pro.md +41 -235
  426. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +288 -39
  427. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +330 -2
  428. package/src/resources/extensions/get-secrets-from-user.ts +24 -1
  429. package/src/resources/extensions/gsd/auto/infra-errors.ts +38 -0
  430. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -0
  431. package/src/resources/extensions/gsd/auto/loop.ts +45 -1
  432. package/src/resources/extensions/gsd/auto/phases.ts +6 -0
  433. package/src/resources/extensions/gsd/auto/session.ts +11 -0
  434. package/src/resources/extensions/gsd/auto-dashboard.ts +29 -18
  435. package/src/resources/extensions/gsd/auto-model-selection.ts +9 -1
  436. package/src/resources/extensions/gsd/auto-prompts.ts +111 -33
  437. package/src/resources/extensions/gsd/auto-start.ts +44 -20
  438. package/src/resources/extensions/gsd/auto-tool-tracking.ts +1 -1
  439. package/src/resources/extensions/gsd/auto-worktree.ts +1 -1
  440. package/src/resources/extensions/gsd/auto.ts +72 -0
  441. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +3 -3
  442. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +6 -0
  443. package/src/resources/extensions/gsd/bootstrap/register-shortcuts.ts +79 -60
  444. package/src/resources/extensions/gsd/bootstrap/system-context.ts +7 -0
  445. package/src/resources/extensions/gsd/commands/context.ts +16 -5
  446. package/src/resources/extensions/gsd/commands/dispatcher.ts +14 -2
  447. package/src/resources/extensions/gsd/commands/handlers/auto.ts +10 -36
  448. package/src/resources/extensions/gsd/commands/handlers/core.ts +58 -11
  449. package/src/resources/extensions/gsd/commands/handlers/notifications-handler.ts +17 -7
  450. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +4 -10
  451. package/src/resources/extensions/gsd/custom-workflow-engine.ts +19 -14
  452. package/src/resources/extensions/gsd/dashboard-overlay.ts +10 -3
  453. package/src/resources/extensions/gsd/dispatch-guard.ts +18 -1
  454. package/src/resources/extensions/gsd/doctor-providers.ts +24 -0
  455. package/src/resources/extensions/gsd/error-classifier.ts +5 -2
  456. package/src/resources/extensions/gsd/file-lock.ts +59 -0
  457. package/src/resources/extensions/gsd/forensics.ts +23 -7
  458. package/src/resources/extensions/gsd/gate-registry.ts +251 -0
  459. package/src/resources/extensions/gsd/gsd-db.ts +51 -0
  460. package/src/resources/extensions/gsd/guided-flow.ts +17 -19
  461. package/src/resources/extensions/gsd/init-wizard.ts +3 -13
  462. package/src/resources/extensions/gsd/interrupted-session.ts +1 -0
  463. package/src/resources/extensions/gsd/metrics.ts +12 -1
  464. package/src/resources/extensions/gsd/milestone-actions.ts +10 -3
  465. package/src/resources/extensions/gsd/milestone-validation-gates.ts +11 -13
  466. package/src/resources/extensions/gsd/notification-overlay.ts +47 -14
  467. package/src/resources/extensions/gsd/notification-store.ts +54 -5
  468. package/src/resources/extensions/gsd/notification-widget.ts +5 -14
  469. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +10 -3
  470. package/src/resources/extensions/gsd/pre-execution-checks.ts +39 -2
  471. package/src/resources/extensions/gsd/prompt-validation.ts +157 -0
  472. package/src/resources/extensions/gsd/prompts/complete-slice.md +5 -3
  473. package/src/resources/extensions/gsd/prompts/discuss.md +33 -13
  474. package/src/resources/extensions/gsd/prompts/execute-task.md +22 -19
  475. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  476. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +2 -0
  477. package/src/resources/extensions/gsd/prompts/guided-resume-task.md +1 -1
  478. package/src/resources/extensions/gsd/prompts/queue.md +3 -2
  479. package/src/resources/extensions/gsd/prompts/system.md +1 -0
  480. package/src/resources/extensions/gsd/prompts/validate-milestone.md +4 -1
  481. package/src/resources/extensions/gsd/session-model-override.ts +36 -0
  482. package/src/resources/extensions/gsd/shortcut-defs.ts +56 -0
  483. package/src/resources/extensions/gsd/state.ts +285 -344
  484. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +25 -9
  485. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +28 -0
  486. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +39 -0
  487. package/src/resources/extensions/gsd/tests/complete-slice-gate-closure.test.ts +167 -0
  488. package/src/resources/extensions/gsd/tests/complete-slice-prompt-task-summary-layout.test.ts +18 -0
  489. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +436 -0
  490. package/src/resources/extensions/gsd/tests/discuss-incremental-persistence.test.ts +9 -0
  491. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  492. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +36 -0
  493. package/src/resources/extensions/gsd/tests/execute-task-prompt-existing-artifact-guard.test.ts +33 -0
  494. package/src/resources/extensions/gsd/tests/file-lock.test.ts +103 -0
  495. package/src/resources/extensions/gsd/tests/forensics-stuck-loops.test.ts +62 -0
  496. package/src/resources/extensions/gsd/tests/format-shortcut.test.ts +31 -0
  497. package/src/resources/extensions/gsd/tests/gate-dispatch.test.ts +27 -0
  498. package/src/resources/extensions/gsd/tests/gate-registry.test.ts +140 -0
  499. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +73 -0
  500. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +180 -0
  501. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +66 -1
  502. package/src/resources/extensions/gsd/tests/model-isolation.test.ts +36 -51
  503. package/src/resources/extensions/gsd/tests/notification-store.test.ts +35 -0
  504. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +26 -0
  505. package/src/resources/extensions/gsd/tests/notifications-handler.test.ts +90 -0
  506. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +1 -0
  507. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +18 -0
  508. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +49 -0
  509. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +19 -0
  510. package/src/resources/extensions/gsd/tests/prompt-system-gate-coverage.test.ts +208 -0
  511. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +16 -0
  512. package/src/resources/extensions/gsd/tests/register-shortcuts.test.ts +63 -5
  513. package/src/resources/extensions/gsd/tests/secure-env-collect.test.ts +45 -0
  514. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +35 -0
  515. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +90 -0
  516. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +7 -0
  517. package/src/resources/extensions/gsd/tests/validate-milestone-prompt-verification-classes.test.ts +18 -0
  518. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +76 -0
  519. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +155 -1
  520. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +22 -0
  521. package/src/resources/extensions/gsd/tools/complete-slice.ts +63 -0
  522. package/src/resources/extensions/gsd/tools/complete-task.ts +63 -0
  523. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +64 -26
  524. package/src/resources/extensions/gsd/types.ts +26 -0
  525. package/src/resources/extensions/gsd/workflow-events.ts +34 -25
  526. package/src/resources/extensions/gsd/workflow-mcp-auto-prep.ts +76 -0
  527. package/src/resources/extensions/gsd/workflow-mcp.ts +1 -1
  528. package/src/resources/extensions/ollama/index.ts +13 -3
  529. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +28 -0
  530. package/src/resources/extensions/shared/gsd-phase-state.ts +42 -0
  531. package/src/resources/extensions/shared/tests/gsd-phase-state.test.ts +48 -0
  532. package/src/resources/extensions/subagent/agents.ts +10 -0
  533. package/src/resources/extensions/subagent/index.ts +18 -0
  534. package/src/resources/extensions/subagent/tests/agents-conflicts.test.ts +33 -0
  535. package/src/resources/skills/create-skill/SKILL.md +2 -0
  536. package/dist/web/standalone/.next/static/chunks/2826.821e01b07d92e948.js +0 -9
  537. package/dist/web/standalone/.next/static/chunks/app/page-7115e62689b5fd84.js +0 -1
  538. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  539. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  540. /package/dist/web/standalone/.next/static/{9pw9EXtXjdM7EFrCXUEPf → hnGGkVMxIGGpxSJkf5jIV}/_buildManifest.js +0 -0
  541. /package/dist/web/standalone/.next/static/{9pw9EXtXjdM7EFrCXUEPf → hnGGkVMxIGGpxSJkf5jIV}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../../src/core/model-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model resolution, scoping, and initial selection\n */\n\nimport type { ThinkingLevel } from \"@gsd/pi-agent-core\";\nimport { type Api, type KnownProvider, type Model, modelsAreEqual } from \"@gsd/pi-ai\";\nimport chalk from \"chalk\";\nimport { minimatch } from \"minimatch\";\nimport { isValidThinkingLevel } from \"../cli/args.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\n\n/** Default model IDs for each known provider */\nconst defaultModelPerProvider: Record<KnownProvider, string> = {\n\t\"amazon-bedrock\": \"us.anthropic.claude-opus-4-6-v1\",\n\tanthropic: \"claude-opus-4-6\",\n\t\"anthropic-vertex\": \"claude-sonnet-4-6\",\n\topenai: \"gpt-5.4\",\n\t\"azure-openai-responses\": \"gpt-5.2\",\n\t\"openai-codex\": \"gpt-5.4\",\n\tgoogle: \"gemini-2.5-pro\",\n\t\"google-gemini-cli\": \"gemini-2.5-pro\",\n\t\"google-antigravity\": \"gemini-3.1-pro-high\",\n\t\"google-vertex\": \"gemini-3-pro-preview\",\n\t\"github-copilot\": \"gpt-4o\",\n\topenrouter: \"openai/gpt-5.1-codex\",\n\t\"vercel-ai-gateway\": \"anthropic/claude-opus-4-6\",\n\txai: \"grok-4-fast-non-reasoning\",\n\tgroq: \"openai/gpt-oss-120b\",\n\tcerebras: \"zai-glm-4.6\",\n\tzai: \"glm-4.6\",\n\tmistral: \"devstral-medium-latest\",\n\tminimax: \"MiniMax-M2.1\",\n\t\"minimax-cn\": \"MiniMax-M2.1\",\n\thuggingface: \"moonshotai/Kimi-K2.5\",\n\topencode: \"claude-opus-4-6\",\n\t\"opencode-go\": \"kimi-k2.5\",\n\t\"kimi-coding\": \"kimi-k2-thinking\",\n\t\"alibaba-coding-plan\": \"qwen3.5-plus\",\n\tollama: \"llama3.1:8b\",\n\t\"ollama-cloud\": \"qwen3:32b\",\n};\n\nexport interface ScopedModel {\n\tmodel: Model<Api>;\n\t/** Thinking level if explicitly specified in pattern (e.g., \"model:high\"), undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n}\n\n/**\n * Helper to check if a model ID looks like an alias (no date suffix)\n * Dates are typically in format: -20241022 or -20250929\n */\nfunction isAlias(id: string): boolean {\n\t// Check if ID ends with -latest\n\tif (id.endsWith(\"-latest\")) return true;\n\n\t// Check if ID ends with a date pattern (-YYYYMMDD)\n\tconst datePattern = /-\\d{8}$/;\n\treturn !datePattern.test(id);\n}\n\n/**\n * Try to match a pattern to a model from the available models list.\n * Returns the matched model or undefined if no match found.\n */\nfunction tryMatchModel(modelPattern: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\t// Check for provider/modelId format (provider is everything before the first /)\n\tconst slashIndex = modelPattern.indexOf(\"/\");\n\tif (slashIndex !== -1) {\n\t\tconst provider = modelPattern.substring(0, slashIndex);\n\t\tconst modelId = modelPattern.substring(slashIndex + 1);\n\t\tconst providerMatch = availableModels.find(\n\t\t\t(m) => m.provider.toLowerCase() === provider.toLowerCase() && m.id.toLowerCase() === modelId.toLowerCase(),\n\t\t);\n\t\tif (providerMatch) {\n\t\t\treturn providerMatch;\n\t\t}\n\t\t// No exact provider/model match - fall through to other matching\n\t}\n\n\t// Check for exact ID match (case-insensitive)\n\tconst exactMatch = availableModels.find((m) => m.id.toLowerCase() === modelPattern.toLowerCase());\n\tif (exactMatch) {\n\t\treturn exactMatch;\n\t}\n\n\t// No exact match - fall back to partial matching\n\tconst matches = availableModels.filter(\n\t\t(m) =>\n\t\t\tm.id.toLowerCase().includes(modelPattern.toLowerCase()) ||\n\t\t\tm.name?.toLowerCase().includes(modelPattern.toLowerCase()),\n\t);\n\n\tif (matches.length === 0) {\n\t\treturn undefined;\n\t}\n\n\t// Separate into aliases and dated versions\n\tconst aliases = matches.filter((m) => isAlias(m.id));\n\tconst datedVersions = matches.filter((m) => !isAlias(m.id));\n\n\tif (aliases.length > 0) {\n\t\t// Prefer alias - if multiple aliases, pick the one that sorts highest\n\t\taliases.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn aliases[0];\n\t} else {\n\t\t// No alias found, pick latest dated version\n\t\tdatedVersions.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn datedVersions[0];\n\t}\n}\n\nexport interface ParsedModelResult {\n\tmodel: Model<Api> | undefined;\n\t/** Thinking level if explicitly specified in pattern, undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n}\n\nfunction buildFallbackModel(provider: string, modelId: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst providerModels = availableModels.filter((m) => m.provider === provider);\n\tif (providerModels.length === 0) return undefined;\n\n\tconst defaultId = defaultModelPerProvider[provider as KnownProvider];\n\tconst baseModel = defaultId\n\t\t? (providerModels.find((m) => m.id === defaultId) ?? providerModels[0])\n\t\t: providerModels[0];\n\n\treturn {\n\t\t...baseModel,\n\t\tid: modelId,\n\t\tname: modelId,\n\t};\n}\n\n/**\n * Parse a pattern to extract model and thinking level.\n * Handles models with colons in their IDs (e.g., OpenRouter's :exacto suffix).\n *\n * Algorithm:\n * 1. Try to match full pattern as a model\n * 2. If found, return it with \"off\" thinking level\n * 3. If not found and has colons, split on last colon:\n * - If suffix is valid thinking level, use it and recurse on prefix\n * - If suffix is invalid, warn and recurse on prefix with \"off\"\n *\n * @internal\n */\nfunction parseModelPattern(\n\tpattern: string,\n\tavailableModels: Model<Api>[],\n\toptions?: { allowInvalidThinkingLevelFallback?: boolean },\n): ParsedModelResult {\n\t// Try exact match first\n\tconst exactMatch = tryMatchModel(pattern, availableModels);\n\tif (exactMatch) {\n\t\treturn { model: exactMatch, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\t// No match - try splitting on last colon if present\n\tconst lastColonIndex = pattern.lastIndexOf(\":\");\n\tif (lastColonIndex === -1) {\n\t\t// No colons, pattern simply doesn't match any model\n\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\tconst prefix = pattern.substring(0, lastColonIndex);\n\tconst suffix = pattern.substring(lastColonIndex + 1);\n\n\tif (isValidThinkingLevel(suffix)) {\n\t\t// Valid thinking level - recurse on prefix and use this level\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\t// Only use this thinking level if no warning from inner recursion\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: result.warning ? undefined : suffix,\n\t\t\t\twarning: result.warning,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t} else {\n\t\t// Invalid suffix\n\t\tconst allowFallback = options?.allowInvalidThinkingLevelFallback ?? true;\n\t\tif (!allowFallback) {\n\t\t\t// In strict mode (CLI --model parsing), treat it as part of the model id and fail.\n\t\t\t// This avoids accidentally resolving to a different model.\n\t\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t\t}\n\n\t\t// Scope mode: recurse on prefix and warn\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: undefined,\n\t\t\t\twarning: `Invalid thinking level \"${suffix}\" in pattern \"${pattern}\". Using default instead.`,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Resolve model patterns to actual Model objects with optional thinking levels\n * Format: \"pattern:level\" where :level is optional\n * For each pattern, finds all matching models and picks the best version:\n * 1. Prefer alias (e.g., claude-sonnet-4-5) over dated versions (claude-sonnet-4-5-20250929)\n * 2. If no alias, pick the latest dated version\n *\n * Supports models with colons in their IDs (e.g., OpenRouter's model:exacto).\n * The algorithm tries to match the full pattern first, then progressively\n * strips colon-suffixes to find a match.\n */\nexport async function resolveModelScope(patterns: string[], modelRegistry: ModelRegistry): Promise<ScopedModel[]> {\n\tconst availableModels = await modelRegistry.getAvailable();\n\tconst scopedModels: ScopedModel[] = [];\n\n\tfor (const pattern of patterns) {\n\t\t// Try exact match first (handles model IDs containing glob chars like [1m])\n\t\tconst exactResult = parseModelPattern(pattern, availableModels);\n\t\tif (exactResult.model) {\n\t\t\tif (exactResult.warning) {\n\t\t\t\tconsole.warn(chalk.yellow(`Warning: ${exactResult.warning}`));\n\t\t\t}\n\t\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, exactResult.model!))) {\n\t\t\t\tscopedModels.push({ model: exactResult.model, thinkingLevel: exactResult.thinkingLevel });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check if pattern contains glob characters\n\t\tif (pattern.includes(\"*\") || pattern.includes(\"?\") || pattern.includes(\"[\")) {\n\t\t\t// Extract optional thinking level suffix (e.g., \"provider/*:high\")\n\t\t\tconst colonIdx = pattern.lastIndexOf(\":\");\n\t\t\tlet globPattern = pattern;\n\t\t\tlet thinkingLevel: ThinkingLevel | undefined;\n\n\t\t\tif (colonIdx !== -1) {\n\t\t\t\tconst suffix = pattern.substring(colonIdx + 1);\n\t\t\t\tif (isValidThinkingLevel(suffix)) {\n\t\t\t\t\tthinkingLevel = suffix;\n\t\t\t\t\tglobPattern = pattern.substring(0, colonIdx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Match against \"provider/modelId\" format OR just model ID\n\t\t\t// This allows \"*sonnet*\" to match without requiring \"anthropic/*sonnet*\"\n\t\t\tconst matchingModels = availableModels.filter((m) => {\n\t\t\t\tconst fullId = `${m.provider}/${m.id}`;\n\t\t\t\treturn minimatch(fullId, globPattern, { nocase: true }) || minimatch(m.id, globPattern, { nocase: true });\n\t\t\t});\n\n\t\t\tif (matchingModels.length === 0) {\n\t\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const model of matchingModels) {\n\t\t\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, availableModels);\n\n\t\tif (warning) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: ${warning}`));\n\t\t}\n\n\t\tif (!model) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Avoid duplicates\n\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t}\n\t}\n\n\treturn scopedModels;\n}\n\nexport interface ResolveCliModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n\t/**\n\t * Error message suitable for CLI display.\n\t * When set, model will be undefined.\n\t */\n\terror: string | undefined;\n}\n\n/**\n * Resolve a single model from CLI flags.\n *\n * Supports:\n * - --provider <provider> --model <pattern>\n * - --model <provider>/<pattern>\n * - Fuzzy matching (same rules as model scoping: exact id, then partial id/name)\n *\n * Note: This does not apply the thinking level by itself, but it may *parse* and\n * return a thinking level from \"<pattern>:<thinking>\" so the caller can apply it.\n */\nexport function resolveCliModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tmodelRegistry: ModelRegistry;\n}): ResolveCliModelResult {\n\tconst { cliProvider, cliModel, modelRegistry } = options;\n\n\tif (!cliModel) {\n\t\treturn { model: undefined, warning: undefined, error: undefined };\n\t}\n\n\t// Important: use *all* models here, not just models with pre-configured auth.\n\t// This allows \"--api-key\" to be used for first-time setup.\n\tconst availableModels = modelRegistry.getAll();\n\tif (availableModels.length === 0) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: \"No models available. Check your installation or add models to models.json.\",\n\t\t};\n\t}\n\n\t// Build canonical provider lookup (case-insensitive)\n\tconst providerMap = new Map<string, string>();\n\tfor (const m of availableModels) {\n\t\tproviderMap.set(m.provider.toLowerCase(), m.provider);\n\t}\n\n\tlet provider = cliProvider ? providerMap.get(cliProvider.toLowerCase()) : undefined;\n\tif (cliProvider && !provider) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: `Unknown provider \"${cliProvider}\". Use --list-models to see available providers/models.`,\n\t\t};\n\t}\n\n\t// If no explicit --provider, try to interpret \"provider/model\" format first.\n\t// When the prefix before the first slash matches a known provider, prefer that\n\t// interpretation over matching models whose IDs literally contain slashes\n\t// (e.g. \"zai/glm-5\" should resolve to provider=zai, model=glm-5, not to a\n\t// vercel-ai-gateway model with id \"zai/glm-5\").\n\tlet pattern = cliModel;\n\tlet inferredProvider = false;\n\n\tif (!provider) {\n\t\tconst slashIndex = cliModel.indexOf(\"/\");\n\t\tif (slashIndex !== -1) {\n\t\t\tconst maybeProvider = cliModel.substring(0, slashIndex);\n\t\t\tconst canonical = providerMap.get(maybeProvider.toLowerCase());\n\t\t\tif (canonical) {\n\t\t\t\tprovider = canonical;\n\t\t\t\tpattern = cliModel.substring(slashIndex + 1);\n\t\t\t\tinferredProvider = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// If no provider was inferred from the slash, try exact matches without provider inference.\n\t// This handles models whose IDs naturally contain slashes (e.g. OpenRouter-style IDs).\n\tif (!provider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t}\n\n\tif (cliProvider && provider) {\n\t\t// If both were provided, tolerate --model <provider>/<pattern> by stripping the provider prefix\n\t\tconst prefix = `${provider}/`;\n\t\tif (cliModel.toLowerCase().startsWith(prefix.toLowerCase())) {\n\t\t\tpattern = cliModel.substring(prefix.length);\n\t\t}\n\t}\n\n\tconst candidates = provider ? availableModels.filter((m) => m.provider === provider) : availableModels;\n\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, candidates, {\n\t\tallowInvalidThinkingLevelFallback: false,\n\t});\n\n\tif (model) {\n\t\treturn { model, thinkingLevel, warning, error: undefined };\n\t}\n\n\t// If we inferred a provider from the slash but found no match within that provider,\n\t// fall back to matching the full input as a raw model id across all models.\n\t// This handles OpenRouter-style IDs like \"openai/gpt-4o:extended\" where \"openai\"\n\t// looks like a provider but the full string is actually a model id on openrouter.\n\tif (inferredProvider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t\t// Also try parseModelPattern on the full input against all models\n\t\tconst fallback = parseModelPattern(cliModel, availableModels, {\n\t\t\tallowInvalidThinkingLevelFallback: false,\n\t\t});\n\t\tif (fallback.model) {\n\t\t\treturn {\n\t\t\t\tmodel: fallback.model,\n\t\t\t\tthinkingLevel: fallback.thinkingLevel,\n\t\t\t\twarning: fallback.warning,\n\t\t\t\terror: undefined,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (provider) {\n\t\tconst fallbackModel = buildFallbackModel(provider, pattern, availableModels);\n\t\tif (fallbackModel) {\n\t\t\tconst fallbackWarning = warning\n\t\t\t\t? `${warning} Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`\n\t\t\t\t: `Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`;\n\t\t\treturn { model: fallbackModel, thinkingLevel: undefined, warning: fallbackWarning, error: undefined };\n\t\t}\n\t}\n\n\tconst display = provider ? `${provider}/${pattern}` : cliModel;\n\treturn {\n\t\tmodel: undefined,\n\t\tthinkingLevel: undefined,\n\t\twarning,\n\t\terror: `Model \"${display}\" not found. Use --list-models to see available models.`,\n\t};\n}\n\nexport interface InitialModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel: ThinkingLevel;\n\tfallbackMessage: string | undefined;\n}\n\n/**\n * Find the initial model to use based on priority:\n * 1. CLI args (provider + model)\n * 2. First model from scoped models (if not continuing/resuming)\n * 3. Restored from session (if continuing/resuming)\n * 4. Saved default from settings\n * 5. First available model with valid API key\n */\nexport async function findInitialModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tscopedModels: ScopedModel[];\n\tisContinuing: boolean;\n\tdefaultProvider?: string;\n\tdefaultModelId?: string;\n\tdefaultThinkingLevel?: ThinkingLevel;\n\tmodelRegistry: ModelRegistry;\n}): Promise<InitialModelResult> {\n\tconst {\n\t\tcliProvider,\n\t\tcliModel,\n\t\tscopedModels,\n\t\tisContinuing,\n\t\tdefaultProvider,\n\t\tdefaultModelId,\n\t\tdefaultThinkingLevel,\n\t\tmodelRegistry,\n\t} = options;\n\n\tlet model: Model<Api> | undefined;\n\tlet thinkingLevel: ThinkingLevel = DEFAULT_THINKING_LEVEL;\n\n\t// 1. CLI args take priority\n\tif (cliProvider && cliModel) {\n\t\tconst resolved = resolveCliModel({\n\t\t\tcliProvider,\n\t\t\tcliModel,\n\t\t\tmodelRegistry,\n\t\t});\n\t\tif (resolved.error) {\n\t\t\tconsole.error(chalk.red(resolved.error));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (resolved.model) {\n\t\t\treturn { model: resolved.model, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 2. Use first model from scoped models (skip if continuing/resuming)\n\tif (scopedModels.length > 0 && !isContinuing) {\n\t\treturn {\n\t\t\tmodel: scopedModels[0].model,\n\t\t\tthinkingLevel: scopedModels[0].thinkingLevel ?? defaultThinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\tfallbackMessage: undefined,\n\t\t};\n\t}\n\n\t// 3. Try saved default from settings\n\tif (defaultProvider && defaultModelId) {\n\t\tconst found = modelRegistry.find(defaultProvider, defaultModelId);\n\t\tif (found) {\n\t\t\t// Check if the provider's recommended default is a higher-capability variant\n\t\t\t// of the saved model (e.g. saved \"claude-opus-4-6\" vs recommended \"claude-opus-4-6-extended\").\n\t\t\t// If so, prefer the recommended variant to avoid using a smaller context window (#1125).\n\t\t\tconst recommendedId = defaultModelPerProvider[defaultProvider as KnownProvider];\n\t\t\tif (recommendedId && recommendedId !== defaultModelId && recommendedId.startsWith(defaultModelId)) {\n\t\t\t\tconst recommended = modelRegistry.find(defaultProvider, recommendedId);\n\t\t\t\tif (recommended) {\n\t\t\t\t\tmodel = recommended;\n\t\t\t\t\tif (defaultThinkingLevel) {\n\t\t\t\t\t\tthinkingLevel = defaultThinkingLevel;\n\t\t\t\t\t}\n\t\t\t\t\treturn { model, thinkingLevel, fallbackMessage: undefined };\n\t\t\t\t}\n\t\t\t}\n\t\t\tmodel = found;\n\t\t\tif (defaultThinkingLevel) {\n\t\t\t\tthinkingLevel = defaultThinkingLevel;\n\t\t\t}\n\t\t\treturn { model, thinkingLevel, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 4. Try first available model with valid API key\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\treturn { model: match, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\treturn { model: availableModels[0], thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t}\n\n\t// 5. No model found\n\treturn { model: undefined, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n}\n"]}
1
+ {"version":3,"file":"model-resolver.js","sourceRoot":"","sources":["../../src/core/model-resolver.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Model resolution, scoping, and initial selection\n */\n\nimport type { ThinkingLevel } from \"@gsd/pi-agent-core\";\nimport { type Api, type KnownProvider, type Model, modelsAreEqual } from \"@gsd/pi-ai\";\nimport chalk from \"chalk\";\nimport { minimatch } from \"minimatch\";\nimport { isValidThinkingLevel } from \"../cli/args.js\";\nimport { DEFAULT_THINKING_LEVEL } from \"./defaults.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\n\n/** Default model IDs for each known provider */\nconst defaultModelPerProvider: Record<KnownProvider, string> = {\n\t\"amazon-bedrock\": \"us.anthropic.claude-opus-4-6-v1\",\n\tanthropic: \"claude-opus-4-6\",\n\t\"anthropic-vertex\": \"claude-sonnet-4-6\",\n\topenai: \"gpt-5.4\",\n\t\"azure-openai-responses\": \"gpt-5.2\",\n\t\"openai-codex\": \"gpt-5.4\",\n\tgoogle: \"gemini-2.5-pro\",\n\t\"google-gemini-cli\": \"gemini-2.5-pro\",\n\t\"google-antigravity\": \"gemini-3.1-pro-high\",\n\t\"google-vertex\": \"gemini-3-pro-preview\",\n\t\"github-copilot\": \"gpt-4o\",\n\topenrouter: \"openai/gpt-5.1-codex\",\n\t\"vercel-ai-gateway\": \"anthropic/claude-opus-4-6\",\n\txai: \"grok-4-fast-non-reasoning\",\n\tgroq: \"openai/gpt-oss-120b\",\n\tcerebras: \"zai-glm-4.6\",\n\tzai: \"glm-4.6\",\n\tmistral: \"devstral-medium-latest\",\n\tminimax: \"MiniMax-M2.1\",\n\t\"minimax-cn\": \"MiniMax-M2.1\",\n\thuggingface: \"moonshotai/Kimi-K2.5\",\n\topencode: \"claude-opus-4-6\",\n\t\"opencode-go\": \"kimi-k2.5\",\n\t\"kimi-coding\": \"kimi-k2-thinking\",\n\t\"alibaba-coding-plan\": \"qwen3.5-plus\",\n\tollama: \"llama3.1:8b\",\n\t\"ollama-cloud\": \"qwen3:32b\",\n};\n\nexport interface ScopedModel {\n\tmodel: Model<Api>;\n\t/** Thinking level if explicitly specified in pattern (e.g., \"model:high\"), undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n}\n\n/**\n * Helper to check if a model ID looks like an alias (no date suffix)\n * Dates are typically in format: -20241022 or -20250929\n */\nfunction isAlias(id: string): boolean {\n\t// Check if ID ends with -latest\n\tif (id.endsWith(\"-latest\")) return true;\n\n\t// Check if ID ends with a date pattern (-YYYYMMDD)\n\tconst datePattern = /-\\d{8}$/;\n\treturn !datePattern.test(id);\n}\n\n/**\n * Try to match a pattern to a model from the available models list.\n * Returns the matched model or undefined if no match found.\n */\nfunction tryMatchModel(modelPattern: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\t// Check for provider/modelId format (provider is everything before the first /)\n\tconst slashIndex = modelPattern.indexOf(\"/\");\n\tif (slashIndex !== -1) {\n\t\tconst provider = modelPattern.substring(0, slashIndex);\n\t\tconst modelId = modelPattern.substring(slashIndex + 1);\n\t\tconst providerMatch = availableModels.find(\n\t\t\t(m) => m.provider.toLowerCase() === provider.toLowerCase() && m.id.toLowerCase() === modelId.toLowerCase(),\n\t\t);\n\t\tif (providerMatch) {\n\t\t\treturn providerMatch;\n\t\t}\n\t\t// No exact provider/model match - fall through to other matching\n\t}\n\n\t// Check for exact ID match (case-insensitive)\n\tconst exactMatch = availableModels.find((m) => m.id.toLowerCase() === modelPattern.toLowerCase());\n\tif (exactMatch) {\n\t\treturn exactMatch;\n\t}\n\n\t// No exact match - fall back to partial matching\n\tconst matches = availableModels.filter(\n\t\t(m) =>\n\t\t\tm.id.toLowerCase().includes(modelPattern.toLowerCase()) ||\n\t\t\tm.name?.toLowerCase().includes(modelPattern.toLowerCase()),\n\t);\n\n\tif (matches.length === 0) {\n\t\treturn undefined;\n\t}\n\n\t// Separate into aliases and dated versions\n\tconst aliases = matches.filter((m) => isAlias(m.id));\n\tconst datedVersions = matches.filter((m) => !isAlias(m.id));\n\n\tif (aliases.length > 0) {\n\t\t// Prefer alias - if multiple aliases, pick the one that sorts highest\n\t\taliases.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn aliases[0];\n\t} else {\n\t\t// No alias found, pick latest dated version\n\t\tdatedVersions.sort((a, b) => b.id.localeCompare(a.id));\n\t\treturn datedVersions[0];\n\t}\n}\n\nexport interface ParsedModelResult {\n\tmodel: Model<Api> | undefined;\n\t/** Thinking level if explicitly specified in pattern, undefined otherwise */\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n}\n\nfunction buildFallbackModel(provider: string, modelId: string, availableModels: Model<Api>[]): Model<Api> | undefined {\n\tconst providerModels = availableModels.filter((m) => m.provider === provider);\n\tif (providerModels.length === 0) return undefined;\n\n\tconst defaultId = defaultModelPerProvider[provider as KnownProvider];\n\tconst baseModel = defaultId\n\t\t? (providerModels.find((m) => m.id === defaultId) ?? providerModels[0])\n\t\t: providerModels[0];\n\n\treturn {\n\t\t...baseModel,\n\t\tid: modelId,\n\t\tname: modelId,\n\t};\n}\n\n/**\n * Parse a pattern to extract model and thinking level.\n * Handles models with colons in their IDs (e.g., OpenRouter's :exacto suffix).\n *\n * Algorithm:\n * 1. Try to match full pattern as a model\n * 2. If found, return it with \"off\" thinking level\n * 3. If not found and has colons, split on last colon:\n * - If suffix is valid thinking level, use it and recurse on prefix\n * - If suffix is invalid, warn and recurse on prefix with \"off\"\n *\n * @internal\n */\nfunction parseModelPattern(\n\tpattern: string,\n\tavailableModels: Model<Api>[],\n\toptions?: { allowInvalidThinkingLevelFallback?: boolean },\n): ParsedModelResult {\n\t// Try exact match first\n\tconst exactMatch = tryMatchModel(pattern, availableModels);\n\tif (exactMatch) {\n\t\treturn { model: exactMatch, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\t// No match - try splitting on last colon if present\n\tconst lastColonIndex = pattern.lastIndexOf(\":\");\n\tif (lastColonIndex === -1) {\n\t\t// No colons, pattern simply doesn't match any model\n\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t}\n\n\tconst prefix = pattern.substring(0, lastColonIndex);\n\tconst suffix = pattern.substring(lastColonIndex + 1);\n\n\tif (isValidThinkingLevel(suffix)) {\n\t\t// Valid thinking level - recurse on prefix and use this level\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\t// Only use this thinking level if no warning from inner recursion\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: result.warning ? undefined : suffix,\n\t\t\t\twarning: result.warning,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t} else {\n\t\t// Invalid suffix\n\t\tconst allowFallback = options?.allowInvalidThinkingLevelFallback ?? true;\n\t\tif (!allowFallback) {\n\t\t\t// In strict mode (CLI --model parsing), treat it as part of the model id and fail.\n\t\t\t// This avoids accidentally resolving to a different model.\n\t\t\treturn { model: undefined, thinkingLevel: undefined, warning: undefined };\n\t\t}\n\n\t\t// Scope mode: recurse on prefix and warn\n\t\tconst result = parseModelPattern(prefix, availableModels, options);\n\t\tif (result.model) {\n\t\t\treturn {\n\t\t\t\tmodel: result.model,\n\t\t\t\tthinkingLevel: undefined,\n\t\t\t\twarning: `Invalid thinking level \"${suffix}\" in pattern \"${pattern}\". Using default instead.`,\n\t\t\t};\n\t\t}\n\t\treturn result;\n\t}\n}\n\n/**\n * Resolve model patterns to actual Model objects with optional thinking levels\n * Format: \"pattern:level\" where :level is optional\n * For each pattern, finds all matching models and picks the best version:\n * 1. Prefer alias (e.g., claude-sonnet-4-5) over dated versions (claude-sonnet-4-5-20250929)\n * 2. If no alias, pick the latest dated version\n *\n * Supports models with colons in their IDs (e.g., OpenRouter's model:exacto).\n * The algorithm tries to match the full pattern first, then progressively\n * strips colon-suffixes to find a match.\n */\nexport async function resolveModelScope(patterns: string[], modelRegistry: ModelRegistry): Promise<ScopedModel[]> {\n\tconst availableModels = await modelRegistry.getAvailable();\n\tconst scopedModels: ScopedModel[] = [];\n\n\tfor (const pattern of patterns) {\n\t\t// Try exact match first (handles model IDs containing glob chars like [1m])\n\t\tconst exactResult = parseModelPattern(pattern, availableModels);\n\t\tif (exactResult.model) {\n\t\t\tif (exactResult.warning) {\n\t\t\t\tconsole.warn(chalk.yellow(`Warning: ${exactResult.warning}`));\n\t\t\t}\n\t\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, exactResult.model!))) {\n\t\t\t\tscopedModels.push({ model: exactResult.model, thinkingLevel: exactResult.thinkingLevel });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Check if pattern contains glob characters\n\t\tif (pattern.includes(\"*\") || pattern.includes(\"?\") || pattern.includes(\"[\")) {\n\t\t\t// Extract optional thinking level suffix (e.g., \"provider/*:high\")\n\t\t\tconst colonIdx = pattern.lastIndexOf(\":\");\n\t\t\tlet globPattern = pattern;\n\t\t\tlet thinkingLevel: ThinkingLevel | undefined;\n\n\t\t\tif (colonIdx !== -1) {\n\t\t\t\tconst suffix = pattern.substring(colonIdx + 1);\n\t\t\t\tif (isValidThinkingLevel(suffix)) {\n\t\t\t\t\tthinkingLevel = suffix;\n\t\t\t\t\tglobPattern = pattern.substring(0, colonIdx);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Match against \"provider/modelId\" format OR just model ID\n\t\t\t// This allows \"*sonnet*\" to match without requiring \"anthropic/*sonnet*\"\n\t\t\tconst matchingModels = availableModels.filter((m) => {\n\t\t\t\tconst fullId = `${m.provider}/${m.id}`;\n\t\t\t\treturn minimatch(fullId, globPattern, { nocase: true }) || minimatch(m.id, globPattern, { nocase: true });\n\t\t\t});\n\n\t\t\tif (matchingModels.length === 0) {\n\t\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tfor (const model of matchingModels) {\n\t\t\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t\t\t}\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, availableModels);\n\n\t\tif (warning) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: ${warning}`));\n\t\t}\n\n\t\tif (!model) {\n\t\t\tconsole.warn(chalk.yellow(`Warning: No models match pattern \"${pattern}\"`));\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Avoid duplicates\n\t\tif (!scopedModels.find((sm) => modelsAreEqual(sm.model, model))) {\n\t\t\tscopedModels.push({ model, thinkingLevel });\n\t\t}\n\t}\n\n\treturn scopedModels;\n}\n\nexport interface ResolveCliModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel?: ThinkingLevel;\n\twarning: string | undefined;\n\t/**\n\t * Error message suitable for CLI display.\n\t * When set, model will be undefined.\n\t */\n\terror: string | undefined;\n}\n\n/**\n * Resolve a single model from CLI flags.\n *\n * Supports:\n * - --provider <provider> --model <pattern>\n * - --model <provider>/<pattern>\n * - Fuzzy matching (same rules as model scoping: exact id, then partial id/name)\n *\n * Note: This does not apply the thinking level by itself, but it may *parse* and\n * return a thinking level from \"<pattern>:<thinking>\" so the caller can apply it.\n */\nexport function resolveCliModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tmodelRegistry: ModelRegistry;\n}): ResolveCliModelResult {\n\tconst { cliProvider, cliModel, modelRegistry } = options;\n\n\tif (!cliModel) {\n\t\treturn { model: undefined, warning: undefined, error: undefined };\n\t}\n\n\t// Important: use *all* models here, not just models with pre-configured auth.\n\t// This allows \"--api-key\" to be used for first-time setup.\n\tconst availableModels = modelRegistry.getAll();\n\tif (availableModels.length === 0) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: \"No models available. Check your installation or add models to models.json.\",\n\t\t};\n\t}\n\n\t// Build canonical provider lookup (case-insensitive)\n\tconst providerMap = new Map<string, string>();\n\tfor (const m of availableModels) {\n\t\tproviderMap.set(m.provider.toLowerCase(), m.provider);\n\t}\n\n\tlet provider = cliProvider ? providerMap.get(cliProvider.toLowerCase()) : undefined;\n\tif (cliProvider && !provider) {\n\t\treturn {\n\t\t\tmodel: undefined,\n\t\t\twarning: undefined,\n\t\t\terror: `Unknown provider \"${cliProvider}\". Use --list-models to see available providers/models.`,\n\t\t};\n\t}\n\n\t// If no explicit --provider, try to interpret \"provider/model\" format first.\n\t// When the prefix before the first slash matches a known provider, prefer that\n\t// interpretation over matching models whose IDs literally contain slashes\n\t// (e.g. \"zai/glm-5\" should resolve to provider=zai, model=glm-5, not to a\n\t// vercel-ai-gateway model with id \"zai/glm-5\").\n\tlet pattern = cliModel;\n\tlet inferredProvider = false;\n\n\tif (!provider) {\n\t\tconst slashIndex = cliModel.indexOf(\"/\");\n\t\tif (slashIndex !== -1) {\n\t\t\tconst maybeProvider = cliModel.substring(0, slashIndex);\n\t\t\tconst canonical = providerMap.get(maybeProvider.toLowerCase());\n\t\t\tif (canonical) {\n\t\t\t\tprovider = canonical;\n\t\t\t\tpattern = cliModel.substring(slashIndex + 1);\n\t\t\t\tinferredProvider = true;\n\t\t\t}\n\t\t}\n\t}\n\n\t// If no provider was inferred from the slash, try exact matches without provider inference.\n\t// This handles models whose IDs naturally contain slashes (e.g. OpenRouter-style IDs).\n\tif (!provider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t}\n\n\tif (cliProvider && provider) {\n\t\t// If both were provided, tolerate --model <provider>/<pattern> by stripping the provider prefix\n\t\tconst prefix = `${provider}/`;\n\t\tif (cliModel.toLowerCase().startsWith(prefix.toLowerCase())) {\n\t\t\tpattern = cliModel.substring(prefix.length);\n\t\t}\n\t}\n\n\tconst candidates = provider ? availableModels.filter((m) => m.provider === provider) : availableModels;\n\tconst { model, thinkingLevel, warning } = parseModelPattern(pattern, candidates, {\n\t\tallowInvalidThinkingLevelFallback: false,\n\t});\n\n\tif (model) {\n\t\treturn { model, thinkingLevel, warning, error: undefined };\n\t}\n\n\t// If we inferred a provider from the slash but found no match within that provider,\n\t// fall back to matching the full input as a raw model id across all models.\n\t// This handles OpenRouter-style IDs like \"openai/gpt-4o:extended\" where \"openai\"\n\t// looks like a provider but the full string is actually a model id on openrouter.\n\tif (inferredProvider) {\n\t\tconst lower = cliModel.toLowerCase();\n\t\tconst exact = availableModels.find(\n\t\t\t(m) => m.id.toLowerCase() === lower || `${m.provider}/${m.id}`.toLowerCase() === lower,\n\t\t);\n\t\tif (exact) {\n\t\t\treturn { model: exact, warning: undefined, thinkingLevel: undefined, error: undefined };\n\t\t}\n\t\t// Also try parseModelPattern on the full input against all models\n\t\tconst fallback = parseModelPattern(cliModel, availableModels, {\n\t\t\tallowInvalidThinkingLevelFallback: false,\n\t\t});\n\t\tif (fallback.model) {\n\t\t\treturn {\n\t\t\t\tmodel: fallback.model,\n\t\t\t\tthinkingLevel: fallback.thinkingLevel,\n\t\t\t\twarning: fallback.warning,\n\t\t\t\terror: undefined,\n\t\t\t};\n\t\t}\n\t}\n\n\tif (provider) {\n\t\tconst fallbackModel = buildFallbackModel(provider, pattern, availableModels);\n\t\tif (fallbackModel) {\n\t\t\tconst fallbackWarning = warning\n\t\t\t\t? `${warning} Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`\n\t\t\t\t: `Model \"${pattern}\" not found for provider \"${provider}\". Using custom model id.`;\n\t\t\treturn { model: fallbackModel, thinkingLevel: undefined, warning: fallbackWarning, error: undefined };\n\t\t}\n\t}\n\n\tconst display = provider ? `${provider}/${pattern}` : cliModel;\n\treturn {\n\t\tmodel: undefined,\n\t\tthinkingLevel: undefined,\n\t\twarning,\n\t\terror: `Model \"${display}\" not found. Use --list-models to see available models.`,\n\t};\n}\n\nexport interface InitialModelResult {\n\tmodel: Model<Api> | undefined;\n\tthinkingLevel: ThinkingLevel;\n\tfallbackMessage: string | undefined;\n}\n\n/**\n * Find the initial model to use based on priority:\n * 1. CLI args (provider + model)\n * 2. First model from scoped models (if not continuing/resuming)\n * 3. Restored from session (if continuing/resuming)\n * 4. Saved default from settings\n * 5. First available model with valid API key\n */\nexport async function findInitialModel(options: {\n\tcliProvider?: string;\n\tcliModel?: string;\n\tscopedModels: ScopedModel[];\n\tisContinuing: boolean;\n\tdefaultProvider?: string;\n\tdefaultModelId?: string;\n\tdefaultThinkingLevel?: ThinkingLevel;\n\tmodelRegistry: ModelRegistry;\n}): Promise<InitialModelResult> {\n\tconst {\n\t\tcliProvider,\n\t\tcliModel,\n\t\tscopedModels,\n\t\tisContinuing,\n\t\tdefaultProvider,\n\t\tdefaultModelId,\n\t\tdefaultThinkingLevel,\n\t\tmodelRegistry,\n\t} = options;\n\n\tlet model: Model<Api> | undefined;\n\tlet thinkingLevel: ThinkingLevel = DEFAULT_THINKING_LEVEL;\n\n\t// 1. CLI args take priority\n\tif (cliProvider && cliModel) {\n\t\tconst resolved = resolveCliModel({\n\t\t\tcliProvider,\n\t\t\tcliModel,\n\t\t\tmodelRegistry,\n\t\t});\n\t\tif (resolved.error) {\n\t\t\tconsole.error(chalk.red(resolved.error));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tif (resolved.model) {\n\t\t\treturn { model: resolved.model, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t}\n\t}\n\n\t// 2. Use first model from scoped models (skip if continuing/resuming)\n\tif (scopedModels.length > 0 && !isContinuing) {\n\t\treturn {\n\t\t\tmodel: scopedModels[0].model,\n\t\t\tthinkingLevel: scopedModels[0].thinkingLevel ?? defaultThinkingLevel ?? DEFAULT_THINKING_LEVEL,\n\t\t\tfallbackMessage: undefined,\n\t\t};\n\t}\n\n\t// 3. Try saved default from settings\n\tif (defaultProvider && defaultModelId) {\n\t\t// Guard against stale settings defaults: only use the saved provider/model\n\t\t// if the provider is actually request-ready (auth/OAuth/CLI ready).\n\t\tif (modelRegistry.isProviderRequestReady(defaultProvider)) {\n\t\t\tconst found = modelRegistry.find(defaultProvider, defaultModelId);\n\t\t\tif (found) {\n\t\t\t\t// Check if the provider's recommended default is a higher-capability variant\n\t\t\t\t// of the saved model (e.g. saved \"claude-opus-4-6\" vs recommended \"claude-opus-4-6-extended\").\n\t\t\t\t// If so, prefer the recommended variant to avoid using a smaller context window (#1125).\n\t\t\t\tconst recommendedId = defaultModelPerProvider[defaultProvider as KnownProvider];\n\t\t\t\tif (recommendedId && recommendedId !== defaultModelId && recommendedId.startsWith(defaultModelId)) {\n\t\t\t\t\tconst recommended = modelRegistry.find(defaultProvider, recommendedId);\n\t\t\t\t\tif (recommended) {\n\t\t\t\t\t\tmodel = recommended;\n\t\t\t\t\t\tif (defaultThinkingLevel) {\n\t\t\t\t\t\t\tthinkingLevel = defaultThinkingLevel;\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn { model, thinkingLevel, fallbackMessage: undefined };\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tmodel = found;\n\t\t\t\tif (defaultThinkingLevel) {\n\t\t\t\t\tthinkingLevel = defaultThinkingLevel;\n\t\t\t\t}\n\t\t\t\treturn { model, thinkingLevel, fallbackMessage: undefined };\n\t\t\t}\n\t\t}\n\t}\n\n\t// 4. Try first available model with valid API key\n\tconst availableModels = await modelRegistry.getAvailable();\n\n\tif (availableModels.length > 0) {\n\t\t// Try to find a default model from known providers\n\t\tfor (const provider of Object.keys(defaultModelPerProvider) as KnownProvider[]) {\n\t\t\tconst defaultId = defaultModelPerProvider[provider];\n\t\t\tconst match = availableModels.find((m) => m.provider === provider && m.id === defaultId);\n\t\t\tif (match) {\n\t\t\t\treturn { model: match, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t\t\t}\n\t\t}\n\n\t\t// If no default found, use first available\n\t\treturn { model: availableModels[0], thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n\t}\n\n\t// 5. No model found\n\treturn { model: undefined, thinkingLevel: DEFAULT_THINKING_LEVEL, fallbackMessage: undefined };\n}\n"]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Regression test for the #unconfigured-models fix: findInitialModel() must
3
+ * skip the saved default when its provider has no working auth, rather than
4
+ * returning an unusable model that every selector surface would display as
5
+ * "current".
6
+ */
7
+ export {};
8
+ //# sourceMappingURL=model-resolver.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-resolver.test.d.ts","sourceRoot":"","sources":["../../src/core/model-resolver.test.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Regression test for the #unconfigured-models fix: findInitialModel() must
3
+ * skip the saved default when its provider has no working auth, rather than
4
+ * returning an unusable model that every selector surface would display as
5
+ * "current".
6
+ */
7
+ import test from "node:test";
8
+ import assert from "node:assert/strict";
9
+ import { findInitialModel } from "./model-resolver.js";
10
+ function fakeRegistry(options) {
11
+ const fullModels = options.models.map((m) => ({
12
+ ...m,
13
+ name: m.id,
14
+ api: "anthropic-messages",
15
+ baseUrl: "",
16
+ reasoning: false,
17
+ input: ["text"],
18
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
19
+ contextWindow: 128_000,
20
+ maxTokens: 4096,
21
+ }));
22
+ const available = fullModels.filter((m) => options.readyProviders.has(m.provider));
23
+ return {
24
+ find(provider, id) {
25
+ return fullModels.find((m) => m.provider === provider && m.id === id);
26
+ },
27
+ getAvailable() {
28
+ return available;
29
+ },
30
+ isProviderRequestReady(provider) {
31
+ return options.readyProviders.has(provider);
32
+ },
33
+ };
34
+ }
35
+ test("findInitialModel skips saved default when provider has no auth", async () => {
36
+ // User saved xai/grok-4 as default, but XAI_API_KEY is unset so xai is
37
+ // in the registry but not ready. Previously findInitialModel() step 3
38
+ // returned xai anyway — now it must fall through to step 4 and pick
39
+ // an available model.
40
+ const registry = fakeRegistry({
41
+ models: [
42
+ { provider: "xai", id: "grok-4-fast-non-reasoning" },
43
+ { provider: "anthropic", id: "claude-opus-4-6" },
44
+ ],
45
+ readyProviders: new Set(["anthropic"]),
46
+ });
47
+ const result = await findInitialModel({
48
+ scopedModels: [],
49
+ isContinuing: false,
50
+ defaultProvider: "xai",
51
+ defaultModelId: "grok-4-fast-non-reasoning",
52
+ modelRegistry: registry,
53
+ });
54
+ assert.ok(result.model, "a model must be returned");
55
+ assert.equal(result.model.provider, "anthropic", "unauth'd saved default must be skipped");
56
+ });
57
+ test("findInitialModel keeps saved default when provider has auth", async () => {
58
+ const registry = fakeRegistry({
59
+ models: [
60
+ { provider: "anthropic", id: "claude-opus-4-6" },
61
+ { provider: "openai", id: "gpt-5.4" },
62
+ ],
63
+ readyProviders: new Set(["anthropic", "openai"]),
64
+ });
65
+ const result = await findInitialModel({
66
+ scopedModels: [],
67
+ isContinuing: false,
68
+ defaultProvider: "openai",
69
+ defaultModelId: "gpt-5.4",
70
+ modelRegistry: registry,
71
+ });
72
+ assert.equal(result.model?.provider, "openai");
73
+ assert.equal(result.model?.id, "gpt-5.4");
74
+ });
75
+ //# sourceMappingURL=model-resolver.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-resolver.test.js","sourceRoot":"","sources":["../../src/core/model-resolver.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Regression test for the #unconfigured-models fix: findInitialModel() must\n * skip the saved default when its provider has no working auth, rather than\n * returning an unusable model that every selector surface would display as\n * \"current\".\n */\n\nimport test from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { findInitialModel } from \"./model-resolver.js\";\n\nfunction fakeRegistry(options: {\n\tmodels: Array<{ provider: string; id: string }>;\n\treadyProviders: Set<string>;\n}) {\n\tconst fullModels = options.models.map((m) => ({\n\t\t...m,\n\t\tname: m.id,\n\t\tapi: \"anthropic-messages\",\n\t\tbaseUrl: \"\",\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: 128_000,\n\t\tmaxTokens: 4096,\n\t}));\n\tconst available = fullModels.filter((m) => options.readyProviders.has(m.provider));\n\treturn {\n\t\tfind(provider: string, id: string) {\n\t\t\treturn fullModels.find((m) => m.provider === provider && m.id === id);\n\t\t},\n\t\tgetAvailable() {\n\t\t\treturn available;\n\t\t},\n\t\tisProviderRequestReady(provider: string) {\n\t\t\treturn options.readyProviders.has(provider);\n\t\t},\n\t};\n}\n\ntest(\"findInitialModel skips saved default when provider has no auth\", async () => {\n\t// User saved xai/grok-4 as default, but XAI_API_KEY is unset so xai is\n\t// in the registry but not ready. Previously findInitialModel() step 3\n\t// returned xai anyway — now it must fall through to step 4 and pick\n\t// an available model.\n\tconst registry = fakeRegistry({\n\t\tmodels: [\n\t\t\t{ provider: \"xai\", id: \"grok-4-fast-non-reasoning\" },\n\t\t\t{ provider: \"anthropic\", id: \"claude-opus-4-6\" },\n\t\t],\n\t\treadyProviders: new Set([\"anthropic\"]),\n\t});\n\n\tconst result = await findInitialModel({\n\t\tscopedModels: [],\n\t\tisContinuing: false,\n\t\tdefaultProvider: \"xai\",\n\t\tdefaultModelId: \"grok-4-fast-non-reasoning\",\n\t\tmodelRegistry: registry as any,\n\t});\n\n\tassert.ok(result.model, \"a model must be returned\");\n\tassert.equal(result.model!.provider, \"anthropic\", \"unauth'd saved default must be skipped\");\n});\n\ntest(\"findInitialModel keeps saved default when provider has auth\", async () => {\n\tconst registry = fakeRegistry({\n\t\tmodels: [\n\t\t\t{ provider: \"anthropic\", id: \"claude-opus-4-6\" },\n\t\t\t{ provider: \"openai\", id: \"gpt-5.4\" },\n\t\t],\n\t\treadyProviders: new Set([\"anthropic\", \"openai\"]),\n\t});\n\n\tconst result = await findInitialModel({\n\t\tscopedModels: [],\n\t\tisContinuing: false,\n\t\tdefaultProvider: \"openai\",\n\t\tdefaultModelId: \"gpt-5.4\",\n\t\tmodelRegistry: registry as any,\n\t});\n\n\tassert.equal(result.model?.provider, \"openai\");\n\tassert.equal(result.model?.id, \"gpt-5.4\");\n});\n"]}
@@ -87,6 +87,11 @@ export declare class RetryHandler {
87
87
  * Classify an error message into a usage-limit error type for credential backoff.
88
88
  */
89
89
  private _classifyErrorType;
90
+ /**
91
+ * Attempt a same-model retry by reducing maxTokens when provider reports
92
+ * an affordability cap (e.g., "can only afford 329").
93
+ */
94
+ private _tryAffordableMaxTokensRetry;
90
95
  /**
91
96
  * Attempt to downgrade a long-context model (e.g. claude-opus-4-6[1m]) to its
92
97
  * base model (claude-opus-4-6) when the account lacks the long-context billing
@@ -1 +1 @@
1
- {"version":3,"file":"retry-handler.d.ts","sourceRoot":"","sources":["../../src/core/retry-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAG1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,gEAAgE;AAChE,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACvC,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,IAAI,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACzC,iEAAiE;IACjE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAC3C;mEAC+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC;CAClC;AAED,qBAAa,YAAY;IAQZ,OAAO,CAAC,QAAQ,CAAC,KAAK;IAPlC,OAAO,CAAC,qBAAqB,CAA0C;IACvE,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,gBAAgB,CAAwD;gBAEnD,KAAK,EAAE,gBAAgB;IAEpD,gDAAgD;IAChD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,kDAAkD;IAClD,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,oCAAoC;IACpC,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED,gCAAgC;IAChC,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI3C;;;;OAIG;IACH,6BAA6B,CAAC,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI;IAc5F;;;OAGG;IACH,wBAAwB,IAAI,IAAI;IAYhC;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;IAiBpD;;;;;OAKG;IACG,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IAoMvE,+BAA+B;IAC/B,UAAU,IAAI,IAAI;IA2BlB;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAMnC,wCAAwC;IACxC,YAAY,IAAI,IAAI;IAQpB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,4BAA4B;IAYpC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAW1B;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAqChC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAsC9B,+DAA+D;IAC/D,OAAO,CAAC,yBAAyB;CAMjC"}
1
+ {"version":3,"file":"retry-handler.d.ts","sourceRoot":"","sources":["../../src/core/retry-handler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAG1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAE5D,gEAAgE;AAChE,MAAM,WAAW,gBAAgB;IAChC,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;IAC1C,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;IAC5C,QAAQ,EAAE,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,SAAS,CAAC;IACvC,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,IAAI,EAAE,CAAC,KAAK,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACzC,iEAAiE;IACjE,aAAa,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IAC3C;mEAC+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC;CAClC;AAED,qBAAa,YAAY;IAQZ,OAAO,CAAC,QAAQ,CAAC,KAAK;IAPlC,OAAO,CAAC,qBAAqB,CAA0C;IACvE,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,aAAa,CAAuC;IAC5D,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,gBAAgB,CAAwD;gBAEnD,KAAK,EAAE,gBAAgB;IAEpD,gDAAgD;IAChD,IAAI,YAAY,IAAI,MAAM,CAEzB;IAED,kDAAkD;IAClD,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,oCAAoC;IACpC,IAAI,gBAAgB,IAAI,OAAO,CAE9B;IAED,gCAAgC;IAChC,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAI3C;;;;OAIG;IACH,6BAA6B,CAAC,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,IAAI;IAc5F;;;OAGG;IACH,wBAAwB,IAAI,IAAI;IAYhC;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;IAiBpD;;;;;OAKG;IACG,oBAAoB,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;IA4MvE,+BAA+B;IAC/B,UAAU,IAAI,IAAI;IA2BlB;;;OAGG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAMnC,wCAAwC;IACxC,YAAY,IAAI,IAAI;IAQpB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,4BAA4B;IAYpC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAa1B;;;OAGG;IACH,OAAO,CAAC,4BAA4B;IA6CpC;;;;OAIG;IACH,OAAO,CAAC,wBAAwB;IAqChC;;;;;OAKG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;;;OAIG;IACH,OAAO,CAAC,sBAAsB;IAsC9B,+DAA+D;IAC/D,OAAO,CAAC,yBAAyB;CAMjC"}
@@ -85,7 +85,7 @@ export class RetryHandler {
85
85
  // generated error from getApiKey() when credentials are in a backoff window.
86
86
  // Re-entering the retry handler for that message creates a cascade of empty
87
87
  // error entries in the session file, breaking resume (#3429).
88
- return /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay|network.?(?:is\s+)?unavailable|credentials.*expired|extra usage is required|(?:out of|no) extra usage|third.party.*draw from extra|third.party.*not.*available/i.test(err);
88
+ return /overloaded|rate.?limit|too many requests|402|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay|network.?(?:is\s+)?unavailable|credentials.*expired|requires more credits|can only afford|insufficient credits|not enough credits|extra usage is required|(?:out of|no) extra usage|third.party.*draw from extra|third.party.*not.*available/i.test(err);
89
89
  }
90
90
  /**
91
91
  * Handle retryable errors with exponential backoff.
@@ -121,6 +121,14 @@ export class RetryHandler {
121
121
  const errorType = this._classifyErrorType(message.errorMessage);
122
122
  const isRateLimit = errorType === "rate_limit";
123
123
  const isQuotaError = errorType === "quota_exhausted";
124
+ // Credit-aware retry (OpenRouter-style 402 affordability errors):
125
+ // when provider reports "can only afford N", lower maxTokens and retry
126
+ // on the same model before rotating credentials/providers.
127
+ if (isQuotaError) {
128
+ const adjusted = this._tryAffordableMaxTokensRetry(message, retryGeneration);
129
+ if (adjusted)
130
+ return true;
131
+ }
124
132
  // Credential rotation — only for transient rate limits (#3430).
125
133
  // Quota errors ("Extra usage is required") are account-level billing
126
134
  // gates; rotating to another credential on the same account won't help
@@ -338,6 +346,8 @@ export class RetryHandler {
338
346
  // Must be checked before the generic 429/rate_limit regex.
339
347
  if (/extra usage is required|long context required/i.test(err))
340
348
  return "quota_exhausted";
349
+ if (/requires more credits|can only afford|insufficient credits|not enough credits|credit balance/i.test(err))
350
+ return "quota_exhausted";
341
351
  if (/quota|billing|exceeded.*limit|usage.*limit/i.test(err))
342
352
  return "quota_exhausted";
343
353
  if (/rate.?limit|too many requests|429/i.test(err))
@@ -346,6 +356,50 @@ export class RetryHandler {
346
356
  return "server_error";
347
357
  return "unknown";
348
358
  }
359
+ /**
360
+ * Attempt a same-model retry by reducing maxTokens when provider reports
361
+ * an affordability cap (e.g., "can only afford 329").
362
+ */
363
+ _tryAffordableMaxTokensRetry(message, retryGeneration) {
364
+ const currentModel = this._deps.getModel();
365
+ if (!currentModel || !message.errorMessage)
366
+ return false;
367
+ // Example: "can only afford 329"
368
+ const match = message.errorMessage.match(/can only afford\s+([\d,]+)/i);
369
+ if (!match?.[1])
370
+ return false;
371
+ const affordable = Number.parseInt(match[1].replace(/,/g, ""), 10);
372
+ if (!Number.isFinite(affordable) || affordable <= 0)
373
+ return false;
374
+ // Leave a small buffer so slight input variance doesn't immediately re-fail.
375
+ const safetyBuffer = Math.min(64, Math.max(16, Math.floor(affordable * 0.1)));
376
+ const targetMaxTokens = Math.max(64, affordable - safetyBuffer);
377
+ const downgradedMaxTokens = Math.min(currentModel.maxTokens, targetMaxTokens);
378
+ if (downgradedMaxTokens >= currentModel.maxTokens)
379
+ return false;
380
+ const downgradedModel = {
381
+ ...currentModel,
382
+ maxTokens: downgradedMaxTokens,
383
+ };
384
+ this._deps.agent.setModel(downgradedModel);
385
+ this._deps.onModelChange(downgradedModel);
386
+ this._removeLastAssistantError();
387
+ this._deps.emit({
388
+ type: "fallback_provider_switch",
389
+ from: `${currentModel.provider}/${currentModel.id} (maxTokens=${currentModel.maxTokens})`,
390
+ to: `${downgradedModel.provider}/${downgradedModel.id} (maxTokens=${downgradedModel.maxTokens})`,
391
+ reason: `credit-aware retry: provider affordable cap ${affordable} tokens`,
392
+ });
393
+ this._deps.emit({
394
+ type: "auto_retry_start",
395
+ attempt: this._retryAttempt + 1,
396
+ maxAttempts: this._deps.settingsManager.getRetrySettings().maxRetries,
397
+ delayMs: 0,
398
+ errorMessage: `${message.errorMessage} (reducing max tokens)`,
399
+ });
400
+ this._scheduleContinue(retryGeneration);
401
+ return true;
402
+ }
349
403
  /**
350
404
  * Attempt to downgrade a long-context model (e.g. claude-opus-4-6[1m]) to its
351
405
  * base model (claude-opus-4-6) when the account lacks the long-context billing
@@ -1 +1 @@
1
- {"version":3,"file":"retry-handler.js","sourceRoot":"","sources":["../../src/core/retry-handler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RetryHandler - Automatic retry logic with exponential backoff and credential/provider fallback.\n *\n * Handles retryable errors (overloaded, rate limit, server errors) by:\n * 1. Trying alternate credentials for the same provider\n * 2. Falling back to other providers via FallbackResolver\n * 3. Exponential backoff with configurable max retries\n *\n * Context overflow errors are NOT handled here (see compaction).\n */\n\nimport type { Agent } from \"@gsd/pi-agent-core\";\nimport type { AssistantMessage, Model } from \"@gsd/pi-ai\";\nimport { isContextOverflow } from \"@gsd/pi-ai\";\nimport type { UsageLimitErrorType } from \"./auth-storage.js\";\nimport type { FallbackResolver } from \"./fallback-resolver.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\nimport type { SettingsManager } from \"./settings-manager.js\";\nimport { sleep } from \"../utils/sleep.js\";\nimport type { AgentSessionEvent } from \"./agent-session.js\";\n\n/** Dependencies injected from AgentSession into RetryHandler */\nexport interface RetryHandlerDeps {\n\treadonly agent: Agent;\n\treadonly settingsManager: SettingsManager;\n\treadonly modelRegistry: ModelRegistry;\n\treadonly fallbackResolver: FallbackResolver;\n\tgetModel: () => Model<any> | undefined;\n\tgetSessionId: () => string;\n\temit: (event: AgentSessionEvent) => void;\n\t/** Called when the retry handler switches to a fallback model */\n\tonModelChange: (model: Model<any>) => void;\n\t/** Optional: check if the claude-code CLI provider is ready (installed + authed).\n\t * Injected from the app layer to preserve package boundary. */\n\tisClaudeCodeReady?: () => boolean;\n}\n\nexport class RetryHandler {\n\tprivate _retryAbortController: AbortController | undefined = undefined;\n\tprivate _retryAttempt = 0;\n\tprivate _retryPromise: Promise<void> | undefined = undefined;\n\tprivate _retryResolve: (() => void) | undefined = undefined;\n\tprivate _retryGeneration = 0;\n\tprivate _continueTimeout: ReturnType<typeof setTimeout> | undefined = undefined;\n\n\tconstructor(private readonly _deps: RetryHandlerDeps) {}\n\n\t/** Current retry attempt (0 if not retrying) */\n\tget retryAttempt(): number {\n\t\treturn this._retryAttempt;\n\t}\n\n\t/** Whether auto-retry is currently in progress */\n\tget isRetrying(): boolean {\n\t\treturn this._retryPromise !== undefined;\n\t}\n\n\t/** Whether auto-retry is enabled */\n\tget autoRetryEnabled(): boolean {\n\t\treturn this._deps.settingsManager.getRetryEnabled();\n\t}\n\n\t/** Toggle auto-retry setting */\n\tsetAutoRetryEnabled(enabled: boolean): void {\n\t\tthis._deps.settingsManager.setRetryEnabled(enabled);\n\t}\n\n\t/**\n\t * Create a retry promise synchronously for agent_end events.\n\t * Must be called synchronously from the agent event handler before\n\t * any async processing, so that waitForRetry() doesn't miss in-flight retries.\n\t */\n\tcreateRetryPromiseForAgentEnd(messages: Array<{ role: string } & Record<string, any>>): void {\n\t\tif (this._retryPromise) return;\n\n\t\tconst settings = this._deps.settingsManager.getRetrySettings();\n\t\tif (!settings.enabled) return;\n\n\t\tconst lastAssistant = this._findLastAssistantInMessages(messages);\n\t\tif (!lastAssistant || !this.isRetryableError(lastAssistant)) return;\n\n\t\tthis._retryPromise = new Promise((resolve) => {\n\t\t\tthis._retryResolve = resolve;\n\t\t});\n\t}\n\n\t/**\n\t * Handle a successful assistant response by resetting retry state.\n\t * Call this when an assistant message completes without error.\n\t */\n\thandleSuccessfulResponse(): void {\n\t\tif (this._retryAttempt > 0) {\n\t\t\tthis._deps.emit({\n\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\tsuccess: true,\n\t\t\t\tattempt: this._retryAttempt,\n\t\t\t});\n\t\t\tthis._retryAttempt = 0;\n\t\t\tthis._resolveRetry();\n\t\t}\n\t}\n\n\t/**\n\t * Check if an error is retryable (overloaded, rate limit, server errors).\n\t * Context overflow errors are NOT retryable (handled by compaction instead).\n\t */\n\tisRetryableError(message: AssistantMessage): boolean {\n\t\tif (message.stopReason !== \"error\" || !message.errorMessage) return false;\n\n\t\t// Context overflow is handled by compaction, not retry\n\t\tconst contextWindow = this._deps.getModel()?.contextWindow ?? 0;\n\t\tif (isContextOverflow(message, contextWindow)) return false;\n\n\t\tconst err = message.errorMessage;\n\t\t// \"temporarily backed off\" is intentionally excluded: it is an internally-\n\t\t// generated error from getApiKey() when credentials are in a backoff window.\n\t\t// Re-entering the retry handler for that message creates a cascade of empty\n\t\t// error entries in the session file, breaking resume (#3429).\n\t\treturn /overloaded|rate.?limit|too many requests|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay|network.?(?:is\\s+)?unavailable|credentials.*expired|extra usage is required|(?:out of|no) extra usage|third.party.*draw from extra|third.party.*not.*available/i.test(\n\t\t\terr,\n\t\t);\n\t}\n\n\t/**\n\t * Handle retryable errors with exponential backoff.\n\t * When multiple credentials are available, marks the failing credential\n\t * as backed off and retries immediately with the next one.\n\t * @returns true if retry was initiated, false if max retries exceeded or disabled\n\t */\n\tasync handleRetryableError(message: AssistantMessage): Promise<boolean> {\n\t\tconst settings = this._deps.settingsManager.getRetrySettings();\n\t\tif (!settings.enabled) {\n\t\t\tthis._resolveRetry();\n\t\t\treturn false;\n\t\t}\n\n\t\t// Retry promise is created synchronously in createRetryPromiseForAgentEnd.\n\t\t// Keep a defensive fallback here in case a future refactor bypasses that path.\n\t\tif (!this._retryPromise) {\n\t\t\tthis._retryPromise = new Promise((resolve) => {\n\t\t\t\tthis._retryResolve = resolve;\n\t\t\t});\n\t\t}\n\n\t\t// Try credential fallback before counting against retry budget.\n\t\tconst retryGeneration = this._retryGeneration;\n\t\tif (this._deps.getModel() && message.errorMessage) {\n\t\t\t// Third-party subscription block (#3772): Anthropic blocks third-party apps\n\t\t\t// from using Pro/Max subscription quotas. If the claude-code CLI provider is\n\t\t\t// available, switch to it immediately — credential rotation won't help.\n\t\t\tif (this._isThirdPartyBlock(message.errorMessage)) {\n\t\t\t\tconst switched = this._tryClaudeCodeFallback(message, retryGeneration);\n\t\t\t\tif (switched) return true;\n\t\t\t\t// CLI not available — fall through to standard error handling\n\t\t\t}\n\n\t\t\tconst errorType = this._classifyErrorType(message.errorMessage);\n\t\t\tconst isRateLimit = errorType === \"rate_limit\";\n\t\t\tconst isQuotaError = errorType === \"quota_exhausted\";\n\n\t\t\t// Credential rotation — only for transient rate limits (#3430).\n\t\t\t// Quota errors (\"Extra usage is required\") are account-level billing\n\t\t\t// gates; rotating to another credential on the same account won't help\n\t\t\t// and the 30-minute backoff blocks all provider requests needlessly.\n\t\t\tif (isRateLimit) {\n\t\t\t\tconst hasAlternate =\n\t\t\t\t\tthis._deps.modelRegistry.authStorage.markUsageLimitReached(\n\t\t\t\t\t\tthis._deps.getModel()!.provider,\n\t\t\t\t\t\tthis._deps.getSessionId(),\n\t\t\t\t\t\t{ errorType },\n\t\t\t\t\t);\n\n\t\t\t\tif (hasAlternate) {\n\t\t\t\t\tthis._removeLastAssistantError();\n\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"auto_retry_start\",\n\t\t\t\t\t\tattempt: this._retryAttempt + 1,\n\t\t\t\t\t\tmaxAttempts: settings.maxRetries,\n\t\t\t\t\t\tdelayMs: 0,\n\t\t\t\t\t\terrorMessage: `${message.errorMessage} (switching credential)`,\n\t\t\t\t\t});\n\n\t\t\t\t\t// Retry immediately with the next credential - don't increment _retryAttempt\n\t\t\t\t\tthis._scheduleContinue(retryGeneration);\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Cross-provider fallback — for rate limits with all creds backed off,\n\t\t\t// or quota errors (which skip credential backoff entirely).\n\t\t\tif (isRateLimit || isQuotaError) {\n\t\t\t\tconst fallbackResult = await this._deps.fallbackResolver.findFallback(\n\t\t\t\t\tthis._deps.getModel()!,\n\t\t\t\t\terrorType,\n\t\t\t\t);\n\n\t\t\t\tif (fallbackResult) {\n\t\t\t\t\tconst previousProvider = this._deps.getModel()!.provider;\n\t\t\t\t\tthis._deps.agent.setModel(fallbackResult.model);\n\t\t\t\t\tthis._deps.onModelChange(fallbackResult.model);\n\t\t\t\t\tthis._removeLastAssistantError();\n\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"fallback_provider_switch\",\n\t\t\t\t\t\tfrom: `${previousProvider}/${this._deps.getModel()?.id}`,\n\t\t\t\t\t\tto: `${fallbackResult.model.provider}/${fallbackResult.model.id}`,\n\t\t\t\t\t\treason: fallbackResult.reason,\n\t\t\t\t\t});\n\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"auto_retry_start\",\n\t\t\t\t\t\tattempt: this._retryAttempt + 1,\n\t\t\t\t\t\tmaxAttempts: settings.maxRetries,\n\t\t\t\t\t\tdelayMs: 0,\n\t\t\t\t\t\terrorMessage: `${message.errorMessage} (${fallbackResult.reason})`,\n\t\t\t\t\t});\n\n\t\t\t\t\t// Retry immediately with fallback provider - don't increment _retryAttempt\n\t\t\t\t\tthis._scheduleContinue(retryGeneration);\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// No fallback available either\n\t\t\t\tif (isQuotaError) {\n\t\t\t\t\t// Try long-context model downgrade ([1m] → base) before giving up\n\t\t\t\t\tconst downgraded = this._tryLongContextDowngrade(message, retryGeneration);\n\t\t\t\t\tif (downgraded) return true;\n\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"fallback_chain_exhausted\",\n\t\t\t\t\t\treason: `All providers exhausted for ${this._deps.getModel()!.provider}/${this._deps.getModel()!.id}`,\n\t\t\t\t\t});\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\t\t\tfinalError: message.errorMessage,\n\t\t\t\t\t});\n\t\t\t\t\tthis._retryAttempt = 0;\n\t\t\t\t\tthis._resolveRetry();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._retryAttempt++;\n\n\t\tif (this._retryAttempt > settings.maxRetries) {\n\t\t\tthis._deps.emit({\n\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\tsuccess: false,\n\t\t\t\tattempt: this._retryAttempt - 1,\n\t\t\t\tfinalError: message.errorMessage,\n\t\t\t});\n\t\t\tthis._retryAttempt = 0;\n\t\t\tthis._resolveRetry();\n\t\t\treturn false;\n\t\t}\n\n\t\t// Use server-requested delay when available, capped by maxDelayMs.\n\t\t// Fall back to exponential backoff when no server hint is present.\n\t\tconst exponentialDelayMs = settings.baseDelayMs * 2 ** (this._retryAttempt - 1);\n\t\tlet delayMs: number;\n\t\tif (message.retryAfterMs !== undefined) {\n\t\t\tconst cap = settings.maxDelayMs > 0 ? settings.maxDelayMs : Infinity;\n\t\t\tif (message.retryAfterMs > cap) {\n\t\t\t\tthis._deps.emit({\n\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tattempt: this._retryAttempt - 1,\n\t\t\t\t\tfinalError: `Rate limit reset in ${Math.ceil(message.retryAfterMs / 1000)}s (max: ${Math.ceil(cap / 1000)}s). ${message.errorMessage || \"\"}`.trim(),\n\t\t\t\t});\n\t\t\t\tthis._retryAttempt = 0;\n\t\t\t\tthis._resolveRetry();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdelayMs = message.retryAfterMs;\n\t\t} else {\n\t\t\tdelayMs = exponentialDelayMs;\n\t\t}\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"auto_retry_start\",\n\t\t\tattempt: this._retryAttempt,\n\t\t\tmaxAttempts: settings.maxRetries,\n\t\t\tdelayMs,\n\t\t\terrorMessage: message.errorMessage || \"Unknown error\",\n\t\t});\n\n\t\tthis._removeLastAssistantError();\n\n\t\t// Wait with exponential backoff (abortable)\n\t\tthis._retryAbortController = new AbortController();\n\t\ttry {\n\t\t\tawait sleep(delayMs, this._retryAbortController.signal);\n\t\t} catch {\n\t\t\t// Aborted during sleep. If the retry generation already advanced, this\n\t\t\t// cancellation was handled externally (e.g. explicit model switch).\n\t\t\tif (retryGeneration !== this._retryGeneration) {\n\t\t\t\tthis._retryAbortController = undefined;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst attempt = this._retryAttempt;\n\t\t\tthis._retryAttempt = 0;\n\t\t\tthis._retryAbortController = undefined;\n\t\t\tthis._deps.emit({\n\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\tsuccess: false,\n\t\t\t\tattempt,\n\t\t\t\tfinalError: \"Retry cancelled\",\n\t\t\t});\n\t\t\tthis._resolveRetry();\n\t\t\treturn false;\n\t\t}\n\t\tthis._retryAbortController = undefined;\n\n\t\t// Retry via continue() - use setTimeout to break out of event handler chain\n\t\tthis._scheduleContinue(retryGeneration);\n\n\t\treturn true;\n\t}\n\n\t/** Cancel in-progress retry */\n\tabortRetry(): void {\n\t\tconst hadRetry =\n\t\t\tthis._retryPromise !== undefined\n\t\t\t|| this._retryAbortController !== undefined\n\t\t\t|| this._continueTimeout !== undefined;\n\t\tif (!hadRetry) return;\n\n\t\tconst attempt = this._retryAttempt > 0 ? this._retryAttempt : 1;\n\t\tthis._retryGeneration++;\n\t\tif (this._continueTimeout) {\n\t\t\tclearTimeout(this._continueTimeout);\n\t\t\tthis._continueTimeout = undefined;\n\t\t}\n\t\tif (this._retryAbortController) {\n\t\t\tthis._retryAbortController.abort();\n\t\t\tthis._retryAbortController = undefined;\n\t\t}\n\t\tthis._retryAttempt = 0;\n\t\tthis._deps.emit({\n\t\t\ttype: \"auto_retry_end\",\n\t\t\tsuccess: false,\n\t\t\tattempt,\n\t\t\tfinalError: \"Retry cancelled\",\n\t\t});\n\t\tthis._resolveRetry();\n\t}\n\n\t/**\n\t * Wait for any in-progress retry to complete.\n\t * Returns immediately if no retry is in progress.\n\t */\n\tasync waitForRetry(): Promise<void> {\n\t\tif (this._retryPromise) {\n\t\t\tawait this._retryPromise;\n\t\t}\n\t}\n\n\t/** Resolve the pending retry promise */\n\tresolveRetry(): void {\n\t\tthis._resolveRetry();\n\t}\n\n\t// =========================================================================\n\t// Private helpers\n\t// =========================================================================\n\n\tprivate _resolveRetry(): void {\n\t\tif (this._retryResolve) {\n\t\t\tthis._retryResolve();\n\t\t\tthis._retryResolve = undefined;\n\t\t\tthis._retryPromise = undefined;\n\t\t}\n\t}\n\n\tprivate _scheduleContinue(retryGeneration: number): void {\n\t\tif (this._continueTimeout) {\n\t\t\tclearTimeout(this._continueTimeout);\n\t\t}\n\t\tthis._continueTimeout = setTimeout(() => {\n\t\t\tthis._continueTimeout = undefined;\n\t\t\tif (retryGeneration !== this._retryGeneration) return;\n\t\t\tthis._deps.agent.continue().catch(() => {});\n\t\t}, 0);\n\t}\n\n\tprivate _findLastAssistantInMessages(\n\t\tmessages: Array<{ role: string } & Record<string, any>>,\n\t): AssistantMessage | undefined {\n\t\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\t\tconst message = messages[i];\n\t\t\tif (message.role === \"assistant\") {\n\t\t\t\treturn message as AssistantMessage;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Classify an error message into a usage-limit error type for credential backoff.\n\t */\n\tprivate _classifyErrorType(errorMessage: string): UsageLimitErrorType {\n\t\tconst err = errorMessage.toLowerCase();\n\t\t// Long-context entitlement errors are billing gates, not transient rate limits.\n\t\t// Must be checked before the generic 429/rate_limit regex.\n\t\tif (/extra usage is required|long context required/i.test(err)) return \"quota_exhausted\";\n\t\tif (/quota|billing|exceeded.*limit|usage.*limit/i.test(err)) return \"quota_exhausted\";\n\t\tif (/rate.?limit|too many requests|429/i.test(err)) return \"rate_limit\";\n\t\tif (/500|502|503|504|server.?error|internal.?error|service.?unavailable/i.test(err)) return \"server_error\";\n\t\treturn \"unknown\";\n\t}\n\n\t/**\n\t * Attempt to downgrade a long-context model (e.g. claude-opus-4-6[1m]) to its\n\t * base model (claude-opus-4-6) when the account lacks the long-context billing\n\t * entitlement. Returns true if the downgrade was initiated.\n\t */\n\tprivate _tryLongContextDowngrade(message: AssistantMessage, retryGeneration: number): boolean {\n\t\tconst currentModel = this._deps.getModel();\n\t\tif (!currentModel) return false;\n\n\t\t// Only attempt downgrade for [1m] (or similar long-context) model IDs\n\t\tconst match = currentModel.id.match(/^(.+)\\[\\d+m\\]$/);\n\t\tif (!match) return false;\n\n\t\tconst baseModelId = match[1];\n\t\tconst baseModel = this._deps.modelRegistry.find(currentModel.provider, baseModelId);\n\t\tif (!baseModel) return false;\n\n\t\tconst previousId = currentModel.id;\n\t\tthis._deps.agent.setModel(baseModel);\n\t\tthis._deps.onModelChange(baseModel);\n\t\tthis._removeLastAssistantError();\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"fallback_provider_switch\",\n\t\t\tfrom: `${currentModel.provider}/${previousId}`,\n\t\t\tto: `${baseModel.provider}/${baseModel.id}`,\n\t\t\treason: `long context downgrade: ${previousId} → ${baseModel.id}`,\n\t\t});\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"auto_retry_start\",\n\t\t\tattempt: this._retryAttempt + 1,\n\t\t\tmaxAttempts: this._deps.settingsManager.getRetrySettings().maxRetries,\n\t\t\tdelayMs: 0,\n\t\t\terrorMessage: `${message.errorMessage} (long context downgrade)`,\n\t\t});\n\n\t\tthis._scheduleContinue(retryGeneration);\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Detect Anthropic subscription block errors (#3772).\n\t * These are hard policy blocks, not transient rate limits — credential\n\t * rotation will not help. Matches both the explicit \"third-party\" message\n\t * and the \"out of extra usage\" variant that subscription users receive.\n\t */\n\tprivate _isThirdPartyBlock(errorMessage: string): boolean {\n\t\treturn /third[- .]party.*(?:draw from extra|not.*available|plan limits|not permitted|cannot be used|not supported)|(?:out of|no) extra usage/i.test(errorMessage);\n\t}\n\n\t/**\n\t * Attempt to switch to the claude-code CLI provider when the current\n\t * Anthropic provider is blocked by the third-party policy (#3772).\n\t * Returns true if the switch was made and retry scheduled.\n\t */\n\tprivate _tryClaudeCodeFallback(message: AssistantMessage, retryGeneration: number): boolean {\n\t\tif (!this._deps.isClaudeCodeReady?.()) return false;\n\n\t\tconst currentModel = this._deps.getModel();\n\t\tif (!currentModel) return false;\n\n\t\t// Only attempt claude-code fallback when the current provider is anthropic.\n\t\t// Other providers may produce similar error text but should not be rerouted.\n\t\tif (currentModel.provider !== \"anthropic\") return false;\n\n\t\t// Find the same model ID under the claude-code provider\n\t\tconst ccModel = this._deps.modelRegistry.find(\"claude-code\", currentModel.id);\n\t\tif (!ccModel) return false;\n\n\t\tconst previousProvider = currentModel.provider;\n\t\tthis._deps.agent.setModel(ccModel);\n\t\tthis._deps.onModelChange(ccModel);\n\t\tthis._removeLastAssistantError();\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"fallback_provider_switch\",\n\t\t\tfrom: `${previousProvider}/${currentModel.id}`,\n\t\t\tto: `claude-code/${ccModel.id}`,\n\t\t\treason: \"Anthropic subscription blocked for third-party apps — routing through Claude Code CLI\",\n\t\t});\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"auto_retry_start\",\n\t\t\tattempt: this._retryAttempt + 1,\n\t\t\tmaxAttempts: this._deps.settingsManager.getRetrySettings().maxRetries,\n\t\t\tdelayMs: 0,\n\t\t\terrorMessage: `${message.errorMessage} (switching to Claude Code CLI)`,\n\t\t});\n\n\t\tthis._scheduleContinue(retryGeneration);\n\t\treturn true;\n\t}\n\n\t/** Remove the last assistant error message from agent state */\n\tprivate _removeLastAssistantError(): void {\n\t\tconst messages = this._deps.agent.state.messages;\n\t\tif (messages.length > 0 && messages[messages.length - 1].role === \"assistant\") {\n\t\t\tthis._deps.agent.replaceMessages(messages.slice(0, -1));\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"retry-handler.js","sourceRoot":"","sources":["../../src/core/retry-handler.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * RetryHandler - Automatic retry logic with exponential backoff and credential/provider fallback.\n *\n * Handles retryable errors (overloaded, rate limit, server errors) by:\n * 1. Trying alternate credentials for the same provider\n * 2. Falling back to other providers via FallbackResolver\n * 3. Exponential backoff with configurable max retries\n *\n * Context overflow errors are NOT handled here (see compaction).\n */\n\nimport type { Agent } from \"@gsd/pi-agent-core\";\nimport type { AssistantMessage, Model } from \"@gsd/pi-ai\";\nimport { isContextOverflow } from \"@gsd/pi-ai\";\nimport type { UsageLimitErrorType } from \"./auth-storage.js\";\nimport type { FallbackResolver } from \"./fallback-resolver.js\";\nimport type { ModelRegistry } from \"./model-registry.js\";\nimport type { SettingsManager } from \"./settings-manager.js\";\nimport { sleep } from \"../utils/sleep.js\";\nimport type { AgentSessionEvent } from \"./agent-session.js\";\n\n/** Dependencies injected from AgentSession into RetryHandler */\nexport interface RetryHandlerDeps {\n\treadonly agent: Agent;\n\treadonly settingsManager: SettingsManager;\n\treadonly modelRegistry: ModelRegistry;\n\treadonly fallbackResolver: FallbackResolver;\n\tgetModel: () => Model<any> | undefined;\n\tgetSessionId: () => string;\n\temit: (event: AgentSessionEvent) => void;\n\t/** Called when the retry handler switches to a fallback model */\n\tonModelChange: (model: Model<any>) => void;\n\t/** Optional: check if the claude-code CLI provider is ready (installed + authed).\n\t * Injected from the app layer to preserve package boundary. */\n\tisClaudeCodeReady?: () => boolean;\n}\n\nexport class RetryHandler {\n\tprivate _retryAbortController: AbortController | undefined = undefined;\n\tprivate _retryAttempt = 0;\n\tprivate _retryPromise: Promise<void> | undefined = undefined;\n\tprivate _retryResolve: (() => void) | undefined = undefined;\n\tprivate _retryGeneration = 0;\n\tprivate _continueTimeout: ReturnType<typeof setTimeout> | undefined = undefined;\n\n\tconstructor(private readonly _deps: RetryHandlerDeps) {}\n\n\t/** Current retry attempt (0 if not retrying) */\n\tget retryAttempt(): number {\n\t\treturn this._retryAttempt;\n\t}\n\n\t/** Whether auto-retry is currently in progress */\n\tget isRetrying(): boolean {\n\t\treturn this._retryPromise !== undefined;\n\t}\n\n\t/** Whether auto-retry is enabled */\n\tget autoRetryEnabled(): boolean {\n\t\treturn this._deps.settingsManager.getRetryEnabled();\n\t}\n\n\t/** Toggle auto-retry setting */\n\tsetAutoRetryEnabled(enabled: boolean): void {\n\t\tthis._deps.settingsManager.setRetryEnabled(enabled);\n\t}\n\n\t/**\n\t * Create a retry promise synchronously for agent_end events.\n\t * Must be called synchronously from the agent event handler before\n\t * any async processing, so that waitForRetry() doesn't miss in-flight retries.\n\t */\n\tcreateRetryPromiseForAgentEnd(messages: Array<{ role: string } & Record<string, any>>): void {\n\t\tif (this._retryPromise) return;\n\n\t\tconst settings = this._deps.settingsManager.getRetrySettings();\n\t\tif (!settings.enabled) return;\n\n\t\tconst lastAssistant = this._findLastAssistantInMessages(messages);\n\t\tif (!lastAssistant || !this.isRetryableError(lastAssistant)) return;\n\n\t\tthis._retryPromise = new Promise((resolve) => {\n\t\t\tthis._retryResolve = resolve;\n\t\t});\n\t}\n\n\t/**\n\t * Handle a successful assistant response by resetting retry state.\n\t * Call this when an assistant message completes without error.\n\t */\n\thandleSuccessfulResponse(): void {\n\t\tif (this._retryAttempt > 0) {\n\t\t\tthis._deps.emit({\n\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\tsuccess: true,\n\t\t\t\tattempt: this._retryAttempt,\n\t\t\t});\n\t\t\tthis._retryAttempt = 0;\n\t\t\tthis._resolveRetry();\n\t\t}\n\t}\n\n\t/**\n\t * Check if an error is retryable (overloaded, rate limit, server errors).\n\t * Context overflow errors are NOT retryable (handled by compaction instead).\n\t */\n\tisRetryableError(message: AssistantMessage): boolean {\n\t\tif (message.stopReason !== \"error\" || !message.errorMessage) return false;\n\n\t\t// Context overflow is handled by compaction, not retry\n\t\tconst contextWindow = this._deps.getModel()?.contextWindow ?? 0;\n\t\tif (isContextOverflow(message, contextWindow)) return false;\n\n\t\tconst err = message.errorMessage;\n\t\t// \"temporarily backed off\" is intentionally excluded: it is an internally-\n\t\t// generated error from getApiKey() when credentials are in a backoff window.\n\t\t// Re-entering the retry handler for that message creates a cascade of empty\n\t\t// error entries in the session file, breaking resume (#3429).\n\t\treturn /overloaded|rate.?limit|too many requests|402|429|500|502|503|504|service.?unavailable|server.?error|internal.?error|connection.?error|connection.?refused|other side closed|fetch failed|upstream.?connect|reset before headers|terminated|retry delay|network.?(?:is\\s+)?unavailable|credentials.*expired|requires more credits|can only afford|insufficient credits|not enough credits|extra usage is required|(?:out of|no) extra usage|third.party.*draw from extra|third.party.*not.*available/i.test(\n\t\t\terr,\n\t\t);\n\t}\n\n\t/**\n\t * Handle retryable errors with exponential backoff.\n\t * When multiple credentials are available, marks the failing credential\n\t * as backed off and retries immediately with the next one.\n\t * @returns true if retry was initiated, false if max retries exceeded or disabled\n\t */\n\tasync handleRetryableError(message: AssistantMessage): Promise<boolean> {\n\t\tconst settings = this._deps.settingsManager.getRetrySettings();\n\t\tif (!settings.enabled) {\n\t\t\tthis._resolveRetry();\n\t\t\treturn false;\n\t\t}\n\n\t\t// Retry promise is created synchronously in createRetryPromiseForAgentEnd.\n\t\t// Keep a defensive fallback here in case a future refactor bypasses that path.\n\t\tif (!this._retryPromise) {\n\t\t\tthis._retryPromise = new Promise((resolve) => {\n\t\t\t\tthis._retryResolve = resolve;\n\t\t\t});\n\t\t}\n\n\t\t// Try credential fallback before counting against retry budget.\n\t\tconst retryGeneration = this._retryGeneration;\n\t\tif (this._deps.getModel() && message.errorMessage) {\n\t\t\t// Third-party subscription block (#3772): Anthropic blocks third-party apps\n\t\t\t// from using Pro/Max subscription quotas. If the claude-code CLI provider is\n\t\t\t// available, switch to it immediately — credential rotation won't help.\n\t\t\tif (this._isThirdPartyBlock(message.errorMessage)) {\n\t\t\t\tconst switched = this._tryClaudeCodeFallback(message, retryGeneration);\n\t\t\t\tif (switched) return true;\n\t\t\t\t// CLI not available — fall through to standard error handling\n\t\t\t}\n\n\t\t\tconst errorType = this._classifyErrorType(message.errorMessage);\n\t\t\tconst isRateLimit = errorType === \"rate_limit\";\n\t\t\tconst isQuotaError = errorType === \"quota_exhausted\";\n\n\t\t\t// Credit-aware retry (OpenRouter-style 402 affordability errors):\n\t\t\t// when provider reports \"can only afford N\", lower maxTokens and retry\n\t\t\t// on the same model before rotating credentials/providers.\n\t\t\tif (isQuotaError) {\n\t\t\t\tconst adjusted = this._tryAffordableMaxTokensRetry(message, retryGeneration);\n\t\t\t\tif (adjusted) return true;\n\t\t\t}\n\n\t\t\t// Credential rotation — only for transient rate limits (#3430).\n\t\t\t// Quota errors (\"Extra usage is required\") are account-level billing\n\t\t\t// gates; rotating to another credential on the same account won't help\n\t\t\t// and the 30-minute backoff blocks all provider requests needlessly.\n\t\t\tif (isRateLimit) {\n\t\t\t\tconst hasAlternate =\n\t\t\t\t\tthis._deps.modelRegistry.authStorage.markUsageLimitReached(\n\t\t\t\t\t\tthis._deps.getModel()!.provider,\n\t\t\t\t\t\tthis._deps.getSessionId(),\n\t\t\t\t\t\t{ errorType },\n\t\t\t\t\t);\n\n\t\t\t\tif (hasAlternate) {\n\t\t\t\t\tthis._removeLastAssistantError();\n\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"auto_retry_start\",\n\t\t\t\t\t\tattempt: this._retryAttempt + 1,\n\t\t\t\t\t\tmaxAttempts: settings.maxRetries,\n\t\t\t\t\t\tdelayMs: 0,\n\t\t\t\t\t\terrorMessage: `${message.errorMessage} (switching credential)`,\n\t\t\t\t\t});\n\n\t\t\t\t\t// Retry immediately with the next credential - don't increment _retryAttempt\n\t\t\t\t\tthis._scheduleContinue(retryGeneration);\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Cross-provider fallback — for rate limits with all creds backed off,\n\t\t\t// or quota errors (which skip credential backoff entirely).\n\t\t\tif (isRateLimit || isQuotaError) {\n\t\t\t\tconst fallbackResult = await this._deps.fallbackResolver.findFallback(\n\t\t\t\t\tthis._deps.getModel()!,\n\t\t\t\t\terrorType,\n\t\t\t\t);\n\n\t\t\t\tif (fallbackResult) {\n\t\t\t\t\tconst previousProvider = this._deps.getModel()!.provider;\n\t\t\t\t\tthis._deps.agent.setModel(fallbackResult.model);\n\t\t\t\t\tthis._deps.onModelChange(fallbackResult.model);\n\t\t\t\t\tthis._removeLastAssistantError();\n\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"fallback_provider_switch\",\n\t\t\t\t\t\tfrom: `${previousProvider}/${this._deps.getModel()?.id}`,\n\t\t\t\t\t\tto: `${fallbackResult.model.provider}/${fallbackResult.model.id}`,\n\t\t\t\t\t\treason: fallbackResult.reason,\n\t\t\t\t\t});\n\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"auto_retry_start\",\n\t\t\t\t\t\tattempt: this._retryAttempt + 1,\n\t\t\t\t\t\tmaxAttempts: settings.maxRetries,\n\t\t\t\t\t\tdelayMs: 0,\n\t\t\t\t\t\terrorMessage: `${message.errorMessage} (${fallbackResult.reason})`,\n\t\t\t\t\t});\n\n\t\t\t\t\t// Retry immediately with fallback provider - don't increment _retryAttempt\n\t\t\t\t\tthis._scheduleContinue(retryGeneration);\n\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\t// No fallback available either\n\t\t\t\tif (isQuotaError) {\n\t\t\t\t\t// Try long-context model downgrade ([1m] → base) before giving up\n\t\t\t\t\tconst downgraded = this._tryLongContextDowngrade(message, retryGeneration);\n\t\t\t\t\tif (downgraded) return true;\n\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"fallback_chain_exhausted\",\n\t\t\t\t\t\treason: `All providers exhausted for ${this._deps.getModel()!.provider}/${this._deps.getModel()!.id}`,\n\t\t\t\t\t});\n\t\t\t\t\tthis._deps.emit({\n\t\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tattempt: this._retryAttempt,\n\t\t\t\t\t\tfinalError: message.errorMessage,\n\t\t\t\t\t});\n\t\t\t\t\tthis._retryAttempt = 0;\n\t\t\t\t\tthis._resolveRetry();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis._retryAttempt++;\n\n\t\tif (this._retryAttempt > settings.maxRetries) {\n\t\t\tthis._deps.emit({\n\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\tsuccess: false,\n\t\t\t\tattempt: this._retryAttempt - 1,\n\t\t\t\tfinalError: message.errorMessage,\n\t\t\t});\n\t\t\tthis._retryAttempt = 0;\n\t\t\tthis._resolveRetry();\n\t\t\treturn false;\n\t\t}\n\n\t\t// Use server-requested delay when available, capped by maxDelayMs.\n\t\t// Fall back to exponential backoff when no server hint is present.\n\t\tconst exponentialDelayMs = settings.baseDelayMs * 2 ** (this._retryAttempt - 1);\n\t\tlet delayMs: number;\n\t\tif (message.retryAfterMs !== undefined) {\n\t\t\tconst cap = settings.maxDelayMs > 0 ? settings.maxDelayMs : Infinity;\n\t\t\tif (message.retryAfterMs > cap) {\n\t\t\t\tthis._deps.emit({\n\t\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\t\tsuccess: false,\n\t\t\t\t\tattempt: this._retryAttempt - 1,\n\t\t\t\t\tfinalError: `Rate limit reset in ${Math.ceil(message.retryAfterMs / 1000)}s (max: ${Math.ceil(cap / 1000)}s). ${message.errorMessage || \"\"}`.trim(),\n\t\t\t\t});\n\t\t\t\tthis._retryAttempt = 0;\n\t\t\t\tthis._resolveRetry();\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tdelayMs = message.retryAfterMs;\n\t\t} else {\n\t\t\tdelayMs = exponentialDelayMs;\n\t\t}\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"auto_retry_start\",\n\t\t\tattempt: this._retryAttempt,\n\t\t\tmaxAttempts: settings.maxRetries,\n\t\t\tdelayMs,\n\t\t\terrorMessage: message.errorMessage || \"Unknown error\",\n\t\t});\n\n\t\tthis._removeLastAssistantError();\n\n\t\t// Wait with exponential backoff (abortable)\n\t\tthis._retryAbortController = new AbortController();\n\t\ttry {\n\t\t\tawait sleep(delayMs, this._retryAbortController.signal);\n\t\t} catch {\n\t\t\t// Aborted during sleep. If the retry generation already advanced, this\n\t\t\t// cancellation was handled externally (e.g. explicit model switch).\n\t\t\tif (retryGeneration !== this._retryGeneration) {\n\t\t\t\tthis._retryAbortController = undefined;\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tconst attempt = this._retryAttempt;\n\t\t\tthis._retryAttempt = 0;\n\t\t\tthis._retryAbortController = undefined;\n\t\t\tthis._deps.emit({\n\t\t\t\ttype: \"auto_retry_end\",\n\t\t\t\tsuccess: false,\n\t\t\t\tattempt,\n\t\t\t\tfinalError: \"Retry cancelled\",\n\t\t\t});\n\t\t\tthis._resolveRetry();\n\t\t\treturn false;\n\t\t}\n\t\tthis._retryAbortController = undefined;\n\n\t\t// Retry via continue() - use setTimeout to break out of event handler chain\n\t\tthis._scheduleContinue(retryGeneration);\n\n\t\treturn true;\n\t}\n\n\t/** Cancel in-progress retry */\n\tabortRetry(): void {\n\t\tconst hadRetry =\n\t\t\tthis._retryPromise !== undefined\n\t\t\t|| this._retryAbortController !== undefined\n\t\t\t|| this._continueTimeout !== undefined;\n\t\tif (!hadRetry) return;\n\n\t\tconst attempt = this._retryAttempt > 0 ? this._retryAttempt : 1;\n\t\tthis._retryGeneration++;\n\t\tif (this._continueTimeout) {\n\t\t\tclearTimeout(this._continueTimeout);\n\t\t\tthis._continueTimeout = undefined;\n\t\t}\n\t\tif (this._retryAbortController) {\n\t\t\tthis._retryAbortController.abort();\n\t\t\tthis._retryAbortController = undefined;\n\t\t}\n\t\tthis._retryAttempt = 0;\n\t\tthis._deps.emit({\n\t\t\ttype: \"auto_retry_end\",\n\t\t\tsuccess: false,\n\t\t\tattempt,\n\t\t\tfinalError: \"Retry cancelled\",\n\t\t});\n\t\tthis._resolveRetry();\n\t}\n\n\t/**\n\t * Wait for any in-progress retry to complete.\n\t * Returns immediately if no retry is in progress.\n\t */\n\tasync waitForRetry(): Promise<void> {\n\t\tif (this._retryPromise) {\n\t\t\tawait this._retryPromise;\n\t\t}\n\t}\n\n\t/** Resolve the pending retry promise */\n\tresolveRetry(): void {\n\t\tthis._resolveRetry();\n\t}\n\n\t// =========================================================================\n\t// Private helpers\n\t// =========================================================================\n\n\tprivate _resolveRetry(): void {\n\t\tif (this._retryResolve) {\n\t\t\tthis._retryResolve();\n\t\t\tthis._retryResolve = undefined;\n\t\t\tthis._retryPromise = undefined;\n\t\t}\n\t}\n\n\tprivate _scheduleContinue(retryGeneration: number): void {\n\t\tif (this._continueTimeout) {\n\t\t\tclearTimeout(this._continueTimeout);\n\t\t}\n\t\tthis._continueTimeout = setTimeout(() => {\n\t\t\tthis._continueTimeout = undefined;\n\t\t\tif (retryGeneration !== this._retryGeneration) return;\n\t\t\tthis._deps.agent.continue().catch(() => {});\n\t\t}, 0);\n\t}\n\n\tprivate _findLastAssistantInMessages(\n\t\tmessages: Array<{ role: string } & Record<string, any>>,\n\t): AssistantMessage | undefined {\n\t\tfor (let i = messages.length - 1; i >= 0; i--) {\n\t\t\tconst message = messages[i];\n\t\t\tif (message.role === \"assistant\") {\n\t\t\t\treturn message as AssistantMessage;\n\t\t\t}\n\t\t}\n\t\treturn undefined;\n\t}\n\n\t/**\n\t * Classify an error message into a usage-limit error type for credential backoff.\n\t */\n\tprivate _classifyErrorType(errorMessage: string): UsageLimitErrorType {\n\t\tconst err = errorMessage.toLowerCase();\n\t\t// Long-context entitlement errors are billing gates, not transient rate limits.\n\t\t// Must be checked before the generic 429/rate_limit regex.\n\t\tif (/extra usage is required|long context required/i.test(err)) return \"quota_exhausted\";\n\t\tif (/requires more credits|can only afford|insufficient credits|not enough credits|credit balance/i.test(err))\n\t\t\treturn \"quota_exhausted\";\n\t\tif (/quota|billing|exceeded.*limit|usage.*limit/i.test(err)) return \"quota_exhausted\";\n\t\tif (/rate.?limit|too many requests|429/i.test(err)) return \"rate_limit\";\n\t\tif (/500|502|503|504|server.?error|internal.?error|service.?unavailable/i.test(err)) return \"server_error\";\n\t\treturn \"unknown\";\n\t}\n\n\t/**\n\t * Attempt a same-model retry by reducing maxTokens when provider reports\n\t * an affordability cap (e.g., \"can only afford 329\").\n\t */\n\tprivate _tryAffordableMaxTokensRetry(message: AssistantMessage, retryGeneration: number): boolean {\n\t\tconst currentModel = this._deps.getModel();\n\t\tif (!currentModel || !message.errorMessage) return false;\n\n\t\t// Example: \"can only afford 329\"\n\t\tconst match = message.errorMessage.match(/can only afford\\s+([\\d,]+)/i);\n\t\tif (!match?.[1]) return false;\n\n\t\tconst affordable = Number.parseInt(match[1].replace(/,/g, \"\"), 10);\n\t\tif (!Number.isFinite(affordable) || affordable <= 0) return false;\n\n\t\t// Leave a small buffer so slight input variance doesn't immediately re-fail.\n\t\tconst safetyBuffer = Math.min(64, Math.max(16, Math.floor(affordable * 0.1)));\n\t\tconst targetMaxTokens = Math.max(64, affordable - safetyBuffer);\n\t\tconst downgradedMaxTokens = Math.min(currentModel.maxTokens, targetMaxTokens);\n\t\tif (downgradedMaxTokens >= currentModel.maxTokens) return false;\n\n\t\tconst downgradedModel = {\n\t\t\t...currentModel,\n\t\t\tmaxTokens: downgradedMaxTokens,\n\t\t};\n\n\t\tthis._deps.agent.setModel(downgradedModel);\n\t\tthis._deps.onModelChange(downgradedModel);\n\t\tthis._removeLastAssistantError();\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"fallback_provider_switch\",\n\t\t\tfrom: `${currentModel.provider}/${currentModel.id} (maxTokens=${currentModel.maxTokens})`,\n\t\t\tto: `${downgradedModel.provider}/${downgradedModel.id} (maxTokens=${downgradedModel.maxTokens})`,\n\t\t\treason: `credit-aware retry: provider affordable cap ${affordable} tokens`,\n\t\t});\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"auto_retry_start\",\n\t\t\tattempt: this._retryAttempt + 1,\n\t\t\tmaxAttempts: this._deps.settingsManager.getRetrySettings().maxRetries,\n\t\t\tdelayMs: 0,\n\t\t\terrorMessage: `${message.errorMessage} (reducing max tokens)`,\n\t\t});\n\n\t\tthis._scheduleContinue(retryGeneration);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Attempt to downgrade a long-context model (e.g. claude-opus-4-6[1m]) to its\n\t * base model (claude-opus-4-6) when the account lacks the long-context billing\n\t * entitlement. Returns true if the downgrade was initiated.\n\t */\n\tprivate _tryLongContextDowngrade(message: AssistantMessage, retryGeneration: number): boolean {\n\t\tconst currentModel = this._deps.getModel();\n\t\tif (!currentModel) return false;\n\n\t\t// Only attempt downgrade for [1m] (or similar long-context) model IDs\n\t\tconst match = currentModel.id.match(/^(.+)\\[\\d+m\\]$/);\n\t\tif (!match) return false;\n\n\t\tconst baseModelId = match[1];\n\t\tconst baseModel = this._deps.modelRegistry.find(currentModel.provider, baseModelId);\n\t\tif (!baseModel) return false;\n\n\t\tconst previousId = currentModel.id;\n\t\tthis._deps.agent.setModel(baseModel);\n\t\tthis._deps.onModelChange(baseModel);\n\t\tthis._removeLastAssistantError();\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"fallback_provider_switch\",\n\t\t\tfrom: `${currentModel.provider}/${previousId}`,\n\t\t\tto: `${baseModel.provider}/${baseModel.id}`,\n\t\t\treason: `long context downgrade: ${previousId} → ${baseModel.id}`,\n\t\t});\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"auto_retry_start\",\n\t\t\tattempt: this._retryAttempt + 1,\n\t\t\tmaxAttempts: this._deps.settingsManager.getRetrySettings().maxRetries,\n\t\t\tdelayMs: 0,\n\t\t\terrorMessage: `${message.errorMessage} (long context downgrade)`,\n\t\t});\n\n\t\tthis._scheduleContinue(retryGeneration);\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Detect Anthropic subscription block errors (#3772).\n\t * These are hard policy blocks, not transient rate limits — credential\n\t * rotation will not help. Matches both the explicit \"third-party\" message\n\t * and the \"out of extra usage\" variant that subscription users receive.\n\t */\n\tprivate _isThirdPartyBlock(errorMessage: string): boolean {\n\t\treturn /third[- .]party.*(?:draw from extra|not.*available|plan limits|not permitted|cannot be used|not supported)|(?:out of|no) extra usage/i.test(errorMessage);\n\t}\n\n\t/**\n\t * Attempt to switch to the claude-code CLI provider when the current\n\t * Anthropic provider is blocked by the third-party policy (#3772).\n\t * Returns true if the switch was made and retry scheduled.\n\t */\n\tprivate _tryClaudeCodeFallback(message: AssistantMessage, retryGeneration: number): boolean {\n\t\tif (!this._deps.isClaudeCodeReady?.()) return false;\n\n\t\tconst currentModel = this._deps.getModel();\n\t\tif (!currentModel) return false;\n\n\t\t// Only attempt claude-code fallback when the current provider is anthropic.\n\t\t// Other providers may produce similar error text but should not be rerouted.\n\t\tif (currentModel.provider !== \"anthropic\") return false;\n\n\t\t// Find the same model ID under the claude-code provider\n\t\tconst ccModel = this._deps.modelRegistry.find(\"claude-code\", currentModel.id);\n\t\tif (!ccModel) return false;\n\n\t\tconst previousProvider = currentModel.provider;\n\t\tthis._deps.agent.setModel(ccModel);\n\t\tthis._deps.onModelChange(ccModel);\n\t\tthis._removeLastAssistantError();\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"fallback_provider_switch\",\n\t\t\tfrom: `${previousProvider}/${currentModel.id}`,\n\t\t\tto: `claude-code/${ccModel.id}`,\n\t\t\treason: \"Anthropic subscription blocked for third-party apps — routing through Claude Code CLI\",\n\t\t});\n\n\t\tthis._deps.emit({\n\t\t\ttype: \"auto_retry_start\",\n\t\t\tattempt: this._retryAttempt + 1,\n\t\t\tmaxAttempts: this._deps.settingsManager.getRetrySettings().maxRetries,\n\t\t\tdelayMs: 0,\n\t\t\terrorMessage: `${message.errorMessage} (switching to Claude Code CLI)`,\n\t\t});\n\n\t\tthis._scheduleContinue(retryGeneration);\n\t\treturn true;\n\t}\n\n\t/** Remove the last assistant error message from agent state */\n\tprivate _removeLastAssistantError(): void {\n\t\tconst messages = this._deps.agent.state.messages;\n\t\tif (messages.length > 0 && messages[messages.length - 1].role === \"assistant\") {\n\t\t\tthis._deps.agent.replaceMessages(messages.slice(0, -1));\n\t\t}\n\t}\n}\n"]}