fix: multiple UI and API issues

- Fix tool calls format for DeepSeek API (add type field)

- Fix config event handler name

- Fix message history display (preserve all messages)

- Fix right panel width and scrolling

- Add async config update to prevent UI freeze

- Add prompt caching with singleton pattern

- Update build scripts with complete hidden imports
This commit is contained in:
JianFeeeee
2026-04-12 23:41:19 +08:00
parent efc8182aa2
commit 82903a3fa7
8 changed files with 223 additions and 54 deletions

View File

@ -96,27 +96,50 @@ class BackendServer:
messages = [{"role": "user", "content": user_input}]
response = self._client.send_message_with_history(messages)
message = response.choices[0].message
content = message.content or "(无<EFBFBD><EFBFBD>复)"
content = message.content or "(无复)"
tool_calls = []
while message.tool_calls:
args = {}
try:
import json
args = json.loads(message.tool_calls[0].function.arguments)
except:
pass
# 处理所有工具调用
tool_results = []
allowed, reason = limiter.can_call(message.tool_calls[0].function.name, args)
if not allowed:
tool_calls.append({"name": message.tool_calls[0].function.name, "result": f"工具调用被拒绝: {reason}"})
continue
for tool_call in message.tool_calls:
args = {}
try:
import json
args = json.loads(tool_call.function.arguments)
except:
pass
allowed, reason = limiter.can_call(tool_call.function.name, args)
if not allowed:
tool_calls.append({"name": tool_call.function.name, "result": f"工具调用被拒绝: {reason}"})
tool_results.append({"role": "tool", "tool_call_id": tool_call.id, "content": f"工具调用被拒绝: {reason}"})
continue
limiter.record_call(tool_call.function.name, args)
result = execute_tool(self._graph, tool_call.function.name, args)
tool_calls.append({"name": tool_call.function.name, "result": result})
tool_results.append({"role": "tool", "tool_call_id": tool_call.id, "content": result})
# 添加 assistant 消息(包含完整的 tool_calls必须有 type 字段)
assistant_msg = {
"role": "assistant",
"content": message.content or "",
"tool_calls": [{
"id": tc.id,
"type": "function",
"function": {
"name": tc.function.name,
"arguments": tc.function.arguments
}
} for tc in message.tool_calls]
}
messages.append(assistant_msg)
# 添加工具结果
messages.extend(tool_results)
limiter.record_call(message.tool_calls[0].function.name, args)
result = execute_tool(self._graph, message.tool_calls[0].function.name, args)
tool_calls.append({"name": message.tool_calls[0].function.name, "result": result})
messages.append({"role": "assistant", "tool_calls": [{"id": "1", "function": {"name": message.tool_calls[0].function.name, "arguments": message.tool_calls[0].function.arguments}}]})
messages.append({"role": "tool", "tool_call_id": "1", "content": result})
response = self._client.send_message_with_history(messages)
message = response.choices[0].message
content = message.content or content

View File

@ -7,17 +7,33 @@ from pathlib import Path
class PromptManager:
"""提示词管理器"""
_instance = None
_cached_prompt = None
def __new__(cls):
"""单例模式,避免重复加载"""
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self):
self.prompts_dir = Path(__file__).parent / "templates"
if not hasattr(self, '_initialized'):
self.prompts_dir = Path(__file__).parent / "templates"
self._initialized = True
def get_system_prompt(self) -> str:
"""获取系统提示词"""
"""获取系统提示词(带缓存)"""
if PromptManager._cached_prompt is not None:
return PromptManager._cached_prompt
prompt_file = self.prompts_dir / "system_prompt.md"
if prompt_file.exists():
with open(prompt_file, "r", encoding="utf-8") as f:
return f.read()
PromptManager._cached_prompt = f.read()
else:
return self._build_default_prompt()
PromptManager._cached_prompt = self._build_default_prompt()
return PromptManager._cached_prompt
def _build_default_prompt(self) -> str:
"""构建默认提示词(精简版)"""