- 为 ai_auto_response 队列消息记录入队时刻,并增加消息过期丢弃机制 - 在出队前与发送前各检查一次消息是否过期,避免补发过时群聊回复 - 为 skip 日志补充 age 字段,便于观察排队老化情况 - 将 ai_auto_response 外层总超时收紧到 20 秒,并新增 message_expire_sec=12 配置 - 将 Dify auto_reply.group 请求超时收紧到 15 秒,并关闭重试以提升群聊时效性
118 lines
4.5 KiB
Python
118 lines
4.5 KiB
Python
from __future__ import annotations
|
|
|
|
from typing import Any, Dict
|
|
|
|
from ..core.reply_formatter import preview_text
|
|
|
|
|
|
def build_log_summary(event: str, data: Dict[str, Any]) -> str:
|
|
room = short_id(data.get("room_id", ""))
|
|
sender_name = data.get("sender_name", "") or short_id(data.get("sender", ""))
|
|
sender = short_id(data.get("sender", ""))
|
|
|
|
if event == "recv":
|
|
return (
|
|
f"[XIAONIU] RECV room={room} user={sender_name}/{sender} "
|
|
f"at={yn(data.get('is_at'))} "
|
|
f"style={style_mark(data.get('humor_style', ''), data.get('sharpness_style', ''))} "
|
|
f"quote={data.get('quote_type', '-') or '-'} "
|
|
f"msg={data.get('content_preview', '')}"
|
|
).strip()
|
|
|
|
if event == "memory":
|
|
return (
|
|
f"[XIAONIU] MEMORY room={room} user={sender} "
|
|
f"ctx={yn(data.get('has_member_context'))} "
|
|
f"follow={yn(data.get('is_followup'))} "
|
|
f"return={data.get('returning_state', 'none')} "
|
|
f"links={data.get('social_links', 0)} "
|
|
f"facts={data.get('group_facts', 0)}"
|
|
).strip()
|
|
|
|
if event == "decision":
|
|
return (
|
|
f"[XIAONIU] DECIDE room={room} user={sender} "
|
|
f"trigger={data.get('trigger_type', 'none')} "
|
|
f"dir={data.get('directed', '-') or '-'} "
|
|
f"flow={data.get('flow_state', '')}:{data.get('flow_score', '')} "
|
|
f"topic={data.get('topic', '-') or '-'} "
|
|
f"reasons={data.get('reasons', '-') or '-'}"
|
|
).strip()
|
|
|
|
if event == "skip":
|
|
age_text = ""
|
|
if data.get("age_sec") not in (None, ""):
|
|
age_text = f" age={data.get('age_sec')}"
|
|
return (
|
|
f"[XIAONIU] SKIP room={room} user={sender} "
|
|
f"reason={data.get('reason', '')} "
|
|
f"trigger={data.get('trigger_type', 'none')} "
|
|
f"mode={data.get('reply_mode', '')} "
|
|
f"topic={data.get('topic', '-') or '-'} "
|
|
f"acc={data.get('acceptance_state', '-') or '-'} "
|
|
f"solver={data.get('solver', '-') or '-'}"
|
|
f"{age_text}"
|
|
).strip()
|
|
|
|
if event == "context":
|
|
return (
|
|
f"[XIAONIU] CTX room={room} user={sender} "
|
|
f"mode={data.get('reply_mode', '')} "
|
|
f"acc={data.get('acceptance_state', '-') or '-'} "
|
|
f"recent={data.get('recent_message_count', 0)} "
|
|
f"vector={data.get('vector_hit_count', 0)} "
|
|
f"mem={data.get('member_focus_count', 0)} "
|
|
f"social={data.get('social_hit_count', 0)} "
|
|
f"facts={data.get('group_fact_hit_count', 0)} "
|
|
f"img={data.get('image_input_count', 0)} "
|
|
f"rank={preview_text(str(data.get('memory_rank_summary', '') or '-'), 108)}"
|
|
).strip()
|
|
|
|
if event == "model_empty":
|
|
return (
|
|
f"[XIAONIU] MODEL_EMPTY room={room} user={sender} "
|
|
f"model={data.get('model', '')} "
|
|
f"mode={data.get('reply_mode', '')} "
|
|
f"err={data.get('last_error', '')}"
|
|
).strip()
|
|
|
|
if event == "sent":
|
|
return (
|
|
f"[XIAONIU] SENT room={room} user={sender_name}/{sender} "
|
|
f"trigger={data.get('trigger_type', 'none')} "
|
|
f"mode={data.get('reply_mode', '')} "
|
|
f"topic={data.get('topic', '-') or '-'} "
|
|
f"chunks={data.get('chunk_count', 1)} "
|
|
f"len={data.get('response_len', 0)} "
|
|
f"reply={data.get('response_preview', '')}"
|
|
).strip()
|
|
|
|
if event == "memory_upsert":
|
|
return (
|
|
f"[XIAONIU] MEM_UPSERT room={room} user={sender} "
|
|
f"type={data.get('memory_type', '')} "
|
|
f"ok={yn(data.get('ok'))} "
|
|
f"trigger={data.get('trigger_type', '-') or '-'} "
|
|
f"err={preview_text(str(data.get('error', '') or '-'), 72)}"
|
|
).strip()
|
|
|
|
compact = " ".join(f"{key}={data[key]}" for key in sorted(data) if data.get(key) not in (None, ""))
|
|
return f"[XIAONIU] {event.upper()} {compact}".strip()
|
|
|
|
|
|
def yn(value: Any) -> str:
|
|
return "Y" if bool(value) else "N"
|
|
|
|
|
|
def short_id(value: str) -> str:
|
|
value = str(value or "")
|
|
if len(value) <= 10:
|
|
return value
|
|
return value[:4] + "..." + value[-4:]
|
|
|
|
|
|
def style_mark(humor_style: str, sharpness_style: str) -> str:
|
|
humor = "humor" if "中等" in str(humor_style) or "偏上" in str(humor_style) else "plain"
|
|
sharp = "sharp" if "毒舌" in str(sharpness_style) or "嘴欠" in str(sharpness_style) else "soft"
|
|
return f"{humor}/{sharp}"
|