@prometheus-ai/ai 0.5.4 → 0.5.8

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 (377) hide show
  1. package/dist/types/auth-broker/remote-store.d.ts +2 -1
  2. package/dist/types/auth-broker/wire-schemas.d.ts +4 -1
  3. package/dist/types/auth-gateway/server.d.ts +19 -0
  4. package/dist/types/auth-gateway/types.d.ts +9 -3
  5. package/dist/types/auth-retry.d.ts +119 -0
  6. package/dist/types/auth-storage.d.ts +217 -8
  7. package/dist/types/errors.d.ts +24 -0
  8. package/dist/types/index.d.ts +5 -9
  9. package/dist/types/provider-details.d.ts +1 -1
  10. package/dist/types/providers/amazon-bedrock.d.ts +12 -6
  11. package/dist/types/providers/anthropic-client.d.ts +10 -3
  12. package/dist/types/providers/anthropic-messages-server-schema.d.ts +2 -2
  13. package/dist/types/providers/anthropic-messages-server.d.ts +3 -3
  14. package/dist/types/providers/anthropic-wire.d.ts +3 -3
  15. package/dist/types/providers/anthropic.d.ts +41 -34
  16. package/dist/types/providers/aws-credentials.d.ts +8 -0
  17. package/dist/types/providers/azure-openai-responses.d.ts +1 -0
  18. package/dist/types/providers/google-gemini-cli.d.ts +22 -1
  19. package/dist/types/providers/google-shared.d.ts +22 -0
  20. package/dist/types/providers/google-types.d.ts +13 -1
  21. package/dist/types/providers/mock.d.ts +8 -3
  22. package/dist/types/providers/ollama.d.ts +6 -0
  23. package/dist/types/providers/openai-chat-server-schema.d.ts +6 -3
  24. package/dist/types/providers/openai-chat-server.d.ts +3 -3
  25. package/dist/types/providers/openai-chat-wire.d.ts +644 -0
  26. package/dist/types/providers/openai-codex/request-transformer.d.ts +8 -0
  27. package/dist/types/providers/openai-codex/response-handler.d.ts +9 -0
  28. package/dist/types/providers/openai-codex-responses.d.ts +31 -2
  29. package/dist/types/providers/openai-completions-compat.d.ts +2 -25
  30. package/dist/types/providers/openai-completions.d.ts +2 -10
  31. package/dist/types/providers/openai-responses-server-schema.d.ts +4 -4
  32. package/dist/types/providers/openai-responses-server.d.ts +2 -2
  33. package/dist/types/providers/openai-responses-shared.d.ts +49 -9
  34. package/dist/types/providers/openai-responses-wire.d.ts +6065 -0
  35. package/dist/types/providers/openai-responses.d.ts +13 -4
  36. package/dist/types/providers/prometheus-native-client.d.ts +9 -0
  37. package/dist/types/providers/prometheus-native-server.d.ts +4 -3
  38. package/dist/types/providers/transform-messages.d.ts +1 -2
  39. package/dist/types/rate-limit-utils.d.ts +3 -2
  40. package/dist/types/registry/aimlapi.d.ts +4 -0
  41. package/dist/types/registry/alibaba-coding-plan.d.ts +7 -0
  42. package/dist/types/registry/amazon-bedrock.d.ts +5 -0
  43. package/dist/types/registry/anthropic.d.ts +10 -0
  44. package/dist/types/{utils/oauth → registry}/api-key-login.d.ts +8 -2
  45. package/dist/types/{utils/oauth → registry}/api-key-validation.d.ts +15 -0
  46. package/dist/types/registry/cerebras.d.ts +7 -0
  47. package/dist/types/registry/cloudflare-ai-gateway.d.ts +13 -0
  48. package/dist/types/registry/cursor.d.ts +7 -0
  49. package/dist/types/registry/deepseek.d.ts +8 -0
  50. package/dist/types/registry/derived.d.ts +5 -0
  51. package/dist/types/registry/firepass.d.ts +16 -0
  52. package/dist/types/registry/fireworks.d.ts +7 -0
  53. package/dist/types/registry/github-copilot.d.ts +7 -0
  54. package/dist/types/registry/gitlab-duo.d.ts +9 -0
  55. package/dist/types/registry/google-antigravity.d.ts +9 -0
  56. package/dist/types/registry/google-gemini-cli.d.ts +9 -0
  57. package/dist/types/registry/google-vertex.d.ts +5 -0
  58. package/dist/types/registry/google.d.ts +4 -0
  59. package/dist/types/registry/groq.d.ts +4 -0
  60. package/dist/types/registry/huggingface.d.ts +7 -0
  61. package/dist/types/registry/index.d.ts +4 -0
  62. package/dist/types/registry/kagi.d.ts +14 -0
  63. package/dist/types/registry/kilo.d.ts +7 -0
  64. package/dist/types/registry/kimi-code.d.ts +7 -0
  65. package/dist/types/registry/litellm.d.ts +13 -0
  66. package/dist/types/registry/lm-studio.d.ts +8 -0
  67. package/dist/types/registry/minimax-code-cn.d.ts +6 -0
  68. package/dist/types/registry/minimax-code.d.ts +6 -0
  69. package/dist/types/registry/minimax.d.ts +4 -0
  70. package/dist/types/registry/mistral.d.ts +4 -0
  71. package/dist/types/registry/moonshot.d.ts +7 -0
  72. package/dist/types/registry/nanogpt.d.ts +7 -0
  73. package/dist/types/registry/nvidia.d.ts +7 -0
  74. package/dist/types/registry/oauth/__tests__/xai-oauth.test.d.ts +1 -0
  75. package/dist/types/{utils → registry}/oauth/anthropic.d.ts +2 -1
  76. package/dist/types/{utils → registry}/oauth/github-copilot.d.ts +15 -23
  77. package/dist/types/{utils → registry}/oauth/index.d.ts +1 -0
  78. package/dist/types/{utils → registry}/oauth/minimax-code.d.ts +5 -5
  79. package/dist/types/{utils → registry}/oauth/types.d.ts +6 -1
  80. package/dist/types/{utils → registry}/oauth/xai-oauth.d.ts +2 -1
  81. package/dist/types/registry/ollama-cloud.d.ts +7 -0
  82. package/dist/types/registry/ollama.d.ts +12 -0
  83. package/dist/types/registry/openai-codex-device.d.ts +8 -0
  84. package/dist/types/registry/openai-codex.d.ts +9 -0
  85. package/dist/types/registry/openai.d.ts +4 -0
  86. package/dist/types/registry/opencode-go.d.ts +6 -0
  87. package/dist/types/registry/opencode-zen.d.ts +6 -0
  88. package/dist/types/registry/openrouter.d.ts +13 -0
  89. package/dist/types/registry/parallel.d.ts +14 -0
  90. package/dist/types/registry/perplexity.d.ts +7 -0
  91. package/dist/types/registry/qianfan.d.ts +7 -0
  92. package/dist/types/registry/qwen-portal.d.ts +7 -0
  93. package/dist/types/registry/registry.d.ts +272 -0
  94. package/dist/types/registry/synthetic.d.ts +6 -0
  95. package/dist/types/registry/tavily.d.ts +14 -0
  96. package/dist/types/registry/together.d.ts +6 -0
  97. package/dist/types/registry/types.d.ts +51 -0
  98. package/dist/types/registry/venice.d.ts +13 -0
  99. package/dist/types/registry/vercel-ai-gateway.d.ts +7 -0
  100. package/dist/types/registry/vllm.d.ts +7 -0
  101. package/dist/types/registry/wafer-pass.d.ts +6 -0
  102. package/dist/types/registry/wafer-serverless.d.ts +6 -0
  103. package/dist/types/registry/xai-oauth.d.ts +7 -0
  104. package/dist/types/registry/xai.d.ts +4 -0
  105. package/dist/types/registry/xiaomi-token-plan-ams.d.ts +6 -0
  106. package/dist/types/registry/xiaomi-token-plan-cn.d.ts +6 -0
  107. package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +6 -0
  108. package/dist/types/registry/xiaomi.d.ts +6 -0
  109. package/dist/types/registry/zai.d.ts +7 -0
  110. package/dist/types/registry/zenmux.d.ts +7 -0
  111. package/dist/types/registry/zhipu-coding-plan.d.ts +7 -0
  112. package/dist/types/stream.d.ts +9 -1
  113. package/dist/types/types.d.ts +56 -295
  114. package/dist/types/usage/google-antigravity.d.ts +15 -1
  115. package/dist/types/usage/openai-codex-reset.d.ts +79 -0
  116. package/dist/types/usage/openai-codex.d.ts +1 -0
  117. package/dist/types/usage.d.ts +77 -4
  118. package/dist/types/utils/abort.d.ts +6 -0
  119. package/dist/types/utils/event-stream.d.ts +2 -0
  120. package/dist/types/utils/http-inspector.d.ts +0 -1
  121. package/dist/types/utils/idle-iterator.d.ts +35 -0
  122. package/dist/types/utils/openai-http.d.ts +58 -0
  123. package/dist/types/utils/request-debug.d.ts +3 -0
  124. package/dist/types/utils/retry-after.d.ts +1 -0
  125. package/dist/types/utils/schema/fields.d.ts +5 -0
  126. package/dist/types/utils/schema/json-schema-validator.d.ts +8 -0
  127. package/dist/types/utils/schema/stamps.d.ts +7 -15
  128. package/dist/types/utils/sse-debug.d.ts +0 -5
  129. package/dist/types/utils/stream-markup-healing.d.ts +2 -0
  130. package/dist/types/utils.d.ts +1 -5
  131. package/package.json +17 -29
  132. package/src/auth-broker/remote-store.ts +10 -1
  133. package/src/auth-broker/snapshot-cache.ts +1 -1
  134. package/src/auth-broker/wire-schemas.ts +1 -1
  135. package/src/auth-gateway/http.ts +1 -1
  136. package/src/auth-gateway/server.ts +95 -30
  137. package/src/auth-gateway/types.ts +10 -2
  138. package/src/auth-retry.ts +238 -0
  139. package/src/auth-storage.ts +935 -430
  140. package/src/errors.ts +32 -0
  141. package/src/index.ts +9 -14
  142. package/src/provider-details.ts +1 -1
  143. package/src/providers/__tests__/google-auth.test.ts +144 -0
  144. package/src/providers/amazon-bedrock.ts +70 -40
  145. package/src/providers/anthropic-client.ts +15 -13
  146. package/src/providers/anthropic-messages-server-schema.ts +17 -7
  147. package/src/providers/anthropic-messages-server.ts +88 -20
  148. package/src/providers/anthropic-wire.ts +4 -3
  149. package/src/providers/anthropic.ts +1234 -621
  150. package/src/providers/aws-credentials.ts +47 -5
  151. package/src/providers/aws-eventstream.ts +5 -0
  152. package/src/providers/azure-openai-responses.ts +117 -67
  153. package/src/providers/cursor.ts +30 -30
  154. package/src/providers/github-copilot-headers.ts +1 -1
  155. package/src/providers/gitlab-duo.ts +36 -29
  156. package/src/providers/google-auth.ts +71 -8
  157. package/src/providers/google-gemini-cli.ts +118 -22
  158. package/src/providers/google-shared.ts +163 -43
  159. package/src/providers/google-types.ts +10 -1
  160. package/src/providers/kimi.ts +1 -1
  161. package/src/providers/mock.ts +11 -3
  162. package/src/providers/ollama.ts +64 -7
  163. package/src/providers/openai-anthropic-shim.ts +17 -8
  164. package/src/providers/openai-chat-server-schema.ts +9 -3
  165. package/src/providers/openai-chat-server.ts +82 -16
  166. package/src/providers/openai-chat-wire.ts +847 -0
  167. package/src/providers/openai-codex/request-transformer.ts +129 -34
  168. package/src/providers/openai-codex/response-handler.ts +22 -1
  169. package/src/providers/openai-codex-responses.ts +699 -247
  170. package/src/providers/openai-completions-compat.ts +8 -308
  171. package/src/providers/openai-completions.ts +416 -267
  172. package/src/providers/openai-responses-server-schema.ts +15 -9
  173. package/src/providers/openai-responses-server.ts +162 -114
  174. package/src/providers/openai-responses-shared.ts +320 -82
  175. package/src/providers/openai-responses-wire.ts +6391 -0
  176. package/src/providers/openai-responses.ts +382 -176
  177. package/src/providers/prometheus-native-client.ts +27 -11
  178. package/src/providers/prometheus-native-server.ts +44 -17
  179. package/src/providers/transform-messages.ts +311 -120
  180. package/src/providers/vision-guard.ts +5 -3
  181. package/src/rate-limit-utils.ts +13 -3
  182. package/src/registry/aimlapi.ts +6 -0
  183. package/src/{utils/oauth → registry}/alibaba-coding-plan.ts +8 -18
  184. package/src/registry/amazon-bedrock.ts +22 -0
  185. package/src/registry/anthropic.ts +26 -0
  186. package/src/{utils/oauth → registry}/api-key-login.ts +25 -3
  187. package/src/{utils/oauth → registry}/api-key-validation.ts +62 -2
  188. package/src/{utils/oauth → registry}/cerebras.ts +8 -1
  189. package/src/{utils/oauth → registry}/cloudflare-ai-gateway.ts +8 -12
  190. package/src/registry/cursor.ts +20 -0
  191. package/src/{utils/oauth → registry}/deepseek.ts +9 -17
  192. package/src/registry/derived.ts +9 -0
  193. package/src/{utils/oauth → registry}/firepass.ts +10 -2
  194. package/src/{utils/oauth → registry}/fireworks.ts +8 -1
  195. package/src/registry/github-copilot.ts +22 -0
  196. package/src/registry/gitlab-duo.ts +19 -0
  197. package/src/registry/google-antigravity.ts +21 -0
  198. package/src/registry/google-gemini-cli.ts +21 -0
  199. package/src/registry/google-vertex.ts +38 -0
  200. package/src/registry/google.ts +6 -0
  201. package/src/registry/groq.ts +6 -0
  202. package/src/{utils/oauth → registry}/huggingface.ts +8 -19
  203. package/src/registry/index.ts +4 -0
  204. package/src/{utils/oauth → registry}/kagi.ts +9 -11
  205. package/src/{utils/oauth → registry}/kilo.ts +11 -6
  206. package/src/registry/kimi-code.ts +17 -0
  207. package/src/{utils/oauth → registry}/litellm.ts +8 -12
  208. package/src/{utils/oauth → registry}/lm-studio.ts +9 -17
  209. package/src/registry/minimax-code-cn.ts +12 -0
  210. package/src/registry/minimax-code.ts +12 -0
  211. package/src/registry/minimax.ts +6 -0
  212. package/src/registry/mistral.ts +6 -0
  213. package/src/{utils/oauth → registry}/moonshot.ts +8 -9
  214. package/src/{utils/oauth → registry}/nanogpt.ts +8 -1
  215. package/src/{utils/oauth → registry}/nvidia.ts +8 -18
  216. package/src/{utils → registry}/oauth/__tests__/xai-oauth.test.ts +4 -7
  217. package/src/{utils → registry}/oauth/anthropic.ts +38 -17
  218. package/src/{utils → registry}/oauth/github-copilot.ts +79 -115
  219. package/src/registry/oauth/gitlab-duo.ts +198 -0
  220. package/src/{utils → registry}/oauth/google-antigravity.ts +1 -4
  221. package/src/{utils → registry}/oauth/google-gemini-cli.ts +1 -4
  222. package/src/registry/oauth/index.ts +164 -0
  223. package/src/{utils → registry}/oauth/minimax-code.ts +16 -14
  224. package/src/{utils → registry}/oauth/types.ts +7 -51
  225. package/src/{utils → registry}/oauth/wafer.ts +1 -1
  226. package/src/{utils → registry}/oauth/xai-oauth.ts +16 -8
  227. package/src/{utils → registry}/oauth/xiaomi.ts +9 -4
  228. package/src/{utils/oauth → registry}/ollama-cloud.ts +8 -1
  229. package/src/{utils/oauth → registry}/ollama.ts +8 -13
  230. package/src/registry/openai-codex-device.ts +18 -0
  231. package/src/registry/openai-codex.ts +19 -0
  232. package/src/registry/openai.ts +6 -0
  233. package/src/registry/opencode-go.ts +12 -0
  234. package/src/registry/opencode-zen.ts +12 -0
  235. package/src/{utils/oauth → registry}/openrouter.ts +10 -2
  236. package/src/{utils/oauth → registry}/parallel.ts +9 -11
  237. package/src/registry/perplexity.ts +13 -0
  238. package/src/{utils/oauth → registry}/qianfan.ts +8 -17
  239. package/src/{utils/oauth → registry}/qwen-portal.ts +8 -19
  240. package/src/registry/registry.ts +149 -0
  241. package/src/{utils/oauth → registry}/synthetic.ts +7 -1
  242. package/src/{utils/oauth → registry}/tavily.ts +10 -12
  243. package/src/{utils/oauth → registry}/together.ts +7 -1
  244. package/src/registry/types.ts +56 -0
  245. package/src/{utils/oauth → registry}/venice.ts +8 -12
  246. package/src/{utils/oauth → registry}/vercel-ai-gateway.ts +8 -18
  247. package/src/{utils/oauth → registry}/vllm.ts +9 -16
  248. package/src/registry/wafer-pass.ts +12 -0
  249. package/src/registry/wafer-serverless.ts +12 -0
  250. package/src/registry/xai-oauth.ts +17 -0
  251. package/src/registry/xai.ts +6 -0
  252. package/src/registry/xiaomi-token-plan-ams.ts +12 -0
  253. package/src/registry/xiaomi-token-plan-cn.ts +12 -0
  254. package/src/registry/xiaomi-token-plan-sgp.ts +12 -0
  255. package/src/registry/xiaomi.ts +12 -0
  256. package/src/{utils/oauth → registry}/zai.ts +10 -22
  257. package/src/{utils/oauth → registry}/zenmux.ts +8 -1
  258. package/src/{utils/oauth/zhipu.ts → registry/zhipu-coding-plan.ts} +9 -21
  259. package/src/stream.ts +229 -199
  260. package/src/types.ts +63 -384
  261. package/src/usage/claude.ts +4 -2
  262. package/src/usage/github-copilot.ts +4 -2
  263. package/src/usage/google-antigravity.ts +196 -28
  264. package/src/usage/kimi.ts +1 -1
  265. package/src/usage/minimax-code.ts +5 -6
  266. package/src/usage/openai-codex-reset.ts +174 -0
  267. package/src/usage/openai-codex.ts +19 -2
  268. package/src/usage/zai.ts +2 -1
  269. package/src/usage.ts +93 -4
  270. package/src/utils/abort.ts +14 -0
  271. package/src/utils/event-stream.ts +17 -0
  272. package/src/utils/http-inspector.ts +4 -12
  273. package/src/utils/idle-iterator.ts +250 -79
  274. package/src/utils/openai-http.ts +157 -0
  275. package/src/utils/request-debug.ts +67 -19
  276. package/src/utils/retry-after.ts +1 -1
  277. package/src/utils/retry.ts +23 -2
  278. package/src/utils/schema/CONSTRAINTS.md +4 -2
  279. package/src/utils/schema/fields.ts +16 -0
  280. package/src/utils/schema/json-schema-validator.ts +19 -1
  281. package/src/utils/schema/normalize.ts +80 -8
  282. package/src/utils/schema/stamps.ts +22 -10
  283. package/src/utils/schema/wire.ts +2 -2
  284. package/src/utils/sse-debug.ts +0 -271
  285. package/src/utils/stream-markup-healing.ts +50 -8
  286. package/src/utils/validation.ts +49 -13
  287. package/src/utils.ts +2 -26
  288. package/dist/types/model-cache.d.ts +0 -17
  289. package/dist/types/model-manager.d.ts +0 -64
  290. package/dist/types/model-thinking.d.ts +0 -100
  291. package/dist/types/models.d.ts +0 -12
  292. package/dist/types/provider-models/bundled-references.d.ts +0 -4
  293. package/dist/types/provider-models/descriptors.d.ts +0 -50
  294. package/dist/types/provider-models/google.d.ts +0 -24
  295. package/dist/types/provider-models/index.d.ts +0 -5
  296. package/dist/types/provider-models/ollama.d.ts +0 -7
  297. package/dist/types/provider-models/openai-compat.d.ts +0 -323
  298. package/dist/types/provider-models/special.d.ts +0 -16
  299. package/dist/types/utils/discovery/antigravity.d.ts +0 -61
  300. package/dist/types/utils/discovery/codex.d.ts +0 -38
  301. package/dist/types/utils/discovery/cursor.d.ts +0 -23
  302. package/dist/types/utils/discovery/gemini.d.ts +0 -25
  303. package/dist/types/utils/discovery/index.d.ts +0 -4
  304. package/dist/types/utils/discovery/openai-compatible.d.ts +0 -72
  305. package/dist/types/utils/oauth/alibaba-coding-plan.d.ts +0 -18
  306. package/dist/types/utils/oauth/cerebras.d.ts +0 -1
  307. package/dist/types/utils/oauth/cloudflare-ai-gateway.d.ts +0 -18
  308. package/dist/types/utils/oauth/deepseek.d.ts +0 -10
  309. package/dist/types/utils/oauth/firepass.d.ts +0 -1
  310. package/dist/types/utils/oauth/fireworks.d.ts +0 -1
  311. package/dist/types/utils/oauth/huggingface.d.ts +0 -19
  312. package/dist/types/utils/oauth/kagi.d.ts +0 -17
  313. package/dist/types/utils/oauth/kilo.d.ts +0 -5
  314. package/dist/types/utils/oauth/litellm.d.ts +0 -18
  315. package/dist/types/utils/oauth/lm-studio.d.ts +0 -17
  316. package/dist/types/utils/oauth/moonshot.d.ts +0 -1
  317. package/dist/types/utils/oauth/nanogpt.d.ts +0 -1
  318. package/dist/types/utils/oauth/nvidia.d.ts +0 -18
  319. package/dist/types/utils/oauth/ollama-cloud.d.ts +0 -2
  320. package/dist/types/utils/oauth/ollama.d.ts +0 -18
  321. package/dist/types/utils/oauth/openrouter.d.ts +0 -1
  322. package/dist/types/utils/oauth/parallel.d.ts +0 -17
  323. package/dist/types/utils/oauth/qianfan.d.ts +0 -17
  324. package/dist/types/utils/oauth/qwen-portal.d.ts +0 -19
  325. package/dist/types/utils/oauth/synthetic.d.ts +0 -1
  326. package/dist/types/utils/oauth/tavily.d.ts +0 -17
  327. package/dist/types/utils/oauth/together.d.ts +0 -1
  328. package/dist/types/utils/oauth/venice.d.ts +0 -18
  329. package/dist/types/utils/oauth/vercel-ai-gateway.d.ts +0 -18
  330. package/dist/types/utils/oauth/vllm.d.ts +0 -16
  331. package/dist/types/utils/oauth/zai.d.ts +0 -18
  332. package/dist/types/utils/oauth/zenmux.d.ts +0 -1
  333. package/dist/types/utils/oauth/zhipu.d.ts +0 -18
  334. package/src/model-cache.ts +0 -129
  335. package/src/model-manager.ts +0 -469
  336. package/src/model-thinking.ts +0 -756
  337. package/src/models.json +0 -60287
  338. package/src/models.json.d.ts +0 -9
  339. package/src/models.ts +0 -56
  340. package/src/provider-models/bundled-references.ts +0 -38
  341. package/src/provider-models/descriptors.ts +0 -364
  342. package/src/provider-models/google.ts +0 -88
  343. package/src/provider-models/index.ts +0 -5
  344. package/src/provider-models/ollama.ts +0 -153
  345. package/src/provider-models/openai-compat.ts +0 -2904
  346. package/src/provider-models/special.ts +0 -67
  347. package/src/utils/discovery/antigravity.ts +0 -261
  348. package/src/utils/discovery/codex.ts +0 -371
  349. package/src/utils/discovery/cursor.ts +0 -306
  350. package/src/utils/discovery/gemini.ts +0 -248
  351. package/src/utils/discovery/index.ts +0 -4
  352. package/src/utils/discovery/openai-compatible.ts +0 -224
  353. package/src/utils/oauth/gitlab-duo.ts +0 -123
  354. package/src/utils/oauth/index.ts +0 -502
  355. /package/dist/types/{utils/oauth/__tests__/xai-oauth.test.d.ts → providers/__tests__/google-auth.test.d.ts} +0 -0
  356. /package/dist/types/{utils → registry}/oauth/callback-server.d.ts +0 -0
  357. /package/dist/types/{utils → registry}/oauth/cursor.d.ts +0 -0
  358. /package/dist/types/{utils → registry}/oauth/gitlab-duo.d.ts +0 -0
  359. /package/dist/types/{utils → registry}/oauth/google-antigravity.d.ts +0 -0
  360. /package/dist/types/{utils → registry}/oauth/google-gemini-cli.d.ts +0 -0
  361. /package/dist/types/{utils → registry}/oauth/google-oauth-shared.d.ts +0 -0
  362. /package/dist/types/{utils → registry}/oauth/kimi.d.ts +0 -0
  363. /package/dist/types/{utils → registry}/oauth/openai-codex.d.ts +0 -0
  364. /package/dist/types/{utils → registry}/oauth/opencode.d.ts +0 -0
  365. /package/dist/types/{utils → registry}/oauth/perplexity.d.ts +0 -0
  366. /package/dist/types/{utils → registry}/oauth/pkce.d.ts +0 -0
  367. /package/dist/types/{utils → registry}/oauth/wafer.d.ts +0 -0
  368. /package/dist/types/{utils → registry}/oauth/xiaomi.d.ts +0 -0
  369. /package/src/{utils → registry}/oauth/callback-server.ts +0 -0
  370. /package/src/{utils → registry}/oauth/cursor.ts +0 -0
  371. /package/src/{utils → registry}/oauth/google-oauth-shared.ts +0 -0
  372. /package/src/{utils → registry}/oauth/kimi.ts +0 -0
  373. /package/src/{utils → registry}/oauth/oauth.html +0 -0
  374. /package/src/{utils → registry}/oauth/openai-codex.ts +0 -0
  375. /package/src/{utils → registry}/oauth/opencode.ts +0 -0
  376. /package/src/{utils → registry}/oauth/perplexity.ts +0 -0
  377. /package/src/{utils → registry}/oauth/pkce.ts +0 -0
