mcpField
T
tanstack-ai-vue-skilld

tanstack-ai-vue-skilld

github.com/skilld-dev開発184109 回インストール3 週間前に更新
リポジトリ

tanstack-ai-vue-skilld について

TanStack AI を使ったストリーミングチャットや生成機能を構築する Vue 3 向けコンポーザブルライブラリです。ヘッドレスクライアントをリアクティブな状態として扱えます。

主な機能

  1. 01リアクティブなストリーミングチャット状態
  2. 02型付きクライアントツールの実行
  3. 03画像・音声・スピーチ・動画の生成
  4. 04構造化出力と文字起こし用コンポーザブル
  5. 05BYOK と WebMCP ツール用コンポーザブル

活用シーン

  1. 01Vue でストリーミングチャット画面を構築
  2. 02Vue アプリに画像や音声の生成を追加
  3. 03WebMCP に実行可能なクライアントツールを登録

インストール

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

$npx skills add https://github.com/skilld-dev/vue-ecosystem-skills --skill tanstack-ai-vue-skilld

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

同梱ファイル

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

references/
byok-and-webmcp.md
chat-ui.md
generation-composables.md
use-chat.md

詳細

@tanstack/ai-vue

TanStack AI のストリーミングチャット、構造化出力、メディア生成向けの Vue 3 コンポーザブルです。ヘッドレスの @tanstack/ai-client クラス(ChatClient、GenerationClient、VideoGenerationClient)をリアクティブな状態でラップします。

  • ドキュメント記載のバージョン:0.24.3(出典:package.json:3)
  • ピア依存関係:vue >=3.5.0、@tanstack/ai ^0.58.0;実行時依存関係:@tanstack/ai-client ^0.33.2、@tanstack/markdown ^0.0.13(出典:package.json:55-62)
  • エントリーポイント:.(メイン)、./ui(ヘッドレスチャット UI ファクトリー)、./byok(独自のキーを使用)(出典:package.json:23-36)
  • 公式ドキュメント:https://tanstack.com/ai/latest/docs/api/ai-vue および https://tanstack.com/ai/latest/docs/getting-started/quick-start-vue
  • インストール:pnpm add @tanstack/ai @tanstack/ai-vue @tanstack/ai-openai(プロバイダーアダプターも必要です。サーバーサイドのチャット機能は @tanstack/ai が提供します)

基本ルール

  1. すべてのコンポーザブルは、コンポーネントの setup またはエフェクトスコープ内で実行する必要があります。onScopeDispose によってクリーンアップは自動的に行われ、スコープが接続を所有します(出典:src/use-chat.ts:259-269)。
  2. すべてのリアクティブな状態は DeepReadonly<ShallowRef<T>> です。スクリプトとテンプレートの両方で .value を使って読み取ります。再代入はしないでください。戻り値のメソッド(setMessages、clear、reset)を使います(出典:src/use-chat.ts:425-457)。
  3. connection アダプター(例:このパッケージから再エクスポートされる fetchServerSentEvents('/api/chat'))または fetcher を渡します。いずれも指定しない場合、生成フックは useGeneration requires either a connection or fetcher option をスローします(出典:src/use-generation.ts:272-274)。
  4. useChat は呼び出しごとに 1 つの ChatClient を生成します。connection(またはその他のトランスポートの識別情報)を変更するには、再マウントするか key プロパティを変更する必要があります。body、forwardedProps、context、queue は監視され、変更が即時に同期されます(出典:src/types.ts:77-79、src/use-chat.ts:212-230)。
  5. コールバックオプション(onChunk、onFinish、onError など)は、呼び出し時にオプションオブジェクトを通じて参照されるため、リアクティブなオプションや変更されたオプションは、クライアントを再生成せずに反映されます(出典:src/use-chat.ts:85-91)。
  6. body より forwardedProps を優先してください。body は非推奨ですが、引き続き同じワイヤーペイロードにマージされます(出典:src/use-chat.ts:207-209)。

クイックスタート:ストリーミングチャット

サーバー(Express、または TanStack AI の SSE を返す任意のバックエンド):

import { chat, toServerSentEventsResponse } from '@tanstack/ai'
import { openaiText } from '@tanstack/ai-openai'

app.post('/api/chat', async (req, res) => {
  const stream = chat({ adapter: openaiText('gpt-4o'), messages: req.body.messages })
  const response = toServerSentEventsResponse(stream)
  // pipe response.body to res
})

クライアントコンポーネント:

<script setup lang="ts">
import { ref } from 'vue'
import { useChat, fetchServerSentEvents } from '@tanstack/ai-vue'

const input = ref('')
const { messages, sendMessage, isLoading } = useChat({
  connection: fetchServerSentEvents('/api/chat'),
})

function handleSubmit() {
  if (input.value.trim() && !isLoading.value) {
    sendMessage(input.value)
    input.value = ''
  }
}
</script>

<template>
  <div v-for="message in messages.value" :key="message.id">
    <div v-for="(part, idx) in message.parts" :key="idx">
      <p v-if="part.type === 'text'">{{ part.content }}</p>
    </div>
  </div>
  <form @submit.prevent="handleSubmit">
    <input v-model="input" :disabled="isLoading.value" />
    <button type="submit">Send</button>
  </form>
</template>

出典:公式クイックスタート、https://tanstack.com/ai/latest/docs/getting-started/quick-start-vue

型付きツール

