chore: auto commit

This commit is contained in:
LIghtJUNction
2026-03-23 22:21:06 +08:00
parent 385d882aa9
commit 99a9941aba
7 changed files with 200 additions and 10 deletions

View File

@@ -7,7 +7,6 @@ The gateway acts as the communication bridge between the dashboard and the orche
from __future__ import annotations
import asyncio
import json
from contextlib import asynccontextmanager
from typing import Any
@@ -41,7 +40,6 @@ class AstrbotGateway(BaseAstrbotGateway):
self.orchestrator = orchestrator
self.ws_manager = WebSocketManager()
self._app: FastAPI | None = None
self._server_task: asyncio.Task[None] | None = None
self._host = "0.0.0.0"
self._port = 8765

View File

@@ -4,9 +4,10 @@ WebSocket connection manager for the AstrBot gateway.
from __future__ import annotations
import asyncio
from typing import Any
import anyio
from astrbot import logger
try:
@@ -27,7 +28,7 @@ class WebSocketManager:
def __init__(self) -> None:
self._connections: set[WebSocket] = set()
self._lock = asyncio.Lock()
self._lock = anyio.Lock()
async def connect(self, websocket: WebSocket) -> None:
"""Accept and register a new WebSocket connection."""

View File

@@ -18,7 +18,7 @@ class AlterCmdCommands(CommandParserMixin):
"""更新reset命令在特定场景下的权限设置"""
from astrbot.api import sp
alter_cmd_cfg = await sp.global_get("alter_cmd", {})
alter_cmd_cfg = await sp.global_get("alter_cmd", {}) or {}
plugin_cfg = alter_cmd_cfg.get("astrbot", {})
reset_cfg = plugin_cfg.get("reset", {})
reset_cfg[scene_key] = perm_type
@@ -47,7 +47,7 @@ class AlterCmdCommands(CommandParserMixin):
if cmd_name == "reset" and cmd_type == "config":
from astrbot.api import sp
alter_cmd_cfg = await sp.global_get("alter_cmd", {})
alter_cmd_cfg = await sp.global_get("alter_cmd", {}) or {}
plugin_ = alter_cmd_cfg.get("astrbot", {})
reset_cfg = plugin_.get("reset", {})
@@ -131,7 +131,7 @@ class AlterCmdCommands(CommandParserMixin):
from astrbot.api import sp
alter_cmd_cfg = await sp.global_get("alter_cmd", {})
alter_cmd_cfg = await sp.global_get("alter_cmd", {}) or {}
plugin_ = alter_cmd_cfg.get(found_plugin.name, {})
cfg = plugin_.get(found_command.handler_name, {})
cfg["permission"] = cmd_type

View File

@@ -48,7 +48,7 @@ class ConversationCommands:
scene = RstScene.get_scene(is_group, is_unique_session)
alter_cmd_cfg = await sp.get_async("global", "global", "alter_cmd", {})
alter_cmd_cfg = await sp.get_async("global", "global", "alter_cmd", {}) or {}
plugin_config = alter_cmd_cfg.get("astrbot", {})
reset_cfg = plugin_config.get("reset", {})

View File

