able-jackal-84140
07/10/2025, 1:28 PMtall-airline-16756
07/10/2025, 1:29 PMtall-airline-16756
07/10/2025, 1:29 PMbefore_tts_cb
callback when initializing your VoicePipelineAgent
. This callback lets you inspect or modify the text before it is sent to TTS.
def replace_words(agent, text):
# Modify text as needed
return text.replace('example', 'demo')
agent = VoicePipelineAgent(
...,
before_tts_cb=replace_words,
)
• Agents v1.0+: Override the tts_node
method in a custom Agent subclass. You can preprocess streaming or non-streaming text here. For example:
class CustomAgent(Agent):
async def tts_node(self, text, model_settings):
async def process_text():
async for chunk in text:
yield chunk.replace('foo', 'bar')
return Agent.default.tts_node(self, process_text(), model_settings)
Both approaches allow for tasks such as text normalization, filtering, or pronunciation adjustments before TTS synthesis. For more advanced post-processing (like volume adjustments), the tts_node
method allows modifications to the resulting audio buffers as well.
Refer to these mechanisms to ensure your logic runs at the correct place in the TTS pipeline.
Sources: VoicePipelineAgent | LiveKit Docs | chain-of-thought-tts/README.mdoc | Agents 0.x migration guide | LiveKit Docs | pipeline-tts/tts_node.py | Voice pipeline nodes | LiveKit Docsable-jackal-84140
07/10/2025, 3:00 PMtall-airline-16756
07/10/2025, 3:01 PMtts_node
method (for Agents 1.0+) or using the llm_node
override. If something's not quite clicking, just let me know your Agent version and what you're trying to do, and we'll figure it out together!
Sources: Voice pipeline nodes | LiveKit Docs | Agents 0.x migration guide | LiveKit Docsable-jackal-84140
07/10/2025, 3:09 PMtall-airline-16756
07/10/2025, 3:09 PMfrom livekit.agents.voice import Agent, ModelSettings
from typing import AsyncIterable
class CustomAgent(Agent):
async def tts_node(self, text: AsyncIterable[str], model_settings: ModelSettings):
async def process_text():
async for chunk in text:
# Replace 'foo' with 'bar' in all TTS output
modified_chunk = chunk.replace('foo', 'bar')
yield modified_chunk
# Use the default tts_node with your modified text stream
return await Agent.default.tts_node(self, process_text(), model_settings)
Pro tip: You can swap out that chunk.replace('foo', 'bar')
line with whatever text processing magic you need. This method gives you the flexibility to modify or filter your text before it gets turned into speech. Pretty cool, right? 😎