@bastani/pi-ai 0.9.19 → 0.9.20-alpha.10

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 (445) hide show
  1. package/CHANGELOG.md +83 -1
  2. package/NOTICE.md +1 -1
  3. package/README.md +203 -30
  4. package/dist/api/anthropic-messages.d.ts.map +1 -1
  5. package/dist/api/anthropic-messages.js +255 -97
  6. package/dist/api/anthropic-messages.js.map +1 -1
  7. package/dist/api/azure-openai-responses.d.ts.map +1 -1
  8. package/dist/api/azure-openai-responses.js +21 -6
  9. package/dist/api/azure-openai-responses.js.map +1 -1
  10. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  11. package/dist/api/bedrock-converse-stream.js +20 -15
  12. package/dist/api/bedrock-converse-stream.js.map +1 -1
  13. package/dist/api/cloudflare-workers-ai-system-one.d.ts +4 -0
  14. package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -0
  15. package/dist/api/cloudflare-workers-ai-system-one.js +43 -0
  16. package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -0
  17. package/dist/api/cloudflare-workers-ai-system-one.lazy.d.ts +3 -0
  18. package/dist/api/cloudflare-workers-ai-system-one.lazy.d.ts.map +1 -0
  19. package/dist/api/cloudflare-workers-ai-system-one.lazy.js +4 -0
  20. package/dist/api/cloudflare-workers-ai-system-one.lazy.js.map +1 -0
  21. package/dist/api/cloudflare.d.ts +2 -0
  22. package/dist/api/cloudflare.d.ts.map +1 -1
  23. package/dist/api/cloudflare.js +2 -0
  24. package/dist/api/cloudflare.js.map +1 -1
  25. package/dist/api/constrained-sampling.d.ts +8 -3
  26. package/dist/api/constrained-sampling.d.ts.map +1 -1
  27. package/dist/api/constrained-sampling.js +29 -11
  28. package/dist/api/constrained-sampling.js.map +1 -1
  29. package/dist/api/google-generative-ai.d.ts.map +1 -1
  30. package/dist/api/google-generative-ai.js +23 -80
  31. package/dist/api/google-generative-ai.js.map +1 -1
  32. package/dist/api/google-shared.d.ts +13 -4
  33. package/dist/api/google-shared.d.ts.map +1 -1
  34. package/dist/api/google-shared.js +54 -4
  35. package/dist/api/google-shared.js.map +1 -1
  36. package/dist/api/google-vertex.d.ts.map +1 -1
  37. package/dist/api/google-vertex.js +26 -65
  38. package/dist/api/google-vertex.js.map +1 -1
  39. package/dist/api/mistral-conversations.d.ts.map +1 -1
  40. package/dist/api/mistral-conversations.js +18 -13
  41. package/dist/api/mistral-conversations.js.map +1 -1
  42. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  43. package/dist/api/openai-codex-responses.js +40 -26
  44. package/dist/api/openai-codex-responses.js.map +1 -1
  45. package/dist/api/openai-completions.d.ts +6 -4
  46. package/dist/api/openai-completions.d.ts.map +1 -1
  47. package/dist/api/openai-completions.js +44 -58
  48. package/dist/api/openai-completions.js.map +1 -1
  49. package/dist/api/openai-responses-shared.d.ts +11 -5
  50. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  51. package/dist/api/openai-responses-shared.js +65 -58
  52. package/dist/api/openai-responses-shared.js.map +1 -1
  53. package/dist/api/openai-responses.d.ts.map +1 -1
  54. package/dist/api/openai-responses.js +15 -19
  55. package/dist/api/openai-responses.js.map +1 -1
  56. package/dist/api/openrouter-images.d.ts +2 -1
  57. package/dist/api/openrouter-images.d.ts.map +1 -1
  58. package/dist/api/openrouter-images.js +1 -0
  59. package/dist/api/openrouter-images.js.map +1 -1
  60. package/dist/api/openrouter-images.lazy.d.ts.map +1 -1
  61. package/dist/api/openrouter-images.lazy.js.map +1 -1
  62. package/dist/api/pi-messages.d.ts +3 -3
  63. package/dist/api/pi-messages.d.ts.map +1 -1
  64. package/dist/api/pi-messages.js +3 -2
  65. package/dist/api/pi-messages.js.map +1 -1
  66. package/dist/api/simple-options.d.ts +3 -3
  67. package/dist/api/simple-options.d.ts.map +1 -1
  68. package/dist/api/simple-options.js +1 -0
  69. package/dist/api/simple-options.js.map +1 -1
  70. package/dist/api/system-one-shared.d.ts +23 -0
  71. package/dist/api/system-one-shared.d.ts.map +1 -0
  72. package/dist/api/system-one-shared.js +170 -0
  73. package/dist/api/system-one-shared.js.map +1 -0
  74. package/dist/api/transform-messages.d.ts.map +1 -1
  75. package/dist/api/transform-messages.js +21 -7
  76. package/dist/api/transform-messages.js.map +1 -1
  77. package/dist/api/typesafe-system-one.d.ts +4 -0
  78. package/dist/api/typesafe-system-one.d.ts.map +1 -0
  79. package/dist/api/typesafe-system-one.js +19 -0
  80. package/dist/api/typesafe-system-one.js.map +1 -0
  81. package/dist/api/typesafe-system-one.lazy.d.ts +3 -0
  82. package/dist/api/typesafe-system-one.lazy.d.ts.map +1 -0
  83. package/dist/api/typesafe-system-one.lazy.js +4 -0
  84. package/dist/api/typesafe-system-one.lazy.js.map +1 -0
  85. package/dist/auth/credential-store.d.ts.map +1 -1
  86. package/dist/auth/credential-store.js +3 -2
  87. package/dist/auth/credential-store.js.map +1 -1
  88. package/dist/auth/oauth/load.d.ts +2 -0
  89. package/dist/auth/oauth/load.d.ts.map +1 -1
  90. package/dist/auth/oauth/load.js +5 -0
  91. package/dist/auth/oauth/load.js.map +1 -1
  92. package/dist/auth/oauth/meta.d.ts +17 -0
  93. package/dist/auth/oauth/meta.d.ts.map +1 -0
  94. package/dist/auth/oauth/meta.js +190 -0
  95. package/dist/auth/oauth/meta.js.map +1 -0
  96. package/dist/auth/resolve.d.ts +6 -8
  97. package/dist/auth/resolve.d.ts.map +1 -1
  98. package/dist/auth/resolve.js +29 -26
  99. package/dist/auth/resolve.js.map +1 -1
  100. package/dist/bun-oauth.d.ts.map +1 -1
  101. package/dist/bun-oauth.js +2 -0
  102. package/dist/bun-oauth.js.map +1 -1
  103. package/dist/compat.d.ts +3 -3
  104. package/dist/compat.d.ts.map +1 -1
  105. package/dist/compat.js +9 -6
  106. package/dist/compat.js.map +1 -1
  107. package/dist/decision-models.d.ts +21 -0
  108. package/dist/decision-models.d.ts.map +1 -0
  109. package/dist/decision-models.generated.d.ts +3 -0
  110. package/dist/decision-models.generated.d.ts.map +1 -0
  111. package/dist/decision-models.generated.js +47 -0
  112. package/dist/decision-models.generated.js.map +1 -0
  113. package/dist/decision-models.js +8 -0
  114. package/dist/decision-models.js.map +1 -0
  115. package/dist/env-api-keys.d.ts +2 -0
  116. package/dist/env-api-keys.d.ts.map +1 -1
  117. package/dist/env-api-keys.js +61 -43
  118. package/dist/env-api-keys.js.map +1 -1
  119. package/dist/image-models.d.ts +19 -8
  120. package/dist/image-models.d.ts.map +1 -1
  121. package/dist/image-models.js +14 -13
  122. package/dist/image-models.js.map +1 -1
  123. package/dist/images-api-registry.d.ts +7 -7
  124. package/dist/images-api-registry.d.ts.map +1 -1
  125. package/dist/images-api-registry.js.map +1 -1
  126. package/dist/images.d.ts +7 -2
  127. package/dist/images.d.ts.map +1 -1
  128. package/dist/images.js +5 -0
  129. package/dist/images.js.map +1 -1
  130. package/dist/index.d.ts +4 -2
  131. package/dist/index.d.ts.map +1 -1
  132. package/dist/index.js +4 -2
  133. package/dist/index.js.map +1 -1
  134. package/dist/model-catalog.d.ts +25 -9
  135. package/dist/model-catalog.d.ts.map +1 -1
  136. package/dist/model-catalog.js +14 -2
  137. package/dist/model-catalog.js.map +1 -1
  138. package/dist/models-store.d.ts +3 -2
  139. package/dist/models-store.d.ts.map +1 -1
  140. package/dist/models-store.js.map +1 -1
  141. package/dist/models.d.ts +99 -31
  142. package/dist/models.d.ts.map +1 -1
  143. package/dist/models.generated.d.ts +133 -39
  144. package/dist/models.generated.d.ts.map +1 -1
  145. package/dist/models.generated.js +133 -39
  146. package/dist/models.generated.js.map +1 -1
  147. package/dist/models.js +161 -31
  148. package/dist/models.js.map +1 -1
  149. package/dist/providers/all.d.ts +19 -13
  150. package/dist/providers/all.d.ts.map +1 -1
  151. package/dist/providers/all.js +27 -21
  152. package/dist/providers/all.js.map +1 -1
  153. package/dist/providers/amazon-bedrock.models.d.ts +4 -3
  154. package/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  155. package/dist/providers/amazon-bedrock.models.js +4 -2
  156. package/dist/providers/amazon-bedrock.models.js.map +1 -1
  157. package/dist/providers/ant-ling.models.d.ts +4 -3
  158. package/dist/providers/ant-ling.models.d.ts.map +1 -1
  159. package/dist/providers/ant-ling.models.js +4 -2
  160. package/dist/providers/ant-ling.models.js.map +1 -1
  161. package/dist/providers/anthropic.models.d.ts +4 -3
  162. package/dist/providers/anthropic.models.d.ts.map +1 -1
  163. package/dist/providers/anthropic.models.js +4 -2
  164. package/dist/providers/anthropic.models.js.map +1 -1
  165. package/dist/providers/azure-openai-responses.models.d.ts +4 -3
  166. package/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
  167. package/dist/providers/azure-openai-responses.models.js +4 -2
  168. package/dist/providers/azure-openai-responses.models.js.map +1 -1
  169. package/dist/providers/baseten.models.d.ts +4 -3
  170. package/dist/providers/baseten.models.d.ts.map +1 -1
  171. package/dist/providers/baseten.models.js +4 -2
  172. package/dist/providers/baseten.models.js.map +1 -1
  173. package/dist/providers/cerebras.models.d.ts +4 -3
  174. package/dist/providers/cerebras.models.d.ts.map +1 -1
  175. package/dist/providers/cerebras.models.js +4 -2
  176. package/dist/providers/cerebras.models.js.map +1 -1
  177. package/dist/providers/cloudflare-ai-gateway.models.d.ts +4 -3
  178. package/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  179. package/dist/providers/cloudflare-ai-gateway.models.js +4 -2
  180. package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  181. package/dist/providers/cloudflare-stream.d.ts +6 -2
  182. package/dist/providers/cloudflare-stream.d.ts.map +1 -1
  183. package/dist/providers/cloudflare-stream.js +6 -0
  184. package/dist/providers/cloudflare-stream.js.map +1 -1
  185. package/dist/providers/cloudflare-workers-ai.d.ts.map +1 -1
  186. package/dist/providers/cloudflare-workers-ai.js +10 -3
  187. package/dist/providers/cloudflare-workers-ai.js.map +1 -1
  188. package/dist/providers/cloudflare-workers-ai.models.d.ts +4 -3
  189. package/dist/providers/cloudflare-workers-ai.models.d.ts.map +1 -1
  190. package/dist/providers/cloudflare-workers-ai.models.js +4 -2
  191. package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
  192. package/dist/providers/data/.manifest.json +1 -1
  193. package/dist/providers/data/amazon-bedrock.json +1 -1
  194. package/dist/providers/data/ant-ling.json +1 -1
  195. package/dist/providers/data/anthropic.json +1 -1
  196. package/dist/providers/data/azure-openai-responses.json +1 -1
  197. package/dist/providers/data/baseten.json +1 -1
  198. package/dist/providers/data/cerebras.json +1 -1
  199. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  200. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  201. package/dist/providers/data/deepseek.json +1 -1
  202. package/dist/providers/data/fireworks.json +1 -1
  203. package/dist/providers/data/github-copilot.json +1 -1
  204. package/dist/providers/data/google-vertex.json +1 -1
  205. package/dist/providers/data/google.json +1 -1
  206. package/dist/providers/data/groq.json +1 -1
  207. package/dist/providers/data/huggingface.json +1 -1
  208. package/dist/providers/data/kimi-coding.json +1 -1
  209. package/dist/providers/data/meta.json +1 -0
  210. package/dist/providers/data/minimax-cn.json +1 -1
  211. package/dist/providers/data/minimax.json +1 -1
  212. package/dist/providers/data/mistral.json +1 -1
  213. package/dist/providers/data/moonshotai-cn.json +1 -1
  214. package/dist/providers/data/moonshotai.json +1 -1
  215. package/dist/providers/data/nvidia.json +1 -1
  216. package/dist/providers/data/openai-codex.json +1 -1
  217. package/dist/providers/data/openai.json +1 -1
  218. package/dist/providers/data/opencode-go.json +1 -1
  219. package/dist/providers/data/opencode.json +1 -1
  220. package/dist/providers/data/openrouter.json +1 -1
  221. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  222. package/dist/providers/data/qwen-token-plan-individual.json +1 -1
  223. package/dist/providers/data/qwen-token-plan.json +1 -1
  224. package/dist/providers/data/radius.json +1 -0
  225. package/dist/providers/data/together.json +1 -1
  226. package/dist/providers/data/typesafe.json +1 -0
  227. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  228. package/dist/providers/data/xai.json +1 -1
  229. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  230. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  231. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  232. package/dist/providers/data/xiaomi.json +1 -1
  233. package/dist/providers/data/zai-coding-cn.json +1 -1
  234. package/dist/providers/data/zai.json +1 -1
  235. package/dist/providers/deepseek.models.d.ts +4 -3
  236. package/dist/providers/deepseek.models.d.ts.map +1 -1
  237. package/dist/providers/deepseek.models.js +4 -2
  238. package/dist/providers/deepseek.models.js.map +1 -1
  239. package/dist/providers/faux.d.ts +3 -2
  240. package/dist/providers/faux.d.ts.map +1 -1
  241. package/dist/providers/faux.js +12 -11
  242. package/dist/providers/faux.js.map +1 -1
  243. package/dist/providers/fireworks.models.d.ts +4 -3
  244. package/dist/providers/fireworks.models.d.ts.map +1 -1
  245. package/dist/providers/fireworks.models.js +4 -2
  246. package/dist/providers/fireworks.models.js.map +1 -1
  247. package/dist/providers/github-copilot.models.d.ts +4 -3
  248. package/dist/providers/github-copilot.models.d.ts.map +1 -1
  249. package/dist/providers/github-copilot.models.js +4 -2
  250. package/dist/providers/github-copilot.models.js.map +1 -1
  251. package/dist/providers/google-vertex.models.d.ts +4 -3
  252. package/dist/providers/google-vertex.models.d.ts.map +1 -1
  253. package/dist/providers/google-vertex.models.js +4 -2
  254. package/dist/providers/google-vertex.models.js.map +1 -1
  255. package/dist/providers/google.models.d.ts +4 -3
  256. package/dist/providers/google.models.d.ts.map +1 -1
  257. package/dist/providers/google.models.js +4 -2
  258. package/dist/providers/google.models.js.map +1 -1
  259. package/dist/providers/groq.models.d.ts +4 -3
  260. package/dist/providers/groq.models.d.ts.map +1 -1
  261. package/dist/providers/groq.models.js +4 -2
  262. package/dist/providers/groq.models.js.map +1 -1
  263. package/dist/providers/huggingface.models.d.ts +4 -3
  264. package/dist/providers/huggingface.models.d.ts.map +1 -1
  265. package/dist/providers/huggingface.models.js +4 -2
  266. package/dist/providers/huggingface.models.js.map +1 -1
  267. package/dist/providers/images/register-builtins.d.ts +1 -1
  268. package/dist/providers/images/register-builtins.d.ts.map +1 -1
  269. package/dist/providers/images/register-builtins.js.map +1 -1
  270. package/dist/providers/kimi-coding.models.d.ts +4 -3
  271. package/dist/providers/kimi-coding.models.d.ts.map +1 -1
  272. package/dist/providers/kimi-coding.models.js +4 -2
  273. package/dist/providers/kimi-coding.models.js.map +1 -1
  274. package/dist/providers/meta.d.ts +3 -0
  275. package/dist/providers/meta.d.ts.map +1 -0
  276. package/dist/providers/meta.js +24 -0
  277. package/dist/providers/meta.js.map +1 -0
  278. package/dist/providers/meta.models.d.ts +5 -0
  279. package/dist/providers/meta.models.d.ts.map +1 -0
  280. package/dist/providers/meta.models.js +8 -0
  281. package/dist/providers/meta.models.js.map +1 -0
  282. package/dist/providers/minimax-cn.models.d.ts +4 -3
  283. package/dist/providers/minimax-cn.models.d.ts.map +1 -1
  284. package/dist/providers/minimax-cn.models.js +4 -2
  285. package/dist/providers/minimax-cn.models.js.map +1 -1
  286. package/dist/providers/minimax.models.d.ts +4 -3
  287. package/dist/providers/minimax.models.d.ts.map +1 -1
  288. package/dist/providers/minimax.models.js +4 -2
  289. package/dist/providers/minimax.models.js.map +1 -1
  290. package/dist/providers/mistral.models.d.ts +4 -3
  291. package/dist/providers/mistral.models.d.ts.map +1 -1
  292. package/dist/providers/mistral.models.js +4 -2
  293. package/dist/providers/mistral.models.js.map +1 -1
  294. package/dist/providers/moonshotai-cn.models.d.ts +4 -3
  295. package/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
  296. package/dist/providers/moonshotai-cn.models.js +4 -2
  297. package/dist/providers/moonshotai-cn.models.js.map +1 -1
  298. package/dist/providers/moonshotai.models.d.ts +4 -3
  299. package/dist/providers/moonshotai.models.d.ts.map +1 -1
  300. package/dist/providers/moonshotai.models.js +4 -2
  301. package/dist/providers/moonshotai.models.js.map +1 -1
  302. package/dist/providers/nvidia.models.d.ts +4 -3
  303. package/dist/providers/nvidia.models.d.ts.map +1 -1
  304. package/dist/providers/nvidia.models.js +4 -2
  305. package/dist/providers/nvidia.models.js.map +1 -1
  306. package/dist/providers/openai-codex.models.d.ts +4 -3
  307. package/dist/providers/openai-codex.models.d.ts.map +1 -1
  308. package/dist/providers/openai-codex.models.js +4 -2
  309. package/dist/providers/openai-codex.models.js.map +1 -1
  310. package/dist/providers/openai.models.d.ts +4 -3
  311. package/dist/providers/openai.models.d.ts.map +1 -1
  312. package/dist/providers/openai.models.js +4 -2
  313. package/dist/providers/openai.models.js.map +1 -1
  314. package/dist/providers/opencode-go.models.d.ts +4 -3
  315. package/dist/providers/opencode-go.models.d.ts.map +1 -1
  316. package/dist/providers/opencode-go.models.js +4 -2
  317. package/dist/providers/opencode-go.models.js.map +1 -1
  318. package/dist/providers/opencode.models.d.ts +4 -3
  319. package/dist/providers/opencode.models.d.ts.map +1 -1
  320. package/dist/providers/opencode.models.js +4 -2
  321. package/dist/providers/opencode.models.js.map +1 -1
  322. package/dist/providers/openrouter.d.ts.map +1 -1
  323. package/dist/providers/openrouter.js +11 -2
  324. package/dist/providers/openrouter.js.map +1 -1
  325. package/dist/providers/openrouter.models.d.ts +4 -3
  326. package/dist/providers/openrouter.models.d.ts.map +1 -1
  327. package/dist/providers/openrouter.models.js +4 -2
  328. package/dist/providers/openrouter.models.js.map +1 -1
  329. package/dist/providers/qwen-token-plan-cn.models.d.ts +4 -3
  330. package/dist/providers/qwen-token-plan-cn.models.d.ts.map +1 -1
  331. package/dist/providers/qwen-token-plan-cn.models.js +4 -2
  332. package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
  333. package/dist/providers/qwen-token-plan-individual.models.d.ts +4 -3
  334. package/dist/providers/qwen-token-plan-individual.models.d.ts.map +1 -1
  335. package/dist/providers/qwen-token-plan-individual.models.js +4 -2
  336. package/dist/providers/qwen-token-plan-individual.models.js.map +1 -1
  337. package/dist/providers/qwen-token-plan.models.d.ts +4 -3
  338. package/dist/providers/qwen-token-plan.models.d.ts.map +1 -1
  339. package/dist/providers/qwen-token-plan.models.js +4 -2
  340. package/dist/providers/qwen-token-plan.models.js.map +1 -1
  341. package/dist/providers/radius.d.ts.map +1 -1
  342. package/dist/providers/radius.js +19 -5
  343. package/dist/providers/radius.js.map +1 -1
  344. package/dist/providers/radius.models.d.ts +5 -0
  345. package/dist/providers/radius.models.d.ts.map +1 -0
  346. package/dist/providers/radius.models.js +8 -0
  347. package/dist/providers/radius.models.js.map +1 -0
  348. package/dist/providers/together.models.d.ts +4 -3
  349. package/dist/providers/together.models.d.ts.map +1 -1
  350. package/dist/providers/together.models.js +4 -2
  351. package/dist/providers/together.models.js.map +1 -1
  352. package/dist/providers/typesafe.d.ts +3 -0
  353. package/dist/providers/typesafe.d.ts.map +1 -0
  354. package/dist/providers/typesafe.js +18 -0
  355. package/dist/providers/typesafe.js.map +1 -0
  356. package/dist/providers/typesafe.models.d.ts +5 -0
  357. package/dist/providers/typesafe.models.d.ts.map +1 -0
  358. package/dist/providers/typesafe.models.js +8 -0
  359. package/dist/providers/typesafe.models.js.map +1 -0
  360. package/dist/providers/vercel-ai-gateway.models.d.ts +4 -3
  361. package/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  362. package/dist/providers/vercel-ai-gateway.models.js +4 -2
  363. package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  364. package/dist/providers/xai.models.d.ts +4 -3
  365. package/dist/providers/xai.models.d.ts.map +1 -1
  366. package/dist/providers/xai.models.js +4 -2
  367. package/dist/providers/xai.models.js.map +1 -1
  368. package/dist/providers/xiaomi-token-plan-ams.models.d.ts +4 -3
  369. package/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
  370. package/dist/providers/xiaomi-token-plan-ams.models.js +4 -2
  371. package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
  372. package/dist/providers/xiaomi-token-plan-cn.models.d.ts +4 -3
  373. package/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
  374. package/dist/providers/xiaomi-token-plan-cn.models.js +4 -2
  375. package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
  376. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts +4 -3
  377. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
  378. package/dist/providers/xiaomi-token-plan-sgp.models.js +4 -2
  379. package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
  380. package/dist/providers/xiaomi.models.d.ts +4 -3
  381. package/dist/providers/xiaomi.models.d.ts.map +1 -1
  382. package/dist/providers/xiaomi.models.js +4 -2
  383. package/dist/providers/xiaomi.models.js.map +1 -1
  384. package/dist/providers/zai-coding-cn.models.d.ts +4 -3
  385. package/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
  386. package/dist/providers/zai-coding-cn.models.js +4 -2
  387. package/dist/providers/zai-coding-cn.models.js.map +1 -1
  388. package/dist/providers/zai.models.d.ts +4 -3
  389. package/dist/providers/zai.models.d.ts.map +1 -1
  390. package/dist/providers/zai.models.js +4 -2
  391. package/dist/providers/zai.models.js.map +1 -1
  392. package/dist/types.d.ts +227 -51
  393. package/dist/types.d.ts.map +1 -1
  394. package/dist/types.js.map +1 -1
  395. package/dist/utils/diagnostics.d.ts +3 -2
  396. package/dist/utils/diagnostics.d.ts.map +1 -1
  397. package/dist/utils/diagnostics.js.map +1 -1
  398. package/dist/utils/estimate.d.ts +2 -2
  399. package/dist/utils/estimate.d.ts.map +1 -1
  400. package/dist/utils/estimate.js +8 -29
  401. package/dist/utils/estimate.js.map +1 -1
  402. package/dist/utils/headers.d.ts +1 -1
  403. package/dist/utils/headers.d.ts.map +1 -1
  404. package/dist/utils/headers.js +10 -8
  405. package/dist/utils/headers.js.map +1 -1
  406. package/dist/utils/model-operations.d.ts +11 -0
  407. package/dist/utils/model-operations.d.ts.map +1 -0
  408. package/dist/utils/model-operations.js +47 -0
  409. package/dist/utils/model-operations.js.map +1 -0
  410. package/dist/utils/models-error.d.ts +8 -0
  411. package/dist/utils/models-error.d.ts.map +1 -0
  412. package/dist/utils/models-error.js +19 -0
  413. package/dist/utils/models-error.js.map +1 -0
  414. package/dist/utils/overflow.d.ts +1 -0
  415. package/dist/utils/overflow.d.ts.map +1 -1
  416. package/dist/utils/overflow.js +17 -5
  417. package/dist/utils/overflow.js.map +1 -1
  418. package/dist/utils/retry.d.ts.map +1 -1
  419. package/dist/utils/retry.js +2 -0
  420. package/dist/utils/retry.js.map +1 -1
  421. package/dist/utils/text.d.ts +9 -1
  422. package/dist/utils/text.d.ts.map +1 -1
  423. package/dist/utils/text.js +26 -0
  424. package/dist/utils/text.js.map +1 -1
  425. package/dist/utils/transcript.d.ts +84 -0
  426. package/dist/utils/transcript.d.ts.map +1 -0
  427. package/dist/utils/transcript.js +204 -0
  428. package/dist/utils/transcript.js.map +1 -0
  429. package/package.json +4 -4
  430. package/dist/image-models.generated.d.ts +0 -785
  431. package/dist/image-models.generated.d.ts.map +0 -1
  432. package/dist/image-models.generated.js +0 -787
  433. package/dist/image-models.generated.js.map +0 -1
  434. package/dist/images-models.d.ts +0 -95
  435. package/dist/images-models.d.ts.map +0 -1
  436. package/dist/images-models.js +0 -143
  437. package/dist/images-models.js.map +0 -1
  438. package/dist/providers/openrouter-images.d.ts +0 -3
  439. package/dist/providers/openrouter-images.d.ts.map +0 -1
  440. package/dist/providers/openrouter-images.js +0 -22
  441. package/dist/providers/openrouter-images.js.map +0 -1
  442. package/dist/utils/deferred-tools.d.ts +0 -9
  443. package/dist/utils/deferred-tools.d.ts.map +0 -1
  444. package/dist/utils/deferred-tools.js +0 -36
  445. package/dist/utils/deferred-tools.js.map +0 -1
@@ -1,6 +1,5 @@
1
1
  import Anthropic from "@anthropic-ai/sdk";
2
2
  import { calculateCost } from "../models.js";
3
- import { splitDeferredTools } from "../utils/deferred-tools.js";
4
3
  import { appendAssistantMessageDiagnostic } from "../utils/diagnostics.js";
5
4
  import { assertSupportedDocumentMimeType } from "../utils/document-input.js";
6
5
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
@@ -11,7 +10,9 @@ import { getProviderEnvValue } from "../utils/provider-env.js";
11
10
  import { retryProviderRequest } from "../utils/provider-retry.js";
12
11
  import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
13
12
  import { createStreamDeadline, withStreamDeadline } from "../utils/stream-deadline.js";
14
- import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
13
+ import { getSystemMessageText, renderSystemMessageUpdate } from "../utils/text.js";
14
+ import { getCurrentTools, getDeclaredTools, getInitialSystemMessage, hasToolRedefinitions, resolveTranscript, } from "../utils/transcript.js";
15
+ import { ANTHROPIC_STRICT_JSON_SCHEMA_PROFILE, getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
15
16
  import { buildCopilotDynamicHeaders, hasCopilotVisionInput, preserveCopilotIntegrationHeader, } from "./github-copilot-headers.js";
16
17
  import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext } from "./simple-options.js";
17
18
  import { transformMessages } from "./transform-messages.js";
@@ -42,13 +43,13 @@ function getCacheControl(model, cacheRetention, env) {
42
43
  // Stealth mode: Mimic Claude Code's tool naming exactly
43
44
  //
44
45
  // Anthropic gates newer models on the `claude-cli/<version>` user agent alone and rejects an
45
- // older one with `claude_code_version_too_old`. `claude-fable-5-1` requires >= 2.1.251, bisected
46
- // against the live API: 2.1.250 -> 400, 2.1.251 -> 200. This is pinned to that exact published
47
- // minimum rather than the newest release, and it is a strict superset of the previous 2.1.75 --
48
- // every model this provider ships answers 200 at 2.1.251. Raise it only when a model rejects
49
- // this value; a caller can override it for one client through the `headers` option, whose
50
- // lowercase `user-agent` key is merged last.
51
- const claudeCodeVersion = "2.1.251";
46
+ // older one with `claude_code_version_too_old`. `claude-fable-5-1` requires >= 2.1.251 (bisected
47
+ // against the live API: 2.1.250 -> 400, 2.1.251 -> 200) and Claude Opus 5.5 requires >= 2.1.280,
48
+ // the floor the API names in its rejection. This is pinned to the highest published minimum
49
+ // among shipped models rather than the newest release; every model this provider ships answers
50
+ // 200 at 2.1.280. Raise it only when a model rejects this value; a caller can override it for
51
+ // one client through the `headers` option, whose lowercase `user-agent` key is merged last.
52
+ const claudeCodeVersion = "2.1.280";
52
53
  // Claude Code 2.x tool names (canonical casing)
53
54
  // Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md
54
55
  // To update: https://github.com/badlogic/cchistory
@@ -127,6 +128,75 @@ const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
127
128
  const SERVER_SIDE_FALLBACK_BETA = "server-side-fallback-2026-07-01";
128
129
  const THINKING_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
129
130
  const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
131
+ const MID_CONVERSATION_TOOL_CHANGES_BETA = "mid-conversation-tool-changes-2026-07-01";
132
+ const FAST_MODE_BETA = "fast-mode-2026-02-01";
133
+ /**
134
+ * Fast mode bills every token category at twice the standard rate for each supported model, across
135
+ * the full context window, and prompt-caching multipliers stack on top.
136
+ * https://platform.claude.com/docs/en/build-with-claude/fast-mode#pricing
137
+ */
138
+ const FAST_MODE_PRICE_MULTIPLIER = 2;
139
+ function requestedSpeed(model) {
140
+ return model.fastRoute?.speed;
141
+ }
142
+ function upstreamModelId(model) {
143
+ return model.fastRoute?.upstreamModelId ?? model.id;
144
+ }
145
+ function reportedSpeed(usage) {
146
+ const speed = usage?.speed;
147
+ return speed === "fast" || speed === "standard" ? speed : undefined;
148
+ }
149
+ function applyFastModePricing(usage) {
150
+ usage.cost.input *= FAST_MODE_PRICE_MULTIPLIER;
151
+ usage.cost.output *= FAST_MODE_PRICE_MULTIPLIER;
152
+ usage.cost.cacheRead *= FAST_MODE_PRICE_MULTIPLIER;
153
+ usage.cost.cacheWrite *= FAST_MODE_PRICE_MULTIPLIER;
154
+ usage.cost.total = usage.cost.input + usage.cost.output + usage.cost.cacheRead + usage.cost.cacheWrite;
155
+ }
156
+ /**
157
+ * Reject a payload hook that rewrote a field the model's fast route owns.
158
+ *
159
+ * A fast variant is recorded, persisted, and billed under its own `-fast` identity, so a hook that
160
+ * changes the upstream model or drops `speed: "fast"` would send a different request under that
161
+ * identity. Refusing loudly surfaces the misconfigured hook instead of silently restoring the route.
162
+ */
163
+ function assertPayloadPreservesFastRoute(model, payload) {
164
+ const fastRoute = model.fastRoute;
165
+ if (fastRoute?.speed === undefined)
166
+ return;
167
+ const remedy = `A fast model variant must send its route's upstream model and speed, because it is recorded, persisted, ` +
168
+ `and billed under its own identity. Select the normal model "${model.provider}/${fastRoute.baseModelId}" ` +
169
+ `if the request needs different routing`;
170
+ if (typeof payload !== "object" || payload === null || Array.isArray(payload)) {
171
+ throw new Error(`A request hook changed payload for fast model "${model.provider}/${model.id}" to a value that cannot carry ` +
172
+ `the route's upstream model and speed. ${remedy}, or return an object that preserves those fields.`);
173
+ }
174
+ const record = payload;
175
+ const conflicts = [];
176
+ if (record.model !== fastRoute.upstreamModelId) {
177
+ conflicts.push(`model (expected "${fastRoute.upstreamModelId}", got ${JSON.stringify(record.model)})`);
178
+ }
179
+ if (record.speed !== fastRoute.speed) {
180
+ conflicts.push(`speed (expected ${JSON.stringify(fastRoute.speed)}, got ${JSON.stringify(record.speed)})`);
181
+ }
182
+ if (conflicts.length === 0)
183
+ return;
184
+ throw new Error(`A request hook changed ${conflicts.join(" and ")} for fast model "${model.provider}/${model.id}". ` +
185
+ `${remedy}, or stop rewriting those fields.`);
186
+ }
187
+ /**
188
+ * Stable deferred tool declared whenever native tool changes are in use. Anthropic adds
189
+ * hidden prompt scaffolding as soon as any tool has `defer_loading`; declaring this
190
+ * placeholder from the first request keeps that scaffolding in the cached prefix, so the
191
+ * first real late tool does not invalidate the cache (measured: full miss without it).
192
+ * It is never activated and the model cannot see it.
193
+ */
194
+ const DEFERRED_TOOL_PLACEHOLDER = {
195
+ name: "__pi_deferred_placeholder__",
196
+ description: "Reserved placeholder. Never available. Never call this.",
197
+ input_schema: { type: "object", properties: {}, required: [] },
198
+ defer_loading: true,
199
+ };
130
200
  function shouldUseServerSideFallbackBeta(model) {
131
201
  return (model.compat?.allowedFallbackModels?.length ?? 0) > 0;
132
202
  }
@@ -205,7 +275,7 @@ function addEarlierAttemptCosts(output, model, servingModel, event) {
205
275
  if (!iteration.output_tokens)
206
276
  continue;
207
277
  // Price at the rates of the model that ran the attempt, which is not the serving model.
208
- const attemptCost = iteration.model === model.id
278
+ const attemptCost = iteration.model === upstreamModelId(model)
209
279
  ? model.cost
210
280
  : iteration.model === servingModel.id
211
281
  ? servingModel.cost
@@ -244,24 +314,10 @@ function getAnthropicCompat(model) {
244
314
  supportsTemperature: model.compat?.supportsTemperature ?? true,
245
315
  allowEmptySignature: model.compat?.allowEmptySignature ?? false,
246
316
  supportsStrictTools: model.compat?.supportsStrictTools ?? false,
247
- supportsToolReferences: model.compat?.supportsToolReferences ?? defaultSupportsToolReferences(model),
317
+ supportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,
318
+ supportsMidConvoToolChanges: model.compat?.supportsMidConvoToolChanges ?? false,
248
319
  };
249
320
  }
250
- /**
251
- * Default for `supportsToolReferences`: first-party Anthropic models except
252
- * Haiku (rejects client-side tool_reference blocks) and models that predate
253
- * tool search (Claude 3.x, Opus/Sonnet 4.0, Opus 4.1).
254
- */
255
- function defaultSupportsToolReferences(model) {
256
- if (model.provider !== "anthropic" || model.id.includes("haiku"))
257
- return false;
258
- const version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\d+)(?:-(\d+))?(?:-|$)/);
259
- if (!version)
260
- return false;
261
- const major = Number(version[1]);
262
- const minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;
263
- return major > 4 || (major === 4 && minor >= 5);
264
- }
265
321
  function mergeHeaders(...headerSources) {
266
322
  const merged = {};
267
323
  for (const headers of headerSources) {
@@ -456,6 +512,8 @@ async function* iterateAnthropicEvents(response, signal) {
456
512
  }
457
513
  export const stream = (model, context, options) => {
458
514
  const stream = new AssistantMessageEventStream();
515
+ const normalizedContext = resolveTranscript(context, getAnthropicCompat(model).supportsMidConvoSystemMessages);
516
+ const currentTools = getCurrentTools(normalizedContext.messages);
459
517
  (async () => {
460
518
  const providerThinkingLevel = supportsMidConvoEffort(model) ? (options?.effort ?? "high") : undefined;
461
519
  const output = {
@@ -482,6 +540,7 @@ export const stream = (model, context, options) => {
482
540
  let client;
483
541
  let isOAuth;
484
542
  let usageModel = model;
543
+ let servedSpeed = requestedSpeed(model);
485
544
  if (options?.client) {
486
545
  client = options.client;
487
546
  isOAuth = false;
@@ -491,30 +550,34 @@ export const stream = (model, context, options) => {
491
550
  assertRequestAuth(model.provider, apiKey, options?.headers);
492
551
  let copilotDynamicHeaders;
493
552
  if (model.provider === "github-copilot") {
494
- const hasImages = hasCopilotVisionInput(context.messages);
553
+ const hasImages = hasCopilotVisionInput(normalizedContext.messages);
495
554
  copilotDynamicHeaders = preserveCopilotIntegrationHeader(model.headers, buildCopilotDynamicHeaders({
496
- messages: context.messages,
555
+ messages: normalizedContext.messages,
497
556
  hasImages,
498
557
  apiKey,
499
558
  }));
500
559
  }
501
560
  const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
502
561
  const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
503
- const created = createClient(model, apiKey, model.reasoning && options?.thinkingEnabled === true && (options.interleavedThinking ?? true), shouldUseFineGrainedToolStreamingBeta(model, context), shouldUseServerSideFallbackBeta(model), options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId);
562
+ const created = createClient(model, apiKey, model.reasoning && options?.thinkingEnabled === true && (options.interleavedThinking ?? true), shouldUseFineGrainedToolStreamingBeta(model, context), shouldUseServerSideFallbackBeta(model), options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, getAnthropicCompat(model).supportsMidConvoToolChanges &&
563
+ getAnthropicCompat(model).supportsMidConvoSystemMessages &&
564
+ (getInitialSystemMessage(normalizedContext.messages)?.toolsAdded?.length ?? 0) > 0 &&
565
+ !hasToolRedefinitions(normalizedContext.messages));
504
566
  client = created.client;
505
567
  isOAuth = created.isOAuthToken;
506
568
  }
507
- let params = buildParams(model, context, isOAuth, options);
569
+ let params = buildParams(model, normalizedContext, isOAuth, options);
508
570
  const nextParams = await options?.onPayload?.(params, model);
509
571
  if (nextParams !== undefined) {
510
572
  params = nextParams;
511
573
  }
574
+ assertPayloadPreservesFastRoute(model, params);
512
575
  const requestOptions = {
513
576
  ...(streamDeadline.signal ? { signal: streamDeadline.signal } : {}),
514
577
  ...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
515
578
  maxRetries: 0,
516
579
  };
517
- const response = await retryProviderRequest(() => client.messages.create({ ...params, stream: true }, requestOptions).asResponse(), {
580
+ const response = await retryProviderRequest(() => client.beta.messages.create({ ...params, stream: true }, requestOptions).asResponse(), {
518
581
  maxRetries: options?.maxRetries,
519
582
  maxRetryDelayMs: options?.maxRetryDelayMs,
520
583
  signal: streamDeadline.signal,
@@ -523,13 +586,16 @@ export const stream = (model, context, options) => {
523
586
  stream.push({ type: "start", partial: output });
524
587
  const blocks = output.content;
525
588
  for await (const event of withStreamDeadline(iterateAnthropicEvents(response, streamDeadline.signal), streamDeadline.deadlineMs, streamDeadline.abort)) {
589
+ await options?.onProviderStreamEvent?.(event, model);
526
590
  if (event.type === "message_start") {
527
591
  output.responseId = event.message.id;
528
- output.model = event.message.model;
529
- const fallbackCost = output.model === model.id
592
+ const responseModel = event.message.model;
593
+ if (responseModel !== upstreamModelId(model))
594
+ output.responseModel = responseModel;
595
+ const fallbackCost = responseModel === upstreamModelId(model)
530
596
  ? undefined
531
- : model.compat?.allowedFallbackModels?.find((fallback) => fallback.provider === model.provider && fallback.model === output.model)?.cost;
532
- usageModel = fallbackCost ? { ...model, id: output.model, cost: fallbackCost } : model;
597
+ : model.compat?.allowedFallbackModels?.find((fallback) => fallback.provider === model.provider && fallback.model === responseModel)?.cost;
598
+ usageModel = fallbackCost ? { ...model, id: responseModel, cost: fallbackCost } : model;
533
599
  // Capture initial token usage from message_start event
534
600
  // This ensures we have input token counts even if the stream is aborted early
535
601
  output.usage.input = event.message.usage.input_tokens || 0;
@@ -541,6 +607,9 @@ export const stream = (model, context, options) => {
541
607
  output.usage.totalTokens =
542
608
  output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
543
609
  calculateCost(usageModel, output.usage);
610
+ servedSpeed = reportedSpeed(event.message.usage) ?? servedSpeed;
611
+ if (servedSpeed === "fast")
612
+ applyFastModePricing(output.usage);
544
613
  inputTransformations = getInputTransformations(event.message) ?? inputTransformations;
545
614
  }
546
615
  else if (event.type === "content_block_start") {
@@ -579,7 +648,7 @@ export const stream = (model, context, options) => {
579
648
  type: "toolCall",
580
649
  id: event.content_block.id,
581
650
  name: isOAuth
582
- ? fromClaudeCodeName(event.content_block.name, context.tools)
651
+ ? fromClaudeCodeName(event.content_block.name, currentTools)
583
652
  : event.content_block.name,
584
653
  arguments: event.content_block.input ?? {},
585
654
  partialJson: "",
@@ -728,6 +797,11 @@ export const stream = (model, context, options) => {
728
797
  // its Usage type, so read it through a narrow cast. Verified against the live API.
729
798
  const thinkingTokens = event.usage
730
799
  .output_tokens_details?.thinking_tokens;
800
+ // Vercel AI Gateway includes the TTL breakdown in deltas, though the SDK only types it on message_start.
801
+ const cacheCreation = event.usage.cache_creation;
802
+ if (cacheCreation?.ephemeral_1h_input_tokens != null) {
803
+ output.usage.cacheWrite1h = cacheCreation.ephemeral_1h_input_tokens;
804
+ }
731
805
  if (thinkingTokens != null) {
732
806
  output.usage.reasoning = thinkingTokens;
733
807
  }
@@ -736,6 +810,9 @@ export const stream = (model, context, options) => {
736
810
  output.usage.totalTokens =
737
811
  output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
738
812
  calculateCost(usageModel, output.usage);
813
+ servedSpeed = reportedSpeed(event.usage) ?? servedSpeed;
814
+ if (servedSpeed === "fast")
815
+ applyFastModePricing(output.usage);
739
816
  // A non-empty final fallback report supersedes the request-start report with
740
817
  // the serving model's transformations. An empty report must not erase drops
741
818
  // already reported at message_start.
@@ -839,7 +916,7 @@ export const streamSimple = (model, context, options) => {
839
916
  function isOAuthToken(apiKey) {
840
917
  return apiKey.includes("sk-ant-oat");
841
918
  }
842
- function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStreamingBeta, useServerSideFallbackBeta, optionsHeaders, fetch, dynamicHeaders, sessionId) {
919
+ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStreamingBeta, useServerSideFallbackBeta, optionsHeaders, fetch, dynamicHeaders, sessionId, useNativeToolChanges = false) {
843
920
  // Adaptive thinking models have interleaved thinking built in, so skip the beta header.
844
921
  const needsInterleavedBeta = interleavedThinking && model.compat?.forceAdaptiveThinking !== true;
845
922
  const betaFeatures = [];
@@ -858,6 +935,10 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
858
935
  if (supportsMidConvoEffort(model)) {
859
936
  betaFeatures.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA, THINKING_BINDING_CONTROLS_BETA);
860
937
  }
938
+ if (useNativeToolChanges)
939
+ betaFeatures.push(MID_CONVERSATION_TOOL_CHANGES_BETA);
940
+ if (requestedSpeed(model) === "fast")
941
+ betaFeatures.push(FAST_MODE_BETA);
861
942
  const uniqueBetaFeatures = [...new Set(betaFeatures)];
862
943
  // Copilot: Bearer auth, selective betas.
863
944
  if (model.provider === "github-copilot") {
@@ -915,29 +996,74 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
915
996
  });
916
997
  return { client, isOAuthToken: false };
917
998
  }
999
+ function getNativeToolChangeBetas(model, context, isOAuth, options) {
1000
+ let configured;
1001
+ for (const headers of [model.headers, options?.headers]) {
1002
+ for (const [name, value] of Object.entries(headers ?? {})) {
1003
+ if (name.toLowerCase() === "anthropic-beta")
1004
+ configured = value;
1005
+ }
1006
+ }
1007
+ if (configured === null)
1008
+ return [];
1009
+ if (configured !== undefined)
1010
+ return [
1011
+ ...new Set(configured
1012
+ .split(",")
1013
+ .map((feature) => feature.trim())
1014
+ .filter(Boolean)),
1015
+ ];
1016
+ const features = [MID_CONVERSATION_TOOL_CHANGES_BETA];
1017
+ if (isOAuth)
1018
+ features.push("claude-code-20250219", "oauth-2025-04-20");
1019
+ if (shouldUseFineGrainedToolStreamingBeta(model, context))
1020
+ features.push(FINE_GRAINED_TOOL_STREAMING_BETA);
1021
+ if (model.reasoning &&
1022
+ options?.thinkingEnabled &&
1023
+ (options.interleavedThinking ?? true) &&
1024
+ model.compat?.forceAdaptiveThinking !== true) {
1025
+ features.push(INTERLEAVED_THINKING_BETA);
1026
+ }
1027
+ if (shouldUseServerSideFallbackBeta(model))
1028
+ features.push(SERVER_SIDE_FALLBACK_BETA);
1029
+ if (shouldUseThinkingBindingControlsBeta(model))
1030
+ features.push(THINKING_BINDING_CONTROLS_BETA);
1031
+ if (supportsMidConvoEffort(model))
1032
+ features.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA, THINKING_BINDING_CONTROLS_BETA);
1033
+ if (requestedSpeed(model) === "fast")
1034
+ features.push(FAST_MODE_BETA);
1035
+ return [...new Set(features)];
1036
+ }
918
1037
  function buildParams(model, context, isOAuthToken, options) {
919
1038
  const { cacheControl } = getCacheControl(model, options?.cacheRetention, options?.env);
920
1039
  const compat = getAnthropicCompat(model);
1040
+ const initialSystemMessage = getInitialSystemMessage(context.messages);
1041
+ const initialSystemText = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : "";
921
1042
  const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
922
- const normalizeToolName = isOAuthToken ? toClaudeCodeName : (name) => name;
923
- const toolPlacement = splitDeferredTools({ ...context, messages: transformedMessages }, compat.supportsToolReferences, normalizeToolName);
924
- let immediateTools = toolPlacement.immediate;
925
- let deferredTools = [...toolPlacement.deferred.values()];
926
- if (immediateTools.length === 0 && deferredTools.length > 0) {
927
- immediateTools = deferredTools;
928
- deferredTools = [];
929
- }
930
- const deferredToolNames = new Set(deferredTools.map((tool) => normalizeToolName(tool.name)));
931
- const converted = convertMessages(transformedMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, deferredToolNames, normalizeToolName, supportsMidConvoEffort(model) ? model.provider : undefined);
1043
+ const conversationMessages = initialSystemMessage ? transformedMessages.slice(1) : transformedMessages;
1044
+ // Native tool changes reference tools by name, so a redefined name cannot be expressed,
1045
+ // and Anthropic rejects a tool list where every tool is deferred, so there must be an
1046
+ // initial active tool to anchor the deferred ones. Otherwise the current tool list is sent.
1047
+ const initialTools = initialSystemMessage?.toolsAdded ?? [];
1048
+ const nativeToolChanges = compat.supportsMidConvoSystemMessages &&
1049
+ compat.supportsMidConvoToolChanges &&
1050
+ initialTools.length > 0 &&
1051
+ !hasToolRedefinitions(context.messages);
1052
+ const converted = convertMessages(conversationMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, supportsMidConvoEffort(model) ? model.provider : undefined, nativeToolChanges);
932
1053
  const activeEffort = options?.effort ?? "high";
933
1054
  const params = {
934
- model: model.id,
1055
+ model: upstreamModelId(model),
935
1056
  messages: (supportsMidConvoEffort(model)
936
1057
  ? insertThinkingLevelMessages(converted, activeEffort)
937
1058
  : converted.messages),
938
1059
  max_tokens: options?.maxTokens ?? model.maxTokens,
939
1060
  stream: true,
940
1061
  };
1062
+ if (nativeToolChanges)
1063
+ params.betas = getNativeToolChangeBetas(model, context, isOAuthToken, options);
1064
+ const speed = requestedSpeed(model);
1065
+ if (speed !== undefined)
1066
+ params.speed = speed;
941
1067
  // For OAuth tokens, we MUST include Claude Code identity
942
1068
  if (isOAuthToken) {
943
1069
  params.system = [
@@ -947,20 +1073,20 @@ function buildParams(model, context, isOAuthToken, options) {
947
1073
  ...(cacheControl ? { cache_control: cacheControl } : {}),
948
1074
  },
949
1075
  ];
950
- if (context.systemPrompt) {
1076
+ if (initialSystemText) {
951
1077
  params.system.push({
952
1078
  type: "text",
953
- text: sanitizeSurrogates(context.systemPrompt),
1079
+ text: sanitizeSurrogates(initialSystemText),
954
1080
  ...(cacheControl ? { cache_control: cacheControl } : {}),
955
1081
  });
956
1082
  }
957
1083
  }
958
- else if (context.systemPrompt) {
1084
+ else if (initialSystemText) {
959
1085
  // Add cache control to system prompt for non-OAuth tokens
960
1086
  params.system = [
961
1087
  {
962
1088
  type: "text",
963
- text: sanitizeSurrogates(context.systemPrompt),
1089
+ text: sanitizeSurrogates(initialSystemText),
964
1090
  ...(cacheControl ? { cache_control: cacheControl } : {}),
965
1091
  },
966
1092
  ];
@@ -972,12 +1098,26 @@ function buildParams(model, context, isOAuthToken, options) {
972
1098
  compat.supportsTemperature) {
973
1099
  params.temperature = options.temperature;
974
1100
  }
975
- if (immediateTools.length > 0 || deferredTools.length > 0) {
1101
+ const toolCacheControl = compat.supportsCacheControlOnTools ? cacheControl : undefined;
1102
+ if (nativeToolChanges) {
1103
+ // Initial tools stay active with the cache breakpoint on the last one. Every later
1104
+ // declaration is deferred and only surfaced by its `tool_addition` block; removed
1105
+ // tools stay declared and are withdrawn by `tool_removal`. The request-level list
1106
+ // therefore only grows, keeping the cached prefix intact across tool changes.
1107
+ const initialNames = new Set(initialTools.map((tool) => tool.name));
1108
+ const laterTools = getDeclaredTools(context.messages).filter((tool) => !initialNames.has(tool.name));
976
1109
  params.tools = [
977
- ...convertTools(immediateTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, compat.supportsCacheControlOnTools ? cacheControl : undefined),
978
- ...convertTools(deferredTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, undefined, true),
1110
+ ...convertTools(initialTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl),
1111
+ DEFERRED_TOOL_PLACEHOLDER,
1112
+ ...convertTools(laterTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools).map((tool) => ({ ...tool, defer_loading: true })),
979
1113
  ];
980
1114
  }
1115
+ else {
1116
+ const tools = getCurrentTools(context.messages);
1117
+ if (tools.length > 0) {
1118
+ params.tools = convertTools(tools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl);
1119
+ }
1120
+ }
981
1121
  // Managed effort models always use adaptive thinking. Their per-turn markers
982
1122
  // carry the actual effort; the top-level high value deliberately stays stable.
983
1123
  if (supportsMidConvoEffort(model)) {
@@ -1082,41 +1222,54 @@ function buildParams(model, context, isOAuthToken, options) {
1082
1222
  function normalizeToolCallId(id) {
1083
1223
  return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
1084
1224
  }
1085
- function convertToolResult(msg, isOAuthToken, deferredToolNames, loadedToolNames, normalizeToolName) {
1086
- const references = [];
1087
- for (const name of msg.addedToolNames ?? []) {
1088
- const normalizedName = normalizeToolName(name);
1089
- if (!deferredToolNames.has(normalizedName) || loadedToolNames.has(normalizedName))
1090
- continue;
1091
- loadedToolNames.add(normalizedName);
1092
- references.push({
1093
- type: "tool_reference",
1094
- tool_name: isOAuthToken ? toClaudeCodeName(name) : name,
1095
- });
1096
- }
1097
- const convertedContent = convertContentBlocks(msg.content);
1098
- // Anthropic rejects tool references mixed with ordinary tool-result content.
1225
+ function convertToolResult(msg) {
1099
1226
  return {
1100
- toolResult: {
1101
- type: "tool_result",
1102
- tool_use_id: msg.toolCallId,
1103
- content: references.length > 0 ? references : convertedContent,
1104
- is_error: msg.isError,
1105
- },
1106
- siblingContent: references.length === 0
1107
- ? []
1108
- : typeof convertedContent === "string"
1109
- ? [{ type: "text", text: convertedContent }]
1110
- : convertedContent,
1227
+ type: "tool_result",
1228
+ tool_use_id: msg.toolCallId,
1229
+ content: convertContentBlocks(msg.content),
1230
+ is_error: msg.isError,
1111
1231
  };
1112
1232
  }
1113
- function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, deferredToolNames = new Set(), normalizeToolName = (name) => name, managedProvider) {
1233
+ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, managedProvider, nativeToolChanges = false) {
1114
1234
  const params = [];
1115
1235
  const assistantLevels = new Map();
1116
- const loadedToolNames = new Set();
1236
+ // Later system messages are held back and emitted directly before the next assistant
1237
+ // message (or at the end of the transcript). Anthropic requires `tool_result` blocks to
1238
+ // immediately follow their `tool_use`, so a system message between them is rejected; this
1239
+ // also mirrors where the managed-effort system messages are inserted. As a result an
1240
+ // update placed before a user message in the transcript lands after it on the wire.
1241
+ const pendingSystemMessages = [];
1242
+ const flushPendingSystemMessages = () => {
1243
+ params.push(...pendingSystemMessages);
1244
+ pendingSystemMessages.length = 0;
1245
+ };
1117
1246
  for (let i = 0; i < transformedMessages.length; i++) {
1118
1247
  const msg = transformedMessages[i];
1119
- if (msg.role === "user") {
1248
+ if (msg.role === "system") {
1249
+ // Later system messages only reach this point when the model accepts them natively;
1250
+ // otherwise the transcript was collapsed into the leading message before conversion.
1251
+ const text = renderSystemMessageUpdate(msg);
1252
+ const blocks = [];
1253
+ if (text.length > 0)
1254
+ blocks.push({ type: "text", text: sanitizeSurrogates(text) });
1255
+ if (nativeToolChanges) {
1256
+ for (const tool of msg.toolsRemoved ?? []) {
1257
+ blocks.push({
1258
+ type: "tool_removal",
1259
+ tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
1260
+ });
1261
+ }
1262
+ for (const tool of msg.toolsAdded ?? []) {
1263
+ blocks.push({
1264
+ type: "tool_addition",
1265
+ tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
1266
+ });
1267
+ }
1268
+ }
1269
+ if (blocks.length > 0)
1270
+ pendingSystemMessages.push({ role: "system", content: blocks });
1271
+ }
1272
+ else if (msg.role === "user") {
1120
1273
  if (typeof msg.content === "string") {
1121
1274
  if (msg.content.trim().length > 0) {
1122
1275
  params.push({
@@ -1173,6 +1326,7 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
1173
1326
  }
1174
1327
  }
1175
1328
  else if (msg.role === "assistant") {
1329
+ flushPendingSystemMessages();
1176
1330
  const blocks = [];
1177
1331
  for (const block of msg.content) {
1178
1332
  if (block.type === "text") {
@@ -1261,31 +1415,32 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
1261
1415
  else if (msg.role === "toolResult") {
1262
1416
  // Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint.
1263
1417
  const toolResults = [];
1264
- const siblingContent = [];
1265
1418
  let j = i;
1266
1419
  while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
1267
- const converted = convertToolResult(transformedMessages[j], isOAuthToken, deferredToolNames, loadedToolNames, normalizeToolName);
1268
- toolResults.push(converted.toolResult);
1269
- siblingContent.push(...converted.siblingContent);
1420
+ toolResults.push(convertToolResult(transformedMessages[j]));
1270
1421
  j++;
1271
1422
  }
1272
1423
  // Skip the messages we've already processed.
1273
1424
  i = j - 1;
1274
- // Displaced reference-bearing results must follow every tool_result block.
1275
1425
  params.push({
1276
1426
  role: "user",
1277
- content: [...toolResults, ...siblingContent],
1427
+ content: toolResults,
1278
1428
  });
1279
1429
  }
1280
1430
  }
1281
- // Add cache_control to the last user message to cache conversation history
1431
+ flushPendingSystemMessages();
1432
+ // Add cache_control to the last user or system message to cache conversation history
1282
1433
  if (cacheControl && params.length > 0) {
1283
1434
  const lastMessage = params[params.length - 1];
1284
- if (lastMessage.role === "user") {
1435
+ if (lastMessage.role === "user" || lastMessage.role === "system") {
1285
1436
  if (Array.isArray(lastMessage.content)) {
1286
1437
  const lastBlock = lastMessage.content[lastMessage.content.length - 1];
1287
1438
  if (lastBlock &&
1288
- (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
1439
+ (lastBlock.type === "text" ||
1440
+ lastBlock.type === "image" ||
1441
+ lastBlock.type === "tool_result" ||
1442
+ lastBlock.type === "tool_addition" ||
1443
+ lastBlock.type === "tool_removal")) {
1289
1444
  lastBlock.cache_control = cacheControl;
1290
1445
  }
1291
1446
  }
@@ -1318,7 +1473,7 @@ function insertThinkingLevelMessages(converted, activeEffort) {
1318
1473
  return messages;
1319
1474
  }
1320
1475
  function shouldUseFineGrainedToolStreamingBeta(model, context) {
1321
- return !!context.tools?.length && !getAnthropicCompat(model).supportsEagerToolInputStreaming;
1476
+ return getCurrentTools(context.messages).length > 0 && !getAnthropicCompat(model).supportsEagerToolInputStreaming;
1322
1477
  }
1323
1478
  function projectObjectUnionForAnthropic(schema) {
1324
1479
  if (schema.properties !== undefined || !Array.isArray(schema.anyOf) || schema.anyOf.length === 0)
@@ -1354,12 +1509,16 @@ function projectObjectUnionForAnthropic(schema) {
1354
1509
  required: (branches[0]?.required ?? []).filter((key) => branches.every((branch) => (branch.required ?? []).includes(key))),
1355
1510
  };
1356
1511
  }
1357
- function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supportsStrictTools, cacheControl, deferLoading = false) {
1512
+ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supportsStrictTools, cacheControl) {
1358
1513
  if (!tools)
1359
1514
  return [];
1515
+ // OAuth canonicalization can make distinct transcript names collide. Keep the latest
1516
+ // declaration, as the pre-transcript tool serializer did, without sending duplicate names.
1517
+ if (isOAuthToken)
1518
+ tools = [...new Map(tools.map((tool) => [toClaudeCodeName(tool.name), tool])).values()];
1360
1519
  return tools.map((tool, index) => {
1361
- const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools);
1362
- const parameters = getJsonSchemaToolParameters(tool, strict);
1520
+ const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools, ANTHROPIC_STRICT_JSON_SCHEMA_PROFILE);
1521
+ const parameters = getJsonSchemaToolParameters(tool, strict, ANTHROPIC_STRICT_JSON_SCHEMA_PROFILE);
1363
1522
  const schema = parameters;
1364
1523
  // Anthropic rejects top-level combinators, so project object-union fields for advertising only.
1365
1524
  // Local runtime validation still enforces the complete authored union without mutating it.
@@ -1381,7 +1540,6 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
1381
1540
  ...(supportsEagerToolInputStreaming ? { eager_input_streaming: true } : {}),
1382
1541
  ...(strict === true ? { strict: true } : {}),
1383
1542
  input_schema: inputSchema,
1384
- ...(deferLoading ? { defer_loading: true } : {}),
1385
1543
  ...(cacheControl && index === tools.length - 1 ? { cache_control: cacheControl } : {}),
1386
1544
  };
1387
1545
  });