mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-13 14:02:16 +00:00
opentui(v6): suppress redundant JSON/diff-echo output under rendered diffs
A patch tool's result is a JSON record whose payload IS the diff. In a verbose
session the gateway redacts + TAIL-caps result_text (_cap_tui_verbose_text),
so the echo arrived under the native diff in two broken shapes: truncated
mid-JSON (unparseable, so the old JSON.parse check failed open), or — for tall
edits — capped PAST the JSON head, which the store's normalizeOutput then
un-escapes into plain lines that duplicate the diff. North star: no raw JSON
in the transcript, ever.
Three layers:
- gateway: when diff_unified ships, result_text drops the in-JSON diff echo
(_result_sans_diff_echo) — small, parseable, carries only the non-diff
signal (success/files_modified/warnings/lsp_diagnostics).
- fileTool diffOutputPlan: anything starting with '{' under a rendered diff is
suppressed regardless of parseability; parseable JSON with real non-diff
signal (error/warning/lsp_diagnostics) renders JUST those as labeled notes;
a non-JSON fragment whose lines echo the rendered diff is suppressed too
(guards older emitters). Plain-text results (lint tails) still render.
This commit is contained in:
parent
0bde6a890f
commit
5fd2b5bb7b
4 changed files with 264 additions and 17 deletions
|
|
@ -241,6 +241,40 @@ def test_tool_complete_emits_full_unified_diff(monkeypatch):
|
|||
assert "inline_diff" in payload
|
||||
|
||||
|
||||
def test_verbose_result_text_drops_diff_echo_when_diff_unified_ships(monkeypatch):
|
||||
# A tall edit's result JSON embeds the WHOLE diff; tail-capping that echo
|
||||
# yields an unparseable JSON-looking fragment the TUI can't suppress
|
||||
# reliably. When diff_unified ships, result_text must carry only the
|
||||
# non-diff signal — small, parseable, never the diff echo.
|
||||
events: list[tuple[str, str, dict]] = []
|
||||
monkeypatch.setattr(
|
||||
server, "_emit", lambda event_type, sid, payload: events.append((event_type, sid, payload))
|
||||
)
|
||||
monkeypatch.setitem(
|
||||
server._sessions,
|
||||
"diff-echo-test",
|
||||
{"tool_progress_mode": "verbose", "tool_started_at": {}, "edit_snapshots": {}},
|
||||
)
|
||||
|
||||
lines = "\n".join(f"+def fn_{i}() -> int: return {i}" for i in range(60))
|
||||
diff = f"--- a/x.py\n+++ b/x.py\n@@ -1,0 +1,60 @@\n{lines}\n"
|
||||
result = json.dumps(
|
||||
{"success": True, "diff": diff, "files_modified": ["x.py"], "_warning": "stale read"}
|
||||
)
|
||||
server._on_tool_complete("diff-echo-test", "tool-1", "patch", {"mode": "patch"}, result)
|
||||
|
||||
payload = events[0][2]
|
||||
assert payload["diff_unified"] == diff
|
||||
text = payload["result_text"]
|
||||
assert "[showing verbose tail" not in text # small enough to dodge the cap
|
||||
parsed = json.loads(text) # parseable …
|
||||
assert "diff" not in parsed # … with the echo gone
|
||||
assert parsed["_warning"] == "stale read" # non-diff signal survives
|
||||
# without diff_unified (non-edit tools) the result_text is untouched
|
||||
assert server._result_sans_diff_echo("plain text result") == "plain text result"
|
||||
assert server._result_sans_diff_echo('{"output": "x"}') == '{"output": "x"}'
|
||||
|
||||
|
||||
def test_cap_diff_unified_truncates_at_line_boundary():
|
||||
line = "+" + "x" * 63 # 64 bytes per line incl. newline
|
||||
diff = "\n".join([line] * 100)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue