PhilipL commited on
Commit
476dbfc
·
verified ·
1 Parent(s): 7ad1213

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +26 -29
app.py CHANGED
@@ -46,7 +46,7 @@ def init_rag_system():
46
  rag_initialized = True
47
 
48
  # ==========================================
49
- # 2. 核心功能 (保持不變)
50
  # ==========================================
51
  def get_restaurant_data(mood_score_str, food_choice):
52
  init_rag_system()
@@ -74,12 +74,22 @@ def get_restaurant_data(mood_score_str, food_choice):
74
 
75
  def generate_content_with_groq(restaurant_name, restaurant_detail, user_diary, mood_score, mood_guide_reason, debug_mode=False):
76
  if not GROQ_API_KEY: return "⚠️ 請設定 GROQ_API_KEY"
 
77
  client = OpenAI(api_key=GROQ_API_KEY, base_url="https://api.groq.com/openai/v1")
 
78
  system_prompt = "你是一個幽默、懂吃且善解人意的 AI 朋友..."
79
  user_msg = f"【狀態】心情分數:{mood_score}\n【日記】{user_diary}\n【建議原因】{mood_guide_reason}\n【餐廳】{restaurant_name}\n資料:{restaurant_detail}"
 
80
  try:
81
  response = client.chat.completions.create(model="llama-3.3-70b-versatile", messages=[{"role": "system", "content": system_prompt}, {"role": "user", "content": user_msg}])
82
- return response.choices[0].message.content
 
 
 
 
 
 
 
83
  except Exception as e: return f"Groq Error: {str(e)}"
84
 
85
  def generate_image_huggingface(prompt):
@@ -97,26 +107,30 @@ def mood_agent_logic(score_input, food_input, diary_input, debug_mode):
97
  if global_retriever:
98
  docs = global_retriever.invoke(name)
99
  if docs: rag_info = "\n".join([d.page_content for d in docs])
 
100
  ai_text = generate_content_with_groq(name, rag_info, diary_input, score_input, mood_reason, debug_mode)
 
 
 
 
 
 
101
  final_response = f"### 🍽️ 推薦:{name}\n\n{ai_text}"
102
  map_html = f'<div style="text-align:center"><a href="{url}" target="_blank" style="background:#4CAF50;color:white;padding:8px 16px;border-radius:20px;text-decoration:none">🗺️ Google Map 導航</a></div>'
 
103
  yield final_response, None, map_html
104
  image_output = generate_image_huggingface(img_prompt)
105
  yield final_response, image_output, map_html
106
 
107
 
108
  # ==========================================
109
- # 3. [修正版] 橋接邏輯 (Bridge Functions)
110
  # ==========================================
111
 
112
- # 這是 app.py 自己的格式 (注意:這裡是半形括號)
113
  def _score_to_radio_value(score):
114
  mapping = {1: "1 (心情差)", 2: "2 (不太好)", 3: "3 (普通)", 4: "4 (不錯)", 5: "5 (超棒)"}
115
- # 預防萬一 score 是 None 或其他怪怪的值
116
- try:
117
- score = int(score)
118
- except:
119
- score = 3
120
  return mapping.get(score, "3 (普通)")
121
 
122
  # 橋接 1:開始
@@ -129,33 +143,21 @@ def bridge_stop_click(st):
129
  res = emotion.on_stop(st)
130
  return res[1], res[0], gr.update(visible=False), res[5], res[4]
131
 
132
- # 橋接 3:Webcam 串流 (修正分數填入問題)
133
  def bridge_predict_frame(frame, st):
134
  res = emotion.on_stream(frame, st)
 
135
 
136
- out_cam = res[0]
137
- out_result = res[1]
138
- # out_mood = res[2] # ❌ 我們不使用隊友回傳的 UI 更新,因為括號格式不同
139
- out_st = res[4]
140
- out_btn_start = res[5]
141
-
142
- score_update = gr.update()
143
- tabs_update = gr.update()
144
- out_btn_stop = gr.update()
145
 
