gsd-pi 2.51.0-dev.ae8f7cb → 2.52.0-dev.585e355

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 (337) hide show
  1. package/README.md +4 -4
  2. package/dist/headless-events.d.ts +18 -0
  3. package/dist/headless-events.js +36 -0
  4. package/dist/headless-types.d.ts +28 -0
  5. package/dist/headless-types.js +7 -0
  6. package/dist/headless.d.ts +8 -3
  7. package/dist/headless.js +47 -16
  8. package/dist/help-text.js +16 -5
  9. package/dist/onboarding.js +5 -4
  10. package/dist/remote-questions-config.js +1 -1
  11. package/dist/resources/extensions/async-jobs/async-bash-tool.js +29 -17
  12. package/dist/resources/extensions/async-jobs/job-manager.js +4 -1
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +18 -19
  14. package/dist/resources/extensions/gsd/auto/phases.js +6 -0
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +18 -0
  16. package/dist/resources/extensions/gsd/auto-start.js +2 -0
  17. package/dist/resources/extensions/gsd/auto-timers.js +24 -2
  18. package/dist/resources/extensions/gsd/auto-tool-tracking.js +25 -7
  19. package/dist/resources/extensions/gsd/auto-worktree.js +21 -0
  20. package/dist/resources/extensions/gsd/auto.js +8 -4
  21. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +105 -70
  22. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +12 -2
  23. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +1 -1
  24. package/dist/resources/extensions/gsd/claude-import.js +60 -9
  25. package/dist/resources/extensions/gsd/commands/handlers/auto.js +69 -6
  26. package/dist/resources/extensions/gsd/commands-config.js +10 -5
  27. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +4 -4
  28. package/dist/resources/extensions/gsd/detection.js +6 -6
  29. package/dist/resources/extensions/gsd/docs/preferences-reference.md +5 -5
  30. package/dist/resources/extensions/gsd/error-classifier.js +105 -0
  31. package/dist/resources/extensions/gsd/git-service.js +4 -3
  32. package/dist/resources/extensions/gsd/gitignore.js +7 -7
  33. package/dist/resources/extensions/gsd/gsd-db.js +298 -45
  34. package/dist/resources/extensions/gsd/init-wizard.js +2 -2
  35. package/dist/resources/extensions/gsd/key-manager.js +7 -16
  36. package/dist/resources/extensions/gsd/markdown-renderer.js +5 -4
  37. package/dist/resources/extensions/gsd/memory-store.js +28 -13
  38. package/dist/resources/extensions/gsd/milestone-actions.js +19 -0
  39. package/dist/resources/extensions/gsd/preferences-models.js +1 -13
  40. package/dist/resources/extensions/gsd/preferences-types.js +1 -1
  41. package/dist/resources/extensions/gsd/preferences.js +13 -13
  42. package/dist/resources/extensions/gsd/prompts/system.md +1 -1
  43. package/dist/resources/extensions/gsd/provider-error-pause.js +0 -44
  44. package/dist/resources/extensions/gsd/rule-registry.js +1 -1
  45. package/dist/resources/extensions/gsd/service-tier.js +13 -2
  46. package/dist/resources/extensions/gsd/state.js +33 -19
  47. package/dist/resources/extensions/gsd/status-guards.js +12 -0
  48. package/dist/resources/extensions/gsd/tools/complete-milestone.js +7 -13
  49. package/dist/resources/extensions/gsd/tools/complete-slice.js +7 -20
  50. package/dist/resources/extensions/gsd/tools/complete-task.js +11 -21
  51. package/dist/resources/extensions/gsd/tools/plan-milestone.js +28 -29
  52. package/dist/resources/extensions/gsd/tools/plan-slice.js +27 -26
  53. package/dist/resources/extensions/gsd/tools/plan-task.js +23 -23
  54. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +50 -41
  55. package/dist/resources/extensions/gsd/tools/reopen-slice.js +4 -3
  56. package/dist/resources/extensions/gsd/tools/reopen-task.js +5 -4
  57. package/dist/resources/extensions/gsd/tools/replan-slice.js +51 -41
  58. package/dist/resources/extensions/gsd/tools/validate-milestone.js +23 -16
  59. package/dist/resources/extensions/gsd/validation.js +21 -0
  60. package/dist/resources/extensions/gsd/workflow-logger.js +0 -1
  61. package/dist/resources/extensions/remote-questions/config.js +1 -1
  62. package/dist/resources/extensions/remote-questions/remote-command.js +1 -1
  63. package/dist/resources/extensions/search-the-web/native-search.js +1 -1
  64. package/dist/resources/extensions/search-the-web/provider.js +1 -1
  65. package/dist/resources/extensions/shared/rtk.js +5 -3
  66. package/dist/rtk.js +3 -1
  67. package/dist/web/standalone/.next/BUILD_ID +1 -1
  68. package/dist/web/standalone/.next/app-path-routes-manifest.json +16 -16
  69. package/dist/web/standalone/.next/build-manifest.json +3 -3
  70. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  71. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  74. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  84. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  85. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  87. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  90. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/experimental/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/experimental/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/index.html +1 -1
  134. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  135. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  137. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  139. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  140. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app-paths-manifest.json +16 -16
  142. package/dist/web/standalone/.next/server/chunks/2229.js +2 -2
  143. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  144. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  146. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  147. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  148. package/dist/web/standalone/.next/static/chunks/4024.21054f459af5cc78.js +9 -0
  149. package/dist/web/standalone/.next/static/chunks/{webpack-cfc9a116e6450a6b.js → webpack-024d82be84800e52.js} +1 -1
  150. package/dist/web/standalone/.next/static/css/a58ef8a151aa0493.css +1 -0
  151. package/dist/wizard.js +4 -1
  152. package/package.json +2 -2
  153. package/packages/mcp-server/README.md +202 -0
  154. package/packages/mcp-server/package.json +36 -0
  155. package/packages/mcp-server/src/cli.ts +68 -0
  156. package/packages/mcp-server/src/index.ts +14 -0
  157. package/packages/mcp-server/src/mcp-server.test.ts +628 -0
  158. package/packages/mcp-server/src/server.ts +278 -0
  159. package/packages/mcp-server/src/session-manager.ts +328 -0
  160. package/packages/mcp-server/src/types.ts +107 -0
  161. package/packages/mcp-server/tsconfig.json +24 -0
  162. package/packages/pi-ai/dist/models.d.ts +14 -3
  163. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  164. package/packages/pi-ai/dist/models.js +53 -10
  165. package/packages/pi-ai/dist/models.js.map +1 -1
  166. package/packages/pi-ai/dist/models.test.js +102 -1
  167. package/packages/pi-ai/dist/models.test.js.map +1 -1
  168. package/packages/pi-ai/dist/types.d.ts +30 -0
  169. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  170. package/packages/pi-ai/dist/types.js.map +1 -1
  171. package/packages/pi-ai/src/models.test.ts +114 -1
  172. package/packages/pi-ai/src/models.ts +70 -13
  173. package/packages/pi-ai/src/types.ts +31 -0
  174. package/packages/pi-coding-agent/dist/cli/args.d.ts +2 -0
  175. package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  176. package/packages/pi-coding-agent/dist/cli/args.js +3 -0
  177. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  178. package/packages/pi-coding-agent/dist/core/bash-executor.d.ts.map +1 -1
  179. package/packages/pi-coding-agent/dist/core/bash-executor.js +5 -1
  180. package/packages/pi-coding-agent/dist/core/bash-executor.js.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  182. package/packages/pi-coding-agent/dist/core/model-registry.js +9 -4
  183. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  184. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts +19 -0
  185. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.d.ts.map +1 -0
  186. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +83 -0
  187. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -0
  188. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/tools/bash.js +5 -1
  190. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  192. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  193. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  194. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  195. package/packages/pi-coding-agent/dist/main.js +5 -3
  196. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  197. package/packages/pi-coding-agent/dist/modes/index.d.ts +1 -1
  198. package/packages/pi-coding-agent/dist/modes/index.d.ts.map +1 -1
  199. package/packages/pi-coding-agent/dist/modes/index.js.map +1 -1
  200. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  201. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +0 -2
  202. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  203. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +28 -1
  204. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  205. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +49 -0
  206. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts +1 -1
  208. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  209. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +114 -6
  210. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  211. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts +9 -0
  212. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.d.ts.map +1 -0
  213. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js +831 -0
  214. package/packages/pi-coding-agent/dist/modes/rpc/rpc-protocol-v2.test.js.map +1 -0
  215. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts +66 -0
  216. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  217. package/packages/pi-coding-agent/dist/modes/rpc/rpc-types.js.map +1 -1
  218. package/packages/pi-coding-agent/dist/utils/shell.d.ts.map +1 -1
  219. package/packages/pi-coding-agent/dist/utils/shell.js +0 -1
  220. package/packages/pi-coding-agent/dist/utils/shell.js.map +1 -1
  221. package/packages/pi-coding-agent/package.json +1 -1
  222. package/packages/pi-coding-agent/src/cli/args.ts +4 -0
  223. package/packages/pi-coding-agent/src/core/bash-executor.ts +5 -1
  224. package/packages/pi-coding-agent/src/core/model-registry.ts +10 -3
  225. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +101 -0
  226. package/packages/pi-coding-agent/src/core/tools/bash.ts +5 -1
  227. package/packages/pi-coding-agent/src/index.ts +3 -0
  228. package/packages/pi-coding-agent/src/main.ts +5 -3
  229. package/packages/pi-coding-agent/src/modes/index.ts +8 -1
  230. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +0 -2
  231. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +54 -1
  232. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +124 -6
  233. package/packages/pi-coding-agent/src/modes/rpc/rpc-protocol-v2.test.ts +971 -0
  234. package/packages/pi-coding-agent/src/modes/rpc/rpc-types.ts +61 -4
  235. package/packages/pi-coding-agent/src/utils/shell.ts +0 -1
  236. package/packages/rpc-client/package.json +20 -0
  237. package/pkg/package.json +1 -1
  238. package/scripts/ensure-workspace-builds.cjs +36 -8
  239. package/src/resources/extensions/async-jobs/async-bash-tool.ts +22 -11
  240. package/src/resources/extensions/async-jobs/job-manager.ts +4 -1
  241. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +19 -20
  242. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +21 -0
  243. package/src/resources/extensions/gsd/auto/phases.ts +6 -0
  244. package/src/resources/extensions/gsd/auto-dispatch.ts +19 -0
  245. package/src/resources/extensions/gsd/auto-start.ts +2 -0
  246. package/src/resources/extensions/gsd/auto-timers.ts +25 -1
  247. package/src/resources/extensions/gsd/auto-tool-tracking.ts +30 -6
  248. package/src/resources/extensions/gsd/auto-worktree.ts +21 -0
  249. package/src/resources/extensions/gsd/auto.ts +10 -4
  250. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +125 -73
  251. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +11 -2
  252. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +1 -1
  253. package/src/resources/extensions/gsd/claude-import.ts +58 -9
  254. package/src/resources/extensions/gsd/commands/handlers/auto.ts +73 -6
  255. package/src/resources/extensions/gsd/commands-config.ts +11 -5
  256. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +4 -4
  257. package/src/resources/extensions/gsd/detection.ts +6 -6
  258. package/src/resources/extensions/gsd/docs/preferences-reference.md +5 -5
  259. package/src/resources/extensions/gsd/error-classifier.ts +139 -0
  260. package/src/resources/extensions/gsd/git-service.ts +4 -3
  261. package/src/resources/extensions/gsd/gitignore.ts +7 -7
  262. package/src/resources/extensions/gsd/gsd-db.ts +355 -63
  263. package/src/resources/extensions/gsd/init-wizard.ts +2 -2
  264. package/src/resources/extensions/gsd/key-manager.ts +7 -16
  265. package/src/resources/extensions/gsd/markdown-renderer.ts +5 -4
  266. package/src/resources/extensions/gsd/memory-store.ts +29 -18
  267. package/src/resources/extensions/gsd/milestone-actions.ts +17 -0
  268. package/src/resources/extensions/gsd/preferences-models.ts +1 -13
  269. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  270. package/src/resources/extensions/gsd/preferences.ts +12 -13
  271. package/src/resources/extensions/gsd/prompts/system.md +1 -1
  272. package/src/resources/extensions/gsd/provider-error-pause.ts +0 -57
  273. package/src/resources/extensions/gsd/rule-registry.ts +1 -1
  274. package/src/resources/extensions/gsd/service-tier.ts +14 -2
  275. package/src/resources/extensions/gsd/state.ts +34 -20
  276. package/src/resources/extensions/gsd/status-guards.ts +13 -0
  277. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -1
  278. package/src/resources/extensions/gsd/tests/auto-milestone-target.test.ts +61 -0
  279. package/src/resources/extensions/gsd/tests/claude-import-marketplace-discovery.test.ts +191 -0
  280. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +1 -1
  281. package/src/resources/extensions/gsd/tests/commands-config.test.ts +24 -0
  282. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  283. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +106 -0
  284. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  285. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +35 -7
  286. package/src/resources/extensions/gsd/tests/detection.test.ts +1 -1
  287. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +4 -4
  288. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +1 -1
  289. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +2 -2
  290. package/src/resources/extensions/gsd/tests/empty-db-reconciliation.test.ts +79 -0
  291. package/src/resources/extensions/gsd/tests/git-service.test.ts +37 -4
  292. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +1 -1
  293. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +125 -0
  294. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +1 -1
  295. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +119 -0
  296. package/src/resources/extensions/gsd/tests/key-manager.test.ts +16 -1
  297. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  298. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  299. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +7 -7
  300. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +85 -0
  301. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +91 -0
  302. package/src/resources/extensions/gsd/tests/preferences.test.ts +2 -2
  303. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +77 -70
  304. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +110 -0
  305. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +29 -0
  306. package/src/resources/extensions/gsd/tests/status-guards.test.ts +30 -0
  307. package/src/resources/extensions/gsd/tests/terminated-transient.test.ts +42 -31
  308. package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +2 -2
  309. package/src/resources/extensions/gsd/tests/vacuous-truth-slices.test.ts +115 -0
  310. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +90 -0
  311. package/src/resources/extensions/gsd/tests/validation.test.ts +72 -0
  312. package/src/resources/extensions/gsd/tests/workflow-logger.test.ts +81 -1
  313. package/src/resources/extensions/gsd/tests/worktree-preferences-sync.test.ts +130 -0
  314. package/src/resources/extensions/gsd/tools/complete-milestone.ts +7 -17
  315. package/src/resources/extensions/gsd/tools/complete-slice.ts +7 -24
  316. package/src/resources/extensions/gsd/tools/complete-task.ts +13 -25
  317. package/src/resources/extensions/gsd/tools/plan-milestone.ts +30 -32
  318. package/src/resources/extensions/gsd/tools/plan-slice.ts +30 -30
  319. package/src/resources/extensions/gsd/tools/plan-task.ts +26 -26
  320. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +57 -46
  321. package/src/resources/extensions/gsd/tools/reopen-slice.ts +4 -3
  322. package/src/resources/extensions/gsd/tools/reopen-task.ts +5 -4
  323. package/src/resources/extensions/gsd/tools/replan-slice.ts +55 -44
  324. package/src/resources/extensions/gsd/tools/validate-milestone.ts +26 -20
  325. package/src/resources/extensions/gsd/validation.ts +23 -0
  326. package/src/resources/extensions/gsd/workflow-logger.ts +0 -1
  327. package/src/resources/extensions/remote-questions/config.ts +1 -1
  328. package/src/resources/extensions/remote-questions/remote-command.ts +1 -1
  329. package/src/resources/extensions/search-the-web/native-search.ts +1 -1
  330. package/src/resources/extensions/search-the-web/provider.ts +1 -1
  331. package/src/resources/extensions/shared/rtk.ts +12 -3
  332. package/dist/web/standalone/.next/static/chunks/4024.9ad5def014d90ce4.js +0 -9
  333. package/dist/web/standalone/.next/static/css/de141508b083f922.css +0 -1
  334. /package/dist/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +0 -0
  335. /package/dist/web/standalone/.next/static/{5_KeZz1X0tXJK-d_4OhjB → KTe1kB5nPLQFIIFz2OcmI}/_buildManifest.js +0 -0
  336. /package/dist/web/standalone/.next/static/{5_KeZz1X0tXJK-d_4OhjB → KTe1kB5nPLQFIIFz2OcmI}/_ssgManifest.js +0 -0
  337. /package/src/resources/extensions/gsd/templates/{preferences.md → PREFERENCES.md} +0 -0
@@ -0,0 +1,107 @@
1
+ /**
2
+ * MCP Server types — session lifecycle and orchestration.
3
+ */
4
+
5
+ import type { RpcClient, SdkAgentEvent, RpcCostUpdateEvent, RpcExtensionUIRequest } from '@gsd/rpc-client';
6
+
7
+ // ---------------------------------------------------------------------------
8
+ // Session Status
9
+ // ---------------------------------------------------------------------------
10
+
11
+ export type SessionStatus = 'starting' | 'running' | 'blocked' | 'completed' | 'error' | 'cancelled';
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Managed Session
15
+ // ---------------------------------------------------------------------------
16
+
17
+ export interface ManagedSession {
18
+ /** Unique session ID returned from RpcClient.init() */
19
+ sessionId: string;
20
+
21
+ /** Absolute path to the project directory */
22
+ projectDir: string;
23
+
24
+ /** Current lifecycle status */
25
+ status: SessionStatus;
26
+
27
+ /** The RpcClient instance managing the agent process */
28
+ client: RpcClient;
29
+
30
+ /** Ring buffer of recent events (capped at MAX_EVENTS) */
31
+ events: SdkAgentEvent[];
32
+
33
+ /** Pending blocker requiring user response, if any */
34
+ pendingBlocker: PendingBlocker | null;
35
+
36
+ /** Cumulative cost tracking (max pattern per K004) */
37
+ cost: CostAccumulator;
38
+
39
+ /** Session start timestamp */
40
+ startTime: number;
41
+
42
+ /** Error message if status is 'error' */
43
+ error?: string;
44
+
45
+ /** Cleanup function to unsubscribe from events */
46
+ unsubscribe?: () => void;
47
+ }
48
+
49
+ // ---------------------------------------------------------------------------
50
+ // Pending Blocker
51
+ // ---------------------------------------------------------------------------
52
+
53
+ export interface PendingBlocker {
54
+ /** The extension_ui_request id */
55
+ id: string;
56
+
57
+ /** The request method (e.g. 'select', 'confirm', 'input') */
58
+ method: string;
59
+
60
+ /** Human-readable message or title */
61
+ message: string;
62
+
63
+ /** Full event payload for inspection */
64
+ event: RpcExtensionUIRequest;
65
+ }
66
+
67
+ // ---------------------------------------------------------------------------
68
+ // Cost Accumulator (K004 — cumulative-max)
69
+ // ---------------------------------------------------------------------------
70
+
71
+ export interface CostAccumulator {
72
+ totalCost: number;
73
+ tokens: {
74
+ input: number;
75
+ output: number;
76
+ cacheRead: number;
77
+ cacheWrite: number;
78
+ };
79
+ }
80
+
81
+ // ---------------------------------------------------------------------------
82
+ // Execute Options
83
+ // ---------------------------------------------------------------------------
84
+
85
+ export interface ExecuteOptions {
86
+ /** Command to send after '/gsd auto' (default: none) */
87
+ command?: string;
88
+
89
+ /** Model ID override */
90
+ model?: string;
91
+
92
+ /** Run in bare mode (skip user config) */
93
+ bare?: boolean;
94
+
95
+ /** Path to CLI binary (overrides GSD_CLI_PATH and which resolution) */
96
+ cliPath?: string;
97
+ }
98
+
99
+ // ---------------------------------------------------------------------------
100
+ // Constants
101
+ // ---------------------------------------------------------------------------
102
+
103
+ /** Maximum number of events kept in the ring buffer */
104
+ export const MAX_EVENTS = 50;
105
+
106
+ /** Timeout for RpcClient initialization (ms) */
107
+ export const INIT_TIMEOUT_MS = 30_000;
@@ -0,0 +1,24 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2024",
4
+ "module": "Node16",
5
+ "lib": ["ES2024"],
6
+ "strict": true,
7
+ "esModuleInterop": true,
8
+ "skipLibCheck": true,
9
+ "forceConsistentCasingInFileNames": true,
10
+ "declaration": true,
11
+ "declarationMap": true,
12
+ "sourceMap": true,
13
+ "inlineSources": true,
14
+ "inlineSourceMap": false,
15
+ "moduleResolution": "Node16",
16
+ "resolveJsonModule": true,
17
+ "allowImportingTsExtensions": false,
18
+ "types": ["node"],
19
+ "outDir": "./dist",
20
+ "rootDir": "./src"
21
+ },
22
+ "include": ["src/**/*.ts"],
23
+ "exclude": ["node_modules", "dist", "**/*.d.ts", "src/**/*.d.ts"]
24
+ }
@@ -1,5 +1,16 @@
1
1
  import { MODELS } from "./models.generated.js";
2
2
  import type { Api, KnownProvider, Model, Usage } from "./types.js";
3
+ /**
4
+ * Apply capability patches to a list of models.
5
+ *
6
+ * Models constructed outside the static pi-ai registry (custom models from
7
+ * models.json, extension-registered models, discovered models) do not pass
8
+ * through the module-init patch loop. Call this function after assembling
9
+ * any model list to ensure capabilities are set correctly.
10
+ *
11
+ * Explicit `capabilities` already set on a model take precedence over patches.
12
+ */
13
+ export declare function applyCapabilityPatches(models: Model<Api>[]): Model<Api>[];
3
14
  /** Providers that have entries in the generated MODELS constant */
4
15
  type GeneratedProvider = keyof typeof MODELS & KnownProvider;
