From 10a44c70b627e38fab04243a5041c59e35061f17 Mon Sep 17 00:00:00 2001 From: Junyan Qin Date: Thu, 10 Jul 2025 10:51:36 +0800 Subject: [PATCH] feat: switch command entities to sdk --- pkg/command/cmdmgr.py | 15 ++-- pkg/command/entities.py | 75 -------------------- pkg/command/errors.py | 26 ------- pkg/command/operator.py | 10 +-- pkg/command/operators/cmd.py | 13 ++-- pkg/command/operators/delc.py | 21 +++--- pkg/command/operators/func.py | 9 ++- pkg/command/operators/help.py | 9 ++- pkg/command/operators/last.py | 15 ++-- pkg/command/operators/list.py | 11 +-- pkg/command/operators/next.py | 15 ++-- pkg/command/operators/plugin.py | 91 ++++++++++++++----------- pkg/command/operators/prompt.py | 11 +-- pkg/command/operators/resend.py | 11 +-- pkg/command/operators/reset.py | 9 ++- pkg/command/operators/update.py | 9 ++- pkg/command/operators/version.py | 9 ++- pkg/platform/sources/officialaccount.py | 4 +- pkg/platform/sources/qqofficial.py | 4 +- pkg/platform/sources/slack.py | 4 +- pkg/platform/sources/wecom.py | 4 +- pkg/platform/sources/wecomcs.py | 4 +- 22 files changed, 169 insertions(+), 210 deletions(-) delete mode 100644 pkg/command/entities.py delete mode 100644 pkg/command/errors.py diff --git a/pkg/command/cmdmgr.py b/pkg/command/cmdmgr.py index 14c3d9e4..b9dae7c8 100644 --- a/pkg/command/cmdmgr.py +++ b/pkg/command/cmdmgr.py @@ -3,10 +3,11 @@ from __future__ import annotations import typing from ..core import app -from . import entities, operator, errors +from . import operator from ..utils import importutil import langbot_plugin.api.entities.builtin.provider.session as provider_session import langbot_plugin.api.entities.builtin.pipeline.query as pipeline_query +from langbot_plugin.api.entities.builtin.command import context as command_context, errors as command_errors # 引入所有算子以便注册 from . import operators @@ -57,10 +58,10 @@ class CommandManager: async def _execute( self, - context: entities.ExecuteContext, + context: command_context.ExecuteContext, operator_list: list[operator.CommandOperator], operator: operator.CommandOperator = None, - ) -> typing.AsyncGenerator[entities.CommandReturn, None]: + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: """执行命令""" found = False @@ -80,10 +81,10 @@ class CommandManager: if not found: # 如果下一个参数未在此节点的子节点中找到,则执行此节点或者报错 if operator is None: - yield entities.CommandReturn(error=errors.CommandNotFoundError(context.crt_params[0])) + yield command_context.CommandReturn(error=command_errors.CommandNotFoundError(context.crt_params[0])) else: if operator.lowest_privilege > context.privilege: - yield entities.CommandReturn(error=errors.CommandPrivilegeError(operator.name)) + yield command_context.CommandReturn(error=command_errors.CommandPrivilegeError(operator.name)) else: async for ret in operator.execute(context): yield ret @@ -93,7 +94,7 @@ class CommandManager: command_text: str, query: pipeline_query.Query, session: provider_session.Session, - ) -> typing.AsyncGenerator[entities.CommandReturn, None]: + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: """执行命令""" privilege = 1 @@ -101,7 +102,7 @@ class CommandManager: if f'{query.launcher_type.value}_{query.launcher_id}' in self.ap.instance_config.data['admins']: privilege = 2 - ctx = entities.ExecuteContext( + ctx = command_context.ExecuteContext( query=query, session=session, command_text=command_text, diff --git a/pkg/command/entities.py b/pkg/command/entities.py deleted file mode 100644 index 2e4f8a96..00000000 --- a/pkg/command/entities.py +++ /dev/null @@ -1,75 +0,0 @@ -from __future__ import annotations - -import typing - -import pydantic - -import langbot_plugin.api.entities.builtin.provider.session as provider_session -from . import errors -import langbot_plugin.api.entities.builtin.platform.message as platform_message -import langbot_plugin.api.entities.builtin.pipeline.query as pipeline_query - - -class CommandReturn(pydantic.BaseModel): - """命令返回值""" - - text: typing.Optional[str] = None - """文本 - """ - - image: typing.Optional[platform_message.Image] = None - """弃用""" - - image_url: typing.Optional[str] = None - """图片链接 - """ - - error: typing.Optional[errors.CommandError] = None - """错误 - """ - - class Config: - arbitrary_types_allowed = True - - -class ExecuteContext(pydantic.BaseModel): - """单次命令执行上下文""" - - query: pipeline_query.Query - """本次消息的请求对象""" - - session: provider_session.Session - """本次消息所属的会话对象""" - - command_text: str - """命令完整文本""" - - command: str - """命令名称""" - - crt_command: str - """当前命令 - - 多级命令中crt_command为当前命令,command为根命令。 - 例如:!plugin on Webwlkr - 处理到plugin时,command为plugin,crt_command为plugin - 处理到on时,command为plugin,crt_command为on - """ - - params: list[str] - """命令参数 - - 整个命令以空格分割后的参数列表 - """ - - crt_params: list[str] - """当前命令参数 - - 多级命令中crt_params为当前命令参数,params为根命令参数。 - 例如:!plugin on Webwlkr - 处理到plugin时,params为['on', 'Webwlkr'],crt_params为['on', 'Webwlkr'] - 处理到on时,params为['on', 'Webwlkr'],crt_params为['Webwlkr'] - """ - - privilege: int - """发起人权限""" diff --git a/pkg/command/errors.py b/pkg/command/errors.py deleted file mode 100644 index df05b3d1..00000000 --- a/pkg/command/errors.py +++ /dev/null @@ -1,26 +0,0 @@ -class CommandError(Exception): - def __init__(self, message: str = None): - self.message = message - - def __str__(self): - return self.message - - -class CommandNotFoundError(CommandError): - def __init__(self, message: str = None): - super().__init__('未知命令: ' + message) - - -class CommandPrivilegeError(CommandError): - def __init__(self, message: str = None): - super().__init__('权限不足: ' + message) - - -class ParamNotEnoughError(CommandError): - def __init__(self, message: str = None): - super().__init__('参数不足: ' + message) - - -class CommandOperationError(CommandError): - def __init__(self, message: str = None): - super().__init__('操作失败: ' + message) diff --git a/pkg/command/operator.py b/pkg/command/operator.py index 9ee3de37..0157cf28 100644 --- a/pkg/command/operator.py +++ b/pkg/command/operator.py @@ -4,7 +4,7 @@ import typing import abc from ..core import app -from . import entities +from langbot_plugin.api.entities.builtin.command import context as command_context preregistered_operators: list[typing.Type[CommandOperator]] = [] @@ -95,16 +95,18 @@ class CommandOperator(metaclass=abc.ABCMeta): pass @abc.abstractmethod - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: """实现此方法以执行命令 支持多次yield以返回多个结果。 例如:一个安装插件的命令,可能会有下载、解压、安装等多个步骤,每个步骤都可以返回一个结果。 Args: - context (entities.ExecuteContext): 命令执行上下文 + context (command_context.ExecuteContext): 命令执行上下文 Yields: - entities.CommandReturn: 命令返回封装 + command_context.CommandReturn: 命令返回封装 """ pass diff --git a/pkg/command/operators/cmd.py b/pkg/command/operators/cmd.py index f5a69a7b..cb0c3554 100644 --- a/pkg/command/operators/cmd.py +++ b/pkg/command/operators/cmd.py @@ -2,14 +2,17 @@ from __future__ import annotations import typing -from .. import operator, entities, errors +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context, errors as command_errors @operator.operator_class(name='cmd', help='显示命令列表', usage='!cmd\n!cmd <命令名称>') class CmdOperator(operator.CommandOperator): """命令列表""" - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: """执行""" if len(context.crt_params) == 0: reply_str = '当前所有命令: \n\n' @@ -20,7 +23,7 @@ class CmdOperator(operator.CommandOperator): reply_str += '\n使用 !cmd <命令名称> 查看命令的详细帮助' - yield entities.CommandReturn(text=reply_str.strip()) + yield command_context.CommandReturn(text=reply_str.strip()) else: cmd_name = context.crt_params[0] @@ -33,9 +36,9 @@ class CmdOperator(operator.CommandOperator): break if cmd is None: - yield entities.CommandReturn(error=errors.CommandNotFoundError(cmd_name)) + yield command_context.CommandReturn(error=command_errors.CommandNotFoundError(cmd_name)) else: reply_str = f'{cmd.name}: {cmd.help}\n\n' reply_str += f'使用方法: \n{cmd.usage}' - yield entities.CommandReturn(text=reply_str.strip()) + yield command_context.CommandReturn(text=reply_str.strip()) diff --git a/pkg/command/operators/delc.py b/pkg/command/operators/delc.py index 7e72ff3c..06db3d1e 100644 --- a/pkg/command/operators/delc.py +++ b/pkg/command/operators/delc.py @@ -2,23 +2,26 @@ from __future__ import annotations import typing -from .. import operator, entities, errors +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context, errors as command_errors @operator.operator_class(name='del', help='删除当前会话的历史记录', usage='!del <序号>\n!del all') class DelOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: if context.session.conversations: delete_index = 0 if len(context.crt_params) > 0: try: delete_index = int(context.crt_params[0]) except Exception: - yield entities.CommandReturn(error=errors.CommandOperationError('索引必须是整数')) + yield command_context.CommandReturn(error=command_errors.CommandOperationError('索引必须是整数')) return if delete_index < 0 or delete_index >= len(context.session.conversations): - yield entities.CommandReturn(error=errors.CommandOperationError('索引超出范围')) + yield command_context.CommandReturn(error=command_errors.CommandOperationError('索引超出范围')) return # 倒序 @@ -29,15 +32,17 @@ class DelOperator(operator.CommandOperator): del context.session.conversations[to_delete_index] - yield entities.CommandReturn(text=f'已删除对话: {delete_index}') + yield command_context.CommandReturn(text=f'已删除对话: {delete_index}') else: - yield entities.CommandReturn(error=errors.CommandOperationError('当前没有对话')) + yield command_context.CommandReturn(error=command_errors.CommandOperationError('当前没有对话')) @operator.operator_class(name='all', help='删除此会话的所有历史记录', parent_class=DelOperator) class DelAllOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: context.session.conversations = [] context.session.using_conversation = None - yield entities.CommandReturn(text='已删除所有对话') + yield command_context.CommandReturn(text='已删除所有对话') diff --git a/pkg/command/operators/func.py b/pkg/command/operators/func.py index 48dbd316..e7828a51 100644 --- a/pkg/command/operators/func.py +++ b/pkg/command/operators/func.py @@ -1,12 +1,15 @@ from __future__ import annotations from typing import AsyncGenerator -from .. import operator, entities +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context @operator.operator_class(name='func', help='查看所有已注册的内容函数', usage='!func') class FuncOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> AsyncGenerator[command_context.CommandReturn, None]: reply_str = '当前已启用的内容函数: \n\n' index = 1 @@ -21,4 +24,4 @@ class FuncOperator(operator.CommandOperator): ) index += 1 - yield entities.CommandReturn(text=reply_str) + yield command_context.CommandReturn(text=reply_str) diff --git a/pkg/command/operators/help.py b/pkg/command/operators/help.py index 91ad66dc..609f05ad 100644 --- a/pkg/command/operators/help.py +++ b/pkg/command/operators/help.py @@ -2,14 +2,17 @@ from __future__ import annotations import typing -from .. import operator, entities +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context @operator.operator_class(name='help', help='显示帮助', usage='!help\n!help <命令名称>') class HelpOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: help = 'LangBot - 大语言模型原生即时通信机器人平台\n链接:https://langbot.app' help += '\n发送命令 !cmd 可查看命令列表' - yield entities.CommandReturn(text=help) + yield command_context.CommandReturn(text=help) diff --git a/pkg/command/operators/last.py b/pkg/command/operators/last.py index 25b1fc6a..3f92e2e2 100644 --- a/pkg/command/operators/last.py +++ b/pkg/command/operators/last.py @@ -3,26 +3,31 @@ from __future__ import annotations import typing -from .. import operator, entities, errors +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context, errors as command_errors @operator.operator_class(name='last', help='切换到前一个对话', usage='!last') class LastOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: if context.session.conversations: # 找到当前会话的上一个会话 for index in range(len(context.session.conversations) - 1, -1, -1): if context.session.conversations[index] == context.session.using_conversation: if index == 0: - yield entities.CommandReturn(error=errors.CommandOperationError('已经是第一个对话了')) + yield command_context.CommandReturn( + error=command_errors.CommandOperationError('已经是第一个对话了') + ) return else: context.session.using_conversation = context.session.conversations[index - 1] time_str = context.session.using_conversation.create_time.strftime('%Y-%m-%d %H:%M:%S') - yield entities.CommandReturn( + yield command_context.CommandReturn( text=f'已切换到上一个对话: {index} {time_str}: {context.session.using_conversation.messages[0].readable_str()}' ) return else: - yield entities.CommandReturn(error=errors.CommandOperationError('当前没有对话')) + yield command_context.CommandReturn(error=command_errors.CommandOperationError('当前没有对话')) diff --git a/pkg/command/operators/list.py b/pkg/command/operators/list.py index 70ff3945..ca1bf8e9 100644 --- a/pkg/command/operators/list.py +++ b/pkg/command/operators/list.py @@ -2,19 +2,22 @@ from __future__ import annotations import typing -from .. import operator, entities, errors +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context, errors as command_errors @operator.operator_class(name='list', help='列出此会话中的所有历史对话', usage='!list\n!list <页码>') class ListOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: page = 0 if len(context.crt_params) > 0: try: page = int(context.crt_params[0] - 1) except Exception: - yield entities.CommandReturn(error=errors.CommandOperationError('页码应为整数')) + yield command_context.CommandReturn(error=command_errors.CommandOperationError('页码应为整数')) return record_per_page = 10 @@ -45,4 +48,4 @@ class ListOperator(operator.CommandOperator): else: content += f'\n当前会话: {using_conv_index} {context.session.using_conversation.create_time.strftime("%Y-%m-%d %H:%M:%S")}: {context.session.using_conversation.messages[0].readable_str() if len(context.session.using_conversation.messages) > 0 else "无内容"}' - yield entities.CommandReturn(text=f'第 {page + 1} 页 (时间倒序):\n{content}') + yield command_context.CommandReturn(text=f'第 {page + 1} 页 (时间倒序):\n{content}') diff --git a/pkg/command/operators/next.py b/pkg/command/operators/next.py index 938c8331..87cc565c 100644 --- a/pkg/command/operators/next.py +++ b/pkg/command/operators/next.py @@ -2,26 +2,31 @@ from __future__ import annotations import typing -from .. import operator, entities, errors +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context, errors as command_errors @operator.operator_class(name='next', help='切换到后一个对话', usage='!next') class NextOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: if context.session.conversations: # 找到当前会话的下一个会话 for index in range(len(context.session.conversations)): if context.session.conversations[index] == context.session.using_conversation: if index == len(context.session.conversations) - 1: - yield entities.CommandReturn(error=errors.CommandOperationError('已经是最后一个对话了')) + yield command_context.CommandReturn( + error=command_errors.CommandOperationError('已经是最后一个对话了') + ) return else: context.session.using_conversation = context.session.conversations[index + 1] time_str = context.session.using_conversation.create_time.strftime('%Y-%m-%d %H:%M:%S') - yield entities.CommandReturn( + yield command_context.CommandReturn( text=f'已切换到后一个对话: {index} {time_str}: {context.session.using_conversation.messages[0].content}' ) return else: - yield entities.CommandReturn(error=errors.CommandOperationError('当前没有对话')) + yield command_context.CommandReturn(error=command_errors.CommandOperationError('当前没有对话')) diff --git a/pkg/command/operators/plugin.py b/pkg/command/operators/plugin.py index 40ec0e3a..1c135bd4 100644 --- a/pkg/command/operators/plugin.py +++ b/pkg/command/operators/plugin.py @@ -2,7 +2,8 @@ from __future__ import annotations import typing import traceback -from .. import operator, entities, errors +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context, errors as command_errors @operator.operator_class( @@ -11,7 +12,9 @@ from .. import operator, entities, errors usage='!plugin\n!plugin get <插件仓库地址>\n!plugin update\n!plugin del <插件名>\n!plugin on <插件名>\n!plugin off <插件名>', ) class PluginOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: plugin_list = self.ap.plugin_mgr.plugins() reply_str = '所有插件({}):\n'.format(len(plugin_list)) idx = 0 @@ -27,32 +30,36 @@ class PluginOperator(operator.CommandOperator): idx += 1 - yield entities.CommandReturn(text=reply_str) + yield command_context.CommandReturn(text=reply_str) @operator.operator_class(name='get', help='安装插件', privilege=2, parent_class=PluginOperator) class PluginGetOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: if len(context.crt_params) == 0: - yield entities.CommandReturn(error=errors.ParamNotEnoughError('请提供插件仓库地址')) + yield command_context.CommandReturn(error=command_errors.ParamNotEnoughError('请提供插件仓库地址')) else: repo = context.crt_params[0] - yield entities.CommandReturn(text='正在安装插件...') + yield command_context.CommandReturn(text='正在安装插件...') try: await self.ap.plugin_mgr.install_plugin(repo) - yield entities.CommandReturn(text='插件安装成功,请重启程序以加载插件') + yield command_context.CommandReturn(text='插件安装成功,请重启程序以加载插件') except Exception as e: traceback.print_exc() - yield entities.CommandReturn(error=errors.CommandError('插件安装失败: ' + str(e))) + yield command_context.CommandReturn(error=command_errors.CommandError('插件安装失败: ' + str(e))) @operator.operator_class(name='update', help='更新插件', privilege=2, parent_class=PluginOperator) class PluginUpdateOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: if len(context.crt_params) == 0: - yield entities.CommandReturn(error=errors.ParamNotEnoughError('请提供插件名称')) + yield command_context.CommandReturn(error=command_errors.ParamNotEnoughError('请提供插件名称')) else: plugin_name = context.crt_params[0] @@ -60,24 +67,26 @@ class PluginUpdateOperator(operator.CommandOperator): plugin_container = self.ap.plugin_mgr.get_plugin_by_name(plugin_name) if plugin_container is not None: - yield entities.CommandReturn(text='正在更新插件...') + yield command_context.CommandReturn(text='正在更新插件...') await self.ap.plugin_mgr.update_plugin(plugin_name) - yield entities.CommandReturn(text='插件更新成功,请重启程序以加载插件') + yield command_context.CommandReturn(text='插件更新成功,请重启程序以加载插件') else: - yield entities.CommandReturn(error=errors.CommandError('插件更新失败: 未找到插件')) + yield command_context.CommandReturn(error=command_errors.CommandError('插件更新失败: 未找到插件')) except Exception as e: traceback.print_exc() - yield entities.CommandReturn(error=errors.CommandError('插件更新失败: ' + str(e))) + yield command_context.CommandReturn(error=command_errors.CommandError('插件更新失败: ' + str(e))) @operator.operator_class(name='all', help='更新所有插件', privilege=2, parent_class=PluginUpdateOperator) class PluginUpdateAllOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: try: plugins = [p.plugin_name for p in self.ap.plugin_mgr.plugins()] if plugins: - yield entities.CommandReturn(text='正在更新插件...') + yield command_context.CommandReturn(text='正在更新插件...') updated = [] try: for plugin_name in plugins: @@ -85,20 +94,22 @@ class PluginUpdateAllOperator(operator.CommandOperator): updated.append(plugin_name) except Exception as e: traceback.print_exc() - yield entities.CommandReturn(error=errors.CommandError('插件更新失败: ' + str(e))) - yield entities.CommandReturn(text='已更新插件: {}'.format(', '.join(updated))) + yield command_context.CommandReturn(error=command_errors.CommandError('插件更新失败: ' + str(e))) + yield command_context.CommandReturn(text='已更新插件: {}'.format(', '.join(updated))) else: - yield entities.CommandReturn(text='没有可更新的插件') + yield command_context.CommandReturn(text='没有可更新的插件') except Exception as e: traceback.print_exc() - yield entities.CommandReturn(error=errors.CommandError('插件更新失败: ' + str(e))) + yield command_context.CommandReturn(error=command_errors.CommandError('插件更新失败: ' + str(e))) @operator.operator_class(name='del', help='删除插件', privilege=2, parent_class=PluginOperator) class PluginDelOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: if len(context.crt_params) == 0: - yield entities.CommandReturn(error=errors.ParamNotEnoughError('请提供插件名称')) + yield command_context.CommandReturn(error=command_errors.ParamNotEnoughError('请提供插件名称')) else: plugin_name = context.crt_params[0] @@ -106,51 +117,55 @@ class PluginDelOperator(operator.CommandOperator): plugin_container = self.ap.plugin_mgr.get_plugin_by_name(plugin_name) if plugin_container is not None: - yield entities.CommandReturn(text='正在删除插件...') + yield command_context.CommandReturn(text='正在删除插件...') await self.ap.plugin_mgr.uninstall_plugin(plugin_name) - yield entities.CommandReturn(text='插件删除成功,请重启程序以加载插件') + yield command_context.CommandReturn(text='插件删除成功,请重启程序以加载插件') else: - yield entities.CommandReturn(error=errors.CommandError('插件删除失败: 未找到插件')) + yield command_context.CommandReturn(error=command_errors.CommandError('插件删除失败: 未找到插件')) except Exception as e: traceback.print_exc() - yield entities.CommandReturn(error=errors.CommandError('插件删除失败: ' + str(e))) + yield command_context.CommandReturn(error=command_errors.CommandError('插件删除失败: ' + str(e))) @operator.operator_class(name='on', help='启用插件', privilege=2, parent_class=PluginOperator) class PluginEnableOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: if len(context.crt_params) == 0: - yield entities.CommandReturn(error=errors.ParamNotEnoughError('请提供插件名称')) + yield command_context.CommandReturn(error=command_errors.ParamNotEnoughError('请提供插件名称')) else: plugin_name = context.crt_params[0] try: if await self.ap.plugin_mgr.update_plugin_switch(plugin_name, True): - yield entities.CommandReturn(text='已启用插件: {}'.format(plugin_name)) + yield command_context.CommandReturn(text='已启用插件: {}'.format(plugin_name)) else: - yield entities.CommandReturn( - error=errors.CommandError('插件状态修改失败: 未找到插件 {}'.format(plugin_name)) + yield command_context.CommandReturn( + error=command_errors.CommandError('插件状态修改失败: 未找到插件 {}'.format(plugin_name)) ) except Exception as e: traceback.print_exc() - yield entities.CommandReturn(error=errors.CommandError('插件状态修改失败: ' + str(e))) + yield command_context.CommandReturn(error=command_errors.CommandError('插件状态修改失败: ' + str(e))) @operator.operator_class(name='off', help='禁用插件', privilege=2, parent_class=PluginOperator) class PluginDisableOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: if len(context.crt_params) == 0: - yield entities.CommandReturn(error=errors.ParamNotEnoughError('请提供插件名称')) + yield command_context.CommandReturn(error=command_errors.ParamNotEnoughError('请提供插件名称')) else: plugin_name = context.crt_params[0] try: if await self.ap.plugin_mgr.update_plugin_switch(plugin_name, False): - yield entities.CommandReturn(text='已禁用插件: {}'.format(plugin_name)) + yield command_context.CommandReturn(text='已禁用插件: {}'.format(plugin_name)) else: - yield entities.CommandReturn( - error=errors.CommandError('插件状态修改失败: 未找到插件 {}'.format(plugin_name)) + yield command_context.CommandReturn( + error=command_errors.CommandError('插件状态修改失败: 未找到插件 {}'.format(plugin_name)) ) except Exception as e: traceback.print_exc() - yield entities.CommandReturn(error=errors.CommandError('插件状态修改失败: ' + str(e))) + yield command_context.CommandReturn(error=command_errors.CommandError('插件状态修改失败: ' + str(e))) diff --git a/pkg/command/operators/prompt.py b/pkg/command/operators/prompt.py index fdcba2bd..b43be2cf 100644 --- a/pkg/command/operators/prompt.py +++ b/pkg/command/operators/prompt.py @@ -2,19 +2,22 @@ from __future__ import annotations import typing -from .. import operator, entities, errors +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context, errors as command_errors @operator.operator_class(name='prompt', help='查看当前对话的前文', usage='!prompt') class PromptOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: """执行""" if context.session.using_conversation is None: - yield entities.CommandReturn(error=errors.CommandOperationError('当前没有对话')) + yield command_context.CommandReturn(error=command_errors.CommandOperationError('当前没有对话')) else: reply_str = '当前对话所有内容:\n\n' for msg in context.session.using_conversation.messages: reply_str += f'{msg.role}: {msg.content}\n' - yield entities.CommandReturn(text=reply_str) + yield command_context.CommandReturn(text=reply_str) diff --git a/pkg/command/operators/resend.py b/pkg/command/operators/resend.py index 39789fef..14bfee99 100644 --- a/pkg/command/operators/resend.py +++ b/pkg/command/operators/resend.py @@ -2,15 +2,18 @@ from __future__ import annotations import typing -from .. import operator, entities, errors +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context, errors as command_errors @operator.operator_class(name='resend', help='重发当前会话的最后一条消息', usage='!resend') class ResendOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: # 回滚到最后一条用户message前 if context.session.using_conversation is None: - yield entities.CommandReturn(error=errors.CommandError('当前没有对话')) + yield command_context.CommandReturn(error=command_errors.CommandError('当前没有对话')) else: conv_msg = context.session.using_conversation.messages @@ -23,4 +26,4 @@ class ResendOperator(operator.CommandOperator): conv_msg.pop() # 不重发了,提示用户已删除就行了 - yield entities.CommandReturn(text='已删除最后一次请求记录') + yield command_context.CommandReturn(text='已删除最后一次请求记录') diff --git a/pkg/command/operators/reset.py b/pkg/command/operators/reset.py index 008143a1..0c85fb32 100644 --- a/pkg/command/operators/reset.py +++ b/pkg/command/operators/reset.py @@ -2,13 +2,16 @@ from __future__ import annotations import typing -from .. import operator, entities +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context @operator.operator_class(name='reset', help='重置当前会话', usage='!reset') class ResetOperator(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: """执行""" context.session.using_conversation = None - yield entities.CommandReturn(text='已重置当前会话') + yield command_context.CommandReturn(text='已重置当前会话') diff --git a/pkg/command/operators/update.py b/pkg/command/operators/update.py index 29b8f560..84e5c9cc 100644 --- a/pkg/command/operators/update.py +++ b/pkg/command/operators/update.py @@ -2,10 +2,13 @@ from __future__ import annotations import typing -from .. import operator, entities +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context @operator.operator_class(name='update', help='更新程序', usage='!update', privilege=2) class UpdateCommand(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: - yield entities.CommandReturn(text='不再支持通过命令更新,请查看 LangBot 文档。') + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: + yield command_context.CommandReturn(text='不再支持通过命令更新,请查看 LangBot 文档。') diff --git a/pkg/command/operators/version.py b/pkg/command/operators/version.py index 200875aa..5b3c3358 100644 --- a/pkg/command/operators/version.py +++ b/pkg/command/operators/version.py @@ -2,12 +2,15 @@ from __future__ import annotations import typing -from .. import operator, entities +from .. import operator +from langbot_plugin.api.entities.builtin.command import context as command_context @operator.operator_class(name='version', help='显示版本信息', usage='!version') class VersionCommand(operator.CommandOperator): - async def execute(self, context: entities.ExecuteContext) -> typing.AsyncGenerator[entities.CommandReturn, None]: + async def execute( + self, context: command_context.ExecuteContext + ) -> typing.AsyncGenerator[command_context.CommandReturn, None]: reply_str = f'当前版本: \n{self.ap.ver_mgr.get_current_version()}' try: @@ -16,4 +19,4 @@ class VersionCommand(operator.CommandOperator): except Exception: pass - yield entities.CommandReturn(text=reply_str.strip()) + yield command_context.CommandReturn(text=reply_str.strip()) diff --git a/pkg/platform/sources/officialaccount.py b/pkg/platform/sources/officialaccount.py index 74321b92..01a2c868 100644 --- a/pkg/platform/sources/officialaccount.py +++ b/pkg/platform/sources/officialaccount.py @@ -11,7 +11,7 @@ from libs.official_account_api.api import OAClientForLongerResponse import langbot_plugin.api.entities.builtin.platform.entities as platform_entities import langbot_plugin.api.entities.builtin.platform.message as platform_message import langbot_plugin.api.entities.builtin.platform.events as platform_events -from ...command.errors import ParamNotEnoughError +from langbot_plugin.api.entities.builtin.command import errors as command_errors from ..logger import EventLogger @@ -75,7 +75,7 @@ class OfficialAccountAdapter(abstract_platform_adapter.AbstractMessagePlatformAd ] missing_keys = [key for key in required_keys if key not in config] if missing_keys: - raise ParamNotEnoughError('微信公众号缺少相关配置项,请查看文档或联系管理员') + raise command_errors.ParamNotEnoughError('微信公众号缺少相关配置项,请查看文档或联系管理员') if self.config['Mode'] == 'drop': self.bot = OAClient( diff --git a/pkg/platform/sources/qqofficial.py b/pkg/platform/sources/qqofficial.py index 1160fd0e..28a09d8c 100644 --- a/pkg/platform/sources/qqofficial.py +++ b/pkg/platform/sources/qqofficial.py @@ -9,7 +9,7 @@ import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platf import langbot_plugin.api.entities.builtin.platform.message as platform_message import langbot_plugin.api.entities.builtin.platform.events as platform_events import langbot_plugin.api.entities.builtin.platform.entities as platform_entities -from ...command.errors import ParamNotEnoughError +from langbot_plugin.api.entities.builtin.command import errors as command_errors from libs.qq_official_api.api import QQOfficialClient from libs.qq_official_api.qqofficialevent import QQOfficialEvent from ...utils import image @@ -148,7 +148,7 @@ class QQOfficialAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter ] missing_keys = [key for key in required_keys if key not in config] if missing_keys: - raise ParamNotEnoughError('QQ官方机器人缺少相关配置项,请查看文档或联系管理员') + raise command_errors.ParamNotEnoughError('QQ官方机器人缺少相关配置项,请查看文档或联系管理员') self.bot = QQOfficialClient( app_id=config['appid'], secret=config['secret'], token=config['token'], logger=self.logger diff --git a/pkg/platform/sources/slack.py b/pkg/platform/sources/slack.py index c2997828..e08cc8c0 100644 --- a/pkg/platform/sources/slack.py +++ b/pkg/platform/sources/slack.py @@ -11,7 +11,7 @@ from libs.slack_api.slackevent import SlackEvent import langbot_plugin.api.entities.builtin.platform.events as platform_events import langbot_plugin.api.entities.builtin.platform.message as platform_message import langbot_plugin.api.entities.builtin.platform.entities as platform_entities -from ...command.errors import ParamNotEnoughError +from langbot_plugin.api.entities.builtin.command import errors as command_errors from ...utils import image from ..logger import EventLogger @@ -99,7 +99,7 @@ class SlackAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): ] missing_keys = [key for key in required_keys if key not in config] if missing_keys: - raise ParamNotEnoughError('Slack机器人缺少相关配置项,请查看文档或联系管理员') + raise command_errors.ParamNotEnoughError('Slack机器人缺少相关配置项,请查看文档或联系管理员') self.bot = SlackClient( bot_token=self.config['bot_token'], signing_secret=self.config['signing_secret'], logger=self.logger diff --git a/pkg/platform/sources/wecom.py b/pkg/platform/sources/wecom.py index 88b89e03..392db801 100644 --- a/pkg/platform/sources/wecom.py +++ b/pkg/platform/sources/wecom.py @@ -8,7 +8,7 @@ import datetime from libs.wecom_api.api import WecomClient import langbot_plugin.api.definition.abstract.platform.adapter as abstract_platform_adapter from libs.wecom_api.wecomevent import WecomEvent -from ...command.errors import ParamNotEnoughError +from langbot_plugin.api.entities.builtin.command import errors as command_errors from ...utils import image from ..logger import EventLogger import langbot_plugin.api.entities.builtin.platform.message as platform_message @@ -146,7 +146,7 @@ class WecomAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): ] missing_keys = [key for key in required_keys if key not in config] if missing_keys: - raise ParamNotEnoughError('企业微信缺少相关配置项,请查看文档或联系管理员') + raise command_errors.ParamNotEnoughError('企业微信缺少相关配置项,请查看文档或联系管理员') self.bot = WecomClient( corpid=config['corpid'], diff --git a/pkg/platform/sources/wecomcs.py b/pkg/platform/sources/wecomcs.py index 0958db68..a0c24c08 100644 --- a/pkg/platform/sources/wecomcs.py +++ b/pkg/platform/sources/wecomcs.py @@ -12,7 +12,7 @@ from libs.wecom_customer_service_api.wecomcsevent import WecomCSEvent import langbot_plugin.api.entities.builtin.platform.entities as platform_entities import langbot_plugin.api.entities.builtin.platform.message as platform_message import langbot_plugin.api.entities.builtin.platform.events as platform_events -from ...command.errors import ParamNotEnoughError +from langbot_plugin.api.entities.builtin.command import errors as command_errors import langbot_plugin.api.definition.abstract.platform.event_logger as abstract_platform_logger @@ -131,7 +131,7 @@ class WecomCSAdapter(abstract_platform_adapter.AbstractMessagePlatformAdapter): ] missing_keys = [key for key in required_keys if key not in config] if missing_keys: - raise ParamNotEnoughError('企业微信客服缺少相关配置项,请查看文档或联系管理员') + raise command_errors.ParamNotEnoughError('企业微信客服缺少相关配置项,请查看文档或联系管理员') bot = WecomCSClient( corpid=config['corpid'],