mirror of
https://github.com/BerriAI/litellm.git
synced 2026-11-10 08:28:25 +00:00
fix(context_management): run edits on the history drop_params sends, so count_tokens and /v1/messages clear alike
This commit is contained in:
parent
272e9cfea2
commit
b089560973
2 changed files with 58 additions and 2 deletions
|
|
@ -8,6 +8,7 @@ from litellm._logging import verbose_logger
|
|||
from litellm.litellm_core_utils.asyncify import asyncify
|
||||
from litellm.types.llms.anthropic import AppliedEdit
|
||||
|
||||
from ..convertible_blocks import drop_non_string_tool_result_texts
|
||||
from .constants import CLEAR_TOOL_USES_EDIT_TYPE, COMPACT_EDIT_TYPE
|
||||
from .editors import (
|
||||
CheckedEdit,
|
||||
|
|
@ -103,7 +104,7 @@ async def apply_context_management(
|
|||
|
||||
Every ``clear_tool_uses_20250919`` edit is validated before any editor runs, so a malformed one raises its 400
|
||||
before a ``compact_20260112`` summary call is paid for, or runs without its malformed fields under
|
||||
``drop_invalid_edits``.
|
||||
``drop_invalid_edits``, which also drops non-string ``tool_result`` text first, as the provider never receives it.
|
||||
|
||||
The dispatcher is async so async editors (``compact_20260112``) can
|
||||
``await`` the configured summarization model. Sync editors run in a
|
||||
|
|
@ -119,7 +120,7 @@ async def apply_context_management(
|
|||
raise first_error
|
||||
well_formed_edits: Final = tuple(check.edit for check in checked)
|
||||
|
||||
current_messages = messages
|
||||
current_messages = list(drop_non_string_tool_result_texts(messages, drop_invalid_edits))
|
||||
current_system = system
|
||||
aggregated_applied: Final[list[AppliedEdit]] = []
|
||||
aggregated_compaction_block = None
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ Unit tests for the context_management polyfill dispatcher.
|
|||
from litellm.llms.anthropic.messages.context_management import (
|
||||
apply_context_management,
|
||||
)
|
||||
from litellm.llms.anthropic.messages.convertible_blocks import drop_non_string_tool_result_texts
|
||||
|
||||
MODEL = "xai/grok-4"
|
||||
|
||||
|
|
@ -159,3 +160,57 @@ async def test_sync_editor_counts_tokens_off_the_event_loop():
|
|||
|
||||
assert result.messages == messages
|
||||
assert_loop_stayed_free(took, lags)
|
||||
|
||||
|
||||
def _history_with_null_text_beside_a_short_first_result():
|
||||
return [
|
||||
{"role": "user", "content": "Hi"},
|
||||
{
|
||||
"role": "assistant",
|
||||
"content": [{"type": "tool_use", "id": "t0", "name": "f", "input": {}}],
|
||||
},
|
||||
{
|
||||
"role": "user",
|
||||
"content": [
|
||||
{
|
||||
"type": "tool_result",
|
||||
"tool_use_id": "t0",
|
||||
"content": [{"type": "text", "text": "ok"}, {"type": "text", "text": None}],
|
||||
}
|
||||
],
|
||||
},
|
||||
*_history_with_two_tool_pairs()[1:],
|
||||
]
|
||||
|
||||
|
||||
async def test_drop_invalid_edits_clears_as_if_malformed_tool_result_text_was_never_sent():
|
||||
spec = {
|
||||
"edits": [
|
||||
{
|
||||
"type": "clear_tool_uses_20250919",
|
||||
"trigger": {"type": "tool_uses", "value": 2},
|
||||
"keep": {"type": "tool_uses", "value": 1},
|
||||
}
|
||||
]
|
||||
}
|
||||
history = _history_with_null_text_beside_a_short_first_result()
|
||||
|
||||
from_raw = await apply_context_management(
|
||||
model=MODEL,
|
||||
messages=history,
|
||||
tools=None,
|
||||
system=None,
|
||||
context_management_spec=spec,
|
||||
drop_invalid_edits=True,
|
||||
)
|
||||
from_sent = await apply_context_management(
|
||||
model=MODEL,
|
||||
messages=list(drop_non_string_tool_result_texts(history, True)),
|
||||
tools=None,
|
||||
system=None,
|
||||
context_management_spec=spec,
|
||||
drop_invalid_edits=True,
|
||||
)
|
||||
|
||||
assert from_raw.applied_edits == from_sent.applied_edits
|
||||
assert from_raw.messages == from_sent.messages
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue