Vanhwbt commited on
Commit
f17b239
·
1 Parent(s): 09b1021
Files changed (2) hide show
  1. app.py +110 -87
  2. requirements.txt +2 -1
app.py CHANGED
@@ -20,7 +20,7 @@ st.set_page_config(
20
  # --- 2. CẤU HÌNH BACKEND ---
21
  API_URL = "https://Vanhwbt-TraPhuHoi-Backend.hf.space/predict"
22
 
23
- # --- 3. HÀM LƯU DỮ LIỆU ĐA NĂNG (HF + IMGBB + SHEET) ---
24
  import gspread
25
  import json
26
  import io
@@ -180,41 +180,51 @@ disease_info = {
180
  }
181
  }
182
 
183
- # --- Cấu hình Gemini (Phiên bản Bất Tử - Fix mọi lỗi Key) ---
 
 
184
  try:
185
- # 1. Kiểm tra xem key 'TraPhuHoi' trong secrets không
186
- if "TraPhuHoi" in st.secrets:
187
- secret_value = st.secrets["TraPhuHoi"]
188
-
189
- # 2. Xử lý thông minh:
190
- # Nếu Hugging Face trả về string (chỉ có mã key AIzaSy...) -> Dùng luôn
191
- if isinstance(secret_value, str):
192
- GEMINI_API_KEY = secret_value
193
-
194
- # Nếu trả về Dictionary (kiểu TOML: [TraPhuHoi] api_key = "...") -> Lấy field api_key
195
- elif isinstance(secret_value, dict) and "api_key" in secret_value:
196
- GEMINI_API_KEY = secret_value["api_key"]
197
 
198
- # Nếu không đúng cả 2
199
- else:
200
- GEMINI_API_KEY = None
 
 
 
201
 
202
- # 3. Tiến hành cấu hình
203
- if GEMINI_API_KEY:
204
- genai.configure(api_key=GEMINI_API_KEY)
205
- model_gemini = genai.GenerativeModel('gemini-2.5-flash')
206
- gemini_configured = True
207
- else:
208
- gemini_configured = False
209
- model_gemini = None
 
 
 
 
 
 
 
 
 
210
  else:
211
- # Không tìm thấy secret tên TraPhuHoi
 
212
  gemini_configured = False
213
  model_gemini = None
214
 
215
  except Exception as e:
216
  # Log lỗi ra terminal server để debug nếu cần
217
- print(f"Lỗi cấu hình Gemini: {e}")
218
  gemini_configured = False
219
  model_gemini = None
220
 
@@ -243,69 +253,82 @@ st.markdown("""
243
  </div>
244
  """, unsafe_allow_html=True)
245
 
246
- # ================== 🤖 CHATBOT ==================
247
- st.divider()
248
- st.subheader("🤖 Trò chuyện cùng Chuyên Gia Trà Phú Hội")
249
-
250
- if gemini_configured and model_gemini:
251
- # [FIX] Sửa prompt thành Cây Trà
252
- personality_prompt = """
253
- Tôi là Bác sĩ AgriDoc, chuyên gia về CÂY TRÀ PHÚ HỘI.
254
- Mục tiêu: Hỗ trợ bà con chẩn đoán bệnh trên cây trà.
255
- Phong cách: Thân thiện, ngắn gọn, thực tế.
256
- Quy tắc: Chỉ trả lời về cây trà. Dựa vào dữ liệu đã học.
257
- """
258
- knowledge_base = "\n\n# DỮ LIỆU BỆNH:\n"
259
- for key, info in disease_info.items():
260
- knowledge_base += f"- {info['ten']}: {info['mo_ta']} | Xử lý: {', '.join(info['xu_ly'])}\n"
261
-
262
- initial_context = personality_prompt + knowledge_base
263
- initial_greeting = "Chào bà con! Tui là chuyên gia cây trà đây, bà con cần hỏi bệnh gì?"
264
 
265
- # Nút xóa hội thoại
266
- if st.button("🗑️ Xóa hội thoại"):
267
- st.session_state.clear()
268
- st.rerun()
269
 
270
- if "chat_history_gemini" not in st.session_state:
271
- st.session_state.chat_history_gemini = [{"role": "assistant", "content": initial_greeting}]
 
 
 
 
272
 
