<@U084APK40NS> how does egress work for a room tha...
# ask-ai
m
@millions-hair-24956 how does egress work for a room that is done using outbound SIP?
g
It might be possible that egress for a room using outbound SIP involves setting up a SIP trunk to handle outbound calls and then using LiveKit's egress service to record or stream the session. According to the SIP Overview, you would need to configure an outbound SIP trunk using a provider like Twilio or Telnyx. Once the SIP trunk is set up, you can initiate outbound calls and manage them as SIP participants in a LiveKit room. For recording or streaming, the Egress Overview suggests using the egress service to capture the session. You can start a RoomCompositeEgress to record the entire room, which includes all participants, including those connected via SIP. This can be done using the
startRoomCompositeEgress
method from the Egress API. Would you like more detailed information on setting up the SIP trunk or using the egress service? Sources: - SIP Overview - Egress Overview - Egress API 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
m
@millions-hair-24956 is there a way to save the job context or chat context of a user/agent? I want to reinitiate the call from the place it left off in case the user needs to drop
g
It seems likely that saving the chat context or job context for later use can be achieved by listening to specific events and storing the context data. According to the VoicePipelineAgent documentation, you can listen to the
user_speech_committed
and
agent_speech_committed
events to capture and save the chat context. This allows you to store the conversation history in a database or file, which can be reloaded when the user reconnects. Additionally, the ChatContext class provides methods to manage chat messages, which can be used to save and restore the chat context. You can use the
append
method to add messages to the context and the
copy
method to create a structured clone of the context for storage. Would you like more detailed guidance on implementing this in your application? Sources: - ChatContext class 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
m
@millions-hair-24956 can you provide an example of how this would look for the voicepipelineagent?
g
Certainly! To save and restore the chat context using the
VoicePipelineAgent
, you can listen to the
user_speech_committed
and
agent_speech_committed
events to capture the conversation. Here's an example in Python:
Copy code
import asyncio
from datetime import datetime
from livekit import rtc
from livekit.agents import llm
from livekit.agents.voice_assistant import VoicePipelineAgent
from livekit.plugins import deepgram, openai, silero

# Initialize the VoicePipelineAgent
agent = VoicePipelineAgent(
    vad=silero.VAD.load(),
    stt=deepgram.STT(),
    llm=openai.LLM(),
    tts=openai.TTS(),
    chat_ctx=llm.ChatContext(),
)

# Queue to store log messages
log_queue = asyncio.Queue()

# Event handler for user speech committed
@agent.on("user_speech_committed")
def on_user_speech_committed(msg: llm.ChatMessage):
    log_queue.put_nowait(f"[{datetime.now()}] USER: {msg.content}\n")

# Event handler for agent speech committed
@agent.on("agent_speech_committed")
def on_agent_speech_committed(msg: llm.ChatMessage):
    log_queue.put_nowait(f"[{datetime.now()}] AGENT: {msg.content}\n")

# Function to write transcriptions to a file
async def write_transcription():
    async with open("transcriptions.log", "w") as f:
        while True:
            msg = await log_queue.get()
            if msg is None:
                break
            await f.write(msg)

# Start the transcription writing task
write_task = asyncio.create_task(write_transcription())

# Function to save the chat context
def save_chat_context(chat_ctx):
    # Convert chat context to a serializable format and save it
    with open("chat_context.json", "w") as f:
        json.dump([msg.to_dict() for msg in chat_ctx.messages], f)

# Function to load the chat context
def load_chat_context():
    with open("chat_context.json", "r") as f:
        messages = json.load(f)
    chat_ctx = llm.ChatContext()
    for msg in messages:
        chat_ctx.append(**msg)
    return chat_ctx

# Example of saving and loading chat context
save_chat_context(agent.chat_ctx)
agent.chat_ctx = load_chat_context()
This example demonstrates how to capture and store the chat context in a file, which can be reloaded later to resume the conversation. Would you like more details on any specific part of this implementation? Sources: - https://livekit-users.slack.com/archives/C07FY8WHGPM/p1730811222.681569 - https://docs.livekit.io/agents/voice-agent/voice-pipeline/#Interruption-handling 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
m
@millions-hair-24956 does the identity of a participant need to be unique if it's for a different context on the same agent on the same pod?
g
It seems likely that the identity of a participant needs to be unique within the same room context, even if it's for a different context on the same agent or pod. According to the LiveKit API Primitives, a participant's identity is unique per room. If participants with the same identity join a room, only the most recent one to join will remain, and the server will automatically disconnect other participants using that identity. If you are using the same agent on the same pod but in different contexts, you should ensure that each participant has a unique identity within each room to avoid conflicts. This is important for maintaining distinct sessions and ensuring that each participant is correctly managed by the server. Would you like more detailed information on managing participant identities? Sources: - LiveKit API Primitives 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.