メインコンテンツへ移動

LiveKit

@mastra/livekit パッケージは、Mastra Agent を LiveKit Agents フレームワークに接続します。LiveKit が音声パイプライン(Voice Activity Detection、Speech-to-Text、ターン検出、Text-to-Speech、割り込み)を実行し、このパッケージが応答生成を Mastra Agent の stream() 呼び出しに橋渡しします。

セットアップと概念については、リアルタイム Voiceを参照してください。

パッケージには3つのエントリーポイントがあります。

createLiveKitWorker()
createlivekitworkerへの直接リンク

Mastra Agent で Voice セッションに応答する LiveKit Agent 定義を構築します。Worker エントリーファイルのデフォルトエクスポートとして使用します。

src/mastra/voice-worker.ts
import { fileURLToPath } from 'node:url'
import { createLiveKitWorker, runLiveKitWorker } from '@mastra/livekit/worker'
import { mastra } from './index'

export default createLiveKitWorker({
mastra,
agent: 'support',
stt: 'deepgram/nova-3',
tts: 'cartesia/sonic-3',
turnDetection: 'multilingual',
})

if (process.argv[1] === fileURLToPath(import.meta.url)) {
runLiveKitWorker({ entry: import.meta.url, agentName: 'mastra-voice' })
}

オプション
オプションへの直接リンク

mastra:

Mastra
Voice セッションを処理する Agent を持つ Mastra インスタンス。

agent?:

string | (args) => string | Agent | Promise<string | Agent>
各セッションに応答する Mastra Agent。固定の Agent キー/ID、または Dispatch メタデータと Job コンテキストを使用してセッションごとに呼び出す Resolver。デフォルトは Dispatch メタデータの agentId です。

workflow?:

string | Workflow | (args) => string | Promise<string>
Agent の代わりに Mastra Workflow で各ターンの応答を生成します。Workflow インスタンス、固定の Workflow キー/ID、またはセッションごとに Workflow ID を返す Resolver を指定します。Workflow はターンごとに1回、完了まで実行されます(suspend/resume はありません)。agent とは同時に指定できず、workflowInput が必要です。

workflowInput?:

(args: VoiceTurnContext & { metadata }) => unknown | Promise<unknown>
ターンを Workflow の inputData にマッピングします。workflow を設定した場合は必須です。各ターンで完全な文字起こしを渡すステートレスなマッピングにより、Workflow で会話状態を保持せずに済みます。

replyStep?:

string
この Workflow Step ID のテキストだけをストリーミングします。デフォルトは writer に書き込むすべての Step です。

resultText?:

(result: unknown) => string | undefined
Workflow が writer 経由でテキストをストリーミングしない場合のフォールバック。最終実行結果から発話応答を取得します。

generate?:

VoiceReplyGenerator
最下層のエスケープハッチ。任意の応答 Generator(カスタム Workflow、リモートブリッジなど)を直接指定します。

stt?:

STT | string
Speech-to-Text。LiveKit プラグインインスタンスまたは 'deepgram/nova-3' などの推論モデル文字列。呼び出しごとに選択するには configuration.stt Resolver を設定します。Resolver が優先され、このオプションがフォールバックになります。

tts?:

TTS | string
Text-to-Speech。LiveKit プラグインインスタンスまたは 'cartesia/sonic-3' などの推論モデル文字列。呼び出しごとに選択するには configuration.tts Resolver を設定します。Resolver が優先され、このオプションがフォールバックになります。

vad?:

VAD | 'silero' | false
= 'silero'
Voice Activity Detection。'silero' は prewarm 中に @livekit/agents-plugin-silero から Silero VAD を読み込みます。独自のものを使用するにはインスタンスを渡し、無効にするには false を渡します。

turnDetection?:

'multilingual' | 'english' | TurnDetectionMode
ターン終了検出。'multilingual' と 'english' は @livekit/agents-plugin-livekit から LiveKit の Semantic Turn Detector を読み込みます。'vad'、'stt'、'manual' などのその他の値はそのまま渡されます。

