Epicenter
Local-first, open source apps
Task is a piece of work the agent is doing, such as finding the project files or updating a page. Each step, like a search, a read or an edit, appears under the task when the agent takes it.
Task is built with Trace with a Trace.Collapsible for each task.
Task or Plan
Both are a list of steps under a collapsible line. The difference is when the steps are known.
Use Plan when the agent decides the steps before it starts. Use Task when the steps come from the work itself, and the agent only knows the next one once it has taken the last.
Installation
Task is built with the Trace component.
Usage
<script lang="ts">
import * as Trace from "$lib/components/ui/trace/index.js";
</script> <Trace.Root>
<Trace.Collapsible open>
<Trace.CollapsibleTrigger>
<Trace.Line>
<Trace.Title>Found the project files</Trace.Title>
</Trace.Line>
</Trace.CollapsibleTrigger>
<Trace.CollapsibleContent>
<Trace.Root>
<Trace.Line>
<Trace.Icon>
<SearchIcon />
</Trace.Icon>
<Trace.Title>Searched for app/page.tsx</Trace.Title>
</Trace.Line>
<a href="/files/app/page.tsx">
<Trace.Line>
<Trace.Icon>
<FileTextIcon />
</Trace.Icon>
<Trace.Title>Read app/page.tsx</Trace.Title>
</Trace.Line>
</a>
</Trace.Root>
</Trace.CollapsibleContent>
</Trace.Collapsible>
</Trace.Root> Status
Set the task's status from its steps. Write the title in the present tense while the task runs, and in the past tense once it is done.
Put several tasks in one Trace. Keep the running task open, and close each task once it is done.
AI SDK
Stream each task as a data part with its own id. The AI SDK replaces a data part with the same id, so writing a task again with a new step updates it in place.
const stream = createUIMessageStream({
execute: async ({ writer }) => {
writer.write({ type: "data-task", id: "update", data: { title, steps } });
},
}); {@const tasks = message.parts.filter((part) => part.type === "data-task")} API Reference
See Trace.