affectUI › Components › Agents

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.

Part of affectUI Pro. Install: npx shadcn@latest add https://www.affectui.com/r/agent-queue.json · Import from @/components/ui/agent-queue

When to use

  • A job queue in an agent product – how many tasks wait, which worker runs what, and how fast the backlog moves
  • Watching backpressure live: a provider rate-limits, the workers pause, the queue builds up and drains again
  • An ops view next to your agents where people can pause the queue, add or remove workers, or move a job to the front

When not to use

  • Several agents side by side over time – use Agent Lanes
  • Handing work to a specific agent by hand – use Delegate Board
  • A list of background tasks with their results – use Agent Inbox
  • Where the time and money of one run go – use Trace Waterfall

Usage

import { AgentQueue, type QueueJob, type QueueWorker } from "@/components/ui/agent-queue";

const workers: QueueWorker[] = [
  { id: "w1", name: "Sonnet 5.5" },
  { id: "w2", name: "GPT-6 Sol" },
];

const jobs: QueueJob[] = [
  { id: "j1", name: "Summarize ticket #4821", kind: "llm", status: "running", worker: "w1",
    enqueuedAt: t0, startedAt: t0 + 1200, progress: 0.4 },
  { id: "j2", name: "Embed 240 docs", kind: "tool", status: "queued", enqueuedAt: t0 + 800 },
  { id: "j3", name: "Draft reply – Acme", kind: "llm", status: "queued", priority: "high", enqueuedAt: t0 + 2100 },
];

export function Jobs() {
  // Times are on one clock (epoch ms here) – without now, the component ticks Date.now while there is work
  return <AgentQueue jobs={jobs} workers={workers} backpressure={20} />;
}

Props

NameTypeDefaultDescription
jobsQueueJob[]{ id, name, kind, status, enqueuedAt, priority?, startedAt?, endedAt?, worker?, progress?, estimate?, attempt?, maxAttempts?, detail?, icon?, error? } – waiting, running and recently finished jobs
kind"llm" | "tool" | "agent" | "human"Per job – picks its tint: LLM calls violet, tool calls teal, sub-agents slate, human review blue
status"queued" | "running" | "done" | "failed"Per job – a job that goes from running back to queued with a higher attempt shows as a retry
priority"high" | "normal" | "low""normal"Per job – a high one glides past the others to the front
progress / estimatenumberPer job – 0–1 while it runs, or the expected run time in ms to estimate it
workersQueueWorker[]{ id, name, detail?, icon? } – the slots; their number is the concurrency
nownumberThe clock, on the same scale as the job times – without it, the component keeps its own (Date.now)
rateLimits{ from, until, label? }[]Stretches when the provider rate-limits – while one is active the running jobs pause in amber with a countdown
paused / onPausedChangeboolean / (paused) => voidThe queue is paused; the handler shows a Pause/Resume button
onConcurrencyChange(workers: number) => voidShows a – N + stepper for the number of workers
minConcurrency / maxConcurrencynumber1 / 8The stepper's range
backpressurenumberA depth that means trouble – a dashed line on the chart; above it Waiting turns amber
windownumber120000How far back the depth chart looks, in ms
totals{ done?, failed? }Counts since the start, when jobs only holds the recent ones
openId / defaultOpenIdstring | nullnullThe job whose card is pinned, controlled or uncontrolled
onOpenChange(id: string | null, job?: QueueJob) => voidA job's card was pinned or closed
onPromote / onCancel(job: QueueJob) => voidShow "Move to front" and "Cancel" in a pinned card
title / namestring"Queue"Heading, and the queue's name muted next to it
classNamestringExtra class on the root

Keyboard

  • Tab: Moves into the jobs (one job is in the tab order), then to the card's buttons
  • ArrowUp / ArrowDown / ArrowLeft / ArrowRight: Walks through the running jobs, slot by slot, then the queue from the front; Home and End jump to the ends
  • Enter / Space: Pins or closes the focused job's card
  • Esc: Closes the card

Accessibility

  • Every job is a real button, labelled with its name, kind, how long it waited or ran, its place in line, priority and attempt
  • Roving focus – only one job is in the tab order, so the flow is a single stop
  • The pinned card is a dialog with a close button; Esc closes it and returns focus to the job
  • Rate limits, their end, failures, retries and crossing the backpressure line are announced in a polite live region
  • The chart is an image with a text summary: how many wait now, the peak, the average and the rate-limited stretches
  • Pause is a toggle button with aria-pressed; the stepper's buttons say what they do and the count is announced

Responsive

  • Built on a container query and the measured width: wide, the flow runs left to right – queue, workers, Done and Failed
  • Under 600px the flow stacks: queue on top, the workers below (just their marks, the rail gets the room), Done and Failed side by side
  • The four numbers wrap to two columns; under 440px Pause and the stepper get a row 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 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
  • Delegate Board – Hand work to your agents by dragging it onto them – each agent previews its new “busy until” time, or switch to Auto and every new task goes to whoever is free first
  • Agent Inbox – All your background agent tasks in one calm list – live clocks and status tags, filter tabs with rolling counts, rows that unfold to the last steps with Approve, Reject, Retry or Open, and glide to their new place
  • 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