turnHandling?:

Partial<TurnHandlingOptions>
ターン処理の調整。エンドポイント遅延、中断感度、先行生成を設定します。ここで設定しない限り、Worker は preemptiveGeneration を無効にします。先行生成を試みるたびに Mastra Agent が再実行され、重複するユーザーメッセージが永続化されるためです。

sessionOptions?:

Partial<AgentSessionOptions>
このヘルパーが構築する設定に統合する追加の LiveKit AgentSession オプション。

memory?:

false | ((args) => { thread, resource } | false)
Memory マッピング。解決された Agent に Memory が設定されている場合、デフォルトは { thread: metadata.threadId ?? room name, resource: metadata.resourceId ?? thread } です。無効にするには false、カスタマイズするには関数を渡します。

toolFeedback?:

(toolCall) => string | undefined
Mastra Agent が応答途中で Tool 呼び出しを開始したときに呼び出されます。Tool の実行中に発話する短いフレーズを返します。

onTurnComplete?:

(ctx: VoiceTurnCompleteContext) => void | Promise<void>
Text-to-Speech への応答ストリーミング完了後、ターンごとに1回呼び出されます。音声パス外で実行され、await されません。コンテキストには生成された応答(text、toolCalls、interrupted、usage)と解決済みの Memory マッピングが含まれます。

configuration?:

LiveKitWorkerConfiguration
グループ化された会話およびコンプライアンス設定。冒頭の挨拶と AI 開示、同意要件、Agent による通話終了、通話ごとの STT/TTS 選択を設定します。
LiveKitWorkerConfiguration

greeting?:

GreetingConfiguration
冒頭の挨拶と AI 開示。text(固定文字列またはテナントごとの挨拶用の通話ごとの Resolver)、allowInterruptions、awaitPlayout、persist、repeatEvery と repeatText による定期的な再開示を設定します。

consentPolicy?:

ConsentConfiguration
名前付き要件(summaryStorage から始まる)としての通話同意ポリシー。宣言的なだけで、Worker 自体は何もブロックしません。createConsentTool で実行時に許可を取得し、独自コードで適用します。宣言したポリシーは照合用に onCallEnd で公開されます。

endCall?:

EndCallConfiguration
Agent による通話終了。Worker は各ターンで通話終了 Tool(createEndCallTool と組み合わせます)を監視し、Agent の終了メッセージの再生完了を待ってから切断し、その過程で onCallEnd を実行します。

stt?:

(context: VoiceCallContext) => STT | string | undefined
通話ごとの Speech-to-Text。接続後、通話ごとに { metadata, requestContext, roomName, ctx } を指定して1回呼び出される Resolver で、トップレベルの stt オプションが受け付ける任意の値を返します。トップレベルの stt にフォールバックするには undefined を返します。Resolver は通話セットアップ中に実行されるため、プラグインインスタンスを通話間でキャッシュしてください。

tts?:

(context: VoiceCallContext) => TTS | string | undefined
通話ごとの Text-to-Speech。接続後、通話ごとに { metadata, requestContext, roomName, ctx } を指定して1回呼び出される Resolver で、トップレベルの tts オプションが受け付ける任意の値を返します。テナントごとに1つの Voice または言語を指定できます。トップレベルの tts にフォールバックするには undefined を返します。プラグインインスタンスを通話間でキャッシュしてください。

greeting?:

string
セッション開始時に発話する静的な挨拶。非推奨:configuration.greeting.text を優先してください。

persistGreeting?:

boolean
= true
発話した挨拶をアシスタントメッセージとして Memory Thread に保存し、保存済み Thread を正確な通話文字起こしにします。挨拶を設定し、Memory が有効な場合だけ適用されます。非推奨:configuration.greeting.persist を優先してください。

observability?:

