@draht/ai 2026.7.13-1 → 2026.7.30

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