Skip to content

Commit ebe294b

Browse files
authored
Merge pull request RooCodeInc#1200 from RooVetGit/cte/thinking-tweaks
Thinking settings tweaks
2 parents 1f86800 + 33fd3bd commit ebe294b

File tree

5 files changed

+54
-48
lines changed

5 files changed

+54
-48
lines changed

.changeset/swift-kings-attack.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"roo-cline": patch
3+
---
4+
5+
Pass "thinking" params to OpenRouter

src/api/providers/anthropic.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@ import { ApiStream } from "../transform/stream"
1414

1515
const ANTHROPIC_DEFAULT_TEMPERATURE = 0
1616

17-
const THINKING_MODELS = ["claude-3-7-sonnet-20250219"]
18-
1917
export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
2018
private options: ApiHandlerOptions
2119
private client: Anthropic
@@ -32,16 +30,19 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
3230
async *createMessage(systemPrompt: string, messages: Anthropic.Messages.MessageParam[]): ApiStream {
3331
let stream: AnthropicStream<Anthropic.Messages.RawMessageStreamEvent>
3432
const cacheControl: CacheControlEphemeral = { type: "ephemeral" }
35-
const modelId = this.getModel().id
36-
const maxTokens = this.getModel().info.maxTokens || 8192
33+
let { id: modelId, info: modelInfo } = this.getModel()
34+
const maxTokens = modelInfo.maxTokens || 8192
3735
let temperature = this.options.modelTemperature ?? ANTHROPIC_DEFAULT_TEMPERATURE
3836
let thinking: BetaThinkingConfigParam | undefined = undefined
3937

40-
if (THINKING_MODELS.includes(modelId)) {
41-
thinking = this.options.anthropicThinking
42-
? { type: "enabled", budget_tokens: this.options.anthropicThinking }
43-
: { type: "disabled" }
44-
38+
// Anthropic "Thinking" models require a temperature of 1.0.
39+
if (modelId === "claude-3-7-sonnet-20250219:thinking") {
40+
// The `:thinking` variant is a virtual identifier for the
41+
// `claude-3-7-sonnet-20250219` model with a thinking budget.
42+
// We can handle this more elegantly in the future.
43+
modelId = "claude-3-7-sonnet-20250219"
44+
const budgetTokens = this.options.anthropicThinking ?? Math.max(maxTokens * 0.8, 1024)
45+
thinking = { type: "enabled", budget_tokens: budgetTokens }
4546
temperature = 1.0
4647
}
4748

@@ -114,8 +115,8 @@ export class AnthropicHandler implements ApiHandler, SingleCompletionHandler {
114115
default: {
115116
stream = (await this.client.messages.create({
116117
model: modelId,
117-
max_tokens: this.getModel().info.maxTokens || 8192,
118-
temperature: this.options.modelTemperature ?? ANTHROPIC_DEFAULT_TEMPERATURE,
118+
max_tokens: maxTokens,
119+
temperature,
119120
system: [{ text: systemPrompt, type: "text" }],
120121
messages,
121122
// tools,

src/api/providers/openrouter.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Anthropic } from "@anthropic-ai/sdk"
2+
import { BetaThinkingConfigParam } from "@anthropic-ai/sdk/resources/beta"
23
import axios from "axios"
34
import OpenAI from "openai"
45
import delay from "delay"
@@ -17,6 +18,7 @@ const OPENROUTER_DEFAULT_TEMPERATURE = 0
1718
type OpenRouterChatCompletionParams = OpenAI.Chat.ChatCompletionCreateParams & {
1819
transforms?: string[]
1920
include_reasoning?: boolean
21+
thinking?: BetaThinkingConfigParam
2022
}
2123

2224
// Add custom interface for OpenRouter usage chunk.
@@ -57,7 +59,7 @@ export class OpenRouterHandler implements ApiHandler, SingleCompletionHandler {
5759
// prompt caching: https://openrouter.ai/docs/prompt-caching
5860
// this is specifically for claude models (some models may 'support prompt caching' automatically without this)
5961
switch (true) {
60-
case this.getModel().id.startsWith("anthropic/"):
62+
case modelId.startsWith("anthropic/"):
6163
openAiMessages[0] = {
6264
role: "system",
6365
content: [
@@ -107,9 +109,12 @@ export class OpenRouterHandler implements ApiHandler, SingleCompletionHandler {
107109
}
108110

109111
let temperature = this.options.modelTemperature ?? defaultTemperature
112+
let thinking: BetaThinkingConfigParam | undefined = undefined
110113

111-
// Anthropic "Thinking" models require a temperature of 1.0.
112114
if (modelInfo.thinking) {
115+
const maxTokens = modelInfo.maxTokens || 8192
116+
const budgetTokens = this.options.anthropicThinking ?? Math.max(maxTokens * 0.8, 1024)
117+
thinking = { type: "enabled", budget_tokens: budgetTokens }
113118
temperature = 1.0
114119
}
115120

@@ -120,6 +125,7 @@ export class OpenRouterHandler implements ApiHandler, SingleCompletionHandler {
120125
model: modelId,
121126
max_tokens: modelInfo.maxTokens,
122127
temperature,
128+
thinking, // OpenRouter is temporarily supporting this.
123129
top_p: topP,
124130
messages: openAiMessages,
125131
stream: true,

src/shared/api.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export const THINKING_BUDGET = {
103103
export type AnthropicModelId = keyof typeof anthropicModels
104104
export const anthropicDefaultModelId: AnthropicModelId = "claude-3-7-sonnet-20250219"
105105
export const anthropicModels = {
106-
"claude-3-7-sonnet-20250219": {
106+
"claude-3-7-sonnet-20250219:thinking": {
107107
maxTokens: 16384,
108108
contextWindow: 200_000,
109109
supportsImages: true,
@@ -115,6 +115,18 @@ export const anthropicModels = {
115115
cacheReadsPrice: 0.3, // $0.30 per million tokens
116116
thinking: true,
117117
},
118+
"claude-3-7-sonnet-20250219": {
119+
maxTokens: 16384,
120+
contextWindow: 200_000,
121+
supportsImages: true,
122+
supportsComputerUse: true,
123+
supportsPromptCache: true,
124+
inputPrice: 3.0, // $3 per million input tokens
125+
outputPrice: 15.0, // $15 per million output tokens
126+
cacheWritesPrice: 3.75, // $3.75 per million tokens
127+
cacheReadsPrice: 0.3, // $0.30 per million tokens
128+
thinking: false,
129+
},
118130
"claude-3-5-sonnet-20241022": {
119131
maxTokens: 8192,
120132
contextWindow: 200_000,

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

Lines changed: 16 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ const ApiOptions = ({
7373
const [openRouterBaseUrlSelected, setOpenRouterBaseUrlSelected] = useState(!!apiConfiguration?.openRouterBaseUrl)
7474
const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false)
7575

76-
const anthropicThinkingBudget = apiConfiguration?.anthropicThinking
76+
const anthropicThinkingBudget = apiConfiguration?.anthropicThinking ?? THINKING_BUDGET.default
7777

7878
const noTransform = <T,>(value: T) => value
7979
const inputEventTransform = <E,>(event: E) => (event as { target: HTMLInputElement })?.target?.value as any
@@ -1272,39 +1272,21 @@ const ApiOptions = ({
12721272
)}
12731273

12741274
{selectedModelInfo && selectedModelInfo.thinking && (
1275-
<div className="flex flex-col gap-2 mt-2">
1276-
<Checkbox
1277-
checked={!!anthropicThinkingBudget}
1278-
onChange={(checked) =>
1279-
setApiConfigurationField(
1280-
"anthropicThinking",
1281-
checked
1282-
? Math.min(
1283-
THINKING_BUDGET.default,
1284-
selectedModelInfo.maxTokens ?? THINKING_BUDGET.default,
1285-
)
1286-
: undefined,
1287-
)
1288-
}>
1289-
Thinking?
1290-
</Checkbox>
1291-
{anthropicThinkingBudget && (
1292-
<>
1293-
<div className="text-muted-foreground text-sm">
1294-
Number of tokens Claude is allowed to use for its internal reasoning process.
1295-
</div>
1296-
<div className="flex items-center gap-2">
1297-
<Slider
1298-
min={THINKING_BUDGET.min}
1299-
max={(selectedModelInfo.maxTokens ?? THINKING_BUDGET.default) - 1}
1300-
step={THINKING_BUDGET.step}
1301-
value={[anthropicThinkingBudget]}
1302-
onValueChange={(value) => setApiConfigurationField("anthropicThinking", value[0])}
1303-
/>
1304-
<div className="w-12">{anthropicThinkingBudget}</div>
1305-
</div>
1306-
</>
1307-
)}
1275+
<div className="flex flex-col gap-1 mt-2">
1276+
<div className="font-medium">Thinking Budget</div>
1277+
<div className="flex items-center gap-1">
1278+
<Slider
1279+
min={THINKING_BUDGET.min}
1280+
max={(selectedModelInfo.maxTokens ?? THINKING_BUDGET.default) - 1}
1281+
step={THINKING_BUDGET.step}
1282+
value={[anthropicThinkingBudget]}
1283+
onValueChange={(value) => setApiConfigurationField("anthropicThinking", value[0])}
1284+
/>
1285+
<div className="w-12 text-sm text-center">{anthropicThinkingBudget}</div>
1286+
</div>
1287+
<div className="text-muted-foreground text-sm">
1288+
Number of tokens Claude is allowed to use for its internal reasoning process.
1289+
</div>
13081290
</div>
13091291
)}
13101292

0 commit comments

Comments
 (0)