@iislee/opencodex 2.11.0 → 2.35.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 (733) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +117 -22
  3. package/bin/ocx.mjs +245 -88
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-Be1sDpWw.css +1 -0
  6. package/gui/dist/assets/index-D4OKgUV4.js +114 -0
  7. package/gui/dist/index.html +2 -2
  8. package/gui/dist/provider-icons/alibaba-color.svg +1 -1
  9. package/gui/dist/provider-icons/antigravity-color.svg +1 -1
  10. package/gui/dist/provider-icons/claude-color.svg +1 -1
  11. package/gui/dist/provider-icons/cline-color.svg +16 -0
  12. package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
  13. package/gui/dist/provider-icons/commandcode-color.svg +1 -0
  14. package/gui/dist/provider-icons/copilot-color.svg +1 -1
  15. package/gui/dist/provider-icons/cursor-color.svg +1 -1
  16. package/gui/dist/provider-icons/deepseek-color.svg +1 -1
  17. package/gui/dist/provider-icons/firepass-color.svg +1 -1
  18. package/gui/dist/provider-icons/fireworks-color.svg +1 -1
  19. package/gui/dist/provider-icons/gemini-color.svg +1 -1
  20. package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
  21. package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
  22. package/gui/dist/provider-icons/grok.svg +1 -1
  23. package/gui/dist/provider-icons/groq-color.svg +1 -1
  24. package/gui/dist/provider-icons/huggingface-color.svg +1 -1
  25. package/gui/dist/provider-icons/kimi-color.svg +1 -1
  26. package/gui/dist/provider-icons/kiro-color.svg +2 -2
  27. package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
  28. package/gui/dist/provider-icons/mistral-color.svg +1 -1
  29. package/gui/dist/provider-icons/moonshot-color.svg +1 -1
  30. package/gui/dist/provider-icons/nvidia-color.svg +1 -1
  31. package/gui/dist/provider-icons/ollama-color.svg +1 -1
  32. package/gui/dist/provider-icons/openai.svg +1 -1
  33. package/gui/dist/provider-icons/opencode.svg +2 -1
  34. package/gui/dist/provider-icons/openrouter-color.svg +1 -1
  35. package/gui/dist/provider-icons/pi.svg +2 -2
  36. package/gui/dist/provider-icons/qianfan-color.svg +1 -1
  37. package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
  38. package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
  39. package/gui/dist/provider-icons/vllm-color.svg +1 -1
  40. package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
  41. package/package.json +21 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +475 -62
  44. package/src/adapters/base.ts +82 -7
  45. package/src/adapters/client-fingerprint.ts +18 -12
  46. package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
  47. package/src/adapters/command-code.ts +637 -0
  48. package/src/adapters/cursor/call-id.ts +44 -0
  49. package/src/adapters/cursor/catalog.ts +541 -0
  50. package/src/adapters/cursor/checkpoint-store.ts +308 -0
  51. package/src/adapters/cursor/cursor-errors.ts +144 -6
  52. package/src/adapters/cursor/discovery.ts +122 -14
  53. package/src/adapters/cursor/effort-map.ts +106 -4
  54. package/src/adapters/cursor/envelope-echo.ts +290 -0
  55. package/src/adapters/cursor/framing.ts +39 -0
  56. package/src/adapters/cursor/h2-pool.ts +123 -0
  57. package/src/adapters/cursor/http1-bidi.ts +361 -0
  58. package/src/adapters/cursor/images.ts +704 -0
  59. package/src/adapters/cursor/live-models.ts +180 -59
  60. package/src/adapters/cursor/live-transport.ts +623 -170
  61. package/src/adapters/cursor/message-mapper.ts +4 -1
  62. package/src/adapters/cursor/native-exec-common.ts +23 -2
  63. package/src/adapters/cursor/native-exec-desktop.ts +23 -0
  64. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  65. package/src/adapters/cursor/native-exec-network.ts +1 -1
  66. package/src/adapters/cursor/native-exec-shell.ts +5 -3
  67. package/src/adapters/cursor/native-exec.ts +121 -14
  68. package/src/adapters/cursor/protobuf-events.ts +829 -11
  69. package/src/adapters/cursor/protobuf-request.ts +447 -75
  70. package/src/adapters/cursor/request-builder.ts +271 -35
  71. package/src/adapters/cursor/tool-definitions.ts +252 -12
  72. package/src/adapters/cursor/tool-result-normalize.ts +115 -0
  73. package/src/adapters/cursor/transport.ts +22 -0
  74. package/src/adapters/cursor/types.ts +48 -1
  75. package/src/adapters/cursor.ts +336 -39
  76. package/src/adapters/exec-tool-result-normalize.ts +99 -0
  77. package/src/adapters/google-antigravity-replay.ts +713 -41
  78. package/src/adapters/google-antigravity-wire.ts +48 -10
  79. package/src/adapters/google-errors.ts +44 -12
  80. package/src/adapters/google-http.ts +38 -10
  81. package/src/adapters/google-tool-schema.ts +80 -15
  82. package/src/adapters/google-truncation.ts +11 -0
  83. package/src/adapters/google.ts +742 -86
  84. package/src/adapters/identity.ts +39 -6
  85. package/src/adapters/image.ts +1 -1
  86. package/src/adapters/kiro-constants.ts +27 -0
  87. package/src/adapters/kiro-errors.ts +11 -0
  88. package/src/adapters/kiro-events.ts +19 -1
  89. package/src/adapters/kiro-thinking.ts +18 -2
  90. package/src/adapters/kiro-tools.ts +65 -17
  91. package/src/adapters/kiro.ts +270 -73
  92. package/src/adapters/mimo-free.ts +17 -0
  93. package/src/adapters/openai-chat-url.ts +11 -0
  94. package/src/adapters/openai-chat.ts +1377 -344
  95. package/src/adapters/openai-responses-url.ts +16 -0
  96. package/src/adapters/openai-responses.ts +1164 -64
  97. package/src/adapters/registry.ts +175 -0
  98. package/src/adapters/responses-tool-schema.ts +67 -0
  99. package/src/adapters/run-turn-queue.ts +36 -1
  100. package/src/adapters/tool-call-id.ts +119 -0
  101. package/src/adapters/tool-catalog-nudge.ts +105 -21
  102. package/src/adapters/xai-tool-schema.ts +436 -0
  103. package/src/adapters/xai-web-search.ts +186 -0
  104. package/src/bridge.ts +512 -92
  105. package/src/chat/inbound.ts +57 -20
  106. package/src/chat/outbound.ts +97 -33
  107. package/src/claude/agents-inject.ts +40 -10
  108. package/src/claude/context-windows.ts +37 -14
  109. package/src/claude/desktop-3p.ts +243 -9
  110. package/src/claude/gateway-cache.ts +41 -4
  111. package/src/claude/inbound.ts +72 -3
  112. package/src/claude/model-info.ts +38 -15
  113. package/src/claude/outbound.ts +88 -21
  114. package/src/cli/access.ts +46 -3
  115. package/src/cli/account-api.ts +150 -19
  116. package/src/cli/account-auth.ts +33 -6
  117. package/src/cli/account-catalog-refresh.ts +14 -0
  118. package/src/cli/account-extended.ts +648 -28
  119. package/src/cli/account-main.ts +317 -0
  120. package/src/cli/account.ts +97 -19
  121. package/src/cli/agent.ts +53 -2
  122. package/src/cli/alias.ts +66 -0
  123. package/src/cli/capabilities-command.ts +94 -0
  124. package/src/cli/capabilities.ts +496 -0
  125. package/src/cli/claude-agent-startup-sync.ts +73 -0
  126. package/src/cli/claude-desktop.ts +60 -15
  127. package/src/cli/claude.ts +129 -35
  128. package/src/cli/codex-log-guard-doctor.ts +103 -0
  129. package/src/cli/codex-shim-autorestore.ts +2 -0
  130. package/src/cli/codex-shim-readiness.ts +76 -0
  131. package/src/cli/combo.ts +8 -0
  132. package/src/cli/config-command.ts +74 -10
  133. package/src/cli/dispatch.ts +821 -0
  134. package/src/cli/doctor.ts +440 -56
  135. package/src/cli/ensure-desired-integrations.ts +152 -0
  136. package/src/cli/export-command.ts +46 -20
  137. package/src/cli/help.ts +34 -274
  138. package/src/cli/index.ts +417 -528
  139. package/src/cli/init.ts +5 -17
  140. package/src/cli/inspect.ts +230 -0
  141. package/src/cli/integrations.ts +120 -2
  142. package/src/cli/lab.ts +607 -0
  143. package/src/cli/launcher-context.ts +77 -0
  144. package/src/cli/minimax.ts +497 -0
  145. package/src/cli/models-runtime.ts +130 -2
  146. package/src/cli/models.ts +118 -16
  147. package/src/cli/observe.ts +123 -11
  148. package/src/cli/opencode.ts +4 -2
  149. package/src/cli/provider-runtime.ts +34 -3
  150. package/src/cli/provider.ts +25 -3
  151. package/src/cli/ready.ts +301 -0
  152. package/src/cli/registry.ts +476 -0
  153. package/src/cli/root.ts +86 -0
  154. package/src/cli/route-policy.ts +92 -0
  155. package/src/cli/runtime-api.ts +57 -10
  156. package/src/cli/star-prompt.ts +71 -15
  157. package/src/cli/status.ts +51 -4
  158. package/src/cli/storage.ts +234 -0
  159. package/src/cli/system-command.ts +16 -0
  160. package/src/cli/system-restart-client.ts +146 -0
  161. package/src/cli/tray-proxy.ts +153 -6
  162. package/src/cli/usage-report.ts +184 -0
  163. package/src/cli/v2.ts +137 -18
  164. package/src/cli/version-skew.ts +46 -0
  165. package/src/cli.ts +1 -1
  166. package/src/clients/config-export.ts +1442 -23
  167. package/src/clients/effective-status.ts +30 -2
  168. package/src/clients/probes/cline.ts +81 -0
  169. package/src/codex/account-label.ts +35 -1
  170. package/src/codex/account-lifecycle.ts +130 -13
  171. package/src/codex/account-namespaces.ts +49 -3
  172. package/src/codex/account-pause.ts +2 -1
  173. package/src/codex/account-priority.ts +84 -0
  174. package/src/codex/account-store.ts +29 -2
  175. package/src/codex/account-usability.ts +25 -2
  176. package/src/codex/admission.ts +256 -0
  177. package/src/codex/affinity-debug.ts +162 -0
  178. package/src/codex/app-server-processes.ts +570 -107
  179. package/src/codex/app-server-restart-service.ts +232 -0
  180. package/src/codex/auth-api.ts +893 -246
  181. package/src/codex/auth-collision.ts +5 -3
  182. package/src/codex/auth-context.ts +348 -32
  183. package/src/codex/autostart-health.ts +24 -1
  184. package/src/codex/catalog/account-models.ts +67 -0
  185. package/src/codex/catalog/aggregation.ts +86 -10
  186. package/src/codex/catalog/bundled.ts +331 -33
  187. package/src/codex/catalog/effort.ts +138 -32
  188. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  189. package/src/codex/catalog/kinds.ts +2 -0
  190. package/src/codex/catalog/metadata.ts +555 -45
  191. package/src/codex/catalog/native-models.ts +75 -0
  192. package/src/codex/catalog/parsing.ts +269 -30
  193. package/src/codex/catalog/provider-fetch.ts +1626 -144
  194. package/src/codex/catalog/sync.ts +1576 -187
  195. package/src/codex/catalog-admission.ts +199 -0
  196. package/src/codex/catalog-refresh-status.ts +105 -0
  197. package/src/codex/catalog-write-serialization.ts +242 -0
  198. package/src/codex/catalog.ts +6 -3
  199. package/src/codex/codex-write-lock.ts +386 -0
  200. package/src/codex/convergence-types.ts +614 -0
  201. package/src/codex/convergence.ts +676 -0
  202. package/src/codex/coordinator-doctor.ts +332 -0
  203. package/src/codex/custom-model-catalog-migration.ts +176 -0
  204. package/src/codex/desired-state.ts +230 -0
  205. package/src/codex/desktop-app-restart.ts +355 -0
  206. package/src/codex/features.ts +636 -39
  207. package/src/codex/generation.ts +202 -0
  208. package/src/codex/history-job.ts +436 -0
  209. package/src/codex/history-lock.ts +242 -0
  210. package/src/codex/history-manifest.ts +112 -0
  211. package/src/codex/history-migration-guardian.ts +30 -24
  212. package/src/codex/history-provider.ts +1016 -235
  213. package/src/codex/history-transition.ts +105 -0
  214. package/src/codex/history-worker.ts +223 -0
  215. package/src/codex/inject-coordination.ts +373 -0
  216. package/src/codex/inject.ts +1114 -152
  217. package/src/codex/injected-marker.ts +37 -3
  218. package/src/codex/integration-record.ts +266 -0
  219. package/src/codex/internal/catalog-writer.ts +203 -0
  220. package/src/codex/internal/history-writer.ts +81 -0
  221. package/src/codex/journal.ts +66 -4
  222. package/src/codex/log-guard/inspect.ts +524 -0
  223. package/src/codex/log-guard/lock.ts +150 -0
  224. package/src/codex/log-guard/maintenance.ts +403 -0
  225. package/src/codex/log-guard/path-safety.ts +88 -0
  226. package/src/codex/log-guard/policy.ts +44 -0
  227. package/src/codex/log-guard/processes.ts +205 -0
  228. package/src/codex/log-guard/protection.ts +489 -0
  229. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  230. package/src/codex/main-account-cache.ts +24 -0
  231. package/src/codex/main-account.ts +29 -1
  232. package/src/codex/management-convergence.ts +167 -0
  233. package/src/codex/model-cache.ts +56 -10
  234. package/src/codex/model-entitlements.ts +360 -0
  235. package/src/codex/native-main-admission.ts +47 -0
  236. package/src/codex/native-main-auth-temp.ts +187 -0
  237. package/src/codex/native-main-claim.ts +178 -0
  238. package/src/codex/native-main-lock-file.ts +162 -0
  239. package/src/codex/native-main-owner.ts +329 -0
  240. package/src/codex/native-profile-api.ts +247 -0
  241. package/src/codex/native-profile-manager.ts +1531 -0
  242. package/src/codex/native-profile-processes.ts +121 -0
  243. package/src/codex/native-profile-recovery.ts +99 -0
  244. package/src/codex/native-profile-stage-store.ts +387 -0
  245. package/src/codex/native-profile-startup.ts +622 -0
  246. package/src/codex/native-profile-store.ts +855 -0
  247. package/src/codex/native-profile-types.ts +120 -0
  248. package/src/codex/native-residue.ts +675 -0
  249. package/src/codex/paths.ts +80 -1
  250. package/src/codex/plan-from-token.ts +140 -0
  251. package/src/codex/plan.ts +40 -0
  252. package/src/codex/plugins-doctor.ts +1 -1
  253. package/src/codex/pool-rotation.ts +74 -4
  254. package/src/codex/project-config-warnings.ts +20 -6
  255. package/src/codex/prompt-journal.ts +352 -0
  256. package/src/codex/prompt-layers.ts +1313 -0
  257. package/src/codex/prompt-lock.ts +143 -0
  258. package/src/codex/prompt-text-probe.ts +238 -0
  259. package/src/codex/quota-rejection.ts +298 -0
  260. package/src/codex/quota.ts +264 -21
  261. package/src/codex/refresh.ts +11 -2
  262. package/src/codex/reset-credit-recovery.ts +1044 -0
  263. package/src/codex/routing.ts +514 -94
  264. package/src/codex/runtime.ts +159 -38
  265. package/src/codex/shim.ts +1065 -31
  266. package/src/codex/subagent-model-fallback.ts +437 -43
  267. package/src/codex/sync.ts +191 -2
  268. package/src/codex/transition-state.ts +720 -0
  269. package/src/codex/upstream-host-health.ts +368 -0
  270. package/src/codex/user-identity.ts +557 -0
  271. package/src/codex/warmup.ts +187 -81
  272. package/src/codex/write-coordination.ts +114 -0
  273. package/src/combos/failover.ts +47 -0
  274. package/src/combos/index.ts +4 -0
  275. package/src/combos/request.ts +32 -0
  276. package/src/combos/types.ts +91 -9
  277. package/src/compatibility/index.ts +26 -0
  278. package/src/compatibility/manifest.ts +253 -0
  279. package/src/compatibility/openai-responses.ts +121 -0
  280. package/src/config/atomic-write.ts +219 -0
  281. package/src/config/paths.ts +40 -0
  282. package/src/config/process-state.ts +309 -0
  283. package/src/config/provider-name.ts +24 -0
  284. package/src/config/provider-validation.ts +177 -0
  285. package/src/config/rebase-provenance.ts +68 -0
  286. package/src/config.ts +1713 -709
  287. package/src/generated/compatibility-version.json +3324 -0
  288. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  289. package/src/grok/inject.ts +16 -5
  290. package/src/grok/inspect.ts +45 -0
  291. package/src/grok/sync.ts +2 -2
  292. package/src/images/loop.ts +157 -33
  293. package/src/images/plan.ts +24 -13
  294. package/src/integrations/config-io.ts +269 -0
  295. package/src/integrations/journal.ts +315 -0
  296. package/src/integrations/merge.ts +135 -0
  297. package/src/integrations/mutation-flight.ts +71 -0
  298. package/src/integrations/native/ownership-preflight.ts +202 -0
  299. package/src/integrations/omp-yaml-source.ts +358 -0
  300. package/src/integrations/owned-refresh.ts +74 -0
  301. package/src/integrations/ownership-policy.ts +160 -0
  302. package/src/integrations/ownership.ts +155 -0
  303. package/src/integrations/registry.ts +166 -0
  304. package/src/integrations/serialize.ts +314 -0
  305. package/src/integrations/state.ts +433 -0
  306. package/src/integrations/store.ts +103 -0
  307. package/src/integrations/writer-lock.ts +98 -0
  308. package/src/integrations/writer.ts +715 -0
  309. package/src/lab/artifacts/sanitize.ts +586 -0
  310. package/src/lab/artifacts/secure-fs.ts +475 -0
  311. package/src/lab/artifacts/store.ts +310 -0
  312. package/src/lab/automation/budgets.ts +78 -0
  313. package/src/lab/automation/config-persistence.ts +256 -0
  314. package/src/lab/automation/constants.ts +39 -0
  315. package/src/lab/automation/cooldown.ts +103 -0
  316. package/src/lab/automation/dispatch.ts +211 -0
  317. package/src/lab/automation/index.ts +13 -0
  318. package/src/lab/automation/orchestrator.ts +499 -0
  319. package/src/lab/automation/persistence.ts +512 -0
  320. package/src/lab/automation/planner.ts +371 -0
  321. package/src/lab/automation/policy.ts +136 -0
  322. package/src/lab/automation/queue.ts +191 -0
  323. package/src/lab/automation/recovery.ts +24 -0
  324. package/src/lab/automation/route-context.ts +21 -0
  325. package/src/lab/automation/run-key.ts +44 -0
  326. package/src/lab/automation/runs-query.ts +34 -0
  327. package/src/lab/automation/types.ts +160 -0
  328. package/src/lab/conformance/assertion.ts +325 -0
  329. package/src/lab/conformance/digest.ts +22 -0
  330. package/src/lab/conformance/executor.ts +741 -0
  331. package/src/lab/conformance/fixture-provider.ts +27 -0
  332. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  333. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  334. package/src/lab/conformance/harness-budget.ts +47 -0
  335. package/src/lab/conformance/index.ts +5 -0
  336. package/src/lab/conformance/jcs.ts +64 -0
  337. package/src/lab/conformance/json-pointer.ts +39 -0
  338. package/src/lab/conformance/manifest.ts +180 -0
  339. package/src/lab/conformance/mcp-stub.ts +179 -0
  340. package/src/lab/conformance/negative-controls.ts +164 -0
  341. package/src/lab/conformance/observation.ts +355 -0
  342. package/src/lab/conformance/runner.ts +68 -0
  343. package/src/lab/conformance/sse-normalize.ts +59 -0
  344. package/src/lab/conformance/suite-manifest.ts +78 -0
  345. package/src/lab/conformance/types.ts +214 -0
  346. package/src/lab/constants.ts +126 -0
  347. package/src/lab/digest.ts +64 -0
  348. package/src/lab/events/errors.ts +9 -0
  349. package/src/lab/events/limits.ts +117 -0
  350. package/src/lab/events/types.ts +229 -0
  351. package/src/lab/events/validate.ts +781 -0
  352. package/src/lab/fabric/constants.ts +40 -0
  353. package/src/lab/fabric/executor.ts +492 -0
  354. package/src/lab/fabric/index.ts +80 -0
  355. package/src/lab/fabric/manifest.ts +222 -0
  356. package/src/lab/fabric/observe.ts +489 -0
  357. package/src/lab/fabric/patch.ts +79 -0
  358. package/src/lab/fabric/producer-child.ts +139 -0
  359. package/src/lab/fabric/producer-isolate.ts +276 -0
  360. package/src/lab/fabric/producer-protocol.ts +61 -0
  361. package/src/lab/fabric/scratch.ts +439 -0
  362. package/src/lab/fabric/subject.ts +106 -0
  363. package/src/lab/fabric/types.ts +134 -0
  364. package/src/lab/fabric/verifier.ts +98 -0
  365. package/src/lab/index.ts +54 -0
  366. package/src/lab/ledger/artifact-refs.ts +127 -0
  367. package/src/lab/ledger/invalidation.ts +136 -0
  368. package/src/lab/ledger/purge.ts +310 -0
  369. package/src/lab/ledger/store.ts +532 -0
  370. package/src/lab/live/credential-lease.ts +53 -0
  371. package/src/lab/live/destination.ts +155 -0
  372. package/src/lab/live/executor.ts +336 -0
  373. package/src/lab/live/inert-tools.ts +56 -0
  374. package/src/lab/live/manifest.ts +85 -0
  375. package/src/lab/live/mcp-loopback.ts +57 -0
  376. package/src/lab/live/runner.ts +19 -0
  377. package/src/lab/live/sandbox.ts +61 -0
  378. package/src/lab/live/suite-manifest.ts +41 -0
  379. package/src/lab/live/transport.ts +118 -0
  380. package/src/lab/live/types.ts +197 -0
  381. package/src/lab/observe/from-conformance.ts +301 -0
  382. package/src/lab/observe/from-live.ts +117 -0
  383. package/src/lab/paths.ts +153 -0
  384. package/src/lab/projection/rebuild.ts +495 -0
  385. package/src/lab/projection/schema.ts +135 -0
  386. package/src/lab/projection/verdicts.ts +474 -0
  387. package/src/lab/projection/verification.ts +412 -0
  388. package/src/lab/public/bundle.ts +217 -0
  389. package/src/lab/public/community-authority.ts +175 -0
  390. package/src/lab/public/community-files.ts +29 -0
  391. package/src/lab/public/community.ts +479 -0
  392. package/src/lab/public/file-safety.ts +155 -0
  393. package/src/lab/public/ids.ts +26 -0
  394. package/src/lab/public/index.ts +16 -0
  395. package/src/lab/public/mutation-lock.ts +424 -0
  396. package/src/lab/public/operator.ts +353 -0
  397. package/src/lab/public/origin-purge.ts +79 -0
  398. package/src/lab/public/origin.ts +203 -0
  399. package/src/lab/public/privacy.ts +143 -0
  400. package/src/lab/public/private-file.ts +261 -0
  401. package/src/lab/public/project.ts +124 -0
  402. package/src/lab/public/purge-test-fault.ts +21 -0
  403. package/src/lab/public/purge.ts +223 -0
  404. package/src/lab/public/registry.ts +44 -0
  405. package/src/lab/public/revocation.ts +252 -0
  406. package/src/lab/public/signature.ts +243 -0
  407. package/src/lab/public/storage.ts +105 -0
  408. package/src/lab/public/strict-json.ts +206 -0
  409. package/src/lab/public/time.ts +26 -0
  410. package/src/lab/public/types.ts +172 -0
  411. package/src/lab/public/validate.ts +391 -0
  412. package/src/lab/query/catalog.ts +101 -0
  413. package/src/lab/query/connection.ts +107 -0
  414. package/src/lab/query/constants.ts +4 -0
  415. package/src/lab/query/cursor.ts +132 -0
  416. package/src/lab/query/dto-map.ts +277 -0
  417. package/src/lab/query/errors.ts +22 -0
  418. package/src/lab/query/freshness.ts +53 -0
  419. package/src/lab/query/index.ts +45 -0
  420. package/src/lab/query/latest-observation.ts +59 -0
  421. package/src/lab/query/passive-production.ts +159 -0
  422. package/src/lab/query/queries.ts +444 -0
  423. package/src/lab/query/types.ts +266 -0
  424. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  425. package/src/lab/subject/installation-salt.ts +112 -0
  426. package/src/lab/subject/protocol-subject.ts +80 -0
  427. package/src/lab/subject/route-subject.ts +74 -0
  428. package/src/lib/admin-secrets.ts +24 -0
  429. package/src/lib/app-owned-memory-stores.ts +22 -0
  430. package/src/lib/bounded-body.ts +167 -11
  431. package/src/lib/bun-runtime.ts +125 -12
  432. package/src/lib/bun-stream-caps.ts +13 -9
  433. package/src/lib/codex-restart-contract.ts +120 -0
  434. package/src/lib/config-ownership.ts +26 -2
  435. package/src/lib/destination-policy.ts +65 -1
  436. package/src/lib/errors.ts +80 -5
  437. package/src/lib/fabric-task-execution-authority.ts +7 -0
  438. package/src/lib/fabric-task-host.ts +29 -0
  439. package/src/lib/lab-activation.ts +223 -0
  440. package/src/lib/lab-live-execution-authority.ts +13 -0
  441. package/src/lib/lab-live-host.ts +30 -0
  442. package/src/lib/lab-live-pinned-sender.ts +56 -0
  443. package/src/lib/lab-live-route-production.ts +130 -0
  444. package/src/lib/lab-passive-linker-registration.ts +26 -0
  445. package/src/lib/local-management-attestation.ts +51 -0
  446. package/src/lib/local-management-capability.ts +100 -0
  447. package/src/lib/local-provider-reload-contract.ts +100 -0
  448. package/src/lib/optional-shutdown-hooks.ts +57 -0
  449. package/src/lib/package-tree-integrity.ts +101 -0
  450. package/src/lib/pinned-http.ts +145 -26
  451. package/src/lib/process-control.ts +6 -2
  452. package/src/lib/provider-outbound.ts +49 -9
  453. package/src/lib/redact.ts +419 -3
  454. package/src/lib/self-launch-argv.ts +15 -0
  455. package/src/lib/server-resource-ownership.ts +71 -0
  456. package/src/lib/service-secrets.ts +15 -0
  457. package/src/lib/shadow-call.ts +35 -4
  458. package/src/lib/sse-decoder.ts +41 -0
  459. package/src/lib/state-store-registrations.ts +10 -2
  460. package/src/lib/system-restart-contract.ts +73 -0
  461. package/src/lib/token-estimate.ts +19 -2
  462. package/src/lib/tool-argument-integers.ts +253 -0
  463. package/src/lib/translator-budget.ts +44 -0
  464. package/src/lib/upstream-http-version.ts +57 -0
  465. package/src/lib/upstream-reachability.ts +95 -0
  466. package/src/lib/upstream-retry.ts +156 -3
  467. package/src/lib/windows-atomic-replace.ts +155 -0
  468. package/src/lib/windows-elevation.ts +70 -2
  469. package/src/lib/windows-secret-acl.ts +409 -69
  470. package/src/lib/windows-service-wrappers.ts +72 -0
  471. package/src/lib/windows-text.ts +106 -0
  472. package/src/lib/windows-user-principal.ts +341 -0
  473. package/src/lib/winsw.ts +33 -5
  474. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  475. package/src/oauth/account-import/index.ts +15 -0
  476. package/src/oauth/account-import/parser.ts +83 -0
  477. package/src/oauth/account-import/registry.ts +18 -0
  478. package/src/oauth/account-import/service.ts +75 -0
  479. package/src/oauth/account-import/types.ts +91 -0
  480. package/src/oauth/anthropic.ts +12 -1
  481. package/src/oauth/callback-server.ts +30 -4
  482. package/src/oauth/chatgpt.ts +12 -1
  483. package/src/oauth/cline.ts +203 -0
  484. package/src/oauth/command-code.ts +239 -0
  485. package/src/oauth/cursor.ts +46 -5
  486. package/src/oauth/generic-account-failover.ts +231 -0
  487. package/src/oauth/google-antigravity.ts +35 -3
  488. package/src/oauth/health.ts +20 -12
  489. package/src/oauth/index.ts +462 -71
  490. package/src/oauth/key-providers.ts +25 -0
  491. package/src/oauth/kimi.ts +25 -3
  492. package/src/oauth/kiro.ts +95 -6
  493. package/src/oauth/local-token-detect.ts +13 -2
  494. package/src/oauth/log.ts +3 -1
  495. package/src/oauth/login-cli.ts +88 -28
  496. package/src/oauth/nous.ts +798 -0
  497. package/src/oauth/open-browser-choice.ts +26 -0
  498. package/src/oauth/store.ts +133 -26
  499. package/src/oauth/token-guardian.ts +9 -3
  500. package/src/oauth/types.ts +15 -0
  501. package/src/pi/models.ts +2 -2
  502. package/src/providers/alibaba-region-migration.ts +1 -1
  503. package/src/providers/antigravity-models.ts +521 -31
  504. package/src/providers/auto-compact-budget.ts +65 -0
  505. package/src/providers/base-url-choices.ts +10 -0
  506. package/src/providers/codex-capacity.ts +292 -0
  507. package/src/providers/command-code-efforts.ts +176 -0
  508. package/src/providers/context-cap.ts +26 -8
  509. package/src/providers/cursor-pool.ts +72 -0
  510. package/src/providers/default-aliases.ts +65 -0
  511. package/src/providers/derive.ts +281 -6
  512. package/src/providers/fastwire.ts +507 -0
  513. package/src/providers/free-directory.ts +10 -7
  514. package/src/providers/google-vertex-location.ts +14 -0
  515. package/src/providers/key-failover.ts +71 -3
  516. package/src/providers/label.ts +35 -2
  517. package/src/providers/model-discovery-limits.ts +16 -0
  518. package/src/providers/model-discovery.ts +115 -22
  519. package/src/providers/model-presets.ts +119 -0
  520. package/src/providers/model-rename-migration.ts +255 -0
  521. package/src/providers/model-rename-startup.ts +28 -0
  522. package/src/providers/new-model-policy.ts +146 -0
  523. package/src/providers/openai-sidecar.ts +72 -4
  524. package/src/providers/openai-tier-startup.ts +31 -2
  525. package/src/providers/openai-tiers.ts +119 -4
  526. package/src/providers/openai-virtual-models.ts +1 -0
  527. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  528. package/src/providers/provider-id-rewrite.ts +30 -0
  529. package/src/providers/quota.ts +1379 -40
  530. package/src/providers/registry.ts +1545 -112
  531. package/src/providers/request-pacing.ts +310 -0
  532. package/src/providers/service-tier.ts +277 -0
  533. package/src/providers/slug-codec.ts +94 -6
  534. package/src/providers/static-model-discovery.ts +86 -0
  535. package/src/providers/xai-responses-opt-in.ts +15 -0
  536. package/src/providers/xai-transport.ts +32 -4
  537. package/src/reasoning-effort.ts +68 -3
  538. package/src/responses/apply-patch-envelope.ts +63 -0
  539. package/src/responses/code-mode-helper-compat.ts +50 -0
  540. package/src/responses/compaction.ts +26 -1
  541. package/src/responses/custom-tool-compat.ts +384 -0
  542. package/src/responses/hosted-tool-policy.ts +9 -0
  543. package/src/responses/namespace-tool-compat.ts +435 -0
  544. package/src/responses/parser.ts +225 -38
  545. package/src/responses/provider-continuation.ts +98 -0
  546. package/src/responses/provider-opaque-metadata.ts +73 -0
  547. package/src/responses/reasoning-envelope.ts +9 -1
  548. package/src/responses/reasoning-replay-cache.ts +504 -0
  549. package/src/responses/schema.ts +12 -2
  550. package/src/responses/spill-store.ts +75 -10
  551. package/src/responses/state.ts +659 -31
  552. package/src/responses/thought-signature-replay.ts +364 -0
  553. package/src/responses/tool-search-compat.ts +301 -0
  554. package/src/responses/truncated-stop-reason.ts +60 -0
  555. package/src/responses/turn-termination.ts +107 -0
  556. package/src/router.ts +405 -31
  557. package/src/routing/analytics.ts +379 -0
  558. package/src/routing/capability.ts +244 -0
  559. package/src/routing/compatibility/assemble.ts +73 -0
  560. package/src/routing/compatibility/behavior.ts +278 -0
  561. package/src/routing/compatibility/catalog.ts +99 -0
  562. package/src/routing/compatibility/endpoint.ts +52 -0
  563. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  564. package/src/routing/compatibility/policy.ts +181 -0
  565. package/src/routing/compatibility/provider-slot.ts +56 -0
  566. package/src/routing/compatibility/reader.ts +110 -0
  567. package/src/routing/compatibility/subject.ts +191 -0
  568. package/src/routing/compatibility/types.ts +64 -0
  569. package/src/routing/compatibility/version.ts +104 -0
  570. package/src/routing/cost.ts +77 -0
  571. package/src/routing/evaluator.ts +495 -0
  572. package/src/routing/health.ts +412 -0
  573. package/src/routing/history/cursor.ts +43 -0
  574. package/src/routing/history/indexer.ts +605 -0
  575. package/src/routing/history/schema.ts +72 -0
  576. package/src/routing/profile-namespace.ts +15 -0
  577. package/src/routing/profile.ts +547 -0
  578. package/src/routing/quota.ts +155 -0
  579. package/src/routing/request-evidence.ts +45 -0
  580. package/src/routing/trace.ts +776 -0
  581. package/src/server/adapter-resolve.ts +2 -29
  582. package/src/server/auth-cors.ts +289 -48
  583. package/src/server/background-lifecycle.ts +182 -0
  584. package/src/server/chat-completions.ts +154 -72
  585. package/src/server/chat-native-sse.ts +331 -0
  586. package/src/server/chat-native.ts +445 -0
  587. package/src/server/claude-messages.ts +160 -44
  588. package/src/server/direct-local-http.ts +347 -0
  589. package/src/server/effort-policy.ts +18 -0
  590. package/src/server/github-copilot-responses-repair.ts +338 -0
  591. package/src/server/gui-static.ts +39 -10
  592. package/src/server/images.ts +94 -12
  593. package/src/server/index.ts +1021 -190
  594. package/src/server/lifecycle.ts +336 -14
  595. package/src/server/live.ts +136 -17
  596. package/src/server/local-management-read-client.ts +90 -0
  597. package/src/server/local-provider-reload-client.ts +137 -0
  598. package/src/server/management/agent-settings-routes.ts +433 -116
  599. package/src/server/management/api-key-usage.ts +31 -5
  600. package/src/server/management/body.ts +6 -0
  601. package/src/server/management/codex-prompt-routes.ts +570 -0
  602. package/src/server/management/combo-routes.ts +64 -25
  603. package/src/server/management/config-routes.ts +511 -51
  604. package/src/server/management/context.ts +89 -2
  605. package/src/server/management/integration-routes.ts +498 -0
  606. package/src/server/management/lab-automation-routes.ts +206 -0
  607. package/src/server/management/lab-routes.ts +563 -0
  608. package/src/server/management/logs-usage-routes.ts +127 -52
  609. package/src/server/management/model-routes.ts +461 -133
  610. package/src/server/management/model-rows.ts +167 -0
  611. package/src/server/management/native-integration-routes.ts +770 -0
  612. package/src/server/management/oauth-account-routes.ts +90 -8
  613. package/src/server/management/provider-capability-config.ts +48 -0
  614. package/src/server/management/provider-routes.ts +836 -159
  615. package/src/server/management/request-history-routes.ts +191 -0
  616. package/src/server/management/route-registry.ts +332 -0
  617. package/src/server/management/routing-analytics-routes.ts +74 -0
  618. package/src/server/management/routing-profile-routes.ts +380 -0
  619. package/src/server/management/shared.ts +27 -11
  620. package/src/server/management/sidebar-routes.ts +47 -31
  621. package/src/server/management/storage-log-guard-routes.ts +186 -0
  622. package/src/server/management/sync-response.ts +69 -0
  623. package/src/server/management/system-restart.ts +289 -33
  624. package/src/server/management/system-routes.ts +77 -0
  625. package/src/server/management/usage-summary-cache.ts +9 -1
  626. package/src/server/management/vision-sidecar-options.ts +167 -0
  627. package/src/server/management/web-search-sidecar-options.ts +120 -0
  628. package/src/server/management-api.ts +126 -23
  629. package/src/server/management-auth.ts +220 -5
  630. package/src/server/passive-route-linker.ts +66 -0
  631. package/src/server/port-reclaim.ts +1 -1
  632. package/src/server/ports.ts +41 -1
  633. package/src/server/proxy-liveness.ts +161 -10
  634. package/src/server/readiness.ts +99 -0
  635. package/src/server/relay-eager.ts +221 -54
  636. package/src/server/relay.ts +479 -87
  637. package/src/server/request-decompress.ts +113 -6
  638. package/src/server/request-log-conversation.ts +51 -0
  639. package/src/server/request-log.ts +298 -31
  640. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  641. package/src/server/responses/agent-task-recovery.ts +465 -0
  642. package/src/server/responses/codex-auth-error.ts +55 -0
  643. package/src/server/responses/collaboration.ts +239 -36
  644. package/src/server/responses/combo-stream-preflight.ts +178 -0
  645. package/src/server/responses/compact.ts +444 -72
  646. package/src/server/responses/core.ts +3579 -436
  647. package/src/server/responses/empty-completion-guard.ts +333 -0
  648. package/src/server/responses/encrypted-payload.ts +62 -39
  649. package/src/server/responses/fetch-helpers.ts +89 -99
  650. package/src/server/responses/input-admission.ts +187 -0
  651. package/src/server/responses/pacing-overload.ts +13 -0
  652. package/src/server/responses/passthrough-error.ts +33 -9
  653. package/src/server/responses/policy-fallback.ts +178 -0
  654. package/src/server/responses/responses-field-backfill.ts +343 -0
  655. package/src/server/responses/terminal-guard.ts +26 -5
  656. package/src/server/responses/upstream-error.ts +5 -0
  657. package/src/server/responses/ws-upstream.ts +381 -0
  658. package/src/server/responses-custom-tool-repair.ts +363 -0
  659. package/src/server/responses-item-id-repair.ts +54 -6
  660. package/src/server/responses-json-events.ts +90 -0
  661. package/src/server/responses-model-rewrite.ts +29 -0
  662. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  663. package/src/server/responses-snapshot-repair.ts +621 -0
  664. package/src/server/responses-terminal-repair.ts +363 -0
  665. package/src/server/responses-tool-search-repair.ts +267 -0
  666. package/src/server/responses-undeclared-tool-guard.ts +376 -0
  667. package/src/server/responses.ts +18 -2
  668. package/src/server/search.ts +78 -13
  669. package/src/server/sse-frame-buffer.ts +319 -0
  670. package/src/server/sse-payload-rewrite.ts +110 -22
  671. package/src/server/startup-action-control.ts +8 -1
  672. package/src/server/startup-health-cache.ts +19 -1
  673. package/src/server/system-env.ts +80 -9
  674. package/src/server/ws-bridge.ts +53 -40
  675. package/src/service-manager-probe.ts +892 -0
  676. package/src/service.ts +1153 -94
  677. package/src/sidecar/auth.ts +92 -0
  678. package/src/sidecar/candidates.ts +83 -0
  679. package/src/storage/cleanup.ts +2 -2
  680. package/src/storage/policy-job.ts +14 -4
  681. package/src/storage/policy.ts +88 -23
  682. package/src/storage/scanner.ts +1 -1
  683. package/src/storage/worker-lifecycle.ts +14 -14
  684. package/src/tray/windows-tray.ps1 +83 -9
  685. package/src/tray/windows.ts +43 -16
  686. package/src/types/accounts.ts +37 -0
  687. package/src/types/config.ts +911 -0
  688. package/src/types/provider.ts +614 -0
  689. package/src/types/request.ts +397 -0
  690. package/src/types/tools.ts +236 -0
  691. package/src/types/wire.ts +80 -0
  692. package/src/types.ts +107 -1237
  693. package/src/update/index.ts +37 -23
  694. package/src/update/job.ts +445 -68
  695. package/src/update/notify.ts +12 -6
  696. package/src/update/npm-cache-preflight.d.mts +47 -0
  697. package/src/update/npm-cache-preflight.mjs +201 -0
  698. package/src/update/transactional-install.d.mts +22 -0
  699. package/src/update/transactional-install.mjs +266 -0
  700. package/src/usage/cost.ts +0 -0
  701. package/src/usage/expected-prices.ts +287 -16
  702. package/src/usage/log.ts +666 -50
  703. package/src/usage/summary.ts +388 -17
  704. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  705. package/src/usage/user-cost-overlays.ts +314 -0
  706. package/src/vision/anthropic-describe.ts +10 -6
  707. package/src/vision/backends.ts +97 -0
  708. package/src/vision/describe.ts +27 -16
  709. package/src/vision/eligibility.ts +250 -0
  710. package/src/vision/index.ts +238 -24
  711. package/src/vision/reasoning.ts +55 -0
  712. package/src/vision/routed-describe.ts +175 -0
  713. package/src/vision/timeout-bounds.ts +9 -0
  714. package/src/web-search/anthropic-executor.ts +13 -7
  715. package/src/web-search/backends.ts +108 -0
  716. package/src/web-search/exa-executor.ts +119 -0
  717. package/src/web-search/executor.ts +21 -6
  718. package/src/web-search/gemini-executor.ts +141 -0
  719. package/src/web-search/index.ts +150 -15
  720. package/src/web-search/loop.ts +284 -54
  721. package/src/web-search/parse.ts +125 -30
  722. package/src/web-search/sources.ts +60 -0
  723. package/src/web-search/xai-executor.ts +219 -0
  724. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  725. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  726. package/gui/dist/provider-icons/antigravity.svg +0 -1
  727. package/gui/dist/provider-icons/claude.svg +0 -1
  728. package/gui/dist/provider-icons/copilot.svg +0 -1
  729. package/gui/dist/provider-icons/cursor.svg +0 -2
  730. package/gui/dist/provider-icons/gemini.svg +0 -1
  731. package/gui/dist/provider-icons/grok-color.svg +0 -1
  732. package/gui/dist/provider-icons/kiro.svg +0 -14
  733. package/src/cli/internal-dispatch.ts +0 -20
@@ -29,6 +29,20 @@ export function encodeRoutedModelId(id: string): string {
29
29
  return id.includes("/") ? id.replaceAll("/", SLUG_ALIAS_SEPARATOR) : id;
30
30
  }
31
31
 
32
+ /**
33
+ * True when `modelId` shares a Codex-facing encoded form with a different known id.
34
+ * That collision is what makes `provider/openai-gpt-5.5` decode to native `openai-gpt-5.5`
35
+ * while a custom `openai/gpt-5.5` row is still visible.
36
+ */
37
+ export function encodedModelIdCollides(modelId: string, knownIds: Iterable<string>): boolean {
38
+ const encoded = encodeRoutedModelId(modelId);
39
+ for (const id of knownIds) {
40
+ if (id === modelId) continue;
41
+ if (encodeRoutedModelId(id) === encoded) return true;
42
+ }
43
+ return false;
44
+ }
45
+
32
46
  /** Codex-facing routed slug: exactly one "/" — `<provider>/<encoded id>`. */
33
47
  export function routedSlug(provider: string, id: string): string {
34
48
  return `${provider}/${encodeRoutedModelId(id)}`;
@@ -51,17 +65,91 @@ export function decodeRoutedModelId(requested: string, knownIds: Iterable<string
51
65
  return aliasMatch ?? requested;
52
66
  }
53
67
 
68
+ /**
69
+ * Decode a Codex-facing id, but fail when a custom slash id and another known id
70
+ * share the same encoded form. Write-time checks cannot cover a later live cache.
71
+ */
72
+ export function decodeRoutedModelIdOrThrow(requested: string, knownIds: Iterable<string>): string {
73
+ const ids = [...knownIds];
74
+ const encodedRequested = encodeRoutedModelId(requested);
75
+ const matches = new Set<string>();
76
+ for (const id of ids) {
77
+ if (id === requested || encodeRoutedModelId(id) === encodedRequested) matches.add(id);
78
+ }
79
+ if (matches.size > 1) throw new Error(`ambiguous model id "${requested}"`);
80
+ return decodeRoutedModelId(requested, ids);
81
+ }
82
+
54
83
  /** Does a stored config slug name this routed model, in either raw or encoded form? */
55
84
  export function slugEquals(stored: string, provider: string, id: string): boolean {
56
85
  return stored === `${provider}/${id}` || stored === routedSlug(provider, id);
57
86
  }
58
87
 
88
+ /** Stable key for the exact equivalence relation used by catalog/config slug matching. */
89
+ export function slugEquivalenceKey(slug: string): string {
90
+ const slash = slug.indexOf("/");
91
+ return slash <= 0
92
+ ? JSON.stringify(["exact", slug])
93
+ : JSON.stringify([
94
+ "routed",
95
+ slug.slice(0, slash),
96
+ encodeRoutedModelId(slug.slice(slash + 1)),
97
+ ]);
98
+ }
99
+
59
100
  /** Equivalence between two routed slugs regardless of raw/encoded mix. */
60
101
  export function slugsEquivalent(a: string, b: string): boolean {
61
- if (a === b) return true;
62
- const pa = a.indexOf("/");
63
- const pb = b.indexOf("/");
64
- if (pa <= 0 || pb <= 0) return false;
65
- if (a.slice(0, pa) !== b.slice(0, pb)) return false;
66
- return encodeRoutedModelId(a.slice(pa + 1)) === encodeRoutedModelId(b.slice(pb + 1));
102
+ return a === b || slugEquivalenceKey(a) === slugEquivalenceKey(b);
103
+ }
104
+
105
+ /**
106
+ * Resolve one config selection against a provider's known native ids (#2491).
107
+ *
108
+ * `slugEquivalenceKey` is deliberately lossy — the Codex one-slash rule forces `a/b` and
109
+ * `a-b` onto the same encoded form — so a selection written in either spelling matches BOTH
110
+ * when a provider publishes both. Filtering and persisted sync share that key, which keeps
111
+ * them consistent with each other but silently over-grants.
112
+ *
113
+ * This resolver keeps the tolerant behaviour (a selection still matches through either
114
+ * spelling, and an id absent from an incomplete live roster still resolves) while reporting
115
+ * whether the match was EXACT or merely equivalent. A caller that can afford to be strict —
116
+ * one holding a complete known-id set — can then prefer the exact row instead of granting the
117
+ * whole collision class.
118
+ *
119
+ * Returning the ambiguity rather than resolving it is deliberate: the roster is an incomplete
120
+ * dictionary, so silently narrowing to the exact spelling would hide a published id whenever
121
+ * discovery omitted it. The caller owns that tradeoff because only the caller knows whether
122
+ * its id set is complete.
123
+ */
124
+ export interface SlugSelectionMatch {
125
+ /** Native ids this selection admits. */
126
+ readonly matched: readonly string[];
127
+ /** The id whose raw form the selection names exactly, when one exists. */
128
+ readonly exact: string | undefined;
129
+ /** True when more than one known id shares the selection's encoded form. */
130
+ readonly ambiguous: boolean;
131
+ }
132
+
133
+ export function resolveSlugSelection(
134
+ provider: string,
135
+ selection: string,
136
+ knownIds: Iterable<string>,
137
+ ): SlugSelectionMatch {
138
+ // A slash in the selection is ambiguous on its own: `p/a-b` is provider-qualified, while
139
+ // `a/b` is a bare NATIVE id that happens to contain a slash. Treating every slash-bearing
140
+ // selection as provider-qualified made `a/b` resolve against provider "a", so the same
141
+ // collision reported ambiguous through the dash spelling and unambiguous through the slash
142
+ // spelling — the exact asymmetry this resolver exists to remove.
143
+ const qualified = selection.startsWith(`${provider}/`)
144
+ ? selection
145
+ : routedSlug(provider, selection);
146
+ const selectionKey = slugEquivalenceKey(qualified);
147
+ const matched: string[] = [];
148
+ let exact: string | undefined;
149
+ for (const id of knownIds) {
150
+ if (slugEquivalenceKey(routedSlug(provider, id)) !== selectionKey) continue;
151
+ matched.push(id);
152
+ if (id === selection || `${provider}/${id}` === selection) exact = id;
153
+ }
154
+ return { matched, exact, ambiguous: matched.length > 1 };
67
155
  }
@@ -0,0 +1,86 @@
1
+ import type { OcxProviderConfig } from "../types";
2
+ import {
3
+ getProviderRegistryEntry,
4
+ providerMatchesRegistryTransport,
5
+ type ProviderRegistryEntry,
6
+ } from "./registry";
7
+
8
+ const STATIC_MODEL_CATALOG_PROVIDER_IDS = new Set(["cline-pass", "mimo-free"]);
9
+
10
+ function normalizedEndpoint(value: string): string {
11
+ const trimmed = value.trim();
12
+ try {
13
+ const parsed = new URL(trimmed);
14
+ parsed.pathname = parsed.pathname.replace(/\/+$/, "") || "/";
15
+ return parsed.toString().replace(/\/$/, "");
16
+ } catch {
17
+ return trimmed.replace(/\/+$/, "");
18
+ }
19
+ }
20
+
21
+ function exactRegistryTransportMatch(
22
+ entry: ProviderRegistryEntry,
23
+ provider: Pick<OcxProviderConfig, "baseUrl" | "adapter"> & Partial<Pick<OcxProviderConfig, "authMode">>,
24
+ options: { allowLegacyMimoLocal?: boolean } = {},
25
+ ): boolean {
26
+ if (entry.allowBaseUrlOverride || /\{[^}]*\}/.test(entry.baseUrl)) return false;
27
+ if (typeof provider.baseUrl !== "string" || provider.adapter !== entry.adapter) return false;
28
+ const legacyMimoLocal = options.allowLegacyMimoLocal === true
29
+ && entry.id === "mimo-free"
30
+ && provider.authMode === "local";
31
+ if (provider.authMode !== undefined && provider.authMode !== "key" && !legacyMimoLocal) return false;
32
+ return normalizedEndpoint(provider.baseUrl) === normalizedEndpoint(entry.baseUrl);
33
+ }
34
+
35
+ /** Registry policy for providers whose maintained model list is authoritative. */
36
+ export function registryEntrySupportsLiveModelDiscovery(entry: ProviderRegistryEntry): boolean {
37
+ return !STATIC_MODEL_CATALOG_PROVIDER_IDS.has(entry.id);
38
+ }
39
+
40
+ /**
41
+ * Static-catalog authority is tied to canonical provider identity and exact transport.
42
+ * Renamed/custom rows stay operator-owned: Cline and ClinePass intentionally share a transport,
43
+ * so destination matching alone cannot safely identify a renamed ClinePass configuration.
44
+ */
45
+ export function staticModelCatalogEntryForProvider(
46
+ name: string,
47
+ provider: OcxProviderConfig,
48
+ ): ProviderRegistryEntry | undefined {
49
+ const entry = getProviderRegistryEntry(name);
50
+ if (!entry || !STATIC_MODEL_CATALOG_PROVIDER_IDS.has(entry.id)) return undefined;
51
+ return exactRegistryTransportMatch(entry, provider, { allowLegacyMimoLocal: true })
52
+ ? entry
53
+ : undefined;
54
+ }
55
+
56
+ export function providerSupportsLiveModelDiscovery(name: string, provider: OcxProviderConfig): boolean {
57
+ return staticModelCatalogEntryForProvider(name, provider) === undefined;
58
+ }
59
+
60
+ /**
61
+ * MiMo Free predates collision preservation in the registry. Keep same-named custom rows out of
62
+ * registry ownership without broadening the generic transport matcher to other key providers.
63
+ */
64
+ export function providerMatchesRegistryTransportWithStaticGuards(
65
+ name: string,
66
+ provider: Pick<OcxProviderConfig, "baseUrl" | "adapter"> & Partial<Pick<OcxProviderConfig, "authMode">>,
67
+ ): boolean {
68
+ if (name !== "mimo-free") return providerMatchesRegistryTransport(name, provider);
69
+ const entry = getProviderRegistryEntry(name);
70
+ return entry !== undefined
71
+ && exactRegistryTransportMatch(entry, provider, { allowLegacyMimoLocal: true });
72
+ }
73
+
74
+ /** Repair only registry-owned legacy state; operator-owned model lists stay untouched. */
75
+ export function repairStaticModelCatalogProvider(name: string, provider: OcxProviderConfig): void {
76
+ const entry = staticModelCatalogEntryForProvider(name, provider);
77
+ if (!entry) return;
78
+ provider.liveModels = false;
79
+ if (
80
+ name === "mimo-free"
81
+ && entry.id === "mimo-free"
82
+ && (provider.authMode === undefined || provider.authMode === "local")
83
+ ) {
84
+ provider.authMode = "key";
85
+ }
86
+ }
@@ -0,0 +1,15 @@
1
+ import type { OcxProviderConfig } from "../types";
2
+
3
+ export const XAI_RESPONSES_OPT_IN_MODELS = ["grok-4.6", "grok-4.5"] as const;
4
+
5
+ export type XaiResponsesOptInState = boolean | "mixed";
6
+
7
+ /** Derived dashboard/API state for the two modelAdapters entries owned by the xAI opt-in. */
8
+ export function xaiResponsesOptInState(provider: OcxProviderConfig): XaiResponsesOptInState {
9
+ const enabled = XAI_RESPONSES_OPT_IN_MODELS.map(
10
+ model => provider.modelAdapters?.[model] === "openai-responses",
11
+ );
12
+ if (enabled.every(Boolean)) return true;
13
+ if (enabled.some(Boolean)) return "mixed";
14
+ return false;
15
+ }
@@ -4,6 +4,27 @@ import { resolveGithubCopilotTransport } from "./github-copilot-transport";
4
4
 
