Files
pikasTech-HWLAB/internal/cloud/workbench-projection-cursor.test.ts
T
2026-06-30 14:05:17 +08:00

154 lines
5.3 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);
});
test("AgentRun projection state resets source cursor when fresh retry switches run", () => {
const state = buildWorkbenchProjectionStateUpdate({
currentState: {
traceId: "trc_cursor_fresh_retry",
sourceRunId: "run_cursor_failed",
sourceCommandId: "cmd_cursor_failed",
lastSourceSeq: 3700,
lastAgentRunSeq: 3700,
lastProjectedSeq: 3700,
sourceLatestSeq: 3700,
projectionStatus: "terminal",
resultSyncState: "pending",
retryParams: {
message: "retry on a fresh AgentRun session",
sessionId: "ses_cursor_fresh_retry",
providerProfile: "dsflash-go",
valuesPrinted: false
},
createdAt: "2026-06-19T12:00:00.000Z"
},
agentRun: {
runId: "run_cursor_fresh_retry",
commandId: "cmd_cursor_fresh_retry",
lastSeq: 0
},
projectionStatus: "projecting",
resultSyncState: null,
now: () => "2026-06-19T12:02:00.000Z"
});
assert.equal(state.sourceRunId, "run_cursor_fresh_retry");
assert.equal(state.sourceCommandId, "cmd_cursor_fresh_retry");
assert.equal(state.lastSourceSeq, 0);
assert.equal(state.lastAgentRunSeq, 0);
assert.equal(state.lastProjectedSeq, 0);
assert.equal(state.sourceLatestSeq, 0);
assert.equal(state.projectionStatus, "projecting");
assert.equal(state.retryParams.message, "retry on a fresh AgentRun session");
const plan = buildAgentRunProjectionEventsFetchPlan({ projectionState: state, agentRun: { runId: "run_cursor_fresh_retry", commandId: "cmd_cursor_fresh_retry", lastSeq: 0 } });
assert.equal(plan.afterSeq, 0);
});