@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
@@ -14,12 +14,15 @@ import type { AdapterRequest, IncomingMeta, ProviderAdapter } from "../adapters/
14
14
  import { existsSync } from "node:fs";
15
15
  import { pathToFileURL } from "node:url";
16
16
  import { createAdapterEventQueue } from "../adapters/run-turn-queue";
17
- import type { AdapterEvent, OcxMessage, OcxParsedRequest, OcxProviderContinuationState, OcxRequestOptions, OcxThinkingContent, OcxUsage } from "../types";
18
- import { namespacedToolName } from "../types";
17
+ import type { AdapterEvent, OcxMessage, OcxParsedRequest, OcxProviderContinuationState, OcxProviderOpaqueToolCallMetadata, OcxRequestOptions, OcxThinkingContent, OcxUsage, RateLimitRetryPolicy } from "../types";
18
+ import { namespacedToolName, toolChoiceToolPredicate } from "../types";
19
+ import { cloneProviderOpaqueToolCallMetadata } from "../responses/provider-opaque-metadata";
20
+ import type { AttemptRecoveryKind } from "../usage/log";
19
21
  import { bridgeToResponsesSSE } from "../bridge";
20
22
  import { clearableDeadline, idleDeadline } from "../lib/abort";
21
23
  import { readBoundedResponseBody } from "../lib/bounded-body";
