Skip to content

Commit ab958bf

Browse files
committed
feat(ui): render reasoning as plain italic text to match <thinking> style; remove bounding container
1 parent 18cf33f commit ab958bf

File tree

2 files changed

+9
-97
lines changed

2 files changed

+9
-97
lines changed

webview-ui/src/components/chat/ChatRow.tsx

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,6 @@ export const ChatRowContent = ({
118118

119119
const { mcpServers, alwaysAllowMcp, currentCheckpoint, mode, apiConfiguration } = useExtensionState()
120120
const { info: model } = useSelectedModel(apiConfiguration)
121-
const [reasoningCollapsed, setReasoningCollapsed] = useState(true)
122121
const [isDiffErrorExpanded, setIsDiffErrorExpanded] = useState(false)
123122
const [showCopySuccess, setShowCopySuccess] = useState(false)
124123
const [isEditing, setIsEditing] = useState(false)
@@ -1084,14 +1083,7 @@ export const ChatRowContent = ({
10841083
</div>
10851084
)
10861085
case "reasoning":
1087-
return (
1088-
<ReasoningBlock
1089-
content={message.text || ""}
1090-
elapsed={isLast && isStreaming ? Date.now() - message.ts : undefined}
1091-
isCollapsed={reasoningCollapsed}
1092-
onToggleCollapse={() => setReasoningCollapsed(!reasoningCollapsed)}
1093-
/>
1094-
)
1086+
return <ReasoningBlock content={message.text || ""} />
10951087
case "api_req_started":
10961088
return (
10971089
<>
Lines changed: 8 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,19 @@
1-
import { useCallback, useEffect, useRef, useState } from "react"
2-
import { CaretDownIcon, CaretUpIcon, CounterClockwiseClockIcon } from "@radix-ui/react-icons"
3-
import { useTranslation } from "react-i18next"
4-
51
import MarkdownBlock from "../common/MarkdownBlock"
6-
import { useMount } from "react-use"
72

83
interface ReasoningBlockProps {
94
content: string
10-
elapsed?: number
11-
isCollapsed?: boolean
12-
onToggleCollapse?: () => void
135
}
146

15-
export const ReasoningBlock = ({ content, elapsed, isCollapsed = false, onToggleCollapse }: ReasoningBlockProps) => {
16-
const contentRef = useRef<HTMLDivElement>(null)
17-
const elapsedRef = useRef<number>(0)
18-
const { t } = useTranslation("chat")
19-
const [thought, setThought] = useState<string>()
20-
const [prevThought, setPrevThought] = useState<string>(t("chat:reasoning.thinking"))
21-
const [isTransitioning, setIsTransitioning] = useState<boolean>(false)
22-
const cursorRef = useRef<number>(0)
23-
const queueRef = useRef<string[]>([])
24-
25-
useEffect(() => {
26-
if (contentRef.current && !isCollapsed) {
27-
contentRef.current.scrollTop = contentRef.current.scrollHeight
28-
}
29-
}, [content, isCollapsed])
30-
31-
useEffect(() => {
32-
if (elapsed) {
33-
elapsedRef.current = elapsed
34-
}
35-
}, [elapsed])
36-
37-
// Process the transition queue.
38-
const processNextTransition = useCallback(() => {
39-
const nextThought = queueRef.current.pop()
40-
queueRef.current = []
41-
42-
if (nextThought) {
43-
setIsTransitioning(true)
44-
}
45-
46-
setTimeout(() => {
47-
if (nextThought) {
48-
setPrevThought(nextThought)
49-
setIsTransitioning(false)
50-
}
51-
52-
setTimeout(() => processNextTransition(), 500)
53-
}, 200)
54-
}, [])
55-
56-
useMount(() => {
57-
processNextTransition()
58-
})
59-
60-
useEffect(() => {
61-
if (content.length - cursorRef.current > 160) {
62-
setThought("... " + content.slice(cursorRef.current))
63-
cursorRef.current = content.length
64-
}
65-
}, [content])
66-
67-
useEffect(() => {
68-
if (thought && thought !== prevThought) {
69-
queueRef.current.push(thought)
70-
}
71-
}, [thought, prevThought])
72-
7+
/**
8+
* Render reasoning as simple italic text, matching how <thinking> content is shown.
9+
* No borders, boxes, headers, timers, or collapsible behavior.
10+
*/
11+
export const ReasoningBlock = ({ content }: ReasoningBlockProps) => {
7312
return (
74-
<div className="bg-vscode-editor-background border border-vscode-border rounded-xs overflow-hidden">
75-
<div
76-
className="flex items-center justify-between gap-1 px-3 py-2 cursor-pointer text-muted-foreground"
77-
onClick={onToggleCollapse}>
78-
<div
79-
className={`truncate flex-1 transition-opacity duration-200 ${isTransitioning ? "opacity-0" : "opacity-100"}`}>
80-
{prevThought}
81-
</div>
82-
<div className="flex flex-row items-center gap-1">
83-
{elapsedRef.current > 1000 && (
84-
<>
85-
<CounterClockwiseClockIcon className="scale-80" />
86-
<div>{t("reasoning.seconds", { count: Math.round(elapsedRef.current / 1000) })}</div>
87-
</>
88-
)}
89-
{isCollapsed ? <CaretDownIcon /> : <CaretUpIcon />}
90-
</div>
13+
<div className="px-3 py-1">
14+
<div className="italic text-muted-foreground">
15+
<MarkdownBlock markdown={content} />
9116
</div>
92-
{!isCollapsed && (
93-
<div ref={contentRef} className="px-3 max-h-[160px] overflow-y-auto">
94-
<MarkdownBlock markdown={content} />
95-
</div>
96-
)}
9717
</div>
9818
)
9919
}

0 commit comments

Comments
 (0)