Added ToolResultMessage again, but only visible when clicking over the tool widget.

This commit is contained in:
famez
2026-02-15 12:23:30 +01:00
parent d8c866ec3c
commit 99bbea32ec

View File

@@ -648,28 +648,50 @@ class ThinkingMessage(Static):
class ToolMessage(Static):
"""Tool execution message"""
# Standard tool icon and color (pa theme)
TOOL_ICON = "$"
TOOL_COLOR = "#9a9a9a" # spirit gray
TOOL_COLOR = "#9a9a9a"
expanded: bool = reactive(False, layout=True)
def __init__(self, tool_name: str, args: str = "", **kwargs):
super().__init__(**kwargs)
self.tool_name = tool_name
self.tool_args = args
self._result_widget: ToolResultMessage | None = None
def render(self) -> Text:
text = Text()
text.append(f"{self.TOOL_ICON} ", style=self.TOOL_COLOR)
text.append(f"{self.tool_name}", style=self.TOOL_COLOR)
text.append("\n", style="")
text.append(self.tool_name, style=self.TOOL_COLOR)
text.append("\n")
# Wrap args
if self.tool_args:
for line in wrap_text_lines(self.tool_args, width=110):
text.append(f" {line}\n", style="#6b6b6b")
return text
def attach_result(self, result_widget: "ToolResultMessage") -> None:
"""Attach a ToolResultMessage widget below this message."""
# Prevent double mounting
if self._result_widget is not None:
return
self._result_widget = result_widget
self._result_widget.display = self.expanded
# Mount immediately after this widget
self.mount(self._result_widget, after=self)
def on_click(self) -> None:
self.expanded = not self.expanded
if self._result_widget:
self._result_widget.display = self.expanded
class ToolResultMessage(Static):
"""Tool result/output message"""
@@ -1685,14 +1707,14 @@ class PentestAgentTUI(App):
def _add_thinking(self, content: str) -> None:
self._add_message(ThinkingMessage(content))
def _add_tool(self, name: str, action: str = "") -> None:
self._add_message(ToolMessage(name, action))
def _add_tool(self, name: str, action: str = "") -> ToolMessage:
tool_message = ToolMessage(name, action)
self._add_message(tool_message)
return tool_message
def _add_tool_result(self, name: str, result: str) -> None:
def _add_tool_result(self, tool_message: ToolMessage, name: str, result: str) -> None:
"""Display tool execution result"""
# Hide tool output - LLM will synthesize it in its response
# This prevents duplication and keeps the chat clean
pass
tool_message.attach_result(ToolResultMessage(name, result))
def _show_system_prompt(self) -> None:
"""Display the current system prompt"""
@@ -3215,6 +3237,8 @@ Be concise. Use the actual data from notes."""
from ..agents.base_agent import AgentState
last_tool_message: ToolMessage
async for response in self.agent.agent_loop(task):
if self._should_stop:
self._add_system("[!] Stopped by user")
@@ -3241,7 +3265,7 @@ Be concise. Use the actual data from notes."""
for call in response.tool_calls:
# Show all tools including finish
args_str = str(call.arguments)
self._add_tool(call.name, args_str)
last_tool_message = self._add_tool(call.name, args_str)
# Show tool results
if response.tool_results:
@@ -3251,11 +3275,11 @@ Be concise. Use the actual data from notes."""
continue
if result.success:
self._add_tool_result(
self._add_tool_result(last_tool_message,
result.tool_name, result.result or "Done"
)
else:
self._add_tool_result(
self._add_tool_result(last_tool_message,
result.tool_name, f"Error: {result.error}"
)