@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,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Schema-aware argument key normalization for Cursor tool calls.
|
|
3
|
+
*
|
|
4
|
+
* Cursor-trained models sometimes emit argument keys that differ from the tool's declared schema
|
|
5
|
+
* (e.g. `filepath` instead of `path`, `cmd` instead of `command`). This module maps common aliases
|
|
6
|
+
* to the canonical key name ONLY when the tool schema declares that canonical key. Keys already
|
|
7
|
+
* matching the schema are never touched.
|
|
8
|
+
*
|
|
9
|
+
* Derived from opencode-cursor reference (src/provider/tool-schema-compat.ts).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const KEY_ALIASES = new Map<string, string>([
|
|
13
|
+
["filepath", "path"],
|
|
14
|
+
["filename", "path"],
|
|
15
|
+
["file", "path"],
|
|
16
|
+
["targetpath", "path"],
|
|
17
|
+
["directorypath", "path"],
|
|
18
|
+
["dir", "path"],
|
|
19
|
+
["folder", "path"],
|
|
20
|
+
["directory", "path"],
|
|
21
|
+
["targetdirectory", "path"],
|
|
22
|
+
["targetfile", "path"],
|
|
23
|
+
["globpattern", "pattern"],
|
|
24
|
+
["filepattern", "pattern"],
|
|
25
|
+
["searchpattern", "pattern"],
|
|
26
|
+
["includepattern", "include"],
|
|
27
|
+
["workingdirectory", "cwd"],
|
|
28
|
+
["workdir", "cwd"],
|
|
29
|
+
["currentdirectory", "cwd"],
|
|
30
|
+
["cmd", "command"],
|
|
31
|
+
["script", "command"],
|
|
32
|
+
["shellcommand", "command"],
|
|
33
|
+
["terminalcommand", "command"],
|
|
34
|
+
["contents", "content"],
|
|
35
|
+
["text", "content"],
|
|
36
|
+
["body", "content"],
|
|
37
|
+
["data", "content"],
|
|
38
|
+
["payload", "content"],
|
|
39
|
+
["streamcontent", "content"],
|
|
40
|
+
["oldstring", "old_string"],
|
|
41
|
+
["newstring", "new_string"],
|
|
42
|
+
["oldtext", "old_string"],
|
|
43
|
+
["newtext", "new_string"],
|
|
44
|
+
["oldcontent", "old_string"],
|
|
45
|
+
["newcontent", "new_string"],
|
|
46
|
+
["recursive", "force"],
|
|
47
|
+
]);
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Extract the set of declared property names from a JSON Schema parameters object.
|
|
51
|
+
* Handles the common `{ type: "object", properties: { ... } }` shape.
|
|
52
|
+
*/
|
|
53
|
+
function schemaPropertyNames(schema: unknown): Set<string> | undefined {
|
|
54
|
+
if (!schema || typeof schema !== "object") return undefined;
|
|
55
|
+
const obj = schema as Record<string, unknown>;
|
|
56
|
+
const props = obj.properties;
|
|
57
|
+
if (!props || typeof props !== "object") return undefined;
|
|
58
|
+
return new Set(Object.keys(props as Record<string, unknown>));
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Normalize argument keys against the tool's declared schema. Keys not in the schema that have a
|
|
63
|
+
* known alias pointing to a schema-declared key are renamed. Explicitly supplied canonical keys
|
|
64
|
+
* always win over aliases, regardless of object property insertion order — conflicting aliases
|
|
65
|
+
* are discarded rather than left beside the canonical key.
|
|
66
|
+
*
|
|
67
|
+
* Returns the original object reference if no changes were needed (cheap identity check for callers).
|
|
68
|
+
*/
|
|
69
|
+
export function normalizeArgKeys(args: Record<string, unknown>, toolSchema: unknown): Record<string, unknown> {
|
|
70
|
+
const declared = schemaPropertyNames(toolSchema);
|
|
71
|
+
if (!declared || declared.size === 0) return args;
|
|
72
|
+
|
|
73
|
+
const suppliedCanonical = new Set<string>();
|
|
74
|
+
for (const key of Object.keys(args)) {
|
|
75
|
+
if (declared.has(key)) suppliedCanonical.add(key);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
let changed = false;
|
|
79
|
+
const result: Record<string, unknown> = {};
|
|
80
|
+
for (const [key, value] of Object.entries(args)) {
|
|
81
|
+
if (declared.has(key)) {
|
|
82
|
+
result[key] = value;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
const canonical = KEY_ALIASES.get(key.toLowerCase());
|
|
86
|
+
if (canonical && declared.has(canonical)) {
|
|
87
|
+
// Canonical was explicitly supplied (any order) — drop the alias entirely.
|
|
88
|
+
if (suppliedCanonical.has(canonical)) {
|
|
89
|
+
changed = true;
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
// First alias fills the canonical slot; later aliases for the same key are discarded.
|
|
93
|
+
if (!(canonical in result)) {
|
|
94
|
+
result[canonical] = value;
|
|
95
|
+
changed = true;
|
|
96
|
+
} else {
|
|
97
|
+
changed = true;
|
|
98
|
+
}
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
result[key] = value;
|
|
102
|
+
}
|
|
103
|
+
return changed ? result : args;
|
|
104
|
+
}
|
|
@@ -0,0 +1,303 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { fromBinary } from "@bufbuild/protobuf";
|
|
3
|
+
import { ConversationStateStructureSchema, type ConversationStateStructure } from "./gen/agent_pb";
|
|
4
|
+
import {
|
|
5
|
+
createCursorBlobCheckpointLease,
|
|
6
|
+
pinCursorBlobIdsForCheckpoint,
|
|
7
|
+
releaseCursorBlobRequestScope,
|
|
8
|
+
type CursorBlobRequestScopeToken,
|
|
9
|
+
} from "./native-exec";
|
|
10
|
+
|
|
11
|
+
export const CURSOR_CHECKPOINT_TTL_MS = 15 * 60_000;
|
|
12
|
+
export const CURSOR_CHECKPOINT_MAX_ENTRIES = 64;
|
|
13
|
+
export const CURSOR_CHECKPOINT_MAX_TOTAL_BYTES = 16 * 1024 * 1024;
|
|
14
|
+
|
|
15
|
+
export type CursorCheckpointInvalidationReason =
|
|
16
|
+
| "missing_ref"
|
|
17
|
+
| "expired"
|
|
18
|
+
| "decode_failed"
|
|
19
|
+
| "conversation_changed"
|
|
20
|
+
| "identity_changed"
|
|
21
|
+
| "model_changed"
|
|
22
|
+
| "compaction"
|
|
23
|
+
| "trailing_tool_result"
|
|
24
|
+
| "force_fresh"
|
|
25
|
+
| "upstream_invalid_argument"
|
|
26
|
+
| "lineage_mismatch";
|
|
27
|
+
|
|
28
|
+
export interface CursorCheckpointSnapshot {
|
|
29
|
+
ref: string;
|
|
30
|
+
conversationId: string;
|
|
31
|
+
identityScope: string;
|
|
32
|
+
modelId: string;
|
|
33
|
+
checkpointBytes: Uint8Array;
|
|
34
|
+
createdAt: number;
|
|
35
|
+
lastAccessAt: number;
|
|
36
|
+
blobLease?: CursorBlobRequestScopeToken;
|
|
37
|
+
coveredMessageCount?: number;
|
|
38
|
+
prefixDigest?: string;
|
|
39
|
+
systemDigest?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface CursorCheckpointStore {
|
|
43
|
+
snapshots: Map<string, CursorCheckpointSnapshot>;
|
|
44
|
+
prefixIndex: Map<string, Set<string>>;
|
|
45
|
+
totalBytes: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const store: CursorCheckpointStore = {
|
|
49
|
+
snapshots: new Map(),
|
|
50
|
+
prefixIndex: new Map(),
|
|
51
|
+
totalBytes: 0,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
let nowFn = (): number => Date.now();
|
|
55
|
+
let scheduleFn = (fn: () => void, ms: number): ReturnType<typeof setTimeout> => {
|
|
56
|
+
const timer = setTimeout(fn, ms);
|
|
57
|
+
timer.unref?.();
|
|
58
|
+
return timer;
|
|
59
|
+
};
|
|
60
|
+
let clearScheduleFn = (timer: ReturnType<typeof setTimeout>): void => {
|
|
61
|
+
clearTimeout(timer);
|
|
62
|
+
};
|
|
63
|
+
let pruneTimer: ReturnType<typeof setTimeout> | undefined;
|
|
64
|
+
|
|
65
|
+
function now(): number {
|
|
66
|
+
return nowFn();
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export function installCursorCheckpointClockForTests(input: {
|
|
70
|
+
now?: () => number;
|
|
71
|
+
schedule?: (fn: () => void, ms: number) => ReturnType<typeof setTimeout>;
|
|
72
|
+
clear?: (timer: ReturnType<typeof setTimeout>) => void;
|
|
73
|
+
}): void {
|
|
74
|
+
if (input.now) nowFn = input.now;
|
|
75
|
+
if (input.schedule) scheduleFn = input.schedule;
|
|
76
|
+
if (input.clear) clearScheduleFn = input.clear;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function resetCursorCheckpointClockForTests(): void {
|
|
80
|
+
nowFn = () => Date.now();
|
|
81
|
+
scheduleFn = (fn, ms) => {
|
|
82
|
+
const timer = setTimeout(fn, ms);
|
|
83
|
+
timer.unref?.();
|
|
84
|
+
return timer;
|
|
85
|
+
};
|
|
86
|
+
clearScheduleFn = timer => {
|
|
87
|
+
clearTimeout(timer);
|
|
88
|
+
};
|
|
89
|
+
stopPruneTimer();
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function stopPruneTimer(): void {
|
|
93
|
+
if (pruneTimer !== undefined) clearScheduleFn(pruneTimer);
|
|
94
|
+
pruneTimer = undefined;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function schedulePrune(at = now()): void {
|
|
98
|
+
stopPruneTimer();
|
|
99
|
+
let nextExpiry = Number.POSITIVE_INFINITY;
|
|
100
|
+
for (const snapshot of store.snapshots.values()) {
|
|
101
|
+
nextExpiry = Math.min(nextExpiry, snapshot.lastAccessAt + CURSOR_CHECKPOINT_TTL_MS);
|
|
102
|
+
}
|
|
103
|
+
if (!Number.isFinite(nextExpiry)) return;
|
|
104
|
+
pruneTimer = scheduleFn(() => {
|
|
105
|
+
pruneTimer = undefined;
|
|
106
|
+
prune();
|
|
107
|
+
schedulePrune();
|
|
108
|
+
}, Math.max(0, nextExpiry - at));
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function prune(at = now()): void {
|
|
112
|
+
for (const [ref, snapshot] of store.snapshots) {
|
|
113
|
+
if (at - snapshot.lastAccessAt > CURSOR_CHECKPOINT_TTL_MS) deleteSnapshot(ref);
|
|
114
|
+
}
|
|
115
|
+
while (store.snapshots.size > CURSOR_CHECKPOINT_MAX_ENTRIES || store.totalBytes > CURSOR_CHECKPOINT_MAX_TOTAL_BYTES) {
|
|
116
|
+
const oldest = store.snapshots.keys().next().value;
|
|
117
|
+
if (oldest === undefined) break;
|
|
118
|
+
deleteSnapshot(oldest);
|
|
119
|
+
}
|
|
120
|
+
schedulePrune(at);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function indexPrefix(digest: string | undefined, ref: string): void {
|
|
124
|
+
if (!digest) return;
|
|
125
|
+
const refs = store.prefixIndex.get(digest) ?? new Set<string>();
|
|
126
|
+
refs.add(ref);
|
|
127
|
+
store.prefixIndex.set(digest, refs);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function unindexPrefix(digest: string | undefined, ref: string): void {
|
|
131
|
+
if (!digest) return;
|
|
132
|
+
const refs = store.prefixIndex.get(digest);
|
|
133
|
+
if (!refs) return;
|
|
134
|
+
refs.delete(ref);
|
|
135
|
+
if (refs.size === 0) store.prefixIndex.delete(digest);
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
function deleteSnapshot(ref: string): void {
|
|
139
|
+
const existing = store.snapshots.get(ref);
|
|
140
|
+
if (!existing) return;
|
|
141
|
+
if (existing.blobLease) releaseCursorBlobRequestScope(existing.blobLease);
|
|
142
|
+
unindexPrefix(existing.prefixDigest, ref);
|
|
143
|
+
store.snapshots.delete(ref);
|
|
144
|
+
store.totalBytes = Math.max(0, store.totalBytes - existing.checkpointBytes.byteLength);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function collectStateBlobIds(state: ConversationStateStructure, ids: Uint8Array[]): void {
|
|
148
|
+
ids.push(
|
|
149
|
+
...state.rootPromptMessagesJson,
|
|
150
|
+
...state.turns,
|
|
151
|
+
...state.turnsOld,
|
|
152
|
+
...state.todos,
|
|
153
|
+
...state.summaryArchives,
|
|
154
|
+
);
|
|
155
|
+
if (state.summary) ids.push(state.summary);
|
|
156
|
+
if (state.summaryArchive) ids.push(state.summaryArchive);
|
|
157
|
+
if (state.plan) ids.push(state.plan);
|
|
158
|
+
for (const value of Object.values(state.fileStates)) ids.push(value);
|
|
159
|
+
for (const value of Object.values(state.fileStatesV2)) {
|
|
160
|
+
if (value.content) ids.push(value.content);
|
|
161
|
+
if (value.initialContent) ids.push(value.initialContent);
|
|
162
|
+
}
|
|
163
|
+
for (const nested of Object.values(state.subagentStates)) {
|
|
164
|
+
if (nested.conversationState) collectStateBlobIds(nested.conversationState, ids);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function collectCheckpointBlobIds(checkpointBytes: Uint8Array): Uint8Array[] | undefined {
|
|
169
|
+
try {
|
|
170
|
+
const ids: Uint8Array[] = [];
|
|
171
|
+
collectStateBlobIds(fromBinary(ConversationStateStructureSchema, checkpointBytes), ids);
|
|
172
|
+
return ids.filter(id => id.byteLength > 0);
|
|
173
|
+
} catch {
|
|
174
|
+
return undefined;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export function cursorCheckpointRefHash(ref: string): string {
|
|
179
|
+
return createHash("sha256").update("ocx:cursor:ckpt-ref:").update(ref).digest("hex").slice(0, 16);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
export function commitCursorCheckpoint(input: {
|
|
183
|
+
conversationId: string;
|
|
184
|
+
identityScope?: string;
|
|
185
|
+
modelId: string;
|
|
186
|
+
checkpointBytes: Uint8Array;
|
|
187
|
+
coveredMessageCount?: number;
|
|
188
|
+
prefixDigest?: string;
|
|
189
|
+
systemDigest?: string;
|
|
190
|
+
}): string | undefined {
|
|
191
|
+
if (!input.conversationId || !input.modelId || input.checkpointBytes.byteLength === 0) return undefined;
|
|
192
|
+
if (input.checkpointBytes.byteLength > CURSOR_CHECKPOINT_MAX_TOTAL_BYTES) return undefined;
|
|
193
|
+
prune();
|
|
194
|
+
const createdAt = now();
|
|
195
|
+
const ref = createHash("sha256")
|
|
196
|
+
.update("ocx:cursor:ckpt:")
|
|
197
|
+
.update(input.conversationId)
|
|
198
|
+
.update("|")
|
|
199
|
+
.update(input.identityScope?.trim() || "local")
|
|
200
|
+
.update("|")
|
|
201
|
+
.update(input.modelId)
|
|
202
|
+
.update("|")
|
|
203
|
+
.update(String(createdAt))
|
|
204
|
+
.update("|")
|
|
205
|
+
.update(input.checkpointBytes)
|
|
206
|
+
.digest("hex")
|
|
207
|
+
.slice(0, 32);
|
|
208
|
+
const snapshot: CursorCheckpointSnapshot = {
|
|
209
|
+
ref,
|
|
210
|
+
conversationId: input.conversationId,
|
|
211
|
+
identityScope: input.identityScope?.trim() || "local",
|
|
212
|
+
modelId: input.modelId,
|
|
213
|
+
checkpointBytes: input.checkpointBytes.slice(),
|
|
214
|
+
createdAt,
|
|
215
|
+
lastAccessAt: createdAt,
|
|
216
|
+
...(input.coveredMessageCount !== undefined ? { coveredMessageCount: input.coveredMessageCount } : {}),
|
|
217
|
+
...(input.prefixDigest ? { prefixDigest: input.prefixDigest } : {}),
|
|
218
|
+
...(input.systemDigest ? { systemDigest: input.systemDigest } : {}),
|
|
219
|
+
};
|
|
220
|
+
const blobIds = collectCheckpointBlobIds(input.checkpointBytes);
|
|
221
|
+
if (blobIds === undefined) return undefined;
|
|
222
|
+
if (blobIds.length > 0) {
|
|
223
|
+
const lease = createCursorBlobCheckpointLease(ref);
|
|
224
|
+
if (!pinCursorBlobIdsForCheckpoint(blobIds, lease)) {
|
|
225
|
+
releaseCursorBlobRequestScope(lease);
|
|
226
|
+
return undefined;
|
|
227
|
+
}
|
|
228
|
+
snapshot.blobLease = lease;
|
|
229
|
+
}
|
|
230
|
+
deleteSnapshot(ref);
|
|
231
|
+
store.snapshots.set(ref, snapshot);
|
|
232
|
+
store.totalBytes += snapshot.checkpointBytes.byteLength;
|
|
233
|
+
indexPrefix(snapshot.prefixDigest, ref);
|
|
234
|
+
prune(createdAt);
|
|
235
|
+
return store.snapshots.has(ref) ? ref : undefined;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function getCursorCheckpointForPrefix(input: {
|
|
239
|
+
prefixDigest: string;
|
|
240
|
+
systemDigest: string;
|
|
241
|
+
coveredMessageCount: number;
|
|
242
|
+
identityScope?: string;
|
|
243
|
+
modelId: string;
|
|
244
|
+
}): CursorCheckpointSnapshot | undefined {
|
|
245
|
+
prune();
|
|
246
|
+
const refs = store.prefixIndex.get(input.prefixDigest);
|
|
247
|
+
if (!refs || refs.size !== 1) return undefined;
|
|
248
|
+
const [ref] = refs;
|
|
249
|
+
if (!ref) return undefined;
|
|
250
|
+
const snapshot = getCursorCheckpoint(ref);
|
|
251
|
+
if (!snapshot) return undefined;
|
|
252
|
+
const identityScope = input.identityScope?.trim() || "local";
|
|
253
|
+
if (snapshot.systemDigest !== input.systemDigest) return undefined;
|
|
254
|
+
if (snapshot.coveredMessageCount !== input.coveredMessageCount) return undefined;
|
|
255
|
+
if (snapshot.identityScope !== identityScope) return undefined;
|
|
256
|
+
if (snapshot.modelId !== input.modelId) return undefined;
|
|
257
|
+
return snapshot;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
export function getLatestCursorCheckpoint(
|
|
261
|
+
match: (snapshot: CursorCheckpointSnapshot) => boolean,
|
|
262
|
+
): CursorCheckpointSnapshot | undefined {
|
|
263
|
+
prune();
|
|
264
|
+
let found: CursorCheckpointSnapshot | undefined;
|
|
265
|
+
for (const snapshot of store.snapshots.values()) {
|
|
266
|
+
if (match(snapshot)) found = snapshot;
|
|
267
|
+
}
|
|
268
|
+
return found ? getCursorCheckpoint(found.ref) : undefined;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
export function getCursorCheckpoint(ref: string | undefined): CursorCheckpointSnapshot | undefined {
|
|
272
|
+
if (!ref) return undefined;
|
|
273
|
+
prune();
|
|
274
|
+
const snapshot = store.snapshots.get(ref);
|
|
275
|
+
if (!snapshot) return undefined;
|
|
276
|
+
const at = now();
|
|
277
|
+
if (at - snapshot.lastAccessAt > CURSOR_CHECKPOINT_TTL_MS) {
|
|
278
|
+
deleteSnapshot(ref);
|
|
279
|
+
return undefined;
|
|
280
|
+
}
|
|
281
|
+
snapshot.lastAccessAt = at;
|
|
282
|
+
store.snapshots.delete(ref);
|
|
283
|
+
store.snapshots.set(ref, snapshot);
|
|
284
|
+
return snapshot;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
export function invalidateCursorCheckpoint(ref: string | undefined): void {
|
|
288
|
+
if (!ref) return;
|
|
289
|
+
deleteSnapshot(ref);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export function clearCursorCheckpointsForTests(): void {
|
|
293
|
+
stopPruneTimer();
|
|
294
|
+
for (const ref of [...store.snapshots.keys()]) deleteSnapshot(ref);
|
|
295
|
+
store.snapshots.clear();
|
|
296
|
+
store.prefixIndex.clear();
|
|
297
|
+
store.totalBytes = 0;
|
|
298
|
+
resetCursorCheckpointClockForTests();
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export function cursorCheckpointStoreMetricsForTests(): { count: number; totalBytes: number } {
|
|
302
|
+
return { count: store.snapshots.size, totalBytes: store.totalBytes };
|
|
303
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
import { redactSecretString } from "../../lib/redact";
|
|
2
|
+
|
|
3
|
+
const ABSOLUTE_PATH_PATTERN = /(?:\/Users\/[^ "';,]+|\/home\/[^ "';,]+|[A-Za-z]:\\Users\\[^ "';,]+)/g;
|
|
4
|
+
// Cursor error messages can contain raw credential key=value pairs beyond what the shared
|
|
5
|
+
// redactSecretString covers. We handle the additional transport-specific patterns locally.
|
|
6
|
+
const CURSOR_CREDENTIAL_PATTERN = /\b(authorization|auth[_-]?token|cursor[_-]?token)=([^&\s"',;]+)/gi;
|
|
7
|
+
|
|
8
|
+
function sanitize(value: string): string {
|
|
9
|
+
return redactSecretString(value)
|
|
10
|
+
.replace(CURSOR_CREDENTIAL_PATTERN, "$1=[REDACTED]")
|
|
11
|
+
.replace(ABSOLUTE_PATH_PATTERN, "[REDACTED_PATH]");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function errorMessage(value: unknown): string {
|
|
15
|
+
if (value instanceof Error) return value.message;
|
|
16
|
+
if (typeof value === "string") return value;
|
|
17
|
+
return String(value ?? "");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function errorCode(value: unknown): string {
|
|
21
|
+
if (typeof value !== "object" || !value || !("code" in value)) return "";
|
|
22
|
+
const code = (value as { code?: unknown }).code;
|
|
23
|
+
return code === undefined || code === null ? "" : String(code);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* True when Cursor intentionally cancelled the HTTP/2 stream after a client-tool suspend.
|
|
28
|
+
* These are expected between multi-turn Responses bridge cycles, not upstream failures.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* A Cursor stream that ended cleanly at the HTTP/2 layer while a client tool call was still
|
|
32
|
+
* open — no `turnEnded`, no error trailer, just EOF. The call's buffered arguments are lost,
|
|
33
|
+
* so the turn is truncated: reporting it as success would hand Codex a turn whose tool call
|
|
34
|
+
* silently never happened. Not retryable — the request is committed once the session connects.
|
|
35
|
+
*/
|
|
36
|
+
export class CursorStreamTruncatedError extends Error {
|
|
37
|
+
constructor(
|
|
38
|
+
public readonly openCallIds: readonly string[],
|
|
39
|
+
public readonly framesReceived: number,
|
|
40
|
+
) {
|
|
41
|
+
super(
|
|
42
|
+
`Cursor stream ended without terminating the turn; ${openCallIds.length} tool call(s) left incomplete `
|
|
43
|
+
+ `(${openCallIds.join(", ")}) after ${framesReceived} frame(s). Arguments may be truncated; the call was not committed.`,
|
|
44
|
+
);
|
|
45
|
+
this.name = "CursorStreamTruncatedError";
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* A cancel-shaped stream failure that WE did not request. `cancelCursorRun` is the only place
|
|
51
|
+
* that cancels our own stream, and it sets `expectedClose` first, so a cancel arriving without it
|
|
52
|
+
* came from Cursor or the network and is a real transport failure.
|
|
53
|
+
*
|
|
54
|
+
* It carries its own message on purpose. Left as a raw `NGHTTP2_CANCEL` error, the text is
|
|
55
|
+
* re-matched downstream (`classifyCursorError`) and labelled "Cursor stream suspended" — a turn
|
|
56
|
+
* that failed unexpectedly would report an intentional suspension and misdirect diagnosis.
|
|
57
|
+
*/
|
|
58
|
+
export class CursorUnexpectedCancelError extends Error {
|
|
59
|
+
/**
|
|
60
|
+
* The originating error's transport code (typically `NGHTTP2_CANCEL`), re-exposed so the
|
|
61
|
+
* per-turn `turn-failed` diagnostic still records how the stream actually died. Wrapping
|
|
62
|
+
* without this made the summary for exactly this failure the one with no code.
|
|
63
|
+
*/
|
|
64
|
+
public readonly code?: string;
|
|
65
|
+
|
|
66
|
+
constructor(public readonly cause?: unknown) {
|
|
67
|
+
super("Cursor connection was cancelled by the server before the turn completed");
|
|
68
|
+
this.name = "CursorUnexpectedCancelError";
|
|
69
|
+
const causeCode = errorCode(cause);
|
|
70
|
+
if (causeCode) this.code = causeCode;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function isCursorBenignCancelError(value: unknown): boolean {
|
|
75
|
+
// An unexpected cancel is never benign, however it is spelled. This class is raised only when
|
|
76
|
+
// the transport knows WE did not request the cancel, so its provenance outranks the code match
|
|
77
|
+
// below — otherwise the adapter would re-decide the same question from the error code alone
|
|
78
|
+
// and swallow a real transport failure (cursor.ts:181).
|
|
79
|
+
if (value instanceof CursorUnexpectedCancelError) return false;
|
|
80
|
+
const message = errorMessage(value).toLowerCase();
|
|
81
|
+
const code = errorCode(value).toUpperCase();
|
|
82
|
+
if (code === "NGHTTP2_CANCEL") return true;
|
|
83
|
+
if (message.includes("nghttp2_cancel")) return true;
|
|
84
|
+
if (message.includes("cursor stream suspended")) return true;
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* True when the turn was torn down by an `AbortSignal` rather than by a transport fault.
|
|
90
|
+
*
|
|
91
|
+
* This is deliberately NOT part of `isCursorBenignCancelError`: an abort mid-turn is a real
|
|
92
|
+
* failure and must still surface. It is only meaningful in combination with a terminal frame
|
|
93
|
+
* having already been emitted, where it means "the answer landed and then the connection went
|
|
94
|
+
* away" (#1527).
|
|
95
|
+
*/
|
|
96
|
+
export function isCursorAbortError(value: unknown): boolean {
|
|
97
|
+
const message = errorMessage(value).toLowerCase();
|
|
98
|
+
if (message.includes("cursor request was aborted")) return true;
|
|
99
|
+
const name = (value as { name?: unknown })?.name;
|
|
100
|
+
return typeof name === "string" && name === "AbortError";
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* True when Cursor Connect rejected the turn with invalid_argument.
|
|
105
|
+
* Seen after stepCompleted on brittle external-model continuations.
|
|
106
|
+
*/
|
|
107
|
+
export function isCursorInvalidArgumentError(value: unknown): boolean {
|
|
108
|
+
const code = errorCode(value).toLowerCase();
|
|
109
|
+
if (code === "invalid_argument") return true;
|
|
110
|
+
const message = errorMessage(value).toLowerCase();
|
|
111
|
+
return message.includes("invalid_argument");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const QUOTA_RATE_CUES = ["too many requests", "quota", "rate limit", "rate-limit", "throttl"];
|
|
115
|
+
/**
|
|
116
|
+
* A bare `resource_exhausted` end-stream with no detail beyond a generic error wrapper
|
|
117
|
+
* ("Error" or empty tail) and zero tokens billed is the shape Cursor's backend emits when
|
|
118
|
+
* the request payload exceeded its context window — not when quota ran out (senpi #1009,
|
|
119
|
+
* #1036: same wording, two causes). Quota rejections always carry an explicit rate cue
|
|
120
|
+
* ("too many requests", "quota exhausted"), so the ABSENCE of those cues plus the
|
|
121
|
+
* absence of a size phrase means payload overflow. Classifying it as 429 makes Codex
|
|
122
|
+
* back off instead of compacting, which burns retries on an unfixable-by-retry failure.
|
|
123
|
+
*/
|
|
124
|
+
const BARE_RE_TAILS = new Set(["error", "", "resource_exhausted", "resource exhausted"]);
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Size prior for bare resource_exhausted classification (devlog 260, live probe 210):
|
|
128
|
+
* a plan-gated model returns the SAME bare RE shape on a ~20-token prompt that a real
|
|
129
|
+
* payload overflow produces, so the message alone cannot separate "compact and retry"
|
|
130
|
+
* from "this account cannot use this model". When the caller can supply how large the
|
|
131
|
+
* request actually was relative to the model's window, a small request keeps the
|
|
132
|
+
* 429-class mapping; only a plausibly-large one classifies as overflow. Unknown
|
|
133
|
+
* sizes keep today's overflow mapping so the prior only ever REMOVES false overflows
|
|
134
|
+
* it can prove.
|
|
135
|
+
*/
|
|
136
|
+
export interface CursorSizeContext {
|
|
137
|
+
estimatedInputTokens?: number;
|
|
138
|
+
contextWindow?: number;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const OVERFLOW_MIN_FRACTION = 0.5;
|
|
142
|
+
|
|
143
|
+
function bareReLooksLikeOverflow(context?: CursorSizeContext): boolean {
|
|
144
|
+
if (!context) return true;
|
|
145
|
+
const { estimatedInputTokens, contextWindow } = context;
|
|
146
|
+
if (estimatedInputTokens === undefined || contextWindow === undefined || contextWindow <= 0) return true;
|
|
147
|
+
return estimatedInputTokens >= OVERFLOW_MIN_FRACTION * contextWindow;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
export function isCursorZeroTokenResourceExhausted(lowerMessage: string): boolean {
|
|
151
|
+
if (!lowerMessage.includes("resource_exhausted") && !lowerMessage.includes("resource exhausted")) return false;
|
|
152
|
+
// Any explicit quota/rate cue wins: this is a real 429.
|
|
153
|
+
if (QUOTA_RATE_CUES.some(cue => lowerMessage.includes(cue))) return false;
|
|
154
|
+
// An explicit size phrase also wins (already handled by the existing classifier).
|
|
155
|
+
if (isCursorRequestTooLargeDetail(lowerMessage)) return false;
|
|
156
|
+
// Extract the tail after the resource_exhausted marker. If it names a specific
|
|
157
|
+
// non-quota, non-size cause, this is NOT bare overflow.
|
|
158
|
+
const idx = Math.max(
|
|
159
|
+
lowerMessage.indexOf("resource_exhausted"),
|
|
160
|
+
lowerMessage.indexOf("resource exhausted"),
|
|
161
|
+
);
|
|
162
|
+
const tail = lowerMessage.slice(idx + "resource_exhausted".length).trim().replace(/^[:\s]+/, "").trim();
|
|
163
|
+
if (!BARE_RE_TAILS.has(tail)) return false;
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const REQUEST_TOO_LARGE_PATTERNS: (string | RegExp)[] = [
|
|
168
|
+
"tool catalog too large",
|
|
169
|
+
"tool registration too large",
|
|
170
|
+
"too many tools",
|
|
171
|
+
"message too large",
|
|
172
|
+
"payload too large",
|
|
173
|
+
"request too large",
|
|
174
|
+
// Size cue required somewhere: a bare "request exceeds ... limit" (concurrency/quota
|
|
175
|
+
// shape) must NOT match, but "request body/size exceeds ... limit" and
|
|
176
|
+
// "request exceeds maximum allowed size" are deterministic overflow (WP3 r1/r2).
|
|
177
|
+
/request exceeds .*size/,
|
|
178
|
+
/request (?:body|size) exceeds .*(?:size|limit)/,
|
|
179
|
+
"maximum allowed size",
|
|
180
|
+
];
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* True when a resource_exhausted detail names a request-size overflow rather than quota.
|
|
184
|
+
* Quota/rate cues are rejected FIRST: "resource_exhausted while loading tool catalog: quota
|
|
185
|
+
* exhausted" is rate limiting, not a too-large request, even though it mentions the catalog.
|
|
186
|
+
*/
|
|
187
|
+
export function isCursorRequestTooLargeDetail(lowerMessage: string): boolean {
|
|
188
|
+
if (QUOTA_RATE_CUES.some(cue => lowerMessage.includes(cue))) return false;
|
|
189
|
+
return REQUEST_TOO_LARGE_PATTERNS.some(pattern =>
|
|
190
|
+
typeof pattern === "string" ? lowerMessage.includes(pattern) : pattern.test(lowerMessage),
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Classify a Cursor transport/Connect/gRPC error message into an actionable category.
|
|
196
|
+
* The returned prefix string is recognized by `src/lib/errors.ts` `classifyError` keywords,
|
|
197
|
+
* so bridge-level error mapping produces the right Codex error type (rate_limit, auth, etc.).
|
|
198
|
+
*/
|
|
199
|
+
export function classifyCursorError(message: string, sizeContext?: CursorSizeContext): string {
|
|
200
|
+
const lower = message.toLowerCase();
|
|
201
|
+
|
|
202
|
+
if (isCursorBenignCancelError(message)) return "Cursor stream suspended";
|
|
203
|
+
|
|
204
|
+
if (
|
|
205
|
+
lower.includes("resource_exhausted") ||
|
|
206
|
+
lower.includes("resource exhausted")
|
|
207
|
+
) {
|
|
208
|
+
// gRPC RESOURCE_EXHAUSTED is quota/rate exhaustion unless the detail names a
|
|
209
|
+
// request-size overflow (tool catalog/registration). Only the latter is a
|
|
210
|
+
// client-fixable 400; everything else surfaces as a 429 so Codex backs off
|
|
211
|
+
// instead of hammering retries (live evidence: 6x 400 retry storm, devlog
|
|
212
|
+
// 260723_cursor_context_continuity/000_plan.md).
|
|
213
|
+
if (isCursorRequestTooLargeDetail(lower)) return "Cursor resource limit exceeded";
|
|
214
|
+
// A bare resource_exhausted with no quota cue and no size phrase is payload
|
|
215
|
+
// overflow, not rate limiting. Classifying it as 429 makes Codex back off on a
|
|
216
|
+
// failure that only compaction can fix (senpi #1009 / #1036; research unit T01).
|
|
217
|
+
// Refinement (devlog 260): plan-gated models emit the same bare shape on tiny
|
|
218
|
+
// requests — when the caller proves the request was small, keep the 429 class.
|
|
219
|
+
if (isCursorZeroTokenResourceExhausted(lower)) {
|
|
220
|
+
return bareReLooksLikeOverflow(sizeContext) ? "Cursor context limit exceeded" : "Cursor rate limit exceeded";
|
|
221
|
+
}
|
|
222
|
+
return "Cursor rate limit exceeded";
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
if (
|
|
226
|
+
lower.includes("rate limit") ||
|
|
227
|
+
lower.includes("rate-limit") ||
|
|
228
|
+
lower.includes("too many requests") ||
|
|
229
|
+
lower.includes("throttling")
|
|
230
|
+
) return "Cursor rate limit exceeded";
|
|
231
|
+
|
|
232
|
+
if (
|
|
233
|
+
lower.includes("unauthenticated") ||
|
|
234
|
+
lower.includes("unauthorized") ||
|
|
235
|
+
lower.includes("permission_denied") ||
|
|
236
|
+
lower.includes("permission denied") ||
|
|
237
|
+
lower.includes("forbidden") ||
|
|
238
|
+
lower.includes("invalid token") ||
|
|
239
|
+
lower.includes("expired token") ||
|
|
240
|
+
lower.includes("authentication") ||
|
|
241
|
+
lower.includes("access denied")
|
|
242
|
+
) return "Cursor authentication failed";
|
|
243
|
+
|
|
244
|
+
if (
|
|
245
|
+
lower.includes("unavailable") ||
|
|
246
|
+
lower.includes("overloaded") ||
|
|
247
|
+
lower.includes("temporarily") ||
|
|
248
|
+
lower.includes("server is busy")
|
|
249
|
+
) return "Cursor server overloaded";
|
|
250
|
+
|
|
251
|
+
if (
|
|
252
|
+
lower.includes("invalid") ||
|
|
253
|
+
lower.includes("not found") ||
|
|
254
|
+
lower.includes("unsupported") ||
|
|
255
|
+
lower.includes("malformed") ||
|
|
256
|
+
lower.includes("unimplemented")
|
|
257
|
+
) return "Cursor invalid request";
|
|
258
|
+
|
|
259
|
+
if (
|
|
260
|
+
lower.includes("timed out") ||
|
|
261
|
+
lower.includes("timeout") ||
|
|
262
|
+
lower.includes("etimedout") ||
|
|
263
|
+
lower.includes("deadline")
|
|
264
|
+
) return "Cursor request timed out";
|
|
265
|
+
|
|
266
|
+
if (
|
|
267
|
+
lower.includes("econnreset") ||
|
|
268
|
+
lower.includes("econnrefused") ||
|
|
269
|
+
lower.includes("goaway") ||
|
|
270
|
+
lower.includes("nghttp2") ||
|
|
271
|
+
lower.includes("socket hang up") ||
|
|
272
|
+
lower.includes("connection reset")
|
|
273
|
+
) return "Cursor connection failed";
|
|
274
|
+
|
|
275
|
+
return "Cursor upstream error";
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Produce a user-facing, secret-safe Cursor error message with an actionable category prefix.
|
|
280
|
+
* Mirrors `safeKiroErrorMessage` / `safeKiroHttpErrorMessage` in kiro-errors.ts.
|
|
281
|
+
*/
|
|
282
|
+
export function safeCursorErrorMessage(rawMessage: string, sizeContext?: CursorSizeContext): string {
|
|
283
|
+
const prefix = classifyCursorError(rawMessage, sizeContext);
|
|
284
|
+
const detail = sanitize(rawMessage)
|
|
285
|
+
.replace(/resource[_ ]exhausted/gi, "resource limit exceeded")
|
|
286
|
+
.slice(0, 500);
|
|
287
|
+
return detail ? `${prefix}: ${detail}` : prefix;
|
|
288
|
+
}
|