diff --git a/src/api/apiforgui.py b/src/api/apiforgui.py index 41313dc73..853e8b49b 100644 --- a/src/api/apiforgui.py +++ b/src/api/apiforgui.py @@ -33,11 +33,11 @@ async def get_subheartflow_cycle_info(subheartflow_id: str, history_len: int) -> async def get_normal_chat_replies(subheartflow_id: str, limit: int = 10) -> list: """获取子心流的NormalChat回复记录 - + Args: subheartflow_id: 子心流ID limit: 最大返回数量,默认10条 - + Returns: list: 回复记录列表,如果未找到则返回空列表 """ diff --git a/src/chat/focus_chat/expressors/default_expressor.py b/src/chat/focus_chat/expressors/default_expressor.py index e0da80193..befe045e8 100644 --- a/src/chat/focus_chat/expressors/default_expressor.py +++ b/src/chat/focus_chat/expressors/default_expressor.py @@ -13,7 +13,6 @@ from src.chat.emoji_system.emoji_manager import emoji_manager from src.chat.focus_chat.heartFC_sender import HeartFCSender from src.chat.utils.utils import process_llm_response from src.chat.utils.info_catcher import info_catcher_manager -from src.manager.mood_manager import mood_manager from src.chat.heart_flow.utils_chat import get_chat_type_and_target_info from src.chat.message_receive.chat_stream import ChatStream from src.chat.focus_chat.hfc_utils import parse_thinking_id_to_timestamp @@ -150,22 +149,22 @@ class DefaultExpressor: action_data=action_data, ) - with Timer("选择表情", cycle_timers): - emoji_keyword = action_data.get("emojis", []) - emoji_base64 = await self._choose_emoji(emoji_keyword) - if emoji_base64: - reply.append(("emoji", emoji_base64)) + with Timer("选择表情", cycle_timers): + emoji_keyword = action_data.get("emojis", []) + emoji_base64 = await self._choose_emoji(emoji_keyword) + if emoji_base64: + reply.append(("emoji", emoji_base64)) - if reply: - with Timer("发送消息", cycle_timers): - sent_msg_list = await self.send_response_messages( - anchor_message=anchor_message, - thinking_id=thinking_id, - response_set=reply, - ) - has_sent_something = True - else: - logger.warning(f"{self.log_prefix} 文本回复生成失败") + if reply: + with Timer("发送消息", cycle_timers): + sent_msg_list = await self.send_response_messages( + anchor_message=anchor_message, + thinking_id=thinking_id, + response_set=reply, + ) + has_sent_something = True + else: + logger.warning(f"{self.log_prefix} 文本回复生成失败") if not has_sent_something: logger.warning(f"{self.log_prefix} 回复动作未包含任何有效内容") @@ -174,6 +173,7 @@ class DefaultExpressor: except Exception as e: logger.error(f"回复失败: {e}") + traceback.print_exc() return False, None # --- 回复器 (Replier) 的定义 --- # @@ -443,7 +443,9 @@ class DefaultExpressor: set_reply = True else: set_reply = False - sent_msg = await self.heart_fc_sender.send_message(bot_message, has_thinking=True, typing=typing, set_reply=set_reply) + sent_msg = await self.heart_fc_sender.send_message( + bot_message, has_thinking=True, typing=typing, set_reply=set_reply + ) reply_message_ids.append(part_message_id) # 记录我们生成的ID diff --git a/src/chat/focus_chat/heartFC_chat.py b/src/chat/focus_chat/heartFC_chat.py index d989fb5e6..6e8beebe7 100644 --- a/src/chat/focus_chat/heartFC_chat.py +++ b/src/chat/focus_chat/heartFC_chat.py @@ -3,7 +3,7 @@ import contextlib import time import traceback from collections import deque -from typing import List, Optional, Dict, Any, Deque +from typing import List, Optional, Dict, Any, Deque, Callable, Awaitable from src.chat.message_receive.chat_stream import ChatStream from src.chat.message_receive.chat_stream import chat_manager from rich.traceback import install @@ -84,6 +84,7 @@ class HeartFChatting: self, chat_id: str, observations: list[Observation], + on_stop_focus_chat: Optional[Callable[[], Awaitable[None]]] = None, ): """ HeartFChatting 初始化函数 @@ -91,6 +92,7 @@ class HeartFChatting: 参数: chat_id: 聊天流唯一标识符(如stream_id) observations: 关联的观察列表 + on_stop_focus_chat: 当收到stop_focus_chat命令时调用的回调函数 """ # 基础属性 self.stream_id: str = chat_id # 聊天流ID @@ -143,6 +145,9 @@ class HeartFChatting: self._current_cycle: Optional[CycleDetail] = None self._shutting_down: bool = False # 关闭标志位 + # 存储回调函数 + self.on_stop_focus_chat = on_stop_focus_chat + async def _initialize(self) -> bool: """ 执行懒初始化操作 @@ -287,6 +292,19 @@ class HeartFChatting: async with global_prompt_manager.async_message_scope(self.chat_stream.context.get_template_name()): logger.debug(f"模板 {self.chat_stream.context.get_template_name()}") loop_info = await self._observe_process_plan_action_loop(cycle_timers, thinking_id) + + print(loop_info["loop_action_info"]["command"]) + if loop_info["loop_action_info"]["command"] == "stop_focus_chat": + logger.info(f"{self.log_prefix} 麦麦决定停止专注聊天") + # 如果设置了回调函数,则调用它 + if self.on_stop_focus_chat: + try: + await self.on_stop_focus_chat() + logger.info(f"{self.log_prefix} 成功调用回调函数处理停止专注聊天") + except Exception as e: + logger.error(f"{self.log_prefix} 调用停止专注聊天回调函数时出错: {e}") + logger.error(traceback.format_exc()) + break self._current_cycle.set_loop_info(loop_info) @@ -410,7 +428,7 @@ class HeartFChatting: return all_plan_info - async def _observe_process_plan_action_loop(self, cycle_timers: dict, thinking_id: str) -> tuple[bool, str]: + async def _observe_process_plan_action_loop(self, cycle_timers: dict, thinking_id: str) -> dict: try: with Timer("观察", cycle_timers): # await self.observations[0].observe() @@ -466,13 +484,14 @@ class HeartFChatting: logger.info(f"{self.log_prefix} 麦麦决定'{action_str}', 原因'{reasoning}'") - success, reply_text = await self._handle_action( + success, reply_text, command = await self._handle_action( action_type, reasoning, action_data, cycle_timers, thinking_id ) loop_action_info = { "action_taken": success, "reply_text": reply_text, + "command": command, } loop_info = { @@ -487,7 +506,12 @@ class HeartFChatting: except Exception as e: logger.error(f"{self.log_prefix} FOCUS聊天处理失败: {e}") logger.error(traceback.format_exc()) - return {} + return { + "loop_observation_info": {}, + "loop_processor_info": {}, + "loop_plan_info": {}, + "loop_action_info": {"action_taken": False, "reply_text": "", "command": ""}, + } async def _handle_action( self, @@ -496,7 +520,7 @@ class HeartFChatting: action_data: dict, cycle_timers: dict, thinking_id: str, - ) -> tuple[bool, str]: + ) -> tuple[bool, str, str]: """ 处理规划动作,使用动作工厂创建相应的动作处理器 @@ -508,36 +532,46 @@ class HeartFChatting: thinking_id: 思考ID 返回: - tuple[bool, str]: (是否执行了动作, 思考消息ID) + tuple[bool, str, str]: (是否执行了动作, 思考消息ID, 命令) """ try: # 使用工厂创建动作处理器实例 - action_handler = self.action_manager.create_action( - action_name=action, - action_data=action_data, - reasoning=reasoning, - cycle_timers=cycle_timers, - thinking_id=thinking_id, - observations=self.all_observations, - expressor=self.expressor, - chat_stream=self.chat_stream, - log_prefix=self.log_prefix, - shutting_down=self._shutting_down, - ) + try: + action_handler = self.action_manager.create_action( + action_name=action, + action_data=action_data, + reasoning=reasoning, + cycle_timers=cycle_timers, + thinking_id=thinking_id, + observations=self.all_observations, + expressor=self.expressor, + chat_stream=self.chat_stream, + log_prefix=self.log_prefix, + shutting_down=self._shutting_down, + ) + except Exception as e: + logger.error(f"{self.log_prefix} 创建动作处理器时出错: {e}") + traceback.print_exc() + return False, "", "" if not action_handler: logger.warning(f"{self.log_prefix} 未能创建动作处理器: {action}, 原因: {reasoning}") - return False, "" + return False, "", "" # 处理动作并获取结果 - success, reply_text = await action_handler.handle_action() - - return success, reply_text + result = await action_handler.handle_action() + if len(result) == 3: + success, reply_text, command = result + else: + success, reply_text = result + command = "" + logger.info(f"{self.log_prefix} 麦麦决定'{action}', 原因'{reasoning}',返回结果'{success}', '{reply_text}', '{command}'") + return success, reply_text, command except Exception as e: logger.error(f"{self.log_prefix} 处理{action}时出错: {e}") traceback.print_exc() - return False, "" + return False, "", "" async def shutdown(self): """优雅关闭HeartFChatting实例,取消活动循环任务""" diff --git a/src/chat/focus_chat/heartflow_message_processor.py b/src/chat/focus_chat/heartflow_message_processor.py index cbef9d5ef..c1efeb522 100644 --- a/src/chat/focus_chat/heartflow_message_processor.py +++ b/src/chat/focus_chat/heartflow_message_processor.py @@ -205,8 +205,8 @@ class HeartFCMessageReceiver: # 6. 兴趣度计算与更新 interested_rate, is_mentioned = await _calculate_interest(message) - await subheartflow.interest_chatting.increase_interest(value=interested_rate) - subheartflow.interest_chatting.add_interest_dict(message, interested_rate, is_mentioned) + # await subheartflow.interest_chatting.increase_interest(value=interested_rate) + subheartflow.add_interest_message(message, interested_rate, is_mentioned) # 7. 日志记录 mes_name = chat.group_info.group_name if chat.group_info else "私聊" diff --git a/src/chat/focus_chat/info/structured_info.py b/src/chat/focus_chat/info/structured_info.py index 616e942d2..a925a6d17 100644 --- a/src/chat/focus_chat/info/structured_info.py +++ b/src/chat/focus_chat/info/structured_info.py @@ -77,9 +77,8 @@ class StructuredInfo: info_str = "" # print(f"self.data: {self.data}") - + for key, value in self.data.items(): - # print(f"key: {key}, value: {value}") info_str += f"信息类型:{key},信息内容:{value}\n" diff --git a/src/chat/focus_chat/info_processors/action_processor.py b/src/chat/focus_chat/info_processors/action_processor.py index 1f05ac842..fe2d8675b 100644 --- a/src/chat/focus_chat/info_processors/action_processor.py +++ b/src/chat/focus_chat/info_processors/action_processor.py @@ -8,7 +8,6 @@ from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservati from src.chat.heart_flow.observation.chatting_observation import ChattingObservation from src.chat.message_receive.chat_stream import chat_manager from typing import Dict -from src.llm_models.utils_model import LLMRequest from src.config.config import global_config import random @@ -137,9 +136,11 @@ class ActionProcessor(BaseProcessor): reply_sequence.append(action_type == "reply") # 检查no_reply比例 - if len(recent_cycles) >= 5 and (no_reply_count / len(recent_cycles)) >= 0.8: + if len(recent_cycles) >= (5 * global_config.focus_chat.exit_focus_threshold) and (no_reply_count / len(recent_cycles)) >= (0.75 * global_config.focus_chat.exit_focus_threshold): if global_config.chat.chat_mode == "auto": result["add"].append("exit_focus_chat") + result["remove"].append("no_reply") + result["remove"].append("reply") # 获取最近三次的reply状态 last_three = reply_sequence[-3:] if len(reply_sequence) >= 3 else reply_sequence diff --git a/src/chat/focus_chat/info_processors/tool_processor.py b/src/chat/focus_chat/info_processors/tool_processor.py index 6980c9083..2d52a04a2 100644 --- a/src/chat/focus_chat/info_processors/tool_processor.py +++ b/src/chat/focus_chat/info_processors/tool_processor.py @@ -76,7 +76,7 @@ class ToolProcessor(BaseProcessor): # 更新WorkingObservation中的结构化信息 logger.debug(f"工具调用结果: {result}") - + for observation in observations: if isinstance(observation, StructureObservation): for structured_info in result: @@ -92,7 +92,7 @@ class ToolProcessor(BaseProcessor): # print(f"working_info: {working_info}") # print(f"working_info.get('type'): {working_info.get('type')}") # print(f"working_info.get('content'): {working_info.get('content')}") - structured_info.set_info(key=working_info.get('type'), value=working_info.get('content')) + structured_info.set_info(key=working_info.get("type"), value=working_info.get("content")) # info = structured_info.get_processed_info() # print(f"info: {info}") diff --git a/src/chat/focus_chat/memory_activator.py b/src/chat/focus_chat/memory_activator.py index e097bdbb9..2aa8fa549 100644 --- a/src/chat/focus_chat/memory_activator.py +++ b/src/chat/focus_chat/memory_activator.py @@ -19,24 +19,24 @@ logger = get_logger("memory_activator") def get_keywords_from_json(json_str): """ 从JSON字符串中提取关键词列表 - + Args: json_str: JSON格式的字符串 - + Returns: List[str]: 关键词列表 """ try: # 使用repair_json修复JSON格式 fixed_json = repair_json(json_str) - + # 如果repair_json返回的是字符串,需要解析为Python对象 if isinstance(fixed_json, str): result = json.loads(fixed_json) else: # 如果repair_json直接返回了字典对象,直接使用 result = fixed_json - + # 提取关键词 keywords = result.get("keywords", []) return keywords @@ -100,7 +100,7 @@ class MemoryActivator: # 将缓存的关键词转换为字符串,用于prompt cached_keywords_str = ", ".join(self.cached_keywords) if self.cached_keywords else "暂无历史关键词" - + prompt = await global_prompt_manager.format_prompt( "memory_activator_prompt", obs_info_text=obs_info_text, @@ -116,7 +116,7 @@ class MemoryActivator: # 只取response的第一个元素(字符串) response_str = response[0] keywords = list(get_keywords_from_json(response_str)) - + # 更新关键词缓存 if keywords: # 限制缓存大小,最多保留10个关键词 @@ -124,12 +124,12 @@ class MemoryActivator: # 转换为列表,移除最早的关键词 cached_list = list(self.cached_keywords) self.cached_keywords = set(cached_list[-8:]) - + # 添加新的关键词到缓存 self.cached_keywords.update(keywords) logger.debug(f"更新关键词缓存: {self.cached_keywords}") - #调用记忆系统获取相关记忆 + # 调用记忆系统获取相关记忆 related_memory = await HippocampusManager.get_instance().get_memory_from_topic( valid_keywords=keywords, max_memory_num=3, max_memory_length=2, max_depth=3 ) diff --git a/src/chat/focus_chat/planners/action_manager.py b/src/chat/focus_chat/planners/action_manager.py index 62db09a96..d2ed378c2 100644 --- a/src/chat/focus_chat/planners/action_manager.py +++ b/src/chat/focus_chat/planners/action_manager.py @@ -29,7 +29,6 @@ class ActionManager: # 当前正在使用的动作集合,默认加载默认动作 self._using_actions: Dict[str, ActionInfo] = {} - # 默认动作集,仅作为快照,用于恢复默认 self._default_actions: Dict[str, ActionInfo] = {} @@ -159,9 +158,9 @@ class ActionManager: Optional[BaseAction]: 创建的动作处理器实例,如果动作名称未注册则返回None """ # 检查动作是否在当前使用的动作集中 - if action_name not in self._using_actions: - logger.warning(f"当前不可用的动作类型: {action_name}") - return None + # if action_name not in self._using_actions: + # logger.warning(f"当前不可用的动作类型: {action_name}") + # return None handler_class = _ACTION_REGISTRY.get(action_name) if not handler_class: @@ -283,7 +282,9 @@ class ActionManager: def restore_actions(self) -> None: """恢复到默认动作集""" - logger.debug(f"恢复动作集: 从 {list(self._using_actions.keys())} 恢复到默认动作集 {list(self._default_actions.keys())}") + logger.debug( + f"恢复动作集: 从 {list(self._using_actions.keys())} 恢复到默认动作集 {list(self._default_actions.keys())}" + ) self._using_actions = self._default_actions.copy() def restore_default_actions(self) -> None: diff --git a/src/chat/focus_chat/planners/actions/__init__.py b/src/chat/focus_chat/planners/actions/__init__.py index 3f2baf665..6fc139d74 100644 --- a/src/chat/focus_chat/planners/actions/__init__.py +++ b/src/chat/focus_chat/planners/actions/__init__.py @@ -1,5 +1,6 @@ # 导入所有动作模块以确保装饰器被执行 from . import reply_action # noqa from . import no_reply_action # noqa +from . import exit_focus_chat_action # noqa # 在此处添加更多动作模块导入 diff --git a/src/chat/focus_chat/planners/actions/exit_focus_chat_action.py b/src/chat/focus_chat/planners/actions/exit_focus_chat_action.py index c7ba64830..8ab43f96d 100644 --- a/src/chat/focus_chat/planners/actions/exit_focus_chat_action.py +++ b/src/chat/focus_chat/planners/actions/exit_focus_chat_action.py @@ -5,8 +5,6 @@ from src.chat.focus_chat.planners.actions.base_action import BaseAction, registe from typing import Tuple, List from src.chat.heart_flow.observation.observation import Observation from src.chat.message_receive.chat_stream import ChatStream -from src.chat.heart_flow.heartflow import heartflow -from src.chat.heart_flow.sub_heartflow import ChatState logger = get_logger("action_taken") @@ -27,7 +25,7 @@ class ExitFocusChatAction(BaseAction): "当前内容不需要持续专注关注,你决定退出专注聊天", "聊天内容已经完成,你决定退出专注聊天", ] - default = True + default = False def __init__( self, @@ -56,7 +54,6 @@ class ExitFocusChatAction(BaseAction): self.observations = observations self.log_prefix = log_prefix self._shutting_down = shutting_down - self.chat_id = chat_stream.stream_id async def handle_action(self) -> Tuple[bool, str]: """ @@ -74,23 +71,8 @@ class ExitFocusChatAction(BaseAction): try: # 转换状态 status_message = "" - self.sub_heartflow = await heartflow.get_or_create_subheartflow(self.chat_id) - if self.sub_heartflow: - try: - # 转换为normal_chat状态 - await self.sub_heartflow.change_chat_state(ChatState.CHAT) - status_message = "已成功切换到普通聊天模式" - logger.info(f"{self.log_prefix} {status_message}") - except Exception as e: - error_msg = f"切换到普通聊天模式失败: {str(e)}" - logger.error(f"{self.log_prefix} {error_msg}") - return False, error_msg - else: - warning_msg = "未找到有效的sub heartflow实例,无法切换状态" - logger.warning(f"{self.log_prefix} {warning_msg}") - return False, warning_msg - - return True, status_message + command = "stop_focus_chat" + return True, status_message, command except asyncio.CancelledError: logger.info(f"{self.log_prefix} 处理 'exit_focus_chat' 时等待被中断 (CancelledError)") @@ -99,4 +81,4 @@ class ExitFocusChatAction(BaseAction): error_msg = f"处理 'exit_focus_chat' 时发生错误: {str(e)}" logger.error(f"{self.log_prefix} {error_msg}") logger.error(traceback.format_exc()) - return False, error_msg + return False, "", "" diff --git a/src/chat/focus_chat/planners/planner.py b/src/chat/focus_chat/planners/planner.py index 05443006c..4a62a0cf8 100644 --- a/src/chat/focus_chat/planners/planner.py +++ b/src/chat/focus_chat/planners/planner.py @@ -156,7 +156,7 @@ class ActionPlanner: logger.info(f"{self.log_prefix}{reasoning}") self.action_manager.restore_actions() logger.debug( - f"{self.log_prefix}恢复到默认动作集, 当前可用: {list(self.action_manager.get_using_actions().keys())}" + f"{self.log_prefix}沉默后恢复到默认动作集, 当前可用: {list(self.action_manager.get_using_actions().keys())}" ) return { "action_result": {"action_type": action, "action_data": action_data, "reasoning": reasoning}, @@ -241,7 +241,7 @@ class ActionPlanner: # 恢复到默认动作集 self.action_manager.restore_actions() logger.debug( - f"{self.log_prefix}恢复到默认动作集, 当前可用: {list(self.action_manager.get_using_actions().keys())}" + f"{self.log_prefix}规划后恢复到默认动作集, 当前可用: {list(self.action_manager.get_using_actions().keys())}" ) action_result = {"action_type": action, "action_data": action_data, "reasoning": reasoning} diff --git a/src/chat/focus_chat/working_memory/memory_manager.py b/src/chat/focus_chat/working_memory/memory_manager.py index 0157e4f8d..af9d87004 100644 --- a/src/chat/focus_chat/working_memory/memory_manager.py +++ b/src/chat/focus_chat/working_memory/memory_manager.py @@ -33,7 +33,10 @@ class MemoryManager: self._id_map: Dict[str, MemoryItem] = {} self.llm_summarizer = LLMRequest( - model=global_config.model.focus_working_memory, temperature=0.3, max_tokens=512, request_type="memory_summarization" + model=global_config.model.focus_working_memory, + temperature=0.3, + max_tokens=512, + request_type="memory_summarization", ) @property diff --git a/src/chat/heart_flow/background_tasks.py b/src/chat/heart_flow/background_tasks.py index b509f84b3..9479804ea 100644 --- a/src/chat/heart_flow/background_tasks.py +++ b/src/chat/heart_flow/background_tasks.py @@ -92,28 +92,30 @@ class BackgroundTaskManager: # 根据 chat_mode 条件添加其他任务 if not (global_config.chat.chat_mode == "normal"): - task_configs.extend([ - ( - self._run_cleanup_cycle, - "info", - f"清理任务已启动 间隔:{CLEANUP_INTERVAL_SECONDS}s", - "_cleanup_task", - ), - # 新增私聊激活任务配置 - ( - # Use lambda to pass the interval to the runner function - lambda: self._run_private_chat_activation_cycle(PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS), - "debug", - f"私聊激活检查任务已启动 间隔:{PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS}s", - "_private_chat_activation_task", - ), - # ( - # self._run_into_focus_cycle, - # "debug", # 设为debug,避免过多日志 - # f"专注评估任务已启动 间隔:{INTEREST_EVAL_INTERVAL_SECONDS}s", - # "_into_focus_task", - # ) - ]) + task_configs.extend( + [ + ( + self._run_cleanup_cycle, + "info", + f"清理任务已启动 间隔:{CLEANUP_INTERVAL_SECONDS}s", + "_cleanup_task", + ), + # 新增私聊激活任务配置 + ( + # Use lambda to pass the interval to the runner function + lambda: self._run_private_chat_activation_cycle(PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS), + "debug", + f"私聊激活检查任务已启动 间隔:{PRIVATE_CHAT_ACTIVATION_CHECK_INTERVAL_SECONDS}s", + "_private_chat_activation_task", + ), + # ( + # self._run_into_focus_cycle, + # "debug", # 设为debug,避免过多日志 + # f"专注评估任务已启动 间隔:{INTEREST_EVAL_INTERVAL_SECONDS}s", + # "_into_focus_task", + # ) + ] + ) else: logger.info("聊天模式为 normal,跳过启动清理任务、私聊激活任务和专注评估任务") diff --git a/src/chat/heart_flow/heartflow.py b/src/chat/heart_flow/heartflow.py index 6e938872f..e1f8d9570 100644 --- a/src/chat/heart_flow/heartflow.py +++ b/src/chat/heart_flow/heartflow.py @@ -59,11 +59,11 @@ class Heartflow: async def api_get_normal_chat_replies(self, subheartflow_id: str, limit: int = 10) -> Optional[List[dict]]: """获取子心流的NormalChat回复记录 - + Args: subheartflow_id: 子心流ID limit: 最大返回数量,默认10条 - + Returns: Optional[List[dict]]: 回复记录列表,如果子心流不存在则返回None """ @@ -71,7 +71,7 @@ class Heartflow: if not subheartflow: logger.warning(f"尝试获取不存在的子心流 {subheartflow_id} 的NormalChat回复记录") return None - + return subheartflow.get_normal_chat_recent_replies(limit) async def heartflow_start_working(self): diff --git a/src/chat/heart_flow/interest_chatting.py b/src/chat/heart_flow/interest_chatting.py index bce372b5c..4cb477c04 100644 --- a/src/chat/heart_flow/interest_chatting.py +++ b/src/chat/heart_flow/interest_chatting.py @@ -20,9 +20,9 @@ MAX_REPLY_PROBABILITY = 1 class InterestChatting: def __init__( self, - decay_rate=global_config.focus_chat.default_decay_rate_per_second, + decay_rate=0.95, max_interest=MAX_INTEREST, - trigger_threshold=global_config.focus_chat.reply_trigger_threshold, + trigger_threshold=4, max_probability=MAX_REPLY_PROBABILITY, ): # 基础属性初始化 diff --git a/src/chat/heart_flow/observation/chatting_observation.py b/src/chat/heart_flow/observation/chatting_observation.py index 4264a76c0..187b8027f 100644 --- a/src/chat/heart_flow/observation/chatting_observation.py +++ b/src/chat/heart_flow/observation/chatting_observation.py @@ -1,5 +1,4 @@ from datetime import datetime -from src.llm_models.utils_model import LLMRequest from src.config.config import global_config import traceback from src.chat.utils.chat_message_builder import ( diff --git a/src/chat/heart_flow/sub_heartflow.py b/src/chat/heart_flow/sub_heartflow.py index 664bb54b6..a7e980f43 100644 --- a/src/chat/heart_flow/sub_heartflow.py +++ b/src/chat/heart_flow/sub_heartflow.py @@ -12,7 +12,6 @@ from src.chat.normal_chat.normal_chat import NormalChat from src.chat.heart_flow.mai_state_manager import MaiStateInfo from src.chat.heart_flow.chat_state_info import ChatState, ChatStateInfo from .utils_chat import get_chat_type_and_target_info -from .interest_chatting import InterestChatting from src.config.config import global_config @@ -51,7 +50,7 @@ class SubHeartflow: # --- End Initialization --- # 兴趣检测器 - self.interest_chatting: InterestChatting = InterestChatting() + self.interest_dict: Dict[str, tuple[MessageRecv, float, bool]] = {} # 活动状态管理 self.should_stop = False # 停止标志 @@ -85,8 +84,8 @@ class SubHeartflow: # --- End using utility function --- # Initialize interest system (existing logic) - await self.interest_chatting.initialize() - logger.debug(f"{self.log_prefix} InterestChatting 实例已初始化。") + # await self.interest_chatting.initialize() + # logger.debug(f"{self.log_prefix} InterestChatting 实例已初始化。") # 根据配置决定初始状态 if global_config.chat.chat_mode == "focus": @@ -131,9 +130,9 @@ class SubHeartflow: if rewind or not self.normal_chat_instance: # 提供回调函数,用于接收需要切换到focus模式的通知 self.normal_chat_instance = NormalChat( - chat_stream=chat_stream, - interest_dict=self.get_interest_dict(), - on_switch_to_focus_callback=self._handle_switch_to_focus_request + chat_stream=chat_stream, + interest_dict=self.interest_dict, + on_switch_to_focus_callback=self._handle_switch_to_focus_request, ) # 进行异步初始化 @@ -152,12 +151,12 @@ class SubHeartflow: async def _handle_switch_to_focus_request(self) -> None: """ 处理来自NormalChat的切换到focus模式的请求 - + Args: stream_id: 请求切换的stream_id """ logger.info(f"{self.log_prefix} 收到NormalChat请求切换到focus模式") - + # 切换到focus模式 current_state = self.chat_state.chat_status if current_state == ChatState.NORMAL: @@ -166,6 +165,21 @@ class SubHeartflow: else: logger.warning(f"{self.log_prefix} 当前状态为{current_state.value},无法切换到FOCUSED状态") + async def _handle_stop_focus_chat_request(self) -> None: + """ + 处理来自HeartFChatting的停止focus模式的请求 + 当收到stop_focus_chat命令时被调用 + """ + logger.info(f"{self.log_prefix} 收到HeartFChatting请求停止focus模式") + + # 切换到normal模式 + current_state = self.chat_state.chat_status + if current_state == ChatState.FOCUSED: + await self.change_chat_state(ChatState.NORMAL) + logger.info(f"{self.log_prefix} 已根据HeartFChatting请求从FOCUSED切换到NORMAL状态") + else: + logger.warning(f"{self.log_prefix} 当前状态为{current_state.value},无法切换到NORMAL状态") + async def _stop_heart_fc_chat(self): """停止并清理 HeartFChatting 实例""" if self.heart_fc_instance: @@ -182,7 +196,7 @@ class SubHeartflow: async def _start_heart_fc_chat(self) -> bool: """启动 HeartFChatting 实例,确保 NormalChat 已停止""" await self._stop_normal_chat() # 确保普通聊天监控已停止 - self.clear_interest_dict() # 清理兴趣字典,准备专注聊天 + self.interest_dict.clear() log_prefix = self.log_prefix # 如果实例已存在,检查其循环任务状态 @@ -211,6 +225,7 @@ class SubHeartflow: self.heart_fc_instance = HeartFChatting( chat_id=self.subheartflow_id, observations=self.observations, + on_stop_focus_chat=self._handle_stop_focus_chat_request, ) # 初始化并启动 HeartFChatting @@ -259,7 +274,7 @@ class SubHeartflow: elif new_state == ChatState.ABSENT: logger.info(f"{log_prefix} 进入 ABSENT 状态,停止所有聊天活动...") - self.clear_interest_dict() + self.interest_dict.clear() await self._stop_normal_chat() await self._stop_heart_fc_chat() state_changed = True @@ -300,38 +315,35 @@ class SubHeartflow: logger.warning(f"SubHeartflow {self.subheartflow_id} 没有找到有效的 ChattingObservation") return None - async def get_interest_state(self) -> dict: - return await self.interest_chatting.get_state() - def get_normal_chat_last_speak_time(self) -> float: if self.normal_chat_instance: return self.normal_chat_instance.last_speak_time return 0 - def get_interest_dict(self) -> Dict[str, tuple[MessageRecv, float, bool]]: - return self.interest_chatting.interest_dict - def get_normal_chat_recent_replies(self, limit: int = 10) -> List[dict]: """获取NormalChat实例的最近回复记录 - + Args: limit: 最大返回数量,默认10条 - + Returns: List[dict]: 最近的回复记录列表,如果没有NormalChat实例则返回空列表 """ if self.normal_chat_instance: return self.normal_chat_instance.get_recent_replies(limit) return [] - - def clear_interest_dict(self): - self.interest_chatting.interest_dict.clear() + + def add_interest_message(self, message: MessageRecv, interest_value: float, is_mentioned: bool): + self.interest_dict[message.message_info.message_id] = (message, interest_value, is_mentioned) + # 如果字典长度超过10,删除最旧的消息 + if len(self.interest_dict) > 10: + oldest_key = next(iter(self.interest_dict)) + self.interest_dict.pop(oldest_key) async def get_full_state(self) -> dict: """获取子心流的完整状态,包括兴趣、思维和聊天状态。""" - interest_state = await self.get_interest_state() return { - "interest_state": interest_state, + "interest_state": "interest_state", "chat_state": self.chat_state.chat_status.value, "chat_state_changed_time": self.chat_state_changed_time, } @@ -349,10 +361,6 @@ class SubHeartflow: await self._stop_normal_chat() await self._stop_heart_fc_chat() - # 停止兴趣更新任务 - if self.interest_chatting: - logger.info(f"{self.log_prefix} 停止兴趣系统后台任务...") - await self.interest_chatting.stop_updates() # 取消可能存在的旧后台任务 (self.task) if self.task and not self.task.done(): diff --git a/src/chat/heart_flow/subheartflow_manager.py b/src/chat/heart_flow/subheartflow_manager.py index 5217202ad..6e8e7b868 100644 --- a/src/chat/heart_flow/subheartflow_manager.py +++ b/src/chat/heart_flow/subheartflow_manager.py @@ -1,6 +1,5 @@ import asyncio import time -import random from typing import Dict, Any, Optional, List from src.common.logger_manager import get_logger from src.chat.message_receive.chat_stream import chat_manager @@ -187,40 +186,40 @@ class SubHeartflowManager: ) # async def sbhf_normal_into_focus(self): - # """评估子心流兴趣度,满足条件则提升到FOCUSED状态(基于start_hfc_probability)""" - # try: - # for sub_hf in list(self.subheartflows.values()): - # flow_id = sub_hf.subheartflow_id - # stream_name = chat_manager.get_stream_name(flow_id) or flow_id + # """评估子心流兴趣度,满足条件则提升到FOCUSED状态(基于start_hfc_probability)""" + # try: + # for sub_hf in list(self.subheartflows.values()): + # flow_id = sub_hf.subheartflow_id + # stream_name = chat_manager.get_stream_name(flow_id) or flow_id - # # 跳过已经是FOCUSED状态的子心流 - # if sub_hf.chat_state.chat_status == ChatState.FOCUSED: - # continue + # # 跳过已经是FOCUSED状态的子心流 + # if sub_hf.chat_state.chat_status == ChatState.FOCUSED: + # continue - # if sub_hf.interest_chatting.start_hfc_probability == 0: - # continue - # else: - # logger.debug( - # f"{stream_name},现在状态: {sub_hf.chat_state.chat_status.value},进入专注概率: {sub_hf.interest_chatting.start_hfc_probability}" - # ) + # if sub_hf.interest_chatting.start_hfc_probability == 0: + # continue + # else: + # logger.debug( + # f"{stream_name},现在状态: {sub_hf.chat_state.chat_status.value},进入专注概率: {sub_hf.interest_chatting.start_hfc_probability}" + # ) - # if random.random() >= sub_hf.interest_chatting.start_hfc_probability: - # continue + # if random.random() >= sub_hf.interest_chatting.start_hfc_probability: + # continue - # # 获取最新状态并执行提升 - # current_subflow = self.subheartflows.get(flow_id) - # if not current_subflow: - # continue + # # 获取最新状态并执行提升 + # current_subflow = self.subheartflows.get(flow_id) + # if not current_subflow: + # continue - # logger.info( - # f"{stream_name} 触发 认真水群 (概率={current_subflow.interest_chatting.start_hfc_probability:.2f})" - # ) + # logger.info( + # f"{stream_name} 触发 认真水群 (概率={current_subflow.interest_chatting.start_hfc_probability:.2f})" + # ) - # # 执行状态提升 - # await current_subflow.change_chat_state(ChatState.FOCUSED) + # # 执行状态提升 + # await current_subflow.change_chat_state(ChatState.FOCUSED) - # except Exception as e: - # logger.error(f"启动HFC 兴趣评估失败: {e}", exc_info=True) + # except Exception as e: + # logger.error(f"启动HFC 兴趣评估失败: {e}", exc_info=True) async def sbhf_focus_into_normal(self, subflow_id: Any): """ @@ -249,7 +248,7 @@ class SubHeartflowManager: ) try: # 从HFC到CHAT时,清空兴趣字典 - subflow.clear_interest_dict() + subflow.interest_dict.clear() await subflow.change_chat_state(target_state) final_state = subflow.chat_state.chat_status if final_state == target_state: diff --git a/src/chat/normal_chat/normal_chat.py b/src/chat/normal_chat/normal_chat.py index 34b79639e..0cf0908f4 100644 --- a/src/chat/normal_chat/normal_chat.py +++ b/src/chat/normal_chat/normal_chat.py @@ -49,14 +49,14 @@ class NormalChat: self.last_speak_time = 0 self._chat_task: Optional[asyncio.Task] = None self._initialized = False # Track initialization status - + # 记录最近的回复内容,每项包含: {time, user_message, response, is_mentioned, is_reference_reply} self.recent_replies = [] self.max_replies_history = 20 # 最多保存最近20条回复记录 - + # 添加回调函数,用于在满足条件时通知切换到focus_chat模式 self.on_switch_to_focus_callback = on_switch_to_focus_callback - + # 最近回复检查相关 self._last_check_time = time.time() self._check_interval = 10 # 每10秒检查一次是否需要切换到focus模式 @@ -207,12 +207,12 @@ class NormalChat: if self._chat_task is None or self._chat_task.cancelled(): logger.info(f"[{self.stream_name}] 兴趣监控任务被取消或置空,退出") break - + # 定期检查是否需要切换到focus模式 - current_time = time.time() - if current_time - self._last_check_time > self._check_interval: - await self._check_switch_to_focus() - self._last_check_time = current_time + # current_time = time.time() + # if current_time - self._last_check_time > self._check_interval: + # await self._check_switch_to_focus() + # self._last_check_time = current_time items_to_process = list(self.interest_dict.items()) if not items_to_process: @@ -329,28 +329,28 @@ class NormalChat: # 检查 first_bot_msg 是否为 None (例如思考消息已被移除的情况) if first_bot_msg: info_catcher.catch_after_response(timing_results["消息发送"], response_set, first_bot_msg) - + # 记录回复信息到最近回复列表中 reply_info = { "time": time.time(), "user_message": message.processed_plain_text, "user_info": { "user_id": message.message_info.user_info.user_id, - "user_nickname": message.message_info.user_info.user_nickname + "user_nickname": message.message_info.user_info.user_nickname, }, "response": response_set, "is_mentioned": is_mentioned, "is_reference_reply": message.reply is not None, # 判断是否为引用回复 - "timing": {k: round(v, 2) for k, v in timing_results.items()} + "timing": {k: round(v, 2) for k, v in timing_results.items()}, } self.recent_replies.append(reply_info) # 保持最近回复历史在限定数量内 if len(self.recent_replies) > self.max_replies_history: - self.recent_replies = self.recent_replies[-self.max_replies_history:] - + self.recent_replies = self.recent_replies[-self.max_replies_history :] + # 检查是否需要切换到focus模式 await self._check_switch_to_focus() - + else: logger.warning(f"[{self.stream_name}] 思考消息 {thinking_id} 在发送前丢失,无法记录 info_catcher") @@ -563,10 +563,10 @@ class NormalChat: # 获取最近回复记录的方法 def get_recent_replies(self, limit: int = 10) -> List[dict]: """获取最近的回复记录 - + Args: limit: 最大返回数量,默认10条 - + Returns: List[dict]: 最近的回复记录列表,每项包含: time: 回复时间戳 @@ -583,21 +583,23 @@ class NormalChat: async def _check_switch_to_focus(self) -> None: """检查是否满足切换到focus模式的条件""" if not self.on_switch_to_focus_callback: - return # 如果没有设置回调函数,直接返回 + return # 如果没有设置回调函数,直接返回 current_time = time.time() - + time_threshold = 120 / global_config.focus_chat.auto_focus_threshold reply_threshold = 6 * global_config.focus_chat.auto_focus_threshold - + one_minute_ago = current_time - time_threshold - + # 统计1分钟内的回复数量 recent_reply_count = sum(1 for reply in self.recent_replies if reply["time"] > one_minute_ago) # print(111111111111111333333333333333333333333331111111111111111111111111111111111) # print(recent_reply_count) # 如果1分钟内回复数量大于8,触发切换到focus模式 if recent_reply_count > reply_threshold: - logger.info(f"[{self.stream_name}] 检测到1分钟内回复数量({recent_reply_count})大于{reply_threshold},触发切换到focus模式") + logger.info( + f"[{self.stream_name}] 检测到1分钟内回复数量({recent_reply_count})大于{reply_threshold},触发切换到focus模式" + ) try: # 调用回调函数通知上层切换到focus模式 await self.on_switch_to_focus_callback() diff --git a/src/config/official_configs.py b/src/config/official_configs.py index 80f0ae7a7..4814052a7 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -44,12 +44,13 @@ class IdentityConfig(ConfigBase): identity_detail: list[str] = field(default_factory=lambda: []) """身份特征""" + @dataclass class RelationshipConfig(ConfigBase): """关系配置类""" give_name: bool = False - """是否给其他人取名""" + """是否给其他人取名""" @dataclass @@ -125,6 +126,9 @@ class FocusChatConfig(ConfigBase): auto_focus_threshold: float = 1.0 """自动切换到专注聊天的阈值,越低越容易进入专注聊天""" + exit_focus_threshold: float = 1.0 + """自动退出专注聊天的阈值,越低越容易退出专注聊天""" + observation_context_size: int = 12 """可观察到的最长上下文大小,超过这个值的上下文会被压缩""" @@ -381,17 +385,16 @@ class ModelConfig(ConfigBase): """模型配置类""" model_max_output_length: int = 800 # 最大回复长度 - - + utils: dict[str, Any] = field(default_factory=lambda: {}) """组件模型配置""" - + utils_small: dict[str, Any] = field(default_factory=lambda: {}) """组件小模型配置""" normal_chat_1: dict[str, Any] = field(default_factory=lambda: {}) """normal_chat首要回复模型模型配置""" - + normal_chat_2: dict[str, Any] = field(default_factory=lambda: {}) """normal_chat次要回复模型配置""" @@ -403,22 +406,22 @@ class ModelConfig(ConfigBase): focus_working_memory: dict[str, Any] = field(default_factory=lambda: {}) """专注工作记忆模型配置""" - + focus_chat_mind: dict[str, Any] = field(default_factory=lambda: {}) """专注聊天规划模型配置""" - + focus_self_recognize: dict[str, Any] = field(default_factory=lambda: {}) """专注自我识别模型配置""" - + focus_tool_use: dict[str, Any] = field(default_factory=lambda: {}) """专注工具使用模型配置""" focus_planner: dict[str, Any] = field(default_factory=lambda: {}) """专注规划模型配置""" - + focus_expressor: dict[str, Any] = field(default_factory=lambda: {}) """专注表达器模型配置""" - + embedding: dict[str, Any] = field(default_factory=lambda: {}) """嵌入模型配置""" @@ -430,7 +433,3 @@ class ModelConfig(ConfigBase): pfc_reply_checker: dict[str, Any] = field(default_factory=lambda: {}) """PFC回复检查模型配置""" - - - - diff --git a/src/llm_models/utils_model.py b/src/llm_models/utils_model.py index 319c020f3..712d51d81 100644 --- a/src/llm_models/utils_model.py +++ b/src/llm_models/utils_model.py @@ -636,18 +636,18 @@ class LLMRequest: "messages": messages, **params_copy, } - + # 添加temp参数(如果不是默认值0.7) if self.temp != 0.7: payload["temperature"] = self.temp - + # 添加enable_thinking参数(如果不是默认值False) if not self.enable_thinking: payload["enable_thinking"] = False - + if self.thinking_budget != 4096: payload["thinking_budget"] = self.thinking_budget - + if "max_tokens" not in payload and "max_completion_tokens" not in payload: payload["max_tokens"] = global_config.model.model_max_output_length # 如果 payload 中依然存在 max_tokens 且需要转换,在这里进行再次检查 diff --git a/src/person_info/person_info.py b/src/person_info/person_info.py index 021297cc7..80edc4db0 100644 --- a/src/person_info/person_info.py +++ b/src/person_info/person_info.py @@ -261,7 +261,7 @@ class PersonInfoManager: current_name_set = set(self.person_name_list.values()) while current_try < max_retries: - prompt_personality = individuality.get_prompt(x_person=2, level=1) + # prompt_personality = individuality.get_prompt(x_person=2, level=1) bot_name = individuality.personality.bot_nickname qv_name_prompt = f"你是{bot_name},一个伪装成人类的AI,你不能让别人发现这一点," @@ -273,9 +273,7 @@ class PersonInfoManager: qv_name_prompt += f"你之前叫他{old_name},是因为{old_reason}," qv_name_prompt += f"\n其他取名的要求是:{request},不要太浮夸,简短," - qv_name_prompt += ( - "\n请根据以上用户信息,想想你叫他什么比较好,不要太浮夸,请最好使用用户的qq昵称,可以稍作修改,优先使用原文。优先使用用户的qq昵称或者群昵称原文。" - ) + qv_name_prompt += "\n请根据以上用户信息,想想你叫他什么比较好,不要太浮夸,请最好使用用户的qq昵称,可以稍作修改,优先使用原文。优先使用用户的qq昵称或者群昵称原文。" if existing_names_str: qv_name_prompt += f"\n请注意,以下名称已被你尝试过或已知存在,请避免:{existing_names_str}。\n" diff --git a/src/plugins/test_plugin/actions/group_whole_ban_action.py b/src/plugins/test_plugin/actions/group_whole_ban_action.py index bb9f35313..7e6553127 100644 --- a/src/plugins/test_plugin/actions/group_whole_ban_action.py +++ b/src/plugins/test_plugin/actions/group_whole_ban_action.py @@ -10,15 +10,13 @@ class GroupWholeBanAction(PluginAction): """群聊全体禁言动作处理类""" action_name = "group_whole_ban_action" - action_description = ( - "开启或关闭群聊全体禁言,当群聊过于混乱或需要安静时使用" - ) + action_description = "开启或关闭群聊全体禁言,当群聊过于混乱或需要安静时使用" action_parameters = { "enable": "是否开启全体禁言,输入True开启,False关闭,必填", } action_require = [ "当群聊过于混乱需要安静时使用", - "当需要临时暂停群聊讨论时使用", + "当需要临时暂停群聊讨论时使用", "当有人要求开启全体禁言时使用", "当管理员需要发布重要公告时使用", ] @@ -31,7 +29,7 @@ class GroupWholeBanAction(PluginAction): # 获取参数 enable = self.action_data.get("enable") - + if enable is None: error_msg = "全体禁言参数不完整,需要enable参数" logger.error(f"{self.log_prefix} {error_msg}") @@ -39,9 +37,9 @@ class GroupWholeBanAction(PluginAction): # 确保enable是布尔类型 if isinstance(enable, str): - if enable.lower() in ['true', '1', 'yes', '开启', '是']: + if enable.lower() in ["true", "1", "yes", "开启", "是"]: enable = True - elif enable.lower() in ['false', '0', 'no', '关闭', '否']: + elif enable.lower() in ["false", "0", "no", "关闭", "否"]: enable = False else: error_msg = f"无效的enable参数: {enable},应该是True或False" @@ -54,20 +52,12 @@ class GroupWholeBanAction(PluginAction): try: # 发送群聊全体禁言命令,按照新格式 - await self.send_message( - type="command", - data={ - "name": "GROUP_WHOLE_BAN", - "args": { - "enable": enable - } - } - ) - + await self.send_message(type="command", data={"name": "GROUP_WHOLE_BAN", "args": {"enable": enable}}) + logger.info(f"{self.log_prefix} 成功{action_text}全体禁言") return True, f"成功{action_text}全体禁言" except Exception as e: logger.error(f"{self.log_prefix} 执行全体禁言动作时出错: {e}") await self.send_message_by_expressor(f"执行全体禁言动作时出错: {e}") - return False, f"执行全体禁言动作时出错: {e}" \ No newline at end of file + return False, f"执行全体禁言动作时出错: {e}" diff --git a/src/plugins/test_plugin/actions/mute_action.py b/src/plugins/test_plugin/actions/mute_action.py index 279ee0109..c693c59af 100644 --- a/src/plugins/test_plugin/actions/mute_action.py +++ b/src/plugins/test_plugin/actions/mute_action.py @@ -10,9 +10,7 @@ class MuteAction(PluginAction): """群聊禁言动作处理类""" action_name = "mute_action" - action_description = ( - "如果某人违反了公序良俗,或者别人戳你太多,或者某人刷屏,一定要禁言某人,如果你很生气,可以禁言某人,可以自选禁言时长,视严重程度而定。" - ) + action_description = "如果某人违反了公序良俗,或者别人戳你太多,或者某人刷屏,一定要禁言某人,如果你很生气,可以禁言某人,可以自选禁言时长,视严重程度而定。" action_parameters = { "target": "禁言对象,输入你要禁言的对象的名字,必填", "duration": "禁言时长,输入你要禁言的时长,单位为秒,必填,必须为数字", @@ -38,7 +36,7 @@ class MuteAction(PluginAction): target = self.action_data.get("target") duration = self.action_data.get("duration") reason = self.action_data.get("reason", "违反群规") - + if not target or not duration: error_msg = "禁言参数不完整,需要target和duration" logger.error(f"{self.log_prefix} {error_msg}") @@ -46,7 +44,7 @@ class MuteAction(PluginAction): # 获取用户ID platform, user_id = await self.get_user_id_by_person_name(target) - + if not user_id: error_msg = f"未找到用户 {target} 的ID" logger.error(f"{self.log_prefix} {error_msg}") @@ -58,19 +56,12 @@ class MuteAction(PluginAction): try: # 确保duration是字符串类型 duration_str = str(duration) - + # 发送群聊禁言命令,按照新格式 await self.send_message( - type="command", - data={ - "name": "GROUP_BAN", - "args": { - "qq_id": str(user_id), - "duration": duration_str - } - } + type="command", data={"name": "GROUP_BAN", "args": {"qq_id": str(user_id), "duration": duration_str}} ) - + logger.info(f"{self.log_prefix} 成功禁言用户 {target}({user_id}),时长 {duration} 秒") return True, f"成功禁言 {target},时长 {duration} 秒" diff --git a/src/tools/tool_use.py b/src/tools/tool_use.py index caca2cb6f..b6fabb21e 100644 --- a/src/tools/tool_use.py +++ b/src/tools/tool_use.py @@ -3,6 +3,8 @@ from src.common.logger_manager import get_logger from src.tools.tool_can_use import get_all_tool_definitions, get_tool_instance logger = get_logger("tool_use") + + class ToolUser: @staticmethod def _define_tools(): diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 9a1fd8934..87eba0ba2 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -80,7 +80,7 @@ talk_frequency_down_groups = [] #降低回复频率的群号码 [focus_chat] #专注聊天 auto_focus_threshold = 1 # 自动切换到专注聊天的阈值,越低越容易进入专注聊天 - +exit_focus_threshold = 1 # 自动退出专注聊天的阈值,越低越容易退出专注聊天 consecutive_no_reply_threshold = 3 # 连续不回复的阈值,越低越容易结束专注聊天 think_interval = 3 # 思考间隔 单位秒,可以有效减少消耗