fix(agent): derive activity stages from tool actions
This commit is contained in:
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user