jeopi-ai 16.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (598) hide show
  1. package/CHANGELOG.md +4347 -0
  2. package/README.md +1193 -0
  3. package/dist/types/api-registry.d.ts +30 -0
  4. package/dist/types/auth-broker/client.d.ts +73 -0
  5. package/dist/types/auth-broker/discover.d.ts +35 -0
  6. package/dist/types/auth-broker/index.d.ts +7 -0
  7. package/dist/types/auth-broker/refresher.d.ts +25 -0
  8. package/dist/types/auth-broker/remote-store.d.ts +102 -0
  9. package/dist/types/auth-broker/server.d.ts +43 -0
  10. package/dist/types/auth-broker/snapshot-cache.d.ts +17 -0
  11. package/dist/types/auth-broker/types.d.ts +107 -0
  12. package/dist/types/auth-broker/wire-schemas.d.ts +411 -0
  13. package/dist/types/auth-gateway/http.d.ts +39 -0
  14. package/dist/types/auth-gateway/index.d.ts +3 -0
  15. package/dist/types/auth-gateway/server.d.ts +36 -0
  16. package/dist/types/auth-gateway/types.d.ts +123 -0
  17. package/dist/types/auth-retry.d.ts +124 -0
  18. package/dist/types/auth-storage.d.ts +1026 -0
  19. package/dist/types/dialect/anthropic.d.ts +15 -0
  20. package/dist/types/dialect/catalog.d.ts +3 -0
  21. package/dist/types/dialect/coercion.d.ts +23 -0
  22. package/dist/types/dialect/deepseek.d.ts +14 -0
  23. package/dist/types/dialect/demotion.d.ts +23 -0
  24. package/dist/types/dialect/examples.d.ts +2 -0
  25. package/dist/types/dialect/factory.d.ts +3 -0
  26. package/dist/types/dialect/fenced-thinking.d.ts +53 -0
  27. package/dist/types/dialect/gemini.d.ts +17 -0
  28. package/dist/types/dialect/gemma.d.ts +15 -0
  29. package/dist/types/dialect/glm.d.ts +9 -0
  30. package/dist/types/dialect/harmony.d.ts +8 -0
  31. package/dist/types/dialect/hermes.d.ts +9 -0
  32. package/dist/types/dialect/history.d.ts +3 -0
  33. package/dist/types/dialect/index.d.ts +11 -0
  34. package/dist/types/dialect/inventory.d.ts +12 -0
  35. package/dist/types/dialect/kimi.d.ts +14 -0
  36. package/dist/types/dialect/minimax.d.ts +3 -0
  37. package/dist/types/dialect/owned-stream.d.ts +4 -0
  38. package/dist/types/dialect/qwen3.d.ts +9 -0
  39. package/dist/types/dialect/rendering.d.ts +45 -0
  40. package/dist/types/dialect/thinking.d.ts +6 -0
  41. package/dist/types/dialect/types.d.ts +69 -0
  42. package/dist/types/dialect/xml.d.ts +9 -0
  43. package/dist/types/error/abort.d.ts +14 -0
  44. package/dist/types/error/auth-classify.d.ts +16 -0
  45. package/dist/types/error/auth.d.ts +27 -0
  46. package/dist/types/error/aws.d.ts +23 -0
  47. package/dist/types/error/classes.d.ts +102 -0
  48. package/dist/types/error/finalize.d.ts +39 -0
  49. package/dist/types/error/flags.d.ts +79 -0
  50. package/dist/types/error/format.d.ts +20 -0
  51. package/dist/types/error/gateway.d.ts +20 -0
  52. package/dist/types/error/index.d.ts +13 -0
  53. package/dist/types/error/oauth.d.ts +43 -0
  54. package/dist/types/error/provider.d.ts +42 -0
  55. package/dist/types/error/rate-limit.d.ts +59 -0
  56. package/dist/types/error/retryable.d.ts +27 -0
  57. package/dist/types/error/validation.d.ts +32 -0
  58. package/dist/types/index.d.ts +49 -0
  59. package/dist/types/provider-details.d.ts +24 -0
  60. package/dist/types/providers/__tests__/google-auth.test.d.ts +1 -0
  61. package/dist/types/providers/__tests__/kimi-code-thinking.test.d.ts +1 -0
  62. package/dist/types/providers/__tests__/openai-codex-error.test.d.ts +1 -0
  63. package/dist/types/providers/amazon-bedrock.d.ts +39 -0
  64. package/dist/types/providers/anthropic-client.d.ts +94 -0
  65. package/dist/types/providers/anthropic-messages-server-schema.d.ts +497 -0
  66. package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
  67. package/dist/types/providers/anthropic-wire.d.ts +318 -0
  68. package/dist/types/providers/anthropic.d.ts +248 -0
  69. package/dist/types/providers/aws-credentials.d.ts +53 -0
  70. package/dist/types/providers/aws-eventstream.d.ts +39 -0
  71. package/dist/types/providers/aws-sigv4.d.ts +55 -0
  72. package/dist/types/providers/azure-openai-responses.d.ts +16 -0
  73. package/dist/types/providers/cursor.d.ts +91 -0
  74. package/dist/types/providers/devin.d.ts +12 -0
  75. package/dist/types/providers/error-message.d.ts +27 -0
  76. package/dist/types/providers/github-copilot-headers.d.ts +40 -0
  77. package/dist/types/providers/gitlab-duo-workflow.d.ts +254 -0
  78. package/dist/types/providers/gitlab-duo.d.ts +27 -0
  79. package/dist/types/providers/google-auth.d.ts +32 -0
  80. package/dist/types/providers/google-gemini-cli.d.ts +118 -0
  81. package/dist/types/providers/google-interactions.d.ts +65 -0
  82. package/dist/types/providers/google-shared.d.ts +203 -0
  83. package/dist/types/providers/google-types.d.ts +155 -0
  84. package/dist/types/providers/google-vertex.d.ts +7 -0
  85. package/dist/types/providers/google.d.ts +4 -0
  86. package/dist/types/providers/grammar.d.ts +1 -0
  87. package/dist/types/providers/kimi.d.ts +27 -0
  88. package/dist/types/providers/mock.d.ts +178 -0
  89. package/dist/types/providers/ollama.d.ts +7 -0
  90. package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
  91. package/dist/types/providers/openai-chat-server-schema.d.ts +695 -0
  92. package/dist/types/providers/openai-chat-server.d.ts +16 -0
  93. package/dist/types/providers/openai-chat-wire.d.ts +644 -0
  94. package/dist/types/providers/openai-codex/request-transformer.d.ts +54 -0
  95. package/dist/types/providers/openai-codex/response-handler.d.ts +26 -0
  96. package/dist/types/providers/openai-codex-responses.d.ts +108 -0
  97. package/dist/types/providers/openai-completions.d.ts +45 -0
  98. package/dist/types/providers/openai-reasoning-fallback.d.ts +25 -0
  99. package/dist/types/providers/openai-responses-server-schema.d.ts +349 -0
  100. package/dist/types/providers/openai-responses-server.d.ts +17 -0
  101. package/dist/types/providers/openai-responses-wire.d.ts +6065 -0
  102. package/dist/types/providers/openai-responses.d.ts +126 -0
  103. package/dist/types/providers/openai-shared.d.ts +506 -0
  104. package/dist/types/providers/pi-native-client.d.ts +13 -0
  105. package/dist/types/providers/pi-native-server.d.ts +69 -0
  106. package/dist/types/providers/register-builtins.d.ts +32 -0
  107. package/dist/types/providers/synthetic.d.ts +26 -0
  108. package/dist/types/providers/transform-messages.d.ts +11 -0
  109. package/dist/types/providers/vision-guard.d.ts +20 -0
  110. package/dist/types/registry/aimlapi.d.ts +4 -0
  111. package/dist/types/registry/alibaba-coding-plan.d.ts +8 -0
  112. package/dist/types/registry/amazon-bedrock.d.ts +5 -0
  113. package/dist/types/registry/anthropic.d.ts +10 -0
  114. package/dist/types/registry/api-key-login.d.ts +42 -0
  115. package/dist/types/registry/api-key-validation.d.ts +43 -0
  116. package/dist/types/registry/azure.d.ts +4 -0
  117. package/dist/types/registry/cerebras.d.ts +7 -0
  118. package/dist/types/registry/cloudflare-ai-gateway.d.ts +13 -0
  119. package/dist/types/registry/coreweave.d.ts +7 -0
  120. package/dist/types/registry/cursor.d.ts +7 -0
  121. package/dist/types/registry/deepseek.d.ts +8 -0
  122. package/dist/types/registry/derived.d.ts +5 -0
  123. package/dist/types/registry/devin.d.ts +8 -0
  124. package/dist/types/registry/firepass.d.ts +16 -0
  125. package/dist/types/registry/fireworks.d.ts +7 -0
  126. package/dist/types/registry/github-copilot.d.ts +7 -0
  127. package/dist/types/registry/gitlab-duo-workflow.d.ts +10 -0
  128. package/dist/types/registry/gitlab-duo.d.ts +9 -0
  129. package/dist/types/registry/google-antigravity.d.ts +9 -0
  130. package/dist/types/registry/google-gemini-cli.d.ts +9 -0
  131. package/dist/types/registry/google-vertex.d.ts +5 -0
  132. package/dist/types/registry/google.d.ts +4 -0
  133. package/dist/types/registry/groq.d.ts +4 -0
  134. package/dist/types/registry/huggingface.d.ts +7 -0
  135. package/dist/types/registry/index.d.ts +4 -0
  136. package/dist/types/registry/kagi.d.ts +14 -0
  137. package/dist/types/registry/kilo.d.ts +7 -0
  138. package/dist/types/registry/kimi-code.d.ts +7 -0
  139. package/dist/types/registry/litellm.d.ts +13 -0
  140. package/dist/types/registry/llama-cpp.d.ts +8 -0
  141. package/dist/types/registry/lm-studio.d.ts +8 -0
  142. package/dist/types/registry/minimax-code-cn.d.ts +6 -0
  143. package/dist/types/registry/minimax-code.d.ts +6 -0
  144. package/dist/types/registry/minimax.d.ts +4 -0
  145. package/dist/types/registry/mistral.d.ts +4 -0
  146. package/dist/types/registry/moonshot.d.ts +7 -0
  147. package/dist/types/registry/nanogpt.d.ts +7 -0
  148. package/dist/types/registry/nvidia.d.ts +7 -0
  149. package/dist/types/registry/oauth/__tests__/xai-oauth.test.d.ts +1 -0
  150. package/dist/types/registry/oauth/anthropic.d.ts +23 -0
  151. package/dist/types/registry/oauth/callback-server.d.ts +72 -0
  152. package/dist/types/registry/oauth/cursor.d.ts +15 -0
  153. package/dist/types/registry/oauth/devin.d.ts +5 -0
  154. package/dist/types/registry/oauth/github-copilot.d.ts +30 -0
  155. package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +6 -0
  156. package/dist/types/registry/oauth/gitlab-duo.d.ts +3 -0
  157. package/dist/types/registry/oauth/google-antigravity.d.ts +11 -0
  158. package/dist/types/registry/oauth/google-gemini-cli.d.ts +10 -0
  159. package/dist/types/registry/oauth/google-oauth-shared.d.ts +22 -0
  160. package/dist/types/registry/oauth/index.d.ts +64 -0
  161. package/dist/types/registry/oauth/kimi.d.ts +21 -0
  162. package/dist/types/registry/oauth/minimax-code.d.ts +27 -0
  163. package/dist/types/registry/oauth/openai-codex.d.ts +33 -0
  164. package/dist/types/registry/oauth/opencode.d.ts +18 -0
  165. package/dist/types/registry/oauth/perplexity.d.ts +9 -0
  166. package/dist/types/registry/oauth/pkce.d.ts +8 -0
  167. package/dist/types/registry/oauth/types.d.ts +56 -0
  168. package/dist/types/registry/oauth/wafer.d.ts +1 -0
  169. package/dist/types/registry/oauth/xai-oauth.d.ts +52 -0
  170. package/dist/types/registry/oauth/xiaomi.d.ts +25 -0
  171. package/dist/types/registry/ollama-cloud.d.ts +7 -0
  172. package/dist/types/registry/ollama.d.ts +12 -0
  173. package/dist/types/registry/openai-codex-device.d.ts +8 -0
  174. package/dist/types/registry/openai-codex.d.ts +9 -0
  175. package/dist/types/registry/openai.d.ts +4 -0
  176. package/dist/types/registry/opencode-go.d.ts +6 -0
  177. package/dist/types/registry/opencode-zen.d.ts +6 -0
  178. package/dist/types/registry/openrouter.d.ts +13 -0
  179. package/dist/types/registry/parallel.d.ts +14 -0
  180. package/dist/types/registry/perplexity.d.ts +7 -0
  181. package/dist/types/registry/qianfan.d.ts +7 -0
  182. package/dist/types/registry/qwen-portal.d.ts +7 -0
  183. package/dist/types/registry/registry.d.ts +303 -0
  184. package/dist/types/registry/sakana.d.ts +7 -0
  185. package/dist/types/registry/synthetic.d.ts +6 -0
  186. package/dist/types/registry/tavily.d.ts +14 -0
  187. package/dist/types/registry/together.d.ts +6 -0
  188. package/dist/types/registry/types.d.ts +51 -0
  189. package/dist/types/registry/umans.d.ts +7 -0
  190. package/dist/types/registry/venice.d.ts +13 -0
  191. package/dist/types/registry/vercel-ai-gateway.d.ts +7 -0
  192. package/dist/types/registry/vllm.d.ts +7 -0
  193. package/dist/types/registry/wafer-serverless.d.ts +6 -0
  194. package/dist/types/registry/xai-oauth.d.ts +7 -0
  195. package/dist/types/registry/xai.d.ts +4 -0
  196. package/dist/types/registry/xiaomi-token-plan-ams.d.ts +6 -0
  197. package/dist/types/registry/xiaomi-token-plan-cn.d.ts +6 -0
  198. package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +6 -0
  199. package/dist/types/registry/xiaomi.d.ts +6 -0
  200. package/dist/types/registry/zai.d.ts +7 -0
  201. package/dist/types/registry/zenmux.d.ts +7 -0
  202. package/dist/types/registry/zhipu-coding-plan.d.ts +7 -0
  203. package/dist/types/stream.d.ts +44 -0
  204. package/dist/types/types.d.ts +715 -0
  205. package/dist/types/usage/claude.d.ts +4 -0
  206. package/dist/types/usage/gemini.d.ts +2 -0
  207. package/dist/types/usage/github-copilot.d.ts +7 -0
  208. package/dist/types/usage/google-antigravity.d.ts +15 -0
  209. package/dist/types/usage/kimi.d.ts +2 -0
  210. package/dist/types/usage/minimax-code.d.ts +2 -0
  211. package/dist/types/usage/ollama.d.ts +5 -0
  212. package/dist/types/usage/openai-codex-base-url.d.ts +18 -0
  213. package/dist/types/usage/openai-codex-reset.d.ts +79 -0
  214. package/dist/types/usage/openai-codex.d.ts +3 -0
  215. package/dist/types/usage/opencode-go.d.ts +2 -0
  216. package/dist/types/usage/shared.d.ts +1 -0
  217. package/dist/types/usage/zai.d.ts +2 -0
  218. package/dist/types/usage.d.ts +346 -0
  219. package/dist/types/utils/abort.d.ts +25 -0
  220. package/dist/types/utils/anthropic-auth.d.ts +35 -0
  221. package/dist/types/utils/block-symbols.d.ts +20 -0
  222. package/dist/types/utils/deterministic-id.d.ts +16 -0
  223. package/dist/types/utils/empty-completion-retry.d.ts +21 -0
  224. package/dist/types/utils/event-stream.d.ts +30 -0
  225. package/dist/types/utils/foundry.d.ts +1 -0
  226. package/dist/types/utils/google-validation.d.ts +2 -0
  227. package/dist/types/utils/harmony-leak.d.ts +118 -0
  228. package/dist/types/utils/http-inspector.d.ts +30 -0
  229. package/dist/types/utils/idle-iterator.d.ts +137 -0
  230. package/dist/types/utils/leaked-thinking-stream.d.ts +29 -0
  231. package/dist/types/utils/openai-http.d.ts +54 -0
  232. package/dist/types/utils/openrouter-headers.d.ts +1 -0
  233. package/dist/types/utils/parse-bind.d.ts +23 -0
  234. package/dist/types/utils/provider-response.d.ts +3 -0
  235. package/dist/types/utils/proxy.d.ts +29 -0
  236. package/dist/types/utils/request-debug.d.ts +29 -0
  237. package/dist/types/utils/retry-after.d.ts +4 -0
  238. package/dist/types/utils/retry.d.ts +14 -0
  239. package/dist/types/utils/schema/adapt.d.ts +24 -0
  240. package/dist/types/utils/schema/compatibility.d.ts +30 -0
  241. package/dist/types/utils/schema/dereference.d.ts +11 -0
  242. package/dist/types/utils/schema/draft.d.ts +10 -0
  243. package/dist/types/utils/schema/equality.d.ts +4 -0
  244. package/dist/types/utils/schema/fields.d.ts +54 -0
  245. package/dist/types/utils/schema/index.d.ts +15 -0
  246. package/dist/types/utils/schema/json-schema-validator.d.ts +20 -0
  247. package/dist/types/utils/schema/meta-validator.d.ts +2 -0
  248. package/dist/types/utils/schema/normalize.d.ts +124 -0
  249. package/dist/types/utils/schema/spill.d.ts +8 -0
  250. package/dist/types/utils/schema/stamps.d.ts +17 -0
  251. package/dist/types/utils/schema/strict-tool-validation.d.ts +16 -0
  252. package/dist/types/utils/schema/types.d.ts +4 -0
  253. package/dist/types/utils/schema/typescript.d.ts +18 -0
  254. package/dist/types/utils/schema/wire.d.ts +92 -0
  255. package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -0
  256. package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
  257. package/dist/types/utils/sse-debug.d.ts +5 -0
  258. package/dist/types/utils/stream-markup-healing.d.ts +87 -0
  259. package/dist/types/utils/thinking-loop.d.ts +102 -0
  260. package/dist/types/utils/tool-call-loop-guard.d.ts +26 -0
  261. package/dist/types/utils/tool-choice.d.ts +50 -0
  262. package/dist/types/utils/validation.d.ts +42 -0
  263. package/dist/types/utils.d.ts +24 -0
  264. package/package.json +139 -0
  265. package/src/api-registry.ts +109 -0
  266. package/src/auth-broker/client.ts +359 -0
  267. package/src/auth-broker/discover.ts +222 -0
  268. package/src/auth-broker/index.ts +7 -0
  269. package/src/auth-broker/refresher.ts +117 -0
  270. package/src/auth-broker/remote-store.ts +657 -0
  271. package/src/auth-broker/server.ts +646 -0
  272. package/src/auth-broker/snapshot-cache.ts +191 -0
  273. package/src/auth-broker/types.ts +130 -0
  274. package/src/auth-broker/wire-schemas.ts +249 -0
  275. package/src/auth-gateway/http.ts +194 -0
  276. package/src/auth-gateway/index.ts +3 -0
  277. package/src/auth-gateway/server.ts +802 -0
  278. package/src/auth-gateway/types.ts +151 -0
  279. package/src/auth-retry.ts +250 -0
  280. package/src/auth-storage.ts +5576 -0
  281. package/src/dialect/anthropic.md +31 -0
  282. package/src/dialect/anthropic.ts +608 -0
  283. package/src/dialect/catalog.ts +29 -0
  284. package/src/dialect/coercion.ts +136 -0
  285. package/src/dialect/deepseek.md +24 -0
  286. package/src/dialect/deepseek.ts +609 -0
  287. package/src/dialect/demotion.ts +36 -0
  288. package/src/dialect/examples.ts +33 -0
  289. package/src/dialect/factory.ts +34 -0
  290. package/src/dialect/fenced-thinking.ts +184 -0
  291. package/src/dialect/gemini.md +44 -0
  292. package/src/dialect/gemini.ts +597 -0
  293. package/src/dialect/gemma.md +33 -0
  294. package/src/dialect/gemma.ts +387 -0
  295. package/src/dialect/glm.md +32 -0
  296. package/src/dialect/glm.ts +456 -0
  297. package/src/dialect/harmony.md +31 -0
  298. package/src/dialect/harmony.ts +346 -0
  299. package/src/dialect/hermes.md +25 -0
  300. package/src/dialect/hermes.ts +206 -0
  301. package/src/dialect/history.ts +81 -0
  302. package/src/dialect/index.ts +15 -0
  303. package/src/dialect/inventory.ts +73 -0
  304. package/src/dialect/kimi.md +24 -0
  305. package/src/dialect/kimi.ts +340 -0
  306. package/src/dialect/minimax.md +31 -0
  307. package/src/dialect/minimax.ts +95 -0
  308. package/src/dialect/owned-stream.ts +470 -0
  309. package/src/dialect/prompt-template.md +12 -0
  310. package/src/dialect/qwen3.md +28 -0
  311. package/src/dialect/qwen3.ts +240 -0
  312. package/src/dialect/rendering.ts +249 -0
  313. package/src/dialect/thinking.ts +122 -0
  314. package/src/dialect/types.ts +57 -0
  315. package/src/dialect/xml.md +22 -0
  316. package/src/dialect/xml.ts +90 -0
  317. package/src/error/abort.ts +18 -0
  318. package/src/error/auth-classify.ts +30 -0
  319. package/src/error/auth.ts +48 -0
  320. package/src/error/aws.ts +31 -0
  321. package/src/error/classes.ts +186 -0
  322. package/src/error/finalize.ts +69 -0
  323. package/src/error/flags.ts +506 -0
  324. package/src/error/format.ts +45 -0
  325. package/src/error/gateway.ts +96 -0
  326. package/src/error/index.ts +13 -0
  327. package/src/error/oauth.ts +58 -0
  328. package/src/error/provider.ts +62 -0
  329. package/src/error/rate-limit.ts +161 -0
  330. package/src/error/retryable.ts +70 -0
  331. package/src/error/validation.ts +44 -0
  332. package/src/index.ts +49 -0
  333. package/src/provider-details.ts +90 -0
  334. package/src/providers/__tests__/google-auth.test.ts +144 -0
  335. package/src/providers/__tests__/kimi-code-thinking.test.ts +112 -0
  336. package/src/providers/__tests__/openai-codex-error.test.ts +84 -0
  337. package/src/providers/amazon-bedrock.ts +1042 -0
  338. package/src/providers/anthropic-client.ts +295 -0
  339. package/src/providers/anthropic-messages-server-schema.ts +252 -0
  340. package/src/providers/anthropic-messages-server.ts +756 -0
  341. package/src/providers/anthropic-wire.ts +318 -0
  342. package/src/providers/anthropic.ts +4078 -0
  343. package/src/providers/aws-credentials.ts +586 -0
  344. package/src/providers/aws-eventstream.ts +181 -0
  345. package/src/providers/aws-sigv4.ts +218 -0
  346. package/src/providers/azure-openai-responses.ts +382 -0
  347. package/src/providers/cursor/proto/agent.proto +3526 -0
  348. package/src/providers/cursor/proto/buf.gen.yaml +6 -0
  349. package/src/providers/cursor/proto/buf.yaml +17 -0
  350. package/src/providers/cursor.ts +2695 -0
  351. package/src/providers/devin/proto/buf/validate/validate.proto +468 -0
  352. package/src/providers/devin/proto/buf.gen.yaml +33 -0
  353. package/src/providers/devin/proto/buf.yaml +17 -0
  354. package/src/providers/devin/proto/cel/expr/checked.proto +103 -0
  355. package/src/providers/devin/proto/cel/expr/eval.proto +38 -0
  356. package/src/providers/devin/proto/cel/expr/explain.proto +15 -0
  357. package/src/providers/devin/proto/cel/expr/syntax.proto +113 -0
  358. package/src/providers/devin/proto/cel/expr/value.proto +41 -0
  359. package/src/providers/devin/proto/connectext/grpc/status/v1/status.proto +11 -0
  360. package/src/providers/devin/proto/errorspb/errors.proto +56 -0
  361. package/src/providers/devin/proto/errorspb/hintdetail.proto +7 -0
  362. package/src/providers/devin/proto/errorspb/markers.proto +10 -0
  363. package/src/providers/devin/proto/errorspb/tags.proto +12 -0
  364. package/src/providers/devin/proto/errorspb/testing.proto +6 -0
  365. package/src/providers/devin/proto/exa/analytics_pb/analytics.proto +188 -0
  366. package/src/providers/devin/proto/exa/api_server_pb/api_server.proto +2461 -0
  367. package/src/providers/devin/proto/exa/auth_pb/auth.proto +19 -0
  368. package/src/providers/devin/proto/exa/auto_cascade_common_pb/auto_cascade_common.proto +79 -0
  369. package/src/providers/devin/proto/exa/browser_preview_pb/browser_preview.proto +32 -0
  370. package/src/providers/devin/proto/exa/bug_checker_pb/bug_checker.proto +22 -0
  371. package/src/providers/devin/proto/exa/cascade_plugins_pb/cascade_plugins.proto +262 -0
  372. package/src/providers/devin/proto/exa/chat_client_server_pb/chat_client_server.proto +57 -0
  373. package/src/providers/devin/proto/exa/chat_pb/chat.proto +449 -0
  374. package/src/providers/devin/proto/exa/code_edit/code_edit_pb/code_edit.proto +186 -0
  375. package/src/providers/devin/proto/exa/codeium_common_pb/codeium_common.proto +4157 -0
  376. package/src/providers/devin/proto/exa/context_module_pb/context_module.proto +175 -0
  377. package/src/providers/devin/proto/exa/cortex_pb/cortex.proto +3268 -0
  378. package/src/providers/devin/proto/exa/dev_pb/dev.proto +26 -0
  379. package/src/providers/devin/proto/exa/diff_action_pb/diff_action.proto +75 -0
  380. package/src/providers/devin/proto/exa/eval/pr_eval/datasets_pb/datasets.proto +103 -0
  381. package/src/providers/devin/proto/exa/eval_pb/eval.proto +1315 -0
  382. package/src/providers/devin/proto/exa/extension_server_pb/extension_server.proto +556 -0
  383. package/src/providers/devin/proto/exa/file_system_provider_pb/file_system_provider.proto +75 -0
  384. package/src/providers/devin/proto/exa/index_pb/index.proto +461 -0
  385. package/src/providers/devin/proto/exa/knowledge_base_pb/knowledge_base.proto +144 -0
  386. package/src/providers/devin/proto/exa/language_server_pb/language_server.proto +2385 -0
  387. package/src/providers/devin/proto/exa/model_management_pb/model_management.proto +186 -0
  388. package/src/providers/devin/proto/exa/opensearch_clients_pb/opensearch_clients.proto +503 -0
  389. package/src/providers/devin/proto/exa/product_analytics_pb/product_analytics.proto +37 -0
  390. package/src/providers/devin/proto/exa/prompt_pb/prompt.proto +92 -0
  391. package/src/providers/devin/proto/exa/reactive_component_pb/reactive_component.proto +96 -0
  392. package/src/providers/devin/proto/exa/seat_management_pb/seat_management.proto +2680 -0
  393. package/src/providers/devin/proto/exa/tokenizer_pb/tokenizer.proto +37 -0
  394. package/src/providers/devin/proto/exa/trainer_pb/config.proto +647 -0
  395. package/src/providers/devin/proto/exa/tree_sitter/language_data_pb/language_data.proto +14 -0
  396. package/src/providers/devin/proto/exa/trust_pb/trust.proto +157 -0
  397. package/src/providers/devin/proto/exa/user_analytics_pb/user_analytics.proto +519 -0
  398. package/src/providers/devin/proto/google.golang.org/appengine/internal/base/api_base.proto +28 -0
  399. package/src/providers/devin/proto/google.golang.org/appengine/internal/datastore/datastore_v3.proto +484 -0
  400. package/src/providers/devin/proto/google.golang.org/appengine/internal/log/log_service.proto +136 -0
  401. package/src/providers/devin/proto/google.golang.org/appengine/internal/remote_api/remote_api.proto +42 -0
  402. package/src/providers/devin/proto/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto +61 -0
  403. package/src/providers/devin/proto/grpc/binlog/v1/binarylog.proto +84 -0
  404. package/src/providers/devin/proto/io/prometheus/client/metrics.proto +98 -0
  405. package/src/providers/devin.ts +577 -0
  406. package/src/providers/error-message.ts +21 -0
  407. package/src/providers/github-copilot-headers.ts +141 -0
  408. package/src/providers/gitlab-duo-workflow-chatml-note.md +1 -0
  409. package/src/providers/gitlab-duo-workflow.ts +3058 -0
  410. package/src/providers/gitlab-duo.ts +395 -0
  411. package/src/providers/google-auth.ts +350 -0
  412. package/src/providers/google-gemini-cli.ts +1362 -0
  413. package/src/providers/google-interactions.ts +753 -0
  414. package/src/providers/google-shared.ts +1103 -0
  415. package/src/providers/google-types.ts +180 -0
  416. package/src/providers/google-vertex.ts +183 -0
  417. package/src/providers/google.ts +87 -0
  418. package/src/providers/grammar.ts +70 -0
  419. package/src/providers/kimi.ts +52 -0
  420. package/src/providers/mock.ts +507 -0
  421. package/src/providers/ollama.ts +773 -0
  422. package/src/providers/openai-anthropic-shim.ts +152 -0
  423. package/src/providers/openai-chat-server-schema.ts +242 -0
  424. package/src/providers/openai-chat-server.ts +715 -0
  425. package/src/providers/openai-chat-wire.ts +847 -0
  426. package/src/providers/openai-codex/request-transformer.ts +295 -0
  427. package/src/providers/openai-codex/response-handler.ts +102 -0
  428. package/src/providers/openai-codex-responses.ts +3468 -0
  429. package/src/providers/openai-completions.ts +2173 -0
  430. package/src/providers/openai-reasoning-fallback.ts +269 -0
  431. package/src/providers/openai-responses-reasoning-suppression.md +1 -0
  432. package/src/providers/openai-responses-server-schema.ts +282 -0
  433. package/src/providers/openai-responses-server.ts +1280 -0
  434. package/src/providers/openai-responses-wire.ts +6391 -0
  435. package/src/providers/openai-responses.ts +1022 -0
  436. package/src/providers/openai-shared.ts +2648 -0
  437. package/src/providers/pi-native-client.ts +266 -0
  438. package/src/providers/pi-native-server.ts +242 -0
  439. package/src/providers/register-builtins.ts +475 -0
  440. package/src/providers/synthetic.ts +50 -0
  441. package/src/providers/transform-messages.ts +787 -0
  442. package/src/providers/vision-guard.ts +54 -0
  443. package/src/registry/aimlapi.ts +6 -0
  444. package/src/registry/alibaba-coding-plan.ts +95 -0
  445. package/src/registry/amazon-bedrock.ts +22 -0
  446. package/src/registry/anthropic.ts +26 -0
  447. package/src/registry/api-key-login.ts +112 -0
  448. package/src/registry/api-key-validation.ts +161 -0
  449. package/src/registry/azure.ts +6 -0
  450. package/src/registry/cerebras.ts +23 -0
  451. package/src/registry/cloudflare-ai-gateway.ts +45 -0
  452. package/src/registry/coreweave.ts +40 -0
  453. package/src/registry/cursor.ts +20 -0
  454. package/src/registry/deepseek.ts +46 -0
  455. package/src/registry/derived.ts +9 -0
  456. package/src/registry/devin.ts +15 -0
  457. package/src/registry/firepass.ts +32 -0
  458. package/src/registry/fireworks.ts +28 -0
  459. package/src/registry/github-copilot.ts +22 -0
  460. package/src/registry/gitlab-duo-workflow.ts +20 -0
  461. package/src/registry/gitlab-duo.ts +19 -0
  462. package/src/registry/google-antigravity.ts +22 -0
  463. package/src/registry/google-gemini-cli.ts +22 -0
  464. package/src/registry/google-vertex.ts +38 -0
  465. package/src/registry/google.ts +6 -0
  466. package/src/registry/groq.ts +6 -0
  467. package/src/registry/huggingface.ts +29 -0
  468. package/src/registry/index.ts +4 -0
  469. package/src/registry/kagi.ts +46 -0
  470. package/src/registry/kilo.ts +114 -0
  471. package/src/registry/kimi-code.ts +17 -0
  472. package/src/registry/litellm.ts +45 -0
  473. package/src/registry/llama-cpp.ts +35 -0
  474. package/src/registry/lm-studio.ts +31 -0
  475. package/src/registry/minimax-code-cn.ts +12 -0
  476. package/src/registry/minimax-code.ts +12 -0
  477. package/src/registry/minimax.ts +6 -0
  478. package/src/registry/mistral.ts +6 -0
  479. package/src/registry/moonshot.ts +22 -0
  480. package/src/registry/nanogpt.ts +22 -0
  481. package/src/registry/nvidia.ts +61 -0
  482. package/src/registry/oauth/__tests__/xai-oauth.test.ts +104 -0
  483. package/src/registry/oauth/anthropic.ts +311 -0
  484. package/src/registry/oauth/callback-server.ts +315 -0
  485. package/src/registry/oauth/cursor.ts +171 -0
  486. package/src/registry/oauth/devin.ts +124 -0
  487. package/src/registry/oauth/github-copilot.ts +369 -0
  488. package/src/registry/oauth/gitlab-duo-workflow.ts +146 -0
  489. package/src/registry/oauth/gitlab-duo.ts +222 -0
  490. package/src/registry/oauth/google-antigravity.ts +209 -0
  491. package/src/registry/oauth/google-gemini-cli.ts +273 -0
  492. package/src/registry/oauth/google-oauth-shared.ts +125 -0
  493. package/src/registry/oauth/index.ts +269 -0
  494. package/src/registry/oauth/kimi.ts +289 -0
  495. package/src/registry/oauth/minimax-code.ts +53 -0
  496. package/src/registry/oauth/oauth.html +311 -0
  497. package/src/registry/oauth/openai-codex.ts +364 -0
  498. package/src/registry/oauth/opencode.ts +50 -0
  499. package/src/registry/oauth/perplexity.ts +228 -0
  500. package/src/registry/oauth/pkce.ts +18 -0
  501. package/src/registry/oauth/types.ts +65 -0
  502. package/src/registry/oauth/wafer.ts +24 -0
  503. package/src/registry/oauth/xai-oauth.ts +394 -0
  504. package/src/registry/oauth/xiaomi.ts +211 -0
  505. package/src/registry/ollama-cloud.ts +36 -0
  506. package/src/registry/ollama.ts +43 -0
  507. package/src/registry/openai-codex-device.ts +18 -0
  508. package/src/registry/openai-codex.ts +19 -0
  509. package/src/registry/openai.ts +6 -0
  510. package/src/registry/opencode-go.ts +12 -0
  511. package/src/registry/opencode-zen.ts +12 -0
  512. package/src/registry/openrouter.ts +28 -0
  513. package/src/registry/parallel.ts +45 -0
  514. package/src/registry/perplexity.ts +13 -0
  515. package/src/registry/qianfan.ts +27 -0
  516. package/src/registry/qwen-portal.ts +50 -0
  517. package/src/registry/registry.ts +161 -0
  518. package/src/registry/sakana.ts +22 -0
  519. package/src/registry/synthetic.ts +21 -0
  520. package/src/registry/tavily.ts +45 -0
  521. package/src/registry/together.ts +22 -0
  522. package/src/registry/types.ts +56 -0
  523. package/src/registry/umans.ts +23 -0
  524. package/src/registry/venice.ts +33 -0
  525. package/src/registry/vercel-ai-gateway.ts +38 -0
  526. package/src/registry/vllm.ts +34 -0
  527. package/src/registry/wafer-serverless.ts +12 -0
  528. package/src/registry/xai-oauth.ts +17 -0
  529. package/src/registry/xai.ts +6 -0
  530. package/src/registry/xiaomi-token-plan-ams.ts +12 -0
  531. package/src/registry/xiaomi-token-plan-cn.ts +12 -0
  532. package/src/registry/xiaomi-token-plan-sgp.ts +12 -0
  533. package/src/registry/xiaomi.ts +12 -0
  534. package/src/registry/zai.ts +27 -0
  535. package/src/registry/zenmux.ts +22 -0
  536. package/src/registry/zhipu-coding-plan.ts +27 -0
  537. package/src/stream.ts +1778 -0
  538. package/src/types.ts +856 -0
  539. package/src/usage/claude.ts +485 -0
  540. package/src/usage/gemini.ts +258 -0
  541. package/src/usage/github-copilot.ts +424 -0
  542. package/src/usage/google-antigravity.ts +497 -0
  543. package/src/usage/kimi.ts +271 -0
  544. package/src/usage/minimax-code.ts +30 -0
  545. package/src/usage/ollama.ts +41 -0
  546. package/src/usage/openai-codex-base-url.ts +35 -0
  547. package/src/usage/openai-codex-reset.ts +174 -0
  548. package/src/usage/openai-codex.ts +535 -0
  549. package/src/usage/opencode-go.ts +89 -0
  550. package/src/usage/shared.ts +10 -0
  551. package/src/usage/zai.ts +321 -0
  552. package/src/usage.ts +333 -0
  553. package/src/utils/abort.ts +67 -0
  554. package/src/utils/anthropic-auth.ts +93 -0
  555. package/src/utils/block-symbols.ts +32 -0
  556. package/src/utils/deterministic-id.ts +20 -0
  557. package/src/utils/empty-completion-retry.ts +159 -0
  558. package/src/utils/event-stream.ts +171 -0
  559. package/src/utils/foundry.ts +8 -0
  560. package/src/utils/google-validation.ts +25 -0
  561. package/src/utils/harmony-leak.ts +456 -0
  562. package/src/utils/http-inspector.ts +168 -0
  563. package/src/utils/idle-iterator.ts +473 -0
  564. package/src/utils/leaked-thinking-stream.ts +294 -0
  565. package/src/utils/openai-http.ts +122 -0
  566. package/src/utils/openrouter-headers.ts +12 -0
  567. package/src/utils/parse-bind.ts +56 -0
  568. package/src/utils/provider-response.ts +30 -0
  569. package/src/utils/proxy.ts +240 -0
  570. package/src/utils/request-debug.ts +351 -0
  571. package/src/utils/retry-after.ts +110 -0
  572. package/src/utils/retry.ts +59 -0
  573. package/src/utils/schema/CONSTRAINTS.md +166 -0
  574. package/src/utils/schema/adapt.ts +36 -0
  575. package/src/utils/schema/compatibility.ts +435 -0
  576. package/src/utils/schema/dereference.ts +98 -0
  577. package/src/utils/schema/draft.ts +341 -0
  578. package/src/utils/schema/equality.ts +97 -0
  579. package/src/utils/schema/fields.ts +207 -0
  580. package/src/utils/schema/index.ts +15 -0
  581. package/src/utils/schema/json-schema-validator.ts +595 -0
  582. package/src/utils/schema/meta-validator.ts +167 -0
  583. package/src/utils/schema/normalize.ts +1901 -0
  584. package/src/utils/schema/spill.ts +43 -0
  585. package/src/utils/schema/stamps.ts +109 -0
  586. package/src/utils/schema/strict-tool-validation.ts +117 -0
  587. package/src/utils/schema/types.ts +10 -0
  588. package/src/utils/schema/typescript.ts +198 -0
  589. package/src/utils/schema/wire.ts +789 -0
  590. package/src/utils/schema/zod-decontaminate.ts +331 -0
  591. package/src/utils/sdk-stream-timeout.ts +43 -0
  592. package/src/utils/sse-debug.ts +18 -0
  593. package/src/utils/stream-markup-healing.ts +247 -0
  594. package/src/utils/thinking-loop.ts +552 -0
  595. package/src/utils/tool-call-loop-guard.ts +107 -0
  596. package/src/utils/tool-choice.ts +99 -0
  597. package/src/utils/validation.ts +1507 -0
  598. package/src/utils.ts +171 -0
