mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-20 15:33:54 +00:00
fix(desktop): stop reasoning text flashing/re-typing on every delta
Reasoning ("Thinking") rendered through MarkdownTextContent with a smooth
typewriter reveal. TextMessagePartProvider mints a fresh part object on every
text change, and useSmooth resets its reveal to empty whenever the part
identity changes — so each reasoning delta restarted the animation from the
first character (h / hell / hello wo ...). Token-streaming reasoners
(R1/Qwen/GLM/Claude thinking) fire a delta per token and flash hard; GPT-5's
coarse reasoning summary updates too rarely to notice, which is why it looked
fine.
Drop smooth on the reasoning path so it plain-appends, exactly like the
assistant answer already does. Removes the now-dead smooth plumbing too.
This commit is contained in:
parent
e0e7cfa673
commit
a4c9b069dc
1 changed files with 9 additions and 14 deletions
|
|
@ -1,6 +1,6 @@
|
|||
'use client'
|
||||
|
||||
import { type SmoothOptions, TextMessagePartProvider, useMessagePartText } from '@assistant-ui/react'
|
||||
import { TextMessagePartProvider, useMessagePartText } from '@assistant-ui/react'
|
||||
import {
|
||||
parseMarkdownIntoBlocks,
|
||||
type StreamdownTextComponents,
|
||||
|
|
@ -342,7 +342,6 @@ interface MarkdownTextSurfaceProps {
|
|||
containerClassName?: string
|
||||
containerProps?: ComponentProps<'div'>
|
||||
defer?: boolean
|
||||
smooth?: boolean | SmoothOptions
|
||||
}
|
||||
|
||||
// Headings shrink to chat scale rather than the prose default (h1≈xl). Kept
|
||||
|
|
@ -391,7 +390,7 @@ function HugeTextFallback({ containerClassName, text }: { containerClassName?: s
|
|||
)
|
||||
}
|
||||
|
||||
function MarkdownTextSurface({ containerClassName, containerProps, defer, smooth }: MarkdownTextSurfaceProps) {
|
||||
function MarkdownTextSurface({ containerClassName, containerProps, defer }: MarkdownTextSurfaceProps) {
|
||||
const { status, text } = useMessagePartText()
|
||||
const isStreaming = status.type === 'running'
|
||||
|
||||
|
|
@ -531,29 +530,25 @@ function MarkdownTextSurface({ containerClassName, containerProps, defer, smooth
|
|||
parseMarkdownIntoBlocksFn={parseMarkdownIntoBlocksCached}
|
||||
plugins={plugins}
|
||||
preprocess={preprocessWithTailRepair}
|
||||
smooth={smooth}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
const SMOOTH_OPTIONS: SmoothOptions = {
|
||||
drainMs: 500,
|
||||
maxCharsPerFrame: 30,
|
||||
minCommitMs: 33
|
||||
}
|
||||
|
||||
interface MarkdownTextContentProps extends MarkdownTextSurfaceProps {
|
||||
isRunning: boolean
|
||||
text: string
|
||||
}
|
||||
|
||||
export function MarkdownTextContent({ isRunning, text, ...surfaceProps }: MarkdownTextContentProps) {
|
||||
// Same path as the assistant answer. A reasoning-only smoothing wrapper used
|
||||
// to sit here but stalled its char-reveal at empty (the part stays running
|
||||
// the whole message), blanking the Thinking widget.
|
||||
// No `smooth` on purpose — same as the assistant answer. `TextMessagePartProvider`
|
||||
// mints a fresh part object on every `text` change, and useSmooth resets its
|
||||
// reveal to empty whenever the part identity changes, so a smoothed reasoning
|
||||
// stream re-types from the first character on every delta (the flash). Token-
|
||||
// streaming reasoners (R1/Qwen/GLM/Claude thinking) hit it hardest; GPT-5's
|
||||
// coarse summary updates too rarely to notice. Plain append matches the answer.
|
||||
return (
|
||||
<TextMessagePartProvider isRunning={isRunning} text={text}>
|
||||
<MarkdownTextSurface defer smooth={SMOOTH_OPTIONS} {...surfaceProps} />
|
||||
<MarkdownTextSurface defer {...surfaceProps} />
|
||||
</TextMessagePartProvider>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue