Skip to content

fix(bedrock/messages): preserve compact_20260112 context_management on /v1/messages - #27534

Merged
oss-pr-review-agent-shin[bot] merged 1 commit into
BerriAI:shin_agent_oss_staging_05_09_2026from
Anai-Guo:fix/bedrock-invoke-context-management-compact-27532
May 9, 2026
Merged

fix(bedrock/messages): preserve compact_20260112 context_management on /v1/messages#27534
oss-pr-review-agent-shin[bot] merged 1 commit into
BerriAI:shin_agent_oss_staging_05_09_2026from
Anai-Guo:fix/bedrock-invoke-context-management-compact-27532

Conversation

@Anai-Guo

@Anai-Guo Anai-Guo commented May 9, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #27532

Bedrock InvokeModel supports Anthropic compaction (compact-2026-01-12 beta) when context_management is sent with the matching anthropic-beta header. Only the Converse API rejects it. The current /v1/messages → Bedrock Invoke transformation in anthropic_claude3_transformation.py strips context_management unconditionally via the allowlist safety net, so:

  • Claude Code clients that send context_management.edits=[{type: compact_20260112}] lose compaction silently, or
  • on older LiteLLM versions Bedrock 400s with "context_management: Extra inputs are not permitted" because the beta header isn't auto-injected.

Fix

Pre-filter context_management before the existing safety-net strip in transform_anthropic_messages_request:

  1. Keep edits with type=compact_20260112 (the only Bedrock-supported edit type).
  2. Auto-inject compact-2026-01-12 into anthropic_beta when any compact edits survive — same pattern as Vertex AI's _add_context_management_beta_headers.
  3. Drop the field entirely when nothing supported remains, so LiteLLM-internal edits like clear_thinking_20251015 (which are consumed via thinking injection elsewhere) stay out of the outgoing body.
  4. Add context_management: dict to BedrockInvokeAnthropicMessagesRequest so the filtered field passes the allowlist.

anthropic_beta_headers_config.json already maps compact-2026-01-12 → compact-2026-01-12 for the bedrock provider, so no further header config change is needed.

Test plan

  • test_bedrock_messages_strips_context_management (existing, clear_thinking-only) — still strips, since no compact edits survive the filter.
  • test_bedrock_messages_allowlist_filters_anthropic_only_fields (existing, empty edits list) — still strips.
  • test_bedrock_messages_preserves_compact_context_management_and_adds_beta (new) — compact edits stay in body and compact-2026-01-12 is added to anthropic_beta.
  • test_bedrock_messages_filters_unsupported_context_management_edits (new) — mixed list keeps only compact edits and adds the beta.

🤖 Generated with Claude Code

…n /v1/messages

Bedrock InvokeModel supports the compact-2026-01-12 beta when context_management
is sent with the matching anthropic-beta header — only Converse rejects it.
The current /v1/messages → Bedrock Invoke transformation strips
context_management unconditionally, so users hit
"context_management: Extra inputs are not permitted" or quietly lose
compaction.

Filter context_management before the safety-net allowlist:
- keep edits with type=compact_20260112
- auto-add compact-2026-01-12 to anthropic_beta when any survive
- drop the field entirely when nothing supported remains, so LiteLLM-internal
  edits like clear_thinking_20251015 stay out of the request body
- allow context_management in BedrockInvokeAnthropicMessagesRequest so the
  filtered field passes the allowlist

Fixes BerriAI#27532
@codecov

