ForcePilot/backend/package/yuxi/channels/adapters/matrix/commands.py
Kris 2063145ce1 feat(matrix): 新增完整的Matrix适配器工具集
新增了20+个Matrix相关工具模块,包含线程处理、自动加入、消息去重、配置管理、安全策略、媒体处理、命令解析等功能,完善Matrix适配器基础能力
2026-05-12 00:45:54 +08:00

117 lines
3.3 KiB
Python

from __future__ import annotations
from typing import Any
_SLASH_COMMANDS: dict[str, dict[str, Any]] = {
"/new": {
"description": "Start a new conversation session",
"handler": "reset_session",
"args": [],
},
"/reset": {
"description": "Reset the current conversation context",
"handler": "reset_session",
"args": [],
},
"/model": {
"description": "Show or change the current model",
"handler": "show_model",
"args": [{"name": "model_name", "required": False, "description": "Model name to switch to"}],
},
"/help": {
"description": "Show available commands",
"handler": "show_help",
"args": [],
},
"/status": {
"description": "Show bot connection status",
"handler": "show_status",
"args": [],
},
"/channels": {
"description": "List connected channels",
"handler": "list_channels",
"args": [],
},
"/proxy": {
"description": "Start an ACP agent session proxy",
"handler": "acp_proxy",
"args": [
{"name": "spawn", "required": False, "description": "Spawn a new agent session"},
{"name": "bind", "required": False, "description": "Bind to thread"},
],
},
"/skill": {
"description": "Invoke a specific skill",
"handler": "invoke_skill",
"args": [{"name": "skill_name", "required": True, "description": "Name of the skill to invoke"}],
},
"/room_info": {
"description": "Show room information",
"handler": "room_info",
"args": [],
},
}
def detect_slash_command(text: str) -> dict[str, Any] | None:
if not text or not text.startswith("/"):
return None
parts = text.strip().split()
if not parts:
return None
command = parts[0].lower()
cmd_def = _SLASH_COMMANDS.get(command)
if not cmd_def:
return None
raw_args = parts[1:] if len(parts) > 1 else []
args: dict[str, str] = {}
cmd_args = cmd_def.get("args", [])
for i, arg_def in enumerate(cmd_args):
if i < len(raw_args):
arg_name = arg_def["name"]
if arg_name in ("spawn", "bind") and not raw_args[i].startswith("--"):
args[arg_name] = raw_args[i]
else:
args[arg_name] = raw_args[i]
return {
"command": command,
"handler": cmd_def["handler"],
"description": cmd_def["description"],
"args": args,
"raw": text,
}
def is_slash_command(text: str) -> bool:
if not text or not text.startswith("/"):
return False
parts = text.strip().split()
if not parts:
return False
return parts[0].lower() in _SLASH_COMMANDS
def get_command_list() -> list[dict[str, Any]]:
return [
{
"command": cmd,
"description": info["description"],
"args": info["args"],
}
for cmd, info in _SLASH_COMMANDS.items()
]
def format_help_text() -> str:
lines = ["**可用命令:**", ""]
for cmd, info in _SLASH_COMMANDS.items():
args_str = " ".join(f"[{a['name']}]" for a in info.get("args", []))
lines.append(f"**{cmd}** {args_str} - {info['description']}")
return "\n".join(lines)