release: v8.0.4 — 会话 SQLite 存储 + 去加载动画 + 展示截断 + 工具调用解析加固
- 会话数据改用 SQLite(chat_history/conversations.db,WAL):sessions / snapshots 两表, 首次启动自动迁移旧 JSON,/chat 与 /resume 改走 SQLite,memory 搜索兼容数据库 - 去掉流式显示(_typeprint 改整段打印)与常驻加载动画(移除 show_animation 线程及逐帧输出) - 展示给用户的消息过长自动截断(仅展示层,底层 messages 完整保存) - 工具调用解析加固:_loads_json 四级兜底修复;新增 _extract_last_action_json 成对错括号扫描; 续轮也下发 Function Calling 工具,减少长文本格式错误浪费 token - 版本号统一更新至 8.0.4(README/about.txt/constants/TUI banner/LSP·MCP clientInfo) - 12 项 session 单测 + 8 项 JSON 提取边界用例全部通过 Co-Authored-By: WorkBuddy <workbuddy@tencent.com>
This commit is contained in:
1 parent
66de8eea13
commit
749fb3f91c
15 files changed
+510
-249
No files matched your search
+22
-24
@@ -9,17 +9,17 @@ class HistoryMixin:
|
||||
"""聊天记录管理相关方法(含 opencode 式会话持久化 /resume)"""
|
||||
|
||||
def save_chat_history(self, name):
|
||||
"""保存当前聊天记录到文件"""
|
||||
"""保存当前聊天记录(SQLite 快照)"""
|
||||
try:
|
||||
chat_data = {
|
||||
"timestamp": time.strftime("%Y-%m-%d %H:%M:%S"),
|
||||
"conversation": self.shared_conversation_history.copy()
|
||||
}
|
||||
file_path = os.path.join(self.chat_history_dir, f"{name}.json")
|
||||
with open(file_path, 'w', encoding='utf-8') as f:
|
||||
json.dump(chat_data, f, ensure_ascii=False, indent=2, default=str)
|
||||
print(f"{Fore.GREEN}聊天记录已保存为: {name}{Style.RESET_ALL}")
|
||||
return True
|
||||
if not hasattr(self, 'session_manager'):
|
||||
self.init_session_manager()
|
||||
ok = self.session_manager.save_snapshot(
|
||||
name, self.shared_conversation_history.copy())
|
||||
if ok:
|
||||
print(f"{Fore.GREEN}聊天记录已保存为: {name}{Style.RESET_ALL}")
|
||||
return True
|
||||
print(f"{Fore.RED}保存聊天记录失败{Style.RESET_ALL}")
|
||||
return False
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}保存聊天记录失败: {e}{Style.RESET_ALL}")
|
||||
return False
|
||||
@@ -27,30 +27,28 @@ class HistoryMixin:
|
||||
def list_chat_history(self):
|
||||
"""列出所有已保存的聊天记录"""
|
||||
try:
|
||||
chat_files = [f for f in os.listdir(self.chat_history_dir) if f.endswith('.json')]
|
||||
if not chat_files:
|
||||
if not hasattr(self, 'session_manager'):
|
||||
self.init_session_manager()
|
||||
snaps = self.session_manager.list_snapshots()
|
||||
if not snaps:
|
||||
print(f"{Fore.YELLOW}没有已保存的聊天记录{Style.RESET_ALL}")
|
||||
return
|
||||
print(f"{Fore.GREEN}已保存的聊天记录:{Style.RESET_ALL}")
|
||||
for i, file in enumerate(chat_files, 1):
|
||||
file_path = os.path.join(self.chat_history_dir, file)
|
||||
mod_time = os.path.getmtime(file_path)
|
||||
mod_time_str = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(mod_time))
|
||||
chat_name = file[:-5]
|
||||
print(f"{Fore.GREEN}{i}. {chat_name} (保存时间: {mod_time_str}){Style.RESET_ALL}")
|
||||
for i, (chat_name, saved_at) in enumerate(snaps, 1):
|
||||
print(f"{Fore.GREEN}{i}. {chat_name} (保存时间: {saved_at}){Style.RESET_ALL}")
|
||||
except Exception as e:
|
||||
print(f"{Fore.RED}列出聊天记录失败: {e}{Style.RESET_ALL}")
|
||||
|
||||
def load_chat_history(self, name):
|
||||
"""加载指定的聊天记录"""
|
||||
"""加载指定的聊天记录(SQLite 快照)"""
|
||||
try:
|
||||
file_path = os.path.join(self.chat_history_dir, f"{name}.json")
|
||||
if not os.path.exists(file_path):
|
||||
if not hasattr(self, 'session_manager'):
|
||||
self.init_session_manager()
|
||||
msgs = self.session_manager.load_snapshot(name)
|
||||
if msgs is None:
|
||||
print(f"{Fore.RED}聊天记录 '{name}' 不存在{Style.RESET_ALL}")
|
||||
return False
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
chat_data = json.load(f)
|
||||
self.shared_conversation_history = chat_data.get("conversation", [])
|
||||
self.shared_conversation_history = list(msgs)
|
||||
self._set_shared_conversation_history()
|
||||
print(f"{Fore.GREEN}已加载聊天记录: {name}{Style.RESET_ALL}")
|
||||
if self.shared_conversation_history:
|
||||
|
||||
Reference in new issue
Block a user