5
5
  export const XAI_GROK_CLI_BASE_URL = "https://cli-chat-proxy.grok.com/v1";
6
6
 
7
+ /** The two hosts that serve xAI's Responses API: the public API and the Grok CLI proxy. */
8
+ const XAI_RESPONSES_HOSTS = new Set(["api.x.ai", "cli-chat-proxy.grok.com"]);
9
+
10
+ /**
11
+ * True when this provider's Responses traffic terminates at xAI itself.
12
+ *
13
+ * Probed 2026-08-22 one field per request: the two hosts accept and refuse exactly the same
14
+ * web_search fields, so they are one dialect rather than two. Matching is exact-host over
15
+ * https, which keeps lookalikes (`api.x.ai.evil.test`) and nonstandard ports out.
16
+ */
17
+ export function isXaiResponsesDestination(provider: Pick<OcxProviderConfig, "baseUrl">): boolean {
18
+ try {
19
+ const url = new URL(provider.baseUrl);
20
+ return url.protocol === "https:"
21
+ && XAI_RESPONSES_HOSTS.has(url.hostname.toLowerCase())
22
+ && (url.port === "" || url.port === "443");
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
27
+
7
28
  export const XAI_GROK_COMPATIBILITY = {
8
29
  version: "0.2.93",
9
30
  userAgent: "opencodex-grok/0.2.93",
@@ -53,7 +74,7 @@ function withoutUserOverridden(
53
74
 
54
75
  function withGeneratedRequestId(
55
76
  init: RequestInit | undefined,
56
- configuredRequestId: string | undefined,
77
+ pinnedRequestId: string,
57
78
  stableHeaders: Readonly<Record<string, string>>,
58
79
  ): RequestInit {
59
80
  const headers = new Headers(init?.headers);
@@ -63,7 +84,7 @@ function withGeneratedRequestId(
63
84
  if (!headers.has(XAI_GROK_COMPATIBILITY.headers.requestId)) {
64
85
  headers.set(
65
86
  XAI_GROK_COMPATIBILITY.headers.requestId,
66
- configuredRequestId ?? randomUUID(),
87
+ pinnedRequestId,
67
88
  );
68
89
  }
69
90
  return { ...init, headers };
@@ -83,7 +104,9 @@ export function deriveXaiConvId(promptCacheKey: string): string {
83
104
 
84
105
  /**
85
106
  * Resolve xAI's runtime transport without mutating persisted config. Conversation/session
86
- * affinity is stable for this resolved transport; request identity is generated per fetch.
107
+ * affinity is stable for this resolved transport; request identity is pinned per resolved
108
+ * transport (= per logical request until key rotation), so same-target replays and transient
109
+ * retries carry the same id while a rotated key gets a fresh one.
87
110
  * Agent, deployment, model-override, turn, mode, and user identity headers are intentionally
88
111
  * omitted because opencodex has no truthful values for the official fields.
89
112
  */
@@ -128,9 +151,14 @@ export function resolveProviderTransport(
128
151
  provider.headers,
129
152
  XAI_GROK_COMPATIBILITY.headers.requestId,
130
153
  );
154
+ // Pin the request id per resolved transport (= per logical request until key rotation):
155
+ // same-target 429 replays must carry the SAME x-grok-req-id as the original dispatch, and
156
+ // transient retries reuse one id so the upstream can dedupe them. A rotated key resolves a
157
+ // fresh transport, which gets its own id.
158
+ const requestId = configuredRequestId ?? randomUUID();
131
159
  const baseFetch = provider.fetch ?? globalThis.fetch;
132
160
  const attemptFetch = ((input, init) =>
133
- baseFetch(input, withGeneratedRequestId(init, configuredRequestId, stableHeaders))) as typeof globalThis.fetch;
161
+ baseFetch(input, withGeneratedRequestId(init, requestId, stableHeaders))) as typeof globalThis.fetch;
134
162
 
135
163
  return {
136
164
  ...provider,
@@ -14,11 +14,67 @@ export const CODEX_REASONING_LEVELS: { effort: string; description: string }[] =
14
14
  const CODEX_REASONING_ORDER = CODEX_REASONING_LEVELS.map(l => l.effort);
15
15
  const CODEX_REASONING_SET = new Set(CODEX_REASONING_ORDER);
16
16
 
17
+ /**
18
+ * Sentinel wire value in reasoningEffortMap / modelReasoningEffortMap to explicitly
19
+ * omit the reasoning_effort field from the upstream wire request (issue #2356).
20
+ */
21
+ export const REASONING_EFFORT_OMIT_SENTINEL = "__omit__";
22
+
23
+ export function isReasoningEffortOmitted(wireEffort: string | undefined): boolean {
24
+ return wireEffort === REASONING_EFFORT_OMIT_SENTINEL;
25
+ }
26
+
17
27
  /** True when `effort` is a member of the Codex reasoning ladder (low..ultra). */
18
28
  export function isCodexReasoningEffort(effort: string): boolean {
19
29
  return CODEX_REASONING_SET.has(effort);
20
30
  }
21
31
 
32
+ /**
33
+ * True for ladder members plus the `none`/`minimal` sentinels. Both are valid declared
34
+ * efforts (OpenAI accepts `minimal`; Codex validates `none` against
35
+ * `supported_reasoning_levels` for no-reasoning subagent spawns, #883/#962) but are NOT
36
+ * part of the low..ultra ladder: they never appear in default ladders, ranks, or clamps
37
+ * (`minimal` is mapped to `low` on the wire by requestToCodexEffort).
38
+ */
39
+ export function isDeclaredReasoningEffort(effort: string): boolean {
40
+ return effort === "none" || effort === "minimal" || CODEX_REASONING_SET.has(effort);
41
+ }
42
+
43
+ /**
44
+ * Reorder any declared subset (low..ultra, plus the optional `none`/`minimal` sentinels
45
+ * first, in that order) into canonical order and drop duplicates. Catalog
46
+ * `supported_reasoning_levels` follow the input order and the fallback default picks the
47
+ * first entry, so a caller-chosen order would otherwise leak into the catalog.
48
+ */
49
+ export function canonicalizeReasoningEfforts(values: readonly string[]): string[] {
50
+ const seen = new Set(values);
51
+ const ordered = CODEX_REASONING_ORDER.filter(effort => seen.has(effort));
52
+ const sentinels = ["none", "minimal"].filter(effort => seen.has(effort));
53
+ return [...sentinels, ...ordered];
54
+ }
55
+
56
+ /**
57
+ * Reasoning ladder accepted for the OpenAI vision sidecar. `ultra` is deliberately excluded:
58
+ * the vision describer is a single helper call, and `ultra` would be collapsed to `max` by the
59
+ * upstream client boundary anyway.
60
+ */
61
+ export const VISION_REASONING_EFFORTS = ["low", "medium", "high", "xhigh", "max"] as const;
62
+ export type VisionReasoningEffort = typeof VISION_REASONING_EFFORTS[number];
63
+
64
+ /** True when `effort` is one of the vision sidecar's supported Responses reasoning levels. */
65
+ export function isVisionReasoningEffort(effort: unknown): effort is VisionReasoningEffort {
66
+ return typeof effort === "string" && (VISION_REASONING_EFFORTS as readonly string[]).includes(effort);
67
+ }
68
+
69
+ /**
70
+ * Normalize a persisted/configured vision reasoning value. Invalid values (hand-edited config,
71
+ * stale files) degrade to `undefined` so the caller falls back to the documented default instead
72
+ * of forwarding an upstream-rejected effort.
73
+ */
74
+ export function sanitizeVisionReasoning(effort: unknown): VisionReasoningEffort | undefined {
75
+ return isVisionReasoningEffort(effort) ? effort : undefined;
76
+ }
77
+
22
78
  /** Position of `effort` in the Codex ladder (low=0 .. ultra=5), or -1 when not a ladder member. */
23
79
  export function codexEffortRank(effort: string): number {
24
80
  return CODEX_REASONING_ORDER.indexOf(effort);
@@ -44,7 +100,9 @@ export function sanitizeCodexReasoningEfforts(efforts: readonly string[] | undef
44
100
  const seen = new Set<string>();
45
101
  const out: string[] = [];
46
102
  for (const effort of efforts) {
47
- if (!CODEX_REASONING_SET.has(effort) || seen.has(effort)) continue;
103
+ // `none`/`minimal` are valid declared sentinels, kept and sorted first (rank -1); they
104
+ // never appear in the default ladder.
105
+ if ((effort !== "none" && effort !== "minimal" && !CODEX_REASONING_SET.has(effort)) || seen.has(effort)) continue;
48
106
  seen.add(effort);
49
107
  out.push(effort);
50
108
  }
@@ -122,7 +180,10 @@ export function mapReasoningEffort(provider: OcxProviderConfig, modelId: string,
122
180
  const boundary = requested === "ultra" ? "max" : requested;
123
181
 
124
182
  const wireMap = reasoningEffortMapFor(provider, modelId);
125
- if (wireMap && Object.prototype.hasOwnProperty.call(wireMap, boundary)) return wireMap[boundary];
183
+ if (wireMap && Object.prototype.hasOwnProperty.call(wireMap, boundary)) {
184
+ const mapped = wireMap[boundary];
185
+ return mapped === REASONING_EFFORT_OMIT_SENTINEL ? undefined : mapped;
186
+ }
126
187
 
127
188
  const supported = configuredReasoningEfforts(provider, modelId);
128
189
  const codexEffort = supported !== undefined ? clampToSupportedCodexEffort(boundary, supported) : requestToCodexEffort(boundary);
@@ -130,6 +191,10 @@ export function mapReasoningEffort(provider: OcxProviderConfig, modelId: string,
130
191
 
131
192
  // Belt for the odd config where the supported ladder is ultra-only and the clamp lands on it.
132
193
  const wire = codexEffort === "ultra" ? "max" : codexEffort;
133
- if (wireMap && Object.prototype.hasOwnProperty.call(wireMap, wire)) return wireMap[wire];
194
+ if (wireMap && Object.prototype.hasOwnProperty.call(wireMap, wire)) {
195
+ const mapped = wireMap[wire];
196
+ return mapped === REASONING_EFFORT_OMIT_SENTINEL ? undefined : mapped;
197
+ }
198
+ if (wire === REASONING_EFFORT_OMIT_SENTINEL) return undefined;
134
199
  return wire;
135
200
  }
@@ -0,0 +1,63 @@
1
+ // Representation repair for top-level Codex apply_patch custom-tool payloads.
2
+ //
3
+ // Some routed models decorate the first and last lines as
4
+ // `*** Begin Patch ***` / `*** End Patch ***`. Codex rejects those otherwise
5
+ // valid custom-tool payloads. Repair is deliberately limited to a complete,
6
+ // structurally recognizable top-level patch: arbitrary `exec` JavaScript is
7
+ // caller-authored executable input and must remain byte-identical.
8
+ //
9
+ // This is the same intent boundary as `src/lib/tool-argument-integers.ts`:
10
+ // repair the one faithful reading, leave genuine patch content alone.
11
+
12
+ const PATCH_BEGIN = "*** Begin Patch";
13
+ const PATCH_END = "*** End Patch";
14
+ const TOP_LEVEL_PATCH_ENVELOPE = /^(\*\*\* Begin Patch(?: \*\*\*)?)(\r?\n)([\s\S]*)(\r?\n)(\*\*\* End Patch(?: \*\*\*)?)(\r?\n)?$/;
15
+ const PATCH_OPERATION_LINE = /^\*\*\* (?:Add|Update|Delete) File: .+$/m;
16
+
17
+ /** Unwrap the `{input:string}` function-call wrapper used for freeform tools. */
18
+ export function unwrapFreeformToolInput(argumentsText: unknown): string {
19
+ if (typeof argumentsText !== "string") return "";
20
+ try {
21
+ const parsed: unknown = JSON.parse(argumentsText);
22
+ if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
23
+ const input = (parsed as { input?: unknown }).input;
24
+ if (typeof input === "string") return input;
25
+ }
26
+ } catch {
27
+ // The string is the freeform body, not nested JSON.
28
+ }
29
+ return argumentsText;
30
+ }
31
+
32
+ /**
33
+ * Strip trailing `***` only from the outer lines of one complete patch.
34
+ * Internal patch content, incomplete envelopes, and non-patch text are exact
35
+ * pass-throughs.
36
+ */
37
+ export function normalizeApplyPatchDelimiters(text: string): string {
38
+ const match = TOP_LEVEL_PATCH_ENVELOPE.exec(text);
39
+ if (!match) return text;
40
+ const [, begin, beginBreak, body, endBreak, end, trailingBreak = ""] = match;
41
+ if (!PATCH_OPERATION_LINE.test(body)) return text;
42
+ if (begin === PATCH_BEGIN && end === PATCH_END) return text;
43
+ return `${PATCH_BEGIN}${beginBreak}${body}${endBreak}${PATCH_END}${trailingBreak}`;
44
+ }
45
+
46
+ /**
47
+ * Repair freeform input before Codex sees it.
48
+ *
49
+ * Only a bare or reserved-`functions` `apply_patch` payload may receive delimiter
50
+ * repair. Remote namespaces own their grammar; those bodies and every other
51
+ * freeform input are unwrapped and left byte-exact.
52
+ */
53
+ export function repairFreeformToolInput(
54
+ argumentsText: unknown,
55
+ toolName = "",
56
+ namespace?: string,
57
+ ): string {
58
+ const unwrapped = unwrapFreeformToolInput(argumentsText);
59
+ const ownsApplyPatchGrammar = namespace === undefined || namespace === "functions";
60
+ return ownsApplyPatchGrammar && toolName === "apply_patch"
61
+ ? normalizeApplyPatchDelimiters(unwrapped)
62
+ : unwrapped;
63
+ }
@@ -0,0 +1,50 @@
1
+ import { normalizeApplyPatchDelimiters } from "./apply-patch-envelope";
2
+
3
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
4
+ return !!value && typeof value === "object" && !Array.isArray(value);
5
+ }
6
+
7
+ function unwrapPatchInput(value: string): string {
8
+ try {
9
+ const parsed: unknown = JSON.parse(value);
10
+ if (isPlainObject(parsed)) {
11
+ if (typeof parsed.input === "string") return parsed.input;
12
+ if (typeof parsed.patch === "string") return parsed.patch;
13
+ }
14
+ } catch {
15
+ // Native custom calls carry the patch body directly.
16
+ }
17
+ return value;
18
+ }
19
+
20
+ /**
21
+ * Convert a nested Code Mode helper call into unified-exec JavaScript.
22
+ *
23
+ * Parsed values are serialized as data, never interpolated as source, so command and patch text
24
+ * cannot escape the generated call. Invalid structured shell payloads are also passed as data so
25
+ * nested-tool validation can reject them without evaluating provider text as JavaScript.
26
+ */
27
+ export function compileCodeModeHelperInput(argumentsText: unknown, toolName: string): string {
28
+ if (typeof argumentsText !== "string") return "";
29
+ if (toolName === "apply_patch") {
30
+ const patch = normalizeApplyPatchDelimiters(unwrapPatchInput(argumentsText));
31
+ return `const result = await tools.apply_patch(${JSON.stringify(patch)});\ntext(result);`;
32
+ }
33
+ let parsed: unknown = argumentsText;
34
+ try {
35
+ parsed = JSON.parse(argumentsText);
36
+ } catch {
37
+ // Keep malformed provider text as data rather than executable source.
38
+ }
39
+ const args: unknown = isPlainObject(parsed) ? { ...parsed } : parsed;
40
+ if (
41
+ toolName === "shell_command"
42
+ && isPlainObject(args)
43
+ && typeof args.command === "string"
44
+ && args.cmd === undefined
45
+ ) {
46
+ args.cmd = args.command;
47
+ delete args.command;
48
+ }
49
+ return `const result = await tools.exec_command(${JSON.stringify(args)});\ntext(result);`;
50
+ }
@@ -33,6 +33,24 @@ export const SUMMARY_PREFIX = "Another language model started to solve this prob
33
33
 
34
34
  export const OPAQUE_COMPACTION_NOTE = "[earlier conversation was compacted; the summary is stored in a format this model cannot read]";
35
35
 
36
+ /**
37
+ * Item types in the compact wire family. Each carries an `encrypted_content` blob the client
38
+ * replays verbatim on every later turn, and the minting backend verifies it is unmodified.
39
+ *
40
+ * Keep this the only enumeration: a copy that listed just `compaction` let the response-side
41
+ * field backfill synthesize ids into the other two, which the client then replayed as "modified
42
+ * from the compact response".
43
+ */
44
+ const COMPACTION_ITEM_TYPES: ReadonlySet<string> = new Set([
45
+ "compaction",
46
+ "compaction_summary",
47
+ "context_compaction",
48
+ ]);
49
+
50
+ export function isCompactionItemType(type: unknown): boolean {
51
+ return typeof type === "string" && COMPACTION_ITEM_TYPES.has(type);
52
+ }
53
+
36
54
  export function encodeCompactionSummary(summary: string): string {
37
55
  return OCX_COMPACTION_PREFIX + Buffer.from(summary, "utf-8").toString("base64");
38
56
  }
@@ -105,7 +123,14 @@ export function buildCompactV1Output(userMessages: string[], summary: string): R
105
123
  remaining -= msg.length;
106
124
  } else {
107
125
  // Budget partially covers this older message: keep its tail (most recent context) and stop.
108
- selected.push(msg.slice(msg.length - remaining));
126
+ let tailStart = msg.length - remaining;
127
+ // Never start the retained tail on a lone LOW surrogate: the pair's
128
+ // other half would be lost and encoding substitutes U+FFFD.
129
+ if (tailStart > 0 && tailStart < msg.length) {
130
+ const first = msg.charCodeAt(tailStart);
131
+ if (first >= 0xdc00 && first <= 0xdfff) tailStart += 1;
132
+ }
133
+ selected.push(msg.slice(tailStart));
109
134
  break;
110
135
  }
111
136
  }