Elements

Elements · Agents

Schedule

A run that repeats on its own, with its cadence and how it has been doing.

Triage the issue queueevery day at 06:00
nextTomorrow, 06:00
recent runs
Today, 06:00ok
Yesterday, 06:00ok
Sat, 06:00failed
fig. 01

Installation

npx shadcn@latest add "@assistant-ui/elements-schedule-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 schedule card shows a run that repeats on its own: its cadence, when it runs next, and whether recent runs succeeded. It is a plain display; the schedule itself, and what pausing actually does, live in your own backend.

Getting started

Anatomy

<div data-slot="schedule-card">
  <div>
    <span>{/* clock icon avatar */}</span>
    <div>
      <span>{name}</span>
      <span>{cadence}</span>
    </div>
    <button role="switch" aria-checked={enabled} />
  </div>
  <div>
    <span>next</span>
    <span>{/* nextRun, or the literal text "paused" */}</span>
  </div>
  <div>
    <span>recent runs</span>
    {/* one row per history entry */}
    <span>{/* check or x */}</span>
    <span>{run.at}</span>
    <span>{/* "ok" or "failed" */}</span>
  </div>
</div>

The "next" row always renders. While enabled is true it shows nextRun; while false it shows the literal text "paused" and the whole row dims. The switch is a controlled visual: its track color and thumb position come entirely from enabled, and clicking it only fires onToggle, so nothing moves until your handler updates the prop. An empty history array renders the "recent runs" label with no rows below it.

Examples

A paused schedule

<ScheduleCard name="Nightly report" cadence="Daily at 06:00" nextRun="Tomorrow 06:00" enabled={false} history={history} />

Reading run history

Each entry is independent of the others; a mix of successes and failures renders in the order you pass:

<ScheduleCard
  {...rest}
  history={[
    { id: "1", at: "Today 06:00", ok: true },
    { id: "2", at: "Yesterday 06:00", ok: false },
  ]}
/>

Restyle the card

The root uses the shared paper surface; the cadence, "next", and "recent runs" labels use mono, and the "next" row sits in a field pill.

<ScheduleCard className="max-w-md rounded-3xl" {...rest} />

API reference