125k

AI SDK

AI SDK メッセージを作成し、モデル、API ルート、ネットワーク リクエスト、API キーを使用せずに useChat を通じて事前定義された会話をストリーミングします。

@shadcn/helpers/ai-sdk を使うと、AI 会話をコードで定義し、モデル、API ルート、ネットワーク リクエスト、API キーを使わずにストリーミングできます。

会話は実際の useChat ライフサイクルを通じてストリーミングされるため、コンポーネントは 本番環境とまったく同じように動作します。

AI SDK がサポートするすべてのパーツ形式(推論、ツール、データ、ファイル、ソース、カスタム パーツ)に対応しています。ツール呼び出しを実際のユーザー入力のために一時停止することもできます。 詳しくはヒューマン・イン・ザ・ループを参照してください。

import { createChat } from "@shadcn/helpers/ai-sdk"
 
const chat = createChat()
  .user("What changed in this release?")
  .assistant("The release adds keyboard shortcuts and faster search.")
  .user("Can you show me the shortcuts?")
  .assistant("Press ⌘K to search and ⌘Enter to submit.")

初期メッセージとローカル トランスポートを指定して、チャットを useChat に渡します。 useChat はストリーミングされた応答を受け取ります。

import { useChat } from "@ai-sdk/react"
 
function Chat() {
  const { messages, sendMessage } = useChat({
    messages: chat.get(0), // starts with no messages.
    transport: chat.transport(),
  })
 
  const nextMessage = chat.next(messages)
 
  return (
    <button
      disabled={!nextMessage}
      onClick={() => {
        if (nextMessage) {
          void sendMessage(nextMessage)
        }
      }}
    >
      Send next message
    </button>
  )
}

get(0) はメッセージなしで始まります。sendMessage(nextMessage) は次の定義済みユーザー メッセージ(承認を含む)を送信し、トランスポートがそのアシスタント応答をストリーミングします。


用途

このヘルパーはチャット UI をモデルやバックエンドから切り離すため、フロントエンドだけで 開発できます。オフラインで即座に実行でき、毎回同じように動作します。

  • コンポーネントを構築します。 メッセージ バブル、ツール カード、推論パネルを、最初に モデルを接続することなく、現実的なストリーミング出力で作成できます。
  • プレビューとデモ。 稼働中のモデルに依存しない、再現可能なプレビュー、スクリーンショット、 ビデオを提供できます。
  • ドキュメントを作成します。 読み込むたびに同じように描画される会話で、ドキュメントの 例を動かせます。
  • テスト ネットワーク呼び出しを行わずに、CI の決定論的ストリームに対してアサートします。 トークンの支出、または不安定なモデル出力を拒否します。

インストール

pnpm add @shadcn/helpers

このヘルパーは既存の AI SDK 構成(ai と @ai-sdk/react)と一緒に使えます。 ヘルパーは @shadcn/helpers/ai-sdk からインポートしてください。


使い方

会話を作成し、そのメッセージとトランスポートを useChat に渡してから、next() で定義済みの ユーザー メッセージを順番に送信します。

"use client"
 
import { useChat } from "@ai-sdk/react"
import { createChat } from "@shadcn/helpers/ai-sdk"
 
const chat = createChat()
  .user("What changed in this release?")
  .assistant("The release adds keyboard shortcuts and faster search.")
  .user("Can you show me the shortcuts?")
  .assistant("Press ⌘K to search and ⌘Enter to submit.")
 
const initialMessages = chat.get(0)
const transport = chat.transport()
 
export function Chat() {
  const { messages, sendMessage, status } = useChat({
    messages: initialMessages,
    transport,
  })
  const nextMessage = chat.next(messages)
  const isBusy = status === "submitted" || status === "streaming"
 
  return (
    <div>
      {messages.map((message) => (
        <div key={message.id}>{/* Render the message */}</div>
      ))}
      <button
        disabled={!nextMessage || isBusy}
        onClick={() => {
          if (nextMessage && !isBusy) {
            void sendMessage(nextMessage)
          }
        }}
      >
        Send
      </button>
    </div>
  )
}
New Chat
How can I help you today?
Morning, shadcn!
What are we working on today? Press send to start a new conversation
Demo is read only. Press send to send messages.
"use client"

