diff --git a/src/chat/chat_loop/hfc_context.py b/src/chat/chat_loop/hfc_context.py index e6a4b31f3..fe5d283ae 100644 --- a/src/chat/chat_loop/hfc_context.py +++ b/src/chat/chat_loop/hfc_context.py @@ -5,6 +5,7 @@ from src.person_info.relationship_builder_manager import RelationshipBuilder from src.chat.express.expression_learner import ExpressionLearner from src.chat.planner_actions.action_manager import ActionManager from src.chat.chat_loop.hfc_utils import CycleDetail +from src.config.config import global_config if TYPE_CHECKING: from .sleep_manager.wakeup_manager import WakeUpManager @@ -64,7 +65,8 @@ class HfcContext: self.energy_manager: Optional["EnergyManager"] = None self.sleep_manager: Optional["SleepManager"] = None - self.focus_energy = 1 + # 从聊天流获取focus_energy,如果没有则使用配置文件中的值 + self.focus_energy = getattr(self.chat_stream, "focus_energy", global_config.chat.focus_value) self.no_reply_consecutive = 0 self.total_interest = 0.0 # breaking形式下的累积兴趣值 diff --git a/src/chat/message_receive/chat_stream.py b/src/chat/message_receive/chat_stream.py index b441ec5d3..77d1abb60 100644 --- a/src/chat/message_receive/chat_stream.py +++ b/src/chat/message_receive/chat_stream.py @@ -83,7 +83,8 @@ class ChatStream: self.sleep_pressure = data.get("sleep_pressure", 0.0) if data else 0.0 self.saved = False self.context: ChatMessageContext = None # type: ignore # 用于存储该聊天的上下文信息 - self.focus_energy = 1 + # 从配置文件中读取focus_value,如果没有则使用默认值1.0 + self.focus_energy = data.get("focus_energy", global_config.chat.focus_value) if data else global_config.chat.focus_value self.no_reply_consecutive = 0 self.breaking_accumulated_interest = 0.0 @@ -98,6 +99,7 @@ class ChatStream: "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, } @@ -360,6 +362,7 @@ class ChatManager: "group_name": group_info_d["group_name"] if group_info_d else "", "energy_value": s_data_dict.get("energy_value", 5.0), "sleep_pressure": s_data_dict.get("sleep_pressure", 0.0), + "focus_energy": s_data_dict.get("focus_energy", global_config.chat.focus_value), } # 根据数据库类型选择插入语句 @@ -421,6 +424,7 @@ class ChatManager: "last_active_time": model_instance.last_active_time, "energy_value": model_instance.energy_value, "sleep_pressure": model_instance.sleep_pressure, + "focus_energy": getattr(model_instance, "focus_energy", global_config.chat.focus_value), } loaded_streams_data.append(data_for_from_dict) session.commit() diff --git a/src/chat/replyer/default_generator.py b/src/chat/replyer/default_generator.py index b577f7499..7576ba38e 100644 --- a/src/chat/replyer/default_generator.py +++ b/src/chat/replyer/default_generator.py @@ -139,8 +139,6 @@ def init_prompt(): -------------------------------- {time_block} -{reply_target_block} - 注意不要复读你前面发过的内容,意思相近也不行。 请注意不要输出多余内容(包括前后缀,冒号和引号,at或 @等 )。只输出回复内容。 @@ -878,16 +876,22 @@ class DefaultReplyer: reply_message.get("user_id"), # type: ignore ) person_name = await person_info_manager.get_value(person_id, "person_name") - sender = person_name + + # 检查是否是bot自己的名字,如果是则替换为"(你)" + bot_user_id = str(global_config.bot.qq_account) + current_user_id = person_info_manager.get_value_sync(person_id, "user_id") + current_platform = reply_message.get("chat_info_platform") + + if current_user_id == bot_user_id and current_platform == global_config.bot.platform: + sender = f"{person_name}(你)" + else: + # 如果不是bot自己,直接使用person_name + sender = person_name target = reply_message.get("processed_plain_text") person_info_manager = get_person_info_manager() person_id = person_info_manager.get_person_id_by_person_name(sender) - user_id = person_info_manager.get_value_sync(person_id, "user_id") platform = chat_stream.platform - if user_id == global_config.bot.qq_account and platform == global_config.bot.platform: - logger.warning("选取了自身作为回复对象,跳过构建prompt") - return "" target = replace_user_references_sync(target, chat_stream.platform, replace_bot_name=True) diff --git a/src/chat/utils/prompt.py b/src/chat/utils/prompt.py index b5cf140c5..ae0c9c4b1 100644 --- a/src/chat/utils/prompt.py +++ b/src/chat/utils/prompt.py @@ -312,16 +312,15 @@ class Prompt: except asyncio.TimeoutError as e: logger.error(f"构建Prompt超时: {e}") - raise TimeoutError(f"构建Prompt超时: {e}") + raise TimeoutError(f"构建Prompt超时: {e}") from e except Exception as e: logger.error(f"构建Prompt失败: {e}") - raise RuntimeError(f"构建Prompt失败: {e}") + raise RuntimeError(f"构建Prompt失败: {e}") from e async def _build_context_data(self) -> Dict[str, Any]: """构建智能上下文数据""" # 并行执行所有构建任务 start_time = time.time() - timing_logs = {} try: # 准备构建任务 @@ -381,7 +380,6 @@ class Prompt: results = [] for i in range(0, len(tasks), max_concurrent_tasks): batch_tasks = tasks[i : i + max_concurrent_tasks] - batch_names = task_names[i : i + max_concurrent_tasks] batch_results = await asyncio.wait_for( asyncio.gather(*batch_tasks, return_exceptions=True), timeout=timeout_seconds @@ -520,13 +518,99 @@ class Prompt: async def _build_expression_habits(self) -> Dict[str, Any]: """构建表达习惯""" - # 简化的实现,完整实现需要导入相关模块 - return {"expression_habits_block": ""} + if not global_config.expression.enable_expression: + return {"expression_habits_block": ""} + + try: + from src.chat.express.expression_selector import ExpressionSelector + + # 获取聊天历史用于表情选择 + chat_history = "" + if self.parameters.message_list_before_now_long: + recent_messages = self.parameters.message_list_before_now_long[-10:] + chat_history = build_readable_messages( + recent_messages, + replace_bot_name=True, + timestamp_mode="normal", + truncate=True + ) + + # 创建表情选择器 + expression_selector = ExpressionSelector(self.parameters.chat_id) + + # 选择合适的表情 + selected_expressions = await expression_selector.select_suitable_expressions_llm( + chat_history=chat_history, + current_message=self.parameters.target, + emotional_tone="neutral", + topic_type="general" + ) + + # 构建表达习惯块 + if selected_expressions: + style_habits_str = "\n".join([f"- {expr}" for expr in selected_expressions]) + expression_habits_block = f"你可以参考以下的语言习惯,当情景合适就使用,但不要生硬使用,以合理的方式结合到你的回复中:\n{style_habits_str}" + else: + expression_habits_block = "" + + return {"expression_habits_block": expression_habits_block} + + except Exception as e: + logger.error(f"构建表达习惯失败: {e}") + return {"expression_habits_block": ""} async def _build_memory_block(self) -> Dict[str, Any]: """构建记忆块""" - # 简化的实现 - return {"memory_block": ""} + if not global_config.memory.enable_memory: + return {"memory_block": ""} + + try: + from src.chat.memory_system.memory_activator import MemoryActivator + from src.chat.memory_system.async_instant_memory_wrapper import async_memory + + # 获取聊天历史 + chat_history = "" + if self.parameters.message_list_before_now_long: + recent_messages = self.parameters.message_list_before_now_long[-20:] + chat_history = build_readable_messages( + recent_messages, + replace_bot_name=True, + timestamp_mode="normal", + truncate=True + ) + + # 激活长期记忆 + memory_activator = MemoryActivator() + running_memories = await memory_activator.activate_memory_with_chat_history( + chat_history=chat_history, + target_user=self.parameters.sender, + chat_id=self.parameters.chat_id + ) + + # 获取即时记忆 + instant_memory = await async_memory.get_memory_with_fallback( + chat_id=self.parameters.chat_id, + target_user=self.parameters.sender + ) + + # 构建记忆块 + memory_parts = [] + + if running_memories: + memory_parts.append("以下是当前在聊天中,你回忆起的记忆:") + for memory in running_memories: + memory_parts.append(f"- {memory['content']}") + + if instant_memory: + memory_parts.append(f"- {instant_memory}") + + memory_block = "\n".join(memory_parts) if memory_parts else "" + + return {"memory_block": memory_block} + + except Exception as e: + logger.error(f"构建记忆块失败: {e}") + return {"memory_block": ""} async def _build_relation_info(self) -> Dict[str, Any]: """构建关系信息""" @@ -539,13 +623,106 @@ class Prompt: async def _build_tool_info(self) -> Dict[str, Any]: """构建工具信息""" - # 简化的实现 - return {"tool_info_block": ""} + if not global_config.tool.enable_tool: + return {"tool_info_block": ""} + + try: + from src.plugin_system.core.tool_use import ToolExecutor + + # 获取聊天历史 + chat_history = "" + if self.parameters.message_list_before_now_long: + recent_messages = self.parameters.message_list_before_now_long[-15:] + chat_history = build_readable_messages( + recent_messages, + replace_bot_name=True, + timestamp_mode="normal", + truncate=True + ) + + # 创建工具执行器 + tool_executor = ToolExecutor() + + # 执行工具获取信息 + tool_results, _, _ = await tool_executor.execute_from_chat_message( + sender=self.parameters.sender, + target_message=self.parameters.target, + chat_history=chat_history, + return_details=False + ) + + # 构建工具信息块 + if tool_results: + tool_info_parts = ["以下是你通过工具获取到的实时信息:"] + for tool_result in tool_results: + tool_name = tool_result.get("tool_name", "unknown") + content = tool_result.get("content", "") + result_type = tool_result.get("type", "tool_result") + + tool_info_parts.append(f"- 【{tool_name}】{result_type}: {content}") + + tool_info_parts.append("以上是你获取到的实时信息,请在回复时参考这些信息。") + tool_info_block = "\n".join(tool_info_parts) + else: + tool_info_block = "" + + return {"tool_info_block": tool_info_block} + + except Exception as e: + logger.error(f"构建工具信息失败: {e}") + return {"tool_info_block": ""} async def _build_knowledge_info(self) -> Dict[str, Any]: """构建知识信息""" - # 简化的实现 - return {"knowledge_prompt": ""} + if not global_config.lpmm_knowledge.enable: + return {"knowledge_prompt": ""} + + try: + from src.chat.knowledge.knowledge_lib import QAManager + + # 获取问题文本(当前消息) + question = self.parameters.target or "" + if not question: + return {"knowledge_prompt": ""} + + # 创建QA管理器 + qa_manager = QAManager() + + # 搜索相关知识 + knowledge_results = await qa_manager.get_knowledge( + question=question, + chat_id=self.parameters.chat_id, + max_results=5, + min_similarity=0.5 + ) + + # 构建知识块 + if knowledge_results and knowledge_results.get("knowledge_items"): + knowledge_parts = ["以下是与你当前对话相关的知识信息:"] + + for item in knowledge_results["knowledge_items"]: + content = item.get("content", "") + source = item.get("source", "") + relevance = item.get("relevance", 0.0) + + if content: + if source: + knowledge_parts.append(f"- [{relevance:.2f}] {content} (来源: {source})") + else: + knowledge_parts.append(f"- [{relevance:.2f}] {content}") + + if knowledge_results.get("summary"): + knowledge_parts.append(f"\n知识总结: {knowledge_results['summary']}") + + knowledge_prompt = "\n".join(knowledge_parts) + else: + knowledge_prompt = "" + + return {"knowledge_prompt": knowledge_prompt} + + except Exception as e: + logger.error(f"构建知识信息失败: {e}") + return {"knowledge_prompt": ""} async def _build_cross_context(self) -> Dict[str, Any]: """构建跨群上下文"""