146
- # 如果辨識完成,我們自己產生一個符合 app.py 格式的 UI 更新
147
  if out_st.finished and hasattr(out_st, 'final_score'):
148
- # ✅ 使用 _score_to_radio_value 將整數轉換為半形括號字串
149
  new_val = _score_to_radio_value(out_st.final_score)
150
  score_update = gr.update(value=new_val)
151
-
152
  tabs_update = gr.Tabs(selected=1)
153
  out_btn_stop = gr.update(visible=False)
154
 
155
  return out_cam, out_result, out_st, out_btn_stop, out_btn_start, score_update, tabs_update
156
 
157
- # (已移除) 橋接 4:圖片上傳 - 功能已移除
158
-
159
 
160
  # ==========================================
161
  # 4. Gradio 介面建構
@@ -180,8 +182,6 @@ with gr.Blocks(title="AI 心情食堂", css=combined_css) as demo:
180
 
181
  cam = gr.Image(sources=["webcam"], streaming=True, type="numpy", label="攝影機畫面", visible=False)
182
  result_markdown = gr.Markdown(emotion._hint_html("請按「開啟攝影機辨識」並允許瀏覽器使用��機。"))
183
-
184
- # (已移除) 上傳照片區塊
185
 
186
  # Tab 2: 主功能區
187
  with gr.TabItem("🍽️ AI 心情食堂 (Step 2)", id=1):
@@ -189,7 +189,6 @@ with gr.Blocks(title="AI 心情食堂", css=combined_css) as demo:
189
  gr.Markdown(f"## 🍱 今天想吃點什麼?")
190
  with gr.Row():
191
  with gr.Column(scale=1):
192
- # 这里的 Radio 选项使用的是半形括号
193
  score_input = gr.Radio(
194
  ["1 (心情差)", "2 (不太好)", "3 (普通)", "4 (不錯)", "5 (超棒)"],
195
  label="1. 心情分數 (由 Tab 1 自動填入)",
@@ -230,8 +229,6 @@ with gr.Blocks(title="AI 心情食堂", css=combined_css) as demo:
230
  show_progress="minimal"
231
  )
232
 