273
- if "gemini_chat" not in st.session_state:
274
- try:
275
- st.session_state.gemini_chat = model_gemini.start_chat(history=[
276
- {'role': 'user', 'parts': [initial_context]},
277
- {'role': 'model', 'parts': [initial_greeting]}
278
- ])
279
- except:
280
- st.error("Lỗi khởi tạo Chat.")
281
- st.stop()
282
-
283
- # Hiện lịch sử chat
284
- for message in st.session_state.chat_history_gemini:
285
- with st.chat_message(message["role"]):
286
- st.markdown(message["content"])
287
-
288
- # Nhập câu hỏi
289
- if user_input := st.chat_input("Hỏi về bệnh trà..."):
290
- st.session_state.chat_history_gemini.append({"role": "user", "content": user_input})
291
- with st.chat_message("user"):
292
- st.markdown(user_input)
293
-
294
- try:
295
- with st.spinner("Đang suy nghĩ..."):
296
- response = st.session_state.gemini_chat.send_message(user_input, stream=True)
297
- with st.chat_message("assistant"):
298
- response_text = ""
299
- response_placeholder = st.empty()
300
- for chunk in response:
301
- response_text += chunk.text
302
- response_placeholder.markdown(response_text + "▌")
303
- response_placeholder.markdown(response_text)
304
- st.session_state.chat_history_gemini.append({"role": "assistant", "content": response_text})
305
- except Exception as e:
306
- st.error(f"Lỗi API: {e}")
307
- else:
308
- st.warning("⚠️ Chưa kết nối được Gemini (Kiểm tra lại Secrets).")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
309
 
310
  # --- 5. GIAO DIỆN CHÍNH (HTML) ---
311
  st.markdown("""
 
20
  # --- 2. CẤU HÌNH BACKEND ---
21
  API_URL = "https://Vanhwbt-TraPhuHoi-Backend.hf.space/predict"
22
 
23
+ # --- 2.5. HÀM LƯU DỮ LIỆU ĐA NĂNG (HF + IMGBB + SHEET) ---
24
  import gspread
25
  import json
26
  import io
 
180
  }
181
  }
182
 
183
+ # --- Cấu hình Gemini (Phiên bản Bất Tử - Fix mọi lỗi Key & Quota) ---
184
+ import random # <--- Nhớ thêm thư viện này để bốc thăm
185
+
186
  try:
187
+ # 1. Gom tất cả các Key vào một danh sách
188
+ potential_keys = ["TraPhuHoi", "TraPhuHoi1", "TraPhuHoi2", "TraPhuHoi3"]
189
+ available_keys = []
190
+
191
+ for key_name in potential_keys:
192
+ if key_name in st.secrets:
193
+ secret_value = st.secrets[key_name]
 
 
 
 
 
194
 
195
+ # Xử lý: Lấy chuỗi key sạch (dù là String hay Dict)
196
+ real_key = None
197
+ if isinstance(secret_value, str):
198
+ real_key = secret_value
199
+ elif isinstance(secret_value, dict) and "api_key" in secret_value:
200
+ real_key = secret_value["api_key"]
201
 
202
+ # Nếu lấy được key thì bỏ vào rổ
203
+ if real_key:
204
+ available_keys.append(real_key)
205
+
206
+ # 2. Bốc thăm và Cấu hình
207
+ if available_keys:
208
+ # Chọn ngẫu nhiên 1 key trong danh sách
209
+ chosen_key = random.choice(available_keys)
210
+
211
+ # In log ra terminal để bro biết đang dùng key nào (Debug)
212
+ print(f"🔑 Đang sử dụng Key (đuôi): ...{chosen_key[-6:]}")
213
+
214
+ genai.configure(api_key=chosen_key)
215
+
216
+ # [QUAN TRỌNG] Dùng bản 1.5 Flash để tránh lỗi 400 và tiết kiệm
217
+ model_gemini = genai.GenerativeModel('gemini-1.5-flash')
218
+ gemini_configured = True
219
  else:
220
+ # Không tìm thấy bất kỳ key nào
221
+ print("❌ Không tìm thấy key Gemini nào trong Secrets!")
222
  gemini_configured = False
223
  model_gemini = None
224
 
225
  except Exception as e:
226
  # Log lỗi ra terminal server để debug nếu cần
227
+ print(f"🔥 Lỗi cấu hình Gemini: {e}")
228
  gemini_configured = False
229
  model_gemini = None
230
 
 
253
  </div>
254
  """, unsafe_allow_html=True)
255
 
256
+ # ================== 🤖 CHATBOT (POWERED BY GEMMA 9B) ==================
257
+ from huggingface_hub import InferenceClient # Nhớ cài thư viện: pip install huggingface_hub
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
 
