<Plan id="plan-comprehensive" title="Feature Implementation Plan" description="Step-by-step guide for implementing the new authentication system" todos={[ { "id": "1", "label": "Review existing auth flow", "status": "completed", "description": "Analyzed current session-based auth and identified pain points" }, { "id": "2", "label": "Design new token structure", "status": "completed", "description": "Created JWT schema with access/refresh token separation" }, { "id": "3", "label": "Implement JWT middleware", "status": "in_progress", "description": "Adding token validation and refresh logic to API routes" }, { "id": "4", "label": "Add refresh token logic", "status": "pending" }, { "id": "5", "label": "Update user model", "status": "pending" }, { "id": "6", "label": "Write integration tests", "status": "pending", "description": "Cover auth flows, token expiry, and edge cases" }, { "id": "7", "label": "Update API documentation", "status": "pending" }, { "id": "8", "label": "Deploy to staging", "status": "pending" } ]}/>Progress bar and "X of Y complete" at a glance
Distinct icons for pending, in progress, completed, and cancelled
Click any todo to reveal additional context
Delightful feedback when all tasks are done
Copy components/tool-ui/plan and the shared directory into your project. The shared folder contains utilities used by all Tool UI components. The tool-ui directory should sit alongside your shadcn ui directory.
This component requires the following shadcn/ui components:
pnpm dlx shadcn@latest add accordion button card collapsible// Backend toolimport { tool, jsonSchema } from "ai";const showPlan = tool({ description: "Display an implementation plan to the user", inputSchema: jsonSchema<{ task: string }>({ type: "object", properties: { task: { type: "string" } }, required: ["task"], additionalProperties: false, }), async execute({ task }) { return { id: "plan-1", title: "Implementation Plan", description: `Steps to complete: ${task}`, todos: [ { id: "1", label: "Analyze requirements", status: "completed" }, { id: "2", label: "Implement solution", status: "in_progress" }, { id: "3", label: "Write tests", status: "pending" }, ], }; },});// Frontend with assistant-uiimport { makeAssistantToolUI } from "@assistant-ui/react";import { Plan, PlanErrorBoundary, parseSerializablePlan,} from "@/components/tool-ui/plan";export const ShowPlanUI = makeAssistantToolUI({ toolName: "showPlan", render: ({ result }) => { // Tool outputs stream in; `result` will be `undefined` until the tool resolves. if (result === undefined) { return ( <div className="bg-card/60 text-muted-foreground w-full max-w-xl rounded-2xl border px-5 py-4 text-sm shadow-xs"> Loading plan… </div> ); } const plan = parseSerializablePlan(result); return ( <PlanErrorBoundary> <Plan {...plan} responseActions={[ { id: "approve", label: "Approve Plan" }, { id: "revise", label: "Request Changes", variant: "secondary" }, ]} onResponseAction={(id) => { if (id === "approve") console.log("Plan approved"); // Handle other actions }} /> </PlanErrorBoundary> ); },});<Plan id="feature-plan" title="Feature Implementation" todos={[ { id: "1", label: "Design API schema", status: "completed", description: "Created OpenAPI spec with all endpoints documented", }, { id: "2", label: "Implement endpoints", status: "in_progress", description: "Working on authentication middleware", }, { id: "3", label: "Write tests", status: "pending" }, ]}/>Prop
Type
Prop
Type
<Plan id="plan-simple" title="Quick Setup" description="Get started in 3 easy steps" todos={[ { "id": "1", "label": "Install dependencies", "status": "completed" }, { "id": "2", "label": "Configure environment", "status": "in_progress" }, { "id": "3", "label": "Run the app", "status": "pending" } ]}/><Plan id="plan-comprehensive" title="Feature Implementation Plan" description="Step-by-step guide for implementing the new authentication system" todos={[ { "id": "1", "label": "Review existing auth flow", "status": "completed", "description": "Analyzed current session-based auth and identified pain points" }, { "id": "2", "label": "Design new token structure", "status": "completed", "description": "Created JWT schema with access/refresh token separation" }, { "id": "3", "label": "Implement JWT middleware", "status": "in_progress", "description": "Adding token validation and refresh logic to API routes" }, { "id": "4", "label": "Add refresh token logic", "status": "pending" }, { "id": "5", "label": "Update user model", "status": "pending" }, { "id": "6", "label": "Write integration tests", "status": "pending", "description": "Cover auth flows, token expiry, and edge cases" }, { "id": "7", "label": "Update API documentation", "status": "pending" }, { "id": "8", "label": "Deploy to staging", "status": "pending" } ]}/><Plan id="plan-mixed" title="Migration Progress" todos={[ { "id": "1", "label": "Backup database", "status": "completed" }, { "id": "2", "label": "Run migration scripts", "status": "completed" }, { "id": "3", "label": "Verify data integrity", "status": "in_progress", "description": "Running checksums on migrated records" }, { "id": "4", "label": "Update legacy endpoints", "status": "cancelled", "description": "Decided to deprecate instead of migrate" }, { "id": "5", "label": "Switch DNS records", "status": "pending" } ]}/><Plan id="plan-all-complete" title="Deployment Complete" description="All steps finished successfully" todos={[ { "id": "1", "label": "Run pre-flight checks", "status": "completed" }, { "id": "2", "label": "Deploy to production", "status": "completed" }, { "id": "3", "label": "Verify health endpoints", "status": "completed" }, { "id": "4", "label": "Update status page", "status": "completed" } ]}/>Prop
Type
prefers-reduced-motion<Plan
id="plan-comprehensive"
title="Feature Implementation Plan"
description="Step-by-step guide for implementing the new authentication system"
todos={[
{
"id": "1",
"label": "Review existing auth flow",
"status": "completed",
"description": "Analyzed current session-based auth and identified pain points"
},
{
"id": "2",
"label": "Design new token structure",
"status": "completed",
"description": "Created JWT schema with access/refresh token separation"
},
{
"id": "3",
"label": "Implement JWT middleware",
"status": "in_progress",
"description": "Adding token validation and refresh logic to API routes"
},
{
"id": "4",
"label": "Add refresh token logic",
"status": "pending"
},
{
"id": "5",
"label": "Update user model",
"status": "pending"
},
{
"id": "6",
"label": "Write integration tests",
"status": "pending",
"description": "Cover auth flows, token expiry, and edge cases"
},
{
"id": "7",
"label": "Update API documentation",
"status": "pending"
},
{
"id": "8",
"label": "Deploy to staging",
"status": "pending"
}
]}
/>pnpm dlx shadcn@latest add accordion button card collapsible// Backend tool
import { tool, jsonSchema } from "ai";
const showPlan = tool({
description: "Display an implementation plan to the user",
inputSchema: jsonSchema<{ task: string }>({
type: "object",
properties: { task: { type: "string" } },
required: ["task"],
additionalProperties: false,
}),
async execute({ task }) {
return {
id: "plan-1",
title: "Implementation Plan",
description: `Steps to complete: ${task}`,
todos: [
{ id: "1", label: "Analyze requirements", status: "completed" },
{ id: "2", label: "Implement solution", status: "in_progress" },
{ id: "3", label: "Write tests", status: "pending" },
],
};
},
});
// Frontend with assistant-ui
import { makeAssistantToolUI } from "@assistant-ui/react";
import {
Plan,
PlanErrorBoundary,
parseSerializablePlan,
} from "@/components/tool-ui/plan";
export const ShowPlanUI = makeAssistantToolUI({
toolName: "showPlan",
render: ({ result }) => {
// Tool outputs stream in; `result` will be `undefined` until the tool resolves.
if (result === undefined) {
return (
<div className="bg-card/60 text-muted-foreground w-full max-w-xl rounded-2xl border px-5 py-4 text-sm shadow-xs">
Loading plan…
</div>
);
}
const plan = parseSerializablePlan(result);
return (
<PlanErrorBoundary>
<Plan
{...plan}
responseActions={[
{ id: "approve", label: "Approve Plan" },
{ id: "revise", label: "Request Changes", variant: "secondary" },
]}
onResponseAction={(id) => {
if (id === "approve") console.log("Plan approved");
// Handle other actions
}}
/>
</PlanErrorBoundary>
);
},
});<Plan
id="feature-plan"
title="Feature Implementation"
todos={[
{
id: "1",
label: "Design API schema",
status: "completed",
description: "Created OpenAPI spec with all endpoints documented",
},
{
id: "2",
label: "Implement endpoints",
status: "in_progress",
description: "Working on authentication middleware",
},
{ id: "3", label: "Write tests", status: "pending" },
]}
/><Plan
id="plan-simple"
title="Quick Setup"
description="Get started in 3 easy steps"
todos={[
{
"id": "1",
"label": "Install dependencies",
"status": "completed"
},
{
"id": "2",
"label": "Configure environment",
"status": "in_progress"
},
{
"id": "3",
"label": "Run the app",
"status": "pending"
}
]}
/><Plan
id="plan-comprehensive"
title="Feature Implementation Plan"
description="Step-by-step guide for implementing the new authentication system"
todos={[
{
"id": "1",
"label": "Review existing auth flow",
"status": "completed",
"description": "Analyzed current session-based auth and identified pain points"
},
{
"id": "2",
"label": "Design new token structure",
"status": "completed",
"description": "Created JWT schema with access/refresh token separation"
},
{
"id": "3",
"label": "Implement JWT middleware",
"status": "in_progress",
"description": "Adding token validation and refresh logic to API routes"
},
{
"id": "4",
"label": "Add refresh token logic",
"status": "pending"
},
{
"id": "5",
"label": "Update user model",
"status": "pending"
},
{
"id": "6",
"label": "Write integration tests",
"status": "pending",
"description": "Cover auth flows, token expiry, and edge cases"
},
{
"id": "7",
"label": "Update API documentation",
"status": "pending"
},
{
"id": "8",
"label": "Deploy to staging",
"status": "pending"
}
]}
/><Plan
id="plan-mixed"
title="Migration Progress"
todos={[
{
"id": "1",
"label": "Backup database",
"status": "completed"
},
{
"id": "2",
"label": "Run migration scripts",
"status": "completed"
},
{
"id": "3",
"label": "Verify data integrity",
"status": "in_progress",
"description": "Running checksums on migrated records"
},
{
"id": "4",
"label": "Update legacy endpoints",
"status": "cancelled",
"description": "Decided to deprecate instead of migrate"
},
{
"id": "5",
"label": "Switch DNS records",
"status": "pending"
}
]}
/><Plan
id="plan-all-complete"
title="Deployment Complete"
description="All steps finished successfully"
todos={[
{
"id": "1",
"label": "Run pre-flight checks",
"status": "completed"
},
{
"id": "2",
"label": "Deploy to production",
"status": "completed"
},
{
"id": "3",
"label": "Verify health endpoints",
"status": "completed"
},
{
"id": "4",
"label": "Update status page",
"status": "completed"
}
]}
/>