4747
4848cummulativeResult = ""
4949isSelect = False
50+ isNarrate = False
51+ isShowSQL = False
52+ isRunSQL = False
53+ isExplainSQL = False
5054last_result_time = None
5155
56+
5257def audio_callback (in_data , frame_count , time_info , status ):
5358 queue .put_nowait (in_data )
5459 return (None , pyaudio .paContinue )
5560
61+
5662p = pyaudio .PyAudio ()
5763
5864stream = p .open (
@@ -68,11 +74,13 @@ def audio_callback(in_data, frame_count, time_info, status):
6874config = from_file ()
6975isInsertResults = False
7076
77+
7178async def send_audio (client ):
7279 while True :
7380 data = await queue .get ()
7481 await client .send_data (data )
7582
83+
7684def play_audio (file_path ):
7785 try :
7886 wf = wave .open (file_path , 'rb' )
@@ -96,9 +104,10 @@ def play_audio(file_path):
96104 except Exception as e :
97105 print (f"Error playing audio: { e } " )
98106
107+
99108class SpeechListener (RealtimeClientListener ):
100109 def on_result (self , result ):
101- global cummulativeResult , isSelect , last_result_time
110+ global cummulativeResult , isSelect , isNarrate , isShowSQL , isRunSQL , isExplainSQL , last_result_time
102111 if result ["transcriptions" ][0 ]["isFinal" ]:
103112 transcription = result ['transcriptions' ][0 ]['transcription' ]
104113 cummulativeResult += transcription
@@ -107,41 +116,60 @@ def on_result(self, result):
107116 if cummulativeResult .lower ().startswith ("hey db" ):
108117 cummulativeResult = cummulativeResult [len ("hey db" ):].strip ()
109118 isSelect = True
119+ elif cummulativeResult .lower ().startswith ("hey deebee" ):
120+ cummulativeResult = cummulativeResult [len ("hey deebee" ):].strip ()
121+ isSelect = True
110122 elif cummulativeResult .lower ().startswith ("adb" ):
111123 cummulativeResult = cummulativeResult [len ("adb" ):].strip ()
112124 isSelect = True
113125 else :
114126 cummulativeResult = ""
127+ if cummulativeResult .lower ().endswith ("use narrate" ):
128+ cummulativeResult = cummulativeResult [:- len ("use narrate" )].strip ()
129+ isNarrate = True
130+ print (f"isNarrate: { isNarrate } " )
131+ elif cummulativeResult .lower ().endswith ("use show sql" ):
132+ cummulativeResult = cummulativeResult [:- len ("use show sql" )].strip ()
133+ isShowSQL = True
134+ print (f"isShowSQL: { isShowSQL } " )
135+ elif cummulativeResult .lower ().endswith ("use run sql" ):
136+ cummulativeResult = cummulativeResult [:- len ("use run sql" )].strip ()
137+ isRunSQL = True
138+ print (f"isRunSQL: { isRunSQL } " )
139+ elif cummulativeResult .lower ().endswith ("use explain" ):
140+ cummulativeResult = cummulativeResult [:- len ("use explain sql" )].strip ()
141+ isExplainSQL = True
142+ print (f"isExplainSQL: { isExplainSQL } " )
115143 last_result_time = asyncio .get_event_loop ().time ()
116144 else :
117145 print (f"Received partial results: { result ['transcriptions' ][0 ]['transcription' ]} " )
118146
119147 def on_ack_message (self , ackmessage ):
120- """Handle acknowledgment messages (required by the abstract class)."""
121148 print (f"ACK received: { ackmessage } " )
122149
123150 def on_connect (self ):
124- """Handle connection event (required by the abstract class)."""
125151 print ("Connected to Realtime Speech Service." )
126152
127153 def on_connect_message (self , connectmessage ):
128- """Handle connection messages (required by the abstract class)."""
129154 print (f"Connect message: { connectmessage } " )
130155
131156 def on_network_event (self , ackmessage ):
132- """Handle network events (required by the abstract class)."""
133157 print (f"Network event: { ackmessage } " )
134158
135159 def on_error (self , exception ):
136- """Handle errors (required by the abstract class)."""
137160 print (f"An error occurred: { exception } " )
138161
162+
139163async def check_idle ():
140- global last_result_time , isSelect
164+ global last_result_time , isSelect , isNarrate , isShowSQL , isRunSQL , isExplainSQL
141165 while True :
142166 if isSelect and last_result_time and (asyncio .get_event_loop ().time () - last_result_time > 2 ):
143167 executeSelectAI ()
144168 isSelect = False
169+ isNarrate = False
170+ isShowSQL = False
171+ isRunSQL = False
172+ isExplainSQL = False
145173 await asyncio .sleep (1 )
146174
147175
@@ -152,30 +180,45 @@ def authenticator():
152180 private_key = oci .signer .load_private_key_from_file (config ["key_file" ])
153181 auth = SecurityTokenSigner (token = token , private_key = private_key )
154182 return auth
183+
184+
155185def executeSelectAI ():
156- global cummulativeResult , isInsertResults , latest_thetime , latest_question , latest_answer
186+ global cummulativeResult , isNarrate , isShowSQL , isRunSQL , isExplainSQL , isInsertResults , latest_thetime , latest_question , latest_answer
157187 print (f"executeSelectAI called cummulative result: { cummulativeResult } " )
188+ cummulativeResult += " . Answer in 20 words or less."
189+ if isNarrate :
190+ selectai_action = "narrate" # query database and give back narration style reply
191+ elif isShowSQL :
192+ selectai_action = "showsql" # show the sql generated by select AI for this prompt/query
193+ elif isRunSQL :
194+ selectai_action = "runsql" # show the results of running the sql generated by select AI for this prompt/query
195+ elif isExplainSQL :
196+ selectai_action = "explainsql" # explain the sql generated by select AI for this prompt/query
197+ else :
198+ selectai_action = "chat" # bypass database and go straight to LLM
158199
159200 query = """SELECT DBMS_CLOUD_AI.GENERATE(
160201 prompt => :prompt,
161- profile_name => 'openai_gpt35 ',
162- action => 'chat' )
202+ profile_name => 'AIHOLO ',
203+ action => :action )
163204 FROM dual"""
164205
165206 try :
166207 with connection .cursor () as cursor :
167- cursor .execute (query , {'prompt' : cummulativeResult })
208+ print (f"executeSelectAI using { selectai_action } " )
209+ cursor .execute (query , {'prompt' : cummulativeResult , 'action' : selectai_action })
168210 result = cursor .fetchone ()
169211 if result and isinstance (result [0 ], oracledb .LOB ):
170212 text_result = result [0 ].read ()
171213 print (f"Query result: { text_result } " )
172-
173214 latest_thetime = datetime .now ()
174215 latest_question = cummulativeResult
175216 latest_answer = text_result [:3000 ]
176217
177218 cummulativeResult = ""
178219
220+ if selectai_action in ("showsql" , "runsql" , "explainsql" ):
221+ return
179222 # API key-based authentication...
180223 config = oci .config .from_file ("~/.oci/config" , "DEFAULT" )
181224 speech_client = AIServiceSpeechClient (config )
@@ -184,13 +227,13 @@ def executeSelectAI():
184227 text = f" { latest_answer } " ,
185228 is_stream_enabled = False ,
186229 configuration = oci .ai_speech .models .TtsOracleConfiguration (
187- model_family = "ORACLE" ,
188- # Brian Annabelle Bob Stacy Phil Cindy Brad
189- model_details = oci .ai_speech .models .TtsOracleTts2NaturalModelDetails (voice_id = "Brian" ),
190- speech_settings = oci .ai_speech .models .TtsOracleSpeechSettings (
191- speech_mark_types = ["WORD" ]
192- ),
193- )
230+ model_family = "ORACLE" ,
231+ # Brian Annabelle Bob Stacy Phil Cindy Brad
232+ model_details = oci .ai_speech .models .TtsOracleTts2NaturalModelDetails (voice_id = "Brian" ),
233+ speech_settings = oci .ai_speech .models .TtsOracleSpeechSettings (
234+ speech_mark_types = ["WORD" ]
235+ ),
236+ )
194237 )
195238
196239 response = speech_client .synthesize_speech (synthesize_speech_details = text_to_speech )
@@ -206,6 +249,7 @@ def executeSelectAI():
206249 except Exception as e :
207250 print (f"An error occurred: { e } " )
208251
252+
209253async def handle_request (request ):
210254 global latest_thetime , latest_question , latest_answer
211255 data = {
@@ -215,6 +259,7 @@ async def handle_request(request):
215259 }
216260 return web .json_response (data )
217261
262+
218263if __name__ == "__main__" :
219264 loop = asyncio .new_event_loop () # Fix event loop issue
220265 asyncio .set_event_loop (loop )
@@ -237,7 +282,7 @@ async def handle_request(request):
237282 )
238283
239284 # Instance, resource principal, or session token-based authentication (as shown below) can also be used
240- # client = AIServiceSpeechClient (
285+ # client = RealtimeClient (
241286 # config=config,
242287 # realtime_speech_parameters=realtime_speech_parameters,
243288 # listener=SpeechListener(),
0 commit comments