feat(命令): 添加直接模式和智能模式切换功能
- 在 OrchestrationAgent 中添加 passthrough 状态管理 - 新增 /direct 和 /smart 命令用于切换模式 - 修改 /list 命令为 /status 并显示当前模式状态 - 更新帮助信息包含新模式命令
This commit is contained in:
parent
5d55d01f40
commit
de6205d2fd
@ -45,8 +45,8 @@ async def handle_command(user_id: str, text: str) -> Optional[str]:
|
|||||||
|
|
||||||
if cmd in ("/new", "/n"):
|
if cmd in ("/new", "/n"):
|
||||||
return await _cmd_new(user_id, args)
|
return await _cmd_new(user_id, args)
|
||||||
elif cmd in ("/list", "/ls", "/l"):
|
elif cmd in ("/status", "/list", "/ls", "/l"):
|
||||||
return await _cmd_list(user_id)
|
return await _cmd_status(user_id)
|
||||||
elif cmd in ("/close", "/c"):
|
elif cmd in ("/close", "/c"):
|
||||||
return await _cmd_close(user_id, args)
|
return await _cmd_close(user_id, args)
|
||||||
elif cmd in ("/switch", "/s"):
|
elif cmd in ("/switch", "/s"):
|
||||||
@ -55,6 +55,10 @@ async def handle_command(user_id: str, text: str) -> Optional[str]:
|
|||||||
return await _cmd_retry(user_id)
|
return await _cmd_retry(user_id)
|
||||||
elif cmd in ("/help", "/h", "/?"):
|
elif cmd in ("/help", "/h", "/?"):
|
||||||
return _cmd_help()
|
return _cmd_help()
|
||||||
|
elif cmd == "/direct":
|
||||||
|
return _cmd_direct(user_id)
|
||||||
|
elif cmd == "/smart":
|
||||||
|
return _cmd_smart(user_id)
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@ -107,18 +111,22 @@ async def _cmd_new(user_id: str, args: str) -> str:
|
|||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
async def _cmd_list(user_id: str) -> str:
|
async def _cmd_status(user_id: str) -> str:
|
||||||
"""List all sessions for this user."""
|
"""Show status: sessions and current mode."""
|
||||||
sessions = manager.list_sessions(user_id=user_id)
|
sessions = manager.list_sessions(user_id=user_id)
|
||||||
if not sessions:
|
if not sessions:
|
||||||
return "No active sessions."
|
return "No active sessions."
|
||||||
|
|
||||||
active = agent.get_active_conv(user_id)
|
active = agent.get_active_conv(user_id)
|
||||||
|
passthrough = agent.get_passthrough(user_id)
|
||||||
lines = ["**Your Sessions:**\n"]
|
lines = ["**Your Sessions:**\n"]
|
||||||
for i, s in enumerate(sessions, 1):
|
for i, s in enumerate(sessions, 1):
|
||||||
marker = "→ " if s["conv_id"] == active else " "
|
marker = "→ " if s["conv_id"] == active else " "
|
||||||
lines.append(f"{marker}{i}. `{s['conv_id']}` - `{s['cwd']}`")
|
lines.append(f"{marker}{i}. `{s['conv_id']}` - `{s['cwd']}`")
|
||||||
lines.append("\nUse `/switch <n>` to activate a session.")
|
status = "Direct 🟢" if passthrough else "Smart ⚪"
|
||||||
|
lines.append(f"\n**Mode:** {status}")
|
||||||
|
lines.append("Use `/switch <n>` to activate a session.")
|
||||||
|
lines.append("Use `/direct` or `/smart` to change mode.")
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
@ -161,7 +169,7 @@ async def _cmd_switch(user_id: str, args: str) -> str:
|
|||||||
return "No sessions available."
|
return "No sessions available."
|
||||||
|
|
||||||
if not args:
|
if not args:
|
||||||
return "Usage: /switch <n>\n" + await _cmd_list(user_id)
|
return "Usage: /switch <n>\n" + await _cmd_status(user_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
idx = int(args) - 1
|
idx = int(args) - 1
|
||||||
@ -180,12 +188,29 @@ async def _cmd_retry(user_id: str) -> str:
|
|||||||
return "Retry not yet implemented. Just send your message again."
|
return "Retry not yet implemented. Just send your message again."
|
||||||
|
|
||||||
|
|
||||||
|
def _cmd_direct(user_id: str) -> str:
|
||||||
|
"""Enable direct mode - messages go straight to Claude Code."""
|
||||||
|
conv = agent.get_active_conv(user_id)
|
||||||
|
if not conv:
|
||||||
|
return "No active session. Use `/new` or `/switch` first."
|
||||||
|
agent.set_passthrough(user_id, True)
|
||||||
|
return f"✓ Direct mode ON. Messages go directly to session `{conv}`."
|
||||||
|
|
||||||
|
|
||||||
|
def _cmd_smart(user_id: str) -> str:
|
||||||
|
"""Enable smart mode - messages go through LLM for routing."""
|
||||||
|
agent.set_passthrough(user_id, False)
|
||||||
|
return "✓ Smart mode ON. Messages go through LLM for intelligent routing."
|
||||||
|
|
||||||
|
|
||||||
def _cmd_help() -> str:
|
def _cmd_help() -> str:
|
||||||
"""Show help."""
|
"""Show help."""
|
||||||
return """**Commands:**
|
return """**Commands:**
|
||||||
/new <dir> [msg] [--timeout N] [--idle N] - Create session
|
/new <dir> [msg] [--timeout N] [--idle N] - Create session
|
||||||
/list - List your sessions
|
/status - Show sessions and current mode
|
||||||
/close [n] - Close session (active or by number)
|
/close [n] - Close session (active or by number)
|
||||||
/switch <n> - Switch to session by number
|
/switch <n> - Switch to session by number
|
||||||
|
/direct - Direct mode: messages → Claude Code (no LLM overhead)
|
||||||
|
/smart - Smart mode: messages → LLM routing (default)
|
||||||
/retry - Retry last message
|
/retry - Retry last message
|
||||||
/help - Show this help"""
|
/help - Show this help"""
|
||||||
|
|||||||
@ -74,6 +74,8 @@ class OrchestrationAgent:
|
|||||||
self._active_conv: Dict[str, Optional[str]] = defaultdict(lambda: None)
|
self._active_conv: Dict[str, Optional[str]] = defaultdict(lambda: None)
|
||||||
# user_id -> asyncio.Lock (prevents concurrent processing per user)
|
# user_id -> asyncio.Lock (prevents concurrent processing per user)
|
||||||
self._user_locks: Dict[str, asyncio.Lock] = defaultdict(asyncio.Lock)
|
self._user_locks: Dict[str, asyncio.Lock] = defaultdict(asyncio.Lock)
|
||||||
|
# user_id -> passthrough mode enabled
|
||||||
|
self._passthrough: Dict[str, bool] = defaultdict(lambda: False)
|
||||||
|
|
||||||
def _build_system_prompt(self, user_id: str) -> str:
|
def _build_system_prompt(self, user_id: str) -> str:
|
||||||
conv_id = self._active_conv[user_id]
|
conv_id = self._active_conv[user_id]
|
||||||
@ -89,6 +91,12 @@ class OrchestrationAgent:
|
|||||||
def get_active_conv(self, user_id: str) -> Optional[str]:
|
def get_active_conv(self, user_id: str) -> Optional[str]:
|
||||||
return self._active_conv.get(user_id)
|
return self._active_conv.get(user_id)
|
||||||
|
|
||||||
|
def get_passthrough(self, user_id: str) -> bool:
|
||||||
|
return self._passthrough.get(user_id, False)
|
||||||
|
|
||||||
|
def set_passthrough(self, user_id: str, enabled: bool) -> None:
|
||||||
|
self._passthrough[user_id] = enabled
|
||||||
|
|
||||||
async def run(self, user_id: str, text: str) -> str:
|
async def run(self, user_id: str, text: str) -> str:
|
||||||
"""Process a user message and return the agent's reply."""
|
"""Process a user message and return the agent's reply."""
|
||||||
async with self._user_locks[user_id]:
|
async with self._user_locks[user_id]:
|
||||||
@ -102,8 +110,8 @@ class OrchestrationAgent:
|
|||||||
logger.info(">>> user=...%s conv=%s msg=%r", short_uid, active_conv, text[:80])
|
logger.info(">>> user=...%s conv=%s msg=%r", short_uid, active_conv, text[:80])
|
||||||
logger.debug(" history_len=%d", len(self._history[user_id]))
|
logger.debug(" history_len=%d", len(self._history[user_id]))
|
||||||
|
|
||||||
# Passthrough mode: if active session, bypass LLM (bot commands handled earlier)
|
# Passthrough mode: if enabled and active session, bypass LLM
|
||||||
if active_conv:
|
if self._passthrough[user_id] and active_conv:
|
||||||
try:
|
try:
|
||||||
reply = await manager.send(active_conv, text, user_id=user_id)
|
reply = await manager.send(active_conv, text, user_id=user_id)
|
||||||
logger.info("<<< [passthrough] reply: %r", reply[:120])
|
logger.info("<<< [passthrough] reply: %r", reply[:120])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user