affectUI › Components › Agents
Fan-out Grid
One agent hands a big job to many workers – every task a cell on a live grid that fills in as they get through it, with retries, failures, cost and the time left, and the details of any task on hover.
Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/fan-out-grid.json · Import from @/components/ui/fan-out-grid
When to use
- An agent fans one job out to many workers – enriching leads, translating pages, labelling tickets, running evals – and you want to watch it fill in
- Batch runs with hundreds of tasks, where retries and failures matter more than any single step
- A live overview next to a run's log: how far it is, what it costs, how long is left
When not to use
- A handful of agents and who started whom – use Agent Tree
- Where the time of one run goes, step by step – use Trace Waterfall
- Several agents side by side over time – use Agent Lanes
Usage
import { FanoutGrid, type FanoutTask } from "@/components/ui/fan-out-grid";
const tasks: FanoutTask[] = leads.map((lead) => ({
id: lead.id,
label: lead.domain,
status: lead.status, // "queued" | "running" | "retrying" | "done" | "failed"
worker: lead.worker,
start: lead.startedMs, end: lead.endedMs,
cost: lead.cost, attempts: lead.attempts,
result: lead.summary, error: lead.error,
}));
export function Enrichment({ elapsed }: { elapsed: number }) {
return <FanoutGrid tasks={tasks} job="Enrich 240 leads" workers={16} now={elapsed} onRetry={(ids) => retry(ids)} />;
}Props
| Name | Type | Default | Description |
|---|---|---|---|
tasks | FanoutTask[] | { id, label, status, worker?, start?, end?, cost?, attempts?, result?, error? } – one per task, in the order the cells should show | |
status | "queued" | "running" | "retrying" | "done" | "failed" | Per task – picks the cell's tint: gray, blue with a shine, amber, green, red | |
start / end | number | Per task, in ms from the start of the job – used for its duration and the time left | |
attempts | number | Per task – 2 and more show in its details | |
job | string | What the whole job does, next to the title – e.g. "Enrich 240 leads" | |
workers | number | How many workers run at once – the time left is worked out from it (defaults to the tasks running now) | |
now | number | 0 | The clock, in ms from the start of the job |
onRetry | (ids: string[]) => void | Shows "Retry failed" while tasks have failed, and gets their ids | |
onSelect | (task | null) => void | A task was picked (click or Enter) – null when it's let go | |
formatCost | (amount: number) => string | dollars | Formats every cost |
title | string | "Fan-out" | Heading of the bar |
icon | ReactNode | A small mark before the title, e.g. the agent's logo | |
className | string | Extra class on the root |
Keyboard
- Tab: Moves into the grid (one stop) and on to the counts on the tray and Retry
- ArrowLeft / ArrowRight / ArrowUp / ArrowDown: Walks the cells and shows each one's details; Home and End jump to the first and the last
- Enter / Space: Keeps the details open, or lets them go
- Esc: Lets go of the details
Accessibility
- The grid is a single tab stop; the details of the cell you're on are its description
- The counts on the tray under the card are toggle buttons (aria-pressed) that show only one state
- The run's progress is announced politely in steps of ten percent, and once more when it's finished
Responsive
- Built on a container query: the grid fills whatever width it gets, the cells wrap into rows
- Under 520px the cells get smaller and the numbers move to a line of their own
- Dark mode built in: switches when an ancestor (usually <html>) has the class dark or data-theme="dark"
Requirements
- React 19
Related
- Agent Tree – Who started whom – an orchestrator and its sub-agents as a live tree, with status, cost and time on every card, costs rolling up each branch, and branches that fold to one line
- Trace Waterfall – Where the time and money of an agent run go – every LLM call, tool call and sub-agent as a bar on a live timeline, with tokens and cost per step, the slowest call marked and branches that fold into their parent
- Agent Lanes – Where every agent is right now – a live timeline with a lane per agent, tasks growing into “now”, hand-offs drawn between agents and approvals right on the block
- Agent Queue – The work waiting for your agents, and how fast it moves – jobs drop into a live queue, glide into free worker slots as growing bars and land in Done or Failed, while a depth chart shows the backlog build up when a rate limit pauses the workers and drain when they resume
Guides
- How to show AI agent costs and token usage – UI patterns for showing what AI agents cost – per run, per step and per agent – plus token usage, context limits and budgets.