diff --git a/src/components/prose/GenerationThoughts.tsx b/src/components/prose/GenerationThoughts.tsx index e9140c38..f8d4ed90 100644 --- a/src/components/prose/GenerationThoughts.tsx +++ b/src/components/prose/GenerationThoughts.tsx @@ -1,3 +1,4 @@ +import { useEffect, useRef } from 'react' import { ChainOfThought, ChainOfThoughtContent, @@ -6,6 +7,23 @@ import { import { Loader2, Brain, Wrench, CheckCircle2, PenLine, FileText } from 'lucide-react' import { type ThoughtStep } from './InlineGenerationInput' +// Streaming text box that follows the bottom while active, unless the user scrolled up +function StreamingText({ text, active, className }: { text: string; active: boolean; className?: string }) { + const ref = useRef(null) + const stick = useRef(true) + + const onScroll = () => { + const el = ref.current + if (el) stick.current = el.scrollHeight - el.scrollTop - el.clientHeight < 24 + } + + useEffect(() => { + if (active && stick.current && ref.current) ref.current.scrollTop = ref.current.scrollHeight + }, [text, active]) + + return
{text}
+} + function formatToolName(name: string): string { return name .replace(/([A-Z])/g, ' $1') @@ -54,9 +72,11 @@ export function GenerationThoughts({ label="Thinking" status={isThinking && i === steps.length - 1 ? 'active' : 'complete'} > -
- {step.text} -
+ ) } @@ -69,9 +89,11 @@ export function GenerationThoughts({ label="Writing Brief" status={isActive ? 'active' : 'complete'} > -
- {step.text} -
+ ) }