@aryee337/aery-ai 0.1.148 → 0.2.10

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 (592) hide show
  1. package/CHANGELOG.md +2914 -0
  2. package/README.md +614 -813
  3. package/dist/types/api-registry.d.ts +30 -0
  4. package/dist/types/auth-broker/client.d.ts +66 -0
  5. package/dist/types/auth-broker/index.d.ts +5 -0
  6. package/dist/types/auth-broker/refresher.d.ts +25 -0
  7. package/dist/types/auth-broker/remote-store.d.ts +96 -0
  8. package/dist/types/auth-broker/server.d.ts +32 -0
  9. package/dist/types/auth-broker/types.d.ts +105 -0
  10. package/dist/types/auth-broker/wire-schemas.d.ts +412 -0
  11. package/dist/types/auth-gateway/http.d.ts +39 -0
  12. package/dist/types/auth-gateway/index.d.ts +3 -0
  13. package/dist/types/auth-gateway/server.d.ts +36 -0
  14. package/dist/types/auth-gateway/types.d.ts +117 -0
  15. package/dist/types/auth-storage.d.ts +739 -0
  16. package/dist/types/index.d.ts +49 -0
  17. package/dist/types/model-cache.d.ts +17 -0
  18. package/dist/types/model-manager.d.ts +64 -0
  19. package/dist/types/model-thinking.d.ts +100 -0
  20. package/dist/types/models.d.ts +12 -0
  21. package/dist/types/provider-details.d.ts +24 -0
  22. package/dist/types/provider-models/bundled-references.d.ts +4 -0
  23. package/dist/types/provider-models/descriptors.d.ts +50 -0
  24. package/dist/types/provider-models/google.d.ts +24 -0
  25. package/dist/types/provider-models/index.d.ts +5 -0
  26. package/dist/types/provider-models/ollama.d.ts +7 -0
  27. package/dist/types/provider-models/openai-compat.d.ts +296 -0
  28. package/dist/types/provider-models/special.d.ts +16 -0
  29. package/dist/types/providers/aery-native-client.d.ts +13 -0
  30. package/dist/types/providers/aery-native-server.d.ts +68 -0
  31. package/dist/types/providers/amazon-bedrock.d.ts +38 -0
  32. package/dist/types/providers/anthropic-client.d.ts +99 -0
  33. package/dist/types/providers/anthropic-messages-server-schema.d.ts +465 -0
  34. package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
  35. package/dist/types/providers/anthropic-wire.d.ts +262 -0
  36. package/dist/types/providers/anthropic.d.ts +206 -0
  37. package/dist/types/providers/aws-credentials.d.ts +43 -0
  38. package/dist/types/providers/aws-eventstream.d.ts +38 -0
  39. package/dist/types/providers/aws-sigv4.d.ts +55 -0
  40. package/dist/types/providers/azure-openai-responses.d.ts +15 -0
  41. package/dist/types/providers/cursor/gen/agent_pb.d.ts +13022 -0
  42. package/dist/types/providers/cursor.d.ts +43 -0
  43. package/dist/types/providers/error-message.d.ts +27 -0
  44. package/dist/types/providers/github-copilot-headers.d.ts +40 -0
  45. package/dist/types/providers/gitlab-duo.d.ts +27 -0
  46. package/dist/types/providers/google-auth.d.ts +24 -0
  47. package/dist/types/providers/google-gemini-cli.d.ts +81 -0
  48. package/dist/types/providers/google-gemini-headers.d.ts +18 -0
  49. package/dist/types/providers/google-shared.d.ts +171 -0
  50. package/dist/types/providers/google-types.d.ts +138 -0
  51. package/dist/types/providers/google-vertex.d.ts +7 -0
  52. package/dist/types/providers/google.d.ts +4 -0
  53. package/dist/types/providers/grammar.d.ts +1 -0
  54. package/dist/types/providers/kimi.d.ts +27 -0
  55. package/dist/types/providers/mock.d.ts +173 -0
  56. package/dist/types/providers/ollama.d.ts +6 -0
  57. package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
  58. package/dist/types/providers/openai-chat-server-schema.d.ts +817 -0
  59. package/dist/types/providers/openai-chat-server.d.ts +16 -0
  60. package/dist/types/providers/openai-codex/constants.d.ts +26 -0
  61. package/dist/types/providers/openai-codex/request-transformer.d.ts +49 -0
  62. package/dist/types/providers/openai-codex/response-handler.d.ts +17 -0
  63. package/dist/types/providers/openai-codex-responses.d.ts +67 -0
  64. package/dist/types/providers/openai-completions-compat.d.ts +25 -0
  65. package/dist/types/providers/openai-completions.d.ts +54 -0
  66. package/dist/types/providers/openai-responses-server-schema.d.ts +392 -0
  67. package/dist/types/providers/openai-responses-server.d.ts +17 -0
  68. package/dist/types/providers/openai-responses-shared.d.ts +100 -0
  69. package/dist/types/providers/openai-responses.d.ts +66 -0
  70. package/dist/types/providers/register-builtins.d.ts +31 -0
  71. package/dist/types/providers/synthetic.d.ts +26 -0
  72. package/dist/{providers → types/providers}/transform-messages.d.ts +6 -2
  73. package/dist/types/providers/vision-guard.d.ts +8 -0
  74. package/dist/types/providers/xai-responses.d.ts +23 -0
  75. package/dist/types/rate-limit-utils.d.ts +19 -0
  76. package/dist/types/stream.d.ts +28 -0
  77. package/dist/types/types.d.ts +801 -0
  78. package/dist/types/usage/claude.d.ts +4 -0
  79. package/dist/types/usage/gemini.d.ts +2 -0
  80. package/dist/types/usage/github-copilot.d.ts +7 -0
  81. package/dist/types/usage/google-antigravity.d.ts +2 -0
  82. package/dist/types/usage/kimi.d.ts +2 -0
  83. package/dist/types/usage/minimax-code.d.ts +2 -0
  84. package/dist/types/usage/openai-codex.d.ts +3 -0
  85. package/dist/types/usage/shared.d.ts +1 -0
  86. package/dist/types/usage/zai.d.ts +2 -0
  87. package/dist/types/usage.d.ts +260 -0
  88. package/dist/types/utils/abort.d.ts +19 -0
  89. package/dist/types/utils/abortable-iterator.d.ts +4 -0
  90. package/dist/types/utils/anthropic-auth.d.ts +35 -0
  91. package/dist/types/utils/discovery/antigravity.d.ts +61 -0
  92. package/dist/types/utils/discovery/codex.d.ts +38 -0
  93. package/dist/types/utils/discovery/cursor.d.ts +23 -0
  94. package/dist/types/utils/discovery/gemini.d.ts +25 -0
  95. package/dist/types/utils/discovery/index.d.ts +4 -0
  96. package/dist/types/utils/discovery/openai-compatible.d.ts +72 -0
  97. package/dist/types/utils/event-stream.d.ts +28 -0
  98. package/dist/types/utils/fireworks-model-id.d.ts +10 -0
  99. package/dist/types/utils/foundry.d.ts +1 -0
  100. package/dist/types/utils/http-inspector.d.ts +31 -0
  101. package/dist/types/utils/idle-iterator.d.ts +78 -0
  102. package/dist/types/utils/json-parse.d.ts +37 -0
  103. package/dist/types/utils/oauth/__tests__/xai-oauth.test.d.ts +1 -0
  104. package/dist/types/utils/oauth/alibaba-coding-plan.d.ts +18 -0
  105. package/dist/types/utils/oauth/anthropic.d.ts +22 -0
  106. package/dist/types/utils/oauth/api-key-login.d.ts +35 -0
  107. package/dist/types/utils/oauth/api-key-validation.d.ts +27 -0
  108. package/dist/types/utils/oauth/callback-server.d.ts +57 -0
  109. package/dist/types/utils/oauth/cerebras.d.ts +1 -0
  110. package/dist/types/utils/oauth/cloudflare-ai-gateway.d.ts +18 -0
  111. package/dist/types/utils/oauth/cursor.d.ts +15 -0
  112. package/dist/types/utils/oauth/deepseek.d.ts +10 -0
  113. package/dist/types/utils/oauth/firepass.d.ts +1 -0
  114. package/dist/types/utils/oauth/fireworks.d.ts +1 -0
  115. package/dist/types/utils/oauth/github-copilot.d.ts +38 -0
  116. package/dist/types/utils/oauth/gitlab-duo.d.ts +3 -0
  117. package/dist/types/utils/oauth/google-antigravity.d.ts +11 -0
  118. package/dist/types/utils/oauth/google-gemini-cli.d.ts +10 -0
  119. package/dist/types/utils/oauth/google-oauth-shared.d.ts +28 -0
  120. package/dist/types/utils/oauth/huggingface.d.ts +19 -0
  121. package/dist/types/utils/oauth/index.d.ts +38 -0
  122. package/dist/types/utils/oauth/kagi.d.ts +17 -0
  123. package/dist/types/utils/oauth/kilo.d.ts +5 -0
  124. package/dist/types/utils/oauth/kimi.d.ts +21 -0
  125. package/dist/types/utils/oauth/litellm.d.ts +18 -0
  126. package/dist/types/utils/oauth/lm-studio.d.ts +17 -0
  127. package/dist/types/utils/oauth/minimax-code.d.ts +28 -0
  128. package/dist/types/utils/oauth/moonshot.d.ts +1 -0
  129. package/dist/types/utils/oauth/nanogpt.d.ts +1 -0
  130. package/dist/types/utils/oauth/nvidia.d.ts +18 -0
  131. package/dist/types/utils/oauth/ollama-cloud.d.ts +2 -0
  132. package/dist/types/utils/oauth/ollama.d.ts +18 -0
  133. package/dist/types/utils/oauth/openai-codex.d.ts +21 -0
  134. package/dist/types/utils/oauth/opencode.d.ts +18 -0
  135. package/dist/types/utils/oauth/openrouter.d.ts +1 -0
  136. package/dist/types/utils/oauth/parallel.d.ts +17 -0
  137. package/dist/types/utils/oauth/perplexity.d.ts +9 -0
  138. package/dist/{utils → types/utils}/oauth/pkce.d.ts +0 -5
  139. package/dist/types/utils/oauth/qianfan.d.ts +17 -0
  140. package/dist/types/utils/oauth/qwen-portal.d.ts +19 -0
  141. package/dist/types/utils/oauth/synthetic.d.ts +1 -0
  142. package/dist/types/utils/oauth/tavily.d.ts +17 -0
  143. package/dist/types/utils/oauth/together.d.ts +1 -0
  144. package/dist/types/utils/oauth/types.d.ts +44 -0
  145. package/dist/types/utils/oauth/venice.d.ts +18 -0
  146. package/dist/types/utils/oauth/vercel-ai-gateway.d.ts +18 -0
  147. package/dist/types/utils/oauth/vllm.d.ts +16 -0
  148. package/dist/types/utils/oauth/wafer.d.ts +2 -0
  149. package/dist/types/utils/oauth/xai-oauth.d.ts +60 -0
  150. package/dist/types/utils/oauth/xiaomi.d.ts +19 -0
  151. package/dist/types/utils/oauth/zai.d.ts +18 -0
  152. package/dist/types/utils/oauth/zenmux.d.ts +1 -0
  153. package/dist/types/utils/oauth/zhipu.d.ts +18 -0
  154. package/dist/{utils → types/utils}/overflow.d.ts +9 -11
  155. package/dist/types/utils/parse-bind.d.ts +23 -0
  156. package/dist/types/utils/provider-response.d.ts +3 -0
  157. package/dist/types/utils/request-debug.d.ts +29 -0
  158. package/dist/types/utils/retry-after.d.ts +3 -0
  159. package/dist/types/utils/retry.d.ts +26 -0
  160. package/dist/types/utils/schema/adapt.d.ts +24 -0
  161. package/dist/types/utils/schema/compatibility.d.ts +30 -0
  162. package/dist/types/utils/schema/dereference.d.ts +11 -0
  163. package/dist/types/utils/schema/draft.d.ts +10 -0
  164. package/dist/types/utils/schema/equality.d.ts +4 -0
  165. package/dist/types/utils/schema/fields.d.ts +49 -0
  166. package/dist/types/utils/schema/index.d.ts +13 -0
  167. package/dist/types/utils/schema/json-schema-validator.d.ts +12 -0
  168. package/dist/types/utils/schema/meta-validator.d.ts +2 -0
  169. package/dist/types/utils/schema/normalize.d.ts +93 -0
  170. package/dist/types/utils/schema/spill.d.ts +8 -0
  171. package/dist/types/utils/schema/stamps.d.ts +25 -0
  172. package/dist/types/utils/schema/types.d.ts +4 -0
  173. package/dist/types/utils/schema/wire.d.ts +53 -0
  174. package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -0
  175. package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
  176. package/dist/types/utils/sse-debug.d.ts +10 -0
  177. package/dist/types/utils/stream-markup-healing.d.ts +80 -0
  178. package/dist/types/utils/tool-choice.d.ts +50 -0
  179. package/dist/types/utils/validation.d.ts +17 -0
  180. package/dist/types/utils.d.ts +28 -0
  181. package/package.json +139 -105
  182. package/src/api-registry.ts +96 -0
  183. package/src/auth-broker/client.ts +358 -0
  184. package/src/auth-broker/index.ts +5 -0
  185. package/src/auth-broker/refresher.ts +117 -0
  186. package/src/auth-broker/remote-store.ts +623 -0
  187. package/src/auth-broker/server.ts +644 -0
  188. package/src/auth-broker/types.ts +127 -0
  189. package/src/auth-broker/wire-schemas.ts +200 -0
  190. package/src/auth-gateway/http.ts +194 -0
  191. package/src/auth-gateway/index.ts +3 -0
  192. package/src/auth-gateway/server.ts +818 -0
  193. package/src/auth-gateway/types.ts +143 -0
  194. package/src/auth-storage.ts +4422 -0
  195. package/src/index.ts +54 -0
  196. package/src/model-cache.ts +129 -0
  197. package/src/model-manager.ts +469 -0
  198. package/src/model-thinking.ts +782 -0
  199. package/src/models.json +83530 -0
  200. package/src/models.json.d.ts +9 -0
  201. package/src/models.ts +56 -0
  202. package/src/prompts/turn-aborted-guidance.md +4 -0
  203. package/src/provider-details.ts +90 -0
  204. package/src/provider-models/bundled-references.ts +38 -0
  205. package/src/provider-models/descriptors.ts +355 -0
  206. package/src/provider-models/google.ts +88 -0
  207. package/src/provider-models/index.ts +5 -0
  208. package/src/provider-models/ollama.ts +153 -0
  209. package/src/provider-models/openai-compat.ts +2817 -0
  210. package/src/provider-models/special.ts +67 -0
  211. package/src/providers/aery-native-client.ts +228 -0
  212. package/src/providers/aery-native-server.ts +212 -0
  213. package/src/providers/amazon-bedrock.ts +873 -0
  214. package/src/providers/anthropic-client.ts +318 -0
  215. package/src/providers/anthropic-messages-server-schema.ts +243 -0
  216. package/src/providers/anthropic-messages-server.ts +683 -0
  217. package/src/providers/anthropic-wire.ts +268 -0
  218. package/src/providers/anthropic.ts +3094 -0
  219. package/src/providers/aws-credentials.ts +501 -0
  220. package/src/providers/aws-eventstream.ts +185 -0
  221. package/src/providers/aws-sigv4.ts +218 -0
  222. package/src/providers/azure-openai-responses.ts +361 -0
  223. package/src/providers/cursor/gen/agent_pb.ts +15274 -0
  224. package/src/providers/cursor/proto/agent.proto +3526 -0
  225. package/src/providers/cursor/proto/buf.gen.yaml +6 -0
  226. package/src/providers/cursor/proto/buf.yaml +17 -0
  227. package/src/providers/cursor.ts +2621 -0
  228. package/src/providers/error-message.ts +21 -0
  229. package/src/providers/github-copilot-headers.ts +140 -0
  230. package/src/providers/gitlab-duo.ts +372 -0
  231. package/src/providers/google-auth.ts +252 -0
  232. package/src/providers/google-gemini-cli.ts +809 -0
  233. package/src/providers/google-gemini-headers.ts +41 -0
  234. package/src/providers/google-shared.ts +917 -0
  235. package/src/providers/google-types.ts +167 -0
  236. package/src/providers/google-vertex.ts +91 -0
  237. package/src/providers/google.ts +41 -0
  238. package/src/providers/grammar.ts +70 -0
  239. package/src/providers/kimi.ts +52 -0
  240. package/src/providers/mock.ts +496 -0
  241. package/src/providers/ollama.ts +644 -0
  242. package/src/providers/openai-anthropic-shim.ts +138 -0
  243. package/src/providers/openai-chat-server-schema.ts +252 -0
  244. package/src/providers/openai-chat-server.ts +647 -0
  245. package/src/providers/openai-codex/constants.ts +43 -0
  246. package/src/providers/openai-codex/request-transformer.ts +161 -0
  247. package/src/providers/openai-codex/response-handler.ts +81 -0
  248. package/src/providers/openai-codex-responses.ts +3018 -0
  249. package/src/providers/openai-completions-compat.ts +300 -0
  250. package/src/providers/openai-completions.ts +1979 -0
  251. package/src/providers/openai-responses-server-schema.ts +290 -0
  252. package/src/providers/openai-responses-server.ts +1183 -0
  253. package/src/providers/openai-responses-shared.ts +873 -0
  254. package/src/providers/openai-responses.ts +679 -0
  255. package/src/providers/register-builtins.ts +436 -0
  256. package/src/providers/synthetic.ts +50 -0
  257. package/src/providers/transform-messages.ts +382 -0
  258. package/src/providers/vision-guard.ts +31 -0
  259. package/src/providers/xai-responses.ts +82 -0
  260. package/src/rate-limit-utils.ts +84 -0
  261. package/src/stream.ts +1065 -0
  262. package/src/types.ts +944 -0
  263. package/src/usage/claude.ts +482 -0
  264. package/src/usage/gemini.ts +250 -0
  265. package/src/usage/github-copilot.ts +421 -0
  266. package/src/usage/google-antigravity.ts +201 -0
  267. package/src/usage/kimi.ts +271 -0
  268. package/src/usage/minimax-code.ts +31 -0
  269. package/src/usage/openai-codex.ts +503 -0
  270. package/src/usage/shared.ts +10 -0
  271. package/src/usage/zai.ts +247 -0
  272. package/src/usage.ts +185 -0
  273. package/src/utils/abort.ts +51 -0
  274. package/src/utils/abortable-iterator.ts +69 -0
  275. package/src/utils/anthropic-auth.ts +93 -0
  276. package/src/utils/discovery/antigravity.ts +261 -0
  277. package/src/utils/discovery/codex.ts +371 -0
  278. package/src/utils/discovery/cursor.ts +306 -0
  279. package/src/utils/discovery/gemini.ts +248 -0
  280. package/src/utils/discovery/index.ts +4 -0
  281. package/src/utils/discovery/openai-compatible.ts +224 -0
  282. package/src/utils/event-stream.ts +142 -0
  283. package/src/utils/fireworks-model-id.ts +30 -0
  284. package/src/utils/foundry.ts +8 -0
  285. package/src/utils/http-inspector.ts +176 -0
  286. package/src/utils/idle-iterator.ts +267 -0
  287. package/src/utils/json-parse.ts +182 -0
  288. package/src/utils/oauth/__tests__/xai-oauth.test.ts +107 -0
  289. package/src/utils/oauth/alibaba-coding-plan.ts +59 -0
  290. package/src/utils/oauth/anthropic.ts +273 -0
  291. package/src/utils/oauth/api-key-login.ts +87 -0
  292. package/src/utils/oauth/api-key-validation.ts +92 -0
  293. package/src/utils/oauth/callback-server.ts +276 -0
  294. package/src/utils/oauth/cerebras.ts +16 -0
  295. package/src/utils/oauth/cloudflare-ai-gateway.ts +48 -0
  296. package/src/utils/oauth/cursor.ts +157 -0
  297. package/src/utils/oauth/deepseek.ts +53 -0
  298. package/src/utils/oauth/firepass.ts +24 -0
  299. package/src/utils/oauth/fireworks.ts +15 -0
  300. package/src/utils/oauth/github-copilot.ts +362 -0
  301. package/src/utils/oauth/gitlab-duo.ts +123 -0
  302. package/src/utils/oauth/google-antigravity.ts +200 -0
  303. package/src/utils/oauth/google-gemini-cli.ts +256 -0
  304. package/src/utils/oauth/google-oauth-shared.ts +110 -0
  305. package/src/utils/oauth/huggingface.ts +62 -0
  306. package/src/utils/oauth/index.ts +484 -0
  307. package/src/utils/oauth/kagi.ts +47 -0
  308. package/src/utils/oauth/kilo.ts +87 -0
  309. package/src/utils/oauth/kimi.ts +254 -0
  310. package/src/utils/oauth/litellm.ts +47 -0
  311. package/src/utils/oauth/lm-studio.ts +38 -0
  312. package/src/utils/oauth/minimax-code.ts +78 -0
  313. package/src/utils/oauth/moonshot.ts +23 -0
  314. package/src/utils/oauth/nanogpt.ts +15 -0
  315. package/src/utils/oauth/nvidia.ts +70 -0
  316. package/src/utils/oauth/oauth.html +203 -0
  317. package/src/utils/oauth/ollama-cloud.ts +28 -0
  318. package/src/utils/oauth/ollama.ts +47 -0
  319. package/src/utils/oauth/openai-codex.ts +299 -0
  320. package/src/utils/oauth/opencode.ts +49 -0
  321. package/src/utils/oauth/openrouter.ts +20 -0
  322. package/src/utils/oauth/parallel.ts +46 -0
  323. package/src/utils/oauth/perplexity.ts +206 -0
  324. package/src/utils/oauth/pkce.ts +18 -0
  325. package/src/utils/oauth/qianfan.ts +58 -0
  326. package/src/utils/oauth/qwen-portal.ts +60 -0
  327. package/src/utils/oauth/synthetic.ts +15 -0
  328. package/src/utils/oauth/tavily.ts +46 -0
  329. package/src/utils/oauth/together.ts +16 -0
  330. package/src/utils/oauth/types.ts +99 -0
  331. package/src/utils/oauth/venice.ts +59 -0
  332. package/src/utils/oauth/vercel-ai-gateway.ts +47 -0
  333. package/src/utils/oauth/vllm.ts +40 -0
  334. package/src/utils/oauth/wafer.ts +50 -0
  335. package/src/utils/oauth/xai-oauth.ts +342 -0
  336. package/src/utils/oauth/xiaomi.ts +139 -0
  337. package/src/utils/oauth/zai.ts +60 -0
  338. package/src/utils/oauth/zenmux.ts +15 -0
  339. package/src/utils/oauth/zhipu.ts +60 -0
  340. package/src/utils/overflow.ts +137 -0
  341. package/src/utils/parse-bind.ts +54 -0
  342. package/src/utils/provider-response.ts +30 -0
  343. package/src/utils/request-debug.ts +336 -0
  344. package/src/utils/retry-after.ts +110 -0
  345. package/src/utils/retry.ts +54 -0
  346. package/src/utils/schema/CONSTRAINTS.md +164 -0
  347. package/src/utils/schema/adapt.ts +36 -0
  348. package/src/utils/schema/compatibility.ts +435 -0
  349. package/src/utils/schema/dereference.ts +98 -0
  350. package/src/utils/schema/draft.ts +341 -0
  351. package/src/utils/schema/equality.ts +97 -0
  352. package/src/utils/schema/fields.ts +191 -0
  353. package/src/utils/schema/index.ts +13 -0
  354. package/src/utils/schema/json-schema-validator.ts +577 -0
  355. package/src/utils/schema/meta-validator.ts +167 -0
  356. package/src/utils/schema/normalize.ts +1588 -0
  357. package/src/utils/schema/spill.ts +43 -0
  358. package/src/utils/schema/stamps.ts +97 -0
  359. package/src/utils/schema/types.ts +10 -0
  360. package/src/utils/schema/wire.ts +293 -0
  361. package/src/utils/schema/zod-decontaminate.ts +331 -0
  362. package/src/utils/sdk-stream-timeout.ts +43 -0
  363. package/src/utils/sse-debug.ts +289 -0
  364. package/src/utils/stream-markup-healing.ts +612 -0
  365. package/src/utils/tool-choice.ts +99 -0
  366. package/src/utils/validation.ts +1024 -0
  367. package/src/utils.ts +166 -0
  368. package/dist/api-registry.d.ts +0 -20
  369. package/dist/api-registry.d.ts.map +0 -1
  370. package/dist/api-registry.js +0 -44
  371. package/dist/api-registry.js.map +0 -1
  372. package/dist/bedrock-provider.d.ts +0 -5
  373. package/dist/bedrock-provider.d.ts.map +0 -1
  374. package/dist/bedrock-provider.js +0 -6
  375. package/dist/bedrock-provider.js.map +0 -1
  376. package/dist/cli.d.ts +0 -3
  377. package/dist/cli.d.ts.map +0 -1
  378. package/dist/cli.js +0 -130
  379. package/dist/cli.js.map +0 -1
  380. package/dist/env-api-keys.d.ts +0 -18
  381. package/dist/env-api-keys.d.ts.map +0 -1
  382. package/dist/env-api-keys.js +0 -178
  383. package/dist/env-api-keys.js.map +0 -1
  384. package/dist/image-models.d.ts +0 -10
  385. package/dist/image-models.d.ts.map +0 -1
  386. package/dist/image-models.generated.d.ts +0 -440
  387. package/dist/image-models.generated.d.ts.map +0 -1
  388. package/dist/image-models.generated.js +0 -442
  389. package/dist/image-models.generated.js.map +0 -1
  390. package/dist/image-models.js +0 -23
  391. package/dist/image-models.js.map +0 -1
  392. package/dist/images-api-registry.d.ts +0 -14
  393. package/dist/images-api-registry.d.ts.map +0 -1
  394. package/dist/images-api-registry.js +0 -22
  395. package/dist/images-api-registry.js.map +0 -1
  396. package/dist/images.d.ts +0 -4
  397. package/dist/images.d.ts.map +0 -1
  398. package/dist/images.js +0 -14
  399. package/dist/images.js.map +0 -1
  400. package/dist/index.d.ts +0 -32
  401. package/dist/index.d.ts.map +0 -1
  402. package/dist/index.js +0 -20
  403. package/dist/index.js.map +0 -1
  404. package/dist/models.d.ts +0 -18
  405. package/dist/models.d.ts.map +0 -1
  406. package/dist/models.generated.d.ts +0 -17480
  407. package/dist/models.generated.d.ts.map +0 -1
  408. package/dist/models.generated.js +0 -16339
  409. package/dist/models.generated.js.map +0 -1
  410. package/dist/models.js +0 -71
  411. package/dist/models.js.map +0 -1
  412. package/dist/oauth.d.ts +0 -2
  413. package/dist/oauth.d.ts.map +0 -1
  414. package/dist/oauth.js +0 -2
  415. package/dist/oauth.js.map +0 -1
  416. package/dist/providers/aery-error-formatting.d.ts +0 -13
  417. package/dist/providers/aery-error-formatting.d.ts.map +0 -1
  418. package/dist/providers/aery-error-formatting.js +0 -112
  419. package/dist/providers/aery-error-formatting.js.map +0 -1
  420. package/dist/providers/amazon-bedrock.d.ts +0 -38
  421. package/dist/providers/amazon-bedrock.d.ts.map +0 -1
  422. package/dist/providers/amazon-bedrock.js +0 -763
  423. package/dist/providers/amazon-bedrock.js.map +0 -1
  424. package/dist/providers/anthropic.d.ts +0 -71
  425. package/dist/providers/anthropic.d.ts.map +0 -1
  426. package/dist/providers/anthropic.js +0 -949
  427. package/dist/providers/anthropic.js.map +0 -1
  428. package/dist/providers/azure-openai-responses.d.ts +0 -15
  429. package/dist/providers/azure-openai-responses.d.ts.map +0 -1
  430. package/dist/providers/azure-openai-responses.js +0 -225
  431. package/dist/providers/azure-openai-responses.js.map +0 -1
  432. package/dist/providers/cloudflare.d.ts +0 -13
  433. package/dist/providers/cloudflare.d.ts.map +0 -1
  434. package/dist/providers/cloudflare.js +0 -26
  435. package/dist/providers/cloudflare.js.map +0 -1
  436. package/dist/providers/faux.d.ts +0 -56
  437. package/dist/providers/faux.d.ts.map +0 -1
  438. package/dist/providers/faux.js +0 -368
  439. package/dist/providers/faux.js.map +0 -1
  440. package/dist/providers/github-copilot-headers.d.ts +0 -8
  441. package/dist/providers/github-copilot-headers.d.ts.map +0 -1
  442. package/dist/providers/github-copilot-headers.js +0 -29
  443. package/dist/providers/github-copilot-headers.js.map +0 -1
  444. package/dist/providers/google-gemini-cli.d.ts +0 -74
  445. package/dist/providers/google-gemini-cli.d.ts.map +0 -1
  446. package/dist/providers/google-gemini-cli.js +0 -779
  447. package/dist/providers/google-gemini-cli.js.map +0 -1
  448. package/dist/providers/google-shared.d.ts +0 -70
  449. package/dist/providers/google-shared.d.ts.map +0 -1
  450. package/dist/providers/google-shared.js +0 -329
  451. package/dist/providers/google-shared.js.map +0 -1
  452. package/dist/providers/google-vertex.d.ts +0 -15
  453. package/dist/providers/google-vertex.d.ts.map +0 -1
  454. package/dist/providers/google-vertex.js +0 -442
  455. package/dist/providers/google-vertex.js.map +0 -1
  456. package/dist/providers/google.d.ts +0 -13
  457. package/dist/providers/google.d.ts.map +0 -1
  458. package/dist/providers/google.js +0 -400
  459. package/dist/providers/google.js.map +0 -1
  460. package/dist/providers/images/openrouter.d.ts +0 -3
  461. package/dist/providers/images/openrouter.d.ts.map +0 -1
  462. package/dist/providers/images/openrouter.js +0 -129
  463. package/dist/providers/images/openrouter.js.map +0 -1
  464. package/dist/providers/images/register-builtins.d.ts +0 -4
  465. package/dist/providers/images/register-builtins.d.ts.map +0 -1
  466. package/dist/providers/images/register-builtins.js +0 -34
  467. package/dist/providers/images/register-builtins.js.map +0 -1
  468. package/dist/providers/mistral.d.ts +0 -25
  469. package/dist/providers/mistral.d.ts.map +0 -1
  470. package/dist/providers/mistral.js +0 -535
  471. package/dist/providers/mistral.js.map +0 -1
  472. package/dist/providers/openai-codex-responses.d.ts +0 -30
  473. package/dist/providers/openai-codex-responses.d.ts.map +0 -1
  474. package/dist/providers/openai-codex-responses.js +0 -1090
  475. package/dist/providers/openai-codex-responses.js.map +0 -1
  476. package/dist/providers/openai-completions.d.ts +0 -19
  477. package/dist/providers/openai-completions.d.ts.map +0 -1
  478. package/dist/providers/openai-completions.js +0 -950
  479. package/dist/providers/openai-completions.js.map +0 -1
  480. package/dist/providers/openai-prompt-cache.d.ts +0 -3
  481. package/dist/providers/openai-prompt-cache.d.ts.map +0 -1
  482. package/dist/providers/openai-prompt-cache.js +0 -10
  483. package/dist/providers/openai-prompt-cache.js.map +0 -1
  484. package/dist/providers/openai-responses-shared.d.ts +0 -18
  485. package/dist/providers/openai-responses-shared.d.ts.map +0 -1
  486. package/dist/providers/openai-responses-shared.js +0 -492
  487. package/dist/providers/openai-responses-shared.js.map +0 -1
  488. package/dist/providers/openai-responses.d.ts +0 -13
  489. package/dist/providers/openai-responses.d.ts.map +0 -1
  490. package/dist/providers/openai-responses.js +0 -237
  491. package/dist/providers/openai-responses.js.map +0 -1
  492. package/dist/providers/register-builtins.d.ts +0 -38
  493. package/dist/providers/register-builtins.d.ts.map +0 -1
  494. package/dist/providers/register-builtins.js +0 -278
  495. package/dist/providers/register-builtins.js.map +0 -1
  496. package/dist/providers/simple-options.d.ts +0 -8
  497. package/dist/providers/simple-options.d.ts.map +0 -1
  498. package/dist/providers/simple-options.js +0 -41
  499. package/dist/providers/simple-options.js.map +0 -1
  500. package/dist/providers/transform-messages.d.ts.map +0 -1
  501. package/dist/providers/transform-messages.js +0 -184
  502. package/dist/providers/transform-messages.js.map +0 -1
  503. package/dist/session-resources.d.ts +0 -4
  504. package/dist/session-resources.d.ts.map +0 -1
  505. package/dist/session-resources.js +0 -22
  506. package/dist/session-resources.js.map +0 -1
  507. package/dist/stream.d.ts +0 -8
  508. package/dist/stream.d.ts.map +0 -1
  509. package/dist/stream.js +0 -27
  510. package/dist/stream.js.map +0 -1
  511. package/dist/types.d.ts +0 -498
  512. package/dist/types.d.ts.map +0 -1
  513. package/dist/types.js +0 -2
  514. package/dist/types.js.map +0 -1
  515. package/dist/utils/diagnostics.d.ts +0 -19
  516. package/dist/utils/diagnostics.d.ts.map +0 -1
  517. package/dist/utils/diagnostics.js +0 -25
  518. package/dist/utils/diagnostics.js.map +0 -1
  519. package/dist/utils/event-stream.d.ts +0 -21
  520. package/dist/utils/event-stream.d.ts.map +0 -1
  521. package/dist/utils/event-stream.js +0 -81
  522. package/dist/utils/event-stream.js.map +0 -1
  523. package/dist/utils/hash.d.ts +0 -3
  524. package/dist/utils/hash.d.ts.map +0 -1
  525. package/dist/utils/hash.js +0 -14
  526. package/dist/utils/hash.js.map +0 -1
  527. package/dist/utils/headers.d.ts +0 -2
  528. package/dist/utils/headers.d.ts.map +0 -1
  529. package/dist/utils/headers.js +0 -8
  530. package/dist/utils/headers.js.map +0 -1
  531. package/dist/utils/json-parse.d.ts +0 -16
  532. package/dist/utils/json-parse.d.ts.map +0 -1
  533. package/dist/utils/json-parse.js +0 -113
  534. package/dist/utils/json-parse.js.map +0 -1
  535. package/dist/utils/node-http-proxy.d.ts +0 -10
  536. package/dist/utils/node-http-proxy.d.ts.map +0 -1
  537. package/dist/utils/node-http-proxy.js +0 -97
  538. package/dist/utils/node-http-proxy.js.map +0 -1
  539. package/dist/utils/oauth/anthropic.d.ts +0 -25
  540. package/dist/utils/oauth/anthropic.d.ts.map +0 -1
  541. package/dist/utils/oauth/anthropic.js +0 -335
  542. package/dist/utils/oauth/anthropic.js.map +0 -1
  543. package/dist/utils/oauth/device-code.d.ts +0 -19
  544. package/dist/utils/oauth/device-code.d.ts.map +0 -1
  545. package/dist/utils/oauth/device-code.js +0 -55
  546. package/dist/utils/oauth/device-code.js.map +0 -1
  547. package/dist/utils/oauth/github-copilot.d.ts +0 -30
  548. package/dist/utils/oauth/github-copilot.d.ts.map +0 -1
  549. package/dist/utils/oauth/github-copilot.js +0 -268
  550. package/dist/utils/oauth/github-copilot.js.map +0 -1
  551. package/dist/utils/oauth/google-antigravity.d.ts +0 -26
  552. package/dist/utils/oauth/google-antigravity.d.ts.map +0 -1
  553. package/dist/utils/oauth/google-antigravity.js +0 -377
  554. package/dist/utils/oauth/google-antigravity.js.map +0 -1
  555. package/dist/utils/oauth/google-gemini-cli.d.ts +0 -26
  556. package/dist/utils/oauth/google-gemini-cli.d.ts.map +0 -1
  557. package/dist/utils/oauth/google-gemini-cli.js +0 -482
  558. package/dist/utils/oauth/google-gemini-cli.js.map +0 -1
  559. package/dist/utils/oauth/index.d.ts +0 -63
  560. package/dist/utils/oauth/index.d.ts.map +0 -1
  561. package/dist/utils/oauth/index.js +0 -131
  562. package/dist/utils/oauth/index.js.map +0 -1
  563. package/dist/utils/oauth/oauth-page.d.ts +0 -3
  564. package/dist/utils/oauth/oauth-page.d.ts.map +0 -1
  565. package/dist/utils/oauth/oauth-page.js +0 -105
  566. package/dist/utils/oauth/oauth-page.js.map +0 -1
  567. package/dist/utils/oauth/openai-codex.d.ts +0 -34
  568. package/dist/utils/oauth/openai-codex.d.ts.map +0 -1
  569. package/dist/utils/oauth/openai-codex.js +0 -385
  570. package/dist/utils/oauth/openai-codex.js.map +0 -1
  571. package/dist/utils/oauth/pkce.d.ts.map +0 -1
  572. package/dist/utils/oauth/pkce.js +0 -31
  573. package/dist/utils/oauth/pkce.js.map +0 -1
  574. package/dist/utils/oauth/types.d.ts +0 -64
  575. package/dist/utils/oauth/types.d.ts.map +0 -1
  576. package/dist/utils/oauth/types.js +0 -2
  577. package/dist/utils/oauth/types.js.map +0 -1
  578. package/dist/utils/overflow.d.ts.map +0 -1
  579. package/dist/utils/overflow.js +0 -151
  580. package/dist/utils/overflow.js.map +0 -1
  581. package/dist/utils/sanitize-unicode.d.ts +0 -22
  582. package/dist/utils/sanitize-unicode.d.ts.map +0 -1
  583. package/dist/utils/sanitize-unicode.js +0 -26
  584. package/dist/utils/sanitize-unicode.js.map +0 -1
  585. package/dist/utils/typebox-helpers.d.ts +0 -17
  586. package/dist/utils/typebox-helpers.d.ts.map +0 -1
  587. package/dist/utils/typebox-helpers.js +0 -21
  588. package/dist/utils/typebox-helpers.js.map +0 -1
  589. package/dist/utils/validation.d.ts +0 -18
  590. package/dist/utils/validation.d.ts.map +0 -1
  591. package/dist/utils/validation.js +0 -281
  592. package/dist/utils/validation.js.map +0 -1
