diff --git a/langgraph/src/agent/coder/nodes/tool-executor.ts b/langgraph/src/agent/coder/nodes/tool-executor.ts index 5339405..b42246a 100644 --- a/langgraph/src/agent/coder/nodes/tool-executor.ts +++ b/langgraph/src/agent/coder/nodes/tool-executor.ts @@ -96,7 +96,10 @@ export async function toolExecutorNode( return { role: "tool" as const, tool_call_id: id, - content: formatToolError(name, e), + content: JSON.stringify({ + error: formatToolError(name, e), + fallback_hint: "沙盒暂时不可用。请告知用户:1) 可以直接分析代码逻辑而无需执行;2) 可稍后重试;3) 可以把代码粘贴到本地环境运行。", + }), }; } }); diff --git a/langgraph/src/agent/enterprise/nodes/tool-executor.ts b/langgraph/src/agent/enterprise/nodes/tool-executor.ts index 0c3db2a..793ef00 100644 --- a/langgraph/src/agent/enterprise/nodes/tool-executor.ts +++ b/langgraph/src/agent/enterprise/nodes/tool-executor.ts @@ -171,6 +171,18 @@ export async function toolExecutorNode( }, { message: lastAiMessage }, ); + if (tickets.length === 0) { + statusList.push({ tool: name, status: "empty", message: "未查询到工单" }); + return { + role: "tool" as const, + tool_call_id: id, + content: JSON.stringify({ + total: 0, + tickets: [], + hint: "未查询到工单。请告知用户可以:1) 尝试不同的查询条件;2) 检查权限;3) 确认工单系统是否有数据。", + }), + }; + } statusList.push({ tool: name, status: "ok" }); return { role: "tool" as const, @@ -225,7 +237,10 @@ export async function toolExecutorNode( return { role: "tool" as const, tool_call_id: id, - content: formatToolError(name, e), + content: JSON.stringify({ + error: formatToolError(name, e), + fallback_hint: "工具执行失败。请用中文向用户解释错误原因,并提供替代建议。", + }), }; } }); diff --git a/langgraph/src/agent/enterprise/tools/soc-client.ts b/langgraph/src/agent/enterprise/tools/soc-client.ts index 89bb74c..9c47396 100644 --- a/langgraph/src/agent/enterprise/tools/soc-client.ts +++ b/langgraph/src/agent/enterprise/tools/soc-client.ts @@ -59,7 +59,7 @@ export async function ticketDetail( // If ticketId looks like a ticketNumber (e.g. "TK-2026-296691"), resolve UUID first let resolvedId = ticketId; if (ticketId.startsWith("TK-")) { - const searchUrl = `${base}/api/tickets?ticketNumber=${encodeURIComponent(ticketId)}&pageSize=1`; + const searchUrl = `${base}/api/tickets?ticketNumber=${encodeURIComponent(ticketId)}&pageSize=50`; const searchResp = await fetch(searchUrl, { headers, signal: AbortSignal.timeout(15000), @@ -67,8 +67,9 @@ export async function ticketDetail( if (searchResp.ok) { const searchData = await searchResp.json(); const tickets = searchData.tickets ?? []; - if (tickets.length > 0 && tickets[0].id) { - resolvedId = tickets[0].id; + const match = tickets.find((t: Record) => t.ticketNumber === ticketId); + if (match?.id) { + resolvedId = String(match.id); } } } diff --git a/langgraph/src/agent/searcher/nodes/tool-executor.ts b/langgraph/src/agent/searcher/nodes/tool-executor.ts index 08119c1..89c039c 100644 --- a/langgraph/src/agent/searcher/nodes/tool-executor.ts +++ b/langgraph/src/agent/searcher/nodes/tool-executor.ts @@ -68,6 +68,18 @@ export async function toolExecutorNode( snippet: r.snippet, })); knowledgeGraph = data.knowledgeGraph; + // Auto-supplement with Jina if results < 3 + if (results.length < 3) { + try { + const supplementData = await webSearch(parsed.query + " 详细信息"); + const supplementResults = supplementData.results.slice(0, 3 - results.length).map((r) => ({ + title: r.title ?? "", + url: r.url ?? "", + snippet: (r.description ?? r.content ?? "").slice(0, 200), + })); + results = [...results, ...supplementResults]; + } catch { /* supplement search failed silently */ } + } } catch { // google_search failed, fallback to web_search_deep (Jina) console.warn(`[fallback] google_search failed, trying web_search_deep`);