refactor(chat): 重构消息兴趣度计算与动作记录机制

重构聊天系统以使用集中式消息管理API,移除ChatMessageContext类,将兴趣度计算和动作记录功能整合到StreamContext中。

主要变更:
- 移除ChatMessageContext类,使用StreamContext统一管理消息上下文
- 在DatabaseMessages模型中添加interest_degree、actions、should_reply字段
- 实现消息管理器API用于更新消息信息和刷新focus_energy
- 重构ChatStream的focus_energy计算逻辑,基于StreamContext历史消息
- 在动作管理器中添加动作记录功能,确保动作执行后更新消息状态

BREAKING CHANGE: ChatMessageContext类已被移除,相关功能需使用StreamContext API替代
This commit is contained in:
Windpicker-owo
2025-09-26 13:56:43 +08:00
parent bcea1a93c1
commit bbbf543078
7 changed files with 364 additions and 181 deletions

View File

@@ -89,6 +89,18 @@ class MessageManager:
logger.debug(f"添加消息到聊天流 {stream_id}: {message.message_id}")
def update_message_and_refresh_energy(self, stream_id: str, message_id: str, interest_degree: float = None, actions: list = None, should_reply: bool = None):
"""更新消息信息"""
if stream_id in self.stream_contexts:
context = self.stream_contexts[stream_id]
context.update_message_info(message_id, interest_degree, actions, should_reply)
def add_action_and_refresh_energy(self, stream_id: str, message_id: str, action: str):
"""添加动作到消息"""
if stream_id in self.stream_contexts:
context = self.stream_contexts[stream_id]
context.add_action_to_message(message_id, action)
async def _manager_loop(self):
"""管理器主循环 - 独立聊天流分发周期版本"""
while self.is_running:
@@ -296,72 +308,6 @@ class MessageManager:
else:
logger.debug(f"聊天流 {stream_id} 未触发打断,打断概率: {interruption_probability:.2f}")
def _calculate_dynamic_distribution_interval(self) -> float:
"""根据所有活跃聊天流的focus_energy动态计算分发周期"""
if not global_config.chat.dynamic_distribution_enabled:
return self.check_interval # 使用固定间隔
if not self.stream_contexts:
return self.check_interval # 默认间隔
# 计算活跃流的平均focus_energy
active_streams = [ctx for ctx in self.stream_contexts.values() if ctx.is_active]
if not active_streams:
return self.check_interval
total_focus_energy = 0.0
max_focus_energy = 0.0
stream_count = 0
for context in active_streams:
from src.plugin_system.apis.chat_api import get_chat_manager
chat_stream = get_chat_manager().get_stream(context.stream_id)
if chat_stream:
focus_energy = chat_stream.focus_energy
total_focus_energy += focus_energy
max_focus_energy = max(max_focus_energy, focus_energy)
stream_count += 1
if stream_count == 0:
return self.check_interval
avg_focus_energy = total_focus_energy / stream_count
# 使用配置参数
base_interval = global_config.chat.dynamic_distribution_base_interval
min_interval = global_config.chat.dynamic_distribution_min_interval
max_interval = global_config.chat.dynamic_distribution_max_interval
jitter_factor = global_config.chat.dynamic_distribution_jitter_factor
# 根据平均兴趣度调整间隔
# 高兴趣度 -> 更频繁检查 (间隔更短)
# 低兴趣度 -> 较少检查 (间隔更长)
if avg_focus_energy >= 0.7:
# 高兴趣度1-5秒
interval = base_interval * (1.0 - (avg_focus_energy - 0.7) * 2.0)
elif avg_focus_energy >= 0.4:
# 中等兴趣度5-15秒
interval = base_interval * (1.0 + (avg_focus_energy - 0.4) * 3.33)
else:
# 低兴趣度15-30秒
interval = base_interval * (3.0 + (0.4 - avg_focus_energy) * 5.0)
# 添加随机扰动避免同步
import random
jitter = random.uniform(1.0 - jitter_factor, 1.0 + jitter_factor)
final_interval = interval * jitter
# 限制在合理范围内
final_interval = max(min_interval, min(max_interval, final_interval))
logger.debug(
f"动态分发周期: {final_interval:.2f}s | "
f"平均兴趣度: {avg_focus_energy:.3f} | "
f"活跃流数: {stream_count}"
)
return final_interval
def _calculate_stream_distribution_interval(self, context: StreamContext) -> float:
"""计算单个聊天流的分发周期 - 基于阈值感知的focus_energy"""
if not global_config.chat.dynamic_distribution_enabled:

