47
47
48
48
cummulativeResult = ""
49
49
isSelect = False
50
+ isNarrate = False
51
+ isShowSQL = False
52
+ isRunSQL = False
53
+ isExplainSQL = False
50
54
last_result_time = None
51
55
56
+
52
57
def audio_callback (in_data , frame_count , time_info , status ):
53
58
queue .put_nowait (in_data )
54
59
return (None , pyaudio .paContinue )
55
60
61
+
56
62
p = pyaudio .PyAudio ()
57
63
58
64
stream = p .open (
@@ -68,11 +74,13 @@ def audio_callback(in_data, frame_count, time_info, status):
68
74
config = from_file ()
69
75
isInsertResults = False
70
76
77
+
71
78
async def send_audio (client ):
72
79
while True :
73
80
data = await queue .get ()
74
81
await client .send_data (data )
75
82
83
+
76
84
def play_audio (file_path ):
77
85
try :
78
86
wf = wave .open (file_path , 'rb' )
@@ -96,9 +104,10 @@ def play_audio(file_path):
96
104
except Exception as e :
97
105
print (f"Error playing audio: { e } " )
98
106
107
+
99
108
class SpeechListener (RealtimeClientListener ):
100
109
def on_result (self , result ):
101
- global cummulativeResult , isSelect , last_result_time
110
+ global cummulativeResult , isSelect , isNarrate , isShowSQL , isRunSQL , isExplainSQL , last_result_time
102
111
if result ["transcriptions" ][0 ]["isFinal" ]:
103
112
transcription = result ['transcriptions' ][0 ]['transcription' ]
104
113
cummulativeResult += transcription
@@ -107,41 +116,60 @@ def on_result(self, result):
107
116
if cummulativeResult .lower ().startswith ("hey db" ):
108
117
cummulativeResult = cummulativeResult [len ("hey db" ):].strip ()
109
118
isSelect = True
119
+ elif cummulativeResult .lower ().startswith ("hey deebee" ):
120
+ cummulativeResult = cummulativeResult [len ("hey deebee" ):].strip ()
121
+ isSelect = True
110
122
elif cummulativeResult .lower ().startswith ("adb" ):
111
123
cummulativeResult = cummulativeResult [len ("adb" ):].strip ()
112
124
isSelect = True
113
125
else :
114
126
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 } " )
115
143
last_result_time = asyncio .get_event_loop ().time ()
116
144
else :
117
145
print (f"Received partial results: { result ['transcriptions' ][0 ]['transcription' ]} " )
118
146
119
147
def on_ack_message (self , ackmessage ):
120
- """Handle acknowledgment messages (required by the abstract class)."""
121
148
print (f"ACK received: { ackmessage } " )
122
149
123
150
def on_connect (self ):
124
- """Handle connection event (required by the abstract class)."""
125
151
print ("Connected to Realtime Speech Service." )
126
152
127
153
def on_connect_message (self , connectmessage ):
128
- """Handle connection messages (required by the abstract class)."""
129
154
print (f"Connect message: { connectmessage } " )
130
155
131
156
def on_network_event (self , ackmessage ):
132
- """Handle network events (required by the abstract class)."""
133
157
print (f"Network event: { ackmessage } " )
134
158
135
159
def on_error (self , exception ):
136
- """Handle errors (required by the abstract class)."""
137
160
print (f"An error occurred: { exception } " )
138
161
162
+
139
163
async def check_idle ():
140
- global last_result_time , isSelect
164
+ global last_result_time , isSelect , isNarrate , isShowSQL , isRunSQL , isExplainSQL
141
165
while True :
142
166
if isSelect and last_result_time and (asyncio .get_event_loop ().time () - last_result_time > 2 ):
143
167
executeSelectAI ()
144
168
isSelect = False
169
+ isNarrate = False
170
+ isShowSQL = False
171
+ isRunSQL = False
172
+ isExplainSQL = False
145
173
await asyncio .sleep (1 )
146
174
147
175
@@ -152,30 +180,45 @@ def authenticator():
152
180
private_key = oci .signer .load_private_key_from_file (config ["key_file" ])
153
181
auth = SecurityTokenSigner (token = token , private_key = private_key )
154
182
return auth
183
+
184
+
155
185
def 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
157
187
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
158
199
159
200
query = """SELECT DBMS_CLOUD_AI.GENERATE(
160
201
prompt => :prompt,
161
- profile_name => 'openai_gpt35 ',
162
- action => 'chat' )
202
+ profile_name => 'AIHOLO ',
203
+ action => :action )
163
204
FROM dual"""
164
205
165
206
try :
166
207
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 })
168
210
result = cursor .fetchone ()
169
211
if result and isinstance (result [0 ], oracledb .LOB ):
170
212
text_result = result [0 ].read ()
171
213
print (f"Query result: { text_result } " )
172
-
173
214
latest_thetime = datetime .now ()
174
215
latest_question = cummulativeResult
175
216
latest_answer = text_result [:3000 ]
176
217
177
218
cummulativeResult = ""
178
219
220
+ if selectai_action in ("showsql" , "runsql" , "explainsql" ):
221
+ return
179
222
# API key-based authentication...
180
223
config = oci .config .from_file ("~/.oci/config" , "DEFAULT" )
181
224
speech_client = AIServiceSpeechClient (config )
@@ -184,13 +227,13 @@ def executeSelectAI():
184
227
text = f" { latest_answer } " ,
185
228
is_stream_enabled = False ,
186
229
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
+ )
194
237
)
195
238
196
239
response = speech_client .synthesize_speech (synthesize_speech_details = text_to_speech )
@@ -206,6 +249,7 @@ def executeSelectAI():
206
249
except Exception as e :
207
250
print (f"An error occurred: { e } " )
208
251
252
+
209
253
async def handle_request (request ):
210
254
global latest_thetime , latest_question , latest_answer
211
255
data = {
@@ -215,6 +259,7 @@ async def handle_request(request):
215
259
}
216
260
return web .json_response (data )
217
261
262
+
218
263
if __name__ == "__main__" :
219
264
loop = asyncio .new_event_loop () # Fix event loop issue
220
265
asyncio .set_event_loop (loop )
@@ -237,7 +282,7 @@ async def handle_request(request):
237
282
)
238
283
239
284
# Instance, resource principal, or session token-based authentication (as shown below) can also be used
240
- # client = AIServiceSpeechClient (
285
+ # client = RealtimeClient (
241
286
# config=config,
242
287
# realtime_speech_parameters=realtime_speech_parameters,
243
288
# listener=SpeechListener(),
0 commit comments