anthropics / anthropics/claude-code
Channel messages are merged into the previous user message and re-rendered on the next request, losing the prompt cache on non-Anthropic backends
- Lenguaje dominante
- Python
- Estrellas
- 145k
- Forks
- 23.1k
- Métricas de merge de PR
- Métricas de PR pendientes
Descripción
**Environment:** Claude Code 2.1.268 (Linux/WSL2), Channels (experimental) via the Atrium plugin (`inject directly`), `ANTHROPIC_BASE_URL` → CLI Proxy API → OpenAI Responses (`gpt-5.6-sol` / `gpt-6-astra`). Also observed on 2.1.26x sessions routed to `gpt-6-astra`.
**What I observe.** With a metadata-only diff of consecutive upstream requests (per-item hashes and byte lengths, no content), a session receiving channel messages produces requests that are not append-only: the previous user message is re-rendered (1,516 B → 2,552 B when a channel message is delivered, then split into 364/436/317 B + a new item on the next request), and `reasoning`/thinking items of the affected turns are inserted or removed before an earlier assistant message. Example windows from the trace: `assistant:88 | user:1516` → `assistant:88 | user:2552`; `reasoning:1835 | reasoning:1535 | reasoning:1515 | assistant:86` → `reasoning:1835 | assistant:86 | user:…`.
It happens whether the channel message arrives during an open turn or while the session is idle (tested with a channel-side hold that delivers only after the Stop hook: same rewrites).
**Why it matters.** On Anthropic the change costs a small cache write (cache_control breakpoints + lookback). On OpenAI's GPT-5.6+ prefix cache, any change before the end of the prompt invalidates everything after it, and explicit breakpoints are rejected by the Codex/ChatGPT-OAuth backend. Measured: on ~300K-token sessions, 8–15 % of requests re-billed the whole context (e.g. 46 requests × ~250K uncached tokens in one day); on a fresh session, 14–21 rewrites over 20–30 requests. Related reports: #76606 (hook system-reminder transformed later), #78660 (task_reminder attached to an old human message), #64901, #80604, #48734.
**Expected.** A delivered channel message (and hook/system-reminder attachments) should be appended as a new user item, and already-sent items should stay byte-stable across requests, so that append-only prefix caches keep working.
**Repro.** Any session with a channel plugin: send a message via the channel while the session is idle, then another one; compare the two API request bodies item by item (or watch `cache_read_input_tokens` drop when routed to a prefix-cache backend). A full dossier (traces, journal of a channel-side hold, before/after runs) is available on request.
Am I missing a setting that changes how channel messages are injected? If this is by design, is there a supported delivery mode that does not rewrite earlier items?
Guía de contribución
No hay ninguna guía de contribución indexada para este repositorio
Línea de trabajo
Start by tracing the Channels experimental plugin's `inject directly` delivery path and the construction of consecutive upstream API request bodies. Compare item hashes and lengths across idle and open-turn deliveries, then verify that delivered messages append as new user items, earlier items remain byte-stable, and prefix-cache reads no longer drop on supported backends.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Área
- api, backend, performance
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Activo
- Claridad
- Bastante claro
- Aptitud para principiantes
- 45/100