mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-04-25 00:51:20 +00:00
feat(tui): interleave tool rows into live assistant turns
Live turn rendering used to show the streaming assistant text as one blob with tool calls pooled in a separate section below, so the live view drifted from the reload view (which threads tool rows inline via toTranscriptMessages). Model now mirrors reload: - turnStore gains streamSegments (completed assistant chunks, each with any tool rows that landed between its predecessor and itself) and streamPendingTools (tool rows waiting for the next chunk) - turnController.flushStreamingSegment() seals the current bufRef into a segment when a new tool.start fires; pending tools get attached to that next chunk so order matches reload hydration - recordMessageComplete returns finalMessages instead of one payload, so appendMessage gets the same shape for live-ending turns as for reloaded ones - appLayout renders segments before the progress/streaming area, and the streaming message + pending-tools fallback carry whatever tools arrived after the last assistant chunk
This commit is contained in:
parent
f53250b5e1
commit
bedbeebbc8
6 changed files with 85 additions and 22 deletions
|
|
@ -4,7 +4,7 @@ import type { CommandsCatalogResponse, GatewayEvent, GatewaySkin } from '../gate
|
|||
import { rpcErrorMessage } from '../lib/rpc.js'
|
||||
import { formatToolCall } from '../lib/text.js'
|
||||
import { fromSkin } from '../theme.js'
|
||||
import type { SubagentProgress } from '../types.js'
|
||||
import type { Msg, SubagentProgress } from '../types.js'
|
||||
|
||||
import type { GatewayEventHandlerContext } from './interfaces.js'
|
||||
import { patchOverlayState } from './overlayStore.js'
|
||||
|
|
@ -377,18 +377,11 @@ export function createGatewayEventHandler(ctx: GatewayEventHandlerContext): (ev:
|
|||
|
||||
return
|
||||
case 'message.complete': {
|
||||
const { finalText, savedReasoning, savedReasoningTokens, savedTools, savedToolTokens, wasInterrupted } =
|
||||
turnController.recordMessageComplete(ev.payload ?? {})
|
||||
const { finalMessages, finalText, wasInterrupted } = turnController.recordMessageComplete(ev.payload ?? {})
|
||||
|
||||
if (!wasInterrupted) {
|
||||
appendMessage({
|
||||
role: 'assistant',
|
||||
text: finalText,
|
||||
thinking: savedReasoning || undefined,
|
||||
thinkingTokens: savedReasoning ? savedReasoningTokens : undefined,
|
||||
toolTokens: savedTools.length ? savedToolTokens : undefined,
|
||||
tools: savedTools.length ? savedTools : undefined
|
||||
})
|
||||
const msgs: Msg[] = finalMessages.length ? finalMessages : [{ role: 'assistant', text: finalText }]
|
||||
msgs.forEach(appendMessage)
|
||||
|
||||
if (bellOnComplete && stdout?.isTTY) {
|
||||
stdout.write('\x07')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue