@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
|
@@ -22,12 +22,26 @@
|
|
|
22
22
|
* dashboard drain-and-restart confirm UX — never request bodies or IDs.
|
|
23
23
|
*/
|
|
24
24
|
import { selectEagerPath } from "../../lib/bun-stream-caps";
|
|
25
|
+
import { reportedBunRuntimeSource } from "../../lib/bun-runtime";
|
|
25
26
|
import { getActiveTurnCount, isDraining } from "../lifecycle";
|
|
26
27
|
import { getActiveMemoryWatchdog, observedMemoryCounter } from "../memory-watchdog";
|
|
27
28
|
import { responseStateMetrics } from "../../responses/state";
|
|
28
29
|
import { appOwnedBytesSnapshot } from "../../lib/app-owned-memory";
|
|
30
|
+
import { readWindowsReplaceRetryCounters } from "../../lib/windows-atomic-replace";
|
|
31
|
+
import {
|
|
32
|
+
SYSTEM_RESTART_EXPECTED_PID_HEADER,
|
|
33
|
+
parseExpectedSystemRestartPid,
|
|
34
|
+
} from "../../lib/system-restart-contract";
|
|
35
|
+
import {
|
|
36
|
+
CODEX_APP_SERVER_STATE_PATH,
|
|
37
|
+
CODEX_RESTART_PATH,
|
|
38
|
+
} from "../../lib/codex-restart-contract";
|
|
29
39
|
import { jsonResponse } from "../auth-cors";
|
|
30
40
|
import { getInspectionCounters } from "../relay";
|
|
41
|
+
import type {
|
|
42
|
+
performCodexRestart,
|
|
43
|
+
readCodexAppServerState,
|
|
44
|
+
} from "../../codex/app-server-restart-service";
|
|
31
45
|
import type { ManagementContext } from "./context";
|
|
32
46
|
import { acceptSystemRestart } from "./system-restart";
|
|
33
47
|
|
|
@@ -78,6 +92,9 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise<Respon
|
|
|
78
92
|
pid: process.pid,
|
|
79
93
|
bunVersion: Bun.version,
|
|
80
94
|
bunRevision: Bun.revision,
|
|
95
|
+
// Recorded at launch, not resolved now: absent means "this service predates the
|
|
96
|
+
// marker", which callers must report as unknown rather than guess.
|
|
97
|
+
bunRuntimeSource: reportedBunRuntimeSource(),
|
|
81
98
|
platform: process.platform,
|
|
82
99
|
uptimeSeconds: process.uptime(),
|
|
83
100
|
rss: usage.rss,
|
|
@@ -99,7 +116,37 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise<Respon
|
|
|
99
116
|
});
|
|
100
117
|
}
|
|
101
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Windows atomic-replace retry counters.
|
|
121
|
+
*
|
|
122
|
+
* A sibling route rather than a field on /api/system/memory: that payload is
|
|
123
|
+
* memory-shaped, and appending unrelated filesystem counters to it makes both
|
|
124
|
+
* harder to consume.
|
|
125
|
+
*
|
|
126
|
+
* Keys are `publisher:CODE` where publisher is a closed union
|
|
127
|
+
* (ReplacePublisher) and never a path — a path could carry a username. The
|
|
128
|
+
* type is what enforces that; a text scan cannot see a runtime value.
|
|
129
|
+
*/
|
|
130
|
+
if (url.pathname === "/api/system/windows-replace-retries" && req.method === "GET") {
|
|
131
|
+
return jsonResponse({ counters: readWindowsReplaceRetryCounters() });
|
|
132
|
+
}
|
|
102
133
|
if (url.pathname === "/api/system/restart" && req.method === "POST") {
|
|
134
|
+
const expectedPid = parseExpectedSystemRestartPid(
|
|
135
|
+
req.headers.get(SYSTEM_RESTART_EXPECTED_PID_HEADER),
|
|
136
|
+
);
|
|
137
|
+
if (expectedPid.kind === "invalid") {
|
|
138
|
+
return jsonResponse({
|
|
139
|
+
success: false,
|
|
140
|
+
error: "Invalid restart target identity.",
|
|
141
|
+
}, 400, req, config);
|
|
142
|
+
}
|
|
143
|
+
if (expectedPid.kind === "present" && expectedPid.pid !== process.pid) {
|
|
144
|
+
return jsonResponse({
|
|
145
|
+
success: false,
|
|
146
|
+
error: "Restart target identity changed.",
|
|
147
|
+
}, 409, req, config);
|
|
148
|
+
}
|
|
149
|
+
|
|
103
150
|
// Longer informed drain than /api/stop; does not tear down Codex/Grok injection.
|
|
104
151
|
const result = acceptSystemRestart();
|
|
105
152
|
return jsonResponse({
|
|
@@ -113,5 +160,35 @@ export async function handleSystemRoutes(ctx: ManagementContext): Promise<Respon
|
|
|
113
160
|
}, 202, req, config);
|
|
114
161
|
}
|
|
115
162
|
|
|
163
|
+
if (
|
|
164
|
+
(url.pathname === CODEX_APP_SERVER_STATE_PATH && req.method === "GET")
|
|
165
|
+
|| (url.pathname === CODEX_RESTART_PATH && req.method === "POST")
|
|
166
|
+
) {
|
|
167
|
+
// Resolved inside the path check, not at the top of this function: every
|
|
168
|
+
// /api/system/* request runs through here, and an unconditional import would
|
|
169
|
+
// pull the platform process-enumeration helpers into requests that never
|
|
170
|
+
// touch them.
|
|
171
|
+
// An explicit branch rather than `??`: the seam is an optional property, and
|
|
172
|
+
// narrowing through a nullish default keeps its `undefined` in the union.
|
|
173
|
+
let service: {
|
|
174
|
+
readState: typeof readCodexAppServerState;
|
|
175
|
+
performRestart: typeof performCodexRestart;
|
|
176
|
+
};
|
|
177
|
+
const injected = ctx.deps.codexRestartService;
|
|
178
|
+
if (injected) {
|
|
179
|
+
service = injected;
|
|
180
|
+
} else {
|
|
181
|
+
const module = await import("../../codex/app-server-restart-service");
|
|
182
|
+
service = {
|
|
183
|
+
readState: module.readCodexAppServerState,
|
|
184
|
+
performRestart: module.performCodexRestart,
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
if (req.method === "GET") {
|
|
188
|
+
return jsonResponse(service.readState(), 200, req, config);
|
|
189
|
+
}
|
|
190
|
+
return jsonResponse(await service.performRestart(), 200, req, config);
|
|
191
|
+
}
|
|
192
|
+
|
|
116
193
|
return null;
|
|
117
194
|
}
|
|
@@ -8,9 +8,17 @@ export type CachedUsageSummary = UsageSummary & {
|
|
|
8
8
|
entriesDropped: number;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
interface UsageSummaryCacheEntry {
|
|
11
|
+
export interface UsageSummaryCacheEntry {
|
|
12
12
|
revisionKey: string;
|
|
13
|
+
/** path/dev/ino/birthtime only; appends keep this stable. */
|
|
14
|
+
identityKey: string;
|
|
15
|
+
maxReadBytes: number;
|
|
16
|
+
/** userCostOverlayVersion() when the summary was computed; overlay edits invalidate the entry. */
|
|
17
|
+
overlayVersion: number;
|
|
13
18
|
expiresAt: number;
|
|
19
|
+
/** Generation freshness: ignore size/mtime until this instant. */
|
|
20
|
+
freshUntil: number;
|
|
21
|
+
lastSeenSize: number;
|
|
14
22
|
summary: CachedUsageSummary;
|
|
15
23
|
revisionReadAt: number;
|
|
16
24
|
sizeBytes: number;
|
|
@@ -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,16 @@ 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 { handleCodexPromptRoutes } from "./management/codex-prompt-routes";
|
|
75
|
+
import { handleIntegrationRoutes } from "./management/integration-routes";
|
|
76
|
+
import { handleNativeIntegrationRoutes } from "./management/native-integration-routes";
|
|
71
77
|
import type { ManagementContext } from "./management/context";
|
|
78
|
+
import type { ManagementPrincipal } from "./management-auth";
|
|
72
79
|
export type { ManagementApiDeps } from "./management/context";
|
|
73
80
|
import { fetchAllModels } from "./management/shared";
|
|
74
81
|
import { CatalogGatherBusyError } from "../codex/catalog/provider-fetch";
|
|
82
|
+
import type { CatalogDisposition, ConvergeCodex } from "../codex/convergence-types";
|
|
83
|
+
import { normalizeCatalogDisposition } from "../codex/catalog-refresh-status";
|
|
75
84
|
import { managementBodyTooLargeResponse } from "./management/body";
|
|
76
85
|
|
|
77
86
|
// installed npm version instead of a stale hardcode.
|
|
@@ -83,7 +92,53 @@ export const VERSION = (() => {
|
|
|
83
92
|
}
|
|
84
93
|
})();
|
|
85
94
|
|
|
86
|
-
|
|
95
|
+
const managementConvergenceBindings = new WeakMap<object, Readonly<{
|
|
96
|
+
factory: (config: Readonly<OcxConfig>) => ConvergeCodex;
|
|
97
|
+
converge: ConvergeCodex;
|
|
98
|
+
}>>();
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Namespace match for management route prefixes: exact hit or a child path, never a
|
|
102
|
+
* prefix collision (`/api/labfoo` must not match `/api/lab`).
|
|
103
|
+
*/
|
|
104
|
+
function pathInManagementNamespace(pathname: string, prefix: string): boolean {
|
|
105
|
+
return pathname === prefix || pathname.startsWith(`${prefix}/`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Routing-profile and Compatibility Lab handlers statically import the Lab module graph,
|
|
110
|
+
* so mounting them eagerly would pull ~70 `src/lab/` modules into every management
|
|
111
|
+
* request -- including installs that never opted into Lab. Loading them per namespace
|
|
112
|
+
* keeps `management-api.ts` on the same footing as the three protected core files.
|
|
113
|
+
*
|
|
114
|
+
* Cherry-picked from @Wibias's PR #1676, which solved this before the boundary work
|
|
115
|
+
* reached it. See devlog/_fin/260814_lab_core_decoupling/.
|
|
116
|
+
*/
|
|
117
|
+
async function handleRoutingProfileRoutesOnDemand(ctx: ManagementContext): Promise<Response | null> {
|
|
118
|
+
if (!pathInManagementNamespace(ctx.url.pathname, "/api/routing-profiles")) return null;
|
|
119
|
+
const { handleRoutingProfileRoutes } = await import("./management/routing-profile-routes");
|
|
120
|
+
return handleRoutingProfileRoutes(ctx);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
async function handleLabRoutesOnDemand(ctx: ManagementContext): Promise<Response | null> {
|
|
124
|
+
if (!pathInManagementNamespace(ctx.url.pathname, "/api/lab")) return null;
|
|
125
|
+
// Automation is checked first so its narrower namespace keeps its own handler, matching
|
|
126
|
+
// the eager chain's ordering.
|
|
127
|
+
if (pathInManagementNamespace(ctx.url.pathname, "/api/lab/automation")) {
|
|
128
|
+
const { handleLabAutomationRoutes } = await import("./management/lab-automation-routes");
|
|
129
|
+
return handleLabAutomationRoutes(ctx);
|
|
130
|
+
}
|
|
131
|
+
const { handleLabRoutes } = await import("./management/lab-routes");
|
|
132
|
+
return handleLabRoutes(ctx);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export async function handleManagementAPI(
|
|
136
|
+
req: Request,
|
|
137
|
+
url: URL,
|
|
138
|
+
config: OcxConfig,
|
|
139
|
+
deps: ManagementApiDeps = {},
|
|
140
|
+
principal?: ManagementPrincipal,
|
|
141
|
+
): Promise<Response | null> {
|
|
87
142
|
if (!isAllowedManagementOrigin(req, config)) {
|
|
88
143
|
return jsonResponse({ error: "cross-origin request blocked" }, 403, req, config);
|
|
89
144
|
}
|
|
@@ -95,13 +150,48 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
95
150
|
return jsonResponse({ error: "request body too large" }, 413, req, config);
|
|
96
151
|
}
|
|
97
152
|
}
|
|
98
|
-
async function
|
|
99
|
-
|
|
153
|
+
async function convergeCodexCatalog(): Promise<CatalogDisposition> {
|
|
154
|
+
let convergenceInvoked = false;
|
|
155
|
+
let managementConvergeCodex: ConvergeCodex | undefined;
|
|
100
156
|
try {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
157
|
+
if (!managementConvergeCodex) {
|
|
158
|
+
const factory = deps.createManagementConvergeCodex
|
|
159
|
+
?? (await import("../codex/management-convergence")).createManagementConvergeCodex;
|
|
160
|
+
if (typeof factory !== "function") throw new TypeError("Catalog convergence factory is unavailable.");
|
|
161
|
+
let binding = managementConvergenceBindings.get(config);
|
|
162
|
+
if (!binding || binding.factory !== factory) {
|
|
163
|
+
const created = factory(config);
|
|
164
|
+
if (typeof created !== "function") throw new TypeError("Catalog convergence factory returned no function.");
|
|
165
|
+
binding = { factory, converge: created };
|
|
166
|
+
managementConvergenceBindings.set(config, binding);
|
|
167
|
+
}
|
|
168
|
+
managementConvergeCodex = binding.converge;
|
|
169
|
+
}
|
|
170
|
+
const { createCatalogConvergeRequest } = await import("../codex/catalog-admission");
|
|
171
|
+
convergenceInvoked = true;
|
|
172
|
+
const outcome = await managementConvergeCodex(createCatalogConvergeRequest({ deadlineMs: 1_000 }));
|
|
173
|
+
const catalogRefresh = outcome?.kind === "catalog-only"
|
|
174
|
+
? normalizeCatalogDisposition(outcome.catalogRefresh)
|
|
175
|
+
: null;
|
|
176
|
+
if (!catalogRefresh) {
|
|
177
|
+
throw new TypeError("Catalog convergence returned an invalid outcome.");
|
|
178
|
+
}
|
|
179
|
+
return catalogRefresh;
|
|
180
|
+
} catch (error) {
|
|
181
|
+
// #1784: this used to manufacture `reason: "disk"` for every escaping error, so a
|
|
182
|
+
// programming fault and a full filesystem were indistinguishable and both reported
|
|
183
|
+
// non-retryable. Classify honestly and keep the cause allowlisted.
|
|
184
|
+
const invalidRequest = error instanceof TypeError
|
|
185
|
+
|| error instanceof RangeError
|
|
186
|
+
|| error instanceof SyntaxError;
|
|
187
|
+
return {
|
|
188
|
+
status: "failed",
|
|
189
|
+
reason: invalidRequest ? "request-invalid" : "internal",
|
|
190
|
+
phase: convergenceInvoked ? "commit" : "gather",
|
|
191
|
+
retryable: false,
|
|
192
|
+
partialWrite: convergenceInvoked,
|
|
193
|
+
cause: { kind: invalidRequest ? "invalid-request" : "unknown" },
|
|
194
|
+
};
|
|
105
195
|
}
|
|
106
196
|
}
|
|
107
197
|
|
|
@@ -118,7 +208,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
118
208
|
import("../claude/context-windows"),
|
|
119
209
|
import("../codex/catalog"),
|
|
120
210
|
]);
|
|
121
|
-
injectClaudeAgentDefs(config, buildClaudeContextWindows([...visibleNativeSlugs(config)], models));
|
|
211
|
+
injectClaudeAgentDefs(config, buildClaudeContextWindows([...visibleNativeSlugs(config)], models, nativeContextLimits(config)));
|
|
122
212
|
} catch {
|
|
123
213
|
// Keep routes available through a provider-discovery blip. A later
|
|
124
214
|
// launch-time sync restores any context markers missing from this pass.
|
|
@@ -126,19 +216,27 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
126
216
|
}
|
|
127
217
|
} catch { /* best-effort */ }
|
|
128
218
|
}
|
|
129
|
-
const ctx: ManagementContext = { req, url, config, deps,
|
|
219
|
+
const ctx: ManagementContext = { req, url, config, deps, principal, convergeCodexCatalog, syncClaudeAgentDefsBestEffort };
|
|
130
220
|
let routed: Response | null;
|
|
131
221
|
try {
|
|
132
222
|
routed = (await handleConfigRoutes(ctx))
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
223
|
+
?? (await handleStorageLogGuardRoutes(ctx))
|
|
224
|
+
?? (await handleLogsUsageRoutes(ctx))
|
|
225
|
+
?? (await handleRequestHistoryRoutes(ctx))
|
|
226
|
+
?? (await handleRoutingAnalyticsRoutes(ctx))
|
|
227
|
+
?? (await handleRoutingProfileRoutesOnDemand(ctx))
|
|
228
|
+
?? (await handleProviderRoutes(ctx))
|
|
229
|
+
?? (await handleModelRoutes(ctx))
|
|
230
|
+
?? (await handleIntegrationRoutes(ctx))
|
|
231
|
+
?? (await handleNativeIntegrationRoutes(ctx))
|
|
232
|
+
?? (await handleAgentSettingsRoutes(ctx))
|
|
233
|
+
?? (await handleCodexPromptRoutes(ctx))
|
|
234
|
+
?? (await handleClientsRoutes(ctx))
|
|
235
|
+
?? (await handleOauthAccountRoutes(ctx))
|
|
236
|
+
?? (await handleComboRoutes(ctx))
|
|
237
|
+
?? (await handleSystemRoutes(ctx))
|
|
238
|
+
?? (await handleCloudSyncRoutes(ctx))
|
|
239
|
+
?? (await handleLabRoutesOnDemand(ctx))
|
|
142
240
|
?? (await handleSidebarRoutes(ctx));
|
|
143
241
|
} catch (error) {
|
|
144
242
|
const tooLarge = managementBodyTooLargeResponse(error, req, config);
|
|
@@ -158,7 +256,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
158
256
|
if (routed) return routed;
|
|
159
257
|
|
|
160
258
|
if (url.pathname === "/api/stop" && req.method === "POST") {
|
|
161
|
-
const {
|
|
259
|
+
const { restoreNativeCodexAsync } = await import("../codex/inject");
|
|
162
260
|
const { stopServiceIfInstalled, isServiceOwnershipError } = await import("../service");
|
|
163
261
|
try {
|
|
164
262
|
stopServiceIfInstalled();
|
|
@@ -171,7 +269,7 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
171
269
|
}
|
|
172
270
|
throw err;
|
|
173
271
|
}
|
|
174
|
-
const restore =
|
|
272
|
+
const restore = await restoreNativeCodexAsync();
|
|
175
273
|
// Both managed configs come down together on an explicit teardown. The daemon's own
|
|
176
274
|
// syncCleanup skips this when OCX_SERVICE is set (so a crash/respawn keeps the fence),
|
|
177
275
|
// which is exactly why an intentional stop has to do it here.
|
|
@@ -187,12 +285,17 @@ export async function handleManagementAPI(req: Request, url: URL, config: OcxCon
|
|
|
187
285
|
: { success: false, message: `Proxy stopping, but native Codex restore failed: ${restore.message}. Run \`ocx restore\`.${grokNote}` });
|
|
188
286
|
}
|
|
189
287
|
|
|
288
|
+
if (url.pathname.startsWith("/api/native-main-profiles")) {
|
|
289
|
+
const { handleNativeProfileAPI } = await import("../codex/native-profile-api");
|
|
290
|
+
return handleNativeProfileAPI(req, url, config, deps.nativeProfileApi);
|
|
291
|
+
}
|
|
292
|
+
|
|
190
293
|
if (url.pathname.startsWith("/api/codex-auth/")) {
|
|
191
294
|
const { handleCodexAuthAPI } = await import("../codex/auth-api");
|
|
192
295
|
const { ConfigMutationLockError } = await import("../config");
|
|
193
296
|
const { CodexCredentialRefreshLockTimeoutError } = await import("../codex/account-store");
|
|
194
297
|
try {
|
|
195
|
-
return await handleCodexAuthAPI(req, url, config);
|
|
298
|
+
return await handleCodexAuthAPI(req, url, config, convergeCodexCatalog);
|
|
196
299
|
} catch (error) {
|
|
197
300
|
// Credential writers remap ConfigMutationLockError to CodexCredentialRefreshLockTimeoutError;
|
|
198
301
|
// treat both as the same retryable busy response.
|