chore: apply ruff format to codebase

Reformat 23 files for consistent code style.
This commit is contained in:
LIghtJUNction
2026-03-24 10:14:28 +08:00
parent cf47a2ec61
commit 92ba30b6e1
23 changed files with 170 additions and 125 deletions
+14 -4
View File
@@ -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)}}
+3 -1
View File
@@ -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.
+4 -1
View File
@@ -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]
+9 -6
View File
@@ -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)
+3 -1
View File
@@ -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():
+10 -3
View File
@@ -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)
+4 -4
View File
@@ -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()
+13 -3
View File
@@ -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
+1 -3
View File
@@ -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()
-16
View File
@@ -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",
+3 -1
View File
@@ -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."
+18 -12
View File
@@ -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
+27 -18
View File
@@ -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")
+18 -12
View File
@@ -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", [])
+3 -1
View File
@@ -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:
+3 -1
View File
@@ -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 = (
+3 -1
View File
@@ -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
View File
@@ -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")
-12
View File
@@ -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...",
+3 -7
View File
@@ -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}")
+3
View File
@@ -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
View File
@@ -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