File size: 3,785 Bytes
1366db9
 
 
 
 
 
 
 
 
 
 
50cee30
1366db9
50cee30
1366db9
 
 
 
 
 
 
 
 
 
 
50cee30
1366db9
 
 
 
 
 
50cee30
 
1366db9
 
 
 
 
 
 
50cee30
1366db9
50cee30
 
1366db9
50cee30
1366db9
 
50cee30
1366db9
50cee30
1366db9
 
 
50cee30
 
 
 
 
 
 
 
1366db9
 
 
 
 
50cee30
 
1366db9
 
 
 
 
 
50cee30
 
 
1366db9
50cee30
1366db9
 
 
 
50cee30
1366db9
 
 
 
 
 
 
50cee30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#
# Copyright (c) 2024–2025, Daily
#
# SPDX-License-Identifier: BSD 2-Clause License
#
import argparse
import asyncio
import os
import sys
from loguru import logger

from call_connection_manager import CallConfigManager
from pipecat.audio.vad.silero import SileroVADAnalyzer
from pipecat.frames.frames import EndTaskFrame, LLMMessagesFrame
from pipecat.pipeline.pipeline import Pipeline
from pipecat.pipeline.runner import PipelineRunner
from pipecat.pipeline.task import PipelineParams, PipelineTask
from pipecat.processors.aggregators.openai_llm_context import OpenAILLMContext
from pipecat.services.cartesia.tts import CartesiaTTSService
from pipecat.services.openai.llm import OpenAILLMService
from pipecat.transports.services.daily import DailyParams, DailyTransport

logger.remove(0)
logger.add(sys.stderr, level="DEBUG")

async def main(room_url: str, token: str, body: dict):
    call_config_manager = CallConfigManager.from_json_string(body) if body else CallConfigManager()
    dialout_settings = call_config_manager.get_dialout_settings()
    test_mode = call_config_manager.is_test_mode()

    # ------------ TRANSPORT SETUP ------------
    transport_params = DailyParams(
        api_url=os.environ.get("DAILY_API_URL", "https://api.daily.co/v1"),
        api_key=os.environ.get("HF_DAILY_API_KEY", ""),
        audio_in_enabled=True,
        audio_out_enabled=True,
        video_out_enabled=False,
        vad_analyzer=SileroVADAnalyzer(),
        transcription_enabled=True,
    )

    transport = DailyTransport(room_url, token, "Simple Dialout Bot", transport_params)
    tts = CartesiaTTSService(
        api_key=os.environ.get("HF_CARTESIA_API_KEY", ""),
        voice_id="b7d50908-b17c-442d-ad8d-810c63997ed9",
    )
    llm = OpenAILLMService(api_key=os.environ.get("HF_OPENAI_API_KEY"))

    # ------------ LLM AND CONTEXT SETUP ------------
    system_instruction = """You are a friendly, helpful robot. Greet the user and ask how you can assist them."""
    messages = [call_config_manager.create_system_message(system_instruction)]
    context = OpenAILLMContext(messages)
    context_aggregator = llm.create_context_aggregator(context)

    # ------------ PIPELINE SETUP ------------
    pipeline = Pipeline([
        transport.input(),
        context_aggregator.user(),
        llm,
        tts,
        transport.output(),
        context_aggregator.assistant(),
    ])

    task = PipelineTask(pipeline, params=PipelineParams(allow_interruptions=True))

    @transport.event_handler("on_first_participant_joined")
    async def on_first_participant_joined(transport, participant):
        await transport.capture_participant_transcription(participant["id"])
        await task.queue_frames([context_aggregator.user().get_context_frame()])

    @transport.event_handler("on_participant_left")
    async def on_participant_left(transport, participant, reason):
        logger.debug(f"Participant left: {participant}, reason: {reason}")
        await task.cancel()

    # ------------ DIALOUT ------------
    if not test_mode:
        await call_config_manager.start_dialout(transport, dialout_settings)

    # ------------ RUN PIPELINE ------------
    runner = PipelineRunner()
    await runner.run(task)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="Pipecat Simple Dialout Bot")
    parser.add_argument("-u", "--url", type=str, help="Room URL")
    parser.add_argument("-t", "--token", type=str, help="Room Token")
    parser.add_argument("-b", "--body", type=str, help="JSON configuration string")
    args = parser.parse_args()
    logger.info(f"Room URL: {args.url}")
    logger.info(f"Token: {args.token}")
    logger.info(f"Body provided: {bool(args.body)}")
    asyncio.run(main(args.url, args.token, args.body))