22
- import { fetchWithResetRetry } from "../lib/upstream-retry";
24
+ import { fetchWithResetRetry, prepareSameTarget429Wait } from "../lib/upstream-retry";
25
+ import { rateLimitRetryDelayMs } from "../providers/key-failover";
23
26
  import {
24
27
  isTranslatorBudgetExceededError,
25
28
  TRANSLATOR_MAX_TURN_BYTES,
@@ -91,6 +94,11 @@ interface ImageCall {
91
94
  id: string;
92
95
  name: string;
93
96
  args: string;
97
+ /**
98
+ * Provider-opaque metadata from the originating part (issue #1735). Stored PER CALL: a
99
+ * signature belongs to one specific part, so parallel calls must not share one value.
100
+ */
101
+ providerMetadata?: OcxProviderOpaqueToolCallMetadata;
94
102
  }
95
103
 
96
104
  /**
@@ -107,13 +115,13 @@ function scanEventsForImageCall(events: AdapterEvent[], toolNames: Set<string>):
107
115
  const calls: ImageCall[] = [];
108
116
  const passthrough: AdapterEvent[] = [];
109
117
  let hasRealToolCall = false;
110
- let pending: { name: string; id: string; argsBuf: string; events: AdapterEvent[] } | null = null;
118
+ let pending: { name: string; id: string; argsBuf: string; events: AdapterEvent[]; providerMetadata?: OcxProviderOpaqueToolCallMetadata } | null = null;
111
119
  const flushPending = (): void => {
112
120
  if (!pending) return;
113
121
  if (toolNames.has(pending.name)) {
114
122
  // Unterminated image call still carries buffered args — fulfill so malformed JSON
115
123
  // becomes a normal tool_result error instead of silently vanishing.
116
- calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf });
124
+ calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf, providerMetadata: pending.providerMetadata });
117
125
  } else {
118
126
  passthrough.push(...pending.events);
119
127
  hasRealToolCall = true;
@@ -123,14 +131,14 @@ function scanEventsForImageCall(events: AdapterEvent[], toolNames: Set<string>):
123
131
  for (const e of events) {
124
132
  if (e.type === "tool_call_start") {
125
133
  flushPending();
126
- pending = { name: e.name, id: e.id, argsBuf: "", events: [e] };
134
+ pending = { name: e.name, id: e.id, argsBuf: "", events: [e], providerMetadata: e.providerMetadata };
127
135
  } else if (e.type === "tool_call_delta" && pending) {
128
136
  pending.argsBuf += e.arguments;
129
137
  pending.events.push(e);
130
138
  } else if (e.type === "tool_call_end" && pending) {
131
139
  pending.events.push(e);
132
140
  if (toolNames.has(pending.name)) {
133
- calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf });
141
+ calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf, providerMetadata: pending.providerMetadata });
134
142
  } else {
135
143
  passthrough.push(...pending.events);
136
144
  hasRealToolCall = true;
@@ -159,6 +167,7 @@ function extractIterationThinking(events: AdapterEvent[]): OcxThinkingContent[]
159
167
  const parts: OcxThinkingContent[] = [];
160
168
  let thinking = "";
161
169
  let signature: string | undefined;
170
+ let rawReasoning = "";
162
171
 
163
172
  const flushVisible = () => {
164
173
  if (!thinking && !signature) return;
@@ -170,19 +179,33 @@ function extractIterationThinking(events: AdapterEvent[]): OcxThinkingContent[]
170
179
  thinking = "";
171
180
  signature = undefined;
172
181
  };
182
+ const flushRaw = () => {
183
+ if (!rawReasoning) return;
184
+ parts.push({ type: "thinking", thinking: rawReasoning });
185
+ rawReasoning = "";
186
+ };
173
187
 
174
188
  for (const e of events) {
175
189
  if (e.type === "thinking_delta") {
190
+ flushRaw();
176
191
  thinking += e.thinking;
192
+ } else if (e.type === "reasoning_raw_delta") {
193
+ // OpenAI-compatible providers emit raw reasoning instead of signed
194
+ // thinking; DeepSeek thinking mode requires it back alongside replayed
195
+ // tool_calls (mirrors src/web-search/loop.ts, issue #950).
196
+ flushVisible();
197
+ rawReasoning += e.text;
177
198
  } else if (e.type === "thinking_signature") {
178
199
  signature = e.signature;
179
200
  flushVisible();
180
201
  } else if (e.type === "redacted_thinking") {
181
202
  flushVisible();
203
+ flushRaw();
182
204
  parts.push({ type: "thinking", thinking: "", redacted: [e.data] });
183
205
  }
184
206
  }
185
207
  flushVisible();
208
+ flushRaw();
186
209
  return parts;
187
210
  }
188
211
 
@@ -202,6 +225,10 @@ class LoopError extends Error {
202
225
  }
203
226
  }
204
227
 
228
+ /**
229
+ * Dependencies for one image-bridge iteration: parsed request, active adapter, incoming
230
+ * metadata, and the optional image/video bridge plans.
231
+ */
205
232
  export interface ImageBridgeDeps {
206
233
  parsed: OcxParsedRequest;
207
234
  adapter: ProviderAdapter;
@@ -212,8 +239,8 @@ export interface ImageBridgeDeps {
212
239
  videoTimeoutMs?: number;
213
240
  /** Headers forwarded from the original request (e.g. Codex auth). Cloned per iteration. */
214
241
  forwardHeaders?: Headers;
215
- /** Called before each routed-model dispatch in the bridge loop, for attempt telemetry. */
216
- onAttemptSend?: () => void;
242
+ /** Called before each routed-model dispatch in the bridge loop, for attempt telemetry. Same-target 429 replays pass the `rate-limit-429` recovery kind. */
243
+ onAttemptSend?: (recovery?: AttemptRecoveryKind) => void;
217
244
  /** Called after each upstream request is built (parity with web-search / normal path). */
218
245
  onRequestBuilt?: (request: AdapterRequest) => void;
219
246
  abortSignal?: AbortSignal;
@@ -226,13 +253,18 @@ export interface ImageBridgeDeps {
226
253
  stallTimeoutSec?: number;
227
254
  /** Provider-specific fetch (e.g. xAI transport wrapper). Falls back to global fetch. */
228
255
  fetchImpl?: typeof globalThis.fetch;
256
+ /** Reserve the routed provider's next request-start slot before each adapter dispatch. */
257
+ waitForRequestSlot?: (signal?: AbortSignal) => Promise<void>;
229
258
  /** Raw adapter usage at the terminal event, pre wire-normalization (see bridgeToResponsesSSE onUsage). */
230
259
  onUsage?: (usage: OcxUsage | undefined) => void;
231
260
  /**
232
- * Optional 429 key-failover for the routed (non-xAI) model. Return a rebuilt adapter for the
233
- * rotated key, or null when the pool is exhausted.
261
+ * Optional 429 failover for the routed (non-xAI) model. Return a rebuilt adapter for the
262
+ * rotated credential, or null when the pool is exhausted. Async hooks support OAuth refresh;
263
+ * existing synchronous key-pool hooks remain valid.
234
264
  */
235
- on429?: (retryAfterHeader: string | null) => ProviderAdapter | null;
265
+ on429?: (retryAfterHeader: string | null) => ProviderAdapter | null | Promise<ProviderAdapter | null>;
266
+ /** Opt-in same-target 429 policy (key-auth providers). When present, 429 replays on the SAME key before on429 rotation. */
267
+ retryOn429Policy?: Required<RateLimitRetryPolicy> | null;
236
268
  /** Called when the bridged Responses stream completes (parity with runTurn / routed paths). */
237
269
  onCompletedResponse?: (response: Record<string, unknown>, providerState?: OcxProviderContinuationState) => void;
238
270
  /** WebSocket Responses path only — leave response id empty for protocol compatibility. */
@@ -331,9 +363,20 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
331
363
  }
332
364
  type IterationSplit = ReturnType<typeof scanEventsForImageCall>;
333
365
 
366
+ // Same-target 429 budget is per REQUEST, not per model iteration: later image rounds inherit
367
+ // what earlier rounds left of `attempts`, so a bounded multi-round turn can never exceed the
368
+ // configured replay count in total (a per-round reset would multiply it by maxRounds).
369
+ const rateLimitRetryPolicy = deps.retryOn429Policy ?? null;
370
+ let rateLimitRetries = 0;
371
+
334
372
  // Acquire one iteration's final response headers. The first call is drained eagerly so an initial
335
373
  // connect/header/HTTP failure stays a non-2xx JSON response — except for runTurn adapters, which
336
374
  // have no HTTP status surface and must not block SSE headers behind queue.collect().
375
+ /**
376
+ * Fetch one image-bridge iteration's final response headers, applying the response-header
377
+ * deadline and the same-target 429 retry policy (with awaited body release and deadline
378
+ * restart) before the `on429` key rotation.
379
+ */
337
380
  const prepareIterationEvents = async function* (forceFinal: boolean): AsyncGenerator<AdapterEvent, IterationResponse> {
338
381
  const iterParsed: OcxParsedRequest = {
339
382
  ...parsed,
@@ -346,6 +389,7 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
346
389
  // expose buildRequest/fetchResponse/parseStream to the bridge, so collect their events through
347
390
  // an AdapterEventQueue and wrap them in a pseudo-response whose parseStream replays them.
348
391
  if (adapter.runTurn) {
392
+ await deps.waitForRequestSlot?.(signal);
349
393
  const queue = createAdapterEventQueue({
350
394
  onBacklogExceeded: () => internalAbort.abort("runTurn backlog exceeded"),
351
395
  });
@@ -422,27 +466,59 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
422
466
  return { response: new Response(new Uint8Array(0), { status: 200 }), responseAdapter: wrappedAdapter };
423
467
  }
424
468
 
425
- const headerDeadline = clearableDeadline(connectTimeoutMs, signal);
469
+ let headerDeadline = clearableDeadline(connectTimeoutMs, signal);
470
+ const paceThenResetHeaderDeadline = async (): Promise<void> => {
471
+ headerDeadline.clear();
472
+ await deps.waitForRequestSlot?.(signal);
473
+ headerDeadline = clearableDeadline(connectTimeoutMs, signal);
474
+ };
426
475
  try {
427
- const fetchOnce = async (requestAdapter: ProviderAdapter): Promise<IterationResponse> => {
428
- const request = await requestAdapter.buildRequest(iterParsed, {
429
- headers: deps.forwardHeaders ? new Headers(deps.forwardHeaders) : new Headers(),
430
- abortSignal: headerDeadline.signal,
431
- translatorBudget,
432
- });
433
- try { deps.onRequestBuilt?.(request); } catch { /* diagnostics are best-effort */ }
434
- deps.onAttemptSend?.();
476
+ /**
477
+ * Build and fetch one image-bridge iteration on the given adapter, under the iteration
478
+ * header deadline. The caller owns same-target 429 replays and key rotation around it.
479
+ * The outbound request is cached per adapter so a same-target replay reuses the EXACT
480
+ * URL, serialized body, and headers (builder runs once per target sequence).
481
+ */
482
+ let cachedRequest: AdapterRequest | undefined;
483
+ let cachedAdapter: ProviderAdapter | undefined;
484
+ /**
485
+ * Build and fetch one image-bridge iteration on the given adapter, under the iteration
486
+ * header deadline. The caller owns same-target 429 replays and key rotation around it.
487
+ */
488
+ const fetchOnce = async (requestAdapter: ProviderAdapter, recovery?: AttemptRecoveryKind): Promise<IterationResponse> => {
489
+ let request: AdapterRequest;
490
+ if (cachedRequest !== undefined && cachedAdapter === requestAdapter) {
491
+ request = cachedRequest;
492
+ } else {
493
+ request = await requestAdapter.buildRequest(iterParsed, {
494
+ headers: deps.forwardHeaders ? new Headers(deps.forwardHeaders) : new Headers(),
495
+ abortSignal: headerDeadline.signal,
496
+ translatorBudget,
497
+ });
498
+ try { deps.onRequestBuilt?.(request); } catch { /* diagnostics are best-effort */ }
499
+ cachedRequest = request;
500
+ cachedAdapter = requestAdapter;
501
+ }
435
502
  let response: Response;
436
503
  try {
437
- response = requestAdapter.fetchResponse
438
- ? await requestAdapter.fetchResponse(request, {
504
+ if (requestAdapter.fetchResponse) {
505
+ await paceThenResetHeaderDeadline();
506
+ deps.onAttemptSend?.(recovery);
507
+ response = await requestAdapter.fetchResponse(request, {
439
508
  abortSignal: headerDeadline.signal,
440
509
  timeoutMs: connectTimeoutMs,
441
510
  returnRawErrors: true,
442
511
  stream: true,
443
- })
444
- : await fetchWithResetRetry(
445
- () => {
512
+ executor: fetchImpl,
513
+ });
514
+ } else {
515
+ response = await fetchWithResetRetry(
516
+ async (retryRecovery) => {
517
+ await paceThenResetHeaderDeadline();
518
+ // Record every helper-driven send (the callback runs for the first attempt and
519
+ // each connection-reset replay); preserve the caller's recovery kind
520
+ // (rate-limit-429 / key-429) when the retry layer supplies none.
521
+ deps.onAttemptSend?.(retryRecovery ?? recovery);
446
522
  const h = new Headers(request.headers);
447
523
  if (!h.has("accept-encoding")) h.set("accept-encoding", "identity");
448
524
  return fetchImpl(request.url, {
@@ -453,7 +529,8 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
453
529
  });
454
530
  },
455
531
  { abortSignal: headerDeadline.signal, label: "image-bridge-loop" },
456
- );
532
+ );
533
+ }
457
534
  } finally {
458
535
  request.releaseBodyObservation?.();
459
536
  }
@@ -461,14 +538,47 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
461
538
  };
462
539
 
463
540
  let prepared = await fetchOnce(adapter);
541
+ // Same-target 429 wait-and-retry (opt-in `retryOn429`) BEFORE key rotation: a primary-key
542
+ // rate-limit blip replays on the SAME key; rotation only runs after attempts exhaust.
543
+ while (
544
+ prepared.response.status === 429
545
+ && rateLimitRetryPolicy !== null
546
+ && rateLimitRetries < rateLimitRetryPolicy.attempts
547
+ ) {
548
+ rateLimitRetries += 1;
549
+ // Release unread body + heartbeat-fed wait via the shared same-target helper.
550
+ const retryAfterHeader = prepared.response.headers.get("retry-after");
551
+ // The old header deadline must not stay armed across the deliberate wait: clear it
552
+ // before sleeping so a stale expiry can never race the client-cancel path.
553
+ headerDeadline.clear();
554
+ try {
555
+ yield* prepareSameTarget429Wait({
556
+ body: prepared.response.body,
557
+ signal,
558
+ delayMs: rateLimitRetryDelayMs(rateLimitRetryPolicy, retryAfterHeader, Date.now()),
559
+ heartbeatIntervalMs: Math.min(10_000, Math.max(250, stallTimeoutMs / 2)),
560
+ });
561
+ } catch {
562
+ throw new LoopError(499, "client closed request during image-bridge");
563
+ }
564
+ // Client cancellation wins over any stale-deadline edge: re-check before telemetry/replay.
565
+ if (signal.aborted) throw new LoopError(499, "client closed request during image-bridge");
566
+ // The deliberate backoff must not consume the cumulative response-header deadline:
567
+ // start a fresh one so the replay gets a new connect budget (504 stays reserved for real
568
+ // upstream latency).
569
+ headerDeadline = clearableDeadline(connectTimeoutMs, signal);
570
+ // Stall-watchdog seam between bounded retry fetches.
571
+ yield { type: "heartbeat" };
572
+ prepared = await fetchOnce(adapter, "rate-limit-429");
573
+ }
464
574
  // 429 key-failover parity with web-search / normal routed path.
465
575
  while (prepared.response.status === 429 && deps.on429) {
466
- const rotated = deps.on429(prepared.response.headers.get("retry-after"));
576
+ const rotated = await deps.on429(prepared.response.headers.get("retry-after"));
467
577
  if (!rotated) break;
468
578
  try { void prepared.response.body?.cancel().catch(() => {}); } catch { /* already closed */ }
469
579
  adapter = rotated;
470
580
  yield { type: "heartbeat" };
471
- prepared = await fetchOnce(adapter);
581
+ prepared = await fetchOnce(adapter, "key-429");
472
582
  }
473
583
 
474
584
  // Final headers have arrived. Clear only the deadline timer before ANY body read.
@@ -567,11 +677,20 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
567
677
  }
568
678
  }
569
679
 
570
- const toolNsMap = new Map<string, { namespace: string; name: string }>();
680
+ const toolNsMap = new Map<string, { namespace: string; name: string; freeform?: true }>();
571
681
  const freeform = new Set<string>();
572
682
  const toolSearch = new Set<string>();
573
- for (const t of parsed.context.tools ?? []) {
574
- if (t.namespace) toolNsMap.set(namespacedToolName(t.namespace, t.name), { namespace: t.namespace, name: t.name });
683
+ const requestedTools = parsed.context.tools ?? [];
684
+ const toolAllowed = toolChoiceToolPredicate(parsed.options.toolChoice, requestedTools);
685
+ for (const t of requestedTools) {
686
+ if (!toolAllowed(t)) continue;
687
+ if (t.namespace) {
688
+ toolNsMap.set(namespacedToolName(t.namespace, t.name), {
689
+ namespace: t.namespace,
690
+ name: t.name,
691
+ ...(t.freeform ? { freeform: true } : {}),
692
+ });
693
+ }
575
694
  if (t.freeform) freeform.add(t.name);
576
695
  if (t.toolSearch) toolSearch.add(t.name);
577
696
  }
@@ -767,6 +886,10 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
767
886
  id: call.id,
768
887
  name: call.name,
769
888
  arguments: args,
889
+ // Clone per call: parallel media calls each keep their own signature.
890
+ ...(cloneProviderOpaqueToolCallMetadata(call.providerMetadata)
891
+ ? { providerMetadata: cloneProviderOpaqueToolCallMetadata(call.providerMetadata) }
892
+ : {}),
770
893
  })),
771
894
  ],
772
895
  timestamp: now,
@@ -808,11 +931,12 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
808
931
  }
809
932
 
810
933
  const sse = bridgeToResponsesSSE(
811
- produce(), parsed.modelId, toolNsMap, freeform, toolSearch, () => {
934
+ produce(), parsed._responseModelId ?? parsed.modelId, toolNsMap, freeform, toolSearch, () => {
812
935
  internalAbort.abort("client closed responses stream");
813
936
  }, 2_000,
814
937
  {
815
938
  translatorBudget,
939
+ replayCacheScope: parsed._reasoningReplayScope,
816
940
  ...(deps.forceEmptyResponseId ? { responseId: "" } : {}),
817
941
  hideThinkingSummary: parsed.options.hideThinkingSummary,
818
942
  stallTimeoutSec: deps.stallTimeoutSec,
@@ -1,4 +1,5 @@
1
1
  import type { OcxConfig, OcxParsedRequest, OcxProviderConfig } from "../types";
2
+ import { toolChoiceToolPredicate } from "../types";
2
3
  import type { ImageBridgePlan, VideoBridgePlan } from "./types";
3
4
  import { resolveEnvValue } from "../config";
4
5
  import { getProviderRegistryEntry } from "../providers/registry";
@@ -46,6 +47,13 @@ export async function planImageBridge(
46
47
  ): Promise<ImageBridgePlan | undefined> {
47
48
  if (config.images?.bridgeEnabled !== true) return undefined;
48
49
  if (!parsed._imageGeneration) return undefined;
50
+ const toolAllowed = toolChoiceToolPredicate(parsed.options.toolChoice);
51
+ const toolNames = new Set([...parsed._imageGeneration.toolNames].filter(name => toolAllowed({ name })));
52
+ if (toolAllowed({ name: IMAGE_GEN_TOOL_NAME })) toolNames.add(IMAGE_GEN_TOOL_NAME);
53
+ if (toolNames.size === 0) return undefined;
54
+ // Responses advertises and rewrites authorized aliases to this synthetic name, so the loop
55
+ // must always intercept it once any image-generation name has armed the bridge.
56
+ toolNames.add(IMAGE_GEN_TOOL_NAME);
49
57
  // Don't intercept for OpenAI native passthrough
50
58
  const host = (() => { try { return new URL(routedProvider.baseUrl).hostname; } catch { return ""; } })();
51
59
  if (host === "api.openai.com") return undefined;
@@ -57,9 +65,7 @@ export async function planImageBridge(
57
65
  const registryEntry = getProviderRegistryEntry("xai");
58
66
  const pinnedBaseUrl = (registryEntry?.baseUrl ?? "https://api.x.ai/v1").replace(/\/+$/, "");
59
67
  // The synthetic tool injected into the conversation is named IMAGE_GEN_TOOL_NAME,
60
- // which is what the model will actually call. Merge it with any original hosted tool names.
61
- const toolNames = new Set(parsed._imageGeneration.toolNames);
62
- toolNames.add(IMAGE_GEN_TOOL_NAME);
68
+ // which is what the model will actually call. toolNames also retains authorized hosted aliases.
63
69
  const original = parsed._imageGeneration.originalTool;
64
70
  const hostedSize = typeof original?.size === "string" ? original.size : undefined;
65
71
  const hostedQuality = typeof original?.quality === "string" ? original.quality : undefined;
@@ -95,16 +101,6 @@ export async function planVideoBridge(
95
101
  routedProvider: OcxProviderConfig,
96
102
  ): Promise<VideoBridgePlan | undefined> {
97
103
  if (config.images?.videoBridgeEnabled !== true) return undefined;
98
- // Don't intercept for OpenAI native passthrough
99
- const host = (() => { try { return new URL(routedProvider.baseUrl).hostname; } catch { return ""; } })();
100
- if (host === "api.openai.com") return undefined;
101
- const found = findXaiProvider(config);
102
- if (!found) return undefined;
103
- const token = resolveXaiImageApiKey(found.provider);
104
- if (!token) return undefined;
105
- // Pin the baseUrl to the registry entry, ignoring any config-level baseUrl override.
106
- const registryEntry = getProviderRegistryEntry("xai");
107
- const pinnedBaseUrl = (registryEntry?.baseUrl ?? "https://api.x.ai/v1").replace(/\/+$/, "");
108
104
  const toolNames = new Set<string>();
109
105
  toolNames.add(VIDEO_GEN_TOOL_NAME);
110
106
  // Collect any existing function tools whose name matches a video_gen alias
@@ -118,6 +114,21 @@ export async function planVideoBridge(
118
114
  toolNames.add(fnName);
119
115
  }
120
116
  }
117
+ const toolAllowed = toolChoiceToolPredicate(parsed.options?.toolChoice);
118
+ for (const name of toolNames) {
119
+ if (!toolAllowed({ name })) toolNames.delete(name);
120
+ }
121
+ if (toolNames.size === 0) return undefined;
122
+ // Don't intercept for OpenAI native passthrough
123
+ const host = (() => { try { return new URL(routedProvider.baseUrl).hostname; } catch { return ""; } })();
124
+ if (host === "api.openai.com") return undefined;
125
+ const found = findXaiProvider(config);
126
+ if (!found) return undefined;
127
+ const token = resolveXaiImageApiKey(found.provider);
128
+ if (!token) return undefined;
129
+ // Pin the baseUrl to the registry entry, ignoring any config-level baseUrl override.
130
+ const registryEntry = getProviderRegistryEntry("xai");
131
+ const pinnedBaseUrl = (registryEntry?.baseUrl ?? "https://api.x.ai/v1").replace(/\/+$/, "");
121
132
  const timeoutMs = clampImageTimeoutMs(config.images?.videoTimeoutMs);
122
133
  const keepRaw = config.images?.artifactsKeepCount;
123
134
  const artifactsKeepCount =