fix:修复路径遗留问题
This commit is contained in:
@@ -172,7 +172,7 @@ ChatState.ABSENT # 离开模式
|
|||||||
|
|
||||||
```python
|
```python
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from src.chat.actions.plugin_action import PluginAction, register_action
|
from src.plugin_system.base.base_action import BaseAction as PluginAction, register_action
|
||||||
from src.chat.heart_flow.sub_heartflow import ChatState
|
from src.chat.heart_flow.sub_heartflow import ChatState
|
||||||
|
|
||||||
@register_action
|
@register_action
|
||||||
|
|||||||
@@ -1,216 +0,0 @@
|
|||||||
import re
|
|
||||||
from abc import ABC, abstractmethod
|
|
||||||
from typing import Dict, List, Type, Optional, Tuple, Pattern
|
|
||||||
from src.common.logger import get_logger
|
|
||||||
from src.chat.message_receive.message import MessageRecv
|
|
||||||
from src.chat.focus_chat.hfc_utils import create_empty_anchor_message
|
|
||||||
from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor
|
|
||||||
|
|
||||||
logger = get_logger("command_handler")
|
|
||||||
|
|
||||||
# 全局命令注册表
|
|
||||||
_COMMAND_REGISTRY: Dict[str, Type["BaseCommand"]] = {}
|
|
||||||
_COMMAND_PATTERNS: Dict[Pattern, Type["BaseCommand"]] = {}
|
|
||||||
|
|
||||||
|
|
||||||
class BaseCommand(ABC):
|
|
||||||
"""命令基类,所有自定义命令都应该继承这个类"""
|
|
||||||
|
|
||||||
# 命令的基本属性
|
|
||||||
command_name: str = "" # 命令名称
|
|
||||||
command_description: str = "" # 命令描述
|
|
||||||
command_pattern: str = "" # 命令匹配模式(正则表达式)
|
|
||||||
command_help: str = "" # 命令帮助信息
|
|
||||||
command_examples: List[str] = [] # 命令使用示例
|
|
||||||
enable_command: bool = True # 是否启用命令
|
|
||||||
|
|
||||||
def __init__(self, message: MessageRecv):
|
|
||||||
"""初始化命令处理器
|
|
||||||
|
|
||||||
Args:
|
|
||||||
message: 接收到的消息对象
|
|
||||||
"""
|
|
||||||
self.message = message
|
|
||||||
self.matched_groups: Dict[str, str] = {} # 存储正则表达式匹配的命名组
|
|
||||||
self._services = {"chat_stream": message.chat_stream} # 存储内部服务
|
|
||||||
|
|
||||||
# 日志前缀
|
|
||||||
self.log_prefix = f"[Command:{self.command_name}]"
|
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
async def execute(self) -> Tuple[bool, Optional[str]]:
|
|
||||||
"""执行命令的抽象方法,需要被子类实现
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Tuple[bool, Optional[str]]: (是否执行成功, 可选的回复消息)
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def set_matched_groups(self, groups: Dict[str, str]) -> None:
|
|
||||||
"""设置正则表达式匹配的命名组
|
|
||||||
|
|
||||||
Args:
|
|
||||||
groups: 正则表达式匹配的命名组
|
|
||||||
"""
|
|
||||||
self.matched_groups = groups
|
|
||||||
|
|
||||||
async def send_reply(self, content: str) -> None:
|
|
||||||
"""发送回复消息
|
|
||||||
|
|
||||||
Args:
|
|
||||||
content: 回复内容
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
# 获取聊天流
|
|
||||||
chat_stream = self.message.chat_stream
|
|
||||||
if not chat_stream:
|
|
||||||
logger.error(f"{self.log_prefix} 无法发送消息:缺少chat_stream")
|
|
||||||
return
|
|
||||||
|
|
||||||
# 创建空的锚定消息
|
|
||||||
anchor_message = await create_empty_anchor_message(
|
|
||||||
chat_stream.platform, chat_stream.group_info, chat_stream
|
|
||||||
)
|
|
||||||
|
|
||||||
# 创建表达器,传入chat_stream参数
|
|
||||||
expressor = DefaultExpressor(chat_stream)
|
|
||||||
|
|
||||||
# 设置服务
|
|
||||||
self._services["expressor"] = expressor
|
|
||||||
|
|
||||||
# 发送消息
|
|
||||||
response_set = [
|
|
||||||
("text", content),
|
|
||||||
]
|
|
||||||
|
|
||||||
# 调用表达器发送消息
|
|
||||||
await expressor.send_response_messages(
|
|
||||||
anchor_message=anchor_message,
|
|
||||||
response_set=response_set,
|
|
||||||
display_message="",
|
|
||||||
)
|
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 命令回复消息发送成功: {content[:30]}...")
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"{self.log_prefix} 发送命令回复消息失败: {e}")
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
logger.error(traceback.format_exc())
|
|
||||||
|
|
||||||
|
|
||||||
def register_command(cls):
|
|
||||||
"""
|
|
||||||
命令注册装饰器
|
|
||||||
|
|
||||||
用法:
|
|
||||||
@register_command
|
|
||||||
class MyCommand(BaseCommand):
|
|
||||||
command_name = "my_command"
|
|
||||||
command_description = "我的命令"
|
|
||||||
command_pattern = r"^/mycommand\s+(?P<arg1>\w+)\s+(?P<arg2>\w+)$"
|
|
||||||
...
|
|
||||||
"""
|
|
||||||
# 检查类是否有必要的属性
|
|
||||||
if (
|
|
||||||
not hasattr(cls, "command_name")
|
|
||||||
or not hasattr(cls, "command_description")
|
|
||||||
or not hasattr(cls, "command_pattern")
|
|
||||||
):
|
|
||||||
logger.error(f"命令类 {cls.__name__} 缺少必要的属性: command_name, command_description 或 command_pattern")
|
|
||||||
return cls
|
|
||||||
|
|
||||||
command_name = cls.command_name
|
|
||||||
command_pattern = cls.command_pattern
|
|
||||||
is_enabled = getattr(cls, "enable_command", True) # 默认启用命令
|
|
||||||
|
|
||||||
if not command_name or not command_pattern:
|
|
||||||
logger.error(f"命令类 {cls.__name__} 的 command_name 或 command_pattern 为空")
|
|
||||||
return cls
|
|
||||||
|
|
||||||
# 将命令类注册到全局注册表
|
|
||||||
_COMMAND_REGISTRY[command_name] = cls
|
|
||||||
|
|
||||||
# 编译正则表达式并注册
|
|
||||||
try:
|
|
||||||
pattern = re.compile(command_pattern, re.IGNORECASE | re.DOTALL)
|
|
||||||
_COMMAND_PATTERNS[pattern] = cls
|
|
||||||
logger.info(f"已注册命令: {command_name} -> {cls.__name__},命令启用: {is_enabled}")
|
|
||||||
except re.error as e:
|
|
||||||
logger.error(f"命令 {command_name} 的正则表达式编译失败: {e}")
|
|
||||||
|
|
||||||
return cls
|
|
||||||
|
|
||||||
|
|
||||||
class CommandManager:
|
|
||||||
"""命令管理器,负责处理命令(不再负责加载,加载由统一的插件加载器处理)"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
"""初始化命令管理器"""
|
|
||||||
# 命令加载现在由统一的插件加载器处理,这里只需要初始化
|
|
||||||
logger.info("命令管理器初始化完成")
|
|
||||||
|
|
||||||
async def process_command(self, message: MessageRecv) -> Tuple[bool, Optional[str], bool]:
|
|
||||||
"""处理消息中的命令
|
|
||||||
|
|
||||||
Args:
|
|
||||||
message: 接收到的消息对象
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Tuple[bool, Optional[str], bool]: (是否找到并执行了命令, 命令执行结果, 是否继续处理消息)
|
|
||||||
"""
|
|
||||||
if not message.processed_plain_text:
|
|
||||||
await message.process()
|
|
||||||
|
|
||||||
text = message.processed_plain_text
|
|
||||||
|
|
||||||
# 检查是否匹配任何命令模式
|
|
||||||
for pattern, command_cls in _COMMAND_PATTERNS.items():
|
|
||||||
match = pattern.match(text)
|
|
||||||
if match and getattr(command_cls, "enable_command", True):
|
|
||||||
# 创建命令实例
|
|
||||||
command_instance = command_cls(message)
|
|
||||||
|
|
||||||
# 提取命名组并设置
|
|
||||||
groups = match.groupdict()
|
|
||||||
command_instance.set_matched_groups(groups)
|
|
||||||
|
|
||||||
try:
|
|
||||||
# 执行命令
|
|
||||||
success, response = await command_instance.execute()
|
|
||||||
|
|
||||||
# 记录命令执行结果
|
|
||||||
if success:
|
|
||||||
logger.info(f"命令 {command_cls.command_name} 执行成功")
|
|
||||||
if response:
|
|
||||||
# 使用命令实例的send_reply方法发送回复
|
|
||||||
await command_instance.send_reply(response)
|
|
||||||
else:
|
|
||||||
logger.warning(f"命令 {command_cls.command_name} 执行失败: {response}")
|
|
||||||
if response:
|
|
||||||
# 使用命令实例的send_reply方法发送错误信息
|
|
||||||
await command_instance.send_reply(f"命令执行失败: {response}")
|
|
||||||
|
|
||||||
# 命令执行后不再继续处理消息
|
|
||||||
return True, response, False
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"执行命令 {command_cls.command_name} 时出错: {e}")
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
logger.error(traceback.format_exc())
|
|
||||||
|
|
||||||
try:
|
|
||||||
# 使用命令实例的send_reply方法发送错误信息
|
|
||||||
await command_instance.send_reply(f"命令执行出错: {str(e)}")
|
|
||||||
except Exception as send_error:
|
|
||||||
logger.error(f"发送错误消息失败: {send_error}")
|
|
||||||
|
|
||||||
# 命令执行出错后不再继续处理消息
|
|
||||||
return True, str(e), False
|
|
||||||
|
|
||||||
# 没有匹配到任何命令,继续处理消息
|
|
||||||
return False, None, True
|
|
||||||
|
|
||||||
|
|
||||||
# 创建全局命令管理器实例
|
|
||||||
command_manager = CommandManager()
|
|
||||||
@@ -15,8 +15,6 @@ from src.chat.focus_chat.info.info_base import InfoBase
|
|||||||
from src.chat.focus_chat.info_processors.chattinginfo_processor import ChattingInfoProcessor
|
from src.chat.focus_chat.info_processors.chattinginfo_processor import ChattingInfoProcessor
|
||||||
from src.chat.focus_chat.info_processors.relationship_processor import RelationshipProcessor
|
from src.chat.focus_chat.info_processors.relationship_processor import RelationshipProcessor
|
||||||
from src.chat.focus_chat.info_processors.working_memory_processor import WorkingMemoryProcessor
|
from src.chat.focus_chat.info_processors.working_memory_processor import WorkingMemoryProcessor
|
||||||
|
|
||||||
# from src.chat.focus_chat.info_processors.action_processor import ActionProcessor
|
|
||||||
from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation
|
from src.chat.heart_flow.observation.hfcloop_observation import HFCloopObservation
|
||||||
from src.chat.heart_flow.observation.working_observation import WorkingMemoryObservation
|
from src.chat.heart_flow.observation.working_observation import WorkingMemoryObservation
|
||||||
from src.chat.heart_flow.observation.chatting_observation import ChattingObservation
|
from src.chat.heart_flow.observation.chatting_observation import ChattingObservation
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
from typing import Dict, List, Optional, Type, Any
|
from typing import Dict, List, Optional, Type, Any
|
||||||
from src.chat.actions.base_action import BaseAction, _ACTION_REGISTRY
|
from src.plugin_system.base.base_action import BaseAction, _ACTION_REGISTRY
|
||||||
from src.chat.heart_flow.observation.observation import Observation
|
from src.chat.heart_flow.observation.observation import Observation
|
||||||
from src.chat.focus_chat.replyer.default_replyer import DefaultReplyer
|
from src.chat.focus_chat.replyer.default_replyer import DefaultReplyer
|
||||||
from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor
|
from src.chat.focus_chat.expressors.default_expressor import DefaultExpressor
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ from src.chat.heart_flow.observation.chatting_observation import ChattingObserva
|
|||||||
from src.chat.message_receive.chat_stream import get_chat_manager
|
from src.chat.message_receive.chat_stream import get_chat_manager
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
from src.llm_models.utils_model import LLMRequest
|
from src.llm_models.utils_model import LLMRequest
|
||||||
from src.chat.actions.base_action import ActionActivationType, ChatMode
|
from src.plugin_system.base.base_action import ActionActivationType, ChatMode
|
||||||
import random
|
import random
|
||||||
import asyncio
|
import asyncio
|
||||||
import hashlib
|
import hashlib
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ from src.common.logger import get_logger
|
|||||||
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
|
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
|
||||||
from src.individuality.individuality import get_individuality
|
from src.individuality.individuality import get_individuality
|
||||||
from src.chat.focus_chat.planners.action_manager import ActionManager
|
from src.chat.focus_chat.planners.action_manager import ActionManager
|
||||||
from src.chat.actions.base_action import ChatMode
|
from src.plugin_system.base.base_action import ChatMode
|
||||||
from json_repair import repair_json
|
from json_repair import repair_json
|
||||||
from src.chat.focus_chat.planners.base_planner import BasePlanner
|
from src.chat.focus_chat.planners.base_planner import BasePlanner
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
from typing import List, Any, Dict
|
from typing import List, Any, Dict
|
||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.chat.focus_chat.planners.action_manager import ActionManager
|
from src.chat.focus_chat.planners.action_manager import ActionManager
|
||||||
from src.chat.actions.base_action import ActionActivationType, ChatMode
|
from src.plugin_system.base.base_action import ActionActivationType, ChatMode
|
||||||
from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat
|
from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat
|
||||||
from src.config.config import global_config
|
from src.config.config import global_config
|
||||||
import random
|
import random
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ from src.common.logger import get_logger
|
|||||||
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
|
from src.chat.utils.prompt_builder import Prompt, global_prompt_manager
|
||||||
from src.individuality.individuality import get_individuality
|
from src.individuality.individuality import get_individuality
|
||||||
from src.chat.focus_chat.planners.action_manager import ActionManager
|
from src.chat.focus_chat.planners.action_manager import ActionManager
|
||||||
from src.chat.actions.base_action import ChatMode
|
from src.plugin_system.base.base_action import ChatMode
|
||||||
from src.chat.message_receive.message import MessageThinking
|
from src.chat.message_receive.message import MessageThinking
|
||||||
from json_repair import repair_json
|
from json_repair import repair_json
|
||||||
from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat
|
from src.chat.utils.chat_message_builder import build_readable_messages, get_raw_msg_before_timestamp_with_chat
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ class BaseAction(ABC):
|
|||||||
return attr.value
|
return attr.value
|
||||||
return str(attr)
|
return str(attr)
|
||||||
|
|
||||||
async def send_reply(self, content: str) -> bool:
|
async def send_text(self, content: str) -> bool:
|
||||||
"""发送回复消息
|
"""发送回复消息
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -137,7 +137,7 @@ class BaseAction(ABC):
|
|||||||
text=content, user_id=str(chat_stream.user_info.user_id), platform=chat_stream.platform
|
text=content, user_id=str(chat_stream.user_info.user_id), platform=chat_stream.platform
|
||||||
)
|
)
|
||||||
|
|
||||||
async def send_type_reply(self, type: str, text: str) -> bool:
|
async def send_type(self, type: str, text: str) -> bool:
|
||||||
"""发送回复消息
|
"""发送回复消息
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -173,7 +173,7 @@ class BaseAction(ABC):
|
|||||||
async def send_command(self, command_name: str, args: dict = None, display_message: str = None) -> bool:
|
async def send_command(self, command_name: str, args: dict = None, display_message: str = None) -> bool:
|
||||||
"""发送命令消息
|
"""发送命令消息
|
||||||
|
|
||||||
使用和send_reply相同的方式通过MessageAPI发送命令
|
使用和send_text相同的方式通过MessageAPI发送命令
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
command_name: 命令名称
|
command_name: 命令名称
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ class BaseCommand(ABC):
|
|||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
async def send_reply(self, content: str) -> None:
|
async def send_text(self, content: str) -> None:
|
||||||
"""发送回复消息
|
"""发送回复消息
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@@ -80,10 +80,45 @@ class BaseCommand(ABC):
|
|||||||
text=content, user_id=str(chat_stream.user_info.user_id), platform=chat_stream.platform
|
text=content, user_id=str(chat_stream.user_info.user_id), platform=chat_stream.platform
|
||||||
)
|
)
|
||||||
|
|
||||||
|
async def send_type(self, message_type: str, content: str, display_message: str = None) -> bool:
|
||||||
|
"""发送指定类型的回复消息到当前聊天环境
|
||||||
|
|
||||||
|
Args:
|
||||||
|
message_type: 消息类型,如"text"、"image"、"emoji"等
|
||||||
|
content: 消息内容
|
||||||
|
display_message: 显示消息(可选)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: 是否发送成功
|
||||||
|
"""
|
||||||
|
# 获取聊天流信息
|
||||||
|
chat_stream = self.message.chat_stream
|
||||||
|
|
||||||
|
if chat_stream.group_info:
|
||||||
|
# 群聊
|
||||||
|
return await self.api.send_message_to_target(
|
||||||
|
message_type=message_type,
|
||||||
|
content=content,
|
||||||
|
platform=chat_stream.platform,
|
||||||
|
target_id=str(chat_stream.group_info.group_id),
|
||||||
|
is_group=True,
|
||||||
|
display_message=display_message,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
# 私聊
|
||||||
|
return await self.api.send_message_to_target(
|
||||||
|
message_type=message_type,
|
||||||
|
content=content,
|
||||||
|
platform=chat_stream.platform,
|
||||||
|
target_id=str(chat_stream.user_info.user_id),
|
||||||
|
is_group=False,
|
||||||
|
display_message=display_message,
|
||||||
|
)
|
||||||
|
|
||||||
async def send_command(self, command_name: str, args: dict = None, display_message: str = None) -> bool:
|
async def send_command(self, command_name: str, args: dict = None, display_message: str = None) -> bool:
|
||||||
"""发送命令消息
|
"""发送命令消息
|
||||||
|
|
||||||
使用和send_reply相同的方式通过MessageAPI发送命令
|
使用和send_text相同的方式通过MessageAPI发送命令
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
command_name: 命令名称
|
command_name: 命令名称
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ class PingCommand(BaseCommand):
|
|||||||
message = self.matched_groups.get("message", "")
|
message = self.matched_groups.get("message", "")
|
||||||
reply_text = f"🏓 Pong! {message}" if message else "🏓 Pong!"
|
reply_text = f"🏓 Pong! {message}" if message else "🏓 Pong!"
|
||||||
|
|
||||||
await self.send_reply(reply_text)
|
await self.send_text(reply_text)
|
||||||
return True, f"发送ping响应: {reply_text}"
|
return True, f"发送ping响应: {reply_text}"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -105,14 +105,14 @@ class DoubaoImageGenerationAction(BaseAction):
|
|||||||
|
|
||||||
if not (http_base_url and http_api_key):
|
if not (http_base_url and http_api_key):
|
||||||
error_msg = "抱歉,图片生成功能所需的HTTP配置(如API地址或密钥)不完整,无法提供服务。"
|
error_msg = "抱歉,图片生成功能所需的HTTP配置(如API地址或密钥)不完整,无法提供服务。"
|
||||||
await self.send_reply(error_msg)
|
await self.send_text(error_msg)
|
||||||
logger.error(f"{self.log_prefix} HTTP调用配置缺失: base_url 或 volcano_generate_api_key.")
|
logger.error(f"{self.log_prefix} HTTP调用配置缺失: base_url 或 volcano_generate_api_key.")
|
||||||
return False, "HTTP配置不完整"
|
return False, "HTTP配置不完整"
|
||||||
|
|
||||||
# API密钥验证
|
# API密钥验证
|
||||||
if http_api_key == "YOUR_DOUBAO_API_KEY_HERE":
|
if http_api_key == "YOUR_DOUBAO_API_KEY_HERE":
|
||||||
error_msg = "图片生成功能尚未配置,请设置正确的API密钥。"
|
error_msg = "图片生成功能尚未配置,请设置正确的API密钥。"
|
||||||
await self.send_reply(error_msg)
|
await self.send_text(error_msg)
|
||||||
logger.error(f"{self.log_prefix} API密钥未配置")
|
logger.error(f"{self.log_prefix} API密钥未配置")
|
||||||
return False, "API密钥未配置"
|
return False, "API密钥未配置"
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ class DoubaoImageGenerationAction(BaseAction):
|
|||||||
description = self.action_data.get("description")
|
description = self.action_data.get("description")
|
||||||
if not description or not description.strip():
|
if not description or not description.strip():
|
||||||
logger.warning(f"{self.log_prefix} 图片描述为空,无法生成图片。")
|
logger.warning(f"{self.log_prefix} 图片描述为空,无法生成图片。")
|
||||||
await self.send_reply("你需要告诉我想要画什么样的图片哦~ 比如说'画一只可爱的小猫'")
|
await self.send_text("你需要告诉我想要画什么样的图片哦~ 比如说'画一只可爱的小猫'")
|
||||||
return False, "图片描述为空"
|
return False, "图片描述为空"
|
||||||
|
|
||||||
# 清理和验证描述
|
# 清理和验证描述
|
||||||
@@ -143,12 +143,12 @@ class DoubaoImageGenerationAction(BaseAction):
|
|||||||
if cache_key in self._request_cache:
|
if cache_key in self._request_cache:
|
||||||
cached_result = self._request_cache[cache_key]
|
cached_result = self._request_cache[cache_key]
|
||||||
logger.info(f"{self.log_prefix} 使用缓存的图片结果")
|
logger.info(f"{self.log_prefix} 使用缓存的图片结果")
|
||||||
await self.send_reply("我之前画过类似的图片,用之前的结果~")
|
await self.send_text("我之前画过类似的图片,用之前的结果~")
|
||||||
|
|
||||||
# 直接发送缓存的结果
|
# 直接发送缓存的结果
|
||||||
send_success = await self._send_image(cached_result)
|
send_success = await self._send_image(cached_result)
|
||||||
if send_success:
|
if send_success:
|
||||||
await self.send_reply("图片已发送!")
|
await self.send_text("图片已发送!")
|
||||||
return True, "图片已发送(缓存)"
|
return True, "图片已发送(缓存)"
|
||||||
else:
|
else:
|
||||||
# 缓存失败,清除这个缓存项并继续正常流程
|
# 缓存失败,清除这个缓存项并继续正常流程
|
||||||
@@ -159,7 +159,7 @@ class DoubaoImageGenerationAction(BaseAction):
|
|||||||
seed_val = self._get_seed()
|
seed_val = self._get_seed()
|
||||||
watermark_val = self._get_watermark()
|
watermark_val = self._get_watermark()
|
||||||
|
|
||||||
await self.send_reply(
|
await self.send_text(
|
||||||
f"收到!正在为您生成关于 '{description}' 的图片,请稍候...(模型: {default_model}, 尺寸: {image_size})"
|
f"收到!正在为您生成关于 '{description}' 的图片,请稍候...(模型: {default_model}, 尺寸: {image_size})"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -97,13 +97,13 @@ class MuteAction(BaseAction):
|
|||||||
if not target:
|
if not target:
|
||||||
error_msg = "禁言目标不能为空"
|
error_msg = "禁言目标不能为空"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
await self.send_reply("没有指定禁言对象呢~")
|
await self.send_text("没有指定禁言对象呢~")
|
||||||
return False, error_msg
|
return False, error_msg
|
||||||
|
|
||||||
if not duration:
|
if not duration:
|
||||||
error_msg = "禁言时长不能为空"
|
error_msg = "禁言时长不能为空"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
await self.send_reply("没有指定禁言时长呢~")
|
await self.send_text("没有指定禁言时长呢~")
|
||||||
return False, error_msg
|
return False, error_msg
|
||||||
|
|
||||||
# 获取时长限制配置
|
# 获取时长限制配置
|
||||||
@@ -116,7 +116,7 @@ class MuteAction(BaseAction):
|
|||||||
if duration_int <= 0:
|
if duration_int <= 0:
|
||||||
error_msg = "禁言时长必须大于0"
|
error_msg = "禁言时长必须大于0"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
await self.send_reply("禁言时长必须是正数哦~")
|
await self.send_text("禁言时长必须是正数哦~")
|
||||||
return False, error_msg
|
return False, error_msg
|
||||||
|
|
||||||
# 限制禁言时长范围
|
# 限制禁言时长范围
|
||||||
@@ -130,7 +130,7 @@ class MuteAction(BaseAction):
|
|||||||
except (ValueError, TypeError):
|
except (ValueError, TypeError):
|
||||||
error_msg = f"禁言时长格式无效: {duration}"
|
error_msg = f"禁言时长格式无效: {duration}"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
await self.send_reply("禁言时长必须是数字哦~")
|
await self.send_text("禁言时长必须是数字哦~")
|
||||||
return False, error_msg
|
return False, error_msg
|
||||||
|
|
||||||
# 获取用户ID
|
# 获取用户ID
|
||||||
@@ -139,12 +139,12 @@ class MuteAction(BaseAction):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_msg = f"查找用户ID时出错: {e}"
|
error_msg = f"查找用户ID时出错: {e}"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
await self.send_reply("查找用户信息时出现问题~")
|
await self.send_text("查找用户信息时出现问题~")
|
||||||
return False, error_msg
|
return False, error_msg
|
||||||
|
|
||||||
if not user_id:
|
if not user_id:
|
||||||
error_msg = f"未找到用户 {target} 的ID"
|
error_msg = f"未找到用户 {target} 的ID"
|
||||||
await self.send_reply(f"找不到 {target} 这个人呢~")
|
await self.send_text(f"找不到 {target} 这个人呢~")
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
return False, error_msg
|
return False, error_msg
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ class MuteAction(BaseAction):
|
|||||||
|
|
||||||
# 获取模板化消息
|
# 获取模板化消息
|
||||||
message = self._get_template_message(target, time_str, reason)
|
message = self._get_template_message(target, time_str, reason)
|
||||||
# await self.send_reply(message)
|
# await self.send_text(message)
|
||||||
await self.send_message_by_expressor(message)
|
await self.send_message_by_expressor(message)
|
||||||
|
|
||||||
# 发送群聊禁言命令
|
# 发送群聊禁言命令
|
||||||
@@ -170,7 +170,7 @@ class MuteAction(BaseAction):
|
|||||||
else:
|
else:
|
||||||
error_msg = "发送禁言命令失败"
|
error_msg = "发送禁言命令失败"
|
||||||
logger.error(f"{self.log_prefix} {error_msg}")
|
logger.error(f"{self.log_prefix} {error_msg}")
|
||||||
await self.send_reply("执行禁言动作失败")
|
await self.send_text("执行禁言动作失败")
|
||||||
return False, error_msg
|
return False, error_msg
|
||||||
|
|
||||||
def _get_template_message(self, target: str, duration_str: str, reason: str) -> str:
|
def _get_template_message(self, target: str, duration_str: str, reason: str) -> str:
|
||||||
@@ -237,7 +237,7 @@ class MuteCommand(BaseCommand):
|
|||||||
reason = self.matched_groups.get("reason", "管理员操作")
|
reason = self.matched_groups.get("reason", "管理员操作")
|
||||||
|
|
||||||
if not all([target, duration]):
|
if not all([target, duration]):
|
||||||
await self.send_reply("❌ 命令参数不完整,请检查格式")
|
await self.send_text("❌ 命令参数不完整,请检查格式")
|
||||||
return False, "参数不完整"
|
return False, "参数不完整"
|
||||||
|
|
||||||
# 获取时长限制配置
|
# 获取时长限制配置
|
||||||
@@ -248,19 +248,19 @@ class MuteCommand(BaseCommand):
|
|||||||
try:
|
try:
|
||||||
duration_int = int(duration)
|
duration_int = int(duration)
|
||||||
if duration_int <= 0:
|
if duration_int <= 0:
|
||||||
await self.send_reply("❌ 禁言时长必须大于0")
|
await self.send_text("❌ 禁言时长必须大于0")
|
||||||
return False, "时长无效"
|
return False, "时长无效"
|
||||||
|
|
||||||
# 限制禁言时长范围
|
# 限制禁言时长范围
|
||||||
if duration_int < min_duration:
|
if duration_int < min_duration:
|
||||||
duration_int = min_duration
|
duration_int = min_duration
|
||||||
await self.send_reply(f"⚠️ 禁言时长过短,调整为{min_duration}秒")
|
await self.send_text(f"⚠️ 禁言时长过短,调整为{min_duration}秒")
|
||||||
elif duration_int > max_duration:
|
elif duration_int > max_duration:
|
||||||
duration_int = max_duration
|
duration_int = max_duration
|
||||||
await self.send_reply(f"⚠️ 禁言时长过长,调整为{max_duration}秒")
|
await self.send_text(f"⚠️ 禁言时长过长,调整为{max_duration}秒")
|
||||||
|
|
||||||
except ValueError:
|
except ValueError:
|
||||||
await self.send_reply("❌ 禁言时长必须是数字")
|
await self.send_text("❌ 禁言时长必须是数字")
|
||||||
return False, "时长格式错误"
|
return False, "时长格式错误"
|
||||||
|
|
||||||
# 获取用户ID
|
# 获取用户ID
|
||||||
@@ -268,11 +268,11 @@ class MuteCommand(BaseCommand):
|
|||||||
platform, user_id = await self.api.get_user_id_by_person_name(target)
|
platform, user_id = await self.api.get_user_id_by_person_name(target)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 查找用户ID时出错: {e}")
|
logger.error(f"{self.log_prefix} 查找用户ID时出错: {e}")
|
||||||
await self.send_reply("❌ 查找用户信息时出现问题")
|
await self.send_text("❌ 查找用户信息时出现问题")
|
||||||
return False, str(e)
|
return False, str(e)
|
||||||
|
|
||||||
if not user_id:
|
if not user_id:
|
||||||
await self.send_reply(f"❌ 找不到用户: {target}")
|
await self.send_text(f"❌ 找不到用户: {target}")
|
||||||
return False, "用户不存在"
|
return False, "用户不存在"
|
||||||
|
|
||||||
# 格式化时长显示
|
# 格式化时长显示
|
||||||
@@ -291,17 +291,17 @@ class MuteCommand(BaseCommand):
|
|||||||
if success:
|
if success:
|
||||||
# 获取并发送模板化消息
|
# 获取并发送模板化消息
|
||||||
message = self._get_template_message(target, time_str, reason)
|
message = self._get_template_message(target, time_str, reason)
|
||||||
await self.send_reply(message)
|
await self.send_text(message)
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 成功禁言 {target}({user_id}),时长 {duration_int} 秒")
|
logger.info(f"{self.log_prefix} 成功禁言 {target}({user_id}),时长 {duration_int} 秒")
|
||||||
return True, f"成功禁言 {target},时长 {time_str}"
|
return True, f"成功禁言 {target},时长 {time_str}"
|
||||||
else:
|
else:
|
||||||
await self.send_reply("❌ 发送禁言命令失败")
|
await self.send_text("❌ 发送禁言命令失败")
|
||||||
return False, "发送禁言命令失败"
|
return False, "发送禁言命令失败"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 禁言命令执行失败: {e}")
|
logger.error(f"{self.log_prefix} 禁言命令执行失败: {e}")
|
||||||
await self.send_reply(f"❌ 禁言命令错误: {str(e)}")
|
await self.send_text(f"❌ 禁言命令错误: {str(e)}")
|
||||||
return False, str(e)
|
return False, str(e)
|
||||||
|
|
||||||
def _get_template_message(self, target: str, duration_str: str, reason: str) -> str:
|
def _get_template_message(self, target: str, duration_str: str, reason: str) -> str:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.chat.actions.base_action import ActionActivationType
|
from src.plugin_system.base.base_action import ActionActivationType
|
||||||
from src.chat.actions.plugin_action import PluginAction, register_action
|
from src.plugin_system.base.base_action import BaseAction as PluginAction, register_action
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
logger = get_logger("tts_action")
|
logger = get_logger("tts_action")
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
from src.common.logger import get_logger
|
from src.common.logger import get_logger
|
||||||
from src.chat.actions.plugin_action import PluginAction, register_action, ActionActivationType
|
from src.plugin_system.base.base_action import BaseAction as PluginAction, ActionActivationType
|
||||||
|
from src.plugin_system.base.base_action import register_action
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
|
|
||||||
logger = get_logger("vtb_action")
|
logger = get_logger("vtb_action")
|
||||||
|
|||||||
@@ -157,12 +157,6 @@ src/plugins/built_in/example_comprehensive/
|
|||||||
|
|
||||||
此插件展示了从旧插件系统到新插件系统的完整升级:
|
此插件展示了从旧插件系统到新插件系统的完整升级:
|
||||||
|
|
||||||
### 旧系统特征
|
|
||||||
- 使用 `@register_command` 装饰器
|
|
||||||
- 继承旧的 `BaseCommand`
|
|
||||||
- 硬编码的消息处理逻辑
|
|
||||||
- 有限的配置支持
|
|
||||||
|
|
||||||
### 新系统特征
|
### 新系统特征
|
||||||
- 使用统一的组件注册机制
|
- 使用统一的组件注册机制
|
||||||
- 新的 `BaseAction` 和 `BaseCommand` 基类
|
- 新的 `BaseAction` 和 `BaseCommand` 基类
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ class ComprehensiveHelpCommand(BaseCommand):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 帮助命令执行失败: {e}")
|
logger.error(f"{self.log_prefix} 帮助命令执行失败: {e}")
|
||||||
await self.send_reply(f"❌ 帮助系统错误: {str(e)}")
|
await self.send_text(f"❌ 帮助系统错误: {str(e)}")
|
||||||
return False, str(e)
|
return False, str(e)
|
||||||
|
|
||||||
async def _show_specific_help(self, command_name: str) -> Tuple[bool, str]:
|
async def _show_specific_help(self, command_name: str) -> Tuple[bool, str]:
|
||||||
@@ -115,7 +115,7 @@ class ComprehensiveHelpCommand(BaseCommand):
|
|||||||
{chr(10).join(f" • {example}" for example in info["examples"])}
|
{chr(10).join(f" • {example}" for example in info["examples"])}
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
return True, response
|
return True, response
|
||||||
|
|
||||||
async def _show_all_commands(self) -> Tuple[bool, str]:
|
async def _show_all_commands(self) -> Tuple[bool, str]:
|
||||||
@@ -143,7 +143,7 @@ class ComprehensiveHelpCommand(BaseCommand):
|
|||||||
💡 使用 /help <命令名> 获取特定命令的详细说明
|
💡 使用 /help <命令名> 获取特定命令的详细说明
|
||||||
""".strip()
|
""".strip()
|
||||||
|
|
||||||
await self.send_reply(help_text)
|
await self.send_text(help_text)
|
||||||
return True, help_text
|
return True, help_text
|
||||||
|
|
||||||
|
|
||||||
@@ -167,13 +167,13 @@ class MessageSendCommand(BaseCommand):
|
|||||||
content = self.matched_groups.get("content")
|
content = self.matched_groups.get("content")
|
||||||
|
|
||||||
if not all([target_type, target_id, content]):
|
if not all([target_type, target_id, content]):
|
||||||
await self.send_reply("❌ 命令参数不完整,请检查格式")
|
await self.send_text("❌ 命令参数不完整,请检查格式")
|
||||||
return False, "参数不完整"
|
return False, "参数不完整"
|
||||||
|
|
||||||
# 长度限制检查
|
# 长度限制检查
|
||||||
max_length = self.api.get_config("send.max_message_length", 500)
|
max_length = self.api.get_config("send.max_message_length", 500)
|
||||||
if len(content) > max_length:
|
if len(content) > max_length:
|
||||||
await self.send_reply(f"❌ 消息过长,最大长度: {max_length} 字符")
|
await self.send_text(f"❌ 消息过长,最大长度: {max_length} 字符")
|
||||||
return False, "消息过长"
|
return False, "消息过长"
|
||||||
|
|
||||||
logger.info(f"{self.log_prefix} 发送消息: {target_type}:{target_id} -> {content[:50]}...")
|
logger.info(f"{self.log_prefix} 发送消息: {target_type}:{target_id} -> {content[:50]}...")
|
||||||
@@ -186,23 +186,23 @@ class MessageSendCommand(BaseCommand):
|
|||||||
success = await self.api.send_text_to_user(text=content, user_id=target_id, platform="qq")
|
success = await self.api.send_text_to_user(text=content, user_id=target_id, platform="qq")
|
||||||
target_desc = f"用户 {target_id}"
|
target_desc = f"用户 {target_id}"
|
||||||
else:
|
else:
|
||||||
await self.send_reply(f"❌ 不支持的目标类型: {target_type}")
|
await self.send_text(f"❌ 不支持的目标类型: {target_type}")
|
||||||
return False, f"不支持的目标类型: {target_type}"
|
return False, f"不支持的目标类型: {target_type}"
|
||||||
|
|
||||||
# 返回结果
|
# 返回结果
|
||||||
if success:
|
if success:
|
||||||
response = f"✅ 消息已成功发送到 {target_desc}"
|
response = f"✅ 消息已成功发送到 {target_desc}"
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
return True, response
|
return True, response
|
||||||
else:
|
else:
|
||||||
response = f"❌ 消息发送失败,目标 {target_desc} 可能不存在"
|
response = f"❌ 消息发送失败,目标 {target_desc} 可能不存在"
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
return False, response
|
return False, response
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 消息发送失败: {e}")
|
logger.error(f"{self.log_prefix} 消息发送失败: {e}")
|
||||||
error_msg = f"❌ 发送失败: {str(e)}"
|
error_msg = f"❌ 发送失败: {str(e)}"
|
||||||
await self.send_reply(error_msg)
|
await self.send_text(error_msg)
|
||||||
return False, str(e)
|
return False, str(e)
|
||||||
|
|
||||||
|
|
||||||
@@ -232,15 +232,15 @@ class DiceCommand(BaseCommand):
|
|||||||
count = int(count_str)
|
count = int(count_str)
|
||||||
if count <= 0:
|
if count <= 0:
|
||||||
response = "❌ 骰子数量必须大于0"
|
response = "❌ 骰子数量必须大于0"
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
return False, response
|
return False, response
|
||||||
if count > 10: # 限制最大数量
|
if count > 10: # 限制最大数量
|
||||||
response = "❌ 一次最多只能掷10个骰子"
|
response = "❌ 一次最多只能掷10个骰子"
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
return False, response
|
return False, response
|
||||||
except ValueError:
|
except ValueError:
|
||||||
response = "❌ 骰子数量必须是整数"
|
response = "❌ 骰子数量必须是整数"
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
return False, response
|
return False, response
|
||||||
|
|
||||||
# 生成随机数
|
# 生成随机数
|
||||||
@@ -254,13 +254,13 @@ class DiceCommand(BaseCommand):
|
|||||||
total = sum(results)
|
total = sum(results)
|
||||||
message = f"🎲 掷出了 {count} 个骰子: [{dice_results}],总点数: {total}"
|
message = f"🎲 掷出了 {count} 个骰子: [{dice_results}],总点数: {total}"
|
||||||
|
|
||||||
await self.send_reply(message)
|
await self.send_text(message)
|
||||||
logger.info(f"{self.log_prefix} 执行骰子命令: {message}")
|
logger.info(f"{self.log_prefix} 执行骰子命令: {message}")
|
||||||
return True, message
|
return True, message
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
error_msg = f"❌ 执行命令时出错: {str(e)}"
|
error_msg = f"❌ 执行命令时出错: {str(e)}"
|
||||||
await self.send_reply(error_msg)
|
await self.send_text(error_msg)
|
||||||
logger.error(f"{self.log_prefix} 执行骰子命令时出错: {e}")
|
logger.error(f"{self.log_prefix} 执行骰子命令时出错: {e}")
|
||||||
return False, error_msg
|
return False, error_msg
|
||||||
|
|
||||||
@@ -280,14 +280,14 @@ class EchoCommand(BaseCommand):
|
|||||||
|
|
||||||
if not message:
|
if not message:
|
||||||
response = "❌ 请提供要重复的消息!用法:/echo <消息内容>"
|
response = "❌ 请提供要重复的消息!用法:/echo <消息内容>"
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
return False, response
|
return False, response
|
||||||
|
|
||||||
# 检查消息长度限制
|
# 检查消息长度限制
|
||||||
max_length = self.api.get_config("echo.max_length", 200)
|
max_length = self.api.get_config("echo.max_length", 200)
|
||||||
if len(message) > max_length:
|
if len(message) > max_length:
|
||||||
response = f"❌ 消息过长,最大长度: {max_length} 字符"
|
response = f"❌ 消息过长,最大长度: {max_length} 字符"
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
return False, response
|
return False, response
|
||||||
|
|
||||||
# 格式化回声消息
|
# 格式化回声消息
|
||||||
@@ -297,14 +297,14 @@ class EchoCommand(BaseCommand):
|
|||||||
else:
|
else:
|
||||||
response = message
|
response = message
|
||||||
|
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
logger.info(f"{self.log_prefix} 回声消息: {message}")
|
logger.info(f"{self.log_prefix} 回声消息: {message}")
|
||||||
return True, response
|
return True, response
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 回声命令失败: {e}")
|
logger.error(f"{self.log_prefix} 回声命令失败: {e}")
|
||||||
error_msg = f"❌ 回声失败: {str(e)}"
|
error_msg = f"❌ 回声失败: {str(e)}"
|
||||||
await self.send_reply(error_msg)
|
await self.send_text(error_msg)
|
||||||
return False, str(e)
|
return False, str(e)
|
||||||
|
|
||||||
|
|
||||||
@@ -369,14 +369,14 @@ class MessageInfoCommand(BaseCommand):
|
|||||||
)
|
)
|
||||||
|
|
||||||
response = "\n".join(info_parts)
|
response = "\n".join(info_parts)
|
||||||
await self.send_reply(response)
|
await self.send_text(response)
|
||||||
logger.info(f"{self.log_prefix} 显示消息信息: {user_info.user_id}")
|
logger.info(f"{self.log_prefix} 显示消息信息: {user_info.user_id}")
|
||||||
return True, response
|
return True, response
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"{self.log_prefix} 消息信息查询失败: {e}")
|
logger.error(f"{self.log_prefix} 消息信息查询失败: {e}")
|
||||||
error_msg = f"❌ 信息查询失败: {str(e)}"
|
error_msg = f"❌ 信息查询失败: {str(e)}"
|
||||||
await self.send_reply(error_msg)
|
await self.send_text(error_msg)
|
||||||
return False, str(e)
|
return False, str(e)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user