Voix Inworld Realtime
La classe InworldRealtimeVoice permet une interaction vocale bidirectionnelle simultanée en temps réel à l'aide de l'API Realtime d'Inworld AI via WebSockets. Elle prend en charge la conversation vocale, l'appel d'outils et des paramètres de session propres à Inworld, comme la détection sémantique de l'activité vocale, le routage des Tools MCP et la vitesse de lecture.
Le protocole de communication d'Inworld suit la spécification OpenAI Realtime GA. Les noms d'événements côté client et serveur correspondent donc à ceux de @mastra/voice-openai-realtime. Les différences propres au Provider concernent le point de terminaison (qui utilise dans l'URL une clé de session générée par le client), l'en-tête Authorization: Basic <key>, le champ de constructeur typé session pour les paramètres propres à Inworld et un objet typé providerData pour les extensions Inworld (STT, TTS, Memory, signaux d'écoute et réactivité), envoyé sous session.providerData.
Pour la synthèse vocale et la reconnaissance vocale par lots, consultez @mastra/voice-inworld.
Exemple d'utilisationLien direct vers Exemple d'utilisation
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()
Les clés d'API Inworld sont déjà encodées en Basic. Copiez-les telles quelles dans
INWORLD_API_KEY. Le package ne les réencode pas.
Paramètres du constructeurLien direct vers Paramètres du constructeur
apiKey?:
url?:
model?:
speaker?:
sessionId?:
key de l'URL. Si elle est omise, une clé fondée sur l'horodatage est générée automatiquement.instructions?:
session?:
debug?:
providerData?:
session ; en cas de conflit de clés, l'option du constructeur l'emporte.connectTimeoutMs?:
connect() attend à la fois la négociation WebSocket et l'aller-retour initial de session.updated. Une erreur ou une fermeture du WebSocket avant son ouverture — ou l'expiration de ce délai — entraîne le rejet de la promesse plutôt qu'une erreur de socket non interceptée.session (paramètres typés)Lien direct vers session-typed-knobs
Utilisez le champ typé session pour les options Realtime Inworld documentées. Les champs se combinent avec les valeurs par défaut appliquées lors de la connexion (par exemple, audio.output.voice défini à partir de speaker) :
output_modalities?:
audio.output.voice?:
speaker du constructeur est utilisé.audio.output.speed?:
audio.output.model?:
audio.output.format?:
{ type, rate? }. rate (Hz) s'applique à audio/pcm et audio/float32 (valeur par défaut : 24000) ; audio/pcmu et audio/pcma sont fixés à 8 kHz.audio.input.format?:
audio.output.format : une chaîne de codec ou un objet { type, rate? }.audio.input.noise_reduction?:
audio.input.transcription?:
{ model: "inworld/inworld-stt-1" }. prompt oriente la transcription à l'aide d'indications de vocabulaire, d'orthographe ou de style. Fournissez votre propre objet pour remplacer cette valeur ; définissez-la sur null pour désactiver la transcription côté utilisateur.audio.input.turn_detection?:
{ type: "semantic_vad", eagerness: "medium", create_response: true, interrupt_response: true }. Fournissez votre propre objet pour la remplacer ; définissez-la sur null pour désactiver entièrement la détection des tours. Le champ eagerness détermine la rapidité avec laquelle la VAD sémantique termine le tour d'un utilisateur : low attend des pauses plus nettes (résiste davantage aux interruptions), tandis que high termine les tours plus tôt (plus réactif, mais plus susceptible de couper la parole). La valeur par défaut medium équilibre les deux. idle_timeout_ms (server_vad uniquement) définit la période d'inactivité avant que le serveur ne valide un tour.tool_choice?:
temperature?:
max_output_tokens?:
truncation?:
tracing?:
include?:
prompt?:
providerData (extensions Inworld)Lien direct vers providerdata-inworld-extensions
providerData est un objet typé destiné aux extensions Realtime propres à Inworld. Il est envoyé sous session.providerData à chaque session.update et se combine avec toute valeur session.providerData définie via le champ session : en cas de conflit de clés, le providerData du constructeur l'emporte.
Il comporte cinq branches et deux champs au niveau de la session :
stt: réglage du STT, notammentprompt,voice_profile,language_hintset les seuils de VAD ou de fin de tour.tts: segmentation et diffusion TTS, notammentsegmenter_strategy,steering_handling,delivery_mode,conversationaletuser_turn_mode.memory: Memory glissante automatique, notammentenabled,turn_intervaletmax_facts. Inworld renvoie son état par l'événementmemory.backchannel: brefs signaux d'écoute (« hum-hum ») pendant que l'utilisateur parle. L'audio arrive par l'événementbackchannel.responsiveness: audio de remplissage précoce pendant la génération de la réponse principale. Cet audio réutilise les événements ordinairesspeakeretspeaking; il n'existe donc pas d'événements distincts.user_idetmetadata: identifiants au niveau de la session transmis à 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',
},
})
MéthodesLien direct vers Méthodes
connect()Lien direct vers connect
Ouvre la connexion WebSocket, envoie le premier session.update et se résout lorsque le serveur répond par session.updated. Cette méthode doit être appelée avant speak(), listen() ou send().
Une error ou une close sur le WebSocket avant son ouverture (ou une négociation qui dépasse connectTimeoutMs (15 s par défaut)) entraîne le rejet de la promesse plutôt qu'une erreur de socket non interceptée. En cas de rejet, le socket partiellement ouvert est fermé.
await voice.connect()
Renvoie : Promise<void>
speak()Lien direct vers speak
Envoie un message texte au modèle et déclenche une réponse audio. La promesse renvoyée ne se résout qu'une fois le cycle de vie complet de la réponse terminé (response.done pour la réponse déclenchée par cet appel) et est rejetée si la réponse est interrompue par la voix de l'utilisateur ou si une erreur de transport se produit.
Les appels séquentiels à speak() constituent le mode d'utilisation pris en charge. Les appels simultanés partagent le même ensemble de listeners et l'ordre d'association des réponses n'est pas défini.
input:
options?:
speaker?:
Renvoie : Promise<void>
listen()Lien direct vers listen
Envoie un unique tampon audio comme tour utilisateur et demande au modèle de répondre uniquement par du texte.
audioData:
Renvoie : Promise<void>
send()Lien direct vers send
Diffuse les données audio en temps réel vers le serveur. Utile pour une entrée continue depuis le microphone.
audioData:
eventId?:
Renvoie : Promise<void>
updateConfig()Lien direct vers updateconfig
Envoie un session.update au serveur. Le champ typé session est fusionné en profondeur dans la charge utile et tout providerData du constructeur est imbriqué sous session.providerData.
sessionConfig:
Renvoie : void
addInstructions()Lien direct vers addinstructions
Définit les instructions système utilisées lors du prochain appel à connect() ou updateConfig().
instructions?:
Renvoie : void
addTools()Lien direct vers addtools
Enregistre les Tools que le modèle peut appeler pendant la session. Lorsque InworldRealtimeVoice est associé à un Agent, les Tools configurés pour cet Agent sont automatiquement disponibles.
tools?:
Renvoie : void
answer()Lien direct vers answer
Envoie un événement response.create afin de déclencher une réponse du modèle, éventuellement avec des options propres à cette réponse.
options?:
Renvoie : Promise<void>
Gestion des tours de paroleLien direct vers Gestion des tours de parole
commitInput()Lien direct vers commitinput
Valide manuellement l'audio d'entrée mis en mémoire tampon comme tour utilisateur. Utilisez cette méthode pour le mode appuyer-pour-parler ou la gestion manuelle des tours lorsque turn_detection est défini sur null.
voice.commitInput()
Renvoie : void
clearInput()Lien direct vers clearinput
Supprime l'audio d'entrée mis en mémoire tampon sans le valider comme tour utilisateur.
voice.clearInput()
Renvoie : void
clearOutput()Lien direct vers clearoutput
Vide entièrement le tampon audio de sortie du serveur, ce qui arrête la lecture. Cela arrête également tout signal d'écoute audio en cours. Le chemin d'interruption par défaut (response.cancel sur interrupted) préserve les signaux d'écoute. Privilégiez-le. N'utilisez clearOutput() que lorsque vous souhaitez tout vider.
voice.clearOutput()
Renvoie : void
close() et disconnect()Lien direct vers close-and-disconnect
Les deux méthodes ferment le WebSocket et marquent l'instance comme déconnectée.
Renvoie : void
getSpeakers()Lien direct vers getspeakers
Renvoie la sélection de Voices incluse dans le package. Le catalogue d'Inworld est plus vaste que cette liste ; tout ID de Voice peut être transmis à speaker lors de l'exécution.
Renvoie : Promise<Array<{ voiceId: string }>>
on() et off()Lien direct vers on-and-off
Enregistrent et suppriment des listeners d'événements. Consultez la section Événements ci-dessous.
ÉvénementsLien direct vers Événements
La classe InworldRealtimeVoice émet les événements suivants :
speaker:
speaking:
speaking.done:
writing:
speech-started:
input_audio_buffer.speech_started provenant du serveur.speech-stopped:
input_audio_buffer.speech_stopped provenant du serveur.interrupted:
response_id en cours lorsque l'utilisateur commence à parler. Utilisez-le pour arrêter la lecture de la réponse principale lors d'une interruption. Le callback reçoit { response_id: string }. Il ne contient que les ID des réponses principales, jamais ceux des signaux d'écoute. L'arrêt du flux speaker correspondant laisse donc les flux backchannel se poursuivre (les signaux d'écoute sont conçus pour chevaucher la parole de l'utilisateur et ne sont jamais annulés lors d'une interruption).turn-suggestion:
turn-suggestion-revoked:
input-committed:
input-cleared:
input-timeout:
output-audio-started:
output-audio-stopped:
output-audio-cleared:
memory:
backchannel:
.id de chaque flux est un backchannel_id qui n'apparaît jamais dans interrupted ; lisez donc ces flux sur une piste distincte que les interruptions n'arrêtent pas. Nécessite 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:
VoixLien direct vers Voix
Le package comprend une sélection d'ID de Voice renvoyés par getSpeakers() :
DennisHadesWendyEdwardOliviaSarahTimothyPriyaRonaldDeborah
Tout ID de Voice du catalogue de Voices d'Inworld peut être transmis à speaker lors de l'exécution.
RemarquesLien direct vers Remarques
- Les clés d'API peuvent être fournies via les options du constructeur ou la variable d'environnement
INWORLD_API_KEY. Elles sont déjà encodées en Basic. Ne les réencodez pas. - L'URL WebSocket ajoute
?key=<sessionId>&protocol=realtime. Le modèle est configuré via le premiersession.update, et non dans l'URL. - À chaque appel,
speak(input, { speaker })limite le remplacement de la Voice à une seule réponse (via le champ simpleresponse.voice) et ne modifie pas la session. - Par défaut, la sortie audio est au format PCM16 à 24 kHz. Les formats téléphoniques
audio/pcmuetaudio/pcmaà 8 kHz, ainsi queaudio/float32, sont également pris en charge viasession.audio.output.format. - Utilisez
connect()avant tout appel à send, speak ou listen. Les événements envoyés avant l'ouverture du WebSocket sont mis en file d'attente puis transmis lorsque le serveur confirmesession.updated. - L'instance de Voice doit être fermée avec
close()oudisconnect()pour libérer le WebSocket. audio.input.turn_detectionutilise par défaut la VAD sémantique lorsquesessionne fournit aucune valeur. Remplacez-la par votre propre objet ou transmetteznullpour désactiver entièrement la détection des tours.audio.input.transcriptionutilise par défaut{ model: 'inworld/inworld-stt-1' }, de sorte que les événementswritingcôté utilisateur sont émis sans configuration supplémentaire. Remplacez cette valeur par votre propre objet ou transmetteznullpour désactiver la transcription côté utilisateur.on()etoff()sont typés selonInworldVoiceEventMap. Les noms d'événements connus produisent une charge utile de callback typée. Les noms inconnus utilisent par défautunknown.