import { useChat } from "@ai-sdk/react"

ユーザーメッセージ

このヘルパーで追加するメッセージには user と assistant のロールが設定されます。user() でユーザー メッセージを追加できます。createChat({ messages }) で開始した場合、既存の AI SDK メッセージは保持されます。

const chat = createChat().user("What changed in this release?")
 
const [message] = chat.get()
 
message.role // "user"
message.parts // [{ type: "text", text: "What changed in this release?" }]

必要に応じて、第 2 引数で id またはメタデータを渡します。

chat.user("What changed in this release?", {
  id: "user-release-question",
  metadata: {
    source: "docs",
  },
})

ユーザー メッセージにはファイルも含められます。ファイルを参照してください。


アシスタントメッセージ

assistant() を使ってアシスタント メッセージを追加します。

const chat = createChat().assistant(
  "The release adds keyboard shortcuts and faster search."
)
 
const [message] = chat.get()
 
message.role // "assistant"
message.parts // [{ type: "text", text: "The release adds...", state: "done" }]

文字列を渡すと 1 つのテキスト パーツが作成されます。AI SDK メッセージ パーツの配列を渡す こともできます。

chat.assistant([
  { type: "text", text: "The release adds keyboard shortcuts." },
  { type: "text", text: "Search is faster too." },
])

プレーン テキスト以外の内容を含むメッセージには、ライター コールバックを使用します。

chat.assistant(({ writer }) => {
  writer.reasoning("I should summarize the release.")
  writer.text("The release adds keyboard shortcuts and faster search.")
})

ライターは、呼び出した順序でパーツを追加します。


メッセージパーツ

アシスタント メッセージには複数のパーツ形式を含められます。writer でパーツを追加すると、 呼び出した順序で assistant() に渡されます。

chat.assistant(({ writer }) => {
  writer.reasoning("Let me check the weather.")
  writer
    .tool("getWeather", { input: { city: "San Francisco" } })
    .output({ city: "San Francisco", temperature: 18, condition: "Breezy" })
  writer.text("It is 18°C and breezy in San Francisco.")
})

テキスト

text() を使ってテキスト パーツを追加します。

chat.assistant(({ writer }) => {
  writer.text("The release adds keyboard shortcuts.")
  writer.text(" Search is faster too.")
})

呼び出すたびに個別のテキスト パーツが作成されます。chat.transport() と一緒に使うと、 テキストは単語ごとにストリーミングされます。

mode: "instant" を渡すとパーツ全体を一度に送信できます。delayMs を使うと、テキストの 差分が送信される間隔を変更できます。

writer.text("Done.", { mode: "instant" })
writer.text("This part streams more slowly.", { delayMs: 100 })

テキスト パーツに安定した識別子が必要な場合は id を渡します。

writer.text("The final answer.", { id: "answer" })

推理

reasoning() を使用して推論部分を追加します。

chat.assistant(({ writer }) => {
  writer.reasoning("I should check the latest conditions first.")
  writer.text("Let me check the weather.")
})

推論では、テキストと同じ id、delayMs、および mode オプションを使用します。

writer.reasoning("Checking the forecast.", { mode: "instant" })

ツール呼び出し

tool() を使ってツール呼び出しを追加します。入力から出力までのツールのライフサイクルを 追跡するハンドルが返されます。

chat.assistant(({ writer }) => {
  writer
    .tool("getWeather", {
      title: "Checking weather",
      input: { city: "San Francisco" },
    })
    .sleep(900)
    .output({
      city: "San Francisco",
      temperature: 18,
      condition: "Breezy",
    })
 
  writer.text("It is 18°C and breezy in San Francisco.")
})

ツールは output()、error()、または denied() で終了できます。メッセージのない場合は、

writer.tool("getWeather", { input: { city: "San Francisco" } }).error()
 
writer.tool("getWeather", { input: { city: "San Francisco" } }).denied()

入力と結果の間にライフサイクル イベントが必要な場合はハンドルを使用します。dynamic: true を指定すると、型付き tool-<name> パーツの代わりに動的ツール パーツが作成されます。

writer.tool("getWeather", {
  dynamic: true,
  input: { city: "San Francisco" },
  output: { city: "San Francisco", temperature: 18, condition: "Breezy" },
})