@@ -9,7 +9,7 @@ class SetUnsetCommands:
async def set_variable(self, event: AstrMessageEvent, key: str, value: str) -> None:
"""设置会话变量"""
uid = event.unified_msg_origin
session_var = await sp.session_get(uid, "session_variables", {})
session_var = await sp.session_get(uid, "session_variables", {}) or {}
session_var[key] = value
await sp.session_put(uid, "session_variables", session_var)
@@ -22,7 +22,7 @@ class SetUnsetCommands:
async def unset_variable(self, event: AstrMessageEvent, key: str) -> None:
"""移除会话变量"""
uid = event.unified_msg_origin
session_var = await sp.session_get(uid, "session_variables", {})
session_var = await sp.session_get(uid, "session_variables", {}) or {}
if key not in session_var:
event.set_result(

111
test_bootstrap.py Normal file
View File

@@ -0,0 +1,111 @@
"""Bootstrap integration test - validates the orchestrator and gateway."""
from __future__ import annotations
import asyncio
import sys
async def test_bootstrap_components():
"""Test that all bootstrap components can be imported and initialized."""
print("=" * 60)
print("AstrBot Bootstrap Integration Test")
print("=" * 60)
# Test 1: Import all components
print("\n[1] Testing imports...")
try:
from astrbot._internal.runtime.orchestrator import AstrbotOrchestrator
from astrbot._internal.geteway.server import AstrbotGateway
from astrbot._internal.abc.base_astrbot_gateway import BaseAstrbotGateway
from astrbot._internal.abc.base_astrbot_orchestrator import BaseAstrbotOrchestrator
print(" ✓ All imports successful")
except Exception as e:
print(f" ✗ Import failed: {e}")
return False
# Test 2: Create orchestrator
print("\n[2] Testing orchestrator creation...")
try:
orchestrator = AstrbotOrchestrator()
print(f" ✓ Orchestrator created")
print(f" - LSP client: {type(orchestrator.lsp).__name__}")
print(f" - MCP client: {type(orchestrator.mcp).__name__}")
print(f" - ACP client: {type(orchestrator.acp).__name__}")
print(f" - ABP client: {type(orchestrator.abp).__name__}")
except Exception as e:
print(f" ✗ Orchestrator creation failed: {e}")
return False
# Test 3: Test ABP star registration
print("\n[3] Testing ABP star registration...")
try:
from unittest.mock import AsyncMock, MagicMock
# Create a mock star
mock_star = MagicMock()
mock_star.call_tool = AsyncMock(return_value="test_result")
# Register the star
await orchestrator.register_star("test-star", mock_star)
print(" ✓ Star registered")
# Verify registration
retrieved = await orchestrator.get_star("test-star")
if retrieved is mock_star:
print(" ✓ Star retrieval works")
else:
print(" ✗ Star retrieval failed")
# List stars
stars = await orchestrator.list_stars()
print(f" ✓ Stars list: {stars}")
# Unregister
await orchestrator.unregister_star("test-star")
print(" ✓ Star unregistered")
except Exception as e:
print(f" ✗ ABP star test failed: {e}")
import traceback
traceback.print_exc()
# Test 4: Create gateway
print("\n[4] Testing gateway creation...")
try:
gateway = AstrbotGateway(orchestrator)
print(f" ✓ Gateway created")
print(f" - Host: {gateway._host}")
print(f" - Port: {gateway._port}")
print(f" - WebSocket manager: {type(gateway.ws_manager).__name__}")
except Exception as e:
print(f" ✗ Gateway creation failed: {e}")
import traceback
traceback.print_exc()
# Test 5: Check anyio usage in components
print("\n[5] Checking anyio compliance...")
import inspect
orchestrator_source = inspect.getsource(orchestrator.__class__)
if "asyncio" in orchestrator_source and "import asyncio" in orchestrator_source:
print(" ⚠ Orchestrator imports asyncio (violation)")
else:
print(" ✓ Orchestrator uses anyio only")
gateway_source = inspect.getsource(gateway.__class__)
if "import asyncio" in gateway_source:
print(" ⚠ Gateway imports asyncio (violation)")
else:
print(" ✓ Gateway anyio check passed")
print("\n" + "=" * 60)
print("Bootstrap integration test completed")
print("=" * 60)
return True
if __name__ == "__main__":
# Run with asyncio since the test itself is sync
result = asyncio.run(test_bootstrap_components())
sys.exit(0 if result else 1)

80
test_lsp_ty.py Normal file
View File

@@ -0,0 +1,80 @@
"""Test LSP client connecting to ty server via stdio."""
from __future__ import annotations
import asyncio
import subprocess
import sys
async def test_lsp_ty_integration():
"""Test that LSP client can connect to ty server via stdio."""
print("=" * 60)
print("LSP Client - ty Server Integration Test")
print("=" * 60)
# Start ty server as subprocess
print("\n[1] Starting ty server...")
ty_process = await asyncio.create_subprocess_exec(
"ty", "server",
stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE,
)
print(f" ✓ ty server started (PID: {ty_process.pid})")
# Import LSP client
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:
print(f" ✗ Failed to import/create client: {e}")
ty_process.terminate()
return False
# Connect to ty server
print("\n[3] Connecting to ty server...")
try:
await client.connect_to_server(
command=["ty", "server"],
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}")
# This is expected - ty server uses stdio but our client expects subprocess
# Test 4: Send initialize request
print("\n[4] Testing LSP protocol...")
try:
result = await client.send_request(
"initialize",
{
"processId": None,
"rootUri": "file:///home/lightjunction/GITHUB/AstrBot",
"capabilities": {},
},
)
print(f" ✓ Initialize response: {result}")
except Exception as e:
print(f" ⚠ LSP request failed: {e}")
# Cleanup
print("\n[5] Shutting down...")
await client.shutdown()
ty_process.terminate()
await ty_process.wait()
print(" ✓ Cleanup complete")
print("\n" + "=" * 60)
print("LSP ty integration test completed")
print("=" * 60)
return True
if __name__ == "__main__":
result = asyncio.run(test_lsp_ty_integration())
sys.exit(0 if result else 1)