@prometheus-ai/ai 0.5.3 → 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
@@ -23,6 +23,7 @@ import * as fs from "node:fs";
23
23
  import * as os from "node:os";
24
24
  import * as path from "node:path";
25
25
  import { $env, isEnoent, logger } from "@prometheus-ai/utils";
26
+ import { raceWithSignal } from "../utils/abort";
26
27
  import type { AwsCredentials } from "./aws-sigv4";
27
28
 
28
29
  export interface ResolvedCredentials extends AwsCredentials {
@@ -39,6 +40,17 @@ export interface CredentialResolveOptions {
39
40
  }
40
41
 
41
42
  const REFRESH_SKEW_MS = 60_000;
43
+ /**
44
+ * TTL for file-sourced credentials that carry a session token but no expiry.
45
+ * Tools like aws-vault/saml2aws rewrite ~/.aws/credentials with short-lived STS
46
+ * session keys; caching them forever serves stale creds after rotation.
47
+ */
48
+ const FILE_SESSION_CREDS_TTL_MS = 5 * 60_000;
49
+ /**
50
+ * Bound for the detached (signal-free) shared resolution: a hung
51
+ * credential_process/SSO/IMDS fetch must not pin the inflight slot forever.
52
+ */
53
+ const SHARED_RESOLVE_TIMEOUT_MS = 30_000;
42
54
 
43
55
  interface CacheEntry {
44
56
  creds: ResolvedCredentials;
@@ -46,6 +58,7 @@ interface CacheEntry {
46
58
  }
47
59
 
48
60
  const cache: Map<string, CacheEntry> = new Map();
61
+ const inflight: Map<string, Promise<ResolvedCredentials>> = new Map();
49
62
 
50
63
  export async function resolveAwsCredentials(opts: CredentialResolveOptions = {}): Promise<ResolvedCredentials> {
51
64
  const profile = opts.profile || $env.AWS_PROFILE || "default";
@@ -55,9 +68,24 @@ export async function resolveAwsCredentials(opts: CredentialResolveOptions = {})
55
68
  const hit = cache.get(cacheKey);
56
69
  if (hit && hit.expiresAt - REFRESH_SKEW_MS > Date.now()) return hit.creds;
57
70
 
58
- const creds = await resolveFresh(profile, region, opts.signal);
59
- cache.set(cacheKey, { creds, expiresAt: creds.expiresAt ?? Number.POSITIVE_INFINITY });
60
- return creds;
71
+ // Single-flight: N concurrent cold calls must not each spawn credential_process/SSO/IMDS fetches.
72
+ // The shared resolution is deliberately detached from any caller's signal — aborting one
73
+ // request must not fail every waiter — and bounded by its own timeout instead; each caller
74
+ // races its own signal against the shared promise.
75
+ const existing = inflight.get(cacheKey);
76
+ if (existing) return raceWithSignal(existing, opts.signal);
77
+
78
+ const promise = (async () => {
79
+ try {
80
+ const creds = await resolveFresh(profile, region, AbortSignal.timeout(SHARED_RESOLVE_TIMEOUT_MS));
81
+ cache.set(cacheKey, { creds, expiresAt: creds.expiresAt ?? Number.POSITIVE_INFINITY });
82
+ return creds;
83
+ } finally {
84
+ inflight.delete(cacheKey);
85
+ }
86
+ })();
87
+ inflight.set(cacheKey, promise);
88
+ return raceWithSignal(promise, opts.signal);
61
89
  }
62
90
 
63
91
  async function resolveFresh(profile: string, region: string, signal?: AbortSignal): Promise<ResolvedCredentials> {
@@ -157,7 +185,12 @@ async function readProfileCredentials(
157
185
  accessKeyId: merged.aws_access_key_id,
158
186
  secretAccessKey: merged.aws_secret_access_key,
159
187
  };
160
- if (merged.aws_session_token) out.sessionToken = merged.aws_session_token;
188
+ if (merged.aws_session_token) {
189
+ out.sessionToken = merged.aws_session_token;
190
+ // Session-token creds in the credentials file are short-lived STS keys that
191
+ // external tools rotate in place; cap the cache so rotations are picked up.
192
+ out.expiresAt = Date.now() + FILE_SESSION_CREDS_TTL_MS;
193
+ }
161
194
  return out;
162
195
  }
163
196
 
@@ -302,7 +335,6 @@ async function readCredentialProcess(
302
335
  signal: AbortSignal | undefined,
303
336
  ): Promise<ResolvedCredentials> {
304
337
  const argv = buildCredentialProcessArgv(profile, command);
305
-
306
338
  const child = Bun.spawn(argv, {
307
339
  stdin: "ignore",
308
340
  stdout: "pipe",
@@ -499,3 +531,13 @@ async function readImdsCredentials(parentSignal: AbortSignal | undefined): Promi
499
531
  export function clearAwsCredentialCache(): void {
500
532
  cache.clear();
501
533
  }
534
+
535
+ /**
536
+ * Drop the cache entry for one profile/region. Called by the Bedrock provider on
537
+ * 401/403 responses so stale credentials are re-resolved instead of served until restart.
538
+ */
539
+ export function invalidateAwsCredentialCache(opts: { profile?: string; region?: string } = {}): void {
540
+ const profile = opts.profile || $env.AWS_PROFILE || "default";
541
+ const region = opts.region || $env.AWS_REGION || $env.AWS_DEFAULT_REGION || "us-east-1";
542
+ cache.delete(`${profile}\x00${region}`);
543
+ }
@@ -161,6 +161,7 @@ export async function* decodeEventStream(source: ReadableStream<Uint8Array>): As
161
161
  // Single growable buffer; we slide a read cursor along it and compact when a
162
162
  // complete prefix has been consumed. Avoids per-message Uint8Array copies.
163
163
  let buf: Uint8Array<ArrayBufferLike> = new Uint8Array(0);
164
+ let completed = false;
164
165
  try {
165
166
  while (true) {
166
167
  const { value, done } = await reader.read();
@@ -179,7 +180,11 @@ export async function* decodeEventStream(source: ReadableStream<Uint8Array>): As
179
180
  if (done) break;
180
181
  }
181
182
  if (buf.length > 0) throw new Error("eventstream: truncated message at end of stream");
183
+ completed = true;
182
184
  } finally {
185
+ // On abnormal exit (consumer threw/broke, decode error) cancel the body so the
186
+ // HTTP connection is released instead of draining until GC.
187
+ if (!completed) await reader.cancel().catch(() => {});
183
188
  reader.releaseLock();
184
189
  }
185
190
  }
@@ -1,16 +1,10 @@
1
1
  import { $env, extractHttpStatusFromError } from "@prometheus-ai/utils";
2
- import { AzureOpenAI, APIConnectionTimeoutError as OpenAIConnectionTimeoutError } from "openai";
3
- import type {
4
- Tool as OpenAITool,
5
- ResponseCreateParamsStreaming,
6
- ResponseInput,
7
- ResponseStreamEvent,
8
- } from "openai/resources/responses/responses";
9
2
  import { getEnvApiKey } from "../stream";
10
3
  import type {
11
4
  AssistantMessage,
12
5
  Context,
13
6
  Model,
7
+ RawSseEvent,
14
8
  ServiceTier,
15
9
  StreamFunction,
16
10
  StreamOptions,
@@ -26,10 +20,10 @@ import {
26
20
  getOpenAIStreamIdleTimeoutMs,
27
21
  iterateWithIdleTimeout,
28
22
  } from "../utils/idle-iterator";
23
+ import { postOpenAIStream } from "../utils/openai-http";
29
24
  import { sanitizeSchemaForOpenAIResponses, toolWireSchema } from "../utils/schema";
30
- import { wrapFetchForSseDebug } from "../utils/sse-debug";
31
25
  import { mapToOpenAIResponsesToolChoice } from "../utils/tool-choice";
32
- import { normalizeOpenAIResponsesPromptCacheKey, supportsDeveloperRole } from "./openai-responses";
26
+ import { getOpenAIResponsesCacheSessionId } from "./openai-responses";
33
27
  import {
34
28
  appendResponsesToolResultMessages,
35
29
  applyCommonResponsesSamplingParams,
@@ -40,14 +34,21 @@ import {
40
34
  isOpenAIResponsesProgressEvent,
41
35
  normalizeResponsesToolCallIdForTransform,
42
36
  processResponsesStream,
37
+ repairOrphanResponsesToolCalls,
43
38
  } from "./openai-responses-shared";
39
+ import type {
40
+ Tool as OpenAITool,
41
+ ResponseCreateParamsStreaming,
42
+ ResponseInput,
43
+ ResponseStreamEvent,
44
+ } from "./openai-responses-wire";
44
45
  import { transformMessages } from "./transform-messages";
45
46
 
46
47
  const DEFAULT_AZURE_API_VERSION = "v1";
47
48
  const AZURE_OPENAI_RESPONSES_FIRST_EVENT_TIMEOUT_MESSAGE =
48
49
  "Azure OpenAI responses stream timed out while waiting for the first event";
49
50
 
50
- function parseDeploymentNameMap(value: string | undefined): Map<string, string> {
51
+ export function parseAzureDeploymentNameMap(value: string | undefined): Map<string, string> {
51
52
  const map = new Map<string, string>();
52
53
  if (!value) return map;
53
54
  for (const entry of value.split(",")) {
@@ -64,7 +65,7 @@ function resolveDeploymentName(model: Model<"azure-openai-responses">, options?:
64
65
  if (options?.azureDeploymentName) {
65
66
  return options.azureDeploymentName;
66
67
  }
67
- const mappedDeployment = parseDeploymentNameMap($env.AZURE_OPENAI_DEPLOYMENT_NAME_MAP).get(model.id);
68
+ const mappedDeployment = parseAzureDeploymentNameMap($env.AZURE_OPENAI_DEPLOYMENT_NAME_MAP).get(model.id);
68
69
  return mappedDeployment ?? model.id;
69
70
  }
70
71
 
@@ -113,13 +114,32 @@ export const streamAzureOpenAIResponses: StreamFunction<"azure-openai-responses"
113
114
  const abortTracker = createAbortSourceTracker(options?.signal);
114
115
  const firstEventTimeoutAbortError = new Error(AZURE_OPENAI_RESPONSES_FIRST_EVENT_TIMEOUT_MESSAGE);
115
116
  const { requestAbortController, requestSignal } = abortTracker;
117
+ const onSseEvent = options?.onSseEvent;
118
+ const rawSseObserver = onSseEvent
119
+ ? (event: RawSseEvent) => {
120
+ if (!event.event && event.data && event.data !== "[DONE]") {
121
+ try {
122
+ const parsed = JSON.parse(event.data);
123
+ const resolvedEvent =
124
+ typeof parsed.type === "string"
125
+ ? parsed.type
126
+ : typeof parsed.object === "string"
127
+ ? parsed.object
128
+ : null;
129
+ if (resolvedEvent) {
130
+ event.event = resolvedEvent;
131
+ event.raw = [`event: ${resolvedEvent}`, ...event.raw];
132
+ }
133
+ } catch {}
134
+ }
135
+ onSseEvent(event, model);
136
+ }
137
+ : undefined;
116
138
 
117
139
  try {
118
- // Create Azure OpenAI client
119
140
  const apiKey = options?.apiKey || getEnvApiKey(model.provider) || "";
120
- const client = createClient(model, apiKey, options);
121
- const { baseUrl } = resolveAzureConfig(model, options);
122
- const params = buildParams(model, context, options, deploymentName, baseUrl);
141
+ const { url, headers } = buildAzureResponsesRequest(model, apiKey, options);
142
+ const params = buildParams(model, context, options, deploymentName);
123
143
  options?.onPayload?.(params);
124
144
  const idleTimeoutMs = options?.streamIdleTimeoutMs ?? getOpenAIStreamIdleTimeoutMs();
125
145
  const firstEventTimeoutMs =
@@ -131,7 +151,7 @@ export const streamAzureOpenAIResponses: StreamFunction<"azure-openai-responses"
131
151
  api: output.api,
132
152
  model: model.id,
133
153
  method: "POST",
134
- url: `${baseUrl}/responses`,
154
+ url,
135
155
  body: params,
136
156
  };
137
157
  let requestTimeout: NodeJS.Timeout | undefined;
@@ -140,41 +160,45 @@ export const streamAzureOpenAIResponses: StreamFunction<"azure-openai-responses"
140
160
  }
141
161
  let openaiStream: AsyncIterable<ResponseStreamEvent>;
142
162
  try {
143
- const requestOptions =
144
- requestTimeoutMs === undefined
145
- ? { signal: requestSignal }
146
- : { signal: requestSignal, timeout: requestTimeoutMs };
147
- openaiStream = await client.responses.create(params, requestOptions);
148
- } catch (error) {
149
- if (error instanceof OpenAIConnectionTimeoutError && !abortTracker.wasCallerAbort()) {
150
- throw firstEventTimeoutAbortError;
163
+ const headersWithTimeout = { ...headers };
164
+ if (requestTimeoutMs !== undefined) {
165
+ headersWithTimeout["X-Stainless-Timeout"] = Math.floor(requestTimeoutMs / 1000).toString();
151
166
  }
152
- throw error;
167
+ const handle = await postOpenAIStream<ResponseStreamEvent>({
168
+ url,
169
+ headers: headersWithTimeout,
170
+ body: params,
171
+ signal: requestSignal,
172
+ fetch: options?.fetch,
173
+ // Watchdog armed → no retries, so they cannot silently extend the deadline.
174
+ maxAttempts: requestTimeoutMs !== undefined ? 1 : undefined,
175
+ onSseEvent: rawSseObserver,
176
+ });
177
+ openaiStream = handle.events;
153
178
  } finally {
154
179
  if (requestTimeout !== undefined) clearTimeout(requestTimeout);
155
180
  }
156
181
  stream.push({ type: "start", partial: output });
157
182
 
158
- await processResponsesStream(
159
- iterateWithIdleTimeout(openaiStream, {
160
- idleTimeoutMs,
161
- firstItemTimeoutMs: firstEventTimeoutMs,
162
- firstItemErrorMessage: AZURE_OPENAI_RESPONSES_FIRST_EVENT_TIMEOUT_MESSAGE,
163
- errorMessage: "Azure OpenAI responses stream stalled while waiting for the next event",
164
- onIdle: () => requestAbortController.abort(),
165
- onFirstItemTimeout: () => abortTracker.abortLocally(firstEventTimeoutAbortError),
166
- abortSignal: options?.signal,
167
- isProgressItem: isOpenAIResponsesProgressEvent,
168
- }),
169
- output,
170
- stream,
171
- model,
172
- {
173
- onFirstToken: () => {
174
- if (!firstTokenTime) firstTokenTime = Date.now();
175
- },
183
+ const timedOpenaiStream = iterateWithIdleTimeout(openaiStream, {
184
+ idleTimeoutMs,
185
+ firstItemTimeoutMs: firstEventTimeoutMs,
186
+ firstItemErrorMessage: AZURE_OPENAI_RESPONSES_FIRST_EVENT_TIMEOUT_MESSAGE,
187
+ errorMessage: "Azure OpenAI responses stream stalled while waiting for the next event",
188
+ onIdle: () => requestAbortController.abort(),
189
+ onFirstItemTimeout: () => abortTracker.abortLocally(firstEventTimeoutAbortError),
190
+ abortSignal: options?.signal,
191
+ isProgressItem: isOpenAIResponsesProgressEvent,
192
+ });
193
+ let sawCompleted = false;
194
+ await processResponsesStream(timedOpenaiStream, output, stream, model, {
195
+ onFirstToken: () => {
196
+ if (!firstTokenTime) firstTokenTime = Date.now();
176
197
  },
177
- );
198
+ onCompleted: () => {
199
+ sawCompleted = true;
200
+ },
201
+ });
178
202
 
179
203
  const firstEventTimeoutError = abortTracker.getLocalAbortReason();
180
204
  if (firstEventTimeoutError) {
@@ -185,6 +209,10 @@ export const streamAzureOpenAIResponses: StreamFunction<"azure-openai-responses"
185
209
  throw new Error("Request was aborted");
186
210
  }
187
211
 
212
+ if (!sawCompleted) {
213
+ throw new Error("Azure OpenAI responses stream closed before response.completed was received");
214
+ }
215
+
188
216
  if (output.stopReason === "aborted" || output.stopReason === "error") {
189
217
  throw new Error(output.errorMessage ?? "An unknown error occurred");
190
218
  }
@@ -248,7 +276,20 @@ function resolveAzureConfig(
248
276
  };
249
277
  }
250
278
 
251
- function createClient(model: Model<"azure-openai-responses">, apiKey: string, options?: AzureOpenAIResponsesOptions) {
279
+ /**
280
+ * Replicates the `AzureOpenAI` SDK client's request shape for `/responses`:
281
+ * a string api key becomes a single `api-key` header (azure.mjs `authHeaders`;
282
+ * never `Authorization: Bearer`), `api-version` rides as a query parameter
283
+ * (azure.mjs constructor `defaultQuery`), and `/responses` is not a
284
+ * deployment-scoped path, so no `/deployments/{model}` URL rewriting applies.
285
+ * Custom model/options headers may override the auth header, matching the SDK's
286
+ * `buildHeaders` precedence.
287
+ */
288
+ function buildAzureResponsesRequest(
289
+ model: Model<"azure-openai-responses">,
290
+ apiKey: string,
291
+ options?: AzureOpenAIResponsesOptions,
292
+ ): { url: string; headers: Record<string, string> } {
252
293
  if (!apiKey) {
253
294
  const envKey = $env.AZURE_OPENAI_API_KEY;
254
295
  if (!envKey) {
@@ -259,25 +300,17 @@ function createClient(model: Model<"azure-openai-responses">, apiKey: string, op
259
300
  apiKey = envKey;
260
301
  }
261
302
 
262
- const headers = { ...(model.headers ?? {}) };
263
-
303
+ const headers: Record<string, string> = { "api-key": apiKey, ...(model.headers ?? {}) };
264
304
  if (options?.headers) {
265
305
  Object.assign(headers, options.headers);
266
306
  }
267
307
 
268
308
  const { baseUrl, apiVersion } = resolveAzureConfig(model, options);
269
309
 
270
- const baseFetch = options?.fetch ?? fetch;
271
- const onSseEvent = options?.onSseEvent;
272
- return new AzureOpenAI({
273
- apiKey,
274
- apiVersion,
275
- dangerouslyAllowBrowser: true,
276
- maxRetries: 5,
277
- defaultHeaders: headers,
278
- baseURL: baseUrl,
279
- fetch: onSseEvent ? wrapFetchForSseDebug(baseFetch, event => onSseEvent(event, model)) : baseFetch,
280
- });
310
+ return {
311
+ url: `${baseUrl}/responses?api-version=${encodeURIComponent(apiVersion)}`,
312
+ headers,
313
+ };
281
314
  }
282
315
 
283
316
  function buildParams(
@@ -285,15 +318,17 @@ function buildParams(
285
318
  context: Context,
286
319
  options: AzureOpenAIResponsesOptions | undefined,
287
320
  deploymentName: string,
288
- resolvedBaseUrl?: string,
289
321
  ) {
290
- const messages = convertMessages(model, context, true, resolvedBaseUrl);
322
+ const messages = convertMessages(model, context, true);
291
323
 
292
324
  const params: AzureOpenAIResponsesSamplingParams = {
293
325
  model: deploymentName,
294
326
  input: messages,
295
327
  stream: true,
296
- prompt_cache_key: normalizeOpenAIResponsesPromptCacheKey(options?.promptCacheKey ?? options?.sessionId),
328
+ prompt_cache_key: getOpenAIResponsesCacheSessionId(options),
329
+ // Encrypted reasoning replay (applyResponsesReasoningParams) requires
330
+ // stateless responses, matching the openai provider.
331
+ store: false,
297
332
  };
298
333
 
299
334
  applyCommonResponsesSamplingParams(params, options, model);
@@ -301,7 +336,15 @@ function buildParams(
301
336
  if (context.tools) {
302
337
  params.tools = convertTools(context.tools);
303
338
  if (options?.toolChoice) {
304
- params.tool_choice = mapToOpenAIResponsesToolChoice(options.toolChoice);
339
+ const toolChoice = mapToOpenAIResponsesToolChoice(options.toolChoice);
340
+ if (
341
+ toolChoice &&
342
+ (typeof toolChoice === "string" ||
343
+ toolChoice.type !== "function" ||
344
+ context.tools.some(tool => tool.name === toolChoice.name))
345
+ ) {
346
+ params.tool_choice = toolChoice;
347
+ }
305
348
  }
306
349
  }
307
350
 
@@ -314,15 +357,15 @@ function convertMessages(
314
357
  model: Model<"azure-openai-responses">,
315
358
  context: Context,
316
359
  strictResponsesPairing: boolean,
317
- resolvedBaseUrl?: string,
318
360
  ): ResponseInput {
319
361
  const messages: ResponseInput = [];
320
362
  const transformedMessages = transformMessages(context.messages, model, normalizeResponsesToolCallIdForTransform);
321
363
  const knownCallIds = new Set<string>();
364
+ const customCallIds = new Set<string>();
322
365
 
323
366
  const systemPrompts = normalizeSystemPrompts(context.systemPrompt);
324
367
  if (systemPrompts.length > 0) {
325
- const role = model.reasoning && supportsDeveloperRole(resolvedBaseUrl ?? model) ? "developer" : "system";
368
+ const role = model.reasoning && model.compat.supportsDeveloperRole ? "developer" : "system";
326
369
  for (const systemPrompt of systemPrompts) {
327
370
  messages.push({ role, content: systemPrompt });
328
371
  }
@@ -338,16 +381,23 @@ function convertMessages(
338
381
  content: msg.role === "developer" && typeof msg.content === "string" ? msg.content.toWellFormed() : content,
339
382
  });
340
383
  } else if (msg.role === "assistant") {
341
- const outputItems = convertResponsesAssistantMessage(msg as AssistantMessage, model, msgIndex, knownCallIds);
384
+ const outputItems = convertResponsesAssistantMessage(
385
+ msg as AssistantMessage,
386
+ model,
387
+ msgIndex,
388
+ knownCallIds,
389
+ true,
390
+ customCallIds,
391
+ );
342
392
  if (outputItems.length === 0) continue;
343
393
  messages.push(...outputItems);
344
394
  } else if (msg.role === "toolResult") {
345
- appendResponsesToolResultMessages(messages, msg, model, strictResponsesPairing, knownCallIds);
395
+ appendResponsesToolResultMessages(messages, msg, model, strictResponsesPairing, knownCallIds, customCallIds);
346
396
  }
347
397
  msgIndex++;
348
398
  }
349
399
 
350
- return messages;
400
+ return repairOrphanResponsesToolCalls(messages);
351
401
  }
352
402
 
353
403
  function convertTools(tools: Tool[]): OpenAITool[] {
@@ -3,35 +3,7 @@ import * as fs from "node:fs/promises";
3
3
  import http2 from "node:http2";
4
4
  import { create, fromBinary, fromJson, type JsonValue, toBinary, toJson } from "@bufbuild/protobuf";
5
5
  import { ValueSchema } from "@bufbuild/protobuf/wkt";
6
- import { $env, extractHttpStatusFromError, sanitizeText } from "@prometheus-ai/utils";
7
- import { calculateCost } from "../models";
8
- import type {
9
- Api,
10
- AssistantMessage,
11
- Context,
12
- CursorExecHandlerResult,
13
- CursorExecHandlers,
14
- CursorMcpCall,
15
- CursorShellStreamCallbacks,
16
- CursorToolResultHandler,
17
- ImageContent,
18
- Message,
19
- Model,
20
- StreamFunction,
21
- StreamOptions,
22
- TextContent,
23
- ThinkingContent,
24
- Tool,
25
- ToolCall,
26
- ToolResultMessage,
27
- } from "../types";
28
- import { normalizeSystemPrompts } from "../utils";
29
- import { AssistantMessageEventStream } from "../utils/event-stream";
30
- import { parseStreamingJson } from "../utils/json-parse";
31
- import { createRequestDebugSession, isRequestDebugEnabled, type RequestDebugResponseLog } from "../utils/request-debug";
32
- import { formatErrorMessageWithRetryAfter } from "../utils/retry-after";
33
- import { toolWireSchema } from "../utils/schema/wire";
34
- import type { McpToolDefinition } from "./cursor/gen/agent_pb";
6
+ import type { McpToolDefinition } from "@prometheus-ai/catalog/discovery/cursor-gen/agent_pb";
35
7
  import {
36
8
  AgentClientMessageSchema,
37
9
  AgentConversationTurnStructureSchema,
@@ -128,7 +100,35 @@ import {
128
100
  WriteShellStdinErrorSchema,
129
101
  WriteShellStdinResultSchema,
130
102
  WriteSuccessSchema,
131
- } from "./cursor/gen/agent_pb";
103
+ } from "@prometheus-ai/catalog/discovery/cursor-gen/agent_pb";
104
+ import { calculateCost } from "@prometheus-ai/catalog/models";
105
+ import { $env, extractHttpStatusFromError, sanitizeText } from "@prometheus-ai/utils";
106
+ import type {
107
+ Api,
108
+ AssistantMessage,
109
+ Context,
110
+ CursorExecHandlerResult,
111
+ CursorExecHandlers,
112
+ CursorMcpCall,
113
+ CursorShellStreamCallbacks,
114
+ CursorToolResultHandler,
115
+ ImageContent,
116
+ Message,
117
+ Model,
118
+ StreamFunction,
119
+ StreamOptions,
120
+ TextContent,
121
+ ThinkingContent,
122
+ Tool,
123
+ ToolCall,
124
+ ToolResultMessage,
125
+ } from "../types";
126
+ import { normalizeSystemPrompts } from "../utils";
127
+ import { AssistantMessageEventStream } from "../utils/event-stream";
128
+ import { parseStreamingJson } from "../utils/json-parse";
129
+ import { createRequestDebugSession, isRequestDebugEnabled, type RequestDebugResponseLog } from "../utils/request-debug";
130
+ import { formatErrorMessageWithRetryAfter } from "../utils/retry-after";
131
+ import { toolWireSchema } from "../utils/schema/wire";
132
132
 
133
133
  export const CURSOR_API_URL = "https://api2.cursor.sh";
134
134
  export const CURSOR_CLIENT_VERSION = "cli-2026.01.09-231024f";
@@ -1,5 +1,5 @@
1
+ import { getGitHubCopilotBaseUrl, parseGitHubCopilotApiKey } from "@prometheus-ai/catalog/wire/github-copilot";
1
2
  import type { Message } from "../types";
2
- import { getGitHubCopilotBaseUrl, parseGitHubCopilotApiKey } from "../utils/oauth/github-copilot";
3
3
  /**
4
4
  * Infer whether the current request to Copilot is user-initiated or agent-initiated.
5
5
  * Accepts `unknown[]` because providers may pass pre-converted message shapes.
@@ -1,5 +1,6 @@
1
+ import { buildModel } from "@prometheus-ai/catalog/build";
1
2
  import { ANTHROPIC_THINKING, mapAnthropicToolChoice } from "../stream";
2
- import type { Api, Context, FetchImpl, Model, SimpleStreamOptions } from "../types";
3
+ import type { Api, Context, FetchImpl, Model, ModelSpec, SimpleStreamOptions } from "../types";
3
4
  import { AssistantMessageEventStream } from "../utils/event-stream";
4
5
  import { createProviderErrorMessage } from "./error-message";
5
6
  import type { OpenAICompletionsOptions } from "./openai-completions";
@@ -145,23 +146,25 @@ export function getModelMapping(modelId: string): GitLabModelMapping | undefined
145
146
  }
146
147
 
147
148
  export function getGitLabDuoModels(): Model<Api>[] {
148
- return Object.entries(MODEL_MAPPINGS).map(([id, mapping]) => ({
149
- id,
150
- name: mapping.name,
151
- api:
152
- mapping.provider === "anthropic"
153
- ? "anthropic-messages"
154
- : mapping.openaiApiType === "responses"
155
- ? "openai-responses"
156
- : "openai-completions",
157
- provider: "gitlab-duo",
158
- baseUrl: mapping.provider === "anthropic" ? ANTHROPIC_PROXY_URL : OPENAI_PROXY_URL,
159
- reasoning: mapping.reasoning,
160
- input: [...mapping.input],
161
- cost: { ...mapping.cost },
162
- contextWindow: mapping.contextWindow,
163
- maxTokens: mapping.maxTokens,
164
- }));
149
+ return Object.entries(MODEL_MAPPINGS).map(([id, mapping]) =>
150
+ buildModel({
151
+ id,
152
+ name: mapping.name,
153
+ api:
154
+ mapping.provider === "anthropic"
155
+ ? "anthropic-messages"
156
+ : mapping.openaiApiType === "responses"
157
+ ? "openai-responses"
158
+ : "openai-completions",
159
+ provider: "gitlab-duo",
160
+ baseUrl: mapping.provider === "anthropic" ? ANTHROPIC_PROXY_URL : OPENAI_PROXY_URL,
161
+ reasoning: mapping.reasoning,
162
+ input: [...mapping.input],
163
+ cost: { ...mapping.cost },
164
+ contextWindow: mapping.contextWindow,
165
+ maxTokens: mapping.maxTokens,
166
+ } as ModelSpec<Api>),
167
+ );
165
168
  }
166
169
 
167
170
  interface DirectAccessToken {
@@ -234,7 +237,8 @@ export function streamGitLabDuo(
234
237
 
235
238
  (async () => {
236
239
  try {
237
- if (!options?.apiKey) {
240
+ const apiKey = typeof options?.apiKey === "string" ? options.apiKey : undefined;
241
+ if (!apiKey || !options) {
238
242
  throw new Error("Missing GitLab access token. Run /login gitlab-duo or set GITLAB_TOKEN.");
239
243
  }
240
244
 
@@ -243,7 +247,7 @@ export function streamGitLabDuo(
243
247
  throw new Error(`Unsupported GitLab Duo model: ${model.id}`);
244
248
  }
245
249
 
246
- const directAccess = await getDirectAccessToken(options.apiKey, options.fetch);
250
+ const directAccess = await getDirectAccessToken(apiKey, options.fetch);
247
251
  const headers = {
248
252
  ...directAccess.headers,
249
253
  ...options.headers,
@@ -254,12 +258,13 @@ export function streamGitLabDuo(
254
258
  const inner =
255
259
  mapping.provider === "anthropic"
256
260
  ? streamAnthropic(
257
- {
261
+ buildModel({
258
262
  ...model,
259
263
  id: mapping.model,
260
264
  api: "anthropic-messages",
261
265
  baseUrl: ANTHROPIC_PROXY_URL,
262
- } as Model<"anthropic-messages">,
266
+ compat: model.compatConfig,
267
+ } as ModelSpec<"anthropic-messages">),
263
268
  context,
264
269
  {
265
270
  apiKey: directAccess.token,
@@ -270,7 +275,7 @@ export function streamGitLabDuo(
270
275
  minP: options.minP,
271
276
  presencePenalty: options.presencePenalty,
272
277
  repetitionPenalty: options.repetitionPenalty,
273
- maxTokens: options.maxTokens ?? model.maxTokens,
278
+ maxTokens: options.maxTokens ?? model.maxTokens ?? undefined,
274
279
  signal: options.signal,
275
280
  cacheRetention: options.cacheRetention,
276
281
  headers,
@@ -292,12 +297,13 @@ export function streamGitLabDuo(
292
297
  )
293
298
  : mapping.openaiApiType === "responses"
294
299
  ? streamOpenAIResponses(
295
- {
300
+ buildModel({
296
301
  ...model,
297
302
  id: mapping.model,
298
303
  api: "openai-responses",
299
304
  baseUrl: OPENAI_PROXY_URL,
300
- } as Model<"openai-responses">,
305
+ compat: model.compatConfig,
306
+ } as ModelSpec<"openai-responses">),
301
307
  context,
302
308
  {
303
309
  apiKey: directAccess.token,
@@ -307,7 +313,7 @@ export function streamGitLabDuo(
307
313
  minP: options.minP,
308
314
  presencePenalty: options.presencePenalty,
309
315
  repetitionPenalty: options.repetitionPenalty,
310
- maxTokens: options.maxTokens ?? model.maxTokens,
316
+ maxTokens: options.maxTokens ?? model.maxTokens ?? undefined,
311
317
  signal: options.signal,
312
318
  cacheRetention: options.cacheRetention,
313
319
  headers,
@@ -324,12 +330,13 @@ export function streamGitLabDuo(
324
330
  } satisfies OpenAIResponsesOptions,
325
331
  )
326
332
  : streamOpenAICompletions(
327
- {
333
+ buildModel({
328
334
  ...model,
329
335
  id: mapping.model,
330
336
  api: "openai-completions",
331
337
  baseUrl: OPENAI_PROXY_URL,
332
- } as Model<"openai-completions">,
338
+ compat: model.compatConfig,
339
+ } as ModelSpec<"openai-completions">),
333
340
  context,
334
341
  {
335
342
  apiKey: directAccess.token,
@@ -339,7 +346,7 @@ export function streamGitLabDuo(
339
346
  minP: options.minP,
340
347
  presencePenalty: options.presencePenalty,
341
348
  repetitionPenalty: options.repetitionPenalty,
342
- maxTokens: options.maxTokens ?? model.maxTokens,
349
+ maxTokens: options.maxTokens ?? model.maxTokens ?? undefined,
343
350
  signal: options.signal,
344
351
  cacheRetention: options.cacheRetention,
345
352
  headers,