@linxiraos/pi-ai 1.0.0

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 (639) hide show
  1. package/CHANGELOG.md +5066 -0
  2. package/README.md +1195 -0
  3. package/dist/types/api-registry.d.ts +30 -0
  4. package/dist/types/auth/sqlite-credential-store.d.ts +117 -0
  5. package/dist/types/auth-broker/client.d.ts +93 -0
  6. package/dist/types/auth-broker/discover.d.ts +39 -0
  7. package/dist/types/auth-broker/index.d.ts +7 -0
  8. package/dist/types/auth-broker/refresher.d.ts +25 -0
  9. package/dist/types/auth-broker/remote-store.d.ts +136 -0
  10. package/dist/types/auth-broker/server.d.ts +48 -0
  11. package/dist/types/auth-broker/snapshot-cache.d.ts +17 -0
  12. package/dist/types/auth-broker/types.d.ts +152 -0
  13. package/dist/types/auth-broker/wire-schema-resource.d.ts +53 -0
  14. package/dist/types/auth-broker/wire-schemas.d.ts +5 -0
  15. package/dist/types/auth-gateway/http.d.ts +56 -0
  16. package/dist/types/auth-gateway/index.d.ts +3 -0
  17. package/dist/types/auth-gateway/server.d.ts +36 -0
  18. package/dist/types/auth-gateway/types.d.ts +127 -0
  19. package/dist/types/auth-retry.d.ts +150 -0
  20. package/dist/types/auth-storage.d.ts +1258 -0
  21. package/dist/types/dialect/anthropic.d.ts +15 -0
  22. package/dist/types/dialect/catalog.d.ts +3 -0
  23. package/dist/types/dialect/coercion.d.ts +23 -0
  24. package/dist/types/dialect/deepseek.d.ts +14 -0
  25. package/dist/types/dialect/demotion.d.ts +30 -0
  26. package/dist/types/dialect/examples.d.ts +18 -0
  27. package/dist/types/dialect/factory.d.ts +3 -0
  28. package/dist/types/dialect/fenced-thinking.d.ts +53 -0
  29. package/dist/types/dialect/gemini.d.ts +17 -0
  30. package/dist/types/dialect/gemma.d.ts +15 -0
  31. package/dist/types/dialect/glm.d.ts +9 -0
  32. package/dist/types/dialect/harmony.d.ts +8 -0
  33. package/dist/types/dialect/hermes.d.ts +9 -0
  34. package/dist/types/dialect/history.d.ts +3 -0
  35. package/dist/types/dialect/index.d.ts +11 -0
  36. package/dist/types/dialect/inventory.d.ts +9 -0
  37. package/dist/types/dialect/kimi.d.ts +14 -0
  38. package/dist/types/dialect/minimax.d.ts +3 -0
  39. package/dist/types/dialect/owned-stream.d.ts +4 -0
  40. package/dist/types/dialect/qwen3.d.ts +9 -0
  41. package/dist/types/dialect/rendering.d.ts +54 -0
  42. package/dist/types/dialect/thinking.d.ts +6 -0
  43. package/dist/types/dialect/types.d.ts +68 -0
  44. package/dist/types/dialect/xml.d.ts +9 -0
  45. package/dist/types/error/abort.d.ts +14 -0
  46. package/dist/types/error/auth-classify.d.ts +20 -0
  47. package/dist/types/error/auth.d.ts +27 -0
  48. package/dist/types/error/aws.d.ts +27 -0
  49. package/dist/types/error/classes.d.ts +106 -0
  50. package/dist/types/error/finalize.d.ts +39 -0
  51. package/dist/types/error/flags.d.ts +94 -0
  52. package/dist/types/error/format.d.ts +20 -0
  53. package/dist/types/error/gateway.d.ts +20 -0
  54. package/dist/types/error/index.d.ts +14 -0
  55. package/dist/types/error/oauth.d.ts +43 -0
  56. package/dist/types/error/provider.d.ts +42 -0
  57. package/dist/types/error/rate-limit.d.ts +80 -0
  58. package/dist/types/error/retryable.d.ts +27 -0
  59. package/dist/types/error/validation.d.ts +32 -0
  60. package/dist/types/index.d.ts +51 -0
  61. package/dist/types/provider-details.d.ts +24 -0
  62. package/dist/types/providers/amazon-bedrock.d.ts +39 -0
  63. package/dist/types/providers/anthropic-client.d.ts +106 -0
  64. package/dist/types/providers/anthropic-messages-server-schema.d.ts +937 -0
  65. package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
  66. package/dist/types/providers/anthropic-wire.d.ts +345 -0
  67. package/dist/types/providers/anthropic.d.ts +261 -0
  68. package/dist/types/providers/aws-credentials.d.ts +48 -0
  69. package/dist/types/providers/aws-eventstream.d.ts +39 -0
  70. package/dist/types/providers/aws-sigv4.d.ts +55 -0
  71. package/dist/types/providers/azure-openai-responses.d.ts +16 -0
  72. package/dist/types/providers/bedrock-mantle.d.ts +13 -0
  73. package/dist/types/providers/claude-code-fingerprint.d.ts +19 -0
  74. package/dist/types/providers/cowork-fetch.d.ts +3 -0
  75. package/dist/types/providers/cursor/exec-modern.d.ts +98 -0
  76. package/dist/types/providers/cursor-pi-args.d.ts +105 -0
  77. package/dist/types/providers/cursor.d.ts +221 -0
  78. package/dist/types/providers/devin.d.ts +12 -0
  79. package/dist/types/providers/error-message.d.ts +25 -0
  80. package/dist/types/providers/github-copilot-headers.d.ts +40 -0
  81. package/dist/types/providers/gitlab-duo-workflow.d.ts +254 -0
  82. package/dist/types/providers/gitlab-duo.d.ts +27 -0
  83. package/dist/types/providers/google-auth.d.ts +24 -0
  84. package/dist/types/providers/google-gemini-cli.d.ts +120 -0
  85. package/dist/types/providers/google-shared.d.ts +203 -0
  86. package/dist/types/providers/google-types.d.ts +155 -0
  87. package/dist/types/providers/google-vertex.d.ts +7 -0
  88. package/dist/types/providers/google.d.ts +4 -0
  89. package/dist/types/providers/grammar.d.ts +1 -0
  90. package/dist/types/providers/kimi.d.ts +27 -0
  91. package/dist/types/providers/mock.d.ts +179 -0
  92. package/dist/types/providers/ollama.d.ts +8 -0
  93. package/dist/types/providers/openai-anthropic-shim.d.ts +35 -0
  94. package/dist/types/providers/openai-chat-server-schema.d.ts +1311 -0
  95. package/dist/types/providers/openai-chat-server.d.ts +16 -0
  96. package/dist/types/providers/openai-chat-wire.d.ts +669 -0
  97. package/dist/types/providers/openai-codex/request-transformer.d.ts +109 -0
  98. package/dist/types/providers/openai-codex/response-handler.d.ts +26 -0
  99. package/dist/types/providers/openai-codex-responses.d.ts +238 -0
  100. package/dist/types/providers/openai-completions.d.ts +48 -0
  101. package/dist/types/providers/openai-reasoning-fallback.d.ts +25 -0
  102. package/dist/types/providers/openai-responses-server-schema.d.ts +1314 -0
  103. package/dist/types/providers/openai-responses-server.d.ts +17 -0
  104. package/dist/types/providers/openai-responses-wire.d.ts +6099 -0
  105. package/dist/types/providers/openai-responses.d.ts +131 -0
  106. package/dist/types/providers/openai-shared.d.ts +624 -0
  107. package/dist/types/providers/pi-native-client.d.ts +13 -0
  108. package/dist/types/providers/pi-native-server.d.ts +69 -0
  109. package/dist/types/providers/register-builtins.d.ts +37 -0
  110. package/dist/types/providers/synthetic.d.ts +26 -0
  111. package/dist/types/providers/transform-messages.d.ts +32 -0
  112. package/dist/types/providers/vision-guard.d.ts +20 -0
  113. package/dist/types/registry/aiand.d.ts +7 -0
  114. package/dist/types/registry/aimlapi.d.ts +4 -0
  115. package/dist/types/registry/alibaba-coding-plan.d.ts +8 -0
  116. package/dist/types/registry/alibaba-token-plan.d.ts +18 -0
  117. package/dist/types/registry/amazon-bedrock.d.ts +5 -0
  118. package/dist/types/registry/anthropic.d.ts +10 -0
  119. package/dist/types/registry/api-key-login.d.ts +42 -0
  120. package/dist/types/registry/api-key-validation.d.ts +43 -0
  121. package/dist/types/registry/aws.d.ts +13 -0
  122. package/dist/types/registry/azure.d.ts +4 -0
  123. package/dist/types/registry/baseten.d.ts +7 -0
  124. package/dist/types/registry/bedrock-mantle.d.ts +22 -0
  125. package/dist/types/registry/cerebras.d.ts +7 -0
  126. package/dist/types/registry/cloudflare-ai-gateway.d.ts +13 -0
  127. package/dist/types/registry/coreweave.d.ts +7 -0
  128. package/dist/types/registry/cursor.d.ts +7 -0
  129. package/dist/types/registry/deepseek.d.ts +8 -0
  130. package/dist/types/registry/derived.d.ts +5 -0
  131. package/dist/types/registry/devin.d.ts +8 -0
  132. package/dist/types/registry/exa.d.ts +8 -0
  133. package/dist/types/registry/firepass.d.ts +16 -0
  134. package/dist/types/registry/fireworks.d.ts +7 -0
  135. package/dist/types/registry/github-copilot.d.ts +7 -0
  136. package/dist/types/registry/gitlab-duo-workflow.d.ts +10 -0
  137. package/dist/types/registry/gitlab-duo.d.ts +9 -0
  138. package/dist/types/registry/gmi-cloud.d.ts +7 -0
  139. package/dist/types/registry/google-antigravity.d.ts +9 -0
  140. package/dist/types/registry/google-gemini-cli.d.ts +9 -0
  141. package/dist/types/registry/google-vertex.d.ts +5 -0
  142. package/dist/types/registry/google.d.ts +4 -0
  143. package/dist/types/registry/groq.d.ts +4 -0
  144. package/dist/types/registry/huggingface.d.ts +7 -0
  145. package/dist/types/registry/index.d.ts +4 -0
  146. package/dist/types/registry/kagi.d.ts +14 -0
  147. package/dist/types/registry/kilo.d.ts +7 -0
  148. package/dist/types/registry/kimi-code.d.ts +7 -0
  149. package/dist/types/registry/litellm.d.ts +13 -0
  150. package/dist/types/registry/llama-cpp.d.ts +8 -0
  151. package/dist/types/registry/lm-studio.d.ts +8 -0
  152. package/dist/types/registry/meta.d.ts +7 -0
  153. package/dist/types/registry/minimax-code-cn.d.ts +6 -0
  154. package/dist/types/registry/minimax-code.d.ts +6 -0
  155. package/dist/types/registry/minimax.d.ts +4 -0
  156. package/dist/types/registry/mistral.d.ts +4 -0
  157. package/dist/types/registry/moonshot.d.ts +7 -0
  158. package/dist/types/registry/nanogpt.d.ts +7 -0
  159. package/dist/types/registry/novita.d.ts +6 -0
  160. package/dist/types/registry/nvidia.d.ts +7 -0
  161. package/dist/types/registry/oauth/anthropic-constants.d.ts +12 -0
  162. package/dist/types/registry/oauth/anthropic.d.ts +24 -0
  163. package/dist/types/registry/oauth/callback-server.d.ts +74 -0
  164. package/dist/types/registry/oauth/cursor.d.ts +16 -0
  165. package/dist/types/registry/oauth/device-code.d.ts +25 -0
  166. package/dist/types/registry/oauth/devin.d.ts +5 -0
  167. package/dist/types/registry/oauth/github-copilot.d.ts +30 -0
  168. package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +6 -0
  169. package/dist/types/registry/oauth/gitlab-duo.d.ts +3 -0
  170. package/dist/types/registry/oauth/google-antigravity.d.ts +11 -0
  171. package/dist/types/registry/oauth/google-gemini-cli.d.ts +22 -0
  172. package/dist/types/registry/oauth/google-oauth-shared.d.ts +56 -0
  173. package/dist/types/registry/oauth/index.d.ts +45 -0
  174. package/dist/types/registry/oauth/kimi.d.ts +21 -0
  175. package/dist/types/registry/oauth/minimax-code.d.ts +27 -0
  176. package/dist/types/registry/oauth/openai-codex.d.ts +33 -0
  177. package/dist/types/registry/oauth/opencode.d.ts +18 -0
  178. package/dist/types/registry/oauth/perplexity.d.ts +9 -0
  179. package/dist/types/registry/oauth/pkce.d.ts +8 -0
  180. package/dist/types/registry/oauth/types.d.ts +87 -0
  181. package/dist/types/registry/oauth/wafer.d.ts +1 -0
  182. package/dist/types/registry/oauth/xai-oauth.d.ts +46 -0
  183. package/dist/types/registry/oauth/xiaomi.d.ts +25 -0
  184. package/dist/types/registry/oauth/zai.d.ts +25 -0
  185. package/dist/types/registry/ollama-cloud.d.ts +7 -0
  186. package/dist/types/registry/ollama.d.ts +12 -0
  187. package/dist/types/registry/openai-codex-device.d.ts +8 -0
  188. package/dist/types/registry/openai-codex.d.ts +9 -0
  189. package/dist/types/registry/openai.d.ts +4 -0
  190. package/dist/types/registry/opencode-go.d.ts +6 -0
  191. package/dist/types/registry/opencode-zen.d.ts +6 -0
  192. package/dist/types/registry/openrouter.d.ts +13 -0
  193. package/dist/types/registry/parallel.d.ts +14 -0
  194. package/dist/types/registry/perplexity.d.ts +7 -0
  195. package/dist/types/registry/qianfan.d.ts +7 -0
  196. package/dist/types/registry/qwen-portal.d.ts +7 -0
  197. package/dist/types/registry/registry.d.ts +367 -0
  198. package/dist/types/registry/sakana.d.ts +7 -0
  199. package/dist/types/registry/siliconflow-cn.d.ts +7 -0
  200. package/dist/types/registry/siliconflow.d.ts +7 -0
  201. package/dist/types/registry/synthetic.d.ts +6 -0
  202. package/dist/types/registry/tavily.d.ts +14 -0
  203. package/dist/types/registry/together.d.ts +6 -0
  204. package/dist/types/registry/types.d.ts +75 -0
  205. package/dist/types/registry/umans.d.ts +7 -0
  206. package/dist/types/registry/venice.d.ts +13 -0
  207. package/dist/types/registry/vercel-ai-gateway.d.ts +7 -0
  208. package/dist/types/registry/vllm.d.ts +7 -0
  209. package/dist/types/registry/wafer-serverless.d.ts +6 -0
  210. package/dist/types/registry/xai-oauth.d.ts +7 -0
  211. package/dist/types/registry/xai.d.ts +7 -0
  212. package/dist/types/registry/xiaomi-token-plan-ams.d.ts +6 -0
  213. package/dist/types/registry/xiaomi-token-plan-cn.d.ts +6 -0
  214. package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +6 -0
  215. package/dist/types/registry/xiaomi.d.ts +6 -0
  216. package/dist/types/registry/zai.d.ts +15 -0
  217. package/dist/types/registry/zenmux.d.ts +7 -0
  218. package/dist/types/registry/zhipu-coding-plan.d.ts +7 -0
  219. package/dist/types/stream.d.ts +46 -0
  220. package/dist/types/types.d.ts +1064 -0
  221. package/dist/types/usage/alibaba-token-plan.d.ts +3 -0
  222. package/dist/types/usage/claude.d.ts +4 -0
  223. package/dist/types/usage/cursor.d.ts +4 -0
  224. package/dist/types/usage/gemini.d.ts +2 -0
  225. package/dist/types/usage/github-copilot.d.ts +7 -0
  226. package/dist/types/usage/google-antigravity.d.ts +15 -0
  227. package/dist/types/usage/kimi.d.ts +2 -0
  228. package/dist/types/usage/minimax-code.d.ts +3 -0
  229. package/dist/types/usage/ollama.d.ts +5 -0
  230. package/dist/types/usage/openai-codex-base-url.d.ts +18 -0
  231. package/dist/types/usage/openai-codex-reset.d.ts +88 -0
  232. package/dist/types/usage/openai-codex.d.ts +10 -0
  233. package/dist/types/usage/opencode-go.d.ts +2 -0
  234. package/dist/types/usage/shared.d.ts +1 -0
  235. package/dist/types/usage/synthetic.d.ts +2 -0
  236. package/dist/types/usage/umans.d.ts +2 -0
  237. package/dist/types/usage/xai-oauth.d.ts +12 -0
  238. package/dist/types/usage/zai.d.ts +3 -0
  239. package/dist/types/usage.d.ts +527 -0
  240. package/dist/types/utils/abort.d.ts +25 -0
  241. package/dist/types/utils/anthropic-auth.d.ts +35 -0
  242. package/dist/types/utils/aws-profile.d.ts +17 -0
  243. package/dist/types/utils/block-symbols.d.ts +62 -0
  244. package/dist/types/utils/deterministic-id.d.ts +16 -0
  245. package/dist/types/utils/empty-completion-retry.d.ts +21 -0
  246. package/dist/types/utils/event-stream.d.ts +39 -0
  247. package/dist/types/utils/foundry.d.ts +1 -0
  248. package/dist/types/utils/google-validation.d.ts +2 -0
  249. package/dist/types/utils/harmony-leak.d.ts +135 -0
  250. package/dist/types/utils/http-inspector.d.ts +49 -0
  251. package/dist/types/utils/idle-iterator.d.ts +149 -0
  252. package/dist/types/utils/leaked-thinking-stream.d.ts +33 -0
  253. package/dist/types/utils/openai-http.d.ts +48 -0
  254. package/dist/types/utils/openrouter-headers.d.ts +1 -0
  255. package/dist/types/utils/parse-bind.d.ts +23 -0
  256. package/dist/types/utils/provider-response.d.ts +3 -0
  257. package/dist/types/utils/proxy.d.ts +39 -0
  258. package/dist/types/utils/request-debug.d.ts +29 -0
  259. package/dist/types/utils/retry-after.d.ts +4 -0
  260. package/dist/types/utils/retry.d.ts +14 -0
  261. package/dist/types/utils/schema/adapt.d.ts +24 -0
  262. package/dist/types/utils/schema/compatibility.d.ts +30 -0
  263. package/dist/types/utils/schema/dereference.d.ts +11 -0
  264. package/dist/types/utils/schema/draft.d.ts +10 -0
  265. package/dist/types/utils/schema/equality.d.ts +4 -0
  266. package/dist/types/utils/schema/fields.d.ts +54 -0
  267. package/dist/types/utils/schema/index.d.ts +14 -0
  268. package/dist/types/utils/schema/json-schema-validator.d.ts +20 -0
  269. package/dist/types/utils/schema/meta-validator.d.ts +2 -0
  270. package/dist/types/utils/schema/normalize.d.ts +153 -0
  271. package/dist/types/utils/schema/spill.d.ts +8 -0
  272. package/dist/types/utils/schema/stamps.d.ts +17 -0
  273. package/dist/types/utils/schema/strict-tool-validation.d.ts +16 -0
  274. package/dist/types/utils/schema/types.d.ts +4 -0
  275. package/dist/types/utils/schema/typescript.d.ts +24 -0
  276. package/dist/types/utils/schema/wire.d.ts +52 -0
  277. package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
  278. package/dist/types/utils/sse-debug.d.ts +5 -0
  279. package/dist/types/utils/stream-markup-healing.d.ts +87 -0
  280. package/dist/types/utils/thinking-loop.d.ts +102 -0
  281. package/dist/types/utils/tool-call-loop-guard.d.ts +26 -0
  282. package/dist/types/utils/tool-choice.d.ts +52 -0
  283. package/dist/types/utils/validation.d.ts +28 -0
  284. package/dist/types/utils.d.ts +57 -0
  285. package/package.json +138 -0
  286. package/src/api-registry.ts +109 -0
  287. package/src/auth/sqlite-credential-store.ts +2066 -0
  288. package/src/auth-broker/client.ts +471 -0
  289. package/src/auth-broker/discover.ts +310 -0
  290. package/src/auth-broker/index.ts +7 -0
  291. package/src/auth-broker/refresher.ts +117 -0
  292. package/src/auth-broker/remote-store.ts +1332 -0
  293. package/src/auth-broker/server.ts +898 -0
  294. package/src/auth-broker/snapshot-cache.ts +200 -0
  295. package/src/auth-broker/types.ts +193 -0
  296. package/src/auth-broker/wire-schema-resource.ts +487 -0
  297. package/src/auth-broker/wire-schemas.ts +43 -0
  298. package/src/auth-gateway/http.ts +227 -0
  299. package/src/auth-gateway/index.ts +3 -0
  300. package/src/auth-gateway/server.ts +836 -0
  301. package/src/auth-gateway/types.ts +153 -0
  302. package/src/auth-retry.ts +401 -0
  303. package/src/auth-storage.ts +6540 -0
  304. package/src/dialect/anthropic.md +31 -0
  305. package/src/dialect/anthropic.ts +608 -0
  306. package/src/dialect/catalog.ts +29 -0
  307. package/src/dialect/coercion.ts +136 -0
  308. package/src/dialect/deepseek.md +24 -0
  309. package/src/dialect/deepseek.ts +609 -0
  310. package/src/dialect/demotion.ts +40 -0
  311. package/src/dialect/examples.ts +71 -0
  312. package/src/dialect/factory.ts +34 -0
  313. package/src/dialect/fenced-thinking.ts +184 -0
  314. package/src/dialect/gemini.md +44 -0
  315. package/src/dialect/gemini.ts +583 -0
  316. package/src/dialect/gemma.md +33 -0
  317. package/src/dialect/gemma.ts +387 -0
  318. package/src/dialect/glm.md +32 -0
  319. package/src/dialect/glm.ts +579 -0
  320. package/src/dialect/harmony.md +31 -0
  321. package/src/dialect/harmony.ts +345 -0
  322. package/src/dialect/hermes.md +25 -0
  323. package/src/dialect/hermes.ts +206 -0
  324. package/src/dialect/history.ts +81 -0
  325. package/src/dialect/index.ts +15 -0
  326. package/src/dialect/inventory.ts +30 -0
  327. package/src/dialect/kimi.md +24 -0
  328. package/src/dialect/kimi.ts +340 -0
  329. package/src/dialect/minimax.md +31 -0
  330. package/src/dialect/minimax.ts +95 -0
  331. package/src/dialect/owned-stream.ts +481 -0
  332. package/src/dialect/prompt-template.md +12 -0
  333. package/src/dialect/qwen3.md +28 -0
  334. package/src/dialect/qwen3.ts +240 -0
  335. package/src/dialect/rendering.ts +304 -0
  336. package/src/dialect/thinking.ts +292 -0
  337. package/src/dialect/types.ts +56 -0
  338. package/src/dialect/xml.md +22 -0
  339. package/src/dialect/xml.ts +90 -0
  340. package/src/error/abort.ts +18 -0
  341. package/src/error/auth-classify.ts +47 -0
  342. package/src/error/auth.ts +48 -0
  343. package/src/error/aws.ts +35 -0
  344. package/src/error/classes.ts +281 -0
  345. package/src/error/finalize.ts +69 -0
  346. package/src/error/flags.ts +602 -0
  347. package/src/error/format.ts +45 -0
  348. package/src/error/gateway.ts +96 -0
  349. package/src/error/index.ts +14 -0
  350. package/src/error/oauth.ts +58 -0
  351. package/src/error/provider.ts +63 -0
  352. package/src/error/rate-limit.ts +303 -0
  353. package/src/error/retryable.ts +70 -0
  354. package/src/error/validation.ts +44 -0
  355. package/src/index.ts +51 -0
  356. package/src/provider-details.ts +90 -0
  357. package/src/providers/amazon-bedrock.ts +1064 -0
  358. package/src/providers/anthropic-client.ts +317 -0
  359. package/src/providers/anthropic-messages-server-schema.ts +252 -0
  360. package/src/providers/anthropic-messages-server.ts +818 -0
  361. package/src/providers/anthropic-wire.ts +359 -0
  362. package/src/providers/anthropic.ts +4539 -0
  363. package/src/providers/aws-credentials.ts +772 -0
  364. package/src/providers/aws-eventstream.ts +181 -0
  365. package/src/providers/aws-sigv4.ts +218 -0
  366. package/src/providers/azure-openai-responses.ts +438 -0
  367. package/src/providers/bedrock-mantle.ts +110 -0
  368. package/src/providers/claude-code-fingerprint.ts +20 -0
  369. package/src/providers/cowork-fetch.ts +201 -0
  370. package/src/providers/cursor/exec-modern.ts +496 -0
  371. package/src/providers/cursor/proto/agent.proto +4533 -0
  372. package/src/providers/cursor/proto/buf.gen.yaml +6 -0
  373. package/src/providers/cursor/proto/buf.yaml +17 -0
  374. package/src/providers/cursor-pi-args.ts +165 -0
  375. package/src/providers/cursor.ts +4689 -0
  376. package/src/providers/devin/proto/buf/validate/validate.proto +468 -0
  377. package/src/providers/devin/proto/buf.gen.yaml +33 -0
  378. package/src/providers/devin/proto/buf.yaml +17 -0
  379. package/src/providers/devin/proto/cel/expr/checked.proto +103 -0
  380. package/src/providers/devin/proto/cel/expr/eval.proto +38 -0
  381. package/src/providers/devin/proto/cel/expr/explain.proto +15 -0
  382. package/src/providers/devin/proto/cel/expr/syntax.proto +113 -0
  383. package/src/providers/devin/proto/cel/expr/value.proto +41 -0
  384. package/src/providers/devin/proto/connectext/grpc/status/v1/status.proto +11 -0
  385. package/src/providers/devin/proto/errorspb/errors.proto +56 -0
  386. package/src/providers/devin/proto/errorspb/hintdetail.proto +7 -0
  387. package/src/providers/devin/proto/errorspb/markers.proto +10 -0
  388. package/src/providers/devin/proto/errorspb/tags.proto +12 -0
  389. package/src/providers/devin/proto/errorspb/testing.proto +6 -0
  390. package/src/providers/devin/proto/exa/analytics_pb/analytics.proto +188 -0
  391. package/src/providers/devin/proto/exa/api_server_pb/api_server.proto +2461 -0
  392. package/src/providers/devin/proto/exa/auth_pb/auth.proto +19 -0
  393. package/src/providers/devin/proto/exa/auto_cascade_common_pb/auto_cascade_common.proto +79 -0
  394. package/src/providers/devin/proto/exa/browser_preview_pb/browser_preview.proto +32 -0
  395. package/src/providers/devin/proto/exa/bug_checker_pb/bug_checker.proto +22 -0
  396. package/src/providers/devin/proto/exa/cascade_plugins_pb/cascade_plugins.proto +262 -0
  397. package/src/providers/devin/proto/exa/chat_client_server_pb/chat_client_server.proto +57 -0
  398. package/src/providers/devin/proto/exa/chat_pb/chat.proto +449 -0
  399. package/src/providers/devin/proto/exa/code_edit/code_edit_pb/code_edit.proto +186 -0
  400. package/src/providers/devin/proto/exa/codeium_common_pb/codeium_common.proto +4157 -0
  401. package/src/providers/devin/proto/exa/context_module_pb/context_module.proto +175 -0
  402. package/src/providers/devin/proto/exa/cortex_pb/cortex.proto +3268 -0
  403. package/src/providers/devin/proto/exa/dev_pb/dev.proto +26 -0
  404. package/src/providers/devin/proto/exa/diff_action_pb/diff_action.proto +75 -0
  405. package/src/providers/devin/proto/exa/eval/pr_eval/datasets_pb/datasets.proto +103 -0
  406. package/src/providers/devin/proto/exa/eval_pb/eval.proto +1315 -0
  407. package/src/providers/devin/proto/exa/extension_server_pb/extension_server.proto +556 -0
  408. package/src/providers/devin/proto/exa/file_system_provider_pb/file_system_provider.proto +75 -0
  409. package/src/providers/devin/proto/exa/index_pb/index.proto +461 -0
  410. package/src/providers/devin/proto/exa/knowledge_base_pb/knowledge_base.proto +144 -0
  411. package/src/providers/devin/proto/exa/language_server_pb/language_server.proto +2385 -0
  412. package/src/providers/devin/proto/exa/model_management_pb/model_management.proto +186 -0
  413. package/src/providers/devin/proto/exa/opensearch_clients_pb/opensearch_clients.proto +503 -0
  414. package/src/providers/devin/proto/exa/product_analytics_pb/product_analytics.proto +37 -0
  415. package/src/providers/devin/proto/exa/prompt_pb/prompt.proto +92 -0
  416. package/src/providers/devin/proto/exa/reactive_component_pb/reactive_component.proto +96 -0
  417. package/src/providers/devin/proto/exa/seat_management_pb/seat_management.proto +2680 -0
  418. package/src/providers/devin/proto/exa/tokenizer_pb/tokenizer.proto +37 -0
  419. package/src/providers/devin/proto/exa/trainer_pb/config.proto +647 -0
  420. package/src/providers/devin/proto/exa/tree_sitter/language_data_pb/language_data.proto +14 -0
  421. package/src/providers/devin/proto/exa/trust_pb/trust.proto +157 -0
  422. package/src/providers/devin/proto/exa/user_analytics_pb/user_analytics.proto +519 -0
  423. package/src/providers/devin/proto/google.golang.org/appengine/internal/base/api_base.proto +28 -0
  424. package/src/providers/devin/proto/google.golang.org/appengine/internal/datastore/datastore_v3.proto +484 -0
  425. package/src/providers/devin/proto/google.golang.org/appengine/internal/log/log_service.proto +136 -0
  426. package/src/providers/devin/proto/google.golang.org/appengine/internal/remote_api/remote_api.proto +42 -0
  427. package/src/providers/devin/proto/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto +61 -0
  428. package/src/providers/devin/proto/grpc/binlog/v1/binarylog.proto +84 -0
  429. package/src/providers/devin/proto/io/prometheus/client/metrics.proto +98 -0
  430. package/src/providers/devin.ts +679 -0
  431. package/src/providers/error-message.ts +23 -0
  432. package/src/providers/github-copilot-headers.ts +141 -0
  433. package/src/providers/gitlab-duo-workflow-chatml-note.md +1 -0
  434. package/src/providers/gitlab-duo-workflow.ts +3135 -0
  435. package/src/providers/gitlab-duo.ts +399 -0
  436. package/src/providers/google-auth.ts +330 -0
  437. package/src/providers/google-gemini-cli.ts +1370 -0
  438. package/src/providers/google-shared.ts +1122 -0
  439. package/src/providers/google-types.ts +180 -0
  440. package/src/providers/google-vertex.ts +135 -0
  441. package/src/providers/google.ts +47 -0
  442. package/src/providers/grammar.ts +70 -0
  443. package/src/providers/kimi.ts +51 -0
  444. package/src/providers/mock.ts +514 -0
  445. package/src/providers/ollama.ts +776 -0
  446. package/src/providers/openai-anthropic-shim.ts +166 -0
  447. package/src/providers/openai-chat-server-schema.ts +243 -0
  448. package/src/providers/openai-chat-server.ts +752 -0
  449. package/src/providers/openai-chat-wire.ts +859 -0
  450. package/src/providers/openai-codex/request-transformer.ts +491 -0
  451. package/src/providers/openai-codex/response-handler.ts +102 -0
  452. package/src/providers/openai-codex-responses.ts +4716 -0
  453. package/src/providers/openai-completions.ts +2389 -0
  454. package/src/providers/openai-reasoning-fallback.ts +269 -0
  455. package/src/providers/openai-responses-server-schema.ts +397 -0
  456. package/src/providers/openai-responses-server.ts +1466 -0
  457. package/src/providers/openai-responses-wire.ts +6416 -0
  458. package/src/providers/openai-responses.ts +1393 -0
  459. package/src/providers/openai-shared.ts +3500 -0
  460. package/src/providers/pi-native-client.ts +275 -0
  461. package/src/providers/pi-native-server.ts +245 -0
  462. package/src/providers/register-builtins.ts +503 -0
  463. package/src/providers/synthetic.ts +50 -0
  464. package/src/providers/transform-messages.ts +1083 -0
  465. package/src/providers/vision-guard.ts +54 -0
  466. package/src/registry/aiand.ts +22 -0
  467. package/src/registry/aimlapi.ts +6 -0
  468. package/src/registry/alibaba-coding-plan.ts +104 -0
  469. package/src/registry/alibaba-token-plan.ts +125 -0
  470. package/src/registry/amazon-bedrock.ts +22 -0
  471. package/src/registry/anthropic.ts +26 -0
  472. package/src/registry/api-key-login.ts +115 -0
  473. package/src/registry/api-key-validation.ts +145 -0
  474. package/src/registry/aws.ts +57 -0
  475. package/src/registry/azure.ts +6 -0
  476. package/src/registry/baseten.ts +22 -0
  477. package/src/registry/bedrock-mantle.ts +34 -0
  478. package/src/registry/cerebras.ts +23 -0
  479. package/src/registry/cloudflare-ai-gateway.ts +45 -0
  480. package/src/registry/coreweave.ts +40 -0
  481. package/src/registry/cursor.ts +20 -0
  482. package/src/registry/deepseek.ts +46 -0
  483. package/src/registry/derived.ts +9 -0
  484. package/src/registry/devin.ts +15 -0
  485. package/src/registry/exa.ts +19 -0
  486. package/src/registry/firepass.ts +32 -0
  487. package/src/registry/fireworks.ts +28 -0
  488. package/src/registry/github-copilot.ts +22 -0
  489. package/src/registry/gitlab-duo-workflow.ts +20 -0
  490. package/src/registry/gitlab-duo.ts +19 -0
  491. package/src/registry/gmi-cloud.ts +22 -0
  492. package/src/registry/google-antigravity.ts +22 -0
  493. package/src/registry/google-gemini-cli.ts +22 -0
  494. package/src/registry/google-vertex.ts +38 -0
  495. package/src/registry/google.ts +6 -0
  496. package/src/registry/groq.ts +6 -0
  497. package/src/registry/huggingface.ts +29 -0
  498. package/src/registry/index.ts +4 -0
  499. package/src/registry/kagi.ts +46 -0
  500. package/src/registry/kilo.ts +114 -0
  501. package/src/registry/kimi-code.ts +17 -0
  502. package/src/registry/litellm.ts +45 -0
  503. package/src/registry/llama-cpp.ts +35 -0
  504. package/src/registry/lm-studio.ts +31 -0
  505. package/src/registry/meta.ts +22 -0
  506. package/src/registry/minimax-code-cn.ts +12 -0
  507. package/src/registry/minimax-code.ts +12 -0
  508. package/src/registry/minimax.ts +6 -0
  509. package/src/registry/mistral.ts +6 -0
  510. package/src/registry/moonshot.ts +28 -0
  511. package/src/registry/nanogpt.ts +22 -0
  512. package/src/registry/novita.ts +25 -0
  513. package/src/registry/nvidia.ts +61 -0
  514. package/src/registry/oauth/anthropic-constants.ts +12 -0
  515. package/src/registry/oauth/anthropic.ts +346 -0
  516. package/src/registry/oauth/callback-server.ts +438 -0
  517. package/src/registry/oauth/cursor.ts +187 -0
  518. package/src/registry/oauth/device-code.ts +92 -0
  519. package/src/registry/oauth/devin.ts +124 -0
  520. package/src/registry/oauth/github-copilot.ts +369 -0
  521. package/src/registry/oauth/gitlab-duo-workflow.ts +146 -0
  522. package/src/registry/oauth/gitlab-duo.ts +222 -0
  523. package/src/registry/oauth/google-antigravity.ts +225 -0
  524. package/src/registry/oauth/google-gemini-cli.ts +297 -0
  525. package/src/registry/oauth/google-oauth-shared.ts +211 -0
  526. package/src/registry/oauth/index.ts +187 -0
  527. package/src/registry/oauth/kimi.ts +297 -0
  528. package/src/registry/oauth/minimax-code.ts +53 -0
  529. package/src/registry/oauth/oauth.html +317 -0
  530. package/src/registry/oauth/openai-codex.ts +384 -0
  531. package/src/registry/oauth/opencode.ts +50 -0
  532. package/src/registry/oauth/perplexity.ts +228 -0
  533. package/src/registry/oauth/pkce.ts +18 -0
  534. package/src/registry/oauth/types.ts +96 -0
  535. package/src/registry/oauth/wafer.ts +24 -0
  536. package/src/registry/oauth/xai-oauth.ts +559 -0
  537. package/src/registry/oauth/xiaomi.ts +211 -0
  538. package/src/registry/oauth/zai.ts +285 -0
  539. package/src/registry/ollama-cloud.ts +36 -0
  540. package/src/registry/ollama.ts +43 -0
  541. package/src/registry/openai-codex-device.ts +18 -0
  542. package/src/registry/openai-codex.ts +19 -0
  543. package/src/registry/openai.ts +6 -0
  544. package/src/registry/opencode-go.ts +12 -0
  545. package/src/registry/opencode-zen.ts +12 -0
  546. package/src/registry/openrouter.ts +28 -0
  547. package/src/registry/parallel.ts +45 -0
  548. package/src/registry/perplexity.ts +13 -0
  549. package/src/registry/qianfan.ts +27 -0
  550. package/src/registry/qwen-portal.ts +50 -0
  551. package/src/registry/registry.ts +182 -0
  552. package/src/registry/sakana.ts +22 -0
  553. package/src/registry/siliconflow-cn.ts +22 -0
  554. package/src/registry/siliconflow.ts +22 -0
  555. package/src/registry/synthetic.ts +21 -0
  556. package/src/registry/tavily.ts +45 -0
  557. package/src/registry/together.ts +22 -0
  558. package/src/registry/types.ts +86 -0
  559. package/src/registry/umans.ts +23 -0
  560. package/src/registry/venice.ts +33 -0
  561. package/src/registry/vercel-ai-gateway.ts +38 -0
  562. package/src/registry/vllm.ts +34 -0
  563. package/src/registry/wafer-serverless.ts +12 -0
  564. package/src/registry/xai-oauth.ts +17 -0
  565. package/src/registry/xai.ts +22 -0
  566. package/src/registry/xiaomi-token-plan-ams.ts +12 -0
  567. package/src/registry/xiaomi-token-plan-cn.ts +12 -0
  568. package/src/registry/xiaomi-token-plan-sgp.ts +12 -0
  569. package/src/registry/xiaomi.ts +12 -0
  570. package/src/registry/zai.ts +41 -0
  571. package/src/registry/zenmux.ts +22 -0
  572. package/src/registry/zhipu-coding-plan.ts +27 -0
  573. package/src/stream.ts +1944 -0
  574. package/src/types.ts +1243 -0
  575. package/src/usage/alibaba-token-plan.ts +230 -0
  576. package/src/usage/claude.ts +830 -0
  577. package/src/usage/cursor.ts +335 -0
  578. package/src/usage/gemini.ts +258 -0
  579. package/src/usage/github-copilot.ts +424 -0
  580. package/src/usage/google-antigravity.ts +497 -0
  581. package/src/usage/kimi.ts +277 -0
  582. package/src/usage/minimax-code.ts +291 -0
  583. package/src/usage/ollama.ts +41 -0
  584. package/src/usage/openai-codex-base-url.ts +35 -0
  585. package/src/usage/openai-codex-reset.ts +205 -0
  586. package/src/usage/openai-codex.ts +627 -0
  587. package/src/usage/opencode-go.ts +89 -0
  588. package/src/usage/shared.ts +10 -0
  589. package/src/usage/synthetic.ts +180 -0
  590. package/src/usage/umans.ts +192 -0
  591. package/src/usage/xai-oauth.ts +414 -0
  592. package/src/usage/zai.ts +370 -0
  593. package/src/usage.ts +411 -0
  594. package/src/utils/abort.ts +67 -0
  595. package/src/utils/anthropic-auth.ts +93 -0
  596. package/src/utils/aws-profile.ts +88 -0
  597. package/src/utils/block-symbols.ts +78 -0
  598. package/src/utils/deterministic-id.ts +20 -0
  599. package/src/utils/empty-completion-retry.ts +161 -0
  600. package/src/utils/event-stream.ts +202 -0
  601. package/src/utils/foundry.ts +8 -0
  602. package/src/utils/google-validation.ts +25 -0
  603. package/src/utils/harmony-leak.ts +500 -0
  604. package/src/utils/http-inspector.ts +196 -0
  605. package/src/utils/idle-iterator.ts +531 -0
  606. package/src/utils/leaked-thinking-stream.ts +483 -0
  607. package/src/utils/openai-http.ts +119 -0
  608. package/src/utils/openrouter-headers.ts +12 -0
  609. package/src/utils/parse-bind.ts +56 -0
  610. package/src/utils/provider-response.ts +30 -0
  611. package/src/utils/proxy.ts +314 -0
  612. package/src/utils/request-debug.ts +351 -0
  613. package/src/utils/retry-after.ts +121 -0
  614. package/src/utils/retry.ts +77 -0
  615. package/src/utils/schema/CONSTRAINTS.md +168 -0
  616. package/src/utils/schema/adapt.ts +36 -0
  617. package/src/utils/schema/compatibility.ts +435 -0
  618. package/src/utils/schema/dereference.ts +98 -0
  619. package/src/utils/schema/draft.ts +341 -0
  620. package/src/utils/schema/equality.ts +97 -0
  621. package/src/utils/schema/fields.ts +210 -0
  622. package/src/utils/schema/index.ts +14 -0
  623. package/src/utils/schema/json-schema-validator.ts +595 -0
  624. package/src/utils/schema/meta-validator.ts +167 -0
  625. package/src/utils/schema/normalize.ts +2314 -0
  626. package/src/utils/schema/spill.ts +43 -0
  627. package/src/utils/schema/stamps.ts +109 -0
  628. package/src/utils/schema/strict-tool-validation.ts +117 -0
  629. package/src/utils/schema/types.ts +10 -0
  630. package/src/utils/schema/typescript.ts +212 -0
  631. package/src/utils/schema/wire.ts +662 -0
  632. package/src/utils/sdk-stream-timeout.ts +43 -0
  633. package/src/utils/sse-debug.ts +18 -0
  634. package/src/utils/stream-markup-healing.ts +247 -0
  635. package/src/utils/thinking-loop.ts +552 -0
  636. package/src/utils/tool-call-loop-guard.ts +107 -0
  637. package/src/utils/tool-choice.ts +101 -0
  638. package/src/utils/validation.ts +1932 -0
  639. package/src/utils.ts +492 -0
