jeopi-ai 16.2.13

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 (598) hide show
  1. package/CHANGELOG.md +4347 -0
  2. package/README.md +1193 -0
  3. package/dist/types/api-registry.d.ts +30 -0
  4. package/dist/types/auth-broker/client.d.ts +73 -0
  5. package/dist/types/auth-broker/discover.d.ts +35 -0
  6. package/dist/types/auth-broker/index.d.ts +7 -0
  7. package/dist/types/auth-broker/refresher.d.ts +25 -0
  8. package/dist/types/auth-broker/remote-store.d.ts +102 -0
  9. package/dist/types/auth-broker/server.d.ts +43 -0
  10. package/dist/types/auth-broker/snapshot-cache.d.ts +17 -0
  11. package/dist/types/auth-broker/types.d.ts +107 -0
  12. package/dist/types/auth-broker/wire-schemas.d.ts +411 -0
  13. package/dist/types/auth-gateway/http.d.ts +39 -0
  14. package/dist/types/auth-gateway/index.d.ts +3 -0
  15. package/dist/types/auth-gateway/server.d.ts +36 -0
  16. package/dist/types/auth-gateway/types.d.ts +123 -0
  17. package/dist/types/auth-retry.d.ts +124 -0
  18. package/dist/types/auth-storage.d.ts +1026 -0
  19. package/dist/types/dialect/anthropic.d.ts +15 -0
  20. package/dist/types/dialect/catalog.d.ts +3 -0
  21. package/dist/types/dialect/coercion.d.ts +23 -0
  22. package/dist/types/dialect/deepseek.d.ts +14 -0
  23. package/dist/types/dialect/demotion.d.ts +23 -0
  24. package/dist/types/dialect/examples.d.ts +2 -0
  25. package/dist/types/dialect/factory.d.ts +3 -0
  26. package/dist/types/dialect/fenced-thinking.d.ts +53 -0
  27. package/dist/types/dialect/gemini.d.ts +17 -0
  28. package/dist/types/dialect/gemma.d.ts +15 -0
  29. package/dist/types/dialect/glm.d.ts +9 -0
  30. package/dist/types/dialect/harmony.d.ts +8 -0
  31. package/dist/types/dialect/hermes.d.ts +9 -0
  32. package/dist/types/dialect/history.d.ts +3 -0
  33. package/dist/types/dialect/index.d.ts +11 -0
  34. package/dist/types/dialect/inventory.d.ts +12 -0
  35. package/dist/types/dialect/kimi.d.ts +14 -0
  36. package/dist/types/dialect/minimax.d.ts +3 -0
  37. package/dist/types/dialect/owned-stream.d.ts +4 -0
  38. package/dist/types/dialect/qwen3.d.ts +9 -0
  39. package/dist/types/dialect/rendering.d.ts +45 -0
  40. package/dist/types/dialect/thinking.d.ts +6 -0
  41. package/dist/types/dialect/types.d.ts +69 -0
  42. package/dist/types/dialect/xml.d.ts +9 -0
  43. package/dist/types/error/abort.d.ts +14 -0
  44. package/dist/types/error/auth-classify.d.ts +16 -0
  45. package/dist/types/error/auth.d.ts +27 -0
  46. package/dist/types/error/aws.d.ts +23 -0
  47. package/dist/types/error/classes.d.ts +102 -0
  48. package/dist/types/error/finalize.d.ts +39 -0
  49. package/dist/types/error/flags.d.ts +79 -0
  50. package/dist/types/error/format.d.ts +20 -0
  51. package/dist/types/error/gateway.d.ts +20 -0
  52. package/dist/types/error/index.d.ts +13 -0
  53. package/dist/types/error/oauth.d.ts +43 -0
  54. package/dist/types/error/provider.d.ts +42 -0
  55. package/dist/types/error/rate-limit.d.ts +59 -0
  56. package/dist/types/error/retryable.d.ts +27 -0
  57. package/dist/types/error/validation.d.ts +32 -0
  58. package/dist/types/index.d.ts +49 -0
  59. package/dist/types/provider-details.d.ts +24 -0
  60. package/dist/types/providers/__tests__/google-auth.test.d.ts +1 -0
  61. package/dist/types/providers/__tests__/kimi-code-thinking.test.d.ts +1 -0
  62. package/dist/types/providers/__tests__/openai-codex-error.test.d.ts +1 -0
  63. package/dist/types/providers/amazon-bedrock.d.ts +39 -0
  64. package/dist/types/providers/anthropic-client.d.ts +94 -0
  65. package/dist/types/providers/anthropic-messages-server-schema.d.ts +497 -0
  66. package/dist/types/providers/anthropic-messages-server.d.ts +17 -0
  67. package/dist/types/providers/anthropic-wire.d.ts +318 -0
  68. package/dist/types/providers/anthropic.d.ts +248 -0
  69. package/dist/types/providers/aws-credentials.d.ts +53 -0
  70. package/dist/types/providers/aws-eventstream.d.ts +39 -0
  71. package/dist/types/providers/aws-sigv4.d.ts +55 -0
  72. package/dist/types/providers/azure-openai-responses.d.ts +16 -0
  73. package/dist/types/providers/cursor.d.ts +91 -0
  74. package/dist/types/providers/devin.d.ts +12 -0
  75. package/dist/types/providers/error-message.d.ts +27 -0
  76. package/dist/types/providers/github-copilot-headers.d.ts +40 -0
  77. package/dist/types/providers/gitlab-duo-workflow.d.ts +254 -0
  78. package/dist/types/providers/gitlab-duo.d.ts +27 -0
  79. package/dist/types/providers/google-auth.d.ts +32 -0
  80. package/dist/types/providers/google-gemini-cli.d.ts +118 -0
  81. package/dist/types/providers/google-interactions.d.ts +65 -0
  82. package/dist/types/providers/google-shared.d.ts +203 -0
  83. package/dist/types/providers/google-types.d.ts +155 -0
  84. package/dist/types/providers/google-vertex.d.ts +7 -0
  85. package/dist/types/providers/google.d.ts +4 -0
  86. package/dist/types/providers/grammar.d.ts +1 -0
  87. package/dist/types/providers/kimi.d.ts +27 -0
  88. package/dist/types/providers/mock.d.ts +178 -0
  89. package/dist/types/providers/ollama.d.ts +7 -0
  90. package/dist/types/providers/openai-anthropic-shim.d.ts +31 -0
  91. package/dist/types/providers/openai-chat-server-schema.d.ts +695 -0
  92. package/dist/types/providers/openai-chat-server.d.ts +16 -0
  93. package/dist/types/providers/openai-chat-wire.d.ts +644 -0
  94. package/dist/types/providers/openai-codex/request-transformer.d.ts +54 -0
  95. package/dist/types/providers/openai-codex/response-handler.d.ts +26 -0
  96. package/dist/types/providers/openai-codex-responses.d.ts +108 -0
  97. package/dist/types/providers/openai-completions.d.ts +45 -0
  98. package/dist/types/providers/openai-reasoning-fallback.d.ts +25 -0
  99. package/dist/types/providers/openai-responses-server-schema.d.ts +349 -0
  100. package/dist/types/providers/openai-responses-server.d.ts +17 -0
  101. package/dist/types/providers/openai-responses-wire.d.ts +6065 -0
  102. package/dist/types/providers/openai-responses.d.ts +126 -0
  103. package/dist/types/providers/openai-shared.d.ts +506 -0
  104. package/dist/types/providers/pi-native-client.d.ts +13 -0
  105. package/dist/types/providers/pi-native-server.d.ts +69 -0
  106. package/dist/types/providers/register-builtins.d.ts +32 -0
  107. package/dist/types/providers/synthetic.d.ts +26 -0
  108. package/dist/types/providers/transform-messages.d.ts +11 -0
  109. package/dist/types/providers/vision-guard.d.ts +20 -0
  110. package/dist/types/registry/aimlapi.d.ts +4 -0
  111. package/dist/types/registry/alibaba-coding-plan.d.ts +8 -0
  112. package/dist/types/registry/amazon-bedrock.d.ts +5 -0
  113. package/dist/types/registry/anthropic.d.ts +10 -0
  114. package/dist/types/registry/api-key-login.d.ts +42 -0
  115. package/dist/types/registry/api-key-validation.d.ts +43 -0
  116. package/dist/types/registry/azure.d.ts +4 -0
  117. package/dist/types/registry/cerebras.d.ts +7 -0
  118. package/dist/types/registry/cloudflare-ai-gateway.d.ts +13 -0
  119. package/dist/types/registry/coreweave.d.ts +7 -0
  120. package/dist/types/registry/cursor.d.ts +7 -0
  121. package/dist/types/registry/deepseek.d.ts +8 -0
  122. package/dist/types/registry/derived.d.ts +5 -0
  123. package/dist/types/registry/devin.d.ts +8 -0
  124. package/dist/types/registry/firepass.d.ts +16 -0
  125. package/dist/types/registry/fireworks.d.ts +7 -0
  126. package/dist/types/registry/github-copilot.d.ts +7 -0
  127. package/dist/types/registry/gitlab-duo-workflow.d.ts +10 -0
  128. package/dist/types/registry/gitlab-duo.d.ts +9 -0
  129. package/dist/types/registry/google-antigravity.d.ts +9 -0
  130. package/dist/types/registry/google-gemini-cli.d.ts +9 -0
  131. package/dist/types/registry/google-vertex.d.ts +5 -0
  132. package/dist/types/registry/google.d.ts +4 -0
  133. package/dist/types/registry/groq.d.ts +4 -0
  134. package/dist/types/registry/huggingface.d.ts +7 -0
  135. package/dist/types/registry/index.d.ts +4 -0
  136. package/dist/types/registry/kagi.d.ts +14 -0
  137. package/dist/types/registry/kilo.d.ts +7 -0
  138. package/dist/types/registry/kimi-code.d.ts +7 -0
  139. package/dist/types/registry/litellm.d.ts +13 -0
  140. package/dist/types/registry/llama-cpp.d.ts +8 -0
  141. package/dist/types/registry/lm-studio.d.ts +8 -0
  142. package/dist/types/registry/minimax-code-cn.d.ts +6 -0
  143. package/dist/types/registry/minimax-code.d.ts +6 -0
  144. package/dist/types/registry/minimax.d.ts +4 -0
  145. package/dist/types/registry/mistral.d.ts +4 -0
  146. package/dist/types/registry/moonshot.d.ts +7 -0
  147. package/dist/types/registry/nanogpt.d.ts +7 -0
  148. package/dist/types/registry/nvidia.d.ts +7 -0
  149. package/dist/types/registry/oauth/__tests__/xai-oauth.test.d.ts +1 -0
  150. package/dist/types/registry/oauth/anthropic.d.ts +23 -0
  151. package/dist/types/registry/oauth/callback-server.d.ts +72 -0
  152. package/dist/types/registry/oauth/cursor.d.ts +15 -0
  153. package/dist/types/registry/oauth/devin.d.ts +5 -0
  154. package/dist/types/registry/oauth/github-copilot.d.ts +30 -0
  155. package/dist/types/registry/oauth/gitlab-duo-workflow.d.ts +6 -0
  156. package/dist/types/registry/oauth/gitlab-duo.d.ts +3 -0
  157. package/dist/types/registry/oauth/google-antigravity.d.ts +11 -0
  158. package/dist/types/registry/oauth/google-gemini-cli.d.ts +10 -0
  159. package/dist/types/registry/oauth/google-oauth-shared.d.ts +22 -0
  160. package/dist/types/registry/oauth/index.d.ts +64 -0
  161. package/dist/types/registry/oauth/kimi.d.ts +21 -0
  162. package/dist/types/registry/oauth/minimax-code.d.ts +27 -0
  163. package/dist/types/registry/oauth/openai-codex.d.ts +33 -0
  164. package/dist/types/registry/oauth/opencode.d.ts +18 -0
  165. package/dist/types/registry/oauth/perplexity.d.ts +9 -0
  166. package/dist/types/registry/oauth/pkce.d.ts +8 -0
  167. package/dist/types/registry/oauth/types.d.ts +56 -0
  168. package/dist/types/registry/oauth/wafer.d.ts +1 -0
  169. package/dist/types/registry/oauth/xai-oauth.d.ts +52 -0
  170. package/dist/types/registry/oauth/xiaomi.d.ts +25 -0
  171. package/dist/types/registry/ollama-cloud.d.ts +7 -0
  172. package/dist/types/registry/ollama.d.ts +12 -0
  173. package/dist/types/registry/openai-codex-device.d.ts +8 -0
  174. package/dist/types/registry/openai-codex.d.ts +9 -0
  175. package/dist/types/registry/openai.d.ts +4 -0
  176. package/dist/types/registry/opencode-go.d.ts +6 -0
  177. package/dist/types/registry/opencode-zen.d.ts +6 -0
  178. package/dist/types/registry/openrouter.d.ts +13 -0
  179. package/dist/types/registry/parallel.d.ts +14 -0
  180. package/dist/types/registry/perplexity.d.ts +7 -0
  181. package/dist/types/registry/qianfan.d.ts +7 -0
  182. package/dist/types/registry/qwen-portal.d.ts +7 -0
  183. package/dist/types/registry/registry.d.ts +303 -0
  184. package/dist/types/registry/sakana.d.ts +7 -0
  185. package/dist/types/registry/synthetic.d.ts +6 -0
  186. package/dist/types/registry/tavily.d.ts +14 -0
  187. package/dist/types/registry/together.d.ts +6 -0
  188. package/dist/types/registry/types.d.ts +51 -0
  189. package/dist/types/registry/umans.d.ts +7 -0
  190. package/dist/types/registry/venice.d.ts +13 -0
  191. package/dist/types/registry/vercel-ai-gateway.d.ts +7 -0
  192. package/dist/types/registry/vllm.d.ts +7 -0
  193. package/dist/types/registry/wafer-serverless.d.ts +6 -0
  194. package/dist/types/registry/xai-oauth.d.ts +7 -0
  195. package/dist/types/registry/xai.d.ts +4 -0
  196. package/dist/types/registry/xiaomi-token-plan-ams.d.ts +6 -0
  197. package/dist/types/registry/xiaomi-token-plan-cn.d.ts +6 -0
  198. package/dist/types/registry/xiaomi-token-plan-sgp.d.ts +6 -0
  199. package/dist/types/registry/xiaomi.d.ts +6 -0
  200. package/dist/types/registry/zai.d.ts +7 -0
  201. package/dist/types/registry/zenmux.d.ts +7 -0
  202. package/dist/types/registry/zhipu-coding-plan.d.ts +7 -0
  203. package/dist/types/stream.d.ts +44 -0
  204. package/dist/types/types.d.ts +715 -0
  205. package/dist/types/usage/claude.d.ts +4 -0
  206. package/dist/types/usage/gemini.d.ts +2 -0
  207. package/dist/types/usage/github-copilot.d.ts +7 -0
  208. package/dist/types/usage/google-antigravity.d.ts +15 -0
  209. package/dist/types/usage/kimi.d.ts +2 -0
  210. package/dist/types/usage/minimax-code.d.ts +2 -0
  211. package/dist/types/usage/ollama.d.ts +5 -0
  212. package/dist/types/usage/openai-codex-base-url.d.ts +18 -0
  213. package/dist/types/usage/openai-codex-reset.d.ts +79 -0
  214. package/dist/types/usage/openai-codex.d.ts +3 -0
  215. package/dist/types/usage/opencode-go.d.ts +2 -0
  216. package/dist/types/usage/shared.d.ts +1 -0
  217. package/dist/types/usage/zai.d.ts +2 -0
  218. package/dist/types/usage.d.ts +346 -0
  219. package/dist/types/utils/abort.d.ts +25 -0
  220. package/dist/types/utils/anthropic-auth.d.ts +35 -0
  221. package/dist/types/utils/block-symbols.d.ts +20 -0
  222. package/dist/types/utils/deterministic-id.d.ts +16 -0
  223. package/dist/types/utils/empty-completion-retry.d.ts +21 -0
  224. package/dist/types/utils/event-stream.d.ts +30 -0
  225. package/dist/types/utils/foundry.d.ts +1 -0
  226. package/dist/types/utils/google-validation.d.ts +2 -0
  227. package/dist/types/utils/harmony-leak.d.ts +118 -0
  228. package/dist/types/utils/http-inspector.d.ts +30 -0
  229. package/dist/types/utils/idle-iterator.d.ts +137 -0
  230. package/dist/types/utils/leaked-thinking-stream.d.ts +29 -0
  231. package/dist/types/utils/openai-http.d.ts +54 -0
  232. package/dist/types/utils/openrouter-headers.d.ts +1 -0
  233. package/dist/types/utils/parse-bind.d.ts +23 -0
  234. package/dist/types/utils/provider-response.d.ts +3 -0
  235. package/dist/types/utils/proxy.d.ts +29 -0
  236. package/dist/types/utils/request-debug.d.ts +29 -0
  237. package/dist/types/utils/retry-after.d.ts +4 -0
  238. package/dist/types/utils/retry.d.ts +14 -0
  239. package/dist/types/utils/schema/adapt.d.ts +24 -0
  240. package/dist/types/utils/schema/compatibility.d.ts +30 -0
  241. package/dist/types/utils/schema/dereference.d.ts +11 -0
  242. package/dist/types/utils/schema/draft.d.ts +10 -0
  243. package/dist/types/utils/schema/equality.d.ts +4 -0
  244. package/dist/types/utils/schema/fields.d.ts +54 -0
  245. package/dist/types/utils/schema/index.d.ts +15 -0
  246. package/dist/types/utils/schema/json-schema-validator.d.ts +20 -0
  247. package/dist/types/utils/schema/meta-validator.d.ts +2 -0
  248. package/dist/types/utils/schema/normalize.d.ts +124 -0
  249. package/dist/types/utils/schema/spill.d.ts +8 -0
  250. package/dist/types/utils/schema/stamps.d.ts +17 -0
  251. package/dist/types/utils/schema/strict-tool-validation.d.ts +16 -0
  252. package/dist/types/utils/schema/types.d.ts +4 -0
  253. package/dist/types/utils/schema/typescript.d.ts +18 -0
  254. package/dist/types/utils/schema/wire.d.ts +92 -0
  255. package/dist/types/utils/schema/zod-decontaminate.d.ts +31 -0
  256. package/dist/types/utils/sdk-stream-timeout.d.ts +33 -0
  257. package/dist/types/utils/sse-debug.d.ts +5 -0
  258. package/dist/types/utils/stream-markup-healing.d.ts +87 -0
  259. package/dist/types/utils/thinking-loop.d.ts +102 -0
  260. package/dist/types/utils/tool-call-loop-guard.d.ts +26 -0
  261. package/dist/types/utils/tool-choice.d.ts +50 -0
  262. package/dist/types/utils/validation.d.ts +42 -0
  263. package/dist/types/utils.d.ts +24 -0
  264. package/package.json +139 -0
  265. package/src/api-registry.ts +109 -0
  266. package/src/auth-broker/client.ts +359 -0
  267. package/src/auth-broker/discover.ts +222 -0
  268. package/src/auth-broker/index.ts +7 -0
  269. package/src/auth-broker/refresher.ts +117 -0
  270. package/src/auth-broker/remote-store.ts +657 -0
  271. package/src/auth-broker/server.ts +646 -0
  272. package/src/auth-broker/snapshot-cache.ts +191 -0
  273. package/src/auth-broker/types.ts +130 -0
  274. package/src/auth-broker/wire-schemas.ts +249 -0
  275. package/src/auth-gateway/http.ts +194 -0
  276. package/src/auth-gateway/index.ts +3 -0
  277. package/src/auth-gateway/server.ts +802 -0
  278. package/src/auth-gateway/types.ts +151 -0
  279. package/src/auth-retry.ts +250 -0
  280. package/src/auth-storage.ts +5576 -0
  281. package/src/dialect/anthropic.md +31 -0
  282. package/src/dialect/anthropic.ts +608 -0
  283. package/src/dialect/catalog.ts +29 -0
  284. package/src/dialect/coercion.ts +136 -0
  285. package/src/dialect/deepseek.md +24 -0
  286. package/src/dialect/deepseek.ts +609 -0
  287. package/src/dialect/demotion.ts +36 -0
  288. package/src/dialect/examples.ts +33 -0
  289. package/src/dialect/factory.ts +34 -0
  290. package/src/dialect/fenced-thinking.ts +184 -0
  291. package/src/dialect/gemini.md +44 -0
  292. package/src/dialect/gemini.ts +597 -0
  293. package/src/dialect/gemma.md +33 -0
  294. package/src/dialect/gemma.ts +387 -0
  295. package/src/dialect/glm.md +32 -0
  296. package/src/dialect/glm.ts +456 -0
  297. package/src/dialect/harmony.md +31 -0
  298. package/src/dialect/harmony.ts +346 -0
  299. package/src/dialect/hermes.md +25 -0
  300. package/src/dialect/hermes.ts +206 -0
  301. package/src/dialect/history.ts +81 -0
  302. package/src/dialect/index.ts +15 -0
  303. package/src/dialect/inventory.ts +73 -0
  304. package/src/dialect/kimi.md +24 -0
  305. package/src/dialect/kimi.ts +340 -0
  306. package/src/dialect/minimax.md +31 -0
  307. package/src/dialect/minimax.ts +95 -0
  308. package/src/dialect/owned-stream.ts +470 -0
  309. package/src/dialect/prompt-template.md +12 -0
  310. package/src/dialect/qwen3.md +28 -0
  311. package/src/dialect/qwen3.ts +240 -0
  312. package/src/dialect/rendering.ts +249 -0
  313. package/src/dialect/thinking.ts +122 -0
  314. package/src/dialect/types.ts +57 -0
  315. package/src/dialect/xml.md +22 -0
  316. package/src/dialect/xml.ts +90 -0
  317. package/src/error/abort.ts +18 -0
  318. package/src/error/auth-classify.ts +30 -0
  319. package/src/error/auth.ts +48 -0
  320. package/src/error/aws.ts +31 -0
  321. package/src/error/classes.ts +186 -0
  322. package/src/error/finalize.ts +69 -0
  323. package/src/error/flags.ts +506 -0
  324. package/src/error/format.ts +45 -0
  325. package/src/error/gateway.ts +96 -0
  326. package/src/error/index.ts +13 -0
  327. package/src/error/oauth.ts +58 -0
  328. package/src/error/provider.ts +62 -0
  329. package/src/error/rate-limit.ts +161 -0
  330. package/src/error/retryable.ts +70 -0
  331. package/src/error/validation.ts +44 -0
  332. package/src/index.ts +49 -0
  333. package/src/provider-details.ts +90 -0
  334. package/src/providers/__tests__/google-auth.test.ts +144 -0
  335. package/src/providers/__tests__/kimi-code-thinking.test.ts +112 -0
  336. package/src/providers/__tests__/openai-codex-error.test.ts +84 -0
  337. package/src/providers/amazon-bedrock.ts +1042 -0
  338. package/src/providers/anthropic-client.ts +295 -0
  339. package/src/providers/anthropic-messages-server-schema.ts +252 -0
  340. package/src/providers/anthropic-messages-server.ts +756 -0
  341. package/src/providers/anthropic-wire.ts +318 -0
  342. package/src/providers/anthropic.ts +4078 -0
  343. package/src/providers/aws-credentials.ts +586 -0
  344. package/src/providers/aws-eventstream.ts +181 -0
  345. package/src/providers/aws-sigv4.ts +218 -0
  346. package/src/providers/azure-openai-responses.ts +382 -0
  347. package/src/providers/cursor/proto/agent.proto +3526 -0
  348. package/src/providers/cursor/proto/buf.gen.yaml +6 -0
  349. package/src/providers/cursor/proto/buf.yaml +17 -0
  350. package/src/providers/cursor.ts +2695 -0
  351. package/src/providers/devin/proto/buf/validate/validate.proto +468 -0
  352. package/src/providers/devin/proto/buf.gen.yaml +33 -0
  353. package/src/providers/devin/proto/buf.yaml +17 -0
  354. package/src/providers/devin/proto/cel/expr/checked.proto +103 -0
  355. package/src/providers/devin/proto/cel/expr/eval.proto +38 -0
  356. package/src/providers/devin/proto/cel/expr/explain.proto +15 -0
  357. package/src/providers/devin/proto/cel/expr/syntax.proto +113 -0
  358. package/src/providers/devin/proto/cel/expr/value.proto +41 -0
  359. package/src/providers/devin/proto/connectext/grpc/status/v1/status.proto +11 -0
  360. package/src/providers/devin/proto/errorspb/errors.proto +56 -0
  361. package/src/providers/devin/proto/errorspb/hintdetail.proto +7 -0
  362. package/src/providers/devin/proto/errorspb/markers.proto +10 -0
  363. package/src/providers/devin/proto/errorspb/tags.proto +12 -0
  364. package/src/providers/devin/proto/errorspb/testing.proto +6 -0
  365. package/src/providers/devin/proto/exa/analytics_pb/analytics.proto +188 -0
  366. package/src/providers/devin/proto/exa/api_server_pb/api_server.proto +2461 -0
  367. package/src/providers/devin/proto/exa/auth_pb/auth.proto +19 -0
  368. package/src/providers/devin/proto/exa/auto_cascade_common_pb/auto_cascade_common.proto +79 -0
  369. package/src/providers/devin/proto/exa/browser_preview_pb/browser_preview.proto +32 -0
  370. package/src/providers/devin/proto/exa/bug_checker_pb/bug_checker.proto +22 -0
  371. package/src/providers/devin/proto/exa/cascade_plugins_pb/cascade_plugins.proto +262 -0
  372. package/src/providers/devin/proto/exa/chat_client_server_pb/chat_client_server.proto +57 -0
  373. package/src/providers/devin/proto/exa/chat_pb/chat.proto +449 -0
  374. package/src/providers/devin/proto/exa/code_edit/code_edit_pb/code_edit.proto +186 -0
  375. package/src/providers/devin/proto/exa/codeium_common_pb/codeium_common.proto +4157 -0
  376. package/src/providers/devin/proto/exa/context_module_pb/context_module.proto +175 -0
  377. package/src/providers/devin/proto/exa/cortex_pb/cortex.proto +3268 -0
  378. package/src/providers/devin/proto/exa/dev_pb/dev.proto +26 -0
  379. package/src/providers/devin/proto/exa/diff_action_pb/diff_action.proto +75 -0
  380. package/src/providers/devin/proto/exa/eval/pr_eval/datasets_pb/datasets.proto +103 -0
  381. package/src/providers/devin/proto/exa/eval_pb/eval.proto +1315 -0
  382. package/src/providers/devin/proto/exa/extension_server_pb/extension_server.proto +556 -0
  383. package/src/providers/devin/proto/exa/file_system_provider_pb/file_system_provider.proto +75 -0
  384. package/src/providers/devin/proto/exa/index_pb/index.proto +461 -0
  385. package/src/providers/devin/proto/exa/knowledge_base_pb/knowledge_base.proto +144 -0
  386. package/src/providers/devin/proto/exa/language_server_pb/language_server.proto +2385 -0
  387. package/src/providers/devin/proto/exa/model_management_pb/model_management.proto +186 -0
  388. package/src/providers/devin/proto/exa/opensearch_clients_pb/opensearch_clients.proto +503 -0
  389. package/src/providers/devin/proto/exa/product_analytics_pb/product_analytics.proto +37 -0
  390. package/src/providers/devin/proto/exa/prompt_pb/prompt.proto +92 -0
  391. package/src/providers/devin/proto/exa/reactive_component_pb/reactive_component.proto +96 -0
  392. package/src/providers/devin/proto/exa/seat_management_pb/seat_management.proto +2680 -0
  393. package/src/providers/devin/proto/exa/tokenizer_pb/tokenizer.proto +37 -0
  394. package/src/providers/devin/proto/exa/trainer_pb/config.proto +647 -0
  395. package/src/providers/devin/proto/exa/tree_sitter/language_data_pb/language_data.proto +14 -0
  396. package/src/providers/devin/proto/exa/trust_pb/trust.proto +157 -0
  397. package/src/providers/devin/proto/exa/user_analytics_pb/user_analytics.proto +519 -0
  398. package/src/providers/devin/proto/google.golang.org/appengine/internal/base/api_base.proto +28 -0
  399. package/src/providers/devin/proto/google.golang.org/appengine/internal/datastore/datastore_v3.proto +484 -0
  400. package/src/providers/devin/proto/google.golang.org/appengine/internal/log/log_service.proto +136 -0
  401. package/src/providers/devin/proto/google.golang.org/appengine/internal/remote_api/remote_api.proto +42 -0
  402. package/src/providers/devin/proto/google.golang.org/appengine/internal/urlfetch/urlfetch_service.proto +61 -0
  403. package/src/providers/devin/proto/grpc/binlog/v1/binarylog.proto +84 -0
  404. package/src/providers/devin/proto/io/prometheus/client/metrics.proto +98 -0
  405. package/src/providers/devin.ts +577 -0
  406. package/src/providers/error-message.ts +21 -0
  407. package/src/providers/github-copilot-headers.ts +141 -0
  408. package/src/providers/gitlab-duo-workflow-chatml-note.md +1 -0
  409. package/src/providers/gitlab-duo-workflow.ts +3058 -0
  410. package/src/providers/gitlab-duo.ts +395 -0
  411. package/src/providers/google-auth.ts +350 -0
  412. package/src/providers/google-gemini-cli.ts +1362 -0
  413. package/src/providers/google-interactions.ts +753 -0
  414. package/src/providers/google-shared.ts +1103 -0
  415. package/src/providers/google-types.ts +180 -0
  416. package/src/providers/google-vertex.ts +183 -0
  417. package/src/providers/google.ts +87 -0
  418. package/src/providers/grammar.ts +70 -0
  419. package/src/providers/kimi.ts +52 -0
  420. package/src/providers/mock.ts +507 -0
  421. package/src/providers/ollama.ts +773 -0
  422. package/src/providers/openai-anthropic-shim.ts +152 -0
  423. package/src/providers/openai-chat-server-schema.ts +242 -0
  424. package/src/providers/openai-chat-server.ts +715 -0
  425. package/src/providers/openai-chat-wire.ts +847 -0
  426. package/src/providers/openai-codex/request-transformer.ts +295 -0
  427. package/src/providers/openai-codex/response-handler.ts +102 -0
  428. package/src/providers/openai-codex-responses.ts +3468 -0
  429. package/src/providers/openai-completions.ts +2173 -0
  430. package/src/providers/openai-reasoning-fallback.ts +269 -0
  431. package/src/providers/openai-responses-reasoning-suppression.md +1 -0
  432. package/src/providers/openai-responses-server-schema.ts +282 -0
  433. package/src/providers/openai-responses-server.ts +1280 -0
  434. package/src/providers/openai-responses-wire.ts +6391 -0
  435. package/src/providers/openai-responses.ts +1022 -0
  436. package/src/providers/openai-shared.ts +2648 -0
  437. package/src/providers/pi-native-client.ts +266 -0
  438. package/src/providers/pi-native-server.ts +242 -0
  439. package/src/providers/register-builtins.ts +475 -0
  440. package/src/providers/synthetic.ts +50 -0
  441. package/src/providers/transform-messages.ts +787 -0
  442. package/src/providers/vision-guard.ts +54 -0
  443. package/src/registry/aimlapi.ts +6 -0
  444. package/src/registry/alibaba-coding-plan.ts +95 -0
  445. package/src/registry/amazon-bedrock.ts +22 -0
  446. package/src/registry/anthropic.ts +26 -0
  447. package/src/registry/api-key-login.ts +112 -0
  448. package/src/registry/api-key-validation.ts +161 -0
  449. package/src/registry/azure.ts +6 -0
  450. package/src/registry/cerebras.ts +23 -0
  451. package/src/registry/cloudflare-ai-gateway.ts +45 -0
  452. package/src/registry/coreweave.ts +40 -0
  453. package/src/registry/cursor.ts +20 -0
  454. package/src/registry/deepseek.ts +46 -0
  455. package/src/registry/derived.ts +9 -0
  456. package/src/registry/devin.ts +15 -0
  457. package/src/registry/firepass.ts +32 -0
  458. package/src/registry/fireworks.ts +28 -0
  459. package/src/registry/github-copilot.ts +22 -0
  460. package/src/registry/gitlab-duo-workflow.ts +20 -0
  461. package/src/registry/gitlab-duo.ts +19 -0
  462. package/src/registry/google-antigravity.ts +22 -0
  463. package/src/registry/google-gemini-cli.ts +22 -0
  464. package/src/registry/google-vertex.ts +38 -0
  465. package/src/registry/google.ts +6 -0
  466. package/src/registry/groq.ts +6 -0
  467. package/src/registry/huggingface.ts +29 -0
  468. package/src/registry/index.ts +4 -0
  469. package/src/registry/kagi.ts +46 -0
  470. package/src/registry/kilo.ts +114 -0
  471. package/src/registry/kimi-code.ts +17 -0
  472. package/src/registry/litellm.ts +45 -0
  473. package/src/registry/llama-cpp.ts +35 -0
  474. package/src/registry/lm-studio.ts +31 -0
  475. package/src/registry/minimax-code-cn.ts +12 -0
  476. package/src/registry/minimax-code.ts +12 -0
  477. package/src/registry/minimax.ts +6 -0
  478. package/src/registry/mistral.ts +6 -0
  479. package/src/registry/moonshot.ts +22 -0
  480. package/src/registry/nanogpt.ts +22 -0
  481. package/src/registry/nvidia.ts +61 -0
  482. package/src/registry/oauth/__tests__/xai-oauth.test.ts +104 -0
  483. package/src/registry/oauth/anthropic.ts +311 -0
  484. package/src/registry/oauth/callback-server.ts +315 -0
  485. package/src/registry/oauth/cursor.ts +171 -0
  486. package/src/registry/oauth/devin.ts +124 -0
  487. package/src/registry/oauth/github-copilot.ts +369 -0
  488. package/src/registry/oauth/gitlab-duo-workflow.ts +146 -0
  489. package/src/registry/oauth/gitlab-duo.ts +222 -0
  490. package/src/registry/oauth/google-antigravity.ts +209 -0
  491. package/src/registry/oauth/google-gemini-cli.ts +273 -0
  492. package/src/registry/oauth/google-oauth-shared.ts +125 -0
  493. package/src/registry/oauth/index.ts +269 -0
  494. package/src/registry/oauth/kimi.ts +289 -0
  495. package/src/registry/oauth/minimax-code.ts +53 -0
  496. package/src/registry/oauth/oauth.html +311 -0
  497. package/src/registry/oauth/openai-codex.ts +364 -0
  498. package/src/registry/oauth/opencode.ts +50 -0
  499. package/src/registry/oauth/perplexity.ts +228 -0
  500. package/src/registry/oauth/pkce.ts +18 -0
  501. package/src/registry/oauth/types.ts +65 -0
  502. package/src/registry/oauth/wafer.ts +24 -0
  503. package/src/registry/oauth/xai-oauth.ts +394 -0
  504. package/src/registry/oauth/xiaomi.ts +211 -0
  505. package/src/registry/ollama-cloud.ts +36 -0
  506. package/src/registry/ollama.ts +43 -0
  507. package/src/registry/openai-codex-device.ts +18 -0
  508. package/src/registry/openai-codex.ts +19 -0
  509. package/src/registry/openai.ts +6 -0
  510. package/src/registry/opencode-go.ts +12 -0
  511. package/src/registry/opencode-zen.ts +12 -0
  512. package/src/registry/openrouter.ts +28 -0
  513. package/src/registry/parallel.ts +45 -0
  514. package/src/registry/perplexity.ts +13 -0
  515. package/src/registry/qianfan.ts +27 -0
  516. package/src/registry/qwen-portal.ts +50 -0
  517. package/src/registry/registry.ts +161 -0
  518. package/src/registry/sakana.ts +22 -0
  519. package/src/registry/synthetic.ts +21 -0
  520. package/src/registry/tavily.ts +45 -0
  521. package/src/registry/together.ts +22 -0
  522. package/src/registry/types.ts +56 -0
  523. package/src/registry/umans.ts +23 -0
  524. package/src/registry/venice.ts +33 -0
  525. package/src/registry/vercel-ai-gateway.ts +38 -0
  526. package/src/registry/vllm.ts +34 -0
  527. package/src/registry/wafer-serverless.ts +12 -0
  528. package/src/registry/xai-oauth.ts +17 -0
  529. package/src/registry/xai.ts +6 -0
  530. package/src/registry/xiaomi-token-plan-ams.ts +12 -0
  531. package/src/registry/xiaomi-token-plan-cn.ts +12 -0
  532. package/src/registry/xiaomi-token-plan-sgp.ts +12 -0
  533. package/src/registry/xiaomi.ts +12 -0
  534. package/src/registry/zai.ts +27 -0
  535. package/src/registry/zenmux.ts +22 -0
  536. package/src/registry/zhipu-coding-plan.ts +27 -0
  537. package/src/stream.ts +1778 -0
  538. package/src/types.ts +856 -0
  539. package/src/usage/claude.ts +485 -0
  540. package/src/usage/gemini.ts +258 -0
  541. package/src/usage/github-copilot.ts +424 -0
  542. package/src/usage/google-antigravity.ts +497 -0
  543. package/src/usage/kimi.ts +271 -0
  544. package/src/usage/minimax-code.ts +30 -0
  545. package/src/usage/ollama.ts +41 -0
  546. package/src/usage/openai-codex-base-url.ts +35 -0
  547. package/src/usage/openai-codex-reset.ts +174 -0
  548. package/src/usage/openai-codex.ts +535 -0
  549. package/src/usage/opencode-go.ts +89 -0
  550. package/src/usage/shared.ts +10 -0
  551. package/src/usage/zai.ts +321 -0
  552. package/src/usage.ts +333 -0
  553. package/src/utils/abort.ts +67 -0
  554. package/src/utils/anthropic-auth.ts +93 -0
  555. package/src/utils/block-symbols.ts +32 -0
  556. package/src/utils/deterministic-id.ts +20 -0
  557. package/src/utils/empty-completion-retry.ts +159 -0
  558. package/src/utils/event-stream.ts +171 -0
  559. package/src/utils/foundry.ts +8 -0
  560. package/src/utils/google-validation.ts +25 -0
  561. package/src/utils/harmony-leak.ts +456 -0
  562. package/src/utils/http-inspector.ts +168 -0
  563. package/src/utils/idle-iterator.ts +473 -0
  564. package/src/utils/leaked-thinking-stream.ts +294 -0
  565. package/src/utils/openai-http.ts +122 -0
  566. package/src/utils/openrouter-headers.ts +12 -0
  567. package/src/utils/parse-bind.ts +56 -0
  568. package/src/utils/provider-response.ts +30 -0
  569. package/src/utils/proxy.ts +240 -0
  570. package/src/utils/request-debug.ts +351 -0
  571. package/src/utils/retry-after.ts +110 -0
  572. package/src/utils/retry.ts +59 -0
  573. package/src/utils/schema/CONSTRAINTS.md +166 -0
  574. package/src/utils/schema/adapt.ts +36 -0
  575. package/src/utils/schema/compatibility.ts +435 -0
  576. package/src/utils/schema/dereference.ts +98 -0
  577. package/src/utils/schema/draft.ts +341 -0
  578. package/src/utils/schema/equality.ts +97 -0
  579. package/src/utils/schema/fields.ts +207 -0
  580. package/src/utils/schema/index.ts +15 -0
  581. package/src/utils/schema/json-schema-validator.ts +595 -0
  582. package/src/utils/schema/meta-validator.ts +167 -0
  583. package/src/utils/schema/normalize.ts +1901 -0
  584. package/src/utils/schema/spill.ts +43 -0
  585. package/src/utils/schema/stamps.ts +109 -0
  586. package/src/utils/schema/strict-tool-validation.ts +117 -0
  587. package/src/utils/schema/types.ts +10 -0
  588. package/src/utils/schema/typescript.ts +198 -0
  589. package/src/utils/schema/wire.ts +789 -0
  590. package/src/utils/schema/zod-decontaminate.ts +331 -0
  591. package/src/utils/sdk-stream-timeout.ts +43 -0
  592. package/src/utils/sse-debug.ts +18 -0
  593. package/src/utils/stream-markup-healing.ts +247 -0
  594. package/src/utils/thinking-loop.ts +552 -0
  595. package/src/utils/tool-call-loop-guard.ts +107 -0
  596. package/src/utils/tool-choice.ts +99 -0
  597. package/src/utils/validation.ts +1507 -0
  598. package/src/utils.ts +171 -0
