diff --git a/astrbot/api/__init__.py b/astrbot/api/__init__.py
index e75cde6ff..dd2e0fbc7 100644
--- a/astrbot/api/__init__.py
+++ b/astrbot/api/__init__.py
@@ -2,6 +2,7 @@ from astrbot.core.config.astrbot_config import AstrBotConfig
from astrbot import logger
from astrbot.core.utils.personality import personalities
from astrbot.core import html_renderer
+from astrbot.core import sp
from astrbot.core.star.register import register_llm_tool as llm_tool
__all__ = [
@@ -10,4 +11,5 @@ __all__ = [
"personalities",
"html_renderer",
"llm_tool",
+ "sp"
]
\ No newline at end of file
diff --git a/astrbot/core/__init__.py b/astrbot/core/__init__.py
index 94e32224c..f7876a78a 100644
--- a/astrbot/core/__init__.py
+++ b/astrbot/core/__init__.py
@@ -1,6 +1,7 @@
import os
from .log import LogManager, LogBroker
from astrbot.core.utils.t2i.renderer import HtmlRenderer
+from astrbot.core.utils.shared_preferences import SharedPreferences
from astrbot.core.db.sqlite import SQLiteDatabase
from astrbot.core.config.default import DB_PATH
@@ -13,4 +14,5 @@ if os.environ.get('TESTING', ""):
logger.setLevel('DEBUG')
db_helper = SQLiteDatabase(DB_PATH)
-WEBUI_SK = "Advanced_System_for_Text_Response_and_Bot_Operations_Tool"
\ No newline at end of file
+sp = SharedPreferences() # 简单的偏好设置存储
+WEBUI_SK = "Advanced_System_for_Text_Response_and_Bot_Operations_Tool"
diff --git a/astrbot/core/core_lifecycle.py b/astrbot/core/core_lifecycle.py
index 3655e55ee..ddb285cc9 100644
--- a/astrbot/core/core_lifecycle.py
+++ b/astrbot/core/core_lifecycle.py
@@ -92,6 +92,8 @@ class AstrBotCoreLifecycle:
self.event_queue.closed = True
for task in self.curr_tasks:
task.cancel()
+
+ await self.provider_manager.terminate()
for task in self.curr_tasks:
try:
diff --git a/astrbot/core/provider/func_tool_manager.py b/astrbot/core/provider/func_tool_manager.py
index 07c672daf..f1d2f7b28 100644
--- a/astrbot/core/provider/func_tool_manager.py
+++ b/astrbot/core/provider/func_tool_manager.py
@@ -14,6 +14,7 @@ class FuncTool:
parameters: Dict
description: str
handler: Awaitable
+ handler_module_path: str = None # 必须要保留这个,handler 在初始化会被 functools.partial 包装,导致 handler 的 __module__ 为 functools
active: bool = True
'''是否激活'''
diff --git a/astrbot/core/provider/manager.py b/astrbot/core/provider/manager.py
index 20ac8a0d0..e020148d6 100644
--- a/astrbot/core/provider/manager.py
+++ b/astrbot/core/provider/manager.py
@@ -5,7 +5,7 @@ from typing import List
from astrbot.core.db import BaseDatabase
from collections import defaultdict
from .register import provider_cls_map, llm_tools
-from astrbot.core import logger
+from astrbot.core import logger, sp
class ProviderManager():
def __init__(self, config: AstrBotConfig, db_helper: BaseDatabase):
@@ -48,21 +48,31 @@ class ProviderManager():
if not provider_config['enable']:
continue
if provider_config['type'] not in provider_cls_map:
- logger.error(f"未找到适用于 {provider_config['type']}({provider_config['id']}) 的 大模型提供商适配器,请检查是否已经安装或者名称填写错误。已跳过。")
+ logger.error(f"未找到适用于 {provider_config['type']}({provider_config['id']}) 的提供商适配器,请检查是否已经安装或者名称填写错误。已跳过。")
continue
+ selected_provider_id = sp.get("curr_provider")
cls_type = provider_cls_map[provider_config['type']]
- logger.info(f"尝试实例化 {provider_config['type']}({provider_config['id']}) 大模型提供商适配器 ...")
+ logger.info(f"尝试实例化 {provider_config['type']}({provider_config['id']}) 提供商适配器 ...")
try:
inst = cls_type(provider_config, self.provider_settings, self.db_helper, self.provider_settings.get('persistant_history', True))
self.provider_insts.append(inst)
+ if selected_provider_id == provider_config['id']:
+ self.curr_provider_inst = inst
+ logger.info(f"已选择 {provider_config['type']}({provider_config['id']}) 作为当前提供商适配器。")
except Exception as e:
traceback.print_exc()
- logger.error(f"实例化 {provider_config['type']}({provider_config['id']}) 大模型提供商适配器 失败:{e}")
+ logger.error(f"实例化 {provider_config['type']}({provider_config['id']}) 提供商适配器失败:{e}")
- if len(self.provider_insts) > 0:
+ if len(self.provider_insts) > 0 and not self.curr_provider_inst:
self.curr_provider_inst = self.provider_insts[0]
- else:
- logger.warning("未启用任何大模型提供商适配器。")
+
+ if not self.curr_provider_inst:
+ logger.warning("未启用任何提供商适配器。")
def get_insts(self):
- return self.provider_insts
\ No newline at end of file
+ return self.provider_insts
+
+ async def terminate(self):
+ for provider_inst in self.provider_insts:
+ if hasattr(provider_inst, "terminate"):
+ await provider_inst.terminate()
\ No newline at end of file
diff --git a/astrbot/core/provider/sources/dify_source.py b/astrbot/core/provider/sources/dify_source.py
index a8b2f73bd..fa797eee6 100644
--- a/astrbot/core/provider/sources/dify_source.py
+++ b/astrbot/core/provider/sources/dify_source.py
@@ -126,3 +126,6 @@ class ProviderDify(Provider):
async def get_human_readable_context(self, session_id, page, page_size):
raise Exception("暂不支持获得 Dify 的历史消息记录。")
+
+ async def terminate(self):
+ await self.api_client.close()
\ No newline at end of file
diff --git a/astrbot/core/star/context.py b/astrbot/core/star/context.py
index 39ed5baf6..58810de96 100644
--- a/astrbot/core/star/context.py
+++ b/astrbot/core/star/context.py
@@ -1,6 +1,7 @@
from asyncio import Queue
from typing import List, TypedDict, Union
+from astrbot.core import sp
from astrbot.core.provider.provider import Provider
from astrbot.core.db import BaseDatabase
from astrbot.core.config.astrbot_config import AstrBotConfig
@@ -39,6 +40,7 @@ class Context:
# back compatibility
_register_tasks: List[Awaitable] = []
+ _star_manager = None
def __init__(self,
event_queue: Queue,
@@ -105,6 +107,12 @@ class Context:
func_tool = self.provider_manager.llm_tools.get_func(name)
if func_tool is not None:
func_tool.active = True
+
+ inactivated_llm_tools: list = sp.get("inactivated_llm_tools", [])
+ if name in inactivated_llm_tools:
+ inactivated_llm_tools.remove(name)
+ sp.put("inactivated_llm_tools", inactivated_llm_tools)
+
return True
return False
@@ -116,6 +124,12 @@ class Context:
func_tool = self.provider_manager.llm_tools.get_func(name)
if func_tool is not None:
func_tool.active = False
+
+ inactivated_llm_tools: list = sp.get("inactivated_llm_tools", [])
+ if name not in inactivated_llm_tools:
+ inactivated_llm_tools.append(name)
+ sp.put("inactivated_llm_tools", inactivated_llm_tools)
+
return True
return False
diff --git a/astrbot/core/star/star.py b/astrbot/core/star/star.py
index cee93c5e6..960504f29 100644
--- a/astrbot/core/star/star.py
+++ b/astrbot/core/star/star.py
@@ -32,6 +32,9 @@ class StarMetadata:
'''Star 的根目录名'''
reserved: bool = False
'''是否是 AstrBot 的保留 Star'''
+
+ activated: bool = True
+ '''是否被激活'''
def __str__(self) -> str:
return f"StarMetadata({self.name}, {self.desc}, {self.version}, {self.repo})"
\ No newline at end of file
diff --git a/astrbot/core/star/star_handler.py b/astrbot/core/star/star_handler.py
index 9acfa56e0..e0e13db40 100644
--- a/astrbot/core/star/star_handler.py
+++ b/astrbot/core/star/star_handler.py
@@ -3,6 +3,7 @@ import enum
from dataclasses import dataclass
from typing import Awaitable, List, Dict, TypeVar, Generic
from .filter import HandlerFilter
+from .star import star_map
T = TypeVar('T', bound='StarHandlerMetadata')
class StarHandlerRegistry(Generic[T], List[T]):
@@ -16,9 +17,18 @@ class StarHandlerRegistry(Generic[T], List[T]):
super().append(handler)
self.star_handlers_map[handler.handler_full_name] = handler
- def get_handlers_by_event_type(self, event_type: EventType) -> List[StarHandlerMetadata]:
+ def get_handlers_by_event_type(self, event_type: EventType, only_activated = True) -> List[StarHandlerMetadata]:
'''通过事件类型获取 Handler'''
- return [handler for handler in self if handler.event_type == event_type]
+ if only_activated:
+ return [
+ handler
+ for handler in self
+ if handler.event_type == event_type and
+ star_map[handler.handler_module_path] and
+ star_map[handler.handler_module_path].activated
+ ]
+ else:
+ return [handler for handler in self if handler.event_type == event_type]
def get_handler_by_full_name(self, full_name: str) -> StarHandlerMetadata:
'''通过 Handler 的全名获取 Handler'''
diff --git a/astrbot/core/star/star_manager.py b/astrbot/core/star/star_manager.py
index 1a49f9826..8d33eb3ab 100644
--- a/astrbot/core/star/star_manager.py
+++ b/astrbot/core/star/star_manager.py
@@ -9,7 +9,7 @@ from types import ModuleType
from typing import List
from pip import main as pip_main
from astrbot.core.config.astrbot_config import AstrBotConfig
-from astrbot.core import logger
+from astrbot.core import logger, sp
from .context import Context
from . import StarMetadata
from .updator import PluginUpdator
@@ -27,6 +27,7 @@ class PluginManager:
self.updator = PluginUpdator(config['plugin_repo_mirror'])
self.context = context
+ self.context._star_manager = self # 就这样吧,不想改了
self.config = config
self.plugin_store_path = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "../../../data/plugins"))
@@ -156,6 +157,9 @@ class PluginManager:
return False, "未找到任何插件模块"
fail_rec = ""
+ inactivated_plugins: list = sp.get("inactivated_plugins", [])
+ inactivated_llm_tools: list = sp.get("inactivated_llm_tools", [])
+
# 导入 Star 模块,并尝试实例化 Star 类
for plugin_module in plugin_modules:
try:
@@ -182,21 +186,24 @@ class PluginManager:
if path in star_map:
# 通过装饰器的方式注册插件
- star_metadata = star_map[path]
- star_metadata.star_cls = star_metadata.star_cls_type(context=self.context)
- star_metadata.module = module
- star_metadata.root_dir_name = root_dir_name
- star_metadata.reserved = reserved
+ metadata = star_map[path]
+ metadata.star_cls = metadata.star_cls_type(context=self.context)
+ metadata.module = module
+ metadata.root_dir_name = root_dir_name
+ metadata.reserved = reserved
- related_handlers = star_handlers_registry.get_handlers_by_module_name(star_metadata.module_path)
+ related_handlers = star_handlers_registry.get_handlers_by_module_name(metadata.module_path)
for handler in related_handlers:
- logger.debug(f"bind handler {handler.handler_name} to {star_metadata.name}")
+ logger.debug(f"bind handler {handler.handler_name} to {metadata.name}")
# handler.handler.__self__ = star_metadata.star_cls # 绑定 handler 的 self
- handler.handler = functools.partial(handler.handler, star_metadata.star_cls)
+ handler.handler = functools.partial(handler.handler, metadata.star_cls)
# llm_tool
for func_tool in llm_tools.func_list:
- if func_tool.handler.__module__ == star_metadata.module_path:
- func_tool.handler = functools.partial(func_tool.handler, star_metadata.star_cls)
+ if func_tool.handler.__module__ == metadata.module_path:
+ func_tool.handler_module_path = metadata.module_path
+ func_tool.handler = functools.partial(func_tool.handler, metadata.star_cls)
+ if func_tool.name in inactivated_llm_tools:
+ func_tool.active = False
else:
# v3.4.0 以前的方式注册插件
@@ -220,6 +227,9 @@ class PluginManager:
star_map[path] = metadata
star_registry.append(metadata)
logger.debug(f"插件 {root_dir_name} 载入成功。")
+
+ if metadata.module_path in inactivated_plugins:
+ metadata.activated = False
except BaseException as e:
traceback.print_exc()
@@ -250,22 +260,25 @@ class PluginManager:
ppath = self.plugin_store_path
# 从 star_registry 和 star_map 中删除
- del star_map[plugin.module_path]
+ await self._unbind_plugin(plugin_name, plugin.module_path)
+
+ if not remove_dir(os.path.join(ppath, root_dir_name)):
+ raise Exception("移除插件成功,但是删除插件文件夹失败。您可以手动删除该文件夹,位于 addons/plugins/ 下。")
+
+ async def _unbind_plugin(self, plugin_name: str, plugin_module_path: str):
+ del star_map[plugin_module_path]
for i, p in enumerate(star_registry):
if p.name == plugin_name:
del star_registry[i]
break
- for handler in star_handlers_registry.get_handlers_by_module_name(plugin.module_path):
+ for handler in star_handlers_registry.get_handlers_by_module_name(plugin_module_path):
logger.debug(f"unbind handler {handler.handler_name} from {plugin_name}")
star_handlers_registry.remove(handler)
- keys_to_delete = [k for k, v in star_handlers_registry.star_handlers_map.items() if k.startswith(plugin.module_path)]
+ keys_to_delete = [k for k, v in star_handlers_registry.star_handlers_map.items() if k.startswith(plugin_module_path)]
for k in keys_to_delete:
v = star_handlers_registry.star_handlers_map[k]
logger.debug(f"unbind handler {v.handler_name} from {plugin_name} (map)")
del star_handlers_registry.star_handlers_map[k]
-
- if not remove_dir(os.path.join(ppath, root_dir_name)):
- raise Exception("移除插件成功,但是删除插件文件夹失败。您可以手动删除该文件夹,位于 addons/plugins/ 下。")
async def update_plugin(self, plugin_name: str):
plugin = self.context.get_registered_star(plugin_name)
@@ -276,6 +289,47 @@ class PluginManager:
await self.updator.update(plugin)
self.reload()
+
+ async def turn_off_plugin(self, plugin_name: str):
+ plugin = self.context.get_registered_star(plugin_name)
+ if not plugin:
+ raise Exception("插件不存在。")
+ inactivated_plugins: list = sp.get("inactivated_plugins", [])
+ if plugin.module_path not in inactivated_plugins:
+ inactivated_plugins.append(plugin.module_path)
+
+ inactivated_llm_tools: list = sp.get("inactivated_llm_tools", [])
+
+ # 禁用插件启用的 llm_tool
+ for func_tool in llm_tools.func_list:
+ if func_tool.handler_module_path == plugin.module_path:
+ func_tool.active = False
+ inactivated_llm_tools.append(func_tool.name)
+
+ sp.put("inactivated_plugins", inactivated_plugins)
+ sp.put("inactivated_llm_tools", inactivated_llm_tools)
+
+ plugin.activated = False
+
+ async def turn_on_plugin(self, plugin_name: str):
+ plugin = self.context.get_registered_star(plugin_name)
+ if not plugin:
+ raise Exception("插件已经启用,无需重新启用。")
+ inactivated_plugins: list = sp.get("inactivated_plugins", [])
+ inactivated_llm_tools: list = sp.get("inactivated_llm_tools", [])
+ if plugin.module_path in inactivated_plugins:
+ inactivated_plugins.remove(plugin.module_path)
+ sp.put("inactivated_plugins", inactivated_plugins)
+
+ # 启用插件启用的 llm_tool
+ for func_tool in llm_tools.func_list:
+ if func_tool.handler_module_path == plugin.module_path:
+ inactivated_llm_tools.remove(func_tool.name)
+ func_tool.active = True
+ sp.put("inactivated_llm_tools", inactivated_llm_tools)
+
+ plugin.activated = True
+
def install_plugin_from_file(self, zip_file_path: str):
desti_dir = os.path.join(self.plugin_store_path, os.path.basename(zip_file_path))
diff --git a/astrbot/core/utils/io.py b/astrbot/core/utils/io.py
index 3c0a6a926..bbc3341bb 100644
--- a/astrbot/core/utils/io.py
+++ b/astrbot/core/utils/io.py
@@ -96,7 +96,7 @@ async def download_file(url: str, path: str):
'''
try:
async with aiohttp.ClientSession() as session:
- async with session.get(url) as resp:
+ async with session.get(url, timeout=20) as resp:
with open(path, 'wb') as f:
while True:
chunk = await resp.content.read(8192)
diff --git a/astrbot/core/utils/shared_preferences.py b/astrbot/core/utils/shared_preferences.py
new file mode 100644
index 000000000..e9a9ed0d7
--- /dev/null
+++ b/astrbot/core/utils/shared_preferences.py
@@ -0,0 +1,33 @@
+import json
+import os
+
+class SharedPreferences:
+ def __init__(self, path="data/shared_preferences.json"):
+ self.path = path
+ self._data = self._load_preferences()
+
+ def _load_preferences(self):
+ if os.path.exists(self.path):
+ with open(self.path, "r") as f:
+ return json.load(f)
+ return {}
+
+ def _save_preferences(self):
+ with open(self.path, "w") as f:
+ json.dump(self._data, f, indent=4)
+
+ def get(self, key, default=None):
+ return self._data.get(key, default)
+
+ def put(self, key, value):
+ self._data[key] = value
+ self._save_preferences()
+
+ def remove(self, key):
+ if key in self._data:
+ del self._data[key]
+ self._save_preferences()
+
+ def clear(self):
+ self._data.clear()
+ self._save_preferences()
\ No newline at end of file
diff --git a/astrbot/dashboard/routes/plugin.py b/astrbot/dashboard/routes/plugin.py
index c43ab7660..bc42d508e 100644
--- a/astrbot/dashboard/routes/plugin.py
+++ b/astrbot/dashboard/routes/plugin.py
@@ -16,7 +16,9 @@ class PluginRoute(Route):
'/plugin/install-upload': ('POST', self.install_plugin_upload),
'/plugin/update': ('POST', self.update_plugin),
'/plugin/uninstall': ('POST', self.uninstall_plugin),
- '/plugin/market_list': ('GET', self.get_online_plugins)
+ '/plugin/market_list': ('GET', self.get_online_plugins),
+ '/plugin/off': ('POST', self.off_plugin),
+ '/plugin/on': ('POST', self.on_plugin)
}
self.core_lifecycle = core_lifecycle
self.plugin_manager = plugin_manager
@@ -42,7 +44,8 @@ class PluginRoute(Route):
"author": plugin.author,
"desc": plugin.desc,
"version": plugin.version,
- "reserved": plugin.reserved
+ "reserved": plugin.reserved,
+ "activated": plugin.activated
}
_plugin_resp.append(_t)
return Response().ok(_plugin_resp).__dict__
@@ -95,4 +98,26 @@ class PluginRoute(Route):
return Response().ok(None, "更新成功。").__dict__
except Exception as e:
logger.error(f"/api/extensions/update: {traceback.format_exc()}")
+ return Response().error(str(e)).__dict__
+
+ async def off_plugin(self):
+ post_data = await request.json
+ plugin_name = post_data["name"]
+ try:
+ await self.plugin_manager.turn_off_plugin(plugin_name)
+ logger.info(f"停用插件 {plugin_name} 。")
+ return Response().ok(None, "停用成功。").__dict__
+ except Exception as e:
+ logger.error(f"/api/extensions/off: {traceback.format_exc()}")
+ return Response().error(str(e)).__dict__
+
+ async def on_plugin(self):
+ post_data = await request.json
+ plugin_name = post_data["name"]
+ try:
+ await self.plugin_manager.turn_on_plugin(plugin_name)
+ logger.info(f"启用插件 {plugin_name} 。")
+ return Response().ok(None, "启用成功。").__dict__
+ except Exception as e:
+ logger.error(f"/api/extensions/on: {traceback.format_exc()}")
return Response().error(str(e)).__dict__
\ No newline at end of file
diff --git a/dashboard/src/views/ExtensionPage.vue b/dashboard/src/views/ExtensionPage.vue
index b0ae0ffd8..69b6295a2 100644
--- a/dashboard/src/views/ExtensionPage.vue
+++ b/dashboard/src/views/ExtensionPage.vue
@@ -29,7 +29,9 @@ import axios from 'axios';
更新
卸载
- 保留插件
+
+ 禁用
+ 启用
@@ -329,6 +331,36 @@ export default {
this.toast(err, "error");
});
},
+ pluginOn(extension) {
+ axios.post('/api/plugin/on',
+ {
+ name: extension.name
+ }).then((res) => {
+ if (res.data.status === "error") {
+ this.toast(res.data.message, "error");
+ return;
+ }
+ this.toast(res.data.message, "success");
+ this.getExtensions();
+ }).catch((err) => {
+ this.toast(err, "error");
+ });
+ },
+ pluginOff(extension) {
+ axios.post('/api/plugin/off',
+ {
+ name: extension.name
+ }).then((res) => {
+ if (res.data.status === "error") {
+ this.toast(res.data.message, "error");
+ return;
+ }
+ this.toast(res.data.message, "success");
+ this.getExtensions();
+ }).catch((err) => {
+ this.toast(err, "error");
+ });
+ },
openExtensionConfig(extension_name) {
this.curr_namespace = extension_name;
this.configDialog = true;
diff --git a/packages/astrbot/main.py b/packages/astrbot/main.py
index 0af740faf..fa5161b7c 100644
--- a/packages/astrbot/main.py
+++ b/packages/astrbot/main.py
@@ -3,7 +3,7 @@ import datetime
import astrbot.api.star as star
import astrbot.api.event.filter as filter
from astrbot.api.event import AstrMessageEvent, MessageEventResult
-from astrbot.api import personalities
+from astrbot.api import personalities, sp
from astrbot.api.provider import Personality, ProviderRequest
from typing import Union
@@ -89,24 +89,41 @@ class Main(star.Star):
event.set_result(MessageEventResult().message(f"停用工具 {tool_name} 失败,未找到此工具。"))
@filter.command("plugin")
- async def plugin(self, event: AstrMessageEvent, oper: str = None):
- if oper is None:
+ async def plugin(self, event: AstrMessageEvent, oper1: str = None, oper2: str = None):
+ if oper1 is None:
plugin_list_info = "已加载的插件:\n"
for plugin in self.context.get_all_stars():
plugin_list_info += f"- `{plugin.name}` By {plugin.author}: {plugin.desc}\n"
if plugin_list_info.strip() == "":
plugin_list_info = "没有加载任何插件。"
- plugin_list_info += "\n使用 /plugin <插件名> 查看插件帮助。"
+ plugin_list_info += "\n使用 /plugin <插件名> 查看插件帮助。\n使用 /plugin on/off <插件名> 启用或者禁用插件。"
event.set_result(MessageEventResult().message(f"{plugin_list_info}").use_t2i(False))
else:
- plugin = self.context.get_registered_star(oper)
- if plugin is None:
- event.set_result(MessageEventResult().message("未找到此插件。"))
+ if oper1 == "off":
+ # 禁用插件
+ if oper2 is None:
+ event.set_result(MessageEventResult().message("/plugin off <插件名> 禁用插件。"))
+ return
+ await self.context._star_manager.turn_off_plugin(oper2)
+ event.set_result(MessageEventResult().message(f"插件 {oper2} 已禁用。"))
+ elif oper1 == "on":
+ # 启用插件
+ if oper2 is None:
+ event.set_result(MessageEventResult().message("/plugin on <插件名> 启用插件。"))
+ return
+ await self.context._star_manager.turn_on_plugin(oper2)
+ event.set_result(MessageEventResult().message(f"插件 {oper2} 已启用。"))
+
else:
- help_msg = plugin.star_cls.__doc__ if plugin.star_cls.__doc__ else "该插件未提供帮助信息"
- ret = f"插件 {oper} 帮助信息:\n" + help_msg
- event.set_result(MessageEventResult().message(ret).use_t2i(False))
+ # 获取插件帮助
+ plugin = self.context.get_registered_star(oper1)
+ if plugin is None:
+ event.set_result(MessageEventResult().message("未找到此插件。"))
+ else:
+ help_msg = plugin.star_cls.__doc__ if plugin.star_cls.__doc__ else "该插件未提供帮助信息"
+ ret = f"插件 {oper1} 帮助信息:\n" + help_msg
+ event.set_result(MessageEventResult().message(ret).use_t2i(False))
@filter.command("t2i")
async def t2i(self, event: AstrMessageEvent):
@@ -169,8 +186,9 @@ UID: {user_id} 此 ID 可用于设置管理员。/op 授权管理员, /deo
if idx is None:
ret = "## 当前载入的 LLM 提供商\n"
for idx, llm in enumerate(self.context.get_all_providers()):
- ret += f"{idx + 1}. {llm.meta().id} ({llm.meta().model})"
- if self.provider == llm:
+ id_ = llm.meta().id
+ ret += f"{idx + 1}. {id_} ({llm.meta().model})"
+ if self.context.get_using_provider().meta().id == id_:
ret += " (当前使用)"
ret += "\n"
@@ -180,9 +198,12 @@ UID: {user_id} 此 ID 可用于设置管理员。/op 授权管理员, /deo
if idx > len(self.context.get_all_providers()) or idx < 1:
event.set_result(MessageEventResult().message("无效的序号。"))
- self.context.provider_manager.curr_provider_inst = self.context.get_all_providers()[idx - 1]
+ provider = self.context.get_all_providers()[idx - 1]
+ id_ = provider.meta().id
+ self.context.provider_manager.curr_provider_inst = provider
+ sp.put("curr_provider", id_)
- event.set_result(MessageEventResult().message(f"成功切换到 {self.context.provider_manager.curr_provider_inst.meta().id}。"))
+ event.set_result(MessageEventResult().message(f"成功切换到 {id_}。"))
@filter.command("reset")
async def reset(self, message: AstrMessageEvent):