5
16
  type ModelApi<TProvider extends GeneratedProvider, TModelId extends keyof (typeof MODELS)[TProvider]> = (typeof MODELS)[TProvider][TModelId] extends {
@@ -12,9 +23,9 @@ export declare function calculateCost<TApi extends Api>(model: Model<TApi>, usag
12
23
  /**
13
24
  * Check if a model supports xhigh thinking level.
14
25
  *
15
- * Supported today:
16
- * - GPT-5.2 / GPT-5.3 / GPT-5.4 model families
17
- * - Anthropic Messages API Opus 4.6 models (xhigh maps to adaptive effort "max")
26
+ * Reads from `model.capabilities.supportsXhigh` — set via CAPABILITY_PATCHES
27
+ * for generated models or declared directly in custom model definitions.
28
+ * Do not add model-ID or provider-name checks here; update CAPABILITY_PATCHES instead.
18
29
  */
19
30
  export declare function supportsXhigh<TApi extends Api>(model: Model<TApi>): boolean;
20
31
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AA4BnE,mEAAmE;AACnE,KAAK,iBAAiB,GAAG,MAAM,OAAO,MAAM,GAAG,aAAa,CAAC;AAE7D,KAAK,QAAQ,CACZ,SAAS,SAAS,iBAAiB,EACnC,QAAQ,SAAS,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,IAC9C,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,IAAI,CAAA;CAAE,GAAG,CAAC,IAAI,SAAS,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;AAEjH,wBAAgB,QAAQ,CAAC,SAAS,SAAS,iBAAiB,EAAE,QAAQ,SAAS,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,EAC9G,QAAQ,EAAE,SAAS,EACnB,OAAO,EAAE,QAAQ,GACf,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAGtC;AAED,wBAAgB,YAAY,IAAI,aAAa,EAAE,CAE9C;AAED,wBAAgB,SAAS,CAAC,SAAS,SAAS,aAAa,EACxD,QAAQ,EAAE,SAAS,GACjB,KAAK,CAAC,GAAG,CAAC,EAAE,CAGd;AAED,wBAAgB,aAAa,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAO/F;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAU3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,SAAS,GAAG,EAC9C,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,EACjC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,GAC/B,OAAO,CAGT"}
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAE/C,OAAO,KAAK,EAAE,GAAG,EAAE,aAAa,EAAE,KAAK,EAAqB,KAAK,EAAE,MAAM,YAAY,CAAC;AAsDtF;;;;;;;;;GASG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,EAAE,CAYzE;AAiBD,mEAAmE;AACnE,KAAK,iBAAiB,GAAG,MAAM,OAAO,MAAM,GAAG,aAAa,CAAC;AAE7D,KAAK,QAAQ,CACZ,SAAS,SAAS,iBAAiB,EACnC,QAAQ,SAAS,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,IAC9C,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,IAAI,CAAA;CAAE,GAAG,CAAC,IAAI,SAAS,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,KAAK,CAAC;AAEjH,wBAAgB,QAAQ,CAAC,SAAS,SAAS,iBAAiB,EAAE,QAAQ,SAAS,MAAM,CAAC,OAAO,MAAM,CAAC,CAAC,SAAS,CAAC,EAC9G,QAAQ,EAAE,SAAS,EACnB,OAAO,EAAE,QAAQ,GACf,KAAK,CAAC,QAAQ,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAGtC;AAED,wBAAgB,YAAY,IAAI,aAAa,EAAE,CAE9C;AAED,wBAAgB,SAAS,CAAC,SAAS,SAAS,aAAa,EACxD,QAAQ,EAAE,SAAS,GACjB,KAAK,CAAC,GAAG,CAAC,EAAE,CAGd;AAED,wBAAgB,aAAa,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAO/F;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,IAAI,SAAS,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAE3E;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,SAAS,GAAG,EAC9C,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,EACjC,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,GAAG,SAAS,GAC/B,OAAO,CAGT"}
@@ -23,6 +23,55 @@ for (const [provider, models] of Object.entries(CUSTOM_MODELS)) {
23
23
  }
24
24
  }
25
25
  }
26
+ const CAPABILITY_PATCHES = [
27
+ // GPT-5.x supports xhigh thinking and OpenAI service tiers
28
+ {
29
+ match: (m) => m.id.includes("gpt-5.2") || m.id.includes("gpt-5.3") || m.id.includes("gpt-5.4"),
30
+ caps: { supportsXhigh: true, supportsServiceTier: true },
31
+ },
32
+ // Anthropic Opus 4.6 supports xhigh thinking
33
+ {
34
+ match: (m) => m.api === "anthropic-messages" && (m.id.includes("opus-4-6") || m.id.includes("opus-4.6")),
35
+ caps: { supportsXhigh: true },
36
+ },
37
+ ];
38
+ /**
39
+ * Apply capability patches to a list of models.
40
+ *
41
+ * Models constructed outside the static pi-ai registry (custom models from
42
+ * models.json, extension-registered models, discovered models) do not pass
43
+ * through the module-init patch loop. Call this function after assembling
44
+ * any model list to ensure capabilities are set correctly.
45
+ *
46
+ * Explicit `capabilities` already set on a model take precedence over patches.
47
+ */
48
+ export function applyCapabilityPatches(models) {
49
+ return models.map((model) => {
50
+ for (const patch of CAPABILITY_PATCHES) {
51
+ if (patch.match(model)) {
52
+ return {
53
+ ...model,
54
+ capabilities: { ...patch.caps, ...model.capabilities },
55
+ };
56
+ }
57
+ }
58
+ return model;
59
+ });
60
+ }
61
+ // Apply patches to the static registry at module load
62
+ for (const [, providerModels] of modelRegistry) {
63
+ for (const [id, model] of providerModels) {
64
+ for (const patch of CAPABILITY_PATCHES) {
65
+ if (patch.match(model)) {
66
+ providerModels.set(id, {
67
+ ...model,
68
+ capabilities: { ...patch.caps, ...model.capabilities },
69
+ });
70
+ break;
71
+ }
72
+ }
73
+ }
74
+ }
26
75
  export function getModel(provider, modelId) {
27
76
  const providerModels = modelRegistry.get(provider);
28
77
  return providerModels?.get(modelId);
@@ -45,18 +94,12 @@ export function calculateCost(model, usage) {
45
94
  /**
46
95
  * Check if a model supports xhigh thinking level.
47
96
  *
48
- * Supported today:
49
- * - GPT-5.2 / GPT-5.3 / GPT-5.4 model families
50
- * - Anthropic Messages API Opus 4.6 models (xhigh maps to adaptive effort "max")
97
+ * Reads from `model.capabilities.supportsXhigh` — set via CAPABILITY_PATCHES
98
+ * for generated models or declared directly in custom model definitions.
99
+ * Do not add model-ID or provider-name checks here; update CAPABILITY_PATCHES instead.
51
100
  */
52
101
  export function supportsXhigh(model) {
53
- if (model.id.includes("gpt-5.2") || model.id.includes("gpt-5.3") || model.id.includes("gpt-5.4")) {
54
- return true;
55
- }
56
- if (model.api === "anthropic-messages") {
57
- return model.id.includes("opus-4-6") || model.id.includes("opus-4.6");
58
- }
59
- return false;
102
+ return model.capabilities?.supportsXhigh ?? false;
60
103
  }
61
104
  /**
62
105
  * Check if two models are equal by comparing both their id and provider.
@@ -1 +1 @@
1
- {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import { MODELS } from \"./models.generated.js\";\nimport { CUSTOM_MODELS } from \"./models.custom.js\";\nimport type { Api, KnownProvider, Model, Usage } from \"./types.js\";\n\nconst modelRegistry: Map<string, Map<string, Model<Api>>> = new Map();\n\n// Initialize registry from auto-generated MODELS (models.dev catalog)\nfor (const [provider, models] of Object.entries(MODELS)) {\n\tconst providerModels = new Map<string, Model<Api>>();\n\tfor (const [id, model] of Object.entries(models)) {\n\t\tproviderModels.set(id, model as Model<Api>);\n\t}\n\tmodelRegistry.set(provider, providerModels);\n}\n\n// Merge manually-maintained custom providers that are NOT in models.dev.\n// Custom models are additive — they never overwrite generated entries.\n// See: https://github.com/gsd-build/gsd-2/issues/2339\nfor (const [provider, models] of Object.entries(CUSTOM_MODELS)) {\n\tif (!modelRegistry.has(provider)) {\n\t\tmodelRegistry.set(provider, new Map<string, Model<Api>>());\n\t}\n\tconst providerModels = modelRegistry.get(provider)!;\n\tfor (const [id, model] of Object.entries(models)) {\n\t\tif (!providerModels.has(id)) {\n\t\t\tproviderModels.set(id, model as Model<Api>);\n\t\t}\n\t}\n}\n\n/** Providers that have entries in the generated MODELS constant */\ntype GeneratedProvider = keyof typeof MODELS & KnownProvider;\n\ntype ModelApi<\n\tTProvider extends GeneratedProvider,\n\tTModelId extends keyof (typeof MODELS)[TProvider],\n> = (typeof MODELS)[TProvider][TModelId] extends { api: infer TApi } ? (TApi extends Api ? TApi : never) : never;\n\nexport function getModel<TProvider extends GeneratedProvider, TModelId extends keyof (typeof MODELS)[TProvider]>(\n\tprovider: TProvider,\n\tmodelId: TModelId,\n): Model<ModelApi<TProvider, TModelId>> {\n\tconst providerModels = modelRegistry.get(provider);\n\treturn providerModels?.get(modelId as string) as Model<ModelApi<TProvider, TModelId>>;\n}\n\nexport function getProviders(): KnownProvider[] {\n\treturn Array.from(modelRegistry.keys()) as KnownProvider[];\n}\n\nexport function getModels<TProvider extends KnownProvider>(\n\tprovider: TProvider,\n): Model<Api>[] {\n\tconst models = modelRegistry.get(provider);\n\treturn models ? (Array.from(models.values()) as Model<Api>[]) : [];\n}\n\nexport function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage): Usage[\"cost\"] {\n\tusage.cost.input = (model.cost.input / 1000000) * usage.input;\n\tusage.cost.output = (model.cost.output / 1000000) * usage.output;\n\tusage.cost.cacheRead = (model.cost.cacheRead / 1000000) * usage.cacheRead;\n\tusage.cost.cacheWrite = (model.cost.cacheWrite / 1000000) * usage.cacheWrite;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n\treturn usage.cost;\n}\n\n/**\n * Check if a model supports xhigh thinking level.\n *\n * Supported today:\n * - GPT-5.2 / GPT-5.3 / GPT-5.4 model families\n * - Anthropic Messages API Opus 4.6 models (xhigh maps to adaptive effort \"max\")\n */\nexport function supportsXhigh<TApi extends Api>(model: Model<TApi>): boolean {\n\tif (model.id.includes(\"gpt-5.2\") || model.id.includes(\"gpt-5.3\") || model.id.includes(\"gpt-5.4\")) {\n\t\treturn true;\n\t}\n\n\tif (model.api === \"anthropic-messages\") {\n\t\treturn model.id.includes(\"opus-4-6\") || model.id.includes(\"opus-4.6\");\n\t}\n\n\treturn false;\n}\n\n/**\n * Check if two models are equal by comparing both their id and provider.\n * Returns false if either model is null or undefined.\n */\nexport function modelsAreEqual<TApi extends Api>(\n\ta: Model<TApi> | null | undefined,\n\tb: Model<TApi> | null | undefined,\n): boolean {\n\tif (!a || !b) return false;\n\treturn a.id === b.id && a.provider === b.provider;\n}\n"]}
1
+ {"version":3,"file":"models.js","sourceRoot":"","sources":["../src/models.ts"],"names":[],"mappings":"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","sourcesContent":["import { MODELS } from \"./models.generated.js\";\nimport { CUSTOM_MODELS } from \"./models.custom.js\";\nimport type { Api, KnownProvider, Model, ModelCapabilities, Usage } from \"./types.js\";\n\nconst modelRegistry: Map<string, Map<string, Model<Api>>> = new Map();\n\n// Initialize registry from auto-generated MODELS (models.dev catalog)\nfor (const [provider, models] of Object.entries(MODELS)) {\n\tconst providerModels = new Map<string, Model<Api>>();\n\tfor (const [id, model] of Object.entries(models)) {\n\t\tproviderModels.set(id, model as Model<Api>);\n\t}\n\tmodelRegistry.set(provider, providerModels);\n}\n\n// Merge manually-maintained custom providers that are NOT in models.dev.\n// Custom models are additive — they never overwrite generated entries.\n// See: https://github.com/gsd-build/gsd-2/issues/2339\nfor (const [provider, models] of Object.entries(CUSTOM_MODELS)) {\n\tif (!modelRegistry.has(provider)) {\n\t\tmodelRegistry.set(provider, new Map<string, Model<Api>>());\n\t}\n\tconst providerModels = modelRegistry.get(provider)!;\n\tfor (const [id, model] of Object.entries(models)) {\n\t\tif (!providerModels.has(id)) {\n\t\t\tproviderModels.set(id, model as Model<Api>);\n\t\t}\n\t}\n}\n\n// ─── Capability Patches ───────────────────────────────────────────────────────\n//\n// Declare capabilities for models that pre-date the `capabilities` field or\n// that live in the auto-generated catalog (models.generated.ts) which we\n// cannot edit directly. Pattern-matching on model IDs is acceptable HERE\n// because this is the single source of truth — call sites must never repeat it.\n//\n// Add new entries as additional capabilities emerge. Existing models that\n// define `capabilities` in their model definition take precedence (the patch\n// only fills in fields that are not already set).\n\ntype CapabilityPatch = { match: (m: Model<Api>) => boolean; caps: ModelCapabilities };\n\nconst CAPABILITY_PATCHES: CapabilityPatch[] = [\n\t// GPT-5.x supports xhigh thinking and OpenAI service tiers\n\t{\n\t\tmatch: (m) => m.id.includes(\"gpt-5.2\") || m.id.includes(\"gpt-5.3\") || m.id.includes(\"gpt-5.4\"),\n\t\tcaps: { supportsXhigh: true, supportsServiceTier: true },\n\t},\n\t// Anthropic Opus 4.6 supports xhigh thinking\n\t{\n\t\tmatch: (m) => m.api === \"anthropic-messages\" && (m.id.includes(\"opus-4-6\") || m.id.includes(\"opus-4.6\")),\n\t\tcaps: { supportsXhigh: true },\n\t},\n];\n\n/**\n * Apply capability patches to a list of models.\n *\n * Models constructed outside the static pi-ai registry (custom models from\n * models.json, extension-registered models, discovered models) do not pass\n * through the module-init patch loop. Call this function after assembling\n * any model list to ensure capabilities are set correctly.\n *\n * Explicit `capabilities` already set on a model take precedence over patches.\n */\nexport function applyCapabilityPatches(models: Model<Api>[]): Model<Api>[] {\n\treturn models.map((model) => {\n\t\tfor (const patch of CAPABILITY_PATCHES) {\n\t\t\tif (patch.match(model)) {\n\t\t\t\treturn {\n\t\t\t\t\t...model,\n\t\t\t\t\tcapabilities: { ...patch.caps, ...model.capabilities },\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t\treturn model;\n\t});\n}\n\n// Apply patches to the static registry at module load\nfor (const [, providerModels] of modelRegistry) {\n\tfor (const [id, model] of providerModels) {\n\t\tfor (const patch of CAPABILITY_PATCHES) {\n\t\t\tif (patch.match(model)) {\n\t\t\t\tproviderModels.set(id, {\n\t\t\t\t\t...model,\n\t\t\t\t\tcapabilities: { ...patch.caps, ...model.capabilities },\n\t\t\t\t});\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n\n/** Providers that have entries in the generated MODELS constant */\ntype GeneratedProvider = keyof typeof MODELS & KnownProvider;\n\ntype ModelApi<\n\tTProvider extends GeneratedProvider,\n\tTModelId extends keyof (typeof MODELS)[TProvider],\n> = (typeof MODELS)[TProvider][TModelId] extends { api: infer TApi } ? (TApi extends Api ? TApi : never) : never;\n\nexport function getModel<TProvider extends GeneratedProvider, TModelId extends keyof (typeof MODELS)[TProvider]>(\n\tprovider: TProvider,\n\tmodelId: TModelId,\n): Model<ModelApi<TProvider, TModelId>> {\n\tconst providerModels = modelRegistry.get(provider);\n\treturn providerModels?.get(modelId as string) as Model<ModelApi<TProvider, TModelId>>;\n}\n\nexport function getProviders(): KnownProvider[] {\n\treturn Array.from(modelRegistry.keys()) as KnownProvider[];\n}\n\nexport function getModels<TProvider extends KnownProvider>(\n\tprovider: TProvider,\n): Model<Api>[] {\n\tconst models = modelRegistry.get(provider);\n\treturn models ? (Array.from(models.values()) as Model<Api>[]) : [];\n}\n\nexport function calculateCost<TApi extends Api>(model: Model<TApi>, usage: Usage): Usage[\"cost\"] {\n\tusage.cost.input = (model.cost.input / 1000000) * usage.input;\n\tusage.cost.output = (model.cost.output / 1000000) * usage.output;\n\tusage.cost.cacheRead = (model.cost.cacheRead / 1000000) * usage.cacheRead;\n\tusage.cost.cacheWrite = (model.cost.cacheWrite / 1000000) * usage.cacheWrite;\n\tusage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;\n\treturn usage.cost;\n}\n\n/**\n * Check if a model supports xhigh thinking level.\n *\n * Reads from `model.capabilities.supportsXhigh` — set via CAPABILITY_PATCHES\n * for generated models or declared directly in custom model definitions.\n * Do not add model-ID or provider-name checks here; update CAPABILITY_PATCHES instead.\n */\nexport function supportsXhigh<TApi extends Api>(model: Model<TApi>): boolean {\n\treturn model.capabilities?.supportsXhigh ?? false;\n}\n\n/**\n * Check if two models are equal by comparing both their id and provider.\n * Returns false if either model is null or undefined.\n */\nexport function modelsAreEqual<TApi extends Api>(\n\ta: Model<TApi> | null | undefined,\n\tb: Model<TApi> | null | undefined,\n): boolean {\n\tif (!a || !b) return false;\n\treturn a.id === b.id && a.provider === b.provider;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import { describe, it } from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { getProviders, getModels, getModel } from "./models.js";
3
+ import { getProviders, getModels, getModel, supportsXhigh, applyCapabilityPatches } from "./models.js";
4
4
  // ═══════════════════════════════════════════════════════════════════════════
5
5
  // Custom provider preservation (regression: #2339)
6
6
  //
@@ -64,4 +64,105 @@ describe("model registry — custom models do not collide with generated models"
64
64
  assert.ok(providers.includes("anthropic"), "anthropic should be in providers");
65
65
  });
66
66
  });
67
+ // ═══════════════════════════════════════════════════════════════════════════
68
+ // Capability patches (regression: #2546)
69
+ //
70
+ // CAPABILITY_PATCHES must apply capabilities to models in the static
71
+ // registry AND to models constructed outside of it (custom, extension,
72
+ // discovered). supportsXhigh() reads model.capabilities — not model IDs.
73
+ // ═══════════════════════════════════════════════════════════════════════════
74
+ /** Helper: build a minimal synthetic model for testing */
75
+ function syntheticModel(overrides) {
76
+ return {
77
+ id: "test-model",
78
+ name: "Test Model",
79
+ api: "openai-completions",
80
+ provider: "test-provider",
81
+ baseUrl: "https://example.com",
82
+ reasoning: false,
83
+ input: ["text"],
84
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
85
+ contextWindow: 128000,
86
+ maxTokens: 16384,
87
+ ...overrides,
88
+ };
89
+ }
90
+ describe("supportsXhigh — registry models", () => {
91
+ it("returns true for GPT-5.4 from the registry", () => {
92
+ const model = getModel("openai", "gpt-5.4");
93
+ if (!model)
94
+ return; // skip if model not in generated catalog
95
+ assert.equal(supportsXhigh(model), true);
96
+ });
97
+ it("returns false for a non-reasoning model", () => {
98
+ const models = getModels("openai");
99
+ const nonXhigh = models.find((m) => !m.id.includes("gpt-5."));
100
+ if (!nonXhigh)
101
+ return;
102
+ assert.equal(supportsXhigh(nonXhigh), false);
103
+ });
104
+ });
105
+ describe("supportsXhigh — synthetic models (regression: custom/extension models)", () => {
106
+ it("returns false for a model without capabilities", () => {
107
+ const model = syntheticModel({ id: "my-custom-model" });
108
+ assert.equal(supportsXhigh(model), false);
109
+ });
110
+ it("returns true when capabilities.supportsXhigh is explicitly set", () => {
111
+ const model = syntheticModel({
112
+ id: "my-custom-model",
113
+ capabilities: { supportsXhigh: true },
114
+ });
115
+ assert.equal(supportsXhigh(model), true);
116
+ });
117
+ });
118
+ describe("applyCapabilityPatches", () => {
119
+ it("patches a GPT-5.4 model that has no capabilities", () => {
120
+ const model = syntheticModel({ id: "gpt-5.4-custom" });
121
+ assert.equal(model.capabilities, undefined);
122
+ const [patched] = applyCapabilityPatches([model]);
123
+ assert.equal(patched.capabilities?.supportsXhigh, true);
124
+ assert.equal(patched.capabilities?.supportsServiceTier, true);
125
+ });
126
+ it("patches a GPT-5.2 model", () => {
127
+ const model = syntheticModel({ id: "gpt-5.2" });
128
+ const [patched] = applyCapabilityPatches([model]);
129
+ assert.equal(patched.capabilities?.supportsXhigh, true);
130
+ });
131
+ it("patches an Anthropic Opus 4.6 model", () => {
132
+ const model = syntheticModel({
133
+ id: "claude-opus-4-6-20260301",
134
+ api: "anthropic-messages",
135
+ });
136
+ const [patched] = applyCapabilityPatches([model]);
137
+ assert.equal(patched.capabilities?.supportsXhigh, true);
138
+ // Opus should not get supportsServiceTier
139
+ assert.equal(patched.capabilities?.supportsServiceTier, undefined);
140
+ });
141
+ it("preserves explicit capabilities over patches", () => {
142
+ const model = syntheticModel({
143
+ id: "gpt-5.4-custom",
144
+ capabilities: { supportsXhigh: false, charsPerToken: 3 },
145
+ });
146
+ const [patched] = applyCapabilityPatches([model]);
147
+ // Explicit supportsXhigh: false wins over patch's true
148
+ assert.equal(patched.capabilities?.supportsXhigh, false);
149
+ // Patch fills in supportsServiceTier since it wasn't explicitly set
150
+ assert.equal(patched.capabilities?.supportsServiceTier, true);
151
+ // Explicit charsPerToken is preserved
152
+ assert.equal(patched.capabilities?.charsPerToken, 3);
153
+ });
154
+ it("does not modify models that match no patches", () => {
155
+ const model = syntheticModel({ id: "gemini-2.5-pro" });
156
+ const [patched] = applyCapabilityPatches([model]);
157
+ assert.equal(patched.capabilities, undefined);
158
+ // Should return the same reference when unpatched
159
+ assert.equal(patched, model);
160
+ });
161
+ it("is idempotent — re-applying patches produces the same result", () => {
162
+ const model = syntheticModel({ id: "gpt-5.3" });
163
+ const first = applyCapabilityPatches([model]);
164
+ const second = applyCapabilityPatches(first);
165
+ assert.deepEqual(first[0].capabilities, second[0].capabilities);
166
+ });
167
+ });
67
168
  //# sourceMappingURL=models.test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"models.test.js","sourceRoot":"","sources":["../src/models.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEhE,8EAA8E;AAC9E,mDAAmD;AACnD,EAAE;AACF,0EAA0E;AAC1E,qEAAqE;AACrE,8CAA8C;AAC9C,8EAA8E;AAE9E,QAAQ,CAAC,mCAAmC,EAAE,GAAG,EAAE;IAClD,EAAE,CAAC,8CAA8C,EAAE,GAAG,EAAE;QACvD,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QACjC,MAAM,CAAC,EAAE,CACR,SAAS,CAAC,QAAQ,CAAC,qBAAqB,CAAC,EACzC,qDAAqD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC3E,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6CAA6C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAChD,MAAM,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG;YAChB,cAAc;YACd,SAAS;YACT,OAAO;YACP,WAAW;YACX,kBAAkB;YAClB,kBAAkB;YAClB,sBAAsB;YACtB,cAAc;SACd,CAAC;QACF,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IACjC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,GAAG,EAAE;QAC9D,MAAM,MAAM,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAK,CACX,KAAK,CAAC,OAAO,EACb,+CAA+C,EAC/C,SAAS,KAAK,CAAC,EAAE,uBAAuB,KAAK,CAAC,OAAO,EAAE,CACvD,CAAC;QACH,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAChE,MAAM,MAAM,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,EAAE,oBAAoB,EAAE,SAAS,KAAK,CAAC,EAAE,mBAAmB,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC;QAChG,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wDAAwD,EAAE,GAAG,EAAE;QACjE,MAAM,MAAM,GAAG,SAAS,CAAC,qBAAqB,CAAC,CAAC;QAChD,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC5B,MAAM,CAAC,KAAK,CACX,KAAK,CAAC,QAAQ,EACd,qBAAqB,EACrB,SAAS,KAAK,CAAC,EAAE,wBAAwB,KAAK,CAAC,QAAQ,EAAE,CACzD,CAAC;QACH,CAAC;IACF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACvE,6EAA6E;QAC7E,mEAAmE;QACnE,8EAA8E;QAC9E,MAAM,KAAK,GAAG,QAAQ,CAAC,qBAA4B,EAAE,cAAqB,CAAC,CAAC;QAC5E,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,0EAA0E,CAAC,CAAC;QAC7F,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,qBAAqB,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,qEAAqE,EAAE,GAAG,EAAE;IACpF,EAAE,CAAC,4DAA4D,EAAE,GAAG,EAAE;QACrE,MAAM,SAAS,GAAG,YAAY,EAAE,CAAC;QACjC,uCAAuC;QACvC,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,+BAA+B,CAAC,CAAC;QACzE,MAAM,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,CAAC,EAAE,kCAAkC,CAAC,CAAC;IAChF,CAAC,CAAC,CAAC;AACJ,CAAC,CAAC,CAAC","sourcesContent":["import { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { getProviders, getModels, getModel } from \"./models.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Custom provider preservation (regression: #2339)\n//\n// Custom providers (like alibaba-coding-plan) are manually maintained and\n// NOT sourced from models.dev. They must survive models.generated.ts\n// regeneration by living in models.custom.ts.\n// ═══════════════════════════════════════════════════════════════════════════\n\ndescribe(\"model registry — custom providers\", () => {\n\tit(\"alibaba-coding-plan is a registered provider\", () => {\n\t\tconst providers = getProviders();\n\t\tassert.ok(\n\t\t\tproviders.includes(\"alibaba-coding-plan\"),\n\t\t\t`Expected \"alibaba-coding-plan\" in providers, got: ${providers.join(\", \")}`,\n\t\t);\n\t});\n\n\tit(\"alibaba-coding-plan has all expected models\", () => {\n\t\tconst models = getModels(\"alibaba-coding-plan\");\n\t\tconst ids = models.map((m) => m.id).sort();\n\t\tconst expected = [\n\t\t\t\"MiniMax-M2.5\",\n\t\t\t\"glm-4.7\",\n\t\t\t\"glm-5\",\n\t\t\t\"kimi-k2.5\",\n\t\t\t\"qwen3-coder-next\",\n\t\t\t\"qwen3-coder-plus\",\n\t\t\t\"qwen3-max-2026-01-23\",\n\t\t\t\"qwen3.5-plus\",\n\t\t];\n\t\tassert.deepEqual(ids, expected);\n\t});\n\n\tit(\"alibaba-coding-plan models use the correct base URL\", () => {\n\t\tconst models = getModels(\"alibaba-coding-plan\");\n\t\tfor (const model of models) {\n\t\t\tassert.equal(\n\t\t\t\tmodel.baseUrl,\n\t\t\t\t\"https://coding-intl.dashscope.aliyuncs.com/v1\",\n\t\t\t\t`Model ${model.id} has wrong baseUrl: ${model.baseUrl}`,\n\t\t\t);\n\t\t}\n\t});\n\n\tit(\"alibaba-coding-plan models use openai-completions API\", () => {\n\t\tconst models = getModels(\"alibaba-coding-plan\");\n\t\tfor (const model of models) {\n\t\t\tassert.equal(model.api, \"openai-completions\", `Model ${model.id} has wrong api: ${model.api}`);\n\t\t}\n\t});\n\n\tit(\"alibaba-coding-plan models have provider set correctly\", () => {\n\t\tconst models = getModels(\"alibaba-coding-plan\");\n\t\tfor (const model of models) {\n\t\t\tassert.equal(\n\t\t\t\tmodel.provider,\n\t\t\t\t\"alibaba-coding-plan\",\n\t\t\t\t`Model ${model.id} has wrong provider: ${model.provider}`,\n\t\t\t);\n\t\t}\n\t});\n\n\tit(\"getModel retrieves alibaba-coding-plan models by provider+id\", () => {\n\t\t// Use type assertion to test runtime behavior — alibaba-coding-plan may come\n\t\t// from custom models rather than the generated file, so the narrow\n\t\t// GeneratedProvider type doesn't include it until models.custom.ts is merged.\n\t\tconst model = getModel(\"alibaba-coding-plan\" as any, \"qwen3.5-plus\" as any);\n\t\tassert.ok(model, \"Expected getModel to return a model for alibaba-coding-plan/qwen3.5-plus\");\n\t\tassert.equal(model.id, \"qwen3.5-plus\");\n\t\tassert.equal(model.provider, \"alibaba-coding-plan\");\n\t});\n});\n\ndescribe(\"model registry — custom models do not collide with generated models\", () => {\n\tit(\"generated providers still exist alongside custom providers\", () => {\n\t\tconst providers = getProviders();\n\t\t// Spot-check a few generated providers\n\t\tassert.ok(providers.includes(\"openai\"), \"openai should be in providers\");\n\t\tassert.ok(providers.includes(\"anthropic\"), \"anthropic should be in providers\");\n\t});\n});\n"]}
