Getting Started
Components
- Agent Status
- Agent Template Card
- API Key Card
- Audio Player
- Bar Visualizer
- Channel Status Card
- Chat Composer
- Code Editor
- Condition Builder
- Confirm Dialog
- Conversation
- Conversation Bar
- Dataset Card
- Document Status Badge
- Extraction Strategy Select
- File Icon
- File Upload
- Indexing Progress
- Live Waveform
- Matrix
- Message
- Mic Selector
- Model Diff View
- Model Selector
- Model Type Filter
- Node Catalog
- Option Editor
- Orb
- Output Variables View
- Package Card
- Prompt Editor
- Provider Status Card
- Radio Card
- Resource Card
- Resource Sidebar
- Response
- Run Node List
- Scrub Bar
- Segment Card
- Shimmering Text
- Speech Input
- Token Trend Chart
- Tool Call Card
- Transcript Viewer
- Usage Stat Card
- Variable Binding Editor
- Variable Selector
- Voice Button
- Voice Picker
- Waveform
- Workflow Node Card
- Workspace Selector
Planning next step
ZGI Agent ProReviewing transcript context before deciding whether to call a tool.
824 ms
IdleListeningSpeakingRunning toolCompleteError
"use client"
import { AgentStatus } from "@/components/ui/agent-status"
export function AgentStatusDemo() {
return (
<div className="w-full max-w-xl space-y-3">
<AgentStatus
state="thinking"
variant="panel"
label="Planning next step"
description="Reviewing transcript context before deciding whether to call a tool."
model="ZGI Agent Pro"
latency="824 ms"
/>
<div className="flex flex-wrap gap-2">
<AgentStatus state="idle" />
<AgentStatus state="listening" />
<AgentStatus state="speaking" />
<AgentStatus state="tool" />
<AgentStatus state="complete" />
<AgentStatus state="error" />
</div>
</div>
)
}
Installation
pnpm dlx shadcn@latest add https://ui.zgi.ai/r/agent-status.jsonpnpm dlx shadcn@latest add https://ui.zgi.ai/r/agent-status.json
yarn dlx shadcn@latest add https://ui.zgi.ai/r/agent-status.jsonComponent
"use client"
import * as React from "react"
import {
AlertCircleIcon,
CheckCircle2Icon,
CircleIcon,
Loader2Icon,
MicIcon,
PauseCircleIcon,
RadioIcon,
Volume2Icon,
WrenchIcon,
} from "lucide-react"
import { cn } from "@/lib/utils"
import { Badge } from "@/components/ui/badge"
export type AgentStatusState =
| "idle"
| "listening"
| "thinking"
| "speaking"
| "tool"
| "paused"
| "complete"
| "error"
export interface AgentStatusProps extends React.ComponentProps<"div"> {
state: AgentStatusState
label?: React.ReactNode
description?: React.ReactNode
latency?: React.ReactNode
model?: React.ReactNode
variant?: "badge" | "panel"
showPulse?: boolean
}
const statusConfig: Record<
AgentStatusState,
{
label: string
icon: React.ComponentType<{ className?: string }>
className: string
active?: boolean
}
> = {
idle: {
label: "Idle",
icon: CircleIcon,
className: "bg-muted text-muted-foreground border-border",
},
listening: {
label: "Listening",
icon: MicIcon,
className:
"border-blue-500/20 bg-blue-500/10 text-blue-700 dark:text-blue-300",
active: true,
},
thinking: {
label: "Thinking",
icon: Loader2Icon,
className:
"border-violet-500/20 bg-violet-500/10 text-violet-700 dark:text-violet-300",
active: true,
},
speaking: {
label: "Speaking",
icon: Volume2Icon,
className:
"border-emerald-500/20 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
active: true,
},
tool: {
label: "Running tool",
icon: WrenchIcon,
className:
"border-amber-500/25 bg-amber-500/10 text-amber-700 dark:text-amber-300",
active: true,
},
paused: {
label: "Paused",
icon: PauseCircleIcon,
className:
"border-slate-500/20 bg-slate-500/10 text-slate-700 dark:text-slate-300",
},
complete: {
label: "Complete",
icon: CheckCircle2Icon,
className:
"border-emerald-500/20 bg-emerald-500/10 text-emerald-700 dark:text-emerald-300",
},
error: {
label: "Error",
icon: AlertCircleIcon,
className: "border-destructive/20 bg-destructive/10 text-destructive",
},
}
export function AgentStatus({
state,
label,
description,
latency,
model,
variant = "badge",
showPulse = true,
className,
...props
}: AgentStatusProps) {
const config = statusConfig[state]
const Icon = config.icon
const content = label ?? config.label
if (variant === "badge") {
return (
<Badge
variant="outline"
className={cn(
"h-7 gap-1.5 rounded-md px-2.5 font-medium",
config.className,
className
)}
{...props}
>
<Icon
className={cn(
"size-3.5",
state === "thinking" && "animate-spin",
config.active &&
showPulse &&
state !== "thinking" &&
"animate-pulse"
)}
/>
{content}
</Badge>
)
}
return (
<div
className={cn(
"border-border bg-card text-card-foreground flex w-full items-center gap-3 rounded-lg border p-3 shadow-sm",
className
)}
{...props}
>
<div
className={cn(
"flex size-9 shrink-0 items-center justify-center rounded-md border",
config.className
)}
>
<Icon
className={cn(
"size-4",
state === "thinking" && "animate-spin",
config.active &&
showPulse &&
state !== "thinking" &&
"animate-pulse"
)}
/>
</div>
<div className="min-w-0 flex-1">
<div className="flex min-w-0 items-center gap-2">
<p className="truncate text-sm font-medium">{content}</p>
{model ? (
<span className="text-muted-foreground truncate text-xs">
{model}
</span>
) : null}
</div>
{description ? (
<p className="text-muted-foreground mt-0.5 line-clamp-2 text-xs leading-5">
{description}
</p>
) : null}
</div>
{latency ? (
<div className="text-muted-foreground shrink-0 text-xs">{latency}</div>
) : null}
<RadioIcon className="text-muted-foreground size-4 shrink-0" />
</div>
)
}
Usage
import { AgentStatus } from "@/components/ui/agent-status"
export function Example() {
return (
<AgentStatus
state="thinking"
variant="panel"
label="Planning next step"
description="Reviewing transcript context before calling a tool."
model="ZGI Agent Pro"
latency="824 ms"
/>
)
}Props
| Prop | Type | Default |
|---|---|---|
| state | AgentStatusState | required |
| variant | "badge" | "panel" | "badge" |
| label | ReactNode | state label |
| description | ReactNode | - |
| model | ReactNode | - |
| latency | ReactNode | - |
| showPulse | boolean | true |
Deploy and Scale Agents with ZGI
ZGI delivers the infrastructure and developer experience you need to ship reliable audio & agent applications at scale.
Talk to an expert