how might i give livekit agent control to end a ca...
# ask-ai
t
how might i give livekit agent control to end a call? @millions-hair-24956 Give example
g
To give a LiveKit agent control to end a call, you can use the
RoomService.remove_participant()
method to disconnect a participant from the room. This can be done programmatically using the LiveKit API. Here's a basic example in Python:
Copy code
from livekit import api, protocol
from livekit.protocol import room as proto_room

# Initialize LiveKit API client
lkapi = api.LiveKitAPI()

# Function to remove a participant
async def remove_participant(room_name, participant_identity):
    response = await lkapi.room.remove_participant(
        proto_room.RoomParticipantIdentity(room=room_name, identity=participant_identity)
    )
    return response
This code snippet demonstrates how to remove a participant from a room, effectively ending their call. You need to replace
room_name
and
participant_identity
with the actual room name and participant identity you wish to disconnect. Would you like more detail on this process? Sources: - LiveKit Slack Discussion 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
t
well id probably want to just end the entire call so we aren't wasting resources. @millions-hair-24956 i just need an example of how we can make the LLM make the decision to do that
g
To end an entire call and close the room, you can use the
RoomService.delete_room()
method. This will disconnect all participants and free up resources. You can integrate this with an LLM by defining a function that the LLM can call when it decides to end the call. Here's an example in Python:
Copy code
from livekit import api, protocol
from livekit.protocol import room as proto_room

# Initialize LiveKit API client
lkapi = api.LiveKitAPI()

# Function to delete a room
async def delete_room(room_name):
    response = await lkapi.room.delete_room(proto_room.DeleteRoomRequest(room=room_name))
    return response

# Example LLM function context
class FunctionContext:
    async def end_call(self, room_name):
        print(f"Ending call for room: {room_name}")
        await delete_room(room_name)
        return "The call has been ended and the room is closed."

# Usage
fnc_ctx = FunctionContext()
await fnc_ctx.end_call("example-room")
In this example, the
end_call
function is part of a
FunctionContext
class that the LLM can use to decide when to end the call. The function calls
delete_room
to close the room and disconnect all participants. Would you like more detail on integrating this with an LLM? Sources: - LiveKit Slack Discussion - LiveKit Room Management 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
t
@millions-hair-24956 how might i make the agent interrupt the caller? I know the caller can interrupt the agent but i want it the other way around as well.
g
To enable an agent to interrupt a caller, you can use the
allow_interruptions
parameter in the
agent.say()
method. By setting
allow_interruptions=True
, the agent can interrupt its current speech to start a new one. Here's an example in Python:
Copy code
import asyncio
from livekit import rtc
from livekit.agents import AutoSubscribe, JobContext, WorkerOptions, cli
from livekit.agents.pipeline import VoicePipelineAgent

# Custom VoicePipelineAgent with interruptible say method
class InterruptibleVoicePipelineAgent(VoicePipelineAgent):
    async def custom_say(self, text, allow_interruptions=False):
        if allow_interruptions and self._playing_speech:
            self._playing_speech.interrupt()
        await super().say(text)

async def entrypoint(ctx: JobContext):
    await ctx.connect(auto_subscribe=AutoSubscribe.AUDIO_ONLY)
    agent = InterruptibleVoicePipelineAgent()
    agent.start(ctx.room)

    # Example usage
    await agent.custom_say("Hello, how can I help you?", allow_interruptions=True)
    await agent.custom_say("I'm interrupting!", allow_interruptions=True)

if __name__ == "__main__":
    cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))
In this example, the
custom_say
method is used to interrupt the current speech if
allow_interruptions
is set to
True
. This allows the agent to start a new speech immediately, interrupting the caller if necessary. Would you like more detail on this implementation? Sources: - LiveKit Slack Discussion - LiveKit Python Documentation 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
t
@millions-hair-24956 lastly, how might i create dynamic start call messages?
g
To create dynamic start call messages, you can use the
entrypoint
function to customize the initial message based on participant attributes or other contextual information. Here's an example in Python:
Copy code
import asyncio
from livekit import rtc
from livekit.agents import AutoSubscribe, JobContext, WorkerOptions, cli
from livekit.agents.pipeline import VoicePipelineAgent

async def entrypoint(ctx: JobContext):
    await ctx.connect(auto_subscribe=AutoSubscribe.AUDIO_ONLY)
    participant = await ctx.wait_for_participant()

    # Customize the start message based on participant identity
    start_message = f"Hello {participant.identity}, welcome to the call!"
    
    agent = VoicePipelineAgent()
    agent.start(ctx.room)

    # Send the dynamic start message
    await agent.say(start_message)

if __name__ == "__main__":
    cli.run_app(WorkerOptions(entrypoint_fnc=entrypoint))
