Tool Latency
Per-tool latency and failure rate — the ops view of a tool fleet. Bars are drawn from p95, not the mean: a tool averaging 200ms that spikes to nine seconds one call in twenty is the one blowing your timeout, and the mean hides it.
src/components/ui/tool-latency.tsxAbout
From the component's own source, where it was written.
Per-tool latency and failure rate — the ops view of a tool fleet.
**p95, not the mean.** A tool averaging 200ms that spikes to nine seconds one call in twenty is the one blowing your agent's timeout, and the mean hides it completely. The bar is drawn from p95 for the same reason.
Bars are scaled against the slowest tool in the set, so the row that is actually the problem is visually the longest. Scaling each to its own maximum would draw every tool as a full bar and rank nothing.
Error rate is coloured by threshold rather than on a gradient: anything above errorThreshold is a problem and everything below it is noise, and a smooth ramp makes 0.4% and 4% look like neighbours.
Install
npx astralyx-ui add tool-latency
Usage
import { ToolLatency } from '@/components/ui/tool-latency'
<ToolLatency tools={rows} errorThreshold={0.01} />Composer
Change the props and the source below follows.
- 610ms9.20s5.2%
issue_refundupstream: stripe - 180ms2.14s0.4%
search_docs - 340ms1.12s1.9%
send_email - 220ms480ms0.0%
create_ticket - 42ms96ms0.0%
get_customer
<ToolLatency
tools={rows}
sorted={true}
errorThreshold={0.01}
/>Examples
A fleet with one bad upstream
<ToolLatency tools={rows} />API
Generated from the source, so it cannot fall behind the code. One table per exported component, then hooks, functions and types.
ToolLatency
Extends Omit<ComponentProps<'div'>, 'children'>.
| Prop | Type | Default | Description |
|---|---|---|---|
| tools | ToolLatencyRow[] | required | { name, p50, p95, calls, errorRate?, meta? }. Durations in milliseconds, errorRate as 0–1. |
| errorThreshold | number | 0.01 | A threshold, not a gradient: above it is a problem, below it is noise, and a smooth ramp makes 0.4% and 4% look like neighbours. |
| sorted | boolean | true | Slowest p95 first. Sorts a copy — the caller’s array is never mutated. |
| formatDuration | (ms: number) => string | defaultFormat | — |
| emptyLabel | string | 'No calls in this window.' | — |
| label | string | 'Tool latency' | — |
| headers | { tool?: string; p50?: string; p95?: string; calls?: string; errors?: string } | — | — |
| scale | p95 vs the slowest tool | — | Scaled across the set, so the worst row is the longest bar. Scaling each to its own maximum would draw every tool full and rank nothing. |
Types
ToolLatencyRow
Per-tool latency and failure rate — the ops view of a tool fleet.
| Field | Type | Description |
|---|---|---|
| name | string | — |
| p50 | number | Milliseconds. |
| p95 | number | — |
| calls | number | Invocations in the window. |
| errorRate? | number | 0–1. |
| meta? | ReactNode | — |