mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-28 06:51:16 +08:00
feat(tui): collapse completed todo panel on turn end
This commit is contained in:
@@ -93,7 +93,13 @@ describe('createGatewayEventHandler', () => {
|
||||
onEvent({ payload: { text: 'done' }, type: 'message.complete' } as any)
|
||||
|
||||
expect(getTurnState().todos).toEqual([])
|
||||
expect(appended).toContainEqual({ kind: 'trail', role: 'system', text: '', todos })
|
||||
expect(appended).toContainEqual({
|
||||
kind: 'trail',
|
||||
role: 'system',
|
||||
text: '',
|
||||
todoCollapsedByDefault: true,
|
||||
todos
|
||||
})
|
||||
})
|
||||
|
||||
it('keeps the current todo list visible when the next message starts', () => {
|
||||
|
||||
@@ -26,6 +26,7 @@ describe('turnStore live progress helpers', () => {
|
||||
kind: 'trail',
|
||||
role: 'system',
|
||||
text: '',
|
||||
todoCollapsedByDefault: true,
|
||||
todos: [
|
||||
{ content: 'prep', id: 'prep', status: 'completed' },
|
||||
{ content: 'serve', id: 'serve', status: 'completed' }
|
||||
|
||||
@@ -49,12 +49,13 @@ export const archiveTodosAtTurnEnd = () => {
|
||||
return []
|
||||
}
|
||||
|
||||
const done = isTodoDone(state.todos)
|
||||
const msg: Msg = {
|
||||
kind: 'trail',
|
||||
role: 'system',
|
||||
text: '',
|
||||
todos: state.todos,
|
||||
...(isTodoDone(state.todos) ? {} : { todoIncomplete: true })
|
||||
...(done ? { todoCollapsedByDefault: true } : { todoIncomplete: true })
|
||||
}
|
||||
|
||||
patchTurnState({ todoCollapsed: false, todos: [] })
|
||||
|
||||
@@ -38,7 +38,14 @@ export const MessageLine = memo(function MessageLine({
|
||||
const thinking = msg.thinking?.trim() ?? ''
|
||||
|
||||
if (msg.kind === 'trail' && msg.todos?.length) {
|
||||
return <TodoPanel incomplete={msg.todoIncomplete} t={t} todos={msg.todos} />
|
||||
return (
|
||||
<TodoPanel
|
||||
defaultCollapsed={msg.todoCollapsedByDefault}
|
||||
incomplete={msg.todoIncomplete}
|
||||
t={t}
|
||||
todos={msg.todos}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
if (msg.kind === 'trail' && (msg.tools?.length || tools.length || thinking)) {
|
||||
|
||||
@@ -14,12 +14,14 @@ const rowColor = (t: Theme, status: TodoItem['status']) => {
|
||||
|
||||
export const TodoPanel = memo(function TodoPanel({
|
||||
collapsed,
|
||||
defaultCollapsed = false,
|
||||
incomplete = false,
|
||||
onToggle,
|
||||
t,
|
||||
todos
|
||||
}: {
|
||||
collapsed?: boolean
|
||||
defaultCollapsed?: boolean
|
||||
incomplete?: boolean
|
||||
onToggle?: () => void
|
||||
t: Theme
|
||||
@@ -28,7 +30,7 @@ export const TodoPanel = memo(function TodoPanel({
|
||||
// Fallback local state for archived todos in transcript where there's no
|
||||
// external controller. Live TodoPanel passes collapsed+onToggle from the
|
||||
// turn store so clicks still work there.
|
||||
const [localCollapsed, setLocalCollapsed] = useState(false)
|
||||
const [localCollapsed, setLocalCollapsed] = useState(defaultCollapsed)
|
||||
const isControlled = typeof collapsed === 'boolean'
|
||||
const effectiveCollapsed = isControlled ? collapsed : localCollapsed
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ export interface Msg {
|
||||
tools?: string[]
|
||||
todos?: TodoItem[]
|
||||
todoIncomplete?: boolean
|
||||
todoCollapsedByDefault?: boolean
|
||||
}
|
||||
|
||||
export type Role = 'assistant' | 'system' | 'tool' | 'user'
|
||||
|
||||
Reference in New Issue
Block a user