From 491992084dff150fa4b2cba88bcbb6661a797d6f Mon Sep 17 00:00:00 2001 From: Valentin Date: Sat, 5 Sep 2026 13:51:01 -0600 Subject: [PATCH] fix(cron): carry tool_call_id on tool messages in desktop resume payload --- tests/test_tui_gateway_server.py | 1 + tui_gateway/session_history.py | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/tests/test_tui_gateway_server.py b/tests/test_tui_gateway_server.py index ec28bc1191f8..1e9299e15fe1 100644 --- a/tests/test_tui_gateway_server.py +++ b/tests/test_tui_gateway_server.py @@ -2743,6 +2743,7 @@ def test_history_to_messages_preserves_tool_calls_for_resume_display(): "context": "resume", "name": "search_files", "role": "tool", + "tool_call_id": "call_1", }, {"role": "assistant", "text": "first answer"}, {"role": "user", "text": "second prompt"}, diff --git a/tui_gateway/session_history.py b/tui_gateway/session_history.py index 998c79e16d60..e9a7ba5c10e1 100644 --- a/tui_gateway/session_history.py +++ b/tui_gateway/session_history.py @@ -199,11 +199,21 @@ def _history_to_messages(history: list[dict]) -> list[dict]: if not content_text.strip(): continue if role == "tool": - tc_name, tc_args = tool_call_args.get(m.get("tool_call_id") or "", (None, None)) + tc_id = m.get("tool_call_id", "") + tc_name, tc_args = tool_call_args.get(tc_id, (None, None)) name = tc_name or m.get("tool_name") or "tool" args = tc_args or {} # `context` is an 80-char preview; ship args so a full-call renderer isn't truncated. - messages.append({"role": "tool", "name": name, "context": _tool_ctx(name, args), **({"args": args} if args else {})}) + # Carry the original ``tool_call_id`` forward so the desktop resume + # payload can pair the tool result with the call that produced it. + # The raw result payload is deliberately NOT forwarded: tool output + # can contain secrets, and the desktop transcript stays redacted. + tool_msg = {"role": "tool", "name": name, "context": _tool_ctx(name, args)} + if args: + tool_msg["args"] = args + if tc_id: + tool_msg["tool_call_id"] = tc_id + messages.append(tool_msg) continue # A reasoning-only assistant turn is kept so "Thinking…" still shows after resume/reload. has_reasoning = role == "assistant" and any(m.get(key) for key in _HISTORY_REASONING_KEYS)