@draht/ai 2026.9.5-1 → 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 (598) hide show
  1. package/dist/api/anthropic-messages.d.ts.map +1 -1
  2. package/dist/api/anthropic-messages.js +392 -137
  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 -11
  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 +194 -22
  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.map +1 -1
  32. package/dist/api/google-generative-ai.js +26 -73
  33. package/dist/api/google-generative-ai.js.map +1 -1
  34. package/dist/api/google-shared.d.ts +14 -5
  35. package/dist/api/google-shared.d.ts.map +1 -1
  36. package/dist/api/google-shared.js +68 -13
  37. package/dist/api/google-shared.js.map +1 -1
  38. package/dist/api/google-vertex.d.ts.map +1 -1
  39. package/dist/api/google-vertex.js +30 -65
  40. package/dist/api/google-vertex.js.map +1 -1
  41. package/dist/api/lazy.d.ts +5 -1
  42. package/dist/api/lazy.d.ts.map +1 -1
  43. package/dist/api/lazy.js +19 -7
  44. package/dist/api/lazy.js.map +1 -1
  45. package/dist/api/llama-cpp-classify.d.ts +33 -0
  46. package/dist/api/llama-cpp-classify.d.ts.map +1 -0
  47. package/dist/api/llama-cpp-classify.js +365 -0
  48. package/dist/api/llama-cpp-classify.js.map +1 -0
  49. package/dist/api/llama-cpp-classify.lazy.d.ts +3 -0
  50. package/dist/api/llama-cpp-classify.lazy.d.ts.map +1 -0
  51. package/dist/api/llama-cpp-classify.lazy.js +4 -0
  52. package/dist/api/llama-cpp-classify.lazy.js.map +1 -0
  53. package/dist/api/mistral-conversations.d.ts +2 -2
  54. package/dist/api/mistral-conversations.d.ts.map +1 -1
  55. package/dist/api/mistral-conversations.js +246 -69
  56. package/dist/api/mistral-conversations.js.map +1 -1
  57. package/dist/api/openai-codex-responses.d.ts.map +1 -1
  58. package/dist/api/openai-codex-responses.js +58 -24
  59. package/dist/api/openai-codex-responses.js.map +1 -1
  60. package/dist/api/openai-completions.d.ts +11 -4
  61. package/dist/api/openai-completions.d.ts.map +1 -1
  62. package/dist/api/openai-completions.js +232 -126
  63. package/dist/api/openai-completions.js.map +1 -1
  64. package/dist/api/openai-responses-shared.d.ts +8 -4
  65. package/dist/api/openai-responses-shared.d.ts.map +1 -1
  66. package/dist/api/openai-responses-shared.js +109 -58
  67. package/dist/api/openai-responses-shared.js.map +1 -1
  68. package/dist/api/openai-responses.d.ts.map +1 -1
  69. package/dist/api/openai-responses.js +58 -24
  70. package/dist/api/openai-responses.js.map +1 -1
  71. package/dist/api/openrouter-images.d.ts +2 -1
  72. package/dist/api/openrouter-images.d.ts.map +1 -1
  73. package/dist/api/openrouter-images.js +1 -0
  74. package/dist/api/openrouter-images.js.map +1 -1
  75. package/dist/api/openrouter-images.lazy.d.ts.map +1 -1
  76. package/dist/api/openrouter-images.lazy.js.map +1 -1
  77. package/dist/api/pi-messages.d.ts +5 -3
  78. package/dist/api/pi-messages.d.ts.map +1 -1
  79. package/dist/api/pi-messages.js +12 -3
  80. package/dist/api/pi-messages.js.map +1 -1
  81. package/dist/api/simple-options.d.ts +9 -3
  82. package/dist/api/simple-options.d.ts.map +1 -1
  83. package/dist/api/simple-options.js +22 -11
  84. package/dist/api/simple-options.js.map +1 -1
  85. package/dist/api/system-one-shared.d.ts +23 -0
  86. package/dist/api/system-one-shared.d.ts.map +1 -0
  87. package/dist/api/system-one-shared.js +183 -0
  88. package/dist/api/system-one-shared.js.map +1 -0
  89. package/dist/api/transform-messages.d.ts.map +1 -1
  90. package/dist/api/transform-messages.js +21 -7
  91. package/dist/api/transform-messages.js.map +1 -1
  92. package/dist/api/typesafe-system-one.d.ts +4 -0
  93. package/dist/api/typesafe-system-one.d.ts.map +1 -0
  94. package/dist/api/typesafe-system-one.js +19 -0
  95. package/dist/api/typesafe-system-one.js.map +1 -0
  96. package/dist/api/typesafe-system-one.lazy.d.ts +3 -0
  97. package/dist/api/typesafe-system-one.lazy.d.ts.map +1 -0
  98. package/dist/api/typesafe-system-one.lazy.js +4 -0
  99. package/dist/api/typesafe-system-one.lazy.js.map +1 -0
  100. package/dist/auth/credential-store.d.ts +6 -6
  101. package/dist/auth/credential-store.d.ts.map +1 -1
  102. package/dist/auth/credential-store.js +24 -15
  103. package/dist/auth/credential-store.js.map +1 -1
  104. package/dist/auth/helpers.d.ts +1 -0
  105. package/dist/auth/helpers.d.ts.map +1 -1
  106. package/dist/auth/helpers.js +8 -3
  107. package/dist/auth/helpers.js.map +1 -1
  108. package/dist/auth/oauth/anthropic.d.ts.map +1 -1
  109. package/dist/auth/oauth/anthropic.js +28 -131
  110. package/dist/auth/oauth/anthropic.js.map +1 -1
  111. package/dist/auth/oauth/callback-server.d.ts +55 -0
  112. package/dist/auth/oauth/callback-server.d.ts.map +1 -0
  113. package/dist/auth/oauth/callback-server.js +146 -0
  114. package/dist/auth/oauth/callback-server.js.map +1 -0
  115. package/dist/auth/oauth/device-code.d.ts +2 -1
  116. package/dist/auth/oauth/device-code.d.ts.map +1 -1
  117. package/dist/auth/oauth/device-code.js +5 -5
  118. package/dist/auth/oauth/device-code.js.map +1 -1
  119. package/dist/auth/oauth/github-copilot.d.ts.map +1 -1
  120. package/dist/auth/oauth/github-copilot.js +13 -9
  121. package/dist/auth/oauth/github-copilot.js.map +1 -1
  122. package/dist/auth/oauth/google-antigravity.d.ts +3 -3
  123. package/dist/auth/oauth/google-antigravity.d.ts.map +1 -1
  124. package/dist/auth/oauth/google-antigravity.js +17 -9
  125. package/dist/auth/oauth/google-antigravity.js.map +1 -1
  126. package/dist/auth/oauth/google-gemini-cli.d.ts +3 -3
  127. package/dist/auth/oauth/google-gemini-cli.d.ts.map +1 -1
  128. package/dist/auth/oauth/google-gemini-cli.js +18 -10
  129. package/dist/auth/oauth/google-gemini-cli.js.map +1 -1
  130. package/dist/auth/oauth/kimi-coding.d.ts.map +1 -1
  131. package/dist/auth/oauth/kimi-coding.js +5 -6
  132. package/dist/auth/oauth/kimi-coding.js.map +1 -1
  133. package/dist/auth/oauth/load.d.ts +4 -0
  134. package/dist/auth/oauth/load.d.ts.map +1 -1
  135. package/dist/auth/oauth/load.js +10 -0
  136. package/dist/auth/oauth/load.js.map +1 -1
  137. package/dist/auth/oauth/meta.d.ts +17 -0
  138. package/dist/auth/oauth/meta.d.ts.map +1 -0
  139. package/dist/auth/oauth/meta.js +190 -0
  140. package/dist/auth/oauth/meta.js.map +1 -0
  141. package/dist/auth/oauth/openai-chatgpt.d.ts +9 -0
  142. package/dist/auth/oauth/openai-chatgpt.d.ts.map +1 -0
  143. package/dist/auth/oauth/openai-chatgpt.js +266 -0
  144. package/dist/auth/oauth/openai-chatgpt.js.map +1 -0
  145. package/dist/auth/oauth/openai-codex.d.ts +1 -1
  146. package/dist/auth/oauth/openai-codex.d.ts.map +1 -1
  147. package/dist/auth/oauth/openai-codex.js +33 -130
  148. package/dist/auth/oauth/openai-codex.js.map +1 -1
  149. package/dist/auth/oauth/openrouter.d.ts +1 -1
  150. package/dist/auth/oauth/openrouter.d.ts.map +1 -1
  151. package/dist/auth/oauth/openrouter.js +26 -145
  152. package/dist/auth/oauth/openrouter.js.map +1 -1
  153. package/dist/auth/oauth/radius.d.ts +1 -1
  154. package/dist/auth/oauth/radius.d.ts.map +1 -1
  155. package/dist/auth/oauth/radius.js +28 -93
  156. package/dist/auth/oauth/radius.js.map +1 -1
  157. package/dist/auth/oauth/xai.d.ts.map +1 -1
  158. package/dist/auth/oauth/xai.js +13 -12
  159. package/dist/auth/oauth/xai.js.map +1 -1
  160. package/dist/auth/resolve.d.ts +3 -8
  161. package/dist/auth/resolve.d.ts.map +1 -1
  162. package/dist/auth/resolve.js +26 -31
  163. package/dist/auth/resolve.js.map +1 -1
  164. package/dist/auth/types.d.ts +29 -8
  165. package/dist/auth/types.d.ts.map +1 -1
  166. package/dist/auth/types.js.map +1 -1
  167. package/dist/bun-oauth.d.ts.map +1 -1
  168. package/dist/bun-oauth.js +4 -0
  169. package/dist/bun-oauth.js.map +1 -1
  170. package/dist/cli.js +4 -1
  171. package/dist/cli.js.map +1 -1
  172. package/dist/compat.d.ts +3 -3
  173. package/dist/compat.d.ts.map +1 -1
  174. package/dist/compat.js +9 -6
  175. package/dist/compat.js.map +1 -1
  176. package/dist/env-api-keys.d.ts +5 -0
  177. package/dist/env-api-keys.d.ts.map +1 -1
  178. package/dist/env-api-keys.js +9 -1
  179. package/dist/env-api-keys.js.map +1 -1
  180. package/dist/image-models.d.ts +19 -8
  181. package/dist/image-models.d.ts.map +1 -1
  182. package/dist/image-models.js +14 -13
  183. package/dist/image-models.js.map +1 -1
  184. package/dist/images-api-registry.d.ts +7 -7
  185. package/dist/images-api-registry.d.ts.map +1 -1
  186. package/dist/images-api-registry.js.map +1 -1
  187. package/dist/images.d.ts +7 -2
  188. package/dist/images.d.ts.map +1 -1
  189. package/dist/images.js +5 -0
  190. package/dist/images.js.map +1 -1
  191. package/dist/index.d.ts +3 -2
  192. package/dist/index.d.ts.map +1 -1
  193. package/dist/index.js +3 -2
  194. package/dist/index.js.map +1 -1
  195. package/dist/model-catalog.d.ts +25 -9
  196. package/dist/model-catalog.d.ts.map +1 -1
  197. package/dist/model-catalog.js +14 -2
  198. package/dist/model-catalog.js.map +1 -1
  199. package/dist/models-store.d.ts +12 -14
  200. package/dist/models-store.d.ts.map +1 -1
  201. package/dist/models-store.js +7 -6
  202. package/dist/models-store.js.map +1 -1
  203. package/dist/models.d.ts +138 -47
  204. package/dist/models.d.ts.map +1 -1
  205. package/dist/models.generated.d.ts +135 -37
  206. package/dist/models.generated.d.ts.map +1 -1
  207. package/dist/models.generated.js +135 -37
  208. package/dist/models.generated.js.map +1 -1
  209. package/dist/models.js +391 -99
  210. package/dist/models.js.map +1 -1
  211. package/dist/providers/all.d.ts +19 -13
  212. package/dist/providers/all.d.ts.map +1 -1
  213. package/dist/providers/all.js +31 -21
  214. package/dist/providers/all.js.map +1 -1
  215. package/dist/providers/amazon-bedrock.d.ts.map +1 -1
  216. package/dist/providers/amazon-bedrock.js +15 -7
  217. package/dist/providers/amazon-bedrock.js.map +1 -1
  218. package/dist/providers/amazon-bedrock.models.d.ts +4 -2
  219. package/dist/providers/amazon-bedrock.models.d.ts.map +1 -1
  220. package/dist/providers/amazon-bedrock.models.js +4 -2
  221. package/dist/providers/amazon-bedrock.models.js.map +1 -1
  222. package/dist/providers/ant-ling.models.d.ts +4 -2
  223. package/dist/providers/ant-ling.models.d.ts.map +1 -1
  224. package/dist/providers/ant-ling.models.js +4 -2
  225. package/dist/providers/ant-ling.models.js.map +1 -1
  226. package/dist/providers/anthropic.d.ts.map +1 -1
  227. package/dist/providers/anthropic.js +39 -8
  228. package/dist/providers/anthropic.js.map +1 -1
  229. package/dist/providers/anthropic.models.d.ts +4 -2
  230. package/dist/providers/anthropic.models.d.ts.map +1 -1
  231. package/dist/providers/anthropic.models.js +4 -2
  232. package/dist/providers/anthropic.models.js.map +1 -1
  233. package/dist/providers/azure-openai-responses.models.d.ts +4 -2
  234. package/dist/providers/azure-openai-responses.models.d.ts.map +1 -1
  235. package/dist/providers/azure-openai-responses.models.js +4 -2
  236. package/dist/providers/azure-openai-responses.models.js.map +1 -1
  237. package/dist/providers/baseten.d.ts +3 -0
  238. package/dist/providers/baseten.d.ts.map +1 -0
  239. package/dist/providers/baseten.js +15 -0
  240. package/dist/providers/baseten.js.map +1 -0
  241. package/dist/providers/baseten.models.d.ts +6 -0
  242. package/dist/providers/baseten.models.d.ts.map +1 -0
  243. package/dist/providers/baseten.models.js +8 -0
  244. package/dist/providers/baseten.models.js.map +1 -0
  245. package/dist/providers/cerebras.models.d.ts +4 -2
  246. package/dist/providers/cerebras.models.d.ts.map +1 -1
  247. package/dist/providers/cerebras.models.js +4 -2
  248. package/dist/providers/cerebras.models.js.map +1 -1
  249. package/dist/providers/cloudflare-ai-gateway.d.ts +3 -1
  250. package/dist/providers/cloudflare-ai-gateway.d.ts.map +1 -1
  251. package/dist/providers/cloudflare-ai-gateway.js +4 -0
  252. package/dist/providers/cloudflare-ai-gateway.js.map +1 -1
  253. package/dist/providers/cloudflare-ai-gateway.models.d.ts +4 -2
  254. package/dist/providers/cloudflare-ai-gateway.models.d.ts.map +1 -1
  255. package/dist/providers/cloudflare-ai-gateway.models.js +4 -2
  256. package/dist/providers/cloudflare-ai-gateway.models.js.map +1 -1
  257. package/dist/providers/cloudflare-auth.d.ts.map +1 -1
  258. package/dist/providers/cloudflare-auth.js +15 -10
  259. package/dist/providers/cloudflare-auth.js.map +1 -1
  260. package/dist/providers/cloudflare-stream.d.ts +6 -2
  261. package/dist/providers/cloudflare-stream.d.ts.map +1 -1
  262. package/dist/providers/cloudflare-stream.js +6 -0
  263. package/dist/providers/cloudflare-stream.js.map +1 -1
  264. package/dist/providers/cloudflare-workers-ai.d.ts.map +1 -1
  265. package/dist/providers/cloudflare-workers-ai.js +10 -3
  266. package/dist/providers/cloudflare-workers-ai.js.map +1 -1
  267. package/dist/providers/cloudflare-workers-ai.models.d.ts +4 -2
  268. package/dist/providers/cloudflare-workers-ai.models.d.ts.map +1 -1
  269. package/dist/providers/cloudflare-workers-ai.models.js +4 -2
  270. package/dist/providers/cloudflare-workers-ai.models.js.map +1 -1
  271. package/dist/providers/data/.manifest.json +1 -1
  272. package/dist/providers/data/amazon-bedrock.json +1 -1
  273. package/dist/providers/data/ant-ling.json +1 -1
  274. package/dist/providers/data/anthropic.json +1 -1
  275. package/dist/providers/data/azure-openai-responses.json +1 -1
  276. package/dist/providers/data/baseten.json +1 -0
  277. package/dist/providers/data/cerebras.json +1 -1
  278. package/dist/providers/data/cloudflare-ai-gateway.json +1 -1
  279. package/dist/providers/data/cloudflare-workers-ai.json +1 -1
  280. package/dist/providers/data/deepseek.json +1 -1
  281. package/dist/providers/data/fireworks.json +1 -1
  282. package/dist/providers/data/github-copilot.json +1 -1
  283. package/dist/providers/data/google-vertex.json +1 -1
  284. package/dist/providers/data/google.json +1 -1
  285. package/dist/providers/data/groq.json +1 -1
  286. package/dist/providers/data/huggingface.json +1 -1
  287. package/dist/providers/data/kimi-coding.json +1 -1
  288. package/dist/providers/data/meta.json +1 -0
  289. package/dist/providers/data/minimax-cn.json +1 -1
  290. package/dist/providers/data/minimax.json +1 -1
  291. package/dist/providers/data/mistral.json +1 -1
  292. package/dist/providers/data/moonshotai-cn.json +1 -1
  293. package/dist/providers/data/moonshotai.json +1 -1
  294. package/dist/providers/data/nvidia.json +1 -1
  295. package/dist/providers/data/openai-codex.json +1 -1
  296. package/dist/providers/data/openai.json +1 -1
  297. package/dist/providers/data/opencode-go.json +1 -1
  298. package/dist/providers/data/opencode.json +1 -1
  299. package/dist/providers/data/openrouter.json +1 -1
  300. package/dist/providers/data/qwen-token-plan-cn.json +1 -1
  301. package/dist/providers/data/qwen-token-plan-individual.json +1 -0
  302. package/dist/providers/data/qwen-token-plan.json +1 -1
  303. package/dist/providers/data/radius.json +1 -0
  304. package/dist/providers/data/together.json +1 -1
  305. package/dist/providers/data/typesafe.json +1 -0
  306. package/dist/providers/data/vercel-ai-gateway.json +1 -1
  307. package/dist/providers/data/xai.json +1 -1
  308. package/dist/providers/data/xiaomi-token-plan-ams.json +1 -1
  309. package/dist/providers/data/xiaomi-token-plan-cn.json +1 -1
  310. package/dist/providers/data/xiaomi-token-plan-sgp.json +1 -1
  311. package/dist/providers/data/xiaomi.json +1 -1
  312. package/dist/providers/data/zai-coding-cn.json +1 -1
  313. package/dist/providers/data/zai.json +1 -1
  314. package/dist/providers/deepseek.models.d.ts +4 -2
  315. package/dist/providers/deepseek.models.d.ts.map +1 -1
  316. package/dist/providers/deepseek.models.js +4 -2
  317. package/dist/providers/deepseek.models.js.map +1 -1
  318. package/dist/providers/faux.d.ts +19 -13
  319. package/dist/providers/faux.d.ts.map +1 -1
  320. package/dist/providers/faux.js +109 -18
  321. package/dist/providers/faux.js.map +1 -1
  322. package/dist/providers/fireworks.models.d.ts +4 -2
  323. package/dist/providers/fireworks.models.d.ts.map +1 -1
  324. package/dist/providers/fireworks.models.js +4 -2
  325. package/dist/providers/fireworks.models.js.map +1 -1
  326. package/dist/providers/github-copilot.js +1 -1
  327. package/dist/providers/github-copilot.js.map +1 -1
  328. package/dist/providers/github-copilot.models.d.ts +4 -2
  329. package/dist/providers/github-copilot.models.d.ts.map +1 -1
  330. package/dist/providers/github-copilot.models.js +4 -2
  331. package/dist/providers/github-copilot.models.js.map +1 -1
  332. package/dist/providers/google-vertex.d.ts.map +1 -1
  333. package/dist/providers/google-vertex.js +15 -7
  334. package/dist/providers/google-vertex.js.map +1 -1
  335. package/dist/providers/google-vertex.models.d.ts +4 -2
  336. package/dist/providers/google-vertex.models.d.ts.map +1 -1
  337. package/dist/providers/google-vertex.models.js +4 -2
  338. package/dist/providers/google-vertex.models.js.map +1 -1
  339. package/dist/providers/google.models.d.ts +4 -2
  340. package/dist/providers/google.models.d.ts.map +1 -1
  341. package/dist/providers/google.models.js +4 -2
  342. package/dist/providers/google.models.js.map +1 -1
  343. package/dist/providers/groq.models.d.ts +4 -2
  344. package/dist/providers/groq.models.d.ts.map +1 -1
  345. package/dist/providers/groq.models.js +4 -2
  346. package/dist/providers/groq.models.js.map +1 -1
  347. package/dist/providers/huggingface.models.d.ts +4 -2
  348. package/dist/providers/huggingface.models.d.ts.map +1 -1
  349. package/dist/providers/huggingface.models.js +4 -2
  350. package/dist/providers/huggingface.models.js.map +1 -1
  351. package/dist/providers/images/register-builtins.d.ts +1 -1
  352. package/dist/providers/images/register-builtins.d.ts.map +1 -1
  353. package/dist/providers/images/register-builtins.js.map +1 -1
  354. package/dist/providers/kimi-coding.d.ts.map +1 -1
  355. package/dist/providers/kimi-coding.js +1 -0
  356. package/dist/providers/kimi-coding.js.map +1 -1
  357. package/dist/providers/kimi-coding.models.d.ts +4 -2
  358. package/dist/providers/kimi-coding.models.d.ts.map +1 -1
  359. package/dist/providers/kimi-coding.models.js +4 -2
  360. package/dist/providers/kimi-coding.models.js.map +1 -1
  361. package/dist/providers/meta.d.ts +3 -0
  362. package/dist/providers/meta.d.ts.map +1 -0
  363. package/dist/providers/meta.js +24 -0
  364. package/dist/providers/meta.js.map +1 -0
  365. package/dist/providers/meta.models.d.ts +6 -0
  366. package/dist/providers/meta.models.d.ts.map +1 -0
  367. package/dist/providers/meta.models.js +8 -0
  368. package/dist/providers/meta.models.js.map +1 -0
  369. package/dist/providers/minimax-cn.models.d.ts +4 -2
  370. package/dist/providers/minimax-cn.models.d.ts.map +1 -1
  371. package/dist/providers/minimax-cn.models.js +4 -2
  372. package/dist/providers/minimax-cn.models.js.map +1 -1
  373. package/dist/providers/minimax.models.d.ts +4 -2
  374. package/dist/providers/minimax.models.d.ts.map +1 -1
  375. package/dist/providers/minimax.models.js +4 -2
  376. package/dist/providers/minimax.models.js.map +1 -1
  377. package/dist/providers/mistral.models.d.ts +4 -2
  378. package/dist/providers/mistral.models.d.ts.map +1 -1
  379. package/dist/providers/mistral.models.js +4 -2
  380. package/dist/providers/mistral.models.js.map +1 -1
  381. package/dist/providers/moonshotai-cn.models.d.ts +4 -2
  382. package/dist/providers/moonshotai-cn.models.d.ts.map +1 -1
  383. package/dist/providers/moonshotai-cn.models.js +4 -2
  384. package/dist/providers/moonshotai-cn.models.js.map +1 -1
  385. package/dist/providers/moonshotai.models.d.ts +4 -2
  386. package/dist/providers/moonshotai.models.d.ts.map +1 -1
  387. package/dist/providers/moonshotai.models.js +4 -2
  388. package/dist/providers/moonshotai.models.js.map +1 -1
  389. package/dist/providers/nvidia.models.d.ts +4 -2
  390. package/dist/providers/nvidia.models.d.ts.map +1 -1
  391. package/dist/providers/nvidia.models.js +4 -2
  392. package/dist/providers/nvidia.models.js.map +1 -1
  393. package/dist/providers/openai-codex.d.ts.map +1 -1
  394. package/dist/providers/openai-codex.js +6 -2
  395. package/dist/providers/openai-codex.js.map +1 -1
  396. package/dist/providers/openai-codex.models.d.ts +4 -2
  397. package/dist/providers/openai-codex.models.d.ts.map +1 -1
  398. package/dist/providers/openai-codex.models.js +4 -2
  399. package/dist/providers/openai-codex.models.js.map +1 -1
  400. package/dist/providers/openai.d.ts.map +1 -1
  401. package/dist/providers/openai.js +11 -2
  402. package/dist/providers/openai.js.map +1 -1
  403. package/dist/providers/openai.models.d.ts +4 -2
  404. package/dist/providers/openai.models.d.ts.map +1 -1
  405. package/dist/providers/openai.models.js +4 -2
  406. package/dist/providers/openai.models.js.map +1 -1
  407. package/dist/providers/opencode-go.d.ts.map +1 -1
  408. package/dist/providers/opencode-go.js +4 -3
  409. package/dist/providers/opencode-go.js.map +1 -1
  410. package/dist/providers/opencode-go.models.d.ts +4 -2
  411. package/dist/providers/opencode-go.models.d.ts.map +1 -1
  412. package/dist/providers/opencode-go.models.js +4 -2
  413. package/dist/providers/opencode-go.models.js.map +1 -1
  414. package/dist/providers/opencode-headers.d.ts +4 -0
  415. package/dist/providers/opencode-headers.d.ts.map +1 -0
  416. package/dist/providers/opencode-headers.js +22 -0
  417. package/dist/providers/opencode-headers.js.map +1 -0
  418. package/dist/providers/opencode.d.ts +3 -1
  419. package/dist/providers/opencode.d.ts.map +1 -1
  420. package/dist/providers/opencode.js +10 -6
  421. package/dist/providers/opencode.js.map +1 -1
  422. package/dist/providers/opencode.models.d.ts +4 -2
  423. package/dist/providers/opencode.models.d.ts.map +1 -1
  424. package/dist/providers/opencode.models.js +4 -2
  425. package/dist/providers/opencode.models.js.map +1 -1
  426. package/dist/providers/openrouter.d.ts +1 -1
  427. package/dist/providers/openrouter.d.ts.map +1 -1
  428. package/dist/providers/openrouter.js +16 -3
  429. package/dist/providers/openrouter.js.map +1 -1
  430. package/dist/providers/openrouter.models.d.ts +4 -2
  431. package/dist/providers/openrouter.models.d.ts.map +1 -1
  432. package/dist/providers/openrouter.models.js +4 -2
  433. package/dist/providers/openrouter.models.js.map +1 -1
  434. package/dist/providers/qwen-token-plan-cn.models.d.ts +4 -2
  435. package/dist/providers/qwen-token-plan-cn.models.d.ts.map +1 -1
  436. package/dist/providers/qwen-token-plan-cn.models.js +4 -2
  437. package/dist/providers/qwen-token-plan-cn.models.js.map +1 -1
  438. package/dist/providers/qwen-token-plan-individual.d.ts +3 -0
  439. package/dist/providers/qwen-token-plan-individual.d.ts.map +1 -0
  440. package/dist/providers/qwen-token-plan-individual.js +15 -0
  441. package/dist/providers/qwen-token-plan-individual.js.map +1 -0
  442. package/dist/providers/qwen-token-plan-individual.models.d.ts +6 -0
  443. package/dist/providers/qwen-token-plan-individual.models.d.ts.map +1 -0
  444. package/dist/providers/qwen-token-plan-individual.models.js +8 -0
  445. package/dist/providers/qwen-token-plan-individual.models.js.map +1 -0
  446. package/dist/providers/qwen-token-plan.models.d.ts +4 -2
  447. package/dist/providers/qwen-token-plan.models.d.ts.map +1 -1
  448. package/dist/providers/qwen-token-plan.models.js +4 -2
  449. package/dist/providers/qwen-token-plan.models.js.map +1 -1
  450. package/dist/providers/radius.d.ts.map +1 -1
  451. package/dist/providers/radius.js +53 -29
  452. package/dist/providers/radius.js.map +1 -1
  453. package/dist/providers/radius.models.d.ts +6 -0
  454. package/dist/providers/radius.models.d.ts.map +1 -0
  455. package/dist/providers/radius.models.js +8 -0
  456. package/dist/providers/radius.models.js.map +1 -0
  457. package/dist/providers/together.models.d.ts +4 -2
  458. package/dist/providers/together.models.d.ts.map +1 -1
  459. package/dist/providers/together.models.js +4 -2
  460. package/dist/providers/together.models.js.map +1 -1
  461. package/dist/providers/typesafe.d.ts +3 -0
  462. package/dist/providers/typesafe.d.ts.map +1 -0
  463. package/dist/providers/typesafe.js +18 -0
  464. package/dist/providers/typesafe.js.map +1 -0
  465. package/dist/providers/typesafe.models.d.ts +6 -0
  466. package/dist/providers/typesafe.models.d.ts.map +1 -0
  467. package/dist/providers/typesafe.models.js +8 -0
  468. package/dist/providers/typesafe.models.js.map +1 -0
  469. package/dist/providers/vercel-ai-gateway.d.ts.map +1 -1
  470. package/dist/providers/vercel-ai-gateway.js +5 -2
  471. package/dist/providers/vercel-ai-gateway.js.map +1 -1
  472. package/dist/providers/vercel-ai-gateway.models.d.ts +4 -2
  473. package/dist/providers/vercel-ai-gateway.models.d.ts.map +1 -1
  474. package/dist/providers/vercel-ai-gateway.models.js +4 -2
  475. package/dist/providers/vercel-ai-gateway.models.js.map +1 -1
  476. package/dist/providers/xai.d.ts.map +1 -1
  477. package/dist/providers/xai.js +1 -0
  478. package/dist/providers/xai.js.map +1 -1
  479. package/dist/providers/xai.models.d.ts +4 -2
  480. package/dist/providers/xai.models.d.ts.map +1 -1
  481. package/dist/providers/xai.models.js +4 -2
  482. package/dist/providers/xai.models.js.map +1 -1
  483. package/dist/providers/xiaomi-token-plan-ams.models.d.ts +4 -2
  484. package/dist/providers/xiaomi-token-plan-ams.models.d.ts.map +1 -1
  485. package/dist/providers/xiaomi-token-plan-ams.models.js +4 -2
  486. package/dist/providers/xiaomi-token-plan-ams.models.js.map +1 -1
  487. package/dist/providers/xiaomi-token-plan-cn.models.d.ts +4 -2
  488. package/dist/providers/xiaomi-token-plan-cn.models.d.ts.map +1 -1
  489. package/dist/providers/xiaomi-token-plan-cn.models.js +4 -2
  490. package/dist/providers/xiaomi-token-plan-cn.models.js.map +1 -1
  491. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts +4 -2
  492. package/dist/providers/xiaomi-token-plan-sgp.models.d.ts.map +1 -1
  493. package/dist/providers/xiaomi-token-plan-sgp.models.js +4 -2
  494. package/dist/providers/xiaomi-token-plan-sgp.models.js.map +1 -1
  495. package/dist/providers/xiaomi.models.d.ts +4 -2
  496. package/dist/providers/xiaomi.models.d.ts.map +1 -1
  497. package/dist/providers/xiaomi.models.js +4 -2
  498. package/dist/providers/xiaomi.models.js.map +1 -1
  499. package/dist/providers/zai-coding-cn.models.d.ts +4 -2
  500. package/dist/providers/zai-coding-cn.models.d.ts.map +1 -1
  501. package/dist/providers/zai-coding-cn.models.js +4 -2
  502. package/dist/providers/zai-coding-cn.models.js.map +1 -1
  503. package/dist/providers/zai.models.d.ts +4 -2
  504. package/dist/providers/zai.models.d.ts.map +1 -1
  505. package/dist/providers/zai.models.js +4 -2
  506. package/dist/providers/zai.models.js.map +1 -1
  507. package/dist/types.d.ts +409 -128
  508. package/dist/types.d.ts.map +1 -1
  509. package/dist/types.js.map +1 -1
  510. package/dist/utils/abort.d.ts +8 -0
  511. package/dist/utils/abort.d.ts.map +1 -0
  512. package/dist/utils/abort.js +49 -0
  513. package/dist/utils/abort.js.map +1 -0
  514. package/dist/utils/assistant-message-frame.d.ts +77 -0
  515. package/dist/utils/assistant-message-frame.d.ts.map +1 -0
  516. package/dist/utils/assistant-message-frame.js +425 -0
  517. package/dist/utils/assistant-message-frame.js.map +1 -0
  518. package/dist/utils/diagnostics.d.ts +3 -2
  519. package/dist/utils/diagnostics.d.ts.map +1 -1
  520. package/dist/utils/diagnostics.js.map +1 -1
  521. package/dist/utils/draht-user-agent.d.ts +2 -0
  522. package/dist/utils/draht-user-agent.d.ts.map +1 -0
  523. package/dist/utils/{pi-user-agent.js → draht-user-agent.js} +3 -3
  524. package/dist/utils/draht-user-agent.js.map +1 -0
  525. package/dist/utils/estimate.d.ts +2 -2
  526. package/dist/utils/estimate.d.ts.map +1 -1
  527. package/dist/utils/estimate.js +8 -29
  528. package/dist/utils/estimate.js.map +1 -1
  529. package/dist/utils/event-stream.d.ts.map +1 -1
  530. package/dist/utils/event-stream.js +30 -8
  531. package/dist/utils/event-stream.js.map +1 -1
  532. package/dist/utils/headers.d.ts +1 -1
  533. package/dist/utils/headers.d.ts.map +1 -1
  534. package/dist/utils/headers.js +10 -8
  535. package/dist/utils/headers.js.map +1 -1
  536. package/dist/utils/model-operations.d.ts +11 -0
  537. package/dist/utils/model-operations.d.ts.map +1 -0
  538. package/dist/utils/model-operations.js +47 -0
  539. package/dist/utils/model-operations.js.map +1 -0
  540. package/dist/utils/models-error.d.ts +8 -0
  541. package/dist/utils/models-error.d.ts.map +1 -0
  542. package/dist/utils/models-error.js +19 -0
  543. package/dist/utils/models-error.js.map +1 -0
  544. package/dist/utils/oauth-page.d.ts.map +1 -0
  545. package/dist/utils/oauth-page.js.map +1 -0
  546. package/dist/utils/overflow.d.ts +11 -1
  547. package/dist/utils/overflow.d.ts.map +1 -1
  548. package/dist/utils/overflow.js +24 -6
  549. package/dist/utils/overflow.js.map +1 -1
  550. package/dist/utils/provider-retry.js +3 -2
  551. package/dist/utils/provider-retry.js.map +1 -1
  552. package/dist/utils/retry.d.ts +6 -1
  553. package/dist/utils/retry.d.ts.map +1 -1
  554. package/dist/utils/retry.js +18 -2
  555. package/dist/utils/retry.js.map +1 -1
  556. package/dist/utils/sleep.d.ts +1 -1
  557. package/dist/utils/sleep.d.ts.map +1 -1
  558. package/dist/utils/sleep.js +4 -4
  559. package/dist/utils/sleep.js.map +1 -1
  560. package/dist/utils/text.d.ts +9 -1
  561. package/dist/utils/text.d.ts.map +1 -1
  562. package/dist/utils/text.js +26 -0
  563. package/dist/utils/text.js.map +1 -1
  564. package/dist/utils/transcript.d.ts +84 -0
  565. package/dist/utils/transcript.d.ts.map +1 -0
  566. package/dist/utils/transcript.js +204 -0
  567. package/dist/utils/transcript.js.map +1 -0
  568. package/dist/utils/uuid.d.ts +2 -2
  569. package/dist/utils/uuid.d.ts.map +1 -1
  570. package/dist/utils/uuid.js +35 -40
  571. package/dist/utils/uuid.js.map +1 -1
  572. package/dist/utils/validation.d.ts.map +1 -1
  573. package/dist/utils/validation.js +34 -0
  574. package/dist/utils/validation.js.map +1 -1
  575. package/package.json +19 -13
  576. package/dist/auth/oauth/oauth-page.d.ts.map +0 -1
  577. package/dist/auth/oauth/oauth-page.js.map +0 -1
  578. package/dist/image-models.generated.d.ts +0 -605
  579. package/dist/image-models.generated.d.ts.map +0 -1
  580. package/dist/image-models.generated.js +0 -607
  581. package/dist/image-models.generated.js.map +0 -1
  582. package/dist/images-models.d.ts +0 -95
  583. package/dist/images-models.d.ts.map +0 -1
  584. package/dist/images-models.js +0 -140
  585. package/dist/images-models.js.map +0 -1
  586. package/dist/providers/openrouter-images.d.ts +0 -3
  587. package/dist/providers/openrouter-images.d.ts.map +0 -1
  588. package/dist/providers/openrouter-images.js +0 -22
  589. package/dist/providers/openrouter-images.js.map +0 -1
  590. package/dist/utils/deferred-tools.d.ts +0 -9
  591. package/dist/utils/deferred-tools.d.ts.map +0 -1
  592. package/dist/utils/deferred-tools.js +0 -36
  593. package/dist/utils/deferred-tools.js.map +0 -1
  594. package/dist/utils/pi-user-agent.d.ts +0 -2
  595. package/dist/utils/pi-user-agent.d.ts.map +0 -1
  596. package/dist/utils/pi-user-agent.js.map +0 -1
  597. /package/dist/{auth/oauth → utils}/oauth-page.d.ts +0 -0
  598. /package/dist/{auth/oauth → utils}/oauth-page.js +0 -0
