@a2ui/react

中文文档
0.15.0发布于 2026/11/02Apache-2.0TypeScriptESM + CJS近 30 天下载 65.4万

A2UI (代理对用户接口) 的反相渲染器

中文使用文档
文档目录29 节
  1. 特征
  2. 安装
  3. 协议版本
  4. 快速启动
  5. 定义自定义组件
  6. 1. 界定组成部分API
  7. 2. 创建反应执行
  8. 一般宾德特征
  9. 无铜元件
  10. 定义目录和函数
  11. 基本目录组件
  12. 输入 Text
  13. 造型和CSS模块
  14. 遗产支助(v0.8)
  15. 导入和使用
  16. 密钥差异( v0. 8 vs v
  17. 警卫
  18. 发展
  19. 设置
  20. 构建
  21. 类型检查
  22. 林特
  23. 测试
  24. 单位测试
  25. 视觉对等测试
  26. 运行视觉对等测试
  27. 快速命令
  28. 文档
  29. 关键概念

@ a2ui/ 反应

A2UI(代理对用户界面)的反相渲染器 - 允许AI代理 通过声明式的JSON生成丰富的交互式用户界面.

特征

  • v0.9 土著: 专门为A2UI v0.9协议所建造,并有更好的模块性和类型安全性.
  • 深度反应:由A2UI通用Binder提供动力,用于自动,精细的更新.
  • 强键:从Zod schemas中推导出的财产类型确保了编译时的安全.
  • 广泛: 容易定义自定义组件目录和逻辑函数.
  • 多面质: 内建支持管理独立的UI表面.

安装

yarn add @a2ui/react @a2ui/web_core

协议版本

A2UI支持多个协议版本以确保后向相容. 对于新项目,建议使用 页:1 协议.

要使用 v0. 9 执行, 从版本路径导入 :

import {A2uiSurface} from '@a2ui/react/v0_9';
import {basicCatalog} from '@a2ui/web_core/v0_9/basic_catalog';

快速启动

反应渲染器与 MessageProcessor 从 @a2ui/web_core. 处理器从一个AI代理解析出JSON消息,并管理由此产生的UI状态. 核心概念是:

  • 处理器 ——接收和解读代理消息.
  • 表面 ——一个独立渲染区域,由字符串ID独有地识别出,由代理创建并配有组件.
  • 目录 ——一组组件(如. Text, (中文(简体) ), Column, (中文(简体) ), Button供表面使用.

下面的例子创建一个处理器,其中包含 basicCatalog 从 @a2ui/web_core,输入一系列被硬编码的信息,使产生的表面.

import {useState, useEffect} from 'react';
import {MessageProcessor} from '@a2ui/web_core/v0_9';
import {basicCatalog} from '@a2ui/web_core/v0_9/basic_catalog';
import {A2uiSurface} from '@a2ui/react/v0_9';

export default function App() {
  // 1. Create the processor and feed it messages.
  const [processor] = useState(() => {
    const p = new MessageProcessor([basicCatalog]);
    p.processMessages(sampleAgentMessages);
    return p;
  });

  // 2. Set up listeners to keep the UI up to date as messages arrive.
  const [surfaces, setSurfaces] = useState(() => Array.from(processor.model.surfacesMap.values()));
  useEffect(() => {
    const sync = () => setSurfaces(Array.from(processor.model.surfacesMap.values()));

    const createdSub = processor.onSurfaceCreated(sync);
    const deletedSub = processor.onSurfaceDeleted(sync);

    return () => {
      createdSub.unsubscribe();
      deletedSub.unsubscribe();
    };
  }, [processor]);

  // 3. Render every surface the agent has created.
  return (
    <div className="a2ui-container">
      {surfaces.length === 0 && <div>Waiting for agent...</div>}
      {surfaces.map(surface => (
        <A2uiSurface key={surface.id} surface={surface} />
      ))}
    </div>
  );
}

// In a real app, these messages would come from an agent via WebSocket, SSE, etc.
// Here we hardcode them to show the message format.
const sampleAgentMessages = [
  {
    version: 'v0.9' as const,
    createSurface: {surfaceId: 'main-chat', catalogId: basicCatalog.id},
  },
  {
    version: 'v0.9' as const,
    updateComponents: {
      surfaceId: 'main-chat',
      components: [
        {id: 'root', component: 'Column', children: ['greeting', 'description']},
        {id: 'greeting', component: 'Text', text: {path: '/title'}},
        {id: 'description', component: 'Text', text: {path: '/body'}},
      ],
    },
  },
  {
    version: 'v0.9' as const,
    updateDataModel: {
      surfaceId: 'main-chat',
      path: '/',
      value: {
        title: 'Hello from A2UI!',
        body: 'Replace these messages with real agent responses to build interactive UIs.',
      },
    },
  },
];

运行此示例应显示“ 来自 A2UI! ” 。 这个例子显示了三种信息类型:

定义自定义组件

A2UI v0.9 严格将组件的API(Schema)与其执行相分离.

1. 界定组成部分API

使用 Zod 定义属性 。 使用 CommonSchemas 从 web_core 允许自动装入 A2UI 原始文件 .

import {z} from 'zod';
import {CommonSchemas} from '@a2ui/web_core/v0_9';

export const MyProfileApi = {
  name: 'Profile',
  schema: z.object({
    username: CommonSchemas.DynamicString, // Can be literal "Alice" or {path: "/user/name"}
    bio: CommonSchemas.DynamicString,
    avatarUrl: CommonSchemas.DynamicString,
    onEdit: CommonSchemas.Action, // Resolves to a clickable () => void
    isEditable: CommonSchemas.DynamicBoolean,
    // Add 'checks' if you want validation support (standard in v0.9 interactive components)
    checks: CommonSchemas.Checkable.shape.checks,
  }),
};

API也可以限制组件出现的地方,使用 allowedParents 财务报告和审定财务报表 allowedChildren 组件名称列表。 消息处理器然后拒绝将组件置于另一个母体之下的有效载荷 UNALLOWED_PARENT,或者给它一个与 UNALLOWED_CHILD中。根组件的父为 Surface。仅以 CommonSchemas.ComponentId 或者说 CommonSchemas.ChildList 抱着孩子,在平地上 z.string() 不检查属性 allowedChildren。 。 。 .

2. 创建反应执行

这个 createComponentImplementation 工厂使用 普通宾德 在组件生成前解决所有动态值.

import {createComponentImplementation} from '@a2ui/react/v0_9';

export const MyProfile = createComponentImplementation(MyProfileApi, ({props, buildChild}) => {
  // 'props' is strictly inferred from the Zod schema:
  // props.username is 'string' (resolved from DynamicString)
  // props.onEdit is '() => void' (resolved from Action)

  return (
    <div className="profile-widget">
      <img src={props.avatarUrl ?? ''} alt={props.username} />
      <h2>{props.username}</h2>
      <p>{props.bio}</p>

      {props.isEditable && (
        <button onClick={props.onEdit} disabled={props.isValid === false}>
          Edit Profile
        </button>
      )}

      {/* Render validation errors if any check fails */}
      {props.validationErrors?.map((err, i) => (
        <div key={i} className="error-hint" style={{color: 'red'}}>
          {err}
        </div>
      ))}
    </div>
  );
});

一般宾德特征

通用Binder是一款框架不可知引擎,将生JSON有效载荷配置转化为由强型道具组成的有凝聚力的反应流.

  • 自动解析属性: DynamicString, (中文(简体) ), DynamicNumber,以及 DynamicBoolean 自动解为当前值(字符串、数字、布尔值).
  • 双向绑定: 如果一个计划使用动态类型( 如 DynamicString),绑定器会自动注入设置器。 为了财产 username,它补充 props.setUsername(val: string),它更新了基础数据模型.
  • 行动背景数字 : Action 属性被解为即时调用功能。 当被调用时,它们会在通知服务器前自动解析其深层上下文绑定(如从模型中收集形式数据).
  • 嵌入值:列表和对象是逐项解决的,所以一个动作,绑定或列表内的孩子列表会像在顶层解决一样,其道具会这样打入.
  • 反应验证:如果您的计划包含 checks,绑定器反应性地评估规则并注入 props.isValid 财务报告和审定财务报表 props.validationErrors 基于逻辑函数的结果.

无铜元件

用于高级使用时需要直接访问 ComponentContext 或想要手动管理反应(例如,用于性能关键动画),使用 createBinderlessComponentImplementation。 。 。 .

import {createBinderlessComponentImplementation} from '@a2ui/react/v0_9';

export const RawInspector = createBinderlessComponentImplementation(InspectorApi, ({context}) => {
  // Access the raw, unresolved component model and the data model directly
  const rawData = context.componentModel.properties;
  const componentId = context.componentModel.id;

  return (
    <details>
      <summary>Raw Component State (ID: {componentId})</summary>
      <pre>{JSON.stringify(rawData, null, 2)}</pre>
    </details>
  );
});

定义目录和函数

将您的组件和逻辑函数分组为 Catalog 用于: MessageProcessor。 。 。 .

import {Catalog, createFunctionImplementation} from '@a2ui/web_core/v0_9';
import {z} from 'zod';

// 1. Implement a custom logic function
const myCheckFunc = createFunctionImplementation(
  {
    name: 'is_admin',
    returnType: 'boolean',
    schema: z.object({role: z.string()}),
  },
  args => args.role === 'admin',
);

// 2. Compose the catalog
export const myCatalog = new Catalog(
  'https://example.com/catalogs/v1.json',
  'v0.9', // Protocol version the catalog targets
  [MyProfile, RawInspector], // List of ReactComponentImplementation
  [myCheckFunc], // List of FunctionImplementation
);

基本目录组件

@a2ui/web_core/v0_9/basic_catalog 页:1 basicCatalog 带有标准组件。 它们是W3C自定义元素,反应渲染器使它们成为元素:

  • 版式数字 : Row, (中文(简体) ), Column, (中文(简体) ), List, (中文(简体) ), Card, (中文(简体) ), Tabs, (中文(简体) ), Modal, (中文(简体) ), Divider
  • 内容数字 : Text, (中文(简体) ), Image, (中文(简体) ), Icon, (中文(简体) ), Video, (中文(简体) ), AudioPlayer
  • 投入数字 : Button, (中文(简体) ), TextField, (中文(简体) ), CheckBox, (中文(简体) ), ChoicePicker, (中文(简体) ), Slider, (中文(简体) ), DateTimeInput

输入 Text

Text 由应用程序提供的渲染器来制作它 给 MarkdownContext 一个返回 HTML 的函数,例如来自 @a2ui/markdown-it,或给予 MarkdownComponentContext a 反应组件:

import {A2uiSurface, MarkdownComponentContext} from '@a2ui/react/v0_9';

const ChatMarkdown = ({markdown}: {markdown: string}) => <Markdown text={markdown} />;

<MarkdownComponentContext.Provider value={ChatMarkdown}>
  <A2uiSurface surface={surface} />
</MarkdownComponentContext.Provider>;

组件在其中 Text,作为应用的回放树的一部分,所以它读取了应用的上下文. 当两者都给出时,则使用组件. Text 读取整个页面的 Markdown 渲染器, 将组件给每个 A2uiSurface 页面或无.

造型和CSS模块

基本目录组件是自成一体的,并使用暴露于 @a2ui/web_core。 。 。 .

您可以使用 CSS 模块来设计您的自定义组件 。 大多数现代反应环境(如Vite,Next.js,和Create React App)都支持出框. 必须配置自定义的构建设置来处理 .module.css 文档,例如 css-loader 在 Webpack 中启用模块.

/* MyComponent.module.css */
.myComponent {
  display: flex;
  gap: var(--a2ui-spacing-m, 8px);
}

/* Use :global to target nested elements (like those generated by Markdown) */
.myComponent :global(p) {
  color: var(--a2ui-color-on-background);
}
import styles from './MyComponent.module.css';

export const MyComponent = createComponentImplementation(MyComponentApi, ({props}) => {
  return <div className={styles.myComponent}>{/* ... */}</div>;
});

遗产支助(v0.8)

A2UI v0.8 为后向相容性维护. 虽然它仍然是默认导出 @a2ui/react 软件包,建议为类型安全绑定器和逻辑函数等新特性向v0.9过渡.

导入和使用

要使用 v0.8 渲染器,请使用 A2UIProvider 财务报告和审定财务报表 A2UIRenderer 组件 :

import {A2UIProvider, A2UIRenderer, injectStyles} from '@a2ui/react/v0_8';

// Inject v0.8 styles
injectStyles();

function LegacyApp() {
  const handleAction = msg => console.log('Action:', msg);

  return (
    <A2UIProvider onAction={handleAction}>
      {/* Renders the surface using v0.8 logic */}
      <A2UIRenderer surfaceId="main" />
    </A2UIProvider>
  );
}

密钥差异( v0. 8 vs v

特性v0.8 (语言)v0.9 (当前)
议定书用途 BeginRendering, (中文(简体) ), SurfaceUpdate。 。 。 .用途 createSurface, (中文(简体) ), updateComponents, (中文(简体) ), updateDataModel。 。 。 .
数据流动单向地表更新 .双向同步sendDataModel) (中文(简体) ).
类型安全通过 node.properties。 。 。 .强键 props 根据Zod计划推断.
逻辑有限客户端逻辑.广泛 Function 系统(例如, formatString, (中文(简体) ), required) (中文(简体) ).
反应基于虎克( C)useA2UIComponent) (中文(简体) ).自动通过 普通宾德 中间软件.
装订手工解析成组件正文.声明式双向绑定与注射定子.

在v0.8中,组件负责用钩子解决自身的动态值:

// v0.8 Manual Resolution
function TextField({node, surfaceId}) {
  const {resolveString, setValue} = useA2UIComponent(node, surfaceId);
  const label = resolveString(node.properties.label);
  // ...
}

在v0.9中,这是由 普通宾德 在组件甚至制作之前,生成更清洁的框架内置视图代码.

警卫

[大 提供的样本代码用于演示,并说明了A2UI的力学. 在建立生产应用程序时,关键是要将任何在您直接控制之外运作的代理商视为一个潜在的不信任实体.

外部代理机构提供的所有业务数据,包括其信息和UI定义,应作为不信任的投入处理。 恶意代理可能试图对合法接口进行套用来欺骗用户(fishing),通过属性值(XSS)来注入恶意脚本,或者产生过度的布局复杂来降低客户端性能(DoS). 如果您的应用程序支持可选的嵌入内容(如iframes或web视图),则必须额外注意防止被恶意外部网站曝光.

开发者责任:不能正确验证数据和严格地提供沙盒内容可能会造成严重的脆弱性。 开发者负责执行适当的安全措施——例如输入消毒、内容安全政策和确保证书处理——以保护他们的系统和用户.

发展

设置

# In the A2UI monorepo root
yarn install

构建

yarn build    # Build the package
yarn dev      # Watch mode

类型检查

yarn typecheck

林特

yarn lint

测试

单位测试

用途 维特 + 键 反应测试库。 。 。 .

yarn test              # Run once
yarn test:watch    # Watch mode

结构 : tests/ ├── setup.ts # Initializes component catalog ├── helpers.tsx # TestWrapper, TestRenderer, message creators └── components/ # Component tests (*.test.tsx)

示例 { tsx 导入{ 渲染、屏幕、 fireEvent} 从 '@ testing-library/ react'; 导入 { testWrapper, TestRender, 创建“./ 帮助者” 的简单消息;

它( 应该在点击时发出动作) , () { { const on Action = v.fn (); const 信件 = 创建 SimpleMessages ("btn 1","按钮",{子:"text-1",动作:{ 名称:“提交”},});

渲染( c) (三);

fireEvent.click(屏幕.getByRole ("按钮")) ; 期望( 关于行动 ) 。 要呼叫( ) ; ) ; @%%

视觉对等测试

React 渲染器与 Lit 渲染器保持视觉等同( 参考) (执行)。 综合测试套件比较像素完美截图 在两个制造器之间.

运行视觉对等测试

cd visual-parity
yarn test

快速命令

# Run all tests
yarn test

# Run specific component tests
yarn test --grep "button"

# Run with UI mode
yarn test:ui

# Start dev servers for manual inspection
yarn dev
# React: http://localhost:5001
# Lit: http://localhost:5002

文档

关键概念

  1. 结构镜像: 反应组件镜像 Lit 的阴影 DOM 结构
  2. CSS 选择器转换数字 : :host → .a2ui-surface .a2ui-{component}
  3. 特性匹配: 用途 :where() 以匹配 Lit 的低特异性

版本与发布记录

@a2ui/react 共发布 17 个版本,首次发布于 2026/03/18;过去 12 个月发布了 17 个版本。

版本发布日期距今
0.15.0latest2026/11/024 天前
0.14.02026/10/1720 天前
0.13.02026/10/1027 天前
0.12.02026/09/291 个月前
0.11.12026/09/121 个月前
0.11.02026/09/012 个月前

关于 @a2ui/react 的常见问题

@a2ui/react 是什么?

A2UI (代理对用户接口) 的反相渲染器

如何安装 @a2ui/react?

在项目目录运行 npm install @a2ui/react,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:zod(^3.25.76)、react(^18.0.0 || ^19.0.0)、react-dom(^18.0.0 || ^19.0.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@a2ui/react 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@a2ui/react 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@a2ui/react 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18.0.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@a2ui/react 可以商用吗?

@a2ui/react 使用 Apache-2.0 许可。宽松许可:允许商业使用、修改和再分发,并附带明确的专利授权;分发时需保留许可与 NOTICE 文件,修改过的文件要注明改动。以上为概括,不构成法律意见,请以许可原文为准。

@a2ui/react 的下载量有多少?

根据 npm 官方下载统计,@a2ui/react 在 2026/10/05 – 2026/11/03 这 30 天内被下载 653,562 次,日均约 21,785 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@a2ui/react 还在维护吗?

最新版本 0.15.0 发布于 2026/11/02(4 天前);至今共发布 17 个版本,其中过去 12 个月发布了 17 个;首次发布于 2026/03/18。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。