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

cloud · assistant-ui — скилл для Claude Code: персистентность чатов assistant-ui

Подключает AssistantCloud к приложению на assistant-ui: история тредов между сессиями, обратная связь по сообщениям и загрузка файлов.

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

Что делает cloud

Скилл описывает, как связать рантайм assistant-ui с AssistantCloud — хостинговым сервисом, который хранит треды и сообщения, генерирует заголовки и принимает оценки от пользователей. Один клиент AssistantCloud работает и с useChatRuntime из @assistant-ui/ai-sdk, и с AISDKThreads({ cloud }) для хостов на AuiConfig, и с useLangGraphRuntime из @assistant-ui/react-langgraph.

Внутри — разбор трёх режимов авторизации: authToken с JWT, apiKey вместе с userId и workspaceId (только на сервере) и anonymous для демо. Отдельно разобраны интеграции с Clerk, Auth0, Supabase и Firebase и эндпоинт выдачи токена на бэкенде. Ещё есть клиентская поверхность cloud.threads, cloud.files, cloud.runs, cloud.telemetry и кастомный ThreadHistoryAdapter поверх CloudMessagePersistence.

Ставить пакеты нужно заранее: npm install @assistant-ui/react @assistant-ui/ai-sdk. Пакет assistant-cloud приезжает зависимостью @assistant-ui/react и реэкспортирует AssistantCloud для браузера, а серверный код импортирует его из assistant-cloud напрямую. Режим anonymous годится для демо — для продакшена нужен токен. Если треды не сохраняются, API отвечает 401 или кнопки обратной связи молчат, скилл как раз про эти случаи.

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

  • сохранить историю тредов между сессиями
  • подключить авторизацию через Clerk, Auth0, Supabase или Firebase
  • сделать загрузку файлов в чат
  • собирать оценки пользователей по сообщениям
  • починить 401 от cloud API и несохраняющуюся обратную связь

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

  • Подключи AssistantCloud к useChatRuntime, чтобы треды сохранялись между сессиями
  • Настрой авторизацию через Clerk и эндпоинт выдачи токена на бэкенде
  • Добавь загрузку файлов через cloud.files в мой чат на assistant-ui

Как установить cloud

1Через Skills CLI (Vercel)

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

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

~/.claude/skills/cloud/SKILL.md

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

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

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

primitives Скилл помогает собирать кастомные интерфейсы чата на базе нестилизованных компонентов @assistant-ui/react. Пригодится при вёрстке тредов, композеров и списков сообщений. CX Codex +1 6 300установок tools Скилл про то, как объявлять инструменты, которые вызывает модель, и рисовать их вызовы в assistant-ui. Пригодится, когда инструмент не вызывается или его UI не отрисовывается. CX Codex +1 6 300установок 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установок 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установок generative-ui Скилл для assistant-ui: модель собирает интерфейс из готовых компонентов во время ответа, а не заполняет заранее написанный вами. CX Codex +1 1 000установок

Другие версии cloud

Похожие

bencium-code-conventions bencium Задаёт правила Bence для React и Next.js: стек, стиль кода, тесты и рабочий процесс. Нужен при создании или настройке проекта по этим соглашениям. CX Codex +1 3 300установок nextjs-typescript-tailwindcss-supabase Mindrally Скилл задаёт агенту правила для Next.js 14, TypeScript, TailwindCSS и Supabase: серверные компоненты, обработка ошибок, читаемый код. CX Codex +1 1 300установок nextjs-supabase-auth sickn33 Скилл настраивает Supabase Auth в Next.js App Router: клиенты, middleware, OAuth callback и Server Actions. Пригодится для защиты маршрутов и работы с сессиями. CX Codex +1 6 600установок typescript-nextjs-supabase-cursorrules-prompt-file PatrickJS Правило для Cursor, которое держит TypeScript-код на Next.js App Router и Supabase в одном стиле: серверные компоненты, Shadcn UI, Tailwind. ★ 41 011звёзд репо modern-web-development Mindrally Набор правил для современного веб-стека: TypeScript, Next.js 14, React Server Components, Supabase, GraphQL и Tailwind CSS. Пригодится, когда агент пишет фронтенд и API в одном проекте. CX Codex +1 1 200установок neon-auth neondatabase Настраивает Managed Better Auth в ветках базы данных Neon. Скилл помогает внедрить вход по почте или OAuth и перенести пользователей с Supabase Auth. CX Codex +1 20 300установок

Рядом в теме «Фронтенд и UI»

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

Вопросы о cloud

Как установить cloud в Claude?

Выполните npx skills add assistant-ui/skills --skill cloud -a claude-code. Скилл появится в ~/.claude/skills/cloud/SKILL.md.

Что делает скилл cloud?

