From a278ece348e1fce93212bdfde2caa0ed773a4f1c Mon Sep 17 00:00:00 2001 From: "Yuyao Huang (Sam)" Date: Mon, 30 Mar 2026 00:11:41 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E5=8F=AF=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E7=9A=84=E5=91=BD=E4=BB=A4=E5=89=8D=E7=BC=80=E4=BB=A5?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E4=B8=8EClaude=20Code=E5=86=B2=E7=AA=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 引入可配置的COMMAND_PREFIX参数,默认设置为"//"以避免与Claude Code的"/"命令冲突 修改相关文件以支持新的命令前缀,包括配置解析、路由逻辑和命令处理 更新帮助文档和提示信息以反映新的命令前缀 --- bot/commands.py | 78 +++++++++++++++++++++------------------- config.py | 4 +++ host_config.example.yaml | 4 +++ orchestrator/agent.py | 49 +++++++++++++++---------- router/routing_agent.py | 6 ++-- 5 files changed, 85 insertions(+), 56 deletions(-) diff --git a/bot/commands.py b/bot/commands.py index e48e2d9..dd406e4 100644 --- a/bot/commands.py +++ b/bot/commands.py @@ -44,14 +44,18 @@ def _perm_label(mode: str) -> str: def parse_command(text: str) -> Optional[Tuple[str, str]]: """ - Parse a slash command from text. + Parse a bot command from text. Returns (command, args) or None if not a command. + Commands must start with COMMAND_PREFIX (default "//"). """ + from config import COMMAND_PREFIX text = text.strip() - if not text.startswith("/"): + if not text.startswith(COMMAND_PREFIX): return None - parts = text.split(None, 1) - cmd = parts[0].lower() + # Strip the prefix, then split into command word and args + body = text[len(COMMAND_PREFIX):] + parts = body.split(None, 1) + cmd = COMMAND_PREFIX + parts[0].lower() args = parts[1] if len(parts) > 1 else "" return (cmd, args) @@ -68,38 +72,39 @@ async def handle_command(user_id: str, text: str) -> Optional[str]: logger.info("Command: %s args=%r user=...%s", cmd, args[:50], user_id[-8:]) # In ROUTER_MODE, only handle router-specific commands locally. - # Session commands (/status, /new, /close, etc.) fall through to node forwarding. - from config import ROUTER_MODE - if ROUTER_MODE and cmd not in ("/nodes", "/node", "/help", "/h", "/?"): + # Session commands (//status, //new, //close, etc.) fall through to node forwarding. + from config import ROUTER_MODE, COMMAND_PREFIX + P = COMMAND_PREFIX + if ROUTER_MODE and cmd not in (P+"nodes", P+"node", P+"help", P+"h", P+"?"): return None set_current_user(user_id) - if cmd in ("/new", "/n"): + if cmd in (P+"new", P+"n"): return await _cmd_new(user_id, args) - elif cmd in ("/status", "/list", "/ls", "/l"): + elif cmd in (P+"status", P+"list", P+"ls", P+"l"): return await _cmd_status(user_id) - elif cmd in ("/close", "/c"): + elif cmd in (P+"close", P+"c"): return await _cmd_close(user_id, args) - elif cmd in ("/switch", "/s"): + elif cmd in (P+"switch", P+"s"): return await _cmd_switch(user_id, args) - elif cmd == "/retry": + elif cmd == P+"retry": return await _cmd_retry(user_id) - elif cmd in ("/help", "/h", "/?"): + elif cmd in (P+"help", P+"h", P+"?"): return _cmd_help() - elif cmd == "/direct": + elif cmd == P+"direct": return _cmd_direct(user_id) - elif cmd == "/smart": + elif cmd == P+"smart": return _cmd_smart(user_id) - elif cmd == "/tasks": + elif cmd == P+"tasks": return _cmd_tasks() - elif cmd == "/shell": + elif cmd == P+"shell": return await _cmd_shell(args) - elif cmd == "/remind": + elif cmd == P+"remind": return await _cmd_remind(args) - elif cmd == "/perm": + elif cmd == P+"perm": return await _cmd_perm(user_id, args) - elif cmd in ("/nodes", "/node"): + elif cmd in (P+"nodes", P+"node"): return await _cmd_nodes(user_id, args) else: return None @@ -431,23 +436,24 @@ async def _cmd_nodes(user_id: str, args: str) -> str: def _cmd_help() -> str: """Show help.""" - return """**Commands:** -/new [msg] [--timeout N] [--idle N] [--perm MODE] - Create session -/status - Show sessions and current mode -/close [n] - Close session (active or by number) -/switch - Switch to session by number -/perm [conv_id] - Set permission mode (bypass/accept/plan) -/direct - Direct mode: messages → Claude Code (no LLM overhead) -/smart - Smart mode: messages → LLM routing (default) -/shell - Run shell command (bypasses LLM) -/remind