diff --git a/packages/ui/src/hooks/useAssistantStatus.ts b/packages/ui/src/hooks/useAssistantStatus.ts index a952fa02..cf3c217e 100644 --- a/packages/ui/src/hooks/useAssistantStatus.ts +++ b/packages/ui/src/hooks/useAssistantStatus.ts @@ -198,28 +198,29 @@ export function useAssistantStatus(): AssistantStatusSnapshot { return { activePartType: undefined, activeToolName: undefined, statusText: 'working', isGenericStatus: true }; } - const assistantMessages = sessionMessages - .filter( - (msg): msg is AssistantSessionMessageRecord => - isAssistantMessage(msg.info) && !isFullySyntheticMessage(msg.parts) - ); + // Pick the latest assistant message by created-time (tiebreak by id) in a + // single pass — sync reconciliation can splice messages out of array order. + const isLater = (a: AssistantSessionMessageRecord, b: AssistantSessionMessageRecord) => { + const aTime = typeof a.info.time?.created === 'number' ? a.info.time.created : null; + const bTime = typeof b.info.time?.created === 'number' ? b.info.time.created : null; + if (aTime !== null && bTime !== null && aTime !== bTime) return aTime > bTime; + return a.info.id.localeCompare(b.info.id) > 0; + }; - if (assistantMessages.length === 0) { - return { activePartType: undefined, activeToolName: undefined, statusText: 'working', isGenericStatus: true }; + let lastAssistant: AssistantSessionMessageRecord | null = null; + for (const candidate of sessionMessages) { + if (!isAssistantMessage(candidate.info) || isFullySyntheticMessage(candidate.parts)) { + continue; + } + const typed = candidate as AssistantSessionMessageRecord; + if (lastAssistant === null || isLater(typed, lastAssistant)) { + lastAssistant = typed; + } } - const sortedAssistantMessages = [...assistantMessages].sort((a, b) => { - const aCreated = typeof a.info.time?.created === 'number' ? a.info.time.created : null; - const bCreated = typeof b.info.time?.created === 'number' ? b.info.time.created : null; - - if (aCreated !== null && bCreated !== null && aCreated !== bCreated) { - return aCreated - bCreated; - } - - return a.info.id.localeCompare(b.info.id); - }); - - const lastAssistant = sortedAssistantMessages[sortedAssistantMessages.length - 1]; + if (!lastAssistant) { + return { activePartType: undefined, activeToolName: undefined, statusText: 'working', isGenericStatus: true }; + } let activePartType: 'text' | 'tool' | 'reasoning' | 'editing' | undefined = undefined; let activeToolName: string | undefined = undefined;