> Discover all available pages from the documentation index: https://mastra.zisheng.pro/fr/llms.txt # LiveKit Le package `@mastra/livekit` connecte les agents Mastra au framework LiveKit Agents. LiveKit exécute le pipeline audio (détection d’activité vocale, transcription de la parole, détection des tours de parole, synthèse vocale, interruption) et le package relie la génération des réponses à l’appel `stream()` d’un agent Mastra. Consultez [Voix en temps réel](https://mastra.zisheng.pro/fr/guides/voice/realtime-voice) pour découvrir la configuration et les concepts. Le package comporte trois points d’entrée : - `@mastra/livekit` : les API côté serveur, [`liveKitConnectionRoute()`](#livekitconnectionroute), [`dispatchVoiceSession()`](#dispatchvoicesession), [`pipeAgentReplyToWriter()`](#pipeagentreplytowriter), [`serializeSessionMetadata()`](#livekitsessionmetadata) et [`createEndCallTool()`](#createendcalltool). Importez-les depuis le code serveur Mastra. Ce point d’entrée ne charge jamais le runtime des agents LiveKit. - `@mastra/livekit/worker` : le runtime du worker, [`createLiveKitWorker()`](#createlivekitworker), [`runLiveKitWorker()`](#runlivekitworker), [`chatContextToMessages()`](#chatcontexttomessages), ainsi que les utilitaires de session [`speakGreeting()`](#speakgreeting), [`waitForAgentDoneSpeaking()`](#waitforagentdonespeaking) et [`runEndCall()`](#runendcall). Importez-le uniquement depuis le fichier d’entrée du worker. - `@mastra/livekit/plugin` : le plugin de composant LLM, [`MastraLLM`](#mastrallm) et [`createRemoteAgentReplyGenerator()`](#createremoteagentreplygenerator). Importez-le dans les workers qui construisent leur propre `voice.AgentSession`. `createRemoteAgentReplyGenerator()` est également exporté depuis `@mastra/livekit/worker`, car il s’intègre à `createLiveKitWorker()` par l’intermédiaire de son option `generate`. `MastraLLM` est disponible uniquement dans le plugin. ## `createLiveKitWorker()` Construit une définition d’agent LiveKit qui répond aux sessions vocales avec des agents Mastra. Utilisez-la comme export par défaut du fichier d’entrée de votre worker. ```typescript import { fileURLToPath } from 'node:url' import { createLiveKitWorker, runLiveKitWorker } from '@mastra/livekit/worker' import { mastra } from './index' export default createLiveKitWorker({ mastra, agent: 'support', stt: 'deepgram/nova-3', tts: 'cartesia/sonic-3', turnDetection: 'multilingual', }) if (process.argv[1] === fileURLToPath(import.meta.url)) { runLiveKitWorker({ entry: import.meta.url, agentName: 'mastra-voice' }) } ``` ### Options **mastra** (`Mastra`): L’instance Mastra dont les agents gèrent les sessions vocales. **agent** (`string | (args) => string | Agent | Promise`): Agent Mastra qui répond à chaque session : une clé ou un identifiant d’agent fixe, ou un résolveur appelé à chaque session avec les métadonnées de dispatch et le contexte de tâche. Utilise par défaut l’agentId des métadonnées de dispatch. **workflow** (`string | Workflow | (args) => string | Promise`): Génère la réponse de chaque tour avec un workflow Mastra plutôt qu’avec un agent : une instance Workflow, une clé ou un identifiant de workflow fixe, ou un résolveur qui renvoie un identifiant de workflow par session. Le workflow s’exécute une fois jusqu’à son terme à chaque tour (sans suspension ni reprise). Mutuellement exclusif avec agent ; nécessite workflowInput. **workflowInput** (`(args: VoiceTurnContext & { metadata }) => unknown | Promise`): Convertit un tour en inputData du workflow. Requis lorsque workflow est défini. Un mappage sans état qui transmet la transcription complète à chaque tour évite de conserver l’état de la conversation dans le workflow. **replyStep** (`string`): Diffuse uniquement le texte de l’identifiant de cette étape du workflow. Par défaut, inclut chaque étape qui écrit dans son writer. **resultText** (`(result: unknown) => string | undefined`): Solution de repli lorsque le workflow ne diffuse aucun texte via writer : déduit la réponse prononcée du résultat final de l’exécution. **generate** (`VoiceReplyGenerator`): Échappatoire de plus bas niveau : fournissez directement n’importe quel générateur de réponses (workflow personnalisé, pont distant, etc.). **stt** (`STT | string`): Transcription de la parole : une instance de plugin LiveKit ou une chaîne de modèle d’inférence telle que 'deepgram/nova-3'. Pour une sélection par appel, définissez le résolveur configuration.stt ; il est prioritaire, cette option servant de repli. **tts** (`TTS | string`): Synthèse vocale : une instance de plugin LiveKit ou une chaîne de modèle d’inférence telle que 'cartesia/sonic-3'. Pour une sélection par appel, définissez le résolveur configuration.tts ; il est prioritaire, cette option servant de repli. **vad** (`VAD | 'silero' | false`): Détection d’activité vocale. 'silero' charge le VAD Silero depuis @livekit/agents-plugin-silero pendant le préchauffage. Transmettez votre propre instance, ou false pour désactiver cette fonction. (Default: `'silero'`) **turnDetection** (`'multilingual' | 'english' | TurnDetectionMode`): Détection de fin de tour. 'multilingual' et 'english' chargent le détecteur sémantique de tours de LiveKit depuis @livekit/agents-plugin-livekit. Les autres valeurs, telles que 'vad', 'stt' ou 'manual', sont transmises telles quelles. **turnHandling** (`Partial`): Réglage de la gestion des tours : délais de détection de fin, sensibilité aux interruptions et génération anticipée. Le worker désactive preemptiveGeneration sauf si cette option est définie ici ; chaque tentative anticipée réexécute l’agent Mastra et conserve un doublon du message utilisateur. **sessionOptions** (`Partial`): Options LiveKit AgentSession supplémentaires fusionnées avec celles construites par cet utilitaire. **memory** (`false | ((args) => { thread, resource } | false)`): Mappage de la mémoire. Utilise par défaut { thread: metadata.threadId ?? nom de la salle, resource: metadata.resourceId ?? thread } lorsque la mémoire est configurée pour l’agent résolu. Transmettez false pour le désactiver, ou une fonction pour le personnaliser. **toolFeedback** (`(toolCall) => string | undefined`): Appelé lorsque l’agent Mastra lance un appel d’outil au milieu d’une réponse. Renvoyez une courte phrase à prononcer pendant l’exécution de l’outil. **onTurnComplete** (`(ctx: VoiceTurnCompleteContext) => void | Promise`): Appelé une fois par tour après la fin de la diffusion de la réponse vers la synthèse vocale. S’exécute hors du chemin audio et n’est pas attendu. Le contexte contient la réponse produite (text, toolCalls, interrupted, usage) et le mappage de mémoire résolu. **configuration** (`LiveKitWorkerConfiguration`): Configuration regroupée de la conversation et de la conformité : message d’accueil et divulgation de l’IA, exigences de consentement, raccrochage initié par l’agent et sélection STT/TTS par appel. **configuration.greeting** (`GreetingConfiguration`): Message d’accueil et divulgation de l’IA : text (chaîne fixe ou résolveur par appel pour des messages propres à chaque locataire), allowInterruptions, awaitPlayout, persist et nouvelle divulgation périodique via repeatEvery et repeatText. **configuration.consentPolicy** (`ConsentConfiguration`): Politique de consentement de l’appel, sous forme d’exigences nommées (à commencer par summaryStorage). Elle est uniquement déclarative : le worker ne bloque rien par lui-même. Enregistrez les consentements à l’exécution avec createConsentTool et appliquez-les dans votre propre code ; la politique déclarée est exposée dans onCallEnd pour permettre une vérification croisée. **configuration.endCall** (`EndCallConfiguration`): Raccrochage initié par l’agent : le worker surveille à chaque tour l’outil de fin d’appel (à associer à createEndCallTool), attend la fin de la lecture des derniers mots de l’agent, puis se déconnecte en exécutant onCallEnd avant de terminer. **configuration.stt** (`(context: VoiceCallContext) => STT | string | undefined`): Transcription de la parole par appel : résolveur invoqué une fois par appel (après la connexion) avec { metadata, requestContext, roomName, ctx }, qui renvoie toute valeur acceptée par l’option stt de premier niveau. Renvoyez undefined pour revenir à la valeur stt de premier niveau. Mettez les instances de plugin en cache entre les appels ; le résolveur s’exécute pendant la configuration de l’appel. **configuration.tts** (`(context: VoiceCallContext) => TTS | string | undefined`): Synthèse vocale par appel : résolveur invoqué une fois par appel (après la connexion) avec { metadata, requestContext, roomName, ctx }, qui renvoie toute valeur acceptée par l’option tts de premier niveau — une voix ou une langue par locataire. Renvoyez undefined pour revenir à la valeur tts de premier niveau. Mettez les instances de plugin en cache entre les appels. **greeting** (`string`): Message d’accueil statique prononcé au démarrage de la session. Obsolète : préférez configuration.greeting.text. **persistGreeting** (`boolean`): Enregistre le message d’accueil prononcé dans le thread de mémoire en tant que message de l’assistant, afin que le thread enregistré constitue une transcription fidèle de l’appel. S’applique uniquement lorsqu’un message d’accueil est défini et que la mémoire est activée. Obsolète : préférez configuration.greeting.persist. (Default: `true`) **observability** (`boolean`): Trace chaque appel lorsque l’observabilité est configurée sur l’instance Mastra. Ouvre un span voice call par session : l’exécution de l’agent à chaque tour y est imbriquée, les métriques LiveKit de latence STT, TTS, de fin d’énoncé, VAD et LLM deviennent des spans enfants, et le span se ferme avec un récapitulatif de l’utilisation par modèle. Transmettez false pour désactiver cette fonction. (Default: `true`) **inputOptions** (`Partial`): Options d’entrée de la salle LiveKit transmises à session.start(). **outputOptions** (`Partial`): Options de sortie de la salle LiveKit transmises à session.start(). **onSessionStart** (`(args: { session, ctx, agent, metadata }) => void | Promise`): Appelé après le démarrage de la session. Ajoutez ici des écouteurs d’événements ou déclenchez des réponses. ## `runLiveKitWorker()` Démarre la CLI du worker LiveKit (sous-commandes `dev`, `start` et `connect`) pour un fichier d’entrée de worker. Appelez-la depuis le fichier qui exporte par défaut la définition du worker, avec une condition garantissant qu’elle ne s’exécute que lorsque le fichier est lancé directement (le worker crée un processus enfant par session, qui réimporte le même fichier). L’utilisation de cet utilitaire plutôt que de `cli.runApp` depuis `@livekit/agents` garantit que le runtime du worker et le pont partagent une même copie du SDK LiveKit. ### Options **entry** (`string | URL`): Module d’entrée du worker dont l’export par défaut est la définition de l’agent. Transmettez import.meta.url. **agentName** (`string`): Nom de l’agent LiveKit pour un dispatch explicite. (Default: `'mastra-voice'`) **serverOptions** (`Partial`): ServerOptions LiveKit supplémentaires fusionnées avec celles construites par cet utilitaire. ## `pipeAgentReplyToWriter()` Diffuse la réponse d’un agent Mastra dans le `writer` d’une étape du workflow sur le chemin de réponse du workflow. Cette fonction transmet les deltas de texte de l’agent, afin que la synthèse vocale commence avant que la réponse complète soit prête, ainsi que ses fragments d’appels d’outils, afin que `toolFeedback` se déclenche et que `onTurnComplete` reçoive la liste des outils. Ne rediriger que `stream.textStream` supprime silencieusement les appels d’outils. Transmettez le `abortSignal` de l’étape à `agent.stream()` afin qu’une interruption arrête rapidement la génération. ```typescript import { pipeAgentReplyToWriter } from '@mastra/livekit' const generateResponse = createStep({ id: 'generateResponse', // input and output schemas omitted execute: async ({ inputData, mastra, writer, abortSignal }) => { const stream = await mastra.getAgent('support').stream(inputData.turn, { abortSignal }) const reply = await pipeAgentReplyToWriter(stream, writer) return { reply } }, }) ``` Renvoie : `Promise`, le texte de réponse accumulé. ### Paramètres **agentStream** (`AgentReplyStreamLike`): Le flux renvoyé par agent.stream() — toute valeur exposant un itérable asynchrone fullStream. **writer** (`WritableStream`): Le writer de l’étape du workflow. ## `chatContextToMessages()` Convertit un contexte de chat LiveKit en messages simples acceptés par `agent.stream()`, en excluant les instructions et les appels de fonctions. Utilisez cette fonction dans `workflowInput` pour transmettre la transcription complète à un workflow sans état. ```typescript import { createLiveKitWorker, chatContextToMessages } from '@mastra/livekit/worker' export default createLiveKitWorker({ mastra, workflow: 'phoneConversation', workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }), }) ``` Renvoie : `VoiceTurnMessage[]`, où chaque entrée est `{ role: 'system' | 'user' | 'assistant'; content: string; id?: string }`. ## `MastraLLM` Un plugin LLM LiveKit standard (`llm.LLM`) reposant sur un agent Mastra. Utilisez-le lorsque vous construisez vous-même la `voice.AgentSession` et souhaitez placer Mastra dans l’emplacement `llm`. [`createLiveKitWorker()`](#createlivekitworker) constitue l’alternative gérée. Consultez [Utiliser Mastra comme composant LLM](https://mastra.zisheng.pro/fr/guides/voice/realtime-voice) pour choisir la solution appropriée. Avec `remote`, le plugin diffuse chaque tour depuis votre serveur Mastra via HTTP à l’aide de Server-Sent Events (SSE). La boucle de l’agent, les outils et la mémoire s’exécutent côté serveur ; interrompre l’agent annule la génération côté serveur. ```typescript import { voice } from '@livekit/agents' import { MastraLLM } from '@mastra/livekit/plugin' const session = new voice.AgentSession({ llm: new MastraLLM({ remote: { baseUrl: process.env.MASTRA_URL!, agentId: 'support' }, memory: { thread: callId, resource: userId }, }), stt: 'deepgram/nova-3', tts: 'cartesia/sonic-3', // Required with `memory`: LiveKit enables preemptive generation by default. turnHandling: { preemptiveGeneration: { enabled: false } }, }) ``` Le plugin définit `provider` sur `mastra` et `model` sur l’identifiant de l’agent, afin que les métriques LiveKit et les adaptateurs de repli l’identifient comme n’importe quel autre LLM. ### Options du constructeur Fournissez exactement une source de réponse : `remote`, `agent` ou `generate`. **remote** (`RemoteMastraAgentOptions`): Serveur Mastra distant accessible via HTTP. Accepte les mêmes options de connexion que createRemoteAgentReplyGenerator() : baseUrl, agentId, apiPrefix, headers, fetch, timeoutMs, retries, body. **agent** (`Agent`): Agent Mastra exécuté dans le processus. Permet de gérer la session sans second déploiement. **generate** (`VoiceReplyGenerator`): Source de réponse personnalisée. Une source generate possède ses propres hooks ; les options toolFeedback, onToolCall et onTurnComplete ci-dessous s’appliquent uniquement aux sources remote et agent. **memory** (`{ thread: string; resource?: string } | false`): Persistance de la conversation, résolue par appel (par exemple à partir de l’identité de l’appelant SIP). Lorsqu’elle est définie, seuls les nouveaux messages depuis la dernière prise de parole de l’agent sont envoyés à chaque tour, et Mastra Memory fournit l’historique. Lorsqu’elle est omise, le contexte de chat LiveKit complet est envoyé à chaque tour. (Default: `false`) **requestContext** (`RequestContext | Record`): Contexte de requête transmis à la génération (locataire, numéro composé, etc.). **toolFeedback** (`(toolCall: VoiceToolCall) => string | undefined`): Renvoie une courte phrase à prononcer pendant l’exécution d’un outil côté serveur. **onToolCall** (`(toolCall: VoiceToolCall) => void`): Appelé au démarrage de chaque appel d’outil, au milieu du flux. Associez-le à runEndCall() pour implémenter votre propre processus de raccrochage initié par l’agent. **onTurnComplete** (`(ctx: VoiceTurnCompleteContext) => void | Promise`): Appelé une fois par tour après la fin de la diffusion de la réponse, hors du chemin audio et sans être attendu. Le contexte contient la réponse produite : text, toolCalls, interrupted et usage. > **Attention:** N’associez pas `memory` à l’option `preemptiveGeneration` de la session, que LiveKit active par défaut dans les sessions que vous construisez vous-même. Un tour spéculatif qui se termine avant que LiveKit ne l’abandonne conserve dans le thread un message utilisateur et une réponse jamais prononcée. Définissez `turnHandling: { preemptiveGeneration: { enabled: false } }` sur la session. Le mode sans état (sans `memory`) fonctionne avec la génération anticipée. ### Exécution des outils sur l’agent Mastra Les outils sont définis et exécutés côté serveur sur l’agent Mastra. Le plugin ne transmet jamais les définitions d’outils LiveKit : si la session fournit un `toolCtx` non vide, il consigne une seule fois un avertissement indiquant les outils ignorés. Chaque outil doit terminer son exécution côté serveur : un outil qui nécessite une approbation ou une exécution côté client fait échouer le tour avec une erreur descriptive au lieu de bloquer l’appel. L’activité des outils parvient au worker via `toolFeedback`, `onToolCall` et `onTurnComplete`. ### Instructions LiveKit injecte, depuis votre `voice.Agent`, ses `instructions` dans le contexte de chat de chaque requête. Le plugin les supprime, car les instructions propres à l’agent Mastra côté serveur font autorité. Pour modifier le prompt, modifiez l’agent Mastra. ### Tours interrompus Lorsque l’utilisateur interrompt une réponse : 1. Le plugin annule le flux. Le serveur interrompt la génération et ne conserve rien de ce tour. 2. LiveKit enregistre dans son contexte de chat la partie effectivement entendue par l’utilisateur, en la marquant comme interrompue. 3. Au tour suivant, le plugin renvoie ce fragment entendu uniquement, placé avant le nouveau message utilisateur, afin que le thread de mémoire soit complété rétroactivement pour correspondre à l’appel. Les messages contiennent les identifiants de message LiveKit et le serveur élimine les doublons par identifiant ; les nouvelles tentatives et les renvois restent donc idempotents. Si un utilisateur raccroche immédiatement après avoir interrompu la réponse, ce dernier fragment n’est pas enregistré. Lorsque la transcription doit l’inclure, effectuez immédiatement la réconciliation à partir de l’événement de session ; grâce à l’identifiant de message partagé, le renvoi au tour suivant effectue une mise à jour ou une insertion plutôt qu’une duplication : ```typescript import { voice } from '@livekit/agents' import { MastraClient } from '@mastra/client-js' const client = new MastraClient({ baseUrl: process.env.MASTRA_URL! }) session.on(voice.AgentSessionEventTypes.ConversationItemAdded, ({ item }) => { if (item.type !== 'message' || item.role !== 'assistant' || !item.interrupted) return void client.saveMessageToMemory({ agentId: 'support', messages: [ { id: item.id, threadId: callId, resourceId: userId, role: 'assistant', content: item.textContent ?? '', type: 'text', createdAt: new Date(), }, ], }) }) ``` ### Métriques d’utilisation Lorsque le serveur communique l’utilisation des tokens pour un tour, le plugin la transmet à LiveKit. Les événements `metrics_collected` de la session contiennent ainsi le délai avant le premier token, la durée et le nombre de tokens, comme pour tout plugin LLM. Le même objet d’utilisation (`promptTokens`, `completionTokens`, `promptCachedTokens`, `totalTokens`) est transmis à `onTurnComplete` sous la forme `result.usage`. ### Erreurs et délais d’expiration Le transport lève les types `APIError` de LiveKit (`APIStatusError`, `APIConnectionError`, `APITimeoutError`), de sorte que la politique de nouvelle tentative de la session (`connOptions.maxRetry`) et le basculement de `FallbackAdapter` fonctionnent sans modification. Un tour n’est jamais retenté après son premier token : mieux vaut qu’une réponse vocale échoue rapidement plutôt qu’elle soit rejouée après avoir été entendue en partie. Un mécanisme de surveillance de la connexion et du premier token utilise le `connOptions.timeoutMs` de la session (10 secondes par défaut). Ainsi, un serveur qui accepte la connexion sans jamais diffuser de contenu ne peut pas provoquer un silence indéfini. Si le serveur Mastra tombe en panne pendant un appel, chaque tentative de réponse échoue avec une erreur typée après ses nouvelles tentatives, et LiveKit ferme la session après plusieurs échecs consécutifs. Rétablissez le serveur avant d’épuiser ce quota pour que l’appel reprenne au tour suivant. ### Contenu des messages L’extraction des messages est limitée au texte : le contenu des images est ignoré et le contenu audio est inclus uniquement par l’intermédiaire de sa transcription. Les pipelines vocaux ne sont pas affectés, mais les éléments que vous injectez vous-même dans le contexte de chat doivent contenir du texte. ## `createRemoteAgentReplyGenerator()` Construit un générateur de réponses qui exécute la boucle de l’agent sur un serveur Mastra **distant** via HTTP/SSE. `MastraLLM` l’utilise en interne dans son mode `remote`. Utilisez-le directement par l’intermédiaire de `createLiveKitWorker` et de son option `generate` pour exécuter le worker complet avec un serveur distant : ```typescript import { createLiveKitWorker, createRemoteAgentReplyGenerator } from '@mastra/livekit/worker' import { mastra } from './index' export default createLiveKitWorker({ mastra, // local instance for logger and worker config; replies come from the remote server generate: createRemoteAgentReplyGenerator({ baseUrl: process.env.MASTRA_URL!, agentId: 'support', }), memory: ({ metadata, roomName }) => ({ thread: metadata.threadId ?? roomName }), stt: 'deepgram/nova-3', tts: 'cartesia/sonic-3', }) ``` Sur le chemin `generate`, les options `toolFeedback` et `onTurnComplete` au niveau du worker ne s’appliquent pas, et la détection de fin d’appel du worker ne se déclenche pas ; transmettez plutôt les hooks au générateur. L’annulation d’un tour (interruption) met fin à la requête HTTP, ce qui annule la génération sur le serveur. Les erreurs sont levées sous forme de types `APIError` LiveKit. L’option `retries` s’applique uniquement aux tentatives de connexion initiales. Un tour n’est jamais retenté après son premier fragment. Renvoie : `VoiceReplyGenerator`. ### Options **baseUrl** (`string`): URL de base du serveur Mastra distant, par exemple https\://my-app.example.com. **agentId** (`string`): Clé enregistrée ou identifiant de l’agent sur l’instance Mastra distante. **apiPrefix** (`string`): Préfixe de chemin de l’API Mastra. (Default: `'/api'`) **headers** (`Record | () => Record | Promise>`): En-têtes statiques, ou résolveur invoqué à chaque tour — par exemple pour générer un nouveau token d’autorisation. **fetch** (`typeof fetch`): Implémentation de fetch injectable pour les tests ou les proxys. (Default: `globalThis.fetch`) **timeoutMs** (`number`): Délai d’expiration de la connexion et du premier token, en millisecondes. Lors d’une utilisation via MastraLLM, prend plutôt par défaut la valeur connOptions.timeoutMs de la session. (Default: `10000`) **retries** (`number`): Tentatives de reconnexion initiale, uniquement avant le premier fragment. Lors d’une utilisation via MastraLLM, la session LiveKit gère les nouvelles tentatives et cette valeur est forcée à 0. (Default: `2`) **body** (`Record`): Champs supplémentaires fusionnés dans le corps de chaque requête de flux. **toolFeedback** (`(toolCall: VoiceToolCall) => string | undefined`): Renvoie une courte phrase à prononcer pendant l’exécution d’un outil côté serveur. **onToolCall** (`(toolCall: VoiceToolCall) => void`): Appelé au démarrage de chaque appel d’outil, au milieu du flux. **onTurnComplete** (`(ctx: VoiceTurnCompleteContext) => void | Promise`): Appelé une fois par tour après la fin de la diffusion de la réponse, hors du chemin audio. ## `speakGreeting()` Prononce un message d’accueil dans une session que vous gérez, en respectant les options d’interruption et de lecture. Renvoie le `SpeechHandle` LiveKit, ou `undefined` en l’absence de texte d’accueil. `createLiveKitWorker()` l’utilise en interne pour sa configuration `greeting`. ```typescript import { speakGreeting } from '@mastra/livekit/worker' await speakGreeting(session, { text: "You've reached support. You're speaking with an AI assistant.", allowInterruptions: false, awaitPlayout: true, }) ``` ### Paramètres **session** (`voice.AgentSession`): Session dans laquelle prononcer le message. **greeting** (`{ text?: string; allowInterruptions?: boolean; awaitPlayout?: boolean }`): Texte du message d’accueil et options de lecture. Lorsque awaitPlayout vaut true, la promesse renvoyée est résolue une fois la lecture du message d’accueil terminée (ou interrompue). ## `waitForAgentDoneSpeaking()` Est résolue dès que l’agent ne produit ni ne lit plus de réponse : son état a quitté `thinking` et `speaking`. Elle est résolue immédiatement si l’agent est déjà inactif et, par sécurité, toujours dans le délai `maxWaitMs` (30 secondes par défaut). Utilisez-la avant de mettre fin à une session pour que les derniers mots soient lus au lieu d’être coupés. ```typescript import { waitForAgentDoneSpeaking } from '@mastra/livekit/worker' await waitForAgentDoneSpeaking(session) ``` ## `runEndCall()` Met fin à l’appel lorsque l’agent demande à raccrocher. Cette fonction attend les derniers mots de l’agent et prononce, sans interruption, un `message` final facultatif. Elle supprime ensuite la salle et raccroche l’appelant, y compris les appelants SIP. La tâche s’arrête avec ses callbacks enregistrés. Associez-la à [`MastraLLM`](#mastrallm) par l’intermédiaire de son `onToolCall` et à un [outil de fin d’appel](#createendcalltool) sur l’agent côté serveur afin de recréer le raccrochage initié par l’agent dans une session que vous gérez : ```typescript import { MastraLLM } from '@mastra/livekit/plugin' import { DEFAULT_END_CALL_TOOL, runEndCall } from '@mastra/livekit/worker' let ending = false const llm = new MastraLLM({ remote: { baseUrl: process.env.MASTRA_URL!, agentId: 'support' }, onToolCall: ({ toolName }) => { if (toolName !== DEFAULT_END_CALL_TOOL || ending) return ending = true void runEndCall(session, ctx, {}, console) }, }) ``` Les constantes exportées `DEFAULT_END_CALL_TOOL` (`'endCall'`), `DEFAULT_END_CALL_REASON` et `DEFAULT_END_CALL_MAX_WAIT_MS` (30000) contiennent les valeurs par défaut. ### Paramètres **session** (`voice.AgentSession`): Session dont l’agent termine ses derniers mots. **ctx** (`JobContext`): Contexte de tâche LiveKit utilisé pour supprimer la salle et arrêter la tâche. **config** (`{ message?: string; reason?: string; maxWaitMs?: number; drainMs?: number }`): Message final facultatif prononcé avant le raccrochage, motif d’arrêt à enregistrer, délai de sécurité pour attendre les derniers mots et délai de vidage après lecture (800 ms par défaut), qui permet au son mis en mémoire tampon chez l’appelant de finir d’être lu avant la suppression de la salle — le suivi de la lecture de LiveKit est local au worker ; raccrocher dès qu’il se termine coupe donc les adieux. **logger** (`{ warn: (message: string, ...args: unknown[]) => void }`): Reçoit des avertissements lorsque les étapes de fermeture échouent. Transmettez votre logger ou console. ## `createEndCallTool()` Construit l’outil Mastra qu’un agent appelle lorsqu’il souhaite mettre fin à l’appel. L’outil signale cette intention et peut effectuer des opérations de suivi facultatives. Le worker réalise le raccrochage proprement dit. L’outil se trouve dans le point d’entrée racine utilisable en toute sécurité côté serveur. Ajoutez-le aux agents définis dans le code serveur. ```typescript import { Agent } from '@mastra/core/agent' import { createEndCallTool } from '@mastra/livekit' const supportAgent = new Agent({ id: 'support', name: 'Support', instructions: 'Help the caller. When everything is wrapped up, say goodbye and call endCall as your final action.', model: 'openai/gpt-5-mini', tools: { endCall: createEndCallTool() }, }) ``` Avec `createLiveKitWorker()`, définissez `configuration: { endCall: {} }` : le worker surveille alors l’outil et raccroche. Dans une session que vous gérez, recréez le raccrochage avec [`runEndCall()`](#runendcall). ### Options **id** (`string`): Identifiant de l’outil que l’agent appelle pour mettre fin à l’appel. Doit correspondre au nom surveillé par le worker (la propriété configuration.endCall.tool du worker, ou votre propre vérification onToolCall). (Default: `'endCall'`) **description** (`string`): Remplace la description présentée au modèle lorsqu’il décide d’appeler l’outil. **onEndCall** (`(request: { reason?: string; resourceId?: string; threadId?: string }) => void | Promise`): Hook de suivi appelé lorsque l’agent invoque l’outil — enregistrez le motif ou marquez l’appel comme résolu. Il s’exécute pendant le tour ; veillez à ce qu’il soit rapide. Il ne raccroche pas l’appel. ## `liveKitConnectionRoute()` Renvoie une [route d’API](https://mastra.zisheng.pro/fr/docs/server/custom-api-routes) qui génère un token d’accès LiveKit et dispatche l’agent vocal dans la salle. Les frontends l’appellent pour rejoindre une session. ```typescript import { Mastra } from '@mastra/core/mastra' import { liveKitConnectionRoute } from '@mastra/livekit' export const mastra = new Mastra({ server: { apiRoutes: [liveKitConnectionRoute({ agentName: 'mastra-voice' })], }, }) ``` La route accepte un corps JSON comportant les champs facultatifs `agentId`, `threadId` et `resourceId`, et répond avec `{ serverUrl, roomName, participantName, participantToken }`. Par défaut, le `threadId` correspond au nom de salle généré. ### Options **path** (`string`): Chemin de la route. (Default: `'/voice/livekit/connection-details'`) **serverUrl** (`string`): URL du serveur LiveKit. (Default: `process.env.LIVEKIT_URL`) **apiKey** (`string`): Clé d’API LiveKit. (Default: `process.env.LIVEKIT_API_KEY`) **apiSecret** (`string`): Secret d’API LiveKit. (Default: `process.env.LIVEKIT_API_SECRET`) **agentName** (`string`): Nom de l’agent LiveKit pour un dispatch explicite. Doit correspondre à l’agentName du worker. (Default: `'mastra-voice'`) **ttl** (`string | number`): Durée de vie du token. (Default: `'15m'`) **requiresAuth** (`boolean`): Indique si la route nécessite une authentification. (Default: `true`) **roomName** (`string | (args) => string`): Nom de la salle ou fonction qui le déduit de la requête. **participantIdentity** (`string | (args) => string`): Identité du participant ou fonction qui la déduit de la requête. **metadata** (`(args) => LiveKitSessionMetadata | Promise`): Construit les métadonnées de session transmises au worker. Par défaut, transmet agentId, threadId et resourceId depuis le corps de la requête. ## `dispatchVoiceSession()` Dispatche par programmation un agent vocal Mastra dans une salle LiveKit, pour les sessions initiées par le serveur telles que les appels sortants. ```typescript import { dispatchVoiceSession } from '@mastra/livekit' await dispatchVoiceSession({ roomName: 'support-call-42', agentName: 'mastra-voice', metadata: { agentId: 'support', threadId: 'thread-42' }, }) ``` ### Options **roomName** (`string`): Salle dans laquelle dispatcher l’agent. Créée à la demande. **agentName** (`string`): Doit correspondre à l’agentName du worker. (Default: `'mastra-voice'`) **metadata** (`LiveKitSessionMetadata`): Métadonnées de session : agentId, threadId, resourceId, requestContext. **serverUrl** (`string`): URL du serveur LiveKit. (Default: `process.env.LIVEKIT_URL`) **apiKey** (`string`): Clé d’API LiveKit. (Default: `process.env.LIVEKIT_API_KEY`) **apiSecret** (`string`): Secret d’API LiveKit. (Default: `process.env.LIVEKIT_API_SECRET`) ## `LiveKitSessionMetadata` Métadonnées transmises du serveur Mastra au worker par le dispatch de tâche LiveKit. **agentId** (`string`): Agent Mastra à exécuter, désigné par sa clé enregistrée ou son identifiant. **threadId** (`string`): Identifiant du thread de mémoire. Utilise par défaut le nom de la salle LiveKit. **resourceId** (`string`): Identifiant de la ressource de mémoire, généralement celui de l’utilisateur final. **requestContext** (`Record`): Entrées d’un objet simple restaurées dans un RequestContext pour l’exécution de l’agent. Les métadonnées sont transmises sous forme de chaîne JSON. `liveKitConnectionRoute()` et `dispatchVoiceSession()` les sérialisent pour vous ; utilisez `serializeSessionMetadata(metadata)` lorsque vous effectuez le dispatch depuis votre propre code, ou écrivez directement le JSON dans une configuration côté LiveKit, telle qu’une règle de dispatch SIP. Les entrées de `requestContext` sont accessibles à chaque tour de l’appel dans les instructions définies à l’exécution, les outils et les processeurs d’entrée de l’agent. ## Voir aussi - [Voix en temps réel](https://mastra.zisheng.pro/fr/guides/voice/realtime-voice) - [Documentation de LiveKit Agents](https://docs.livekit.io/agents/)