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 建構函式欄位,以及用於 Inworld 擴充功能(STT、TTS、記憶體、反饋語和回應速度)的具型別 providerData 物件;此物件會在 session.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 Realtime 選項。欄位會與連線時的預設值組合(例如從 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 特定 Realtime 擴充功能的具型別物件。每次 session.update 都會在 session.providerData 下傳送,並與你透過 session 欄位設定的任何 session.providerData 組合;若金鑰衝突,以建構函式的 providerData 為準。
它包含五個分支和兩個工作階段層級的欄位:
stt:STT 微調,例如prompt、voice_profile、language_hints,以及 VAD 或對話輪次結束閾值。tts:TTS 分段和表達,例如segmenter_strategy、steering_handling、delivery_mode、conversational和user_turn_mode。memory:自動捲動記憶體,例如enabled、turn_interval和max_facts。Inworld 會透過memory事件回傳其狀態。backchannel:使用者說話時的簡短反饋語(「嗯哼」)。音訊會透過backchannel事件抵達。responsiveness:主要回應產生時提早播放的填充音訊。填充音訊會重複使用一般的speaker和speaking事件,因此沒有獨立事件。user_id和metadata:傳遞給 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() 和 disconnect()「close-and-disconnect」的直接連結
這兩種方法都會關閉 WebSocket,並將執行個體標記為已中斷連線。
傳回:void
getSpeakers()「getspeakers」的直接連結
傳回套件內附的精選語音清單。Inworld 的目錄比此清單更大;執行階段可將任何語音 ID 傳入 speaker。
傳回:Promise<Array<{ voiceId: string }>>
on() 和 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。