fix(converters): strip Claude Code 2.1.x billing attribution from sys…#215
fix(converters): strip Claude Code 2.1.x billing attribution from sys…#215liwenquantop-dot wants to merge 2 commits into
Conversation
…tem prompt Claude Code 2.1.x prepends a per-request system text block of the form: x-anthropic-billing-header: cc_version=2.1.153.d02; cc_entrypoint=sdk-cli; cch=<5hex>; The cch segment is a fresh random hex token on every request. Because extract_system_prompt() concatenates all system text blocks into a single string before forwarding to Kiro, this random prefix poisons the prompt seen by the upstream and invalidates any prefix-keyed prompt cache (the attribution header is meant to be an HTTP header but ships in body here). Add _strip_billing_attribution() and call it from extract_system_prompt() for both string and list system formats. Blocks that are pure attribution are dropped; mixed blocks have the leading attribution line removed. The behavior is gated by STRIP_BILLING_HEADER (default true) so it can be disabled for A/B comparison.
|
Thanks for the PR! 🎉 Before merge, we need a one-time CLA confirmation. Full CLA text: Please reply once with: You need to write once, all further messages from me can be ignored. |
|
I have read the CLA and I accept its terms |
|
Thank you for your pull request and welcome to our community. We could not parse the GitHub identity of the following contributors: liwenquan.
|
de07e76 to
3ecbf73
Compare
|
Thanks for the PR! 🎉 Before merge, we need a one-time CLA confirmation. Full CLA text: Please reply once with: You need to write once, all further messages from me can be ignored. |
|
@jwadow Please add |
Strip Claude Code 2.1.x billing attribution from system prompt (cherry-pick upstream jwadow#215)
Problem
Claude Code 2.1.x prepends a per-request system text block of the form:
x-anthropic-billing-header: cc_version=2.1.153.d02; cc_entrypoint=sdk-cli; cch=<5hex>;
The
cchtoken is a fresh random hex on every request. Becauseextract_system_prompt()concatenates all system text blocks into a single string before forwarding to Kiro, this random prefix poisons the prompt seen by upstream and invalidates any prefix-keyed prompt cache. (The attribution header is meant to be an HTTP header but ships in the request body forclaude -p/ SDK mode.)Solution
Add
_strip_billing_attribution()and call it fromextract_system_prompt()for both string and list system formats. Pure-attribution blocks are dropped; mixed blocks have the leading attribution line removed. Behavior is gated bySTRIP_BILLING_HEADER(defaulttrue) so it can be disabled for A/B comparison.Empirical validation (local)
Replay benchmark using real captured Claude Code body (212KB, 3 system blocks), N=30 interleaved, randomized cch per request:
Byte-level check via
DEBUG_MODE=all: incoming body containscch=<hex>andx-anthropic-billing-header; outgoing Kiro payload has zero matches for either string.Alternative
CLAUDE_CODE_ATTRIBUTION_HEADER=0set in the client environment achieves the same effect on the Claude Code side. The gateway-level fix is complementary and protects users / clients that don't (or can't) set the env var.Files
kiro/config.py: addSTRIP_BILLING_HEADERenv (default true)kiro/converters_anthropic.py: add_strip_billing_attribution(), apply inextract_system_prompt()