@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.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +114 -19
- package/bin/ocx.mjs +164 -36
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-BF38heuV.js +104 -0
- package/gui/dist/assets/index-DMiI18Kv.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +19 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +376 -52
- package/src/adapters/base.ts +54 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +129 -6
- package/src/adapters/cursor/discovery.ts +61 -4
- package/src/adapters/cursor/effort-map.ts +27 -3
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +174 -58
- package/src/adapters/cursor/live-transport.ts +609 -170
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +0 -1
- package/src/adapters/cursor/native-exec.ts +101 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +383 -65
- package/src/adapters/cursor/request-builder.ts +237 -31
- package/src/adapters/cursor/tool-definitions.ts +242 -12
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +28 -1
- package/src/adapters/cursor.ts +133 -7
- package/src/adapters/google-antigravity-replay.ts +558 -34
- package/src/adapters/google-antigravity-wire.ts +43 -10
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +618 -74
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +10 -1
- package/src/adapters/kiro.ts +92 -54
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1311 -336
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +830 -56
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +104 -21
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +428 -61
- package/src/chat/inbound.ts +43 -19
- package/src/chat/outbound.ts +82 -26
- package/src/claude/agents-inject.ts +32 -9
- package/src/claude/context-windows.ts +21 -5
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +70 -16
- package/src/cli/account-api.ts +35 -1
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +389 -2
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +30 -6
- package/src/cli/agent.ts +45 -1
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +29 -4
- package/src/cli/claude.ts +103 -34
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +593 -0
- package/src/cli/doctor.ts +315 -43
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +20 -271
- package/src/cli/index.ts +378 -519
- package/src/cli/init.ts +4 -17
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +35 -2
- package/src/cli/models.ts +100 -14
- package/src/cli/observe.ts +92 -3
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +18 -1
- package/src/cli/provider.ts +24 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +437 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +6 -3
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +10 -3
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/v2.ts +105 -10
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1358 -21
- package/src/codex/account-label.ts +14 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +493 -106
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +849 -242
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +345 -32
- package/src/codex/autostart-health.ts +8 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +68 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +121 -30
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +529 -45
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +224 -30
- package/src/codex/catalog/provider-fetch.ts +1460 -134
- package/src/codex/catalog/sync.ts +1449 -186
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +384 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +651 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +407 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-migration-guardian.ts +26 -20
- package/src/codex/history-provider.ts +231 -28
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1073 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +80 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +506 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +353 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +492 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +682 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +967 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +175 -13
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +505 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1009 -28
- package/src/codex/subagent-model-fallback.ts +350 -35
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +612 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +20 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +81 -9
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +1762 -140
- package/src/generated/compatibility-version.json +3164 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +152 -29
- package/src/images/plan.ts +23 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership.ts +111 -0
- package/src/integrations/registry.ts +159 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +361 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +691 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +153 -9
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +6 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +44 -2
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +4 -1
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +8 -2
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +398 -66
- package/src/oauth/key-providers.ts +16 -0
- package/src/oauth/kimi.ts +16 -2
- package/src/oauth/kiro.ts +50 -6
- package/src/oauth/local-token-detect.ts +11 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/store.ts +119 -21
- package/src/oauth/token-guardian.ts +9 -3
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +22 -5
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +253 -6
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +1 -1
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +29 -0
- package/src/providers/quota.ts +1319 -38
- package/src/providers/registry.ts +1429 -111
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +42 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +11 -4
- package/src/reasoning-effort.ts +49 -1
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +266 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +355 -0
- package/src/responses/parser.ts +220 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +7 -1
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +565 -27
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +366 -30
- package/src/routing/analytics.ts +378 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +145 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +267 -46
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +130 -56
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +159 -43
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +865 -181
- package/src/server/lifecycle.ts +284 -13
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +398 -103
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/combo-routes.ts +62 -24
- package/src/server/management/config-routes.ts +464 -51
- package/src/server/management/context.ts +80 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +101 -32
- package/src/server/management/model-routes.ts +189 -131
- package/src/server/management/model-rows.ts +163 -0
- package/src/server/management/native-integration-routes.ts +769 -0
- package/src/server/management/oauth-account-routes.ts +80 -4
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +764 -157
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +288 -32
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +115 -14
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +132 -5
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +82 -42
- package/src/server/relay.ts +236 -76
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log.ts +235 -22
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/collaboration.ts +204 -35
- package/src/server/responses/compact.ts +442 -55
- package/src/server/responses/core.ts +2872 -331
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +79 -4
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +251 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +342 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +153 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +39 -38
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1111 -90
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +845 -0
- package/src/types/provider.ts +545 -0
- package/src/types/request.ts +384 -0
- package/src/types/tools.ts +131 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +104 -1236
- package/src/update/index.ts +32 -19
- package/src/update/job.ts +442 -67
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +268 -16
- package/src/usage/log.ts +606 -41
- package/src/usage/summary.ts +177 -9
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +9 -3
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +11 -3
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +279 -50
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place that decides which models the management API offers as vision
|
|
3
|
+
* describers, and which it refuses to persist.
|
|
4
|
+
*
|
|
5
|
+
* Two routes write a vision sidecar model — `PUT /api/sidecar-settings` and the
|
|
6
|
+
* `visionSidecar` override in `PUT /api/claude-code`. They share this module so
|
|
7
|
+
* the policy cannot drift: a gate on one route and a stale copy on the other is
|
|
8
|
+
* the same as no gate at all.
|
|
9
|
+
*/
|
|
10
|
+
import type { OcxConfig } from "../../types";
|
|
11
|
+
import { findAnthropicVisionProvider, type AnthropicVisionProvider } from "../../vision";
|
|
12
|
+
import { VISION_BACKENDS } from "../../vision/backends";
|
|
13
|
+
import {
|
|
14
|
+
modelAcceptsImageInput,
|
|
15
|
+
visionEligibleModelOptions,
|
|
16
|
+
type VisionCandidateModel,
|
|
17
|
+
type VisionModelOption,
|
|
18
|
+
type VisionSidecarBackend,
|
|
19
|
+
} from "../../vision/eligibility";
|
|
20
|
+
import { pickerVisibleSidecarCandidates } from "../../sidecar/candidates";
|
|
21
|
+
import { resolveSidecarAuth } from "../../sidecar/auth";
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Backends whose executor could actually run (#2188 roadmap 170): openai
|
|
25
|
+
* forward, anthropic OAuth, xai OAuth, Antigravity OAuth — resolved by the
|
|
26
|
+
* VISION_BACKENDS descriptor table so this module and the options path cannot
|
|
27
|
+
* drift on what "active" means.
|
|
28
|
+
*
|
|
29
|
+
* `anthropicSidecar` is REQUIRED rather than defaulted. `findAnthropicVisionProvider`
|
|
30
|
+
* reads the OAuth account store from disk, and a default argument made every helper
|
|
31
|
+
* in this chain re-resolve it whenever a caller passed an explicit `undefined` —
|
|
32
|
+
* which is exactly the no-executor case. Passing it in keeps one read per request.
|
|
33
|
+
* The descriptor table re-derives the anthropic flag from the shared auth
|
|
34
|
+
* module; asserting the caller's resolution stays consistent with it is the
|
|
35
|
+
* job of the shared module, not this file.
|
|
36
|
+
*/
|
|
37
|
+
export function enabledVisionBackends(
|
|
38
|
+
config: OcxConfig,
|
|
39
|
+
anthropicSidecar: AnthropicVisionProvider | undefined,
|
|
40
|
+
): VisionSidecarBackend[] {
|
|
41
|
+
const auth = resolveSidecarAuth(config);
|
|
42
|
+
// Preserve the caller's resolution for the anthropic side: the descriptor
|
|
43
|
+
// reads the shared auth module, but a caller that already resolved "no
|
|
44
|
+
// executor" must not see anthropic options it cannot dispatch. The filter
|
|
45
|
+
// applies to the ACTIVE set only — the fresh-install fallback below stays
|
|
46
|
+
// both universal sides, exactly the pre-widening behavior (test 6 pins it).
|
|
47
|
+
const active = VISION_BACKENDS
|
|
48
|
+
.filter(descriptor => descriptor.isActive(auth, config))
|
|
49
|
+
.map(descriptor => descriptor.backend)
|
|
50
|
+
.filter(backend => backend !== "anthropic" || anthropicSidecar !== undefined);
|
|
51
|
+
// "routed" is active by construction, so the fresh-install fallback keys on
|
|
52
|
+
// the UNIVERSAL sides: when neither resolves, both are offered so the picker
|
|
53
|
+
// stays populated (permissive-unknown rule; test 6 pins it).
|
|
54
|
+
if (!active.includes("openai") && !active.includes("anthropic")) {
|
|
55
|
+
return ["openai", "anthropic", ...active];
|
|
56
|
+
}
|
|
57
|
+
return active;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Visible catalog rows in the shape the eligibility predicate consumes.
|
|
62
|
+
* Sourced from the unified picker set (#2188): picker-visible rows ∪ auth
|
|
63
|
+
* slots, UNFILTERED. Rule 2 (− provably text-only) belongs to the OPTIONS
|
|
64
|
+
* path only (visionEligibleModelOptions already applies it). The PUT gate
|
|
65
|
+
* consumes this list as EVIDENCE: a picker row proving an id text-only is
|
|
66
|
+
* exactly what visionDescriberIsProvablyBlind needs to reject that id, so
|
|
67
|
+
* pre-filtering here would deaden the gate (review F1: reject → allow flip).
|
|
68
|
+
*/
|
|
69
|
+
export async function visionCandidateRows(config: OcxConfig): Promise<VisionCandidateModel[]> {
|
|
70
|
+
const auth = resolveSidecarAuth(config);
|
|
71
|
+
const all = await pickerVisibleSidecarCandidates(config, auth);
|
|
72
|
+
return all.map(candidate => ({
|
|
73
|
+
provider: candidate.provider,
|
|
74
|
+
id: candidate.id,
|
|
75
|
+
...(candidate.inputModalities ? { inputModalities: candidate.inputModalities } : {}),
|
|
76
|
+
...(candidate.native ? { native: true } : {}),
|
|
77
|
+
}));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function visionModelOptionsFrom(
|
|
81
|
+
config: OcxConfig,
|
|
82
|
+
candidates: readonly VisionCandidateModel[],
|
|
83
|
+
anthropicSidecar: AnthropicVisionProvider | undefined,
|
|
84
|
+
): VisionModelOption[] {
|
|
85
|
+
return visionEligibleModelOptions(
|
|
86
|
+
config,
|
|
87
|
+
candidates,
|
|
88
|
+
enabledVisionBackends(config, anthropicSidecar),
|
|
89
|
+
anthropicSidecar?.providerName,
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Convenience for read paths that have no candidate list in hand yet. */
|
|
94
|
+
export async function visionModelOptionsFor(
|
|
95
|
+
config: OcxConfig,
|
|
96
|
+
anthropicSidecar: AnthropicVisionProvider | undefined,
|
|
97
|
+
): Promise<VisionModelOption[]> {
|
|
98
|
+
return visionModelOptionsFrom(config, await visionCandidateRows(config), anthropicSidecar);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Can we PROVE the requested describer is blind?
|
|
103
|
+
*
|
|
104
|
+
* Only a positive `false` rejects. An id no source knows stays allowed, because
|
|
105
|
+
* the runtime never required catalog membership and an operator may be ahead of
|
|
106
|
+
* our tables.
|
|
107
|
+
*
|
|
108
|
+
* When no catalog row matches, the caller's `backend` is only a HINT, never the
|
|
109
|
+
* authority. Trusting it let a client launder a known-blind OpenAI model past the
|
|
110
|
+
* gate by claiming `backend: "anthropic"`, since the id is absent from the
|
|
111
|
+
* Anthropic table and absence reads as "unknown".
|
|
112
|
+
*
|
|
113
|
+
* A NAMESPACED id ("provider/model", the routed-backend option shape) names
|
|
114
|
+
* its provider outright, so that provider's config row and metadata family
|
|
115
|
+
* are probed directly. A BARE id probes ALL configured provider families and
|
|
116
|
+
* any positive text-only verdict wins (roadmap 170: a bare `grok-4` is
|
|
117
|
+
* provably text-only in the xai vendor table and must not slip through a
|
|
118
|
+
* two-family probe). That is safe precisely because the vendor tables share
|
|
119
|
+
* no bare model id (collision scan in roadmap 160: openai 48, anthropic 26,
|
|
120
|
+
* xai 32, google 43, zero overlaps), so they can never disagree about one.
|
|
121
|
+
*/
|
|
122
|
+
export function visionDescriberIsProvablyBlind(
|
|
123
|
+
config: OcxConfig,
|
|
124
|
+
requested: string,
|
|
125
|
+
candidates: readonly VisionCandidateModel[],
|
|
126
|
+
backendHint: VisionSidecarBackend | undefined,
|
|
127
|
+
): boolean {
|
|
128
|
+
// Catalog rows can carry operator-authored modalities. A positive claim from one
|
|
129
|
+
// must not hide another row or canonical metadata that proves this id is blind.
|
|
130
|
+
if (candidates.some(candidate => candidate.id === requested
|
|
131
|
+
&& modelAcceptsImageInput(config, candidate) === false)) return true;
|
|
132
|
+
|
|
133
|
+
// Namespaced routed id: the provider is named, probe it directly (config
|
|
134
|
+
// row enrichment + its metadata family both flow through the predicate).
|
|
135
|
+
const sep = requested.indexOf("/");
|
|
136
|
+
if (sep > 0) {
|
|
137
|
+
const provider = requested.slice(0, sep);
|
|
138
|
+
const id = requested.slice(sep + 1);
|
|
139
|
+
if (modelAcceptsImageInput(config, { provider, id }) === false) return true;
|
|
140
|
+
// A namespaced candidate row (value shape) may also carry the proof.
|
|
141
|
+
return candidates.some(candidate => candidate.provider === provider && candidate.id === id
|
|
142
|
+
&& modelAcceptsImageInput(config, candidate) === false);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Bare id: probe the base vendor families plus every configured provider —
|
|
146
|
+
// a positive text-only verdict from any source wins.
|
|
147
|
+
const families = new Set(["openai", "anthropic", "xai", "google-antigravity", ...Object.keys(config.providers ?? {})]);
|
|
148
|
+
const ordered = backendHint === "anthropic"
|
|
149
|
+
? ["anthropic", ...[...families].filter(family => family !== "anthropic")]
|
|
150
|
+
: ["openai", ...[...families].filter(family => family !== "openai")];
|
|
151
|
+
return ordered.some(provider => modelAcceptsImageInput(config, { provider, id: requested }) === false);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/** The 400 body both routes return, so the two errors cannot diverge either. */
|
|
155
|
+
export function visionDescriberRejection(
|
|
156
|
+
field: "vision.model" | "visionSidecar.model",
|
|
157
|
+
requested: string,
|
|
158
|
+
config: OcxConfig,
|
|
159
|
+
candidates: readonly VisionCandidateModel[],
|
|
160
|
+
): { error: string; allowed: string[] } {
|
|
161
|
+
return {
|
|
162
|
+
error: `${field} "${requested}" cannot describe images: it has no image input support, or it is a model the vision sidecar describes FOR.`,
|
|
163
|
+
// The rejection path is not hot, so it resolves the executor itself rather than
|
|
164
|
+
// making every 400 caller thread one through.
|
|
165
|
+
allowed: visionModelOptionsFrom(config, candidates, findAnthropicVisionProvider(config)).map(option => option.value),
|
|
166
|
+
};
|
|
167
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one place that decides which models the management API offers as the
|
|
3
|
+
* web-search sidecar, and which it refuses to persist (#2188).
|
|
4
|
+
*
|
|
5
|
+
* Two routes write `webSearchSidecar.model` — `PUT /api/sidecar-settings`
|
|
6
|
+
* and the `webSearchSidecar` override in `PUT /api/claude-code`. They share
|
|
7
|
+
* this module for the same reason the vision routes share
|
|
8
|
+
* vision-sidecar-options.ts: a gate on one route and a stale copy on the
|
|
9
|
+
* other is the same as no gate at all. `ocx config set` raw JSON writes
|
|
10
|
+
* bypass management gates by design (operator escape hatch, same as vision).
|
|
11
|
+
*
|
|
12
|
+
* Unlike vision's provably-blind gate (reject only on positive proof), the
|
|
13
|
+
* web-search gate is MEMBERSHIP: the executor set is closed and known, so an
|
|
14
|
+
* id outside (candidates ∪ auth slots) can never run and is refused.
|
|
15
|
+
*/
|
|
16
|
+
import type { OcxConfig } from "../../types";
|
|
17
|
+
import { AUTH_SLOT_MODELS, resolveSidecarAuth } from "../../sidecar/auth";
|
|
18
|
+
import { pickerVisibleSidecarCandidates, type SidecarCandidate } from "../../sidecar/candidates";
|
|
19
|
+
import { WEB_SEARCH_BACKENDS, webSearchSidecarCandidates } from "../../web-search/backends";
|
|
20
|
+
import type { WebSearchBackendId } from "../../web-search/index";
|
|
21
|
+
|
|
22
|
+
// The full configured union. Rows only ever materialize for backends whose
|
|
23
|
+
// executor admits the candidate, so inert arms (gemini/exa without config)
|
|
24
|
+
// simply never produce rows.
|
|
25
|
+
export type WebSearchBackend = WebSearchBackendId;
|
|
26
|
+
|
|
27
|
+
export interface WebSearchCandidateRow extends SidecarCandidate {
|
|
28
|
+
/** Executor backend that admitted this exact candidate row. */
|
|
29
|
+
backend: WebSearchBackend;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export interface WebSearchModelOption {
|
|
33
|
+
value: string;
|
|
34
|
+
label: string;
|
|
35
|
+
/** Exact runnable pair represented by this picker row. */
|
|
36
|
+
backend: WebSearchBackend;
|
|
37
|
+
model: string;
|
|
38
|
+
/** True when the row is an auth-slot entitlement rather than a picker row. */
|
|
39
|
+
authSlot?: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** The candidate rows the web-search executors can actually run right now. */
|
|
43
|
+
export async function webSearchCandidateRows(config: OcxConfig): Promise<WebSearchCandidateRow[]> {
|
|
44
|
+
const auth = resolveSidecarAuth(config);
|
|
45
|
+
const all = await pickerVisibleSidecarCandidates(config, auth);
|
|
46
|
+
return webSearchSidecarCandidates(config, auth, all).flatMap(candidate => {
|
|
47
|
+
const descriptor = WEB_SEARCH_BACKENDS.find(entry =>
|
|
48
|
+
entry.isActive(auth, config) && entry.eligibleModel(candidate, auth));
|
|
49
|
+
return descriptor ? [{ ...candidate, backend: descriptor.backend }] : [];
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* The GUI/CLI option list. The persisted model is display-grandfathered so an
|
|
55
|
+
* operator can SEE a now-illegal setting in the picker (parity with the vision
|
|
56
|
+
* GET); new writes of such an id are still rejected by the gate below.
|
|
57
|
+
*/
|
|
58
|
+
export function webSearchModelOptionsFrom(
|
|
59
|
+
config: Pick<OcxConfig, "webSearchSidecar">,
|
|
60
|
+
candidates: readonly WebSearchCandidateRow[],
|
|
61
|
+
): WebSearchModelOption[] {
|
|
62
|
+
const byValue = new Map<string, WebSearchModelOption>();
|
|
63
|
+
for (const candidate of candidates) {
|
|
64
|
+
if (byValue.has(candidate.id)) continue;
|
|
65
|
+
byValue.set(candidate.id, {
|
|
66
|
+
value: candidate.id,
|
|
67
|
+
label: candidate.id,
|
|
68
|
+
backend: candidate.backend,
|
|
69
|
+
model: candidate.id,
|
|
70
|
+
...(candidate.authSlot ? { authSlot: true } : {}),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const persisted = config.webSearchSidecar?.model;
|
|
74
|
+
if (persisted && !byValue.has(persisted)) {
|
|
75
|
+
byValue.set(persisted, {
|
|
76
|
+
value: persisted,
|
|
77
|
+
label: persisted,
|
|
78
|
+
backend: config.webSearchSidecar?.backend ?? "openai",
|
|
79
|
+
model: persisted,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return [...byValue.values()].sort((a, b) => a.value.localeCompare(b.value));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Membership gate: reject when the id is neither a runnable candidate nor an
|
|
87
|
+
* auth-slot model. Auth slots pass even when the matching login is currently
|
|
88
|
+
* absent — the slot is a legal setting whose executor simply is not live yet,
|
|
89
|
+
* and refusing it would make settings order-dependent on login state.
|
|
90
|
+
*/
|
|
91
|
+
export function webSearchModelIsRejected(
|
|
92
|
+
backend: WebSearchBackend,
|
|
93
|
+
requested: string,
|
|
94
|
+
candidates: readonly WebSearchCandidateRow[],
|
|
95
|
+
): boolean {
|
|
96
|
+
if (requested === AUTH_SLOT_MODELS.codex) return backend !== "openai";
|
|
97
|
+
if (requested === AUTH_SLOT_MODELS.anthropic) return backend !== "anthropic";
|
|
98
|
+
return !candidates.some(candidate => candidate.backend === backend && candidate.id === requested);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Uniform 400 payload naming the filter, mirroring visionDescriberRejection's shape. */
|
|
102
|
+
export function webSearchModelRejection(
|
|
103
|
+
field: string,
|
|
104
|
+
backend: WebSearchBackend,
|
|
105
|
+
requested: string,
|
|
106
|
+
candidates: readonly WebSearchCandidateRow[],
|
|
107
|
+
): { error: string; allowedModels: string[] } {
|
|
108
|
+
const allowed = new Set(candidates
|
|
109
|
+
.filter(candidate => candidate.backend === backend)
|
|
110
|
+
.map(candidate => candidate.id));
|
|
111
|
+
// Preserve the response contract: allowedModels lists both always-configurable
|
|
112
|
+
// auth-slot ids even though the pair gate below binds each to its own backend.
|
|
113
|
+
allowed.add(AUTH_SLOT_MODELS.codex);
|
|
114
|
+
allowed.add(AUTH_SLOT_MODELS.anthropic);
|
|
115
|
+
return {
|
|
116
|
+
error: `${field}: backend/model pair "${backend}/${requested}" is not a web-search sidecar candidate — ` +
|
|
117
|
+
"the model must be picker-visible and runnable by that executor-backed backend (or its auth-slot model)",
|
|
118
|
+
allowedModels: [...allowed].sort(),
|
|
119
|
+
};
|
|
120
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import type { CatalogModel } from "../codex/catalog";
|
|
4
|
-
import { catalogModelSlug, invalidateCodexModelsCache, nativeModelRows, uniqueCatalogModelsForPublicList } from "../codex/catalog";
|
|
4
|
+
import { catalogModelSlug, invalidateCodexModelsCache, nativeContextLimits, nativeModelRows, uniqueCatalogModelsForPublicList } from "../codex/catalog";
|
|
5
5
|
import {
|
|
6
6
|
DEFAULT_SUBAGENT_MODELS,
|
|
7
7
|
codexAutoStartEnabled,
|
|
@@ -28,7 +28,7 @@ import { deriveProviderPresets } from "../providers/derive";
|
|
|
28
28
|
import { providerCodexAccountMode } from "../providers/registry";
|
|
29
29
|
import { routedSlug, slugEquals } from "../providers/slug-codec";
|
|
30
30
|
import { clearProviderQuotaCache, fetchProviderQuotaReports } from "../providers/quota";
|
|
31
|
-
import { isCanonicalOpenAiForwardProvider } from "../providers/openai-tiers";
|
|
31
|
+
import { isCanonicalOpenAiForwardProvider, OPENAI_CODEX_PROVIDER_ID } from "../providers/openai-tiers";
|
|
32
32
|
import { clearThreadAccountMap } from "../codex/routing";
|
|
33
33
|
import { primeCodexPoolQuotas } from "../codex/auth-api";
|
|
34
34
|
import { DEFAULT_PROVIDER_CONTEXT_CAP, globalContextCapValue, providerContextCap, providerContextCaps, setAllProviderContextCaps, setGlobalContextCapValue, setProviderContextCap } from "../providers/context-cap";
|
|
@@ -59,6 +59,9 @@ import { applySystemEnvToggle } from "./system-env";
|
|
|
59
59
|
import type { ManagementApiDeps } from "./management/context";
|
|
60
60
|
import { handleConfigRoutes } from "./management/config-routes";
|
|
61
61
|
import { handleLogsUsageRoutes } from "./management/logs-usage-routes";
|
|
62
|
+
import { handleStorageLogGuardRoutes } from "./management/storage-log-guard-routes";
|
|
63
|
+
import { handleRequestHistoryRoutes } from "./management/request-history-routes";
|
|
64
|
+
import { handleRoutingAnalyticsRoutes } from "./management/routing-analytics-routes";
|
|
62
65
|
import { handleProviderRoutes } from "./management/provider-routes";
|
|
63
66
|
import { handleModelRoutes } from "./management/model-routes";
|
|
64
67
|
import { handleAgentSettingsRoutes } from "./management/agent-settings-routes";
|
|
@@ -68,10 +71,15 @@ import { handleComboRoutes } from "./management/combo-routes";
|
|
|
68
71
|
import { handleSystemRoutes } from "./management/system-routes";
|
|
69
72
|
import { handleCloudSyncRoutes } from "./management/cloud-sync-routes";
|
|
70
73
|
import { handleSidebarRoutes } from "./management/sidebar-routes";
|
|
74
|
+
import { handleIntegrationRoutes } from "./management/integration-routes";
|
|
75
|
+
import { handleNativeIntegrationRoutes } from "./management/native-integration-routes";
|
|
71
76
|
import type { ManagementContext } from "./management/context";
|
|
77
|
+
import type { ManagementPrincipal } from "./management-auth";
|
|
72
78
|
export type { ManagementApiDeps } from "./management/context";
|
|
73
79
|
import { fetchAllModels } from "./management/shared";
|
|
74
80
|
import { CatalogGatherBusyError } from "../codex/catalog/provider-fetch";
|
|
81
|
+
import type { CatalogDisposition, ConvergeCodex } from "../codex/convergence-types";
|
|
82
|
+
import { normalizeCatalogDisposition } from "../codex/catalog-refresh-status";
|
|
75
83
|
import { managementBodyTooLargeResponse } from "./management/body";
|
|
76
84
|
|
|
77
85
|
// installed npm version instead of a stale hardcode.
|
|
@@ -83,7 +91,53 @@ export const VERSION = (() => {
|
|
|
83
91
|
}
|
|
84
92
|
})();
|
|
85
93
|
|
|
86
|
-
|
|
94
|
+
const managementConvergenceBindings = new WeakMap<object, Readonly<{
|
|
95
|
+
factory: (config: Readonly<OcxConfig>) => ConvergeCodex;
|
|
96
|
+
converge: ConvergeCodex;
|
|
97
|
+
}>>();
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Namespace match for management route prefixes: exact hit or a child path, never a
|
|
101
|
+
* prefix collision (`/api/labfoo` must not match `/api/lab`).
|
|
102
|
+
*/
|
|
103
|
+
function pathInManagementNamespace(pathname: string, prefix: string): boolean {
|
|
104
|
+
return pathname === prefix || pathname.startsWith(`${prefix}/`);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Routing-profile and Compatibility Lab handlers statically import the Lab module graph,
|
|
109
|
+
* so mounting them eagerly would pull ~70 `src/lab/` modules into every management
|
|
110
|
+
* request -- including installs that never opted into Lab. Loading them per namespace
|
|
111
|
+
* keeps `management-api.ts` on the same footing as the three protected core files.
|
|
112
|
+
*
|
|
113
|
+
* Cherry-picked from @Wibias's PR #1676, which solved this before the boundary work
|
|
114
|
+
* reached it. See devlog/_fin/260814_lab_core_decoupling/.
|
|
115
|
+
*/
|
|
116
|
+
async function handleRoutingProfileRoutesOnDemand(ctx: ManagementContext): Promise<Response | null> {
|
|
117
|
+
if (!pathInManagementNamespace(ctx.url.pathname, "/api/routing-profiles")) return null;
|
|
118
|
+
const { handleRoutingProfileRoutes } = await import("./management/routing-profile-routes");
|
|
119
|
+
return handleRoutingProfileRoutes(ctx);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
async function handleLabRoutesOnDemand(ctx: ManagementContext): Promise<Response | null> {
|
|
123
|
+
if (!pathInManagementNamespace(ctx.url.pathname, "/api/lab")) return null;
|
|
124
|
+
// Automation is checked first so its narrower namespace keeps its own handler, matching
|
|
125
|
+
// the eager chain's ordering.
|
|
126
|
+
if (pathInManagementNamespace(ctx.url.pathname, "/api/lab/automation")) {
|
|
127
|
+
const { handleLabAutomationRoutes } = await import("./management/lab-automation-routes");
|
|
128
|
+
return handleLabAutomationRoutes(ctx);
|
|
129
|
+
}
|
|
130
|
+
const { handleLabRoutes } = await import("./management/lab-routes");
|
|
131
|
+
return handleLabRoutes(ctx);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export async function handleManagementAPI(
|
|
135
|
+
req: Request,
|
|
136
|
+
url: URL,
|
|
137
|
+
config: OcxConfig,
|
|
138
|
+
deps: ManagementApiDeps = {},
|
|
139
|
+
principal?: ManagementPrincipal,
|
|
140
|
+
): Promise<Response | null> {
|
|
87
141
|
if (!isAllowedManagementOrigin(req, config)) {
|
|
88
142
|
return jsonResponse({ error: "cross-origin request blocked" }, 403, req, config);
|
|
89
143
|
}
|
|
@@ -95,13 +149,48 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
95
149
|
return jsonResponse({ error: "request body too large" }, 413, req, config);
|
|
96
150
|
}
|
|
97
151
|
}
|
|
98
|
-
async function
|
|
99
|
-
|
|
152
|
+
async function convergeCodexCatalog(): Promise<CatalogDisposition> {
|
|
153
|
+
let convergenceInvoked = false;
|
|
154
|
+
let managementConvergeCodex: ConvergeCodex | undefined;
|
|
100
155
|
try {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
156
|
+
if (!managementConvergeCodex) {
|
|
157
|
+
const factory = deps.createManagementConvergeCodex
|
|
158
|
+
?? (await import("../codex/management-convergence")).createManagementConvergeCodex;
|
|
159
|
+
if (typeof factory !== "function") throw new TypeError("Catalog convergence factory is unavailable.");
|
|
160
|
+
let binding = managementConvergenceBindings.get(config);
|
|
161
|
+
if (!binding || binding.factory !== factory) {
|
|
162
|
+
const created = factory(config);
|
|
163
|
+
if (typeof created !== "function") throw new TypeError("Catalog convergence factory returned no function.");
|
|
164
|
+
binding = { factory, converge: created };
|
|
165
|
+
managementConvergenceBindings.set(config, binding);
|
|
166
|
+
}
|
|
167
|
+
managementConvergeCodex = binding.converge;
|
|
168
|
+
}
|
|
169
|
+
const { createCatalogConvergeRequest } = await import("../codex/catalog-admission");
|
|
170
|
+
convergenceInvoked = true;
|
|
171
|
+
const outcome = await managementConvergeCodex(createCatalogConvergeRequest({ deadlineMs: 1_000 }));
|
|
172
|
+
const catalogRefresh = outcome?.kind === "catalog-only"
|
|
173
|
+
? normalizeCatalogDisposition(outcome.catalogRefresh)
|
|
174
|
+
: null;
|
|
175
|
+
if (!catalogRefresh) {
|
|
176
|
+
throw new TypeError("Catalog convergence returned an invalid outcome.");
|
|
177
|
+
}
|
|
178
|
+
return catalogRefresh;
|
|
179
|
+
} catch (error) {
|
|
180
|
+
// #1784: this used to manufacture `reason: "disk"` for every escaping error, so a
|
|
181
|
+
// programming fault and a full filesystem were indistinguishable and both reported
|
|
182
|
+
// non-retryable. Classify honestly and keep the cause allowlisted.
|
|
183
|
+
const invalidRequest = error instanceof TypeError
|
|
184
|
+
|| error instanceof RangeError
|
|
185
|
+
|| error instanceof SyntaxError;
|
|
186
|
+
return {
|
|
187
|
+
status: "failed",
|
|
188
|
+
reason: invalidRequest ? "request-invalid" : "internal",
|
|
189
|
+
phase: convergenceInvoked ? "commit" : "gather",
|
|
190
|
+
retryable: false,
|
|
191
|
+
partialWrite: convergenceInvoked,
|
|
192
|
+
cause: { kind: invalidRequest ? "invalid-request" : "unknown" },
|
|
193
|
+
};
|
|
105
194
|
}
|
|
106
195
|
}
|
|
107
196
|
|
|
@@ -118,7 +207,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
118
207
|
import("../claude/context-windows"),
|
|
119
208
|
import("../codex/catalog"),
|
|
120
209
|
]);
|
|
121
|
-
injectClaudeAgentDefs(config, buildClaudeContextWindows([...visibleNativeSlugs(config)], models));
|
|
210
|
+
injectClaudeAgentDefs(config, buildClaudeContextWindows([...visibleNativeSlugs(config)], models, nativeContextLimits(config)));
|
|
122
211
|
} catch {
|
|
123
212
|
// Keep routes available through a provider-discovery blip. A later
|
|
124
213
|
// launch-time sync restores any context markers missing from this pass.
|
|
@@ -126,19 +215,26 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
126
215
|
}
|
|
127
216
|
} catch { /* best-effort */ }
|
|
128
217
|
}
|
|
129
|
-
const ctx: ManagementContext = { req, url, config, deps,
|
|
218
|
+
const ctx: ManagementContext = { req, url, config, deps, principal, convergeCodexCatalog, syncClaudeAgentDefsBestEffort };
|
|
130
219
|
let routed: Response | null;
|
|
131
220
|
try {
|
|
132
221
|
routed = (await handleConfigRoutes(ctx))
|
|
222
|
+
?? (await handleStorageLogGuardRoutes(ctx))
|
|
133
223
|
?? (await handleLogsUsageRoutes(ctx))
|
|
224
|
+
?? (await handleRequestHistoryRoutes(ctx))
|
|
225
|
+
?? (await handleRoutingAnalyticsRoutes(ctx))
|
|
226
|
+
?? (await handleRoutingProfileRoutesOnDemand(ctx))
|
|
134
227
|
?? (await handleProviderRoutes(ctx))
|
|
135
228
|
?? (await handleModelRoutes(ctx))
|
|
229
|
+
?? (await handleIntegrationRoutes(ctx))
|
|
230
|
+
?? (await handleNativeIntegrationRoutes(ctx))
|
|
136
231
|
?? (await handleAgentSettingsRoutes(ctx))
|
|
137
232
|
?? (await handleClientsRoutes(ctx))
|
|
138
233
|
?? (await handleOauthAccountRoutes(ctx))
|
|
139
234
|
?? (await handleComboRoutes(ctx))
|
|
140
235
|
?? (await handleSystemRoutes(ctx))
|
|
141
236
|
?? (await handleCloudSyncRoutes(ctx))
|
|
237
|
+
?? (await handleLabRoutesOnDemand(ctx))
|
|
142
238
|
?? (await handleSidebarRoutes(ctx));
|
|
143
239
|
} catch (error) {
|
|
144
240
|
const tooLarge = managementBodyTooLargeResponse(error, req, config);
|
|
@@ -158,7 +254,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
158
254
|
if (routed) return routed;
|
|
159
255
|
|
|
160
256
|
if (url.pathname === "/api/stop" && req.method === "POST") {
|
|
161
|
-
const {
|
|
257
|
+
const { restoreNativeCodexAsync } = await import("../codex/inject");
|
|
162
258
|
const { stopServiceIfInstalled, isServiceOwnershipError } = await import("../service");
|
|
163
259
|
try {
|
|
164
260
|
stopServiceIfInstalled();
|
|
@@ -171,7 +267,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
171
267
|
}
|
|
172
268
|
throw err;
|
|
173
269
|
}
|
|
174
|
-
const restore =
|
|
270
|
+
const restore = await restoreNativeCodexAsync();
|
|
175
271
|
// Both managed configs come down together on an explicit teardown. The daemon's own
|
|
176
272
|
// syncCleanup skips this when OCX_SERVICE is set (so a crash/respawn keeps the fence),
|
|
177
273
|
// which is exactly why an intentional stop has to do it here.
|
|
@@ -187,12 +283,17 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
187
283
|
: { success: false, message: `Proxy stopping, but native Codex restore failed: ${restore.message}. Run \`ocx restore\`.${grokNote}` });
|
|
188
284
|
}
|
|
189
285
|
|
|
286
|
+
if (url.pathname.startsWith("/api/native-main-profiles")) {
|
|
287
|
+
const { handleNativeProfileAPI } = await import("../codex/native-profile-api");
|
|
288
|
+
return handleNativeProfileAPI(req, url, config, deps.nativeProfileApi);
|
|
289
|
+
}
|
|
290
|
+
|
|
190
291
|
if (url.pathname.startsWith("/api/codex-auth/")) {
|
|
191
292
|
const { handleCodexAuthAPI } = await import("../codex/auth-api");
|
|
192
293
|
const { ConfigMutationLockError } = await import("../config");
|
|
193
294
|
const { CodexCredentialRefreshLockTimeoutError } = await import("../codex/account-store");
|
|
194
295
|
try {
|
|
195
|
-
return await handleCodexAuthAPI(req, url, config);
|
|
296
|
+
return await handleCodexAuthAPI(req, url, config, convergeCodexCatalog);
|
|
196
297
|
} catch (error) {
|
|
197
298
|
// Credential writers remap ConfigMutationLockError to CodexCredentialRefreshLockTimeoutError;
|
|
198
299
|
// treat both as the same retryable busy response.
|