createChat にメッセージ型を渡すと、ツール名、入力、出力に型を付けられます。useChat と同じ 型パラメーターを使用します。

import type { UIMessage } from "ai"
 
type Tools = {
  getWeather: {
    input: { city: string }
    output: { city: string; temperature: number; condition: string }
  }
}
 
type ChatMessage = UIMessage<unknown, Record<string, never>, Tools>
 
const chat = createChat<ChatMessage>()

メッセージ型は一度だけ定義し、createChat と useChat の両方で使用します。

const { messages } = useChat<ChatMessage>({
  messages: chat.get(0),
  transport: chat.transport(),
})

ツール呼び出しをスクリプト内で完了させず、ユーザーの入力を待つこともできます。 ヒューマン・イン・ザ・ループを参照してください。


ヒューマン・イン・ザ・ループ

ツール呼び出しを一時停止して、実際のユーザーに操作を委ねられます。このヘルパーは AI SDK の 2 種類のヒューマン・イン・ザ・ループ フローに対応しています。1 つはユーザーが出力を入力する クライアント実行ツール、もう 1 つはユーザーが承認または拒否してから定義済みの出力を ストリーミングする承認ゲート付きツールです。

ツール呼び出しを一時停止する

ツール呼び出しを未解決のままにしてターンを一時停止します。入力のストリーミングが完了した後も、 クライアントが addToolOutput で出力を渡すまで、パーツは input-available 状態に留まります。

chat.assistant(({ writer }) => {
  writer.text("Answer these and I'll tailor the prototype.")
  writer.tool("askQuestions", { input: { questions } })
})

承認が必要

needsApproval: true を渡すと、ユーザーの判断が下るまで一時停止します。この場合の output は すぐに解決されず、承認後にストリーミングされます。拒否された場合は tool-output-denied が 自動的にストリーミングされ、needsApproval とともに errorText を指定すると、承認後に 失敗するツールを定義できます。

chat.assistant(({ writer }) => {
  writer.text("That will archive 3 drafts. I need your approval.")
  writer.tool("archiveDrafts", {
    input: { count: 3 },
    needsApproval: true,
    output: { archived: 3 },
  })
})

needsApproval を指定した呼び出しのハンドルで output()、error()、または denied() を呼ぶと 例外が発生します。ユーザーの判断によって呼び出しが解決されます。

継続処理

一時停止したターンの直後にコールバックで定義したターンは、継続処理になります。スクリプトを 構築した時点では実体化されず、後続リクエストが届いたときに実行されます。コンテキストには toolCall が含まれ、一時停止した呼び出しとユーザーの操作が結合されます。

chat
  .assistant(({ writer }) => {
    writer.tool("askQuestions", { input: { questions } })
  })
  .assistant(({ writer, toolCall }) => {
    writer.text(
      toolCall?.name === "askQuestions" && toolCall.output
        ? `Starting with ${toolCall.output.answers.direction}.`
        : "Starting now."
    )
  })

クライアント実行ツールでは、toolCall.output がユーザーの入力した出力です。承認フローでは、 toolCall.approved と toolCall.denied に判断結果が入り、コールバックの内容より先に定義済みの 出力がストリーミングされます。

プロパティ説明
nameツール名。比較すると input と output が絞り込まれます。
toolCallId一時停止した呼び出しの ID。
inputツールの入力。
outputユーザーが入力した出力、または承認後のゲート付き出力。
approvedユーザーが承認した場合は true。承認フローでのみ使用します。
deniedユーザーが拒否した場合は true。承認フローでのみ使用します。

継続処理のコンテキストには、ライブな会話履歴である messages と、1 つのターンに複数ある場合の すべての一時停止呼び出しを含む toolCalls も含まれます。

継続処理は純粋なままにしてください。再生成時には現在の会話履歴に対して再解決されるため、 判断が変わると別の分岐が生成されます。

クライアント配線

クライアント側では AI SDK をそのまま使用します。クライアント実行ツールの出力は addToolOutput で送信し、承認には addToolApprovalResponse で応答します。後続リクエストは sendAutomaticallyWhen に送信させます。

import {
  lastAssistantMessageIsCompleteWithApprovalResponses,
  lastAssistantMessageIsCompleteWithToolCalls,
} from "ai"
 
