feat:新增麦麦好奇功能,优化记忆构建

pull/1273/head
SengokuCola 2025-09-29 23:46:49 +08:00
parent d519406e4a
commit e2310de6b5
20 changed files with 554 additions and 46 deletions

1
.gitignore vendored
View File

@ -324,6 +324,7 @@ run_pet.bat
!/plugins/emoji_manage_plugin
!/plugins/take_picture_plugin
!/plugins/deep_think
!/plugins/MaiFrequencyControl
!/plugins/__init__.py
config.toml

View File

@ -25,7 +25,7 @@ from src.plugin_system.core import events_manager
from src.plugin_system.apis import generator_api, send_api, message_api, database_api
from src.mais4u.mai_think import mai_thinking_manager
from src.mais4u.s4u_config import s4u_config
from src.chat.memory_system.Memory_chest import global_memory_chest
from src.memory_system.Memory_chest import global_memory_chest
from src.chat.utils.chat_message_builder import (
build_readable_messages_with_id,
get_raw_msg_before_timestamp_with_chat,

View File

@ -6,7 +6,7 @@ import re
from typing import List, Optional, Dict, Any, Tuple
from datetime import datetime
from src.chat.memory_system.Memory_chest import global_memory_chest
from src.memory_system.Memory_chest import global_memory_chest
from src.mais4u.mai_think import mai_thinking_manager
from src.common.logger import get_logger
from src.common.data_models.database_data_model import DatabaseMessages
@ -27,7 +27,7 @@ from src.chat.utils.chat_message_builder import (
)
from src.chat.express.expression_selector import expression_selector
# from src.chat.memory_system.memory_activator import MemoryActivator
# from src.memory_system.memory_activator import MemoryActivator
from src.person_info.person_info import Person
from src.plugin_system.base.component_types import ActionInfo, EventType
from src.plugin_system.apis import llm_api

View File

@ -6,7 +6,7 @@ import re
from typing import List, Optional, Dict, Any, Tuple
from datetime import datetime
from src.chat.memory_system.Memory_chest import global_memory_chest
from src.memory_system.Memory_chest import global_memory_chest
from src.mais4u.mai_think import mai_thinking_manager
from src.common.logger import get_logger
from src.common.data_models.database_data_model import DatabaseMessages
@ -27,7 +27,7 @@ from src.chat.utils.chat_message_builder import (
)
from src.chat.express.expression_selector import expression_selector
# from src.chat.memory_system.memory_activator import MemoryActivator
# from src.memory_system.memory_activator import MemoryActivator
from src.person_info.person_info import Person, is_person_known
from src.plugin_system.base.component_types import ActionInfo, EventType

View File

@ -1,5 +1,5 @@
from src.chat.utils.prompt_builder import Prompt
# from src.chat.memory_system.memory_activator import MemoryActivator
# from src.memory_system.memory_activator import MemoryActivator
def init_lpmm_prompt():

View File

@ -1,5 +1,5 @@
from src.chat.utils.prompt_builder import Prompt
# from src.chat.memory_system.memory_activator import MemoryActivator
# from src.memory_system.memory_activator import MemoryActivator
def init_rewrite_prompt():

View File

@ -326,6 +326,19 @@ class MemoryChest(BaseModel):
class Meta:
table_name = "memory_chest"
class MemoryConflict(BaseModel):
"""
用于存储记忆整合过程中冲突内容的模型
"""
conflict_content = TextField() # 冲突内容
answer = TextField(null=True) # 回答内容
create_time = FloatField() # 创建时间
update_time = FloatField() # 更新时间
class Meta:
table_name = "memory_conflicts"
@ -382,6 +395,7 @@ def create_tables():
GraphEdges, # 添加图边表
ActionRecords, # 添加 ActionRecords 到初始化列表
MemoryChest,
MemoryConflict, # 添加记忆冲突表
]
)
@ -410,6 +424,7 @@ def initialize_database(sync_constraints=False):
GraphEdges,
ActionRecords, # 添加 ActionRecords 到初始化列表
MemoryChest,
MemoryConflict,
]
try:
@ -508,6 +523,7 @@ def sync_field_constraints():
GraphEdges,
ActionRecords,
MemoryChest,
MemoryConflict,
]
try:
@ -692,6 +708,8 @@ def check_field_constraints():
GraphNodes,
GraphEdges,
ActionRecords,
MemoryChest,
MemoryConflict,
]
inconsistencies = {}

View File

