diff --git a/internal/cloud/workbench-projection-writer.ts b/internal/cloud/workbench-projection-writer.ts index 4744dd3f..35cde634 100644 --- a/internal/cloud/workbench-projection-writer.ts +++ b/internal/cloud/workbench-projection-writer.ts @@ -110,13 +110,14 @@ export async function writeWorkbenchProjectionEvent({ runtimeStore = null, event if (!traceId) return null; const projectedAt = new Date().toISOString(); const sourceSeq = nonNegativeInteger(event.sourceSeq ?? event.seq); - const occurredAt = timestampValue(event.createdAt ?? event.occurredAt ?? event.updatedAt ?? projectedAt); const sessionId = textValue(event.sessionId ?? requestMeta.sessionId) || null; const turnId = textValue(event.turnId) || traceId; const terminal = event.terminal === true || TERMINAL_STATUSES.has(normalizeWorkbenchStatus(event.status)); const status = terminal ? normalizeWorkbenchStatus(event.status) : "running"; const previousCheckpoint = await latestWorkbenchCheckpoint(runtimeStore, traceId); const previousTiming = normalizeTimingProjection(previousCheckpoint?.timing) ?? normalizeTimingProjection(previousCheckpoint); + const sourceOccurredAt = timestampValue(event.createdAt ?? event.occurredAt ?? event.updatedAt ?? projectedAt); + const occurredAt = latestTimestamp(previousTiming?.lastEventAt, sourceOccurredAt) ?? sourceOccurredAt; const previousTerminal = checkpointIsTerminal(previousCheckpoint); const suppressedAfterSeal = previousTerminal && !terminal; const explicitEventTiming = normalizeTimingProjection(event.timing) ?? normalizeTimingProjection(event); @@ -222,6 +223,8 @@ export async function writeWorkbenchProjectionEvent({ runtimeStore = null, event finishedAt: eventTiming?.finishedAt ?? null, durationMs: eventTiming?.durationMs ?? null, suppressedAfterSeal, + sourceOccurredAt: sourceOccurredAt !== occurredAt ? sourceOccurredAt : null, + createdAt: occurredAt, occurredAt, updatedAt: projectedAt }],