@draht/ai 2026.7.13 → 2026.9.5-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 (524) hide show
  1. package/dist/api/anthropic-messages.d.ts.map +1 -1
  2. package/dist/api/anthropic-messages.js +144 -65
  3. package/dist/api/anthropic-messages.js.map +1 -1
  4. package/dist/api/azure-openai-responses.d.ts.map +1 -1
  5. package/dist/api/azure-openai-responses.js +28 -10
  6. package/dist/api/azure-openai-responses.js.map +1 -1
  7. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  8. package/dist/api/bedrock-converse-stream.js +70 -25
  9. package/dist/api/bedrock-converse-stream.js.map +1 -1
  10. package/dist/api/constrained-sampling.d.ts +17 -0
  11. package/dist/api/constrained-sampling.d.ts.map +1 -0
  12. package/dist/api/constrained-sampling.js +100 -0
  13. package/dist/api/constrained-sampling.js.map +1 -0
  14. package/dist/api/google-generative-ai.d.ts +2 -2
  15. package/dist/api/google-generative-ai.d.ts.map +1 -1
  16. package/dist/api/google-generative-ai.js +37 -27
  17. package/dist/api/google-generative-ai.js.map +1 -1
  18. package/dist/api/google-shared.d.ts +19 -5
  19. package/dist/api/google-shared.d.ts.map +1 -1
  20. package/dist/api/google-shared.js +77 -10
  21. package/dist/api/google-shared.js.map +1 -1
  22. package/dist/api/google-vertex.d.ts +2 -2
  23. package/dist/api/google-vertex.d.ts.map +1 -1
  24. package/dist/api/google-vertex.js +35 -25
  25. package/dist/api/google-vertex.js.map +1 -1
  26. package/dist/api/lazy.d.ts.map +1 -1
  27. package/dist/api/lazy.js +9 -10
  28. package/dist/api/lazy.js.map +1 -1
  29. package/dist/api/mistral-conversations.d.ts.map +1 -1
  30. package/dist/api/mistral-conversations.js +38 -21
  31. package/dist/api/mistral-conversations.js.map +1 -1
  32. package/dist/api/openai-codex-responses.d.ts +1 -0
  33. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  34. package/dist/api/openai-codex-responses.js +136 -68
  35. package/dist/api/openai-codex-responses.js.map +1 -1
  36. package/dist/api/openai-completions.d.ts +8 -8
  37. package/dist/api/openai-completions.d.ts.map +1 -1
  38. package/dist/api/openai-completions.js +230 -54
  39. package/dist/api/openai-completions.js.map +1 -1
  40. package/dist/api/openai-responses-shared.d.ts +8 -1
  41. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  42. package/dist/api/openai-responses-shared.js +233 -67
  43. package/dist/api/openai-responses-shared.js.map +1 -1
  44. package/dist/api/openai-responses.d.ts +1 -0
  45. package/dist/api/openai-responses.d.ts.map +1 -1
  46. package/dist/api/openai-responses.js +66 -18
  47. package/dist/api/openai-responses.js.map +1 -1
  48. package/dist/api/openrouter-images.d.ts.map +1 -1
  49. package/dist/api/openrouter-images.js +11 -5
  50. package/dist/api/openrouter-images.js.map +1 -1
  51. package/dist/api/pi-messages.d.ts +97 -0
  52. package/dist/api/pi-messages.d.ts.map +1 -0
  53. package/dist/api/pi-messages.js +305 -0
  54. package/dist/api/pi-messages.js.map +1 -0
  55. package/dist/api/pi-messages.lazy.d.ts +3 -0
  56. package/dist/api/pi-messages.lazy.d.ts.map +1 -0
  57. package/dist/api/pi-messages.lazy.js +3 -0
  58. package/dist/api/pi-messages.lazy.js.map +1 -0
  59. package/dist/api/simple-options.d.ts.map +1 -1
  60. package/dist/api/simple-options.js +1 -0
  61. package/dist/api/simple-options.js.map +1 -1
  62. package/dist/auth/credential-store.d.ts +2 -1
  63. package/dist/auth/credential-store.d.ts.map +1 -1
  64. package/dist/auth/credential-store.js +3 -0
  65. package/dist/auth/credential-store.js.map +1 -1
  66. package/dist/auth/helpers.d.ts +1 -0
  67. package/dist/auth/helpers.d.ts.map +1 -1
  68. package/dist/auth/helpers.js +7 -5
  69. package/dist/auth/helpers.js.map +1 -1
  70. package/dist/auth/oauth/anthropic.d.ts +9 -0
  71. package/dist/auth/oauth/anthropic.d.ts.map +1 -0
  72. package/dist/{utils → auth}/oauth/anthropic.js +51 -116
  73. package/dist/auth/oauth/anthropic.js.map +1 -0
  74. package/dist/auth/oauth/device-code.d.ts.map +1 -0
  75. package/dist/auth/oauth/device-code.js.map +1 -0
  76. package/dist/auth/oauth/github-copilot.d.ts +6 -0
  77. package/dist/auth/oauth/github-copilot.d.ts.map +1 -0
  78. package/dist/{utils → auth}/oauth/github-copilot.js +124 -107
  79. package/dist/auth/oauth/github-copilot.js.map +1 -0
  80. package/dist/auth/oauth/google-antigravity.d.ts +21 -0
  81. package/dist/auth/oauth/google-antigravity.d.ts.map +1 -0
  82. package/dist/{utils → auth}/oauth/google-antigravity.js +79 -79
  83. package/dist/auth/oauth/google-antigravity.js.map +1 -0
  84. package/dist/auth/oauth/google-gemini-cli.d.ts +21 -0
  85. package/dist/auth/oauth/google-gemini-cli.d.ts.map +1 -0
  86. package/dist/{utils → auth}/oauth/google-gemini-cli.js +79 -79
  87. package/dist/auth/oauth/google-gemini-cli.js.map +1 -0
  88. package/dist/auth/oauth/kimi-coding.d.ts +10 -0
  89. package/dist/auth/oauth/kimi-coding.d.ts.map +1 -0
  90. package/dist/auth/oauth/kimi-coding.js +249 -0
  91. package/dist/auth/oauth/kimi-coding.js.map +1 -0
  92. package/dist/auth/oauth/load.d.ts +33 -0
  93. package/dist/auth/oauth/load.d.ts.map +1 -0
  94. package/dist/auth/oauth/load.js +74 -0
  95. package/dist/auth/oauth/load.js.map +1 -0
  96. package/dist/auth/oauth/oauth-page.d.ts.map +1 -0
  97. package/dist/auth/oauth/oauth-page.js.map +1 -0
  98. package/dist/auth/oauth/openai-codex.d.ts +9 -0
  99. package/dist/auth/oauth/openai-codex.d.ts.map +1 -0
  100. package/dist/{utils → auth}/oauth/openai-codex.js +61 -155
  101. package/dist/auth/oauth/openai-codex.js.map +1 -0
  102. package/dist/auth/oauth/opencode-go.d.ts +14 -0
  103. package/dist/auth/oauth/opencode-go.d.ts.map +1 -0
  104. package/dist/auth/oauth/opencode-go.js +41 -0
  105. package/dist/auth/oauth/opencode-go.js.map +1 -0
  106. package/dist/auth/oauth/openrouter.d.ts +15 -0
  107. package/dist/auth/oauth/openrouter.d.ts.map +1 -0
  108. package/dist/auth/oauth/openrouter.js +277 -0
  109. package/dist/auth/oauth/openrouter.js.map +1 -0
  110. package/dist/auth/oauth/pkce.d.ts.map +1 -0
  111. package/dist/auth/oauth/pkce.js.map +1 -0
  112. package/dist/auth/oauth/radius.d.ts +17 -0
  113. package/dist/auth/oauth/radius.d.ts.map +1 -0
  114. package/dist/auth/oauth/radius.js +318 -0
  115. package/dist/auth/oauth/radius.js.map +1 -0
  116. package/dist/auth/oauth/xai.d.ts +17 -0
  117. package/dist/auth/oauth/xai.d.ts.map +1 -0
  118. package/dist/{utils → auth}/oauth/xai.js +54 -89
  119. package/dist/auth/oauth/xai.js.map +1 -0
  120. package/dist/auth/resolve.d.ts +4 -4
  121. package/dist/auth/resolve.d.ts.map +1 -1
  122. package/dist/auth/resolve.js +38 -17
  123. package/dist/auth/resolve.js.map +1 -1
  124. package/dist/auth/types.d.ts +49 -10
  125. package/dist/auth/types.d.ts.map +1 -1
  126. package/dist/auth/types.js.map +1 -1
  127. package/dist/bun-oauth.d.ts +3 -0
  128. package/dist/bun-oauth.d.ts.map +1 -0
  129. package/dist/bun-oauth.js +27 -0
  130. package/dist/bun-oauth.js.map +1 -0
  131. package/dist/cli.js +58 -76
  132. package/dist/cli.js.map +1 -1
  133. package/dist/compat/extension-oauth-types.d.ts +39 -0
  134. package/dist/compat/extension-oauth-types.d.ts.map +1 -0
  135. package/dist/compat/extension-oauth-types.js +2 -0
  136. package/dist/compat/extension-oauth-types.js.map +1 -0
  137. package/dist/compat.d.ts +2 -0
  138. package/dist/compat.d.ts.map +1 -1
  139. package/dist/compat.js +25 -8
  140. package/dist/compat.js.map +1 -1
  141. package/dist/env-api-keys.d.ts +3 -0
  142. package/dist/env-api-keys.d.ts.map +1 -1
  143. package/dist/env-api-keys.js +12 -3
  144. package/dist/env-api-keys.js.map +1 -1
  145. package/dist/image-models.generated.d.ts +75 -0
  146. package/dist/image-models.generated.d.ts.map +1 -1
  147. package/dist/image-models.generated.js +251 -176
  148. package/dist/image-models.generated.js.map +1 -1
  149. package/dist/images-models.d.ts +4 -2
  150. package/dist/images-models.d.ts.map +1 -1
  151. package/dist/images-models.js +5 -4
  152. package/dist/images-models.js.map +1 -1
  153. package/dist/index.d.ts +6 -2
  154. package/dist/index.d.ts.map +1 -1
  155. package/dist/index.js +3 -0
  156. package/dist/index.js.map +1 -1
  157. package/dist/model-catalog.d.ts +17 -0
  158. package/dist/model-catalog.d.ts.map +1 -0
  159. package/dist/model-catalog.js +4 -0
  160. package/dist/model-catalog.js.map +1 -0
  161. package/dist/models-store.d.ts +32 -0
  162. package/dist/models-store.d.ts.map +1 -0
  163. package/dist/models-store.js +16 -0
  164. package/dist/models-store.js.map +1 -0
  165. package/dist/models.d.ts +66 -30
  166. package/dist/models.d.ts.map +1 -1
  167. package/dist/models.generated.d.ts +74 -22035
  168. package/dist/models.generated.d.ts.map +1 -1
  169. package/dist/models.generated.js +4 -0
  170. package/dist/models.generated.js.map +1 -1
  171. package/dist/models.js +213 -29
  172. package/dist/models.js.map +1 -1
  173. package/dist/oauth.d.ts +2 -1
  174. package/dist/oauth.d.ts.map +1 -1
  175. package/dist/oauth.js +1 -1
  176. package/dist/oauth.js.map +1 -1
  177. package/dist/providers/all.d.ts +13 -6
  178. package/dist/providers/all.d.ts.map +1 -1
  179. package/dist/providers/all.js +13 -0
  180. package/dist/providers/all.js.map +1 -1
  181. package/dist/providers/amazon-bedrock.d.ts.map +1 -1
  182. package/dist/providers/amazon-bedrock.js +54 -8
  183. package/dist/providers/amazon-bedrock.js.map +1 -1
  184. package/dist/providers/amazon-bedrock.models.d.ts +3 -1931
  185. package/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  186. package/dist/providers/amazon-bedrock.models.js +3 -1838
  187. package/dist/providers/amazon-bedrock.models.js.map +1 -1
  188. package/dist/providers/ant-ling.models.d.ts +3 -85
  189. package/dist/providers/ant-ling.models.d.ts.map +1 -1
  190. package/dist/providers/ant-ling.models.js +3 -57
  191. package/dist/providers/ant-ling.models.js.map +1 -1
  192. package/dist/providers/anthropic.d.ts.map +1 -1
  193. package/dist/providers/anthropic.js +31 -4
  194. package/dist/providers/anthropic.js.map +1 -1
  195. package/dist/providers/anthropic.models.d.ts +3 -283
  196. package/dist/providers/anthropic.models.d.ts.map +1 -1
  197. package/dist/providers/anthropic.models.js +3 -252
  198. package/dist/providers/anthropic.models.js.map +1 -1
  199. package/dist/providers/azure-openai-responses.models.d.ts +3 -886
  200. package/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
  201. package/dist/providers/azure-openai-responses.models.js +3 -811
  202. package/dist/providers/azure-openai-responses.models.js.map +1 -1
  203. package/dist/providers/cerebras.models.d.ts +3 -65
  204. package/dist/providers/cerebras.models.d.ts.map +1 -1
  205. package/dist/providers/cerebras.models.js +3 -56
  206. package/dist/providers/cerebras.models.js.map +1 -1
  207. package/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
  208. package/dist/providers/cloudflare-ai-gateway.js +4 -3
  209. package/dist/providers/cloudflare-ai-gateway.js.map +1 -1
  210. package/dist/providers/cloudflare-ai-gateway.models.d.ts +3 -795
  211. package/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  212. package/dist/providers/cloudflare-ai-gateway.models.js +3 -683
  213. package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  214. package/dist/providers/cloudflare-auth.d.ts.map +1 -1
  215. package/dist/providers/cloudflare-auth.js +22 -26
  216. package/dist/providers/cloudflare-auth.js.map +1 -1
  217. package/dist/providers/cloudflare-stream.d.ts +8 -0
  218. package/dist/providers/cloudflare-stream.d.ts.map +1 -0
  219. package/dist/providers/cloudflare-stream.js +21 -0
  220. package/dist/providers/cloudflare-stream.js.map +1 -0
  221. package/dist/providers/cloudflare-workers-ai.d.ts.map +1 -1
  222. package/dist/providers/cloudflare-workers-ai.js +2 -1
  223. package/dist/providers/cloudflare-workers-ai.js.map +1 -1
  224. package/dist/providers/cloudflare-workers-ai.models.d.ts +3 -301
  225. package/dist/providers/cloudflare-workers-ai.models.d.ts.map +1 -1
  226. package/dist/providers/cloudflare-workers-ai.models.js +3 -236
  227. package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
  228. package/dist/providers/data/.manifest.json +1 -0
  229. package/dist/providers/data/amazon-bedrock.json +1 -0
  230. package/dist/providers/data/ant-ling.json +1 -0
  231. package/dist/providers/data/anthropic.json +1 -0
  232. package/dist/providers/data/azure-openai-responses.json +1 -0
  233. package/dist/providers/data/cerebras.json +1 -0
  234. package/dist/providers/data/cloudflare-ai-gateway.json +1 -0
  235. package/dist/providers/data/cloudflare-workers-ai.json +1 -0
  236. package/dist/providers/data/deepseek.json +1 -0
  237. package/dist/providers/data/fireworks.json +1 -0
  238. package/dist/providers/data/github-copilot.json +1 -0
  239. package/dist/providers/data/google-vertex.json +1 -0
  240. package/dist/providers/data/google.json +1 -0
  241. package/dist/providers/data/groq.json +1 -0
  242. package/dist/providers/data/huggingface.json +1 -0
  243. package/dist/providers/data/kimi-coding.json +1 -0
  244. package/dist/providers/data/minimax-cn.json +1 -0
  245. package/dist/providers/data/minimax.json +1 -0
  246. package/dist/providers/data/mistral.json +1 -0
  247. package/dist/providers/data/moonshotai-cn.json +1 -0
  248. package/dist/providers/data/moonshotai.json +1 -0
  249. package/dist/providers/data/nvidia.json +1 -0
  250. package/dist/providers/data/openai-codex.json +1 -0
  251. package/dist/providers/data/openai.json +1 -0
  252. package/dist/providers/data/opencode-go.json +1 -0
  253. package/dist/providers/data/opencode.json +1 -0
  254. package/dist/providers/data/openrouter.json +1 -0
  255. package/dist/providers/data/qwen-token-plan-cn.json +1 -0
  256. package/dist/providers/data/qwen-token-plan.json +1 -0
  257. package/dist/providers/data/together.json +1 -0
  258. package/dist/providers/data/vercel-ai-gateway.json +1 -0
  259. package/dist/providers/data/xai.json +1 -0
  260. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -0
  261. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -0
  262. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -0
  263. package/dist/providers/data/xiaomi.json +1 -0
  264. package/dist/providers/data/zai-coding-cn.json +1 -0
  265. package/dist/providers/data/zai.json +1 -0
  266. package/dist/providers/deepseek.models.d.ts +3 -62
  267. package/dist/providers/deepseek.models.d.ts.map +1 -1
  268. package/dist/providers/deepseek.models.js +3 -40
  269. package/dist/providers/deepseek.models.js.map +1 -1
  270. package/dist/providers/faux.d.ts.map +1 -1
  271. package/dist/providers/faux.js +4 -1
  272. package/dist/providers/faux.js.map +1 -1
  273. package/dist/providers/fireworks.models.d.ts +3 -380
  274. package/dist/providers/fireworks.models.d.ts.map +1 -1
  275. package/dist/providers/fireworks.models.js +3 -292
  276. package/dist/providers/fireworks.models.js.map +1 -1
  277. package/dist/providers/github-copilot.d.ts.map +1 -1
  278. package/dist/providers/github-copilot.js +11 -1
  279. package/dist/providers/github-copilot.js.map +1 -1
  280. package/dist/providers/github-copilot.models.d.ts +3 -790
  281. package/dist/providers/github-copilot.models.d.ts.map +1 -1
  282. package/dist/providers/github-copilot.models.js +3 -538
  283. package/dist/providers/github-copilot.models.js.map +1 -1
  284. package/dist/providers/google-vertex.d.ts.map +1 -1
  285. package/dist/providers/google-vertex.js +56 -5
  286. package/dist/providers/google-vertex.js.map +1 -1
  287. package/dist/providers/google-vertex.models.d.ts +3 -201
  288. package/dist/providers/google-vertex.models.d.ts.map +1 -1
  289. package/dist/providers/google-vertex.models.js +3 -179
  290. package/dist/providers/google-vertex.models.js.map +1 -1
  291. package/dist/providers/google.models.d.ts +3 -327
  292. package/dist/providers/google.models.d.ts.map +1 -1
  293. package/dist/providers/google.models.js +3 -285
  294. package/dist/providers/google.models.js.map +1 -1
  295. package/dist/providers/groq.models.d.ts +3 -127
  296. package/dist/providers/groq.models.d.ts.map +1 -1
  297. package/dist/providers/groq.models.js +3 -122
  298. package/dist/providers/groq.models.js.map +1 -1
  299. package/dist/providers/huggingface.models.d.ts +3 -982
  300. package/dist/providers/huggingface.models.d.ts.map +1 -1
  301. package/dist/providers/huggingface.models.js +3 -884
  302. package/dist/providers/huggingface.models.js.map +1 -1
  303. package/dist/providers/kimi-coding.d.ts.map +1 -1
  304. package/dist/providers/kimi-coding.js +10 -2
  305. package/dist/providers/kimi-coding.js.map +1 -1
  306. package/dist/providers/kimi-coding.models.d.ts +3 -62
  307. package/dist/providers/kimi-coding.models.d.ts.map +1 -1
  308. package/dist/providers/kimi-coding.models.js +3 -56
  309. package/dist/providers/kimi-coding.models.js.map +1 -1
  310. package/dist/providers/minimax-cn.models.d.ts +3 -53
  311. package/dist/providers/minimax-cn.models.d.ts.map +1 -1
  312. package/dist/providers/minimax-cn.models.js +3 -53
  313. package/dist/providers/minimax-cn.models.js.map +1 -1
  314. package/dist/providers/minimax.models.d.ts +3 -53
  315. package/dist/providers/minimax.models.d.ts.map +1 -1
  316. package/dist/providers/minimax.models.js +3 -53
  317. package/dist/providers/minimax.models.js.map +1 -1
  318. package/dist/providers/mistral.models.d.ts +3 -512
  319. package/dist/providers/mistral.models.d.ts.map +1 -1
  320. package/dist/providers/mistral.models.js +3 -512
  321. package/dist/providers/mistral.models.js.map +1 -1
  322. package/dist/providers/moonshotai-cn.models.d.ts +3 -233
  323. package/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
  324. package/dist/providers/moonshotai-cn.models.js +3 -166
  325. package/dist/providers/moonshotai-cn.models.js.map +1 -1
  326. package/dist/providers/moonshotai.models.d.ts +3 -233
  327. package/dist/providers/moonshotai.models.d.ts.map +1 -1
  328. package/dist/providers/moonshotai.models.js +3 -166
  329. package/dist/providers/moonshotai.models.js.map +1 -1
  330. package/dist/providers/nvidia.models.d.ts +3 -562
  331. package/dist/providers/nvidia.models.d.ts.map +1 -1
  332. package/dist/providers/nvidia.models.js +3 -382
  333. package/dist/providers/nvidia.models.js.map +1 -1
  334. package/dist/providers/openai-codex.d.ts.map +1 -1
  335. package/dist/providers/openai-codex.js +1 -1
  336. package/dist/providers/openai-codex.js.map +1 -1
  337. package/dist/providers/openai-codex.models.d.ts +3 -187
  338. package/dist/providers/openai-codex.models.d.ts.map +1 -1
  339. package/dist/providers/openai-codex.models.js +3 -133
  340. package/dist/providers/openai-codex.models.js.map +1 -1
  341. package/dist/providers/openai.models.d.ts +3 -936
  342. package/dist/providers/openai.models.d.ts.map +1 -1
  343. package/dist/providers/openai.models.js +3 -818
  344. package/dist/providers/openai.models.js.map +1 -1
  345. package/dist/providers/opencode-go.d.ts +1 -1
  346. package/dist/providers/opencode-go.d.ts.map +1 -1
  347. package/dist/providers/opencode-go.js +15 -3
  348. package/dist/providers/opencode-go.js.map +1 -1
  349. package/dist/providers/opencode-go.models.d.ts +3 -308
  350. package/dist/providers/opencode-go.models.d.ts.map +1 -1
  351. package/dist/providers/opencode-go.models.js +3 -237
  352. package/dist/providers/opencode-go.models.js.map +1 -1
  353. package/dist/providers/opencode.models.d.ts +3 -1183
  354. package/dist/providers/opencode.models.d.ts.map +1 -1
  355. package/dist/providers/opencode.models.js +3 -977
  356. package/dist/providers/opencode.models.js.map +1 -1
  357. package/dist/providers/openrouter-images.d.ts.map +1 -1
  358. package/dist/providers/openrouter-images.js +10 -2
  359. package/dist/providers/openrouter-images.js.map +1 -1
  360. package/dist/providers/openrouter.d.ts.map +1 -1
  361. package/dist/providers/openrouter.js +10 -2
  362. package/dist/providers/openrouter.js.map +1 -1
  363. package/dist/providers/openrouter.models.d.ts +3 -5705
  364. package/dist/providers/openrouter.models.d.ts.map +1 -1
  365. package/dist/providers/openrouter.models.js +3 -4873
  366. package/dist/providers/openrouter.models.js.map +1 -1
  367. package/dist/providers/qwen-token-plan-cn.d.ts +3 -0
  368. package/dist/providers/qwen-token-plan-cn.d.ts.map +1 -0
  369. package/dist/providers/qwen-token-plan-cn.js +15 -0
  370. package/dist/providers/qwen-token-plan-cn.js.map +1 -0
  371. package/dist/providers/qwen-token-plan-cn.models.d.ts +4 -0
  372. package/dist/providers/qwen-token-plan-cn.models.d.ts.map +1 -0
  373. package/dist/providers/qwen-token-plan-cn.models.js +6 -0
  374. package/dist/providers/qwen-token-plan-cn.models.js.map +1 -0
  375. package/dist/providers/qwen-token-plan.d.ts +3 -0
  376. package/dist/providers/qwen-token-plan.d.ts.map +1 -0
  377. package/dist/providers/qwen-token-plan.js +15 -0
  378. package/dist/providers/qwen-token-plan.js.map +1 -0
  379. package/dist/providers/qwen-token-plan.models.d.ts +4 -0
  380. package/dist/providers/qwen-token-plan.models.d.ts.map +1 -0
  381. package/dist/providers/qwen-token-plan.models.js +6 -0
  382. package/dist/providers/qwen-token-plan.models.js.map +1 -0
  383. package/dist/providers/radius-config.d.ts +26 -0
  384. package/dist/providers/radius-config.d.ts.map +1 -0
  385. package/dist/providers/radius-config.js +63 -0
  386. package/dist/providers/radius-config.js.map +1 -0
  387. package/dist/providers/radius.d.ts +9 -0
  388. package/dist/providers/radius.d.ts.map +1 -0
  389. package/dist/providers/radius.js +54 -0
  390. package/dist/providers/radius.js.map +1 -0
  391. package/dist/providers/together.models.d.ts +3 -597
  392. package/dist/providers/together.models.d.ts.map +1 -1
  393. package/dist/providers/together.models.js +3 -377
  394. package/dist/providers/together.models.js.map +1 -1
  395. package/dist/providers/vercel-ai-gateway.models.d.ts +3 -3391
  396. package/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  397. package/dist/providers/vercel-ai-gateway.models.js +3 -3327
  398. package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  399. package/dist/providers/xai.d.ts +1 -1
  400. package/dist/providers/xai.d.ts.map +1 -1
  401. package/dist/providers/xai.js +8 -4
  402. package/dist/providers/xai.js.map +1 -1
  403. package/dist/providers/xai.models.d.ts +3 -178
  404. package/dist/providers/xai.models.d.ts.map +1 -1
  405. package/dist/providers/xai.models.js +3 -146
  406. package/dist/providers/xai.models.js.map +1 -1
  407. package/dist/providers/xiaomi-token-plan-ams.models.d.ts +3 -65
  408. package/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
  409. package/dist/providers/xiaomi-token-plan-ams.models.js +3 -56
  410. package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
  411. package/dist/providers/xiaomi-token-plan-cn.models.d.ts +3 -65
  412. package/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
  413. package/dist/providers/xiaomi-token-plan-cn.models.js +3 -56
  414. package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
  415. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts +3 -65
  416. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
  417. package/dist/providers/xiaomi-token-plan-sgp.models.js +3 -56
  418. package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
  419. package/dist/providers/xiaomi.models.d.ts +3 -128
  420. package/dist/providers/xiaomi.models.d.ts.map +1 -1
  421. package/dist/providers/xiaomi.models.js +3 -110
  422. package/dist/providers/xiaomi.models.js.map +1 -1
  423. package/dist/providers/zai-coding-cn.models.d.ts +3 -152
  424. package/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
  425. package/dist/providers/zai-coding-cn.models.js +3 -111
  426. package/dist/providers/zai-coding-cn.models.js.map +1 -1
  427. package/dist/providers/zai.models.d.ts +3 -152
  428. package/dist/providers/zai.models.d.ts.map +1 -1
  429. package/dist/providers/zai.models.js +3 -111
  430. package/dist/providers/zai.models.js.map +1 -1
  431. package/dist/types.d.ts +77 -8
  432. package/dist/types.d.ts.map +1 -1
  433. package/dist/types.js.map +1 -1
  434. package/dist/utils/deferred-tools.d.ts +9 -0
  435. package/dist/utils/deferred-tools.d.ts.map +1 -0
  436. package/dist/utils/deferred-tools.js +36 -0
  437. package/dist/utils/deferred-tools.js.map +1 -0
  438. package/dist/utils/error-body.d.ts.map +1 -1
  439. package/dist/utils/error-body.js +31 -7
  440. package/dist/utils/error-body.js.map +1 -1
  441. package/dist/utils/estimate.d.ts.map +1 -1
  442. package/dist/utils/estimate.js +18 -5
  443. package/dist/utils/estimate.js.map +1 -1
  444. package/dist/utils/node-http-proxy.d.ts.map +1 -1
  445. package/dist/utils/node-http-proxy.js +53 -12
  446. package/dist/utils/node-http-proxy.js.map +1 -1
  447. package/dist/utils/overflow.d.ts +1 -0
  448. package/dist/utils/overflow.d.ts.map +1 -1
  449. package/dist/utils/overflow.js +3 -0
  450. package/dist/utils/overflow.js.map +1 -1
  451. package/dist/utils/pi-user-agent.d.ts +2 -0
  452. package/dist/utils/pi-user-agent.d.ts.map +1 -0
  453. package/dist/utils/pi-user-agent.js +12 -0
  454. package/dist/utils/pi-user-agent.js.map +1 -0
  455. package/dist/utils/provider-retry.d.ts +16 -0
  456. package/dist/utils/provider-retry.d.ts.map +1 -0
  457. package/dist/utils/provider-retry.js +94 -0
  458. package/dist/utils/provider-retry.js.map +1 -0
  459. package/dist/utils/retry.d.ts +41 -0
  460. package/dist/utils/retry.d.ts.map +1 -1
  461. package/dist/utils/retry.js +84 -0
  462. package/dist/utils/retry.js.map +1 -1
  463. package/dist/utils/sleep.d.ts +2 -0
  464. package/dist/utils/sleep.d.ts.map +1 -0
  465. package/dist/utils/sleep.js +15 -0
  466. package/dist/utils/sleep.js.map +1 -0
  467. package/dist/utils/text.d.ts +6 -0
  468. package/dist/utils/text.d.ts.map +1 -0
  469. package/dist/utils/text.js +10 -0
  470. package/dist/utils/text.js.map +1 -0
  471. package/dist/utils/uuid.d.ts +3 -0
  472. package/dist/utils/uuid.d.ts.map +1 -0
  473. package/dist/utils/uuid.js +47 -0
  474. package/dist/utils/uuid.js.map +1 -0
  475. package/dist/utils/validation.d.ts.map +1 -1
  476. package/dist/utils/validation.js +6 -0
  477. package/dist/utils/validation.js.map +1 -1
  478. package/package.json +12 -6
  479. package/dist/utils/oauth/anthropic.d.ts +0 -27
  480. package/dist/utils/oauth/anthropic.d.ts.map +0 -1
  481. package/dist/utils/oauth/anthropic.js.map +0 -1
  482. package/dist/utils/oauth/device-code.d.ts.map +0 -1
  483. package/dist/utils/oauth/device-code.js.map +0 -1
  484. package/dist/utils/oauth/github-copilot.d.ts +0 -32
  485. package/dist/utils/oauth/github-copilot.d.ts.map +0 -1
  486. package/dist/utils/oauth/github-copilot.js.map +0 -1
  487. package/dist/utils/oauth/google-antigravity.d.ts +0 -26
  488. package/dist/utils/oauth/google-antigravity.d.ts.map +0 -1
  489. package/dist/utils/oauth/google-antigravity.js.map +0 -1
  490. package/dist/utils/oauth/google-gemini-cli.d.ts +0 -26
  491. package/dist/utils/oauth/google-gemini-cli.d.ts.map +0 -1
  492. package/dist/utils/oauth/google-gemini-cli.js.map +0 -1
  493. package/dist/utils/oauth/index.d.ts +0 -60
  494. package/dist/utils/oauth/index.d.ts.map +0 -1
  495. package/dist/utils/oauth/index.js +0 -130
  496. package/dist/utils/oauth/index.js.map +0 -1
  497. package/dist/utils/oauth/load.d.ts +0 -6
  498. package/dist/utils/oauth/load.d.ts.map +0 -1
  499. package/dist/utils/oauth/load.js +0 -23
  500. package/dist/utils/oauth/load.js.map +0 -1
  501. package/dist/utils/oauth/oauth-page.d.ts.map +0 -1
  502. package/dist/utils/oauth/oauth-page.js.map +0 -1
  503. package/dist/utils/oauth/openai-codex.d.ts +0 -45
  504. package/dist/utils/oauth/openai-codex.d.ts.map +0 -1
  505. package/dist/utils/oauth/openai-codex.js.map +0 -1
  506. package/dist/utils/oauth/opencode-go.d.ts +0 -23
  507. package/dist/utils/oauth/opencode-go.d.ts.map +0 -1
  508. package/dist/utils/oauth/opencode-go.js +0 -46
  509. package/dist/utils/oauth/opencode-go.js.map +0 -1
  510. package/dist/utils/oauth/pkce.d.ts.map +0 -1
  511. package/dist/utils/oauth/pkce.js.map +0 -1
  512. package/dist/utils/oauth/types.d.ts +0 -64
  513. package/dist/utils/oauth/types.d.ts.map +0 -1
  514. package/dist/utils/oauth/types.js +0 -2
  515. package/dist/utils/oauth/types.js.map +0 -1
  516. package/dist/utils/oauth/xai.d.ts +0 -34
  517. package/dist/utils/oauth/xai.d.ts.map +0 -1
  518. package/dist/utils/oauth/xai.js.map +0 -1
  519. /package/dist/{utils → auth}/oauth/device-code.d.ts +0 -0
  520. /package/dist/{utils → auth}/oauth/device-code.js +0 -0
  521. /package/dist/{utils → auth}/oauth/oauth-page.d.ts +0 -0
  522. /package/dist/{utils → auth}/oauth/oauth-page.js +0 -0
  523. /package/dist/{utils → auth}/oauth/pkce.d.ts +0 -0
  524. /package/dist/{utils → auth}/oauth/pkce.js +0 -0
