@prometheus-ai/ai 0.5.0

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 (369) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/README.md +1184 -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 +6 -0
  6. package/dist/types/auth-broker/refresher.d.ts +25 -0
  7. package/dist/types/auth-broker/remote-store.d.ts +101 -0
  8. package/dist/types/auth-broker/server.d.ts +32 -0
  9. package/dist/types/auth-broker/snapshot-cache.d.ts +17 -0
  10. package/dist/types/auth-broker/types.d.ts +107 -0
  11. package/dist/types/auth-broker/wire-schemas.d.ts +412 -0
  12. package/dist/types/auth-gateway/http.d.ts +39 -0
  13. package/dist/types/auth-gateway/index.d.ts +3 -0
  14. package/dist/types/auth-gateway/server.d.ts +36 -0
  15. package/dist/types/auth-gateway/types.d.ts +117 -0
  16. package/dist/types/auth-storage.d.ts +762 -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 +64 -0
  20. package/dist/types/model-thinking.d.ts +100 -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 +50 -0
  25. package/dist/types/provider-models/google.d.ts +24 -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 +323 -0
  29. package/dist/types/provider-models/special.d.ts +16 -0
  30. package/dist/types/providers/amazon-bedrock.d.ts +38 -0
  31. package/dist/types/providers/anthropic-client.d.ts +99 -0
  32. package/dist/types/providers/anthropic-messages-server-schema.d.ts +465 -0
  33. package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
  34. package/dist/types/providers/anthropic-wire.d.ts +262 -0
  35. package/dist/types/providers/anthropic.d.ts +206 -0
  36. package/dist/types/providers/aws-credentials.d.ts +43 -0
  37. package/dist/types/providers/aws-eventstream.d.ts +38 -0
  38. package/dist/types/providers/aws-sigv4.d.ts +55 -0
  39. package/dist/types/providers/azure-openai-responses.d.ts +15 -0
  40. package/dist/types/providers/cursor/gen/agent_pb.d.ts +13022 -0
  41. package/dist/types/providers/cursor.d.ts +43 -0
  42. package/dist/types/providers/error-message.d.ts +27 -0
  43. package/dist/types/providers/github-copilot-headers.d.ts +40 -0
  44. package/dist/types/providers/gitlab-duo.d.ts +27 -0
  45. package/dist/types/providers/google-auth.d.ts +24 -0
  46. package/dist/types/providers/google-gemini-cli.d.ts +81 -0
  47. package/dist/types/providers/google-gemini-headers.d.ts +18 -0
  48. package/dist/types/providers/google-shared.d.ts +171 -0
  49. package/dist/types/providers/google-types.d.ts +138 -0
  50. package/dist/types/providers/google-vertex.d.ts +7 -0
  51. package/dist/types/providers/google.d.ts +4 -0
  52. package/dist/types/providers/grammar.d.ts +1 -0
  53. package/dist/types/providers/kimi.d.ts +27 -0
  54. package/dist/types/providers/mock.d.ts +173 -0
  55. package/dist/types/providers/ollama.d.ts +6 -0
  56. package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
  57. package/dist/types/providers/openai-chat-server-schema.d.ts +817 -0
  58. package/dist/types/providers/openai-chat-server.d.ts +16 -0
  59. package/dist/types/providers/openai-codex/constants.d.ts +26 -0
  60. package/dist/types/providers/openai-codex/request-transformer.d.ts +49 -0
  61. package/dist/types/providers/openai-codex/response-handler.d.ts +17 -0
  62. package/dist/types/providers/openai-codex-responses.d.ts +67 -0
  63. package/dist/types/providers/openai-completions-compat.d.ts +27 -0
  64. package/dist/types/providers/openai-completions.d.ts +54 -0
  65. package/dist/types/providers/openai-responses-server-schema.d.ts +392 -0
  66. package/dist/types/providers/openai-responses-server.d.ts +17 -0
  67. package/dist/types/providers/openai-responses-shared.d.ts +105 -0
  68. package/dist/types/providers/openai-responses.d.ts +66 -0
  69. package/dist/types/providers/prometheus-native-client.d.ts +13 -0
  70. package/dist/types/providers/prometheus-native-server.d.ts +68 -0
  71. package/dist/types/providers/register-builtins.d.ts +31 -0
  72. package/dist/types/providers/synthetic.d.ts +26 -0
  73. package/dist/types/providers/transform-messages.d.ts +12 -0
  74. package/dist/types/providers/vision-guard.d.ts +20 -0
  75. package/dist/types/providers/xai-responses.d.ts +23 -0
  76. package/dist/types/rate-limit-utils.d.ts +19 -0
  77. package/dist/types/stream.d.ts +28 -0
  78. package/dist/types/types.d.ts +819 -0
  79. package/dist/types/usage/claude.d.ts +4 -0
  80. package/dist/types/usage/gemini.d.ts +2 -0
  81. package/dist/types/usage/github-copilot.d.ts +7 -0
  82. package/dist/types/usage/google-antigravity.d.ts +2 -0
  83. package/dist/types/usage/kimi.d.ts +2 -0
  84. package/dist/types/usage/minimax-code.d.ts +2 -0
  85. package/dist/types/usage/openai-codex.d.ts +3 -0
  86. package/dist/types/usage/shared.d.ts +1 -0
  87. package/dist/types/usage/zai.d.ts +2 -0
  88. package/dist/types/usage.d.ts +260 -0
  89. package/dist/types/utils/abort.d.ts +19 -0
  90. package/dist/types/utils/abortable-iterator.d.ts +4 -0
  91. package/dist/types/utils/anthropic-auth.d.ts +35 -0
  92. package/dist/types/utils/discovery/antigravity.d.ts +61 -0
  93. package/dist/types/utils/discovery/codex.d.ts +38 -0
  94. package/dist/types/utils/discovery/cursor.d.ts +23 -0
  95. package/dist/types/utils/discovery/gemini.d.ts +25 -0
  96. package/dist/types/utils/discovery/index.d.ts +4 -0
  97. package/dist/types/utils/discovery/openai-compatible.d.ts +72 -0
  98. package/dist/types/utils/event-stream.d.ts +28 -0
  99. package/dist/types/utils/fireworks-model-id.d.ts +10 -0
  100. package/dist/types/utils/foundry.d.ts +1 -0
  101. package/dist/types/utils/http-inspector.d.ts +31 -0
  102. package/dist/types/utils/idle-iterator.d.ts +78 -0
  103. package/dist/types/utils/json-parse.d.ts +37 -0
  104. package/dist/types/utils/oauth/__tests__/xai-oauth.test.d.ts +1 -0
  105. package/dist/types/utils/oauth/alibaba-coding-plan.d.ts +18 -0
  106. package/dist/types/utils/oauth/anthropic.d.ts +22 -0
  107. package/dist/types/utils/oauth/api-key-login.d.ts +35 -0
  108. package/dist/types/utils/oauth/api-key-validation.d.ts +27 -0
  109. package/dist/types/utils/oauth/callback-server.d.ts +57 -0
  110. package/dist/types/utils/oauth/cerebras.d.ts +1 -0
  111. package/dist/types/utils/oauth/cloudflare-ai-gateway.d.ts +18 -0
  112. package/dist/types/utils/oauth/cursor.d.ts +15 -0
  113. package/dist/types/utils/oauth/deepseek.d.ts +10 -0
  114. package/dist/types/utils/oauth/firepass.d.ts +1 -0
  115. package/dist/types/utils/oauth/fireworks.d.ts +1 -0
  116. package/dist/types/utils/oauth/github-copilot.d.ts +38 -0
  117. package/dist/types/utils/oauth/gitlab-duo.d.ts +3 -0
  118. package/dist/types/utils/oauth/google-antigravity.d.ts +11 -0
  119. package/dist/types/utils/oauth/google-gemini-cli.d.ts +10 -0
  120. package/dist/types/utils/oauth/google-oauth-shared.d.ts +28 -0
  121. package/dist/types/utils/oauth/huggingface.d.ts +19 -0
  122. package/dist/types/utils/oauth/index.d.ts +38 -0
  123. package/dist/types/utils/oauth/kagi.d.ts +17 -0
  124. package/dist/types/utils/oauth/kilo.d.ts +5 -0
  125. package/dist/types/utils/oauth/kimi.d.ts +21 -0
  126. package/dist/types/utils/oauth/litellm.d.ts +18 -0
  127. package/dist/types/utils/oauth/lm-studio.d.ts +17 -0
  128. package/dist/types/utils/oauth/minimax-code.d.ts +28 -0
  129. package/dist/types/utils/oauth/moonshot.d.ts +1 -0
  130. package/dist/types/utils/oauth/nanogpt.d.ts +1 -0
  131. package/dist/types/utils/oauth/nvidia.d.ts +18 -0
  132. package/dist/types/utils/oauth/ollama-cloud.d.ts +2 -0
  133. package/dist/types/utils/oauth/ollama.d.ts +18 -0
  134. package/dist/types/utils/oauth/openai-codex.d.ts +21 -0
  135. package/dist/types/utils/oauth/opencode.d.ts +18 -0
  136. package/dist/types/utils/oauth/openrouter.d.ts +1 -0
  137. package/dist/types/utils/oauth/parallel.d.ts +17 -0
  138. package/dist/types/utils/oauth/perplexity.d.ts +9 -0
  139. package/dist/types/utils/oauth/pkce.d.ts +8 -0
  140. package/dist/types/utils/oauth/qianfan.d.ts +17 -0
  141. package/dist/types/utils/oauth/qwen-portal.d.ts +19 -0
  142. package/dist/types/utils/oauth/synthetic.d.ts +1 -0
  143. package/dist/types/utils/oauth/tavily.d.ts +17 -0
  144. package/dist/types/utils/oauth/together.d.ts +1 -0
  145. package/dist/types/utils/oauth/types.d.ts +44 -0
  146. package/dist/types/utils/oauth/venice.d.ts +18 -0
  147. package/dist/types/utils/oauth/vercel-ai-gateway.d.ts +18 -0
  148. package/dist/types/utils/oauth/vllm.d.ts +16 -0
  149. package/dist/types/utils/oauth/wafer.d.ts +2 -0
  150. package/dist/types/utils/oauth/xai-oauth.d.ts +60 -0
  151. package/dist/types/utils/oauth/xiaomi.d.ts +25 -0
  152. package/dist/types/utils/oauth/zai.d.ts +18 -0
  153. package/dist/types/utils/oauth/zenmux.d.ts +1 -0
  154. package/dist/types/utils/oauth/zhipu.d.ts +18 -0
  155. package/dist/types/utils/overflow.d.ts +54 -0
  156. package/dist/types/utils/parse-bind.d.ts +23 -0
  157. package/dist/types/utils/provider-response.d.ts +3 -0
  158. package/dist/types/utils/request-debug.d.ts +29 -0
  159. package/dist/types/utils/retry-after.d.ts +3 -0
  160. package/dist/types/utils/retry.d.ts +26 -0
  161. package/dist/types/utils/schema/adapt.d.ts +24 -0
  162. package/dist/types/utils/schema/compatibility.d.ts +30 -0
  163. package/dist/types/utils/schema/dereference.d.ts +11 -0
  164. package/dist/types/utils/schema/draft.d.ts +10 -0
  165. package/dist/types/utils/schema/equality.d.ts +4 -0
  166. package/dist/types/utils/schema/fields.d.ts +49 -0
  167. package/dist/types/utils/schema/index.d.ts +13 -0
  168. package/dist/types/utils/schema/json-schema-validator.d.ts +12 -0
  169. package/dist/types/utils/schema/meta-validator.d.ts +2 -0
  170. package/dist/types/utils/schema/normalize.d.ts +93 -0
  171. package/dist/types/utils/schema/spill.d.ts +8 -0
  172. package/dist/types/utils/schema/stamps.d.ts +25 -0
  173. package/dist/types/utils/schema/types.d.ts +4 -0
  174. package/dist/types/utils/schema/wire.d.ts +53 -0
  175. package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -0
  176. package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
  177. package/dist/types/utils/sse-debug.d.ts +10 -0
  178. package/dist/types/utils/stream-markup-healing.d.ts +80 -0
  179. package/dist/types/utils/tool-choice.d.ts +50 -0
  180. package/dist/types/utils/validation.d.ts +17 -0
  181. package/dist/types/utils.d.ts +28 -0
  182. package/package.json +142 -0
  183. package/src/api-registry.ts +96 -0
  184. package/src/auth-broker/client.ts +358 -0
  185. package/src/auth-broker/index.ts +6 -0
  186. package/src/auth-broker/refresher.ts +117 -0
  187. package/src/auth-broker/remote-store.ts +637 -0
  188. package/src/auth-broker/server.ts +644 -0
  189. package/src/auth-broker/snapshot-cache.ts +174 -0
  190. package/src/auth-broker/types.ts +130 -0
  191. package/src/auth-broker/wire-schemas.ts +200 -0
  192. package/src/auth-gateway/http.ts +194 -0
  193. package/src/auth-gateway/index.ts +3 -0
  194. package/src/auth-gateway/server.ts +822 -0
  195. package/src/auth-gateway/types.ts +143 -0
  196. package/src/auth-storage.ts +4608 -0
  197. package/src/index.ts +54 -0
  198. package/src/model-cache.ts +129 -0
  199. package/src/model-manager.ts +469 -0
  200. package/src/model-thinking.ts +756 -0
  201. package/src/models.json +60287 -0
  202. package/src/models.json.d.ts +9 -0
  203. package/src/models.ts +56 -0
  204. package/src/prompts/turn-aborted-guidance.md +4 -0
  205. package/src/provider-details.ts +90 -0
  206. package/src/provider-models/bundled-references.ts +38 -0
  207. package/src/provider-models/descriptors.ts +364 -0
  208. package/src/provider-models/google.ts +88 -0
  209. package/src/provider-models/index.ts +5 -0
  210. package/src/provider-models/ollama.ts +153 -0
  211. package/src/provider-models/openai-compat.ts +2904 -0
  212. package/src/provider-models/special.ts +67 -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 +681 -0
  217. package/src/providers/anthropic-wire.ts +268 -0
  218. package/src/providers/anthropic.ts +3106 -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 +3027 -0
  249. package/src/providers/openai-completions-compat.ts +320 -0
  250. package/src/providers/openai-completions.ts +2002 -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 +956 -0
  254. package/src/providers/openai-responses.ts +679 -0
  255. package/src/providers/prometheus-native-client.ts +228 -0
  256. package/src/providers/prometheus-native-server.ts +212 -0
  257. package/src/providers/register-builtins.ts +457 -0
  258. package/src/providers/synthetic.ts +50 -0
  259. package/src/providers/transform-messages.ts +382 -0
  260. package/src/providers/vision-guard.ts +52 -0
  261. package/src/providers/xai-responses.ts +82 -0
  262. package/src/rate-limit-utils.ts +91 -0
  263. package/src/stream.ts +1068 -0
  264. package/src/types.ts +965 -0
  265. package/src/usage/claude.ts +482 -0
  266. package/src/usage/gemini.ts +250 -0
  267. package/src/usage/github-copilot.ts +421 -0
  268. package/src/usage/google-antigravity.ts +201 -0
  269. package/src/usage/kimi.ts +271 -0
  270. package/src/usage/minimax-code.ts +31 -0
  271. package/src/usage/openai-codex.ts +503 -0
  272. package/src/usage/shared.ts +10 -0
  273. package/src/usage/zai.ts +247 -0
  274. package/src/usage.ts +185 -0
  275. package/src/utils/abort.ts +51 -0
  276. package/src/utils/abortable-iterator.ts +69 -0
  277. package/src/utils/anthropic-auth.ts +93 -0
  278. package/src/utils/discovery/antigravity.ts +261 -0
  279. package/src/utils/discovery/codex.ts +371 -0
  280. package/src/utils/discovery/cursor.ts +306 -0
  281. package/src/utils/discovery/gemini.ts +248 -0
  282. package/src/utils/discovery/index.ts +4 -0
  283. package/src/utils/discovery/openai-compatible.ts +224 -0
  284. package/src/utils/event-stream.ts +142 -0
  285. package/src/utils/fireworks-model-id.ts +30 -0
  286. package/src/utils/foundry.ts +8 -0
  287. package/src/utils/http-inspector.ts +176 -0
  288. package/src/utils/idle-iterator.ts +273 -0
  289. package/src/utils/json-parse.ts +182 -0
  290. package/src/utils/oauth/__tests__/xai-oauth.test.ts +107 -0
  291. package/src/utils/oauth/alibaba-coding-plan.ts +59 -0
  292. package/src/utils/oauth/anthropic.ts +273 -0
  293. package/src/utils/oauth/api-key-login.ts +87 -0
  294. package/src/utils/oauth/api-key-validation.ts +92 -0
  295. package/src/utils/oauth/callback-server.ts +276 -0
  296. package/src/utils/oauth/cerebras.ts +16 -0
  297. package/src/utils/oauth/cloudflare-ai-gateway.ts +48 -0
  298. package/src/utils/oauth/cursor.ts +157 -0
  299. package/src/utils/oauth/deepseek.ts +53 -0
  300. package/src/utils/oauth/firepass.ts +24 -0
  301. package/src/utils/oauth/fireworks.ts +15 -0
  302. package/src/utils/oauth/github-copilot.ts +362 -0
  303. package/src/utils/oauth/gitlab-duo.ts +123 -0
  304. package/src/utils/oauth/google-antigravity.ts +200 -0
  305. package/src/utils/oauth/google-gemini-cli.ts +256 -0
  306. package/src/utils/oauth/google-oauth-shared.ts +110 -0
  307. package/src/utils/oauth/huggingface.ts +62 -0
  308. package/src/utils/oauth/index.ts +502 -0
  309. package/src/utils/oauth/kagi.ts +47 -0
  310. package/src/utils/oauth/kilo.ts +87 -0
  311. package/src/utils/oauth/kimi.ts +254 -0
  312. package/src/utils/oauth/litellm.ts +47 -0
  313. package/src/utils/oauth/lm-studio.ts +38 -0
  314. package/src/utils/oauth/minimax-code.ts +80 -0
  315. package/src/utils/oauth/moonshot.ts +23 -0
  316. package/src/utils/oauth/nanogpt.ts +15 -0
  317. package/src/utils/oauth/nvidia.ts +70 -0
  318. package/src/utils/oauth/oauth.html +199 -0
  319. package/src/utils/oauth/ollama-cloud.ts +28 -0
  320. package/src/utils/oauth/ollama.ts +47 -0
  321. package/src/utils/oauth/openai-codex.ts +299 -0
  322. package/src/utils/oauth/opencode.ts +49 -0
  323. package/src/utils/oauth/openrouter.ts +20 -0
  324. package/src/utils/oauth/parallel.ts +46 -0
  325. package/src/utils/oauth/perplexity.ts +206 -0
  326. package/src/utils/oauth/pkce.ts +18 -0
  327. package/src/utils/oauth/qianfan.ts +58 -0
  328. package/src/utils/oauth/qwen-portal.ts +60 -0
  329. package/src/utils/oauth/synthetic.ts +15 -0
  330. package/src/utils/oauth/tavily.ts +46 -0
  331. package/src/utils/oauth/together.ts +16 -0
  332. package/src/utils/oauth/types.ts +102 -0
  333. package/src/utils/oauth/venice.ts +59 -0
  334. package/src/utils/oauth/vercel-ai-gateway.ts +47 -0
  335. package/src/utils/oauth/vllm.ts +40 -0
  336. package/src/utils/oauth/wafer.ts +50 -0
  337. package/src/utils/oauth/xai-oauth.ts +342 -0
  338. package/src/utils/oauth/xiaomi.ts +194 -0
  339. package/src/utils/oauth/zai.ts +60 -0
  340. package/src/utils/oauth/zenmux.ts +15 -0
  341. package/src/utils/oauth/zhipu.ts +60 -0
  342. package/src/utils/overflow.ts +137 -0
  343. package/src/utils/parse-bind.ts +54 -0
  344. package/src/utils/provider-response.ts +30 -0
  345. package/src/utils/request-debug.ts +336 -0
  346. package/src/utils/retry-after.ts +110 -0
  347. package/src/utils/retry.ts +54 -0
  348. package/src/utils/schema/CONSTRAINTS.md +164 -0
  349. package/src/utils/schema/adapt.ts +36 -0
  350. package/src/utils/schema/compatibility.ts +435 -0
  351. package/src/utils/schema/dereference.ts +98 -0
  352. package/src/utils/schema/draft.ts +341 -0
  353. package/src/utils/schema/equality.ts +97 -0
  354. package/src/utils/schema/fields.ts +191 -0
  355. package/src/utils/schema/index.ts +13 -0
  356. package/src/utils/schema/json-schema-validator.ts +577 -0
  357. package/src/utils/schema/meta-validator.ts +167 -0
  358. package/src/utils/schema/normalize.ts +1588 -0
  359. package/src/utils/schema/spill.ts +43 -0
  360. package/src/utils/schema/stamps.ts +97 -0
  361. package/src/utils/schema/types.ts +10 -0
  362. package/src/utils/schema/wire.ts +293 -0
  363. package/src/utils/schema/zod-decontaminate.ts +331 -0
  364. package/src/utils/sdk-stream-timeout.ts +43 -0
  365. package/src/utils/sse-debug.ts +289 -0
  366. package/src/utils/stream-markup-healing.ts +612 -0
  367. package/src/utils/tool-choice.ts +99 -0
  368. package/src/utils/validation.ts +1024 -0
  369. package/src/utils.ts +166 -0
