К основному содержанию
скилл CX Codex

generative-ui · assistant-ui — скилл для Claude Code: интерфейсы из компонентов

Скилл для assistant-ui: модель собирает интерфейс из готовых компонентов во время ответа, а не заполняет заранее написанный вами.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add assistant-ui/skills --skill generative-ui -a claude-code
Открыть на GitHub

Что делает generative-ui

Обычная схема — один компонент на один вызов инструмента. Здесь наоборот: вы отдаёте словарь компонентов, а дерево из них собирает модель через инструмент present или ваш бэкенд через часть сообщения. Пакет @assistant-ui/generative-ui привозит 29 компонентов по умолчанию — карточки, таблицы, графики, формы — и конвертеры, которые превращают то же дерево в Slack Block Kit или Adaptive Card для Microsoft Teams.

Ставится двумя командами: npm install @assistant-ui/generative-ui zod и npx assistant-ui@latest add generative-ui. Дальше включаете компилятор "use generative" для своего фреймворка — в Next это withAui из @assistant-ui/next, в Vite и TanStack Start aui() из @assistant-ui/vite. Директива нужна потому, что один файл объявляет инструменты и для браузера, и для серверного роута: компилятор вырезает браузерную половину из серверной сборки, а схемы — из клиентской.

present — фронтенд-инструмент, он резолвится в браузере. Без sendAutomaticallyWhen интерфейс отрисуется, а разговор встанет до того, как модель скажет что-то ещё. Ещё момент: present и примитив MessagePrimitive.GenerativeUI оба принимают JSON-дерево, но формы у них разные и друг в друга не перекладываются. Если непонятное имя _type или компонента бросает ошибку либо молча рисует пустоту — это сюда. Для виджета под один конкретный вызов инструмента идите в скилл tool-ui.

Какие задачи решает

  • собрать дашборд из компонентов силами модели, а не верстать его вручную
  • починить пустой рендер при неизвестном имени компонента
  • отправить одну и ту же композицию в браузер и в Slack
  • показать Adaptive Card в Microsoft Teams из того же дерева
  • подключить A2UI-поверхность поверх AG-UI

Примеры запросов агенту

  • собери дашборд по метрикам за неделю через present
  • почему дерево с неизвестным _type рендерится пустым?
  • отправь эту карточку в Slack через Block Kit

Как установить generative-ui

1Через Skills CLI (Vercel)

npx skills add assistant-ui/skills --skill generative-ui -a claude-code

2Вручную: положить файлы

~/.claude/skills/generative-ui/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/generative-ui/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о generative-ui

Как установить generative-ui в Claude?

Сначала npx skills add assistant-ui/skills --skill generative-ui -a claude-code, затем проверьте, что файл появился по пути ~/.claude/skills/generative-ui/SKILL.md.

Что делает generative-ui?

Даёт модели словарь компонентов, из которого она собирает интерфейс во время ответа через инструмент present. Плюс конвертеры того же дерева в Slack Block Kit и Adaptive Card для Teams.

Чем это отличается от tool-ui?

tool-ui рисует виджет под один вызов инструмента, который вы уже знаете. generative-ui нужен, когда раскладку придумывает сама модель.

Исходный текст

SKILL.md · MIT
---
name: generative-ui
description: "Lets the model compose interfaces at runtime from a component vocabulary instead of one hand-written component per tool, and covers every generative UI pattern in the framework. Use for the model-driven present tool: JSONGenerativeUI, defaultGenerativeUILibrary, and present({ display }) from @assistant-ui/generative-ui/react, registered through AuiConfig({ tools: Tools({ toolkit }) }). Also covers the backend-driven MessagePrimitive.GenerativeUI primitive and its component allowlist, the Slack Block Kit and Microsoft Teams Adaptive Card renderers and their action decoders, A2UI surfaces over AG-UI, and the third-party OpenUI integration. Route here when the model should design its own layout rather than fill one you wrote, when an unknown _type or component name throws or silently renders nothing, or when a generative UI tree needs to post to Slack or Teams or paint an A2UI surface. For a widget tied to one tool call you already know about, use tool-ui in the tools skill instead."
license: MIT
---

# assistant-ui Generative UI

