@yansigit/opencodex 2.31.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 (826) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/LICENSE +21 -0
  3. package/README.md +303 -0
  4. package/assets/architecture.png +0 -0
  5. package/assets/banner.png +0 -0
  6. package/assets/claude-code-models.gif +0 -0
  7. package/assets/codex-app-picker.png +0 -0
  8. package/bin/ocx.mjs +587 -0
  9. package/bin/package-main.mjs +9 -0
  10. package/gui/dist/assets/index-BNJ7r4Gd.js +102 -0
  11. package/gui/dist/assets/index-CGoDO3uO.css +1 -0
  12. package/gui/dist/favicon.png +0 -0
  13. package/gui/dist/icons.svg +24 -0
  14. package/gui/dist/index.html +25 -0
  15. package/gui/dist/logo.png +0 -0
  16. package/gui/dist/provider-icons/alibaba-color.svg +1 -0
  17. package/gui/dist/provider-icons/antigravity-color.svg +1 -0
  18. package/gui/dist/provider-icons/claude-color.svg +1 -0
  19. package/gui/dist/provider-icons/cline-color.svg +16 -0
  20. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
  21. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  22. package/gui/dist/provider-icons/copilot-color.svg +1 -0
  23. package/gui/dist/provider-icons/cursor-color.svg +2 -0
  24. package/gui/dist/provider-icons/deepseek-color.svg +1 -0
  25. package/gui/dist/provider-icons/discord.svg +1 -0
  26. package/gui/dist/provider-icons/firepass-color.svg +1 -0
  27. package/gui/dist/provider-icons/fireworks-color.svg +1 -0
  28. package/gui/dist/provider-icons/gemini-color.svg +1 -0
  29. package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
  30. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
  31. package/gui/dist/provider-icons/grok.svg +1 -0
  32. package/gui/dist/provider-icons/groq-color.svg +1 -0
  33. package/gui/dist/provider-icons/huggingface-color.svg +1 -0
  34. package/gui/dist/provider-icons/kimi-color.svg +1 -0
  35. package/gui/dist/provider-icons/kiro-color.svg +15 -0
  36. package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
  37. package/gui/dist/provider-icons/mistral-color.svg +1 -0
  38. package/gui/dist/provider-icons/moonshot-color.svg +1 -0
  39. package/gui/dist/provider-icons/nvidia-color.svg +1 -0
  40. package/gui/dist/provider-icons/ollama-color.svg +1 -0
  41. package/gui/dist/provider-icons/openai.svg +1 -0
  42. package/gui/dist/provider-icons/opencode.svg +2 -0
  43. package/gui/dist/provider-icons/openrouter-color.svg +1 -0
  44. package/gui/dist/provider-icons/pi.svg +21 -0
  45. package/gui/dist/provider-icons/qianfan-color.svg +1 -0
  46. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
  47. package/gui/dist/provider-icons/telegram.svg +1 -0
  48. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
  49. package/gui/dist/provider-icons/vllm-color.svg +1 -0
  50. package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
  51. package/package.json +108 -0
  52. package/src/AGENTS.md +28 -0
  53. package/src/adapters/anthropic-image-guard.ts +251 -0
  54. package/src/adapters/anthropic-image-normalize.ts +518 -0
  55. package/src/adapters/anthropic-output-schema.ts +137 -0
  56. package/src/adapters/anthropic.ts +1327 -0
  57. package/src/adapters/azure.ts +36 -0
  58. package/src/adapters/base.ts +121 -0
  59. package/src/adapters/client-fingerprint.ts +65 -0
  60. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  61. package/src/adapters/command-code.ts +601 -0
  62. package/src/adapters/cursor/arg-codec.ts +38 -0
  63. package/src/adapters/cursor/arg-normalize.ts +104 -0
  64. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  65. package/src/adapters/cursor/cursor-errors.ts +288 -0
  66. package/src/adapters/cursor/discovery.ts +333 -0
  67. package/src/adapters/cursor/effort-map.ts +151 -0
  68. package/src/adapters/cursor/exec-policy.ts +88 -0
  69. package/src/adapters/cursor/framing.ts +250 -0
  70. package/src/adapters/cursor/gen/agent_pb.ts +15274 -0
  71. package/src/adapters/cursor/h2-pool.ts +123 -0
  72. package/src/adapters/cursor/http1-bidi.ts +361 -0
  73. package/src/adapters/cursor/images.ts +704 -0
  74. package/src/adapters/cursor/kv-store.ts +52 -0
  75. package/src/adapters/cursor/live-models.ts +269 -0
  76. package/src/adapters/cursor/live-smoke-gate.ts +41 -0
  77. package/src/adapters/cursor/live-transport.ts +1653 -0
  78. package/src/adapters/cursor/mcp-config.ts +42 -0
  79. package/src/adapters/cursor/mcp-manager.ts +333 -0
  80. package/src/adapters/cursor/message-mapper.ts +49 -0
  81. package/src/adapters/cursor/native-exec-common.ts +76 -0
  82. package/src/adapters/cursor/native-exec-desktop.ts +184 -0
  83. package/src/adapters/cursor/native-exec-fs.ts +332 -0
  84. package/src/adapters/cursor/native-exec-mcp.ts +153 -0
  85. package/src/adapters/cursor/native-exec-network.ts +43 -0
  86. package/src/adapters/cursor/native-exec-shell.ts +547 -0
  87. package/src/adapters/cursor/native-exec-tools.ts +118 -0
  88. package/src/adapters/cursor/native-exec.ts +663 -0
  89. package/src/adapters/cursor/protobuf-events.ts +1381 -0
  90. package/src/adapters/cursor/protobuf-request.ts +1032 -0
  91. package/src/adapters/cursor/request-builder.ts +461 -0
  92. package/src/adapters/cursor/thread-continuity.ts +67 -0
  93. package/src/adapters/cursor/tool-definitions.ts +735 -0
  94. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  95. package/src/adapters/cursor/transport-retry.ts +132 -0
  96. package/src/adapters/cursor/transport.ts +79 -0
  97. package/src/adapters/cursor/types.ts +79 -0
  98. package/src/adapters/cursor.ts +322 -0
  99. package/src/adapters/google-antigravity-hosts.ts +48 -0
  100. package/src/adapters/google-antigravity-replay.ts +827 -0
  101. package/src/adapters/google-antigravity-tools.ts +105 -0
  102. package/src/adapters/google-antigravity-wire.ts +141 -0
  103. package/src/adapters/google-errors.ts +92 -0
  104. package/src/adapters/google-http.ts +460 -0
  105. package/src/adapters/google-tool-schema.ts +238 -0
  106. package/src/adapters/google-truncation.ts +24 -0
  107. package/src/adapters/google-wire-compiler.ts +232 -0
  108. package/src/adapters/google.ts +1377 -0
  109. package/src/adapters/identity.ts +77 -0
  110. package/src/adapters/image.ts +23 -0
  111. package/src/adapters/kiro-constants.ts +16 -0
  112. package/src/adapters/kiro-errors.ts +208 -0
  113. package/src/adapters/kiro-events.ts +197 -0
  114. package/src/adapters/kiro-images.ts +129 -0
  115. package/src/adapters/kiro-retry.ts +312 -0
  116. package/src/adapters/kiro-thinking.ts +112 -0
  117. package/src/adapters/kiro-tool-fallback.ts +36 -0
  118. package/src/adapters/kiro-tools.ts +224 -0
  119. package/src/adapters/kiro-truncation.ts +33 -0
  120. package/src/adapters/kiro-wire.ts +129 -0
  121. package/src/adapters/kiro.ts +1936 -0
  122. package/src/adapters/mimo-free.ts +280 -0
  123. package/src/adapters/openai-chat-url.ts +11 -0
  124. package/src/adapters/openai-chat.ts +1980 -0
  125. package/src/adapters/openai-responses-url.ts +16 -0
  126. package/src/adapters/openai-responses.ts +1911 -0
  127. package/src/adapters/registry.ts +175 -0
  128. package/src/adapters/responses-tool-schema.ts +67 -0
  129. package/src/adapters/run-turn-queue.ts +114 -0
  130. package/src/adapters/tool-call-id.ts +119 -0
  131. package/src/adapters/tool-catalog-nudge.ts +154 -0
  132. package/src/adapters/upstream-http-error.ts +48 -0
  133. package/src/adapters/xai-web-search.ts +185 -0
  134. package/src/bridge.ts +1986 -0
  135. package/src/chat/inbound.ts +319 -0
  136. package/src/chat/outbound.ts +821 -0
  137. package/src/claude/agents-inject.ts +266 -0
  138. package/src/claude/alias.ts +149 -0
  139. package/src/claude/auth-detect.ts +229 -0
  140. package/src/claude/auth-mode-migration.ts +32 -0
  141. package/src/claude/auth-mode.ts +62 -0
  142. package/src/claude/context-windows.ts +205 -0
  143. package/src/claude/desktop-3p-guard.ts +35 -0
  144. package/src/claude/desktop-3p-paths.ts +84 -0
  145. package/src/claude/desktop-3p.ts +615 -0
  146. package/src/claude/desktop-health.ts +26 -0
  147. package/src/claude/desktop-profile.ts +263 -0
  148. package/src/claude/gateway-cache.ts +107 -0
  149. package/src/claude/inbound-debug.ts +163 -0
  150. package/src/claude/inbound.ts +578 -0
  151. package/src/claude/model-info.ts +174 -0
  152. package/src/claude/outbound.ts +926 -0
  153. package/src/cli/access.ts +108 -0
  154. package/src/cli/account-api.ts +302 -0
  155. package/src/cli/account-auth.ts +250 -0
  156. package/src/cli/account-catalog-refresh.ts +14 -0
  157. package/src/cli/account-extended.ts +737 -0
  158. package/src/cli/account-main.ts +317 -0
  159. package/src/cli/account.ts +299 -0
  160. package/src/cli/agent-driven.ts +70 -0
  161. package/src/cli/agent.ts +290 -0
  162. package/src/cli/catalog-prewarm.ts +27 -0
  163. package/src/cli/claude-agent-startup-sync.ts +73 -0
  164. package/src/cli/claude-desktop.ts +213 -0
  165. package/src/cli/claude.ts +355 -0
  166. package/src/cli/codex-log-guard-doctor.ts +103 -0
  167. package/src/cli/codex-shim-autorestore.ts +47 -0
  168. package/src/cli/codex-shim-readiness.ts +76 -0
  169. package/src/cli/combo.ts +127 -0
  170. package/src/cli/config-command.ts +209 -0
  171. package/src/cli/debug.ts +228 -0
  172. package/src/cli/dispatch.ts +585 -0
  173. package/src/cli/doctor.ts +1202 -0
  174. package/src/cli/ensure-desired-integrations.ts +152 -0
  175. package/src/cli/export-command.ts +213 -0
  176. package/src/cli/help.ts +101 -0
  177. package/src/cli/index.ts +973 -0
  178. package/src/cli/init.ts +211 -0
  179. package/src/cli/integrations.ts +260 -0
  180. package/src/cli/interactive-confirm.ts +133 -0
  181. package/src/cli/lab.ts +607 -0
  182. package/src/cli/launcher-context.ts +77 -0
  183. package/src/cli/minimax.ts +497 -0
  184. package/src/cli/models-runtime.ts +245 -0
  185. package/src/cli/models.ts +422 -0
  186. package/src/cli/observe.ts +206 -0
  187. package/src/cli/opencode.ts +588 -0
  188. package/src/cli/provider-replit.ts +232 -0
  189. package/src/cli/provider-runtime.ts +179 -0
  190. package/src/cli/provider.ts +492 -0
  191. package/src/cli/ready.ts +301 -0
  192. package/src/cli/registry.ts +422 -0
  193. package/src/cli/replit-gateway-key-input.ts +138 -0
  194. package/src/cli/root.ts +86 -0
  195. package/src/cli/route-policy.ts +92 -0
  196. package/src/cli/runtime-api.ts +328 -0
  197. package/src/cli/star-prompt.ts +211 -0
  198. package/src/cli/status-oauth.ts +78 -0
  199. package/src/cli/status.ts +328 -0
  200. package/src/cli/system-command.ts +112 -0
  201. package/src/cli/system-restart-client.ts +146 -0
  202. package/src/cli/tray-proxy.ts +199 -0
  203. package/src/cli/v2.ts +268 -0
  204. package/src/cli.ts +10 -0
  205. package/src/clients/config-export.ts +1704 -0
  206. package/src/codex/account-id.ts +34 -0
  207. package/src/codex/account-label.ts +47 -0
  208. package/src/codex/account-lifecycle.ts +172 -0
  209. package/src/codex/account-namespace-match.ts +63 -0
  210. package/src/codex/account-namespaces.ts +195 -0
  211. package/src/codex/account-pause.ts +20 -0
  212. package/src/codex/account-priority.ts +83 -0
  213. package/src/codex/account-runtime-state.ts +31 -0
  214. package/src/codex/account-store.ts +544 -0
  215. package/src/codex/account-usability.ts +43 -0
  216. package/src/codex/admission.ts +256 -0
  217. package/src/codex/affinity-debug.ts +162 -0
  218. package/src/codex/agent-roles-sync.ts +225 -0
  219. package/src/codex/agent-roles.ts +238 -0
  220. package/src/codex/app-server-processes.ts +1143 -0
  221. package/src/codex/app-server-restart-service.ts +232 -0
  222. package/src/codex/auth-api.ts +2147 -0
  223. package/src/codex/auth-collision.ts +109 -0
  224. package/src/codex/auth-context.ts +665 -0
  225. package/src/codex/autostart-health.ts +156 -0
  226. package/src/codex/catalog/account-models.ts +67 -0
  227. package/src/codex/catalog/aggregation.ts +436 -0
  228. package/src/codex/catalog/bundled.ts +549 -0
  229. package/src/codex/catalog/effort.ts +446 -0
  230. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  231. package/src/codex/catalog/kinds.ts +2 -0
  232. package/src/codex/catalog/metadata.ts +664 -0
  233. package/src/codex/catalog/native-models.ts +72 -0
  234. package/src/codex/catalog/parsing.ts +650 -0
  235. package/src/codex/catalog/provider-fetch.ts +2064 -0
  236. package/src/codex/catalog/sync.ts +1883 -0
  237. package/src/codex/catalog-admission.ts +199 -0
  238. package/src/codex/catalog-refresh-status.ts +105 -0
  239. package/src/codex/catalog-write-serialization.ts +242 -0
  240. package/src/codex/catalog.ts +14 -0
  241. package/src/codex/codex-write-lock.ts +384 -0
  242. package/src/codex/convergence-types.ts +614 -0
  243. package/src/codex/convergence.ts +651 -0
  244. package/src/codex/coordinator-doctor.ts +332 -0
  245. package/src/codex/custom-model-catalog-migration.ts +176 -0
  246. package/src/codex/data/upstream-models.json +830 -0
  247. package/src/codex/desired-state.ts +230 -0
  248. package/src/codex/exec-invocation.ts +22 -0
  249. package/src/codex/features.ts +1566 -0
  250. package/src/codex/generation.ts +202 -0
  251. package/src/codex/history-job.ts +407 -0
  252. package/src/codex/history-lock.ts +242 -0
  253. package/src/codex/history-migration-guardian.ts +108 -0
  254. package/src/codex/history-provider.ts +979 -0
  255. package/src/codex/history-transition.ts +105 -0
  256. package/src/codex/history-worker.ts +220 -0
  257. package/src/codex/home.ts +206 -0
  258. package/src/codex/inject-coordination.ts +290 -0
  259. package/src/codex/inject.ts +1733 -0
  260. package/src/codex/injected-marker.ts +106 -0
  261. package/src/codex/integration-record.ts +266 -0
  262. package/src/codex/internal/catalog-writer.ts +203 -0
  263. package/src/codex/internal/history-writer.ts +80 -0
  264. package/src/codex/journal.ts +225 -0
  265. package/src/codex/log-guard/inspect.ts +506 -0
  266. package/src/codex/log-guard/lock.ts +150 -0
  267. package/src/codex/log-guard/maintenance.ts +403 -0
  268. package/src/codex/log-guard/path-safety.ts +88 -0
  269. package/src/codex/log-guard/policy.ts +44 -0
  270. package/src/codex/log-guard/processes.ts +205 -0
  271. package/src/codex/log-guard/protection.ts +489 -0
  272. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  273. package/src/codex/main-account-cache.ts +56 -0
  274. package/src/codex/main-account.ts +68 -0
  275. package/src/codex/management-convergence.ts +167 -0
  276. package/src/codex/model-cache.ts +273 -0
  277. package/src/codex/model-entitlements.ts +353 -0
  278. package/src/codex/native-main-admission.ts +47 -0
  279. package/src/codex/native-main-auth-temp.ts +187 -0
  280. package/src/codex/native-main-claim.ts +178 -0
  281. package/src/codex/native-main-lock-file.ts +162 -0
  282. package/src/codex/native-main-owner.ts +329 -0
  283. package/src/codex/native-profile-api.ts +247 -0
  284. package/src/codex/native-profile-manager.ts +1531 -0
  285. package/src/codex/native-profile-processes.ts +121 -0
  286. package/src/codex/native-profile-recovery.ts +99 -0
  287. package/src/codex/native-profile-stage-store.ts +387 -0
  288. package/src/codex/native-profile-startup.ts +492 -0
  289. package/src/codex/native-profile-store.ts +855 -0
  290. package/src/codex/native-profile-types.ts +120 -0
  291. package/src/codex/native-residue.ts +682 -0
  292. package/src/codex/paths.ts +144 -0
  293. package/src/codex/plan-from-token.ts +140 -0
  294. package/src/codex/plan.ts +40 -0
  295. package/src/codex/plugins-doctor.ts +242 -0
  296. package/src/codex/pool-rotation.ts +295 -0
  297. package/src/codex/project-config-warnings.ts +425 -0
  298. package/src/codex/prompt-journal.ts +352 -0
  299. package/src/codex/prompt-layers.ts +967 -0
  300. package/src/codex/prompt-lock.ts +143 -0
  301. package/src/codex/quota-rejection.ts +298 -0
  302. package/src/codex/quota.ts +573 -0
  303. package/src/codex/refresh.ts +62 -0
  304. package/src/codex/reset-credit-recovery.ts +1044 -0
  305. package/src/codex/routing.ts +1888 -0
  306. package/src/codex/runtime.ts +659 -0
  307. package/src/codex/shim.ts +2170 -0
  308. package/src/codex/subagent-defaults.ts +550 -0
  309. package/src/codex/subagent-model-fallback.ts +784 -0
  310. package/src/codex/sync.ts +319 -0
  311. package/src/codex/transition-state.ts +612 -0
  312. package/src/codex/upstream-host-health.ts +368 -0
  313. package/src/codex/user-identity.ts +557 -0
  314. package/src/codex/warmup.ts +298 -0
  315. package/src/codex/websocket-registry.ts +100 -0
  316. package/src/codex/write-coordination.ts +114 -0
  317. package/src/combos/failover.ts +160 -0
  318. package/src/combos/index.ts +45 -0
  319. package/src/combos/request.ts +94 -0
  320. package/src/combos/resolve.ts +232 -0
  321. package/src/combos/types.ts +398 -0
  322. package/src/config/provider-name.ts +24 -0
  323. package/src/config.ts +4041 -0
  324. package/src/fork/register.ts +3 -0
  325. package/src/generated/compatibility-version.json +3116 -0
  326. package/src/generated/model-metadata.ts +106 -0
  327. package/src/github/star-state.ts +203 -0
  328. package/src/grok/inject.ts +530 -0
  329. package/src/grok/inspect.ts +45 -0
  330. package/src/grok/status.ts +121 -0
  331. package/src/grok/sync.ts +66 -0
  332. package/src/images/artifacts.ts +516 -0
  333. package/src/images/fulfill-video.ts +163 -0
  334. package/src/images/fulfill.ts +149 -0
  335. package/src/images/index.ts +4 -0
  336. package/src/images/loop.ts +955 -0
  337. package/src/images/plan.ts +143 -0
  338. package/src/images/synthetic-tool.ts +133 -0
  339. package/src/images/types.ts +41 -0
  340. package/src/images/xai-client.ts +141 -0
  341. package/src/images/xai-video-client.ts +163 -0
  342. package/src/index.ts +22 -0
  343. package/src/integrations/config-io.ts +269 -0
  344. package/src/integrations/journal.ts +315 -0
  345. package/src/integrations/merge.ts +135 -0
  346. package/src/integrations/mutation-flight.ts +71 -0
  347. package/src/integrations/native/ownership-preflight.ts +202 -0
  348. package/src/integrations/omp-yaml-source.ts +358 -0
  349. package/src/integrations/owned-refresh.ts +74 -0
  350. package/src/integrations/ownership.ts +111 -0
  351. package/src/integrations/registry.ts +159 -0
  352. package/src/integrations/serialize.ts +314 -0
  353. package/src/integrations/state.ts +361 -0
  354. package/src/integrations/store.ts +103 -0
  355. package/src/integrations/writer-lock.ts +98 -0
  356. package/src/integrations/writer.ts +691 -0
  357. package/src/lab/artifacts/sanitize.ts +586 -0
  358. package/src/lab/artifacts/secure-fs.ts +475 -0
  359. package/src/lab/artifacts/store.ts +310 -0
  360. package/src/lab/automation/budgets.ts +78 -0
  361. package/src/lab/automation/config-persistence.ts +256 -0
  362. package/src/lab/automation/constants.ts +39 -0
  363. package/src/lab/automation/cooldown.ts +103 -0
  364. package/src/lab/automation/dispatch.ts +211 -0
  365. package/src/lab/automation/index.ts +13 -0
  366. package/src/lab/automation/orchestrator.ts +499 -0
  367. package/src/lab/automation/persistence.ts +512 -0
  368. package/src/lab/automation/planner.ts +371 -0
  369. package/src/lab/automation/policy.ts +136 -0
  370. package/src/lab/automation/queue.ts +191 -0
  371. package/src/lab/automation/recovery.ts +24 -0
  372. package/src/lab/automation/route-context.ts +21 -0
  373. package/src/lab/automation/run-key.ts +44 -0
  374. package/src/lab/automation/runs-query.ts +34 -0
  375. package/src/lab/automation/types.ts +160 -0
  376. package/src/lab/conformance/assertion.ts +325 -0
  377. package/src/lab/conformance/digest.ts +22 -0
  378. package/src/lab/conformance/executor.ts +741 -0
  379. package/src/lab/conformance/fixture-provider.ts +27 -0
  380. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  381. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  382. package/src/lab/conformance/harness-budget.ts +47 -0
  383. package/src/lab/conformance/index.ts +5 -0
  384. package/src/lab/conformance/jcs.ts +64 -0
  385. package/src/lab/conformance/json-pointer.ts +39 -0
  386. package/src/lab/conformance/manifest.ts +180 -0
  387. package/src/lab/conformance/mcp-stub.ts +179 -0
  388. package/src/lab/conformance/negative-controls.ts +164 -0
  389. package/src/lab/conformance/observation.ts +355 -0
  390. package/src/lab/conformance/runner.ts +68 -0
  391. package/src/lab/conformance/sse-normalize.ts +59 -0
  392. package/src/lab/conformance/suite-manifest.ts +78 -0
  393. package/src/lab/conformance/types.ts +214 -0
  394. package/src/lab/constants.ts +126 -0
  395. package/src/lab/digest.ts +64 -0
  396. package/src/lab/events/errors.ts +9 -0
  397. package/src/lab/events/limits.ts +117 -0
  398. package/src/lab/events/types.ts +229 -0
  399. package/src/lab/events/validate.ts +781 -0
  400. package/src/lab/fabric/constants.ts +40 -0
  401. package/src/lab/fabric/executor.ts +492 -0
  402. package/src/lab/fabric/index.ts +80 -0
  403. package/src/lab/fabric/manifest.ts +222 -0
  404. package/src/lab/fabric/observe.ts +489 -0
  405. package/src/lab/fabric/patch.ts +79 -0
  406. package/src/lab/fabric/producer-child.ts +139 -0
  407. package/src/lab/fabric/producer-isolate.ts +276 -0
  408. package/src/lab/fabric/producer-protocol.ts +61 -0
  409. package/src/lab/fabric/scratch.ts +439 -0
  410. package/src/lab/fabric/subject.ts +106 -0
  411. package/src/lab/fabric/types.ts +134 -0
  412. package/src/lab/fabric/verifier.ts +98 -0
  413. package/src/lab/index.ts +54 -0
  414. package/src/lab/ledger/artifact-refs.ts +127 -0
  415. package/src/lab/ledger/invalidation.ts +136 -0
  416. package/src/lab/ledger/purge.ts +310 -0
  417. package/src/lab/ledger/store.ts +532 -0
  418. package/src/lab/live/credential-lease.ts +53 -0
  419. package/src/lab/live/destination.ts +155 -0
  420. package/src/lab/live/executor.ts +336 -0
  421. package/src/lab/live/inert-tools.ts +56 -0
  422. package/src/lab/live/manifest.ts +85 -0
  423. package/src/lab/live/mcp-loopback.ts +57 -0
  424. package/src/lab/live/runner.ts +19 -0
  425. package/src/lab/live/sandbox.ts +61 -0
  426. package/src/lab/live/suite-manifest.ts +41 -0
  427. package/src/lab/live/transport.ts +118 -0
  428. package/src/lab/live/types.ts +197 -0
  429. package/src/lab/observe/from-conformance.ts +301 -0
  430. package/src/lab/observe/from-live.ts +117 -0
  431. package/src/lab/paths.ts +153 -0
  432. package/src/lab/projection/rebuild.ts +495 -0
  433. package/src/lab/projection/schema.ts +135 -0
  434. package/src/lab/projection/verdicts.ts +474 -0
  435. package/src/lab/projection/verification.ts +412 -0
  436. package/src/lab/public/bundle.ts +217 -0
  437. package/src/lab/public/community-authority.ts +175 -0
  438. package/src/lab/public/community-files.ts +29 -0
  439. package/src/lab/public/community.ts +479 -0
  440. package/src/lab/public/file-safety.ts +155 -0
  441. package/src/lab/public/ids.ts +26 -0
  442. package/src/lab/public/index.ts +16 -0
  443. package/src/lab/public/mutation-lock.ts +424 -0
  444. package/src/lab/public/operator.ts +353 -0
  445. package/src/lab/public/origin-purge.ts +79 -0
  446. package/src/lab/public/origin.ts +203 -0
  447. package/src/lab/public/privacy.ts +143 -0
  448. package/src/lab/public/private-file.ts +261 -0
  449. package/src/lab/public/project.ts +124 -0
  450. package/src/lab/public/purge-test-fault.ts +21 -0
  451. package/src/lab/public/purge.ts +223 -0
  452. package/src/lab/public/registry.ts +44 -0
  453. package/src/lab/public/revocation.ts +252 -0
  454. package/src/lab/public/signature.ts +243 -0
  455. package/src/lab/public/storage.ts +105 -0
  456. package/src/lab/public/strict-json.ts +206 -0
  457. package/src/lab/public/time.ts +26 -0
  458. package/src/lab/public/types.ts +172 -0
  459. package/src/lab/public/validate.ts +391 -0
  460. package/src/lab/query/catalog.ts +101 -0
  461. package/src/lab/query/connection.ts +107 -0
  462. package/src/lab/query/constants.ts +4 -0
  463. package/src/lab/query/cursor.ts +132 -0
  464. package/src/lab/query/dto-map.ts +277 -0
  465. package/src/lab/query/errors.ts +22 -0
  466. package/src/lab/query/freshness.ts +53 -0
  467. package/src/lab/query/index.ts +45 -0
  468. package/src/lab/query/latest-observation.ts +59 -0
  469. package/src/lab/query/passive-production.ts +159 -0
  470. package/src/lab/query/queries.ts +444 -0
  471. package/src/lab/query/types.ts +266 -0
  472. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  473. package/src/lab/subject/installation-salt.ts +112 -0
  474. package/src/lab/subject/protocol-subject.ts +80 -0
  475. package/src/lab/subject/route-subject.ts +74 -0
  476. package/src/lib/abort.ts +146 -0
  477. package/src/lib/admin-secrets.ts +25 -0
  478. package/src/lib/admission.ts +83 -0
  479. package/src/lib/app-owned-memory-stores.ts +195 -0
  480. package/src/lib/app-owned-memory.ts +265 -0
  481. package/src/lib/bounded-body.ts +346 -0
  482. package/src/lib/bun-binary-validator.d.mts +3 -0
  483. package/src/lib/bun-binary-validator.mjs +18 -0
  484. package/src/lib/bun-runtime.ts +184 -0
  485. package/src/lib/bun-stream-caps.ts +130 -0
  486. package/src/lib/codex-restart-contract.ts +120 -0
  487. package/src/lib/config-ownership.ts +364 -0
  488. package/src/lib/crash-guard.ts +344 -0
  489. package/src/lib/debug-log-buffer.ts +83 -0
  490. package/src/lib/debug-settings.ts +108 -0
  491. package/src/lib/debug.ts +31 -0
  492. package/src/lib/destination-policy.ts +380 -0
  493. package/src/lib/errors.ts +406 -0
  494. package/src/lib/eventstream-decoder.ts +253 -0
  495. package/src/lib/fabric-task-execution-authority.ts +7 -0
  496. package/src/lib/fabric-task-host.ts +29 -0
  497. package/src/lib/gcp-adc.ts +341 -0
  498. package/src/lib/injection-debug-log.ts +58 -0
  499. package/src/lib/lab-activation.ts +223 -0
  500. package/src/lib/lab-live-execution-authority.ts +13 -0
  501. package/src/lib/lab-live-host.ts +30 -0
  502. package/src/lib/lab-live-pinned-sender.ts +56 -0
  503. package/src/lib/lab-live-route-production.ts +130 -0
  504. package/src/lib/lab-passive-linker-registration.ts +26 -0
  505. package/src/lib/local-management-attestation.ts +51 -0
  506. package/src/lib/local-management-capability.ts +100 -0
  507. package/src/lib/local-provider-reload-contract.ts +100 -0
  508. package/src/lib/open-url.ts +25 -0
  509. package/src/lib/optional-shutdown-hooks.ts +57 -0
  510. package/src/lib/pinned-http.ts +270 -0
  511. package/src/lib/privacy.ts +20 -0
  512. package/src/lib/process-control.ts +168 -0
  513. package/src/lib/provider-outbound.ts +210 -0
  514. package/src/lib/provider-url.ts +14 -0
  515. package/src/lib/proxy-env.ts +18 -0
  516. package/src/lib/redact.ts +521 -0
  517. package/src/lib/retry-after.ts +55 -0
  518. package/src/lib/self-launch-argv.ts +15 -0
  519. package/src/lib/server-resource-ownership.ts +71 -0
  520. package/src/lib/service-secrets.ts +25 -0
  521. package/src/lib/shadow-call.ts +61 -0
  522. package/src/lib/sidecar-tracker.ts +52 -0
  523. package/src/lib/sse-decoder.ts +364 -0
  524. package/src/lib/state-store-registrations.ts +119 -0
  525. package/src/lib/state-store-sweeper.ts +184 -0
  526. package/src/lib/system-restart-contract.ts +73 -0
  527. package/src/lib/test-home-guard.ts +90 -0
  528. package/src/lib/token-estimate.ts +86 -0
  529. package/src/lib/tool-argument-integers.ts +202 -0
  530. package/src/lib/translator-budget.ts +400 -0
  531. package/src/lib/upstream-http-version.ts +57 -0
  532. package/src/lib/upstream-reachability.ts +95 -0
  533. package/src/lib/upstream-retry.ts +392 -0
  534. package/src/lib/win-exec.ts +115 -0
  535. package/src/lib/win-paths.ts +68 -0
  536. package/src/lib/windows-atomic-replace.ts +156 -0
  537. package/src/lib/windows-elevation.ts +773 -0
  538. package/src/lib/windows-secret-acl.ts +854 -0
  539. package/src/lib/windows-service-wrappers.ts +72 -0
  540. package/src/lib/windows-text.ts +106 -0
  541. package/src/lib/windows-user-principal.ts +341 -0
  542. package/src/lib/winsw.ts +403 -0
  543. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  544. package/src/oauth/account-import/index.ts +15 -0
  545. package/src/oauth/account-import/parser.ts +83 -0
  546. package/src/oauth/account-import/registry.ts +18 -0
  547. package/src/oauth/account-import/service.ts +75 -0
  548. package/src/oauth/account-import/types.ts +91 -0
  549. package/src/oauth/anthropic-routing.ts +594 -0
  550. package/src/oauth/anthropic.ts +188 -0
  551. package/src/oauth/antigravity-routing.ts +151 -0
  552. package/src/oauth/callback-server.ts +300 -0
  553. package/src/oauth/chatgpt.ts +161 -0
  554. package/src/oauth/command-code.ts +239 -0
  555. package/src/oauth/cursor.ts +252 -0
  556. package/src/oauth/github-copilot.ts +428 -0
  557. package/src/oauth/google-antigravity.ts +262 -0
  558. package/src/oauth/health.ts +407 -0
  559. package/src/oauth/index.ts +1504 -0
  560. package/src/oauth/key-providers.ts +124 -0
  561. package/src/oauth/kimi.ts +227 -0
  562. package/src/oauth/kiro-credentials.ts +726 -0
  563. package/src/oauth/kiro.ts +621 -0
  564. package/src/oauth/local-token-detect.ts +130 -0
  565. package/src/oauth/log.ts +50 -0
  566. package/src/oauth/login-cli.ts +223 -0
  567. package/src/oauth/nous.ts +798 -0
  568. package/src/oauth/pkce.ts +15 -0
  569. package/src/oauth/store.ts +728 -0
  570. package/src/oauth/token-guardian.ts +309 -0
  571. package/src/oauth/types.ts +62 -0
  572. package/src/oauth/xai.ts +241 -0
  573. package/src/providers/alibaba-region-backup.ts +75 -0
  574. package/src/providers/alibaba-region-migration.ts +156 -0
  575. package/src/providers/alibaba-region-startup.ts +36 -0
  576. package/src/providers/antigravity-models.ts +695 -0
  577. package/src/providers/antigravity-quota.ts +216 -0
  578. package/src/providers/api-keys.ts +140 -0
  579. package/src/providers/base-url-choices.ts +74 -0
  580. package/src/providers/codex-capacity.ts +292 -0
  581. package/src/providers/command-code-efforts.ts +144 -0
  582. package/src/providers/context-cap.ts +82 -0
  583. package/src/providers/cursor-pool.ts +72 -0
  584. package/src/providers/derive.ts +586 -0
  585. package/src/providers/fastwire.ts +501 -0
  586. package/src/providers/free-directory.ts +187 -0
  587. package/src/providers/github-copilot-transport.ts +56 -0
  588. package/src/providers/google-vertex-location.ts +14 -0
  589. package/src/providers/key-failover.ts +271 -0
  590. package/src/providers/kiro-models.ts +67 -0
  591. package/src/providers/label.ts +19 -0
  592. package/src/providers/model-discovery-limits.ts +16 -0
  593. package/src/providers/model-discovery.ts +449 -0
  594. package/src/providers/model-rename-migration.ts +255 -0
  595. package/src/providers/model-rename-startup.ts +28 -0
  596. package/src/providers/openai-sidecar.ts +243 -0
  597. package/src/providers/openai-tier-startup.ts +56 -0
  598. package/src/providers/openai-tiers.ts +423 -0
  599. package/src/providers/openai-virtual-models.ts +83 -0
  600. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  601. package/src/providers/openrouter-routing.ts +102 -0
  602. package/src/providers/provider-id-rewrite.ts +185 -0
  603. package/src/providers/quota.ts +2345 -0
  604. package/src/providers/registry.ts +2918 -0
  605. package/src/providers/replit/constants.ts +27 -0
  606. package/src/providers/replit/derive.ts +85 -0
  607. package/src/providers/replit/headers.ts +28 -0
  608. package/src/providers/replit/origin.ts +55 -0
  609. package/src/providers/replit/pair-install-response.ts +72 -0
  610. package/src/providers/replit/probe.ts +199 -0
  611. package/src/providers/replit/setup.ts +350 -0
  612. package/src/providers/request-pacing.ts +310 -0
  613. package/src/providers/service-tier.ts +277 -0
  614. package/src/providers/slug-codec.ts +103 -0
  615. package/src/providers/static-model-discovery.ts +86 -0
  616. package/src/providers/xai-responses-opt-in.ts +15 -0
  617. package/src/providers/xai-transport.ts +148 -0
  618. package/src/reasoning-effort.ts +183 -0
  619. package/src/responses/compaction.ts +142 -0
  620. package/src/responses/custom-tool-compat.ts +266 -0
  621. package/src/responses/hosted-tool-policy.ts +9 -0
  622. package/src/responses/namespace-tool-compat.ts +355 -0
  623. package/src/responses/parser.ts +838 -0
  624. package/src/responses/provider-continuation.ts +98 -0
  625. package/src/responses/provider-opaque-metadata.ts +73 -0
  626. package/src/responses/reasoning-envelope.ts +60 -0
  627. package/src/responses/reasoning-replay-cache.ts +426 -0
  628. package/src/responses/schema.ts +165 -0
  629. package/src/responses/spill-store.ts +459 -0
  630. package/src/responses/state.ts +1433 -0
  631. package/src/responses/thought-signature-replay.ts +347 -0
  632. package/src/responses/tool-groups.ts +19 -0
  633. package/src/responses/tool-search-compat.ts +301 -0
  634. package/src/responses/truncated-stop-reason.ts +60 -0
  635. package/src/router.ts +761 -0
  636. package/src/routing/analytics.ts +378 -0
  637. package/src/routing/capability.ts +244 -0
  638. package/src/routing/compatibility/assemble.ts +73 -0
  639. package/src/routing/compatibility/behavior.ts +278 -0
  640. package/src/routing/compatibility/catalog.ts +99 -0
  641. package/src/routing/compatibility/endpoint.ts +52 -0
  642. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  643. package/src/routing/compatibility/policy.ts +181 -0
  644. package/src/routing/compatibility/provider-slot.ts +56 -0
  645. package/src/routing/compatibility/reader.ts +110 -0
  646. package/src/routing/compatibility/subject.ts +191 -0
  647. package/src/routing/compatibility/types.ts +64 -0
  648. package/src/routing/compatibility/version.ts +104 -0
  649. package/src/routing/cost.ts +77 -0
  650. package/src/routing/evaluator.ts +495 -0
  651. package/src/routing/health.ts +412 -0
  652. package/src/routing/history/cursor.ts +43 -0
  653. package/src/routing/history/indexer.ts +605 -0
  654. package/src/routing/history/schema.ts +72 -0
  655. package/src/routing/profile-namespace.ts +15 -0
  656. package/src/routing/profile.ts +547 -0
  657. package/src/routing/quota.ts +145 -0
  658. package/src/routing/request-evidence.ts +45 -0
  659. package/src/routing/trace.ts +776 -0
  660. package/src/server/adapter-resolve.ts +53 -0
  661. package/src/server/auth-cors.ts +751 -0
  662. package/src/server/background-lifecycle.ts +182 -0
  663. package/src/server/chat-completions.ts +442 -0
  664. package/src/server/chat-native-sse.ts +331 -0
  665. package/src/server/chat-native.ts +426 -0
  666. package/src/server/claude-messages.ts +1030 -0
  667. package/src/server/direct-local-http.ts +347 -0
  668. package/src/server/effort-policy.ts +190 -0
  669. package/src/server/github-copilot-responses-repair.ts +338 -0
  670. package/src/server/gui-static.ts +152 -0
  671. package/src/server/image-retry.ts +42 -0
  672. package/src/server/images.ts +568 -0
  673. package/src/server/index.ts +1813 -0
  674. package/src/server/lifecycle.ts +498 -0
  675. package/src/server/live.ts +717 -0
  676. package/src/server/local-management-read-client.ts +90 -0
  677. package/src/server/local-provider-reload-client.ts +137 -0
  678. package/src/server/management/agent-settings-routes.ts +1433 -0
  679. package/src/server/management/api-access.ts +141 -0
  680. package/src/server/management/api-key-usage.ts +193 -0
  681. package/src/server/management/body.ts +41 -0
  682. package/src/server/management/combo-routes.ts +263 -0
  683. package/src/server/management/config-routes.ts +835 -0
  684. package/src/server/management/context.ts +113 -0
  685. package/src/server/management/integration-routes.ts +498 -0
  686. package/src/server/management/lab-automation-routes.ts +206 -0
  687. package/src/server/management/lab-routes.ts +563 -0
  688. package/src/server/management/logs-usage-routes.ts +586 -0
  689. package/src/server/management/model-routes.ts +560 -0
  690. package/src/server/management/model-rows.ts +163 -0
  691. package/src/server/management/native-integration-routes.ts +769 -0
  692. package/src/server/management/oauth-account-routes.ts +637 -0
  693. package/src/server/management/provider-capability-config.ts +48 -0
  694. package/src/server/management/provider-routes.ts +1033 -0
  695. package/src/server/management/replit-provider-routes.ts +86 -0
  696. package/src/server/management/request-history-routes.ts +191 -0
  697. package/src/server/management/routing-analytics-routes.ts +74 -0
  698. package/src/server/management/routing-profile-routes.ts +385 -0
  699. package/src/server/management/shared.ts +286 -0
  700. package/src/server/management/sidebar-routes.ts +106 -0
  701. package/src/server/management/storage-log-guard-routes.ts +186 -0
  702. package/src/server/management/sync-response.ts +69 -0
  703. package/src/server/management/system-restart.ts +435 -0
  704. package/src/server/management/system-routes.ts +194 -0
  705. package/src/server/management/usage-summary-cache.ts +94 -0
  706. package/src/server/management/vision-sidecar-options.ts +167 -0
  707. package/src/server/management/web-search-sidecar-options.ts +120 -0
  708. package/src/server/management-api.ts +314 -0
  709. package/src/server/management-auth.ts +482 -0
  710. package/src/server/memory-watchdog.ts +156 -0
  711. package/src/server/passive-route-linker.ts +66 -0
  712. package/src/server/port-reclaim.ts +307 -0
  713. package/src/server/ports.ts +156 -0
  714. package/src/server/proxy-liveness.ts +328 -0
  715. package/src/server/readiness.ts +99 -0
  716. package/src/server/relay-eager.ts +353 -0
  717. package/src/server/relay.ts +1209 -0
  718. package/src/server/request-decompress.ts +239 -0
  719. package/src/server/request-log-conversation.ts +168 -0
  720. package/src/server/request-log.ts +1259 -0
  721. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  722. package/src/server/responses/agent-task-recovery.ts +465 -0
  723. package/src/server/responses/collaboration.ts +551 -0
  724. package/src/server/responses/compact.ts +771 -0
  725. package/src/server/responses/core.ts +5389 -0
  726. package/src/server/responses/empty-completion-guard.ts +276 -0
  727. package/src/server/responses/encrypted-payload.ts +331 -0
  728. package/src/server/responses/fetch-helpers.ts +232 -0
  729. package/src/server/responses/input-admission.ts +185 -0
  730. package/src/server/responses/pacing-overload.ts +13 -0
  731. package/src/server/responses/passthrough-error.ts +78 -0
  732. package/src/server/responses/policy-fallback.ts +178 -0
  733. package/src/server/responses/responses-field-backfill.ts +251 -0
  734. package/src/server/responses/terminal-guard.ts +251 -0
  735. package/src/server/responses/upstream-error.ts +53 -0
  736. package/src/server/responses/ws-upstream.ts +308 -0
  737. package/src/server/responses-custom-tool-repair.ts +282 -0
  738. package/src/server/responses-image-gen-repair.ts +132 -0
  739. package/src/server/responses-item-id-repair.ts +272 -0
  740. package/src/server/responses-json-events.ts +90 -0
  741. package/src/server/responses-model-rewrite.ts +29 -0
  742. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  743. package/src/server/responses-snapshot-repair.ts +621 -0
  744. package/src/server/responses-terminal-repair.ts +342 -0
  745. package/src/server/responses-tool-search-repair.ts +267 -0
  746. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  747. package/src/server/responses.ts +25 -0
  748. package/src/server/search.ts +201 -0
  749. package/src/server/sse-frame-buffer.ts +292 -0
  750. package/src/server/sse-payload-rewrite.ts +263 -0
  751. package/src/server/startup-action-control.ts +315 -0
  752. package/src/server/startup-health-cache.ts +131 -0
  753. package/src/server/system-env.ts +484 -0
  754. package/src/server/windows-tcp-drop.ts +184 -0
  755. package/src/server/windows-tray-control.ts +41 -0
  756. package/src/server/ws-bridge.ts +472 -0
  757. package/src/service-manager-probe.ts +892 -0
  758. package/src/service.ts +3575 -0
  759. package/src/sidecar/auth.ts +92 -0
  760. package/src/sidecar/candidates.ts +83 -0
  761. package/src/stall-timeout.ts +20 -0
  762. package/src/storage/cleanup-job.ts +57 -0
  763. package/src/storage/cleanup.ts +3085 -0
  764. package/src/storage/policy-job.ts +457 -0
  765. package/src/storage/policy-scheduler.ts +40 -0
  766. package/src/storage/policy-worker.ts +59 -0
  767. package/src/storage/policy.ts +527 -0
  768. package/src/storage/restore-job.ts +299 -0
  769. package/src/storage/restore-worker.ts +58 -0
  770. package/src/storage/scanner.ts +238 -0
  771. package/src/storage/storage-mutation-coordinator.ts +139 -0
  772. package/src/storage/worker-lifecycle.ts +215 -0
  773. package/src/tray/assets/opencodex-tray-offline.ico +0 -0
  774. package/src/tray/assets/opencodex-tray-online.ico +0 -0
  775. package/src/tray/assets/opencodex-tray-warning.ico +0 -0
  776. package/src/tray/assets/opencodex-tray.png +0 -0
  777. package/src/tray/windows-tray.ps1 +364 -0
  778. package/src/tray/windows.ts +757 -0
  779. package/src/types/accounts.ts +37 -0
  780. package/src/types/config.ts +876 -0
  781. package/src/types/provider.ts +545 -0
  782. package/src/types/request.ts +384 -0
  783. package/src/types/tools.ts +131 -0
  784. package/src/types/wire.ts +80 -0
  785. package/src/types.ts +106 -0
  786. package/src/update/badge.ts +72 -0
  787. package/src/update/index.ts +415 -0
  788. package/src/update/job.ts +1887 -0
  789. package/src/update/notify.ts +263 -0
  790. package/src/update/npm-cache-preflight.d.mts +47 -0
  791. package/src/update/npm-cache-preflight.mjs +201 -0
  792. package/src/update/npm-invocation.d.mts +23 -0
  793. package/src/update/npm-invocation.mjs +94 -0
  794. package/src/update/transactional-install.d.mts +22 -0
  795. package/src/update/transactional-install.mjs +259 -0
  796. package/src/update/tray-update-plan.d.mts +18 -0
  797. package/src/update/tray-update-plan.mjs +38 -0
  798. package/src/usage/cost.ts +625 -0
  799. package/src/usage/debug.ts +97 -0
  800. package/src/usage/expected-prices.ts +416 -0
  801. package/src/usage/log.ts +1223 -0
  802. package/src/usage/summary.ts +753 -0
  803. package/src/usage/totals.ts +14 -0
  804. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  805. package/src/usage/user-cost-overlays.ts +314 -0
  806. package/src/vision/anthropic-describe.ts +189 -0
  807. package/src/vision/backends.ts +97 -0
  808. package/src/vision/describe.ts +131 -0
  809. package/src/vision/eligibility.ts +250 -0
  810. package/src/vision/index.ts +681 -0
  811. package/src/vision/reasoning.ts +55 -0
  812. package/src/vision/routed-describe.ts +175 -0
  813. package/src/vision/timeout-bounds.ts +9 -0
  814. package/src/web-search/anthropic-executor.ts +195 -0
  815. package/src/web-search/backends.ts +108 -0
  816. package/src/web-search/exa-executor.ts +88 -0
  817. package/src/web-search/executor.ts +113 -0
  818. package/src/web-search/format-result.ts +89 -0
  819. package/src/web-search/gemini-executor.ts +141 -0
  820. package/src/web-search/index.ts +331 -0
  821. package/src/web-search/loop.ts +896 -0
  822. package/src/web-search/parse.ts +315 -0
  823. package/src/web-search/progress-stream.ts +342 -0
  824. package/src/web-search/sources.ts +60 -0
  825. package/src/web-search/synthetic-tool.ts +47 -0
  826. package/src/web-search/xai-executor.ts +219 -0
