fix(frontend): update TimelineToolGroup to visually propagate error status with red color and X icon
This commit is contained in:
@@ -65,7 +65,12 @@ interface Message {
|
||||
|
||||
type TimelineEntry =
|
||||
| { kind: "thought"; text: string }
|
||||
| { kind: "tool"; name: string; status: "running" | "done"; result?: string }
|
||||
| {
|
||||
kind: "tool";
|
||||
name: string;
|
||||
status: "running" | "done" | "error";
|
||||
result?: string;
|
||||
}
|
||||
// A text segment from one round of the assistant's tool loop.
|
||||
// Each text SSE event from the server starts a new entry; subsequent
|
||||
// streaming chunks for that same round append to the most-recent
|
||||
@@ -589,6 +594,7 @@ function TimelineToolGroup({
|
||||
const [expanded, setExpanded] = useState(false);
|
||||
const count = entries.length;
|
||||
const allDone = entries.every((e) => e.status === "done");
|
||||
const hasError = entries.some((e) => e.status === "error");
|
||||
|
||||
return (
|
||||
<div
|
||||
@@ -616,7 +622,9 @@ function TimelineToolGroup({
|
||||
}}
|
||||
>
|
||||
<span style={{ width: 14, display: "flex", justifyContent: "center" }}>
|
||||
{!allDone ? (
|
||||
{hasError ? (
|
||||
<span style={{ color: "#ef4444", fontWeight: "bold" }}>✗</span>
|
||||
) : !allDone ? (
|
||||
<Loader2
|
||||
style={{ width: 12, height: 12 }}
|
||||
className="animate-spin"
|
||||
@@ -625,8 +633,9 @@ function TimelineToolGroup({
|
||||
<Wrench style={{ width: 12, height: 12, color: "#2e7d32" }} />
|
||||
)}
|
||||
</span>
|
||||
<span style={{ flex: 1 }}>
|
||||
{category} {count > 1 ? `(x${count})` : ""} {!allDone ? "..." : " ✓"}
|
||||
<span style={{ flex: 1, color: hasError ? "#ef4444" : undefined }}>
|
||||
{category} {count > 1 ? `(x${count})` : ""}
|
||||
{hasError ? " ✗" : !allDone ? "..." : " ✓"}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
@@ -1294,6 +1303,14 @@ export function ChatPanel({
|
||||
// earlier same-named entries.
|
||||
let updated = false;
|
||||
const newTl: TimelineEntry[] = [];
|
||||
|
||||
const isToolErr =
|
||||
typeof ev.result === "string" &&
|
||||
(ev.result.toLowerCase().includes("error") ||
|
||||
ev.result.toLowerCase().includes("failed") ||
|
||||
ev.result.toLowerCase().includes("unexpected") ||
|
||||
ev.result.toLowerCase().includes("not found"));
|
||||
|
||||
for (let i = tl.length - 1; i >= 0; i--) {
|
||||
const e = tl[i];
|
||||
if (
|
||||
@@ -1304,7 +1321,7 @@ export function ChatPanel({
|
||||
) {
|
||||
newTl.unshift({
|
||||
...e,
|
||||
status: "done",
|
||||
status: isToolErr ? "error" : "done",
|
||||
result: ev.result,
|
||||
});
|
||||
updated = true;
|
||||
|
||||
Reference in New Issue
Block a user