fix(agent): derive activity stages from tool actions
Generic Container CI/CD / test-build-publish (push) Successful in 2m24s
Agent CI/CD v2 / build-test-publish-and-deploy (push) Successful in 2m24s

This commit is contained in:
2026-09-25 16:23:00 +08:00
parent 54d8feca14
commit 4744f1f20a
2 changed files with 152 additions and 7 deletions
+64
View File
@@ -1,8 +1,72 @@
import { describe, expect, it } from "bun:test";
import { createActivityTracker } from "../../src/routes/chatActivityTracker.js";
import { initialActivity } from "../../src/routes/chatStreamEvents.js";
describe("createActivityTracker", () => {
it("moves real tool work out of preparation when the model omits activity updates", () => {
const events: Array<{ event: string; data: Record<string, unknown> }> = [];
const tracker = createActivityTracker({
clientSessionId: "client-session-1",
write: (event, data) => events.push({ event, data }),
});
const action = (id: string, tool: string, status: string) =>
tracker.upsertAction(
{ id, tool, state: { status, input: {} } } as never,
{},
);
tracker.start(initialActivity.id, initialActivity.title, initialActivity.reason);
action("skill-1", "skill", "completed");
action("read-1", "read", "completed");
action("data-1", "tjwater_cli", "completed");
action("data-1", "tjwater_cli", "completed");
action("compute-1", "bash", "completed");
action("map-1", "show_chart", "completed");
tracker.finalize("completed");
const started = events
.filter(({ data }) =>
(data.activity as { actions: unknown[] }).actions.length === 0 &&
(data.activity as { status: string }).status === "running",
)
.map(({ data }) => (data.activity as { title: string }).title);
expect(started).toEqual([
initialActivity.title,
"查找所需资料",
"获取业务数据",
"处理分析数据",
"更新地图与图表",
]);
expect(tracker.getActionContext("read-1")?.title).toBe("查找所需资料");
expect(tracker.getActionContext("data-1")?.title).toBe("获取业务数据");
expect(tracker.getActionContext("map-1")?.title).toBe("更新地图与图表");
});
it("keeps a model-provided stage across tool categories", () => {
const events: Array<{ event: string; data: Record<string, unknown> }> = [];
const tracker = createActivityTracker({
clientSessionId: "client-session-1",
write: (event, data) => events.push({ event, data }),
});
tracker.start(initialActivity.id, initialActivity.title, initialActivity.reason);
tracker.start("model-stage", "验证分析结果", "核对本次计算与数据。");
for (const [id, tool] of [["tool-1", "tjwater_cli"], ["tool-2", "show_chart"]]) {
tracker.upsertAction(
{ id, tool, state: { status: "completed", input: {} } } as never,
{},
);
}
expect(tracker.getActionContext("tool-1")?.title).toBe("验证分析结果");
expect(tracker.getActionContext("tool-2")?.title).toBe("验证分析结果");
expect(
events.filter(({ data }) =>
(data.activity as { actions: unknown[] }).actions.length === 0 &&
(data.activity as { status: string }).status === "running",
),
).toHaveLength(2);
});
it("groups actions and closes running children with their activity", () => {
const events: Array<{ event: string; data: Record<string, unknown> }> = [];
const tracker = createActivityTracker({