@@ -1,26 +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
- import { getPiUserAgent } from "../utils/pi-user-agent.js";
8
9
  import { getProviderEnvValue } from "../utils/provider-env.js";
9
10
  import { retryProviderRequest } from "../utils/provider-retry.js";
10
11
  import { sanitizeSurrogates } from "../utils/sanitize-unicode.js";
11
- 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";
12
15
  import { buildCopilotDynamicHeaders, hasCopilotVisionInput } from "./github-copilot-headers.js";
13
16
  import { adjustMaxTokensForThinking, buildBaseOptions, clampMaxTokensToContext } from "./simple-options.js";
14
17
  import { transformMessages } from "./transform-messages.js";
15
18
  /**
16
19
  * Resolve cache retention preference.
17
- * Defaults to "short" and uses PI_CACHE_RETENTION for backward compatibility.
20
+ * Defaults to "short" and uses DRAHT_CACHE_RETENTION for backward compatibility.
18
21
  */
19
22
  function resolveCacheRetention(cacheRetention, env) {
20
23
  if (cacheRetention) {
21
24
  return cacheRetention;
22
25
  }
23
- if (getProviderEnvValue("PI_CACHE_RETENTION", env) === "long") {
26
+ if (getProviderEnvValue("DRAHT_CACHE_RETENTION", env) === "long") {
24
27
  return "long";
25
28
  }
26
29
  return "short";
@@ -37,7 +40,7 @@ function getCacheControl(model, cacheRetention, env) {
37
40
  };
38
41
  }
39
42
  // Stealth mode: Mimic Claude Code's tool naming exactly
40
- const claudeCodeVersion = "2.1.251";
43
+ const claudeCodeVersion = "2.1.280";
41
44
  // Claude Code 2.x tool names (canonical casing)
42
45
  // Source: https://cchistory.mariozechner.at/data/prompts-2.1.11.md
43
46
  // To update: https://github.com/badlogic/cchistory
@@ -110,33 +113,41 @@ function convertContentBlocks(content) {
110
113
  }
111
114
  const FINE_GRAINED_TOOL_STREAMING_BETA = "fine-grained-tool-streaming-2025-05-14";
112
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
+ }
113
136
  function getAnthropicCompat(model) {
137
+ const isOpenRouter = model.provider === "openrouter" || model.baseUrl.includes("openrouter.ai");
114
138
  return {
115
139
  supportsEagerToolInputStreaming: model.compat?.supportsEagerToolInputStreaming ?? true,
116
140
  supportsLongCacheRetention: model.compat?.supportsLongCacheRetention ?? true,
117
- sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? false,
141
+ sendSessionAffinityHeaders: model.compat?.sendSessionAffinityHeaders ?? isOpenRouter,
142
+ sessionAffinityFormat: model.compat?.sessionAffinityFormat ?? (isOpenRouter ? "openrouter" : undefined),
118
143
  supportsCacheControlOnTools: model.compat?.supportsCacheControlOnTools ?? true,
119
144
  supportsTemperature: model.compat?.supportsTemperature ?? true,
120
145
  allowEmptySignature: model.compat?.allowEmptySignature ?? false,
121
146
  supportsStrictTools: model.compat?.supportsStrictTools ?? false,
122
- supportsToolReferences: model.compat?.supportsToolReferences ?? defaultSupportsToolReferences(model),
147
+ supportsMidConvoSystemMessages: model.compat?.supportsMidConvoSystemMessages ?? false,
148
+ supportsMidConvoToolChanges: model.compat?.supportsMidConvoToolChanges ?? false,
123
149
  };
124
150
  }
