Skip to content

Commit 00afe75

Browse files
committed
ui(reasoning): simplify ReasoningBlock to italic content only; remove timer/header/icons and inline styles; align ChatRow props; type-safe updateMessageReasoningMeta; remove added logging
1 parent ea322fd commit 00afe75

File tree

3 files changed

+21
-100
lines changed

3 files changed

+21
-100
lines changed

src/core/webview/webviewMessageHandler.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2866,7 +2866,7 @@ export const webviewMessageHandler = async (
28662866
break
28672867
}
28682868
case "updateMessageReasoningMeta": {
2869-
// Persist reasoning timer metadata on a specific message (by ts)
2869+
// Persist reasoning metadata on a specific message (by ts)
28702870
try {
28712871
const currentCline = provider.getCurrentTask()
28722872
if (!currentCline || !message.messageTs) {
@@ -2876,21 +2876,28 @@ export const webviewMessageHandler = async (
28762876
if (messageIndex === -1) {
28772877
break
28782878
}
2879-
const msg = currentCline.clineMessages[messageIndex] as any
2880-
const existingMeta = (msg.metadata as any) || {}
2881-
const existingReasoning = existingMeta.reasoning || {}
2882-
msg.metadata = {
2879+
2880+
type ReasoningMeta = { startedAt?: number; elapsedMs?: number }
2881+
type MetadataWithReasoning = Record<string, unknown> & { reasoning?: ReasoningMeta }
2882+
2883+
const msg = currentCline.clineMessages[messageIndex] as ClineMessage
2884+
const existingMeta = (msg.metadata as MetadataWithReasoning | undefined) ?? {}
2885+
const existingReasoning = existingMeta.reasoning ?? {}
2886+
2887+
const updatedMeta: MetadataWithReasoning = {
28832888
...existingMeta,
2884-
reasoning: { ...existingReasoning, ...(message.reasoningMeta || {}) },
2889+
reasoning: { ...existingReasoning, ...(message.reasoningMeta ?? {}) },
28852890
}
28862891

2892+
;(msg as unknown as { metadata?: MetadataWithReasoning }).metadata = updatedMeta
2893+
28872894
await saveTaskMessages({
28882895
messages: currentCline.clineMessages,
28892896
taskId: currentCline.taskId,
28902897
globalStoragePath: provider.contextProxy.globalStorageUri.fsPath,
28912898
})
2892-
} catch (error) {
2893-
console.error("[updateMessageReasoningMeta] Failed to persist reasoning metadata:", error)
2899+
} catch {
2900+
/* noop */
28942901
}
28952902
break
28962903
}

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1083,15 +1083,7 @@ export const ChatRowContent = ({
10831083
</div>
10841084
)
10851085
case "reasoning":
1086-
return (
1087-
<ReasoningBlock
1088-
content={message.text || ""}
1089-
ts={message.ts}
1090-
isStreaming={isStreaming}
1091-
isLast={isLast}
1092-
metadata={message.metadata as any}
1093-
/>
1094-
)
1086+
return <ReasoningBlock content={message.text || ""} />
10951087
case "api_req_started":
10961088
return (
10971089
<>
Lines changed: 5 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,15 @@
1-
import React, { useEffect, useMemo, useRef, useState } from "react"
2-
import { useTranslation } from "react-i18next"
3-
1+
import React from "react"
42
import MarkdownBlock from "../common/MarkdownBlock"
5-
import { vscode } from "@src/utils/vscode"
63

74
interface ReasoningBlockProps {
85
content: string
9-
ts: number
10-
isStreaming: boolean
11-
isLast: boolean
12-
metadata?: Record<string, any>
136
}
147

15-
/**
16-
* Render reasoning with a heading and a persistent timer.
17-
* - Heading uses i18n key chat:reasoning.thinking
18-
* - Timer shown as "(⟲ 24s)" beside the heading and persists via message.metadata.reasoning { startedAt, elapsedMs }
19-
*/
20-
export const ReasoningBlock = ({ content, ts, isStreaming, isLast, metadata }: ReasoningBlockProps) => {
21-
const { t } = useTranslation()
22-
23-
const persisted = (metadata?.reasoning as { startedAt?: number; elapsedMs?: number } | undefined) || {}
24-
const startedAtRef = useRef<number>(persisted.startedAt ?? Date.now())
25-
const [elapsed, setElapsed] = useState<number>(persisted.elapsedMs ?? 0)
26-
27-
// Initialize startedAt on first mount if missing (persist to task)
28-
useEffect(() => {
29-
if (!persisted.startedAt && isLast) {
30-
vscode.postMessage({
31-
type: "updateMessageReasoningMeta",
32-
messageTs: ts,
33-
reasoningMeta: { startedAt: startedAtRef.current },
34-
} as any)
35-
}
36-
// eslint-disable-next-line react-hooks/exhaustive-deps
37-
}, [ts])
38-
39-
// Tick while active (last row and streaming)
40-
useEffect(() => {
41-
const active = isLast && isStreaming
42-
if (!active) return
43-
44-
const tick = () => setElapsed(Date.now() - startedAtRef.current)
45-
tick()
46-
const id = setInterval(tick, 1000)
47-
return () => clearInterval(id)
48-
}, [isLast, isStreaming])
49-
50-
// Persist final elapsed when streaming stops
51-
const wasActiveRef = useRef<boolean>(false)
52-
useEffect(() => {
53-
const active = isLast && isStreaming
54-
if (wasActiveRef.current && !active) {
55-
const finalMs = Date.now() - startedAtRef.current
56-
setElapsed(finalMs)
57-
vscode.postMessage({
58-
type: "updateMessageReasoningMeta",
59-
messageTs: ts,
60-
reasoningMeta: { startedAt: startedAtRef.current, elapsedMs: finalMs },
61-
} as any)
62-
}
63-
wasActiveRef.current = active
64-
}, [isLast, isStreaming, ts])
65-
66-
const displayMs = useMemo(() => {
67-
if (isLast && isStreaming) return elapsed
68-
return persisted.elapsedMs ?? elapsed
69-
}, [elapsed, isLast, isStreaming, persisted.elapsedMs])
70-
71-
const seconds = Math.max(0, Math.floor((displayMs || 0) / 1000))
72-
const secondsLabel = t("chat:reasoning.seconds", { count: seconds })
73-
8+
export const ReasoningBlock = ({ content }: ReasoningBlockProps) => {
9+
if (!content?.trim()) return null
7410
return (
75-
<div className="py-1">
76-
<div className="flex items-center justify-between mb-[10px]">
77-
<div className="flex items-center gap-2">
78-
<span className="codicon codicon-light-bulb" style={{ color: "var(--vscode-charts-yellow)" }} />
79-
<span className="font-bold text-vscode-foreground">{t("chat:reasoning.thinking")}</span>
80-
</div>
81-
<span className="text-vscode-foreground tabular-nums flex items-center gap-1">
82-
<span className="codicon codicon-clock" style={{ fontSize: "inherit" }} />
83-
{secondsLabel}
84-
</span>
85-
</div>
86-
{(content?.trim()?.length ?? 0) > 0 && (
87-
<div className="px-3 italic text-vscode-descriptionForeground">
88-
<MarkdownBlock markdown={content} />
89-
</div>
90-
)}
11+
<div className="px-3 py-1 italic text-vscode-descriptionForeground">
12+
<MarkdownBlock markdown={content} />
9113
</div>
9214
)
9315
}

0 commit comments

Comments
 (0)