View File

@@ -25,43 +25,6 @@ install(extra_lines=3)
logger = get_logger("chat_stream")
class ChatMessageContext:
"""聊天消息上下文,存储消息的上下文信息"""
def __init__(self, message: "MessageRecv"):
self.message = message
def get_template_name(self) -> Optional[str]:
"""获取模板名称"""
if self.message.message_info.template_info and not self.message.message_info.template_info.template_default:
return self.message.message_info.template_info.template_name # type: ignore
return None
def get_last_message(self) -> "MessageRecv":
"""获取最后一条消息"""
return self.message
def check_types(self, types: list) -> bool:
# sourcery skip: invert-any-all, use-any, use-next
"""检查消息类型"""
if not self.message.message_info.format_info.accept_format: # type: ignore
return False
for t in types:
if t not in self.message.message_info.format_info.accept_format: # type: ignore
return False
return True
def get_priority_mode(self) -> str:
"""获取优先级模式"""
return self.message.priority_mode
def get_priority_info(self) -> Optional[dict]:
"""获取优先级信息"""
if hasattr(self.message, "priority_info") and self.message.priority_info:
return self.message.priority_info
return None
class ChatStream:
"""聊天流对象,存储一个完整的聊天上下文"""
@@ -79,24 +42,23 @@ class ChatStream:
self.group_info = group_info
self.create_time = data.get("create_time", time.time()) if data else time.time()
self.last_active_time = data.get("last_active_time", self.create_time) if data else self.create_time
self.energy_value = data.get("energy_value", 5.0) if data else 5.0
self.sleep_pressure = data.get("sleep_pressure", 0.0) if data else 0.0
self.saved = False
self.context: ChatMessageContext = None # type: ignore # 用于存储该聊天的上下文信息
# 动态兴趣度系统 - 重构后的focus_energy
self.base_interest_energy = data.get("base_interest_energy", 0.5) if data else 0.5
self.message_interest_total = data.get("message_interest_total", 0.0) if data else 0.0
self.message_count = data.get("message_count", 0) if data else 0
self.action_count = data.get("action_count", 0) if data else 0
self.reply_count = data.get("reply_count", 0) if data else 0
self.last_interaction_time = data.get("last_interaction_time", time.time()) if data else time.time()
self.consecutive_no_reply = data.get("consecutive_no_reply", 0) if data else 0
# 使用StreamContext替代ChatMessageContext
from src.common.data_models.message_manager_data_model import StreamContext
from src.plugin_system.base.component_types import ChatType, ChatMode
self.stream_context: StreamContext = StreamContext(
stream_id=stream_id,
chat_type=ChatType.GROUP if group_info else ChatType.PRIVATE,
chat_mode=ChatMode.NORMAL
)
# 计算动态focus_energy
self.focus_energy = self._calculate_dynamic_focus_energy()
# 基础参数
self.base_interest_energy = 0.5 # 默认基础兴趣度
self._focus_energy = 0.5 # 内部存储的focus_energy值
self.no_reply_consecutive = 0
self.breaking_accumulated_interest = 0.0
def to_dict(self) -> dict:
"""转换为字典格式"""
@@ -107,18 +69,13 @@ class ChatStream:
"group_info": self.group_info.to_dict() if self.group_info else None,
"create_time": self.create_time,
"last_active_time": self.last_active_time,
"energy_value": self.energy_value,
"sleep_pressure": self.sleep_pressure,
"focus_energy": self.focus_energy,
"breaking_accumulated_interest": self.breaking_accumulated_interest,
# 新增动态兴趣度系统字段
# 基础兴趣度
"base_interest_energy": self.base_interest_energy,
"message_interest_total": self.message_interest_total,
"message_count": self.message_count,
"action_count": self.action_count,
"reply_count": self.reply_count,
"last_interaction_time": self.last_interaction_time,
"consecutive_no_reply": self.consecutive_no_reply,
# 新增stream_context信息
"stream_context_chat_type": self.stream_context.chat_type.value,
"stream_context_chat_mode": self.stream_context.chat_mode.value,
}
@classmethod
@@ -127,7 +84,7 @@ class ChatStream:
user_info = UserInfo.from_dict(data.get("user_info", {})) if data.get("user_info") else None
group_info = GroupInfo.from_dict(data.get("group_info", {})) if data.get("group_info") else None
return cls(
instance = cls(
stream_id=data["stream_id"],
platform=data["platform"],
user_info=user_info, # type: ignore
@@ -135,6 +92,16 @@ class ChatStream:
data=data,
)
# 恢复stream_context信息
if "stream_context_chat_type" in data:
from src.plugin_system.base.component_types import ChatType, ChatMode
instance.stream_context.chat_type = ChatType(data["stream_context_chat_type"])
if "stream_context_chat_mode" in data:
from src.plugin_system.base.component_types import ChatType, ChatMode
instance.stream_context.chat_mode = ChatMode(data["stream_context_chat_mode"])
return instance
def update_active_time(self):
"""更新最后活跃时间"""
self.last_active_time = time.time()
@@ -142,32 +109,91 @@ class ChatStream:
def set_context(self, message: "MessageRecv"):
"""设置聊天消息上下文"""
self.context = ChatMessageContext(message)
# 将MessageRecv转换为DatabaseMessages并设置到stream_context
from src.common.data_models.database_data_model import DatabaseMessages
# 简化转换,实际可能需要更完整的转换逻辑
db_message = DatabaseMessages(
message_id=getattr(message, 'message_id', ''),
time=getattr(message, 'time', time.time()),
chat_id=getattr(message, 'chat_id', ''),
user_id=str(getattr(message.message_info, 'user_info', {}).user_id) if hasattr(message, 'message_info') and hasattr(message.message_info, 'user_info') else '',
user_nickname=getattr(message.message_info, 'user_info', {}).user_nickname if hasattr(message, 'message_info') and hasattr(message.message_info, 'user_info') else '',
user_platform=getattr(message.message_info, 'user_info', {}).platform if hasattr(message, 'message_info') and hasattr(message.message_info, 'user_info') else '',
priority_mode=getattr(message, 'priority_mode', None),
priority_info=str(getattr(message, 'priority_info', None)) if hasattr(message, 'priority_info') and message.priority_info else None,
)
self.stream_context.set_current_message(db_message)
self.stream_context.priority_mode = getattr(message, 'priority_mode', None)
self.stream_context.priority_info = getattr(message, 'priority_info', None)
@property
def focus_energy(self) -> float:
"""动态计算的聊天流总体兴趣度,访问时自动更新"""
self._focus_energy = self._calculate_dynamic_focus_energy()
return self._focus_energy
@focus_energy.setter
def focus_energy(self, value: float):
"""设置focus_energy值主要用于初始化或特殊场景"""
self._focus_energy = max(0.0, min(1.0, value))
def _calculate_dynamic_focus_energy(self) -> float:
"""动态计算聊天流的总体兴趣度"""
"""动态计算聊天流的总体兴趣度使用StreamContext历史消息"""
try:
# 基础分:平均消息兴趣度
avg_message_interest = self.message_interest_total / max(self.message_count, 1)
# 从StreamContext获取历史消息计算统计数据
history_messages = self.stream_context.get_history_messages(limit=global_config.chat.max_context_size)
unread_messages = self.stream_context.get_unread_messages()
all_messages = history_messages + unread_messages
# 动作参与度:动作执行率
action_rate = self.action_count / max(self.message_count, 1)
# 计算基于历史消息的统计数据
if all_messages:
# 基础分:平均消息兴趣度
message_interests = [msg.interest_degree for msg in all_messages if hasattr(msg, 'interest_degree')]
avg_message_interest = sum(message_interests) / len(message_interests) if message_interests else 0.3
# 回复活跃度:回复率
reply_rate = self.reply_count / max(self.message_count, 1)
# 动作参与度:有动作的消息比例
messages_with_actions = [msg for msg in all_messages if hasattr(msg, 'actions') and msg.actions]
action_rate = len(messages_with_actions) / len(all_messages)
# 回复活跃度:应该回复且已回复的消息比例
should_reply_messages = [msg for msg in all_messages if hasattr(msg, 'should_reply') and msg.should_reply]
replied_messages = [msg for msg in should_reply_messages if hasattr(msg, 'actions') and 'reply' in (msg.actions or [])]
reply_rate = len(replied_messages) / len(should_reply_messages) if should_reply_messages else 0.0
# 获取最后交互时间
if all_messages:
self.last_interaction_time = max(msg.time for msg in all_messages)
# 连续无回复计算:从最近的未回复消息计数
consecutive_no_reply = 0
for msg in reversed(all_messages):
if hasattr(msg, 'should_reply') and msg.should_reply:
if not (hasattr(msg, 'actions') and 'reply' in (msg.actions or [])):
consecutive_no_reply += 1
else:
break
else:
# 没有历史消息时的默认值
avg_message_interest = 0.3
action_rate = 0.0
reply_rate = 0.0
consecutive_no_reply = 0
self.last_interaction_time = time.time()
# 获取用户关系分(对于私聊,群聊无效)
relationship_factor = self._get_user_relationship_score()
# 时间衰减因子:最近活跃度
current_time = time.time()
if not self.last_interaction_time:
if not hasattr(self, 'last_interaction_time') or not self.last_interaction_time:
self.last_interaction_time = current_time
time_since_interaction = current_time - self.last_interaction_time
time_decay = max(0.3, 1.0 - min(time_since_interaction / (7 * 24 * 3600), 0.7)) # 7天衰减
# 连续无回复惩罚
no_reply_penalty = max(0.1, 1.0 - self.consecutive_no_reply * 0.1)
no_reply_penalty = max(0.1, 1.0 - consecutive_no_reply * 0.1)
# 获取AFC系统阈值添加None值检查
reply_threshold = getattr(global_config.affinity_flow, 'reply_action_interest_threshold', 0.4)
@@ -250,45 +276,8 @@ class ChatStream:
# 默认基础分
return 0.3
def add_message_interest(self, interest_score: float):
"""添加消息兴趣值并更新focus_energy"""
self.message_interest_total += interest_score
self.message_count += 1
self.last_interaction_time = time.time()
self.focus_energy = self._calculate_dynamic_focus_energy()
def update_focus_energy(self):
"""手动触发更新focus_energy"""
self.focus_energy = self._calculate_dynamic_focus_energy()
def record_action(self, is_reply: bool = False):
"""记录动作执行"""
self.action_count += 1
if is_reply:
self.reply_count += 1
self.consecutive_no_reply = max(0, self.consecutive_no_reply - 1)
self.last_interaction_time = time.time()
self.focus_energy = self._calculate_dynamic_focus_energy()
def record_no_reply(self):
"""记录无回复动作"""
self.consecutive_no_reply += 1
self.last_interaction_time = time.time()
self.focus_energy = self._calculate_dynamic_focus_energy()
def get_adjusted_focus_energy(self) -> float:
"""获取应用了afc调整的focus_energy"""
try:
from src.chat.message_manager.message_manager import message_manager
if self.stream_id in message_manager.stream_contexts:
context = message_manager.stream_contexts[self.stream_id]
afc_adjustment = context.get_afc_threshold_adjustment()
# 对动态计算的focus_energy应用AFC调整
adjusted_energy = max(0.0, self.focus_energy - afc_adjustment)
return adjusted_energy
except Exception:
pass
return self.focus_energy
class ChatManager:

View File

@@ -1,7 +1,6 @@
import asyncio
import traceback
import time
import random
from typing import Dict, Optional, Type, Any, Tuple
@@ -210,8 +209,10 @@ class ChatterActionManager:
target_message,
)
# 如果动作执行成功且不是no_action重置打断计数
# 记录执行的动作到目标消息
if success:
await self._record_action_to_message(chat_stream, action_name, target_message, action_data)
# 重置打断计数
await self._reset_interruption_count_after_action(chat_stream.stream_id)
return {
@@ -252,6 +253,9 @@ class ChatterActionManager:
[], # actions
)
# 记录回复动作到目标消息
await self._record_action_to_message(chat_stream, "reply", target_message, action_data)
# 回复成功,重置打断计数
await self._reset_interruption_count_after_action(chat_stream.stream_id)
@@ -268,6 +272,45 @@ class ChatterActionManager:
"error": str(e),
}
async def _record_action_to_message(self, chat_stream, action_name, target_message, action_data):
"""
记录执行的动作到目标消息中
Args:
chat_stream: ChatStream实例
action_name: 动作名称
target_message: 目标消息
action_data: 动作数据
"""
try:
from src.chat.message_manager.message_manager import message_manager
# 获取目标消息ID
target_message_id = None
if target_message and isinstance(target_message, dict):
target_message_id = target_message.get("message_id")
elif action_data and isinstance(action_data, dict):
target_message_id = action_data.get("target_message_id")
if not target_message_id:
logger.debug(f"无法获取目标消息ID动作: {action_name}")
return
# 通过message_manager更新消息的动作记录并刷新focus_energy
if chat_stream.stream_id in message_manager.stream_contexts:
message_manager.add_action_and_refresh_energy(
stream_id=chat_stream.stream_id,
message_id=target_message_id,
action=action_name
)
logger.debug(f"已记录动作 {action_name} 到消息 {target_message_id} 并更新focus_energy")
else:
logger.debug(f"未找到stream_context: {chat_stream.stream_id}")
except Exception as e:
logger.error(f"记录动作到消息失败: {e}")
# 不抛出异常,避免影响主要功能
async def _reset_interruption_count_after_action(self, stream_id: str):
"""在动作执行成功后重置打断计数"""
from src.chat.message_manager.message_manager import message_manager

