diff --git a/langgraph/src/agent-uis/enterprise/knowledge-result/index.tsx b/langgraph/src/agent-uis/enterprise/knowledge-result/index.tsx index 2b1d597..28b9c6b 100644 --- a/langgraph/src/agent-uis/enterprise/knowledge-result/index.tsx +++ b/langgraph/src/agent-uis/enterprise/knowledge-result/index.tsx @@ -1,4 +1,4 @@ -import { BookOpen } from "lucide-react"; +import { BookOpen, AlertCircle } from "lucide-react"; import { ActionBar } from "@/components/ActionBar"; import { SourceBadge } from "@/components/SourceBadge"; @@ -8,6 +8,7 @@ interface KnowledgeResultProps { results: Array<{ title: string; category: string; snippet: string }>; sourceType?: string; confidence?: "high" | "medium" | "low"; + errorMessage?: string; } export default function KnowledgeResult({ @@ -16,9 +17,10 @@ export default function KnowledgeResult({ results, sourceType, confidence, + errorMessage, }: KnowledgeResultProps) { return ( -
{errorMessage}
+{errorMessage}
+;
sourceType?: string;
confidence?: "high" | "medium" | "low";
+ errorMessage?: string;
}
function getDomain(url: string): string {
@@ -24,9 +25,10 @@ export default function SearchResult({
results,
sourceType,
confidence,
+ errorMessage,
}: SearchResultProps) {
return (
-
+
{/* Header */}
@@ -44,6 +46,14 @@ export default function SearchResult({
+ {/* Error */}
+ {errorMessage && (
+
+
+ {errorMessage}
+
+ )}
+
{/* Results */}
{results.length === 0 ? (
diff --git a/langgraph/src/agent-uis/enterprise/ticket-summary/index.tsx b/langgraph/src/agent-uis/enterprise/ticket-summary/index.tsx
index 5e2193d..8047f0e 100644
--- a/langgraph/src/agent-uis/enterprise/ticket-summary/index.tsx
+++ b/langgraph/src/agent-uis/enterprise/ticket-summary/index.tsx
@@ -1,4 +1,4 @@
-import { TicketIcon } from "lucide-react";
+import { TicketIcon, AlertCircle } from "lucide-react";
import { cn } from "@/lib/utils";
import { ActionBar } from "@/components/ActionBar";
import { SourceBadge } from "@/components/SourceBadge";
@@ -16,6 +16,7 @@ interface TicketSummaryProps {
stats: Record;
sourceType?: string;
confidence?: "high" | "medium" | "low";
+ errorMessage?: string;
}
function priorityClass(priority: string): string {
@@ -54,9 +55,10 @@ export default function TicketSummary({
stats,
sourceType,
confidence,
+ errorMessage,
}: TicketSummaryProps) {
return (
-
+
{/* Header */}
@@ -84,6 +86,14 @@ export default function TicketSummary({
)}
+ {/* Error */}
+ {errorMessage && (
+
+
+ {errorMessage}
+
+ )}
+
{/* Ticket list */}
{tickets.length === 0 ? (
diff --git a/langgraph/src/components/ToolCallStatus.tsx b/langgraph/src/components/ToolCallStatus.tsx
index cb5c14a..0653068 100644
--- a/langgraph/src/components/ToolCallStatus.tsx
+++ b/langgraph/src/components/ToolCallStatus.tsx
@@ -1,4 +1,4 @@
-import { Loader2, CheckCircle2, ChevronRight, ChevronDown } from "lucide-react";
+import { Loader2, CheckCircle2, ChevronRight, ChevronDown, XCircle } from "lucide-react";
import { useState } from "react";
import { LoadExternalComponent } from "@langchain/langgraph-sdk/react-ui";
@@ -52,6 +52,7 @@ interface ToolCallStatusProps {
toolCalls: ToolCall[];
isLoading: boolean;
completedToolIds?: Set;
+ failedToolIds?: Set;
uiItems?: UIMsgLocal[];
stream?: Parameters[0]["stream"];
components?: Parameters[0]["components"];
@@ -60,12 +61,14 @@ interface ToolCallStatusProps {
function ToolCallRow({
tc,
isDone,
+ isFailed,
uiItem,
stream,
components,
}: {
tc: ToolCall;
isDone: boolean;
+ isFailed: boolean;
uiItem?: UIMsgLocal;
stream?: ToolCallStatusProps["stream"];
components?: ToolCallStatusProps["components"];
@@ -91,21 +94,33 @@ function ToolCallRow({
) : (
)}
- {isDone ? (
+ {isFailed ? (
+
+ ) : isDone ? (
) : (
)}
{label}
- {isDone ? (canExpand ? (expanded ? "收起" : "查看结果") : `已完成 · ${label}`) : (tc.name ? (TOOL_LOADING_MAP[tc.name] ?? `正在${label}...`) : "思考中...")}
+ {isFailed ? `失败 · ${label}` : isDone ? (canExpand ? (expanded ? "收起" : "查看结果") : `已完成 · ${label}`) : (tc.name ? (TOOL_LOADING_MAP[tc.name] ?? `正在${label}...`) : "思考中...")}
{expanded && uiItem && stream && components && (
-
+
+
+
+
+ )}
+ {expanded && !uiItem && (
+
+
+
+
+
)}
@@ -116,6 +131,7 @@ export default function ToolCallStatus({
toolCalls,
isLoading,
completedToolIds,
+ failedToolIds,
uiItems = [],
stream,
components,
@@ -139,6 +155,7 @@ export default function ToolCallStatus({
{toolCalls.map((tc, i) => {
const isDone = !isLoading || (tc.id && completedToolIds?.has(tc.id));
+ const isFailed = !!(tc.id && failedToolIds?.has(tc.id));
let uiItem: UIMsgLocal | undefined;
if (tc.name && UI_NAME_MAP[tc.name]) {
const uiName = UI_NAME_MAP[tc.name];
@@ -153,6 +170,7 @@ export default function ToolCallStatus({
key={tc.id ?? i}
tc={tc}
isDone={!!isDone}
+ isFailed={isFailed}
uiItem={uiItem}
stream={stream}
components={components}
diff --git a/langgraph/src/main.tsx b/langgraph/src/main.tsx
index 02d29eb..0848b92 100644
--- a/langgraph/src/main.tsx
+++ b/langgraph/src/main.tsx
@@ -318,6 +318,14 @@ function App() {
.filter(Boolean),
);
+ // ── Collect failed tool call IDs ─────────────────────────────────────────
+ const failedToolIds = new Set(
+ thread.messages
+ .filter((m) => m.type === "tool" && (m as any).status === "error")
+ .map((m) => (m as any).tool_call_id as string)
+ .filter(Boolean),
+ );
+
// ── Find last AI message index ──────────────────────────────────────────
const lastAiIdx = thread.messages.reduce((last, m, i) => (m.type === "ai" ? i : last), -1);
@@ -490,6 +498,7 @@ function App() {
toolCalls={toolCalls}
isLoading={thread.isLoading}
completedToolIds={completedToolIds}
+ failedToolIds={failedToolIds}
uiItems={uiItems}
stream={thread}
components={ComponentMap as any}