[Bug]: Claude Messages to Astra cache plateau/reset with growing history; Codex CLI comparison
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 48/100
- Issue type
- Bug
- Clarity
- Mostly clear
- Activity status
- Active
- Tech stack
- typescript
- Domain
- backend-api-design
Research direction
Start with the named paths in src/claude/inbound.ts, src/server/claude-messages.ts, and src/adapters/openai-responses.ts to trace cache-key and session identity through the native forward boundary; review src/claude/outbound.ts for usage mapping. Capture only field presence, equality, and prefix-change locations across a warm/cold pair, including tools, instructions, history, identifiers, and selected account. Done means the evidence distinguishes client prefix changes, OCX translation, and upstream cache placement or expiry.
Written by the indexing model from the issue text.
Description
Client or integration
Claude Desktop 3P and ocx claude, compared with Codex CLI.
Area
Proxy and routing: Anthropic Messages to native OpenAI Responses.
Summary
With gpt-6-astra, a Claude Desktop main-agent conversation reused essentially the same 27.6k-token prefix across several continuations, despite growing input. Separate synthetic ocx claude sequences show that this route can grow cache reads, but one also went warm → cold within seconds. A Codex CLI control grew its cached prefix on every continuation.
This reports measured symptoms, not a proven OCX root cause or a claim that every continuation must hit cache. Please investigate prefix preservation and effective session/cache identity at the native forward boundary. Existing logs do not distinguish client prefix changes, OCX translation, and upstream cache placement/expiry.
Version
OpenCodex CLI and running proxy: 2.43.0, no version skew at the time of measurement.
Operating system
macOS 26.5.2.
Provider and model
OpenAI / gpt-6-astra, native OpenAI Responses adapter through a local OCX proxy.
Additional environment details
- Desktop embedded Claude Code: 2.1.260, transcript entrypoint
claude-desktop-3p. - Standalone Claude Code: 2.1.258.
- Codex CLI: 0.153.2.
- Local loopback proxy; native OpenAI account-pool route,
openai-responsesadapter. - All successful rows below: resolved
gpt-6-astra, requested efforthigh, HTTP 200, one attempt, the same anonymized account label A. This does not prove a common upstream cache machine/cohort. - Measurements: 2026-09-06, 10:18–10:34 UTC.
Desktop main-agent evidence
OCX's conversation group also contained a child Astra agent and Luna calls. I matched the local Desktop transcript to OCX usage by input/cache counts and timestamps, selected isSidechain=false, and deduplicated assistant content blocks sharing one message ID. Only the six main-agent requests are below:
| Request start UTC | Total input tokens | Cache-read tokens | Read share |
|---|---|---|---|
| 10:18:45 | 43,084 | 0 | 0.0% |
| 10:20:13 | 43,201 | 27,648 | 64.0% |
| 10:21:49 | 43,653 | 27,648 | 63.3% |
| 10:21:54 | 43,816 | 27,648 | 63.1% |
| 10:22:08 | 45,592 | 27,648 | 60.6% |
| 10:24:06 | 47,427 | 28,928 | 61.0% |
Total: 139,520 / 266,773 = 52.3% cache reads; excluding the initial cold request, 62.4%. Requests 2–5 remain at exactly 27,648 cached tokens. The first two responses are text; request 3 returns a Skill call; thinking blocks first appear in response 4. Thus dropping prior thinking blocks cannot explain the earliest plateau by itself. No compaction event appears in this main transcript.
The five child-Astra rows and four Luna rows are excluded from this table. Treating the whole log conversation group as the main agent would give a misleading result.
Synthetic CLI comparisons
Each sequence used a fresh session, the same generated user-text growth pattern, four sequential turns with --resume/exec resume, high effort, and the response OK. No tools were called. Earlier user records were retained; each turn appended 120 new records after an initial 400. Each session's OCX conversation ID remained nonempty and equal across its successful requests.
| Sequence | Total input tokens by turn | Cache-read tokens by turn |
|---|---|---|
| Codex CLI | 29,150 → 31,361 → 33,572 → 35,783 | 0 → 28,928 → 31,232 → 33,408 |
ocx claude --bare, explicit fixed system prompt |
7,388 → 9,599 → 11,810 → 14,021 | 0 → 0 → 9,472 → 11,648 |
ocx claude --bare, no custom system prompt |
7,412 → 9,623 → 11,834 → 14,045 | 0 → 7,296 → 9,472 → 0 |
The last sequence's request starts were 10:33:46, 10:33:49, 10:33:54, and 10:33:58 UTC. Its final successful turn lost all reported cache reads about five seconds after a warm request.
These are minimal controls, not identical wire payloads or a client performance ranking: the clients have different system/tool envelopes, Desktop used real tools, and the standalone/embedded Claude versions differ. Two additional startup rows, one per Claude sequence, returned 499 without reported usage; they are excluded rather than counted as zero-cache successes.
Reproduction
The intermittent miss is not established as deterministic. To repeat the minimal comparison:
-
Use an already running local OCX proxy with the same Astra route. Use a disposable working directory and isolated
CLAUDE_CONFIG_DIRfor Claude. -
Generate records using:
records = '\n'.join( f'Record {i:04d}: amber cedar river stone meadow lantern willow garden copper island violet orchard.' for i in range(start, end) )Ranges:
[0,400),[400,520),[520,640),[640,760). Each turn asks to retain the reference records, reply onlyOK, and take no external action. -
Claude invocation:
ocx claude --bare -p --output-format json --model gpt-6-astra --effort high --tools '' --strict-mcp-config --mcp-config '{"mcpServers":{}}' --setting-sources '' --max-turns 1, then--resume <returned-session-id>for later turns. Supply authentication appropriate to the local proxy. For this loopback-only sample, an invocation-scopedapiKeyHelperreturned OCX's documentedopencodex-proxymarker; no upstream credential or global auth setting was changed. The first Claude sequence additionally supplied a fixed--system-promptasking only forOKand no tools. The second omitted that override. -
Codex invocation:
codex exec --ignore-user-config --skip-git-repo-check --json -m gpt-6-astra -c 'openai_base_url="http://127.0.0.1:10100/v1"' -c 'model_reasoning_effort="high"' -c 'project_doc_max_bytes=0' -c 'features.shell_tool=false' -c 'features.apply_patch_freeform=false' -c 'sandbox_mode="read-only"' -c 'approval_policy="never"' -. Continue the returned ID withcodex exec resume, retaining the same overrides. Prompts go through stdin. -
Correlate successful requests in
usage.jsonl. OCX/OpenAIinputTokensincludes cached input; Claude's clientinput_tokensexcludes it. Add Claude input + cache-read + cache-creation before comparing. Client totals and OCX totals agreed in these samples.
Source checks and remaining evidence gap
The following installed files were byte-identical to main at commit 06ec553630fa2ee51a96b5cbf694089021249194:
inbound.ts: metadata-backed cache key generation; also contains the assistant thinking-drop policy.claude-messages.ts: native metadata-backed requests synthesize an underscoresession_idheader from that key.outbound.ts: cache counters are mapped into Anthropic usage.src/adapters/openai-responses.ts: includessession_idin forward headers and reads upstream cached-token usage.
The populated conversation groups are consistent with metadata-backed identity, but there was no inbound/outbound wire capture. Stable logged identity/account labels do not establish byte-identical prefixes or the effective forwarded headers. Claude inbound debug was disabled. The next useful capture would record only field presence/equality and prefix-change locations across a warm/cold pair, including tools/instructions/history, cache key, underscore/hyphenated session identifiers, and selected account. No private request content is needed publicly.
Related: #3433 tracks Hermes Chat Completions cache misses with missing identity fields; this report adds the Claude Messages path with populated conversation correlation and a Desktop main-agent plateau. #3719 explicitly concerns intentional Anthropic upstream thinking replay; this report's upstream is OpenAI Astra. No duplicate claiming this exact comparison was found.
Checks
- Searched existing issues and current source.
- Removed personal paths, original prompts, session IDs, account identifiers, credentials, and private tool output.
- No proxy/provider configuration change, restart, or local source patch was made for this investigation.
- Dominant language
- TypeScript
- Stars
- 16.9k
- Forks
- 1.3k
- Avg merge
- 7h 38m
- Merged PRs (30d)
- 659
Getting set up
This project ships no dev container, Dockerfile or contributing guide, so setting up is up to you: start from its README, and see our first-contribution guide for the general steps.
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from lidge-jun/opencodex
-
account-pool bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
lidge-jun/opencodex#7440 · 2 comments ·
Maintainers usually reply within 1 day
-
[Docs]: translate the #7395 OpenGateway and Mistral provider-guide sectionsPossibly taken @MannXo claimed this today. Opendocumentation
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
lidge-jun/opencodex#7405 · 3 comments ·
Maintainers usually reply within 1 day
-
bug cli
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
lidge-jun/opencodex#7403 · 2 comments ·
Maintainers usually reply within 1 day
-
account-pool enhancement needs-design proxy
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
lidge-jun/opencodex#6737 · 1 comment ·
Maintainers usually reply within 1 day
-
enhancement proxy
Difficulty 4/5 1-2 days Newbie friendliness 55/100
lidge-jun/opencodex#7443 · 3 comments ·
Maintainers usually reply within 1 day
All issues in lidge-jun/opencodex
Similar issues
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
getsentry/sentry-conventions#732 · 1 comment ·
Maintainers usually reply within 1 day
-
status:in-linear status:team-assigned team:nodes
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
n8n-io/n8n#41548 · 2 comments ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
motiondivision/motion#3955 ·
Maintainers usually reply within 1 day
-
enhancement
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
equinor/prisma-decision-web#919 ·
Maintainers usually reply within 1 day
-
Difficulty 1/5 Under an hour Newbie friendliness 83/100