**Always consult [assistant-ui.com/llms.txt](https://www.assistant-ui.com/llms.txt) for the latest API.**

Generative UI inverts the usual tool-rendering relationship. Instead of one hand-written component per tool call, you ship a vocabulary of components and let something assemble a tree from it: either the model, through the `present` tool, or your backend, through a message part or a LangGraph event. `@assistant-ui/generative-ui` ships a default vocabulary of 29 components (cards, facts, tables, charts, forms, controls) plus converters that turn the same tree into Slack Block Kit or a Microsoft Teams Adaptive Card, and one that turns an A2UI surface into it, so a composition built once can render in the browser and outside it.

## References

- [./references/vocabulary.md](./references/vocabulary.md) -- the 29 default components and how to add your own with `defineGenerativeComponents`
- [./references/actions.md](./references/actions.md) -- `_action` dispatch, `createActionRegistry`, and the `$input` shapes interactive components send back
- [./references/renderers.md](./references/renderers.md) -- `MessagePrimitive.GenerativeUI` and its allowlist, the Slack and Teams converters, and why the two spec shapes do not interchange
- [./references/a2ui-openui.md](./references/a2ui-openui.md) -- A2UI surfaces over AG-UI and the third-party OpenUI integration
- [./references/tokens.md](./references/tokens.md) -- the shared token arrays and how to restyle or override the vocabulary

## Which generative UI pattern?

Two questions separate the patterns: does the **model** compose the layout or do you bind it ahead of time, and does the UI originate from a **tool call** or from a part your backend emits.

| Pattern | API | Best for |
|---|---|---|
| The `present` tool | `JSONGenerativeUI` + `present` | The model composes dashboards, cards, and layouts from a vocabulary you ship |
| Tool UI | toolkit `render` (see [tools](../tools/SKILL.md)) | A widget tied to one tool call you already know about |
| Generative UI primitive | `MessagePrimitive.GenerativeUI` + allowlist | A backend that already emits `generative-ui` message parts |
| LangGraph data UI | `makeAssistantDataUI` + `ui_message` | LangGraph agents emitting UI on the LangGraph stream, see [assistant-ui.com/docs/runtimes/langgraph/generative-ui](https://www.assistant-ui.com/docs/runtimes/langgraph/generative-ui) |
| OpenUI | `@openuidev/assistant-ui`, third party | Already invested in the OpenUI ecosystem and its component kit |

The first two are tool-driven, so the model decides when UI appears; the LangGraph row is backend-driven, so your agent does. `present` and the generative UI primitive both take a JSON component tree, but in non-interchangeable shapes, see [Spec shape differences](./references/renderers.md#spec-shape-differences). A tree built for `present` is also the shape the Slack and Teams converters accept and the A2UI converter produces.

## Quick start

Install the package, add the styled element, and enable the `"use generative"` compiler for your framework:

`zod` is an optional peer dependency imported by the `/react` entry, so install it with the package.

```bash
npm install @assistant-ui/generative-ui zod
npx assistant-ui@latest add generative-ui
```

```ts title="next.config.ts"
import { withAui } from "@assistant-ui/next";

export default withAui({
  /* your Next config */
});
```

Vite and TanStack Start use `aui()` from `@assistant-ui/vite` (`plugins: [aui({ ... })]`); Expo and bare React Native use `const { withAui } = require("@assistant-ui/metro");` in `metro.config.js`. The directive lets one file declare tools that both the browser and your server route import: the compiler strips the browser-only halves from the server build and the schemas from the client build.

`JSONGenerativeUI` turns a component library into the model-facing schema for `present`. Register the result on a toolkit like any other tool:

```tsx title="app/toolkit.tsx"
"use generative";

import { defineToolkit } from "@assistant-ui/react";
import {
  JSONGenerativeUI,
  defaultGenerativeUILibrary,
} from "@assistant-ui/generative-ui/react";

const generative = new JSONGenerativeUI({
  library: defaultGenerativeUILibrary,
});

export default defineToolkit({
  present: generative.present({ display: "standalone" }),
});
```

`display: "standalone"` renders the result on its own surface, outside the chain-of-thought trace; omit it to render inline. The default vocabulary is already a working setup with no components of your own, see [vocabulary.md](./references/vocabulary.md) for the full list and how to extend it.

Register the toolkit on the client through `AuiConfig`, and set `sendAutomaticallyWhen` so the run continues once the frontend tool resolves:

```tsx title="app/MyRuntimeProvider.tsx"
"use client";

import { AssistantRuntimeProvider, AuiConfig, Tools } from "@assistant-ui/react";
import { useChatRuntime } from "@assistant-ui/ai-sdk";
import { lastAssistantMessageIsCompleteWithToolCalls } from "ai";
import toolkit from "./toolkit";

export function MyRuntimeProvider({
  children,
}: {
  children: React.ReactNode;
}) {
  const runtime = useChatRuntime({
    sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls,
  });
  const config = AuiConfig({ tools: Tools({ toolkit }) });

  return (
    <AssistantRuntimeProvider runtime={runtime} config={config}>
      {children}
    </AssistantRuntimeProvider>
  );
}
```

`present` is a frontend tool: it resolves in the browser, and without `sendAutomaticallyWhen` the UI renders and the conversation stops before the model says anything else.

The route imports the same toolkit module. The compiler resolves that import to the server build, so only the schemas cross over and no browser code enters your server bundle:

```ts title="app/api/chat/route.ts"
import { openai } from "@ai-sdk/openai";
import { AISDKToolkit } from "@assistant-ui/ai-sdk";
import { convertToModelMessages, stepCountIs, streamText } from "ai";
import toolkit from "@/app/toolkit";

const aiToolkit = new AISDKToolkit({ toolkit });

export async function POST(req: Request) {
  const { messages, tools } = await req.json();

  const result = streamText({
    model: openai("gpt-5.6-luna"),
    messages: await convertToModelMessages(messages),
    stopWhen: stepCountIs(10),
    tools: await aiToolkit.tools({ frontend: tools }),
  });

  return result.toUIMessageStreamResponse();
}
```

When no backend of yours imports the toolkit module, for example a cloud-hosted run, compile with `backendless: true` so the client keeps every schema uploadable, including `present`'s:

```ts title="next.config.ts"
export default withAui({ ...yourConfig, aui: { backendless: true } });
```

## Style it

`npx assistant-ui@latest add generative-ui`, run above, installs the shipped stylesheet plus `components/assistant-ui/elements/generative-ui.tsx`, which exports `styledGenerativeUILibrary`: the same 29 components with a real markdown renderer swapped in for the default plain-text one. It is a `"use client"` module, so wiring it into a `"use generative"` toolkit file follows the client-module rule in the gotchas below; see [tokens.md](./references/tokens.md) for the exact override pattern, the `data-aui` styling hooks, and the token arrays.

## Beyond present

- Extend the vocabulary with your own components, or read back a model-produced tree for display: [vocabulary.md](./references/vocabulary.md).
- Let rendered nodes call back into your app through `_action`: [actions.md](./references/actions.md).
- Render a `generative-ui` message part your backend already emits, with `MessagePrimitive.GenerativeUI` and a consumer-provided allowlist: [renderers.md](./references/renderers.md).
- Post a tree to Slack or Microsoft Teams, or render an A2UI surface over AG-UI, or wire the third-party OpenUI integration: [renderers.md](./references/renderers.md) and [a2ui-openui.md](./references/a2ui-openui.md).

## Common Gotchas

**`present` renders the UI, then the conversation just stops**
- `present` is a frontend tool; without `sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithToolCalls` on `useChatRuntime`, the run never continues after it resolves.

**The model never learns about `present` on a cloud-hosted backend**
- The client build skips uploading frontend and human schemas because it assumes your backend imported the same toolkit module. Compile with `aui: { backendless: true }` when no server of yours does.

**`styledGenerativeUILibrary` breaks the `"use generative"` build**
- It is a `"use client"` module. A `"use generative"` file may reference it only as the inline `render` value inside a `defineGenerativeComponents` call, never as a spread, a top-level constant, or the `library` option directly. Passing it straight to `library` works only in a plain file with no `"use generative"` directive; see [tokens.md](./references/tokens.md).

**A `generative-ui` message part renders nothing**
- The default shadcn `Thread` does not wire `MessagePrimitive.GenerativeUI`. Opt in explicitly in your message renderer; see [renderers.md](./references/renderers.md).

**Unknown component name: silent drop versus thrown error**
- The `present` tool path drops an unrecognized `_type` and warns in development. The generative UI primitive throws a typed `GenerativeUIRenderError` unless you pass `Fallback`. Neither boundary constrains the props those components receive; validate `href`/`src` values yourself and never forward agent-supplied props into `dangerouslySetInnerHTML`.

**Slack or Teams output does not match the browser**
- Conversion is total but lossy: read the returned `warnings` array. Only a `$type` tree built for `present` converts; the primitive's `{ component, props }` shape has no Slack, Teams, or A2UI converter.

**`useChatRuntime` never emits a native `generative-ui` part**
- The AI SDK maps tool results to `tool-call` parts, not `generative-ui` parts. Bridge with a `render_gui` tool whose result you parse into a spec yourself (the docs call that helper `parseRenderGuiResult`; it is not a package export); see [renderers.md](./references/renderers.md).

## Related Skills

- [tools](../tools/SKILL.md) -- toolkit authoring, the `"use generative"` compiler, and tool UI for a widget tied to one specific tool call
- [elements](../elements/SKILL.md) -- installing the `generative-ui` styled element and the rest of the catalog
- [primitives](../primitives/SKILL.md) -- `MessagePrimitive` and the other unstyled building blocks
- [runtime](../runtime/SKILL.md) -- `AuiConfig`, `Tools`, and the rest of the config plumbing

© assistant-ui · MIT · assistant-ui/skills

Похожие скиллы

Всё по теме «Фронтенд и UI» →

Сначала — generative-ui от других авторов.

generative-ui himself65 Задаёт правила дизайн-системы для интерактивных HTML- и SVG-виджетов. Нужен, когда вместо текста агенту поручают показать графики, диаграммы или калькуляторы. CX Codex +1 3 200установок channels-setup CopilotKit Скилл для создания первого CopilotKit Channels агента и подключения его к Slack или Microsoft Teams. Охватывает весь путь: от проверки проекта до запуска агента, который отвечает на упоминания в чате. CX Codex +1 1 400установок service-itsm-channels-coordinate forcedotcom Интерактивный координатор для запуска настройки каналов связи Employee Service (ITSM) в Salesforce. Помогает выбрать между порталом, Teams и Slack. CX Codex +1 1 200установок slack-to-teams microsoft Разбирает существующий Slack-бот и помогает перевести его на Teams или сделать сразу под две платформы. Нужен, когда бот уже работает и его пора тянуть дальше. ★ 3 148звёзд репо block-kit slackapi Собирает и проверяет Block Kit JSON для сообщений, модалок и Home tab в Slack. Пригодится, когда нужно быстро получить валидную раскладку без чтения документации вручную. CX Codex +1 500установок chat-sdk vercel Помогает создавать мультиплатформенных чат-ботов на TypeScript с помощью Chat SDK от Vercel. Пригодится при настройке логики для Slack, Discord, Telegram или WhatsApp. CX Codex +1 5 400установок slack-messaging официальный anthropics Скилл помогает агенту писать сообщения для Slack с разметкой mrkdwn, выбирать структуру и учитывать контекст канала. Пригодится для черновиков и публикаций. CX Codex +1 4 000установок

Из того же набора13

thread-list Скилл для assistant-ui: добавляет боковую панель с несколькими диалогами, переключением, переименованием, архивацией и удалением. CX Codex +1 6 200установок update Обновляет существующее приложение на assistant-ui до актуальных версий AI SDK v7 и assistant-ui 0.15.x, применяя нужные миграции. Пригодится, когда после апдейта посыпались ошибки типов или пропали хуки. CX Codex +1 5 900установок cloud Подключает AssistantCloud к приложению на assistant-ui: история тредов между сессиями, обратная связь по сообщениям и загрузка файлов. CX Codex +1 5 000установок react-mcp Скилл для работы с @assistant-ui/react-mcp: подключает MCP-серверы, выбранные пользователем, прямо в браузере и регистрирует их инструменты в чате. CX Codex +1 4 000установок observability Подключает Langfuse, LangSmith или Helicone к бэкенд-роутам assistant-ui на AI SDK и рисует собранные спаны через экспериментальный @assistant-ui/react-o11y. CX Codex +1 4 000установок copilots Скилл для assistant-ui: учит агента читать состояние страницы, кликать по компонентам и менять их состояние через хуки React. CX Codex +1 3 900установок ink Скилл для сборки чат-интерфейсов прямо в терминале: связывает рантайм assistant-ui с рендерером Ink и выводит ответы как ANSI-разметку. CX Codex +1 923установок react-native Скилл для сборки чат-интерфейсов assistant-ui в Expo и чистом React Native: нативные примитивы, рантайм AI SDK и транспорт к бэкенду. CX Codex +1 909установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой