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,65 @@
1
+ import type { FetchImpl } from "../../types";
2
+ import type { OAuthProviderUnion } from "../registry";
3
+
4
+ export type OAuthCredentials = {
5
+ refresh: string;
6
+ access: string;
7
+ expires: number;
8
+ enterpriseUrl?: string;
9
+ projectId?: string;
10
+ email?: string;
11
+ accountId?: string;
12
+ apiEndpoint?: string;
13
+ };
14
+
15
+ export type OAuthProvider = OAuthProviderUnion;
16
+
17
+ export type OAuthProviderId = OAuthProvider | (string & {});
18
+
19
+ export type OAuthPrompt = {
20
+ message: string;
21
+ placeholder?: string;
22
+ allowEmpty?: boolean;
23
+ };
24
+
25
+ export type OAuthAuthInfo = {
26
+ url: string;
27
+ instructions?: string;
28
+ };
29
+
30
+ export interface OAuthProviderInfo {
31
+ id: OAuthProviderId;
32
+ name: string;
33
+ available: boolean;
34
+ /**
35
+ * Provider id the login stores credentials under, when it differs from `id`
36
+ * (e.g. `openai-codex-device` ⇒ `openai-codex`). Lets callers map a login
37
+ * entry back to the model provider it authenticates.
38
+ */
39
+ storeCredentialsAs?: string;
40
+ }
41
+
42
+ export interface OAuthController {
43
+ onAuth?(info: OAuthAuthInfo): void;
44
+ onProgress?(message: string): void;
45
+ onManualCodeInput?(): Promise<string>;
46
+ onPrompt?(prompt: OAuthPrompt): Promise<string>;
47
+ signal?: AbortSignal;
48
+ fetch?: FetchImpl;
49
+ }
50
+
51
+ export interface OAuthLoginCallbacks extends OAuthController {
52
+ onAuth: (info: OAuthAuthInfo) => void;
53
+ onPrompt: (prompt: OAuthPrompt) => Promise<string>;
54
+ }
55
+
56
+ export interface OAuthProviderInterface {
57
+ readonly id: OAuthProviderId;
58
+ readonly name: string;
59
+ readonly sourceId?: string;
60
+ login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials | string>;
61
+ refreshToken?(credentials: OAuthCredentials): Promise<OAuthCredentials>;
62
+ getApiKey?(credentials: OAuthCredentials): string;
63
+ /** Store resulting OAuth credentials under a different provider id. */
64
+ readonly storeCredentialsAs?: string;
65
+ }
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Wafer Serverless login flow.
3
+ *
4
+ * Wafer (https://wafer.ai) exposes a pay-as-you-go OpenAI-compatible SKU at
5
+ * `https://pass.wafer.ai/v1`. Keys use the `wfr_…` prefix and are validated
6
+ * against `/v1/models`, which is cheap (no token spend).
7
+ */
8
+ import { createApiKeyLogin } from "../api-key-login";
9
+
10
+ const WAFER_AUTH_URL = "https://wafer.ai/dashboard";
11
+ const WAFER_MODELS_URL = "https://pass.wafer.ai/v1/models";
12
+
13
+ export const loginWaferServerless = createApiKeyLogin({
14
+ providerLabel: "Wafer Serverless",
15
+ authUrl: WAFER_AUTH_URL,
16
+ instructions: "Create or copy your Wafer Serverless API key from the Wafer dashboard",
17
+ promptMessage: "Paste your Wafer Serverless API key",
18
+ placeholder: "wfr_...",
19
+ validation: {
20
+ kind: "models-endpoint",
21
+ provider: "Wafer Serverless",
22
+ modelsUrl: WAFER_MODELS_URL,
23
+ },
24
+ });
@@ -0,0 +1,394 @@
1
+ // Ported from NousResearch/hermes-agent (MIT) — hermes_cli/auth.py xAI sections (L93-111, L2979-3160, L5286-5469).
2
+
3
+ /**
4
+ * xAI Grok (SuperGrok Subscription) OAuth flow.
5
+ *
6
+ * Loopback PKCE flow on `127.0.0.1:56121/callback`. One token unlocks Grok-4.x
7
+ * chat, Grok Imagine image generation, and Grok Voice TTS via subsequent
8
+ * commits. Endpoint discovery is hardened against MITM via
9
+ * {@link validateXAIEndpoint}: any non-HTTPS or non-`x.ai`/`*.x.ai` host is
10
+ * rejected on every call site, not just the first.
11
+ */
12
+
13
+ import * as AIError from "../../error";
14
+ import type { FetchImpl } from "../../types";
15
+ import { OAuthCallbackFlow, type OAuthCallbackFlowOptions } from "./callback-server";
16
+ import { generatePKCE } from "./pkce";
17
+ import type { OAuthController, OAuthCredentials } from "./types";
18
+
19
+ // Hermes hermes_cli/auth.py L93-111
20
+ const XAI_OAUTH_ISSUER = "https://auth.x.ai";
21
+ const XAI_OAUTH_DISCOVERY_URL = `${XAI_OAUTH_ISSUER}/.well-known/openid-configuration`;
22
+ const XAI_OAUTH_CLIENT_ID = "b1a00492-073a-47ea-816f-4c329264a828";
23
+ const XAI_OAUTH_SCOPE = "openid profile email offline_access grok-cli:access api:access";
24
+ const XAI_OAUTH_REDIRECT_HOST = "127.0.0.1";
25
+ const XAI_OAUTH_REDIRECT_PORT = 56121;
26
+ const XAI_OAUTH_REDIRECT_PATH = "/callback";
27
+ const XAI_OAUTH_DOCS_URL = "https://hermes-agent.nousresearch.com/docs/guides/xai-grok-oauth";
28
+
29
+ // Mirrors the 5-min skew used by anthropic.ts:160 — keeps every provider on the
30
+ // same conservative client-side expiry window.
31
+ const ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1000;
32
+
33
+ const DISCOVERY_TIMEOUT_MS = 15_000;
34
+ const TOKEN_REQUEST_TIMEOUT_MS = 20_000;
35
+
36
+ interface XAIOAuthDiscovery {
37
+ authorization_endpoint: string;
38
+ token_endpoint: string;
39
+ }
40
+
41
+ /**
42
+ * Validate an xAI OIDC discovery endpoint against scheme + host.
43
+ *
44
+ * Hermes `_xai_validate_oauth_endpoint` L2997-3035. The discovery response is
45
+ * long-lived and cached in {@link OAuthCredentials}; a single MITM during
46
+ * initial login could substitute a malicious `token_endpoint` that would then
47
+ * receive every future refresh_token. Rejecting non-HTTPS or non-`x.ai` /
48
+ * `*.x.ai` hosts pins the cached endpoint to the xAI auth origin.
49
+ *
50
+ * @throws Error with message `Invalid xAI <field>: <url>` when the URL fails
51
+ * either scheme or host validation.
52
+ */
53
+ export function validateXAIEndpoint(url: string, field: string): string {
54
+ let parsed: URL;
55
+ try {
56
+ parsed = new URL(url);
57
+ } catch {
58
+ throw new AIError.OAuthError(`Invalid xAI ${field}: ${url}`, { kind: "validation", provider: "xai" });
59
+ }
60
+ if (parsed.protocol !== "https:") {
61
+ throw new AIError.OAuthError(`Invalid xAI ${field}: ${url}`, { kind: "validation", provider: "xai" });
62
+ }
63
+ const host = parsed.hostname.toLowerCase();
64
+ if (!host || (host !== "x.ai" && !host.endsWith(".x.ai"))) {
65
+ throw new AIError.OAuthError(`Invalid xAI ${field}: ${url}`, { kind: "validation", provider: "xai" });
66
+ }
67
+ return url;
68
+ }
69
+
70
+ /**
71
+ * Fetch xAI's OIDC discovery document and validate both endpoints.
72
+ *
73
+ * Hermes `_xai_oauth_discovery` L3038-3084.
74
+ */
75
+ async function xaiOAuthDiscovery(
76
+ timeoutMs: number = DISCOVERY_TIMEOUT_MS,
77
+ fetchOverride?: FetchImpl,
78
+ ): Promise<XAIOAuthDiscovery> {
79
+ const fetchImpl = fetchOverride ?? fetch;
80
+ let response: Response;
81
+ try {
82
+ response = await fetchImpl(XAI_OAUTH_DISCOVERY_URL, {
83
+ method: "GET",
84
+ headers: { Accept: "application/json" },
85
+ signal: AbortSignal.timeout(timeoutMs),
86
+ });
87
+ } catch (error) {
88
+ throw new AIError.OAuthError(
89
+ `xAI OIDC discovery failed: ${error instanceof Error ? error.message : String(error)}`,
90
+ {
91
+ kind: "discovery",
92
+ provider: "xai",
93
+ cause: error,
94
+ },
95
+ );
96
+ }
97
+ if (response.status !== 200) {
98
+ throw new AIError.OAuthError(`xAI OIDC discovery returned status ${response.status}.`, {
99
+ kind: "discovery",
100
+ provider: "xai",
101
+ status: response.status,
102
+ });
103
+ }
104
+ let payload: unknown;
105
+ try {
106
+ payload = await response.json();
107
+ } catch (error) {
108
+ throw new AIError.OAuthError(
109
+ `xAI OIDC discovery returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
110
+ { kind: "validation", provider: "xai", cause: error },
111
+ );
112
+ }
113
+ if (!payload || typeof payload !== "object") {
114
+ throw new AIError.OAuthError("xAI OIDC discovery response was not a JSON object.", {
115
+ kind: "validation",
116
+ provider: "xai",
117
+ });
118
+ }
119
+ const obj = payload as Record<string, unknown>;
120
+ const authorizationEndpoint =
121
+ typeof obj.authorization_endpoint === "string" ? obj.authorization_endpoint.trim() : "";
122
+ const tokenEndpoint = typeof obj.token_endpoint === "string" ? obj.token_endpoint.trim() : "";
123
+ if (!authorizationEndpoint || !tokenEndpoint) {
124
+ throw new AIError.OAuthError("xAI OIDC discovery response was missing required endpoints.", {
125
+ kind: "validation",
126
+ provider: "xai",
127
+ });
128
+ }
129
+ validateXAIEndpoint(authorizationEndpoint, "authorization_endpoint");
130
+ validateXAIEndpoint(tokenEndpoint, "token_endpoint");
131
+ return {
132
+ authorization_endpoint: authorizationEndpoint,
133
+ token_endpoint: tokenEndpoint,
134
+ };
135
+ }
136
+
137
+ /**
138
+ * Check whether a JWT access token is at or past its `exp` claim (with an
139
+ * optional refresh-skew margin).
140
+ *
141
+ * Hermes `_xai_access_token_is_expiring` L2979-2994. Returns `false` for any
142
+ * malformed input — this is a refresh-trigger check, not a validation, so
143
+ * non-JWTs ("no token in cache") must NOT trigger a spurious refresh.
144
+ */
145
+ export function isXAIAccessTokenExpiring(jwt: string, skewSeconds: number = 0): boolean {
146
+ try {
147
+ if (typeof jwt !== "string" || !jwt.includes(".")) return false;
148
+ const parts = jwt.split(".");
149
+ if (parts.length < 2) return false;
150
+ const payloadPart = parts[1];
151
+ if (!payloadPart) return false;
152
+ const decoded = Buffer.from(payloadPart, "base64url").toString("utf8");
153
+ const payload = JSON.parse(decoded) as { exp?: unknown };
154
+ const exp = payload.exp;
155
+ if (typeof exp !== "number" || !Number.isFinite(exp)) return false;
156
+ const now = Math.floor(Date.now() / 1000);
157
+ const skew = Math.max(0, Math.floor(skewSeconds));
158
+ return exp <= now + skew;
159
+ } catch {
160
+ return false;
161
+ }
162
+ }
163
+
164
+ interface BuildXAIAuthorizeUrlOptions {
165
+ authorizationEndpoint: string;
166
+ redirectUri: string;
167
+ codeChallenge: string;
168
+ state: string;
169
+ nonce: string;
170
+ }
171
+
172
+ /**
173
+ * Build the xAI authorization URL.
174
+ *
175
+ * Hermes `_xai_oauth_build_authorize_url` L5286-5312. `plan=generic` opts the
176
+ * consent screen into xAI's generic OAuth plan tier; without it,
177
+ * `accounts.x.ai` rejects loopback OAuth from non-allowlisted clients.
178
+ * `referrer=oh-my-pi` lets xAI attribute oh-my-pi-originated logins in their
179
+ * OAuth server logs (Hermes uses `referrer=hermes-agent`; oh-my-pi mirrors the
180
+ * pattern with its own attribution string).
181
+ */
182
+ function buildXAIAuthorizeUrl(opts: BuildXAIAuthorizeUrlOptions): string {
183
+ const params = new URLSearchParams({
184
+ response_type: "code",
185
+ client_id: XAI_OAUTH_CLIENT_ID,
186
+ redirect_uri: opts.redirectUri,
187
+ scope: XAI_OAUTH_SCOPE,
188
+ code_challenge: opts.codeChallenge,
189
+ code_challenge_method: "S256",
190
+ state: opts.state,
191
+ nonce: opts.nonce,
192
+ plan: "generic",
193
+ referrer: "oh-my-pi",
194
+ });
195
+ return `${opts.authorizationEndpoint}?${params.toString()}`;
196
+ }
197
+
198
+ /**
199
+ * xAI Grok OAuth loopback flow (Hermes `_xai_oauth_loopback_login` L5315-5469).
200
+ *
201
+ * Uses a fixed redirect URI so the callback server fails fast instead of
202
+ * falling back to a random port that xAI's redirect_uri allowlist rejects.
203
+ */
204
+ export class XAIOAuthFlow extends OAuthCallbackFlow {
205
+ #verifier: string = "";
206
+ #fetch: FetchImpl;
207
+
208
+ constructor(ctrl: OAuthController) {
209
+ super(ctrl, {
210
+ preferredPort: XAI_OAUTH_REDIRECT_PORT,
211
+ callbackPath: XAI_OAUTH_REDIRECT_PATH,
212
+ callbackHostname: XAI_OAUTH_REDIRECT_HOST,
213
+ redirectUri: `http://${XAI_OAUTH_REDIRECT_HOST}:${XAI_OAUTH_REDIRECT_PORT}${XAI_OAUTH_REDIRECT_PATH}`,
214
+ } satisfies OAuthCallbackFlowOptions);
215
+ this.#fetch = ctrl.fetch ?? fetch;
216
+ }
217
+
218
+ async generateAuthUrl(state: string, redirectUri: string): Promise<{ url: string; instructions?: string }> {
219
+ const pkce = await generatePKCE();
220
+ this.#verifier = pkce.verifier;
221
+ const nonce = crypto.randomUUID().replace(/-/g, "");
222
+
223
+ const discovery = await xaiOAuthDiscovery(DISCOVERY_TIMEOUT_MS, this.#fetch);
224
+ const url = buildXAIAuthorizeUrl({
225
+ authorizationEndpoint: discovery.authorization_endpoint,
226
+ redirectUri,
227
+ codeChallenge: pkce.challenge,
228
+ state,
229
+ nonce,
230
+ });
231
+
232
+ return {
233
+ url,
234
+ instructions: `Complete login in your browser for xAI Grok (SuperGrok). Docs: ${XAI_OAUTH_DOCS_URL}`,
235
+ };
236
+ }
237
+
238
+ async exchangeToken(code: string, _state: string, redirectUri: string): Promise<OAuthCredentials> {
239
+ const discovery = await xaiOAuthDiscovery(DISCOVERY_TIMEOUT_MS, this.#fetch);
240
+ const tokenEndpoint = validateXAIEndpoint(discovery.token_endpoint, "token_endpoint");
241
+
242
+ const body = new URLSearchParams({
243
+ grant_type: "authorization_code",
244
+ client_id: XAI_OAUTH_CLIENT_ID,
245
+ code,
246
+ redirect_uri: redirectUri,
247
+ code_verifier: this.#verifier,
248
+ });
249
+
250
+ const response = await this.#fetch(tokenEndpoint, {
251
+ method: "POST",
252
+ headers: {
253
+ "Content-Type": "application/x-www-form-urlencoded",
254
+ Accept: "application/json",
255
+ },
256
+ body,
257
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS),
258
+ });
259
+
260
+ if (!response.ok) {
261
+ let detail = "";
262
+ try {
263
+ detail = (await response.text()).trim();
264
+ } catch {
265
+ // Ignore body-read failures; the status code is the diagnostic.
266
+ }
267
+ throw new AIError.OAuthError(`xAI token exchange failed: ${response.status}${detail ? ` ${detail}` : ""}`, {
268
+ kind: "token-exchange",
269
+ provider: "xai",
270
+ status: response.status,
271
+ });
272
+ }
273
+
274
+ let tokenData: { access_token?: unknown; refresh_token?: unknown; expires_in?: unknown };
275
+ try {
276
+ tokenData = (await response.json()) as typeof tokenData;
277
+ } catch (error) {
278
+ throw new AIError.OAuthError(
279
+ `xAI token exchange returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
280
+ { kind: "validation", provider: "xai", cause: error },
281
+ );
282
+ }
283
+
284
+ if (typeof tokenData.access_token !== "string" || !tokenData.access_token) {
285
+ throw new AIError.OAuthError("xAI token exchange response missing access_token", {
286
+ kind: "validation",
287
+ provider: "xai",
288
+ });
289
+ }
290
+ if (typeof tokenData.refresh_token !== "string" || !tokenData.refresh_token) {
291
+ throw new AIError.OAuthError("xAI token exchange response missing refresh_token", {
292
+ kind: "validation",
293
+ provider: "xai",
294
+ });
295
+ }
296
+ if (typeof tokenData.expires_in !== "number" || !Number.isFinite(tokenData.expires_in)) {
297
+ throw new AIError.OAuthError("xAI token exchange response missing expires_in", {
298
+ kind: "validation",
299
+ provider: "xai",
300
+ });
301
+ }
302
+
303
+ return {
304
+ access: tokenData.access_token,
305
+ refresh: tokenData.refresh_token,
306
+ expires: Date.now() + tokenData.expires_in * 1000 - ACCESS_TOKEN_CLIENT_SKEW_MS,
307
+ };
308
+ }
309
+ }
310
+
311
+ /**
312
+ * Login with xAI Grok OAuth (SuperGrok Subscription).
313
+ */
314
+ export async function loginXAIOAuth(ctrl: OAuthController): Promise<OAuthCredentials> {
315
+ return new XAIOAuthFlow(ctrl).login();
316
+ }
317
+
318
+ /**
319
+ * Refresh an xAI OAuth access token using a stored refresh_token.
320
+ *
321
+ * Hermes `refresh_xai_oauth_pure` L3087-3160. Re-runs OIDC discovery and
322
+ * re-validates the cached `token_endpoint` on the refresh hot path so a
323
+ * cached-but-poisoned endpoint cannot silently leak a refresh_token.
324
+ */
325
+ export async function refreshXAIOAuthToken(refreshToken: string, fetchOverride?: FetchImpl): Promise<OAuthCredentials> {
326
+ const fetchImpl = fetchOverride ?? fetch;
327
+ if (typeof refreshToken !== "string" || !refreshToken.trim()) {
328
+ throw new AIError.OAuthError("missing refresh_token", { kind: "validation", provider: "xai" });
329
+ }
330
+
331
+ const discovery = await xaiOAuthDiscovery(DISCOVERY_TIMEOUT_MS, fetchImpl);
332
+ const tokenEndpoint = validateXAIEndpoint(discovery.token_endpoint, "token_endpoint");
333
+
334
+ const body = new URLSearchParams({
335
+ grant_type: "refresh_token",
336
+ client_id: XAI_OAUTH_CLIENT_ID,
337
+ refresh_token: refreshToken,
338
+ });
339
+
340
+ const response = await fetchImpl(tokenEndpoint, {
341
+ method: "POST",
342
+ headers: {
343
+ "Content-Type": "application/x-www-form-urlencoded",
344
+ Accept: "application/json",
345
+ },
346
+ body,
347
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS),
348
+ });
349
+
350
+ if (!response.ok) {
351
+ let detail = "";
352
+ try {
353
+ detail = (await response.text()).trim();
354
+ } catch {
355
+ // Ignore body-read failures; the status code is the diagnostic.
356
+ }
357
+ throw new AIError.OAuthError(`xAI token refresh failed: ${response.status}${detail ? ` ${detail}` : ""}`, {
358
+ kind: "token-refresh",
359
+ provider: "xai",
360
+ status: response.status,
361
+ });
362
+ }
363
+
364
+ let data: { access_token?: unknown; refresh_token?: unknown; expires_in?: unknown };
365
+ try {
366
+ data = (await response.json()) as typeof data;
367
+ } catch (error) {
368
+ throw new AIError.OAuthError(
369
+ `xAI token refresh returned invalid JSON: ${error instanceof Error ? error.message : String(error)}`,
370
+ { kind: "validation", provider: "xai", cause: error },
371
+ );
372
+ }
373
+
374
+ if (typeof data.access_token !== "string" || !data.access_token) {
375
+ throw new AIError.OAuthError("xAI token refresh response missing access_token", {
376
+ kind: "validation",
377
+ provider: "xai",
378
+ });
379
+ }
380
+ if (typeof data.expires_in !== "number" || !Number.isFinite(data.expires_in)) {
381
+ throw new AIError.OAuthError("xAI token refresh response missing expires_in", {
382
+ kind: "validation",
383
+ provider: "xai",
384
+ });
385
+ }
386
+
387
+ const newRefresh = typeof data.refresh_token === "string" && data.refresh_token ? data.refresh_token : refreshToken;
388
+
389
+ return {
390
+ access: data.access_token,
391
+ refresh: newRefresh,
392
+ expires: Date.now() + data.expires_in * 1000 - ACCESS_TOKEN_CLIENT_SKEW_MS,
393
+ };
394
+ }
@@ -0,0 +1,211 @@
1
+ /**
2
+ * Xiaomi MiMo login flow.
3
+ *
4
+ * Xiaomi MiMo provides OpenAI-compatible models via
5
+ * https://api.xiaomimimo.com/v1.
6
+ *
7
+ * Standard Xiaomi login opens the pay-as-you-go API key console. Token Plan
8
+ * login opens plan management so users copy the regional `tp-...` key.
9
+ */
10
+
11
+ import * as AIError from "../../error";
12
+ import type { FetchImpl } from "../../types";
13
+ import type { OAuthController } from "./types";
14
+
15
+ const PROVIDER_ID = "xiaomi";
16
+ const PROVIDER_NAME = "Xiaomi MiMo";
17
+ const STANDARD_AUTH_URL = "https://platform.xiaomimimo.com/#/console/api-keys";
18
+ const TOKEN_PLAN_AUTH_URL = "https://platform.xiaomimimo.com/console/plan-manage";
19
+ const STANDARD_API_BASE_URL = "https://api.xiaomimimo.com/v1";
20
+ const TOKEN_PLAN_KEY_PREFIX = "tp-";
21
+ const STANDARD_VALIDATION_MODEL = "mimo-v2.5";
22
+ const TOKEN_PLAN_VALIDATION_MODEL = "mimo-v2.5";
23
+ const TOKEN_PLAN_SGP_API_BASE_URL = "https://token-plan-sgp.xiaomimimo.com/v1";
24
+ const TOKEN_PLAN_AMS_API_BASE_URL = "https://token-plan-ams.xiaomimimo.com/v1";
25
+ const TOKEN_PLAN_CN_API_BASE_URL = "https://token-plan-cn.xiaomimimo.com/v1";
26
+
27
+ /** Region codes accepted by the Xiaomi Token Plan login flow. */
28
+ export type XiaomiTokenPlanRegion = "sgp" | "ams" | "cn";
29
+
30
+ type XiaomiValidationEndpoint = {
31
+ baseUrl: string;
32
+ model: string;
33
+ };
34
+
35
+ const TOKEN_PLAN_VALIDATION_ENDPOINTS: Record<XiaomiTokenPlanRegion, XiaomiValidationEndpoint> = {
36
+ sgp: { baseUrl: TOKEN_PLAN_SGP_API_BASE_URL, model: TOKEN_PLAN_VALIDATION_MODEL },
37
+ ams: { baseUrl: TOKEN_PLAN_AMS_API_BASE_URL, model: TOKEN_PLAN_VALIDATION_MODEL },
38
+ cn: { baseUrl: TOKEN_PLAN_CN_API_BASE_URL, model: TOKEN_PLAN_VALIDATION_MODEL },
39
+ };
40
+
41
+ const TOKEN_PLAN_REGION_NAMES: Record<XiaomiTokenPlanRegion, string> = {
42
+ sgp: "Singapore",
43
+ ams: "Europe",
44
+ cn: "China",
45
+ };
46
+
47
+ function isTokenPlanKey(apiKey: string): boolean {
48
+ return apiKey.startsWith(TOKEN_PLAN_KEY_PREFIX);
49
+ }
50
+
51
+ const VALIDATION_TIMEOUT_MS = 15_000;
52
+
53
+ async function validateXiaomiApiKey(
54
+ apiKey: string,
55
+ tokenPlanRegion: XiaomiTokenPlanRegion | undefined,
56
+ signal?: AbortSignal,
57
+ fetchOverride?: FetchImpl,
58
+ ): Promise<void> {
59
+ const fetchImpl = fetchOverride ?? fetch;
60
+ // Region-specific Token Plan logins must validate against the selected
61
+ // cluster. Generic Xiaomi login keeps the historical SGP → AMS → CN fallback.
62
+ const endpoints = tokenPlanRegion
63
+ ? [TOKEN_PLAN_VALIDATION_ENDPOINTS[tokenPlanRegion]]
64
+ : isTokenPlanKey(apiKey)
65
+ ? [
66
+ TOKEN_PLAN_VALIDATION_ENDPOINTS.sgp,
67
+ TOKEN_PLAN_VALIDATION_ENDPOINTS.ams,
68
+ TOKEN_PLAN_VALIDATION_ENDPOINTS.cn,
69
+ ]
70
+ : [{ baseUrl: STANDARD_API_BASE_URL, model: STANDARD_VALIDATION_MODEL }];
71
+
72
+ let lastError: Error | null = null;
73
+
74
+ for (const ep of endpoints) {
75
+ // Fresh timeout per endpoint so SGP→AMS fallback works after a regional
76
+ // timeout: a shared AbortSignal.timeout would stay aborted and instantly
77
+ // abort the AMS fetch.
78
+ const timeoutSignal = AbortSignal.timeout(VALIDATION_TIMEOUT_MS);
79
+ const requestSignal = signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal;
80
+ try {
81
+ const response = await fetchImpl(`${ep.baseUrl}/chat/completions`, {
82
+ method: "POST",
83
+ headers: {
84
+ "Content-Type": "application/json",
85
+ Authorization: `Bearer ${apiKey}`,
86
+ },
87
+ body: JSON.stringify({
88
+ model: ep.model,
89
+ max_tokens: 1,
90
+ messages: [{ role: "user", content: "ping" }],
91
+ }),
92
+ signal: requestSignal,
93
+ });
94
+
95
+ if (response.ok) {
96
+ return;
97
+ }
98
+
99
+ // 401 means this endpoint didn't accept the key; try the next one
100
+ if (response.status === 401) {
101
+ let details = "";
102
+ try {
103
+ details = (await response.text()).trim();
104
+ } catch {
105
+ // ignore body parse errors, status is enough
106
+ }
107
+ lastError = new AIError.OAuthError(
108
+ details
109
+ ? `${PROVIDER_NAME} API key validation failed (${response.status}): ${details}`
110
+ : `${PROVIDER_NAME} API key validation failed (${response.status})`,
111
+ { kind: "validation", provider: PROVIDER_ID, status: response.status },
112
+ );
113
+ continue;
114
+ }
115
+
116
+ // Non-auth errors are real failures
117
+ let details = "";
118
+ try {
119
+ details = (await response.text()).trim();
120
+ } catch {
121
+ // ignore body parse errors, status is enough
122
+ }
123
+ const message = details
124
+ ? `${PROVIDER_NAME} API key validation failed (${response.status}): ${details}`
125
+ : `${PROVIDER_NAME} API key validation failed (${response.status})`;
126
+ throw new AIError.OAuthError(message, {
127
+ kind: "validation",
128
+ provider: PROVIDER_ID,
129
+ status: response.status,
130
+ });
131
+ } catch (e) {
132
+ // Only re-throw AbortError when the caller explicitly cancelled.
133
+ // Timeout aborts (from AbortSignal.timeout) should fall through to
134
+ // the next endpoint so SGP→AMS fallback works during regional outages.
135
+ if (e instanceof DOMException && e.name === "AbortError" && signal?.aborted) {
136
+ throw e;
137
+ }
138
+ lastError = e instanceof Error ? e : new Error(String(e));
139
+ }
140
+ }
141
+ throw (
142
+ lastError ??
143
+ new AIError.OAuthError(`${PROVIDER_NAME} API key validation failed`, {
144
+ kind: "validation",
145
+ provider: PROVIDER_ID,
146
+ })
147
+ );
148
+ }
149
+
150
+ /**
151
+ * Login to Xiaomi MiMo.
152
+ *
153
+ * Opens browser to API keys page, prompts user to paste their API key.
154
+ * Returns the API key directly (not OAuthCredentials - this isn't OAuth).
155
+ */
156
+ export async function loginXiaomi(options: OAuthController): Promise<string> {
157
+ const fetchImpl = options.fetch ?? fetch;
158
+ if (!options.onPrompt) {
159
+ throw new AIError.OnPromptRequiredError(PROVIDER_NAME);
160
+ }
161
+ options.onAuth?.({
162
+ url: STANDARD_AUTH_URL,
163
+ instructions: "Copy your API key from the Xiaomi MiMo console",
164
+ });
165
+ const apiKey = await options.onPrompt({
166
+ message: "Paste your Xiaomi API key (sk-... or token-plan tp-...)",
167
+ placeholder: "sk-... or tp-...",
168
+ });
169
+ if (options.signal?.aborted) {
170
+ throw new AIError.LoginCancelledError();
171
+ }
172
+ const trimmed = apiKey.trim();
173
+ if (!trimmed) {
174
+ throw new AIError.ApiKeyRequiredError();
175
+ }
176
+
177
+ options.onProgress?.(`Validating ${PROVIDER_ID} API key...`);
178
+ await validateXiaomiApiKey(trimmed, undefined, options.signal, fetchImpl);
179
+ return trimmed;
180
+ }
181
+
182
+ /**
183
+ * Login to a regional Xiaomi Token Plan endpoint.
184
+ *
185
+ * Prompts for a token-plan API key and validates it against the selected region.
186
+ */
187
+ export async function loginXiaomiTokenPlan(options: OAuthController, region: XiaomiTokenPlanRegion): Promise<string> {
188
+ const fetchImpl = options.fetch ?? fetch;
189
+ if (!options.onPrompt) {
190
+ throw new AIError.OnPromptRequiredError(`Xiaomi Token Plan (${TOKEN_PLAN_REGION_NAMES[region]})`);
191
+ }
192
+ options.onAuth?.({
193
+ url: TOKEN_PLAN_AUTH_URL,
194
+ instructions: `Copy your token-plan API key for the ${TOKEN_PLAN_REGION_NAMES[region]} region`,
195
+ });
196
+ const apiKey = await options.onPrompt({
197
+ message: `Paste your Xiaomi Token Plan ${TOKEN_PLAN_REGION_NAMES[region]} API key (tp-...)`,
198
+ placeholder: "tp-...",
199
+ });
200
+ if (options.signal?.aborted) {
201
+ throw new AIError.LoginCancelledError();
202
+ }
203
+ const trimmed = apiKey.trim();
204
+ if (!trimmed) {
205
+ throw new AIError.ApiKeyRequiredError();
206
+ }
207
+
208
+ options.onProgress?.(`Validating Xiaomi Token Plan (${TOKEN_PLAN_REGION_NAMES[region]}) API key...`);
209
+ await validateXiaomiApiKey(trimmed, region, options.signal, fetchImpl);
210
+ return trimmed;
211
+ }