diff --git a/server/routers/chat_router.py b/server/routers/chat_router.py index 9f6beece..26e5b279 100644 --- a/server/routers/chat_router.py +++ b/server/routers/chat_router.py @@ -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()) diff --git a/src/agents/common/tools.py b/src/agents/common/tools.py index 27210ac6..f78ebb40 100644 --- a/src/agents/common/tools.py +++ b/src/agents/common/tools.py @@ -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: diff --git a/web/src/layouts/AppLayout.vue b/web/src/layouts/AppLayout.vue index 2fc655b2..1d6fbf70 100644 --- a/web/src/layouts/AppLayout.vue +++ b/web/src/layouts/AppLayout.vue @@ -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" > - + diff --git a/web/src/utils/messageProcessor.js b/web/src/utils/messageProcessor.js index d7fe3799..6f71b754 100644 --- a/web/src/utils/messageProcessor.js +++ b/web/src/utils/messageProcessor.js @@ -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); - }); - } } /**