Skip to content

Commit 5f7999d

Browse files
authored
Merge branch 'RooCodeInc:main' into FCO-only
2 parents 3c3d39c + 7cd6520 commit 5f7999d

File tree

7 files changed

+47
-96
lines changed

7 files changed

+47
-96
lines changed

apps/web-roo-code/src/app/evals/plot.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,13 +175,13 @@ export const Plot = ({ tableData }: PlotProps) => {
175175
<>
176176
<div className="pt-4 pb-8 font-mono">Cost x Score</div>
177177
<ChartContainer config={chartConfig} className="h-[500px] w-full">
178-
<ScatterChart margin={{ top: 0, right: 0, bottom: 0, left: 20 }}>
178+
<ScatterChart margin={{ top: 20, right: 0, bottom: 0, left: 20 }}>
179179
<XAxis
180180
type="number"
181181
dataKey="cost"
182182
name="Cost"
183183
domain={[
184-
(dataMin: number) => Math.round((dataMin - 5) / 5) * 5,
184+
(dataMin: number) => Math.max(0, Math.round((dataMin - 5) / 5) * 5),
185185
(dataMax: number) => Math.round((dataMax + 5) / 5) * 5,
186186
]}
187187
tickFormatter={(value) => formatCurrency(value)}

packages/types/npm/package.metadata.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@roo-code/types",
3-
"version": "1.74.0",
3+
"version": "1.75.0",
44
"description": "TypeScript type definitions for Roo Code.",
55
"publishConfig": {
66
"access": "public",

packages/types/src/cloud.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ export type UserFeatures = z.infer<typeof userFeaturesSchema>
162162

163163
export const userSettingsConfigSchema = z.object({
164164
extensionBridgeEnabled: z.boolean().optional(),
165+
taskSyncEnabled: z.boolean().optional(),
165166
})
166167

167168
export type UserSettingsConfig = z.infer<typeof userSettingsConfigSchema>

src/api/providers/__tests__/groq.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ describe("GroqHandler", () => {
149149
expect(firstChunk.done).toBe(false)
150150
expect(firstChunk.value).toMatchObject({
151151
type: "usage",
152-
inputTokens: 70, // 100 total - 30 cached
152+
inputTokens: 100,
153153
outputTokens: 50,
154154
cacheWriteTokens: 0,
155155
cacheReadTokens: 30,

src/api/providers/groq.ts

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,20 +66,9 @@ export class GroqHandler extends BaseOpenAiCompatibleProvider<GroqModelId> {
6666
// Calculate cost using OpenAI-compatible cost calculation
6767
const totalCost = calculateApiCostOpenAI(info, inputTokens, outputTokens, cacheWriteTokens, cacheReadTokens)
6868

69-
// Calculate non-cached input tokens for proper reporting
70-
const nonCachedInputTokens = Math.max(0, inputTokens - cacheReadTokens - cacheWriteTokens)
71-
72-
console.log("usage", {
73-
inputTokens: nonCachedInputTokens,
74-
outputTokens,
75-
cacheWriteTokens,
76-
cacheReadTokens,
77-
totalCost,
78-
})
79-
8069
yield {
8170
type: "usage",
82-
inputTokens: nonCachedInputTokens,
71+
inputTokens,
8372
outputTokens,
8473
cacheWriteTokens,
8574
cacheReadTokens,

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

Lines changed: 4 additions & 4 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)
@@ -1087,9 +1086,10 @@ export const ChatRowContent = ({
10871086
return (
10881087
<ReasoningBlock
10891088
content={message.text || ""}
1090-
elapsed={isLast && isStreaming ? Date.now() - message.ts : undefined}
1091-
isCollapsed={reasoningCollapsed}
1092-
onToggleCollapse={() => setReasoningCollapsed(!reasoningCollapsed)}
1089+
ts={message.ts}
1090+
isStreaming={isStreaming}
1091+
isLast={isLast}
1092+
metadata={message.metadata as any}
10931093
/>
10941094
)
10951095
case "api_req_started":

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

Lines changed: 37 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,57 @@
1-
import { useCallback, useEffect, useRef, useState } from "react"
2-
import { CaretDownIcon, CaretUpIcon, CounterClockwiseClockIcon } from "@radix-ui/react-icons"
1+
import React, { useEffect, useRef, useState } from "react"
32
import { useTranslation } from "react-i18next"
43

54
import MarkdownBlock from "../common/MarkdownBlock"
6-
import { useMount } from "react-use"
5+
import { Clock, Lightbulb } from "lucide-react"
76

87
interface ReasoningBlockProps {
98
content: string
10-
elapsed?: number
11-
isCollapsed?: boolean
12-
onToggleCollapse?: () => void
9+
ts: number
10+
isStreaming: boolean
11+
isLast: boolean
12+
metadata?: any
1313
}
1414

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[]>([])
15+
/**
16+
* Render reasoning with a heading and a simple timer.
17+
* - Heading uses i18n key chat:reasoning.thinking
18+
* - Timer runs while reasoning is active (no persistence)
19+
*/
20+
export const ReasoningBlock = ({ content, isStreaming, isLast }: ReasoningBlockProps) => {
21+
const { t } = useTranslation()
2422

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-
})
23+
const startTimeRef = useRef<number>(Date.now())
24+
const [elapsed, setElapsed] = useState<number>(0)
5925

26+
// Simple timer that runs while streaming
6027
useEffect(() => {
61-
if (content.length - cursorRef.current > 160) {
62-
setThought("... " + content.slice(cursorRef.current))
63-
cursorRef.current = content.length
28+
if (isLast && isStreaming) {
29+
const tick = () => setElapsed(Date.now() - startTimeRef.current)
30+
tick()
31+
const id = setInterval(tick, 1000)
32+
return () => clearInterval(id)
6433
}
65-
}, [content])
34+
}, [isLast, isStreaming])
6635

67-
useEffect(() => {
68-
if (thought && thought !== prevThought) {
69-
queueRef.current.push(thought)
70-
}
71-
}, [thought, prevThought])
36+
const seconds = Math.floor(elapsed / 1000)
37+
const secondsLabel = t("chat:reasoning.seconds", { count: seconds })
7238

7339
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 />}
40+
<div className="py-1">
41+
<div className="flex items-center justify-between mb-2.5 pr-2">
42+
<div className="flex items-center gap-2">
43+
<Lightbulb className="w-4" />
44+
<span className="font-bold text-vscode-foreground">{t("chat:reasoning.thinking")}</span>
9045
</div>
46+
{elapsed > 0 && (
47+
<span className="text-vscode-foreground tabular-nums flex items-center gap-1">
48+
<Clock className="w-4" />
49+
{secondsLabel}
50+
</span>
51+
)}
9152
</div>
92-
{!isCollapsed && (
93-
<div ref={contentRef} className="px-3 max-h-[160px] overflow-y-auto">
53+
{(content?.trim()?.length ?? 0) > 0 && (
54+
<div className="px-3 italic text-vscode-descriptionForeground">
9455
<MarkdownBlock markdown={content} />
9556
</div>
9657
)}

0 commit comments

Comments
 (0)