Skip to content
Mizen UI
Docs

IntroductionInstallationCLIStylingFoundationsThemingCompositionIntegrationsAccessibilityFor agents

useCopyToClipboard

AccordionAspect RatioCardCollapsibleFrameGridGroupInlineScroll AreaSectionSeparatorSpacerStack

BlockquoteCitationCodeHeadingKbdLabelLinkTextVisually Hidden

ButtonButton GroupToggleToggle groupToolbar

CalendarCheckboxCheckbox groupComboboxDate pickerDate range pickerDate-Time InputFieldFieldsetFile UploadFormInputInput groupNumber fieldOTP FieldRadio groupSelectSliderSwitchTextareaTime Input

BreadcrumbMenubarNavigation MenuPaginationSegmented ControlStepperTabs

Alert dialogCommandContext MenuDialogDrawerMenuPopoverPreview CardSheetTooltip

AlertBadgeEmptyError StateMeterProgressSkeletonSpinnerStatus dotToast

Activity FeedAvatarAvatar GroupData TableListMetricOverflow ListProperty ListTableTokenTree

Area ChartBar ListCalendar HeatmapCategory ComparisonChart FrameChart LegendChart TooltipDistributionFunnelHeatmapMetric TrendPart-to-WholeProgress RingsRadar ChartRadial BarsSankey ChartScatter ChartScore GaugeTime Series

Diagram

AttachmentCarouselCode BlockLightboxMarkdownThumbnailTimestamp

Agent ThinkingApproval CardComposerConversationInline CitationMessageMessage ScrollerQuestion CardSourcesStreaming TextSuggestionTask ListTerminalTool Call

On this page

  • Preview
  • Usage
  • With the AI SDK
  • With TanStack AI
  • Examples
  • Failed step
  • Recommendations
  • Usage boundaries
  • API reference

Agentic

Task List

The steps an agent plans and how far it has got. It can ask before the agent starts, marks the step in progress, and folds into a summary when every step is done.

idle

Usage

import { TaskList } from "@mizen-labs/ui";

With the AI SDK

The AI SDK has no plan part. Stream the plan as a custom data part and update each step's status as the agent works.

import { useChat } from "@ai-sdk/react";
import { TaskList, type TaskListStep } from "@mizen-labs/ui";

// Your agent streams its plan as a data part, such as data-plan, and
// updates each step's status as it works.
type PlanPart = {
	data: { steps: TaskListStep[]; title: string };
	type: "data-plan";
};

export function AgentPlan({ onApprove }: { onApprove: () => void }) {
	const { messages, status } = useChat();
	const reply = messages.findLast((message) => message.role === "assistant");
	const plan = reply?.parts.findLast(
		(part): part is PlanPart => part.type === "data-plan"
	);
	if (!plan) return null;
	return (
		<TaskList
			// Ask before running while the agent waits for an answer.
			approval={status === "ready" && plan.data.steps.every((step) => step.status === "pending")}
			onApprove={onApprove}
			steps={plan.data.steps}
			title={plan.data.title}
		/>
	);
}

With TanStack AI

Return the plan from a tool, such as a plan tool the model calls first, and read its output from the tool-call part.

import { TaskList, type TaskListStep } from "@mizen-labs/ui";

// part is a tool-call part whose tool returns { title, steps }.
export function PlanFromTool({ part }: { part: { output?: { steps: TaskListStep[]; title: string } } }) {
	return part.output ? (
		<TaskList steps={part.output.steps} title={part.output.title} />
	) : null;
}

Examples

Failed step

A failed step stops the plan and says why, with Retry from here.

Recommendations

GuidancePractice
Do

Keep step titles short and in the imperative, such as "Run the visual tests". Update each step's status as the agent works, and mark exactly one step as running.

Usage boundaries

GuidanceBoundary
Scope

The application runs the agent and stores the plan. Task List shows each step's state; Approve, Revise, and Retry only report the choice.

Scope

Use it for steps the agent decides on before it starts. Calls it makes along the way belong in Tool Call Group.

API reference

Public props from @mizen-labs/ui. Use exported prop types for the complete TypeScript contract.

PropTypeDefaultDescription
titlestring—The plan's goal, shown in the header and naming the list.
stepsreadonly { id; title; status: "pending" | "running" | "complete" | "error"; detail?; duration?; error? }[]—Each step with an id, a title, and a status. detail adds a muted second line; duration and error show once it ends.
approval / onApprove / onReviseboolean / () => voidfalseAsks before the agent starts, with Approve and Revise. Each button appears only with its handler.
onRetry(stepId: string) => void—Shows Retry from here under a failed step, with the step's id.
durationnumberMeasuredSeconds the plan took, shown once it is done. Measured while the component watches it run; pass it for a plan from history.
PreviousSuggestionNextTerminal
  1. Find the media queries in Card, not started

    packages/ui/src/components/card

  2. Add container-type to the card wrapper, not started
  3. Rewrite the breakpoints as @container rules, not started
  4. Run the visual tests, not started

    Light, dark, and 390px

Approve this plan to start.

Failed 4 of 4: Run the visual tests
  1. Find the media queries in Card, done0.8s

    packages/ui/src/components/card

  2. Add container-type to the card wrapper, done0.4s
  3. Rewrite the breakpoints as @container rules, done2.1s
  4. Run the visual tests, failed12s

    Light, dark, and 390px

    3 screenshots changed: Card in the settings sidebar is 32px wider.