perf(renderer): share terminal agent type index (#8066)

This commit is contained in:
Neil
2026-07-10 20:51:23 -07:00
committed by GitHub
parent 818e182a0c
commit 74e68afbb2
3 changed files with 152 additions and 14 deletions
@@ -101,7 +101,6 @@ import {
import { shouldChatTakeOverMobileSurface } from '../native-chat/native-chat-send-eligibility'
import { canToggleNativeChat } from '../native-chat/native-chat-availability'
import { isNativeChatTranscriptLocalReadable } from '@/lib/native-chat-transcript-readability'
import type { AgentType } from '../../../../shared/agent-status-types'
import { resolvePaneKeyForManager } from '@/lib/pane-manager/pane-key-resolution'
import { safeFit } from '@/lib/pane-manager/pane-tree-ops'
import { captureTerminalShutdownLayout } from './terminal-shutdown-layout-capture'
@@ -148,6 +147,7 @@ import { scheduleImagePasteWebglAtlasRecovery } from './terminal-webgl-atlas-rec
import { restoreTerminalFitToDesktop, restoreTerminalFitsToDesktop } from './terminal-fit-restore'
import { useVisibleTerminalTabClaim } from './use-visible-terminal-tab-claim'
import { TerminalSshReconnectOverlay } from './TerminalSshReconnectOverlay'
import { selectTerminalTabAgentTypesByLeaf } from './terminal-tab-agent-type-index'
const NATIVE_CHAT_ROOT_SELECTOR = '[data-native-chat-root="true"]'
@@ -680,19 +680,10 @@ export default function TerminalPane({
// when Orca launched a *supported* agent here or one was detected live for the
// leaf, keyed `${tabId}:${leafId}`. Carry the agent identity, not just "an
// agent exists", so the gate can reject Grok et al.
// Scoped to this tab's panes (leafId → agentType) and shallow-compared so an
// unrelated tab's agent status tick doesn't re-render this pane.
const tabAgentTypeByLeaf = useAppStore(
useShallow((store) => {
const prefix = `${tabId}:`
const byLeaf: Record<string, AgentType> = {}
for (const [paneKey, entry] of Object.entries(store.agentStatusByPaneKey)) {
if (paneKey.startsWith(prefix) && entry.agentType) {
byLeaf[paneKey.slice(prefix.length)] = entry.agentType
}
}
return byLeaf
})
// Scope to this tab's panes and reuse the shared map index so hidden tabs do
// not each rescan every agent entry on unrelated store writes.
const tabAgentTypeByLeaf = useAppStore((store) =>
selectTerminalTabAgentTypesByLeaf(store.agentStatusByPaneKey, tabId)
)
const toggleTabViewMode = useAppStore((store) => store.toggleTabViewMode)
const savedLayout = useAppStore((store) => store.terminalLayoutsByTabId[tabId] ?? EMPTY_LAYOUT)
@@ -0,0 +1,74 @@
import { describe, expect, it, vi } from 'vitest'
import type { AgentStatusEntry } from '../../../../shared/agent-status-types'
import { createTerminalTabAgentTypeSelector } from './terminal-tab-agent-type-index'
function entry(agentType: AgentStatusEntry['agentType'], state = 'working'): AgentStatusEntry {
return { agentType, state, updatedAt: 0 } as AgentStatusEntry
}
describe('createTerminalTabAgentTypeSelector', () => {
it('scans one global map only once across all mounted tab selectors', () => {
const onEntryVisited = vi.fn()
const select = createTerminalTabAgentTypeSelector({ onEntryVisited })
const state = {
'tab-1:leaf-a': entry('claude'),
'tab-1:leaf-b': entry('codex'),
'tab-2:leaf-c': entry('grok')
}
expect(select(state, 'tab-1')).toEqual({ 'leaf-a': 'claude', 'leaf-b': 'codex' })
expect(select(state, 'tab-2')).toEqual({ 'leaf-c': 'grok' })
for (let index = 0; index < 100; index += 1) {
select(state, `hidden-tab-${index}`)
}
expect(onEntryVisited).toHaveBeenCalledTimes(3)
})
it('reuses per-tab results across state-only agent transitions', () => {
const select = createTerminalTabAgentTypeSelector()
const working = {
'tab-1:leaf-a': entry('claude', 'working'),
'tab-2:leaf-b': entry('codex', 'working')
}
const firstTab = select(working, 'tab-1')
const secondTab = select(working, 'tab-2')
const done = {
'tab-1:leaf-a': entry('claude', 'done'),
'tab-2:leaf-b': entry('codex', 'done')
}
expect(select(done, 'tab-1')).toBe(firstTab)
expect(select(done, 'tab-2')).toBe(secondTab)
})
it('changes only the tab whose agent identity changes', () => {
const select = createTerminalTabAgentTypeSelector()
const before = {
'tab-1:leaf-a': entry('claude'),
'tab-2:leaf-b': entry('codex')
}
const firstTab = select(before, 'tab-1')
const secondTab = select(before, 'tab-2')
const after = {
...before,
'tab-2:leaf-b': entry('grok')
}
expect(select(after, 'tab-1')).toBe(firstTab)
expect(select(after, 'tab-2')).not.toBe(secondTab)
expect(select(after, 'tab-2')).toEqual({ 'leaf-b': 'grok' })
})
it('ignores missing agent types and keys without a tab prefix', () => {
const select = createTerminalTabAgentTypeSelector()
const state = {
malformed: entry('claude'),
':leaf-a': entry('codex'),
'tab-1:leaf-a': entry(undefined)
}
expect(select(state, 'tab-1')).toEqual({})
expect(select(state, 'malformed')).toEqual({})
})
})
@@ -0,0 +1,73 @@
import type { AgentStatusEntry, AgentType } from '../../../../shared/agent-status-types'
export type TerminalTabAgentTypeState = Record<string, AgentStatusEntry>
export type TerminalTabAgentTypesByLeaf = Readonly<Record<string, AgentType>>
type SelectorDependencies = {
onEntryVisited?: (paneKey: string) => void
}
const EMPTY_AGENT_TYPES_BY_LEAF: TerminalTabAgentTypesByLeaf = Object.freeze({})
function reuseRecordIfEqual(
previous: TerminalTabAgentTypesByLeaf | undefined,
next: Record<string, AgentType>
): TerminalTabAgentTypesByLeaf {
if (!previous) {
return next
}
const nextKeys = Object.keys(next)
if (Object.keys(previous).length !== nextKeys.length) {
return next
}
return nextKeys.every((key) => previous[key] === next[key]) ? previous : next
}
export function createTerminalTabAgentTypeSelector(
dependencies: SelectorDependencies = {}
): (state: TerminalTabAgentTypeState, tabId: string) => TerminalTabAgentTypesByLeaf {
let cachedState: TerminalTabAgentTypeState | null = null
let cachedByTabId = new Map<string, TerminalTabAgentTypesByLeaf>()
return (state, tabId) => {
// Why: production writes replace this map. Its identity lets unrelated
// Zustand notifications skip the global scan entirely.
if (state !== cachedState) {
const previousByTabId = cachedByTabId
const nextByTabId = new Map<string, Record<string, AgentType>>()
for (const [paneKey, entry] of Object.entries(state)) {
dependencies.onEntryVisited?.(paneKey)
if (!entry.agentType) {
continue
}
const separator = paneKey.indexOf(':')
if (separator <= 0) {
continue
}
const entryTabId = paneKey.slice(0, separator)
const leafId = paneKey.slice(separator + 1)
const byLeaf = nextByTabId.get(entryTabId)
if (byLeaf) {
byLeaf[leafId] = entry.agentType
} else {
nextByTabId.set(entryTabId, { [leafId]: entry.agentType })
}
}
const stabilizedByTabId = new Map<string, TerminalTabAgentTypesByLeaf>()
for (const [entryTabId, byLeaf] of nextByTabId) {
stabilizedByTabId.set(
entryTabId,
reuseRecordIfEqual(previousByTabId.get(entryTabId), byLeaf)
)
}
cachedByTabId = stabilizedByTabId
cachedState = state
}
return cachedByTabId.get(tabId) ?? EMPTY_AGENT_TYPES_BY_LEAF
}
}
// Why: TerminalPane is mounted once per retained tab. Share one index so a
// store write scans the global agent map once, not once for every hidden tab.
export const selectTerminalTabAgentTypesByLeaf = createTerminalTabAgentTypeSelector()