@@ -0,0 +1,647 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { resolvePromptCacheKey } from "../auth-gateway/http";
3
+ /**
4
+ * Parsed inbound OpenAI chat-completions request, ready to feed into aery-ai
5
+ * `stream(model, context, options)`.
6
+ */
7
+ import type { AuthGatewayParsedRequest as ParsedRequest } from "../auth-gateway/types";
8
+ import type {
9
+ AssistantMessage,
10
+ AssistantMessageEventStream,
11
+ Context,
12
+ ImageContent,
13
+ Message,
14
+ ResolvedServiceTier,
15
+ StopReason,
16
+ TextContent,
17
+ Tool,
18
+ ToolCall,
19
+ ToolResultMessage,
20
+ TSchema,
21
+ } from "../types";
22
+ import {
23
+ type OpenAIChatContentPart,
24
+ type OpenAIChatMessage,
25
+ type OpenAIChatTool,
26
+ type OpenAIChatToolCall,
27
+ type OpenAIChatToolChoice,
28
+ openaiChatRequestSchema,
29
+ } from "./openai-chat-server-schema";
30
+
31
+ export type { ParsedRequest };
32
+
33
+ type ReasoningEffort = NonNullable<ParsedRequest["options"]["reasoning"]>;
34
+
35
+ function isReasoningEffort(value: unknown): value is ReasoningEffort {
36
+ return value === "minimal" || value === "low" || value === "medium" || value === "high" || value === "xhigh";
37
+ }
38
+
39
+ function isServiceTier(value: unknown): value is ResolvedServiceTier {
40
+ return value === "auto" || value === "default" || value === "flex" || value === "scale" || value === "priority";
41
+ }
42
+
43
+ // ---------------------------------------------------------------------------
44
+ // parseRequest
45
+ // ---------------------------------------------------------------------------
46
+
47
+ export function parseRequest(body: unknown, headers?: Headers): ParsedRequest {
48
+ // Header capture is centralized in `auth-gateway/server.ts` (allow-listed
49
+ // headers like openai-organization/openai-project/openai-beta/x-stainless-*
50
+ // land on `options.headers` automatically). We consult `headers` here too
51
+ // for `resolvePromptCacheKey` to pull a cache identity out of inbound
52
+ // vendor-neutral headers when the body doesn't carry one.
53
+ const parsed = openaiChatRequestSchema.safeParse(body);
54
+ if (!parsed.success) {
55
+ throw new Error(`openai-chat: ${parsed.error.message}`);
56
+ }
57
+ const data = parsed.data;
58
+
59
+ const now = Date.now();
60
+ const systemParts: string[] = [];
61
+ const messages: Message[] = [];
62
+ // Map of `tool_call_id` → function name, populated as we walk assistant
63
+ // turns. The OpenAI wire spec drops `name` from `role:"tool"` messages,
64
+ // but downstream providers (notably Google: `functionResponse.name` is
65
+ // required) need it. We back-resolve from the matching call. If the
66
+ // client did send a wire `name` we still prefer that (forward-compat).
67
+ const toolNamesById = new Map<string, string>();
68
+
69
+ for (const m of data.messages as OpenAIChatMessage[]) {
70
+ switch (m.role) {
71
+ case "system": {
72
+ const text = stringifyContent(m.content);
73
+ if (text.length > 0) systemParts.push(text);
74
+ break;
75
+ }
76
+ case "developer":
77
+ messages.push({ role: "developer", content: parseUserLikeContent(m.content), timestamp: now });
78
+ break;
79
+ case "user":
80
+ messages.push({ role: "user", content: parseUserLikeContent(m.content), timestamp: now });
81
+ break;
82
+ case "assistant":
83
+ if (m.tool_calls) {
84
+ for (const raw of m.tool_calls) {
85
+ if (raw.type !== undefined && raw.type !== "function") continue;
86
+ const fn = (raw as { function?: { name?: string } }).function;
87
+ if (raw.id && fn?.name) toolNamesById.set(raw.id, fn.name);
88
+ }
89
+ }
90
+ messages.push(
91
+ buildAssistantMessage(
92
+ (m.content ?? undefined) as string | OpenAIChatContentPart[] | undefined,
93
+ m.tool_calls,
94
+ data.model,
95
+ now,
96
+ ),
97
+ );
98
+ break;
99
+ case "tool": {
100
+ // Prefer the wire `name` when present; otherwise back-resolve from
101
+ // the assistant `tool_calls` map. Falls through to "" only when no
102
+ // prior call shares this id, which is the well-known broken case.
103
+ const wireName = (m as { name?: string }).name;
104
+ const resolvedName = wireName ?? (m.tool_call_id ? toolNamesById.get(m.tool_call_id) : undefined);
105
+ pushToolResultMessages(messages, m.content, m.tool_call_id, resolvedName, now);
106
+ break;
107
+ }
108
+ case "function": {
109
+ // Legacy `function` role (pre-tools API): the message carries the tool's
110
+ // name on `name` and its output on `content`. Translate to a canonical
111
+ // `toolResult` with a synthetic id (no original id on the wire).
112
+ const fn = m as { role: "function"; name: string; content: string | null };
113
+ pushToolResultMessages(messages, fn.content ?? "", undefined, fn.name, now);
114
+ break;
115
+ }
116
+ }
117
+ }
118
+
119
+ const tools = data.tools ? buildTools(data.tools as OpenAIChatTool[]) : undefined;
120
+
121
+ const context: Context = {
122
+ messages,
123
+ ...(systemParts.length > 0 ? { systemPrompt: [systemParts.join("\n\n")] } : {}),
124
+ ...(tools ? { tools } : {}),
125
+ };
126
+
127
+ // Prefer max_completion_tokens (newer) over max_tokens.
128
+ const maxOutputTokens = data.max_completion_tokens ?? data.max_tokens;
129
+ const stopSequences = normalizeStop(data.stop);
130
+ // Schema accepts the Anthropic-style {type:'tool', name} variant that the SDK
131
+ // union doesn't model; the normalizer collapses it to a plain name lookup.
132
+ const toolChoice = normalizeToolChoice(data.tool_choice as Parameters<typeof normalizeToolChoice>[0]);
133
+ const includeStreamingUsage = data.stream_options?.include_usage === true;
134
+
135
+ // `includeStreamingUsage` is the one genuinely-opaque flag — the streaming
136
+ // encoder reads it later off `options.extra`. Everything else now lives on
137
+ // a typed field; `extra` stays undefined when only typed values are set.
138
+ const extra: Record<string, unknown> = {};
139
+ let hasExtra = false;
140
+ if (includeStreamingUsage) {
141
+ extra.includeStreamingUsage = true;
142
+ hasExtra = true;
143
+ }
144
+
145
+ const options: ParsedRequest["options"] = {};
146
+ if (maxOutputTokens !== undefined) options.maxOutputTokens = maxOutputTokens;
147
+ if (data.temperature !== undefined) options.temperature = data.temperature;
148
+ if (data.top_p !== undefined) options.topP = data.top_p;
149
+ if (stopSequences) options.stopSequences = stopSequences;
150
+ if (toolChoice !== undefined) options.toolChoice = toolChoice;
151
+ if (data.presence_penalty !== undefined) options.presencePenalty = data.presence_penalty;
152
+ if (data.frequency_penalty !== undefined) options.frequencyPenalty = data.frequency_penalty;
153
+ if (data.seed !== undefined) options.seed = data.seed;
154
+ if (data.logit_bias !== undefined) options.logitBias = data.logit_bias;
155
+ if (data.user !== undefined) options.user = data.user;
156
+ if (data.response_format !== undefined) options.responseFormat = data.response_format;
157
+ if (data.parallel_tool_calls !== undefined) options.parallelToolCalls = data.parallel_tool_calls;
158
+ if (data.reasoning_effort !== undefined && isReasoningEffort(data.reasoning_effort)) {
159
+ options.reasoning = data.reasoning_effort;
160
+ }
161
+ if (data.service_tier !== undefined && isServiceTier(data.service_tier)) {
162
+ options.serviceTier = data.service_tier;
163
+ }
164
+ if (data.metadata !== undefined) options.metadata = data.metadata;
165
+ const cacheKey = resolvePromptCacheKey(body, headers);
166
+ if (cacheKey !== undefined) options.promptCacheKey = cacheKey;
167
+ if (hasExtra) options.extra = extra;
168
+
169
+ return {
170
+ modelId: data.model,
171
+ context,
172
+ stream: data.stream === true,
173
+ options,
174
+ };
175
+ }
176
+
177
+ function stringifyContent(content: string | OpenAIChatContentPart[] | undefined): string {
178
+ if (content === undefined) return "";
179
+ if (typeof content === "string") return content;
180
+ const out: string[] = [];
181
+ for (const part of content) {
182
+ if (part.type === "text") out.push(part.text);
183
+ }
184
+ return out.join("");
185
+ }
186
+
187
+ function parseUserLikeContent(
188
+ content: string | OpenAIChatContentPart[] | undefined,
189
+ ): string | (TextContent | ImageContent)[] {
190
+ if (content === undefined) return "";
191
+ if (typeof content === "string") return content;
192
+ const parts: (TextContent | ImageContent)[] = [];
193
+ for (const part of content) {
194
+ if (part.type === "text") {
195
+ parts.push({ type: "text", text: part.text });
196
+ continue;
197
+ }
198
+ if (part.type !== "image_url") continue;
199
+ // input_audio / file / refusal / unknown-type parts are accepted by the
200
+ // schema for forward-compat but dropped here — aery-ai's canonical user
201
+ // content only models text and image today.
202
+ const url = typeof part.image_url === "string" ? part.image_url : part.image_url.url;
203
+ const decoded = decodeDataUri(url);
204
+ if (decoded) {
205
+ parts.push({ type: "image", data: decoded.data, mimeType: decoded.mimeType });
206
+ } else {
207
+ // No image fetcher available in the gateway; surface as a text placeholder so
208
+ // downstream providers still receive a coherent message.
209
+ parts.push({ type: "text", text: `[image: ${url}]` });
210
+ }
211
+ }
212
+ return parts;
213
+ }
214
+
215
+ function decodeDataUri(url: string): { data: string; mimeType: string } | undefined {
216
+ if (!url.startsWith("data:")) return undefined;
217
+ const comma = url.indexOf(",");
218
+ if (comma < 0) return undefined;
219
+ const header = url.slice(5, comma);
220
+ const payload = url.slice(comma + 1);
221
+ const isBase64 = header.endsWith(";base64");
222
+ const mimeType = (isBase64 ? header.slice(0, -";base64".length) : header) || "application/octet-stream";
223
+ const data = isBase64 ? payload : Buffer.from(decodeURIComponent(payload), "utf8").toString("base64");
224
+ return { data, mimeType };
225
+ }
226
+
227
+ function buildAssistantMessage(
228
+ content: string | OpenAIChatContentPart[] | undefined,
229
+ toolCalls: OpenAIChatToolCall[] | undefined,
230
+ modelId: string,
231
+ now: number,
232
+ ): AssistantMessage {
233
+ const parts: AssistantMessage["content"] = [];
234
+ const text = stringifyContent(content);
235
+ if (text.length > 0) parts.push({ type: "text", text });
236
+ if (toolCalls) {
237
+ for (const raw of toolCalls) {
238
+ // Schema only accepts type:"function" (or omitted); narrow the SDK
239
+ // union here so the custom-tool variant doesn't trip TS.
240
+ if (raw.type !== undefined && raw.type !== "function") continue;
241
+ const fn = (raw as { function: { name: string; arguments: string } }).function;
242
+ const argsStr = fn.arguments;
243
+ let args: Record<string, unknown> = {};
244
+ if (argsStr.length > 0) {
245
+ try {
246
+ const v: unknown = JSON.parse(argsStr);
247
+ args =
248
+ v && typeof v === "object" && !Array.isArray(v) ? (v as Record<string, unknown>) : { __raw: argsStr };
249
+ } catch {
250
+ args = { __raw: argsStr };
251
+ }
252
+ }
253
+ const call: ToolCall = { type: "toolCall", id: raw.id, name: fn.name, arguments: args };
254
+ parts.push(call);
255
+ }
256
+ }
257
+ return {
258
+ role: "assistant",
259
+ content: parts,
260
+ api: "openai-completions",
261
+ provider: "openai",
262
+ model: modelId,
263
+ usage: {
264
+ input: 0,
265
+ output: 0,
266
+ cacheRead: 0,
267
+ cacheWrite: 0,
268
+ totalTokens: 0,
269
+ cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },
270
+ },
271
+ stopReason: "stop",
272
+ timestamp: now,
273
+ };
274
+ }
275
+
276
+ /**
277
+ * Walk a wire `tool` (or legacy `function`) message into canonical messages.
278
+ * Tool-result content may carry images alongside text; aery-ai's
279
+ * `ToolResultMessage` accepts both, but most downstream providers ignore
280
+ * images on tool results. To mirror Rust's `encode_messages` behavior we
281
+ * keep text inside the tool-result message and hoist any image parts into a
282
+ * follow-up `user` message so they still reach the model.
283
+ */
284
+ function pushToolResultMessages(
285
+ messages: Message[],
286
+ content: string | OpenAIChatContentPart[] | undefined | null,
287
+ toolCallId: string | undefined,
288
+ toolName: string | undefined,
289
+ now: number,
290
+ ): void {
291
+ const textParts: TextContent[] = [];
292
+ const imageParts: ImageContent[] = [];
293
+
294
+ if (typeof content === "string") {
295
+ if (content.length > 0) textParts.push({ type: "text", text: content });
296
+ } else if (Array.isArray(content)) {
297
+ for (const part of content) {
298
+ if (part.type === "text") {
299
+ textParts.push({ type: "text", text: part.text });
300
+ continue;
301
+ }
302
+ if (part.type !== "image_url") continue;
303
+ const url = typeof part.image_url === "string" ? part.image_url : part.image_url.url;
304
+ const decoded = decodeDataUri(url);
305
+ if (decoded) {
306
+ imageParts.push({ type: "image", data: decoded.data, mimeType: decoded.mimeType });
307
+ } else {
308
+ // No fetcher available; degrade gracefully to a text placeholder.
309
+ textParts.push({ type: "text", text: `[image: ${url}]` });
310
+ }
311
+ }
312
+ }
313
+
314
+ const toolMsg: ToolResultMessage = {
315
+ role: "toolResult",
316
+ toolCallId: toolCallId ?? "",
317
+ // OpenAI's `tool` role omits the tool name on the wire; the legacy
318
+ // `function` role supplies it. Downstream providers tolerate empty.
319
+ toolName: toolName ?? "",
320
+ content: textParts.length > 0 ? textParts : [{ type: "text", text: "" }],
321
+ isError: false,
322
+ timestamp: now,
323
+ };
324
+ messages.push(toolMsg);
325
+
326
+ if (imageParts.length > 0) {
327
+ messages.push({
328
+ role: "user",
329
+ content: imageParts,
330
+ timestamp: now,
331
+ });
332
+ }
333
+ }
334
+
335
+ function buildTools(tools: OpenAIChatTool[]): Tool[] | undefined {
336
+ if (tools.length === 0) return undefined;
337
+ const out: Tool[] = [];
338
+ for (const t of tools) {
339
+ if (t.type !== "function") continue;
340
+ out.push({
341
+ name: t.function.name,
342
+ description: t.function.description ?? "",
343
+ parameters: (t.function.parameters ?? {}) as Record<string, unknown> as TSchema,
344
+ });
345
+ }
346
+ return out;
347
+ }
348
+
349
+ function normalizeStop(value: string | string[] | undefined): string[] | undefined {
350
+ if (value === undefined) return undefined;
351
+ if (typeof value === "string") return [value];
352
+ return value.length > 0 ? value : undefined;
353
+ }
354
+
355
+ function normalizeToolChoice(value: OpenAIChatToolChoice | undefined): ParsedRequest["options"]["toolChoice"] {
356
+ if (value === undefined) return undefined;
357
+ if (value === "auto" || value === "none" || value === "required") return value;
358
+ if (typeof value === "object" && value !== null) {
359
+ // OpenAI canonical: { type: 'function', function: { name } }
360
+ if ("function" in value && value.function) return { name: value.function.name };
361
+ // Anthropic-style passthrough (schema-allowed): { type: 'tool', name }
362
+ const anthropicLike = value as unknown as { type?: string; name?: string };
363
+ if (anthropicLike.type === "tool" && typeof anthropicLike.name === "string") {
364
+ return { name: anthropicLike.name };
365
+ }
366
+ }
367
+ return undefined;
368
+ }
369
+
370
+ // ---------------------------------------------------------------------------
371
+ // encodeResponse (non-streaming)
372
+ // ---------------------------------------------------------------------------
373
+
374
+ export function encodeResponse(message: AssistantMessage, requestedModelId: string): Record<string, unknown> {
375
+ const { text, reasoning, toolCalls } = flattenAssistant(message);
376
+
377
+ const responseMessage: Record<string, unknown> = {
378
+ role: "assistant",
379
+ content: text.length > 0 ? text : null,
380
+ // aery-ai does not surface real refusals yet; emit `null` so SDKs that
381
+ // probe `.refusal` see the documented field shape rather than missing.
382
+ refusal: null,
383
+ };
384
+ if (reasoning.length > 0) {
385
+ // DeepSeek-style / o-series reasoning channel.
386
+ responseMessage.reasoning_content = reasoning;
387
+ }
388
+ if (toolCalls.length > 0) {
389
+ responseMessage.tool_calls = toolCalls.map(tc => ({
390
+ id: tc.id,
391
+ type: "function",
392
+ function: { name: tc.name, arguments: stringifyArgs(tc.arguments) },
393
+ }));
394
+ }
395
+
396
+ return {
397
+ id: makeId(),
398
+ object: "chat.completion",
399
+ created: Math.floor(Date.now() / 1000),
400
+ model: requestedModelId,
401
+ // Real OpenAI always emits this key, even when the value is null. Mirror
402
+ // the contract so probing SDKs do not throw on a missing field.
403
+ system_fingerprint: null,
404
+ choices: [
405
+ {
406
+ index: 0,
407
+ message: responseMessage,
408
+ finish_reason: mapFinishReason(message.stopReason, toolCalls.length > 0),
409
+ logprobs: null,
410
+ },
411
+ ],
412
+ usage: buildUsage(message),
413
+ };
414
+ }
415
+
416
+ function buildUsage(message: AssistantMessage): Record<string, unknown> {
417
+ const promptTokens = message.usage.input + message.usage.cacheRead + message.usage.cacheWrite;
418
+ const usage: Record<string, unknown> = {
419
+ prompt_tokens: promptTokens,
420
+ completion_tokens: message.usage.output,
421
+ total_tokens: promptTokens + message.usage.output,
422
+ prompt_tokens_details: { cached_tokens: message.usage.cacheRead },
423
+ };
424
+ if (message.usage.reasoningTokens !== undefined) {
425
+ usage.completion_tokens_details = { reasoning_tokens: message.usage.reasoningTokens };
426
+ }
427
+ return usage;
428
+ }
429
+
430
+ function flattenAssistant(message: AssistantMessage): {
431
+ text: string;
432
+ reasoning: string;
433
+ toolCalls: ToolCall[];
434
+ } {
435
+ let text = "";
436
+ let reasoning = "";
437
+ const toolCalls: ToolCall[] = [];
438
+ for (const part of message.content) {
439
+ switch (part.type) {
440
+ case "text":
441
+ text += part.text;
442
+ break;
443
+ case "thinking":
444
+ reasoning += part.thinking;
445
+ break;
446
+ case "redactedThinking":
447
+ // Opaque blob — surface verbatim on the reasoning channel so the
448
+ // concatenation round-trips through clients that just echo it.
449
+ reasoning += part.data;
450
+ break;
451
+ case "toolCall":
452
+ toolCalls.push(part);
453
+ break;
454
+ }
455
+ }
456
+ return { text, reasoning, toolCalls };
457
+ }
458
+
459
+ function isOnlyRaw(args: Record<string, unknown>): boolean {
460
+ for (const k in args) {
461
+ if (k !== "__raw") return false;
462
+ }
463
+ return true;
464
+ }
465
+
466
+ function stringifyArgs(args: Record<string, unknown>): string {
467
+ // `__raw` is our fallback marker for un-parseable inbound args; preserve it verbatim on the way out.
468
+ if (typeof args.__raw === "string" && isOnlyRaw(args)) return args.__raw;
469
+ try {
470
+ return JSON.stringify(args);
471
+ } catch {
472
+ return "{}";
473
+ }
474
+ }
475
+
476
+ function mapFinishReason(reason: StopReason, hasToolCalls: boolean): string {
477
+ if (reason === "toolUse" || (hasToolCalls && reason === "stop")) return "tool_calls";
478
+ if (reason === "length") return "length";
479
+ // aery-ai's StopReason does not currently carry a content-filter signal;
480
+ // when it does, map it to "content_filter" here.
481
+ return "stop";
482
+ }
483
+
484
+ function makeId(): string {
485
+ return `chatcmpl-${randomUUID()}`;
486
+ }
487
+
488
+ // ---------------------------------------------------------------------------
489
+ // encodeStream (SSE)
490
+ // ---------------------------------------------------------------------------
491
+
492
+ export function encodeStream(
493
+ events: AssistantMessageEventStream,
494
+ requestedModelId: string,
495
+ options?: ParsedRequest["options"],
496
+ ): ReadableStream<Uint8Array> {
497
+ const encoder = new TextEncoder();
498
+ const id = makeId();
499
+ const created = Math.floor(Date.now() / 1000);
500
+ const includeUsage = options?.extra?.includeStreamingUsage === true;
501
+
502
+ const baseChunk = (delta: Record<string, unknown>, finishReason: string | null) => ({
503
+ id,
504
+ object: "chat.completion.chunk",
505
+ created,
506
+ model: requestedModelId,
507
+ system_fingerprint: null,
508
+ choices: [{ index: 0, delta, finish_reason: finishReason, logprobs: null }],
509
+ ...(includeUsage ? { usage: null } : {}),
510
+ });
511
+
512
+ const writeSse = (controller: ReadableStreamDefaultController<Uint8Array>, payload: unknown): void => {
513
+ controller.enqueue(encoder.encode(`data: ${JSON.stringify(payload)}\n\n`));
514
+ };
515
+
516
+ const writeUsage = (controller: ReadableStreamDefaultController<Uint8Array>, message: AssistantMessage): void => {
517
+ writeSse(controller, {
518
+ id,
519
+ object: "chat.completion.chunk",
520
+ created,
521
+ model: requestedModelId,
522
+ system_fingerprint: null,
523
+ choices: [],
524
+ usage: buildUsage(message),
525
+ });
526
+ };
527
+
528
+ return new ReadableStream<Uint8Array>({
529
+ async start(controller) {
530
+ // contentIndex (from aery-ai events) -> tool_calls index on the wire.
531
+ const toolIndexByContentIndex = new Map<number, number>();
532
+ let nextToolIndex = 0;
533
+ let hasToolCalls = false;
534
+ let finishReason: string = "stop";
535
+
536
+ try {
537
+ // Initial role chunk.
538
+ writeSse(controller, baseChunk({ role: "assistant" }, null));
539
+
540
+ for await (const event of events) {
541
+ switch (event.type) {
542
+ case "text_delta":
543
+ if (event.delta.length > 0) {
544
+ writeSse(controller, baseChunk({ content: event.delta }, null));
545
+ }
546
+ break;
547
+
548
+ case "thinking_delta":
549
+ // DeepSeek-style / o-series reasoning channel. Clients that don't
550
+ // understand it ignore the unknown delta key.
551
+ if (event.delta.length > 0) {
552
+ writeSse(controller, baseChunk({ reasoning_content: event.delta }, null));
553
+ }
554
+ break;
555
+
556
+ case "toolcall_start": {
557
+ hasToolCalls = true;
558
+ const idx = nextToolIndex++;
559
+ toolIndexByContentIndex.set(event.contentIndex, idx);
560
+ const partial = event.partial.content[event.contentIndex];
561
+ const call = partial && partial.type === "toolCall" ? partial : undefined;
562
+ writeSse(
563
+ controller,
564
+ baseChunk(
565
+ {
566
+ tool_calls: [
567
+ {
568
+ index: idx,
569
+ id: call?.id ?? "",
570
+ type: "function",
571
+ function: { name: call?.name ?? "", arguments: "" },
572
+ },
573
+ ],
574
+ },
575
+ null,
576
+ ),
577
+ );
578
+ break;
579
+ }
580
+
581
+ case "toolcall_delta": {
582
+ const idx = toolIndexByContentIndex.get(event.contentIndex);
583
+ if (idx === undefined) break;
584
+ writeSse(
585
+ controller,
586
+ baseChunk({ tool_calls: [{ index: idx, function: { arguments: event.delta } }] }, null),
587
+ );
588
+ break;
589
+ }
590
+
591
+ case "done":
592
+ finishReason =
593
+ event.reason === "toolUse"
594
+ ? "tool_calls"
595
+ : event.reason === "length"
596
+ ? "length"
597
+ : hasToolCalls
598
+ ? "tool_calls"
599
+ : "stop";
600
+ writeSse(controller, baseChunk({}, finishReason));
601
+ if (includeUsage) writeUsage(controller, event.message);
602
+ controller.enqueue(encoder.encode("data: [DONE]\n\n"));
603
+ controller.close();
604
+ return;
605
+
606
+ case "error": {
607
+ const msg = event.error.errorMessage ?? "stream error";
608
+ writeSse(controller, { error: { message: msg, type: "upstream_error" } });
609
+ controller.close();
610
+ return;
611
+ }
612
+
613
+ // Drop start / *_start / *_end — chat-completions wire only
614
+ // surfaces deltas and the terminal finish_reason.
615
+ default:
616
+ break;
617
+ }
618
+ }
619
+
620
+ // Stream ended without a terminal `done` (defensive). Close gracefully.
621
+ writeSse(controller, baseChunk({}, hasToolCalls ? "tool_calls" : "stop"));
622
+ controller.enqueue(encoder.encode("data: [DONE]\n\n"));
623
+ controller.close();
624
+ } catch (err) {
625
+ const msg = err instanceof Error ? err.message : String(err);
626
+ writeSse(controller, { error: { message: msg, type: "upstream_error" } });
627
+ controller.close();
628
+ }
629
+ },
630
+ });
631
+ }
632
+
633
+ // ---------------------------------------------------------------------------
634
+ // formatError
635
+ // ---------------------------------------------------------------------------
636
+
637
+ /**
638
+ * OpenAI chat-completions error envelope:
639
+ * `{ error: { message, type } }`
640
+ * Matches the shape the official SDK auto-parses into `APIError`.
641
+ */
642
+ export function formatError(status: number, type: string, message: string): Response {
643
+ return new Response(JSON.stringify({ error: { message, type } }), {
644
+ status,
645
+ headers: { "Content-Type": "application/json" },
646
+ });
647
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Constants for OpenAI Codex (ChatGPT OAuth) backend
3
+ */
4
+
5
+ export const CODEX_BASE_URL = "https://chatgpt.com/backend-api";
6
+
7
+ export const OPENAI_HEADERS = {
8
+ BETA: "OpenAI-Beta",
9
+ ACCOUNT_ID: "chatgpt-account-id",
10
+ ORIGINATOR: "originator",
11
+ SESSION_ID: "session_id",
12
+ CONVERSATION_ID: "conversation_id",
13
+ } as const;
14
+
15
+ export const OPENAI_HEADER_VALUES = {
16
+ BETA_RESPONSES: "responses=experimental",
17
+ BETA_RESPONSES_WEBSOCKETS_V2: "responses_websockets=2026-02-06",
18
+ ORIGINATOR_CODEX: "aery",
19
+ } as const;
20
+
21
+ export const URL_PATHS = {
22
+ RESPONSES: "/responses",
23
+ CODEX_RESPONSES: "/codex/responses",
24
+ } as const;
25
+
26
+ export const JWT_CLAIM_PATH = "https://api.openai.com/auth" as const;
27
+
28
+ /**
29
+ * Extract account ID from a Codex JWT access token.
30
+ * Returns undefined if the token is not a valid Codex JWT.
31
+ */
32
+ export function getCodexAccountId(accessToken: string): string | undefined {
33
+ try {
34
+ const parts = accessToken.split(".");
35
+ if (parts.length !== 3) return undefined;
36
+ const decoded = Buffer.from(parts[1] ?? "", "base64").toString("utf-8");
37
+ const payload = JSON.parse(decoded) as Record<string, unknown>;
38
+ const auth = payload[JWT_CLAIM_PATH] as { chatgpt_account_id?: string } | undefined;
39
+ return auth?.chatgpt_account_id ?? undefined;
40
+ } catch {
41
+ return undefined;
42
+ }
43
+ }