@gajae-code/ai 0.1.1

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 (349) hide show
  1. package/CHANGELOG.md +2644 -0
  2. package/README.md +1181 -0
  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 +17 -0
  14. package/dist/types/auth-gateway/types.d.ts +115 -0
  15. package/dist/types/auth-storage.d.ts +641 -0
  16. package/dist/types/cli.d.ts +2 -0
  17. package/dist/types/index.d.ts +49 -0
  18. package/dist/types/model-cache.d.ts +17 -0
  19. package/dist/types/model-manager.d.ts +62 -0
  20. package/dist/types/model-thinking.d.ts +71 -0
  21. package/dist/types/models.d.ts +12 -0
  22. package/dist/types/provider-details.d.ts +24 -0
  23. package/dist/types/provider-models/bundled-references.d.ts +4 -0
  24. package/dist/types/provider-models/descriptors.d.ts +48 -0
  25. package/dist/types/provider-models/google.d.ts +20 -0
  26. package/dist/types/provider-models/index.d.ts +5 -0
  27. package/dist/types/provider-models/ollama.d.ts +7 -0
  28. package/dist/types/provider-models/openai-compat.d.ts +237 -0
  29. package/dist/types/provider-models/special.d.ts +16 -0
  30. package/dist/types/providers/amazon-bedrock.d.ts +36 -0
  31. package/dist/types/providers/anthropic-messages-server-schema.d.ts +450 -0
  32. package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
  33. package/dist/types/providers/anthropic.d.ts +188 -0
  34. package/dist/types/providers/aws-credentials.d.ts +43 -0
  35. package/dist/types/providers/aws-eventstream.d.ts +38 -0
  36. package/dist/types/providers/aws-sigv4.d.ts +55 -0
  37. package/dist/types/providers/azure-openai-responses.d.ts +15 -0
  38. package/dist/types/providers/cursor/gen/agent_pb.d.ts +13022 -0
  39. package/dist/types/providers/cursor.d.ts +42 -0
  40. package/dist/types/providers/error-message.d.ts +27 -0
  41. package/dist/types/providers/github-copilot-headers.d.ts +40 -0
  42. package/dist/types/providers/gitlab-duo.d.ts +27 -0
  43. package/dist/types/providers/google-auth.d.ts +24 -0
  44. package/dist/types/providers/google-gemini-cli.d.ts +72 -0
  45. package/dist/types/providers/google-gemini-headers.d.ts +18 -0
  46. package/dist/types/providers/google-shared.d.ts +163 -0
  47. package/dist/types/providers/google-types.d.ts +138 -0
  48. package/dist/types/providers/google-vertex.d.ts +7 -0
  49. package/dist/types/providers/google.d.ts +4 -0
  50. package/dist/types/providers/grammar.d.ts +1 -0
  51. package/dist/types/providers/kimi.d.ts +27 -0
  52. package/dist/types/providers/mock.d.ts +175 -0
  53. package/dist/types/providers/ollama.d.ts +6 -0
  54. package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
  55. package/dist/types/providers/openai-chat-server-schema.d.ts +814 -0
  56. package/dist/types/providers/openai-chat-server.d.ts +16 -0
  57. package/dist/types/providers/openai-codex/constants.d.ts +26 -0
  58. package/dist/types/providers/openai-codex/request-transformer.d.ts +49 -0
  59. package/dist/types/providers/openai-codex/response-handler.d.ts +17 -0
  60. package/dist/types/providers/openai-codex-responses.d.ts +67 -0
  61. package/dist/types/providers/openai-completions-compat.d.ts +25 -0
  62. package/dist/types/providers/openai-completions.d.ts +33 -0
  63. package/dist/types/providers/openai-responses-server-schema.d.ts +392 -0
  64. package/dist/types/providers/openai-responses-server.d.ts +17 -0
  65. package/dist/types/providers/openai-responses-shared.d.ts +89 -0
  66. package/dist/types/providers/openai-responses.d.ts +32 -0
  67. package/dist/types/providers/pi-native-client.d.ts +13 -0
  68. package/dist/types/providers/pi-native-server.d.ts +68 -0
  69. package/dist/types/providers/register-builtins.d.ts +31 -0
  70. package/dist/types/providers/synthetic.d.ts +26 -0
  71. package/dist/types/providers/transform-messages.d.ts +12 -0
  72. package/dist/types/providers/vision-guard.d.ts +8 -0
  73. package/dist/types/rate-limit-utils.d.ts +19 -0
  74. package/dist/types/stream.d.ts +24 -0
  75. package/dist/types/types.d.ts +746 -0
  76. package/dist/types/usage/claude.d.ts +3 -0
  77. package/dist/types/usage/gemini.d.ts +2 -0
  78. package/dist/types/usage/github-copilot.d.ts +7 -0
  79. package/dist/types/usage/google-antigravity.d.ts +2 -0
  80. package/dist/types/usage/kimi.d.ts +2 -0
  81. package/dist/types/usage/minimax-code.d.ts +2 -0
  82. package/dist/types/usage/openai-codex.d.ts +3 -0
  83. package/dist/types/usage/shared.d.ts +1 -0
  84. package/dist/types/usage/zai.d.ts +2 -0
  85. package/dist/types/usage.d.ts +258 -0
  86. package/dist/types/utils/abort.d.ts +19 -0
  87. package/dist/types/utils/anthropic-auth.d.ts +31 -0
  88. package/dist/types/utils/discovery/antigravity.d.ts +61 -0
  89. package/dist/types/utils/discovery/codex.d.ts +38 -0
  90. package/dist/types/utils/discovery/cursor.d.ts +23 -0
  91. package/dist/types/utils/discovery/gemini.d.ts +25 -0
  92. package/dist/types/utils/discovery/index.d.ts +4 -0
  93. package/dist/types/utils/discovery/openai-compatible.d.ts +72 -0
  94. package/dist/types/utils/event-stream.d.ts +28 -0
  95. package/dist/types/utils/fireworks-model-id.d.ts +10 -0
  96. package/dist/types/utils/foundry.d.ts +1 -0
  97. package/dist/types/utils/h2-fetch.d.ts +22 -0
  98. package/dist/types/utils/http-inspector.d.ts +31 -0
  99. package/dist/types/utils/idle-iterator.d.ts +67 -0
  100. package/dist/types/utils/json-parse.d.ts +10 -0
  101. package/dist/types/utils/oauth/alibaba-coding-plan.d.ts +18 -0
  102. package/dist/types/utils/oauth/anthropic.d.ts +22 -0
  103. package/dist/types/utils/oauth/api-key-login.d.ts +35 -0
  104. package/dist/types/utils/oauth/api-key-validation.d.ts +27 -0
  105. package/dist/types/utils/oauth/callback-server.d.ts +57 -0
  106. package/dist/types/utils/oauth/cerebras.d.ts +1 -0
  107. package/dist/types/utils/oauth/cloudflare-ai-gateway.d.ts +18 -0
  108. package/dist/types/utils/oauth/cursor.d.ts +15 -0
  109. package/dist/types/utils/oauth/deepseek.d.ts +10 -0
  110. package/dist/types/utils/oauth/firepass.d.ts +1 -0
  111. package/dist/types/utils/oauth/fireworks.d.ts +1 -0
  112. package/dist/types/utils/oauth/github-copilot.d.ts +38 -0
  113. package/dist/types/utils/oauth/gitlab-duo.d.ts +3 -0
  114. package/dist/types/utils/oauth/google-antigravity.d.ts +11 -0
  115. package/dist/types/utils/oauth/google-gemini-cli.d.ts +10 -0
  116. package/dist/types/utils/oauth/google-oauth-shared.d.ts +28 -0
  117. package/dist/types/utils/oauth/huggingface.d.ts +19 -0
  118. package/dist/types/utils/oauth/index.d.ts +38 -0
  119. package/dist/types/utils/oauth/kagi.d.ts +17 -0
  120. package/dist/types/utils/oauth/kilo.d.ts +5 -0
  121. package/dist/types/utils/oauth/kimi.d.ts +21 -0
  122. package/dist/types/utils/oauth/litellm.d.ts +18 -0
  123. package/dist/types/utils/oauth/lm-studio.d.ts +17 -0
  124. package/dist/types/utils/oauth/minimax-code.d.ts +28 -0
  125. package/dist/types/utils/oauth/moonshot.d.ts +1 -0
  126. package/dist/types/utils/oauth/nanogpt.d.ts +1 -0
  127. package/dist/types/utils/oauth/nvidia.d.ts +18 -0
  128. package/dist/types/utils/oauth/ollama-cloud.d.ts +2 -0
  129. package/dist/types/utils/oauth/ollama.d.ts +18 -0
  130. package/dist/types/utils/oauth/openai-codex.d.ts +21 -0
  131. package/dist/types/utils/oauth/opencode.d.ts +18 -0
  132. package/dist/types/utils/oauth/parallel.d.ts +17 -0
  133. package/dist/types/utils/oauth/perplexity.d.ts +9 -0
  134. package/dist/types/utils/oauth/pkce.d.ts +8 -0
  135. package/dist/types/utils/oauth/qianfan.d.ts +17 -0
  136. package/dist/types/utils/oauth/qwen-portal.d.ts +19 -0
  137. package/dist/types/utils/oauth/synthetic.d.ts +1 -0
  138. package/dist/types/utils/oauth/tavily.d.ts +17 -0
  139. package/dist/types/utils/oauth/together.d.ts +1 -0
  140. package/dist/types/utils/oauth/types.d.ts +44 -0
  141. package/dist/types/utils/oauth/venice.d.ts +18 -0
  142. package/dist/types/utils/oauth/vercel-ai-gateway.d.ts +18 -0
  143. package/dist/types/utils/oauth/vllm.d.ts +16 -0
  144. package/dist/types/utils/oauth/xiaomi.d.ts +19 -0
  145. package/dist/types/utils/oauth/zai.d.ts +18 -0
  146. package/dist/types/utils/oauth/zenmux.d.ts +1 -0
  147. package/dist/types/utils/overflow.d.ts +54 -0
  148. package/dist/types/utils/parse-bind.d.ts +23 -0
  149. package/dist/types/utils/provider-response.d.ts +3 -0
  150. package/dist/types/utils/retry-after.d.ts +3 -0
  151. package/dist/types/utils/retry.d.ts +26 -0
  152. package/dist/types/utils/schema/adapt.d.ts +24 -0
  153. package/dist/types/utils/schema/compatibility.d.ts +30 -0
  154. package/dist/types/utils/schema/dereference.d.ts +11 -0
  155. package/dist/types/utils/schema/draft.d.ts +10 -0
  156. package/dist/types/utils/schema/equality.d.ts +4 -0
  157. package/dist/types/utils/schema/fields.d.ts +49 -0
  158. package/dist/types/utils/schema/index.d.ts +13 -0
  159. package/dist/types/utils/schema/json-schema-validator.d.ts +12 -0
  160. package/dist/types/utils/schema/meta-validator.d.ts +2 -0
  161. package/dist/types/utils/schema/normalize.d.ts +93 -0
  162. package/dist/types/utils/schema/spill.d.ts +8 -0
  163. package/dist/types/utils/schema/stamps.d.ts +25 -0
  164. package/dist/types/utils/schema/types.d.ts +4 -0
  165. package/dist/types/utils/schema/wire.d.ts +54 -0
  166. package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -0
  167. package/dist/types/utils/sse-debug.d.ts +10 -0
  168. package/dist/types/utils/tool-call-healing.d.ts +71 -0
  169. package/dist/types/utils/tool-choice.d.ts +50 -0
  170. package/dist/types/utils/validation.d.ts +17 -0
  171. package/dist/types/utils.d.ts +28 -0
  172. package/package.json +146 -0
  173. package/src/api-registry.ts +96 -0
  174. package/src/auth-broker/client.ts +358 -0
  175. package/src/auth-broker/index.ts +5 -0
  176. package/src/auth-broker/refresher.ts +127 -0
  177. package/src/auth-broker/remote-store.ts +623 -0
  178. package/src/auth-broker/server.ts +644 -0
  179. package/src/auth-broker/types.ts +127 -0
  180. package/src/auth-broker/wire-schemas.ts +200 -0
  181. package/src/auth-gateway/http.ts +194 -0
  182. package/src/auth-gateway/index.ts +3 -0
  183. package/src/auth-gateway/server.ts +717 -0
  184. package/src/auth-gateway/types.ts +134 -0
  185. package/src/auth-storage.ts +4104 -0
  186. package/src/cli.ts +262 -0
  187. package/src/index.ts +54 -0
  188. package/src/model-cache.ts +129 -0
  189. package/src/model-manager.ts +450 -0
  190. package/src/model-thinking.ts +691 -0
  191. package/src/models.json +73853 -0
  192. package/src/models.json.d.ts +9 -0
  193. package/src/models.ts +56 -0
  194. package/src/prompts/turn-aborted-guidance.md +4 -0
  195. package/src/provider-details.ts +90 -0
  196. package/src/provider-models/bundled-references.ts +38 -0
  197. package/src/provider-models/descriptors.ts +308 -0
  198. package/src/provider-models/google.ts +91 -0
  199. package/src/provider-models/index.ts +5 -0
  200. package/src/provider-models/ollama.ts +153 -0
  201. package/src/provider-models/openai-compat.ts +2275 -0
  202. package/src/provider-models/special.ts +67 -0
  203. package/src/providers/amazon-bedrock.ts +849 -0
  204. package/src/providers/anthropic-messages-server-schema.ts +229 -0
  205. package/src/providers/anthropic-messages-server.ts +677 -0
  206. package/src/providers/anthropic.ts +2696 -0
  207. package/src/providers/aws-credentials.ts +501 -0
  208. package/src/providers/aws-eventstream.ts +185 -0
  209. package/src/providers/aws-sigv4.ts +218 -0
  210. package/src/providers/azure-openai-responses.ts +337 -0
  211. package/src/providers/cursor/gen/agent_pb.ts +15274 -0
  212. package/src/providers/cursor/proto/agent.proto +3526 -0
  213. package/src/providers/cursor/proto/buf.gen.yaml +6 -0
  214. package/src/providers/cursor/proto/buf.yaml +17 -0
  215. package/src/providers/cursor.ts +2561 -0
  216. package/src/providers/error-message.ts +21 -0
  217. package/src/providers/github-copilot-headers.ts +140 -0
  218. package/src/providers/gitlab-duo.ts +372 -0
  219. package/src/providers/google-auth.ts +252 -0
  220. package/src/providers/google-gemini-cli.ts +795 -0
  221. package/src/providers/google-gemini-headers.ts +41 -0
  222. package/src/providers/google-shared.ts +902 -0
  223. package/src/providers/google-types.ts +167 -0
  224. package/src/providers/google-vertex.ts +88 -0
  225. package/src/providers/google.ts +41 -0
  226. package/src/providers/grammar.ts +70 -0
  227. package/src/providers/kimi.ts +52 -0
  228. package/src/providers/mock.ts +500 -0
  229. package/src/providers/ollama.ts +544 -0
  230. package/src/providers/openai-anthropic-shim.ts +138 -0
  231. package/src/providers/openai-chat-server-schema.ts +243 -0
  232. package/src/providers/openai-chat-server.ts +628 -0
  233. package/src/providers/openai-codex/constants.ts +43 -0
  234. package/src/providers/openai-codex/request-transformer.ts +161 -0
  235. package/src/providers/openai-codex/response-handler.ts +81 -0
  236. package/src/providers/openai-codex-responses.ts +2598 -0
  237. package/src/providers/openai-completions-compat.ts +279 -0
  238. package/src/providers/openai-completions.ts +1853 -0
  239. package/src/providers/openai-responses-server-schema.ts +290 -0
  240. package/src/providers/openai-responses-server.ts +1183 -0
  241. package/src/providers/openai-responses-shared.ts +800 -0
  242. package/src/providers/openai-responses.ts +621 -0
  243. package/src/providers/pi-native-client.ts +228 -0
  244. package/src/providers/pi-native-server.ts +210 -0
  245. package/src/providers/register-builtins.ts +412 -0
  246. package/src/providers/synthetic.ts +50 -0
  247. package/src/providers/transform-messages.ts +309 -0
  248. package/src/providers/vision-guard.ts +31 -0
  249. package/src/rate-limit-utils.ts +84 -0
  250. package/src/stream.ts +895 -0
  251. package/src/types.ts +884 -0
  252. package/src/usage/claude.ts +431 -0
  253. package/src/usage/gemini.ts +250 -0
  254. package/src/usage/github-copilot.ts +421 -0
  255. package/src/usage/google-antigravity.ts +201 -0
  256. package/src/usage/kimi.ts +271 -0
  257. package/src/usage/minimax-code.ts +31 -0
  258. package/src/usage/openai-codex.ts +503 -0
  259. package/src/usage/shared.ts +10 -0
  260. package/src/usage/zai.ts +247 -0
  261. package/src/usage.ts +183 -0
  262. package/src/utils/abort.ts +51 -0
  263. package/src/utils/anthropic-auth.ts +87 -0
  264. package/src/utils/discovery/antigravity.ts +261 -0
  265. package/src/utils/discovery/codex.ts +371 -0
  266. package/src/utils/discovery/cursor.ts +306 -0
  267. package/src/utils/discovery/gemini.ts +248 -0
  268. package/src/utils/discovery/index.ts +4 -0
  269. package/src/utils/discovery/openai-compatible.ts +224 -0
  270. package/src/utils/event-stream.ts +142 -0
  271. package/src/utils/fireworks-model-id.ts +30 -0
  272. package/src/utils/foundry.ts +8 -0
  273. package/src/utils/h2-fetch.ts +60 -0
  274. package/src/utils/http-inspector.ts +176 -0
  275. package/src/utils/idle-iterator.ts +250 -0
  276. package/src/utils/json-parse.ts +148 -0
  277. package/src/utils/oauth/alibaba-coding-plan.ts +59 -0
  278. package/src/utils/oauth/anthropic.ts +200 -0
  279. package/src/utils/oauth/api-key-login.ts +87 -0
  280. package/src/utils/oauth/api-key-validation.ts +92 -0
  281. package/src/utils/oauth/callback-server.ts +276 -0
  282. package/src/utils/oauth/cerebras.ts +16 -0
  283. package/src/utils/oauth/cloudflare-ai-gateway.ts +48 -0
  284. package/src/utils/oauth/cursor.ts +157 -0
  285. package/src/utils/oauth/deepseek.ts +53 -0
  286. package/src/utils/oauth/firepass.ts +24 -0
  287. package/src/utils/oauth/fireworks.ts +15 -0
  288. package/src/utils/oauth/github-copilot.ts +362 -0
  289. package/src/utils/oauth/gitlab-duo.ts +123 -0
  290. package/src/utils/oauth/google-antigravity.ts +200 -0
  291. package/src/utils/oauth/google-gemini-cli.ts +256 -0
  292. package/src/utils/oauth/google-oauth-shared.ts +110 -0
  293. package/src/utils/oauth/huggingface.ts +62 -0
  294. package/src/utils/oauth/index.ts +444 -0
  295. package/src/utils/oauth/kagi.ts +47 -0
  296. package/src/utils/oauth/kilo.ts +87 -0
  297. package/src/utils/oauth/kimi.ts +254 -0
  298. package/src/utils/oauth/litellm.ts +47 -0
  299. package/src/utils/oauth/lm-studio.ts +38 -0
  300. package/src/utils/oauth/minimax-code.ts +78 -0
  301. package/src/utils/oauth/moonshot.ts +16 -0
  302. package/src/utils/oauth/nanogpt.ts +15 -0
  303. package/src/utils/oauth/nvidia.ts +70 -0
  304. package/src/utils/oauth/oauth.html +199 -0
  305. package/src/utils/oauth/ollama-cloud.ts +28 -0
  306. package/src/utils/oauth/ollama.ts +47 -0
  307. package/src/utils/oauth/openai-codex.ts +299 -0
  308. package/src/utils/oauth/opencode.ts +49 -0
  309. package/src/utils/oauth/parallel.ts +46 -0
  310. package/src/utils/oauth/perplexity.ts +206 -0
  311. package/src/utils/oauth/pkce.ts +18 -0
  312. package/src/utils/oauth/qianfan.ts +58 -0
  313. package/src/utils/oauth/qwen-portal.ts +60 -0
  314. package/src/utils/oauth/synthetic.ts +16 -0
  315. package/src/utils/oauth/tavily.ts +46 -0
  316. package/src/utils/oauth/together.ts +16 -0
  317. package/src/utils/oauth/types.ts +94 -0
  318. package/src/utils/oauth/venice.ts +59 -0
  319. package/src/utils/oauth/vercel-ai-gateway.ts +47 -0
  320. package/src/utils/oauth/vllm.ts +40 -0
  321. package/src/utils/oauth/xiaomi.ts +137 -0
  322. package/src/utils/oauth/zai.ts +60 -0
  323. package/src/utils/oauth/zenmux.ts +15 -0
  324. package/src/utils/overflow.ts +137 -0
  325. package/src/utils/parse-bind.ts +54 -0
  326. package/src/utils/provider-response.ts +30 -0
  327. package/src/utils/retry-after.ts +110 -0
  328. package/src/utils/retry.ts +54 -0
  329. package/src/utils/schema/CONSTRAINTS.md +164 -0
  330. package/src/utils/schema/adapt.ts +36 -0
  331. package/src/utils/schema/compatibility.ts +435 -0
  332. package/src/utils/schema/dereference.ts +98 -0
  333. package/src/utils/schema/draft.ts +341 -0
  334. package/src/utils/schema/equality.ts +97 -0
  335. package/src/utils/schema/fields.ts +190 -0
  336. package/src/utils/schema/index.ts +13 -0
  337. package/src/utils/schema/json-schema-validator.ts +577 -0
  338. package/src/utils/schema/meta-validator.ts +167 -0
  339. package/src/utils/schema/normalize.ts +1588 -0
  340. package/src/utils/schema/spill.ts +43 -0
  341. package/src/utils/schema/stamps.ts +97 -0
  342. package/src/utils/schema/types.ts +11 -0
  343. package/src/utils/schema/wire.ts +213 -0
  344. package/src/utils/schema/zod-decontaminate.ts +331 -0
  345. package/src/utils/sse-debug.ts +289 -0
  346. package/src/utils/tool-call-healing.ts +271 -0
  347. package/src/utils/tool-choice.ts +99 -0
  348. package/src/utils/validation.ts +1019 -0
  349. package/src/utils.ts +166 -0
@@ -0,0 +1,93 @@
1
+ import { type DescriptionSpillFormat } from "./spill";
2
+ import { type JsonObject } from "./types";
3
+ export type ResidualSchemaIncompatibility = "type-array" | "type-null" | "nullable" | "combiners";
4
+ export interface NormalizeSchemaOptions {
5
+ unsupportedFields: (key: string) => boolean;
6
+ normalizeFieldNames: boolean;
7
+ collapseNullFields: boolean;
8
+ normalizeTypeArrayToNullable: boolean;
9
+ stripNullableKeyword: boolean;
10
+ autoPropertyOrdering: boolean;
11
+ ensureObjectProperties: boolean;
12
+ liftStrippedToDescription: false | {
13
+ keys?: (key: string) => boolean;
14
+ format?: DescriptionSpillFormat;
15
+ };
16
+ mergeObjectCombiners: boolean;
17
+ collapseSameTypeCombiners: boolean;
18
+ collapseMixedTypeCombiners: boolean;
19
+ stripResidualCombinersFixpoint: boolean;
20
+ extractNullableFromUnions: boolean;
21
+ rejectResidualIncompatibilities?: ReadonlyArray<ResidualSchemaIncompatibility>;
22
+ validateAndFallback?: {
23
+ fallback: unknown;
24
+ };
25
+ }
26
+ /** Copy all keys from a schema except the specified combiner key. */
27
+ export declare function copySchemaWithout(schema: JsonObject, combiner: string): JsonObject;
28
+ /**
29
+ * Recursively strip any remaining anyOf/oneOf that same-type or mixed-type
30
+ * collapse can handle. This is needed because object-combiner merging can
31
+ * create new anyOf in merged subtrees after child normalization already ran.
32
+ */
33
+ export declare function stripResidualCombiners(value: unknown, epoch?: number): unknown;
34
+ export declare function normalizeSchema(value: unknown, options: NormalizeSchemaOptions): unknown;
35
+ export declare function normalizeSchemaForGoogle(value: unknown): unknown;
36
+ export declare function normalizeSchemaForCCA(value: unknown): unknown;
37
+ export declare function normalizeSchemaForMCP(value: unknown): unknown;
38
+ /**
39
+ * OpenAI Responses rejects `oneOf` in tool schemas even when strict mode is
40
+ * disabled, and rejects every schema node with `type: "object"` unless it has
41
+ * a `properties` member. Normalize only schema-valued positions so literal
42
+ * payloads under `enum`, `const`, `default`, and `examples` remain unchanged.
43
+ *
44
+ * Identity-preserving: returns the input reference unchanged when no rewrite
45
+ * occurred so callers can dedupe via reference equality (and the strict-mode
46
+ * cache stays warm). If a node has both `oneOf` and `anyOf`, the two are
47
+ * concatenated (the wire payload accepts a single union; preserving both
48
+ * would not survive).
49
+ */
50
+ export declare function sanitizeSchemaForOpenAIResponses(schema: JsonObject): JsonObject;
51
+ /**
52
+ * Alias for {@link sanitizeSchemaForOpenAIResponses} matching the
53
+ * `normalizeSchemaFor*` dispatcher naming used elsewhere in this module.
54
+ */
55
+ export declare const normalizeSchemaForOpenAIResponses: (schema: JsonObject) => JsonObject;
56
+ /**
57
+ * First pass of strict-mode preparation.
58
+ *
59
+ * Rewrites everything strict mode forbids into something it accepts:
60
+ * - Drops non-structural keywords (`format`, `pattern`, `examples`, …),
61
+ * `const`, `nullable`, and `additionalProperties` (re-added by
62
+ * `enforceStrictSchema` as `false`).
63
+ * - `type: [a, b]` → `anyOf: [{type: a, …}, {type: b, …}]`, copying only the
64
+ * keywords each variant can use (e.g. `properties` stays only on the
65
+ * object variant).
66
+ * - `const` → single-entry `enum`.
67
+ * - Description carries a `(default: X)` suffix so the model still sees the
68
+ * documented default after the keyword is stripped.
69
+ * - `nullable: true` wraps the whole node in `anyOf:[T,{type:"null"}]`.
70
+ *
71
+ * Recurses into properties, items, prefixItems, combinators, and $defs. The
72
+ * `cache` WeakMap dedupes shared subgraphs; the `epoch` is the cycle guard.
73
+ */
74
+ export declare function sanitizeSchemaForStrictMode(schema: Record<string, unknown>, epoch?: number, cache?: WeakMap<Record<string, unknown>, Record<string, unknown>>, root?: Record<string, unknown>): Record<string, unknown>;
75
+ /**
76
+ * Recursively enforces JSON Schema constraints required by OpenAI/OpenAI code backend strict mode:
77
+ * - `additionalProperties: false` on every object node
78
+ * - every key in `properties` present in `required`
79
+ *
80
+ * Properties absent from the original `required` array were TypeBox-optional.
81
+ * They are made nullable (`anyOf: [T, { type: "null" }]`) so the model can
82
+ * signal omission by outputting null rather than omitting the key entirely.
83
+ *
84
+ * @throws {Error} When a schema node has no `type`, array-based combinator
85
+ * (`anyOf`/`allOf`/`oneOf`), object-based combinator (`not`), or `$ref` —
86
+ * i.e. the node is not representable in strict mode. Prefer
87
+ * {@link tryEnforceStrictSchema} which catches this and degrades gracefully.
88
+ */
89
+ export declare function enforceStrictSchema(schema: Record<string, unknown>, cache?: WeakMap<Record<string, unknown>, Record<string, unknown>>): Record<string, unknown>;
90
+ export declare function tryEnforceStrictSchema(schema: Record<string, unknown>): {
91
+ schema: Record<string, unknown>;
92
+ strict: boolean;
93
+ };
@@ -0,0 +1,8 @@
1
+ import type { JsonObject } from "./types";
2
+ export type DescriptionSpillFormat = "spill" | "paren";
3
+ /**
4
+ * Demote stripped JSON Schema keywords into a node's `description` so the model
5
+ * still receives the constraint as natural-language context after the wire
6
+ * schema drops it.
7
+ */
8
+ export declare function spillToDescription(node: JsonObject, entries: ReadonlyArray<readonly [string, unknown]>, format?: DescriptionSpillFormat): void;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Symbol-keyed lazy memoization stamped directly onto the host object.
3
+ *
4
+ * Faster than a module-level `WeakMap` in V8/JSC because the symbol slot is
5
+ * resolved through the object's hidden class instead of a side-table hash
6
+ * lookup. The slot is defined as a non-enumerable property so the stamp
7
+ * does not leak through `{...spread}`, `Object.keys`, `JSON.stringify`, or
8
+ * `toEqual`-style deep equality.
9
+ *
10
+ * Caveats: the stamp lives as long as the host object, even after callers
11
+ * release their references to the cached value — only use this for caches
12
+ * whose lifetime should match the host. Frozen hosts will throw on write in
13
+ * strict mode; callers that may receive frozen input must handle that.
14
+ */
15
+ export declare function stamp<T extends object, V>(target: T, key: symbol, compute: (target: T) => V): V;
16
+ export declare function epochNext(): number;
17
+ /**
18
+ * Marks `target` as visited for this `epoch`. Returns `true` the first time
19
+ * it is called for a given (target, epoch) pair and `false` on every
20
+ * subsequent call within the same epoch.
21
+ */
22
+ export declare function once<T extends object>(target: T, epoch: number): boolean;
23
+ /** Returns `true` on first entry, `false` if `target` is already on the current path. */
24
+ export declare function enter<T extends object>(target: T): boolean;
25
+ export declare function exit<T extends object>(target: T): void;
@@ -0,0 +1,4 @@
1
+ export type JsonObject = Record<string, unknown>;
2
+ export declare function isJsonObject(value: unknown): value is JsonObject;
3
+ /** True when `value` is a plain JSON object with no own enumerable keys. */
4
+ export declare function isJsonObjectEmpty(value: JsonObject): boolean;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Compute the wire (JSON Schema) representation of a tool's parameters and
3
+ * convert TypeBox-style schemas into Zod for internal validation.
4
+ *
5
+ * Tools may author parameters in two shapes:
6
+ * 1. Zod (canonical going forward) — converted to JSON Schema on demand.
7
+ * 2. TypeBox / plain JSON Schema (legacy + extension compat) — upgraded to
8
+ * draft 2020-12 without converting through Zod.
9
+ *
10
+ * Both are normalized at the boundary so providers and validators see the same
11
+ * JSON Schema dialect.
12
+ */
13
+ import { type ZodType } from "zod/v4";
14
+ import type { Tool } from "../../types";
15
+ /**
16
+ * True when `value` is a live Zod schema instance.
17
+ *
18
+ * The check is stricter than "has a `_zod` property" because a JSON
19
+ * round-trip preserves the `_zod` key as a plain object and would otherwise
20
+ * fool the predicate — see issue #1101, where MCP servers ship
21
+ * `JSON.stringify(zodSchemaInstance)` as a tool's `inputSchema` and the
22
+ * resulting plain object then explodes `z.toJSONSchema` because the prototype
23
+ * (and every Zod parsing method) is gone.
24
+ *
25
+ * Live Zod instances always carry a `.parse` function on the prototype;
26
+ * impostors do not.
27
+ */
28
+ export declare function isZodSchema(value: unknown): value is ZodType;
29
+ /**
30
+ * Normalize `{}` (empty JSON Schema = `z.unknown()` / unconstrained value) to
31
+ * boolean `true` in every schema-valued position. JSON Schema draft 2020-12
32
+ * §4.3.1: `{}` and `true` are semantically equivalent ("any JSON value").
33
+ * Grammar-constrained samplers (llama.cpp, etc.) treat the object form as
34
+ * "generate an empty object" rather than "any JSON value", causing open-typed
35
+ * fields like `extra.title` (from `z.record(z.string(), z.unknown())`) to
36
+ * always emit `{}` instead of the intended string/number/etc. (issue #1179).
37
+ *
38
+ * Mutates in place. Provider-agnostic — applied to every tool wire schema so
39
+ * Anthropic, Google, OpenAI, Ollama, Bedrock, and Cursor all see the
40
+ * normalized form, regardless of whether the source was Zod or TypeBox.
41
+ */
42
+ export declare function normalizeEmptySchemas(node: unknown): void;
43
+ /** Convert a Zod schema into the JSON Schema shape providers consume. */
44
+ export declare function zodToWireSchema(schema: ZodType): Record<string, unknown>;
45
+ /**
46
+ * Resolve a tool's parameters to a JSON Schema object suitable for sending
47
+ * over the wire. Zod schemas are converted (and cached); legacy TypeBox / raw
48
+ * JSON Schema parameters are upgraded to draft 2020-12 (and cached).
49
+ *
50
+ * Both branches finish with `normalizeEmptySchemas` so every provider —
51
+ * OpenAI, Anthropic, Google, Ollama, Bedrock, Cursor — sees `{}` normalized
52
+ * to `true` in schema-valued positions (issue #1179).
53
+ */
54
+ export declare function toolWireSchema(tool: Tool): Record<string, unknown>;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Defensive rewrite for nodes that look like `JSON.stringify(zodSchemaInstance)`
3
+ * output rather than JSON Schema. MCP servers using Zod 4 sometimes ship a
4
+ * serialised schema instance directly as a tool's `inputSchema`, because the
5
+ * fields Zod surfaces on its instances (`type`, `enum`, `options`, `def`) shadow
6
+ * (and clash with) JSON Schema keywords. The resulting payload is neither valid
7
+ * Zod nor valid JSON Schema 2020-12 and Anthropic's strict validator rejects
8
+ * the whole tool list.
9
+ *
10
+ * Symptoms we've observed (gitnexus_impact.direction):
11
+ * {
12
+ * def: { type: "enum", entries: { upstream: "upstream", ... } },
13
+ * type: "enum", // <- invalid `type` value
14
+ * enum: { upstream: "upstream", ... }, // <- `enum` MUST be an array
15
+ * options: ["upstream", "downstream"],
16
+ * }
17
+ *
18
+ * This module recognises the shape (`def.type === node.type` and `def.type` is
19
+ * a known Zod kind) and rewrites it to clean JSON Schema where deterministic.
20
+ * For Zod kinds we don't fully model, we strip the toxic siblings (`def`,
21
+ * `options`, object-shaped `enum`) and drop an invalid `type` so the remainder
22
+ * passes meta-schema validation as a permissive node.
23
+ *
24
+ * Pure / identity-preserving: returns the input reference when nothing changes.
25
+ */
26
+ /**
27
+ * Walks a JSON value and rewrites every Zod-instance-shaped node into clean
28
+ * JSON Schema 2020-12. Identity-preserving when no rewrite fires. Tolerates
29
+ * self-referential graphs — a revisited node returns as-is.
30
+ */
31
+ export declare function decontaminateZodInstance(value: unknown): unknown;
@@ -0,0 +1,10 @@
1
+ import type { ServerSentEvent } from "@gajae-code/utils";
2
+ import type { RawSseEvent } from "../types";
3
+ type FetchFunction = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
4
+ type FetchWithPreconnect = FetchFunction & {
5
+ preconnect?: typeof fetch.preconnect;
6
+ };
7
+ type RawSseObserver = (event: RawSseEvent) => void;
8
+ export declare function notifyRawSseEvent(observer: RawSseObserver | undefined, event: ServerSentEvent | RawSseEvent): void;
9
+ export declare function wrapFetchForSseDebug(fetchImpl: FetchWithPreconnect, observer: RawSseObserver | undefined): FetchWithPreconnect;
10
+ export {};
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Streaming-safe filter for the Kimi K2 chat-template "tool-call section"
3
+ * grammar.
4
+ *
5
+ * Some providers hosting Kimi K2 (the native `kimi-code` API, OpenRouter,
6
+ * Fireworks, and others) leak the raw chat-template special tokens into
7
+ * `delta.content` instead of emitting structured `tool_calls`. Visually
8
+ * that looks like:
9
+ *
10
+ * <|tool_calls_section_begin|>
11
+ * <|tool_call_begin|>functions.read:0<|tool_call_argument_begin|>{"path":"foo"}<|tool_call_end|>
12
+ * <|tool_calls_section_end|>
13
+ *
14
+ * Without healing, the user sees the raw markers and the agent loop never
15
+ * sees a tool call. This module reconstructs the embedded calls and strips
16
+ * the markers from visible text. It is stream-aware: any partial token at
17
+ * the end of a chunk is held back until the next chunk arrives.
18
+ */
19
+ export interface HealedToolCall {
20
+ readonly id: string;
21
+ readonly name: string;
22
+ readonly arguments: string;
23
+ }
24
+ /**
25
+ * State machine that consumes streamed text, emits visible text with all
26
+ * Kimi tool-call markers stripped, and accumulates the embedded tool calls
27
+ * for the caller to drain after each `feed()`.
28
+ *
29
+ * One instance per stream. Feed only the channel that may carry leaked
30
+ * markers (typically `delta.content`); mixing reasoning + content into the
31
+ * same accumulator corrupts the holdback buffer if both channels race in
32
+ * the same chunk.
33
+ */
34
+ export declare class ToolCallHealer {
35
+ #private;
36
+ /**
37
+ * Feed a chunk of streamed text. Returns the portion safe to emit
38
+ * downstream (with all tokens stripped). Any partial token suffix is
39
+ * held back until the next chunk arrives or {@link flushPending} is
40
+ * called.
41
+ */
42
+ feed(text: string): string;
43
+ /**
44
+ * Like {@link feed}, but discards any tool calls that the chunk completes.
45
+ * Used when the upstream provider also emits structured `delta.tool_calls`
46
+ * for the same chunk: the healer still strips leaked marker text from the
47
+ * visible output, but the structured payload remains the single source of
48
+ * truth for the call list.
49
+ */
50
+ consumeWithoutCalls(text: string): string;
51
+ /**
52
+ * Drain accumulated tool calls. The internal list is cleared so a
53
+ * subsequent section in the same stream (rare) yields fresh calls.
54
+ */
55
+ drainCompleted(): HealedToolCall[];
56
+ /**
57
+ * Flush any held-back fragment when the stream ends. If we were mid-call
58
+ * the partial is dropped (emitting raw token bytes would surface markers
59
+ * to the user); otherwise the fragment is returned verbatim so a literal
60
+ * `<|` in prose is not silently lost.
61
+ */
62
+ flushPending(): string;
63
+ /** True once any tool-call section in this stream has fully closed. */
64
+ get sectionClosed(): boolean;
65
+ }
66
+ /**
67
+ * Cheap test for whether a given model is known to leak Kimi-K2 chat-template
68
+ * tool-call tokens into visible text. Used to gate the per-stream healer so
69
+ * non-Kimi providers do not pay for the scan.
70
+ */
71
+ export declare function modelMayLeakKimiToolCalls(provider: string, modelId: string): boolean;
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Utility functions for mapping unified ToolChoice to provider-specific formats.
3
+ */
4
+ import type { ToolChoice } from "../types";
5
+ /** OpenAI Completions API tool choice format */
6
+ export type OpenAICompletionsToolChoice = "auto" | "none" | "required" | {
7
+ type: "function";
8
+ function: {
9
+ name: string;
10
+ };
11
+ } | undefined;
12
+ /** OpenAI Responses API tool choice format (flat structure) */
13
+ export type OpenAIResponsesToolChoice = "auto" | "none" | "required" | {
14
+ type: "function";
15
+ name: string;
16
+ } | {
17
+ type: "custom";
18
+ name: string;
19
+ } | undefined;
20
+ /** Anthropic-compatible tool choice format */
21
+ export type AnthropicToolChoice = "auto" | "none" | "any" | {
22
+ type: "tool";
23
+ name: string;
24
+ } | undefined;
25
+ /**
26
+ * Map unified ToolChoice to OpenAI Completions API format.
27
+ * - "any" → "required"
28
+ * - { type: "tool", name } → { type: "function", function: { name } }
29
+ */
30
+ export declare function mapToOpenAICompletionsToolChoice(choice?: ToolChoice): OpenAICompletionsToolChoice;
31
+ /**
32
+ * Returns true when an OpenAI-completions `tool_choice` value forces a tool
33
+ * call (`"required"` or a function-name pin), as opposed to leaving it open
34
+ * (`"auto"`, `"none"`, or unset). Accepts `unknown` because the param shape
35
+ * pulled from the OpenAI SDK (`ChatCompletionToolChoiceOption`) widens with
36
+ * each release; this check only needs the open/forced bit.
37
+ */
38
+ export declare function isForcedToolChoice(choice: unknown): boolean;
39
+ /**
40
+ * Map unified ToolChoice to OpenAI Responses API format.
41
+ * - "any" → "required"
42
+ * - { type: "tool", name } → { type: "function", name } (flat structure)
43
+ */
44
+ export declare function mapToOpenAIResponsesToolChoice(choice?: ToolChoice): OpenAIResponsesToolChoice;
45
+ /**
46
+ * Map unified ToolChoice to Anthropic-compatible format.
47
+ * - "required" → "any"
48
+ * - { type: "function", ... } → { type: "tool", name }
49
+ */
50
+ export declare function mapToAnthropicToolChoice(choice?: ToolChoice): AnthropicToolChoice;
@@ -0,0 +1,17 @@
1
+ import type { Tool, ToolCall } from "../types";
2
+ /**
3
+ * Finds a tool by name and validates the tool call arguments against its schema.
4
+ * @param tools Array of tool definitions
5
+ * @param toolCall The tool call from the LLM
6
+ * @returns The validated arguments
7
+ * @throws Error if tool is not found or validation fails
8
+ */
9
+ export declare function validateToolCall(tools: Tool[], toolCall: ToolCall): ToolCall["arguments"];
10
+ /**
11
+ * Validates tool call arguments against the tool's schema (Zod or plain JSON
12
+ * Schema). Applies LLM-quirk coercions (numeric strings, JSON-string
13
+ * containers, null-for-optional, null-for-default) before declaring failure.
14
+ *
15
+ * @throws Error with a formatted message when validation cannot be reconciled.
16
+ */
17
+ export declare function validateToolArguments(tool: Tool, toolCall: ToolCall): ToolCall["arguments"];
@@ -0,0 +1,28 @@
1
+ import type { ResponseInput } from "openai/resources/responses/responses";
2
+ import type { CacheRetention, OpenAIResponsesHistoryPayload, ProviderPayload } from "./types";
3
+ export { isRecord } from "@gajae-code/utils";
4
+ export declare function normalizeSystemPrompts(systemPrompt: readonly string[] | string | undefined | null): string[];
5
+ export declare function toNumber(value: unknown): number | undefined;
6
+ export declare function toPositiveNumber(value: unknown, fallback: number): number;
7
+ export declare function toBoolean(value: unknown): boolean | undefined;
8
+ export declare function normalizeToolCallId(id: string): string;
9
+ type ResponsesToolItemIdPrefix = "fc" | "ctc";
10
+ export declare function normalizeResponsesToolCallId(id: string, itemPrefix?: ResponsesToolItemIdPrefix): {
11
+ callId: string;
12
+ itemId: string;
13
+ };
14
+ /**
15
+ * Truncate an OpenAI Responses API item ID to 64 characters.
16
+ * IDs exceeding the limit are replaced with a hash-based ID using the given prefix.
17
+ */
18
+ export declare function truncateResponseItemId(id: string, prefix: string): string;
19
+ export declare function sanitizeOpenAIResponsesHistoryItemsForReplay(items: Array<Record<string, unknown>>): ResponseInput;
20
+ export declare function createOpenAIResponsesHistoryPayload(provider: string, items: Array<Record<string, unknown>>, incremental?: boolean): OpenAIResponsesHistoryPayload;
21
+ export declare function getOpenAIResponsesHistoryPayload(providerPayload: ProviderPayload | undefined, currentProvider: string, fallbackProvider?: string): OpenAIResponsesHistoryPayload | undefined;
22
+ export declare function getOpenAIResponsesHistoryItems(providerPayload: ProviderPayload | undefined, currentProvider: string, fallbackProvider?: string): Array<Record<string, unknown>> | undefined;
23
+ /**
24
+ * Resolve cache retention preference.
25
+ * Defaults to "short" and uses PI_CACHE_RETENTION for backward compatibility.
26
+ */
27
+ export declare function resolveCacheRetention(cacheRetention?: CacheRetention): CacheRetention;
28
+ export declare function isAnthropicOAuthToken(key: string): boolean;
package/package.json ADDED
@@ -0,0 +1,146 @@
1
+ {
2
+ "type": "module",
3
+ "name": "@gajae-code/ai",
4
+ "version": "0.1.1",
5
+ "description": "Unified LLM API with automatic model discovery and provider configuration",
6
+ "homepage": "https://gajae-code.dev",
7
+ "author": "Can Boluk",
8
+ "contributors": [
9
+ "Mario Zechner"
10
+ ],
11
+ "license": "MIT",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/gajae-ai/gajae-code.git",
15
+ "directory": "packages/ai"
16
+ },
17
+ "bugs": {
18
+ "url": "https://github.com/gajae-ai/gajae-code/issues"
19
+ },
20
+ "keywords": [
21
+ "ai",
22
+ "llm",
23
+ "openai",
24
+ "anthropic",
25
+ "gemini",
26
+ "unified",
27
+ "api"
28
+ ],
29
+ "main": "./src/index.ts",
30
+ "types": "./dist/types/index.d.ts",
31
+ "bin": {
32
+ "pi-ai": "./src/cli.ts"
33
+ },
34
+ "scripts": {
35
+ "check": "biome check . && bun run check:types",
36
+ "check:types": "tsgo -p tsconfig.json --noEmit",
37
+ "lint": "biome lint .",
38
+ "test": "bun test",
39
+ "fix": "biome check --write --unsafe .",
40
+ "fmt": "biome format --write .",
41
+ "generate-models": "bun scripts/generate-models.ts"
42
+ },
43
+ "dependencies": {
44
+ "@anthropic-ai/sdk": "^0.94.0",
45
+ "@bufbuild/protobuf": "^2.12.0",
46
+ "@gajae-code/utils": "0.1.1",
47
+ "openai": "^6.36.0",
48
+ "partial-json": "^0.1.7",
49
+ "zod": "4.4.3"
50
+ },
51
+ "devDependencies": {
52
+ "@types/bun": "^1.3.14"
53
+ },
54
+ "engines": {
55
+ "bun": ">=1.3.14"
56
+ },
57
+ "files": [
58
+ "src",
59
+ "README.md",
60
+ "CHANGELOG.md",
61
+ "dist/types"
62
+ ],
63
+ "exports": {
64
+ ".": {
65
+ "types": "./dist/types/index.d.ts",
66
+ "import": "./src/index.ts"
67
+ },
68
+ "./*": {
69
+ "types": "./dist/types/*.d.ts",
70
+ "import": "./src/*.ts"
71
+ },
72
+ "./auth-broker": {
73
+ "types": "./dist/types/auth-broker/index.d.ts",
74
+ "import": "./src/auth-broker/index.ts"
75
+ },
76
+ "./auth-broker/*": {
77
+ "types": "./dist/types/auth-broker/*.d.ts",
78
+ "import": "./src/auth-broker/*.ts"
79
+ },
80
+ "./auth-gateway": {
81
+ "types": "./dist/types/auth-gateway/index.d.ts",
82
+ "import": "./src/auth-gateway/index.ts"
83
+ },
84
+ "./auth-gateway/*": {
85
+ "types": "./dist/types/auth-gateway/*.d.ts",
86
+ "import": "./src/auth-gateway/*.ts"
87
+ },
88
+ "./models.json": {
89
+ "types": "./dist/types/models.json.d.d.ts",
90
+ "import": "./src/models.json"
91
+ },
92
+ "./provider-models": {
93
+ "types": "./dist/types/provider-models/index.d.ts",
94
+ "import": "./src/provider-models/index.ts"
95
+ },
96
+ "./provider-models/*": {
97
+ "types": "./dist/types/provider-models/*.d.ts",
98
+ "import": "./src/provider-models/*.ts"
99
+ },
100
+ "./providers/*": {
101
+ "types": "./dist/types/providers/*.d.ts",
102
+ "import": "./src/providers/*.ts"
103
+ },
104
+ "./providers/cursor/gen/*": {
105
+ "types": "./dist/types/providers/cursor/gen/*.d.ts",
106
+ "import": "./src/providers/cursor/gen/*.ts"
107
+ },
108
+ "./providers/openai-codex/*": {
109
+ "types": "./dist/types/providers/openai-codex/*.d.ts",
110
+ "import": "./src/providers/openai-codex/*.ts"
111
+ },
112
+ "./usage/*": {
113
+ "types": "./dist/types/usage/*.d.ts",
114
+ "import": "./src/usage/*.ts"
115
+ },
116
+ "./utils/*": {
117
+ "types": "./dist/types/utils/*.d.ts",
118
+ "import": "./src/utils/*.ts"
119
+ },
120
+ "./utils/discovery": {
121
+ "types": "./dist/types/utils/discovery/index.d.ts",
122
+ "import": "./src/utils/discovery/index.ts"
123
+ },
124
+ "./utils/discovery/*": {
125
+ "types": "./dist/types/utils/discovery/*.d.ts",
126
+ "import": "./src/utils/discovery/*.ts"
127
+ },
128
+ "./utils/oauth": {
129
+ "types": "./dist/types/utils/oauth/index.d.ts",
130
+ "import": "./src/utils/oauth/index.ts"
131
+ },
132
+ "./utils/oauth/*": {
133
+ "types": "./dist/types/utils/oauth/*.d.ts",
134
+ "import": "./src/utils/oauth/*.ts"
135
+ },
136
+ "./utils/schema": {
137
+ "types": "./dist/types/utils/schema/index.d.ts",
138
+ "import": "./src/utils/schema/index.ts"
139
+ },
140
+ "./utils/schema/*": {
141
+ "types": "./dist/types/utils/schema/*.d.ts",
142
+ "import": "./src/utils/schema/*.ts"
143
+ },
144
+ "./*.js": "./src/*.ts"
145
+ }
146
+ }
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Custom API provider registry.
3
+ *
4
+ * Allows extensions to register streaming functions for custom API types
5
+ * (e.g., "vertex-Anthropic model-api") that are not built into stream.ts.
6
+ */
7
+ import type {
8
+ Api,
9
+ AssistantMessageEventStream,
10
+ Context,
11
+ KnownApi,
12
+ Model,
13
+ SimpleStreamOptions,
14
+ StreamOptions,
15
+ } from "./types";
16
+
17
+ const BUILTIN_APIS = new Set<KnownApi>([
18
+ "openai-completions",
19
+ "openai-responses",
20
+ "openai-codex-responses",
21
+ "azure-openai-responses",
22
+ "anthropic-messages",
23
+ "bedrock-converse-stream",
24
+ "google-generative-ai",
25
+ "google-gemini-cli",
26
+ "google-vertex",
27
+ "ollama-chat",
28
+ "cursor-agent",
29
+ ]);
30
+
31
+ export type CustomStreamFn = (
32
+ model: Model<Api>,
33
+ context: Context,
34
+ options?: StreamOptions,
35
+ ) => AssistantMessageEventStream;
36
+ export type CustomStreamSimpleFn = (
37
+ model: Model<Api>,
38
+ context: Context,
39
+ options?: SimpleStreamOptions,
40
+ ) => AssistantMessageEventStream;
41
+
42
+ export interface RegisteredCustomApi {
43
+ stream: CustomStreamFn;
44
+ streamSimple: CustomStreamSimpleFn;
45
+ sourceId?: string;
46
+ }
47
+
48
+ const customApiRegistry = new Map<string, RegisteredCustomApi>();
49
+
50
+ function assertCustomApiName(api: string): void {
51
+ if (BUILTIN_APIS.has(api as KnownApi)) {
52
+ throw new Error(`Cannot register custom API "${api}": built-in API names are reserved.`);
53
+ }
54
+ }
55
+
56
+ /**
57
+ * Register a custom API streaming function.
58
+ */
59
+ export function registerCustomApi(
60
+ api: string,
61
+ streamSimple: CustomStreamSimpleFn,
62
+ sourceId?: string,
63
+ stream?: CustomStreamFn,
64
+ ): void {
65
+ assertCustomApiName(api);
66
+ customApiRegistry.set(api, {
67
+ stream: stream ?? ((model, context, options) => streamSimple(model, context, options as SimpleStreamOptions)),
68
+ streamSimple,
69
+ sourceId,
70
+ });
71
+ }
72
+
73
+ /**
74
+ * Get a custom API provider by API identifier.
75
+ */
76
+ export function getCustomApi(api: string): RegisteredCustomApi | undefined {
77
+ return customApiRegistry.get(api);
78
+ }
79
+
80
+ /**
81
+ * Remove all custom APIs registered by a specific source (e.g., extension path).
82
+ */
83
+ export function unregisterCustomApis(sourceId: string): void {
84
+ for (const [api, entry] of customApiRegistry.entries()) {
85
+ if (entry.sourceId === sourceId) {
86
+ customApiRegistry.delete(api);
87
+ }
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Clear all custom API registrations.
93
+ */
94
+ export function clearCustomApis(): void {
95
+ customApiRegistry.clear();
96
+ }