diff --git a/changelogs/changelog.md b/changelogs/changelog.md index c12e726b..690f797d 100644 --- a/changelogs/changelog.md +++ b/changelogs/changelog.md @@ -1,5 +1,11 @@ # Changelog +## [0.11.7] - 2025-12-2 +- 增加麦麦做梦功能 + +- 添加全局记忆配置项 + + ## [0.11.6] - 2025-12-2 ### 🌟 重大更新 - 大幅提高记忆检索能力,略微提高token消耗 diff --git a/dummy b/dummy new file mode 100644 index 00000000..5cae3661 --- /dev/null +++ b/dummy @@ -0,0 +1,10 @@ +{ + "cells": [], + "metadata": { + "language_info": { + "name": "python" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} \ No newline at end of file diff --git a/src/chat/replyer/group_generator.py b/src/chat/replyer/group_generator.py index 18812cce..a37925c2 100644 --- a/src/chat/replyer/group_generator.py +++ b/src/chat/replyer/group_generator.py @@ -256,7 +256,7 @@ class DefaultReplyer: logger.debug(f"使用处理器选中的{len(selected_expressions)}个表达方式") for expr in selected_expressions: if isinstance(expr, dict) and "situation" in expr and "style" in expr: - style_habits.append(f"当{expr['situation']}时,使用 {expr['style']}") + style_habits.append(f"当{expr['situation']}时:{expr['style']}") else: logger.debug("没有从处理器获得表达方式,将使用空的表达方式") # 不再在replyer中进行随机选择,全部交给处理器处理 diff --git a/src/chat/replyer/private_generator.py b/src/chat/replyer/private_generator.py index ecba37f9..726ce4b2 100644 --- a/src/chat/replyer/private_generator.py +++ b/src/chat/replyer/private_generator.py @@ -271,7 +271,7 @@ class PrivateReplyer: logger.debug(f"使用处理器选中的{len(selected_expressions)}个表达方式") for expr in selected_expressions: if isinstance(expr, dict) and "situation" in expr and "style" in expr: - style_habits.append(f"当{expr['situation']}时,使用 {expr['style']}") + style_habits.append(f"当{expr['situation']}时:{expr['style']}") else: logger.debug("没有从处理器获得表达方式,将使用空的表达方式") # 不再在replyer中进行随机选择,全部交给处理器处理 diff --git a/src/chat/replyer/prompt/replyer_prompt.py b/src/chat/replyer/prompt/replyer_prompt.py index f9ee25a4..c1c89124 100644 --- a/src/chat/replyer/prompt/replyer_prompt.py +++ b/src/chat/replyer/prompt/replyer_prompt.py @@ -19,7 +19,7 @@ def init_replyer_prompt(): {planner_reasoning} {identity} {chat_prompt}你正在群里聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state} -尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。 +尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理。 {reply_style} 请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出一句回复内容就好。 不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。 @@ -39,7 +39,7 @@ def init_replyer_prompt(): {planner_reasoning} {identity} {chat_prompt}你正在和{sender_name}聊天,现在请你读读之前的聊天记录,然后给出日常且口语化的回复,平淡一些,{mood_state} -尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理,可以有个性。 +尽量简短一些。{keywords_reaction_prompt}请注意把握聊天内容,不要回复的太有条理。 {reply_style} 请注意不要输出多余内容(包括前后缀,冒号和引号,括号,表情等),只输出回复内容。 {moderation_prompt}不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。""", diff --git a/src/config/official_configs.py b/src/config/official_configs.py index e7fce623..2def18f2 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -247,6 +247,9 @@ class MemoryConfig(ConfigBase): enable_jargon_detection: bool = True """记忆检索过程中是否启用黑话识别""" + global_memory: bool = False + """是否允许记忆检索在聊天记录中进行全局查询(忽略当前chat_id,仅对 search_chat_history 等工具生效)""" + def __post_init__(self): """验证配置值""" if self.max_agent_iterations < 1: @@ -726,9 +729,14 @@ class DreamConfig(ConfigBase): max_iterations: int = 20 """做梦最大轮次,默认20轮""" + first_delay_seconds: int = 60 + """程序启动后首次做梦前的延迟时间(秒),默认60秒""" + def __post_init__(self): """验证配置值""" if self.interval_minutes < 1: raise ValueError(f"interval_minutes 必须至少为1,当前值: {self.interval_minutes}") if self.max_iterations < 1: - raise ValueError(f"max_iterations 必须至少为1,当前值: {self.max_iterations}") \ No newline at end of file + raise ValueError(f"max_iterations 必须至少为1,当前值: {self.max_iterations}") + if self.first_delay_seconds < 0: + raise ValueError(f"first_delay_seconds 不能为负数,当前值: {self.first_delay_seconds}") \ No newline at end of file diff --git a/src/express/expression_learner.py b/src/express/expression_learner.py index 0c335488..c18f3b6d 100644 --- a/src/express/expression_learner.py +++ b/src/express/expression_learner.py @@ -40,9 +40,9 @@ def init_prompt() -> None: [ {{"situation": "AAAAA", "style": "BBBBB", "source_id": "3"}}, {{"situation": "CCCC", "style": "DDDD", "source_id": "7"}} - {{"situation": "对某件事表示十分惊叹", "style": "我嘞个xxxx", "source_id": "[消息编号]"}}, + {{"situation": "对某件事表示十分惊叹", "style": "使用 我嘞个xxxx", "source_id": "[消息编号]"}}, {{"situation": "表示讽刺的赞同,不讲道理", "style": "对对对", "source_id": "[消息编号]"}}, - {{"situation": "当涉及游戏相关时,夸赞,略带戏谑意味", "style": "这么强!", "source_id": "[消息编号]"}}, + {{"situation": "当涉及游戏相关时,夸赞,略带戏谑意味", "style": "使用 这么强!", "source_id": "[消息编号]"}}, ] 请注意: diff --git a/src/main.py b/src/main.py index 03580008..d2ca213b 100644 --- a/src/main.py +++ b/src/main.py @@ -108,7 +108,7 @@ class MainSystem: await async_task_manager.add_task(TelemetryHeartBeatTask()) # 添加记忆遗忘任务 - from src.chat.utils.memory_forget_task import MemoryForgetTask + from src.hippo_memorizer.memory_forget_task import MemoryForgetTask await async_task_manager.add_task(MemoryForgetTask()) diff --git a/src/memory_system/retrieval_tools/query_chat_history.py b/src/memory_system/retrieval_tools/query_chat_history.py index 097632c4..0d2d2cc7 100644 --- a/src/memory_system/retrieval_tools/query_chat_history.py +++ b/src/memory_system/retrieval_tools/query_chat_history.py @@ -5,11 +5,13 @@ import json from typing import Optional +from datetime import datetime + from src.common.logger import get_logger from src.common.database.database_model import ChatHistory from src.chat.utils.utils import parse_keywords_string +from src.config.config import global_config from .tool_registry import register_memory_retrieval_tool -from datetime import datetime logger = get_logger("memory_retrieval_tools") @@ -33,7 +35,18 @@ async def search_chat_history( return "未指定查询参数(需要提供keyword或participant之一)" # 构建查询条件 - query = ChatHistory.select().where(ChatHistory.chat_id == chat_id) + # 根据配置决定是否限制在当前 chat_id 内查询 + use_global_search = global_config.memory.global_memory + + if use_global_search: + # 全局查询所有聊天记录 + query = ChatHistory.select() + logger.debug( + f"search_chat_history 启用全局查询模式,忽略 chat_id 过滤,keyword={keyword}, participant={participant}" + ) + else: + # 仅在当前聊天流内查询 + query = ChatHistory.select().where(ChatHistory.chat_id == chat_id) # 执行查询 records = list(query.order_by(ChatHistory.start_time.desc()).limit(50)) @@ -139,9 +152,45 @@ async def search_chat_history( else: return "未找到相关聊天记录" - # 构建结果文本,返回id、theme和keywords + # 如果匹配结果超过20条,不返回具体记录,只返回提示和所有相关关键词 + if len(filtered_records) > 20: + # 统计所有记录上的关键词并去重 + all_keywords_set = set() + for record in filtered_records: + if record.keywords: + try: + keywords_data = ( + json.loads(record.keywords) + if isinstance(record.keywords, str) + else record.keywords + ) + if isinstance(keywords_data, list): + for k in keywords_data: + k_str = str(k).strip() + if k_str: + all_keywords_set.add(k_str) + except (json.JSONDecodeError, TypeError, ValueError): + continue + + # xxx 使用用户原始查询词,优先 keyword,其次 participant,最后退化成“当前条件” + search_label = keyword or participant or "当前条件" + + if all_keywords_set: + keywords_str = "、".join(sorted(all_keywords_set)) + return ( + f"包含“{search_label}”的结果过多,请尝试更多关键词精确查找\n\n" + f"有关\"{search_label}\"的关键词:\n" + f"{keywords_str}" + ) + else: + return ( + f"包含“{search_label}”的结果过多,请尝试更多关键词精确查找\n\n" + f"有关\"{search_label}\"的关键词信息为空" + ) + + # 构建结果文本,返回id、theme和keywords(最多20条) results = [] - for record in filtered_records[:20]: # 最多返回20条记录 + for record in filtered_records[:20]: result_parts = [] # 添加记忆ID @@ -173,9 +222,6 @@ async def search_chat_history( return "未找到相关聊天记录" response_text = "\n\n---\n\n".join(results) - if len(filtered_records) > 20: - omitted_count = len(filtered_records) - 20 - response_text += f"\n\n(还有{omitted_count}条记录已省略,可使用记忆ID查询详细信息)" return response_text except Exception as e: diff --git a/template/bot_config_template.toml b/template/bot_config_template.toml index 465ab682..2832ba93 100644 --- a/template/bot_config_template.toml +++ b/template/bot_config_template.toml @@ -1,5 +1,5 @@ [inner] -version = "7.0.0" +version = "7.0.1" #----以下是给开发人员阅读的,如果你只是部署了麦麦,不需要阅读---- # 如果你想要修改配置文件,请递增version的值 @@ -110,10 +110,12 @@ include_planner_reasoning = false # 是否将planner推理加入replyer,默认 [memory] max_agent_iterations = 3 # 记忆思考深度(最低为1(不深入思考)) enable_jargon_detection = true # 记忆检索过程中是否启用黑话识别 +global_memory = false # 是否允许记忆检索进行全局查询 [dream] -interval_minutes = 30 # 做梦时间间隔(分钟),默认30分钟 +interval_minutes = 45 # 做梦时间间隔(分钟),默认30分钟 max_iterations = 20 # 做梦最大轮次,默认20轮 +first_delay_seconds = 1200 # 程序启动后首次做梦前的延迟时间(秒),默认60秒 [jargon] all_global = true # 是否开启全局黑话模式,注意,此功能关闭后,已经记录的全局黑话不会改变,需要手动删除