@tanstack/ai の toolDefinition() でツールを一度定義し、コンポーネント内で .client(fn) を実装して、ここから再エクスポートされる @tanstack/ai-client の clientTools() でラップします。これにより、as const を使わなくても part.name、part.input、part.output が適切な型に絞り込まれます。クライアントツールは自動的に実行されるため、onToolCall オプションはありません。createChatClientOptions と InferChatMessages(どちらも再エクスポートされています)を使ってメッセージ型を導出します。出典:https://tanstack.com/ai/latest/docs/api/ai-vue

<script setup lang="ts">
import { useChat, fetchServerSentEvents, clientTools } from '@tanstack/ai-vue'
import { updateUIDef } from './tool-definitions'

const updateUI = updateUIDef.client((input) => {
  notification.value = input.message
  return { success: true }
})

const { messages, sendMessage } = useChat({
  connection: fetchServerSentEvents('/api/chat'),
  tools: clientTools(updateUI),
})
</script>

共有チャットフック

createChatHook(options)(ルートエントリー)は、モジュールスコープでオプションをバインドし、useChat コンポーザブルを返します。インスタンスごとに上書きできるのは threadId、live、forwardedProps、body、initialMessages のみです。tools、interrupts、outputSchema はファクトリーのオプションに設定したままにします。インポートした useChat と名前が衝突する場合は、呼び出し側で名前を変更してください(出典:src/create-chat-hook.ts:28-45)。

const { useChat: useAppChat } = createChatHook(chatOptions)
const chat = useAppChat({ threadId: 'support-1' })

生成コンポーザブル

すべて同じパターンです。connection または fetcher を渡し、generate(input) を呼び出して、リアクティブな状態を読み取ります。

コンポーザブル入力型結果型その他
useGenerationカスタムの TInputカスタムの TResultカスタム型向けの基本コンポーザブル
useGenerateImageImageGenerateInputImageGenerationResult
useGenerateAudioAudioGenerateInputAudioGenerationResult
useGenerateSpeechSpeechGenerateInputTTSResult
useTranscriptionTranscriptionGenerateInputTranscriptionResult
useSummarizeSummarizeGenerateInputSummarizationResult
useGenerateVideoVideoGenerateInputVideoGenerateResultjobId、videoStatus、onJobCreated、onStatusUpdate

共通の戻り値:generate、result、isLoading、error、status、stop、reset、runId。詳細、変換、永続化については、references/generation-composables.md を参照してください。

stop() はローカルのストリームを中断するだけです。プロバイダーですでに実行中の処理は停止しません。キャンセルまたはポーリングするには、独自のエンドポイントで runId を使用してください(出典:src/use-generation.ts:124-131)。

チャット UI(@tanstack/ai-vue/ui)

/ui サブパスの createChatHook を使ってチャットインターフェースを構築します(非推奨のビルトインコンポーネント Chat、ChatInput、ChatMessage、ChatMessages、ToolApproval は使用しないでください。これらは 0.3.0 から非推奨で、1.0.0 での削除が予定されています)。このサブパスでは、レンダリングレスの UIChat、UIProvider、UIMessages、UIMessage、UIPart、UIInterrupts、UIQueue、および createChatUI / createChatHookContexts もエクスポートされます。このサブパスは生の .ts / .vue ソースとして提供されるため、独自の tsconfig に対して型チェックされます(出典:package.json:28-31、src/ui.ts:2-33、src/chat-ui/types.ts:5)。

ガイド:references/chat-ui.md

BYOK と WebMCP

  • useByok(client) は ByokClient をリアクティブな ByokSnapshot に変換します。/byok サブパスの defineByok、ByokClient、passkeyStorage などを使ってクライアントを構築してください。キーはリクエスト本文には含まれず、x-byok-* ヘッダーで送信されます(出典:src/use-byok.ts:5-14、src/use-generation.ts:35-38)。
  • useWebMCPTools([searchProducts]) は、現在のスコープで実行可能なクライアントツールを WebMCP に登録します。破棄時に登録が解除されます(出典:src/use-web-mcp-tools.ts:27-55)。

ガイド:references/byok-and-webmcp.md

トラブルシューティング

  • テンプレートで状態が更新されない:これらは ShallowRef です。テンプレート内でも isLoading.value を使用してください。
  • useChat でオプションの変更が反映されない:トランスポートの識別情報(connection、threadId の永続化形式)はインスタンスごとに固定されます。再マウントするか、コンポーネントの key を変更してください(出典:src/types.ts:77-79)。
  • 承認レスポンスが拒否される:addToolApprovalResponse に渡すのはツール呼び出し ID ではなく、承認 ID(part.approval.id)です(出典:src/types.ts:193-199)。
  • 再読み込み時に何も復元されない:永続化には安定した threadId が必要です。指定しない場合、クライアントはマウント後に ID を生成し、チャットは一時的なままとなります(出典:src/use-chat.ts:101-103)。

参考資料

  • useChat API:オプション、戻り値の完全な形式、構造化出力、中断、キュー、ライブモード、再開。
  • 生成コンポーザブル:useGeneration と 6 つの特化型フック、onResult による変換、永続化、useAudioRecorder。
  • チャット UI:/ui サブパス、ファクトリー設定、レンダリングレスコンポーネント、非推奨コンポーネントからの移行。
  • BYOK と WebMCP:/byok サブパス、useByok、useWebMCPTools。

コメント