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:
shuiyu67andWorkBuddy committed 2026-08-08 00:54:18 +08:00
1 parent 66de8eea13
commit 749fb3f91c
15 files changed
+510 -249

No files matched your search

+24 -9
View File
@@ -39,9 +39,24 @@ class DisplayMixin:
else:
print(message)
def _truncate_for_display(self, content, max_chars=4000, max_lines=160):
"""仅用于「展示层」的截断:过长时折叠,不影响底层存储的对话数据。"""
if not content:
return content
lines = content.split('\n')
if len(lines) > max_lines or len(content) > max_chars:
kept = "\n".join(lines[:max_lines])
kept = kept[:max_chars]
hidden = len(content) - len(kept)
note = f"\n\n… (展示已折叠,完整内容共 {len(content)} 字符 / {len(lines)} 行,已完整保存到会话)"
return kept + note
return content
def _display_response(self, content, is_continue=False):
"""统一显示 AI 响应,支持 TUI 和 CLI 模式"""
"""统一显示 AI 响应,支持 TUI 和 CLI 模式(仅展示层截断,不改存储)"""
user_id_display = f"[用户ID: {self.user_id}]"
# 仅展示截断:存储用的 shared_conversation_history 仍是完整内容
content = self._truncate_for_display(content)
response_lines = content.split('\n')
if self.tui_output_callback:
for i, line in enumerate(response_lines):
@@ -98,14 +113,14 @@ class DisplayMixin:
self._output(f"{color} {line}{Style.RESET_ALL}")
def _typeprint(self, text, color=None, delay=0.01):
"""逐字输出文本,实现打字机效果"""
for char in text:
if color:
print(f"{color}{char}{Style.RESET_ALL}", end="", flush=True)
else:
print(char, end="", flush=True)
time.sleep(delay)
print()
"""输出文本(已取消逐字打字机效果,改为一次性完整输出)。
保留方法签名以兼容潜在调用方;不再逐字符 sleep,避免「流式显示」。
"""
if color:
print(f"{color}{text}{Style.RESET_ALL}")
else:
print(text)
# ── 图片显示 ──