@@ -0,0 +1,435 @@
1
+ import {
2
+ CCA_UNSUPPORTED_SCHEMA_FIELDS,
3
+ COMBINATOR_KEYS,
4
+ NON_STRUCTURAL_SCHEMA_KEYS,
5
+ UNSUPPORTED_SCHEMA_FIELDS,
6
+ } from "./fields";
7
+ import { isValidJsonSchema } from "./meta-validator";
8
+ import { isJsonObject, type JsonObject } from "./types";
9
+
10
+ /**
11
+ * Schema compatibility audits.
12
+ *
13
+ * Each provider has a different idea of what JSON Schema features it accepts
14
+ * for tool definitions. The normalizers in `normalize.ts`, `strict-mode`,
15
+ * and `adapt.ts` rewrite incoming schemas to fit. This module is the
16
+ * *audit* counterpart: it walks a (presumably already-sanitized) schema and
17
+ * reports any feature the target provider would reject. Tests use it to lock
18
+ * down the contract; the runtime uses it to fail-open with diagnostic logs
19
+ * rather than silently shipping a broken tool definition.
20
+ */
21
+ export type SchemaCompatibilityProvider = "openai-strict" | "google" | "cloud-code-assist-claude";
22
+
23
+ export interface SchemaCompatibilityViolation {
24
+ path: string;
25
+ rule: string;
26
+ message: string;
27
+ key?: string;
28
+ value?: unknown;
29
+ }
30
+
31
+ export interface SchemaCompatibilityResult {
32
+ provider: SchemaCompatibilityProvider;
33
+ compatible: boolean;
34
+ violations: SchemaCompatibilityViolation[];
35
+ }
36
+
37
+ export interface StrictSchemaEnforcementResult {
38
+ schema: Record<string, unknown>;
39
+ strict: boolean;
40
+ }
41
+
42
+ // Per-provider forbidden-key sets. Subsets of the shared `fields.ts` constants
43
+ // plus a few provider-specific extras (`const`, `nullable`) folded in here so
44
+ // each rule is defined in exactly one place.
45
+ const STRICT_FORBIDDEN_KEYS: Record<string, true> = { ...NON_STRUCTURAL_SCHEMA_KEYS, const: true, nullable: true };
46
+ const GOOGLE_FORBIDDEN_KEYS: Record<string, true> = { ...UNSUPPORTED_SCHEMA_FIELDS, const: true };
47
+ const CCA_FORBIDDEN_KEYS: Record<string, true> = { ...CCA_UNSUPPORTED_SCHEMA_FIELDS, const: true };
48
+
49
+ // Keys whose values are JSON-Schema *containers* (arrays of values, scalars,
50
+ // etc.) rather than nested schemas. The traversal must skip these — recursing
51
+ // would walk into `enum` strings or `default` objects and emit spurious
52
+ // violations against keys that happen to share JSON-Schema keyword names.
53
+ const NON_SCHEMA_CONTAINER_ARRAY_KEYS: Record<string, true> = {
54
+ enum: true,
55
+ required: true,
56
+ examples: true,
57
+ type: true,
58
+ };
59
+ const NON_SCHEMA_CONTAINER_OBJECT_KEYS: Record<string, true> = { const: true, default: true, example: true };
60
+
61
+ interface TraversalState {
62
+ path: string;
63
+ }
64
+
65
+ function createViolation(
66
+ path: string,
67
+ rule: string,
68
+ message: string,
69
+ key?: string,
70
+ value?: unknown,
71
+ ): SchemaCompatibilityViolation {
72
+ return {
73
+ path,
74
+ rule,
75
+ message,
76
+ ...(key === undefined ? {} : { key }),
77
+ ...(value === undefined ? {} : { value }),
78
+ };
79
+ }
80
+
81
+ /**
82
+ * Recursively visit every schema node in a JSON Schema tree.
83
+ *
84
+ * The walker is *structural*, not type-aware: it knows which keywords contain
85
+ * nested schemas vs. plain values, so it descends into `properties.*`,
86
+ * `$defs.*`, `items`, combinator arrays, etc. but never into `enum`, `const`,
87
+ * `default`, or `type` arrays.
88
+ */
89
+ function walkSchema(
90
+ value: unknown,
91
+ state: TraversalState,
92
+ visitNode: (node: JsonObject, state: TraversalState) => void,
93
+ ): void {
94
+ if (Array.isArray(value)) {
95
+ for (let index = 0; index < value.length; index++) {
96
+ walkSchema(value[index], { path: `${state.path}[${index}]` }, visitNode);
97
+ }
98
+ return;
99
+ }
100
+
101
+ if (!isJsonObject(value)) {
102
+ return;
103
+ }
104
+
105
+ visitNode(value, state);
106
+
107
+ for (const key in value) {
108
+ // Schema-map keywords: value is `{ name: schema, … }`. Recurse into each
109
+ // entry's schema rather than the map object itself.
110
+ const entry = value[key];
111
+ if (key === "properties" || key === "$defs" || key === "definitions" || key === "dependentSchemas") {
112
+ if (isJsonObject(entry)) {
113
+ for (const name in entry) {
114
+ const child = entry[name];
115
+ walkSchema(child, { path: `${state.path}.${key}.${name}` }, visitNode);
116
+ }
117
+ }
118
+ continue;
119
+ }
120
+ // Non-schema container keywords — values are not schemas, do not descend.
121
+
122
+ if (key in NON_SCHEMA_CONTAINER_ARRAY_KEYS || key in NON_SCHEMA_CONTAINER_OBJECT_KEYS) {
123
+ continue;
124
+ }
125
+ // Array-of-schemas keywords (e.g. `allOf`, `anyOf`, `oneOf`, `prefixItems`).
126
+
127
+ if (Array.isArray(entry)) {
128
+ for (let index = 0; index < entry.length; index++) {
129
+ walkSchema(entry[index], { path: `${state.path}.${key}[${index}]` }, visitNode);
130
+ }
131
+ continue;
132
+ }
133
+
134
+ if (isJsonObject(entry)) {
135
+ walkSchema(entry, { path: `${state.path}.${key}` }, visitNode);
136
+ }
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Strict-mode audit (OpenAI Responses / Codex `strict: true`):
142
+ * 1. Forbid keywords that strict mode disallows (`format`, `pattern`, `const`,
143
+ * `nullable`, etc. — see `STRICT_FORBIDDEN_KEYS`).
144
+ * 2. Every node must declare *something* concrete: a `type`, a combinator,
145
+ * a `$ref`, or a `not` branch. Empty `{}` is rejected.
146
+ * 3. Object nodes must set `additionalProperties: false`, declare a real
147
+ * `properties` map, and require every property in that map. Required
148
+ * properties not in `properties` are also rejected — strict mode demands
149
+ * a closed object shape.
150
+ */
151
+ function validateStrictNode(node: JsonObject, state: TraversalState): SchemaCompatibilityViolation[] {
152
+ const violations: SchemaCompatibilityViolation[] = [];
153
+
154
+ for (const key in node) {
155
+ const value = node[key];
156
+ if (!(key in STRICT_FORBIDDEN_KEYS)) {
157
+ continue;
158
+ }
159
+
160
+ violations.push(
161
+ createViolation(
162
+ `${state.path}.${key}`,
163
+ "strict-forbidden-key",
164
+ `Strict schema contains forbidden key "${key}"`,
165
+ key,
166
+ value,
167
+ ),
168
+ );
169
+ }
170
+ // Rule 2: node must declare at least one concrete shape descriptor.
171
+
172
+ const hasCombinator = COMBINATOR_KEYS.some(key => Array.isArray(node[key]));
173
+ const hasRef = typeof node.$ref === "string";
174
+ const hasNot = isJsonObject(node.not);
175
+ if (node.type === undefined && !hasCombinator && !hasRef && !hasNot) {
176
+ violations.push(
177
+ createViolation(
178
+ state.path,
179
+ "strict-unrepresentable-node",
180
+ "Strict schema node must declare type, combinator, $ref, or not",
181
+ ),
182
+ );
183
+ }
184
+ // Rules 3a-3d apply only to object-shaped nodes.
185
+
186
+ const isObjectNode = node.type === "object" || isJsonObject(node.properties);
187
+ if (!isObjectNode) {
188
+ return violations;
189
+ }
190
+
191
+ if (node.additionalProperties !== false) {
192
+ violations.push(
193
+ createViolation(
194
+ `${state.path}.additionalProperties`,
195
+ "strict-object-additional-properties",
196
+ "Strict object schema must set additionalProperties to false",
197
+ "additionalProperties",
198
+ node.additionalProperties,
199
+ ),
200
+ );
201
+ }
202
+ // 3b: `properties` must exist and be an object — without it strict mode has nothing to validate.
203
+
204
+ if (!isJsonObject(node.properties)) {
205
+ violations.push(
206
+ createViolation(
207
+ `${state.path}.properties`,
208
+ "strict-object-properties",
209
+ "Strict object schema must provide an object-valued properties map",
210
+ "properties",
211
+ node.properties,
212
+ ),
213
+ );
214
+ return violations;
215
+ }
216
+
217
+ const propertyNames = Object.keys(node.properties);
218
+ const requiredValues = Array.isArray(node.required)
219
+ ? node.required.filter((entry): entry is string => typeof entry === "string")
220
+ : [];
221
+ const requiredSet = new Set(requiredValues);
222
+
223
+ for (const propertyName of propertyNames) {
224
+ if (requiredSet.has(propertyName)) {
225
+ continue;
226
+ }
227
+ violations.push(
228
+ createViolation(
229
+ `${state.path}.required`,
230
+ "strict-object-required",
231
+ `Strict object schema must require property "${propertyName}"`,
232
+ "required",
233
+ node.required,
234
+ ),
235
+ );
236
+ }
237
+ // 3d: any property declared in `required` but missing from `properties` is unrepresentable.
238
+
239
+ const propertyNameSet = new Set(propertyNames);
240
+ for (const requiredKey of requiredValues) {
241
+ if (propertyNameSet.has(requiredKey)) {
242
+ continue;
243
+ }
244
+ violations.push(
245
+ createViolation(
246
+ `${state.path}.required`,
247
+ "strict-object-required-extra",
248
+ `Strict object schema requires non-existent property "${requiredKey}"`,
249
+ "required",
250
+ node.required,
251
+ ),
252
+ );
253
+ }
254
+
255
+ return violations;
256
+ }
257
+
258
+ function validateGoogleNode(node: JsonObject, state: TraversalState): SchemaCompatibilityViolation[] {
259
+ const violations: SchemaCompatibilityViolation[] = [];
260
+
261
+ for (const key in node) {
262
+ const value = node[key];
263
+ if (!(key in GOOGLE_FORBIDDEN_KEYS)) {
264
+ continue;
265
+ }
266
+ violations.push(
267
+ createViolation(
268
+ `${state.path}.${key}`,
269
+ "google-forbidden-key",
270
+ `Google schema contains unsupported key "${key}"`,
271
+ key,
272
+ value,
273
+ ),
274
+ );
275
+ }
276
+
277
+ if (Array.isArray(node.type)) {
278
+ violations.push(
279
+ createViolation(
280
+ `${state.path}.type`,
281
+ "google-type-array",
282
+ "Google schema type must be a scalar string, not an array",
283
+ "type",
284
+ node.type,
285
+ ),
286
+ );
287
+ }
288
+
289
+ return violations;
290
+ }
291
+
292
+ function validateCloudCodeAssistNode(node: JsonObject, state: TraversalState): SchemaCompatibilityViolation[] {
293
+ const violations: SchemaCompatibilityViolation[] = [];
294
+
295
+ for (const key in node) {
296
+ const value = node[key];
297
+ if (key in CCA_FORBIDDEN_KEYS) {
298
+ violations.push(
299
+ createViolation(
300
+ `${state.path}.${key}`,
301
+ "cca-forbidden-key",
302
+ `Cloud Code Assist schema contains unsupported key "${key}"`,
303
+ key,
304
+ value,
305
+ ),
306
+ );
307
+ }
308
+ }
309
+
310
+ if (Array.isArray(node.type)) {
311
+ violations.push(
312
+ createViolation(
313
+ `${state.path}.type`,
314
+ "cca-type-array",
315
+ "Cloud Code Assist schema forbids array-valued type",
316
+ "type",
317
+ node.type,
318
+ ),
319
+ );
320
+ }
321
+
322
+ if (node.type === "null") {
323
+ violations.push(
324
+ createViolation(
325
+ `${state.path}.type`,
326
+ "cca-null-type",
327
+ 'Cloud Code Assist schema forbids type: "null"',
328
+ "type",
329
+ node.type,
330
+ ),
331
+ );
332
+ }
333
+
334
+ if (Object.hasOwn(node, "nullable")) {
335
+ violations.push(
336
+ createViolation(
337
+ `${state.path}.nullable`,
338
+ "cca-nullable-key",
339
+ "Cloud Code Assist schema forbids nullable keyword",
340
+ "nullable",
341
+ node.nullable,
342
+ ),
343
+ );
344
+ }
345
+
346
+ for (const key of COMBINATOR_KEYS) {
347
+ if (Array.isArray(node[key])) {
348
+ violations.push(
349
+ createViolation(
350
+ `${state.path}.${key}`,
351
+ "cca-combiner",
352
+ `Cloud Code Assist schema forbids ${key}`,
353
+ key,
354
+ node[key],
355
+ ),
356
+ );
357
+ }
358
+ }
359
+
360
+ return violations;
361
+ }
362
+
363
+ function validateCloudCodeAssistSchema(schema: unknown): SchemaCompatibilityViolation[] {
364
+ if (isValidJsonSchema(schema)) {
365
+ return [];
366
+ }
367
+ return [
368
+ createViolation(
369
+ "root",
370
+ "cca-meta-schema-validation",
371
+ "Cloud Code Assist schema is not a structurally valid JSON Schema",
372
+ ),
373
+ ];
374
+ }
375
+
376
+ export function validateSchemaCompatibility(
377
+ schema: unknown,
378
+ provider: SchemaCompatibilityProvider,
379
+ ): SchemaCompatibilityResult {
380
+ const violations: SchemaCompatibilityViolation[] = [];
381
+
382
+ switch (provider) {
383
+ case "openai-strict": {
384
+ walkSchema(schema, { path: "root" }, (node, state) => {
385
+ violations.push(...validateStrictNode(node, state));
386
+ });
387
+ break;
388
+ }
389
+ case "google": {
390
+ walkSchema(schema, { path: "root" }, (node, state) => {
391
+ violations.push(...validateGoogleNode(node, state));
392
+ });
393
+ break;
394
+ }
395
+ case "cloud-code-assist-claude": {
396
+ walkSchema(schema, { path: "root" }, (node, state) => {
397
+ violations.push(...validateCloudCodeAssistNode(node, state));
398
+ });
399
+ violations.push(...validateCloudCodeAssistSchema(schema));
400
+ break;
401
+ }
402
+ }
403
+
404
+ return {
405
+ provider,
406
+ compatible: violations.length === 0,
407
+ violations,
408
+ };
409
+ }
410
+
411
+ export function validateStrictSchemaEnforcement(
412
+ originalSchema: Record<string, unknown>,
413
+ result: StrictSchemaEnforcementResult,
414
+ ): SchemaCompatibilityResult {
415
+ if (result.strict) {
416
+ return validateSchemaCompatibility(result.schema, "openai-strict");
417
+ }
418
+
419
+ const violations: SchemaCompatibilityViolation[] = [];
420
+ if (result.schema !== originalSchema) {
421
+ violations.push(
422
+ createViolation(
423
+ "root",
424
+ "strict-fail-open-original-schema",
425
+ "Strict fail-open must return the original schema object when strict=false",
426
+ ),
427
+ );
428
+ }
429
+
430
+ return {
431
+ provider: "openai-strict",
432
+ compatible: violations.length === 0,
433
+ violations,
434
+ };
435
+ }
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Inline `$ref` / `$defs` in a JSON Schema so every consumer sees
3
+ * the full definition without needing a resolver.
4
+ *
5
+ * Handles:
6
+ * - Local `$ref` pointers (`#/$defs/Foo`, `#/definitions/Foo`)
7
+ * - Nested `$defs` / `definitions` blocks
8
+ * - Circular references (breaks the cycle by emitting `{}`)
9
+ *
10
+ * After dereferencing, `$defs` and `definitions` are stripped from the root.
11
+ */
12
+ import { isJsonObject, type JsonObject } from "./types";
13
+
14
+ /**
15
+ * Resolve a JSON-pointer-style `$ref` against the root schema's `$defs`
16
+ * or `definitions` block. Returns `undefined` for external or unresolvable refs.
17
+ */
18
+ function resolveLocalRef(ref: string, root: JsonObject): JsonObject | undefined {
19
+ // Only handle local refs: #/$defs/Name or #/definitions/Name
20
+ const match = /^#\/(\$defs|definitions)\/(.+)$/.exec(ref);
21
+ if (!match) return undefined;
22
+
23
+ const [, defsKey, name] = match;
24
+ const defs = root[defsKey!];
25
+ if (!isJsonObject(defs)) return undefined;
26
+
27
+ const resolved = defs[name!];
28
+ return isJsonObject(resolved) ? resolved : undefined;
29
+ }
30
+
31
+ /**
32
+ * Recursively dereference a JSON Schema node, inlining all local `$ref` pointers.
33
+ */
34
+ function dereferenceNode(node: unknown, root: JsonObject, visiting: Set<string>): unknown {
35
+ if (!isJsonObject(node)) return node;
36
+ if (Array.isArray(node)) return node.map(item => dereferenceNode(item, root, visiting));
37
+
38
+ const ref = node.$ref;
39
+ if (typeof ref === "string") {
40
+ // Break circular references
41
+ if (visiting.has(ref)) return {};
42
+ const resolved = resolveLocalRef(ref, root);
43
+ if (!resolved) return node; // External ref — leave as-is
44
+ visiting.add(ref);
45
+ const inlined = dereferenceNode(resolved, root, visiting);
46
+ visiting.delete(ref);
47
+
48
+ // Merge sibling keywords (e.g. description, default) from the
49
+ // referencing node. In draft 2020-12 these are valid alongside $ref.
50
+ let hasSiblings = false;
51
+ for (const k in node) {
52
+ if (k !== "$ref") {
53
+ hasSiblings = true;
54
+ break;
55
+ }
56
+ }
57
+ if (!hasSiblings || !isJsonObject(inlined)) return inlined;
58
+ const merged: JsonObject = { ...inlined, ...node };
59
+ delete merged.$ref;
60
+ return merged;
61
+ }
62
+
63
+ const result: JsonObject = {};
64
+ for (const key in node) {
65
+ const value = node[key];
66
+ // Skip $defs/definitions — they get inlined into consumers
67
+ if (key === "$defs" || key === "definitions") continue;
68
+
69
+ if (Array.isArray(value)) {
70
+ result[key] = value.map(item => dereferenceNode(item, root, visiting));
71
+ } else if (isJsonObject(value)) {
72
+ result[key] = dereferenceNode(value, root, visiting);
73
+ } else {
74
+ result[key] = value;
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+
80
+ /**
81
+ * Dereference all local `$ref` pointers in a JSON Schema, inlining definitions
82
+ * from `$defs` / `definitions`. The `$defs` block is stripped from the output.
83
+ *
84
+ * Non-local refs (e.g. `http://...`) are left untouched.
85
+ * Circular references are broken with `{}`.
86
+ *
87
+ * @returns A new schema object with all local refs inlined, or the input unchanged
88
+ * if it's not an object or has no `$defs`/`definitions`.
89
+ */
90
+ export function dereferenceJsonSchema(schema: unknown): unknown {
91
+ if (!isJsonObject(schema)) return schema;
92
+
93
+ // Fast path: nothing to dereference
94
+ const hasDefs = schema.$defs !== undefined || schema.definitions !== undefined;
95
+ if (!hasDefs) return schema;
96
+
97
+ return dereferenceNode(schema, schema, new Set());
98
+ }