anymous 1.2.7 → 1.3.1

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 (448) hide show
  1. package/bin/anymous.exe +7 -0
  2. package/package.json +20 -135
  3. package/postinstall.mjs +214 -0
  4. package/bin/anymous.cjs +0 -45
  5. package/src/account/account.ts +0 -473
  6. package/src/account/repo.ts +0 -171
  7. package/src/account/schema.ts +0 -99
  8. package/src/account/url.ts +0 -8
  9. package/src/acp/agent.ts +0 -95
  10. package/src/acp/config-option.ts +0 -203
  11. package/src/acp/content.ts +0 -269
  12. package/src/acp/directory.ts +0 -212
  13. package/src/acp/error.ts +0 -97
  14. package/src/acp/event.ts +0 -342
  15. package/src/acp/permission.ts +0 -254
  16. package/src/acp/profile.ts +0 -42
  17. package/src/acp/service.ts +0 -1097
  18. package/src/acp/session.ts +0 -232
  19. package/src/acp/tool.ts +0 -364
  20. package/src/acp/usage.ts +0 -239
  21. package/src/agent/agent.ts +0 -973
  22. package/src/agent/generate.txt +0 -75
  23. package/src/agent/prompt/architect.txt +0 -26
  24. package/src/agent/prompt/backend.txt +0 -26
  25. package/src/agent/prompt/build.txt +0 -31
  26. package/src/agent/prompt/code-reviewer.txt +0 -29
  27. package/src/agent/prompt/compaction.txt +0 -45
  28. package/src/agent/prompt/database.txt +0 -27
  29. package/src/agent/prompt/debug-tools.txt +0 -40
  30. package/src/agent/prompt/debug.txt +0 -23
  31. package/src/agent/prompt/devops.txt +0 -26
  32. package/src/agent/prompt/docs.txt +0 -23
  33. package/src/agent/prompt/exe-extractor.txt +0 -39
  34. package/src/agent/prompt/explore.txt +0 -42
  35. package/src/agent/prompt/frontend.txt +0 -29
  36. package/src/agent/prompt/general.txt +0 -25
  37. package/src/agent/prompt/memory-dump.txt +0 -37
  38. package/src/agent/prompt/pentest-critic.txt +0 -51
  39. package/src/agent/prompt/pentest-enumerator.txt +0 -72
  40. package/src/agent/prompt/pentest-exploiter.txt +0 -69
  41. package/src/agent/prompt/pentest-identity.txt +0 -59
  42. package/src/agent/prompt/pentest-lead.txt +0 -46
  43. package/src/agent/prompt/pentest-postexploit.txt +0 -84
  44. package/src/agent/prompt/pentest-recon.txt +0 -50
  45. package/src/agent/prompt/pentest-reporter.txt +0 -76
  46. package/src/agent/prompt/pentest-scanner.txt +0 -57
  47. package/src/agent/prompt/pentest-webapp.txt +0 -94
  48. package/src/agent/prompt/performance.txt +0 -27
  49. package/src/agent/prompt/plan.txt +0 -35
  50. package/src/agent/prompt/refactor.txt +0 -31
  51. package/src/agent/prompt/reverser-automator.txt +0 -96
  52. package/src/agent/prompt/reverser-binary.txt +0 -62
  53. package/src/agent/prompt/reverser-dynamic.txt +0 -76
  54. package/src/agent/prompt/reverser-source.txt +0 -93
  55. package/src/agent/prompt/reverser-static.txt +0 -76
  56. package/src/agent/prompt/security.txt +0 -34
  57. package/src/agent/prompt/summary.txt +0 -22
  58. package/src/agent/prompt/test-writer.txt +0 -34
  59. package/src/agent/prompt/title.txt +0 -44
  60. package/src/agent/prompt/web-designer.txt +0 -23
  61. package/src/agent/subagent-permissions.ts +0 -27
  62. package/src/audio.d.ts +0 -14
  63. package/src/auth/index.ts +0 -97
  64. package/src/background/job.ts +0 -37
  65. package/src/bus/global.ts +0 -22
  66. package/src/cli/bootstrap.ts +0 -11
  67. package/src/cli/cmd/account.ts +0 -264
  68. package/src/cli/cmd/acp.ts +0 -73
  69. package/src/cli/cmd/agent.ts +0 -259
  70. package/src/cli/cmd/attach.ts +0 -148
  71. package/src/cli/cmd/cmd.ts +0 -7
  72. package/src/cli/cmd/db.ts +0 -62
  73. package/src/cli/cmd/debug/agent.handler.ts +0 -193
  74. package/src/cli/cmd/debug/agent.ts +0 -27
  75. package/src/cli/cmd/debug/config.ts +0 -14
  76. package/src/cli/cmd/debug/file.ts +0 -73
  77. package/src/cli/cmd/debug/index.ts +0 -87
  78. package/src/cli/cmd/debug/lsp.ts +0 -50
  79. package/src/cli/cmd/debug/ripgrep.ts +0 -79
  80. package/src/cli/cmd/debug/scrap.ts +0 -16
  81. package/src/cli/cmd/debug/skill.ts +0 -15
  82. package/src/cli/cmd/debug/snapshot.ts +0 -50
  83. package/src/cli/cmd/debug/startup.ts +0 -11
  84. package/src/cli/cmd/debug/v2.ts +0 -42
  85. package/src/cli/cmd/export.ts +0 -292
  86. package/src/cli/cmd/generate.ts +0 -54
  87. package/src/cli/cmd/github.handler.ts +0 -1593
  88. package/src/cli/cmd/github.shared.ts +0 -30
  89. package/src/cli/cmd/github.ts +0 -42
  90. package/src/cli/cmd/import.ts +0 -230
  91. package/src/cli/cmd/mcp.ts +0 -840
  92. package/src/cli/cmd/models.ts +0 -66
  93. package/src/cli/cmd/plug.ts +0 -230
  94. package/src/cli/cmd/pr.ts +0 -115
  95. package/src/cli/cmd/prompt-display.ts +0 -1
  96. package/src/cli/cmd/providers.ts +0 -534
  97. package/src/cli/cmd/run/demo.ts +0 -1274
  98. package/src/cli/cmd/run/entry.body.ts +0 -205
  99. package/src/cli/cmd/run/footer.command.tsx +0 -1070
  100. package/src/cli/cmd/run/footer.menu.tsx +0 -351
  101. package/src/cli/cmd/run/footer.permission.tsx +0 -472
  102. package/src/cli/cmd/run/footer.prompt.tsx +0 -1315
  103. package/src/cli/cmd/run/footer.question.tsx +0 -573
  104. package/src/cli/cmd/run/footer.subagent.tsx +0 -175
  105. package/src/cli/cmd/run/footer.ts +0 -1129
  106. package/src/cli/cmd/run/footer.view.tsx +0 -945
  107. package/src/cli/cmd/run/footer.width.ts +0 -27
  108. package/src/cli/cmd/run/permission.shared.ts +0 -256
  109. package/src/cli/cmd/run/prompt.editor.ts +0 -157
  110. package/src/cli/cmd/run/prompt.shared.ts +0 -153
  111. package/src/cli/cmd/run/question.shared.ts +0 -340
  112. package/src/cli/cmd/run/runtime.boot.ts +0 -202
  113. package/src/cli/cmd/run/runtime.lifecycle.ts +0 -410
  114. package/src/cli/cmd/run/runtime.queue.ts +0 -349
  115. package/src/cli/cmd/run/runtime.shared.ts +0 -17
  116. package/src/cli/cmd/run/runtime.stdin.ts +0 -37
  117. package/src/cli/cmd/run/runtime.ts +0 -821
  118. package/src/cli/cmd/run/scrollback.shared.ts +0 -92
  119. package/src/cli/cmd/run/scrollback.surface.ts +0 -431
  120. package/src/cli/cmd/run/scrollback.writer.tsx +0 -352
  121. package/src/cli/cmd/run/session-data.ts +0 -1113
  122. package/src/cli/cmd/run/session-replay.ts +0 -374
  123. package/src/cli/cmd/run/session.shared.ts +0 -196
  124. package/src/cli/cmd/run/splash.ts +0 -289
  125. package/src/cli/cmd/run/stream.transport.ts +0 -1462
  126. package/src/cli/cmd/run/stream.ts +0 -175
  127. package/src/cli/cmd/run/subagent-data.ts +0 -876
  128. package/src/cli/cmd/run/theme.ts +0 -690
  129. package/src/cli/cmd/run/tool.ts +0 -1486
  130. package/src/cli/cmd/run/trace.ts +0 -94
  131. package/src/cli/cmd/run/turn-summary.ts +0 -47
  132. package/src/cli/cmd/run/types.ts +0 -350
  133. package/src/cli/cmd/run/variant.shared.ts +0 -216
  134. package/src/cli/cmd/run.ts +0 -1011
  135. package/src/cli/cmd/serve.ts +0 -24
  136. package/src/cli/cmd/session.ts +0 -147
  137. package/src/cli/cmd/stats.ts +0 -393
  138. package/src/cli/cmd/tui.ts +0 -309
  139. package/src/cli/cmd/uninstall.ts +0 -353
  140. package/src/cli/cmd/upgrade.ts +0 -113
  141. package/src/cli/cmd/web.ts +0 -84
  142. package/src/cli/effect/prompt.ts +0 -37
  143. package/src/cli/effect-cmd.ts +0 -96
  144. package/src/cli/error.ts +0 -130
  145. package/src/cli/heap.ts +0 -45
  146. package/src/cli/logo.ts +0 -1
  147. package/src/cli/network.ts +0 -80
  148. package/src/cli/tui/layer.ts +0 -8
  149. package/src/cli/tui/validate-session.ts +0 -29
  150. package/src/cli/tui/worker.ts +0 -80
  151. package/src/cli/ui.ts +0 -146
  152. package/src/cli/upgrade.ts +0 -79
  153. package/src/cli/version.ts +0 -14
  154. package/src/command/index.ts +0 -177
  155. package/src/command/template/initialize.txt +0 -66
  156. package/src/command/template/review.txt +0 -101
  157. package/src/config/agent.ts +0 -59
  158. package/src/config/command.ts +0 -39
  159. package/src/config/config.ts +0 -689
  160. package/src/config/entry-name.ts +0 -19
  161. package/src/config/managed.ts +0 -69
  162. package/src/config/markdown.ts +0 -36
  163. package/src/config/parse.ts +0 -79
  164. package/src/config/paths.ts +0 -45
  165. package/src/config/plugin.ts +0 -79
  166. package/src/config/tui-cwd.ts +0 -5
  167. package/src/config/tui-host-attention.ts +0 -21
  168. package/src/config/tui-migrate.ts +0 -132
  169. package/src/config/tui.ts +0 -276
  170. package/src/config/variable.ts +0 -91
  171. package/src/control-plane/adapters/index.ts +0 -41
  172. package/src/control-plane/adapters/worktree.ts +0 -96
  173. package/src/control-plane/dev/README.md +0 -19
  174. package/src/control-plane/dev/debug-workspace-plugin.ts +0 -73
  175. package/src/control-plane/types.ts +0 -59
  176. package/src/control-plane/util.ts +0 -39
  177. package/src/control-plane/workspace-adapter-runtime.ts +0 -51
  178. package/src/control-plane/workspace-context.ts +0 -26
  179. package/src/control-plane/workspace.ts +0 -964
  180. package/src/effect/app-node-builder-v1.ts +0 -12
  181. package/src/effect/app-runtime.ts +0 -137
  182. package/src/effect/bootstrap-runtime.ts +0 -19
  183. package/src/effect/bridge.ts +0 -84
  184. package/src/effect/config-service.ts +0 -67
  185. package/src/effect/instance-ref.ts +0 -11
  186. package/src/effect/instance-registry.ts +0 -12
  187. package/src/effect/instance-state.ts +0 -69
  188. package/src/effect/promise.ts +0 -17
  189. package/src/effect/run-service.ts +0 -47
  190. package/src/effect/runner.ts +0 -217
  191. package/src/effect/runtime-flags.ts +0 -79
  192. package/src/env/index.ts +0 -41
  193. package/src/event-manifest.ts +0 -3
  194. package/src/event-v2-bridge.ts +0 -71
  195. package/src/format/formatter.ts +0 -404
  196. package/src/format/index.ts +0 -203
  197. package/src/git/index.ts +0 -348
  198. package/src/id/id.ts +0 -80
  199. package/src/ide/index.ts +0 -54
  200. package/src/image/image.ts +0 -172
  201. package/src/index.ts +0 -142
  202. package/src/installation/index.ts +0 -336
  203. package/src/lsp/client.ts +0 -650
  204. package/src/lsp/diagnostic.ts +0 -29
  205. package/src/lsp/language.ts +0 -121
  206. package/src/lsp/launch.ts +0 -21
  207. package/src/lsp/lsp.ts +0 -507
  208. package/src/lsp/server.ts +0 -1983
  209. package/src/markdown.d.ts +0 -4
  210. package/src/mcp/auth.ts +0 -163
  211. package/src/mcp/browser.ts +0 -37
  212. package/src/mcp/catalog.ts +0 -170
  213. package/src/mcp/index.ts +0 -1004
  214. package/src/mcp/oauth-callback.ts +0 -194
  215. package/src/mcp/oauth-provider.ts +0 -259
  216. package/src/memory/memory.ts +0 -133
  217. package/src/node.ts +0 -4
  218. package/src/patch/index.ts +0 -686
  219. package/src/permission/arity.ts +0 -163
  220. package/src/permission/evaluate.ts +0 -1
  221. package/src/permission/index.ts +0 -229
  222. package/src/plugin/azure.ts +0 -26
  223. package/src/plugin/cloudflare.ts +0 -76
  224. package/src/plugin/digitalocean.ts +0 -325
  225. package/src/plugin/github-copilot/copilot.ts +0 -414
  226. package/src/plugin/github-copilot/models.ts +0 -258
  227. package/src/plugin/index.ts +0 -311
  228. package/src/plugin/install.ts +0 -439
  229. package/src/plugin/loader.ts +0 -237
  230. package/src/plugin/meta.ts +0 -188
  231. package/src/plugin/openai/README.md +0 -31
  232. package/src/plugin/openai/codex.ts +0 -565
  233. package/src/plugin/openai/ws-pool.ts +0 -270
  234. package/src/plugin/openai/ws.ts +0 -381
  235. package/src/plugin/pty-environment.ts +0 -24
  236. package/src/plugin/shared.ts +0 -323
  237. package/src/plugin/snowflake-cortex.ts +0 -507
  238. package/src/plugin/tui/internal.ts +0 -10
  239. package/src/plugin/tui/runtime.ts +0 -1131
  240. package/src/plugin/xai.ts +0 -626
  241. package/src/project/bootstrap-service.ts +0 -9
  242. package/src/project/bootstrap.ts +0 -58
  243. package/src/project/instance-context.ts +0 -24
  244. package/src/project/instance-runtime.ts +0 -16
  245. package/src/project/instance-store.ts +0 -213
  246. package/src/project/project.ts +0 -483
  247. package/src/project/vcs.ts +0 -423
  248. package/src/provider/auth.ts +0 -229
  249. package/src/provider/error.ts +0 -188
  250. package/src/provider/model-status.ts +0 -8
  251. package/src/provider/provider.ts +0 -2006
  252. package/src/provider/transform.ts +0 -1832
  253. package/src/question/index.ts +0 -161
  254. package/src/question/schema.ts +0 -4
  255. package/src/server/auth.ts +0 -48
  256. package/src/server/event.ts +0 -10
  257. package/src/server/global-lifecycle.ts +0 -28
  258. package/src/server/init-projectors.ts +0 -3
  259. package/src/server/mdns.ts +0 -47
  260. package/src/server/projectors.ts +0 -1
  261. package/src/server/proxy-util.ts +0 -48
  262. package/src/server/routes/instance/httpapi/AGENTS.md +0 -39
  263. package/src/server/routes/instance/httpapi/api.ts +0 -97
  264. package/src/server/routes/instance/httpapi/errors.ts +0 -193
  265. package/src/server/routes/instance/httpapi/groups/config.ts +0 -65
  266. package/src/server/routes/instance/httpapi/groups/control-plane.ts +0 -35
  267. package/src/server/routes/instance/httpapi/groups/control.ts +0 -76
  268. package/src/server/routes/instance/httpapi/groups/event.ts +0 -29
  269. package/src/server/routes/instance/httpapi/groups/experimental.ts +0 -275
  270. package/src/server/routes/instance/httpapi/groups/file.ts +0 -185
  271. package/src/server/routes/instance/httpapi/groups/global.ts +0 -136
  272. package/src/server/routes/instance/httpapi/groups/instance.ts +0 -206
  273. package/src/server/routes/instance/httpapi/groups/mcp.ts +0 -156
  274. package/src/server/routes/instance/httpapi/groups/metadata.ts +0 -18
  275. package/src/server/routes/instance/httpapi/groups/permission.ts +0 -61
  276. package/src/server/routes/instance/httpapi/groups/project-copy.ts +0 -32
  277. package/src/server/routes/instance/httpapi/groups/project.ts +0 -93
  278. package/src/server/routes/instance/httpapi/groups/provider.ts +0 -101
  279. package/src/server/routes/instance/httpapi/groups/pty.ts +0 -172
  280. package/src/server/routes/instance/httpapi/groups/query.ts +0 -12
  281. package/src/server/routes/instance/httpapi/groups/question.ts +0 -74
  282. package/src/server/routes/instance/httpapi/groups/session.ts +0 -462
  283. package/src/server/routes/instance/httpapi/groups/sync.ts +0 -113
  284. package/src/server/routes/instance/httpapi/groups/tui.ts +0 -208
  285. package/src/server/routes/instance/httpapi/groups/workspace.ts +0 -141
  286. package/src/server/routes/instance/httpapi/handlers/config.ts +0 -34
  287. package/src/server/routes/instance/httpapi/handlers/control-plane.ts +0 -37
  288. package/src/server/routes/instance/httpapi/handlers/control.ts +0 -43
  289. package/src/server/routes/instance/httpapi/handlers/event.ts +0 -99
  290. package/src/server/routes/instance/httpapi/handlers/experimental.ts +0 -193
  291. package/src/server/routes/instance/httpapi/handlers/file.ts +0 -139
  292. package/src/server/routes/instance/httpapi/handlers/global.ts +0 -156
  293. package/src/server/routes/instance/httpapi/handlers/instance.ts +0 -110
  294. package/src/server/routes/instance/httpapi/handlers/mcp.ts +0 -111
  295. package/src/server/routes/instance/httpapi/handlers/permission.ts +0 -41
  296. package/src/server/routes/instance/httpapi/handlers/project-copy.ts +0 -83
  297. package/src/server/routes/instance/httpapi/handlers/project.ts +0 -63
  298. package/src/server/routes/instance/httpapi/handlers/provider.ts +0 -113
  299. package/src/server/routes/instance/httpapi/handlers/pty.ts +0 -273
  300. package/src/server/routes/instance/httpapi/handlers/question.ts +0 -54
  301. package/src/server/routes/instance/httpapi/handlers/session-errors.ts +0 -21
  302. package/src/server/routes/instance/httpapi/handlers/session.ts +0 -442
  303. package/src/server/routes/instance/httpapi/handlers/sync.ts +0 -89
  304. package/src/server/routes/instance/httpapi/handlers/tui.ts +0 -131
  305. package/src/server/routes/instance/httpapi/handlers/workspace.ts +0 -102
  306. package/src/server/routes/instance/httpapi/lifecycle.ts +0 -54
  307. package/src/server/routes/instance/httpapi/middleware/authorization.ts +0 -150
  308. package/src/server/routes/instance/httpapi/middleware/compression.ts +0 -64
  309. package/src/server/routes/instance/httpapi/middleware/cors-vary.ts +0 -29
  310. package/src/server/routes/instance/httpapi/middleware/error.ts +0 -43
  311. package/src/server/routes/instance/httpapi/middleware/fence.ts +0 -25
  312. package/src/server/routes/instance/httpapi/middleware/instance-context.ts +0 -43
  313. package/src/server/routes/instance/httpapi/middleware/proxy.ts +0 -108
  314. package/src/server/routes/instance/httpapi/middleware/schema-error.ts +0 -41
  315. package/src/server/routes/instance/httpapi/middleware/workspace-routing.ts +0 -250
  316. package/src/server/routes/instance/httpapi/public.ts +0 -537
  317. package/src/server/routes/instance/httpapi/server.ts +0 -327
  318. package/src/server/routes/instance/httpapi/websocket-tracker.ts +0 -60
  319. package/src/server/server.ts +0 -226
  320. package/src/server/shared/fence.ts +0 -60
  321. package/src/server/shared/pty-ticket.ts +0 -15
  322. package/src/server/shared/public-ui.ts +0 -12
  323. package/src/server/shared/tui-control.ts +0 -28
  324. package/src/server/shared/ui.ts +0 -108
  325. package/src/server/shared/workspace-routing.ts +0 -38
  326. package/src/server/tui-event.ts +0 -1
  327. package/src/session/compaction.ts +0 -562
  328. package/src/session/instruction.ts +0 -237
  329. package/src/session/llm/AGENTS.md +0 -90
  330. package/src/session/llm/ai-sdk.ts +0 -288
  331. package/src/session/llm/native-request.ts +0 -196
  332. package/src/session/llm/native-runtime.ts +0 -195
  333. package/src/session/llm/request.ts +0 -226
  334. package/src/session/llm.ts +0 -404
  335. package/src/session/message-error.ts +0 -14
  336. package/src/session/message-v2.ts +0 -734
  337. package/src/session/message.ts +0 -148
  338. package/src/session/overflow.ts +0 -34
  339. package/src/session/processor.ts +0 -718
  340. package/src/session/prompt/anthropic.txt +0 -96
  341. package/src/session/prompt/beast.txt +0 -147
  342. package/src/session/prompt/build-switch.txt +0 -5
  343. package/src/session/prompt/codex.txt +0 -79
  344. package/src/session/prompt/copilot-gpt-5.txt +0 -143
  345. package/src/session/prompt/default.txt +0 -89
  346. package/src/session/prompt/gemini.txt +0 -155
  347. package/src/session/prompt/gpt.txt +0 -107
  348. package/src/session/prompt/kimi.txt +0 -95
  349. package/src/session/prompt/meta.txt +0 -64
  350. package/src/session/prompt/plan-mode.txt +0 -70
  351. package/src/session/prompt/plan-reminder-anthropic.txt +0 -67
  352. package/src/session/prompt/plan.txt +0 -26
  353. package/src/session/prompt/trinity.txt +0 -97
  354. package/src/session/prompt.ts +0 -1636
  355. package/src/session/reminders.ts +0 -92
  356. package/src/session/retry.ts +0 -201
  357. package/src/session/revert.ts +0 -146
  358. package/src/session/run-state.ts +0 -151
  359. package/src/session/schema.ts +0 -26
  360. package/src/session/session.ts +0 -1018
  361. package/src/session/status.ts +0 -56
  362. package/src/session/summary.ts +0 -160
  363. package/src/session/system.ts +0 -145
  364. package/src/session/todo.ts +0 -74
  365. package/src/session/tools.ts +0 -590
  366. package/src/share/session.ts +0 -58
  367. package/src/share/share-next.ts +0 -371
  368. package/src/skill/discovery.ts +0 -140
  369. package/src/skill/index.ts +0 -354
  370. package/src/snapshot/index.ts +0 -807
  371. package/src/sql.d.ts +0 -4
  372. package/src/storage/schema.ts +0 -5
  373. package/src/storage/storage.ts +0 -327
  374. package/src/sync/README.md +0 -179
  375. package/src/sync/schema.ts +0 -11
  376. package/src/temporary.ts +0 -31
  377. package/src/tool/apply_patch.ts +0 -313
  378. package/src/tool/apply_patch.txt +0 -33
  379. package/src/tool/code-mode.ts +0 -310
  380. package/src/tool/computer.ts +0 -476
  381. package/src/tool/computer.txt +0 -25
  382. package/src/tool/edit.ts +0 -737
  383. package/src/tool/edit.txt +0 -10
  384. package/src/tool/external-directory.ts +0 -49
  385. package/src/tool/glob.ts +0 -76
  386. package/src/tool/glob.txt +0 -6
  387. package/src/tool/grep.ts +0 -115
  388. package/src/tool/grep.txt +0 -8
  389. package/src/tool/invalid.ts +0 -21
  390. package/src/tool/json-schema.ts +0 -164
  391. package/src/tool/lsp.ts +0 -113
  392. package/src/tool/lsp.txt +0 -24
  393. package/src/tool/mcp-websearch.ts +0 -96
  394. package/src/tool/memory.ts +0 -59
  395. package/src/tool/memory.txt +0 -14
  396. package/src/tool/plan-enter.txt +0 -14
  397. package/src/tool/plan-exit.txt +0 -13
  398. package/src/tool/plan.ts +0 -79
  399. package/src/tool/question.ts +0 -44
  400. package/src/tool/question.txt +0 -10
  401. package/src/tool/read.ts +0 -386
  402. package/src/tool/read.txt +0 -14
  403. package/src/tool/registry.ts +0 -460
  404. package/src/tool/schema.ts +0 -14
  405. package/src/tool/shell/id.ts +0 -19
  406. package/src/tool/shell/prompt.ts +0 -293
  407. package/src/tool/shell/shell.txt +0 -21
  408. package/src/tool/shell.ts +0 -645
  409. package/src/tool/skill.ts +0 -70
  410. package/src/tool/skill.txt +0 -5
  411. package/src/tool/task.ts +0 -360
  412. package/src/tool/task.txt +0 -19
  413. package/src/tool/todo.ts +0 -46
  414. package/src/tool/todowrite.txt +0 -44
  415. package/src/tool/tool.ts +0 -183
  416. package/src/tool/truncate.ts +0 -156
  417. package/src/tool/truncation-dir.ts +0 -4
  418. package/src/tool/webfetch.ts +0 -192
  419. package/src/tool/webfetch.txt +0 -13
  420. package/src/tool/websearch.ts +0 -143
  421. package/src/tool/websearch.txt +0 -14
  422. package/src/tool/write.ts +0 -104
  423. package/src/tool/write.txt +0 -8
  424. package/src/util/archive.ts +0 -17
  425. package/src/util/bom.ts +0 -27
  426. package/src/util/data-url.ts +0 -9
  427. package/src/util/defer.ts +0 -10
  428. package/src/util/effect-http-client.ts +0 -11
  429. package/src/util/error.ts +0 -1
  430. package/src/util/filesystem.ts +0 -251
  431. package/src/util/html.ts +0 -8
  432. package/src/util/iife.ts +0 -3
  433. package/src/util/lazy.ts +0 -20
  434. package/src/util/local-context.ts +0 -25
  435. package/src/util/locale.ts +0 -2
  436. package/src/util/media.ts +0 -26
  437. package/src/util/process.ts +0 -177
  438. package/src/util/proxy-env.ts +0 -72
  439. package/src/util/queue.ts +0 -32
  440. package/src/util/record.ts +0 -1
  441. package/src/util/repository.ts +0 -232
  442. package/src/util/rpc.ts +0 -66
  443. package/src/util/signal.ts +0 -12
  444. package/src/util/timeout.ts +0 -13
  445. package/src/util/token.ts +0 -1
  446. package/src/util/wildcard.ts +0 -59
  447. package/src/worktree/index.ts +0 -623
  448. package/tsconfig.json +0 -17
