perf: reduce status row streaming churn

Replace live assistant-part status subscriptions with coarse session phase, retry, permission, and abort state so the composing row no longer rerenders on every text delta.
This commit is contained in:
Bohdan Triapitsyn
2026-04-05 17:29:14 +03:00
parent c88e68e5f7
commit 3bf9947388
@@ -1,25 +1,71 @@
import React from 'react';
import { useAssistantStatus } from '@/hooks/useAssistantStatus';
import { useCurrentSessionActivity } from '@/hooks/useSessionActivity';
import { useConfigStore } from '@/stores/useConfigStore';
import { useSessionPermissions, useSessionStatus } from '@/sync/sync-context';
import { useSessionUIStore } from '@/sync/session-ui-store';
import { StatusRow } from './StatusRow';
const DEFAULT_WORKING_STATUS = 'working';
/**
* Self-contained wrapper — subscribes to assistant status internally
* so MessageList doesn't re-render on every streaming part delta.
* Coarse status wrapper.
* Avoids subscribing to live assistant parts so the row doesn't rerender on every text delta.
*/
export const StatusRowContainer: React.FC = React.memo(() => {
const { working } = useAssistantStatus();
const currentSessionId = useSessionUIStore((state) => state.currentSessionId);
const abortRecord = useSessionUIStore(
React.useCallback((state) => {
if (!currentSessionId) {
return null;
}
return state.sessionAbortFlags?.get(currentSessionId) ?? null;
}, [currentSessionId]),
);
const permissions = useSessionPermissions(currentSessionId ?? '');
const sessionStatus = useSessionStatus(currentSessionId ?? '');
const { phase, isWorking } = useCurrentSessionActivity();
const currentAgentName = useConfigStore((state) => state.currentAgentName);
const wasAborted = Boolean(abortRecord && !abortRecord.acknowledged);
const isWaitingForPermission = permissions.length > 0;
const isRetry = sessionStatus?.type === 'retry';
const statusText = React.useMemo(() => {
if (isWaitingForPermission) {
return 'waiting for permission';
}
if (isRetry) {
return 'retrying';
}
if (!isWorking) {
return null;
}
if (phase === 'busy') {
return 'composing';
}
return DEFAULT_WORKING_STATUS;
}, [isRetry, isWaitingForPermission, isWorking, phase]);
const retryInfo = React.useMemo(() => {
if (!isRetry) {
return null;
}
return {
attempt: (sessionStatus as { attempt?: number } | undefined)?.attempt,
next: (sessionStatus as { next?: number } | undefined)?.next,
};
}, [isRetry, sessionStatus]);
return (
<StatusRow
isWorking={working.isWorking}
statusText={working.statusText}
isGenericStatus={working.isGenericStatus}
isWaitingForPermission={working.isWaitingForPermission}
wasAborted={working.wasAborted}
abortActive={working.abortActive}
retryInfo={working.retryInfo}
isWorking={isWorking}
statusText={statusText}
isGenericStatus={true}
isWaitingForPermission={isWaitingForPermission}
wasAborted={wasAborted}
abortActive={wasAborted}
retryInfo={retryInfo}
showAssistantStatus
showTodos={false}
agentName={currentAgentName}