1+ import asyncio
2+ import logging
3+ import os
4+ from uuid import uuid4
5+ from dotenv import load_dotenv
6+ from examples .utils import create_user , open_browser
7+ from getstream import Stream
8+ from getstream .plugins .sts .openai_realtime import OpenAIRealtime
9+
10+
11+ logging .basicConfig (
12+ level = logging .INFO ,
13+ format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s" ,
14+ force = True , # Override any previous basicConfig calls
15+ )
16+
17+ # Enable verbose logging for the OpenAI Realtime plugin
18+ logging .getLogger ("getstream.plugins.sts.openai_realtime.sts" ).setLevel (logging .INFO )
19+
20+
21+ async def main ():
22+ """Run a demo call with an OpenAI Speech-to-Speech agent attached."""
23+
24+ load_dotenv (os .path .join (os .path .dirname (__file__ ), ".." , ".env" ))
25+
26+ # Initialize Stream client from env vars (STREAM_API_KEY / SECRET / BASE_URL)
27+ client = Stream .from_env ()
28+
29+ user_id = f"user-{ uuid4 ()} "
30+ create_user (client , user_id , "My User" )
31+ logging .info ("👤 Created user: %s" , user_id )
32+
33+ user_token = client .create_token (user_id , expiration = 3600 )
34+ logging .info ("🔑 Created token for user: %s" , user_id )
35+
36+ bot_user_id = f"openai-realtime-speech-to-speech-bot-{ uuid4 ()} "
37+ create_user (client , bot_user_id , "OpenAI Realtime Speech to Speech Bot" )
38+ logging .info ("🤖 Created bot user: %s" , bot_user_id )
39+
40+ call_id = str (uuid4 ())
41+ logging .info ("📞 Call ID: %s" , call_id )
42+
43+ call = client .video .call ("default" , call_id )
44+ call .get_or_create (data = {"created_by_id" : bot_user_id })
45+ logging .info ("📞 Call created: %s" , call_id )
46+
47+ # Open demo browser so you can join from the UI
48+ open_browser (client .api_key , user_token , call_id )
49+
50+ sts_bot = OpenAIRealtime (
51+ api_key = os .getenv ("OPENAI_API_KEY" ),
52+ model = "gpt-4o-realtime-preview" ,
53+ instructions = "You are a friendly assistant; reply verbally in a short sentence." ,
54+ voice = "alloy" ,
55+ )
56+
57+ @sts_bot .on ("connected" )
58+ async def _on_connected ():
59+ print ("✅ CONNECTED EVENT RECEIVED" )
60+ logging .info ("✅ Bot connected successfully" )
61+
62+ @sts_bot .on ("disconnected" )
63+ async def _on_disconnected ():
64+ print ("❌ DISCONNECTED EVENT RECEIVED" )
65+ logging .info ("❌ Bot disconnected" )
66+
67+ @sts_bot .on ("error" )
68+ async def _on_error (error ):
69+ print (f"💥 ERROR EVENT RECEIVED: { error } " )
70+ logging .error ("💥 Bot error: %s" , error )
71+
72+ @sts_bot .on ("session.created" )
73+ @sts_bot .on ("session.updated" )
74+ @sts_bot .on ("conversation.item.created" )
75+ @sts_bot .on ("response.created" )
76+ @sts_bot .on ("response.done" )
77+ @sts_bot .on ("call.session_participant_joined" )
78+ @sts_bot .on ("call.session_participant_left" )
79+ async def _on_openai_event (event ):
80+ print (f"🔔 Event received: { event .type } " )
81+ print (f" Event data: { event } " )
82+ logging .info ("🔔 Event: %s" , event .type )
83+
84+ try :
85+ logging .info ("Connecting to OpenAI Realtime..." )
86+
87+ # Check if API key is set
88+ if not os .getenv ("OPENAI_API_KEY" ):
89+ logging .error ("❌ OPENAI_API_KEY not found in environment" )
90+ return
91+
92+ await sts_bot .connect (call , agent_user_id = bot_user_id )
93+ logging .info ("🎧 Listening for responses... (Press Ctrl+C to stop)" )
94+ logging .info ("💡 Try speaking in the browser to generate audio events!" )
95+
96+ while sts_bot .is_connected :
97+ await asyncio .sleep (1 )
98+
99+ except KeyboardInterrupt : # noqa: WPS420
100+ logging .info ("\n ⏹️ Stopping OpenAI Realtime Speech to Speech bot…" )
101+ except Exception as e : # noqa: BLE001
102+ logging .exception ("❌ Error: %s" , e )
103+ finally :
104+ logging .info ("Cleaning up..." )
105+ await sts_bot .close ()
106+ client .delete_users ([user_id , bot_user_id ])
107+ logging .info ("Cleanup complete" )
108+
109+
110+ if __name__ == "__main__" :
111+ asyncio .run (main ())
0 commit comments