@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
@@ -0,0 +1,182 @@
1
+ import type { StorageCleanupPolicy } from "../types";
2
+ import { startStateStoreSweeper } from "../lib/state-store-sweeper";
3
+ import {
4
+ abortStorageCleanupPolicyJobAsync,
5
+ setStorageCleanupPolicyJobLiveApply,
6
+ } from "../storage/policy-job";
7
+ import { setStorageCleanupPolicyLiveSink } from "../storage/policy";
8
+ import {
9
+ scheduleStorageCleanupStartupRun,
10
+ startStorageCleanupScheduler,
11
+ stopStorageCleanupScheduler,
12
+ } from "../storage/policy-scheduler";
13
+ import {
14
+ cancelQueuedStorageWorkerSpawns,
15
+ drainStorageWorkers,
16
+ } from "../storage/worker-lifecycle";
17
+ import {
18
+ acquireServerResourceOwner,
19
+ type ServerResourceOwnerLease,
20
+ } from "../lib/server-resource-ownership";
21
+ import {
22
+ startMemoryWatchdog,
23
+ type MemoryWatchdog,
24
+ } from "./memory-watchdog";
25
+
26
+ type PolicyApply = (policy: StorageCleanupPolicy) => void;
27
+
28
+ type ProcessLoops = {
29
+ memoryWatchdog: MemoryWatchdog;
30
+ stateStoreSweeper: ReturnType<typeof startStateStoreSweeper>;
31
+ };
32
+
33
+ type LeaseOwner = {
34
+ token: symbol;
35
+ applyPolicy: PolicyApply;
36
+ resources: ServerResourceOwnerLease;
37
+ };
38
+
39
+ export type ServerBackgroundLifecycleLease = {
40
+ scheduleStartupRun(): void;
41
+ release(): Promise<void>;
42
+ releaseAfterFailedStart(): void;
43
+ };
44
+
45
+ const owners: LeaseOwner[] = [];
46
+ let processLoops: ProcessLoops | null = null;
47
+ let cleanupInProgress = false;
48
+
49
+ function setLivePolicyOwner(applyPolicy: PolicyApply | null): void {
50
+ setStorageCleanupPolicyLiveSink(applyPolicy);
51
+ setStorageCleanupPolicyJobLiveApply(applyPolicy);
52
+ }
53
+
54
+ function startProcessLoops(applyPolicy: PolicyApply): ProcessLoops {
55
+ let memoryWatchdog: MemoryWatchdog | null = null;
56
+ let stateStoreSweeper: ReturnType<typeof startStateStoreSweeper> | null = null;
57
+ try {
58
+ memoryWatchdog = startMemoryWatchdog();
59
+ stateStoreSweeper = startStateStoreSweeper();
60
+ setLivePolicyOwner(applyPolicy);
61
+ startStorageCleanupScheduler();
62
+ return { memoryWatchdog, stateStoreSweeper };
63
+ } catch (error) {
64
+ memoryWatchdog?.stop();
65
+ stateStoreSweeper?.stop();
66
+ stopStorageCleanupScheduler();
67
+ setLivePolicyOwner(null);
68
+ throw error;
69
+ }
70
+ }
71
+
72
+ function stopProcessLoops(): void {
73
+ const loops = processLoops;
74
+ processLoops = null;
75
+ loops?.memoryWatchdog.stop();
76
+ loops?.stateStoreSweeper.stop();
77
+ stopStorageCleanupScheduler();
78
+ setLivePolicyOwner(null);
79
+ }
80
+
81
+ async function stopStoragePolicyWorker(): Promise<void> {
82
+ cancelQueuedStorageWorkerSpawns();
83
+ const abortResult = await Promise.allSettled([abortStorageCleanupPolicyJobAsync()]);
84
+ if (abortResult[0]?.status === "rejected") {
85
+ console.warn(
86
+ "[storage] policy worker abort during server stop failed:",
87
+ abortResult[0].reason instanceof Error
88
+ ? abortResult[0].reason.message
89
+ : abortResult[0].reason,
90
+ );
91
+ }
92
+ try {
93
+ await drainStorageWorkers();
94
+ } catch (error) {
95
+ console.warn(
96
+ "[storage] worker drain during server stop failed:",
97
+ error instanceof Error ? error.message : error,
98
+ );
99
+ }
100
+ }
101
+
102
+ function removeOwner(owner: LeaseOwner): boolean {
103
+ const index = owners.findIndex(candidate => candidate.token === owner.token);
104
+ if (index === -1) return false;
105
+ owners.splice(index, 1);
106
+ return true;
107
+ }
108
+
109
+ function releaseOwnerSynchronously(owner: LeaseOwner): "inactive" | "shared" | "last" {
110
+ if (!removeOwner(owner)) return "inactive";
111
+ owner.resources.release();
112
+ const nextOwner = owners.at(-1);
113
+ if (nextOwner) {
114
+ setLivePolicyOwner(nextOwner.applyPolicy);
115
+ return "shared";
116
+ }
117
+ stopProcessLoops();
118
+ return "last";
119
+ }
120
+
121
+ /**
122
+ * Acquire one server's lease on process-wide singleton loops.
123
+ *
124
+ * The first live server starts the loops. Later servers only add a reference and
125
+ * become the current policy sink; out-of-order release restores the newest
126
+ * remaining sink. The final release owns timer and Worker teardown. Resources
127
+ * registered while this server starts are released with this exact lease.
128
+ */
129
+ export function acquireServerBackgroundLifecycle(
130
+ applyPolicy: PolicyApply,
131
+ ): ServerBackgroundLifecycleLease {
132
+ if (cleanupInProgress) {
133
+ throw new Error("server background lifecycle cleanup is still in progress");
134
+ }
135
+
136
+ const owner: LeaseOwner = {
137
+ token: Symbol("server-background-lifecycle"),
138
+ applyPolicy,
139
+ resources: acquireServerResourceOwner(),
140
+ };
141
+ try {
142
+ if (!processLoops) {
143
+ processLoops = startProcessLoops(applyPolicy);
144
+ } else {
145
+ setLivePolicyOwner(applyPolicy);
146
+ }
147
+ owners.push(owner);
148
+ } catch (error) {
149
+ owner.resources.release();
150
+ throw error;
151
+ }
152
+
153
+ let releaseFlight: Promise<void> | null = null;
154
+ return {
155
+ scheduleStartupRun() {
156
+ if (owners.some(candidate => candidate.token === owner.token)) {
157
+ scheduleStorageCleanupStartupRun();
158
+ }
159
+ },
160
+ release() {
161
+ if (releaseFlight) return releaseFlight;
162
+ const outcome = releaseOwnerSynchronously(owner);
163
+ if (outcome !== "last") {
164
+ releaseFlight = Promise.resolve();
165
+ return releaseFlight;
166
+ }
167
+ cleanupInProgress = true;
168
+ releaseFlight = stopStoragePolicyWorker().finally(() => {
169
+ cleanupInProgress = false;
170
+ });
171
+ return releaseFlight;
172
+ },
173
+ releaseAfterFailedStart() {
174
+ if (releaseFlight) return;
175
+ // Startup evaluation is scheduled only after both listeners bind, so a
176
+ // failed start cannot have spawned a Worker for this lease. Keep rollback
177
+ // synchronous so a caller may immediately retry a different port.
178
+ releaseOwnerSynchronously(owner);
179
+ releaseFlight = Promise.resolve();
180
+ },
181
+ };
182
+ }
@@ -2,11 +2,15 @@
2
2
  * OpenAI Chat Completions inbound (/v1/chat/completions) for GitHub Copilot App
