fix(telemetry): capture tool args in tool_executions for TUI renderers

The 19 tool renderers under strix/interface/tool_components/ all read
tool_data.get("args", {}) to render meaningful previews (URLs, methods,
note titles, vuln severities, etc.). After the SDK migration,
tracer.log_tool_start was only recording tool_name — every renderer
silently fell back to its empty-args path and the TUI lost its
per-call context.

Pull args from the SDK-native ToolContext (tool_input when parsed,
otherwise json-decode tool_arguments) and stash them on the
tool_executions entry. log_tool_start now takes an optional args dict;
existing callers pass nothing and get the empty-dict default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
0xallam
2026-04-25 18:08:36 -07:00
parent 6bdaa843d9
commit 5253332906
2 changed files with 30 additions and 3 deletions
+23 -2
View File
@@ -2,6 +2,7 @@
from __future__ import annotations
import json
import logging
from datetime import UTC, datetime
from typing import Any
@@ -9,6 +10,7 @@ from typing import Any
from agents.items import ModelResponse
from agents.lifecycle import RunHooks
from agents.run_context import AgentHookContext, RunContextWrapper
from agents.tool_context import ToolContext
logger = logging.getLogger(__name__)
@@ -219,8 +221,27 @@ class StrixOrchestrationHooks(RunHooks[Any]):
if not isinstance(ctx, dict):
return
tracer = ctx.get("tracer")
if tracer is not None:
tracer.log_tool_start(ctx.get("agent_id", "?"), tool.name)
if tracer is None:
return
# ``context`` is a ``ToolContext`` for function-tool calls (per the
# SDK ``RunHooks.on_tool_start`` docstring) — that's where the
# per-call args live. ``tool_input`` is the parsed dict when the
# SDK has it; otherwise parse ``tool_arguments`` (raw JSON).
args: dict[str, Any] = {}
if isinstance(context, ToolContext):
tool_input = context.tool_input
if isinstance(tool_input, dict):
args = tool_input
else:
raw = context.tool_arguments
if raw:
try:
parsed = json.loads(raw)
except (ValueError, TypeError):
parsed = None
if isinstance(parsed, dict):
args = parsed
tracer.log_tool_start(ctx.get("agent_id", "?"), tool.name, args)
except Exception:
logger.exception("on_tool_start failed")
+7 -1
View File
@@ -249,13 +249,19 @@ class Tracer:
final_scan_result=self.final_scan_result,
)
def log_tool_start(self, agent_id: str, tool_name: str) -> int:
def log_tool_start(
self,
agent_id: str,
tool_name: str,
args: dict[str, Any] | None = None,
) -> int:
"""Record a tool invocation in flight. Returns an exec_id."""
exec_id = self._next_exec_id
self._next_exec_id += 1
self.tool_executions[exec_id] = {
"agent_id": agent_id,
"tool_name": tool_name,
"args": args or {},
"status": "running",
"result": None,
"timestamp": datetime.now(UTC).isoformat(),