专注讲解如何使用 useXChat Hook,包括自定义 Provider 的集成、消息管理、错误处理、多会话管理等
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when building AI-driven UIs with @ant-design/x-card — covers XCard.Box, XCard.Card, A2UI v0.9 commands, data binding, catalogs, actions, and streaming patterns.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
설치 방법 보기설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.
This skill covers @ant-design/x-card — the React implementation of the A2UI protocol, enabling AI agents to dynamically render rich interactive UIs through structured JSON command streams.
It covers:
XCard.Box + XCard.Card component usagecreateSurface, updateComponents, updateDataModel, deleteSurfaceScope: v0.9 is the recommended protocol. v0.8 is supported for backward compatibility only — prefer v0.9 for all new work.
| Package | Responsibility |
|---|---|
@ant-design/x-card | React renderer for A2UI protocol — XCard.Box, XCard.Card, catalog APIs |
@ant-design/x | Chat UI components (Bubble, Sender, etc.) — not covered here |
@ant-design/x-sdk | Data providers, streaming — not covered here |
npm install @ant-design/x-card
Exports:
import {
XCard,
registerCatalog,
loadCatalog,
validateComponent,
clearCatalogCache,
} from '@ant-design/x-card';
import type {
XAgentCommand_v0_9,
XAgentCommand_v0_8,
ActionPayload,
Catalog,
CatalogComponent,
} from '@ant-design/x-card';
// Subcomponents
XCard.Box; // Container: receives commands, owns catalog maps
XCard.Card; // Renderer: renders a single surface by id
XCard.Box
├── owns: catalogMap, surfaceCatalogMap
├── dispatches: commands → all XCard.Card children
├── aggregates: onAction events from all Cards
└── XCard.Card (id="surface-a")
│ ├── owns: component tree, data model, commandVersion
│ └── resolves: data bindings, triggers actions
└── XCard.Card (id="surface-b")
└── ...
interface BoxProps {
commands?: (XAgentCommand_v0_9 | XAgentCommand_v0_8)[];
/** Component names must start with an uppercase letter (React component convention) */
components?: Record<string, React.ComponentType<any>>;
onAction?: (payload: ActionPayload) => void;
children?: React.ReactNode; // Should contain XCard.Card elements
}
interface CardProps {
id: string; // surfaceId to render
}
interface ActionPayload {
name: string; // from action.event.name
surfaceId: string; // which surface triggered it
/**
* Context passed by component, with path references automatically resolved.
*
* For action.event.context fields using { path: "xxx" } format:
* - X-Card automatically resolves them to { value: "actual_value" }
* - Other properties (like label) are preserved
*
* Example input config:
* { username: { path: "/form/username", label: "用户名" } }
*
* Example resolved context:
* { username: { value: "张三", label: "用户名" } }
*/
context: Record<string, any>;
}
| If you need to... | Read first |
|---|---|
| Set up XCard.Box + XCard.Card | USAGE.md → Basic Setup |
| Send commands from agent to card | COMMANDS.md |
| Register a custom component catalog | CATALOG.md → Local Catalog |
| Bind component props to live data | DATA_BINDING.md |
| Handle user interactions / form submit | ACTIONS.md |
| Build a streaming progressive UI | USAGE.md → Streaming |
| Migrate from v0.8 to v0.9 | COMMANDS.md → v0.8 vs v0.9 |
| Look up full prop types | API.md |
XCard.Box components prop.XCard.Box, add XCard.Card per surface.XAgentCommand_v0_9[] into commands prop (typically from streaming agent response).ActionPayload in onAction, update commands in response.import React, { useState } from 'react';
import { XCard, registerCatalog } from '@ant-design/x-card';
import type { XAgentCommand_v0_9, ActionPayload, Catalog } from '@ant-design/x-card';
// 1. Define and register local catalog
const myCatalog: Catalog = {
catalogId: 'local://my_catalog.json',
components: {
Text: {
type: 'object',
properties: { text: { type: 'string' }, variant: { type: 'string' } },
required: ['text'],
},
Button: {
type: 'object',
properties: { text: { type: 'string' }, action: {} },
required: ['text'],
},
},
};
registerCatalog(myCatalog);
// 2. Custom component implementations
const Text: React.FC<{ text: string; variant?: string }> = ({ text, variant }) => (
<p className={`text-${variant ?? 'body'}`}>{text}</p>
);
const Button: React.FC<{ text: string; onAction?: (ctx: any) => void; action?: any }> = ({
text,
onAction,
action,
}) => <button onClick={() => onAction?.(action?.event?.context ?? {})}>{text}</button>;
// 3. Build commands (from agent stream)
const commands: XAgentCommand_v0_9[] = [
{
version: 'v0.9',
createSurface: {
surfaceId: 'welcome',
catalogId: 'local://my_catalog.json',
},
},
{
version: 'v0.9',
updateComponents: {
surfaceId: 'welcome',
components: [
{ id: 'root', component: 'Column', children: ['title', 'btn'] },
{ id: 'title', component: 'Text', text: { path: '/user/name' }, variant: 'h1' },
{
id: 'btn',
component: 'Button',
text: 'Start',
action: { event: { name: 'start', context: {} } },
},
],
},
},
{
version: 'v0.9',
updateDataModel: {
surfaceId: 'welcome',
path: '/user/name',
value: 'Alice',
},
},
];
// 4. Render
export default function App() {
const [cmdQueue, setCmdQueue] = useState<XAgentCommand_v0_9[]>(commands);
const handleAction = (payload: ActionPayload) => {
console.log('Action:', payload.name, payload.context);
// Append new commands based on agent response
setCmdQueue((prev) => [...prev /* new commands */]);
};
return (
<XCard.Box commands={cmdQueue} components={{ Text, Button }} onAction={handleAction}>
<XCard.Card id="welcome" />
</XCard.Box>
);
}
"version": "v0.9" on every command — omitting it causes protocol rejection.id: "root" component per surface's component tree — this is the tree root.id string.updateComponents for layout, updateDataModel for content/state.registerCatalog() before the component tree renders.components map to XCard.Box, not to XCard.Card — Box distributes to all Cards.components object inline — keep it stable with useMemo or module-level constant to avoid re-renders.value: { path: "..." } for two-way binding — literal values do not update the data model.action.event.context paths are write targets — they point to where user-entered data lives in the data model; do not resolve them as read sources.{ path: "xxx" } in the action config to { value: "actual_value" } in the onAction payload. This works for both v0.9 (action.event.context = { key: { path } }) and v0.8 (action.context = [{ key, value: { path } }]) formats.| Scenario | Skill combination |
|---|---|
| AI chat with structured card responses | use-x-chat + x-components + x-card |
| Standalone agent form UI | x-card only |
| Streaming Markdown + card side-panel | x-markdown + x-card |
| HTTP streaming from agent into card | x-request → feed response as commands |
아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.
로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.
아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.
专注讲解如何使用 useXChat Hook,包括自定义 Provider 的集成、消息管理、错误处理、多会话管理等
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Focus on explaining how to use the useXChat Hook, including custom Provider integration, message management, error handling, multi-conversation management, and more
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
当需要用 @ant-design/x-card 让 AI Agent 动态渲染富交互 UI 时使用——涵盖 XCard.Box、XCard.Card、A2UI v0.9 命令、数据绑定、Catalog、Actions 和流式渲染模式。
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Focus on implementing custom Chat Provider, helping to adapt any streaming interface to Ant Design X standard format
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
专注于自定义 Chat Provider 的实现,帮助将任意流式接口适配为 Ant Design X 标准格式
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.
Use when building AI chat UIs with @ant-design/x components — covers Bubble, Sender, Conversations, Prompts, ThoughtChain, Actions, Welcome, Attachments, Sources, Suggestion, Think, FileCard, CodeHighlighter, Mermaid, Folder, XProvider, and Notification.
한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.