> Discover all available pages from the documentation index: https://mastra.zisheng.pro/fr/llms.txt # 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](https://docs.inworld.ai/realtime/quickstart-websocket) 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 `, 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`](https://mastra.zisheng.pro/fr/reference/voice/inworld). ## Exemple d'utilisation ```typescript 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 constructeur **apiKey** (`string`): Clé d'API Inworld. Utilise par défaut la variable d'environnement INWORLD\_API\_KEY. Les clés sont encodées en Basic et transmises telles quelles dans l'en-tête Authorization. **url** (`string`): Point de terminaison WebSocket Realtime. Une clé de session générée par le client et un paramètre de protocole sont ajoutés automatiquement. (Default: `'wss://api.inworld.ai/api/v1/realtime/session'`) **model** (`string`): ID du modèle LLM Router. Il est envoyé dans le premier session.update, et non dans l'URL. Tout modèle pris en charge par le routeur d'Inworld est accepté. (Default: `'inworld/models/gemma-4-26b-a4b-it'`) **speaker** (`string`): ID de Voice par défaut pour la synthèse vocale. Toute Voice du catalogue d'Inworld est acceptée. (Default: `'Sarah'`) **sessionId** (`string`): Clé de session générée par le client et exposée comme paramètre key de l'URL. Si elle est omise, une clé fondée sur l'horodatage est générée automatiquement. (Default: `'voice-{Date.now()}'`) **instructions** (`string`): Prompt système envoyé avec le premier session.update. **session** (`Partial`): Options de session typées de premier niveau (audio, tool\_choice, output\_modalities, temperature, ...). Elles sont fusionnées en profondeur dans chaque session.update afin que les champs imbriqués tels que audio.output.voice et audio.output.speed se combinent au lieu de s'écraser. Consultez le champ session ci-dessous. **debug** (`boolean`): Consigne les événements bruts du serveur. (Default: `false`) **providerData** (`InworldProviderData`): Configuration typée des extensions Inworld (stt, tts, memory, backchannel, responsiveness, ainsi que user\_id et metadata). Elle est envoyée sous session.providerData à chaque session.update. Elle se combine avec toute valeur session.providerData définie via le champ session ; en cas de conflit de clés, l'option du constructeur l'emporte. **connectTimeoutMs** (`number`): Durée maximale pendant laquelle 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. (Default: `15000`) ### `session` (paramètres typés) 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** (`Array<"text" | "audio">`): Modalités que le modèle doit produire. **audio.output.voice** (`string`): ID du catalogue de Voice. En cas d'omission, le speaker du constructeur est utilisé. **audio.output.speed** (`number`): Multiplicateur de vitesse de lecture de l'audio synthétisé (de 0,25 à 1,5). **audio.output.model** (`string`): Modèle TTS Inworld (par exemple, "inworld-tts-2"). **audio.output.format** (`InworldAudioFormat`): Encodage de l'audio de sortie. Une chaîne de codec (par exemple, "audio/pcm", "audio/pcmu", "audio/pcma", "audio/float32") ou un objet { 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** (`InworldAudioFormat`): Encodage de l'audio d'entrée envoyé au serveur. Même forme que audio.output.format : une chaîne de codec ou un objet { type, rate? }. **audio.input.noise\_reduction** (`{ type: "near_field" | "far_field" }`): Mode de réduction du bruit appliqué à l'entrée avant la transcription et la VAD. **audio.input.transcription** (`{ model?: string; language?: string; prompt?: string }`): Transcription côté serveur de l'audio entrant de l'utilisateur. La valeur par défaut est { 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** (`InworldTurnDetection | null`): Détection d'activité vocale et de tour de parole. La valeur par défaut est { 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** (`string | { type: "function"; name: string } | { type: "mcp"; server_label: string }`): Stratégie de sélection des Tools. Utilisez la variante mcp pour acheminer les appels de Tools via un serveur MCP Inworld configuré. **temperature** (`number`): Température d'échantillonnage du modèle. **max\_output\_tokens** (`number | "inf"`): Nombre maximal de tokens générés par réponse. **truncation** (`"auto" | "disabled" | { type: "retention_ratio"; retention_ratio: number }`): Stratégie de troncature de la conversation. **tracing** (`"auto" | { workflow_name?: string; group_id?: string; metadata?: Record }`): Configuration du traçage distribué. Utilisez "auto" pour les valeurs par défaut du serveur, ou nommez explicitement le Workflow ou le groupe. **include** (`Array<"item.input_audio_transcription.logprobs">`): Champs supplémentaires que le serveur doit inclure dans les événements émis lorsque vous les activez. **prompt** (`string | null`): Référence à un modèle de prompt côté serveur. Transmettez null pour l'effacer. ### `providerData` (extensions Inworld) `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, notamment `prompt`, `voice_profile`, `language_hints` et les seuils de VAD ou de fin de tour. - `tts` : segmentation et diffusion TTS, notamment `segmenter_strategy`, `steering_handling`, `delivery_mode`, `conversational` et `user_turn_mode`. - `memory` : Memory glissante automatique, notamment `enabled`, `turn_interval` et `max_facts`. Inworld renvoie son état par l'événement `memory`. - `backchannel` : brefs signaux d'écoute (« hum-hum ») pendant que l'utilisateur parle. L'audio arrive par l'événement `backchannel`. - `responsiveness` : audio de remplissage précoce pendant la génération de la réponse principale. Cet audio réutilise les événements ordinaires `speaker` et `speaking` ; il n'existe donc pas d'événements distincts. - `user_id` et `metadata` : identifiants au niveau de la session transmis à Inworld. ```typescript 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éthodes ### `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é. ```typescript await voice.connect() ``` Renvoie : `Promise` ### `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** (`string | NodeJS.ReadableStream`): Texte ou flux de texte à convertir en parole. **options** (`Options`): Configuration propre à chaque appel. **options.speaker** (`string`): ID de Voice à utiliser pour cette requête précise. Renvoie : `Promise` ### `listen()` Envoie un unique tampon audio comme tour utilisateur et demande au modèle de répondre uniquement par du texte. **audioData** (`NodeJS.ReadableStream`): Flux audio à transcrire. Renvoie : `Promise` ### `send()` Diffuse les données audio en temps réel vers le serveur. Utile pour une entrée continue depuis le microphone. **audioData** (`NodeJS.ReadableStream | Int16Array`): Données audio à diffuser. Int16Array est envoyé sous forme de fragment base64 unique ; un flux lisible est transmis fragment par fragment. **eventId** (`string`): ID d'événement facultatif transmis au serveur avec chaque fragment audio. Renvoie : `Promise` ### `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** (`InworldSessionConfig | Record`): Configuration partielle de session à appliquer. Renvoie : `void` ### `addInstructions()` Définit les instructions système utilisées lors du prochain appel à `connect()` ou `updateConfig()`. **instructions** (`string`): Prompt système du modèle. Renvoie : `void` ### `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** (`ToolsInput`): Configuration des Tools à fournir. Renvoie : `void` ### `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** (`Record`): Options de réponse transmises au serveur. Renvoie : `Promise` ### Gestion des tours de parole #### `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`. ```typescript voice.commitInput() ``` Renvoie : `void` #### `clearInput()` Supprime l'audio d'entrée mis en mémoire tampon sans le valider comme tour utilisateur. ```typescript voice.clearInput() ``` Renvoie : `void` #### `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. ```typescript voice.clearOutput() ``` Renvoie : `void` ### `close()` et `disconnect()` Les deux méthodes ferment le WebSocket et marquent l'instance comme déconnectée. Renvoie : `void` ### `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>` ### `on()` et `off()` Enregistrent et suppriment des listeners d'événements. Consultez la section [Événements](#events) ci-dessous. ## Événements La classe `InworldRealtimeVoice` émet les événements suivants : **speaker** (`event`): Émis une fois par réponse avec un flux PassThrough contenant de l’audio PCM. Utilisez cet événement pour transmettre l’audio à un lecteur. **speaking** (`event`): Émis pour chaque delta audio. Le callback reçoit { audio: Buffer, response\_id: string }. **speaking.done** (`event`): Émis lorsque la sortie audio d'une réponse est terminée. Le callback reçoit { response\_id: string }. **writing** (`event`): Émis à mesure que le texte transcrit devient disponible. Le callback reçoit { text: string, response\_id: string, role: "assistant" | "user", voiceProfile? }. Les deltas de transcription audio et de texte d'une même réponse sont dédupliqués, de sorte qu'une réponse n'émet qu'un seul flux. Pour les événements utilisateur, voiceProfile est présent lorsque providerData.stt.voice\_profile est activé. **speech-started** (`event`): Front VAD brut input\_audio\_buffer.speech\_started provenant du serveur. **speech-stopped** (`event`): Front VAD brut input\_audio\_buffer.speech\_stopped provenant du serveur. **interrupted** (`event`): Signal synthétique côté client : émis une fois par 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** (`event`): Indication intelligente de fin de tour pour un énoncé utilisateur mis en mémoire tampon. Le callback reçoit { item\_id, utterance\_index, probability, trailing\_silence\_ms?, audio\_duration\_ms?, inference\_ms? }. **turn-suggestion-revoked** (`event`): Une suggestion de tour précédemment émise a été retirée. Le callback reçoit { item\_id, utterance\_index }. **input-committed** (`event`): L'audio d'entrée mis en mémoire tampon a été validé comme tour utilisateur (via commitInput() ou la VAD automatique). Le callback reçoit { item\_id, previous\_item\_id? }, où previous\_item\_id peut être null. **input-cleared** (`event`): L'audio d'entrée mis en mémoire tampon a été supprimé (via clearInput()). Le callback reçoit {}. **input-timeout** (`event`): Un délai d'inactivité de la VAD du serveur a validé un tour utilisateur. Le callback reçoit { audio\_start\_ms, audio\_end\_ms, item\_id }. **output-audio-started** (`event`): Le serveur a commencé à émettre l'audio de sortie. Le callback reçoit {}. **output-audio-stopped** (`event`): Le serveur a cessé d'émettre l'audio de sortie de la réponse actuelle. Le callback reçoit {}. **output-audio-cleared** (`event`): Le tampon audio de sortie du serveur a été vidé, ce qui a arrêté la lecture (via clearOutput()). Le callback reçoit {}. **memory** (`event`): Émis avec le résumé glissant et l'état des faits d'Inworld, dédupliqués par version. Nécessite providerData.memory.enabled. Le callback reçoit InworldMemoryState. **backchannel** (`event`): Émis avec un flux PassThrough d'audio PCM de signaux d'écoute (brefs acquiescements pendant que l'utilisateur parle). L'.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** (`event`): Émis lorsqu'un signal d'écoute se termine. Le callback reçoit { backchannel\_id: string, phrase? }. **backchannel.skipped** (`event`): Émis lorsque le mécanisme de décision ignore un signal d'écoute avant la production de tout audio. Le callback reçoit { reason: string }. **response.created** (`event`): Émis lorsqu’une nouvelle réponse commence. Le callback reçoit l’événement serveur complet. **response.done** (`event`): Émis lorsqu’une réponse se termine. Le callback reçoit l’événement serveur complet. **conversation.item.added** (`event`): Émis lorsqu’un nouvel élément est ajouté à la conversation. **conversation.item.done** (`event`): Émis lorsqu’un élément de conversation se termine. **function\_call.arguments** (`event`): Émis avec les arguments complets de l'appel de Tool. Le callback reçoit { call\_id, name, arguments }. **tool-call-start** (`event`): Émis avant l'exécution d'un Tool enregistré. **tool-call-result** (`event`): Émis après le renvoi d'un résultat par un Tool enregistré. **error** (`event`): Émis en cas d’erreur de transport ou du serveur. ## Voix Le package comprend une sélection d'ID de Voice renvoyés par `getSpeakers()` : - `Dennis` - `Hades` - `Wendy` - `Edward` - `Olivia` - `Sarah` - `Timothy` - `Priya` - `Ronald` - `Deborah` Tout ID de Voice du [catalogue de Voices d'Inworld](https://docs.inworld.ai/quickstart-tts) peut être transmis à `speaker` lors de l'exécution. ## 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=&protocol=realtime`. Le modèle est configuré via le premier `session.update`, et non dans l'URL. - À chaque appel, `speak(input, { speaker })` limite le remplacement de la Voice à une seule réponse (via le champ simple `response.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/pcmu` et `audio/pcma` à 8 kHz, ainsi que `audio/float32`, sont également pris en charge via `session.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 confirme `session.updated`. - L'instance de Voice doit être fermée avec `close()` ou `disconnect()` pour libérer le WebSocket. - `audio.input.turn_detection` utilise par défaut la VAD sémantique lorsque `session` ne fournit aucune valeur. Remplacez-la par votre propre objet ou transmettez `null` pour désactiver entièrement la détection des tours. - `audio.input.transcription` utilise par défaut `{ model: 'inworld/inworld-stt-1' }`, de sorte que les événements `writing` côté utilisateur sont émis sans configuration supplémentaire. Remplacez cette valeur par votre propre objet ou transmettez `null` pour désactiver la transcription côté utilisateur. - `on()` et `off()` sont typés selon `InworldVoiceEventMap`. Les noms d'événements connus produisent une charge utile de callback typée. Les noms inconnus utilisent par défaut `unknown`.