mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-09-06 08:18:39 +00:00
fix(gemini): upgrade @google/genai to support thinkingLevel for Gemini 3 models
The previous SDK version (1.29.1) did not include the `thinkingLevel` property in `ThinkingConfig`, causing INVALID_ARGUMENT errors when using Gemini 3 Pro and Flash models which require effort-based reasoning configuration via `thinkingLevel`. Changes: - Update @google/genai from ^1.29.1 to ^1.30.0 (adds thinkingLevel support) - Import ThinkingLevel enum and map lowercase effort values to SDK enum values - Update GeminiReasoningParams type to use SDK's ThinkingConfig directly - Update tests to expect uppercase ThinkingLevel enum values
This commit is contained in:
parent
1e71015e54
commit
41c99fad5d
5 changed files with 46 additions and 20 deletions
12
.changeset/fix-gemini-3-thinking-level.md
Normal file
12
.changeset/fix-gemini-3-thinking-level.md
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
"roo-cline": patch
|
||||
---
|
||||
|
||||
fix(gemini): upgrade @google/genai to support thinkingLevel for Gemini 3 models
|
||||
|
||||
The previous SDK version (1.29.1) did not include the `thinkingLevel` property in
|
||||
`ThinkingConfig`, causing INVALID_ARGUMENT errors when using Gemini 3 Pro and Flash
|
||||
models which require effort-based reasoning configuration via `thinkingLevel`.
|
||||
|
||||
Updated to @google/genai ^1.30.0 which adds support for `thinkingLevel` with values:
|
||||
MINIMAL, LOW, MEDIUM, HIGH.
|
||||
16
pnpm-lock.yaml
generated
16
pnpm-lock.yaml
generated
|
|
@ -668,8 +668,8 @@ importers:
|
|||
specifier: ^3.922.0
|
||||
version: 3.922.0
|
||||
'@google/genai':
|
||||
specifier: ^1.29.1
|
||||
version: 1.29.1(@modelcontextprotocol/sdk@1.12.0)
|
||||
specifier: ^1.30.0
|
||||
version: 1.34.0(@modelcontextprotocol/sdk@1.12.0)
|
||||
'@lmstudio/sdk':
|
||||
specifier: ^1.1.1
|
||||
version: 1.2.0
|
||||
|
|
@ -1973,11 +1973,11 @@ packages:
|
|||
'@floating-ui/utils@0.2.9':
|
||||
resolution: {integrity: sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg==}
|
||||
|
||||
'@google/genai@1.29.1':
|
||||
resolution: {integrity: sha512-Buywpq0A6xf9cOdhiWCi5KUiDBbZkjCH5xbl+xxNQRItoYQgd31p0OKyn5cUnT0YNzC/pAmszqXoOc7kncqfFQ==}
|
||||
'@google/genai@1.34.0':
|
||||
resolution: {integrity: sha512-vu53UMPvjmb7PGzlYu6Tzxso8Dfhn+a7eQFaS2uNemVtDZKwzSpJ5+ikqBbXplF7RGB1STcVDqCkPvquiwb2sw==}
|
||||
engines: {node: '>=20.0.0'}
|
||||
peerDependencies:
|
||||
'@modelcontextprotocol/sdk': ^1.20.1
|
||||
'@modelcontextprotocol/sdk': ^1.24.0
|
||||
peerDependenciesMeta:
|
||||
'@modelcontextprotocol/sdk':
|
||||
optional: true
|
||||
|
|
@ -11594,7 +11594,7 @@ snapshots:
|
|||
|
||||
'@floating-ui/utils@0.2.9': {}
|
||||
|
||||
'@google/genai@1.29.1(@modelcontextprotocol/sdk@1.12.0)':
|
||||
'@google/genai@1.34.0(@modelcontextprotocol/sdk@1.12.0)':
|
||||
dependencies:
|
||||
google-auth-library: 10.5.0
|
||||
ws: 8.18.3
|
||||
|
|
@ -11854,7 +11854,7 @@ snapshots:
|
|||
|
||||
'@lmstudio/lms-isomorphic@0.4.5':
|
||||
dependencies:
|
||||
ws: 8.18.2
|
||||
ws: 8.18.3
|
||||
transitivePeerDependencies:
|
||||
- bufferutil
|
||||
- utf-8-validate
|
||||
|
|
@ -18954,7 +18954,7 @@ snapshots:
|
|||
debug: 4.4.1(supports-color@8.1.1)
|
||||
devtools-protocol: 0.0.1452169
|
||||
typed-query-selector: 2.12.0
|
||||
ws: 8.18.2
|
||||
ws: 8.18.3
|
||||
transitivePeerDependencies:
|
||||
- bare-buffer
|
||||
- bufferutil
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
// npx vitest run src/api/transform/__tests__/reasoning.spec.ts
|
||||
|
||||
import type { ModelInfo, ProviderSettings, ReasoningEffortWithMinimal } from "@roo-code/types"
|
||||
import { ThinkingLevel } from "@google/genai"
|
||||
|
||||
import {
|
||||
getOpenRouterReasoning,
|
||||
|
|
@ -615,7 +616,7 @@ describe("reasoning.ts", () => {
|
|||
const result = getGeminiReasoning(options) as GeminiReasoningParams | undefined
|
||||
|
||||
// Budget should not be used for effort-only models
|
||||
expect(result).toEqual({ thinkingLevel: "high", includeThoughts: true })
|
||||
expect(result).toEqual({ thinkingLevel: ThinkingLevel.HIGH, includeThoughts: true })
|
||||
})
|
||||
|
||||
it("should still return thinkingLevel when enableReasoningEffort is false but effort is explicitly set", () => {
|
||||
|
|
@ -641,7 +642,7 @@ describe("reasoning.ts", () => {
|
|||
}
|
||||
|
||||
const result = getGeminiReasoning(options) as GeminiReasoningParams | undefined
|
||||
expect(result).toEqual({ thinkingLevel: "high", includeThoughts: true })
|
||||
expect(result).toEqual({ thinkingLevel: ThinkingLevel.HIGH, includeThoughts: true })
|
||||
})
|
||||
|
||||
it("should return thinkingLevel for minimal effort", () => {
|
||||
|
|
@ -664,7 +665,7 @@ describe("reasoning.ts", () => {
|
|||
}
|
||||
|
||||
const result = getGeminiReasoning(options) as GeminiReasoningParams | undefined
|
||||
expect(result).toEqual({ thinkingLevel: "minimal", includeThoughts: true })
|
||||
expect(result).toEqual({ thinkingLevel: ThinkingLevel.MINIMAL, includeThoughts: true })
|
||||
})
|
||||
|
||||
it("should return thinkingLevel for medium effort", () => {
|
||||
|
|
@ -687,11 +688,17 @@ describe("reasoning.ts", () => {
|
|||
}
|
||||
|
||||
const result = getGeminiReasoning(options) as GeminiReasoningParams | undefined
|
||||
expect(result).toEqual({ thinkingLevel: "medium", includeThoughts: true })
|
||||
expect(result).toEqual({ thinkingLevel: ThinkingLevel.MEDIUM, includeThoughts: true })
|
||||
})
|
||||
|
||||
it("should handle all four Gemini thinking levels", () => {
|
||||
const levels: GeminiThinkingLevel[] = ["minimal", "low", "medium", "high"]
|
||||
const expectedThinkingLevels: Record<GeminiThinkingLevel, ThinkingLevel> = {
|
||||
minimal: ThinkingLevel.MINIMAL,
|
||||
low: ThinkingLevel.LOW,
|
||||
medium: ThinkingLevel.MEDIUM,
|
||||
high: ThinkingLevel.HIGH,
|
||||
}
|
||||
|
||||
levels.forEach((level) => {
|
||||
const geminiModel: ModelInfo = {
|
||||
|
|
@ -718,7 +725,7 @@ describe("reasoning.ts", () => {
|
|||
}
|
||||
|
||||
const result = getGeminiReasoning(options) as GeminiReasoningParams | undefined
|
||||
expect(result).toEqual({ thinkingLevel: level, includeThoughts: true })
|
||||
expect(result).toEqual({ thinkingLevel: expectedThinkingLevels[level], includeThoughts: true })
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -836,7 +843,7 @@ describe("reasoning.ts", () => {
|
|||
}
|
||||
|
||||
const result = getGeminiReasoning(options) as GeminiReasoningParams | undefined
|
||||
expect(result).toEqual({ thinkingLevel: "medium", includeThoughts: true })
|
||||
expect(result).toEqual({ thinkingLevel: ThinkingLevel.MEDIUM, includeThoughts: true })
|
||||
})
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { BetaThinkingConfigParam } from "@anthropic-ai/sdk/resources/beta"
|
||||
import OpenAI from "openai"
|
||||
import type { GenerateContentConfig } from "@google/genai"
|
||||
import { ThinkingLevel, type GenerateContentConfig } from "@google/genai"
|
||||
|
||||
import type { ModelInfo, ProviderSettings, ReasoningEffortExtended } from "@roo-code/types"
|
||||
|
||||
|
|
@ -21,7 +21,7 @@ export type AnthropicReasoningParams = BetaThinkingConfigParam
|
|||
|
||||
export type OpenAiReasoningParams = { reasoning_effort: OpenAI.Chat.ChatCompletionCreateParams["reasoning_effort"] }
|
||||
|
||||
// Valid Gemini thinking levels for effort-based reasoning
|
||||
// Valid Gemini thinking levels for effort-based reasoning (lowercase for internal use)
|
||||
const GEMINI_THINKING_LEVELS = ["minimal", "low", "medium", "high"] as const
|
||||
|
||||
export type GeminiThinkingLevel = (typeof GEMINI_THINKING_LEVELS)[number]
|
||||
|
|
@ -30,10 +30,16 @@ export function isGeminiThinkingLevel(value: unknown): value is GeminiThinkingLe
|
|||
return typeof value === "string" && GEMINI_THINKING_LEVELS.includes(value as GeminiThinkingLevel)
|
||||
}
|
||||
|
||||
export type GeminiReasoningParams = GenerateContentConfig["thinkingConfig"] & {
|
||||
thinkingLevel?: GeminiThinkingLevel
|
||||
// Map lowercase thinking levels to SDK's ThinkingLevel enum
|
||||
const THINKING_LEVEL_MAP: Record<GeminiThinkingLevel, ThinkingLevel> = {
|
||||
minimal: ThinkingLevel.MINIMAL,
|
||||
low: ThinkingLevel.LOW,
|
||||
medium: ThinkingLevel.MEDIUM,
|
||||
high: ThinkingLevel.HIGH,
|
||||
}
|
||||
|
||||
export type GeminiReasoningParams = GenerateContentConfig["thinkingConfig"]
|
||||
|
||||
export type GetModelReasoningOptions = {
|
||||
model: ModelInfo
|
||||
reasoningBudget: number | undefined
|
||||
|
|
@ -155,5 +161,6 @@ export const getGeminiReasoning = ({
|
|||
return undefined
|
||||
}
|
||||
|
||||
return { thinkingLevel: selectedEffort, includeThoughts: true }
|
||||
// Map lowercase effort to SDK's ThinkingLevel enum (uppercase values)
|
||||
return { thinkingLevel: THINKING_LEVEL_MAP[selectedEffort], includeThoughts: true }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -435,7 +435,7 @@
|
|||
"@anthropic-ai/vertex-sdk": "^0.7.0",
|
||||
"@aws-sdk/client-bedrock-runtime": "^3.922.0",
|
||||
"@aws-sdk/credential-providers": "^3.922.0",
|
||||
"@google/genai": "^1.29.1",
|
||||
"@google/genai": "^1.30.0",
|
||||
"@lmstudio/sdk": "^1.1.1",
|
||||
"@mistralai/mistralai": "^1.9.18",
|
||||
"@modelcontextprotocol/sdk": "1.12.0",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue