cloud について
cloudは、ReactチャットUIにスレッドの永続化、メッセージ履歴、タイトル生成、フィードバック、ファイルアップロードを追加するassistant-uiのホステッドサービスです。AssistantCloudクライアントでassistant-ui runtimeと連携し、LangGraph Cloudバックエンドのスレッド管理にも対応します。
主な機能
- 01スレッドとメッセージ履歴の永続化
- 02スレッドタイトルの自動生成
- 03メッセージフィードバックの保存
- 04ファイルアップロードへの対応
- 05assistant-ui runtimeおよびLangGraph Cloudとの連携
活用シーン
- 01チャット履歴を保存しスレッド切替時に読み込む
- 02メッセージへの肯定・否定フィードバックを記録する
- 03チャット画面でファイルをアップロードする
- 04LangGraph Cloud経由で会話スレッドを管理する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ assistant-ui/ skills --skill cloudインストール後、Claude Code で/cloudを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/auth-integrations.mdauthorization.mdcustom-persistence.mdpersistence.md詳細
assistant-ui Cloud
最新の API については、常に assistant-ui.com/llms.txt を参照してください。
Assistant Cloud は、任意の React チャット UI にスレッドの永続化、メッセージ履歴、自動生成タイトル、メッセージフィードバック、ファイルアップロードを追加するホステッドサービスです。1 つの AssistantCloud クライアントが、assistant-ui ランタイム、AuiConfig のスレッド統合、および LangGraph Cloud を支えます。
目次
- リファレンス | インストール | クイックスタート: useChatRuntime | AuiConfig ホスト: AISDKThreads | Cloud AI SDK からの移行 | LangGraph | メッセージフィードバック | 認証 | クライアント API | 環境変数 | よくある落とし穴 | 関連スキル
リファレンス
- ./references/persistence.md -- スレッド、メッセージ、ファイル、および run のクライアント API の全体像。ソースと照合済み
- ./references/authorization.md -- 3 つの認証モードと直接的なプロバイダー統合 (Clerk、Auth0、Supabase、Firebase)
- ./references/custom-persistence.md --
CloudMessagePersistenceとcreateFormattedPersistence。クラウドのメッセージストレージを基盤とするカスタムThreadHistoryAdapter向け - ./references/auth-integrations.md -- Auth.js (next-auth)、Clerk、better-auth による非クラウドの認証ゲーティング、および AssistantCloud とバックエンドのトークンエンドポイントの組み合わせ
インストール
npm install @assistant-ui/react @assistant-ui/ai-sdk
assistant-cloud は @assistant-ui/react の依存関係として配布されており、ブラウザーコード向けに AssistantCloud を再エクスポートします。@assistant-ui/react に依存する理由のないサーバーサイドコード (API ルート、トークンエンドポイント) は、assistant-cloud から AssistantCloud を直接インポートします。
クイックスタート: useChatRuntime
@assistant-ui/ai-sdk の useChatRuntime({ cloud }) は、AI SDK の useChat をラップし、永続化を追加します。最初のメッセージでクラウドスレッドを作成し、ストリーミング中にメッセージを永続化し、最初の応答後にタイトルを生成し、<ThreadList /> によるスレッド切り替え時に履歴を読み込み、保存されたメッセージに対してメッセージフィードバックを送信します。
"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 はデモ用です。本番環境の認証については 認証 を参照してください。useChatRuntime はほかにも adapters.history (ThreadHistoryAdapter。AI SDK と組み合わせるには withFormat を実装する必要があります)、adapters.feedback (cloud が設定されている場合はデフォルトでクラウドのフィードバックアダプター)、adapters.attachments、toCreateMessage、transport (デフォルトは /api/chat を呼び出す AssistantChatTransport)、および onResumeError を受け付けます。
AuiConfig ホスト: AISDKThreads
@assistant-ui/ai-sdk の AISDKThreads({ cloud }) は、AssistantRuntimeProvider ではないホスト (Vue、または手書きの AssistantClient) 向けの AuiConfig 相当のものです。cloud を設定すると、スレッドリストはバックグラウンドスレッドを持つ RemoteThreadList になります。訪問したすべてのスレッドは切り替え後も実行と自身の履歴を保持し、新しく作成されたスレッドは自らタイトルを付けます。
import { AuiConfig, AuiProvider } from "@assistant-ui/react";
import { AISDKThreads } from "@assistant-ui/ai-sdk";
const config = AuiConfig({
threads: AISDKThreads({ cloud }),
});
Cloud AI SDK からの移行
@assistant-ui/cloud-ai-sdk は非推奨です。新しいコードでは、@assistant-ui/ai-sdk の useChatRuntime の cloud オプションを使用してください。AuiConfig ホストの場合は、AISDKThreads({ cloud }) を使用してください。移行の詳細については Cloud AI SDK からの移行 を参照してください。
LangGraph: useLangGraphRuntime
@assistant-ui/react-langgraph の useLangGraphRuntime は、stream、create、load、delete に加えて cloud を受け取り、LangGraph Cloud バックエンド上でのクラウドベースのスレッド管理を行います。
"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 は { externalId } を返します。これはバックエンドの LangGraph スレッド ID です。load はそのスレッドのメッセージ(および任意で割り込み)を返します。delete は externalId を受け取り、指定されている場合はスレッド一覧 UI からの削除を有効にします。
メッセージフィードバック
useChatRuntime(または AISDKThreads)で cloud が設定されている場合、ランタイムはデフォルトの FeedbackAdapter を組み込み、cloud.threads.messages.feedback を自動的に呼び出します。そのため、標準の高評価・低評価ボタンは追加のコードなしで保存済みメッセージに対して永続化されます。直接呼び出す場合:
const { feedback_id, type } = await cloud.threads.messages.feedback(threadId, messageId, {
type: "positive", // or "negative"
});
認証
渡すフィールドによって選ばれる 3 つのコンストラクタ形式があります:
// 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,
});
認可はワークスペース単位でスコープされます(一般には userId、orgId_userId、または projectId_userId)。Assistant Cloud ダッシュボードから直接プロバイダー連携(Clerk、Auth0、Supabase、Firebase)を設定するか、API キークライアントを用いてサーバー側でトークンを発行し、フロントエンドの authToken コールバックが取得するエンドポイントから返します。両方の手順の詳細については authorization.md を、Cloud と Auth.js、Clerk、または better-auth のセッションデータを組み合わせる方法については auth-integrations.md をご覧ください。
クライアント API
すべてのメソッドは src/cloud/** に対して検証されています。threadId/messageId は常に最初の引数です。一覧エンドポイントは after(オフセットではなくカーソル)でページングします。
// 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 の last_message_at は必須です。create と update のその他の項目はすべて任意です。CloudThread のフィールド: id、title、last_message_at、created_at、updated_at、is_archived、external_id、metadata、project_id、workspace_id。CloudMessage のフィールド: id、parent_id、height、format、content、created_at、updated_at。content/format はクライアントにとって不透明です。useChatRuntime と AISDKThreads は format: "ai-sdk/v6" を、AI SDK の UIMessage 形式の content とともに書き込みます。cloud.projects.threads.messages.list は limit/after ページングを受け付けますが、cloud.threads.messages.list は受け付けません。失敗したリクエストは assistant-cloud から CloudAPIError(.status 付き)をスローします。不正な形式のレスポンスは CloudResponseError をスローします。詳細、自動保存の動作、テレメトリフィールド、エラー処理については persistence.md をご覧ください。
環境変数
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 は EXPO_PUBLIC_ASSISTANT_BASE_URL を読み取り、React Ink は ASSISTANT_BASE_URL を読み取ります(バンドラーがブラウザーに公開する仕組みがないため、NEXT_PUBLIC_ プレフィックスは付きません)。
よくある落とし穴
スレッドが永続化されない
cloudはuseChatRuntimeまたはAISDKThreadsに渡す必要があります。まだメッセージがないスレッドは作成されません。authTokenが黙ってnullに解決されていないか確認してください。その場合、実際のリクエストはネットワークに到達する前に素のError("Authorization failed")をスローします。これはCloudAPIErrorの 401 とは異なります。
クラウド API に対する 401 または「Authorization failed」
baseUrlがプロジェクトのフロントエンド API URL と完全に一致していることを確認してください(ホストの後に余分な内容がないこと)。- JWT モードでは、最初のリクエストの前に
authTokenが解決されることを確認してください。Clerk テンプレートの場合、JWT の aud クレームは"assistant-ui"でなければなりません。
フィードバックボタンは表示されるが何も永続化されない
- デフォルトのフィードバックアダプターは、
cloudがランタイムに渡されたときにのみ接続されます。カスタムのadapters.feedbackはそれを完全に上書きします。
ページのリロード後にメッセージ履歴が順不同で再表示される
- メッセージ行の
contentを手書きしないでください。これはアクティブなフォーマットのencodeが生成した内容と正確に一致している必要があり、そうでないとリロード時にdecodeが失敗します。テストデータは、行を直接挿入するのではなく、ランタイムを通じてシードしてください。
@assistant-ui/react-ai-sdk からのインポート
- このパッケージは、古いバージョンに固定されたインストール向けに
@assistant-ui/ai-sdkを再エクスポートするだけです。新しいコードでは、useChatRuntimeとAssistantChatTransportを@assistant-ui/ai-sdkからインポートしてください。
匿名モードでは履歴が失われる
- 匿名モードではブラウザセッションごとに新しいユーザーが作成されます(デバイス間の同期はありません)。永続性が必要になったら、JWT または API キー認証に切り替えてください。
関連スキル
- thread-list --
<ThreadList />サイドバー UI、スレッド CRUD セレクター、および完全にセルフホスト可能な(非クラウドの)スレッドリスト向けのRemoteThreadListAdapterコントラクト - setup -- assistant-ui のインストールとランタイムフックの選択(
cloudおよびcloud-clerkCLI テンプレートを含む) - runtime -- クラウドが満たす一般的なアダプターコントラクト(
ThreadHistoryAdapter、FeedbackAdapter、AttachmentAdapter)