인월드 실시간 음성
그만큼InworldRealtimeVoice클래스는 다음을 사용하여 실시간 전이중 음성 상호작용을 제공합니다.Inworld AI의 실시간 APIWebSocket을 통해. 음성 대 음성, Tool 호출 및 의미론적 음성 활동 감지, MCP Tool 라우팅 및 재생 속도와 같은 Inworld 관련 세션 노브를 지원합니다.
Inworld의 유선 프로토콜은 OpenAI Realtime GA 사양이므로 클라이언트 및 서버 이벤트 이름이 @mastra/voice-openai-realtime과 일치합니다. Provider 수준의 차이점은 엔드포인트(URL에서 클라이언트가 생성한 세션 키 사용), Authorization: Basic <key> 헤더, Inworld 전용 핸들을 위한 형식화된 생성자 session 필드, 그리고 Inworld 확장(STT, TTS, Memory, 백채널, 응답성)을 위한 형식화된 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이 열리기 전에 오류가 발생하거나 닫히는 경우 또는 이 제한 시간이 만료되는 경우, 포착되지 않은 소켓 오류 대신 거부된 프로미스로 노출됩니다.session(타이핑된 손잡이)session-typed-knobs에 대한 직접 링크
문서화된 Inworld 실시간 옵션에는 형식화된 session 필드를 사용하세요. 필드는 연결 시 기본값(예: 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는 8kHz로 고정됩니다.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(인월드 확장)providerdata-inworld-extensions에 대한 직접 링크
providerData는 Inworld 관련 실시간 확장을 위한 형식화된 객체입니다. 모든 session.update에서 session.providerData 아래에 전송되며, session 필드로 설정한 모든 session.providerData와 조합됩니다. 키가 충돌하면 생성자의 providerData가 우선합니다.
여기에는 5개의 분기와 2개의 세션 수준 필드가 있습니다.
stt:prompt,voice_profile,language_hints, VAD 또는 턴 종료 임계값 등의 STT 튜닝입니다.tts:segmenter_strategy,steering_handling,delivery_mode,conversational,user_turn_mode등의 TTS 분할 및 전달 설정입니다.memory:enabled,turn_interval,max_facts등의 자동 롤링 Memory입니다. 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초를 초과하는 핸드셰이크)는 포착되지 않은 소켓 오류 대신 거부된 프로미스로 노출됩니다. 거부되면 반쯤 열린 소켓이 닫힙니다.
await voice.connect()
보고:Promise<void>
speak()speak에 대한 직접 링크
Model에 텍스트 메시지를 보내고 오디오 응답을 트리거합니다. 반환된 프로미스는 전체 응답 수명 주기가 완료된 후(이 호출이 트리거한 응답의 response.done)에만 이행되며, 사용자 음성으로 응답이 중단되거나 전송 오류가 발생하면 거부됩니다.
순차적인 speak() 호출이 지원되는 패턴입니다. 동시 호출은 동일한 리스너 풀을 공유하며 응답 고정 순서가 정의되지 않습니다.
input:
options?:
speaker?:
보고:Promise<void>
listen()listen에 대한 직접 링크
사용자 차례에 따라 단일 오디오 버퍼를 보내고 Model에게 텍스트로만 응답하도록 요청합니다.
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에 대한 직접 링크
세션 중에 Model이 호출할 수 있는 Tool을 등록합니다. InworldRealtimeVoice가 Agent에 연결되면 Agent에 구성된 Tool을 자동으로 사용할 수 있습니다.
tools?:
보고:void
answer()answer에 대한 직접 링크
Model 응답을 트리거하기 위해 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에 대한 직접 링크
이벤트 리스너를 등록하고 제거합니다. 보다Events below.
이벤트이벤트에 대한 직접 링크
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:
목소리목소리에 대한 직접 링크
패키지에는 다음에서 반환된 선별된 음성 ID 세트가 포함되어 있습니다.getSpeakers():
DennisHadesWendyEdwardOliviaSarahTimothyPriyaRonaldDeborah
Inworld의 음성 카탈로그에 있는 모든 음성 ID를 런타임에 speaker로 전달할 수 있습니다.
메모메모에 대한 직접 링크
- API 키는 생성자 옵션 또는
INWORLD_API_KEY환경 변수를 통해 제공됩니다. 키는 미리 Basic 인코딩되어 있습니다. 다시 인코딩하지 마세요. - WebSocket URL에는
?key=<sessionId>&protocol=realtime이 추가됩니다. Model은 URL이 아니라 초기session.update를 통해 구성됩니다. - 호출별
speak(input, { speaker })는 음성 재정의를 단일 응답에만 적용하고(평면response.voice필드를 통해) 세션을 변경하지 않습니다. - 오디오 출력은 기본적으로 24kHz PCM16입니다. 8kHz 전화 통신용
audio/pcmu및audio/pcma, 그리고audio/float32도session.audio.output.format을 통해 지원됩니다. - send, speak 또는 listen을 호출하기 전에
connect()를 사용하세요. WebSocket이 열리기 전에 전송된 이벤트는 대기열에 저장되며 서버가session.updated를 확인하면 전송됩니다. - WebSocket을 해제하려면
close()또는disconnect()로 음성 인스턴스를 닫아야 합니다. session이audio.input.turn_detection을 제공하지 않으면 기본값은 의미론적 VAD입니다. 자체 객체로 재정의하거나null을 전달하여 턴 감지를 완전히 비활성화하세요.audio.input.transcription의 기본값은{ model: 'inworld/inworld-stt-1' }이므로 사용자 측writing이벤트가 별도 구성 없이 발생합니다. 자체 객체로 재정의하거나null을 전달하여 사용자 측 전사를 비활성화하세요.on()및off()는InworldVoiceEventMap을 기준으로 형식화됩니다. 알려진 이벤트 이름에는 형식화된 콜백 페이로드가 제공됩니다. 알 수 없는 이름은unknown으로 대체됩니다.