@iislee/opencodex 2.11.0 → 2.31.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 (675) hide show
  1. package/AGENTS_INSTALL.md +109 -0
  2. package/README.md +114 -19
  3. package/bin/ocx.mjs +164 -36
  4. package/bin/package-main.mjs +1 -1
  5. package/gui/dist/assets/index-BF38heuV.js +104 -0
  6. package/gui/dist/assets/index-DMiI18Kv.css +1 -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 +19 -10
  42. package/src/adapters/anthropic-output-schema.ts +137 -0
  43. package/src/adapters/anthropic.ts +376 -52
  44. package/src/adapters/base.ts +54 -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 +601 -0
  48. package/src/adapters/cursor/checkpoint-store.ts +303 -0
  49. package/src/adapters/cursor/cursor-errors.ts +129 -6
  50. package/src/adapters/cursor/discovery.ts +61 -4
  51. package/src/adapters/cursor/effort-map.ts +27 -3
  52. package/src/adapters/cursor/framing.ts +39 -0
  53. package/src/adapters/cursor/h2-pool.ts +123 -0
  54. package/src/adapters/cursor/http1-bidi.ts +361 -0
  55. package/src/adapters/cursor/images.ts +704 -0
  56. package/src/adapters/cursor/live-models.ts +174 -58
  57. package/src/adapters/cursor/live-transport.ts +609 -170
  58. package/src/adapters/cursor/native-exec-common.ts +23 -2
  59. package/src/adapters/cursor/native-exec-fs.ts +10 -7
  60. package/src/adapters/cursor/native-exec-network.ts +1 -1
  61. package/src/adapters/cursor/native-exec-shell.ts +0 -1
  62. package/src/adapters/cursor/native-exec.ts +101 -14
  63. package/src/adapters/cursor/protobuf-events.ts +829 -11
  64. package/src/adapters/cursor/protobuf-request.ts +383 -65
  65. package/src/adapters/cursor/request-builder.ts +237 -31
  66. package/src/adapters/cursor/tool-definitions.ts +242 -12
  67. package/src/adapters/cursor/tool-result-normalize.ts +92 -0
  68. package/src/adapters/cursor/transport.ts +22 -0
  69. package/src/adapters/cursor/types.ts +28 -1
  70. package/src/adapters/cursor.ts +133 -7
  71. package/src/adapters/google-antigravity-replay.ts +558 -34
  72. package/src/adapters/google-antigravity-wire.ts +43 -10
  73. package/src/adapters/google-http.ts +38 -10
  74. package/src/adapters/google-tool-schema.ts +80 -15
  75. package/src/adapters/google-truncation.ts +11 -0
  76. package/src/adapters/google.ts +618 -74
  77. package/src/adapters/identity.ts +39 -6
  78. package/src/adapters/kiro-errors.ts +11 -0
  79. package/src/adapters/kiro-events.ts +19 -1
  80. package/src/adapters/kiro-thinking.ts +18 -2
  81. package/src/adapters/kiro-tools.ts +10 -1
  82. package/src/adapters/kiro.ts +92 -54
  83. package/src/adapters/mimo-free.ts +17 -0
  84. package/src/adapters/openai-chat-url.ts +11 -0
  85. package/src/adapters/openai-chat.ts +1311 -336
  86. package/src/adapters/openai-responses-url.ts +16 -0
  87. package/src/adapters/openai-responses.ts +830 -56
  88. package/src/adapters/registry.ts +175 -0
  89. package/src/adapters/responses-tool-schema.ts +67 -0
  90. package/src/adapters/tool-call-id.ts +119 -0
  91. package/src/adapters/tool-catalog-nudge.ts +104 -21
  92. package/src/adapters/xai-web-search.ts +185 -0
  93. package/src/bridge.ts +428 -61
  94. package/src/chat/inbound.ts +43 -19
  95. package/src/chat/outbound.ts +82 -26
  96. package/src/claude/agents-inject.ts +32 -9
  97. package/src/claude/context-windows.ts +21 -5
  98. package/src/claude/desktop-3p.ts +243 -9
  99. package/src/claude/gateway-cache.ts +41 -4
  100. package/src/claude/inbound.ts +72 -3
  101. package/src/claude/model-info.ts +38 -15
  102. package/src/claude/outbound.ts +70 -16
  103. package/src/cli/account-api.ts +35 -1
  104. package/src/cli/account-auth.ts +33 -6
  105. package/src/cli/account-catalog-refresh.ts +14 -0
  106. package/src/cli/account-extended.ts +389 -2
  107. package/src/cli/account-main.ts +317 -0
  108. package/src/cli/account.ts +30 -6
  109. package/src/cli/agent.ts +45 -1
  110. package/src/cli/claude-agent-startup-sync.ts +73 -0
  111. package/src/cli/claude-desktop.ts +29 -4
  112. package/src/cli/claude.ts +103 -34
  113. package/src/cli/codex-log-guard-doctor.ts +103 -0
  114. package/src/cli/codex-shim-autorestore.ts +2 -0
  115. package/src/cli/codex-shim-readiness.ts +76 -0
  116. package/src/cli/combo.ts +8 -0
  117. package/src/cli/config-command.ts +74 -10
  118. package/src/cli/dispatch.ts +593 -0
  119. package/src/cli/doctor.ts +315 -43
  120. package/src/cli/ensure-desired-integrations.ts +152 -0
  121. package/src/cli/export-command.ts +46 -20
  122. package/src/cli/help.ts +20 -271
  123. package/src/cli/index.ts +378 -519
  124. package/src/cli/init.ts +4 -17
  125. package/src/cli/integrations.ts +120 -2
  126. package/src/cli/lab.ts +607 -0
  127. package/src/cli/launcher-context.ts +77 -0
  128. package/src/cli/minimax.ts +497 -0
  129. package/src/cli/models-runtime.ts +35 -2
  130. package/src/cli/models.ts +100 -14
  131. package/src/cli/observe.ts +92 -3
  132. package/src/cli/opencode.ts +4 -2
  133. package/src/cli/provider-runtime.ts +18 -1
  134. package/src/cli/provider.ts +24 -3
  135. package/src/cli/ready.ts +301 -0
  136. package/src/cli/registry.ts +437 -0
  137. package/src/cli/root.ts +86 -0
  138. package/src/cli/route-policy.ts +92 -0
  139. package/src/cli/runtime-api.ts +6 -3
  140. package/src/cli/star-prompt.ts +71 -15
  141. package/src/cli/status.ts +10 -3
  142. package/src/cli/system-restart-client.ts +146 -0
  143. package/src/cli/tray-proxy.ts +153 -6
  144. package/src/cli/v2.ts +105 -10
  145. package/src/cli.ts +1 -1
  146. package/src/clients/config-export.ts +1358 -21
  147. package/src/codex/account-label.ts +14 -1
  148. package/src/codex/account-lifecycle.ts +130 -13
  149. package/src/codex/account-namespaces.ts +49 -3
  150. package/src/codex/account-priority.ts +83 -0
  151. package/src/codex/account-store.ts +29 -2
  152. package/src/codex/account-usability.ts +25 -2
  153. package/src/codex/admission.ts +256 -0
  154. package/src/codex/affinity-debug.ts +162 -0
  155. package/src/codex/app-server-processes.ts +493 -106
  156. package/src/codex/app-server-restart-service.ts +232 -0
  157. package/src/codex/auth-api.ts +849 -242
  158. package/src/codex/auth-collision.ts +5 -3
  159. package/src/codex/auth-context.ts +345 -32
  160. package/src/codex/autostart-health.ts +8 -1
  161. package/src/codex/catalog/account-models.ts +67 -0
  162. package/src/codex/catalog/aggregation.ts +68 -10
  163. package/src/codex/catalog/bundled.ts +331 -33
  164. package/src/codex/catalog/effort.ts +121 -30
  165. package/src/codex/catalog/filesystem-evidence.ts +302 -0
  166. package/src/codex/catalog/kinds.ts +2 -0
  167. package/src/codex/catalog/metadata.ts +529 -45
  168. package/src/codex/catalog/native-models.ts +72 -0
  169. package/src/codex/catalog/parsing.ts +224 -30
  170. package/src/codex/catalog/provider-fetch.ts +1460 -134
  171. package/src/codex/catalog/sync.ts +1449 -186
  172. package/src/codex/catalog-admission.ts +199 -0
  173. package/src/codex/catalog-refresh-status.ts +105 -0
  174. package/src/codex/catalog-write-serialization.ts +242 -0
  175. package/src/codex/catalog.ts +6 -3
  176. package/src/codex/codex-write-lock.ts +384 -0
  177. package/src/codex/convergence-types.ts +614 -0
  178. package/src/codex/convergence.ts +651 -0
  179. package/src/codex/coordinator-doctor.ts +332 -0
  180. package/src/codex/custom-model-catalog-migration.ts +176 -0
  181. package/src/codex/desired-state.ts +230 -0
  182. package/src/codex/features.ts +636 -39
  183. package/src/codex/generation.ts +202 -0
  184. package/src/codex/history-job.ts +407 -0
  185. package/src/codex/history-lock.ts +242 -0
  186. package/src/codex/history-migration-guardian.ts +26 -20
  187. package/src/codex/history-provider.ts +231 -28
  188. package/src/codex/history-transition.ts +105 -0
  189. package/src/codex/history-worker.ts +220 -0
  190. package/src/codex/inject-coordination.ts +290 -0
  191. package/src/codex/inject.ts +1073 -152
  192. package/src/codex/injected-marker.ts +37 -3
  193. package/src/codex/integration-record.ts +266 -0
  194. package/src/codex/internal/catalog-writer.ts +203 -0
  195. package/src/codex/internal/history-writer.ts +80 -0
  196. package/src/codex/journal.ts +66 -4
  197. package/src/codex/log-guard/inspect.ts +506 -0
  198. package/src/codex/log-guard/lock.ts +150 -0
  199. package/src/codex/log-guard/maintenance.ts +403 -0
  200. package/src/codex/log-guard/path-safety.ts +88 -0
  201. package/src/codex/log-guard/policy.ts +44 -0
  202. package/src/codex/log-guard/processes.ts +205 -0
  203. package/src/codex/log-guard/protection.ts +489 -0
  204. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  205. package/src/codex/main-account-cache.ts +24 -0
  206. package/src/codex/main-account.ts +29 -1
  207. package/src/codex/management-convergence.ts +167 -0
  208. package/src/codex/model-cache.ts +56 -10
  209. package/src/codex/model-entitlements.ts +353 -0
  210. package/src/codex/native-main-admission.ts +47 -0
  211. package/src/codex/native-main-auth-temp.ts +187 -0
  212. package/src/codex/native-main-claim.ts +178 -0
  213. package/src/codex/native-main-lock-file.ts +162 -0
  214. package/src/codex/native-main-owner.ts +329 -0
  215. package/src/codex/native-profile-api.ts +247 -0
  216. package/src/codex/native-profile-manager.ts +1531 -0
  217. package/src/codex/native-profile-processes.ts +121 -0
  218. package/src/codex/native-profile-recovery.ts +99 -0
  219. package/src/codex/native-profile-stage-store.ts +387 -0
  220. package/src/codex/native-profile-startup.ts +492 -0
  221. package/src/codex/native-profile-store.ts +855 -0
  222. package/src/codex/native-profile-types.ts +120 -0
  223. package/src/codex/native-residue.ts +682 -0
  224. package/src/codex/paths.ts +80 -1
  225. package/src/codex/plan-from-token.ts +140 -0
  226. package/src/codex/plan.ts +40 -0
  227. package/src/codex/plugins-doctor.ts +1 -1
  228. package/src/codex/pool-rotation.ts +74 -4
  229. package/src/codex/project-config-warnings.ts +20 -6
  230. package/src/codex/prompt-journal.ts +352 -0
  231. package/src/codex/prompt-layers.ts +967 -0
  232. package/src/codex/prompt-lock.ts +143 -0
  233. package/src/codex/quota-rejection.ts +298 -0
  234. package/src/codex/quota.ts +175 -13
  235. package/src/codex/refresh.ts +11 -2
  236. package/src/codex/reset-credit-recovery.ts +1044 -0
  237. package/src/codex/routing.ts +505 -94
  238. package/src/codex/runtime.ts +159 -38
  239. package/src/codex/shim.ts +1009 -28
  240. package/src/codex/subagent-model-fallback.ts +350 -35
  241. package/src/codex/sync.ts +191 -2
  242. package/src/codex/transition-state.ts +612 -0
  243. package/src/codex/upstream-host-health.ts +368 -0
  244. package/src/codex/user-identity.ts +557 -0
  245. package/src/codex/warmup.ts +187 -81
  246. package/src/codex/write-coordination.ts +114 -0
  247. package/src/combos/failover.ts +20 -0
  248. package/src/combos/index.ts +4 -0
  249. package/src/combos/request.ts +32 -0
  250. package/src/combos/types.ts +81 -9
  251. package/src/config/provider-name.ts +24 -0
  252. package/src/config.ts +1762 -140
  253. package/src/generated/compatibility-version.json +3164 -0
  254. package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
  255. package/src/grok/inject.ts +16 -5
  256. package/src/grok/inspect.ts +45 -0
  257. package/src/grok/sync.ts +2 -2
  258. package/src/images/loop.ts +152 -29
  259. package/src/images/plan.ts +23 -13
  260. package/src/integrations/config-io.ts +269 -0
  261. package/src/integrations/journal.ts +315 -0
  262. package/src/integrations/merge.ts +135 -0
  263. package/src/integrations/mutation-flight.ts +71 -0
  264. package/src/integrations/native/ownership-preflight.ts +202 -0
  265. package/src/integrations/omp-yaml-source.ts +358 -0
  266. package/src/integrations/owned-refresh.ts +74 -0
  267. package/src/integrations/ownership.ts +111 -0
  268. package/src/integrations/registry.ts +159 -0
  269. package/src/integrations/serialize.ts +314 -0
  270. package/src/integrations/state.ts +361 -0
  271. package/src/integrations/store.ts +103 -0
  272. package/src/integrations/writer-lock.ts +98 -0
  273. package/src/integrations/writer.ts +691 -0
  274. package/src/lab/artifacts/sanitize.ts +586 -0
  275. package/src/lab/artifacts/secure-fs.ts +475 -0
  276. package/src/lab/artifacts/store.ts +310 -0
  277. package/src/lab/automation/budgets.ts +78 -0
  278. package/src/lab/automation/config-persistence.ts +256 -0
  279. package/src/lab/automation/constants.ts +39 -0
  280. package/src/lab/automation/cooldown.ts +103 -0
  281. package/src/lab/automation/dispatch.ts +211 -0
  282. package/src/lab/automation/index.ts +13 -0
  283. package/src/lab/automation/orchestrator.ts +499 -0
  284. package/src/lab/automation/persistence.ts +512 -0
  285. package/src/lab/automation/planner.ts +371 -0
  286. package/src/lab/automation/policy.ts +136 -0
  287. package/src/lab/automation/queue.ts +191 -0
  288. package/src/lab/automation/recovery.ts +24 -0
  289. package/src/lab/automation/route-context.ts +21 -0
  290. package/src/lab/automation/run-key.ts +44 -0
  291. package/src/lab/automation/runs-query.ts +34 -0
  292. package/src/lab/automation/types.ts +160 -0
  293. package/src/lab/conformance/assertion.ts +325 -0
  294. package/src/lab/conformance/digest.ts +22 -0
  295. package/src/lab/conformance/executor.ts +741 -0
  296. package/src/lab/conformance/fixture-provider.ts +27 -0
  297. package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
  298. package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
  299. package/src/lab/conformance/harness-budget.ts +47 -0
  300. package/src/lab/conformance/index.ts +5 -0
  301. package/src/lab/conformance/jcs.ts +64 -0
  302. package/src/lab/conformance/json-pointer.ts +39 -0
  303. package/src/lab/conformance/manifest.ts +180 -0
  304. package/src/lab/conformance/mcp-stub.ts +179 -0
  305. package/src/lab/conformance/negative-controls.ts +164 -0
  306. package/src/lab/conformance/observation.ts +355 -0
  307. package/src/lab/conformance/runner.ts +68 -0
  308. package/src/lab/conformance/sse-normalize.ts +59 -0
  309. package/src/lab/conformance/suite-manifest.ts +78 -0
  310. package/src/lab/conformance/types.ts +214 -0
  311. package/src/lab/constants.ts +126 -0
  312. package/src/lab/digest.ts +64 -0
  313. package/src/lab/events/errors.ts +9 -0
  314. package/src/lab/events/limits.ts +117 -0
  315. package/src/lab/events/types.ts +229 -0
  316. package/src/lab/events/validate.ts +781 -0
  317. package/src/lab/fabric/constants.ts +40 -0
  318. package/src/lab/fabric/executor.ts +492 -0
  319. package/src/lab/fabric/index.ts +80 -0
  320. package/src/lab/fabric/manifest.ts +222 -0
  321. package/src/lab/fabric/observe.ts +489 -0
  322. package/src/lab/fabric/patch.ts +79 -0
  323. package/src/lab/fabric/producer-child.ts +139 -0
  324. package/src/lab/fabric/producer-isolate.ts +276 -0
  325. package/src/lab/fabric/producer-protocol.ts +61 -0
  326. package/src/lab/fabric/scratch.ts +439 -0
  327. package/src/lab/fabric/subject.ts +106 -0
  328. package/src/lab/fabric/types.ts +134 -0
  329. package/src/lab/fabric/verifier.ts +98 -0
  330. package/src/lab/index.ts +54 -0
  331. package/src/lab/ledger/artifact-refs.ts +127 -0
  332. package/src/lab/ledger/invalidation.ts +136 -0
  333. package/src/lab/ledger/purge.ts +310 -0
  334. package/src/lab/ledger/store.ts +532 -0
  335. package/src/lab/live/credential-lease.ts +53 -0
  336. package/src/lab/live/destination.ts +155 -0
  337. package/src/lab/live/executor.ts +336 -0
  338. package/src/lab/live/inert-tools.ts +56 -0
  339. package/src/lab/live/manifest.ts +85 -0
  340. package/src/lab/live/mcp-loopback.ts +57 -0
  341. package/src/lab/live/runner.ts +19 -0
  342. package/src/lab/live/sandbox.ts +61 -0
  343. package/src/lab/live/suite-manifest.ts +41 -0
  344. package/src/lab/live/transport.ts +118 -0
  345. package/src/lab/live/types.ts +197 -0
  346. package/src/lab/observe/from-conformance.ts +301 -0
  347. package/src/lab/observe/from-live.ts +117 -0
  348. package/src/lab/paths.ts +153 -0
  349. package/src/lab/projection/rebuild.ts +495 -0
  350. package/src/lab/projection/schema.ts +135 -0
  351. package/src/lab/projection/verdicts.ts +474 -0
  352. package/src/lab/projection/verification.ts +412 -0
  353. package/src/lab/public/bundle.ts +217 -0
  354. package/src/lab/public/community-authority.ts +175 -0
  355. package/src/lab/public/community-files.ts +29 -0
  356. package/src/lab/public/community.ts +479 -0
  357. package/src/lab/public/file-safety.ts +155 -0
  358. package/src/lab/public/ids.ts +26 -0
  359. package/src/lab/public/index.ts +16 -0
  360. package/src/lab/public/mutation-lock.ts +424 -0
  361. package/src/lab/public/operator.ts +353 -0
  362. package/src/lab/public/origin-purge.ts +79 -0
  363. package/src/lab/public/origin.ts +203 -0
  364. package/src/lab/public/privacy.ts +143 -0
  365. package/src/lab/public/private-file.ts +261 -0
  366. package/src/lab/public/project.ts +124 -0
  367. package/src/lab/public/purge-test-fault.ts +21 -0
  368. package/src/lab/public/purge.ts +223 -0
  369. package/src/lab/public/registry.ts +44 -0
  370. package/src/lab/public/revocation.ts +252 -0
  371. package/src/lab/public/signature.ts +243 -0
  372. package/src/lab/public/storage.ts +105 -0
  373. package/src/lab/public/strict-json.ts +206 -0
  374. package/src/lab/public/time.ts +26 -0
  375. package/src/lab/public/types.ts +172 -0
  376. package/src/lab/public/validate.ts +391 -0
  377. package/src/lab/query/catalog.ts +101 -0
  378. package/src/lab/query/connection.ts +107 -0
  379. package/src/lab/query/constants.ts +4 -0
  380. package/src/lab/query/cursor.ts +132 -0
  381. package/src/lab/query/dto-map.ts +277 -0
  382. package/src/lab/query/errors.ts +22 -0
  383. package/src/lab/query/freshness.ts +53 -0
  384. package/src/lab/query/index.ts +45 -0
  385. package/src/lab/query/latest-observation.ts +59 -0
  386. package/src/lab/query/passive-production.ts +159 -0
  387. package/src/lab/query/queries.ts +444 -0
  388. package/src/lab/query/types.ts +266 -0
  389. package/src/lab/subject/behavior-fingerprint.ts +77 -0
  390. package/src/lab/subject/installation-salt.ts +112 -0
  391. package/src/lab/subject/protocol-subject.ts +80 -0
  392. package/src/lab/subject/route-subject.ts +74 -0
  393. package/src/lib/app-owned-memory-stores.ts +22 -0
  394. package/src/lib/bounded-body.ts +153 -9
  395. package/src/lib/bun-runtime.ts +125 -12
  396. package/src/lib/bun-stream-caps.ts +13 -9
  397. package/src/lib/codex-restart-contract.ts +120 -0
  398. package/src/lib/config-ownership.ts +6 -2
  399. package/src/lib/destination-policy.ts +65 -1
  400. package/src/lib/errors.ts +44 -2
  401. package/src/lib/fabric-task-execution-authority.ts +7 -0
  402. package/src/lib/fabric-task-host.ts +29 -0
  403. package/src/lib/lab-activation.ts +223 -0
  404. package/src/lib/lab-live-execution-authority.ts +13 -0
  405. package/src/lib/lab-live-host.ts +30 -0
  406. package/src/lib/lab-live-pinned-sender.ts +56 -0
  407. package/src/lib/lab-live-route-production.ts +130 -0
  408. package/src/lib/lab-passive-linker-registration.ts +26 -0
  409. package/src/lib/local-management-attestation.ts +51 -0
  410. package/src/lib/local-management-capability.ts +100 -0
  411. package/src/lib/local-provider-reload-contract.ts +100 -0
  412. package/src/lib/optional-shutdown-hooks.ts +57 -0
  413. package/src/lib/pinned-http.ts +145 -26
  414. package/src/lib/process-control.ts +4 -1
  415. package/src/lib/provider-outbound.ts +49 -9
  416. package/src/lib/redact.ts +419 -3
  417. package/src/lib/self-launch-argv.ts +15 -0
  418. package/src/lib/server-resource-ownership.ts +71 -0
  419. package/src/lib/shadow-call.ts +35 -4
  420. package/src/lib/sse-decoder.ts +41 -0
  421. package/src/lib/state-store-registrations.ts +10 -2
  422. package/src/lib/system-restart-contract.ts +73 -0
  423. package/src/lib/token-estimate.ts +19 -2
  424. package/src/lib/tool-argument-integers.ts +202 -0
  425. package/src/lib/translator-budget.ts +44 -0
  426. package/src/lib/upstream-http-version.ts +57 -0
  427. package/src/lib/upstream-reachability.ts +95 -0
  428. package/src/lib/upstream-retry.ts +156 -3
  429. package/src/lib/windows-atomic-replace.ts +155 -0
  430. package/src/lib/windows-elevation.ts +70 -2
  431. package/src/lib/windows-secret-acl.ts +409 -69
  432. package/src/lib/windows-service-wrappers.ts +72 -0
  433. package/src/lib/windows-text.ts +106 -0
  434. package/src/lib/windows-user-principal.ts +341 -0
  435. package/src/lib/winsw.ts +33 -5
  436. package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
  437. package/src/oauth/account-import/index.ts +15 -0
  438. package/src/oauth/account-import/parser.ts +83 -0
  439. package/src/oauth/account-import/registry.ts +18 -0
  440. package/src/oauth/account-import/service.ts +75 -0
  441. package/src/oauth/account-import/types.ts +91 -0
  442. package/src/oauth/anthropic.ts +12 -1
  443. package/src/oauth/callback-server.ts +8 -2
  444. package/src/oauth/chatgpt.ts +12 -1
  445. package/src/oauth/command-code.ts +239 -0
  446. package/src/oauth/cursor.ts +46 -5
  447. package/src/oauth/google-antigravity.ts +35 -3
  448. package/src/oauth/health.ts +20 -12
  449. package/src/oauth/index.ts +398 -66
  450. package/src/oauth/key-providers.ts +16 -0
  451. package/src/oauth/kimi.ts +16 -2
  452. package/src/oauth/kiro.ts +50 -6
  453. package/src/oauth/local-token-detect.ts +11 -2
  454. package/src/oauth/log.ts +3 -1
  455. package/src/oauth/login-cli.ts +88 -28
  456. package/src/oauth/nous.ts +798 -0
  457. package/src/oauth/store.ts +119 -21
  458. package/src/oauth/token-guardian.ts +9 -3
  459. package/src/pi/models.ts +2 -2
  460. package/src/providers/alibaba-region-migration.ts +1 -1
  461. package/src/providers/antigravity-models.ts +521 -31
  462. package/src/providers/base-url-choices.ts +10 -0
  463. package/src/providers/codex-capacity.ts +292 -0
  464. package/src/providers/command-code-efforts.ts +144 -0
  465. package/src/providers/context-cap.ts +22 -5
  466. package/src/providers/cursor-pool.ts +72 -0
  467. package/src/providers/derive.ts +253 -6
  468. package/src/providers/fastwire.ts +501 -0
  469. package/src/providers/free-directory.ts +10 -7
  470. package/src/providers/google-vertex-location.ts +14 -0
  471. package/src/providers/key-failover.ts +71 -3
  472. package/src/providers/label.ts +1 -1
  473. package/src/providers/model-discovery-limits.ts +16 -0
  474. package/src/providers/model-discovery.ts +115 -22
  475. package/src/providers/model-rename-migration.ts +255 -0
  476. package/src/providers/model-rename-startup.ts +28 -0
  477. package/src/providers/openai-sidecar.ts +72 -4
  478. package/src/providers/openai-tier-startup.ts +31 -2
  479. package/src/providers/openai-tiers.ts +119 -4
  480. package/src/providers/openai-virtual-models.ts +1 -0
  481. package/src/providers/opencode-zen-rate-limit.ts +102 -0
  482. package/src/providers/provider-id-rewrite.ts +29 -0
  483. package/src/providers/quota.ts +1319 -38
  484. package/src/providers/registry.ts +1429 -111
  485. package/src/providers/request-pacing.ts +310 -0
  486. package/src/providers/service-tier.ts +277 -0
  487. package/src/providers/slug-codec.ts +42 -6
  488. package/src/providers/static-model-discovery.ts +86 -0
  489. package/src/providers/xai-responses-opt-in.ts +15 -0
  490. package/src/providers/xai-transport.ts +11 -4
  491. package/src/reasoning-effort.ts +49 -1
  492. package/src/responses/compaction.ts +26 -1
  493. package/src/responses/custom-tool-compat.ts +266 -0
  494. package/src/responses/hosted-tool-policy.ts +9 -0
  495. package/src/responses/namespace-tool-compat.ts +355 -0
  496. package/src/responses/parser.ts +220 -38
  497. package/src/responses/provider-continuation.ts +98 -0
  498. package/src/responses/provider-opaque-metadata.ts +73 -0
  499. package/src/responses/reasoning-envelope.ts +9 -1
  500. package/src/responses/reasoning-replay-cache.ts +426 -0
  501. package/src/responses/schema.ts +7 -1
  502. package/src/responses/spill-store.ts +75 -10
  503. package/src/responses/state.ts +565 -27
  504. package/src/responses/thought-signature-replay.ts +347 -0
  505. package/src/responses/tool-search-compat.ts +301 -0
  506. package/src/responses/truncated-stop-reason.ts +60 -0
  507. package/src/router.ts +366 -30
  508. package/src/routing/analytics.ts +378 -0
  509. package/src/routing/capability.ts +244 -0
  510. package/src/routing/compatibility/assemble.ts +73 -0
  511. package/src/routing/compatibility/behavior.ts +278 -0
  512. package/src/routing/compatibility/catalog.ts +99 -0
  513. package/src/routing/compatibility/endpoint.ts +52 -0
  514. package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
  515. package/src/routing/compatibility/policy.ts +181 -0
  516. package/src/routing/compatibility/provider-slot.ts +56 -0
  517. package/src/routing/compatibility/reader.ts +110 -0
  518. package/src/routing/compatibility/subject.ts +191 -0
  519. package/src/routing/compatibility/types.ts +64 -0
  520. package/src/routing/compatibility/version.ts +104 -0
  521. package/src/routing/cost.ts +77 -0
  522. package/src/routing/evaluator.ts +495 -0
  523. package/src/routing/health.ts +412 -0
  524. package/src/routing/history/cursor.ts +43 -0
  525. package/src/routing/history/indexer.ts +605 -0
  526. package/src/routing/history/schema.ts +72 -0
  527. package/src/routing/profile-namespace.ts +15 -0
  528. package/src/routing/profile.ts +547 -0
  529. package/src/routing/quota.ts +145 -0
  530. package/src/routing/request-evidence.ts +45 -0
  531. package/src/routing/trace.ts +776 -0
  532. package/src/server/adapter-resolve.ts +2 -29
  533. package/src/server/auth-cors.ts +267 -46
  534. package/src/server/background-lifecycle.ts +182 -0
  535. package/src/server/chat-completions.ts +130 -56
  536. package/src/server/chat-native-sse.ts +331 -0
  537. package/src/server/chat-native.ts +426 -0
  538. package/src/server/claude-messages.ts +159 -43
  539. package/src/server/direct-local-http.ts +347 -0
  540. package/src/server/effort-policy.ts +18 -0
  541. package/src/server/github-copilot-responses-repair.ts +338 -0
  542. package/src/server/gui-static.ts +39 -10
  543. package/src/server/images.ts +94 -12
  544. package/src/server/index.ts +865 -181
  545. package/src/server/lifecycle.ts +284 -13
  546. package/src/server/live.ts +136 -17
  547. package/src/server/local-management-read-client.ts +90 -0
  548. package/src/server/local-provider-reload-client.ts +137 -0
  549. package/src/server/management/agent-settings-routes.ts +398 -103
  550. package/src/server/management/api-key-usage.ts +31 -5
  551. package/src/server/management/body.ts +6 -0
  552. package/src/server/management/combo-routes.ts +62 -24
  553. package/src/server/management/config-routes.ts +464 -51
  554. package/src/server/management/context.ts +80 -2
  555. package/src/server/management/integration-routes.ts +498 -0
  556. package/src/server/management/lab-automation-routes.ts +206 -0
  557. package/src/server/management/lab-routes.ts +563 -0
  558. package/src/server/management/logs-usage-routes.ts +101 -32
  559. package/src/server/management/model-routes.ts +189 -131
  560. package/src/server/management/model-rows.ts +163 -0
  561. package/src/server/management/native-integration-routes.ts +769 -0
  562. package/src/server/management/oauth-account-routes.ts +80 -4
  563. package/src/server/management/provider-capability-config.ts +48 -0
  564. package/src/server/management/provider-routes.ts +764 -157
  565. package/src/server/management/request-history-routes.ts +191 -0
  566. package/src/server/management/routing-analytics-routes.ts +74 -0
  567. package/src/server/management/routing-profile-routes.ts +380 -0
  568. package/src/server/management/shared.ts +27 -11
  569. package/src/server/management/sidebar-routes.ts +47 -31
  570. package/src/server/management/storage-log-guard-routes.ts +186 -0
  571. package/src/server/management/sync-response.ts +69 -0
  572. package/src/server/management/system-restart.ts +288 -32
  573. package/src/server/management/system-routes.ts +77 -0
  574. package/src/server/management/usage-summary-cache.ts +9 -1
  575. package/src/server/management/vision-sidecar-options.ts +167 -0
  576. package/src/server/management/web-search-sidecar-options.ts +120 -0
  577. package/src/server/management-api.ts +115 -14
  578. package/src/server/management-auth.ts +220 -5
  579. package/src/server/passive-route-linker.ts +66 -0
  580. package/src/server/ports.ts +41 -1
  581. package/src/server/proxy-liveness.ts +132 -5
  582. package/src/server/readiness.ts +99 -0
  583. package/src/server/relay-eager.ts +82 -42
  584. package/src/server/relay.ts +236 -76
  585. package/src/server/request-decompress.ts +113 -6
  586. package/src/server/request-log.ts +235 -22
  587. package/src/server/responses/agent-task-recovery-cache.ts +143 -0
  588. package/src/server/responses/agent-task-recovery.ts +465 -0
  589. package/src/server/responses/collaboration.ts +204 -35
  590. package/src/server/responses/compact.ts +442 -55
  591. package/src/server/responses/core.ts +2872 -331
  592. package/src/server/responses/empty-completion-guard.ts +276 -0
  593. package/src/server/responses/encrypted-payload.ts +62 -39
  594. package/src/server/responses/fetch-helpers.ts +79 -4
  595. package/src/server/responses/input-admission.ts +185 -0
  596. package/src/server/responses/pacing-overload.ts +13 -0
  597. package/src/server/responses/policy-fallback.ts +178 -0
  598. package/src/server/responses/responses-field-backfill.ts +251 -0
  599. package/src/server/responses/terminal-guard.ts +26 -5
  600. package/src/server/responses/upstream-error.ts +5 -0
  601. package/src/server/responses/ws-upstream.ts +308 -0
  602. package/src/server/responses-custom-tool-repair.ts +282 -0
  603. package/src/server/responses-item-id-repair.ts +54 -6
  604. package/src/server/responses-json-events.ts +90 -0
  605. package/src/server/responses-model-rewrite.ts +29 -0
  606. package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
  607. package/src/server/responses-snapshot-repair.ts +621 -0
  608. package/src/server/responses-terminal-repair.ts +342 -0
  609. package/src/server/responses-tool-search-repair.ts +267 -0
  610. package/src/server/responses-undeclared-tool-guard.ts +153 -0
  611. package/src/server/responses.ts +18 -2
  612. package/src/server/search.ts +78 -13
  613. package/src/server/sse-frame-buffer.ts +292 -0
  614. package/src/server/sse-payload-rewrite.ts +110 -22
  615. package/src/server/startup-action-control.ts +8 -1
  616. package/src/server/startup-health-cache.ts +19 -1
  617. package/src/server/system-env.ts +80 -9
  618. package/src/server/ws-bridge.ts +39 -38
  619. package/src/service-manager-probe.ts +892 -0
  620. package/src/service.ts +1111 -90
  621. package/src/sidecar/auth.ts +92 -0
  622. package/src/sidecar/candidates.ts +83 -0
  623. package/src/storage/cleanup.ts +2 -2
  624. package/src/storage/scanner.ts +1 -1
  625. package/src/storage/worker-lifecycle.ts +14 -14
  626. package/src/tray/windows-tray.ps1 +83 -9
  627. package/src/tray/windows.ts +43 -16
  628. package/src/types/accounts.ts +37 -0
  629. package/src/types/config.ts +845 -0
  630. package/src/types/provider.ts +545 -0
  631. package/src/types/request.ts +384 -0
  632. package/src/types/tools.ts +131 -0
  633. package/src/types/wire.ts +80 -0
  634. package/src/types.ts +104 -1236
  635. package/src/update/index.ts +32 -19
  636. package/src/update/job.ts +442 -67
  637. package/src/update/notify.ts +12 -6
  638. package/src/update/npm-cache-preflight.d.mts +47 -0
  639. package/src/update/npm-cache-preflight.mjs +201 -0
  640. package/src/update/transactional-install.d.mts +22 -0
  641. package/src/update/transactional-install.mjs +259 -0
  642. package/src/usage/cost.ts +0 -0
  643. package/src/usage/expected-prices.ts +268 -16
  644. package/src/usage/log.ts +606 -41
  645. package/src/usage/summary.ts +177 -9
  646. package/src/usage/user-cost-overlay-reconciler.ts +313 -0
  647. package/src/usage/user-cost-overlays.ts +314 -0
  648. package/src/vision/anthropic-describe.ts +10 -6
  649. package/src/vision/backends.ts +97 -0
  650. package/src/vision/describe.ts +9 -3
  651. package/src/vision/eligibility.ts +250 -0
  652. package/src/vision/index.ts +238 -24
  653. package/src/vision/reasoning.ts +55 -0
  654. package/src/vision/routed-describe.ts +175 -0
  655. package/src/vision/timeout-bounds.ts +9 -0
  656. package/src/web-search/anthropic-executor.ts +13 -7
  657. package/src/web-search/backends.ts +108 -0
  658. package/src/web-search/exa-executor.ts +88 -0
  659. package/src/web-search/executor.ts +11 -3
  660. package/src/web-search/gemini-executor.ts +141 -0
  661. package/src/web-search/index.ts +150 -15
  662. package/src/web-search/loop.ts +279 -50
  663. package/src/web-search/parse.ts +125 -30
  664. package/src/web-search/sources.ts +60 -0
  665. package/src/web-search/xai-executor.ts +219 -0
  666. package/gui/dist/assets/index-DTpMHS4F.js +0 -67
  667. package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
  668. package/gui/dist/provider-icons/antigravity.svg +0 -1
  669. package/gui/dist/provider-icons/claude.svg +0 -1
  670. package/gui/dist/provider-icons/copilot.svg +0 -1
  671. package/gui/dist/provider-icons/cursor.svg +0 -2
  672. package/gui/dist/provider-icons/gemini.svg +0 -1
  673. package/gui/dist/provider-icons/grok-color.svg +0 -1
  674. package/gui/dist/provider-icons/kiro.svg +0 -14
  675. package/src/cli/internal-dispatch.ts +0 -20
