Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 28 additions & 9 deletions frontends/continue_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,12 +271,21 @@ def _rounds_for_file(path, st):
return n, key


def list_sessions(exclude_pid=None):
def _normalize_path(path):
if not path:
return ''
return os.path.normcase(os.path.abspath(path))


def list_sessions(exclude_pid=None, exclude_path=None):
"""Newest-first list of (path, mtime, preview_text, n_rounds). Preview uses head/tail window only."""
files = glob.glob(_LOG_GLOB)
if exclude_pid is not None:
tag = f'model_responses_{exclude_pid}.txt'
files = [f for f in files if not f.endswith(tag)]
exclude_key = _normalize_path(exclude_path)
if exclude_key:
files = [f for f in files if _normalize_path(f) != exclude_key]
out = []
valid_keys = []
for f in files:
Expand Down Expand Up @@ -322,9 +331,17 @@ def _current_log_path(pid=None):
return os.path.join(_LOG_DIR, f'model_responses_{pid}.txt')


def _snapshot_current_log(pid=None):
"""Persist current PID log as a standalone recoverable snapshot, then clear it."""
path = _current_log_path(pid)
def _log_path_for_agent(agent=None, pid=None):
if agent is not None:
path = getattr(agent, 'log_path', '') or getattr(getattr(agent, 'llmclient', None), 'log_path', '')
if path:
return path
return _current_log_path(pid)


def _snapshot_current_log(agent=None, pid=None):
"""Persist the agent's active log as a recoverable snapshot, then clear it."""
path = _log_path_for_agent(agent, pid)
if not os.path.isfile(path):
return None
try:
Expand All @@ -351,7 +368,7 @@ def reset_conversation(agent, message='🆕 已开启新对话,当前上下文
agent.abort()
except Exception:
pass
_snapshot_current_log()
_snapshot_current_log(agent)
if hasattr(agent, 'history'):
agent.history = []
for client in _agent_clients(agent):
Expand Down Expand Up @@ -397,12 +414,13 @@ def restore(agent, path):
def handle(agent, query, display_queue):
"""Dispatch /continue or /continue N. Returns None if consumed else original query."""
s = (query or '').strip()
exclude_path = _log_path_for_agent(agent)
if s == '/continue':
display_queue.put({'done': format_list(list_sessions(exclude_pid=os.getpid())), 'source': 'system'})
display_queue.put({'done': format_list(list_sessions(exclude_pid=os.getpid(), exclude_path=exclude_path)), 'source': 'system'})
return None
m = re.match(r'/continue\s+(\d+)\s*$', s)
if m:
sessions = list_sessions(exclude_pid=os.getpid())
sessions = list_sessions(exclude_pid=os.getpid(), exclude_path=exclude_path)
idx = int(m.group(1)) - 1
if not (0 <= idx < len(sessions)):
display_queue.put({'done': f'❌ 索引越界(有效范围 1-{len(sessions)})', 'source': 'system'})
Expand Down Expand Up @@ -557,12 +575,13 @@ def handle_frontend_command(agent, query, exclude_pid=None):
"""Frontend-friendly /continue entry that returns text directly."""
s = (query or '').strip()
exclude_pid = os.getpid() if exclude_pid is None else exclude_pid
exclude_path = _log_path_for_agent(agent, exclude_pid)
if s == '/continue':
return format_list(list_sessions(exclude_pid=exclude_pid))
return format_list(list_sessions(exclude_pid=exclude_pid, exclude_path=exclude_path))
m = re.match(r'/continue\s+(\d+)\s*$', s)
if not m:
return '用法: /continue 或 /continue N'
sessions = list_sessions(exclude_pid=exclude_pid)
sessions = list_sessions(exclude_pid=exclude_pid, exclude_path=exclude_path)
idx = int(m.group(1)) - 1
if not (0 <= idx < len(sessions)):
return f'❌ 索引越界(有效范围 1-{len(sessions)})'
Expand Down
5 changes: 3 additions & 2 deletions frontends/tuiapp_v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3991,10 +3991,11 @@ def _cmd_review(self, args, raw):
def _cmd_continue(self, args, raw):
sess = self.current
m = re.match(r"/continue\s+(\S.*?)\s*$", (raw or "").strip())
log_path = getattr(sess.agent, "log_path", "") or ""
if m:
token = m.group(1)
if token.isdigit():
sessions = continue_list(exclude_pid=os.getpid())
sessions = continue_list(exclude_pid=os.getpid(), exclude_path=log_path)
idx = int(token) - 1
if not (0 <= idx < len(sessions)):
self._system(f"❌ 索引越界(有效范围 1-{len(sessions)})"); return
Expand All @@ -4013,7 +4014,7 @@ def _cmd_continue(self, args, raw):
self._system(f"❌ 找不到名为 {token!r} 的会话"); return
self._do_continue_restore(path)
return
sessions = continue_list(exclude_pid=os.getpid())
sessions = continue_list(exclude_pid=os.getpid(), exclude_path=log_path)
if not sessions:
self._system("❌ 没有可恢复的历史会话"); return
choices = []
Expand Down