@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,9 @@
|
|
|
1
|
+
/** Classify SQLite lock contention consistently across Log Guard mutation paths. */
|
|
2
|
+
export function isSqliteBusy(error: unknown): boolean {
|
|
3
|
+
const code = error && typeof error === "object" && "code" in error
|
|
4
|
+
? String((error as { code?: unknown }).code)
|
|
5
|
+
: "";
|
|
6
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
7
|
+
return code === "SQLITE_BUSY" || code === "SQLITE_LOCKED"
|
|
8
|
+
|| /database (?:is|table is) locked/i.test(message);
|
|
9
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import type { StoredAccountQuota } from "./quota";
|
|
2
|
+
import { truncateRetainedUtf8 } from "../lib/admission";
|
|
3
|
+
|
|
4
|
+
const MAX_DIAGNOSTIC_VALUE_BYTES = 8 * 1024;
|
|
5
|
+
|
|
6
|
+
export interface MainAccountInfo {
|
|
7
|
+
email: string | null;
|
|
8
|
+
plan: string | null;
|
|
9
|
+
quota: Omit<StoredAccountQuota, "updatedAt"> | null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface CachedMainAccountInfo extends MainAccountInfo {
|
|
13
|
+
ts: number;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let cachedMainAccountInfo: CachedMainAccountInfo | null = null;
|
|
17
|
+
let cachedMainCredentialPresence: boolean | null = null;
|
|
18
|
+
let mainAccountIdentityGeneration = 0;
|
|
19
|
+
|
|
20
|
+
export function captureMainAccountIdentityGeneration(): number {
|
|
21
|
+
return mainAccountIdentityGeneration;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function isMainAccountIdentityGenerationLive(generation: number): boolean {
|
|
25
|
+
return generation === mainAccountIdentityGeneration;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function getMainAccountInfoCache(): CachedMainAccountInfo | null {
|
|
29
|
+
return cachedMainAccountInfo;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function setMainAccountInfoCache(value: CachedMainAccountInfo): void {
|
|
33
|
+
cachedMainAccountInfo = {
|
|
34
|
+
...value,
|
|
35
|
+
email: value.email === null ? null : truncateRetainedUtf8(value.email, MAX_DIAGNOSTIC_VALUE_BYTES),
|
|
36
|
+
plan: value.plan === null ? null : truncateRetainedUtf8(value.plan, MAX_DIAGNOSTIC_VALUE_BYTES),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function clearMainAccountInfoCache(): void {
|
|
41
|
+
cachedMainAccountInfo = null;
|
|
42
|
+
mainAccountIdentityGeneration += 1;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** Last physical credential presence observed while native-main ownership was held. */
|
|
46
|
+
export function getMainAccountCredentialPresence(): boolean | null {
|
|
47
|
+
return cachedMainCredentialPresence;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function setMainAccountCredentialPresence(present: boolean): void {
|
|
51
|
+
cachedMainCredentialPresence = present;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function clearMainAccountCredentialPresence(): void {
|
|
55
|
+
cachedMainCredentialPresence = null;
|
|
56
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { readCodexTokens } from "./auth-collision";
|
|
2
|
+
import { decodeJwtPayload } from "../oauth/chatgpt";
|
|
3
|
+
import { extractChatgptPlanType } from "./plan";
|
|
4
|
+
import { MAIN_CODEX_ACCOUNT_ID } from "./account-id";
|
|
5
|
+
|
|
6
|
+
export { MAIN_CODEX_ACCOUNT_ID } from "./account-id";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Main account plan (e.g. "plus", "go", "free", "team"), populated from the WHAM usage
|
|
10
|
+
* fetch. Used by the rotation usage-score so go/free main accounts score on monthly
|
|
11
|
+
* percent, matching pool-account behavior.
|
|
12
|
+
*/
|
|
13
|
+
let mainAccountPlan: string | null = null;
|
|
14
|
+
let jwtPlanAttempted = false;
|
|
15
|
+
|
|
16
|
+
export function setMainAccountPlan(plan: string | null): void {
|
|
17
|
+
mainAccountPlan = plan;
|
|
18
|
+
if (plan === null) jwtPlanAttempted = false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function getMainAccountPlan(): string | undefined {
|
|
22
|
+
if (mainAccountPlan) return mainAccountPlan;
|
|
23
|
+
if (jwtPlanAttempted) return undefined;
|
|
24
|
+
jwtPlanAttempted = true;
|
|
25
|
+
const tokens = readCodexTokens();
|
|
26
|
+
const jwtPlan = tokens
|
|
27
|
+
? extractChatgptPlanType(tokens.id_token, tokens.access_token)
|
|
28
|
+
: undefined;
|
|
29
|
+
if (jwtPlan) mainAccountPlan = jwtPlan;
|
|
30
|
+
return jwtPlan;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** Read-only main account token from ~/.codex/auth.json, or null when not logged in. */
|
|
34
|
+
export function getMainAccountToken(): { accessToken: string; chatgptAccountId: string } | null {
|
|
35
|
+
const tokens = readCodexTokens();
|
|
36
|
+
if (!tokens?.access_token) return null;
|
|
37
|
+
return { accessToken: tokens.access_token, chatgptAccountId: tokens.account_id };
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The main token is usable when it exists and — if its JWT carries a decodable `exp` — is
|
|
42
|
+
* not expired. When `exp` cannot be decoded we treat the token as live (best-effort); an
|
|
43
|
+
* actually-invalid token then surfaces via the upstream 401 → cooldown path.
|
|
44
|
+
*/
|
|
45
|
+
export function isMainAccountTokenLive(now = Date.now()): boolean {
|
|
46
|
+
const tokens = readCodexTokens();
|
|
47
|
+
if (!tokens?.access_token) return false;
|
|
48
|
+
const payload = decodeJwtPayload(tokens.access_token);
|
|
49
|
+
const exp = typeof payload?.exp === "number" ? payload.exp * 1000 : undefined;
|
|
50
|
+
return exp === undefined || exp > now;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Strict liveness for auth-terminality decisions: true only when the access-token JWT
|
|
55
|
+
* carries a decodable `exp` that is still in the future.
|
|
56
|
+
*
|
|
57
|
+
* Unlike {@link isMainAccountTokenLive}, an undecodable `exp` counts as NOT live here.
|
|
58
|
+
* This gate decides whether a bare WHAM 401 is downgraded to a transient failure; if an
|
|
59
|
+
* undecodable token could vouch for itself, a genuinely dead credential would keep every
|
|
60
|
+
* 401 "transient" and needsReauth could never flip.
|
|
61
|
+
*/
|
|
62
|
+
export function isMainAccountTokenVerifiablyLive(now = Date.now()): boolean {
|
|
63
|
+
const tokens = readCodexTokens();
|
|
64
|
+
if (!tokens?.access_token) return false;
|
|
65
|
+
const payload = decodeJwtPayload(tokens.access_token);
|
|
66
|
+
const exp = typeof payload?.exp === "number" ? payload.exp * 1000 : undefined;
|
|
67
|
+
return exp !== undefined && exp > now;
|
|
68
|
+
}
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
import type { OcxConfig } from "../types";
|
|
2
|
+
import { captureCatalogAdmissionSnapshot } from "./catalog-admission";
|
|
3
|
+
import { convergeCodexCatalog } from "./convergence";
|
|
4
|
+
import type {
|
|
5
|
+
CatalogDisposition,
|
|
6
|
+
CatalogFailureCause,
|
|
7
|
+
CatalogOnlyOutcome,
|
|
8
|
+
CodexHistoryState,
|
|
9
|
+
CodexObservedState,
|
|
10
|
+
ConvergeCodex,
|
|
11
|
+
ProjectCatalogOnlyOutcomeInput,
|
|
12
|
+
} from "./convergence-types";
|
|
13
|
+
|
|
14
|
+
function notEvaluatedHistory(): CodexHistoryState {
|
|
15
|
+
return {
|
|
16
|
+
status: "not-evaluated",
|
|
17
|
+
attempts: 0,
|
|
18
|
+
nextRetryAt: null,
|
|
19
|
+
txId: null,
|
|
20
|
+
pendingRows: null,
|
|
21
|
+
backupEntries: null,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function notEvaluatedObserved(history: CodexHistoryState): CodexObservedState {
|
|
26
|
+
return {
|
|
27
|
+
aggregate: "not-evaluated",
|
|
28
|
+
isApplied: null,
|
|
29
|
+
desired: "unknown",
|
|
30
|
+
converged: null,
|
|
31
|
+
authority: { service: "unknown", externalProvider: null },
|
|
32
|
+
surfaces: {
|
|
33
|
+
config: "not-evaluated",
|
|
34
|
+
profile: "not-evaluated",
|
|
35
|
+
catalog: "not-evaluated",
|
|
36
|
+
cache: "not-evaluated",
|
|
37
|
+
journal: "not-evaluated",
|
|
38
|
+
history: {
|
|
39
|
+
state: history,
|
|
40
|
+
database: "not-evaluated",
|
|
41
|
+
manifest: "not-evaluated",
|
|
42
|
+
rollouts: "not-evaluated",
|
|
43
|
+
},
|
|
44
|
+
provenance: {
|
|
45
|
+
state: "not-evaluated",
|
|
46
|
+
nativeGeneration: null,
|
|
47
|
+
currentTxId: null,
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** Recognized errno/code tokens. Anything else is dropped rather than echoed. */
|
|
54
|
+
const RECOGNIZED_FAILURE_CODES: ReadonlySet<string> = new Set([
|
|
55
|
+
"ENOSPC", "EACCES", "EPERM", "EROFS", "ENOENT", "SQLITE_BUSY",
|
|
56
|
+
]);
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Reduce a caught error to an allowlisted cause (#1784).
|
|
60
|
+
*
|
|
61
|
+
* Nothing from the error text reaches the caller: `kind` is chosen from a closed set and
|
|
62
|
+
* `code` is only emitted when it is a recognized token. An `Error.message` routinely carries
|
|
63
|
+
* paths, home directories and account ids, and `redactSecretString` masks token shapes but
|
|
64
|
+
* none of those, so the message is never a safe thing to forward from here.
|
|
65
|
+
*/
|
|
66
|
+
function catalogFailureCause(error: unknown): CatalogFailureCause {
|
|
67
|
+
const raw = (error as { code?: unknown } | null)?.code;
|
|
68
|
+
const code = typeof raw === "string" && RECOGNIZED_FAILURE_CODES.has(raw)
|
|
69
|
+
? raw as CatalogFailureCause["code"]
|
|
70
|
+
: undefined;
|
|
71
|
+
if (error instanceof TypeError || error instanceof RangeError || error instanceof SyntaxError) {
|
|
72
|
+
return { kind: "invalid-request", ...(code ? { code } : {}) };
|
|
73
|
+
}
|
|
74
|
+
if (code === "SQLITE_BUSY") return { kind: "lock-busy", code };
|
|
75
|
+
if (code !== undefined) return { kind: "io", code };
|
|
76
|
+
return { kind: "unknown" };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Classify a failure that is NOT a filesystem problem.
|
|
81
|
+
*
|
|
82
|
+
* `disk` used to be the catch-all, so an operator saw "non-retryable disk failure" for a
|
|
83
|
+
* malformed request. Reserve `disk` for real IO and route the rest to honest reasons.
|
|
84
|
+
*/
|
|
85
|
+
function classifiedCatalogFailure(error: unknown, commitBegan: boolean): CatalogDisposition {
|
|
86
|
+
const cause = catalogFailureCause(error);
|
|
87
|
+
const reason = cause.kind === "invalid-request"
|
|
88
|
+
? "request-invalid" as const
|
|
89
|
+
: cause.kind === "lock-busy"
|
|
90
|
+
? "admission" as const
|
|
91
|
+
: cause.kind === "io"
|
|
92
|
+
? "disk" as const
|
|
93
|
+
: "internal" as const;
|
|
94
|
+
return {
|
|
95
|
+
status: "failed",
|
|
96
|
+
reason,
|
|
97
|
+
phase: commitBegan ? "commit" : "gather",
|
|
98
|
+
// Contention is the one class worth retrying unchanged.
|
|
99
|
+
retryable: reason === "admission",
|
|
100
|
+
partialWrite: commitBegan,
|
|
101
|
+
cause,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function unexpectedCatalogFailure(commitBegan: boolean): CatalogDisposition {
|
|
106
|
+
return {
|
|
107
|
+
status: "failed",
|
|
108
|
+
reason: "disk",
|
|
109
|
+
phase: commitBegan ? "commit" : "gather",
|
|
110
|
+
retryable: false,
|
|
111
|
+
partialWrite: commitBegan,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function admissionFailure(error: unknown): CatalogDisposition {
|
|
116
|
+
const message = error instanceof Error ? error.message : "";
|
|
117
|
+
if (message.includes("config generation is busy") || message.includes("config generation is database")) {
|
|
118
|
+
return { status: "skipped", reason: "busy", retryable: true };
|
|
119
|
+
}
|
|
120
|
+
return classifiedCatalogFailure(error, false);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/** Project catalog work into the shared no-change/not-evaluated outcome shape. */
|
|
124
|
+
export function projectCatalogOnlyOutcome({
|
|
125
|
+
changed,
|
|
126
|
+
catalogRefresh,
|
|
127
|
+
}: ProjectCatalogOnlyOutcomeInput): CatalogOnlyOutcome {
|
|
128
|
+
const history = notEvaluatedHistory();
|
|
129
|
+
return {
|
|
130
|
+
kind: "catalog-only",
|
|
131
|
+
changed,
|
|
132
|
+
observed: notEvaluatedObserved(history),
|
|
133
|
+
catalogRefresh,
|
|
134
|
+
history,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Bind the management callback's exact config authority to a catalog-only
|
|
140
|
+
* funnel. This module is intentionally not re-exported by a public Codex facade.
|
|
141
|
+
*/
|
|
142
|
+
export function createManagementConvergeCodex(
|
|
143
|
+
config: Readonly<OcxConfig>,
|
|
144
|
+
): ConvergeCodex {
|
|
145
|
+
const retainedConfig = config;
|
|
146
|
+
return async request => {
|
|
147
|
+
let commitBegan = false;
|
|
148
|
+
try {
|
|
149
|
+
if (request.scope !== "catalog" || request.action !== "converge") {
|
|
150
|
+
return projectCatalogOnlyOutcome({
|
|
151
|
+
changed: false,
|
|
152
|
+
catalogRefresh: unexpectedCatalogFailure(false),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
const snapshot = captureCatalogAdmissionSnapshot(retainedConfig);
|
|
156
|
+
const result = await convergeCodexCatalog(snapshot, request, {
|
|
157
|
+
onCommitBegin: () => { commitBegan = true; },
|
|
158
|
+
});
|
|
159
|
+
return projectCatalogOnlyOutcome(result);
|
|
160
|
+
} catch (error) {
|
|
161
|
+
return projectCatalogOnlyOutcome({
|
|
162
|
+
changed: false,
|
|
163
|
+
catalogRefresh: commitBegan ? classifiedCatalogFailure(error, true) : admissionFailure(error),
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory, per-provider TTL cache for live `/models` results.
|
|
3
|
+
*
|
|
4
|
+
* Ported in spirit from jawcode's packages/ai/src/model-manager.ts (the "always load the latest
|
|
5
|
+
* model list" resolver): live fetch when the cache is stale, serve the cache while it is fresh,
|
|
6
|
+
* and fall back to the last-known-good list when a live fetch fails. opencodex's proxy is a single
|
|
7
|
+
* long-running process and the on-disk Codex catalog already persists the last sync across
|
|
8
|
+
* restarts, so an in-memory cache is sufficient here (no SQLite layer needed).
|
|
9
|
+
*/
|
|
10
|
+
import type { CatalogModel } from "./catalog";
|
|
11
|
+
import type { GenerationContext } from "../lib/state-store-sweeper";
|
|
12
|
+
import { enforceAppOwnedMemoryBudget, type RetainedStoreSnapshot } from "../lib/app-owned-memory";
|
|
13
|
+
|
|
14
|
+
/** Default freshness window. Matches Codex's own 5-min models cache so the two stay in step. */
|
|
15
|
+
export const DEFAULT_MODEL_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
16
|
+
|
|
17
|
+
interface CacheEntry {
|
|
18
|
+
models: CatalogModel[];
|
|
19
|
+
fetchedAt: number;
|
|
20
|
+
sizeBytes: number;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export type ProviderModelDiscoveryFailureReason =
|
|
24
|
+
| "http"
|
|
25
|
+
| "blocked"
|
|
26
|
+
| "invalid_response"
|
|
27
|
+
| "network"
|
|
28
|
+
| "provider";
|
|
29
|
+
|
|
30
|
+
export type ProviderModelDiscoveryStatus =
|
|
31
|
+
| { status: "ok" }
|
|
32
|
+
| { status: "failed"; reason: "http"; httpStatus: number }
|
|
33
|
+
| {
|
|
34
|
+
status: "failed";
|
|
35
|
+
reason: Exclude<ProviderModelDiscoveryFailureReason, "http">;
|
|
36
|
+
httpStatus?: never;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export type ProviderModelDiscoveryFailure = ProviderModelDiscoveryStatus extends infer Status
|
|
40
|
+
? Status extends { status: "failed" }
|
|
41
|
+
? Omit<Status, "status">
|
|
42
|
+
: never
|
|
43
|
+
: never;
|
|
44
|
+
|
|
45
|
+
/** Whether clearing cache rows also revokes in-flight discovery authority. */
|
|
46
|
+
export type ModelCacheClearReason = "authority" | "eviction";
|
|
47
|
+
|
|
48
|
+
const cache = new Map<string, CacheEntry>();
|
|
49
|
+
let globalCacheGeneration = 0;
|
|
50
|
+
export const providerCacheGenerations = new Map<string, number>();
|
|
51
|
+
let cacheBytes = 0;
|
|
52
|
+
let oldestCachedProvider: string | undefined;
|
|
53
|
+
let oldestCachedAt: number | null = null;
|
|
54
|
+
const modelCacheEncoder = new TextEncoder();
|
|
55
|
+
|
|
56
|
+
function recomputeOldestCachedProvider(): void {
|
|
57
|
+
oldestCachedProvider = undefined;
|
|
58
|
+
oldestCachedAt = null;
|
|
59
|
+
for (const [provider, entry] of cache) {
|
|
60
|
+
if (oldestCachedAt !== null && entry.fetchedAt >= oldestCachedAt) continue;
|
|
61
|
+
oldestCachedProvider = provider;
|
|
62
|
+
oldestCachedAt = entry.fetchedAt;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function deleteCachedProvider(provider: string): number {
|
|
67
|
+
const entry = cache.get(provider);
|
|
68
|
+
if (!entry) return 0;
|
|
69
|
+
cache.delete(provider);
|
|
70
|
+
cacheBytes = Math.max(0, cacheBytes - entry.sizeBytes);
|
|
71
|
+
if (oldestCachedProvider === provider) recomputeOldestCachedProvider();
|
|
72
|
+
return entry.sizeBytes;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Cooldown after a failed live `/models` fetch, so a dead/unreachable provider doesn't re-pay
|
|
76
|
+
* the full fetch timeout on every catalog poll (issue #54: UI stalls behind corporate proxies). */
|
|
77
|
+
export const MODELS_FETCH_FAILURE_COOLDOWN_MS = 30_000;
|
|
78
|
+
|
|
79
|
+
const failureAt = new Map<string, number>();
|
|
80
|
+
const discoveryStatus = new Map<string, ProviderModelDiscoveryStatus>();
|
|
81
|
+
/**
|
|
82
|
+
* How many models the last successful discovery actually returned, before any configured-alias
|
|
83
|
+
* augmentation or custom-model merge. Consumers cannot recover this by subtracting known custom
|
|
84
|
+
* ids: a custom id that later also appears upstream would make a real live catalog look
|
|
85
|
+
* custom-only, and the provider's configured fallback would wrongly stay authoritative.
|
|
86
|
+
*/
|
|
87
|
+
const liveModelCounts = new Map<string, number>();
|
|
88
|
+
let lastReconciledGeneration = 0;
|
|
89
|
+
|
|
90
|
+
export function markModelsFetchFailure(provider: string, now = Date.now()): void {
|
|
91
|
+
failureAt.set(provider, now);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** `liveModelCount` is required so a caller that forgets to pass it fails typecheck instead of
|
|
95
|
+
* silently recording zero and misclassifying the provider as having no live catalog. */
|
|
96
|
+
export function markProviderDiscoveryOk(provider: string, liveModelCount: number): void {
|
|
97
|
+
discoveryStatus.set(provider, { status: "ok" });
|
|
98
|
+
liveModelCounts.set(provider, Math.max(0, Math.floor(liveModelCount)));
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function markProviderDiscoveryFailed(
|
|
102
|
+
provider: string,
|
|
103
|
+
failure: ProviderModelDiscoveryFailure,
|
|
104
|
+
): void {
|
|
105
|
+
discoveryStatus.set(provider, { status: "failed", ...failure });
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Decide whether a discovery FAILURE should be logged, to avoid flooding the log with an identical
|
|
110
|
+
* warning on every poll (#395: an anthropic-adapter baseUrl without `/v1/models`, e.g. Azure AI
|
|
111
|
+
* Foundry, returns HTTP 404 forever; the 30s cooldown re-probes and previously re-logged each time).
|
|
112
|
+
*
|
|
113
|
+
* Returns true only when the failure SIGNATURE changed since the last observed status — i.e. the
|
|
114
|
+
* previous state was ok/undefined, or a different reason/httpStatus. Repeated identical failures
|
|
115
|
+
* stay observable through `getProviderDiscoveryStatus()` / the providers API without log spam.
|
|
116
|
+
* Call this BEFORE `markProviderDiscoveryFailed` so it can see the prior state.
|
|
117
|
+
*/
|
|
118
|
+
export function shouldLogDiscoveryFailure(
|
|
119
|
+
provider: string,
|
|
120
|
+
failure: ProviderModelDiscoveryFailure,
|
|
121
|
+
): boolean {
|
|
122
|
+
const prev = discoveryStatus.get(provider);
|
|
123
|
+
if (!prev || prev.status !== "failed") return true;
|
|
124
|
+
if (prev.reason !== failure.reason) return true;
|
|
125
|
+
if (prev.reason === "http" && failure.reason === "http") {
|
|
126
|
+
return prev.httpStatus !== failure.httpStatus;
|
|
127
|
+
}
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function clearProviderDiscoveryStatus(provider: string): void {
|
|
132
|
+
discoveryStatus.delete(provider);
|
|
133
|
+
liveModelCounts.delete(provider);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export function getProviderDiscoveryStatus(provider: string): ProviderModelDiscoveryStatus | undefined {
|
|
137
|
+
return discoveryStatus.get(provider);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** Undefined when discovery has never succeeded for this provider. A failed refresh keeps the
|
|
141
|
+
* last successful count so a stale catalog is still recognised as live-origin. */
|
|
142
|
+
export function getProviderLiveModelCount(provider: string): number | undefined {
|
|
143
|
+
return liveModelCounts.get(provider);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function isModelsFetchCoolingDown(provider: string, cooldownMs = MODELS_FETCH_FAILURE_COOLDOWN_MS, now = Date.now()): boolean {
|
|
147
|
+
const at = failureAt.get(provider);
|
|
148
|
+
return at !== undefined && now - at < cooldownMs;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/** Fresh cached models for a provider, or null when absent/stale (caller should re-fetch). */
|
|
152
|
+
export function getFreshCached(provider: string, ttlMs: number, now = Date.now()): CatalogModel[] | null {
|
|
153
|
+
const entry = cache.get(provider);
|
|
154
|
+
if (!entry) return null;
|
|
155
|
+
return now - entry.fetchedAt < ttlMs ? entry.models : null;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** Last-known-good models regardless of age — the fallback when a live fetch fails. */
|
|
159
|
+
export function getStaleCached(provider: string): CatalogModel[] | null {
|
|
160
|
+
return cache.get(provider)?.models ?? null;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/** Capture the cache generation before an asynchronous provider discovery starts. */
|
|
164
|
+
export function captureModelCacheGeneration(provider: string): string {
|
|
165
|
+
if (!providerCacheGenerations.has(provider)) providerCacheGenerations.set(provider, 0);
|
|
166
|
+
return `${globalCacheGeneration}:${providerCacheGenerations.get(provider)!}`;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** Whether a discovery started under {@link captureModelCacheGeneration} may still write. */
|
|
170
|
+
export function isModelCacheGenerationCurrent(provider: string, generation: string): boolean {
|
|
171
|
+
return generation === captureModelCacheGeneration(provider);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Store a live result unless the cache was cleared while that asynchronous discovery was running.
|
|
176
|
+
* The optional generation keeps existing direct cache writers unchanged while discovery callers can
|
|
177
|
+
* prevent a previous OAuth account from repopulating the current account's cache.
|
|
178
|
+
*/
|
|
179
|
+
export function setCached(
|
|
180
|
+
provider: string,
|
|
181
|
+
models: CatalogModel[],
|
|
182
|
+
now = Date.now(),
|
|
183
|
+
generation?: string,
|
|
184
|
+
): boolean {
|
|
185
|
+
if (generation !== undefined && !isModelCacheGenerationCurrent(provider, generation)) return false;
|
|
186
|
+
deleteCachedProvider(provider);
|
|
187
|
+
const sizeBytes = modelCacheEncoder.encode(provider).byteLength
|
|
188
|
+
+ modelCacheEncoder.encode(JSON.stringify(models)).byteLength;
|
|
189
|
+
cache.set(provider, { models, fetchedAt: now, sizeBytes });
|
|
190
|
+
cacheBytes += sizeBytes;
|
|
191
|
+
if (oldestCachedAt === null || now < oldestCachedAt) {
|
|
192
|
+
oldestCachedProvider = provider;
|
|
193
|
+
oldestCachedAt = now;
|
|
194
|
+
}
|
|
195
|
+
enforceAppOwnedMemoryBudget();
|
|
196
|
+
return true;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** Drop one provider's cache (or all) so the next resolve forces a live re-fetch. */
|
|
200
|
+
export function clearModelCache(
|
|
201
|
+
provider?: string,
|
|
202
|
+
reason: ModelCacheClearReason = "authority",
|
|
203
|
+
): void {
|
|
204
|
+
const revokesInFlightDiscovery = reason === "authority";
|
|
205
|
+
if (provider) {
|
|
206
|
+
if (revokesInFlightDiscovery) {
|
|
207
|
+
providerCacheGenerations.set(provider, (providerCacheGenerations.get(provider) ?? 0) + 1);
|
|
208
|
+
}
|
|
209
|
+
deleteCachedProvider(provider);
|
|
210
|
+
failureAt.delete(provider);
|
|
211
|
+
discoveryStatus.delete(provider);
|
|
212
|
+
liveModelCounts.delete(provider);
|
|
213
|
+
} else {
|
|
214
|
+
if (revokesInFlightDiscovery) globalCacheGeneration += 1;
|
|
215
|
+
cache.clear();
|
|
216
|
+
cacheBytes = 0;
|
|
217
|
+
oldestCachedProvider = undefined;
|
|
218
|
+
oldestCachedAt = null;
|
|
219
|
+
failureAt.clear();
|
|
220
|
+
discoveryStatus.clear();
|
|
221
|
+
liveModelCounts.clear();
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
export function reconcileModelCacheProviders(
|
|
226
|
+
validProviders: ReadonlySet<string>,
|
|
227
|
+
generation = lastReconciledGeneration + 1,
|
|
228
|
+
): number {
|
|
229
|
+
if (generation <= lastReconciledGeneration) return 0;
|
|
230
|
+
const removedProviders = new Set<string>();
|
|
231
|
+
const trackedProviders = new Set([
|
|
232
|
+
...providerCacheGenerations.keys(),
|
|
233
|
+
...failureAt.keys(),
|
|
234
|
+
...discoveryStatus.keys(),
|
|
235
|
+
...liveModelCounts.keys(),
|
|
236
|
+
...cache.keys(),
|
|
237
|
+
]);
|
|
238
|
+
let revokedRemovedProviderAuthority = false;
|
|
239
|
+
for (const provider of trackedProviders) {
|
|
240
|
+
if (validProviders.has(provider)) continue;
|
|
241
|
+
if (!revokedRemovedProviderAuthority) {
|
|
242
|
+
globalCacheGeneration += 1;
|
|
243
|
+
revokedRemovedProviderAuthority = true;
|
|
244
|
+
}
|
|
245
|
+
providerCacheGenerations.set(provider, (providerCacheGenerations.get(provider) ?? 0) + 1);
|
|
246
|
+
providerCacheGenerations.delete(provider);
|
|
247
|
+
deleteCachedProvider(provider);
|
|
248
|
+
failureAt.delete(provider);
|
|
249
|
+
discoveryStatus.delete(provider);
|
|
250
|
+
liveModelCounts.delete(provider);
|
|
251
|
+
removedProviders.add(provider);
|
|
252
|
+
}
|
|
253
|
+
lastReconciledGeneration = generation;
|
|
254
|
+
return removedProviders.size;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export function reconcileModelCacheGeneration(context: GenerationContext): number {
|
|
258
|
+
return reconcileModelCacheProviders(context.providerNames, context.generation);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
export function modelCacheRetainedStoreSnapshot(): RetainedStoreSnapshot {
|
|
262
|
+
return {
|
|
263
|
+
count: cache.size,
|
|
264
|
+
bytes: cacheBytes,
|
|
265
|
+
evictableBytes: cacheBytes,
|
|
266
|
+
pinnedBytes: 0,
|
|
267
|
+
oldestAt: oldestCachedAt,
|
|
268
|
+
};
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function evictOldestModelCacheForBudget(): number {
|
|
272
|
+
return oldestCachedProvider === undefined ? 0 : deleteCachedProvider(oldestCachedProvider);
|
|
273
|
+
}
|