@iislee/opencodex 2.11.0 → 2.35.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS_INSTALL.md +109 -0
- package/README.md +117 -22
- package/bin/ocx.mjs +245 -88
- package/bin/package-main.mjs +1 -1
- package/gui/dist/assets/index-Be1sDpWw.css +1 -0
- package/gui/dist/assets/index-D4OKgUV4.js +114 -0
- package/gui/dist/index.html +2 -2
- package/gui/dist/provider-icons/alibaba-color.svg +1 -1
- package/gui/dist/provider-icons/antigravity-color.svg +1 -1
- package/gui/dist/provider-icons/claude-color.svg +1 -1
- package/gui/dist/provider-icons/cline-color.svg +16 -0
- package/gui/dist/provider-icons/cloudflare-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/commandcode-color.svg +1 -0
- package/gui/dist/provider-icons/copilot-color.svg +1 -1
- package/gui/dist/provider-icons/cursor-color.svg +1 -1
- package/gui/dist/provider-icons/deepseek-color.svg +1 -1
- package/gui/dist/provider-icons/firepass-color.svg +1 -1
- package/gui/dist/provider-icons/fireworks-color.svg +1 -1
- package/gui/dist/provider-icons/gemini-color.svg +1 -1
- package/gui/dist/provider-icons/github-copilot-color.svg +1 -1
- package/gui/dist/provider-icons/gitlab-duo-color.svg +1 -1
- package/gui/dist/provider-icons/grok.svg +1 -1
- package/gui/dist/provider-icons/groq-color.svg +1 -1
- package/gui/dist/provider-icons/huggingface-color.svg +1 -1
- package/gui/dist/provider-icons/kimi-color.svg +1 -1
- package/gui/dist/provider-icons/kiro-color.svg +2 -2
- package/gui/dist/provider-icons/lm-studio-color.svg +1 -1
- package/gui/dist/provider-icons/mistral-color.svg +1 -1
- package/gui/dist/provider-icons/moonshot-color.svg +1 -1
- package/gui/dist/provider-icons/nvidia-color.svg +1 -1
- package/gui/dist/provider-icons/ollama-color.svg +1 -1
- package/gui/dist/provider-icons/openai.svg +1 -1
- package/gui/dist/provider-icons/opencode.svg +2 -1
- package/gui/dist/provider-icons/openrouter-color.svg +1 -1
- package/gui/dist/provider-icons/pi.svg +2 -2
- package/gui/dist/provider-icons/qianfan-color.svg +1 -1
- package/gui/dist/provider-icons/qwen-portal-color.svg +1 -1
- package/gui/dist/provider-icons/vercel-ai-gateway-color.svg +1 -1
- package/gui/dist/provider-icons/vllm-color.svg +1 -1
- package/gui/dist/provider-icons/xiaomi-color.svg +1 -1
- package/package.json +21 -10
- package/src/adapters/anthropic-output-schema.ts +137 -0
- package/src/adapters/anthropic.ts +475 -62
- package/src/adapters/base.ts +82 -7
- package/src/adapters/client-fingerprint.ts +18 -12
- package/src/adapters/cline-pass-deepseek-v4-tool-replay.ts +69 -0
- package/src/adapters/command-code.ts +637 -0
- package/src/adapters/cursor/call-id.ts +44 -0
- package/src/adapters/cursor/catalog.ts +541 -0
- package/src/adapters/cursor/checkpoint-store.ts +308 -0
- package/src/adapters/cursor/cursor-errors.ts +144 -6
- package/src/adapters/cursor/discovery.ts +122 -14
- package/src/adapters/cursor/effort-map.ts +106 -4
- package/src/adapters/cursor/envelope-echo.ts +290 -0
- package/src/adapters/cursor/framing.ts +39 -0
- package/src/adapters/cursor/h2-pool.ts +123 -0
- package/src/adapters/cursor/http1-bidi.ts +361 -0
- package/src/adapters/cursor/images.ts +704 -0
- package/src/adapters/cursor/live-models.ts +180 -59
- package/src/adapters/cursor/live-transport.ts +623 -170
- package/src/adapters/cursor/message-mapper.ts +4 -1
- package/src/adapters/cursor/native-exec-common.ts +23 -2
- package/src/adapters/cursor/native-exec-desktop.ts +23 -0
- package/src/adapters/cursor/native-exec-fs.ts +10 -7
- package/src/adapters/cursor/native-exec-network.ts +1 -1
- package/src/adapters/cursor/native-exec-shell.ts +5 -3
- package/src/adapters/cursor/native-exec.ts +121 -14
- package/src/adapters/cursor/protobuf-events.ts +829 -11
- package/src/adapters/cursor/protobuf-request.ts +447 -75
- package/src/adapters/cursor/request-builder.ts +271 -35
- package/src/adapters/cursor/tool-definitions.ts +252 -12
- package/src/adapters/cursor/tool-result-normalize.ts +115 -0
- package/src/adapters/cursor/transport.ts +22 -0
- package/src/adapters/cursor/types.ts +48 -1
- package/src/adapters/cursor.ts +336 -39
- package/src/adapters/exec-tool-result-normalize.ts +99 -0
- package/src/adapters/google-antigravity-replay.ts +713 -41
- package/src/adapters/google-antigravity-wire.ts +48 -10
- package/src/adapters/google-errors.ts +44 -12
- package/src/adapters/google-http.ts +38 -10
- package/src/adapters/google-tool-schema.ts +80 -15
- package/src/adapters/google-truncation.ts +11 -0
- package/src/adapters/google.ts +742 -86
- package/src/adapters/identity.ts +39 -6
- package/src/adapters/image.ts +1 -1
- package/src/adapters/kiro-constants.ts +27 -0
- package/src/adapters/kiro-errors.ts +11 -0
- package/src/adapters/kiro-events.ts +19 -1
- package/src/adapters/kiro-thinking.ts +18 -2
- package/src/adapters/kiro-tools.ts +65 -17
- package/src/adapters/kiro.ts +270 -73
- package/src/adapters/mimo-free.ts +17 -0
- package/src/adapters/openai-chat-url.ts +11 -0
- package/src/adapters/openai-chat.ts +1377 -344
- package/src/adapters/openai-responses-url.ts +16 -0
- package/src/adapters/openai-responses.ts +1164 -64
- package/src/adapters/registry.ts +175 -0
- package/src/adapters/responses-tool-schema.ts +67 -0
- package/src/adapters/run-turn-queue.ts +36 -1
- package/src/adapters/tool-call-id.ts +119 -0
- package/src/adapters/tool-catalog-nudge.ts +105 -21
- package/src/adapters/xai-tool-schema.ts +436 -0
- package/src/adapters/xai-web-search.ts +186 -0
- package/src/bridge.ts +512 -92
- package/src/chat/inbound.ts +57 -20
- package/src/chat/outbound.ts +97 -33
- package/src/claude/agents-inject.ts +40 -10
- package/src/claude/context-windows.ts +37 -14
- package/src/claude/desktop-3p.ts +243 -9
- package/src/claude/gateway-cache.ts +41 -4
- package/src/claude/inbound.ts +72 -3
- package/src/claude/model-info.ts +38 -15
- package/src/claude/outbound.ts +88 -21
- package/src/cli/access.ts +46 -3
- package/src/cli/account-api.ts +150 -19
- package/src/cli/account-auth.ts +33 -6
- package/src/cli/account-catalog-refresh.ts +14 -0
- package/src/cli/account-extended.ts +648 -28
- package/src/cli/account-main.ts +317 -0
- package/src/cli/account.ts +97 -19
- package/src/cli/agent.ts +53 -2
- package/src/cli/alias.ts +66 -0
- package/src/cli/capabilities-command.ts +94 -0
- package/src/cli/capabilities.ts +496 -0
- package/src/cli/claude-agent-startup-sync.ts +73 -0
- package/src/cli/claude-desktop.ts +60 -15
- package/src/cli/claude.ts +129 -35
- package/src/cli/codex-log-guard-doctor.ts +103 -0
- package/src/cli/codex-shim-autorestore.ts +2 -0
- package/src/cli/codex-shim-readiness.ts +76 -0
- package/src/cli/combo.ts +8 -0
- package/src/cli/config-command.ts +74 -10
- package/src/cli/dispatch.ts +821 -0
- package/src/cli/doctor.ts +440 -56
- package/src/cli/ensure-desired-integrations.ts +152 -0
- package/src/cli/export-command.ts +46 -20
- package/src/cli/help.ts +34 -274
- package/src/cli/index.ts +417 -528
- package/src/cli/init.ts +5 -17
- package/src/cli/inspect.ts +230 -0
- package/src/cli/integrations.ts +120 -2
- package/src/cli/lab.ts +607 -0
- package/src/cli/launcher-context.ts +77 -0
- package/src/cli/minimax.ts +497 -0
- package/src/cli/models-runtime.ts +130 -2
- package/src/cli/models.ts +118 -16
- package/src/cli/observe.ts +123 -11
- package/src/cli/opencode.ts +4 -2
- package/src/cli/provider-runtime.ts +34 -3
- package/src/cli/provider.ts +25 -3
- package/src/cli/ready.ts +301 -0
- package/src/cli/registry.ts +476 -0
- package/src/cli/root.ts +86 -0
- package/src/cli/route-policy.ts +92 -0
- package/src/cli/runtime-api.ts +57 -10
- package/src/cli/star-prompt.ts +71 -15
- package/src/cli/status.ts +51 -4
- package/src/cli/storage.ts +234 -0
- package/src/cli/system-command.ts +16 -0
- package/src/cli/system-restart-client.ts +146 -0
- package/src/cli/tray-proxy.ts +153 -6
- package/src/cli/usage-report.ts +184 -0
- package/src/cli/v2.ts +137 -18
- package/src/cli/version-skew.ts +46 -0
- package/src/cli.ts +1 -1
- package/src/clients/config-export.ts +1442 -23
- package/src/clients/effective-status.ts +30 -2
- package/src/clients/probes/cline.ts +81 -0
- package/src/codex/account-label.ts +35 -1
- package/src/codex/account-lifecycle.ts +130 -13
- package/src/codex/account-namespaces.ts +49 -3
- package/src/codex/account-pause.ts +2 -1
- package/src/codex/account-priority.ts +84 -0
- package/src/codex/account-store.ts +29 -2
- package/src/codex/account-usability.ts +25 -2
- package/src/codex/admission.ts +256 -0
- package/src/codex/affinity-debug.ts +162 -0
- package/src/codex/app-server-processes.ts +570 -107
- package/src/codex/app-server-restart-service.ts +232 -0
- package/src/codex/auth-api.ts +893 -246
- package/src/codex/auth-collision.ts +5 -3
- package/src/codex/auth-context.ts +348 -32
- package/src/codex/autostart-health.ts +24 -1
- package/src/codex/catalog/account-models.ts +67 -0
- package/src/codex/catalog/aggregation.ts +86 -10
- package/src/codex/catalog/bundled.ts +331 -33
- package/src/codex/catalog/effort.ts +138 -32
- package/src/codex/catalog/filesystem-evidence.ts +302 -0
- package/src/codex/catalog/kinds.ts +2 -0
- package/src/codex/catalog/metadata.ts +555 -45
- package/src/codex/catalog/native-models.ts +75 -0
- package/src/codex/catalog/parsing.ts +269 -30
- package/src/codex/catalog/provider-fetch.ts +1626 -144
- package/src/codex/catalog/sync.ts +1576 -187
- package/src/codex/catalog-admission.ts +199 -0
- package/src/codex/catalog-refresh-status.ts +105 -0
- package/src/codex/catalog-write-serialization.ts +242 -0
- package/src/codex/catalog.ts +6 -3
- package/src/codex/codex-write-lock.ts +386 -0
- package/src/codex/convergence-types.ts +614 -0
- package/src/codex/convergence.ts +676 -0
- package/src/codex/coordinator-doctor.ts +332 -0
- package/src/codex/custom-model-catalog-migration.ts +176 -0
- package/src/codex/desired-state.ts +230 -0
- package/src/codex/desktop-app-restart.ts +355 -0
- package/src/codex/features.ts +636 -39
- package/src/codex/generation.ts +202 -0
- package/src/codex/history-job.ts +436 -0
- package/src/codex/history-lock.ts +242 -0
- package/src/codex/history-manifest.ts +112 -0
- package/src/codex/history-migration-guardian.ts +30 -24
- package/src/codex/history-provider.ts +1016 -235
- package/src/codex/history-transition.ts +105 -0
- package/src/codex/history-worker.ts +223 -0
- package/src/codex/inject-coordination.ts +373 -0
- package/src/codex/inject.ts +1114 -152
- package/src/codex/injected-marker.ts +37 -3
- package/src/codex/integration-record.ts +266 -0
- package/src/codex/internal/catalog-writer.ts +203 -0
- package/src/codex/internal/history-writer.ts +81 -0
- package/src/codex/journal.ts +66 -4
- package/src/codex/log-guard/inspect.ts +524 -0
- package/src/codex/log-guard/lock.ts +150 -0
- package/src/codex/log-guard/maintenance.ts +403 -0
- package/src/codex/log-guard/path-safety.ts +88 -0
- package/src/codex/log-guard/policy.ts +44 -0
- package/src/codex/log-guard/processes.ts +205 -0
- package/src/codex/log-guard/protection.ts +489 -0
- package/src/codex/log-guard/sqlite-errors.ts +9 -0
- package/src/codex/main-account-cache.ts +24 -0
- package/src/codex/main-account.ts +29 -1
- package/src/codex/management-convergence.ts +167 -0
- package/src/codex/model-cache.ts +56 -10
- package/src/codex/model-entitlements.ts +360 -0
- package/src/codex/native-main-admission.ts +47 -0
- package/src/codex/native-main-auth-temp.ts +187 -0
- package/src/codex/native-main-claim.ts +178 -0
- package/src/codex/native-main-lock-file.ts +162 -0
- package/src/codex/native-main-owner.ts +329 -0
- package/src/codex/native-profile-api.ts +247 -0
- package/src/codex/native-profile-manager.ts +1531 -0
- package/src/codex/native-profile-processes.ts +121 -0
- package/src/codex/native-profile-recovery.ts +99 -0
- package/src/codex/native-profile-stage-store.ts +387 -0
- package/src/codex/native-profile-startup.ts +622 -0
- package/src/codex/native-profile-store.ts +855 -0
- package/src/codex/native-profile-types.ts +120 -0
- package/src/codex/native-residue.ts +675 -0
- package/src/codex/paths.ts +80 -1
- package/src/codex/plan-from-token.ts +140 -0
- package/src/codex/plan.ts +40 -0
- package/src/codex/plugins-doctor.ts +1 -1
- package/src/codex/pool-rotation.ts +74 -4
- package/src/codex/project-config-warnings.ts +20 -6
- package/src/codex/prompt-journal.ts +352 -0
- package/src/codex/prompt-layers.ts +1313 -0
- package/src/codex/prompt-lock.ts +143 -0
- package/src/codex/prompt-text-probe.ts +238 -0
- package/src/codex/quota-rejection.ts +298 -0
- package/src/codex/quota.ts +264 -21
- package/src/codex/refresh.ts +11 -2
- package/src/codex/reset-credit-recovery.ts +1044 -0
- package/src/codex/routing.ts +514 -94
- package/src/codex/runtime.ts +159 -38
- package/src/codex/shim.ts +1065 -31
- package/src/codex/subagent-model-fallback.ts +437 -43
- package/src/codex/sync.ts +191 -2
- package/src/codex/transition-state.ts +720 -0
- package/src/codex/upstream-host-health.ts +368 -0
- package/src/codex/user-identity.ts +557 -0
- package/src/codex/warmup.ts +187 -81
- package/src/codex/write-coordination.ts +114 -0
- package/src/combos/failover.ts +47 -0
- package/src/combos/index.ts +4 -0
- package/src/combos/request.ts +32 -0
- package/src/combos/types.ts +91 -9
- package/src/compatibility/index.ts +26 -0
- package/src/compatibility/manifest.ts +253 -0
- package/src/compatibility/openai-responses.ts +121 -0
- package/src/config/atomic-write.ts +219 -0
- package/src/config/paths.ts +40 -0
- package/src/config/process-state.ts +309 -0
- package/src/config/provider-name.ts +24 -0
- package/src/config/provider-validation.ts +177 -0
- package/src/config/rebase-provenance.ts +68 -0
- package/src/config.ts +1713 -709
- package/src/generated/compatibility-version.json +3324 -0
- package/src/generated/{jawcode-model-metadata.ts → model-metadata.ts} +19 -17
- package/src/grok/inject.ts +16 -5
- package/src/grok/inspect.ts +45 -0
- package/src/grok/sync.ts +2 -2
- package/src/images/loop.ts +157 -33
- package/src/images/plan.ts +24 -13
- package/src/integrations/config-io.ts +269 -0
- package/src/integrations/journal.ts +315 -0
- package/src/integrations/merge.ts +135 -0
- package/src/integrations/mutation-flight.ts +71 -0
- package/src/integrations/native/ownership-preflight.ts +202 -0
- package/src/integrations/omp-yaml-source.ts +358 -0
- package/src/integrations/owned-refresh.ts +74 -0
- package/src/integrations/ownership-policy.ts +160 -0
- package/src/integrations/ownership.ts +155 -0
- package/src/integrations/registry.ts +166 -0
- package/src/integrations/serialize.ts +314 -0
- package/src/integrations/state.ts +433 -0
- package/src/integrations/store.ts +103 -0
- package/src/integrations/writer-lock.ts +98 -0
- package/src/integrations/writer.ts +715 -0
- package/src/lab/artifacts/sanitize.ts +586 -0
- package/src/lab/artifacts/secure-fs.ts +475 -0
- package/src/lab/artifacts/store.ts +310 -0
- package/src/lab/automation/budgets.ts +78 -0
- package/src/lab/automation/config-persistence.ts +256 -0
- package/src/lab/automation/constants.ts +39 -0
- package/src/lab/automation/cooldown.ts +103 -0
- package/src/lab/automation/dispatch.ts +211 -0
- package/src/lab/automation/index.ts +13 -0
- package/src/lab/automation/orchestrator.ts +499 -0
- package/src/lab/automation/persistence.ts +512 -0
- package/src/lab/automation/planner.ts +371 -0
- package/src/lab/automation/policy.ts +136 -0
- package/src/lab/automation/queue.ts +191 -0
- package/src/lab/automation/recovery.ts +24 -0
- package/src/lab/automation/route-context.ts +21 -0
- package/src/lab/automation/run-key.ts +44 -0
- package/src/lab/automation/runs-query.ts +34 -0
- package/src/lab/automation/types.ts +160 -0
- package/src/lab/conformance/assertion.ts +325 -0
- package/src/lab/conformance/digest.ts +22 -0
- package/src/lab/conformance/executor.ts +741 -0
- package/src/lab/conformance/fixture-provider.ts +27 -0
- package/src/lab/conformance/fixtures/live-v1-cases.json +175 -0
- package/src/lab/conformance/fixtures/protocol-v1-cases.json +461 -0
- package/src/lab/conformance/harness-budget.ts +47 -0
- package/src/lab/conformance/index.ts +5 -0
- package/src/lab/conformance/jcs.ts +64 -0
- package/src/lab/conformance/json-pointer.ts +39 -0
- package/src/lab/conformance/manifest.ts +180 -0
- package/src/lab/conformance/mcp-stub.ts +179 -0
- package/src/lab/conformance/negative-controls.ts +164 -0
- package/src/lab/conformance/observation.ts +355 -0
- package/src/lab/conformance/runner.ts +68 -0
- package/src/lab/conformance/sse-normalize.ts +59 -0
- package/src/lab/conformance/suite-manifest.ts +78 -0
- package/src/lab/conformance/types.ts +214 -0
- package/src/lab/constants.ts +126 -0
- package/src/lab/digest.ts +64 -0
- package/src/lab/events/errors.ts +9 -0
- package/src/lab/events/limits.ts +117 -0
- package/src/lab/events/types.ts +229 -0
- package/src/lab/events/validate.ts +781 -0
- package/src/lab/fabric/constants.ts +40 -0
- package/src/lab/fabric/executor.ts +492 -0
- package/src/lab/fabric/index.ts +80 -0
- package/src/lab/fabric/manifest.ts +222 -0
- package/src/lab/fabric/observe.ts +489 -0
- package/src/lab/fabric/patch.ts +79 -0
- package/src/lab/fabric/producer-child.ts +139 -0
- package/src/lab/fabric/producer-isolate.ts +276 -0
- package/src/lab/fabric/producer-protocol.ts +61 -0
- package/src/lab/fabric/scratch.ts +439 -0
- package/src/lab/fabric/subject.ts +106 -0
- package/src/lab/fabric/types.ts +134 -0
- package/src/lab/fabric/verifier.ts +98 -0
- package/src/lab/index.ts +54 -0
- package/src/lab/ledger/artifact-refs.ts +127 -0
- package/src/lab/ledger/invalidation.ts +136 -0
- package/src/lab/ledger/purge.ts +310 -0
- package/src/lab/ledger/store.ts +532 -0
- package/src/lab/live/credential-lease.ts +53 -0
- package/src/lab/live/destination.ts +155 -0
- package/src/lab/live/executor.ts +336 -0
- package/src/lab/live/inert-tools.ts +56 -0
- package/src/lab/live/manifest.ts +85 -0
- package/src/lab/live/mcp-loopback.ts +57 -0
- package/src/lab/live/runner.ts +19 -0
- package/src/lab/live/sandbox.ts +61 -0
- package/src/lab/live/suite-manifest.ts +41 -0
- package/src/lab/live/transport.ts +118 -0
- package/src/lab/live/types.ts +197 -0
- package/src/lab/observe/from-conformance.ts +301 -0
- package/src/lab/observe/from-live.ts +117 -0
- package/src/lab/paths.ts +153 -0
- package/src/lab/projection/rebuild.ts +495 -0
- package/src/lab/projection/schema.ts +135 -0
- package/src/lab/projection/verdicts.ts +474 -0
- package/src/lab/projection/verification.ts +412 -0
- package/src/lab/public/bundle.ts +217 -0
- package/src/lab/public/community-authority.ts +175 -0
- package/src/lab/public/community-files.ts +29 -0
- package/src/lab/public/community.ts +479 -0
- package/src/lab/public/file-safety.ts +155 -0
- package/src/lab/public/ids.ts +26 -0
- package/src/lab/public/index.ts +16 -0
- package/src/lab/public/mutation-lock.ts +424 -0
- package/src/lab/public/operator.ts +353 -0
- package/src/lab/public/origin-purge.ts +79 -0
- package/src/lab/public/origin.ts +203 -0
- package/src/lab/public/privacy.ts +143 -0
- package/src/lab/public/private-file.ts +261 -0
- package/src/lab/public/project.ts +124 -0
- package/src/lab/public/purge-test-fault.ts +21 -0
- package/src/lab/public/purge.ts +223 -0
- package/src/lab/public/registry.ts +44 -0
- package/src/lab/public/revocation.ts +252 -0
- package/src/lab/public/signature.ts +243 -0
- package/src/lab/public/storage.ts +105 -0
- package/src/lab/public/strict-json.ts +206 -0
- package/src/lab/public/time.ts +26 -0
- package/src/lab/public/types.ts +172 -0
- package/src/lab/public/validate.ts +391 -0
- package/src/lab/query/catalog.ts +101 -0
- package/src/lab/query/connection.ts +107 -0
- package/src/lab/query/constants.ts +4 -0
- package/src/lab/query/cursor.ts +132 -0
- package/src/lab/query/dto-map.ts +277 -0
- package/src/lab/query/errors.ts +22 -0
- package/src/lab/query/freshness.ts +53 -0
- package/src/lab/query/index.ts +45 -0
- package/src/lab/query/latest-observation.ts +59 -0
- package/src/lab/query/passive-production.ts +159 -0
- package/src/lab/query/queries.ts +444 -0
- package/src/lab/query/types.ts +266 -0
- package/src/lab/subject/behavior-fingerprint.ts +77 -0
- package/src/lab/subject/installation-salt.ts +112 -0
- package/src/lab/subject/protocol-subject.ts +80 -0
- package/src/lab/subject/route-subject.ts +74 -0
- package/src/lib/admin-secrets.ts +24 -0
- package/src/lib/app-owned-memory-stores.ts +22 -0
- package/src/lib/bounded-body.ts +167 -11
- package/src/lib/bun-runtime.ts +125 -12
- package/src/lib/bun-stream-caps.ts +13 -9
- package/src/lib/codex-restart-contract.ts +120 -0
- package/src/lib/config-ownership.ts +26 -2
- package/src/lib/destination-policy.ts +65 -1
- package/src/lib/errors.ts +80 -5
- package/src/lib/fabric-task-execution-authority.ts +7 -0
- package/src/lib/fabric-task-host.ts +29 -0
- package/src/lib/lab-activation.ts +223 -0
- package/src/lib/lab-live-execution-authority.ts +13 -0
- package/src/lib/lab-live-host.ts +30 -0
- package/src/lib/lab-live-pinned-sender.ts +56 -0
- package/src/lib/lab-live-route-production.ts +130 -0
- package/src/lib/lab-passive-linker-registration.ts +26 -0
- package/src/lib/local-management-attestation.ts +51 -0
- package/src/lib/local-management-capability.ts +100 -0
- package/src/lib/local-provider-reload-contract.ts +100 -0
- package/src/lib/optional-shutdown-hooks.ts +57 -0
- package/src/lib/package-tree-integrity.ts +101 -0
- package/src/lib/pinned-http.ts +145 -26
- package/src/lib/process-control.ts +6 -2
- package/src/lib/provider-outbound.ts +49 -9
- package/src/lib/redact.ts +419 -3
- package/src/lib/self-launch-argv.ts +15 -0
- package/src/lib/server-resource-ownership.ts +71 -0
- package/src/lib/service-secrets.ts +15 -0
- package/src/lib/shadow-call.ts +35 -4
- package/src/lib/sse-decoder.ts +41 -0
- package/src/lib/state-store-registrations.ts +10 -2
- package/src/lib/system-restart-contract.ts +73 -0
- package/src/lib/token-estimate.ts +19 -2
- package/src/lib/tool-argument-integers.ts +253 -0
- package/src/lib/translator-budget.ts +44 -0
- package/src/lib/upstream-http-version.ts +57 -0
- package/src/lib/upstream-reachability.ts +95 -0
- package/src/lib/upstream-retry.ts +156 -3
- package/src/lib/windows-atomic-replace.ts +155 -0
- package/src/lib/windows-elevation.ts +70 -2
- package/src/lib/windows-secret-acl.ts +409 -69
- package/src/lib/windows-service-wrappers.ts +72 -0
- package/src/lib/windows-text.ts +106 -0
- package/src/lib/windows-user-principal.ts +341 -0
- package/src/lib/winsw.ts +33 -5
- package/src/oauth/account-import/google-antigravity-adapter.ts +74 -0
- package/src/oauth/account-import/index.ts +15 -0
- package/src/oauth/account-import/parser.ts +83 -0
- package/src/oauth/account-import/registry.ts +18 -0
- package/src/oauth/account-import/service.ts +75 -0
- package/src/oauth/account-import/types.ts +91 -0
- package/src/oauth/anthropic.ts +12 -1
- package/src/oauth/callback-server.ts +30 -4
- package/src/oauth/chatgpt.ts +12 -1
- package/src/oauth/cline.ts +203 -0
- package/src/oauth/command-code.ts +239 -0
- package/src/oauth/cursor.ts +46 -5
- package/src/oauth/generic-account-failover.ts +231 -0
- package/src/oauth/google-antigravity.ts +35 -3
- package/src/oauth/health.ts +20 -12
- package/src/oauth/index.ts +462 -71
- package/src/oauth/key-providers.ts +25 -0
- package/src/oauth/kimi.ts +25 -3
- package/src/oauth/kiro.ts +95 -6
- package/src/oauth/local-token-detect.ts +13 -2
- package/src/oauth/log.ts +3 -1
- package/src/oauth/login-cli.ts +88 -28
- package/src/oauth/nous.ts +798 -0
- package/src/oauth/open-browser-choice.ts +26 -0
- package/src/oauth/store.ts +133 -26
- package/src/oauth/token-guardian.ts +9 -3
- package/src/oauth/types.ts +15 -0
- package/src/pi/models.ts +2 -2
- package/src/providers/alibaba-region-migration.ts +1 -1
- package/src/providers/antigravity-models.ts +521 -31
- package/src/providers/auto-compact-budget.ts +65 -0
- package/src/providers/base-url-choices.ts +10 -0
- package/src/providers/codex-capacity.ts +292 -0
- package/src/providers/command-code-efforts.ts +176 -0
- package/src/providers/context-cap.ts +26 -8
- package/src/providers/cursor-pool.ts +72 -0
- package/src/providers/default-aliases.ts +65 -0
- package/src/providers/derive.ts +281 -6
- package/src/providers/fastwire.ts +507 -0
- package/src/providers/free-directory.ts +10 -7
- package/src/providers/google-vertex-location.ts +14 -0
- package/src/providers/key-failover.ts +71 -3
- package/src/providers/label.ts +35 -2
- package/src/providers/model-discovery-limits.ts +16 -0
- package/src/providers/model-discovery.ts +115 -22
- package/src/providers/model-presets.ts +119 -0
- package/src/providers/model-rename-migration.ts +255 -0
- package/src/providers/model-rename-startup.ts +28 -0
- package/src/providers/new-model-policy.ts +146 -0
- package/src/providers/openai-sidecar.ts +72 -4
- package/src/providers/openai-tier-startup.ts +31 -2
- package/src/providers/openai-tiers.ts +119 -4
- package/src/providers/openai-virtual-models.ts +1 -0
- package/src/providers/opencode-zen-rate-limit.ts +102 -0
- package/src/providers/provider-id-rewrite.ts +30 -0
- package/src/providers/quota.ts +1379 -40
- package/src/providers/registry.ts +1545 -112
- package/src/providers/request-pacing.ts +310 -0
- package/src/providers/service-tier.ts +277 -0
- package/src/providers/slug-codec.ts +94 -6
- package/src/providers/static-model-discovery.ts +86 -0
- package/src/providers/xai-responses-opt-in.ts +15 -0
- package/src/providers/xai-transport.ts +32 -4
- package/src/reasoning-effort.ts +68 -3
- package/src/responses/apply-patch-envelope.ts +63 -0
- package/src/responses/code-mode-helper-compat.ts +50 -0
- package/src/responses/compaction.ts +26 -1
- package/src/responses/custom-tool-compat.ts +384 -0
- package/src/responses/hosted-tool-policy.ts +9 -0
- package/src/responses/namespace-tool-compat.ts +435 -0
- package/src/responses/parser.ts +225 -38
- package/src/responses/provider-continuation.ts +98 -0
- package/src/responses/provider-opaque-metadata.ts +73 -0
- package/src/responses/reasoning-envelope.ts +9 -1
- package/src/responses/reasoning-replay-cache.ts +504 -0
- package/src/responses/schema.ts +12 -2
- package/src/responses/spill-store.ts +75 -10
- package/src/responses/state.ts +659 -31
- package/src/responses/thought-signature-replay.ts +364 -0
- package/src/responses/tool-search-compat.ts +301 -0
- package/src/responses/truncated-stop-reason.ts +60 -0
- package/src/responses/turn-termination.ts +107 -0
- package/src/router.ts +405 -31
- package/src/routing/analytics.ts +379 -0
- package/src/routing/capability.ts +244 -0
- package/src/routing/compatibility/assemble.ts +73 -0
- package/src/routing/compatibility/behavior.ts +278 -0
- package/src/routing/compatibility/catalog.ts +99 -0
- package/src/routing/compatibility/endpoint.ts +52 -0
- package/src/routing/compatibility/lab-evidence-provider.ts +130 -0
- package/src/routing/compatibility/policy.ts +181 -0
- package/src/routing/compatibility/provider-slot.ts +56 -0
- package/src/routing/compatibility/reader.ts +110 -0
- package/src/routing/compatibility/subject.ts +191 -0
- package/src/routing/compatibility/types.ts +64 -0
- package/src/routing/compatibility/version.ts +104 -0
- package/src/routing/cost.ts +77 -0
- package/src/routing/evaluator.ts +495 -0
- package/src/routing/health.ts +412 -0
- package/src/routing/history/cursor.ts +43 -0
- package/src/routing/history/indexer.ts +605 -0
- package/src/routing/history/schema.ts +72 -0
- package/src/routing/profile-namespace.ts +15 -0
- package/src/routing/profile.ts +547 -0
- package/src/routing/quota.ts +155 -0
- package/src/routing/request-evidence.ts +45 -0
- package/src/routing/trace.ts +776 -0
- package/src/server/adapter-resolve.ts +2 -29
- package/src/server/auth-cors.ts +289 -48
- package/src/server/background-lifecycle.ts +182 -0
- package/src/server/chat-completions.ts +154 -72
- package/src/server/chat-native-sse.ts +331 -0
- package/src/server/chat-native.ts +445 -0
- package/src/server/claude-messages.ts +160 -44
- package/src/server/direct-local-http.ts +347 -0
- package/src/server/effort-policy.ts +18 -0
- package/src/server/github-copilot-responses-repair.ts +338 -0
- package/src/server/gui-static.ts +39 -10
- package/src/server/images.ts +94 -12
- package/src/server/index.ts +1021 -190
- package/src/server/lifecycle.ts +336 -14
- package/src/server/live.ts +136 -17
- package/src/server/local-management-read-client.ts +90 -0
- package/src/server/local-provider-reload-client.ts +137 -0
- package/src/server/management/agent-settings-routes.ts +433 -116
- package/src/server/management/api-key-usage.ts +31 -5
- package/src/server/management/body.ts +6 -0
- package/src/server/management/codex-prompt-routes.ts +570 -0
- package/src/server/management/combo-routes.ts +64 -25
- package/src/server/management/config-routes.ts +511 -51
- package/src/server/management/context.ts +89 -2
- package/src/server/management/integration-routes.ts +498 -0
- package/src/server/management/lab-automation-routes.ts +206 -0
- package/src/server/management/lab-routes.ts +563 -0
- package/src/server/management/logs-usage-routes.ts +127 -52
- package/src/server/management/model-routes.ts +461 -133
- package/src/server/management/model-rows.ts +167 -0
- package/src/server/management/native-integration-routes.ts +770 -0
- package/src/server/management/oauth-account-routes.ts +90 -8
- package/src/server/management/provider-capability-config.ts +48 -0
- package/src/server/management/provider-routes.ts +836 -159
- package/src/server/management/request-history-routes.ts +191 -0
- package/src/server/management/route-registry.ts +332 -0
- package/src/server/management/routing-analytics-routes.ts +74 -0
- package/src/server/management/routing-profile-routes.ts +380 -0
- package/src/server/management/shared.ts +27 -11
- package/src/server/management/sidebar-routes.ts +47 -31
- package/src/server/management/storage-log-guard-routes.ts +186 -0
- package/src/server/management/sync-response.ts +69 -0
- package/src/server/management/system-restart.ts +289 -33
- package/src/server/management/system-routes.ts +77 -0
- package/src/server/management/usage-summary-cache.ts +9 -1
- package/src/server/management/vision-sidecar-options.ts +167 -0
- package/src/server/management/web-search-sidecar-options.ts +120 -0
- package/src/server/management-api.ts +126 -23
- package/src/server/management-auth.ts +220 -5
- package/src/server/passive-route-linker.ts +66 -0
- package/src/server/port-reclaim.ts +1 -1
- package/src/server/ports.ts +41 -1
- package/src/server/proxy-liveness.ts +161 -10
- package/src/server/readiness.ts +99 -0
- package/src/server/relay-eager.ts +221 -54
- package/src/server/relay.ts +479 -87
- package/src/server/request-decompress.ts +113 -6
- package/src/server/request-log-conversation.ts +51 -0
- package/src/server/request-log.ts +298 -31
- package/src/server/responses/agent-task-recovery-cache.ts +143 -0
- package/src/server/responses/agent-task-recovery.ts +465 -0
- package/src/server/responses/codex-auth-error.ts +55 -0
- package/src/server/responses/collaboration.ts +239 -36
- package/src/server/responses/combo-stream-preflight.ts +178 -0
- package/src/server/responses/compact.ts +444 -72
- package/src/server/responses/core.ts +3579 -436
- package/src/server/responses/empty-completion-guard.ts +333 -0
- package/src/server/responses/encrypted-payload.ts +62 -39
- package/src/server/responses/fetch-helpers.ts +89 -99
- package/src/server/responses/input-admission.ts +187 -0
- package/src/server/responses/pacing-overload.ts +13 -0
- package/src/server/responses/passthrough-error.ts +33 -9
- package/src/server/responses/policy-fallback.ts +178 -0
- package/src/server/responses/responses-field-backfill.ts +343 -0
- package/src/server/responses/terminal-guard.ts +26 -5
- package/src/server/responses/upstream-error.ts +5 -0
- package/src/server/responses/ws-upstream.ts +381 -0
- package/src/server/responses-custom-tool-repair.ts +363 -0
- package/src/server/responses-item-id-repair.ts +54 -6
- package/src/server/responses-json-events.ts +90 -0
- package/src/server/responses-model-rewrite.ts +29 -0
- package/src/server/responses-reasoning-summary-rewrite.ts +178 -0
- package/src/server/responses-snapshot-repair.ts +621 -0
- package/src/server/responses-terminal-repair.ts +363 -0
- package/src/server/responses-tool-search-repair.ts +267 -0
- package/src/server/responses-undeclared-tool-guard.ts +376 -0
- package/src/server/responses.ts +18 -2
- package/src/server/search.ts +78 -13
- package/src/server/sse-frame-buffer.ts +319 -0
- package/src/server/sse-payload-rewrite.ts +110 -22
- package/src/server/startup-action-control.ts +8 -1
- package/src/server/startup-health-cache.ts +19 -1
- package/src/server/system-env.ts +80 -9
- package/src/server/ws-bridge.ts +53 -40
- package/src/service-manager-probe.ts +892 -0
- package/src/service.ts +1153 -94
- package/src/sidecar/auth.ts +92 -0
- package/src/sidecar/candidates.ts +83 -0
- package/src/storage/cleanup.ts +2 -2
- package/src/storage/policy-job.ts +14 -4
- package/src/storage/policy.ts +88 -23
- package/src/storage/scanner.ts +1 -1
- package/src/storage/worker-lifecycle.ts +14 -14
- package/src/tray/windows-tray.ps1 +83 -9
- package/src/tray/windows.ts +43 -16
- package/src/types/accounts.ts +37 -0
- package/src/types/config.ts +911 -0
- package/src/types/provider.ts +614 -0
- package/src/types/request.ts +397 -0
- package/src/types/tools.ts +236 -0
- package/src/types/wire.ts +80 -0
- package/src/types.ts +107 -1237
- package/src/update/index.ts +37 -23
- package/src/update/job.ts +445 -68
- package/src/update/notify.ts +12 -6
- package/src/update/npm-cache-preflight.d.mts +47 -0
- package/src/update/npm-cache-preflight.mjs +201 -0
- package/src/update/transactional-install.d.mts +22 -0
- package/src/update/transactional-install.mjs +266 -0
- package/src/usage/cost.ts +0 -0
- package/src/usage/expected-prices.ts +287 -16
- package/src/usage/log.ts +666 -50
- package/src/usage/summary.ts +388 -17
- package/src/usage/user-cost-overlay-reconciler.ts +313 -0
- package/src/usage/user-cost-overlays.ts +314 -0
- package/src/vision/anthropic-describe.ts +10 -6
- package/src/vision/backends.ts +97 -0
- package/src/vision/describe.ts +27 -16
- package/src/vision/eligibility.ts +250 -0
- package/src/vision/index.ts +238 -24
- package/src/vision/reasoning.ts +55 -0
- package/src/vision/routed-describe.ts +175 -0
- package/src/vision/timeout-bounds.ts +9 -0
- package/src/web-search/anthropic-executor.ts +13 -7
- package/src/web-search/backends.ts +108 -0
- package/src/web-search/exa-executor.ts +119 -0
- package/src/web-search/executor.ts +21 -6
- package/src/web-search/gemini-executor.ts +141 -0
- package/src/web-search/index.ts +150 -15
- package/src/web-search/loop.ts +284 -54
- package/src/web-search/parse.ts +125 -30
- package/src/web-search/sources.ts +60 -0
- package/src/web-search/xai-executor.ts +219 -0
- package/gui/dist/assets/index-DTpMHS4F.js +0 -67
- package/gui/dist/assets/index-ZNVDE3C7.css +0 -1
- package/gui/dist/provider-icons/antigravity.svg +0 -1
- package/gui/dist/provider-icons/claude.svg +0 -1
- package/gui/dist/provider-icons/copilot.svg +0 -1
- package/gui/dist/provider-icons/cursor.svg +0 -2
- package/gui/dist/provider-icons/gemini.svg +0 -1
- package/gui/dist/provider-icons/grok-color.svg +0 -1
- package/gui/dist/provider-icons/kiro.svg +0 -14
- package/src/cli/internal-dispatch.ts +0 -20
package/src/adapters/cursor.ts
CHANGED
|
@@ -3,19 +3,42 @@ import type { AdapterEvent, OcxProviderConfig } from "../types";
|
|
|
3
3
|
import type { ProviderAdapter } from "./base";
|
|
4
4
|
import { isTranslatorBudgetExceededError } from "../lib/translator-budget";
|
|
5
5
|
import { cursorExecDeniedMessage, cursorRequestDeclaresFullAccess } from "./cursor/exec-policy";
|
|
6
|
-
import { isCursorBenignCancelError, isCursorInvalidArgumentError, safeCursorErrorMessage } from "./cursor/cursor-errors";
|
|
7
|
-
import { isCursorExternalWireModel } from "./cursor/discovery";
|
|
6
|
+
import { isCursorBenignCancelError, isCursorInvalidArgumentError, safeCursorErrorMessage, type CursorSizeContext } from "./cursor/cursor-errors";
|
|
7
|
+
import { cursorCheckpointModelAffinityId, inferCursorContextWindow, isCursorExternalWireModel } from "./cursor/discovery";
|
|
8
8
|
import { createCursorKvStore, type CursorKvStore } from "./cursor/kv-store";
|
|
9
9
|
import { mapCursorServerMessage } from "./cursor/message-mapper";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
createCursorRequest,
|
|
12
|
+
cursorClientThreadOwner,
|
|
13
|
+
cursorCoveredPrefixDigest,
|
|
14
|
+
cursorInstructionDigest,
|
|
15
|
+
} from "./cursor/request-builder";
|
|
11
16
|
import {
|
|
12
17
|
createLiveCursorTransport,
|
|
13
18
|
CursorMissingCredentialError,
|
|
14
19
|
rekeyCursorContextUsage,
|
|
15
20
|
resolveCursorToken,
|
|
21
|
+
capturedCursorCheckpointBytes,
|
|
16
22
|
} from "./cursor/live-transport";
|
|
23
|
+
import {
|
|
24
|
+
commitCursorCheckpoint,
|
|
25
|
+
cursorCheckpointRefHash,
|
|
26
|
+
invalidateCursorCheckpoint,
|
|
27
|
+
} from "./cursor/checkpoint-store";
|
|
28
|
+
import { debugProviderDiagnostic } from "../lib/debug";
|
|
29
|
+
import { estimateTokens } from "../lib/token-estimate";
|
|
17
30
|
import { rememberCursorThreadConversation } from "./cursor/thread-continuity";
|
|
18
31
|
import { runCursorTurnWithRetry } from "./cursor/transport-retry";
|
|
32
|
+
import { cursorRequestHasShellAlias, cursorRequestUsesCodeMode } from "./cursor/tool-definitions";
|
|
33
|
+
import {
|
|
34
|
+
CURSOR_ECHO_RETRY_CONTINUATION_TEXT,
|
|
35
|
+
CURSOR_ROUTING_COMMENTARY_RETRY_TEXT,
|
|
36
|
+
CursorEnvelopeEchoSniffer,
|
|
37
|
+
CursorMidstreamEchoObserver,
|
|
38
|
+
CursorRoutingCommentaryError,
|
|
39
|
+
CursorRoutingCommentarySniffer,
|
|
40
|
+
CursorToolResultEchoError,
|
|
41
|
+
} from "./cursor/envelope-echo";
|
|
19
42
|
import {
|
|
20
43
|
createDisabledCursorTransport,
|
|
21
44
|
CursorTransportDisabledError,
|
|
@@ -42,16 +65,29 @@ export interface CursorAdapterDeps {
|
|
|
42
65
|
rekeyContextUsage?: (fromConversationId: string, toConversationId: string) => void;
|
|
43
66
|
}
|
|
44
67
|
|
|
45
|
-
function safeCursorTransportError(err: unknown): string {
|
|
68
|
+
function safeCursorTransportError(err: unknown, sizeContext?: CursorSizeContext): string {
|
|
46
69
|
if (err instanceof CursorTransportDisabledError) return CURSOR_TRANSPORT_DISABLED_MESSAGE;
|
|
47
70
|
if (err instanceof CursorMissingCredentialError) {
|
|
48
71
|
return "Cursor live transport is enabled, but no Cursor access token is configured. Set provider.apiKey or OPENCODEX_CURSOR_TEST_TOKEN.";
|
|
49
72
|
}
|
|
50
73
|
const message = err instanceof Error ? err.message : typeof err === "string" ? err : undefined;
|
|
51
|
-
if (message) return safeCursorErrorMessage(message);
|
|
74
|
+
if (message) return safeCursorErrorMessage(message, sizeContext);
|
|
52
75
|
return "Cursor upstream error: transport failed before completion.";
|
|
53
76
|
}
|
|
54
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Size prior for bare resource_exhausted classification (devlog 260): a rough input
|
|
80
|
+
* estimate over the outgoing text vs the model's context window. Only used to keep
|
|
81
|
+
* SMALL requests on the 429 class — unknown/large stays on the overflow mapping.
|
|
82
|
+
*/
|
|
83
|
+
function cursorRequestSizeContext(request: { modelId: string; system: string[]; messages: { content: string }[] }): CursorSizeContext {
|
|
84
|
+
const text = [...request.system, ...request.messages.map(message => message.content)].join("\n");
|
|
85
|
+
return {
|
|
86
|
+
estimatedInputTokens: estimateTokens(text, request.modelId),
|
|
87
|
+
contextWindow: inferCursorContextWindow(request.modelId),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
55
91
|
export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAdapterDeps = {}): ProviderAdapter {
|
|
56
92
|
return {
|
|
57
93
|
name: "cursor",
|
|
@@ -77,6 +113,9 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
|
|
|
77
113
|
emit({ type: "error", message: "Cursor turn was aborted before start." });
|
|
78
114
|
return;
|
|
79
115
|
}
|
|
116
|
+
// Captured after createCursorRequest so the catch block can apply the bare-RE
|
|
117
|
+
// size prior (devlog 260) even though `request` is scoped inside the try.
|
|
118
|
+
let requestSizeContext: CursorSizeContext | undefined;
|
|
80
119
|
try {
|
|
81
120
|
const makeTransport = deps.createTransport ?? createLiveCursorTransport;
|
|
82
121
|
const kv = deps.kv ?? createCursorKvStore({}, incoming.translatorBudget);
|
|
@@ -96,8 +135,10 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
|
|
|
96
135
|
/* Missing credential is handled by the live transport path below. */
|
|
97
136
|
}
|
|
98
137
|
}
|
|
138
|
+
const inheritedCheckpointRef = _parsed._providerContinuation?.cursor?.checkpointRef;
|
|
99
139
|
const previousConversationId = _parsed._cursorConversationId;
|
|
100
140
|
let request = createCursorRequest(_parsed);
|
|
141
|
+
requestSizeContext = cursorRequestSizeContext(request);
|
|
101
142
|
// The builder may derive a stable provider id from the client thread when Responses state
|
|
102
143
|
// is unavailable. Rekey only existing state; there is nothing to migrate on a fresh turn,
|
|
103
144
|
// and isolated helper/compaction turns must never inherit or donate the parent's usage state.
|
|
@@ -112,8 +153,115 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
|
|
|
112
153
|
let emittedOutput = false;
|
|
113
154
|
let replayUnsafe = false;
|
|
114
155
|
const lastRawIsToolResult = _parsed.context.messages.at(-1)?.role === "toolResult";
|
|
156
|
+
let completedNormally = false;
|
|
157
|
+
let lastTransport: { captured?: Uint8Array } | undefined;
|
|
158
|
+
let emittedClientTool = false;
|
|
159
|
+
// Ordering proof for tool-suspended checkpoints: true only when the newest captured
|
|
160
|
+
// checkpoint bytes arrived AFTER the turn emitted a client tool call, i.e. upstream
|
|
161
|
+
// serialized its suspended-on-tool-call state. Only that snapshot can safely resume
|
|
162
|
+
// with the covered-prefix + trailing-toolResult path (devlog 260826 050).
|
|
163
|
+
let capturedAfterClientTool = false;
|
|
164
|
+
|
|
165
|
+
const commitCapturedCheckpoint = (activeRequest: ReturnType<typeof createCursorRequest>): void => {
|
|
166
|
+
const toolSuspendedCommit =
|
|
167
|
+
emittedClientTool
|
|
168
|
+
&& capturedAfterClientTool
|
|
169
|
+
&& isCursorExternalWireModel(activeRequest.modelId);
|
|
170
|
+
if (
|
|
171
|
+
replayUnsafe
|
|
172
|
+
|| (emittedClientTool && !toolSuspendedCommit)
|
|
173
|
+
|| activeRequest.contextUsageStoreCheckpoints === false
|
|
174
|
+
|| !lastTransport?.captured
|
|
175
|
+
|| lastTransport.captured.byteLength === 0
|
|
176
|
+
) {
|
|
177
|
+
// Refusal diagnostics (devlog 260826 050/080): name the exact guard so a live
|
|
178
|
+
// missing_ref chain can be attributed without instrumented rebuilds.
|
|
179
|
+
debugProviderDiagnostic("cursor", "checkpoint-commit-refused", {
|
|
180
|
+
replayUnsafe,
|
|
181
|
+
emittedClientTool,
|
|
182
|
+
capturedAfterClientTool,
|
|
183
|
+
externalModel: isCursorExternalWireModel(activeRequest.modelId),
|
|
184
|
+
storeCheckpoints: activeRequest.contextUsageStoreCheckpoints !== false,
|
|
185
|
+
capturedBytes: lastTransport?.captured?.byteLength ?? 0,
|
|
186
|
+
});
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const previousRef = _parsed._providerContinuation?.cursor?.checkpointRef;
|
|
190
|
+
const coveredMessageCount = _parsed.context.messages.length;
|
|
191
|
+
const checkpointRef = commitCursorCheckpoint({
|
|
192
|
+
conversationId: activeRequest.conversationId,
|
|
193
|
+
identityScope: _parsed._cursorIdentityScope,
|
|
194
|
+
modelId: cursorCheckpointModelAffinityId(activeRequest.modelId),
|
|
195
|
+
checkpointBytes: lastTransport.captured,
|
|
196
|
+
coveredMessageCount,
|
|
197
|
+
prefixDigest: cursorCoveredPrefixDigest(_parsed, coveredMessageCount),
|
|
198
|
+
systemDigest: cursorInstructionDigest(_parsed),
|
|
199
|
+
});
|
|
200
|
+
if (!checkpointRef) return;
|
|
201
|
+
if (previousRef && previousRef !== checkpointRef) invalidateCursorCheckpoint(previousRef);
|
|
202
|
+
_parsed._providerContinuation = {
|
|
203
|
+
...(_parsed._providerContinuation ?? {}),
|
|
204
|
+
cursor: {
|
|
205
|
+
...(_parsed._providerContinuation?.cursor ?? {}),
|
|
206
|
+
conversationId: activeRequest.conversationId,
|
|
207
|
+
// A tool-suspended checkpoint is only usable by the immediate trailing-toolResult
|
|
208
|
+
// continuation; the request-builder guard keys on checkpointUsable=false for that.
|
|
209
|
+
checkpointUsable: !toolSuspendedCommit,
|
|
210
|
+
checkpointRef,
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
debugProviderDiagnostic("cursor", "checkpoint-continuation", {
|
|
214
|
+
mode: activeRequest.continuationMode ?? "full-replay",
|
|
215
|
+
conversationHash: activeRequest.conversationId.slice(0, 16),
|
|
216
|
+
checkpointRefHash: cursorCheckpointRefHash(checkpointRef),
|
|
217
|
+
checkpointBytes: lastTransport.captured.byteLength,
|
|
218
|
+
wireModel: activeRequest.modelId,
|
|
219
|
+
...(toolSuspendedCommit ? { toolSuspended: true } : {}),
|
|
220
|
+
});
|
|
221
|
+
};
|
|
115
222
|
|
|
116
223
|
const runOnce = async (activeRequest: ReturnType<typeof createCursorRequest>) => {
|
|
224
|
+
// Envelope echo quarantine (devlog 260826 gap-10): external full-replay continuations
|
|
225
|
+
// whose trailing input is a tool result sometimes ECHO the replayed "[Tool Result]"
|
|
226
|
+
// envelope as assistant text (kimi-k3 ~30-40% of multi-round probes). Hold the first
|
|
227
|
+
// text deltas until they provably diverge from the markers; a completed marker turns
|
|
228
|
+
// the turn into a retryable semantic failure BEFORE any client-visible delta escapes.
|
|
229
|
+
// Armed for ANY external turn whose replayed history contains a tool result — echo
|
|
230
|
+
// priming was observed live on user-action rounds too (the envelope lives in the
|
|
231
|
+
// flattened history regardless of which role ends the input).
|
|
232
|
+
const armEchoSniffer =
|
|
233
|
+
isCursorExternalWireModel(activeRequest.modelId)
|
|
234
|
+
&& (_parsed.context.messages ?? []).some(message => message.role === "toolResult");
|
|
235
|
+
const echoSniffer = armEchoSniffer ? new CursorEnvelopeEchoSniffer() : undefined;
|
|
236
|
+
// Mid-stream observer (devlog 260828 F1/F2): diagnostic-only; armed with the
|
|
237
|
+
// prefix sniffer because both fire on flattened tool-result replay priming.
|
|
238
|
+
const midstreamObserver = armEchoSniffer ? new CursorMidstreamEchoObserver() : undefined;
|
|
239
|
+
const armRoutingCommentarySniffer =
|
|
240
|
+
isCursorExternalWireModel(activeRequest.modelId)
|
|
241
|
+
&& (
|
|
242
|
+
cursorRequestUsesCodeMode(activeRequest.tools, activeRequest.toolChoice)
|
|
243
|
+
|| cursorRequestHasShellAlias(activeRequest.tools)
|
|
244
|
+
);
|
|
245
|
+
const routingCommentarySniffer = armRoutingCommentarySniffer
|
|
246
|
+
? new CursorRoutingCommentarySniffer()
|
|
247
|
+
: undefined;
|
|
248
|
+
let guardHeld: AdapterEvent[] = [];
|
|
249
|
+
// Exactly-once observation: every client-bound text delta passes through here
|
|
250
|
+
// exactly once — held deltas only on release, ordinary deltas at emit time.
|
|
251
|
+
const emitTextObserved = (event: AdapterEvent): void => {
|
|
252
|
+
if (event.type === "text_delta") midstreamObserver?.feed(event.text);
|
|
253
|
+
emit(event);
|
|
254
|
+
};
|
|
255
|
+
const releaseGuardHeld = () => {
|
|
256
|
+
for (const held of guardHeld) {
|
|
257
|
+
if (held.type !== "heartbeat") emittedOutput = true;
|
|
258
|
+
emitTextObserved(held);
|
|
259
|
+
}
|
|
260
|
+
guardHeld = [];
|
|
261
|
+
};
|
|
262
|
+
const guardsSettled = () =>
|
|
263
|
+
(!echoSniffer || echoSniffer.settled)
|
|
264
|
+
&& (!routingCommentarySniffer || routingCommentarySniffer.settled);
|
|
117
265
|
await runCursorTurnWithRetry(
|
|
118
266
|
makeTransport,
|
|
119
267
|
{
|
|
@@ -121,6 +269,8 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
|
|
|
121
269
|
headers: incoming.headers,
|
|
122
270
|
translatorBudget: incoming.translatorBudget,
|
|
123
271
|
requestDeclaresFullAccess: cursorRequestDeclaresFullAccess(activeRequest),
|
|
272
|
+
sessionId: activeRequest.conversationId,
|
|
273
|
+
...(incoming.providerFetch ? { fetch: incoming.providerFetch } : {}),
|
|
124
274
|
},
|
|
125
275
|
activeRequest,
|
|
126
276
|
incoming.abortSignal,
|
|
@@ -130,15 +280,89 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
|
|
|
130
280
|
return;
|
|
131
281
|
}
|
|
132
282
|
if (message.type === "local_side_effect") replayUnsafe = true;
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
283
|
+
if (message.type === "done") completedNormally = true;
|
|
284
|
+
if (message.type === "tool_call_end") emittedClientTool = true;
|
|
285
|
+
const captured = capturedCursorCheckpointBytes(activeTransport);
|
|
286
|
+
if (captured) {
|
|
287
|
+
if (captured !== lastTransport?.captured) capturedAfterClientTool = emittedClientTool;
|
|
288
|
+
lastTransport = { captured };
|
|
289
|
+
}
|
|
290
|
+
const events = mapCursorServerMessage(message, {
|
|
291
|
+
kv,
|
|
292
|
+
writeClient: clientMessage => {
|
|
293
|
+
void activeTransport.writeClient(clientMessage);
|
|
294
|
+
},
|
|
295
|
+
});
|
|
296
|
+
for (const event of events) {
|
|
297
|
+
if (!guardsSettled()) {
|
|
298
|
+
if (event.type === "text_delta") {
|
|
299
|
+
guardHeld.push(event);
|
|
300
|
+
if (echoSniffer && !echoSniffer.settled) {
|
|
301
|
+
const decision = echoSniffer.feed(event.text);
|
|
302
|
+
if (decision.kind === "echo") {
|
|
303
|
+
guardHeld = [];
|
|
304
|
+
throw new CursorToolResultEchoError(decision.marker);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
if (routingCommentarySniffer && !routingCommentarySniffer.settled) {
|
|
308
|
+
const decision = routingCommentarySniffer.feed(event.text);
|
|
309
|
+
if (decision.kind === "hallucination") {
|
|
310
|
+
guardHeld = [];
|
|
311
|
+
throw new CursorRoutingCommentaryError();
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (guardsSettled()) releaseGuardHeld();
|
|
315
|
+
continue;
|
|
316
|
+
} else if (event.type === "thinking_delta" || event.type === "heartbeat") {
|
|
317
|
+
// Reasoning before first text stays ordered; liveness still passes through.
|
|
318
|
+
if (event.type === "thinking_delta") {
|
|
319
|
+
guardHeld.push(event);
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
} else {
|
|
323
|
+
// A tool call, done, or error closes the text quarantine. Re-check the full
|
|
324
|
+
// held first line before release so a fragmented routing claim cannot leak.
|
|
325
|
+
echoSniffer?.finish();
|
|
326
|
+
const routingDecision = routingCommentarySniffer?.finish();
|
|
327
|
+
if (routingDecision?.kind === "hallucination") {
|
|
328
|
+
guardHeld = [];
|
|
329
|
+
throw new CursorRoutingCommentaryError();
|
|
330
|
+
}
|
|
331
|
+
releaseGuardHeld();
|
|
332
|
+
}
|
|
333
|
+
}
|
|
140
334
|
if (event.type !== "heartbeat") emittedOutput = true;
|
|
141
|
-
|
|
335
|
+
if (event.type === "done") {
|
|
336
|
+
for (const finding of midstreamObserver?.findings() ?? []) {
|
|
337
|
+
debugProviderDiagnostic("cursor", "midstream-envelope-echo", {
|
|
338
|
+
wireModel: activeRequest.modelId,
|
|
339
|
+
conversationHash: activeRequest.conversationId.slice(0, 16),
|
|
340
|
+
marker: finding.marker,
|
|
341
|
+
offset: finding.offset,
|
|
342
|
+
callIdCorrupt: finding.callIdCorrupt,
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
commitCapturedCheckpoint(activeRequest);
|
|
346
|
+
const inheritedCursor = _parsed._providerContinuation?.cursor;
|
|
347
|
+
const isolatedOrCompaction =
|
|
348
|
+
_parsed._cursorIsolateConversation === true
|
|
349
|
+
|| activeRequest.contextUsageStoreCheckpoints === false;
|
|
350
|
+
const providerState = inheritedCursor
|
|
351
|
+
? {
|
|
352
|
+
cursor: isolatedOrCompaction
|
|
353
|
+
? {
|
|
354
|
+
conversationId: activeRequest.conversationId,
|
|
355
|
+
...(inheritedCursor.checkpointUsable !== undefined
|
|
356
|
+
? { checkpointUsable: inheritedCursor.checkpointUsable }
|
|
357
|
+
: {}),
|
|
358
|
+
}
|
|
359
|
+
: { ...inheritedCursor, conversationId: activeRequest.conversationId },
|
|
360
|
+
}
|
|
361
|
+
: undefined;
|
|
362
|
+
emit(providerState ? { ...event, providerState } : event);
|
|
363
|
+
} else {
|
|
364
|
+
emitTextObserved(event);
|
|
365
|
+
}
|
|
142
366
|
}
|
|
143
367
|
},
|
|
144
368
|
);
|
|
@@ -147,35 +371,108 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
|
|
|
147
371
|
try {
|
|
148
372
|
await runOnce(request);
|
|
149
373
|
} catch (err) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
374
|
+
const outputGuardRetryText =
|
|
375
|
+
err instanceof CursorToolResultEchoError
|
|
376
|
+
? CURSOR_ECHO_RETRY_CONTINUATION_TEXT
|
|
377
|
+
: err instanceof CursorRoutingCommentaryError
|
|
378
|
+
? CURSOR_ROUTING_COMMENTARY_RETRY_TEXT
|
|
379
|
+
: undefined;
|
|
380
|
+
// One-shot corrective retry for guarded external output (devlog 260826 gap-10/11).
|
|
381
|
+
// The quarantine guarantees no client-visible delta escaped, so a fresh-conversation
|
|
382
|
+
// retry is safe. A second rejection propagates as an error rather than looping.
|
|
153
383
|
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|| replayUnsafe
|
|
159
|
-
|| incoming.abortSignal?.aborted
|
|
384
|
+
outputGuardRetryText
|
|
385
|
+
&& !emittedOutput
|
|
386
|
+
&& !replayUnsafe
|
|
387
|
+
&& !incoming.abortSignal?.aborted
|
|
160
388
|
) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
// compaction turns must not park their throwaway id under the parent thread key.
|
|
171
|
-
if (_parsed._clientThreadId && _parsed._cursorIsolateConversation !== true) {
|
|
172
|
-
rememberCursorThreadConversation(
|
|
173
|
-
_parsed._clientThreadId,
|
|
174
|
-
request.conversationId,
|
|
175
|
-
_parsed._cursorIdentityScope,
|
|
389
|
+
debugProviderDiagnostic(
|
|
390
|
+
"cursor",
|
|
391
|
+
err instanceof CursorToolResultEchoError
|
|
392
|
+
? "envelope-echo-retry"
|
|
393
|
+
: "routing-commentary-retry",
|
|
394
|
+
{
|
|
395
|
+
wireModel: request.modelId,
|
|
396
|
+
conversationHash: request.conversationId.slice(0, 16),
|
|
397
|
+
},
|
|
176
398
|
);
|
|
399
|
+
const echoedConversationId = request.conversationId;
|
|
400
|
+
lastTransport = undefined;
|
|
401
|
+
_parsed._cursorConversationId = undefined;
|
|
402
|
+
request = {
|
|
403
|
+
...createCursorRequest(_parsed, { forceFreshConversation: true }),
|
|
404
|
+
echoRetryContinuationText: outputGuardRetryText,
|
|
405
|
+
};
|
|
406
|
+
rekeyContextUsage(echoedConversationId, request.conversationId);
|
|
407
|
+
_parsed._cursorConversationId = request.conversationId;
|
|
408
|
+
const echoThreadOwner = cursorClientThreadOwner(_parsed);
|
|
409
|
+
if (echoThreadOwner && _parsed._cursorIsolateConversation !== true) {
|
|
410
|
+
rememberCursorThreadConversation(
|
|
411
|
+
echoThreadOwner,
|
|
412
|
+
request.conversationId,
|
|
413
|
+
_parsed._cursorIdentityScope,
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
await runOnce(request);
|
|
417
|
+
} else {
|
|
418
|
+
// One-shot fallback for external-model Connect invalid_argument before any
|
|
419
|
+
// non-heartbeat output. Retries apply only to safe plain-user turns; tool-result
|
|
420
|
+
// resumes, local exec/MCP side effects, and already-emitted output fail closed.
|
|
421
|
+
if (
|
|
422
|
+
!isCursorInvalidArgumentError(err)
|
|
423
|
+
|| !isCursorExternalWireModel(request.modelId)
|
|
424
|
+
|| lastRawIsToolResult
|
|
425
|
+
|| emittedOutput
|
|
426
|
+
|| replayUnsafe
|
|
427
|
+
|| incoming.abortSignal?.aborted
|
|
428
|
+
) {
|
|
429
|
+
throw err;
|
|
430
|
+
}
|
|
431
|
+
const failedConversationId = request.conversationId;
|
|
432
|
+
lastTransport = undefined;
|
|
433
|
+
_parsed._cursorConversationId = undefined;
|
|
434
|
+
request = createCursorRequest(_parsed, { forceFreshConversation: true });
|
|
435
|
+
rekeyContextUsage(failedConversationId, request.conversationId);
|
|
436
|
+
_parsed._cursorConversationId = request.conversationId;
|
|
437
|
+
// Persist recovery for store:false clients that send any stable Cursor thread owner, so
|
|
438
|
+
// the next turn does not recompute the stale deterministic thread hash. Isolated helper /
|
|
439
|
+
// compaction turns must not park their throwaway id under the parent or Desktop owner.
|
|
440
|
+
const threadOwner = cursorClientThreadOwner(_parsed);
|
|
441
|
+
if (threadOwner && _parsed._cursorIsolateConversation !== true) {
|
|
442
|
+
rememberCursorThreadConversation(
|
|
443
|
+
threadOwner,
|
|
444
|
+
request.conversationId,
|
|
445
|
+
_parsed._cursorIdentityScope,
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
await runOnce(request);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (
|
|
452
|
+
request.checkpointInvalidationReason
|
|
453
|
+
&& request.checkpointInvalidationReason !== "missing_ref"
|
|
454
|
+
) {
|
|
455
|
+
invalidateCursorCheckpoint(inheritedCheckpointRef);
|
|
456
|
+
debugProviderDiagnostic("cursor", "checkpoint-invalidated", {
|
|
457
|
+
reason: request.checkpointInvalidationReason,
|
|
458
|
+
});
|
|
459
|
+
} else if (!completedNormally && request.checkpointInvalidationReason) {
|
|
460
|
+
debugProviderDiagnostic("cursor", "checkpoint-invalidated", {
|
|
461
|
+
reason: request.checkpointInvalidationReason,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
if (
|
|
465
|
+
_parsed._cursorIsolateConversation === true
|
|
466
|
+
|| request.contextUsageStoreCheckpoints === false
|
|
467
|
+
) {
|
|
468
|
+
const inherited = _parsed._providerContinuation?.cursor;
|
|
469
|
+
if (inherited) {
|
|
470
|
+
const { checkpointRef: _ignoredCheckpointRef, ...cursorWithoutCheckpointRef } = inherited;
|
|
471
|
+
_parsed._providerContinuation = {
|
|
472
|
+
...(_parsed._providerContinuation ?? {}),
|
|
473
|
+
cursor: cursorWithoutCheckpointRef,
|
|
474
|
+
};
|
|
177
475
|
}
|
|
178
|
-
await runOnce(request);
|
|
179
476
|
}
|
|
180
477
|
} catch (err) {
|
|
181
478
|
if (isCursorBenignCancelError(err)) return;
|
|
@@ -184,7 +481,7 @@ export function createCursorAdapter(provider: OcxProviderConfig, deps: CursorAda
|
|
|
184
481
|
type: "error",
|
|
185
482
|
message: isTranslatorBudgetExceededError(err)
|
|
186
483
|
? "upstream translation buffer exceeded the safe limit"
|
|
187
|
-
: safeCursorTransportError(err),
|
|
484
|
+
: safeCursorTransportError(err, requestSizeContext),
|
|
188
485
|
...(isTranslatorBudgetExceededError(err)
|
|
189
486
|
? { status: 502, errorType: "upstream_error", code: "translation_buffer_limit" }
|
|
190
487
|
: {}),
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-neutral empty-exec-output normalization.
|
|
3
|
+
*
|
|
4
|
+
* A code-mode `exec` cell that never calls `text()`/`notify()` returns nothing: the last
|
|
5
|
+
* expression value is NOT echoed automatically. The routed model reads a blank tool result,
|
|
6
|
+
* concludes its earlier output was lost, and burns turns re-running the same call or restarting
|
|
7
|
+
* the task from scratch. Naming that state explicitly is what breaks the loop.
|
|
8
|
+
*
|
|
9
|
+
* This module owns the shared detection so every adapter reports the same thing. Cursor keeps its
|
|
10
|
+
* own wrapper (`normalizeCursorToolResultText`) for Computer Use precedence and isError policy;
|
|
11
|
+
* Kiro consumes this helper directly.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Matches exec wrappers whose only payload is an empty-output marker.
|
|
16
|
+
*
|
|
17
|
+
* `Script failed` is deliberately NOT in this set. A failed cell with no captured output is still
|
|
18
|
+
* a FAILURE, and the success guidance below ("not a blocked tool", "do not re-run") would erase the
|
|
19
|
+
* only signal that anything went wrong — reachable through Responses history, where
|
|
20
|
+
* `function_call_output` is parsed with `isError: false`. Cursor keeps its own broader regex for
|
|
21
|
+
* Computer Use, where a failed wrapper is separately marked `isError`.
|
|
22
|
+
*/
|
|
23
|
+
export const EMPTY_EXEC_OUTPUT_REGEX = /^(?:(?:Script completed|Command finished|Execution finished)[^\n]*\n+)?(?:Wall time[^\n]*\n+)?(?:Output:\s*)?(?:<empty>)?\s*$/;
|
|
24
|
+
|
|
25
|
+
/** Wrapper for a cell that FAILED without emitting output: empty, but not a success. */
|
|
26
|
+
export const FAILED_EXEC_OUTPUT_REGEX = /^Script failed[^\n]*\n*(?:Wall time[^\n]*\n*)?(?:Output:\s*)?(?:<empty>)?\s*$/;
|
|
27
|
+
|
|
28
|
+
/** Guidance for a failed cell whose output was empty: the failure must survive normalization. */
|
|
29
|
+
export const FAILED_EXEC_OUTPUT_MESSAGE =
|
|
30
|
+
"[exec failed with no captured output: the cell raised before emitting anything. This is a real failure, not an empty success — inspect the call for a thrown error or syntax problem before retrying.]";
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The guidance itself. Worded to close all three wrong conclusions a model draws from a blank
|
|
34
|
+
* result: that context was lost, that the tool is blocked, and that retrying will differ.
|
|
35
|
+
*/
|
|
36
|
+
export const EMPTY_EXEC_OUTPUT_MESSAGE =
|
|
37
|
+
"[empty output: the exec cell completed but emitted nothing. This is NOT lost context and NOT a blocked tool — in code mode call text(...) or notify(...) on any value you need to see (a bare await tools.exec_command(...) is not echoed automatically); in shell mode the command simply printed nothing. Do not re-run the same call expecting different output.]";
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The SAME rule stated BEFORE the first call, for the code-mode tool-catalog nudge.
|
|
41
|
+
*
|
|
42
|
+
* `EMPTY_EXEC_OUTPUT_MESSAGE` above is a repair: it fires only after a model has already spent a
|
|
43
|
+
* call and read a blank result. That recovers the turn but cannot prevent the wasted round trip,
|
|
44
|
+
* and the model still has to guess whether its command failed or its output was merely dropped.
|
|
45
|
+
* Stating the echo rule up front removes the failure instead of explaining it afterwards.
|
|
46
|
+
*
|
|
47
|
+
* Kept beside the recovery text on purpose: the two are one pair guarding one defect, and wording
|
|
48
|
+
* that drifts apart is how a model gets told two different things about the same isolate.
|
|
49
|
+
*/
|
|
50
|
+
export const CODE_MODE_RESULT_ECHO_SENTENCE =
|
|
51
|
+
"Nothing in the isolate is echoed automatically: a bare trailing `await tools.<name>(...)` or final expression value is DISCARDED, and the cell reports empty output. Pass anything you need to read to `text(...)` (or `notify(...)`) in the same cell — for example `text(JSON.stringify(await tools.exec_command({cmd: \"ls\"})))` — and treat an empty result as your own missing `text(...)` call rather than a failed command or lost context.";
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Codex exec / shell-bridge tool names (flat and MCP-prefixed display aliases). An empty result
|
|
55
|
+
* here is almost always a code-mode cell that never called text()/notify().
|
|
56
|
+
*/
|
|
57
|
+
export function isCodexExecBridgeTool(toolName?: string, toolNamespace?: string): boolean {
|
|
58
|
+
if (toolNamespace && toolNamespace.includes("opencodex-responses")) return true;
|
|
59
|
+
if (!toolName) return false;
|
|
60
|
+
const lower = toolName.toLowerCase();
|
|
61
|
+
return (
|
|
62
|
+
lower === "exec"
|
|
63
|
+
|| lower === "exec_command"
|
|
64
|
+
|| lower === "shell_command"
|
|
65
|
+
// Codex CLI/desktop native tool names: the multi-round "이전 출력이 비어 있어 처음부터"
|
|
66
|
+
// restart loop reproduced via codex exec because `shell` was not in this set
|
|
67
|
+
// (devlog 260826 gap-8 QA round 2).
|
|
68
|
+
|| lower === "shell"
|
|
69
|
+
|| lower === "local_shell"
|
|
70
|
+
|| lower === "container.exec"
|
|
71
|
+
|| lower.startsWith("mcp_opencodex-responses_")
|
|
72
|
+
|| lower.startsWith("mcp__opencodex-responses__")
|
|
73
|
+
);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** True when this result is an exec-bridge call that produced no usable output. */
|
|
77
|
+
export function isEmptyExecToolResult(
|
|
78
|
+
text: string,
|
|
79
|
+
options: { toolName?: string; toolNamespace?: string } = {},
|
|
80
|
+
): boolean {
|
|
81
|
+
return isCodexExecBridgeTool(options.toolName, options.toolNamespace)
|
|
82
|
+
&& EMPTY_EXEC_OUTPUT_REGEX.test(text.trim());
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Returns the guidance text when this is an empty exec-bridge result, else `undefined` so the
|
|
87
|
+
* caller keeps its own fallback. Undefined rather than the original text: an adapter must be able
|
|
88
|
+
* to tell "not my case" from "normalized to the same string".
|
|
89
|
+
*/
|
|
90
|
+
export function normalizeEmptyExecToolResultText(
|
|
91
|
+
text: string,
|
|
92
|
+
options: { toolName?: string; toolNamespace?: string } = {},
|
|
93
|
+
): string | undefined {
|
|
94
|
+
if (!isCodexExecBridgeTool(options.toolName, options.toolNamespace)) return undefined;
|
|
95
|
+
const trimmed = text.trim();
|
|
96
|
+
// Failure first: a failed wrapper must never be described as an empty success.
|
|
97
|
+
if (FAILED_EXEC_OUTPUT_REGEX.test(trimmed)) return FAILED_EXEC_OUTPUT_MESSAGE;
|
|
98
|
+
return EMPTY_EXEC_OUTPUT_REGEX.test(trimmed) ? EMPTY_EXEC_OUTPUT_MESSAGE : undefined;
|
|
99
|
+
}
|