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:
+34
-4
@@ -1972,6 +1972,31 @@ def _cap_diff_unified(diff: str, max_bytes: int = _DIFF_UNIFIED_MAX_BYTES) -> st
|
||||
return f"{head}\n# … diff truncated ({omitted} more bytes)"
|
||||
|
||||
|
||||
def _result_sans_diff_echo(result: str) -> str:
|
||||
"""The file-edit result JSON minus its `diff` echo.
|
||||
|
||||
Used for verbose `result_text` when the FULL diff already ships as
|
||||
`diff_unified`: a multi-KB diff echo inside the result JSON gets
|
||||
tail-capped by `_cap_tui_verbose_text` into an unparseable JSON-looking
|
||||
fragment that a client can neither render nor reliably suppress. The
|
||||
native renderer shows the real diff, so result_text should carry only the
|
||||
non-diff signal (success/files_modified/warnings/lsp_diagnostics).
|
||||
Returns `result` unchanged when it isn't a JSON object with a `diff` key.
|
||||
"""
|
||||
try:
|
||||
data = json.loads(result)
|
||||
except Exception:
|
||||
return result
|
||||
if not isinstance(data, dict) or "diff" not in data:
|
||||
return result
|
||||
try:
|
||||
return json.dumps(
|
||||
{k: v for k, v in data.items() if k != "diff"}, ensure_ascii=False
|
||||
)
|
||||
except Exception:
|
||||
return result
|
||||
|
||||
|
||||
def _redact_tui_verbose_text(text: str) -> str:
|
||||
try:
|
||||
from agent.redact import redact_sensitive_text
|
||||
@@ -2093,10 +2118,6 @@ def _on_tool_complete(sid: str, tool_call_id: str, name: str, args: dict, result
|
||||
summary = _tool_summary(name, result, duration_s)
|
||||
if summary:
|
||||
payload["summary"] = summary
|
||||
if _session_verbose(sid):
|
||||
result_text = _tool_result_text(result)
|
||||
if result_text:
|
||||
payload["result_text"] = result_text
|
||||
if name == "todo":
|
||||
try:
|
||||
data = json.loads(result)
|
||||
@@ -2134,6 +2155,15 @@ def _on_tool_complete(sid: str, tool_call_id: str, name: str, args: dict, result
|
||||
payload["diff_unified"] = _cap_diff_unified(diff_unified)
|
||||
except Exception:
|
||||
pass
|
||||
if _session_verbose(sid):
|
||||
# Computed AFTER diff_unified: when the full diff ships natively, the
|
||||
# result_text drops the in-JSON diff echo (it would tail-cap into
|
||||
# unparseable JSON-looking noise under the client's rendered diff).
|
||||
result_text = _tool_result_text(
|
||||
_result_sans_diff_echo(result) if payload.get("diff_unified") else result
|
||||
)
|
||||
if result_text:
|
||||
payload["result_text"] = result_text
|
||||
if _tool_progress_enabled(sid) or payload.get("inline_diff") or payload.get("diff_unified"):
|
||||
_emit("tool.complete", sid, payload)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user