boolean
= true
Mastra インスタンスに Observability が設定されている場合、各通話を Trace します。セッションごとに voice call Span を開き、各ターンの Agent 実行をその下にネストします。LiveKit の STT、TTS、発話終了、VAD、LLM レイテンシーのメトリクスが子 Span となり、モデルごとの使用量集計とともに Span を閉じます。無効にするには false を渡します。

inputOptions?:

Partial<RoomInputOptions>
session.start() に渡す LiveKit Room 入力オプション。

outputOptions?:

Partial<RoomOutputOptions>
session.start() に渡す LiveKit Room 出力オプション。

onSessionStart?:

(args: { session, ctx, agent, metadata }) => void | Promise<void>
セッション開始後に呼び出されます。ここでイベントリスナーを設定するか、応答を開始します。

runLiveKitWorker()
runlivekitworkerへの直接リンク

Worker エントリーファイル用の LiveKit Worker CLI(devstartconnect サブコマンド)を起動します。Worker 定義をデフォルトエクスポートするファイルから呼び出し、直接実行した場合だけ動作するようにガードします。@livekit/agentscli.runApp の代わりにこのヘルパーを使用すると、Worker ランタイムとブリッジが LiveKit SDK の同じコピーを共有することが保証されます。

オプション
オプションへの直接リンク

entry:

string | URL
Agent 定義をデフォルトエクスポートする Worker エントリーモジュール。import.meta.url を渡します。

agentName?:

string
= 'mastra-voice'
明示的な Dispatch に使用する LiveKit Agent 名。

serverOptions?:

Partial<ServerOptions>
このヘルパーが構築する設定に統合する追加の LiveKit ServerOptions。

pipeAgentReplyToWriter()
pipeagentreplytowriterへの直接リンク

Workflow の応答パスで、Mastra Agent の応答を Workflow Step の writer にストリーミングします。Agent のテキスト差分を転送するため、完全な応答の準備前に Text-to-Speech が開始されます。また Tool 呼び出しチャンクも転送するため、toolFeedback が発生し、onTurnComplete で Tool 一覧を確認できます。stream.textStream だけをパイプすると Tool 呼び出しが通知なしで失われます。Step の abortSignalagent.stream() に渡し、割り込み時に生成をすぐ停止できるようにしてください。

src/mastra/workflows/phone-conversation.ts
import { pipeAgentReplyToWriter } from '@mastra/livekit'

const generateResponse = createStep({
id: 'generateResponse',
// input and output schemas omitted
execute: async ({ inputData, mastra, writer, abortSignal }) => {
const stream = await mastra.getAgent('support').stream(inputData.turn, { abortSignal })
const reply = await pipeAgentReplyToWriter(stream, writer)
return { reply }
},
})

戻り値:Promise<string>。蓄積された応答テキスト。

パラメーター
パラメーターへの直接リンク

agentStream:

AgentReplyStreamLike
agent.stream() が返すストリーム。fullStream 非同期 Iterable を公開する任意のオブジェクト。

writer:

WritableStream<unknown>
Workflow Step の writer。

chatContextToMessages()
chatcontexttomessagesへの直接リンク

LiveKit Chat コンテキストを、指示と関数呼び出しを除いた agent.stream() が受け付けるプレーンメッセージに変換します。完全な文字起こしをステートレスな Workflow に渡すため、workflowInput で使用します。

src/mastra/voice-worker.ts
import { createLiveKitWorker, chatContextToMessages } from '@mastra/livekit/worker'

export default createLiveKitWorker({
mastra,
workflow: 'phoneConversation',
workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }),
})

戻り値:VoiceTurnMessage[]。各要素は { role: 'system' | 'user' | 'assistant'; content: string; id?: string } です。

MastraLLM
mastrallmへの直接リンク

Mastra Agent を基盤とする標準 LiveKit LLM プラグイン(llm.LLM)です。独自に voice.AgentSession を構築し、llm スロットで Mastra を使用する場合に利用します。マネージドな代替手段は createLiveKitWorker() です。選択方法については、Mastra を LLM コンポーネントとして使用するを参照してください。