const { messages, addToolOutput, addToolApprovalResponse } = useChat({
  messages: chat.get(0),
  transport: chat.transport(),
  sendAutomaticallyWhen: (options) =>
    lastAssistantMessageIsCompleteWithToolCalls(options) ||
    lastAssistantMessageIsCompleteWithApprovalResponses(options),
})
// In a pending tool part renderer.
addToolOutput({
  tool: "askQuestions",
  toolCallId: part.toolCallId,
  output: { answers },
})
 
// In an approval-requested part renderer.
addToolApprovalResponse({ id: part.approval.id, approved: true })

継続は、一時停止したアシスタント メッセージの新しいステップとしてストリーミングされます。クライアントは新しいメッセージを追加する代わりに、そのパーツをメッセージにマージします。ヘルパーはステップ境界を出力し、継続のメッセージ ID を省略するため、マージが維持され、自動送信が再度トリガーされることもありません。

開発環境では、needsApproval の呼び出しに後続の継続ターンがない場合や、保留中のツール呼び出し なしで継続処理が解決された場合に、ヘルパーが警告します。


データ

data() を使用して、型指定された data-* 部分を追加します。

type DataParts = {
  weather: {
    city: string
    status: "loading" | "success"
    temperature?: number
    condition?: string
  }
}
 
const chat = createChat<UIMessage<unknown, DataParts>>().assistant(
  ({ writer }) => {
    writer.data({
      type: "data-weather",
      id: "weather-sf",
      data: { city: "San Francisco", status: "loading" },
    })
  }
)

同じ type と id を再度送信すると、そのパーツを所定の位置で更新できます。読み込み中から 成功へ状態を更新する場合などに便利です。

writer.data({
  type: "data-weather",
  id: "weather-sf",
  data: {
    city: "San Francisco",
    status: "success",
    temperature: 27,
    condition: "Breezy",
  },
})

クライアントにはストリーミングするものの最終メッセージには残さない更新には、 transient: true を設定します。

writer.data({
  type: "data-weather",
  data: { city: "San Francisco", status: "loading" },
  transient: true,
})

ファイル

files オプションを使ってユーザー メッセージにファイルを追加します。

chat.user("Summarize this report.", {
  files: [
    {
      filename: "report.pdf",
      mediaType: "application/pdf",
      url: "https://example.com/report.pdf",
    },
  ],
})

file() を使ってアシスタント メッセージにファイルを追加します。

chat.assistant(({ writer }) => {
  writer.file({
    filename: "summary.md",
    mediaType: "text/markdown",
    url: "https://example.com/summary.md",
  })
})

推論パーツにファイルを添付するには reasoningFile() を使います。

writer.reasoningFile({
  filename: "notes.txt",
  mediaType: "text/plain",
  url: "https://example.com/notes.txt",
})

ソース

sourceUrl() を使って URL ソースを追加します。

writer.sourceUrl({
  sourceId: "source-1",
  title: "Release notes",
  url: "https://example.com/releases",
})

sourceDocument() を使用してドキュメント ソースを追加します。

writer.sourceDocument({
  sourceId: "source-2",
  title: "Product brief",
  mediaType: "application/pdf",
  filename: "brief.pdf",
})

ステップ開始

stepStart() を使用して AI SDK ステップ境界を追加します。

chat.assistant(({ writer }) => {
  writer.stepStart()
  writer.reasoning("I should search the release notes.")
  writer.stepStart()
  writer.text("Here is what changed.")
})

カスタム パーツ

custom() を使ってカスタム パーツを追加します。

chat.assistant(({ writer }) => {
  writer.custom("app.approval")
})

メッセージには指定した kind を持つ custom パーツが追加されます。AI SDK では、kind に {provider}.{provider-type} 形式を使用します。kind なしで custom() を呼ぶと "test.output" が使われます。


メッセージを読む

get() を使うと、会話の先頭からメッセージを取得できます。

chat.get() // Every message.
chat.get(2) // The first two messages.
chat.get(0) // An empty initial conversation.

get() はメッセージの複製を返し、チャットを変更しません。継続処理はライブな会話履歴なしでは メッセージを持たないため、最初の継続ターンの前で停止します。count が実際の メッセージ数を超えると例外が発生します。

