@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,650 @@
1
+ import { execFileSync } from "node:child_process";
2
+ import { createHash } from "node:crypto";
3
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, realpathSync } from "node:fs";
4
+ import { delimiter, dirname, join, resolve } from "node:path";
5
+ import { atomicWriteFile, expandUserPath, getConfigDir, websocketsEnabled } from "../../config";
6
+ import { CODEX_CONFIG_PATH, CODEX_MODELS_CACHE_PATH, DEFAULT_CATALOG_PATH, readRootTomlString, resolveCodexConfigPath } from "../paths";
7
+ import { clearModelCache, DEFAULT_MODEL_CACHE_TTL_MS, getFreshCached, getStaleCached, isModelsFetchCoolingDown, markModelsFetchFailure, setCached } from "../model-cache";
8
+ import { buildModelsRequest, resolveModelsAuthToken } from "../../oauth";
9
+ import type { OcxConfig, OcxProviderConfig } from "../../types";
10
+ import { modelInList } from "../../types";
11
+ import { CODEX_REASONING_LEVELS, codexEffortRank, configuredReasoningEfforts, modelRecordValue, sanitizeCodexReasoningEfforts } from "../../reasoning-effort";
12
+ import { getModelMetadata, getModelMetadataCaseInsensitive, listModelMetadata, resolveMetadataProvider } from "../../generated/model-metadata";
13
+ import { enrichProviderFromRegistry, shouldCaseFoldMetadataModelId } from "../../providers/derive";
14
+ import { getProviderRegistryEntry } from "../../providers/registry";
15
+ import { applyProviderContextCap, providerContextCap } from "../../providers/context-cap";
16
+ import { encodeRoutedModelId, routedSlug, slugEquals, slugsEquivalent } from "../../providers/slug-codec";
17
+ import { CODEX_GPT5_IDENTITY_LINE } from "../../adapters/identity";
18
+ import { filterCursorConfiguredModelsByLiveDiscovery } from "../../adapters/cursor/discovery";
19
+ import { fetchCursorUsableModels } from "../../adapters/cursor/live-models";
20
+ import { isCanonicalOpenAiForwardProvider, OPENAI_API_PROVIDER_ID, OPENAI_CODEX_PROVIDER_ID } from "../../providers/openai-tiers";
21
+ import {
22
+ COMBO_NAMESPACE,
23
+ comboModelId,
24
+ getCombo,
25
+ listComboIds,
26
+ targetKey,
27
+ } from "../../combos";
28
+ import type { NormalizedComboConfig } from "../../combos/types";
29
+ import { providerDestinationResolvedError } from "../../lib/destination-policy";
30
+ import { redactSecretString } from "../../lib/redact";
31
+ import upstreamModelsSnapshot from "../data/upstream-models.json";
32
+
33
+
34
+ import { NATIVE_OPENAI_CONTEXT_OVERRIDES, SUPPORTED_NATIVE_OPENAI_SLUGS, UPSTREAM_NATIVE_ENTRIES, isNativeOpenAiCapabilityAliasModel, nativeMultiAgentVersion, nativeOpenAiContextWindow, nativeOpenAiMaxInputTokens, type NativeContextLimitsInput } from "./metadata";
35
+ import { trustedAccountBoundNativeCatalogSlug } from "./account-models";
36
+ import { CODEX_NATIVE_ALIAS_CATALOG_KIND } from "./kinds";
37
+
38
+ export function legacyCatalogBackupPath(): string {
39
+ return join(getConfigDir(), "catalog-backup.json");
40
+ }
41
+
42
+ export function catalogBackupPathFor(catalogPath: string): string {
43
+ const normalized = process.platform === "win32" ? resolve(catalogPath).toLowerCase() : resolve(catalogPath);
44
+ const id = createHash("sha256").update(normalized).digest("hex").slice(0, 16);
45
+ return join(getConfigDir(), `catalog-backup-${id}.json`);
46
+ }
47
+
48
+ export function samePath(a: string, b: string): boolean {
49
+ const left = resolve(a);
50
+ const right = resolve(b);
51
+ return process.platform === "win32" ? left.toLowerCase() === right.toLowerCase() : left === right;
52
+ }
53
+
54
+ export function activeCodexHome(): string | null {
55
+ const raw = process.env.CODEX_HOME?.trim();
56
+ if (!raw) return null;
57
+ const path = resolve(expandUserPath(raw));
58
+ try {
59
+ return realpathSync.native(path);
60
+ } catch {
61
+ return path;
62
+ }
63
+ }
64
+
65
+ export function activeCodexConfigPath(): string {
66
+ const home = activeCodexHome();
67
+ return home ? join(home, "config.toml") : CODEX_CONFIG_PATH;
68
+ }
69
+
70
+ export function activeDefaultCatalogPath(): string {
71
+ const home = activeCodexHome();
72
+ return home ? join(home, "opencodex-catalog.json") : DEFAULT_CATALOG_PATH;
73
+ }
74
+
75
+ export function activeCodexModelsCachePath(): string {
76
+ const home = activeCodexHome();
77
+ return home ? join(home, "models_cache.json") : CODEX_MODELS_CACHE_PATH;
78
+ }
79
+
80
+ export function resolveActiveCodexConfigPath(path: string): string {
81
+ const home = activeCodexHome();
82
+ return home ? resolve(home, path) : resolveCodexConfigPath(path);
83
+ }
84
+
85
+ export function isDefaultCatalogPath(path: string): boolean {
86
+ return samePath(path, activeDefaultCatalogPath());
87
+ }
88
+
89
+ /** Stable nonsemantic ownership marker for rows projected from config.customModels. */
90
+ export const CODEX_CUSTOM_MODEL_CATALOG_KIND = "custom-model-v1";
91
+ /** A formerly ambiguous slug was authoritatively observed as an ordinary provider row. */
92
+ export const CODEX_PROVIDER_MODEL_CATALOG_KIND = "provider-model-v1";
93
+
94
+ export interface CatalogModel {
95
+ id: string;
96
+ provider: string;
97
+ /** Public Codex-facing slug override (used by combo aliases). */
98
+ alias?: string;
99
+ /** Explicit combo takeover of a bare OpenAI-native catalog id. */
100
+ nativeAlias?: boolean;
101
+ /**
102
+ * Display-only Codex catalog `display_name` override. Relabels the picker row ONLY — it never
103
+ * affects the routing slug, alias-collision order, native marketing-name precedence, or provider
104
+ * behavior. When unset, the entry falls back to its Codex-facing slug (the historical behavior).
105
+ * Native upstream entries (e.g. gpt-5.6-sol → "GPT-5.6-Sol") come from the pinned snapshot path
106
+ * which carries no CatalogModel, so a configured displayName can never override a native name.
107
+ */
108
+ displayName?: string;
109
+ owned_by?: string;
110
+ reasoningEfforts?: string[];
111
+ defaultReasoningEffort?: string;
112
+ contextWindow?: number;
113
+ maxInputTokens?: number;
114
+ contextCap?: number;
115
+ contextCapped?: boolean;
116
+ inputModalities?: string[];
117
+ /** Provider opted into parallel tool calls (OcxProviderConfig.parallelToolCalls). */
118
+ parallelToolCalls?: boolean;
119
+ /**
120
+ * This routed row is an explicitly configured account-native alias on the canonical ChatGPT
121
+ * forward provider. It may inherit pinned native Codex metadata without changing its wire id.
122
+ */
123
+ codexForwardNativeCapabilityAlias?: boolean;
124
+ /** Whether Codex may send Responses text.verbosity for this routed model. */
125
+ supportsVerbosity?: boolean;
126
+ /** Whether this exact routed model has a verified OpenAI-compatible service tier. */
127
+ supportsServiceTier?: boolean;
128
+ /** Optional provider-specific copy for the advertised Fast tier. */
129
+ fastTierDescription?: string;
130
+ supportsReasoningSummaries?: boolean;
131
+ /**
132
+ * Codex tool calling mode for this routed model.
133
+ * "code_mode_only" (default) sets entry.tool_mode = "code_mode_only".
134
+ * "shell" leaves tool_mode unset so Codex declares top-level shell tools (exec_command).
135
+ */
136
+ codexToolMode?: "code_mode_only" | "shell";
137
+ /** Normalized upstream capability names retained for management/API consumers (#485 follow-up). */
138
+ capabilities?: string[];
139
+ /** OpenCodex-only catalog ownership marker; Codex ignores the serialized extension field. */
140
+ catalogKind?: typeof CODEX_CUSTOM_MODEL_CATALOG_KIND | typeof CODEX_PROVIDER_MODEL_CATALOG_KIND;
141
+ }
142
+
143
+ export type RawEntry = Record<string, unknown>;
144
+
145
+ export type RawCatalog = { models?: RawEntry[]; [k: string]: unknown };
146
+
147
+ export const JAWCODE_CATALOG_AUGMENT_PROVIDERS = new Set(["opencode-go", "deepseek"]);
148
+
149
+ export const ROUTED_MODEL_COMPATIBILITY_EXCLUSIONS = new Set([
150
+ // Issue #82: Zen Go /models advertises HY3, but Console Go rejects it as outside the lite list.
151
+ "opencode-go/hy3-preview",
152
+ ]);
153
+
154
+ export function isRoutedModelCompatibilityExcluded(slug: string): boolean {
155
+ return ROUTED_MODEL_COMPATIBILITY_EXCLUSIONS.has(slug);
156
+ }
157
+
158
+ export const MEDIA_GEN_FAMILIES = [
159
+ "dall-e", "dalle", "imagen", "sora", "veo", "flux", "kling",
160
+ "seedance", "hailuo", "stable-diffusion", "sdxl", "midjourney",
161
+ ];
162
+
163
+ export const MEDIA_GEN_ID_RE = new RegExp(
164
+ `(?:^|[/_-])(?:image|video)(?:[/_-]|$)|(?:^|[/_-])(?:${MEDIA_GEN_FAMILIES.join("|")})(?:[/_-]|$|\\d)`,
165
+ "i",
166
+ );
167
+
168
+ export function isMediaGenerationModelId(id: string): boolean {
169
+ return MEDIA_GEN_ID_RE.test(id);
170
+ }
171
+
172
+ /**
173
+ * Gemini image-capable chat models produce inline images within text responses
174
+ * via the Responses API. Explicit allowlist only — a broad `/gemini/ && /image/`
175
+ * heuristic resurrects standalone media-gen IDs (e.g. gemini-3-pro-image).
176
+ */
177
+ const GEMINI_IMAGE_CHAT_MODEL_IDS = new Set([
178
+ "gemini-3.1-flash-image",
179
+ "gemini-2.0-flash-preview-image-generation",
180
+ "gemini-3-pro-image-preview",
181
+ ]);
182
+
183
+ function isGeminiImageChatModel(id: string): boolean {
184
+ return GEMINI_IMAGE_CHAT_MODEL_IDS.has(id);
185
+ }
186
+
187
+ export function shouldExposeRoutedModel(model: CatalogModel): boolean {
188
+ if (isRoutedModelCompatibilityExcluded(`${model.provider}/${model.id}`)) return false;
189
+ if (isGeminiImageChatModel(model.id)) return true;
190
+ return !isMediaGenerationModelId(model.id);
191
+ }
192
+
193
+ export function readCodexCatalogPath(): string {
194
+ try {
195
+ const configPath = activeCodexConfigPath();
196
+ if (existsSync(configPath)) {
197
+ const toml = readFileSync(configPath, "utf-8");
198
+ const path = readRootTomlString(toml, "model_catalog_json");
199
+ if (path) return resolveActiveCodexConfigPath(path);
200
+ }
201
+ } catch { /* ignore */ }
202
+ return activeDefaultCatalogPath();
203
+ }
204
+
205
+ export function parseCatalogJson(raw: string): RawCatalog | null {
206
+ try {
207
+ const cat = JSON.parse(raw);
208
+ return (cat && Array.isArray(cat.models)) ? cat : null;
209
+ } catch { return null; }
210
+ }
211
+
212
+ export function readCatalog(path: string): RawCatalog | null {
213
+ try {
214
+ if (!existsSync(path)) return null;
215
+ return parseCatalogJson(readFileSync(path, "utf-8"));
216
+ } catch { return null; }
217
+ }
218
+
219
+ export function findNativeTemplate(catalog: RawCatalog | null): RawEntry | null {
220
+ return catalog?.models?.find(
221
+ m => typeof m.slug === "string"
222
+ && !m.slug.includes("/")
223
+ && "base_instructions" in m
224
+ && m.opencodex_catalog_kind !== CODEX_NATIVE_ALIAS_CATALOG_KIND
225
+ && m.owned_by !== COMBO_NAMESPACE
226
+ && !(typeof m.description === "string" && m.description.startsWith("Routed via opencodex → ")),
227
+ ) ?? null;
228
+ }
229
+
230
+ /**
231
+ * Native OpenAI slugs that do NOT support the Fast (priority) service tier.
232
+ * Upstream may advertise service_tiers for these models, but the tier is not
233
+ * actually available — strip it so the Codex UI does not offer a dead toggle.
234
+ */
235
+ const NO_FAST_TIER_NATIVE_SLUGS = new Set([
236
+ "gpt-5.3-codex-spark",
237
+ ]);
238
+
239
+ export function normalizeServiceTiers(entry: RawEntry): RawEntry {
240
+ // Strip service tiers for models that do not actually support the Fast tier.
241
+ if (typeof entry.slug === "string" && NO_FAST_TIER_NATIVE_SLUGS.has(entry.slug)) {
242
+ delete entry.service_tier;
243
+ delete entry.service_tiers;
244
+ delete entry.default_service_tier;
245
+ delete entry.additional_speed_tiers;
246
+ return entry;
247
+ }
248
+ // Codex stores the user-facing config spelling as "fast", but the catalog/request
249
+ // service tier id is "priority" in current codex-rs. Keep legacy catalogs working.
250
+ if (entry.service_tier === "fast") entry.service_tier = "priority";
251
+ if (Array.isArray(entry.service_tiers)) {
252
+ entry.service_tiers = entry.service_tiers.map(tier => {
253
+ if (tier && typeof tier === "object" && "id" in tier && tier.id === "fast") {
254
+ return { ...tier, id: "priority" };
255
+ }
256
+ return tier;
257
+ });
258
+ }
259
+ return entry;
260
+ }
261
+
262
+ export function ensureAutoCompactTokenLimit(entry: RawEntry): RawEntry {
263
+ if (
264
+ typeof entry.context_window === "number"
265
+ && entry.context_window > 0
266
+ && typeof entry.auto_compact_token_limit !== "number"
267
+ ) {
268
+ entry.auto_compact_token_limit = Math.floor(entry.context_window * 0.9);
269
+ }
270
+ return entry;
271
+ }
272
+
273
+ export function isNativeOpenAiEntry(entry: RawEntry): boolean {
274
+ return typeof entry.slug === "string" && !entry.slug.includes("/");
275
+ }
276
+
277
+ /**
278
+ * Auto-compaction threshold for a native row.
279
+ *
280
+ * The usual rule is 90% of the window, but a row whose input ceiling sits below that has to
281
+ * clamp to the ceiling instead — otherwise the client keeps filling until upstream answers
282
+ * `context_length_exceeded` and compaction never gets a chance to run. Native GPT-5.6 no
283
+ * longer trips this (922,000 window, 829,800 at 90%), but the routed and API-key rows carry
284
+ * the same family at a 1,050,000 window where 90% would be 945,000 — past the ceiling.
285
+ */
286
+ function nativeAutoCompactLimit(contextWindow: number, maxInputTokens: number | undefined, contextCap?: number): number {
287
+ const ninety = Math.floor(contextWindow * 0.9);
288
+ if (typeof maxInputTokens !== "number" || maxInputTokens <= 0) return ninety;
289
+ const cappedMaxInput = applyProviderContextCap(maxInputTokens, contextCap) ?? maxInputTokens;
290
+ return Math.min(ninety, cappedMaxInput, contextWindow);
291
+ }
292
+
293
+ /**
294
+ * Narrow any already-resolved native window by the user levers.
295
+ *
296
+ * Used for the fields the accessors do not own (`max_context_window`, and preserved rows
297
+ * that carry no static override) so every field on a row lands at the same width.
298
+ */
299
+ function narrowNativeMaxContextWindow(
300
+ slug: string,
301
+ value: number | undefined,
302
+ limits?: NativeContextLimitsInput,
303
+ ): number | undefined {
304
+ if (typeof value !== "number" || value <= 0) return value;
305
+ const resolved = nativeOpenAiContextWindow(slug, limits);
306
+ const authoritative = nativeOpenAiContextWindow(slug);
307
+ // The accessor pair tells us how far the levers moved this slug; apply the same delta to a
308
+ // field the accessor does not model, without ever raising it.
309
+ if (resolved === undefined || authoritative === undefined) return value;
310
+ return Math.min(value, Math.max(resolved, 1));
311
+ }
312
+
313
+ export function applyNativeOpenAiContextOverride(entry: RawEntry, limits?: NativeContextLimitsInput): void {
314
+ const nativeSlug = trustedAccountBoundNativeCatalogSlug(entry)
315
+ ?? (isNativeOpenAiEntry(entry) ? entry.slug as string : undefined);
316
+ if (!nativeSlug) return;
317
+ const override = NATIVE_OPENAI_CONTEXT_OVERRIDES[nativeSlug];
318
+ if (override) {
319
+ // Read the effective values through the accessors rather than re-deriving them from the
320
+ // static table: this function used to apply only the provider cap, so a per-model window
321
+ // the dashboard had already accepted was silently written back at full width here.
322
+ if (typeof override.contextWindow === "number") {
323
+ const contextWindow = nativeOpenAiContextWindow(nativeSlug, limits) ?? override.contextWindow;
324
+ entry.context_window = contextWindow;
325
+ entry.auto_compact_token_limit = nativeAutoCompactLimit(
326
+ contextWindow,
327
+ nativeOpenAiMaxInputTokens(nativeSlug, limits) ?? override.maxInputTokens,
328
+ undefined,
329
+ );
330
+ }
331
+ if (typeof override.maxContextWindow === "number") {
332
+ const maxContextWindow = narrowNativeMaxContextWindow(nativeSlug, override.maxContextWindow, limits);
333
+ entry.max_context_window = maxContextWindow;
334
+ }
335
+ }
336
+ // providerContextCaps.openai is a ceiling for native OpenAI rows regardless of where the
337
+ // advertised window came from (#1430): preserved rows without a hardcoded override (e.g.
338
+ // gpt-5.4-mini) must stay under the cap too, and auto-compaction follows the capped window.
339
+ // The per-model window narrows the same rows for the same reason.
340
+ const currentContext = typeof entry.context_window === "number" ? entry.context_window : undefined;
341
+ const cappedContext = narrowNativeMaxContextWindow(nativeSlug, currentContext, limits);
342
+ if (cappedContext !== currentContext && typeof cappedContext === "number") {
343
+ entry.context_window = cappedContext;
344
+ entry.auto_compact_token_limit = nativeAutoCompactLimit(
345
+ cappedContext,
346
+ nativeOpenAiMaxInputTokens(nativeSlug, limits) ?? override?.maxInputTokens,
347
+ undefined,
348
+ );
349
+ }
350
+ const currentMax = typeof entry.max_context_window === "number" ? entry.max_context_window : undefined;
351
+ const cappedMax = narrowNativeMaxContextWindow(nativeSlug, currentMax, limits);
352
+ if (cappedMax !== currentMax) {
353
+ entry.max_context_window = cappedMax;
354
+ }
355
+ }
356
+
357
+ export function ensureStrictCatalogFields(
358
+ entry: RawEntry,
359
+ options: { preserveExactInputModalities?: boolean; isRouted?: boolean } = {},
360
+ ): RawEntry {
361
+ if (typeof entry.supports_reasoning_summaries !== "boolean") entry.supports_reasoning_summaries = false;
362
+ if (typeof entry.default_reasoning_summary !== "string") entry.default_reasoning_summary = "none";
363
+ if (typeof entry.support_verbosity !== "boolean") entry.support_verbosity = true;
364
+ if (typeof entry.default_verbosity !== "string") entry.default_verbosity = "low";
365
+ if (typeof entry.apply_patch_tool_type !== "string") entry.apply_patch_tool_type = "freeform";
366
+ if (!entry.truncation_policy || typeof entry.truncation_policy !== "object" || Array.isArray(entry.truncation_policy)) {
367
+ entry.truncation_policy = { mode: "tokens", limit: 10000 };
368
+ }
369
+ if (typeof entry.supports_parallel_tool_calls !== "boolean") entry.supports_parallel_tool_calls = true;
370
+ if (typeof entry.supports_image_detail_original !== "boolean") entry.supports_image_detail_original = false;
371
+ if (!Array.isArray(entry.experimental_supported_tools)) entry.experimental_supported_tools = [];
372
+ if (!Array.isArray(entry.input_modalities) && !options.preserveExactInputModalities) {
373
+ entry.input_modalities = ["text"];
374
+ }
375
+ // Codex parses `input_modalities` as a closed enum. One out-of-enum value (zenmux advertises
376
+ // "video") makes its config loader reject the entire catalog, which takes down plugins, apps and
377
+ // MCP servers — not just that model. Normalize at the single point every entry passes through,
378
+ // because provider metadata, jawcode metadata and effort sync each write this field.
379
+ if (Array.isArray(entry.input_modalities)) {
380
+ const accepted = entry.input_modalities.filter(value =>
381
+ value === "text" || value === "image" || value === "audio");
382
+ // Never leave it empty: an entry with no modality at all is worse than a text-only one.
383
+ entry.input_modalities = accepted.length > 0 ? accepted : ["text"];
384
+ }
385
+ const contextWindow = typeof entry.context_window === "number" && entry.context_window > 0 ? entry.context_window : 128000;
386
+ entry.context_window = contextWindow;
387
+ if (
388
+ typeof entry.max_context_window !== "number"
389
+ || entry.max_context_window <= 0
390
+ || ((options.isRouted === true || !isNativeOpenAiEntry(entry)) && entry.max_context_window > contextWindow)
391
+ ) {
392
+ entry.max_context_window = contextWindow;
393
+ }
394
+ if (typeof entry.effective_context_window_percent !== "number") entry.effective_context_window_percent = 95;
395
+ if (typeof entry.comp_hash !== "string") entry.comp_hash = "opencodex";
396
+ return ensureAutoCompactTokenLimit(entry);
397
+ }
398
+
399
+ export type MultiAgentMode = "v1" | "default" | "v2";
400
+
401
+ export interface MultiAgentModeOptions {
402
+ /**
403
+ * When the catalog is in v2 mode, stamp ChatGPT-native rows as v1 instead.
404
+ * Routed parents get v2 (plaintext child tasks). Native Sol/Terra stay on v1
405
+ * so they can still spawn Grok/Claude — ChatGPT encrypts v2 NEW_TASK bodies.
406
+ */
407
+ keepNativeChatGptOnV1?: boolean;
408
+ }
409
+
410
+ /** Catalog rows that run on the ChatGPT backend (encrypt v2 child tasks). */
411
+ export function catalogEntryIsNativeChatGpt(entry: RawEntry): boolean {
412
+ const slug = typeof entry.slug === "string" ? entry.slug : "";
413
+ // combo-native-alias-v1 occupies a bare native slug but is routed through
414
+ // OpenCodex. Keep those on v2 unless the row still carries the ChatGPT-forward
415
+ // contract (`use_responses_lite`).
416
+ if (entry.opencodex_catalog_kind === CODEX_NATIVE_ALIAS_CATALOG_KIND) {
417
+ return entry.use_responses_lite === true;
418
+ }
419
+ if (trustedAccountBoundNativeCatalogSlug(entry)) return true;
420
+ const routedNativeSlug = slug.startsWith(`${OPENAI_CODEX_PROVIDER_ID}/`)
421
+ ? slug.slice(OPENAI_CODEX_PROVIDER_ID.length + 1)
422
+ : "";
423
+ if (
424
+ entry.opencodex_catalog_kind === CODEX_CUSTOM_MODEL_CATALOG_KIND
425
+ && entry.use_responses_lite === true
426
+ && isNativeOpenAiCapabilityAliasModel(routedNativeSlug)
427
+ ) return true;
428
+ if (UPSTREAM_NATIVE_ENTRIES.has(slug) || SUPPORTED_NATIVE_OPENAI_SLUGS.has(slug)) return true;
429
+ return false;
430
+ }
431
+
432
+ export const ROUTED_CODEX_TOOL_MODE = "code_mode_only";
433
+
434
+ export function applyRoutedCodexToolMode(
435
+ entry: RawEntry,
436
+ toolMode?: "code_mode_only" | "shell" | string,
437
+ ): RawEntry {
438
+ if (toolMode === "shell") {
439
+ delete entry.tool_mode;
440
+ return entry;
441
+ }
442
+ entry.tool_mode = ROUTED_CODEX_TOOL_MODE;
443
+ return entry;
444
+ }
445
+
446
+ /**
447
+ * @param v2FeatureEnabled When the native multi_agent_v2 feature is on, "default"
448
+ * mode stamps unpinned entries as "v2" instead of deleting the key. The native
449
+ * binary validates spawn_agent models against THIS catalog with its own
450
+ * `multi_agent_version == Some(V2)` test (codex-rs multi_agents_common.rs), so an
451
+ * absent pin means a clean refusal at spawn time — exactly the cross-provider
452
+ * spawns opencodex exists to enable (option B, devlog
453
+ * 260730_codex_rs_upstream_v2_live_handoff/060). Upstream pins are always
454
+ * preserved: a genuine "v1" pin is a real capability statement and stays excluded.
455
+ * With the feature off the output is byte-identical to the historical behavior.
456
+ *
457
+ * `keepNativeChatGptOnV1` only applies when `mode === "v2"`. It leaves Sol/Terra
458
+ * (and other ChatGPT-native rows) on v1 so a native parent can still spawn a
459
+ * routed child. See issue #92.
460
+ */
461
+ export function applyMultiAgentMode(
462
+ entries: RawEntry[],
463
+ mode: MultiAgentMode,
464
+ v2FeatureEnabled = false,
465
+ options: MultiAgentModeOptions = {},
466
+ ): RawEntry[] {
467
+ if (mode === "v2" && options.keepNativeChatGptOnV1 === true) {
468
+ for (const entry of entries) {
469
+ entry.multi_agent_version = catalogEntryIsNativeChatGpt(entry) ? "v1" : "v2";
470
+ }
471
+ return entries;
472
+ }
473
+ if (mode === "default") {
474
+ // Restore upstream defaults: clear any stale forced multi_agent_version and
475
+ // re-apply upstream pins from the snapshot for native entries that have one.
476
+ for (const entry of entries) {
477
+ const slug = typeof entry.slug === "string" ? entry.slug : "";
478
+ const nativeAlias = entry.opencodex_catalog_kind === CODEX_NATIVE_ALIAS_CATALOG_KIND;
479
+ const routedNativeSlug = slug.startsWith(`${OPENAI_CODEX_PROVIDER_ID}/`)
480
+ ? slug.slice(OPENAI_CODEX_PROVIDER_ID.length + 1)
481
+ : "";
482
+ const codexForwardCapabilityAlias = entry.opencodex_catalog_kind === CODEX_CUSTOM_MODEL_CATALOG_KIND
483
+ && entry.use_responses_lite === true
484
+ && isNativeOpenAiCapabilityAliasModel(routedNativeSlug)
485
+ ? routedNativeSlug
486
+ : undefined;
487
+ const upstreamPin = nativeAlias
488
+ ? nativeMultiAgentVersion(slug)
489
+ : codexForwardCapabilityAlias
490
+ ? nativeMultiAgentVersion(codexForwardCapabilityAlias)
491
+ : UPSTREAM_NATIVE_ENTRIES.get(trustedAccountBoundNativeCatalogSlug(entry) ?? slug)?.multi_agent_version;
492
+ if (typeof upstreamPin === "string") {
493
+ entry.multi_agent_version = upstreamPin;
494
+ } else if (v2FeatureEnabled) {
495
+ entry.multi_agent_version = "v2";
496
+ } else {
497
+ delete entry.multi_agent_version;
498
+ }
499
+ }
500
+ return entries;
501
+ }
502
+ for (const entry of entries) {
503
+ entry.multi_agent_version = mode;
504
+ }
505
+ return entries;
506
+ }
507
+
508
+ export function normalizeRoutedCatalogEntry(
509
+ entry: RawEntry,
510
+ parallelToolCalls = false,
511
+ toolMode?: "code_mode_only" | "shell" | string,
512
+ ): RawEntry {
513
+ delete entry.model_messages;
514
+ delete entry.tool_mode;
515
+ applyRoutedCodexToolMode(entry, toolMode);
516
+ delete entry.multi_agent_version;
517
+ delete entry.use_responses_lite;
518
+ delete entry.supports_websockets;
519
+ delete entry.additional_speed_tiers;
520
+ delete entry.service_tier;
521
+ delete entry.service_tiers;
522
+ delete entry.default_service_tier;
523
+ // Routed rows cloned from native templates must not inherit OpenAI-only summary delivery.
524
+ // Explicit provider/model metadata is re-applied after this normalization step.
525
+ delete entry.supports_reasoning_summaries;
526
+ const isCursorEntry = typeof entry.slug === "string" && entry.slug.startsWith("cursor/");
527
+ // `supports_search_tool` selects Codex's deferred tool-discovery surface; it is not the hosted
528
+ // web-search capability. Routed rows also carry tool_mode=code_mode_only (below), and under code
529
+ // mode DEFERRED MCP tools remain callable through exec's `tools` global / ALL_TOOLS without any
530
+ // tool_search round-trip (upstream codex-rs code_mode suite; live canary 2026-08-13: routed
531
+ // kimi/k3 called tools.mcp__node_repl__js → isError:false). Stamping false here instead forces
532
+ // every MCP declaration into exec.description — a measured 2.7x turn-1 payload regression
533
+ // (96,699 → 258,929 chars; devlog/_plan/260813_tool_catalog_deferral/010). So every routed
534
+ // code-mode row advertises deferred discovery. Cursor still omits hosted web-search metadata below,
535
+ // but disabling this separate exposure bit can inflate `exec` past Cursor's 120 KB wire cap (#1830).
536
+ if (isCursorEntry) {
537
+ delete entry.web_search_tool_type;
538
+ } else {
539
+ entry.web_search_tool_type = "text_and_image";
540
+ }
541
+ entry.supports_search_tool = true;
542
+ // Cursor's transport already serializes overlapping tool calls into atomic Responses tool events.
543
+ // Advertising parallel calls lets Codex send the same native capability bit it sends for OpenAI.
544
+ // Opt-in providers (OcxProviderConfig.parallelToolCalls, e.g. xAI) advertise it too: the
545
+ // openai-chat adapter stops forcing parallel_tool_calls:false and the buffered stream parser
546
+ // assembles multi-call turns (devlog/_plan/260709_parallel_tool_calls).
547
+ entry.supports_parallel_tool_calls = isCursorEntry || parallelToolCalls === true;
548
+ return ensureStrictCatalogFields(entry, { isRouted: true });
549
+ }
550
+
551
+ /** Resolve reasoning-summary support from the active Codex catalog for wire sanitization. */
552
+ export function catalogModelSupportsReasoningSummaries(modelId: string): boolean | undefined {
553
+ if (typeof modelId !== "string" || modelId.length === 0) return undefined;
554
+ const catalog = readCatalog(readCodexCatalogPath()) ?? readCatalog(activeCodexModelsCachePath());
555
+ const models = catalog?.models ?? [];
556
+ const exact = models.find(entry => entry.slug === modelId || entry.id === modelId);
557
+ if (typeof exact?.supports_reasoning_summaries === "boolean") {
558
+ return exact.supports_reasoning_summaries;
559
+ }
560
+ const encodedModelId = encodeRoutedModelId(modelId);
561
+ const matches = models.filter(entry => (
562
+ typeof entry.slug === "string"
563
+ && entry.slug.includes("/")
564
+ && entry.slug.slice(entry.slug.indexOf("/") + 1) === encodedModelId
565
+ && typeof entry.supports_reasoning_summaries === "boolean"
566
+ ));
567
+ const values = new Set(matches.map(entry => entry.supports_reasoning_summaries as boolean));
568
+ return values.size === 1 ? values.values().next().value : undefined;
569
+ }
570
+
571
+ /**
572
+ * Resolve the generated jawcode metadata row for a provider/model pair.
573
+ *
574
+ * Exported because it is the SECOND source of real capability assertions:
575
+ * `applyCatalogMetadata` writes context/modalities from it without ever
576
+ * touching a `CatalogModel`, so the routing-evidence provenance stamp in
577
+ * `applyCatalogModelMetadata` has to consult the same table. Both callers share
578
+ * this one lookup rather than duplicating the resolve/case-fold rules, which is
579
+ * what keeps the serialized entry and its provenance from drifting apart.
580
+ */
581
+ export function generatedModelMetadata(provider: string, modelId: string) {
582
+ const jawcodeProvider = resolveMetadataProvider(provider);
583
+ if (!jawcodeProvider) return undefined;
584
+ return getModelMetadata(jawcodeProvider, modelId)
585
+ ?? (shouldCaseFoldMetadataModelId(provider) ? getModelMetadataCaseInsensitive(jawcodeProvider, modelId) : undefined);
586
+ }
587
+
588
+ export function applyCatalogMetadata(entry: RawEntry, provider: string, modelId: string, contextCap?: number): void {
589
+ const meta = generatedModelMetadata(provider, modelId);
590
+ if (!meta) return;
591
+ if (typeof meta.contextWindow === "number" && meta.contextWindow > 0) {
592
+ const contextWindow = applyProviderContextCap(meta.contextWindow, contextCap) ?? meta.contextWindow;
593
+ entry.context_window = contextWindow;
594
+ entry.max_context_window = contextWindow;
595
+ entry.auto_compact_token_limit = Math.floor(contextWindow * 0.9);
596
+ }
597
+ if (Array.isArray(meta.input) && meta.input.length > 0) {
598
+ entry.input_modalities = meta.input;
599
+ }
600
+ }
601
+
602
+ export function catalogModelSlug(model: CatalogModel): string {
603
+ return model.alias ?? routedSlug(model.provider, model.id);
604
+ }
605
+
606
+ export function filterSupportedNativeSlugs(models: RawEntry[]): string[] {
607
+ return models
608
+ .filter(m => typeof m.slug === "string" && !(m.slug as string).includes("/") && m.visibility === "list" && SUPPORTED_NATIVE_OPENAI_SLUGS.has(m.slug as string))
609
+ .map(m => m.slug as string);
610
+ }
611
+
612
+ export function readCatalogBackup(catalogPath: string): RawCatalog | null {
613
+ return readCatalog(catalogBackupPathFor(catalogPath))
614
+ ?? (isDefaultCatalogPath(catalogPath) ? readCatalog(legacyCatalogBackupPath()) : null);
615
+ }
616
+
617
+ export function catalogHasRoutedEntries(catalog: RawCatalog | null): boolean {
618
+ return (catalog?.models ?? []).some(m => typeof m.slug === "string"
619
+ && (m.slug.includes("/") || m.opencodex_catalog_kind === CODEX_NATIVE_ALIAS_CATALOG_KIND));
620
+ }
621
+
622
+ export function writePristineCatalogBackup(backupPath: string, catalogPath: string, catalog: RawCatalog): void {
623
+ if (existsSync(backupPath)) return;
624
+ const onDisk = readCatalog(catalogPath);
625
+ if (onDisk && !catalogHasRoutedEntries(onDisk)) {
626
+ copyFileSync(catalogPath, backupPath);
627
+ return;
628
+ }
629
+ if (!catalogHasRoutedEntries(catalog)) {
630
+ atomicWriteFile(backupPath, JSON.stringify(catalog, null, 2) + "\n");
631
+ }
632
+ }
633
+
634
+ export function ensureCatalogBackup(catalogPath: string, catalog: RawCatalog): void {
635
+ const dir = getConfigDir();
636
+ if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
637
+ writePristineCatalogBackup(catalogBackupPathFor(catalogPath), catalogPath, catalog);
638
+ if (isDefaultCatalogPath(catalogPath)) writePristineCatalogBackup(legacyCatalogBackupPath(), catalogPath, catalog);
639
+ }
640
+
641
+ export function readNativeBaseline(catalogPath: string): Map<string, number> {
642
+ const backup = readCatalogBackup(catalogPath);
643
+ const out = new Map<string, number>();
644
+ for (const e of backup?.models ?? []) {
645
+ if (typeof e.slug === "string" && !e.slug.includes("/") && typeof e.priority === "number") {
646
+ out.set(e.slug, e.priority);
647
+ }
648
+ }
649
+ return out;
650
+ }