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

オープン
#93,622 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る
area:cost area:plugins bug platform:wsl
主要言語
Python
スター
145k
フォーク
23.1k
PR マージ指標
PR 指標を取得中

説明

**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?

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

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.

索引モデルが issue の本文から書いたものです。

評価

領域
api, backend, performance
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
活発
明瞭さ
おおむね明確
初心者へのやさしさ
45/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。