next() を使うと、すでに表示したメッセージの次にある定義済みユーザー メッセージを取得できます。

const initialMessages = chat.get(2)
const nextMessage = chat.next(initialMessages)

next() は、インデックスではなく、常にメッセージ トランスクリプトを受け入れます。次の ユーザー メッセージが使用されるか、何も残っていない場合は null が使用されます。


既存のメッセージから開始する

保存した会話やフィクスチャから続行するには messages を渡します。

import { createChat } from "@shadcn/helpers/ai-sdk"
import type { UIMessage } from "ai"
 
declare const savedMessages: UIMessage[]
 
const chat = createChat({ messages: savedMessages })
  .user("What should we do next?")
  .assistant("Turn the open questions into a checklist.")

既存の ID、メタデータ、パーツは保持されます。


トランスポート

transport() は、useChat に直接渡せる AI SDK の ChatTransport を作成します。

const transport = chat.transport()
 
const { messages, sendMessage } = useChat({
  messages: chat.get(0),
  transport,
})

sendMessage() が実行されると、トランスポートは現在の会話履歴に続くアシスタント メッセージを 見つけ、通常の AI SDK チャット ライフサイクルを通してストリーミングします。まずメッセージ ID で照合し、見つからない場合は最新メッセージのロールとテキストで照合します。ツール結果や承認 応答の後に自動送信されるリクエストは次の継続処理を解決します。メッセージ ID で ターンを再生するのは再生成の場合だけです。

オプション

オプション型デフォルト説明
delayMsnumber50テキストと推論の差分の間隔。0 または undefined で無効化します。
fallbackstring、UIMessagePart[]、またはコールバックなし事前定義されたアシスタント応答が残っていない場合のストリームへの応答。

トランスポート レベルの delayMs は、すべてのストリーミングされるテキストと推論パーツの デフォルト値です。1 つのパーツだけ変更するには、writer.text(..., { delayMs }) または writer.reasoning(..., { delayMs }) を使います。

const transport = chat.transport({
  delayMs: 25,
})

フォールバック

定義済みのアシスタント応答が残っていない場合は fallback を使います。定義済みの応答を使い 切った後もデモを利用できるようになります。

const transport = chat.transport({
  fallback: "This demo has no more predefined replies.",
})

フォールバックには、AI SDK メッセージ パーツの配列やライター コールバックも指定できます。 コールバックには受信した会話履歴が渡されるため、現在の状態から応答を作成できます。

const transport = chat.transport({
  fallback: ({ writer, messages }) => {
    writer.text(`This example already has ${messages.length} messages.`, {
      mode: "instant",
    })
  },
})

フォールバック応答はアシスタント応答と同様にストリーミングされますが、定義済みの会話には 追加されません。フォールバックがない状態で会話が終了すると、トランスポートは "No assistant response found for this transcript." をスローします。

useChat から stop() を呼び出すと、アクティブなトランスポート ストリームが中止されます。 再接続には対応していません。reconnectToStream() は null を返します。


タイミング

遅延を使うと、実際の応答のテンポを再現できます。

const chat = createChat()
  .user("Give me a project update.")
  .sleep(800)
  .assistant(({ writer }) => {
    writer.text("The first milestone is complete.", { mode: "instant" })
    writer.sleep(500)
    writer.text(" The next one is ready.")
  })
 
const transport = chat.transport({ delayMs: 50 })
  • chat.sleep(ms) は、次のアシスタント応答が始まる前に待機します。
  • writer.sleep(ms) は、アシスタント応答のパーツ間で待機します。
  • tool.sleep(ms) は、ツールの入力とその結果の間で待機します。
  • transport({ delayMs }) は、テキストと推論の差分間隔のデフォルト値を設定します。
  • writer.text(text, { delayMs }) と writer.reasoning(text, { delayMs }) は、1 つの パーツだけその間隔を上書きします。
  • mode: "instant" は、テキストまたは推論パーツ全体を 1 回の差分で送信します。

高速なテストでは、chat.transport({ delayMs: 0 }) と即時テキストを使用します。


エラー

アシスタント応答全体を失敗させるには、チャットで error() を使います。

