Skip to content

[Bug]: Cursor adapter always full-replays with cached_tokens=0; direct cursor-agent cache-hits on the same account #4245

Description

@whelp99-code

Client or integration

Codex CLI and Codex App (same OpenCodex proxy)

Area

Provider adapter / Cursor continuation + cache

Provider or upstream service

cursor (adapter: "cursor", OAuth, https://api2.cursor.sh)

OpenCodex version

2.48.0 (ocx --version; running proxy matched)

Operating system

macOS (darwin 25.5.0)

Endpoint or capability

POST /v1/responses → Cursor adapter runTurn / AgentService/Run

Provider and model

  • OpenCodex route: cursor/auto-intelligence (Cursor Router wire model default)
  • Native control on the same proxy: gpt-5.6-sol
  • Direct Cursor control (OpenCodex not in path): cursor-agent --model auto

Summary

A two-turn Reply only OK / Reply only OK2 pair on the same machine and Cursor account shows:

  • Direct cursor-agent: turn 2 input collapses to 253 tokens with cacheReadTokens=25856.
  • Native gpt-5.6-sol through OpenCodex: turn 2 reports cached_input_tokens=21504.
  • cursor/auto-intelligence through OpenCodex: turn 2 is 74477 input with zero cache. Provider debug is continuationMode=full-replay, checkpointPresent=false, checkpointInvalidationReason=missing_ref on both turns. checkpoint-commit-refused fires with emittedClientTool=true.

This is not the old large-catalog resource_exhausted failure (#190) and not the kimi-k3 short-output collapse (#1527, closed on 2.41.0). HTTP is 200. The remaining #1527 cache note (direct cacheReadTokens vs cached_tokens=0 through the proxy) still reproduces here, and the debug fields requested in #1527 are now available.

#3433 tracks intermittent zero cache on the Hermes → Chat Completions → Codex Responses path. This report is the Cursor runTurn checkpoint/replay path, so it is filed separately.

Current behaviour

Isolated Codex CLI (--ignore-user-config, openai_base_url pointed at loopback OpenCodex, no user plugins):

Client Model Turn input cache OpenCodex usage
Codex CLI cursor/auto-intelligence 1 (ephemeral) 22122 0 estimated, no cachedTokens
Codex CLI gpt-5.6-sol 1 (ephemeral) 21159 0 reported
Codex CLI gpt-5.6-sol 2 (resume) 49654 21504 reported
Codex CLI cursor/auto-intelligence 1 (persisted) 45213 0 estimated
Codex CLI cursor/auto-intelligence 2 (resume) 74477 0 estimated
cursor-agent --print --mode ask auto 1 18029 7936 n/a (direct)
cursor-agent resume auto 2 253 25856 n/a (direct)

ocx debug provider on the isolated Cursor conversation (ids redacted to 12 chars):

[ocx:cursor:run-request] turnType=initial rawMessages=3 continuationMode=full-replay checkpointPresent=false checkpointInvalidationReason=missing_ref rootBlobs=4 rootBytes=54328 turnBlobs=2 tools=3
[ocx:cursor:checkpoint-commit-refused] emittedClientTool=true capturedAfterClientTool=true capturedBytes=1969
[ocx:cursor:run-request] turnType=tool-continuation rawMessages=5 continuationMode=full-replay checkpointPresent=false checkpointInvalidationReason=missing_ref rootBlobs=5 rootBytes=54394
[ocx:cursor:checkpoint-continuation] mode=full-replay
# after resume "Reply only OK2"
[ocx:cursor:run-request] action=userMessageAction rawMessages=10 continuationMode=full-replay checkpointPresent=false checkpointInvalidationReason=missing_ref rootBlobs=9 rootBytes=82007

Adapter docs say a successful no-tool turn should reuse ConversationStateStructure on the next linear continuation. These turns were no-tool user messages (Reply only OK / Reply only OK2) and still full-replayed.

Expected behaviour

On a validated linear continuation of the same Cursor account/model/thread:

  1. continuationMode should become checkpoint (or equivalent suffix-only replay) after the first successful turn, matching https://opencodex.me/reference/adapters/ and the fix(cursor): reuse conversation checkpoints for incremental continuation (#2054 rebased) #2277 / [Bug]: Cursor adapter large-context turns collapse or rate-limit while direct Cursor remains healthy #1527 follow-up.
  2. OpenCodex should not grow rootBytes from ~54 KiB to ~82 KiB for a one-line follow-up.
  3. Either Cursor cache_read / cached_tokens should be non-zero on turn 2 (as direct cursor-agent and routed Sol already are on this install), or usage should stop advertising a cache-hit counter it cannot see — but the request itself should not full-replay.

Reproduction

Proxy already running on 127.0.0.1:10100. Cursor OAuth logged in (ocx login cursor). Then:

ocx debug provider on

CODEX_BIN="$(command -v codex.opencodex-real || command -v codex)"
WORKDIR="$(mktemp -d)"

# A. isolated Cursor, two turns
"$CODEX_BIN" exec \
  --ignore-user-config --skip-git-repo-check --json --color never \
  -m cursor/auto-intelligence \
  -c openai_base_url='"http://127.0.0.1:10100/v1"' \
  -c model_catalog_json="\"${CODEX_HOME:-$HOME/.codex}/opencodex-catalog.json\"" \
  -c model_reasoning_effort='"none"' \
  -c approval_policy='"never"' \
  -s read-only -C "$WORKDIR" \
  "Reply only OK"

"$CODEX_BIN" exec resume --ignore-user-config --skip-git-repo-check --json \
  --dangerously-bypass-approvals-and-sandbox \
  -m cursor/auto-intelligence \
  -c openai_base_url='"http://127.0.0.1:10100/v1"' \
  -c model_catalog_json="\"${CODEX_HOME:-$HOME/.codex}/opencodex-catalog.json\"" \
  --last \
  "Reply only OK2"

# B. same pair with -m gpt-5.6-sol (control)
# C. direct Cursor, OpenCodex not in path
cursor-agent --print --mode ask --output-format json --trust \
  --sandbox disabled --model auto --workspace "$WORKDIR" \
  "Reply only OK"
# then --resume <session_id> "Reply only OK2"

First-turn isolated Cursor vs Sol is close (22.1k vs 21.2k). The defect is the second turn.

Actual response or error

No transport error. Both Cursor turns completed 200 / OK / OK2. Codex JSON usage for the Cursor resume:

turn.completed usage: input_tokens=74477 cached_input_tokens=0 cache_write_input_tokens=0 output_tokens=24

Direct cursor-agent resume JSON (redacted ids):

usage: inputTokens=253 outputTokens=17 cacheReadTokens=25856 cacheWriteTokens=0

WebSocket to ws://127.0.0.1:10100/v1/responses returns 426 and Codex falls back to HTTP/SSE. That fallback succeeds and is not the failure.

Upstream documentation

No public Cursor Connect spec. The expected continuation contract is OpenCodex’s own adapter document plus the direct cursor-agent control on the same account.

Suggested mapping or implementation notes

Highest-confidence local hypothesis: resolveCursorCheckpoint() never accepts the previous turn (missing_ref), and checkpoint-commit-refused with emittedClientTool=true prevents storing a checkpoint even when the user turn had no tool call from Codex’s point of view (only the advertised exec / client-tool catalog).

#1527 asked for exactly these run-request fields. They now show full-replay on a 2-line isolated thread, not only on huge Desktop catalogs.

Please do not treat “disable Desktop App Tools” as the fix. That only slows Codex Desktop context_window_exceeded (190k window on cursor/auto-intelligence, ~35–42k/turn, cache 0). The isolated CLI pair above already has almost no plugins and still full-replays.

Additional context

Related:

Codex CLI used for the pair: 0.147.0 (OpenCodex-selected). Codex Desktop 0.153.4 shows the same estimated / cache-0 pattern on cursor/auto-intelligence in daily use, but the CLI pair is the clean reproduction.

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.
  • The request and response were redacted.
  • The expected behaviour is based on OpenCodex adapter docs and a same-account direct Cursor control.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    account-poolOAuth, credentials, Codex pool, quota, failover, planscatalogModel catalog, slugs, visibility, routed entrieslanded-via-maintainerOriginal PR closed after landing via a maintainer merge trainproviderProvider adapters, OpenAI-compat presets, upstream API quirksprovider-compatibilityProvider compatibility reports

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions