diff --git a/src/chat/focus_chat/heartFC_chat.py b/src/chat/focus_chat/heartFC_chat.py index d5e9622f..a6ca4814 100644 --- a/src/chat/focus_chat/heartFC_chat.py +++ b/src/chat/focus_chat/heartFC_chat.py @@ -16,16 +16,18 @@ from src.chat.focus_chat.info.info_base import InfoBase from src.chat.focus_chat.info_processors.chattinginfo_processor import ChattingInfoProcessor from src.chat.focus_chat.info_processors.mind_processor import MindProcessor from src.chat.focus_chat.info_processors.working_memory_processor import WorkingMemoryProcessor -from src.chat.focus_chat.info_processors.action_processor import ActionProcessor +# from src.chat.focus_chat.info_processors.action_processor import ActionProcessor from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation from src.chat.heart_flow.observation.working_observation import WorkingMemoryObservation from src.chat.heart_flow.observation.structure_observation import StructureObservation +from src.chat.heart_flow.observation.actions_observation import ActionObservation from src.chat.focus_chat.info_processors.tool_processor import ToolProcessor from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor from src.chat.focus_chat.memory_activator import MemoryActivator from src.chat.focus_chat.info_processors.base_processor import BaseProcessor from src.chat.focus_chat.info_processors.self_processor import SelfProcessor from src.chat.focus_chat.planners.planner import ActionPlanner +from src.chat.focus_chat.planners.modify_actions import ActionModifier from src.chat.focus_chat.planners.action_manager import ActionManager from src.chat.focus_chat.working_memory.working_memory import WorkingMemory from src.config.config import global_config @@ -41,7 +43,7 @@ PROCESSOR_CLASSES = { "ToolProcessor": (ToolProcessor, "tool_use_processor"), "WorkingMemoryProcessor": (WorkingMemoryProcessor, "working_memory_processor"), "SelfProcessor": (SelfProcessor, "self_identify_processor"), - "ActionProcessor": (ActionProcessor, "action_processor"), # 这个处理器不需要配置键名,默认启用 + # "ActionProcessor": (ActionProcessor, "action_processor"), # 这个处理器不需要配置键名,默认启用 } @@ -129,8 +131,10 @@ class HeartFChatting: self.expressor = DefaultExpressor(chat_id=self.stream_id) self.action_manager = ActionManager() self.action_planner = ActionPlanner(log_prefix=self.log_prefix, action_manager=self.action_manager) + self.action_modifier = ActionModifier(action_manager=self.action_manager) + self.action_observation = ActionObservation(observe_id=self.stream_id) - self.hfcloop_observation.set_action_manager(self.action_manager) + self.action_observation.set_action_manager(self.action_manager) self.all_observations = observations @@ -470,6 +474,12 @@ class HeartFChatting: with Timer("回忆", cycle_timers): running_memorys = await self.memory_activator.activate_memory(observations) + with Timer("调整动作", cycle_timers): + # 处理特殊的观察 + await self.action_modifier.modify_actions(observations=observations, running_memorys=running_memorys) + await self.action_observation.observe() + observations.append(self.action_observation) + with Timer("执行 信息处理器", cycle_timers): all_plan_info, processor_time_costs = await self._process_processors(observations, running_memorys, cycle_timers) diff --git a/src/chat/focus_chat/info_processors/mind_processor.py b/src/chat/focus_chat/info_processors/mind_processor.py index 5f8c9866..609e40e9 100644 --- a/src/chat/focus_chat/info_processors/mind_processor.py +++ b/src/chat/focus_chat/info_processors/mind_processor.py @@ -14,6 +14,7 @@ from .base_processor import BaseProcessor from src.chat.focus_chat.info.mind_info import MindInfo from typing import List, Optional from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation +from src.chat.heart_flow.observation.actions_observation import ActionObservation from typing import Dict from src.chat.focus_chat.info.info_base import InfoBase @@ -30,6 +31,8 @@ def init_prompt(): 现在是{time_now},你正在上网,和qq群里的网友们聊天,以下是正在进行的聊天内容: {chat_observe_info} +{action_observe_info} + 以下是你之前对聊天的观察和规划,你的名字是{bot_name}: {last_mind} @@ -50,6 +53,8 @@ def init_prompt(): 现在是{time_now},你正在上网,和qq群里的网友们聊天,以下是正在进行的聊天内容: {chat_observe_info} +{action_observe_info} + 以下是你之前对聊天的观察和规划,你的名字是{bot_name}: {last_mind} @@ -191,6 +196,8 @@ class MindProcessor(BaseProcessor): person_list = observation.person_list if isinstance(observation, HFCloopObservation): hfcloop_observe_info = observation.get_observe_info() + if isinstance(observation, ActionObservation): + action_observe_info = observation.get_observe_info() # ---------- 3. 准备个性化数据 ---------- # 获取个性化信息 @@ -211,6 +218,7 @@ class MindProcessor(BaseProcessor): chat_observe_info=chat_observe_info, last_mind=previous_mind, cycle_info_block=hfcloop_observe_info, + action_observe_info=action_observe_info, chat_target_name=chat_target_name, ) diff --git a/src/chat/focus_chat/info_processors/action_processor.py b/src/chat/focus_chat/planners/modify_actions.py similarity index 75% rename from src/chat/focus_chat/info_processors/action_processor.py rename to src/chat/focus_chat/planners/modify_actions.py index f4aa7c1d..dcaa9180 100644 --- a/src/chat/focus_chat/info_processors/action_processor.py +++ b/src/chat/focus_chat/planners/modify_actions.py @@ -2,7 +2,7 @@ from typing import List, Optional, Any from src.chat.heart_flow.observation.observation import Observation from src.chat.focus_chat.info.info_base import InfoBase from src.chat.focus_chat.info.action_info import ActionInfo -from .base_processor import BaseProcessor +from ..info_processors.base_processor import BaseProcessor from src.common.logger_manager import get_logger from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation from src.chat.heart_flow.observation.chatting_observation import ChattingObservation @@ -10,45 +10,38 @@ from src.chat.message_receive.chat_stream import chat_manager from typing import Dict from src.config.config import global_config import random +from src.chat.focus_chat.planners.action_manager import ActionManager -logger = get_logger("processor") +logger = get_logger("action_manager") -class ActionProcessor(BaseProcessor): +class ActionModifier(): """动作处理器 用于处理Observation对象,将其转换为ObsInfo对象。 """ log_prefix = "动作处理" + - def __init__(self): + def __init__(self, action_manager: ActionManager): """初始化观察处理器""" - super().__init__() + self.action_manager = action_manager + self.all_actions = self.action_manager.get_registered_actions() - async def process_info( + async def modify_actions( self, observations: Optional[List[Observation]] = None, running_memorys: Optional[List[Dict]] = None, **kwargs: Any, - ) -> List[InfoBase]: - """处理Observation对象 - - Args: - infos: InfoBase对象列表 - observations: 可选的Observation对象列表 - **kwargs: 其他可选参数 - - Returns: - List[InfoBase]: 处理后的ObsInfo实例列表 - """ + ): # print(f"observations: {observations}") - processed_infos = [] + # processed_infos = [] # 处理Observation对象 if observations: - action_info = ActionInfo() - all_actions = None + # action_info = ActionInfo() + # all_actions = None hfc_obs = None chat_obs = None @@ -66,7 +59,7 @@ class ActionProcessor(BaseProcessor): # 处理HFCloopObservation if hfc_obs: obs = hfc_obs - all_actions = obs.all_actions + all_actions = self.all_actions action_changes = await self.analyze_loop_actions(obs) if action_changes["add"] or action_changes["remove"]: # 合并动作变更 @@ -74,13 +67,13 @@ class ActionProcessor(BaseProcessor): merged_action_changes["remove"].extend(action_changes["remove"]) # 收集变更原因 - if action_changes["add"]: - reasons.append(f"添加动作{action_changes['add']}因为检测到大量无回复") - if action_changes["remove"]: - reasons.append(f"移除动作{action_changes['remove']}因为检测到连续回复") + # if action_changes["add"]: + # reasons.append(f"添加动作{action_changes['add']}因为检测到大量无回复") + # if action_changes["remove"]: + # reasons.append(f"移除动作{action_changes['remove']}因为检测到连续回复") # 处理ChattingObservation - if chat_obs and all_actions is not None: + if chat_obs : obs = chat_obs # 检查动作的关联类型 chat_context = chat_manager.get_stream(obs.chat_id).context @@ -98,14 +91,23 @@ class ActionProcessor(BaseProcessor): merged_action_changes["remove"].extend(type_mismatched_actions) reasons.append(f"移除动作{type_mismatched_actions}因为关联类型不匹配") + for action_name in merged_action_changes["add"]: + if action_name in self.action_manager.get_registered_actions(): + self.action_manager.add_action_to_using(action_name) + logger.debug(f"{self.log_prefix} 添加动作: {action_name}, 原因: {reasons}") + + for action_name in merged_action_changes["remove"]: + self.action_manager.remove_action_from_using(action_name) + logger.debug(f"{self.log_prefix} 移除动作: {action_name}, 原因: {reasons}") + # 如果有任何动作变更,设置到action_info中 - if merged_action_changes["add"] or merged_action_changes["remove"]: - action_info.set_action_changes(merged_action_changes) - action_info.set_reason(" | ".join(reasons)) + # if merged_action_changes["add"] or merged_action_changes["remove"]: + # action_info.set_action_changes(merged_action_changes) + # action_info.set_reason(" | ".join(reasons)) - processed_infos.append(action_info) + # processed_infos.append(action_info) - return processed_infos + # return processed_infos async def analyze_loop_actions(self, obs: HFCloopObservation) -> Dict[str, List[str]]: """分析最近的循环内容并决定动作的增减 diff --git a/src/chat/focus_chat/planners/planner.py b/src/chat/focus_chat/planners/planner.py index 61a33990..ab1c9f42 100644 --- a/src/chat/focus_chat/planners/planner.py +++ b/src/chat/focus_chat/planners/planner.py @@ -101,29 +101,26 @@ class ActionPlanner: # 获取观察信息 extra_info: list[str] = [] - # 首先处理动作变更 - for info in all_plan_info: - if isinstance(info, ActionInfo) and info.has_changes(): - add_actions = info.get_add_actions() - remove_actions = info.get_remove_actions() - reason = info.get_reason() - print(f"{self.log_prefix} 动作变更: {add_actions} {remove_actions} {reason}") + # # 首先处理动作变更 + # for info in all_plan_info: + # if isinstance(info, ActionInfo) and info.has_changes(): + # add_actions = info.get_add_actions() + # remove_actions = info.get_remove_actions() + # reason = info.get_reason() + # print(f"{self.log_prefix} 动作变更: {add_actions} {remove_actions} {reason}") - # 处理动作的增加 - for action_name in add_actions: - if action_name in self.action_manager.get_registered_actions(): - self.action_manager.add_action_to_using(action_name) - logger.debug(f"{self.log_prefix}添加动作: {action_name}, 原因: {reason}") + # # 处理动作的增加 + # for action_name in add_actions: + # if action_name in self.action_manager.get_registered_actions(): + # self.action_manager.add_action_to_using(action_name) + # logger.debug(f"{self.log_prefix}添加动作: {action_name}, 原因: {reason}") + + # # 处理动作的移除 + # for action_name in remove_actions: + # self.action_manager.remove_action_from_using(action_name) + # logger.debug(f"{self.log_prefix}移除动作: {action_name}, 原因: {reason}") - # 处理动作的移除 - for action_name in remove_actions: - self.action_manager.remove_action_from_using(action_name) - logger.debug(f"{self.log_prefix}移除动作: {action_name}, 原因: {reason}") - # 如果当前选择的动作被移除了,更新为no_reply - if action in remove_actions: - action = "no_reply" - reasoning = f"之前选择的动作{action}已被移除,原因: {reason}" # 继续处理其他信息 self_info = "" @@ -146,8 +143,8 @@ class ActionPlanner: elif isinstance(info, StructuredInfo): structured_info = info.get_processed_info() # print(f"structured_info: {structured_info}") - elif not isinstance(info, ActionInfo): # 跳过已处理的ActionInfo - extra_info.append(info.get_processed_info()) + # elif not isinstance(info, ActionInfo): # 跳过已处理的ActionInfo + # extra_info.append(info.get_processed_info()) # 获取当前可用的动作 current_available_actions = self.action_manager.get_using_actions() diff --git a/src/chat/heart_flow/observation/actions_observation.py b/src/chat/heart_flow/observation/actions_observation.py new file mode 100644 index 00000000..c840aece --- /dev/null +++ b/src/chat/heart_flow/observation/actions_observation.py @@ -0,0 +1,36 @@ +# 定义了来自外部世界的信息 +# 外部世界可以是某个聊天 不同平台的聊天 也可以是任意媒体 +from datetime import datetime +from src.common.logger_manager import get_logger +from src.chat.focus_chat.planners.action_manager import ActionManager + +logger = get_logger("observation") + +# 特殊的观察,专门用于观察动作 +# 所有观察的基类 +class ActionObservation: + def __init__(self, observe_id): + self.observe_info = "" + self.observe_id = observe_id + self.last_observe_time = datetime.now().timestamp() # 初始化为当前时间 + self.action_manager: ActionManager = None + + self.all_actions = {} + self.all_using_actions = {} + + def get_observe_info(self): + return self.observe_info + + + def set_action_manager(self, action_manager: ActionManager): + self.action_manager = action_manager + self.all_actions = self.action_manager.get_registered_actions() + + async def observe(self): + action_info_block = "" + self.all_using_actions = self.action_manager.get_using_actions() + for action_name, action_info in self.all_using_actions.items(): + action_info_block += f"\n{action_name}: {action_info.get('description', '')}" + action_info_block += f"\n注意,除了上面动作选项之外,你在群聊里不能做其他任何事情,这是你能力的边界\n" + + self.observe_info = action_info_block diff --git a/src/chat/heart_flow/observation/hfcloop_observation.py b/src/chat/heart_flow/observation/hfcloop_observation.py index 171aaeb7..43828bf7 100644 --- a/src/chat/heart_flow/observation/hfcloop_observation.py +++ b/src/chat/heart_flow/observation/hfcloop_observation.py @@ -17,9 +17,6 @@ class HFCloopObservation: self.observe_id = observe_id self.last_observe_time = datetime.now().timestamp() # 初始化为当前时间 self.history_loop: List[CycleDetail] = [] - self.action_manager: ActionManager = None - - self.all_actions = {} def get_observe_info(self): return self.observe_info @@ -27,10 +24,6 @@ class HFCloopObservation: def add_loop_info(self, loop_info: CycleDetail): self.history_loop.append(loop_info) - def set_action_manager(self, action_manager: ActionManager): - self.action_manager = action_manager - self.all_actions = self.action_manager.get_registered_actions() - async def observe(self): recent_active_cycles: List[CycleDetail] = [] for cycle in reversed(self.history_loop): diff --git a/template/template.env b/template/template.env index 3800e7d5..dd63a5f4 100644 --- a/template/template.env +++ b/template/template.env @@ -2,14 +2,16 @@ HOST=127.0.0.1 PORT=8000 #key and url -CHAT_ANY_WHERE_BASE_URL=https://api.chatanywhere.tech/v1 SILICONFLOW_BASE_URL=https://api.siliconflow.cn/v1/ DEEP_SEEK_BASE_URL=https://api.deepseek.com/v1 +CHAT_ANY_WHERE_BASE_URL=https://api.chatanywhere.tech/v1 +xxxxxxx_BASE_URL=https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx # 定义你要用的api的key(需要去对应网站申请哦) DEEP_SEEK_KEY= CHAT_ANY_WHERE_KEY= SILICONFLOW_KEY= +xxxxxxx_KEY= # 定义日志相关配置 @@ -22,8 +24,8 @@ CONSOLE_LOG_LEVEL=INFO # 自定义日志的默认文件输出日志级别 FILE_LOG_LEVEL=DEBUG -# 原生日志的控制台输出日志级别(nonebot就是这一类) +# 原生日志的控制台输出日志级别 DEFAULT_CONSOLE_LOG_LEVEL=SUCCESS -# 原生日志的默认文件输出日志级别(nonebot就是这一类) +# 原生日志的默认文件输出日志级别 DEFAULT_FILE_LOG_LEVEL=DEBUG diff --git a/tests/test_config.py b/tests/test_config.py deleted file mode 100644 index 1a123960..00000000 --- a/tests/test_config.py +++ /dev/null @@ -1,7 +0,0 @@ -from src.config.config import global_config - - -class TestConfig: - def test_load(self): - config = global_config - print(config)