Skip to content
Mizen UI
Docs

IntroductionInstallationCLIStylingFoundationsThemingCompositionIntegrationsAccessibilityFor agents

useCopyToClipboard

AccordionAspect RatioCardCollapsibleFrameGridGroupInlineScroll AreaSectionSeparatorSpacerStack

BlockquoteCitationCodeHeadingKbdLabelLinkTextVisually Hidden

ButtonButton GroupToggleToggle groupToolbar

CalendarCheckboxCheckbox groupComboboxDate pickerDate range pickerDate-Time InputFieldFieldsetFile UploadFormInputInput groupNumber fieldOTP FieldRadio groupSelectSliderSwitchTextareaTime Input

BreadcrumbMenubarNavigation MenuPaginationSegmented ControlStepperTabs

Alert dialogCommandContext MenuDialogDrawerMenuPopoverPreview CardSheetTooltip

AlertBadgeEmptyError StateMeterProgressSkeletonSpinnerStatus dotToast

Activity FeedAvatarAvatar GroupData TableListMetricOverflow ListProperty ListTableTokenTree

Area ChartBar ListCalendar HeatmapCategory ComparisonChart FrameChart LegendChart TooltipDistributionFunnelHeatmapMetric TrendPart-to-WholeProgress RingsRadar ChartRadial BarsSankey ChartScatter ChartScore GaugeTime Series

Diagram

AttachmentCarouselCode BlockLightboxMarkdownThumbnailTimestamp

Agent ThinkingApproval CardComposerConversationInline CitationMessageMessage ScrollerQuestion CardSourcesStreaming TextSuggestionTask ListTerminalTool Call

On this page

  • Preview
  • Usage
  • With the AI SDK
  • With TanStack AI
  • Examples
  • Answered
  • Recommendations
  • Usage boundaries
  • API reference

Agentic

Approval Card

The agent asks before it acts: what it will do, why, and the details, with Deny and Approve. Denying can tell the agent what to do instead, and a decision folds into one line.

idle

Usage

import { ApprovalCard } from "@mizen-labs/ui";

With the AI SDK

Show the card while a tool part is approval-requested. A note given with a denial reaches the model as its reason. Decisions made by a rule arrive with isAutomatic set.

import { useChat } from "@ai-sdk/react";
import { ApprovalCard } from "@mizen-labs/ui";

// Render a tool part that waits for approval, or one that was decided.
export function ToolApproval({ part }: { part: ToolPart }) {
	const { addToolApprovalResponse } = useChat();
	if (part.state === "approval-requested" && !part.approval.isAutomatic) {
		return (
			<ApprovalCard
				description={part.approval.requestReason}
				details={[{ label: "Command", value: part.input.command }]}
				onApprove={() =>
					addToolApprovalResponse({ approved: true, id: part.approval.id })
				}
				// A note reaches the model with the denial.
				onDeny={({ note }) =>
					addToolApprovalResponse({
						approved: false,
						id: part.approval.id,
						reason: note,
					})
				}
				status="pending"
				title={`Run ${part.input.command}`}
			/>
		);
	}
	if (part.approval?.approved === undefined) return null;
	return (
		<ApprovalCard
			automatic={part.approval.isAutomatic}
			note={part.approval.reason}
			status={part.approval.approved ? "approved" : "denied"}
			title={`Run ${part.input.command}`}
		/>
	);
}

With TanStack AI

tool-call parts in the approval-requested state carry the input. Pass the person's answer to your app's handler.

import { ApprovalCard } from "@mizen-labs/ui";

// part is a tool-call part in the approval-requested state. The docs do not
// show how to answer it, so pass your app's handler.
export function ToolApproval({ part, respond }: { part: { input: { command: string } }; respond: (approved: boolean, note?: string) => void }) {
	return (
		<ApprovalCard
			onApprove={() => respond(true)}
			onDeny={({ note }) => respond(false, note)}
			status="pending"
			title={`Run ${part.input.command}`}
		/>
	);
}

Examples

Answered

A decision a rule made, and a denial with the person's note for the agent.

Recommendations

GuidancePractice
Do

Name the action in the title as a verb phrase, say why in the description, and list what will happen in details. Pass a denial's note to the agent so it can change course.

Usage boundaries

GuidanceBoundary
Scope

The application runs the action and stores the decision. Approval Card only reports Approve, Deny, the note, and Always allow.

Scope

Use it for actions that are hard to undo, such as sending, deleting, or paying. For a tool call already on screen, Tool Call asks inline.

API reference

Public props from @mizen-labs/ui. Use exported prop types for the complete TypeScript contract.

PropTypeDefaultDescription
titlestring—The action the agent asks to take, such as Send the October newsletter. It names the card.
status"pending" | "approved" | "denied"—pending shows Deny and Approve; approved and denied fold the card into one line that opens to what was asked.
description / detailsstring / readonly { label: string; value: ReactNode }[]—Why the agent asks, such as the AI SDK's requestReason, and label and value rows for what will happen.
onApprove / onDeny({ always }) => void / ({ note? }) => void—Called with the person's choice. Deny first asks what the agent should do instead; the note is optional and comes back as note.
allowAlwaysbooleanfalseShows Always allow this action. Your app remembers the choice and stops asking.
automatic / noteboolean / stringfalseThe decision came from a rule, shown as Approved automatically. note shows the reason given with a decision.
PreviousAgent ThinkingNextComposer

Needs your approval

Send the October newsletter

It goes to everyone on the list and can't be unsent.

To
Product updates · 42 people
Subject
What's new in October
Send
Today, 9:00 AM
Approved automatically: Read your calendar for next week
Denied: Delete the build folder