fix: prioritize terminal checkpoint status

This commit is contained in:
lyon
2026-06-21 03:21:09 +08:00
parent 4ce6b2db1b
commit 0d861d03ec
+15 -7
View File
@@ -505,7 +505,11 @@ function factSessionSummary(session, facts = {}) {
const messages = factMessagesForSession(session, facts);
const traceStatus = normalizeTerminalStatus(trace?.status);
const checkpointStatus = normalizeTerminalStatus(checkpoint?.status);
const status = normalizeStatus(turn?.status ?? checkpointStatus ?? traceStatus ?? session?.status);
const turnStatus = normalizeStatus(turn?.status);
// Terminal checkpoint/trace evidence is the turn lifecycle authority. A
// stale running turn row must not keep the visible timer running after the
// terminal event has already been projected.
const status = normalizeStatus(checkpointStatus ?? traceStatus ?? turnStatus ?? session?.status);
const timingSource = checkpoint ?? (traceId ? null : session);
const timing = factTimingProjection(timingSource, status);
return {
@@ -528,9 +532,9 @@ function factSessionSummary(session, facts = {}) {
turnSummary: turn ? {
turnId: factTurnId(turn, traceId),
traceId,
status: normalizeStatus(turn.status ?? status),
running: RUNNING_STATUSES.has(normalizeStatus(turn.status ?? status)),
terminal: TERMINAL_STATUSES.has(normalizeStatus(turn.status ?? status)) && !RUNNING_STATUSES.has(normalizeStatus(turn.status ?? status)),
status,
running: RUNNING_STATUSES.has(status),
terminal: TERMINAL_STATUSES.has(status) && !RUNNING_STATUSES.has(status),
eventCount: projection?.lastProjectedSeq ?? trace?.eventCount,
projection,
projectionStatus: projection?.projectionStatus ?? null,
@@ -587,10 +591,12 @@ function factMessageDto(message, parts = [], facts = {}) {
if (!messageId) return null;
const traceId = safeTraceId(message?.traceId) ?? null;
const role = textValue(message?.role) || "agent";
const status = normalizeStatus(message?.status);
const turn = traceId ? factTurnForTrace(facts, traceId) : null;
const checkpoint = traceId ? factCheckpointForTrace(facts, traceId) : null;
const timing = factTimingProjection(isAssistantLikeRole(role) ? turn ?? checkpoint ?? message : message, status);
const messageStatus = normalizeStatus(message?.status);
const checkpointStatus = isAssistantLikeRole(role) ? normalizeTerminalStatus(checkpoint?.status) : null;
const status = normalizeStatus(checkpointStatus ?? (isAssistantLikeRole(role) ? turn?.status : null) ?? messageStatus);
const timing = factTimingProjection(isAssistantLikeRole(role) ? checkpoint ?? turn ?? message : message, status);
const text = projectionText(message?.text, message?.content, message?.message, message?.finalResponse);
const normalizedParts = parts.length > 0
? [...parts].sort(compareFactPartsAsc).map((part) => factPartDto(part, messageId, traceId)).filter(Boolean)
@@ -652,7 +658,9 @@ function factTurnSnapshot({ turn = null, session = null, facts = {}, traceId, tu
const assistantMessage = [...messages].reverse().find((message) => isAssistantLikeRole(message.role)) ?? null;
const checkpoint = safeTrace ? factCheckpointForTrace(facts, safeTrace) : null;
const trace = factTraceSnapshot(facts, safeTrace);
const status = normalizeStatus(turn?.status ?? normalizeTerminalStatus(checkpoint?.status) ?? normalizeTerminalStatus(trace.status) ?? session?.status);
const checkpointStatus = normalizeTerminalStatus(checkpoint?.status);
const traceStatus = normalizeTerminalStatus(trace.status);
const status = normalizeStatus(checkpointStatus ?? traceStatus ?? turn?.status ?? session?.status);
const finalText = projectionText(turn?.finalResponse, turn?.assistantText, turn?.text, assistantMessage?.text);
const timing = factTimingProjection(checkpoint, status);
return {