import { describe, expect, it } from "vitest"; import { applyChecklistToolEvent, 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([ { id: undefined, content: "搜题", status: "completed", activeForm: "正在搜题" }, { id: undefined, content: "写报告", status: "in_progress", activeForm: "正在写报告" }, { id: undefined, content: "发卡片", status: "pending", activeForm: undefined }, ]); expect(todoProgressSummary(todos!)).toEqual({ completed: 1, total: 3, inProgress: 1 }); }); it("folds TaskCreate + TaskUpdate into a checklist", () => { let todos = applyChecklistToolEvent([], { toolName: "TaskCreate", input: { subject: "说你好", description: "greet" }, result: "Task #1 created successfully: 说你好", }); expect(todos).toEqual([ { id: "1", content: "说你好", status: "pending", activeForm: undefined }, ]); todos = applyChecklistToolEvent(todos!, { toolName: "TaskCreate_1", input: { subject: "算 1+1", description: "math" }, result: "Task #2 created successfully: 算 1+1", }); todos = applyChecklistToolEvent(todos!, { toolName: "TaskUpdate", input: { taskId: "1", status: "in_progress", activeForm: "正在问好" }, result: "Updated task #1 status", }); todos = applyChecklistToolEvent(todos!, { toolName: "TaskUpdate_4", input: { taskId: "1", status: "completed" }, result: "Updated task #1 status", }); todos = applyChecklistToolEvent(todos!, { toolName: "TaskUpdate", input: { taskId: "2", status: "completed" }, result: "Updated task #2 status", }); expect(todos).toEqual([ { id: "1", content: "说你好", status: "completed", activeForm: "正在问好" }, { id: "2", content: "算 1+1", status: "completed", activeForm: undefined }, ]); expect(todoProgressSummary(todos!)).toEqual({ completed: 2, total: 2, inProgress: 0 }); }); it("recognizes TodoWrite tool names", () => { expect(isTodoWriteTool("TodoWrite")).toBe(true); expect(isTodoWriteTool("mcp__cph_hub__todo_write")).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: [ { id: "1", content: "A", status: "completed", activeForm: undefined }, { id: "2", content: "B", status: "in_progress", activeForm: "Doing B" }, { id: "3", content: "C", status: "pending", activeForm: undefined }, ], toolUseSteps: [ { id: "1", seq: 1, toolName: "TaskCreate", 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"); // TaskCreate noise filtered when checklist present (no separate tool panel if only Task*) expect(json).not.toContain("TaskCreate"); }); });