@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,202 @@
1
+ // Schema-aware repair for tool arguments whose serialized representation disagrees
2
+ // with the declared schema in a way that has exactly one faithful reading.
3
+ //
4
+ // Case 1 — integer fields arriving as integral floats (issue #1611).
5
+ //
6
+ // Grok serializes integer tool-call arguments through a float representation, so
7
+ // `yield_time_ms: 120000` leaves the provider as `120000.0`. Codex declares those
8
+ // fields as Rust integer types, so it rejects the call BEFORE running the tool:
9
+ //
10
+ // failed to parse function arguments: invalid type: floating point `120000.0`, expected u64
11
+ //
12
+ // That is a hard failure, not a degradation — the model gets no result and retries
13
+ // the same float. Nothing on the routed path reconciled argument values against the
14
+ // declared schema, so the `.0` passed straight through.
15
+ //
16
+ // The boundary this file draws is INTENT, not convenience:
17
+ // - an integral float in an integer-typed field is a representation artifact, and
18
+ // `120000.0` has exactly one integer reading, so it is repaired;
19
+ // - `1.5` in an integer field is a genuine disagreement with the schema and is left
20
+ // alone so it still fails, rather than being truncated into a plausible lie.
21
+ //
22
+ // Case 2 — string fields arriving as bare integers (issue #1938).
23
+ //
24
+ // Cursor-served models emit `{"cell_id": 4}` where the schema declares
25
+ // `{"type": "string"}`. Codex rejects the call before the tool runs (invalid type:
26
+ // integer `4`, expected a string), and the model never self-corrects, so every such
27
+ // call is a hard failure loop. A safely-integral JSON number in a string-declared
28
+ // field has exactly one faithful string reading (`4` -> `"4"`), so it is repaired
29
+ // under the same intent boundary:
30
+ // - only when the field declares `string` and no numeric type (a
31
+ // `["integer","string"]` union accepts the number as-is and is left alone);
32
+ // - a non-integral number (`4.5`) in a string field is a genuine disagreement and
33
+ // is left alone so it still fails;
34
+ // - beyond 2^53-1 the parsed value may differ from the serialized text, so the
35
+ // original bytes stay.
36
+ //
37
+ // Anything without a declared `integer`/`string` type is never touched.
38
+
39
+ /** JSON Schema subset we need; provider tool schemas are untrusted input. */
40
+ type SchemaNode = Record<string, unknown>;
41
+
42
+ function asSchema(value: unknown): SchemaNode | undefined {
43
+ return value && typeof value === "object" && !Array.isArray(value)
44
+ ? value as SchemaNode
45
+ : undefined;
46
+ }
47
+
48
+ /** True when the node declares `integer`, including `["integer","null"]` unions. */
49
+ function declaresInteger(schema: SchemaNode): boolean {
50
+ const type = schema.type;
51
+ if (type === "integer") return true;
52
+ return Array.isArray(type) && type.includes("integer");
53
+ }
54
+
55
+ /** True when the node declares `string`, including `["string","null"]` unions. */
56
+ function declaresString(schema: SchemaNode): boolean {
57
+ const type = schema.type;
58
+ if (type === "string") return true;
59
+ return Array.isArray(type) && type.includes("string");
60
+ }
61
+
62
+ /** True when the node accepts a JSON number (`integer` or `number`), so a numeric
63
+ * value is already schema-valid and must not be rewritten into a string. */
64
+ function declaresNumeric(schema: SchemaNode): boolean {
65
+ const type = schema.type;
66
+ if (type === "integer" || type === "number") return true;
67
+ return Array.isArray(type) && (type.includes("integer") || type.includes("number"));
68
+ }
69
+
70
+ /**
71
+ * Resolve a local `$ref` (`#/$defs/Foo`, `#/definitions/Foo`).
72
+ *
73
+ * Only same-document refs are followed: a remote ref is not fetchable here, and a
74
+ * schema we cannot resolve must leave its values untouched rather than guessed at.
75
+ */
76
+ function resolveRef(schema: SchemaNode, root: SchemaNode, seen: Set<string>): SchemaNode | undefined {
77
+ const ref = schema.$ref;
78
+ if (typeof ref !== "string" || !ref.startsWith("#/")) return schema;
79
+ if (seen.has(ref)) return undefined; // cyclic $ref: stop rather than recurse forever
80
+ seen.add(ref);
81
+ let node: unknown = root;
82
+ for (const rawSegment of ref.slice(2).split("/")) {
83
+ const segment = rawSegment.replace(/~1/g, "/").replace(/~0/g, "~");
84
+ const current = asSchema(node);
85
+ if (!current) return undefined;
86
+ node = current[segment];
87
+ }
88
+ const resolved = asSchema(node);
89
+ return resolved ? resolveRef(resolved, root, seen) : undefined;
90
+ }
91
+
92
+ /** Composition keywords whose branches may carry the integer declaration. */
93
+ const COMPOSITION_KEYS = ["anyOf", "oneOf", "allOf"] as const;
94
+
95
+ function compositionBranches(schema: SchemaNode): SchemaNode[] {
96
+ const branches: SchemaNode[] = [];
97
+ for (const key of COMPOSITION_KEYS) {
98
+ const value = schema[key];
99
+ if (!Array.isArray(value)) continue;
100
+ for (const branch of value) {
101
+ const node = asSchema(branch);
102
+ if (node) branches.push(node);
103
+ }
104
+ }
105
+ return branches;
106
+ }
107
+
108
+ /**
109
+ * A JS number can only represent integers exactly up to 2^53-1. Beyond that a
110
+ * rewrite would emit a silently different value, so the original text stays.
111
+ */
112
+ function safelyIntegral(value: number): boolean {
113
+ return Number.isInteger(value) && Math.abs(value) <= Number.MAX_SAFE_INTEGER;
114
+ }
115
+
116
+ interface CoerceResult {
117
+ value: unknown;
118
+ changed: boolean;
119
+ }
120
+
121
+ function coerceValue(value: unknown, schema: SchemaNode | undefined, root: SchemaNode, depth: number): CoerceResult {
122
+ // A hostile or deeply nested schema must not blow the stack.
123
+ if (depth > 64) return { value, changed: false };
124
+ const resolved = schema ? resolveRef(schema, root, new Set()) : undefined;
125
+
126
+ if (typeof value === "number") {
127
+ if (!resolved) return { value, changed: false };
128
+ const branches = compositionBranches(resolved);
129
+ const integerDeclared = declaresInteger(resolved) || branches.some(declaresInteger);
130
+ if (!integerDeclared && safelyIntegral(value)) {
131
+ // Issue #1938: a bare integer in a string-only field has exactly one faithful
132
+ // string reading. A field that also accepts a numeric type keeps the number.
133
+ const stringDeclared = declaresString(resolved) || branches.some(declaresString);
134
+ const numericDeclared = declaresNumeric(resolved) || branches.some(declaresNumeric);
135
+ if (stringDeclared && !numericDeclared) {
136
+ return { value: String(value), changed: true };
137
+ }
138
+ }
139
+ // Not an integer field, already an integer, non-integral, or unrepresentable:
140
+ // in every one of those cases the received value is the right thing to keep.
141
+ if (!integerDeclared || !safelyIntegral(value)) return { value, changed: false };
142
+ // `120000.0` and `120000` are the same JS number; the difference is only in the
143
+ // serialized text, which is repaired by re-stringifying the parsed value.
144
+ return { value, changed: true };
145
+ }
146
+
147
+ if (Array.isArray(value)) {
148
+ const itemSchema = resolved ? asSchema(resolved.items) : undefined;
149
+ let changed = false;
150
+ const next = value.map(entry => {
151
+ const result = coerceValue(entry, itemSchema, root, depth + 1);
152
+ if (result.changed) changed = true;
153
+ return result.value;
154
+ });
155
+ return changed ? { value: next, changed } : { value, changed: false };
156
+ }
157
+
158
+ const object = asSchema(value);
159
+ if (!object) return { value, changed: false };
160
+
161
+ const properties = resolved ? asSchema(resolved.properties) : undefined;
162
+ const additional = resolved ? asSchema(resolved.additionalProperties) : undefined;
163
+ let changed = false;
164
+ const next: Record<string, unknown> = {};
165
+ for (const [key, entry] of Object.entries(object)) {
166
+ const childSchema = asSchema(properties?.[key]) ?? additional;
167
+ const result = coerceValue(entry, childSchema, root, depth + 1);
168
+ if (result.changed) changed = true;
169
+ next[key] = result.value;
170
+ }
171
+ return changed ? { value: next, changed } : { value, changed: false };
172
+ }
173
+
174
+ /**
175
+ * Repair integral floats in a tool-call arguments STRING against the tool's declared
176
+ * parameter schema.
177
+ *
178
+ * Returns the original string unchanged when there is no schema, the payload does not
179
+ * parse, or nothing needed repair — so an unaffected call keeps its exact bytes and
180
+ * this stays a no-op for every provider that already emits real integers.
181
+ */
182
+ export function coerceIntegerToolArguments(
183
+ args: string,
184
+ parameters: Record<string, unknown> | undefined,
185
+ ): string {
186
+ if (!parameters || !args) return args;
187
+ // Cheap reject: a payload with no digit cannot need either repair (integral-float
188
+ // -> integer, or bare-integer -> string).
189
+ if (!/\d/.test(args)) return args;
190
+ let parsed: unknown;
191
+ try {
192
+ parsed = JSON.parse(args);
193
+ } catch {
194
+ // Malformed or still-streaming arguments are not this function's problem; the
195
+ // existing paths already handle them.
196
+ return args;
197
+ }
198
+ const root = parameters as SchemaNode;
199
+ const result = coerceValue(parsed, root, root, 0);
200
+ if (!result.changed) return args;
201
+ return JSON.stringify(result.value);
202
+ }
@@ -0,0 +1,400 @@
1
+ export const TRANSLATOR_MAX_CALL_ARGUMENT_BYTES = 2 * 1024 * 1024;
2
+ export const TRANSLATOR_MAX_TURN_BYTES = 32 * 1024 * 1024;
3
+ export const TRANSLATOR_MAX_SSE_EVENT_BYTES = 32 * 1024 * 1024;
4
+ export const CURSOR_MAX_CONNECT_FRAME_BYTES = 32 * 1024 * 1024;
5
+ export const CURSOR_MAX_EFFECTIVE_CONNECT_PAYLOAD_BYTES = 16 * 1024 * 1024;
6
+ export const CURSOR_TRANSPORT_MAX_BUFFERED_BYTES = 32 * 1024 * 1024;
7
+ export const CURSOR_TRANSPORT_RESUME_BYTES = 16 * 1024 * 1024;
8
+ export const CURSOR_MAX_PENDING_FRAMES = 1024;
9
+ export const CURSOR_PENDING_FRAMES_RESUME = 512;
10
+ export const MAX_PENDING_IMAGE_FULFILLMENTS = 64;
11
+ export const MAX_PENDING_OAUTH_MUTATIONS = 128;
12
+
13
+ export type TranslatorBufferKind =
14
+ | "tool_args"
15
+ | "retained_collectors"
16
+ | "live_transient"
17
+ | "reasoning"
18
+ | "item_ids"
19
+ | "tool_search_sources"
20
+ | "cursor_transport"
21
+ | "cursor_kv"
22
+ | "request_copies";
23
+
24
+ export type ExternallyCappedKind = "passthrough_serialization" | "mcp_payload";
25
+
26
+ export class TranslatorBudgetExceededError extends Error {
27
+ readonly code = "translation_buffer_limit";
28
+
29
+ constructor(readonly kind: TranslatorBufferKind, readonly limitBytes: number) {
30
+ super(`translator ${kind} buffer exceeded ${limitBytes} bytes`);
31
+ this.name = "TranslatorBudgetExceededError";
32
+ }
33
+ }
34
+
35
+ export function isTranslatorBudgetExceededError(error: unknown): error is TranslatorBudgetExceededError {
36
+ return error instanceof TranslatorBudgetExceededError
37
+ || (error instanceof Error && (error as { code?: unknown }).code === "translation_buffer_limit");
38
+ }
39
+
40
+ export interface TranslatorBudgetSnapshot {
41
+ currentBytes: number;
42
+ highWaterBytes: number;
43
+ activeCalls: number;
44
+ overflows: number;
45
+ }
46
+
47
+ export interface TranslatorBudgetOptions {
48
+ maxCallArgumentBytes?: number;
49
+ maxTurnBytes?: number;
50
+ }
51
+
52
+ export interface TranslatorTransientReservation {
53
+ commitRetained(): void;
54
+ release(): void;
55
+ }
56
+
57
+ export interface TranslatorBudget {
58
+ openCall(id: string): void;
59
+ closeCall(id: string): void;
60
+ reserveTransient(
61
+ bytes: number,
62
+ scope: { kind: TranslatorBufferKind; callId?: string },
63
+ ): TranslatorTransientReservation;
64
+ chargeRetained(delta: number, scope: { kind: TranslatorBufferKind; callId?: string }): void;
65
+ releaseRetained(bytes: number, scope: { kind: TranslatorBufferKind; callId?: string }): void;
66
+ observeAcceptedRequestCopy(bytes: number): () => void;
67
+ observeExternallyCapped(kind: ExternallyCappedKind, bytes: number): () => void;
68
+ snapshot(): TranslatorBudgetSnapshot;
69
+ dispose(): void;
70
+ }
71
+
72
+ const retainedEventOwnership = new WeakMap<object, { budget: TranslatorBudget; bytes: number }>();
73
+
74
+ /**
75
+ * Charge one event appended to an incrementally materialized adapter-event batch.
76
+ * The newest event owns the closing array bracket; moving that byte from the old
77
+ * tail keeps in-order release accounting equal to the still-retained JSON array.
78
+ */
79
+ export function retainTranslatedEvent<T extends object>(
80
+ event: T,
81
+ budget: TranslatorBudget,
82
+ previousTail?: object,
83
+ ): void {
84
+ if (retainedEventOwnership.has(event)) {
85
+ throw new Error("translated event is already retained");
86
+ }
87
+ if (previousTail === event) {
88
+ throw new Error("incremental translated event tail must be a distinct object");
89
+ }
90
+ const previousOwnership = previousTail === undefined
91
+ ? undefined
92
+ : retainedEventOwnership.get(previousTail);
93
+ if (
94
+ previousTail !== undefined
95
+ && (!previousOwnership || previousOwnership.budget !== budget || previousOwnership.bytes < 2)
96
+ ) {
97
+ throw new Error("incremental translated event tail is not retained by this budget");
98
+ }
99
+
100
+ const serializedBytes = Buffer.byteLength(JSON.stringify(event));
101
+ budget.chargeRetained(serializedBytes + (previousTail === undefined ? 2 : 1), {
102
+ kind: "retained_collectors",
103
+ });
104
+ if (previousOwnership) previousOwnership.bytes -= 1;
105
+ retainedEventOwnership.set(event, { budget, bytes: serializedBytes + 2 });
106
+ }
107
+
108
+ /**
109
+ * Charge a materialized adapter-event batch and attach its lease to the events themselves.
110
+ * A copied event array (for example terminal-guard collection) preserves the event objects, so
111
+ * the response builder can consume each source lease immediately after its replacement lands.
112
+ */
113
+ export function retainTranslatedEventBatch<T extends object>(events: T[], budget: TranslatorBudget): void {
114
+ if (events.length === 0) return;
115
+ const serialized = events.map(event => JSON.stringify(event));
116
+ const totalBytes = Buffer.byteLength(`[${serialized.join(",")}]`);
117
+ budget.chargeRetained(totalBytes, { kind: "retained_collectors" });
118
+ for (let index = 0; index < events.length; index++) {
119
+ const delimiterBytes = index === events.length - 1 ? 2 : 1;
120
+ retainedEventOwnership.set(events[index]!, {
121
+ budget,
122
+ bytes: Buffer.byteLength(serialized[index]!) + delimiterBytes,
123
+ });
124
+ }
125
+ }
126
+
127
+ /** Transfer one charged adapter event to the response builder's newly materialized owner. */
128
+ export function releaseTranslatedEvent(event: object, budget: TranslatorBudget): void {
129
+ const ownership = retainedEventOwnership.get(event);
130
+ if (!ownership || ownership.budget !== budget) return;
131
+ retainedEventOwnership.delete(event);
132
+ budget.releaseRetained(ownership.bytes, { kind: "retained_collectors" });
133
+ }
134
+
135
+ const liveBudgets = new Set<Budget>();
136
+ let aggregateCurrentBytes = 0;
137
+ let aggregateActiveCalls = 0;
138
+ let aggregateHighWaterBytes = 0;
139
+ let aggregateOverflows = 0;
140
+
141
+ function normalizeBytes(bytes: number): number {
142
+ return Number.isFinite(bytes) && bytes > 0 ? Math.floor(bytes) : 0;
143
+ }
144
+
145
+ function observeAggregate(): void {
146
+ aggregateHighWaterBytes = Math.max(aggregateHighWaterBytes, aggregateCurrentBytes);
147
+ }
148
+
149
+ class Budget implements TranslatorBudget {
150
+ private readonly calls = new Map<string, { logicalBytes: number; physicalBytes: number }>();
151
+ private readonly charged = new Map<TranslatorBufferKind, number>();
152
+ private hardChargedBytes = 0;
153
+ private observedBytes = 0;
154
+ private currentBytes = 0;
155
+ private highWaterBytes = 0;
156
+ private overflowCount = 0;
157
+ private disposed = false;
158
+
159
+ constructor(
160
+ private readonly maxCallArgumentBytes: number,
161
+ private readonly maxTurnBytes: number,
162
+ ) {}
163
+
164
+ private chargedBytes(): number {
165
+ return this.hardChargedBytes;
166
+ }
167
+
168
+ observedCurrentBytes(): number {
169
+ return this.currentBytes;
170
+ }
171
+
172
+ private changed(): void {
173
+ const nextBytes = this.hardChargedBytes + this.observedBytes;
174
+ aggregateCurrentBytes += nextBytes - this.currentBytes;
175
+ this.currentBytes = nextBytes;
176
+ this.highWaterBytes = Math.max(this.highWaterBytes, nextBytes);
177
+ observeAggregate();
178
+ }
179
+
180
+ private reject(kind: TranslatorBufferKind, limitBytes: number): never {
181
+ this.overflowCount += 1;
182
+ aggregateOverflows += 1;
183
+ throw new TranslatorBudgetExceededError(kind, limitBytes);
184
+ }
185
+
186
+ private admit(kind: TranslatorBufferKind, bytes: number): number {
187
+ const admitted = normalizeBytes(bytes);
188
+ if (this.chargedBytes() + admitted > this.maxTurnBytes) this.reject(kind, this.maxTurnBytes);
189
+ return admitted;
190
+ }
191
+
192
+ openCall(id: string): void {
193
+ if (!this.calls.has(id)) {
194
+ this.calls.set(id, { logicalBytes: 0, physicalBytes: 0 });
195
+ aggregateActiveCalls += 1;
196
+ }
197
+ }
198
+
199
+ closeCall(id: string): void {
200
+ const call = this.calls.get(id);
201
+ if (!call) return;
202
+ this.hardChargedBytes = Math.max(0, this.hardChargedBytes - call.physicalBytes);
203
+ this.calls.delete(id);
204
+ aggregateActiveCalls = Math.max(0, aggregateActiveCalls - 1);
205
+ this.changed();
206
+ }
207
+
208
+ reserveTransient(
209
+ bytes: number,
210
+ scope: { kind: TranslatorBufferKind; callId?: string },
211
+ ): TranslatorTransientReservation {
212
+ const admitted = normalizeBytes(bytes);
213
+ if (scope.callId && admitted > this.maxCallArgumentBytes) {
214
+ this.reject("tool_args", this.maxCallArgumentBytes);
215
+ }
216
+ this.admit(scope.kind, admitted);
217
+ this.charged.set(scope.kind, (this.charged.get(scope.kind) ?? 0) + admitted);
218
+ this.hardChargedBytes += admitted;
219
+ this.changed();
220
+ let state: "reserved" | "committed" | "released" = "reserved";
221
+ return {
222
+ commitRetained: () => {
223
+ if (state !== "reserved") return;
224
+ state = "committed";
225
+ if (!scope.callId) return;
226
+ const call = this.calls.get(scope.callId) ?? { logicalBytes: 0, physicalBytes: 0 };
227
+ this.charged.set(scope.kind, Math.max(0, (this.charged.get(scope.kind) ?? 0) - admitted));
228
+ call.logicalBytes = admitted;
229
+ call.physicalBytes += admitted;
230
+ this.calls.set(scope.callId, call);
231
+ this.changed();
232
+ },
233
+ release: () => {
234
+ if (state !== "reserved") return;
235
+ state = "released";
236
+ this.charged.set(scope.kind, Math.max(0, (this.charged.get(scope.kind) ?? 0) - admitted));
237
+ this.hardChargedBytes = Math.max(0, this.hardChargedBytes - admitted);
238
+ this.changed();
239
+ },
240
+ };
241
+ }
242
+
243
+ chargeRetained(delta: number, scope: { kind: TranslatorBufferKind; callId?: string }): void {
244
+ const admitted = normalizeBytes(delta);
245
+ if (scope.callId) {
246
+ const call = this.calls.get(scope.callId) ?? { logicalBytes: 0, physicalBytes: 0 };
247
+ if (call.logicalBytes + admitted > this.maxCallArgumentBytes) {
248
+ this.reject("tool_args", this.maxCallArgumentBytes);
249
+ }
250
+ this.admit(scope.kind, admitted);
251
+ call.logicalBytes += admitted;
252
+ call.physicalBytes += admitted;
253
+ this.calls.set(scope.callId, call);
254
+ } else {
255
+ this.admit(scope.kind, admitted);
256
+ this.charged.set(scope.kind, (this.charged.get(scope.kind) ?? 0) + admitted);
257
+ }
258
+ this.hardChargedBytes += admitted;
259
+ this.changed();
260
+ }
261
+
262
+ releaseRetained(bytes: number, scope: { kind: TranslatorBufferKind; callId?: string }): void {
263
+ const released = normalizeBytes(bytes);
264
+ if (scope.callId) {
265
+ const call = this.calls.get(scope.callId);
266
+ if (call) {
267
+ const actual = Math.min(released, call.physicalBytes);
268
+ call.physicalBytes -= actual;
269
+ this.hardChargedBytes = Math.max(0, this.hardChargedBytes - actual);
270
+ }
271
+ } else {
272
+ const current = this.charged.get(scope.kind) ?? 0;
273
+ const actual = Math.min(released, current);
274
+ this.charged.set(scope.kind, current - actual);
275
+ this.hardChargedBytes = Math.max(0, this.hardChargedBytes - actual);
276
+ }
277
+ this.changed();
278
+ }
279
+
280
+ private observe(bytes: number): () => void {
281
+ const observed = normalizeBytes(bytes);
282
+ this.observedBytes += observed;
283
+ this.changed();
284
+ let released = false;
285
+ return () => {
286
+ if (released) return;
287
+ released = true;
288
+ this.observedBytes = Math.max(0, this.observedBytes - observed);
289
+ this.changed();
290
+ };
291
+ }
292
+
293
+ observeAcceptedRequestCopy(bytes: number): () => void {
294
+ return this.observe(bytes);
295
+ }
296
+
297
+ observeExternallyCapped(_kind: ExternallyCappedKind, bytes: number): () => void {
298
+ return this.observe(bytes);
299
+ }
300
+
301
+ snapshot(): TranslatorBudgetSnapshot {
302
+ return {
303
+ currentBytes: this.observedCurrentBytes(),
304
+ highWaterBytes: this.highWaterBytes,
305
+ activeCalls: this.calls.size,
306
+ overflows: this.overflowCount,
307
+ };
308
+ }
309
+
310
+ dispose(): void {
311
+ if (this.disposed) return;
312
+ this.disposed = true;
313
+ aggregateActiveCalls = Math.max(0, aggregateActiveCalls - this.calls.size);
314
+ aggregateCurrentBytes = Math.max(0, aggregateCurrentBytes - this.currentBytes);
315
+ this.calls.clear();
316
+ this.charged.clear();
317
+ this.hardChargedBytes = 0;
318
+ this.observedBytes = 0;
319
+ this.currentBytes = 0;
320
+ liveBudgets.delete(this);
321
+ observeAggregate();
322
+ }
323
+ }
324
+
325
+ export function createTranslatorBudget(options: TranslatorBudgetOptions = {}): TranslatorBudget {
326
+ const budget = new Budget(
327
+ options.maxCallArgumentBytes ?? TRANSLATOR_MAX_CALL_ARGUMENT_BYTES,
328
+ options.maxTurnBytes ?? TRANSLATOR_MAX_TURN_BYTES,
329
+ );
330
+ liveBudgets.add(budget);
331
+ observeAggregate();
332
+ return budget;
333
+ }
334
+
335
+ export function translatorObservedBufferSnapshot(): {
336
+ currentBytes: number;
337
+ highWaterBytes: number;
338
+ active: number;
339
+ } {
340
+ return {
341
+ currentBytes: aggregateCurrentBytes,
342
+ highWaterBytes: aggregateHighWaterBytes,
343
+ active: aggregateActiveCalls,
344
+ };
345
+ }
346
+
347
+ /** Internal diagnostics used by focused tests; never registered with app-owned memory. */
348
+ export function translatorObservedOverflowCount(): number {
349
+ return aggregateOverflows;
350
+ }
351
+
352
+ /** Test-only: proves owned default budgets are disposed on every stream-death path. */
353
+ export function translatorLiveBudgetCountForTests(): number {
354
+ return liveBudgets.size;
355
+ }
356
+
357
+ /** Test-only: proves no charge survives against a disposed budget (cancel race). */
358
+ export function translatorAggregateCurrentBytesForTests(): number {
359
+ return aggregateCurrentBytes;
360
+ }
361
+
362
+ /** Clears process-wide translator diagnostics and disposes leaked test budgets. */
363
+ export function resetTranslatorAggregateForTests(): void {
364
+ for (const budget of liveBudgets) budget.dispose();
365
+ aggregateCurrentBytes = 0;
366
+ aggregateActiveCalls = 0;
367
+ aggregateHighWaterBytes = 0;
368
+ aggregateOverflows = 0;
369
+ }
370
+
371
+ export function finalizeTranslatorBudgetResponse(response: Response, budget: TranslatorBudget): Response {
372
+ if (!response.body) {
373
+ budget.dispose();
374
+ return response;
375
+ }
376
+ const reader = response.body.getReader();
377
+ let finalized = false;
378
+ const finalize = () => {
379
+ if (finalized) return;
380
+ finalized = true;
381
+ budget.dispose();
382
+ };
383
+ return new Response(new ReadableStream<Uint8Array>({
384
+ async pull(controller) {
385
+ try {
386
+ const result = await reader.read();
387
+ if (result.done) {
388
+ finalize();
389
+ controller.close();
390
+ } else controller.enqueue(result.value);
391
+ } catch (error) {
392
+ finalize();
393
+ controller.error(error);
394
+ }
395
+ },
396
+ async cancel(reason) {
397
+ try { await reader.cancel(reason); } finally { finalize(); }
398
+ },
399
+ }), { status: response.status, statusText: response.statusText, headers: response.headers });
400
+ }
@@ -0,0 +1,57 @@
1
+ import type { OcxProviderConfig, UpstreamHttpVersion } from "../types";
2
+
3
+ /** True when a provider explicitly selected the HTTP/1.1 compatibility path. */
4
+ export function isPinnedHttp1(version: UpstreamHttpVersion | undefined): boolean {
5
+ return version === "http1.1" || version === "h1";
6
+ }
7
+
8
+ /**
9
+ * Bun's fetch accepts a non-standard `protocol` init to pin the HTTP version
10
+ * (BunFetchRequestInit.protocol). The DOM lib types do not include it, so the
11
+ * value is represented through a RequestInit cast at this shared boundary.
12
+ */
13
+ const UPSTREAM_HTTP_VERSION_PROTOCOL: Record<Exclude<UpstreamHttpVersion, "auto">, string> = {
14
+ "http1.1": "http1.1",
15
+ h1: "h1",
16
+ http2: "http2",
17
+ h2: "h2",
18
+ };
19
+
20
+ /** Raised before I/O when a fixed Bun HTTP-version pin cannot apply to the target URL. */
21
+ export class UpstreamHttpVersionTargetError extends Error {
22
+ readonly code = "upstream_http_version_target";
23
+
24
+ constructor(readonly observedProtocol: string) {
25
+ super(`upstream HTTP version pin requires an HTTPS target (received ${observedProtocol})`);
26
+ this.name = "UpstreamHttpVersionTargetError";
27
+ }
28
+ }
29
+
30
+ /** Attach Bun's `protocol` pin for one explicit version value. */
31
+ export function withUpstreamHttpVersionValue(
32
+ input: Parameters<typeof globalThis.fetch>[0],
33
+ init: RequestInit | undefined,
34
+ version: UpstreamHttpVersion | undefined,
35
+ ): RequestInit | undefined {
36
+ if (!version || version === "auto") return init;
37
+ // Bun's protocol pin requires an https: target. An explicit fixed-version request must fail
38
+ // locally when the pin cannot be honored instead of silently negotiating another transport.
39
+ const target = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
40
+ let targetUrl: URL;
41
+ try {
42
+ targetUrl = new URL(target);
43
+ } catch {
44
+ throw new UpstreamHttpVersionTargetError("unparseable");
45
+ }
46
+ if (targetUrl.protocol !== "https:") throw new UpstreamHttpVersionTargetError(targetUrl.protocol);
47
+ return { ...(init ?? {}), protocol: UPSTREAM_HTTP_VERSION_PROTOCOL[version] } as RequestInit;
48
+ }
49
+
50
+ /** Attach Bun's `protocol` pin when the provider opted into a fixed HTTP version. */
51
+ export function withUpstreamHttpVersion(
52
+ input: Parameters<typeof globalThis.fetch>[0],
53
+ init: RequestInit | undefined,
54
+ provider: Pick<OcxProviderConfig, "upstreamHttpVersion">,
55
+ ): RequestInit | undefined {
56
+ return withUpstreamHttpVersionValue(input, init, provider.upstreamHttpVersion);
57
+ }