@iislee/opencodex 2.11.0 → 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/README.md +114 -19
- package/bin/ocx.mjs +164 -36
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-BF38heuV.js +104 -0
- package/gui/dist/assets/index-DMiI18Kv.css +1 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +19 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +376 -52
- package/src/adapters/base.ts +54 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +601 -0
- package/src/adapters/cursor/checkpoint-store.ts +303 -0
- package/src/adapters/cursor/cursor-errors.ts +129 -6
- package/src/adapters/cursor/discovery.ts +61 -4
- package/src/adapters/cursor/effort-map.ts +27 -3
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +174 -58
- package/src/adapters/cursor/live-transport.ts +609 -170
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +0 -1
- package/src/adapters/cursor/native-exec.ts +101 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +383 -65
- package/src/adapters/cursor/request-builder.ts +237 -31
- package/src/adapters/cursor/tool-definitions.ts +242 -12
- package/src/adapters/cursor/tool-result-normalize.ts +92 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +28 -1
- package/src/adapters/cursor.ts +133 -7
- package/src/adapters/google-antigravity-replay.ts +558 -34
- package/src/adapters/google-antigravity-wire.ts +43 -10
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +618 -74
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +10 -1
- package/src/adapters/kiro.ts +92 -54
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1311 -336
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +830 -56
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +104 -21
- package/src/adapters/xai-web-search.ts +185 -0
- package/src/bridge.ts +428 -61
- package/src/chat/inbound.ts +43 -19
- package/src/chat/outbound.ts +82 -26
- package/src/claude/agents-inject.ts +32 -9
- package/src/claude/context-windows.ts +21 -5
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +70 -16
- package/src/cli/account-api.ts +35 -1
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +389 -2
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +30 -6
- package/src/cli/agent.ts +45 -1
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +29 -4
- package/src/cli/claude.ts +103 -34
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +593 -0
- package/src/cli/doctor.ts +315 -43
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +20 -271
- package/src/cli/index.ts +378 -519
- package/src/cli/init.ts +4 -17
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +35 -2
- package/src/cli/models.ts +100 -14
- package/src/cli/observe.ts +92 -3
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +18 -1
- package/src/cli/provider.ts +24 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +437 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +6 -3
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +10 -3
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/v2.ts +105 -10
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1358 -21
- package/src/codex/account-label.ts +14 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-priority.ts +83 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +493 -106
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +849 -242
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +345 -32
- package/src/codex/autostart-health.ts +8 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +68 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +121 -30
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +529 -45
- package/src/codex/catalog/native-models.ts +72 -0
- package/src/codex/catalog/parsing.ts +224 -30
- package/src/codex/catalog/provider-fetch.ts +1460 -134
- package/src/codex/catalog/sync.ts +1449 -186
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +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/desired-state.ts +230 -0
- package/src/codex/features.ts +636 -39
- 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 +26 -20
- package/src/codex/history-provider.ts +231 -28
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +220 -0
- package/src/codex/inject-coordination.ts +290 -0
- package/src/codex/inject.ts +1073 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +80 -0
- package/src/codex/journal.ts +66 -4
- 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 +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +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 +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +967 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +175 -13
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +505 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1009 -28
- package/src/codex/subagent-model-fallback.ts +350 -35
- package/src/codex/sync.ts +191 -2
- 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 +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +20 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +81 -9
- package/src/config/provider-name.ts +24 -0
- package/src/config.ts +1762 -140
- package/src/generated/compatibility-version.json +3164 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +152 -29
- package/src/images/plan.ts +23 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership.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/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +153 -9
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +6 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +44 -2
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +4 -1
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +202 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +8 -2
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +398 -66
- package/src/oauth/key-providers.ts +16 -0
- package/src/oauth/kimi.ts +16 -2
- package/src/oauth/kiro.ts +50 -6
- package/src/oauth/local-token-detect.ts +11 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/store.ts +119 -21
- package/src/oauth/token-guardian.ts +9 -3
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +144 -0
- package/src/providers/context-cap.ts +22 -5
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/derive.ts +253 -6
- package/src/providers/fastwire.ts +501 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +1 -1
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +29 -0
- package/src/providers/quota.ts +1319 -38
- package/src/providers/registry.ts +1429 -111
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +42 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +11 -4
- package/src/reasoning-effort.ts +49 -1
- package/src/responses/compaction.ts +26 -1
- 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 +220 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +426 -0
- package/src/responses/schema.ts +7 -1
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +565 -27
- package/src/responses/thought-signature-replay.ts +347 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/router.ts +366 -30
- 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 +2 -29
- package/src/server/auth-cors.ts +267 -46
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +130 -56
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +426 -0
- package/src/server/claude-messages.ts +159 -43
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +865 -181
- package/src/server/lifecycle.ts +284 -13
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +398 -103
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/combo-routes.ts +62 -24
- package/src/server/management/config-routes.ts +464 -51
- package/src/server/management/context.ts +80 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +101 -32
- package/src/server/management/model-routes.ts +189 -131
- 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 +80 -4
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +764 -157
- 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 +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +288 -32
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +115 -14
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +132 -5
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +82 -42
- package/src/server/relay.ts +236 -76
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log.ts +235 -22
- 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 +204 -35
- package/src/server/responses/compact.ts +442 -55
- package/src/server/responses/core.ts +2872 -331
- package/src/server/responses/empty-completion-guard.ts +276 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +79 -4
- package/src/server/responses/input-admission.ts +185 -0
- package/src/server/responses/pacing-overload.ts +13 -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 +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +308 -0
- package/src/server/responses-custom-tool-repair.ts +282 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +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 +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +292 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +39 -38
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1111 -90
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +845 -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 +104 -1236
- package/src/update/index.ts +32 -19
- package/src/update/job.ts +442 -67
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +259 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +268 -16
- package/src/usage/log.ts +606 -41
- package/src/usage/summary.ts +177 -9
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +9 -3
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +88 -0
- package/src/web-search/executor.ts +11 -3
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +279 -50
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
|
@@ -7,12 +7,25 @@ import { McpToolDefinitionSchema, McpToolsSchema, type McpToolDefinition } from
|
|
|
7
7
|
export const OCX_RESPONSES_TOOL_PROVIDER = "opencodex-responses";
|
|
8
8
|
export const CODEX_EXEC_COMMAND_TOOL = "exec_command";
|
|
9
9
|
export const CODEX_SHELL_COMMAND_TOOL = "shell_command";
|
|
10
|
+
/** Codex Desktop unified-exec client tool. Companion of `wait`; not an `exec_command` schema alias. */
|
|
11
|
+
export const CODEX_UNIFIED_EXEC_TOOL = "exec";
|
|
12
|
+
export const CODEX_WAIT_TOOL = "wait";
|
|
10
13
|
export const CODEX_APPLY_PATCH_TOOL = "apply_patch";
|
|
14
|
+
export const CURSOR_EDIT_FILE_TOOL = "edit_file";
|
|
15
|
+
export const CURSOR_MULTI_EDIT_TOOL = "multi_edit";
|
|
16
|
+
export const CURSOR_STRUCTURED_EDIT_TOOLS = [CURSOR_EDIT_FILE_TOOL, CURSOR_MULTI_EDIT_TOOL] as const;
|
|
11
17
|
export const CURSOR_EXEC_COMMAND_TOOL = CODEX_EXEC_COMMAND_TOOL;
|
|
12
18
|
export const CODEX_SHELL_BRIDGE_TOOL_NAMES = [CODEX_EXEC_COMMAND_TOOL, CODEX_SHELL_COMMAND_TOOL] as const;
|
|
13
19
|
export const CURSOR_SHELL_ALIAS_SYSTEM_NOTE =
|
|
14
|
-
'Shell commands use the Codex shell bridge tool shown in this turn\'s catalog (`shell_command` or `exec_command`) with JSON arguments like {"cmd":"..."}. The long `mcp_opencodex-responses_*` display name is the same tool. Prefer it over Cursor-native Shell
|
|
20
|
+
'Shell commands use the Codex shell bridge tool shown in this turn\'s catalog (`shell_command` or `exec_command`) with JSON arguments like {"cmd":"..."}. The long `mcp_opencodex-responses_*` display name is the same tool. Prefer it over Cursor-native Shell.';
|
|
15
21
|
const NEIGHBOR_AGENT_TOOL_NAMES = ["Read", "Grep", "Glob", "Bash", "LS"] as const;
|
|
22
|
+
const NEIGHBOR_AGENT_TOOL_ALIASES: Record<(typeof NEIGHBOR_AGENT_TOOL_NAMES)[number], readonly string[]> = {
|
|
23
|
+
Read: ["read", "read_file"],
|
|
24
|
+
Grep: ["grep"],
|
|
25
|
+
Glob: ["glob", "find"],
|
|
26
|
+
Bash: ["bash", "shell"],
|
|
27
|
+
LS: ["ls"],
|
|
28
|
+
};
|
|
16
29
|
|
|
17
30
|
export const CURSOR_GENERIC_TOOL_USE_USER_HINT = [
|
|
18
31
|
"For generic tool-use/count demos, satisfy the request with repeated Codex shell bridge calls (`shell_command` or `exec_command`) for harmless commands.",
|
|
@@ -23,8 +36,7 @@ export const CURSOR_GENERIC_TOOL_USE_USER_HINT = [
|
|
|
23
36
|
"The Cursor bridge may suspend after the first returned bridge tool call, so emit sibling calls together before any result is needed.",
|
|
24
37
|
"If parallel emission is unavailable, continue with separate shell-bridge calls until the requested count has returned.",
|
|
25
38
|
"Do not use `tool_search`, external MCP, or resource discovery just to pad the count unless explicitly asked.",
|
|
26
|
-
"Do not suggest or switch to neighboring-agent tools such as `Grep`, `Read`, `Glob`, `Bash`, or `LS` unless this turn's catalog lists those exact names.",
|
|
27
|
-
"Never tell the user that shell or read access is blocked, disabled, or denied unless the Codex shell bridge tool itself fails. Do not narrate Cursor-native Shell/Read routing.",
|
|
39
|
+
"Do not suggest or switch to neighboring-agent tools such as `Grep`, `Read`, `Glob`, `Bash`, or `LS` unless this turn's catalog lists those exact names or an equivalent listed client tool.",
|
|
28
40
|
].join(" ");
|
|
29
41
|
|
|
30
42
|
export const CURSOR_EXEC_COMMAND_INPUT_SCHEMA = {
|
|
@@ -41,6 +53,47 @@ export const CURSOR_EXEC_COMMAND_INPUT_SCHEMA = {
|
|
|
41
53
|
additionalProperties: false,
|
|
42
54
|
} as const;
|
|
43
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Structured single-replacement schema advertised to Cursor models in addition to the freeform
|
|
58
|
+
* `apply_patch` tool. Cursor-trained models reliably emit exact-match replacements (the native
|
|
59
|
+
* Edit shape) but cannot produce Codex's freeform patch grammar, so every file edit attempt on the
|
|
60
|
+
* Cursor route produced malformed `apply_patch` payloads that the Codex client rejected locally
|
|
61
|
+
* (#1017). Calls to this tool are converted server-side into a valid apply_patch payload.
|
|
62
|
+
*/
|
|
63
|
+
export const CURSOR_EDIT_FILE_INPUT_SCHEMA = {
|
|
64
|
+
type: "object",
|
|
65
|
+
properties: {
|
|
66
|
+
file_path: { type: "string", description: "Path of the file to edit, relative to the workspace root." },
|
|
67
|
+
old_string: { type: "string", description: "Exact text to replace. Must match the current file content, including line breaks." },
|
|
68
|
+
new_string: { type: "string", description: "Replacement text. Empty removes the matched text." },
|
|
69
|
+
},
|
|
70
|
+
required: ["file_path", "old_string", "new_string"],
|
|
71
|
+
additionalProperties: false,
|
|
72
|
+
} as const;
|
|
73
|
+
|
|
74
|
+
/** Structured multi-replacement schema; mirrors Cursor's native MultiEdit shape. */
|
|
75
|
+
export const CURSOR_MULTI_EDIT_INPUT_SCHEMA = {
|
|
76
|
+
type: "object",
|
|
77
|
+
properties: {
|
|
78
|
+
file_path: { type: "string", description: "Path of the file to edit, relative to the workspace root." },
|
|
79
|
+
edits: {
|
|
80
|
+
type: "array",
|
|
81
|
+
items: {
|
|
82
|
+
type: "object",
|
|
83
|
+
properties: {
|
|
84
|
+
old_string: { type: "string", description: "Exact text to replace. Must match the current file content, including line breaks." },
|
|
85
|
+
new_string: { type: "string", description: "Replacement text. Empty removes the matched text." },
|
|
86
|
+
},
|
|
87
|
+
required: ["old_string", "new_string"],
|
|
88
|
+
additionalProperties: false,
|
|
89
|
+
},
|
|
90
|
+
description: "Ordered replacement edits for this file. Each old_string must match the current file content.",
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
required: ["file_path", "edits"],
|
|
94
|
+
additionalProperties: false,
|
|
95
|
+
} as const;
|
|
96
|
+
|
|
44
97
|
/**
|
|
45
98
|
* Responses/Codex-side schema used ONLY for arg-key normalization after Cursor returns a call.
|
|
46
99
|
* Cursor models are trained to emit `cmd`; Codex `shell_command` / `exec_command` validate
|
|
@@ -123,6 +176,59 @@ export function isBareCodexShellBridgeTool(tool: Pick<OcxTool, "namespace" | "na
|
|
|
123
176
|
return !tool.namespace && isCodexShellBridgeToolName(tool.name);
|
|
124
177
|
}
|
|
125
178
|
|
|
179
|
+
function isCursorResponsesProvider(namespace: string | undefined): boolean {
|
|
180
|
+
return !namespace || namespace === OCX_RESPONSES_TOOL_PROVIDER;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
const CURSOR_EXECUTION_PATH_TOOL_NAMES = [
|
|
184
|
+
CODEX_UNIFIED_EXEC_TOOL,
|
|
185
|
+
CODEX_EXEC_COMMAND_TOOL,
|
|
186
|
+
CODEX_SHELL_COMMAND_TOOL,
|
|
187
|
+
] as const;
|
|
188
|
+
|
|
189
|
+
/** True for the Codex execution path that must survive Cursor transport truncation. */
|
|
190
|
+
export function isCursorExecutionPathTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
|
|
191
|
+
return isCursorResponsesProvider(tool.namespace)
|
|
192
|
+
&& (CURSOR_EXECUTION_PATH_TOOL_NAMES as readonly string[]).includes(tool.name);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/** `wait` only resumes a yielded exec cell; it is unusable without an execution-path tool. */
|
|
196
|
+
export function isCursorWaitTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
|
|
197
|
+
return isCursorResponsesProvider(tool.namespace) && tool.name === CODEX_WAIT_TOOL;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* True for Codex's unified-exec "code mode" tool: a freeform `exec` whose body is JavaScript
|
|
202
|
+
* evaluated in a V8 isolate, not a shell command string.
|
|
203
|
+
*/
|
|
204
|
+
export function isCursorCodeModeExecTool(
|
|
205
|
+
tool: Pick<OcxTool, "namespace" | "name" | "freeform">,
|
|
206
|
+
): boolean {
|
|
207
|
+
return isCursorResponsesProvider(tool.namespace)
|
|
208
|
+
&& tool.name === CODEX_UNIFIED_EXEC_TOOL
|
|
209
|
+
&& tool.freeform === true;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Codex code mode advertises ONE freeform `exec` tool and no bare shell bridge. Shell, file
|
|
214
|
+
* edits, and MCP calls are reachable only as nested `tools.<name>(...)` helpers described inside
|
|
215
|
+
* that tool's own description, so a flat catalog scan cannot see them.
|
|
216
|
+
*
|
|
217
|
+
* This matters because the shell-bridge guidance below is written for a flat catalog. Emitting
|
|
218
|
+
* "call \`exec_command\`" into a code-mode turn names a top-level tool that does not exist: the
|
|
219
|
+
* model calls it, gets nothing back, and burns turns rediscovering the real contract from error
|
|
220
|
+
* messages (empty output until \`text()\` is called, \`require is not defined\` because the isolate
|
|
221
|
+
* is not Node, \`apply_patch\` rejected because it too is only a nested helper here).
|
|
222
|
+
*/
|
|
223
|
+
export function cursorRequestUsesCodeMode(
|
|
224
|
+
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
225
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
226
|
+
): boolean {
|
|
227
|
+
const catalog = tools ?? [];
|
|
228
|
+
const visible = catalog.filter(tool => cursorToolAllowedByChoice(tool, toolChoice, catalog));
|
|
229
|
+
return visible.some(isCursorCodeModeExecTool) && !visible.some(isBareCodexShellBridgeTool);
|
|
230
|
+
}
|
|
231
|
+
|
|
126
232
|
/** @deprecated Prefer isBareCodexShellBridgeTool; kept for older call sites/tests. */
|
|
127
233
|
function isBareCodexExecCommandTool(tool: Pick<OcxTool, "namespace" | "name">): boolean {
|
|
128
234
|
return isBareCodexShellBridgeTool(tool);
|
|
@@ -132,6 +238,12 @@ export function cursorRequestHasShellAlias(tools: readonly Pick<OcxTool, "namesp
|
|
|
132
238
|
return tools?.some(isBareCodexExecCommandTool) ?? false;
|
|
133
239
|
}
|
|
134
240
|
|
|
241
|
+
function cursorRequestHasExecutionPath(
|
|
242
|
+
tools: readonly Pick<OcxTool, "namespace" | "name">[] | undefined,
|
|
243
|
+
): boolean {
|
|
244
|
+
return tools?.some(isCursorExecutionPathTool) ?? false;
|
|
245
|
+
}
|
|
246
|
+
|
|
135
247
|
export function cursorRequestAdvertisesApplyPatch(
|
|
136
248
|
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
137
249
|
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
@@ -140,6 +252,73 @@ export function cursorRequestAdvertisesApplyPatch(
|
|
|
140
252
|
return catalog.some(tool => !tool.namespace && tool.name === CODEX_APPLY_PATCH_TOOL && tool.freeform === true && cursorToolAllowedByChoice(tool, toolChoice, catalog));
|
|
141
253
|
}
|
|
142
254
|
|
|
255
|
+
export function isCursorStructuredEditToolName(name: string): boolean {
|
|
256
|
+
return (CURSOR_STRUCTURED_EDIT_TOOLS as readonly string[]).includes(name);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/** Internal provenance gate for synthetic edits after prompt filtering and catalog budgeting. */
|
|
260
|
+
export function isCursorSyntheticStructuredEditTool(
|
|
261
|
+
tool: Pick<OcxTool, "namespace" | "name" | "cursorStructuredEdit">,
|
|
262
|
+
): boolean {
|
|
263
|
+
return !tool.namespace && tool.cursorStructuredEdit === true && isCursorStructuredEditToolName(tool.name);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Synthetic structured edit tools for the Cursor route (#1017).
|
|
268
|
+
*
|
|
269
|
+
* Codex exposes `apply_patch` as a freeform custom tool whose body must be the exact Codex patch
|
|
270
|
+
* grammar (`*** Begin Patch` envelope, `@@` hunks, `-`/`+` prefixes). Cursor-trained models are
|
|
271
|
+
* trained on exact-match edit tools instead and emit malformed patch text on every attempt, which
|
|
272
|
+
* the Codex client then rejects locally ("invalid hunk"). When the request advertises the freeform
|
|
273
|
+
* `apply_patch` tool, also advertise Cursor-native-shaped `edit_file` / `multi_edit` tools; the
|
|
274
|
+
* adapter converts their exact-match replacements into a valid apply_patch payload (see
|
|
275
|
+
* protobuf-events.translateStructuredEditCall).
|
|
276
|
+
*
|
|
277
|
+
* Never widened when the caller pinned an explicit tool choice: a forced `apply_patch` selection
|
|
278
|
+
* must not gain sibling tools the client did not ask for.
|
|
279
|
+
*/
|
|
280
|
+
export function cursorStructuredEditTools(
|
|
281
|
+
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
282
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
283
|
+
): OcxTool[] {
|
|
284
|
+
if (!cursorRequestAdvertisesApplyPatch(tools, toolChoice)) return [];
|
|
285
|
+
if (toolChoice && toolChoice !== "auto" && toolChoice !== "required") return [];
|
|
286
|
+
// Never shadow an already-advertised bare tool with the same name (a client catalog could
|
|
287
|
+
// legitimately expose its own `edit_file` / `multi_edit` MCP-style tools).
|
|
288
|
+
const existingBareNames = new Set(
|
|
289
|
+
(tools ?? []).filter(tool => !tool.namespace).map(tool => tool.name),
|
|
290
|
+
);
|
|
291
|
+
const candidates: OcxTool[] = [
|
|
292
|
+
{
|
|
293
|
+
name: CURSOR_EDIT_FILE_TOOL,
|
|
294
|
+
cursorStructuredEdit: true,
|
|
295
|
+
description:
|
|
296
|
+
"Replace one block of text in a file. OpenCodex converts the replacement into a Codex apply_patch change. Copy old_string and new_string with their exact leading whitespace — Codex may locate a line after trimming indent, but it writes new_string verbatim, so stripped indent silently corrupts the file. An empty old_string with a non-empty new_string creates a new file (Add File). If the same text appears more than once, the first match is updated. Matching is line-based, so an edit cannot add or remove only the file's final newline, and old_string/new_string that are identical after line normalization are rejected as a no-op.",
|
|
297
|
+
parameters: { ...CURSOR_EDIT_FILE_INPUT_SCHEMA },
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
name: CURSOR_MULTI_EDIT_TOOL,
|
|
301
|
+
cursorStructuredEdit: true,
|
|
302
|
+
description:
|
|
303
|
+
"Apply several text replacements to one file. OpenCodex converts them into one Codex apply_patch change. Copy each old_string/new_string with exact leading whitespace. If a later edit's old_string is the text after an earlier replacement, OpenCodex folds those edits into one original-file hunk. Independent edits stay separate hunks. An empty old_string with a non-empty new_string creates a new file (Add File); do not mix that with an independent Update on the same path. If the same text appears more than once, the first match is updated. Matching is line-based, so an edit cannot add or remove only the file's final newline, and identical old/new after line normalization are rejected as a no-op.",
|
|
304
|
+
parameters: { ...CURSOR_MULTI_EDIT_INPUT_SCHEMA },
|
|
305
|
+
},
|
|
306
|
+
];
|
|
307
|
+
return candidates.filter(tool => !existingBareNames.has(tool.name));
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* True when this request actually advertises the synthetic structured edit tools (`edit_file` /
|
|
312
|
+
* `multi_edit`) — i.e. a freeform `apply_patch` is advertised, no tool-choice pin blocks widening,
|
|
313
|
+
* and neither name is shadowed by an existing bare tool in the client catalog.
|
|
314
|
+
*/
|
|
315
|
+
export function cursorRequestAdvertisesStructuredEdits(
|
|
316
|
+
tools: readonly Pick<OcxTool, "namespace" | "name" | "freeform">[] | undefined,
|
|
317
|
+
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
318
|
+
): boolean {
|
|
319
|
+
return cursorStructuredEditTools(tools, toolChoice).length > 0;
|
|
320
|
+
}
|
|
321
|
+
|
|
143
322
|
export function cursorToolWireName(tool: Pick<OcxTool, "namespace" | "name">): string {
|
|
144
323
|
return namespacedToolName(tool.namespace, tool.name);
|
|
145
324
|
}
|
|
@@ -157,6 +336,26 @@ export function normalizeCursorWireName(name: string): string {
|
|
|
157
336
|
return name.startsWith(CURSOR_MCP_DISPLAY_PREFIX) ? name.slice(CURSOR_MCP_DISPLAY_PREFIX.length) : name;
|
|
158
337
|
}
|
|
159
338
|
|
|
339
|
+
/**
|
|
340
|
+
* #2305: some models emit a TEXTUAL pseudo tool call ("[TOOL_CALL]name[ARGS]{...}")
|
|
341
|
+
* instead of a real frame, using Cursor's display alias as the name. Text-mode clients
|
|
342
|
+
* (Pi) parse that text and then cannot dispatch the undeclared display name. Rewrite the
|
|
343
|
+
* display alias to the advertised wire name ONLY inside the marker pair — prose that
|
|
344
|
+
* merely mentions the alias stays untouched, and the scope guard is the exact
|
|
345
|
+
* `mcp_${OCX_RESPONSES_TOOL_PROVIDER}_` prefix, never generic `mcp_`.
|
|
346
|
+
* Known limit (recorded in devlog 230): a marker split across two streaming deltas is
|
|
347
|
+
* not rewritten; tail-buffering is deferred until a live trace shows split markers.
|
|
348
|
+
*/
|
|
349
|
+
const CURSOR_TEXT_TOOL_MARKER = new RegExp(
|
|
350
|
+
String.raw`\[TOOL_CALL\](${CURSOR_MCP_DISPLAY_PREFIX.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}[^\[\]]+)\[ARGS\]`,
|
|
351
|
+
"g",
|
|
352
|
+
);
|
|
353
|
+
|
|
354
|
+
export function normalizeCursorTextToolMarkers(text: string): string {
|
|
355
|
+
if (!text.includes(CURSOR_MCP_DISPLAY_PREFIX)) return text;
|
|
356
|
+
return text.replace(CURSOR_TEXT_TOOL_MARKER, (_match, name: string) => `[TOOL_CALL]${normalizeCursorWireName(name)}[ARGS]`);
|
|
357
|
+
}
|
|
358
|
+
|
|
160
359
|
export function responsesToolNameFromCursorWire(name: string, cursorToolNameMap?: ReadonlyMap<string, string>): string {
|
|
161
360
|
const normalized = normalizeCursorWireName(name);
|
|
162
361
|
if (!cursorToolNameMap) return normalized;
|
|
@@ -286,7 +485,7 @@ export function shouldUseNativeExecOnlyForGenericToolUse(
|
|
|
286
485
|
text: string,
|
|
287
486
|
): boolean {
|
|
288
487
|
const trimmed = text.trim();
|
|
289
|
-
if (trimmed.length === 0 || !
|
|
488
|
+
if (trimmed.length === 0 || !cursorRequestHasExecutionPath(tools) || !isGenericToolUseCountDemoPrompt(trimmed)) return false;
|
|
290
489
|
return !/\b(?:mcp|resource|resources|tool_search|plugin|plugins|app connector|github)\b/i.test(trimmed)
|
|
291
490
|
&& !/(?:리소스|플러그인|깃허브|github)/i.test(trimmed);
|
|
292
491
|
}
|
|
@@ -297,7 +496,7 @@ export function cursorToolsForActivePrompt<T extends Pick<OcxTool, "namespace" |
|
|
|
297
496
|
toolChoice?: OcxRequestOptions["toolChoice"],
|
|
298
497
|
): readonly T[] | undefined {
|
|
299
498
|
if (!shouldUseNativeExecOnlyForGenericToolUse(tools, activeText)) return tools;
|
|
300
|
-
const execTools = tools?.filter(
|
|
499
|
+
const execTools = tools?.filter(isCursorExecutionPathTool);
|
|
301
500
|
const catalog = tools ?? [];
|
|
302
501
|
if (execTools?.length && !execTools.some(tool => cursorToolAllowedByChoice(tool, toolChoice, catalog))) return tools;
|
|
303
502
|
return execTools && execTools.length > 0 ? execTools : tools;
|
|
@@ -352,7 +551,12 @@ export function nonEmptyShellBridgeCommandFromArgs(
|
|
|
352
551
|
}
|
|
353
552
|
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return undefined;
|
|
354
553
|
const record = parsed as Record<string, unknown>;
|
|
355
|
-
|
|
554
|
+
const requiredKeys = shellBridgeRequiredCommandKeys(toolName, schema);
|
|
555
|
+
const candidateKeys = new Set<"cmd" | "command">([
|
|
556
|
+
...requiredKeys,
|
|
557
|
+
requiredKeys.includes("cmd") ? "command" : "cmd",
|
|
558
|
+
]);
|
|
559
|
+
for (const key of candidateKeys) {
|
|
356
560
|
const value = record[key];
|
|
357
561
|
if (typeof value === "string" && value.trim().length > 0) return value.trim();
|
|
358
562
|
}
|
|
@@ -385,9 +589,14 @@ function quotedNames(names: readonly string[]): string {
|
|
|
385
589
|
return names.map(name => `\`${name}\``).join(", ");
|
|
386
590
|
}
|
|
387
591
|
|
|
592
|
+
function advertisedCoversNeighbor(wireNames: readonly string[], neighbor: (typeof NEIGHBOR_AGENT_TOOL_NAMES)[number]): boolean {
|
|
593
|
+
const advertised = new Set(wireNames.map(name => name.toLowerCase()));
|
|
594
|
+
if (advertised.has(neighbor.toLowerCase())) return true;
|
|
595
|
+
return NEIGHBOR_AGENT_TOOL_ALIASES[neighbor].some(alias => advertised.has(alias.toLowerCase()));
|
|
596
|
+
}
|
|
597
|
+
|
|
388
598
|
function unavailableNeighborAgentToolNames(wireNames: readonly string[]): string[] {
|
|
389
|
-
|
|
390
|
-
return NEIGHBOR_AGENT_TOOL_NAMES.filter(name => !advertised.has(name));
|
|
599
|
+
return NEIGHBOR_AGENT_TOOL_NAMES.filter(name => !advertisedCoversNeighbor(wireNames, name));
|
|
391
600
|
}
|
|
392
601
|
|
|
393
602
|
function discoveryToolLabel(wireNames: readonly string[]): string | undefined {
|
|
@@ -413,14 +622,25 @@ export function buildCursorToolGuidanceSystemNote(
|
|
|
413
622
|
const listedNames = quotedNames(wireNames);
|
|
414
623
|
const shellBridgeNames = wireNames.filter(isCodexShellBridgeToolName);
|
|
415
624
|
const hasBareExec = shellBridgeNames.length > 0;
|
|
625
|
+
const codeMode = cursorRequestUsesCodeMode(tools, toolChoice);
|
|
626
|
+
// Code mode describes how the freeform exec tool works; it does not suppress the rest of the
|
|
627
|
+
// catalog. A turn can advertise freeform `exec` AND ordinary top-level tools at once, and
|
|
628
|
+
// telling the model those are "not separate top-level tools" would make it refuse tools that
|
|
629
|
+
// are right there in its catalog. Name the ones that stay callable instead.
|
|
630
|
+
const codeModeOtherTopLevelNames = codeMode
|
|
631
|
+
? wireNames.filter(name => name !== CODEX_UNIFIED_EXEC_TOOL && !isCodexShellBridgeToolName(name))
|
|
632
|
+
: [];
|
|
416
633
|
const shellBridgeLabel = quotedNames(shellBridgeNames.length > 0 ? shellBridgeNames : [...CODEX_SHELL_BRIDGE_TOOL_NAMES]);
|
|
417
634
|
const hasApplyPatch = cursorRequestAdvertisesApplyPatch(tools, toolChoice);
|
|
635
|
+
const structuredEditNames = tools
|
|
636
|
+
?.filter(tool => !tool.namespace && isCursorStructuredEditToolName(tool.name))
|
|
637
|
+
.map(tool => tool.name) ?? [];
|
|
418
638
|
const discoveryTools = discoveryToolLabel(wireNames);
|
|
419
639
|
const unavailableNeighborNames = unavailableNeighborAgentToolNames(wireNames);
|
|
420
640
|
// Host-shell-neutral: the Codex client executes bridge commands, and may differ from
|
|
421
641
|
// the OpenCodex proxy OS (LAN/SSH remote-proxy). Always cover PowerShell 5.1 pitfalls.
|
|
422
642
|
const hostShellNote = hasBareExec
|
|
423
|
-
? "Match shell syntax to the Codex client host that runs the bridge (not only the proxy OS). Windows PowerShell 5.1: no CMD `cd /d`, no bash heredocs (`<<EOF`); `&&`/`||` are unsupported parser errors — prefer the bridge working-directory argument for directory changes, and use `if ($?) { ... }` for success-gated follow-up steps; do not treat `;` as a substitute for `&&`. POSIX: use portable commands. After a shell failure, make at most one corrected bridge attempt, then report the error and stop — do not repeat equivalent failing commands."
|
|
643
|
+
? "Match shell syntax to the Codex client host that runs the bridge (not only the proxy OS). Windows PowerShell 5.1: no CMD `cd /d`, no bash heredocs (`<<EOF`); `&&`/`||` are unsupported parser errors — prefer the bridge working-directory argument for directory changes, and use `if ($?) { ... }` for success-gated follow-up steps; do not treat `;` as a substitute for `&&`. POSIX: use portable commands (`cat`/`ls`/`rg`); never emit Get-Content or Get-ChildItem unless the host shell is PowerShell. After a shell failure, make at most one corrected bridge attempt, then report the error and stop — do not repeat equivalent failing commands."
|
|
424
644
|
: undefined;
|
|
425
645
|
const notes = [
|
|
426
646
|
`Cursor tool calls: available tool names are exactly ${listedNames}.`,
|
|
@@ -428,6 +648,14 @@ export function buildCursorToolGuidanceSystemNote(
|
|
|
428
648
|
unavailableNeighborNames.length > 0
|
|
429
649
|
? `This turn does not expose neighboring-agent tool names ${quotedNames(unavailableNeighborNames)}; do not call or suggest them unless the catalog lists them.`
|
|
430
650
|
: undefined,
|
|
651
|
+
// Code mode: shell/edit/MCP live inside freeform `exec` as nested helpers. Without this the
|
|
652
|
+
// model probes for a top-level shell tool that is not there.
|
|
653
|
+
codeMode
|
|
654
|
+
? `\`${CODEX_UNIFIED_EXEC_TOOL}\` is Codex code mode: its body is JavaScript evaluated in a V8 isolate, not a shell command and not Node. Shell, file edits, and MCP are nested helpers called INSIDE that body as \`await tools.<name>(...)\`, for example \`await tools.exec_command({cmd: \"ls\"})\`. Read the tool description and the isolate global \`ALL_TOOLS\` (not \`tools.ALL_TOOLS\`) for helpers this turn provides; absence from the top-level catalog or from \`exec\`'s description is not absence. Those nested helpers are not themselves top-level tools, so do not call \`exec_command\` or \`shell_command\` at the top level here${codeModeOtherTopLevelNames.length > 0 ? `; every other tool this turn lists, including ${quotedNames(codeModeOtherTopLevelNames)}, remains callable at the top level as usual` : ""}.`
|
|
655
|
+
: undefined,
|
|
656
|
+
codeMode
|
|
657
|
+
? "In code mode the isolate returns nothing on its own: call `text(...)` (or `notify(...)`) on any value you need to see, or the call completes with empty output. There is no `require`, no `module`, and no filesystem or network globals; reach the host only through the nested helpers."
|
|
658
|
+
: undefined,
|
|
431
659
|
hasBareExec
|
|
432
660
|
? `${shellBridgeLabel} is the Codex Responses shell bridge for this turn, exposed through Cursor's tool protocol; it is not an external MCP server tool. \`shell_command\` and \`exec_command\` are aliases of the same bridge.`
|
|
433
661
|
: undefined,
|
|
@@ -435,7 +663,7 @@ export function buildCursorToolGuidanceSystemNote(
|
|
|
435
663
|
? "Your tool list may display it under a longer `mcp_opencodex-responses_shell_command` / `mcp_opencodex-responses_exec_command` name; those are the SAME tool — call whichever your list shows, and do not comment on the naming difference to the user."
|
|
436
664
|
: undefined,
|
|
437
665
|
hasBareExec
|
|
438
|
-
?
|
|
666
|
+
? `Prefer the Codex shell bridge over Cursor-native Shell/Read. If a Cursor-native file read, directory listing, grep, or shell operation is rejected, continue with the listed catalog tool ${shellBridgeLabel}.`
|
|
439
667
|
: undefined,
|
|
440
668
|
hostShellNote,
|
|
441
669
|
"Cursor product features (Chronicle, screen recording, Notes, Plans, background agents) are available only if this turn's catalog lists a matching tool; do not offer or promise them otherwise.",
|
|
@@ -443,7 +671,9 @@ export function buildCursorToolGuidanceSystemNote(
|
|
|
443
671
|
? `For file read/search/listing, use ${shellBridgeLabel} when no more specific listed tool is available.`
|
|
444
672
|
: undefined,
|
|
445
673
|
hasApplyPatch
|
|
446
|
-
?
|
|
674
|
+
? structuredEditNames.length > 0
|
|
675
|
+
? `For file edits, prefer the structured edit tools ${quotedNames(structuredEditNames)} — they take replacements that OpenCodex converts into Codex \`apply_patch\` changes. Include exact leading whitespace in old_string/new_string. Use \`apply_patch\` directly only with a \`*** Begin Patch\` envelope and bare \`@@\` hunks (never git-style \`@@ -n,m +n,m @@\`); never emit patch-like plain text as tool arguments.`
|
|
676
|
+
: "For file edits, use the `apply_patch` tool, not built-in file write/delete tools."
|
|
447
677
|
: undefined,
|
|
448
678
|
hasBareExec
|
|
449
679
|
? "For tool-count demos, each counted tool must be a separate Codex shell-bridge invocation/result; do not collapse several requested tools into one chained shell command."
|
|
@@ -457,7 +687,7 @@ export function buildCursorToolGuidanceSystemNote(
|
|
|
457
687
|
: undefined,
|
|
458
688
|
"Do not count or report a tool call unless a tool result was actually returned.",
|
|
459
689
|
hasBareExec
|
|
460
|
-
? `If a Cursor-native file read, directory listing, grep, or shell operation is rejected by the runtime,
|
|
690
|
+
? `If a Cursor-native file read, directory listing, grep, or shell operation is rejected by the runtime, use ${shellBridgeLabel} with an equivalent host-shell-safe command (POSIX: \`cat\`/\`ls\`/\`rg\`; Windows PowerShell: \`Get-Content\`/\`Get-ChildItem\`/\`Select-String\`). For file edits, use ${structuredEditNames.length > 0 ? `the structured edit tools (${quotedNames(structuredEditNames)}) or ` : ""}\`apply_patch\` when available.`
|
|
461
691
|
: undefined,
|
|
462
692
|
].filter((note): note is string => typeof note === "string");
|
|
463
693
|
return notes.join(" ");
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor tool-result normalization for Computer Use / node_repl surfaces (#1920/#1866).
|
|
3
|
+
*
|
|
4
|
+
* Scoped re-implementation of PR #1920 per the 260818 campaign disposition
|
|
5
|
+
* (REDESIGN-SMALL: "apply formatted.text at native toolResultPart + decode test").
|
|
6
|
+
* Only empty-output and known-failure-state normalization ships here; screenshot
|
|
7
|
+
* stripping and AXTree text compaction from the original PR are deliberately out
|
|
8
|
+
* of scope (the native path already bounds step size by real serialized bytes,
|
|
9
|
+
* dropping images oldest-first — see toolCallStep in protobuf-request.ts).
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
const COMPUTER_USE_TOOL_NAMES = new Set([
|
|
13
|
+
"node_repl",
|
|
14
|
+
"node_repl__js",
|
|
15
|
+
"mcp__node_repl__js",
|
|
16
|
+
"get_app_state",
|
|
17
|
+
"list_apps",
|
|
18
|
+
"screenshot",
|
|
19
|
+
"computer_use",
|
|
20
|
+
]);
|
|
21
|
+
|
|
22
|
+
function isNodeReplOrComputerUseTool(toolName?: string, toolNamespace?: string): boolean {
|
|
23
|
+
if (toolNamespace && (toolNamespace === "mcp__node_repl" || toolNamespace.includes("node_repl") || toolNamespace.includes("computer_use"))) {
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
if (!toolName) return false;
|
|
27
|
+
const lower = toolName.toLowerCase();
|
|
28
|
+
if (COMPUTER_USE_TOOL_NAMES.has(lower)) return true;
|
|
29
|
+
return lower.startsWith("mcp__node_repl") || lower.startsWith("mcp__computer_use");
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** Failure states the Computer Use / node_repl runtime reports as PLAIN TEXT inside a non-error result. */
|
|
33
|
+
const RUNTIME_FAILURE_GUIDANCE: ReadonlyArray<{ marker: string; guidance: string }> = [
|
|
34
|
+
{
|
|
35
|
+
marker: "SkyComputerUseError",
|
|
36
|
+
guidance: "The Computer Use runtime rejected this action. Re-check application state with get_app_state before retrying.",
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
marker: "sky is not defined",
|
|
40
|
+
guidance: "The sky binding is unavailable in this context; Computer Use calls only work inside the privileged node_repl session.",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
marker: "has already been declared",
|
|
44
|
+
guidance: "The node_repl session keeps earlier declarations; rename the variable or use var/reassignment instead of redeclaring.",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
marker: "unsupported import in exec",
|
|
48
|
+
guidance: "Imports are not available in this exec context; use the injected globals instead.",
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
|
|
52
|
+
/** Matches exec wrappers whose only payload is an empty-output marker. */
|
|
53
|
+
const EMPTY_EXEC_OUTPUT_REGEX = /^(?:(?:Script completed|Script failed|Command finished|Execution finished)[^\n]*\n+)?(?:Wall time[^\n]*\n+)?(?:Output:\s*)?(?:<empty>)?\s*$/;
|
|
54
|
+
|
|
55
|
+
export interface NormalizedToolResultText {
|
|
56
|
+
text: string;
|
|
57
|
+
isError: boolean;
|
|
58
|
+
/** True when normalization changed either field (lets callers skip work on the common path). */
|
|
59
|
+
changed: boolean;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Normalize a Cursor-bound tool-result TEXT payload:
|
|
64
|
+
* - blank / empty-exec-wrapper output on Computer Use or node_repl tools becomes an
|
|
65
|
+
* actionable error instead of an empty string the model silently accepts;
|
|
66
|
+
* - known runtime failure states reported as plain text are marked isError with a
|
|
67
|
+
* one-line recovery hint appended.
|
|
68
|
+
* Everything else passes through byte-identical.
|
|
69
|
+
*/
|
|
70
|
+
export function normalizeCursorToolResultText(
|
|
71
|
+
text: string,
|
|
72
|
+
options: { toolName?: string; toolNamespace?: string; isError?: boolean } = {},
|
|
73
|
+
): NormalizedToolResultText {
|
|
74
|
+
const isError = options.isError === true;
|
|
75
|
+
const computerUse = isNodeReplOrComputerUseTool(options.toolName, options.toolNamespace);
|
|
76
|
+
if (computerUse && EMPTY_EXEC_OUTPUT_REGEX.test(text.trim())) {
|
|
77
|
+
return {
|
|
78
|
+
text: "[empty output: the tool ran but produced no stdout or return value. Verify application state with get_app_state, or make the script emit output.]",
|
|
79
|
+
isError: true,
|
|
80
|
+
changed: true,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
if (!isError) {
|
|
84
|
+
for (const { marker, guidance } of RUNTIME_FAILURE_GUIDANCE) {
|
|
85
|
+
if (text.includes(marker)) {
|
|
86
|
+
return { text: `${text}\n[recovery: ${guidance}]`, isError: true, changed: true };
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return { text, isError, changed: false };
|
|
91
|
+
}
|
|
92
|
+
|
|
@@ -12,16 +12,33 @@ export interface CursorTransport {
|
|
|
12
12
|
* accepted is never replayed. Absent (undefined) is treated as "committed" — safe by default.
|
|
13
13
|
*/
|
|
14
14
|
requestCommitted?(): boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Last ConversationStateStructure captured from conversationCheckpointUpdate on this transport.
|
|
17
|
+
* Test and adapter seams use this instead of reaching into LiveCursorTransport.
|
|
18
|
+
*/
|
|
19
|
+
capturedConversationCheckpoint?(): Uint8Array | undefined;
|
|
15
20
|
}
|
|
16
21
|
|
|
17
22
|
export interface CursorTransportFactoryInput {
|
|
18
23
|
provider: OcxProviderConfig;
|
|
19
24
|
translatorBudget: TranslatorBudget;
|
|
20
25
|
headers?: Headers;
|
|
26
|
+
/** Router-prepared fetch that preserves provider overrides and per-request pacing. */
|
|
27
|
+
fetch?: typeof globalThis.fetch;
|
|
21
28
|
/** Pre-first-frame deadline (dial + first server frame). Defaults to 30s when omitted. */
|
|
22
29
|
firstFrameTimeoutMs?: number;
|
|
23
30
|
/** Grace (ms) between close() and the force-destroy fallback after a first-frame timeout. Defaults to 1s. */
|
|
24
31
|
timeoutDestroyGraceMs?: number;
|
|
32
|
+
/**
|
|
33
|
+
* T04 watchdog: maximum inbound decoded-frame silence (ms) after the first frame before the
|
|
34
|
+
* turn is failed. Defaults to 30s.
|
|
35
|
+
*/
|
|
36
|
+
streamSilenceFailMs?: number;
|
|
37
|
+
/**
|
|
38
|
+
* T04 watchdog: maximum heartbeat/checkpoint-only traffic (ms) without turn progress before
|
|
39
|
+
* the turn is failed. Defaults to 90s.
|
|
40
|
+
*/
|
|
41
|
+
streamHeartbeatOnlyFailMs?: number;
|
|
25
42
|
/**
|
|
26
43
|
* Grace window (ms) before a drained client-tool turn is finalized, so a sibling tool call
|
|
27
44
|
* announced in a later receive chunk can revoke a premature finalize. Defaults to 50ms.
|
|
@@ -33,6 +50,11 @@ export interface CursorTransportFactoryInput {
|
|
|
33
50
|
* native local exec authorization because the text is caller-controlled.
|
|
34
51
|
*/
|
|
35
52
|
requestDeclaresFullAccess?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Stable Cursor Connect `x-session-id` across transport rebuilds for the same
|
|
55
|
+
* client thread. Distinct from the per-transport native-exec/shell owner.
|
|
56
|
+
*/
|
|
57
|
+
sessionId?: string;
|
|
36
58
|
}
|
|
37
59
|
|
|
38
60
|
export type CursorTransportFactory = (input: CursorTransportFactoryInput) => CursorTransport;
|
|
@@ -1,15 +1,30 @@
|
|
|
1
1
|
import type { OcxUsage } from "../../types";
|
|
2
2
|
import type { OcxMessage, OcxRequestOptions, OcxTool } from "../../types";
|
|
3
3
|
import type { CursorRoutingLevel } from "./discovery";
|
|
4
|
+
import type { CursorCheckpointInvalidationReason } from "./checkpoint-store";
|
|
5
|
+
import type { ResolvedCursorImage } from "./images";
|
|
6
|
+
|
|
7
|
+
export interface CursorRequestedModelParameter {
|
|
8
|
+
id: string;
|
|
9
|
+
value: string;
|
|
10
|
+
}
|
|
4
11
|
|
|
5
12
|
export interface CursorRunRequest {
|
|
6
13
|
modelId: string;
|
|
14
|
+
/** Cursor model-picker parameters encoded through AgentRunRequest.requested_model. */
|
|
15
|
+
requestedModelParameters?: readonly CursorRequestedModelParameter[];
|
|
7
16
|
/** Cursor Router optimization parameter; valid only while modelId is the `default` wire model. */
|
|
8
17
|
routingLevel?: CursorRoutingLevel;
|
|
9
18
|
conversationId: string;
|
|
10
19
|
system: string[];
|
|
11
20
|
messages: CursorRequestMessage[];
|
|
12
|
-
rawMessages?: OcxMessage[];
|
|
21
|
+
rawMessages?: readonly OcxMessage[];
|
|
22
|
+
/**
|
|
23
|
+
* Images for the active user/developer turn. Encoded as SelectedImage blobIdWithData refs under
|
|
24
|
+
* UserMessage.selected_context (bytes live in the request-scoped KV store for getBlobArgs
|
|
25
|
+
* hydration). History stays text-only. data: URLs only in this slice.
|
|
26
|
+
*/
|
|
27
|
+
selectedImages?: readonly ResolvedCursorImage[];
|
|
13
28
|
tools?: OcxTool[];
|
|
14
29
|
toolChoice?: OcxRequestOptions["toolChoice"];
|
|
15
30
|
parallelToolCalls?: boolean;
|
|
@@ -24,6 +39,18 @@ export interface CursorRunRequest {
|
|
|
24
39
|
* pre-compaction history being summarized and must not become the next turn's carry-forward total.
|
|
25
40
|
*/
|
|
26
41
|
contextUsageStoreCheckpoints?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Reuse a previously captured ConversationStateStructure instead of rebuilding historical
|
|
44
|
+
* root/turn blobs. Absent means the existing full-replay path.
|
|
45
|
+
*/
|
|
46
|
+
checkpointBytes?: Uint8Array;
|
|
47
|
+
continuationMode?: "full-replay" | "checkpoint";
|
|
48
|
+
checkpointInvalidationReason?: CursorCheckpointInvalidationReason;
|
|
49
|
+
/**
|
|
50
|
+
* When set with checkpointBytes, only this suffix of rawMessages is replayed onto the
|
|
51
|
+
* decoded ConversationStateStructure. Used for tool-result continuations.
|
|
52
|
+
*/
|
|
53
|
+
checkpointSuffixStart?: number;
|
|
27
54
|
}
|
|
28
55
|
|
|
29
56
|
export interface CursorRequestMessage {
|