@ -422,6 +422,7 @@ MODULE_COLORS = {
# s4u
"context_web_api": "\033[38;5;240m", # 深灰色
"S4U_chat": "\033[92m", # 深灰色
"conflict_tracker": "\033[38;5;82m", # 柔和的粉色,不显眼但保持粉色系
}
# 定义模块别名映射 - 将真实的logger名称映射到显示的别名

View File

@ -0,0 +1,245 @@
import time
import asyncio
from rich.traceback import install
from src.common.logger import get_logger
from src.common.database.database_model import MemoryConflict
from src.chat.utils.chat_message_builder import (
get_raw_msg_by_timestamp_with_chat,
build_readable_messages,
)
from src.llm_models.utils_model import LLMRequest
from src.config.config import model_config, global_config
logger = get_logger("conflict_tracker")
logger = get_logger("conflict_tracker")
install(extra_lines=3)
class QuestionTracker:
"""
用于跟踪一个问题在后续聊天中的解答情况
"""
def __init__(self, question: str, chat_id: str) -> None:
self.question = question
self.chat_id = chat_id
now = time.time()
self.start_time = now
self.last_read_time = now
self.active = True
# 将 LLM 实例作为类属性,使用 utils 模型
self.llm_request = LLMRequest(model_set=model_config.model_task_config.utils, request_type="conflict.judge")
def stop(self) -> None:
self.active = False
async def judge_answer(self, conversation_text: str) -> tuple[bool, str]:
"""
使用小模型判定问题是否已得到解答
返回 (已解答, 答案)
"""
prompt = (
"你是一个严谨的判定器。下面给出聊天记录以及一个问题。\n"
"任务:判断在这段聊天中,该问题是否已经得到明确解答。或从聊天内容中可以整理出答案\n"
"如果已解答请只输出YES: <简短答案>\n"
"如果没有请只输出NO\n\n"
f"问题:{self.question}\n"
"聊天记录如下:\n"
f"{conversation_text}"
)
if global_config.debug.show_prompt:
logger.info(f"判定提示词: {prompt}")
else:
logger.debug("已发送判定提示词")
result_text, _ = await self.llm_request.generate_response_async(prompt, temperature=0.2)
if not result_text:
return False, ""
logger.info(f"判定提示词: {prompt},问题: {self.question},result: {result_text}")
text = result_text.strip()
if text.upper().startswith("YES:"):
answer = text[4:].strip()
return True, answer
if text.upper().startswith("YES"):
# 兼容仅输出 YES 或 YES <answer>
answer = text[3:].strip().lstrip(":").strip()
return True, answer
return False, ""
class ConflictTracker:
"""
记忆整合冲突追踪器
用于记录和存储记忆整合过程中的冲突内容
"""
async def record_conflict(self, conflict_content: str, start_following: bool = False,chat_id: str = "") -> bool:
"""
记录冲突内容
Args:k
conflict_content: 冲突内容
Returns:
bool: 是否成功记录
"""
try:
if not conflict_content or conflict_content.strip() == "":
return False
# 若需要跟随后续消息以判断是否得到解答,则进入跟踪流程
if start_following and chat_id:
tracker = QuestionTracker(conflict_content.strip(), chat_id)
# 后台启动跟踪任务,避免阻塞
asyncio.create_task(self._follow_and_record(tracker, conflict_content.strip()))
return True
# 默认:直接记录,不进行跟踪
MemoryConflict.create(
conflict_content=conflict_content,
create_time=time.time(),
update_time=time.time(),
answer="",
)
logger.info(f"记录冲突内容: {len(conflict_content)} 字符")
return True
except Exception as e:
logger.error(f"记录冲突内容时出错: {e}")
return False
async def _follow_and_record(self, tracker: QuestionTracker, original_question: str) -> None:
"""
后台任务跟踪问题是否被解答并写入数据库
"""
try:
max_duration = 30 * 60 # 30 分钟
max_messages = 100 # 最多 100 条消息
poll_interval = 2.0 # 秒
while tracker.active:
now_ts = time.time()
# 终止条件:时长达到上限
if now_ts - tracker.start_time >= max_duration:
logger.info("问题跟踪达到30分钟上限判定为未解答")
break
# 统计最近一段是否有新消息(不过滤机器人,过滤命令)
recent_msgs = get_raw_msg_by_timestamp_with_chat(
chat_id=tracker.chat_id,
timestamp_start=tracker.last_read_time,
timestamp_end=now_ts,
limit=0,
limit_mode="latest",
filter_bot=False,
filter_command=True,
)
if len(recent_msgs) > 0:
tracker.last_read_time = now_ts
# 统计从开始到现在的总消息数用于触发100条上限
all_msgs = get_raw_msg_by_timestamp_with_chat(
chat_id=tracker.chat_id,
timestamp_start=tracker.start_time,
timestamp_end=now_ts,
limit=0,
limit_mode="latest",
filter_bot=False,
filter_command=True,
)
# 构建可读聊天文本
chat_text = build_readable_messages(
all_msgs,
replace_bot_name=True,
timestamp_mode="relative",
read_mark=0.0,
truncate=False,
show_actions=False,
show_pic=False,
remove_emoji_stickers=True,
)
# 让小模型判断是否有答案
answered, answer_text = await tracker.judge_answer(chat_text)
if answered:
logger.info("问题已得到解答,结束跟踪并写入答案")
tracker.stop()
MemoryConflict.create(
conflict_content=tracker.question,
create_time=tracker.start_time,
update_time=time.time(),
answer=answer_text or "",
)
return
if len(all_msgs) >= max_messages:
logger.info("问题跟踪达到100条消息上限判定为未解答")
break
# 无新消息时稍作等待
await asyncio.sleep(poll_interval)
# 未获取到答案,仅存储问题
MemoryConflict.create(
conflict_content=original_question,
create_time=time.time(),
update_time=time.time(),
answer="",
)
logger.info(f"记录冲突内容(未解答): {len(original_question)} 字符")
except Exception as e:
logger.error(f"后台问题跟踪任务异常: {e}")
async def record_memory_merge_conflict(self, part2_content: str) -> bool:
"""
记录记忆整合过程中的冲突内容part2
Args:
part2_content: 冲突内容part2
Returns:
bool: 是否成功记录
"""
if not part2_content or part2_content.strip() == "":
return False
return await self.record_conflict(part2_content)
async def get_all_conflicts(self) -> list:
"""
获取所有冲突记录
Returns:
list: 冲突记录列表
"""
try:
conflicts = list(MemoryConflict.select())
return conflicts
except Exception as e:
logger.error(f"获取冲突记录时出错: {e}")
return []
async def get_conflict_count(self) -> int:
"""
获取冲突记录数量
Returns:
int: 记录数量
"""
try:
return MemoryConflict.select().count()
except Exception as e:
logger.error(f"获取冲突记录数量时出错: {e}")
return 0
# 全局冲突追踪器实例
global_conflict_tracker = ConflictTracker()

