Search

Search components and blocks

Sign in

Agent Run

ProOpen page

A single agent run as a card: a pulsing avatar, a live status and timer, a progress line, and tool-call steps that spin, tick off and expand to show their output.

pnpm dlx shadcn@latest add @ditherui/agent-run
R

Refactor agent

Ready · 0.0s

Props

namestring—
stepsAgentRunStep[]—
stepMsnumber1400
classNamestring—

Agent Run with Approval

ProOpen page

A chat-style agent run: a segmented progress rail, steps that open to show their live process while they run, then a final accordion that pauses on a diff for you to approve or reject.

pnpm dlx shadcn@latest add @ditherui/agent-run-approval
Customers are being charged twice when the payment gateway times out. Find the cause in the retry logic and fix it.
Working
0.0s · 0 tokens

  • ›Charge happens in the payments retry path
  • ›Checking how retries build the gateway request
  • ›Plan: search → read → patch

  • ›$ rg idempotencyKey src/
  • ›3 matches in 2 files
  • ›Only src/payments/retry.ts creates the key

  • ›Opened src/payments/retry.ts
  • ›Reading chargeWithRetry (lines 36–47)
src/payments/retry.ts lines 36–45
36export async function chargeWithRetry(order: Order, attempts = 3) {
37 let lastError: unknown;
38 for (let attempt = 1; attempt <= attempts; attempt++) {
39 try {
40 const idempotencyKey = crypto.randomUUID();
41 return await gateway.charge(order, { idempotencyKey });
42 } catch (error) {
43 lastError = error;
44 }
45 }

  • ›Comparing the key across attempts
  • ›Every retry generates a different key

Line 40 creates a new key inside the loop, so every attempt after a timeout looks like a brand-new charge. The key belongs to the order, not the attempt: create it once, before the loop, and reuse it.

src/payments/retry.ts

36export async function chargeWithRetry(order: Order, attempts = 3) {
37+ // One key per order, so the gateway drops a repeated charge.
38+ const idempotencyKey = order.idempotencyKey ?? crypto.randomUUID();
39 let lastError: unknown;
40 for (let attempt = 1; attempt <= attempts; attempt++) {
41 try {
− const idempotencyKey = crypto.randomUUID();
42 return await gateway.charge(order, { idempotencyKey });
Apply this change to retry.ts?

Props

promptstring—
stepsApprovalStep[]—
filenamestring—
diffApprovalDiffLine[]—
classNamestring—

When to use the agent run

Use the agent run card to show one run in progress: a live status and timer, a progress line, and tool-call steps that spin, tick off and expand to show output.

  • Open the CLI tab on any preview above for the exact shadcn command. The source is copied into your project, so you can edit it like any other file.

Suggested components