fix(workbench): keep turn last event timing latest (#2019)

This commit is contained in:
Lyon
2026-06-24 05:53:43 +08:00
committed by GitHub
parent 0b4cec3bb6
commit a7e4de6910
2 changed files with 41 additions and 1 deletions
@@ -58,6 +58,36 @@ test("workbench projection diagnostics keeps projecting health distinct from cau
assert.equal(diagnostics.projectionHealth, "projecting");
});
test("workbench turn projection keeps lastEventAt on the latest event instead of stale admission timing (#1889)", () => {
const traceId = "trc_turn_timing_latest_event";
const result = {
traceId,
status: "running",
startedAt: "2026-06-23T21:43:48.740Z",
lastEventAt: "2026-06-23T21:43:48.740Z",
timing: {
startedAt: "2026-06-23T21:43:48.740Z",
lastEventAt: "2026-06-23T21:43:48.740Z",
durationMs: null
}
};
const trace = {
traceId,
status: "running",
updatedAt: "2026-06-23T21:44:33.486Z",
lastEventAt: "2026-06-23T21:44:31.000Z",
events: [
{ seq: 1, type: "admitted", createdAt: "2026-06-23T21:43:48.740Z" },
{ seq: 2, type: "commandExecution", status: "completed", updatedAt: "2026-06-23T21:44:31.000Z" }
],
eventCount: 2
};
const projection = createWorkbenchTurnProjection({ traceId, result, trace });
assert.equal(projection.startedAt, "2026-06-23T21:43:48.740Z");
assert.equal(projection.lastEventAt, "2026-06-23T21:44:33.486Z");
assert.equal(projection.timing.lastEventAt, "2026-06-23T21:44:33.486Z");
});
test("workbench turn projection treats retryable provider stream disconnect as active", () => {
const traceId = "trc_retryable_provider_stream_disconnect";
const result = {
+11 -1
View File
@@ -67,7 +67,7 @@ export function createWorkbenchTurnTimingProjection({ result = null, session = n
firstEvent?.createdAt,
firstEvent?.occurredAt
);
const lastEventAt = firstTimestamp(
const lastEventAt = latestTimestamp(
result?.lastEventAt,
directTiming?.lastEventAt,
trace?.lastEventAt,
@@ -382,6 +382,16 @@ function firstTimestamp(...values) {
return null;
}
function latestTimestamp(...values) {
let latest = null;
for (const value of values) {
const ms = Date.parse(String(value ?? ""));
if (!Number.isFinite(ms)) continue;
latest = latest === null ? ms : Math.max(latest, ms);
}
return latest === null ? null : new Date(latest).toISOString();
}
function durationValue(...values) {
let max = null;
for (const value of values) {