remote を指定すると、プラグインは Server-Sent Events(SSE)を使用し、Mastra サーバーから HTTP 経由で各ターンをストリーミングします。Agent ループ、Tool、Memory はサーバー側で実行され、Agent を中断するとサーバー側の生成も中止されます。

src/mastra/voice-worker-plugin.ts
import { voice } from '@livekit/agents'
import { MastraLLM } from '@mastra/livekit/plugin'

const session = new voice.AgentSession({
llm: new MastraLLM({
remote: { baseUrl: process.env.MASTRA_URL!, agentId: 'support' },
memory: { thread: callId, resource: userId },
}),
stt: 'deepgram/nova-3',
tts: 'cartesia/sonic-3',
// Required with `memory`: LiveKit enables preemptive generation by default.
turnHandling: { preemptiveGeneration: { enabled: false } },
})

プラグインは providermastramodel を Agent ID として報告するため、LiveKit のメトリクスとフォールバックアダプターはほかの LLM と同様に識別します。

コンストラクターオプション
コンストラクターオプションへの直接リンク

remoteagentgenerate のいずれか1つだけを応答ソースとして指定します。

remote?:

RemoteMastraAgentOptions
HTTP 経由で接続するリモート Mastra サーバー。createRemoteAgentReplyGenerator() と同じ接続オプション(baseUrl、agentId、apiPrefix、headers、fetch、timeoutMs、retries、body)を受け取ります。

agent?:

Agent
プロセス内の Mastra Agent。2つ目のデプロイなしでセッションを所有します。

generate?:

VoiceReplyGenerator
カスタム応答ソース。generate ソースは独自の Hook を所有します。以下の toolFeedback、onToolCall、onTurnComplete は remote と agent ソースだけに適用されます。

memory?:

{ thread: string; resource?: string } | false
= false
通話ごとに解決される会話の永続化(SIP 発信者 ID からの解決など)。設定すると、Agent の最後の発話以降の新しいメッセージだけが各ターンで送信され、履歴は Mastra Memory が提供します。省略すると、各ターンで完全な LiveKit Chat コンテキストが送信されます。

requestContext?:

RequestContext | Record<string, unknown>
生成へ転送するリクエストコンテキスト(テナント、ダイヤル番号など)。

toolFeedback?:

(toolCall: VoiceToolCall) => string | undefined
サーバー側 Tool の実行中に発話する短いフレーズを返します。

onToolCall?:

(toolCall: VoiceToolCall) => void
各 Tool 呼び出しがストリーム途中で開始されたときに呼び出されます。runEndCall() と組み合わせ、独自の Agent 主導の通話終了フローを実装します。

onTurnComplete?:

(ctx: VoiceTurnCompleteContext) => void | Promise<void>
応答ストリーミング完了後、ターンごとに1回、音声パス外で呼び出され、await されません。コンテキストには生成された応答(text、toolCalls、interrupted、usage)が含まれます。
警告

memory をセッションの preemptiveGeneration オプションと組み合わせないでください。独自に構築したセッションでは LiveKit がこのオプションをデフォルトで有効にします。LiveKit が破棄する前に先行ターンが完了すると、ユーザーメッセージと発話されなかった応答が Thread に永続化されます。セッションで turnHandling: { preemptiveGeneration: { enabled: false } } を設定してください。ステートレスモード(memory なし)は先行生成と併用できます。

Mastra Agent で実行する Tool
Mastra Agent で実行する Toolへの直接リンク

Tool は Mastra Agent のサーバー側で定義および実行されます。プラグインが LiveKit Tool 定義を転送することはありません。セッションが空でない toolCtx を渡すと、無視した Tool の名前を含む警告を1回記録します。すべての Tool はサーバー側で完了する必要があります。承認またはクライアント側の実行が必要な Tool は、通話を停止させる代わりに説明的なエラーでターンを失敗させます。

