@@ -83,6 +83,12 @@ async def user_variable(q: Q):
83
83
84
84
async def client_variable (q : Q ):
85
85
q .client .query = None
86
+ _gretting_msg = ["""Welcome to the SQL Sidekick!\n I am an AI assistant, i am here to help you find answers to questions on structured data.
87
+ To get started, please select a table from the dropdown and ask your question.
88
+ One could start by learning about the dataset by asking questions like:
89
+ - Describe data.
90
+ - Preview.""" , True ]
91
+ q .client .chat_buffer = [_gretting_msg ]
86
92
87
93
# Reference: https://wave.h2o.ai/docs/examples/table-markdown-pandas/
88
94
def make_markdown_row (values ):
@@ -113,6 +119,52 @@ def clear_cards(q, ignore: Optional[List[str]] = []) -> None:
113
119
del q .page [name ]
114
120
q .client .cards .remove (name )
115
121
122
+ async def draw_additional_actions (q : Q ):
123
+ add_card (
124
+ q ,
125
+ "additional_actions" ,
126
+ ui .form_card (
127
+ box = ui .box ("vertical" , height = "120px" ),
128
+ items = [
129
+ ui .buttons (
130
+ [
131
+ ui .button (
132
+ name = "suggest" ,
133
+ icon = "" ,
134
+ caption = "Suggests possible questions one could start with" ,
135
+ label = "Discover" ,
136
+ ),
137
+ ui .button (
138
+ name = "regenerate" ,
139
+ icon = "RepeatOne" ,
140
+ caption = "Attempts regeneration of the last response" ,
141
+ label = "Try Again" ,
142
+ primary = True ,
143
+ ),
144
+ ui .button (
145
+ name = "regenerate_with_options" ,
146
+ icon = "RepeatAll" ,
147
+ caption = "Regenerates with options" ,
148
+ label = "Try Harder" ,
149
+ ),
150
+ ui .button (
151
+ name = "save_conversation" ,
152
+ caption = "Saves the conversation in the history for future reference to improve response" ,
153
+ label = "Accept" ,
154
+ icon = "Emoji2" ,
155
+ ),
156
+ ui .button (
157
+ name = "save_rejected_conversation" ,
158
+ caption = "Saves the disappointed conversation to improve response." ,
159
+ label = "Reject" ,
160
+ icon = "EmojiDisappointed" ,
161
+ ),
162
+ ],
163
+ justify = "center" ,
164
+ )
165
+ ],
166
+ ),
167
+ )
116
168
117
169
@on ("#chat" )
118
170
async def chat (q : Q ):
@@ -209,77 +261,24 @@ async def chat(q: Q):
209
261
ui .chatbot_card (
210
262
box = ui .box ("vertical" , height = "500px" ),
211
263
name = "chatbot" ,
212
- data = data (fields = "content from_user" , t = "list" , size = - 50 ),
264
+ placeholder = "Type your question here, happy to help!" ,
265
+ data = data (fields = "content from_user" , t = "list" , size = - 50 , rows = q .client .chat_buffer ),
213
266
commands = chat_card_command_items ,
214
- events = ["scroll " ],
267
+ events = ["scroll_up " ],
215
268
),
216
269
),
217
- add_card (
218
- q ,
219
- "additional_actions" ,
220
- ui .form_card (
221
- box = ui .box ("vertical" , height = "120px" ),
222
- items = [
223
- ui .progress (name = 'progress' , label = 'Thinking ...' , value = 0 ),
224
- ui .buttons (
225
- [
226
- ui .button (
227
- name = "suggest" ,
228
- icon = "" ,
229
- caption = "Suggests possible questions one could start with" ,
230
- label = "Discover" ,
231
- ),
232
- ui .button (
233
- name = "regenerate" ,
234
- icon = "RepeatOne" ,
235
- caption = "Attempts regeneration of the last response" ,
236
- label = "Try Again" ,
237
- primary = True ,
238
- ),
239
- ui .button (
240
- name = "regenerate_with_options" ,
241
- icon = "RepeatAll" ,
242
- caption = "Regenerates with options" ,
243
- label = "Try Harder" ,
244
- ),
245
- ui .button (
246
- name = "save_conversation" ,
247
- caption = "Saves the conversation in the history for future reference to improve response" ,
248
- label = "Accept" ,
249
- icon = "Emoji2" ,
250
- ),
251
- ui .button (
252
- name = "save_rejected_conversation" ,
253
- caption = "Saves the disappointed conversation to improve response." ,
254
- label = "Reject" ,
255
- icon = "EmojiDisappointed" ,
256
- ),
257
- ],
258
- justify = "center" ,
259
- )
260
- ],
261
- ),
262
- )
263
270
264
- if q .args .chatbot is None or q .args .chatbot .strip () == "" :
265
- _msg = """Welcome to the SQL Sidekick!\n I am an AI assistant, i am here to help you find answers to questions on structured data.
266
- To get started, please select a table from the dropdown and ask your question.
267
- One could start by learning about the dataset by asking questions like:
268
- - Describe data.
269
- - Preview."""
270
- q .args .chatbot = _msg
271
- q .page ["chat_card" ].data += [q .args .chatbot , False ]
272
- logging .info (f"Chatbot response: { q .args .chatbot } " )
271
+ # additional actions
272
+ await draw_additional_actions (q )
273
273
274
274
275
275
async def update_ui (q : Q , value : int ):
276
- q .page ['additional_actions ' ].progress .value = value
276
+ q .page ['chat_card_progress ' ].progress .value = value
277
277
await q .page .save ()
278
278
279
279
280
- def _execute_suggestions (q : Q , loop : asyncio .AbstractEventLoop ):
280
+ def _execute_suggestions (q : Q , loop : asyncio .AbstractEventLoop , time_out = 50 ):
281
281
count = 0
282
- time_out = 50
283
282
future = executor = None
284
283
result = task = None
285
284
while count < time_out :
@@ -301,10 +300,12 @@ async def chatbot(q: Q):
301
300
q .page ["sidebar" ].value = "#chat"
302
301
303
302
# Append user message.
303
+ q .client .chat_buffer .append ([q .args .chatbot , True ])
304
304
q .page ["chat_card" ].data += [q .args .chatbot , True ]
305
305
306
306
if q .page ["select_tables" ].table_dropdown .value is None or q .client .table_name is None :
307
307
q .page ["chat_card" ].data += ["Please select a table to continue!" , False ]
308
+ q .client .chat_buffer .append ([q .args .chatbot , False ])
308
309
return
309
310
310
311
if (
@@ -336,12 +337,42 @@ async def chatbot(q: Q):
336
337
llm_response = f"The selected dataset has total number of { n_cols } columns.\n Below is quick preview:\n { df_markdown } "
337
338
elif q .args .chatbot and (q .args .chatbot .lower () == "recommend questions" or q .args .chatbot .lower () == "recommend qs" ):
338
339
await q .page .save ()
340
+ #_rows = q.page["chat_card"].data.rows
341
+ #import pdb; pdb.set_trace()
342
+ del q .page ["chat_card" ]
343
+ del q .page ["additional_actions" ]
344
+ add_card (
345
+ q ,
346
+ "chat_card_progress" ,
347
+ ui .form_card (
348
+ box = ui .box ("vertical" , height = "500px" ), items = [ui .progress (name = 'progress' , label = 'Thinking ...' , value = 0 )]))
349
+ await draw_additional_actions (q )
339
350
loop = asyncio .get_event_loop ()
340
351
with concurrent .futures .ThreadPoolExecutor () as pool :
341
352
llm_response = await q .exec (pool , _execute_suggestions , q , loop = loop )
342
353
if not llm_response :
343
354
llm_response = "Something went wrong, check the API Keys provided."
344
355
logging .info (f"Recommended Questions:\n { llm_response } " )
356
+ # Re-draw the chat-card
357
+ del q .page ["chat_card_progress" ]
358
+ del q .page ["additional_actions" ]
359
+ chat_card_command_items = [
360
+ ui .command (name = "download_accept" , label = "Download QnA history" , icon = "Download" ),
361
+ ui .command (name = "download_reject" , label = "Download in-correct QnA history" , icon = "Download" ),
362
+ ]
363
+ _chat_history = q .client .chat_buffer
364
+ add_card (
365
+ q ,
366
+ "chat_card" ,
367
+ ui .chatbot_card (
368
+ box = ui .box ("vertical" , height = "500px" ),
369
+ name = "chatbot" ,
370
+ placeholder = "Type your question here, happy to help!" ,
371
+ data = data (fields = "content from_user" , t = "list" , size = - 50 , rows = _chat_history ),
372
+ commands = chat_card_command_items ,
373
+ events = ["scroll_up" ],
374
+ )),
375
+ await draw_additional_actions (q )
345
376
q .args .chatbot = None
346
377
elif q .args .chatbot and q .args .chatbot .lower () == "db setup" :
347
378
llm_response , err = db_setup (
@@ -415,7 +446,7 @@ async def chatbot(q: Q):
415
446
torch .cuda .empty_cache ()
416
447
llm_response = "Something went wrong, try executing the query again!"
417
448
q .client .llm_response = llm_response
418
- q .page [ "chat_card" ]. data += [llm_response , False ]
449
+ q .client . chat_buffer . append ( [llm_response , False ])
419
450
420
451
421
452
@on ("submit_url_keys" )
@@ -752,7 +783,6 @@ async def init(q: Q) -> None:
752
783
],
753
784
)
754
785
755
- # Connect to LLM
756
786
openai .api_key = ""
757
787
758
788
await user_variable (q )
0 commit comments