Skip to content

Commit f21bcb2

Browse files
feat: Add extended thinking for LiteLLM provider (RooCodeInc#2615)
* feat: add extended thinking slider to LiteLLM provider Signed-off-by: Jorge García Rey <[email protected]> * feat: add changeset Signed-off-by: Jorge García Rey <[email protected]> * fix: format Signed-off-by: Jorge García Rey <[email protected]> --------- Signed-off-by: Jorge García Rey <[email protected]>
1 parent d490029 commit f21bcb2

File tree

4 files changed

+58
-4
lines changed

4 files changed

+58
-4
lines changed

.changeset/clever-eggs-perform.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"claude-dev": minor
3+
---
4+
5+
Add Enable extended thinking for LiteLLM provider

src/api/providers/litellm.ts

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,16 @@ export class LiteLlmHandler implements ApiHandler {
5959
}
6060
const modelId = this.options.liteLlmModelId || liteLlmDefaultModelId
6161
const isOminiModel = modelId.includes("o1-mini") || modelId.includes("o3-mini")
62+
63+
// Configuration for extended thinking
64+
const budgetTokens = this.options.thinkingBudgetTokens || 0
65+
const reasoningOn = budgetTokens !== 0 ? true : false
66+
const thinkingConfig = reasoningOn ? { type: "enabled", budget_tokens: budgetTokens } : undefined
67+
6268
let temperature: number | undefined = 0
6369

64-
if (isOminiModel) {
65-
temperature = undefined // does not support temperature
70+
if (isOminiModel && reasoningOn) {
71+
temperature = undefined // Thinking mode doesn't support temperature
6672
}
6773

6874
const stream = await this.client.chat.completions.create({
@@ -71,20 +77,37 @@ export class LiteLlmHandler implements ApiHandler {
7177
temperature,
7278
stream: true,
7379
stream_options: { include_usage: true },
80+
...(thinkingConfig && { thinking: thinkingConfig }), // Add thinking configuration when applicable
7481
})
7582

7683
const inputCost = (await this.calculateCost(1e6, 0)) || 0
7784
const outputCost = (await this.calculateCost(0, 1e6)) || 0
7885

7986
for await (const chunk of stream) {
8087
const delta = chunk.choices[0]?.delta
88+
89+
// Handle normal text content
8190
if (delta?.content) {
8291
yield {
8392
type: "text",
8493
text: delta.content,
8594
}
8695
}
8796

97+
// Handle reasoning events (thinking)
98+
// Thinking is not in the standard types but may be in the response
99+
interface ThinkingDelta {
100+
thinking?: string
101+
}
102+
103+
if ((delta as ThinkingDelta)?.thinking) {
104+
yield {
105+
type: "reasoning",
106+
reasoning: (delta as ThinkingDelta).thinking || "",
107+
}
108+
}
109+
110+
// Handle token usage information
88111
if (chunk.usage) {
89112
const totalCost =
90113
(inputCost * chunk.usage.prompt_tokens) / 1e6 + (outputCost * chunk.usage.completion_tokens) / 1e6

webview-ui/src/components/settings/ApiOptions.tsx

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,24 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is
12051205
placeholder={"e.g. gpt-4"}>
12061206
<span style={{ fontWeight: 500 }}>Model ID</span>
12071207
</VSCodeTextField>
1208+
1209+
<>
1210+
<ThinkingBudgetSlider apiConfiguration={apiConfiguration} setApiConfiguration={setApiConfiguration} />
1211+
<p
1212+
style={{
1213+
fontSize: "12px",
1214+
marginTop: "5px",
1215+
color: "var(--vscode-charts-green)",
1216+
}}>
1217+
Extended thinking is available for models as Sonnet-3-7, o3-mini, Deepseek R1, etc. More info on{" "}
1218+
<VSCodeLink
1219+
href="https://docs.litellm.ai/docs/reasoning_content"
1220+
style={{ display: "inline", fontSize: "inherit" }}>
1221+
thinking mode configuration
1222+
</VSCodeLink>
1223+
</p>
1224+
</>
1225+
12081226
<p
12091227
style={{
12101228
fontSize: "12px",

webview-ui/src/components/settings/ThinkingBudgetSlider.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,11 +123,12 @@ const ThinkingBudgetSlider = ({ apiConfiguration, setApiConfiguration }: Thinkin
123123
{isEnabled && (
124124
<>
125125
<LabelContainer>
126-
<Label>
126+
<Label htmlFor="thinking-budget-slider">
127127
<strong>Budget:</strong> {localValue.toLocaleString()} tokens
128128
</Label>
129129
</LabelContainer>
130130
<RangeInput
131+
id="thinking-budget-slider"
131132
type="range"
132133
min={MIN_VALID_TOKENS}
133134
max={maxSliderValue}
@@ -139,9 +140,16 @@ const ThinkingBudgetSlider = ({ apiConfiguration, setApiConfiguration }: Thinkin
139140
$value={localValue}
140141
$min={MIN_VALID_TOKENS}
141142
$max={maxSliderValue}
143+
aria-label={`Thinking budget: ${localValue.toLocaleString()} tokens`}
144+
aria-valuemin={MIN_VALID_TOKENS}
145+
aria-valuemax={maxSliderValue}
146+
aria-valuenow={localValue}
147+
aria-describedby="thinking-budget-description"
142148
/>
143149

144-
<Description>Higher budgets may allow you to achieve more comprehensive and nuanced reasoning</Description>
150+
<Description id="thinking-budget-description">
151+
Higher budgets may allow you to achieve more comprehensive and nuanced reasoning
152+
</Description>
145153
</>
146154
)}
147155
</Container>

0 commit comments

Comments
 (0)