@iislee/opencodex 2.11.0 → 2.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -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 +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -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 +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- 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 +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- 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 +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- 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 +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- 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 +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- 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 +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- 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 +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- 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 +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -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 +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- 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 +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -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/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -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 +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -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 +360 -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 +622 -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 +675 -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 +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -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 +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -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 +157 -33
- package/src/images/plan.ts +24 -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-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -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/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- 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 +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- 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/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- 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/service-secrets.ts +15 -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 +253 -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 +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -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/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- 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/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -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 +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -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 +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -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 +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -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 +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -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 +155 -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 +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- 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 +1021 -190
- package/src/server/lifecycle.ts +336 -14
- 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 +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -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 +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -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 +289 -33
- 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 +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- 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/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -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 +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -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 +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -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 +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- 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 +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- 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 +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- 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 +27 -16
- 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 +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- 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,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which backends may DESCRIBE images for the vision sidecar, and which
|
|
3
|
+
* candidate rows each can describe through (#2188 vision rules; roadmap 170
|
|
4
|
+
* REVISED: the "routed" backend).
|
|
5
|
+
*
|
|
6
|
+
* A SIBLING of WEB_SEARCH_BACKENDS, not a shared table: vision has no
|
|
7
|
+
* per-model probe (rule 2 is "− provably text-only", enforced by
|
|
8
|
+
* modelAcceptsImageInput, not here), carries per-side baseline models, and
|
|
9
|
+
* excludes non-LLM backends like exa.
|
|
10
|
+
*
|
|
11
|
+
* Three backends, not one per provider: "openai" and "anthropic" carry auth
|
|
12
|
+
* semantics loopback routing cannot replicate (forwarded ChatGPT headers,
|
|
13
|
+
* OAuth beta fences) and their defaults must not drift. Every OTHER
|
|
14
|
+
* picker-visible provider row reaches the describer through "routed" — a
|
|
15
|
+
* loopback self-fetch of the proxy's own /v1/chat/completions, where the
|
|
16
|
+
* router and adapters already speak each provider's wire. That is what makes
|
|
17
|
+
* this table closed under provider growth: a new provider needs no new
|
|
18
|
+
* describe executor.
|
|
19
|
+
*/
|
|
20
|
+
import type { OcxConfig } from "../types";
|
|
21
|
+
import type { SidecarAuthState } from "../sidecar/auth";
|
|
22
|
+
import { listOpenAiForwardSidecarCandidates } from "../providers/openai-sidecar";
|
|
23
|
+
import type { VisionCandidateModel, VisionSidecarBackend } from "./eligibility";
|
|
24
|
+
|
|
25
|
+
export interface VisionBackendDescriptor {
|
|
26
|
+
backend: VisionSidecarBackend;
|
|
27
|
+
/** Liveness signal for this backend. */
|
|
28
|
+
isActive(auth: SidecarAuthState, config: OcxConfig): boolean;
|
|
29
|
+
/** Which candidate rows this backend's describe executor can actually run. */
|
|
30
|
+
candidateMatch(candidate: VisionCandidateModel, auth: SidecarAuthState): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Default entry for this side: cheap, image-capable, present in every
|
|
33
|
+
* deployment. Only the two universal sides carry one — "routed" has no
|
|
34
|
+
* universal model to name.
|
|
35
|
+
*/
|
|
36
|
+
baseline?: string;
|
|
37
|
+
/** Stable option ordering (baselines first within a side). */
|
|
38
|
+
rank: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export const VISION_BACKENDS: readonly VisionBackendDescriptor[] = [
|
|
42
|
+
{
|
|
43
|
+
backend: "openai",
|
|
44
|
+
// The OpenAI describer needs a CANONICAL ChatGPT forward provider, not
|
|
45
|
+
// merely a provider keyed "openai" — same predicate the runtime sidecar
|
|
46
|
+
// resolver uses. Deliberately NOT auth.isCodexAuth: tightening to a live
|
|
47
|
+
// credential here would change which options a fresh install sees, and
|
|
48
|
+
// the options list is a suggestion surface, not the write gate.
|
|
49
|
+
isActive: (_auth, config) => listOpenAiForwardSidecarCandidates(config).length > 0,
|
|
50
|
+
candidateMatch: candidate => candidate.native === true || candidate.provider === "openai",
|
|
51
|
+
baseline: "gpt-5.6-luna",
|
|
52
|
+
rank: 0,
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
backend: "anthropic",
|
|
56
|
+
isActive: auth => auth.isAnthropicAuth,
|
|
57
|
+
// The runtime dispatches through exactly ONE Anthropic provider — the
|
|
58
|
+
// resolved OAuth row. Same-adapter keyed rows are unreachable (see
|
|
59
|
+
// visionBackendForCandidate's original stance).
|
|
60
|
+
candidateMatch: (candidate, auth) => candidate.provider === auth.anthropicProviderName,
|
|
61
|
+
baseline: "claude-haiku-4-5",
|
|
62
|
+
rank: 1,
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
backend: "routed",
|
|
66
|
+
// Always offered: options only materialize when a matching picker row
|
|
67
|
+
// exists, and the row's own provider config is the liveness signal — the
|
|
68
|
+
// loopback request fails closed through ordinary routing errors.
|
|
69
|
+
isActive: () => true,
|
|
70
|
+
// Any row the other two executors do NOT own. Auth-slot rows are
|
|
71
|
+
// entitlements of the openai/anthropic sides and never route here.
|
|
72
|
+
candidateMatch: (candidate, auth) =>
|
|
73
|
+
candidate.native !== true
|
|
74
|
+
&& candidate.provider !== "openai"
|
|
75
|
+
&& candidate.provider !== auth.anthropicProviderName,
|
|
76
|
+
rank: 2,
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
export function visionBackendDescriptor(backend: VisionSidecarBackend): VisionBackendDescriptor {
|
|
81
|
+
const descriptor = VISION_BACKENDS.find(entry => entry.backend === backend);
|
|
82
|
+
if (!descriptor) throw new Error(`unknown vision backend "${backend}"`);
|
|
83
|
+
return descriptor;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The active backend set for option generation. Falls back to the two
|
|
88
|
+
* UNIVERSAL sides when neither is active (fresh install: picker stays
|
|
89
|
+
* populated, permissive-unknown rule); "routed" is active by construction.
|
|
90
|
+
*/
|
|
91
|
+
export function activeVisionBackends(auth: SidecarAuthState, config: OcxConfig): VisionSidecarBackend[] {
|
|
92
|
+
const active = VISION_BACKENDS.filter(entry => entry.isActive(auth, config)).map(entry => entry.backend);
|
|
93
|
+
return active.includes("openai") || active.includes("anthropic")
|
|
94
|
+
? active
|
|
95
|
+
: ["openai", "anthropic", ...active.filter(backend => backend === "routed")];
|
|
96
|
+
}
|
|
97
|
+
|
package/src/vision/describe.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { OcxProviderConfig } from "../types";
|
|
2
|
+
import type { VisionReasoningEffort } from "../reasoning-effort";
|
|
2
3
|
import { FORWARD_HEADERS } from "../adapters/openai-responses";
|
|
3
4
|
import { signalWithTimeout, cancelBodyOnAbort } from "../lib/abort";
|
|
4
5
|
import { redactSecretString } from "../lib/redact";
|
|
@@ -9,6 +10,7 @@ import type { SidecarOutcomeRecorder } from "../web-search/executor";
|
|
|
9
10
|
|
|
10
11
|
export interface VisionSettings {
|
|
11
12
|
model: string;
|
|
13
|
+
reasoning: VisionReasoningEffort;
|
|
12
14
|
timeoutMs: number;
|
|
13
15
|
}
|
|
14
16
|
|
|
@@ -77,9 +79,9 @@ export async function describeImage(
|
|
|
77
79
|
"verbatim, and note UI/layout, colors, branding/logos, charts, and notable details. Focus on " +
|
|
78
80
|
"what's relevant to the user's request. Output only the description.",
|
|
79
81
|
input: [{ type: "message", role: "user", content }],
|
|
80
|
-
reasoning: { effort:
|
|
81
|
-
// The ChatGPT (codex) backend rejects `max_output_tokens` ("Unsupported parameter"); the
|
|
82
|
-
//
|
|
82
|
+
reasoning: { effort: settings.reasoning },
|
|
83
|
+
// The ChatGPT (codex) backend rejects `max_output_tokens` ("Unsupported parameter"); the shared
|
|
84
|
+
// SSE parser bounds raw response bytes before DESC_MAX_CHARS applies its display clamp.
|
|
83
85
|
store: false,
|
|
84
86
|
stream: true,
|
|
85
87
|
};
|
|
@@ -93,29 +95,38 @@ export async function describeImage(
|
|
|
93
95
|
headers,
|
|
94
96
|
body: JSON.stringify(body),
|
|
95
97
|
signal: linkedSignal.signal,
|
|
98
|
+
// Credential-bearing: do not follow a cross-origin 3xx. Bun strips `Authorization`
|
|
99
|
+
// across origins but forwards nonstandard headers such as `chatgpt-account-id`,
|
|
100
|
+
// `session_id`, and `x-codex-turn-metadata` to the redirect target.
|
|
101
|
+
redirect: "manual",
|
|
96
102
|
}),
|
|
97
103
|
{ abortSignal: linkedSignal.signal, label: "vision-sidecar" },
|
|
98
104
|
);
|
|
99
|
-
recordOutcome?.(res.status);
|
|
100
|
-
if (!res.ok) {
|
|
101
|
-
const t = await res.text().catch(() => "");
|
|
102
|
-
console.warn(`[vision] sidecar HTTP ${res.status} (${Date.now() - t0}ms)`);
|
|
103
|
-
return { text: "", error: `vision sidecar HTTP ${res.status}: ${redactSecretString(t.slice(0, 200))}` };
|
|
104
|
-
}
|
|
105
105
|
const detachBodyGuard = cancelBodyOnAbort(res.body, linkedSignal.signal);
|
|
106
|
-
let parsed;
|
|
107
106
|
try {
|
|
108
|
-
|
|
107
|
+
if (!res.ok) {
|
|
108
|
+
recordOutcome?.(res.status);
|
|
109
|
+
const t = await res.text().catch(() => "");
|
|
110
|
+
console.warn(`[vision] sidecar HTTP ${res.status} (${Date.now() - t0}ms)`);
|
|
111
|
+
return { text: "", error: `vision sidecar HTTP ${res.status}: ${redactSecretString(t.slice(0, 200))}` };
|
|
112
|
+
}
|
|
113
|
+
const parsed = await parseSidecarSSE(res);
|
|
114
|
+
if (linkedSignal.signal.aborted) throw linkedSignal.signal.reason;
|
|
115
|
+
recordOutcome?.(res.status);
|
|
116
|
+
// The backend can return HTTP 200 then stream a `response.failed`/`error` event with no text;
|
|
117
|
+
// surface that as a describe error instead of an empty (silently-blank) description.
|
|
118
|
+
if (!parsed.text.trim() && parsed.error) return { text: "", error: parsed.error };
|
|
119
|
+
return { text: parsed.text };
|
|
109
120
|
} finally {
|
|
110
121
|
detachBodyGuard();
|
|
111
122
|
}
|
|
112
|
-
// The backend can return HTTP 200 then stream a `response.failed`/`error` event with no text;
|
|
113
|
-
// surface that as a describe error instead of an empty (silently-blank) description.
|
|
114
|
-
if (!parsed.text.trim() && parsed.error) return { text: "", error: parsed.error };
|
|
115
|
-
return { text: parsed.text };
|
|
116
123
|
} catch (e) {
|
|
117
|
-
recordOutcome?.(e instanceof Error && e.name === "TimeoutError" ? "timeout" : "connect_error");
|
|
118
124
|
const kind = e instanceof Error && e.name === "TimeoutError" ? "timeout" : "connect_error";
|
|
125
|
+
const callerAborted = abortSignal?.aborted === true
|
|
126
|
+
&& linkedSignal.signal.aborted
|
|
127
|
+
&& linkedSignal.signal.reason === abortSignal.reason
|
|
128
|
+
&& e === linkedSignal.signal.reason;
|
|
129
|
+
recordOutcome?.(callerAborted ? "connect_neutral" : kind);
|
|
119
130
|
console.warn(`[vision] sidecar ${kind} (${Date.now() - t0}ms)`);
|
|
120
131
|
return { text: "", error: e instanceof Error ? e.message : String(e) };
|
|
121
132
|
} finally {
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which models may serve AS the vision sidecar (the describer), as opposed to the
|
|
3
|
+
* models the sidecar describes FOR.
|
|
4
|
+
*
|
|
5
|
+
* Three rules make this non-obvious, and all are load-bearing:
|
|
6
|
+
*
|
|
7
|
+
* 1. `provider.noVisionModels` marks models the proxy describes images for, and
|
|
8
|
+
* `applyProviderConfigHints` deliberately ADDS "image" to their advertised
|
|
9
|
+
* input modalities so the Codex app does not block the attachment client-side.
|
|
10
|
+
* A blind model therefore advertises image input. Membership in that list is a
|
|
11
|
+
* hard disqualifier here, checked BEFORE the modality list it rewrote.
|
|
12
|
+
* 2. The catalog enriches configured providers from the registry before it
|
|
13
|
+
* applies that rule. Eligibility must use the same effective provider policy,
|
|
14
|
+
* including a `noVisionModels` list learned after the config was persisted.
|
|
15
|
+
* 3. Catalog rows frequently omit `inputModalities` entirely (the live
|
|
16
|
+
* `/api/models` response carries none for either openai or anthropic rows).
|
|
17
|
+
* Unknown is not zero: when no source can speak, the model stays eligible
|
|
18
|
+
* rather than silently vanishing from the picker.
|
|
19
|
+
* Native OpenAI metadata is likewise authoritative only for a native row or
|
|
20
|
+
* the canonical OpenAI provider; a routed row with the same id owns its own
|
|
21
|
+
* explicit modalities.
|
|
22
|
+
*/
|
|
23
|
+
import { modelInList, type OcxConfig, type OcxProviderConfig } from "../types";
|
|
24
|
+
import { getModelMetadataCaseInsensitive, resolveMetadataProvider } from "../generated/model-metadata";
|
|
25
|
+
import { nativeInputModalities } from "../codex/catalog/metadata";
|
|
26
|
+
import { SUPPORTED_NATIVE_OPENAI_SLUGS } from "../codex/catalog/native-models";
|
|
27
|
+
import { enrichProviderFromRegistry } from "../providers/derive";
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The wire protocols `planVisionSidecar` can dispatch to (#2188 roadmap 170
|
|
31
|
+
* REVISED). "routed" describes through the proxy's OWN router via loopback —
|
|
32
|
+
* one executor for every non-forward, non-OAuth-Anthropic provider row.
|
|
33
|
+
*/
|
|
34
|
+
export type VisionSidecarBackend = "openai" | "anthropic" | "routed";
|
|
35
|
+
|
|
36
|
+
/** The two sides every deployment has; also the empty-auth fallback set. */
|
|
37
|
+
export type UniversalVisionBackend = "openai" | "anthropic";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Default entry per backend: cheap, image-capable, and present in every deployment. Offered
|
|
41
|
+
* whenever its side is enabled, and withheld only when that provider explicitly lists it as a
|
|
42
|
+
* model the sidecar describes FOR — never merely because a metadata table stayed silent.
|
|
43
|
+
*
|
|
44
|
+
* Keyed by the UNIVERSAL subset on purpose (roadmap 170, audit blocker A):
|
|
45
|
+
* xai/gemini are auth-gated sides whose catalogs are present whenever the side
|
|
46
|
+
* is, so they carry no baseline, and a narrow-key total record documents that
|
|
47
|
+
* without sprinkling non-null assertions at the consumers.
|
|
48
|
+
*/
|
|
49
|
+
export const BASELINE_VISION_MODELS: Record<UniversalVisionBackend, string> = {
|
|
50
|
+
openai: "gpt-5.6-luna",
|
|
51
|
+
anthropic: "claude-haiku-4-5",
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export interface VisionCandidateModel {
|
|
55
|
+
provider: string;
|
|
56
|
+
id: string;
|
|
57
|
+
inputModalities?: string[];
|
|
58
|
+
native?: boolean;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export interface VisionModelOption {
|
|
62
|
+
value: string;
|
|
63
|
+
label: string;
|
|
64
|
+
backend: VisionSidecarBackend;
|
|
65
|
+
/** True when the row is a guaranteed baseline rather than a catalog discovery. */
|
|
66
|
+
baseline?: boolean;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type EnrichedProviderCache = Map<string, OcxProviderConfig>;
|
|
70
|
+
|
|
71
|
+
function advertisesImageInput(modalities: readonly string[] | undefined): boolean | undefined {
|
|
72
|
+
if (!modalities || modalities.length === 0) return undefined;
|
|
73
|
+
return modalities.includes("image");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Vendor-table modalities for a routed row, or undefined when the table has no opinion. */
|
|
77
|
+
function metadataImageInput(provider: string, modelId: string): boolean | undefined {
|
|
78
|
+
const resolved = resolveMetadataProvider(provider) ?? provider;
|
|
79
|
+
const meta = getModelMetadataCaseInsensitive(resolved, modelId);
|
|
80
|
+
return advertisesImageInput(meta?.input);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Mirrors the catalog's registry enrichment without mutating saved configuration. The picker
|
|
85
|
+
* checks many rows from one provider, so its caller shares this small call-local cache.
|
|
86
|
+
*/
|
|
87
|
+
function enrichedProviderForVision(
|
|
88
|
+
config: Pick<OcxConfig, "providers">,
|
|
89
|
+
providerName: string,
|
|
90
|
+
cache: EnrichedProviderCache,
|
|
91
|
+
): OcxProviderConfig | undefined {
|
|
92
|
+
const cached = cache.get(providerName);
|
|
93
|
+
if (cached) return cached;
|
|
94
|
+
const configured = config.providers?.[providerName];
|
|
95
|
+
if (!configured) return undefined;
|
|
96
|
+
const enriched = structuredClone(configured);
|
|
97
|
+
enrichProviderFromRegistry(providerName, enriched);
|
|
98
|
+
cache.set(providerName, enriched);
|
|
99
|
+
return enriched;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function isVisionSidecarConsumerWithCache(
|
|
103
|
+
config: Pick<OcxConfig, "providers">,
|
|
104
|
+
providerName: string,
|
|
105
|
+
modelId: string,
|
|
106
|
+
cache: EnrichedProviderCache,
|
|
107
|
+
): boolean {
|
|
108
|
+
return modelInList(enrichedProviderForVision(config, providerName, cache)?.noVisionModels, modelId);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* Is this model listed as one the sidecar describes FOR? Such a model cannot be
|
|
113
|
+
* the describer, and its advertised modalities are untrustworthy.
|
|
114
|
+
*/
|
|
115
|
+
export function isVisionSidecarConsumer(config: Pick<OcxConfig, "providers">, providerName: string, modelId: string): boolean {
|
|
116
|
+
return isVisionSidecarConsumerWithCache(config, providerName, modelId, new Map());
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Can this model accept an image on the wire? Sources are consulted in descending
|
|
121
|
+
* trustworthiness; the first that speaks wins. `undefined` means nothing knows,
|
|
122
|
+
* which callers treat as eligible.
|
|
123
|
+
*/
|
|
124
|
+
export function modelAcceptsImageInput(
|
|
125
|
+
config: Pick<OcxConfig, "providers">,
|
|
126
|
+
candidate: VisionCandidateModel,
|
|
127
|
+
): boolean | undefined {
|
|
128
|
+
return modelAcceptsImageInputWithCache(config, candidate, new Map());
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
function modelAcceptsImageInputWithCache(
|
|
132
|
+
config: Pick<OcxConfig, "providers">,
|
|
133
|
+
candidate: VisionCandidateModel,
|
|
134
|
+
cache: EnrichedProviderCache,
|
|
135
|
+
): boolean | undefined {
|
|
136
|
+
if (isVisionSidecarConsumerWithCache(config, candidate.provider, candidate.id, cache)) return false;
|
|
137
|
+
if (candidate.native === true || (candidate.provider === "openai" && SUPPORTED_NATIVE_OPENAI_SLUGS.has(candidate.id))) {
|
|
138
|
+
return advertisesImageInput(nativeInputModalities(candidate.id)) ?? true;
|
|
139
|
+
}
|
|
140
|
+
const fromRow = advertisesImageInput(candidate.inputModalities);
|
|
141
|
+
if (fromRow !== undefined) return fromRow;
|
|
142
|
+
return metadataImageInput(candidate.provider, candidate.id);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/** Eligible = not a sidecar consumer, and not positively known to be text-only. */
|
|
146
|
+
export function isVisionEligibleModel(
|
|
147
|
+
config: Pick<OcxConfig, "providers">,
|
|
148
|
+
candidate: VisionCandidateModel,
|
|
149
|
+
): boolean {
|
|
150
|
+
return isVisionEligibleModelWithCache(config, candidate, new Map());
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function isVisionEligibleModelWithCache(
|
|
154
|
+
config: Pick<OcxConfig, "providers">,
|
|
155
|
+
candidate: VisionCandidateModel,
|
|
156
|
+
cache: EnrichedProviderCache,
|
|
157
|
+
): boolean {
|
|
158
|
+
return modelAcceptsImageInputWithCache(config, candidate, cache) !== false;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/** Which executor can describe through this row. */
|
|
162
|
+
export function visionBackendForCandidate(
|
|
163
|
+
config: Pick<OcxConfig, "providers">,
|
|
164
|
+
candidate: VisionCandidateModel,
|
|
165
|
+
anthropicProviderName?: string,
|
|
166
|
+
): VisionSidecarBackend | undefined {
|
|
167
|
+
if (candidate.native || candidate.provider === "openai") return "openai";
|
|
168
|
+
// The runtime dispatches through exactly ONE Anthropic provider — the enabled OAuth row
|
|
169
|
+
// with a healthy active account that `findAnthropicVisionProvider` picks. Speaking the
|
|
170
|
+
// Messages wire is not enough: a key-auth row of the same adapter is unreachable, and an
|
|
171
|
+
// option that cannot be dispatched is worse than a missing one, because selecting it fails
|
|
172
|
+
// at describe time rather than at pick time.
|
|
173
|
+
if (anthropicProviderName !== undefined && candidate.provider === anthropicProviderName) {
|
|
174
|
+
return "anthropic";
|
|
175
|
+
}
|
|
176
|
+
// EVERY other provider row describes through the proxy's own router
|
|
177
|
+
// (roadmap 170 revised): the loopback executor covers all provider wires,
|
|
178
|
+
// so no row is left without an executor.
|
|
179
|
+
return "routed";
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function baselineCandidate(
|
|
183
|
+
backend: UniversalVisionBackend,
|
|
184
|
+
anthropicProviderName: string | undefined,
|
|
185
|
+
): VisionCandidateModel {
|
|
186
|
+
return {
|
|
187
|
+
provider: backend === "openai" ? "openai" : anthropicProviderName ?? "anthropic",
|
|
188
|
+
id: BASELINE_VISION_MODELS[backend],
|
|
189
|
+
// Both baselines are known image-capable. This makes their only exclusion path the
|
|
190
|
+
// provider's explicit consumer list, never a silent or stale metadata table.
|
|
191
|
+
inputModalities: ["text", "image"],
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* The picker's option list: every eligible row reachable by an enabled
|
|
197
|
+
* executor, plus each enabled universal side's baseline unless that baseline
|
|
198
|
+
* is explicitly excluded, de-duplicated and stably ordered (side rank order,
|
|
199
|
+
* baselines first within a side). Anthropic rows must belong to the OAuth
|
|
200
|
+
* provider that would actually execute them, so `anthropicProviderName` is
|
|
201
|
+
* what makes that side's catalog rows eligible at all; xai/gemini rows map by
|
|
202
|
+
* provider identity and appear only when the caller enabled those backends.
|
|
203
|
+
*
|
|
204
|
+
* This is the SUGGESTION list (narrow): it emits only rows an executor can reach
|
|
205
|
+
* and some source has heard of. It is deliberately NOT the same set as the write
|
|
206
|
+
* gate. `modelAcceptsImageInput` answers "can we prove this model cannot see?"
|
|
207
|
+
* and is the only input to rejection. Absence from this list must never imply
|
|
208
|
+
* rejection — an unknown id stays eligible via the undefined → eligible fallback.
|
|
209
|
+
*
|
|
210
|
+
* De-duplication is by BARE model id, first eligible row wins. Two providers of
|
|
211
|
+
* the same adapter family can expose the same id; they resolve to the same
|
|
212
|
+
* backend, and only `value` reaches the client, so first-wins costs nothing.
|
|
213
|
+
*/
|
|
214
|
+
export function visionEligibleModelOptions(
|
|
215
|
+
config: Pick<OcxConfig, "providers">,
|
|
216
|
+
candidates: readonly VisionCandidateModel[],
|
|
217
|
+
enabledBackends: readonly VisionSidecarBackend[],
|
|
218
|
+
anthropicProviderName?: string,
|
|
219
|
+
): VisionModelOption[] {
|
|
220
|
+
const enabled = new Set(enabledBackends);
|
|
221
|
+
const byValue = new Map<string, VisionModelOption>();
|
|
222
|
+
const enrichedProviders: EnrichedProviderCache = new Map();
|
|
223
|
+
|
|
224
|
+
for (const backend of Object.keys(BASELINE_VISION_MODELS) as UniversalVisionBackend[]) {
|
|
225
|
+
if (!enabled.has(backend)) continue;
|
|
226
|
+
const candidate = baselineCandidate(backend, anthropicProviderName);
|
|
227
|
+
if (!isVisionEligibleModelWithCache(config, candidate, enrichedProviders)) continue;
|
|
228
|
+
const id = candidate.id;
|
|
229
|
+
byValue.set(id, { value: id, label: id, backend, baseline: true });
|
|
230
|
+
}
|
|
231
|
+
for (const candidate of candidates) {
|
|
232
|
+
const backend = visionBackendForCandidate(config, candidate, anthropicProviderName);
|
|
233
|
+
if (!backend || !enabled.has(backend)) continue;
|
|
234
|
+
if (!isVisionEligibleModelWithCache(config, candidate, enrichedProviders)) continue;
|
|
235
|
+
// Routed rows carry NAMESPACED values ("provider/model") so the loopback
|
|
236
|
+
// dispatch is unambiguous under routeModel; the legacy sides keep bare ids
|
|
237
|
+
// (GUI current-value compatibility, and the forward/OAuth executors POST
|
|
238
|
+
// the string verbatim). De-dup stays keyed by the emitted value.
|
|
239
|
+
const value = backend === "routed" ? `${candidate.provider}/${candidate.id}` : candidate.id;
|
|
240
|
+
if (byValue.has(value)) continue;
|
|
241
|
+
byValue.set(value, { value, label: value, backend });
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Two slots per side (baseline first), ranked openai < anthropic < routed
|
|
245
|
+
// so widening the union appends rather than interleaves (roadmap 170).
|
|
246
|
+
const sideRank: Record<VisionSidecarBackend, number> = { openai: 0, anthropic: 2, routed: 4 };
|
|
247
|
+
const order = (option: VisionModelOption) =>
|
|
248
|
+
sideRank[option.backend] + (option.baseline ? 0 : 1);
|
|
249
|
+
return [...byValue.values()].sort((a, b) => order(a) - order(b) || a.value.localeCompare(b.value));
|
|
250
|
+
}
|