Files
pikasTech-HWLAB/internal/cloud/workbench-projection-cursor.test.ts
T

112 lines
3.7 KiB
TypeScript

// SPEC: PJ2026-0104010803 Workbench唯一投影 draft-2026-06-19-p1-agentrun-incremental-cursor.
// Responsibility: Independent backend unit tests for AgentRun projection cursor planning.
import assert from "node:assert/strict";
import { test } from "bun:test";
import { buildAgentRunProjectionEventsFetchPlan, buildWorkbenchProjectionStateUpdate } from "./workbench-projection-cursor.ts";
test("AgentRun projection fetch plan uses durable cursor without scanning long trace", () => {
const poisonTrace = {};
Object.defineProperty(poisonTrace, "events", {
get() {
throw new Error("trace events must not be read to compute AgentRun afterSeq");
}
});
const poisonResult = {};
Object.defineProperty(poisonResult, "events", {
get() {
throw new Error("result events must not be read to compute AgentRun afterSeq");
}
});
const plan = buildAgentRunProjectionEventsFetchPlan({
projectionState: {
traceId: "trc_cursor_o1",
sourceRunId: "run_cursor_o1",
sourceCommandId: "cmd_cursor_o1",
lastSourceSeq: 3700,
lastProjectedSeq: 129
},
agentRun: {
runId: "run_cursor_o1",
commandId: "cmd_cursor_o1",
lastSeq: 12
},
trace: poisonTrace,
result: poisonResult,
pageLimit: 500
});
assert.equal(plan.runId, "run_cursor_o1");
assert.equal(plan.commandId, "cmd_cursor_o1");
assert.equal(plan.afterSeq, 3700);
assert.equal(plan.limit, 500);
assert.equal(plan.cursorSource, "projection-state");
});
test("AgentRun projection state advances from incremental events response", () => {
const state = buildWorkbenchProjectionStateUpdate({
currentState: {
traceId: "trc_cursor_update",
sourceRunId: "run_cursor_update",
sourceCommandId: "cmd_cursor_update",
lastSourceSeq: 3700,
lastProjectedSeq: 3700,
sourceLatestSeq: 3700,
projectionStatus: "projecting",
resultSyncState: "not_started",
createdAt: "2026-06-19T12:00:00.000Z"
},
agentRun: {
runId: "run_cursor_update",
commandId: "cmd_cursor_update",
lastSeq: 3700
},
eventsResponse: {
traceLastSeq: 3720,
maxSeq: 3721,
rawEventCount: 20
},
now: () => "2026-06-19T12:01:00.000Z"
});
assert.equal(state.lastSourceSeq, 3720);
assert.equal(state.lastAgentRunSeq, 3720);
assert.equal(state.lastProjectedSeq, 3720);
assert.equal(state.sourceLatestSeq, 3721);
assert.equal(state.projectionStatus, "projecting");
assert.equal(state.resultSyncState, "not_started");
assert.equal(state.createdAt, "2026-06-19T12:00:00.000Z");
assert.equal(state.updatedAt, "2026-06-19T12:01:00.000Z");
});
test("AgentRun projection state preserves retry params for background resume", () => {
const state = buildWorkbenchProjectionStateUpdate({
currentState: {
traceId: "trc_cursor_retry_params",
sourceRunId: "run_cursor_retry_params",
sourceCommandId: "cmd_cursor_retry_params",
retryParams: {
message: "preserve this prompt for fresh-session retry",
sessionId: "ses_cursor_retry",
providerProfile: "dsflash-go",
valuesPrinted: false
},
createdAt: "2026-06-19T12:00:00.000Z"
},
agentRun: {
runId: "run_cursor_retry_params",
commandId: "cmd_cursor_retry_params",
lastSeq: 3
},
now: () => "2026-06-19T12:01:00.000Z"
});
assert.equal(state.retryParams.message, "preserve this prompt for fresh-session retry");
assert.equal(state.retryParams.prompt, "preserve this prompt for fresh-session retry");
assert.equal(state.retryParams.sessionId, "ses_cursor_retry");
assert.equal(state.retryParams.providerProfile, "dsflash-go");
assert.equal(state.retryParams.valuesPrinted, false);
});