Coverage for cli / commands / session.py: 18%
74 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-29 02:55 +0800
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-29 02:55 +0800
1"""
2/session 命令处理模块
3"""
4from rich.console import Console
5from rich.table import Table
6from qrclaw.memory.session import Session, list_sessions, delete_session
7from qrclaw.workspace import Workspace
8from qrclaw.logger import setup_logger
9from qrclaw.config import LOG_LEVEL, LOG_MAX_DAYS, LOG_TO_FILE, LOG_TO_CONSOLE, LOG_CONSOLE_LEVEL
12def handle(args: str, current_session: Session, console: Console, workspace: Workspace) -> Session:
13 """
14 处理 /session 子命令,返回(可能切换后的)Session。
16 子命令:
17 list 列出当前 agent 的所有会话
18 new [id] 新建并切换(不传 id 则自动生成)
19 switch <id> 切换到已有会话
20 delete <id> 删除指定会话
21 """
22 parts = args.strip().split(maxsplit=1)
24 if not parts or not parts[0]:
25 _print_help(console)
26 return current_session
28 subcommand = parts[0]
29 sub_args = parts[1].strip() if len(parts) > 1 else ""
31 if subcommand == "list":
32 return _cmd_list(current_session, console, workspace)
33 elif subcommand == "new":
34 return _cmd_new(sub_args, current_session, console, workspace)
35 elif subcommand == "switch":
36 return _cmd_switch(sub_args, current_session, console, workspace)
37 elif subcommand == "delete":
38 return _cmd_delete(sub_args, current_session, console, workspace)
39 else:
40 console.print(f"[red]未知子命令: {subcommand}[/red]")
41 _print_help(console)
42 return current_session
45def _cmd_list(current_session: Session, console: Console, workspace: Workspace) -> Session:
46 sessions = list_sessions(workspace.sessions_dir)
47 if not sessions:
48 console.print("[yellow]没有已保存的会话[/yellow]")
49 return current_session
51 table = Table(title=f"会话列表 (agent: {workspace.agent_id})")
52 table.add_column("会话 ID", style="cyan")
53 table.add_column("消息数", style="green", justify="right")
54 table.add_column("最后更新", style="dim")
55 table.add_column("", style="bold yellow")
57 for s in sessions:
58 marker = "← 当前" if s["id"] == current_session.session_id else ""
59 table.add_row(s["id"], str(s["message_count"]), s["updated_at"], marker)
61 console.print(table)
62 return current_session
65def _cmd_new(session_id: str, current_session: Session, console: Console, workspace: Workspace) -> Session:
66 _reinit_logger(session_id or None, workspace)
67 # 关键修复:必须传入 resume=False,否则会恢复最近的会话
68 new_session = Session(sessions_dir=workspace.sessions_dir, session_id=session_id or None, resume=False)
69 console.print(f"[bold cyan]已新建并切换到会话: {new_session.session_id}[/bold cyan]")
70 return new_session
73def _cmd_switch(session_id: str, current_session: Session, console: Console, workspace: Workspace) -> Session:
74 if not session_id:
75 console.print("[red]用法: /session switch <会话ID>[/red]")
76 return current_session
78 _reinit_logger(session_id, workspace)
79 target = Session(sessions_dir=workspace.sessions_dir, session_id=session_id)
80 msg = f"已切换到会话: {session_id}"
81 if target.messages:
82 msg += f"({len(target.messages)} 条历史消息)"
83 console.print(f"[bold cyan]{msg}[/bold cyan]")
84 return target
87def _cmd_delete(session_id: str, current_session: Session, console: Console, workspace: Workspace) -> Session:
88 if not session_id:
89 console.print("[red]用法: /session delete <会话ID>[/red]")
90 return current_session
92 if session_id == current_session.session_id:
93 console.print("[red]不能删除当前正在使用的会话,请先切换到其他会话[/red]")
94 return current_session
96 if delete_session(session_id, workspace.sessions_dir):
97 console.print(f"[dim]会话 {session_id} 已删除[/dim]")
98 else:
99 console.print(f"[yellow]会话 {session_id} 不存在[/yellow]")
101 return current_session
104def _reinit_logger(session_id: str | None, workspace: Workspace) -> None:
105 setup_logger(
106 session_id=session_id or "tmp",
107 log_level=LOG_LEVEL,
108 log_to_file=LOG_TO_FILE,
109 log_to_console=LOG_TO_CONSOLE,
110 log_max_days=LOG_MAX_DAYS,
111 console_level=LOG_CONSOLE_LEVEL,
112 log_dir=workspace.logs_dir,
113 )
116def _print_help(console: Console) -> None:
117 console.print("[dim]用法: /session <list|new|switch|delete> [会话ID][/dim]")
118 console.print("[dim] list 列出所有会话[/dim]")
119 console.print("[dim] new [id] 新建会话(不传 id 则自动生成)[/dim]")
120 console.print("[dim] switch <id> 切换会话[/dim]")
121 console.print("[dim] delete <id> 删除会话[/dim]")