233
- # (已移除) 上傳圖片事件
234
-
235
  submit_btn.click(
236
  fn=mood_agent_logic,
237
  inputs=[score_input, food_input, diary_input, debug_mode_btn],
 
46
  rag_initialized = True
47
 
48
  # ==========================================
49
+ # 2. 核心功能 (已修復除錯模式)
50
  # ==========================================
51
  def get_restaurant_data(mood_score_str, food_choice):
52
  init_rag_system()
 
74
 
75
  def generate_content_with_groq(restaurant_name, restaurant_detail, user_diary, mood_score, mood_guide_reason, debug_mode=False):
76
  if not GROQ_API_KEY: return "⚠️ 請設定 GROQ_API_KEY"
77
+
78
  client = OpenAI(api_key=GROQ_API_KEY, base_url="https://api.groq.com/openai/v1")
79
+
80
  system_prompt = "你是一個幽默、懂吃且善解人意的 AI 朋友..."
81
  user_msg = f"【狀態】心情分數:{mood_score}\n【日記】{user_diary}\n【建議原因】{mood_guide_reason}\n【餐廳】{restaurant_name}\n資料:{restaurant_detail}"
82
+
83
  try:
84
  response = client.chat.completions.create(model="llama-3.3-70b-versatile", messages=[{"role": "system", "content": system_prompt}, {"role": "user", "content": user_msg}])
85
+ content = response.choices[0].message.content
86
+
87
+ # ### [修復] 除錯模式邏輯 ###
88
+ if debug_mode:
89
+ content += f"\n\n--- 🔧 DEBUG: Groq Prompt ---\n**System:** {system_prompt}\n\n**User:** {user_msg}\n-----------------------"
90
+ # ########################
91
+
92
+ return content
93
  except Exception as e: return f"Groq Error: {str(e)}"
94
 
95
  def generate_image_huggingface(prompt):
 
107
  if global_retriever:
108
  docs = global_retriever.invoke(name)
109
  if docs: rag_info = "\n".join([d.page_content for d in docs])
110
+
111
  ai_text = generate_content_with_groq(name, rag_info, diary_input, score_input, mood_reason, debug_mode)
112
+
113
+ # ### [修復] 除錯模式邏輯 (圖片 Prompt) ###
114
+ if debug_mode:
115
+ ai_text += f"\n\n--- 🔧 DEBUG: Image Prompt ---\n{img_prompt}\n-----------------------"
116
+ # ######################################
117
+
118
  final_response = f"### 🍽️ 推薦:{name}\n\n{ai_text}"
119
  map_html = f'<div style="text-align:center"><a href="{url}" target="_blank" style="background:#4CAF50;color:white;padding:8px 16px;border-radius:20px;text-decoration:none">🗺️ Google Map 導航</a></div>'
120
+
121
  yield final_response, None, map_html
122
  image_output = generate_image_huggingface(img_prompt)
123
  yield final_response, image_output, map_html
124
 
125
 
126
  # ==========================================
127
+ # 3. 橋接邏輯 (Bridge Functions)
128
  # ==========================================
129
 
 
130
  def _score_to_radio_value(score):
131
  mapping = {1: "1 (心情差)", 2: "2 (不太好)", 3: "3 (普通)", 4: "4 (不錯)", 5: "5 (超棒)"}
132
+ try: score = int(score)
133
+ except: score = 3
 
 
 
134
  return mapping.get(score, "3 (普通)")
135
 
136
  # 橋接 1:開始
 
143
  res = emotion.on_stop(st)
144
  return res[1], res[0], gr.update(visible=False), res[5], res[4]
145
 
146
+ # 橋接 3:Webcam 串流
147
  def bridge_predict_frame(frame, st):
148
  res = emotion.on_stream(frame, st)
149
+ out_cam = res[0]; out_result = res[1]; out_st = res[4]; out_btn_start = res[5]
150
 
151
+ score_update = gr.update(); tabs_update = gr.update(); out_btn_stop = gr.update()
 
 
 
 
 
 
 
 
152
 
 
153
  if out_st.finished and hasattr(out_st, 'final_score'):
 
154
  new_val = _score_to_radio_value(out_st.final_score)
155
  score_update = gr.update(value=new_val)
 
156
  tabs_update = gr.Tabs(selected=1)
157
  out_btn_stop = gr.update(visible=False)
158
 
159
  return out_cam, out_result, out_st, out_btn_stop, out_btn_start, score_update, tabs_update
160
 
 
 
161
 
162
  # ==========================================
163
  # 4. Gradio 介面建構
 
182
 
183
  cam = gr.Image(sources=["webcam"], streaming=True, type="numpy", label="攝影機畫面", visible=False)
184
  result_markdown = gr.Markdown(emotion._hint_html("請按「開啟攝影機辨識」並允許瀏覽器使用��機。"))
 
 
185
 
186
  # Tab 2: 主功能區
187
  with gr.TabItem("🍽️ AI 心情食堂 (Step 2)", id=1):
 
189
  gr.Markdown(f"## 🍱 今天想吃點什麼?")
190
  with gr.Row():
191
  with gr.Column(scale=1):
 
192
  score_input = gr.Radio(
193
  ["1 (心情差)", "2 (不太好)", "3 (普通)", "4 (不錯)", "5 (超棒)"],
194
  label="1. 心情分數 (由 Tab 1 自動填入)",
 
229
  show_progress="minimal"
230
  )
231
 
 
 
232
  submit_btn.click(
233
  fn=mood_agent_logic,
234
  inputs=[score_input, food_input, diary_input, debug_mode_btn],