From f21bcb22a66cb8fa148fd556c040136edaeb7f74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Garc=C3=ADa=20Rey?= Date: Wed, 2 Apr 2025 04:07:30 +0200 Subject: [PATCH] feat: Add extended thinking for LiteLLM provider (#2615) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add extended thinking slider to LiteLLM provider Signed-off-by: Jorge García Rey * feat: add changeset Signed-off-by: Jorge García Rey * fix: format Signed-off-by: Jorge García Rey --------- Signed-off-by: Jorge García Rey --- .changeset/clever-eggs-perform.md | 5 ++++ src/api/providers/litellm.ts | 27 +++++++++++++++++-- .../src/components/settings/ApiOptions.tsx | 18 +++++++++++++ .../settings/ThinkingBudgetSlider.tsx | 12 +++++++-- 4 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 .changeset/clever-eggs-perform.md diff --git a/.changeset/clever-eggs-perform.md b/.changeset/clever-eggs-perform.md new file mode 100644 index 0000000000..560f72f8a8 --- /dev/null +++ b/.changeset/clever-eggs-perform.md @@ -0,0 +1,5 @@ +--- +"claude-dev": minor +--- + +Add Enable extended thinking for LiteLLM provider diff --git a/src/api/providers/litellm.ts b/src/api/providers/litellm.ts index 9acf4bb6ce..74184a9b54 100644 --- a/src/api/providers/litellm.ts +++ b/src/api/providers/litellm.ts @@ -59,10 +59,16 @@ export class LiteLlmHandler implements ApiHandler { } const modelId = this.options.liteLlmModelId || liteLlmDefaultModelId const isOminiModel = modelId.includes("o1-mini") || modelId.includes("o3-mini") + + // Configuration for extended thinking + const budgetTokens = this.options.thinkingBudgetTokens || 0 + const reasoningOn = budgetTokens !== 0 ? true : false + const thinkingConfig = reasoningOn ? { type: "enabled", budget_tokens: budgetTokens } : undefined + let temperature: number | undefined = 0 - if (isOminiModel) { - temperature = undefined // does not support temperature + if (isOminiModel && reasoningOn) { + temperature = undefined // Thinking mode doesn't support temperature } const stream = await this.client.chat.completions.create({ @@ -71,6 +77,7 @@ export class LiteLlmHandler implements ApiHandler { temperature, stream: true, stream_options: { include_usage: true }, + ...(thinkingConfig && { thinking: thinkingConfig }), // Add thinking configuration when applicable }) const inputCost = (await this.calculateCost(1e6, 0)) || 0 @@ -78,6 +85,8 @@ export class LiteLlmHandler implements ApiHandler { for await (const chunk of stream) { const delta = chunk.choices[0]?.delta + + // Handle normal text content if (delta?.content) { yield { type: "text", @@ -85,6 +94,20 @@ export class LiteLlmHandler implements ApiHandler { } } + // Handle reasoning events (thinking) + // Thinking is not in the standard types but may be in the response + interface ThinkingDelta { + thinking?: string + } + + if ((delta as ThinkingDelta)?.thinking) { + yield { + type: "reasoning", + reasoning: (delta as ThinkingDelta).thinking || "", + } + } + + // Handle token usage information if (chunk.usage) { const totalCost = (inputCost * chunk.usage.prompt_tokens) / 1e6 + (outputCost * chunk.usage.completion_tokens) / 1e6 diff --git a/webview-ui/src/components/settings/ApiOptions.tsx b/webview-ui/src/components/settings/ApiOptions.tsx index 5d24ed899d..04cd31b255 100644 --- a/webview-ui/src/components/settings/ApiOptions.tsx +++ b/webview-ui/src/components/settings/ApiOptions.tsx @@ -1205,6 +1205,24 @@ const ApiOptions = ({ showModelOptions, apiErrorMessage, modelIdErrorMessage, is placeholder={"e.g. gpt-4"}> Model ID + + <> + +

+ Extended thinking is available for models as Sonnet-3-7, o3-mini, Deepseek R1, etc. More info on{" "} + + thinking mode configuration + +

+ +

- - Higher budgets may allow you to achieve more comprehensive and nuanced reasoning + + Higher budgets may allow you to achieve more comprehensive and nuanced reasoning + )}