diff --git a/agent/display.py b/agent/display.py index 063b7bb1c7ce..d7c0857cb420 100644 --- a/agent/display.py +++ b/agent/display.py @@ -270,7 +270,10 @@ def build_tool_preview(tool_name: str, args: dict, max_len: int | None = None) - if not preview: return None if max_len > 0 and len(preview) > max_len: - preview = preview[:max_len - 3] + "..." + if max_len <= 3: + preview = "." * max_len + else: + preview = preview[:max_len - 3] + "..." return preview diff --git a/tests/agent/test_display.py b/tests/agent/test_display.py index 5127a930ba11..1fb52a5307a9 100644 --- a/tests/agent/test_display.py +++ b/tests/agent/test_display.py @@ -53,11 +53,32 @@ def test_unknown_tool_no_matching_key(self): assert result is None def test_long_value_truncated(self): - """Preview should truncate long values.""" + """Preview should truncate long values and never exceed max_len.""" long_cmd = "a" * 100 result = build_tool_preview("terminal", {"command": long_cmd}, max_len=40) assert result is not None - assert len(result) <= 43 # max_len + "..." + assert len(result) <= 40 + assert result.endswith("...") + + def test_tiny_max_len_respects_bound(self): + """Regression for #9439: max_len in {1, 2, 3} must not overflow.""" + long_cmd = "abcdefghijklmnopqrstuvwxyz" + for limit in (1, 2, 3): + result = build_tool_preview("terminal", {"command": long_cmd}, max_len=limit) + assert result is not None + assert len(result) <= limit, f"max_len={limit} produced {result!r}" + + def test_max_len_exactly_four(self): + """The smallest max_len that still fits content plus ellipsis.""" + result = build_tool_preview("terminal", {"command": "abcdefghij"}, max_len=4) + assert result is not None + assert len(result) <= 4 + assert result.endswith("...") + + def test_short_value_not_truncated(self): + """Values already within max_len should pass through unchanged.""" + result = build_tool_preview("terminal", {"command": "ls"}, max_len=2) + assert result == "ls" def test_process_tool_with_none_args(self): """Process tool special case should also handle None args."""