Skip to content

Commit bd5071e

Browse files
committed
Show truncated tool-call args in TUI labels
Replace the drop-args-over-80-chars filter with _arg_repr(), which truncates each argument repr to ~100 chars plus an ellipsis. The content key stays hidden; short values render unchanged.
1 parent d47ed77 commit bd5071e

2 files changed

Lines changed: 73 additions & 3 deletions

File tree

‎python_agent_harness/tui/render.py‎

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,18 @@ def _head_chars(text: str, n: int) -> str:
6969
return text[:n] + "…"
7070

7171

72+
def _arg_repr(value: Any, limit: int = 100) -> str:
73+
"""repr() of a tool-call argument, truncated to LIMIT chars total.
74+
75+
Long values (a long Bash command, a big JSON payload) are cut with
76+
an ellipsis instead of being dropped from the label entirely.
77+
"""
78+
r = repr(value)
79+
if len(r) <= limit:
80+
return r
81+
return r[: limit - 1] + "…"
82+
83+
7284
def _tool_result_preview(content: str) -> str:
7385
"""Preview of a tool result: first N lines, capped at N chars.
7486
@@ -228,9 +240,7 @@ def _build_history_rows(self, full: bool = False) -> list[Any]:
228240
args = {}
229241
if isinstance(args, dict):
230242
params = " ".join(
231-
f"{k}={v!r}"
232-
for k, v in args.items()
233-
if k != "content" and len(repr(v)) < 80
243+
f"{k}={_arg_repr(v)}" for k, v in args.items() if k != "content"
234244
)
235245
else:
236246
params = ""

‎tests/tui/test_tui_render.py‎

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,66 @@ def test_tool_call_non_dict_arguments(self):
760760
self.assertIn("tool: Bash", out)
761761
self.assertNotIn("ls", out)
762762

763+
def test_tool_call_args_shown(self):
764+
"""Short arguments render inside the tool label."""
765+
tui, buf = make_tui()
766+
tui.session.last_messages = [
767+
Message(role="user", content="go"),
768+
Message(
769+
role="assistant",
770+
content="",
771+
tool_calls=[ToolCall(id="1", name="Read", arguments='{"file_path": "a.py"}')],
772+
),
773+
Message(role="tool", content="x", tool_call_id="1", name="Read"),
774+
]
775+
tui.console.print(tui._render_conversation())
776+
out = buf.getvalue()
777+
self.assertIn("tool: Read(file_path='a.py')", out)
778+
779+
def test_tool_call_long_args_truncated_not_dropped(self):
780+
"""A long argument value (e.g. a long Bash command) is truncated
781+
with an ellipsis, not dropped from the label."""
782+
tui, buf = make_tui()
783+
cmd = "echo " + "y" * 300
784+
tui.session.last_messages = [
785+
Message(role="user", content="go"),
786+
Message(
787+
role="assistant",
788+
content="",
789+
tool_calls=[ToolCall(id="1", name="Bash", arguments=f'{{"command": "{cmd}"}}')],
790+
),
791+
Message(role="tool", content="ok", tool_call_id="1", name="Bash"),
792+
]
793+
tui.console.print(tui._render_conversation())
794+
out = buf.getvalue()
795+
self.assertIn("tool: Bash(command=", out)
796+
self.assertIn("…", out) # truncation marker present
797+
self.assertNotIn(cmd, out) # full value not rendered
798+
self.assertIn("y" * 50, out) # head of the value shown
799+
800+
def test_tool_call_content_arg_hidden(self):
801+
"""The 'content' argument stays hidden (huge payloads, noise)."""
802+
tui, buf = make_tui()
803+
tui.session.last_messages = [
804+
Message(role="user", content="go"),
805+
Message(
806+
role="assistant",
807+
content="",
808+
tool_calls=[
809+
ToolCall(
810+
id="1",
811+
name="Write",
812+
arguments='{"file_path": "a.py", "content": "huge body"}',
813+
)
814+
],
815+
),
816+
Message(role="tool", content="ok", tool_call_id="1", name="Write"),
817+
]
818+
tui.console.print(tui._render_conversation())
819+
out = buf.getvalue()
820+
self.assertIn("tool: Write(file_path='a.py')", out)
821+
self.assertNotIn("huge body", out)
822+
763823
# ------------------------------------------------------------------
764824
# row budget: visible-row cap and line estimates
765825
# ------------------------------------------------------------------

0 commit comments

Comments
 (0)