Tool Trace
Live timeline of every tool call with inputs, outputs, and policy flags.
Install
npx ax-depute@latest add tool-tracepnpm dlx ax-depute@latest add tool-traceyarn dlx ax-depute@latest add tool-tracebunx ax-depute@latest add tool-traceOverview
Auto-scrolling timeline representing the agent's inner loop. Entries with policyFlags (requiresApproval, writesState, externalAction) are visually distinguished from routine calls.
- validate_schema1.3s
- create_record924mswrites
- read_file1.6s
- write_file733mswrites
Basic usage
<Tool Trace
calls={[]}
autoScroll={true}
/>With mock data
Because Tool Trace requires an array of tool call objects to render its timeline, you'll typically pass in an array that looks like this:
import { ToolTrace } from '@/components/ToolTrace';
import type { ToolCall } from '@/types/ax-common';
const mockCalls: ToolCall[] = [
{
id: 'call_1',
name: 'fetch_user_data',
status: 'completed',
timestamp: new Date(),
input: { userId: '123' },
output: { name: 'Alice' },
policyFlags: { externalAction: true }
}
];
export function App() {
return (
<Tool Trace
calls={mockCalls}
expandable={true}
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
calls | ToolCall[] | Required | Array of tool calls to display in the trace timeline. |
autoScroll | boolean | false | Whether the timeline should automatically scroll to the latest entry when new calls are added. |
maxHeight | string | undefined | Maximum height of the container before an internal scrollbar appears (e.g., '400px'). |
onEntryClick | (call: ToolCall) => void | undefined | Callback fired when a user clicks on a tool call entry. |
expandable | boolean | false | If true, entries can be clicked to expand and reveal their raw JSON input and output. |
When to use
- An agent is actively executing and the user should be able to observe its tool call activity in real time
- Auditability is required — after the run, the user or a reviewer should be able to inspect exactly which tools ran, with what inputs, and what they returned
- The agent can call external, state-mutating, or policy-flagged tools and you want to surface those calls distinctly from routine ones
When not to use
- The agent's operations are already fully visible through another mechanism (e.g., a database log) — don't duplicate audit trails in the UI
- The agent only performs a single tool call — a full scrollable trace timeline adds visual weight without value; a simpler status indicator suffices
- You are building a developer debugging view —
Tool Traceis a user-facing oversight tool, not a raw log viewer; for raw logs, link to your platform's log explorer
Accessibility
- Each tool call entry is a
<li>within arole="log"list, which communicates the live-updating nature to assistive technologies - New entries appended during streaming are announced via
aria-live="polite"on the log container - Expandable entries use
<button aria-expanded>with descriptive labels (e.g., "Expand tool call: fetch_user_data") - Policy flag badges (e.g.,
externalAction,writesState) are exposed asaria-labeltext — not color alone - Duration and timestamp metadata are part of the accessible text, not hidden in tooltips
Solution Patterns
Tool Trace is the primary visual feedback mechanism while an agent is actively running. It generally renders below Run Controls:
Plan Card → Approval Gate → Run Controls → [Tool Trace] → Artifact CardIt updates asynchronously. As soon as the agent completes its final tool call, the flow concludes with an Artifact Card.
Design rationale
Why comprehension over logging? Standard terminal logs are unreadable for non-engineers. Tool Trace formats JSON inputs and outputs into a structured UI, translating machine process into human-readable proof of work.
What is policy flagging? Not all tools are equal. A read_file is routine, but a execute_payment is critical. The policyFlags system allows specific tool calls to bear visual severity tokens (e.g., an amber badge for writesState), distinguishing high-risk calls from routine ones at a glance and directing human attention where it matters.
Why automatic anchoring? In an active stream, the human loses context if the UI doesn't track the edge of computation. The autoScroll logic ensures the most recent action is always in view, creating a sense of live generative momentum.