diff --git a/litellm/llms/anthropic/experimental_pass_through/context_management/dispatcher.py b/litellm/llms/anthropic/experimental_pass_through/context_management/dispatcher.py index 17a510b8aba..93881580e92 100644 --- a/litellm/llms/anthropic/experimental_pass_through/context_management/dispatcher.py +++ b/litellm/llms/anthropic/experimental_pass_through/context_management/dispatcher.py @@ -1,6 +1,6 @@ """Dispatch ``context_management`` edits to registered polyfill editors.""" -from typing import Any, Callable, Dict, List, Optional, Tuple +from typing import Any, Callable, Dict, List, Optional, Tuple, Union from litellm._logging import verbose_logger from litellm.types.llms.anthropic import AppliedEdit @@ -21,10 +21,27 @@ def apply_context_management( messages: List[Dict[str, Any]], tools: Optional[List[Dict[str, Any]]], system: Any, - context_management_spec: Dict[str, Any], + context_management_spec: Union[Dict[str, Any], List[Dict[str, Any]], None], ) -> Tuple[List[Dict[str, Any]], List[AppliedEdit]]: """Run edits in order; return (messages, applied_edits that fired).""" - edits = context_management_spec.get("edits") if context_management_spec else None + # Accept both Anthropic-native dict form and OpenAI list form. The other + # provider paths normalize via ``map_openai_context_management_to_anthropic`` + # before dispatching; do the same here so the polyfill path doesn't silently + # no-op on list input. + if isinstance(context_management_spec, list): + from litellm.llms.anthropic.chat.transformation import AnthropicConfig + + context_management_spec = ( + AnthropicConfig.map_openai_context_management_to_anthropic( + context_management_spec + ) + ) + + edits = ( + context_management_spec.get("edits") + if isinstance(context_management_spec, dict) + else None + ) if not edits or not isinstance(edits, list): return messages, [] diff --git a/litellm/llms/anthropic/experimental_pass_through/context_management/editors/clear_tool_uses.py b/litellm/llms/anthropic/experimental_pass_through/context_management/editors/clear_tool_uses.py index 4e9bab0f4e2..a6c102db2b9 100644 --- a/litellm/llms/anthropic/experimental_pass_through/context_management/editors/clear_tool_uses.py +++ b/litellm/llms/anthropic/experimental_pass_through/context_management/editors/clear_tool_uses.py @@ -15,14 +15,20 @@ from ..placeholders import build_cleared_tool_result_content def _count_tool_uses(messages: List[Dict[str, Any]]) -> int: - """Return the number of tool_use content blocks across all messages.""" + """Return the number of tool_use content blocks across all messages. + + Only counts blocks with a string ``id`` to stay consistent with + :func:`_collect_tool_use_ids_in_order`, which is the source of truth for + which blocks are clearable. + """ count = 0 for msg in messages: content = msg.get("content") if isinstance(content, list): for block in content: if isinstance(block, dict) and block.get("type") == "tool_use": - count += 1 + if isinstance(block.get("id"), str): + count += 1 return count