codecov Bot commented May 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 87.50000% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...ransformations/anthropic_claude3_transformation.py 86.66% 2 Missing ⚠️

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes silent compaction loss when Claude Code clients send context_management with compact_20260112 edits through LiteLLM's Bedrock InvokeModel path. The previous implementation stripped context_management unconditionally via the allowlist safety net, so compact edits never reached Bedrock.

  • Adds _filter_context_management_for_bedrock_invoke to pre-filter the edits list, keeping only compact_20260112 entries and auto-injecting the compact-2026-01-12 beta header when any survive — mirroring the pattern used by the Vertex AI transformation.
  • Adds context_management: dict to BedrockInvokeAnthropicMessagesRequest so the pre-filtered field clears the allowlist safety net; the config at anthropic_beta_headers_config.json already maps compact-2026-01-12 → compact-2026-01-12 for bedrock, so no config changes are needed.
  • New unit tests cover the compact-preserve path and the mixed-edit filtering case; existing tests were only updated in their docstrings, not their assertions.

Confidence Score: 4/5

Safe to merge; the change is narrowly scoped to the Bedrock InvokeModel transformation path and is well-tested.

The logic is sound and mirrors the established Vertex AI pattern. One small defensive gap exists: when context_management is present but is not a dict, the early return now leaves the raw value in the request dict — unlike before, the value will pass the allowlist and reach Bedrock, which would return a 400. This is a low-probability edge case with malformed client input, but it is a subtle regression from the original stripping behavior.

anthropic_claude3_transformation.py — the early-return guard in _filter_context_management_for_bedrock_invoke should pop the field rather than return silently.

Important Files Changed

Filename Overview
litellm/llms/bedrock/messages/invoke_transformations/anthropic_claude3_transformation.py Adds _filter_context_management_for_bedrock_invoke to pre-filter context_management before the safety-net allowlist, preserving only compact_20260112 edits and auto-injecting the compact-2026-01-12 beta header; the hook is inserted at the right point in transform_anthropic_messages_request
litellm/types/llms/bedrock.py Adds context_management: dict to BedrockInvokeAnthropicMessagesRequest so the pre-filtered field passes the safety-net allowlist; well-documented with a comment explaining the invariant
tests/test_litellm/llms/bedrock/messages/invoke_transformations/test_anthropic_claude3_transformation.py Adds two new unit tests for compact edge cases and updates docstrings on an existing test; no real-network calls, all mock-based, and no existing assertions were weakened

Reviews (1): Last reviewed commit: "fix(bedrock/messages): preserve compact_..." | Re-trigger Greptile

Comment on lines +430 to +433
cm = anthropic_messages_request.get("context_management")
if not isinstance(cm, dict):
return
edits = cm.get("edits")

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.

P2 When context_management is present but not a dict (e.g. a string or None due to a client bug), the function returns early and leaves the value in anthropic_messages_request untouched. Before this PR the safety-net allowlist would have stripped the field; now that context_management is in the allowlist it passes through to Bedrock verbatim, which would cause a 400. Popping it instead of returning early preserves the previous defensive behavior.

Suggested change
cm = anthropic_messages_request.get("context_management")
if not isinstance(cm, dict):
return
edits = cm.get("edits")
cm = anthropic_messages_request.get("context_management")
if not isinstance(cm, dict):
anthropic_messages_request.pop("context_management", None)
return
edits = cm.get("edits")

@oss-pr-review-agent-shin
oss-pr-review-agent-shin Bot changed the base branch from litellm_internal_staging to shin_agent_oss_staging_05_09_2026 May 9, 2026 20:26
@oss-pr-review-agent-shin
oss-pr-review-agent-shin Bot merged commit f8b078b into BerriAI:shin_agent_oss_staging_05_09_2026 May 9, 2026
42 checks passed
@oss-pr-review-agent-shin

Copy link
Copy Markdown
Contributor

🤖 litellm-agent: Squash-merged into staging branch shin_agent_oss_staging_05_09_2026. Staging PR: #27549


Triage Summary
Gathered PR data only — the triage LLM step did not produce a valid report, so failing-check classification and prior-signal reconciliation were skipped. 137 line(s) across 3 file(s) (+132/-5).

137 lines across 3 files (+132 / -5)

Merge Confidence: 5/5 ✅ READY
Ready to ship.

All checks green. Greptile 4/5, no blocking pattern findings, no CircleCI runs (OSS-typical).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants