From 2280aa224b9a184280f60bbff76da6e2c06ff91c Mon Sep 17 00:00:00 2001 From: mateo-berri <277851410+mateo-berri@users.noreply.github.com> Date: Fri, 6 Nov 2026 21:19:18 -0800 Subject: [PATCH] fix(ollama): keep the repair warning's argument preview unless message logging is off Backport of #49183 to lts/1.108.x. Cherry-picked from 5ef6d62cca7e0a9a9e6db2609ca435e9b957de5e (fix-ollama-chat-stream-tool-call-index). Adapted to the line. The repair warning lives in common_utils.py here. --- .../prompt_templates/common_utils.py | 13 +++++++++- ...ore_utils_prompt_templates_common_utils.py | 25 ++++++++++++++++--- 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/litellm/litellm_core_utils/prompt_templates/common_utils.py b/litellm/litellm_core_utils/prompt_templates/common_utils.py index 5ad87ab5f9f..66e943401fa 100644 --- a/litellm/litellm_core_utils/prompt_templates/common_utils.py +++ b/litellm/litellm_core_utils/prompt_templates/common_utils.py @@ -20,6 +20,7 @@ from pydantic import TypeAdapter import litellm from litellm import verbose_logger +from litellm.constants import REDACTED_BY_LITELLM from litellm.router_utils.batch_utils import InMemoryFile from litellm.types.llms.openai import ( AllMessageValues, @@ -2660,6 +2661,15 @@ def merge_consecutive_system_messages( _DECODED_JSON: Final = TypeAdapter(object) +_ARGUMENT_PREVIEW_CHARS: Final = 200 + + +def _logged_arguments(arguments: str) -> str: + if litellm.turn_off_message_logging: + return REDACTED_BY_LITELLM + if len(arguments) <= _ARGUMENT_PREVIEW_CHARS: + return arguments + return f"{arguments[:_ARGUMENT_PREVIEW_CHARS]}..." def _attempt_json_repair(s: str) -> object | None: @@ -2757,10 +2767,11 @@ def parse_tool_call_arguments( repaired: Final = _attempt_json_repair(arguments) if repaired is not None: verbose_logger.warning( - "Repaired truncated tool call arguments for tool '%s' (%s). Original length: %d chars", + "Repaired truncated tool call arguments for tool '%s' (%s). Original (%d chars): %s", tool_name or "", context or "unknown context", len(arguments), + _logged_arguments(arguments), ) return repaired diff --git a/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_common_utils.py b/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_common_utils.py index 674d39438cf..5d19f3f6b04 100644 --- a/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_common_utils.py +++ b/tests/unit/litellm_core_utils/prompt_templates/test_litellm_core_utils_prompt_templates_common_utils.py @@ -10,6 +10,8 @@ from typing import Final, cast import pytest +import litellm +from litellm.constants import REDACTED_BY_LITELLM from litellm.litellm_core_utils.prompt_templates.common_utils import ( ENCRYPTED_REASONING_SIGNATURE_PREFIX, TOOL_RESULT_IMAGE_BOUNDARY, @@ -2442,12 +2444,29 @@ def test_schema_size_counts_every_written_object_once(schema, properties, branch assert schema_grammar_branch_count(schema) == branches -def test_parse_tool_call_arguments_repair_warning_leaves_out_argument_content( +def test_parse_tool_call_arguments_repair_warning_previews_the_first_200_characters( caplog: pytest.LogCaptureFixture, ) -> None: + arguments: Final = '{"patient": "Jane Doe", "note": "' + "x" * 300 + '"' with caplog.at_level(logging.WARNING, logger="LiteLLM"): - result: Final = parse_tool_call_arguments('{"patient": "Jane Doe"', tool_name="lookup", context="test") + result: Final = parse_tool_call_arguments(arguments, tool_name="lookup", context="test") + + assert result == {"patient": "Jane Doe", "note": "x" * 300} + assert ( + f"Repaired truncated tool call arguments for tool 'lookup' (test). Original ({len(arguments)} chars): " + f"{arguments[:200]}..." in caplog.text + ) + assert arguments not in caplog.text + + +def test_parse_tool_call_arguments_repair_warning_redacts_arguments_when_message_logging_is_off( + caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch +) -> None: + monkeypatch.setattr(litellm, "turn_off_message_logging", True) + arguments: Final = '{"patient": "Jane Doe"' + with caplog.at_level(logging.WARNING, logger="LiteLLM"): + result: Final = parse_tool_call_arguments(arguments, tool_name="lookup", context="test") assert result == {"patient": "Jane Doe"} - assert "Repaired truncated tool call arguments for tool 'lookup'" in caplog.text + assert f"Original ({len(arguments)} chars): {REDACTED_BY_LITELLM}" in caplog.text assert "Jane Doe" not in caplog.text