@mastra/livekit 0.0.0 → 0.2.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +80 -0
  2. package/LICENSE.md +30 -0
  3. package/README.md +270 -7
  4. package/dist/bridge.d.ts +153 -0
  5. package/dist/bridge.d.ts.map +1 -0
  6. package/dist/chunk-2E3MTAOA.js +133 -0
  7. package/dist/chunk-2E3MTAOA.js.map +1 -0
  8. package/dist/chunk-MWTEZOBS.cjs +139 -0
  9. package/dist/chunk-MWTEZOBS.cjs.map +1 -0
  10. package/dist/constants.d.ts +3 -0
  11. package/dist/constants.d.ts.map +1 -0
  12. package/dist/dispatch.d.ts +20 -0
  13. package/dist/dispatch.d.ts.map +1 -0
  14. package/dist/index.cjs +105 -0
  15. package/dist/index.cjs.map +1 -0
  16. package/dist/index.d.ts +10 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +91 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/messages.d.ts +24 -0
  21. package/dist/messages.d.ts.map +1 -0
  22. package/dist/metadata.d.ts +17 -0
  23. package/dist/metadata.d.ts.map +1 -0
  24. package/dist/observability.d.ts +46 -0
  25. package/dist/observability.d.ts.map +1 -0
  26. package/dist/routes.d.ts +52 -0
  27. package/dist/routes.d.ts.map +1 -0
  28. package/dist/run.d.ts +32 -0
  29. package/dist/run.d.ts.map +1 -0
  30. package/dist/voice-thread.d.ts +23 -0
  31. package/dist/voice-thread.d.ts.map +1 -0
  32. package/dist/worker-entry.cjs +656 -0
  33. package/dist/worker-entry.cjs.map +1 -0
  34. package/dist/worker-entry.d.ts +8 -0
  35. package/dist/worker-entry.d.ts.map +1 -0
  36. package/dist/worker-entry.js +652 -0
  37. package/dist/worker-entry.js.map +1 -0
  38. package/dist/worker-setup.d.ts +5 -0
  39. package/dist/worker-setup.d.ts.map +1 -0
  40. package/dist/worker.d.ts +187 -0
  41. package/dist/worker.d.ts.map +1 -0
  42. package/dist/workflow-generator.d.ts +92 -0
  43. package/dist/workflow-generator.d.ts.map +1 -0
  44. package/package.json +24 -14
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/messages.ts","../src/bridge.ts","../src/observability.ts","../src/voice-thread.ts","../src/worker-setup.ts","../src/worker.ts","../src/run.ts"],"names":["ReadableStream","RequestContext","llm","voice","getOrCreateSpan","SpanType","metrics","randomUUID","InferenceRunner","defineAgent","parseSessionMetadata","requestContext","createWorkflowReplyGenerator","fileURLToPath","cli","ServerOptions","DEFAULT_LIVEKIT_AGENT_NAME"],"mappings":"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","file":"worker-entry.cjs","sourcesContent":["import type { llm } from '@livekit/agents';\n\nexport type VoiceTurnMessage =\n | { role: 'system'; content: string }\n | { role: 'user'; content: string }\n | { role: 'assistant'; content: string };\n\nfunction textOfMessage(message: llm.ChatMessage): string {\n const parts: string[] = [];\n for (const part of message.content) {\n if (typeof part === 'string') {\n parts.push(part);\n } else if (part.type === 'instructions') {\n parts.push(part.value);\n } else if (part.type === 'audio_content' && part.transcript) {\n parts.push(part.transcript);\n }\n }\n return parts.join('\\n').trim();\n}\n\nfunction toVoiceTurnMessage(item: llm.ChatItem): VoiceTurnMessage | undefined {\n if (item.type !== 'message') return undefined;\n const content = textOfMessage(item);\n if (!content) return undefined;\n if (item.role === 'user') return { role: 'user', content };\n if (item.role === 'assistant') return { role: 'assistant', content };\n // 'system' and 'developer' both map to a Mastra system message.\n return { role: 'system', content };\n}\n\n/**\n * Extracts only the messages added since the agent last spoke. Used when Mastra Memory is\n * the source of truth for conversation history: prior turns are already persisted in the\n * thread, so re-sending them would duplicate history.\n */\nexport function extractNewTurnMessages(chatCtx: llm.ChatContext): VoiceTurnMessage[] {\n const items = chatCtx.items;\n let lastAssistantIdx = -1;\n for (let i = items.length - 1; i >= 0; i--) {\n const item = items[i];\n if (item?.type === 'message' && item.role === 'assistant') {\n lastAssistantIdx = i;\n break;\n }\n }\n const messages: VoiceTurnMessage[] = [];\n for (const item of items.slice(lastAssistantIdx + 1)) {\n const message = toVoiceTurnMessage(item);\n if (message) messages.push(message);\n }\n return messages;\n}\n\n/**\n * Converts the full LiveKit chat context to Mastra messages. Used when the bridge runs\n * without Mastra Memory and LiveKit's in-session context is the only history. The agent's\n * LiveKit-level instructions are excluded — the Mastra agent applies its own instructions.\n */\nexport function chatContextToMessages(chatCtx: llm.ChatContext): VoiceTurnMessage[] {\n const withoutInstructions = chatCtx.copy({ excludeInstructions: true, excludeFunctionCall: true });\n const messages: VoiceTurnMessage[] = [];\n for (const item of withoutInstructions.items) {\n const message = toVoiceTurnMessage(item);\n if (message) messages.push(message);\n }\n return messages;\n}\n","import { ReadableStream } from 'node:stream/web';\nimport { llm, voice } from '@livekit/agents';\nimport type { Agent as MastraAgent, AgentExecutionOptionsBase } from '@mastra/core/agent';\nimport type { TracingContext } from '@mastra/core/observability';\nimport { RequestContext } from '@mastra/core/request-context';\nimport { chatContextToMessages, extractNewTurnMessages } from './messages';\nimport type { VoiceTurnMessage } from './messages';\n\nconst DEFAULT_INSTRUCTIONS = 'You are a helpful voice assistant powered by a Mastra agent.';\n\nexport type MastraStreamOptions = Partial<AgentExecutionOptionsBase<unknown>>;\n\nexport interface VoiceToolCall {\n toolCallId: string;\n toolName: string;\n args?: unknown;\n}\n\nexport interface MastraVoiceAgentMemory {\n thread: string;\n resource?: string;\n}\n\n/**\n * Per-turn context handed to a {@link VoiceReplyGenerator}. LiveKit calls `llmNode` once per\n * detected user turn; the bridge builds this context and asks the generator for the reply.\n */\nexport interface VoiceTurnContext {\n /**\n * The messages to generate a reply from. With Mastra Memory on, only the messages new since\n * the agent last spoke (history comes from the thread); with memory off, the full session.\n *\n * For a workflow / custom generator: pass these straight to a memory-backed `agent.stream(...,\n * { memory })` inside a step so the agent backfills history from the thread (no duplication). A\n * stateless workflow that wants the entire transcript every turn should read `chatCtx` instead\n * (e.g. `chatContextToMessages(chatCtx)`), since there is no thread to backfill from.\n */\n messages: VoiceTurnMessage[];\n /** The raw LiveKit chat context, for generators that want the full transcript or message parts. */\n chatCtx: llm.ChatContext;\n /** Resolved memory mapping for the call, or `false` when memory is disabled. */\n memory: MastraVoiceAgentMemory | false;\n /** Request context forwarded to generation. */\n requestContext?: RequestContext;\n /** Voice-call span context, so each turn's generation nests under the call trace. */\n tracingContext?: TracingContext;\n}\n\n/**\n * What a turn produced, handed to {@link VoiceTurnCompleteHook} after the reply finishes.\n */\nexport interface VoiceTurnResult {\n /** The assistant reply text streamed this turn, accumulated from the model's text deltas. */\n text: string;\n /** Tool calls the agent made during the turn, in order. */\n toolCalls: VoiceToolCall[];\n /** True when barge-in cut the turn short before it finished streaming. */\n interrupted: boolean;\n}\n\n/** {@link VoiceTurnContext} plus the reply it produced. Passed to {@link VoiceTurnCompleteHook}. */\nexport interface VoiceTurnCompleteContext extends VoiceTurnContext {\n /** The reply the agent produced this turn. */\n result: VoiceTurnResult;\n}\n\n/**\n * Called once per turn AFTER the reply has finished streaming to text-to-speech — off the audio\n * path. It runs fire-and-forget: the turn does not await it, so post-turn work (memory\n * maintenance, CRM writes, analytics) never delays what the caller hears or the next turn. A\n * thrown error or rejected promise is logged, not propagated. Because the resolved `memory`\n * mapping (`thread`/`resource`) is on the context, this is the place for a truly non-blocking\n * `memory.updateWorkingMemory(...)`. See {@link MastraVoiceAgentOptions.onTurnComplete}.\n */\nexport type VoiceTurnCompleteHook = (ctx: VoiceTurnCompleteContext) => void | Promise<void>;\n\n/**\n * Produces a stream of text deltas for one conversational turn, or `null` to stay silent.\n * Cancelling the returned stream (LiveKit does this on barge-in) must abort the underlying\n * generation. Built-in implementations: {@link createAgentReplyGenerator} (a Mastra agent) and\n * `createWorkflowReplyGenerator` (a Mastra workflow).\n */\nexport type VoiceReplyGenerator = (\n ctx: VoiceTurnContext,\n) => ReadableStream<string> | null | Promise<ReadableStream<string> | null>;\n\nexport interface AgentReplyGeneratorOptions {\n /** The Mastra agent that generates replies. Tools and memory run inside this agent. */\n agent: MastraAgent;\n /** Extra options merged into every `agent.stream()` call (e.g. `tracingContext`). */\n streamOptions?: MastraStreamOptions;\n /** Speak a short phrase while a tool call runs. See {@link MastraVoiceAgentOptions.toolFeedback}. */\n toolFeedback?: (toolCall: VoiceToolCall) => string | undefined | void;\n /** Fired off the audio path after the reply streams. See {@link MastraVoiceAgentOptions.onTurnComplete}. */\n onTurnComplete?: VoiceTurnCompleteHook;\n}\n\n/**\n * A {@link VoiceReplyGenerator} backed by a Mastra agent: runs the agent's full loop (model,\n * tools, memory) and streams its text deltas. On barge-in the returned stream is cancelled,\n * which aborts the in-flight `agent.stream()`.\n */\nexport function createAgentReplyGenerator(options: AgentReplyGeneratorOptions): VoiceReplyGenerator {\n const { agent, streamOptions, toolFeedback, onTurnComplete } = options;\n return ctx => {\n if (ctx.messages.length === 0) return null;\n\n const abortController = new AbortController();\n const mergedOptions: MastraStreamOptions = {\n ...streamOptions,\n abortSignal: abortController.signal,\n };\n if (ctx.memory) mergedOptions.memory = ctx.memory;\n if (ctx.requestContext) mergedOptions.requestContext = ctx.requestContext;\n\n let cancelled = false;\n // Accumulated as the turn streams so the post-turn hook can see what was actually produced.\n let replyText = '';\n const toolCalls: VoiceToolCall[] = [];\n\n // Fire-and-forget after the reply has streamed: off the audio path (the caller already heard\n // the text), and not awaited, so it never delays the next turn. Errors are logged, not thrown.\n const emitTurnComplete = (interrupted: boolean) => {\n if (!onTurnComplete) return;\n const completeCtx: VoiceTurnCompleteContext = { ...ctx, result: { text: replyText, toolCalls, interrupted } };\n Promise.resolve()\n .then(() => onTurnComplete(completeCtx))\n .catch(error => {\n console.warn('@mastra/livekit: onTurnComplete hook threw', error);\n });\n };\n\n return new ReadableStream<string>({\n start: async controller => {\n try {\n const result = await agent.stream(ctx.messages, mergedOptions);\n for await (const chunk of result.fullStream) {\n if (cancelled) break;\n if (chunk.type === 'text-delta') {\n if (chunk.payload.text) {\n replyText += chunk.payload.text;\n controller.enqueue(chunk.payload.text);\n }\n } else if (chunk.type === 'tool-call') {\n const toolCall: VoiceToolCall = {\n toolCallId: chunk.payload.toolCallId,\n toolName: chunk.payload.toolName,\n args: chunk.payload.args,\n };\n toolCalls.push(toolCall);\n if (toolFeedback) {\n const filler = toolFeedback(toolCall);\n if (filler) controller.enqueue(filler.endsWith(' ') ? filler : `${filler} `);\n }\n } else if (chunk.type === 'error') {\n const error = chunk.payload.error;\n throw error instanceof Error ? error : new Error(String(error));\n }\n }\n if (!cancelled) controller.close();\n // Success, or a clean barge-in break out of the loop: the turn is done either way.\n emitTurnComplete(cancelled);\n } catch (error) {\n // Barge-in cancels the stream and aborts generation; that's not a failure — the turn\n // still completed (interrupted), so the hook still fires for memory reconciliation.\n if (cancelled || abortController.signal.aborted) {\n emitTurnComplete(true);\n return;\n }\n controller.error(error);\n }\n },\n cancel: () => {\n cancelled = true;\n abortController.abort();\n },\n });\n };\n}\n\nexport interface MastraVoiceAgentOptions {\n /**\n * The Mastra agent that generates replies. Tools and memory run inside this agent. Provide\n * either this or {@link MastraVoiceAgentOptions.generate}.\n */\n agent?: MastraAgent;\n /**\n * A lower-level reply generator (e.g. from `createWorkflowReplyGenerator`). Use instead of\n * `agent` to drive replies with a workflow or any custom generator.\n */\n generate?: VoiceReplyGenerator;\n /**\n * Conversation persistence. When set, only messages new since the agent last spoke are\n * sent each turn and Mastra Memory supplies history. When `false`, the full LiveKit\n * in-session context is sent on every turn instead.\n */\n memory?: MastraVoiceAgentMemory | false;\n /** Request context entries forwarded to generation. */\n requestContext?: RequestContext | Record<string, unknown>;\n /**\n * Called when the Mastra agent starts a tool call mid-reply. Return a short phrase (e.g. \"Let\n * me look that up.\") to speak it while the tool runs; it also appears in the transcript. Return\n * nothing to stay silent. Applies to the agent generator built here; the workflow generator\n * takes its own equivalent via `createWorkflowReplyGenerator`.\n */\n toolFeedback?: (toolCall: VoiceToolCall) => string | undefined | void;\n /**\n * Called once per turn after the reply has finished streaming to text-to-speech. Runs off the\n * audio path and fire-and-forget — the turn does not await it — so post-turn memory\n * maintenance, CRM writes, or analytics never delay the caller or the next turn. The context\n * carries the produced reply ({@link VoiceTurnResult}) and the resolved `memory` mapping, so\n * this is where a truly non-blocking `memory.updateWorkingMemory(...)` belongs. A thrown error\n * or rejected promise is logged, not propagated. Applies to the agent generator built here; the\n * workflow generator takes its own via `createWorkflowReplyGenerator`.\n */\n onTurnComplete?: VoiceTurnCompleteHook;\n /** Extra options merged into every `agent.stream()` call (agent generator only). */\n streamOptions?: MastraStreamOptions;\n /** LiveKit agent instructions. Unused for reply generation (the Mastra agent/workflow applies its own). */\n instructions?: string;\n id?: voice.AgentOptions<unknown>['id'];\n stt?: voice.AgentOptions<unknown>['stt'];\n vad?: voice.AgentOptions<unknown>['vad'];\n tts?: voice.AgentOptions<unknown>['tts'];\n turnHandling?: voice.AgentOptions<unknown>['turnHandling'];\n}\n\nfunction toRequestContext(value: RequestContext | Record<string, unknown> | undefined): RequestContext | undefined {\n if (!value) return undefined;\n if (value instanceof RequestContext) return value;\n return new RequestContext<unknown>(Object.entries(value));\n}\n\n/**\n * The session only runs its cascaded reply pipeline when an `llm` instance is present —\n * `llmNode` replaces the inference step, but the gate checks `llm instanceof LLM`. This\n * placeholder satisfies the gate; the Mastra agent/workflow does the actual generation.\n */\nclass MastraPlaceholderLLM extends llm.LLM {\n label(): string {\n return 'mastra.MastraVoiceAgent';\n }\n\n override get model(): string {\n return 'mastra-agent';\n }\n\n override get provider(): string {\n return 'mastra';\n }\n\n chat(): llm.LLMStream {\n throw new Error(\n '@mastra/livekit: reply generation runs through the Mastra agent via llmNode; the placeholder LLM cannot be used for inference.',\n );\n }\n}\n\n/**\n * A LiveKit `voice.Agent` whose replies come from a Mastra agent or workflow.\n *\n * LiveKit keeps ownership of the audio loop (VAD, STT, turn detection, TTS, barge-in) and calls\n * `llmNode` once per detected user turn; the node delegates to a {@link VoiceReplyGenerator}\n * which streams text deltas back. On barge-in LiveKit cancels the returned stream, which aborts\n * the in-flight generation.\n */\nexport class MastraVoiceAgent extends voice.Agent {\n readonly mastraAgent?: MastraAgent;\n readonly memory: MastraVoiceAgentMemory | false;\n readonly requestContext?: RequestContext;\n readonly streamOptions?: MastraStreamOptions;\n private readonly replyGenerator: VoiceReplyGenerator;\n\n constructor(options: MastraVoiceAgentOptions) {\n if (options.agent && options.generate) {\n throw new Error(\n '@mastra/livekit: MastraVoiceAgent requires `agent` or `generate`, not both — they are mutually exclusive reply sources.',\n );\n }\n super({\n id: options.id,\n instructions: options.instructions ?? DEFAULT_INSTRUCTIONS,\n stt: options.stt,\n vad: options.vad,\n llm: new MastraPlaceholderLLM(),\n tts: options.tts,\n turnHandling: options.turnHandling,\n });\n this.memory = options.memory ?? false;\n this.requestContext = toRequestContext(options.requestContext);\n this.streamOptions = options.streamOptions;\n\n if (options.generate) {\n this.replyGenerator = options.generate;\n } else if (options.agent) {\n this.mastraAgent = options.agent;\n this.replyGenerator = createAgentReplyGenerator({\n agent: options.agent,\n streamOptions: options.streamOptions,\n toolFeedback: options.toolFeedback,\n onTurnComplete: options.onTurnComplete,\n });\n } else {\n throw new Error('@mastra/livekit: MastraVoiceAgent requires `agent` or `generate`.');\n }\n }\n\n override async llmNode(\n chatCtx: llm.ChatContext,\n _toolCtx: llm.ToolContext,\n _modelSettings: voice.ModelSettings,\n ): Promise<ReadableStream<llm.ChatChunk | string> | null> {\n const messages: VoiceTurnMessage[] =\n this.memory === false ? chatContextToMessages(chatCtx) : extractNewTurnMessages(chatCtx);\n if (messages.length === 0) return null;\n\n return this.replyGenerator({\n messages,\n chatCtx,\n memory: this.memory,\n requestContext: this.requestContext,\n tracingContext: this.streamOptions?.tracingContext,\n });\n }\n}\n\nexport function createMastraVoiceAgent(options: MastraVoiceAgentOptions): MastraVoiceAgent {\n return new MastraVoiceAgent(options);\n}\n","import { metrics, voice } from '@livekit/agents';\nimport type { Mastra } from '@mastra/core/mastra';\nimport { getOrCreateSpan, SpanType } from '@mastra/core/observability';\nimport type { Span, TracingContext } from '@mastra/core/observability';\nimport type { RequestContext } from '@mastra/core/request-context';\nimport type { LiveKitSessionMetadata } from './metadata';\n\nexport interface VoiceCallObservabilityOptions {\n /** The Mastra instance whose observability config receives the spans. */\n mastra: Mastra;\n /** Resolved Mastra agent id/key answering the call (for span attribution). */\n agentId: string;\n /** LiveKit room name for this session. */\n roomName: string;\n /** Dispatch metadata for the session. */\n metadata: LiveKitSessionMetadata;\n /** Request context forwarded to span sampling. */\n requestContext?: RequestContext;\n}\n\nexport interface VoiceCallObservability {\n /** The root `voice call` span. Each turn's agent run and every pipeline metric nests under it. */\n readonly span: Span<SpanType.GENERIC>;\n /** Thread into the bridge's `streamOptions` so each turn's agent run nests under the call. */\n readonly tracingContext: TracingContext;\n /** Subscribe to the session's `metrics_collected` events. Call once, before `session.start()`. */\n attach(session: voice.AgentSession): void;\n /** Close the call span with the usage roll-up. Idempotent; safe to call from a shutdown hook. */\n finalize(options?: { error?: unknown }): void;\n}\n\nfunction modelMeta(metadata?: metrics.MetricsMetadata): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n if (metadata?.modelProvider) out.modelProvider = metadata.modelProvider;\n if (metadata?.modelName) out.modelName = metadata.modelName;\n return out;\n}\n\nconst ms = (n: number) => `${Math.round(n)}ms`;\nconst secs = (n: number) => `${(n / 1000).toFixed(1)}s`;\n\n/**\n * Maps a LiveKit pipeline metric to an event-span name and the latency/usage fields worth\n * recording. The name carries the headline number so it reads in the trace timeline without\n * opening the span. Metrics this release does not surface (interruption, EOT inference, avatar)\n * return `undefined` — they still feed the session usage roll-up via the ModelUsageCollector.\n */\nfunction describeMetric(metric: metrics.AgentMetrics): { name: string; data: Record<string, unknown> } | undefined {\n switch (metric.type) {\n case 'eou_metrics':\n // End-of-utterance: how long turn detection took to decide the caller finished.\n return {\n name: `eou ${ms(metric.endOfUtteranceDelayMs)}`,\n data: {\n endOfUtteranceDelayMs: metric.endOfUtteranceDelayMs,\n transcriptionDelayMs: metric.transcriptionDelayMs,\n onUserTurnCompletedDelayMs: metric.onUserTurnCompletedDelayMs,\n },\n };\n case 'stt_metrics':\n return {\n name: `stt ${secs(metric.audioDurationMs)}`,\n data: {\n audioDurationMs: metric.audioDurationMs,\n durationMs: metric.durationMs,\n streamed: metric.streamed,\n ...modelMeta(metric.metadata),\n },\n };\n case 'llm_metrics':\n // LiveKit's view of the reply latency (includes transport), distinct from the Mastra\n // agent-run model span: time-to-first-token is what the caller actually waits for.\n return {\n name: `llm ttft ${ms(metric.ttftMs)}`,\n data: {\n ttftMs: metric.ttftMs,\n durationMs: metric.durationMs,\n tokensPerSecond: metric.tokensPerSecond,\n promptTokens: metric.promptTokens,\n completionTokens: metric.completionTokens,\n totalTokens: metric.totalTokens,\n cancelled: metric.cancelled,\n ...modelMeta(metric.metadata),\n },\n };\n case 'tts_metrics':\n return {\n name: `tts ttfb ${ms(metric.ttfbMs)}`,\n data: {\n ttfbMs: metric.ttfbMs,\n durationMs: metric.durationMs,\n audioDurationMs: metric.audioDurationMs,\n charactersCount: metric.charactersCount,\n cancelled: metric.cancelled,\n streamed: metric.streamed,\n ...modelMeta(metric.metadata),\n },\n };\n case 'vad_metrics':\n return {\n name: 'vad',\n data: {\n idleTimeMs: metric.idleTimeMs,\n inferenceCount: metric.inferenceCount,\n inferenceDurationTotalMs: metric.inferenceDurationTotalMs,\n },\n };\n case 'realtime_model_metrics':\n return {\n name: `realtime ttft ${ms(metric.ttftMs)}`,\n data: {\n ttftMs: metric.ttftMs,\n durationMs: metric.durationMs,\n tokensPerSecond: metric.tokensPerSecond,\n promptTokens: metric.inputTokens,\n completionTokens: metric.outputTokens,\n totalTokens: metric.totalTokens,\n ...modelMeta(metric.metadata),\n },\n };\n default:\n return undefined;\n }\n}\n\n/**\n * Opens a `voice call` trace for one LiveKit session and bridges LiveKit's voice-pipeline\n * metrics into Mastra observability.\n *\n * The returned root span groups everything about the call: each conversation turn's Mastra\n * agent run (nested via {@link VoiceCallObservability.tracingContext}) plus an event span for\n * every STT, TTS, end-of-utterance, VAD, and LLM-latency metric LiveKit emits. Metrics are\n * point-in-time, so they're recorded as event spans (no duration) with the value in the name.\n * The root closes on the session `close` event with a per-model usage roll-up (token, character,\n * and audio totals for the whole call) from a `ModelUsageCollector`.\n *\n * Returns `undefined` when the Mastra instance has no observability configured, so callers\n * can treat instrumentation as a no-op without branching on config.\n */\nexport function startVoiceCallObservability(\n options: VoiceCallObservabilityOptions,\n): VoiceCallObservability | undefined {\n const span = getOrCreateSpan<SpanType.GENERIC>({\n mastra: options.mastra,\n type: SpanType.GENERIC,\n name: 'voice call',\n requestContext: options.requestContext,\n metadata: {\n agentId: options.agentId,\n roomName: options.roomName,\n ...(options.metadata.threadId ? { threadId: options.metadata.threadId } : {}),\n ...(options.metadata.resourceId ? { resourceId: options.metadata.resourceId } : {}),\n },\n });\n\n if (!span) return undefined;\n\n const usage = new metrics.ModelUsageCollector();\n let finalized = false;\n\n const finalize = (opts?: { error?: unknown }): void => {\n if (finalized) return;\n finalized = true;\n const summary = usage.flatten();\n if (opts?.error) {\n span.error({\n error: opts.error instanceof Error ? opts.error : new Error(String(opts.error)),\n metadata: { usage: summary },\n });\n } else {\n span.end({ output: { usage: summary } });\n }\n };\n\n return {\n span,\n tracingContext: { currentSpan: span },\n attach(session: voice.AgentSession) {\n session.on(voice.AgentSessionEventTypes.MetricsCollected, (event: { metrics: metrics.AgentMetrics }) => {\n usage.collect(event.metrics);\n const described = describeMetric(event.metrics);\n if (!described) return;\n // Event span: a point-in-time measurement, not a duration. The value is in the name\n // (for the timeline) and the full fields are on output.\n span.createEventSpan({ type: SpanType.GENERIC, name: described.name, output: described.data });\n });\n // The call ends when the session closes — finalize then so the root span and its usage\n // roll-up land promptly. The worker's ctx.addShutdownCallback is a backstop for abnormal\n // termination (the job ending without a clean session close).\n session.on(voice.AgentSessionEventTypes.Close, (event: { error?: unknown }) => {\n finalize({ error: event?.error ?? undefined });\n });\n },\n finalize,\n };\n}\n","import { randomUUID } from 'node:crypto';\nimport type { MastraDBMessage } from '@mastra/core/agent';\nimport type { MastraMemory } from '@mastra/core/memory';\n\nexport interface VoiceThreadArgs {\n memory: MastraMemory;\n threadId: string;\n resourceId: string;\n}\n\n/**\n * Creates the call's memory thread up front when it doesn't exist yet, titled and tagged\n * so it reads as a voice call in Studio's thread list instead of an untitled thread that\n * only appears after the first exchange.\n */\nexport async function ensureVoiceCallThread({\n memory,\n threadId,\n resourceId,\n roomName,\n}: VoiceThreadArgs & { roomName: string }): Promise<void> {\n const existing = await memory.getThreadById({ threadId });\n if (existing) return;\n await memory.createThread({\n threadId,\n resourceId,\n title: 'Voice call',\n metadata: { source: 'livekit', roomName },\n });\n}\n\n/**\n * Persists the spoken greeting as an assistant message. The greeting is spoken via TTS\n * without going through the Mastra agent, so without this the saved thread would start\n * at the caller's first words instead of being a faithful call transcript.\n */\nexport async function persistSpokenGreeting({\n memory,\n threadId,\n resourceId,\n greeting,\n}: VoiceThreadArgs & { greeting: string }): Promise<void> {\n // A whitespace/empty greeting would persist a low-value assistant message; skip it.\n if (!greeting.trim()) return;\n const message: MastraDBMessage = {\n id: randomUUID(),\n role: 'assistant',\n type: 'text',\n createdAt: new Date(),\n threadId,\n resourceId,\n content: {\n format: 2,\n parts: [{ type: 'text', text: greeting }],\n metadata: { source: 'voice', kind: 'greeting' },\n },\n };\n await memory.saveMessages({ messages: [message] });\n}\n","/**\n * Coordination between worker definition and worker startup. LiveKit plugins register\n * their inference runners at module-import time, and the AgentServer only spawns the\n * inference process for runners registered before it starts — so plugin imports kicked\n * off by `createLiveKitWorker()` must complete before `runLiveKitWorker()` boots the\n * server.\n */\nconst pendingSetup: Promise<unknown>[] = [];\nconst requestedEouMethods = new Set<string>();\n\nexport function queueWorkerSetup(setup: Promise<unknown>): void {\n pendingSetup.push(setup);\n}\n\nexport function workerSetupComplete(): Promise<unknown> {\n return Promise.allSettled(pendingSetup);\n}\n\nexport function requestEouMethod(method: string): void {\n requestedEouMethods.add(method);\n}\n\nexport function isEouMethodRequested(method: string): boolean {\n return requestedEouMethods.has(method);\n}\n","import { defineAgent, InferenceRunner, voice } from '@livekit/agents';\nimport type { JobContext, JobProcess, VAD } from '@livekit/agents';\nimport type { Agent as MastraAgent } from '@mastra/core/agent';\nimport type { Mastra } from '@mastra/core/mastra';\nimport type { MastraMemory } from '@mastra/core/memory';\nimport { RequestContext } from '@mastra/core/request-context';\nimport type { Workflow } from '@mastra/core/workflows';\nimport { createMastraVoiceAgent } from './bridge';\nimport type {\n MastraVoiceAgent,\n MastraVoiceAgentMemory,\n VoiceReplyGenerator,\n VoiceToolCall,\n VoiceTurnCompleteHook,\n VoiceTurnContext,\n} from './bridge';\nimport { parseSessionMetadata } from './metadata';\nimport type { LiveKitSessionMetadata } from './metadata';\nimport { startVoiceCallObservability } from './observability';\nimport { ensureVoiceCallThread, persistSpokenGreeting } from './voice-thread';\nimport { isEouMethodRequested, queueWorkerSetup, requestEouMethod } from './worker-setup';\nimport { createWorkflowReplyGenerator } from './workflow-generator';\n\nconst EOU_METHODS = {\n english: 'lk_end_of_utterance_en',\n multilingual: 'lk_end_of_utterance_multilingual',\n} as const;\n\ninterface WorkerUserData {\n vad?: VAD;\n [key: string]: unknown;\n}\n\ntype TurnDetectionSetting = Exclude<voice.AgentSessionOptions['turnDetection'], undefined>;\n\nexport interface ResolveMastraAgentArgs {\n metadata: LiveKitSessionMetadata;\n ctx: JobContext;\n}\n\nexport interface SessionStartArgs {\n session: voice.AgentSession;\n ctx: JobContext;\n agent: MastraVoiceAgent;\n metadata: LiveKitSessionMetadata;\n}\n\n/** Context handed to {@link CreateLiveKitWorkerOptions.onCallEnd} when the call ends. */\nexport interface VoiceCallEndArgs {\n /** Resolved memory mapping for the call (thread/resource), or `false` if memory was disabled. */\n memory: MastraVoiceAgentMemory | false;\n /**\n * The `Memory` instance backing the call, or `null`. On the agent path it's the agent's\n * (storage-equipped) memory; on the workflow/custom path it's the resolved `memoryInstance`. Use\n * it for end-of-call maintenance — e.g. flush observational memory off the audio path.\n */\n memoryInstance: MastraMemory | null;\n /** Dispatch metadata for the call. */\n metadata: LiveKitSessionMetadata;\n /** Request context for the call, if any. */\n requestContext?: RequestContext;\n /** The LiveKit room name. */\n roomName: string;\n /** The LiveKit job context, for advanced teardown needs. */\n ctx: JobContext;\n}\n\n/**\n * Fired once when the call ends. Runs off the audio path inside LiveKit's shutdown grace window,\n * and — unlike the per-turn {@link MastraVoiceAgentOptions.onTurnComplete} — it is AWAITED, so the\n * work completes before the worker process exits. A thrown error is logged, not propagated.\n */\nexport type VoiceCallEndHook = (args: VoiceCallEndArgs) => void | Promise<void>;\n\nexport interface CreateLiveKitWorkerOptions {\n /** The Mastra instance whose agents handle voice sessions. */\n mastra: Mastra;\n /**\n * Which Mastra agent answers each session: a fixed agent key/id, or a resolver called\n * per session with the dispatch metadata. Defaults to `metadata.agentId`.\n */\n agent?: string | ((args: ResolveMastraAgentArgs) => string | MastraAgent | Promise<string | MastraAgent>);\n /**\n * Generate each turn's reply with a Mastra workflow instead of an agent: a `Workflow`\n * instance, a fixed workflow key/id, or a resolver that returns a workflow id per session.\n * The workflow runs once to completion per turn (LiveKit owns the turn boundary, so there is\n * no suspend/resume). Mutually exclusive with `agent`; requires\n * {@link CreateLiveKitWorkerOptions.workflowInput}.\n */\n workflow?: string | Workflow | ((args: ResolveMastraAgentArgs) => string | Promise<string>);\n /**\n * Maps a turn into the workflow's `inputData`. Required when `workflow` is set. A stateless\n * mapping that passes the full transcript each turn avoids carrying conversation state in the\n * workflow, e.g. `({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) })`.\n */\n workflowInput?: (args: VoiceTurnContext & { metadata: LiveKitSessionMetadata }) => unknown | Promise<unknown>;\n /** Only stream text from this workflow step id. Defaults to every step that writes to its `writer`. */\n replyStep?: string;\n /** Fallback when the workflow streams no text via `writer`: derive the spoken reply from the final result. */\n resultText?: (result: unknown) => string | undefined | void;\n /** Lowest-level escape hatch: supply any reply generator directly (a custom workflow, remote bridge, …). */\n generate?: VoiceReplyGenerator;\n /** Speech-to-text: a LiveKit plugin instance or an inference model string like 'deepgram/nova-3'. */\n stt?: voice.AgentSessionOptions['stt'];\n /** Text-to-speech: a LiveKit plugin instance or an inference model string like 'cartesia/sonic-3'. */\n tts?: voice.AgentSessionOptions['tts'];\n /**\n * Voice activity detection. `'silero'` (default) loads the Silero VAD from\n * `@livekit/agents-plugin-silero`; pass an instance to bring your own, or `false` to disable.\n */\n vad?: VAD | 'silero' | false;\n /**\n * End-of-turn detection. `'multilingual'` or `'english'` load LiveKit's semantic turn\n * detector model from `@livekit/agents-plugin-livekit`; other values are passed through\n * (e.g. `'vad'`, `'stt'`, `'manual'`).\n */\n turnDetection?: 'multilingual' | 'english' | TurnDetectionSetting;\n /** Turn handling tuning (endpointing delays, interruption sensitivity, preemptive generation). */\n turnHandling?: voice.AgentSessionOptions['turnHandling'];\n /** Extra `AgentSession` options merged over what this helper builds. */\n sessionOptions?: Partial<voice.AgentSessionOptions>;\n /**\n * Memory mapping. Defaults to `{ thread: metadata.threadId ?? room name, resource:\n * metadata.resourceId ?? thread }` when the resolved agent has memory configured.\n * Pass `false` to disable, or a function to customize.\n */\n memory?: false | ((args: ResolveMastraAgentArgs & { roomName: string }) => MastraVoiceAgentMemory | false);\n /**\n * The `Memory` instance used to bootstrap the call thread and persist the greeting on the\n * workflow / custom-generator path, where there is no agent to source it from. Ignored on the\n * agent path (the resolved agent's own memory is used). Pass the same `Memory` your workflow\n * steps read and write through, so the saved thread is one faithful transcript (the up-front\n * thread + the persisted greeting + every turn the steps write). If the `Memory` has no\n * `storage` of its own, this worker's Mastra storage is injected into it (same as\n * `agent.getMemory()` does), so a `Memory` that relies on the Mastra instance for storage works.\n */\n memoryInstance?:\n | MastraMemory\n | ((args: ResolveMastraAgentArgs) => MastraMemory | undefined | Promise<MastraMemory | undefined>);\n /**\n * Spoken while a Mastra tool call runs. Works on both the agent and workflow paths; on the\n * workflow path it fires only for tool calls the reply step surfaces to its `writer` (use\n * `pipeAgentReplyToWriter`). See {@link MastraVoiceAgentOptions.toolFeedback}.\n */\n toolFeedback?: (toolCall: VoiceToolCall) => string | undefined | void;\n /**\n * Fired once per turn after the reply has streamed to text-to-speech, off the audio path and\n * fire-and-forget. Works on both the agent and workflow paths. Use it to fully background\n * post-turn memory maintenance — e.g. a non-blocking `memory.updateWorkingMemory(...)` — so it\n * never adds to the caller's latency. See {@link MastraVoiceAgentOptions.onTurnComplete}.\n */\n onTurnComplete?: VoiceTurnCompleteHook;\n /**\n * Fired once when the call ends (participant disconnects / job shuts down), via LiveKit's\n * shutdown callback — entirely off the audio path, when latency no longer matters. Unlike\n * `onTurnComplete`, it is AWAITED within LiveKit's shutdown grace window, so end-of-call work\n * completes before the process exits. The ideal place to flush observational memory once for the\n * whole call (instead of paying for it inline per turn). Keep it to a few seconds so it fits the\n * grace window; a thrown error is logged, not propagated. See {@link VoiceCallEndArgs}.\n */\n onCallEnd?: VoiceCallEndHook;\n /** Static greeting spoken when the session starts. */\n greeting?: string;\n /**\n * Save the spoken greeting to the memory thread as an assistant message, so the saved\n * thread is a faithful call transcript. Defaults to `true`; only applies when a\n * greeting is set and memory is enabled.\n */\n persistGreeting?: boolean;\n /**\n * Voice-pipeline observability. When the Mastra instance has observability configured, each\n * session opens a `voice call` trace: LiveKit's STT, TTS, end-of-utterance, VAD, and LLM\n * latency metrics become child spans, and every turn's Mastra agent run nests under the call,\n * which closes with a token/audio usage roll-up. Defaults to `true`; pass `false` to disable.\n */\n observability?: boolean;\n inputOptions?: Parameters<voice.AgentSession['start']>[0]['inputOptions'];\n outputOptions?: Parameters<voice.AgentSession['start']>[0]['outputOptions'];\n /** Called after the session starts — attach event listeners, trigger replies, etc. */\n onSessionStart?: (args: SessionStartArgs) => void | Promise<void>;\n}\n\nasync function loadSileroVad(): Promise<VAD> {\n let silero;\n try {\n silero = await import('@livekit/agents-plugin-silero');\n } catch (error) {\n throw new Error(\n \"@mastra/livekit: voice activity detection requires '@livekit/agents-plugin-silero'. \" +\n 'Install it, pass your own `vad` instance, or set `vad: false`.',\n { cause: error },\n );\n }\n return silero.VAD.load();\n}\n\nasync function loadTurnDetector(kind: 'multilingual' | 'english'): Promise<TurnDetectionSetting> {\n let plugin;\n try {\n plugin = await import('@livekit/agents-plugin-livekit');\n } catch (error) {\n throw new Error(\n `@mastra/livekit: turnDetection '${kind}' requires '@livekit/agents-plugin-livekit'. ` +\n \"Install it or use a built-in mode like 'vad' or 'stt'.\",\n { cause: error },\n );\n }\n return kind === 'english'\n ? (new plugin.turnDetector.EnglishModel() as TurnDetectionSetting)\n : (new plugin.turnDetector.MultilingualModel() as TurnDetectionSetting);\n}\n\nasync function resolveMastraAgent(\n options: CreateLiveKitWorkerOptions,\n args: ResolveMastraAgentArgs,\n): Promise<MastraAgent> {\n let ref: string | MastraAgent | undefined =\n typeof options.agent === 'function' ? await options.agent(args) : options.agent;\n ref ??= args.metadata.agentId;\n if (!ref) {\n throw new Error(\n '@mastra/livekit: no Mastra agent specified. Set `agent` on createLiveKitWorker or pass ' +\n '`agentId` in the dispatch metadata (e.g. via liveKitConnectionRoute).',\n );\n }\n if (typeof ref !== 'string') return ref;\n try {\n return options.mastra.getAgentById(ref);\n } catch {\n return options.mastra.getAgent(ref);\n }\n}\n\n// Returns the workflow boxed in an object: `Workflow` is thenable (it has a `.then()` builder\n// method), so a bare `Promise<Workflow>` return — or awaiting a `Workflow`-typed value — trips\n// TS's thenable checks and, at runtime, `await workflow` would call the builder's `.then`.\nasync function resolveWorkflow(\n options: CreateLiveKitWorkerOptions,\n args: ResolveMastraAgentArgs,\n): Promise<{ workflow: Workflow }> {\n const resolver = options.workflow;\n // The function form resolves to an id string (safe to await); a Workflow instance is only\n // accepted as a direct value, never awaited.\n const ref: string | Workflow = typeof resolver === 'function' ? await resolver(args) : (resolver ?? '');\n if (!ref) {\n throw new Error('@mastra/livekit: no workflow specified. Set `workflow` on createLiveKitWorker.');\n }\n if (typeof ref !== 'string') return { workflow: ref };\n // getWorkflowById matches by workflow id and falls back to the registration key.\n return { workflow: options.mastra.getWorkflowById(ref as never) as Workflow };\n}\n\nfunction resolveMemory(\n options: CreateLiveKitWorkerOptions,\n mastraAgent: MastraAgent | undefined,\n args: ResolveMastraAgentArgs,\n roomName: string,\n): MastraVoiceAgentMemory | false {\n if (options.memory === false) return false;\n if (typeof options.memory === 'function') return options.memory({ ...args, roomName });\n // With an agent, default to memory only when the agent has its own. With a workflow (no\n // agent), default the thread/resource mapping so the workflow input can use it.\n if (mastraAgent && !mastraAgent.hasOwnMemory()) return false;\n const thread = args.metadata.threadId ?? roomName;\n return { thread, resource: args.metadata.resourceId ?? thread };\n}\n\n// The Memory instance backing thread bootstrap + greeting persistence. With an agent it comes\n// from the agent; on the workflow/custom-generator path there is no agent, so it comes from the\n// `memoryInstance` option (instance or resolver). Returns null when unavailable — bootstrap and\n// greeting persistence are then skipped and the generator owns persistence.\nexport async function resolveMemoryInstance(\n options: Pick<CreateLiveKitWorkerOptions, 'memoryInstance' | 'mastra'>,\n mastraAgent: MastraAgent | undefined,\n args: ResolveMastraAgentArgs,\n requestContext: RequestContext | undefined,\n): Promise<MastraMemory | null> {\n if (mastraAgent) return (await mastraAgent.getMemory({ requestContext })) ?? null;\n const resolver = options.memoryInstance;\n if (!resolver) return null;\n const instance = typeof resolver === 'function' ? await resolver(args) : resolver;\n if (!instance) return null;\n // Mirror Agent.getMemory: a Memory built without its own `storage` relies on the Mastra\n // instance for one. The agent path gets that via getMemory(); on the workflow/custom-generator\n // path we wire it here, so the worker's direct thread bootstrap + greeting persistence have a\n // storage provider instead of throwing \"Memory requires a storage provider\".\n instance.__registerMastra(options.mastra);\n if (!instance.hasOwnStorage) {\n const storage = options.mastra.getStorage();\n if (storage) instance.setStorage(storage);\n }\n return instance;\n}\n\nexport function buildTurnHandling(\n options: Pick<CreateLiveKitWorkerOptions, 'turnHandling'>,\n turnDetection: TurnDetectionSetting | undefined,\n): voice.AgentSessionOptions['turnHandling'] {\n return {\n ...(turnDetection ? { turnDetection } : {}),\n // Preemptive generation re-runs the Mastra agent on interim transcripts (up to 3\n // times per turn), and every run persists the user message to the memory thread —\n // duplicating and even saving partial transcripts. Off by default; opt back in via\n // `turnHandling.preemptiveGeneration` if the latency win matters more than exact\n // thread history.\n preemptiveGeneration: { enabled: false },\n ...options.turnHandling,\n };\n}\n\nasync function resolveInstructions(\n mastraAgent: MastraAgent,\n requestContext: RequestContext | undefined,\n): Promise<string | undefined> {\n try {\n const instructions = await mastraAgent.getInstructions({ requestContext });\n return typeof instructions === 'string' ? instructions : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Builds a LiveKit agent worker definition that answers voice sessions with Mastra agents.\n *\n * Use as the default export of your worker entry file, then run it with the LiveKit\n * agents CLI:\n *\n * ```ts\n * // src/mastra/voice-worker.ts\n * import { fileURLToPath } from 'node:url';\n * import { createLiveKitWorker, runLiveKitWorker } from '@mastra/livekit/worker';\n * import { mastra } from './index';\n *\n * export default createLiveKitWorker({\n * mastra,\n * stt: 'deepgram/nova-3',\n * tts: 'cartesia/sonic-3',\n * turnDetection: 'multilingual',\n * });\n *\n * if (process.argv[1] === fileURLToPath(import.meta.url)) {\n * runLiveKitWorker({ entry: import.meta.url, agentName: 'mastra-voice' });\n * }\n * ```\n */\nexport function createLiveKitWorker(options: CreateLiveKitWorkerOptions) {\n if (options.generate && (options.agent || options.workflow)) {\n throw new Error(\n '@mastra/livekit: set exactly one reply generator — `generate`, `agent`, or `workflow` — not a combination.',\n );\n }\n if (options.agent && options.workflow) {\n throw new Error(\n '@mastra/livekit: set `agent` or `workflow`, not both — they are mutually exclusive reply generators.',\n );\n }\n if (options.workflow && !options.workflowInput) {\n throw new Error(\n '@mastra/livekit: `workflowInput` is required when `workflow` is set. Map the turn into the ' +\n 'workflow inputData, e.g. workflowInput: ({ chatCtx }) => ({ history: chatContextToMessages(chatCtx) }).',\n );\n }\n\n const wantsSileroVad = options.vad === undefined || options.vad === 'silero';\n\n // The turn detector's inference runners register at plugin-import time, and the agent\n // server only spawns its inference process for runners registered before it starts —\n // so begin the import now (worker definition happens at module scope, before\n // runLiveKitWorker boots the server, which awaits this).\n if (options.turnDetection === 'multilingual' || options.turnDetection === 'english') {\n requestEouMethod(EOU_METHODS[options.turnDetection]);\n queueWorkerSetup(\n import('@livekit/agents-plugin-livekit')\n .then(() => {\n // The plugin registers both language runners; keep only the requested ones so\n // the inference process doesn't initialize (and require model files for) both.\n for (const method of Object.values(EOU_METHODS)) {\n if (!isEouMethodRequested(method)) {\n delete InferenceRunner.registeredRunners[method];\n }\n }\n })\n .catch(() => {\n // Surfaced with install guidance when the session actually needs it.\n }),\n );\n }\n\n return defineAgent<WorkerUserData>({\n prewarm: async (proc: JobProcess<WorkerUserData>) => {\n if (wantsSileroVad) {\n proc.userData.vad = await loadSileroVad();\n }\n },\n entry: async (ctx: JobContext<WorkerUserData>) => {\n // Route degradation warnings through the Mastra logger so they honor the app's\n // configured log level and transports instead of writing straight to the console.\n const logger = options.mastra.getLogger();\n const metadata = parseSessionMetadata(ctx.job.metadata);\n const args: ResolveMastraAgentArgs = { metadata, ctx };\n const requestContext = metadata.requestContext\n ? new RequestContext<unknown>(Object.entries(metadata.requestContext))\n : undefined;\n\n // Resolve the per-turn reply generator. Precedence: an explicit `generate` function, then\n // a `workflow` (run-to-completion per turn), then a Mastra `agent` (the default).\n let mastraAgent: MastraAgent | undefined;\n let replyGenerator: VoiceReplyGenerator | undefined;\n let agentLabel: string;\n if (options.generate) {\n replyGenerator = options.generate;\n agentLabel = 'mastra-voice';\n } else if (options.workflow) {\n const { workflow } = await resolveWorkflow(options, args);\n agentLabel = workflow.id;\n const mapInput = options.workflowInput!;\n replyGenerator = createWorkflowReplyGenerator({\n workflow,\n workflowInput: turnCtx => mapInput({ ...turnCtx, metadata }),\n replyStep: options.replyStep,\n resultText: options.resultText,\n toolFeedback: options.toolFeedback,\n onTurnComplete: options.onTurnComplete,\n });\n } else {\n mastraAgent = await resolveMastraAgent(options, args);\n agentLabel = mastraAgent.id ?? mastraAgent.name;\n }\n\n await ctx.connect();\n const roomName = ctx.room.name ?? 'mastra-voice';\n\n let vad: VAD | undefined;\n if (options.vad && options.vad !== 'silero') {\n vad = options.vad;\n } else if (wantsSileroVad) {\n vad = ctx.proc.userData.vad ?? (await loadSileroVad());\n }\n\n let turnDetection: TurnDetectionSetting | undefined;\n if (options.turnDetection === 'multilingual' || options.turnDetection === 'english') {\n turnDetection = await loadTurnDetector(options.turnDetection);\n } else {\n turnDetection = options.turnDetection;\n }\n\n const memory = resolveMemory(options, mastraAgent, args, roomName);\n // The memory instance backs up-front thread bootstrap and greeting persistence. With an\n // agent it comes from the agent; on the workflow/custom-generator path it comes from the\n // `memoryInstance` option. When neither is available it stays null and the generator owns\n // persistence (e.g. saveMessages inside a step).\n const memoryInstance = memory ? await resolveMemoryInstance(options, mastraAgent, args, requestContext) : null;\n if (memory && memoryInstance) {\n try {\n await ensureVoiceCallThread({\n memory: memoryInstance,\n threadId: memory.thread,\n resourceId: memory.resource ?? memory.thread,\n roomName,\n });\n } catch (error) {\n logger.warn('@mastra/livekit: failed to create the voice call thread', error);\n }\n }\n\n // One `voice call` trace per session: per-turn agent runs nest under it (via\n // tracingContext below) and LiveKit's pipeline metrics attach as child spans. No-ops\n // when the Mastra instance has no observability configured.\n const voiceObs =\n options.observability === false\n ? undefined\n : startVoiceCallObservability({\n mastra: options.mastra,\n agentId: agentLabel,\n roomName,\n metadata,\n requestContext,\n });\n // Close the call span when the job ends, however it ends (registered up front so a\n // failed start still finalizes); finalize() is idempotent.\n if (voiceObs) {\n ctx.addShutdownCallback(async () => {\n voiceObs.finalize();\n });\n }\n\n // End-of-call hook: runs after the caller hangs up, awaited within LiveKit's shutdown grace\n // window so the work finishes before the process exits. Registered up front (like the\n // observability finalizer) so it still fires if session start fails. Errors are logged.\n if (options.onCallEnd) {\n const onCallEnd = options.onCallEnd;\n ctx.addShutdownCallback(async () => {\n try {\n await onCallEnd({ memory, memoryInstance, metadata, requestContext, roomName, ctx });\n } catch (error) {\n logger.warn('@mastra/livekit: onCallEnd hook threw', error);\n }\n });\n }\n\n const agent = createMastraVoiceAgent({\n ...(replyGenerator ? { generate: replyGenerator } : { agent: mastraAgent! }),\n instructions: mastraAgent ? await resolveInstructions(mastraAgent, requestContext) : undefined,\n memory,\n requestContext,\n toolFeedback: options.toolFeedback,\n onTurnComplete: options.onTurnComplete,\n streamOptions: voiceObs ? { tracingContext: voiceObs.tracingContext } : undefined,\n });\n\n const session = new voice.AgentSession({\n stt: options.stt,\n tts: options.tts,\n vad,\n turnHandling: buildTurnHandling(options, turnDetection),\n ...options.sessionOptions,\n });\n\n // Subscribe before start so the first turn's metrics are captured.\n voiceObs?.attach(session);\n\n try {\n await session.start({\n agent,\n room: ctx.room,\n inputOptions: options.inputOptions,\n outputOptions: options.outputOptions,\n });\n\n if (options.greeting) {\n session.say(options.greeting);\n if (options.persistGreeting !== false && memory && memoryInstance) {\n try {\n await persistSpokenGreeting({\n memory: memoryInstance,\n threadId: memory.thread,\n resourceId: memory.resource ?? memory.thread,\n greeting: options.greeting,\n });\n } catch (error) {\n logger.warn('@mastra/livekit: failed to persist the greeting', error);\n }\n }\n }\n await options.onSessionStart?.({ session, ctx, agent, metadata });\n } catch (error) {\n voiceObs?.finalize({ error });\n throw error;\n }\n },\n });\n}\n","import { fileURLToPath } from 'node:url';\nimport { cli, ServerOptions } from '@livekit/agents';\nimport { DEFAULT_LIVEKIT_AGENT_NAME } from './constants';\nimport { workerSetupComplete } from './worker-setup';\n\nexport interface RunLiveKitWorkerOptions {\n /** The worker entry module whose default export is the agent definition. Pass `import.meta.url`. */\n entry: string | URL;\n /** LiveKit agent name for explicit dispatch. Defaults to `'mastra-voice'`. */\n agentName?: string;\n /** Extra LiveKit ServerOptions merged over what this helper builds. */\n serverOptions?: Partial<ConstructorParameters<typeof ServerOptions>[0]>;\n}\n\nexport function resolveWorkerEntryPath(entry: string | URL): string {\n if (entry instanceof URL) return fileURLToPath(entry);\n return entry.startsWith('file:') ? fileURLToPath(entry) : entry;\n}\n\n/**\n * Starts the LiveKit agent worker CLI (`dev` / `start` / `connect` subcommands) for a\n * worker entry file. Call it from the same file that default-exports\n * {@link createLiveKitWorker}, guarded so it only runs when executed directly:\n *\n * ```ts\n * import { fileURLToPath } from 'node:url';\n * import { createLiveKitWorker, runLiveKitWorker } from '@mastra/livekit/worker';\n * import { mastra } from './index';\n *\n * export default createLiveKitWorker({ mastra, agent: 'support' });\n *\n * if (process.argv[1] === fileURLToPath(import.meta.url)) {\n * runLiveKitWorker({ entry: import.meta.url, agentName: 'mastra-voice' });\n * }\n * ```\n *\n * Using this helper (instead of `cli.runApp` from `@livekit/agents`) guarantees the worker\n * runtime and the bridge share one copy of the LiveKit SDK.\n */\nexport function runLiveKitWorker(options: RunLiveKitWorkerOptions): void {\n // Wait for plugin imports queued by createLiveKitWorker so their inference runners\n // (e.g. the turn detector) are registered before the agent server starts.\n void workerSetupComplete().then(() => {\n cli.runApp(\n new ServerOptions({\n agent: resolveWorkerEntryPath(options.entry),\n agentName: options.agentName ?? DEFAULT_LIVEKIT_AGENT_NAME,\n ...options.serverOptions,\n }),\n );\n });\n}\n"]}
@@ -0,0 +1,8 @@
1
+ export { createLiveKitWorker } from './worker.js';
2
+ export type { CreateLiveKitWorkerOptions, ResolveMastraAgentArgs, SessionStartArgs, VoiceCallEndArgs, VoiceCallEndHook, } from './worker.js';
3
+ export { runLiveKitWorker } from './run.js';
4
+ export type { RunLiveKitWorkerOptions } from './run.js';
5
+ export { chatContextToMessages } from './messages.js';
6
+ export type { VoiceTurnMessage } from './messages.js';
7
+ export type { MastraVoiceAgentMemory, VoiceReplyGenerator, VoiceToolCall, VoiceTurnCompleteContext, VoiceTurnCompleteHook, VoiceTurnContext, VoiceTurnResult, } from './bridge.js';
8
+ //# sourceMappingURL=worker-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-entry.d.ts","sourceRoot":"","sources":["../src/worker-entry.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,YAAY,EACV,0BAA0B,EAC1B,sBAAsB,EACtB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AACzC,YAAY,EAAE,uBAAuB,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EACV,sBAAsB,EACtB,mBAAmB,EACnB,aAAa,EACb,wBAAwB,EACxB,qBAAqB,EACrB,gBAAgB,EAChB,eAAe,GAChB,MAAM,UAAU,CAAC"}