const chat = createChat()
  .user("Load the report.")
  .error("The report could not be loaded.")

他のパーツをストリーミングした後に失敗させるには、writer.error() を使います。

chat.assistant(({ writer }) => {
  writer.text("I found the report.")
  writer.error("The connection closed before it could be read.")
})

メタデータと ID

個別のメッセージにメタデータを渡します。メタデータの型は get()、next()、トランスポートを 通して保持されます。

type Metadata = {
  model: string
}
 
const chat = createChat<UIMessage<Metadata>>()
  .user("Hello", { metadata: { model: "demo" } })
  .assistant("Hi.", {
    id: "assistant-welcome",
    metadata: { model: "demo" },
  })

フィクスチャにカスタム プレフィックスまたは固定クロックが必要な場合は、チャット オプションを使用します。

const chat = createChat({
  messageIdPrefix: "demo-message",
  toolCallIdPrefix: "demo-tool",
  sourceIdPrefix: "demo-source",
  now: "2026-01-01T00:00:00.000Z",
})

API リファレンス

上記のセクションでは一般的なフローを説明しました。このリファレンスには、すべての公開されている エクスポートとオプションを一覧にしています。

createChat()

型付きの会話を作成し、メソッドをチェーンできるチャット インターフェースを返します。

function createChat<UI_MESSAGE extends UIMessage = UIMessage>(
  options?: CreateChatOptions<UI_MESSAGE>
): AiSdkChat<UI_MESSAGE>

型パラメーター

パラメーター説明
UI_MESSAGE会話の UIMessage タイプ。useChat が受け入れるのと同じタイプ パラメータ。一度定義して共有します。

メッセージ型には、メタデータの形、型付きの data-* パーツ、ツール定義が含まれます。

type ChatMessage = UIMessage<Metadata, DataParts, Tools>

オプション

オプションタイプデフォルト説明
messagesUIMessage[][]既存の会話履歴から開始します。メッセージは複製されます。
messageIdPrefixstring"msg"生成するメッセージ ID のプレフィックス。
toolCallIdPrefixstring"call"生成するツール呼び出し ID のプレフィックス。
sourceIdPrefixstring"source"生成するソース ID のプレフィックス。
nowDate | string"2026-01-01T00:00:00.000Z"生成する createdAt メタデータに使う固定時刻。

messages 内にある ID は予約されるため、新しく生成する ID は既存の会話履歴の続きから始まります。

AiSdkChat

コンテンツを追加するすべてのメソッドは同じチャットを返すため、呼び出しをチェーンできます。

メソッド戻り値説明
user(text?, options?)AiSdkChatテキストと任意のファイルを含むユーザー メッセージを追加します。
assistant(input?, options?)AiSdkChatテキスト、パーツ、またはライター コールバックからアシスタント メッセージを追加します。
sleep(delayMs)AiSdkChat次のアシスタント応答が始まる前に待機します。
error(errorText?)AiSdkChatエラーを発生させるアシスタント応答を追加します。
get(count?)UIMessage[]会話の開始時から複製したメッセージを返します。
next(messages)UIMessage | null会話履歴の次にある定義済みユーザー メッセージを返します。
transport(options?)ChatTransportuseChat が使うトランスポートを作成します。

user() または assistant() を内容なしで呼ぶと "Summarize the uploaded receipt." が使われます。 メッセージなしで error() を呼ぶと "An error occurred." が使われます。count が負数または 整数でない場合、get(count) は例外を発生させます。

user() オプション

オプション型説明
idstring特定のメッセージ ID を使用します。
metadataMETADATAこのメッセージのメタデータを設定します。
filesFilePayload[]ユーザーのテキスト パーツの後にファイル パーツを追加します。

ユーザー ファイルの形式は次のとおりです。

type FilePayload = {
  type?: "file"
  mediaType: string
  url: string
  filename?: string
  providerMetadata?: Record<string, unknown>
}

assistant() の入力

入力結果
string単語ごとにストリーミングされる 1 つのテキスト部分。
UIMessagePart[]既存の順序でストリーミングされる静的な AI SDK パーツ。
({ writer }) => voidパーツ、ツール、エラー、タイミングを定義する同期コールバック。一時停止したターンの後は継続処理になり、toolCall、toolCalls、messages を受け取ります。