package/src/errors.ts ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Structured HTTP errors thrown by provider clients.
3
+ *
4
+ * Downstream classification reads these fields structurally rather than via
5
+ * `instanceof`: `extractHttpStatusFromError` (@prometheus-ai/utils) reads `status`,
6
+ * `getHeadersFromError` (retry-after extraction) reads `headers`, and retry
7
+ * policies such as `isCopilotTransientModelError` read `code`. Per-provider
8
+ * subclasses exist so call sites can narrow with `instanceof` and logs carry
9
+ * a meaningful `error.name`.
10
+ */
11
+ export interface ProviderHttpErrorOptions {
12
+ /** Response headers; enables `retry-after`/rate-limit extraction downstream. */
13
+ headers?: Headers;
14
+ /** Machine-readable error code from the response body (`error.code` / `error.type`). */
15
+ code?: string;
16
+ cause?: unknown;
17
+ }
18
+
19
+ /** Non-2xx HTTP response from a provider endpoint. */
20
+ export class ProviderHttpError extends Error {
21
+ readonly status: number;
22
+ readonly headers: Headers | undefined;
23
+ readonly code: string | undefined;
24
+
25
+ constructor(message: string, status: number, options?: ProviderHttpErrorOptions) {
26
+ super(message, options?.cause === undefined ? undefined : { cause: options.cause });
27
+ this.name = "ProviderHttpError";
28
+ this.status = status;
29
+ this.headers = options?.headers;
30
+ this.code = options?.code;
31
+ }
32
+ }
package/src/index.ts CHANGED
@@ -1,15 +1,17 @@
1
+ export {
2
+ ANTIGRAVITY_SYSTEM_INSTRUCTION,
3
+ getAntigravityUserAgent,
4
+ getGeminiCliHeaders,
5
+ } from "@prometheus-ai/catalog/wire/gemini-headers";
1
6
  export { type ZodType, z } from "zod/v4";
