fix: shared MCP truncate() crashes on None/non-string tool output (#1605)
This commit is contained in:
@@ -13,6 +13,10 @@ SEARCH_TIMEOUT = 30
|
||||
|
||||
def truncate(text: str, limit: int = MAX_OUTPUT_CHARS) -> str:
|
||||
"""Truncate text to *limit* characters with a suffix note."""
|
||||
if not isinstance(text, str):
|
||||
# Tool output is occasionally None or a non-string; len(None) would
|
||||
# raise. Coerce so this shared helper never crashes a tool response.
|
||||
text = "" if text is None else str(text)
|
||||
if len(text) > limit:
|
||||
return text[:limit] + f"\n... (truncated, {len(text)} chars total)"
|
||||
return text
|
||||
|
||||
27
tests/test_mcp_common_truncate.py
Normal file
27
tests/test_mcp_common_truncate.py
Normal file
@@ -0,0 +1,27 @@
|
||||
"""Regression: the shared MCP truncate() must tolerate non-string input."""
|
||||
import importlib.machinery
|
||||
import importlib.util
|
||||
from pathlib import Path
|
||||
|
||||
_PATH = Path(__file__).resolve().parents[1] / "mcp_servers" / "_common.py"
|
||||
|
||||
|
||||
def _load():
|
||||
loader = importlib.machinery.SourceFileLoader("odysseus_mcp_common", str(_PATH))
|
||||
spec = importlib.util.spec_from_loader(loader.name, loader)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
loader.exec_module(module)
|
||||
return module
|
||||
|
||||
|
||||
def test_truncate_handles_none_and_nonstring():
|
||||
c = _load()
|
||||
assert c.truncate(None) == ""
|
||||
assert c.truncate(12345) == "12345"
|
||||
|
||||
|
||||
def test_truncate_string_behaviour_unchanged():
|
||||
c = _load()
|
||||
assert c.truncate("hello", limit=100) == "hello"
|
||||
out = c.truncate("x" * 50, limit=10)
|
||||
assert out.startswith("x" * 10) and "truncated" in out
|
||||
Reference in New Issue
Block a user