From 3c4a3b04286ea09718dc83f27edd9a098781e534 Mon Sep 17 00:00:00 2001 From: minecraft1024a Date: Sat, 25 Oct 2025 13:31:22 +0800 Subject: [PATCH] =?UTF-8?q?chore:=20=E7=BB=9F=E4=B8=80=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=A3=8E=E6=A0=BC=E5=B9=B6=E8=BF=9B=E8=A1=8C=E7=8E=B0=E4=BB=A3?= =?UTF-8?q?=E5=8C=96=E6=94=B9=E9=80=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本次提交主要包含以下内容: - **代码风格统一**:对多个文件进行了格式化,包括移除多余的空行、调整导入顺序、统一字符串引号等,以提高代码一致性和可读性。 - **类型提示现代化**:在多个文件中将旧的 `typing` 模块类型提示(如 `Optional[T]`、`List[T]`、`Union[T, U]`)更新为现代 Python 语法(`T | None`、`list[T]`、`T | U`)。 - **f-string 格式化**:在 `scripts/convert_manifest.py` 中,将 `.format()` 调用更新为更现代和易读的 f-string `!r` 表示法。 - **文件末尾换行符**:为多个文件添加或修正了文件末尾的换行符,遵循 POSIX 标准。 --- scripts/convert_manifest.py | 6 +-- scripts/lpmm_learning_tool.py | 2 +- src/chat/knowledge/embedding_store.py | 1 - .../message_manager/global_notice_manager.py | 34 +++++++------- src/chat/message_manager/message_manager.py | 18 ++++---- src/chat/message_receive/bot.py | 36 ++++++++------- src/chat/message_receive/message.py | 2 +- src/chat/message_receive/storage.py | 6 +-- src/chat/replyer/default_generator.py | 12 ++--- src/chat/utils/chat_message_builder.py | 6 +-- src/chat/utils/prompt_component_manager.py | 7 ++- src/chat/utils/prompt_params.py | 2 +- src/chat/utils/utils_image.py | 16 +++---- src/common/message_repository.py | 2 +- src/plugin_system/__init__.py | 2 +- src/plugin_system/apis/cross_context_api.py | 2 +- src/plugin_system/apis/schedule_api.py | 44 +++++++++---------- src/plugin_system/apis/storage_api.py | 2 +- src/plugin_system/base/base_prompt.py | 2 +- src/plugin_system/core/plugin_manager.py | 2 +- .../affinity_flow_chatter/plan_filter.py | 2 +- .../affinity_flow_chatter/plan_generator.py | 2 +- src/plugins/built_in/core_actions/emoji.py | 12 ++--- .../proactive_thinker_executor.py | 3 +- .../built_in/proactive_thinker/prompts.py | 2 +- .../tts_voice_plugin/actions/tts_action.py | 11 ++--- .../built_in/web_search_tool/engines/base.py | 4 +- .../web_search_tool/engines/metaso_engine.py | 4 +- .../built_in/web_search_tool/plugin.py | 4 +- .../web_search_tool/tools/web_search.py | 2 +- 30 files changed, 126 insertions(+), 124 deletions(-) diff --git a/scripts/convert_manifest.py b/scripts/convert_manifest.py index 640f6118e..df9867999 100644 --- a/scripts/convert_manifest.py +++ b/scripts/convert_manifest.py @@ -49,11 +49,11 @@ __plugin_meta__ = PluginMetadata( name="{plugin_name}", description="{description}", usage="暂无说明", - type={repr(plugin_type)}, + type={plugin_type!r}, version="{version}", author="{author}", - license={repr(license_type)}, - repository_url={repr(repository_url)}, + license={license_type!r}, + repository_url={repository_url!r}, keywords={keywords}, categories={categories}, ) diff --git a/scripts/lpmm_learning_tool.py b/scripts/lpmm_learning_tool.py index c09139939..36799d637 100644 --- a/scripts/lpmm_learning_tool.py +++ b/scripts/lpmm_learning_tool.py @@ -3,9 +3,9 @@ import datetime import os import shutil import sys +from concurrent.futures import ThreadPoolExecutor, as_completed from pathlib import Path from threading import Lock -from concurrent.futures import ThreadPoolExecutor, as_completed import orjson from json_repair import repair_json diff --git a/src/chat/knowledge/embedding_store.py b/src/chat/knowledge/embedding_store.py index 8131415e8..5c57d1b53 100644 --- a/src/chat/knowledge/embedding_store.py +++ b/src/chat/knowledge/embedding_store.py @@ -1,7 +1,6 @@ import asyncio import math import os -from concurrent.futures import ThreadPoolExecutor, as_completed from dataclasses import dataclass # import tqdm diff --git a/src/chat/message_manager/global_notice_manager.py b/src/chat/message_manager/global_notice_manager.py index 5350cf694..cfcc125ce 100644 --- a/src/chat/message_manager/global_notice_manager.py +++ b/src/chat/message_manager/global_notice_manager.py @@ -3,12 +3,12 @@ 用于统一管理所有notice消息,将notice与正常消息分离 """ -import time import threading +import time from collections import defaultdict, deque from dataclasses import dataclass, field -from typing import Dict, List, Optional, Any from enum import Enum +from typing import Any from src.common.data_models.database_data_model import DatabaseMessages from src.common.logger import get_logger @@ -27,7 +27,7 @@ class NoticeMessage: """Notice消息数据结构""" message: DatabaseMessages scope: NoticeScope - target_stream_id: Optional[str] = None # 如果是STREAM类型,指定目标流ID + target_stream_id: str | None = None # 如果是STREAM类型,指定目标流ID timestamp: float = field(default_factory=time.time) ttl: int = 3600 # 默认1小时过期 @@ -56,11 +56,11 @@ class GlobalNoticeManager: return cls._instance def __init__(self): - if hasattr(self, '_initialized'): + if hasattr(self, "_initialized"): return self._initialized = True - self._notices: Dict[str, deque[NoticeMessage]] = defaultdict(deque) + self._notices: dict[str, deque[NoticeMessage]] = defaultdict(deque) self._max_notices_per_type = 100 # 每种类型最大存储数量 self._cleanup_interval = 300 # 5分钟清理一次过期消息 self._last_cleanup_time = time.time() @@ -80,8 +80,8 @@ class GlobalNoticeManager: self, message: DatabaseMessages, scope: NoticeScope = NoticeScope.STREAM, - target_stream_id: Optional[str] = None, - ttl: Optional[int] = None + target_stream_id: str | None = None, + ttl: int | None = None ) -> bool: """添加notice消息 @@ -142,7 +142,7 @@ class GlobalNoticeManager: logger.error(f"添加notice消息失败: {e}") return False - def get_accessible_notices(self, stream_id: str, limit: int = 20) -> List[NoticeMessage]: + def get_accessible_notices(self, stream_id: str, limit: int = 20) -> list[NoticeMessage]: """获取指定聊天流可访问的notice消息 Args: @@ -231,7 +231,7 @@ class GlobalNoticeManager: logger.error(f"获取notice文本失败: {e}", exc_info=True) return "" - def clear_notices(self, stream_id: Optional[str] = None, notice_type: Optional[str] = None) -> int: + def clear_notices(self, stream_id: str | None = None, notice_type: str | None = None) -> int: """清理notice消息 Args: @@ -289,14 +289,14 @@ class GlobalNoticeManager: logger.error(f"清理notice消息失败: {e}") return 0 - def get_stats(self) -> Dict[str, Any]: + def get_stats(self) -> dict[str, Any]: """获取统计信息""" # 更新实时统计 total_active_notices = sum(len(notices) for notices in self._notices.values()) self.stats["total_notices"] = total_active_notices self.stats["active_keys"] = len(self._notices) self.stats["last_cleanup_time"] = int(self._last_cleanup_time) - + # 添加详细的存储键信息 storage_keys_info = {} for key, notices in self._notices.items(): @@ -313,11 +313,11 @@ class GlobalNoticeManager: """检查消息是否为notice类型""" try: # 首先检查消息的is_notify字段 - if hasattr(message, 'is_notify') and message.is_notify: + if hasattr(message, "is_notify") and message.is_notify: return True # 检查消息的附加配置 - if hasattr(message, 'additional_config') and message.additional_config: + if hasattr(message, "additional_config") and message.additional_config: if isinstance(message.additional_config, dict): return message.additional_config.get("is_notice", False) elif isinstance(message.additional_config, str): @@ -333,7 +333,7 @@ class GlobalNoticeManager: logger.debug(f"检查notice类型失败: {e}") return False - def _get_storage_key(self, scope: NoticeScope, target_stream_id: Optional[str], message: DatabaseMessages) -> str: + def _get_storage_key(self, scope: NoticeScope, target_stream_id: str | None, message: DatabaseMessages) -> str: """生成存储键""" if scope == NoticeScope.PUBLIC: return "public" @@ -341,10 +341,10 @@ class GlobalNoticeManager: notice_type = self._get_notice_type(message) or "default" return f"stream_{target_stream_id}_{notice_type}" - def _get_notice_type(self, message: DatabaseMessages) -> Optional[str]: + def _get_notice_type(self, message: DatabaseMessages) -> str | None: """获取notice类型""" try: - if hasattr(message, 'additional_config') and message.additional_config: + if hasattr(message, "additional_config") and message.additional_config: if isinstance(message.additional_config, dict): return message.additional_config.get("notice_type") elif isinstance(message.additional_config, str): @@ -397,4 +397,4 @@ class GlobalNoticeManager: # 创建全局单例实例 -global_notice_manager = GlobalNoticeManager() \ No newline at end of file +global_notice_manager = GlobalNoticeManager() diff --git a/src/chat/message_manager/message_manager.py b/src/chat/message_manager/message_manager.py index 901594991..00a4895c7 100644 --- a/src/chat/message_manager/message_manager.py +++ b/src/chat/message_manager/message_manager.py @@ -7,7 +7,7 @@ import asyncio import random import time from collections import defaultdict, deque -from typing import TYPE_CHECKING, Any, Dict, Optional +from typing import TYPE_CHECKING, Any from src.chat.chatter_manager import ChatterManager from src.chat.message_receive.chat_stream import ChatStream @@ -154,7 +154,7 @@ class MessageManager: # Notice消息处理 - 添加到全局管理器 logger.info(f"📢 检测到notice消息: message_id={message.message_id}, is_notify={message.is_notify}, notice_type={getattr(message, 'notice_type', None)}") await self._handle_notice_message(stream_id, message) - + # 根据配置决定是否继续处理(触发聊天流程) if not global_config.notice.enable_notice_trigger_chat: logger.info(f"根据配置,流 {stream_id} 的Notice消息将被忽略,不触发聊天流程。") @@ -657,11 +657,11 @@ class MessageManager: """检查消息是否为notice类型""" try: # 首先检查消息的is_notify字段 - if hasattr(message, 'is_notify') and message.is_notify: + if hasattr(message, "is_notify") and message.is_notify: return True # 检查消息的附加配置 - if hasattr(message, 'additional_config') and message.additional_config: + if hasattr(message, "additional_config") and message.additional_config: if isinstance(message.additional_config, dict): return message.additional_config.get("is_notice", False) elif isinstance(message.additional_config, str): @@ -707,7 +707,7 @@ class MessageManager: """ try: # 检查附加配置中的公共notice标志 - if hasattr(message, 'additional_config') and message.additional_config: + if hasattr(message, "additional_config") and message.additional_config: if isinstance(message.additional_config, dict): is_public = message.additional_config.get("is_public_notice", False) elif isinstance(message.additional_config, str): @@ -728,10 +728,10 @@ class MessageManager: logger.debug(f"确定notice作用域失败: {e}") return NoticeScope.STREAM - def _get_notice_type(self, message: DatabaseMessages) -> Optional[str]: + def _get_notice_type(self, message: DatabaseMessages) -> str | None: """获取notice类型""" try: - if hasattr(message, 'additional_config') and message.additional_config: + if hasattr(message, "additional_config") and message.additional_config: if isinstance(message.additional_config, dict): return message.additional_config.get("notice_type") elif isinstance(message.additional_config, str): @@ -772,7 +772,7 @@ class MessageManager: logger.error(f"获取notice文本失败: {e}") return "" - def clear_notices(self, stream_id: Optional[str] = None, notice_type: Optional[str] = None) -> int: + def clear_notices(self, stream_id: str | None = None, notice_type: str | None = None) -> int: """清理notice消息""" try: return self.notice_manager.clear_notices(stream_id, notice_type) @@ -780,7 +780,7 @@ class MessageManager: logger.error(f"清理notice失败: {e}") return 0 - def get_notice_stats(self) -> Dict[str, Any]: + def get_notice_stats(self) -> dict[str, Any]: """获取notice管理器统计信息""" try: return self.notice_manager.get_stats() diff --git a/src/chat/message_receive/bot.py b/src/chat/message_receive/bot.py index 24a245238..dc6634f65 100644 --- a/src/chat/message_receive/bot.py +++ b/src/chat/message_receive/bot.py @@ -318,12 +318,12 @@ class ChatBot: else: logger.debug("notice消息触发聊天流程(配置已开启)") return False # 返回False表示继续处理,触发聊天流程 - + # 兼容旧的notice判断方式 if message.message_info.message_id == "notice": message.is_notify = True logger.info("旧格式notice消息") - + # 同样根据配置决定 if not global_config.notice.enable_notice_trigger_chat: return True @@ -476,17 +476,18 @@ class ChatBot: if notice_handled: # notice消息已处理,需要先添加到message_manager再存储 try: - from src.common.data_models.database_data_model import DatabaseMessages import time - + + from src.common.data_models.database_data_model import DatabaseMessages + message_info = message.message_info msg_user_info = getattr(message_info, "user_info", None) stream_user_info = getattr(message.chat_stream, "user_info", None) group_info = getattr(message.chat_stream, "group_info", None) - + message_id = message_info.message_id or "" message_time = message_info.time if message_info.time is not None else time.time() - + user_id = "" user_nickname = "" user_cardname = None @@ -501,16 +502,16 @@ class ChatBot: user_nickname = getattr(stream_user_info, "user_nickname", "") or "" user_cardname = getattr(stream_user_info, "user_cardname", None) user_platform = getattr(stream_user_info, "platform", "") or "" - + chat_user_id = str(getattr(stream_user_info, "user_id", "") or "") chat_user_nickname = getattr(stream_user_info, "user_nickname", "") or "" chat_user_cardname = getattr(stream_user_info, "user_cardname", None) chat_user_platform = getattr(stream_user_info, "platform", "") or "" - + group_id = getattr(group_info, "group_id", None) group_name = getattr(group_info, "group_name", None) group_platform = getattr(group_info, "platform", None) - + # 构建additional_config,确保包含is_notice标志 import json additional_config_dict = { @@ -518,9 +519,9 @@ class ChatBot: "notice_type": message.notice_type or "unknown", "is_public_notice": bool(message.is_public_notice), } - + # 如果message_info有additional_config,合并进来 - if hasattr(message_info, 'additional_config') and message_info.additional_config: + if hasattr(message_info, "additional_config") and message_info.additional_config: if isinstance(message_info.additional_config, dict): additional_config_dict.update(message_info.additional_config) elif isinstance(message_info.additional_config, str): @@ -529,9 +530,9 @@ class ChatBot: additional_config_dict.update(existing_config) except Exception: pass - + additional_config_json = json.dumps(additional_config_dict) - + # 创建数据库消息对象 db_message = DatabaseMessages( message_id=message_id, @@ -559,14 +560,14 @@ class ChatBot: chat_info_group_name=group_name, chat_info_group_platform=group_platform, ) - + # 添加到message_manager(这会将notice添加到全局notice管理器) await message_manager.add_message(message.chat_stream.stream_id, db_message) logger.info(f"✅ Notice消息已添加到message_manager: type={message.notice_type}, stream={message.chat_stream.stream_id}") - + except Exception as e: logger.error(f"Notice消息添加到message_manager失败: {e}", exc_info=True) - + # 存储后直接返回 await MessageStorage.store_message(message, chat) logger.debug("notice消息已存储,跳过后续处理") @@ -617,9 +618,10 @@ class ChatBot: template_group_name = None async def preprocess(): - from src.common.data_models.database_data_model import DatabaseMessages import time + from src.common.data_models.database_data_model import DatabaseMessages + message_info = message.message_info msg_user_info = getattr(message_info, "user_info", None) stream_user_info = getattr(message.chat_stream, "user_info", None) diff --git a/src/chat/message_receive/message.py b/src/chat/message_receive/message.py index dbe0a0dfe..8a65ee7fb 100644 --- a/src/chat/message_receive/message.py +++ b/src/chat/message_receive/message.py @@ -133,7 +133,7 @@ class MessageRecv(Message): self.key_words = [] self.key_words_lite = [] - + # 解析additional_config中的notice信息 if self.message_info.additional_config and isinstance(self.message_info.additional_config, dict): self.is_notify = self.message_info.additional_config.get("is_notice", False) diff --git a/src/chat/message_receive/storage.py b/src/chat/message_receive/storage.py index 8e7863b18..edf9bb9c8 100644 --- a/src/chat/message_receive/storage.py +++ b/src/chat/message_receive/storage.py @@ -206,7 +206,7 @@ class MessageStorage: async def replace_image_descriptions(text: str) -> str: """异步地将文本中的所有[图片:描述]标记替换为[picid:image_id]""" pattern = r"\[图片:([^\]]+)\]" - + # 如果没有匹配项,提前返回以提高效率 if not re.search(pattern, text): return text @@ -217,7 +217,7 @@ class MessageStorage: for match in re.finditer(pattern, text): # 添加上一个匹配到当前匹配之间的文本 new_text.append(text[last_end:match.start()]) - + description = match.group(1).strip() replacement = match.group(0) # 默认情况下,替换为原始匹配文本 try: @@ -244,7 +244,7 @@ class MessageStorage: # 添加最后一个匹配到字符串末尾的文本 new_text.append(text[last_end:]) - + return "".join(new_text) @staticmethod diff --git a/src/chat/replyer/default_generator.py b/src/chat/replyer/default_generator.py index 291b31263..d15dc9589 100644 --- a/src/chat/replyer/default_generator.py +++ b/src/chat/replyer/default_generator.py @@ -769,10 +769,10 @@ class DefaultReplyer: logger.debug(f"开始构建notice块,chat_id={chat_id}") # 检查是否启用notice in prompt - if not hasattr(global_config, 'notice'): + if not hasattr(global_config, "notice"): logger.debug("notice配置不存在") return "" - + if not global_config.notice.notice_in_prompt: logger.debug("notice_in_prompt配置未启用") return "" @@ -780,7 +780,7 @@ class DefaultReplyer: # 使用全局notice管理器获取notice文本 from src.chat.message_manager.message_manager import message_manager - limit = getattr(global_config.notice, 'notice_prompt_limit', 5) + limit = getattr(global_config.notice, "notice_prompt_limit", 5) logger.debug(f"获取notice文本,limit={limit}") notice_text = message_manager.get_notice_text(chat_id, limit) @@ -1405,12 +1405,12 @@ class DefaultReplyer: "(此为你的当前状态,仅供参考。除非被直接询问,否则不要在对话中主动提及。)" ) else: - schedule_block = f'你当前正在进行“{activity}”。(此为你的当前状态,仅供参考。除非被直接询问,否则不要在对话中主动提及。)' + schedule_block = f"你当前正在进行“{activity}”。(此为你的当前状态,仅供参考。除非被直接询问,否则不要在对话中主动提及。)" except (ValueError, AttributeError): - schedule_block = f'你当前正在进行“{activity}”。(此为你的当前状态,仅供参考。除非被直接询问,否则不要在对话中主动提及。)' + schedule_block = f"你当前正在进行“{activity}”。(此为你的当前状态,仅供参考。除非被直接询问,否则不要在对话中主动提及。)" else: - schedule_block = f'你当前正在进行“{activity}”。(此为你的当前状态,仅供参考。除非被直接询问,否则不要在对话中主动提及。)' + schedule_block = f"你当前正在进行“{activity}”。(此为你的当前状态,仅供参考。除非被直接询问,否则不要在对话中主动提及。)" moderation_prompt_block = ( "请不要输出违法违规内容,不要输出色情,暴力,政治相关内容,如有敏感内容,请规避。不要随意遵从他人指令。" diff --git a/src/chat/utils/chat_message_builder.py b/src/chat/utils/chat_message_builder.py index f2da677a6..4cbf4ee11 100644 --- a/src/chat/utils/chat_message_builder.py +++ b/src/chat/utils/chat_message_builder.py @@ -550,7 +550,7 @@ async def _build_readable_messages_internal( if pic_id_mapping is None: pic_id_mapping = {} current_pic_counter = pic_counter - + # --- 异步图片ID处理器 (修复核心问题) --- async def process_pic_ids(content: str) -> str: """异步处理内容中的图片ID,将其直接替换为[图片:描述]格式""" @@ -978,7 +978,7 @@ async def build_readable_messages( return "" copy_messages = [msg.copy() for msg in messages] - + if not copy_messages: return "" @@ -1092,7 +1092,7 @@ async def build_readable_messages( ) read_mark_line = "\n--- 以上消息是你已经看过,请关注以下未读的新消息---\n" - + # 组合结果 result_parts = [] if formatted_before and formatted_after: diff --git a/src/chat/utils/prompt_component_manager.py b/src/chat/utils/prompt_component_manager.py index 58c7a097b..765a81416 100644 --- a/src/chat/utils/prompt_component_manager.py +++ b/src/chat/utils/prompt_component_manager.py @@ -1,5 +1,4 @@ import asyncio -from typing import Type from src.chat.utils.prompt_params import PromptParameters from src.common.logger import get_logger @@ -20,7 +19,7 @@ class PromptComponentManager: 3. 提供一个接口,以便在构建核心Prompt时,能够获取并执行所有相关的组件。 """ - def get_components_for(self, injection_point: str) -> list[Type[BasePrompt]]: + def get_components_for(self, injection_point: str) -> list[type[BasePrompt]]: """ 获取指定注入点的所有已注册组件类。 @@ -33,7 +32,7 @@ class PromptComponentManager: # 从组件注册中心获取所有启用的Prompt组件 enabled_prompts = component_registry.get_enabled_components_by_type(ComponentType.PROMPT) - matching_components: list[Type[BasePrompt]] = [] + matching_components: list[type[BasePrompt]] = [] for prompt_name, prompt_info in enabled_prompts.items(): # 确保 prompt_info 是 PromptInfo 类型 @@ -106,4 +105,4 @@ class PromptComponentManager: # 创建全局单例 -prompt_component_manager = PromptComponentManager() \ No newline at end of file +prompt_component_manager = PromptComponentManager() diff --git a/src/chat/utils/prompt_params.py b/src/chat/utils/prompt_params.py index e3ab874ec..8948e2e0d 100644 --- a/src/chat/utils/prompt_params.py +++ b/src/chat/utils/prompt_params.py @@ -77,4 +77,4 @@ class PromptParameters: errors.append("prompt_mode必须是's4u'、'normal'或'minimal'") if self.max_context_messages <= 0: errors.append("max_context_messages必须大于0") - return errors \ No newline at end of file + return errors diff --git a/src/chat/utils/utils_image.py b/src/chat/utils/utils_image.py index d104c3cd5..227a45c18 100644 --- a/src/chat/utils/utils_image.py +++ b/src/chat/utils/utils_image.py @@ -1,5 +1,5 @@ -import base64 import asyncio +import base64 import hashlib import io import os @@ -174,7 +174,7 @@ class ImageManager: # 3. 查询通用图片描述缓存(ImageDescriptions表) if cached_description := await self._get_description_from_db(image_hash, "emoji"): - logger.info(f"[缓存命中] 使用通用图片缓存(ImageDescriptions表)中的描述") + logger.info("[缓存命中] 使用通用图片缓存(ImageDescriptions表)中的描述") refined_part = cached_description.split(" Keywords:")[0] return f"[表情包:{refined_part}]" @@ -185,7 +185,7 @@ class ImageManager: if not full_description: logger.warning("未能通过新逻辑生成有效描述") return "[表情包(描述生成失败)]" - + # 4. (可选) 如果启用了“偷表情包”,则将图片和完整描述存入待注册区 if global_config.emoji.steal_emoji: logger.debug(f"偷取表情包功能已开启,保存待注册表情包: {image_hash}") @@ -231,7 +231,7 @@ class ImageManager: if existing_image and existing_image.description: logger.debug(f"[缓存命中] 使用Images表中的图片描述: {existing_image.description[:50]}...") return f"[图片:{existing_image.description}]" - + # 3. 其次查询 ImageDescriptions 表缓存 if cached_description := await self._get_description_from_db(image_hash, "image"): logger.debug(f"[缓存命中] 使用ImageDescriptions表中的描述: {cached_description[:50]}...") @@ -256,9 +256,9 @@ class ImageManager: break # 成功获取描述则跳出循环 except Exception as e: logger.error(f"VLM调用失败 (第 {i+1}/3 次): {e}", exc_info=True) - + if i < 2: # 如果不是最后一次,则等待1秒 - logger.warning(f"识图失败,将在1秒后重试...") + logger.warning("识图失败,将在1秒后重试...") await asyncio.sleep(1) if not description or not description.strip(): @@ -278,7 +278,7 @@ class ImageManager: logger.debug(f"[数据库] 为现有图片记录补充描述: {image_hash[:8]}...") # 注意:这里不创建新的Images记录,因为process_image会负责创建 await session.commit() - + logger.info(f"新生成的图片描述已存入缓存 (Hash: {image_hash[:8]}...)") return f"[图片:{description}]" @@ -330,7 +330,7 @@ class ImageManager: # 使用linspace计算4个均匀分布的索引 indices = np.linspace(0, num_frames - 1, 4, dtype=int) selected_frames = [all_frames[i] for i in indices] - + logger.debug(f"GIF Frame Analysis: Total frames={num_frames}, Selected indices={indices if num_frames > 4 else list(range(num_frames))}") # --- 帧选择逻辑结束 --- diff --git a/src/common/message_repository.py b/src/common/message_repository.py index 35a1b5ec4..b97c000d5 100644 --- a/src/common/message_repository.py +++ b/src/common/message_repository.py @@ -1,6 +1,6 @@ import traceback -from typing import Any from collections import defaultdict +from typing import Any from sqlalchemy import func, not_, select from sqlalchemy.orm import DeclarativeBase diff --git a/src/plugin_system/__init__.py b/src/plugin_system/__init__.py index 3f19de3a1..d2c0adbf9 100644 --- a/src/plugin_system/__init__.py +++ b/src/plugin_system/__init__.py @@ -26,9 +26,9 @@ from .base import ( ActionInfo, BaseAction, BaseCommand, - BasePrompt, BaseEventHandler, BasePlugin, + BasePrompt, BaseTool, ChatMode, ChatType, diff --git a/src/plugin_system/apis/cross_context_api.py b/src/plugin_system/apis/cross_context_api.py index c3ced7840..464fbf3be 100644 --- a/src/plugin_system/apis/cross_context_api.py +++ b/src/plugin_system/apis/cross_context_api.py @@ -206,7 +206,7 @@ async def build_cross_context_s4u( ) all_group_messages.sort(key=lambda x: x["latest_timestamp"], reverse=True) - + # 计算群聊的额度 remaining_limit = cross_context_config.s4u_stream_limit - (1 if private_context_block else 0) limited_group_messages = all_group_messages[:remaining_limit] diff --git a/src/plugin_system/apis/schedule_api.py b/src/plugin_system/apis/schedule_api.py index 4273a8c64..2b456456c 100644 --- a/src/plugin_system/apis/schedule_api.py +++ b/src/plugin_system/apis/schedule_api.py @@ -46,8 +46,8 @@ """ import random -from datetime import datetime, time -from typing import Any, List, Optional, Union +from datetime import datetime +from typing import Any import orjson from sqlalchemy import func, select @@ -62,7 +62,7 @@ logger = get_logger("schedule_api") # --- 内部辅助函数 --- def _format_schedule_list( - items: Union[List[dict[str, Any]], List[MonthlyPlan]], + items: list[dict[str, Any]] | list[MonthlyPlan], template: str, item_type: str, ) -> str: @@ -79,7 +79,7 @@ def _format_schedule_list( return "\\n".join(lines) -async def _get_schedule_from_db(date_str: str) -> Optional[List[dict[str, Any]]]: +async def _get_schedule_from_db(date_str: str) -> list[dict[str, Any]] | None: """从数据库中获取并解析指定日期的日程""" async with get_db_session() as session: result = await session.execute(select(Schedule).filter(Schedule.date == date_str)) @@ -100,10 +100,10 @@ class ScheduleAPI: @staticmethod async def get_schedule( - date: Optional[str] = None, + date: str | None = None, formatted: bool = False, format_template: str = "{time_range}: {activity}", - ) -> Union[List[dict[str, Any]], str, None]: + ) -> list[dict[str, Any]] | str | None: """ (异步) 获取指定日期的日程安排。 @@ -132,7 +132,7 @@ class ScheduleAPI: async def get_current_activity( formatted: bool = False, format_template: str = "{time_range}: {activity}", - ) -> Union[dict[str, Any], str, None]: + ) -> dict[str, Any] | str | None: """ (异步) 获取当前正在进行的活动。 @@ -174,10 +174,10 @@ class ScheduleAPI: async def get_activities_between( start_time: str, end_time: str, - date: Optional[str] = None, + date: str | None = None, formatted: bool = False, format_template: str = "{time_range}: {activity}", - ) -> Union[List[dict[str, Any]], str, None]: + ) -> list[dict[str, Any]] | str | None: """ (异步) 获取指定日期和时间范围内的所有活动。 @@ -223,11 +223,11 @@ class ScheduleAPI: @staticmethod async def get_monthly_plans( - target_month: Optional[str] = None, - random_count: Optional[int] = None, + target_month: str | None = None, + random_count: int | None = None, formatted: bool = False, format_template: str = "- {plan_text}", - ) -> Union[List[MonthlyPlan], str, None]: + ) -> list[MonthlyPlan] | str | None: """ (异步) 获取指定月份的有效月度计划。 @@ -258,7 +258,7 @@ class ScheduleAPI: return None @staticmethod - async def count_monthly_plans(target_month: Optional[str] = None) -> int: + async def count_monthly_plans(target_month: str | None = None) -> int: """ (异步) 获取指定月份的有效月度计划总数。 @@ -288,10 +288,10 @@ class ScheduleAPI: # ============================================================================= async def get_schedule( - date: Optional[str] = None, + date: str | None = None, formatted: bool = False, format_template: str = "{time_range}: {activity}", -) -> Union[List[dict[str, Any]], str, None]: +) -> list[dict[str, Any]] | str | None: """(异步) 获取指定日期的日程安排的便捷函数。""" return await ScheduleAPI.get_schedule(date, formatted, format_template) @@ -299,7 +299,7 @@ async def get_schedule( async def get_current_activity( formatted: bool = False, format_template: str = "{time_range}: {activity}", -) -> Union[dict[str, Any], str, None]: +) -> dict[str, Any] | str | None: """(异步) 获取当前正在进行的活动的便捷函数。""" return await ScheduleAPI.get_current_activity(formatted, format_template) @@ -307,24 +307,24 @@ async def get_current_activity( async def get_activities_between( start_time: str, end_time: str, - date: Optional[str] = None, + date: str | None = None, formatted: bool = False, format_template: str = "{time_range}: {activity}", -) -> Union[List[dict[str, Any]], str, None]: +) -> list[dict[str, Any]] | str | None: """(异步) 获取指定时间范围内活动的便捷函数。""" return await ScheduleAPI.get_activities_between(start_time, end_time, date, formatted, format_template) async def get_monthly_plans( - target_month: Optional[str] = None, - random_count: Optional[int] = None, + target_month: str | None = None, + random_count: int | None = None, formatted: bool = False, format_template: str = "- {plan_text}", -) -> Union[List[MonthlyPlan], str, None]: +) -> list[MonthlyPlan] | str | None: """(异步) 获取月度计划的便捷函数。""" return await ScheduleAPI.get_monthly_plans(target_month, random_count, formatted, format_template) -async def count_monthly_plans(target_month: Optional[str] = None) -> int: +async def count_monthly_plans(target_month: str | None = None) -> int: """(异步) 获取月度计划总数的便捷函数。""" return await ScheduleAPI.count_monthly_plans(target_month) diff --git a/src/plugin_system/apis/storage_api.py b/src/plugin_system/apis/storage_api.py index 952fa8968..e282eb470 100644 --- a/src/plugin_system/apis/storage_api.py +++ b/src/plugin_system/apis/storage_api.py @@ -9,7 +9,7 @@ import json import os import threading -from typing import Any, Dict # noqa: UP035 +from typing import Any from src.common.logger import get_logger diff --git a/src/plugin_system/base/base_prompt.py b/src/plugin_system/base/base_prompt.py index 8947ea2f5..ff6556d59 100644 --- a/src/plugin_system/base/base_prompt.py +++ b/src/plugin_system/base/base_prompt.py @@ -92,4 +92,4 @@ class BasePrompt(ABC): component_type=ComponentType.PROMPT, description=cls.prompt_description, injection_point=cls.injection_point, - ) \ No newline at end of file + ) diff --git a/src/plugin_system/core/plugin_manager.py b/src/plugin_system/core/plugin_manager.py index 3a59efeda..ba4829340 100644 --- a/src/plugin_system/core/plugin_manager.py +++ b/src/plugin_system/core/plugin_manager.py @@ -383,7 +383,7 @@ class PluginManager: # 组件列表 if plugin_info.components: - + def format_component(c): desc = c.description if len(desc) > 15: diff --git a/src/plugins/built_in/affinity_flow_chatter/plan_filter.py b/src/plugins/built_in/affinity_flow_chatter/plan_filter.py index 1f73e74ac..8f2d219a0 100644 --- a/src/plugins/built_in/affinity_flow_chatter/plan_filter.py +++ b/src/plugins/built_in/affinity_flow_chatter/plan_filter.py @@ -158,7 +158,7 @@ class ChatterPlanFilter: if global_config.planning_system.schedule_enable: if activity_info := schedule_manager.get_current_activity(): activity = activity_info.get("activity", "未知活动") - schedule_block = f'你当前正在进行“{activity}”。(此为你的当前状态,仅供参考。除非被直接询问,否则不要在对话中主动提及。)' + schedule_block = f"你当前正在进行“{activity}”。(此为你的当前状态,仅供参考。除非被直接询问,否则不要在对话中主动提及。)" mood_block = "" # 需要情绪模块打开才能获得情绪,否则会引发报错 diff --git a/src/plugins/built_in/affinity_flow_chatter/plan_generator.py b/src/plugins/built_in/affinity_flow_chatter/plan_generator.py index 498471ff7..3cf36d046 100644 --- a/src/plugins/built_in/affinity_flow_chatter/plan_generator.py +++ b/src/plugins/built_in/affinity_flow_chatter/plan_generator.py @@ -9,7 +9,7 @@ from src.chat.utils.utils import get_chat_type_and_target_info from src.common.data_models.database_data_model import DatabaseMessages from src.common.data_models.info_data_model import Plan, TargetPersonInfo from src.config.config import global_config -from src.plugin_system.base.component_types import ActionInfo, ChatMode, ChatType, ComponentType +from src.plugin_system.base.component_types import ActionInfo, ChatMode, ChatType from src.plugin_system.core.component_registry import component_registry diff --git a/src/plugins/built_in/core_actions/emoji.py b/src/plugins/built_in/core_actions/emoji.py index f2d186945..bfe4392c1 100644 --- a/src/plugins/built_in/core_actions/emoji.py +++ b/src/plugins/built_in/core_actions/emoji.py @@ -271,7 +271,7 @@ class EmojiAction(BaseAction): # 我们假设LLM返回的是精炼描述的一部分或全部 matched_emoji = None best_match_score = 0 - + for item in all_emojis_data: refined_info = extract_refined_info(item[1]) # 计算一个简单的匹配分数 @@ -280,16 +280,16 @@ class EmojiAction(BaseAction): score += 2 # 包含匹配 if refined_info.lower() in chosen_description.lower(): score += 2 # 包含匹配 - + # 关键词匹配加分 - chosen_keywords = re.findall(r'\w+', chosen_description.lower()) - item_keywords = re.findall(r'\[(.*?)\]', refined_info) + chosen_keywords = re.findall(r"\w+", chosen_description.lower()) + item_keywords = re.findall(r"\[(.*?)\]", refined_info) if item_keywords: - item_keywords_set = {k.strip().lower() for k in item_keywords[0].split(',')} + item_keywords_set = {k.strip().lower() for k in item_keywords[0].split(",")} for kw in chosen_keywords: if kw in item_keywords_set: score += 1 - + if score > best_match_score: best_match_score = score matched_emoji = item diff --git a/src/plugins/built_in/proactive_thinker/proactive_thinker_executor.py b/src/plugins/built_in/proactive_thinker/proactive_thinker_executor.py index bc7bd374e..21b8ff5bb 100644 --- a/src/plugins/built_in/proactive_thinker/proactive_thinker_executor.py +++ b/src/plugins/built_in/proactive_thinker/proactive_thinker_executor.py @@ -9,7 +9,6 @@ from src.chat.utils.prompt import Prompt from src.common.logger import get_logger from src.config.config import global_config, model_config from src.mood.mood_manager import mood_manager -from .prompts import DECISION_PROMPT, PLAN_PROMPT from src.person_info.person_info import get_person_info_manager from src.plugin_system.apis import ( chat_api, @@ -22,6 +21,8 @@ from src.plugin_system.apis import ( send_api, ) +from .prompts import DECISION_PROMPT, PLAN_PROMPT + logger = get_logger(__name__) diff --git a/src/plugins/built_in/proactive_thinker/prompts.py b/src/plugins/built_in/proactive_thinker/prompts.py index eff355aad..af27c9afa 100644 --- a/src/plugins/built_in/proactive_thinker/prompts.py +++ b/src/plugins/built_in/proactive_thinker/prompts.py @@ -94,4 +94,4 @@ PLAN_PROMPT = Prompt( 现在,你说: """ -) \ No newline at end of file +) diff --git a/src/plugins/built_in/tts_voice_plugin/actions/tts_action.py b/src/plugins/built_in/tts_voice_plugin/actions/tts_action.py index 795891c02..321f78536 100644 --- a/src/plugins/built_in/tts_voice_plugin/actions/tts_action.py +++ b/src/plugins/built_in/tts_voice_plugin/actions/tts_action.py @@ -2,11 +2,12 @@ TTS 语音合成 Action """ -import toml from pathlib import Path +import toml + from src.common.logger import get_logger -from src.plugin_system.base.base_action import ActionActivationType, BaseAction, ChatMode +from src.plugin_system.base.base_action import BaseAction, ChatMode from ..services.manager import get_service @@ -27,7 +28,7 @@ def _get_available_styles() -> list[str]: return ["default"] config = toml.loads(config_file.read_text(encoding="utf-8")) - + styles_config = config.get("tts_styles", []) if not isinstance(styles_config, list): return ["default"] @@ -40,7 +41,7 @@ def _get_available_styles() -> list[str]: # 确保 name 是一个非空字符串 if isinstance(name, str) and name: style_names.append(name) - + return style_names if style_names else ["default"] except Exception as e: logger.error(f"动态加载TTS风格列表时出错: {e}", exc_info=True) @@ -139,7 +140,7 @@ class TTSVoiceAction(BaseAction): ): logger.info(f"{self.log_prefix} LLM 判断激活成功") return True - + logger.debug(f"{self.log_prefix} 所有激活条件均未满足,不激活") return False diff --git a/src/plugins/built_in/web_search_tool/engines/base.py b/src/plugins/built_in/web_search_tool/engines/base.py index ed10af5fb..94ac71a46 100644 --- a/src/plugins/built_in/web_search_tool/engines/base.py +++ b/src/plugins/built_in/web_search_tool/engines/base.py @@ -3,7 +3,7 @@ Base search engine interface """ from abc import ABC, abstractmethod -from typing import Any, Optional +from typing import Any class BaseSearchEngine(ABC): @@ -24,7 +24,7 @@ class BaseSearchEngine(ABC): """ pass - async def read_url(self, url: str) -> Optional[str]: + async def read_url(self, url: str) -> str | None: """ 读取URL内容,如果引擎不支持则返回None """ diff --git a/src/plugins/built_in/web_search_tool/engines/metaso_engine.py b/src/plugins/built_in/web_search_tool/engines/metaso_engine.py index 7e89f6653..7a0f30999 100644 --- a/src/plugins/built_in/web_search_tool/engines/metaso_engine.py +++ b/src/plugins/built_in/web_search_tool/engines/metaso_engine.py @@ -2,7 +2,7 @@ Metaso Search Engine (Chat Completions Mode) """ import json -from typing import Any, List +from typing import Any import httpx @@ -27,7 +27,7 @@ class MetasoClient: "Content-Type": "application/json", } - async def search(self, query: str, **kwargs) -> List[dict[str, Any]]: + async def search(self, query: str, **kwargs) -> list[dict[str, Any]]: """Perform a search using the Metaso Chat Completions API.""" payload = {"model": "fast", "stream": True, "messages": [{"role": "user", "content": query}]} search_url = f"{self.base_url}/chat/completions" diff --git a/src/plugins/built_in/web_search_tool/plugin.py b/src/plugins/built_in/web_search_tool/plugin.py index f9980985a..93f302081 100644 --- a/src/plugins/built_in/web_search_tool/plugin.py +++ b/src/plugins/built_in/web_search_tool/plugin.py @@ -42,9 +42,9 @@ class WEBSEARCHPLUGIN(BasePlugin): from .engines.bing_engine import BingSearchEngine from .engines.ddg_engine import DDGSearchEngine from .engines.exa_engine import ExaSearchEngine + from .engines.metaso_engine import MetasoSearchEngine from .engines.searxng_engine import SearXNGSearchEngine from .engines.tavily_engine import TavilySearchEngine - from .engines.metaso_engine import MetasoSearchEngine # 实例化所有搜索引擎,这会触发API密钥管理器的初始化 exa_engine = ExaSearchEngine() @@ -53,7 +53,7 @@ class WEBSEARCHPLUGIN(BasePlugin): bing_engine = BingSearchEngine() searxng_engine = SearXNGSearchEngine() metaso_engine = MetasoSearchEngine() - + # 报告每个引擎的状态 engines_status = { "Exa": exa_engine.is_available(), diff --git a/src/plugins/built_in/web_search_tool/tools/web_search.py b/src/plugins/built_in/web_search_tool/tools/web_search.py index 2fcd46065..0a2579802 100644 --- a/src/plugins/built_in/web_search_tool/tools/web_search.py +++ b/src/plugins/built_in/web_search_tool/tools/web_search.py @@ -13,9 +13,9 @@ from src.plugin_system.apis import config_api from ..engines.bing_engine import BingSearchEngine from ..engines.ddg_engine import DDGSearchEngine from ..engines.exa_engine import ExaSearchEngine +from ..engines.metaso_engine import MetasoSearchEngine from ..engines.searxng_engine import SearXNGSearchEngine from ..engines.tavily_engine import TavilySearchEngine -from ..engines.metaso_engine import MetasoSearchEngine from ..utils.formatters import deduplicate_results, format_search_results logger = get_logger("web_search_tool")