assistant() オプション

オプション型説明
idstring特定のメッセージ ID を使用します。
metadataMETADATAこのメッセージのメタデータを設定します。

transport() オプション

オプション型デフォルト説明
delayMsnumber50テキストと推論の差分の間隔。0 または undefined で無効化します。
fallbackstring | UIMessagePart[] | ({ writer, messages }) => voidなし定義済みのアシスタント応答が残っていない場合に使う応答。

照合、フォールバック、中止、ストリーミングの動作についてはトランスポートを 参照してください。

ライター

ライターは assistant(({ writer }) => {}) とフォールバック コールバック内で使用できます。

メソッド説明
text(text?, options?)テキスト パーツを追加します。
reasoning(text?, options?)推論パーツを追加します。
tool(name, options?)型付きまたは動的なツール呼び出しを追加し、そのライフサイクル ハンドルを返します。
data(part)型付きデータ パーツを追加または更新します。
file(options?)ファイル パーツを追加します。
reasoningFile(options?)推論ファイル パーツを追加します。
sourceUrl(options?)URL ソース パーツを追加します。
sourceDocument(options?)ドキュメント ソース パーツを追加します。
stepStart()AI SDK ステップ境界を追加します。
custom(kind?)指定した kind のカスタム パーツを追加します。
sleep(delayMs)次のライター イベントまで待機します。
error(errorText?)エラーを発行し、finish チャンクなしで応答を終了します。

内容なしで text() を呼ぶと "Summarize the uploaded receipt." が使われます。内容なしで reasoning() を呼ぶと "I need to inspect the available context before answering." が使われます。 error() は "An error occurred." を使用します。

テキストと推論のオプション

オプション型デフォルト説明
idstring生成値安定したパーツ ID を使用します。
delayMsnumberトランスポートこのパーツのトランスポート遅延を上書きします。
mode"stream" | "instant""stream"単語単位で差分をストリーミングするか、パーツ全体を 1 回の差分で送信します。

ツール オプション

オプション型説明
toolCallIdstring特定のツール呼び出し ID を使用します。
titlestringツール パーツに表示用タイトルを追加します。
toolMetadataRecord<string, unknown>プロバイダーまたはアプリケーションのメタデータを追加します。
providerExecutedbooleanプロバイダーによって実行された呼び出しとして記録します。
inputTOOLS[NAME]["input"]型付きツール入力を設定します。
outputTOOLS[NAME]["output"]型付きの出力で直ちに完了します。needsApproval の場合は承認後にストリーミングします。
errorTextstringエラーで直ちに完了します。needsApproval の場合は承認後にストリーミングします。
dynamicbooleantool-<name> の代わりに dynamic-tool パーツを出力します。
needsApprovalbooleanユーザーの決定の後にターンを一時停止します。 ヒューマン・イン・ザ・ループ を参照してください。
approvalIdstring特定の承認 ID を使用します。

tool() は sleep(delayMs)、output(value)、error(errorText?)、denied() を持つハンドルを 返します。入力と結果の間にイベントが必要な場合は、このハンドルを使用します。メッセージなしで tool.error() を呼ぶと "Tool call failed." が使われます。needsApproval を指定した呼び出し では、解決メソッドが例外を発生させます。

データ入力

writer.data({
  type: "data-name",
  id: "optional-id",
  data: value,
  transient: false,
})

同じ type と id を繰り返すと、以前のデータ パーツが置き換えられます。transient パーツは クライアントへストリーミングされますが、get() が返す最終メッセージには含まれません。

ファイルとソースのオプション

メソッドフィールド
file()mediaType?, url?, filename?, providerMetadata?
reasoningFile()mediaType?、url?、filename?、providerMetadata?
sourceUrl()sourceId?, url?, title?, providerMetadata?
sourceDocument()sourceId?, mediaType?, title?, filename?, providerMetadata?

これらのメソッドは、省略されたフィールドにサンプル用のデフォルト値を設定します。コンポーネントや テストでペイロードの内容が重要な場合は、明示的な値を渡してください。

型

エクスポート説明
AiSdkChatcreateChat() が返す、メソッドをチェーンできる型付きチャット。
CreateChatOptionscreateChat() が受け取るオプション。