@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,397 @@
1
+ import type { KiroOAuthMetadata } from "../oauth/types";
2
+ import type { OcxTool, OcxToolChoice } from "./tools";
3
+ import type { TierDecision, TierObservationContext } from "./provider";
4
+
5
+ /** Exact provider/credential namespace for process-local reasoning replay. */
6
+ export interface OcxReasoningReplayIdentity {
7
+ providerName: string;
8
+ /** Opaque process-local digest of the exact upstream destination. */
9
+ providerDestinationIdentity: string;
10
+ /**
11
+ * The same destination, digested WITHOUT the process-local random key, so it can key a
12
+ * durable store. Absent when no base URL was resolvable.
13
+ */
14
+ providerDestinationDurableIdentity?: string;
15
+ adapterName: string;
16
+ modelId: string;
17
+ /** Opaque process-local credential identity; never a raw token or API key. */
18
+ credentialIdentity: string;
19
+ /**
20
+ * Salted-HMAC credential identity that survives restarts, for the durable
21
+ * thought-signature store (#1926). Absent when no durable identity could be
22
+ * derived — the durable store then refuses to key the entry (fail closed).
23
+ */
24
+ credentialDurableIdentity?: string;
25
+ }
26
+
27
+ /**
28
+ * Stable holder shared by parsed-request copies and already-created bridges.
29
+ * Credential/provider rotation replaces `current` atomically without replacing
30
+ * the holder, so late tool-call cache writes see the active physical identity.
31
+ */
32
+ export interface OcxReasoningReplayScopeRef {
33
+ /**
34
+ * Conversation namespace for replay state. Historically this was always the Codex parent-thread
35
+ * id; headerless Responses callers use a raw sanitized thread/Cursor/session fallback, never the
36
+ * hashed request-log conversation id.
37
+ */
38
+ readonly clientThreadId: string;
39
+ current?: Readonly<OcxReasoningReplayIdentity>;
40
+ }
41
+
42
+ export interface OcxParsedRequest {
43
+ modelId: string;
44
+ /** Client-facing model selector retained for Anthropic routes after wire-model normalization. */
45
+ _responseModelId?: string;
46
+ /** Selected OpenAI API virtual-model id retained after it rewrites the upstream wire model. */
47
+ _openAiVirtualSelectedModelId?: string;
48
+ previousResponseId?: string;
49
+ context: OcxContext;
50
+ stream: boolean;
51
+ options: OcxRequestOptions;
52
+ _rawBody?: unknown;
53
+ /**
54
+ * Boundary between replayed history and this turn's newly appended input. Usually the
55
+ * items the proxy restored from local previous_response_id state; also set when the
56
+ * CLIENT already carried that history verbatim and the proxy skipped the prepend.
57
+ */
58
+ _replayPrefixLen?: number;
59
+ /** Parsed-message index before the first conversational item in a continuation's current delta. */
60
+ _continuationConversationMessageIndex?: number;
61
+ /**
62
+ * True when the full history for a previous_response_id request is present in the input —
63
+ * whether the proxy expanded it or the client already sent it. Consumers read this as
64
+ * "this request is self-contained", never as "the proxy mutated it".
65
+ */
66
+ _previousResponseInputExpanded?: boolean;
67
+ /** Provider-private stable Cursor conversation id resolved from the Responses previous_response_id chain. */
68
+ _cursorConversationId?: string;
69
+ /** Stable upstream client thread identity, used only to derive provider-scoped continuation ids. */
70
+ _clientThreadId?: string;
71
+ /** Cursor-only thread owner; may be an opaque process-local Desktop session/thread identity. */
72
+ _cursorClientThreadId?: string;
73
+ /** Conversation/provider/account/model-bound namespace for reasoning replay state. */
74
+ _reasoningReplayScope?: OcxReasoningReplayScopeRef;
75
+ /**
76
+ * Set by bindRouteReasoningReplayScope after a proven serving-identity change, or by
77
+ * prepareOpaqueBlobRecovery after an authoritative rejection; consumers strip replayed blobs.
78
+ */
79
+ _stripReasoningEncryptedContent?: boolean;
80
+ /**
81
+ * Optional authenticated tenant/operator namespace for Cursor thread→conversation derivation.
82
+ * When absent (single-operator local proxy), derivation stays local-scoped.
83
+ */
84
+ _cursorIdentityScope?: string;
85
+ /**
86
+ * True for helper/shadow/compaction turns that must not append into the main Cursor conversation
87
+ * derived from the parent thread id.
88
+ */
89
+ _cursorIsolateConversation?: boolean;
90
+ /** Account-scoped, non-secret Kiro request metadata selected with the OAuth access token. */
91
+ _kiroAuthContext?: Pick<KiroOAuthMetadata, "profileArn" | "apiRegion" | "ssoRegion" | "authType">;
92
+ /** Provider-private continuation metadata resolved from the Responses previous_response_id chain. */
93
+ _providerContinuation?: OcxProviderContinuationState;
94
+ /** Persisted continuation considered only after the final physical route is known. */
95
+ _providerContinuationCandidate?: OcxProviderContinuationState;
96
+ /** Exact process-local route owner attached to newly persisted provider state. */
97
+ _providerContinuationOwner?: OcxProviderContinuationOwner;
98
+ /**
99
+ * The hosted `{type:"web_search", ...}` tool config, stashed when Codex enables web search. Routed
100
+ * (non-OpenAI) providers can't run it server-side, so the proxy re-exposes it as a function tool and
101
+ * executes searches via the gpt-5.4-mini sidecar (see src/web-search). Absent when not requested.
102
+ */
103
+ _webSearch?: Record<string, unknown>;
104
+ /** Hosted image_generation tool config stashed for the image bridge sidecar (see src/images). */
105
+ _imageGeneration?: { toolNames: Set<string>; originalTool?: Record<string, unknown> };
106
+ /**
107
+ * True when Codex requested structured output (`text.format` = json_schema/json_object). The
108
+ * web-search tool_result is then rendered as compact JSON instead of markdown prose, so its
109
+ * answer/"Sources:" text can't bleed into and corrupt the model's schema-constrained output.
110
+ */
111
+ _structuredOutput?: boolean;
112
+ /**
113
+ * True when the input carried `{type:"compaction_trigger"}` — Codex remote compaction v2 asking
114
+ * this turn to produce a `{type:"compaction"}` output item. Routed adapters can't natively;
115
+ * the server runs the model as a summarizer and the bridge emits a synthetic compaction item
116
+ * (see src/responses/compaction.ts).
117
+ */
118
+ _compactionRequest?: boolean;
119
+ /**
120
+ * True when the current request newly introduced a stored compaction summary/marker. Historical
121
+ * markers restored by previous_response_id expansion were already acknowledged and do not reset
122
+ * provider-private continuation caches again on every later turn.
123
+ */
124
+ _contextCompactionBoundary?: boolean;
125
+ }
126
+
127
+ export interface OcxContext {
128
+ systemPrompt?: string[];
129
+ messages: OcxMessage[];
130
+ tools?: OcxTool[];
131
+ }
132
+
133
+ export type OcxMessage =
134
+ | OcxUserMessage
135
+ | OcxAssistantMessage
136
+ | OcxDeveloperMessage
137
+ | OcxToolResultMessage;
138
+
139
+ export interface OcxUserMessage {
140
+ role: "user";
141
+ content: string | OcxContentPart[];
142
+ timestamp: number;
143
+ }
144
+
145
+ export interface OcxAssistantMessage {
146
+ role: "assistant";
147
+ content: OcxAssistantContentPart[];
148
+ /** Responses message phase, preserved when replaying translated provider output. */
149
+ phase?: OcxMessagePhase;
150
+ model?: string;
151
+ timestamp: number;
152
+ /**
153
+ * Kiro `reasoningContent.redactedContent` for THIS assistant turn — an opaque encrypted blob
154
+ * Kiro replays to preserve model reasoning across turns. Provider-specific and unrenderable, so
155
+ * it rides the message rather than a content part: any other adapter simply ignores it.
156
+ */
157
+ kiroRedactedReasoning?: string;
158
+ }
159
+
160
+ export interface OcxDeveloperMessage {
161
+ role: "developer";
162
+ content: string | OcxContentPart[];
163
+ timestamp: number;
164
+ }
165
+
166
+ export interface OcxToolResultMessage {
167
+ role: "toolResult";
168
+ toolCallId: string;
169
+ toolName: string;
170
+ /** MCP namespace from the originating tool call, if any. */
171
+ toolNamespace?: string;
172
+ /** Text, or content parts when a tool (e.g. Codex view_image) returns an image in its output. */
173
+ content: string | OcxContentPart[];
174
+ /** True when the Responses result contained opaque encrypted output Kiro cannot translate. */
175
+ containsEncryptedContent?: boolean;
176
+ isError: boolean;
177
+ timestamp: number;
178
+ }
179
+
180
+ export interface OcxTextContent {
181
+ type: "text";
182
+ text: string;
183
+ }
184
+
185
+ export interface OcxImageContent {
186
+ type: "image";
187
+ /** A `data:` URL (base64) or a remote https URL — passed through from Codex verbatim, NEVER inlined as text. */
188
+ imageUrl: string;
189
+ /** Fidelity hint from Codex: "low" | "high" | "auto". */
190
+ detail?: string;
191
+ }
192
+
193
+ export interface OcxVideoContent {
194
+ type: "video";
195
+ /** A base64 `data:` URL from an OpenAI-compatible `video_url` part. */
196
+ videoUrl: string;
197
+ }
198
+
199
+ /** A user/developer message content part: text or native media. */
200
+ export type OcxContentPart = OcxTextContent | OcxImageContent | OcxVideoContent;
201
+
202
+ export interface OcxThinkingContent {
203
+ type: "thinking";
204
+ thinking: string;
205
+ signature?: string;
206
+ itemId?: string;
207
+ /** Raw Anthropic redacted_thinking block payloads to replay verbatim (order preserved). */
208
+ redacted?: string[];
209
+ }
210
+
211
+ export interface OcxToolCall {
212
+ type: "toolCall";
213
+ id: string;
214
+ name: string;
215
+ arguments: Record<string, unknown>;
216
+ customWireName?: string;
217
+ thoughtSignature?: string;
218
+ /**
219
+ * Provider-issued opaque metadata that must survive the whole round trip unchanged
220
+ * (issue #1735). A signed Gemini part is only valid when its signature comes back on the
221
+ * SAME part it was issued for, so this travels with the individual tool call rather than
222
+ * being matched by name/arguments after the fact.
223
+ */
224
+ providerMetadata?: OcxProviderOpaqueToolCallMetadata;
225
+ /** MCP namespace (e.g. "mcp__context7") when this call targets a namespaced tool. */
226
+ namespace?: string;
227
+ }
228
+
229
+ /**
230
+ * Opaque, provider-scoped tool-call metadata. Values are never parsed, merged, re-encoded, or
231
+ * synthesized — they are carried verbatim or not at all.
232
+ */
233
+ export interface OcxProviderOpaqueToolCallMetadata {
234
+ google?: {
235
+ thoughtSignature?: string;
236
+ };
237
+ }
238
+
239
+ export type OcxAssistantContentPart = OcxTextContent | OcxThinkingContent | OcxToolCall;
240
+ export interface OcxRequestOptions {
241
+ maxOutputTokens?: number;
242
+ temperature?: number;
243
+ topP?: number;
244
+ stopSequences?: string[];
245
+ toolChoice?: OcxToolChoice;
246
+ parallelToolCalls?: boolean;
247
+ reasoning?: string;
248
+ hideThinkingSummary?: boolean;
249
+ serviceTier?: string;
250
+ /** Final outbound tier action, resolved after the provider/model wire is settled. */
251
+ tierDecision?: TierDecision;
252
+ /** Internal B0 observation inputs; adapters combine these with the wire they actually serialize. */
253
+ tierObservation?: TierObservationContext;
254
+ presencePenalty?: number;
255
+ frequencyPenalty?: number;
256
+ /** Responses prompt-cache affinity key. Passthrough preserves it via _rawBody; routed adapters do not consume it unless their upstream wire supports it. */
257
+ promptCacheKey?: string;
258
+ /**
259
+ * Responses `text.format` (json_schema / json_object), preserved for adapters whose
260
+ * upstream wire has an equivalent. The openai-chat adapter re-nests it as chat
261
+ * `response_format`, the exact inverse of responseFormatToText in src/chat/inbound.ts.
262
+ * The native passthrough ignores it (it forwards `_rawBody.text` verbatim) and Kiro
263
+ * keeps rejecting structured output via `_structuredOutput`.
264
+ */
265
+ textFormat?: {
266
+ type: "json_schema" | "json_object";
267
+ name?: string;
268
+ description?: string;
269
+ schema?: Record<string, unknown>;
270
+ strict?: boolean;
271
+ };
272
+ }
273
+
274
+ export type OcxMessagePhase = "commentary" | "final_answer";
275
+
276
+ /** Non-secret, process-local owner fence for provider-private continuation state. */
277
+ export interface OcxProviderContinuationOwner {
278
+ [field: string]: string | number;
279
+ version: 1;
280
+ providerName: string;
281
+ providerDestinationIdentity: string;
282
+ adapterName: string;
283
+ modelId: string;
284
+ credentialIdentity: string;
285
+ }
286
+
287
+ /**
288
+ * Provider-private state that must follow a locally expanded `previous_response_id` chain.
289
+ * Kept out of public Responses output and persisted only in the bounded local continuation cache.
290
+ */
291
+ export interface OcxProviderContinuationState {
292
+ /** Proxy-authored owner metadata; stripped before provider adapters receive the state. */
293
+ __ocxOwner?: OcxProviderContinuationOwner;
294
+ cursor?: {
295
+ [field: string]: unknown;
296
+ conversationId?: string;
297
+ checkpointUsable?: boolean;
298
+ /** Opaque process-local Cursor ConversationStateStructure snapshot ref. Never raw protobuf. */
299
+ checkpointRef?: string;
300
+ };
301
+ kiro?: {
302
+ [field: string]: unknown;
303
+ conversationId?: string;
304
+ };
305
+ [provider: string]: Record<string, unknown> | undefined;
306
+ }
307
+
308
+ export type AdapterEvent =
309
+ | { type: "heartbeat" }
310
+ | { type: "text_delta"; text: string; phase?: OcxMessagePhase }
311
+ | { type: "thinking_delta"; thinking: string }
312
+ // Anthropic extended-thinking round-trip: signature_delta for the current thinking block, and
313
+ // opaque redacted_thinking blocks. Both must be replayed verbatim or tool-use turns 400.
314
+ | { type: "thinking_signature"; signature: string }
315
+ | { type: "redacted_thinking"; data: string }
316
+ // Kiro reasoning round-trip: the encrypted `redactedContent` blob for the CURRENT assistant turn.
317
+ // Never rendered — it only rides the reasoning item's envelope so the next request can replay it.
318
+ | { type: "kiro_redacted_reasoning"; data: string }
319
+ | { type: "reasoning_raw_delta"; text: string }
320
+ | { type: "tool_call_start"; id: string; name: string; providerMetadata?: OcxProviderOpaqueToolCallMetadata }
321
+ | { type: "tool_call_delta"; arguments: string }
322
+ | { type: "tool_call_end" }
323
+ /** Internal boundary between a guarded first pass and its one-shot continuation. */
324
+ | { type: "assistant_boundary" }
325
+ // Native web-search activity surfaced by the web-search sidecar so Codex renders a "Searched the
326
+ // web" cell. Emitted as a lifecycle PAIR at real wall-clock moments by src/web-search/loop.ts
327
+ // (routed adapters never emit these): `begin` right before the sidecar runs so Codex shows the
328
+ // "Searching the web" spinner, then `end` once it resolves. The bridge maps begin → an
329
+ // output_item.added(in_progress) and end → the matching output_item.done(completed|failed) under
330
+ // the SAME output index, so the activity animates instead of flashing completed instantly.
331
+ | { type: "web_search_call_begin"; id: string }
332
+ | { type: "web_search_call_end"; id: string; queries: string[]; status?: "completed" | "failed"; sources?: OcxUrlCitation[] }
333
+ | {
334
+ type: "done";
335
+ usage?: OcxUsage;
336
+ stopReason?: string;
337
+ endTurn?: boolean;
338
+ providerState?: OcxProviderContinuationState;
339
+ }
340
+ | {
341
+ type: "incomplete";
342
+ reason: string;
343
+ message?: string;
344
+ usage?: OcxUsage;
345
+ retryable?: boolean;
346
+ endTurn?: boolean;
347
+ providerState?: OcxProviderContinuationState;
348
+ }
349
+ // `usage` carries best-effort partial consumption when a turn dies before a clean done
350
+ // (e.g. cursor upstream 502 mid-stream), so failed requests can log real token counts.
351
+ | {
352
+ type: "error";
353
+ message: string;
354
+ usage?: OcxUsage;
355
+ /** Authoritative upstream/proxy status when known; avoids message-based classification. */
356
+ status?: number;
357
+ /** Responses error type and code when the adapter has a structured provider failure. */
358
+ errorType?: string;
359
+ code?: string;
360
+ retryable?: boolean;
361
+ };
362
+
363
+ /**
364
+ * A web source backing a search answer. Surfaced on the search-end event and rendered by the bridge
365
+ * as a `url_citation` annotation on the following assistant message (the desktop app's Sources chip
366
+ * reads these; the TUI ignores annotations, so this is additive).
367
+ */
368
+ export interface OcxUrlCitation {
369
+ url: string;
370
+ title?: string;
371
+ }
372
+
373
+ /**
374
+ * Canonical usage convention (devlog/260711_claude_inbound/070):
375
+ * - `inputTokens` is the TOTAL prompt size, INCLUDING cache reads and cache writes
376
+ * (OpenAI Responses convention). Anthropic parse sites normalize into this shape.
377
+ * - `cachedInputTokens` is cache READ tokens only (a subset of `inputTokens`).
378
+ * - `cacheReadInputTokens`/`cacheCreationInputTokens` carry the read/write split when
379
+ * the provider reports both; reads mirror `cachedInputTokens`.
380
+ * - `totalTokens` = inputTokens + outputTokens. Never re-add cache detail on top.
381
+ */
382
+ export interface OcxUsage {
383
+ inputTokens: number;
384
+ outputTokens: number;
385
+ /**
386
+ * Absolute active-context size after the response. Stateful providers can expose this separately
387
+ * from their per-attempt usage. Responses serialization derives the input side from
388
+ * `contextTotalTokens - outputTokens` so output is never added to an absolute checkpoint twice.
389
+ */
390
+ contextTotalTokens?: number;
391
+ totalTokens?: number;
392
+ cachedInputTokens?: number;
393
+ cacheReadInputTokens?: number;
394
+ cacheCreationInputTokens?: number;
395
+ reasoningOutputTokens?: number;
396
+ estimated?: boolean;
397
+ }
@@ -0,0 +1,236 @@
1
+ export interface OcxTool {
2
+ name: string;
3
+ description: string;
4
+ parameters: Record<string, unknown>;
5
+ strict?: boolean;
6
+ /** MCP namespace (e.g. "mcp__context7") for tools flattened out of a Responses "namespace" tool. */
7
+ namespace?: string;
8
+ /** Freeform/custom tool (e.g. apply_patch): the model's call must be relayed as a custom_tool_call. */
9
+ freeform?: boolean;
10
+ /** Client-executed tool discovery (tool_search): the model's call must be relayed as a tool_search_call. */
11
+ toolSearch?: boolean;
12
+ /** Tool definition restored from a prior tool_search output; transports may prioritize it when catalogs are bounded. */
13
+ loadedFromToolSearch?: boolean;
14
+ /** Cursor-only synthetic exact-match edit tool; never inferred from the wire name. */
15
+ cursorStructuredEdit?: true;
16
+ /** Synthetic web_search tool: the model's call is executed by the gpt-5.4-mini sidecar, not relayed to Codex. */
17
+ webSearch?: boolean;
18
+ /** Synthetic image_gen tool: the model's call is executed by the xAI image bridge sidecar, not relayed to Codex. */
19
+ imageGeneration?: boolean;
20
+ /** Synthetic video_gen tool: executed by the xAI video bridge sidecar. */
21
+ videoGeneration?: boolean;
22
+ }
23
+
24
+ /**
25
+ * Wire name a chat model sees for a tool. Namespaced (MCP) tools are flattened to
26
+ * "<namespace>__<name>" so they survive the chat-completions function-tool format;
27
+ * the proxy maps this back to {namespace, name} on the return trip (Codex routes MCP
28
+ * calls by an explicit `namespace` field, not by parsing the name).
29
+ */
30
+ export function namespacedToolName(namespace: string | undefined, name: string): string {
31
+ return namespace ? `${namespace}__${name}` : name;
32
+ }
33
+
34
+ /**
35
+ * Codex unified-exec name normalization.
36
+ *
37
+ * Codex's code-mode shell tool is declared as `exec` (a freeform custom tool whose own
38
+ * description mentions the nested `await tools.exec_command(...)` helper). Routed models —
39
+ * DeepSeek in particular — sometimes echo that helper name as the tool-call name, emitting
40
+ * `exec_command` or `apply_patch` instead of the declared `exec`. Accept these nested helper
41
+ * names only when the request catalog actually declares `exec` and does not itself declare the
42
+ * emitted name (an MCP server may legitimately advertise one under its own namespace).
43
+ */
44
+ const LEGACY_SHELL_BRIDGE_TOOL_NAMES = ["exec_command", "shell_command"] as const;
45
+ const CODE_MODE_HELPER_TOOL_NAMES = [...LEGACY_SHELL_BRIDGE_TOOL_NAMES, "apply_patch"] as const;
46
+
47
+ export function normalizeDeclaredToolName(
48
+ name: string,
49
+ declared: ReadonlySet<string> | undefined,
50
+ ): string {
51
+ if (!declared || !declared.has("exec")) return name;
52
+ if (declared.has(name)) return name;
53
+ if (name === "apply_patch") return "exec";
54
+ // When the catalog explicitly declares any legacy shell bridge name, the environment
55
+ // genuinely exposes that tool — turn normalization off so a call is never mis-routed
56
+ // to `exec`.
57
+ if ((LEGACY_SHELL_BRIDGE_TOOL_NAMES as readonly string[]).some(legacy => declared.has(legacy))) {
58
+ return name;
59
+ }
60
+ return (CODE_MODE_HELPER_TOOL_NAMES as readonly string[]).includes(name) ? "exec" : name;
61
+ }
62
+
63
+ export function toolChoiceAliases(tool: Pick<OcxTool, "namespace" | "name">): string[] {
64
+ const wireName = namespacedToolName(tool.namespace, tool.name);
65
+ return tool.namespace ? [wireName, `${tool.namespace}.${tool.name}`] : [wireName];
66
+ }
67
+
68
+ function sameToolIdentity(
69
+ left: Pick<OcxTool, "namespace" | "name">,
70
+ right: Pick<OcxTool, "namespace" | "name">,
71
+ ): boolean {
72
+ return left.namespace === right.namespace && left.name === right.name;
73
+ }
74
+
75
+ type ToolIdentity = Readonly<Pick<OcxTool, "namespace" | "name">>;
76
+
77
+ function snapshotToolIdentity(tool: Pick<OcxTool, "namespace" | "name">): ToolIdentity {
78
+ return Object.freeze({
79
+ name: tool.name,
80
+ ...(tool.namespace === undefined ? {} : { namespace: tool.namespace }),
81
+ });
82
+ }
83
+
84
+ function buildToolChoiceCatalog(
85
+ tools: readonly ToolIdentity[],
86
+ ): {
87
+ candidatesByName: ReadonlyMap<string, readonly ToolIdentity[]>;
88
+ sourceCandidatesByName: ReadonlyMap<string, readonly ToolIdentity[]>;
89
+ identitiesByTool: WeakMap<object, ToolIdentity>;
90
+ } {
91
+ const index = new Map<string, ToolIdentity[]>();
92
+ const sourceIndex = new Map<string, ToolIdentity[]>();
93
+ const identities = new Map<string, Set<string>>();
94
+ const identitiesByTool = new WeakMap<object, ToolIdentity>();
95
+ for (const tool of tools) {
96
+ const snapshot = snapshotToolIdentity(tool);
97
+ identitiesByTool.set(tool, snapshot);
98
+ const identity = JSON.stringify([snapshot.namespace ?? null, snapshot.name]);
99
+ for (const selector of [...toolChoiceAliases(snapshot), snapshot.name]) {
100
+ const candidates = index.get(selector);
101
+ if (!candidates) {
102
+ index.set(selector, [snapshot]);
103
+ sourceIndex.set(selector, [tool]);
104
+ identities.set(selector, new Set([identity]));
105
+ } else if (!identities.get(selector)!.has(identity)) {
106
+ candidates.push(snapshot);
107
+ sourceIndex.get(selector)!.push(tool);
108
+ identities.get(selector)!.add(identity);
109
+ }
110
+ }
111
+ }
112
+ return { candidatesByName: index, sourceCandidatesByName: sourceIndex, identitiesByTool };
113
+ }
114
+
115
+ /** Compile one immutable view of a request's tool catalog for repeated policy checks. */
116
+ export function createToolChoiceResolver(tools: readonly ToolIdentity[] | undefined) {
117
+ const compiled = tools ? buildToolChoiceCatalog(tools) : undefined;
118
+ const candidatesByName = compiled?.candidatesByName;
119
+ const snapshotFor = (tool: ToolIdentity): ToolIdentity | undefined => {
120
+ const snapshot = compiled?.identitiesByTool.get(tool);
121
+ return snapshot && sameToolIdentity(snapshot, tool) ? snapshot : undefined;
122
+ };
123
+ return {
124
+ candidates(name: string): ToolIdentity[] {
125
+ return (candidatesByName?.get(name) ?? []).map(candidate => ({ ...candidate }));
126
+ },
127
+ candidateCount(name: string): number {
128
+ return candidatesByName?.get(name)?.length ?? 0;
129
+ },
130
+ allows(tool: ToolIdentity, allowedTools: ReadonlySet<string>): boolean {
131
+ if (!candidatesByName) return toolChoiceAliases(tool).some(name => allowedTools.has(name));
132
+ const snapshot = snapshotFor(tool);
133
+ return snapshot ? toolAllowedByChoiceFromIndex(snapshot, allowedTools, candidatesByName) : false;
134
+ },
135
+ selects(tool: ToolIdentity, name: string): boolean {
136
+ const snapshot = snapshotFor(tool);
137
+ const candidates = candidatesByName?.get(name);
138
+ return !!snapshot && candidates?.length === 1 && sameToolIdentity(candidates[0], snapshot);
139
+ },
140
+ };
141
+ }
142
+
143
+ /**
144
+ * All tools that could be selected by one client-facing name. Bare logical names are included
145
+ * here because they are a compatibility selector for namespaced tools, while wire and dotted
146
+ * aliases come from `toolChoiceAliases`. A selector with more than one candidate is invalid.
147
+ */
148
+ export function toolChoiceCandidates(
149
+ tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined,
150
+ name: string,
151
+ ): Pick<OcxTool, "namespace" | "name">[] {
152
+ if (!tools) return [];
153
+ return [...(buildToolChoiceCatalog(tools).sourceCandidatesByName.get(name) ?? [])];
154
+ }
155
+
156
+ /**
157
+ * Newer Codex clients can select a tool nested in a namespace by its bare name. Resolve that
158
+ * shorthand only when the request contains one tool with the logical name, so an ambiguous name
159
+ * cannot authorize a tool from an unintended namespace.
160
+ */
161
+ export function toolAllowedByChoice(
162
+ tool: Pick<OcxTool, "namespace" | "name">,
163
+ allowedTools: ReadonlySet<string>,
164
+ tools?: readonly Pick<OcxTool, "namespace" | "name">[],
165
+ ): boolean {
166
+ if (!tools) return toolChoiceAliases(tool).some(name => allowedTools.has(name));
167
+ return toolAllowedByChoiceFromIndex(
168
+ snapshotToolIdentity(tool),
169
+ allowedTools,
170
+ buildToolChoiceCatalog(tools).candidatesByName,
171
+ );
172
+ }
173
+
174
+ function toolAllowedByChoiceFromIndex(
175
+ tool: ToolIdentity,
176
+ allowedTools: ReadonlySet<string>,
177
+ candidatesByName: ReadonlyMap<string, readonly ToolIdentity[]>,
178
+ ): boolean {
179
+ for (const name of [...toolChoiceAliases(tool), tool.name]) {
180
+ if (!allowedTools.has(name)) continue;
181
+ const candidates = candidatesByName.get(name);
182
+ if (candidates?.length === 1 && sameToolIdentity(candidates[0], tool)) return true;
183
+ }
184
+ return false;
185
+ }
186
+
187
+ export function resolveToolChoiceWireName(tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined, name: string): string {
188
+ const candidates = toolChoiceCandidates(tools, name);
189
+ if (candidates.length === 1) {
190
+ const match = candidates[0];
191
+ return namespacedToolName(match.namespace, match.name);
192
+ }
193
+ // Keep unknown/ambiguous names unchanged for callers that only serialize a selector. The
194
+ // catalog-aware predicate rejects them, and parseRequest rejects ambiguous request selectors.
195
+ return name;
196
+ }
197
+
198
+ /**
199
+ * Whether `modelId` is in a per-provider classification list (e.g. `noVisionModels`). Matches the full
200
+ * id, OR — for Ollama-style ids — the family before the ":size" tag, so a `gpt-oss` entry covers
201
+ * `gpt-oss:120b`/`gpt-oss:20b`. Colon-less ids (e.g. `grok-build-0.1`) still match exactly only.
202
+ */
203
+ export function modelInList(list: string[] | undefined, modelId: string): boolean {
204
+ if (!list || list.length === 0) return false;
205
+ if (list.includes(modelId)) return true;
206
+ const colon = modelId.indexOf(":");
207
+ return colon > 0 && list.includes(modelId.slice(0, colon));
208
+ }
209
+
210
+ export type OcxToolChoice =
211
+ | "auto"
212
+ | "none"
213
+ | "required"
214
+ | { name: string }
215
+ | { allowedTools: string[]; mode: "auto" | "required" };
216
+
217
+ export function isAllowedToolChoice(value: OcxToolChoice | undefined): value is { allowedTools: string[]; mode: "auto" | "required" } {
218
+ return typeof value === "object" && value !== null && "allowedTools" in value;
219
+ }
220
+
221
+ /** Compile the request's tool-choice policy into a reusable advertisement/restoration predicate. */
222
+ export function toolChoiceToolPredicate(
223
+ choice: OcxToolChoice | undefined,
224
+ tools?: readonly Pick<OcxTool, "namespace" | "name">[],
225
+ ): (tool: Pick<OcxTool, "namespace" | "name">) => boolean {
226
+ if (!choice || choice === "auto" || choice === "required") return () => true;
227
+ if (choice === "none") return () => false;
228
+ if (isAllowedToolChoice(choice)) {
229
+ const allowed = new Set(choice.allowedTools);
230
+ const resolver = createToolChoiceResolver(tools);
231
+ return tool => resolver.allows(tool, allowed);
232
+ }
233
+ if (!tools) return tool => toolChoiceAliases(tool).includes(choice.name);
234
+ const resolver = createToolChoiceResolver(tools);
235
+ return tool => resolver.selects(tool, choice.name);
236
+ }