@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
@@ -1,5 +1,7 @@
1
- import { getAntigravityUserAgent } from "../providers/google-gemini-headers";
1
+ import { getAntigravityUserAgent } from "@prometheus-ai/catalog/wire/gemini-headers";
2
2
  import type {
3
+ CredentialRankingContext,
4
+ CredentialRankingStrategy,
3
5
  UsageAmount,
4
6
  UsageFetchContext,
5
7
  UsageFetchParams,
@@ -18,6 +20,8 @@ interface AntigravityQuotaInfo {
18
20
  tier?: string;
19
21
  windowId?: string;
20
22
  windowLabel?: string;
23
+ apiProvider?: string;
24
+ modelProvider?: string;
21
25
  }
22
26
 
23
27
  interface AntigravityModelInfo {
@@ -25,6 +29,8 @@ interface AntigravityModelInfo {
25
29
  quotaInfo?: AntigravityQuotaInfo | AntigravityQuotaInfo[];
26
30
  quotaInfos?: AntigravityQuotaInfo[];
27
31
  quotaInfoByTier?: Record<string, AntigravityQuotaInfo | AntigravityQuotaInfo[]>;
32
+ apiProvider?: string;
33
+ modelProvider?: string;
28
34
  }
29
35
 
30
36
  interface AntigravityUsageResponse {
@@ -60,22 +66,47 @@ function parseWindow(info: AntigravityQuotaInfo): UsageWindow | undefined {
60
66
  }
61
67
 
62
68
  function buildAmount(info: AntigravityQuotaInfo): UsageAmount {
63
- const remainingFraction = clampFraction(info.remainingFraction);
69
+ const apiRemainingFraction = clampFraction(info.remainingFraction);
70
+ // Observed Antigravity responses omit remainingFraction for exhausted
71
+ // Google/Gemini counters and keep only resetTime. Treat that shape as
72
+ // "blocked until reset" rather than unknown so a healthy sibling backend
73
+ // counter cannot mask it during dedupe.
74
+ const remainingFraction = apiRemainingFraction ?? (info.resetTime ? 0 : undefined);
64
75
  const amount: UsageAmount = { unit: "percent" };
65
76
  if (remainingFraction === undefined) return amount;
66
- const usedFraction = clampFraction(1 - remainingFraction);
77
+ const usedFraction = 1 - remainingFraction;
67
78
  amount.remainingFraction = remainingFraction;
68
79
  amount.usedFraction = usedFraction;
69
80
  amount.remaining = remainingFraction * 100;
70
- amount.used = usedFraction !== undefined ? usedFraction * 100 : undefined;
81
+ amount.used = usedFraction * 100;
71
82
  amount.limit = 100;
72
83
  return amount;
73
84
  }
74
85
 
86
+ function formatCounterName(info: AntigravityQuotaInfo): string | undefined {
87
+ switch (info.modelProvider ?? info.apiProvider) {
88
+ case "MODEL_PROVIDER_ANTHROPIC":
89
+ case "API_PROVIDER_ANTHROPIC_VERTEX":
90
+ return "Anthropic";
91
+ case "MODEL_PROVIDER_GOOGLE":
92
+ case "API_PROVIDER_GOOGLE_GEMINI":
93
+ return "Google";
94
+ case "MODEL_PROVIDER_OPENAI":
95
+ case "API_PROVIDER_OPENAI_VERTEX":
96
+ return "OpenAI";
97
+ default:
98
+ return undefined;
99
+ }
100
+ }
101
+
75
102
  function normalizeQuotaInfos(info: AntigravityModelInfo): AntigravityQuotaInfo[] {
76
103
  const results: AntigravityQuotaInfo[] = [];
104
+ const source = {
105
+ ...(info.apiProvider ? { apiProvider: info.apiProvider } : {}),
106
+ ...(info.modelProvider ? { modelProvider: info.modelProvider } : {}),
107
+ };
77
108
  const addInfo = (value: AntigravityQuotaInfo, tier?: string) => {
78
- results.push({ ...value, ...(tier ? { tier } : {}) });
109
+ results.push({ ...source, ...value, ...(tier ? { tier } : {}) });
79
110
  };
80
111
  const addArray = (values?: AntigravityQuotaInfo[]) => {
81
112
  if (!values) return;
@@ -148,10 +179,26 @@ async function fetchAntigravityUsage(params: UsageFetchParams, ctx: UsageFetchCo
148
179
  }
149
180
 
150
181
  const data = (await response.json()) as AntigravityUsageResponse;
151
- const limits: UsageLimit[] = [];
182
+
183
+ // The API returns per-model quota entries, but quota is shared across
184
+ // models within the same backend counter, tier, and reset window. Keep
185
+ // Google and Anthropic-backed Antigravity models separate so a healthy
186
+ // Claude counter cannot mask an exhausted Gemini counter.
187
+ const deduped = new Map<
188
+ string,
189
+ {
190
+ amount: UsageAmount;
191
+ window: UsageWindow | undefined;
192
+ tier: string | undefined;
193
+ tierKey: string;
194
+ windowId: string;
195
+ counterName: string | undefined;
196
+ counterKey: string;
197
+ }
198
+ >();
152
199
  let earliestReset: number | undefined;
153
200
 
154
- for (const [modelId, modelInfo] of Object.entries(data.models ?? {})) {
201
+ for (const [_modelId, modelInfo] of Object.entries(data.models ?? {})) {
155
202
  const quotaInfos = normalizeQuotaInfos(modelInfo);
156
203
  for (const quotaInfo of quotaInfos) {
157
204
  const amount = buildAmount(quotaInfo);
@@ -159,35 +206,90 @@ async function fetchAntigravityUsage(params: UsageFetchParams, ctx: UsageFetchCo
159
206
  if (window?.resetsAt) {
160
207
  earliestReset = earliestReset ? Math.min(earliestReset, window.resetsAt) : window.resetsAt;
161
208
  }
162
- const labelBase = modelInfo.displayName || modelId;
163
- const label = quotaInfo.tier ? `${labelBase} (${quotaInfo.tier})` : labelBase;
164
- const windowId = window?.id ?? "default";
165
- limits.push({
166
- id: `${modelId}:${quotaInfo.tier ?? "default"}:${windowId}`,
167
- label,
168
- scope: {
169
- provider: params.provider,
170
- accountId: credential.accountId,
171
- projectId: credential.projectId,
172
- modelId,
173
- tier: quotaInfo.tier,
174
- windowId,
175
- },
176
- window,
177
- amount,
178
- status: getUsageStatus(amount.remainingFraction),
209
+ const tierKey = (quotaInfo.tier ?? "default").toLowerCase();
210
+ const counterName = formatCounterName(quotaInfo);
211
+ const counterKey = counterName?.toLowerCase() ?? "default";
212
+ // Use quotaInfo.windowId even when parseWindow returns undefined
213
+ // (no resetTime) — separate windows must not collapse to "default".
214
+ const windowId = quotaInfo.windowId ?? window?.id ?? "default";
215
+ const key = `${counterKey}|${tierKey}|${windowId}`;
216
+ const existing = deduped.get(key);
217
+ if (!existing) {
218
+ deduped.set(key, { amount, window, tier: quotaInfo.tier, tierKey, windowId, counterName, counterKey });
219
+ continue;
220
+ }
221
+ // Merge: keep the entry with fraction data for the bar, but
222
+ // also keep any window with a reset time so "resets in…" survives.
223
+ const eFrac = existing.amount.remainingFraction;
224
+ const cFrac = amount.remainingFraction;
225
+ const eHasFrac = eFrac !== undefined;
226
+ const cHasFrac = cFrac !== undefined;
227
+
228
+ let bestAmount = existing.amount;
229
+ let bestWindow = existing.window?.resetsAt ? existing.window : (window ?? existing.window);
230
+ let bestTier = existing.tier ?? quotaInfo.tier;
231
+
232
+ if (!eHasFrac && cHasFrac) {
233
+ bestAmount = amount;
234
+ bestTier = quotaInfo.tier ?? existing.tier;
235
+ } else if (eFrac !== undefined && cFrac !== undefined && cFrac < eFrac) {
236
+ bestAmount = amount;
237
+ bestTier = quotaInfo.tier ?? existing.tier;
238
+ }
239
+ // Always merge in window with reset time if the current
240
+ // best doesn't have one.
241
+ if (!bestWindow?.resetsAt && window?.resetsAt) {
242
+ bestWindow = window;
243
+ }
244
+ deduped.set(key, {
245
+ amount: bestAmount,
246
+ window: bestWindow,
247
+ tier: bestTier,
248
+ tierKey: existing.tierKey,
249
+ windowId: existing.windowId,
250
+ counterName: existing.counterName,
251
+ counterKey: existing.counterKey,
179
252
  });
180
253
  }
181
254
  }
182
255
 
256
+ const limits: UsageLimit[] = [];
257
+ for (const entry of deduped.values()) {
258
+ const label = entry.counterName ? `Usage (${entry.counterName})` : "Usage";
259
+ limits.push({
260
+ id: `${params.provider}:${entry.counterKey}:${entry.tierKey}:${entry.windowId}`,
261
+ label,
262
+ scope: {
263
+ provider: params.provider,
264
+ accountId: credential.accountId,
265
+ projectId: credential.projectId,
266
+ tier: entry.tier,
267
+ windowId: entry.windowId,
268
+ },
269
+ window: entry.window,
270
+ amount: entry.amount,
271
+ status: getUsageStatus(entry.amount.remainingFraction),
272
+ });
273
+ }
274
+
275
+ limits.sort((a, b) => {
276
+ const aFraction = a.amount.remainingFraction ?? 1;
277
+ const bFraction = b.amount.remainingFraction ?? 1;
278
+ return aFraction - bFraction;
279
+ });
280
+
281
+ const metadata: UsageReport["metadata"] = {
282
+ endpoint: url,
283
+ projectId: credential.projectId,
284
+ };
285
+ if (credential.email) metadata.email = credential.email;
286
+ if (credential.accountId) metadata.accountId = credential.accountId;
287
+
183
288
  const report: UsageReport = {
184
289
  provider: params.provider,
185
290
  fetchedAt: nowMs,
186
291
  limits,
187
- metadata: {
188
- endpoint: url,
189
- projectId: credential.projectId,
190
- },
292
+ metadata,
191
293
  raw: data,
192
294
  };
193
295
 
@@ -199,3 +301,69 @@ export const antigravityUsageProvider: UsageProvider = {
199
301
  fetchUsage: fetchAntigravityUsage,
200
302
  supports: params => params.provider === "google-antigravity",
201
303
  };
304
+
305
+ const ONE_DAY_MS = 24 * 60 * 60 * 1000;
306
+
307
+ function getAntigravityCounterKeyForModel(context: CredentialRankingContext | undefined): string | undefined {
308
+ const modelId = context?.modelId?.toLowerCase();
309
+ if (!modelId) return undefined;
310
+ if (modelId.startsWith("claude-")) return "anthropic";
311
+ if (modelId.startsWith("gemini-") || modelId.startsWith("gemma-")) return "google";
312
+ if (modelId.startsWith("gpt-") || modelId.startsWith("openai/")) return "openai";
313
+ return undefined;
314
+ }
315
+
316
+ function getAntigravityCounterLimits(report: UsageReport, counterKey: string): UsageLimit[] {
317
+ const prefix = `${report.provider}:${counterKey}:`;
318
+ return report.limits.filter(limit => limit.id.toLowerCase().startsWith(prefix));
319
+ }
320
+
321
+ // Exhaustion checks are only safe with a concrete backend counter. A no-model
322
+ // Antigravity credential lookup (for example image-provider discovery) must
323
+ // not turn one exhausted family into a provider-wide block.
324
+ function scopeAntigravityLimitsForModel(
325
+ report: UsageReport,
326
+ context: CredentialRankingContext | undefined,
327
+ ): UsageLimit[] {
328
+ const counterKey = getAntigravityCounterKeyForModel(context);
329
+ if (!counterKey) return [];
330
+ const backendLimits = getAntigravityCounterLimits(report, counterKey);
331
+ if (backendLimits.length > 0) return backendLimits;
332
+ return getAntigravityCounterLimits(report, "default");
333
+ }
334
+
335
+ function rankAntigravityLimits(report: UsageReport, context: CredentialRankingContext | undefined): UsageLimit[] {
336
+ const counterKey = getAntigravityCounterKeyForModel(context);
337
+ if (!counterKey) return report.limits;
338
+ return scopeAntigravityLimitsForModel(report, context);
339
+ }
340
+
341
+ /**
342
+ * Antigravity quotas reset daily and are returned per backend counter
343
+ * (Anthropic / Google / OpenAI) without a fixed "primary vs secondary"
344
+ * split. `fetchAntigravityUsage` already sorts `limits` ascending by
345
+ * `remainingFraction`; after model-family scoping, the most-pressured
346
+ * relevant counter is index 0.
347
+ *
348
+ * Leave `secondary` unset: AuthStorage compares secondary metrics before
349
+ * primary metrics, which is correct for providers with explicit long-window
350
+ * limits but wrong here. Ranking Antigravity by the bottleneck counter first
351
+ * avoids preferring an account at 95% Gemini / 0% Claude over one at
352
+ * 80% Gemini / 70% Claude.
353
+ */
354
+ export const antigravityRankingStrategy: CredentialRankingStrategy = {
355
+ findWindowLimits(report, context) {
356
+ return { primary: rankAntigravityLimits(report, context)[0] };
357
+ },
358
+ scopeLimits: scopeAntigravityLimitsForModel,
359
+ // Always return a scope for Antigravity so missing/unknown model context
360
+ // cannot fall through to AuthStorage's provider-wide block bucket.
361
+ blockScope(context) {
362
+ const counterKey = getAntigravityCounterKeyForModel(context);
363
+ return `counter:${counterKey ?? "unknown"}`;
364
+ },
365
+ // Antigravity windows omit `durationMs`; the endpoint is
366
+ // `daily-cloudcode-pa.googleapis.com`, so fall back to 24h when computing
367
+ // drain rate.
368
+ windowDefaults: { primaryMs: ONE_DAY_MS, secondaryMs: ONE_DAY_MS },
369
+ };
package/src/usage/kimi.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { $env } from "@prometheus-ai/utils";
2
+ import { getKimiCommonHeaders } from "../registry/oauth/kimi";
2
3
  import type {
3
4
  UsageAmount,
4
5
  UsageFetchContext,
@@ -10,7 +11,6 @@ import type {
10
11
  UsageWindow,
11
12
  } from "../usage";
12
13
  import { isRecord } from "../utils";
13
- import { getKimiCommonHeaders } from "../utils/oauth/kimi";
14
14
  // (Refresh is the sole responsibility of AuthStorage; no provider-direct refresh here.)
15
15
  import { toNumber } from "./shared";
16
16
 
@@ -1,13 +1,12 @@
1
1
  import type { UsageFetchContext, UsageFetchParams, UsageProvider, UsageReport } from "../usage";
2
2
 
3
3
  /**
4
- * MiniMax Coding Plan usage provider.
4
+ * MiniMax Token Plan usage provider.
5
5
  *
6
- * MiniMax Coding Plan is a subscription-based service with a 5-hour rolling window
7
- * quota system. The quota resets automatically based on a rolling window.
6
+ * MiniMax Token Plan is a subscription-based service with a rolling quota system.
8
7
  *
9
- * Currently, MiniMax does not expose a usage/quota API endpoint for the Coding Plan.
10
- * Usage is tracked via the web dashboard at https://platform.minimax.io/user-center/payment/coding-plan
8
+ * Currently, MiniMax does not expose a usage/quota API endpoint for the Token Plan.
9
+ * Usage is tracked via the web dashboard at https://platform.minimax.io/user-center/payment/token-plan
11
10
  *
12
11
  * This provider exists to register support for the minimax-code provider in the
13
12
  * usage system. When MiniMax adds a usage API, this can be implemented.
@@ -17,7 +16,7 @@ async function fetchMiniMaxCodeUsage(params: UsageFetchParams, _ctx: UsageFetchC
17
16
  return null;
18
17
  }
19
18
 
20
- // MiniMax Coding Plan does not currently expose a usage API
19
+ // MiniMax Token Plan does not currently expose a usage API
21
20
  // Users can check their usage via the web dashboard
22
21
  return null;
23
22
  }
@@ -0,0 +1,174 @@
1
+ /**
2
+ * OpenAI Codex "saved rate limit reset" redemption client.
3
+ *
4
+ * OpenAI lets paid Codex accounts bank a usage-window reset and spend it on
5
+ * demand (announced 2026-06-11). The count is surfaced on `/wham/usage` as
6
+ * `rate_limit_reset_credits.available_count` (see `./openai-codex.ts`), but the
7
+ * actual credit objects and the redeem action live on two dedicated routes:
8
+ *
9
+ * GET /wham/rate-limit-reset-credits → list redeemable credits
10
+ * POST /wham/rate-limit-reset-credits/consume → spend one credit
11
+ * body: { credit_id, redeem_request_id }
12
+ *
13
+ * `redeem_request_id` is a client-generated idempotency key (UUID). The consume
14
+ * response carries a `code`: `"reset"` on success, otherwise a business reason
15
+ * (`already_redeemed`, `no_credit`, `nothing_to_reset`).
16
+ *
17
+ * These are thin, dependency-light functions so both the interactive session
18
+ * (the `/usage reset` command + auto-redeem) and any out-of-band tooling can
19
+ * share one wire contract.
20
+ */
21
+ import type { FetchImpl } from "../types";
22
+ import { isRecord } from "../utils";
23
+ import { normalizeCodexBaseUrl } from "./openai-codex";
24
+ import { toNumber } from "./shared";
25
+
26
+ const RESET_CREDITS_PATH = "wham/rate-limit-reset-credits";
27
+ const RESET_CREDITS_CONSUME_PATH = "wham/rate-limit-reset-credits/consume";
28
+
29
+ /** A single redeemable (or already-spent) saved reset. */
30
+ export interface CodexResetCredit {
31
+ /** Opaque credit id, e.g. `RateLimitResetCredit_…`. Pass to {@link consumeCodexResetCredit}. */
32
+ id: string;
33
+ /** Backend reset family, e.g. `codex_rate_limits`. */
34
+ resetType?: string;
35
+ /** `available`, `redeemed`, … */
36
+ status?: string;
37
+ grantedAt?: string;
38
+ expiresAt?: string;
39
+ redeemStartedAt?: string | null;
40
+ redeemedAt?: string | null;
41
+ /** Human-facing card title, e.g. "One free rate limit reset". */
42
+ title?: string;
43
+ description?: string;
44
+ }
45
+
46
+ /** Result of listing an account's saved resets. */
47
+ export interface CodexResetCreditList {
48
+ credits: CodexResetCredit[];
49
+ /** Backend-reported count of credits redeemable right now. */
50
+ availableCount: number;
51
+ }
52
+
53
+ /**
54
+ * Consume outcome `code`. `reset` means a window was actually reset; the others
55
+ * are no-op business outcomes the caller should surface verbatim-ish to the user.
56
+ */
57
+ export type CodexResetConsumeCode =
58
+ | "reset"
59
+ | "already_redeemed"
60
+ | "no_credit"
61
+ | "nothing_to_reset"
62
+ // Forward-compatible: unknown future codes pass through.
63
+ | (string & {});
64
+
65
+ export interface CodexResetConsumeResult {
66
+ /** `true` only when `code === "reset"` (a reset was applied). */
67
+ ok: boolean;
68
+ code: CodexResetConsumeCode;
69
+ /** HTTP status of the consume call (for diagnostics). */
70
+ status: number;
71
+ raw?: unknown;
72
+ }
73
+
74
+ interface CodexResetAuth {
75
+ accessToken: string;
76
+ accountId?: string;
77
+ /** Provider base URL override; defaults to the Codex backend. */
78
+ baseUrl?: string;
79
+ fetch: FetchImpl;
80
+ signal?: AbortSignal;
81
+ }
82
+
83
+ function buildUrl(baseUrl: string | undefined, routePath: string): string {
84
+ const base = normalizeCodexBaseUrl(baseUrl);
85
+ const normalized = base.endsWith("/") ? base : `${base}/`;
86
+ return `${normalized}${routePath}`;
87
+ }
88
+
89
+ function buildHeaders(auth: CodexResetAuth, json: boolean): Record<string, string> {
90
+ const headers: Record<string, string> = {
91
+ Authorization: `Bearer ${auth.accessToken}`,
92
+ "User-Agent": "OpenCode-Status-Plugin/1.0",
93
+ };
94
+ if (auth.accountId) headers["ChatGPT-Account-Id"] = auth.accountId;
95
+ if (json) headers["Content-Type"] = "application/json";
96
+ return headers;
97
+ }
98
+
99
+ function parseCredit(value: unknown): CodexResetCredit | null {
100
+ if (!isRecord(value)) return null;
101
+ const id = typeof value.id === "string" ? value.id : undefined;
102
+ if (!id) return null;
103
+ const str = (key: string): string | undefined =>
104
+ typeof value[key] === "string" ? (value[key] as string) : undefined;
105
+ const nullableStr = (key: string): string | null | undefined => {
106
+ const raw = value[key];
107
+ if (raw === null) return null;
108
+ return typeof raw === "string" ? raw : undefined;
109
+ };
110
+ return {
111
+ id,
112
+ resetType: str("reset_type"),
113
+ status: str("status"),
114
+ grantedAt: str("granted_at"),
115
+ expiresAt: str("expires_at"),
116
+ redeemStartedAt: nullableStr("redeem_started_at"),
117
+ redeemedAt: nullableStr("redeemed_at"),
118
+ title: str("title"),
119
+ description: str("description"),
120
+ };
121
+ }
122
+
123
+ /**
124
+ * List the account's saved rate-limit resets. Returns `null` on transport/auth
125
+ * failure (non-2xx or thrown), letting callers treat it the same as "no data".
126
+ */
127
+ export async function listCodexResetCredits(auth: CodexResetAuth): Promise<CodexResetCreditList | null> {
128
+ const url = buildUrl(auth.baseUrl, RESET_CREDITS_PATH);
129
+ let payload: unknown;
130
+ try {
131
+ const response = await auth.fetch(url, { headers: buildHeaders(auth, false), signal: auth.signal });
132
+ if (!response.ok) return null;
133
+ payload = await response.json();
134
+ } catch {
135
+ return null;
136
+ }
137
+ if (!isRecord(payload)) return null;
138
+ const credits = Array.isArray(payload.credits)
139
+ ? payload.credits.map(parseCredit).filter((c): c is CodexResetCredit => c !== null)
140
+ : [];
141
+ const reported = toNumber(payload.available_count);
142
+ const availableCount =
143
+ reported !== undefined
144
+ ? Math.max(0, Math.trunc(reported))
145
+ : credits.filter(c => (c.status ?? "available") === "available").length;
146
+ return { credits, availableCount };
147
+ }
148
+
149
+ /**
150
+ * Spend one saved reset. `redeemRequestId` is the idempotency key; one is
151
+ * generated when omitted, so retrying with the SAME id is safe and won't
152
+ * double-spend. The returned `code` is `"reset"` on success.
153
+ */
154
+ export async function consumeCodexResetCredit(
155
+ auth: CodexResetAuth & { creditId: string; redeemRequestId?: string },
156
+ ): Promise<CodexResetConsumeResult> {
157
+ const redeemRequestId = auth.redeemRequestId ?? crypto.randomUUID();
158
+ const url = buildUrl(auth.baseUrl, RESET_CREDITS_CONSUME_PATH);
159
+ const response = await auth.fetch(url, {
160
+ method: "POST",
161
+ headers: buildHeaders(auth, true),
162
+ body: JSON.stringify({ credit_id: auth.creditId, redeem_request_id: redeemRequestId }),
163
+ signal: auth.signal,
164
+ });
165
+ let body: unknown;
166
+ try {
167
+ body = await response.json();
168
+ } catch {
169
+ body = undefined;
170
+ }
171
+ const code =
172
+ isRecord(body) && typeof body.code === "string" ? body.code : response.ok ? "reset" : `http_${response.status}`;
173
+ return { ok: code === "reset", code, status: response.status, raw: body };
174
+ }
@@ -1,5 +1,5 @@
1
1
  import { Buffer } from "node:buffer";
2
- import { CODEX_BASE_URL } from "../providers/openai-codex/constants";
2
+ import { CODEX_BASE_URL } from "@prometheus-ai/catalog/wire/codex";
3
3
  import type {
4
4
  CredentialRankingStrategy,
5
5
  UsageAmount,
@@ -8,6 +8,7 @@ import type {
8
8
  UsageLimit,
9
9
  UsageProvider,
10
10
  UsageReport,
11
+ UsageResetCredits,
11
12
  UsageWindow,
12
13
  } from "../usage";
13
14
  import { isRecord } from "../utils";
@@ -185,7 +186,21 @@ function parseUsagePayload(payload: unknown): ParsedUsage | null {
185
186
  return parsed;
186
187
  }
187
188
 
188
- function normalizeCodexBaseUrl(baseUrl?: string): string {
189
+ /**
190
+ * Parse the `rate_limit_reset_credits` block from `/wham/usage`. OpenAI Codex
191
+ * reports the count of saved rate-limit resets the account can redeem here; the
192
+ * redeem action itself lives in `./openai-codex-reset`.
193
+ */
194
+ function parseResetCredits(payload: unknown): UsageResetCredits | undefined {
195
+ if (!isRecord(payload)) return undefined;
196
+ const block = payload.rate_limit_reset_credits;
197
+ if (!isRecord(block)) return undefined;
198
+ const availableCount = toNumber(block.available_count);
199
+ if (availableCount === undefined) return undefined;
200
+ return { availableCount: Math.max(0, Math.trunc(availableCount)) };
201
+ }
202
+
203
+ export function normalizeCodexBaseUrl(baseUrl?: string): string {
189
204
  const fallback = CODEX_BASE_URL;
190
205
  const trimmed = baseUrl?.trim() ? baseUrl.trim() : fallback;
191
206
  const base = trimmed.replace(/\/+$/, "");
@@ -454,10 +469,12 @@ export const openaiCodexUsageProvider: UsageProvider = {
454
469
  }
455
470
  }
456
471
 
472
+ const resetCredits = parseResetCredits(payload);
457
473
  const report: UsageReport = {
458
474
  provider: "openai-codex",
459
475
  fetchedAt: nowMs,
460
476
  limits,
477
+ ...(resetCredits ? { resetCredits } : {}),
461
478
  metadata: {
462
479
  planType,
463
480
  allowed: parsed?.allowed,
package/src/usage/zai.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { toNumber } from "@prometheus-ai/catalog/utils";
1
2
  import type {
2
3
  UsageAmount,
3
4
  UsageFetchContext,
@@ -8,7 +9,7 @@ import type {
8
9
  UsageStatus,
9
10
  UsageWindow,
10
11
  } from "../usage";
11
- import { isRecord, toNumber } from "../utils";
12
+ import { isRecord } from "../utils";
12
13
 
13
14
  const DEFAULT_ENDPOINT = "https://api.z.ai";
14
15
  const QUOTA_PATH = "/api/monitor/usage/quota/limit";