2
7
  export * from "./api-registry";
3
8
  export * from "./auth-broker";
4
9
  export { type AuthGatewayBootOptions, type ModelResolver, startAuthGateway } from "./auth-gateway/server";
5
10
  export * from "./auth-gateway/types";
11
+ export * from "./auth-retry";
6
12
  export * from "./auth-storage";
7
- export * from "./model-cache";
8
- export * from "./model-manager";
9
- export * from "./model-thinking";
10
- export * from "./models";
13
+ export * from "./errors";
11
14
  export * from "./provider-details";
12
- export * from "./provider-models";
13
15
  export * from "./providers/anthropic";
14
16
  export * from "./providers/anthropic-client";
15
17
  export * from "./providers/azure-openai-responses";
@@ -17,7 +19,6 @@ export type * from "./providers/cursor";
17
19
  export * from "./providers/gitlab-duo";
18
20
  export type * from "./providers/google";
19
21
  export type * from "./providers/google-gemini-cli";
20
- export * from "./providers/google-gemini-headers";
21
22
  export type * from "./providers/google-vertex";
22
23
  export * from "./providers/kimi";
23
24
  export * from "./providers/mock";
@@ -27,6 +28,7 @@ export * from "./providers/openai-completions";
27
28
  export * from "./providers/openai-responses";
