refactor: delegate handler spec normalization to dispatcher

_normalize_spec_edits in adapters/handler.py duplicated the spec-shape
normalization already implemented by _normalize_spec in
context_management/dispatcher.py. The two could drift: a change in one
(e.g. supporting a new spec shape) without the other would cause the
handler's polyfill_will_run prediction to disagree with the
dispatcher's actual behavior, breaking the client-history pre-processing
skip.

Have the handler delegate to the dispatcher's _normalize_spec while
keeping handler-specific concerns (drop_params short-circuit, swallow
mapping exceptions) at the wrapper level.

Co-authored-by: Yassin Kortam <yassin@berri.ai>
This commit is contained in:
Cursor Agent 2026-05-28 04:02:53 +00:00
parent 9e381e1e4f
commit 5298d52e2c
No known key found for this signature in database

View file

@ -175,7 +175,11 @@ def _normalize_spec_edits(
context_management_spec: Any,
drop_params: Optional[bool],
) -> Optional[List[Dict[str, Any]]]:
"""Return the normalized ``edits`` list, or ``None`` if the polyfill won't run."""
"""Return the normalized ``edits`` list, or ``None`` if the polyfill won't run.
Delegates spec-shape normalization to the dispatcher's ``_normalize_spec``
so the prediction here can't drift from what the dispatcher actually does.
"""
if not context_management_spec:
return None
@ -185,19 +189,14 @@ def _normalize_spec_edits(
if effective_drop_params:
return None
spec = context_management_spec
if isinstance(spec, list):
try:
from litellm.llms.anthropic.chat.transformation import AnthropicConfig
from litellm.llms.anthropic.experimental_pass_through.context_management.dispatcher import (
_normalize_spec,
)
spec = AnthropicConfig.map_openai_context_management_to_anthropic(spec)
except Exception:
return None
edits = spec.get("edits") if isinstance(spec, dict) else None
if not isinstance(edits, list):
try:
return _normalize_spec(context_management_spec)
except Exception:
return None
return edits
async def _run_polyfill_if_enabled(