View File

@@ -7,7 +7,8 @@ from typing import List, Any, Dict, TYPE_CHECKING, Tuple
from src.common.logger import get_logger
from src.config.config import global_config, model_config
from src.llm_models.utils_model import LLMRequest
from src.chat.message_receive.chat_stream import get_chat_manager, ChatMessageContext
from src.chat.message_receive.chat_stream import get_chat_manager
from src.common.data_models.message_manager_data_model import StreamContext
from src.chat.planner_actions.action_manager import ChatterActionManager
from src.chat.utils.chat_message_builder import get_raw_msg_before_timestamp_with_chat, build_readable_messages
from src.plugin_system.base.component_types import ActionInfo, ActionActivationType
@@ -124,7 +125,7 @@ class ActionModifier:
logger.debug(f"{self.log_prefix}阶段一移除动作: {disabled_action_name},原因: 用户自行禁用")
# === 第二阶段:检查动作的关联类型 ===
chat_context = self.chat_stream.context
chat_context = self.chat_stream.stream_context
current_actions_s2 = self.action_manager.get_using_actions()
type_mismatched_actions = self._check_action_associated_types(current_actions_s2, chat_context)
@@ -166,7 +167,7 @@ class ActionModifier:
logger.info(f"{self.log_prefix} 当前可用动作: {available_actions_text}||移除: {removals_summary}")
def _check_action_associated_types(self, all_actions: Dict[str, ActionInfo], chat_context: ChatMessageContext):
def _check_action_associated_types(self, all_actions: Dict[str, ActionInfo], chat_context: StreamContext):
type_mismatched_actions: List[Tuple[str, str]] = []
for action_name, action_info in all_actions.items():
if action_info.associated_types and not chat_context.check_types(action_info.associated_types):

