@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,310 @@
1
+ import type { OcxProviderConfig, RequestPacingRule } from "../types";
2
+ import type { GenerationContext } from "../lib/state-store-sweeper";
3
+
4
+ export const REQUEST_PACING_MAX_QUEUE_DEPTH = 256;
5
+ export const REQUEST_PACING_MAX_QUEUE_AGE_MS = 60_000;
6
+
7
+ let maxQueueDepth = REQUEST_PACING_MAX_QUEUE_DEPTH;
8
+ let maxQueueAgeMs = REQUEST_PACING_MAX_QUEUE_AGE_MS;
9
+
10
+ export type RequestPacingQueueOverloadReason = "queue_full" | "queue_expired";
11
+
12
+ export class RequestPacingQueueOverloadError extends Error {
13
+ constructor(
14
+ public readonly providerName: string,
15
+ public readonly reason: RequestPacingQueueOverloadReason,
16
+ public readonly retryAfterSeconds: number,
17
+ ) {
18
+ super(reason === "queue_full"
19
+ ? `request pacing queue for provider '${providerName}' is full`
20
+ : `request pacing queue for provider '${providerName}' exceeded the maximum queued age`);
21
+ this.name = "RequestPacingQueueOverloadError";
22
+ }
23
+ }
24
+
25
+ export class RequestPacingProviderRemovedError extends Error {
26
+ constructor(public readonly providerName: string) {
27
+ super(`request pacing provider '${providerName}' was removed`);
28
+ this.name = "RequestPacingProviderRemovedError";
29
+ }
30
+ }
31
+
32
+ interface Waiter {
33
+ modelId?: string;
34
+ providerIntervalMs: number;
35
+ modelIntervalMs: number;
36
+ queuedAt: number;
37
+ signal?: AbortSignal;
38
+ resolve: () => void;
39
+ reject: (reason: unknown) => void;
40
+ abort?: () => void;
41
+ }
42
+
43
+ interface ProviderPacer {
44
+ queue: Waiter[];
45
+ providerNextStartAt: number;
46
+ modelNextStartAt: Map<string, number>;
47
+ timer?: unknown;
48
+ lastStartedAt?: number;
49
+ lastModelId?: string;
50
+ }
51
+
52
+ export interface RequestPacingRuntime {
53
+ now: () => number;
54
+ setTimer: (callback: () => void, delayMs: number) => unknown;
55
+ clearTimer: (handle: unknown) => void;
56
+ enqueueMicrotask: (callback: () => void) => void;
57
+ }
58
+
59
+ export interface ProviderRequestPacingStatus {
60
+ provider: string;
61
+ enabled: boolean;
62
+ queued: number;
63
+ nextSlotInMs: number;
64
+ lastStartedAt?: number;
65
+ lastModelId?: string;
66
+ }
67
+
68
+ const pacers = new Map<string, ProviderPacer>();
69
+ const defaultRuntime: RequestPacingRuntime = {
70
+ now: Date.now,
71
+ setTimer: (callback, delayMs) => setTimeout(callback, delayMs),
72
+ clearTimer: handle => clearTimeout(handle as ReturnType<typeof setTimeout>),
73
+ enqueueMicrotask: queueMicrotask,
74
+ };
75
+ let runtime = defaultRuntime;
76
+ let lastReconciledGeneration = 0;
77
+
78
+ function abortReason(signal: AbortSignal): unknown {
79
+ return signal.reason ?? new DOMException("The operation was aborted", "AbortError");
80
+ }
81
+
82
+ function normalizedInterval(rule: RequestPacingRule | undefined): number {
83
+ if (!rule) return 0;
84
+ const rpmInterval = typeof rule.requestsPerMinute === "number" && rule.requestsPerMinute > 0
85
+ ? 60_000 / rule.requestsPerMinute
86
+ : 0;
87
+ const fixedInterval = typeof rule.minIntervalMs === "number" && rule.minIntervalMs > 0
88
+ ? rule.minIntervalMs
89
+ : 0;
90
+ return Math.max(rpmInterval, fixedInterval);
91
+ }
92
+
93
+ export function requestPacingIntervalMs(provider: OcxProviderConfig, modelId?: string): number {
94
+ const policy = provider.requestPacing;
95
+ if (!policy?.enabled) return 0;
96
+ const override = modelId ? policy.models?.[modelId] : undefined;
97
+ return Math.max(normalizedInterval(policy), normalizedInterval(override));
98
+ }
99
+
100
+ function requestPacingIntervals(provider: OcxProviderConfig, modelId?: string): {
101
+ providerIntervalMs: number;
102
+ modelIntervalMs: number;
103
+ } {
104
+ const policy = provider.requestPacing;
105
+ if (!policy?.enabled) return { providerIntervalMs: 0, modelIntervalMs: 0 };
106
+ return {
107
+ providerIntervalMs: normalizedInterval(policy),
108
+ modelIntervalMs: modelId ? normalizedInterval(policy.models?.[modelId]) : 0,
109
+ };
110
+ }
111
+
112
+ function waiterReadyAt(state: ProviderPacer, modelId: string | undefined): number {
113
+ return Math.max(
114
+ state.providerNextStartAt,
115
+ modelId ? (state.modelNextStartAt.get(modelId) ?? 0) : 0,
116
+ );
117
+ }
118
+
119
+ function pacingRetryAfterSeconds(state: ProviderPacer, modelId: string | undefined, now: number): number {
120
+ return Math.max(1, Math.ceil(Math.max(0, waiterReadyAt(state, modelId) - now) / 1000));
121
+ }
122
+
123
+ function rejectExpiredWaiters(providerName: string, state: ProviderPacer, now: number): void {
124
+ for (let index = state.queue.length - 1; index >= 0; index -= 1) {
125
+ const waiter = state.queue[index]!;
126
+ if (now - waiter.queuedAt < maxQueueAgeMs) continue;
127
+ state.queue.splice(index, 1);
128
+ if (waiter.abort) waiter.signal?.removeEventListener("abort", waiter.abort);
129
+ waiter.reject(new RequestPacingQueueOverloadError(
130
+ providerName,
131
+ "queue_expired",
132
+ pacingRetryAfterSeconds(state, waiter.modelId, now),
133
+ ));
134
+ }
135
+ }
136
+
137
+ function removeProviderPacer(providerName: string, state: ProviderPacer): void {
138
+ if (state.timer) runtime.clearTimer(state.timer);
139
+ state.timer = undefined;
140
+ pacers.delete(providerName);
141
+ const waiters = state.queue.splice(0);
142
+ const error = new RequestPacingProviderRemovedError(providerName);
143
+ for (const waiter of waiters) {
144
+ if (waiter.abort) waiter.signal?.removeEventListener("abort", waiter.abort);
145
+ waiter.reject(error);
146
+ }
147
+ }
148
+
149
+ function runQueue(providerName: string, state: ProviderPacer): void {
150
+ if (state.queue.length === 0) {
151
+ if (state.timer) runtime.clearTimer(state.timer);
152
+ state.timer = undefined;
153
+ return;
154
+ }
155
+ if (state.timer) return;
156
+ const now = runtime.now();
157
+ for (const [modelId, readyAt] of state.modelNextStartAt) {
158
+ if (readyAt <= now) state.modelNextStartAt.delete(modelId);
159
+ }
160
+ rejectExpiredWaiters(providerName, state, now);
161
+ if (state.queue.length === 0) return;
162
+
163
+ const providerReadyAt = Math.max(now, state.providerNextStartAt);
164
+ const waiterIndex = state.queue.findIndex(waiter => {
165
+ const modelReadyAt = waiter.modelId ? (state.modelNextStartAt.get(waiter.modelId) ?? 0) : 0;
166
+ return Math.max(providerReadyAt, modelReadyAt) <= now;
167
+ });
168
+ if (waiterIndex < 0) {
169
+ let earliestAt = Number.POSITIVE_INFINITY;
170
+ for (const waiter of state.queue) {
171
+ const modelReadyAt = waiter.modelId ? (state.modelNextStartAt.get(waiter.modelId) ?? 0) : 0;
172
+ const readyAt = Math.max(providerReadyAt, modelReadyAt);
173
+ const expiresAt = waiter.queuedAt + maxQueueAgeMs;
174
+ earliestAt = Math.min(earliestAt, readyAt, expiresAt);
175
+ }
176
+ const delayMs = Math.max(0, earliestAt - now);
177
+ state.timer = runtime.setTimer(() => {
178
+ state.timer = undefined;
179
+ runQueue(providerName, state);
180
+ }, delayMs);
181
+ return;
182
+ }
183
+ const waiter = state.queue[waiterIndex]!;
184
+ state.queue.splice(waiterIndex, 1);
185
+ if (waiter.abort) waiter.signal?.removeEventListener("abort", waiter.abort);
186
+ const startedAt = runtime.now();
187
+ state.lastStartedAt = startedAt;
188
+ state.lastModelId = waiter.modelId;
189
+ state.providerNextStartAt = startedAt + waiter.providerIntervalMs;
190
+ if (waiter.modelId && waiter.modelIntervalMs > 0) {
191
+ state.modelNextStartAt.set(waiter.modelId, startedAt + waiter.modelIntervalMs);
192
+ }
193
+ waiter.resolve();
194
+ runtime.enqueueMicrotask(() => runQueue(providerName, state));
195
+ }
196
+
197
+ export async function waitForProviderRequestSlot(
198
+ providerName: string,
199
+ provider: OcxProviderConfig,
200
+ modelId?: string,
201
+ signal?: AbortSignal,
202
+ ): Promise<void> {
203
+ const intervals = requestPacingIntervals(provider, modelId);
204
+ if (Math.max(intervals.providerIntervalMs, intervals.modelIntervalMs) <= 0) return;
205
+ if (signal?.aborted) throw abortReason(signal);
206
+
207
+ const state = pacers.get(providerName) ?? {
208
+ queue: [], providerNextStartAt: 0, modelNextStartAt: new Map<string, number>(),
209
+ };
210
+ pacers.set(providerName, state);
211
+
212
+ // Give already-eligible or expired waiters a chance to leave before applying the
213
+ // admission bound to the newest request. This preserves FIFO-ish fairness while
214
+ // keeping the retained queue strictly bounded under burst load.
215
+ if (state.timer) {
216
+ runtime.clearTimer(state.timer);
217
+ state.timer = undefined;
218
+ }
219
+ runQueue(providerName, state);
220
+ if (state.queue.length >= maxQueueDepth) {
221
+ throw new RequestPacingQueueOverloadError(
222
+ providerName,
223
+ "queue_full",
224
+ pacingRetryAfterSeconds(state, modelId, runtime.now()),
225
+ );
226
+ }
227
+
228
+ await new Promise<void>((resolve, reject) => {
229
+ const waiter: Waiter = { modelId, ...intervals, queuedAt: runtime.now(), signal, resolve, reject };
230
+ waiter.abort = () => {
231
+ const index = state.queue.indexOf(waiter);
232
+ if (index >= 0) state.queue.splice(index, 1);
233
+ if (state.timer) {
234
+ runtime.clearTimer(state.timer);
235
+ state.timer = undefined;
236
+ }
237
+ reject(abortReason(signal!));
238
+ runQueue(providerName, state);
239
+ };
240
+ signal?.addEventListener("abort", waiter.abort, { once: true });
241
+ state.queue.push(waiter);
242
+ // Abort may race between the eager check above and listener registration.
243
+ if (signal?.aborted) {
244
+ waiter.abort();
245
+ return;
246
+ }
247
+ if (state.timer) {
248
+ runtime.clearTimer(state.timer);
249
+ state.timer = undefined;
250
+ }
251
+ runQueue(providerName, state);
252
+ });
253
+ }
254
+
255
+ export function providerRequestPacingStatus(
256
+ providerName: string,
257
+ provider: OcxProviderConfig,
258
+ now = runtime.now(),
259
+ ): ProviderRequestPacingStatus {
260
+ const state = pacers.get(providerName);
261
+ let nextSlotAt = state?.providerNextStartAt ?? 0;
262
+ if (state && state.queue.length > 0) {
263
+ let earliestQueuedSlotAt = Number.POSITIVE_INFINITY;
264
+ for (const waiter of state.queue) {
265
+ earliestQueuedSlotAt = Math.min(earliestQueuedSlotAt, waiterReadyAt(state, waiter.modelId));
266
+ }
267
+ if (Number.isFinite(earliestQueuedSlotAt)) nextSlotAt = earliestQueuedSlotAt;
268
+ }
269
+ return {
270
+ provider: providerName,
271
+ enabled: provider.requestPacing?.enabled === true,
272
+ queued: state?.queue.length ?? 0,
273
+ nextSlotInMs: Math.max(0, Math.ceil(nextSlotAt - now)),
274
+ ...(state?.lastStartedAt !== undefined ? { lastStartedAt: state.lastStartedAt } : {}),
275
+ ...(state?.lastModelId ? { lastModelId: state.lastModelId } : {}),
276
+ };
277
+ }
278
+
279
+ export function setProviderRequestPacingLimitsForTest(limits: {
280
+ maxQueueDepth?: number;
281
+ maxQueueAgeMs?: number;
282
+ }): void {
283
+ if (limits.maxQueueDepth !== undefined) maxQueueDepth = limits.maxQueueDepth;
284
+ if (limits.maxQueueAgeMs !== undefined) maxQueueAgeMs = limits.maxQueueAgeMs;
285
+ }
286
+
287
+ export function setProviderRequestPacingRuntimeForTest(nextRuntime: RequestPacingRuntime): void {
288
+ runtime = nextRuntime;
289
+ }
290
+
291
+ export function reconcileProviderRequestPacing(context: GenerationContext): number {
292
+ if (context.generation <= lastReconciledGeneration) return 0;
293
+ let removed = 0;
294
+ for (const [providerName, state] of pacers) {
295
+ if (context.providerNames.has(providerName)) continue;
296
+ removeProviderPacer(providerName, state);
297
+ removed += 1;
298
+ }
299
+ lastReconciledGeneration = context.generation;
300
+ return removed;
301
+ }
302
+
303
+ export function resetProviderRequestPacingForTest(): void {
304
+ for (const state of pacers.values()) if (state.timer) runtime.clearTimer(state.timer);
305
+ pacers.clear();
306
+ maxQueueDepth = REQUEST_PACING_MAX_QUEUE_DEPTH;
307
+ maxQueueAgeMs = REQUEST_PACING_MAX_QUEUE_AGE_MS;
308
+ runtime = defaultRuntime;
309
+ lastReconciledGeneration = 0;
310
+ }
@@ -0,0 +1,277 @@
1
+ import type { OcxProviderConfig } from "../types";
2
+ import { captureWireAdapterHardPins } from "../types";
3
+ import { isCanonicalOpenAiForwardProvider } from "./openai-tiers";
4
+ import {
5
+ getProviderRegistryEntry,
6
+ providerMatchesRegistryTransport,
7
+ registryModelServiceTierCapabilityApplies,
8
+ type InboundWire,
9
+ type ModelWireDefault,
10
+ } from "./registry";
11
+ import {
12
+ cloneFastWire,
13
+ resolveFastPolicy,
14
+ resolveProviderAuthTransport,
15
+ type FastPolicyAuthority,
16
+ type ResolvedFastPolicy,
17
+ } from "./fastwire";
18
+
19
+ /** OpenAI-compatible adapters that can carry the standard `service_tier` field. */
20
+ export const SERVICE_TIER_ADAPTERS = new Set(["openai-chat", "openai-responses"]);
21
+
22
+ /** @deprecated A1 evolves this snapshot into the complete FastPolicyAuthority. */
23
+ export type CapturedServiceTierAdapterAuthority = FastPolicyAuthority;
24
+
25
+ const capturedFastPolicyAuthorities = new WeakMap<object, FastPolicyAuthority>();
26
+
27
+ type ServiceTierCapabilityProvider = Pick<
28
+ OcxProviderConfig,
29
+ | "adapter"
30
+ | "supportsServiceTier"
31
+ | "modelSupportsServiceTier"
32
+ | "modelAdapters"
33
+ | "baseUrl"
34
+ | "authMode"
35
+ | "apiKeyTransport"
36
+ | "chatServiceTier"
37
+ | "fastWire"
38
+ >;
39
+
40
+ function cloneRegistryWireDefaults(
41
+ defaults: Readonly<Record<string, ModelWireDefault>> | undefined,
42
+ ): Readonly<Record<string, ModelWireDefault>> {
43
+ if (!defaults) return Object.freeze({});
44
+ const clone: Record<string, ModelWireDefault> = {};
45
+ for (const [modelId, declaration] of Object.entries(defaults)) {
46
+ clone[modelId.trim().toLowerCase()] = typeof declaration === "string"
47
+ ? declaration
48
+ : Object.freeze({
49
+ wire: declaration.wire,
50
+ inbound: Object.freeze([...declaration.inbound]),
51
+ ...(declaration.authModes
52
+ ? { authModes: Object.freeze([...declaration.authModes]) }
53
+ : {}),
54
+ ...(declaration.forwardCallerServiceTier !== undefined
55
+ ? { forwardCallerServiceTier: declaration.forwardCallerServiceTier }
56
+ : {}),
57
+ });
58
+ }
59
+ return Object.freeze(clone);
60
+ }
61
+
62
+ /**
63
+ * Capture every registry-owned input before an asynchronous catalog flight begins.
64
+ * The resolver itself is pure and never reads the live provider registry.
65
+ */
66
+ function buildFastPolicyAuthority(
67
+ providerName: string,
68
+ provider: ServiceTierCapabilityProvider,
69
+ registryTransportMatch: boolean,
70
+ capabilityProvider: ServiceTierCapabilityProvider = provider,
71
+ ): FastPolicyAuthority {
72
+ const registry = registryTransportMatch ? getProviderRegistryEntry(providerName) : undefined;
73
+ const authTransport = resolveProviderAuthTransport(
74
+ provider.adapter,
75
+ provider.authMode ?? registry?.authKind ?? "key",
76
+ provider.apiKeyTransport,
77
+ );
78
+ const keyAuthDefaults = registry?.allowKeyAuthOverride === true
79
+ && (authTransport === "authorization_bearer" || authTransport === "x_api_key")
80
+ ? registry.keyAuthServiceTier
81
+ : undefined;
82
+ const registryModelCapabilities = registry
83
+ && registryModelServiceTierCapabilityApplies(registry, capabilityProvider)
84
+ ? registry.modelSupportsServiceTier
85
+ : undefined;
86
+ const providerCapability = capabilityProvider.supportsServiceTier
87
+ ?? keyAuthDefaults?.supportsServiceTier
88
+ ?? registry?.supportsServiceTier;
89
+ const authority: FastPolicyAuthority = Object.freeze({
90
+ providerAdapter: provider.adapter,
91
+ providerAuthMode: provider.authMode ?? registry?.authKind ?? "key",
92
+ fastWireDeclaration: cloneFastWire(
93
+ provider.fastWire !== undefined ? provider.fastWire : registry?.fastWire,
94
+ { freeze: true },
95
+ ),
96
+ ...(registry?.fastTierDescription !== undefined
97
+ ? { fastTierDescription: registry.fastTierDescription }
98
+ : {}),
99
+ modelWireOverrideAllowed: !isCanonicalOpenAiForwardProvider(provider as OcxProviderConfig),
100
+ authTransport,
101
+ capability: Object.freeze({
102
+ ...(providerCapability !== undefined ? { provider: providerCapability } : {}),
103
+ models: Object.freeze({
104
+ ...(registryModelCapabilities ?? {}),
105
+ ...(keyAuthDefaults?.modelSupportsServiceTier ?? {}),
106
+ ...(capabilityProvider.modelSupportsServiceTier ?? {}),
107
+ }),
108
+ ...(provider.chatServiceTier !== undefined
109
+ ? { chatServiceTier: provider.chatServiceTier }
110
+ : keyAuthDefaults?.chatServiceTier !== undefined
111
+ ? { chatServiceTier: keyAuthDefaults.chatServiceTier }
112
+ : {}),
113
+ }),
114
+ modelAdapters: Object.freeze({ ...(provider.modelAdapters ?? {}) }),
115
+ hardPins: captureWireAdapterHardPins(providerName),
116
+ registryWireDefaults: cloneRegistryWireDefaults(registry?.modelWireDefaults),
117
+ });
118
+ return authority;
119
+ }
120
+
121
+ export function captureFastPolicyAuthority(
122
+ providerName: string,
123
+ provider: ServiceTierCapabilityProvider,
124
+ registryTransportMatch: boolean,
125
+ capabilityProvider: ServiceTierCapabilityProvider = provider,
126
+ ): FastPolicyAuthority {
127
+ const authority = buildFastPolicyAuthority(
128
+ providerName,
129
+ provider,
130
+ registryTransportMatch,
131
+ capabilityProvider,
132
+ );
133
+ if (Object.isFrozen(provider)) capturedFastPolicyAuthorities.set(provider, authority);
134
+ return authority;
135
+ }
136
+
137
+ /** @deprecated Use captureFastPolicyAuthority. The legacy inbound argument is now snapshot data. */
138
+ export function captureServiceTierAdapterAuthority(
139
+ providerName: string,
140
+ provider: ServiceTierCapabilityProvider,
141
+ registryTransportMatch: boolean,
142
+ _inbound: InboundWire = "responses",
143
+ ): FastPolicyAuthority {
144
+ return captureFastPolicyAuthority(providerName, provider, registryTransportMatch);
145
+ }
146
+
147
+ function authorityForProvider(
148
+ provider: ServiceTierCapabilityProvider,
149
+ providerName?: string,
150
+ capabilityProvider?: ServiceTierCapabilityProvider,
151
+ ): FastPolicyAuthority {
152
+ // Preserve the legacy no-name short circuit: serviceTierSupportForModel() used the
153
+ // provider adapter directly when no provider identity was available, so no configured
154
+ // override, hard pin, or registry default may participate on this path in A1.
155
+ if (providerName === undefined) {
156
+ const authority = buildFastPolicyAuthority("", provider, false, capabilityProvider ?? provider);
157
+ return Object.freeze({
158
+ ...authority,
159
+ modelAdapters: Object.freeze({}),
160
+ hardPins: Object.freeze({}),
161
+ registryWireDefaults: Object.freeze({}),
162
+ });
163
+ }
164
+ const captured = capabilityProvider === undefined && Object.isFrozen(provider)
165
+ ? capturedFastPolicyAuthorities.get(provider)
166
+ : undefined;
167
+ if (captured) return captured;
168
+ const registryTransportMatch = providerMatchesRegistryTransport(providerName, provider);
169
+ const authority = buildFastPolicyAuthority(
170
+ providerName,
171
+ provider,
172
+ registryTransportMatch,
173
+ capabilityProvider ?? provider,
174
+ );
175
+ // Frozen provider snapshots cannot drift, so repeated catalog/runtime projections may safely
176
+ // reuse the registry lookup and detached declaration maps. Mutable configs still rebuild.
177
+ if (Object.isFrozen(provider)) capturedFastPolicyAuthorities.set(provider, authority);
178
+ return authority;
179
+ }
180
+
181
+ /** Resolve the pure Fast policy for a provider/model pair. */
182
+ export function fastPolicyForModel(
183
+ provider: ServiceTierCapabilityProvider,
184
+ modelId: string,
185
+ providerName?: string,
186
+ inbound: InboundWire = "responses",
187
+ capabilityProvider?: ServiceTierCapabilityProvider,
188
+ ): ResolvedFastPolicy {
189
+ return resolveFastPolicy(
190
+ authorityForProvider(provider, providerName, capabilityProvider),
191
+ modelId,
192
+ inbound,
193
+ );
194
+ }
195
+
196
+ /**
197
+ * Resolve the declared provider/model capability without applying wire availability.
198
+ * Kept as a public compatibility helper for callers that need the pure tri-state.
199
+ */
200
+ export function supportsServiceTierForModel(
201
+ provider: Pick<OcxProviderConfig, "supportsServiceTier" | "modelSupportsServiceTier">,
202
+ modelId: string,
203
+ ): boolean | undefined {
204
+ const authority: FastPolicyAuthority = {
205
+ providerAdapter: "openai-responses",
206
+ fastWireDeclaration: undefined,
207
+ modelWireOverrideAllowed: true,
208
+ authTransport: "authorization_bearer",
209
+ capability: {
210
+ ...(provider.supportsServiceTier !== undefined ? { provider: provider.supportsServiceTier } : {}),
211
+ models: provider.modelSupportsServiceTier ?? {},
212
+ },
213
+ modelAdapters: {},
214
+ hardPins: {},
215
+ registryWireDefaults: {},
216
+ };
217
+ return resolveFastPolicy(authority, modelId).capability;
218
+ }
219
+
220
+ /** Whether a Chat route may forward an arbitrary caller tier rather than canonical Fast. */
221
+ export function canForwardForeignServiceTierForChatModel(
222
+ provider: Pick<OcxProviderConfig, "supportsServiceTier" | "modelSupportsServiceTier" | "chatServiceTier">,
223
+ modelId: string,
224
+ ): boolean {
225
+ const capability = supportsServiceTierForModel(provider, modelId);
226
+ return capability !== false && provider.chatServiceTier === true;
227
+ }
228
+
229
+ /** Final adapter selected by the Fast policy's four-level wire resolver. */
230
+ export function serviceTierAdapterForModel(
231
+ providerName: string,
232
+ provider: ServiceTierCapabilityProvider,
233
+ modelId: string,
234
+ inbound: InboundWire = "responses",
235
+ ): string {
236
+ return fastPolicyForModel(provider, modelId, providerName, inbound).adapter;
237
+ }
238
+
239
+ /** Whether the final provider/model pair can publish/send OpenAI service tiers. */
240
+ export function canForwardServiceTierForModel(
241
+ provider: ServiceTierCapabilityProvider,
242
+ modelId: string,
243
+ providerName?: string,
244
+ inbound: InboundWire = "responses",
245
+ ): boolean {
246
+ return serviceTierSupportForModel(provider, modelId, providerName, inbound) === true;
247
+ }
248
+
249
+ /**
250
+ * Compatibility projection for catalog, routing, and fingerprint consumers. The new
251
+ * resolver carries richer eligibility internally while preserving the old tri-state bytes.
252
+ */
253
+ export function serviceTierSupportForModel(
254
+ provider: ServiceTierCapabilityProvider,
255
+ modelId: string,
256
+ providerName?: string,
257
+ inbound: InboundWire = "responses",
258
+ ): boolean | undefined {
259
+ const policy = fastPolicyForModel(provider, modelId, providerName, inbound);
260
+ return serviceTierSupportFromPolicy(policy);
261
+ }
262
+
263
+ /** Compatibility projection shared by catalog, routing, and request logging. */
264
+ export function serviceTierSupportFromPolicy(
265
+ policy: Pick<ResolvedFastPolicy, "eligibility" | "adapter" | "forwardCallerTier">,
266
+ ): boolean | undefined {
267
+ if (policy.eligibility === "eligible") return true;
268
+ if (policy.eligibility === "unclassified") {
269
+ // An unclassified route that cannot forward a caller tier has definitive negative
270
+ // evidence even when its adapter can normally serialize service_tier. This covers both
271
+ // Chat routes without chatServiceTier and a registry default that explicitly closes a
272
+ // subscription gateway. Generic unclassified Responses routes still project unknown.
273
+ if (!policy.forwardCallerTier) return false;
274
+ return undefined;
275
+ }
276
+ return false;
277
+ }