@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,363 @@
1
+ import type { TranslatorBudget } from "../lib/translator-budget";
2
+ import { normalizeApplyPatchDelimiters } from "../responses/apply-patch-envelope";
3
+ import { compileCodeModeHelperInput } from "../responses/code-mode-helper-compat";
4
+ import {
5
+ customToolItemId,
6
+ restoreRoutedCustomCalls,
7
+ routedCustomToolTargetName,
8
+ routedCustomToolWireName,
9
+ unwrapRoutedCustomToolArguments,
10
+ } from "../responses/custom-tool-compat";
11
+ import {
12
+ replaceSseDataPayload,
13
+ sseDataPayload,
14
+ type SseBlockRewrite,
15
+ } from "./sse-payload-rewrite";
16
+
17
+ /** Exact compact prefix used by our upstream rewriter; progressive matching also
18
+ * tolerates insignificant JSON whitespace via FREEFORM_WRAP_PREFIX_RE. */
19
+ const FREEFORM_WRAP_PREFIX = '{"input":"';
20
+ const FREEFORM_WRAP_PREFIX_RE = /^\s*\{\s*"input"\s*:\s*"/;
21
+
22
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
23
+ return !!value && typeof value === "object" && !Array.isArray(value);
24
+ }
25
+
26
+ /**
27
+ * Progressive decode of the freeform `{ "input": "…" }` wrapper.
28
+ * Returns null when the accumulated text does not (yet) match that wrapper so
29
+ * callers suppress deltas and rely on `response.custom_tool_call_input.done`.
30
+ */
31
+ function partialCustomToolInput(argumentsText: string): string | null {
32
+ const match = FREEFORM_WRAP_PREFIX_RE.exec(argumentsText);
33
+ if (!match) return null;
34
+ const body = argumentsText.slice(match[0]!.length);
35
+ let output = "";
36
+ for (let index = 0; index < body.length; index++) {
37
+ const char = body[index];
38
+ if (char === '"') break;
39
+ if (char !== "\\") {
40
+ output += char;
41
+ continue;
42
+ }
43
+ const escaped = body[index + 1];
44
+ if (escaped === undefined) break;
45
+ index += 1;
46
+ if (escaped === "n") output += "\n";
47
+ else if (escaped === "t") output += "\t";
48
+ else if (escaped === "r") output += "\r";
49
+ else if (escaped === "b") output += "\b";
50
+ else if (escaped === "f") output += "\f";
51
+ else if (escaped === "u") {
52
+ const hex = body.slice(index + 1, index + 5);
53
+ if (hex.length !== 4 || !/^[0-9a-fA-F]{4}$/.test(hex)) break;
54
+ output += String.fromCharCode(Number.parseInt(hex, 16));
55
+ index += 4;
56
+ } else output += escaped;
57
+ }
58
+ return output;
59
+ }
60
+
61
+ function replaceSseEventName(block: string, type: string): string {
62
+ const newline = block.includes("\r\n") ? "\r\n" : "\n";
63
+ const lines = block.split(/\r?\n/);
64
+ let replaced = false;
65
+ const next = lines.map(line => {
66
+ if (!replaced && line.startsWith("event:")) {
67
+ replaced = true;
68
+ return `event: ${type}`;
69
+ }
70
+ return line;
71
+ });
72
+ return next.join(newline);
73
+ }
74
+
75
+ type OpenCustomCall = {
76
+ argumentsText: string;
77
+ emittedInput: string;
78
+ retainedBytes: number;
79
+ };
80
+
81
+ type PendingArgumentBlock = {
82
+ block: string;
83
+ itemId?: string;
84
+ outputIndex?: number;
85
+ retainedBytes: number;
86
+ };
87
+
88
+ export function createRoutedCustomToolRestoreBlockRewrite(
89
+ names: ReadonlySet<string>,
90
+ budget?: TranslatorBudget,
91
+ repairNames: ReadonlySet<string> = new Set(),
92
+ declaredNames?: ReadonlySet<string>,
93
+ ): SseBlockRewrite {
94
+ const itemNames = new Map<string, { name: string; aliased: boolean; namespace?: string }>();
95
+ const customAliasItemNames = new Map<string, string>();
96
+ const repairItemNames = new Map<string, string>();
97
+ const ordinaryItemIds = new Set<string>();
98
+ const openCalls = new Map<string, OpenCustomCall>();
99
+ let pendingArguments: PendingArgumentBlock[] = [];
100
+ let disposed = false;
101
+
102
+ const releaseCall = (itemId: string): void => {
103
+ const open = openCalls.get(itemId);
104
+ if (!open) return;
105
+ if (open.retainedBytes > 0) {
106
+ budget?.releaseRetained(open.retainedBytes, { kind: "retained_collectors" });
107
+ }
108
+ openCalls.delete(itemId);
109
+ };
110
+
111
+ const releaseAll = (): void => {
112
+ if (disposed) return;
113
+ disposed = true;
114
+ for (const itemId of openCalls.keys()) releaseCall(itemId);
115
+ const pendingBytes = pendingArguments.reduce((total, pending) => total + pending.retainedBytes, 0);
116
+ if (pendingBytes > 0) {
117
+ budget?.releaseRetained(pendingBytes, { kind: "retained_collectors" });
118
+ }
119
+ pendingArguments = [];
120
+ itemNames.clear();
121
+ customAliasItemNames.clear();
122
+ repairItemNames.clear();
123
+ ordinaryItemIds.clear();
124
+ };
125
+
126
+ const retainPendingArgument = (
127
+ block: string,
128
+ itemId: string | undefined,
129
+ outputIndex: number | undefined,
130
+ ): void => {
131
+ const retainedBytes = Buffer.byteLength(block, "utf8");
132
+ if (retainedBytes > 0) budget?.chargeRetained(retainedBytes, { kind: "retained_collectors" });
133
+ pendingArguments.push({ block, itemId, outputIndex, retainedBytes });
134
+ };
135
+
136
+ const takePendingArguments = (
137
+ itemId: string | undefined,
138
+ outputIndex: number | undefined,
139
+ ): string[] => {
140
+ const matched: PendingArgumentBlock[] = [];
141
+ const remaining: PendingArgumentBlock[] = [];
142
+ for (const pending of pendingArguments) {
143
+ const matches = pending.itemId !== undefined
144
+ ? itemId !== undefined && pending.itemId === itemId
145
+ : outputIndex !== undefined && pending.outputIndex === outputIndex;
146
+ (matches ? matched : remaining).push(pending);
147
+ }
148
+ pendingArguments = remaining;
149
+ const retainedBytes = matched.reduce((total, pending) => total + pending.retainedBytes, 0);
150
+ if (retainedBytes > 0) {
151
+ budget?.releaseRetained(retainedBytes, { kind: "retained_collectors" });
152
+ }
153
+ // Index-matched entries carry no item id. Stamp the resolved id so replay
154
+ // classifies the event instead of buffering it a second time.
155
+ return matched.map(pending => {
156
+ if (pending.itemId !== undefined || itemId === undefined) return pending.block;
157
+ const payload = sseDataPayload(pending.block);
158
+ if (payload === null) return pending.block;
159
+ try {
160
+ const parsed: unknown = JSON.parse(payload);
161
+ if (!isPlainObject(parsed)) return pending.block;
162
+ return replaceSseDataPayload(pending.block, JSON.stringify({ ...parsed, item_id: itemId }));
163
+ } catch {
164
+ return pending.block;
165
+ }
166
+ });
167
+ };
168
+
169
+ const rewrite: SseBlockRewrite = (block: string): readonly string[] => {
170
+ if (disposed) return [block];
171
+ const payload = sseDataPayload(block);
172
+ if (payload === null || payload === "[DONE]") return [block];
173
+ let parsed: unknown;
174
+ try {
175
+ parsed = JSON.parse(payload);
176
+ } catch {
177
+ return [block];
178
+ }
179
+ if (!isPlainObject(parsed)) return [block];
180
+
181
+ const type = typeof parsed.type === "string" ? parsed.type : "";
182
+ const outputIndex = typeof parsed.output_index === "number"
183
+ && Number.isInteger(parsed.output_index)
184
+ && parsed.output_index >= 0
185
+ ? parsed.output_index
186
+ : undefined;
187
+ if (
188
+ (type === "response.output_item.added" || type === "response.output_item.done")
189
+ && isPlainObject(parsed.item)
190
+ && parsed.item.type === "custom_tool_call"
191
+ && typeof parsed.item.name === "string"
192
+ ) {
193
+ const upstreamItemId = typeof parsed.item.id === "string" ? parsed.item.id : undefined;
194
+ const wireName = routedCustomToolWireName(parsed.item);
195
+ const targetName = routedCustomToolTargetName(parsed.item, names, declaredNames);
196
+ const aliased = targetName !== undefined && targetName !== wireName;
197
+ if (upstreamItemId && aliased) {
198
+ customAliasItemNames.set(upstreamItemId, parsed.item.name);
199
+ if (type === "response.output_item.added") {
200
+ openCalls.set(upstreamItemId, { argumentsText: "", emittedInput: "", retainedBytes: 0 });
201
+ }
202
+ }
203
+ const repairable = wireName !== undefined && repairNames.has(wireName);
204
+ if (upstreamItemId && repairable) repairItemNames.set(upstreamItemId, parsed.item.name);
205
+ const restored = repairable || aliased
206
+ ? restoreRoutedCustomCalls(parsed, names, repairNames, declaredNames)
207
+ : { value: parsed, changed: false };
208
+ if (type === "response.output_item.done" && upstreamItemId) releaseCall(upstreamItemId);
209
+ return restored.changed
210
+ ? [replaceSseDataPayload(block, JSON.stringify(restored.value))]
211
+ : [block];
212
+ }
213
+ if (
214
+ (type === "response.output_item.added" || type === "response.output_item.done")
215
+ && isPlainObject(parsed.item)
216
+ && parsed.item.type === "function_call"
217
+ && typeof parsed.item.name === "string"
218
+ ) {
219
+ const upstreamItemId = typeof parsed.item.id === "string" ? parsed.item.id : undefined;
220
+ const targetName = routedCustomToolTargetName(parsed.item, names, declaredNames);
221
+ const routed = targetName !== undefined;
222
+ const wireName = routedCustomToolWireName(parsed.item);
223
+ if (upstreamItemId) {
224
+ if (routed) {
225
+ itemNames.set(upstreamItemId, {
226
+ name: parsed.item.name,
227
+ aliased: targetName !== wireName,
228
+ ...(typeof parsed.item.namespace === "string" ? { namespace: parsed.item.namespace } : {}),
229
+ });
230
+ ordinaryItemIds.delete(upstreamItemId);
231
+ } else {
232
+ ordinaryItemIds.add(upstreamItemId);
233
+ }
234
+ if (routed && type === "response.output_item.added") {
235
+ openCalls.set(upstreamItemId, { argumentsText: "", emittedInput: "", retainedBytes: 0 });
236
+ }
237
+ }
238
+ const pending = takePendingArguments(upstreamItemId, outputIndex);
239
+ if (!routed) {
240
+ if (type === "response.output_item.done" && upstreamItemId) ordinaryItemIds.delete(upstreamItemId);
241
+ return [...pending, block];
242
+ }
243
+ if (upstreamItemId && pending.length > 0 && !openCalls.has(upstreamItemId)) {
244
+ openCalls.set(upstreamItemId, { argumentsText: "", emittedInput: "", retainedBytes: 0 });
245
+ }
246
+ const restored = restoreRoutedCustomCalls(parsed, names, repairNames, declaredNames);
247
+ const restoredBlock = restored.changed
248
+ ? replaceSseDataPayload(block, JSON.stringify(restored.value))
249
+ : block;
250
+ const replayed = pending.flatMap(pendingBlock => rewrite(pendingBlock));
251
+ if (type === "response.output_item.done" && upstreamItemId) releaseCall(upstreamItemId);
252
+ return type === "response.output_item.added"
253
+ ? [restoredBlock, ...replayed]
254
+ : [...replayed, restoredBlock];
255
+ }
256
+
257
+ const upstreamItemId = typeof parsed.item_id === "string" ? parsed.item_id : undefined;
258
+ if (
259
+ type === "response.custom_tool_call_input.delta"
260
+ && upstreamItemId
261
+ && customAliasItemNames.has(upstreamItemId)
262
+ ) {
263
+ const open = openCalls.get(upstreamItemId) ?? { argumentsText: "", emittedInput: "", retainedBytes: 0 };
264
+ const delta = typeof parsed.delta === "string" ? parsed.delta : "";
265
+ const deltaBytes = Buffer.byteLength(delta, "utf8");
266
+ if (deltaBytes > 0) budget?.chargeRetained(deltaBytes, { kind: "retained_collectors" });
267
+ open.argumentsText += delta;
268
+ open.retainedBytes += deltaBytes;
269
+ openCalls.set(upstreamItemId, open);
270
+ return [];
271
+ }
272
+ if (
273
+ type === "response.custom_tool_call_input.done"
274
+ && upstreamItemId
275
+ && customAliasItemNames.has(upstreamItemId)
276
+ ) {
277
+ const source = typeof parsed.input === "string"
278
+ ? parsed.input
279
+ : openCalls.get(upstreamItemId)?.argumentsText ?? "";
280
+ return [replaceSseDataPayload(block, JSON.stringify({
281
+ ...parsed,
282
+ input: compileCodeModeHelperInput(source, customAliasItemNames.get(upstreamItemId)!),
283
+ }))];
284
+ }
285
+ if (
286
+ type === "response.custom_tool_call_input.done"
287
+ && upstreamItemId
288
+ && repairItemNames.has(upstreamItemId)
289
+ && typeof parsed.input === "string"
290
+ ) {
291
+ const input = normalizeApplyPatchDelimiters(parsed.input);
292
+ if (input !== parsed.input) {
293
+ return [replaceSseDataPayload(block, JSON.stringify({ ...parsed, input }))];
294
+ }
295
+ }
296
+ const argumentEvent = type === "response.function_call_arguments.delta"
297
+ || type === "response.function_call_arguments.done";
298
+ if (argumentEvent && (!upstreamItemId || (!itemNames.has(upstreamItemId) && !ordinaryItemIds.has(upstreamItemId)))) {
299
+ retainPendingArgument(block, upstreamItemId, outputIndex);
300
+ return [];
301
+ }
302
+ if (
303
+ type === "response.function_call_arguments.delta"
304
+ && upstreamItemId
305
+ && itemNames.has(upstreamItemId)
306
+ ) {
307
+ const open = openCalls.get(upstreamItemId) ?? { argumentsText: "", emittedInput: "", retainedBytes: 0 };
308
+ const delta = typeof parsed.delta === "string" ? parsed.delta : "";
309
+ const deltaBytes = Buffer.byteLength(delta, "utf8");
310
+ if (deltaBytes > 0) budget?.chargeRetained(deltaBytes, { kind: "retained_collectors" });
311
+ open.argumentsText += delta;
312
+ open.retainedBytes += deltaBytes;
313
+ openCalls.set(upstreamItemId, open);
314
+ // Still accumulating toward the compact wrapper, or an unrecognized shape:
315
+ // suppress progressive emission and let the done event carry input.
316
+ if (FREEFORM_WRAP_PREFIX.startsWith(open.argumentsText)) return [];
317
+ const fullInput = partialCustomToolInput(open.argumentsText);
318
+ if (fullInput === null) return [];
319
+ if (!fullInput.startsWith(open.emittedInput) || fullInput.length === open.emittedInput.length) return [];
320
+ const inputDelta = fullInput.slice(open.emittedInput.length);
321
+ open.emittedInput = fullInput;
322
+ const nextType = "response.custom_tool_call_input.delta";
323
+ const next = {
324
+ ...parsed,
325
+ type: nextType,
326
+ item_id: customToolItemId(upstreamItemId),
327
+ delta: inputDelta,
328
+ };
329
+ return [replaceSseDataPayload(replaceSseEventName(block, nextType), JSON.stringify(next))];
330
+ }
331
+
332
+ if (
333
+ type === "response.function_call_arguments.done"
334
+ && upstreamItemId
335
+ && itemNames.has(upstreamItemId)
336
+ ) {
337
+ const nextType = "response.custom_tool_call_input.done";
338
+ const source = typeof parsed.arguments === "string"
339
+ ? parsed.arguments
340
+ : openCalls.get(upstreamItemId)?.argumentsText ?? "";
341
+ const { arguments: _arguments, ...rest } = parsed;
342
+ const itemName = itemNames.get(upstreamItemId);
343
+ const next = {
344
+ ...rest,
345
+ type: nextType,
346
+ item_id: customToolItemId(upstreamItemId),
347
+ input: itemName?.aliased
348
+ ? compileCodeModeHelperInput(source, itemName.name)
349
+ : unwrapRoutedCustomToolArguments(source, itemName?.name ?? "", itemName?.namespace),
350
+ };
351
+ return [replaceSseDataPayload(replaceSseEventName(block, nextType), JSON.stringify(next))];
352
+ }
353
+
354
+ const restored = restoreRoutedCustomCalls(parsed, names, repairNames, declaredNames);
355
+ const terminal = type === "response.completed" || type === "response.failed" || type === "response.incomplete";
356
+ if (terminal) releaseAll();
357
+ return restored.changed
358
+ ? [replaceSseDataPayload(block, JSON.stringify(restored.value))]
359
+ : [block];
360
+ };
361
+ rewrite.dispose = releaseAll;
362
+ return rewrite;
363
+ }
@@ -7,8 +7,11 @@ type RepairableItemType = "message" | "reasoning";
7
7
 
