@aryee337/aery-ai 0.2.27 → 0.2.29

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 (417) hide show
  1. package/CHANGELOG.md +2914 -0
  2. package/README.md +614 -813
  3. package/package.json +140 -105
  4. package/src/api-registry.ts +96 -0
  5. package/src/auth-broker/client.ts +358 -0
  6. package/src/auth-broker/index.ts +5 -0
  7. package/src/auth-broker/refresher.ts +117 -0
  8. package/src/auth-broker/remote-store.ts +623 -0
  9. package/src/auth-broker/server.ts +644 -0
  10. package/src/auth-broker/types.ts +127 -0
  11. package/src/auth-broker/wire-schemas.ts +200 -0
  12. package/src/auth-gateway/http.ts +194 -0
  13. package/src/auth-gateway/index.ts +3 -0
  14. package/src/auth-gateway/server.ts +818 -0
  15. package/src/auth-gateway/types.ts +143 -0
  16. package/src/auth-storage.ts +4422 -0
  17. package/src/index.ts +54 -0
  18. package/src/model-cache.ts +129 -0
  19. package/src/model-manager.ts +469 -0
  20. package/src/model-thinking.ts +782 -0
  21. package/src/models.json +83530 -0
  22. package/src/models.json.d.ts +9 -0
  23. package/src/models.ts +56 -0
  24. package/src/prompts/turn-aborted-guidance.md +4 -0
  25. package/src/provider-details.ts +90 -0
  26. package/src/provider-models/bundled-references.ts +38 -0
  27. package/src/provider-models/descriptors.ts +355 -0
  28. package/src/provider-models/google.ts +88 -0
  29. package/src/provider-models/index.ts +5 -0
  30. package/src/provider-models/ollama.ts +153 -0
  31. package/src/provider-models/openai-compat.ts +2817 -0
  32. package/src/provider-models/special.ts +67 -0
  33. package/src/providers/aery-native-client.ts +228 -0
  34. package/src/providers/aery-native-server.ts +212 -0
  35. package/src/providers/amazon-bedrock.ts +873 -0
  36. package/src/providers/anthropic-client.ts +318 -0
  37. package/src/providers/anthropic-messages-server-schema.ts +243 -0
  38. package/src/providers/anthropic-messages-server.ts +683 -0
  39. package/src/providers/anthropic-wire.ts +268 -0
  40. package/src/providers/anthropic.ts +3094 -0
  41. package/src/providers/aws-credentials.ts +501 -0
  42. package/src/providers/aws-eventstream.ts +185 -0
  43. package/src/providers/aws-sigv4.ts +218 -0
  44. package/src/providers/azure-openai-responses.ts +361 -0
  45. package/src/providers/cursor/gen/agent_pb.ts +15274 -0
  46. package/src/providers/cursor/proto/agent.proto +3526 -0
  47. package/src/providers/cursor/proto/buf.gen.yaml +6 -0
  48. package/src/providers/cursor/proto/buf.yaml +17 -0
  49. package/src/providers/cursor.ts +2621 -0
  50. package/src/providers/error-message.ts +21 -0
  51. package/src/providers/github-copilot-headers.ts +140 -0
  52. package/src/providers/gitlab-duo.ts +372 -0
  53. package/src/providers/google-auth.ts +252 -0
  54. package/src/providers/google-gemini-cli.ts +809 -0
  55. package/src/providers/google-gemini-headers.ts +41 -0
  56. package/src/providers/google-shared.ts +917 -0
  57. package/src/providers/google-types.ts +167 -0
  58. package/src/providers/google-vertex.ts +91 -0
  59. package/src/providers/google.ts +41 -0
  60. package/src/providers/grammar.ts +70 -0
  61. package/src/providers/kimi.ts +52 -0
  62. package/src/providers/mock.ts +496 -0
  63. package/src/providers/ollama.ts +644 -0
  64. package/src/providers/openai-anthropic-shim.ts +138 -0
  65. package/src/providers/openai-chat-server-schema.ts +252 -0
  66. package/src/providers/openai-chat-server.ts +647 -0
  67. package/src/providers/openai-codex/constants.ts +43 -0
  68. package/src/providers/openai-codex/request-transformer.ts +161 -0
  69. package/src/providers/openai-codex/response-handler.ts +81 -0
  70. package/src/providers/openai-codex-responses.ts +3018 -0
  71. package/src/providers/openai-completions-compat.ts +300 -0
  72. package/src/providers/openai-completions.ts +1979 -0
  73. package/src/providers/openai-responses-server-schema.ts +290 -0
  74. package/src/providers/openai-responses-server.ts +1183 -0
  75. package/src/providers/openai-responses-shared.ts +873 -0
  76. package/src/providers/openai-responses.ts +679 -0
  77. package/src/providers/register-builtins.ts +436 -0
  78. package/src/providers/synthetic.ts +50 -0
  79. package/src/providers/transform-messages.ts +382 -0
  80. package/src/providers/vision-guard.ts +31 -0
  81. package/src/providers/xai-responses.ts +82 -0
  82. package/src/rate-limit-utils.ts +84 -0
  83. package/src/stream.ts +1065 -0
  84. package/src/types.ts +944 -0
  85. package/src/usage/claude.ts +482 -0
  86. package/src/usage/gemini.ts +250 -0
  87. package/src/usage/github-copilot.ts +421 -0
  88. package/src/usage/google-antigravity.ts +201 -0
  89. package/src/usage/kimi.ts +271 -0
  90. package/src/usage/minimax-code.ts +31 -0
  91. package/src/usage/openai-codex.ts +503 -0
  92. package/src/usage/shared.ts +10 -0
  93. package/src/usage/zai.ts +247 -0
  94. package/src/usage.ts +185 -0
  95. package/src/utils/abort.ts +51 -0
  96. package/src/utils/abortable-iterator.ts +69 -0
  97. package/src/utils/anthropic-auth.ts +93 -0
  98. package/src/utils/discovery/antigravity.ts +261 -0
  99. package/src/utils/discovery/codex.ts +371 -0
  100. package/src/utils/discovery/cursor.ts +306 -0
  101. package/src/utils/discovery/gemini.ts +248 -0
  102. package/src/utils/discovery/index.ts +4 -0
  103. package/src/utils/discovery/openai-compatible.ts +224 -0
  104. package/src/utils/event-stream.ts +142 -0
  105. package/src/utils/fireworks-model-id.ts +30 -0
  106. package/src/utils/foundry.ts +8 -0
  107. package/src/utils/http-inspector.ts +176 -0
  108. package/src/utils/idle-iterator.ts +267 -0
  109. package/src/utils/json-parse.ts +182 -0
  110. package/src/utils/oauth/__tests__/xai-oauth.test.ts +107 -0
  111. package/src/utils/oauth/alibaba-coding-plan.ts +59 -0
  112. package/src/utils/oauth/anthropic.ts +273 -0
  113. package/src/utils/oauth/api-key-login.ts +87 -0
  114. package/src/utils/oauth/api-key-validation.ts +92 -0
  115. package/src/utils/oauth/callback-server.ts +276 -0
  116. package/src/utils/oauth/cerebras.ts +16 -0
  117. package/src/utils/oauth/cloudflare-ai-gateway.ts +48 -0
  118. package/src/utils/oauth/cursor.ts +157 -0
  119. package/src/utils/oauth/deepseek.ts +53 -0
  120. package/src/utils/oauth/firepass.ts +24 -0
  121. package/src/utils/oauth/fireworks.ts +15 -0
  122. package/src/utils/oauth/github-copilot.ts +362 -0
  123. package/src/utils/oauth/gitlab-duo.ts +123 -0
  124. package/src/utils/oauth/google-antigravity.ts +200 -0
  125. package/src/utils/oauth/google-gemini-cli.ts +256 -0
  126. package/src/utils/oauth/google-oauth-shared.ts +110 -0
  127. package/src/utils/oauth/huggingface.ts +62 -0
  128. package/src/utils/oauth/index.ts +484 -0
  129. package/src/utils/oauth/kagi.ts +47 -0
  130. package/src/utils/oauth/kilo.ts +87 -0
  131. package/src/utils/oauth/kimi.ts +254 -0
  132. package/src/utils/oauth/litellm.ts +47 -0
  133. package/src/utils/oauth/lm-studio.ts +38 -0
  134. package/src/utils/oauth/minimax-code.ts +78 -0
  135. package/src/utils/oauth/moonshot.ts +23 -0
  136. package/src/utils/oauth/nanogpt.ts +15 -0
  137. package/src/utils/oauth/nvidia.ts +70 -0
  138. package/src/utils/oauth/oauth.html +203 -0
  139. package/src/utils/oauth/ollama-cloud.ts +28 -0
  140. package/src/utils/oauth/ollama.ts +47 -0
  141. package/src/utils/oauth/openai-codex.ts +299 -0
  142. package/src/utils/oauth/opencode.ts +49 -0
  143. package/src/utils/oauth/openrouter.ts +20 -0
  144. package/src/utils/oauth/parallel.ts +46 -0
  145. package/src/utils/oauth/perplexity.ts +206 -0
  146. package/src/utils/oauth/pkce.ts +18 -0
  147. package/src/utils/oauth/qianfan.ts +58 -0
  148. package/src/utils/oauth/qwen-portal.ts +60 -0
  149. package/src/utils/oauth/synthetic.ts +15 -0
  150. package/src/utils/oauth/tavily.ts +46 -0
  151. package/src/utils/oauth/together.ts +16 -0
  152. package/src/utils/oauth/types.ts +99 -0
  153. package/src/utils/oauth/venice.ts +59 -0
  154. package/src/utils/oauth/vercel-ai-gateway.ts +47 -0
  155. package/src/utils/oauth/vllm.ts +40 -0
  156. package/src/utils/oauth/wafer.ts +50 -0
  157. package/src/utils/oauth/xai-oauth.ts +342 -0
  158. package/src/utils/oauth/xiaomi.ts +139 -0
  159. package/src/utils/oauth/zai.ts +60 -0
  160. package/src/utils/oauth/zenmux.ts +15 -0
  161. package/src/utils/oauth/zhipu.ts +60 -0
  162. package/src/utils/overflow.ts +137 -0
  163. package/src/utils/parse-bind.ts +54 -0
  164. package/src/utils/provider-response.ts +30 -0
  165. package/src/utils/request-debug.ts +336 -0
  166. package/src/utils/retry-after.ts +110 -0
  167. package/src/utils/retry.ts +54 -0
  168. package/src/utils/schema/CONSTRAINTS.md +164 -0
  169. package/src/utils/schema/adapt.ts +36 -0
  170. package/src/utils/schema/compatibility.ts +435 -0
  171. package/src/utils/schema/dereference.ts +98 -0
  172. package/src/utils/schema/draft.ts +341 -0
  173. package/src/utils/schema/equality.ts +97 -0
  174. package/src/utils/schema/fields.ts +191 -0
  175. package/src/utils/schema/index.ts +13 -0
  176. package/src/utils/schema/json-schema-validator.ts +577 -0
  177. package/src/utils/schema/meta-validator.ts +167 -0
  178. package/src/utils/schema/normalize.ts +1588 -0
  179. package/src/utils/schema/spill.ts +43 -0
  180. package/src/utils/schema/stamps.ts +97 -0
  181. package/src/utils/schema/types.ts +10 -0
  182. package/src/utils/schema/wire.ts +293 -0
  183. package/src/utils/schema/zod-decontaminate.ts +331 -0
  184. package/src/utils/sdk-stream-timeout.ts +43 -0
  185. package/src/utils/sse-debug.ts +289 -0
  186. package/src/utils/stream-markup-healing.ts +612 -0
  187. package/src/utils/tool-choice.ts +99 -0
  188. package/src/utils/validation.ts +1024 -0
  189. package/src/utils.ts +166 -0
  190. package/dist/api-registry.d.ts +0 -20
  191. package/dist/api-registry.d.ts.map +0 -1
  192. package/dist/api-registry.js +0 -44
  193. package/dist/api-registry.js.map +0 -1
  194. package/dist/bedrock-provider.d.ts +0 -5
  195. package/dist/bedrock-provider.d.ts.map +0 -1
  196. package/dist/bedrock-provider.js +0 -6
  197. package/dist/bedrock-provider.js.map +0 -1
  198. package/dist/cli.d.ts +0 -3
  199. package/dist/cli.d.ts.map +0 -1
  200. package/dist/cli.js +0 -130
  201. package/dist/cli.js.map +0 -1
  202. package/dist/env-api-keys.d.ts +0 -18
  203. package/dist/env-api-keys.d.ts.map +0 -1
  204. package/dist/env-api-keys.js +0 -178
  205. package/dist/env-api-keys.js.map +0 -1
  206. package/dist/image-models.d.ts +0 -10
  207. package/dist/image-models.d.ts.map +0 -1
  208. package/dist/image-models.generated.d.ts +0 -440
  209. package/dist/image-models.generated.d.ts.map +0 -1
  210. package/dist/image-models.generated.js +0 -442
  211. package/dist/image-models.generated.js.map +0 -1
  212. package/dist/image-models.js +0 -23
  213. package/dist/image-models.js.map +0 -1
  214. package/dist/images-api-registry.d.ts +0 -14
  215. package/dist/images-api-registry.d.ts.map +0 -1
  216. package/dist/images-api-registry.js +0 -22
  217. package/dist/images-api-registry.js.map +0 -1
  218. package/dist/images.d.ts +0 -4
  219. package/dist/images.d.ts.map +0 -1
  220. package/dist/images.js +0 -14
  221. package/dist/images.js.map +0 -1
  222. package/dist/index.d.ts +0 -32
  223. package/dist/index.d.ts.map +0 -1
  224. package/dist/index.js +0 -20
  225. package/dist/index.js.map +0 -1
  226. package/dist/models.d.ts +0 -18
  227. package/dist/models.d.ts.map +0 -1
  228. package/dist/models.generated.d.ts +0 -17707
  229. package/dist/models.generated.d.ts.map +0 -1
  230. package/dist/models.generated.js +0 -16561
  231. package/dist/models.generated.js.map +0 -1
  232. package/dist/models.js +0 -71
  233. package/dist/models.js.map +0 -1
  234. package/dist/oauth.d.ts +0 -2
  235. package/dist/oauth.d.ts.map +0 -1
  236. package/dist/oauth.js +0 -2
  237. package/dist/oauth.js.map +0 -1
  238. package/dist/providers/aery-error-formatting.d.ts +0 -13
  239. package/dist/providers/aery-error-formatting.d.ts.map +0 -1
  240. package/dist/providers/aery-error-formatting.js +0 -112
  241. package/dist/providers/aery-error-formatting.js.map +0 -1
  242. package/dist/providers/amazon-bedrock.d.ts +0 -38
  243. package/dist/providers/amazon-bedrock.d.ts.map +0 -1
  244. package/dist/providers/amazon-bedrock.js +0 -763
  245. package/dist/providers/amazon-bedrock.js.map +0 -1
  246. package/dist/providers/anthropic.d.ts +0 -71
  247. package/dist/providers/anthropic.d.ts.map +0 -1
  248. package/dist/providers/anthropic.js +0 -949
  249. package/dist/providers/anthropic.js.map +0 -1
  250. package/dist/providers/azure-openai-responses.d.ts +0 -15
  251. package/dist/providers/azure-openai-responses.d.ts.map +0 -1
  252. package/dist/providers/azure-openai-responses.js +0 -225
  253. package/dist/providers/azure-openai-responses.js.map +0 -1
  254. package/dist/providers/cloudflare.d.ts +0 -13
  255. package/dist/providers/cloudflare.d.ts.map +0 -1
  256. package/dist/providers/cloudflare.js +0 -26
  257. package/dist/providers/cloudflare.js.map +0 -1
  258. package/dist/providers/faux.d.ts +0 -56
  259. package/dist/providers/faux.d.ts.map +0 -1
  260. package/dist/providers/faux.js +0 -368
  261. package/dist/providers/faux.js.map +0 -1
  262. package/dist/providers/github-copilot-headers.d.ts +0 -8
  263. package/dist/providers/github-copilot-headers.d.ts.map +0 -1
  264. package/dist/providers/github-copilot-headers.js +0 -29
  265. package/dist/providers/github-copilot-headers.js.map +0 -1
  266. package/dist/providers/google-gemini-cli.d.ts +0 -74
  267. package/dist/providers/google-gemini-cli.d.ts.map +0 -1
  268. package/dist/providers/google-gemini-cli.js +0 -779
  269. package/dist/providers/google-gemini-cli.js.map +0 -1
  270. package/dist/providers/google-shared.d.ts +0 -70
  271. package/dist/providers/google-shared.d.ts.map +0 -1
  272. package/dist/providers/google-shared.js +0 -329
  273. package/dist/providers/google-shared.js.map +0 -1
  274. package/dist/providers/google-vertex.d.ts +0 -15
  275. package/dist/providers/google-vertex.d.ts.map +0 -1
  276. package/dist/providers/google-vertex.js +0 -442
  277. package/dist/providers/google-vertex.js.map +0 -1
  278. package/dist/providers/google.d.ts +0 -13
  279. package/dist/providers/google.d.ts.map +0 -1
  280. package/dist/providers/google.js +0 -400
  281. package/dist/providers/google.js.map +0 -1
  282. package/dist/providers/images/openrouter.d.ts +0 -3
  283. package/dist/providers/images/openrouter.d.ts.map +0 -1
  284. package/dist/providers/images/openrouter.js +0 -129
  285. package/dist/providers/images/openrouter.js.map +0 -1
  286. package/dist/providers/images/register-builtins.d.ts +0 -4
  287. package/dist/providers/images/register-builtins.d.ts.map +0 -1
  288. package/dist/providers/images/register-builtins.js +0 -34
  289. package/dist/providers/images/register-builtins.js.map +0 -1
  290. package/dist/providers/mistral.d.ts +0 -25
  291. package/dist/providers/mistral.d.ts.map +0 -1
  292. package/dist/providers/mistral.js +0 -535
  293. package/dist/providers/mistral.js.map +0 -1
  294. package/dist/providers/openai-codex-responses.d.ts +0 -30
  295. package/dist/providers/openai-codex-responses.d.ts.map +0 -1
  296. package/dist/providers/openai-codex-responses.js +0 -1090
  297. package/dist/providers/openai-codex-responses.js.map +0 -1
  298. package/dist/providers/openai-completions.d.ts +0 -19
  299. package/dist/providers/openai-completions.d.ts.map +0 -1
  300. package/dist/providers/openai-completions.js +0 -950
  301. package/dist/providers/openai-completions.js.map +0 -1
  302. package/dist/providers/openai-prompt-cache.d.ts +0 -3
  303. package/dist/providers/openai-prompt-cache.d.ts.map +0 -1
  304. package/dist/providers/openai-prompt-cache.js +0 -10
  305. package/dist/providers/openai-prompt-cache.js.map +0 -1
  306. package/dist/providers/openai-responses-shared.d.ts +0 -18
  307. package/dist/providers/openai-responses-shared.d.ts.map +0 -1
  308. package/dist/providers/openai-responses-shared.js +0 -492
  309. package/dist/providers/openai-responses-shared.js.map +0 -1
  310. package/dist/providers/openai-responses.d.ts +0 -13
  311. package/dist/providers/openai-responses.d.ts.map +0 -1
  312. package/dist/providers/openai-responses.js +0 -237
  313. package/dist/providers/openai-responses.js.map +0 -1
  314. package/dist/providers/register-builtins.d.ts +0 -38
  315. package/dist/providers/register-builtins.d.ts.map +0 -1
  316. package/dist/providers/register-builtins.js +0 -278
  317. package/dist/providers/register-builtins.js.map +0 -1
  318. package/dist/providers/simple-options.d.ts +0 -8
  319. package/dist/providers/simple-options.d.ts.map +0 -1
  320. package/dist/providers/simple-options.js +0 -41
  321. package/dist/providers/simple-options.js.map +0 -1
  322. package/dist/providers/transform-messages.d.ts +0 -8
  323. package/dist/providers/transform-messages.d.ts.map +0 -1
  324. package/dist/providers/transform-messages.js +0 -184
  325. package/dist/providers/transform-messages.js.map +0 -1
  326. package/dist/session-resources.d.ts +0 -4
  327. package/dist/session-resources.d.ts.map +0 -1
  328. package/dist/session-resources.js +0 -22
  329. package/dist/session-resources.js.map +0 -1
  330. package/dist/stream.d.ts +0 -8
  331. package/dist/stream.d.ts.map +0 -1
  332. package/dist/stream.js +0 -27
  333. package/dist/stream.js.map +0 -1
  334. package/dist/types.d.ts +0 -498
  335. package/dist/types.d.ts.map +0 -1
  336. package/dist/types.js +0 -2
  337. package/dist/types.js.map +0 -1
  338. package/dist/utils/diagnostics.d.ts +0 -19
  339. package/dist/utils/diagnostics.d.ts.map +0 -1
  340. package/dist/utils/diagnostics.js +0 -25
  341. package/dist/utils/diagnostics.js.map +0 -1
  342. package/dist/utils/event-stream.d.ts +0 -21
  343. package/dist/utils/event-stream.d.ts.map +0 -1
  344. package/dist/utils/event-stream.js +0 -81
  345. package/dist/utils/event-stream.js.map +0 -1
  346. package/dist/utils/hash.d.ts +0 -3
  347. package/dist/utils/hash.d.ts.map +0 -1
  348. package/dist/utils/hash.js +0 -14
  349. package/dist/utils/hash.js.map +0 -1
  350. package/dist/utils/headers.d.ts +0 -2
  351. package/dist/utils/headers.d.ts.map +0 -1
  352. package/dist/utils/headers.js +0 -8
  353. package/dist/utils/headers.js.map +0 -1
  354. package/dist/utils/json-parse.d.ts +0 -16
  355. package/dist/utils/json-parse.d.ts.map +0 -1
  356. package/dist/utils/json-parse.js +0 -113
  357. package/dist/utils/json-parse.js.map +0 -1
  358. package/dist/utils/node-http-proxy.d.ts +0 -10
  359. package/dist/utils/node-http-proxy.d.ts.map +0 -1
  360. package/dist/utils/node-http-proxy.js +0 -97
  361. package/dist/utils/node-http-proxy.js.map +0 -1
  362. package/dist/utils/oauth/anthropic.d.ts +0 -25
  363. package/dist/utils/oauth/anthropic.d.ts.map +0 -1
  364. package/dist/utils/oauth/anthropic.js +0 -335
  365. package/dist/utils/oauth/anthropic.js.map +0 -1
  366. package/dist/utils/oauth/device-code.d.ts +0 -19
  367. package/dist/utils/oauth/device-code.d.ts.map +0 -1
  368. package/dist/utils/oauth/device-code.js +0 -55
  369. package/dist/utils/oauth/device-code.js.map +0 -1
  370. package/dist/utils/oauth/github-copilot.d.ts +0 -30
  371. package/dist/utils/oauth/github-copilot.d.ts.map +0 -1
  372. package/dist/utils/oauth/github-copilot.js +0 -268
  373. package/dist/utils/oauth/github-copilot.js.map +0 -1
  374. package/dist/utils/oauth/google-antigravity.d.ts +0 -26
  375. package/dist/utils/oauth/google-antigravity.d.ts.map +0 -1
  376. package/dist/utils/oauth/google-antigravity.js +0 -377
  377. package/dist/utils/oauth/google-antigravity.js.map +0 -1
  378. package/dist/utils/oauth/google-gemini-cli.d.ts +0 -26
  379. package/dist/utils/oauth/google-gemini-cli.d.ts.map +0 -1
  380. package/dist/utils/oauth/google-gemini-cli.js +0 -482
  381. package/dist/utils/oauth/google-gemini-cli.js.map +0 -1
  382. package/dist/utils/oauth/index.d.ts +0 -63
  383. package/dist/utils/oauth/index.d.ts.map +0 -1
  384. package/dist/utils/oauth/index.js +0 -131
  385. package/dist/utils/oauth/index.js.map +0 -1
  386. package/dist/utils/oauth/oauth-page.d.ts +0 -3
  387. package/dist/utils/oauth/oauth-page.d.ts.map +0 -1
  388. package/dist/utils/oauth/oauth-page.js +0 -105
  389. package/dist/utils/oauth/oauth-page.js.map +0 -1
  390. package/dist/utils/oauth/openai-codex.d.ts +0 -34
  391. package/dist/utils/oauth/openai-codex.d.ts.map +0 -1
  392. package/dist/utils/oauth/openai-codex.js +0 -385
  393. package/dist/utils/oauth/openai-codex.js.map +0 -1
  394. package/dist/utils/oauth/pkce.d.ts +0 -13
  395. package/dist/utils/oauth/pkce.d.ts.map +0 -1
  396. package/dist/utils/oauth/pkce.js +0 -31
  397. package/dist/utils/oauth/pkce.js.map +0 -1
  398. package/dist/utils/oauth/types.d.ts +0 -64
  399. package/dist/utils/oauth/types.d.ts.map +0 -1
  400. package/dist/utils/oauth/types.js +0 -2
  401. package/dist/utils/oauth/types.js.map +0 -1
  402. package/dist/utils/overflow.d.ts +0 -56
  403. package/dist/utils/overflow.d.ts.map +0 -1
  404. package/dist/utils/overflow.js +0 -151
  405. package/dist/utils/overflow.js.map +0 -1
  406. package/dist/utils/sanitize-unicode.d.ts +0 -22
  407. package/dist/utils/sanitize-unicode.d.ts.map +0 -1
  408. package/dist/utils/sanitize-unicode.js +0 -26
  409. package/dist/utils/sanitize-unicode.js.map +0 -1
  410. package/dist/utils/typebox-helpers.d.ts +0 -17
  411. package/dist/utils/typebox-helpers.d.ts.map +0 -1
  412. package/dist/utils/typebox-helpers.js +0 -21
  413. package/dist/utils/typebox-helpers.js.map +0 -1
  414. package/dist/utils/validation.d.ts +0 -18
  415. package/dist/utils/validation.d.ts.map +0 -1
  416. package/dist/utils/validation.js +0 -281
  417. package/dist/utils/validation.js.map +0 -1
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Anthropic OAuth flow (Claude Pro/Max)
3
+ */
4
+ import { OAuthCallbackFlow } from "./callback-server";
5
+ import { generatePKCE } from "./pkce";
6
+ import type { OAuthController, OAuthCredentials } from "./types";
7
+
8
+ const decode = (s: string) => atob(s);
9
+ const CLIENT_ID = decode("OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl");
10
+ const AUTHORIZE_URL = "https://claude.ai/oauth/authorize";
11
+ const TOKEN_URL = "https://api.anthropic.com/v1/oauth/token";
12
+ const BOOTSTRAP_URL = "https://api.anthropic.com/api/claude_cli/bootstrap";
13
+ const CLAUDE_CODE_BOOTSTRAP_MODEL = "claude-opus-4-8";
14
+ const CLAUDE_CODE_BOOTSTRAP_USER_AGENT = "claude-code/2.1.160";
15
+ const CALLBACK_PORT = 54545;
16
+ const CALLBACK_PATH = "/callback";
17
+ // Scopes required for direct OAuth-token inference (user:inference) plus account/session management.
18
+ // platform.claude.com/oauth/authorize issues console tokens (org:create_api_key only) and does not
19
+ // grant user:inference — the claude.ai endpoint is required for direct inference access.
20
+ const SCOPES =
21
+ "org:create_api_key user:profile user:inference user:sessions:claude_code user:mcp_servers user:file_upload";
22
+
23
+ function formatErrorDetails(error: unknown): string {
24
+ if (error instanceof Error) {
25
+ const details: string[] = [`${error.name}: ${error.message}`];
26
+ const errorWithCode = error as Error & { code?: string; errno?: number | string; cause?: unknown };
27
+ if (errorWithCode.code) details.push(`code=${errorWithCode.code}`);
28
+ if (typeof errorWithCode.errno !== "undefined") details.push(`errno=${String(errorWithCode.errno)}`);
29
+ if (typeof error.cause !== "undefined") {
30
+ details.push(`cause=${formatErrorDetails(error.cause)}`);
31
+ }
32
+ if (error.stack) {
33
+ details.push(`stack=${error.stack}`);
34
+ }
35
+ return details.join("; ");
36
+ }
37
+ return String(error);
38
+ }
39
+
40
+ async function postJson(
41
+ url: string,
42
+ body: Record<string, string | number>,
43
+ extraHeaders?: Record<string, string>,
44
+ ): Promise<string> {
45
+ const response = await fetch(url, {
46
+ method: "POST",
47
+ headers: {
48
+ // No Accept header: CC omits it on OAuth token requests.
49
+ ...extraHeaders,
50
+ "Content-Type": "application/json",
51
+ },
52
+ body: JSON.stringify(body),
53
+ signal: AbortSignal.timeout(30_000),
54
+ });
55
+
56
+ const responseBody = await response.text();
57
+ if (!response.ok) {
58
+ throw new Error(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`);
59
+ }
60
+ return responseBody;
61
+ }
62
+
63
+ /**
64
+ * Decoded shape of Anthropic's `/v1/oauth/token` response (both
65
+ * `authorization_code` exchange and `refresh_token` refresh return the same
66
+ * envelope). Newer responses inline `account`; older/stale credentials can
67
+ * recover the same identity from `/api/claude_cli/bootstrap`.
68
+ */
69
+ interface AnthropicTokenResponse {
70
+ access_token: string;
71
+ refresh_token: string;
72
+ expires_in: number;
73
+ account?: { uuid?: string; email_address?: string };
74
+ }
75
+
76
+ interface AnthropicBootstrapResponse {
77
+ oauth_account?: {
78
+ account_uuid?: string;
79
+ account_email?: string;
80
+ };
81
+ }
82
+
83
+ function parseOAuthTokenResponse(responseBody: string, operation: string): AnthropicTokenResponse {
84
+ try {
85
+ return JSON.parse(responseBody) as AnthropicTokenResponse;
86
+ } catch (error) {
87
+ throw new Error(
88
+ `Anthropic ${operation} returned invalid JSON. url=${TOKEN_URL}; body=${responseBody}; details=${formatErrorDetails(error)}`,
89
+ );
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Lift the OAuth response's `account: { uuid, email_address }` block onto
95
+ * {@link OAuthCredentials} so downstream identity propagation (e.g.
96
+ * `metadata.user_id.account_uuid`, usage tracking) works without a separate
97
+ * `/api/oauth/profile` round-trip. Returns `undefined` for either field when
98
+ * the response omits it or carries a non-string / empty value.
99
+ */
100
+ function extractAccountFromTokenResponse(data: AnthropicTokenResponse): {
101
+ accountId?: string;
102
+ email?: string;
103
+ } {
104
+ const accountUuid = data.account?.uuid;
105
+ const emailAddress = data.account?.email_address;
106
+ return {
107
+ accountId: typeof accountUuid === "string" && accountUuid.length > 0 ? accountUuid : undefined,
108
+ email: typeof emailAddress === "string" && emailAddress.length > 0 ? emailAddress : undefined,
109
+ };
110
+ }
111
+
112
+ async function fetchBootstrapIdentity(accessToken: string): Promise<{ accountId?: string; email?: string }> {
113
+ const url = `${BOOTSTRAP_URL}?entrypoint=cli&model=${encodeURIComponent(CLAUDE_CODE_BOOTSTRAP_MODEL)}`;
114
+ const response = await fetch(url, {
115
+ method: "GET",
116
+ headers: {
117
+ Accept: "application/json, text/plain, */*",
118
+ Authorization: `Bearer ${accessToken}`,
119
+ "Content-Type": "application/json",
120
+ "User-Agent": CLAUDE_CODE_BOOTSTRAP_USER_AGENT,
121
+ "anthropic-beta": "oauth-2025-04-20",
122
+ },
123
+ signal: AbortSignal.timeout(30_000),
124
+ });
125
+ const responseBody = await response.text();
126
+ if (!response.ok) {
127
+ throw new Error(`HTTP request failed. status=${response.status}; url=${url}; body=${responseBody}`);
128
+ }
129
+ let data: AnthropicBootstrapResponse;
130
+ try {
131
+ data = JSON.parse(responseBody) as AnthropicBootstrapResponse;
132
+ } catch (error) {
133
+ throw new Error(
134
+ `Anthropic bootstrap returned invalid JSON. url=${url}; body=${responseBody}; details=${formatErrorDetails(error)}`,
135
+ );
136
+ }
137
+ const accountUuid = data.oauth_account?.account_uuid;
138
+ const accountEmail = data.oauth_account?.account_email;
139
+ return {
140
+ accountId: typeof accountUuid === "string" && accountUuid.length > 0 ? accountUuid : undefined,
141
+ email: typeof accountEmail === "string" && accountEmail.length > 0 ? accountEmail : undefined,
142
+ };
143
+ }
144
+
145
+ async function resolveAccountIdentity(data: AnthropicTokenResponse): Promise<{ accountId?: string; email?: string }> {
146
+ const identity = extractAccountFromTokenResponse(data);
147
+ if (identity.accountId && identity.email) return identity;
148
+ try {
149
+ const bootstrap = await fetchBootstrapIdentity(data.access_token);
150
+ return {
151
+ accountId: identity.accountId ?? bootstrap.accountId,
152
+ email: identity.email ?? bootstrap.email,
153
+ };
154
+ } catch {
155
+ return identity;
156
+ }
157
+ }
158
+
159
+ export class AnthropicOAuthFlow extends OAuthCallbackFlow {
160
+ #verifier: string = "";
161
+ #challenge: string = "";
162
+
163
+ constructor(ctrl: OAuthController) {
164
+ super(ctrl, CALLBACK_PORT, CALLBACK_PATH);
165
+ }
166
+
167
+ async generateAuthUrl(state: string, redirectUri: string): Promise<{ url: string; instructions?: string }> {
168
+ const pkce = await generatePKCE();
169
+ this.#verifier = pkce.verifier;
170
+ this.#challenge = pkce.challenge;
171
+
172
+ const authParams = new URLSearchParams({
173
+ code: "true",
174
+ client_id: CLIENT_ID,
175
+ response_type: "code",
176
+ redirect_uri: redirectUri,
177
+ scope: SCOPES,
178
+ code_challenge: this.#challenge,
179
+ code_challenge_method: "S256",
180
+ state,
181
+ });
182
+ const url = `${AUTHORIZE_URL}?${authParams.toString()}`;
183
+
184
+ return {
185
+ url,
186
+ instructions:
187
+ "Complete login in your browser. If the browser cannot reach this machine, paste the final redirect URL or authorization code when prompted.",
188
+ };
189
+ }
190
+
191
+ async exchangeToken(code: string, state: string, redirectUri: string): Promise<OAuthCredentials> {
192
+ let exchangeCode = code;
193
+ let exchangeState = state;
194
+ const codeFragmentIndex = code.indexOf("#");
195
+ if (codeFragmentIndex >= 0) {
196
+ exchangeCode = code.slice(0, codeFragmentIndex);
197
+ const codeFragmentState = code.slice(codeFragmentIndex + 1);
198
+ if (codeFragmentState.length > 0) {
199
+ exchangeState = codeFragmentState;
200
+ }
201
+ }
202
+
203
+ let responseBody: string;
204
+ try {
205
+ responseBody = await postJson(TOKEN_URL, {
206
+ grant_type: "authorization_code",
207
+ client_id: CLIENT_ID,
208
+ code: exchangeCode,
209
+ state: exchangeState,
210
+ redirect_uri: redirectUri,
211
+ code_verifier: this.#verifier,
212
+ });
213
+ } catch (error) {
214
+ throw new Error(
215
+ `Token exchange request failed. url=${TOKEN_URL}; redirect_uri=${redirectUri}; response_type=authorization_code; details=${formatErrorDetails(error)}`,
216
+ );
217
+ }
218
+
219
+ const tokenData = parseOAuthTokenResponse(responseBody, "token exchange");
220
+ const { accountId, email } = await resolveAccountIdentity(tokenData);
221
+
222
+ return {
223
+ refresh: tokenData.refresh_token,
224
+ access: tokenData.access_token,
225
+ expires: Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000,
226
+ accountId,
227
+ email,
228
+ };
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Login with Anthropic OAuth
234
+ */
235
+ export async function loginAnthropic(ctrl: OAuthController): Promise<OAuthCredentials> {
236
+ const flow = new AnthropicOAuthFlow(ctrl);
237
+ return flow.login();
238
+ }
239
+
240
+ /**
241
+ * Refresh Anthropic OAuth token
242
+ */
243
+ export async function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials> {
244
+ let responseBody: string;
245
+ try {
246
+ responseBody = await postJson(
247
+ TOKEN_URL,
248
+ {
249
+ grant_type: "refresh_token",
250
+ client_id: CLIENT_ID,
251
+ refresh_token: refreshToken,
252
+ },
253
+ {
254
+ // CC sends these on refresh but not on the initial code exchange
255
+ "anthropic-beta": "oauth-2025-04-20",
256
+ "User-Agent": "anthropic-sdk-typescript/0.94.0 userOAuthProvider",
257
+ },
258
+ );
259
+ } catch (error) {
260
+ throw new Error(`Anthropic token refresh request failed. url=${TOKEN_URL}; details=${formatErrorDetails(error)}`);
261
+ }
262
+
263
+ const data = parseOAuthTokenResponse(responseBody, "token refresh");
264
+ const { accountId, email } = await resolveAccountIdentity(data);
265
+
266
+ return {
267
+ refresh: data.refresh_token || refreshToken,
268
+ access: data.access_token,
269
+ expires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,
270
+ accountId,
271
+ email,
272
+ };
273
+ }
@@ -0,0 +1,87 @@
1
+ /**
2
+ * Shared factory for API-key-paste "login" flows.
3
+ *
4
+ * Several providers (Cerebras, Synthetic, Moonshot, Together, NanoGPT, ZenMux)
5
+ * don't actually implement OAuth — they just ask the user to paste an API key,
6
+ * optionally validate it, and return the trimmed key.
7
+ */
8
+
9
+ import { validateApiKeyAgainstModelsEndpoint, validateOpenAICompatibleApiKey } from "./api-key-validation";
10
+ import type { OAuthController } from "./types";
11
+
12
+ type ChatCompletionsValidation = {
13
+ kind: "chat-completions";
14
+ provider: string;
15
+ baseUrl: string;
16
+ model: string;
17
+ };
18
+
19
+ type ModelsEndpointValidation = {
20
+ kind: "models-endpoint";
21
+ provider: string;
22
+ modelsUrl: string;
23
+ };
24
+
25
+ export type ApiKeyLoginConfig = {
26
+ /** Display name used in error messages, e.g. "Cerebras", "NanoGPT". */
27
+ providerLabel: string;
28
+ /** URL opened in browser for the user to grab their key. */
29
+ authUrl: string;
30
+ /** Instructions shown with the onAuth callback. */
31
+ instructions: string;
32
+ /** Prompt message shown when asking for the key paste. */
33
+ promptMessage: string;
34
+ /** Placeholder string for the prompt (e.g. "sk-...", "csk-..."). */
35
+ placeholder: string;
36
+ /** Validation strategy, or `null` to skip validation. */
37
+ validation: ChatCompletionsValidation | ModelsEndpointValidation | null;
38
+ };
39
+
40
+ export function createApiKeyLogin(config: ApiKeyLoginConfig): (options: OAuthController) => Promise<string> {
41
+ return async function login(options: OAuthController): Promise<string> {
42
+ if (!options.onPrompt) {
43
+ throw new Error(`${config.providerLabel} login requires onPrompt callback`);
44
+ }
45
+
46
+ options.onAuth?.({
47
+ url: config.authUrl,
48
+ instructions: config.instructions,
49
+ });
50
+
51
+ const apiKey = await options.onPrompt({
52
+ message: config.promptMessage,
53
+ placeholder: config.placeholder,
54
+ });
55
+
56
+ if (options.signal?.aborted) {
57
+ throw new Error("Login cancelled");
58
+ }
59
+
60
+ const trimmed = apiKey.trim();
61
+ if (!trimmed) {
62
+ throw new Error("API key is required");
63
+ }
64
+
65
+ if (config.validation) {
66
+ options.onProgress?.("Validating API key...");
67
+ if (config.validation.kind === "chat-completions") {
68
+ await validateOpenAICompatibleApiKey({
69
+ provider: config.validation.provider,
70
+ apiKey: trimmed,
71
+ baseUrl: config.validation.baseUrl,
72
+ model: config.validation.model,
73
+ signal: options.signal,
74
+ });
75
+ } else {
76
+ await validateApiKeyAgainstModelsEndpoint({
77
+ provider: config.validation.provider,
78
+ apiKey: trimmed,
79
+ modelsUrl: config.validation.modelsUrl,
80
+ signal: options.signal,
81
+ });
82
+ }
83
+ }
84
+
85
+ return trimmed;
86
+ };
87
+ }
@@ -0,0 +1,92 @@
1
+ type OpenAICompatibleValidationOptions = {
2
+ provider: string;
3
+ apiKey: string;
4
+ baseUrl: string;
5
+ model: string;
6
+ signal?: AbortSignal;
7
+ };
8
+
9
+ type ModelListValidationOptions = {
10
+ provider: string;
11
+ apiKey: string;
12
+ modelsUrl: string;
13
+ signal?: AbortSignal;
14
+ };
15
+
16
+ const VALIDATION_TIMEOUT_MS = 15_000;
17
+
18
+ /**
19
+ * Validate an API key against an OpenAI-compatible chat completions endpoint.
20
+ *
21
+ * Performs a minimal request to verify credentials and endpoint access.
22
+ */
23
+ export async function validateOpenAICompatibleApiKey(options: OpenAICompatibleValidationOptions): Promise<void> {
24
+ const timeoutSignal = AbortSignal.timeout(VALIDATION_TIMEOUT_MS);
25
+ const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
26
+
27
+ const response = await fetch(`${options.baseUrl}/chat/completions`, {
28
+ method: "POST",
29
+ headers: {
30
+ "Content-Type": "application/json",
31
+ Authorization: `Bearer ${options.apiKey}`,
32
+ },
33
+ body: JSON.stringify({
34
+ model: options.model,
35
+ messages: [{ role: "user", content: "ping" }],
36
+ max_tokens: 1,
37
+ temperature: 0,
38
+ }),
39
+ signal,
40
+ });
41
+
42
+ if (response.ok) {
43
+ return;
44
+ }
45
+
46
+ let details = "";
47
+ try {
48
+ details = (await response.text()).trim();
49
+ } catch {
50
+ // ignore body parse errors, status is enough
51
+ }
52
+
53
+ const message = details
54
+ ? `${options.provider} API key validation failed (${response.status}): ${details}`
55
+ : `${options.provider} API key validation failed (${response.status})`;
56
+ throw new Error(message);
57
+ }
58
+
59
+ /**
60
+ * Validate an API key against a provider models endpoint.
61
+ *
62
+ * Useful for providers where access to specific models may vary by plan and
63
+ * should not block key validation.
64
+ */
65
+ export async function validateApiKeyAgainstModelsEndpoint(options: ModelListValidationOptions): Promise<void> {
66
+ const timeoutSignal = AbortSignal.timeout(VALIDATION_TIMEOUT_MS);
67
+ const signal = options.signal ? AbortSignal.any([options.signal, timeoutSignal]) : timeoutSignal;
68
+
69
+ const response = await fetch(options.modelsUrl, {
70
+ method: "GET",
71
+ headers: {
72
+ Authorization: `Bearer ${options.apiKey}`,
73
+ },
74
+ signal,
75
+ });
76
+
77
+ if (response.ok) {
78
+ return;
79
+ }
80
+
81
+ let details = "";
82
+ try {
83
+ details = (await response.text()).trim();
84
+ } catch {
85
+ // ignore body parse errors, status is enough
86
+ }
87
+
88
+ const message = details
89
+ ? `${options.provider} API key validation failed (${response.status}): ${details}`
90
+ : `${options.provider} API key validation failed (${response.status})`;
91
+ throw new Error(message);
92
+ }