mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +00:00
fix(tui): collapse long system messages in transcript with expand toggle
System messages over 400 chars (system prompt, AGENTS.md, etc.) now render as a collapsed \u25b8/\u25be toggle line in the transcript, matching the Chevron convention used for runtime details. The summary shows the first line + char count; clicking expands to full content.
This commit is contained in:
parent
d78c34928f
commit
68162eb18f
1 changed files with 29 additions and 1 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import { Ansi, Box, NoSelect, Text } from '@hermes/ink'
|
||||
import { memo } from 'react'
|
||||
import { memo, useState } from 'react'
|
||||
|
||||
import { LONG_MSG } from '../config/limits.js'
|
||||
import { sectionMode } from '../domain/details.js'
|
||||
|
|
@ -22,6 +22,9 @@ import { StreamingMd } from './streamingMarkdown.js'
|
|||
import { ToolTrail } from './thinking.js'
|
||||
import { TodoPanel } from './todoPanel.js'
|
||||
|
||||
// Collapse threshold for long system messages (system prompt etc.)
|
||||
const SYSTEM_COLLAPSE_CHARS = 400
|
||||
|
||||
export const MessageLine = memo(function MessageLine({
|
||||
cols,
|
||||
compact,
|
||||
|
|
@ -46,6 +49,10 @@ export const MessageLine = memo(function MessageLine({
|
|||
const activityMode = sectionMode('activity', detailsMode, sections, detailsModeCommandOverride)
|
||||
const thinking = msg.thinking?.trim() ?? ''
|
||||
|
||||
// Collapse toggle for long system messages
|
||||
const systemIsLong = msg.role === 'system' && msg.text.length > SYSTEM_COLLAPSE_CHARS
|
||||
const [systemOpen, setSystemOpen] = useState(false)
|
||||
|
||||
if (msg.kind === 'trail' && msg.todos?.length) {
|
||||
return (
|
||||
<TodoPanel
|
||||
|
|
@ -106,6 +113,27 @@ export const MessageLine = memo(function MessageLine({
|
|||
return <Text color={t.color.muted}>{msg.text}</Text>
|
||||
}
|
||||
|
||||
// ── Collapsible long system message (system prompt, AGENTS.md, etc.) ──
|
||||
// MUST come before the hasAnsi check — system messages from the backend
|
||||
// contain Rich markup escape codes that would otherwise hit <Ansi> full render.
|
||||
if (systemIsLong) {
|
||||
const firstLine = (msg.text.split('\n')[0] ?? '').trim().slice(0, 120) || '(system message)'
|
||||
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
<Box onClick={() => setSystemOpen(v => !v)}>
|
||||
<Text color={t.color.accent}>{systemOpen ? '▾ ' : '▸ '}</Text>
|
||||
<Text color={t.color.muted}>{firstLine}</Text>
|
||||
<Text color={t.color.muted} dimColor>
|
||||
{' — '}
|
||||
{msg.text.length.toLocaleString()} chars
|
||||
</Text>
|
||||
</Box>
|
||||
{systemOpen && <Ansi>{msg.text}</Ansi>}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
if (msg.role !== 'user' && hasAnsi(msg.text)) {
|
||||
return <Ansi>{msg.text}</Ansi>
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue