youngtsai commited on
Commit
2f94953
·
1 Parent(s): 78a1c85

def chat_with_any_ai(ai_type, password, video_id, user_data, transcript_state, key_moments, user_message, chat_history, content_subject, content_grade, questions_answers_json, socratic_mode=False, thread_id=None, ai_name=None):

Browse files
Files changed (1) hide show
  1. app.py +131 -193
app.py CHANGED
@@ -1261,7 +1261,6 @@ def change_questions(password, df_string):
1261
  print("=====get_questions=====")
1262
  return q1, q2, q3
1263
 
1264
- # 「關鍵時刻」另外獨立成一個 tab,時間戳記和文字的下方附上對應的截圖,重點摘要的「關鍵時刻」加上截圖資訊
1265
  def get_key_moments(video_id, formatted_simple_transcript, formatted_transcript, source):
1266
  if source == "gcs":
1267
  print("===get_key_moments on gcs===")
@@ -2100,12 +2099,10 @@ def get_instructions(content_subject, content_grade, key_moments, socratic_mode=
2100
  """
2101
  return instructions
2102
 
2103
- def chat_with_ai(ai_name, password, video_id, user_data, trascript_state, key_moments, user_message, chat_history, content_subject, content_grade, questions_answers_json, socratic_mode=False):
2104
- verify_password(password)
2105
-
2106
- print("=====user_data=====")
2107
  print(f"user_data: {user_data}")
2108
-
2109
  verify_message_length(user_message, max_length=1500)
2110
 
2111
  is_questions_answers_exists, question_message, answer_message = check_questions_answers(user_message, questions_answers_json)
@@ -2113,10 +2110,52 @@ def chat_with_ai(ai_name, password, video_id, user_data, trascript_state, key_mo
2113
  chat_history = update_chat_history(question_message, answer_message, chat_history)
2114
  send_btn_update, send_feedback_btn_update = update_send_and_feedback_buttons(chat_history, CHAT_LIMIT)
2115
  time.sleep(3)
2116
- return "", chat_history, send_btn_update, send_feedback_btn_update
2117
 
 
 
2118
  verify_chat_limit(chat_history, CHAT_LIMIT)
2119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2120
  if not ai_name in ["foxcat", "lili", "maimai"]:
2121
  ai_name = "foxcat"
2122
 
@@ -2140,10 +2179,10 @@ def chat_with_ai(ai_name, password, video_id, user_data, trascript_state, key_mo
2140
  ai_client = ai_name_clients_model.get(ai_name, "foxcat")["ai_client"]
2141
  ai_model_name = ai_name_clients_model.get(ai_name, "foxcat")["ai_model_name"]
2142
 
2143
- if isinstance(trascript_state, str):
2144
- simple_transcript = json.loads(trascript_state)
2145
  else:
2146
- simple_transcript = trascript_state
2147
 
2148
  if isinstance(key_moments, str):
2149
  key_moments_json = json.loads(key_moments)
@@ -2170,26 +2209,9 @@ def chat_with_ai(ai_name, password, video_id, user_data, trascript_state, key_mo
2170
  "instructions": instructions
2171
  }
2172
 
2173
- try:
2174
- chatbot = Chatbot(chatbot_config)
2175
- response_completion = chatbot.chat(user_message, chat_history, socratic_mode, ai_model_name)
2176
- except Exception as e:
2177
- print(f"Error: {e}")
2178
- response_completion = "學習精靈有點累,請稍後再試!"
2179
-
2180
- try:
2181
- # 更新聊天历史
2182
- chat_history = update_chat_history(user_message, response_completion, chat_history)
2183
- send_btn_update, send_feedback_btn_update = update_send_and_feedback_buttons(chat_history, CHAT_LIMIT)
2184
-
2185
- # 返回聊天历史和空字符串清空输入框
2186
- return "", chat_history, send_btn_update, send_feedback_btn_update
2187
- except Exception as e:
2188
- # 处理错误情况
2189
- print(f"Error: {e}")
2190
- return "请求失败,请稍后再试!", chat_history
2191
 
2192
- def feedback_with_ai(chat_history):
2193
  # prompt: 請依據以上的對話(chat_history),總結我的「提問力」,並給予我是否有「問對問題」的回饋和建議
2194
  system_content = """
2195
  你是一個擅長引導問答素養的老師,user 為學生的提問跟回答,請精讀對話過程,針對 user 給予回饋就好,根據以下 Rule:
@@ -2225,10 +2247,16 @@ def feedback_with_ai(chat_history):
2225
  提問表現:【🟡】加油,持續練習,你的提問力會越來越好!
2226
  """
2227
 
2228
-
2229
  client = OPEN_AI_CLIENT
2230
- model_name = "gpt-4-turbo"
2231
- response_text = handle_conversation_by_open_ai_chat_completions(client, model_name, user_content, system_content)
 
 
 
 
 
 
 
2232
  chat_history = update_chat_history(feedback_request_message, response_text, chat_history)
2233
  feedback_btn_update = gr.update(value="已回饋", interactive=False, variant="secondary")
2234
 
@@ -2246,139 +2274,6 @@ def handle_conversation_by_open_ai_chat_completions(client, model_name, user_con
2246
  response_text = response.choices[0].message.content.strip()
2247
  return response_text
2248
 
2249
- # open ai assistant
2250
- def chat_with_opan_ai_assistant(password, youtube_id, user_data, thread_id, trascript_state, key_moments, user_message, chat_history, content_subject, content_grade, questions_answers_json, socratic_mode=False):
2251
- verify_password(password)
2252
-
2253
- print("=====user_data=====")
2254
- print(f"user_data: {user_data}")
2255
-
2256
- verify_message_length(user_message, max_length=1500)
2257
-
2258
- is_questions_answers_exists, question_message, answer_message = check_questions_answers(user_message, questions_answers_json)
2259
- if is_questions_answers_exists:
2260
- chat_history = update_chat_history(question_message, answer_message, chat_history)
2261
- send_btn_update, send_feedback_btn_update = update_send_and_feedback_buttons(chat_history, CHAT_LIMIT)
2262
- time.sleep(3)
2263
- return "", chat_history, thread_id, send_btn_update, send_feedback_btn_update
2264
-
2265
- verify_chat_limit(chat_history, CHAT_LIMIT)
2266
-
2267
- client = OPEN_AI_CLIENT
2268
- assistant_id = OPEN_AI_ASSISTANT_ID_GPT4 #GPT 4 turbo
2269
- if isinstance(key_moments, str):
2270
- key_moments_json = json.loads(key_moments)
2271
- else:
2272
- key_moments_json = key_moments
2273
- # key_moments_json remove images
2274
- for moment in key_moments_json:
2275
- moment.pop('images', None)
2276
- moment.pop('end', None)
2277
- moment.pop('transcript', None)
2278
- key_moments_text = json.dumps(key_moments_json, ensure_ascii=False)
2279
- instructions = get_instructions(content_subject, content_grade, key_moments_text, socratic_mode)
2280
- print(f"=== instructions:{instructions} ===")
2281
- metadata={
2282
- "video_id": youtube_id,
2283
- "user_data": user_data,
2284
- "content_subject": content_subject,
2285
- "content_grade": content_grade,
2286
- "socratic_mode": str(socratic_mode),
2287
- "assistant_id": assistant_id,
2288
- "is_streaming": "false",
2289
- }
2290
- user_message_note = "/n 請嚴格遵循instructions,擔任一位蘇格拉底家教,絕對不要重複 user 的問句,請用引導的方式指引方向,請一定要用繁體中文回答 zh-TW,並用台灣人的禮貌口語表達,回答時不要特別說明這是台灣人的語氣,請在回答的最後標註【參考:(時):(分):(秒)】,(如果是反問學生,就只問一個問題,請幫助學生更好的理解資料,字數在100字以內,回答時如果講到數學專有名詞,請用數學符號代替文字(Latex 用 $ 字號 render, ex: $x^2$)"
2291
- user_content = user_message + user_message_note
2292
- response_text, thread_id = handle_conversation_by_open_ai_assistant(client, user_content, instructions, assistant_id, thread_id, metadata, fallback=True)
2293
-
2294
- # 更新聊天历史
2295
- chat_history = update_chat_history(user_message, response_text, chat_history)
2296
- send_btn_update, send_feedback_btn_update = update_send_and_feedback_buttons(chat_history, CHAT_LIMIT)
2297
-
2298
- return "", chat_history, thread_id, send_btn_update, send_feedback_btn_update
2299
-
2300
- def feedback_with_opan_ai_assistant(thread_id, chat_history):
2301
- # prompt: 請依據以上的對話(chat_history),總結我的「提問力」,並給予我是否有「問對問題」的回饋和建議
2302
- system_content = """
2303
- 你是一個擅長引導問答素養的老師,user 為學生的提問跟回答,請精讀對話過程,針對 user 給予回饋就好,根據以下 Rule:
2304
- - 請使用繁體中文 zh-TW 總結 user 的提問力,並給予是否有問對問題的回饋和建議
2305
- - 不採計【預設提問】的問題,如果 user 的提問都來自【預設提問】,表達用戶善於使用系統,請給予回饋並鼓勵 user 親自提問更具體的問題
2306
- - 如果用戶提問都相當簡短,甚至就是一個字或都是一個數字(像是 user: 1, user:2),請給予回饋並建議 user 提問更具體的問題
2307
- - 如果用戶提問內容只有符號或是亂碼,像是?,!, ..., 3bhwbqhfw2vve2 等,請給予回饋並建議 user 提問更具體的問題
2308
- - 如果用戶提問內容有色情、暴力、仇恨、不當言論等,請給予嚴厲的回饋並建議 user 提問更具體的問題
2309
- - 並用第二人稱「你」來代表 user
2310
- - 請禮貌,並給予鼓勵
2311
- """
2312
- chat_history_conversation = ""
2313
- # 標註 user and assistant as string
2314
- # chat_history 第一組不採計
2315
- for chat in chat_history[1:]:
2316
- user_message = chat[0]
2317
- assistant_message = chat[1]
2318
- chat_history_conversation += f"User: {user_message}\nAssistant: {assistant_message}\n"
2319
-
2320
- feedback_request_message = "請依據以上的對話,總結我的「提問力」,並給予我是否有「問對問題」的回饋和建議"
2321
- user_content = f"""conversation: {chat_history_conversation}
2322
- {feedback_request_message}
2323
- 最後根據提問力表現,給予提問建議、提問表現,並用 emoji 來表示評分:
2324
- 🟢:(表現很好的回饋,給予正向肯定)
2325
- 🟡:(還可以加油的的回饋,給予明確的建議)
2326
- 🔴:(非常不懂提問的回饋,給予鼓勵並給出明確示範)
2327
-
2328
- example:
2329
- 另一方面,你表達「我不想學了」這個情感,其實也是一種重要的反饋。這顯示你可能感到挫折或疲倦。在這種情況下,表達出你的感受是好的,但如果能具體說明是什麼讓你感到這樣,或是有什麼具體的學習障礙,會更有助於找到解決方案。
2330
- 給予你的建議是,嘗試在提問時更明確一些,這樣不僅能幫助你獲得更好的學習支持,也能提高你的問題解決技巧。
2331
- ......
2332
- 提問建議:在提問時,試著具體並清晰地表達你的需求和疑惑,這樣能更有效地得到幫助。
2333
- 提問表現:【🟡】加油,持續練習,你的提問力會越來越好!
2334
- """
2335
-
2336
-
2337
- client = OPEN_AI_CLIENT
2338
- assistant_id = OPEN_AI_ASSISTANT_ID_GPT4 #GPT 4 turbo
2339
- # assistant_id = OPEN_AI_ASSISTANT_ID_GPT3 #GPT 3.5 turbo
2340
- instructions = system_content
2341
- response_text, thread_id = handle_conversation_by_open_ai_assistant(client, user_content, instructions, assistant_id, thread_id, metadata=None, fallback=True)
2342
- chat_history = update_chat_history(feedback_request_message, response_text, chat_history)
2343
- feedback_btn_update = gr.update(value="已回饋", interactive=False, variant="secondary")
2344
-
2345
- return chat_history, feedback_btn_update
2346
-
2347
- def verify_message_length(user_message, max_length=500):
2348
- # 驗證用戶消息的長度
2349
- if len(user_message) > max_length:
2350
- error_msg = "你的訊息太長了,請縮短訊息長度至五百字以內"
2351
- raise gr.Error(error_msg)
2352
-
2353
- def check_questions_answers(user_message, questions_answers_json):
2354
- """檢查問答是否存在,並處理相關邏輯"""
2355
- is_questions_answers_exists = False
2356
- answer = ""
2357
- # 解析問答數據
2358
- if isinstance(questions_answers_json, str):
2359
- qa_data = json.loads(questions_answers_json)
2360
- else:
2361
- qa_data = questions_answers_json
2362
-
2363
- question_message = ""
2364
- answer_message = ""
2365
- for qa in qa_data:
2366
- if user_message == qa["question"] and qa["answer"]:
2367
- is_questions_answers_exists = True
2368
- question_message = f"【預設問題】{user_message}"
2369
- answer_message = qa["answer"]
2370
- print("=== in questions_answers_json==")
2371
- print(f"question: {qa['question']}")
2372
- print(f"answer: {answer_message}")
2373
- break # 匹配到答案後退出循環
2374
-
2375
- return is_questions_answers_exists, question_message, answer_message
2376
-
2377
- def verify_chat_limit(chat_history, chat_limit):
2378
- if chat_history is not None and len(chat_history) > chat_limit:
2379
- error_msg = "此次對話超過上限(對話一輪10次)"
2380
- raise gr.Error(error_msg)
2381
-
2382
  def handle_conversation_by_open_ai_assistant(client, user_message, instructions, assistant_id, thread_id=None, metadata=None, fallback=False):
2383
  """
2384
  Handles the creation and management of a conversation thread.
@@ -2433,6 +2328,41 @@ def handle_conversation_by_open_ai_assistant(client, user_message, instructions,
2433
 
2434
  return response_text, thread_id
2435
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2436
  def update_chat_history(user_message, response, chat_history):
2437
  # 更新聊天歷史的邏輯
2438
  new_chat_history = (user_message, response)
@@ -2661,7 +2591,8 @@ def chatbot_select(chatbot_name):
2661
  chatbot_open_ai_streaming_visible = gr.update(visible=True)
2662
  else:
2663
  chatbot_jutor_visible = gr.update(visible=True)
2664
- ai_name_update = gr.update(value=chatbot_name)
 
2665
 
2666
  return chatbot_select_accordion_visible, all_chatbot_select_btn_visible, chatbot_open_ai_visible, chatbot_open_ai_streaming_visible, chatbot_jutor_visible, ai_name_update
2667
 
@@ -2833,6 +2764,18 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue=gr.themes.colors.orange, seconda
2833
  with gr.Tab("AI小精靈"):
2834
  with gr.Row():
2835
  all_chatbot_select_btn = gr.Button("選擇 AI 小精靈 👈", elem_id="all_chatbot_select_btn", visible=False, variant="secondary", size="sm")
 
 
 
 
 
 
 
 
 
 
 
 
2836
  with gr.Accordion("選擇 AI 小精靈", elem_id="chatbot_select_accordion") as chatbot_select_accordion:
2837
  with gr.Row():
2838
  user_avatar = "https://em-content.zobj.net/source/google/263/flushed-face_1f633.png"
@@ -2927,6 +2870,7 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue=gr.themes.colors.orange, seconda
2927
  with gr.Row():
2928
  chatbot = gr.Chatbot(avatar_images=[user_avatar, bot_avatar], label="OPEN AI", show_share_button=False, likeable=True, show_label=False, latex_delimiters=latex_delimiters,value=chatbot_greeting)
2929
  with gr.Row():
 
2930
  thread_id = gr.Textbox(label="thread_id", visible=False)
2931
  socratic_mode_btn = gr.Checkbox(label="蘇格拉底家教助理模式", value=True, visible=False)
2932
  with gr.Row():
@@ -2972,18 +2916,12 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue=gr.themes.colors.orange, seconda
2972
  💤 精靈們體力都有限,每一次學習只能回答十個問題,請讓我休息一下再問問題喔!
2973
  """,
2974
  ]]
2975
- ai_name = gr.Dropdown(
2976
- label="選擇 AI 助理",
2977
- choices=[
2978
- ("梨梨","lili"),
2979
- ("麥麥","maimai"),
2980
- ("狐狸貓","foxcat")
2981
- ],
2982
- value="foxcat",
2983
- visible=False
2984
- )
2985
- ai_chatbot = gr.Chatbot(label="ai_chatbot", show_share_button=False, likeable=True, show_label=False, latex_delimiters=latex_delimiters, value=ai_chatbot_greeting)
2986
- ai_chatbot_socratic_mode_btn = gr.Checkbox(label="蘇格拉底家教助理模式", value=True, visible=False)
2987
  with gr.Row():
2988
  with gr.Accordion("你也有類似的問題想問嗎? 請按下 ◀︎", open=False) as ask_questions_accordion_2:
2989
  ai_chatbot_question_1 = gr.Button("問題一")
@@ -3234,14 +3172,14 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue=gr.themes.colors.orange, seconda
3234
 
3235
  # OPENAI ASSISTANT CHATBOT 模式
3236
  send_button.click(
3237
- chat_with_opan_ai_assistant,
3238
- inputs=[password, video_id, user_data, thread_id, trascript_state, key_moments, msg, chatbot, content_subject, content_grade, questions_answers_json, socratic_mode_btn],
3239
- outputs=[msg, chatbot, thread_id, send_button, send_feedback_btn],
3240
  scroll_to_output=True
3241
  )
3242
  send_feedback_btn.click(
3243
- feedback_with_opan_ai_assistant,
3244
- inputs=[thread_id, chatbot],
3245
  outputs=[chatbot, send_feedback_btn],
3246
  scroll_to_output=True
3247
  )
@@ -3260,9 +3198,9 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue=gr.themes.colors.orange, seconda
3260
  )
3261
  question_buttons = [btn_1, btn_2, btn_3]
3262
  for question_btn in question_buttons:
3263
- inputs_list = [password, video_id, user_data, thread_id, trascript_state, key_moments, question_btn, chatbot, content_subject, content_grade, questions_answers_json, socratic_mode_btn]
3264
- outputs_list = [msg, chatbot, thread_id, send_button, send_feedback_btn]
3265
- setup_question_button_click(question_btn, inputs_list, outputs_list, chat_with_opan_ai_assistant)
3266
 
3267
  # 為生成問題按鈕設定特殊的點擊事件
3268
  btn_create_question.click(
@@ -3273,23 +3211,23 @@ with gr.Blocks(theme=gr.themes.Base(primary_hue=gr.themes.colors.orange, seconda
3273
 
3274
  # 其他精靈 ai_chatbot 模式
3275
  ai_send_button.click(
3276
- chat_with_ai,
3277
- inputs=[ai_name, password, video_id, user_data, trascript_state, key_moments, ai_msg, ai_chatbot, content_subject, content_grade, questions_answers_json, ai_chatbot_socratic_mode_btn],
3278
- outputs=[ai_msg, ai_chatbot, ai_send_button, ai_send_feedback_btn],
3279
  scroll_to_output=True
3280
  )
3281
  ai_send_feedback_btn.click(
3282
  feedback_with_ai,
3283
- inputs=[ai_chatbot],
3284
  outputs=[ai_chatbot, ai_send_feedback_btn],
3285
  scroll_to_output=True
3286
  )
3287
  # 其他精靈 ai_chatbot 连接 QA 按钮点击事件
3288
  ai_chatbot_question_buttons = [ai_chatbot_question_1, ai_chatbot_question_2, ai_chatbot_question_3]
3289
  for question_btn in ai_chatbot_question_buttons:
3290
- inputs_list = [ai_name, password, video_id, user_data, trascript_state, key_moments, question_btn, ai_chatbot, content_subject, content_grade, questions_answers_json, ai_chatbot_socratic_mode_btn]
3291
- outputs_list = [ai_msg, ai_chatbot, ai_send_button, ai_send_feedback_btn]
3292
- setup_question_button_click(question_btn, inputs_list, outputs_list, chat_with_ai)
3293
 
3294
  ai_chatbot_audio_input.change(
3295
  process_open_ai_audio_to_chatbot,
 
1261
  print("=====get_questions=====")
1262
  return q1, q2, q3
1263
 
 
1264
  def get_key_moments(video_id, formatted_simple_transcript, formatted_transcript, source):
1265
  if source == "gcs":
1266
  print("===get_key_moments on gcs===")
 
2099
  """
2100
  return instructions
2101
 
2102
+ def chat_with_any_ai(ai_type, password, video_id, user_data, transcript_state, key_moments, user_message, chat_history, content_subject, content_grade, questions_answers_json, socratic_mode=False, thread_id=None, ai_name=None):
2103
+ print(f"ai_type: {ai_type}")
 
 
2104
  print(f"user_data: {user_data}")
2105
+ verify_password(password)
2106
  verify_message_length(user_message, max_length=1500)
2107
 
2108
  is_questions_answers_exists, question_message, answer_message = check_questions_answers(user_message, questions_answers_json)
 
2110
  chat_history = update_chat_history(question_message, answer_message, chat_history)
2111
  send_btn_update, send_feedback_btn_update = update_send_and_feedback_buttons(chat_history, CHAT_LIMIT)
2112
  time.sleep(3)
 
2113
 
2114
+ return "", chat_history, send_btn_update, send_feedback_btn_update, thread_id
2115
+
2116
  verify_chat_limit(chat_history, CHAT_LIMIT)
2117
 
2118
+ if ai_type == "chat_completions":
2119
+ chatbot_config = get_chatbot_config(ai_name, transcript_state, key_moments, content_subject, content_grade, video_id, socratic_mode)
2120
+ chatbot = Chatbot(chatbot_config)
2121
+ response_text = chatbot.chat(user_message, chat_history)
2122
+ thread_id = ""
2123
+ elif ai_type == "assistant":
2124
+ client = OPEN_AI_CLIENT
2125
+ assistant_id = OPEN_AI_ASSISTANT_ID_GPT4 #GPT 4 turbo
2126
+ if isinstance(key_moments, str):
2127
+ key_moments_json = json.loads(key_moments)
2128
+ else:
2129
+ key_moments_json = key_moments
2130
+ # key_moments_json remove images
2131
+ for moment in key_moments_json:
2132
+ moment.pop('images', None)
2133
+ moment.pop('end', None)
2134
+ moment.pop('transcript', None)
2135
+ key_moments_text = json.dumps(key_moments_json, ensure_ascii=False)
2136
+ instructions = get_instructions(content_subject, content_grade, key_moments_text, socratic_mode)
2137
+ print(f"=== instructions:{instructions} ===")
2138
+ metadata={
2139
+ "video_id": video_id,
2140
+ "user_data": user_data,
2141
+ "content_subject": content_subject,
2142
+ "content_grade": content_grade,
2143
+ "socratic_mode": str(socratic_mode),
2144
+ "assistant_id": assistant_id,
2145
+ "is_streaming": "false",
2146
+ }
2147
+ user_message_note = "/n 請嚴格遵循instructions,擔任一位蘇格拉底家教,絕對不要重複 user 的問句,請用引導的方式指引方向,請一定要用繁體中文回答 zh-TW,並用台灣人的禮貌口語表達,回答時不要特別說明這是台灣人的語氣,請在回答的最後標註【參考:(時):(分):(秒)】,(如果是反問學生,就只問一個問題,請幫助學生更好的理解資料,字數在100字以內,回答時如果講到數學專有名詞,請用數學符號代替文字(Latex 用 $ 字號 render, ex: $x^2$)"
2148
+ user_content = user_message + user_message_note
2149
+ response_text, thread_id = handle_conversation_by_open_ai_assistant(client, user_content, instructions, assistant_id, thread_id, metadata, fallback=True)
2150
+
2151
+ # 更新聊天历史
2152
+ chat_history = update_chat_history(user_message, response_text, chat_history)
2153
+ send_btn_update, send_feedback_btn_update = update_send_and_feedback_buttons(chat_history, CHAT_LIMIT)
2154
+
2155
+ # 返回聊天历史和空字符串清空输入框
2156
+ return "", chat_history, send_btn_update, send_feedback_btn_update, thread_id
2157
+
2158
+ def get_chatbot_config(ai_name, transcript_state, key_moments, content_subject, content_grade, video_id, socratic_mode=True):
2159
  if not ai_name in ["foxcat", "lili", "maimai"]:
2160
  ai_name = "foxcat"
2161
 
 
2179
  ai_client = ai_name_clients_model.get(ai_name, "foxcat")["ai_client"]
2180
  ai_model_name = ai_name_clients_model.get(ai_name, "foxcat")["ai_model_name"]
2181
 
2182
+ if isinstance(transcript_state, str):
2183
+ simple_transcript = json.loads(transcript_state)
2184
  else:
2185
+ simple_transcript = transcript_state
2186
 
2187
  if isinstance(key_moments, str):
2188
  key_moments_json = json.loads(key_moments)
 
2209
  "instructions": instructions
2210
  }
2211
 
2212
+ return chatbot_config
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2213
 
2214
+ def feedback_with_ai(ai_type, chat_history, thread_id=None):
2215
  # prompt: 請依據以上的對話(chat_history),總結我的「提問力」,並給予我是否有「問對問題」的回饋和建議
2216
  system_content = """
2217
  你是一個擅長引導問答素養的老師,user 為學生的提問跟回答,請精讀對話過程,針對 user 給予回饋就好,根據以下 Rule:
 
2247
  提問表現:【🟡】加油,持續練習,你的提問力會越來越好!
2248
  """
2249
 
 
2250
  client = OPEN_AI_CLIENT
2251
+
2252
+ if ai_type == "chat_completions":
2253
+ model_name = "gpt-4-turbo"
2254
+ response_text = handle_conversation_by_open_ai_chat_completions(client, model_name, user_content, system_content)
2255
+ elif ai_type == "assistant":
2256
+ assistant_id = OPEN_AI_ASSISTANT_ID_GPT4 #GPT 4 turbo
2257
+ # assistant_id = OPEN_AI_ASSISTANT_ID_GPT3 #GPT 3.5 turbo
2258
+ response_text, thread_id = handle_conversation_by_open_ai_assistant(client, user_content, system_content, assistant_id, thread_id, metadata=None, fallback=True)
2259
+
2260
  chat_history = update_chat_history(feedback_request_message, response_text, chat_history)
2261
  feedback_btn_update = gr.update(value="已回饋", interactive=False, variant="secondary")
2262
 
 
2274
  response_text = response.choices[0].message.content.strip()
2275
  return response_text
2276
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2277
  def handle_conversation_by_open_ai_assistant(client, user_message, instructions, assistant_id, thread_id=None, metadata=None, fallback=False):
2278
  """
2279
  Handles the creation and management of a conversation thread.
 
2328
 
2329
  return response_text, thread_id
2330
 
2331
+ def verify_message_length(user_message, max_length=500):
2332
+ # 驗證用戶消息的長度
2333
+ if len(user_message) > max_length:
2334
+ error_msg = "你的訊息太長了,請縮短訊息長度至五百字以內"
2335
+ raise gr.Error(error_msg)
2336
+
2337
+ def check_questions_answers(user_message, questions_answers_json):
2338
+ """檢查問答是否存在,並處理相關邏輯"""
2339
+ is_questions_answers_exists = False
2340
+ answer = ""
2341
+ # 解析問答數據
2342
+ if isinstance(questions_answers_json, str):
2343
+ qa_data = json.loads(questions_answers_json)
2344
+ else:
2345
+ qa_data = questions_answers_json
2346
+
2347
+ question_message = ""
2348
+ answer_message = ""
2349
+ for qa in qa_data:
2350
+ if user_message == qa["question"] and qa["answer"]:
2351
+ is_questions_answers_exists = True
2352
+ question_message = f"【預設問題】{user_message}"
2353
+ answer_message = qa["answer"]
2354
+ print("=== in questions_answers_json==")
2355
+ print(f"question: {qa['question']}")
2356
+ print(f"answer: {answer_message}")
2357
+ break # 匹配到答案後退出循環
2358
+
2359
+ return is_questions_answers_exists, question_message, answer_message
2360
+
2361
+ def verify_chat_limit(chat_history, chat_limit):
2362
+ if chat_history is not None and len(chat_history) > chat_limit:
2363
+ error_msg = "此次對話超過上限(對話一輪10次)"
2364
+ raise gr.Error(error_msg)
2365
+
2366
  def update_chat_history(user_message, response, chat_history):
2367
  # 更新聊天歷史的邏輯
2368
  new_chat_history = (user_message, response)
 
2591
  chatbot_open_ai_streaming_visible = gr.update(visible=True)
2592
  else:
2593
  chatbot_jutor_visible = gr.update(visible=True)
2594
+
2595
+ ai_name_update = gr.update(value=chatbot_name)
2596
 
2597
  return chatbot_select_accordion_visible, all_chatbot_select_btn_visible, chatbot_open_ai_visible, chatbot_open_ai_streaming_visible, chatbot_jutor_visible, ai_name_update
2598
 
 
2764
  with gr.Tab("AI小精靈"):
2765
  with gr.Row():
2766
  all_chatbot_select_btn = gr.Button("選擇 AI 小精靈 👈", elem_id="all_chatbot_select_btn", visible=False, variant="secondary", size="sm")
2767
+ ai_name = gr.Dropdown(
2768
+ label="選擇 AI 助理",
2769
+ choices=[
2770
+ ("飛特精靈","chatbot_open_ai"),
2771
+ ("飛特音速","chatbot_open_ai_streaming"),
2772
+ ("梨梨","lili"),
2773
+ ("麥麥","maimai"),
2774
+ ("狐狸貓","foxcat")
2775
+ ],
2776
+ value="foxcat",
2777
+ visible=False
2778
+ )
2779
  with gr.Accordion("選擇 AI 小精靈", elem_id="chatbot_select_accordion") as chatbot_select_accordion:
2780
  with gr.Row():
2781
  user_avatar = "https://em-content.zobj.net/source/google/263/flushed-face_1f633.png"
 
2870
  with gr.Row():
2871
  chatbot = gr.Chatbot(avatar_images=[user_avatar, bot_avatar], label="OPEN AI", show_share_button=False, likeable=True, show_label=False, latex_delimiters=latex_delimiters,value=chatbot_greeting)
2872
  with gr.Row():
2873
+ chatbot_ai_type = gr.Textbox(value="assistant", visible=False)
2874
  thread_id = gr.Textbox(label="thread_id", visible=False)
2875
  socratic_mode_btn = gr.Checkbox(label="蘇格拉底家教助理模式", value=True, visible=False)
2876
  with gr.Row():
 
2916
  💤 精靈們體力都有限,每一次學習只能回答十個問題,請讓我休息一下再問問題喔!
2917
  """,
2918
  ]]
2919
+ with gr.Row():
2920
+ ai_chatbot = gr.Chatbot(label="ai_chatbot", show_share_button=False, likeable=True, show_label=False, latex_delimiters=latex_delimiters, value=ai_chatbot_greeting)
2921
+ with gr.Row():
2922
+ ai_chatbot_ai_type = gr.Textbox(value="chat_completions", visible=False)
2923
+ ai_chatbot_thread_id = gr.Textbox(label="thread_id", visible=False)
2924
+ ai_chatbot_socratic_mode_btn = gr.Checkbox(label="蘇格拉底家教助理模式", value=True, visible=False)
 
 
 
 
 
 
2925
  with gr.Row():
2926
  with gr.Accordion("你也有類似的問題想問嗎? 請按下 ◀︎", open=False) as ask_questions_accordion_2:
2927
  ai_chatbot_question_1 = gr.Button("問題一")
 
3172
 
3173
  # OPENAI ASSISTANT CHATBOT 模式
3174
  send_button.click(
3175
+ chat_with_any_ai,
3176
+ inputs=[chatbot_ai_type, password, video_id, user_data, trascript_state, key_moments, msg, chatbot, content_subject, content_grade, questions_answers_json, socratic_mode_btn, thread_id, ai_name],
3177
+ outputs=[msg, chatbot, send_button, send_feedback_btn, thread_id],
3178
  scroll_to_output=True
3179
  )