View File

@ -13,9 +13,9 @@ from src.common.logger import get_logger
from src.common.server import get_global_server, Server
from src.mood.mood_manager import mood_manager
from src.chat.knowledge import lpmm_start_up
from src.chat.memory_system.Hippocampus import hippocampus_manager
from src.chat.memory_system.hippocampus_to_memory_chest_task import HippocampusToMemoryChestTask
from src.chat.memory_system.memory_management_task import MemoryManagementTask
from src.memory_system.Hippocampus import hippocampus_manager
from src.memory_system.hippocampus_to_memory_chest_task import HippocampusToMemoryChestTask
from src.memory_system.memory_management_task import MemoryManagementTask
from rich.traceback import install
from src.migrate_helper.migrate import check_and_run_migrations
# from src.api.main import start_api_server

View File

@ -2,7 +2,7 @@ import asyncio
import math
from typing import Tuple
from src.chat.memory_system.Hippocampus import hippocampus_manager
from src.memory_system.Hippocampus import hippocampus_manager
from src.chat.message_receive.message import MessageRecv, MessageRecvS4U
from maim_message.message_base import GroupInfo
from src.chat.message_receive.storage import MessageStorage

View File

@ -4,7 +4,7 @@ from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat
import time
from src.chat.utils.utils import get_recent_group_speaker
from src.chat.memory_system.Hippocampus import hippocampus_manager
from src.memory_system.Hippocampus import hippocampus_manager
import random
from datetime import datetime
import asyncio

View File

@ -99,19 +99,34 @@ class MemoryChest:
current_running_content = self.running_content_list[chat_id]["content"]
prompt = f"""
以下是你的记忆内容
以下是你的记忆内容和新的聊天记录请你将他们整合和修改
记忆内容
<memory_content>
{current_running_content}
</memory_content>
请将下面的新聊天记录内的有用的信息添加到你的记忆中
请主要关注概念和知识而不是聊天的琐事
重要你要关注的概念和知识必须是较为不常见的信息或者时效性较强的信息
不要关注常见的只是或者已经过时的信息
<聊天记录>
{message_str}
</聊天记录>
聊天记录中可能包含有效信息也可能信息密度很低请你根据聊天记录中的信息修改<part1>中的内容与<part2>中的内容
--------------------------------
请将上面的新聊天记录内的有用的信息进行整合到现有的记忆中
请主要关注概念和知识或者时效性较强的信息而不是聊天的琐事
1.不要关注诸如某个用户做了什么说了什么不要关注某个用户的行为而是关注其中的概念性信息
2.概念要求精确不啰嗦像科普读物或教育课本那样
3.如果有图片请只关注图片和文本结合的知识和概念性内容
记忆为一段纯文本逻辑清晰指出概念的含义并说明关系
请输出添加后的记忆内容不要输出其他内容
{message_str}
4.记忆为一段纯文本逻辑清晰指出概念的含义并说明关系
记忆内容的格式你必须仿照下面的格式但不一定全部使用:
[概念] [概念的含义(简短描述不超过十个字)]
[概念] 不是 [对概念的负面含义(简短描述不超过十个字)]
[概念1] [概念2] [概念1和概念2的关联(简短描述不超过二十个字)]
[概念1] 包含 [概念2] [概念3]
[概念1] 属于 [概念2]
......(不要包含中括号)
请仿照上述格式输出每个知识点一句话输出成一段平文本
现在请你输出,不要输出其他内容注意一定要直白白话口语化不要浮夸修辞
"""
if global_config.debug.show_prompt:
@ -120,7 +135,7 @@ class MemoryChest:
logger.debug(f"记忆仓库构建运行内容 prompt: {prompt}")
running_content, (reasoning_content, model_name, tool_calls) = await self.LLMRequest_build.generate_response_async(prompt)
print(f"记忆仓库构建运行内容: {running_content}")
# 如果有chat_id更新对应的running_content
@ -136,7 +151,7 @@ class MemoryChest:
"create_time": create_time
}
# 检查running_content长度是否大于500
# 检查running_content长度是否大于限制
if len(running_content) > self.memory_size_limit:
await self._save_to_database_and_clear(chat_id, running_content)
@ -147,8 +162,7 @@ class MemoryChest:
f"内容大小 {len(running_content)} 达到限制的 {int(self.memory_size_limit * 0.3)} 字符,强制保存")
await self._save_to_database_and_clear(chat_id, running_content)
return running_content
@ -478,6 +492,54 @@ class MemoryChest:
logger.error(f"根据标题查找记忆时出错: {e}")
return []
def _parse_merged_parts(self, merged_response: str) -> tuple[str, str]:
"""
解析合并记忆的part1和part2内容
Args:
merged_response: LLM返回的合并记忆响应
Returns:
tuple[str, str]: (part1_content, part2_content)
"""
try:
# 使用正则表达式提取part1和part2内容
import re
# 提取part1内容
part1_pattern = r'<part1>(.*?)</part1>'
part1_match = re.search(part1_pattern, merged_response, re.DOTALL)
part1_content = part1_match.group(1).strip() if part1_match else ""
# 提取part2内容
part2_pattern = r'<part2>(.*?)</part2>'
part2_match = re.search(part2_pattern, merged_response, re.DOTALL)
part2_content = part2_match.group(1).strip() if part2_match else ""
# 检查是否包含none或None不区分大小写
def is_none_content(content: str) -> bool:
if not content:
return True
# 检查是否只包含"none"或"None"(不区分大小写)
return re.match(r'^\s*none\s*$', content, re.IGNORECASE) is not None
# 如果包含none则设置为空字符串
if is_none_content(part1_content):
part1_content = ""
logger.info("part1内容为none设置为空")
if is_none_content(part2_content):
part2_content = ""
logger.info("part2内容为none设置为空")
logger.info(f"解析合并记忆结果: part1={len(part1_content)}字符, part2={len(part2_content)}字符")
return part1_content, part2_content
except Exception as e:
logger.error(f"解析合并记忆part1/part2时出错: {e}")
return "", ""
def _parse_merge_target_json(self, json_text: str) -> list[str]:
"""
解析choose_merge_target生成的JSON响应
@ -542,19 +604,35 @@ class MemoryChest:
content += f"{memory}\n"
prompt = f"""
以下是多段记忆内容请将它们合并成一段记忆
以下是多段记忆内容请将它们进行整合和修改
{content}
请将下面的多段记忆内容合并成一段记忆
--------------------------------
请将上面的多段记忆内容合并成两部分内容第一部分是可以整合不冲突的概念和知识第二部分是相互有冲突的概念和知识
请主要关注概念和知识而不是聊天的琐事
重要你要关注的概念和知识必须是较为不常见的信息或者时效性较强的信息
不要关注常见的只是或者已经过时的信息
1.不要关注诸如某个用户做了什么说了什么不要关注某个用户的行为而是关注其中的概念性信息
2.概念要求精确不啰嗦像科普读物或教育课本那样
3.如果有图片请只关注图片和文本结合的知识和概念性内容
4.如果记忆中有冲突的地方可以进行整合如果无法整合需要在此处标注存在冲突的不同信息
记忆为一段纯文本逻辑清晰指出概念的含义并说明关系
请输出合并的记忆内容不要输出其他内容
4.记忆为一段纯文本逻辑清晰指出概念的含义并说明关系
**第一部分**
1.如果两个概念在描述同一件事情且相互之间逻辑不冲突请你严格判断且相互之间没有矛盾请将它们整合成一个概念并输出到第一部分
2.如果某个概念在时间上更新了另一个概念请用新概念更新就概念来整合并输出到第一部分
3.如果没有可整合的概念请你输出none
**第二部分**
1.如果记忆中有无法整合的地方例如概念不一致有逻辑上的冲突请你输出到第二部分
2.如果两个概念在描述同一件事情但相互之间逻辑冲突请将它们输出到第二部分
3.如果没有无法整合的概念请你输出none
**输出格式要求**
请你按以下格式输出
<part1>
第一部分内容整合后的概念如果第一部分为none请输出none
</part1>
<part2>
第二部分内容无法整合冲突的概念如果第二部分为none请输出none
</part2>
不要输出其他内容现在请你输出,不要输出其他内容注意一定要直白白话口语化不要浮夸修辞
"""
if global_config.debug.show_prompt:
@ -564,18 +642,33 @@ class MemoryChest:
merged_memory, (reasoning_content, model_name, tool_calls) = await self.LLMRequest_build.generate_response_async(prompt)
# 生成合并后的标题
merged_title = await self._generate_title_for_merged_memory(merged_memory)
# 保存合并后的记忆到数据库
MemoryChestModel.create(
title=merged_title,
content=merged_memory
)
logger.info(f"合并记忆已保存: {merged_title}")
return merged_title, merged_memory
# 解析part1和part2
part1_content, part2_content = self._parse_merged_parts(merged_memory)
# 处理part2独立记录冲突内容无论part1是否为空
if part2_content and part2_content.strip() != "none":
logger.info(f"合并记忆part2记录冲突内容: {len(part2_content)} 字符")
# 导入冲突追踪器
from src.curiousity.questions import global_conflict_tracker
# 记录冲突到数据库
await global_conflict_tracker.record_memory_merge_conflict(part2_content)
# 处理part1生成标题并保存
if part1_content and part1_content.strip() != "none":
merged_title = await self._generate_title_for_merged_memory(part1_content)
# 保存part1到数据库
MemoryChestModel.create(
title=merged_title,
content=part1_content
)
logger.info(f"合并记忆part1已保存: {merged_title}")
return merged_title, part1_content
else:
logger.warning("合并记忆part1为空跳过保存")
return "", ""
except Exception as e:
logger.error(f"合并记忆时出错: {e}")
return "", ""

View File

@ -5,7 +5,7 @@ import re
from typing import List
from src.manager.async_task_manager import AsyncTask
from src.chat.memory_system.Hippocampus import hippocampus_manager
from src.memory_system.Hippocampus import hippocampus_manager
from src.common.logger import get_logger
logger = get_logger("hippocampus_to_memory_chest")

View File

@ -4,7 +4,7 @@ import random
from typing import List
from src.manager.async_task_manager import AsyncTask
from src.chat.memory_system.Memory_chest import global_memory_chest
from src.memory_system.Memory_chest import global_memory_chest
from src.common.logger import get_logger
from src.common.database.database_model import MemoryChest as MemoryChestModel
from src.config.config import global_config

View File

@ -0,0 +1,34 @@
{
"manifest_version": 1,
"name": "MaiCurious插件 (MaiCurious Actions)",
"version": "1.0.0",
"description": "可以好奇",
"author": {
"name": "SengokuCola",
"url": "https://github.com/MaiM-with-u"
},
"license": "GPL-v3.0-or-later",
"host_application": {
"min_version": "0.11.0"
},
"homepage_url": "https://github.com/MaiM-with-u/maibot",
"repository_url": "https://github.com/MaiM-with-u/maibot",
"keywords": ["curious", "action", "built-in"],
"categories": ["Deep Think"],
"default_locale": "zh-CN",
"locales_path": "_locales",
"plugin_info": {
"is_built_in": true,
"plugin_type": "action_provider",
"components": [
{
"type": "action",
"name": "maicurious",
"description": "发送好奇"
}
]
}
}

View File

@ -0,0 +1,116 @@
from typing import List, Tuple, Type, Any
# 导入新插件系统
from src.plugin_system import BasePlugin, register_plugin, ComponentInfo
from src.plugin_system.base.config_types import ConfigField
from src.person_info.person_info import Person
from src.plugin_system.base.base_tool import BaseTool, ToolParamType
# 导入依赖的系统组件
from src.common.logger import get_logger
from src.plugins.built_in.relation.relation import BuildRelationAction
from src.plugin_system.apis import llm_api
from src.plugin_system.base.base_action import BaseAction
from src.plugin_system.base.component_types import ActionActivationType
from src.plugin_system.apis import config_api
from src.plugin_system.apis import frequency_api
from src.plugin_system.apis import generator_api
from src.curiousity.questions import global_conflict_tracker
logger = get_logger("relation_actions")
class CuriousAction(BaseAction):
"""频率调节动作 - 调整聊天发言频率"""
activation_type = ActionActivationType.LLM_JUDGE
parallel_action = False
# 动作基本信息
action_name = "question"
action_description = "对现有的存在疑问的信息生成一个问题"
# 动作参数定义
action_parameters = {
"question": "存在疑问的信息,提出一个问题",
}
# 动作使用场景
bot_name = config_api.get_global_config("bot.nickname")
action_require = [
f"当聊天记录中的信息存在逻辑上的矛盾时使用",
f"当有人反对或否定你提出的信息时使用",
f"或当你对现有的信息存在疑问时使用",
]
# 关联类型
associated_types = ["text"]
async def execute(self) -> Tuple[bool, str]:
"""执行频率调节动作"""
try:
question = self.action_data.get("question", "")
# 存储问题到冲突追踪器
if question:
await global_conflict_tracker.record_conflict(conflict_content=question, start_following=True,chat_id=self.chat_id)
logger.info(f"已存储问题到冲突追踪器: {len(question)} 字符")
await self.store_action_info(
action_build_into_prompt=True,
action_prompt_display=f"你产生了一个问题,原因:{question},尝试向其他人提问或回忆吧",
action_done=True,
)
return True, "问题已记录"
except Exception as e:
error_msg = f"问题生成失败: {str(e)}"
logger.error(f"{self.log_prefix} {error_msg}", exc_info=True)
await self.send_text("问题生成失败")
return False, error_msg
@register_plugin
class CuriousPlugin(BasePlugin):
"""关系动作插件
系统内置插件提供基础的聊天交互功能
- Reply: 回复动作
- NoReply: 不回复动作
- Emoji: 表情动作
注意插件基本信息优先从_manifest.json文件中读取
"""
# 插件基本信息
plugin_name: str = "maicurious" # 内部标识符
enable_plugin: bool = True
dependencies: list[str] = [] # 插件依赖列表
python_dependencies: list[str] = [] # Python包依赖列表
config_file_name: str = "config.toml"
# 配置节描述
config_section_descriptions = {
"plugin": "插件启用配置",
"components": "核心组件启用配置",
}
# 配置Schema定义
config_schema: dict = {
"plugin": {
"enabled": ConfigField(type=bool, default=False, description="是否启用插件"),
"config_version": ConfigField(type=str, default="3.0.0", description="配置文件版本"),
}
}
def get_plugin_components(self) -> List[Tuple[ComponentInfo, Type]]:
"""返回插件包含的组件列表"""
# --- 根据配置注册组件 ---
components = []
components.append((CuriousAction.get_action_info(), CuriousAction))
return components

View File

@ -5,9 +5,9 @@ from src.config.config import global_config
from src.chat.utils.prompt_builder import Prompt
from src.llm_models.payload_content.tool_option import ToolParamType
from src.plugin_system import BaseAction, ActionActivationType
from src.chat.memory_system.Hippocampus import hippocampus_manager
from src.memory_system.Hippocampus import hippocampus_manager
from src.chat.utils.utils import cut_key_words
from src.chat.memory_system.Memory_chest import global_memory_chest
from src.memory_system.Memory_chest import global_memory_chest
from src.plugin_system.base.base_tool import BaseTool
from typing import Any