Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import pandas as pd | |
| from datetime import datetime | |
| from sentiment import analyze_sentiment | |
| from reply_style import warm_reply | |
| def sentiment_to_numeric(label: str, score: float) -> float: | |
| label = label.lower() | |
| if label == "positive": | |
| return round(score, 3) | |
| elif label == "negative": | |
| return round(-score, 3) | |
| else: # neutral | |
| return 0.0 | |
| def confidence_level(score: float) -> str: | |
| score = float(score) | |
| if score < 0.4: | |
| return "low" | |
| elif score < 0.7: | |
| return "medium" | |
| return "high" | |
| def chatbot_response(user_input, chat_messages, mood_log, memory): | |
| # State 初始化(避免 None) | |
| chat_messages = chat_messages or [] # list[dict] | |
| mood_log = mood_log or [] # list[dict] | |
| memory = memory or [] # list[dict] (Groq messages) | |
| user_input = (user_input or "").strip() | |
| if not user_input: | |
| chat_messages = chat_messages + [{"role": "assistant", "content": "(你沒有輸入內容哦)"}] | |
| return chat_messages, chat_messages, mood_log, memory, "" | |
| # 1) 顯示:使用者訊息 | |
| chat_messages = chat_messages + [{"role": "user", "content": user_input}] | |
| # 2) 情緒分析 | |
| sentiment, score = analyze_sentiment(user_input) | |
| # 3) 生成回覆(warm_reply 必須回傳 reply, memory) | |
| reply, memory = warm_reply(user_input, sentiment, score, memory) | |
| # 4) 顯示:助理回覆 | |
| chat_messages = chat_messages + [{"role": "assistant", "content": reply}] | |
| # 5) 記錄心情(含轉換後欄位) | |
| sentiment_numeric = sentiment_to_numeric(sentiment, score) | |
| confidence_lvl = confidence_level(score) | |
| if mood_log: | |
| prev = mood_log[-1] | |
| delta_sentiment = sentiment_numeric - float(prev.get("sentiment_numeric", 0.0)) | |
| delta_confidence = float(score) - float(prev.get("confidence_score", 0.0)) | |
| else: | |
| delta_sentiment = 0.0 | |
| delta_confidence = 0.0 | |
| mood_log.append({ | |
| "timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"), | |
| "text": user_input, | |
| "sentiment_label": sentiment, | |
| "sentiment_numeric": sentiment_numeric, | |
| "confidence_score": round(float(score), 3), | |
| "confidence_level": confidence_lvl, | |
| "delta_sentiment": round(delta_sentiment, 3), | |
| "delta_confidence": round(delta_confidence, 3), | |
| }) | |
| # 最後回傳 msg="" 清空輸入框 | |
| return chat_messages, chat_messages, mood_log, memory, "" | |
| def export_csv(mood_log): | |
| if not mood_log: | |
| return None | |
| df = pd.DataFrame(mood_log) | |
| columns = [ | |
| "timestamp", | |
| "text", | |
| "sentiment_label", | |
| "sentiment_numeric", | |
| "confidence_score", | |
| "confidence_level", | |
| "delta_sentiment", | |
| "delta_confidence", | |
| ] | |
| for c in columns: | |
| if c not in df.columns: | |
| df[c] = None | |
| df = df[columns] | |
| df.to_csv("mood_analysis.csv", index=False, encoding="utf-8-sig") | |
| return "mood_analysis.csv" | |
| def reset_session(): | |
| # 回傳:chat_state, mood_state, memory_state, msg, chatbot | |
| return [], [], [], "", [] | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# 跟我聊聊天") | |
| chatbot = gr.Chatbot(height=420) | |
| chat_state = gr.State([]) # messages list (dict) | |
| mood_state = gr.State([]) # mood log list (dict) | |
| memory_state = gr.State([]) # groq memory list (dict) | |
| with gr.Row(): | |
| msg = gr.Textbox(placeholder="輸入訊息…", show_label=False, scale=5) | |
| submit = gr.Button("送出", scale=1) | |
| msg.submit( | |
| chatbot_response, | |
| inputs=[msg, chat_state, mood_state, memory_state], | |
| outputs=[chatbot, chat_state, mood_state, memory_state, msg], | |
| ) | |
| submit.click( | |
| chatbot_response, | |
| inputs=[msg, chat_state, mood_state, memory_state], | |
| outputs=[chatbot, chat_state, mood_state, memory_state, msg], | |
| ) | |
| with gr.Row(): | |
| export_btn = gr.Button("匯出心情記錄 CSV") | |
| download_file = gr.File(label="File") | |
| export_btn.click(export_csv, inputs=[mood_state], outputs=[download_file]) | |
| with gr.Row(): | |
| reset_btn = gr.Button("清除本次對話/記憶") | |
| reset_btn.click( | |
| reset_session, | |
| inputs=None, | |
| outputs=[chat_state, mood_state, memory_state, msg, chatbot], | |
| ) | |
| demo.launch() | |