DEV Community

Cover image for How to Transfer Calls in AI Voice Agents Using SIP Telephony
Chaitrali Kakde
Chaitrali Kakde

Posted on

How to Transfer Calls in AI Voice Agents Using SIP Telephony

When someone calls a business, they’re usually looking for a quick and clear resolution not a conversation with a bot that can’t help them move forward. Sometimes it’s a billing issue. Sometimes it’s a sales inquiry. And sometimes, they just want to speak to a real person.

A well-designed AI voice agent knows when to assist and when to step aside. That’s where Call Transfer in VideoSDK comes in. It allows your AI agent to transfer an ongoing SIP call to the right person, without disconnecting the caller or breaking the flow of the conversation.

What is Call Transfer

Call Transfer enables an AI agent to move an active SIP call to another phone number without ending the session. From the caller’s perspective, the transition is automatic, the call continues without dropping, there’s no need to redial, and the conversation flows naturally without awkward pauses or repeated explanations.

How It Works

  • The agent evaluates the user’s intent to determine when a call transfer is required and then triggers the function tool.
  • When the function tool is triggered, it tells the system to move the call to another phone number.
  • The ongoing SIP call is forwarded to the new number instantly, without disconnecting or redialing.

How To Trigger Call Transfer

To set up incoming call handling, outbound calling, and routing rules, check out the Quick Start Example

from videosdk.agents import Agent, function_tool, 

class CallTransferAgent(Agent):
    def __init__(self):
        super().__init__(
            instructions="You are the Call Transfer Agent Which Help and provide to transfer on going call to new number. use transfer_call tool to transfer the call to new number.",
        )

    async def on_enter(self) -> None:
        await self.session.say("Hello Buddy, How can I help you today?")

    async def on_exit(self) -> None:
        await self.session.say("Goodbye Buddy, Thank you for calling!")

    @function_tool
    async def transfer_call(self) -> None:
        """Transfer the call to Provided number"""
        token = os.getenv("VIDEOSDK_AUTH_TOKEN")
        transfer_to = os.getenv("CALL_TRANSFER_TO") 
        return await self.session.call_transfer(token,transfer_to)
Enter fullscreen mode Exit fullscreen mode

Full Working Example

import logging
import os

from videosdk.agents import (Agent, AgentSession, CascadingPipeline, function_tool, WorkerJob, ConversationFlow, JobContext, RoomOptions, Options)
from videosdk.plugins.deepgram import DeepgramSTT
from videosdk.plugins.google import GoogleLLM
from videosdk.plugins.cartesia import CartesiaTTS
from videosdk.plugins.silero import SileroVAD
from videosdk.plugins.turn_detector import TurnDetector, pre_download_model

# Setup logging
logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
    handlers=[logging.StreamHandler()]
)

# Pre-download turn detector model
pre_download_model()


class CallTransferAgent(Agent):
    def __init__(self):
        super().__init__(
            instructions=(
                "You are the Call Transfer Agent. "
                "Help transfer ongoing calls to a new number using the transfer_call tool."
            )
        )

    async def on_enter(self) -> None:
        await self.session.say("Hello Buddy, How can I help you today?")

    async def on_exit(self) -> None:
        await self.session.say("Goodbye Buddy, Thank you for calling!")

    @function_tool
    async def transfer_call(self) -> None:
        """Transfer the call to the provided number"""
        token = os.getenv("VIDEOSDK_AUTH_TOKEN")
        transfer_to = os.getenv("CALL_TRANSFER_TO")
        return await self.session.call_transfer(token, transfer_to)


async def entrypoint(ctx: JobContext):
    agent = CallTransferAgent()
    conversation_flow = ConversationFlow(agent)

    pipeline = CascadingPipeline(
        stt=DeepgramSTT(),
        llm=GoogleLLM(),
        tts=CartesiaTTS(),
        vad=SileroVAD(),
        turn_detector=TurnDetector()
    )

    session = AgentSession(
        agent=agent,
        pipeline=pipeline,
        conversation_flow=conversation_flow
    )

    await session.start(wait_for_participant=True, run_until_shutdown=True)


def make_context() -> JobContext:
    room_options = RoomOptions(name="Call Transfer Agent", playground=True)
    return JobContext(room_options=room_options)


if __name__ == "__main__":
    job = WorkerJob(
        entrypoint=entrypoint,
        jobctx=make_context,
        options=Options(
            agent_id="YOUR_AGENT_ID",
            register=True,
            host="localhost",
            port=8081
        )
    )
    job.start()
Enter fullscreen mode Exit fullscreen mode

Conclusion

Call Transfer transforms your AI voice agent from a simple responder into a capable call-handling system. By automatically routing ongoing SIP calls to the right person, it ensures users never experience dropped calls or awkward handoffs.

Resources and Next Steps

Top comments (0)