@@ -0,0 +1,321 @@
1
+ import { toNumber } from "jeopi-catalog/utils";
2
+ import type {
3
+ UsageAmount,
4
+ UsageFetchContext,
5
+ UsageFetchParams,
6
+ UsageLimit,
7
+ UsageProvider,
8
+ UsageReport,
9
+ UsageStatus,
10
+ UsageWindow,
11
+ } from "../usage";
12
+ import { isRecord } from "../utils";
13
+
14
+ const DEFAULT_ENDPOINT = "https://api.z.ai";
15
+ const QUOTA_PATH = "/api/monitor/usage/quota/limit";
16
+ const MODEL_USAGE_PATH = "/api/monitor/usage/model-usage";
17
+ const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
18
+ const HOUR_MS = 60 * 60 * 1000;
19
+ const DAY_MS = 24 * HOUR_MS;
20
+ const WEEK_MS = 7 * DAY_MS;
21
+ const MONTH_MS = 30 * DAY_MS;
22
+
23
+ interface ZaiUsageDetail {
24
+ modelCode?: string;
25
+ usage?: number;
26
+ }
27
+
28
+ function normalizeZaiBaseUrl(baseUrl?: string): string {
29
+ if (!baseUrl?.trim()) return DEFAULT_ENDPOINT;
30
+ try {
31
+ return new URL(baseUrl.trim()).origin;
32
+ } catch {
33
+ return DEFAULT_ENDPOINT;
34
+ }
35
+ }
36
+
37
+ interface ZaiUsageLimitItem {
38
+ type?: string;
39
+ usage?: number;
40
+ currentValue?: number;
41
+ percentage?: number;
42
+ remaining?: number;
43
+ nextResetTime?: number;
44
+ unit?: number;
45
+ number?: number;
46
+ usageDetails?: ZaiUsageDetail[];
47
+ }
48
+
49
+ interface ZaiQuotaPayload {
50
+ success?: boolean;
51
+ code?: number;
52
+ msg?: string;
53
+ data?: {
54
+ limits?: ZaiUsageLimitItem[];
55
+ };
56
+ }
57
+
58
+ function parseMillis(value: unknown): number | undefined {
59
+ const parsed = toNumber(value);
60
+ if (parsed === undefined) return undefined;
61
+ return parsed > 1_000_000_000_000 ? parsed : parsed * 1000;
62
+ }
63
+
64
+ function parseUsageDetails(value: unknown): ZaiUsageDetail[] | undefined {
65
+ if (!Array.isArray(value)) return undefined;
66
+ const details: ZaiUsageDetail[] = [];
67
+ for (const item of value) {
68
+ if (!isRecord(item)) continue;
69
+ const modelCode = typeof item.modelCode === "string" && item.modelCode ? item.modelCode : undefined;
70
+ const usage = toNumber(item.usage);
71
+ details.push({
72
+ ...(modelCode !== undefined ? { modelCode } : {}),
73
+ ...(usage !== undefined ? { usage } : {}),
74
+ });
75
+ }
76
+ return details.length > 0 ? details : undefined;
77
+ }
78
+
79
+ function parseLimitItem(value: unknown): ZaiUsageLimitItem | null {
80
+ if (!isRecord(value)) return null;
81
+ const type = typeof value.type === "string" ? value.type : undefined;
82
+ if (!type) return null;
83
+ return {
84
+ type,
85
+ usage: toNumber(value.usage),
86
+ currentValue: toNumber(value.currentValue),
87
+ percentage: toNumber(value.percentage),
88
+ remaining: toNumber(value.remaining),
89
+ nextResetTime: parseMillis(value.nextResetTime),
90
+ unit: toNumber(value.unit),
91
+ number: toNumber(value.number),
92
+ usageDetails: parseUsageDetails(value.usageDetails),
93
+ };
94
+ }
95
+
96
+ function buildUsageAmount(args: {
97
+ used: number | undefined;
98
+ limit: number | undefined;
99
+ remaining: number | undefined;
100
+ unit: UsageAmount["unit"];
101
+ percentage?: number;
102
+ }): UsageAmount {
103
+ const usedFraction =
104
+ args.percentage !== undefined
105
+ ? Math.min(Math.max(args.percentage / 100, 0), 1)
106
+ : args.used !== undefined && args.limit !== undefined && args.limit > 0
107
+ ? Math.min(args.used / args.limit, 1)
108
+ : undefined;
109
+ const remainingFraction = usedFraction !== undefined ? Math.max(1 - usedFraction, 0) : undefined;
110
+ return {
111
+ used: args.used,
112
+ limit: args.limit,
113
+ remaining: args.remaining,
114
+ usedFraction,
115
+ remainingFraction,
116
+ unit: args.unit,
117
+ };
118
+ }
119
+
120
+ function getUsageStatus(usedFraction: number | undefined): UsageStatus | undefined {
121
+ if (usedFraction === undefined) return undefined;
122
+ if (usedFraction >= 1) return "exhausted";
123
+ if (usedFraction >= 0.9) return "warning";
124
+ return "ok";
125
+ }
126
+
127
+ function formatDate(value: Date): string {
128
+ const pad = (input: number) => String(input).padStart(2, "0");
129
+ return `${value.getFullYear()}-${pad(value.getMonth() + 1)}-${pad(value.getDate())}+${pad(value.getHours())}:${pad(
130
+ value.getMinutes(),
131
+ )}:${pad(value.getSeconds())}`;
132
+ }
133
+
134
+ function formatCountedUnit(count: number, singular: string): string {
135
+ const suffix = count === 1 ? "" : "s";
136
+ return `${count} ${singular}${suffix}`;
137
+ }
138
+
139
+ function buildZaiWindow(parsed: ZaiUsageLimitItem): UsageWindow {
140
+ const count = parsed.number !== undefined && parsed.number > 0 ? parsed.number : 1;
141
+ let id: string;
142
+ let label: string;
143
+ let durationMs: number | undefined;
144
+ switch (parsed.unit) {
145
+ case 3:
146
+ id = `${count}h`;
147
+ label = formatCountedUnit(count, "Hour");
148
+ durationMs = count * HOUR_MS;
149
+ break;
150
+ case 4:
151
+ id = `${count}d`;
152
+ label = formatCountedUnit(count, "Day");
153
+ durationMs = count * DAY_MS;
154
+ break;
155
+ case 5:
156
+ id = `${count}mo`;
157
+ label = count === 1 ? "Monthly" : formatCountedUnit(count, "Month");
158
+ durationMs = count * MONTH_MS;
159
+ break;
160
+ case 6:
161
+ id = "1w";
162
+ label = "Weekly";
163
+ durationMs = WEEK_MS;
164
+ break;
165
+ default:
166
+ id = parsed.unit !== undefined ? `${count}u${parsed.unit}` : "quota";
167
+ label = "Quota";
168
+ break;
169
+ }
170
+ return {
171
+ id,
172
+ label,
173
+ ...(durationMs !== undefined ? { durationMs } : {}),
174
+ ...(parsed.nextResetTime !== undefined ? { resetsAt: parsed.nextResetTime } : {}),
175
+ };
176
+ }
177
+
178
+ function requestQuotaLabel(parsed: ZaiUsageLimitItem): string {
179
+ const detailCodes =
180
+ parsed.usageDetails?.map(detail => detail.modelCode).filter((code): code is string => !!code) ?? [];
181
+ if (detailCodes.includes("search-prime") && detailCodes.includes("web-reader") && detailCodes.includes("zread")) {
182
+ return "ZAI Web Search / Reader / Zread Quota";
183
+ }
184
+ return "ZAI Request Quota";
185
+ }
186
+
187
+ function buildModelUsageUrl(baseUrl: string, now: Date): string {
188
+ const start = new Date(now.getTime() - SEVEN_DAYS_MS);
189
+ const startTime = formatDate(start);
190
+ const endTime = formatDate(now);
191
+ return `${baseUrl}${MODEL_USAGE_PATH}?startTime=${encodeURIComponent(startTime)}&endTime=${encodeURIComponent(endTime)}`;
192
+ }
193
+
194
+ async function fetchZaiUsage(params: UsageFetchParams, ctx: UsageFetchContext): Promise<UsageReport | null> {
195
+ if (params.provider !== "zai") return null;
196
+ const credential = params.credential;
197
+ if (credential.type !== "api_key" || !credential.apiKey) return null;
198
+
199
+ const baseUrl = normalizeZaiBaseUrl(params.baseUrl);
200
+ const url = `${baseUrl}${QUOTA_PATH}`;
201
+ const headers: Record<string, string> = {
202
+ Authorization: credential.apiKey,
203
+ "Content-Type": "application/json",
204
+ "User-Agent": "OpenCode-Status-Plugin/1.0",
205
+ };
206
+
207
+ let payload: ZaiQuotaPayload | null = null;
208
+ try {
209
+ const response = await ctx.fetch(url, {
210
+ headers,
211
+ signal: params.signal,
212
+ });
213
+ if (!response.ok) {
214
+ ctx.logger?.warn("ZAI usage fetch failed", { status: response.status, statusText: response.statusText });
215
+ return null;
216
+ }
217
+ payload = (await response.json()) as ZaiQuotaPayload;
218
+ } catch (error) {
219
+ ctx.logger?.warn("ZAI usage fetch error", { error: String(error) });
220
+ return null;
221
+ }
222
+
223
+ if (!payload) return null;
224
+ if (payload.success !== true) {
225
+ ctx.logger?.warn("ZAI usage response invalid", { code: payload.code, message: payload.msg });
226
+ return null;
227
+ }
228
+
229
+ const limitsPayload = Array.isArray(payload.data?.limits) ? payload.data?.limits : [];
230
+ const limits: UsageLimit[] = [];
231
+
232
+ for (const rawLimit of limitsPayload) {
233
+ const parsed = parseLimitItem(rawLimit);
234
+ if (!parsed) continue;
235
+ if (parsed.type === "TOKENS_LIMIT") {
236
+ const amount = buildUsageAmount({
237
+ used: parsed.currentValue,
238
+ limit: parsed.usage,
239
+ remaining: parsed.remaining,
240
+ percentage: parsed.percentage,
241
+ unit: "tokens",
242
+ });
243
+ const window = buildZaiWindow(parsed);
244
+ limits.push({
245
+ id: `zai:tokens:${window.id}`,
246
+ label: `ZAI ${window.label} Token Quota`,
247
+ scope: {
248
+ provider: params.provider,
249
+ windowId: window.id,
250
+ shared: true,
251
+ },
252
+ window,
253
+ amount,
254
+ status: getUsageStatus(amount.usedFraction),
255
+ });
256
+ }
257
+ if (parsed.type === "TIME_LIMIT") {
258
+ const window = buildZaiWindow(parsed);
259
+ const amount = buildUsageAmount({
260
+ used: parsed.currentValue,
261
+ limit: parsed.usage,
262
+ remaining: parsed.remaining,
263
+ percentage: parsed.percentage,
264
+ unit: "requests",
265
+ });
266
+ limits.push({
267
+ id: `zai:requests:${window.id}`,
268
+ label: requestQuotaLabel(parsed),
269
+ scope: {
270
+ provider: params.provider,
271
+ windowId: window.id,
272
+ shared: true,
273
+ },
274
+ window,
275
+ amount,
276
+ status: getUsageStatus(amount.usedFraction),
277
+ });
278
+ }
279
+ }
280
+
281
+ if (limits.length === 0) return null;
282
+
283
+ const report: UsageReport = {
284
+ provider: params.provider,
285
+ fetchedAt: Date.now(),
286
+ limits,
287
+ metadata: {
288
+ endpoint: url,
289
+ accountId: credential.accountId,
290
+ email: credential.email,
291
+ },
292
+ raw: payload,
293
+ };
294
+
295
+ const modelUsageUrl = buildModelUsageUrl(baseUrl, new Date());
296
+ try {
297
+ const response = await ctx.fetch(modelUsageUrl, {
298
+ headers,
299
+ signal: params.signal,
300
+ });
301
+ if (response.ok) {
302
+ const modelUsagePayload = (await response.json()) as unknown;
303
+ if (isRecord(modelUsagePayload)) {
304
+ report.metadata = {
305
+ ...report.metadata,
306
+ modelUsage: modelUsagePayload,
307
+ };
308
+ }
309
+ }
310
+ } catch (error) {
311
+ ctx.logger?.debug("ZAI model usage fetch failed", { error: String(error) });
312
+ }
313
+
314
+ return report;
315
+ }
316
+
317
+ export const zaiUsageProvider: UsageProvider = {
318
+ id: "zai",
319
+ fetchUsage: fetchZaiUsage,
320
+ supports: params => params.provider === "zai" && params.credential.type === "api_key",
321
+ };
package/src/usage.ts ADDED
@@ -0,0 +1,333 @@
1
+ /**
2
+ * Usage reporting types for provider quota/limit endpoints.
3
+ *
4
+ * Provides a normalized schema to represent multiple limit windows, model tiers,
5
+ * and shared quotas across providers.
6
+ */
7
+ import { type } from "arktype";
8
+ import type { FetchImpl, Provider } from "./types";
9
+ export type UsageUnit = "percent" | "tokens" | "requests" | "usd" | "minutes" | "bytes" | "unknown";
10
+
11
+ export type UsageStatus = "ok" | "warning" | "exhausted" | "unknown";
12
+
13
+ /** Time window for a limit (e.g. 5h, 7d, monthly). */
14
+ export interface UsageWindow {
15
+ /** Stable identifier (e.g. "5h", "7d", "monthly"). */
16
+ id: string;
17
+ /** Human label (e.g. "5 Hour", "7 Day"). */
18
+ label: string;
19
+ /** Window duration in milliseconds, when known. */
20
+ durationMs?: number;
21
+ /** Absolute reset timestamp in milliseconds since epoch. */
22
+ resetsAt?: number;
23
+ }
24
+
25
+ /** Quantitative usage data. */
26
+ export interface UsageAmount {
27
+ /** Amount used in the given unit. */
28
+ used?: number;
29
+ /** Maximum limit in the given unit. */
30
+ limit?: number;
31
+ /** Remaining amount in the given unit. */
32
+ remaining?: number;
33
+ /** Fraction used (0..1). */
34
+ usedFraction?: number;
35
+ /** Fraction remaining (0..1). */
36
+ remainingFraction?: number;
37
+ /** Unit for the amounts (percent, tokens, etc.). */
38
+ unit: UsageUnit;
39
+ }
40
+
41
+ /** Scope metadata describing what the limit applies to. */
42
+ export interface UsageScope {
43
+ provider: Provider;
44
+ accountId?: string;
45
+ projectId?: string;
46
+ orgId?: string;
47
+ modelId?: string;
48
+ tier?: string;
49
+ windowId?: string;
50
+ shared?: boolean;
51
+ }
52
+
53
+ /** Normalized limit entry for a single window or quota bucket. */
54
+ export interface UsageLimit {
55
+ /** Stable identifier for this limit entry. */
56
+ id: string;
57
+ /** Human label for display. */
58
+ label: string;
59
+ scope: UsageScope;
60
+ window?: UsageWindow;
61
+ amount: UsageAmount;
62
+ status?: UsageStatus;
63
+ notes?: string[];
64
+ }
65
+
66
+ /**
67
+ * Per-credit detail for a saved/banked rate-limit reset.
68
+ *
69
+ * Populated when the provider's listing endpoint returns individual credit
70
+ * metadata (e.g. OpenAI Codex `wham/rate-limit-reset-credits`). Callers that
71
+ * only need the count can ignore this; display layers use `expiresAt` to show
72
+ * when banked resets expire ([#3339](https://github.com/can1357/oh-my-pi/issues/3339)).
73
+ */
74
+ export interface UsageResetCreditDetail {
75
+ /** ISO timestamp when the credit was granted. */
76
+ grantedAt?: string;
77
+ /** ISO timestamp when the credit expires and can no longer be redeemed. */
78
+ expiresAt?: string;
79
+ /** Backend status, e.g. `available`, `redeemed`. */
80
+ status?: string;
81
+ }
82
+
83
+ /**
84
+ * Saved/banked rate-limit resets an account can redeem on demand.
85
+ *
86
+ * Surfaced by providers that let users defer a usage-window reset and spend it
87
+ * later (OpenAI Codex "saved rate limit resets"). The redeem itself is a
88
+ * separate, provider-specific action; this is the read-only count for display.
89
+ */
90
+ export interface UsageResetCredits {
91
+ /** Number of resets available to redeem right now. */
92
+ availableCount: number;
93
+ /** Individual credit details (expiry dates, etc.) when the provider exposes them. */
94
+ credits?: UsageResetCreditDetail[];
95
+ }
96
+
97
+ /** Aggregated usage report for a provider. */
98
+ export interface UsageReport {
99
+ provider: Provider;
100
+ fetchedAt: number;
101
+ limits: UsageLimit[];
102
+ /** Saved rate-limit resets the account can redeem, when the provider reports them. */
103
+ resetCredits?: UsageResetCredits;
104
+ /**
105
+ * Provider-wide disclaimers shown once above per-account sections.
106
+ * Use this for caveats that apply to every limit (e.g. "OMP-observed
107
+ * spend only"). Per-limit notes that differ per window (e.g. "Overage
108
+ * requests: N") stay on {@link UsageLimit.notes}.
109
+ */
110
+ notes?: string[];
111
+ metadata?: Record<string, unknown>;
112
+ raw?: unknown;
113
+ }
114
+
115
+ /**
116
+ * Resolve a limit's used fraction (0..1; >1 means overage) from whichever
117
+ * amount fields the provider populated. Precedence mirrors the usage UIs:
118
+ * explicit fraction > used/limit > percent-unit used > inverted remaining.
119
+ */
120
+ export function resolveUsedFraction(limit: UsageLimit): number | undefined {
121
+ const amount = limit.amount;
122
+ if (amount.usedFraction !== undefined) return amount.usedFraction;
123
+ if (amount.used !== undefined && amount.limit !== undefined && amount.limit > 0) {
124
+ return amount.used / amount.limit;
125
+ }
126
+ if (amount.unit === "percent" && amount.used !== undefined) return amount.used / 100;
127
+ if (amount.remainingFraction !== undefined) return Math.max(0, 1 - amount.remainingFraction);
128
+ return undefined;
129
+ }
130
+
131
+ /**
132
+ * One recorded usage-limit snapshot: a single limit window of one account at
133
+ * a point in time. The usage cache itself is latest-snapshot-only; history
134
+ * rows are appended by the auth storage layer whenever a fresh report is
135
+ * fetched, so limit utilization stays inspectable over time.
136
+ */
137
+ export interface UsageHistoryEntry {
138
+ /** Epoch ms the report was fetched. */
139
+ recordedAt: number;
140
+ provider: Provider;
141
+ /** Stable credential identity key (account/email/project derived). */
142
+ accountKey: string;
143
+ email?: string;
144
+ accountId?: string;
145
+ /** {@link UsageLimit.id} of the recorded window. */
146
+ limitId: string;
147
+ /** Human label of the limit. */
148
+ label: string;
149
+ windowLabel?: string;
150
+ /** Used fraction (0..1) when resolvable. */
151
+ usedFraction?: number;
152
+ status?: UsageStatus;
153
+ /** Epoch ms the window resets, when known. */
154
+ resetsAt?: number;
155
+ }
156
+
157
+ /** Filter for reading recorded usage history. */
158
+ export interface UsageHistoryQuery {
159
+ provider?: string;
160
+ /** Inclusive lower bound on {@link UsageHistoryEntry.recordedAt} (epoch ms). */
161
+ sinceMs?: number;
162
+ }
163
+ /** One observed provider request cost, attributed to the credential that made it. */
164
+ export interface UsageCostHistoryEntry {
165
+ /** Epoch ms the request completed. */
166
+ recordedAt: number;
167
+ provider: Provider;
168
+ /** Stable credential identity key (account/email/project/secret derived). */
169
+ accountKey: string;
170
+ /** Estimated request cost in USD. */
171
+ costUsd: number;
172
+ }
173
+
174
+ /** Filter for reading observed request costs. */
175
+ export interface UsageCostHistoryQuery {
176
+ provider?: string;
177
+ accountKey?: string;
178
+ /** Inclusive lower bound on {@link UsageCostHistoryEntry.recordedAt} (epoch ms). */
179
+ sinceMs?: number;
180
+ }
181
+
182
+ // ─── Zod schemas (wire-shape validation for the broker `/v1/usage` endpoint) ─
183
+
184
+ export const usageUnitSchema = type("'percent' | 'tokens' | 'requests' | 'usd' | 'minutes' | 'bytes' | 'unknown'");
185
+ export const usageStatusSchema = type("'ok' | 'warning' | 'exhausted' | 'unknown'");
186
+
187
+ export const usageWindowSchema = type({
188
+ id: "string",
189
+ label: "string",
190
+ "durationMs?": "number",
191
+ "resetsAt?": "number",
192
+ });
193
+
194
+ export const usageAmountSchema = type({
195
+ "used?": "number",
196
+ "limit?": "number",
197
+ "remaining?": "number",
198
+ "usedFraction?": "number",
199
+ "remainingFraction?": "number",
200
+ unit: usageUnitSchema,
201
+ });
202
+
203
+ export const usageScopeSchema = type({
204
+ provider: "string",
205
+ "accountId?": "string",
206
+ "projectId?": "string",
207
+ "orgId?": "string",
208
+ "modelId?": "string",
209
+ "tier?": "string",
210
+ "windowId?": "string",
211
+ "shared?": "boolean",
212
+ });
213
+
214
+ export const usageLimitSchema = type({
215
+ id: "string",
216
+ label: "string",
217
+ scope: usageScopeSchema,
218
+ "window?": usageWindowSchema,
219
+ amount: usageAmountSchema,
220
+ "status?": usageStatusSchema,
221
+ "notes?": "string[]",
222
+ });
223
+
224
+ export const usageResetCreditDetailSchema = type({
225
+ "grantedAt?": "string",
226
+ "expiresAt?": "string",
227
+ "status?": "string",
228
+ });
229
+
230
+ export const usageResetCreditsSchema = type({
231
+ availableCount: "number",
232
+ "credits?": usageResetCreditDetailSchema.array(),
233
+ });
234
+
235
+ export const usageReportSchema = type({
236
+ provider: "string",
237
+ fetchedAt: "number",
238
+ limits: usageLimitSchema.array(),
239
+ "resetCredits?": usageResetCreditsSchema,
240
+ "notes?": "string[]",
241
+ "metadata?": { "[string]": "unknown" },
242
+ // `raw` is provider-specific and may be anything; the broker strips it before
243
+ // sending the report over the wire, so accept-but-ignore here.
244
+ "raw?": "unknown",
245
+ });
246
+
247
+ /** Optional logger for usage fetchers. */
248
+ export interface UsageLogger {
249
+ debug(message: string, meta?: Record<string, unknown>): void;
250
+ warn(message: string, meta?: Record<string, unknown>): void;
251
+ }
252
+
253
+ /** Credential bundle for usage endpoints. */
254
+ export interface UsageCredential {
255
+ type: "api_key" | "oauth";
256
+ apiKey?: string;
257
+ accessToken?: string;
258
+ refreshToken?: string;
259
+ expiresAt?: number;
260
+ accountId?: string;
261
+ projectId?: string;
262
+ email?: string;
263
+ enterpriseUrl?: string;
264
+ metadata?: Record<string, unknown>;
265
+ apiEndpoint?: string;
266
+ }
267
+
268
+ /** Parameters provided to a usage fetcher. */
269
+ export interface UsageFetchParams {
270
+ provider: Provider;
271
+ credential: UsageCredential;
272
+ /** Stable credential identity key derived by the auth storage layer. */
273
+ accountKey?: string;
274
+ baseUrl?: string;
275
+ signal?: AbortSignal;
276
+ }
277
+
278
+ /** Shared runtime utilities for fetchers. */
279
+ export interface UsageFetchContext {
280
+ fetch: FetchImpl;
281
+ logger?: UsageLogger;
282
+ retryWait?: (delayMs: number, signal?: AbortSignal) => Promise<void>;
283
+ /** Observed request-cost history for providers without upstream usage APIs. */
284
+ listUsageCosts?: (query?: UsageCostHistoryQuery) => UsageCostHistoryEntry[];
285
+ }
286
+
287
+ /** Provider implementation for fetching usage information. */
288
+ export interface UsageProvider {
289
+ id: Provider;
290
+ fetchUsage(params: UsageFetchParams, ctx: UsageFetchContext): Promise<UsageReport | null>;
291
+ /** Parse provider rate-limit response headers (lowercased keys) into a usage report, if supported. */
292
+ parseRateLimitHeaders?(headers: Record<string, string>, now?: number): UsageReport | null;
293
+ supports?(params: UsageFetchParams): boolean;
294
+ /** True when fetchUsage contacts upstream and can authenticate the credential for health checks. */
295
+ validatesCredentials?: boolean;
296
+ }
297
+
298
+ /** Request context used when ranking usage for a specific model. */
299
+ export interface CredentialRankingContext {
300
+ /** Provider model id, when the caller is selecting a credential for one model. */
301
+ modelId?: string;
302
+ }
303
+
304
+ /** Strategy for usage-based credential ranking. Providers implement this to opt into smart credential selection. */
305
+ export interface CredentialRankingStrategy {
306
+ /** Extract the primary (short) and secondary (long) window limits from a usage report. */
307
+ findWindowLimits(
308
+ report: UsageReport,
309
+ context?: CredentialRankingContext,
310
+ ): {
311
+ primary?: UsageLimit;
312
+ secondary?: UsageLimit;
313
+ };
314
+ /**
315
+ * Restrict limits to the ones relevant for the requested model before
316
+ * credential-wide exhaustion checks and ranking. Providers with shared
317
+ * account-wide quotas can omit this and use all limits.
318
+ */
319
+ scopeLimits?(report: UsageReport, context?: CredentialRankingContext): UsageLimit[];
320
+ /**
321
+ * Return a provider-local backoff scope for the requested model. Providers
322
+ * with backend-specific quotas use this so one exhausted model family does
323
+ * not block unrelated families on the same OAuth credential.
324
+ */
325
+ blockScope?(context?: CredentialRankingContext): string | undefined;
326
+ /** Fallback window durations (ms) when limits don't specify durationMs. */
327
+ windowDefaults: {
328
+ primaryMs: number;
329
+ secondaryMs: number;
330
+ };
331
+ /** Optional: priority boost for specific credential states (e.g., fresh 5h ticker start). */
332
+ hasPriorityBoost?(primary: UsageLimit | undefined): boolean;
333
+ }