mirror of
https://github.com/stablyai/orca.git
synced 2026-10-21 00:03:46 +00:00
fix(agent-rows): preserve same-tab child labels
This commit is contained in:
@@ -56,6 +56,44 @@ describe('useAgentRowConversationName', () => {
|
||||
expect(useAgentRowConversationName(makeAgent({ rowSource: 'subagent' }))).toBeNull()
|
||||
})
|
||||
|
||||
it('does not inherit a same-tab lineage parent conversation name', () => {
|
||||
const tabsByWorktree = new Proxy(
|
||||
{},
|
||||
{
|
||||
get: () => {
|
||||
throw new Error('same-tab child rows must not read the parent tab')
|
||||
}
|
||||
}
|
||||
)
|
||||
storeState.current = { settings: {}, tabsByWorktree }
|
||||
expect(
|
||||
useAgentRowConversationName(
|
||||
makeAgent({
|
||||
entry: {
|
||||
prompt: 'child prompt',
|
||||
orchestration: {
|
||||
parentPaneKey: 'tab-1:aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa'
|
||||
}
|
||||
},
|
||||
lineage: { depth: 1, isFirstSibling: true, isLastSibling: true, childCount: 0 }
|
||||
} as Partial<DashboardAgentRow>)
|
||||
)
|
||||
).toBeNull()
|
||||
})
|
||||
|
||||
it('uses a lineage child conversation name when it owns a separate tab', () => {
|
||||
const agent = makeAgent({
|
||||
entry: {
|
||||
prompt: 'child prompt',
|
||||
orchestration: {
|
||||
parentPaneKey: 'parent-tab:aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa'
|
||||
}
|
||||
},
|
||||
lineage: { depth: 1, isFirstSibling: true, isLastSibling: true, childCount: 0 }
|
||||
} as Partial<DashboardAgentRow>)
|
||||
expect(useAgentRowConversationName(agent)).toBe('Patient sync spike')
|
||||
})
|
||||
|
||||
it('indexes one immutable tab array once across rows', () => {
|
||||
let tabReads = 0
|
||||
const tabs = new Proxy(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { getAgentRowConversationName } from '../../../../shared/agent-row-conversation-name'
|
||||
import { parsePaneKey } from '../../../../shared/stable-pane-id'
|
||||
import { useAppStore } from '@/store'
|
||||
import type { AppState } from '@/store/types'
|
||||
import type { DashboardAgentRow } from './useDashboardData'
|
||||
@@ -24,15 +25,22 @@ function getIndexedTab(
|
||||
|
||||
/** The row's conversation name, or null when nothing usable exists. */
|
||||
export function useAgentRowConversationName(agent: DashboardAgentRow): string | null {
|
||||
const isSubagent = agent.rowSource === 'subagent'
|
||||
const parentPaneKey = agent.entry.orchestration?.parentPaneKey
|
||||
const usesParentTab =
|
||||
agent.lineage?.depth === 1 &&
|
||||
parentPaneKey !== undefined &&
|
||||
parsePaneKey(parentPaneKey)?.tabId === agent.tab.id
|
||||
const cannotOwnTabName = agent.rowSource === 'subagent' || usesParentTab
|
||||
const generatedTitlesEnabled = useAppStore(
|
||||
(s) => !isSubagent && s.settings?.tabAutoGenerateTitle === true
|
||||
(s) => !cannotOwnTabName && s.settings?.tabAutoGenerateTitle === true
|
||||
)
|
||||
// Why: child rows describe the child, so the parent tab would mislabel them.
|
||||
const liveTab = useAppStore((s) =>
|
||||
isSubagent ? undefined : getIndexedTab(s.tabsByWorktree[agent.tab.worktreeId], agent.tab.id)
|
||||
cannotOwnTabName
|
||||
? undefined
|
||||
: getIndexedTab(s.tabsByWorktree[agent.tab.worktreeId], agent.tab.id)
|
||||
)
|
||||
if (isSubagent) {
|
||||
// Why: synthetic and same-tab child rows do not own the parent tab's name.
|
||||
if (cannotOwnTabName) {
|
||||
return null
|
||||
}
|
||||
// Why: retained row snapshots need a fallback after their live tab disappears.
|
||||
|
||||
+3
-2
@@ -474,8 +474,9 @@ describe('WorktreeCard agent-list <-> child-worktrees expansion coupling', () =>
|
||||
setAgentLineageState({ agentActivityDisplayMode: 'full' })
|
||||
const { container } = await renderWorktreeList()
|
||||
|
||||
// Sanity: real agent rows rendered (parent + its lineage child agent).
|
||||
expect(container.textContent).toContain('PARENT_AGENT_PROMPT')
|
||||
// Same-tab lineage children must not inherit the parent's conversation name.
|
||||
expect(container.textContent).toContain('Parent Terminal')
|
||||
expect(container.textContent).not.toContain('PARENT_AGENT_PROMPT')
|
||||
expect(container.textContent).toContain('CHILD_AGENT_PROMPT')
|
||||
|
||||
// Both controls exist and are independent DOM elements.
|
||||
|
||||
Reference in New Issue
Block a user