28
29
  export * from "./providers/synthetic";
29
30
  export * from "./rate-limit-utils";
31
+ export * from "./registry";
30
32
  export * from "./stream";
31
33
  export * from "./types";
32
34
  export * from "./usage";
@@ -37,17 +39,10 @@ export * from "./usage/google-antigravity";
37
39
  export * from "./usage/kimi";
38
40
  export * from "./usage/minimax-code";
39
41
  export * from "./usage/openai-codex";
42
+ export * from "./usage/openai-codex-reset";
40
43
  export * from "./usage/zai";
41
44
  export * from "./utils/anthropic-auth";
42
- export * from "./utils/discovery";
43
45
  export * from "./utils/event-stream";
44
- export * from "./utils/oauth";
45
- export type {
46
- OAuthCredentials,
47
- OAuthProvider,
48
- OAuthProviderId,
49
- OAuthProviderInfo,
50
- } from "./utils/oauth/types";
51
46
  export * from "./utils/overflow";
52
47
  export * from "./utils/retry";
53
48
  export * from "./utils/schema";
@@ -18,7 +18,7 @@ export interface ProviderDetailsContext {
18
18
  authMode?: string;
19
19
  /**
20
20
  * Human-readable description of the active credential, e.g.
21
- * `"broker http://can.internal:8765 · oauth #5 (foo@bar.com)"`.
21
+ * `"broker http://auth-broker.internal:8765 - oauth #5 (foo@bar.com)"`.
22
22
  * Rendered as a `Source` field; omitted when undefined.
23
23
  */
24
24
  credentialSource?: string;
@@ -0,0 +1,144 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from "bun:test";
2
+ import { Buffer } from "node:buffer";
3
+ import * as fs from "node:fs/promises";
4
+ import * as os from "node:os";
5
+ import * as path from "node:path";
6
+ import type { FetchImpl } from "../../types";
7
+ import { __resetVertexTokenCache, getVertexAccessToken } from "../google-auth";
8
+
9
+ const CLOUD_PLATFORM_SCOPE = "https://www.googleapis.com/auth/cloud-platform";
10
+ const JWT_BEARER_GRANT = "urn:ietf:params:oauth:grant-type:jwt-bearer";
11
+
12
+ /** Generate a real RS256 private key so signJwtRs256 / pemToPkcs8 run for real. */
13
+ async function generateServiceAccountPem(): Promise<string> {
14
+ const keyPair = (await globalThis.crypto.subtle.generateKey(
15
+ { name: "RSASSA-PKCS1-v1_5", modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: "SHA-256" },
16
+ true,
17
+ ["sign", "verify"],
18
+ )) as CryptoKeyPair;
19
+ const pkcs8 = new Uint8Array(await globalThis.crypto.subtle.exportKey("pkcs8", keyPair.privateKey));
20
+ const body = (
21
+ Buffer.from(pkcs8)
22
+ .toString("base64")
23
+ .match(/.{1,64}/g) ?? []
24
+ ).join("\n");
25
+ return `-----BEGIN PRIVATE KEY-----\n${body}\n-----END PRIVATE KEY-----\n`;
26
+ }
27
+
28
+ function urlOf(input: string | URL | Request): string {
29
+ if (typeof input === "string") return input;
30
+ if (input instanceof URL) return input.toString();
31
+ return input.url;
32
+ }
33
+
34
+ describe("getVertexAccessToken impersonated_service_account ADC", () => {
35
+ let tmpDir: string;
36
+ let originalGac: string | undefined;
37
+
38
+ beforeEach(async () => {
39
+ __resetVertexTokenCache();
40
+ originalGac = Bun.env.GOOGLE_APPLICATION_CREDENTIALS;
41
+ tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), "prometheus-vertex-adc-"));
42
+ });
43
+
44
+ afterEach(async () => {
45
+ __resetVertexTokenCache();
46
+ if (originalGac === undefined) delete Bun.env.GOOGLE_APPLICATION_CREDENTIALS;
47
+ else Bun.env.GOOGLE_APPLICATION_CREDENTIALS = originalGac;
48
+ await fs.rm(tmpDir, { recursive: true, force: true });
49
+ });
50
+
51
+ it("rejects a malformed service_account_impersonation_url before any network call", async () => {
52
+ const adcPath = path.join(tmpDir, "impersonated-bad-url.json");
53
+ await Bun.write(
54
+ adcPath,
55
+ JSON.stringify({
56
+ type: "impersonated_service_account",
57
+ // Missing the trailing ":generateAccessToken" the principal parser requires.
58
+ service_account_impersonation_url:
59
+ "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/target@project.iam.gserviceaccount.com",
60
+ source_credentials: {
61
+ type: "authorized_user",
62
+ client_id: "client-id",
63
+ client_secret: "client-secret",
64
+ refresh_token: "refresh-token",
65
+ },
66
+ }),
67
+ );
68
+ Bun.env.GOOGLE_APPLICATION_CREDENTIALS = adcPath;
69
+
70
+ const calls: string[] = [];
71
+ const fetchImpl: FetchImpl = async input => {
72
+ calls.push(urlOf(input));
73
+ return new Response("{}");
74
+ };
75
+
76
+ // The principal is parsed before the source exchange, so a bad URL must fail
77
+ // up front rather than after burning a source-token round trip.
78
+ await expect(getVertexAccessToken({ fetch: fetchImpl })).rejects.toBeInstanceOf(RangeError);
79
+ expect(calls).toEqual([]);
80
+ });
81
+
82
+ it("signs an RS256 JWT for a service_account source and reconstructs the IAM URL", async () => {
83
+ const pem = await generateServiceAccountPem();
84
+ const adcPath = path.join(tmpDir, "impersonated-sa.json");
85
+ await Bun.write(
86
+ adcPath,
87
+ JSON.stringify({
88
+ type: "impersonated_service_account",
89
+ // Non-canonical project segment proves the request URL is rebuilt, not echoed.
90
+ service_account_impersonation_url:
91
+ "https://iamcredentials.googleapis.com/v1/projects/explicit-proj/serviceAccounts/target@project.iam.gserviceaccount.com:generateAccessToken",
92
+ source_credentials: {
93
+ type: "service_account",
94
+ client_email: "source@project.iam.gserviceaccount.com",
95
+ private_key: pem,
96
+ private_key_id: "key-1",
97
+ },
98
+ // delegates intentionally omitted — the IAM body must default to [].
99
+ }),
100
+ );
101
+ Bun.env.GOOGLE_APPLICATION_CREDENTIALS = adcPath;
102
+
103
+ const calls: { url: string; init?: RequestInit }[] = [];
104
+ const fetchImpl: FetchImpl = async (input, init) => {
105
+ const url = urlOf(input);
106
+ calls.push({ url, init });
107
+ if (url === "https://oauth2.googleapis.com/token") {
108
+ return new Response(JSON.stringify({ access_token: "sa-source-token", expires_in: 3600 }));
109
+ }
110
+ if (url.startsWith("https://iamcredentials.googleapis.com/")) {
111
+ return new Response(
112
+ JSON.stringify({
113
+ accessToken: "impersonated-token",
114
+ expireTime: new Date(Date.now() + 3_600_000).toISOString(),
115
+ }),
116
+ );
117
+ }
118
+ return new Response("unexpected", { status: 404 });
119
+ };
120
+
121
+ const token = await getVertexAccessToken({ fetch: fetchImpl });
122
+ expect(token).toBe("impersonated-token");
123
+
124
+ // Source JWT exchange happens first, then the impersonation exchange.
125
+ expect(calls.map(c => c.url)).toEqual([
126
+ "https://oauth2.googleapis.com/token",
127
+ "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/target@project.iam.gserviceaccount.com:generateAccessToken",
128
+ ]);
129
+
130
+ // Source credential is exchanged via a signed JWT bearer assertion, not a refresh grant.
131
+ const sourceBody = new URLSearchParams(String(calls[0].init?.body));
132
+ expect(sourceBody.get("grant_type")).toBe(JWT_BEARER_GRANT);
133
+ expect((sourceBody.get("assertion") ?? "").split(".")).toHaveLength(3);
134
+
135
+ // The IAM call carries the source-derived bearer token and defaults delegates to [].
136
+ const iamHeaders = calls[1].init?.headers as Record<string, string>;
137
+ expect(iamHeaders.Authorization).toBe("Bearer sa-source-token");
138
+ expect(JSON.parse(String(calls[1].init?.body))).toEqual({
139
+ delegates: [],
140
+ scope: [CLOUD_PLATFORM_SCOPE],
141
+ lifetime: "3600s",
142
+ });
143
+ });
144
+ });
@@ -7,10 +7,11 @@
7
7
  * Bun's native `HTTPS_PROXY` support.