View File

@@ -95,6 +95,10 @@ class DatabaseMessages(BaseDataModel):
chat_info_platform: str = "",
chat_info_create_time: float = 0.0,
chat_info_last_active_time: float = 0.0,
# 新增字段
interest_degree: float = 0.0,
actions: Optional[list] = None,
should_reply: bool = False,
**kwargs: Any,
):
self.message_id = message_id
@@ -103,6 +107,11 @@ class DatabaseMessages(BaseDataModel):
self.reply_to = reply_to
self.interest_value = interest_value
# 新增字段
self.interest_degree = interest_degree
self.actions = actions
self.should_reply = should_reply
self.key_words = key_words
self.key_words_lite = key_words_lite
self.is_mentioned = is_mentioned
@@ -191,6 +200,10 @@ class DatabaseMessages(BaseDataModel):
"is_notify": self.is_notify,
"selected_expressions": self.selected_expressions,
"is_read": self.is_read,
# 新增字段
"interest_degree": self.interest_degree,
"actions": self.actions,
"should_reply": self.should_reply,
"user_id": self.user_info.user_id,
"user_nickname": self.user_info.user_nickname,
"user_cardname": self.user_info.user_cardname,
@@ -208,6 +221,60 @@ class DatabaseMessages(BaseDataModel):
"chat_info_user_cardname": self.chat_info.user_info.user_cardname,
}
def update_message_info(self, interest_degree: float = None, actions: list = None, should_reply: bool = None):
"""
更新消息信息
Args:
interest_degree: 兴趣度值
actions: 执行的动作列表
should_reply: 是否应该回复
"""
if interest_degree is not None:
self.interest_degree = interest_degree
if actions is not None:
self.actions = actions
if should_reply is not None:
self.should_reply = should_reply
def add_action(self, action: str):
"""
添加执行的动作到消息中
Args:
action: 要添加的动作名称
"""
if self.actions is None:
self.actions = []
if action not in self.actions: # 避免重复添加
self.actions.append(action)
def get_actions(self) -> list:
"""
获取执行的动作列表
Returns:
动作列表,如果没有动作则返回空列表
"""
return self.actions or []
def get_message_summary(self) -> Dict[str, Any]:
"""
获取消息摘要信息
Returns:
包含关键字段的消息摘要
"""
return {
"message_id": self.message_id,
"time": self.time,
"interest_degree": self.interest_degree,
"actions": self.actions,
"should_reply": self.should_reply,
"user_nickname": self.user_info.user_nickname,
"display_message": self.display_message,
}
@dataclass(init=False)
class DatabaseActionRecords(BaseDataModel):

View File

@@ -47,6 +47,11 @@ class StreamContext(BaseDataModel):
next_check_time: float = field(default_factory=time.time) # 下次检查时间
distribution_interval: float = 5.0 # 当前分发周期(秒)
# 新增字段以替代ChatMessageContext功能
current_message: Optional["DatabaseMessages"] = None
priority_mode: Optional[str] = None
priority_info: Optional[dict] = None
def add_message(self, message: "DatabaseMessages"):
"""添加消息到上下文"""
message.is_read = False
@@ -55,6 +60,48 @@ class StreamContext(BaseDataModel):
# 自动检测和更新chat type
self._detect_chat_type(message)
def update_message_info(self, message_id: str, interest_degree: float = None, actions: list = None, should_reply: bool = None):
"""
更新消息信息
Args:
message_id: 消息ID
interest_degree: 兴趣度值
actions: 执行的动作列表
should_reply: 是否应该回复
"""
# 在未读消息中查找并更新
for message in self.unread_messages:
if message.message_id == message_id:
message.update_message_info(interest_degree, actions, should_reply)
break
# 在历史消息中查找并更新
for message in self.history_messages:
if message.message_id == message_id:
message.update_message_info(interest_degree, actions, should_reply)
break
def add_action_to_message(self, message_id: str, action: str):
"""
向指定消息添加执行的动作
Args:
message_id: 消息ID
action: 要添加的动作名称
"""
# 在未读消息中查找并更新
for message in self.unread_messages:
if message.message_id == message_id:
message.add_action(action)
break
# 在历史消息中查找并更新
for message in self.history_messages:
if message.message_id == message_id:
message.add_action(action)
break
def _detect_chat_type(self, message: "DatabaseMessages"):
"""根据消息内容自动检测聊天类型"""
# 只有在第一次添加消息时才检测聊天类型,避免后续消息改变类型
@@ -150,6 +197,61 @@ class StreamContext(BaseDataModel):
"""获取当前的afc阈值调整量"""
return self.afc_threshold_adjustment
def set_current_message(self, message: "DatabaseMessages"):
"""设置当前消息"""
self.current_message = message
def get_template_name(self) -> Optional[str]:
"""获取模板名称"""
if self.current_message and hasattr(self.current_message, 'additional_config') and self.current_message.additional_config:
try:
import json
config = json.loads(self.current_message.additional_config)
if config.get('template_info') and not config.get('template_default', True):
return config.get('template_name')
except (json.JSONDecodeError, AttributeError):
pass
return None
def get_last_message(self) -> Optional["DatabaseMessages"]:
"""获取最后一条消息"""
if self.current_message:
return self.current_message
if self.unread_messages:
return self.unread_messages[-1]
if self.history_messages:
return self.history_messages[-1]
return None
def check_types(self, types: list) -> bool:
"""检查消息类型"""
if not self.current_message:
return False
# 检查消息是否支持指定的类型
# 这里简化处理,实际应该根据消息的格式信息检查
if hasattr(self.current_message, 'additional_config') and self.current_message.additional_config:
try:
import json
config = json.loads(self.current_message.additional_config)
if 'format_info' in config and 'accept_format' in config['format_info']:
accept_format = config['format_info']['accept_format']
for t in types:
if t not in accept_format:
return False
return True
except (json.JSONDecodeError, AttributeError):
pass
return False
def get_priority_mode(self) -> Optional[str]:
"""获取优先级模式"""
return self.priority_mode
def get_priority_info(self) -> Optional[dict]:
"""获取优先级信息"""
return self.priority_info
@dataclass
class MessageManagerStats(BaseDataModel):

