@yansigit/opencodex 2.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/LICENSE +21 -0
- package/README.md +303 -0
- package/assets/architecture.png +0 -0
- package/assets/banner.png +0 -0
- package/assets/claude-code-models.gif +0 -0
- package/assets/codex-app-picker.png +0 -0
- package/bin/ocx.mjs +587 -0
- package/bin/package-main.mjs +9 -0
- package/gui/dist/assets/index-BNJ7r4Gd.js +102 -0
- package/gui/dist/assets/index-CGoDO3uO.css +1 -0
- package/gui/dist/favicon.png +0 -0
- package/gui/dist/icons.svg +24 -0
- package/gui/dist/index.html +25 -0
- package/gui/dist/logo.png +0 -0
- package/gui/dist/provider-icons/alibaba-color.svg +1 -0
- package/gui/dist/provider-icons/antigravity-color.svg +1 -0
- package/gui/dist/provider-icons/claude-color.svg +1 -0
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -0
- package/gui/dist/provider-icons/cursor-color.svg +2 -0
- package/gui/dist/provider-icons/deepseek-color.svg +1 -0
- package/gui/dist/provider-icons/discord.svg +1 -0
- package/gui/dist/provider-icons/firepass-color.svg +1 -0
- package/gui/dist/provider-icons/fireworks-color.svg +1 -0
- package/gui/dist/provider-icons/gemini-color.svg +1 -0
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -0
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -0
- package/gui/dist/provider-icons/grok.svg +1 -0
- package/gui/dist/provider-icons/groq-color.svg +1 -0
- package/gui/dist/provider-icons/huggingface-color.svg +1 -0
- package/gui/dist/provider-icons/kimi-color.svg +1 -0
- package/gui/dist/provider-icons/kiro-color.svg +15 -0
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -0
- package/gui/dist/provider-icons/mistral-color.svg +1 -0
- package/gui/dist/provider-icons/moonshot-color.svg +1 -0
- package/gui/dist/provider-icons/nvidia-color.svg +1 -0
- package/gui/dist/provider-icons/ollama-color.svg +1 -0
- package/gui/dist/provider-icons/openai.svg +1 -0
- package/gui/dist/provider-icons/opencode.svg +2 -0
- package/gui/dist/provider-icons/openrouter-color.svg +1 -0
- package/gui/dist/provider-icons/pi.svg +21 -0
- package/gui/dist/provider-icons/qianfan-color.svg +1 -0
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -0
- package/gui/dist/provider-icons/telegram.svg +1 -0
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -0
- package/gui/dist/provider-icons/vllm-color.svg +1 -0
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -0
- package/package.json +108 -0
- package/src/AGENTS.md +28 -0
- package/src/adapters/anthropic-image-guard.ts +251 -0
- package/src/adapters/anthropic-image-normalize.ts +518 -0
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +1327 -0
- package/src/adapters/azure.ts +36 -0
- package/src/adapters/base.ts +121 -0
- package/src/adapters/client-fingerprint.ts +65 -0
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/arg-codec.ts +38 -0
- package/src/adapters/cursor/arg-normalize.ts +104 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +288 -0
- package/src/adapters/cursor/discovery.ts +333 -0
- package/src/adapters/cursor/effort-map.ts +151 -0
- package/src/adapters/cursor/exec-policy.ts +88 -0
- package/src/adapters/cursor/framing.ts +250 -0
- package/src/adapters/cursor/gen/agent_pb.ts +15274 -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/kv-store.ts +52 -0
- package/src/adapters/cursor/live-models.ts +269 -0
- package/src/adapters/cursor/live-smoke-gate.ts +41 -0
- package/src/adapters/cursor/live-transport.ts +1653 -0
- package/src/adapters/cursor/mcp-config.ts +42 -0
- package/src/adapters/cursor/mcp-manager.ts +333 -0
- package/src/adapters/cursor/message-mapper.ts +49 -0
- package/src/adapters/cursor/native-exec-common.ts +76 -0
- package/src/adapters/cursor/native-exec-desktop.ts +184 -0
- package/src/adapters/cursor/native-exec-fs.ts +332 -0
- package/src/adapters/cursor/native-exec-mcp.ts +153 -0
- package/src/adapters/cursor/native-exec-network.ts +43 -0
- package/src/adapters/cursor/native-exec-shell.ts +547 -0
- package/src/adapters/cursor/native-exec-tools.ts +118 -0
- package/src/adapters/cursor/native-exec.ts +663 -0
- package/src/adapters/cursor/protobuf-events.ts +1381 -0
- package/src/adapters/cursor/protobuf-request.ts +1032 -0
- package/src/adapters/cursor/request-builder.ts +461 -0
- package/src/adapters/cursor/thread-continuity.ts +67 -0
- package/src/adapters/cursor/tool-definitions.ts +735 -0
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport-retry.ts +132 -0
- package/src/adapters/cursor/transport.ts +79 -0
- package/src/adapters/cursor/types.ts +79 -0
- package/src/adapters/cursor.ts +322 -0
- package/src/adapters/google-antigravity-hosts.ts +48 -0
- package/src/adapters/google-antigravity-replay.ts +827 -0
- package/src/adapters/google-antigravity-tools.ts +105 -0
- package/src/adapters/google-antigravity-wire.ts +141 -0
- package/src/adapters/google-errors.ts +92 -0
- package/src/adapters/google-http.ts +460 -0
- package/src/adapters/google-tool-schema.ts +238 -0
- package/src/adapters/google-truncation.ts +24 -0
- package/src/adapters/google-wire-compiler.ts +232 -0
- package/src/adapters/google.ts +1377 -0
- package/src/adapters/identity.ts +77 -0
- package/src/adapters/image.ts +23 -0
- package/src/adapters/kiro-constants.ts +16 -0
- package/src/adapters/kiro-errors.ts +208 -0
- package/src/adapters/kiro-events.ts +197 -0
- package/src/adapters/kiro-images.ts +129 -0
- package/src/adapters/kiro-retry.ts +312 -0
- package/src/adapters/kiro-thinking.ts +112 -0
- package/src/adapters/kiro-tool-fallback.ts +36 -0
- package/src/adapters/kiro-tools.ts +224 -0
- package/src/adapters/kiro-truncation.ts +33 -0
- package/src/adapters/kiro-wire.ts +129 -0
- package/src/adapters/kiro.ts +1936 -0
- package/src/adapters/mimo-free.ts +280 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1980 -0
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1911 -0
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +114 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +154 -0
- package/src/adapters/upstream-http-error.ts +48 -0
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +1986 -0
- package/src/chat/inbound.ts +319 -0
- package/src/chat/outbound.ts +821 -0
- package/src/claude/agents-inject.ts +266 -0
- package/src/claude/alias.ts +149 -0
- package/src/claude/auth-detect.ts +229 -0
- package/src/claude/auth-mode-migration.ts +32 -0
- package/src/claude/auth-mode.ts +62 -0
- package/src/claude/context-windows.ts +205 -0
- package/src/claude/desktop-3p-guard.ts +35 -0
- package/src/claude/desktop-3p-paths.ts +84 -0
- package/src/claude/desktop-3p.ts +615 -0
- package/src/claude/desktop-health.ts +26 -0
- package/src/claude/desktop-profile.ts +263 -0
- package/src/claude/gateway-cache.ts +107 -0
- package/src/claude/inbound-debug.ts +163 -0
- package/src/claude/inbound.ts +578 -0
- package/src/claude/model-info.ts +174 -0
- package/src/claude/outbound.ts +926 -0
- package/src/cli/access.ts +108 -0
- package/src/cli/account-api.ts +302 -0
- package/src/cli/account-auth.ts +250 -0
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +737 -0
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +299 -0
- package/src/cli/agent-driven.ts +70 -0
- package/src/cli/agent.ts +290 -0
- package/src/cli/catalog-prewarm.ts +27 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +213 -0
- package/src/cli/claude.ts +355 -0
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +47 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +127 -0
- package/src/cli/config-command.ts +209 -0
- package/src/cli/debug.ts +228 -0
- package/src/cli/dispatch.ts +585 -0
- package/src/cli/doctor.ts +1202 -0
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +213 -0
- package/src/cli/help.ts +101 -0
- package/src/cli/index.ts +973 -0
- package/src/cli/init.ts +211 -0
- package/src/cli/integrations.ts +260 -0
- package/src/cli/interactive-confirm.ts +133 -0
- 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 +245 -0
- package/src/cli/models.ts +422 -0
- package/src/cli/observe.ts +206 -0
- package/src/cli/opencode.ts +588 -0
- package/src/cli/provider-replit.ts +232 -0
- package/src/cli/provider-runtime.ts +179 -0
- package/src/cli/provider.ts +492 -0
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +422 -0
- package/src/cli/replit-gateway-key-input.ts +138 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +328 -0
- package/src/cli/star-prompt.ts +211 -0
- package/src/cli/status-oauth.ts +78 -0
- package/src/cli/status.ts +328 -0
- package/src/cli/system-command.ts +112 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +199 -0
- package/src/cli/v2.ts +268 -0
- package/src/cli.ts +10 -0
- package/src/clients/config-export.ts +1704 -0
- package/src/codex/account-id.ts +34 -0
- package/src/codex/account-label.ts +47 -0
- package/src/codex/account-lifecycle.ts +172 -0
- package/src/codex/account-namespace-match.ts +63 -0
- package/src/codex/account-namespaces.ts +195 -0
- package/src/codex/account-pause.ts +20 -0
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-runtime-state.ts +31 -0
- package/src/codex/account-store.ts +544 -0
- package/src/codex/account-usability.ts +43 -0
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/agent-roles-sync.ts +225 -0
- package/src/codex/agent-roles.ts +238 -0
- package/src/codex/app-server-processes.ts +1143 -0
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +2147 -0
- package/src/codex/auth-collision.ts +109 -0
- package/src/codex/auth-context.ts +665 -0
- package/src/codex/autostart-health.ts +156 -0
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +436 -0
- package/src/codex/catalog/bundled.ts +549 -0
- package/src/codex/catalog/effort.ts +446 -0
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +664 -0
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +650 -0
- package/src/codex/catalog/provider-fetch.ts +2064 -0
- package/src/codex/catalog/sync.ts +1883 -0
- 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 +14 -0
- package/src/codex/codex-write-lock.ts +384 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +651 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/data/upstream-models.json +830 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/exec-invocation.ts +22 -0
- package/src/codex/features.ts +1566 -0
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +407 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-migration-guardian.ts +108 -0
- package/src/codex/history-provider.ts +979 -0
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/home.ts +206 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1733 -0
- package/src/codex/injected-marker.ts +106 -0
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +80 -0
- package/src/codex/journal.ts +225 -0
- package/src/codex/log-guard/inspect.ts +506 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +56 -0
- package/src/codex/main-account.ts +68 -0
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +273 -0
- package/src/codex/model-entitlements.ts +353 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +492 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +682 -0
- package/src/codex/paths.ts +144 -0
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +242 -0
- package/src/codex/pool-rotation.ts +295 -0
- package/src/codex/project-config-warnings.ts +425 -0
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +967 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +573 -0
- package/src/codex/refresh.ts +62 -0
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +1888 -0
- package/src/codex/runtime.ts +659 -0
- package/src/codex/shim.ts +2170 -0
- package/src/codex/subagent-defaults.ts +550 -0
- package/src/codex/subagent-model-fallback.ts +784 -0
- package/src/codex/sync.ts +319 -0
- package/src/codex/transition-state.ts +612 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +298 -0
- package/src/codex/websocket-registry.ts +100 -0
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +160 -0
- package/src/combos/index.ts +45 -0
- package/src/combos/request.ts +94 -0
- package/src/combos/resolve.ts +232 -0
- package/src/combos/types.ts +398 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +4041 -0
- package/src/fork/register.ts +3 -0
- package/src/generated/compatibility-version.json +3116 -0
- package/src/generated/model-metadata.ts +106 -0
- package/src/github/star-state.ts +203 -0
- package/src/grok/inject.ts +530 -0
- package/src/grok/inspect.ts +45 -0
- package/src/grok/status.ts +121 -0
- package/src/grok/sync.ts +66 -0
- package/src/images/artifacts.ts +516 -0
- package/src/images/fulfill-video.ts +163 -0
- package/src/images/fulfill.ts +149 -0
- package/src/images/index.ts +4 -0
- package/src/images/loop.ts +955 -0
- package/src/images/plan.ts +143 -0
- package/src/images/synthetic-tool.ts +133 -0
- package/src/images/types.ts +41 -0
- package/src/images/xai-client.ts +141 -0
- package/src/images/xai-video-client.ts +163 -0
- package/src/index.ts +22 -0
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership.ts +111 -0
- package/src/integrations/registry.ts +159 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +361 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +691 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/abort.ts +146 -0
- package/src/lib/admin-secrets.ts +25 -0
- package/src/lib/admission.ts +83 -0
- package/src/lib/app-owned-memory-stores.ts +195 -0
- package/src/lib/app-owned-memory.ts +265 -0
- package/src/lib/bounded-body.ts +346 -0
- package/src/lib/bun-binary-validator.d.mts +3 -0
- package/src/lib/bun-binary-validator.mjs +18 -0
- package/src/lib/bun-runtime.ts +184 -0
- package/src/lib/bun-stream-caps.ts +130 -0
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +364 -0
- package/src/lib/crash-guard.ts +344 -0
- package/src/lib/debug-log-buffer.ts +83 -0
- package/src/lib/debug-settings.ts +108 -0
- package/src/lib/debug.ts +31 -0
- package/src/lib/destination-policy.ts +380 -0
- package/src/lib/errors.ts +406 -0
- package/src/lib/eventstream-decoder.ts +253 -0
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/gcp-adc.ts +341 -0
- package/src/lib/injection-debug-log.ts +58 -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/open-url.ts +25 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +270 -0
- package/src/lib/privacy.ts +20 -0
- package/src/lib/process-control.ts +168 -0
- package/src/lib/provider-outbound.ts +210 -0
- package/src/lib/provider-url.ts +14 -0
- package/src/lib/proxy-env.ts +18 -0
- package/src/lib/redact.ts +521 -0
- package/src/lib/retry-after.ts +55 -0
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +25 -0
- package/src/lib/shadow-call.ts +61 -0
- package/src/lib/sidecar-tracker.ts +52 -0
- package/src/lib/sse-decoder.ts +364 -0
- package/src/lib/state-store-registrations.ts +119 -0
- package/src/lib/state-store-sweeper.ts +184 -0
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/test-home-guard.ts +90 -0
- package/src/lib/token-estimate.ts +86 -0
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +400 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +392 -0
- package/src/lib/win-exec.ts +115 -0
- package/src/lib/win-paths.ts +68 -0
- package/src/lib/windows-atomic-replace.ts +156 -0
- package/src/lib/windows-elevation.ts +773 -0
- package/src/lib/windows-secret-acl.ts +854 -0
- 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 +403 -0
- 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-routing.ts +594 -0
- package/src/oauth/anthropic.ts +188 -0
- package/src/oauth/antigravity-routing.ts +151 -0
- package/src/oauth/callback-server.ts +300 -0
- package/src/oauth/chatgpt.ts +161 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +252 -0
- package/src/oauth/github-copilot.ts +428 -0
- package/src/oauth/google-antigravity.ts +262 -0
- package/src/oauth/health.ts +407 -0
- package/src/oauth/index.ts +1504 -0
- package/src/oauth/key-providers.ts +124 -0
- package/src/oauth/kimi.ts +227 -0
- package/src/oauth/kiro-credentials.ts +726 -0
- package/src/oauth/kiro.ts +621 -0
- package/src/oauth/local-token-detect.ts +130 -0
- package/src/oauth/log.ts +50 -0
- package/src/oauth/login-cli.ts +223 -0
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/pkce.ts +15 -0
- package/src/oauth/store.ts +728 -0
- package/src/oauth/token-guardian.ts +309 -0
- package/src/oauth/types.ts +62 -0
- package/src/oauth/xai.ts +241 -0
- package/src/providers/alibaba-region-backup.ts +75 -0
- package/src/providers/alibaba-region-migration.ts +156 -0
- package/src/providers/alibaba-region-startup.ts +36 -0
- package/src/providers/antigravity-models.ts +695 -0
- package/src/providers/antigravity-quota.ts +216 -0
- package/src/providers/api-keys.ts +140 -0
- package/src/providers/base-url-choices.ts +74 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +82 -0
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +586 -0
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +187 -0
- package/src/providers/github-copilot-transport.ts +56 -0
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +271 -0
- package/src/providers/kiro-models.ts +67 -0
- package/src/providers/label.ts +19 -0
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +449 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +243 -0
- package/src/providers/openai-tier-startup.ts +56 -0
- package/src/providers/openai-tiers.ts +423 -0
- package/src/providers/openai-virtual-models.ts +83 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/openrouter-routing.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +185 -0
- package/src/providers/quota.ts +2345 -0
- package/src/providers/registry.ts +2918 -0
- package/src/providers/replit/constants.ts +27 -0
- package/src/providers/replit/derive.ts +85 -0
- package/src/providers/replit/headers.ts +28 -0
- package/src/providers/replit/origin.ts +55 -0
- package/src/providers/replit/pair-install-response.ts +72 -0
- package/src/providers/replit/probe.ts +199 -0
- package/src/providers/replit/setup.ts +350 -0
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +103 -0
- 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 +148 -0
- package/src/reasoning-effort.ts +183 -0
- package/src/responses/compaction.ts +142 -0
- package/src/responses/custom-tool-compat.ts +266 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +355 -0
- package/src/responses/parser.ts +838 -0
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +60 -0
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +165 -0
- package/src/responses/spill-store.ts +459 -0
- package/src/responses/state.ts +1433 -0
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-groups.ts +19 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +761 -0
- package/src/routing/analytics.ts +378 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +145 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +53 -0
- package/src/server/auth-cors.ts +751 -0
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +442 -0
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +1030 -0
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +190 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +152 -0
- package/src/server/image-retry.ts +42 -0
- package/src/server/images.ts +568 -0
- package/src/server/index.ts +1813 -0
- package/src/server/lifecycle.ts +498 -0
- package/src/server/live.ts +717 -0
- 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 +1433 -0
- package/src/server/management/api-access.ts +141 -0
- package/src/server/management/api-key-usage.ts +193 -0
- package/src/server/management/body.ts +41 -0
- package/src/server/management/combo-routes.ts +263 -0
- package/src/server/management/config-routes.ts +835 -0
- package/src/server/management/context.ts +113 -0
- 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 +586 -0
- package/src/server/management/model-routes.ts +560 -0
- package/src/server/management/model-rows.ts +163 -0
- package/src/server/management/native-integration-routes.ts +769 -0
- package/src/server/management/oauth-account-routes.ts +637 -0
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +1033 -0
- package/src/server/management/replit-provider-routes.ts +86 -0
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +385 -0
- package/src/server/management/shared.ts +286 -0
- package/src/server/management/sidebar-routes.ts +106 -0
- 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 +435 -0
- package/src/server/management/system-routes.ts +194 -0
- package/src/server/management/usage-summary-cache.ts +94 -0
- 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 +314 -0
- package/src/server/management-auth.ts +482 -0
- package/src/server/memory-watchdog.ts +156 -0
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +307 -0
- package/src/server/ports.ts +156 -0
- package/src/server/proxy-liveness.ts +328 -0
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +353 -0
- package/src/server/relay.ts +1209 -0
- package/src/server/request-decompress.ts +239 -0
- package/src/server/request-log-conversation.ts +168 -0
- package/src/server/request-log.ts +1259 -0
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/collaboration.ts +551 -0
- package/src/server/responses/compact.ts +771 -0
- package/src/server/responses/core.ts +5389 -0
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +331 -0
- package/src/server/responses/fetch-helpers.ts +232 -0
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +78 -0
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +251 -0
- package/src/server/responses/terminal-guard.ts +251 -0
- package/src/server/responses/upstream-error.ts +53 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-image-gen-repair.ts +132 -0
- package/src/server/responses-item-id-repair.ts +272 -0
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +342 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +153 -0
- package/src/server/responses.ts +25 -0
- package/src/server/search.ts +201 -0
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +263 -0
- package/src/server/startup-action-control.ts +315 -0
- package/src/server/startup-health-cache.ts +131 -0
- package/src/server/system-env.ts +484 -0
- package/src/server/windows-tcp-drop.ts +184 -0
- package/src/server/windows-tray-control.ts +41 -0
- package/src/server/ws-bridge.ts +472 -0
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +3575 -0
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/stall-timeout.ts +20 -0
- package/src/storage/cleanup-job.ts +57 -0
- package/src/storage/cleanup.ts +3085 -0
- package/src/storage/policy-job.ts +457 -0
- package/src/storage/policy-scheduler.ts +40 -0
- package/src/storage/policy-worker.ts +59 -0
- package/src/storage/policy.ts +527 -0
- package/src/storage/restore-job.ts +299 -0
- package/src/storage/restore-worker.ts +58 -0
- package/src/storage/scanner.ts +238 -0
- package/src/storage/storage-mutation-coordinator.ts +139 -0
- package/src/storage/worker-lifecycle.ts +215 -0
- package/src/tray/assets/opencodex-tray-offline.ico +0 -0
- package/src/tray/assets/opencodex-tray-online.ico +0 -0
- package/src/tray/assets/opencodex-tray-warning.ico +0 -0
- package/src/tray/assets/opencodex-tray.png +0 -0
- package/src/tray/windows-tray.ps1 +364 -0
- package/src/tray/windows.ts +757 -0
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +876 -0
- package/src/types/provider.ts +545 -0
- package/src/types/request.ts +384 -0
- package/src/types/tools.ts +131 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +106 -0
- package/src/update/badge.ts +72 -0
- package/src/update/index.ts +415 -0
- package/src/update/job.ts +1887 -0
- package/src/update/notify.ts +263 -0
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/npm-invocation.d.mts +23 -0
- package/src/update/npm-invocation.mjs +94 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/update/tray-update-plan.d.mts +18 -0
- package/src/update/tray-update-plan.mjs +38 -0
- package/src/usage/cost.ts +625 -0
- package/src/usage/debug.ts +97 -0
- package/src/usage/expected-prices.ts +416 -0
- package/src/usage/log.ts +1223 -0
- package/src/usage/summary.ts +753 -0
- package/src/usage/totals.ts +14 -0
- 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 +189 -0
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +131 -0
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +681 -0
- 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 +195 -0
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +113 -0
- package/src/web-search/format-result.ts +89 -0
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +331 -0
- package/src/web-search/loop.ts +896 -0
- package/src/web-search/parse.ts +315 -0
- package/src/web-search/progress-stream.ts +342 -0
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/synthetic-tool.ts +47 -0
- package/src/web-search/xai-executor.ts +219 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getConfigDir,
|
|
3
|
+
reconcileConfigWarningMemos,
|
|
4
|
+
sweepDeadOcxStartProcessCache,
|
|
5
|
+
} from "../config";
|
|
6
|
+
import { reconcileCodexReauthState } from "../codex/account-runtime-state";
|
|
7
|
+
import { reconcileCatalogWarningMemos } from "../codex/catalog/aggregation";
|
|
8
|
+
import { reconcileProviderFetchWarnings } from "../codex/catalog/provider-fetch";
|
|
9
|
+
import { reconcileModelCacheGeneration } from "../codex/model-cache";
|
|
10
|
+
import { reconcilePoolRotationState } from "../codex/pool-rotation";
|
|
11
|
+
import { reconcileCodexQuotaAccounts } from "../codex/quota";
|
|
12
|
+
import {
|
|
13
|
+
listLiveCodexAccountIds,
|
|
14
|
+
reconcileCodexRoutingHealth,
|
|
15
|
+
} from "../codex/routing";
|
|
16
|
+
import { sweepExpiredSubagentModelHealth } from "../codex/subagent-model-fallback";
|
|
17
|
+
import {
|
|
18
|
+
reconcileComboTargetCooldowns,
|
|
19
|
+
sweepExpiredComboTargetCooldowns,
|
|
20
|
+
} from "../combos/failover";
|
|
21
|
+
import { reconcileComboWarningMemos } from "../combos/request";
|
|
22
|
+
import { reconcileComboRotationState } from "../combos/resolve";
|
|
23
|
+
import { listLiveComboTargetKeys } from "../combos/types";
|
|
24
|
+
import {
|
|
25
|
+
listLiveConfigOwnershipRoots,
|
|
26
|
+
reconcileConfigOwnershipRoots,
|
|
27
|
+
} from "./config-ownership";
|
|
28
|
+
import { reconcileGcpAdcTokens, sweepExpiredGcpAdcTokens } from "./gcp-adc";
|
|
29
|
+
import {
|
|
30
|
+
reconcileOAuthFlowState,
|
|
31
|
+
sweepExpiredXaiPermanentFailureVerdicts,
|
|
32
|
+
} from "../oauth";
|
|
33
|
+
import { sweepExpiredAnthropicRoutingHealth } from "../oauth/anthropic-routing";
|
|
34
|
+
import { sweepExpiredAntigravityRoutingHealth } from "../oauth/antigravity-routing";
|
|
35
|
+
import { listLiveOAuthAccountKeys, reconcileOAuthReauthState } from "../oauth/store";
|
|
36
|
+
import { reconcileGuardianBackoff } from "../oauth/token-guardian";
|
|
37
|
+
import { sweepExpiredApiKeyCooldowns } from "../providers/key-failover";
|
|
38
|
+
import { reconcileProviderRequestPacing } from "../providers/request-pacing";
|
|
39
|
+
import { sweepAbandonedResponseStateTemps, sweepExpiredResponseStates } from "../responses/state";
|
|
40
|
+
import { sweepExpiredAntigravityReplay } from "../adapters/google-antigravity-replay";
|
|
41
|
+
import { reconcileProviderAccountQuotaRows } from "../providers/quota";
|
|
42
|
+
import { reconcileRouterWarningMemos } from "../router";
|
|
43
|
+
import type { OcxConfig } from "../types";
|
|
44
|
+
import {
|
|
45
|
+
type GenerationContext,
|
|
46
|
+
reconcileStateGeneration,
|
|
47
|
+
registerStateStore,
|
|
48
|
+
setGenerationContextBuilder,
|
|
49
|
+
type StateStoreRegistration,
|
|
50
|
+
} from "./state-store-sweeper";
|
|
51
|
+
|
|
52
|
+
let liveServerConfig: OcxConfig | null = null;
|
|
53
|
+
|
|
54
|
+
export function setLiveStateStoreConfig(config: OcxConfig): void {
|
|
55
|
+
liveServerConfig = config;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function reconcileLiveStateStores() {
|
|
59
|
+
if (!liveServerConfig) return { storesVisited: 0, rowsRemoved: 0 };
|
|
60
|
+
return reconcileStateGeneration(buildGenerationContext());
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function buildGenerationContext(): GenerationContext {
|
|
64
|
+
if (!liveServerConfig) throw new Error("live server config is not installed");
|
|
65
|
+
const providerNames = new Set(Object.keys(liveServerConfig.providers));
|
|
66
|
+
return {
|
|
67
|
+
generation: 0,
|
|
68
|
+
providerNames,
|
|
69
|
+
comboIds: new Set(Object.keys(liveServerConfig.combos ?? {})),
|
|
70
|
+
comboTargets: listLiveComboTargetKeys(liveServerConfig),
|
|
71
|
+
codexAccountIds: listLiveCodexAccountIds(liveServerConfig),
|
|
72
|
+
oauthAccountKeys: listLiveOAuthAccountKeys(providerNames),
|
|
73
|
+
configRoots: listLiveConfigOwnershipRoots(getConfigDir()),
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export const STATE_STORE_REGISTRATIONS = [
|
|
78
|
+
{ name: "subagent-model-health", sweepExpired: sweepExpiredSubagentModelHealth },
|
|
79
|
+
{ name: "api-key-cooldowns", sweepExpired: sweepExpiredApiKeyCooldowns },
|
|
80
|
+
{ name: "provider-request-pacing", reconcileGeneration: reconcileProviderRequestPacing },
|
|
81
|
+
{
|
|
82
|
+
name: "combo-target-cooldowns",
|
|
83
|
+
sweepExpired: sweepExpiredComboTargetCooldowns,
|
|
84
|
+
reconcileGeneration: reconcileComboTargetCooldowns,
|
|
85
|
+
},
|
|
86
|
+
{ name: "anthropic-routing-health", sweepExpired: sweepExpiredAnthropicRoutingHealth },
|
|
87
|
+
{ name: "antigravity-routing-health", sweepExpired: sweepExpiredAntigravityRoutingHealth },
|
|
88
|
+
{ name: "xai-refresh-verdicts", sweepExpired: sweepExpiredXaiPermanentFailureVerdicts },
|
|
89
|
+
{
|
|
90
|
+
name: "responses-continuation",
|
|
91
|
+
sweepExpired: sweepExpiredResponseStates,
|
|
92
|
+
// Disk reclaim rides the liveness tick, not the TTL tick: sweepExpiredOnWrite puts
|
|
93
|
+
// sweepExpired on hot write paths, where a directory scan does not belong.
|
|
94
|
+
sweepLiveness: sweepAbandonedResponseStateTemps,
|
|
95
|
+
},
|
|
96
|
+
{ name: "antigravity-replay", sweepExpired: sweepExpiredAntigravityReplay },
|
|
97
|
+
{ name: "config-warning-memos", reconcileGeneration: (context: GenerationContext) => reconcileConfigWarningMemos(context.generation) },
|
|
98
|
+
{ name: "catalog-warning-memos", reconcileGeneration: (context: GenerationContext) => reconcileCatalogWarningMemos(context.generation) },
|
|
99
|
+
{ name: "provider-fetch-warning-memos", reconcileGeneration: (context: GenerationContext) => reconcileProviderFetchWarnings(context.generation) },
|
|
100
|
+
{ name: "combo-warning-memos", reconcileGeneration: (context: GenerationContext) => reconcileComboWarningMemos(context.generation) },
|
|
101
|
+
{ name: "router-warning-memos", reconcileGeneration: (context: GenerationContext) => reconcileRouterWarningMemos(context.generation) },
|
|
102
|
+
{ name: "codex-quota", reconcileGeneration: reconcileCodexQuotaAccounts },
|
|
103
|
+
{ name: "provider-quota-history", reconcileGeneration: reconcileProviderAccountQuotaRows },
|
|
104
|
+
{ name: "codex-routing-health", reconcileGeneration: reconcileCodexRoutingHealth },
|
|
105
|
+
{ name: "model-cache-history", reconcileGeneration: reconcileModelCacheGeneration },
|
|
106
|
+
{ name: "pool-rotation", reconcileGeneration: reconcilePoolRotationState },
|
|
107
|
+
{ name: "combo-rotation", reconcileGeneration: reconcileComboRotationState },
|
|
108
|
+
{ name: "guardian-backoff", reconcileGeneration: reconcileGuardianBackoff },
|
|
109
|
+
{ name: "codex-reauth", reconcileGeneration: reconcileCodexReauthState },
|
|
110
|
+
{ name: "oauth-reauth", reconcileGeneration: reconcileOAuthReauthState },
|
|
111
|
+
{ name: "gcp-adc", sweepExpired: sweepExpiredGcpAdcTokens, reconcileGeneration: reconcileGcpAdcTokens },
|
|
112
|
+
{ name: "config-ownership", reconcileGeneration: reconcileConfigOwnershipRoots },
|
|
113
|
+
{ name: "oauth-flow-state", reconcileGeneration: reconcileOAuthFlowState },
|
|
114
|
+
{ name: "ocx-start-process-cache", sweepLiveness: sweepDeadOcxStartProcessCache },
|
|
115
|
+
] satisfies readonly StateStoreRegistration[];
|
|
116
|
+
|
|
117
|
+
for (const registration of STATE_STORE_REGISTRATIONS) registerStateStore(registration);
|
|
118
|
+
|
|
119
|
+
setGenerationContextBuilder(buildGenerationContext);
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
export const STATE_SWEEP_INTERVAL_MS = 60_000;
|
|
2
|
+
|
|
3
|
+
export interface GenerationContext {
|
|
4
|
+
generation: number;
|
|
5
|
+
providerNames: ReadonlySet<string>;
|
|
6
|
+
comboIds: ReadonlySet<string>;
|
|
7
|
+
comboTargets: ReadonlySet<string>;
|
|
8
|
+
codexAccountIds: ReadonlySet<string>;
|
|
9
|
+
oauthAccountKeys: ReadonlySet<string>;
|
|
10
|
+
configRoots: ReadonlySet<string>;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface StateStoreRegistration {
|
|
14
|
+
name: string;
|
|
15
|
+
sweepExpired?: (now: number) => number;
|
|
16
|
+
sweepLiveness?: () => number;
|
|
17
|
+
reconcileGeneration?: (context: GenerationContext) => number;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface StateSweepAfterTickRegistration {
|
|
21
|
+
name: string;
|
|
22
|
+
afterTick(): void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface StateSweepResult {
|
|
26
|
+
storesVisited: number;
|
|
27
|
+
rowsRemoved: number;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface StateStoreSweeperOptions {
|
|
31
|
+
/** Override the 60 s interval (tests only; production uses the default). */
|
|
32
|
+
intervalMs?: number;
|
|
33
|
+
/** Injectable clock for tests. */
|
|
34
|
+
now?: () => number;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const registrations = new Map<string, StateStoreRegistration>();
|
|
38
|
+
const afterTickRegistrations = new Map<string, StateSweepAfterTickRegistration>();
|
|
39
|
+
let configGeneration = 0;
|
|
40
|
+
let attemptSequence = 0;
|
|
41
|
+
let generationContextBuilder: (() => GenerationContext) | null = null;
|
|
42
|
+
let reconciliationRetryPending = false;
|
|
43
|
+
let interval: ReturnType<typeof setInterval> | null = null;
|
|
44
|
+
|
|
45
|
+
function logCallbackFailure(name: string): void {
|
|
46
|
+
console.warn(`[state-store-sweeper] ${name} failed`);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function registerStateStore(registration: StateStoreRegistration): () => void {
|
|
50
|
+
registrations.set(registration.name, registration);
|
|
51
|
+
return () => {
|
|
52
|
+
if (registrations.get(registration.name) === registration) {
|
|
53
|
+
registrations.delete(registration.name);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function registerStateSweepAfterTick(registration: StateSweepAfterTickRegistration): () => void {
|
|
59
|
+
afterTickRegistrations.set(registration.name, registration);
|
|
60
|
+
return () => {
|
|
61
|
+
if (afterTickRegistrations.get(registration.name) === registration) {
|
|
62
|
+
afterTickRegistrations.delete(registration.name);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function runCallbacks(
|
|
68
|
+
callback: (registration: StateStoreRegistration) => (() => number) | undefined,
|
|
69
|
+
): StateSweepResult {
|
|
70
|
+
let storesVisited = 0;
|
|
71
|
+
let rowsRemoved = 0;
|
|
72
|
+
for (const registration of registrations.values()) {
|
|
73
|
+
const invoke = callback(registration);
|
|
74
|
+
if (!invoke) continue;
|
|
75
|
+
storesVisited += 1;
|
|
76
|
+
try {
|
|
77
|
+
rowsRemoved += invoke();
|
|
78
|
+
} catch {
|
|
79
|
+
logCallbackFailure(registration.name);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return { storesVisited, rowsRemoved };
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function sweepExpired(now = Date.now()): StateSweepResult {
|
|
86
|
+
return runCallbacks(registration => registration.sweepExpired
|
|
87
|
+
? () => registration.sweepExpired!(now)
|
|
88
|
+
: undefined);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function sweepExpiredOnWrite(now = Date.now()): StateSweepResult {
|
|
92
|
+
const result = sweepExpired(now);
|
|
93
|
+
if (reconciliationRetryPending && generationContextBuilder) {
|
|
94
|
+
try {
|
|
95
|
+
reconcileStateGeneration(generationContextBuilder());
|
|
96
|
+
} catch {
|
|
97
|
+
// The builder reads authoritative live owners. Keep the single retry pending
|
|
98
|
+
// until a later successful owner write can obtain a complete context.
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function sweepLiveness(): StateSweepResult {
|
|
105
|
+
return runCallbacks(registration => registration.sweepLiveness);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function runAfterTickCallbacks(): void {
|
|
109
|
+
for (const registration of afterTickRegistrations.values()) {
|
|
110
|
+
try {
|
|
111
|
+
registration.afterTick();
|
|
112
|
+
} catch {
|
|
113
|
+
logCallbackFailure(registration.name);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function captureConfigGeneration(): number {
|
|
119
|
+
return configGeneration;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function setGenerationContextBuilder(build: () => GenerationContext): void {
|
|
123
|
+
generationContextBuilder = build;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function reconcileStateGeneration(context: GenerationContext): StateSweepResult {
|
|
127
|
+
const candidateGeneration = ++attemptSequence;
|
|
128
|
+
const candidateContext: GenerationContext = {
|
|
129
|
+
...context,
|
|
130
|
+
generation: candidateGeneration,
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
let storesVisited = 0;
|
|
134
|
+
let rowsRemoved = 0;
|
|
135
|
+
let failed = false;
|
|
136
|
+
for (const registration of registrations.values()) {
|
|
137
|
+
if (!registration.reconcileGeneration) continue;
|
|
138
|
+
storesVisited += 1;
|
|
139
|
+
try {
|
|
140
|
+
rowsRemoved += registration.reconcileGeneration(candidateContext);
|
|
141
|
+
} catch {
|
|
142
|
+
failed = true;
|
|
143
|
+
logCallbackFailure(registration.name);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (failed) {
|
|
147
|
+
reconciliationRetryPending = true;
|
|
148
|
+
} else {
|
|
149
|
+
configGeneration = candidateGeneration;
|
|
150
|
+
reconciliationRetryPending = false;
|
|
151
|
+
}
|
|
152
|
+
return { storesVisited, rowsRemoved };
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export function startStateStoreSweeper(
|
|
156
|
+
options: StateStoreSweeperOptions = {},
|
|
157
|
+
): { stop(): void } {
|
|
158
|
+
stopStateStoreSweeper();
|
|
159
|
+
const now = options.now ?? Date.now;
|
|
160
|
+
interval = setInterval(() => {
|
|
161
|
+
sweepExpired(now());
|
|
162
|
+
sweepLiveness();
|
|
163
|
+
runAfterTickCallbacks();
|
|
164
|
+
}, options.intervalMs ?? STATE_SWEEP_INTERVAL_MS);
|
|
165
|
+
interval.unref?.();
|
|
166
|
+
return { stop: stopStateStoreSweeper };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export function stopStateStoreSweeper(): void {
|
|
170
|
+
if (!interval) return;
|
|
171
|
+
clearInterval(interval);
|
|
172
|
+
interval = null;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** Test-only reset for module-global registrations, generation, and lifecycle state. */
|
|
176
|
+
export function resetStateStoreSweeperForTests(): void {
|
|
177
|
+
stopStateStoreSweeper();
|
|
178
|
+
registrations.clear();
|
|
179
|
+
afterTickRegistrations.clear();
|
|
180
|
+
configGeneration = 0;
|
|
181
|
+
attemptSequence = 0;
|
|
182
|
+
generationContextBuilder = null;
|
|
183
|
+
reconciliationRetryPending = false;
|
|
184
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { isLocalAttestationSecret } from "./local-management-attestation";
|
|
3
|
+
|
|
4
|
+
export const SYSTEM_RESTART_METHOD = "POST";
|
|
5
|
+
export const SYSTEM_RESTART_PATH = "/api/system/restart";
|
|
6
|
+
export const SYSTEM_RESTART_CAPABILITY_VERSION = "v1";
|
|
7
|
+
export const SYSTEM_RESTART_EXPECTED_PID_HEADER = "x-opencodex-restart-expected-pid";
|
|
8
|
+
export const SYSTEM_RESTART_NONCE_HEADER = "x-opencodex-restart-nonce";
|
|
9
|
+
export const SYSTEM_RESTART_CAPABILITY_HEADER = "x-opencodex-restart-capability";
|
|
10
|
+
|
|
11
|
+
/** Fixed drain and replacement budgets shared by the server, CLI, and tray. */
|
|
12
|
+
export const MEMORY_DRAIN_RESTART_MS = 60_000;
|
|
13
|
+
export const REPLACEMENT_READY_TIMEOUT_MS = 70_000;
|
|
14
|
+
|
|
15
|
+
const BASE64URL_256 = /^[A-Za-z0-9_-]{43}$/;
|
|
16
|
+
|
|
17
|
+
export type ExpectedSystemRestartPid =
|
|
18
|
+
| { kind: "absent" }
|
|
19
|
+
| { kind: "invalid" }
|
|
20
|
+
| { kind: "present"; pid: number };
|
|
21
|
+
|
|
22
|
+
export function parseExpectedSystemRestartPid(value: string | null): ExpectedSystemRestartPid {
|
|
23
|
+
if (value === null) return { kind: "absent" };
|
|
24
|
+
if (!/^[1-9]\d*$/.test(value)) return { kind: "invalid" };
|
|
25
|
+
const pid = Number(value);
|
|
26
|
+
return Number.isSafeInteger(pid) ? { kind: "present", pid } : { kind: "invalid" };
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function restartCapabilityPayload(
|
|
30
|
+
nonce: string,
|
|
31
|
+
method: string,
|
|
32
|
+
path: string,
|
|
33
|
+
pid: number,
|
|
34
|
+
port: number,
|
|
35
|
+
): string | null {
|
|
36
|
+
if (!BASE64URL_256.test(nonce)) return null;
|
|
37
|
+
if (method !== SYSTEM_RESTART_METHOD || path !== SYSTEM_RESTART_PATH) return null;
|
|
38
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return null;
|
|
39
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535) return null;
|
|
40
|
+
return `opencodex-system-restart-v1\n${nonce}\n${method}\n${path}\n${pid}\n${port}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** Process-scoped, operation-only authorization. It is not a reusable management credential. */
|
|
44
|
+
export function createSystemRestartCapability(
|
|
45
|
+
secret: string,
|
|
46
|
+
nonce: string,
|
|
47
|
+
method: string,
|
|
48
|
+
path: string,
|
|
49
|
+
pid: number,
|
|
50
|
+
port: number,
|
|
51
|
+
): string | null {
|
|
52
|
+
if (!isLocalAttestationSecret(secret)) return null;
|
|
53
|
+
const payload = restartCapabilityPayload(nonce, method, path, pid, port);
|
|
54
|
+
if (!payload) return null;
|
|
55
|
+
return createHmac("sha256", secret).update(payload).digest("base64url");
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function verifySystemRestartCapability(
|
|
59
|
+
secret: string,
|
|
60
|
+
nonce: string | null,
|
|
61
|
+
method: string,
|
|
62
|
+
path: string,
|
|
63
|
+
pid: number,
|
|
64
|
+
port: number,
|
|
65
|
+
capability: string | null,
|
|
66
|
+
): boolean {
|
|
67
|
+
if (!nonce || !capability || !BASE64URL_256.test(capability)) return false;
|
|
68
|
+
const expected = createSystemRestartCapability(secret, nonce, method, path, pid, port);
|
|
69
|
+
if (!expected) return false;
|
|
70
|
+
const expectedBytes = Buffer.from(expected);
|
|
71
|
+
const actualBytes = Buffer.from(capability);
|
|
72
|
+
return expectedBytes.length === actualBytes.length && timingSafeEqual(expectedBytes, actualBytes);
|
|
73
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fail-closed protection for the user's REAL OpenCodex home while tests run.
|
|
3
|
+
*
|
|
4
|
+
* A management-route unit test once passed an in-memory fixture config to a handler
|
|
5
|
+
* that persisted it through the process-global writer, replacing a live 41KB,
|
|
6
|
+
* ten-provider `~/.opencodex/config.json` with an 874-byte fixture on a real machine.
|
|
7
|
+
* Credentials survived only because the store files are separate; the providers were
|
|
8
|
+
* recoverable only because an unrelated backup snapshot happened to exist.
|
|
9
|
+
* (devlog `_plan/260730_codex_rs_upstream_v2_live_handoff/070`.)
|
|
10
|
+
*
|
|
11
|
+
* Two properties matter more than breadth here:
|
|
12
|
+
*
|
|
13
|
+
* 1. It must be INERT in production. Guessing "am I a test?" from ecosystem variables
|
|
14
|
+
* like NODE_ENV would brick `NODE_ENV=test ocx ...` for a user who did nothing
|
|
15
|
+
* wrong — worse than the bug it prevents. Arming requires OCX_TEST_HOME_GUARD=1,
|
|
16
|
+
* which only this repository's test preload sets.
|
|
17
|
+
* 2. It must fail CLOSED for code nobody has written yet. So it denies ONE path — the
|
|
18
|
+
* captured production home — instead of allow-listing known-good test directories.
|
|
19
|
+
* An allowlist would have to be opted into, and the test that forgets is exactly
|
|
20
|
+
* how this incident happened.
|
|
21
|
+
*/
|
|
22
|
+
import { homedir } from "node:os";
|
|
23
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
24
|
+
import { realpathSync } from "node:fs";
|
|
25
|
+
|
|
26
|
+
const GUARD_ENV = "OCX_TEST_HOME_GUARD";
|
|
27
|
+
/**
|
|
28
|
+
* Set by `scripts/test.ts` to the ORIGINAL home before it hands the child a rewritten
|
|
29
|
+
* HOME. On that path `homedir()` already points at the sandbox by the time this module
|
|
30
|
+
* loads, so the true home is only knowable from this hand-off.
|
|
31
|
+
*/
|
|
32
|
+
const REAL_HOME_ENV = "OCX_REAL_HOME";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Resolve symlinks so two spellings of one location compare equal — macOS hands out
|
|
36
|
+
* `/var/folders/...` whose realpath is `/private/var/folders/...` — and so a path that
|
|
37
|
+
* merely *points* at the protected home cannot slip past a string comparison. A path
|
|
38
|
+
* that does not exist yet canonicalizes through its nearest existing ancestor, which is
|
|
39
|
+
* the common case for a config file about to be created.
|
|
40
|
+
*/
|
|
41
|
+
function canonicalize(path: string): string {
|
|
42
|
+
let current = resolve(path);
|
|
43
|
+
const unresolved: string[] = [];
|
|
44
|
+
for (;;) {
|
|
45
|
+
try {
|
|
46
|
+
return join(realpathSync.native(current), ...unresolved.reverse());
|
|
47
|
+
} catch {
|
|
48
|
+
const parent = dirname(current);
|
|
49
|
+
if (parent === current) return resolve(path);
|
|
50
|
+
unresolved.push(current.slice(parent.length + 1));
|
|
51
|
+
current = parent;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Captured ONCE at module load, before any harness replaces HOME/USERPROFILE. Reading
|
|
58
|
+
* `homedir()` later would return the sandbox and leave the real home unprotected — the
|
|
59
|
+
* guard would be perfectly inverted while its tests still looked green.
|
|
60
|
+
*/
|
|
61
|
+
const PROTECTED_HOME = canonicalize(
|
|
62
|
+
join(process.env[REAL_HOME_ENV]?.trim() || homedir(), ".opencodex"),
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
/** The production home this process protects. Exported for the guard's own tests. */
|
|
66
|
+
export function protectedHomeForTests(): string {
|
|
67
|
+
return PROTECTED_HOME;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function isTestHomeGuardArmed(): boolean {
|
|
71
|
+
return process.env[GUARD_ENV] === "1";
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Throw when an armed test process is about to write the real OpenCodex home.
|
|
76
|
+
*
|
|
77
|
+
* Call FIRST inside a writer, before any mkdir/chmod/write, so a rejected write leaves
|
|
78
|
+
* nothing behind. Silent no-op when disarmed (production) or when `dir` is any other
|
|
79
|
+
* location, including a suite's own `mkdtemp` fixture — no registration required, which
|
|
80
|
+
* is what keeps the 54 existing suites that write config working untouched.
|
|
81
|
+
*/
|
|
82
|
+
export function assertNotRealHomeUnderTest(dir: string): void {
|
|
83
|
+
if (!isTestHomeGuardArmed()) return;
|
|
84
|
+
if (canonicalize(dir) !== PROTECTED_HOME) return;
|
|
85
|
+
throw new Error(
|
|
86
|
+
`refusing to write the real OpenCodex home (${PROTECTED_HOME}) from a test process. `
|
|
87
|
+
+ "Point OPENCODEX_HOME at a temp directory for this test, or inject persistence "
|
|
88
|
+
+ "instead of calling the global writer (see devlog 260730_codex_rs_upstream_v2_live_handoff/070).",
|
|
89
|
+
);
|
|
90
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Heuristic token-estimation sidecar.
|
|
3
|
+
*
|
|
4
|
+
* Some providers (notably kiro / CodeWhisperer) return no token usage in their stream, so Codex's
|
|
5
|
+
* usage display and auto-compact (which read response.completed.usage) never engage. This module
|
|
6
|
+
* provides a cheap, dependency-free char-based estimate to fill that gap.
|
|
7
|
+
*
|
|
8
|
+
* Grounding (web): 1 token ~= 4 chars for English prose; empirical model ratios are ~Claude 3.5,
|
|
9
|
+
* ~GPT 3.6, ~Gemini 3.8 chars/token (within ~10%). Code / JSON / tool-args (the dominant Codex
|
|
10
|
+
* traffic) pack MORE tokens per char, so a lower chars-per-token ratio is used for those models.
|
|
11
|
+
* Over-counting fails safe (auto-compact fires earlier); under-counting risks context overflow.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/** Generic English-prose fallback ratio (chars per token). */
|
|
15
|
+
const DEFAULT_CHARS_PER_TOKEN = 4;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Kiro routes code/JSON-heavy agent traffic whose true ratio is ~3.0-3.3 chars/token. 3.5 keeps a
|
|
19
|
+
* small safety margin (slight over-count) without wildly inflating; tune toward 3.3 if overflow is
|
|
20
|
+
* ever observed. All kiro models are text LLMs, so a single ratio applies to the whole family.
|
|
21
|
+
*/
|
|
22
|
+
const KIRO_CHARS_PER_TOKEN = 3.5;
|
|
23
|
+
|
|
24
|
+
const KIRO_MODEL_PREFIXES = ["kiro", "claude", "deepseek", "minimax", "glm", "qwen"];
|
|
25
|
+
|
|
26
|
+
/** Model-aware chars-per-token ratio. Unknown models fall back to the generic English ratio. */
|
|
27
|
+
export function charsPerToken(modelId?: string): number {
|
|
28
|
+
if (!modelId) return DEFAULT_CHARS_PER_TOKEN;
|
|
29
|
+
const id = modelId.toLowerCase();
|
|
30
|
+
if (KIRO_MODEL_PREFIXES.some(p => id.startsWith(p))) return KIRO_CHARS_PER_TOKEN;
|
|
31
|
+
return DEFAULT_CHARS_PER_TOKEN;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* CJK-aware ratio (devlog 260712 B3, audit R2#7): Korean/Chinese/Japanese text packs
|
|
36
|
+
* roughly one token per 1.5-3 chars, so a CJK-heavy blob estimated at English ratios
|
|
37
|
+
* badly undercounts. When >30% of chars are CJK, clamp DOWN to 2.5 chars/token —
|
|
38
|
+
* `min(model ratio, 2.5)` so per-model ratios (Claude 3.5, Kiro family) never rise.
|
|
39
|
+
*/
|
|
40
|
+
const CJK_CHARS_PER_TOKEN = 2.5;
|
|
41
|
+
const CJK_RATIO_THRESHOLD = 0.3;
|
|
42
|
+
// Hangul syllables/jamo, CJK unified ideographs (+ext A), hiragana/katakana.
|
|
43
|
+
const CJK_RE = /[\uAC00-\uD7A3\u1100-\u11FF\u3130-\u318F\u4E00-\u9FFF\u3400-\u4DBF\u3040-\u30FF]/;
|
|
44
|
+
|
|
45
|
+
function cjkRatio(text: string): number {
|
|
46
|
+
if (text.length === 0) return 0;
|
|
47
|
+
// Sample long blobs for O(1) cost: every char up to 2k, then a stride.
|
|
48
|
+
const stride = text.length > 2048 ? Math.ceil(text.length / 2048) : 1;
|
|
49
|
+
let cjk = 0;
|
|
50
|
+
let sampled = 0;
|
|
51
|
+
for (let i = 0; i < text.length; i += stride) {
|
|
52
|
+
sampled++;
|
|
53
|
+
if (CJK_RE.test(text[i]!)) cjk++;
|
|
54
|
+
}
|
|
55
|
+
return sampled === 0 ? 0 : cjk / sampled;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Cap an estimated token count at a model's context window (codex-router PR #140).
|
|
60
|
+
*
|
|
61
|
+
* A request the provider answered cannot have exceeded the window, so the estimate is never
|
|
62
|
+
* allowed to claim it did: the estimate only ever substitutes a reported-zero (or missing)
|
|
63
|
+
* input count, and a value above the window would be provably false. Positive or missing
|
|
64
|
+
* reported counts are never rewritten here — this bounds the heuristic estimate itself.
|
|
65
|
+
* Non-positive or non-integer windows (unknown model) leave the estimate untouched.
|
|
66
|
+
*/
|
|
67
|
+
export function capEstimateAtContextWindow(estimate: number, contextWindow: number | undefined): number {
|
|
68
|
+
return typeof contextWindow === "number" && Number.isInteger(contextWindow) && contextWindow > 0
|
|
69
|
+
? Math.min(estimate, contextWindow)
|
|
70
|
+
: estimate;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Estimate the token count of a text blob. Pure and deterministic.
|
|
75
|
+
* Returns 0 for empty/whitespace-free-empty input; otherwise ceil(length / ratio), min 1.
|
|
76
|
+
* When `contextWindow` is a positive integer the estimate is capped at it: a request the
|
|
77
|
+
* provider answered cannot have exceeded the window, so the estimate must not claim it did.
|
|
78
|
+
*/
|
|
79
|
+
export function estimateTokens(text: string, modelId?: string, contextWindow?: number): number {
|
|
80
|
+
if (!text) return 0;
|
|
81
|
+
const len = text.length;
|
|
82
|
+
if (len === 0) return 0;
|
|
83
|
+
let ratio = charsPerToken(modelId);
|
|
84
|
+
if (cjkRatio(text) > CJK_RATIO_THRESHOLD) ratio = Math.min(ratio, CJK_CHARS_PER_TOKEN);
|
|
85
|
+
return capEstimateAtContextWindow(Math.max(1, Math.ceil(len / ratio)), contextWindow);
|
|
86
|
+
}
|