mirror of
https://github.com/getcompanion-ai/co-mono.git
synced 2026-04-17 03:03:44 +00:00
Support thinking level configuration for Gemini 3 Pro models (#176)
* support Google thinking level configuration for Gemini 3 Pro models * relax model ID check for gemini 3 pro
This commit is contained in:
parent
38119ffbb0
commit
6b48fa58d7
2 changed files with 44 additions and 9 deletions
|
|
@ -6,6 +6,8 @@ import {
|
|||
type GenerateContentParameters,
|
||||
GoogleGenAI,
|
||||
type Part,
|
||||
type ThinkingConfig,
|
||||
type ThinkingLevel,
|
||||
} from "@google/genai";
|
||||
import { calculateCost } from "../models.js";
|
||||
import type {
|
||||
|
|
@ -31,6 +33,7 @@ export interface GoogleOptions extends StreamOptions {
|
|||
thinking?: {
|
||||
enabled: boolean;
|
||||
budgetTokens?: number; // -1 for dynamic, 0 to disable
|
||||
level?: ThinkingLevel;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -293,10 +296,13 @@ function buildParams(
|
|||
}
|
||||
|
||||
if (options.thinking?.enabled && model.reasoning) {
|
||||
config.thinkingConfig = {
|
||||
includeThoughts: true,
|
||||
...(options.thinking.budgetTokens !== undefined && { thinkingBudget: options.thinking.budgetTokens }),
|
||||
};
|
||||
const thinkingConfig: ThinkingConfig = { includeThoughts: true };
|
||||
if (options.thinking.level !== undefined) {
|
||||
thinkingConfig.thinkingLevel = options.thinking.level;
|
||||
} else if (options.thinking.budgetTokens !== undefined) {
|
||||
thinkingConfig.thinkingBudget = options.thinking.budgetTokens;
|
||||
}
|
||||
config.thinkingConfig = thinkingConfig;
|
||||
}
|
||||
|
||||
if (options.signal) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import { ThinkingLevel } from "@google/genai";
|
||||
import { type AnthropicOptions, streamAnthropic } from "./providers/anthropic.js";
|
||||
import { type GoogleOptions, streamGoogle } from "./providers/google.js";
|
||||
import { type OpenAICompletionsOptions, streamOpenAICompletions } from "./providers/openai-completions.js";
|
||||
|
|
@ -159,15 +160,26 @@ function mapOptionsForApi<TApi extends Api>(
|
|||
case "google-generative-ai": {
|
||||
if (!options?.reasoning) return base as any;
|
||||
|
||||
const googleBudget = getGoogleBudget(
|
||||
model as Model<"google-generative-ai">,
|
||||
clampReasoning(options.reasoning)!,
|
||||
);
|
||||
const googleModel = model as Model<"google-generative-ai">;
|
||||
const effort = clampReasoning(options.reasoning)!;
|
||||
|
||||
// Gemini 3 Pro models use thinkingLevel exclusively instead of thinkingBudget.
|
||||
// https://ai.google.dev/gemini-api/docs/thinking#set-budget
|
||||
if (isGemini3ProModel(googleModel)) {
|
||||
return {
|
||||
...base,
|
||||
thinking: {
|
||||
enabled: true,
|
||||
level: getGoogleThinkingLevel(effort),
|
||||
},
|
||||
} satisfies GoogleOptions;
|
||||
}
|
||||
|
||||
return {
|
||||
...base,
|
||||
thinking: {
|
||||
enabled: true,
|
||||
budgetTokens: googleBudget,
|
||||
budgetTokens: getGoogleBudget(googleModel, effort),
|
||||
},
|
||||
} satisfies GoogleOptions;
|
||||
}
|
||||
|
|
@ -182,6 +194,23 @@ function mapOptionsForApi<TApi extends Api>(
|
|||
|
||||
type ClampedReasoningEffort = Exclude<ReasoningEffort, "xhigh">;
|
||||
|
||||
function isGemini3ProModel(model: Model<"google-generative-ai">): boolean {
|
||||
// Covers gemini-3-pro, gemini-3-pro-preview, and possible other prefixed ids in the future
|
||||
return model.id.includes("3-pro");
|
||||
}
|
||||
|
||||
function getGoogleThinkingLevel(effort: ClampedReasoningEffort): ThinkingLevel {
|
||||
// Gemini 3 Pro only supports LOW/HIGH (for now)
|
||||
switch (effort) {
|
||||
case "minimal":
|
||||
case "low":
|
||||
return ThinkingLevel.LOW;
|
||||
case "medium":
|
||||
case "high":
|
||||
return ThinkingLevel.HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
function getGoogleBudget(model: Model<"google-generative-ai">, effort: ClampedReasoningEffort): number {
|
||||
// See https://ai.google.dev/gemini-api/docs/thinking#set-budget
|
||||
if (model.id.includes("2.5-pro")) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue