Skip to content

callback: added a pre-hook callback to remove anthropic header#98

Open
SirajuddinShaik wants to merge 6 commits into
release/prodfrom
message-filter
Open

callback: added a pre-hook callback to remove anthropic header#98
SirajuddinShaik wants to merge 6 commits into
release/prodfrom
message-filter

Conversation

@SirajuddinShaik

Copy link
Copy Markdown
Member

Relevant issues

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Type

🆕 New Feature
🐛 Bug Fix
🧹 Refactoring
📖 Documentation
🚄 Infrastructure
✅ Test

Changes

Copilot AI review requested due to automatic review settings March 11, 2026 15:27

Copilot AI 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.

Pull request overview

Adds a production pre-call guardrail callback intended to strip Anthropic billing-header metadata from request payloads to improve cache hit rates and avoid cache-busting content in prompts.

Changes:

  • Introduces MessageFilterProd (CustomGuardrail) with an async_pre_call_hook to filter matching content from data["messages"] and data["system"].
  • Adds a pre-configured production instance message_filter_prod.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment thread litellm/callbacks/message_filter.py Outdated
Comment on lines +49 to +53
def _filter_content(self, content):
"""Filter content (string or list of blocks)."""
if isinstance(content, str):
return content

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

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

_filter_content() returns strings unchanged, so this hook will never remove the x-anthropic-billing-header: metadata when it appears as a string (e.g., system message content can be a plain string in existing Anthropic translation paths). To actually prevent cache-busting, add string handling that detects/removes (or returns None for) strings starting with the billing-header prefix and ensure callers drop the field/message when the result is None.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@copilot open a new pull request to apply changes based on this feedback

Comment on lines +84 to +87
filtered_content = self._filter_content(content)
if filtered_content != content:
message["content"] = filtered_content
filtered_count += 1

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

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

If all content blocks are filtered out, filtered_content becomes an empty list and the message is still kept with content=[]. Several provider adapters (including Anthropic) treat empty text blocks/content as invalid and can error. After filtering, if content becomes empty (or None if you adopt that), remove the entire message entry (and similarly clear data['system']) instead of leaving an empty content value.

Copilot uses AI. Check for mistakes.
Comment thread litellm/callbacks/message_filter.py Outdated
Comment thread litellm/callbacks/message_filter.py Outdated
Comment on lines +63 to +70
async def async_pre_call_hook(
self,
user_api_key_dict: UserAPIKeyAuth,
cache: DualCache,
data: dict,
call_type: CallTypesLiteral,
) -> Optional[Union[Exception, str, dict]]:
"""Filter cache-busting content from messages and system fields."""

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

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

This PR adds new behavior that mutates request payloads in a pre-call hook but doesn’t include tests. Please add at least one unit test covering: (1) filtering when the header appears in string content (system message/content), (2) filtering when it appears as a [{type:'text', text:'...'}] block list, and (3) the empty-after-filter case to ensure the message/system field is removed rather than left empty.

Copilot uses AI. Check for mistakes.
Comment thread litellm/callbacks/message_filter.py Outdated
Comment on lines +111 to +112
# Production instance
message_filter_prod = MessageFilterProd(filter_keywords=["x-anthropic-billing-header"])

Copilot AI Mar 11, 2026

Copy link

Choose a reason for hiding this comment

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

The default/production filter_keywords uses the prefix "x-anthropic-billing-header" without the trailing :. This will also match and remove any user content that happens to begin with that phrase (not necessarily the metadata line). Consider using the more specific prefix used elsewhere in the codebase ("x-anthropic-billing-header:") or otherwise tightening the match to reduce false positives.

Copilot uses AI. Check for mistakes.
SirajuddinShaik and others added 2 commits March 11, 2026 21:07
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

Copilot AI commented Mar 11, 2026

Copy link
Copy Markdown

@SirajuddinShaik I've opened a new pull request, #99, to work on those changes. Once the pull request is ready, I'll request review from you.

@prakhar-prakash-juspay

Copy link
Copy Markdown
Collaborator

Duplicate functionality: This filtering already exists in two places:

  • litellm/llms/anthropic/chat/transformation.py:929-951
  • litellm/llms/anthropic/experimental_pass_through/messages/transformation.py:47-78

@github-actions

Copy link
Copy Markdown

This pull request has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.

@github-actions github-actions Bot added the Stale label Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants