import { describe, expect, it } from "vitest"; import { isTodoWriteTool, parseTodoWriteInput, todoProgressSummary, } from "../../src/agent/todoList.js"; import { buildAgentCard } from "../../src/feishu/card/builder.js"; describe("todo list parse", () => { it("accepts TodoWrite payloads", () => { const todos = parseTodoWriteInput({ todos: [ { content: "搜题", status: "completed", activeForm: "正在搜题" }, { content: "写报告", status: "in_progress", activeForm: "正在写报告" }, { content: "发卡片", status: "pending" }, ], }); expect(todos).toEqual([ { content: "搜题", status: "completed", activeForm: "正在搜题" }, { content: "写报告", status: "in_progress", activeForm: "正在写报告" }, { content: "发卡片", status: "pending", activeForm: undefined }, ]); expect(todoProgressSummary(todos!)).toEqual({ completed: 1, total: 3, inProgress: 1 }); }); it("rejects empty or invalid bodies", () => { expect(parseTodoWriteInput(null)).toBeNull(); expect(parseTodoWriteInput({ todos: [] })).toBeNull(); expect(parseTodoWriteInput({ todos: [{ status: "pending" }] })).toBeNull(); }); it("recognizes TodoWrite tool names", () => { expect(isTodoWriteTool("TodoWrite")).toBe(true); expect(isTodoWriteTool("Bash")).toBe(false); }); }); describe("agent card todo panel", () => { it("renders a progress checklist when todos are present", () => { const card = buildAgentCard({ phase: "streaming", text: "", reasoningText: undefined, todos: [ { content: "A", status: "completed", activeForm: undefined }, { content: "B", status: "in_progress", activeForm: "Doing B" }, { content: "C", status: "pending", activeForm: undefined }, ], toolUseSteps: [ { id: "1", seq: 1, toolName: "TodoWrite", toolUseId: "t1", input: {}, result: undefined, error: undefined, status: "success", startedAt: 0, finishedAt: 1, durationMs: 1, }, ], toolUseElapsedMs: 10, isError: undefined, interrupted: undefined, runId: "run-1", }); const json = JSON.stringify(card); expect(json).toContain("任务进度 1/3"); expect(json).toContain("Doing B"); expect(json).toContain("collapsible_panel"); }); });