@@ -0,0 +1,789 @@
1
+ /**
2
+ * Compute the wire (JSON Schema) representation of a tool's parameters.
3
+ *
4
+ * Tools may author parameters in three shapes:
5
+ * 1. Zod (canonical) — converted to JSON Schema on demand.
6
+ * 2. ArkType — converted to JSON Schema via its native `toJsonSchema`.
7
+ * 3. TypeBox / plain JSON Schema (legacy + extension compat) — upgraded to
8
+ * draft 2020-12 without converting.
9
+ *
10
+ * All three are normalized at the boundary so providers and validators see the same
11
+ * JSON Schema dialect.
12
+ */
13
+
14
+ import type { Type } from "arktype";
15
+ // We import the Zod *value* (z) for runtime APIs. Marker checks rely on the
16
+ // `_zod` symbol that every Zod v4 schema instance carries.
17
+ import { type ZodType, z } from "zod/v4";
18
+ import type { Tool, TSchema } from "../../types";
19
+ import { upgradeJsonSchemaTo202012 } from "./draft";
20
+ import { stamp } from "./stamps";
21
+
22
+ /**
23
+ * True when `value` is a live Zod schema instance.
24
+ *
25
+ * The check is stricter than "has a `_zod` property" because a JSON
26
+ * round-trip preserves the `_zod` key as a plain object and would otherwise
27
+ * fool the predicate — see issue #1101, where MCP servers ship
28
+ * `JSON.stringify(zodSchemaInstance)` as a tool's `inputSchema` and the
29
+ * resulting plain object then explodes `z.toJSONSchema` because the prototype
30
+ * (and every Zod parsing method) is gone.
31
+ *
32
+ * Live Zod instances always carry a `.parse` function on the prototype;
33
+ * impostors do not.
34
+ */
35
+ export function isZodSchema(value: unknown): value is ZodType {
36
+ return (
37
+ typeof value === "object" &&
38
+ value !== null &&
39
+ // Zod v4 instances expose a `_zod` internal property with a `def` object.
40
+ // Tagging on this marker keeps the check stable across Zod minor versions.
41
+ // (`_zod` is part of Zod's documented internal contract used by introspection.)
42
+ // We avoid checking constructor name because Zod ships multiple variants
43
+ // (`ZodObject`, `ZodOptional`, etc.) and a tagged-union style check would
44
+ // have to enumerate them all.
45
+ "_zod" in value &&
46
+ typeof (value as { _zod?: { def?: unknown } })._zod === "object" &&
47
+ // Reject JSON-roundtripped objects that kept the `_zod` key but lost the
48
+ // prototype. Real instances have `.parse` on the prototype chain.
49
+ typeof (value as { parse?: unknown }).parse === "function"
50
+ );
51
+ }
52
+
53
+ /**
54
+ * True when `value` is a live ArkType schema instance.
55
+ *
56
+ * ArkType schemas are callable functions carrying `toJsonSchema`/`assert`
57
+ * methods. Zod v4 instances are non-callable objects (keyed off `_zod`), and
58
+ * raw JSON Schema is a plain object — the three are disjoint. We deliberately
59
+ * avoid the Standard Schema `~standard` marker because Zod v4 implements it too.
60
+ */
61
+ export function isArkSchema(value: unknown): value is Type {
62
+ return (
63
+ typeof value === "function" &&
64
+ typeof (value as { toJsonSchema?: unknown }).toJsonSchema === "function" &&
65
+ typeof (value as { assert?: unknown }).assert === "function"
66
+ );
67
+ }
68
+
69
+ function isArkJsonAst(value: unknown): boolean {
70
+ if (Array.isArray(value)) return value.some(isArkJsonAst);
71
+ if (!isSchemaRecord(value)) return false;
72
+ if (typeof value.domain === "string" || Object.hasOwn(value, "unit")) return true;
73
+ if (value.proto === "Array" && Object.hasOwn(value, "sequence")) return true;
74
+ const required = value.required;
75
+ return (
76
+ Array.isArray(required) &&
77
+ required.some(entry => isSchemaRecord(entry) && typeof entry.key === "string" && "value" in entry)
78
+ );
79
+ }
80
+
81
+ function parseArkObjectKey(key: string): { name: string; description?: string } {
82
+ const match = /^(.*?)\s*\/\*\*\s*([\s\S]*?)\s*\*\/\s*$/.exec(key);
83
+ if (!match) return { name: key };
84
+ return { name: match[1].trim(), description: match[2].trim() };
85
+ }
86
+
87
+ function withArkKeyDescription(schema: unknown, description: string | undefined): unknown {
88
+ if (!description) return schema;
89
+ if (isSchemaRecord(schema)) {
90
+ if (typeof schema.description !== "string") schema.description = description;
91
+ return schema;
92
+ }
93
+ return { anyOf: [schema], description };
94
+ }
95
+
96
+ function arkJsonAstToWire(value: unknown): unknown {
97
+ if (typeof value === "string") {
98
+ switch (value) {
99
+ case "string":
100
+ case "number":
101
+ case "integer":
102
+ case "boolean":
103
+ case "object":
104
+ return { type: value };
105
+ case "unknown":
106
+ return {};
107
+ default:
108
+ return {};
109
+ }
110
+ }
111
+
112
+ if (Array.isArray(value)) {
113
+ if (value.every(item => isSchemaRecord(item) && Object.hasOwn(item, "unit"))) {
114
+ return { enum: value.map(item => (item as { unit: unknown }).unit) };
115
+ }
116
+ return { anyOf: value.map(arkJsonAstToWire) };
117
+ }
118
+
119
+ if (!isSchemaRecord(value)) return {};
120
+
121
+ if (Object.hasOwn(value, "unit")) return { const: value.unit };
122
+
123
+ if (value.proto === "Array" && Object.hasOwn(value, "sequence")) {
124
+ return { type: "array", items: arkJsonAstToWire(value.sequence) };
125
+ }
126
+
127
+ if (value.domain === "object") {
128
+ const properties: Record<string, unknown> = {};
129
+ const required: string[] = [];
130
+ const addEntry = (entry: unknown, isRequired: boolean): void => {
131
+ if (!isSchemaRecord(entry) || typeof entry.key !== "string" || !("value" in entry)) return;
132
+ const key = parseArkObjectKey(entry.key);
133
+ properties[key.name] = withArkKeyDescription(arkJsonAstToWire(entry.value), key.description);
134
+ if (isRequired) required.push(key.name);
135
+ };
136
+ if (Array.isArray(value.required)) {
137
+ for (const entry of value.required) addEntry(entry, true);
138
+ }
139
+ if (Array.isArray(value.optional)) {
140
+ for (const entry of value.optional) addEntry(entry, false);
141
+ }
142
+ const schema: Record<string, unknown> = { type: "object", properties };
143
+ if (required.length > 0) schema.required = required;
144
+ return schema;
145
+ }
146
+
147
+ if (typeof value.domain === "string") return { type: value.domain };
148
+ return {};
149
+ }
150
+
151
+ /** Symbol-stamped caches keyed by schema object identity. */
152
+ const kZodWireSchema = Symbol("pi.schema.zod.wire");
153
+ const kJsonWireSchema = Symbol("pi.schema.json.wire");
154
+ const kArkWireSchema = Symbol("pi.schema.ark.wire");
155
+ const kStrippedSchema = Symbol("pi.schema.descriptions.stripped");
156
+
157
+ /**
158
+ * Post-process Zod-emitted JSON Schema so it matches the wire shape providers
159
+ * already expect from TypeBox-authored tools:
160
+ *
161
+ * - Drop the `$schema` URL (providers parse the body, not the metadata).
162
+ * - Make fields with a `default` non-required (TypeBox/JSON-Schema semantics
163
+ * treat defaulted fields as optional; Zod inverts this and keeps them
164
+ * required at the input boundary, then materializes the default).
165
+ * - Strip the noisy safe-integer bounds Zod injects for `z.number().int()`.
166
+ *
167
+ * The empty-schema normalization (`{}` → `true`, see `normalizeEmptySchemas`)
168
+ * runs separately from `toolWireSchema` so both Zod and TypeBox tools get it.
169
+ */
170
+ function postProcess(schema: Record<string, unknown>): Record<string, unknown> {
171
+ delete schema.$schema;
172
+ walk(schema, true);
173
+ normalizeArkPropertyComments(schema);
174
+ normalizeEmptySchemas(schema);
175
+ return schema;
176
+ }
177
+
178
+ function postProcessJsonSchema(schema: Record<string, unknown>): Record<string, unknown> {
179
+ walk(schema, false);
180
+ normalizeArkPropertyComments(schema);
181
+ normalizeEmptySchemas(schema);
182
+ return schema;
183
+ }
184
+
185
+ const SAFE_INTEGER_MAX = Number.MAX_SAFE_INTEGER;
186
+ const SAFE_INTEGER_MIN = Number.MIN_SAFE_INTEGER;
187
+ const NULLABLE_SCALAR_TYPES = new Set(["string", "number", "integer", "boolean"]);
188
+
189
+ const SCHEMA_DEFINING_SIBLING_KEYS = new Set([
190
+ "$ref",
191
+ "additionalProperties",
192
+ "allOf",
193
+ "anyOf",
194
+ "const",
195
+ "contains",
196
+ "enum",
197
+ "if",
198
+ "items",
199
+ "not",
200
+ "oneOf",
201
+ "patternProperties",
202
+ "prefixItems",
203
+ "properties",
204
+ "propertyNames",
205
+ "then",
206
+ "else",
207
+ "unevaluatedItems",
208
+ "unevaluatedProperties",
209
+ ]);
210
+
211
+ function isSchemaRecord(value: unknown): value is Record<string, unknown> {
212
+ return value !== null && typeof value === "object" && !Array.isArray(value);
213
+ }
214
+
215
+ function hasSchemaDefiningSibling(schema: Record<string, unknown>): boolean {
216
+ for (const key in schema) {
217
+ if (key !== "anyOf" && SCHEMA_DEFINING_SIBLING_KEYS.has(key)) return true;
218
+ }
219
+ return false;
220
+ }
221
+
222
+ function isNullVariant(schema: Record<string, unknown>): boolean {
223
+ return schema.type === "null" && Object.keys(schema).length === 1;
224
+ }
225
+
226
+ function isScalarVariant(schema: Record<string, unknown>): schema is Record<string, unknown> & { type: string } {
227
+ return typeof schema.type === "string" && NULLABLE_SCALAR_TYPES.has(schema.type);
228
+ }
229
+
230
+ function hasIntegerType(type: unknown): boolean {
231
+ return type === "integer" || (Array.isArray(type) && type.includes("integer"));
232
+ }
233
+
234
+ function copyNullableScalarConstraints(schema: Record<string, unknown>, scalarVariant: Record<string, unknown>): void {
235
+ for (const key in scalarVariant) {
236
+ if (key === "type" || key === "enum" || key === "const" || Object.hasOwn(schema, key)) continue;
237
+ schema[key] = scalarVariant[key];
238
+ }
239
+
240
+ if (Object.hasOwn(scalarVariant, "const")) {
241
+ schema.enum = [scalarVariant.const, null];
242
+ return;
243
+ }
244
+
245
+ const enumValues = scalarVariant.enum;
246
+ if (Array.isArray(enumValues)) {
247
+ schema.enum = enumValues.includes(null) ? enumValues : [...enumValues, null];
248
+ }
249
+ }
250
+
251
+ function rewriteNullableScalarAnyOf(schema: Record<string, unknown>): void {
252
+ if (hasSchemaDefiningSibling(schema)) return;
253
+ const variants = schema.anyOf;
254
+ if (!Array.isArray(variants) || variants.length !== 2) return;
255
+
256
+ let scalarVariant: Record<string, unknown> | undefined;
257
+ let scalarType: string | undefined;
258
+ let sawNull = false;
259
+ for (const variant of variants) {
260
+ if (!isSchemaRecord(variant)) return;
261
+ if (isNullVariant(variant)) {
262
+ if (sawNull) return;
263
+ sawNull = true;
264
+ continue;
265
+ }
266
+ if (!isScalarVariant(variant) || scalarVariant) return;
267
+ scalarVariant = variant;
268
+ scalarType = variant.type;
269
+ }
270
+ if (!sawNull || !scalarVariant || !scalarType) return;
271
+
272
+ delete schema.anyOf;
273
+ copyNullableScalarConstraints(schema, scalarVariant);
274
+ schema.type = [scalarType, "null"];
275
+ }
276
+
277
+ /** Keys whose values are a single JSON Schema (not an array or map). */
278
+ const SCHEMA_VALUE_KEYS = [
279
+ "additionalProperties",
280
+ "unevaluatedProperties",
281
+ "unevaluatedItems",
282
+ "items",
283
+ "contains",
284
+ "propertyNames",
285
+ "if",
286
+ "then",
287
+ "else",
288
+ "not",
289
+ ] as const;
290
+
291
+ /** Keys whose values are a map of `{ key: Schema }` entries. */
292
+ const SCHEMA_MAP_KEYS = ["properties", "patternProperties", "$defs", "definitions"] as const;
293
+
294
+ /** Keys whose values are an array of schemas. */
295
+ const SCHEMA_ARRAY_KEYS = ["anyOf", "oneOf", "allOf", "prefixItems"] as const;
296
+
297
+ function normalizeArkPropertyComments(node: unknown): void {
298
+ if (Array.isArray(node)) {
299
+ for (const child of node) normalizeArkPropertyComments(child);
300
+ return;
301
+ }
302
+ if (!isSchemaRecord(node)) return;
303
+ const obj = node as Record<string, unknown>;
304
+
305
+ const properties = obj.properties;
306
+ if (isSchemaRecord(properties)) {
307
+ const required = Array.isArray(obj.required) ? obj.required : undefined;
308
+ if (required) {
309
+ obj.required = required.map(key => (typeof key === "string" ? parseArkObjectKey(key).name : key));
310
+ }
311
+ for (const key of Object.keys(properties)) {
312
+ const parsed = parseArkObjectKey(key);
313
+ const targetKey = parsed.name;
314
+ let propertySchema = properties[key];
315
+ if (parsed.description) {
316
+ propertySchema = withArkKeyDescription(propertySchema, parsed.description);
317
+ delete properties[key];
318
+ properties[targetKey] = propertySchema;
319
+ }
320
+ normalizeArkPropertyComments(propertySchema);
321
+ }
322
+ }
323
+
324
+ for (const key of SCHEMA_VALUE_KEYS) {
325
+ if (Object.hasOwn(obj, key)) normalizeArkPropertyComments(obj[key]);
326
+ }
327
+ for (const mapKey of SCHEMA_MAP_KEYS) {
328
+ if (mapKey === "properties") continue;
329
+ const map = obj[mapKey];
330
+ if (isSchemaRecord(map)) {
331
+ for (const key in map) normalizeArkPropertyComments(map[key]);
332
+ }
333
+ }
334
+ for (const arrayKey of SCHEMA_ARRAY_KEYS) {
335
+ const array = obj[arrayKey];
336
+ if (Array.isArray(array)) {
337
+ for (const child of array) normalizeArkPropertyComments(child);
338
+ }
339
+ }
340
+ }
341
+
342
+ /** True when `val` is a plain empty object `{}`. */
343
+ function isEmptyObject(val: unknown): val is Record<string, never> {
344
+ if (val === null || typeof val !== "object" || Array.isArray(val)) return false;
345
+ return Object.keys(val).length === 0;
346
+ }
347
+
348
+ /**
349
+ * The single JSON Schema scalar `type` that describes every member of a
350
+ * homogeneous primitive enum, or `undefined` when the members are mixed,
351
+ * non-scalar (`null`/object/array), or the list is empty.
352
+ */
353
+ function homogeneousEnumScalarType(values: readonly unknown[]): string | undefined {
354
+ if (values.length === 0) return undefined;
355
+ let inferred: string | undefined;
356
+ for (const value of values) {
357
+ let scalar: string | undefined;
358
+ switch (typeof value) {
359
+ case "string":
360
+ scalar = "string";
361
+ break;
362
+ case "boolean":
363
+ scalar = "boolean";
364
+ break;
365
+ case "number":
366
+ scalar = "number";
367
+ break;
368
+ default:
369
+ return undefined; // null / object / array — not a single scalar type
370
+ }
371
+ if (inferred === undefined) inferred = scalar;
372
+ else if (inferred !== scalar) return undefined; // mixed primitives
373
+ }
374
+ return inferred;
375
+ }
376
+
377
+ /**
378
+ * ArkType emits string-literal unions (and raw JSON-Schema tools can declare
379
+ * enums) as a bare `{ enum: [...] }` with no `type`. That is valid JSON Schema
380
+ * and accepted by OpenAI/Anthropic, but Gemini/Vertex — including the
381
+ * OpenAI-compatible gateways fronting it — reject a function-declaration enum
382
+ * that omits `type` ("schema didn't specify the schema type field"). Complete
383
+ * the node by inferring the scalar `type` when every member shares one.
384
+ */
385
+ function inferBareEnumScalarType(obj: Record<string, unknown>): void {
386
+ if ("type" in obj || !Array.isArray(obj.enum)) return;
387
+ const inferred = homogeneousEnumScalarType(obj.enum);
388
+ if (inferred !== undefined) obj.type = inferred;
389
+ }
390
+
391
+ /**
392
+ * ArkType serializes a *described* literal union — `type.enumerated(...).describe(d)`
393
+ * or a `"a" | "b"` union carrying a description — as an `anyOf` of
394
+ * `{ const, description }` branches that repeat the description on every branch
395
+ * *and* the union root. The meta is distributed across the union's constituents
396
+ * at the type level (each `unit` node inherits it), so the duplication is baked
397
+ * in before serialization rather than added by this pipeline.
398
+ *
399
+ * Collapse such a homogeneous all-`const` union into one typed
400
+ * `{ type, enum, description }` node: a shorter wire and a single description in
401
+ * the place providers expect it. The collapse is conservative — applied only
402
+ * when it is lossless:
403
+ * - every branch is a bare `{ const }` (optionally `{ const, description }`),
404
+ * - all branch values share one scalar JSON type (so `enum` gets a `type`,
405
+ * which Gemini/Vertex require),
406
+ * - branch descriptions are either all absent or all identical,
407
+ * so a union whose branches carry *distinct* per-variant descriptions is left
408
+ * untouched (a flat `enum` has nowhere to keep them). The union root's own
409
+ * description wins when present; otherwise the shared branch description is kept.
410
+ */
411
+ function collapseConstUnionAnyOf(obj: Record<string, unknown>): void {
412
+ // `hasSchemaDefiningSibling` already rejects a sibling `enum`/`const`/etc.; it
413
+ // does not list `type`, so guard it here — collapsing would overwrite a
414
+ // wrapper `type` constraint paired with the `anyOf`.
415
+ if (hasSchemaDefiningSibling(obj) || "type" in obj) return;
416
+ const variants = obj.anyOf;
417
+ if (!Array.isArray(variants) || variants.length < 2) return;
418
+
419
+ const values: unknown[] = [];
420
+ let branchDescription: string | undefined;
421
+ let describedCount = 0;
422
+ for (const variant of variants) {
423
+ if (!isSchemaRecord(variant) || !Object.hasOwn(variant, "const")) return;
424
+ for (const key in variant) {
425
+ if (key !== "const" && key !== "description") return; // extra constraints — not a bare const
426
+ }
427
+ const desc = variant.description;
428
+ if (typeof desc === "string") {
429
+ if (describedCount === 0) branchDescription = desc;
430
+ else if (desc !== branchDescription) return; // distinct per-variant descriptions — preserve them
431
+ describedCount++;
432
+ }
433
+ values.push(variant.const);
434
+ }
435
+ if (describedCount !== 0 && describedCount !== variants.length) return; // mixed described/undescribed
436
+ // A shared branch description that disagrees with the union root's own
437
+ // description would be silently dropped by the collapse — keep the anyOf so
438
+ // neither annotation is lost. (Equal descriptions, the ArkType case, collapse.)
439
+ if (
440
+ describedCount === variants.length &&
441
+ typeof obj.description === "string" &&
442
+ obj.description !== branchDescription
443
+ ) {
444
+ return;
445
+ }
446
+
447
+ const scalarType = homogeneousEnumScalarType(values);
448
+ if (scalarType === undefined) return; // mixed / non-scalar (incl. null) — leave as anyOf
449
+
450
+ delete obj.anyOf;
451
+ obj.type = scalarType;
452
+ obj.enum = values;
453
+ if (typeof obj.description !== "string" && branchDescription !== undefined) {
454
+ obj.description = branchDescription;
455
+ }
456
+ }
457
+
458
+ function walk(node: unknown, zodCleanup: boolean): void {
459
+ if (Array.isArray(node)) {
460
+ for (const child of node) walk(child, zodCleanup);
461
+ return;
462
+ }
463
+ if (!node || typeof node !== "object") return;
464
+ const obj = node as Record<string, unknown>;
465
+ rewriteNullableScalarAnyOf(obj);
466
+ inferBareEnumScalarType(obj);
467
+ collapseConstUnionAnyOf(obj);
468
+
469
+ if (zodCleanup) {
470
+ // Drop noise injected for `z.number().int()`.
471
+ if (hasIntegerType(obj.type)) {
472
+ if (obj.minimum === SAFE_INTEGER_MIN) delete obj.minimum;
473
+ if (obj.maximum === SAFE_INTEGER_MAX) delete obj.maximum;
474
+ }
475
+
476
+ // Make defaulted properties non-required.
477
+ if (Array.isArray(obj.required) && obj.properties && typeof obj.properties === "object") {
478
+ const properties = obj.properties as Record<string, unknown>;
479
+ const required = obj.required as string[];
480
+ const filtered = required.filter(name => {
481
+ const propertySchema = properties[name];
482
+ if (!propertySchema || typeof propertySchema !== "object") return true;
483
+ return !("default" in (propertySchema as Record<string, unknown>));
484
+ });
485
+ if (filtered.length !== required.length) {
486
+ if (filtered.length === 0) {
487
+ delete obj.required;
488
+ } else {
489
+ obj.required = filtered;
490
+ }
491
+ }
492
+ }
493
+ }
494
+
495
+ for (const k in obj) walk(obj[k], zodCleanup);
496
+ }
497
+
498
+ /**
499
+ * Normalize `{}` (empty JSON Schema = `z.unknown()` / unconstrained value) to
500
+ * boolean `true` in every schema-valued position. JSON Schema draft 2020-12
501
+ * §4.3.1: `{}` and `true` are semantically equivalent ("any JSON value").
502
+ * Grammar-constrained samplers (llama.cpp, etc.) treat the object form as
503
+ * "generate an empty object" rather than "any JSON value", causing open-typed
504
+ * fields like `extra.title` (from `z.record(z.string(), z.unknown())`) to
505
+ * always emit `{}` instead of the intended string/number/etc. (issue #1179).
506
+ *
507
+ * Mutates in place. Provider-agnostic — applied to every tool wire schema so
508
+ * Anthropic, Google, OpenAI, Ollama, Bedrock, and Cursor all see the
509
+ * normalized form, regardless of whether the source was Zod or TypeBox.
510
+ */
511
+ export function normalizeEmptySchemas(node: unknown): void {
512
+ if (Array.isArray(node)) {
513
+ for (const child of node) normalizeEmptySchemas(child);
514
+ return;
515
+ }
516
+ if (!node || typeof node !== "object") return;
517
+ const obj = node as Record<string, unknown>;
518
+
519
+ for (const key of SCHEMA_VALUE_KEYS) {
520
+ if (Object.hasOwn(obj, key) && isEmptyObject(obj[key])) obj[key] = true;
521
+ }
522
+ for (const mapKey of SCHEMA_MAP_KEYS) {
523
+ const map = obj[mapKey];
524
+ if (map !== null && typeof map === "object" && !Array.isArray(map)) {
525
+ for (const k in map as Record<string, unknown>) {
526
+ if (isEmptyObject((map as Record<string, unknown>)[k])) (map as Record<string, unknown>)[k] = true;
527
+ }
528
+ }
529
+ }
530
+ for (const arrKey of SCHEMA_ARRAY_KEYS) {
531
+ const arr = obj[arrKey];
532
+ if (Array.isArray(arr)) {
533
+ for (let i = 0; i < arr.length; i++) {
534
+ if (isEmptyObject(arr[i])) arr[i] = true;
535
+ }
536
+ }
537
+ }
538
+
539
+ for (const k in obj) normalizeEmptySchemas(obj[k]);
540
+ }
541
+
542
+ /** Convert a Zod schema into the JSON Schema shape providers consume. */
543
+ export function zodToWireSchema(schema: ZodType): Record<string, unknown> {
544
+ return stamp(schema, kZodWireSchema, s => {
545
+ // `target: "draft-2020-12"` matches what Anthropic's `input_schema` validator
546
+ // requires out of the box; our other provider sanitizers (OpenAI strict,
547
+ // Google, Anthropic CCA) already handle the superset structurally.
548
+ const raw = z.toJSONSchema(s, { target: "draft-2020-12" }) as Record<string, unknown>;
549
+ return postProcess(raw);
550
+ });
551
+ }
552
+
553
+ /**
554
+ * Recursively set `additionalProperties: false` on declared object nodes so the
555
+ * model-facing wire matches Zod's closed emission. Only nodes that declare
556
+ * `properties` and carry neither `additionalProperties` nor `patternProperties`
557
+ * are closed — open record/index nodes (which already carry one of those, e.g.
558
+ * `additionalProperties: true` after empty-schema normalization) stay open.
559
+ *
560
+ * Traverses only schema-valued positions via the shared traversal-key constants
561
+ * so it never descends into `default`/`examples`/`enum`/`const` instance data.
562
+ */
563
+ function closeDeclaredObjects(node: unknown): void {
564
+ if (Array.isArray(node)) {
565
+ for (const child of node) closeDeclaredObjects(child);
566
+ return;
567
+ }
568
+ if (!node || typeof node !== "object") return;
569
+ const obj = node as Record<string, unknown>;
570
+
571
+ const isObjectType = obj.type === "object" || (Array.isArray(obj.type) && obj.type.includes("object"));
572
+ if (
573
+ isObjectType &&
574
+ obj.properties !== undefined &&
575
+ !("additionalProperties" in obj) &&
576
+ !("patternProperties" in obj)
577
+ ) {
578
+ obj.additionalProperties = false;
579
+ }
580
+
581
+ for (const key of SCHEMA_VALUE_KEYS) {
582
+ if (Object.hasOwn(obj, key)) closeDeclaredObjects(obj[key]);
583
+ }
584
+ for (const mapKey of SCHEMA_MAP_KEYS) {
585
+ const map = obj[mapKey];
586
+ if (map !== null && typeof map === "object" && !Array.isArray(map)) {
587
+ for (const k in map as Record<string, unknown>) closeDeclaredObjects((map as Record<string, unknown>)[k]);
588
+ }
589
+ }
590
+ for (const arrKey of SCHEMA_ARRAY_KEYS) {
591
+ const arr = obj[arrKey];
592
+ if (Array.isArray(arr)) for (const child of arr) closeDeclaredObjects(child);
593
+ }
594
+ }
595
+
596
+ /** A subschema admitting any JSON value: `{}` or boolean `true` (draft 2020-12 §4.3.1). */
597
+ function isUnconstrainedSchema(val: unknown): boolean {
598
+ return val === true || isEmptyObject(val);
599
+ }
600
+
601
+ /**
602
+ * ArkType-only: prune the unconstrained branch ArkType emits for a `T | undefined`
603
+ * value-union (e.g. `{ id: "string | undefined" }`).
604
+ *
605
+ * `undefined` has no JSON Schema form, so `arkToWireSchema`'s `fallback` degrades the
606
+ * `undefined` arm to the unconstrained empty schema, producing
607
+ * `{ anyOf: [{ type: "string" }, {}] }`. That bare `{}`/`true` combiner branch makes
608
+ * the property match any value; strict providers (OpenAI/Codex) reject it ("Invalid
609
+ * schema for function ..."), and `enforceStrictSchema` waves the non-object `true`
610
+ * branch straight through, so the break only surfaces server-side. This drops the
611
+ * unconstrained branch(es) from every ArkType-emitted `anyOf`/`oneOf` and inlines the
612
+ * lone remaining concrete branch (keeping sibling keywords like `description`).
613
+ *
614
+ * `required` is deliberately left untouched: ArkType validates a `T | undefined` key
615
+ * as required-present (an absent key is rejected at runtime), so the wire must keep the
616
+ * key required to stay consistent with runtime validation — demoting it to optional
617
+ * would let the model omit the key (or, under strict-mode nullable wrapping, send
618
+ * `null`) and then fail ArkType validation.
619
+ *
620
+ * Scoped to `arkToWireSchema` and run before `normalizeEmptySchemas` so the
621
+ * provider-agnostic `{}`→`true` pass (issue #1179) still preserves intentional open
622
+ * unions in Zod / raw-JSON tools. Traverses only schema-valued positions so it never
623
+ * descends into `default`/`examples`/`enum`/`const` instance data.
624
+ */
625
+ function pruneArkUndefinedUnionBranches(node: unknown): void {
626
+ if (Array.isArray(node)) {
627
+ for (const child of node) pruneArkUndefinedUnionBranches(child);
628
+ return;
629
+ }
630
+ if (!node || typeof node !== "object") return;
631
+ const obj = node as Record<string, unknown>;
632
+
633
+ for (const unionKey of ["anyOf", "oneOf"] as const) {
634
+ const branches = obj[unionKey];
635
+ if (!Array.isArray(branches)) continue;
636
+ const concrete = branches.filter(branch => !isUnconstrainedSchema(branch));
637
+ if (concrete.length === branches.length || concrete.length === 0) continue;
638
+ const only = concrete.length === 1 ? concrete[0] : undefined;
639
+ if (only !== undefined && isSchemaRecord(only)) {
640
+ delete obj[unionKey];
641
+ for (const key in only) {
642
+ if (!(key in obj)) obj[key] = only[key];
643
+ }
644
+ } else {
645
+ obj[unionKey] = concrete;
646
+ }
647
+ }
648
+
649
+ for (const key of SCHEMA_VALUE_KEYS) {
650
+ if (Object.hasOwn(obj, key)) pruneArkUndefinedUnionBranches(obj[key]);
651
+ }
652
+ for (const mapKey of SCHEMA_MAP_KEYS) {
653
+ const map = obj[mapKey];
654
+ if (map !== null && typeof map === "object" && !Array.isArray(map)) {
655
+ for (const key in map as Record<string, unknown>) {
656
+ pruneArkUndefinedUnionBranches((map as Record<string, unknown>)[key]);
657
+ }
658
+ }
659
+ }
660
+ for (const arrKey of SCHEMA_ARRAY_KEYS) {
661
+ const arr = obj[arrKey];
662
+ if (Array.isArray(arr)) for (const child of arr) pruneArkUndefinedUnionBranches(child);
663
+ }
664
+ }
665
+
666
+ /**
667
+ * Convert an ArkType schema into the JSON Schema shape providers consume.
668
+ *
669
+ * Mirrors {@link zodToWireSchema}: emit draft-2020-12, drop the `$schema`
670
+ * metadata, run the JSON-schema post-process (NOT the Zod-only cleanup), then
671
+ * close declared objects so the wire is `additionalProperties: false` like Zod.
672
+ *
673
+ * The `fallback` degrades any un-emittable node (a `.narrow()` predicate or a
674
+ * morph) to its underlying base schema instead of throwing — matching Zod,
675
+ * whose `.refine()`/`.transform()` likewise never appear in the wire schema.
676
+ */
677
+ export function arkToWireSchema(schema: Type): Record<string, unknown> {
678
+ return stamp(schema, kArkWireSchema, s => {
679
+ const raw = s.toJsonSchema({ target: "draft-2020-12", fallback: ctx => ctx.base }) as Record<string, unknown>;
680
+ delete raw.$schema;
681
+ pruneArkUndefinedUnionBranches(raw);
682
+ const upgraded = postProcessJsonSchema(upgradeJsonSchemaTo202012(raw) as Record<string, unknown>);
683
+ closeDeclaredObjects(upgraded);
684
+ return upgraded;
685
+ });
686
+ }
687
+
688
+ /**
689
+ * Resolve a tool's parameters to a JSON Schema object suitable for sending
690
+ * over the wire. Zod schemas are converted (and cached); legacy TypeBox / raw
691
+ * JSON Schema parameters are upgraded to draft 2020-12 (and cached).
692
+ *
693
+ * Zod schemas also receive Zod-artifact cleanup; both branches normalize
694
+ * schema-valued positions and nullable scalar unions.
695
+ */
696
+ export function toolWireSchema(tool: Tool): Record<string, unknown> {
697
+ const params: TSchema = tool.parameters;
698
+ if (isArkSchema(params)) return arkToWireSchema(params);
699
+ if (isZodSchema(params)) return zodToWireSchema(params);
700
+ return stamp(params as Record<string, unknown>, kJsonWireSchema, p => {
701
+ const raw = isArkJsonAst(p) ? arkJsonAstToWire(p) : p;
702
+ const upgraded = upgradeJsonSchemaTo202012(raw) as Record<string, unknown>;
703
+ return postProcessJsonSchema(upgraded);
704
+ });
705
+ }
706
+
707
+ /**
708
+ * Schema-valued keywords whose value is a single subschema (or an array of
709
+ * subschemas — the recursion dispatches on array-ness, so tuple forms like
710
+ * draft-07 `items: []` are handled too). Covers the draft 2020-12 surface plus
711
+ * the legacy `additionalItems` that may survive an incomplete upgrade.
712
+ */
713
+ const STRIP_SCHEMA_VALUE_KEYS = [
714
+ "additionalProperties",
715
+ "unevaluatedProperties",
716
+ "unevaluatedItems",
717
+ "items",
718
+ "additionalItems",
719
+ "contains",
720
+ "propertyNames",
721
+ "contentSchema",
722
+ "if",
723
+ "then",
724
+ "else",
725
+ "not",
726
+ "anyOf",
727
+ "oneOf",
728
+ "allOf",
729
+ "prefixItems",
730
+ ] as const;
731
+
732
+ /** Keywords whose value is a `{ name: Schema }` map — names are NOT annotations. */
733
+ const STRIP_SCHEMA_MAP_KEYS = ["properties", "patternProperties", "$defs", "definitions", "dependentSchemas"] as const;
734
+
735
+ /**
736
+ * Recursively strip human-readable `description` annotations from a JSON Schema,
737
+ * descending only through schema-valued keywords so a property literally named
738
+ * `"description"` inside a `properties`/`$defs` map keeps its schema (only its own
739
+ * annotation is dropped), and data-bearing keywords (`default`/`const`/`examples`)
740
+ * are never traversed. Mutates `node` in place — callers pass a clone.
741
+ */
742
+ function stripSchemaDescriptionsInPlace(node: unknown): void {
743
+ if (Array.isArray(node)) {
744
+ for (const child of node) stripSchemaDescriptionsInPlace(child);
745
+ return;
746
+ }
747
+ if (!isSchemaRecord(node)) return;
748
+ delete node.description;
749
+ for (const key of STRIP_SCHEMA_VALUE_KEYS) {
750
+ if (Object.hasOwn(node, key)) stripSchemaDescriptionsInPlace(node[key]);
751
+ }
752
+ for (const mapKey of STRIP_SCHEMA_MAP_KEYS) {
753
+ const map = node[mapKey];
754
+ if (isSchemaRecord(map)) {
755
+ for (const key in map) stripSchemaDescriptionsInPlace(map[key]);
756
+ }
757
+ }
758
+ }
759
+
760
+ /**
761
+ * Return a deep clone of `schema` with every `description` annotation removed.
762
+ * The result is memoized on the input via a non-enumerable symbol (`stamp`) so
763
+ * repeated provider requests reuse the same stripped object; the input is never
764
+ * mutated, so the stamped `toolWireSchema` cache stays intact for
765
+ * system-prompt/UI rendering.
766
+ */
767
+ export function stripSchemaDescriptions(schema: Record<string, unknown>): Record<string, unknown> {
768
+ return stamp(schema, kStrippedSchema, source => {
769
+ const clone = structuredClone(source);
770
+ stripSchemaDescriptionsInPlace(clone);
771
+ return clone;
772
+ });
773
+ }
774
+
775
+ /**
776
+ * Strip a tool's human-readable text from its provider-bound spec: empties the
777
+ * top-level `description` and removes nested schema `description` annotations.
778
+ * Used when the full tool catalog is rendered into the system prompt instead, so
779
+ * the descriptions ride the wire once (in the prompt) rather than duplicated on
780
+ * every tool definition. Parameters are resolved to wire JSON Schema and cloned,
781
+ * leaving the original tool objects and the stamped schema cache untouched.
782
+ */
783
+ export function stripToolDescriptions(tools: readonly Tool[]): Tool[] {
784
+ return tools.map(tool => ({
785
+ ...tool,
786
+ description: "",
787
+ parameters: stripSchemaDescriptions(toolWireSchema(tool)),
788
+ }));
789
+ }