@@ -0,0 +1,277 @@
1
+ import { $env } from "@linxiraos/pi-utils";
2
+ import { getKimiCommonHeaders } from "../registry/oauth/kimi";
3
+ import type {
4
+ UsageAmount,
5
+ UsageFetchContext,
6
+ UsageFetchParams,
7
+ UsageLimit,
8
+ UsageProvider,
9
+ UsageReport,
10
+ UsageStatus,
11
+ UsageWindow,
12
+ } from "../usage";
13
+ import { isRecord } from "../utils";
14
+ // (Refresh is the sole responsibility of AuthStorage; no provider-direct refresh here.)
15
+ import { toNumber } from "./shared";
16
+
17
+ const DEFAULT_BASE_URL = "https://api.kimi.com/coding/v1";
18
+ const USAGE_PATH = "usages";
19
+
20
+ interface KimiUsagePayload {
21
+ usage?: unknown;
22
+ limits?: unknown;
23
+ }
24
+
25
+ type KimiUsageRow = {
26
+ label: string;
27
+ used?: number;
28
+ limit?: number;
29
+ remaining?: number;
30
+ resetsAt?: number;
31
+ window?: UsageWindow;
32
+ };
33
+
34
+ function normalizeBaseUrl(baseUrl?: string): string {
35
+ const envBase = $env.KIMI_CODE_BASE_URL?.trim();
36
+ const candidate = baseUrl?.trim() || envBase || DEFAULT_BASE_URL;
37
+ return candidate.replace(/\/+$/, "");
38
+ }
39
+
40
+ function buildUsageUrl(baseUrl: string): string {
41
+ const normalized = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
42
+ return `${normalized}${USAGE_PATH}`;
43
+ }
44
+
45
+ function parseResetTime(data: Record<string, unknown>, nowMs: number): number | undefined {
46
+ const timeKeys = ["reset_at", "resetAt", "reset_time", "resetTime"] as const;
47
+ for (const key of timeKeys) {
48
+ const value = data[key];
49
+ if (typeof value === "string" && value.trim()) {
50
+ const parsed = Date.parse(value);
51
+ if (Number.isFinite(parsed)) return parsed;
52
+ }
53
+ if (typeof value === "number" && Number.isFinite(value)) {
54
+ return value > 1_000_000_000_000 ? value : value * 1000;
55
+ }
56
+ }
57
+
58
+ const secondsKeys = ["reset_in", "resetIn", "ttl", "window"] as const;
59
+ for (const key of secondsKeys) {
60
+ const seconds = toNumber(data[key]);
61
+ if (seconds !== undefined) return nowMs + seconds * 1000;
62
+ }
63
+
64
+ return undefined;
65
+ }
66
+
67
+ function formatDurationLabel(duration: number, timeUnit: string): string | undefined {
68
+ const upper = timeUnit.toUpperCase();
69
+ if (upper.includes("MINUTE")) {
70
+ if (duration >= 60 && duration % 60 === 0) return `${duration / 60}h limit`;
71
+ return `${duration}m limit`;
72
+ }
73
+ if (upper.includes("HOUR")) return `${duration}h limit`;
74
+ if (upper.includes("DAY")) return `${duration}d limit`;
75
+ if (upper.includes("SECOND")) return `${duration}s limit`;
76
+ return undefined;
77
+ }
78
+
79
+ function buildWindow(windowData: Record<string, unknown>, nowMs: number): UsageWindow | undefined {
80
+ const duration = toNumber(windowData.duration);
81
+ const timeUnit = typeof windowData.timeUnit === "string" ? windowData.timeUnit : "";
82
+ const label = duration !== undefined && timeUnit ? formatDurationLabel(duration, timeUnit) : undefined;
83
+ const resetsAt = parseResetTime(windowData, nowMs);
84
+
85
+ if (duration === undefined && !label && !resetsAt) return undefined;
86
+ let durationMs: number | undefined;
87
+ if (duration !== undefined) {
88
+ if (timeUnit.toUpperCase().includes("MINUTE")) durationMs = duration * 60_000;
89
+ else if (timeUnit.toUpperCase().includes("HOUR")) durationMs = duration * 3_600_000;
90
+ else if (timeUnit.toUpperCase().includes("DAY")) durationMs = duration * 86_400_000;
91
+ else if (timeUnit.toUpperCase().includes("SECOND")) durationMs = duration * 1000;
92
+ }
93
+
94
+ return {
95
+ id: duration !== undefined && timeUnit ? `${duration}${timeUnit.toLowerCase()}` : "default",
96
+ label: label ?? "Usage window",
97
+ durationMs,
98
+ resetsAt,
99
+ };
100
+ }
101
+
102
+ function buildUsageRow(data: Record<string, unknown>, defaultLabel: string, nowMs: number): KimiUsageRow | null {
103
+ const limit = toNumber(data.limit);
104
+ let used = toNumber(data.used);
105
+ const remaining = toNumber(data.remaining);
106
+ if (used === undefined && remaining !== undefined && limit !== undefined) {
107
+ used = limit - remaining;
108
+ }
109
+
110
+ if (used === undefined && limit === undefined) return null;
111
+ const resetsAt = parseResetTime(data, nowMs);
112
+ return {
113
+ label:
114
+ typeof data.name === "string" && data.name
115
+ ? data.name
116
+ : typeof data.title === "string" && data.title
117
+ ? data.title
118
+ : defaultLabel,
119
+ used,
120
+ limit,
121
+ remaining,
122
+ resetsAt,
123
+ };
124
+ }
125
+
126
+ function buildUsageAmount(row: KimiUsageRow): UsageAmount {
127
+ const amount: UsageAmount = { unit: "unknown" };
128
+ if (row.limit !== undefined) amount.limit = row.limit;
129
+ if (row.used !== undefined) amount.used = row.used;
130
+ if (row.remaining !== undefined) amount.remaining = row.remaining;
131
+ if (row.limit !== undefined && row.used !== undefined && row.limit > 0) {
132
+ amount.usedFraction = Math.min(Math.max(row.used / row.limit, 0), 1);
133
+ amount.remainingFraction = Math.min(Math.max((row.limit - row.used) / row.limit, 0), 1);
134
+ amount.remaining = amount.remaining ?? row.limit - row.used;
135
+ }
136
+ return amount;
137
+ }
138
+
139
+ function buildUsageStatus(amount: UsageAmount): UsageStatus {
140
+ if (amount.usedFraction === undefined) return "unknown";
141
+ if (amount.usedFraction >= 1) return "exhausted";
142
+ if (amount.usedFraction >= 0.9) return "warning";
143
+ return "ok";
144
+ }
145
+
146
+ function toUsageLimit(row: KimiUsageRow, provider: string, index: number, accountId?: string): UsageLimit {
147
+ // Kimi puts `resetTime` on the limit `detail`, not on `window`, so a
148
+ // window built from `duration`/`timeUnit` alone carries no resetsAt.
149
+ // Fall back to the row-level reset so `omp usage` can render
150
+ // "resets in …" for the 5h window too.
151
+ const window: UsageWindow | undefined = row.window
152
+ ? row.window.resetsAt !== undefined || row.resetsAt === undefined
153
+ ? row.window
154
+ : { ...row.window, resetsAt: row.resetsAt }
155
+ : row.resetsAt
156
+ ? {
157
+ id: "default",
158
+ label: "Usage window",
159
+ resetsAt: row.resetsAt,
160
+ }
161
+ : undefined;
162
+
163
+ const amount = buildUsageAmount(row);
164
+ return {
165
+ id: `${provider}:${index}`,
166
+ label: row.label,
167
+ scope: {
168
+ provider,
169
+ accountId,
170
+ windowId: window?.id,
171
+ shared: true,
172
+ },
173
+ window,
174
+ amount,
175
+ status: buildUsageStatus(amount),
176
+ };
177
+ }
178
+
179
+ function parseUsagePayload(payload: unknown, nowMs: number): { rows: KimiUsageRow[]; raw: KimiUsagePayload } | null {
180
+ if (!isRecord(payload)) return null;
181
+ const data = payload as KimiUsagePayload;
182
+ const rows: KimiUsageRow[] = [];
183
+
184
+ if (isRecord(data.usage)) {
185
+ const summary = buildUsageRow(data.usage, "Total quota", nowMs);
186
+ if (summary) rows.push(summary);
187
+ }
188
+
189
+ if (Array.isArray(data.limits)) {
190
+ data.limits.forEach((item, idx) => {
191
+ if (!isRecord(item)) return;
192
+ const detail = isRecord(item.detail) ? item.detail : item;
193
+ const windowData = isRecord(item.window) ? item.window : {};
194
+ const label =
195
+ (typeof item.name === "string" && item.name) ||
196
+ (typeof item.title === "string" && item.title) ||
197
+ (typeof item.scope === "string" && item.scope) ||
198
+ (typeof detail.name === "string" && detail.name) ||
199
+ (typeof detail.title === "string" && detail.title) ||
200
+ formatDurationLabel(toNumber(windowData.duration) ?? 0, String(windowData.timeUnit || "")) ||
201
+ `Limit #${idx + 1}`;
202
+ const row = buildUsageRow(detail, label, nowMs);
203
+ if (row) {
204
+ row.window = buildWindow(windowData, nowMs);
205
+ rows.push(row);
206
+ }
207
+ });
208
+ }
209
+
210
+ return { rows, raw: data };
211
+ }
212
+
213
+ export const kimiUsageProvider: UsageProvider = {
214
+ id: "kimi-code",
215
+ supports(params: UsageFetchParams): boolean {
216
+ return params.provider === "kimi-code" && params.credential.type === "oauth";
217
+ },
218
+ async fetchUsage(params: UsageFetchParams, ctx: UsageFetchContext): Promise<UsageReport | null> {
219
+ if (params.provider !== "kimi-code") return null;
220
+ const { credential } = params;
221
+ if (credential.type !== "oauth") return null;
222
+
223
+ const accessToken = credential.accessToken;
224
+ if (!accessToken) return null;
225
+
226
+ const nowMs = Date.now();
227
+ // AuthStorage refreshes OAuth credentials pre-emptively (60s skew). If the
228
+ // usage probe lands with an expired token, short-circuit rather than POST
229
+ // the broker sentinel back to Kimi — the next cycle will carry a freshly
230
+ // refreshed credential.
231
+ if (credential.expiresAt !== undefined && credential.expiresAt <= nowMs) {
232
+ ctx.logger?.debug("Kimi usage token expired; skipping probe", { provider: params.provider });
233
+ return null;
234
+ }
235
+
236
+ const baseUrl = normalizeBaseUrl(params.baseUrl);
237
+ const url = buildUsageUrl(baseUrl);
238
+ let payload: unknown;
239
+ try {
240
+ const response = await ctx.fetch(url, {
241
+ headers: {
242
+ ...getKimiCommonHeaders(),
243
+ Authorization: `Bearer ${accessToken}`,
244
+ },
245
+ signal: params.signal,
246
+ });
247
+ if (!response.ok) {
248
+ ctx.logger?.warn("Kimi usage request failed", { status: response.status, provider: params.provider });
249
+ return null;
250
+ }
251
+ payload = await response.json();
252
+ } catch (error) {
253
+ ctx.logger?.warn("Kimi usage request error", { provider: params.provider, error: String(error) });
254
+ return null;
255
+ }
256
+
257
+ const parsed = parseUsagePayload(payload, nowMs);
258
+ if (!parsed || parsed.rows.length === 0) {
259
+ ctx.logger?.warn("Kimi usage response invalid", { provider: params.provider });
260
+ return null;
261
+ }
262
+
263
+ const limits = parsed.rows.map((row, index) => toUsageLimit(row, params.provider, index, credential.accountId));
264
+
265
+ const report: UsageReport = {
266
+ provider: params.provider,
267
+ fetchedAt: nowMs,
268
+ limits,
269
+ metadata: {
270
+ endpoint: url,
271
+ },
272
+ raw: parsed.raw,
273
+ };
274
+
275
+ return report;
276
+ },
277
+ };
@@ -0,0 +1,291 @@
1
+ import type {
2
+ UsageFetchContext,
3
+ UsageFetchParams,
4
+ UsageLimit,
5
+ UsageProvider,
6
+ UsageReport,
7
+ UsageStatus,
8
+ } from "../usage";
9
+ import { isRecord } from "../utils";
10
+ import { toNumber } from "./shared";
11
+
12
+ const INTL_PROVIDER = "minimax-code";
13
+ const INTL_BASE_URL = "https://api.minimax.io";
14
+ const REMAINS_PATH = "/v1/token_plan/remains";
15
+ const HOUR_MS = 60 * 60 * 1000;
16
+ /** `current_*_status` enum reported per window: 1 normal, 2 exhausted, 3 unlimited. */
17
+ const STATUS_EXHAUSTED = 2;
18
+ const STATUS_UNLIMITED = 3;
19
+ /**
20
+ * The plan-wide token quota every chat model draws from. It is a quota category,
21
+ * not a catalog model id, so its limits are scoped `shared`: `AuthStorage` has no
22
+ * MiniMax ranking strategy and would otherwise match `scope.modelId` against ids
23
+ * like `MiniMax-M3` and drop the "models with usage data" mapping. Category
24
+ * buckets such as `video` meter a separate quota and keep their own model scope.
25
+ */
26
+ const SHARED_BUCKET = "general";
27
+
28
+ /** One `model_remains[]` bucket: a plan quota tracked over a rolling interval plus a weekly window. */
29
+ interface TokenPlanBucket {
30
+ modelName: string;
31
+ intervalStart?: number;
32
+ intervalEnd?: number;
33
+ intervalRemainingPercent?: number;
34
+ intervalTotalCount?: number;
35
+ intervalUsageCount?: number;
36
+ intervalStatus?: number;
37
+ weeklyStart?: number;
38
+ weeklyEnd?: number;
39
+ weeklyRemainingPercent?: number;
40
+ weeklyTotalCount?: number;
41
+ weeklyUsageCount?: number;
42
+ weeklyStatus?: number;
43
+ }
44
+
45
+ /** MiniMax reports epoch milliseconds; tolerate seconds in case a deployment differs. */
46
+ function parseTimestamp(value: unknown): number | undefined {
47
+ const parsed = toNumber(value);
48
+ if (parsed === undefined || parsed <= 0) return undefined;
49
+ return parsed < 1_000_000_000_000 ? parsed * 1000 : parsed;
50
+ }
51
+
52
+ /** `current_*_remaining_percent` is 0..100 remaining; usage fractions are 0..1 used. */
53
+ function usedFractionFromRemainingPercent(value: unknown): number | undefined {
54
+ const parsed = toNumber(value);
55
+ if (parsed === undefined || !Number.isFinite(parsed)) return undefined;
56
+ // (100 - p) / 100 keeps whole percentages exact; 1 - p / 100 does not (90 → 0.09999999999999998).
57
+ return Math.min(1, Math.max(0, (100 - parsed) / 100));
58
+ }
59
+
60
+ function usageStatus(usedFraction: number): UsageStatus {
61
+ if (usedFraction >= 1) return "exhausted";
62
+ if (usedFraction >= 0.9) return "warning";
63
+ return "ok";
64
+ }
65
+
66
+ function parseBucket(value: unknown): TokenPlanBucket | null {
67
+ if (!isRecord(value)) return null;
68
+ const modelName = typeof value.model_name === "string" ? value.model_name.trim() : "";
69
+ if (!modelName) return null;
70
+ return {
71
+ modelName,
72
+ intervalStart: parseTimestamp(value.start_time),
73
+ intervalEnd: parseTimestamp(value.end_time),
74
+ intervalRemainingPercent: toNumber(value.current_interval_remaining_percent),
75
+ intervalTotalCount: toNumber(value.current_interval_total_count),
76
+ intervalUsageCount: toNumber(value.current_interval_usage_count),
77
+ intervalStatus: toNumber(value.current_interval_status),
78
+ weeklyStart: parseTimestamp(value.weekly_start_time),
79
+ weeklyEnd: parseTimestamp(value.weekly_end_time),
80
+ weeklyRemainingPercent: toNumber(value.current_weekly_remaining_percent),
81
+ weeklyTotalCount: toNumber(value.current_weekly_total_count),
82
+ weeklyUsageCount: toNumber(value.current_weekly_usage_count),
83
+ weeklyStatus: toNumber(value.current_weekly_status),
84
+ };
85
+ }
86
+
87
+ /**
88
+ * A model outside the current plan is reported as both windows "unlimited"
89
+ * with zero totals and 100% remaining, which would otherwise read as a pristine
90
+ * quota. MiniMax's own CLI treats exactly this shape as "not in plan"
91
+ * ([MiniMax-AI/cli#173](https://github.com/MiniMax-AI/cli/issues/173)), so the
92
+ * bucket is kept out of the limits and named in `metadata.unavailableModels`.
93
+ * Zero totals alone are not enough: a live plan reports `0/0` with status 1 and
94
+ * a real remaining percentage.
95
+ */
96
+ function isUnavailablePlan(bucket: TokenPlanBucket): boolean {
97
+ return (
98
+ bucket.intervalTotalCount === 0 &&
99
+ bucket.weeklyTotalCount === 0 &&
100
+ bucket.intervalStatus === STATUS_UNLIMITED &&
101
+ bucket.weeklyStatus === STATUS_UNLIMITED
102
+ );
103
+ }
104
+
105
+ /**
106
+ * Interval length varies per bucket (text quotas roll every few hours, media
107
+ * quotas daily), so the window id follows the reported span instead of a
108
+ * hardcoded tier. Spans that are not whole hours are labelled in minutes
109
+ * rather than rounded into a wrong hour count.
110
+ */
111
+ function intervalWindowId(durationMs: number | undefined): { id: string; label: string } {
112
+ if (durationMs === undefined || durationMs <= 0) return { id: "interval", label: "Interval" };
113
+ if (durationMs % HOUR_MS === 0) {
114
+ const hours = durationMs / HOUR_MS;
115
+ return { id: `${hours}h`, label: `${hours} Hour` };
116
+ }
117
+ const minutes = Math.round(durationMs / 60_000);
118
+ if (minutes <= 0) return { id: "interval", label: "Interval" };
119
+ return { id: `${minutes}m`, label: `${minutes} Minute` };
120
+ }
121
+
122
+ function buildLimit(args: {
123
+ provider: string;
124
+ bucket: TokenPlanBucket;
125
+ windowId: string;
126
+ windowLabel: string;
127
+ durationMs?: number;
128
+ resetsAt?: number;
129
+ usedFraction: number | undefined;
130
+ windowStatus?: number;
131
+ usageCount?: number;
132
+ totalCount?: number;
133
+ accountId?: string;
134
+ }): UsageLimit | undefined {
135
+ // The endpoint's own status outranks the percentage: an exhausted window may
136
+ // omit it, or keep a stale one that would otherwise render as healthy quota.
137
+ const usedFraction = args.windowStatus === STATUS_EXHAUSTED ? 1 : args.usedFraction;
138
+ if (usedFraction === undefined) return undefined;
139
+ const totalCount = args.totalCount;
140
+ return {
141
+ id: `${args.bucket.modelName}:${args.windowId}`,
142
+ label: `${args.bucket.modelName.charAt(0).toUpperCase()}${args.bucket.modelName.slice(1)} ${args.windowLabel}`,
143
+ scope: {
144
+ provider: args.provider,
145
+ ...(args.accountId ? { accountId: args.accountId } : {}),
146
+ ...(args.bucket.modelName === SHARED_BUCKET ? { shared: true as const } : { modelId: args.bucket.modelName }),
147
+ windowId: args.windowId,
148
+ },
149
+ window: {
150
+ id: args.windowId,
151
+ label: args.windowLabel,
152
+ ...(args.durationMs !== undefined && args.durationMs > 0 ? { durationMs: args.durationMs } : {}),
153
+ ...(args.resetsAt ? { resetsAt: args.resetsAt } : {}),
154
+ },
155
+ amount: {
156
+ used: usedFraction * 100,
157
+ usedFraction,
158
+ remaining: 100 - usedFraction * 100,
159
+ remainingFraction: 1 - usedFraction,
160
+ unit: "percent",
161
+ },
162
+ status: usageStatus(usedFraction),
163
+ ...(totalCount !== undefined && totalCount > 0
164
+ ? { notes: [`Requests: ${args.usageCount ?? 0}/${totalCount}`] }
165
+ : {}),
166
+ };
167
+ }
168
+
169
+ function buildBucketLimits(provider: string, bucket: TokenPlanBucket, accountId: string | undefined): UsageLimit[] {
170
+ const intervalDuration =
171
+ bucket.intervalStart !== undefined && bucket.intervalEnd !== undefined
172
+ ? bucket.intervalEnd - bucket.intervalStart
173
+ : undefined;
174
+ const weeklyDuration =
175
+ bucket.weeklyStart !== undefined && bucket.weeklyEnd !== undefined
176
+ ? bucket.weeklyEnd - bucket.weeklyStart
177
+ : undefined;
178
+ const interval = intervalWindowId(intervalDuration);
179
+ return [
180
+ buildLimit({
181
+ provider,
182
+ bucket,
183
+ windowId: interval.id,
184
+ windowLabel: interval.label,
185
+ durationMs: intervalDuration,
186
+ resetsAt: bucket.intervalEnd,
187
+ usedFraction: usedFractionFromRemainingPercent(bucket.intervalRemainingPercent),
188
+ windowStatus: bucket.intervalStatus,
189
+ usageCount: bucket.intervalUsageCount,
190
+ totalCount: bucket.intervalTotalCount,
191
+ accountId,
192
+ }),
193
+ buildLimit({
194
+ provider,
195
+ bucket,
196
+ windowId: "7d",
197
+ windowLabel: "7 Day",
198
+ durationMs: weeklyDuration,
199
+ resetsAt: bucket.weeklyEnd,
200
+ usedFraction: usedFractionFromRemainingPercent(bucket.weeklyRemainingPercent),
201
+ windowStatus: bucket.weeklyStatus,
202
+ usageCount: bucket.weeklyUsageCount,
203
+ totalCount: bucket.weeklyTotalCount,
204
+ accountId,
205
+ }),
206
+ ].filter((limit): limit is UsageLimit => limit !== undefined);
207
+ }
208
+
209
+ /**
210
+ * MiniMax Token Plan usage provider (international, `api.minimax.io`).
211
+ *
212
+ * `GET /v1/token_plan/remains` returns one `model_remains[]` bucket per plan
213
+ * quota (text, media, …), each carrying a rolling interval window and a weekly
214
+ * window with the remaining percentage. MiniMax answers HTTP 200 even for
215
+ * rejected credentials, so `base_resp.status_code` is the real success signal.
216
+ */
217
+ async function fetchMiniMaxCodeUsage(params: UsageFetchParams, ctx: UsageFetchContext): Promise<UsageReport | null> {
218
+ if (params.provider !== INTL_PROVIDER) return null;
219
+ const apiKey = params.credential.apiKey;
220
+ if (params.credential.type !== "api_key" || !apiKey) return null;
221
+
222
+ try {
223
+ const configuredBaseUrl = params.baseUrl?.trim();
224
+ const baseUrl = configuredBaseUrl ? configuredBaseUrl.replace(/\/+$/, "").replace(/\/v1$/, "") : INTL_BASE_URL;
225
+ const response = await ctx.fetch(`${baseUrl}${REMAINS_PATH}`, {
226
+ headers: { Accept: "application/json", Authorization: `Bearer ${apiKey}` },
227
+ signal: params.signal,
228
+ });
229
+ if (!response.ok) {
230
+ ctx.logger?.warn("MiniMax Token Plan usage fetch failed", {
231
+ provider: params.provider,
232
+ status: response.status,
233
+ });
234
+ return null;
235
+ }
236
+ const payload: unknown = await response.json();
237
+ if (!isRecord(payload)) return null;
238
+ const statusCode = isRecord(payload.base_resp) ? toNumber(payload.base_resp.status_code) : undefined;
239
+ if (statusCode !== 0) {
240
+ ctx.logger?.warn("MiniMax Token Plan usage response rejected", {
241
+ provider: params.provider,
242
+ statusCode: statusCode ?? "missing",
243
+ });
244
+ return null;
245
+ }
246
+ if (!Array.isArray(payload.model_remains)) return null;
247
+
248
+ const accountId = params.credential.accountId;
249
+ const limits: UsageLimit[] = [];
250
+ const models: string[] = [];
251
+ const unavailableModels: string[] = [];
252
+ for (const entry of payload.model_remains) {
253
+ const bucket = parseBucket(entry);
254
+ if (!bucket) continue;
255
+ models.push(bucket.modelName);
256
+ if (isUnavailablePlan(bucket)) {
257
+ unavailableModels.push(bucket.modelName);
258
+ continue;
259
+ }
260
+ limits.push(...buildBucketLimits(params.provider, bucket, accountId));
261
+ }
262
+ if (limits.length === 0) return null;
263
+
264
+ return {
265
+ provider: params.provider,
266
+ fetchedAt: Date.now(),
267
+ limits,
268
+ metadata: {
269
+ source: "minimax-token-plan",
270
+ models,
271
+ ...(unavailableModels.length > 0 ? { unavailableModels } : {}),
272
+ ...(accountId ? { accountId } : {}),
273
+ },
274
+ raw: payload,
275
+ };
276
+ } catch (error) {
277
+ ctx.logger?.warn("MiniMax Token Plan usage request failed", {
278
+ provider: params.provider,
279
+ error: error instanceof Error ? error.name : "unknown",
280
+ });
281
+ return null;
282
+ }
283
+ }
284
+
285
+ /** MiniMax Token Plan (international, `api.minimax.io`). */
286
+ export const minimaxCodeUsageProvider: UsageProvider = {
287
+ id: INTL_PROVIDER,
288
+ fetchUsage: fetchMiniMaxCodeUsage,
289
+ supports: params =>
290
+ params.provider === INTL_PROVIDER && params.credential.type === "api_key" && Boolean(params.credential.apiKey),
291
+ };
@@ -0,0 +1,41 @@
1
+ import type { UsageFetchContext, UsageFetchParams, UsageProvider, UsageReport } from "../usage";
2
+
3
+ const OLLAMA_PROVIDER = "ollama";
4
+ const OLLAMA_CLOUD_PROVIDER = "ollama-cloud";
5
+
6
+ async function fetchOllamaUsage(params: UsageFetchParams, _ctx: UsageFetchContext): Promise<UsageReport | null> {
7
+ if (params.provider !== OLLAMA_PROVIDER && params.provider !== OLLAMA_CLOUD_PROVIDER) {
8
+ return null;
9
+ }
10
+
11
+ const metadata: Record<string, unknown> = {};
12
+ if (params.credential.email) metadata.email = params.credential.email;
13
+ if (params.credential.accountId) metadata.accountId = params.credential.accountId;
14
+ if (params.credential.projectId) metadata.projectId = params.credential.projectId;
15
+
16
+ return {
17
+ provider: params.provider,
18
+ fetchedAt: Date.now(),
19
+ limits: [],
20
+ notes: [
21
+ "Ollama does not expose a standalone quota usage API; per-response token usage is reported during requests.",
22
+ ],
23
+ metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
24
+ };
25
+ }
26
+
27
+ /** Registers Ollama accounts with usage views even though no quota endpoint is exposed. */
28
+ export const ollamaUsageProvider: UsageProvider = {
29
+ id: OLLAMA_PROVIDER,
30
+ fetchUsage: fetchOllamaUsage,
31
+ supports: params => params.provider === OLLAMA_PROVIDER,
32
+ validatesCredentials: false,
33
+ };
34
+
35
+ /** Registers Ollama Cloud accounts with usage views until a quota endpoint is available. */
36
+ export const ollamaCloudUsageProvider: UsageProvider = {
37
+ id: OLLAMA_CLOUD_PROVIDER,
38
+ fetchUsage: fetchOllamaUsage,
39
+ supports: params => params.provider === OLLAMA_CLOUD_PROVIDER,
40
+ validatesCredentials: false,
41
+ };
@@ -0,0 +1,35 @@
1
+ import { CODEX_BASE_URL } from "@linxiraos/pi-catalog/wire/codex";
2
+
3
+ /**
4
+ * Resolve the base URL for ChatGPT account-API requests (`wham/usage`,
5
+ * `wham/rate-limit-reset-credits`).
6
+ *
7
+ * These endpoints live on the canonical ChatGPT origin and authenticate with
8
+ * the Codex OAuth bearer minted for that origin. They are NOT part of the
9
+ * `/responses` API surface that streaming proxies (Headroom, 9router, etc.)
10
+ * forward, so a `providers.openai-codex.baseUrl` override pointed at such a
11
+ * proxy MUST NOT be used here — doing so 404s and silently breaks
12
+ * `/usage show` (issue #3679).
13
+ *
14
+ * Accepted overrides are the canonical `chatgpt.com` / `chat.openai.com`
15
+ * origins. Any extra path (e.g. a streaming override like
16
+ * `/backend-api/codex/responses`) is normalized to `${origin}/backend-api`,
17
+ * since the account endpoints always live directly under `/backend-api`. Any
18
+ * other host falls back to {@link CODEX_BASE_URL}.
19
+ */
20
+ export function normalizeCodexBaseUrl(baseUrl?: string): string {
21
+ const trimmed = baseUrl?.trim().replace(/\/+$/, "");
22
+ if (!trimmed) return CODEX_BASE_URL;
23
+ let parsed: URL;
24
+ try {
25
+ parsed = new URL(trimmed);
26
+ } catch {
27
+ return CODEX_BASE_URL;
28
+ }
29
+ const host = parsed.host.toLowerCase();
30
+ if (host !== "chatgpt.com" && host !== "chat.openai.com") return CODEX_BASE_URL;
31
+ // wham/usage always lives at `${origin}/backend-api/...` on the canonical
32
+ // ChatGPT origin, so ignore any extra path (e.g. `/backend-api/codex/responses`
33
+ // from a streaming baseUrl) — otherwise we'd build `.../codex/responses/wham/usage`.
34
+ return `${parsed.origin}/backend-api`;
35
+ }