1
+ {"version":3,"file":"models.test.js","sourceRoot":"","sources":["../src/models.test.ts"],"names":[],"mappings":"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","sourcesContent":["import { describe, it } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { getProviders, getModels, getModel, supportsXhigh, applyCapabilityPatches } from \"./models.js\";\nimport type { Api, Model } from \"./types.js\";\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Custom provider preservation (regression: #2339)\n//\n// Custom providers (like alibaba-coding-plan) are manually maintained and\n// NOT sourced from models.dev. They must survive models.generated.ts\n// regeneration by living in models.custom.ts.\n// ═══════════════════════════════════════════════════════════════════════════\n\ndescribe(\"model registry — custom providers\", () => {\n\tit(\"alibaba-coding-plan is a registered provider\", () => {\n\t\tconst providers = getProviders();\n\t\tassert.ok(\n\t\t\tproviders.includes(\"alibaba-coding-plan\"),\n\t\t\t`Expected \"alibaba-coding-plan\" in providers, got: ${providers.join(\", \")}`,\n\t\t);\n\t});\n\n\tit(\"alibaba-coding-plan has all expected models\", () => {\n\t\tconst models = getModels(\"alibaba-coding-plan\");\n\t\tconst ids = models.map((m) => m.id).sort();\n\t\tconst expected = [\n\t\t\t\"MiniMax-M2.5\",\n\t\t\t\"glm-4.7\",\n\t\t\t\"glm-5\",\n\t\t\t\"kimi-k2.5\",\n\t\t\t\"qwen3-coder-next\",\n\t\t\t\"qwen3-coder-plus\",\n\t\t\t\"qwen3-max-2026-01-23\",\n\t\t\t\"qwen3.5-plus\",\n\t\t];\n\t\tassert.deepEqual(ids, expected);\n\t});\n\n\tit(\"alibaba-coding-plan models use the correct base URL\", () => {\n\t\tconst models = getModels(\"alibaba-coding-plan\");\n\t\tfor (const model of models) {\n\t\t\tassert.equal(\n\t\t\t\tmodel.baseUrl,\n\t\t\t\t\"https://coding-intl.dashscope.aliyuncs.com/v1\",\n\t\t\t\t`Model ${model.id} has wrong baseUrl: ${model.baseUrl}`,\n\t\t\t);\n\t\t}\n\t});\n\n\tit(\"alibaba-coding-plan models use openai-completions API\", () => {\n\t\tconst models = getModels(\"alibaba-coding-plan\");\n\t\tfor (const model of models) {\n\t\t\tassert.equal(model.api, \"openai-completions\", `Model ${model.id} has wrong api: ${model.api}`);\n\t\t}\n\t});\n\n\tit(\"alibaba-coding-plan models have provider set correctly\", () => {\n\t\tconst models = getModels(\"alibaba-coding-plan\");\n\t\tfor (const model of models) {\n\t\t\tassert.equal(\n\t\t\t\tmodel.provider,\n\t\t\t\t\"alibaba-coding-plan\",\n\t\t\t\t`Model ${model.id} has wrong provider: ${model.provider}`,\n\t\t\t);\n\t\t}\n\t});\n\n\tit(\"getModel retrieves alibaba-coding-plan models by provider+id\", () => {\n\t\t// Use type assertion to test runtime behavior — alibaba-coding-plan may come\n\t\t// from custom models rather than the generated file, so the narrow\n\t\t// GeneratedProvider type doesn't include it until models.custom.ts is merged.\n\t\tconst model = getModel(\"alibaba-coding-plan\" as any, \"qwen3.5-plus\" as any);\n\t\tassert.ok(model, \"Expected getModel to return a model for alibaba-coding-plan/qwen3.5-plus\");\n\t\tassert.equal(model.id, \"qwen3.5-plus\");\n\t\tassert.equal(model.provider, \"alibaba-coding-plan\");\n\t});\n});\n\ndescribe(\"model registry — custom models do not collide with generated models\", () => {\n\tit(\"generated providers still exist alongside custom providers\", () => {\n\t\tconst providers = getProviders();\n\t\t// Spot-check a few generated providers\n\t\tassert.ok(providers.includes(\"openai\"), \"openai should be in providers\");\n\t\tassert.ok(providers.includes(\"anthropic\"), \"anthropic should be in providers\");\n\t});\n});\n\n// ═══════════════════════════════════════════════════════════════════════════\n// Capability patches (regression: #2546)\n//\n// CAPABILITY_PATCHES must apply capabilities to models in the static\n// registry AND to models constructed outside of it (custom, extension,\n// discovered). supportsXhigh() reads model.capabilities — not model IDs.\n// ═══════════════════════════════════════════════════════════════════════════\n\n/** Helper: build a minimal synthetic model for testing */\nfunction syntheticModel(overrides: Partial<Model<Api>>): Model<Api> {\n\treturn {\n\t\tid: \"test-model\",\n\t\tname: \"Test Model\",\n\t\tapi: \"openai-completions\" as Api,\n\t\tprovider: \"test-provider\",\n\t\tbaseUrl: \"https://example.com\",\n\t\treasoning: false,\n\t\tinput: [\"text\"],\n\t\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: 128000,\n\t\tmaxTokens: 16384,\n\t\t...overrides,\n\t} as Model<Api>;\n}\n\ndescribe(\"supportsXhigh — registry models\", () => {\n\tit(\"returns true for GPT-5.4 from the registry\", () => {\n\t\tconst model = getModel(\"openai\", \"gpt-5.4\" as any);\n\t\tif (!model) return; // skip if model not in generated catalog\n\t\tassert.equal(supportsXhigh(model), true);\n\t});\n\n\tit(\"returns false for a non-reasoning model\", () => {\n\t\tconst models = getModels(\"openai\");\n\t\tconst nonXhigh = models.find((m) => !m.id.includes(\"gpt-5.\"));\n\t\tif (!nonXhigh) return;\n\t\tassert.equal(supportsXhigh(nonXhigh), false);\n\t});\n});\n\ndescribe(\"supportsXhigh — synthetic models (regression: custom/extension models)\", () => {\n\tit(\"returns false for a model without capabilities\", () => {\n\t\tconst model = syntheticModel({ id: \"my-custom-model\" });\n\t\tassert.equal(supportsXhigh(model), false);\n\t});\n\n\tit(\"returns true when capabilities.supportsXhigh is explicitly set\", () => {\n\t\tconst model = syntheticModel({\n\t\t\tid: \"my-custom-model\",\n\t\t\tcapabilities: { supportsXhigh: true },\n\t\t});\n\t\tassert.equal(supportsXhigh(model), true);\n\t});\n});\n\ndescribe(\"applyCapabilityPatches\", () => {\n\tit(\"patches a GPT-5.4 model that has no capabilities\", () => {\n\t\tconst model = syntheticModel({ id: \"gpt-5.4-custom\" });\n\t\tassert.equal(model.capabilities, undefined);\n\n\t\tconst [patched] = applyCapabilityPatches([model]);\n\t\tassert.equal(patched.capabilities?.supportsXhigh, true);\n\t\tassert.equal(patched.capabilities?.supportsServiceTier, true);\n\t});\n\n\tit(\"patches a GPT-5.2 model\", () => {\n\t\tconst model = syntheticModel({ id: \"gpt-5.2\" });\n\t\tconst [patched] = applyCapabilityPatches([model]);\n\t\tassert.equal(patched.capabilities?.supportsXhigh, true);\n\t});\n\n\tit(\"patches an Anthropic Opus 4.6 model\", () => {\n\t\tconst model = syntheticModel({\n\t\t\tid: \"claude-opus-4-6-20260301\",\n\t\t\tapi: \"anthropic-messages\" as Api,\n\t\t});\n\t\tconst [patched] = applyCapabilityPatches([model]);\n\t\tassert.equal(patched.capabilities?.supportsXhigh, true);\n\t\t// Opus should not get supportsServiceTier\n\t\tassert.equal(patched.capabilities?.supportsServiceTier, undefined);\n\t});\n\n\tit(\"preserves explicit capabilities over patches\", () => {\n\t\tconst model = syntheticModel({\n\t\t\tid: \"gpt-5.4-custom\",\n\t\t\tcapabilities: { supportsXhigh: false, charsPerToken: 3 },\n\t\t});\n\t\tconst [patched] = applyCapabilityPatches([model]);\n\t\t// Explicit supportsXhigh: false wins over patch's true\n\t\tassert.equal(patched.capabilities?.supportsXhigh, false);\n\t\t// Patch fills in supportsServiceTier since it wasn't explicitly set\n\t\tassert.equal(patched.capabilities?.supportsServiceTier, true);\n\t\t// Explicit charsPerToken is preserved\n\t\tassert.equal(patched.capabilities?.charsPerToken, 3);\n\t});\n\n\tit(\"does not modify models that match no patches\", () => {\n\t\tconst model = syntheticModel({ id: \"gemini-2.5-pro\" });\n\t\tconst [patched] = applyCapabilityPatches([model]);\n\t\tassert.equal(patched.capabilities, undefined);\n\t\t// Should return the same reference when unpatched\n\t\tassert.equal(patched, model);\n\t});\n\n\tit(\"is idempotent — re-applying patches produces the same result\", () => {\n\t\tconst model = syntheticModel({ id: \"gpt-5.3\" });\n\t\tconst first = applyCapabilityPatches([model]);\n\t\tconst second = applyCapabilityPatches(first);\n\t\tassert.deepEqual(first[0].capabilities, second[0].capabilities);\n\t});\n});\n"]}
@@ -287,6 +287,31 @@ export interface VercelGatewayRouting {
287
287
  /** List of provider slugs to try in order (e.g., ["anthropic", "openai"]). */
288
288
  order?: string[];
289
289
  }
