This message was deleted.
# ask-ai
s
This message was deleted.
t
Thanks for reaching out, Yashish. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
To build a bot that initiates an outbound call, begins the conversation, waits patiently and silently during hold music, then resumes when a human joins, you will need to address several architectural components with LiveKit: • Outbound Call Setup: Use a SIP trunk to place outbound calls from LiveKit. The outbound number and trunk must be configured with your SIP provider (e.g., Twilio, Telnyx). • Call Flow Management: When your bot starts the call, play the initial message (e.g., “I would like to speak with a human agent.”). Use participant event detection (such as monitoring the
sip.callStatus
attribute) to determine when the call is connected and when a human joins. • Hold Music Handling: After playing the initial message, implement voice activity detection (VAD) and turn detection to distinguish between silence, hold music, and real human speech. Tools like Silero’s VAD, together with turn detection models, can help your bot remain silent during hold music but resume when a human answers. • Resume on Human Response: Once your system detects human speech (not music), resume the bot's active conversation and proceed to gather the required details. • Voicemail Handling: Optionally, detect if the call reaches voicemail and execute a different flow (such as leaving a message). The practical implementation involves setting up the outbound call via your SIP provider, incorporating VAD and turn detection, and handling the call flow as described above. You’ll need: a SIP provider and trunk, LiveKit Cloud or self-hosted deployment, and access to the LiveKit Agent SDK with proper API keys. If you need code samples or stepwise implementation for any of these aspects, let me know which part you wish to focus on first. Sources: Outbound call examples, call state monitoring, and VAD/turn detection details from the LiveKit knowledge base. Sources: Agents telephony integration | LiveKit Docs | Making outbound calls | LiveKit Docs | agent.py | Making calls using SIP | LiveKit Docs
Hey there! Let me walk you through an example of creating a LiveKit Agent that handles an outbound SIP call. I've put together a Python snippet that shows how this might work, and I'll break it down in a friendly, approachable way. Think of this as a step-by-step guide to building a conversational phone bot.
Copy code
from livekit import api
import json, asyncio
from my_agents import Agent, AgentSession, EnglishModel  # replace with your actual import paths
from silero import VAD              # replace with your VAD import/path if needed

class OutboundBot(Agent):
    def __init__(self, **kwargs):
        super().__init__(
            instructions="""
            You are making an outbound call. Greet and state: 'I would like to speak with a human agent.' Then remain silent until human speech is detected. When a human replies, resume the conversation to collect required information.
            """
        )
        self.initial_message_played = False
        self.human_detected = False

    async def handle_call_flow(self, session):
        if not self.initial_message_played:
            await session.generate_reply(
                text="I would like to speak with a human agent."
            )
            self.initial_message_played = True

        # Wait for human speech (using turn and VAD logic)
        if not self.human_detected:
            vad_result = await session.vad.detect()  # pseudocode: replace with your VAD/human speech detection
            if vad_result == 'human':
                self.human_detected = True
                await session.generate_reply(
                    text="Thank you. I need the following information ..."  # adapt for your flow
                )

async def entrypoint(ctx):
    await ctx.connect()
    dial_info = json.loads(ctx.job.metadata)
    phone_number = dial_info["phone_number"]
    await ctx.api.sip.create_sip_participant(api.CreateSIPParticipantRequest(
        room_name=ctx.room.name,
        sip_trunk_id='YOUR_TRUNK_ID',
        sip_call_to=phone_number,
        participant_identity=phone_number,
        wait_until_answered=True
    ))
    agent = OutboundBot()  # you may want to supply call-specific instructions here
    session = AgentSession(
        turn_detection=EnglishModel(),
        vad=VAD.load(),
        # Add your ASR/TTS configs
    )
    await session.start(agent=agent, room=ctx.room)
I know this looks like a lot, but don't worry! This is just a starting point. You'll want to customize this code to fit your specific project needs. Think of it like a blueprint that you can modify and make your own. If you're feeling stuck or want to dive deeper into any part of this – like setting up voice activity detection or handling different call states – just give me a shout, and I'll be happy to help you work through it! Sources: LiveKit outbound call and agent code patterns, SIP event handling, and VAD/turn detection best practices.
m
can you provide some example links for similar type of implementation
t
Hey there! I've got some awesome resources that might be just what you need for your outbound SIP calling and agent workflows with LiveKit. Let me walk you through some helpful examples that could make your project a breeze! • Python Outbound Caller Example: https://github.com/livekit-examples/outbound-caller-python This is a super cool example that shows how an AI agent can make outbound calls, handle voicemail, and even potentially transfer to a human operator. Pretty neat, right? • Additional Python Telephony Examples: https://github.com/livekit/python-agents-examples/tree/main/telephony Check out these extra examples covering phone calls, SIP warm handoffs, and SIP lifecycle management. Lots of good stuff to explore! • Node.js SIP Make a Call Example: https://github.com/livekit/node-agents-examples/tree/main/packages/sip--make-a-callDocumentation Recipes and Telephony Scenarios: The LiveKit docs have some awesome recipes at https://docs.livekit.io/agents/recipes - think IVR agent, company directory, survey caller, and some really cool handoff patterns! Just a heads up - while these examples are great for outbound calls and conversation flows, you might need to add some custom logic (like VAD and turn detection) if you want to handle things like hold music or specific transfer scenarios. Sources: Python outbound caller, node telephony agent code samples, and documentation example listings. Sources: README.md | packages/sip--make-a-call/README.md | Making calls using SIP | LiveKit Docs | Agents telephony integration | LiveKit Docs | LiveKit | Recipes and examples for voice AI and more. | LiveKit Docs | README.md
m
here here how it will not respond to tune?
t
I don't have the answer you're looking for. You could also try asking your question: • in one of the other Slack channels or • to https://deepwiki.com/livekit/livekit_composite which is trained on all LiveKit source code If you find the answer, please post it here to help others!
m
Is this correct way for waiting agent? class WaitingAgent(Agent): """Agent 2: Listens silently while on hold for a human to answer.""" def __init__(self, chat_ctx: ChatContext): super().__init__( instructions = """ You are currently on hold, waiting for a human agent to respond. Remain completely silent. STRICTLY follow these rules: - DO NOT respond to any automated messages under any circumstance. - Ignore all automated voice prompts, recordings, announcements, and messages (e.g., "All our representatives are busy", "Please stay on the line", "Your call is important to us", etc.). - Ignore all hold music, background noise, and silence. You must stay completely silent and passive until a real human directly engages you with a natural, unscripted greeting (e.g., "Hello", "Hi, how can I help you?"). As soon as you detect a real human greeting you directly, immediately call the
human_has_answered
tool. Do not respond or take any action unless you are absolutely sure a human has spoken to you. """, chat_ctx=chat_ctx ) async def on_enter(self) -> None: logger.info("WaitingAgent is active. Listening silently for a human...") @function_tool() async def human_has_answered(self) -> Agent: logger.info("Human detected. Handoff -> PharmacistInteractionAgent") return PharmacistInteractionAgent(chat_ctx=self.session._chat_ctx)