@assistant-ui/react-generative-ui

中文文档
0.1.7发布于 2026/10/28MITTypeScriptES Module构建来源已验证近 30 天下载 32.2万

Generative UI components for assistant-ui

原始使用文档
文档目录9 节
  1. Installation
  2. Usage
  3. Streaming props
  4. "use generative" authoring
  5. Slack, Teams, and A2UI
  6. @assistant-ui/react-generative-ui/slack
  7. @assistant-ui/react-generative-ui/teams
  8. @assistant-ui/react-generative-ui/a2ui
  9. License

@assistant-ui/react-generative-ui

This package re-exports @assistant-ui/generative-ui, the framework-neutral home of assistant-ui's generative UI. Existing imports keep working unchanged; new code should depend on @assistant-ui/generative-ui directly and import the React renderer from @assistant-ui/generative-ui/react.

Generative UI tools for assistant-ui.

Installation

npm install @assistant-ui/react-generative-ui

Usage

Declare the components the model is allowed to render in a library, then expose them through the present tool. The model emits a { _type, ...props } tree (_type names the component, so a real type prop never collides); the tool renders it against the library.

import { JSONGenerativeUI } from "@assistant-ui/react-generative-ui";
import { Thread, Tools } from "@assistant-ui/react";
import { z } from "zod";

const generativeUI = new JSONGenerativeUI({
  library: {
    Card: {
      description: "A card container with a title.",
      properties: z.object({ title: z.string() }),
      render: ({ title, children }) => (
        <section className="card">
          <h3>{title}</h3>
          {children}
        </section>
      ),
    },
    Text: {
      description: "A run of text.",
      properties: z.object({ tone: z.enum(["muted", "normal"]).optional() }),
      render: ({ tone, children }) => <p data-tone={tone}>{children}</p>,
    },
  },
});

const toolkit = {
  present: generativeUI.present(),
};

function App() {
  return (
    <Thread>
      <Tools toolkit={toolkit} />
      {/* MessageList, Composer, ... */}
    </Thread>
  );
}

A node's children prop is rendered recursively, so components can be nested:

{
  "_type": "Card",
  "title": "Hello",
  "children": [{ "_type": "Text", "tone": "muted", "children": "Nested text" }]
}

Streaming props

By default a component renders only once its props have fully arrived, so render always sees complete props. Opt into rendering from partial props with streamProperties. When you do, render receives an injected $status prop that discriminates the props: while "streaming" they are Partial, and once "done" they are complete.

const generativeUI = new JSONGenerativeUI({
  library: {
    Weather: {
      description: "A live weather card.",
      properties: z.object({ city: z.string(), temp: z.number() }),
      streamProperties: true,
      render: (props) => {
        if (props.$status === "done") {
          return <Card>{`${props.city}: ${props.temp}°`}</Card>; // complete props
        }
        return <Card>{props.city ?? "Loading…"}</Card>; // partial props
      },
    },
  },
});

render is a function of props, not a React component — but it runs on its own fiber, so you can call hooks inside it as usual.

"use generative" authoring

The examples above wire the library up by hand on the client. With the "use generative" compiler (@assistant-ui/next or @assistant-ui/vite) you can instead colocate a component's properties schema with its render and expose the library as tools, and the build splits each half to the right target: the schema goes to the server (so the model sees the tool), the render stays on the client.

"use generative";

import { z } from "zod";
import { Weather } from "@/components/weather";
import { defineToolkit } from "@assistant-ui/react";
import {
  JSONGenerativeUI,
  defineGenerativeComponents,
} from "@assistant-ui/react-generative-ui";

const generative = new JSONGenerativeUI({
  library: defineGenerativeComponents({
    Weather: {
      description: "Show a weather card.",
      properties: z.object({ city: z.string() }),
      render: (props) => <Weather {...props} />,
    },
  }),
});

export default defineToolkit({
  // `present` displays a component; `prompt_user` is a human-in-the-loop prompt.
  present: generative.present(),
  prompt_user: generative.promptUser(),
});

The model calls present with a node like { "_type": "Weather", "city": "SF" }. Pass present({ display: "standalone" }) to render the component on its own surface instead of inline. See the "use generative" docs for the build setup.

Slack, Teams, and A2UI

The same tree is plain JSON, so it is not tied to the browser. Three React-free subpaths convert it for Slack Block Kit, Microsoft Teams Adaptive Cards, and inbound A2UI surfaces. They run in server actions, queue workers, and webhook handlers. Conversion is over the built-in vocabulary; a $type outside it is dropped with a warning. What each target does with a component, and how unsupported content degrades, is documented on Generative UI on Slack, Generative UI on Microsoft Teams, and A2UI over AG-UI.

@assistant-ui/react-generative-ui/slack

Converts a tree to Slack Block Kit JSON (toSlackBlocks), decodes block_actions webhooks back into $action payloads (decodeBlockAction), and maps Block Kit back into vocabulary nodes (fromSlackBlocks).

import { toSlackBlocks } from "@assistant-ui/react-generative-ui/slack";

const { blocks, warnings } = toSlackBlocks({
  $type: "Card",
  title: "Order #48213",
  children: [{ $type: "Text", value: "Shipped, arriving Thursday." }],
});

@assistant-ui/react-generative-ui/teams

Converts a tree to a Microsoft Teams Adaptive Card (toAdaptiveCard) or bot-framework attachments with root-carousel support (toTeamsAttachments), and decodes an incoming activity.value (decodeSubmitData).

import { toAdaptiveCard } from "@assistant-ui/react-generative-ui/teams";

const { card, warnings } = toAdaptiveCard({
  $type: "Card",
  title: "Order #48213",
  children: [{ $type: "Text", value: "Shipped, arriving Thursday." }],
});

@assistant-ui/react-generative-ui/a2ui

The inbound direction: applies A2UI surface operations (applyA2uiOperations) and converts a surface into a vocabulary tree (convertSurfaceToUISpec) that renders through the same present path.

import {
  applyA2uiOperations,
  convertSurfaceToUISpec,
} from "@assistant-ui/react-generative-ui/a2ui";

const { state } = applyA2uiOperations(new Map(), operations);
for (const surface of state.values()) {
  const { spec, warnings } = convertSurfaceToUISpec(surface);
}

License

MIT

版本与发布记录

@assistant-ui/react-generative-ui 共发布 31 个版本,首次发布于 2026/06/05;过去 12 个月发布了 31 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.1.7latest2026/10/2810 天前
0.1.62026/10/2315 天前
0.1.52026/10/2018 天前
0.1.42026/10/1623 天前
0.1.32026/10/1325 天前
0.1.22026/10/1226 天前

关于 @assistant-ui/react-generative-ui 的常见问题

@assistant-ui/react-generative-ui 是什么?

Generative UI components for assistant-ui

如何安装 @assistant-ui/react-generative-ui?

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

@assistant-ui/react-generative-ui 支持 TypeScript 吗?

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

@assistant-ui/react-generative-ui 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@assistant-ui/react-generative-ui 可以商用吗?

@assistant-ui/react-generative-ui 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@assistant-ui/react-generative-ui 的下载量有多少?

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

@assistant-ui/react-generative-ui 还在维护吗?

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