xiaoli-cli 7.0.0: 重构底层架构 + 移除工具截断

- 重构 core/ 底层 (7文件): app/runner/engine/parser/history/safety/display
- FC原生调用为主,prompt-JSON保底
- 移除所有工具返回截断 (ai_search/git_tools/cmd_executor/browser_auto/network_tools/sub_agent/tool_search)
- 删除无用文件 (旧服务器/WebUI/彩蛋/启动器等21个文件)
- 清理 constants.py 死代码
- 版本号更新为 7.0.0
This commit is contained in:
shuiyu1123 committed 2026-07-05 13:17:27 +08:00
commit 78fea7ccdd
57 files changed
+18358

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
"""线程安全对话历史"""
import json
import threading
from .types import Message
class History:
def __init__(self, max_size=999999):
self._msgs = []
self._lock = threading.RLock()
self._max = max_size
def add_user(self, text):
with self._lock:
self._msgs.append(Message("user", text))
self._trim()
def add_assistant(self, text, tool_calls=None):
with self._lock:
m = Message("assistant", text)
if tool_calls:
m.tool_calls = tool_calls
self._msgs.append(m)
self._trim()
def add_tool(self, call_id, name, result):
with self._lock:
self._msgs.append(Message("tool", result, tool_call_id=call_id, name=name))
self._trim()
def add_cancel(self, name, args):
with self._lock:
self._msgs.append(Message("user", f"工具 {name} 已取消。参数: {args}"))
self._trim()
def _trim(self):
if len(self._msgs) > self._max:
self._msgs = self._msgs[-self._max:]
def render(self, system_prompt="", current=None, fc=False):
"""渲染为消息列表。fc=True 用 role:tool,否则工具结果用 role:user"""
with self._lock:
result = []
if system_prompt:
result.append({"role": "system", "content": system_prompt})
for m in self._msgs:
if m.role == "tool" and not fc:
result.append({"role": "user", "content": m.content})
else:
entry = {"role": m.role, "content": m.content}
if fc and m.role == "tool" and m.tool_call_id:
entry["tool_call_id"] = m.tool_call_id
if m.name:
entry["name"] = m.name
if fc and m.role == "assistant" and m.tool_calls:
# content 为空时设为 None(OpenAI 规范:有 tool_calls 时 content 可为 null)
if not entry.get("content"):
entry["content"] = None
# arguments 必须是 JSON 字符串(OpenAI 规范)
entry["tool_calls"] = [
{"id": tc.id, "type": "function",
"function": {
"name": tc.name,
"arguments": json.dumps(tc.arguments, ensure_ascii=False) if tc.arguments
else json.dumps({"args": tc.args}, ensure_ascii=False)
}}
for tc in m.tool_calls
]
result.append(entry)
if current:
result.append({"role": "user", "content": current})
return result
def snapshot(self):
with self._lock:
return list(self._msgs)
def clear(self):
with self._lock:
self._msgs.clear()
def __len__(self):
with self._lock:
return len(self._msgs)