@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,156 @@
1
+ import { codexAutoStartEnabled } from "../config";
2
+ import { diagnoseService, type ServiceDiagnostic } from "../service";
3
+ import type { OcxConfig } from "../types";
4
+ import { getCodexRoutingKind, type CodexRoutingKind } from "./inject";
5
+ import { diagnoseCodexShim, type CodexShimDiagnostic } from "./shim";
6
+
7
+ export type StartupProtection = "service" | "shim" | "none";
8
+ export type StartupHealthStatus = "native" | "protected" | "at-risk";
9
+ export type ShimCoverage = "full" | "cli-only" | "none";
10
+
11
+ export interface StartupHealthInputs {
12
+ routingKind: CodexRoutingKind;
13
+ autostartEnabled: boolean;
14
+ serviceInstalled: boolean;
15
+ serviceViable: boolean;
16
+ serviceEnabled: boolean;
17
+ serviceRunning: boolean;
18
+ serviceStale: boolean;
19
+ serviceConflict: boolean;
20
+ serviceSupported: boolean;
21
+ shimInstalled: boolean;
22
+ shimHealthy: boolean;
23
+ platform: NodeJS.Platform;
24
+ diagnosticStale?: boolean;
25
+ }
26
+
27
+ export interface StartupHealth {
28
+ status: StartupHealthStatus;
29
+ routingKind: CodexRoutingKind;
30
+ routingInjected: boolean;
31
+ localRoutingDependency: boolean;
32
+ autostartEnabled: boolean;
33
+ rebootSafe: boolean;
34
+ protection: StartupProtection;
35
+ serviceInstalled: boolean;
36
+ serviceViable: boolean;
37
+ serviceEnabled: boolean;
38
+ serviceRunning: boolean;
39
+ serviceStale: boolean;
40
+ serviceConflict: boolean;
41
+ shimInstalled: boolean;
42
+ shimHealthy: boolean;
43
+ shimCoverage: ShimCoverage;
44
+ serviceSupported: boolean;
45
+ platform: NodeJS.Platform;
46
+ diagnosticStale: boolean;
47
+ recommendedCommand: string | null;
48
+ commands: {
49
+ installService: string;
50
+ repairService: string;
51
+ installShim: string;
52
+ restoreNative: string;
53
+ };
54
+ }
55
+
56
+ const COMMANDS = {
57
+ installService: "ocx service install",
58
+ repairService: "ocx service repair",
59
+ installShim: "ocx codex-shim install",
60
+ restoreNative: "ocx restore",
61
+ } as const;
62
+
63
+ export function deriveStartupHealth(inputs: StartupHealthInputs): StartupHealth {
64
+ const shimEffective = inputs.autostartEnabled && inputs.shimHealthy;
65
+ const routingInjected = inputs.routingKind === "opencodex-local";
66
+ const localRoutingDependency = inputs.routingKind === "opencodex-local"
67
+ || inputs.routingKind === "custom-local"
68
+ || inputs.routingKind === "unknown";
69
+ // Script launchers never cover Codex Desktop/app-server surfaces. This is
70
+ // intentionally conservative on every OS and for WSL-shared Codex homes.
71
+ const shimCoverage: ShimCoverage = !shimEffective
72
+ ? "none"
73
+ : "cli-only";
74
+ // We can only credit an opencodex service/shim for routing that opencodex owns.
75
+ // An arbitrary localhost gateway has an independent lifecycle that OCX cannot repair.
76
+ const ownsLocalRouting = inputs.routingKind === "opencodex-local";
77
+ const protection: StartupProtection = ownsLocalRouting && inputs.serviceViable
78
+ ? "service"
79
+ : ownsLocalRouting && shimEffective
80
+ ? "shim"
81
+ : "none";
82
+ const rebootSafe = !localRoutingDependency || (ownsLocalRouting && inputs.serviceViable);
83
+ const status: StartupHealthStatus = !localRoutingDependency
84
+ ? "native"
85
+ : rebootSafe
86
+ ? "protected"
87
+ : "at-risk";
88
+ const recommendedCommand = status !== "at-risk"
89
+ ? null
90
+ : inputs.routingKind === "custom-local" || inputs.routingKind === "unknown"
91
+ ? COMMANDS.restoreNative
92
+ : inputs.serviceSupported
93
+ // An already-registered service is refreshed in place: `repair` rewrites its assets
94
+ // and restarts it without re-registering, so it needs no elevation on Windows and
95
+ // cannot switch a WinSW install to Task Scheduler the way `install` would. Only a
96
+ // genuinely absent (or conflicting, which needs uninstall-then-install) service
97
+ // gets the registering command.
98
+ ? (inputs.serviceInstalled && !inputs.serviceConflict ? COMMANDS.repairService : COMMANDS.installService)
99
+ : COMMANDS.restoreNative;
100
+ return {
101
+ ...inputs,
102
+ diagnosticStale: inputs.diagnosticStale ?? false,
103
+ routingInjected,
104
+ localRoutingDependency,
105
+ status,
106
+ rebootSafe,
107
+ protection,
108
+ shimCoverage,
109
+ recommendedCommand,
110
+ commands: { ...COMMANDS },
111
+ };
112
+ }
113
+
114
+ export interface StartupHealthDiagnostics {
115
+ routingKind?: CodexRoutingKind;
116
+ service?: ServiceDiagnostic;
117
+ shim?: CodexShimDiagnostic;
118
+ }
119
+
120
+ /** Collect current machine state without mutating config, services, or shims. */
121
+ export function collectStartupHealth(
122
+ config: Pick<OcxConfig, "codexAutoStart">,
123
+ diagnostics: StartupHealthDiagnostics = {},
124
+ ): StartupHealth {
125
+ const shim = diagnostics.shim ?? diagnoseCodexShim();
126
+ const service = diagnostics.service ?? diagnoseService();
127
+ return deriveStartupHealth({
128
+ routingKind: diagnostics.routingKind ?? getCodexRoutingKind(),
129
+ autostartEnabled: codexAutoStartEnabled(config),
130
+ serviceInstalled: service.installed,
131
+ serviceViable: service.viable,
132
+ serviceEnabled: service.enabled,
133
+ serviceRunning: service.running,
134
+ serviceStale: service.stale,
135
+ serviceConflict: service.conflict,
136
+ serviceSupported: service.supported,
137
+ shimInstalled: shim.installed,
138
+ shimHealthy: shim.healthy,
139
+ platform: process.platform,
140
+ });
141
+ }
142
+
143
+ export function startupHealthSummary(health: StartupHealth): string {
144
+ if (health.status === "native") return health.routingKind === "custom-remote"
145
+ ? "custom remote Codex routing (no local restart dependency)"
146
+ : "native Codex routing (no opencodex restart dependency)";
147
+ if (health.protection === "service") return "protected by background service";
148
+ const command = health.recommendedCommand ?? health.commands.restoreNative;
149
+ if (health.routingKind === "unknown") return `AT RISK after restart (Codex routing could not be verified; run '${command}')`;
150
+ if (health.routingKind === "custom-local") return `AT RISK after restart (custom local gateway lifecycle is not managed by opencodex; run '${command}')`;
151
+ if (health.shimCoverage === "cli-only") return `AT RISK for Codex Desktop after restart (launcher shim covers CLI scripts only; run '${command}')`;
152
+ if (health.serviceConflict) return `AT RISK after restart (background service managers conflict; run '${command}')`;
153
+ if (health.serviceStale) return `AT RISK after restart (background service files are stale; run '${command}')`;
154
+ if (health.serviceInstalled && !health.serviceViable) return `AT RISK after restart (installed service is disabled, stopped, or unhealthy; run '${command}')`;
155
+ return `AT RISK after restart (no viable background service; run '${command}')`;
156
+ }
@@ -0,0 +1,67 @@
1
+ import type { OcxConfig } from "../../types";
2
+ import {
3
+ codexAccountNamespaceEntries,
4
+ codexAccountPickerEnabled,
5
+ isMainCodexAccountTarget,
6
+ } from "../account-namespaces";
7
+ import type { RawEntry } from "./parsing";
8
+
9
+ /** Stable nonsemantic marker used to distinguish generated rows from provider-owned rows. */
10
+ export const CODEX_ACCOUNT_BOUND_CATALOG_KIND = "account-selector-v1";
11
+
12
+ /**
13
+ * Public selectors whose configured account row still exists.
14
+ *
15
+ * Stale mappings stay in config so exact routing keeps failing closed, but they must not advertise
16
+ * a deleted account. Credential health, pause, and reauthentication state intentionally do not
17
+ * churn catalog identity. Selector keys have already passed config's nonempty, single-segment
18
+ * namespace validation. Only those public keys leave this boundary; private account ids do not.
19
+ */
20
+ export function visibleCodexAccountSelectors(
21
+ config: Pick<OcxConfig, "codexAccounts" | "codexAccountNamespaces" | "codexAccountPickerEnabled">,
22
+ ): string[] {
23
+ if (!codexAccountPickerEnabled(config)) return [];
24
+ const storedPoolAccounts = new Set(
25
+ (config.codexAccounts ?? [])
26
+ .filter(account => !account.isMain)
27
+ .map(account => account.id),
28
+ );
29
+ return codexAccountNamespaceEntries(config)
30
+ .filter(([, accountId]) =>
31
+ isMainCodexAccountTarget(accountId) || storedPoolAccounts.has(accountId)
32
+ )
33
+ .map(([selector]) => selector);
34
+ }
35
+
36
+ export function accountBoundNativeDisplayName(selector: string, native: RawEntry): string {
37
+ const rawModel = typeof native.display_name === "string"
38
+ ? native.display_name
39
+ : String(native.slug ?? "");
40
+ const model = rawModel
41
+ .replace(/^gpt-/i, "")
42
+ .split("-")
43
+ .filter(Boolean)
44
+ .map(part => /^[a-z]/.test(part) ? part.charAt(0).toUpperCase() + part.slice(1) : part)
45
+ .join(" ");
46
+ return `${selector} / ${model}`;
47
+ }
48
+
49
+ /** Identify current generated rows without changing Codex's semantic model fields. */
50
+ export function trustedAccountBoundNativeCatalogSlug(entry: RawEntry): string | undefined {
51
+ if (entry.opencodex_catalog_kind !== CODEX_ACCOUNT_BOUND_CATALOG_KIND
52
+ || typeof entry.slug !== "string") return undefined;
53
+ const slash = entry.slug.indexOf("/");
54
+ if (slash <= 0 || slash !== entry.slug.lastIndexOf("/") || slash === entry.slug.length - 1) {
55
+ return undefined;
56
+ }
57
+ return entry.slug.slice(slash + 1);
58
+ }
59
+
60
+ export function accountBoundNativeModelSlugs(
61
+ config: Pick<OcxConfig, "codexAccounts" | "codexAccountNamespaces" | "codexAccountPickerEnabled">,
62
+ nativeSlugs: Iterable<string>,
63
+ ): string[] {
64
+ const natives = [...nativeSlugs];
65
+ return visibleCodexAccountSelectors(config)
66
+ .flatMap(selector => natives.map(slug => `${selector}/${slug}`));
67
+ }
@@ -0,0 +1,436 @@
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 { routedSlug, slugEquals, slugEquivalenceKey, 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
+ comboDisabledModelSelectors,
24
+ comboModelId,
25
+ getCombo,
26
+ listComboIds,
27
+ targetKey,
28
+ } from "../../combos";
29
+ import type { NormalizedComboConfig } from "../../combos/types";
30
+ import { providerDestinationResolvedError } from "../../lib/destination-policy";
31
+ import { redactSecretString } from "../../lib/redact";
32
+ import upstreamModelsSnapshot from "../data/upstream-models.json";
33
+
34
+
35
+ import { catalogModelSlug } from "./parsing";
36
+ import type { CatalogModel } from "./parsing";
37
+
38
+ export const openAiApiCollisionWarnings = new Set<string>();
39
+
40
+ export const comboCatalogWarningSignatures = new Map<string, string>();
41
+
42
+ /**
43
+ * Why `deriveComboCatalogModel` rejected a configured combo (#484 / #516).
44
+ * Distinguishes unresolved/incomplete member metadata from a complete but empty
45
+ * modality intersection so diagnostics do not send operators to the wrong fix.
46
+ */
47
+ export type ComboCatalogOmissionReason =
48
+ | "incomplete_metadata"
49
+ | "incompatible_modalities";
50
+
51
+ /** Combos omitted from the catalog during the most recent `gatherRoutedModels` call (#484). */
52
+ export interface ComboCatalogOmission {
53
+ id: string;
54
+ targets: string[];
55
+ reason: ComboCatalogOmissionReason;
56
+ message: string;
57
+ }
58
+
59
+ let lastComboCatalogOmissions: ComboCatalogOmission[] = [];
60
+
61
+ export function clearLastComboCatalogOmissions(): void {
62
+ lastComboCatalogOmissions = [];
63
+ }
64
+
65
+ export function getLastComboCatalogOmissions(): readonly ComboCatalogOmission[] {
66
+ return lastComboCatalogOmissions;
67
+ }
68
+
69
+ export function replaceLastComboCatalogOmissions(items: readonly ComboCatalogOmission[]): void {
70
+ lastComboCatalogOmissions = [...items];
71
+ }
72
+
73
+ export function intersectStrings(values: readonly string[][]): string[] {
74
+ if (values.length === 0) return [];
75
+ const rest = values.slice(1).map(value => new Set(value));
76
+ return [...new Set(values[0])].filter(value => rest.every(set => set.has(value)));
77
+ }
78
+
79
+ export function effectiveComboDefault(
80
+ configured: string | null | undefined,
81
+ common: readonly string[],
82
+ ): string | undefined {
83
+ if (!configured) return undefined;
84
+ if (configured && common.includes(configured)) return configured;
85
+ const requestedRank = codexEffortRank(configured);
86
+ const ranked = common
87
+ .map(effort => ({ effort, rank: codexEffortRank(effort) }))
88
+ .filter(item => item.rank >= 0)
89
+ .sort((a, b) => a.rank - b.rank);
90
+ if (ranked.length === 0) return undefined;
91
+ const atOrBelow = ranked.filter(item => item.rank <= requestedRank);
92
+ return atOrBelow.at(-1)?.effort ?? ranked[0]!.effort;
93
+ }
94
+
95
+ /**
96
+ * Classify a combo derivation failure. Returns `null` when the combo would catalog.
97
+ * Callers that already know derivation failed can map the reason into diagnostics.
98
+ */
99
+ export function comboCatalogOmissionReason(
100
+ combo: NormalizedComboConfig,
101
+ members: readonly CatalogModel[],
102
+ ): ComboCatalogOmissionReason | null {
103
+ if (combo.targets.length === 0) return "incomplete_metadata";
104
+ if (new Set(combo.targets.map(targetKey)).size !== combo.targets.length) {
105
+ return "incomplete_metadata";
106
+ }
107
+ if (members.length !== combo.targets.length) return "incomplete_metadata";
108
+ if (!members.every((member, index) => (
109
+ `${member.provider}/${member.id}` === targetKey(combo.targets[index]!)
110
+ ))) {
111
+ return "incomplete_metadata";
112
+ }
113
+ const contexts = members.map(member => member.contextWindow);
114
+ if (contexts.some(value => typeof value !== "number" || value <= 0)) {
115
+ return "incomplete_metadata";
116
+ }
117
+
118
+ const inputModalities = intersectStrings(
119
+ members.map(member => member.inputModalities ?? ["text"]),
120
+ );
121
+ if (inputModalities.length === 0) return "incompatible_modalities";
122
+ return null;
123
+ }
124
+
125
+ export function deriveComboCatalogModel(
126
+ id: string,
127
+ combo: NormalizedComboConfig,
128
+ members: readonly CatalogModel[],
129
+ ): CatalogModel | null {
130
+ if (comboCatalogOmissionReason(combo, members) !== null) return null;
131
+
132
+ const derivedInputModalities = intersectStrings(
133
+ members.map(member => member.inputModalities ?? ["text"]),
134
+ );
135
+ const inputModalities = combo.imageInput === "disabled"
136
+ ? derivedInputModalities.filter(modality => modality !== "image")
137
+ : derivedInputModalities;
138
+ if (inputModalities.length === 0) return null;
139
+ // Unknown ladders (`undefined`) are wildcards for catalog derivation — same
140
+ // boundary as the GUI picker. An explicit empty ladder still constrains.
141
+ const advertisedLadders = members
142
+ .map(member => member.reasoningEfforts)
143
+ .filter((ladder): ladder is string[] => ladder !== undefined);
144
+ const reasoningEfforts = advertisedLadders.length === 0
145
+ ? []
146
+ : intersectStrings(advertisedLadders);
147
+ const contextWindow = Math.min(...members.map(member => member.contextWindow!));
148
+ const limitingMembers = members.filter(member => member.contextWindow === contextWindow);
149
+ const hasLimitingContextCapMetadata = limitingMembers.some(
150
+ member => typeof member.contextCapped === "boolean",
151
+ );
152
+ // A combo is cap-limited only when every member defining its effective minimum was
153
+ // itself reduced by a provider cap. An uncapped member at the same minimum means the
154
+ // combo would have the same window even without the cap.
155
+ const contextCapped = limitingMembers.every(member => member.contextCapped === true);
156
+ const maxInputTokens = Math.min(
157
+ ...members.map(member => member.maxInputTokens ?? member.contextWindow!),
158
+ );
159
+ const defaultReasoningEffort = effectiveComboDefault(
160
+ combo.defaultEffort,
161
+ reasoningEfforts,
162
+ );
163
+
164
+ return {
165
+ provider: COMBO_NAMESPACE,
166
+ id,
167
+ owned_by: COMBO_NAMESPACE,
168
+ contextWindow,
169
+ maxInputTokens,
170
+ ...(hasLimitingContextCapMetadata ? { contextCapped } : {}),
171
+ inputModalities,
172
+ reasoningEfforts,
173
+ ...(combo.alias ? { alias: combo.alias } : {}),
174
+ ...(combo.nativeAlias ? { nativeAlias: true } : {}),
175
+ ...(combo.displayName ? { displayName: combo.displayName } : {}),
176
+ ...(defaultReasoningEffort ? { defaultReasoningEffort } : {}),
177
+ ...(members.every(member => member.parallelToolCalls === true)
178
+ ? { parallelToolCalls: true }
179
+ : {}),
180
+ ...(members.every(member => member.supportsServiceTier === true)
181
+ ? { supportsServiceTier: true }
182
+ : members.some(member => member.supportsServiceTier === false)
183
+ ? { supportsServiceTier: false }
184
+ : {}),
185
+ ...(members.some(member => member.supportsReasoningSummaries === false) ? { supportsReasoningSummaries: false } : {}),
186
+ ...(members.every(member => member.codexToolMode === "shell")
187
+ ? { codexToolMode: "shell" as const }
188
+ : {}),
189
+ };
190
+ }
191
+
192
+ export function safeCatalogWarningLabel(value: string): string {
193
+ return redactSecretString(value)
194
+ .replace(/[\u0000-\u001f\u007f]/g, "?")
195
+ .slice(0, 200);
196
+ }
197
+
198
+ export function comboCatalogWarningSignature(
199
+ combo: NormalizedComboConfig,
200
+ members: readonly CatalogModel[],
201
+ ): string {
202
+ const discovered = new Map<string, CatalogModel>(members.map(member => [
203
+ `${member.provider}/${member.id}`,
204
+ member,
205
+ ] as const));
206
+ return JSON.stringify(combo.targets.map(target => {
207
+ const key = targetKey(target);
208
+ const member = discovered.get(key);
209
+ return {
210
+ key,
211
+ contextWindow: member?.contextWindow ?? null,
212
+ maxInputTokens: member?.maxInputTokens ?? null,
213
+ inputModalities: [...new Set(member?.inputModalities ?? [])].sort(),
214
+ reasoningEfforts: [...new Set(member?.reasoningEfforts ?? [])].sort(),
215
+ parallelToolCalls: member?.parallelToolCalls === true,
216
+ supportsReasoningSummaries: member?.supportsReasoningSummaries !== false,
217
+ };
218
+ }).sort((a, b) => a.key.localeCompare(b.key)));
219
+ }
220
+
221
+ export function comboCatalogOmissionDetail(reason: ComboCatalogOmissionReason): string {
222
+ return reason === "incompatible_modalities"
223
+ ? "members have no common input modalities"
224
+ : "member capabilities are incomplete";
225
+ }
226
+
227
+ /** One-line sync/CLI summary that respects the actual omission reason(s). */
228
+ export function summarizeComboCatalogOmissions(
229
+ omissions: readonly Pick<ComboCatalogOmission, "reason">[],
230
+ ): string {
231
+ const n = omissions.length;
232
+ const prefix = `${n} combo${n === 1 ? "" : "s"} omitted from the catalog`;
233
+ if (n === 0) return prefix + ".";
234
+ const reasons = new Set(omissions.map(item => item.reason));
235
+ if (reasons.size === 1) {
236
+ return `${prefix} because ${comboCatalogOmissionDetail([...reasons][0]!)}.`;
237
+ }
238
+ return `${prefix}.`;
239
+ }
240
+
241
+ export function buildComboCatalogOmission(
242
+ id: string,
243
+ combo: NormalizedComboConfig,
244
+ members: readonly CatalogModel[],
245
+ ): ComboCatalogOmission {
246
+ const targets = combo.targets
247
+ .map(target => safeCatalogWarningLabel(targetKey(target)))
248
+ .sort((a, b) => a.localeCompare(b));
249
+ const reason = comboCatalogOmissionReason(combo, members) ?? "incomplete_metadata";
250
+ return {
251
+ id,
252
+ targets,
253
+ reason,
254
+ message: `[opencodex] Combo "${safeCatalogWarningLabel(id)}" is omitted from the catalog because ${comboCatalogOmissionDetail(reason)}: ${targets.join(", ")}.`,
255
+ };
256
+ }
257
+
258
+ /**
259
+ * Record a combo omitted from `/v1/models` + on-disk catalog and warn once per signature.
260
+ * Callers that need a race-free list (catalog sync) pass a local `sink` from the same
261
+ * gather invocation instead of reading process-global state afterward (#484 review).
262
+ */
263
+ export function warnUncataloguedComboOnce(
264
+ id: string,
265
+ combo: NormalizedComboConfig,
266
+ members: readonly CatalogModel[],
267
+ sink: ComboCatalogOmission[] = lastComboCatalogOmissions,
268
+ ): ComboCatalogOmission {
269
+ const omission = buildComboCatalogOmission(id, combo, members);
270
+ sink.push(omission);
271
+ const signature = comboCatalogWarningSignature(combo, members);
272
+ if (comboCatalogWarningSignatures.get(id) !== signature) {
273
+ comboCatalogWarningSignatures.set(id, signature);
274
+ console.warn(omission.message);
275
+ }
276
+ return omission;
277
+ }
278
+
279
+ export function exactComboCatalogSlugs(
280
+ config: Pick<OcxConfig, "combos" | "disabledModels">,
281
+ ): Set<string> {
282
+ const disabled = new Set(config.disabledModels ?? []);
283
+ return new Set(listComboIds(config).flatMap(id => {
284
+ const raw = config.combos?.[id];
285
+ const alias = typeof raw?.alias === "string"
286
+ ? raw.alias.trim()
287
+ : "";
288
+ const canonical = comboModelId(id);
289
+ const publicSlug = alias || canonical;
290
+ const comboDisabled = comboDisabledModelSelectors(id, raw ?? {})
291
+ .some(selector => disabled.has(selector));
292
+ return comboDisabled ? [] : [publicSlug];
293
+ }));
294
+ }
295
+
296
+ export function normalizedOpenAiApiSignature(model: CatalogModel): string {
297
+ const normalized = {
298
+ provider: model.provider,
299
+ id: model.id,
300
+ contextWindow: model.contextWindow ?? null,
301
+ maxInputTokens: model.maxInputTokens ?? null,
302
+ inputModalities: [...new Set(model.inputModalities ?? [])].sort(),
303
+ reasoningEfforts: [...new Set(model.reasoningEfforts ?? [])].sort(),
304
+ ownedBy: model.owned_by ?? null,
305
+ };
306
+ return JSON.stringify(normalized);
307
+ }
308
+
309
+ export function resetOpenAiApiCatalogWarningStateForTests(): void {
310
+ openAiApiCollisionWarnings.clear();
311
+ }
312
+
313
+ export const slugAliasCollisionWarnings = new Set<string>();
314
+
315
+ export const comboMasqueradeCollisionWarnings = new Set<string>();
316
+
317
+ export const comboUnrestorableShadowWarnings = new Set<string>();
318
+
319
+ export const accountSelectorShadowCollisionWarnings = new Set<string>();
320
+ let lastWarningReconciledGeneration = 0;
321
+
322
+ export function reconcileCatalogWarningMemos(generation: number): number {
323
+ if (generation <= lastWarningReconciledGeneration) return 0;
324
+ const removed = openAiApiCollisionWarnings.size
325
+ + comboCatalogWarningSignatures.size
326
+ + slugAliasCollisionWarnings.size
327
+ + comboMasqueradeCollisionWarnings.size
328
+ + comboUnrestorableShadowWarnings.size
329
+ + accountSelectorShadowCollisionWarnings.size;
330
+ openAiApiCollisionWarnings.clear();
331
+ comboCatalogWarningSignatures.clear();
332
+ slugAliasCollisionWarnings.clear();
333
+ comboMasqueradeCollisionWarnings.clear();
334
+ comboUnrestorableShadowWarnings.clear();
335
+ accountSelectorShadowCollisionWarnings.clear();
336
+ lastWarningReconciledGeneration = generation;
337
+ return removed;
338
+ }
339
+
340
+ export function warnComboMasqueradeCollisionOnce(slug: string): void {
341
+ if (comboMasqueradeCollisionWarnings.has(slug)) return;
342
+ comboMasqueradeCollisionWarnings.add(slug);
343
+ console.warn(
344
+ `[opencodex] combo alias collision on "${safeCatalogWarningLabel(slug)}": the combo wins and the shadowed provider model is omitted from the catalog.`,
345
+ );
346
+ }
347
+
348
+ export function warnComboUnrestorableShadowOnce(slug: string): void {
349
+ const key = slugEquivalenceKey(slug);
350
+ if (comboUnrestorableShadowWarnings.has(key)) return;
351
+ comboUnrestorableShadowWarnings.add(key);
352
+ console.warn(
353
+ `[opencodex] combo alias collision on "${safeCatalogWarningLabel(slug)}": the existing user-managed or foreign catalog row is retained because no pristine backup can restore it. Rename the combo alias to expose both models.`,
354
+ );
355
+ }
356
+
357
+ /** Warn once when a live provider row loses its reserved slug to an account selector. */
358
+ export function warnAccountSelectorShadowedProviderOnce(slug: string): void {
359
+ if (accountSelectorShadowCollisionWarnings.has(slug)) return;
360
+ accountSelectorShadowCollisionWarnings.add(slug);
361
+ console.warn(
362
+ `[opencodex] account selector collision on "${safeCatalogWarningLabel(slug)}": the account-bound native model wins and the shadowed provider model is omitted from the catalog. Rename the provider or account selector.`,
363
+ );
364
+ }
365
+
366
+ export function resolveSlugAliasCollisions(goModels: CatalogModel[]): Set<CatalogModel> {
367
+ const skipped = new Set<CatalogModel>();
368
+ const winnerByAlias = new Map<string, CatalogModel>();
369
+ for (const m of goModels) {
370
+ // Combo aliases have their own collision policy below: they always shadow provider rows.
371
+ if (m.provider === COMBO_NAMESPACE) continue;
372
+ const key = catalogModelSlug(m);
373
+ const winner = winnerByAlias.get(key);
374
+ if (!winner) {
375
+ winnerByAlias.set(key, m);
376
+ continue;
377
+ }
378
+ const winnerIsPlainAlias = !winner.id.includes("/");
379
+ const currentIsPlainAlias = !m.id.includes("/");
380
+ if (currentIsPlainAlias && !winnerIsPlainAlias) {
381
+ skipped.add(winner);
382
+ winnerByAlias.set(key, m);
383
+ } else {
384
+ skipped.add(m);
385
+ }
386
+ if (!slugAliasCollisionWarnings.has(key)) {
387
+ slugAliasCollisionWarnings.add(key);
388
+ console.warn(
389
+ `[opencodex] slug alias collision on "${key}": multiple native ids encode to the same Codex-facing slug; `
390
+ + "the plain-hyphen native id is cataloged, the slash id remains callable via its raw selector.",
391
+ );
392
+ }
393
+ }
394
+ return skipped;
395
+ }
396
+
397
+ export function uniqueCatalogModelsForPublicList(goModels: CatalogModel[]): CatalogModel[] {
398
+ const collisionSkipped = resolveSlugAliasCollisions(goModels);
399
+ const comboPublicSlugs = new Set(goModels
400
+ .filter(model => model.provider === COMBO_NAMESPACE)
401
+ .map(catalogModelSlug));
402
+ const seen = new Set<string>();
403
+ const out: CatalogModel[] = [];
404
+ for (const model of goModels) {
405
+ if (collisionSkipped.has(model)) continue;
406
+ const slug = catalogModelSlug(model);
407
+ if (model.provider !== COMBO_NAMESPACE && comboPublicSlugs.has(slug)) {
408
+ warnComboMasqueradeCollisionOnce(slug);
409
+ continue;
410
+ }
411
+ if (seen.has(slug)) continue;
412
+ seen.add(slug);
413
+ out.push(model);
414
+ }
415
+ return out;
416
+ }
417
+
418
+ export function uniqueCatalogModelsForRawPublicList(goModels: CatalogModel[]): CatalogModel[] {
419
+ const publicId = (model: CatalogModel): string => model.alias ?? `${model.provider}/${model.id}`;
420
+ const comboPublicIds = new Set(goModels
421
+ .filter(model => model.provider === COMBO_NAMESPACE)
422
+ .map(publicId));
423
+ const seen = new Set<string>();
424
+ const out: CatalogModel[] = [];
425
+ for (const model of goModels) {
426
+ const id = publicId(model);
427
+ if (model.provider !== COMBO_NAMESPACE && comboPublicIds.has(id)) {
428
+ warnComboMasqueradeCollisionOnce(id);
429
+ continue;
430
+ }
431
+ if (seen.has(id)) continue;
432
+ seen.add(id);
433
+ out.push(model);
434
+ }
435
+ return out;
436
+ }