In this example, the
start_message
is dynamically created using the participant's identity. You can further customize this message based on other attributes or external data sources. Would you like more detail on this approach? Sources: - LiveKit Slack Discussion 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
t
@millions-hair-24956 What's the correct way to add a function to the LLM in LiveKit's Python SDK? What's the recommended approach for ending a call in LiveKit? Is there a simple way to make the AI responses more concise?
g
To add a function to the LLM in LiveKit's Python SDK, you can define a function within a
FunctionContext
and use the
@llm.ai_callable()
decorator. This makes the function available to the LLM for execution. Here's a basic example:
Copy code
from livekit.agents import llm
from typing import Annotated

class AssistantFnc(llm.FunctionContext):
    @llm.ai_callable()
    async def get_weather(self, location: Annotated[str, llm.TypeInfo(description="The location to get the weather for")]):
        # Function logic here
        return f"The weather in {location} is sunny."
For ending a call in LiveKit, the recommended approach is to use the
RoomService.delete_room()
method, which disconnects all participants and closes the room. This can be integrated into a function that the LLM can call when needed. To make AI responses more concise, you can adjust the
temperature
and
max_output_tokens
parameters when initializing the LLM. Lowering the
temperature
makes responses more deterministic, while reducing
max_output_tokens
limits the length of the response. Would you like more detail on any of these topics? Sources: - Function Calling with Voice Agents - Adjusting Model Parameters 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
t
1. @millions-hair-24956 What's the correct syntax for passing functions to the Google LLM? 2. Is there a simpler approach to end the call without using function calling?
g
It seems likely that for passing functions to a Google LLM, you would typically define the functions within a
FunctionContext
and use decorators like
@llm.ai_callable()
to make them available to the LLM. However, specific syntax for Google LLMs isn't detailed in the provided data sources, so this approach is based on general practices with LLMs in LiveKit. For ending a call without using function calling, you can directly use the
RoomService.delete_room()
method to close the room and disconnect all participants. This method does not require function calling and can be invoked directly when you want to end the call. Would you like more detail on these approaches? Sources: - Function Calling with Voice Agents 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
t
why am i getting this error when trying to record ? "{"message": "Error setting up GCP recording: Protocol message GCPUpload has no \"prefix\" field.", "level": "ERROR", "name": "sales-bot-agent", "pid": 18350, "job_id": "AJ_EMDD6HCo8AKJ", "timestamp": "2025-02-26T182250.390840+00:00"}" @millions-hair-24956
g
It seems likely that the error you're encountering is due to a missing or incorrectly specified field in the
GCPUpload
configuration for recording. The error message indicates that the
GCPUpload
protocol message does not have a "prefix" field, which suggests that the configuration might be missing required fields or using incorrect field names. To resolve this, you should verify the configuration for
GCPUpload
in your recording setup. Ensure that all required fields are correctly specified according to the LiveKit Egress documentation. Double-check the field names and ensure that they match the expected parameters. Would you like more detail on configuring GCP recording in LiveKit? Sources: - https://livekit-users.slack.com/archives/C07FVFARRK7/p1728711710.058359 - https://docs.livekit.io/python/livekit/protocol/egress.html Note: I wasn’t able to find highly relevant data sources, but above are a few potentially relevant links. 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
t
@millions-hair-24956 just for reference could i use auto egress instead and livekit handled all the server stuff for me i just specify my gcp stuff?
g
Yes, you can use Auto Egress to simplify the recording process in LiveKit. Auto Egress allows you to automatically start recording when a room is created, and you can specify your GCP configuration for storage. This way, LiveKit handles the server-side setup for you. To use Auto Egress, you need to specify the egress configuration when creating a room. Here's an example of how you might configure it to record to GCP:
Copy code
{
  "name": "my-room",
  "egress": {
    "room": {
      "customBaseUrl": "https://your-template-url",
      "segments": {
        "filename_prefix": "path-in-bucket/myfile",
        "segment_duration": 3,
        "gcp": {
          "credentials": "<json-encoded-credentials>",
          "bucket": "mybucket"
        }
      }
    }
  }
}
This configuration will automatically record the room and store the recordings in the specified GCP bucket. Would you like more detail on setting up Auto Egress? Sources: - Auto Egress Documentation 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.
t
does auto egress Create the room or just record the room?
does auto egress Create the room or just record a created room? @millions-hair-24956
g
Auto Egress in LiveKit is designed to automatically start recording a room once it is created, but it does not create the room itself. You need to explicitly create the room using the
CreateRoom
API, and during this creation process, you can specify the egress configuration to enable Auto Egress for recording. Would you like more detail on how to set up Auto Egress during room creation? Sources: - Auto Egress Documentation - Room Management API 👍 0 button 👎 0 button 💡 Hint: Mention @runllm in the thread for followups.