mcpField
C
cloud

cloud

github.com/assistant-uiクラウド・DevOps295.1k 回インストール1 日前に更新
リポジトリ

cloud について

cloudは、ReactチャットUIにスレッドの永続化、メッセージ履歴、タイトル生成、フィードバック、ファイルアップロードを追加するassistant-uiのホステッドサービスです。AssistantCloudクライアントでassistant-ui runtimeと連携し、LangGraph Cloudバックエンドのスレッド管理にも対応します。

主な機能

  1. 01スレッドとメッセージ履歴の永続化
  2. 02スレッドタイトルの自動生成
  3. 03メッセージフィードバックの保存
  4. 04ファイルアップロードへの対応
  5. 05assistant-ui runtimeおよびLangGraph Cloudとの連携

活用シーン

  1. 01チャット履歴を保存しスレッド切替時に読み込む
  2. 02メッセージへの肯定・否定フィードバックを記録する
  3. 03チャット画面でファイルをアップロードする
  4. 04LangGraph Cloud経由で会話スレッドを管理する

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/assistant-ui/skills --skill cloud

インストール後、Claude Code で/cloudを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
auth-integrations.md
authorization.md
custom-persistence.md
persistence.md

詳細

assistant-ui Cloud

最新の API については、常に assistant-ui.com/llms.txt を参照してください。

Assistant Cloud は、任意の React チャット UI にスレッドの永続化、メッセージ履歴、自動生成タイトル、メッセージフィードバック、ファイルアップロードを追加するホステッドサービスです。1 つの AssistantCloud クライアントが、assistant-ui ランタイム、AuiConfig のスレッド統合、および LangGraph Cloud を支えます。

目次

リファレンス

  • ./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-clerk CLI テンプレートを含む)
  • runtime -- クラウドが満たす一般的なアダプターコントラクト(ThreadHistoryAdapter、FeedbackAdapter、AttachmentAdapter)

コメント