3
3
  * and other OpenAI-compatible clients.
4
4
  *
5
- * Translate-and-replay: Chat Completions body -> /v1/responses via handleResponses,
6
- * then bridge the Responses output back to Chat Completions SSE/JSON.
5
+ * Ordinary openai-chat routes send directly on the Chat Completions wire. Routes
6
+ * that need Responses-only behavior keep the Chat -> Responses -> Chat bridge.
7
7
  */
8
8
  import { FORWARD_HEADERS } from "../adapters/openai-responses";
9
- import { ChatCompletionsRequestError, chatCompletionsToResponsesBody } from "../chat/inbound";
9
+ import {
10
+ assertChatCompletionsRoutingBody,
11
+ ChatCompletionsRequestError,
12
+ chatCompletionsToResponsesBody,
13
+ } from "../chat/inbound";
10
14
  import {
11
15
  chatCompletionsErrorResponse,
12
16
  collectChatCompletion,
@@ -14,17 +18,18 @@ import {
14
18
  responsesJsonToChatCompletion,
15
19
  responsesSseToChatCompletionsSse,
16
20
  } from "../chat/outbound";
17
- import { classifyError, CYBER_POLICY_ERROR_CODE, isCyberPolicyCode } from "../lib/errors";
21
+ import { classifyError, cyberPolicyErrorType, CYBER_POLICY_ERROR_CODE, isCyberPolicyCode } from "../lib/errors";
18
22
  import { redactSecretString } from "../lib/redact";
19
23
  import { resolveClientRetryAfter } from "../lib/retry-after";
20
24
  import { estimateTokens } from "../lib/token-estimate";
21
- import { routeModel } from "../router";
25
+ import { NoEligiblePolicyCandidateError, routeModel } from "../router";
26
+ import { evidenceFromBody } from "../routing/request-evidence";
22
27
  import { resolveWireProtocolOverride } from "./adapter-resolve";
23
28
  import type { OcxConfig } from "../types";
24
29
  import { readJsonRequestBody } from "./request-decompress";
25
30
  import {
26
31
  addFinalRequestLog,
27
- httpStatusForTerminalStatus,
32
+ httpStatusForRequestLogTerminal,
28
33
  recordFirstOutput,
29
34
  type RequestLogContext,
30
35
  type RequestLogEntry,
@@ -32,12 +37,15 @@ import {
32
37
  import { responseWithDeferredRequestLog } from "./relay";
33
38
  import { handleResponses } from "./responses";
34
39
  import type { AdmissionLease } from "../lib/admission";
40
+ import type { DataPlaneAdmission } from "./auth-cors";
41
+ import { tryClaimNativeMainProfileForTurn } from "../codex/native-main-admission";
35
42
  import {
36
43
  createTranslatorBudget,
37
44
  finalizeTranslatorBudgetResponse,
38
45
  isTranslatorBudgetExceededError,
39
46
  type TranslatorBudget,
40
47
  } from "../lib/translator-budget";
48
+ import { handleNativeChatCompletions, isNativeChatRouteEligible } from "./chat-native";
41
49
 
42
50
  type Rec = Record<string, unknown>;
43
51
 
@@ -57,7 +65,7 @@ export async function handleChatCompletions(
57
65
  req: Request,
58
66
  config: OcxConfig,
59
67
  logCtx: RequestLogContext,
60
- logIds?: { requestId: string; start: number; turnAdmissionLease?: AdmissionLease },
68
+ logIds?: { requestId: string; start: number; turnAdmissionLease?: AdmissionLease; admission?: DataPlaneAdmission },
61
69
  ): Promise<Response> {
62
70
  const translatorBudget = createTranslatorBudget();
63
71
  try {
@@ -76,14 +84,13 @@ async function handleChatCompletionsWithBudget(
76
84
  config: OcxConfig,
77
85
  logCtx: RequestLogContext,
78
86
  translatorBudget: TranslatorBudget,
79
- logIds?: { requestId: string; start: number; turnAdmissionLease?: AdmissionLease },
87
+ logIds?: { requestId: string; start: number; turnAdmissionLease?: AdmissionLease; admission?: DataPlaneAdmission },
80
88
  ): Promise<Response> {
81
- let chatBody: unknown;
82
- let internalBody: Rec;
89
+ let chatBody: Rec;
83
90
  try {
84
- chatBody = await readChatBody(req, translatorBudget);
85
- internalBody = chatCompletionsToResponsesBody(chatBody);
86
- translatorBudget.chargeRetained(new TextEncoder().encode(JSON.stringify(internalBody)).byteLength, { kind: "request_copies" });
91
+ const rawBody = await readChatBody(req, translatorBudget);
92
+ assertChatCompletionsRoutingBody(rawBody);
93
+ chatBody = rawBody;
87
94
  } catch (err) {
88
95
  const overflow = isTranslatorBudgetExceededError(err);
89
96
  const status = overflow ? 413 : err instanceof ChatCompletionsRequestError ? 400 : 500;
@@ -96,60 +103,98 @@ async function handleChatCompletionsWithBudget(
96
103
  );
97
104
  }
98
105
 
99
- const requestedModel = (chatBody as Rec).model as string;
100
- const stream = internalBody.stream === true;
106
+ const requestedModel = chatBody.model as string;
107
+ const stream = chatBody.stream === true;
101
108
  // Best-effort Grok attribution: the managed fence stamps this header on every model
102
109
  // it registers (extra_headers, sent verbatim by upstream Grok). Dashboard usage
103
110
  // bucketing only — never an auth or billing signal.
104
111
  if (req.headers.get("x-opencodex-grok") === "1") logCtx.surface = "grok";
105
- // Routed adapters only support streamed turns; always stream internally and fold
106
- // for non-streaming clients.
107
- internalBody.stream = true;
108
-
109
- let nativeRoute = false;
110
112
  let directRoute = false;
113
+ let settledRoute: ReturnType<typeof routeModel> | null = null;
114
+ let chatNativeRoute: ReturnType<typeof routeModel> | null = null;
111
115
  try {
112
- const route = routeModel(config, internalBody.model as string);
116
+ const route = routeModel(config, requestedModel, evidenceFromBody(chatBody));
113
117
  // Settle the wire once so every branch below reads the adapter this model will
114
118
  // actually use, not the provider-wide default (#404).
115
119
  route.provider = resolveWireProtocolOverride(route.providerName, route.modelId, route.provider, "chat");
116
120
  logCtx.model = route.modelId;
117
121
  logCtx.providerAdapter = route.provider.adapter;
118
122
  logCtx.requestedModel = requestedModel;
123
+ if (route.routeReason === "model-alias" || route.modelId !== requestedModel && requestedModel.includes("/")) logCtx.requestedAlias = requestedModel;
119
124
  logCtx.provider = route.providerName;
125
+ logCtx.routeDecision = route.routeDecision;
126
+ settledRoute = route;
120
127
  if (route.provider.adapter === "openai-responses") {
121
- nativeRoute = true;
122
128
  directRoute = route.codexAccountMode === "direct";
123
- // ChatGPT backend rejects store:true and unsupported sampling knobs.
124
- internalBody.store = false;
125
- delete internalBody.max_output_tokens;
126
- delete internalBody.temperature;
127
- delete internalBody.top_p;
128
- delete internalBody.stop;
129
- delete internalBody.user;
130
- } else if (internalBody.store === undefined) {
131
- internalBody.store = false;
132
- }
133
- if (route.provider.adapter === "openai-chat" && internalBody.text !== undefined) {
134
- if (logIds) addFinalRequestLog(logIds.requestId, logIds.start, logCtx, 400, { closeReason: "non_stream" });
135
- return chatCompletionsErrorResponse(400, "response_format is not supported for routed openai-chat models");
136
129
  }
137
130
  if (route.provider.adapter === "cursor" || route.provider.adapter === "kiro") {
138
- const raw = chatBody as Rec;
139
131
  const parts: string[] = [];
140
- if (raw.messages !== undefined) parts.push(JSON.stringify(raw.messages));
141
- if (raw.tools !== undefined) parts.push(JSON.stringify(raw.tools));
132
+ if (chatBody.messages !== undefined) parts.push(JSON.stringify(chatBody.messages));
133
+ if (chatBody.tools !== undefined) parts.push(JSON.stringify(chatBody.tools));
142
134
  logCtx.usageLogInputTokens = Math.max(1, estimateTokens(parts.join("\n"), requestedModel));
143
135
  }
144
- if (internalBody.reasoning !== undefined) {
145
- const { supportedLadderFor } = await import("./effort-policy");
146
- const ladder = supportedLadderFor({ provider: route.provider, modelId: route.modelId });
147
- if (ladder !== undefined && ladder.length === 0) delete internalBody.reasoning;
136
+ if (isNativeChatRouteEligible(route, chatBody)) chatNativeRoute = route;
137
+ } catch (err) {
138
+ if (err instanceof NoEligiblePolicyCandidateError) {
139
+ logCtx.routeDecision = err.trace;
140
+ if (logIds) addFinalRequestLog(logIds.requestId, logIds.start, logCtx, 404, { closeReason: "non_stream" });
141
+ return chatCompletionsErrorResponse(404, err.message, "invalid_request_error");
148
142
  }
149
- } catch {
150
143
  /* unknown model: let handleResponses shape the 404 */
151
144
  }
152
- void nativeRoute;
145
+
146
+ if (chatNativeRoute) {
147
+ return handleNativeChatCompletions({
148
+ req,
149
+ config,
150
+ logCtx,
151
+ ...(logIds ? { logIds } : {}),
152
+ route: chatNativeRoute,
153
+ chatBody,
154
+ requestedModel,
155
+ requestedStream: stream,
156
+ translatorBudget,
157
+ });
158
+ }
159
+
160
+ let internalBody: Rec;
161
+ try {
162
+ // Validate the full Chat boundary after routing. Native Chat keeps `chatBody` as
163
+ // its wire source; this Responses projection is used only by the fallback path.
164
+ internalBody = chatCompletionsToResponsesBody(chatBody);
165
+ } catch (err) {
166
+ const overflow = isTranslatorBudgetExceededError(err);
167
+ const status = overflow ? 413 : err instanceof ChatCompletionsRequestError ? 400 : 500;
168
+ if (logIds) addFinalRequestLog(logIds.requestId, logIds.start, logCtx, status, { closeReason: "non_stream" });
169
+ return chatCompletionsErrorResponse(
170
+ status,
171
+ overflow ? "request translation buffer exceeded the safe limit" : err instanceof Error ? err.message : String(err),
172
+ overflow ? "request_too_large" : undefined,
173
+ overflow ? "translation_buffer_limit" : undefined,
174
+ );
175
+ }
176
+
177
+ // Routed adapters only support streamed turns; always stream internally and fold
178
+ // for non-streaming clients. Native Chat uses the caller's original stream bit.
179
+ internalBody.stream = true;
180
+ if (settledRoute?.provider.adapter === "openai-responses") {
181
+ // ChatGPT backend rejects store:true and unsupported sampling knobs.
182
+ internalBody.store = false;
183
+ delete internalBody.max_output_tokens;
184
+ delete internalBody.temperature;
185
+ delete internalBody.top_p;
186
+ delete internalBody.stop;
187
+ delete internalBody.user;
188
+ } else if (internalBody.store === undefined) {
189
+ internalBody.store = false;
190
+ }
191
+ if (settledRoute && internalBody.reasoning !== undefined) {
192
+ const { stripEmptyLadderEffort, supportedLadderFor } = await import("./effort-policy");
193
+ const ladder = supportedLadderFor({ provider: settledRoute.provider, modelId: settledRoute.modelId });
194
+ const next = stripEmptyLadderEffort(internalBody.reasoning, ladder);
195
+ if (next === undefined) delete internalBody.reasoning;
196
+ else internalBody.reasoning = next;
197
+ }
153
198
 
154
199
  const headers = new Headers({ "content-type": "application/json" });
155
200
  for (const name of FORWARD_HEADERS) {
@@ -158,19 +203,42 @@ async function handleChatCompletionsWithBudget(
158
203
  if (value) headers.set(name, value);
159
204
  }
160
205
  // Prefer main ChatGPT auth so OpenAI-backed sidecars remain reachable on routed turns.
161
- if (!directRoute) try {
162
- const { getMainAccountToken } = await import("../codex/main-account");
163
- const token = getMainAccountToken();
164
- if (token) {
165
- headers.set("authorization", `Bearer ${token.accessToken}`);
166
- headers.set("chatgpt-account-id", token.chatgptAccountId);
206
+ if (!directRoute) {
207
+ // This enrichment is optional for routed/non-main providers. If native main
208
+ // is fenced, omit it and let auth-context reject only a final physical-main
209
+ // selection while healthy pool/provider routes continue.
210
+ if (tryClaimNativeMainProfileForTurn(logIds?.turnAdmissionLease)) {
211
+ try {
212
+ const { getMainAccountToken } = await import("../codex/main-account");
213
+ const token = getMainAccountToken();
214
+ if (token) {
215
+ headers.set("authorization", `Bearer ${token.accessToken}`);
216
+ headers.set("chatgpt-account-id", token.chatgptAccountId);
217
+ }
218
+ } catch {
219
+ /* optional */
220
+ }
167
221
  }
168
- } catch {
169
- /* optional */
170
222
  }
171
223
 
172
- const internalBodyJson = JSON.stringify(internalBody);
173
- translatorBudget.chargeRetained(new TextEncoder().encode(internalBodyJson).byteLength, { kind: "request_copies" });
224
+ let internalBodyJson: string;
225
+ try {
226
+ internalBodyJson = JSON.stringify(internalBody);
227
+ translatorBudget.chargeRetained(
228
+ new TextEncoder().encode(internalBodyJson).byteLength,
229
+ { kind: "request_copies" },
230
+ );
231
+ } catch (err) {
232
+ const overflow = isTranslatorBudgetExceededError(err);
233
+ const status = overflow ? 413 : 500;
234
+ if (logIds) addFinalRequestLog(logIds.requestId, logIds.start, logCtx, status, { closeReason: "non_stream" });
235
+ return chatCompletionsErrorResponse(
236
+ status,
237
+ overflow ? "request translation buffer exceeded the safe limit" : err instanceof Error ? err.message : String(err),
238
+ overflow ? "request_too_large" : undefined,
239
+ overflow ? "translation_buffer_limit" : undefined,
240
+ );
241
+ }
174
242
  const internalReq = new Request("http://localhost/v1/responses", {
175
243
  method: "POST",
176
244
  headers,
@@ -185,12 +253,19 @@ async function handleChatCompletionsWithBudget(
185
253
  };
186
254
  const upstream = await handleResponses(internalReq, config, logCtx, {
187
255
  ...(logIds?.turnAdmissionLease ? { turnAdmissionLease: logIds.turnAdmissionLease } : {}),
256
+ // #1686: the Chat surface translates its body and replays here, so the admission fact has
257
+ // to ride along or a bearer-admitted Chat caller would still be refused by Direct.
258
+ ...(logIds?.admission ? { admission: logIds.admission } : {}),
188
259
  abortSignal: req.signal,
189
260
  // Body is Responses-shaped by now, but the client spoke Chat Completions.
190
261
  inboundWire: "chat",
262
+ // Terminal vision-describe marker (roadmap 180): the bridge rebuilds
263
+ // headers from the FORWARD_HEADERS allowlist, which would drop the raw
264
+ // header — so the fact is detected here and carried as an option flag.
265
+ ...(req.headers.get("x-opencodex-vision-describe") === "1" ? { visionDescribeTerminal: true } : {}),
191
266
  translatorBudget,
192
267
  ...(logIds ? { onFirstOutput: () => recordFirstOutput(logCtx, logIds.start) } : {}),
193
- onNativePassthroughTerminal: status => finalizeNativeLog(httpStatusForTerminalStatus(status), { terminalStatus: status, closeReason: "terminal" }),
268
+ onNativePassthroughTerminal: status => finalizeNativeLog(httpStatusForRequestLogTerminal(status, logCtx), { terminalStatus: status, closeReason: "terminal" }),
194
269
  onNativePassthroughCancel: () => finalizeNativeLog(499, { closeReason: "client_cancel" }),
195
270
  });
196
271
 
@@ -206,26 +281,26 @@ async function handleChatCompletionsWithBudget(
206
281
  const parsed = JSON.parse(text) as {
207
282
  error?: { message?: string; type?: string; code?: string | null } | string;
208
283
  message?: string;
284
+ type?: string;
285
+ code?: string | null;
209
286
  };
210
287
  const nested = typeof parsed?.error === "object" && parsed.error ? parsed.error : undefined;
211
288
  const flat = typeof parsed?.error === "string" ? parsed.error : parsed?.message;
212
289
  const rawFallback = text
213
290
  ? `upstream error (${upstream.status}): ${redactSecretString(text).slice(0, 400)}`
214
291
  : message;
215
- message = nested?.message || flat || rawFallback;
216
- if (nested) {
217
- if (typeof nested.type === "string") upstreamType = nested.type;
218
- if (nested.code === null || typeof nested.code === "string") upstreamCode = nested.code;
219
- }
292
+ const upstreamMessage = nested?.message || flat;
293
+ message = upstreamMessage
294
+ ? redactSecretString(upstreamMessage).slice(0, 500)
295
+ : rawFallback;
296
+ const structuredType = nested?.type ?? parsed.type;
297
+ const structuredCode = nested?.code ?? parsed.code;
298
+ if (typeof structuredType === "string") upstreamType = structuredType;
299
+ if (structuredCode === null || typeof structuredCode === "string") upstreamCode = structuredCode;
220
300
  } catch {
221
301
  if (text) message = `upstream error (${upstream.status}): ${redactSecretString(text).slice(0, 400)}`;
222
302
  }
223
303
  } catch { /* keep fallback */ }
224
- const retryAfter = resolveClientRetryAfter({
225
- status: upstream.status,
226
- message,
227
- upstreamRetryAfter: upstream.headers.get("retry-after"),
228
- });
229
304
  const classified = classifyError(
230
305
  upstream.status,
231
306
  upstreamType
@@ -235,9 +310,9 @@ async function handleChatCompletionsWithBudget(
235
310
  : "invalid_request_error"),
236
311
  message,
237
312
  );
238
- if (isCyberPolicyCode(upstreamCode)) {
313
+ if (isCyberPolicyCode(upstreamCode) || classified.code === CYBER_POLICY_ERROR_CODE) {
239
314
  classified.code = CYBER_POLICY_ERROR_CODE;
240
- classified.type = "invalid_request_error";
315
+ classified.type = cyberPolicyErrorType(upstreamType);
241
316
  } else if (upstreamCode === "model_not_found") {
242
317
  // Structured model_not_found must win over classifyError's generic remaps.
243
318
  classified.code = "model_not_found";
@@ -246,6 +321,13 @@ async function handleChatCompletionsWithBudget(
246
321
  classified.code = upstreamCode;
247
322
  }
248
323
  const status = isCyberPolicyCode(classified.code) ? 400 : upstream.status;
324
+ const retryAfter = isCyberPolicyCode(classified.code)
325
+ ? undefined
326
+ : resolveClientRetryAfter({
327
+ status: upstream.status,
328
+ message,
329
+ upstreamRetryAfter: upstream.headers.get("retry-after"),
330
+ });
249
331
  const rewritten = new Response(JSON.stringify({
250
332
  error: {
251
333
  message: classified.message,
@@ -312,14 +394,14 @@ async function handleChatCompletionsWithBudget(
312
394
  const status = (json as Rec)?.status;
313
395
  if (status === "failed") {
314
396
  const error = (json as { error?: { message?: string; type?: string; code?: string | null } }).error;
315
- const message = error?.message ?? "upstream request failed";
397
+ const message = redactSecretString(error?.message ?? "upstream request failed");
316
398
  const classified = classifyError(502, error?.type ?? "server_error", message);
317
399
  if (error?.code === "translation_buffer_limit") {
318
400
  classified.code = "translation_buffer_limit";
319
- classified.type = "invalid_request_error";
320
- } else if (isCyberPolicyCode(error?.code)) {
401
+ classified.type = "upstream_error";
402
+ } else if (isCyberPolicyCode(error?.code) || classified.code === CYBER_POLICY_ERROR_CODE) {
321
403
  classified.code = CYBER_POLICY_ERROR_CODE;
322
- classified.type = "invalid_request_error";
404
+ classified.type = cyberPolicyErrorType(error?.type);
323
405
  } else if (error?.code === "model_not_found") {
324
406
  // Same deliberate preserve as the non-OK path: structured code beats generic classify.
325
407
  classified.code = "model_not_found";
@@ -327,7 +409,7 @@ async function handleChatCompletionsWithBudget(
327
409
  }
328
410
  return chatCompletionsErrorResponse(
329
411
  classified.code === "translation_buffer_limit"
330
- ? 413
412
+ ? 502
331
413
  : isCyberPolicyCode(classified.code) ? 400 : 502,
332
414
  message,
333
415
  classified.type,