@aryee337/aery-ai 0.2.28 → 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,482 @@
1
+ import { scheduler } from "node:timers/promises";
2
+ import type {
3
+ CredentialRankingStrategy,
4
+ UsageAmount,
5
+ UsageFetchContext,
6
+ UsageFetchParams,
7
+ UsageLimit,
8
+ UsageProvider,
9
+ UsageReport,
10
+ UsageStatus,
11
+ UsageWindow,
12
+ } from "../usage";
13
+ import { isRecord, toNumber } from "../utils";
14
+
15
+ const DEFAULT_ENDPOINT = "https://api.anthropic.com/api/oauth";
16
+ const FIVE_HOURS_MS = 5 * 60 * 60 * 1000;
17
+ const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000;
18
+ const MAX_ATTEMPTS = 3;
19
+ const BASE_RETRY_DELAY_MS = 500;
20
+
21
+ const CLAUDE_HEADERS = {
22
+ accept: "application/json, text/plain, */*",
23
+ "accept-encoding": "gzip, compress, deflate, br",
24
+ "anthropic-beta":
25
+ "claude-code-20250219,oauth-2025-04-20,context-1m-2025-08-07,interleaved-thinking-2025-05-14,redact-thinking-2026-02-12,context-management-2025-06-27,prompt-caching-scope-2026-01-05,mid-conversation-system-2026-04-07,advanced-tool-use-2025-11-20,effort-2025-11-24,extended-cache-ttl-2025-04-11",
26
+ "content-type": "application/json",
27
+ "user-agent": "claude-cli/2.1.160 (external, cli)",
28
+ connection: "keep-alive",
29
+ } as const;
30
+
31
+ function normalizeClaudeBaseUrl(baseUrl?: string): string {
32
+ if (!baseUrl?.trim()) return DEFAULT_ENDPOINT;
33
+ const trimmed = baseUrl.trim().replace(/\/+$/, "");
34
+ const lower = trimmed.toLowerCase();
35
+ if (lower.endsWith("/api/oauth")) return trimmed;
36
+ let url: URL;
37
+ try {
38
+ url = new URL(trimmed);
39
+ } catch {
40
+ return DEFAULT_ENDPOINT;
41
+ }
42
+ let path = url.pathname.replace(/\/+$/, "");
43
+ if (path === "/") path = "";
44
+ if (path.toLowerCase().endsWith("/v1")) {
45
+ path = path.slice(0, -3);
46
+ }
47
+ if (!path) return `${url.origin}/api/oauth`;
48
+ return `${url.origin}${path}/api/oauth`;
49
+ }
50
+
51
+ interface ClaudeUsageBucket {
52
+ utilization?: number;
53
+ resets_at?: string;
54
+ }
55
+
56
+ interface ParsedUsageBucket {
57
+ utilization?: number;
58
+ resetsAt?: number;
59
+ }
60
+ type ClaudeUnifiedWindow = "5h" | "7d";
61
+
62
+ interface ClaudeUsageResponse {
63
+ five_hour?: ClaudeUsageBucket | null;
64
+ seven_day?: ClaudeUsageBucket | null;
65
+ seven_day_opus?: ClaudeUsageBucket | null;
66
+ seven_day_sonnet?: ClaudeUsageBucket | null;
67
+ }
68
+
69
+ type ClaudeUsagePayload = {
70
+ payload: ClaudeUsageResponse;
71
+ orgId?: string;
72
+ };
73
+
74
+ function parseIsoTime(value: string | undefined): number | undefined {
75
+ if (!value) return undefined;
76
+ const parsed = Date.parse(value);
77
+ return Number.isFinite(parsed) ? parsed : undefined;
78
+ }
79
+
80
+ function parseBucket(bucket: unknown): ParsedUsageBucket | undefined {
81
+ if (!isRecord(bucket)) return undefined;
82
+ const utilization = toNumber(bucket.utilization);
83
+ const resetsAt = parseIsoTime(typeof bucket.resets_at === "string" ? bucket.resets_at : undefined);
84
+ if (utilization === undefined && resetsAt === undefined) {
85
+ return undefined;
86
+ }
87
+ return { utilization, resetsAt };
88
+ }
89
+ function parseUnifiedWindow(
90
+ headers: Record<string, string>,
91
+ window: ClaudeUnifiedWindow,
92
+ ): ParsedUsageBucket | undefined {
93
+ const prefix = `anthropic-ratelimit-unified-${window}-`;
94
+ const utilizationFraction = toNumber(headers[`${prefix}utilization`]);
95
+ const resetSeconds = toNumber(headers[`${prefix}reset`]);
96
+ const utilization = utilizationFraction === undefined ? undefined : utilizationFraction * 100;
97
+ const resetsAt = resetSeconds !== undefined && resetSeconds > 0 ? resetSeconds * 1000 : undefined;
98
+ if (utilization === undefined && resetsAt === undefined) {
99
+ return undefined;
100
+ }
101
+ return { utilization, resetsAt };
102
+ }
103
+
104
+ function getPayloadString(payload: Record<string, unknown>, key: string): string | undefined {
105
+ const value = payload[key];
106
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
107
+ }
108
+
109
+ function getNestedPayloadString(payload: Record<string, unknown>, key: string, nestedKey: string): string | undefined {
110
+ const nested = payload[key];
111
+ return isRecord(nested) ? getPayloadString(nested, nestedKey) : undefined;
112
+ }
113
+
114
+ function extractUsageIdentity(payload: ClaudeUsageResponse, orgId?: string): { accountId?: string; email?: string } {
115
+ if (!isRecord(payload)) return { accountId: orgId };
116
+ const accountId =
117
+ getPayloadString(payload, "account_id") ??
118
+ getPayloadString(payload, "accountId") ??
119
+ getPayloadString(payload, "user_id") ??
120
+ getPayloadString(payload, "userId") ??
121
+ getPayloadString(payload, "org_id") ??
122
+ getPayloadString(payload, "orgId") ??
123
+ getNestedPayloadString(payload, "account", "uuid") ??
124
+ getNestedPayloadString(payload, "account", "id") ??
125
+ getNestedPayloadString(payload, "organization", "uuid") ??
126
+ getNestedPayloadString(payload, "organization", "id") ??
127
+ getNestedPayloadString(payload, "user", "uuid") ??
128
+ getNestedPayloadString(payload, "user", "id") ??
129
+ orgId;
130
+ const email =
131
+ getPayloadString(payload, "email") ??
132
+ getPayloadString(payload, "user_email") ??
133
+ getPayloadString(payload, "userEmail") ??
134
+ getNestedPayloadString(payload, "account", "email") ??
135
+ getNestedPayloadString(payload, "user", "email");
136
+ return { accountId, email };
137
+ }
138
+
139
+ function hasUsageData(payload: ClaudeUsageResponse): boolean {
140
+ return (
141
+ parseBucket(payload.five_hour)?.utilization !== undefined ||
142
+ parseBucket(payload.seven_day)?.utilization !== undefined ||
143
+ parseBucket(payload.seven_day_opus)?.utilization !== undefined ||
144
+ parseBucket(payload.seven_day_sonnet)?.utilization !== undefined
145
+ );
146
+ }
147
+
148
+ function isRetryableStatus(status: number): boolean {
149
+ return status === 429 || (status >= 500 && status < 600);
150
+ }
151
+
152
+ function isAbortError(error: unknown, signal?: AbortSignal): boolean {
153
+ if (signal?.aborted) return true;
154
+ if (!isRecord(error)) return false;
155
+ return error.name === "AbortError" || error.name === "TimeoutError";
156
+ }
157
+
158
+ function retryDelayMs(attempt: number, retryAfter: string | null): number {
159
+ const baseline = BASE_RETRY_DELAY_MS * 2 ** attempt;
160
+ if (!retryAfter?.trim()) return baseline;
161
+ const seconds = Number.parseFloat(retryAfter);
162
+ if (Number.isFinite(seconds)) return Math.max(baseline, Math.max(0, seconds * 1000));
163
+ const dateDelay = Date.parse(retryAfter) - Date.now();
164
+ return Number.isFinite(dateDelay) ? Math.max(baseline, Math.max(0, dateDelay)) : baseline;
165
+ }
166
+
167
+ async function waitBeforeRetry(
168
+ attempt: number,
169
+ retryAfter: string | null,
170
+ signal?: AbortSignal,
171
+ retryWait?: UsageFetchContext["retryWait"],
172
+ ): Promise<boolean> {
173
+ if (signal?.aborted) return false;
174
+ if (attempt >= MAX_ATTEMPTS - 1) return false;
175
+ try {
176
+ const delayMs = retryDelayMs(attempt, retryAfter);
177
+ if (retryWait) {
178
+ await retryWait(delayMs, signal);
179
+ } else {
180
+ await scheduler.wait(delayMs, { signal });
181
+ }
182
+ return !signal?.aborted;
183
+ } catch (error) {
184
+ if (isAbortError(error, signal)) return false;
185
+ throw error;
186
+ }
187
+ }
188
+
189
+ async function fetchUsagePayload(
190
+ url: string,
191
+ headers: Record<string, string>,
192
+ ctx: UsageFetchContext,
193
+ signal?: AbortSignal,
194
+ ): Promise<ClaudeUsagePayload | null> {
195
+ if (signal?.aborted) return null;
196
+
197
+ let lastPayload: ClaudeUsageResponse | null = null;
198
+ let lastOrgId: string | undefined;
199
+ for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
200
+ try {
201
+ const response = await ctx.fetch(url, { headers, signal });
202
+ const orgId = response.headers.get("anthropic-organization-id")?.trim() || undefined;
203
+ lastOrgId = orgId ?? lastOrgId;
204
+
205
+ if (!response.ok) {
206
+ const retryable = isRetryableStatus(response.status);
207
+ ctx.logger?.warn("Claude usage fetch failed", {
208
+ status: response.status,
209
+ statusText: response.statusText,
210
+ attempt,
211
+ willRetry: retryable && attempt < MAX_ATTEMPTS - 1,
212
+ });
213
+ if (!retryable) return null;
214
+ const retryAfter = response.headers.get("retry-after");
215
+ if (!(await waitBeforeRetry(attempt, retryAfter, signal, ctx.retryWait))) break;
216
+ continue;
217
+ }
218
+
219
+ const parsed = (await response.json()) as unknown;
220
+ if (isRecord(parsed)) {
221
+ const payload = parsed as ClaudeUsageResponse;
222
+ lastPayload = payload;
223
+ if (hasUsageData(payload)) return { payload, orgId };
224
+ }
225
+
226
+ ctx.logger?.warn("Claude usage response missing usage data", {
227
+ attempt,
228
+ willRetry: attempt < MAX_ATTEMPTS - 1,
229
+ });
230
+ if (!(await waitBeforeRetry(attempt, null, signal, ctx.retryWait))) break;
231
+ } catch (error) {
232
+ if (isAbortError(error, signal)) return null;
233
+ ctx.logger?.warn("Claude usage fetch error", {
234
+ error: String(error),
235
+ attempt,
236
+ willRetry: attempt < MAX_ATTEMPTS - 1,
237
+ });
238
+ if (!(await waitBeforeRetry(attempt, null, signal, ctx.retryWait))) break;
239
+ }
240
+ }
241
+
242
+ return lastPayload ? { payload: lastPayload, orgId: lastOrgId } : null;
243
+ }
244
+
245
+ interface ClaudeProfile {
246
+ uuid?: string;
247
+ email?: string;
248
+ account?: {
249
+ uuid?: string;
250
+ email?: string;
251
+ };
252
+ }
253
+
254
+ function extractProfileIdentity(profile: ClaudeProfile | null): { accountId?: string; email?: string } {
255
+ if (!profile || !isRecord(profile)) return {};
256
+ const account = isRecord(profile.account) ? profile.account : undefined;
257
+ return {
258
+ accountId:
259
+ (typeof profile.uuid === "string" && profile.uuid.trim() ? profile.uuid.trim() : undefined) ??
260
+ (typeof account?.uuid === "string" && account.uuid.trim() ? account.uuid.trim() : undefined),
261
+ email:
262
+ (typeof profile.email === "string" && profile.email.trim() ? profile.email.trim() : undefined) ??
263
+ (typeof account?.email === "string" && account.email.trim() ? account.email.trim() : undefined),
264
+ };
265
+ }
266
+
267
+ async function fetchProfile(
268
+ baseUrl: string,
269
+ headers: Record<string, string>,
270
+ ctx: UsageFetchContext,
271
+ signal?: AbortSignal,
272
+ ): Promise<ClaudeProfile | null> {
273
+ if (signal?.aborted) return null;
274
+ const url = `${baseUrl}/profile`;
275
+ try {
276
+ const response = await ctx.fetch(url, { headers, signal });
277
+ if (!response.ok) return null;
278
+ const payload = (await response.json()) as unknown;
279
+ return isRecord(payload) ? (payload as ClaudeProfile) : null;
280
+ } catch (error) {
281
+ if (isAbortError(error, signal)) return null;
282
+ ctx.logger?.debug("Claude profile fetch error", { error: String(error) });
283
+ return null;
284
+ }
285
+ }
286
+
287
+ function buildUsageAmount(utilization: number | undefined): UsageAmount | undefined {
288
+ if (utilization === undefined) return undefined;
289
+ const clamped = Math.min(Math.max(utilization, 0), 100);
290
+ const usedFraction = clamped / 100;
291
+ return {
292
+ used: clamped,
293
+ limit: 100,
294
+ remaining: Math.max(0, 100 - clamped),
295
+ usedFraction,
296
+ remainingFraction: Math.max(0, 1 - usedFraction),
297
+ unit: "percent",
298
+ };
299
+ }
300
+
301
+ function buildUsageStatus(usedFraction: number | undefined): UsageStatus | undefined {
302
+ if (usedFraction === undefined) return undefined;
303
+ if (usedFraction >= 1) return "exhausted";
304
+ if (usedFraction >= 0.9) return "warning";
305
+ return "ok";
306
+ }
307
+
308
+ function buildUsageLimit(args: {
309
+ id: string;
310
+ label: string;
311
+ windowId: string;
312
+ windowLabel: string;
313
+ durationMs: number;
314
+ bucket: ParsedUsageBucket | undefined;
315
+ provider: "anthropic";
316
+ tier?: string;
317
+ shared?: boolean;
318
+ }): UsageLimit | null {
319
+ if (!args.bucket) return null;
320
+ const amount = buildUsageAmount(args.bucket.utilization);
321
+ if (!amount) return null;
322
+ const window: UsageWindow = {
323
+ id: args.windowId,
324
+ label: args.windowLabel,
325
+ durationMs: args.durationMs,
326
+ ...(args.bucket.resetsAt !== undefined ? { resetsAt: args.bucket.resetsAt } : {}),
327
+ };
328
+ return {
329
+ id: args.id,
330
+ label: args.label,
331
+ scope: {
332
+ provider: args.provider,
333
+ windowId: args.windowId,
334
+ tier: args.tier,
335
+ shared: args.shared,
336
+ },
337
+ window,
338
+ amount,
339
+ status: buildUsageStatus(amount.usedFraction),
340
+ };
341
+ }
342
+
343
+ export function parseClaudeRateLimitHeaders(headers: Record<string, string>, now = Date.now()): UsageReport | null {
344
+ const fiveHour = parseUnifiedWindow(headers, "5h");
345
+ const sevenDay = parseUnifiedWindow(headers, "7d");
346
+ const limits = [
347
+ buildUsageLimit({
348
+ id: "anthropic:5h",
349
+ label: "Claude 5 Hour",
350
+ windowId: "5h",
351
+ windowLabel: "5 Hour",
352
+ durationMs: FIVE_HOURS_MS,
353
+ bucket: fiveHour,
354
+ provider: "anthropic",
355
+ shared: true,
356
+ }),
357
+ buildUsageLimit({
358
+ id: "anthropic:7d",
359
+ label: "Claude 7 Day",
360
+ windowId: "7d",
361
+ windowLabel: "7 Day",
362
+ durationMs: SEVEN_DAYS_MS,
363
+ bucket: sevenDay,
364
+ provider: "anthropic",
365
+ shared: true,
366
+ }),
367
+ ].filter((limit): limit is UsageLimit => limit !== null);
368
+
369
+ if (limits.length === 0) return null;
370
+ return {
371
+ provider: "anthropic",
372
+ fetchedAt: now,
373
+ limits,
374
+ metadata: { source: "ratelimit-headers" },
375
+ };
376
+ }
377
+
378
+ async function fetchClaudeUsage(params: UsageFetchParams, ctx: UsageFetchContext): Promise<UsageReport | null> {
379
+ if (params.provider !== "anthropic") return null;
380
+ const credential = params.credential;
381
+ if (credential.type !== "oauth" || !credential.accessToken) return null;
382
+
383
+ const baseUrl = normalizeClaudeBaseUrl(params.baseUrl);
384
+ const url = `${baseUrl}/usage`;
385
+ const headers: Record<string, string> = {
386
+ ...CLAUDE_HEADERS,
387
+ authorization: `Bearer ${credential.accessToken}`,
388
+ };
389
+
390
+ const payloadResult = await fetchUsagePayload(url, headers, ctx, params.signal);
391
+ if (!payloadResult || !isRecord(payloadResult.payload)) return null;
392
+ const { payload, orgId } = payloadResult;
393
+
394
+ const fiveHour = parseBucket(payload.five_hour);
395
+ const sevenDay = parseBucket(payload.seven_day);
396
+ const sevenDayOpus = parseBucket(payload.seven_day_opus);
397
+ const sevenDaySonnet = parseBucket(payload.seven_day_sonnet);
398
+
399
+ const limits = [
400
+ buildUsageLimit({
401
+ id: "anthropic:5h",
402
+ label: "Claude 5 Hour",
403
+ windowId: "5h",
404
+ windowLabel: "5 Hour",
405
+ durationMs: FIVE_HOURS_MS,
406
+ bucket: fiveHour,
407
+ provider: "anthropic",
408
+ shared: true,
409
+ }),
410
+ buildUsageLimit({
411
+ id: "anthropic:7d",
412
+ label: "Claude 7 Day",
413
+ windowId: "7d",
414
+ windowLabel: "7 Day",
415
+ durationMs: SEVEN_DAYS_MS,
416
+ bucket: sevenDay,
417
+ provider: "anthropic",
418
+ shared: true,
419
+ }),
420
+ buildUsageLimit({
421
+ id: "anthropic:7d:opus",
422
+ label: "Claude 7 Day (Opus)",
423
+ windowId: "7d",
424
+ windowLabel: "7 Day",
425
+ durationMs: SEVEN_DAYS_MS,
426
+ bucket: sevenDayOpus,
427
+ provider: "anthropic",
428
+ tier: "opus",
429
+ }),
430
+ buildUsageLimit({
431
+ id: "anthropic:7d:sonnet",
432
+ label: "Claude 7 Day (Sonnet)",
433
+ windowId: "7d",
434
+ windowLabel: "7 Day",
435
+ durationMs: SEVEN_DAYS_MS,
436
+ bucket: sevenDaySonnet,
437
+ provider: "anthropic",
438
+ tier: "sonnet",
439
+ }),
440
+ ].filter((limit): limit is UsageLimit => limit !== null);
441
+
442
+ if (limits.length === 0) return null;
443
+ const identity = extractUsageIdentity(payload, orgId);
444
+ let accountId = identity.accountId ?? credential.accountId;
445
+ let email = identity.email ?? credential.email;
446
+ if ((!accountId || !email) && !params.signal?.aborted) {
447
+ const profileIdentity = extractProfileIdentity(await fetchProfile(baseUrl, headers, ctx, params.signal));
448
+ accountId = accountId ?? profileIdentity.accountId;
449
+ email = email ?? profileIdentity.email;
450
+ }
451
+
452
+ const report: UsageReport = {
453
+ provider: params.provider,
454
+ fetchedAt: Date.now(),
455
+ limits,
456
+ metadata: {
457
+ endpoint: url,
458
+ ...(accountId ? { accountId } : {}),
459
+ ...(email ? { email } : {}),
460
+ ...(orgId ? { orgId } : {}),
461
+ },
462
+ raw: payload,
463
+ };
464
+
465
+ return report;
466
+ }
467
+
468
+ export const claudeUsageProvider: UsageProvider = {
469
+ id: "anthropic",
470
+ fetchUsage: fetchClaudeUsage,
471
+ parseRateLimitHeaders: parseClaudeRateLimitHeaders,
472
+ supports: params => params.provider === "anthropic" && params.credential.type === "oauth",
473
+ };
474
+
475
+ export const claudeRankingStrategy: CredentialRankingStrategy = {
476
+ findWindowLimits(report) {
477
+ const primary = report.limits.find(l => l.id === "anthropic:5h");
478
+ const secondary = report.limits.find(l => l.id === "anthropic:7d");
479
+ return { primary, secondary };
480
+ },
481
+ windowDefaults: { primaryMs: 5 * 60 * 60 * 1000, secondaryMs: 7 * 24 * 60 * 60 * 1000 },
482
+ };