8
8
  */
9
9
 
10
+ import type { Effort } from "@prometheus-ai/catalog/effort";
11
+ import { mapEffortToAnthropicAdaptiveEffort, requireSupportedEffort } from "@prometheus-ai/catalog/model-thinking";
12
+ import { calculateCost } from "@prometheus-ai/catalog/models";
10
13
  import { $env, $flag, extractHttpStatusFromError, fetchWithRetry } from "@prometheus-ai/utils";
11
- import type { Effort } from "../model-thinking";
12
- import { mapEffortToAnthropicAdaptiveEffort, requireSupportedEffort } from "../model-thinking";
13
- import { calculateCost } from "../models";
14
+ import { ProviderHttpError } from "../errors";
14
15
  import type {
15
16
  Api,
16
17
  AssistantMessage,
@@ -29,14 +30,20 @@ import type {
29
30
  } from "../types";
30
31
  import { normalizeToolCallId, resolveCacheRetention } from "../utils";
31
32
  import { AssistantMessageEventStream } from "../utils/event-stream";
32
- import { appendRawHttpRequestDumpFor400, type RawHttpRequestDump, withHttpStatus } from "../utils/http-inspector";
33
+ import { appendRawHttpRequestDumpFor400, type RawHttpRequestDump } from "../utils/http-inspector";
34
+ import { getStreamFirstEventTimeoutMs } from "../utils/idle-iterator";
33
35
  import { parseStreamingJson, parseStreamingJsonThrottled } from "../utils/json-parse";
34
36
  import { toolWireSchema } from "../utils/schema/wire";
35
- import { resolveAwsCredentials } from "./aws-credentials";
37
+ import { invalidateAwsCredentialCache, resolveAwsCredentials } from "./aws-credentials";
36
38
  import { decodeEventStream } from "./aws-eventstream";
37
39
  import { signRequest } from "./aws-sigv4";
38
40
  import { transformMessages } from "./transform-messages";
39
41
 
42
+ /** Non-2xx response (or in-stream exception event) from the Bedrock runtime API. */
43
+ export class BedrockApiError extends ProviderHttpError {
44
+ override readonly name = "BedrockApiError";
45
+ }
46
+
40
47
  export type BedrockThinkingDisplay = "summarized" | "omitted";
41
48
 
42
49
  export interface BedrockOptions extends StreamOptions {
@@ -57,11 +64,12 @@ export interface BedrockOptions extends StreamOptions {
57
64
  * - `"omitted"`: thinking content is suppressed; the encrypted signature still
58
65
  * travels back for multi-turn continuity.
59
66
  *
60
- * Starting with Claude Opus 4.7 the Anthropic API default is `"omitted"`, which
61
- * leaves callers waiting on a silent stream during long reasoning runs (issue
62
- * #1373). We default to `"summarized"` so adaptive-thinking models that accept
63
- * the field keep producing visible thinking deltas. Older adaptive-thinking
64
- * models (Opus 4.6, Sonnet 4.6+) reject the field, so we omit it for them.
67
+ * Starting with Claude Opus 4.7 and Claude Fable/Mythos 5 the Anthropic API
68
+ * default is `"omitted"`, which leaves callers waiting on a silent stream during
69
+ * long reasoning runs (issue #1373). We default to `"summarized"` so adaptive-
70
+ * thinking models that accept the field keep producing visible thinking deltas.
71
+ * Older adaptive-thinking models (Opus 4.6, Sonnet 4.6+) reject the field, so
72
+ * we omit it for them.
65
73
  */
66
74
  thinkingDisplay?: BedrockThinkingDisplay;
67
75
  }
@@ -202,7 +210,10 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream"> = (
202
210
 
203
211
  try {
204
212
  const cacheRetention = resolveCacheRetention(options.cacheRetention);
205
- const toolConfig = convertToolConfig(context.tools, options.toolChoice);
213
+ const historyHasToolBlocks = context.messages.some(
214
+ m => m.role === "toolResult" || (m.role === "assistant" && m.content.some(b => b.type === "toolCall")),
215
+ );
216
+ const toolConfig = convertToolConfig(context.tools, options.toolChoice, historyHasToolBlocks);
206
217
  let additionalModelRequestFields = buildAdditionalModelRequestFields(model, options);
207
218
 
208
219
  // Bedrock rejects thinking + forced tool_choice ("any" or specific tool).
@@ -272,20 +283,41 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream"> = (
272
283
  requestHeaders = { ...baseHeaders, ...signed };
273
284
  }
274
285
 
286
+ // Bun's native fetch ceiling is disabled below (`timeout: false`) so
287
+ // configurable watchdogs govern slow-prefill streams (issue #2422).
288
+ // Direct callers that bypass `register-builtins` (which installs the
289
+ // iterator-level first-event watchdog) still need a pre-response
290
+ // timer, otherwise a Bedrock/proxy that accepts the POST and never
291
+ // sends headers would hang forever.
292
+ const firstEventTimeoutMs = options.streamFirstEventTimeoutMs ?? getStreamFirstEventTimeoutMs();
293
+ const preResponseWatchdog =
294
+ firstEventTimeoutMs !== undefined && firstEventTimeoutMs > 0
295
+ ? AbortSignal.timeout(firstEventTimeoutMs)
296
+ : undefined;
297
+ const fetchSignal = preResponseWatchdog
298
+ ? options.signal
299
+ ? AbortSignal.any([options.signal, preResponseWatchdog])
300
+ : preResponseWatchdog
301
+ : options.signal;
275
302
  const response = await fetchWithRetry(url, {
276
303
  method: "POST",
277
304
  headers: requestHeaders,
278
305
  body,
279
- signal: options.signal,
306
+ signal: fetchSignal,
280
307
  fetch: options.fetch,
308
+ timeout: false,
281
309
  });
282
310
 
283
311
  if (!response.ok) {
312
+ if (!bearerToken && (response.status === 401 || response.status === 403)) {
313
+ // Stale cached credentials (e.g. rotated session keys in ~/.aws/credentials) —
314
+ // drop the cache entry so the next attempt re-resolves from scratch.
315
+ invalidateAwsCredentialCache({ profile: options.profile, region });
316
+ }
284
317
  const errBody = await response.text().catch(() => "");
285
- throw withHttpStatus(
286
- new Error(`Bedrock HTTP ${response.status}: ${errBody.slice(0, 1000)}`),
287
- response.status,
288
- );
318
+ throw new BedrockApiError(`Bedrock HTTP ${response.status}: ${errBody.slice(0, 1000)}`, response.status, {
319
+ headers: response.headers,
320
+ });
289
321
  }
290
322
  if (!response.body) throw new Error("Bedrock response has no body");
291
323
 
@@ -298,9 +330,10 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream"> = (
298
330
  const exceptionType = message.headers[":exception-type"] || "Exception";
299
331
  const payload = safeParsePayload(message.payload) as { message?: string } | undefined;
300
332
  const errorMessage = payload?.message || new TextDecoder().decode(message.payload);
301
- const status = exceptionType === "validationException" ? 400 : 0;
302
- const err = new Error(`${exceptionType}: ${errorMessage}`);
303
- throw status ? withHttpStatus(err, status) : err;
333
+ const text = `${exceptionType}: ${errorMessage}`;
334
+ throw exceptionType === "validationException"
335
+ ? new BedrockApiError(text, 400, { code: exceptionType })
336
+ : new Error(text);
304
337
  }
305
338
  if (messageType === "error") {
306
339
  const code = message.headers[":error-code"] || "UnknownError";
@@ -339,6 +372,9 @@ export const streamBedrock: StreamFunction<"bedrock-converse-stream"> = (
339
372
  case "messageStop": {
340
373
  const ev = payload as MessageStopEvent;
341
374
  output.stopReason = mapStopReason(ev.stopReason);
375
+ if (output.stopReason === "error") {
376
+ output.errorMessage = `Generation failed with stop reason: ${ev.stopReason ?? "unknown"}`;
377
+ }
342
378
  break;
343
379
  }
344
380
  case "metadata": {
@@ -739,8 +775,9 @@ function convertMessages(
739
775
  function convertToolConfig(
740
776
  tools: Tool[] | undefined,
741
777
  toolChoice: BedrockOptions["toolChoice"],
778
+ historyHasToolBlocks: boolean,
742
779
  ): WireToolConfig | undefined {
743
- if (!tools?.length || toolChoice === "none") return undefined;
780
+ if (!tools?.length) return undefined;
744
781
 
745
782
  const bedrockTools: WireToolSpec[] = tools.map(tool => ({
746
783
  toolSpec: {
@@ -750,6 +787,13 @@ function convertToolConfig(
750
787
  },
751
788
  }));
752
789
 
790
+ // Bedrock rejects requests whose history contains toolUse/toolResult blocks without a
791
+ // toolConfig. With prior tool use we must keep the tool specs and merely omit the choice
792
+ // (there is no "none" choice on Converse); dropping toolConfig entirely would 400.
793
+ if (toolChoice === "none") {
794
+ return historyHasToolBlocks ? { tools: bedrockTools } : undefined;
795
+ }
796
+
753
797
  let bedrockToolChoice: WireToolChoice | undefined;
754
798
  switch (toolChoice) {
755
799
  case "auto":
@@ -792,12 +836,13 @@ function buildAdditionalModelRequestFields(
792
836
  const mode = model.thinking?.mode;
793
837
  if (mode === "anthropic-adaptive") {
794
838
  const effort = mapEffortToAnthropicAdaptiveEffort(model, reasoning);
795
- // Starting with Claude Opus 4.7, Anthropic switched the adaptive-thinking
796
- // default to "omitted", which silently suppresses streamed reasoning and
797
- // can read as a stalled stream during long reasoning runs (issue #1373).
798
- // Opt back into "summarized" by default on models that accept the field.
839
+ // Starting with Claude Opus 4.7 and Claude Fable/Mythos 5, Anthropic switched
840
+ // the adaptive-thinking default to "omitted", which silently suppresses
841
+ // streamed reasoning and can read as a stalled stream during long reasoning
842
+ // runs (issue #1373). Opt back into "summarized" by default on models that
843
+ // accept the field.
799
844
  const adaptive: { type: "adaptive"; display?: BedrockThinkingDisplay } = { type: "adaptive" };
800
- if (supportsAdaptiveThinkingDisplay(model.id)) {
845
+ if (model.thinking?.supportsDisplay) {
801
846
  adaptive.display = options.thinkingDisplay ?? "summarized";
802
847
  }
803
848
  return {
@@ -831,21 +876,6 @@ function buildAdditionalModelRequestFields(
831
876
  return result;
832
877
  }
833
878
 
834
- /**
835
- * Adaptive thinking `display` is supported starting with Claude Opus 4.7.
836
- * Older adaptive-thinking models (Opus 4.6, Sonnet 4.6+) reject the field.
837
- * Bedrock model ids are prefixed with region/inference-profile slugs (e.g.
838
- * `eu.anthropic.claude-opus-4-7-...`); the regex matches the `claude-opus-X-Y`
839
- * fragment regardless of prefix.
840
- */
841
- function supportsAdaptiveThinkingDisplay(modelId: string): boolean {
842
- const match = /claude-opus-(\d+)-(\d+)/.exec(modelId);
843
- if (!match) return false;
844
- const major = Number(match[1]);
845
- const minor = Number(match[2]);
846
- return major > 4 || (major === 4 && minor >= 7);
847
- }
848
-
849
879
  /**
850
880
  * Bedrock's wire format expects the image as `{ source: { bytes: <base64-string> }, format }`.
851
881
  * The caller already passes base64-encoded data, so no decode/re-encode round-trip is needed.
@@ -1,8 +1,8 @@
1
1
  /**
2
2
  * Minimal HTTP client for the Anthropic Messages API.
3
3
  *
4
- * @prometheus-ai/ai builds every request header itself (`buildAnthropicHeaders`), serializes
5
- * the body itself (`buildParams`), and parses SSE frames itself
4
+ * This package builds every request header itself (`buildAnthropicHeaders`),
5
+ * serializes the body itself (`buildParams`), and parses SSE frames itself
6
6
  * (`iterateAnthropicEvents`), so the only `@anthropic-ai/sdk` surface this
7
7
  * package ever exercised was URL assembly, auth-header injection, bounded
8
8
  * retries, the pre-response timeout, and HTTP-error-to-status mapping. This
@@ -21,6 +21,7 @@
21
21
  * with up to 25% jitter).
22
22
  */
23
23
  import { scheduler } from "node:timers/promises";
24
+ import { ProviderHttpError } from "../errors";
24
25
  import type { FetchImpl } from "../types";
25
26
  import type { MessageCreateParamsStreaming } from "./anthropic-wire";
26
27
 
@@ -43,7 +44,9 @@ export interface AnthropicRequestOptions {
43
44
  /**
44
45
  * Extra `RequestInit` fields merged into every fetch call. Bun extends
45
46
  * `RequestInit` with a `tls` option used for the Claude Code TLS profile and
46
- * Foundry mTLS.
47
+ * Foundry mTLS. Core request fields (`method`, `headers`, `body`, `signal`)
48
+ * are owned by the client and cannot be overridden from here — the timeout
49
+ * controller's signal in particular must always win.
47
50
  */
48
51
  export type AnthropicFetchOptions = RequestInit & {
49
52
  tls?: {
@@ -54,6 +57,8 @@ export type AnthropicFetchOptions = RequestInit & {
54
57
  cert?: string;
55
58
  key?: string;
56
59
  };
60
+ /** Bun extension: see {@link FetchWithRetryOptions.timeout} — `false` disables Bun's native fetch TTFT timeout (issue #2422). */
61
+ timeout?: number | false;
57
62
  };
58
63
 
59
64
  export interface AnthropicClientOptions {
@@ -71,16 +76,13 @@ export interface AnthropicClientOptions {
71
76
  }
72
77
 
73
78
  /** Non-2xx response from the Anthropic API. */
74
- export class AnthropicApiError extends Error {
75
- readonly status: number;
76
- readonly headers: Headers;
79
+ export class AnthropicApiError extends ProviderHttpError {
80
+ declare readonly headers: Headers;
77
81
  readonly requestId: string | null;
78
82
 
79
83
  constructor(status: number, message: string, headers: Headers) {
80
- super(message);
84
+ super(message, status, { headers });
81
85
  this.name = "AnthropicApiError";
82
- this.status = status;
83
- this.headers = headers;
84
86
  this.requestId = headers.get("request-id");
85
87
  }
86
88
 
@@ -121,7 +123,7 @@ function shouldRetryResponse(response: Response): boolean {
121
123
  }
122
124
 
123
125
  /** Server-suggested delay (`retry-after-ms`, then `retry-after` seconds or HTTP date). */
124
- function retryDelayFromHeaders(headers: Headers | undefined): number | undefined {
126
+ export function retryDelayFromHeaders(headers: Headers | undefined): number | undefined {
125
127
  if (!headers) return undefined;
126
128
  const retryAfterMs = headers.get("retry-after-ms");
127
129
  if (retryAfterMs) {
@@ -138,7 +140,7 @@ function retryDelayFromHeaders(headers: Headers | undefined): number | undefined
138
140
  return undefined;
139
141
  }
140
142
 
141
- function defaultRetryDelayMs(attempt: number): number {
143
+ export function calculateAnthropicRetryDelayMs(attempt: number): number {
142
144
  const sleepSeconds = Math.min(INITIAL_RETRY_DELAY_S * 2 ** attempt, MAX_RETRY_DELAY_S);
143
145
  const jitter = 1 - Math.random() * 0.25;
144
146
  return sleepSeconds * jitter * 1000;
@@ -288,11 +290,11 @@ export class AnthropicMessagesClient implements AnthropicMessagesClientLike {
288
290
  callerSignal?.addEventListener("abort", onAbort, { once: true });
289
291
  try {
290
292
  return await fetchFn(url, {
293
+ ...(this.#options.fetchOptions ?? {}),
291
294
  method: "POST",
292
295
  headers,
293
296
  body,
294
297
  signal: controller.signal,
295
- ...(this.#options.fetchOptions ?? {}),
296
298
  });
297
299
  } catch (error) {
298
300
  if (timedOut && !callerSignal?.aborted) throw new AnthropicConnectionTimeoutError();
@@ -308,7 +310,7 @@ export class AnthropicMessagesClient implements AnthropicMessagesClientLike {
308
310
  responseHeaders: Headers | undefined,
309
311
  signal: AbortSignal | undefined,
310
312
  ): Promise<void> {
311
- const delayMs = retryDelayFromHeaders(responseHeaders) ?? defaultRetryDelayMs(attempt);
313
+ const delayMs = retryDelayFromHeaders(responseHeaders) ?? calculateAnthropicRetryDelayMs(attempt);
312
314
  try {
313
315
  await scheduler.wait(delayMs, { signal });
314
316
  } catch {
@@ -5,10 +5,10 @@
5
5
  * `.refine(...)` so the error mentions them explicitly.
6
6
  *
7
7
  * Used by `anthropic-messages.ts:parseRequest` to validate the inbound JSON
8
- * before walking it into @prometheus-ai/ai's canonical `Context`.
8
+ * before walking it into Prometheus AI's canonical `Context`.
9
9
  */
10
10
 
11
- import * as z from "zod/v4";
11
+ import { z } from "zod/v4";
12
12
  import type {
13
13
  ContentBlockParam,
14
14
  ImageBlockParam,
@@ -19,10 +19,10 @@ import type {
19
19
  ToolChoice,
20
20
  } from "./anthropic-wire";
21
21
 
22
- // `cache_control` is accepted and translated to @prometheus-ai/ai's per-request
22
+ // `cache_control` is accepted and translated to Prometheus AI's per-request
23
23
  // `cacheRetention` (any `ttl: "1h"` marker upgrades the request to "long";
24
24
  // any other ephemeral marker maps to "short"). The walker doesn't try to
25
- // preserve per-block breakpoints — @prometheus-ai/ai's anthropic provider re-applies them
25
+ // preserve per-block breakpoints — Prometheus AI's anthropic provider re-applies them
26
26
  // against the rebuilt outbound request anyway.
27
27
  export const cacheControlSchema = z
28
28
  .object({
@@ -102,7 +102,17 @@ const toolResultBlockSchema = z.object({
102
102
  // natively understand (server_tool_use, web_search_tool_result, mcp_*,
103
103
  // container_upload, code_execution_*, document, …). The walker flattens these
104
104
  // to a text placeholder so legitimate Anthropic clients don't get rejected.
105
- const unknownContentBlockSchema = z.object({ type: z.string() }).loose();
105
+ // Known `type` values are excluded so a malformed known block (e.g.
106
+ // `{type:"text", text: 123}`) fails validation with a clean 400 instead of
107
+ // slipping past the discriminated union and throwing a TypeError downstream.
108
+ function unknownContentBlockSchema(knownTypes: readonly string[]) {
109
+ const known = new Set(knownTypes);
110
+ return z
111
+ .object({
112
+ type: z.string().refine(t => !known.has(t), { message: "malformed known content block" }),
113
+ })
114
+ .loose();
115
+ }
106
116
 
107
117
  // ─── System ────────────────────────────────────────────────────────────────
108
118
 
@@ -118,7 +128,7 @@ export const systemSchema = z.union([z.string(), z.array(systemBlockSchema)]).op
118
128
 
119
129
  const userContentBlockSchema = z.union([
120
130
  z.discriminatedUnion("type", [textBlockSchema, imageBlockSchema, toolResultBlockSchema]),
121
- unknownContentBlockSchema,
131
+ unknownContentBlockSchema(["text", "image", "tool_result"]),
122
132
  ]);
123
133
 
124
134
  const assistantContentBlockSchema = z.union([
@@ -128,7 +138,7 @@ const assistantContentBlockSchema = z.union([
128
138
  redactedThinkingBlockSchema,
129
139
  toolUseBlockSchema,
130
140
  ]),
131
- unknownContentBlockSchema,
141
+ unknownContentBlockSchema(["text", "thinking", "redacted_thinking", "tool_use"]),
132
142
  ]);
133
143
 
134
144
  export const userMessageSchema = z.object({