1717- Built-in semantic VAD (voice activity detection)
1818- Streaming user transcription
1919- Text and audio input
20+ - Function calling (tool use)
2021
2122Requirements:
2223 - INWORLD_API_KEY environment variable set
3233from dotenv import load_dotenv
3334from loguru import logger
3435
36+ from pipecat .adapters .schemas .function_schema import FunctionSchema
37+ from pipecat .adapters .schemas .tools_schema import ToolsSchema
3538from pipecat .frames .frames import LLMRunFrame
3639from pipecat .observers .loggers .transcription_log_observer import (
3740 TranscriptionLogObserver ,
4851from pipecat .runner .types import RunnerArguments
4952from pipecat .runner .utils import create_transport
5053from pipecat .services .inworld .realtime .llm import InworldRealtimeLLMService
54+ from pipecat .services .llm_service import FunctionCallParams
5155from pipecat .transports .base_transport import BaseTransport , TransportParams
5256from pipecat .transports .daily .transport import DailyParams
5357from pipecat .transports .websocket .fastapi import FastAPIWebsocketParams
5458
5559load_dotenv (override = True )
5660
5761
62+ # --- Function Calling (Tool Use) ---
63+
64+
65+ async def fetch_restaurant_recommendation (params : FunctionCallParams ):
66+ await params .result_callback ({"name" : "Pizza King" })
67+
68+
69+ restaurant_function = FunctionSchema (
70+ name = "get_restaurant_recommendation" ,
71+ description = "Get a restaurant recommendation" ,
72+ properties = {
73+ "location" : {
74+ "type" : "string" ,
75+ "description" : "The city and state, e.g. San Francisco, CA" ,
76+ },
77+ },
78+ required = ["location" ],
79+ )
80+
81+ tools = ToolsSchema (standard_tools = [restaurant_function ])
82+
83+
5884# --- Transport Configuration ---
5985
6086# No local VAD needed — Inworld's server-side semantic VAD handles turn detection.
@@ -80,9 +106,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
80106 # Create the Inworld Realtime LLM service.
81107 # Common params (llm_model, voice, tts_model, stt_model) are top-level.
82108 # For full control, use settings=InworldRealtimeLLMService.Settings(session_properties=...)
109+ #
110+ # llm_model can be any supported model or an Inworld Router.
111+ # See: https://docs.inworld.ai/router/introduction
83112 llm = InworldRealtimeLLMService (
84113 api_key = os .getenv ("INWORLD_API_KEY" ),
85- llm_model = "openai/gpt-4.1-nano " ,
114+ llm_model = "openai/gpt-4.1-mini " ,
86115 voice = "Sarah" ,
87116 settings = InworldRealtimeLLMService .Settings (
88117 system_instruction = """You are a helpful and friendly AI assistant powered by Inworld.
@@ -94,9 +123,12 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
94123 ),
95124 )
96125
97- # Create context with initial message
126+ llm .register_function ("get_restaurant_recommendation" , fetch_restaurant_recommendation )
127+
128+ # Create context with initial message and tools
98129 context = LLMContext (
99130 [{"role" : "user" , "content" : "Say hello and introduce yourself!" }],
131+ tools ,
100132 )
101133
102134 user_aggregator , assistant_aggregator = LLMContextAggregatorPair (context )
0 commit comments