Показывает, как подключить AssistantCloud к assistant-ui: персистентность тредов и сообщений, авторизация, телеметрия, загрузка файлов и обратная связь. Работает с useChatRuntime, AISDKThreads({ cloud }) и useLangGraphRuntime.

Какие пакеты нужны для работы?

npm install @assistant-ui/react @assistant-ui/ai-sdk. AssistantCloud для браузера реэкспортируется из @assistant-ui/react, серверный код импортирует его из assistant-cloud.

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

SKILL.md · MIT
---
name: cloud
description: "Adds AssistantCloud backed persistence, authorization, and telemetry to assistant-ui apps. Use when wiring cross-session thread and message history, multi-device chat, message feedback, file uploads, or auth: passing `cloud` to `useChatRuntime` from `@assistant-ui/ai-sdk`, `AISDKThreads({ cloud })` for `AuiConfig` hosts, or `cloud` on `useLangGraphRuntime`. Covers constructing `AssistantCloud` with `authToken` (JWT), `apiKey` plus `userId`/`workspaceId` (server-side only), or `anonymous`; Clerk, Auth0, Supabase, and Firebase integrations and a backend token endpoint; the `cloud.threads`, `cloud.files`, `cloud.runs`, and `cloud.telemetry` client surface; and a custom `ThreadHistoryAdapter` on `CloudMessagePersistence`. Route here for threads that do not persist, 401s against the cloud API, or feedback buttons that do not save. For the `<ThreadList />` sidebar UI use thread-list; for the general adapter contracts use runtime."
license: MIT
---

# assistant-ui Cloud

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

Assistant Cloud is a hosted service that adds thread persistence, message history, auto-generated titles, message feedback, and file uploads to any React chat UI. One `AssistantCloud` client backs the assistant-ui runtime, `AuiConfig` thread integration, and LangGraph Cloud.

## Contents

