优化 Agent 过程展示,增加时间格式化和状态管理

This commit is contained in:
2026-05-13 17:43:06 +08:00
parent 536cd6a5d1
commit a4486e3d89
7 changed files with 249 additions and 41 deletions
@@ -5,13 +5,26 @@ import { AgentProgressTimeline } from "./AgentProgressTimeline";
import type { ChatProgress } from "./GlobalChatbox.types";
describe("AgentProgressTimeline", () => {
beforeEach(() => {
jest.useFakeTimers();
jest.setSystemTime(new Date("2026-01-01T00:00:00.000Z"));
});
afterEach(() => {
jest.useRealTimers();
});
it("shows the running step and keeps the timeline expanded while running", () => {
const now = Date.now();
const progress: ChatProgress[] = [
{
id: "start",
phase: "start",
status: "completed",
status: "running",
title: "收到请求",
startedAt: now - 5000,
elapsedMs: 5000,
elapsedSnapshotAt: now,
},
{
id: "tool",
@@ -19,42 +32,79 @@ describe("AgentProgressTimeline", () => {
status: "running",
title: "正在调用 dynamic_http_call",
detail: "GET /api/v1/network/bottlenecks",
startedAt: now - 1200,
elapsedMs: 1200,
elapsedSnapshotAt: now,
},
];
render(<AgentProgressTimeline progress={progress} />);
expect(screen.getByText("Agent 过程")).toBeInTheDocument();
expect(screen.getByText("正在调用 dynamic_http_call")).toBeInTheDocument();
expect(screen.getByText(/Agent 过程:/)).toBeInTheDocument();
expect(screen.getByText(/耗时 5.0s/)).toBeInTheDocument();
expect(screen.getByText("查询后端数据")).toBeInTheDocument();
expect(screen.getByText("GET /api/v1/network/bottlenecks")).toBeInTheDocument();
expect(screen.getByText("1.2s")).toBeInTheDocument();
});
it("summarizes completed steps and lets users expand details", async () => {
const progress: ChatProgress[] = [
{ id: "start", phase: "start", status: "completed", title: "收到请求" },
{ id: "done", phase: "complete", status: "completed", title: "分析完成" },
{
id: "request-received",
phase: "start",
status: "completed",
title: "收到请求",
startedAt: Date.now() - 8000,
endedAt: Date.now(),
durationMs: 8000,
},
{
id: "done",
phase: "complete",
status: "completed",
title: "分析完成",
startedAt: Date.now() - 1000,
endedAt: Date.now(),
durationMs: 1000,
},
];
render(<AgentProgressTimeline progress={progress} />);
expect(screen.getByText("已完成 2 步")).toBeInTheDocument();
expect(screen.getByText(/已完成 \(2 步\)/)).toBeInTheDocument();
expect(screen.getByText(/耗时 8.0s/)).toBeInTheDocument();
expect(screen.queryByText("分析完成")).not.toBeVisible();
fireEvent.click(screen.getByRole("button", { name: "展开" }));
fireEvent.click(screen.getByText(/Agent 过程:/));
expect(screen.getByText("分析完成")).toBeVisible();
});
it("treats stale running steps as finished after a complete event", () => {
const progress: ChatProgress[] = [
{ id: "tool", phase: "tool", status: "running", title: "正在调用 dynamic_http_call" },
{ id: "done", phase: "complete", status: "completed", title: "分析完成" },
{
id: "tool",
phase: "tool",
status: "completed",
title: "正在调用 dynamic_http_call",
startedAt: Date.now() - 4000,
endedAt: Date.now(),
},
{
id: "done",
phase: "complete",
status: "completed",
title: "分析完成",
startedAt: Date.now() - 500,
endedAt: Date.now(),
durationMs: 500,
},
];
render(<AgentProgressTimeline progress={progress} />);
expect(screen.getByText("已完成 2 步")).toBeInTheDocument();
expect(screen.getByText(/已完成 \(2 步\)/)).toBeInTheDocument();
expect(screen.getByText("4.0s")).toBeInTheDocument();
expect(screen.queryByRole("progressbar")).not.toBeInTheDocument();
});
});