Inworld Realtime 語音
InworldRealtimeVoice 類別透過 WebSocket 使用 Inworld AI Realtime API,提供即時全雙工語音互動。它支援語音對語音、Tool 呼叫,以及語意語音活動偵測、MCP Tool 路由和播放速度等 Inworld 專用工作階段設定。
Inworld 的線路協定採用 OpenAI Realtime GA 規格,因此用戶端與伺服器事件名稱均與 @mastra/voice-openai-realtime 相符。Provider 層面的差異包括端點(在 URL 中使用由用戶端產生的工作階段密鑰)、Authorization: Basic <key> 標頭、用於 Inworld 專用設定且具型別的 session 建構函式欄位,以及在 session.providerData 下傳送、用於 Inworld 擴充功能(STT、TTS、記憶、回應聲和回應速度)且具型別的 providerData 物件。
如需批次文字轉語音及語音轉文字,請參閱 @mastra/voice-inworld。
使用範例使用範例 的直接連結
import { InworldRealtimeVoice } from '@mastra/voice-inworld'
import { playAudio, getMicrophoneStream } from '@mastra/node-audio'
// Initialize with INWORLD_API_KEY from the environment
const voice = new InworldRealtimeVoice()
// Or initialize with explicit configuration
const voiceWithConfig = new InworldRealtimeVoice({
apiKey: 'your-inworld-api-key',
model: 'inworld/models/gemma-4-26b-a4b-it',
speaker: 'Sarah',
instructions: 'You are a helpful voice assistant.',
session: {
audio: {
output: { speed: 1.1 },
input: { turn_detection: { type: 'semantic_vad', eagerness: 'high' } },
},
},
})
// Establish connection
await voice.connect()
// Listen for audio output (PCM16 @ 24 kHz by default)
voice.on('speaker', stream => {
playAudio(stream)
})
voice.on('writing', ({ text, role }) => {
console.log(`${role}: ${text}`)
})
// Convert text to speech
await voice.speak('Hello, how can I help you today?', {
speaker: 'Hades',
})
// Stream microphone audio to the model
const microphoneStream = getMicrophoneStream()
await voice.send(microphoneStream)
// Clean up
voice.close()
Inworld API 金鑰已預先以 Basic 編碼。請原封不動貼入
INWORLD_API_KEY。此套件不會重新編碼。
建構函式參數建構函式參數 的直接連結
apiKey?:
url?:
model?:
speaker?:
sessionId?:
key 參數的工作階段密鑰。省略時會自動產生以時間戳記為基礎的密鑰。instructions?:
session?:
debug?:
providerData?:
session 欄位設定的任何 session.providerData 組合;若鍵值衝突,以建構函式選項為準。connectTimeoutMs?:
connect() 等候 WebSocket 交握及初始 session.updated 往返的最長時間。WebSocket 開啟前發生錯誤或關閉,或此逾時期限屆滿,均會以被拒絕的 promise 呈現,而非未捕捉的 socket 錯誤。session(具型別的設定)session-typed-knobs 的直接連結
使用具型別的 session 欄位設定文件所列的 Inworld 即時選項。各欄位會與連線時的預設值組合(例如由 speaker 設定的 audio.output.voice):
output_modalities?:
audio.output.voice?:
speaker。audio.output.speed?:
audio.output.model?:
audio.output.format?:
{ type, rate? }。rate(Hz)適用於 audio/pcm 及 audio/float32(預設為 24000);audio/pcmu 及 audio/pcma 固定為 8 kHz。audio.input.format?:
audio.output.format 相同,可以是編解碼器字串或 { type, rate? } 物件。audio.input.noise_reduction?:
audio.input.transcription?:
{ model: "inworld/inworld-stt-1" }。prompt 會以詞彙、拼寫或風格提示引導轉錄。提供自訂物件即可覆寫;設為 null 可停用使用者端轉錄。audio.input.turn_detection?:
{ type: "semantic_vad", eagerness: "medium", create_response: true, interrupt_response: true }。提供自訂物件即可覆寫;設為 null 可完全停用輪次偵測。eagerness 欄位控制語意 VAD 結束使用者輪次的速度:low 會等待更明顯的停頓(較不易被中斷),high 會更快結束輪次(反應較快,但較容易打斷使用者)。預設的 medium 會平衡兩者。idle_timeout_ms(只適用於 server_vad)設定伺服器提交輪次前的閒置時限。tool_choice?:
temperature?:
max_output_tokens?:
truncation?:
tracing?:
include?:
prompt?:
providerData(Inworld 擴充功能)providerdata-inworld-extensions 的直接連結
providerData 是用於 Inworld 專用即時擴充功能且具型別的物件。每次 session.update 時都會在 session.providerData 下傳送,並與你透過 session 欄位設定的任何 session.providerData 組合;若鍵值衝突,以建構函式的 providerData 為準。
它有五個分支及兩個工作階段層級欄位:
stt: STT 微調,例如prompt,voice_profile,language_hints, and VAD or end-of-turn thresholds.tts: TTS 分段與傳送,例如segmenter_strategy,steering_handling,delivery_mode,conversational, anduser_turn_mode.memory: 自動滾動記憶,例如enabled,turn_interval, andmax_facts. Inworld 會透過memory事件回傳其狀態。backchannel: 使用者說話時的簡短回應聲(「嗯哼」)。音訊會透過backchannel事件送達。responsiveness: 產生主要回應期間提早播放的填充音訊。填充音訊會重用一般的speaker及speaking事件,因此沒有獨立事件。user_idandmetadata: 傳送至 Inworld 的工作階段層級識別資料。
const voice = new InworldRealtimeVoice({
providerData: {
stt: { voice_profile: true, language_hints: ['en-US'] },
tts: { delivery_mode: 'CREATIVE', segmenter_strategy: 'balanced' },
memory: { enabled: true, turn_interval: 4 },
backchannel: { enabled: true, max_per_turn: 1 },
user_id: 'user-123',
},
})
方法方法 的直接連結
connect()connect 的直接連結
開啟 WebSocket 連線、傳送初始 session.update,並在伺服器以 session.updated 確認後完成。必須在 speak()、listen() 或 send() 前呼叫。
WebSocket 開啟前發生的 error 或 close(或交握超過 connectTimeoutMs,預設為 15 秒)會以被拒絕的 promise 呈現,而非未捕捉的 socket 錯誤。拒絕時,半開啟的 socket 會關閉。
await voice.connect()
傳回: Promise<void>
speak()speak 的直接連結
向模型傳送文字訊息並觸發音訊回應。傳回的 promise 只會在完整回應生命週期完成後(即此呼叫所觸發回應的 response.done)完成;若回應被使用者語音中斷或發生傳輸錯誤,則會被拒絕。
支援的模式是依序呼叫 speak()。並行呼叫會共用同一個監聽器集區,而回應綁定次序並未定義。
input:
options?:
speaker?:
傳回: Promise<void>
listen()listen 的直接連結
將單一音訊緩衝區作為使用者輪次傳送,並要求模型只以文字回應。
audioData:
傳回: Promise<void>
send()send 的直接連結
即時串流音訊資料至伺服器,適合持續的咪高峰輸入。
audioData:
eventId?:
傳回: Promise<void>
updateConfig()updateconfig 的直接連結
向伺服器傳送 session.update。具型別的 session 欄位會深層合併至承載資料,而任何建構函式 providerData 都會置於 session.providerData 下。
sessionConfig:
傳回: void
addInstructions()addinstructions 的直接連結
設定下一次呼叫 connect() 或 updateConfig() 時使用的系統指示。
instructions?:
傳回: void
addTools()addtools 的直接連結
註冊模型可在工作階段期間呼叫的 Tool。當 InworldRealtimeVoice 附加至 Agent 時,為該 Agent 設定的 Tool 會自動提供。
tools?:
傳回: void
answer()answer 的直接連結
傳送 response.create 事件以觸發模型回應,亦可選擇加入每次回應的選項。
options?:
傳回: Promise<void>
輪流對話輪流對話 的直接連結
commitInput()commitinput 的直接連結
手動將已緩衝的輸入音訊提交為使用者輪次。當 turn_detection 設為 null 時,可用於按鍵通話或手動輪流對話。
voice.commitInput()
傳回: void
clearInput()clearinput 的直接連結
捨棄已緩衝的輸入音訊,不會提交為使用者輪次。
voice.clearInput()
傳回: void
clearOutput()clearoutput 的直接連結
清除伺服器的整個輸出音訊緩衝區並停止播放。這亦會停止任何正在傳送的回應聲音訊。預設插話路徑(於 interrupted 時執行 response.cancel)不會影響回應聲,應優先使用。只在你想清除所有內容時使用 clearOutput()。
voice.clearOutput()
傳回: void
close() and disconnect()close-and-disconnect 的直接連結
兩個方法都會關閉 WebSocket,並將執行個體標記為已中斷連線。
傳回: void
getSpeakers()getspeakers 的直接連結
傳回套件隨附的精選語音清單。Inworld 目錄包含更多語音;執行時可將任何語音 ID 傳給 speaker。
傳回: Promise<Array<{ voiceId: string }>>
on() and off()on-and-off 的直接連結
註冊及移除事件監聽器。請參閱下方的事件。
事件事件 的直接連結
InworldRealtimeVoice 類別會發出以下事件:
speaker:
speaking:
speaking.done:
writing:
speech-started:
input_audio_buffer.speech_started VAD 邊緣事件。speech-stopped:
input_audio_buffer.speech_stopped VAD 邊緣事件。interrupted:
response_id 發出一次。插話時可用它停止播放主要回應。回呼會收到 { response_id: string }。它只帶有主要回應 ID,絕不會帶有回應聲 ID,因此停止相符的 speaker 串流後,backchannel 串流仍會繼續播放(回應聲原本就會與使用者語音重疊,絕不會因插話而取消)。turn-suggestion:
turn-suggestion-revoked:
input-committed:
input-cleared:
input-timeout:
output-audio-started:
output-audio-stopped:
output-audio-cleared:
memory:
backchannel:
.id 都是絕不會出現在 interrupted 中的 backchannel_id,因此請在不會因插話而停止的獨立音軌上播放。需要 providerData.backchannel.enabled。backchannel.done:
backchannel.skipped:
response.created:
response.done:
conversation.item.added:
conversation.item.done:
function_call.arguments:
tool-call-start:
tool-call-result:
error:
語音語音 的直接連結
套件包含一組由 getSpeakers() 傳回的精選語音 ID:
DennisHadesWendyEdwardOliviaSarahTimothyPriyaRonaldDeborah
執行時可將 Inworld 語音目錄中的任何語音 ID 傳給 speaker。
注意事項注意事項 的直接連結
- API 金鑰可透過建構函式選項或
INWORLD_API_KEY環境變數提供。密鑰已預先以 Basic 編碼,請勿重新編碼。 - WebSocket URL 會附加
?key=<sessionId>&protocol=realtime。模型透過初始session.update設定,而非 URL。 - 每次呼叫的
speak(input, { speaker })會將語音覆寫限制於單一回應(透過扁平的response.voice欄位),不會變更工作階段。 - 音訊輸出預設為 24 kHz PCM16。亦可透過
session.audio.output.format使用 8 kHz 電話音訊audio/pcmu、audio/pcma及audio/float32。 - 在任何 send、speak 或 listen 呼叫前使用
connect()。WebSocket 開啟前傳送的事件會排入佇列,待伺服器確認session.updated後送出。 - 必須使用
close()或disconnect()關閉語音執行個體,以釋放 WebSocket。 - 若
session未提供,audio.input.turn_detection預設為語意 VAD。可使用自訂物件覆寫,或傳入null完全停用輪次偵測。 audio.input.transcription預設為{ model: 'inworld/inworld-stt-1' },因此使用者端writing事件無需額外設定即可觸發。可使用自訂物件覆寫,或傳入null停用使用者端轉錄。on()及off()以InworldVoiceEventMap定型。已知事件名稱會產生具型別的回呼承載資料;未知名稱則回退至unknown。