mirror of
https://github.com/usestrix/strix.git
synced 2026-10-03 02:24:24 +00:00
perf(tui): cache event renders and eliminate redundant work during running state
Three more performance issues in the running state hot path: Per-event render cache in _get_rendered_events_content: every 350ms tick during active streaming caused a full re-render of all events in the conversation — every chat message through AgentMessageRenderer (including Pygments syntax highlighting for code blocks) and every tool event. Chat messages and completed/failed tool events are now cached by (event_id, status) and only re-rendered when their status changes. Running tool events are re-rendered each tick as their content may still update. Skip duplicate _update_agent_status_display in _update_ui_from_tracer when the dot animation timer is active: _animate_dots (60ms) already calls it for "running" agents, so the unconditional call from _update_ui_from_tracer (350ms) was redundant, doubling the widget update rate during active scans. Fix _get_agent_name_for_vulnerability to use per-agent tool execution index instead of scanning all tool_executions, consistent with the other O(N) scan fixes from the previous commit.
This commit is contained in:
parent
3508da4beb
commit
4b17b57696
1 changed files with 26 additions and 10 deletions
|
|
@ -715,6 +715,7 @@ class StrixTUIApp(App): # type: ignore[misc]
|
|||
|
||||
self._streaming_render_cache: dict[str, tuple[int, Any]] = {}
|
||||
self._last_streaming_len: dict[str, int] = {}
|
||||
self._event_render_cache: dict[str, Any] = {}
|
||||
|
||||
self._scan_thread: threading.Thread | None = None
|
||||
self._scan_stop_event = threading.Event()
|
||||
|
|
@ -925,7 +926,8 @@ class StrixTUIApp(App): # type: ignore[misc]
|
|||
|
||||
self._update_chat_view()
|
||||
|
||||
self._update_agent_status_display()
|
||||
if self._dot_animation_timer is None:
|
||||
self._update_agent_status_display()
|
||||
|
||||
self._update_stats_display()
|
||||
|
||||
|
|
@ -1091,11 +1093,24 @@ class StrixTUIApp(App): # type: ignore[misc]
|
|||
|
||||
for event in events:
|
||||
content: Any = None
|
||||
event_id = event["id"]
|
||||
|
||||
if event["type"] == "chat":
|
||||
content = self._render_chat_content(event["data"])
|
||||
if event_id in self._event_render_cache:
|
||||
content = self._event_render_cache[event_id]
|
||||
else:
|
||||
content = self._render_chat_content(event["data"])
|
||||
if content is not None:
|
||||
self._event_render_cache[event_id] = content
|
||||
elif event["type"] == "tool":
|
||||
content = self._render_tool_content_simple(event["data"])
|
||||
status = event["data"].get("status", "")
|
||||
cache_key = f"{event_id}_{status}"
|
||||
if cache_key in self._event_render_cache:
|
||||
content = self._event_render_cache[cache_key]
|
||||
else:
|
||||
content = self._render_tool_content_simple(event["data"])
|
||||
if content is not None and status in ("completed", "failed", "error"):
|
||||
self._event_render_cache[cache_key] = content
|
||||
|
||||
if content:
|
||||
if renderables:
|
||||
|
|
@ -1344,13 +1359,13 @@ class StrixTUIApp(App): # type: ignore[misc]
|
|||
|
||||
def _get_agent_name_for_vulnerability(self, report_id: str) -> str | None:
|
||||
"""Find the agent name that created a vulnerability report."""
|
||||
for _exec_id, tool_data in list(self.tracer.tool_executions.items()):
|
||||
if tool_data.get("tool_name") == "create_vulnerability_report":
|
||||
result = tool_data.get("result", {})
|
||||
if isinstance(result, dict) and result.get("report_id") == report_id:
|
||||
agent_id = tool_data.get("agent_id")
|
||||
if agent_id and agent_id in self.tracer.agents:
|
||||
name: str = self.tracer.agents[agent_id].get("name", "Unknown Agent")
|
||||
for agent_id, agent_data in self.tracer.agents.items():
|
||||
for exec_id in agent_data.get("tool_executions", []):
|
||||
tool_data = self.tracer.tool_executions.get(exec_id)
|
||||
if tool_data and tool_data.get("tool_name") == "create_vulnerability_report":
|
||||
result = tool_data.get("result", {})
|
||||
if isinstance(result, dict) and result.get("report_id") == report_id:
|
||||
name: str = agent_data.get("name", "Unknown Agent")
|
||||
return name
|
||||
return None
|
||||
|
||||
|
|
@ -1494,6 +1509,7 @@ class StrixTUIApp(App): # type: ignore[misc]
|
|||
self._displayed_events.clear()
|
||||
self._streaming_render_cache.clear()
|
||||
self._last_streaming_len.clear()
|
||||
self._event_render_cache.clear()
|
||||
|
||||
self.call_later(self._update_chat_view)
|
||||
self._update_agent_status_display()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue