mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
fix(tui): chevrons re-toggle even when section default is expanded
Recovers the manual click on the details accordion: with #14968's new SECTION_DEFAULTS (thinking/tools start `expanded`), every panel render was OR-ing the local open toggle against `visible.X === 'expanded'`. That pinned `open=true` for the default-expanded sections, so clicking the chevron flipped the local state but the panel never collapsed. Local toggle is now the sole source of truth at render time; the useState init still seeds from the resolved visibility (so first paint is correct) and the existing useEffect still re-syncs when the user mutates visibility at runtime via `/details`. Same OR-lock cleared inside SubagentAccordion (`showChildren || openX`) — pre-existing but the same shape, so expand-all on the spawn tree no longer makes inner sections un-collapsible either.
This commit is contained in:
parent
62c14d5513
commit
f5e2a77a80
1 changed files with 26 additions and 16 deletions
|
|
@ -392,6 +392,9 @@ function SubagentAccordion({
|
||||||
const hasTools = item.tools.length > 0
|
const hasTools = item.tools.length > 0
|
||||||
const noteRows = [...(summary ? [summary] : []), ...item.notes]
|
const noteRows = [...(summary ? [summary] : []), ...item.notes]
|
||||||
const hasNotes = noteRows.length > 0
|
const hasNotes = noteRows.length > 0
|
||||||
|
// `showChildren` only seeds the recursive `expanded` prop for nested
|
||||||
|
// subagents — it MUST NOT be OR-ed into the local section toggles, or
|
||||||
|
// expand-all permanently locks the inner chevrons open.
|
||||||
const showChildren = expanded || deep
|
const showChildren = expanded || deep
|
||||||
const noteColor = statusTone === 'error' ? t.color.error : statusTone === 'warn' ? t.color.warn : t.color.dim
|
const noteColor = statusTone === 'error' ? t.color.error : statusTone === 'warn' ? t.color.warn : t.color.dim
|
||||||
|
|
||||||
|
|
@ -414,13 +417,13 @@ function SubagentAccordion({
|
||||||
setOpenThinking(v => !v)
|
setOpenThinking(v => !v)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
open={showChildren || openThinking}
|
open={openThinking}
|
||||||
t={t}
|
t={t}
|
||||||
title="Thinking"
|
title="Thinking"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: 'thinking',
|
key: 'thinking',
|
||||||
open: showChildren || openThinking,
|
open: openThinking,
|
||||||
render: childRails => (
|
render: childRails => (
|
||||||
<Thinking
|
<Thinking
|
||||||
active={item.status === 'running'}
|
active={item.status === 'running'}
|
||||||
|
|
@ -447,13 +450,13 @@ function SubagentAccordion({
|
||||||
setOpenTools(v => !v)
|
setOpenTools(v => !v)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
open={showChildren || openTools}
|
open={openTools}
|
||||||
t={t}
|
t={t}
|
||||||
title="Tool calls"
|
title="Tool calls"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: 'tools',
|
key: 'tools',
|
||||||
open: showChildren || openTools,
|
open: openTools,
|
||||||
render: childRails => (
|
render: childRails => (
|
||||||
<Box flexDirection="column">
|
<Box flexDirection="column">
|
||||||
{item.tools.map((line, index) => (
|
{item.tools.map((line, index) => (
|
||||||
|
|
@ -488,14 +491,14 @@ function SubagentAccordion({
|
||||||
setOpenNotes(v => !v)
|
setOpenNotes(v => !v)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
open={showChildren || openNotes}
|
open={openNotes}
|
||||||
t={t}
|
t={t}
|
||||||
title="Progress"
|
title="Progress"
|
||||||
tone={statusTone}
|
tone={statusTone}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: 'notes',
|
key: 'notes',
|
||||||
open: showChildren || openNotes,
|
open: openNotes,
|
||||||
render: childRails => (
|
render: childRails => (
|
||||||
<Box flexDirection="column">
|
<Box flexDirection="column">
|
||||||
{noteRows.map((line, index) => (
|
{noteRows.map((line, index) => (
|
||||||
|
|
@ -528,14 +531,14 @@ function SubagentAccordion({
|
||||||
setOpenKids(v => !v)
|
setOpenKids(v => !v)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
open={showChildren || openKids}
|
open={openKids}
|
||||||
suffix={`d${item.depth + 1} · ${aggregate.descendantCount} total`}
|
suffix={`d${item.depth + 1} · ${aggregate.descendantCount} total`}
|
||||||
t={t}
|
t={t}
|
||||||
title="Spawned"
|
title="Spawned"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: 'subagents',
|
key: 'subagents',
|
||||||
open: showChildren || openKids,
|
open: openKids,
|
||||||
render: childRails => (
|
render: childRails => (
|
||||||
<Box flexDirection="column">
|
<Box flexDirection="column">
|
||||||
{children.map((child, i) => (
|
{children.map((child, i) => (
|
||||||
|
|
@ -718,6 +721,13 @@ export const ToolTrail = memo(function ToolTrail({
|
||||||
)
|
)
|
||||||
|
|
||||||
const [now, setNow] = useState(() => Date.now())
|
const [now, setNow] = useState(() => Date.now())
|
||||||
|
// Local toggles own the open state once mounted. Init from the resolved
|
||||||
|
// section visibility so default-expanded sections (thinking/tools) render
|
||||||
|
// open on first paint; the useEffect below re-syncs when the user mutates
|
||||||
|
// visibility at runtime via /details. NEVER OR these against
|
||||||
|
// `visible.X === 'expanded'` at render time — that locks the panel open
|
||||||
|
// and silently breaks manual chevron clicks for default-expanded
|
||||||
|
// sections (regression caught after #14968).
|
||||||
const [openThinking, setOpenThinking] = useState(visible.thinking === 'expanded')
|
const [openThinking, setOpenThinking] = useState(visible.thinking === 'expanded')
|
||||||
const [openTools, setOpenTools] = useState(visible.tools === 'expanded')
|
const [openTools, setOpenTools] = useState(visible.tools === 'expanded')
|
||||||
const [openSubagents, setOpenSubagents] = useState(visible.subagents === 'expanded')
|
const [openSubagents, setOpenSubagents] = useState(visible.subagents === 'expanded')
|
||||||
|
|
@ -960,7 +970,7 @@ export const ToolTrail = memo(function ToolTrail({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Text color={t.color.dim} dim={!thinkingLive}>
|
<Text color={t.color.dim} dim={!thinkingLive}>
|
||||||
<Text color={t.color.amber}>{visible.thinking === 'expanded' || openThinking ? '▾ ' : '▸ '}</Text>
|
<Text color={t.color.amber}>{openThinking ? '▾ ' : '▸ '}</Text>
|
||||||
{thinkingLive ? (
|
{thinkingLive ? (
|
||||||
<Text bold color={t.color.cornsilk}>
|
<Text bold color={t.color.cornsilk}>
|
||||||
Thinking
|
Thinking
|
||||||
|
|
@ -980,7 +990,7 @@ export const ToolTrail = memo(function ToolTrail({
|
||||||
</Box>
|
</Box>
|
||||||
),
|
),
|
||||||
key: 'thinking',
|
key: 'thinking',
|
||||||
open: visible.thinking === 'expanded' || openThinking,
|
open: openThinking,
|
||||||
render: rails => (
|
render: rails => (
|
||||||
<Thinking
|
<Thinking
|
||||||
active={reasoningActive}
|
active={reasoningActive}
|
||||||
|
|
@ -1007,14 +1017,14 @@ export const ToolTrail = memo(function ToolTrail({
|
||||||
setOpenTools(v => !v)
|
setOpenTools(v => !v)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
open={visible.tools === 'expanded' || openTools}
|
open={openTools}
|
||||||
suffix={toolTokensLabel}
|
suffix={toolTokensLabel}
|
||||||
t={t}
|
t={t}
|
||||||
title="Tool calls"
|
title="Tool calls"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: 'tools',
|
key: 'tools',
|
||||||
open: visible.tools === 'expanded' || openTools,
|
open: openTools,
|
||||||
render: rails => (
|
render: rails => (
|
||||||
<Box flexDirection="column">
|
<Box flexDirection="column">
|
||||||
{groups.map((group, index) => {
|
{groups.map((group, index) => {
|
||||||
|
|
@ -1072,14 +1082,14 @@ export const ToolTrail = memo(function ToolTrail({
|
||||||
setDeepSubagents(false)
|
setDeepSubagents(false)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
open={visible.subagents === 'expanded' || openSubagents}
|
open={openSubagents}
|
||||||
suffix={suffix}
|
suffix={suffix}
|
||||||
t={t}
|
t={t}
|
||||||
title="Spawn tree"
|
title="Spawn tree"
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: 'subagents',
|
key: 'subagents',
|
||||||
open: visible.subagents === 'expanded' || openSubagents,
|
open: openSubagents,
|
||||||
render: renderSubagentList
|
render: renderSubagentList
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -1096,14 +1106,14 @@ export const ToolTrail = memo(function ToolTrail({
|
||||||
setOpenMeta(v => !v)
|
setOpenMeta(v => !v)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
open={visible.activity === 'expanded' || openMeta}
|
open={openMeta}
|
||||||
t={t}
|
t={t}
|
||||||
title="Activity"
|
title="Activity"
|
||||||
tone={metaTone}
|
tone={metaTone}
|
||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
key: 'meta',
|
key: 'meta',
|
||||||
open: visible.activity === 'expanded' || openMeta,
|
open: openMeta,
|
||||||
render: rails => (
|
render: rails => (
|
||||||
<Box flexDirection="column">
|
<Box flexDirection="column">
|
||||||
{meta.map((row, index) => (
|
{meta.map((row, index) => (
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue