Skip to content
TuffTasks, docs and chat for teams and AI agents

Observability

Tool Call Graph

An agent fanned out to the tools it calls — calls, latency and error rate per edge, with the hottest path picked out.

1 variantMIT

Preview

Tool call graph

triage-l · v14 · last 24 h · 11,857 calls

triage-l · v14

agent · 3.1k runs

Calls / run
3.8
Tool share of latency
63%
Retries
173 · 1.5%
Hot path
refund.create → email.send

Highest call volume: crm.lookup

Installation

Copies the component into components/ui and installs its dependencies and theme tokens.

pnpm dlx shadcn@latest add https://tuffui.com/r/tool-call-graph.json

Usage

Pass your own data and wire the callbacks to your agent runtime.

import { ToolCallGraph } from "@/components/ui/tool-call-graph";

export function AgentTools({ agent, window }: { agent: Agent; window: ToolStats[] }) {
  const calls = window.reduce((sum, t) => sum + t.calls, 0);

  return (
    <ToolCallGraph
      subtitle={`${agent.name} · ${agent.version} · last 24 h · ${calls.toLocaleString()} calls`}
      agent={{ label: `${agent.name} · ${agent.version}`, meta: `agent · ${agent.runs} runs` }}
      tools={window.map((t) => ({
        id: t.tool,
        label: t.tool, // "refund.create"
        calls: t.calls,
        p50Ms: t.p50,
        errorRate: t.failed / t.calls, // 0…1
        retries: t.retries,
      }))}
      stats={[
        { label: "Calls / run", value: (calls / agent.runs).toFixed(1) },
        { label: "Hot path", value: "refund.create → email.send", accent: true },
      ]}
      onSelect={(id) => openToolTraces(id)}
    />
  );
}

Props

PropTypeDefaultDescription
agent*{ label: string; meta?: string }—The caller drawn on the left. `meta` is a short second line, e.g. run count. Narrow cards show only its icon.
tools*ToolCallNode[]—One node per tool, drawn top to bottom in array order. The order never changes with the metric, so nodes stay put while edges re-weigh.
metric"calls" | "latency" | "errors"—Controlled metric. Edge width and opacity scale with it, against the tool with the most of it.
defaultMetric"calls" | "latency" | "errors""calls"Starting metric when uncontrolled.
onMetricChange(metric: ToolCallMetric) => void—Called when the Calls / Latency / Errors switch changes.
highlightstring | nulltop tool for the metricTool to pick out with a tinted node and a flowing edge. Left out, it follows the metric; `null` turns it off.
errorThresholdnumber0.02Error rate from which a tool reads as failing: red dot, red error chip, and a red pick in the Errors view.
titlestring"Tool call graph"Header title.
subtitlestring"<agent> · <calls> calls"Secondary line under the title.
statsToolCallStat[]calls, error rate, retriesFooter row. Pass `[]` to hide it. `accent` draws a value in the accent colour, e.g. a hot path.
formatLatency(ms: number) => string"212 ms" / "1.8 s"Formats p50 latency on the nodes.
onSelect(id: string) => void—Called when a tool node is clicked or pressed. Hover and focus highlight the node's edge on their own.
classNamestring—Extra classes for the root element.
type ToolCallNode = {
  id: string;
  label: string;      // tool name
  calls: number;      // calls in the window
  p50Ms: number;      // median latency, ms
  errorRate: number;  // 0…1
  retries?: number;
};

type ToolCallStat = {
  label: string;
  value: ReactNode;
  accent?: boolean;
};