gsd-pi 2.76.0-dev.fe143342a → 2.77.0-dev.1d17f366c

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 (597) hide show
  1. package/README.md +17 -35
  2. package/dist/claude-cli-check.js +32 -3
  3. package/dist/cli-web-branch.d.ts +1 -0
  4. package/dist/cli-web-branch.js +3 -0
  5. package/dist/cli.js +38 -2
  6. package/dist/extension-discovery.d.ts +6 -0
  7. package/dist/extension-discovery.js +37 -0
  8. package/dist/extension-registry.d.ts +3 -0
  9. package/dist/extension-sort.d.ts +18 -0
  10. package/dist/extension-sort.js +114 -0
  11. package/dist/extension-validator.d.ts +47 -0
  12. package/dist/extension-validator.js +127 -0
  13. package/dist/loader.js +35 -7
  14. package/dist/onboarding.js +45 -0
  15. package/dist/provider-migrations.d.ts +18 -0
  16. package/dist/provider-migrations.js +14 -0
  17. package/dist/resources/extensions/claude-code-cli/readiness.js +4 -3
  18. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +78 -59
  19. package/dist/resources/extensions/cmux/index.js +20 -0
  20. package/dist/resources/extensions/github-sync/templates.js +103 -0
  21. package/dist/resources/extensions/google-search/extension-manifest.json +5 -4
  22. package/dist/resources/extensions/google-search/index.js +3 -375
  23. package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
  24. package/dist/resources/extensions/gsd/auto/loop.js +90 -2
  25. package/dist/resources/extensions/gsd/auto/phases.js +95 -21
  26. package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
  27. package/dist/resources/extensions/gsd/auto/run-unit.js +48 -4
  28. package/dist/resources/extensions/gsd/auto/session.js +18 -1
  29. package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
  30. package/dist/resources/extensions/gsd/auto-dispatch.js +115 -17
  31. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  32. package/dist/resources/extensions/gsd/auto-model-selection.js +1 -1
  33. package/dist/resources/extensions/gsd/auto-post-unit.js +90 -2
  34. package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
  35. package/dist/resources/extensions/gsd/auto-recovery.js +46 -1
  36. package/dist/resources/extensions/gsd/auto-start.js +45 -39
  37. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
  38. package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
  39. package/dist/resources/extensions/gsd/auto-worktree.js +109 -61
  40. package/dist/resources/extensions/gsd/auto.js +97 -31
  41. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +27 -1
  42. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +4 -2
  43. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +11 -0
  44. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +17 -6
  45. package/dist/resources/extensions/gsd/bootstrap/system-context.js +11 -6
  46. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
  47. package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
  48. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
  49. package/dist/resources/extensions/gsd/commands-cmux.js +9 -6
  50. package/dist/resources/extensions/gsd/commands-extensions.js +634 -43
  51. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
  52. package/dist/resources/extensions/gsd/dispatch-guard.js +29 -3
  53. package/dist/resources/extensions/gsd/file-lock.js +49 -9
  54. package/dist/resources/extensions/gsd/git-service.js +1 -0
  55. package/dist/resources/extensions/gsd/gitignore.js +2 -0
  56. package/dist/resources/extensions/gsd/gsd-db.js +90 -30
  57. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
  58. package/dist/resources/extensions/gsd/guided-flow.js +212 -9
  59. package/dist/resources/extensions/gsd/health-widget.js +4 -1
  60. package/dist/resources/extensions/gsd/journal.js +17 -2
  61. package/dist/resources/extensions/gsd/key-manager.js +22 -0
  62. package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
  63. package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
  64. package/dist/resources/extensions/gsd/model-router.js +36 -3
  65. package/dist/resources/extensions/gsd/notifications.js +30 -16
  66. package/dist/resources/extensions/gsd/pre-execution-checks.js +31 -6
  67. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +29 -2
  68. package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
  69. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  70. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  71. package/dist/resources/extensions/gsd/prompts/system.md +1 -0
  72. package/dist/resources/extensions/gsd/reports.js +5 -4
  73. package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
  74. package/dist/resources/extensions/gsd/safety/file-change-validator.js +12 -4
  75. package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
  76. package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
  77. package/dist/resources/extensions/gsd/state.js +25 -25
  78. package/dist/resources/extensions/gsd/token-counter.js +22 -5
  79. package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
  80. package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
  81. package/dist/resources/extensions/gsd/tools/complete-task.js +31 -0
  82. package/dist/resources/extensions/gsd/uok/audit.js +18 -2
  83. package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
  84. package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
  85. package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
  86. package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
  87. package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
  88. package/dist/resources/extensions/gsd/uok/plan-v2.js +30 -7
  89. package/dist/resources/extensions/gsd/uok/writer.js +82 -0
  90. package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
  91. package/dist/resources/extensions/gsd/worktree-manager.js +1 -0
  92. package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
  93. package/dist/resources/extensions/mcp-client/auth.js +10 -1
  94. package/dist/resources/extensions/mcp-client/index.js +118 -9
  95. package/dist/resources/extensions/shared/cmux-events.js +12 -0
  96. package/dist/resources/extensions/shared/rtk-session-stats.js +1 -2
  97. package/dist/resources/skills/create-skill/SKILL.md +2 -2
  98. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  99. package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  100. package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  101. package/dist/resources/skills/verify-before-complete/SKILL.md +2 -1
  102. package/dist/resources/skills/write-docs/SKILL.md +2 -1
  103. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  104. package/dist/web/standalone/.next/BUILD_ID +1 -1
  105. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  106. package/dist/web/standalone/.next/build-manifest.json +3 -3
  107. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  108. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  133. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  135. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  137. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/notifications/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  173. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/index.html +1 -1
  190. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  191. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  192. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  193. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  194. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  195. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  196. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  197. package/dist/web/standalone/.next/server/chunks/1926.js +1 -0
  198. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  199. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  200. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  201. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  202. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  203. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  204. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  205. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
  206. package/dist/web/standalone/.next/static/chunks/{webpack-5fc74f13a25fa1bb.js → webpack-2e68521d7c82f7c2.js} +1 -1
  207. package/dist/welcome-screen.js +6 -1
  208. package/dist/wizard.js +2 -0
  209. package/package.json +16 -14
  210. package/packages/daemon/package.json +2 -2
  211. package/packages/mcp-server/README.md +3 -3
  212. package/packages/mcp-server/dist/env-writer.d.ts +1 -0
  213. package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
  214. package/packages/mcp-server/dist/env-writer.js +74 -6
  215. package/packages/mcp-server/dist/env-writer.js.map +1 -1
  216. package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
  217. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
  218. package/packages/mcp-server/dist/remote-questions.js +732 -0
  219. package/packages/mcp-server/dist/remote-questions.js.map +1 -0
  220. package/packages/mcp-server/dist/server.d.ts +7 -0
  221. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  222. package/packages/mcp-server/dist/server.js +95 -10
  223. package/packages/mcp-server/dist/server.js.map +1 -1
  224. package/packages/mcp-server/dist/session-manager.d.ts +14 -0
  225. package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
  226. package/packages/mcp-server/dist/session-manager.js +49 -1
  227. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  228. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  229. package/packages/mcp-server/dist/workflow-tools.js +15 -6
  230. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  231. package/packages/mcp-server/package.json +9 -3
  232. package/packages/mcp-server/src/env-writer.test.ts +79 -1
  233. package/packages/mcp-server/src/env-writer.ts +76 -6
  234. package/packages/mcp-server/src/mcp-server.test.ts +67 -0
  235. package/packages/mcp-server/src/readers/readers.test.ts +5 -1
  236. package/packages/mcp-server/src/remote-questions.test.ts +294 -0
  237. package/packages/mcp-server/src/remote-questions.ts +916 -0
  238. package/packages/mcp-server/src/server.ts +118 -16
  239. package/packages/mcp-server/src/session-manager.ts +43 -1
  240. package/packages/mcp-server/src/workflow-tools.test.ts +44 -0
  241. package/packages/mcp-server/src/workflow-tools.ts +19 -6
  242. package/packages/mcp-server/tsconfig.test.json +19 -0
  243. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  244. package/packages/native/package.json +6 -1
  245. package/packages/native/src/__tests__/clipboard.test.mjs +69 -23
  246. package/packages/native/tsconfig.tsbuildinfo +1 -1
  247. package/packages/pi-agent-core/package.json +6 -1
  248. package/packages/pi-agent-core/src/agent-loop.test.ts +220 -15
  249. package/packages/pi-ai/dist/models/custom.d.ts +38 -0
  250. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/models/custom.js +41 -0
  252. package/packages/pi-ai/dist/models/custom.js.map +1 -1
  253. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
  254. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  255. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  256. package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
  257. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  258. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  259. package/packages/pi-ai/dist/providers/anthropic.js +8 -3
  260. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  261. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
  262. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
  263. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
  264. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
  265. package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
  266. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  267. package/packages/pi-ai/dist/providers/simple-options.js +16 -1
  268. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  269. package/packages/pi-ai/package.json +6 -1
  270. package/packages/pi-ai/src/models/custom.ts +42 -0
  271. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
  272. package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
  273. package/packages/pi-ai/src/providers/anthropic.ts +9 -3
  274. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
  275. package/packages/pi-ai/src/providers/simple-options.ts +17 -1
  276. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  277. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
  278. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
  280. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/agent-session.js +7 -0
  282. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +25 -0
  284. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +105 -6
  286. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js +230 -28
  288. package/packages/pi-coding-agent/dist/core/compaction/compaction.test.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts +30 -2
  290. package/packages/pi-coding-agent/dist/core/compaction/utils.d.ts.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/compaction/utils.js +113 -12
  292. package/packages/pi-coding-agent/dist/core/compaction/utils.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
  294. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +29 -18
  296. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
  298. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
  299. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
  300. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
  301. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js +56 -1
  302. package/packages/pi-coding-agent/dist/core/compaction-utils.test.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +8 -15
  304. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts +25 -0
  306. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.d.ts.map +1 -0
  307. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js +109 -0
  308. package/packages/pi-coding-agent/dist/core/extensions/extension-discovery.js.map +1 -0
  309. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts +67 -0
  310. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.d.ts.map +1 -0
  311. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js +167 -0
  312. package/packages/pi-coding-agent/dist/core/extensions/extension-registry.js.map +1 -0
  313. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +3 -2
  314. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  315. package/packages/pi-coding-agent/dist/core/extensions/loader.js +24 -8
  316. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  317. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
  318. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  319. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +14 -0
  321. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  323. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +11 -0
  324. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +2 -2
  326. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
  328. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
  329. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
  330. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
  331. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/model-registry.js +14 -0
  333. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/core/resource-loader.js +1 -1
  335. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  336. package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -0
  337. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
  339. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  340. package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
  341. package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/session-manager.js +1 -1
  343. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/core/session-manager.test.js +21 -1
  345. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  346. package/packages/pi-coding-agent/dist/core/system-prompt.js +3 -3
  347. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js +2 -1
  349. package/packages/pi-coding-agent/dist/core/tools/path-utils.test.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +15 -6
  351. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -1
  352. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  353. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
  354. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  355. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
  356. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  357. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
  358. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
  359. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +14 -0
  360. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  361. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
  363. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  364. package/packages/pi-coding-agent/package.json +6 -1
  365. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
  366. package/packages/pi-coding-agent/src/core/agent-session.ts +11 -0
  367. package/packages/pi-coding-agent/src/core/compaction/compaction.test.ts +368 -28
  368. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +122 -6
  369. package/packages/pi-coding-agent/src/core/compaction/utils.ts +111 -13
  370. package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
  371. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +32 -18
  372. package/packages/pi-coding-agent/src/core/compaction-utils.test.ts +68 -1
  373. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +9 -18
  374. package/packages/pi-coding-agent/src/core/extensions/extension-discovery.ts +119 -0
  375. package/packages/pi-coding-agent/src/core/extensions/extension-registry.ts +222 -0
  376. package/packages/pi-coding-agent/src/core/extensions/loader.ts +24 -11
  377. package/packages/pi-coding-agent/src/core/extensions/runner.ts +2 -0
  378. package/packages/pi-coding-agent/src/core/extensions/types.ts +15 -0
  379. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +13 -0
  380. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +2 -2
  381. package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
  382. package/packages/pi-coding-agent/src/core/model-registry.ts +16 -0
  383. package/packages/pi-coding-agent/src/core/resource-loader.ts +1 -1
  384. package/packages/pi-coding-agent/src/core/sdk.test.ts +25 -1
  385. package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
  386. package/packages/pi-coding-agent/src/core/session-manager.test.ts +30 -1
  387. package/packages/pi-coding-agent/src/core/session-manager.ts +1 -1
  388. package/packages/pi-coding-agent/src/core/system-prompt.ts +3 -3
  389. package/packages/pi-coding-agent/src/core/tools/path-utils.test.ts +2 -1
  390. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
  391. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +14 -5
  392. package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
  393. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +14 -0
  394. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
  395. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  396. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +12 -5
  397. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  398. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +21 -0
  399. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  400. package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
  401. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  402. package/packages/pi-tui/dist/stdin-buffer.js +20 -0
  403. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  404. package/packages/pi-tui/package.json +6 -1
  405. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +20 -5
  406. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +27 -0
  407. package/packages/pi-tui/src/stdin-buffer.ts +26 -0
  408. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  409. package/packages/rpc-client/package.json +6 -1
  410. package/pkg/package.json +1 -1
  411. package/scripts/install.js +512 -0
  412. package/scripts/lib/workspace-manifest.cjs +86 -0
  413. package/scripts/link-workspace-packages.cjs +5 -17
  414. package/scripts/postinstall.js +9 -178
  415. package/src/resources/extensions/claude-code-cli/readiness.ts +4 -3
  416. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +91 -63
  417. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +114 -12
  418. package/src/resources/extensions/cmux/index.ts +35 -10
  419. package/src/resources/extensions/github-sync/templates.ts +151 -0
  420. package/src/resources/extensions/github-sync/tests/templates.test.ts +59 -0
  421. package/src/resources/extensions/google-search/extension-manifest.json +5 -4
  422. package/src/resources/extensions/google-search/index.ts +9 -470
  423. package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
  424. package/src/resources/extensions/gsd/auto/loop-deps.ts +14 -1
  425. package/src/resources/extensions/gsd/auto/loop.ts +104 -2
  426. package/src/resources/extensions/gsd/auto/phases.ts +123 -21
  427. package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
  428. package/src/resources/extensions/gsd/auto/run-unit.ts +56 -4
  429. package/src/resources/extensions/gsd/auto/session.ts +28 -1
  430. package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
  431. package/src/resources/extensions/gsd/auto/types.ts +1 -1
  432. package/src/resources/extensions/gsd/auto-dispatch.ts +117 -16
  433. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  434. package/src/resources/extensions/gsd/auto-model-selection.ts +1 -1
  435. package/src/resources/extensions/gsd/auto-post-unit.ts +92 -3
  436. package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
  437. package/src/resources/extensions/gsd/auto-recovery.ts +40 -1
  438. package/src/resources/extensions/gsd/auto-start.ts +48 -52
  439. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
  440. package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
  441. package/src/resources/extensions/gsd/auto-worktree.ts +122 -68
  442. package/src/resources/extensions/gsd/auto.ts +105 -35
  443. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +34 -1
  444. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -2
  445. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +11 -0
  446. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +18 -6
  447. package/src/resources/extensions/gsd/bootstrap/system-context.ts +13 -9
  448. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
  449. package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
  450. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
  451. package/src/resources/extensions/gsd/commands-cmux.ts +10 -6
  452. package/src/resources/extensions/gsd/commands-extensions.ts +747 -41
  453. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
  454. package/src/resources/extensions/gsd/dispatch-guard.ts +26 -2
  455. package/src/resources/extensions/gsd/file-lock.ts +84 -11
  456. package/src/resources/extensions/gsd/git-service.ts +1 -0
  457. package/src/resources/extensions/gsd/gitignore.ts +2 -1
  458. package/src/resources/extensions/gsd/gsd-db.ts +92 -32
  459. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
  460. package/src/resources/extensions/gsd/guided-flow.ts +259 -10
  461. package/src/resources/extensions/gsd/health-widget.ts +3 -1
  462. package/src/resources/extensions/gsd/journal.ts +29 -3
  463. package/src/resources/extensions/gsd/key-manager.ts +22 -0
  464. package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
  465. package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
  466. package/src/resources/extensions/gsd/model-router.ts +42 -1
  467. package/src/resources/extensions/gsd/notifications.ts +27 -15
  468. package/src/resources/extensions/gsd/pre-execution-checks.ts +33 -7
  469. package/src/resources/extensions/gsd/preferences-types.ts +8 -0
  470. package/src/resources/extensions/gsd/prompts/discuss-headless.md +29 -2
  471. package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
  472. package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  473. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  474. package/src/resources/extensions/gsd/prompts/system.md +1 -0
  475. package/src/resources/extensions/gsd/reports.ts +5 -4
  476. package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
  477. package/src/resources/extensions/gsd/safety/file-change-validator.ts +16 -3
  478. package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
  479. package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
  480. package/src/resources/extensions/gsd/state.ts +35 -30
  481. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +238 -4
  482. package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
  483. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
  484. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +122 -0
  485. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
  486. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +63 -0
  487. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
  488. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
  489. package/src/resources/extensions/gsd/tests/cmux.test.ts +5 -9
  490. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +15 -0
  491. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
  492. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  493. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  494. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +161 -0
  495. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
  496. package/src/resources/extensions/gsd/tests/derive-state.test.ts +1 -2
  497. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +14 -9
  498. package/src/resources/extensions/gsd/tests/dispatch-guard-summary-db-mismatch.test.ts +77 -0
  499. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
  500. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
  501. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +31 -0
  502. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
  503. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +1 -1
  504. package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
  505. package/src/resources/extensions/gsd/tests/exec-history.test.ts +113 -0
  506. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
  507. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +38 -0
  508. package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
  509. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +131 -0
  510. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +296 -1
  511. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
  512. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
  513. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +4 -2
  514. package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
  515. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
  516. package/src/resources/extensions/gsd/tests/integration/worktree-e2e.test.ts +11 -0
  517. package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
  518. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +66 -0
  519. package/src/resources/extensions/gsd/tests/key-manager.test.ts +2 -0
  520. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +76 -0
  521. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  522. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
  523. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  524. package/src/resources/extensions/gsd/tests/milestone-status-authoritative.test.ts +3 -3
  525. package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
  526. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +4 -2
  527. package/src/resources/extensions/gsd/tests/parallel-commit-scope.test.ts +5 -0
  528. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
  529. package/src/resources/extensions/gsd/tests/parallel-skill-prompt-integration.test.ts +150 -0
  530. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
  531. package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
  532. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +337 -0
  533. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
  534. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +39 -25
  535. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +181 -0
  536. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
  537. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
  538. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
  539. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
  540. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
  541. package/src/resources/extensions/gsd/tests/rewrite-docs-abandon-detect.test.ts +195 -0
  542. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
  543. package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
  544. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
  545. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
  546. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
  547. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +24 -0
  548. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
  549. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
  550. package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
  551. package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
  552. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
  553. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
  554. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
  555. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
  556. package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
  557. package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
  558. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +42 -2
  559. package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
  560. package/src/resources/extensions/gsd/tests/validate-extension-package.test.ts +168 -0
  561. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +138 -5
  562. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +25 -2
  563. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
  564. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
  565. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
  566. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
  567. package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
  568. package/src/resources/extensions/gsd/token-counter.ts +22 -5
  569. package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
  570. package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
  571. package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
  572. package/src/resources/extensions/gsd/uok/audit.ts +20 -2
  573. package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
  574. package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
  575. package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
  576. package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
  577. package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
  578. package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
  579. package/src/resources/extensions/gsd/uok/plan-v2.ts +39 -8
  580. package/src/resources/extensions/gsd/uok/writer.ts +113 -0
  581. package/src/resources/extensions/gsd/workflow-logger.ts +23 -3
  582. package/src/resources/extensions/gsd/worktree-manager.ts +1 -0
  583. package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
  584. package/src/resources/extensions/mcp-client/auth.ts +12 -1
  585. package/src/resources/extensions/mcp-client/index.ts +129 -10
  586. package/src/resources/extensions/shared/cmux-events.ts +59 -0
  587. package/src/resources/extensions/shared/rtk-session-stats.ts +1 -2
  588. package/src/resources/skills/create-skill/SKILL.md +2 -2
  589. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  590. package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  591. package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  592. package/src/resources/skills/verify-before-complete/SKILL.md +2 -1
  593. package/src/resources/skills/write-docs/SKILL.md +2 -1
  594. package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
  595. package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +0 -9
  596. /package/dist/web/standalone/.next/static/{n21VtX2hZlkpdEUO_nU4z → vidAVJkURvTJ0_V2-64ro}/_buildManifest.js +0 -0
  597. /package/dist/web/standalone/.next/static/{n21VtX2hZlkpdEUO_nU4z → vidAVJkURvTJ0_V2-64ro}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["// Lazy-loaded: Anthropic SDK (~500ms) is imported on first use, not at startup.\n// This avoids penalizing users who don't use Anthropic models.\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport { getEnvApiKey } from \"../env-api-keys.js\";\nimport type {\n\tContext,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n} from \"../types.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\n\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.js\";\nimport { adjustMaxTokensForThinking, buildBaseOptions } from \"./simple-options.js\";\nimport {\n\ttype AnthropicEffort,\n\ttype AnthropicOptions,\n\textractRetryAfterMs,\n\tmapThinkingLevelToEffort,\n\tprocessAnthropicStream,\n\tsupportsAdaptiveThinking,\n} from \"./anthropic-shared.js\";\n\n// Re-export types used by other modules\nexport type { AnthropicEffort, AnthropicOptions };\nexport { extractRetryAfterMs };\n\n/**\n * Resolve the base URL for Anthropic API requests.\n *\n * Resolution order:\n * 1. ANTHROPIC_BASE_URL environment variable (if set and non-empty after trim)\n * 2. model.baseUrl (from the model definition)\n *\n * This allows routing traffic through custom proxy endpoints (e.g. OpusMax,\n * local mirrors, corporate gateways) without modifying model definitions.\n */\nexport function resolveAnthropicBaseUrl(model: Model<\"anthropic-messages\">): string {\n\tconst envBaseUrl = process.env.ANTHROPIC_BASE_URL?.trim();\n\tif (envBaseUrl) {\n\t\treturn envBaseUrl;\n\t}\n\treturn model.baseUrl;\n}\n\nlet _AnthropicClass: typeof Anthropic | undefined;\nasync function getAnthropicClass(): Promise<typeof Anthropic> {\n\tif (!_AnthropicClass) {\n\t\tconst mod = await import(\"@anthropic-ai/sdk\");\n\t\t_AnthropicClass = mod.default;\n\t}\n\treturn _AnthropicClass;\n}\n\nfunction mergeHeaders(...headerSources: (Record<string, string> | undefined)[]): Record<string, string> {\n\tconst merged: Record<string, string> = {};\n\tfor (const headers of headerSources) {\n\t\tif (headers) {\n\t\t\tObject.assign(merged, headers);\n\t\t}\n\t}\n\treturn merged;\n}\n\nexport function usesAnthropicBearerAuth(provider: Model<\"anthropic-messages\">[\"provider\"]): boolean {\n\treturn provider === \"alibaba-coding-plan\" || provider === \"minimax\" || provider === \"minimax-cn\";\n}\n\nfunction hasBearerAuthorizationHeader(model: Model<\"anthropic-messages\">): boolean {\n\tconst authHeader = model.headers?.Authorization ?? model.headers?.authorization;\n\treturn typeof authHeader === \"string\" && authHeader.trim().toLowerCase().startsWith(\"bearer \");\n}\n\nasync function createClient(\n\tmodel: Model<\"anthropic-messages\">,\n\tapiKey: string,\n\tinterleavedThinking: boolean,\n\toptionsHeaders?: Record<string, string>,\n\tdynamicHeaders?: Record<string, string>,\n): Promise<{ client: Anthropic; isOAuthToken: boolean }> {\n\tconst AnthropicClass = await getAnthropicClass();\n\t// Adaptive thinking models (Opus 4.6, Sonnet 4.6) have interleaved thinking built-in.\n\t// The beta header is deprecated on Opus 4.6 and redundant on Sonnet 4.6, so skip it.\n\tconst needsInterleavedBeta = interleavedThinking && !supportsAdaptiveThinking(model.id);\n\n\t// Copilot: Bearer auth, selective betas (no fine-grained-tool-streaming)\n\tif (model.provider === \"github-copilot\") {\n\t\tconst betaFeatures: string[] = [];\n\t\tif (needsInterleavedBeta) {\n\t\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t\t}\n\n\t\tconst client = new AnthropicClass({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: resolveAnthropicBaseUrl(model),\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t...(betaFeatures.length > 0 ? { \"anthropic-beta\": betaFeatures.join(\",\") } : {}),\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\tdynamicHeaders,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: false };\n\t}\n\n\t// Skip beta headers for providers that don't support them (e.g., Alibaba Coding Plan)\n\tconst skipBetaHeaders = model.provider === \"alibaba-coding-plan\";\n\tconst betaFeatures = skipBetaHeaders ? [] : [\"fine-grained-tool-streaming-2025-05-14\"];\n\tif (needsInterleavedBeta && !skipBetaHeaders) {\n\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t}\n\n\t// API key auth (Anthropic OAuth removed per TOS compliance — use API keys or Claude CLI)\n\t// Some Anthropic-compatible providers require Bearer auth instead of x-api-key.\n\tconst usesBearerAuth = usesAnthropicBearerAuth(model.provider) || hasBearerAuthorizationHeader(model);\n\tconst client = new AnthropicClass({\n\t\tapiKey: usesBearerAuth ? null : apiKey,\n\t\tauthToken: usesBearerAuth ? apiKey : undefined,\n\t\tbaseURL: model.baseUrl,\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: mergeHeaders(\n\t\t\t{\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t...(betaFeatures.length > 0 ? { \"anthropic-beta\": betaFeatures.join(\",\") } : {}),\n\t\t\t},\n\t\t\tmodel.headers,\n\t\t\toptionsHeaders,\n\t\t),\n\t});\n\n\treturn { client, isOAuthToken: false };\n}\n\nexport const streamAnthropic: StreamFunction<\"anthropic-messages\", AnthropicOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: AnthropicOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t(async () => {\n\t\tconst apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? \"\";\n\n\t\tlet copilotDynamicHeaders: Record<string, string> | undefined;\n\t\tif (model.provider === \"github-copilot\") {\n\t\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\t\tcopilotDynamicHeaders = buildCopilotDynamicHeaders({\n\t\t\t\tmessages: context.messages,\n\t\t\t\thasImages,\n\t\t\t});\n\t\t}\n\n\t\tconst { client, isOAuthToken: isOAuth } = await createClient(\n\t\t\tmodel,\n\t\t\tapiKey,\n\t\t\toptions?.interleavedThinking ?? true,\n\t\t\toptions?.headers,\n\t\t\tcopilotDynamicHeaders,\n\t\t);\n\n\t\tprocessAnthropicStream(stream, {\n\t\t\tclient,\n\t\t\tmodel,\n\t\t\tcontext,\n\t\t\tisOAuthToken: isOAuth,\n\t\t\toptions,\n\t\t\tAnthropicSdkClass: _AnthropicClass,\n\t\t});\n\t})();\n\n\treturn stream;\n};\n\nexport const streamSimpleAnthropic: StreamFunction<\"anthropic-messages\", SimpleStreamOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider);\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = buildBaseOptions(model, options, apiKey);\n\tif (!options?.reasoning) {\n\t\treturn streamAnthropic(model, context, { ...base, thinkingEnabled: false } satisfies AnthropicOptions);\n\t}\n\n\t// For Opus 4.6 and Sonnet 4.6: use adaptive thinking with effort level\n\t// For older models: use budget-based thinking\n\tif (supportsAdaptiveThinking(model.id)) {\n\t\tconst effort = mapThinkingLevelToEffort(options.reasoning, model.id);\n\t\treturn streamAnthropic(model, context, {\n\t\t\t...base,\n\t\t\tthinkingEnabled: true,\n\t\t\teffort,\n\t\t} satisfies AnthropicOptions);\n\t}\n\n\tconst adjusted = adjustMaxTokensForThinking(\n\t\tbase.maxTokens || 0,\n\t\tmodel.maxTokens,\n\t\toptions.reasoning,\n\t\toptions.thinkingBudgets,\n\t);\n\n\treturn streamAnthropic(model, context, {\n\t\t...base,\n\t\tmaxTokens: adjusted.maxTokens,\n\t\tthinkingEnabled: true,\n\t\tthinkingBudgetTokens: adjusted.thinkingBudget,\n\t} satisfies AnthropicOptions);\n};\n"]}
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"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","sourcesContent":["// Lazy-loaded: Anthropic SDK (~500ms) is imported on first use, not at startup.\n// This avoids penalizing users who don't use Anthropic models.\nimport type Anthropic from \"@anthropic-ai/sdk\";\nimport { getEnvApiKey } from \"../env-api-keys.js\";\nimport type {\n\tContext,\n\tModel,\n\tSimpleStreamOptions,\n\tStreamFunction,\n} from \"../types.js\";\nimport { AssistantMessageEventStream } from \"../utils/event-stream.js\";\n\nimport { buildCopilotDynamicHeaders, hasCopilotVisionInput } from \"./github-copilot-headers.js\";\nimport { adjustMaxTokensForThinking, buildBaseOptions } from \"./simple-options.js\";\nimport {\n\ttype AnthropicEffort,\n\ttype AnthropicOptions,\n\textractRetryAfterMs,\n\tmapThinkingLevelToEffort,\n\tprocessAnthropicStream,\n\tsupportsAdaptiveThinking,\n} from \"./anthropic-shared.js\";\n\n// Re-export types used by other modules\nexport type { AnthropicEffort, AnthropicOptions };\nexport { extractRetryAfterMs };\n\n/**\n * Resolve the base URL for Anthropic API requests.\n *\n * Resolution order:\n * 1. ANTHROPIC_BASE_URL environment variable (if set and non-empty after trim)\n * 2. model.baseUrl (from the model definition)\n *\n * This allows routing traffic through custom proxy endpoints (e.g. OpusMax,\n * local mirrors, corporate gateways) without modifying model definitions.\n */\nexport function resolveAnthropicBaseUrl(model: Model<\"anthropic-messages\">): string {\n\tconst envBaseUrl = process.env.ANTHROPIC_BASE_URL?.trim();\n\tif (envBaseUrl) {\n\t\treturn envBaseUrl;\n\t}\n\treturn model.baseUrl;\n}\n\nlet _AnthropicClass: typeof Anthropic | undefined;\nasync function getAnthropicClass(): Promise<typeof Anthropic> {\n\tif (!_AnthropicClass) {\n\t\tconst mod = await import(\"@anthropic-ai/sdk\");\n\t\t_AnthropicClass = mod.default;\n\t}\n\treturn _AnthropicClass;\n}\n\nfunction mergeHeaders(...headerSources: (Record<string, string> | undefined)[]): Record<string, string> {\n\tconst merged: Record<string, string> = {};\n\tfor (const headers of headerSources) {\n\t\tif (headers) {\n\t\t\tObject.assign(merged, headers);\n\t\t}\n\t}\n\treturn merged;\n}\n\nexport function usesAnthropicBearerAuth(provider: Model<\"anthropic-messages\">[\"provider\"]): boolean {\n\treturn provider === \"alibaba-coding-plan\" || provider === \"minimax\" || provider === \"minimax-cn\";\n}\n\nfunction hasBearerAuthorizationHeader(model: Model<\"anthropic-messages\">): boolean {\n\tconst authHeader = model.headers?.Authorization ?? model.headers?.authorization;\n\treturn typeof authHeader === \"string\" && authHeader.trim().toLowerCase().startsWith(\"bearer \");\n}\n\nasync function createClient(\n\tmodel: Model<\"anthropic-messages\">,\n\tapiKey: string,\n\tinterleavedThinking: boolean,\n\toptionsHeaders?: Record<string, string>,\n\tdynamicHeaders?: Record<string, string>,\n): Promise<{ client: Anthropic; isOAuthToken: boolean }> {\n\tconst AnthropicClass = await getAnthropicClass();\n\t// Adaptive thinking models (Opus 4.6, Sonnet 4.6) have interleaved thinking built-in.\n\t// The beta header is deprecated on Opus 4.6 and redundant on Sonnet 4.6, so skip it.\n\tconst needsInterleavedBeta = interleavedThinking && !supportsAdaptiveThinking(model.id);\n\n\t// Copilot: Bearer auth, selective betas (no fine-grained-tool-streaming)\n\tif (model.provider === \"github-copilot\") {\n\t\tconst betaFeatures: string[] = [];\n\t\tif (needsInterleavedBeta) {\n\t\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t\t}\n\n\t\tconst client = new AnthropicClass({\n\t\t\tapiKey: null,\n\t\t\tauthToken: apiKey,\n\t\t\tbaseURL: resolveAnthropicBaseUrl(model),\n\t\t\tdangerouslyAllowBrowser: true,\n\t\t\tdefaultHeaders: mergeHeaders(\n\t\t\t\t{\n\t\t\t\t\taccept: \"application/json\",\n\t\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t\t...(betaFeatures.length > 0 ? { \"anthropic-beta\": betaFeatures.join(\",\") } : {}),\n\t\t\t\t},\n\t\t\t\tmodel.headers,\n\t\t\t\tdynamicHeaders,\n\t\t\t\toptionsHeaders,\n\t\t\t),\n\t\t});\n\n\t\treturn { client, isOAuthToken: false };\n\t}\n\n\t// Skip beta headers for providers that don't support fine-grained-tool-streaming.\n\t// MiniMax and minimax-cn implement the beta by emitting empty tool names in\n\t// content_block_start (name arrives as a delta instead), which corrupts conversation\n\t// history and triggers MiniMax error 2013 on the next request (#4538).\n\tconst skipBetaHeaders =\n\t\tmodel.provider === \"alibaba-coding-plan\" ||\n\t\tmodel.provider === \"minimax\" ||\n\t\tmodel.provider === \"minimax-cn\";\n\tconst betaFeatures = skipBetaHeaders ? [] : [\"fine-grained-tool-streaming-2025-05-14\"];\n\tif (needsInterleavedBeta && !skipBetaHeaders) {\n\t\tbetaFeatures.push(\"interleaved-thinking-2025-05-14\");\n\t}\n\n\t// API key auth (Anthropic OAuth removed per TOS compliance — use API keys or Claude CLI)\n\t// Some Anthropic-compatible providers require Bearer auth instead of x-api-key.\n\tconst usesBearerAuth = usesAnthropicBearerAuth(model.provider) || hasBearerAuthorizationHeader(model);\n\tconst client = new AnthropicClass({\n\t\tapiKey: usesBearerAuth ? null : apiKey,\n\t\tauthToken: usesBearerAuth ? apiKey : undefined,\n\t\tbaseURL: resolveAnthropicBaseUrl(model),\n\t\tdangerouslyAllowBrowser: true,\n\t\tdefaultHeaders: mergeHeaders(\n\t\t\t{\n\t\t\t\taccept: \"application/json\",\n\t\t\t\t\"anthropic-dangerous-direct-browser-access\": \"true\",\n\t\t\t\t...(betaFeatures.length > 0 ? { \"anthropic-beta\": betaFeatures.join(\",\") } : {}),\n\t\t\t},\n\t\t\tmodel.headers,\n\t\t\toptionsHeaders,\n\t\t),\n\t});\n\n\treturn { client, isOAuthToken: false };\n}\n\nexport const streamAnthropic: StreamFunction<\"anthropic-messages\", AnthropicOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: AnthropicOptions,\n): AssistantMessageEventStream => {\n\tconst stream = new AssistantMessageEventStream();\n\n\t(async () => {\n\t\tconst apiKey = options?.apiKey ?? getEnvApiKey(model.provider) ?? \"\";\n\n\t\tlet copilotDynamicHeaders: Record<string, string> | undefined;\n\t\tif (model.provider === \"github-copilot\") {\n\t\t\tconst hasImages = hasCopilotVisionInput(context.messages);\n\t\t\tcopilotDynamicHeaders = buildCopilotDynamicHeaders({\n\t\t\t\tmessages: context.messages,\n\t\t\t\thasImages,\n\t\t\t});\n\t\t}\n\n\t\tconst { client, isOAuthToken: isOAuth } = await createClient(\n\t\t\tmodel,\n\t\t\tapiKey,\n\t\t\toptions?.interleavedThinking ?? true,\n\t\t\toptions?.headers,\n\t\t\tcopilotDynamicHeaders,\n\t\t);\n\n\t\tprocessAnthropicStream(stream, {\n\t\t\tclient,\n\t\t\tmodel,\n\t\t\tcontext,\n\t\t\tisOAuthToken: isOAuth,\n\t\t\toptions,\n\t\t\tAnthropicSdkClass: _AnthropicClass,\n\t\t});\n\t})();\n\n\treturn stream;\n};\n\nexport const streamSimpleAnthropic: StreamFunction<\"anthropic-messages\", SimpleStreamOptions> = (\n\tmodel: Model<\"anthropic-messages\">,\n\tcontext: Context,\n\toptions?: SimpleStreamOptions,\n): AssistantMessageEventStream => {\n\tconst apiKey = options?.apiKey || getEnvApiKey(model.provider);\n\tif (!apiKey) {\n\t\tthrow new Error(`No API key for provider: ${model.provider}`);\n\t}\n\n\tconst base = buildBaseOptions(model, options, apiKey);\n\tif (!options?.reasoning) {\n\t\treturn streamAnthropic(model, context, { ...base, thinkingEnabled: false } satisfies AnthropicOptions);\n\t}\n\n\t// For Opus 4.6 and Sonnet 4.6: use adaptive thinking with effort level\n\t// For older models: use budget-based thinking\n\tif (supportsAdaptiveThinking(model.id)) {\n\t\tconst effort = mapThinkingLevelToEffort(options.reasoning, model.id);\n\t\treturn streamAnthropic(model, context, {\n\t\t\t...base,\n\t\t\tthinkingEnabled: true,\n\t\t\teffort,\n\t\t} satisfies AnthropicOptions);\n\t}\n\n\tconst adjusted = adjustMaxTokensForThinking(\n\t\tbase.maxTokens || 0,\n\t\tmodel.maxTokens,\n\t\toptions.reasoning,\n\t\toptions.thinkingBudgets,\n\t);\n\n\treturn streamAnthropic(model, context, {\n\t\t...base,\n\t\tmaxTokens: adjusted.maxTokens,\n\t\tthinkingEnabled: true,\n\t\tthinkingBudgetTokens: adjusted.thinkingBudget,\n\t} satisfies AnthropicOptions);\n};\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=minimax-tool-name.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minimax-tool-name.test.d.ts","sourceRoot":"","sources":["../../src/providers/minimax-tool-name.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Regression tests for MiniMax error 2013 "function name or parameters is empty" (#4538).
3
+ *
4
+ * Root cause: the `fine-grained-tool-streaming-2025-05-14` beta header is sent to
5
+ * MiniMax. MiniMax's Anthropic-compatible API implements this beta by streaming the
6
+ * tool name as a delta (empty string in `content_block_start`). The empty name gets
7
+ * stored in conversation history and sent back on the next request, causing MiniMax
8
+ * to return error 2013.
9
+ *
10
+ * Fix: exclude MiniMax (and minimax-cn) from the fine-grained-tool-streaming beta,
11
+ * same as alibaba-coding-plan. Also guard against storing empty tool names.
12
+ */
13
+ import test, { describe } from "node:test";
14
+ import assert from "node:assert/strict";
15
+ import { readFileSync } from "node:fs";
16
+ import { dirname, join } from "node:path";
17
+ import { fileURLToPath } from "node:url";
18
+ import { convertMessages } from "./anthropic-shared.js";
19
+ const __dirname = dirname(fileURLToPath(import.meta.url));
20
+ const source = readFileSync(join(__dirname, "anthropic.ts"), "utf-8");
21
+ describe("MiniMax fine-grained-tool-streaming exclusion (#4538)", () => {
22
+ test("minimax is excluded from fine-grained-tool-streaming-2025-05-14 beta", () => {
23
+ // The skipBetaHeaders flag must include minimax so it never receives the
24
+ // fine-grained-tool-streaming beta that causes empty tool names.
25
+ assert.match(source, /skipBetaHeaders.*minimax/s, "minimax must be included in skipBetaHeaders to suppress fine-grained-tool-streaming");
26
+ });
27
+ test("minimax-cn is excluded from fine-grained-tool-streaming-2025-05-14 beta", () => {
28
+ assert.match(source, /skipBetaHeaders.*minimax-cn/s, "minimax-cn must be included in skipBetaHeaders to suppress fine-grained-tool-streaming");
29
+ });
30
+ });
31
+ describe("empty tool name guard in convertMessages (#4538)", () => {
32
+ // When fine-grained-tool-streaming causes a tool name to arrive as empty in
33
+ // content_block_start, we must not store '' in conversation history.
34
+ // convertMessages must skip tool_use blocks with empty/missing names.
35
+ const minimaxModel = {
36
+ id: "MiniMax-M2",
37
+ api: "anthropic-messages",
38
+ provider: "minimax",
39
+ baseUrl: "https://api.minimax.io/anthropic",
40
+ reasoning: true,
41
+ input: ["text"],
42
+ name: "MiniMax-M2",
43
+ cost: { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 },
44
+ contextWindow: 196608,
45
+ maxTokens: 128000,
46
+ };
47
+ test("tool_use blocks with empty name are dropped from converted messages", () => {
48
+ const assistantMsg = {
49
+ role: "assistant",
50
+ content: [
51
+ {
52
+ type: "toolCall",
53
+ id: "toolu_01",
54
+ name: "", // empty — the bug: fine-grained streaming left name as ""
55
+ arguments: { path: "/foo" },
56
+ },
57
+ ],
58
+ api: "anthropic-messages",
59
+ provider: "minimax",
60
+ model: "MiniMax-M2",
61
+ usage: { input: 1, output: 1, cacheRead: 0, cacheWrite: 0, totalTokens: 2, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
62
+ stopReason: "toolUse",
63
+ timestamp: Date.now(),
64
+ };
65
+ const messages = [assistantMsg];
66
+ const result = convertMessages(messages, minimaxModel, false, undefined);
67
+ // The assistant block with the empty-name toolCall must not appear in the output.
68
+ // If it does appear, its tool_use name must not be empty.
69
+ for (const param of result) {
70
+ if (param.role === "assistant" && Array.isArray(param.content)) {
71
+ for (const block of param.content) {
72
+ if (block.type === "tool_use") {
73
+ assert.ok(block.name && block.name.length > 0, `tool_use block must never have an empty name; got: "${block.name}"`);
74
+ }
75
+ }
76
+ }
77
+ }
78
+ });
79
+ });
80
+ //# sourceMappingURL=minimax-tool-name.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"minimax-tool-name.test.js","sourceRoot":"","sources":["../../src/providers/minimax-tool-name.test.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Regression tests for MiniMax error 2013 \"function name or parameters is empty\" (#4538).\n *\n * Root cause: the `fine-grained-tool-streaming-2025-05-14` beta header is sent to\n * MiniMax. MiniMax's Anthropic-compatible API implements this beta by streaming the\n * tool name as a delta (empty string in `content_block_start`). The empty name gets\n * stored in conversation history and sent back on the next request, causing MiniMax\n * to return error 2013.\n *\n * Fix: exclude MiniMax (and minimax-cn) from the fine-grained-tool-streaming beta,\n * same as alibaba-coding-plan. Also guard against storing empty tool names.\n */\nimport test, { describe } from \"node:test\";\nimport assert from \"node:assert/strict\";\nimport { readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport { convertMessages } from \"./anthropic-shared.js\";\nimport type { AssistantMessage } from \"../types.js\";\n\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst source = readFileSync(join(__dirname, \"anthropic.ts\"), \"utf-8\");\n\ndescribe(\"MiniMax fine-grained-tool-streaming exclusion (#4538)\", () => {\n\ttest(\"minimax is excluded from fine-grained-tool-streaming-2025-05-14 beta\", () => {\n\t\t// The skipBetaHeaders flag must include minimax so it never receives the\n\t\t// fine-grained-tool-streaming beta that causes empty tool names.\n\t\tassert.match(\n\t\t\tsource,\n\t\t\t/skipBetaHeaders.*minimax/s,\n\t\t\t\"minimax must be included in skipBetaHeaders to suppress fine-grained-tool-streaming\",\n\t\t);\n\t});\n\n\ttest(\"minimax-cn is excluded from fine-grained-tool-streaming-2025-05-14 beta\", () => {\n\t\tassert.match(\n\t\t\tsource,\n\t\t\t/skipBetaHeaders.*minimax-cn/s,\n\t\t\t\"minimax-cn must be included in skipBetaHeaders to suppress fine-grained-tool-streaming\",\n\t\t);\n\t});\n});\n\ndescribe(\"empty tool name guard in convertMessages (#4538)\", () => {\n\t// When fine-grained-tool-streaming causes a tool name to arrive as empty in\n\t// content_block_start, we must not store '' in conversation history.\n\t// convertMessages must skip tool_use blocks with empty/missing names.\n\tconst minimaxModel = {\n\t\tid: \"MiniMax-M2\",\n\t\tapi: \"anthropic-messages\" as const,\n\t\tprovider: \"minimax\" as const,\n\t\tbaseUrl: \"https://api.minimax.io/anthropic\",\n\t\treasoning: true,\n\t\tinput: [\"text\"] as [\"text\"],\n\t\tname: \"MiniMax-M2\",\n\t\tcost: { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 },\n\t\tcontextWindow: 196608,\n\t\tmaxTokens: 128000,\n\t};\n\n\ttest(\"tool_use blocks with empty name are dropped from converted messages\", () => {\n\t\tconst assistantMsg: AssistantMessage = {\n\t\t\trole: \"assistant\",\n\t\t\tcontent: [\n\t\t\t\t{\n\t\t\t\t\ttype: \"toolCall\",\n\t\t\t\t\tid: \"toolu_01\",\n\t\t\t\t\tname: \"\", // empty — the bug: fine-grained streaming left name as \"\"\n\t\t\t\t\targuments: { path: \"/foo\" },\n\t\t\t\t},\n\t\t\t],\n\t\t\tapi: \"anthropic-messages\",\n\t\t\tprovider: \"minimax\",\n\t\t\tmodel: \"MiniMax-M2\",\n\t\t\tusage: { input: 1, output: 1, cacheRead: 0, cacheWrite: 0, totalTokens: 2, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },\n\t\t\tstopReason: \"toolUse\",\n\t\t\ttimestamp: Date.now(),\n\t\t};\n\n\t\tconst messages = [assistantMsg];\n\t\tconst result = convertMessages(messages, minimaxModel, false, undefined);\n\n\t\t// The assistant block with the empty-name toolCall must not appear in the output.\n\t\t// If it does appear, its tool_use name must not be empty.\n\t\tfor (const param of result) {\n\t\t\tif (param.role === \"assistant\" && Array.isArray(param.content)) {\n\t\t\t\tfor (const block of param.content) {\n\t\t\t\t\tif ((block as any).type === \"tool_use\") {\n\t\t\t\t\t\tassert.ok(\n\t\t\t\t\t\t\t(block as any).name && (block as any).name.length > 0,\n\t\t\t\t\t\t\t`tool_use block must never have an empty name; got: \"${(block as any).name}\"`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n});\n"]}
@@ -1,4 +1,14 @@
1
1
  import type { Api, Model, SimpleStreamOptions, StreamOptions, ThinkingBudgets, ThinkingLevel } from "../types.js";
2
+ /**
3
+ * Compute the default maxTokens for a model when no explicit value is provided.
4
+ *
5
+ * The 32 k cap is retained only for native Anthropic models (api === "anthropic-messages")
6
+ * where the Anthropic API historically rejected higher values. Custom and
7
+ * Anthropic-compatible models (e.g. OpenAI-completions, Vertex, etc.) use their
8
+ * declared model.maxTokens directly so that providers with larger output windows
9
+ * (131 072 tokens, etc.) are not silently capped.
10
+ */
11
+ export declare function defaultMaxTokens(model: Model<Api>): number;
2
12
  export declare function buildBaseOptions(model: Model<Api>, options?: SimpleStreamOptions, apiKey?: string): StreamOptions;
3
13
  export declare function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, "xhigh"> | undefined;
4
14
  export declare function adjustMaxTokensForThinking(baseMaxTokens: number, modelMaxTokens: number, reasoningLevel: ThinkingLevel, customBudgets?: ThinkingBudgets): {
@@ -1 +1 @@
1
- {"version":3,"file":"simple-options.d.ts","sourceRoot":"","sources":["../../src/providers/simple-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAElH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAajH;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,GAAG,SAAS,CAE7G;AAED,wBAAgB,0BAA0B,CACzC,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,aAAa,EAC7B,aAAa,CAAC,EAAE,eAAe,GAC7B;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAmB/C"}
1
+ {"version":3,"file":"simple-options.d.ts","sourceRoot":"","sources":["../../src/providers/simple-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,mBAAmB,EAAE,aAAa,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAElH;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,MAAM,CAK1D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,mBAAmB,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAajH;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,EAAE,OAAO,CAAC,GAAG,SAAS,CAE7G;AAED,wBAAgB,0BAA0B,CACzC,aAAa,EAAE,MAAM,EACrB,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,aAAa,EAC7B,aAAa,CAAC,EAAE,eAAe,GAC7B;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,MAAM,CAAA;CAAE,CAmB/C"}
@@ -1,7 +1,22 @@
1
+ /**
2
+ * Compute the default maxTokens for a model when no explicit value is provided.
3
+ *
4
+ * The 32 k cap is retained only for native Anthropic models (api === "anthropic-messages")
5
+ * where the Anthropic API historically rejected higher values. Custom and
6
+ * Anthropic-compatible models (e.g. OpenAI-completions, Vertex, etc.) use their
7
+ * declared model.maxTokens directly so that providers with larger output windows
8
+ * (131 072 tokens, etc.) are not silently capped.
9
+ */
10
+ export function defaultMaxTokens(model) {
11
+ if (model.api === "anthropic-messages") {
12
+ return Math.min(model.maxTokens, 32000);
13
+ }
14
+ return model.maxTokens;
15
+ }
1
16
  export function buildBaseOptions(model, options, apiKey) {
2
17
  return {
3
18
  temperature: options?.temperature,
4
- maxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),
19
+ maxTokens: options?.maxTokens || defaultMaxTokens(model),
5
20
  signal: options?.signal,
6
21
  apiKey: apiKey || options?.apiKey,
7
22
  cacheRetention: options?.cacheRetention,
@@ -1 +1 @@
1
- {"version":3,"file":"simple-options.js","sourceRoot":"","sources":["../../src/providers/simple-options.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,gBAAgB,CAAC,KAAiB,EAAE,OAA6B,EAAE,MAAe;IACjG,OAAO;QACN,WAAW,EAAE,OAAO,EAAE,WAAW;QACjC,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC;QACjE,MAAM,EAAE,OAAO,EAAE,MAAM;QACvB,MAAM,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM;QACjC,cAAc,EAAE,OAAO,EAAE,cAAc;QACvC,SAAS,EAAE,OAAO,EAAE,SAAS;QAC7B,OAAO,EAAE,OAAO,EAAE,OAAO;QACzB,SAAS,EAAE,OAAO,EAAE,SAAS;QAC7B,eAAe,EAAE,OAAO,EAAE,eAAe;QACzC,QAAQ,EAAE,OAAO,EAAE,QAAQ;KAC3B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAiC;IAC/D,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,0BAA0B,CACzC,aAAqB,EACrB,cAAsB,EACtB,cAA6B,EAC7B,aAA+B;IAE/B,MAAM,cAAc,GAAoB;QACvC,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,KAAK;KACX,CAAC;IACF,MAAM,OAAO,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,aAAa,EAAE,CAAC;IAExD,MAAM,eAAe,GAAG,IAAI,CAAC;IAC7B,MAAM,KAAK,GAAG,cAAc,CAAC,cAAc,CAAE,CAAC;IAC9C,IAAI,cAAc,GAAG,OAAO,CAAC,KAAK,CAAE,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,cAAc,EAAE,cAAc,CAAC,CAAC;IAE3E,IAAI,SAAS,IAAI,cAAc,EAAE,CAAC;QACjC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,eAAe,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;AACtC,CAAC","sourcesContent":["import type { Api, Model, SimpleStreamOptions, StreamOptions, ThinkingBudgets, ThinkingLevel } from \"../types.js\";\n\nexport function buildBaseOptions(model: Model<Api>, options?: SimpleStreamOptions, apiKey?: string): StreamOptions {\n\treturn {\n\t\ttemperature: options?.temperature,\n\t\tmaxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),\n\t\tsignal: options?.signal,\n\t\tapiKey: apiKey || options?.apiKey,\n\t\tcacheRetention: options?.cacheRetention,\n\t\tsessionId: options?.sessionId,\n\t\theaders: options?.headers,\n\t\tonPayload: options?.onPayload,\n\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\tmetadata: options?.metadata,\n\t};\n}\n\nexport function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, \"xhigh\"> | undefined {\n\treturn effort === \"xhigh\" ? \"high\" : effort;\n}\n\nexport function adjustMaxTokensForThinking(\n\tbaseMaxTokens: number,\n\tmodelMaxTokens: number,\n\treasoningLevel: ThinkingLevel,\n\tcustomBudgets?: ThinkingBudgets,\n): { maxTokens: number; thinkingBudget: number } {\n\tconst defaultBudgets: ThinkingBudgets = {\n\t\tminimal: 1024,\n\t\tlow: 2048,\n\t\tmedium: 8192,\n\t\thigh: 16384,\n\t};\n\tconst budgets = { ...defaultBudgets, ...customBudgets };\n\n\tconst minOutputTokens = 1024;\n\tconst level = clampReasoning(reasoningLevel)!;\n\tlet thinkingBudget = budgets[level]!;\n\tconst maxTokens = Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);\n\n\tif (maxTokens <= thinkingBudget) {\n\t\tthinkingBudget = Math.max(0, maxTokens - minOutputTokens);\n\t}\n\n\treturn { maxTokens, thinkingBudget };\n}\n"]}
1
+ {"version":3,"file":"simple-options.js","sourceRoot":"","sources":["../../src/providers/simple-options.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAiB;IACjD,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,EAAE,CAAC;QACxC,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,KAAK,CAAC,SAAS,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAAiB,EAAE,OAA6B,EAAE,MAAe;IACjG,OAAO;QACN,WAAW,EAAE,OAAO,EAAE,WAAW;QACjC,SAAS,EAAE,OAAO,EAAE,SAAS,IAAI,gBAAgB,CAAC,KAAK,CAAC;QACxD,MAAM,EAAE,OAAO,EAAE,MAAM;QACvB,MAAM,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM;QACjC,cAAc,EAAE,OAAO,EAAE,cAAc;QACvC,SAAS,EAAE,OAAO,EAAE,SAAS;QAC7B,OAAO,EAAE,OAAO,EAAE,OAAO;QACzB,SAAS,EAAE,OAAO,EAAE,SAAS;QAC7B,eAAe,EAAE,OAAO,EAAE,eAAe;QACzC,QAAQ,EAAE,OAAO,EAAE,QAAQ;KAC3B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,MAAiC;IAC/D,OAAO,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,0BAA0B,CACzC,aAAqB,EACrB,cAAsB,EACtB,cAA6B,EAC7B,aAA+B;IAE/B,MAAM,cAAc,GAAoB;QACvC,OAAO,EAAE,IAAI;QACb,GAAG,EAAE,IAAI;QACT,MAAM,EAAE,IAAI;QACZ,IAAI,EAAE,KAAK;KACX,CAAC;IACF,MAAM,OAAO,GAAG,EAAE,GAAG,cAAc,EAAE,GAAG,aAAa,EAAE,CAAC;IAExD,MAAM,eAAe,GAAG,IAAI,CAAC;IAC7B,MAAM,KAAK,GAAG,cAAc,CAAC,cAAc,CAAE,CAAC;IAC9C,IAAI,cAAc,GAAG,OAAO,CAAC,KAAK,CAAE,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,aAAa,GAAG,cAAc,EAAE,cAAc,CAAC,CAAC;IAE3E,IAAI,SAAS,IAAI,cAAc,EAAE,CAAC;QACjC,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,eAAe,CAAC,CAAC;IAC3D,CAAC;IAED,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;AACtC,CAAC","sourcesContent":["import type { Api, Model, SimpleStreamOptions, StreamOptions, ThinkingBudgets, ThinkingLevel } from \"../types.js\";\n\n/**\n * Compute the default maxTokens for a model when no explicit value is provided.\n *\n * The 32 k cap is retained only for native Anthropic models (api === \"anthropic-messages\")\n * where the Anthropic API historically rejected higher values. Custom and\n * Anthropic-compatible models (e.g. OpenAI-completions, Vertex, etc.) use their\n * declared model.maxTokens directly so that providers with larger output windows\n * (131 072 tokens, etc.) are not silently capped.\n */\nexport function defaultMaxTokens(model: Model<Api>): number {\n\tif (model.api === \"anthropic-messages\") {\n\t\treturn Math.min(model.maxTokens, 32000);\n\t}\n\treturn model.maxTokens;\n}\n\nexport function buildBaseOptions(model: Model<Api>, options?: SimpleStreamOptions, apiKey?: string): StreamOptions {\n\treturn {\n\t\ttemperature: options?.temperature,\n\t\tmaxTokens: options?.maxTokens || defaultMaxTokens(model),\n\t\tsignal: options?.signal,\n\t\tapiKey: apiKey || options?.apiKey,\n\t\tcacheRetention: options?.cacheRetention,\n\t\tsessionId: options?.sessionId,\n\t\theaders: options?.headers,\n\t\tonPayload: options?.onPayload,\n\t\tmaxRetryDelayMs: options?.maxRetryDelayMs,\n\t\tmetadata: options?.metadata,\n\t};\n}\n\nexport function clampReasoning(effort: ThinkingLevel | undefined): Exclude<ThinkingLevel, \"xhigh\"> | undefined {\n\treturn effort === \"xhigh\" ? \"high\" : effort;\n}\n\nexport function adjustMaxTokensForThinking(\n\tbaseMaxTokens: number,\n\tmodelMaxTokens: number,\n\treasoningLevel: ThinkingLevel,\n\tcustomBudgets?: ThinkingBudgets,\n): { maxTokens: number; thinkingBudget: number } {\n\tconst defaultBudgets: ThinkingBudgets = {\n\t\tminimal: 1024,\n\t\tlow: 2048,\n\t\tmedium: 8192,\n\t\thigh: 16384,\n\t};\n\tconst budgets = { ...defaultBudgets, ...customBudgets };\n\n\tconst minOutputTokens = 1024;\n\tconst level = clampReasoning(reasoningLevel)!;\n\tlet thinkingBudget = budgets[level]!;\n\tconst maxTokens = Math.min(baseMaxTokens + thinkingBudget, modelMaxTokens);\n\n\tif (maxTokens <= thinkingBudget) {\n\t\tthinkingBudget = Math.max(0, maxTokens - minOutputTokens);\n\t}\n\n\treturn { maxTokens, thinkingBudget };\n}\n"]}
@@ -1,8 +1,13 @@
1
1
  {
2
2
  "name": "@gsd/pi-ai",
3
- "version": "2.76.0",
3
+ "version": "2.77.0",
4
4
  "description": "Unified LLM API (vendored from pi-mono)",
5
5
  "type": "module",
6
+ "gsd": {
7
+ "linkable": true,
8
+ "scope": "@gsd",
9
+ "name": "pi-ai"
10
+ },
6
11
  "main": "./dist/index.js",
7
12
  "types": "./dist/index.d.ts",
8
13
  "exports": {
@@ -292,4 +292,46 @@ export const CUSTOM_MODELS = {
292
292
  compat: { thinkingFormat: "zai", supportsDeveloperRole: false },
293
293
  } satisfies Model<"openai-completions">,
294
294
  },
295
+
296
+ // ─── MiniMax additive hotfixes ───────────────────────────────────────
297
+ // models.dev currently omits MiniMax-M2.1-highspeed in some snapshots.
298
+ // Keep this additive (no overrides) so generated models still win when present.
299
+ "minimax": {
300
+ "MiniMax-M2.1-highspeed": {
301
+ id: "MiniMax-M2.1-highspeed",
302
+ name: "MiniMax-M2.1-highspeed",
303
+ api: "anthropic-messages",
304
+ provider: "minimax",
305
+ baseUrl: "https://api.minimax.io/anthropic",
306
+ reasoning: true,
307
+ input: ["text"],
308
+ cost: {
309
+ input: 0.6,
310
+ output: 2.4,
311
+ cacheRead: 0,
312
+ cacheWrite: 0,
313
+ },
314
+ contextWindow: 204800,
315
+ maxTokens: 131072,
316
+ } satisfies Model<"anthropic-messages">,
317
+ },
318
+ "minimax-cn": {
319
+ "MiniMax-M2.1-highspeed": {
320
+ id: "MiniMax-M2.1-highspeed",
321
+ name: "MiniMax-M2.1-highspeed",
322
+ api: "anthropic-messages",
323
+ provider: "minimax-cn",
324
+ baseUrl: "https://api.minimaxi.com/anthropic",
325
+ reasoning: true,
326
+ input: ["text"],
327
+ cost: {
328
+ input: 0.6,
329
+ output: 2.4,
330
+ cacheRead: 0,
331
+ cacheWrite: 0,
332
+ },
333
+ contextWindow: 204800,
334
+ maxTokens: 131072,
335
+ } satisfies Model<"anthropic-messages">,
336
+ },
295
337
  } as const;
@@ -18,7 +18,7 @@ test("usesAnthropicBearerAuth covers Bearer-only Anthropic-compatible providers
18
18
  test("createClient routes Bearer-auth providers through authToken (#3783)", () => {
19
19
  const source = readFileSync(join(__dirname, "..", "..", "src", "providers", "anthropic.ts"), "utf-8");
20
20
  assert.ok(
21
- source.includes("const usesBearerAuth = usesAnthropicBearerAuth(model.provider);"),
21
+ source.includes("const usesBearerAuth = usesAnthropicBearerAuth(model.provider)"),
22
22
  "createClient should derive auth mode from usesAnthropicBearerAuth",
23
23
  );
24
24
  assert.ok(
@@ -339,10 +339,16 @@ export function convertMessages(
339
339
  });
340
340
  }
341
341
  } else if (block.type === "toolCall") {
342
+ // Guard: never forward a tool_use block with an empty name.
343
+ // fine-grained-tool-streaming-2025-05-14 can cause the name to arrive
344
+ // as a delta on incompatible providers (e.g. MiniMax), leaving block.name
345
+ // as "". Re-sending that to MiniMax triggers error 2013 (#4538).
346
+ const toolName = isOAuthToken ? toClaudeCodeName(block.name) : block.name;
347
+ if (!toolName) continue;
342
348
  blocks.push({
343
349
  type: "tool_use",
344
350
  id: block.id,
345
- name: isOAuthToken ? toClaudeCodeName(block.name) : block.name,
351
+ name: toolName,
346
352
  input: block.arguments ?? {},
347
353
  });
348
354
  } else if (block.type === "serverToolUse") {
@@ -505,7 +511,9 @@ export function buildParams(
505
511
  if (supportsAdaptiveThinking(model.id)) {
506
512
  params.thinking = { type: "adaptive" };
507
513
  if (options.effort) {
508
- params.output_config = { effort: options.effort };
514
+ // The SDK's OutputConfig.effort type doesn't include "xhigh" yet.
515
+ // Cast so our superset AnthropicEffort type compiles cleanly.
516
+ params.output_config = { effort: options.effort as "low" | "medium" | "high" | "max" };
509
517
  }
510
518
  } else {
511
519
  params.thinking = {
@@ -641,12 +649,25 @@ export function processAnthropicStream(
641
649
  output.content.push(block);
642
650
  stream.push({ type: "thinking_start", contentIndex: output.content.length - 1, partial: output });
643
651
  } else if (event.content_block.type === "tool_use") {
652
+ // Guard: some Anthropic-compatible providers (e.g. MiniMax with
653
+ // fine-grained-tool-streaming beta) stream the tool name as a delta,
654
+ // leaving content_block.name as "" here. Fall back to the tool list
655
+ // if available to avoid storing an empty name in history (#4538).
656
+ const rawName = event.content_block.name;
657
+ let resolvedName: string;
658
+ if (rawName) {
659
+ resolvedName = isOAuthToken ? fromClaudeCodeName(rawName, context.tools) : rawName;
660
+ } else {
661
+ const fallbackName = context.tools?.[0]?.name ?? rawName;
662
+ if (fallbackName && fallbackName !== rawName) {
663
+ console.warn(`[anthropic-shared] Empty tool name in content_block_start (id=${event.content_block.id}); falling back to first tool: ${fallbackName}`);
664
+ }
665
+ resolvedName = fallbackName;
666
+ }
644
667
  const block: Block = {
645
668
  type: "toolCall",
646
669
  id: event.content_block.id,
647
- name: isOAuthToken
648
- ? fromClaudeCodeName(event.content_block.name, context.tools)
649
- : event.content_block.name,
670
+ name: resolvedName,
650
671
  arguments: (event.content_block.input as Record<string, any>) ?? {},
651
672
  partialJson: "",
652
673
  index: event.index,
@@ -110,8 +110,14 @@ async function createClient(
110
110
  return { client, isOAuthToken: false };
111
111
  }
112
112
 
113
- // Skip beta headers for providers that don't support them (e.g., Alibaba Coding Plan)
114
- const skipBetaHeaders = model.provider === "alibaba-coding-plan";
113
+ // Skip beta headers for providers that don't support fine-grained-tool-streaming.
114
+ // MiniMax and minimax-cn implement the beta by emitting empty tool names in
115
+ // content_block_start (name arrives as a delta instead), which corrupts conversation
116
+ // history and triggers MiniMax error 2013 on the next request (#4538).
117
+ const skipBetaHeaders =
118
+ model.provider === "alibaba-coding-plan" ||
119
+ model.provider === "minimax" ||
120
+ model.provider === "minimax-cn";
115
121
  const betaFeatures = skipBetaHeaders ? [] : ["fine-grained-tool-streaming-2025-05-14"];
116
122
  if (needsInterleavedBeta && !skipBetaHeaders) {
117
123
  betaFeatures.push("interleaved-thinking-2025-05-14");
@@ -123,7 +129,7 @@ async function createClient(
123
129
  const client = new AnthropicClass({
124
130
  apiKey: usesBearerAuth ? null : apiKey,
125
131
  authToken: usesBearerAuth ? apiKey : undefined,
126
- baseURL: model.baseUrl,
132
+ baseURL: resolveAnthropicBaseUrl(model),
127
133
  dangerouslyAllowBrowser: true,
128
134
  defaultHeaders: mergeHeaders(
129
135
  {
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Regression tests for MiniMax error 2013 "function name or parameters is empty" (#4538).
3
+ *
4
+ * Root cause: the `fine-grained-tool-streaming-2025-05-14` beta header is sent to
5
+ * MiniMax. MiniMax's Anthropic-compatible API implements this beta by streaming the
6
+ * tool name as a delta (empty string in `content_block_start`). The empty name gets
7
+ * stored in conversation history and sent back on the next request, causing MiniMax
8
+ * to return error 2013.
9
+ *
10
+ * Fix: exclude MiniMax (and minimax-cn) from the fine-grained-tool-streaming beta,
11
+ * same as alibaba-coding-plan. Also guard against storing empty tool names.
12
+ */
13
+ import test, { describe } from "node:test";
14
+ import assert from "node:assert/strict";
15
+ import { readFileSync } from "node:fs";
16
+ import { dirname, join } from "node:path";
17
+ import { fileURLToPath } from "node:url";
18
+ import { convertMessages } from "./anthropic-shared.js";
19
+ import type { AssistantMessage } from "../types.js";
20
+
21
+ const __dirname = dirname(fileURLToPath(import.meta.url));
22
+ const source = readFileSync(join(__dirname, "anthropic.ts"), "utf-8");
23
+
24
+ describe("MiniMax fine-grained-tool-streaming exclusion (#4538)", () => {
25
+ test("minimax is excluded from fine-grained-tool-streaming-2025-05-14 beta", () => {
26
+ // The skipBetaHeaders flag must include minimax so it never receives the
27
+ // fine-grained-tool-streaming beta that causes empty tool names.
28
+ assert.match(
29
+ source,
30
+ /skipBetaHeaders.*minimax/s,
31
+ "minimax must be included in skipBetaHeaders to suppress fine-grained-tool-streaming",
32
+ );
33
+ });
34
+
35
+ test("minimax-cn is excluded from fine-grained-tool-streaming-2025-05-14 beta", () => {
36
+ assert.match(
37
+ source,
38
+ /skipBetaHeaders.*minimax-cn/s,
39
+ "minimax-cn must be included in skipBetaHeaders to suppress fine-grained-tool-streaming",
40
+ );
41
+ });
42
+ });
43
+
44
+ describe("empty tool name guard in convertMessages (#4538)", () => {
45
+ // When fine-grained-tool-streaming causes a tool name to arrive as empty in
46
+ // content_block_start, we must not store '' in conversation history.
47
+ // convertMessages must skip tool_use blocks with empty/missing names.
48
+ const minimaxModel = {
49
+ id: "MiniMax-M2",
50
+ api: "anthropic-messages" as const,
51
+ provider: "minimax" as const,
52
+ baseUrl: "https://api.minimax.io/anthropic",
53
+ reasoning: true,
54
+ input: ["text"] as ["text"],
55
+ name: "MiniMax-M2",
56
+ cost: { input: 0.3, output: 1.2, cacheRead: 0, cacheWrite: 0 },
57
+ contextWindow: 196608,
58
+ maxTokens: 128000,
59
+ };
60
+
61
+ test("tool_use blocks with empty name are dropped from converted messages", () => {
62
+ const assistantMsg: AssistantMessage = {
63
+ role: "assistant",
64
+ content: [
65
+ {
66
+ type: "toolCall",
67
+ id: "toolu_01",
68
+ name: "", // empty — the bug: fine-grained streaming left name as ""
69
+ arguments: { path: "/foo" },
70
+ },
71
+ ],
72
+ api: "anthropic-messages",
73
+ provider: "minimax",
74
+ model: "MiniMax-M2",
75
+ usage: { input: 1, output: 1, cacheRead: 0, cacheWrite: 0, totalTokens: 2, cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 } },
76
+ stopReason: "toolUse",
77
+ timestamp: Date.now(),
78
+ };
79
+
80
+ const messages = [assistantMsg];
81
+ const result = convertMessages(messages, minimaxModel, false, undefined);
82
+
83
+ // The assistant block with the empty-name toolCall must not appear in the output.
84
+ // If it does appear, its tool_use name must not be empty.
85
+ for (const param of result) {
86
+ if (param.role === "assistant" && Array.isArray(param.content)) {
87
+ for (const block of param.content) {
88
+ if ((block as any).type === "tool_use") {
89
+ assert.ok(
90
+ (block as any).name && (block as any).name.length > 0,
91
+ `tool_use block must never have an empty name; got: "${(block as any).name}"`,
92
+ );
93
+ }
94
+ }
95
+ }
96
+ }
97
+ });
98
+ });
@@ -1,9 +1,25 @@
1
1
  import type { Api, Model, SimpleStreamOptions, StreamOptions, ThinkingBudgets, ThinkingLevel } from "../types.js";
2
2
 
3
+ /**
4
+ * Compute the default maxTokens for a model when no explicit value is provided.
5
+ *
6
+ * The 32 k cap is retained only for native Anthropic models (api === "anthropic-messages")
7
+ * where the Anthropic API historically rejected higher values. Custom and
8
+ * Anthropic-compatible models (e.g. OpenAI-completions, Vertex, etc.) use their
9
+ * declared model.maxTokens directly so that providers with larger output windows
10
+ * (131 072 tokens, etc.) are not silently capped.
11
+ */
12
+ export function defaultMaxTokens(model: Model<Api>): number {
13
+ if (model.api === "anthropic-messages") {
14
+ return Math.min(model.maxTokens, 32000);
15
+ }
16
+ return model.maxTokens;
17
+ }
18
+
3
19
  export function buildBaseOptions(model: Model<Api>, options?: SimpleStreamOptions, apiKey?: string): StreamOptions {
4
20
  return {
5
21
  temperature: options?.temperature,
6
- maxTokens: options?.maxTokens || Math.min(model.maxTokens, 32000),
22
+ maxTokens: options?.maxTokens || defaultMaxTokens(model),
7
23
  signal: options?.signal,
8
24
  apiKey: apiKey || options?.apiKey,
9
25
  cacheRetention: options?.cacheRetention,