From 02899c9c15e1edc7f214be89710503713b58b671 Mon Sep 17 00:00:00 2001 From: thejesh23 Date: Tue, 21 Jul 2026 17:14:00 -0700 Subject: [PATCH] fix(tui): report an incomplete replay instead of an empty response _format_replay_tool_result sets success=False with no `error` key when a replay never reaches DONE, so the widened gate sent it down the normal response branch and rendered elapsed time with an empty response, as if the request had come back. Report the replay status instead (TIMEDOUT, ERROR, ...). Both the error and success paths are unchanged. Adds tests for the incomplete-replay and successful-replay cases. --- .../interface/tui/renderers/proxy_renderer.py | 9 +++++ tests/test_proxy_renderer.py | 37 +++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/strix/interface/tui/renderers/proxy_renderer.py b/strix/interface/tui/renderers/proxy_renderer.py index 9645bad9..410372a3 100644 --- a/strix/interface/tui/renderers/proxy_renderer.py +++ b/strix/interface/tui/renderers/proxy_renderer.py @@ -275,6 +275,15 @@ class RepeatRequestRenderer(BaseToolRenderer): if _has_result(status) and isinstance(result, dict): if not result.get("success", True) and result.get("error"): text.append(f"\n error: {_sanitize(str(result['error']), 150)}", style="#ef4444") + elif not result.get("success", True): + # A replay that never reached DONE carries no `error`; report the + # replay status rather than rendering an empty response as if the + # request had come back. + replay_status = _sanitize(str(result.get("status") or "unknown"), 40) + text.append( + f"\n replay did not complete: {replay_status}", + style="#ef4444", + ) else: elapsed_ms = result.get("elapsed_ms") response = result.get("response") or {} diff --git a/tests/test_proxy_renderer.py b/tests/test_proxy_renderer.py index 0d0be9f0..f0a35165 100644 --- a/tests/test_proxy_renderer.py +++ b/tests/test_proxy_renderer.py @@ -85,6 +85,43 @@ def test_tool_status_from_result_maps_failure_to_failed() -> None: assert _tool_status_from_result({"success": True}) == "completed" +def test_incomplete_replay_says_so_instead_of_showing_an_empty_response() -> None: + # _format_replay_tool_result sets success=False with no `error` key when the + # replay never reached DONE; it must not render as a returned response. + tool_data = { + "args": {"request_id": "req-1"}, + "result": { + "success": False, + "status": "TIMEDOUT", + "session_id": "s-1", + "elapsed_ms": 30000, + "response": None, + }, + "status": "failed", + } + text = _plain(RepeatRequestRenderer.render(tool_data)) + + assert "replay did not complete: TIMEDOUT" in text + assert "<<" not in text, "rendered a response line for a replay that never returned" + + +def test_successful_replay_still_renders_its_response() -> None: + tool_data = { + "args": {"request_id": "req-1"}, + "result": { + "success": True, + "status": "DONE", + "elapsed_ms": 12, + "response": {"status_code": 200, "body": "ok"}, + }, + "status": "completed", + } + text = _plain(RepeatRequestRenderer.render(tool_data)) + + assert "200" in text + assert "replay did not complete" not in text + + def test_successful_result_still_renders() -> None: tool_data = { "args": {},