From 4c66f91c84f79676d3f0a2d12fd614e98ffda8d7 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Tue, 27 Oct 2026 00:34:28 -0700 Subject: [PATCH] perf(native-chat): stop unrelated host status flips from rerendering every chat (#34300) useStructuredAgentSessionOwnPermissionState subscribed to the whole runtimeStatusByEnvironmentId map, so each status publication for any paired host rerendered every mounted chat (including hidden ones). Select the derived capability verdict for the chat's own host instead. Co-authored-by: Claude --- ...t-session-host-capability-scaling.test.tsx | 51 +++++++++++++++++++ ...tructured-agent-session-host-capability.ts | 10 ++-- 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/src/renderer/src/runtime/structured-agent-session-host-capability-scaling.test.tsx b/src/renderer/src/runtime/structured-agent-session-host-capability-scaling.test.tsx index a41dd2bdd0f..ae75125406b 100644 --- a/src/renderer/src/runtime/structured-agent-session-host-capability-scaling.test.tsx +++ b/src/renderer/src/runtime/structured-agent-session-host-capability-scaling.test.tsx @@ -25,6 +25,7 @@ import { AGENT_SESSION_PERMISSION_OWN_RUNTIME_CAPABILITY } from '../../../shared import { createCompatibleRuntimeStatusResponse } from './runtime-compatibility-test-fixture' import { clearRuntimeCompatibilityCacheForTests } from './runtime-rpc-client' import { RuntimeHostStatusOwner } from '../../../shared/runtime-host-status-owner' +import type { RuntimeEnvironmentStatus } from '../../../shared/runtime-host-status' import { useStructuredAgentSessionOwnPermissionState } from './structured-agent-session-host-capability' const owners: RuntimeHostStatusOwner[] = [] @@ -145,3 +146,53 @@ it.each([10, 100])( expect(call).not.toHaveBeenCalled() } ) + +it('does not rerender local or other-host consumers when an unrelated host status changes', () => { + const unrelated = createCompatibleRuntimeStatusResponse('other') + const own = createCompatibleRuntimeStatusResponse('host') + if (!unrelated.ok || !own.ok) { + throw new Error('expected successful fixture') + } + const statuses = (otherStatus: typeof unrelated.result | null) => + new Map([ + ['host', { status: own.result, checkedAt: 1 }], + ['other', { status: otherStatus, checkedAt: 1 }] + ]) + useAppStore.setState({ runtimeStatusByEnvironmentId: statuses(null) }) + let renders = 0 + const targets = [{ kind: 'local' }, { kind: 'environment', environmentId: 'host' }] as const + const views = targets.map((target) => + renderHook(() => { + renders += 1 + return useStructuredAgentSessionOwnPermissionState(target) + }) + ) + const before = renders + for (let flip = 0; flip < 10; flip += 1) { + act(() => + useAppStore.setState({ + runtimeStatusByEnvironmentId: statuses(flip % 2 === 0 ? unrelated.result : null) + }) + ) + } + expect(renders - before).toBe(0) + const hostState = views[1].result.current + act(() => + useAppStore.setState({ + runtimeStatusByEnvironmentId: new Map([ + [ + 'host', + { + status: { + ...own.result, + capabilities: + hostState === 'supported' ? [] : [AGENT_SESSION_PERMISSION_OWN_RUNTIME_CAPABILITY] + }, + checkedAt: 2 + } + ] + ]) + }) + ) + expect(views[1].result.current).toBe(hostState === 'supported' ? 'unsupported' : 'supported') +}) diff --git a/src/renderer/src/runtime/structured-agent-session-host-capability.ts b/src/renderer/src/runtime/structured-agent-session-host-capability.ts index 4107600a8e8..99592766aa5 100644 --- a/src/renderer/src/runtime/structured-agent-session-host-capability.ts +++ b/src/renderer/src/runtime/structured-agent-session-host-capability.ts @@ -1,5 +1,5 @@ import { AGENT_SESSION_PERMISSION_OWN_RUNTIME_CAPABILITY } from '../../../shared/agent-session-permission-modes-capability' -import { useEffect, useMemo, useState, useSyncExternalStore } from 'react' +import { useEffect, useState, useSyncExternalStore } from 'react' import { useAppStore } from '@/store' import { AGENT_SESSION_CONVERSATION_STOP_RUNTIME_CAPABILITY, @@ -37,19 +37,19 @@ export function useStructuredAgentSessionOwnPermissionState( ): StructuredAgentSessionHostCapabilityState { const capability = AGENT_SESSION_PERMISSION_OWN_RUNTIME_CAPABILITY const environmentId = target?.kind === 'environment' ? target.environmentId : null - const statuses = useAppStore((state) => state.runtimeStatusByEnvironmentId) - const remote = useMemo((): StructuredAgentSessionHostCapabilityState => { + // Select the verdict, not the map: unrelated host flips must not rerender every chat. + const remote = useAppStore((state): StructuredAgentSessionHostCapabilityState => { if (environmentId === null) { return 'unknown' } - const entry = statuses.get(environmentId) + const entry = state.runtimeStatusByEnvironmentId.get(environmentId) const status = isRuntimeHostContactRevoked(entry) ? null : lastVerifiedRuntimeStatus(entry) return status ? status.capabilities?.includes(capability) ? 'supported' : 'unsupported' : 'unknown' - }, [statuses, environmentId, capability]) + }) const local = useSyncExternalStore( subscribeLocalRuntimeCapabilityObservation, () => localCapabilityState(capability),