LawrenceBai commited on
Commit
757aa6c
·
1 Parent(s): f89f516
Files changed (2) hide show
  1. app.py +11 -31
  2. core/emotion_care_manager.py +26 -9
app.py CHANGED
@@ -1064,37 +1064,12 @@ async def websocket_endpoint_with_jwt(
1064
  if transcription:
1065
  logger.info(f"🤖 處理即時轉錄結果: {transcription}")
1066
 
1067
- # 音頻情緒辨識(新增
1068
  audio_emotion = None
 
1069
  if audio_buffer:
1070
- try:
1071
- from services.audio_emotion_service import audio_emotion_service
1072
- logger.info(f"🎭 開始音頻情緒辨識,音頻大小: {len(audio_buffer)} bytes")
1073
- audio_emotion = await audio_emotion_service.predict_from_bytes(audio_buffer)
1074
-
1075
- if audio_emotion.get("success"):
1076
- emotion_label = audio_emotion.get("emotion")
1077
- confidence = audio_emotion.get("confidence", 0.0)
1078
- logger.info(f"✅ 音頻情緒: {emotion_label} (置信度: {confidence:.4f})")
1079
-
1080
- # 發送音頻情緒給前端
1081
- await websocket.send_json({
1082
- "type": "audio_emotion_detected",
1083
- "emotion": emotion_label,
1084
- "confidence": confidence,
1085
- "all_emotions": audio_emotion.get("all_emotions", {}),
1086
- "source": "audio"
1087
- })
1088
- else:
1089
- logger.warning(f"⚠️ 音頻情緒辨識失敗: {audio_emotion.get('error')}")
1090
- audio_emotion = None
1091
- except Exception as e:
1092
- logger.error(f"❌ 音頻情緒辨識異常: {e}")
1093
- audio_emotion = None
1094
- finally:
1095
- # 清理音頻緩衝
1096
- client_info.pop("audio_buffer", None)
1097
- manager.set_client_info(user_id, client_info)
1098
 
1099
  # 通知前端開始思考
1100
  await websocket.send_json({"type": "typing", "message": "thinking"})
@@ -1346,17 +1321,22 @@ async def handle_message(user_message, user_id, chat_id, messages, request_id: s
1346
  # 提取情緒與關懷模式資訊(新增)
1347
  emotion = res.meta.get('emotion') if res.meta else None
1348
  care_mode = res.meta.get('care_mode', False) if res.meta else False
 
 
1349
 
1350
  # 立即返回完整結果(包含工具信息與情緒)
 
1351
  if tool_name or tool_data or emotion or care_mode:
 
1352
  return {
1353
  'message': res.text,
1354
  'tool_name': tool_name,
1355
  'tool_data': tool_data,
1356
- 'emotion': emotion, # 新增情緒欄位
1357
- 'care_mode': care_mode # 新增關懷模式標記
1358
  }
1359
  else:
 
1360
  return res.text
1361
 
1362
 
 
1064
  if transcription:
1065
  logger.info(f"🤖 處理即時轉錄結果: {transcription}")
1066
 
1067
+ # 音頻情緒辨識已禁用改用文字情緒偵測
1068
  audio_emotion = None
1069
+ # 清理音頻緩衝
1070
  if audio_buffer:
1071
+ client_info.pop("audio_buffer", None)
1072
+ manager.set_client_info(user_id, client_info)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1073
 
1074
  # 通知前端開始思考
1075
  await websocket.send_json({"type": "typing", "message": "thinking"})
 
1321
  # 提取情緒與關懷模式資訊(新增)
1322
  emotion = res.meta.get('emotion') if res.meta else None
1323
  care_mode = res.meta.get('care_mode', False) if res.meta else False
1324
+
1325
+ logger.info(f"🎭 handle_message 情緒: emotion={emotion}, care_mode={care_mode}, meta={res.meta}")
1326
 
1327
  # 立即返回完整結果(包含工具信息與情緒)
1328
+ # 注意:即使 emotion 是 "neutral" 也要返回 dict,確保前端收到情緒資訊
1329
  if tool_name or tool_data or emotion or care_mode:
1330
+ logger.info(f"📤 返回 dict 格式: emotion={emotion}")
1331
  return {
1332
  'message': res.text,
1333
  'tool_name': tool_name,
1334
  'tool_data': tool_data,
1335
+ 'emotion': emotion,
1336
+ 'care_mode': care_mode
1337
  }
1338
  else:
1339
+ logger.info(f"📤 返回純文字格式(無情緒資訊)")
1340
  return res.text
1341
 
1342
 
core/emotion_care_manager.py CHANGED
@@ -17,20 +17,37 @@ class EmotionCareManager:
17
 
18
  # 極端情緒定義(需要進入關懷模式的情緒)
19
  EXTREME_EMOTIONS = {"sad", "angry", "fear"}
 
 
 
20
 
21
  # 模式存活與冷卻(避免反覆觸發)
22
- CARE_TTL_SECONDS = 20 * 60 # 20 分鐘自動失效
23
- COOLDOWN_SECONDS = 10 * 60 # 10 分鐘內不重入
24
 
25
  # 解除關懷模式的關鍵字
26
  RELEASE_KEYWORDS = [
27
- # 繁體
28
  "我沒事了", "我好了", "沒事了", "好多了", "好一點了",
29
  "我好些了", "沒關係了", "我ok了", "我可以了",
30
- "不用擔心", "別擔心我",
31
- # 簡體
 
 
32
  "我没事了", "没事了", "好一点了", "没关系了",
33
- "不用担心", "别担心我",
 
 
 
 
 
 
 
 
 
 
 
 
34
  ]
35
 
36
  # 用戶關懷狀態
@@ -107,15 +124,15 @@ class EmotionCareManager:
107
  if not state or not state.get("in_care_mode", False):
108
  return False
109
 
110
- # 優先檢查情緒:如果偵測到 neutral,立即解除關懷模式
111
- if emotion and emotion.lower() == "neutral":
112
  original_emotion = state.get("emotion", "unknown")
113
  duration = time.time() - state.get("start_time", 0)
114
 
115
  state["in_care_mode"] = False
116
  state["last_exit_time"] = time.time()
117
 
118
- logger.info(f"✅ 用戶 {user_id}(chat={chat_id or 'default'})情緒恢復為 neutral({original_emotion} → neutral),解除關懷模式(持續 {duration:.1f}秒)")
119
  return True
120
 
121
  # 檢查是否包含解除關鍵字
 
17
 
18
  # 極端情緒定義(需要進入關懷模式的情緒)
19
  EXTREME_EMOTIONS = {"sad", "angry", "fear"}
20
+
21
+ # 正面情緒定義(可以解除關懷模式的情緒)
22
+ POSITIVE_EMOTIONS = {"neutral", "happy", "surprise"}
23
 
24
  # 模式存活與冷卻(避免反覆觸發)
25
+ CARE_TTL_SECONDS = 10 * 60 # 10 分鐘自動失效(從 20 分鐘縮短)
26
+ COOLDOWN_SECONDS = 5 * 60 # 5 分鐘內不重入(從 10 分鐘縮短)
27
 
28
  # 解除關懷模式的關鍵字
29
  RELEASE_KEYWORDS = [
30
+ # 繁體中文
31
  "我沒事了", "我好了", "沒事了", "好多了", "好一點了",
32
  "我好些了", "沒關係了", "我ok了", "我可以了",
33
+ "不用擔心", "別擔心我", "謝謝關心", "感謝你",
34
+ "我很好", "心情好多了", "開心", "快樂", "高興",
35
+ "沒問題", "放心", "安心了", "舒服多了",
36
+ # 簡體中文
37
  "我没事了", "没事了", "好一点了", "没关系了",
38
+ "不用担心", "别担心我", "谢谢关心", "感谢你",
39
+ "我很好", "心情好多了", "开心", "快乐", "高兴",
40
+ "没问题", "放心", "安心了", "舒服多了",
41
+ # 英文
42
+ "i'm fine", "i am fine", "i'm ok", "i am ok", "i'm okay", "i am okay",
43
+ "i feel better", "feeling better", "much better", "all good",
44
+ "don't worry", "no worries", "thank you", "thanks",
45
+ # 日文
46
+ "大丈夫", "元気", "ありがとう", "心配しないで",
47
+ # 印尼文
48
+ "saya baik", "tidak apa-apa", "terima kasih",
49
+ # 越南文
50
+ "tôi ổn", "không sao", "cảm ơn",
51
  ]
52
 
53
  # 用戶關懷狀態
 
124
  if not state or not state.get("in_care_mode", False):
125
  return False
126
 
127
+ # 優先檢查情緒:如果偵測到正面情緒(neutral, happy, surprise),立即解除關懷模式
128
+ if emotion and emotion.lower() in cls.POSITIVE_EMOTIONS:
129
  original_emotion = state.get("emotion", "unknown")
130
  duration = time.time() - state.get("start_time", 0)
131
 
132
  state["in_care_mode"] = False
133
  state["last_exit_time"] = time.time()
134
 
135
+ logger.info(f"✅ 用戶 {user_id}(chat={chat_id or 'default'})情緒恢復為 {emotion}({original_emotion} → {emotion}),解除關懷模式(持續 {duration:.1f}秒)")
136
  return True
137
 
138
  # 檢查是否包含解除關鍵字