feat: 修复消息渲染不完整的 bug

This commit is contained in:
Wenjie Zhang 2025-11-05 10:15:17 +08:00
parent 71cf6830e4
commit cf5f1a3d7e
4 changed files with 13 additions and 46 deletions

View File

@ -280,6 +280,11 @@ async def check_and_handle_interrupts(agent, langgraph_config, make_chunk, meta,
async def call(query: str = Body(...), meta: dict = Body(None), current_user: User = Depends(get_required_user)):
"""调用模型进行简单问答(需要登录)"""
meta = meta or {}
# 确保 request_id 存在
if "request_id" not in meta or not meta.get("request_id"):
meta["request_id"] = str(uuid.uuid4())
model = select_model(
model_provider=meta.get("model_provider"),
model_name=meta.get("model_name"),
@ -293,7 +298,7 @@ async def call(query: str = Body(...), meta: dict = Body(None), current_user: Us
response = await call_async(query)
logger.debug({"query": query, "response": response.content})
return {"response": response.content}
return {"response": response.content, "request_id": meta["request_id"]}
@chat.get("/agent")
@ -323,6 +328,10 @@ async def chat_agent(
logger.info(f"agent_id: {agent_id}, query: {query}, config: {config}, meta: {meta}")
# 确保 request_id 存在
if "request_id" not in meta or not meta.get("request_id"):
meta["request_id"] = str(uuid.uuid4())
meta.update(
{
"query": query,
@ -342,8 +351,6 @@ async def chat_agent(
+ b"\n"
)
# TODO:[功能建议]针对需要人工审批后再执行的工具,
# 可以使用langgraph的interrupt方法中断对话等待用户输入后再使用command跳转回去
async def stream_messages():
# 代表服务端已经收到了请求
yield make_chunk(status="init", meta=meta, msg=HumanMessage(content=query).model_dump())

View File

@ -88,7 +88,7 @@ def query_knowledge_graph(query: Annotated[str, "The keyword to query knowledge
def get_static_tools() -> list:
"""注册静态工具"""
static_tools = [query_knowledge_graph, get_approved_user_goal]
static_tools = [query_knowledge_graph, get_approved_user_goal, calculator]
# 检查是否启用网页搜索
if config.enable_web_search:

View File

@ -5,7 +5,7 @@ import {
GithubOutlined,
ExclamationCircleOutlined,
} from '@ant-design/icons-vue'
import { Bot, Waypoints, LibraryBig, Settings, BarChart3, BookOpen, ListChecks } from 'lucide-vue-next';
import { Bot, Waypoints, LibraryBig, Settings, BarChart3, BookOpen, CircleCheck } from 'lucide-vue-next';
import { onLongPress } from '@vueuse/core'
import { useConfigStore } from '@/stores/config'
@ -154,7 +154,7 @@ const mainList = [{
class="task-center-badge"
size="small"
>
<ListChecks class="icon" size="22" />
<CircleCheck class="icon" size="22" />
</a-badge>
</a-tooltip>
</div>

View File

@ -194,46 +194,6 @@ export class MessageProcessor {
}
}
}
// 4. 同步 tool_call_chunks 到 tool_calls (构建完整的工具调用)
if (result.tool_call_chunks && result.tool_call_chunks.length > 0) {
if (!result.tool_calls) result.tool_calls = [];
for (const chunk of result.tool_call_chunks) {
if (chunk.name && chunk.args) {
const existingToolCall = result.tool_calls.find(t => t.id === chunk.id);
if (!existingToolCall) {
// 创建新的完整工具调用
result.tool_calls.push({
id: chunk.id,
name: chunk.name,
args: chunk.args,
type: 'tool_call'
});
} else {
// 更新现有工具调用的参数
existingToolCall.args = chunk.args;
}
}
}
}
// 5. 清理无效的工具调用
if (result.tool_calls) {
result.tool_calls = result.tool_calls.filter(toolCall => {
// 保留有id或有name的工具调用并且不是空的args对象
return (toolCall.id || toolCall.name) &&
(toolCall.args !== undefined || toolCall.function?.arguments);
});
}
// 清理空的tool_call_chunks
if (result.tool_call_chunks) {
result.tool_call_chunks = result.tool_call_chunks.filter(chunk => {
return (chunk.id || chunk.name || chunk.args);
});
}
}
/**