@@ -0,0 +1,460 @@
1
+ import type { AdapterFetchContext, AdapterRequest } from "./base";
2
+ import {
3
+ isAntigravityGeoBlockedBody,
4
+ isQuotaExhaustedBody,
5
+ retryableGoogleStatus,
6
+ safeGoogleHttpErrorMessage,
7
+ } from "./google-errors";
8
+ import { repairGoogleInvalidRequestBody } from "./google-wire-compiler";
9
+ import { normalizeUpstreamHttpErrorResponse, readDisplaySafeErrorPayloadText } from "./upstream-http-error";
10
+ import { recordAntigravityCooldown } from "../oauth/antigravity-routing";
11
+ import {
12
+ antigravityHostCandidates,
13
+ canonicalAntigravityHttpsHost,
14
+ isAntigravityHttpsHost,
15
+ } from "./google-antigravity-hosts";
16
+ import {
17
+ abortError,
18
+ cancelResponseBodyBestEffort,
19
+ fetchWithAttemptDeadline,
20
+ retryBackoffDelayMs,
21
+ sleepWithAbort,
22
+ } from "../lib/upstream-retry";
23
+
24
+ const GOOGLE_RETRY_ATTEMPTS = 3;
25
+ const GOOGLE_RETRY_BASE_MS = 250;
26
+ const GOOGLE_RETRY_MAX_MS = 2_000;
27
+ export const CCA_STREAM_CLASSIFY_MAX_BYTES = 256 * 1024;
28
+ export const CCA_STREAM_PROBE_MAX_BYTES = CCA_STREAM_CLASSIFY_MAX_BYTES;
29
+
30
+ function isAntigravitySseRequest(request: AdapterRequest): boolean {
31
+ return request.url.includes("/v1internal:streamGenerateContent?alt=sse");
32
+ }
33
+
34
+ function requestForHost(request: AdapterRequest, host: string): AdapterRequest {
35
+ const current = new URL(request.url);
36
+ const target = new URL(host);
37
+ target.pathname = current.pathname;
38
+ target.search = current.search;
39
+ return { ...request, url: target.toString() };
40
+ }
41
+
42
+ type CcaSseProbe = "empty" | "candidate" | "unavailable" | "quota_exhausted" | "geo_blocked" | "terminal";
43
+
44
+ function probeCcaSseEvent(bytes: Uint8Array): CcaSseProbe {
45
+ const text = new TextDecoder().decode(bytes);
46
+ for (const line of text.split(/\r?\n/)) {
47
+ if (!line.startsWith("data:")) continue;
48
+ const payload = line.slice(5).trim();
49
+ if (!payload) continue;
50
+ let frame: unknown;
51
+ try {
52
+ frame = JSON.parse(payload);
53
+ } catch {
54
+ return "terminal";
55
+ }
56
+ if (!frame || typeof frame !== "object" || Array.isArray(frame)) return "terminal";
57
+ const record = frame as Record<string, unknown>;
58
+ if (record.error) {
59
+ const error = record.error;
60
+ const errorRecord = error && typeof error === "object" && !Array.isArray(error)
61
+ ? error as Record<string, unknown>
62
+ : {};
63
+ const status = String(errorRecord.status ?? "").toUpperCase();
64
+ const code = errorRecord.code;
65
+ if (status === "UNAVAILABLE" || status === "503" || code === 503 || code === "503") {
66
+ return "unavailable";
67
+ }
68
+ const serialized = JSON.stringify(frame);
69
+ if (isQuotaExhaustedBody(serialized)) return "quota_exhausted";
70
+ if (isAntigravityGeoBlockedBody(serialized)) return "geo_blocked";
71
+ return "terminal";
72
+ }
73
+ const response = record.response;
74
+ if (!response || typeof response !== "object" || Array.isArray(response)) return "terminal";
75
+ const root = response as Record<string, unknown>;
76
+ if (Array.isArray(root.candidates) && root.candidates.length > 0) return "candidate";
77
+ }
78
+ return "empty";
79
+ }
80
+
81
+ export class CcaProbeBuffer {
82
+ private storage: Uint8Array;
83
+ length = 0;
84
+
85
+ constructor(private readonly maxBytes = CCA_STREAM_PROBE_MAX_BYTES) {
86
+ this.storage = new Uint8Array(Math.min(64 * 1024, maxBytes));
87
+ }
88
+
89
+ append(next: Uint8Array): boolean {
90
+ if (next.byteLength === 0) return true;
91
+ const required = this.length + next.byteLength;
92
+ if (required > this.maxBytes) return false;
93
+ if (required > this.storage.byteLength) {
94
+ let capacity = Math.max(this.storage.byteLength, 1);
95
+ while (capacity < required) {
96
+ const grownCapacity = Math.min(this.maxBytes, capacity * 2);
97
+ capacity = grownCapacity <= capacity ? this.maxBytes : grownCapacity;
98
+ }
99
+ const grown = new Uint8Array(capacity);
100
+ grown.set(this.storage.subarray(0, this.length));
101
+ this.storage = grown;
102
+ }
103
+ this.storage.set(next, this.length);
104
+ this.length = required;
105
+ return true;
106
+ }
107
+
108
+ view(): Uint8Array {
109
+ return this.storage.subarray(0, this.length);
110
+ }
111
+ }
112
+
113
+ function firstSseEventEnd(bytes: Uint8Array, from: number): number | undefined {
114
+ for (let index = from; index + 1 < bytes.byteLength; index++) {
115
+ if (bytes[index] === 10 && bytes[index + 1] === 10) return index + 2;
116
+ if (index + 3 < bytes.byteLength
117
+ && bytes[index] === 13 && bytes[index + 1] === 10
118
+ && bytes[index + 2] === 13 && bytes[index + 3] === 10) {
119
+ return index + 4;
120
+ }
121
+ }
122
+ return undefined;
123
+ }
124
+
125
+ function responseWithBufferedBody(
126
+ response: Response,
127
+ buffered: Uint8Array,
128
+ reader: ReadableStreamDefaultReader<Uint8Array>,
129
+ pending?: Uint8Array,
130
+ status = response.status,
131
+ ): Response {
132
+ let bufferedBody = buffered;
133
+ let pendingBody = pending;
134
+ let readerReleased = false;
135
+ const releaseReader = () => {
136
+ if (readerReleased) return;
137
+ readerReleased = true;
138
+ reader.releaseLock();
139
+ };
140
+ const body = new ReadableStream<Uint8Array>({
141
+ async pull(controller) {
142
+ try {
143
+ if (bufferedBody.byteLength > 0 || pendingBody?.byteLength) {
144
+ if (bufferedBody.byteLength > 0) {
145
+ controller.enqueue(bufferedBody);
146
+ bufferedBody = new Uint8Array();
147
+ }
148
+ if (pendingBody?.byteLength) {
149
+ controller.enqueue(pendingBody);
150
+ pendingBody = undefined;
151
+ }
152
+ return;
153
+ }
154
+
155
+ const { done, value } = await reader.read();
156
+ if (done) {
157
+ controller.close();
158
+ releaseReader();
159
+ return;
160
+ }
161
+ if (value?.byteLength) controller.enqueue(value);
162
+ } catch (error) {
163
+ controller.error(error);
164
+ releaseReader();
165
+ }
166
+ },
167
+ cancel(reason) {
168
+ void reader.cancel(reason).catch(() => {}).finally(releaseReader);
169
+ },
170
+ });
171
+ return new Response(body, {
172
+ status,
173
+ statusText: response.statusText,
174
+ headers: response.headers,
175
+ });
176
+ }
177
+
178
+ async function prepareCcaSseResponse(
179
+ response: Response,
180
+ fetchPeer: (() => Promise<Response>) | undefined,
181
+ ): Promise<Response> {
182
+ if (!response.body) return fetchPeer ? fetchPeer() : response;
183
+ const reader = response.body.getReader();
184
+ const probeBuffer = new CcaProbeBuffer();
185
+ let scanned = 0;
186
+ const passthrough = (pending?: Uint8Array, status = response.status) =>
187
+ responseWithBufferedBody(response, probeBuffer.view(), reader, pending, status);
188
+ const failoverOrPassthrough = async (): Promise<Response> => {
189
+ if (!fetchPeer) return passthrough();
190
+ await reader.cancel().catch(() => {});
191
+ reader.releaseLock();
192
+ return fetchPeer();
193
+ };
194
+ try {
195
+ while (probeBuffer.length < CCA_STREAM_CLASSIFY_MAX_BYTES) {
196
+ if (scanned >= CCA_STREAM_CLASSIFY_MAX_BYTES || probeBuffer.length >= CCA_STREAM_CLASSIFY_MAX_BYTES) {
197
+ return passthrough();
198
+ }
199
+ const { done, value } = await reader.read();
200
+ if (done) {
201
+ const buffered = probeBuffer.view();
202
+ const residual = buffered.subarray(scanned);
203
+ if (residual.byteLength > 0) {
204
+ const probe = probeCcaSseEvent(residual);
205
+ if (probe === "candidate" || probe === "terminal") {
206
+ return passthrough();
207
+ }
208
+ if (probe === "unavailable") {
209
+ return failoverOrPassthrough();
210
+ }
211
+ if (probe === "quota_exhausted" || probe === "geo_blocked") {
212
+ const status = probe === "quota_exhausted" ? 429 : 403;
213
+ return passthrough(undefined, status);
214
+ }
215
+ }
216
+ return failoverOrPassthrough();
217
+ }
218
+ if (!value?.byteLength) continue;
219
+ const classifyRemaining = CCA_STREAM_CLASSIFY_MAX_BYTES - probeBuffer.length;
220
+ const copyBytes = Math.min(value.byteLength, classifyRemaining);
221
+ const overflow = value.byteLength > copyBytes ? value.subarray(copyBytes) : undefined;
222
+ if (copyBytes > 0) {
223
+ probeBuffer.append(value.subarray(0, copyBytes));
224
+ }
225
+ const buffered = probeBuffer.view();
226
+ while (true) {
227
+ if (scanned >= CCA_STREAM_CLASSIFY_MAX_BYTES) return passthrough(overflow);
228
+ const eventEnd = firstSseEventEnd(buffered, scanned);
229
+ if (eventEnd === undefined) break;
230
+ const probe = probeCcaSseEvent(buffered.subarray(scanned, eventEnd));
231
+ scanned = eventEnd;
232
+ if (probe === "candidate") return passthrough(overflow);
233
+ if (probe === "unavailable") {
234
+ if (overflow?.byteLength) {
235
+ return passthrough(overflow);
236
+ }
237
+ return failoverOrPassthrough();
238
+ }
239
+ if (probe === "quota_exhausted" || probe === "geo_blocked") {
240
+ const status = probe === "quota_exhausted" ? 429 : 403;
241
+ return passthrough(overflow, status);
242
+ }
243
+ if (probe === "terminal") return passthrough(overflow);
244
+ }
245
+ if (overflow?.byteLength) return passthrough(overflow);
246
+ if (scanned >= CCA_STREAM_CLASSIFY_MAX_BYTES || probeBuffer.length >= CCA_STREAM_CLASSIFY_MAX_BYTES) {
247
+ return passthrough();
248
+ }
249
+ }
250
+ return passthrough();
251
+ } catch (error) {
252
+ try { await reader.cancel(error); } catch { /* cleanup only */ }
253
+ reader.releaseLock();
254
+ throw error;
255
+ }
256
+ }
257
+
258
+ function isUnavailableResponse(response: Response): boolean {
259
+ return response.status === 503;
260
+ }
261
+
262
+ export interface GoogleRetryOptions {
263
+ /** Repair-and-replay structurally invalid 400 bodies (Vertex/Antigravity behavior). */
264
+ repairInvalid400?: boolean;
265
+ }
266
+
267
+ async function normalizeFinalGoogleError(label: string, res: Response, signal?: AbortSignal): Promise<Response> {
268
+ return normalizeUpstreamHttpErrorResponse(res, {
269
+ signal,
270
+ formatMessage: payloadText => safeGoogleHttpErrorMessage(label, res.status, payloadText),
271
+ });
272
+ }
273
+
274
+ function retryAfterMs(value: string | null, now = Date.now()): number | undefined {
275
+ const text = value?.trim();
276
+ if (!text) return undefined;
277
+ if (/^\d+(?:\.\d+)?$/.test(text)) {
278
+ const seconds = Number(text);
279
+ return Number.isFinite(seconds) && seconds > 0 ? Math.ceil(seconds * 1000) : undefined;
280
+ }
281
+ const timestamp = Date.parse(text);
282
+ return Number.isFinite(timestamp) && timestamp > now ? timestamp - now : undefined;
283
+ }
284
+
285
+ async function recordAntigravityHttpCooldown(
286
+ response: Response,
287
+ accountId: string | undefined,
288
+ ): Promise<boolean> {
289
+ if (!accountId || (response.status !== 429 && response.status !== 403)) return false;
290
+ const payloadText = await readDisplaySafeErrorPayloadText(response.clone());
291
+ if (response.status === 429) {
292
+ recordAntigravityCooldown(
293
+ accountId,
294
+ isQuotaExhaustedBody(payloadText) ? "quota_exhausted" : "rate_limited",
295
+ retryAfterMs(response.headers.get("retry-after")),
296
+ );
297
+ return true;
298
+ }
299
+ if (isAntigravityGeoBlockedBody(payloadText)) {
300
+ recordAntigravityCooldown(accountId, "geo_blocked");
301
+ return true;
302
+ }
303
+ return false;
304
+ }
305
+
306
+ /**
307
+ * Fetch a Google-family upstream with Kiro-style hardening: per-attempt timeout
308
+ * (`AbortSignal.any([parent, timeout])`), bounded retry on transient status / network errors,
309
+ * `Retry-After` honoring, jittered exponential backoff, and (unless raw mode is used) a
310
+ * classified + redacted final error body. `label` is the provider-facing prefix used in error
311
+ * messages.
312
+ */
313
+ async function fetchGoogleWithRetryInternal(
314
+ label: string,
315
+ request: AdapterRequest,
316
+ ctx: AdapterFetchContext,
317
+ allowAntigravityHostFailover: boolean,
318
+ opts: GoogleRetryOptions = {},
319
+ ): Promise<Response> {
320
+ const repairInvalid400 = opts.repairInvalid400 ?? true;
321
+ const timeoutMs = ctx.timeoutMs ?? 200_000;
322
+ const executor = ctx.executor ?? globalThis.fetch;
323
+ let activeRequest = request;
324
+ if (label === "Antigravity" && isAntigravitySseRequest(activeRequest)) {
325
+ const origin = new URL(activeRequest.url).origin;
326
+ const canonicalHttps = canonicalAntigravityHttpsHost(origin);
327
+ if (canonicalHttps) {
328
+ activeRequest = requestForHost(activeRequest, canonicalHttps);
329
+ } else if (!isAntigravityHttpsHost(origin)) {
330
+ throw new Error("Antigravity OAuth bearer requests must use HTTPS");
331
+ }
332
+ }
333
+ const antigravityHosts = allowAntigravityHostFailover && label === "Antigravity" && isAntigravitySseRequest(activeRequest)
334
+ ? antigravityHostCandidates(new URL(activeRequest.url).origin).filter(isAntigravityHttpsHost)
335
+ : [];
336
+ let antigravityHostIndex = 0;
337
+ let lastError: unknown;
338
+ let compatibilityReplayUsed = false;
339
+ for (let attempt = 0; attempt < GOOGLE_RETRY_ATTEMPTS; attempt++) {
340
+ if (ctx.abortSignal?.aborted) throw abortError(ctx.abortSignal);
341
+ try {
342
+ const res = await fetchWithAttemptDeadline(activeRequest.url, {
343
+ method: activeRequest.method,
344
+ headers: activeRequest.headers,
345
+ body: activeRequest.body,
346
+ }, timeoutMs, ctx.abortSignal, ctx.stream, executor);
347
+ if (label === "Antigravity") {
348
+ const cooldownRecorded = await recordAntigravityHttpCooldown(res, ctx.accountId);
349
+ if (cooldownRecorded) {
350
+ return ctx.returnRawErrors ? res : normalizeFinalGoogleError(label, res, ctx.abortSignal);
351
+ }
352
+ }
353
+ if (antigravityHosts.length > 1 && antigravityHostIndex === 0) {
354
+ const shouldTryPeer = res.status === 404 || isUnavailableResponse(res);
355
+ if (shouldTryPeer) {
356
+ cancelResponseBodyBestEffort(res);
357
+ antigravityHostIndex = 1;
358
+ activeRequest = requestForHost(activeRequest, antigravityHosts[antigravityHostIndex]!);
359
+ continue;
360
+ }
361
+ }
362
+ if (label === "Antigravity" && isAntigravitySseRequest(activeRequest) && res.ok) {
363
+ const fetchPeer = antigravityHosts.length > 1 && antigravityHostIndex === 0
364
+ ? () => fetchGoogleWithRetryInternal(
365
+ label,
366
+ requestForHost(activeRequest, antigravityHosts[1]!),
367
+ ctx,
368
+ false,
369
+ opts,
370
+ )
371
+ : undefined;
372
+ return prepareCcaSseResponse(res, fetchPeer);
373
+ }
374
+ if (res.status === 400 && repairInvalid400 && !compatibilityReplayUsed) {
375
+ let payloadText = "";
376
+ try {
377
+ payloadText = await readDisplaySafeErrorPayloadText(res.clone(), ctx.abortSignal);
378
+ } catch (error) {
379
+ if (ctx.abortSignal?.aborted) throw error;
380
+ }
381
+ const repairedBody = repairGoogleInvalidRequestBody(activeRequest.body, payloadText);
382
+ if (repairedBody !== undefined) {
383
+ compatibilityReplayUsed = true;
384
+ activeRequest = { ...activeRequest, body: repairedBody };
385
+ cancelResponseBodyBestEffort(res);
386
+ attempt--; // The changed-request replay is separate from transient retry accounting.
387
+ continue;
388
+ }
389
+ }
390
+ if (!retryableGoogleStatus(res.status) || attempt === GOOGLE_RETRY_ATTEMPTS - 1) {
391
+ return ctx.returnRawErrors ? res : normalizeFinalGoogleError(label, res, ctx.abortSignal);
392
+ }
393
+ // A 429 may be a transient rate limit (retry) or hard quota exhaustion (do NOT retry —
394
+ // it won't recover for hours and burns retries). Peek the body to tell them apart.
395
+ if (res.status === 429) {
396
+ const peekTarget = ctx.returnRawErrors ? res.clone() : res;
397
+ const peek = await readDisplaySafeErrorPayloadText(peekTarget, ctx.abortSignal);
398
+ if (isQuotaExhaustedBody(peek)) {
399
+ return ctx.returnRawErrors ? res : normalizeUpstreamHttpErrorResponse(res, {
400
+ signal: ctx.abortSignal,
401
+ formatMessage: payloadText => safeGoogleHttpErrorMessage(label, res.status, payloadText || peek),
402
+ });
403
+ }
404
+ }
405
+ cancelResponseBodyBestEffort(res);
406
+ await sleepWithAbort(retryBackoffDelayMs(attempt, {
407
+ baseDelayMs: GOOGLE_RETRY_BASE_MS,
408
+ maxDelayMs: GOOGLE_RETRY_MAX_MS,
409
+ headers: res.headers,
410
+ }), ctx.abortSignal);
411
+ } catch (err) {
412
+ if (ctx.abortSignal?.aborted) throw err;
413
+ lastError = err;
414
+ if (antigravityHosts.length > 1 && antigravityHostIndex === 0) {
415
+ antigravityHostIndex = 1;
416
+ activeRequest = requestForHost(activeRequest, antigravityHosts[antigravityHostIndex]!);
417
+ continue;
418
+ }
419
+ if (attempt === GOOGLE_RETRY_ATTEMPTS - 1) throw err;
420
+ await sleepWithAbort(retryBackoffDelayMs(attempt, {
421
+ baseDelayMs: GOOGLE_RETRY_BASE_MS,
422
+ maxDelayMs: GOOGLE_RETRY_MAX_MS,
423
+ }), ctx.abortSignal);
424
+ }
425
+ }
426
+ throw lastError ?? new Error(`${label} fetch failed`);
427
+ }
428
+
429
+ export function fetchGoogleWithRetry(
430
+ label: string,
431
+ request: AdapterRequest,
432
+ ctx: AdapterFetchContext = {},
433
+ opts: GoogleRetryOptions = {},
434
+ ): Promise<Response> {
435
+ return fetchGoogleWithRetryInternal(label, request, ctx, true, opts);
436
+ }
437
+
438
+ /**
439
+ * AI Studio direct (`generativelanguage.googleapis.com`) retry wrapper.
440
+ *
441
+ * Direct requests keep the default server error surface — the raw `Provider error <status>:
442
+ * <body>` text the shared Responses path formats — and keep single-shot 400 semantics (no
443
+ * request-shape compatibility replay). The wrapper exists for the failure mode observed in
444
+ * production: AI Studio's transient `503 UNAVAILABLE` "model is currently experiencing high
445
+ * demand" spikes, plus plain rate-limit 429s, both of which previously failed immediately
446
+ * because the default server fetch path only retries connection resets.
447
+ */
448
+ export function fetchDirectGeminiWithRetry(request: AdapterRequest, ctx: AdapterFetchContext = {}): Promise<Response> {
449
+ return fetchGoogleWithRetry("Gemini", request, { ...ctx, returnRawErrors: true }, { repairInvalid400: false });
450
+ }
451
+
452
+ /** Vertex AI retry wrapper. */
453
+ export function fetchVertexWithRetry(request: AdapterRequest, ctx: AdapterFetchContext = {}): Promise<Response> {
454
+ return fetchGoogleWithRetry("Vertex AI", request, ctx);
455
+ }
456
+
457
+ /** Antigravity (Cloud Code Assist) retry wrapper. */
458
+ export function fetchAntigravityWithRetry(request: AdapterRequest, ctx: AdapterFetchContext = {}): Promise<Response> {
459
+ return fetchGoogleWithRetry("Antigravity", request, ctx);
460
+ }
@@ -0,0 +1,238 @@
1
+ type Schema = Record<string, unknown>;
2
+
3
+ // Google documents this function-schema subset: type, nullable, required, format, description,
4
+ // properties, items, enum, anyOf, $ref, and $defs. We inline local refs and normalize anyOf, so
5
+ // only the eight scalar/container keywords below are ever emitted. Building from an allowlist
6
+ // prevents new MCP/JSON-Schema annotations from turning into provider-wide 400 responses.
7
+ const ALLOWED_TYPES = new Set(["string", "integer", "number", "boolean", "array", "object"]);
8
+ const MAX_SCHEMA_DEPTH = 24; // Google's documented nesting limit is 32; leave headroom for CCA.
9
+ const MAX_DEREF_DEPTH = 16;
10
+ const MAX_SCHEMA_NODES = 1_024;
11
+ const BUDGET_EXHAUSTED = Symbol("schema-budget-exhausted");
12
+ const MERGED_SCHEMA_KEYS = [
13
+ "type",
14
+ "nullable",
15
+ "description",
16
+ "format",
17
+ "enum",
18
+ "const",
19
+ "properties",
20
+ "items",
21
+ "required",
22
+ "anyOf",
23
+ ] as const;
24
+
25
+ type SanitizeResult = Schema | typeof BUDGET_EXHAUSTED;
26
+
27
+ interface SanitizeState {
28
+ activeRefs: Set<string>;
29
+ remainingNodes: number;
30
+ }
31
+
32
+ function isRecord(value: unknown): value is Schema {
33
+ return !!value && typeof value === "object" && !Array.isArray(value);
34
+ }
35
+
36
+ function resolveRef(ref: string, defs: Map<string, unknown>): unknown {
37
+ // Only local pointers into the schema's own $defs/definitions are safe to inline.
38
+ const match = /^#\/(?:\$defs|definitions)\/(.+)$/.exec(ref);
39
+ if (!match) return undefined;
40
+ try {
41
+ return defs.get(decodeURIComponent(match[1].replace(/~1/g, "/").replace(/~0/g, "~")));
42
+ } catch {
43
+ return undefined;
44
+ }
45
+ }
46
+
47
+ function collectDefs(root: unknown, defs: Map<string, unknown>): void {
48
+ if (!isRecord(root)) return;
49
+ for (const bag of ["$defs", "definitions"] as const) {
50
+ const group = root[bag];
51
+ if (!isRecord(group)) continue;
52
+ for (const [name, value] of Object.entries(group)) {
53
+ if (!defs.has(name)) defs.set(name, value);
54
+ }
55
+ }
56
+ }
57
+
58
+ function mergeRefTarget(target: Schema, overlay: Schema): Schema {
59
+ const merged: Schema = {};
60
+ if (Object.hasOwn(target, "$ref")) merged.$ref = target.$ref;
61
+ for (const key of MERGED_SCHEMA_KEYS) {
62
+ if (Object.hasOwn(overlay, key)) merged[key] = overlay[key];
63
+ else if (Object.hasOwn(target, key)) merged[key] = target[key];
64
+ }
65
+ return merged;
66
+ }
67
+
68
+ function normalizeType(value: unknown, out: Schema, preserveNullType: boolean): void {
69
+ const candidates = Array.isArray(value) ? value : [value];
70
+ let sawNull = false;
71
+
72
+ for (const candidate of candidates) {
73
+ if (typeof candidate !== "string") continue;
74
+ const type = candidate.toLowerCase();
75
+ if (type === "null") {
76
+ sawNull = true;
77
+ } else if (out.type === undefined && ALLOWED_TYPES.has(type)) {
78
+ out.type = type;
79
+ }
80
+ }
81
+
82
+ if (!sawNull) return;
83
+ if (out.type !== undefined) out.nullable = true;
84
+ else if (preserveNullType) out.type = "null";
85
+ else out.nullable = true;
86
+ }
87
+
88
+ function sanitizeEnum(value: unknown): string[] | undefined {
89
+ if (!Array.isArray(value)) return undefined;
90
+ const values = [...new Set(value.filter((item): item is string => typeof item === "string"))];
91
+ return values.length > 0 ? values : undefined;
92
+ }
93
+
94
+ function normalizeAnyOf(
95
+ value: unknown,
96
+ defs: Map<string, unknown>,
97
+ depth: number,
98
+ refDepth: number,
99
+ state: SanitizeState,
100
+ ): Schema {
101
+ if (!Array.isArray(value) || value.length === 0) return {};
102
+ const schemas: Schema[] = [];
103
+ for (let index = 0; index < value.length; index++) {
104
+ if (state.remainingNodes <= 0) return {};
105
+ const schema = sanitizeSchema(value[index], defs, depth + 1, refDepth, true, state);
106
+ if (schema === BUDGET_EXHAUSTED) return {};
107
+ schemas.push(schema);
108
+ }
109
+
110
+ const nonNullSchemas = schemas.filter(schema => schema.type !== "null");
111
+ const nullSchemas = schemas.filter(schema => schema.type === "null");
112
+ if (
113
+ nonNullSchemas.length === 1
114
+ && nullSchemas.length > 0
115
+ && nullSchemas.every(schema => Object.keys(schema).every(key => key === "type"))
116
+ ) {
117
+ return { ...nonNullSchemas[0], nullable: true };
118
+ }
119
+
120
+ const type = schemas[0]?.type;
121
+ const sameType = schemas.length > 0 && schemas.every(schema => schema.type === type);
122
+ const enumOnly = schemas.every(schema => {
123
+ const allowedKeys = type === undefined ? new Set(["enum"]) : new Set(["type", "enum"]);
124
+ return Array.isArray(schema.enum) && Object.keys(schema).every(key => allowedKeys.has(key));
125
+ });
126
+ if (sameType && enumOnly && type !== "null") {
127
+ const values = sanitizeEnum(schemas.flatMap(schema => schema.enum as unknown[]));
128
+ if (values) return { ...(typeof type === "string" ? { type } : {}), enum: values };
129
+ }
130
+
131
+ // CCA's Claude bridge turns typed anyOf branches into an invalid input_schema. Widen only this
132
+ // node when a union cannot be collapsed losslessly; parent annotations and structure survive.
133
+ return {};
134
+ }
135
+
136
+ function sanitizeProperties(
137
+ value: unknown,
138
+ defs: Map<string, unknown>,
139
+ depth: number,
140
+ refDepth: number,
141
+ state: SanitizeState,
142
+ ): Record<string, Schema> | undefined {
143
+ if (!isRecord(value)) return undefined;
144
+ const properties: Record<string, Schema> = Object.create(null) as Record<string, Schema>;
145
+ for (const name in value) {
146
+ if (!Object.hasOwn(value, name)) continue;
147
+ if (state.remainingNodes <= 0) break;
148
+ // Property names form a name bag and must never be interpreted as schema keywords.
149
+ const schema = sanitizeSchema(value[name], defs, depth + 1, refDepth, false, state);
150
+ if (schema === BUDGET_EXHAUSTED) break;
151
+ properties[name] = schema;
152
+ }
153
+ return properties;
154
+ }
155
+
156
+ function sanitizeSchema(
157
+ node: unknown,
158
+ defs: Map<string, unknown>,
159
+ depth: number,
160
+ refDepth: number,
161
+ preserveNullType: boolean,
162
+ state: SanitizeState,
163
+ ): SanitizeResult {
164
+ if (state.remainingNodes <= 0) return BUDGET_EXHAUSTED;
165
+ state.remainingNodes -= 1;
166
+ if (depth >= MAX_SCHEMA_DEPTH || !isRecord(node)) return {};
167
+
168
+ if (typeof node.$ref === "string" && refDepth < MAX_DEREF_DEPTH) {
169
+ const target = resolveRef(node.$ref, defs);
170
+ if (isRecord(target)) {
171
+ if (state.activeRefs.has(node.$ref)) return {};
172
+ state.activeRefs.add(node.$ref);
173
+ // Select only inputs the sanitizer can consume. Spreading an untrusted definition here would
174
+ // enumerate and allocate every unsupported annotation before the node budget can stop work.
175
+ const merged = mergeRefTarget(target, node);
176
+ try {
177
+ return sanitizeSchema(merged, defs, depth, refDepth + 1, preserveNullType, state);
178
+ } finally {
179
+ state.activeRefs.delete(node.$ref);
180
+ }
181
+ }
182
+ }
183
+
184
+ const out: Schema = {};
185
+ normalizeType(node.type, out, preserveNullType);
186
+
187
+ if (typeof node.nullable === "boolean") out.nullable = node.nullable;
188
+ if (typeof node.description === "string") out.description = node.description;
189
+ if (typeof node.format === "string") out.format = node.format;
190
+
191
+ const enumValues = sanitizeEnum(node.enum ?? (typeof node.const === "string" ? [node.const] : undefined));
192
+ if (enumValues) out.enum = enumValues;
193
+
194
+ const properties = sanitizeProperties(node.properties, defs, depth, refDepth, state);
195
+ if (properties) out.properties = properties;
196
+
197
+ if (properties && Array.isArray(node.required)) {
198
+ const required = [...new Set(node.required.filter((item): item is string => (
199
+ typeof item === "string" && Object.hasOwn(properties, item)
200
+ )))];
201
+ if (required.length > 0) out.required = required;
202
+ }
203
+
204
+ if (state.remainingNodes <= 0) return out;
205
+
206
+ if (isRecord(node.items)) {
207
+ const items = sanitizeSchema(node.items, defs, depth + 1, refDepth, false, state);
208
+ if (items !== BUDGET_EXHAUSTED) out.items = items;
209
+ }
210
+
211
+ if (state.remainingNodes <= 0) return out;
212
+ if (node.anyOf !== undefined) {
213
+ Object.assign(out, normalizeAnyOf(node.anyOf, defs, depth, refDepth, state));
214
+ }
215
+ return out;
216
+ }
217
+
218
+ export function sanitizeGeminiToolParameters(parameters: unknown): Record<string, unknown> {
219
+ try {
220
+ const defs = new Map<string, unknown>();
221
+ collectDefs(parameters, defs);
222
+ const state: SanitizeState = {
223
+ activeRefs: new Set(),
224
+ remainingNodes: MAX_SCHEMA_NODES,
225
+ };
226
+ const sanitized = sanitizeSchema(parameters, defs, 0, 0, false, state);
227
+ const root = sanitized === BUDGET_EXHAUSTED ? {} : sanitized;
228
+
229
+ // Function arguments are always an object. Claude additionally rejects root composition and a
230
+ // missing root type even when those forms are valid general-purpose JSON Schema.
231
+ root.type = "object";
232
+ if (!isRecord(root.properties)) root.properties = {};
233
+ return root;
234
+ } catch {
235
+ // Last-resort containment: no third-party schema may break every tool in the request.
236
+ return { type: "object", properties: {} };
237
+ }
238
+ }