Tool のアクティビティは toolFeedbackonToolCallonTurnComplete を通じて Worker に届きます。

指示
指示への直接リンク

LiveKit は voice.Agentinstructions を各リクエストの Chat コンテキストに挿入します。サーバー側 Mastra Agent の指示が正となるため、プラグインはこれを破棄します。プロンプトを変更するには Mastra Agent を変更してください。

中断されたターン
中断されたターンへの直接リンク

ユーザーが応答を中断した場合:

  1. プラグインがストリームをキャンセルします。サーバーは生成を中止し、そのターンの内容を永続化しません。
  2. LiveKit はユーザーが実際に聞いた部分を、中断済みのフラグを付けて Chat コンテキストに記録します。
  3. 次のターンで、プラグインは聞こえた部分だけを新しいユーザーメッセージの前に再送信し、Memory Thread を通話に合わせて補完します。メッセージには LiveKit のメッセージ ID があり、サーバーは ID で重複排除するため、再試行と再送信は冪等です。

中断直後にユーザーが通話を終了すると、最後の断片は記録されません。文字起こしに含める必要がある場合は、セッションイベントからすぐに反映してください。共有メッセージ ID により、次のターンでの再送信は重複ではなく Upsert になります。

src/mastra/voice-worker-plugin.ts
import { voice } from '@livekit/agents'
import { MastraClient } from '@mastra/client-js'

const client = new MastraClient({ baseUrl: process.env.MASTRA_URL! })

session.on(voice.AgentSessionEventTypes.ConversationItemAdded, ({ item }) => {
if (item.type !== 'message' || item.role !== 'assistant' || !item.interrupted) return
void client.saveMessageToMemory({
agentId: 'support',
messages: [
{
id: item.id,
threadId: callId,
resourceId: userId,
role: 'assistant',
content: item.textContent ?? '',
type: 'text',
createdAt: new Date(),
},
],
})
})

使用量メトリクス
使用量メトリクスへの直接リンク

サーバーがターンのトークン使用量を報告すると、プラグインは LiveKit に渡します。そのため、セッションの metrics_collected イベントにはほかの LLM プラグインと同様に、最初のトークンまでの時間、所要時間、トークン数が含まれます。同じ使用量オブジェクト(promptTokenscompletionTokenspromptCachedTokenstotalTokens)が onTurnCompleteresult.usage として届きます。

エラーとタイムアウト
エラーとタイムアウトへの直接リンク

トランスポートは LiveKit の APIError 型(APIStatusErrorAPIConnectionErrorAPITimeoutError)をスローするため、セッションの再試行ポリシー(connOptions.maxRetry)と FallbackAdapter のフェイルオーバーはそのまま動作します。最初のトークン後にターンが再試行されることはありません。Voice 応答では、途中まで聞こえた内容を再生し直すよりも速やかに失敗する方が適切です。

接続と最初のトークンの Watchdog はセッションの connOptions.timeoutMs(デフォルト10秒)を使用するため、接続を受け入れてもストリーミングしないサーバーによって無音状態が無期限に続くことはありません。

通話途中で Mastra サーバーが停止すると、各応答の試行は再試行後に型付きエラーで失敗し、応答が数回連続で失敗すると LiveKit がセッションを閉じます。その上限に達する前にサーバーを復旧すれば、次のターンで通話が復旧します。

メッセージ内容
メッセージ内容への直接リンク

メッセージ抽出の対象はテキストだけです。画像コンテンツは破棄され、音声コンテンツは文字起こしだけが含まれます。Voice パイプラインには影響しませんが、Chat コンテキストに独自に挿入する項目にはテキストが必要です。

createRemoteAgentReplyGenerator()
createremoteagentreplygeneratorへの直接リンク

HTTP/SSE 経由でリモート Mastra サーバー上の Agent ループを実行する応答 Generator を構築します。MastraLLMremote モードが内部で使用します。createLiveKitWorkergenerate オプションから直接使用し、機能一式を備えた Worker をリモートサーバーに対して実行できます。