- [References](#references) | [Install](#install) | [Quick start: useChatRuntime](#quick-start-usechatruntime) | [AuiConfig hosts: AISDKThreads](#auiconfig-hosts-aisdkthreads) | [Migrate from Cloud AI SDK](#migrate-from-cloud-ai-sdk) | [LangGraph](#langgraph-uselanggraphruntime) | [Message feedback](#message-feedback) | [Authentication](#authentication) | [Client API](#client-api) | [Environment variables](#environment-variables) | [Common Gotchas](#common-gotchas) | [Related Skills](#related-skills)

## References

- [./references/persistence.md](./references/persistence.md) -- the thread, message, file, and run client API in full, verified against source
- [./references/authorization.md](./references/authorization.md) -- the three auth modes and direct provider integrations (Clerk, Auth0, Supabase, Firebase)
- [./references/custom-persistence.md](./references/custom-persistence.md) -- `CloudMessagePersistence` and `createFormattedPersistence`, for a custom `ThreadHistoryAdapter` backed by cloud message storage
- [./references/auth-integrations.md](./references/auth-integrations.md) -- non-cloud auth gating with Auth.js (next-auth), Clerk, and better-auth, plus pairing AssistantCloud with a backend token endpoint

## Install

```bash
npm install @assistant-ui/react @assistant-ui/ai-sdk
```

`assistant-cloud` ships as a dependency of `@assistant-ui/react`, which re-exports `AssistantCloud` for browser code. Server-side code (API routes, token endpoints) that has no reason to depend on `@assistant-ui/react` imports `AssistantCloud` from `assistant-cloud` directly.

## Quick start: useChatRuntime

`useChatRuntime({ cloud })` from `@assistant-ui/ai-sdk` wraps AI SDK's `useChat` and adds persistence. It creates a cloud thread on the first message, persists messages as they stream, generates a title after the first response, loads history on thread switch through `<ThreadList />`, and submits message feedback against the stored message.

```tsx
"use client";

import { useMemo } from "react";
import { AssistantCloud, AssistantRuntimeProvider } from "@assistant-ui/react";
import { useChatRuntime } from "@assistant-ui/ai-sdk";
import { Thread } from "@/components/assistant-ui/elements/thread.aui";
import { ThreadList } from "@/components/assistant-ui/elements/thread-list.aui";

export default function ChatPage() {
  const cloud = useMemo(
    () =>
      new AssistantCloud({
        baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
        anonymous: true,
      }),
    [],
  );

  const runtime = useChatRuntime({ cloud });

  return (
    <AssistantRuntimeProvider runtime={runtime}>
      <div className="grid h-dvh grid-cols-[250px_1fr] gap-x-2">
        <ThreadList />
        <Thread />
      </div>
    </AssistantRuntimeProvider>
  );
}
```

`anonymous: true` is for demos; see [Authentication](#authentication) for production auth. `useChatRuntime` also accepts `adapters.history` (a `ThreadHistoryAdapter`, must implement `withFormat` to combine with AI SDK), `adapters.feedback` (defaults to the cloud feedback adapter when `cloud` is set), `adapters.attachments`, `toCreateMessage`, `transport` (defaults to `AssistantChatTransport` calling `/api/chat`), and `onResumeError`.

## AuiConfig hosts: AISDKThreads

`AISDKThreads({ cloud })` from `@assistant-ui/ai-sdk` is the `AuiConfig` equivalent for a host that is not `AssistantRuntimeProvider` (Vue, or a hand-rolled `AssistantClient`). With `cloud` set, the thread list is a `RemoteThreadList` with background threads: every visited thread keeps running and its own history after a switch, and a freshly created thread titles itself.

```tsx
import { AuiConfig, AuiProvider } from "@assistant-ui/react";
import { AISDKThreads } from "@assistant-ui/ai-sdk";

const config = AuiConfig({
  threads: AISDKThreads({ cloud }),
});
```

## Migrate from Cloud AI SDK

`@assistant-ui/cloud-ai-sdk` is deprecated. For new code, use the `cloud` option of `useChatRuntime` from `@assistant-ui/ai-sdk`; for an `AuiConfig` host, use `AISDKThreads({ cloud })`. See [Migrate from Cloud AI SDK](https://www.assistant-ui.com/docs/cloud/migrate-cloud-ai-sdk) for the migration details.

## LangGraph: useLangGraphRuntime

`useLangGraphRuntime` from `@assistant-ui/react-langgraph` takes `cloud` alongside `stream`, `create`, `load`, and `delete` for cloud-backed thread management over a LangGraph Cloud backend.

```tsx
"use client";

import { AssistantCloud, AssistantRuntimeProvider } from "@assistant-ui/react";
import { useLangGraphRuntime, type LangChainMessage } from "@assistant-ui/react-langgraph";
import { useMemo } from "react";
import { createThread, deleteThread, getThreadState, sendMessage } from "@/lib/chatApi";

export function MyRuntimeProvider({ children }: { children: React.ReactNode }) {
  const cloud = useMemo(
    () => new AssistantCloud({ baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!, anonymous: true }),
    [],
  );

  const runtime = useLangGraphRuntime({
    cloud,
    stream: async function* (messages, { initialize }) {
      const { externalId } = await initialize();
      if (!externalId) throw new Error("Thread not found");
      return sendMessage({ threadId: externalId, messages });
    },
    create: async () => ({ externalId: (await createThread()).thread_id }),
    load: async (externalId) => {
      const state = await getThreadState(externalId);
      return { messages: (state.values as { messages?: LangChainMessage[] }).messages ?? [] };
    },
    delete: async (externalId) => deleteThread(externalId),
  });

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

`create` returns `{ externalId }`, your backend's LangGraph thread id; `load` returns that thread's messages (and optionally interrupts); `delete` receives the `externalId` and, when provided, enables delete from the thread list UI.

## Message feedback

When `cloud` is set on `useChatRuntime` (or `AISDKThreads`), the runtime wires a default `FeedbackAdapter` that calls `cloud.threads.messages.feedback` automatically, so the built-in thumbs up and down buttons persist against the stored message with no extra code. Calling it directly:

```ts
const { feedback_id, type } = await cloud.threads.messages.feedback(threadId, messageId, {
  type: "positive", // or "negative"
});
```

## Authentication

Three constructor shapes, chosen by which fields you pass:

```ts
// JWT (recommended for production; client-side)
const cloud = new AssistantCloud({
  baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
  authToken: async () => getAuthToken(), // returns a JWT, or null
});

// API key (server-side only; baseUrl defaults to https://backend.assistant-api.com)
const cloud = new AssistantCloud({
  apiKey: process.env.ASSISTANT_API_KEY!,
  userId: user.id,
  workspaceId: user.workspaceId,
});

// Anonymous (demos and prototypes; a new user per browser session)
const cloud = new AssistantCloud({
  baseUrl: process.env.NEXT_PUBLIC_ASSISTANT_BASE_URL!,
  anonymous: true,
});
```

Authorization is scoped to a workspace (commonly `userId`, `orgId_userId`, or `projectId_userId`). Wire a direct provider integration (Clerk, Auth0, Supabase, Firebase) from the Assistant Cloud dashboard, or mint a token server-side with the API key client and return it from an endpoint your frontend's `authToken` callback fetches. See [authorization.md](./references/authorization.md) for both paths in full, and [auth-integrations.md](./references/auth-integrations.md) for pairing Cloud with Auth.js, Clerk, or better-auth session data.

## Client API

Every method is verified against `src/cloud/**`. `threadId`/`messageId` are always the first arguments; list endpoints page with `after` (a cursor, not an offset).

```ts
// Threads
const { threads } = await cloud.threads.list({ is_archived: false, limit: 50, after: cursor });
const thread = await cloud.threads.get(threadId);
const { thread_id } = await cloud.threads.create({ last_message_at: new Date(), title, external_id, metadata });
await cloud.threads.update(threadId, { title, last_message_at, metadata, is_archived });
await cloud.threads.delete(threadId);

// Messages (parent_id and format are required on create; update touches content only)
const { messages } = await cloud.threads.messages.list(threadId, { format: "ai-sdk/v6" });
const { message_id } = await cloud.threads.messages.create(threadId, { parent_id, format, content });
await cloud.threads.messages.update(threadId, messageId, { content });
await cloud.threads.messages.feedback(threadId, messageId, { type: "positive" });

// Files
const { signedUrl, publicUrl, expiresAt } = await cloud.files.generatePresignedUploadUrl({ filename });
await fetch(signedUrl, { method: "PUT", body: file });

// Runs, projects, auth
await cloud.runs.report(runReport); // telemetry sink; the runtime calls this for you
const { threads: projectThreads } = await cloud.projects.threads.list({ limit: 50, after: cursor }); // whole project, not one workspace
const { messages: projectMessages } = await cloud.projects.threads.messages.list(threadId, { limit: 50, after: cursor });
const { token } = await cloud.auth.tokens.create(); // server-side, API key mode
cloud.telemetry; // { enabled: boolean, beforeReport? }
```

`cloud.threads.create`'s `last_message_at` is required; everything else on create and update is optional. `CloudThread` fields: `id`, `title`, `last_message_at`, `created_at`, `updated_at`, `is_archived`, `external_id`, `metadata`, `project_id`, `workspace_id`. `CloudMessage` fields: `id`, `parent_id`, `height`, `format`, `content`, `created_at`, `updated_at`. `content`/`format` are opaque to the client; `useChatRuntime` and `AISDKThreads` write `format: "ai-sdk/v6"` with an AI SDK `UIMessage`-shaped `content`. `cloud.projects.threads.messages.list` accepts `limit`/`after` paging that `cloud.threads.messages.list` does not. Failed requests throw `CloudAPIError` (with `.status`) from `assistant-cloud`; a malformed response throws `CloudResponseError`. Full detail, auto-save behavior, telemetry fields, and error handling: [persistence.md](./references/persistence.md).

## Environment variables

```env
NEXT_PUBLIC_ASSISTANT_BASE_URL=https://proj-[YOUR-ID].assistant-api.com  # client-side
ASSISTANT_API_KEY=your-api-key-here                                     # server-side only, never expose to the client
```

React Native reads `EXPO_PUBLIC_ASSISTANT_BASE_URL`; React Ink reads `ASSISTANT_BASE_URL` (no `NEXT_PUBLIC_` prefix, since there is no bundler exposing it to a browser).

## Common Gotchas

**Threads not persisting**
- `cloud` must be passed to `useChatRuntime` or `AISDKThreads`; a thread with no messages yet is never created.
- Check that `authToken` isn't silently resolving to `null`: any real request then throws a plain `Error("Authorization failed")` before it reaches the network, distinct from a `CloudAPIError` 401.

**401 or "Authorization failed" against the cloud API**
- Verify `baseUrl` matches the project's Frontend API URL exactly (no trailing content after the host).
- For JWT mode, confirm `authToken` resolves before the first request; for a Clerk template, the aud claim in the JWT must be `"assistant-ui"`.

**Feedback buttons render but nothing persists**
- The default feedback adapter only wires up when `cloud` is passed to the runtime; a custom `adapters.feedback` overrides it entirely.

**Message history reappears out of order after a page reload**
- Do not hand-write `content` for a message row; it must be exactly what the active format's `encode` produced, or `decode` fails on reload. Seed test data through the runtime, not by inserting rows directly.

**Importing from `@assistant-ui/react-ai-sdk`**
- That package only re-exports `@assistant-ui/ai-sdk` for installs pinned to an older version. Import `useChatRuntime` and `AssistantChatTransport` from `@assistant-ui/ai-sdk` in new code.

**Anonymous mode loses history**
- Anonymous creates a new user per browser session (no cross-device sync); switch to JWT or API key auth once you need durability.

## Related Skills

- [thread-list](../thread-list/SKILL.md) -- the `<ThreadList />` sidebar UI, thread CRUD selectors, and the `RemoteThreadListAdapter` contract for a fully self-hosted (non-cloud) thread list
- [setup](../setup/SKILL.md) -- installing assistant-ui and picking a runtime hook, including the `cloud` and `cloud-clerk` CLI templates
- [runtime](../runtime/SKILL.md) -- the general adapter contracts (`ThreadHistoryAdapter`, `FeedbackAdapter`, `AttachmentAdapter`) that cloud fulfills

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

Смотрите также

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

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