125
- /**
126
- * Default for `supportsToolReferences`: first-party Anthropic models except
127
- * Haiku (rejects client-side tool_reference blocks) and models that predate
128
- * tool search (Claude 3.x, Opus/Sonnet 4.0, Opus 4.1).
129
- */
130
- function defaultSupportsToolReferences(model) {
131
- if (model.provider !== "anthropic" || model.id.includes("haiku"))
132
- return false;
133
- const version = model.id.match(/^claude-(?:opus|sonnet|fable)-(\d+)(?:-(\d+))?(?:-|$)/);
134
- if (!version)
135
- return false;
136
- const major = Number(version[1]);
137
- const minor = version[2] && version[2].length < 8 ? Number(version[2]) : 0;
138
- return major > 4 || (major === 4 && minor >= 5);
139
- }
140
151
  function mergeHeaders(...headerSources) {
141
152
  const merged = {};
142
153
  for (const headers of headerSources) {
@@ -147,7 +158,7 @@ function mergeHeaders(...headerSources) {
147
158
  return merged;
148
159
  }
149
160
  function mergeClientHeaders(...headerSources) {
150
- return mergeHeaders({ "User-Agent": getPiUserAgent() }, ...headerSources);
161
+ return mergeHeaders({ "User-Agent": getDrahtUserAgent() }, ...headerSources);
151
162
  }
152
163
  function hasHeader(headers, name) {
153
164
  if (!headers)
@@ -159,16 +170,58 @@ function hasHeader(headers, name) {
159
170
  }
160
171
  return false;
161
172
  }
162
- function assertRequestAuth(provider, apiKey, headers) {
163
- if (apiKey)
164
- return;
165
- if (hasHeader(headers, "authorization") ||
173
+ function hasRequestAuth(apiKey, headers) {
174
+ return (!!apiKey ||
175
+ hasHeader(headers, "authorization") ||
166
176
  hasHeader(headers, "x-api-key") ||
167
- hasHeader(headers, "cf-aig-authorization")) {
168
- 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;
169
192
  }
170
- throw new Error(`No API key for provider: ${provider}`);
171
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;
172
225
  const ANTHROPIC_MESSAGE_EVENTS = new Set([
173
226
  "message_start",
174
227
  "message_delta",
@@ -322,13 +375,17 @@ async function* iterateAnthropicEvents(response, signal) {
322
375
  }
323
376
  export const stream = (model, context, options) => {
324
377
  const stream = new AssistantMessageEventStream();
378
+ const normalizedContext = resolveTranscript(context, getAnthropicCompat(model).supportsMidConvoSystemMessages);
379
+ const currentTools = getCurrentTools(normalizedContext.messages);
325
380
  (async () => {
381
+ const providerThinkingLevel = model.compat?.supportsMidConvoEffort ? (options?.effort ?? "high") : undefined;
326
382
  const output = {
327
383
  role: "assistant",
328
384
  content: [],
329
385
  api: model.api,
330
386
  provider: model.provider,
331
387
  model: model.id,
388
+ ...(providerThinkingLevel === undefined ? {} : { providerThinkingLevel }),
332
389
  usage: {
333
390
  input: 0,
334
391
  output: 0,
@@ -343,38 +400,42 @@ export const stream = (model, context, options) => {
343
400
  try {
344
401
  let client;
345
402
  let isOAuth;
403
+ let usageModel = model;
404
+ let inputTransformations;
346
405
  if (options?.client) {
347
406
  client = options.client;
348
407
  isOAuth = false;
349
408
  }
350
409
  else {
351
410
  const apiKey = options?.apiKey;
352
- 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);
353
414
  let copilotDynamicHeaders;
354
415
  if (model.provider === "github-copilot") {
355
- const hasImages = hasCopilotVisionInput(context.messages);
416
+ const hasImages = hasCopilotVisionInput(normalizedContext.messages);
356
417
  copilotDynamicHeaders = buildCopilotDynamicHeaders({
357
- messages: context.messages,
418
+ messages: normalizedContext.messages,
358
419
  hasImages,
359
420
  });
360
421
  }
361
422
  const cacheRetention = resolveCacheRetention(options?.cacheRetention, options?.env);
362
423
  const cacheSessionId = cacheRetention === "none" ? undefined : options?.sessionId;
363
- 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);
364
425
  client = created.client;
365
426
  isOAuth = created.isOAuthToken;
366
427
  }
367
- let params = buildParams(model, context, isOAuth, options);
428
+ let params = buildParams(model, normalizedContext, isOAuth, options);
368
429
  const nextParams = await options?.onPayload?.(params, model);
369
430
  if (nextParams !== undefined) {
370
- params = nextParams;
431
+ params = { ...nextParams, stream: true };
371
432
  }
372
433
  const requestOptions = {
373
434
  ...(options?.signal ? { signal: options.signal } : {}),
374
435
  ...(options?.timeoutMs !== undefined ? { timeout: options.timeoutMs } : {}),
375
436
  maxRetries: 0,
376
437
  };
377
- const response = await retryProviderRequest(() => client.messages.create({ ...params, stream: true }, requestOptions).asResponse(), {
438
+ const response = await retryProviderRequest(() => client.beta.messages.create(params, requestOptions).asResponse(), {
378
439
  maxRetries: options?.maxRetries,
379
440
  maxRetryDelayMs: options?.maxRetryDelayMs,
380
441
  signal: options?.signal,
@@ -383,8 +444,19 @@ export const stream = (model, context, options) => {
383
444
  stream.push({ type: "start", partial: output });
384
445
  const blocks = output.content;
385
446
  for await (const event of iterateAnthropicEvents(response, options?.signal)) {
447
+ await options?.onProviderStreamEvent?.(event, model);
386
448
  if (event.type === "message_start") {
387
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;
388
460
  // Capture initial token usage from message_start event
389
461
  // This ensures we have input token counts even if the stream is aborted early
390
462
  output.usage.input = event.message.usage.input_tokens || 0;
@@ -395,9 +467,15 @@ export const stream = (model, context, options) => {
395
467
  // Anthropic doesn't provide total_tokens, compute from components
396
468
  output.usage.totalTokens =
397
469
  output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
398
- calculateCost(model, output.usage);
470
+ calculateCost(usageModel, output.usage);
399
471
  }
400
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
+ }
401
479
  if (event.content_block.type === "text") {
402
480
  const block = {
403
481
  type: "text",
@@ -433,7 +511,7 @@ export const stream = (model, context, options) => {
433
511
  type: "toolCall",
434
512
  id: event.content_block.id,
435
513
  name: isOAuth
436
- ? fromClaudeCodeName(event.content_block.name, context.tools)
514
+ ? fromClaudeCodeName(event.content_block.name, currentTools)
437
515
  : event.content_block.name,
438
516
  arguments: event.content_block.input ?? {},
439
517
  partialJson: "",
@@ -529,6 +607,9 @@ export const stream = (model, context, options) => {
529
607
  }
530
608
  }
531
609
  else if (event.type === "message_delta") {
610
+ const transformations = event.input_transformations;
611
+ if (Array.isArray(transformations))
612
+ inputTransformations = transformations;
532
613
  if (event.delta.stop_reason) {
533
614
  output.rawStopReason = event.delta.stop_reason;
534
615
  const stopReasonResult = mapStopReason(event.delta.stop_reason, event.delta.stop_details);
@@ -552,11 +633,13 @@ export const stream = (model, context, options) => {
552
633
  if (event.usage.cache_creation_input_tokens != null) {
553
634
  output.usage.cacheWrite = event.usage.cache_creation_input_tokens;
554
635
  }
555
- // Anthropic reports reasoning tokens in `output_tokens_details.thinking_tokens` on the
556
- // final message_delta usage (a subset of output_tokens). SDK 0.91.1 omits the field from
557
- // its Usage type, so read it through a narrow cast. Verified against the live API.
558
- const thinkingTokens = event.usage
559
- .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;
560
643
  if (thinkingTokens != null) {
561
644
  output.usage.reasoning = thinkingTokens;
562
645
  }
@@ -564,7 +647,7 @@ export const stream = (model, context, options) => {
564
647
  // Anthropic doesn't provide total_tokens, compute from components
565
648
  output.usage.totalTokens =
566
649
  output.usage.input + output.usage.output + output.usage.cacheRead + output.usage.cacheWrite;
567
- calculateCost(model, output.usage);
650
+ calculateCost(usageModel, output.usage);
568
651
  }
569
652
  }
570
653
  if (options?.signal?.aborted) {
@@ -576,6 +659,19 @@ export const stream = (model, context, options) => {
576
659
  if (output.stopReason === "aborted" || output.stopReason === "error") {
577
660
  throw new Error(output.errorMessage || "An unknown error occurred");
578
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
+ }
579
675
  stream.push({ type: "done", reason: output.stopReason, message: output });
580
676
  stream.end();
581
677
  }
@@ -615,13 +711,18 @@ function mapThinkingLevelToEffort(model, level) {
615
711
  }
616
712
  }
617
713
  export const streamSimple = (model, context, options) => {
618
- assertRequestAuth(model.provider, options?.apiKey, options?.headers);
714
+ if (!getAnthropicFederation(model, options?.apiKey, options?.headers, options?.env)) {
715
+ assertRequestAuth(model.provider, options?.apiKey, options?.headers);
716
+ }
619
717
  const base = {
620
718
  ...buildBaseOptions(model, context, options, options?.apiKey),
621
719
  toolChoice: options?.toolChoice,
622
720
  };
623
721
  if (!options?.reasoning) {
624
- return stream(model, context, { ...base, thinkingEnabled: false });
722
+ return stream(model, context, {
723
+ ...base,
724
+ thinkingEnabled: false,
725
+ });
625
726
  }
626
727
  // For models with adaptive thinking: use an effort level.
627
728
  // For older models: use budget-based thinking.
@@ -647,19 +748,10 @@ export const streamSimple = (model, context, options) => {
647
748
  function isOAuthToken(apiKey) {
648
749
  return apiKey.includes("sk-ant-oat");
649
750
  }
650
- function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStreamingBeta, optionsHeaders, fetch, dynamicHeaders, sessionId) {
651
- // Adaptive thinking models have interleaved thinking built in, so skip the beta header.
652
- const needsInterleavedBeta = interleavedThinking && model.compat?.forceAdaptiveThinking !== true;
653
- const betaFeatures = [];
654
- if (useFineGrainedToolStreamingBeta) {
655
- betaFeatures.push(FINE_GRAINED_TOOL_STREAMING_BETA);
656
- }
657
- if (needsInterleavedBeta) {
658
- betaFeatures.push(INTERLEAVED_THINKING_BETA);
659
- }
660
- // Copilot: Bearer auth, selective betas.
751
+ function createClient(model, apiKey, optionsHeaders, fetch, dynamicHeaders, sessionId, federation) {
752
+ // Copilot: Bearer auth.
661
753
  if (model.provider === "github-copilot") {
662
- const client = new Anthropic({
754
+ const client = new PiAnthropic({
663
755
  apiKey: null,
664
756
  authToken: apiKey ?? null,
665
757
  baseURL: model.baseUrl,
@@ -668,14 +760,13 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
668
760
  defaultHeaders: mergeClientHeaders({
669
761
  accept: "application/json",
670
762
  "anthropic-dangerous-direct-browser-access": "true",
671
- ...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
672
763
  }, model.headers, dynamicHeaders, optionsHeaders),
673
764
  });
674
765
  return { client, isOAuthToken: false };
675
766
  }
676
767
  // OAuth: Bearer auth, Claude Code identity headers
677
768
  if (apiKey && isOAuthToken(apiKey)) {
678
- const client = new Anthropic({
769
+ const client = new PiAnthropic({
679
770
  apiKey: null,
680
771
  authToken: apiKey,
681
772
  baseURL: model.baseUrl,
@@ -684,21 +775,39 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
684
775
  defaultHeaders: mergeClientHeaders({
685
776
  accept: "application/json",
686
777
  "anthropic-dangerous-direct-browser-access": "true",
687
- "anthropic-beta": ["claude-code-20250219", "oauth-2025-04-20", ...betaFeatures].join(","),
688
778
  "user-agent": `claude-cli/${claudeCodeVersion}`,
689
779
  "x-app": "cli",
690
780
  }, model.headers, optionsHeaders),
691
781
  });
692
782
  return { client, isOAuthToken: true };
693
783
  }
694
- // API key or header-owned auth.
695
- const sessionAffinityHeaders = sessionId && getAnthropicCompat(model).sendSessionAffinityHeaders ? { "x-session-affinity": sessionId } : {};
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
+ }
696
791
  const defaultHeaders = mergeClientHeaders({
697
792
  accept: "application/json",
698
793
  "anthropic-dangerous-direct-browser-access": "true",
699
- ...(betaFeatures.length > 0 ? { "anthropic-beta": betaFeatures.join(",") } : {}),
700
794
  }, sessionAffinityHeaders, model.headers, optionsHeaders);
701
- 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({
702
811
  apiKey: apiKey ?? null,
703
812
  authToken: null,
704
813
  baseURL: model.baseUrl,
@@ -708,24 +817,70 @@ function createClient(model, apiKey, interleavedThinking, useFineGrainedToolStre
708
817
  });
709
818
  return { client, isOAuthToken: false };
710
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
+ }
711
858
  function buildParams(model, context, isOAuthToken, options) {
712
859
  const { cacheControl } = getCacheControl(model, options?.cacheRetention, options?.env);
713
860
  const compat = getAnthropicCompat(model);
861
+ const initialSystemMessage = getInitialSystemMessage(context.messages);
862
+ const initialSystemText = initialSystemMessage ? getSystemMessageText(initialSystemMessage) : "";
714
863
  const transformedMessages = transformMessages(context.messages, model, normalizeToolCallId);
715
- const normalizeToolName = isOAuthToken ? toClaudeCodeName : (name) => name;
716
- const toolPlacement = splitDeferredTools({ ...context, messages: transformedMessages }, compat.supportsToolReferences, normalizeToolName);
717
- let immediateTools = toolPlacement.immediate;
718
- let deferredTools = [...toolPlacement.deferred.values()];
719
- if (immediateTools.length === 0 && deferredTools.length > 0) {
720
- immediateTools = deferredTools;
721
- deferredTools = [];
722
- }
723
- 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);
724
876
  const params = {
725
877
  model: model.id,
726
- messages: convertMessages(transformedMessages, isOAuthToken, cacheControl, compat.allowEmptySignature, deferredToolNames, normalizeToolName),
878
+ messages: model.compat?.supportsMidConvoEffort === true
879
+ ? insertThinkingLevelMessages(converted, activeEffort)
880
+ : converted.messages,
727
881
  max_tokens: options?.maxTokens ?? model.maxTokens,
728
882
  stream: true,
883
+ ...(betaFeatures.length > 0 ? { betas: betaFeatures } : {}),
729
884
  };
730
885
  // For OAuth tokens, we MUST include Claude Code identity
731
886
  if (isOAuthToken) {
@@ -736,36 +891,62 @@ function buildParams(model, context, isOAuthToken, options) {
736
891
  ...(cacheControl ? { cache_control: cacheControl } : {}),
737
892
  },
738
893
  ];
739
- if (context.systemPrompt) {
894
+ if (initialSystemText) {
740
895
  params.system.push({
741
896
  type: "text",
742
- text: sanitizeSurrogates(context.systemPrompt),
897
+ text: sanitizeSurrogates(initialSystemText),
743
898
  ...(cacheControl ? { cache_control: cacheControl } : {}),
744
899
  });
745
900
  }
746
901
  }
747
- else if (context.systemPrompt) {
902
+ else if (initialSystemText) {
748
903
  // Add cache control to system prompt for non-OAuth tokens
749
904
  params.system = [
750
905
  {
751
906
  type: "text",
752
- text: sanitizeSurrogates(context.systemPrompt),
907
+ text: sanitizeSurrogates(initialSystemText),
753
908
  ...(cacheControl ? { cache_control: cacheControl } : {}),
754
909
  },
755
910
  ];
756
911
  }
757
912
  // Temperature is incompatible with extended thinking and unsupported on Claude Opus 4.7+.
758
- if (options?.temperature !== undefined && !options?.thinkingEnabled && compat.supportsTemperature) {
913
+ if (options?.temperature !== undefined &&
914
+ !options?.thinkingEnabled &&
915
+ model.compat?.supportsMidConvoEffort !== true &&
916
+ compat.supportsTemperature) {
759
917
  params.temperature = options.temperature;
760
918
  }
761
- 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));
762
927
  params.tools = [
763
- ...convertTools(immediateTools, isOAuthToken, compat.supportsEagerToolInputStreaming, compat.supportsStrictTools, compat.supportsCacheControlOnTools ? cacheControl : undefined),
764
- ...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 })),
765
931
  ];
766
932
  }
767
- // Configure thinking mode: adaptive, budget-based, or explicitly disabled.
768
- 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) {
769
950
  if (options?.thinkingEnabled) {
770
951
  // Default to "summarized" so Opus 4.7 and Mythos Preview behave like
771
952
  // older Claude 4 models (whose API default is also "summarized").
@@ -774,11 +955,7 @@ function buildParams(model, context, isOAuthToken, options) {
774
955
  // Adaptive thinking: Claude decides when and how much to think.
775
956
  params.thinking = { type: "adaptive", display };
776
957
  if (options.effort) {
777
- // The Anthropic SDK types can lag newly supported effort values such as "xhigh".
778
- params.output_config =
779
- options.effort === "xhigh"
780
- ? { effort: options.effort }
781
- : { effort: options.effort };
958
+ params.output_config = { effort: options.effort };
782
959
  }
783
960
  }
784
961
  else {
@@ -808,46 +985,64 @@ function buildParams(model, context, isOAuthToken, options) {
808
985
  params.tool_choice = options.toolChoice;
809
986
  }
810
987
  }
988
+ const allowedFallbackModels = model.compat?.allowedFallbackModels;
989
+ if (allowedFallbackModels && allowedFallbackModels.length > 0) {
990
+ params.fallbacks = allowedFallbackModels.map((fallback) => ({ model: fallback.model }));
991
+ }
811
992
  return params;
812
993
  }
813
994
  // Normalize tool call IDs to match Anthropic's required pattern and length
814
995
  function normalizeToolCallId(id) {
815
996
  return id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
816
997
  }
817
- function convertToolResult(msg, isOAuthToken, deferredToolNames, loadedToolNames, normalizeToolName) {
818
- const references = [];
819
- for (const name of msg.addedToolNames ?? []) {
820
- const normalizedName = normalizeToolName(name);
821
- if (!deferredToolNames.has(normalizedName) || loadedToolNames.has(normalizedName))
822
- continue;
823
- loadedToolNames.add(normalizedName);
824
- references.push({
825
- type: "tool_reference",
826
- tool_name: isOAuthToken ? toClaudeCodeName(name) : name,
827
- });
828
- }
829
- const convertedContent = convertContentBlocks(msg.content);
830
- // Anthropic rejects tool references mixed with ordinary tool-result content.
998
+ function convertToolResult(msg) {
831
999
  return {
832
- toolResult: {
833
- type: "tool_result",
834
- tool_use_id: msg.toolCallId,
835
- content: references.length > 0 ? references : convertedContent,
836
- is_error: msg.isError,
837
- },
838
- siblingContent: references.length === 0
839
- ? []
840
- : typeof convertedContent === "string"
841
- ? [{ type: "text", text: convertedContent }]
842
- : convertedContent,
1000
+ type: "tool_result",
1001
+ tool_use_id: msg.toolCallId,
1002
+ content: convertContentBlocks(msg.content),
1003
+ is_error: msg.isError,
843
1004
  };
844
1005
  }
845
- function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, deferredToolNames = new Set(), normalizeToolName = (name) => name) {
1006
+ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowEmptySignature = false, managedProvider, nativeToolChanges = false) {
846
1007
  const params = [];
847
- 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
+ };
848
1019
  for (let i = 0; i < transformedMessages.length; i++) {
849
1020
  const msg = transformedMessages[i];
850
- 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") {
851
1046
  if (typeof msg.content === "string") {
852
1047
  if (msg.content.trim().length > 0) {
853
1048
  params.push({
@@ -890,6 +1085,7 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
890
1085
  }
891
1086
  }
892
1087
  else if (msg.role === "assistant") {
1088
+ flushPendingSystemMessages();
893
1089
  const blocks = [];
894
1090
  for (const block of msg.content) {
895
1091
  if (block.type === "text") {
@@ -947,39 +1143,47 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
947
1143
  }
948
1144
  if (blocks.length === 0)
949
1145
  continue;
1146
+ const messageIndex = params.length;
950
1147
  params.push({
951
1148
  role: "assistant",
952
1149
  content: blocks,
953
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
+ }
954
1157
  }
955
1158
  else if (msg.role === "toolResult") {
956
1159
  // Collect all consecutive toolResult messages, needed for z.ai Anthropic endpoint.
957
1160
  const toolResults = [];
958
- const siblingContent = [];
959
1161
  let j = i;
960
1162
  while (j < transformedMessages.length && transformedMessages[j].role === "toolResult") {
961
- const converted = convertToolResult(transformedMessages[j], isOAuthToken, deferredToolNames, loadedToolNames, normalizeToolName);
962
- toolResults.push(converted.toolResult);
963
- siblingContent.push(...converted.siblingContent);
1163
+ toolResults.push(convertToolResult(transformedMessages[j]));
964
1164
  j++;
965
1165
  }
966
1166
  // Skip the messages we've already processed.
967
1167
  i = j - 1;
968
- // Displaced reference-bearing results must follow every tool_result block.
969
1168
  params.push({
970
1169
  role: "user",
971
- content: [...toolResults, ...siblingContent],
1170
+ content: toolResults,
972
1171
  });
973
1172
  }
974
1173
  }
975
- // 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
976
1176
  if (cacheControl && params.length > 0) {
977
1177
  const lastMessage = params[params.length - 1];
978
- if (lastMessage.role === "user") {
1178
+ if (lastMessage.role === "user" || lastMessage.role === "system") {
979
1179
  if (Array.isArray(lastMessage.content)) {
980
1180
  const lastBlock = lastMessage.content[lastMessage.content.length - 1];
981
1181
  if (lastBlock &&
982
- (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")) {
983
1187
  lastBlock.cache_control = cacheControl;
984
1188
  }
985
1189
  }
@@ -994,17 +1198,69 @@ function convertMessages(transformedMessages, isOAuthToken, cacheControl, allowE
994
1198
  }
995
1199
  }
996
1200
  }
997
- 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;
998
1217
  }
999
1218
  function shouldUseFineGrainedToolStreamingBeta(model, context) {
1000
- return !!context.tools?.length && !getAnthropicCompat(model).supportsEagerToolInputStreaming;
1219
+ return getCurrentTools(context.messages).length > 0 && !getAnthropicCompat(model).supportsEagerToolInputStreaming;
1001
1220
  }
1002
- 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) {
1003
1258
  if (!tools)
1004
1259
  return [];
1005
1260
  return tools.map((tool, index) => {
1006
- const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools);
1007
- const schema = tool.parameters;
1261
+ const strict = resolveJsonSchemaStrictSampling(tool, supportsStrictTools, isAnthropicStrictUnsupportedKeyword);
1262
+ const parameters = getJsonSchemaToolParameters(tool, strict);
1263
+ const schema = parameters;
1008
1264
  const legacyInputSchema = {
1009
1265
  type: "object",
1010
1266
  properties: schema.properties ?? {},
@@ -1012,7 +1268,7 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
1012
1268
  };
1013
1269
  const inputSchema = strict === true
1014
1270
  ? {
1015
- ...tool.parameters,
1271
+ ...parameters,
1016
1272
  ...legacyInputSchema,
1017
1273
  }
1018
1274
  : legacyInputSchema;
@@ -1022,7 +1278,6 @@ function convertTools(tools, isOAuthToken, supportsEagerToolInputStreaming, supp
1022
1278
  ...(supportsEagerToolInputStreaming ? { eager_input_streaming: true } : {}),
1023
1279
  ...(strict === true ? { strict: true } : {}),
1024
1280
  input_schema: inputSchema,
1025
- ...(deferLoading ? { defer_loading: true } : {}),
1026
1281
  ...(cacheControl && index === tools.length - 1 ? { cache_control: cacheControl } : {}),
1027
1282
  };
1028
1283
  });