affectUI › Components › Agents

Agent Handoff

A task passed from agent to agent like a relay – at every handoff what went along to the next one, and what got lost on the way.

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

When to use

  • Several agents work on tasks one after another – research, analysis, writing, review – and people need to see what each one passed on
  • Debugging multi-agent pipelines: where did the context get lost?
  • Letting people push a task on to a later agent and watch it travel down the relay

When not to use

  • Agents working side by side at the same time – use Agent Lanes
  • Who started whom, as a hierarchy – use Agent Tree

Usage

import { AgentHandoff, type HandoffAgent, type Handoff } from "@/components/ui/agent-handoff";

const agents: HandoffAgent[] = [
  { id: "research", name: "Researcher", model: "Opus 5.5", avatar: <ClaudeLogo /> },
  { id: "writer", name: "Writer", model: "GPT-5", avatar: <OpenAILogo /> },
];

const handoffs: Handoff[] = [
  {
    id: "launch-1", from: "research", to: "writer", task: "Launch post",
    items: [
      { id: "brief", label: "launch-brief.md", kind: "file" },
      { id: "quotes", label: "3 user quotes", kind: "note", lost: true, why: "Over the writer's context budget" },
    ],
  },
];

<AgentHandoff
  agents={agents}
  handoffs={handoffs}
  tasks={[
    { id: "launch", title: "Launch post", logo: <NotionLogo />, status: "working", agent: "writer", note: "Drafting" },
    { id: "pricing", title: "Pricing page copy", logo: <NotionLogo />, status: "todo" },
  ]}
  onAssign={(task, agent) => run(task.id, agent.id)}
  onRestore={(handoff, item) => passOn(handoff.id, item.id)}
/>

Props

NameTypeDefaultDescription
agentsHandoffAgent[]In relay order: { id, name, model?, avatar?, description? } – each card shows what it's for and the task it's on, taken from tasks
handoffsHandoff[]What was handed over: { id, from, to, task, items } – each lands as a card in the column between from and to, latest on top; a new id sends light along its lines
itemsHandoffItem[]Per handoff: { id, label, kind?: "file" | "source" | "fact" | "decision" | "note", lost?, why? } – lost ones are struck through, why shows on hover
tasksHandoffTask[]Every task: { id, title, logo?, status: "todo" | "working" | "done" | "warning", agent?, note? } – handoffs refer to them by title for the logo and where the task is now; the first agent shows the next todo one as up next
onAssign(task, agent) => voidA handoff card was dropped on an agent to the right of its column – give that task to it and keep handoffs and tasks up to date. Cards only move on down the relay, never back
onRestore(handoff, item) => voidAdds "Add back" to a lost item's card – pass it on after all
classNamestringExtra class on the root

Keyboard

  • Tab: Moves through the waiting tasks, the agents (while a task is picked up) and the handed-over items
  • Enter / Space: Opens a card or an agent's task; with a card picked up, gives it to the focused agent; on a lost item: shows why, and Add back

Accessibility

  • Tasks can be given to an agent without dragging: double-tap a card, then tap an agent to its right
  • Each column and each handoff's items are labelled lists; cards and lost items are buttons with aria-expanded

Responsive

  • Below about 760px the status shows as an icon only; below 620px the relay stacks into one column – an agent, its handoff, the next agent
  • 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
  • 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
  • Context Map – What fills an agent's context window, as a living treemap – system prompt, tools, memory, every file, the chat and tool results as tiles that glide as it grows, the free space dashed, and compaction squeezing old turns into a summary
  • 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