diff --git a/examples/foundational/24-stt-mute-filter.py b/examples/foundational/24-stt-mute-filter.py index 2706bebaf..7b07edeb7 100644 --- a/examples/foundational/24-stt-mute-filter.py +++ b/examples/foundational/24-stt-mute-filter.py @@ -14,11 +14,17 @@ from loguru import logger from pipecat.adapters.schemas.function_schema import FunctionSchema from pipecat.adapters.schemas.tools_schema import ToolsSchema from pipecat.audio.vad.silero import SileroVADAnalyzer +from pipecat.frames.frames import 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.processors.filters.stt_mute_filter import STTMuteConfig, STTMuteFilter, STTMuteStrategy +from pipecat.processors.filters.stt_mute_filter import ( + STTMuteConfig, + STTMuteFilter, + STTMuteFrame, + STTMuteStrategy, +) from pipecat.services.deepgram.stt import DeepgramSTTService from pipecat.services.deepgram.tts import DeepgramTTSService from pipecat.services.llm_service import FunctionCallParams @@ -30,14 +36,6 @@ from pipecat.transports.services.daily import DailyParams load_dotenv(override=True) -async def fetch_weather_from_api(params: FunctionCallParams): - # Add a delay to test interruption during function calls - logger.info("Weather API call starting...") - await asyncio.sleep(5) # 5-second delay - logger.info("Weather API call completed") - await params.result_callback({"conditions": "nice", "temperature": "75"}) - - # We store functions so objects (e.g. SileroVADAnalyzer) don't get # instantiated. The function will be called when the desired transport gets # selected. @@ -69,39 +67,57 @@ async def run_example(transport: BaseTransport, _: argparse.Namespace, handle_si stt_mute_processor = STTMuteFilter( config=STTMuteConfig( strategies={ - STTMuteStrategy.MUTE_UNTIL_FIRST_BOT_COMPLETE, STTMuteStrategy.FUNCTION_CALL, + STTMuteStrategy.MUTE_UNTIL_FIRST_BOT_COMPLETE, } ), ) tts = DeepgramTTSService(api_key=os.getenv("DEEPGRAM_API_KEY"), voice="aura-helios-en") - llm = OpenAILLMService(api_key=os.getenv("OPENAI_API_KEY")) - llm.register_function("get_current_weather", fetch_weather_from_api) + async def transfer_to_human(params: FunctionCallParams): + # Add a delay to test interruption during function calls - weather_function = FunctionSchema( - name="get_current_weather", - description="Get the current weather", + caller_name = params.arguments.get("caller_name", "Unknown") + human_agent_name = params.arguments.get("human_agent_name", "Unknown") + logger.info(f"Transfer starting... {caller_name} wants to transfer to {human_agent_name}") + await task.queue_frame(STTMuteFrame(True)) + await asyncio.sleep(5) # 5-second delay + logger.info("Transfer complete, calling result callback") + messages.clear() + messages.append( + { + "role": "system", + "content": f"You are now an agent named {human_agent_name}. Greet {caller_name} and let them know you are taking over the conversation.", + } + ) + await params.llm.push_frame(LLMMessagesFrame(messages)) + await params.result_callback({"transfer_successful": True}) + + llm = OpenAILLMService(api_key=os.getenv("OPENAI_API_KEY")) + llm.register_function("transfer_to_human", transfer_to_human) + + transfer_function = FunctionSchema( + name="transfer_to_human", + description="Transfer the conversation to a human agent.", properties={ - "location": { + "caller_name": { "type": "string", - "description": "The city and state, e.g. San Francisco, CA", + "description": "The name of the person who is calling. This will be used to greet them.", }, - "format": { + "human_agent_name": { "type": "string", - "enum": ["celsius", "fahrenheit"], - "description": "The temperature unit to use. Infer this from the user's location.", + "description": "The name of the human agent to transfer the conversation to.", }, }, - required=["location", "format"], + required=["caller_name", "human_agent_name"], ) - tools = ToolsSchema(standard_tools=[weather_function]) + tools = ToolsSchema(standard_tools=[transfer_function]) messages = [ { "role": "system", - "content": "You are a helpful assistant who can check the weather. Always check the weather when a location is mentioned. Respond concisely and naturally. Your output will be converted to audio so use only simple words and punctuation.", + "content": "You are a cheerful and helpful assistant named James. It is your job to ask the user their name, and the name of the person they want to transfer the conversation to.", }, ]