3180
  send_feedback_btn.click(
3181
+ feedback_with_ai,
3182
+ inputs=[chatbot_ai_type, chatbot, thread_id],
3183
  outputs=[chatbot, send_feedback_btn],
3184
  scroll_to_output=True
3185
  )
 
3198
  )
3199
  question_buttons = [btn_1, btn_2, btn_3]
3200
  for question_btn in question_buttons:
3201
+ inputs_list = [chatbot_ai_type, password, video_id, user_data, trascript_state, key_moments, question_btn, chatbot, content_subject, content_grade, questions_answers_json, socratic_mode_btn, thread_id, ai_name]
3202
+ outputs_list = [msg, chatbot, send_button, send_feedback_btn, thread_id]
3203
+ setup_question_button_click(question_btn, inputs_list, outputs_list, chat_with_any_ai)
3204
 
3205
  # 為生成問題按鈕設定特殊的點擊事件
3206
  btn_create_question.click(
 
3211
 
3212
  # 其他精靈 ai_chatbot 模式
3213
  ai_send_button.click(
3214
+ chat_with_any_ai,
3215
+ inputs=[ai_chatbot_ai_type, password, video_id, user_data, trascript_state, key_moments, ai_msg, ai_chatbot, content_subject, content_grade, questions_answers_json, ai_chatbot_socratic_mode_btn, ai_chatbot_thread_id, ai_name],
3216
+ outputs=[ai_msg, ai_chatbot, ai_send_button, ai_send_feedback_btn, ai_chatbot_thread_id],
3217
  scroll_to_output=True
3218
  )
3219
  ai_send_feedback_btn.click(
3220
  feedback_with_ai,
3221
+ inputs=[ai_chatbot_ai_type, ai_chatbot, ai_chatbot_thread_id],
3222
  outputs=[ai_chatbot, ai_send_feedback_btn],
3223
  scroll_to_output=True
3224
  )
3225
  # 其他精靈 ai_chatbot 连接 QA 按钮点击事件
3226
  ai_chatbot_question_buttons = [ai_chatbot_question_1, ai_chatbot_question_2, ai_chatbot_question_3]
3227
  for question_btn in ai_chatbot_question_buttons:
3228
+ inputs_list = [ai_chatbot_ai_type, password, video_id, user_data, trascript_state, key_moments, question_btn, ai_chatbot, content_subject, content_grade, questions_answers_json, ai_chatbot_socratic_mode_btn, ai_chatbot_thread_id, ai_name]
3229
+ outputs_list = [ai_msg, ai_chatbot, ai_send_button, ai_send_feedback_btn, ai_chatbot_thread_id]
3230
+ setup_question_button_click(question_btn, inputs_list, outputs_list, chat_with_any_ai)
3231
 
3232
  ai_chatbot_audio_input.change(
3233
  process_open_ai_audio_to_chatbot,