mirror of
https://github.com/stablyai/orca.git
synced 2026-10-06 16:02:25 +00:00
perf(renderer): share terminal agent type index (#8066)
This commit is contained in:
@@ -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()
|
||||
Reference in New Issue
Block a user