259
+ st.divider()
260
+ st.subheader("🤖 Trò chuyện cùng Chuyên Gia Trà Phú Hội (Gemma AI)")
 
 
261
 
262
+ # --- 1. HÀM GỌI GEMMA 9B ---
263
+ def chat_with_gemma(prompt):
264
+ try:
265
+ # Kiểm tra Token
266
+ if "HF_TOKEN" not in st.secrets:
267
+ return "⚠️ Lỗi: Chưa có HF_TOKEN trong Secrets."
268
 
269
+ # Khởi tạo Client
270
+ client = InferenceClient(api_key=st.secrets["HF_TOKEN"])
271
+
272
+ # Thiết lập tính cách chuyên gia
273
+ system_instruction = """
274
+ Bạn là Kỹ sư Nông nghiệp chuyên về Cây Trà Phú Hội (Nhơn Trạch, Đồng Nai).
275
+ Nhiệm vụ: Tư vấn kỹ thuật trồng, chăm sóc, trị bệnh (Rầy nhảy, Đốm rong, Cháy lá...) cho bà con.
276
+ Phong cách: Thân thiện, ngắn gọn, súc tích, dùng từ ngữ bình dân dễ hiểu.
277
+ Tuyệt đối: Trả lời Tiếng Việt. Nếu không biết thì khuyên bà con hỏi cán bộ khuyến nông.
278
+ """
279
+
280
+ # Tạo tin nhắn gửi đi
281
+ messages = [
282
+ {"role": "user", "content": f"{system_instruction}\n\nCâu hỏi của bà con: {prompt}"}
283
+ ]
284
+
285
+ # Gọi Model Gemma-2-9B (Bản thông minh, miễn phí)
286
+ response = client.chat_completion(
287
+ model="google/gemma-2-9b-it",
288
+ messages=messages,
289
+ max_tokens=800,
290
+ stream=False # Tắt stream để chạy ổn định hơn trên Web
291
+ )
292
+ return response.choices[0].message.content
293
+
294
+ except Exception as e:
295
+ return f"😔 Kỹ sư Gemma đang bận (Lỗi kết nối): {e}"
296
+
297
+ # --- 2. GIAO DIỆN CHAT ---
298
+
299
+ # Nút xóa hội thoại
300
+ if st.button("🗑️ Xóa hội thoại"):
301
+ st.session_state.chat_history_gemini = []
302
+ st.rerun()
303
+
304
+ # Khởi tạo lịch sử nếu chưa
305
+ if "chat_history_gemini" not in st.session_state:
306
+ st.session_state.chat_history_gemini = [
307
+ {"role": "assistant", "content": "Chào bà con! Tui là Kỹ sư Gemma (Trí tuệ nhân tạo), bà con cần hỏi bệnh gì về cây trà không?"}
308
+ ]
309
+
310
+ # Hiện lịch sử chat cũ
311
+ for message in st.session_state.chat_history_gemini:
312
+ with st.chat_message(message["role"]):
313
+ st.markdown(message["content"])
314
+
315
+ # --- 3. XỬ LÝ KHI NGƯỜI DÙNG NHẬP CÂU HỎI ---
316
+ if user_input := st.chat_input("Hỏi về bệnh trà, cách bón phân..."):
317
+ # A. Hiện câu hỏi của người dùng ngay lập tức
318
+ st.session_state.chat_history_gemini.append({"role": "user", "content": user_input})
319
+ with st.chat_message("user"):
320
+ st.markdown(user_input)
321
+
322
+ # B. Gọi Gemma trả lời
323
+ with st.spinner("Kỹ sư Gemma đang suy nghĩ..."):
324
+ bot_reply = chat_with_gemma(user_input)
325
+
326
+ # Hiện câu trả lời của Bot
327
+ with st.chat_message("assistant"):
328
+ st.markdown(bot_reply)
329
+
330
+ # Lưu vào lịch sử
331
+ st.session_state.chat_history_gemini.append({"role": "assistant", "content": bot_reply})
332
 
333
  # --- 5. GIAO DIỆN CHÍNH (HTML) ---
334
  st.markdown("""
requirements.txt CHANGED
@@ -4,4 +4,5 @@ pillow
4
  google-generativeai
5
  gspread
6
  oauth2client
7
- google-api-python-client
 
 
4
  google-generativeai
5
  gspread
6
  oauth2client
7
+ google-api-python-client
8
+ huggingface_hub