src/mastra/voice-worker.ts
import { createLiveKitWorker, createRemoteAgentReplyGenerator } from '@mastra/livekit/worker'
import { mastra } from './index'

export default createLiveKitWorker({
mastra, // local instance for logger and worker config; replies come from the remote server
generate: createRemoteAgentReplyGenerator({
baseUrl: process.env.MASTRA_URL!,
agentId: 'support',
}),
memory: ({ metadata, roomName }) => ({ thread: metadata.threadId ?? roomName }),
stt: 'deepgram/nova-3',
tts: 'cartesia/sonic-3',
})

generate パスでは Worker レベルの toolFeedbackonTurnComplete オプションは適用されず、Worker の通話終了検出も発生しません。代わりに Hook を Generator へ渡してください。

ターンのキャンセル(割り込み)は HTTP リクエストを破棄し、サーバー上の生成を中止します。エラーは LiveKit の APIError 型としてスローされます。retries オプションは最初の接続試行だけに適用されます。最初のチャンク後にターンが再試行されることはありません。

戻り値:VoiceReplyGenerator

オプション
オプションへの直接リンク

baseUrl:

string
リモート Mastra サーバーのベース URL(例:https://my-app.example.com)。

agentId:

string
リモート Mastra インスタンスに登録された Agent のキーまたは ID。

apiPrefix?:

string
= '/api'
Mastra API のパスプレフィックス。

headers?:

Record<string, string> | () => Record<string, string> | Promise<Record<string, string>>
静的ヘッダー、またはターンごとに呼び出す Resolver(新しい認証トークンの発行など)。

fetch?:

typeof fetch
= globalThis.fetch
テストまたは Proxy 用に注入可能な fetch 実装。

timeoutMs?:

number
= 10000
接続と最初のトークンのタイムアウト(ミリ秒)。MastraLLM 経由で使用する場合、デフォルトはセッションの connOptions.timeoutMs です。

retries?:

number
= 2
最初のチャンクより前の初期接続の再試行回数。MastraLLM 経由で使用する場合、LiveKit セッションが再試行を管理するため、0 に固定されます。

body?:

Record<string, unknown>
各ストリームリクエスト本文に統合する追加フィールド。

toolFeedback?:

(toolCall: VoiceToolCall) => string | undefined
サーバー側 Tool の実行中に発話する短いフレーズを返します。

onToolCall?:

(toolCall: VoiceToolCall) => void
各 Tool 呼び出しがストリーム途中で開始されたときに呼び出されます。

onTurnComplete?:

(ctx: VoiceTurnCompleteContext) => void | Promise<void>
応答ストリーミング完了後、ターンごとに1回、音声パス外で呼び出されます。

speakGreeting()
speakgreetingへの直接リンク

所有するセッションで、中断と再生オプションに従って冒頭の挨拶を発話します。LiveKit の SpeechHandle を返し、挨拶テキストがない場合は undefined を返します。createLiveKitWorker()greeting 設定で内部的に使用します。

import { speakGreeting } from '@mastra/livekit/worker'

await speakGreeting(session, {
text: "You've reached support. You're speaking with an AI assistant.",
allowInterruptions: false,
awaitPlayout: true,
})

パラメーター
パラメーターへの直接リンク

session:

voice.AgentSession
発話するセッション。

greeting:

{ text?: string; allowInterruptions?: boolean; awaitPlayout?: boolean }
挨拶テキストと再生オプション。awaitPlayout が true の場合、返された Promise は挨拶の再生完了後(または中断後)に解決します。

waitForAgentDoneSpeaking()
waitforagentdonespeakingへの直接リンク

Agent が応答の生成も再生も行わなくなり、状態が thinkingspeaking から移行すると解決します。Agent がすでにアイドル状態の場合は直ちに解決し、安全上の上限として常に maxWaitMs(デフォルト30秒)以内に解決します。終了メッセージが途中で切れずに再生されるよう、セッションを破棄する前に使用します。

import { waitForAgentDoneSpeaking } from '@mastra/livekit/worker'

await waitForAgentDoneSpeaking(session)

runEndCall()
runendcallへの直接リンク

Agent が通話終了を求めた後に通話を終了します。Agent の終了メッセージを待ち、省略可能な最後の message を中断なしで発話します。その後 Room を削除し、SIP 発信者を含む通話相手を切断します。Job は登録済みコールバックとともにシャットダウンします。

MastraLLMonToolCall およびサーバー側 Agent の通話終了 Toolと組み合わせ、所有するセッションで Agent 主導の通話終了を再構築します。

src/mastra/voice-worker-plugin.ts
import { MastraLLM } from '@mastra/livekit/plugin'
import { DEFAULT_END_CALL_TOOL, runEndCall } from '@mastra/livekit/worker'

let ending = false

const llm = new MastraLLM({
remote: { baseUrl: process.env.MASTRA_URL!, agentId: 'support' },
onToolCall: ({ toolName }) => {
if (toolName !== DEFAULT_END_CALL_TOOL || ending) return
ending = true
void runEndCall(session, ctx, {}, console)
},
})

エクスポートされる定数 DEFAULT_END_CALL_TOOL'endCall')、DEFAULT_END_CALL_REASONDEFAULT_END_CALL_MAX_WAIT_MS(30000)にはデフォルト値が格納されています。

