remove:无用配置,整理配置文件

This commit is contained in:
SengokuCola
2026-04-07 14:30:23 +08:00
parent 50a51757a8
commit f2b64cc58c
17 changed files with 159 additions and 1654 deletions

View File

@@ -27,14 +27,15 @@ from .official_configs import (
MaiSakaConfig,
MaimMessageConfig,
MCPConfig,
PluginRuntimeConfig,
MemoryConfig,
MessageReceiveConfig,
PersonalityConfig,
PluginRuntimeConfig,
RelationshipConfig,
ResponsePostProcessConfig,
ResponseSplitterConfig,
TelemetryConfig,
VisualConfig,
VoiceConfig,
WebUIConfig,
)
@@ -55,7 +56,7 @@ CONFIG_DIR: Path = PROJECT_ROOT / "config"
BOT_CONFIG_PATH: Path = (CONFIG_DIR / "bot_config.toml").resolve().absolute()
MODEL_CONFIG_PATH: Path = (CONFIG_DIR / "model_config.toml").resolve().absolute()
MMC_VERSION: str = "1.0.0"
CONFIG_VERSION: str = "8.3.4"
CONFIG_VERSION: str = "8.4.1"
MODEL_CONFIG_VERSION: str = "1.13.1"
logger = get_logger("config")
@@ -73,6 +74,9 @@ class Config(ConfigBase):
personality: PersonalityConfig = Field(default_factory=PersonalityConfig)
"""人格配置类"""
visual: VisualConfig = Field(default_factory=VisualConfig)
"""视觉配置类"""
expression: ExpressionConfig = Field(default_factory=ExpressionConfig)
"""表达配置类"""
@@ -474,6 +478,10 @@ def load_config_from_file(
if env_migration.migrated:
logger.warning(f"检测到旧版环境变量绑定配置,已迁移到主配置: {env_migration.reason}")
config_data = env_migration.data
legacy_migration = try_migrate_legacy_bot_config_dict(config_data)
if legacy_migration.migrated:
logger.warning(t("config.legacy_migrated", reason=legacy_migration.reason))
config_data = legacy_migration.data
# 保留一份“干净”的原始数据副本,避免第一次 from_dict 过程中对 dict 的就地修改
original_data: dict[str, Any] = copy.deepcopy(config_data)
try:

View File

@@ -75,6 +75,18 @@ def _migrate_env_value(section: dict[str, Any], key: str, parsed_env_value: Any,
return True
def _move_section_key(source: dict[str, Any], target: dict[str, Any], key: str) -> bool:
"""将配置项从旧分组移动到新分组,若新分组已有值则保留新值。"""
if key not in source:
return False
if key not in target:
target[key] = source[key]
source.pop(key, None)
return True
def _parse_triplet_target(s: str) -> Optional[dict[str, str]]:
"""
解析 "platform:id:type" -> {platform,item_id,rule_type}
@@ -273,6 +285,21 @@ def _migrate_extra_prompt_list(exp: dict[str, Any], key: str) -> bool:
return True
def _parse_multimodal_replyer(v: Any) -> Optional[bool]:
"""兼容旧 replyer_generator_type 到布尔开关的迁移。"""
if isinstance(v, bool):
return v
if not isinstance(v, str):
return None
normalized_value = v.strip().lower()
if normalized_value == "multimodal":
return True
if normalized_value == "legacy":
return False
return None
def migrate_legacy_bind_env_to_bot_config_dict(data: dict[str, Any]) -> MigrationResult:
"""将旧版环境变量中的绑定地址迁移到主配置结构。"""
@@ -351,12 +378,61 @@ def try_migrate_legacy_bot_config_dict(data: dict[str, Any]) -> MigrationResult:
migrated_any = True
reasons.append("chat.private_plan_style_removed")
personality = _as_dict(data.get("personality"))
visual = _as_dict(data.get("visual"))
if visual is None and (
(personality is not None and "visual_style" in personality)
or "multimodal_planner" in chat
or "replyer_generator_type" in chat
):
visual = {}
data["visual"] = visual
if visual is not None and personality is not None and "visual_style" in personality:
if "visual_style" not in visual:
visual["visual_style"] = personality["visual_style"]
personality.pop("visual_style", None)
migrated_any = True
reasons.append("personality.visual_style_moved_to_visual.visual_style")
if visual is not None and "multimodal_planner" in chat:
if "multimodal_planner" not in visual and isinstance(chat["multimodal_planner"], bool):
visual["multimodal_planner"] = chat["multimodal_planner"]
if "multimodal_planner" in visual:
chat.pop("multimodal_planner", None)
migrated_any = True
reasons.append("chat.multimodal_planner_moved_to_visual.multimodal_planner")
if visual is not None and "replyer_generator_type" in chat:
multimodal_replyer = _parse_multimodal_replyer(chat["replyer_generator_type"])
if "multimodal_replyer" not in visual and multimodal_replyer is not None:
visual["multimodal_replyer"] = multimodal_replyer
if "multimodal_replyer" in visual:
chat.pop("replyer_generator_type", None)
migrated_any = True
reasons.append("chat.replyer_generator_type_moved_to_visual.multimodal_replyer")
maisaka = _as_dict(data.get("maisaka"))
mem = _as_dict(data.get("memory"))
if maisaka is not None:
moved_memory_keys = ("enable_memory_query_tool", "memory_query_default_limit")
if any(key in maisaka for key in moved_memory_keys) and mem is None:
mem = {}
data["memory"] = mem
if mem is not None:
for moved_key in moved_memory_keys:
if _move_section_key(maisaka, mem, moved_key):
migrated_any = True
reasons.append(f"maisaka.{moved_key}_moved_to_memory")
if mem is not None:
if _migrate_target_item_list(mem, "global_memory_blacklist"):
migrated_any = True
reasons.append("memory.global_memory_blacklist")
for removed_key in (
"agent_timeout_seconds",
"global_memory",
"global_memory_blacklist",
"max_agent_iterations",
):
if removed_key in mem:

View File

@@ -113,15 +113,6 @@ class PersonalityConfig(ConfigBase):
)
"""每次构建回复时,从 multiple_reply_style 中随机替换 reply_style 的概率0.0-1.0"""
visual_style: str = Field(
default="请用中文描述这张图片的内容。如果有文字请把文字描述概括出来请留意其主题直观感受输出为一段平文本最多30字请注意不要分点就输出一段文本",
json_schema_extra={
"x-widget": "textarea",
"x-icon": "image",
},
)
"""_wrap_识图提示词不建议修改"""
states: list[str] = Field(
default_factory=lambda: [
"是一个女大学生,喜欢上网聊天,会刷小红书。",
@@ -148,6 +139,40 @@ class PersonalityConfig(ConfigBase):
"""状态概率每次构建人格时替换personality的概率"""
class VisualConfig(ConfigBase):
"""视觉配置类"""
__ui_label__ = "视觉"
__ui_icon__ = "image"
multimodal_planner: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "image",
},
)
"""是否直接输入图片"""
multimodal_replyer: bool = Field(
default=False,
json_schema_extra={
"x-widget": "switch",
"x-icon": "git-branch",
},
)
"""是否启用 Maisaka 多模态 replyer 生成器"""
visual_style: str = Field(
default="请用中文描述这张图片的内容。如果有文字请把文字描述概括出来请留意其主题直观感受输出为一段平文本最多30字请注意不要分点就输出一段文本",
json_schema_extra={
"x-widget": "textarea",
"x-icon": "image",
},
)
"""_wrap_识图提示词不建议修改"""
class RelationshipConfig(ConfigBase):
"""关系配置类"""
@@ -253,24 +278,6 @@ class ChatConfig(ConfigBase):
},
)
multimodal_planner: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "image",
},
)
"""是否直接输入图片"""
replyer_generator_type: Literal["legacy", "multimodal"] = Field(
default="legacy",
json_schema_extra={
"x-widget": "select",
"x-icon": "git-branch",
},
)
"""Maisaka replyer 生成器类型legacy旧版单 prompt/ multimodal多模态版适合主循环直接展示图片"""
enable_talk_value_rules: bool = Field(
default=True,
json_schema_extra={
@@ -373,24 +380,6 @@ class MemoryConfig(ConfigBase):
__ui_parent__ = "emoji"
max_agent_iterations: int = Field(
default=5,
ge=1,
json_schema_extra={
"x-widget": "input",
"x-icon": "layers",
},
)
"""记忆思考深度最低为1"""
agent_timeout_seconds: float = Field(
default=120.0,
json_schema_extra={
"x-widget": "input",
"x-icon": "clock",
},
)
"""最长回忆时间(秒)"""
global_memory: bool = Field(
default=False,
@@ -410,6 +399,26 @@ class MemoryConfig(ConfigBase):
)
"""_wrap_全局记忆黑名单当启用全局记忆时不将特定聊天流纳入检索"""
enable_memory_query_tool: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "database",
},
)
"""是否启用 Maisaka 内置长期记忆检索工具 query_memory"""
memory_query_default_limit: int = Field(
default=5,
ge=1,
le=20,
json_schema_extra={
"x-widget": "input",
"x-icon": "hash",
},
)
"""Maisaka 内置长期记忆检索工具 query_memory 的默认返回条数"""
long_term_auto_summary_enabled: bool = Field(
default=True,
json_schema_extra={
@@ -657,16 +666,6 @@ class ExpressionConfig(ConfigBase):
)
"""是否开启全局黑话模式,注意,此功能关闭后,已经记录的全局黑话不会改变,需要手动删除"""
enable_jargon_explanation: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "info",
},
)
"""是否在回复前尝试对上下文中的黑话进行解释关闭可减少一次LLM调用仅影响回复前的黑话匹配与解释不影响黑话学习"""
class VoiceConfig(ConfigBase):
"""语音识别配置类"""
@@ -700,7 +699,7 @@ class EmojiConfig(ConfigBase):
"""一次从多少个表情包中选择发送,最大为 64"""
max_reg_num: int = Field(
default=100,
default=64,
json_schema_extra={
"x-widget": "input",
"x-icon": "hash",
@@ -988,23 +987,6 @@ class DebugConfig(ConfigBase):
)
"""是否显示prompt"""
show_replyer_prompt: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "message-square",
},
)
"""是否显示回复器prompt"""
show_replyer_reasoning: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "brain",
},
)
show_maisaka_thinking: bool = Field(
default=True,
json_schema_extra={
@@ -1041,25 +1023,6 @@ class DebugConfig(ConfigBase):
)
"""是否显示记忆检索相关prompt"""
show_planner_prompt: bool = Field(
default=False,
json_schema_extra={
"x-widget": "switch",
"x-icon": "map",
},
)
"""是否显示planner的prompt和原始返回结果"""
show_lpmm_paragraph: bool = Field(
default=False,
json_schema_extra={
"x-widget": "switch",
"x-icon": "file-text",
},
)
"""是否显示lpmm找到的相关文段日志"""
class ExtraPromptItem(ConfigBase):
platform: str = Field(
default="",
@@ -1511,16 +1474,6 @@ class MaiSakaConfig(ConfigBase):
)
"""MaiSaka 使用的用户名称"""
max_internal_rounds: int = Field(
default=6,
ge=1,
json_schema_extra={
"x-widget": "input",
"x-icon": "repeat",
},
)
"""每个入站消息的最大内部规划轮数"""
planner_interrupt_max_consecutive_count: int = Field(
default=2,
ge=0,
@@ -1531,26 +1484,6 @@ class MaiSakaConfig(ConfigBase):
)
"""Planner 连续被新消息打断的最大次数0 表示不启用打断"""
enable_memory_query_tool: bool = Field(
default=True,
json_schema_extra={
"x-widget": "switch",
"x-icon": "database",
},
)
"""是否启用 Maisaka 内置长期记忆检索工具 query_memory"""
memory_query_default_limit: int = Field(
default=5,
ge=1,
le=20,
json_schema_extra={
"x-widget": "input",
"x-icon": "hash",
},
)
"""Maisaka 内置长期记忆检索工具 query_memory 的默认返回条数"""
tool_filter_task_name: str = Field(
default="utils",
json_schema_extra={