feat(m1-08): stream safe execution summaries
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { ExecutionProgressState } from "./execution-progress-state";
|
||||
|
||||
const T0 = "2026-08-03T00:00:00.000Z";
|
||||
const T1 = "2026-08-03T00:00:18.000Z";
|
||||
|
||||
describe("ExecutionProgressState", () => {
|
||||
it("starts a turn with no invented operation steps", () => {
|
||||
const state = new ExecutionProgressState();
|
||||
expect(state.begin("exec_001", T0)).toEqual(expect.objectContaining({ id: "exec_001", status: "running", steps: [] }));
|
||||
});
|
||||
|
||||
it("only accepts bounded, canonical execution steps for the matching turn", () => {
|
||||
const state = new ExecutionProgressState();
|
||||
state.begin("exec_001", T0);
|
||||
expect(state.applyTrace("exec_other", "completed", [], T1)).toBeUndefined();
|
||||
const summary = state.applyTrace("exec_001", "completed", [{ id: "step_01", title: "检查 qmtbridge health", status: "completed" }], T1);
|
||||
expect(summary).toEqual(expect.objectContaining({ status: "completed", steps: [{ id: "step_01", title: "检查 qmtbridge health", status: "completed" }] }));
|
||||
});
|
||||
|
||||
it("updates a real running step in place before the turn ends", () => {
|
||||
const state = new ExecutionProgressState();
|
||||
state.begin("exec_001", T0);
|
||||
expect(state.applyTrace("exec_001", "running", [{ id: "step_01", title: "查询公开资料", status: "running" }], T1))
|
||||
.toEqual(expect.objectContaining({ status: "running", finished_at: undefined, steps: [{ id: "step_01", title: "查询公开资料", status: "running" }] }));
|
||||
expect(state.applyTrace("exec_001", "completed", [{ id: "step_01", title: "查询公开资料", status: "completed" }], T1))
|
||||
.toEqual(expect.objectContaining({ status: "completed", finished_at: T1 }));
|
||||
});
|
||||
|
||||
it("finishes without a trace without fabricating a fixed lifecycle", () => {
|
||||
const state = new ExecutionProgressState();
|
||||
state.begin("exec_001", T0);
|
||||
expect(state.finishActive("completed", T1)).toEqual(expect.objectContaining({ steps: [] }));
|
||||
});
|
||||
|
||||
it("keeps overlapping execution ids independent and finishes only the matching turn", () => {
|
||||
const state = new ExecutionProgressState();
|
||||
state.begin("exec_001", T0);
|
||||
state.begin("exec_002", T1);
|
||||
state.finish("exec_002", "completed", T1);
|
||||
expect(state.snapshot()).toEqual([
|
||||
expect.objectContaining({ id: "exec_001", status: "running" }),
|
||||
expect.objectContaining({ id: "exec_002", status: "completed" }),
|
||||
]);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user