8
8
  interface ResponsesItemIdRepairState {
9
9
  readonly repairMissingTerminalIds: boolean;
10
+ readonly repairInvalidIds: boolean;
10
11
  readonly placeholders: Record<RepairableItemType, ReadonlySet<string>>;
11
12
  readonly outputIds: Record<RepairableItemType, Map<number, string>>;
13
+ /** JSON [outputIndex, rawId] -> canonical id, for exact item_id rewrites on part/delta events. */
14
+ readonly rawIds: Map<string, string>;
12
15
  readonly scope: string;
13
16
  readonly budget?: TranslatorBudget;
14
17
  }
@@ -53,6 +56,7 @@ function mintCanonicalId(type: RepairableItemType, scope: string, outputIndex: n
53
56
  function createRepairState(config: ResponsesItemIdRepairConfig, budget?: TranslatorBudget): ResponsesItemIdRepairState {
54
57
  const state = {
55
58
  repairMissingTerminalIds: config.repairMissingTerminalIds === true,
59
+ repairInvalidIds: config.repairInvalidIds === true,
56
60
  placeholders: {
57
61
  message: new Set(config.message ?? []),
58
62
  reasoning: new Set(config.reasoning ?? []),
@@ -61,6 +65,7 @@ function createRepairState(config: ResponsesItemIdRepairConfig, budget?: Transla
61
65
  message: new Map<number, string>(),
62
66
  reasoning: new Map<number, string>(),
63
67
  },
68
+ rawIds: new Map<string, string>(),
64
69
  scope: randomUUID().replace(/-/g, ""),
65
70
  budget,
66
71
  };
@@ -85,12 +90,19 @@ function rememberMappedId(
85
90
  if (!rawId) return null;
86
91
  const mapped = state.placeholders[type].has(rawId)
87
92
  ? mintCanonicalId(type, state.scope, outputIndex)
88
- : state.repairMissingTerminalIds
89
- ? rawId
90
- : null;
93
+ : state.repairInvalidIds && !rawId.startsWith(REPAIRABLE_PREFIXES[type])
94
+ // An existing id without the canonical msg_/rs_ prefix (bare UUIDs from
95
+ // DeepSeek's Responses route) leaves Codex stuck on Thinking (#938).
96
+ ? mintCanonicalId(type, state.scope, outputIndex)
97
+ : state.repairMissingTerminalIds
98
+ ? rawId
99
+ : null;
91
100
  if (!mapped) return null;
92
101
  state.budget?.chargeRetained(new TextEncoder().encode(JSON.stringify([outputIndex, rawId, mapped])).byteLength, { kind: "item_ids" });
93
102
  state.outputIds[type].set(outputIndex, mapped);
103
+ // Keyed by (index, rawId): an upstream that reuses one placeholder id across
104
+ // several items must not collapse them into the last item's canonical id.
105
+ if (rawId !== mapped) state.rawIds.set(JSON.stringify([outputIndex, rawId]), mapped);
94
106
  return mapped;
95
107
  }
96
108
 
@@ -114,11 +126,24 @@ function rewriteItemIdField(
114
126
  ): { event: Record<string, unknown>; changed: boolean } {
115
127
  const eventType = typeof event.type === "string" ? ITEM_ID_EVENT_TYPES[event.type] : undefined;
116
128
  if (!eventType) return { event, changed: false };
129
+ const currentId = typeof event.item_id === "string" ? event.item_id : undefined;
130
+ // content_part.* events are shared between message and reasoning items (DeepSeek's
131
+ // streamed reasoning wraps its text in content parts), so the static event-type map
132
+ // can point at the wrong id table. The rewrite is therefore exact-only when the
133
+ // event carries an item_id: it fires when (output_index, item_id) names an id the
134
+ // item stream already repaired, and otherwise leaves the event alone — an unknown
135
+ // id belongs to an item this repair never touched (function_call, already-canonical
136
+ // ids), and guessing by index could borrow a sibling item's identity. The index
137
+ // table serves only events with NO item_id, where repairMissingTerminalIds
138
+ // explicitly opts into the positional guess (the pre-existing contract).
139
+ if (currentId !== undefined) {
140
+ const mapped = state.rawIds.get(JSON.stringify([outputIndex, currentId]));
141
+ if (!mapped || currentId === mapped) return { event, changed: false };
142
+ return { event: { ...event, item_id: mapped }, changed: true };
143
+ }
144
+ if (!state.repairMissingTerminalIds) return { event, changed: false };
117
145
  const mapped = state.outputIds[eventType].get(outputIndex);
118
146
  if (!mapped) return { event, changed: false };
119
- const currentId = typeof event.item_id === "string" ? event.item_id : undefined;
120
- if (currentId === mapped) return { event, changed: false };
121
- if (currentId === undefined && !state.repairMissingTerminalIds) return { event, changed: false };
122
147
  return { event: { ...event, item_id: mapped }, changed: true };
123
148
  }
124
149
 
@@ -219,6 +244,29 @@ export function relaySseWithResponsesItemIdRepair(
219
244
 
220
245
  export function hasResponsesItemIdRepair(config: ResponsesItemIdRepairConfig | undefined): boolean {
221
246
  return config?.repairMissingTerminalIds === true
247
+ || config?.repairInvalidIds === true
222
248
  || (config?.message?.length ?? 0) > 0
223
249
  || (config?.reasoning?.length ?? 0) > 0;
224
250
  }
251
+
252
+ /**
253
+ * Client-facing id normalization for a WHOLE bounded-JSON Responses object.
254
+ *
255
+ * The bounded-JSON policy (#875) answers a streaming client by synthesizing SSE
256
+ * from a completed JSON body, and reframes the same body into events for WS
257
+ * turns. Neither path goes through the SSE relay, so neither picks up the SSE
258
+ * item-id rewrite — a provider that needs id repair would get it on a streaming
259
+ * response and silently lose it the moment the reliability policy switched the
260
+ * upstream to bounded JSON. This applies the same rewrite to the object so all
261
+ * three paths agree. Raw recorded state is untouched: recording happens before
262
+ * any normalization.
263
+ */
264
+ export function repairResponsesJsonItemIds(
265
+ response: Record<string, unknown>,
266
+ config: ResponsesItemIdRepairConfig,
267
+ budget?: TranslatorBudget,
268
+ ): Record<string, unknown> {
269
+ const state = createRepairState(config, budget);
270
+ const rewritten = rewriteResponseSnapshot(state, response);
271
+ return rewritten.changed ? rewritten.response : response;
272
+ }
@@ -0,0 +1,90 @@
1
+ /**
2
+ * Shared bounded-JSON → Responses event sequence (#875): the same pure event
3
+ * list used by the WebSocket bridge (sendResponsesJsonAsEvents) and by the
4
+ * HTTP SSE synthesis for models whose reliability policy forces a bounded
5
+ * JSON upstream. One algorithm, two serializations — no duplicated drift.
6
+ */
7
+
8
+ export type ResponsesJsonEventFrame = Record<string, unknown>;
9
+
10
+ export const MAX_SYNTHESIZED_OUTPUT_ITEMS = 10_000;
11
+
12
+ /**
13
+ * The canonical minimal sequence Codex commits: response.created (empty
14
+ * output, in_progress) → one response.output_item.done per output item → a
15
+ * status-preserving terminal (completed / failed / incomplete).
16
+ */
17
+ export function responsesJsonEventSequence(
18
+ response: Record<string, unknown>,
19
+ rewritePayload?: (payload: Record<string, unknown>) => Record<string, unknown>,
20
+ ): ResponsesJsonEventFrame[] {
21
+ return [...iterateResponsesJsonEvents(response, rewritePayload)];
22
+ }
23
+
24
+ function* iterateResponsesJsonEvents(
25
+ response: Record<string, unknown>,
26
+ rewritePayload?: (payload: Record<string, unknown>) => Record<string, unknown>,
27
+ ): Generator<ResponsesJsonEventFrame> {
28
+ const rewrite = rewritePayload ?? ((payload: Record<string, unknown>) => payload);
29
+ const output = Array.isArray(response.output) ? response.output : [];
30
+ if (output.length > MAX_SYNTHESIZED_OUTPUT_ITEMS) {
31
+ throw new RangeError(
32
+ `Responses JSON output contains ${output.length} items; maximum is ${MAX_SYNTHESIZED_OUTPUT_ITEMS}`,
33
+ );
34
+ }
35
+ const finalStatus = response.status === "failed" || response.status === "incomplete"
36
+ ? response.status
37
+ : "completed";
38
+ yield rewrite({
39
+ type: "response.created",
40
+ response: { ...response, status: "in_progress", output: [] },
41
+ });
42
+ for (const [outputIndex, item] of output.entries()) {
43
+ yield rewrite({
44
+ type: "response.output_item.done",
45
+ output_index: outputIndex,
46
+ item,
47
+ });
48
+ }
49
+ yield rewrite({
50
+ type: `response.${finalStatus}`,
51
+ response: { ...response, status: finalStatus },
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Serialize the event sequence as one SSE body with exactly one
57
+ * `data: [DONE]\n\n` trailer.
58
+ */
59
+ export function responsesJsonToSseBody(
60
+ response: Record<string, unknown>,
61
+ rewritePayload?: (payload: Record<string, unknown>) => Record<string, unknown>,
62
+ ): string {
63
+ const frames = responsesJsonEventSequence(response, rewritePayload)
64
+ .map(frame => `data: ${JSON.stringify(frame)}\n\n`);
65
+ return `${frames.join("")}data: [DONE]\n\n`;
66
+ }
67
+
68
+ /** Stream synthesized SSE frames without retaining the expanded body in memory. */
69
+ export function responsesJsonToSseStream(
70
+ response: Record<string, unknown>,
71
+ rewritePayload?: (payload: Record<string, unknown>) => Record<string, unknown>,
72
+ ): ReadableStream<Uint8Array> {
73
+ const output = Array.isArray(response.output) ? response.output : [];
74
+ if (output.length > MAX_SYNTHESIZED_OUTPUT_ITEMS) {
75
+ throw new RangeError(
76
+ `Responses JSON output contains ${output.length} items; maximum is ${MAX_SYNTHESIZED_OUTPUT_ITEMS}`,
77
+ );
78
+ }
79
+ const frames = iterateResponsesJsonEvents(response, rewritePayload);
80
+ const encoder = new TextEncoder();
81
+ return new ReadableStream({
82
+ pull(controller) {
83
+ const next = frames.next();
84
+ controller.enqueue(encoder.encode(
85
+ next.done ? "data: [DONE]\n\n" : `data: ${JSON.stringify(next.value)}\n\n`,
86
+ ));
87
+ if (next.done) controller.close();
88
+ },
89
+ });
90
+ }
@@ -0,0 +1,29 @@
1
+ import type { SsePayloadRewrite } from "./sse-payload-rewrite";
2
+
3
+ function rewriteResponseObjectModel(value: unknown, responseModelId: string): boolean {
4
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
5
+ const response = value as Record<string, unknown>;
6
+ if (typeof response.model !== "string" || response.model === responseModelId) return false;
7
+ response.model = responseModelId;
8
+ return true;
9
+ }
10
+
11
+ /** Rewrite only existing Responses model metadata; unrelated and malformed payloads stay byte-identical. */
12
+ export function rewriteResponsesModelJson(json: string, responseModelId: string): string {
13
+ let parsed: unknown;
14
+ try {
15
+ parsed = JSON.parse(json);
16
+ } catch {
17
+ return json;
18
+ }
19
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return json;
20
+ const record = parsed as Record<string, unknown>;
21
+ const rootChanged = rewriteResponseObjectModel(record, responseModelId);
22
+ const nestedChanged = rewriteResponseObjectModel(record.response, responseModelId);
23
+ const changed = rootChanged || nestedChanged;
24
+ return changed ? JSON.stringify(record) : json;
25
+ }
26
+
27
+ export function createResponsesModelPayloadRewrite(responseModelId: string): SsePayloadRewrite {
28
+ return payload => rewriteResponsesModelJson(payload, responseModelId);
29
+ }