View File

@@ -128,7 +128,6 @@ class ChatterActionPlanner:
# 更新ChatStream的兴趣度数据
from src.plugin_system.apis.chat_api import get_chat_manager
chat_stream = get_chat_manager().get_stream(self.chat_id)
chat_stream.add_message_interest(score)
logger.debug(f"已更新聊天 {self.chat_id} 的ChatStream兴趣度分数: {score:.3f}")
# 更新情绪状态和ChatStream兴趣度数据
@@ -137,6 +136,39 @@ class ChatterActionPlanner:
await chat_mood.update_mood_by_message(latest_message, score)
logger.debug(f"已更新聊天 {self.chat_id} 的情绪状态,兴趣度: {score:.3f}")
# 为所有未读消息记录兴趣度信息
for message in unread_messages:
# 查找对应的兴趣度评分
message_score = next((s for s in interest_scores if s.message_id == message.message_id), None)
if message_score:
message.interest_degree = message_score.total_score
message.should_reply = self.interest_scoring.should_reply(message_score, message)[0]
logger.debug(f"已记录消息 {message.message_id} - 兴趣度: {message_score.total_score:.3f}, 应回复: {message.should_reply}")
# 更新StreamContext中的消息信息并刷新focus_energy
if context:
from src.chat.message_manager.message_manager import message_manager
message_manager.update_message_and_refresh_energy(
stream_id=self.chat_id,
message_id=message.message_id,
interest_degree=message_score.total_score,
should_reply=message.should_reply
)
else:
# 如果没有找到评分,设置默认值
message.interest_degree = 0.0
message.should_reply = False
# 更新StreamContext中的消息信息并刷新focus_energy
if context:
from src.chat.message_manager.message_manager import message_manager
message_manager.update_message_and_refresh_energy(
stream_id=self.chat_id,
message_id=message.message_id,
interest_degree=0.0,
should_reply=False
)
# base_threshold = self.interest_scoring.reply_threshold
# 检查兴趣度是否达到非回复动作阈值
non_reply_action_interest_threshold = global_config.affinity_flow.non_reply_action_interest_threshold
@@ -169,10 +201,13 @@ class ChatterActionPlanner:
# 5. 使用 PlanExecutor 执行 Plan
execution_result = await self.executor.execute(filtered_plan)
# 6. 根据执行结果更新统计信息
# 6. 动作记录现在由ChatterActionManager统一处理
# 动作记录逻辑已移至ChatterActionManager.execute_action方法中
# 7. 根据执行结果更新统计信息
self._update_stats_from_execution_result(execution_result)
# 7. 检查关系更新
# 8. 检查关系更新
await self.relationship_tracker.check_and_update_relationships()
# 8. 返回结果