fix(agent): align investigation waits and interruption messages
Separate waiting-stage reports from final recovery closure and route resumed runs through the actual handling phase. Keep superseded runs distinct from expired leases and transport failures, with focused heartbeat response coverage.
This commit is contained in:
@@ -5,6 +5,8 @@ import {
|
||||
humanTaskEvidenceCommandSchema,
|
||||
hasOperationalTaskRun,
|
||||
OperationalTaskClient,
|
||||
OperationalTaskClientError,
|
||||
taskRunInterruptionMessage,
|
||||
proposedTaskActionSchema,
|
||||
releaseOperationalTaskCredential,
|
||||
} from "../../src/product/operational-task-client.js";
|
||||
@@ -53,6 +55,32 @@ afterEach(() => {
|
||||
releaseOperationalTaskCredential("runtime-1");
|
||||
});
|
||||
|
||||
it.each([
|
||||
["RUN_SUPERSEDED", "任务已收到更新,本轮执行已停止,由新一轮执行接续。"],
|
||||
["LEASE_EXPIRED", "工况任务租约已失效,本次执行已停止,等待任务重新领取。"],
|
||||
["VERSION_CONFLICT", "工况任务心跳校验失败,本次执行已停止,请检查任务状态或服务连接。"],
|
||||
] as const)("distinguishes heartbeat interruption %s from lease expiry", async (code, message) => {
|
||||
let calls = 0;
|
||||
globalThis.fetch = (async () => ++calls === 1 ? Response.json(run)
|
||||
: Response.json({ code, detail: "Server rejected heartbeat" }, { status: 409 })) as unknown as typeof fetch;
|
||||
bindOperationalTaskCredential("runtime-1", { authorization: "Bearer test-only", projectId: "project-1" });
|
||||
const client = new OperationalTaskClient("http://server.test");
|
||||
await client.claimTask("runtime-1", taskId, runId, {
|
||||
requestId: crypto.randomUUID(), expectedRevision: 1, sourceSessionId: "session-1",
|
||||
});
|
||||
let caught: Error | undefined;
|
||||
try { await client.heartbeatTask("runtime-1", taskId, runId, "session-1"); }
|
||||
catch (error) { caught = error as Error; }
|
||||
expect(caught).toBeInstanceOf(OperationalTaskClientError);
|
||||
expect(caught).toMatchObject({ code, status: 409 });
|
||||
expect(taskRunInterruptionMessage(caught!)).toBe(message);
|
||||
});
|
||||
|
||||
it("does not describe a network heartbeat failure as lease expiry", () => {
|
||||
expect(taskRunInterruptionMessage(new Error("fetch failed")))
|
||||
.toBe("工况任务心跳校验失败,本次执行已停止,请检查任务状态或服务连接。");
|
||||
});
|
||||
|
||||
describe("OperationalTaskClient", () => {
|
||||
it("requests a selected report while retaining the current task snapshot", async () => {
|
||||
let requestedUrl = "";
|
||||
|
||||
@@ -12,7 +12,8 @@ describe("supply Agent identity", () => {
|
||||
);
|
||||
|
||||
expect(instruction).toContain("TJWater 实验性供水数据 Agent");
|
||||
expect(instruction).toContain("供水事件数据边界");
|
||||
expect(instruction).toContain("公共指令规定数据与权限边界");
|
||||
expect(instruction).toContain("Server 访问、路由及凭据由宿主管理");
|
||||
expect(instruction).not.toContain("source/");
|
||||
expect(instruction).not.toContain("排水");
|
||||
expect(instruction).not.toContain("雨污混接");
|
||||
|
||||
Reference in New Issue
Block a user