290
+ /**
291
+ * Provider-agnostic capability declarations for a model.
292
+ *
293
+ * These fields allow models to self-declare supported features so that call
294
+ * sites can read from metadata rather than pattern-matching on model IDs or
295
+ * provider names. Add fields here as new cross-provider capabilities emerge.
296
+ */
297
+ export interface ModelCapabilities {
298
+ /** Whether the model supports xhigh thinking level. */
299
+ supportsXhigh?: boolean;
300
+ /**
301
+ * Whether tool call IDs must be included and normalised in tool results for
302
+ * this model. Relevant for models deployed cross-provider (e.g. Claude or
303
+ * GPT variants via Google APIs) where the host API imposes stricter ID rules.
304
+ */
305
+ requiresToolCallId?: boolean;
306
+ /** Whether OpenAI-style service tiers (priority/flex) apply to this model. */
307
+ supportsServiceTier?: boolean;
308
+ /**
309
+ * Approximate characters per token for this model.
310
+ * Used as a fallback when an accurate tokenizer is unavailable.
311
+ * If omitted, the provider-level default is used.
312
+ */
313
+ charsPerToken?: number;
314
+ }
290
315
  export interface Model<TApi extends Api> {
291
316
  id: string;
292
317
  name: string;
@@ -306,5 +331,10 @@ export interface Model<TApi extends Api> {
306
331
  headers?: Record<string, string>;
307
332
  /** Compatibility overrides for OpenAI-compatible APIs. If not set, auto-detected from baseUrl. */
308
333
  compat?: TApi extends "openai-completions" ? OpenAICompletionsCompat : TApi extends "openai-responses" ? OpenAIResponsesCompat : never;
334
+ /**
335
+ * Provider-agnostic capability declarations for this model.
336
+ * Read these fields instead of pattern-matching on model IDs or provider names.
337
+ */
338
+ capabilities?: ModelCapabilities;
309
339
  }
310
340
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type KnownApi =\n\t| \"openai-completions\"\n\t| \"mistral-conversations\"\n\t| \"openai-responses\"\n\t| \"azure-openai-responses\"\n\t| \"openai-codex-responses\"\n\t| \"anthropic-messages\"\n\t| \"anthropic-vertex\"\n\t| \"bedrock-converse-stream\"\n\t| \"google-generative-ai\"\n\t| \"google-gemini-cli\"\n\t| \"google-vertex\";\n\nexport type Api = KnownApi | (string & {});\n\nexport type KnownProvider =\n\t| \"amazon-bedrock\"\n\t| \"anthropic\"\n\t| \"anthropic-vertex\"\n\t| \"google\"\n\t| \"google-gemini-cli\"\n\t| \"google-antigravity\"\n\t| \"google-vertex\"\n\t| \"openai\"\n\t| \"azure-openai-responses\"\n\t| \"openai-codex\"\n\t| \"github-copilot\"\n\t| \"xai\"\n\t| \"groq\"\n\t| \"cerebras\"\n\t| \"openrouter\"\n\t| \"vercel-ai-gateway\"\n\t| \"zai\"\n\t| \"mistral\"\n\t| \"minimax\"\n\t| \"minimax-cn\"\n\t| \"huggingface\"\n\t| \"opencode\"\n\t| \"opencode-go\"\n\t| \"kimi-coding\"\n\t| \"alibaba-coding-plan\"\n\t| \"ollama-cloud\";\nexport type Provider = KnownProvider | string;\n\nexport type ThinkingLevel = \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\n/** Token budgets for each thinking level (token-based providers only) */\nexport interface ThinkingBudgets {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\n// Base options all providers share\nexport type CacheRetention = \"none\" | \"short\" | \"long\";\n\nexport type Transport = \"sse\" | \"websocket\" | \"auto\";\n\nexport interface StreamOptions {\n\ttemperature?: number;\n\tmaxTokens?: number;\n\tsignal?: AbortSignal;\n\tapiKey?: string;\n\t/**\n\t * Preferred transport for providers that support multiple transports.\n\t * Providers that do not support this option ignore it.\n\t */\n\ttransport?: Transport;\n\t/**\n\t * Prompt cache retention preference. Providers map this to their supported values.\n\t * Default: \"short\".\n\t */\n\tcacheRetention?: CacheRetention;\n\t/**\n\t * Optional session identifier for providers that support session-based caching.\n\t * Providers can use this to enable prompt caching, request routing, or other\n\t * session-aware features. Ignored by providers that don't support it.\n\t */\n\tsessionId?: string;\n\t/**\n\t * Optional callback for inspecting or replacing provider payloads before sending.\n\t * Return undefined to keep the payload unchanged.\n\t */\n\tonPayload?: (payload: unknown, model: Model<Api>) => unknown | undefined | Promise<unknown | undefined>;\n\t/**\n\t * Optional custom HTTP headers to include in API requests.\n\t * Merged with provider defaults; can override default headers.\n\t * Not supported by all providers (e.g., AWS Bedrock uses SDK auth).\n\t */\n\theaders?: Record<string, string>;\n\t/**\n\t * Maximum delay in milliseconds to wait for a retry when the server requests a long wait.\n\t * If the server's requested delay exceeds this value, the request fails immediately\n\t * with an error containing the requested delay, allowing higher-level retry logic\n\t * to handle it with user visibility.\n\t * Default: 60000 (60 seconds). Set to 0 to disable the cap.\n\t */\n\tmaxRetryDelayMs?: number;\n\t/**\n\t * Optional metadata to include in API requests.\n\t * Providers extract the fields they understand and ignore the rest.\n\t * For example, Anthropic uses `user_id` for abuse tracking and rate limiting.\n\t */\n\tmetadata?: Record<string, unknown>;\n}\n\nexport type ProviderStreamOptions = StreamOptions & Record<string, unknown>;\n\n// Unified options with reasoning passed to streamSimple() and completeSimple()\nexport interface SimpleStreamOptions extends StreamOptions {\n\treasoning?: ThinkingLevel;\n\t/** Custom token budgets for thinking levels (token-based providers only) */\n\tthinkingBudgets?: ThinkingBudgets;\n}\n\n// Generic StreamFunction with typed options\nexport type StreamFunction<TApi extends Api = Api, TOptions extends StreamOptions = StreamOptions> = (\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: TOptions,\n) => AssistantMessageEventStream;\n\nexport interface TextSignatureV1 {\n\tv: 1;\n\tid: string;\n\tphase?: \"commentary\" | \"final_answer\";\n}\n\nexport interface TextContent {\n\ttype: \"text\";\n\ttext: string;\n\ttextSignature?: string; // e.g., for OpenAI responses, message metadata (legacy id string or TextSignatureV1 JSON)\n}\n\nexport interface ThinkingContent {\n\ttype: \"thinking\";\n\tthinking: string;\n\tthinkingSignature?: string; // e.g., for OpenAI responses, the reasoning item ID\n\t/** When true, the thinking content was redacted by safety filters. The opaque\n\t * encrypted payload is stored in `thinkingSignature` so it can be passed back\n\t * to the API for multi-turn continuity. */\n\tredacted?: boolean;\n}\n\nexport interface ImageContent {\n\ttype: \"image\";\n\tdata: string; // base64 encoded image data\n\tmimeType: string; // e.g., \"image/jpeg\", \"image/png\"\n}\n\nexport interface ToolCall {\n\ttype: \"toolCall\";\n\tid: string;\n\tname: string;\n\targuments: Record<string, any>;\n\tthoughtSignature?: string; // Google-specific: opaque signature for reusing thought context\n}\n\n/** Server-side tool use (e.g., Anthropic native web search). Executed by the API, not the client. */\nexport interface ServerToolUseContent {\n\ttype: \"serverToolUse\";\n\tid: string;\n\tname: string; // e.g., \"web_search\"\n\tinput: unknown;\n}\n\n/** Result of a server-side tool execution, paired with a ServerToolUseContent by toolUseId. */\nexport interface WebSearchResultContent {\n\ttype: \"webSearchResult\";\n\ttoolUseId: string;\n\t/** Search results or error from the server. Opaque — stored for API replay. */\n\tcontent: unknown;\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport type StopReason = \"stop\" | \"length\" | \"toolUse\" | \"error\" | \"aborted\";\n\nexport interface UserMessage {\n\trole: \"user\";\n\tcontent: string | (TextContent | ImageContent)[];\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface AssistantMessage {\n\trole: \"assistant\";\n\tcontent: (TextContent | ThinkingContent | ToolCall | ServerToolUseContent | WebSearchResultContent)[];\n\tapi: Api;\n\tprovider: Provider;\n\tmodel: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n\terrorMessage?: string;\n\t/** Server-requested retry delay in milliseconds (from Retry-After or rate limit headers). */\n\tretryAfterMs?: number;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface ToolResultMessage<TDetails = any> {\n\trole: \"toolResult\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tcontent: (TextContent | ImageContent)[]; // Supports text and images\n\tdetails?: TDetails;\n\tisError: boolean;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport type Message = UserMessage | AssistantMessage | ToolResultMessage;\n\nimport type { TSchema } from \"@sinclair/typebox\";\n\nexport interface Tool<TParameters extends TSchema = TSchema> {\n\tname: string;\n\tdescription: string;\n\tparameters: TParameters;\n}\n\nexport interface Context {\n\tsystemPrompt?: string;\n\tmessages: Message[];\n\ttools?: Tool[];\n}\n\nexport type AssistantMessageEvent =\n\t| { type: \"start\"; partial: AssistantMessage }\n\t| { type: \"text_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"text_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"thinking_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"thinking_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"toolcall_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"toolcall_end\"; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage; malformedArguments?: boolean }\n\t| { type: \"server_tool_use\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"web_search_result\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"done\"; reason: Extract<StopReason, \"stop\" | \"length\" | \"toolUse\">; message: AssistantMessage }\n\t| { type: \"error\"; reason: Extract<StopReason, \"aborted\" | \"error\">; error: AssistantMessage };\n\n/**\n * Compatibility settings for OpenAI-compatible completions APIs.\n * Use this to override URL-based auto-detection for custom providers.\n */\nexport interface OpenAICompletionsCompat {\n\t/** Whether the provider supports the `store` field. Default: auto-detected from URL. */\n\tsupportsStore?: boolean;\n\t/** Whether the provider supports the `developer` role (vs `system`). Default: auto-detected from URL. */\n\tsupportsDeveloperRole?: boolean;\n\t/** Whether the provider supports `reasoning_effort`. Default: auto-detected from URL. */\n\tsupportsReasoningEffort?: boolean;\n\t/** Optional mapping from pi-ai reasoning levels to provider/model-specific `reasoning_effort` values. */\n\treasoningEffortMap?: Partial<Record<ThinkingLevel, string>>;\n\t/** Whether the provider supports `stream_options: { include_usage: true }` for token usage in streaming responses. Default: true. */\n\tsupportsUsageInStreaming?: boolean;\n\t/** Which field to use for max tokens. Default: auto-detected from URL. */\n\tmaxTokensField?: \"max_completion_tokens\" | \"max_tokens\";\n\t/** Whether tool results require the `name` field. Default: auto-detected from URL. */\n\trequiresToolResultName?: boolean;\n\t/** Whether a user message after tool results requires an assistant message in between. Default: auto-detected from URL. */\n\trequiresAssistantAfterToolResult?: boolean;\n\t/** Whether thinking blocks must be converted to text blocks with <thinking> delimiters. Default: auto-detected from URL. */\n\trequiresThinkingAsText?: boolean;\n\t/** Format for reasoning/thinking parameter. \"openai\" uses reasoning_effort, \"zai\" uses thinking: { type: \"enabled\" }, \"qwen\" uses enable_thinking: boolean. Default: \"openai\". */\n\tthinkingFormat?: \"openai\" | \"zai\" | \"qwen\";\n\t/** OpenRouter-specific routing preferences. Only used when baseUrl points to OpenRouter. */\n\topenRouterRouting?: OpenRouterRouting;\n\t/** Vercel AI Gateway routing preferences. Only used when baseUrl points to Vercel AI Gateway. */\n\tvercelGatewayRouting?: VercelGatewayRouting;\n\t/** Whether the provider supports the `strict` field in tool definitions. Default: true. */\n\tsupportsStrictMode?: boolean;\n}\n\n/** Compatibility settings for OpenAI Responses APIs. */\nexport interface OpenAIResponsesCompat {\n\t// Reserved for future use\n}\n\n/**\n * OpenRouter provider routing preferences.\n * Controls which upstream providers OpenRouter routes requests to.\n * @see https://openrouter.ai/docs/provider-routing\n */\nexport interface OpenRouterRouting {\n\t/** List of provider slugs to exclusively use for this request (e.g., [\"amazon-bedrock\", \"anthropic\"]). */\n\tonly?: string[];\n\t/** List of provider slugs to try in order (e.g., [\"anthropic\", \"openai\"]). */\n\torder?: string[];\n}\n\n/**\n * Vercel AI Gateway routing preferences.\n * Controls which upstream providers the gateway routes requests to.\n * @see https://vercel.com/docs/ai-gateway/models-and-providers/provider-options\n */\nexport interface VercelGatewayRouting {\n\t/** List of provider slugs to exclusively use for this request (e.g., [\"bedrock\", \"anthropic\"]). */\n\tonly?: string[];\n\t/** List of provider slugs to try in order (e.g., [\"anthropic\", \"openai\"]). */\n\torder?: string[];\n}\n\n// Model interface for the unified model system\nexport interface Model<TApi extends Api> {\n\tid: string;\n\tname: string;\n\tapi: TApi;\n\tprovider: Provider;\n\tbaseUrl: string;\n\treasoning: boolean;\n\tinput: (\"text\" | \"image\")[];\n\tcost: {\n\t\tinput: number; // $/million tokens\n\t\toutput: number; // $/million tokens\n\t\tcacheRead: number; // $/million tokens\n\t\tcacheWrite: number; // $/million tokens\n\t};\n\tcontextWindow: number;\n\tmaxTokens: number;\n\theaders?: Record<string, string>;\n\t/** Compatibility overrides for OpenAI-compatible APIs. If not set, auto-detected from baseUrl. */\n\tcompat?: TApi extends \"openai-completions\"\n\t\t? OpenAICompletionsCompat\n\t\t: TApi extends \"openai-responses\"\n\t\t\t? OpenAIResponsesCompat\n\t\t\t: never;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["import type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type { AssistantMessageEventStream } from \"./utils/event-stream.js\";\n\nexport type KnownApi =\n\t| \"openai-completions\"\n\t| \"mistral-conversations\"\n\t| \"openai-responses\"\n\t| \"azure-openai-responses\"\n\t| \"openai-codex-responses\"\n\t| \"anthropic-messages\"\n\t| \"anthropic-vertex\"\n\t| \"bedrock-converse-stream\"\n\t| \"google-generative-ai\"\n\t| \"google-gemini-cli\"\n\t| \"google-vertex\";\n\nexport type Api = KnownApi | (string & {});\n\nexport type KnownProvider =\n\t| \"amazon-bedrock\"\n\t| \"anthropic\"\n\t| \"anthropic-vertex\"\n\t| \"google\"\n\t| \"google-gemini-cli\"\n\t| \"google-antigravity\"\n\t| \"google-vertex\"\n\t| \"openai\"\n\t| \"azure-openai-responses\"\n\t| \"openai-codex\"\n\t| \"github-copilot\"\n\t| \"xai\"\n\t| \"groq\"\n\t| \"cerebras\"\n\t| \"openrouter\"\n\t| \"vercel-ai-gateway\"\n\t| \"zai\"\n\t| \"mistral\"\n\t| \"minimax\"\n\t| \"minimax-cn\"\n\t| \"huggingface\"\n\t| \"opencode\"\n\t| \"opencode-go\"\n\t| \"kimi-coding\"\n\t| \"alibaba-coding-plan\"\n\t| \"ollama-cloud\";\nexport type Provider = KnownProvider | string;\n\nexport type ThinkingLevel = \"minimal\" | \"low\" | \"medium\" | \"high\" | \"xhigh\";\n\n/** Token budgets for each thinking level (token-based providers only) */\nexport interface ThinkingBudgets {\n\tminimal?: number;\n\tlow?: number;\n\tmedium?: number;\n\thigh?: number;\n}\n\n// Base options all providers share\nexport type CacheRetention = \"none\" | \"short\" | \"long\";\n\nexport type Transport = \"sse\" | \"websocket\" | \"auto\";\n\nexport interface StreamOptions {\n\ttemperature?: number;\n\tmaxTokens?: number;\n\tsignal?: AbortSignal;\n\tapiKey?: string;\n\t/**\n\t * Preferred transport for providers that support multiple transports.\n\t * Providers that do not support this option ignore it.\n\t */\n\ttransport?: Transport;\n\t/**\n\t * Prompt cache retention preference. Providers map this to their supported values.\n\t * Default: \"short\".\n\t */\n\tcacheRetention?: CacheRetention;\n\t/**\n\t * Optional session identifier for providers that support session-based caching.\n\t * Providers can use this to enable prompt caching, request routing, or other\n\t * session-aware features. Ignored by providers that don't support it.\n\t */\n\tsessionId?: string;\n\t/**\n\t * Optional callback for inspecting or replacing provider payloads before sending.\n\t * Return undefined to keep the payload unchanged.\n\t */\n\tonPayload?: (payload: unknown, model: Model<Api>) => unknown | undefined | Promise<unknown | undefined>;\n\t/**\n\t * Optional custom HTTP headers to include in API requests.\n\t * Merged with provider defaults; can override default headers.\n\t * Not supported by all providers (e.g., AWS Bedrock uses SDK auth).\n\t */\n\theaders?: Record<string, string>;\n\t/**\n\t * Maximum delay in milliseconds to wait for a retry when the server requests a long wait.\n\t * If the server's requested delay exceeds this value, the request fails immediately\n\t * with an error containing the requested delay, allowing higher-level retry logic\n\t * to handle it with user visibility.\n\t * Default: 60000 (60 seconds). Set to 0 to disable the cap.\n\t */\n\tmaxRetryDelayMs?: number;\n\t/**\n\t * Optional metadata to include in API requests.\n\t * Providers extract the fields they understand and ignore the rest.\n\t * For example, Anthropic uses `user_id` for abuse tracking and rate limiting.\n\t */\n\tmetadata?: Record<string, unknown>;\n}\n\nexport type ProviderStreamOptions = StreamOptions & Record<string, unknown>;\n\n// Unified options with reasoning passed to streamSimple() and completeSimple()\nexport interface SimpleStreamOptions extends StreamOptions {\n\treasoning?: ThinkingLevel;\n\t/** Custom token budgets for thinking levels (token-based providers only) */\n\tthinkingBudgets?: ThinkingBudgets;\n}\n\n// Generic StreamFunction with typed options\nexport type StreamFunction<TApi extends Api = Api, TOptions extends StreamOptions = StreamOptions> = (\n\tmodel: Model<TApi>,\n\tcontext: Context,\n\toptions?: TOptions,\n) => AssistantMessageEventStream;\n\nexport interface TextSignatureV1 {\n\tv: 1;\n\tid: string;\n\tphase?: \"commentary\" | \"final_answer\";\n}\n\nexport interface TextContent {\n\ttype: \"text\";\n\ttext: string;\n\ttextSignature?: string; // e.g., for OpenAI responses, message metadata (legacy id string or TextSignatureV1 JSON)\n}\n\nexport interface ThinkingContent {\n\ttype: \"thinking\";\n\tthinking: string;\n\tthinkingSignature?: string; // e.g., for OpenAI responses, the reasoning item ID\n\t/** When true, the thinking content was redacted by safety filters. The opaque\n\t * encrypted payload is stored in `thinkingSignature` so it can be passed back\n\t * to the API for multi-turn continuity. */\n\tredacted?: boolean;\n}\n\nexport interface ImageContent {\n\ttype: \"image\";\n\tdata: string; // base64 encoded image data\n\tmimeType: string; // e.g., \"image/jpeg\", \"image/png\"\n}\n\nexport interface ToolCall {\n\ttype: \"toolCall\";\n\tid: string;\n\tname: string;\n\targuments: Record<string, any>;\n\tthoughtSignature?: string; // Google-specific: opaque signature for reusing thought context\n}\n\n/** Server-side tool use (e.g., Anthropic native web search). Executed by the API, not the client. */\nexport interface ServerToolUseContent {\n\ttype: \"serverToolUse\";\n\tid: string;\n\tname: string; // e.g., \"web_search\"\n\tinput: unknown;\n}\n\n/** Result of a server-side tool execution, paired with a ServerToolUseContent by toolUseId. */\nexport interface WebSearchResultContent {\n\ttype: \"webSearchResult\";\n\ttoolUseId: string;\n\t/** Search results or error from the server. Opaque — stored for API replay. */\n\tcontent: unknown;\n}\n\nexport interface Usage {\n\tinput: number;\n\toutput: number;\n\tcacheRead: number;\n\tcacheWrite: number;\n\ttotalTokens: number;\n\tcost: {\n\t\tinput: number;\n\t\toutput: number;\n\t\tcacheRead: number;\n\t\tcacheWrite: number;\n\t\ttotal: number;\n\t};\n}\n\nexport type StopReason = \"stop\" | \"length\" | \"toolUse\" | \"error\" | \"aborted\";\n\nexport interface UserMessage {\n\trole: \"user\";\n\tcontent: string | (TextContent | ImageContent)[];\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface AssistantMessage {\n\trole: \"assistant\";\n\tcontent: (TextContent | ThinkingContent | ToolCall | ServerToolUseContent | WebSearchResultContent)[];\n\tapi: Api;\n\tprovider: Provider;\n\tmodel: string;\n\tusage: Usage;\n\tstopReason: StopReason;\n\terrorMessage?: string;\n\t/** Server-requested retry delay in milliseconds (from Retry-After or rate limit headers). */\n\tretryAfterMs?: number;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport interface ToolResultMessage<TDetails = any> {\n\trole: \"toolResult\";\n\ttoolCallId: string;\n\ttoolName: string;\n\tcontent: (TextContent | ImageContent)[]; // Supports text and images\n\tdetails?: TDetails;\n\tisError: boolean;\n\ttimestamp: number; // Unix timestamp in milliseconds\n}\n\nexport type Message = UserMessage | AssistantMessage | ToolResultMessage;\n\nimport type { TSchema } from \"@sinclair/typebox\";\n\nexport interface Tool<TParameters extends TSchema = TSchema> {\n\tname: string;\n\tdescription: string;\n\tparameters: TParameters;\n}\n\nexport interface Context {\n\tsystemPrompt?: string;\n\tmessages: Message[];\n\ttools?: Tool[];\n}\n\nexport type AssistantMessageEvent =\n\t| { type: \"start\"; partial: AssistantMessage }\n\t| { type: \"text_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"text_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"text_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"thinking_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"thinking_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"thinking_end\"; contentIndex: number; content: string; partial: AssistantMessage }\n\t| { type: \"toolcall_start\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"toolcall_delta\"; contentIndex: number; delta: string; partial: AssistantMessage }\n\t| { type: \"toolcall_end\"; contentIndex: number; toolCall: ToolCall; partial: AssistantMessage; malformedArguments?: boolean }\n\t| { type: \"server_tool_use\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"web_search_result\"; contentIndex: number; partial: AssistantMessage }\n\t| { type: \"done\"; reason: Extract<StopReason, \"stop\" | \"length\" | \"toolUse\">; message: AssistantMessage }\n\t| { type: \"error\"; reason: Extract<StopReason, \"aborted\" | \"error\">; error: AssistantMessage };\n\n/**\n * Compatibility settings for OpenAI-compatible completions APIs.\n * Use this to override URL-based auto-detection for custom providers.\n */\nexport interface OpenAICompletionsCompat {\n\t/** Whether the provider supports the `store` field. Default: auto-detected from URL. */\n\tsupportsStore?: boolean;\n\t/** Whether the provider supports the `developer` role (vs `system`). Default: auto-detected from URL. */\n\tsupportsDeveloperRole?: boolean;\n\t/** Whether the provider supports `reasoning_effort`. Default: auto-detected from URL. */\n\tsupportsReasoningEffort?: boolean;\n\t/** Optional mapping from pi-ai reasoning levels to provider/model-specific `reasoning_effort` values. */\n\treasoningEffortMap?: Partial<Record<ThinkingLevel, string>>;\n\t/** Whether the provider supports `stream_options: { include_usage: true }` for token usage in streaming responses. Default: true. */\n\tsupportsUsageInStreaming?: boolean;\n\t/** Which field to use for max tokens. Default: auto-detected from URL. */\n\tmaxTokensField?: \"max_completion_tokens\" | \"max_tokens\";\n\t/** Whether tool results require the `name` field. Default: auto-detected from URL. */\n\trequiresToolResultName?: boolean;\n\t/** Whether a user message after tool results requires an assistant message in between. Default: auto-detected from URL. */\n\trequiresAssistantAfterToolResult?: boolean;\n\t/** Whether thinking blocks must be converted to text blocks with <thinking> delimiters. Default: auto-detected from URL. */\n\trequiresThinkingAsText?: boolean;\n\t/** Format for reasoning/thinking parameter. \"openai\" uses reasoning_effort, \"zai\" uses thinking: { type: \"enabled\" }, \"qwen\" uses enable_thinking: boolean. Default: \"openai\". */\n\tthinkingFormat?: \"openai\" | \"zai\" | \"qwen\";\n\t/** OpenRouter-specific routing preferences. Only used when baseUrl points to OpenRouter. */\n\topenRouterRouting?: OpenRouterRouting;\n\t/** Vercel AI Gateway routing preferences. Only used when baseUrl points to Vercel AI Gateway. */\n\tvercelGatewayRouting?: VercelGatewayRouting;\n\t/** Whether the provider supports the `strict` field in tool definitions. Default: true. */\n\tsupportsStrictMode?: boolean;\n}\n\n/** Compatibility settings for OpenAI Responses APIs. */\nexport interface OpenAIResponsesCompat {\n\t// Reserved for future use\n}\n\n/**\n * OpenRouter provider routing preferences.\n * Controls which upstream providers OpenRouter routes requests to.\n * @see https://openrouter.ai/docs/provider-routing\n */\nexport interface OpenRouterRouting {\n\t/** List of provider slugs to exclusively use for this request (e.g., [\"amazon-bedrock\", \"anthropic\"]). */\n\tonly?: string[];\n\t/** List of provider slugs to try in order (e.g., [\"anthropic\", \"openai\"]). */\n\torder?: string[];\n}\n\n/**\n * Vercel AI Gateway routing preferences.\n * Controls which upstream providers the gateway routes requests to.\n * @see https://vercel.com/docs/ai-gateway/models-and-providers/provider-options\n */\nexport interface VercelGatewayRouting {\n\t/** List of provider slugs to exclusively use for this request (e.g., [\"bedrock\", \"anthropic\"]). */\n\tonly?: string[];\n\t/** List of provider slugs to try in order (e.g., [\"anthropic\", \"openai\"]). */\n\torder?: string[];\n}\n\n/**\n * Provider-agnostic capability declarations for a model.\n *\n * These fields allow models to self-declare supported features so that call\n * sites can read from metadata rather than pattern-matching on model IDs or\n * provider names. Add fields here as new cross-provider capabilities emerge.\n */\nexport interface ModelCapabilities {\n\t/** Whether the model supports xhigh thinking level. */\n\tsupportsXhigh?: boolean;\n\t/**\n\t * Whether tool call IDs must be included and normalised in tool results for\n\t * this model. Relevant for models deployed cross-provider (e.g. Claude or\n\t * GPT variants via Google APIs) where the host API imposes stricter ID rules.\n\t */\n\trequiresToolCallId?: boolean;\n\t/** Whether OpenAI-style service tiers (priority/flex) apply to this model. */\n\tsupportsServiceTier?: boolean;\n\t/**\n\t * Approximate characters per token for this model.\n\t * Used as a fallback when an accurate tokenizer is unavailable.\n\t * If omitted, the provider-level default is used.\n\t */\n\tcharsPerToken?: number;\n}\n\n// Model interface for the unified model system\nexport interface Model<TApi extends Api> {\n\tid: string;\n\tname: string;\n\tapi: TApi;\n\tprovider: Provider;\n\tbaseUrl: string;\n\treasoning: boolean;\n\tinput: (\"text\" | \"image\")[];\n\tcost: {\n\t\tinput: number; // $/million tokens\n\t\toutput: number; // $/million tokens\n\t\tcacheRead: number; // $/million tokens\n\t\tcacheWrite: number; // $/million tokens\n\t};\n\tcontextWindow: number;\n\tmaxTokens: number;\n\theaders?: Record<string, string>;\n\t/** Compatibility overrides for OpenAI-compatible APIs. If not set, auto-detected from baseUrl. */\n\tcompat?: TApi extends \"openai-completions\"\n\t\t? OpenAICompletionsCompat\n\t\t: TApi extends \"openai-responses\"\n\t\t\t? OpenAIResponsesCompat\n\t\t\t: never;\n\t/**\n\t * Provider-agnostic capability declarations for this model.\n\t * Read these fields instead of pattern-matching on model IDs or provider names.\n\t */\n\tcapabilities?: ModelCapabilities;\n}\n"]}