fix: agent_tools._truncate crashes on non-string input (#1624)
* fix: agent_tools._truncate crashes on non-string input * fix: agent_tools._truncate returns a string for non-string input, not the raw value
This commit is contained in:
@@ -80,6 +80,11 @@ def get_mcp_manager():
|
|||||||
# Helpers (kept here — used by sub-modules)
|
# Helpers (kept here — used by sub-modules)
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
def _truncate(text: str, limit: int = MAX_OUTPUT_CHARS) -> str:
|
def _truncate(text: str, limit: int = MAX_OUTPUT_CHARS) -> str:
|
||||||
|
# Callers treat the result as text, so always return a string: coerce a
|
||||||
|
# non-string (None -> "", otherwise str(...)) instead of returning it raw,
|
||||||
|
# which would just move the crash downstream.
|
||||||
|
if not isinstance(text, str):
|
||||||
|
text = "" if text is None else str(text)
|
||||||
if len(text) > limit:
|
if len(text) > limit:
|
||||||
return text[:limit] + f"\n... (truncated, {len(text)} chars total)"
|
return text[:limit] + f"\n... (truncated, {len(text)} chars total)"
|
||||||
return text
|
return text
|
||||||
|
|||||||
24
tests/test_agent_tools_truncate_nonstring.py
Normal file
24
tests/test_agent_tools_truncate_nonstring.py
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
"""Regression: agent_tools._truncate must always return a string.
|
||||||
|
|
||||||
|
It did `len(text)` directly, so `_truncate(None)` raised TypeError. Returning
|
||||||
|
the raw non-string just moves the crash downstream (callers treat it as text),
|
||||||
|
so non-strings are now coerced to a string and still truncated.
|
||||||
|
"""
|
||||||
|
from src.agent_tools import _truncate
|
||||||
|
|
||||||
|
|
||||||
|
def test_non_string_coerced_to_string():
|
||||||
|
assert _truncate(None) == ""
|
||||||
|
assert _truncate(123) == "123"
|
||||||
|
assert isinstance(_truncate({"a": 1}), str)
|
||||||
|
|
||||||
|
|
||||||
|
def test_non_string_is_also_truncated():
|
||||||
|
out = _truncate(12345, limit=3)
|
||||||
|
assert out.startswith("123") and "truncated" in out
|
||||||
|
|
||||||
|
|
||||||
|
def test_string_truncation_unchanged():
|
||||||
|
assert _truncate("hello", limit=100) == "hello"
|
||||||
|
out = _truncate("x" * 50, limit=10)
|
||||||
|
assert out.startswith("x" * 10) and "truncated" in out
|
||||||
Reference in New Issue
Block a user