@draht/ai 2026.7.30 → 2026.10.4-2

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 (604) hide show
  1. package/dist/api/anthropic-messages.d.ts.map +1 -1
  2. package/dist/api/anthropic-messages.js +404 -142
  3. package/dist/api/anthropic-messages.js.map +1 -1
  4. package/dist/api/azure-openai-responses.d.ts +2 -0
  5. package/dist/api/azure-openai-responses.d.ts.map +1 -1
  6. package/dist/api/azure-openai-responses.js +34 -10
  7. package/dist/api/azure-openai-responses.js.map +1 -1
  8. package/dist/api/bedrock-converse-stream.d.ts.map +1 -1
  9. package/dist/api/bedrock-converse-stream.js +210 -24
  10. package/dist/api/bedrock-converse-stream.js.map +1 -1
  11. package/dist/api/cloudflare-ai-binding.d.ts +77 -0
  12. package/dist/api/cloudflare-ai-binding.d.ts.map +1 -0
  13. package/dist/api/cloudflare-ai-binding.js +72 -0
  14. package/dist/api/cloudflare-ai-binding.js.map +1 -0
  15. package/dist/api/cloudflare-workers-ai-system-one.d.ts +4 -0
  16. package/dist/api/cloudflare-workers-ai-system-one.d.ts.map +1 -0
  17. package/dist/api/cloudflare-workers-ai-system-one.js +43 -0
  18. package/dist/api/cloudflare-workers-ai-system-one.js.map +1 -0
  19. package/dist/api/cloudflare-workers-ai-system-one.lazy.d.ts +3 -0
  20. package/dist/api/cloudflare-workers-ai-system-one.lazy.d.ts.map +1 -0
  21. package/dist/api/cloudflare-workers-ai-system-one.lazy.js +4 -0
  22. package/dist/api/cloudflare-workers-ai-system-one.lazy.js.map +1 -0
  23. package/dist/api/cloudflare.d.ts +2 -0
  24. package/dist/api/cloudflare.d.ts.map +1 -1
  25. package/dist/api/cloudflare.js +2 -0
  26. package/dist/api/cloudflare.js.map +1 -1
  27. package/dist/api/constrained-sampling.d.ts +10 -1
  28. package/dist/api/constrained-sampling.d.ts.map +1 -1
  29. package/dist/api/constrained-sampling.js +137 -4
  30. package/dist/api/constrained-sampling.js.map +1 -1
  31. package/dist/api/google-generative-ai.d.ts +2 -2
  32. package/dist/api/google-generative-ai.d.ts.map +1 -1
  33. package/dist/api/google-generative-ai.js +39 -82
  34. package/dist/api/google-generative-ai.js.map +1 -1
  35. package/dist/api/google-shared.d.ts +27 -5
  36. package/dist/api/google-shared.d.ts.map +1 -1
  37. package/dist/api/google-shared.js +126 -18
  38. package/dist/api/google-shared.js.map +1 -1
  39. package/dist/api/google-vertex.d.ts +2 -2
  40. package/dist/api/google-vertex.d.ts.map +1 -1
  41. package/dist/api/google-vertex.js +42 -73
  42. package/dist/api/google-vertex.js.map +1 -1
  43. package/dist/api/lazy.d.ts +5 -1
  44. package/dist/api/lazy.d.ts.map +1 -1
  45. package/dist/api/lazy.js +19 -7
  46. package/dist/api/lazy.js.map +1 -1
  47. package/dist/api/llama-cpp-classify.d.ts +33 -0
  48. package/dist/api/llama-cpp-classify.d.ts.map +1 -0
  49. package/dist/api/llama-cpp-classify.js +365 -0
  50. package/dist/api/llama-cpp-classify.js.map +1 -0
  51. package/dist/api/llama-cpp-classify.lazy.d.ts +3 -0
  52. package/dist/api/llama-cpp-classify.lazy.d.ts.map +1 -0
  53. package/dist/api/llama-cpp-classify.lazy.js +4 -0
  54. package/dist/api/llama-cpp-classify.lazy.js.map +1 -0
  55. package/dist/api/mistral-conversations.d.ts +2 -2
  56. package/dist/api/mistral-conversations.d.ts.map +1 -1
  57. package/dist/api/mistral-conversations.js +250 -69
  58. package/dist/api/mistral-conversations.js.map +1 -1
  59. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  60. package/dist/api/openai-codex-responses.js +107 -55
  61. package/dist/api/openai-codex-responses.js.map +1 -1
  62. package/dist/api/openai-completions.d.ts +11 -4
  63. package/dist/api/openai-completions.d.ts.map +1 -1
  64. package/dist/api/openai-completions.js +241 -129
  65. package/dist/api/openai-completions.js.map +1 -1
  66. package/dist/api/openai-responses-shared.d.ts +8 -4
  67. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  68. package/dist/api/openai-responses-shared.js +109 -58
  69. package/dist/api/openai-responses-shared.js.map +1 -1
  70. package/dist/api/openai-responses.d.ts.map +1 -1
  71. package/dist/api/openai-responses.js +62 -24
  72. package/dist/api/openai-responses.js.map +1 -1
  73. package/dist/api/openrouter-images.d.ts +2 -1
  74. package/dist/api/openrouter-images.d.ts.map +1 -1
  75. package/dist/api/openrouter-images.js +1 -0
  76. package/dist/api/openrouter-images.js.map +1 -1
  77. package/dist/api/openrouter-images.lazy.d.ts.map +1 -1
  78. package/dist/api/openrouter-images.lazy.js.map +1 -1
  79. package/dist/api/pi-messages.d.ts +5 -3
  80. package/dist/api/pi-messages.d.ts.map +1 -1
  81. package/dist/api/pi-messages.js +13 -4
  82. package/dist/api/pi-messages.js.map +1 -1
  83. package/dist/api/simple-options.d.ts +9 -3
  84. package/dist/api/simple-options.d.ts.map +1 -1
  85. package/dist/api/simple-options.js +22 -11
  86. package/dist/api/simple-options.js.map +1 -1
  87. package/dist/api/system-one-shared.d.ts +23 -0
  88. package/dist/api/system-one-shared.d.ts.map +1 -0
  89. package/dist/api/system-one-shared.js +183 -0
  90. package/dist/api/system-one-shared.js.map +1 -0
  91. package/dist/api/transform-messages.d.ts.map +1 -1
  92. package/dist/api/transform-messages.js +21 -7
  93. package/dist/api/transform-messages.js.map +1 -1
  94. package/dist/api/typesafe-system-one.d.ts +4 -0
  95. package/dist/api/typesafe-system-one.d.ts.map +1 -0
  96. package/dist/api/typesafe-system-one.js +19 -0
  97. package/dist/api/typesafe-system-one.js.map +1 -0
  98. package/dist/api/typesafe-system-one.lazy.d.ts +3 -0
  99. package/dist/api/typesafe-system-one.lazy.d.ts.map +1 -0
  100. package/dist/api/typesafe-system-one.lazy.js +4 -0
  101. package/dist/api/typesafe-system-one.lazy.js.map +1 -0
  102. package/dist/auth/credential-store.d.ts +6 -6
  103. package/dist/auth/credential-store.d.ts.map +1 -1
  104. package/dist/auth/credential-store.js +24 -15
  105. package/dist/auth/credential-store.js.map +1 -1
  106. package/dist/auth/helpers.d.ts +1 -0
  107. package/dist/auth/helpers.d.ts.map +1 -1
  108. package/dist/auth/helpers.js +8 -3
  109. package/dist/auth/helpers.js.map +1 -1
  110. package/dist/auth/oauth/anthropic.d.ts.map +1 -1
  111. package/dist/auth/oauth/anthropic.js +28 -131
  112. package/dist/auth/oauth/anthropic.js.map +1 -1
  113. package/dist/auth/oauth/callback-server.d.ts +55 -0
  114. package/dist/auth/oauth/callback-server.d.ts.map +1 -0
  115. package/dist/auth/oauth/callback-server.js +146 -0
  116. package/dist/auth/oauth/callback-server.js.map +1 -0
  117. package/dist/auth/oauth/device-code.d.ts +2 -1
  118. package/dist/auth/oauth/device-code.d.ts.map +1 -1
  119. package/dist/auth/oauth/device-code.js +5 -5
  120. package/dist/auth/oauth/device-code.js.map +1 -1
  121. package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  122. package/dist/auth/oauth/github-copilot.js +121 -41
  123. package/dist/auth/oauth/github-copilot.js.map +1 -1
  124. package/dist/auth/oauth/google-antigravity.d.ts +3 -3
  125. package/dist/auth/oauth/google-antigravity.d.ts.map +1 -1
  126. package/dist/auth/oauth/google-antigravity.js +17 -9
  127. package/dist/auth/oauth/google-antigravity.js.map +1 -1
  128. package/dist/auth/oauth/google-gemini-cli.d.ts +3 -3
  129. package/dist/auth/oauth/google-gemini-cli.d.ts.map +1 -1
  130. package/dist/auth/oauth/google-gemini-cli.js +18 -10
  131. package/dist/auth/oauth/google-gemini-cli.js.map +1 -1
  132. package/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
  133. package/dist/auth/oauth/kimi-coding.js +5 -6
  134. package/dist/auth/oauth/kimi-coding.js.map +1 -1
  135. package/dist/auth/oauth/load.d.ts +4 -0
  136. package/dist/auth/oauth/load.d.ts.map +1 -1
  137. package/dist/auth/oauth/load.js +10 -0
  138. package/dist/auth/oauth/load.js.map +1 -1
  139. package/dist/auth/oauth/meta.d.ts +17 -0
  140. package/dist/auth/oauth/meta.d.ts.map +1 -0
  141. package/dist/auth/oauth/meta.js +190 -0
  142. package/dist/auth/oauth/meta.js.map +1 -0
  143. package/dist/auth/oauth/openai-chatgpt.d.ts +9 -0
  144. package/dist/auth/oauth/openai-chatgpt.d.ts.map +1 -0
  145. package/dist/auth/oauth/openai-chatgpt.js +266 -0
  146. package/dist/auth/oauth/openai-chatgpt.js.map +1 -0
  147. package/dist/auth/oauth/openai-codex.d.ts +1 -1
  148. package/dist/auth/oauth/openai-codex.d.ts.map +1 -1
  149. package/dist/auth/oauth/openai-codex.js +33 -130
  150. package/dist/auth/oauth/openai-codex.js.map +1 -1
  151. package/dist/auth/oauth/openrouter.d.ts +1 -1
  152. package/dist/auth/oauth/openrouter.d.ts.map +1 -1
  153. package/dist/auth/oauth/openrouter.js +26 -145
  154. package/dist/auth/oauth/openrouter.js.map +1 -1
  155. package/dist/auth/oauth/radius.d.ts +1 -1
  156. package/dist/auth/oauth/radius.d.ts.map +1 -1
  157. package/dist/auth/oauth/radius.js +28 -93
  158. package/dist/auth/oauth/radius.js.map +1 -1
  159. package/dist/auth/oauth/xai.d.ts.map +1 -1
  160. package/dist/auth/oauth/xai.js +13 -12
  161. package/dist/auth/oauth/xai.js.map +1 -1
  162. package/dist/auth/resolve.d.ts +3 -8
  163. package/dist/auth/resolve.d.ts.map +1 -1
  164. package/dist/auth/resolve.js +27 -31
  165. package/dist/auth/resolve.js.map +1 -1
  166. package/dist/auth/types.d.ts +29 -8
  167. package/dist/auth/types.d.ts.map +1 -1
  168. package/dist/auth/types.js.map +1 -1
  169. package/dist/bun-oauth.d.ts.map +1 -1
  170. package/dist/bun-oauth.js +4 -0
  171. package/dist/bun-oauth.js.map +1 -1
  172. package/dist/cli.js +4 -1
  173. package/dist/cli.js.map +1 -1
  174. package/dist/compat.d.ts +3 -3
  175. package/dist/compat.d.ts.map +1 -1
  176. package/dist/compat.js +9 -6
  177. package/dist/compat.js.map +1 -1
  178. package/dist/env-api-keys.d.ts +5 -0
  179. package/dist/env-api-keys.d.ts.map +1 -1
  180. package/dist/env-api-keys.js +9 -1
  181. package/dist/env-api-keys.js.map +1 -1
  182. package/dist/image-models.d.ts +19 -8
  183. package/dist/image-models.d.ts.map +1 -1
  184. package/dist/image-models.js +14 -13
  185. package/dist/image-models.js.map +1 -1
  186. package/dist/images-api-registry.d.ts +7 -7
  187. package/dist/images-api-registry.d.ts.map +1 -1
  188. package/dist/images-api-registry.js.map +1 -1
  189. package/dist/images.d.ts +7 -2
  190. package/dist/images.d.ts.map +1 -1
  191. package/dist/images.js +5 -0
  192. package/dist/images.js.map +1 -1
  193. package/dist/index.d.ts +4 -3
  194. package/dist/index.d.ts.map +1 -1
  195. package/dist/index.js +3 -2
  196. package/dist/index.js.map +1 -1
  197. package/dist/model-catalog.d.ts +25 -9
  198. package/dist/model-catalog.d.ts.map +1 -1
  199. package/dist/model-catalog.js +14 -2
  200. package/dist/model-catalog.js.map +1 -1
  201. package/dist/models-store.d.ts +12 -14
  202. package/dist/models-store.d.ts.map +1 -1
  203. package/dist/models-store.js +7 -6
  204. package/dist/models-store.js.map +1 -1
  205. package/dist/models.d.ts +138 -47
  206. package/dist/models.d.ts.map +1 -1
  207. package/dist/models.generated.d.ts +135 -37
  208. package/dist/models.generated.d.ts.map +1 -1
  209. package/dist/models.generated.js +135 -37
  210. package/dist/models.generated.js.map +1 -1
  211. package/dist/models.js +391 -99
  212. package/dist/models.js.map +1 -1
  213. package/dist/providers/all.d.ts +19 -13
  214. package/dist/providers/all.d.ts.map +1 -1
  215. package/dist/providers/all.js +31 -21
  216. package/dist/providers/all.js.map +1 -1
  217. package/dist/providers/amazon-bedrock.d.ts.map +1 -1
  218. package/dist/providers/amazon-bedrock.js +15 -7
  219. package/dist/providers/amazon-bedrock.js.map +1 -1
  220. package/dist/providers/amazon-bedrock.models.d.ts +4 -2
  221. package/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  222. package/dist/providers/amazon-bedrock.models.js +4 -2
  223. package/dist/providers/amazon-bedrock.models.js.map +1 -1
  224. package/dist/providers/ant-ling.models.d.ts +4 -2
  225. package/dist/providers/ant-ling.models.d.ts.map +1 -1
  226. package/dist/providers/ant-ling.models.js +4 -2
  227. package/dist/providers/ant-ling.models.js.map +1 -1
  228. package/dist/providers/anthropic.d.ts.map +1 -1
  229. package/dist/providers/anthropic.js +39 -8
  230. package/dist/providers/anthropic.js.map +1 -1
  231. package/dist/providers/anthropic.models.d.ts +4 -2
  232. package/dist/providers/anthropic.models.d.ts.map +1 -1
  233. package/dist/providers/anthropic.models.js +4 -2
  234. package/dist/providers/anthropic.models.js.map +1 -1
  235. package/dist/providers/azure-openai-responses.models.d.ts +4 -2
  236. package/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
  237. package/dist/providers/azure-openai-responses.models.js +4 -2
  238. package/dist/providers/azure-openai-responses.models.js.map +1 -1
  239. package/dist/providers/baseten.d.ts +3 -0
  240. package/dist/providers/baseten.d.ts.map +1 -0
  241. package/dist/providers/baseten.js +15 -0
  242. package/dist/providers/baseten.js.map +1 -0
  243. package/dist/providers/baseten.models.d.ts +6 -0
  244. package/dist/providers/baseten.models.d.ts.map +1 -0
  245. package/dist/providers/baseten.models.js +8 -0
  246. package/dist/providers/baseten.models.js.map +1 -0
  247. package/dist/providers/cerebras.models.d.ts +4 -2
  248. package/dist/providers/cerebras.models.d.ts.map +1 -1
  249. package/dist/providers/cerebras.models.js +4 -2
  250. package/dist/providers/cerebras.models.js.map +1 -1
  251. package/dist/providers/cloudflare-ai-gateway.d.ts +3 -1
  252. package/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
  253. package/dist/providers/cloudflare-ai-gateway.js +4 -0
  254. package/dist/providers/cloudflare-ai-gateway.js.map +1 -1
  255. package/dist/providers/cloudflare-ai-gateway.models.d.ts +4 -2
  256. package/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  257. package/dist/providers/cloudflare-ai-gateway.models.js +4 -2
  258. package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  259. package/dist/providers/cloudflare-auth.d.ts.map +1 -1
  260. package/dist/providers/cloudflare-auth.js +15 -10
  261. package/dist/providers/cloudflare-auth.js.map +1 -1
  262. package/dist/providers/cloudflare-stream.d.ts +6 -2
  263. package/dist/providers/cloudflare-stream.d.ts.map +1 -1
  264. package/dist/providers/cloudflare-stream.js +6 -0
  265. package/dist/providers/cloudflare-stream.js.map +1 -1
  266. package/dist/providers/cloudflare-workers-ai.d.ts.map +1 -1
  267. package/dist/providers/cloudflare-workers-ai.js +10 -3
  268. package/dist/providers/cloudflare-workers-ai.js.map +1 -1
  269. package/dist/providers/cloudflare-workers-ai.models.d.ts +4 -2
  270. package/dist/providers/cloudflare-workers-ai.models.d.ts.map +1 -1
  271. package/dist/providers/cloudflare-workers-ai.models.js +4 -2
  272. package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
  273. package/dist/providers/data/.manifest.json +1 -1
  274. package/dist/providers/data/amazon-bedrock.json +1 -1
  275. package/dist/providers/data/ant-ling.json +1 -1
  276. package/dist/providers/data/anthropic.json +1 -1
  277. package/dist/providers/data/azure-openai-responses.json +1 -1
  278. package/dist/providers/data/baseten.json +1 -0
  279. package/dist/providers/data/cerebras.json +1 -1
  280. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  281. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  282. package/dist/providers/data/deepseek.json +1 -1
  283. package/dist/providers/data/fireworks.json +1 -1
  284. package/dist/providers/data/github-copilot.json +1 -1
  285. package/dist/providers/data/google-vertex.json +1 -1
  286. package/dist/providers/data/google.json +1 -1
  287. package/dist/providers/data/groq.json +1 -1
  288. package/dist/providers/data/huggingface.json +1 -1
  289. package/dist/providers/data/kimi-coding.json +1 -1
  290. package/dist/providers/data/meta.json +1 -0
  291. package/dist/providers/data/minimax-cn.json +1 -1
  292. package/dist/providers/data/minimax.json +1 -1
  293. package/dist/providers/data/mistral.json +1 -1
  294. package/dist/providers/data/moonshotai-cn.json +1 -1
  295. package/dist/providers/data/moonshotai.json +1 -1
  296. package/dist/providers/data/nvidia.json +1 -1
  297. package/dist/providers/data/openai-codex.json +1 -1
  298. package/dist/providers/data/openai.json +1 -1
  299. package/dist/providers/data/opencode-go.json +1 -1
  300. package/dist/providers/data/opencode.json +1 -1
  301. package/dist/providers/data/openrouter.json +1 -1
  302. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  303. package/dist/providers/data/qwen-token-plan-individual.json +1 -0
  304. package/dist/providers/data/qwen-token-plan.json +1 -1
  305. package/dist/providers/data/radius.json +1 -0
  306. package/dist/providers/data/together.json +1 -1
  307. package/dist/providers/data/typesafe.json +1 -0
  308. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  309. package/dist/providers/data/xai.json +1 -1
  310. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  311. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  312. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  313. package/dist/providers/data/xiaomi.json +1 -1
  314. package/dist/providers/data/zai-coding-cn.json +1 -1
  315. package/dist/providers/data/zai.json +1 -1
  316. package/dist/providers/deepseek.models.d.ts +4 -2
  317. package/dist/providers/deepseek.models.d.ts.map +1 -1
  318. package/dist/providers/deepseek.models.js +4 -2
  319. package/dist/providers/deepseek.models.js.map +1 -1
  320. package/dist/providers/faux.d.ts +19 -13
  321. package/dist/providers/faux.d.ts.map +1 -1
  322. package/dist/providers/faux.js +109 -18
  323. package/dist/providers/faux.js.map +1 -1
  324. package/dist/providers/fireworks.models.d.ts +4 -2
  325. package/dist/providers/fireworks.models.d.ts.map +1 -1
  326. package/dist/providers/fireworks.models.js +4 -2
  327. package/dist/providers/fireworks.models.js.map +1 -1
  328. package/dist/providers/github-copilot.js +1 -1
  329. package/dist/providers/github-copilot.js.map +1 -1
  330. package/dist/providers/github-copilot.models.d.ts +4 -2
  331. package/dist/providers/github-copilot.models.d.ts.map +1 -1
  332. package/dist/providers/github-copilot.models.js +4 -2
  333. package/dist/providers/github-copilot.models.js.map +1 -1
  334. package/dist/providers/google-vertex.d.ts.map +1 -1
  335. package/dist/providers/google-vertex.js +15 -7
  336. package/dist/providers/google-vertex.js.map +1 -1
  337. package/dist/providers/google-vertex.models.d.ts +4 -2
  338. package/dist/providers/google-vertex.models.d.ts.map +1 -1
  339. package/dist/providers/google-vertex.models.js +4 -2
  340. package/dist/providers/google-vertex.models.js.map +1 -1
  341. package/dist/providers/google.models.d.ts +4 -2
  342. package/dist/providers/google.models.d.ts.map +1 -1
  343. package/dist/providers/google.models.js +4 -2
  344. package/dist/providers/google.models.js.map +1 -1
  345. package/dist/providers/groq.models.d.ts +4 -2
  346. package/dist/providers/groq.models.d.ts.map +1 -1
  347. package/dist/providers/groq.models.js +4 -2
  348. package/dist/providers/groq.models.js.map +1 -1
  349. package/dist/providers/huggingface.models.d.ts +4 -2
  350. package/dist/providers/huggingface.models.d.ts.map +1 -1
  351. package/dist/providers/huggingface.models.js +4 -2
  352. package/dist/providers/huggingface.models.js.map +1 -1
  353. package/dist/providers/images/register-builtins.d.ts +1 -1
  354. package/dist/providers/images/register-builtins.d.ts.map +1 -1
  355. package/dist/providers/images/register-builtins.js.map +1 -1
  356. package/dist/providers/kimi-coding.d.ts.map +1 -1
  357. package/dist/providers/kimi-coding.js +1 -0
  358. package/dist/providers/kimi-coding.js.map +1 -1
  359. package/dist/providers/kimi-coding.models.d.ts +4 -2
  360. package/dist/providers/kimi-coding.models.d.ts.map +1 -1
  361. package/dist/providers/kimi-coding.models.js +4 -2
  362. package/dist/providers/kimi-coding.models.js.map +1 -1
  363. package/dist/providers/meta.d.ts +3 -0
  364. package/dist/providers/meta.d.ts.map +1 -0
  365. package/dist/providers/meta.js +24 -0
  366. package/dist/providers/meta.js.map +1 -0
  367. package/dist/providers/meta.models.d.ts +6 -0
  368. package/dist/providers/meta.models.d.ts.map +1 -0
  369. package/dist/providers/meta.models.js +8 -0
  370. package/dist/providers/meta.models.js.map +1 -0
  371. package/dist/providers/minimax-cn.models.d.ts +4 -2
  372. package/dist/providers/minimax-cn.models.d.ts.map +1 -1
  373. package/dist/providers/minimax-cn.models.js +4 -2
  374. package/dist/providers/minimax-cn.models.js.map +1 -1
  375. package/dist/providers/minimax.models.d.ts +4 -2
  376. package/dist/providers/minimax.models.d.ts.map +1 -1
  377. package/dist/providers/minimax.models.js +4 -2
  378. package/dist/providers/minimax.models.js.map +1 -1
  379. package/dist/providers/mistral.models.d.ts +4 -2
  380. package/dist/providers/mistral.models.d.ts.map +1 -1
  381. package/dist/providers/mistral.models.js +4 -2
  382. package/dist/providers/mistral.models.js.map +1 -1
  383. package/dist/providers/moonshotai-cn.models.d.ts +4 -2
  384. package/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
  385. package/dist/providers/moonshotai-cn.models.js +4 -2
  386. package/dist/providers/moonshotai-cn.models.js.map +1 -1
  387. package/dist/providers/moonshotai.models.d.ts +4 -2
  388. package/dist/providers/moonshotai.models.d.ts.map +1 -1
  389. package/dist/providers/moonshotai.models.js +4 -2
  390. package/dist/providers/moonshotai.models.js.map +1 -1
  391. package/dist/providers/nvidia.models.d.ts +4 -2
  392. package/dist/providers/nvidia.models.d.ts.map +1 -1
  393. package/dist/providers/nvidia.models.js +4 -2
  394. package/dist/providers/nvidia.models.js.map +1 -1
  395. package/dist/providers/openai-codex.d.ts.map +1 -1
  396. package/dist/providers/openai-codex.js +6 -2
  397. package/dist/providers/openai-codex.js.map +1 -1
  398. package/dist/providers/openai-codex.models.d.ts +4 -2
  399. package/dist/providers/openai-codex.models.d.ts.map +1 -1
  400. package/dist/providers/openai-codex.models.js +4 -2
  401. package/dist/providers/openai-codex.models.js.map +1 -1
  402. package/dist/providers/openai.d.ts.map +1 -1
  403. package/dist/providers/openai.js +11 -2
  404. package/dist/providers/openai.js.map +1 -1
  405. package/dist/providers/openai.models.d.ts +4 -2
  406. package/dist/providers/openai.models.d.ts.map +1 -1
  407. package/dist/providers/openai.models.js +4 -2
  408. package/dist/providers/openai.models.js.map +1 -1
  409. package/dist/providers/opencode-go.d.ts.map +1 -1
  410. package/dist/providers/opencode-go.js +4 -3
  411. package/dist/providers/opencode-go.js.map +1 -1
  412. package/dist/providers/opencode-go.models.d.ts +4 -2
  413. package/dist/providers/opencode-go.models.d.ts.map +1 -1
  414. package/dist/providers/opencode-go.models.js +4 -2
  415. package/dist/providers/opencode-go.models.js.map +1 -1
  416. package/dist/providers/opencode-headers.d.ts +4 -0
  417. package/dist/providers/opencode-headers.d.ts.map +1 -0
  418. package/dist/providers/opencode-headers.js +22 -0
  419. package/dist/providers/opencode-headers.js.map +1 -0
  420. package/dist/providers/opencode.d.ts +3 -1
  421. package/dist/providers/opencode.d.ts.map +1 -1
  422. package/dist/providers/opencode.js +10 -6
  423. package/dist/providers/opencode.js.map +1 -1
  424. package/dist/providers/opencode.models.d.ts +4 -2
  425. package/dist/providers/opencode.models.d.ts.map +1 -1
  426. package/dist/providers/opencode.models.js +4 -2
  427. package/dist/providers/opencode.models.js.map +1 -1
  428. package/dist/providers/openrouter.d.ts +1 -1
  429. package/dist/providers/openrouter.d.ts.map +1 -1
  430. package/dist/providers/openrouter.js +16 -3
  431. package/dist/providers/openrouter.js.map +1 -1
  432. package/dist/providers/openrouter.models.d.ts +4 -2
  433. package/dist/providers/openrouter.models.d.ts.map +1 -1
  434. package/dist/providers/openrouter.models.js +4 -2
  435. package/dist/providers/openrouter.models.js.map +1 -1
  436. package/dist/providers/qwen-token-plan-cn.models.d.ts +4 -2
  437. package/dist/providers/qwen-token-plan-cn.models.d.ts.map +1 -1
  438. package/dist/providers/qwen-token-plan-cn.models.js +4 -2
  439. package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
  440. package/dist/providers/qwen-token-plan-individual.d.ts +3 -0
  441. package/dist/providers/qwen-token-plan-individual.d.ts.map +1 -0
  442. package/dist/providers/qwen-token-plan-individual.js +15 -0
  443. package/dist/providers/qwen-token-plan-individual.js.map +1 -0
  444. package/dist/providers/qwen-token-plan-individual.models.d.ts +6 -0
  445. package/dist/providers/qwen-token-plan-individual.models.d.ts.map +1 -0
  446. package/dist/providers/qwen-token-plan-individual.models.js +8 -0
  447. package/dist/providers/qwen-token-plan-individual.models.js.map +1 -0
  448. package/dist/providers/qwen-token-plan.models.d.ts +4 -2
  449. package/dist/providers/qwen-token-plan.models.d.ts.map +1 -1
  450. package/dist/providers/qwen-token-plan.models.js +4 -2
  451. package/dist/providers/qwen-token-plan.models.js.map +1 -1
  452. package/dist/providers/radius.d.ts.map +1 -1
  453. package/dist/providers/radius.js +53 -29
  454. package/dist/providers/radius.js.map +1 -1
  455. package/dist/providers/radius.models.d.ts +6 -0
  456. package/dist/providers/radius.models.d.ts.map +1 -0
  457. package/dist/providers/radius.models.js +8 -0
  458. package/dist/providers/radius.models.js.map +1 -0
  459. package/dist/providers/together.models.d.ts +4 -2
  460. package/dist/providers/together.models.d.ts.map +1 -1
  461. package/dist/providers/together.models.js +4 -2
  462. package/dist/providers/together.models.js.map +1 -1
  463. package/dist/providers/typesafe.d.ts +3 -0
  464. package/dist/providers/typesafe.d.ts.map +1 -0
  465. package/dist/providers/typesafe.js +18 -0
  466. package/dist/providers/typesafe.js.map +1 -0
  467. package/dist/providers/typesafe.models.d.ts +6 -0
  468. package/dist/providers/typesafe.models.d.ts.map +1 -0
  469. package/dist/providers/typesafe.models.js +8 -0
  470. package/dist/providers/typesafe.models.js.map +1 -0
  471. package/dist/providers/vercel-ai-gateway.d.ts.map +1 -1
  472. package/dist/providers/vercel-ai-gateway.js +5 -2
  473. package/dist/providers/vercel-ai-gateway.js.map +1 -1
  474. package/dist/providers/vercel-ai-gateway.models.d.ts +4 -2
  475. package/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  476. package/dist/providers/vercel-ai-gateway.models.js +4 -2
  477. package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  478. package/dist/providers/xai.d.ts +1 -1
  479. package/dist/providers/xai.d.ts.map +1 -1
  480. package/dist/providers/xai.js +2 -5
  481. package/dist/providers/xai.js.map +1 -1
  482. package/dist/providers/xai.models.d.ts +4 -2
  483. package/dist/providers/xai.models.d.ts.map +1 -1
  484. package/dist/providers/xai.models.js +4 -2
  485. package/dist/providers/xai.models.js.map +1 -1
  486. package/dist/providers/xiaomi-token-plan-ams.models.d.ts +4 -2
  487. package/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
  488. package/dist/providers/xiaomi-token-plan-ams.models.js +4 -2
  489. package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
  490. package/dist/providers/xiaomi-token-plan-cn.models.d.ts +4 -2
  491. package/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
  492. package/dist/providers/xiaomi-token-plan-cn.models.js +4 -2
  493. package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
  494. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts +4 -2
  495. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
  496. package/dist/providers/xiaomi-token-plan-sgp.models.js +4 -2
  497. package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
  498. package/dist/providers/xiaomi.models.d.ts +4 -2
  499. package/dist/providers/xiaomi.models.d.ts.map +1 -1
  500. package/dist/providers/xiaomi.models.js +4 -2
  501. package/dist/providers/xiaomi.models.js.map +1 -1
  502. package/dist/providers/zai-coding-cn.models.d.ts +4 -2
  503. package/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
  504. package/dist/providers/zai-coding-cn.models.js +4 -2
  505. package/dist/providers/zai-coding-cn.models.js.map +1 -1
  506. package/dist/providers/zai.models.d.ts +4 -2
  507. package/dist/providers/zai.models.d.ts.map +1 -1
  508. package/dist/providers/zai.models.js +4 -2
  509. package/dist/providers/zai.models.js.map +1 -1
  510. package/dist/types.d.ts +411 -127
  511. package/dist/types.d.ts.map +1 -1
  512. package/dist/types.js.map +1 -1
  513. package/dist/utils/abort.d.ts +8 -0
  514. package/dist/utils/abort.d.ts.map +1 -0
  515. package/dist/utils/abort.js +49 -0
  516. package/dist/utils/abort.js.map +1 -0
  517. package/dist/utils/assistant-message-frame.d.ts +77 -0
  518. package/dist/utils/assistant-message-frame.d.ts.map +1 -0
  519. package/dist/utils/assistant-message-frame.js +425 -0
  520. package/dist/utils/assistant-message-frame.js.map +1 -0
  521. package/dist/utils/diagnostics.d.ts +3 -2
  522. package/dist/utils/diagnostics.d.ts.map +1 -1
  523. package/dist/utils/diagnostics.js.map +1 -1
  524. package/dist/utils/draht-user-agent.d.ts +2 -0
  525. package/dist/utils/draht-user-agent.d.ts.map +1 -0
  526. package/dist/utils/draht-user-agent.js +12 -0
  527. package/dist/utils/draht-user-agent.js.map +1 -0
  528. package/dist/utils/error-body.d.ts.map +1 -1
  529. package/dist/utils/error-body.js +23 -4
  530. package/dist/utils/error-body.js.map +1 -1
  531. package/dist/utils/estimate.d.ts +2 -2
  532. package/dist/utils/estimate.d.ts.map +1 -1
  533. package/dist/utils/estimate.js +8 -29
  534. package/dist/utils/estimate.js.map +1 -1
  535. package/dist/utils/event-stream.d.ts.map +1 -1
  536. package/dist/utils/event-stream.js +30 -8
  537. package/dist/utils/event-stream.js.map +1 -1
  538. package/dist/utils/headers.d.ts +1 -1
  539. package/dist/utils/headers.d.ts.map +1 -1
  540. package/dist/utils/headers.js +10 -8
  541. package/dist/utils/headers.js.map +1 -1
  542. package/dist/utils/model-operations.d.ts +11 -0
  543. package/dist/utils/model-operations.d.ts.map +1 -0
  544. package/dist/utils/model-operations.js +47 -0
  545. package/dist/utils/model-operations.js.map +1 -0
  546. package/dist/utils/models-error.d.ts +8 -0
  547. package/dist/utils/models-error.d.ts.map +1 -0
  548. package/dist/utils/models-error.js +19 -0
  549. package/dist/utils/models-error.js.map +1 -0
  550. package/dist/utils/node-http-proxy.d.ts.map +1 -1
  551. package/dist/utils/node-http-proxy.js +53 -12
  552. package/dist/utils/node-http-proxy.js.map +1 -1
  553. package/dist/utils/oauth-page.d.ts.map +1 -0
  554. package/dist/utils/oauth-page.js.map +1 -0
  555. package/dist/utils/overflow.d.ts +11 -1
  556. package/dist/utils/overflow.d.ts.map +1 -1
  557. package/dist/utils/overflow.js +24 -6
  558. package/dist/utils/overflow.js.map +1 -1
  559. package/dist/utils/provider-retry.js +3 -2
  560. package/dist/utils/provider-retry.js.map +1 -1
  561. package/dist/utils/retry.d.ts +6 -1
  562. package/dist/utils/retry.d.ts.map +1 -1
  563. package/dist/utils/retry.js +19 -2
  564. package/dist/utils/retry.js.map +1 -1
  565. package/dist/utils/sleep.d.ts +2 -0
  566. package/dist/utils/sleep.d.ts.map +1 -0
  567. package/dist/utils/sleep.js +15 -0
  568. package/dist/utils/sleep.js.map +1 -0
  569. package/dist/utils/text.d.ts +9 -1
  570. package/dist/utils/text.d.ts.map +1 -1
  571. package/dist/utils/text.js +26 -0
  572. package/dist/utils/text.js.map +1 -1
  573. package/dist/utils/transcript.d.ts +84 -0
  574. package/dist/utils/transcript.d.ts.map +1 -0
  575. package/dist/utils/transcript.js +204 -0
  576. package/dist/utils/transcript.js.map +1 -0
  577. package/dist/utils/uuid.d.ts +2 -2
  578. package/dist/utils/uuid.d.ts.map +1 -1
  579. package/dist/utils/uuid.js +35 -40
  580. package/dist/utils/uuid.js.map +1 -1
  581. package/dist/utils/validation.d.ts.map +1 -1
  582. package/dist/utils/validation.js +40 -0
  583. package/dist/utils/validation.js.map +1 -1
  584. package/package.json +19 -13
  585. package/dist/auth/oauth/oauth-page.d.ts.map +0 -1
  586. package/dist/auth/oauth/oauth-page.js.map +0 -1
  587. package/dist/image-models.generated.d.ts +0 -605
  588. package/dist/image-models.generated.d.ts.map +0 -1
  589. package/dist/image-models.generated.js +0 -607
  590. package/dist/image-models.generated.js.map +0 -1
  591. package/dist/images-models.d.ts +0 -95
  592. package/dist/images-models.d.ts.map +0 -1
  593. package/dist/images-models.js +0 -140
  594. package/dist/images-models.js.map +0 -1
  595. package/dist/providers/openrouter-images.d.ts +0 -3
  596. package/dist/providers/openrouter-images.d.ts.map +0 -1
  597. package/dist/providers/openrouter-images.js +0 -22
  598. package/dist/providers/openrouter-images.js.map +0 -1
  599. package/dist/utils/deferred-tools.d.ts +0 -9
  600. package/dist/utils/deferred-tools.d.ts.map +0 -1
  601. package/dist/utils/deferred-tools.js +0 -36
  602. package/dist/utils/deferred-tools.js.map +0 -1
  603. /package/dist/{auth/oauth → utils}/oauth-page.d.ts +0 -0
  604. /package/dist/{auth/oauth → utils}/oauth-page.js +0 -0
@@ -1,25 +1,29 @@
1
- import Anthropic from "@anthropic-ai/sdk";
1
+ import Anthropic, {} from "@anthropic-ai/sdk";
2
+ import { ANTHROPIC_FEDERATION_RULE_ID_ENV, ANTHROPIC_IDENTITY_TOKEN_FILE_ENV, ANTHROPIC_ORGANIZATION_ID_ENV, ANTHROPIC_SERVICE_ACCOUNT_ID_ENV, ANTHROPIC_WORKSPACE_ID_ENV, } from "../env-api-keys.js";
2
3
  import { calculateCost } from "../models.js";
3
- import { splitDeferredTools } from "../utils/deferred-tools.js";
4
+ import { appendAssistantMessageDiagnostic } from "../utils/diagnostics.js";
5
+ import { getDrahtUserAgent } from "../utils/draht-user-agent.js";
4
6
  import { AssistantMessageEventStream } from "../utils/event-stream.js";
5
7
  import { headersToRecord } from "../utils/headers.js";
6
8
  import { parseJsonWithRepair, parseStreamingJson } from "../utils/json-parse.js";
7
9
  import { getProviderEnvValue } from "../utils/provider-env.js";
8
10
  import { retryProviderRequest } from "../utils/provider-retry.js";
9
11
  import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
10
- import { resolveJsonSchemaStrictSampling } from "./constrained-sampling.js";
12
+ import { getSystemMessageText, renderSystemMessageUpdate } from "../utils/text.js";
13
+ import { getCurrentTools, getDeclaredTools, getInitialSystemMessage, hasToolRedefinitions, resolveTranscript, } from "../utils/transcript.js";
14
+ import { getJsonSchemaToolParameters, resolveJsonSchemaStrictSampling, } from "./constrained-sampling.js";
11
15
  import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
12
16
  import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext } from "./simple-options.js";
13
17
  import { transformMessages } from "./transform-messages.js";
14
18
  /**
15
19
  * Resolve cache retention preference.
16
- * Defaults to "short" and uses PI_CACHE_RETENTION for backward compatibility.
20
+ * Defaults to "short" and uses DRAHT_CACHE_RETENTION for backward compatibility.
17
21
  */
18
22
  function resolveCacheRetention(cacheRetention, env) {
19
23
  if (cacheRetention) {
20
24
  return cacheRetention;
21
25
  }
22
- if (getProviderEnvValue("PI_CACHE_RETENTION", env) === "long") {
26
+ if (getProviderEnvValue("DRAHT_CACHE_RETENTION", env) === "long") {
23
27
  return "long";
24
28
  }
25
29
  return "short";
@@ -36,7 +40,7 @@ function getCacheControl(model, cacheRetention, env) {
36
40
  };
37
41
  }
38
42
  // Stealth mode: Mimic Claude Code's tool naming exactly
39
- const claudeCodeVersion = "2.1.75";
43
+ const claudeCodeVersion = "2.1.280";
40
44
  // Claude Code 2.x tool names (canonical casing)
41
45
  // Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md
42
46
  // To update: https://github.com/badlogic/cchistory
@@ -109,33 +113,41 @@ function convertContentBlocks(content) {
109
113
  }
110
114
  const FINE_GRAINED_TOOL_STREAMING_BETA = "fine-grained-tool-streaming-2025-05-14";
111
115
  const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
116
+ const SERVER_SIDE_FALLBACK_BETA = "server-side-fallback-2026-07-01";
117
+ const MID_CONVERSATION_OUTPUT_CONFIG_BETA = "mid-conversation-output-config-2026-07-01";
118
+ const THINKING_BINDING_CONTROLS_BETA = "thinking-binding-controls-2026-08-01";
119
+ const MID_CONVERSATION_TOOL_CHANGES_BETA = "mid-conversation-tool-changes-2026-07-01";
120
+ /**
121
+ * Stable deferred tool declared whenever native tool changes are in use. Anthropic adds
122
+ * hidden prompt scaffolding as soon as any tool has `defer_loading`; declaring this
123
+ * placeholder from the first request keeps that scaffolding in the cached prefix, so the
124
+ * first real late tool does not invalidate the cache (measured: full miss without it).
125
+ * It is never activated and the model cannot see it.
126
+ */
127
+ const DEFERRED_TOOL_PLACEHOLDER = {
128
+ name: "__pi_deferred_placeholder__",
129
+ description: "Reserved placeholder. Never available. Never call this.",
130
+ input_schema: { type: "object", properties: {}, required: [] },
131
+ defer_loading: true,
132
+ };
133
+ function shouldUseServerSideFallbackBeta(model) {
134
+ return (model.compat?.allowedFallbackModels?.length ?? 0) > 0;
135
+ }
112
136
  function getAnthropicCompat(model) {
137
+ const isOpenRouter = model.provider === "openrouter" || model.baseUrl.includes("openrouter.ai");
113
138
  return {
114
139
  supportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? true,
115
140
  supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,
116
- sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? false,
141
+ sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? isOpenRouter,
142
+ sessionAffinityFormat: model.compat?.sessionAffinityFormat ?? (isOpenRouter ? "openrouter" : undefined),
117
143
  supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? true,
118
144
  supportsTemperature: model.compat?.supportsTemperature ?? true,
119
145
  allowEmptySignature: model.compat?.allowEmptySignature ?? false,
120
146
  supportsStrictTools: model.compat?.supportsStrictTools ?? false,
121
- supportsToolReferences: model.compat?.supportsToolReferences ?? defaultSupportsToolReferences(model),
147
+ supportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,
148
+ supportsMidConvoToolChanges: model.compat?.supportsMidConvoToolChanges ?? false,
122
149
  };
123
150
  }
124
- /**
125
- * Default for `supportsToolReferences`: first-party Anthropic models except
126
- * Haiku (rejects client-side tool_reference blocks) and models that predate
127
- * tool search (Claude 3.x, Opus/Sonnet 4.0, Opus 4.1).
128
- */
129
- function defaultSupportsToolReferences(model) {
130
- if (model.provider !== "anthropic" || model.id.includes("haiku"))
131
- return false;
132
- const version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\d+)(?:-(\d+))?(?:-|$)/);
133
- if (!version)
134
- return false;
135
- const major = Number(version[1]);
136
- const minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;
137
- return major > 4 || (major === 4 && minor >= 5);
138
- }
139
151
  function mergeHeaders(...headerSources) {
140
152
  const merged = {};
141
153
  for (const headers of headerSources) {
@@ -145,6 +157,9 @@ function mergeHeaders(...headerSources) {
145
157
  }
146
158
  return merged;
147
159
  }
160
+ function mergeClientHeaders(...headerSources) {
161
+ return mergeHeaders({ "User-Agent": getDrahtUserAgent() }, ...headerSources);
162
+ }
148
163
  function hasHeader(headers, name) {
149
164
  if (!headers)
150
165
  return false;
@@ -155,16 +170,58 @@ function hasHeader(headers, name) {
155
170
  }
156
171
  return false;
157
172
  }
158
- function assertRequestAuth(provider, apiKey, headers) {
159
- if (apiKey)
160
- return;
161
- if (hasHeader(headers, "authorization") ||
173
+ function hasRequestAuth(apiKey, headers) {
174
+ return (!!apiKey ||
175
+ hasHeader(headers, "authorization") ||
162
176
  hasHeader(headers, "x-api-key") ||
163
- hasHeader(headers, "cf-aig-authorization")) {
164
- return;
177
+ hasHeader(headers, "cf-aig-authorization"));
178
+ }
179
+ function assertRequestAuth(provider, apiKey, headers) {
180
+ if (!hasRequestAuth(apiKey, headers))
181
+ throw new Error(`No API key for provider: ${provider}`);
182
+ }
183
+ /**
184
+ * Anthropic SDK client that never runs the SDK's own credential chain
185
+ * (ANTHROPIC_PROFILE config files, federation env vars). Without this, every
186
+ * client built with `apiKey: null, authToken: null` for header-owned auth would
187
+ * also resolve and exchange SDK credentials behind pi's auth resolver.
188
+ */
189
+ class PiAnthropic extends Anthropic {
190
+ _shouldResolveDefaultCredentials() {
191
+ return false;
165
192
  }
166
- throw new Error(`No API key for provider: ${provider}`);
167
193
  }
194
+ /**
195
+ * Workload identity federation config from the ANTHROPIC_* variables the
196
+ * Anthropic SDK documents; the SDK performs the token exchange and refresh.
197
+ * Only for the anthropic provider, since the exchange is an Anthropic API
198
+ * endpoint, and only when no key or auth header was resolved.
199
+ */
200
+ function getAnthropicFederation(model, apiKey, headers, env) {
201
+ if (model.provider !== "anthropic" || hasRequestAuth(apiKey, headers))
202
+ return undefined;
203
+ const federationRuleId = getProviderEnvValue(ANTHROPIC_FEDERATION_RULE_ID_ENV, env);
204
+ const organizationId = getProviderEnvValue(ANTHROPIC_ORGANIZATION_ID_ENV, env);
205
+ const identityTokenFile = getProviderEnvValue(ANTHROPIC_IDENTITY_TOKEN_FILE_ENV, env);
206
+ if (!federationRuleId || !organizationId || !identityTokenFile)
207
+ return undefined;
208
+ return {
209
+ organization_id: organizationId,
210
+ workspace_id: getProviderEnvValue(ANTHROPIC_WORKSPACE_ID_ENV, env),
211
+ authentication: {
212
+ type: "oidc_federation",
213
+ federation_rule_id: federationRuleId,
214
+ service_account_id: getProviderEnvValue(ANTHROPIC_SERVICE_ACCOUNT_ID_ENV, env),
215
+ identity_token: { source: "file", path: identityTokenFile },
216
+ },
217
+ };
218
+ }
219
+ /**
220
+ * The SDK caches the federated access token per client, but pi creates a client
221
+ * per request. Keep one client for the current federation config and fetch, and
222
+ * clone it per request with `withOptions()`, which shares the token cache.
223
+ */
224
+ let federationClient;
168
225
  const ANTHROPIC_MESSAGE_EVENTS = new Set([
169
226
  "message_start",
170
227
  "message_delta",
@@ -318,13 +375,17 @@ async function* iterateAnthropicEvents(response, signal) {
318
375
  }
319
376
  export const stream = (model, context, options) => {
320
377
  const stream = new AssistantMessageEventStream();
378
+ const normalizedContext = resolveTranscript(context, getAnthropicCompat(model).supportsMidConvoSystemMessages);
379
+ const currentTools = getCurrentTools(normalizedContext.messages);
321
380
  (async () => {
381
+ const providerThinkingLevel = model.compat?.supportsMidConvoEffort ? (options?.effort ?? "high") : undefined;
322
382
  const output = {
323
383
  role: "assistant",
324
384
  content: [],
325
385
  api: model.api,
326
386
  provider: model.provider,
327
387
  model: model.id,
388
+ ...(providerThinkingLevel === undefined ? {} : { providerThinkingLevel }),
328
389
  usage: {
329
390
  input: 0,
330
391
  output: 0,
@@ -339,38 +400,42 @@ export const stream = (model, context, options) => {
339
400
  try {
340
401
  let client;
341
402
  let isOAuth;
403
+ let usageModel = model;
404
+ let inputTransformations;
342
405
  if (options?.client) {
343
406
  client = options.client;
344
407
  isOAuth = false;
345
408
  }
346
409
  else {
347
410
  const apiKey = options?.apiKey;
348
- assertRequestAuth(model.provider, apiKey, options?.headers);
411
+ const federation = getAnthropicFederation(model, apiKey, options?.headers, options?.env);
412
+ if (!federation)
413
+ assertRequestAuth(model.provider, apiKey, options?.headers);
349
414
  let copilotDynamicHeaders;
350
415
  if (model.provider === "github-copilot") {
351
- const hasImages = hasCopilotVisionInput(context.messages);
416
+ const hasImages = hasCopilotVisionInput(normalizedContext.messages);
352
417
  copilotDynamicHeaders = buildCopilotDynamicHeaders({
353
- messages: context.messages,
418
+ messages: normalizedContext.messages,
354
419
  hasImages,
355
420
  });
356
421
  }
357
422
  const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
358
423
  const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
359
- const created = createClient(model, apiKey, options?.interleavedThinking ?? true, shouldUseFineGrainedToolStreamingBeta(model, context), options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId);
424
+ const created = createClient(model, apiKey, options?.headers, options?.fetch, copilotDynamicHeaders, cacheSessionId, federation);
360
425
  client = created.client;
361
426
  isOAuth = created.isOAuthToken;
362
427
  }
363
- let params = buildParams(model, context, isOAuth, options);
428
+ let params = buildParams(model, normalizedContext, isOAuth, options);
364
429
  const nextParams = await options?.onPayload?.(params, model);
365
430
  if (nextParams !== undefined) {
366
- params = nextParams;
431
+ params = { ...nextParams, stream: true };
367
432
  }
368
433
  const requestOptions = {
369
434
  ...(options?.signal ? { signal: options.signal } : {}),
370
435
  ...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
371
436
  maxRetries: 0,
372
437
  };
373
- const response = await retryProviderRequest(() => client.messages.create({ ...params, stream: true }, requestOptions).asResponse(), {
438
+ const response = await retryProviderRequest(() => client.beta.messages.create(params, requestOptions).asResponse(), {
374
439
  maxRetries: options?.maxRetries,
375
440
  maxRetryDelayMs: options?.maxRetryDelayMs,
376
441
  signal: options?.signal,
@@ -379,8 +444,19 @@ export const stream = (model, context, options) => {
379
444
  stream.push({ type: "start", partial: output });
380
445
  const blocks = output.content;
381
446
  for await (const event of iterateAnthropicEvents(response, options?.signal)) {
447
+ await options?.onProviderStreamEvent?.(event, model);
382
448
  if (event.type === "message_start") {
383
449
  output.responseId = event.message.id;
450
+ const transformations = event.message.input_transformations;
451
+ if (Array.isArray(transformations))
452
+ inputTransformations = transformations;
453
+ const responseModel = event.message.model;
454
+ if (responseModel !== model.id)
455
+ output.responseModel = responseModel;
456
+ const fallbackCost = responseModel === model.id
457
+ ? undefined
458
+ : model.compat?.allowedFallbackModels?.find((fallback) => fallback.provider === model.provider && fallback.model === responseModel)?.cost;
459
+ usageModel = fallbackCost ? { ...model, id: responseModel, cost: fallbackCost } : model;
384
460
  // Capture initial token usage from message_start event
385
461
  // This ensures we have input token counts even if the stream is aborted early
386
462
  output.usage.input = event.message.usage.input_tokens || 0;
@@ -391,13 +467,19 @@ export const stream = (model, context, options) => {
391
467
  // Anthropic doesn't provide total_tokens, compute from components
392
468
  output.usage.totalTokens =
393
469
  output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
394
- calculateCost(model, output.usage);
470
+ calculateCost(usageModel, output.usage);
395
471
  }
396
472
  else if (event.type === "content_block_start") {
473
+ if (event.content_block.type === "fallback") {
474
+ if (output.content.length > 0) {
475
+ throw new Error("Anthropic performed an unsupported mid-output model fallback");
476
+ }
477
+ continue;
478
+ }
397
479
  if (event.content_block.type === "text") {
398
480
  const block = {
399
481
  type: "text",
400
- text: "",
482
+ text: event.content_block.text ?? "",
401
483
  index: event.index,
402
484
  };
403
485
  output.content.push(block);
@@ -406,8 +488,8 @@ export const stream = (model, context, options) => {
406
488
  else if (event.content_block.type === "thinking") {
407
489
  const block = {
408
490
  type: "thinking",
409
- thinking: "",
410
- thinkingSignature: "",
491
+ thinking: event.content_block.thinking ?? "",
492
+ thinkingSignature: event.content_block.signature ?? "",
411
493
  index: event.index,
412
494
  };
413
495
  output.content.push(block);
@@ -429,7 +511,7 @@ export const stream = (model, context, options) => {
429
511
  type: "toolCall",
430
512
  id: event.content_block.id,
431
513
  name: isOAuth
432
- ? fromClaudeCodeName(event.content_block.name, context.tools)
514
+ ? fromClaudeCodeName(event.content_block.name, currentTools)
433
515
  : event.content_block.name,
434
516
  arguments: event.content_block.input ?? {},
435
517
  partialJson: "",
@@ -525,6 +607,9 @@ export const stream = (model, context, options) => {
525
607
  }
526
608
  }
527
609
  else if (event.type === "message_delta") {
610
+ const transformations = event.input_transformations;
611
+ if (Array.isArray(transformations))
612
+ inputTransformations = transformations;
528
613
  if (event.delta.stop_reason) {
529
614
  output.rawStopReason = event.delta.stop_reason;
530
615
  const stopReasonResult = mapStopReason(event.delta.stop_reason, event.delta.stop_details);
@@ -548,11 +633,13 @@ export const stream = (model, context, options) => {
548
633
  if (event.usage.cache_creation_input_tokens != null) {
549
634
  output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
550
635
  }
551
- // Anthropic reports reasoning tokens in `output_tokens_details.thinking_tokens` on the
552
- // final message_delta usage (a subset of output_tokens). SDK 0.91.1 omits the field from
553
- // its Usage type, so read it through a narrow cast. Verified against the live API.
554
- const thinkingTokens = event.usage
555
- .output_tokens_details?.thinking_tokens;
636
+ // Vercel AI Gateway includes the TTL breakdown in deltas, though the SDK only types it on message_start.
637
+ const cacheCreation = event.usage.cache_creation;
638
+ if (cacheCreation?.ephemeral_1h_input_tokens != null) {
639
+ output.usage.cacheWrite1h = cacheCreation.ephemeral_1h_input_tokens;
640
+ }
641
+ // Anthropic reports reasoning tokens as a subset of output tokens.
642
+ const thinkingTokens = event.usage.output_tokens_details?.thinking_tokens;
556
643
  if (thinkingTokens != null) {
557
644
  output.usage.reasoning = thinkingTokens;
558
645
  }
@@ -560,7 +647,7 @@ export const stream = (model, context, options) => {
560
647
  // Anthropic doesn't provide total_tokens, compute from components
561
648
  output.usage.totalTokens =
562
649
  output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
563
- calculateCost(model, output.usage);
650
+ calculateCost(usageModel, output.usage);
564
651
  }
565
652
  }
566
653
  if (options?.signal?.aborted) {
@@ -572,6 +659,19 @@ export const stream = (model, context, options) => {
572
659
  if (output.stopReason === "aborted" || output.stopReason === "error") {
573
660
  throw new Error(output.errorMessage || "An unknown error occurred");
574
661
  }
662
+ if (inputTransformations && inputTransformations.length > 0) {
663
+ appendAssistantMessageDiagnostic(output, {
664
+ type: "anthropic_input_transformations",
665
+ timestamp: Date.now(),
666
+ details: {
667
+ transformations: inputTransformations.map((transformation) => ({
668
+ type: transformation.type ?? undefined,
669
+ path: transformation.path ?? undefined,
670
+ reason: transformation.reason ?? undefined,
671
+ })),
672
+ },
673
+ });
674
+ }
575
675
  stream.push({ type: "done", reason: output.stopReason, message: output });
576
676
  stream.end();
577
677
  }
@@ -611,10 +711,18 @@ function mapThinkingLevelToEffort(model, level) {
611
711
  }
612
712
  }
613
713
  export const streamSimple = (model, context, options) => {
614
- assertRequestAuth(model.provider, options?.apiKey, options?.headers);
615
- const base = buildBaseOptions(model, context, options, options?.apiKey);
714
+ if (!getAnthropicFederation(model, options?.apiKey, options?.headers, options?.env)) {
715
+ assertRequestAuth(model.provider, options?.apiKey, options?.headers);
716
+ }
717
+ const base = {
718
+ ...buildBaseOptions(model, context, options, options?.apiKey),
719
+ toolChoice: options?.toolChoice,
720
+ };
616
721
  if (!options?.reasoning) {
617
- return stream(model, context, { ...base, thinkingEnabled: false });
722
+ return stream(model, context, {
723
+ ...base,
724
+ thinkingEnabled: false,
725
+ });
618
726
  }
619
727
  // For models with adaptive thinking: use an effort level.
620
728
  // For older models: use budget-based thinking.
@@ -640,58 +748,66 @@ export const streamSimple = (model, context, options) => {
640
748
  function isOAuthToken(apiKey) {
641
749
  return apiKey.includes("sk-ant-oat");
642
750
  }
643
- function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStreamingBeta, optionsHeaders, fetch, dynamicHeaders, sessionId) {
644
- // Adaptive thinking models have interleaved thinking built in, so skip the beta header.
645
- const needsInterleavedBeta = interleavedThinking && model.compat?.forceAdaptiveThinking !== true;
646
- const betaFeatures = [];
647
- if (useFineGrainedToolStreamingBeta) {
648
- betaFeatures.push(FINE_GRAINED_TOOL_STREAMING_BETA);
649
- }
650
- if (needsInterleavedBeta) {
651
- betaFeatures.push(INTERLEAVED_THINKING_BETA);
652
- }
653
- // Copilot: Bearer auth, selective betas.
751
+ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation) {
752
+ // Copilot: Bearer auth.
654
753
  if (model.provider === "github-copilot") {
655
- const client = new Anthropic({
754
+ const client = new PiAnthropic({
656
755
  apiKey: null,
657
756
  authToken: apiKey ?? null,
658
757
  baseURL: model.baseUrl,
659
758
  dangerouslyAllowBrowser: true,
660
759
  fetch,
661
- defaultHeaders: mergeHeaders({
760
+ defaultHeaders: mergeClientHeaders({
662
761
  accept: "application/json",
663
762
  "anthropic-dangerous-direct-browser-access": "true",
664
- ...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
665
763
  }, model.headers, dynamicHeaders, optionsHeaders),
666
764
  });
667
765
  return { client, isOAuthToken: false };
668
766
  }
669
767
  // OAuth: Bearer auth, Claude Code identity headers
670
768
  if (apiKey && isOAuthToken(apiKey)) {
671
- const client = new Anthropic({
769
+ const client = new PiAnthropic({
672
770
  apiKey: null,
673
771
  authToken: apiKey,
674
772
  baseURL: model.baseUrl,
675
773
  dangerouslyAllowBrowser: true,
676
774
  fetch,
677
- defaultHeaders: mergeHeaders({
775
+ defaultHeaders: mergeClientHeaders({
678
776
  accept: "application/json",
679
777
  "anthropic-dangerous-direct-browser-access": "true",
680
- "anthropic-beta": ["claude-code-20250219", "oauth-2025-04-20", ...betaFeatures].join(","),
681
778
  "user-agent": `claude-cli/${claudeCodeVersion}`,
682
779
  "x-app": "cli",
683
780
  }, model.headers, optionsHeaders),
684
781
  });
685
782
  return { client, isOAuthToken: true };
686
783
  }
687
- // API key or header-owned auth.
688
- const sessionAffinityHeaders = sessionId && getAnthropicCompat(model).sendSessionAffinityHeaders ? { "x-session-affinity": sessionId } : {};
689
- const defaultHeaders = mergeHeaders({
784
+ // API key, header-owned auth, or workload identity federation.
785
+ const compat = getAnthropicCompat(model);
786
+ const sessionAffinityHeaders = {};
787
+ if (sessionId && compat.sendSessionAffinityHeaders) {
788
+ const header = compat.sessionAffinityFormat === "openrouter" ? "x-session-id" : "x-session-affinity";
789
+ sessionAffinityHeaders[header] = sessionId;
790
+ }
791
+ const defaultHeaders = mergeClientHeaders({
690
792
  accept: "application/json",
691
793
  "anthropic-dangerous-direct-browser-access": "true",
692
- ...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
693
794
  }, sessionAffinityHeaders, model.headers, optionsHeaders);
694
- const client = new Anthropic({
795
+ if (federation) {
796
+ const key = JSON.stringify([model.baseUrl, federation]);
797
+ if (federationClient?.key !== key || federationClient.fetch !== fetch) {
798
+ const client = new PiAnthropic({
799
+ apiKey: null,
800
+ authToken: null,
801
+ config: federation,
802
+ baseURL: model.baseUrl,
803
+ dangerouslyAllowBrowser: true,
804
+ fetch,
805
+ });
806
+ federationClient = { key, fetch, client };
807
+ }
808
+ return { client: federationClient.client.withOptions({ defaultHeaders }), isOAuthToken: false };
809
+ }
810
+ const client = new PiAnthropic({
695
811
  apiKey: apiKey ?? null,
696
812
  authToken: null,
697
813
  baseURL: model.baseUrl,
@@ -701,24 +817,70 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
701
817
  });
702
818
  return { client, isOAuthToken: false };
703
819
  }
820
+ function getBetaFeatures(model, context, isOAuthToken, nativeToolChanges, options) {
821
+ let configuredFeatures;
822
+ for (const headers of [model.headers, options?.headers]) {
823
+ for (const [name, value] of Object.entries(headers ?? {})) {
824
+ if (name.toLowerCase() === "anthropic-beta")
825
+ configuredFeatures = value;
826
+ }
827
+ }
828
+ if (configuredFeatures === null)
829
+ return [];
830
+ if (configuredFeatures !== undefined) {
831
+ return [
832
+ ...new Set(configuredFeatures
833
+ .split(",")
834
+ .map((feature) => feature.trim())
835
+ .filter((feature) => feature.length > 0)),
836
+ ];
837
+ }
838
+ const features = [];
839
+ if (isOAuthToken)
840
+ features.push("claude-code-20250219", "oauth-2025-04-20");
841
+ if (shouldUseFineGrainedToolStreamingBeta(model, context))
842
+ features.push(FINE_GRAINED_TOOL_STREAMING_BETA);
843
+ if (model.reasoning &&
844
+ options?.thinkingEnabled === true &&
845
+ (options.interleavedThinking ?? true) &&
846
+ model.compat?.forceAdaptiveThinking !== true) {
847
+ features.push(INTERLEAVED_THINKING_BETA);
848
+ }
849
+ if (shouldUseServerSideFallbackBeta(model))
850
+ features.push(SERVER_SIDE_FALLBACK_BETA);
851
+ if (model.compat?.supportsMidConvoEffort === true) {
852
+ features.push(MID_CONVERSATION_OUTPUT_CONFIG_BETA, THINKING_BINDING_CONTROLS_BETA);
853
+ }
854
+ if (nativeToolChanges)
855
+ features.push(MID_CONVERSATION_TOOL_CHANGES_BETA);
856
+ return [...new Set(features)];
857
+ }
704
858
  function buildParams(model, context, isOAuthToken, options) {
705
859
  const { cacheControl } = getCacheControl(model, options?.cacheRetention, options?.env);
706
860
  const compat = getAnthropicCompat(model);
861
+ const initialSystemMessage = getInitialSystemMessage(context.messages);
862
+ const initialSystemText = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : "";
707
863
  const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
708
- const normalizeToolName = isOAuthToken ? toClaudeCodeName : (name) => name;
709
- const toolPlacement = splitDeferredTools({ ...context, messages: transformedMessages }, compat.supportsToolReferences, normalizeToolName);
710
- let immediateTools = toolPlacement.immediate;
711
- let deferredTools = [...toolPlacement.deferred.values()];
712
- if (immediateTools.length === 0 && deferredTools.length > 0) {
713
- immediateTools = deferredTools;
714
- deferredTools = [];
715
- }
716
- const deferredToolNames = new Set(deferredTools.map((tool) => normalizeToolName(tool.name)));
864
+ const conversationMessages = initialSystemMessage ? transformedMessages.slice(1) : transformedMessages;
865
+ // Native tool changes reference tools by name, so a redefined name cannot be expressed,
866
+ // and Anthropic rejects a tool list where every tool is deferred, so there must be an
867
+ // initial active tool to anchor the deferred ones. Otherwise the current tool list is sent.
868
+ const initialTools = initialSystemMessage?.toolsAdded ?? [];
869
+ const nativeToolChanges = compat.supportsMidConvoSystemMessages &&
870
+ compat.supportsMidConvoToolChanges &&
871
+ initialTools.length > 0 &&
872
+ !hasToolRedefinitions(context.messages);
873
+ const converted = convertMessages(conversationMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, model.compat?.supportsMidConvoEffort === true ? model.provider : undefined, nativeToolChanges);
874
+ const activeEffort = options?.effort ?? "high";
875
+ const betaFeatures = getBetaFeatures(model, context, isOAuthToken, nativeToolChanges, options);
717
876
  const params = {
718
877
  model: model.id,
719
- messages: convertMessages(transformedMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, deferredToolNames, normalizeToolName),
878
+ messages: model.compat?.supportsMidConvoEffort === true
879
+ ? insertThinkingLevelMessages(converted, activeEffort)
880
+ : converted.messages,
720
881
  max_tokens: options?.maxTokens ?? model.maxTokens,
721
882
  stream: true,
883
+ ...(betaFeatures.length > 0 ? { betas: betaFeatures } : {}),
722
884
  };
723
885
  // For OAuth tokens, we MUST include Claude Code identity
724
886
  if (isOAuthToken) {
@@ -729,36 +891,62 @@ function buildParams(model, context, isOAuthToken, options) {
729
891
  ...(cacheControl ? { cache_control: cacheControl } : {}),
730
892
  },
731
893
  ];
732
- if (context.systemPrompt) {
894
+ if (initialSystemText) {
733
895
  params.system.push({
734
896
  type: "text",
735
- text: sanitizeSurrogates(context.systemPrompt),
897
+ text: sanitizeSurrogates(initialSystemText),
736
898
  ...(cacheControl ? { cache_control: cacheControl } : {}),
737
899
  });
738
900
  }
739
901
  }
740
- else if (context.systemPrompt) {
902
+ else if (initialSystemText) {
741
903
  // Add cache control to system prompt for non-OAuth tokens
742
904
  params.system = [
743
905
  {
744
906
  type: "text",
745
- text: sanitizeSurrogates(context.systemPrompt),
907
+ text: sanitizeSurrogates(initialSystemText),
746
908
  ...(cacheControl ? { cache_control: cacheControl } : {}),
747
909
  },
748
910
  ];
749
911
  }
750
912
  // Temperature is incompatible with extended thinking and unsupported on Claude Opus 4.7+.
751
- if (options?.temperature !== undefined && !options?.thinkingEnabled && compat.supportsTemperature) {
913
+ if (options?.temperature !== undefined &&
914
+ !options?.thinkingEnabled &&
915
+ model.compat?.supportsMidConvoEffort !== true &&
916
+ compat.supportsTemperature) {
752
917
  params.temperature = options.temperature;
753
918
  }
754
- if (immediateTools.length > 0 || deferredTools.length > 0) {
919
+ const toolCacheControl = compat.supportsCacheControlOnTools ? cacheControl : undefined;
920
+ if (nativeToolChanges) {
921
+ // Initial tools stay active with the cache breakpoint on the last one. Every later
922
+ // declaration is deferred and only surfaced by its `tool_addition` block; removed
923
+ // tools stay declared and are withdrawn by `tool_removal`. The request-level list
924
+ // therefore only grows, keeping the cached prefix intact across tool changes.
925
+ const initialNames = new Set(initialTools.map((tool) => tool.name));
926
+ const laterTools = getDeclaredTools(context.messages).filter((tool) => !initialNames.has(tool.name));
755
927
  params.tools = [
756
- ...convertTools(immediateTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, compat.supportsCacheControlOnTools ? cacheControl : undefined),
757
- ...convertTools(deferredTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, undefined, true),
928
+ ...convertTools(initialTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl),
929
+ DEFERRED_TOOL_PLACEHOLDER,
930
+ ...convertTools(laterTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools).map((tool) => ({ ...tool, defer_loading: true })),
758
931
  ];
759
932
  }
760
- // Configure thinking mode: adaptive, budget-based, or explicitly disabled.
761
- if (model.reasoning) {
933
+ else {
934
+ const tools = getCurrentTools(context.messages);
935
+ if (tools.length > 0) {
936
+ params.tools = convertTools(tools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, toolCacheControl);
937
+ }
938
+ }
939
+ // Managed effort models always use adaptive thinking so prefix mismatches can
940
+ // be dropped instead of surfacing as persistent 400 responses.
941
+ if (model.compat?.supportsMidConvoEffort === true) {
942
+ params.thinking = {
943
+ type: "adaptive",
944
+ display: options?.thinkingDisplay ?? "summarized",
945
+ block_binding: { prefix_mismatch_behavior: "drop_block" },
946
+ };
947
+ params.output_config = { effort: "high" };
948
+ }
949
+ else if (model.reasoning) {
762
950
  if (options?.thinkingEnabled) {
763
951
  // Default to "summarized" so Opus 4.7 and Mythos Preview behave like
764
952
  // older Claude 4 models (whose API default is also "summarized").
@@ -767,11 +955,7 @@ function buildParams(model, context, isOAuthToken, options) {
767
955
  // Adaptive thinking: Claude decides when and how much to think.
768
956
  params.thinking = { type: "adaptive", display };
769
957
  if (options.effort) {
770
- // The Anthropic SDK types can lag newly supported effort values such as "xhigh".
771
- params.output_config =
772
- options.effort === "xhigh"
773
- ? { effort: options.effort }
774
- : { effort: options.effort };
958
+ params.output_config = { effort: options.effort };
775
959
  }
776
960
  }
777
961
  else {
@@ -801,46 +985,64 @@ function buildParams(model, context, isOAuthToken, options) {
801
985
  params.tool_choice = options.toolChoice;
802
986
  }
803
987
  }
988
+ const allowedFallbackModels = model.compat?.allowedFallbackModels;
989
+ if (allowedFallbackModels && allowedFallbackModels.length > 0) {
990
+ params.fallbacks = allowedFallbackModels.map((fallback) => ({ model: fallback.model }));
991
+ }
804
992
  return params;
805
993
  }
806
994
  // Normalize tool call IDs to match Anthropic's required pattern and length
807
995
  function normalizeToolCallId(id) {
808
996
  return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
809
997
  }
810
- function convertToolResult(msg, isOAuthToken, deferredToolNames, loadedToolNames, normalizeToolName) {
811
- const references = [];
812
- for (const name of msg.addedToolNames ?? []) {
813
- const normalizedName = normalizeToolName(name);
814
- if (!deferredToolNames.has(normalizedName) || loadedToolNames.has(normalizedName))
815
- continue;
816
- loadedToolNames.add(normalizedName);
817
- references.push({
818
- type: "tool_reference",
819
- tool_name: isOAuthToken ? toClaudeCodeName(name) : name,
820
- });
821
- }
822
- const convertedContent = convertContentBlocks(msg.content);
823
- // Anthropic rejects tool references mixed with ordinary tool-result content.
998
+ function convertToolResult(msg) {
824
999
  return {
825
- toolResult: {
826
- type: "tool_result",
827
- tool_use_id: msg.toolCallId,
828
- content: references.length > 0 ? references : convertedContent,
829
- is_error: msg.isError,
830
- },
831
- siblingContent: references.length === 0
832
- ? []
833
- : typeof convertedContent === "string"
834
- ? [{ type: "text", text: convertedContent }]
835
- : convertedContent,
1000
+ type: "tool_result",
1001
+ tool_use_id: msg.toolCallId,
1002
+ content: convertContentBlocks(msg.content),
1003
+ is_error: msg.isError,
836
1004
  };
837
1005
  }
838
- function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, deferredToolNames = new Set(), normalizeToolName = (name) => name) {
1006
+ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, managedProvider, nativeToolChanges = false) {
839
1007
  const params = [];
840
- const loadedToolNames = new Set();
1008
+ const assistantLevels = new Map();
1009
+ // Later system messages are held back and emitted directly before the next assistant
1010
+ // message (or at the end of the transcript). Anthropic requires `tool_result` blocks to
1011
+ // immediately follow their `tool_use`, so a system message between them is rejected; this
1012
+ // also mirrors where the managed-effort system messages are inserted. As a result an
1013
+ // update placed before a user message in the transcript lands after it on the wire.
1014
+ const pendingSystemMessages = [];
1015
+ const flushPendingSystemMessages = () => {
1016
+ params.push(...pendingSystemMessages);
1017
+ pendingSystemMessages.length = 0;
1018
+ };
841
1019
  for (let i = 0; i < transformedMessages.length; i++) {
842
1020
  const msg = transformedMessages[i];
843
- if (msg.role === "user") {
1021
+ if (msg.role === "system") {
1022
+ // Later system messages only reach this point when the model accepts them natively;
1023
+ // otherwise the transcript was collapsed into the leading message before conversion.
1024
+ const text = renderSystemMessageUpdate(msg);
1025
+ const blocks = [];
1026
+ if (text.length > 0)
1027
+ blocks.push({ type: "text", text: sanitizeSurrogates(text) });
1028
+ if (nativeToolChanges) {
1029
+ for (const tool of msg.toolsRemoved ?? []) {
1030
+ blocks.push({
1031
+ type: "tool_removal",
1032
+ tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
1033
+ });
1034
+ }
1035
+ for (const tool of msg.toolsAdded ?? []) {
1036
+ blocks.push({
1037
+ type: "tool_addition",
1038
+ tool: { type: "tool_reference", name: isOAuthToken ? toClaudeCodeName(tool.name) : tool.name },
1039
+ });
1040
+ }
1041
+ }
1042
+ if (blocks.length > 0)
1043
+ pendingSystemMessages.push({ role: "system", content: blocks });
1044
+ }
1045
+ else if (msg.role === "user") {
844
1046
  if (typeof msg.content === "string") {
845
1047
  if (msg.content.trim().length > 0) {
846
1048
  params.push({
@@ -883,6 +1085,7 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
883
1085
  }
884
1086
  }
885
1087
  else if (msg.role === "assistant") {
1088
+ flushPendingSystemMessages();
886
1089
  const blocks = [];
887
1090
  for (const block of msg.content) {
888
1091
  if (block.type === "text") {
@@ -940,39 +1143,47 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
940
1143
  }
941
1144
  if (blocks.length === 0)
942
1145
  continue;
1146
+ const messageIndex = params.length;
943
1147
  params.push({
944
1148
  role: "assistant",
945
1149
  content: blocks,
946
1150
  });
1151
+ if (managedProvider !== undefined &&
1152
+ msg.api === "anthropic-messages" &&
1153
+ msg.provider === managedProvider &&
1154
+ isAnthropicEffort(msg.providerThinkingLevel)) {
1155
+ assistantLevels.set(messageIndex, msg.providerThinkingLevel);
1156
+ }
947
1157
  }
948
1158
  else if (msg.role === "toolResult") {
949
1159
  // Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint.
950
1160
  const toolResults = [];
951
- const siblingContent = [];
952
1161
  let j = i;
953
1162
  while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
954
- const converted = convertToolResult(transformedMessages[j], isOAuthToken, deferredToolNames, loadedToolNames, normalizeToolName);
955
- toolResults.push(converted.toolResult);
956
- siblingContent.push(...converted.siblingContent);
1163
+ toolResults.push(convertToolResult(transformedMessages[j]));
957
1164
  j++;
958
1165
  }
959
1166
  // Skip the messages we've already processed.
960
1167
  i = j - 1;
961
- // Displaced reference-bearing results must follow every tool_result block.
962
1168
  params.push({
963
1169
  role: "user",
964
- content: [...toolResults, ...siblingContent],
1170
+ content: toolResults,
965
1171
  });
966
1172
  }
967
1173
  }
968
- // Add cache_control to the last user message to cache conversation history
1174
+ flushPendingSystemMessages();
1175
+ // Add cache_control to the last user or system message to cache conversation history
969
1176
  if (cacheControl && params.length > 0) {
970
1177
  const lastMessage = params[params.length - 1];
971
- if (lastMessage.role === "user") {
1178
+ if (lastMessage.role === "user" || lastMessage.role === "system") {
972
1179
  if (Array.isArray(lastMessage.content)) {
973
1180
  const lastBlock = lastMessage.content[lastMessage.content.length - 1];
974
1181
  if (lastBlock &&
975
- (lastBlock.type === "text" || lastBlock.type === "image" || lastBlock.type === "tool_result")) {
1182
+ (lastBlock.type === "text" ||
1183
+ lastBlock.type === "image" ||
1184
+ lastBlock.type === "tool_result" ||
1185
+ lastBlock.type === "tool_addition" ||
1186
+ lastBlock.type === "tool_removal")) {
976
1187
  lastBlock.cache_control = cacheControl;
977
1188
  }
978
1189
  }
@@ -987,17 +1198,69 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
987
1198
  }
988
1199
  }
989
1200
  }
990
- return params;
1201
+ return { messages: params, assistantLevels };
1202
+ }
1203
+ function isAnthropicEffort(value) {
1204
+ return value === "low" || value === "medium" || value === "high" || value === "xhigh" || value === "max";
1205
+ }
1206
+ function insertThinkingLevelMessages(converted, activeEffort) {
1207
+ const messages = [];
1208
+ for (let index = 0; index < converted.messages.length; index++) {
1209
+ const historicalEffort = converted.assistantLevels.get(index);
1210
+ if (historicalEffort !== undefined) {
1211
+ messages.push({ role: "system", content: [], output_config: { effort: historicalEffort } });
1212
+ }
1213
+ messages.push(converted.messages[index]);
1214
+ }
1215
+ messages.push({ role: "system", content: [], output_config: { effort: activeEffort } });
1216
+ return messages;
991
1217
  }
992
1218
  function shouldUseFineGrainedToolStreamingBeta(model, context) {
993
- return !!context.tools?.length && !getAnthropicCompat(model).supportsEagerToolInputStreaming;
1219
+ return getCurrentTools(context.messages).length > 0 && !getAnthropicCompat(model).supportsEagerToolInputStreaming;
994
1220
  }
995
- function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supportsStrictTools, cacheControl, deferLoading = false) {
1221
+ // Keywords Anthropic strict tool use rejects with a 400 for the whole request.
1222
+ // https://platform.claude.com/docs/en/build-with-claude/structured-outputs#json-schema-limitations
1223
+ const ANTHROPIC_STRICT_UNSUPPORTED_KEYWORDS = new Set([
1224
+ "minimum",
1225
+ "maximum",
1226
+ "exclusiveMinimum",
1227
+ "exclusiveMaximum",
1228
+ "multipleOf",
1229
+ "maxItems",
1230
+ "uniqueItems",
1231
+ "minContains",
1232
+ "maxContains",
1233
+ "minProperties",
1234
+ "maxProperties",
1235
+ ]);
1236
+ const ANTHROPIC_STRICT_STRING_FORMATS = new Set([
1237
+ "date-time",
1238
+ "time",
1239
+ "date",
1240
+ "duration",
1241
+ "email",
1242
+ "hostname",
1243
+ "uri",
1244
+ "ipv4",
1245
+ "ipv6",
1246
+ "uuid",
1247
+ ]);
1248
+ const isAnthropicStrictUnsupportedKeyword = (key, value) => {
1249
+ if (ANTHROPIC_STRICT_UNSUPPORTED_KEYWORDS.has(key))
1250
+ return true;
1251
+ if (key === "minItems")
1252
+ return value !== 0 && value !== 1;
1253
+ if (key === "format")
1254
+ return typeof value !== "string" || !ANTHROPIC_STRICT_STRING_FORMATS.has(value);
1255
+ return false;
1256
+ };
1257
+ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supportsStrictTools, cacheControl) {
996
1258
  if (!tools)
997
1259
  return [];
998
1260
  return tools.map((tool, index) => {
999
- const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools);
1000
- const schema = tool.parameters;
1261
+ const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools, isAnthropicStrictUnsupportedKeyword);
1262
+ const parameters = getJsonSchemaToolParameters(tool, strict);
1263
+ const schema = parameters;
1001
1264
  const legacyInputSchema = {
1002
1265
  type: "object",
1003
1266
  properties: schema.properties ?? {},
@@ -1005,7 +1268,7 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
1005
1268
  };
1006
1269
  const inputSchema = strict === true
1007
1270
  ? {
1008
- ...tool.parameters,
1271
+ ...parameters,
1009
1272
  ...legacyInputSchema,
1010
1273
  }
1011
1274
  : legacyInputSchema;
@@ -1015,7 +1278,6 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
1015
1278
  ...(supportsEagerToolInputStreaming ? { eager_input_streaming: true } : {}),
1016
1279
  ...(strict === true ? { strict: true } : {}),
1017
1280
  input_schema: inputSchema,
1018
- ...(deferLoading ? { defer_loading: true } : {}),
1019
1281
  ...(cacheControl && index === tools.length - 1 ? { cache_control: cacheControl } : {}),
1020
1282
  };
1021
1283
  });