@@ -0,0 +1,278 @@
1
+ import { modelRecordValue } from "../../reasoning-effort";
2
+ import { modelInList } from "../../types";
3
+ import type { OcxConfig, OcxProviderConfig } from "../../types";
4
+ import { PROVIDER_REGISTRY } from "../../providers/registry";
5
+ import { fastPolicyForModel, serviceTierSupportFromPolicy } from "../../providers/service-tier";
6
+ import { resolveProviderAuthTransport } from "../../providers/fastwire";
7
+ import { localFingerprint } from "../../lab/digest";
8
+ import type { LabBehaviorSource, LabBehaviorValues } from "../../lab/live/types";
9
+
10
+ export function upstreamProtocolForAdapter(adapter: string): string {
11
+ switch (adapter) {
12
+ case "openai-responses":
13
+ return "openai-responses";
14
+ case "openai-chat":
15
+ case "command-code":
16
+ case "cursor":
17
+ case "azure":
18
+ case "azure-openai":
19
+ case "kiro":
20
+ case "mimo-free":
21
+ return "openai-chat";
22
+ case "anthropic":
23
+ return "anthropic-messages";
24
+ case "google":
25
+ return "google-generate";
26
+ default:
27
+ return "openai-responses";
28
+ }
29
+ }
30
+
31
+ export function surfaceForProtocols(inboundProtocol: string, upstreamProtocol: string): string {
32
+ if (inboundProtocol === "anthropic-messages") return "anthropic-messages-http";
33
+ if (upstreamProtocol === "anthropic-messages") return "responses-http";
34
+ if (upstreamProtocol === "openai-chat") return "responses-sse";
35
+ return "responses-http";
36
+ }
37
+
38
+ function behaviorRow(source: LabBehaviorSource, value: unknown) {
39
+ return { source, value };
40
+ }
41
+
42
+ /**
43
+ * Membership for the provider's `no*Models`-style lists.
44
+ *
45
+ * Delegates to modelInList so the report matches the wire: every runtime gate these
46
+ * rows describe (openai-chat's sampling/reasoning/tool-choice gates, reasoning-effort's
47
+ * noReasoningModels) matches through modelInList, which also accepts a bare entry for a
48
+ * tagged id. ollama-cloud serves `gpt-oss:120b` and lists the bare `gpt-oss`, so an
49
+ * exact-only check here reported "temperature is sent" on a request that omits it.
50
+ */
51
+ function includesModel(list: string[] | undefined, modelId: string): boolean {
52
+ return modelInList(list, modelId);
53
+ }
54
+
55
+ /**
56
+ * Per-model override lookup for the nine family-aware report rows.
57
+ *
58
+ * Delegates to modelRecordValue so the report reads these maps the way the
59
+ * runtime does -- own properties only, then the pre-colon family, then a
60
+ * case-folded key. A bare index disagreed on all three: it missed the
61
+ * `gpt-oss` entry ollama-cloud's `gpt-oss:120b` actually resolves, missed a
62
+ * differently-cased key, and walked the prototype chain, so a routed model id
63
+ * of `constructor`/`toString` yielded an Object.prototype function. That last
64
+ * one made buildBehaviorFingerprintV1 throw ("unsupported value type
65
+ * function"); the caller catches it (`src/routing/compatibility/subject.ts:125`)
66
+ * and returns no route, so the subject is silently dropped -- and the linker
67
+ * contract says implementations do not throw.
68
+ *
69
+ * Not every override map belongs here. `modelPreferHostedTools` and
70
+ * `modelOpenRouterRouting` are exact-own at runtime and go through
71
+ * `exactOwnValue` below; widening those to the family would be this same bug
72
+ * with the sign flipped.
73
+ */
74
+ function modelValue<T>(map: Record<string, T> | undefined, modelId: string): T | undefined {
75
+ return modelRecordValue(map, modelId);
76
+ }
77
+
78
+ /**
79
+ * Exact, own-property lookup for the two maps the runtime resolves that way.
80
+ *
81
+ * `modelPreferHostedTools` and `modelOpenRouterRouting` are deliberately exact: the
82
+ * adapter reads the first through `hasOwnProperty`
83
+ * (`src/adapters/openai-responses.ts:1001`) and the second through `Object.hasOwn`
84
+ * (`src/providers/openrouter-routing.ts:89`), and the type documents the first as
85
+ * "Exact-model hosted tools" (`src/types.ts:1584`). Sending them through
86
+ * `modelRecordValue` would make the report say a `gpt-oss` entry applies to
87
+ * `gpt-oss:120b` when the adapter will never apply it -- the same divergence this
88
+ * file exists to remove, pointed the other way. A bare index is not the answer
89
+ * either: it walks the prototype chain, which is the bug `modelValue` just fixed.
90
+ * Neither existing primitive is right for these two, so this is the third one.
91
+ */
92
+ function exactOwnValue<T>(map: Record<string, T> | undefined, modelId: string): T | undefined {
93
+ return map !== undefined && Object.hasOwn(map, modelId) ? map[modelId] : undefined;
94
+ }
95
+
96
+ const CREDENTIAL_HEADER = /(authorization|api[-_]?key|token|secret|credential|cookie)/i;
97
+
98
+ function nonCredentialHeaderDigest(
99
+ headers: Record<string, string> | undefined,
100
+ installationSalt: Uint8Array | string,
101
+ ): string {
102
+ const rows = Object.entries(headers ?? {})
103
+ .filter(([name]) => !CREDENTIAL_HEADER.test(name))
104
+ .map(([name, value]) => [name.toLowerCase().trim(), value] as const)
105
+ .sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0);
106
+ return localFingerprint("nonCredentialHeaders", rows, installationSalt);
107
+ }
108
+
109
+ function effectiveOpenRouterRouting(effective: OcxProviderConfig, modelId: string) {
110
+ return exactOwnValue(effective.modelOpenRouterRouting, modelId) ?? effective.openRouterRouting;
111
+ }
112
+
113
+ /**
114
+ * Production behavior resolver for route-subject fingerprinting.
115
+ *
116
+ * The caller supplies the already-resolved effective provider config. This is
117
+ * deliberately the same effective config used for routeContext identity so a
118
+ * model wire override cannot disagree with the behavior fingerprint.
119
+ */
120
+ export function resolveProductionBehaviorValues(
121
+ config: OcxConfig,
122
+ providerName: string,
123
+ modelId: string,
124
+ effective: OcxProviderConfig,
125
+ installationSalt: Uint8Array | string,
126
+ ): LabBehaviorValues | null {
127
+ const provider = config.providers[providerName];
128
+ if (!provider || provider.disabled === true) return null;
129
+ const adapter = effective.adapter ?? "openai-responses";
130
+ const upstreamProtocol = upstreamProtocolForAdapter(adapter);
131
+ const registryEntry = PROVIDER_REGISTRY.find(entry => entry.id === providerName);
132
+ const authMode = effective.authMode ?? registryEntry?.authKind ?? "key";
133
+ const reasoningEfforts = modelValue(effective.modelReasoningEfforts, modelId)
134
+ ?? effective.reasoningEfforts
135
+ ?? [];
136
+ const defaultReasoningEffort = modelValue(effective.modelDefaultReasoningEfforts, modelId) ?? null;
137
+ const reasoningEffortMap = modelValue(effective.modelReasoningEffortMap, modelId)
138
+ ?? effective.reasoningEffortMap
139
+ ?? {};
140
+ const openRouterRouting = effectiveOpenRouterRouting(effective, modelId);
141
+ const project = typeof effective.project === "string" && effective.project ? effective.project : null;
142
+ const location = typeof effective.location === "string" && effective.location ? effective.location : null;
143
+ const nativeLocalExec = effective.nativeLocalExec === "on" || effective.unsafeAllowNativeLocalExec === true;
144
+ const fastPolicy = fastPolicyForModel(effective, modelId, providerName, "responses", provider);
145
+
146
+ const values: LabBehaviorValues = {
147
+ "wire.adapter": behaviorRow("provider_config", adapter),
148
+ "wire.upstreamProtocol": behaviorRow("provider_config", upstreamProtocol),
149
+ "wire.responsesPath": behaviorRow("provider_config", effective.responsesPath ?? null),
150
+ "wire.commandCodeVersion": behaviorRow("provider_config", effective.commandCodeVersion ?? null),
151
+ "wire.modelSuffixMode": behaviorRow(
152
+ "provider_config",
153
+ effective.modelSuffixBracketStrip === true ? "bracket_strip" : "none",
154
+ ),
155
+ "auth.mode": behaviorRow("provider_config", authMode),
156
+ "auth.transport": behaviorRow(
157
+ "provider_config",
158
+ resolveProviderAuthTransport(adapter, authMode, effective.apiKeyTransport),
159
+ ),
160
+ "responses.stateful": behaviorRow("provider_config", effective.statelessResponses !== true),
161
+ "responses.serviceTier": behaviorRow(
162
+ "provider_config",
163
+ serviceTierSupportFromPolicy(fastPolicy) ?? null,
164
+ ),
165
+ "responses.fastWireKind": behaviorRow(
166
+ "provider_config",
167
+ fastPolicy.fastWire?.kind ?? null,
168
+ ),
169
+ "responses.fastWireValue": behaviorRow(
170
+ "provider_config",
171
+ fastPolicy.fastWire?.canonicalToWire.priority ?? null,
172
+ ),
173
+ "responses.snapshotRepair": behaviorRow("provider_config", effective.responsesSnapshotRepair === true),
174
+ "responses.itemIdRepair": behaviorRow("provider_config", effective.responsesItemIdRepair ?? null),
175
+ "limits.contextWindow": behaviorRow(
176
+ "provider_config",
177
+ modelValue(effective.modelContextWindows, modelId) ?? effective.contextWindow ?? null,
178
+ ),
179
+ "limits.maxInputTokens": behaviorRow(
180
+ "provider_config",
181
+ modelValue(effective.modelMaxInputTokens, modelId) ?? null,
182
+ ),
183
+ "limits.maxOutputTokens": behaviorRow(
184
+ "provider_config",
185
+ modelValue(effective.modelMaxOutputTokens, modelId) ?? effective.defaultMaxOutputTokens ?? null,
186
+ ),
187
+ "modalities.input": behaviorRow(
188
+ "provider_config",
189
+ modelValue(effective.modelInputModalities, modelId) ?? ["text"],
190
+ ),
191
+ "sampling.omitTemperature": behaviorRow("provider_config", includesModel(effective.noTemperatureModels, modelId)),
192
+ "sampling.omitTopP": behaviorRow("provider_config", includesModel(effective.noTopPModels, modelId)),
193
+ "sampling.omitPenalties": behaviorRow("provider_config", includesModel(effective.noPenaltyModels, modelId)),
194
+ "reasoning.supported": behaviorRow(
195
+ "provider_config",
196
+ includesModel(effective.noReasoningModels, modelId)
197
+ ? false
198
+ : reasoningEfforts.length > 0 || Boolean(registryEntry?.reasoningEfforts),
199
+ ),
200
+ "reasoning.efforts": behaviorRow("provider_config", reasoningEfforts),
201
+ "reasoning.defaultEffort": behaviorRow("provider_config", defaultReasoningEffort),
202
+ "reasoning.effortMap": behaviorRow("provider_config", reasoningEffortMap),
203
+ "reasoning.wireFormat": behaviorRow("provider_config", effective.reasoningWireFormat ?? null),
204
+ "reasoning.summaryMode": behaviorRow("provider_config", {
205
+ supported: modelValue(effective.modelSupportsReasoningSummaries, modelId) ?? null,
206
+ delivery: modelValue(effective.modelReasoningSummaryDelivery, modelId) ?? null,
207
+ }),
208
+ "reasoning.replayMode": behaviorRow("provider_config", {
209
+ preserveResponses: effective.preserveResponsesReasoningContent === true,
210
+ preserveContent: includesModel(effective.preserveReasoningContentModels, modelId),
211
+ placeholder: includesModel(effective.requiresReasoningPlaceholderModels, modelId),
212
+ }),
213
+ "reasoning.splitMode": behaviorRow("provider_config", includesModel(effective.reasoningSplitModels, modelId)),
214
+ "reasoning.toggleMode": behaviorRow("provider_config", includesModel(effective.thinkingToggleModels, modelId)),
215
+ "reasoning.budgetMode": behaviorRow("provider_config", includesModel(effective.thinkingBudgetModels, modelId)),
216
+ "tools.choiceRestrictions": behaviorRow(
217
+ "provider_config",
218
+ includesModel(effective.autoToolChoiceOnlyModels, modelId) ? ["auto"] : [],
219
+ ),
220
+ "tools.parallel": behaviorRow(
221
+ "provider_config",
222
+ effective.parallelToolCalls ?? (upstreamProtocol === "openai-chat"),
223
+ ),
224
+ "tools.hostedPreference": behaviorRow("provider_config", {
225
+ tools: exactOwnValue(effective.modelPreferHostedTools, modelId) ?? [],
226
+ }),
227
+ "tools.builtinNameEscaping": behaviorRow("provider_config", effective.escapeBuiltinToolNames === true),
228
+ "cache.forwarding": behaviorRow("provider_config", effective.promptCacheKey === true),
229
+ "cache.retention": behaviorRow("global_config", config.cacheRetention ?? "short"),
230
+ "anthropic.eofPolicy": behaviorRow("provider_config", effective.anthropicEofTolerance === true ? "tolerant" : "strict"),
231
+ "openai-chat.eofPolicy": behaviorRow("provider_config", effective.openaiChatEofTolerance === true ? "tolerant" : "strict"),
232
+ "google.mode": behaviorRow("provider_config", effective.googleMode ?? null),
233
+ "google.projectFingerprint": behaviorRow(
234
+ "provider_config",
235
+ project ? localFingerprint("googleProject", project, installationSalt) : null,
236
+ ),
237
+ "google.locationFingerprint": behaviorRow(
238
+ "provider_config",
239
+ location ? localFingerprint("googleLocation", location, installationSalt) : null,
240
+ ),
241
+ "openrouter.order": behaviorRow("provider_config", openRouterRouting?.order ?? []),
242
+ "openrouter.only": behaviorRow("provider_config", openRouterRouting?.only ?? []),
243
+ "openrouter.allowFallbacks": behaviorRow("provider_config", openRouterRouting?.allowFallbacks ?? null),
244
+ "sidecars.vision": behaviorRow(
245
+ "global_config",
246
+ localFingerprint("visionSidecar", config.visionSidecar ?? null, installationSalt),
247
+ ),
248
+ "sidecars.webSearch": behaviorRow(
249
+ "global_config",
250
+ localFingerprint("webSearchSidecar", config.webSearchSidecar ?? null, installationSalt),
251
+ ),
252
+ "mcp.maxTools": behaviorRow("provider_config", effective.mcpMaxTools ?? null),
253
+ "mcp.maxSchemaBytes": behaviorRow("provider_config", effective.mcpMaxSchemaBytes ?? null),
254
+ "mcp.maxResultBytes": behaviorRow("provider_config", effective.mcpMaxResultBytes ?? null),
255
+ "mcp.nativeLocalExec": behaviorRow("provider_config", nativeLocalExec),
256
+ "runtime.bunVersion": behaviorRow("registry_runtime_default", Bun.version),
257
+ "runtime.platform": behaviorRow("registry_runtime_default", process.platform),
258
+ "runtime.arch": behaviorRow("registry_runtime_default", process.arch),
259
+ "runtime.streamMode": behaviorRow("global_config", config.streamMode ?? "auto"),
260
+ "runtime.fastMode": behaviorRow("global_config", config.fastMode === true),
261
+ "runtime.effortCap": behaviorRow("global_config", config.effortCap ?? null),
262
+ "headers.nonCredentialBehaviorDigest": behaviorRow(
263
+ "provider_config",
264
+ nonCredentialHeaderDigest(effective.headers, installationSalt),
265
+ ),
266
+ };
267
+
268
+ return values;
269
+ }
270
+
271
+ export function providerInstanceKey(
272
+ providerName: string,
273
+ effective: OcxProviderConfig,
274
+ ): string {
275
+ const baseUrl = typeof effective.baseUrl === "string" ? effective.baseUrl.trim() : "";
276
+ const adapter = typeof effective.adapter === "string" ? effective.adapter : "";
277
+ return `${providerName}\0${baseUrl}\0${adapter}`;
278
+ }
@@ -0,0 +1,99 @@
1
+ import { queryLabCatalog } from "../../lab/query/catalog";
2
+ import type { CatalogScenarioDto } from "../../lab/query/types";
3
+ import type {
4
+ CompatibilitySuiteRequirement,
5
+ RoutingCompatibilityEvidenceLayer,
6
+ } from "./types";
7
+
8
+ export interface CompatibilityCatalogSuite {
9
+ suiteId: string;
10
+ evidenceLayer: RoutingCompatibilityEvidenceLayer;
11
+ suiteVersion: string;
12
+ suiteManifestDigest: string;
13
+ maxAgeMs: number | null;
14
+ }
15
+
16
+ export type CompatibilityCatalogSnapshot = Map<string, CompatibilityCatalogSuite>;
17
+
18
+ export function compatibilitySuiteKey(
19
+ evidenceLayer: RoutingCompatibilityEvidenceLayer,
20
+ suiteId: string,
21
+ ): string {
22
+ return `${evidenceLayer}:${suiteId}`;
23
+ }
24
+
25
+ function scenarioMaxAge(row: CatalogScenarioDto): number | null | undefined {
26
+ if (!row.freshness || typeof row.freshness !== "object") return undefined;
27
+ if (!Object.hasOwn(row.freshness, "maxAgeMs")) return undefined;
28
+ const value = row.freshness.maxAgeMs;
29
+ if (value === null) return null;
30
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return undefined;
31
+ return value;
32
+ }
33
+
34
+ /**
35
+ * Resolve current suite identities/freshness once per evidence layer before a
36
+ * routing evaluation. The pure evaluator never performs manifest I/O.
37
+ */
38
+ export function loadCompatibilityCatalogSnapshot(
39
+ requirements: readonly CompatibilitySuiteRequirement[],
40
+ ): CompatibilityCatalogSnapshot {
41
+ const wanted = new Map<RoutingCompatibilityEvidenceLayer, Set<string>>();
42
+ for (const requirement of requirements) {
43
+ const suites = wanted.get(requirement.evidenceLayer) ?? new Set<string>();
44
+ suites.add(requirement.suiteId);
45
+ wanted.set(requirement.evidenceLayer, suites);
46
+ }
47
+
48
+ const out: CompatibilityCatalogSnapshot = new Map();
49
+ const invalid = new Set<string>();
50
+
51
+ for (const [layer, suiteIds] of wanted) {
52
+ let rows: CatalogScenarioDto[];
53
+ try {
54
+ rows = queryLabCatalog({ layer });
55
+ } catch {
56
+ // Catalog/manifest failure is fail-safe: affected requirements become
57
+ // missing evidence and follow the profile's unknown-evidence policy.
58
+ continue;
59
+ }
60
+
61
+ for (const row of rows) {
62
+ if (!suiteIds.has(row.suiteId)) continue;
63
+ const key = compatibilitySuiteKey(layer, row.suiteId);
64
+ if (invalid.has(key)) continue;
65
+ const maxAgeMs = scenarioMaxAge(row);
66
+ if (maxAgeMs === undefined) {
67
+ out.delete(key);
68
+ invalid.add(key);
69
+ continue;
70
+ }
71
+
72
+ const prior = out.get(key);
73
+ if (prior && (
74
+ prior.suiteVersion !== row.suiteVersion
75
+ || prior.suiteManifestDigest !== row.suiteManifestDigest
76
+ )) {
77
+ // One current suite id must have one exact version/digest identity.
78
+ out.delete(key);
79
+ invalid.add(key);
80
+ continue;
81
+ }
82
+
83
+ const effectiveMaxAge = prior?.maxAgeMs == null
84
+ ? maxAgeMs
85
+ : maxAgeMs == null
86
+ ? prior.maxAgeMs
87
+ : Math.min(prior.maxAgeMs, maxAgeMs);
88
+ out.set(key, {
89
+ suiteId: row.suiteId,
90
+ evidenceLayer: layer,
91
+ suiteVersion: row.suiteVersion,
92
+ suiteManifestDigest: row.suiteManifestDigest,
93
+ maxAgeMs: effectiveMaxAge,
94
+ });
95
+ }
96
+ }
97
+
98
+ return out;
99
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * DNS-free endpoint fingerprint for routing-time route subject construction.
3
+ * Mirrors the snapshot fields hashed in `createLabDestination` without resolution.
4
+ */
5
+ import { localFingerprint } from "../../lab/digest";
6
+
7
+ function normalizeBasePath(pathname: string): string {
8
+ if (!pathname || pathname === "/") return "";
9
+ const trimmed = pathname.endsWith("/") ? pathname.slice(0, -1) : pathname;
10
+ return trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
11
+ }
12
+
13
+ export interface EndpointFingerprintParts {
14
+ scheme: "http" | "https";
15
+ host: string;
16
+ port: number;
17
+ basePath: string;
18
+ }
19
+
20
+ /** Parse and normalize a provider base URL without network I/O. */
21
+ export function parseEndpointFingerprintParts(baseUrl: string): EndpointFingerprintParts | null {
22
+ try {
23
+ const parsed = new URL(baseUrl);
24
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return null;
25
+ if (parsed.username || parsed.password || parsed.search || parsed.hash) return null;
26
+ const scheme = parsed.protocol === "https:" ? "https" as const : "http" as const;
27
+ const port = parsed.port ? Number(parsed.port) : scheme === "https" ? 443 : 80;
28
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
29
+ return {
30
+ scheme,
31
+ host: parsed.hostname.toLowerCase(),
32
+ port,
33
+ basePath: normalizeBasePath(parsed.pathname),
34
+ };
35
+ } catch {
36
+ return null;
37
+ }
38
+ }
39
+
40
+ export function endpointFingerprintFromBaseUrl(
41
+ baseUrl: string,
42
+ installationSalt: Uint8Array | string,
43
+ ): string | null {
44
+ const parts = parseEndpointFingerprintParts(baseUrl);
45
+ if (!parts) return null;
46
+ return localFingerprint("endpoint", {
47
+ scheme: parts.scheme,
48
+ host: parts.host,
49
+ port: parts.port,
50
+ basePath: parts.basePath,
51
+ }, installationSalt);
52
+ }
@@ -0,0 +1,130 @@
1
+ /**
2
+ * Compatibility-evidence provider (Lab-backed).
3
+ *
4
+ * Holds every Lab-reaching part of policy candidate evidence: route/protocol subject
5
+ * construction, the suite catalog snapshot, and the projection read. The core assembler
6
+ * (`assemble.ts`) keeps capability, health, quota, and cost and consults this only through
7
+ * the provider slot, so an install that never activates Lab never loads this module.
8
+ *
9
+ * This is a relocation of previously inline logic, not a rewrite: `attachCompatibilityEvidence`
10
+ * below is the original function, and its state arrives entirely through arguments.
11
+ *
12
+ * @internal registered by the Lab activation path
13
+ */
14
+ import type { OcxConfig } from "../../types";
15
+ import type { NormalizedRoutingProfile } from "../profile";
16
+ import {
17
+ compatibilitySuiteKey,
18
+ loadCompatibilityCatalogSnapshot,
19
+ type CompatibilityCatalogSnapshot,
20
+ } from "./catalog";
21
+ import { findVerdictForSuite, loadCompatibilityEvidenceSnapshot } from "./reader";
22
+ import {
23
+ resolvePolicyCompatibilitySubjects,
24
+ type ResolvedPolicyCompatibilitySubjects,
25
+ } from "./subject";
26
+ import type { CandidateCompatibilityEvidence } from "./types";
27
+ import type { CoreEvidenceOptions, CompatibilityEvidenceProvider } from "./provider-slot";
28
+
29
+ /** Lab-side seams, kept off the core options contract. */
30
+ export interface LabCompatibilityProviderOptions extends CoreEvidenceOptions {
31
+ resolveSubjects?: typeof resolvePolicyCompatibilitySubjects;
32
+ loadEvidenceSnapshot?: typeof loadCompatibilityEvidenceSnapshot;
33
+ loadCatalogSnapshot?: typeof loadCompatibilityCatalogSnapshot;
34
+ }
35
+
36
+ function attachCompatibilityEvidence(
37
+ resolved: ResolvedPolicyCompatibilitySubjects | undefined,
38
+ snapshot: ReturnType<typeof loadCompatibilityEvidenceSnapshot>,
39
+ catalog: CompatibilityCatalogSnapshot,
40
+ profile: NonNullable<NormalizedRoutingProfile["compatibility"]>,
41
+ ): CandidateCompatibilityEvidence {
42
+ const subjectIds = resolved?.subjectIds ?? {};
43
+ const suites: CandidateCompatibilityEvidence["suites"] = [];
44
+
45
+ for (const requirement of profile.requiredSuites) {
46
+ const subjectId = subjectIds[requirement.evidenceLayer];
47
+ if (!subjectId) continue;
48
+ const metadata = catalog.get(compatibilitySuiteKey(requirement.evidenceLayer, requirement.suiteId));
49
+ if (!metadata) continue;
50
+ const row = findVerdictForSuite(
51
+ snapshot,
52
+ subjectId,
53
+ requirement.evidenceLayer,
54
+ requirement.suiteId,
55
+ metadata.suiteVersion,
56
+ metadata.suiteManifestDigest,
57
+ );
58
+ if (!row) continue;
59
+ suites.push({
60
+ subjectId,
61
+ suiteId: row.suiteId,
62
+ evidenceLayer: requirement.evidenceLayer,
63
+ suiteVersion: row.suiteVersion,
64
+ suiteManifestDigest: row.suiteManifestDigest,
65
+ verdict: row.verdict,
66
+ asOf: row.asOf,
67
+ maxAgeMs: metadata.maxAgeMs,
68
+ notes: row.notes,
69
+ });
70
+ }
71
+
72
+ return {
73
+ subjectIds: { ...subjectIds },
74
+ projectionAvailable: snapshot.projectionAvailable,
75
+ suites,
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Build compatibility evidence for every candidate of one profile.
81
+ * Keyed `provider/model`; a candidate absent from the map has no compatibility evidence.
82
+ */
83
+ export const labCompatibilityEvidenceProvider: CompatibilityEvidenceProvider = (
84
+ config: OcxConfig,
85
+ profile: NormalizedRoutingProfile,
86
+ policy: NonNullable<NormalizedRoutingProfile["compatibility"]>,
87
+ options: CoreEvidenceOptions,
88
+ ): Map<string, CandidateCompatibilityEvidence> => {
89
+ const labOptions = options as LabCompatibilityProviderOptions;
90
+ const resolveSubjects = labOptions.resolveSubjects ?? resolvePolicyCompatibilitySubjects;
91
+ const loadCatalog = labOptions.loadCatalogSnapshot ?? loadCompatibilityCatalogSnapshot;
92
+ const loadEvidence = labOptions.loadEvidenceSnapshot ?? loadCompatibilityEvidenceSnapshot;
93
+
94
+ const resolvedByCandidate = new Map<string, ResolvedPolicyCompatibilitySubjects>();
95
+ const catalog: CompatibilityCatalogSnapshot = loadCatalog(policy.requiredSuites);
96
+ const subjectIds = new Set<string>();
97
+
98
+ for (const candidate of profile.candidates) {
99
+ const provider = config.providers[candidate.provider];
100
+ if (!provider) continue;
101
+ try {
102
+ const routed = options.routedProviderConfig(candidate.provider, provider);
103
+ const resolved = resolveSubjects(
104
+ config,
105
+ candidate.provider,
106
+ candidate.model,
107
+ routed,
108
+ options.configDir,
109
+ );
110
+ resolvedByCandidate.set(`${candidate.provider}/${candidate.model}`, resolved);
111
+ for (const subjectId of Object.values(resolved.subjectIds)) {
112
+ if (subjectId) subjectIds.add(subjectId);
113
+ }
114
+ } catch {
115
+ // Subject construction failure is handled per required layer as unknown.
116
+ }
117
+ }
118
+
119
+ const snapshot = loadEvidence([...subjectIds], options.configDir);
120
+
121
+ const byCandidate = new Map<string, CandidateCompatibilityEvidence>();
122
+ for (const candidate of profile.candidates) {
123
+ const key = `${candidate.provider}/${candidate.model}`;
124
+ byCandidate.set(
125
+ key,
126
+ attachCompatibilityEvidence(resolvedByCandidate.get(key), snapshot, catalog, policy),
127
+ );
128
+ }
129
+ return byCandidate;
130
+ };