@@ -1,1832 +0,0 @@
1
- import type { ModelMessage, ToolResultPart } from "ai"
2
- import { mergeDeep, unique } from "remeda"
3
- import type { JSONSchema7 } from "@ai-sdk/provider"
4
- import type * as Provider from "./provider"
5
- import type * as ModelsDev from "@anymous-ai/core/models-dev"
6
- import { iife } from "@/util/iife"
7
-
8
- type Modality = NonNullable<ModelsDev.Model["modalities"]>["input"][number]
9
-
10
- function mimeToModality(mime: string): Modality | undefined {
11
- if (mime.startsWith("image/")) return "image"
12
- if (mime.startsWith("audio/")) return "audio"
13
- if (mime.startsWith("video/")) return "video"
14
- if (mime === "application/pdf") return "pdf"
15
- return undefined
16
- }
17
-
18
- export const OUTPUT_TOKEN_MAX = 32_000
19
-
20
- // OpenAI Responses `include` value that returns the encrypted reasoning state
21
- // needed for stateless multi-turn reasoning (store: false). Hoisted so every
22
- // branch that requests it stays in lockstep.
23
- const INCLUDE_ENCRYPTED_REASONING = ["reasoning.encrypted_content"] as const
24
-
25
- export function sanitizeSurrogates(content: string) {
26
- return content.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD")
27
- }
28
-
29
- function isKimiFamily(model: Provider.Model) {
30
- if (
31
- [model.providerID, model.api.id].some((id) => {
32
- const value = id.toLowerCase()
33
- return value.includes("kimi") || value.includes("moonshot")
34
- })
35
- )
36
- return true
37
- const url = model.api.url.toLowerCase()
38
- return ["api.kimi.com", "api.moonshot.ai", "api.moonshot.cn", "api.moonshotai.cn"].some((host) => url.includes(host))
39
- }
40
-
41
- // Maps npm package to the key the AI SDK expects for providerOptions
42
- function sdkKey(npm: string): string | undefined {
43
- switch (npm) {
44
- case "@ai-sdk/github-copilot":
45
- return "copilot"
46
- case "@ai-sdk/azure":
47
- return "azure"
48
- case "@ai-sdk/openai":
49
- return "openai"
50
- case "@ai-sdk/amazon-bedrock/mantle":
51
- return "openai"
52
- case "@ai-sdk/amazon-bedrock":
53
- return "bedrock"
54
- case "@ai-sdk/anthropic":
55
- case "@ai-sdk/google-vertex/anthropic":
56
- return "anthropic"
57
- case "@ai-sdk/google-vertex":
58
- return "vertex"
59
- case "@ai-sdk/google":
60
- return "google"
61
- case "@ai-sdk/alibaba":
62
- return "alibaba"
63
- case "@ai-sdk/cerebras":
64
- return "cerebras"
65
- case "@ai-sdk/cohere":
66
- return "cohere"
67
- case "@ai-sdk/deepinfra":
68
- return "deepinfra"
69
- case "@ai-sdk/groq":
70
- return "groq"
71
- case "@ai-sdk/mistral":
72
- return "mistral"
73
- case "@ai-sdk/perplexity":
74
- return "perplexity"
75
- case "@ai-sdk/togetherai":
76
- return "togetherai"
77
- case "@ai-sdk/vercel":
78
- return "vercel"
79
- case "@ai-sdk/xai":
80
- return "xai"
81
- case "venice-ai-sdk-provider":
82
- return "venice"
83
- case "@ai-sdk/gateway":
84
- return "gateway"
85
- case "@openrouter/ai-sdk-provider":
86
- return "openrouter"
87
- case "ai-gateway-provider":
88
- // ai-gateway-provider/unified wraps createOpenAICompatible({ name: "Unified" }),
89
- // and @ai-sdk/openai-compatible parses compatibleOptions from one of
90
- // "openai-compatible" / "openaiCompatible" / "Unified" / "unified". The
91
- // "openai-compatible" key emits a deprecation warning at runtime, so we
92
- // pick the camelCase form the SDK now treats as canonical.
93
- return "openaiCompatible"
94
- }
95
- return undefined
96
- }
97
-
98
- // TODO: optimize this function - currently iterates multiple times over messages
99
- function normalizeMessages(
100
- msgs: ModelMessage[],
101
- model: Provider.Model,
102
- _options: Record<string, unknown>,
103
- ): ModelMessage[] {
104
- const sanitizeToolResultOutput = (content: ToolResultPart) => {
105
- if (content.output.type === "text" || content.output.type === "error-text") {
106
- content.output.value = sanitizeSurrogates(content.output.value)
107
- }
108
- if (content.output.type === "content") {
109
- content.output.value = content.output.value.map((item) => {
110
- if (item.type === "text") {
111
- item.text = sanitizeSurrogates(item.text)
112
- }
113
- return item
114
- })
115
- }
116
- return content
117
- }
118
-
119
- msgs = msgs.map((msg) => {
120
- switch (msg.role) {
121
- case "tool":
122
- if (!Array.isArray(msg.content)) return msg
123
- msg.content = msg.content.map((content) => {
124
- if (content.type === "tool-result") {
125
- return sanitizeToolResultOutput(content)
126
- }
127
- return content
128
- })
129
- return msg
130
-
131
- case "system":
132
- msg.content = sanitizeSurrogates(msg.content)
133
- return msg
134
-
135
- case "user":
136
- if (typeof msg.content === "string") {
137
- msg.content = sanitizeSurrogates(msg.content)
138
- } else {
139
- msg.content = msg.content.map((content) => {
140
- if (content.type === "text") {
141
- content.text = sanitizeSurrogates(content.text)
142
- }
143
- return content
144
- })
145
- }
146
- return msg
147
-
148
- case "assistant":
149
- if (typeof msg.content === "string") {
150
- msg.content = sanitizeSurrogates(msg.content)
151
- } else {
152
- msg.content = msg.content.map((content) => {
153
- if (content.type === "text" || content.type === "reasoning") {
154
- content.text = sanitizeSurrogates(content.text)
155
- }
156
- if (content.type === "tool-result") {
157
- return sanitizeToolResultOutput(content)
158
- }
159
- return content
160
- })
161
- }
162
- return msg
163
- }
164
- })
165
-
166
- // Anthropic rejects messages with empty content - filter out empty string messages
167
- // and remove empty text/reasoning parts from array content
168
- if (model.api.npm === "@ai-sdk/anthropic") {
169
- msgs = msgs
170
- .map((msg) => {
171
- if (typeof msg.content === "string") {
172
- if (msg.content === "") return undefined
173
- return msg
174
- }
175
- if (!Array.isArray(msg.content)) return msg
176
- const filtered = msg.content.filter((part) => {
177
- if (part.type === "text") {
178
- return part.text !== ""
179
- }
180
- if (part.type === "reasoning") {
181
- return (
182
- part.text.trim().length > 0 ||
183
- part.providerOptions?.anthropic?.signature != null ||
184
- part.providerOptions?.anthropic?.redactedData != null
185
- )
186
- }
187
- return true
188
- })
189
- if (filtered.length === 0) return undefined
190
- return { ...msg, content: filtered }
191
- })
192
- .filter((msg): msg is ModelMessage => msg !== undefined && msg.content !== "")
193
- }
194
-
195
- // Bedrock specific transforms
196
- if (model.api.npm === "@ai-sdk/amazon-bedrock") {
197
- msgs = msgs
198
- .map((msg) => {
199
- if (typeof msg.content === "string") {
200
- if (msg.content === "") return undefined
201
- return msg
202
- }
203
- if (!Array.isArray(msg.content)) return msg
204
- const filtered = msg.content.filter((part) => {
205
- if (part.type === "text") {
206
- return part.text !== ""
207
- }
208
- if (part.type === "reasoning") {
209
- return (
210
- part.text.trim().length > 0 ||
211
- part.providerOptions?.bedrock?.signature != null ||
212
- part.providerOptions?.bedrock?.redactedData != null
213
- )
214
- }
215
- return true
216
- })
217
- if (filtered.length === 0) return undefined
218
- return { ...msg, content: filtered }
219
- })
220
- .filter((msg): msg is ModelMessage => msg !== undefined && msg.content !== "")
221
- }
222
-
223
- if (model.api.id.includes("claude")) {
224
- const scrub = (id: string) => id.replace(/[^a-zA-Z0-9_-]/g, "_")
225
- msgs = msgs.map((msg) => {
226
- if (msg.role === "assistant" && Array.isArray(msg.content)) {
227
- return {
228
- ...msg,
229
- content: msg.content.map((part) => {
230
- if (part.type === "tool-call" || part.type === "tool-result") {
231
- return { ...part, toolCallId: scrub(part.toolCallId) }
232
- }
233
- return part
234
- }),
235
- }
236
- }
237
- if (msg.role === "tool" && Array.isArray(msg.content)) {
238
- return {
239
- ...msg,
240
- content: msg.content.map((part) => {
241
- if (part.type === "tool-result") {
242
- return { ...part, toolCallId: scrub(part.toolCallId) }
243
- }
244
- return part
245
- }),
246
- }
247
- }
248
- return msg
249
- })
250
- }
251
-
252
- const modelID = model.api.id.toLowerCase()
253
- if (
254
- model.providerID === "mistral" ||
255
- ["mistral", "devstral", "codestral", "pixtral", "mixtral"].some((family) => modelID.includes(family))
256
- ) {
257
- const scrub = (id: string) => {
258
- return id
259
- .replace(/[^a-zA-Z0-9]/g, "") // Remove non-alphanumeric characters
260
- .substring(0, 9) // Take first 9 characters
261
- .padEnd(9, "0") // Pad with zeros if less than 9 characters
262
- }
263
- const result: ModelMessage[] = []
264
- for (let i = 0; i < msgs.length; i++) {
265
- const msg = msgs[i]
266
- const nextMsg = msgs[i + 1]
267
-
268
- if (msg.role === "assistant" && Array.isArray(msg.content)) {
269
- msg.content = msg.content.map((part) => {
270
- if (part.type === "tool-call" || part.type === "tool-result") {
271
- return { ...part, toolCallId: scrub(part.toolCallId) }
272
- }
273
- return part
274
- })
275
- }
276
- if (msg.role === "tool" && Array.isArray(msg.content)) {
277
- msg.content = msg.content.map((part) => {
278
- if (part.type === "tool-result") {
279
- return { ...part, toolCallId: scrub(part.toolCallId) }
280
- }
281
- return part
282
- })
283
- }
284
- result.push(msg)
285
-
286
- // Fix message sequence: tool messages cannot be followed by user messages
287
- if (msg.role === "tool" && nextMsg?.role === "user") {
288
- result.push({
289
- role: "assistant",
290
- content: [
291
- {
292
- type: "text",
293
- text: "Done.",
294
- },
295
- ],
296
- })
297
- }
298
- }
299
- return result
300
- }
301
-
302
- // Deepseek requires all assistant messages to have reasoning on them
303
- if (model.api.id.toLowerCase().includes("deepseek")) {
304
- msgs = msgs.map((msg) => {
305
- if (msg.role !== "assistant") return msg
306
- if (Array.isArray(msg.content)) {
307
- if (msg.content.some((part) => part.type === "reasoning")) return msg
308
- return { ...msg, content: [...msg.content, { type: "reasoning", text: "" }] }
309
- }
310
- return {
311
- ...msg,
312
- content: [
313
- ...(msg.content ? [{ type: "text" as const, text: msg.content }] : []),
314
- { type: "reasoning" as const, text: "" },
315
- ],
316
- }
317
- })
318
- }
319
-
320
- if (
321
- typeof model.capabilities.interleaved === "object" &&
322
- model.capabilities.interleaved.field &&
323
- model.api.npm !== "@openrouter/ai-sdk-provider"
324
- ) {
325
- const field = model.capabilities.interleaved.field
326
- return msgs.map((msg) => {
327
- if (msg.role === "assistant" && Array.isArray(msg.content)) {
328
- const reasoningParts = msg.content.filter((part: any) => part.type === "reasoning")
329
- const reasoningText = reasoningParts.map((part: any) => part.text).join("")
330
-
331
- // Filter out reasoning parts from content
332
- const filteredContent = msg.content.filter((part: any) => part.type !== "reasoning")
333
-
334
- // Include reasoning_content | reasoning_details directly on the message for all assistant messages.
335
- // Always set the field even when empty — some providers (e.g. DeepSeek) may return empty
336
- // reasoning_content which still needs to be sent back in subsequent requests.
337
- return {
338
- ...msg,
339
- content: filteredContent,
340
- providerOptions: {
341
- ...msg.providerOptions,
342
- openaiCompatible: {
343
- ...msg.providerOptions?.openaiCompatible,
344
- [field]: reasoningText,
345
- },
346
- },
347
- }
348
- }
349
-
350
- return msg
351
- })
352
- }
353
-
354
- return msgs
355
- }
356
-
357
- function applyCaching(msgs: ModelMessage[], model: Provider.Model): ModelMessage[] {
358
- const system = msgs.filter((msg) => msg.role === "system").slice(0, 2)
359
- const final = msgs.filter((msg) => msg.role !== "system").slice(-2)
360
-
361
- const providerOptions = {
362
- anthropic: {
363
- cacheControl: { type: "ephemeral" },
364
- },
365
- openrouter: {
366
- cacheControl: { type: "ephemeral" },
367
- },
368
- bedrock: {
369
- cachePoint: { type: "default" },
370
- },
371
- openaiCompatible: {
372
- cache_control: { type: "ephemeral" },
373
- },
374
- copilot: {
375
- copilot_cache_control: { type: "ephemeral" },
376
- },
377
- alibaba: {
378
- cacheControl: { type: "ephemeral" },
379
- },
380
- }
381
-
382
- for (const msg of unique([...system, ...final])) {
383
- const useMessageLevelOptions =
384
- model.providerID === "anthropic" ||
385
- model.providerID.includes("bedrock") ||
386
- model.api.npm === "@ai-sdk/amazon-bedrock"
387
- const shouldUseContentOptions = !useMessageLevelOptions && Array.isArray(msg.content) && msg.content.length > 0
388
-
389
- if (shouldUseContentOptions) {
390
- const lastContent = msg.content[msg.content.length - 1]
391
- if (
392
- lastContent &&
393
- typeof lastContent === "object" &&
394
- lastContent.type !== "tool-approval-request" &&
395
- lastContent.type !== "tool-approval-response"
396
- ) {
397
- lastContent.providerOptions = mergeDeep(lastContent.providerOptions ?? {}, providerOptions)
398
- continue
399
- }
400
- }
401
-
402
- msg.providerOptions = mergeDeep(msg.providerOptions ?? {}, providerOptions)
403
- }
404
-
405
- return msgs
406
- }
407
-
408
- function unsupportedParts(msgs: ModelMessage[], model: Provider.Model): ModelMessage[] {
409
- return msgs.map((msg) => {
410
- if (msg.role !== "user" || !Array.isArray(msg.content)) return msg
411
-
412
- const filtered = msg.content.map((part) => {
413
- if (part.type !== "file" && part.type !== "image") return part
414
-
415
- // Check for empty base64 image data
416
- if (part.type === "image") {
417
- const imageStr = String(part.image)
418
- if (imageStr.startsWith("data:")) {
419
- const match = imageStr.match(/^data:([^;]+);base64,(.*)$/)
420
- if (match && (!match[2] || match[2].length === 0)) {
421
- return {
422
- type: "text" as const,
423
- text: "ERROR: Image file is empty or corrupted. Please provide a valid image.",
424
- }
425
- }
426
- }
427
- }
428
-
429
- const mime = part.type === "image" ? String(part.image).split(";")[0].replace("data:", "") : part.mediaType
430
- const filename = part.type === "file" ? part.filename : undefined
431
- const modality = mimeToModality(mime)
432
- if (!modality) return part
433
- if (model.capabilities.input[modality]) return part
434
-
435
- const name = filename ? `"${filename}"` : modality
436
- return {
437
- type: "text" as const,
438
- text: `ERROR: Cannot read ${name} (this model does not support ${modality} input). Inform the user.`,
439
- }
440
- })
441
-
442
- return { ...msg, content: filtered }
443
- })
444
- }
445
-
446
- function mapProviderOptions(
447
- msgs: ModelMessage[],
448
- transform: (options: Record<string, any> | undefined) => Record<string, any> | undefined,
449
- ) {
450
- return msgs.map((msg) => {
451
- if (!Array.isArray(msg.content)) return { ...msg, providerOptions: transform(msg.providerOptions) }
452
- return {
453
- ...msg,
454
- providerOptions: transform(msg.providerOptions),
455
- content: msg.content.map((part) =>
456
- part.type === "tool-approval-request" || part.type === "tool-approval-response"
457
- ? part
458
- : { ...part, providerOptions: transform(part.providerOptions) },
459
- ),
460
- } as typeof msg
461
- })
462
- }
463
-
464
- export function message(msgs: ModelMessage[], model: Provider.Model, options: Record<string, unknown>) {
465
- msgs = unsupportedParts(msgs, model)
466
- msgs = normalizeMessages(msgs, model, options)
467
- const usesAnthropicAutomaticCaching =
468
- options.cacheControl !== undefined &&
469
- (model.api.npm === "@ai-sdk/anthropic" || model.api.npm === "@ai-sdk/google-vertex/anthropic")
470
- if (
471
- (model.providerID === "anthropic" ||
472
- model.providerID === "google-vertex-anthropic" ||
473
- model.api.id.includes("anthropic") ||
474
- model.api.id.includes("claude") ||
475
- model.id.includes("anthropic") ||
476
- model.id.includes("claude") ||
477
- model.api.npm === "@ai-sdk/anthropic" ||
478
- model.api.npm === "@ai-sdk/alibaba") &&
479
- model.api.npm !== "@ai-sdk/gateway" &&
480
- !usesAnthropicAutomaticCaching
481
- ) {
482
- msgs = applyCaching(msgs, model)
483
- }
484
-
485
- // Remap providerOptions keys from stored providerID to expected SDK key
486
- const key = sdkKey(model.api.npm)
487
- if (key && key !== model.providerID) {
488
- const remap = (opts: Record<string, any> | undefined) => {
489
- if (!opts) return opts
490
- if (!(model.providerID in opts)) return opts
491
- const result = { ...opts }
492
- result[key] = result[model.providerID]
493
- delete result[model.providerID]
494
- return result
495
- }
496
-
497
- msgs = mapProviderOptions(msgs, remap)
498
- }
499
-
500
- // Strip Responses item IDs before serialization, following Codex and keeping signed request bodies immutable.
501
- if (
502
- options.store !== true &&
503
- key &&
504
- ["@ai-sdk/openai", "@ai-sdk/azure", "@ai-sdk/amazon-bedrock/mantle", "@ai-sdk/github-copilot"].includes(
505
- model.api.npm,
506
- )
507
- ) {
508
- msgs = mapProviderOptions(msgs, (options) => {
509
- if (!options?.[key] || !("itemId" in options[key])) return options
510
- const metadata = { ...options[key] }
511
- delete metadata.itemId
512
- return { ...options, [key]: metadata }
513
- })
514
- }
515
-
516
- return msgs
517
- }
518
-
519
- export function temperature(model: Provider.Model) {
520
- const id = model.id.toLowerCase()
521
- if (id.includes("north-mini-code")) return 1.0
522
- if (id.includes("qwen")) return 0.55
523
- if (id.includes("claude")) return undefined
524
- if (id.includes("gemini")) return 1.0
525
- if (id.includes("glm-4.6")) return 1.0
526
- if (id.includes("glm-4.7")) return 1.0
527
- if (id.includes("minimax-m2")) return 1.0
528
- if (id.includes("kimi-k2")) {
529
- // kimi-k2-thinking & kimi-k2.5 && kimi-k2p5 && kimi-k2-5
530
- if (["thinking", "k2.", "k2p", "k2-5"].some((s) => id.includes(s))) {
531
- return 1.0
532
- }
533
- return 0.6
534
- }
535
- return undefined
536
- }
537
-
538
- export function topP(model: Provider.Model) {
539
- const id = model.id.toLowerCase()
540
- if (id.includes("qwen")) return 1
541
- if (["minimax-m2", "gemini", "kimi-k2.5", "kimi-k2p5", "kimi-k2-5"].some((s) => id.includes(s))) {
542
- return 0.95
543
- }
544
- return undefined
545
- }
546
-
547
- export function topK(model: Provider.Model) {
548
- const id = model.id.toLowerCase()
549
- if (id.includes("minimax-m2")) {
550
- if (["m2.", "m25", "m21"].some((s) => id.includes(s))) return 40
551
- return 20
552
- }
553
- if (id.includes("gemini")) return 64
554
- return undefined
555
- }
556
-
557
- const WIDELY_SUPPORTED_EFFORTS = ["low", "medium", "high"]
558
- const OPENAI_EFFORTS = ["none", "minimal", ...WIDELY_SUPPORTED_EFFORTS, "xhigh"]
559
- const OPENAI_GPT5_1_EFFORTS = ["none", ...WIDELY_SUPPORTED_EFFORTS]
560
- const OPENAI_GPT5_2_PLUS_EFFORTS = [...OPENAI_GPT5_1_EFFORTS, "xhigh"]
561
- const OPENAI_GPT5_PRO_EFFORTS = ["high"]
562
- const OPENAI_GPT5_PRO_2_PLUS_EFFORTS = ["medium", "high", "xhigh"]
563
- const OPENAI_GPT5_CHAT_EFFORTS = ["medium"]
564
- const OPENAI_GPT5_CODEX_XHIGH_EFFORTS = [...WIDELY_SUPPORTED_EFFORTS, "xhigh"]
565
- const OPENAI_GPT5_CODEX_3_PLUS_EFFORTS = ["none", ...OPENAI_GPT5_CODEX_XHIGH_EFFORTS]
566
-
567
- // OpenAI rolled out the `none` reasoning_effort tier on this date (Responses API).
568
- // Models released before it 400 on `reasoning_effort: "none"`, so we only expose
569
- // it as a variant for models new enough to accept it.
570
- const OPENAI_NONE_EFFORT_RELEASE_DATE = "2025-11-13"
571
-
572
- // OpenAI rolled out the `xhigh` reasoning_effort tier on this date. Same reasoning.
573
- const OPENAI_XHIGH_EFFORT_RELEASE_DATE = "2025-12-04"
574
-
575
- // Matches members of the gpt-5 family across the id formats we encounter:
576
- // "gpt-5", "gpt-5-nano", "gpt-5.4", "openai/gpt-5.4-codex".
577
- // Anchored to start-of-string or "/" so it doesn't false-match "gpt-50" or "gpt-5o".
578
- const GPT5_FAMILY_RE = /(?:^|\/)gpt-5(?:[.-]|$)/
579
- const GPT5_VERSION_RE = /(?:^|\/)gpt-5[.-](\d+)(?:[.-]|$)/
580
- const GPT5_PRO_RE = /(?:^|\/)gpt-5[.-]?pro(?:[.-]|$)/
581
- const GPT5_VERSIONED_PRO_RE = /(?:^|\/)gpt-5[.-]\d+[.-]pro(?:[.-]|$)/
582
-
583
- function gpt5Version(apiId: string) {
584
- return Number(GPT5_VERSION_RE.exec(apiId)?.[1]) || undefined
585
- }
586
-
587
- function versionedGpt5ReasoningEfforts(apiId: string) {
588
- if (GPT5_VERSIONED_PRO_RE.test(apiId)) return OPENAI_GPT5_PRO_2_PLUS_EFFORTS
589
- const version = gpt5Version(apiId)
590
- if (version === undefined) return undefined
591
- if (version === 1) return OPENAI_GPT5_1_EFFORTS
592
- return OPENAI_GPT5_2_PLUS_EFFORTS
593
- }
594
-
595
- function gpt5CodexReasoningEfforts(apiId: string) {
596
- if (!GPT5_FAMILY_RE.test(apiId) || !apiId.includes("codex")) return undefined
597
- const version = gpt5Version(apiId)
598
- if (version !== undefined && version >= 3) return OPENAI_GPT5_CODEX_3_PLUS_EFFORTS
599
- if (apiId.includes("codex-max") || (version !== undefined && version >= 2)) return OPENAI_GPT5_CODEX_XHIGH_EFFORTS
600
- return WIDELY_SUPPORTED_EFFORTS
601
- }
602
-
603
- function gpt5ChatReasoningEfforts(apiId: string) {
604
- if (!GPT5_FAMILY_RE.test(apiId) || !apiId.includes("-chat")) return undefined
605
- return gpt5Version(apiId) === undefined ? [] : OPENAI_GPT5_CHAT_EFFORTS
606
- }
607
-
608
- // Computes the reasoning_effort tiers an OpenAI (or OpenAI-compatible upstream
609
- // routed through it, e.g. cf-ai-gateway) model exposes. Effort order: weakest
610
- // to strongest.
611
- function openaiReasoningEfforts(apiId: string, releaseDate: string) {
612
- const id = apiId.toLowerCase()
613
- if (id.includes("deep-research")) return ["medium"]
614
- const chatEfforts = gpt5ChatReasoningEfforts(id)
615
- if (chatEfforts) return chatEfforts
616
- if (GPT5_PRO_RE.test(id)) return OPENAI_GPT5_PRO_EFFORTS
617
- const codexEfforts = gpt5CodexReasoningEfforts(id)
618
- if (codexEfforts) return codexEfforts
619
- const versionedEfforts = versionedGpt5ReasoningEfforts(id)
620
- // GPT-5.1 replaced GPT-5's `minimal` effort with `none`; GPT-5.2+
621
- // additionally accepts `xhigh`. Model pages list the supported subset.
622
- if (versionedEfforts) return versionedEfforts
623
- const efforts = [...WIDELY_SUPPORTED_EFFORTS]
624
- if (GPT5_FAMILY_RE.test(id)) efforts.unshift("minimal")
625
- if (releaseDate >= OPENAI_NONE_EFFORT_RELEASE_DATE) efforts.unshift("none")
626
- if (releaseDate >= OPENAI_XHIGH_EFFORT_RELEASE_DATE) efforts.push("xhigh")
627
- return efforts
628
- }
629
-
630
- function openaiCompatibleReasoningEfforts(id: string) {
631
- const apiId = id.toLowerCase()
632
- const chatEfforts = gpt5ChatReasoningEfforts(apiId)
633
- if (chatEfforts) return chatEfforts
634
- if (GPT5_PRO_RE.test(apiId)) return OPENAI_GPT5_PRO_EFFORTS
635
- return gpt5CodexReasoningEfforts(apiId) ?? versionedGpt5ReasoningEfforts(apiId) ?? OPENAI_EFFORTS
636
- }
637
-
638
- function anthropicUsesModernAdaptiveThinking(apiId: string) {
639
- if (!apiId.toLowerCase().includes("claude-")) return false
640
- // Covers family-first IDs such as claude-opus-4.7 and version-first IDs such as claude-4.7-opus.
641
- // Limit minors to two digits so release dates in IDs such as claude-opus-4-20250514 are not versions.
642
- const version = /claude-(?:[a-z]+-)?(\d+)(?:[.-](\d{1,2}))?(?:[.@-]|$)/i.exec(apiId)
643
- if (!version) return true
644
- const major = Number(version[1])
645
- const minor = Number(version[2] ?? 0)
646
- return major > 4 || (major === 4 && minor >= 7)
647
- }
648
-
649
- function anthropicOpus45(apiId: string) {
650
- return ["opus-4-5", "opus-4.5"].some((value) => apiId.includes(value))
651
- }
652
-
653
- function anthropicAdaptiveEfforts(apiId: string): string[] | null {
654
- if (anthropicUsesModernAdaptiveThinking(apiId)) {
655
- return ["low", "medium", "high", "xhigh", "max"]
656
- }
657
- if (
658
- ["opus-4-6", "opus-4.6", "4-6-opus", "4.6-opus", "sonnet-4-6", "sonnet-4.6", "4-6-sonnet", "4.6-sonnet"].some((v) =>
659
- apiId.includes(v),
660
- )
661
- ) {
662
- return ["low", "medium", "high", "max"]
663
- }
664
- return null
665
- }
666
-
667
- function anthropicOmitsThinking(apiId: string) {
668
- return anthropicUsesModernAdaptiveThinking(apiId)
669
- }
670
-
671
- function googleThinkingLevelEfforts(apiId: string) {
672
- const id = apiId.toLowerCase()
673
- if (!id.includes("gemini-3")) return ["low", "high"]
674
- if (id.includes("flash-image")) return ["minimal", "high"]
675
- if (id.includes("pro-image")) return ["high"]
676
- if (id.includes("flash")) return ["minimal", "low", "medium", "high"]
677
- return ["low", "medium", "high"]
678
- }
679
-
680
- function googleThinkingBudgetMax(apiId: string) {
681
- const id = apiId.toLowerCase()
682
- if (id.includes("2.5") && id.includes("pro") && !id.includes("flash")) return 32_768
683
- return 24_576
684
- }
685
-
686
- // SAP's Zod schema drops unknown top-level keys; reasoning controls survive
687
- // only via `modelParams` (catchall), forwarded verbatim by the SAP SDKs.
688
- function wrapInSapModelParams(variants: Record<string, Record<string, any>>): Record<string, Record<string, any>> {
689
- return Object.fromEntries(Object.entries(variants).map(([k, v]) => [k, { modelParams: v }]))
690
- }
691
-
692
- function googleThinkingVariants(model: Provider.Model): Record<string, Record<string, any>> {
693
- const id = model.api.id.toLowerCase()
694
- if (id.includes("2.5")) {
695
- return {
696
- high: { thinkingConfig: { includeThoughts: true, thinkingBudget: 16000 } },
697
- max: {
698
- thinkingConfig: { includeThoughts: true, thinkingBudget: googleThinkingBudgetMax(id) },
699
- },
700
- }
701
- }
702
- return Object.fromEntries(
703
- googleThinkingLevelEfforts(id).map((effort) => [
704
- effort,
705
- { thinkingConfig: { includeThoughts: true, thinkingLevel: effort } },
706
- ]),
707
- )
708
- }
709
-
710
- export function variants(model: Provider.Model): Record<string, Record<string, any>> {
711
- if (!model.capabilities.reasoning) return {}
712
-
713
- const id = model.id.toLowerCase()
714
- const glm52 = ["glm-5.2", "glm-5-2", "glm-5p2"].some(
715
- (name) => id.includes(name) || model.api.id.toLowerCase().includes(name),
716
- )
717
- if (
718
- model.api.id.toLowerCase().includes("minimax-m3") &&
719
- ["@ai-sdk/anthropic", "@ai-sdk/openai-compatible"].includes(model.api.npm)
720
- ) {
721
- if (["nvidia", "lilac"].includes(model.providerID)) {
722
- return {
723
- none: { chat_template_kwargs: { thinking_mode: "disabled" } },
724
- thinking: { chat_template_kwargs: { thinking_mode: "enabled" } },
725
- }
726
- }
727
- return {
728
- none: { thinking: { type: "disabled" } },
729
- thinking: { thinking: { type: "adaptive" } },
730
- }
731
- }
732
- const adaptiveThinkingOmitted = anthropicOmitsThinking(model.api.id)
733
- const adaptiveEfforts = anthropicAdaptiveEfforts(model.api.id)
734
- if (glm52 && model.api.npm === "@openrouter/ai-sdk-provider") {
735
- // OpenRouter maps xhigh to GLM-5.2's native max effort.
736
- return {
737
- high: { reasoning: { effort: "high" } },
738
- xhigh: { reasoning: { effort: "xhigh" } },
739
- }
740
- }
741
- if (glm52 && model.api.npm === "@ai-sdk/openai-compatible") {
742
- return {
743
- high: { reasoningEffort: "high" },
744
- max: { reasoningEffort: "max" },
745
- }
746
- }
747
- if (glm52 && model.api.npm === "@ai-sdk/anthropic") {
748
- return {
749
- high: { effort: "high" },
750
- max: { effort: "max" },
751
- }
752
- }
753
- // Kimi's Anthropic-compatible transports implement adaptive thinking effort.
754
- if (isKimiFamily(model) && ["@ai-sdk/anthropic", "@ai-sdk/google-vertex/anthropic"].includes(model.api.npm)) {
755
- return Object.fromEntries(
756
- ["low", "medium", "high", "xhigh", "max"].map((effort) => [
757
- effort,
758
- { thinking: { type: "adaptive", display: "summarized" }, effort },
759
- ]),
760
- )
761
- }
762
- if (
763
- id.includes("deepseek-chat") ||
764
- id.includes("deepseek-reasoner") ||
765
- id.includes("deepseek-r1") ||
766
- id.includes("deepseek-v3") ||
767
- id.includes("minimax") ||
768
- (id.includes("glm") && !glm52) ||
769
- id.includes("kimi") ||
770
- id.includes("k2p") ||
771
- id.includes("qwen") ||
772
- id.includes("big-pickle")
773
- )
774
- return {}
775
-
776
- // see: https://docs.x.ai/docs/guides/reasoning#control-how-hard-the-model-thinks
777
- if (id.includes("grok") && id.includes("grok-3-mini")) {
778
- if (model.api.npm === "@openrouter/ai-sdk-provider") {
779
- return {
780
- low: { reasoning: { effort: "low" } },
781
- high: { reasoning: { effort: "high" } },
782
- }
783
- }
784
- return {
785
- low: { reasoningEffort: "low" },
786
- high: { reasoningEffort: "high" },
787
- }
788
- }
789
-
790
- switch (model.api.npm) {
791
- case "@openrouter/ai-sdk-provider":
792
- return Object.fromEntries(
793
- (model.api.id.startsWith("openai/") || id.includes("gpt")
794
- ? openaiCompatibleReasoningEfforts(model.api.id)
795
- : WIDELY_SUPPORTED_EFFORTS
796
- ).map((effort) => [effort, { reasoning: { effort } }]),
797
- )
798
-
799
- case "ai-gateway-provider": {
800
- // Cloudflare AI Gateway routes every upstream through its OpenAI-compatible
801
- // /v1/compat endpoint, so the body is always OAI-shaped. The gateway
802
- // translates `reasoning_effort` to the upstream provider's native control
803
- // (e.g. Anthropic thinking budgets) when needed. Variants therefore stay
804
- // OAI-style for all upstreams, with an extended effort set for OpenAI
805
- // models that support it.
806
- if (model.api.id.startsWith("openai/")) {
807
- const efforts = openaiReasoningEfforts(model.api.id, model.release_date)
808
- return Object.fromEntries(efforts.map((effort) => [effort, { reasoningEffort: effort }]))
809
- }
810
- return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }]))
811
- }
812
-
813
- case "@ai-sdk/gateway":
814
- if (model.api.id.includes("anthropic")) {
815
- if (adaptiveEfforts) {
816
- return Object.fromEntries(
817
- adaptiveEfforts.map((effort) => [
818
- effort,
819
- {
820
- thinking: {
821
- type: "adaptive",
822
- // Newer adaptive-only models default `display` to "omitted", which
823
- // returns empty thinking blocks. Force "summarized" so summaries
824
- // survive (4.6/Sonnet 4.6 already default to "summarized").
825
- ...(adaptiveThinkingOmitted ? { display: "summarized" } : {}),
826
- },
827
- effort,
828
- },
829
- ]),
830
- )
831
- }
832
- return {
833
- high: {
834
- thinking: {
835
- type: "enabled",
836
- budgetTokens: 16000,
837
- },
838
- },
839
- max: {
840
- thinking: {
841
- type: "enabled",
842
- budgetTokens: 31999,
843
- },
844
- },
845
- }
846
- }
847
- if (model.api.id.includes("google")) {
848
- if (model.api.id.includes("2.5")) {
849
- return {
850
- high: {
851
- thinkingConfig: {
852
- includeThoughts: true,
853
- thinkingBudget: 16000,
854
- },
855
- },
856
- max: {
857
- thinkingConfig: {
858
- includeThoughts: true,
859
- thinkingBudget: googleThinkingBudgetMax(model.api.id.toLowerCase()),
860
- },
861
- },
862
- }
863
- }
864
- return Object.fromEntries(
865
- ["low", "high"].map((effort) => [
866
- effort,
867
- {
868
- includeThoughts: true,
869
- thinkingLevel: effort,
870
- },
871
- ]),
872
- )
873
- }
874
- return Object.fromEntries(
875
- openaiCompatibleReasoningEfforts(model.api.id).map((effort) => [effort, { reasoningEffort: effort }]),
876
- )
877
-
878
- case "@ai-sdk/github-copilot":
879
- if (model.id.includes("gemini")) {
880
- // currently github copilot only returns thinking
881
- return {}
882
- }
883
- if (model.id.includes("claude")) {
884
- return Object.fromEntries(WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, { reasoningEffort: effort }]))
885
- }
886
- const copilotEfforts = iife(() => {
887
- if (id.includes("5.1-codex-max") || id.includes("5.2") || id.includes("5.3"))
888
- return [...WIDELY_SUPPORTED_EFFORTS, "xhigh"]
889
- const arr = [...WIDELY_SUPPORTED_EFFORTS]
890
- if (id.includes("gpt-5") && model.release_date >= "2025-12-04") arr.push("xhigh")
891
- return arr
892
- })
893
- return Object.fromEntries(
894
- copilotEfforts.map((effort) => [
895
- effort,
896
- {
897
- reasoningEffort: effort,
898
- reasoningSummary: "auto",
899
- include: INCLUDE_ENCRYPTED_REASONING,
900
- },
901
- ]),
902
- )
903
-
904
- case "@ai-sdk/cerebras":
905
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/cerebras
906
- case "@ai-sdk/togetherai":
907
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/togetherai
908
- case "@ai-sdk/xai":
909
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/xai
910
- case "@ai-sdk/deepinfra":
911
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/deepinfra
912
- case "venice-ai-sdk-provider":
913
- // https://docs.venice.ai/overview/guides/reasoning-models#reasoning-effort
914
- case "@ai-sdk/openai-compatible":
915
- if (model.api.id.toLowerCase().includes("north-mini-code")) {
916
- return Object.fromEntries(["none", "high"].map((effort) => [effort, { reasoningEffort: effort }]))
917
- }
918
- const efforts = [...WIDELY_SUPPORTED_EFFORTS]
919
- if (model.api.id.toLowerCase().includes("deepseek-v4")) {
920
- efforts.push("max")
921
- }
922
- return Object.fromEntries(efforts.map((effort) => [effort, { reasoningEffort: effort }]))
923
-
924
- case "@ai-sdk/azure":
925
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/azure
926
- if (id === "o1-mini") return {}
927
- return Object.fromEntries(
928
- openaiReasoningEfforts(id, model.release_date).map((effort) => [
929
- effort,
930
- {
931
- reasoningEffort: effort,
932
- reasoningSummary: "auto",
933
- include: INCLUDE_ENCRYPTED_REASONING,
934
- },
935
- ]),
936
- )
937
- case "@ai-sdk/amazon-bedrock/mantle":
938
- case "@ai-sdk/openai": {
939
- if (model.providerID === "meta") {
940
- return Object.fromEntries(
941
- OPENAI_EFFORTS.map((effort) => [
942
- effort,
943
- {
944
- reasoningEffort: effort,
945
- reasoningSummary: "auto",
946
- include: INCLUDE_ENCRYPTED_REASONING,
947
- },
948
- ]),
949
- )
950
- }
951
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/openai
952
- const efforts = openaiReasoningEfforts(model.api.id, model.release_date)
953
- return Object.fromEntries(
954
- efforts.map((effort) => [
955
- effort,
956
- {
957
- reasoningEffort: effort,
958
- reasoningSummary: "auto",
959
- include: INCLUDE_ENCRYPTED_REASONING,
960
- },
961
- ]),
962
- )
963
- }
964
-
965
- case "@ai-sdk/anthropic":
966
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/anthropic
967
- case "@ai-sdk/google-vertex/anthropic":
968
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/google-vertex#anthropic-provider
969
- if (adaptiveEfforts) {
970
- let efforts = [...adaptiveEfforts]
971
- if (model.providerID === "github-copilot") {
972
- if (model.api.id.includes("opus-4.7")) {
973
- efforts = ["medium"]
974
- }
975
- // Efforts currently supported are: low, medium, high
976
- efforts = efforts.filter((v) => v !== "max" && v !== "xhigh")
977
- }
978
- return Object.fromEntries(
979
- efforts.map((effort) => [
980
- effort,
981
- {
982
- thinking: {
983
- type: "adaptive",
984
- ...(adaptiveThinkingOmitted ? { display: "summarized" } : {}),
985
- },
986
- effort,
987
- },
988
- ]),
989
- )
990
- }
991
-
992
- if (anthropicOpus45(model.api.id)) {
993
- return Object.fromEntries(
994
- WIDELY_SUPPORTED_EFFORTS.map((effort) => [effort, anthropicOpus45Effort(model, effort)]),
995
- )
996
- }
997
-
998
- return {
999
- high: {
1000
- thinking: {
1001
- type: "enabled",
1002
- budgetTokens: Math.min(16_000, Math.floor(model.limit.output / 2 - 1)),
1003
- },
1004
- },
1005
- max: {
1006
- thinking: {
1007
- type: "enabled",
1008
- budgetTokens: Math.min(31_999, model.limit.output - 1),
1009
- },
1010
- },
1011
- }
1012
-
1013
- case "@ai-sdk/amazon-bedrock":
1014
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/amazon-bedrock
1015
- if (adaptiveEfforts) {
1016
- return Object.fromEntries(
1017
- adaptiveEfforts.map((effort) => [
1018
- effort,
1019
- {
1020
- reasoningConfig: {
1021
- type: "adaptive",
1022
- maxReasoningEffort: effort,
1023
- ...(adaptiveThinkingOmitted ? { display: "summarized" } : {}),
1024
- },
1025
- },
1026
- ]),
1027
- )
1028
- }
1029
- // For Anthropic models on Bedrock, use reasoningConfig with budgetTokens
1030
- if (model.api.id.includes("anthropic")) {
1031
- return {
1032
- high: {
1033
- reasoningConfig: {
1034
- type: "enabled",
1035
- budgetTokens: 16000,
1036
- },
1037
- },
1038
- max: {
1039
- reasoningConfig: {
1040
- type: "enabled",
1041
- budgetTokens: 31999,
1042
- },
1043
- },
1044
- }
1045
- }
1046
-
1047
- // For Amazon Nova models, use reasoningConfig with maxReasoningEffort
1048
- return Object.fromEntries(
1049
- WIDELY_SUPPORTED_EFFORTS.map((effort) => [
1050
- effort,
1051
- {
1052
- reasoningConfig: {
1053
- type: "enabled",
1054
- maxReasoningEffort: effort,
1055
- },
1056
- },
1057
- ]),
1058
- )
1059
-
1060
- case "@ai-sdk/google-vertex":
1061
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/google-vertex
1062
- case "@ai-sdk/google":
1063
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/google-generative-ai
1064
- return googleThinkingVariants(model)
1065
-
1066
- case "@ai-sdk/mistral":
1067
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/mistral
1068
- // https://docs.mistral.ai/capabilities/reasoning/adjustable
1069
- if (!model.capabilities.reasoning) return {}
1070
- // Only Mistral Small 4 and Medium 3.5 support reasoning
1071
- const MISTRAL_REASONING_IDS = [
1072
- "mistral-small-2603",
1073
- "mistral-small-latest",
1074
- "mistral-medium-3.5",
1075
- "mistral-medium-2604",
1076
- ]
1077
- const mistralId = model.api.id.toLowerCase()
1078
- if (!MISTRAL_REASONING_IDS.some((id) => mistralId.includes(id))) return {}
1079
- return {
1080
- high: { reasoningEffort: "high" },
1081
- }
1082
-
1083
- case "@ai-sdk/cohere":
1084
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/cohere
1085
- return {}
1086
-
1087
- case "@ai-sdk/groq":
1088
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/groq
1089
- const groqEffort = ["none", ...WIDELY_SUPPORTED_EFFORTS]
1090
- return Object.fromEntries(
1091
- groqEffort.map((effort) => [
1092
- effort,
1093
- {
1094
- reasoningEffort: effort,
1095
- },
1096
- ]),
1097
- )
1098
-
1099
- case "@ai-sdk/perplexity":
1100
- // https://v5.ai-sdk.dev/providers/ai-sdk-providers/perplexity
1101
- return {}
1102
-
1103
- case "@jerome-benoit/sap-ai-provider-v2": {
1104
- if (id.includes("anthropic")) {
1105
- if (adaptiveEfforts) {
1106
- // Bedrock adaptive splits `effort` out into `output_config` (vs Anthropic
1107
- // native which inlines it). Claude 4.7+ defaults `display` to "omitted".
1108
- return wrapInSapModelParams(
1109
- Object.fromEntries(
1110
- adaptiveEfforts.map((effort) => [
1111
- effort,
1112
- {
1113
- thinking: { type: "adaptive", ...(adaptiveThinkingOmitted ? { display: "summarized" } : {}) },
1114
- output_config: { effort },
1115
- },
1116
- ]),
1117
- ),
1118
- )
1119
- }
1120
- return wrapInSapModelParams({
1121
- high: { thinking: { type: "enabled", budget_tokens: 16000 } },
1122
- max: { thinking: { type: "enabled", budget_tokens: 31999 } },
1123
- })
1124
- }
1125
- if (id.includes("gemini") && id.includes("2.5")) {
1126
- return wrapInSapModelParams(googleThinkingVariants(model))
1127
- }
1128
- if (id.includes("gpt") || /\bo[1-9]/.test(id)) {
1129
- const efforts = openaiReasoningEfforts(id, model.release_date)
1130
- return wrapInSapModelParams(Object.fromEntries(efforts.map((effort) => [effort, { reasoning_effort: effort }])))
1131
- }
1132
- return wrapInSapModelParams(
1133
- Object.fromEntries(["low", "medium", "high"].map((effort) => [effort, { reasoning_effort: effort }])),
1134
- )
1135
- }
1136
- }
1137
- return {}
1138
- }
1139
-
1140
- export function options(input: {
1141
- model: Provider.Model
1142
- sessionID: string
1143
- providerOptions?: Record<string, any>
1144
- }): Record<string, any> {
1145
- const result: Record<string, any> = {}
1146
-
1147
- if (
1148
- input.model.api.npm === "@ai-sdk/google-vertex/anthropic" ||
1149
- (!input.model.api.id.includes("claude") && input.model.api.npm === "@ai-sdk/anthropic")
1150
- ) {
1151
- result["toolStreaming"] = false
1152
- }
1153
-
1154
- // openai and providers using openai package should set store to false by default.
1155
- if (
1156
- input.model.providerID === "openai" ||
1157
- input.model.api.npm === "@ai-sdk/openai" ||
1158
- input.model.api.npm === "@ai-sdk/github-copilot" ||
1159
- input.model.api.npm === "@ai-sdk/amazon-bedrock/mantle" ||
1160
- input.model.api.npm === "@ai-sdk/xai"
1161
- ) {
1162
- result["store"] = false
1163
- }
1164
-
1165
- if (input.model.api.npm === "@ai-sdk/azure") {
1166
- result["store"] = false
1167
- }
1168
-
1169
- if (input.model.api.npm === "@openrouter/ai-sdk-provider" || input.model.api.npm === "@llmgateway/ai-sdk-provider") {
1170
- result["usage"] = {
1171
- include: true,
1172
- }
1173
- if (input.model.api.id.includes("gemini-3")) {
1174
- result["reasoning"] = { effort: "high" }
1175
- }
1176
- }
1177
-
1178
- if (
1179
- input.model.providerID === "baseten" ||
1180
- (input.model.providerID === "anymous" && ["kimi-k2-thinking", "glm-4.6"].includes(input.model.api.id))
1181
- ) {
1182
- result["chat_template_args"] = { enable_thinking: true }
1183
- }
1184
-
1185
- if (
1186
- ["zai", "zhipuai"].some((id) => input.model.providerID.includes(id)) &&
1187
- input.model.api.npm === "@ai-sdk/openai-compatible"
1188
- ) {
1189
- result["thinking"] = {
1190
- type: "enabled",
1191
- clear_thinking: false,
1192
- }
1193
- }
1194
-
1195
- if (input.model.providerID === "meta" && input.model.api.npm === "@ai-sdk/openai") {
1196
- result["reasoningSummary"] = "auto"
1197
- result["include"] = INCLUDE_ENCRYPTED_REASONING
1198
- }
1199
-
1200
- if (input.model.api.npm === "@ai-sdk/google" || input.model.api.npm === "@ai-sdk/google-vertex") {
1201
- if (input.model.capabilities.reasoning) {
1202
- result["thinkingConfig"] = {
1203
- includeThoughts: true,
1204
- }
1205
- if (input.model.api.id.includes("gemini-3")) {
1206
- result["thinkingConfig"]["thinkingLevel"] = "high"
1207
- }
1208
- }
1209
- }
1210
-
1211
- const modelId = input.model.api.id.toLowerCase()
1212
-
1213
- // MiniMax's Anthropic interface defaults thinking off, unlike Chat Completions.
1214
- if (modelId.includes("minimax-m3") && input.model.api.npm === "@ai-sdk/anthropic") {
1215
- result["thinking"] = { type: "adaptive" }
1216
- }
1217
-
1218
- // Moonshot's Anthropic-compatible API uses adaptive effort rather than token budgets.
1219
- // Request summaries so thinking content survives replay on subsequent turns.
1220
- if (
1221
- ["@ai-sdk/anthropic", "@ai-sdk/google-vertex/anthropic"].includes(input.model.api.npm) &&
1222
- isKimiFamily(input.model) &&
1223
- input.model.capabilities.reasoning
1224
- ) {
1225
- result["thinking"] = { type: "adaptive", display: "summarized" }
1226
- result["effort"] = "high"
1227
- }
1228
-
1229
- // Enable thinking for reasoning models on alibaba-cn (DashScope).
1230
- // DashScope's OpenAI-compatible API requires `enable_thinking: true` in the request body
1231
- // to return reasoning_content. Without it, models like kimi-k2.5, qwen-plus, qwen3, qwq,
1232
- // deepseek-r1, etc. never output thinking/reasoning tokens.
1233
- // Note: kimi-k2-thinking is excluded as it returns reasoning_content by default.
1234
- if (
1235
- input.model.providerID === "alibaba-cn" &&
1236
- input.model.capabilities.reasoning &&
1237
- input.model.api.npm === "@ai-sdk/openai-compatible" &&
1238
- !modelId.includes("kimi-k2-thinking")
1239
- ) {
1240
- result["enable_thinking"] = true
1241
- }
1242
-
1243
- if (input.providerOptions?.setCacheKey !== false) {
1244
- if (input.model.api.npm === "@ai-sdk/deepinfra" || input.model.api.npm === "@ai-sdk/cerebras") {
1245
- result["prompt_cache_key"] = input.sessionID
1246
- } else if (
1247
- input.model.api.npm === "@ai-sdk/openai" ||
1248
- input.model.api.npm === "@ai-sdk/azure" ||
1249
- input.model.api.npm === "@ai-sdk/xai" ||
1250
- input.model.api.npm === "@ai-sdk/mistral" ||
1251
- input.model.api.npm === "venice-ai-sdk-provider" ||
1252
- input.providerOptions?.setCacheKey === true
1253
- ) {
1254
- result["promptCacheKey"] = input.sessionID
1255
- }
1256
- }
1257
-
1258
- if (input.model.api.npm === "@ai-sdk/gateway") {
1259
- result["gateway"] = { caching: "auto" }
1260
- }
1261
-
1262
- if (input.model.api.npm === "@ai-sdk/azure" && input.model.api.id.includes("gpt-5.5")) {
1263
- result["reasoningSummary"] = "auto"
1264
- return result
1265
- }
1266
-
1267
- if (input.model.api.id.includes("gpt-5") && !input.model.api.id.includes("gpt-5-chat")) {
1268
- if (!input.model.api.id.includes("gpt-5-pro")) {
1269
- result["reasoningEffort"] = "medium"
1270
- if (
1271
- input.model.api.npm === "@ai-sdk/openai" ||
1272
- input.model.api.npm === "@ai-sdk/azure" ||
1273
- input.model.api.npm === "@ai-sdk/github-copilot" ||
1274
- input.model.api.npm === "@ai-sdk/amazon-bedrock/mantle"
1275
- ) {
1276
- result["reasoningSummary"] = "auto"
1277
- }
1278
- if (input.model.api.npm === "@ai-sdk/openai" || input.model.api.npm === "@ai-sdk/amazon-bedrock/mantle") {
1279
- result["include"] = INCLUDE_ENCRYPTED_REASONING
1280
- }
1281
- }
1282
-
1283
- // Only set textVerbosity for non-chat gpt-5.x models
1284
- // Chat models (e.g. gpt-5.2-chat-latest) only support "medium" verbosity
1285
- if (
1286
- input.model.api.id.includes("gpt-5.") &&
1287
- !input.model.api.id.includes("codex") &&
1288
- !input.model.api.id.includes("-chat") &&
1289
- input.model.providerID !== "azure"
1290
- ) {
1291
- result["textVerbosity"] = "low"
1292
- }
1293
-
1294
- if (input.model.providerID.startsWith("anymous") && input.providerOptions?.setCacheKey !== false) {
1295
- result["promptCacheKey"] = input.sessionID
1296
- result["include"] = INCLUDE_ENCRYPTED_REASONING
1297
- result["reasoningSummary"] = "auto"
1298
- }
1299
- }
1300
-
1301
- return result
1302
- }
1303
-
1304
- export function smallOptions(model: Provider.Model) {
1305
- const small = Object.values(model.variants ?? {})[0] ?? {}
1306
- if (
1307
- model.providerID === "openai" ||
1308
- model.api.npm === "@ai-sdk/openai" ||
1309
- model.api.npm === "@ai-sdk/github-copilot" ||
1310
- model.api.npm === "@ai-sdk/xai"
1311
- ) {
1312
- const base = { store: false }
1313
- return mergeDeep(base, small)
1314
- }
1315
- if (model.providerID === "openrouter" || model.providerID === "llmgateway") {
1316
- if (Object.keys(small).length === 0 && model.api.id.includes("google")) {
1317
- return { reasoning: { enabled: false } }
1318
- }
1319
- }
1320
-
1321
- if (model.providerID === "venice") {
1322
- if (Object.keys(small).length > 0) return small
1323
- return { veniceParameters: { disableThinking: true } }
1324
- }
1325
-
1326
- return small
1327
- }
1328
-
1329
- // Maps model ID prefix to provider slug used in providerOptions.
1330
- // Example: "amazon/nova-2-lite" → "bedrock"
1331
- const SLUG_OVERRIDES: Record<string, string> = {
1332
- amazon: "bedrock",
1333
- }
1334
-
1335
- export function providerOptions(model: Provider.Model, options: { [x: string]: any }) {
1336
- const usesOpenAIReasoningGate =
1337
- model.api.npm === "@ai-sdk/openai" ||
1338
- model.api.npm === "@ai-sdk/azure" ||
1339
- model.api.npm === "@ai-sdk/amazon-bedrock/mantle"
1340
- const normalized =
1341
- usesOpenAIReasoningGate &&
1342
- (model.capabilities.reasoning || options.reasoningEffort !== undefined || options.reasoningSummary !== undefined)
1343
- ? { ...options, forceReasoning: true }
1344
- : options
1345
-
1346
- if (model.api.npm === "@ai-sdk/gateway") {
1347
- // Gateway providerOptions are split across two namespaces:
1348
- // - `gateway`: gateway-native routing/caching controls (order, only, byok, etc.)
1349
- // - `<upstream slug>`: provider-specific model options (anthropic/openai/...)
1350
- // We keep `gateway` as-is and route every other top-level option under the
1351
- // model-derived upstream slug.
1352
- const i = model.api.id.indexOf("/")
1353
- const rawSlug = i > 0 ? model.api.id.slice(0, i) : undefined
1354
- const slug = rawSlug ? (SLUG_OVERRIDES[rawSlug] ?? rawSlug) : undefined
1355
- const gateway = normalized.gateway
1356
- const rest = Object.fromEntries(Object.entries(normalized).filter(([k]) => k !== "gateway"))
1357
- const has = Object.keys(rest).length > 0
1358
-
1359
- const result: Record<string, any> = {}
1360
- if (gateway !== undefined) result.gateway = gateway
1361
-
1362
- if (has) {
1363
- if (slug) {
1364
- // Route model-specific options under the provider slug
1365
- result[slug] = rest
1366
- } else if (gateway && typeof gateway === "object" && !Array.isArray(gateway)) {
1367
- result.gateway = { ...gateway, ...rest }
1368
- } else {
1369
- result.gateway = rest
1370
- }
1371
- }
1372
-
1373
- return result
1374
- }
1375
-
1376
- // AI SDK packages that resolve providerOptionsName by splitting the
1377
- // provider name on "." (e.g. "wafer.ai" -> "wafer") need the same
1378
- // logic here so the key we write matches the key they read.
1379
- // Other SDKs (xai, mistral, groq, cohere, etc.) use hardcoded keys
1380
- // like "xai" or "cohere" - applying .split(".")[0] would break those.
1381
- const usesDotSplitOptions =
1382
- model.api.npm === "@ai-sdk/openai-compatible" ||
1383
- model.api.npm === "@ai-sdk/openai" ||
1384
- model.api.npm === "@ai-sdk/anthropic"
1385
- const key = sdkKey(model.api.npm) ?? (usesDotSplitOptions ? model.providerID.split(".")[0] : model.providerID)
1386
- // @ai-sdk/azure delegates to OpenAIChatLanguageModel which reads from
1387
- // providerOptions["openai"], but OpenAIResponsesLanguageModel checks
1388
- // "azure" first. Pass both so model options work on either code path.
1389
- if (model.api.npm === "@ai-sdk/azure") {
1390
- return { openai: normalized, azure: normalized }
1391
- }
1392
- return { [key]: normalized }
1393
- }
1394
-
1395
- export function maxOutputTokens(model: Provider.Model, outputTokenMax = OUTPUT_TOKEN_MAX): number {
1396
- return Math.min(model.limit.output, outputTokenMax) || outputTokenMax
1397
- }
1398
-
1399
- type JsonRecord = Record<string, unknown>
1400
-
1401
- function isPlainObject(value: unknown): value is JsonRecord {
1402
- return typeof value === "object" && value !== null && !Array.isArray(value)
1403
- }
1404
-
1405
- // Mirrors Codex's Rust JSON schema compatibility lowering for OpenAI tool schemas.
1406
- function sanitizeOpenAISchema(value: unknown): unknown {
1407
- const types = ["string", "number", "boolean", "integer", "object", "array", "null"]
1408
- const compositionKeys = ["anyOf", "oneOf", "allOf"]
1409
-
1410
- // JSON Schema's boolean form (`true`/`false`) is unsupported by OpenAI tool schemas.
1411
- if (typeof value === "boolean") return { type: "string" }
1412
- if (Array.isArray(value)) return value.map(sanitizeOpenAISchema)
1413
- if (!isPlainObject(value)) return value
1414
-
1415
- const result: JsonRecord = {}
1416
-
1417
- if (typeof value.$ref === "string") result.$ref = value.$ref
1418
- if (typeof value.description === "string") result.description = value.description
1419
- if ("const" in value) result.enum = [value.const]
1420
- else if (Array.isArray(value.enum)) result.enum = value.enum
1421
-
1422
- if (isPlainObject(value.properties)) {
1423
- result.properties = Object.fromEntries(
1424
- Object.entries(value.properties).map(([key, item]) => [key, sanitizeOpenAISchema(item)]),
1425
- )
1426
- }
1427
-
1428
- if (Array.isArray(value.required)) {
1429
- result.required = value.required.filter((item) => typeof item === "string")
1430
- }
1431
-
1432
- if ("items" in value) result.items = sanitizeOpenAISchema(value.items)
1433
-
1434
- if ("additionalProperties" in value) {
1435
- result.additionalProperties =
1436
- typeof value.additionalProperties === "boolean"
1437
- ? value.additionalProperties
1438
- : sanitizeOpenAISchema(value.additionalProperties)
1439
- }
1440
-
1441
- for (const key of compositionKeys) {
1442
- if (Array.isArray(value[key])) result[key] = value[key].map(sanitizeOpenAISchema)
1443
- }
1444
-
1445
- for (const key of ["$defs", "definitions"]) {
1446
- if (isPlainObject(value[key])) {
1447
- result[key] = Object.fromEntries(
1448
- Object.entries(value[key]).map(([name, item]) => [name, sanitizeOpenAISchema(item)]),
1449
- )
1450
- }
1451
- }
1452
-
1453
- const schemaTypes =
1454
- typeof value.type === "string"
1455
- ? types.includes(value.type)
1456
- ? [value.type]
1457
- : []
1458
- : Array.isArray(value.type)
1459
- ? value.type.filter((item) => typeof item === "string" && types.includes(item))
1460
- : []
1461
-
1462
- if (schemaTypes.length === 0 && (typeof result.$ref === "string" || compositionKeys.some((key) => key in result))) {
1463
- return result
1464
- }
1465
-
1466
- // MCP schemas may omit `type` while still using keywords that imply one.
1467
- // Keep the schema usable after unsupported keywords are dropped.
1468
- const inferredTypes =
1469
- schemaTypes.length > 0
1470
- ? schemaTypes
1471
- : ["properties", "required", "additionalProperties"].some((key) => key in value)
1472
- ? ["object"]
1473
- : ["items", "prefixItems"].some((key) => key in value)
1474
- ? ["array"]
1475
- : "enum" in result || "format" in value
1476
- ? ["string"]
1477
- : ["minimum", "maximum", "exclusiveMinimum", "exclusiveMaximum", "multipleOf"].some((key) => key in value)
1478
- ? ["number"]
1479
- : []
1480
-
1481
- if (inferredTypes.length === 0) return {}
1482
-
1483
- result.type = inferredTypes.length === 1 ? inferredTypes[0] : inferredTypes
1484
- if (inferredTypes.includes("object") && !("properties" in result)) result.properties = {}
1485
- if (inferredTypes.includes("array") && !("items" in result)) result.items = { type: "string" }
1486
- return result
1487
- }
1488
-
1489
- export function schema(model: Provider.Model, schema: JSONSchema7): JSONSchema7 {
1490
- /*
1491
- if (["openai", "azure"].includes(providerID)) {
1492
- if (schema.type === "object" && schema.properties) {
1493
- for (const [key, value] of Object.entries(schema.properties)) {
1494
- if (schema.required?.includes(key)) continue
1495
- schema.properties[key] = {
1496
- anyOf: [
1497
- value as JSONSchema.JSONSchema,
1498
- {
1499
- type: "null",
1500
- },
1501
- ],
1502
- }
1503
- }
1504
- }
1505
- }
1506
- */
1507
-
1508
- if (model.api.npm === "@ai-sdk/openai" || model.api.npm === "@ai-sdk/azure") {
1509
- schema = sanitizeOpenAISchema(schema) as JSONSchema7
1510
- // Codex also applies lossy compaction above 4 KB; defer that until anymous needs the same schema budget.
1511
- }
1512
-
1513
- if (model.providerID === "moonshotai" || model.api.id.toLowerCase().includes("kimi")) {
1514
- const sanitizeMoonshot = (obj: unknown): unknown => {
1515
- if (obj === null || typeof obj !== "object") return obj
1516
- if (Array.isArray(obj)) return obj.map(sanitizeMoonshot)
1517
- // Moonshot expands $ref before validation and rejects sibling keywords like description on the same node.
1518
- if ("$ref" in obj && typeof obj.$ref === "string") return { $ref: obj.$ref }
1519
- const result = Object.fromEntries(Object.entries(obj).map(([key, value]) => [key, sanitizeMoonshot(value)]))
1520
- // MFJS does not support tuple-style `items` arrays; it requires one schema object for all array items.
1521
- if (Array.isArray(result.items)) result.items = result.items[0] ?? {}
1522
- return result
1523
- }
1524
-
1525
- const sanitized = sanitizeMoonshot(schema)
1526
- if (typeof sanitized === "object" && sanitized !== null && !Array.isArray(sanitized)) {
1527
- schema = sanitized
1528
- }
1529
- }
1530
-
1531
- // Convert integer enums to string enums for Google/Gemini
1532
- if (model.providerID === "google" || model.api.id.includes("gemini")) {
1533
- const isPlainObject = (node: unknown): node is Record<string, any> =>
1534
- typeof node === "object" && node !== null && !Array.isArray(node)
1535
- const hasCombiner = (node: unknown) =>
1536
- isPlainObject(node) && (Array.isArray(node.anyOf) || Array.isArray(node.oneOf) || Array.isArray(node.allOf))
1537
- const hasSchemaIntent = (node: unknown) => {
1538
- if (!isPlainObject(node)) return false
1539
- if (hasCombiner(node)) return true
1540
- return [
1541
- "type",
1542
- "properties",
1543
- "items",
1544
- "prefixItems",
1545
- "enum",
1546
- "const",
1547
- "$ref",
1548
- "additionalProperties",
1549
- "patternProperties",
1550
- "required",
1551
- "not",
1552
- "if",
1553
- "then",
1554
- "else",
1555
- ].some((key) => key in node)
1556
- }
1557
-
1558
- const sanitizeGemini = (obj: any): any => {
1559
- if (obj === null || typeof obj !== "object") {
1560
- return obj
1561
- }
1562
-
1563
- if (Array.isArray(obj)) {
1564
- return obj.map(sanitizeGemini)
1565
- }
1566
-
1567
- const result: any = {}
1568
- for (const [key, value] of Object.entries(obj)) {
1569
- if (key === "enum" && Array.isArray(value)) {
1570
- // Convert all enum values to strings
1571
- result[key] = value.map((v) => String(v))
1572
- // If we have integer type with enum, change type to string
1573
- if (result.type === "integer" || result.type === "number") {
1574
- result.type = "string"
1575
- }
1576
- } else if (typeof value === "object" && value !== null) {
1577
- result[key] = sanitizeGemini(value)
1578
- } else {
1579
- result[key] = value
1580
- }
1581
- }
1582
-
1583
- // Gemini requires a single `type`, not a JSON Schema type array such as
1584
- // `["number","string"]` (emitted by some MCP servers). Plain `@ai-sdk/google`
1585
- // rewrites these into an `anyOf` of single-type schemas, but OpenAI-compatible
1586
- // transports (e.g. GitHub Copilot proxying to Gemini) forward them verbatim
1587
- // and the backend rejects the array form. Mirror the SDK: split non-null
1588
- // types into `anyOf`, and lift `null` into `nullable`.
1589
- if (Array.isArray(result.type)) {
1590
- const hasNull = result.type.includes("null")
1591
- const nonNull = result.type.filter((entry: unknown) => entry !== "null")
1592
- if (nonNull.length === 0) {
1593
- result.type = "null"
1594
- } else {
1595
- delete result.type
1596
- result.anyOf = nonNull.map((entry: unknown) => ({ type: entry }))
1597
- if (hasNull) result.nullable = true
1598
- }
1599
- }
1600
-
1601
- // Filter required array to only include fields that exist in properties
1602
- if (result.type === "object" && result.properties && Array.isArray(result.required)) {
1603
- result.required = result.required.filter((field: any) => field in result.properties)
1604
- }
1605
-
1606
- if (result.type === "array" && !hasCombiner(result)) {
1607
- if (result.items == null) {
1608
- result.items = {}
1609
- }
1610
- // Ensure items has a type only when it's still schema-empty.
1611
- if (isPlainObject(result.items) && !hasSchemaIntent(result.items)) {
1612
- result.items.type = "string"
1613
- }
1614
- }
1615
-
1616
- // Remove properties/required from non-object types (Gemini rejects these)
1617
- if (result.type && result.type !== "object" && !hasCombiner(result)) {
1618
- delete result.properties
1619
- delete result.required
1620
- }
1621
-
1622
- return result
1623
- }
1624
-
1625
- schema = sanitizeGemini(schema)
1626
- }
1627
-
1628
- return schema
1629
- }
1630
-
1631
- export function reasoningVariants(model: ModelsDev.Model, target: Provider.Model): Provider.Model["variants"] {
1632
- const options = model.reasoning_options
1633
- if (options === undefined) return
1634
- if (options.length === 0) return {}
1635
-
1636
- const effort = options.find((option) => option.type === "effort")
1637
- if (effort) return effortVariants(target, effort.values)
1638
-
1639
- const toggle = options.some((option) => option.type === "toggle")
1640
- const budget = options.find((option) => option.type === "budget_tokens")
1641
- if (!budget) return toggle ? nonEmptyVariants(reasoningToggle(target)) : undefined
1642
-
1643
- return nonEmptyVariants({
1644
- ...(toggle ? reasoningToggle(target) : {}),
1645
- ...budgetVariants(target, budget.min, budget.max),
1646
- })
1647
- }
1648
-
1649
- function effortVariants(model: Provider.Model, values: readonly unknown[]) {
1650
- return Object.fromEntries(
1651
- values.flatMap((value) => {
1652
- const id = (() => {
1653
- if (value === null) return "none"
1654
- if (typeof value === "string") return value
1655
- })()
1656
- if (id === undefined) return []
1657
- const settings = reasoningEffort(model, id)
1658
- return settings ? [[id, settings]] : []
1659
- }),
1660
- )
1661
- }
1662
-
1663
- function budgetVariants(model: Provider.Model, min?: number, max?: number) {
1664
- const maximum = Math.min(max ?? OUTPUT_TOKEN_MAX - 1, model.limit.output - 1, OUTPUT_TOKEN_MAX - 1)
1665
- if (maximum <= 0) return {}
1666
- const high = Math.min(Math.max(min ?? 0, Math.floor((maximum + 1) / 2)), maximum)
1667
- return Object.fromEntries(
1668
- [
1669
- { id: "high", budget: high },
1670
- { id: "max", budget: maximum },
1671
- ].flatMap((item) => {
1672
- const settings = reasoningBudget(model, item.budget)
1673
- return settings ? [[item.id, settings]] : []
1674
- }),
1675
- )
1676
- }
1677
-
1678
- function nonEmptyVariants(variants: NonNullable<Provider.Model["variants"]>): Provider.Model["variants"] {
1679
- return Object.keys(variants).length > 0 ? variants : undefined
1680
- }
1681
-
1682
- function reasoningToggle(model: Provider.Model): NonNullable<Provider.Model["variants"]> {
1683
- if (model.api.npm === "@ai-sdk/alibaba")
1684
- return {
1685
- none: { enableThinking: false },
1686
- high: { enableThinking: true },
1687
- }
1688
- if (model.api.npm === "@ai-sdk/cohere")
1689
- return {
1690
- none: { thinking: { type: "disabled" } },
1691
- high: { thinking: { type: "enabled" } },
1692
- }
1693
- return {}
1694
- }
1695
-
1696
- function reasoningEffort(model: Provider.Model, effort: string) {
1697
- switch (model.api.npm) {
1698
- case "@openrouter/ai-sdk-provider":
1699
- return { reasoning: { effort } }
1700
- case "@ai-sdk/anthropic":
1701
- case "@ai-sdk/google-vertex/anthropic":
1702
- return anthropicEffort(model, effort) ?? { effort }
1703
- case "@ai-sdk/google":
1704
- case "@ai-sdk/google-vertex":
1705
- return { thinkingConfig: { includeThoughts: true, thinkingLevel: effort } }
1706
- case "@ai-sdk/amazon-bedrock":
1707
- if (anthropicAdaptiveEfforts(model.api.id))
1708
- return {
1709
- reasoningConfig: {
1710
- type: "adaptive",
1711
- maxReasoningEffort: effort,
1712
- ...(anthropicOmitsThinking(model.api.id) ? { display: "summarized" } : {}),
1713
- },
1714
- }
1715
- if (anthropicOpus45(model.api.id))
1716
- return {
1717
- reasoningConfig: {
1718
- type: "enabled",
1719
- budgetTokens: Math.min(16_000, Math.floor(model.limit.output / 2 - 1)),
1720
- maxReasoningEffort: effort,
1721
- },
1722
- }
1723
- if (model.api.id.includes("anthropic")) return
1724
- return { reasoningConfig: { type: "enabled", maxReasoningEffort: effort } }
1725
- case "@ai-sdk/gateway":
1726
- if (model.id.includes("anthropic")) return { thinking: { type: "adaptive", display: "summarized" }, effort }
1727
- if (model.id.includes("google")) return { thinkingConfig: { includeThoughts: true, thinkingLevel: effort } }
1728
- return { reasoningEffort: effort }
1729
- case "@ai-sdk/github-copilot":
1730
- // OAuth discovery replaces these with variants from Copilot's /models capabilities.
1731
- if (model.id.includes("gemini")) return
1732
- if (model.id.includes("claude")) return { reasoningEffort: effort }
1733
- return { reasoningEffort: effort, reasoningSummary: "auto", include: INCLUDE_ENCRYPTED_REASONING }
1734
- case "@ai-sdk/openai":
1735
- case "@ai-sdk/amazon-bedrock/mantle":
1736
- return { reasoningEffort: effort, reasoningSummary: "auto", include: INCLUDE_ENCRYPTED_REASONING }
1737
- case "@ai-sdk/azure":
1738
- return { reasoningEffort: effort, reasoningSummary: "auto", include: INCLUDE_ENCRYPTED_REASONING }
1739
- case "@jerome-benoit/sap-ai-provider-v2":
1740
- if (model.id.includes("anthropic"))
1741
- return { modelParams: { thinking: { type: "adaptive", display: "summarized" }, output_config: { effort } } }
1742
- return { modelParams: { reasoning_effort: effort } }
1743
- case "@ai-sdk/openai-compatible":
1744
- case "@ai-sdk/xai":
1745
- case "@ai-sdk/mistral":
1746
- case "@ai-sdk/groq":
1747
- case "@ai-sdk/cerebras":
1748
- case "@ai-sdk/deepinfra":
1749
- case "@ai-sdk/togetherai":
1750
- case "venice-ai-sdk-provider":
1751
- case "ai-gateway-provider":
1752
- return { reasoningEffort: effort }
1753
- case "@ai-sdk/cohere":
1754
- case "@ai-sdk/perplexity":
1755
- case "@ai-sdk/vercel":
1756
- case "@ai-sdk/alibaba":
1757
- case "gitlab-ai-provider":
1758
- return
1759
- }
1760
- }
1761
-
1762
- function anthropicEffort(model: Provider.Model, effort: string) {
1763
- if (anthropicOpus45(model.api.id)) return anthropicOpus45Effort(model, effort)
1764
- // Kimi defaults to omitting adaptive thinking text unless summarized display is requested.
1765
- if (isKimiFamily(model)) return { thinking: { type: "adaptive", display: "summarized" }, effort }
1766
- if (!anthropicAdaptiveEfforts(model.api.id)) return
1767
- return {
1768
- thinking: {
1769
- type: "adaptive",
1770
- ...(anthropicOmitsThinking(model.api.id) ? { display: "summarized" } : {}),
1771
- },
1772
- effort,
1773
- }
1774
- }
1775
-
1776
- function anthropicOpus45Effort(model: Provider.Model, effort: string) {
1777
- return {
1778
- thinking: {
1779
- type: "enabled",
1780
- budgetTokens: Math.min(16_000, Math.floor(model.limit.output / 2 - 1)),
1781
- },
1782
- effort,
1783
- }
1784
- }
1785
-
1786
- function reasoningBudget(model: Provider.Model, budget: number) {
1787
- switch (model.api.npm) {
1788
- case "@openrouter/ai-sdk-provider":
1789
- return { reasoning: { max_tokens: budget } }
1790
- case "@ai-sdk/anthropic":
1791
- case "@ai-sdk/google-vertex/anthropic":
1792
- return { thinking: { type: "enabled", budgetTokens: budget } }
1793
- case "@ai-sdk/google":
1794
- case "@ai-sdk/google-vertex":
1795
- return { thinkingConfig: { includeThoughts: true, thinkingBudget: budget } }
1796
- case "@ai-sdk/amazon-bedrock":
1797
- return { reasoningConfig: { type: "enabled", budgetTokens: budget } }
1798
- case "@ai-sdk/gateway":
1799
- if (model.id.includes("anthropic")) return { thinking: { type: "enabled", budgetTokens: budget } }
1800
- if (model.id.includes("google")) return { thinkingConfig: { includeThoughts: true, thinkingBudget: budget } }
1801
- return
1802
- case "@ai-sdk/cohere":
1803
- return { thinking: { type: "enabled", tokenBudget: budget } }
1804
- case "@ai-sdk/alibaba":
1805
- return { enableThinking: true, thinkingBudget: budget }
1806
- case "@jerome-benoit/sap-ai-provider-v2":
1807
- if (model.id.includes("anthropic"))
1808
- return { modelParams: { thinking: { type: "enabled", budget_tokens: budget } } }
1809
- if (model.id.includes("gemini"))
1810
- return { modelParams: { thinkingConfig: { includeThoughts: true, thinkingBudget: budget } } }
1811
- return
1812
- case "@ai-sdk/amazon-bedrock/mantle":
1813
- case "@ai-sdk/azure":
1814
- case "@ai-sdk/cerebras":
1815
- case "@ai-sdk/deepinfra":
1816
- case "@ai-sdk/github-copilot":
1817
- case "@ai-sdk/groq":
1818
- case "@ai-sdk/mistral":
1819
- case "@ai-sdk/openai":
1820
- case "@ai-sdk/openai-compatible":
1821
- case "@ai-sdk/perplexity":
1822
- case "@ai-sdk/togetherai":
1823
- case "@ai-sdk/vercel":
1824
- case "@ai-sdk/xai":
1825
- case "ai-gateway-provider":
1826
- case "gitlab-ai-provider":
1827
- case "venice-ai-sdk-provider":
1828
- return
1829
- }
1830
- }
1831
-
1832
- export * as ProviderTransform from "./transform"