AI Elements
Plan
Displays the steps the agent plans to take, and how far it has got.
Plan is the list of steps the agent decides on before it starts, such as the steps of a migration. Each step is done, running or pending, and the title counts how many are done.
Plan is built with UiTrace with a UiTraceCollapsible for the plan.
When the steps are not known up front, use Task instead.
Installation
Plan is built with the Trace component.
Usage
<template>
<UiTrace>
<UiTraceCollapsible default-open>
<UiTraceCollapsibleTrigger>
<UiTraceLine status="running">
<UiTraceIcon>
<UiIcon name="lucide:route" />
</UiTraceIcon>
<UiTraceTitle>Plan: migrate to Base UI</UiTraceTitle>
<UiTraceDescription>2 of 5 done</UiTraceDescription>
</UiTraceLine>
</UiTraceCollapsibleTrigger>
<UiTraceCollapsibleContent>
<UiTrace>
<UiTraceLine>
<UiTraceIcon>
<UiIcon name="lucide:circle-check" />
</UiTraceIcon>
<UiTraceTitle>Replace the Radix imports</UiTraceTitle>
</UiTraceLine>
<UiTraceLine status="running">
<UiTraceIcon>
<UiIcon name="lucide:circle-dot" />
</UiTraceIcon>
<UiTraceTitle>Rename asChild to render</UiTraceTitle>
</UiTraceLine>
<UiTraceLine status="pending">
<UiTraceIcon>
<UiIcon name="lucide:circle" />
</UiTraceIcon>
<UiTraceTitle>Run the type checker</UiTraceTitle>
</UiTraceLine>
</UiTrace>
</UiTraceCollapsibleContent>
</UiTraceCollapsible>
</UiTrace>
</template>
Details
Put a description above the steps, inside UiTraceCollapsibleContent.
Store the theme in a cookie so the server renders the right one and the page does not flash on load.
AI SDK
Stream the plan as a data part with a fixed id. The AI SDK replaces a data part with the same id, so it updates in place.
const stream = createUIMessageStream({
execute: async ({ writer }) => {
writer.write({ type: "data-plan", id: "plan", data: { title, steps } });
},
});
const plan = computed(() => props.message.parts.find((part) => part.type === "data-plan"));
API Reference
See Trace.