パラメーター
パラメーターへの直接リンク

session:

voice.AgentSession
Agent が終了メッセージを終えようとしているセッション。

ctx:

JobContext
Room の削除とシャットダウンに使用する LiveKit Job コンテキスト。

config:

{ message?: string; reason?: string; maxWaitMs?: number; drainMs?: number }
通話終了前に発話する省略可能な最後のメッセージ、記録するシャットダウン理由、終了メッセージの待機時間の安全上限、Room 削除前に通話相手側でバッファリングされた音声の再生を完了させる再生後のドレイン(デフォルト800 ms)。LiveKit の再生時間計測は Worker ローカルであるため、完了直後に通話を終了すると挨拶が途切れます。

logger:

{ warn: (message: string, ...args: unknown[]) => void }
破棄 Step が失敗した場合に警告を受け取ります。Logger または console を渡します。

createEndCallTool()
createendcalltoolへの直接リンク

Agent が通話を終了するときに呼び出す Mastra Tool を構築します。Tool は意図を通知し、省略可能な記録処理を実行できます。実際の通話終了は Worker が行います。Tool はサーバーセーフなルートエントリーに存在します。サーバーコードで定義された Agent に追加してください。

src/mastra/agents/support-agent.ts
import { Agent } from '@mastra/core/agent'
import { createEndCallTool } from '@mastra/livekit'

const supportAgent = new Agent({
id: 'support',
name: 'Support',
instructions:
'Help the caller. When everything is wrapped up, say goodbye and call endCall as your final action.',
model: 'openai/gpt-5-mini',
tools: { endCall: createEndCallTool() },
})

createLiveKitWorker() では configuration: { endCall: {} } を設定すると、Worker が Tool を監視して通話を終了します。所有するセッションでは、runEndCall() を使用して通話終了を再構築します。

オプション
オプションへの直接リンク

id?:

string
= 'endCall'
Agent が通話終了時に呼び出す Tool ID。Worker が監視する名前(Worker の configuration.endCall.tool、または独自の onToolCall チェック)と一致する必要があります。

description?:

string
Tool の呼び出しを決定するときにモデルが参照する説明を上書きします。

onEndCall?:

(request: { reason?: string; resourceId?: string; threadId?: string }) => void | Promise<void>
Agent が Tool を呼び出したときに実行される記録用 Hook。理由を記録するか、通話を解決済みとしてマークします。ターン内で実行されるため、短時間で完了させてください。この Hook 自体は通話を終了しません。

