66 / 122 · Agents
Agent card
Who you are about to talk to: its skills, its model, and the endpoint behind it.
Maintainerv1.4.0assistant-ui
Works through the issue queue: reproduces the report, writes the fix, and opens the PR.
triageRead an issue and label it
reproBuild a minimal reproduction
patchOpen a PR with the fix
https://agents.example.com/a2aopus
Installation
npx shadcn@latest add "@assistant-ui/elements-agent-card"
Usage
import { AgentCard } from "@/components/elements/agent-card";
<AgentCard
name="Maintainer"
description="Reproduces the report, writes the fix, opens the PR."
provider="assistant-ui"
version="1.4.0"
model="opus"
endpoint="https://agents.example.com/a2a"
skills={skills}
connected={false}
onConnect={connect}
/>Props
name*stringDisplay name of the agent.
description*stringWhat it does, in one or two sentences.
provider*stringWho publishes it.
version*stringCard version, printed next to the name.
model*stringModel the agent runs on.
endpoint*stringWhere it is reached. Truncates rather than wraps.
skills*AgentSkill[]Named capabilities the card advertises.
connected*booleanSwaps the action for a settled Connected state and disables it.
onConnect() => voidCalled when the agent is added.
classNamestringExtra classes merged onto the root.
Source
agent-card.tsx"use client";
import { BotIcon, CheckIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { field, inkButton, mono, paper } from "./surfaces";
export interface AgentSkill {
name: string;
description: string;
}
export function AgentCard({
name,
description,
provider,
version,
model,
endpoint,
skills,
connected,
onConnect,
className,
}: {
name: string;
description: string;
provider: string;
version: string;
model: string;
endpoint: string;
skills: readonly AgentSkill[];
connected: boolean;
onConnect?: () => void;
className?: string;
}) {
return (
<div
className={cn(
paper,
"flex w-full max-w-sm flex-col gap-3.5 rounded-[20px] p-4",
className,
)}
>
<div className="flex items-start gap-3">
<span className="bg-foreground/[0.05] text-foreground/45 flex size-9 shrink-0 items-center justify-center rounded-xl">
<BotIcon className="size-4" />
</span>
<div className="flex min-w-0 flex-1 flex-col">
<span className="flex items-baseline gap-2">
<span className="truncate text-[13.5px] font-medium">{name}</span>
<span className={cn(mono, "text-foreground/30 shrink-0")}>
v{version}
</span>
</span>
<span className="text-foreground/45 truncate text-xs">
{provider}
</span>
</div>
</div>
<p className="text-foreground/60 text-xs leading-relaxed">
{description}
</p>
<div className="flex flex-col gap-1.5">
{skills.map((skill) => (
<div key={skill.name} className="flex items-baseline gap-2">
<span
className={cn(
field,
mono,
"text-foreground/55 shrink-0 rounded-md px-1.5 py-0.5",
)}
>
{skill.name}
</span>
<span className="text-foreground/45 min-w-0 flex-1 truncate text-xs">
{skill.description}
</span>
</div>
))}
</div>
<div className="border-foreground/[0.07] flex items-center gap-2 border-t pt-3">
<span
className={cn(mono, "text-foreground/30 min-w-0 flex-1 truncate")}
>
{endpoint}
</span>
<span className={cn(mono, "text-foreground/30 shrink-0")}>{model}</span>
</div>
<button
type="button"
onClick={onConnect}
disabled={connected}
className={cn(
connected
? cn(field, "text-foreground/55")
: cn(inkButton, "justify-center"),
"flex h-8 items-center justify-center gap-1.5 rounded-full px-3.5 text-xs font-medium disabled:pointer-events-none",
)}
>
{connected ? (
<>
<CheckIcon className="size-3.5 text-emerald-500" />
Connected
</>
) : (
"Connect"
)}
</button>
</div>
);
}