@@ -2,10 +2,14 @@ import OpenAI from "openai";
2
2
  import { calculateCost, clampThinkingLevel } from "../models.js";
3
3
  import { formatProviderError, normalizeProviderError } from "../utils/error-body.js";
4
4
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
5
+ import { shortHash } from "../utils/hash.js";
5
6
  import { headersToRecord } from "../utils/headers.js";
6
7
  import { parseStreamingJson } from "../utils/json-parse.js";
8
+ import { getPiUserAgent } from "../utils/pi-user-agent.js";
7
9
  import { getProviderEnvValue } from "../utils/provider-env.js";
10
+ import { retryProviderRequest } from "../utils/provider-retry.js";
8
11
  import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
12
+ import { appendGrammarToolInputJsonDelta, createGrammarToolInputProperties, getGrammarToolInput, resolveGrammarConstrainedSampling, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
9
13
  import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
10
14
  import { clampOpenAIPromptCacheKey } from "./openai-prompt-cache.js";
11
15
  import { buildBaseOptions } from "./simple-options.js";
@@ -45,6 +49,25 @@ function hasToolHistory(messages) {
45
49
  }
46
50
  return false;
47
51
  }
52
+ function getDeferredToolNames(messages) {
53
+ const names = new Set();
54
+ for (const message of messages) {
55
+ if (message.role === "toolResult") {
56
+ for (const name of message.addedToolNames ?? []) {
57
+ names.add(name);
58
+ }
59
+ }
60
+ }
61
+ return names;
62
+ }
63
+ function getToolsByName(tools, names) {
64
+ if (!tools)
65
+ return [];
66
+ const toolsByName = new Map(tools.map((tool) => [tool.name, tool]));
67
+ return Array.from(names)
68
+ .map((name) => toolsByName.get(name))
69
+ .filter((tool) => tool !== undefined);
70
+ }
48
71
  function isTextContentBlock(block) {
49
72
  return block.type === "text";
50
73
  }
