mirror of
https://github.com/AstrBotDevs/AstrBot.git
synced 2026-09-24 16:39:52 +08:00
chore: apply ruff format to codebase
Reformat 23 files for consistent code style.
This commit is contained in:
@@ -160,7 +160,9 @@ class AstrbotGateway(BaseAstrbotGateway):
|
||||
|
||||
self._app.include_router(memory_router)
|
||||
|
||||
async def _handle_ws_message(self, message: dict[str, Any]) -> dict[str, Any] | None:
|
||||
async def _handle_ws_message(
|
||||
self, message: dict[str, Any]
|
||||
) -> dict[str, Any] | None:
|
||||
"""
|
||||
Handle an incoming WebSocket message.
|
||||
|
||||
@@ -182,7 +184,10 @@ class AstrbotGateway(BaseAstrbotGateway):
|
||||
if msg_type == "get_stars":
|
||||
return {"type": "stars_list", "data": await self._list_stars()}
|
||||
|
||||
return {"type": "error", "data": {"message": f"Unknown message type: {msg_type}"}}
|
||||
return {
|
||||
"type": "error",
|
||||
"data": {"message": f"Unknown message type: {msg_type}"},
|
||||
}
|
||||
|
||||
async def _handle_call_tool(self, data: dict[str, Any]) -> dict[str, Any]:
|
||||
"""Handle a tool call request via WebSocket."""
|
||||
@@ -191,10 +196,15 @@ class AstrbotGateway(BaseAstrbotGateway):
|
||||
arguments = data.get("arguments", {})
|
||||
|
||||
if not star_name or not tool_name:
|
||||
return {"type": "tool_result", "data": {"error": "Missing star or tool name"}}
|
||||
return {
|
||||
"type": "tool_result",
|
||||
"data": {"error": "Missing star or tool name"},
|
||||
}
|
||||
|
||||
try:
|
||||
result = await self.orchestrator.abp.call_star_tool(star_name, tool_name, arguments)
|
||||
result = await self.orchestrator.abp.call_star_tool(
|
||||
star_name, tool_name, arguments
|
||||
)
|
||||
return {"type": "tool_result", "data": {"result": result}}
|
||||
except Exception as e:
|
||||
return {"type": "tool_result", "data": {"error": str(e)}}
|
||||
|
||||
@@ -78,7 +78,9 @@ class WebSocketManager:
|
||||
async with self._lock:
|
||||
self._connections.discard(conn)
|
||||
|
||||
async def send_to(self, websocket: WebSocket, message: str | dict[str, Any]) -> None:
|
||||
async def send_to(
|
||||
self, websocket: WebSocket, message: str | dict[str, Any]
|
||||
) -> None:
|
||||
"""
|
||||
Send a message to a specific WebSocket.
|
||||
|
||||
|
||||
@@ -107,7 +107,10 @@ class AstrbotAcpClient(BaseAstrbotAcpClient):
|
||||
continue
|
||||
|
||||
content_length = header.get("content-length", 0)
|
||||
if content_length == 0 or len(buffer) < header_end + 1 + content_length:
|
||||
if (
|
||||
content_length == 0
|
||||
or len(buffer) < header_end + 1 + content_length
|
||||
):
|
||||
break
|
||||
|
||||
content = buffer[header_end + 1 : header_end + 1 + content_length]
|
||||
|
||||
@@ -322,12 +322,15 @@ class McpClient(BaseAstrbotMcpClient):
|
||||
stdio_transport = await self.exit_stack.enter_async_context(
|
||||
mcp.stdio_client(
|
||||
server_params,
|
||||
errlog=cast(Any, LogPipe(
|
||||
level=logging.INFO,
|
||||
logger=logger,
|
||||
identifier=f"MCPServer-{name}",
|
||||
callback=callback,
|
||||
)),
|
||||
errlog=cast(
|
||||
Any,
|
||||
LogPipe(
|
||||
level=logging.INFO,
|
||||
logger=logger,
|
||||
identifier=f"MCPServer-{name}",
|
||||
callback=callback,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
self.process_pid = self._extract_stdio_process_pid(stdio_transport)
|
||||
|
||||
@@ -131,7 +131,9 @@ class ToolSet:
|
||||
"""List all tools in this set."""
|
||||
return list(self._tools.values())
|
||||
|
||||
def openai_schema(self, omit_empty_parameter_field: bool = False) -> list[dict[str, Any]]:
|
||||
def openai_schema(
|
||||
self, omit_empty_parameter_field: bool = False
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Convert tools to OpenAI API function calling schema format."""
|
||||
result: list[dict[str, Any]] = []
|
||||
for tool in self._tools.values():
|
||||
|
||||
@@ -117,7 +117,9 @@ class FunctionToolManager:
|
||||
"""Initialize MCP clients (stub)."""
|
||||
pass
|
||||
|
||||
async def test_mcp_server_connection(self, config: dict[str, Any]) -> tuple[bool, str]:
|
||||
async def test_mcp_server_connection(
|
||||
self, config: dict[str, Any]
|
||||
) -> tuple[bool, str]:
|
||||
"""Test MCP server connection (stub)."""
|
||||
return False, "Not implemented"
|
||||
|
||||
@@ -215,7 +217,9 @@ class FuncCall(FunctionToolManager):
|
||||
"""Remove a tool by its name (alias for remove)."""
|
||||
self.remove(name)
|
||||
|
||||
def get_func_desc_openai_style(self, omit_empty_parameter_field: bool = False) -> list[dict[str, Any]]:
|
||||
def get_func_desc_openai_style(
|
||||
self, omit_empty_parameter_field: bool = False
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Get tools in OpenAI style (deprecated, use get_full_tool_set().openai_schema())."""
|
||||
tool_set = self.get_full_tool_set()
|
||||
return tool_set.openai_schema(omit_empty_parameter_field)
|
||||
@@ -248,13 +252,16 @@ class FuncCall(FunctionToolManager):
|
||||
"""Deactivate an LLM tool (stub implementation)."""
|
||||
return True
|
||||
|
||||
async def test_mcp_server_connection(self, config: dict[str, Any]) -> tuple[bool, str]:
|
||||
async def test_mcp_server_connection(
|
||||
self, config: dict[str, Any]
|
||||
) -> tuple[bool, str]:
|
||||
"""Test MCP server connection (stub implementation)."""
|
||||
# Import the actual test function if available
|
||||
try:
|
||||
from astrbot._internal.protocols.mcp.client import (
|
||||
_quick_test_mcp_connection,
|
||||
)
|
||||
|
||||
success, message = await _quick_test_mcp_connection(config)
|
||||
if not success:
|
||||
raise Exception(message)
|
||||
|
||||
@@ -176,15 +176,15 @@ def remove(name: str) -> None:
|
||||
|
||||
plugin_path = plugin["local_path"]
|
||||
|
||||
click.confirm(
|
||||
t("plugin_uninstall_confirm", name=name), default=False, abort=True
|
||||
)
|
||||
click.confirm(t("plugin_uninstall_confirm", name=name), default=False, abort=True)
|
||||
|
||||
try:
|
||||
shutil.rmtree(plugin_path)
|
||||
click.echo(t("plugin_uninstall_success", name=name))
|
||||
except Exception as e:
|
||||
raise click.ClickException(t("plugin_uninstall_failed_ex", name=name, error=str(e)))
|
||||
raise click.ClickException(
|
||||
t("plugin_uninstall_failed_ex", name=name, error=str(e))
|
||||
)
|
||||
|
||||
|
||||
@plug.command()
|
||||
|
||||
@@ -338,7 +338,10 @@ def run(
|
||||
from astrbot.core.initial_loader import InitialLoader
|
||||
|
||||
if (
|
||||
os.environ.get("ASTRBOT_DASHBOARD_ENABLE", os.environ.get("DASHBOARD_ENABLE"))
|
||||
os.environ.get(
|
||||
"ASTRBOT_DASHBOARD_ENABLE",
|
||||
os.environ.get("DASHBOARD_ENABLE"),
|
||||
)
|
||||
== "True"
|
||||
):
|
||||
await DashboardManager().ensure_installed(astrbot_root)
|
||||
@@ -357,7 +360,9 @@ def run(
|
||||
"""Stream logs from LogBroker to stdout."""
|
||||
while True:
|
||||
try:
|
||||
log_entry = await asyncio.wait_for(log_queue.get(), timeout=0.5)
|
||||
log_entry = await asyncio.wait_for(
|
||||
log_queue.get(), timeout=0.5
|
||||
)
|
||||
# Format: [LEVEL] message
|
||||
level = log_entry.get("level_name", "INFO")
|
||||
message = log_entry.get("message", "")
|
||||
@@ -369,7 +374,12 @@ def run(
|
||||
"ERROR": "red",
|
||||
"CRITICAL": "red",
|
||||
}.get(level, "white")
|
||||
click.secho(f"[{level}]", fg=level_color, bold=False, nl=False)
|
||||
click.secho(
|
||||
f"[{level}]",
|
||||
fg=level_color,
|
||||
bold=False,
|
||||
nl=False,
|
||||
)
|
||||
click.echo(f" {message}")
|
||||
except asyncio.TimeoutError:
|
||||
continue
|
||||
|
||||
@@ -318,9 +318,7 @@ class TUIClient:
|
||||
|
||||
try:
|
||||
# Format umo for tui
|
||||
umo = (
|
||||
f"tui:FriendMessage:tui!{self.username}!{self.conversation_id}"
|
||||
)
|
||||
umo = f"tui:FriendMessage:tui!{self.username}!{self.conversation_id}"
|
||||
|
||||
# Reset parser for new stream
|
||||
self._parser.reset()
|
||||
|
||||
@@ -26,7 +26,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"cli_version": "AstrBot CLI 版本: {version}",
|
||||
"cli_unknown_command": "未知命令: {command}",
|
||||
"cli_help_available": "使用 astrbot help --all 查看所有命令",
|
||||
|
||||
# Dashboard commands
|
||||
"dashboard_bundled": "Dashboard 已打包在安装包中 - 跳过下载",
|
||||
"dashboard_not_installed": "Dashboard 未安装",
|
||||
@@ -41,7 +40,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"dashboard_download_failed": "Dashboard 下载失败: {error}",
|
||||
"dashboard_init_dir": "正在初始化 Dashboard 目录...",
|
||||
"dashboard_init_success": "Dashboard 初始化成功",
|
||||
|
||||
# Plugin commands
|
||||
"plugin_installing": "正在安装插件: {name}",
|
||||
"plugin_install_success": "插件安装成功: {name}",
|
||||
@@ -60,7 +58,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"plugin_updating": "正在更新插件 {name}...",
|
||||
"plugin_search_no_result": "未找到匹配 '{query}' 的插件",
|
||||
"plugin_search_results": "搜索结果: '{query}'",
|
||||
|
||||
# Config commands
|
||||
"config_show": "显示配置",
|
||||
"config_set_success": "配置项已更新: {key} = {value}",
|
||||
@@ -70,7 +67,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"config_get_not_found": "配置项未找到: {key}",
|
||||
"config_reset_confirm": "确定要重置所有配置吗?",
|
||||
"config_reset_success": "配置已重置",
|
||||
|
||||
# Config validators
|
||||
"config_log_level_invalid": "日志级别必须是 DEBUG/INFO/WARNING/ERROR/CRITICAL 之一",
|
||||
"config_port_must_be_number": "端口必须是数字",
|
||||
@@ -82,7 +78,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"config_key_unsupported": "不支持的配置项: {key}",
|
||||
"config_key_unknown": "未知的配置项: {key}",
|
||||
"config_updated": "配置已更新: {key}",
|
||||
|
||||
# Init command
|
||||
"init_creating": "正在创建配置目录...",
|
||||
"init_created": "配置目录已创建: {path}",
|
||||
@@ -90,19 +85,16 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"init_copied": "配置文件已复制",
|
||||
"init_success": "AstrBot 初始化完成!",
|
||||
"init_failed": "初始化失败: {error}",
|
||||
|
||||
# Run command
|
||||
"run_starting": "正在启动 AstrBot...",
|
||||
"run_started": "AstrBot 已启动!",
|
||||
"run_backend_only": "以无界面模式启动",
|
||||
"run_failed": "启动失败: {error}",
|
||||
"run_stopped": "AstrBot 已停止",
|
||||
|
||||
# TUI command
|
||||
"tui_starting": "正在启动 TUI...",
|
||||
"tui_started": "TUI 已启动",
|
||||
"tui_failed": "TUI 启动失败: {error}",
|
||||
|
||||
# Common
|
||||
"yes": "是",
|
||||
"no": "否",
|
||||
@@ -125,7 +117,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"cli_version": "AstrBot CLI version: {version}",
|
||||
"cli_unknown_command": "Unknown command: {command}",
|
||||
"cli_help_available": "Use astrbot help --all to see all commands",
|
||||
|
||||
# Dashboard commands
|
||||
"dashboard_bundled": "Dashboard is bundled with the package - skipping download",
|
||||
"dashboard_not_installed": "Dashboard is not installed",
|
||||
@@ -140,7 +131,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"dashboard_download_failed": "Failed to download dashboard: {error}",
|
||||
"dashboard_init_dir": "Initializing dashboard directory...",
|
||||
"dashboard_init_success": "Dashboard initialized successfully",
|
||||
|
||||
# Plugin commands
|
||||
"plugin_installing": "Installing plugin: {name}",
|
||||
"plugin_install_success": "Plugin installed successfully: {name}",
|
||||
@@ -159,7 +149,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"plugin_updating": "Updating plugin {name}...",
|
||||
"plugin_search_no_result": "No plugins matching '{query}' found",
|
||||
"plugin_search_results": "Search results: '{query}'",
|
||||
|
||||
# Config commands
|
||||
"config_show": "Show configuration",
|
||||
"config_set_success": "Configuration updated: {key} = {value}",
|
||||
@@ -169,7 +158,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"config_get_not_found": "Configuration key not found: {key}",
|
||||
"config_reset_confirm": "Reset all configuration?",
|
||||
"config_reset_success": "Configuration reset",
|
||||
|
||||
# Config validators
|
||||
"config_log_level_invalid": "Log level must be one of DEBUG/INFO/WARNING/ERROR/CRITICAL",
|
||||
"config_port_must_be_number": "Port must be a number",
|
||||
@@ -181,7 +169,6 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"config_key_unsupported": "Unsupported config key: {key}",
|
||||
"config_key_unknown": "Unknown config key: {key}",
|
||||
"config_updated": "Config updated: {key}",
|
||||
|
||||
# Init command
|
||||
"init_creating": "Creating config directory...",
|
||||
"init_created": "Config directory created: {path}",
|
||||
@@ -189,19 +176,16 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"init_copied": "Config files copied",
|
||||
"init_success": "AstrBot initialized successfully!",
|
||||
"init_failed": "Initialization failed: {error}",
|
||||
|
||||
# Run command
|
||||
"run_starting": "Starting AstrBot...",
|
||||
"run_started": "AstrBot started!",
|
||||
"run_backend_only": "Starting in backend-only mode",
|
||||
"run_failed": "Failed to start: {error}",
|
||||
"run_stopped": "AstrBot stopped",
|
||||
|
||||
# TUI command
|
||||
"tui_starting": "Starting TUI...",
|
||||
"tui_started": "TUI started",
|
||||
"tui_failed": "Failed to start TUI: {error}",
|
||||
|
||||
# Common
|
||||
"yes": "Yes",
|
||||
"no": "No",
|
||||
|
||||
@@ -72,7 +72,9 @@ class FunctionTool(ToolSchema, Generic[TContext]):
|
||||
def __repr__(self) -> str:
|
||||
return f"FuncTool(name={self.name}, parameters={self.parameters}, description={self.description})"
|
||||
|
||||
async def call(self, context: ContextWrapper[TContext], **kwargs: Any) -> ToolExecResult:
|
||||
async def call(
|
||||
self, context: ContextWrapper[TContext], **kwargs: Any
|
||||
) -> ToolExecResult:
|
||||
"""Run the tool with the given arguments. The handler field has priority."""
|
||||
raise NotImplementedError(
|
||||
"FunctionTool.call() must be implemented by subclasses or set a handler."
|
||||
|
||||
@@ -191,12 +191,15 @@ class AstrBotConfigManager:
|
||||
raise ValueError("不能删除默认配置文件")
|
||||
|
||||
# 从映射中移除
|
||||
abconf_data = self.sp.get(
|
||||
"abconf_mapping",
|
||||
{},
|
||||
scope="global",
|
||||
scope_id="global",
|
||||
) or {}
|
||||
abconf_data = (
|
||||
self.sp.get(
|
||||
"abconf_mapping",
|
||||
{},
|
||||
scope="global",
|
||||
scope_id="global",
|
||||
)
|
||||
or {}
|
||||
)
|
||||
if conf_id not in abconf_data:
|
||||
logger.warning(f"配置文件 {conf_id} 不存在于映射中")
|
||||
return False
|
||||
@@ -242,12 +245,15 @@ class AstrBotConfigManager:
|
||||
if conf_id == "default":
|
||||
raise ValueError("不能更新默认配置文件的信息")
|
||||
|
||||
abconf_data = self.sp.get(
|
||||
"abconf_mapping",
|
||||
{},
|
||||
scope="global",
|
||||
scope_id="global",
|
||||
) or {}
|
||||
abconf_data = (
|
||||
self.sp.get(
|
||||
"abconf_mapping",
|
||||
{},
|
||||
scope="global",
|
||||
scope_id="global",
|
||||
)
|
||||
or {}
|
||||
)
|
||||
if conf_id not in abconf_data:
|
||||
logger.warning(f"配置文件 {conf_id} 不存在于映射中")
|
||||
return False
|
||||
|
||||
@@ -75,7 +75,12 @@ class QQOfficialMessageEvent(AstrMessageEvent):
|
||||
# 先标记事件层“已执行发送操作”,避免异常路径遗漏
|
||||
await super().send_streaming(generator, use_fallback)
|
||||
# QQ C2C 流式协议:开始/中间分片使用 state=1,结束分片使用 state=10
|
||||
stream_payload: dict[str, Any] = {"state": 1, "id": None, "index": 0, "reset": False}
|
||||
stream_payload: dict[str, Any] = {
|
||||
"state": 1,
|
||||
"id": None,
|
||||
"index": 0,
|
||||
"reset": False,
|
||||
}
|
||||
last_edit_time = 0 # 上次发送分片的时间
|
||||
throttle_interval = 1 # 分片间最短间隔 (秒)
|
||||
ret = None
|
||||
|
||||
@@ -23,12 +23,15 @@ class SessionServiceManager:
|
||||
|
||||
"""
|
||||
# 获取会话服务配置
|
||||
session_services = await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_service_config",
|
||||
default={},
|
||||
) or {}
|
||||
session_services = (
|
||||
await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_service_config",
|
||||
default={},
|
||||
)
|
||||
or {}
|
||||
)
|
||||
|
||||
# 如果配置了该会话的LLM状态,返回该状态
|
||||
llm_enabled = session_services.get("llm_enabled")
|
||||
@@ -94,12 +97,15 @@ class SessionServiceManager:
|
||||
|
||||
"""
|
||||
# 获取会话服务配置
|
||||
session_services = await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_service_config",
|
||||
default={},
|
||||
) or {}
|
||||
session_services = (
|
||||
await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_service_config",
|
||||
default={},
|
||||
)
|
||||
or {}
|
||||
)
|
||||
|
||||
# 如果配置了该会话的TTS状态,返回该状态
|
||||
tts_enabled = session_services.get("tts_enabled")
|
||||
@@ -169,12 +175,15 @@ class SessionServiceManager:
|
||||
|
||||
"""
|
||||
# 获取会话服务配置
|
||||
session_services = await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_service_config",
|
||||
default={},
|
||||
) or {}
|
||||
session_services = (
|
||||
await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_service_config",
|
||||
default={},
|
||||
)
|
||||
or {}
|
||||
)
|
||||
|
||||
# 如果配置了该会话的整体状态,返回该状态
|
||||
session_enabled = session_services.get("session_enabled")
|
||||
|
||||
@@ -23,12 +23,15 @@ class SessionPluginManager:
|
||||
|
||||
"""
|
||||
# 获取会话插件配置
|
||||
session_plugin_config = await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_plugin_config",
|
||||
default={},
|
||||
) or {}
|
||||
session_plugin_config = (
|
||||
await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_plugin_config",
|
||||
default={},
|
||||
)
|
||||
or {}
|
||||
)
|
||||
session_config = session_plugin_config.get(session_id, {})
|
||||
|
||||
enabled_plugins = session_config.get("enabled_plugins", [])
|
||||
@@ -65,12 +68,15 @@ class SessionPluginManager:
|
||||
session_id = event.unified_msg_origin
|
||||
filtered_handlers = []
|
||||
|
||||
session_plugin_config = await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_plugin_config",
|
||||
default={},
|
||||
) or {}
|
||||
session_plugin_config = (
|
||||
await sp.get_async(
|
||||
scope="umo",
|
||||
scope_id=session_id,
|
||||
key="session_plugin_config",
|
||||
default={},
|
||||
)
|
||||
or {}
|
||||
)
|
||||
session_config = session_plugin_config.get(session_id, {})
|
||||
disabled_plugins = session_config.get("disabled_plugins", [])
|
||||
|
||||
|
||||
@@ -99,7 +99,9 @@ class SendMessageToUserTool(FunctionTool[AstrAgentContext]):
|
||||
async def call(
|
||||
self, context: ContextWrapper[AstrAgentContext], **kwargs: Any
|
||||
) -> ToolExecResult:
|
||||
session: str | MessageSession = kwargs.get("session") or context.context.event.unified_msg_origin
|
||||
session: str | MessageSession = (
|
||||
kwargs.get("session") or context.context.event.unified_msg_origin
|
||||
)
|
||||
messages: list[dict[str, Any]] | None = kwargs.get("messages")
|
||||
|
||||
if not isinstance(messages, list) or not messages:
|
||||
|
||||
@@ -23,7 +23,9 @@ class Route:
|
||||
# 统一添加 /api 前缀
|
||||
full_path = f"/api{path}"
|
||||
endpoint = f"{self.__class__.__name__.lower()}_{func.__name__}"
|
||||
self.app.add_url_rule(full_path, view_func=func, methods=[method], endpoint=endpoint)
|
||||
self.app.add_url_rule(
|
||||
full_path, view_func=func, methods=[method], endpoint=endpoint
|
||||
)
|
||||
|
||||
# 兼容字典和列表两种格式
|
||||
routes_to_register = (
|
||||
|
||||
@@ -271,7 +271,9 @@ class ToolsRoute(Route):
|
||||
or is_rename
|
||||
):
|
||||
try:
|
||||
await self.tool_mgr.disable_mcp_server(old_name, shutdown_timeout=10)
|
||||
await self.tool_mgr.disable_mcp_server(
|
||||
old_name, shutdown_timeout=10
|
||||
)
|
||||
except TimeoutError as e:
|
||||
return (
|
||||
Response()
|
||||
|
||||
+15
-14
@@ -476,14 +476,15 @@ class AstrBotDashboard:
|
||||
async def run(self) -> None:
|
||||
"""Run dashboard server (blocking)"""
|
||||
if self._webui_fallback:
|
||||
logger.warning("前端未内置或未初始化,回退到仅启动后端。请访问在线面板:dash.astrbot.men")
|
||||
logger.warning(
|
||||
"前端未内置或未初始化,回退到仅启动后端。请访问在线面板:dash.astrbot.men"
|
||||
)
|
||||
elif not self.enable_webui:
|
||||
logger.warning("前端已禁用,请访问在线面板:dash.astrbot.men")
|
||||
|
||||
dashboard_config = self.config.get("dashboard", {})
|
||||
host_value = (
|
||||
os.environ.get("ASTRBOT_HOST")
|
||||
or dashboard_config.get("host", "0.0.0.0")
|
||||
host_value = os.environ.get("ASTRBOT_HOST") or dashboard_config.get(
|
||||
"host", "0.0.0.0"
|
||||
)
|
||||
host = _resolve_dashboard_value(host_value, field_name="host")
|
||||
if not isinstance(host, str) or not host:
|
||||
@@ -494,7 +495,10 @@ class AstrBotDashboard:
|
||||
json_port = dashboard_config.get("port")
|
||||
if env_port is not None:
|
||||
port_value = env_port
|
||||
logger.info("[Dashboard] Using port from ASTRBOT_PORT environment variable: %s", env_port)
|
||||
logger.info(
|
||||
"[Dashboard] Using port from ASTRBOT_PORT environment variable: %s",
|
||||
env_port,
|
||||
)
|
||||
elif json_port is not None:
|
||||
port_value = json_port
|
||||
logger.info("[Dashboard] Using port from cmd_config.json: %s", json_port)
|
||||
@@ -542,19 +546,16 @@ class AstrBotDashboard:
|
||||
config.bind = binds
|
||||
|
||||
if ssl_enable:
|
||||
cert_file = (
|
||||
os.environ.get("ASTRBOT_SSL_CERT")
|
||||
or ssl_config.get("cert_file", "")
|
||||
cert_file = os.environ.get("ASTRBOT_SSL_CERT") or ssl_config.get(
|
||||
"cert_file", ""
|
||||
)
|
||||
cert_file = _resolve_dashboard_value(cert_file, field_name="ssl.cert_file")
|
||||
key_file = (
|
||||
os.environ.get("ASTRBOT_SSL_KEY")
|
||||
or ssl_config.get("key_file", "")
|
||||
key_file = os.environ.get("ASTRBOT_SSL_KEY") or ssl_config.get(
|
||||
"key_file", ""
|
||||
)
|
||||
key_file = _resolve_dashboard_value(key_file, field_name="ssl.key_file")
|
||||
ca_certs = (
|
||||
os.environ.get("ASTRBOT_SSL_CA_CERTS")
|
||||
or ssl_config.get("ca_certs", "")
|
||||
ca_certs = os.environ.get("ASTRBOT_SSL_CA_CERTS") or ssl_config.get(
|
||||
"ca_certs", ""
|
||||
)
|
||||
ca_certs = _resolve_dashboard_value(ca_certs, field_name="ssl.ca_certs")
|
||||
|
||||
|
||||
@@ -26,36 +26,30 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"welcome_local_mode": "本地测试模式",
|
||||
"welcome_instructions": "输入消息后按 Enter 发送, ESC 或 Ctrl+C 退出",
|
||||
"welcome_language": "语言已自动检测为中文",
|
||||
|
||||
# Status messages
|
||||
"status_ready": "就绪",
|
||||
"status_connected": "已连接",
|
||||
"status_disconnected": "未连接",
|
||||
"status_processing": "处理中...",
|
||||
"status_sending": "发送中...",
|
||||
|
||||
# Message indicators
|
||||
"indicator_user": "我",
|
||||
"indicator_bot": "AI",
|
||||
"indicator_system": "系统",
|
||||
"indicator_tool": "工具",
|
||||
"indicator_reasoning": "推理",
|
||||
|
||||
# Input hints
|
||||
"input_prompt": "> ",
|
||||
"input_placeholder": "输入消息...",
|
||||
|
||||
# Error messages
|
||||
"error_empty_message": "消息不能为空",
|
||||
"error_send_failed": "发送失败",
|
||||
"error_connection_lost": "连接已断开",
|
||||
"error_unknown": "未知错误",
|
||||
|
||||
# Tool messages
|
||||
"tool_using": "使用工具中",
|
||||
"tool_completed": "工具执行完成",
|
||||
"tool_failed": "工具执行失败",
|
||||
|
||||
# Reasoning messages
|
||||
"reasoning_thinking": "思考中...",
|
||||
"reasoning_reasoning": "推理中...",
|
||||
@@ -66,36 +60,30 @@ _TRANSLATIONS: dict[Language, dict[str, str]] = {
|
||||
"welcome_local_mode": "Local Testing Mode",
|
||||
"welcome_instructions": "Type your message and press Enter to send. ESC or Ctrl+C to exit.",
|
||||
"welcome_language": "Language auto-detected as English",
|
||||
|
||||
# Status messages
|
||||
"status_ready": "Ready",
|
||||
"status_connected": "Connected",
|
||||
"status_disconnected": "Disconnected",
|
||||
"status_processing": "Processing...",
|
||||
"status_sending": "Sending...",
|
||||
|
||||
# Message indicators
|
||||
"indicator_user": "Me",
|
||||
"indicator_bot": "AI",
|
||||
"indicator_system": "Sys",
|
||||
"indicator_tool": "Tool",
|
||||
"indicator_reasoning": "Reason",
|
||||
|
||||
# Input hints
|
||||
"input_prompt": "> ",
|
||||
"input_placeholder": "Type a message...",
|
||||
|
||||
# Error messages
|
||||
"error_empty_message": "Message cannot be empty",
|
||||
"error_send_failed": "Failed to send",
|
||||
"error_connection_lost": "Connection lost",
|
||||
"error_unknown": "Unknown error",
|
||||
|
||||
# Tool messages
|
||||
"tool_using": "Using tool",
|
||||
"tool_completed": "Tool completed",
|
||||
"tool_failed": "Tool failed",
|
||||
|
||||
# Reasoning messages
|
||||
"reasoning_thinking": "Thinking...",
|
||||
"reasoning_reasoning": "Reasoning...",
|
||||
|
||||
@@ -83,25 +83,21 @@ async def main() -> None:
|
||||
result = await orchestrator.abp.call_star_tool(
|
||||
star_name="demo-star",
|
||||
tool_name="echo",
|
||||
arguments={"message": "Hello from ABP!"}
|
||||
arguments={"message": "Hello from ABP!"},
|
||||
)
|
||||
print(f" - Result: {result}")
|
||||
|
||||
# Test 2: Add tool
|
||||
print("\n Test 2: add tool")
|
||||
result = await orchestrator.abp.call_star_tool(
|
||||
star_name="demo-star",
|
||||
tool_name="add",
|
||||
arguments={"a": 10, "b": 25}
|
||||
star_name="demo-star", tool_name="add", arguments={"a": 10, "b": 25}
|
||||
)
|
||||
print(f" - Result: {result}")
|
||||
|
||||
# Test 3: Status tool
|
||||
print("\n Test 3: status tool")
|
||||
result = await orchestrator.abp.call_star_tool(
|
||||
star_name="demo-star",
|
||||
tool_name="status",
|
||||
arguments={}
|
||||
star_name="demo-star", tool_name="status", arguments={}
|
||||
)
|
||||
print(f" - Result: {result}")
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ async def test_bootstrap_components():
|
||||
try:
|
||||
from astrbot._internal.geteway.server import AstrbotGateway
|
||||
from astrbot._internal.runtime.orchestrator import AstrbotOrchestrator
|
||||
|
||||
print(" ✓ All imports successful")
|
||||
except Exception as e:
|
||||
print(f" ✗ Import failed: {e}")
|
||||
@@ -65,6 +66,7 @@ async def test_bootstrap_components():
|
||||
except Exception as e:
|
||||
print(f" ✗ ABP star test failed: {e}")
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
|
||||
# Test 4: Create gateway
|
||||
@@ -78,6 +80,7 @@ async def test_bootstrap_components():
|
||||
except Exception as e:
|
||||
print(f" ✗ Gateway creation failed: {e}")
|
||||
import traceback
|
||||
|
||||
traceback.print_exc()
|
||||
|
||||
# Test 5: Check anyio usage in components
|
||||
|
||||
+7
-3
@@ -15,7 +15,8 @@ async def test_lsp_ty_integration():
|
||||
# Start ty server as subprocess
|
||||
print("\n[1] Starting ty server...")
|
||||
ty_process = await asyncio.create_subprocess_exec(
|
||||
"ty", "server",
|
||||
"ty",
|
||||
"server",
|
||||
stdin=asyncio.subprocess.PIPE,
|
||||
stdout=asyncio.subprocess.PIPE,
|
||||
stderr=asyncio.subprocess.PIPE,
|
||||
@@ -26,6 +27,7 @@ async def test_lsp_ty_integration():
|
||||
print("\n[2] Importing LSP client...")
|
||||
try:
|
||||
from astrbot._internal.protocols.lsp.client import AstrbotLspClient
|
||||
|
||||
client = AstrbotLspClient()
|
||||
print(" ✓ LSP client created")
|
||||
except Exception as e:
|
||||
@@ -38,11 +40,13 @@ async def test_lsp_ty_integration():
|
||||
try:
|
||||
await client.connect_to_server(
|
||||
command=["ty", "server"],
|
||||
workspace_uri="file:///home/lightjunction/GITHUB/AstrBot"
|
||||
workspace_uri="file:///home/lightjunction/GITHUB/AstrBot",
|
||||
)
|
||||
print(" ✓ Connected to ty server")
|
||||
except Exception as e:
|
||||
print(f" ⚠ Connection failed (expected if ty doesn't support external connections): {e}")
|
||||
print(
|
||||
f" ⚠ Connection failed (expected if ty doesn't support external connections): {e}"
|
||||
)
|
||||
# This is expected - ty server uses stdio but our client expects subprocess
|
||||
|
||||
# Test 4: Send initialize request
|
||||
|
||||
Reference in New Issue
Block a user