fix(workbench): preserve message timing authority (#1984)
Co-authored-by: root <root@lyon.remote>
This commit is contained in:
@@ -1810,36 +1810,13 @@ function messageTimingPatch(value: unknown): Partial<ChatMessage> {
|
||||
}
|
||||
|
||||
function messageTimingPatchForMerge(message: ChatMessage, value: unknown): Partial<ChatMessage> {
|
||||
const patch = messageTimingPatch(value);
|
||||
if (!patch.timing) return patch;
|
||||
const terminal = timingPatchIsTerminal(value, patch.timing);
|
||||
const durationMs = terminal
|
||||
? terminalTimingDurationMsForMerge(message, patch.timing)
|
||||
: maxFiniteNumber(patch.timing.durationMs, message.durationMs, message.timing?.durationMs, message.runnerTrace?.durationMs, message.runnerTrace?.timing?.durationMs);
|
||||
const timing = { ...patch.timing, durationMs } as WorkbenchTurnTimingProjection;
|
||||
return { timing, startedAt: timing.startedAt ?? null, lastEventAt: timing.lastEventAt ?? null, finishedAt: timing.finishedAt ?? null, durationMs };
|
||||
}
|
||||
|
||||
function terminalTimingDurationMsForMerge(message: ChatMessage, timing: WorkbenchTurnTimingProjection): number | null {
|
||||
const elapsed = elapsedTimingDurationMs(timing);
|
||||
const maximum = maxFiniteNumber(timing.durationMs, elapsed, message.durationMs, message.timing?.durationMs, message.runnerTrace?.durationMs, message.runnerTrace?.timing?.durationMs);
|
||||
if (maximum !== null) return maximum;
|
||||
return firstFiniteNumber(timing.durationMs, elapsed, message.durationMs, message.timing?.durationMs, message.runnerTrace?.durationMs, message.runnerTrace?.timing?.durationMs);
|
||||
}
|
||||
|
||||
function timingPatchIsTerminal(value: unknown, timing: WorkbenchTurnTimingProjection): boolean {
|
||||
const record = recordValue(value);
|
||||
const trace = recordValue(record?.runnerTrace);
|
||||
const status = normalizedStatusText(record?.status ?? record?.traceStatus ?? trace?.status ?? trace?.traceStatus);
|
||||
return Boolean(timing.finishedAt || isTerminalMessageStatus(status));
|
||||
}
|
||||
|
||||
function elapsedTimingDurationMs(timing: WorkbenchTurnTimingProjection): number | null {
|
||||
const start = timing.startedAt ? Date.parse(timing.startedAt) : NaN;
|
||||
const endedAt = timing.finishedAt ?? timing.lastEventAt;
|
||||
const end = endedAt ? Date.parse(endedAt) : NaN;
|
||||
if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return null;
|
||||
return Math.trunc(end - start);
|
||||
void value;
|
||||
// Trace/result hydration may update runnerTrace and TraceTimeline, but the
|
||||
// main Code Agent card timing is a durable message projection field. Do not
|
||||
// let trace snapshots or terminal result polling rewrite message.timing;
|
||||
// otherwise visible card elapsed can jump or diverge from the sealed message
|
||||
// projection when trace rows arrive out of order.
|
||||
return messageTimingPatch(message);
|
||||
}
|
||||
|
||||
function firstPositiveFiniteNumber(...values: unknown[]): number | null {
|
||||
|
||||
Reference in New Issue
Block a user