@@ -94,16 +117,17 @@ export const stream = (model, context, options) => {
94
117
  totalTokens: 0,
95
118
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
96
119
  },
97
- stopReason: "stop",
120
+ stopReason: "pending",
98
121
  timestamp: Date.now(),
99
122
  };
100
123
  try {
101
124
  const apiKey = getClientApiKey(model.provider, options?.apiKey, options?.headers);
102
125
  const compat = getCompat(model);
126
+ const grammarToolInputProperties = createGrammarToolInputProperties(context.tools, compat.supportsOpenAIGrammarTools);
103
127
  const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
104
128
  const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
105
- const client = createClient(model, context, apiKey, options?.headers, cacheSessionId, compat);
106
- let params = buildParams(model, context, options, compat, cacheRetention);
129
+ const client = createClient(model, context, apiKey, options?.headers, options?.fetch, cacheSessionId, compat);
130
+ let params = buildParams(model, context, options, compat, cacheRetention, grammarToolInputProperties);
107
131
  const nextParams = await options?.onPayload?.(params, model);
108
132
  if (nextParams !== undefined) {
109
133
  params = nextParams;
@@ -111,11 +135,13 @@ export const stream = (model, context, options) => {
111
135
  const requestOptions = {
112
136
  ...(options?.signal ? { signal: options.signal } : {}),
113
137
  ...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
114
- maxRetries: options?.maxRetries ?? 0,
138
+ maxRetries: 0,
115
139
  };
116
- const { data: openaiStream, response } = await client.chat.completions
117
- .create(params, requestOptions)
118
- .withResponse();
140
+ const { data: openaiStream, response } = await retryProviderRequest(() => client.chat.completions.create(params, requestOptions).withResponse(), {
141
+ maxRetries: options?.maxRetries,
142
+ maxRetryDelayMs: options?.maxRetryDelayMs,
143
+ signal: options?.signal,
144
+ });
119
145
  await options?.onResponse?.({ status: response.status, headers: headersToRecord(response.headers) }, model);
120
146
  stream.push({ type: "start", partial: output });
121
147
  let textBlock = null;
@@ -126,6 +152,21 @@ export const stream = (model, context, options) => {
126
152
  const pendingReasoningDetailsByToolCallId = new Map();
127
153
  const blocks = output.content;
128
154
  const getContentIndex = (block) => blocks.indexOf(block);
155
+ const getCustomToolCallInput = (block) => {
156
+ const property = block.customInput?.property;
157
+ if (property === undefined)
158
+ return "";
159
+ const value = block.arguments[property];
160
+ return typeof value === "string" ? value : "";
161
+ };
162
+ const appendCustomToolCallInput = (block, nextInput, close) => {
163
+ const customInput = block.customInput;
164
+ if (!customInput)
165
+ return undefined;
166
+ const delta = appendGrammarToolInputJsonDelta(customInput.jsonBuffer, customInput.property, nextInput, close);
167
+ block.arguments = { [customInput.property]: nextInput };
168
+ return delta;
169
+ };
129
170
  const finishBlock = (block) => {
130
171
  const contentIndex = getContentIndex(block);
131
172
  if (contentIndex === -1) {
@@ -148,10 +189,24 @@ export const stream = (model, context, options) => {
148
189
  });
149
190
  }
150
191
  else if (block.type === "toolCall") {
151
- block.arguments = parseStreamingJson(block.partialArgs);
192
+ if (block.customInput) {
193
+ const delta = appendCustomToolCallInput(block, getCustomToolCallInput(block), true);
194
+ if (delta !== undefined) {
195
+ stream.push({
196
+ type: "toolcall_delta",
197
+ contentIndex,
198
+ delta,
199
+ partial: output,
200
+ });
201
+ }
202
+ }
203
+ else {
204
+ block.arguments = parseStreamingJson(block.partialArgs);
205
+ }
152
206
  // Finalize in-place and strip the scratch buffers so replay only
153
207
  // carries parsed arguments.
154
208
  delete block.partialArgs;
209
+ delete block.customInput;
155
210
  delete block.streamIndex;
156
211
  stream.push({
157
212
  type: "toolcall_end",
@@ -193,17 +248,25 @@ export const stream = (model, context, options) => {
193
248
  };
194
249
  const ensureToolCallBlock = (toolCall) => {
195
250
  const streamIndex = typeof toolCall.index === "number" ? toolCall.index : undefined;
251
+ const name = toolCall.function?.name ?? toolCall.custom?.name ?? "";
196
252
  let block = streamIndex !== undefined ? toolCallBlocksByIndex.get(streamIndex) : undefined;
197
253
  if (!block && toolCall.id) {
198
254
  block = toolCallBlocksById.get(toolCall.id);
199
255
  }
200
256
  if (!block) {
257
+ // Note: the "input" fallback here should/must not be taken. in case the LLM makes up
258
+ // a tool we don't knwo about, we at least have a place to stash our stuff.
259
+ const customInputProperty = toolCall.custom && !toolCall.function ? (grammarToolInputProperties.get(name) ?? "input") : undefined;
260
+ const hasCustomInput = customInputProperty !== undefined;
201
261
  block = {
202
262
  type: "toolCall",
203
263
  id: toolCall.id || "",
204
- name: toolCall.function?.name || "",
205
- arguments: {},
206
- partialArgs: "",
264
+ name,
265
+ arguments: hasCustomInput ? { [customInputProperty]: "" } : {},
266
+ partialArgs: hasCustomInput ? undefined : "",
267
+ customInput: hasCustomInput
268
+ ? { property: customInputProperty, jsonBuffer: { input: "", started: false, closed: false } }
269
+ : undefined,
207
270
  streamIndex,
208
271
  };
209
272
  if (streamIndex !== undefined) {
@@ -226,6 +289,18 @@ export const stream = (model, context, options) => {
226
289
  if (toolCall.id) {
227
290
  toolCallBlocksById.set(toolCall.id, block);
228
291
  }
292
+ if (!block.name && name) {
293
+ block.name = name;
294
+ }
295
+ if (toolCall.custom && !toolCall.function && !block.customInput) {
296
+ const customInputProperty = grammarToolInputProperties.get(block.name) ?? "input";
297
+ block.arguments = { [customInputProperty]: "" };
298
+ block.customInput = {
299
+ property: customInputProperty,
300
+ jsonBuffer: { input: "", started: false, closed: false },
301
+ };
302
+ delete block.partialArgs;
303
+ }
229
304
  applyPendingReasoningDetail(block);
230
305
  return block;
231
306
  };
@@ -250,6 +325,7 @@ export const stream = (model, context, options) => {
250
325
  output.usage = parseChunkUsage(choice.usage, model);
251
326
  }
252
327
  if (choice.finish_reason) {
328
+ output.rawStopReason = choice.finish_reason;
253
329
  const finishReasonResult = mapStopReason(choice.finish_reason);
254
330
  output.stopReason = finishReasonResult.stopReason;
255
331
  if (finishReasonResult.errorMessage) {
@@ -307,8 +383,9 @@ export const stream = (model, context, options) => {
307
383
  block.id = toolCall.id;
308
384
  toolCallBlocksById.set(toolCall.id, block);
309
385
  }
310
- if (!block.name && toolCall.function?.name) {
311
- block.name = toolCall.function.name;
386
+ const name = toolCall.function?.name ?? toolCall.custom?.name;
387
+ if (!block.name && name) {
388
+ block.name = name;
312
389
  }
313
390
  let delta = "";
314
391
  if (toolCall.function?.arguments) {
@@ -316,6 +393,10 @@ export const stream = (model, context, options) => {
316
393
  block.partialArgs = (block.partialArgs ?? "") + toolCall.function.arguments;
317
394
  block.arguments = parseStreamingJson(block.partialArgs);
318
395
  }
396
+ else if (toolCall.custom?.input) {
397
+ const nextInput = getCustomToolCallInput(block) + toolCall.custom.input;
398
+ delta = appendCustomToolCallInput(block, nextInput, false) ?? "";
399
+ }
319
400
  stream.push({
320
401
  type: "toolcall_delta",
321
402
  contentIndex: getContentIndex(block),
@@ -353,7 +434,7 @@ export const stream = (model, context, options) => {
353
434
  if (output.stopReason === "error") {
354
435
  throw new Error(output.errorMessage || "Provider returned an error stop reason");
355
436
  }
356
- if (!hasFinishReason) {
437
+ if (!hasFinishReason || output.stopReason === "pending") {
357
438
  throw new Error("Stream ended without finish_reason");
358
439
  }
359
440
  stream.push({ type: "done", reason: output.stopReason, message: output });
@@ -364,6 +445,7 @@ export const stream = (model, context, options) => {
364
445
  delete block.index;
365
446
  // Streaming scratch buffers are only used during parsing; never persist them.
366
447
  delete block.partialArgs;
448
+ delete block.customInput;
367
449
  delete block.streamIndex;
368
450
  }
369
451
  output.stopReason = options?.signal?.aborted ? "aborted" : "error";
@@ -384,18 +466,19 @@ export const stream = (model, context, options) => {
384
466
  };
385
467
  export const streamSimple = (model, context, options) => {
386
468
  getClientApiKey(model.provider, options?.apiKey, options?.headers);
387
- const base = buildBaseOptions(model, context, options, options?.apiKey);
469
+ const base = {
470
+ ...buildBaseOptions(model, context, options, options?.apiKey),
471
+ toolChoice: options?.toolChoice,
472
+ };
388
473
  const clampedReasoning = options?.reasoning ? clampThinkingLevel(model, options.reasoning) : undefined;
389
474
  const reasoningEffort = clampedReasoning === "off" ? undefined : clampedReasoning;
390
- const toolChoice = options?.toolChoice;
391
475
  return stream(model, context, {
392
476
  ...base,
393
477
  reasoningEffort,
394
- toolChoice,
395
478
  });
396
479
  };
397
- function createClient(model, context, apiKey, optionsHeaders, sessionId, compat = getCompat(model)) {
398
- const headers = { ...model.headers };
480
+ function createClient(model, context, apiKey, optionsHeaders, fetch, sessionId, compat = getCompat(model)) {
481
+ const headers = { "User-Agent": getPiUserAgent(), ...model.headers };
399
482
  if (model.provider === "github-copilot") {
400
483
  const hasImages = hasCopilotVisionInput(context.messages);
401
484
  const copilotHeaders = buildCopilotDynamicHeaders({
@@ -405,9 +488,16 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat
405
488
  Object.assign(headers, copilotHeaders);
406
489
  }
407
490
  if (sessionId && compat.sendSessionAffinityHeaders) {
408
- headers.session_id = sessionId;
409
- headers["x-client-request-id"] = sessionId;
410
- headers["x-session-affinity"] = sessionId;
491
+ if (compat.sessionAffinityFormat === "openrouter") {
492
+ headers["x-session-id"] = sessionId;
493
+ }
494
+ else {
495
+ if (compat.sessionAffinityFormat === "openai") {
496
+ headers.session_id = sessionId;
497
+ }
498
+ headers["x-client-request-id"] = sessionId;
499
+ headers["x-session-affinity"] = sessionId;
500
+ }
411
501
  }
412
502
  // Merge options headers last so they can override defaults
413
503
  if (optionsHeaders) {
@@ -417,11 +507,12 @@ function createClient(model, context, apiKey, optionsHeaders, sessionId, compat
417
507
  apiKey,
418
508
  baseURL: model.baseUrl,
419
509
  dangerouslyAllowBrowser: true,
510
+ fetch,
420
511
  defaultHeaders: headers,
421
512
  });
422
513
  }
423
- function buildParams(model, context, options, compat = getCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env)) {
424
- const messages = convertMessages(model, context, compat);
514
+ function buildParams(model, context, options, compat = getCompat(model), cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env), grammarToolInputProperties = createGrammarToolInputProperties(context.tools, compat.supportsOpenAIGrammarTools)) {
515
+ const messages = convertMessages(model, context, compat, { grammarToolInputProperties });
425
516
  const cacheControl = getCompatCacheControl(compat, cacheRetention);
426
517
  const params = {
427
518
  model: model.id,
@@ -450,8 +541,10 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
450
541
  if (options?.temperature !== undefined) {
451
542
  params.temperature = options.temperature;
452
543
  }
453
- if (context.tools && context.tools.length > 0) {
454
- params.tools = convertTools(context.tools, compat);
544
+ const deferredToolNames = compat.deferredToolsMode === "kimi" ? getDeferredToolNames(context.messages) : new Set();
545
+ const activeTools = context.tools?.filter((tool) => !deferredToolNames.has(tool.name));
546
+ if (activeTools && activeTools.length > 0) {
547
+ params.tools = convertTools(activeTools, compat);
455
548
  if (compat.zaiToolStream) {
456
549
  params.tool_stream = true;
457
550
  }
@@ -463,7 +556,7 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
463
556
  if (cacheControl) {
464
557
  applyAnthropicCacheControl(messages, params.tools, cacheControl);
465
558
  }
466
- if (options?.toolChoice) {
559
+ if (options?.toolChoice && params.tools?.length) {
467
560
  params.tool_choice = options.toolChoice;
468
561
  }
469
562
  if (compat.thinkingFormat === "zai" && model.reasoning) {
@@ -479,6 +572,12 @@ function buildParams(model, context, options, compat = getCompat(model), cacheRe
479
572
  }
480
573
  else if (compat.thinkingFormat === "qwen" && model.reasoning) {
481
574
  params.enable_thinking = !!options?.reasoningEffort;
575
+ if (options?.reasoningEffort && compat.supportsReasoningEffort) {
576
+ const effort = model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort;
577
+ if (typeof effort === "string") {
578
+ params.reasoning_effort = effort;
579
+ }
580
+ }
482
581
  }
483
582
  else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) {
484
583
  params.chat_template_kwargs = {
@@ -613,7 +712,7 @@ function addCacheControlToSystemPrompt(messages, cacheControl) {
613
712
  function addCacheControlToLastConversationMessage(messages, cacheControl) {
614
713
  for (let i = messages.length - 1; i >= 0; i--) {
615
714
  const message = messages[i];
616
- if (message.role === "user" || message.role === "assistant") {
715
+ if (message.role === "user" || message.role === "assistant" || message.role === "tool") {
617
716
  if (addCacheControlToMessage(message, cacheControl)) {
618
717
  return;
619
718
  }
@@ -631,7 +730,7 @@ function addCacheControlToInstructionMessage(message, cacheControl) {
631
730
  return addCacheControlToTextContent(message, cacheControl);
632
731
  }
633
732
  function addCacheControlToMessage(message, cacheControl) {
634
- if (message.role === "user" || message.role === "assistant") {
733
+ if (message.role === "user" || message.role === "assistant" || message.role === "tool") {
635
734
  return addCacheControlToTextContent(message, cacheControl);
636
735
  }
637
736
  return false;
@@ -664,17 +763,28 @@ function addCacheControlToTextContent(message, cacheControl) {
664
763
  }
665
764
  return false;
666
765
  }
667
- export function convertMessages(model, context, compat) {
766
+ export function convertMessages(model, context, compat, options) {
668
767
  const params = [];
669
768
  const normalizeToolCallId = (id) => {
670
769
  // Handle pipe-separated IDs from OpenAI Responses API
671
770
  // Format: {call_id}|{id} where {id} can be 400+ chars with special chars (+, /, =)
672
771
  // These come from providers like github-copilot, openai-codex, opencode
673
772
  // Extract just the call_id part and normalize it
773
+ // Multiple tool calls in the same turn can share call_id but differ by item_id.
774
+ // Preserve item-level uniqueness when replaying into Chat Completions, which
775
+ // requires distinct tool call ids.
674
776
  if (id.includes("|")) {
675
- const [callId] = id.split("|");
676
777
  // Sanitize to allowed chars and truncate to 40 chars (OpenAI limit)
677
- return callId.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 40);
778
+ const separatorIndex = id.indexOf("|");
779
+ const callId = id.slice(0, separatorIndex).replace(/[^a-zA-Z0-9_-]/g, "_");
780
+ const itemId = id.slice(separatorIndex + 1).replace(/[^a-zA-Z0-9_-]/g, "_");
781
+ const combinedId = itemId.length > 0 ? `${callId}_${itemId}` : callId;
782
+ if (combinedId.length <= 40) {
783
+ return combinedId;
784
+ }
785
+ const hash = shortHash(id).slice(0, 8);
786
+ const prefix = callId.slice(0, Math.max(1, 40 - hash.length - 1));
787
+ return `${prefix}_${hash}`;
678
788
  }
679
789
  if (model.provider === "openai")
680
790
  return id.length > 40 ? id.slice(0, 40) : id;
@@ -780,14 +890,27 @@ export function convertMessages(model, context, compat) {
780
890
  }
781
891
  const toolCalls = msg.content.filter(isToolCallBlock);
782
892
  if (toolCalls.length > 0) {
783
- assistantMsg.tool_calls = toolCalls.map((tc) => ({
784
- id: tc.id,
785
- type: "function",
786
- function: {
787
- name: tc.name,
788
- arguments: JSON.stringify(tc.arguments),
789
- },
790
- }));
893
+ assistantMsg.tool_calls = toolCalls.map((tc) => {
894
+ const customInputProperty = options?.grammarToolInputProperties?.get(tc.name);
895
+ if (customInputProperty !== undefined) {
896
+ return {
897
+ id: tc.id,
898
+ type: "custom",
899
+ custom: {
900
+ name: tc.name,
901
+ input: sanitizeSurrogates(getGrammarToolInput(tc.name, tc.arguments, customInputProperty)),
902
+ },
903
+ };
904
+ }
905
+ return {
906
+ id: tc.id,
907
+ type: "function",
908
+ function: {
909
+ name: tc.name,
910
+ arguments: JSON.stringify(tc.arguments),
911
+ },
912
+ };
913
+ });
791
914
  const reasoningDetails = toolCalls
792
915
  .filter((tc) => tc.thoughtSignature)
793
916
  .map((tc) => {
@@ -827,6 +950,7 @@ export function convertMessages(model, context, compat) {
827
950
  }
828
951
  else if (msg.role === "toolResult") {
829
952
  const imageBlocks = [];
953
+ const deferredToolNames = new Set();
830
954
  let j = i;
831
955
  for (; j < transformedMessages.length && transformedMessages[j].role === "toolResult"; j++) {
832
956
  const toolMsg = transformedMessages[j];
@@ -849,6 +973,11 @@ export function convertMessages(model, context, compat) {
849
973
  toolResultMsg.name = toolMsg.toolName;
850
974
  }
851
975
  params.push(toolResultMsg);
976
+ if (compat.deferredToolsMode === "kimi") {
977
+ for (const name of toolMsg.addedToolNames ?? []) {
978
+ deferredToolNames.add(name);
979
+ }
980
+ }
852
981
  if (hasImages && model.input.includes("image")) {
853
982
  for (const block of toolMsg.content) {
854
983
  if (isImageContentBlock(block)) {
@@ -885,6 +1014,17 @@ export function convertMessages(model, context, compat) {
885
1014
  else {
886
1015
  lastRole = "toolResult";
887
1016
  }
1017
+ if (deferredToolNames.size > 0) {
1018
+ const deferredTools = getToolsByName(context.tools, deferredToolNames);
1019
+ if (deferredTools.length > 0) {
1020
+ const kimiToolMessage = {
1021
+ role: "system",
1022
+ tools: convertTools(deferredTools, compat),
1023
+ };
1024
+ // Kimi accepts a system message with tools but omits the standard content field.
1025
+ params.push(kimiToolMessage);
1026
+ }
1027
+ }
888
1028
  continue;
889
1029
  }
890
1030
  lastRole = msg.role;
@@ -892,23 +1032,46 @@ export function convertMessages(model, context, compat) {
892
1032
  return params;
893
1033
  }
894
1034
  function convertTools(tools, compat) {
895
- return tools.map((tool) => ({
896
- type: "function",
897
- function: {
898
- name: tool.name,
899
- description: tool.description,
900
- parameters: tool.parameters, // TypeBox already generates JSON Schema
901
- // Only include strict if provider supports it. Some reject unknown fields.
902
- ...(compat.supportsStrictMode !== false && { strict: false }),
903
- },
904
- }));
1035
+ return tools.map((tool) => {
1036
+ const grammar = resolveGrammarConstrainedSampling(tool, compat.supportsOpenAIGrammarTools);
1037
+ if (grammar) {
1038
+ return {
1039
+ type: "custom",
1040
+ custom: {
1041
+ name: tool.name,
1042
+ description: tool.description,
1043
+ format: {
1044
+ type: "grammar",
1045
+ grammar: {
1046
+ syntax: grammar.format,
1047
+ definition: grammar.definition,
1048
+ },
1049
+ },
1050
+ },
1051
+ };
1052
+ }
1053
+ const strict = resolveJsonSchemaStrictSampling(tool, compat.supportsStrictMode !== false);
1054
+ return {
1055
+ type: "function",
1056
+ function: {
1057
+ name: tool.name,
1058
+ description: tool.description,
1059
+ parameters: tool.parameters, // TypeBox already generates JSON Schema
1060
+ // Only include strict if provider supports it. Some reject unknown fields.
1061
+ ...(compat.supportsStrictMode !== false && { strict: strict ?? false }),
1062
+ },
1063
+ };
1064
+ });
905
1065
  }
906
1066
  function parseChunkUsage(rawUsage, model) {
907
1067
  const promptTokens = rawUsage.prompt_tokens || 0;
908
- const cacheReadTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? rawUsage.prompt_cache_hit_tokens ?? 0;
1068
+ const cacheReadTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? rawUsage.prompt_cache_hit_tokens ?? rawUsage.cached_tokens ?? 0;
909
1069
  const cacheWriteTokens = rawUsage.prompt_tokens_details?.cache_write_tokens || 0;
910
1070
  // Follow documented OpenAI/OpenRouter semantics: cached_tokens is cache-read
911
- // tokens (hits). OpenAI does not document or emit cache_write_tokens, but
1071
+ // tokens (hits). Providers disagree on placement: OpenAI/OpenRouter use
1072
+ // prompt_tokens_details.cached_tokens, DeepSeek uses prompt_cache_hit_tokens,
1073
+ // and Kimi documents top-level usage.cached_tokens on the final usage chunk.
1074
+ // OpenAI does not document or emit cache_write_tokens, but
912
1075
  // OpenRouter-compatible providers can include it as a separate write count.
913
1076
  // OpenRouter's own provider/tests affirm the separate mapping:
914
1077
  // https://github.com/OpenRouterTeam/ai-sdk-provider/pull/409
@@ -987,9 +1150,16 @@ function detectCompat(model) {
987
1150
  isCloudflareWorkersAI ||
988
1151
  isCloudflareAiGateway ||
989
1152
  isAntLing;
990
- const useMaxTokens = baseUrl.includes("chutes.ai") || isMoonshot || isCloudflareAiGateway || isTogether || isNvidia || isAntLing;
991
- const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
992
1153
  const isDeepSeek = provider === "deepseek" || baseUrl.includes("deepseek.com");
1154
+ const useMaxTokens = baseUrl.includes("chutes.ai") ||
1155
+ isDeepSeek ||
1156
+ isMoonshot ||
1157
+ isCloudflareAiGateway ||
1158
+ isTogether ||
1159
+ isNvidia ||
1160
+ isAntLing ||
1161
+ isZai;
1162
+ const isGrok = provider === "xai" || baseUrl.includes("api.x.ai");
993
1163
  const isOpenRouterDeveloperRoleModel = isOpenRouter && (model.id.startsWith("anthropic/") || model.id.startsWith("openai/"));
994
1164
  const cacheControlFormat = provider === "openrouter" && model.id.startsWith("anthropic/") ? "anthropic" : undefined;
995
1165
  return {
@@ -1018,8 +1188,11 @@ function detectCompat(model) {
1018
1188
  chatTemplateKwargs: {},
1019
1189
  zaiToolStream: false,
1020
1190
  supportsStrictMode: !isMoonshot && !isTogether && !isCloudflareAiGateway && !isNvidia,
1191
+ supportsOpenAIGrammarTools: false,
1021
1192
  cacheControlFormat,
1022
1193
  sendSessionAffinityHeaders: false,
1194
+ deferredToolsMode: undefined,
1195
+ sessionAffinityFormat: isOpenRouter ? "openrouter" : "openai",
1023
1196
  supportsLongCacheRetention: !(isTogether ||
1024
1197
  isCloudflareWorkersAI ||
1025
1198
  isCloudflareAiGateway ||
@@ -1052,8 +1225,11 @@ function getCompat(model) {
1052
1225
  chatTemplateKwargs: model.compat.chatTemplateKwargs ?? detected.chatTemplateKwargs,
1053
1226
  zaiToolStream: model.compat.zaiToolStream ?? detected.zaiToolStream,
1054
1227
  supportsStrictMode: model.compat.supportsStrictMode ?? detected.supportsStrictMode,
1228
+ supportsOpenAIGrammarTools: model.compat.supportsOpenAIGrammarTools ?? detected.supportsOpenAIGrammarTools,
1055
1229
  cacheControlFormat: model.compat.cacheControlFormat ?? detected.cacheControlFormat,
1056
1230
  sendSessionAffinityHeaders: model.compat.sendSessionAffinityHeaders ?? detected.sendSessionAffinityHeaders,
1231
+ deferredToolsMode: model.compat.deferredToolsMode ?? detected.deferredToolsMode,
1232
+ sessionAffinityFormat: model.compat.sessionAffinityFormat ?? detected.sessionAffinityFormat,
1057
1233
  supportsLongCacheRetention: model.compat.supportsLongCacheRetention ?? detected.supportsLongCacheRetention,
1058
1234
  };
1059
1235
  }