polite-oil-10264
08/07/2025, 12:33 PMtall-airline-16756
08/07/2025, 12:33 PMtall-airline-16756
08/07/2025, 12:33 PMtts_node
method. Here's an example implementation:
class CustomAgent(Agent):
async def tts_node(self, text: AsyncIterable[str], model_settings: ModelSettings) -> AsyncIterable[str]:
# Process the text before TTS
async def process_text(text_stream: AsyncIterable[str]) -> AsyncIterable[str]:
async for chunk in text_stream:
# Replace any unwanted text or tokens
cleaned_chunk = chunk.replace("original_text", "modified_text")
yield cleaned_chunk
# Process the text and then use the default TTS node
processed_text = process_text(text)
return await super().tts_node(processed_text, model_settings)
Explanation:
• Overriding `tts_node`: This method allows you to process the text output from the LLM before it is converted to speech.
• Text Processing: In the example, specific text is replaced, but you can implement more complex logic like removing tokens or altering the tone.
• Integration: After processing, the modified text is passed through the default TTS pipeline to generate the final audio output.
This approach gives you fine-grained control over the LLM's output before it is vocalized, enabling a more tailored user experience.polite-oil-10264
08/07/2025, 12:34 PMtall-airline-16756
08/07/2025, 12:35 PMsendpack
while working with just STT and LLM, you can make good use of LiveKit's TextStreamWriter
feature. Here's a simple way to do it:
async function sendLlmOutputToParticipants(llmOutput, participantId) {
const stream = await room.localParticipant.streamText({
destinationIdentities: [participantId], // Optional, leave empty to send to all participants
topic: "llm-output", // Optional topic for filtering
});
try {
await stream.write(llmOutput); // Send the LLM output
} finally {
await stream.close(); // Make sure to close the stream
}
}
Here are a few key things to keep in mind:
• Create a Text Stream Writer: Use streamText()
to get a TextStreamWriter
instance that lets you send text data.
• Write LLM Output: Call the write()
method to send the LLM's text output to your participants.
• Close the Stream: Don’t forget to close the stream with close()
once you’re done sending.
• Optional Parameters: You can specify who gets the message using destinationIdentities
(or leave it empty to reach everyone) and use topic
to label the data stream.
This approach is a smooth way to share text-based LLM output without needing TTS. If you have any questions or want me to walk you through it, just let me know—I’m here to help!polite-oil-10264
08/07/2025, 12:38 PMtall-airline-16756
08/07/2025, 12:38 PMconsole.log
right before the text goes to the TTS service. Here’s a quick example:
const text = "This is the text to be synthesized";
console.log(`Text to synthesize: ${text}`); // Logs the text to the console
If you’re working with a streaming API, you can log the text as it’s being passed along like this:
const stream = tts.stream();
// Push text to stream and log it
stream.pushText(text);
console.log(`Stream text: ${text}`);
// End the stream
stream.flush();
stream.endInput();
For something a bit more advanced, you might want to wrap the TTS functionality in a custom class that logs the text for you. Here’s how you could do that:
class LoggingTTS {
constructor(tts) {
this.tts = tts;
}
async synthesize(text) {
console.log(`Synthesizing text: ${text}`);
return this.tts.synthesize(text);
}
stream() {
const stream = this.tts.stream();
const originalPushText = stream.pushText.bind(stream);
stream.pushText = (text) => {
console.log(`Streaming text: ${text}`);
return originalPushText(text);
};
return stream;
}
}
// Usage
const loggingTTS = new LoggingTTS(tts);
const text = "This is the text to be synthesized";
const audioStream = loggingTTS.synthesize(text);
These are some handy ways to keep an eye on the text before it gets processed by your TTS engine. If you have any questions or want to dive deeper, just let me know—I’m here to help!polite-oil-10264
08/07/2025, 12:39 PMtall-airline-16756
08/07/2025, 12:40 PMllm_node
method in your agent class. Here’s a simple example to get you started:
import logging
from livekit.agents import Agent
from livekit.plugins import deepgram, openai
logger = logging.getLogger("llm-logger")
logger.setLevel(<http://logging.INFO|logging.INFO>)
class LoggingAgent(Agent):
def __init__(self):
super().__init__(
instructions="You are a helpful assistant.",
stt=deepgram.STT(),
llm=openai.LLM(model="gpt-4o"),
)
async def llm_node(self, chat_ctx, tools, model_settings=None):
async def process_stream():
async with self.llm.chat(chat_ctx=chat_ctx, tools=tools, tool_choice=None) as stream:
async for chunk in stream:
if chunk is None:
continue
content = getattr(chunk.delta, 'content', None) if hasattr(chunk, 'delta') else str(chunk)
if content is None:
yield chunk
continue
# Log the LLM output
<http://logger.info|logger.info>(f"LLM Output: {content}")
print(f"LLM Output: {content}")
yield chunk
return process_stream()
Here’s a quick rundown:
• Custom Agent Class: We create a LoggingAgent
that builds on the base Agent
and sets up STT and LLM.
• Logging LLM Output: By overriding llm_node
, you catch the LLM’s output stream and log each piece right to your console.
• Real-Time Feedback: You’ll see the LLM output printed out as it’s generated, so you can keep track instantly.
This way, you get all your LLM outputs logged neatly while working with only STT and LLM. If you want to chat more or need a hand with anything else, just let me know—I’m here to help!