liveKitConnectionRoute()
livekitconnectionrouteへの直接リンク

Voice Agent を Room に Dispatch した LiveKit アクセストークンを発行する API Route を返します。フロントエンドがセッションへの参加時に呼び出します。

src/mastra/index.ts
import { Mastra } from '@mastra/core/mastra'
import { liveKitConnectionRoute } from '@mastra/livekit'

export const mastra = new Mastra({
server: {
apiRoutes: [liveKitConnectionRoute({ agentName: 'mastra-voice' })],
},
})

Route は省略可能な agentIdthreadIdresourceId フィールドを含む JSON 本文を受け取り、{ serverUrl, roomName, participantName, participantToken } で応答します。threadId のデフォルトは生成された Room 名です。

オプション
オプションへの直接リンク

path?:

string
= '/voice/livekit/connection-details'
Route のパス。

serverUrl?:

string
= process.env.LIVEKIT_URL
LiveKit サーバー URL。

apiKey?:

string
= process.env.LIVEKIT_API_KEY
LiveKit API キー。

apiSecret?:

string
= process.env.LIVEKIT_API_SECRET
LiveKit API シークレット。

agentName?:

string
= 'mastra-voice'
明示的な Dispatch に使用する LiveKit Agent 名。Worker の agentName と一致する必要があります。

ttl?:

string | number
= '15m'
トークンの有効期間。

requiresAuth?:

boolean
= true
Route で認証が必要かどうか。

roomName?:

string | (args) => string
Room 名、またはリクエストから Room 名を取得する関数。

participantIdentity?:

string | (args) => string
参加者 ID、またはリクエストから参加者 ID を取得する関数。

metadata?:

(args) => LiveKitSessionMetadata | Promise<LiveKitSessionMetadata>
Worker に配信するセッションメタデータを構築します。デフォルトではリクエスト本文の agentId、threadId、resourceId をそのまま渡します。

dispatchVoiceSession()
dispatchvoicesessionへの直接リンク

Mastra Voice Agent をプログラムで LiveKit Room に Dispatch します。発信通話など、サーバーが開始するセッションに使用します。

import { dispatchVoiceSession } from '@mastra/livekit'

await dispatchVoiceSession({
roomName: 'support-call-42',
agentName: 'mastra-voice',
metadata: { agentId: 'support', threadId: 'thread-42' },
})

オプション
オプションへの直接リンク

roomName:

string
Agent を Dispatch する Room。必要に応じて作成されます。

agentName?:

string
= 'mastra-voice'
Worker の agentName と一致する必要があります。

metadata?:

LiveKitSessionMetadata
セッションメタデータ:agentId、threadId、resourceId、requestContext。

serverUrl?:

string
= process.env.LIVEKIT_URL
LiveKit サーバー URL。

apiKey?:

string
= process.env.LIVEKIT_API_KEY
LiveKit API キー。

apiSecret?:

string
= process.env.LIVEKIT_API_SECRET
LiveKit API シークレット。

LiveKitSessionMetadata
livekitsessionmetadataへの直接リンク

LiveKit Job Dispatch を通じて Mastra サーバーから Worker に渡されるメタデータです。

agentId?:

string
実行する Mastra Agent。登録済みのキーまたは Agent ID で指定します。

threadId?:

string
Memory Thread ID。デフォルトは LiveKit Room 名です。

resourceId?:

string
Memory Resource ID。通常はエンドユーザー ID です。

requestContext?:

Record<string, unknown>
Agent の実行時に RequestContext へ復元されるプレーンオブジェクトの項目。

メタデータは JSON 文字列として転送されます。liveKitConnectionRoute()dispatchVoiceSession() がシリアライズします。独自コードから Dispatch する場合は serializeSessionMetadata(metadata) を使用するか、SIP Dispatch ルールなどの LiveKit 側設定に JSON を直接記述します。requestContext の項目は、通話の各ターンで Agent の実行時定義の指示、Tool、Input Processor に届きます。