From e9a5488b62db5b94838482843cb7fd0b8e4ab1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A2=A8=E6=A2=93=E6=9F=92?= <1787882683@qq.com> Date: Sun, 28 Sep 2025 00:02:18 +0800 Subject: [PATCH] Ruff Fix --- plugins/emoji_manage_plugin/plugin.py | 33 +++---- src/chat/brain_chat/brain_chat.py | 21 ++--- src/chat/brain_chat/brain_planner.py | 4 +- src/chat/express/expression_learner.py | 90 +++++++++++++------ src/chat/express/expression_selector.py | 6 +- .../frequency_control/frequency_control.py | 2 +- src/chat/heart_flow/heartFC_chat.py | 18 ++-- .../heart_flow/heartflow_message_processor.py | 6 +- src/chat/message_receive/bot.py | 2 +- src/chat/planner_actions/planner.py | 5 +- src/chat/replyer/group_generator.py | 22 ++--- src/chat/replyer/private_generator.py | 24 ++--- src/chat/replyer/prompt/lpmm_prompt.py | 4 - src/chat/replyer/prompt/replyer_prompt.py | 22 ++--- src/chat/replyer/prompt/rewrite_prompt.py | 4 +- src/chat/utils/chat_message_builder.py | 4 +- src/common/data_models/llm_data_model.py | 2 +- src/common/database/database_model.py | 6 +- src/config/official_configs.py | 9 +- src/llm_models/exceptions.py | 2 +- src/llm_models/model_client/gemini_client.py | 20 ++--- src/llm_models/model_client/openai_client.py | 4 +- src/llm_models/utils_model.py | 2 +- src/mood/mood_manager.py | 12 ++- src/person_info/person_info.py | 26 +++--- src/plugin_system/apis/emoji_api.py | 56 ++++++------ src/plugin_system/apis/frequency_api.py | 7 +- src/plugin_system/apis/mood_api.py | 9 +- src/plugin_system/apis/send_api.py | 6 +- src/plugin_system/core/tool_use.py | 2 +- src/plugins/built_in/emoji_plugin/emoji.py | 2 +- src/plugins/built_in/relation/plugin.py | 5 +- 32 files changed, 215 insertions(+), 222 deletions(-) diff --git a/plugins/emoji_manage_plugin/plugin.py b/plugins/emoji_manage_plugin/plugin.py index 893d14b7..453afbc2 100644 --- a/plugins/emoji_manage_plugin/plugin.py +++ b/plugins/emoji_manage_plugin/plugin.py @@ -1,26 +1,19 @@ -import random -from typing import List, Tuple, Type, Any +from typing import List, Tuple, Type from src.plugin_system import ( BasePlugin, register_plugin, - BaseAction, BaseCommand, - BaseTool, ComponentInfo, - ActionActivationType, ConfigField, - BaseEventHandler, - EventType, - MaiMessages, - ToolParamType, ReplyContentType, emoji_api, ) from maim_message import Seg -from src.config.config import global_config from src.common.logger import get_logger + logger = get_logger("emoji_manage_plugin") + class AddEmojiCommand(BaseCommand): command_name = "add_emoji" command_description = "添加表情包" @@ -29,7 +22,7 @@ class AddEmojiCommand(BaseCommand): async def execute(self) -> Tuple[bool, str, bool]: # 查找消息中的表情包 # logger.info(f"查找消息中的表情包: {self.message.message_segment}") - + emoji_base64_list = self.find_and_return_emoji_in_message(self.message.message_segment) if not emoji_base64_list: @@ -51,7 +44,7 @@ class AddEmojiCommand(BaseCommand): emotions = result.get("emotions", []) replaced = result.get("replaced", False) - result_msg = f"表情包 {i+1} 注册成功{'(替换旧表情包)' if replaced else '(新增表情包)'}" + result_msg = f"表情包 {i + 1} 注册成功{'(替换旧表情包)' if replaced else '(新增表情包)'}" if description: result_msg += f"\n描述: {description}" if emotions: @@ -61,11 +54,11 @@ class AddEmojiCommand(BaseCommand): else: fail_count += 1 error_msg = result.get("message", "注册失败") - results.append(f"表情包 {i+1} 注册失败: {error_msg}") + results.append(f"表情包 {i + 1} 注册失败: {error_msg}") except Exception as e: fail_count += 1 - results.append(f"表情包 {i+1} 注册时发生错误: {str(e)}") + results.append(f"表情包 {i + 1} 注册时发生错误: {str(e)}") # 构建返回消息 total_count = success_count + fail_count @@ -140,6 +133,7 @@ class AddEmojiCommand(BaseCommand): emoji_base64_list.extend(self.find_and_return_emoji_in_message(seg.data)) return emoji_base64_list + class ListEmojiCommand(BaseCommand): """列表表情包Command - 响应/emoji list命令""" @@ -156,6 +150,7 @@ class ListEmojiCommand(BaseCommand): # 解析命令参数 import re + match = re.match(r"^/emoji list(?:\s+(\d+))?$", self.message.raw_message) max_count = 10 # 默认显示10个 if match and match.group(1): @@ -195,7 +190,7 @@ class ListEmojiCommand(BaseCommand): display_emojis = all_emojis[:max_count] message_lines.append(f"\n📋 显示前 {len(display_emojis)} 个表情包:") - for i, (emoji_base64, description, emotion) in enumerate(display_emojis, 1): + for i, (_, description, emotion) in enumerate(display_emojis, 1): # 截断过长的描述 short_desc = description[:50] + "..." if len(description) > 50 else description message_lines.append(f"{i}. {short_desc} [{emotion}]") @@ -257,7 +252,7 @@ class DeleteEmojiCommand(BaseCommand): count_after = result.get("count_after", 0) emotions = result.get("emotions", []) - result_msg = f"表情包 {i+1} 删除成功" + result_msg = f"表情包 {i + 1} 删除成功" if description: result_msg += f"\n描述: {description}" if emotions: @@ -268,11 +263,11 @@ class DeleteEmojiCommand(BaseCommand): else: fail_count += 1 error_msg = result.get("message", "删除失败") - results.append(f"表情包 {i+1} 删除失败: {error_msg}") + results.append(f"表情包 {i + 1} 删除失败: {error_msg}") except Exception as e: fail_count += 1 - results.append(f"表情包 {i+1} 删除时发生错误: {str(e)}") + results.append(f"表情包 {i + 1} 删除时发生错误: {str(e)}") # 构建返回消息 total_count = success_count + fail_count @@ -401,4 +396,4 @@ class EmojiManagePlugin(BasePlugin): (AddEmojiCommand.get_command_info(), AddEmojiCommand), (ListEmojiCommand.get_command_info(), ListEmojiCommand), (DeleteEmojiCommand.get_command_info(), DeleteEmojiCommand), - ] \ No newline at end of file + ] diff --git a/src/chat/brain_chat/brain_chat.py b/src/chat/brain_chat/brain_chat.py index 5ba077ab..36f78af4 100644 --- a/src/chat/brain_chat/brain_chat.py +++ b/src/chat/brain_chat/brain_chat.py @@ -16,7 +16,6 @@ from src.chat.brain_chat.brain_planner import BrainPlanner from src.chat.planner_actions.action_modifier import ActionModifier from src.chat.planner_actions.action_manager import ActionManager from src.chat.heart_flow.hfc_utils import CycleDetail -from src.chat.heart_flow.hfc_utils import send_typing, stop_typing from src.chat.express.expression_learner import expression_learner_manager from src.person_info.person_info import Person from src.plugin_system.base.component_types import EventType, ActionInfo @@ -96,7 +95,6 @@ class BrainChatting: self.last_read_time = time.time() - 2 self.more_plan = False - async def start(self): """检查是否需要启动主循环,如果未激活则启动。""" @@ -171,10 +169,8 @@ class BrainChatting: if len(recent_messages_list) >= 1: self.last_read_time = time.time() - await self._observe( - recent_messages_list=recent_messages_list - ) - + await self._observe(recent_messages_list=recent_messages_list) + else: # Normal模式:消息数量不足,等待 await asyncio.sleep(0.2) @@ -233,11 +229,11 @@ class BrainChatting: async def _observe( self, # interest_value: float = 0.0, - recent_messages_list: Optional[List["DatabaseMessages"]] = None + recent_messages_list: Optional[List["DatabaseMessages"]] = None, ) -> bool: # sourcery skip: merge-else-if-into-elif, remove-redundant-if if recent_messages_list is None: recent_messages_list = [] - reply_text = "" # 初始化reply_text变量,避免UnboundLocalError + _reply_text = "" # 初始化reply_text变量,避免UnboundLocalError async with global_prompt_manager.async_message_scope(self.chat_stream.context.get_template_name()): await self.expression_learner.trigger_learning_for_chat() @@ -334,7 +330,7 @@ class BrainChatting: "taken_time": time.time(), } ) - reply_text = reply_text_from_reply + _reply_text = reply_text_from_reply else: # 没有回复信息,构建纯动作的loop_info loop_info = { @@ -347,7 +343,7 @@ class BrainChatting: "taken_time": time.time(), }, } - reply_text = action_reply_text + _reply_text = action_reply_text self.end_cycle(loop_info, cycle_timers) self.print_cycle_info(cycle_timers) @@ -484,7 +480,6 @@ class BrainChatting: """执行单个动作的通用函数""" try: with Timer(f"动作{action_planner_info.action_type}", cycle_timers): - if action_planner_info.action_type == "no_reply": # 直接处理no_action逻辑,不再通过动作系统 reason = action_planner_info.reasoning or "选择不回复" @@ -517,7 +512,9 @@ class BrainChatting: if not success or not llm_response or not llm_response.reply_set: if action_planner_info.action_message: - logger.info(f"对 {action_planner_info.action_message.processed_plain_text} 的回复生成失败") + logger.info( + f"对 {action_planner_info.action_message.processed_plain_text} 的回复生成失败" + ) else: logger.info("回复生成失败") return {"action_type": "reply", "success": False, "reply_text": "", "loop_info": None} diff --git a/src/chat/brain_chat/brain_planner.py b/src/chat/brain_chat/brain_planner.py index 30627a5b..5c4f969c 100644 --- a/src/chat/brain_chat/brain_planner.py +++ b/src/chat/brain_chat/brain_planner.py @@ -307,7 +307,9 @@ class BrainPlanner: if chat_target_info: # 构建聊天上下文描述 - chat_context_description = f"你正在和 {chat_target_info.person_name or chat_target_info.user_nickname or '对方'} 聊天中" + chat_context_description = ( + f"你正在和 {chat_target_info.person_name or chat_target_info.user_nickname or '对方'} 聊天中" + ) # 构建动作选项块 action_options_block = await self._build_action_options_block(current_available_actions) diff --git a/src/chat/express/expression_learner.py b/src/chat/express/expression_learner.py index 79fa433e..72f5630a 100644 --- a/src/chat/express/expression_learner.py +++ b/src/chat/express/expression_learner.py @@ -10,11 +10,14 @@ from src.common.logger import get_logger from src.common.database.database_model import Expression from src.llm_models.utils_model import LLMRequest from src.config.config import model_config, global_config -from src.chat.utils.chat_message_builder import get_raw_msg_by_timestamp_with_chat_inclusive, build_anonymous_messages, build_bare_messages +from src.chat.utils.chat_message_builder import ( + get_raw_msg_by_timestamp_with_chat_inclusive, + build_anonymous_messages, + build_bare_messages, +) from src.chat.utils.prompt_builder import Prompt, global_prompt_manager from src.chat.message_receive.chat_stream import get_chat_manager from json_repair import repair_json -from src.chat.utils.utils import get_embedding MAX_EXPRESSION_COUNT = 300 @@ -99,7 +102,9 @@ class ExpressionLearner: self.last_learning_time: float = time.time() # 学习参数 - _, self.enable_learning, self.learning_intensity = global_config.expression.get_expression_config_for_chat(self.chat_id) + _, self.enable_learning, self.learning_intensity = global_config.expression.get_expression_config_for_chat( + self.chat_id + ) self.min_messages_for_learning = 15 / self.learning_intensity # 触发学习所需的最少消息数 self.min_learning_interval = 150 / self.learning_intensity @@ -237,17 +242,42 @@ class ExpressionLearner: return [] learnt_expressions = res learnt_expressions_str = "" - for _chat_id, situation, style, context, context_words, full_context, full_context_embedding in learnt_expressions: + for ( + _chat_id, + situation, + style, + _context, + _context_words, + _full_context, + _full_context_embedding, + ) in learnt_expressions: learnt_expressions_str += f"{situation}->{style}\n" - + logger.info(f"在 {self.chat_name} 学习到表达风格:\n{learnt_expressions_str}") # 按chat_id分组 chat_dict: Dict[str, List[Dict[str, Any]]] = {} - for chat_id, situation, style, context, context_words, full_context, full_context_embedding in learnt_expressions: + for ( + chat_id, + situation, + style, + context, + context_words, + full_context, + full_context_embedding, + ) in learnt_expressions: if chat_id not in chat_dict: chat_dict[chat_id] = [] - chat_dict[chat_id].append({"situation": situation, "style": style, "context": context, "context_words": context_words, "full_context": full_context, "full_context_embedding": full_context_embedding}) + chat_dict[chat_id].append( + { + "situation": situation, + "style": style, + "context": context, + "context_words": context_words, + "full_context": full_context, + "full_context_embedding": full_context_embedding, + } + ) current_time = time.time() @@ -300,11 +330,13 @@ class ExpressionLearner: expr.delete_instance() return learnt_expressions - async def match_expression_context(self, expression_pairs: List[Tuple[str, str]], random_msg_match_str: str) -> List[Tuple[str, str, str]]: + async def match_expression_context( + self, expression_pairs: List[Tuple[str, str]], random_msg_match_str: str + ) -> List[Tuple[str, str, str]]: # 为expression_pairs逐个条目赋予编号,并构建成字符串 numbered_pairs = [] for i, (situation, style) in enumerate(expression_pairs, 1): - numbered_pairs.append(f"{i}. 当\"{situation}\"时,使用\"{style}\"") + numbered_pairs.append(f'{i}. 当"{situation}"时,使用"{style}"') expression_pairs_str = "\n".join(numbered_pairs) @@ -319,20 +351,20 @@ class ExpressionLearner: print(f"match_expression_context_prompt: {prompt}") print(f"random_msg_match_str: {response}") - + # 解析JSON响应 match_responses = [] try: response = response.strip() # 检查是否已经是标准JSON数组格式 - if response.startswith('[') and response.endswith(']'): + if response.startswith("[") and response.endswith("]"): match_responses = json.loads(response) else: # 尝试直接解析多个JSON对象 try: # 如果是多个JSON对象用逗号分隔,包装成数组 - if response.startswith('{') and not response.startswith('['): - response = '[' + response + ']' + if response.startswith("{") and not response.startswith("["): + response = "[" + response + "]" match_responses = json.loads(response) else: # 使用repair_json处理响应 @@ -394,7 +426,9 @@ class ExpressionLearner: return matched_expressions - async def learn_expression(self, num: int = 10) -> Optional[List[Tuple[str, str, str, List[str], str, List[float]]]]: + async def learn_expression( + self, num: int = 10 + ) -> Optional[List[Tuple[str, str, str, List[str], str, List[float]]]]: """从指定聊天流学习表达方式 Args: @@ -416,11 +450,10 @@ class ExpressionLearner: if not random_msg or random_msg == []: return None # 转化成str - chat_id: str = random_msg[0].chat_id + _chat_id: str = random_msg[0].chat_id # random_msg_str: str = build_readable_messages(random_msg, timestamp_mode="normal") random_msg_str: str = await build_anonymous_messages(random_msg) random_msg_match_str: str = await build_bare_messages(random_msg) - prompt: str = await global_prompt_manager.format_prompt( prompt, @@ -440,24 +473,31 @@ class ExpressionLearner: expressions: List[Tuple[str, str]] = self.parse_expression_response(response) - matched_expressions: List[Tuple[str, str, str]] = await self.match_expression_context(expressions, random_msg_match_str) + matched_expressions: List[Tuple[str, str, str]] = await self.match_expression_context( + expressions, random_msg_match_str + ) + + split_matched_expressions: List[Tuple[str, str, str, List[str]]] = self.split_expression_context( + matched_expressions + ) - split_matched_expressions: List[Tuple[str, str, str, List[str]]] = self.split_expression_context(matched_expressions) - split_matched_expressions_w_emb = [] full_context_embedding: List[float] = await self.get_full_context_embedding(random_msg_match_str) - - for situation, style, context, context_words in split_matched_expressions: - split_matched_expressions_w_emb.append((self.chat_id, situation, style, context, context_words, random_msg_match_str,full_context_embedding)) + for situation, style, context, context_words in split_matched_expressions: + split_matched_expressions_w_emb.append( + (self.chat_id, situation, style, context, context_words, random_msg_match_str, full_context_embedding) + ) return split_matched_expressions_w_emb - + async def get_full_context_embedding(self, context: str) -> List[float]: embedding, _ = await self.embedding_model.get_embedding(context) return embedding - - def split_expression_context(self, matched_expressions: List[Tuple[str, str, str]]) -> List[Tuple[str, str, str, List[str]]]: + + def split_expression_context( + self, matched_expressions: List[Tuple[str, str, str]] + ) -> List[Tuple[str, str, str, List[str]]]: """ 对matched_expressions中的context部分进行jieba分词 diff --git a/src/chat/express/expression_selector.py b/src/chat/express/expression_selector.py index 557ffd11..dbb40f6a 100644 --- a/src/chat/express/expression_selector.py +++ b/src/chat/express/expression_selector.py @@ -114,10 +114,10 @@ class ExpressionSelector: def get_related_chat_ids(self, chat_id: str) -> List[str]: """根据expression_groups配置,获取与当前chat_id相关的所有chat_id(包括自身)""" groups = global_config.expression.expression_groups - + # 检查是否存在全局共享组(包含"*"的组) global_group_exists = any("*" in group for group in groups) - + if global_group_exists: # 如果存在全局共享组,则返回所有可用的chat_id all_chat_ids = set() @@ -126,7 +126,7 @@ class ExpressionSelector: if chat_id_candidate := self._parse_stream_config_to_chat_id(stream_config_str): all_chat_ids.add(chat_id_candidate) return list(all_chat_ids) if all_chat_ids else [chat_id] - + # 否则使用现有的组逻辑 for group in groups: group_chat_ids = [] diff --git a/src/chat/frequency_control/frequency_control.py b/src/chat/frequency_control/frequency_control.py index 1d9b1fbb..60056c21 100644 --- a/src/chat/frequency_control/frequency_control.py +++ b/src/chat/frequency_control/frequency_control.py @@ -43,4 +43,4 @@ class FrequencyControlManager: # 创建全局实例 -frequency_control_manager = FrequencyControlManager() \ No newline at end of file +frequency_control_manager = FrequencyControlManager() diff --git a/src/chat/heart_flow/heartFC_chat.py b/src/chat/heart_flow/heartFC_chat.py index 88909b2b..d6a7ca6d 100644 --- a/src/chat/heart_flow/heartFC_chat.py +++ b/src/chat/heart_flow/heartFC_chat.py @@ -206,7 +206,11 @@ class HeartFChatting: # *控制频率用 if mentioned_message: await self._observe(recent_messages_list=recent_messages_list, force_reply_message=mentioned_message) - elif random.random() < global_config.chat.talk_value * frequency_control_manager.get_or_create_frequency_control(self.stream_id).get_talk_frequency_adjust(): + elif ( + random.random() + < global_config.chat.talk_value + * frequency_control_manager.get_or_create_frequency_control(self.stream_id).get_talk_frequency_adjust() + ): await self._observe(recent_messages_list=recent_messages_list) else: # 没有提到,继续保持沉默,等待5秒防止频繁触发 @@ -276,9 +280,8 @@ class HeartFChatting: recent_messages_list = [] reply_text = "" # 初始化reply_text变量,避免UnboundLocalError - start_time = time.time() - + if s4u_config.enable_s4u: await send_typing() @@ -350,7 +353,7 @@ class HeartFChatting: available_actions=available_actions, ) ) - + logger.info( f"{self.log_prefix} 决定执行{len(action_to_use_info)}个动作: {' '.join([a.action_type for a in action_to_use_info])}" ) @@ -412,7 +415,7 @@ class HeartFChatting: }, } reply_text = action_reply_text - + self.end_cycle(loop_info, cycle_timers) self.print_cycle_info(cycle_timers) @@ -423,11 +426,6 @@ class HeartFChatting: else: await asyncio.sleep(0.1) - - - - - """S4U内容,暂时保留""" if s4u_config.enable_s4u: await stop_typing() diff --git a/src/chat/heart_flow/heartflow_message_processor.py b/src/chat/heart_flow/heartflow_message_processor.py index 54c92b35..fdc13e2f 100644 --- a/src/chat/heart_flow/heartflow_message_processor.py +++ b/src/chat/heart_flow/heartflow_message_processor.py @@ -1,10 +1,8 @@ -import asyncio import re import traceback from typing import Tuple, TYPE_CHECKING -from src.config.config import global_config from src.chat.message_receive.message import MessageRecv from src.chat.message_receive.storage import MessageStorage from src.chat.heart_flow.heartflow import heartflow @@ -74,7 +72,7 @@ class HeartFCMessageReceiver: await self.storage.store_message(message, chat) - heartflow_chat: HeartFChatting = await heartflow.get_or_create_heartflow_chat(chat.stream_id) # type: ignore + _heartflow_chat: HeartFChatting = await heartflow.get_or_create_heartflow_chat(chat.stream_id) # type: ignore # 3. 日志记录 mes_name = chat.group_info.group_name if chat.group_info else "私聊" @@ -102,7 +100,7 @@ class HeartFCMessageReceiver: replace_bot_name=True, ) # if not processed_plain_text: - # print(message) + # print(message) logger.info(f"[{mes_name}]{userinfo.user_nickname}:{processed_plain_text}") # type: ignore diff --git a/src/chat/message_receive/bot.py b/src/chat/message_receive/bot.py index d963779b..89e9bb5a 100644 --- a/src/chat/message_receive/bot.py +++ b/src/chat/message_receive/bot.py @@ -8,7 +8,7 @@ from maim_message import UserInfo, Seg, GroupInfo from src.common.logger import get_logger from src.config.config import global_config from src.mood.mood_manager import mood_manager # 导入情绪管理器 -from src.chat.message_receive.chat_stream import get_chat_manager, ChatStream +from src.chat.message_receive.chat_stream import get_chat_manager from src.chat.message_receive.message import MessageRecv, MessageRecvS4U from src.chat.message_receive.storage import MessageStorage from src.chat.heart_flow.heartflow_message_processor import HeartFCMessageReceiver diff --git a/src/chat/planner_actions/planner.py b/src/chat/planner_actions/planner.py index 46967075..edff07aa 100644 --- a/src/chat/planner_actions/planner.py +++ b/src/chat/planner_actions/planner.py @@ -343,7 +343,6 @@ class ActionPlanner: interest=interest, plan_style=global_config.personality.plan_style, ) - return prompt, message_id_list except Exception as e: @@ -502,9 +501,7 @@ class ActionPlanner: action.action_data = action.action_data or {} action.action_data["loop_start_time"] = loop_start_time - logger.debug( - f"{self.log_prefix}规划器选择了{len(actions)}个动作: {' '.join([a.action_type for a in actions])}" - ) + logger.debug(f"{self.log_prefix}规划器选择了{len(actions)}个动作: {' '.join([a.action_type for a in actions])}") return actions diff --git a/src/chat/replyer/group_generator.py b/src/chat/replyer/group_generator.py index 87bfc670..4624fac1 100644 --- a/src/chat/replyer/group_generator.py +++ b/src/chat/replyer/group_generator.py @@ -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.person_info.person_info import Person, is_person_known +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 @@ -42,6 +42,7 @@ init_rewrite_prompt() logger = get_logger("replyer") + class DefaultReplyer: def __init__( self, @@ -215,7 +216,7 @@ class DefaultReplyer: traceback.print_exc() return False, llm_response -#移动到 relation插件中构建 + # 移动到 relation插件中构建 # async def build_relation_info(self, chat_content: str, sender: str, person_list: List[Person]): # if not global_config.relationship.enable_relationship: # return "" @@ -277,9 +278,7 @@ class DefaultReplyer: expression_habits_block = "" expression_habits_title = "" if style_habits_str.strip(): - expression_habits_title = ( - "在回复时,你可以参考以下的语言习惯,不要生硬使用:" - ) + expression_habits_title = "在回复时,你可以参考以下的语言习惯,不要生硬使用:" expression_habits_block += f"{style_habits_str}\n" return f"{expression_habits_title}\n{expression_habits_block}", selected_ids @@ -498,7 +497,6 @@ class DefaultReplyer: -------------------------------- """ - # 构建背景对话 prompt all_dialogue_prompt = "" if message_list_before_now: @@ -524,7 +522,6 @@ class DefaultReplyer: time_block: str, chat_target_1: str, chat_target_2: str, - identity_block: str, sender: str, target: str, @@ -759,13 +756,9 @@ class DefaultReplyer: if sender: if is_group_chat: - reply_target_block = ( - f"现在{sender}说的:{target}。引起了你的注意" - ) + reply_target_block = f"现在{sender}说的:{target}。引起了你的注意" else: # private chat - reply_target_block = ( - f"现在{sender}说的:{target}。引起了你的注意" - ) + reply_target_block = f"现在{sender}说的:{target}。引起了你的注意" else: reply_target_block = "" @@ -1044,6 +1037,3 @@ def weighted_sample_no_replacement(items, weights, k) -> list: pool.pop(idx) break return selected - - - diff --git a/src/chat/replyer/private_generator.py b/src/chat/replyer/private_generator.py index c134b64e..e8f1ad00 100644 --- a/src/chat/replyer/private_generator.py +++ b/src/chat/replyer/private_generator.py @@ -6,7 +6,6 @@ import re from typing import List, Optional, Dict, Any, Tuple from datetime import datetime -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 from src.common.data_models.info_data_model import ActionPlannerInfo @@ -43,6 +42,7 @@ init_rewrite_prompt() logger = get_logger("replyer") + class PrivateReplyer: def __init__( self, @@ -273,9 +273,7 @@ class PrivateReplyer: expression_habits_block = "" expression_habits_title = "" if style_habits_str.strip(): - expression_habits_title = ( - "在回复时,你可以参考以下的语言习惯,不要生硬使用:" - ) + expression_habits_title = "在回复时,你可以参考以下的语言习惯,不要生硬使用:" expression_habits_block += f"{style_habits_str}\n" return f"{expression_habits_title}\n{expression_habits_block}", selected_ids @@ -521,8 +519,6 @@ class PrivateReplyer: sender = person_name target = reply_message.processed_plain_text - - target = replace_user_references(target, chat_stream.platform, replace_bot_name=True) target = re.sub(r"\\[picid:[^\\]]+\\]", "[图片]", target) @@ -531,7 +527,7 @@ class PrivateReplyer: timestamp=time.time(), limit=global_config.chat.max_context_size, ) - + dialogue_prompt = build_readable_messages( message_list_before_now_long, replace_bot_name=True, @@ -579,9 +575,7 @@ class PrivateReplyer: self._time_and_run_task( self.build_expression_habits(chat_talking_prompt_short, target), "expression_habits" ), - self._time_and_run_task( - self.build_relation_info(chat_talking_prompt_short, sender), "relation_info" - ), + self._time_and_run_task(self.build_relation_info(chat_talking_prompt_short, sender), "relation_info"), # self._time_and_run_task(self.build_memory_block(message_list_before_short, target), "memory_block"), self._time_and_run_task( self.build_tool_info(chat_talking_prompt_short, sender, target, enable_tool=enable_tool), "tool_info" @@ -639,9 +633,7 @@ class PrivateReplyer: moderation_prompt_block = "请不要输出违法违规内容,不要输出色情,暴力,政治相关内容,如有敏感内容,请规避。" - reply_target_block = ( - f"现在对方说的:{target}。引起了你的注意" - ) + reply_target_block = f"现在对方说的:{target}。引起了你的注意" if global_config.bot.qq_account == user_id and platform == global_config.bot.platform: return await global_prompt_manager.format_prompt( @@ -654,7 +646,6 @@ class PrivateReplyer: extra_info_block=extra_info_block, identity=personality_prompt, action_descriptions=actions_info, - dialogue_prompt=dialogue_prompt, time_block=time_block, target=target, @@ -698,8 +689,6 @@ class PrivateReplyer: target = replace_user_references(target, chat_stream.platform, replace_bot_name=True) target = re.sub(r"\\[picid:[^\\]]+\\]", "[图片]", target) - - message_list_before_now_half = get_raw_msg_before_timestamp_with_chat( chat_id=chat_id, timestamp=time.time(), @@ -916,6 +905,3 @@ def weighted_sample_no_replacement(items, weights, k) -> list: pool.pop(idx) break return selected - - - diff --git a/src/chat/replyer/prompt/lpmm_prompt.py b/src/chat/replyer/prompt/lpmm_prompt.py index d5d02664..afce7f5e 100644 --- a/src/chat/replyer/prompt/lpmm_prompt.py +++ b/src/chat/replyer/prompt/lpmm_prompt.py @@ -1,9 +1,7 @@ - from src.chat.utils.prompt_builder import Prompt # from src.chat.memory_system.memory_activator import MemoryActivator - def init_lpmm_prompt(): Prompt( """ @@ -20,5 +18,3 @@ If you need to use the search tool, please directly call the function "lpmm_sear """, name="lpmm_get_knowledge_prompt", ) - - diff --git a/src/chat/replyer/prompt/replyer_prompt.py b/src/chat/replyer/prompt/replyer_prompt.py index dd1a434e..997a760c 100644 --- a/src/chat/replyer/prompt/replyer_prompt.py +++ b/src/chat/replyer/prompt/replyer_prompt.py @@ -1,18 +1,15 @@ - from src.chat.utils.prompt_builder import Prompt # from src.chat.memory_system.memory_activator import MemoryActivator - def init_replyer_prompt(): Prompt("你正在qq群里聊天,下面是群里正在聊的内容:", "chat_target_group1") Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1") Prompt("正在群里聊天", "chat_target_group2") Prompt("和{sender_name}聊天", "chat_target_private2") - - + Prompt( -"""{knowledge_prompt}{tool_info_block}{extra_info_block} + """{knowledge_prompt}{tool_info_block}{extra_info_block} {expression_habits_block} 你正在qq群里聊天,下面是群里正在聊的内容: @@ -30,8 +27,6 @@ def init_replyer_prompt(): "replyer_prompt", ) - - Prompt( """{knowledge_prompt}{tool_info_block}{extra_info_block} {expression_habits_block} @@ -50,11 +45,9 @@ def init_replyer_prompt(): """, "replyer_self_prompt", ) - - - + Prompt( -"""{knowledge_prompt}{tool_info_block}{extra_info_block} + """{knowledge_prompt}{tool_info_block}{extra_info_block} {expression_habits_block} 你正在和{sender_name}聊天,这是你们之前聊的内容: @@ -70,10 +63,9 @@ def init_replyer_prompt(): {moderation_prompt}不要输出多余内容(包括前后缀,冒号和引号,括号,表情包,at或 @等 )。""", "private_replyer_prompt", ) - - + Prompt( - """{knowledge_prompt}{tool_info_block}{extra_info_block} + """{knowledge_prompt}{tool_info_block}{extra_info_block} {expression_habits_block} 你正在和{sender_name}聊天,这是你们之前聊的内容: @@ -89,4 +81,4 @@ def init_replyer_prompt(): {moderation_prompt}不要输出多余内容(包括冒号和引号,括号,表情包,at或 @等 )。 """, "private_replyer_self_prompt", - ) \ No newline at end of file + ) diff --git a/src/chat/replyer/prompt/rewrite_prompt.py b/src/chat/replyer/prompt/rewrite_prompt.py index 3118ae88..b96d8cd4 100644 --- a/src/chat/replyer/prompt/rewrite_prompt.py +++ b/src/chat/replyer/prompt/rewrite_prompt.py @@ -1,9 +1,7 @@ - from src.chat.utils.prompt_builder import Prompt # from src.chat.memory_system.memory_activator import MemoryActivator - def init_rewrite_prompt(): Prompt("你正在qq群里聊天,下面是群里正在聊的内容:", "chat_target_group1") Prompt("你正在和{sender_name}聊天,这是你们之前聊的内容:", "chat_target_private1") @@ -31,4 +29,4 @@ def init_rewrite_prompt(): 现在,你说: """, "default_expressor_prompt", - ) \ No newline at end of file + ) diff --git a/src/chat/utils/chat_message_builder.py b/src/chat/utils/chat_message_builder.py index 5488dc9f..b02a9164 100644 --- a/src/chat/utils/chat_message_builder.py +++ b/src/chat/utils/chat_message_builder.py @@ -859,7 +859,6 @@ async def build_anonymous_messages(messages: List[DatabaseMessages]) -> str: # 处理图片ID content = process_pic_ids(content) - anon_name = get_anon_name(platform, user_id) # print(f"anon_name:{anon_name}") @@ -945,11 +944,12 @@ async def build_bare_messages(messages: List[DatabaseMessages]) -> str: # 获取纯文本内容 content = msg.processed_plain_text or "" - # 处理图片ID pic_pattern = r"\[picid:[^\]]+\]" + def replace_pic_id(match): return "[图片]" + content = re.sub(pic_pattern, replace_pic_id, content) # 处理用户引用格式,移除回复和@标记 diff --git a/src/common/data_models/llm_data_model.py b/src/common/data_models/llm_data_model.py index e8d57b41..2d2ee0c3 100644 --- a/src/common/data_models/llm_data_model.py +++ b/src/common/data_models/llm_data_model.py @@ -16,4 +16,4 @@ class LLMGenerationDataModel(BaseDataModel): tool_calls: Optional[List["ToolCall"]] = None prompt: Optional[str] = None selected_expressions: Optional[List[int]] = None - reply_set: Optional["ReplySetModel"] = None \ No newline at end of file + reply_set: Optional["ReplySetModel"] = None diff --git a/src/common/database/database_model.py b/src/common/database/database_model.py index 4c8e6ed3..4684f338 100644 --- a/src/common/database/database_model.py +++ b/src/common/database/database_model.py @@ -732,11 +732,14 @@ def check_field_constraints(): logger.exception(f"检查字段约束时出错: {e}") return inconsistencies + + def fix_image_id(): """ 修复表情包的 image_id 字段 """ import uuid + try: with db: for img in Images.select(): @@ -747,6 +750,7 @@ def fix_image_id(): except Exception as e: logger.exception(f"修复 image_id 时出错: {e}") + # 模块加载时调用初始化函数 initialize_database(sync_constraints=True) -fix_image_id() \ No newline at end of file +fix_image_id() diff --git a/src/config/official_configs.py b/src/config/official_configs.py index b61a234a..87bb4d97 100644 --- a/src/config/official_configs.py +++ b/src/config/official_configs.py @@ -46,13 +46,13 @@ class PersonalityConfig(ConfigBase): interest: str = "" """兴趣""" - + plan_style: str = "" """说话规则,行为风格""" - + visual_style: str = "" """图片提示词""" - + private_plan_style: str = "" """私聊说话规则,行为风格""" @@ -86,7 +86,7 @@ class ChatConfig(ConfigBase): planner_smooth: float = 3 """规划器平滑,增大数值会减小planner负荷,略微降低反应速度,推荐2-5,0为关闭,必须大于等于0""" - + talk_value: float = 1 """思考频率""" @@ -302,6 +302,7 @@ class EmojiConfig(ConfigBase): filtration_prompt: str = "符合公序良俗" """表情包过滤要求""" + @dataclass class KeywordRuleConfig(ConfigBase): """关键词规则配置类""" diff --git a/src/llm_models/exceptions.py b/src/llm_models/exceptions.py index bf1c88de..65e49f74 100644 --- a/src/llm_models/exceptions.py +++ b/src/llm_models/exceptions.py @@ -85,4 +85,4 @@ class ModelAttemptFailed(Exception): self.original_exception = original_exception def __str__(self): - return self.message \ No newline at end of file + return self.message diff --git a/src/llm_models/model_client/gemini_client.py b/src/llm_models/model_client/gemini_client.py index 0713a33a..e8cf44f7 100644 --- a/src/llm_models/model_client/gemini_client.py +++ b/src/llm_models/model_client/gemini_client.py @@ -182,7 +182,7 @@ def _process_delta( if delta.text: fc_delta_buffer.write(delta.text) - + # 处理 thought(Gemini 的特殊字段) for c in getattr(delta, "candidates", []): if c.content and getattr(c.content, "parts", None): @@ -190,7 +190,7 @@ def _process_delta( if getattr(p, "thought", False) and getattr(p, "text", None): # 把 thought 写入 buffer,避免 resp.content 永远为空 fc_delta_buffer.write(p.text) - + if delta.function_calls: # 为什么不用hasattr呢,是因为这个属性一定有,即使是个空的 for call in delta.function_calls: try: @@ -250,11 +250,8 @@ def _build_stream_api_resp( " 可能会对回复内容造成影响,建议修改模型 max_tokens 配置!" ) else: - logger.warning( - "⚠ Gemini 响应因达到 max_tokens 限制被截断,\n" - " 请修改模型 max_tokens 配置!" - ) - + logger.warning("⚠ Gemini 响应因达到 max_tokens 限制被截断,\n 请修改模型 max_tokens 配置!") + if not resp.content and not resp.tool_calls: raise EmptyResponseException() @@ -387,10 +384,7 @@ def _default_normal_response_parser( " 可能会对回复内容造成影响,建议修改模型 max_tokens 配置!" ) else: - logger.warning( - "⚠ Gemini 响应因达到 max_tokens 限制被截断,\n" - " 请修改模型 max_tokens 配置!" - ) + logger.warning("⚠ Gemini 响应因达到 max_tokens 限制被截断,\n 请修改模型 max_tokens 配置!") return api_response, _usage_record except Exception as e: @@ -447,7 +441,7 @@ class GeminiClient(BaseClient): logger.warning( f"无效的 thinking_budget 值 {extra_params['thinking_budget']},将使用模型自动预算模式 {tb}" ) - + # 优先尝试精确匹配 if model_id in THINKING_BUDGET_LIMITS: limits = THINKING_BUDGET_LIMITS[model_id] @@ -532,7 +526,7 @@ class GeminiClient(BaseClient): tools = _convert_tool_options(tool_options) if tool_options else None # 解析并裁剪 thinking_budget tb = self.clamp_thinking_budget(extra_params, model_info.model_identifier) - + # 将response_format转换为Gemini API所需的格式 generation_config_dict = { "max_output_tokens": max_tokens, diff --git a/src/llm_models/model_client/openai_client.py b/src/llm_models/model_client/openai_client.py index 92632222..148ec8cb 100644 --- a/src/llm_models/model_client/openai_client.py +++ b/src/llm_models/model_client/openai_client.py @@ -487,7 +487,7 @@ class OpenaiClient(BaseClient): req_task.cancel() raise ReqAbortException("请求被外部信号中断") await asyncio.sleep(0.1) # 等待0.5秒后再次检查任务&中断信号量状态 - + # logger. logger.debug(f"OpenAI API响应(非流式): {req_task.result()}") @@ -511,7 +511,7 @@ class OpenaiClient(BaseClient): ) # logger.debug(f"OpenAI API响应: {resp}") - + return resp async def get_embedding( diff --git a/src/llm_models/utils_model.py b/src/llm_models/utils_model.py index 78631d6b..4d7865d9 100644 --- a/src/llm_models/utils_model.py +++ b/src/llm_models/utils_model.py @@ -149,7 +149,7 @@ class LLMRequest: logger.debug(f"LLM请求总耗时: {time.time() - start_time}") logger.debug(f"LLM生成内容: {response}") - + content = response.content reasoning_content = response.reasoning_content or "" tool_calls = response.tool_calls diff --git a/src/mood/mood_manager.py b/src/mood/mood_manager.py index d0832d18..3978d738 100644 --- a/src/mood/mood_manager.py +++ b/src/mood/mood_manager.py @@ -44,7 +44,7 @@ def init_prompt(): """, "get_mood_prompt", ) - + Prompt( """ {chat_talking_prompt} @@ -103,9 +103,7 @@ class ChatMood: if random.random() > update_probability: return - logger.debug( - f"{self.log_prefix} 更新情绪状态,更新概率: {update_probability:.2f}" - ) + logger.debug(f"{self.log_prefix} 更新情绪状态,更新概率: {update_probability:.2f}") message_time: float = message.message_info.time # type: ignore message_list_before_now = get_raw_msg_by_timestamp_with_chat_inclusive( @@ -154,12 +152,12 @@ class ChatMood: self.mood_state = response self.last_change_time = message_time - + async def get_mood(self) -> str: self.regression_count = 0 current_time = time.time() - + logger.info(f"{self.log_prefix} 获取情绪状态") message_list_before_now = get_raw_msg_by_timestamp_with_chat_inclusive( chat_id=self.chat_id, @@ -207,7 +205,7 @@ class ChatMood: self.mood_state = response self.last_change_time = current_time - + return response async def regress_mood(self): diff --git a/src/person_info/person_info.py b/src/person_info/person_info.py index f4aeecc7..7793da31 100644 --- a/src/person_info/person_info.py +++ b/src/person_info/person_info.py @@ -17,7 +17,9 @@ from src.config.config import global_config, model_config logger = get_logger("person_info") -relation_selection_model = LLMRequest(model_set=model_config.model_task_config.utils_small, request_type="relation_selection") +relation_selection_model = LLMRequest( + model_set=model_config.model_task_config.utils_small, request_type="relation_selection" +) def get_person_id(platform: str, user_id: Union[int, str]) -> str: @@ -91,9 +93,10 @@ def extract_categories_from_response(response: str) -> list[str]: """从response中提取所有<>包裹的内容""" if not isinstance(response, str): return [] - + import re - pattern = r'<([^<>]+)>' + + pattern = r"<([^<>]+)>" matches = re.findall(pattern, response) return matches @@ -420,7 +423,7 @@ class Person: except Exception as e: logger.error(f"同步用户 {self.person_id} 信息到数据库时出错: {e}") - async def build_relationship(self,chat_content:str = "",info_type = ""): + async def build_relationship(self, chat_content: str = "", info_type=""): if not self.is_known: return "" # 构建points文本 @@ -433,7 +436,7 @@ class Person: points_text = "" category_list = self.get_all_category() - + if chat_content: prompt = f"""当前聊天内容: {chat_content} @@ -449,11 +452,13 @@ class Person: # print(prompt) # print(response) category_list = extract_categories_from_response(response) - if "none" not in category_list: + if "none" not in category_list: for category in category_list: random_memory = self.get_random_memory_by_category(category, 2) if random_memory: - random_memory_str = "\n".join([get_memory_content_from_memory(memory) for memory in random_memory]) + random_memory_str = "\n".join( + [get_memory_content_from_memory(memory) for memory in random_memory] + ) points_text = f"有关 {category} 的内容:{random_memory_str}" break elif info_type: @@ -469,15 +474,16 @@ class Person: # print(prompt) # print(response) category_list = extract_categories_from_response(response) - if "none" not in category_list: + if "none" not in category_list: for category in category_list: random_memory = self.get_random_memory_by_category(category, 3) if random_memory: - random_memory_str = "\n".join([get_memory_content_from_memory(memory) for memory in random_memory]) + random_memory_str = "\n".join( + [get_memory_content_from_memory(memory) for memory in random_memory] + ) points_text = f"有关 {category} 的内容:{random_memory_str}" break else: - for category in category_list: random_memory = self.get_random_memory_by_category(category, 1)[0] if random_memory: diff --git a/src/plugin_system/apis/emoji_api.py b/src/plugin_system/apis/emoji_api.py index 6d142a9e..e1661887 100644 --- a/src/plugin_system/apis/emoji_api.py +++ b/src/plugin_system/apis/emoji_api.py @@ -12,7 +12,6 @@ import random import base64 import os import uuid -import time from typing import Optional, Tuple, List, Dict, Any from src.common.logger import get_logger @@ -358,7 +357,7 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D "description": None, "emotions": None, "replaced": None, - "hash": None + "hash": None, } # 3. 确保emoji目录存在 @@ -368,19 +367,21 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D if not filename: # 基于时间戳、微秒和短base64生成唯一文件名 import time + timestamp = int(time.time()) microseconds = int(time.time() * 1000000) % 1000000 # 添加微秒级精度 # 生成12位随机标识符,使用base64编码(增加随机性) import random - random_bytes = random.getrandbits(72).to_bytes(9, 'big') # 72位 = 9字节 = 12位base64 - short_id = base64.b64encode(random_bytes).decode('ascii')[:12].rstrip('=') + + random_bytes = random.getrandbits(72).to_bytes(9, "big") # 72位 = 9字节 = 12位base64 + short_id = base64.b64encode(random_bytes).decode("ascii")[:12].rstrip("=") # 确保base64编码适合文件名(替换/和-) - short_id = short_id.replace('/', '_').replace('+', '-') + short_id = short_id.replace("/", "_").replace("+", "-") filename = f"emoji_{timestamp}_{microseconds}_{short_id}" # 确保文件名有扩展名 - if not filename.lower().endswith(('.jpg', '.jpeg', '.png', '.gif')): + if not filename.lower().endswith((".jpg", ".jpeg", ".png", ".gif")): filename = f"{filename}.png" # 默认使用png格式 # 检查文件名是否已存在,如果存在则重新生成短标识符 @@ -390,14 +391,15 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D while os.path.exists(temp_file_path) and attempts < max_attempts: # 重新生成短标识符 import random - random_bytes = random.getrandbits(48).to_bytes(6, 'big') - short_id = base64.b64encode(random_bytes).decode('ascii')[:8].rstrip('=') - short_id = short_id.replace('/', '_').replace('+', '-') + + random_bytes = random.getrandbits(48).to_bytes(6, "big") + short_id = base64.b64encode(random_bytes).decode("ascii")[:8].rstrip("=") + short_id = short_id.replace("/", "_").replace("+", "-") # 分离文件名和扩展名,重新生成文件名 name_part, ext = os.path.splitext(filename) # 去掉原来的标识符,添加新的 - base_name = name_part.rsplit('_', 1)[0] # 移除最后一个_后的部分 + base_name = name_part.rsplit("_", 1)[0] # 移除最后一个_后的部分 filename = f"{base_name}_{short_id}{ext}" temp_file_path = os.path.join(EMOJI_DIR, filename) attempts += 1 @@ -406,7 +408,7 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D if os.path.exists(temp_file_path): uuid_short = str(uuid.uuid4())[:8] name_part, ext = os.path.splitext(filename) - base_name = name_part.rsplit('_', 1)[0] + base_name = name_part.rsplit("_", 1)[0] filename = f"{base_name}_{uuid_short}{ext}" temp_file_path = os.path.join(EMOJI_DIR, filename) @@ -428,7 +430,7 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D "description": None, "emotions": None, "replaced": None, - "hash": None + "hash": None, } # 5. 保存base64图片到emoji目录 @@ -443,7 +445,7 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D "description": None, "emotions": None, "replaced": None, - "hash": None + "hash": None, } logger.debug(f"[EmojiAPI] 图片已保存到临时文件: {temp_file_path}") @@ -456,7 +458,7 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D "description": None, "emotions": None, "replaced": None, - "hash": None + "hash": None, } # 6. 调用注册方法 @@ -483,8 +485,8 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D # 通过文件名查找新注册的表情包(注意:文件名在注册后可能已经改变) for emoji_obj in reversed(emoji_manager.emoji_objects): if not emoji_obj.is_deleted and ( - emoji_obj.filename == filename or # 直接匹配 - (hasattr(emoji_obj, 'full_path') and filename in emoji_obj.full_path) # 路径包含匹配 + emoji_obj.filename == filename # 直接匹配 + or (hasattr(emoji_obj, "full_path") and filename in emoji_obj.full_path) # 路径包含匹配 ): new_emoji_info = emoji_obj break @@ -501,7 +503,7 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D "description": description, "emotions": emotions, "replaced": replaced, - "hash": emoji_hash + "hash": emoji_hash, } else: return { @@ -510,7 +512,7 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D "description": None, "emotions": None, "replaced": None, - "hash": None + "hash": None, } except Exception as e: @@ -521,7 +523,7 @@ async def register_emoji(image_base64: str, filename: Optional[str] = None) -> D "description": None, "emotions": None, "replaced": None, - "hash": None + "hash": None, } @@ -585,16 +587,16 @@ async def delete_emoji(emoji_hash: str) -> Dict[str, Any]: "count_before": count_before, "count_after": count_after, "description": description, - "emotions": emotions + "emotions": emotions, } else: return { "success": False, - "message": f"表情包删除失败,可能因为哈希值不存在或删除过程出错", + "message": "表情包删除失败,可能因为哈希值不存在或删除过程出错", "count_before": count_before, "count_after": count_after, "description": None, - "emotions": None + "emotions": None, } except Exception as e: @@ -605,7 +607,7 @@ async def delete_emoji(emoji_hash: str) -> Dict[str, Any]: "count_before": None, "count_after": None, "description": None, - "emotions": None + "emotions": None, } @@ -659,7 +661,7 @@ async def delete_emoji_by_description(description: str, exact_match: bool = Fals "message": f"未找到匹配描述 '{description}' 的表情包", "deleted_count": 0, "deleted_hashes": [], - "matched_count": 0 + "matched_count": 0, } # 删除匹配的表情包 @@ -681,7 +683,7 @@ async def delete_emoji_by_description(description: str, exact_match: bool = Fals "message": f"成功删除 {deleted_count} 个表情包 (匹配到 {matched_count} 个)", "deleted_count": deleted_count, "deleted_hashes": deleted_hashes, - "matched_count": matched_count + "matched_count": matched_count, } else: return { @@ -689,7 +691,7 @@ async def delete_emoji_by_description(description: str, exact_match: bool = Fals "message": f"匹配到 {matched_count} 个表情包,但删除全部失败", "deleted_count": 0, "deleted_hashes": [], - "matched_count": matched_count + "matched_count": matched_count, } except Exception as e: @@ -699,5 +701,5 @@ async def delete_emoji_by_description(description: str, exact_match: bool = Fals "message": f"删除过程中发生错误: {str(e)}", "deleted_count": 0, "deleted_hashes": [], - "matched_count": 0 + "matched_count": 0, } diff --git a/src/plugin_system/apis/frequency_api.py b/src/plugin_system/apis/frequency_api.py index 51d10a09..68c1fa5a 100644 --- a/src/plugin_system/apis/frequency_api.py +++ b/src/plugin_system/apis/frequency_api.py @@ -3,13 +3,14 @@ from src.chat.frequency_control.frequency_control import frequency_control_manag logger = get_logger("frequency_api") + def get_current_talk_frequency(chat_id: str) -> float: return frequency_control_manager.get_or_create_frequency_control(chat_id).get_talk_frequency_adjust() + def set_talk_frequency_adjust(chat_id: str, talk_frequency_adjust: float) -> None: - frequency_control_manager.get_or_create_frequency_control( - chat_id - ).set_talk_frequency_adjust(talk_frequency_adjust) + frequency_control_manager.get_or_create_frequency_control(chat_id).set_talk_frequency_adjust(talk_frequency_adjust) + def get_talk_frequency_adjust(chat_id: str) -> float: return frequency_control_manager.get_or_create_frequency_control(chat_id).get_talk_frequency_adjust() diff --git a/src/plugin_system/apis/mood_api.py b/src/plugin_system/apis/mood_api.py index 10094021..d5300e9f 100644 --- a/src/plugin_system/apis/mood_api.py +++ b/src/plugin_system/apis/mood_api.py @@ -1,9 +1,6 @@ import asyncio -import traceback -import time -from typing import Optional, Union, Dict, List, TYPE_CHECKING, Tuple +from typing import Optional -from src.chat.message_receive import message from src.common.logger import get_logger from src.mood.mood_manager import mood_manager @@ -12,5 +9,5 @@ logger = get_logger("mood_api") async def get_mood_by_chat_id(chat_id: str) -> Optional[float]: chat_mood = mood_manager.get_mood_by_chat_id(chat_id) - mood = asyncio.create_task(chat_mood.get_mood()) - return mood \ No newline at end of file + mood = asyncio.create_task(chat_mood.get_mood()) + return mood diff --git a/src/plugin_system/apis/send_api.py b/src/plugin_system/apis/send_api.py index e73504a4..fd2b723f 100644 --- a/src/plugin_system/apis/send_api.py +++ b/src/plugin_system/apis/send_api.py @@ -363,7 +363,7 @@ async def custom_reply_set_to_stream( ) -> bool: """ 向指定流发送混合型消息集 - + Args: reply_set: ReplySetModel 对象,包含多个 ReplyContent stream_id: 聊天流ID @@ -451,7 +451,9 @@ def _parse_content_to_seg(reply_content: "ReplyContent") -> Tuple[Seg, bool]: single_node_content.append(sub_seg) message_segment = Seg(type="seglist", data=single_node_content) forward_message_list.append( - MessageBase(message_segment=message_segment, message_info=BaseMessageInfo(user_info=user_info)).to_dict() + MessageBase( + message_segment=message_segment, message_info=BaseMessageInfo(user_info=user_info) + ).to_dict() ) return Seg(type="forward", data=forward_message_list), False # type: ignore else: diff --git a/src/plugin_system/core/tool_use.py b/src/plugin_system/core/tool_use.py index 56768a33..5c8b0033 100644 --- a/src/plugin_system/core/tool_use.py +++ b/src/plugin_system/core/tool_use.py @@ -91,7 +91,7 @@ class ToolExecutor: # 缓存未命中,执行工具调用 # 获取可用工具 tools = self._get_tool_definitions() - + # print(f"tools: {tools}") # 获取当前时间 diff --git a/src/plugins/built_in/emoji_plugin/emoji.py b/src/plugins/built_in/emoji_plugin/emoji.py index 63a9cc51..91f3ff0e 100644 --- a/src/plugins/built_in/emoji_plugin/emoji.py +++ b/src/plugins/built_in/emoji_plugin/emoji.py @@ -48,7 +48,7 @@ class EmojiAction(BaseAction): # 1. 获取发送表情的原因 # reason = self.action_data.get("reason", "表达当前情绪") reason = self.reasoning - + # 2. 随机获取20个表情包 sampled_emojis = await emoji_api.get_random(30) if not sampled_emojis: diff --git a/src/plugins/built_in/relation/plugin.py b/src/plugins/built_in/relation/plugin.py index 500dae39..577eb94c 100644 --- a/src/plugins/built_in/relation/plugin.py +++ b/src/plugins/built_in/relation/plugin.py @@ -14,7 +14,6 @@ from src.plugins.built_in.relation.relation import BuildRelationAction logger = get_logger("relation_actions") - class GetPersonInfoTool(BaseTool): """获取用户信息""" @@ -24,7 +23,7 @@ class GetPersonInfoTool(BaseTool): ("person_name", ToolParamType.STRING, "需要获取信息的人的名称", True, None), ("info_type", ToolParamType.STRING, "需要获取信息的类型", True, None), ] - + available_for_llm = True async def execute(self, function_args: dict[str, Any]) -> dict[str, Any]: @@ -44,7 +43,7 @@ class GetPersonInfoTool(BaseTool): return {"content": f"用户 {person_name} 不存在"} if not person.is_known: return {"content": f"不认识用户 {person_name}"} - + relation_str = await person.build_relationship(info_type=info_type) return {"content": relation_str}