Skip to content

Commit bcb4275

Browse files
committed
Refactor reasoning budget settings and update localization for reasoning effort
1 parent 7ee90f9 commit bcb4275

File tree

33 files changed

+165
-98
lines changed

33 files changed

+165
-98
lines changed

evals/packages/types/src/roo-code.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ const genericProviderSettingsSchema = z.object({
340340
rateLimitSeconds: z.number().optional(),
341341

342342
// Model reasoning.
343-
enableReasoningEffort: z.boolean().optional(),
343+
setReasoningEffort: z.boolean().optional(),
344344
reasoningEffort: reasoningEffortsSchema.optional(),
345345
modelMaxTokens: z.number().optional(),
346346
modelMaxThinkingTokens: z.number().optional(),
@@ -395,7 +395,7 @@ const openAiSchema = z.object({
395395
openAiUseAzure: z.boolean().optional(),
396396
azureApiVersion: z.string().optional(),
397397
openAiStreamingEnabled: z.boolean().optional(),
398-
enableReasoningEffort: z.boolean().optional(),
398+
setReasoningEffort: z.boolean().optional(),
399399
openAiHostHeader: z.string().optional(), // Keep temporarily for backward compatibility during migration.
400400
openAiHeaders: z.record(z.string(), z.string()).optional(),
401401
})
@@ -663,7 +663,7 @@ const providerSettingsRecord: ProviderSettingsRecord = {
663663
openAiUseAzure: undefined,
664664
azureApiVersion: undefined,
665665
openAiStreamingEnabled: undefined,
666-
enableReasoningEffort: undefined,
666+
setReasoningEffort: undefined,
667667
openAiHostHeader: undefined, // Keep temporarily for backward compatibility during migration
668668
openAiHeaders: undefined,
669669
// Ollama

packages/types/src/provider-settings.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ const baseProviderSettingsSchema = z.object({
6060
rateLimitSeconds: z.number().optional(),
6161

6262
// Model reasoning.
63-
enableReasoningEffort: z.boolean().optional(),
63+
setReasoningEffort: z.boolean().optional(),
6464
reasoningEffort: reasoningEffortsSchema.optional(),
6565
modelMaxTokens: z.number().optional(),
6666
modelMaxThinkingTokens: z.number().optional(),
@@ -331,7 +331,7 @@ export const PROVIDER_SETTINGS_KEYS = keysOf<ProviderSettings>()([
331331
"codeIndexOpenAiKey",
332332
"codeIndexQdrantApiKey",
333333
// Reasoning
334-
"enableReasoningEffort",
334+
"setReasoningEffort",
335335
"reasoningEffort",
336336
"modelMaxTokens",
337337
"modelMaxThinkingTokens",

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ describe("OpenAiHandler", () => {
162162
it("should include reasoning_effort when reasoning effort is enabled", async () => {
163163
const reasoningOptions: ApiHandlerOptions = {
164164
...mockOptions,
165-
enableReasoningEffort: true,
165+
setReasoningEffort: true,
166166
openAiCustomModelInfo: {
167167
contextWindow: 128_000,
168168
supportsPromptCache: false,
@@ -184,7 +184,7 @@ describe("OpenAiHandler", () => {
184184
it("should not include reasoning_effort when reasoning effort is disabled", async () => {
185185
const noReasoningOptions: ApiHandlerOptions = {
186186
...mockOptions,
187-
enableReasoningEffort: false,
187+
setReasoningEffort: false,
188188
openAiCustomModelInfo: { contextWindow: 128_000, supportsPromptCache: false },
189189
}
190190
const noReasoningHandler = new OpenAiHandler(noReasoningOptions)

src/api/providers/gemini.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,10 @@ export class GeminiHandler extends BaseProvider implements SingleCompletionHandl
120120
return {
121121
id,
122122
info,
123-
thinkingConfig: this.options.modelMaxThinkingTokens
124-
? { thinkingBudget: this.options.modelMaxThinkingTokens }
125-
: undefined,
123+
thinkingConfig:
124+
this.options.setReasoningEffort && this.options.modelMaxThinkingTokens !== undefined
125+
? { thinkingBudget: this.options.modelMaxThinkingTokens }
126+
: undefined,
126127
maxOutputTokens: this.options.modelMaxTokens ?? info.maxTokens ?? undefined,
127128
}
128129
}

src/api/providers/vertex.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ export class VertexHandler extends GeminiHandler implements SingleCompletionHand
2323
return {
2424
id,
2525
info,
26-
thinkingConfig: this.options.modelMaxThinkingTokens
27-
? { thinkingBudget: this.options.modelMaxThinkingTokens }
28-
: undefined,
26+
thinkingConfig:
27+
this.options.setReasoningEffort && this.options.modelMaxThinkingTokens !== undefined
28+
? { thinkingBudget: this.options.modelMaxThinkingTokens }
29+
: undefined,
2930
maxOutputTokens: this.options.modelMaxTokens ?? info.maxTokens ?? undefined,
3031
}
3132
}

src/api/transform/__tests__/model-params.test.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ describe("getModelParams", () => {
207207
})
208208
})
209209

210-
it("should handle supportsReasoningBudget with enableReasoningEffort setting", () => {
210+
it("should handle supportsReasoningBudget with setReasoningEffort setting", () => {
211211
const model: ModelInfo = {
212212
...baseModel,
213213
maxTokens: 2000,
@@ -216,7 +216,7 @@ describe("getModelParams", () => {
216216

217217
const result = getModelParams({
218218
...anthropicParams,
219-
settings: { enableReasoningEffort: true },
219+
settings: { setReasoningEffort: true },
220220
model,
221221
})
222222

@@ -228,7 +228,7 @@ describe("getModelParams", () => {
228228
})
229229
})
230230

231-
it("should not use reasoning budget when supportsReasoningBudget is true but enableReasoningEffort is false", () => {
231+
it("should not use reasoning budget when supportsReasoningBudget is true but setReasoningEffort is false", () => {
232232
const model: ModelInfo = {
233233
...baseModel,
234234
maxTokens: 2000,
@@ -237,7 +237,7 @@ describe("getModelParams", () => {
237237

238238
const result = getModelParams({
239239
...anthropicParams,
240-
settings: { enableReasoningEffort: false },
240+
settings: { setReasoningEffort: false },
241241
model,
242242
})
243243

@@ -537,7 +537,7 @@ describe("getModelParams", () => {
537537
it("should keep model maxTokens for hybrid models when using reasoning budget", () => {
538538
const result = getModelParams({
539539
...anthropicParams,
540-
settings: { enableReasoningEffort: true },
540+
settings: { setReasoningEffort: true },
541541
model,
542542
})
543543

@@ -560,7 +560,7 @@ describe("getModelParams", () => {
560560
// Only reasoning budget should be used (takes precedence)
561561
const result = getModelParams({
562562
...anthropicParams,
563-
settings: { enableReasoningEffort: true },
563+
settings: { setReasoningEffort: true },
564564
model,
565565
})
566566

@@ -645,7 +645,7 @@ describe("getModelParams", () => {
645645
const result = getModelParams({
646646
...anthropicParams,
647647
settings: {
648-
enableReasoningEffort: true,
648+
setReasoningEffort: true,
649649
modelMaxTokens: 20000,
650650
modelMaxThinkingTokens: 10000,
651651
modelTemperature: 0.8,

src/api/transform/__tests__/reasoning.test.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ describe("reasoning.ts", () => {
4747
}
4848

4949
const settingsWithEnabled: ProviderSettings = {
50-
enableReasoningEffort: true,
50+
setReasoningEffort: true,
5151
}
5252

5353
const options = {
@@ -108,7 +108,7 @@ describe("reasoning.ts", () => {
108108
}
109109

110110
const settingsWithBoth: ProviderSettings = {
111-
enableReasoningEffort: true,
111+
setReasoningEffort: true,
112112
reasoningEffort: "low",
113113
}
114114

@@ -189,14 +189,14 @@ describe("reasoning.ts", () => {
189189
expect(result).toEqual({ max_tokens: 0 })
190190
})
191191

192-
it("should not use reasoning budget when supportsReasoningBudget is true but enableReasoningEffort is false", () => {
192+
it("should not use reasoning budget when supportsReasoningBudget is true but setReasoningEffort is false", () => {
193193
const modelWithSupported: ModelInfo = {
194194
...baseModel,
195195
supportsReasoningBudget: true,
196196
}
197197

198198
const settingsWithDisabled: ProviderSettings = {
199-
enableReasoningEffort: false,
199+
setReasoningEffort: false,
200200
}
201201

202202
const options = {
@@ -252,7 +252,7 @@ describe("reasoning.ts", () => {
252252
}
253253

254254
const settingsWithEnabled: ProviderSettings = {
255-
enableReasoningEffort: true,
255+
setReasoningEffort: true,
256256
}
257257

258258
const options = {
@@ -274,14 +274,14 @@ describe("reasoning.ts", () => {
274274
expect(result).toBeUndefined()
275275
})
276276

277-
it("should return undefined when supportsReasoningBudget is true but enableReasoningEffort is false", () => {
277+
it("should return undefined when supportsReasoningBudget is true but setReasoningEffort is false", () => {
278278
const modelWithSupported: ModelInfo = {
279279
...baseModel,
280280
supportsReasoningBudget: true,
281281
}
282282

283283
const settingsWithDisabled: ProviderSettings = {
284-
enableReasoningEffort: false,
284+
setReasoningEffort: false,
285285
}
286286

287287
const options = {
@@ -513,7 +513,7 @@ describe("reasoning.ts", () => {
513513
}
514514

515515
const settingsWithEnabled: ProviderSettings = {
516-
enableReasoningEffort: true,
516+
setReasoningEffort: true,
517517
}
518518

519519
const options = {
@@ -583,7 +583,7 @@ describe("reasoning.ts", () => {
583583
}
584584

585585
const settingsWithBoth: ProviderSettings = {
586-
enableReasoningEffort: true,
586+
setReasoningEffort: true,
587587
reasoningEffort: "high",
588588
}
589589

src/api/transform/model-params.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { ModelInfo, ProviderSettings } from "@roo-code/types"
22

33
import { ANTHROPIC_DEFAULT_MAX_TOKENS } from "../providers/constants"
4-
import { shouldUseReasoningBudget, shouldUseReasoningEffort } from "../../shared/api"
4+
import { shouldSetReasoningBudget, shouldUseReasoningEffort } from "../../shared/api"
55

66
import {
77
type AnthropicReasoningParams,
@@ -67,7 +67,7 @@ export function getModelParams({
6767
let reasoningBudget: ModelParams["reasoningBudget"] = undefined
6868
let reasoningEffort: ModelParams["reasoningEffort"] = undefined
6969

70-
if (shouldUseReasoningBudget({ model, settings })) {
70+
if (shouldSetReasoningBudget({ model, settings })) {
7171
// "Hybrid" reasoning models use the `reasoningBudget` parameter.
7272
maxTokens = customMaxTokens ?? maxTokens
7373

src/api/transform/reasoning.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import OpenAI from "openai"
33

44
import type { ModelInfo, ProviderSettings } from "@roo-code/types"
55

6-
import { shouldUseReasoningBudget, shouldUseReasoningEffort } from "../../shared/api"
6+
import { shouldSetReasoningBudget, shouldUseReasoningEffort } from "../../shared/api"
77

88
type ReasoningEffort = "low" | "medium" | "high"
99

@@ -30,7 +30,7 @@ export const getOpenRouterReasoning = ({
3030
reasoningEffort,
3131
settings,
3232
}: GetModelReasoningOptions): OpenRouterReasoningParams | undefined =>
33-
shouldUseReasoningBudget({ model, settings })
33+
shouldSetReasoningBudget({ model, settings })
3434
? { max_tokens: reasoningBudget }
3535
: shouldUseReasoningEffort({ model, settings })
3636
? { effort: reasoningEffort }
@@ -41,7 +41,7 @@ export const getAnthropicReasoning = ({
4141
reasoningBudget,
4242
settings,
4343
}: GetModelReasoningOptions): AnthropicReasoningParams | undefined =>
44-
shouldUseReasoningBudget({ model, settings }) ? { type: "enabled", budget_tokens: reasoningBudget! } : undefined
44+
shouldSetReasoningBudget({ model, settings }) ? { type: "enabled", budget_tokens: reasoningBudget! } : undefined
4545

4646
export const getOpenAiReasoning = ({
4747
model,

src/core/config/ProviderSettingsManager.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export const providerProfilesSchema = z.object({
2626
rateLimitSecondsMigrated: z.boolean().optional(),
2727
diffSettingsMigrated: z.boolean().optional(),
2828
openAiHeadersMigrated: z.boolean().optional(),
29+
manualThinkingBudgetMigrated: z.boolean().optional(),
2930
})
3031
.optional(),
3132
})
@@ -48,6 +49,7 @@ export class ProviderSettingsManager {
4849
rateLimitSecondsMigrated: true, // Mark as migrated on fresh installs
4950
diffSettingsMigrated: true, // Mark as migrated on fresh installs
5051
openAiHeadersMigrated: true, // Mark as migrated on fresh installs
52+
manualThinkingBudgetMigrated: true, // Mark as migrated on fresh installs
5153
},
5254
}
5355

@@ -113,6 +115,7 @@ export class ProviderSettingsManager {
113115
rateLimitSecondsMigrated: false,
114116
diffSettingsMigrated: false,
115117
openAiHeadersMigrated: false,
118+
manualThinkingBudgetMigrated: false,
116119
} // Initialize with default values
117120
isDirty = true
118121
}
@@ -135,6 +138,12 @@ export class ProviderSettingsManager {
135138
isDirty = true
136139
}
137140

141+
if (!providerProfiles.migrations.manualThinkingBudgetMigrated) {
142+
await this.migrateManualThinkingBudget(providerProfiles)
143+
providerProfiles.migrations.manualThinkingBudgetMigrated = true
144+
isDirty = true
145+
}
146+
138147
if (isDirty) {
139148
await this.store(providerProfiles)
140149
}
@@ -228,6 +237,23 @@ export class ProviderSettingsManager {
228237
}
229238
}
230239

240+
private async migrateManualThinkingBudget(providerProfiles: ProviderProfiles) {
241+
try {
242+
for (const [_name, apiConfig] of Object.entries(providerProfiles.apiConfigs)) {
243+
// For existing users who have modelMaxThinkingTokens set, enable manual control
244+
// This maintains backward compatibility - if they were manually setting thinking tokens,
245+
// they should continue to have manual control enabled
246+
if (apiConfig.modelMaxThinkingTokens !== undefined && apiConfig.setReasoningEffort === undefined) {
247+
apiConfig.setReasoningEffort = true
248+
}
249+
// For new users or existing users without thinking tokens set,
250+
// default to false (automatic mode) - this is handled by the UI component's default logic
251+
}
252+
} catch (error) {
253+
console.error(`[MigrateManualThinkingBudget] Failed to migrate manual thinking budget settings:`, error)
254+
}
255+
}
256+
231257
/**
232258
* List all available configs with metadata.
233259
*/

0 commit comments

Comments
 (0)