Skip to content

Strip the billing header from the first part of the system msg in anthropic#323

Merged
Erin McNulty (erin2722) merged 2 commits into
mainfrom
strip-anthropic-billing-msg
Jun 25, 2026
Merged

Strip the billing header from the first part of the system msg in anthropic#323
Erin McNulty (erin2722) merged 2 commits into
mainfrom
strip-anthropic-billing-msg

Conversation

@erin2722

@erin2722 Erin McNulty (erin2722) commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

This was causing caching to be broken for claude when using the gateway with different models-- see musistudio/claude-code-router#1220 for a similar issue.

We can just strip the stray text in lingua so that our users do not need to worry about this.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fbe38ee7bc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +348 to +350
UserContent::Array(parts) => {
let before = parts.len();
parts.retain(|part| !is_billing_header_part(part));

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Strip only the marker line from text blocks

When Anthropic system is an array and the first text block contains both the billing line and real instructions (for example "x-anthropic-billing-header: ...\nYou are helpful"), this retain drops the entire block, so non-Anthropic transforms silently lose the actual system prompt. The string branch handles this shape by removing only the first line; the array branch should do the same for matching Text parts and only remove the part if it becomes empty.

Useful? React with 👍 / 👎.

@erin2722

Copy link
Copy Markdown
Contributor Author

Codex (@codex) review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2367608647

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "Codex (@codex) review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "Codex (@codex) address that feedback".

Comment on lines +346 to +353
parts.retain_mut(|part| {
let UserContentPart::Text(text) = part else {
return true;
};
if !text
.text
.trim_start()
.starts_with(CLAUDE_CODE_BILLING_PREFIX)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Limit stripping to the leading billing block

This scans every text block in every system message, so an Anthropic prompt like [{text: "real instructions"}, {text: "x-anthropic-billing-header: ..."}] loses the later block even though the Claude Code attribution described above is only the prepended leading block. For non-Anthropic transforms that include literal examples or instructions beginning with this header name after the real prompt, this silently changes user-visible system instructions; restrict the removal to the first system content block/line that represents the attribution.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Erin McNulty (@erin2722) I don't actually know if this is correct. I think you can have multiple system messages with anthropic now so im not sure if it's correct to only check the first block

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahhhh interesting, yeah I believe you can, and the edge case it calls out is super niche lol. Lets leave this as is for now

Comment on lines +346 to +353
parts.retain_mut(|part| {
let UserContentPart::Text(text) = part else {
return true;
};
if !text
.text
.trim_start()
.starts_with(CLAUDE_CODE_BILLING_PREFIX)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Erin McNulty (@erin2722) I don't actually know if this is correct. I think you can have multiple system messages with anthropic now so im not sure if it's correct to only check the first block

@erin2722 Erin McNulty (erin2722) merged commit e061090 into main Jun 25, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants