Elements

Elements · Agents · AUI

Task card

A delegated task with its state, timing, result, and transcript in one card.

fig. 01 · plays once, replay from the corner

Installation

npx shadcn@latest add "@assistant-ui/task-card"
First time? Set up a runtime

Runtime components read their state from an assistant-ui runtime. Add one to an existing project:

npx assistant-ui@latest init

Then wrap your app in a runtime provider:

import { AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime, AssistantChatTransport } from "@assistant-ui/ai-sdk";

export default function App() {
  const runtime = useChatRuntime({
    transport: new AssistantChatTransport({ api: "/api/chat" }),
  });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      {/* your components */}
    </AssistantRuntimeProvider>
  );
}

The installation guide covers new projects, templates, and API routes.

A task card makes delegated work legible without losing the conversation behind it. With a runtime and the opt in components.TaskGroup slot, Thread recognizes nested tool calls and renders them as cards; standalone, you supply the task's state, timing, result, and transcript yourself.

Getting started

Enable task lanes in Thread

app/thread.tsx
"use client";

import { TaskGroup } from "@/components/assistant-ui/elements/task-card.aui";
import { Thread, type ThreadComponents } from "@/components/assistant-ui/elements/thread.aui";

const THREAD_COMPONENTS: ThreadComponents = { TaskGroup };

export function Conversation() {
  return <Thread components={THREAD_COMPONENTS} />;
}

Thread keeps its install lean, so task lanes are one opt in: once components.TaskGroup is set, a tool call carrying a nested messages array with no registered tool UI (and no ui:// MCP app resource) renders through it instead of the tool group; without the slot the same call renders like any other tool call. A lane whose call waits on the user keeps the tool fallback's approval and resume controls under its header and keeps counting elapsed time, so the run never stalls behind the card. A failed call shows the tool fallback's error text under the card, and a cancelled call reads as cancelled rather than failed. Pass your own component to the same slot to replace the lanes; it receives group with the task indices and status counts. Sibling delegations form lanes of four, with a Show N more button for the remaining cards and a summary such as 5 tasks · 1 running · 1 failed; every lane has a state icon, a label taken from the first string among description, task, title, name, prompt, query, and instructions (falling back to the tool name), an optional meta tag from subagent_type, subagentType, agent, or model, and elapsed time from the part's timing. Opening a card mounts its nested conversation through ReadonlyThreadProvider only while the transcript is visible. The tool result renders once below the card.

Place a card yourself

A registered tool UI always takes precedence over the slot. Return the bound TaskCard from a toolkit render when one nested tool call needs a specific location.

app/toolkit.tsx
"use client";

import { defineToolkit } from "@assistant-ui/react";
import { TaskCard } from "@/components/assistant-ui/elements/task-card.aui";

export const toolkit = defineToolkit({
  delegate: {
    type: "backend",
    render: (props) => <TaskCard part={props} />,
  },
});

Anatomy

<div data-slot="task-card">
  <button />
  <div data-slot="task-card-actions" />
  <div data-slot="task-card-transcript" />
  <div data-slot="task-card-result" />
</div>
<div data-slot="aui_task-group">
  <div data-slot="aui_task-group-summary" />
  <button data-slot="aui_task-group-more" />
</div>
<div data-slot="aui_task-transcript-message" />

task-card-actions exists only when actions is supplied; the bound card fills it with the approval and resume controls while the call waits on the user. task-card-transcript exists only when the card has transcript children and is open. task-card-result exists whenever result is supplied, including while the transcript is closed. aui_task-group-summary and aui_task-group-more appear only for groups with more than one task, and the more button appears only when cards remain hidden.

API reference

Bound TaskCard

PropTypeDefaultDescription
partTaskPartrequiredA tool call with a status. Its nested messages, timing, arguments, and result drive the card.
classNamestringMerged onto the card root.

TaskGroup

PropTypeDefaultDescription
groupMessagePrimitive.GroupedParts.GroupPartrequiredProvides task indices and aggregate counts from Thread.
classNamestringMerged onto the group root.