fix(server): 修复对话消息被空历史覆盖——WebTerminal.__del__与回收器保存增加非空守卫

对话级 terminal 隔离后,被丢弃的实例(竞态重复、回收重建、TTL回收)
常处于 current_conversation_id 已设但 conversation_history 为空的状态,
GC 触发 __del__ 时无条件 save_current_conversation 把磁盘非空对话覆盖为空。
两处保存路径均增加 conversation_history 非空守卫。
This commit is contained in:
JOJO 2026-07-20 13:26:18 +08:00
parent de318636ce
commit 8628954f30
2 changed files with 9 additions and 4 deletions

View File

@ -835,10 +835,14 @@ class WebTerminal(MainTerminal):
def __del__(self):
"""析构函数,确保资源释放"""
try:
# 保存当前对话
# 保存当前对话(仅当内存中确有消息时)。
# 竞态重建/回收场景下,被丢弃的实例可能只设了
# current_conversation_id 而 conversation_history 为空,
# 此时保存会把磁盘上非空的对话覆盖成空消息。
if hasattr(self, 'context_manager') and self.context_manager:
if self.context_manager.current_conversation_id:
self.context_manager.save_current_conversation()
cm = self.context_manager
if cm.current_conversation_id and getattr(cm, 'conversation_history', None):
cm.save_current_conversation()
# 关闭所有终端
if hasattr(self, 'terminal_manager') and self.terminal_manager:

View File

@ -893,7 +893,8 @@ def reap_idle_conversation_terminals(now: Optional[float] = None) -> int:
continue
try:
cm = getattr(terminal, "context_manager", None)
if cm and getattr(cm, "current_conversation_id", None):
# 与 __del__ 同理:空 history 保存会把磁盘上非空对话覆盖为空
if cm and getattr(cm, "current_conversation_id", None) and getattr(cm, "conversation_history", None):
cm.save_current_conversation()
except Exception as exc:
debug_log(f"[ConvTerminalReaper] 保存对话失败 {conversation_id}: {exc}")