Depute Logo

Plan Card

Show the agent's proposed plan before it executes. Users see the trajectory before anything happens.

Install

npx ax-depute@latest add plan-card
pnpm dlx ax-depute@latest add plan-card
yarn dlx ax-depute@latest add plan-card
bunx ax-depute@latest add plan-card

Overview

Plan Card implements the plan-first pattern: show the trajectory, then execute. Before an agent takes any action, it proposes a plan — a numbered list of steps with confidence scores and assumptions.

This lowers fear and increases informed consent. Users can see where they're going before anything happens.

Customer Analysis Pipeline

Plan: Customer Analysis Pipeline, step 3 of 4 in progress
  1. Fetch customer data from CRM
  2. Cross-reference billing records
  3. Generate summary report
  4. Send notification to stakeholders
Interactive StorybookView all states, toggle props, and test edge cases.

Basic usage

<PlanCard
  steps={agent.proposedPlan}
  assumptions={agent.assumptions}
/>

With mock data

import { generateMockPlan } from '@/utils/mockData';

const plan = generateMockPlan(4); // 4-step plan

<PlanCard
  steps={plan.steps}
  assumptions={plan.assumptions}
/>

Live execution state

When the agent is running, pass activeStepId to highlight the current step:

<PlanCard
  steps={agent.plan}
  activeStepId={agent.currentStepId}
/>

Streaming state

When steps are still being generated by a streaming backend, pass isStreaming. This adds data-streaming="true" to the root element — no built-in animation. Style it however the host product expects:

<PlanCard
  title={agent.planTitle}
  steps={agent.partialSteps}
  isStreaming={agent.isStreaming}
  mode="indeterminate"
/>
/* Host product controls the visual */
[data-streaming="true"] .plan-card-title::after {
  content: "…";
  animation: pulse 1s infinite;
}

Per-step reasoning

When each PlanStep has a reasoning string, opt-in to collapsible reasoning toggles with showReasoning. Set defaultExpandedStepId to pre-expand a specific step on mount:

<PlanCard
  title={agent.planTitle}
  steps={agent.planSteps} // steps with .reasoning populated
  showReasoning
  defaultExpandedStepId={agent.activeStepId}
/>

Props

PropTypeDefaultDescription
stepsPlanStep[]RequiredOrdered list of plan steps
titlestringRequiredTitle of the plan
assumptionsstring[]undefinedAgent's stated assumptions
reasoningstringundefinedAgent's overall reasoning (collapsible)
activeStepIdstringundefinedID of the currently executing step
showConfidencebooleanfalseShow confidence badge per step
isStreamingbooleanfalseSignals that steps are still being generated. Adds data-streaming="true" to the root element — no built-in animation; style via CSS.
showReasoningbooleanfalseRenders a collapsible reasoning toggle on each step that has a reasoning string.
defaultExpandedStepIdstringundefinedID of the step whose reasoning is expanded by default (uncontrolled). Follows the activeStepId pattern.

PlanStep type

interface PlanStep {
  id: string;
  label: string;
  status: 'pending' | 'active' | 'completed' | 'failed';
  confidence?: number;   // 0–1
}

When to use

  • The agent is about to take a multi-step or multi-tool action and the user should be aware of the trajectory before it begins
  • Trust is low or the action surface is new — surfacing the plan early builds informed consent
  • The agent's intent is ambiguous without a plan (e.g., "refactor this codebase" covers too many possibilities)
  • You want to give the user a natural moment to abort before any irreversible step starts

When not to use

  • The agent is performing a single, trivially understood action (e.g., "look up the weather") — a full plan card adds friction without value
  • The agent's actions are happening fully in the background with no synchronous human checkpoint; use Tool Trace for passive monitoring instead
  • You are already showing a Decision Record that captures the full approved plan — avoid duplicating plan state in both components

Accessibility

  • Uses semantic <ol> for step lists; each step renders as <li> with role="listitem"
  • Active step is annotated with aria-current="step" to assist screen reader navigation
  • Completed and failed steps carry aria-label values that include their status (e.g., "Step 2: Complete. Write schema migration.")
  • Streaming state is announced via aria-live="polite" on the container when isStreaming is true
  • All collapsible reasoning toggles use <button aria-expanded> with accessible toggle labels

Solution Patterns

Plan Card is always the first primitive in a single-agent flow:

Plan Card → Approval Gate → Run Controls → Tool Trace → Artifact Card

Show it before the agent runs. Once execution starts, it updates step statuses live.

Design rationale

Why show the plan before execution? Claude Cowork (Anthropic) shows the full plan in a "Progress" panel before any action is taken — validating the plan-first pattern. The core idea: agents that propose concrete work before asking for permission feel collaborative rather than autonomous. Users who can see a trajectory are far more likely to engage with it critically than users who are handed a fait accompli.

On this page