@aigne/gemini 0.14.4-beta.6 → 0.14.4-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.14.4-beta.7](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.4-beta.6...gemini-v0.14.4-beta.7) (2025-10-29)
4
+
5
+
6
+ ### Features
7
+
8
+ * add reasoningEffort option for chat model ([#680](https://github.com/AIGNE-io/aigne-framework/issues/680)) ([f69d232](https://github.com/AIGNE-io/aigne-framework/commit/f69d232d714d4a3e4946bdc8c6598747c9bcbd57))
9
+
10
+
11
+ ### Dependencies
12
+
13
+ * The following workspace dependencies were updated
14
+ * dependencies
15
+ * @aigne/core bumped to 1.65.0-beta.4
16
+ * devDependencies
17
+ * @aigne/test-utils bumped to 0.5.57-beta.5
18
+
3
19
  ## [0.14.4-beta.6](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.4-beta.5...gemini-v0.14.4-beta.6) (2025-10-28)
4
20
 
5
21
 
@@ -1,4 +1,4 @@
1
- import { type AgentProcessResult, ChatModel, type ChatModelInput, type ChatModelOptions, type ChatModelOutput } from "@aigne/core";
1
+ import { type AgentProcessResult, ChatModel, type ChatModelInput, type ChatModelInputOptions, type ChatModelOptions, type ChatModelOutput } from "@aigne/core";
2
2
  import { type PromiseOrValue } from "@aigne/core/utils/type-utils.js";
3
3
  import { GoogleGenAI, type GoogleGenAIOptions } from "@google/genai";
4
4
  export interface GeminiChatModelOptions extends ChatModelOptions {
@@ -34,10 +34,30 @@ export declare class GeminiChatModel extends ChatModel {
34
34
  apiKey: string | undefined;
35
35
  model: string;
36
36
  };
37
- get modelOptions(): Omit<import("@aigne/core").ChatModelInputOptions, "model"> | undefined;
37
+ get modelOptions(): Omit<ChatModelInputOptions, "model"> | undefined;
38
38
  process(input: ChatModelInput): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
39
+ protected thinkingBudgetModelMap: ({
40
+ pattern: RegExp;
41
+ support: boolean;
42
+ min: number;
43
+ max: number;
44
+ } | {
45
+ pattern: RegExp;
46
+ support: boolean;
47
+ min?: undefined;
48
+ max?: undefined;
49
+ })[];
50
+ protected thinkingBudgetLevelMap: {
51
+ high: number;
52
+ medium: number;
53
+ low: number;
54
+ minimal: number;
55
+ };
56
+ protected getThinkingBudget(model: string, effort: ChatModelInputOptions["reasoningEffort"]): {
57
+ support: boolean;
58
+ budget?: number;
59
+ };
39
60
  private processInput;
40
- protected supportThinkingModels: string[];
41
61
  private buildConfig;
42
62
  private buildTools;
43
63
  private buildContents;
@@ -61,15 +61,63 @@ class GeminiChatModel extends core_1.ChatModel {
61
61
  process(input) {
62
62
  return this.processInput(input);
63
63
  }
64
+ // References: https://ai.google.dev/gemini-api/docs/thinking#set-budget
65
+ thinkingBudgetModelMap = [
66
+ {
67
+ pattern: /gemini-2.5-pro/,
68
+ support: true,
69
+ min: 128,
70
+ max: 32768,
71
+ },
72
+ {
73
+ pattern: /gemini-2.5-flash/,
74
+ support: true,
75
+ min: 0,
76
+ max: 24576,
77
+ },
78
+ {
79
+ pattern: /2.5-flash-lite/,
80
+ support: true,
81
+ min: 512,
82
+ max: 24576,
83
+ },
84
+ {
85
+ pattern: /.*/,
86
+ support: false,
87
+ },
88
+ ];
89
+ thinkingBudgetLevelMap = {
90
+ high: 100000, // use 100k for high, finally capped by model max
91
+ medium: 10000,
92
+ low: 5000,
93
+ minimal: 200,
94
+ };
95
+ getThinkingBudget(model, effort) {
96
+ const m = this.thinkingBudgetModelMap.find((i) => i.pattern.test(model));
97
+ if (!m?.support)
98
+ return { support: false };
99
+ let budget = typeof effort === "string" ? this.thinkingBudgetLevelMap[effort] || undefined : effort;
100
+ if (typeof budget === "undefined")
101
+ return { support: true };
102
+ if (typeof m.min === "number")
103
+ budget = Math.max(m.min, budget);
104
+ if (typeof m.max === "number")
105
+ budget = Math.min(m.max, budget);
106
+ return { support: true, budget };
107
+ }
64
108
  async *processInput(input) {
65
109
  const model = input.modelOptions?.model || this.credential.model;
66
110
  const { contents, config } = await this.buildContents(input);
111
+ const thinkingBudget = this.getThinkingBudget(model, input.modelOptions?.reasoningEffort ?? this.modelOptions?.reasoningEffort);
67
112
  const parameters = {
68
113
  model,
69
114
  contents,
70
115
  config: {
71
- thinkingConfig: this.supportThinkingModels.includes(model)
72
- ? { includeThoughts: true }
116
+ thinkingConfig: thinkingBudget.support
117
+ ? {
118
+ includeThoughts: true,
119
+ thinkingBudget: thinkingBudget.budget,
120
+ }
73
121
  : undefined,
74
122
  responseModalities: input.modelOptions?.modalities,
75
123
  temperature: input.modelOptions?.temperature || this.modelOptions?.temperature,
@@ -201,9 +249,18 @@ class GeminiChatModel extends core_1.ChatModel {
201
249
  }
202
250
  }
203
251
  }
204
- yield { delta: { json: { usage, files: files.length ? files : undefined } } };
252
+ yield {
253
+ delta: {
254
+ json: {
255
+ usage,
256
+ files: files.length ? files : undefined,
257
+ modelOptions: {
258
+ reasoningEffort: parameters.config?.thinkingConfig?.thinkingBudget,
259
+ },
260
+ },
261
+ },
262
+ };
205
263
  }
206
- supportThinkingModels = ["gemini-2.5-pro", "gemini-2.5-flash"];
207
264
  async buildConfig(input) {
208
265
  const config = {};
209
266
  const { tools, toolConfig } = await this.buildTools(input);
@@ -1,4 +1,4 @@
1
- import { type AgentProcessResult, ChatModel, type ChatModelInput, type ChatModelOptions, type ChatModelOutput } from "@aigne/core";
1
+ import { type AgentProcessResult, ChatModel, type ChatModelInput, type ChatModelInputOptions, type ChatModelOptions, type ChatModelOutput } from "@aigne/core";
2
2
  import { type PromiseOrValue } from "@aigne/core/utils/type-utils.js";
3
3
  import { GoogleGenAI, type GoogleGenAIOptions } from "@google/genai";
4
4
  export interface GeminiChatModelOptions extends ChatModelOptions {
@@ -34,10 +34,30 @@ export declare class GeminiChatModel extends ChatModel {
34
34
  apiKey: string | undefined;
35
35
  model: string;
36
36
  };
37
- get modelOptions(): Omit<import("@aigne/core").ChatModelInputOptions, "model"> | undefined;
37
+ get modelOptions(): Omit<ChatModelInputOptions, "model"> | undefined;
38
38
  process(input: ChatModelInput): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
39
+ protected thinkingBudgetModelMap: ({
40
+ pattern: RegExp;
41
+ support: boolean;
42
+ min: number;
43
+ max: number;
44
+ } | {
45
+ pattern: RegExp;
46
+ support: boolean;
47
+ min?: undefined;
48
+ max?: undefined;
49
+ })[];
50
+ protected thinkingBudgetLevelMap: {
51
+ high: number;
52
+ medium: number;
53
+ low: number;
54
+ minimal: number;
55
+ };
56
+ protected getThinkingBudget(model: string, effort: ChatModelInputOptions["reasoningEffort"]): {
57
+ support: boolean;
58
+ budget?: number;
59
+ };
39
60
  private processInput;
40
- protected supportThinkingModels: string[];
41
61
  private buildConfig;
42
62
  private buildTools;
43
63
  private buildContents;
@@ -1,4 +1,4 @@
1
- import { type AgentProcessResult, ChatModel, type ChatModelInput, type ChatModelOptions, type ChatModelOutput } from "@aigne/core";
1
+ import { type AgentProcessResult, ChatModel, type ChatModelInput, type ChatModelInputOptions, type ChatModelOptions, type ChatModelOutput } from "@aigne/core";
2
2
  import { type PromiseOrValue } from "@aigne/core/utils/type-utils.js";
3
3
  import { GoogleGenAI, type GoogleGenAIOptions } from "@google/genai";
4
4
  export interface GeminiChatModelOptions extends ChatModelOptions {
@@ -34,10 +34,30 @@ export declare class GeminiChatModel extends ChatModel {
34
34
  apiKey: string | undefined;
35
35
  model: string;
36
36
  };
37
- get modelOptions(): Omit<import("@aigne/core").ChatModelInputOptions, "model"> | undefined;
37
+ get modelOptions(): Omit<ChatModelInputOptions, "model"> | undefined;
38
38
  process(input: ChatModelInput): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
39
+ protected thinkingBudgetModelMap: ({
40
+ pattern: RegExp;
41
+ support: boolean;
42
+ min: number;
43
+ max: number;
44
+ } | {
45
+ pattern: RegExp;
46
+ support: boolean;
47
+ min?: undefined;
48
+ max?: undefined;
49
+ })[];
50
+ protected thinkingBudgetLevelMap: {
51
+ high: number;
52
+ medium: number;
53
+ low: number;
54
+ minimal: number;
55
+ };
56
+ protected getThinkingBudget(model: string, effort: ChatModelInputOptions["reasoningEffort"]): {
57
+ support: boolean;
58
+ budget?: number;
59
+ };
39
60
  private processInput;
40
- protected supportThinkingModels: string[];
41
61
  private buildConfig;
42
62
  private buildTools;
43
63
  private buildContents;
@@ -58,15 +58,63 @@ export class GeminiChatModel extends ChatModel {
58
58
  process(input) {
59
59
  return this.processInput(input);
60
60
  }
61
+ // References: https://ai.google.dev/gemini-api/docs/thinking#set-budget
62
+ thinkingBudgetModelMap = [
63
+ {
64
+ pattern: /gemini-2.5-pro/,
65
+ support: true,
66
+ min: 128,
67
+ max: 32768,
68
+ },
69
+ {
70
+ pattern: /gemini-2.5-flash/,
71
+ support: true,
72
+ min: 0,
73
+ max: 24576,
74
+ },
75
+ {
76
+ pattern: /2.5-flash-lite/,
77
+ support: true,
78
+ min: 512,
79
+ max: 24576,
80
+ },
81
+ {
82
+ pattern: /.*/,
83
+ support: false,
84
+ },
85
+ ];
86
+ thinkingBudgetLevelMap = {
87
+ high: 100000, // use 100k for high, finally capped by model max
88
+ medium: 10000,
89
+ low: 5000,
90
+ minimal: 200,
91
+ };
92
+ getThinkingBudget(model, effort) {
93
+ const m = this.thinkingBudgetModelMap.find((i) => i.pattern.test(model));
94
+ if (!m?.support)
95
+ return { support: false };
96
+ let budget = typeof effort === "string" ? this.thinkingBudgetLevelMap[effort] || undefined : effort;
97
+ if (typeof budget === "undefined")
98
+ return { support: true };
99
+ if (typeof m.min === "number")
100
+ budget = Math.max(m.min, budget);
101
+ if (typeof m.max === "number")
102
+ budget = Math.min(m.max, budget);
103
+ return { support: true, budget };
104
+ }
61
105
  async *processInput(input) {
62
106
  const model = input.modelOptions?.model || this.credential.model;
63
107
  const { contents, config } = await this.buildContents(input);
108
+ const thinkingBudget = this.getThinkingBudget(model, input.modelOptions?.reasoningEffort ?? this.modelOptions?.reasoningEffort);
64
109
  const parameters = {
65
110
  model,
66
111
  contents,
67
112
  config: {
68
- thinkingConfig: this.supportThinkingModels.includes(model)
69
- ? { includeThoughts: true }
113
+ thinkingConfig: thinkingBudget.support
114
+ ? {
115
+ includeThoughts: true,
116
+ thinkingBudget: thinkingBudget.budget,
117
+ }
70
118
  : undefined,
71
119
  responseModalities: input.modelOptions?.modalities,
72
120
  temperature: input.modelOptions?.temperature || this.modelOptions?.temperature,
@@ -198,9 +246,18 @@ export class GeminiChatModel extends ChatModel {
198
246
  }
199
247
  }
200
248
  }
201
- yield { delta: { json: { usage, files: files.length ? files : undefined } } };
249
+ yield {
250
+ delta: {
251
+ json: {
252
+ usage,
253
+ files: files.length ? files : undefined,
254
+ modelOptions: {
255
+ reasoningEffort: parameters.config?.thinkingConfig?.thinkingBudget,
256
+ },
257
+ },
258
+ },
259
+ };
202
260
  }
203
- supportThinkingModels = ["gemini-2.5-pro", "gemini-2.5-flash"];
204
261
  async buildConfig(input) {
205
262
  const config = {};
206
263
  const { tools, toolConfig } = await this.buildTools(input);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigne/gemini",
3
- "version": "0.14.4-beta.6",
3
+ "version": "0.14.4-beta.7",
4
4
  "description": "AIGNE Gemini SDK for integrating with Google's Gemini AI models",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -39,7 +39,7 @@
39
39
  "@google/genai": "^1.24.0",
40
40
  "zod": "^3.25.67",
41
41
  "zod-to-json-schema": "^3.24.6",
42
- "@aigne/core": "^1.65.0-beta.3",
42
+ "@aigne/core": "^1.65.0-beta.4",
43
43
  "@aigne/platform-helpers": "^0.6.3"
44
44
  },
45
45
  "devDependencies": {
@@ -48,7 +48,7 @@
48
48
  "npm-run-all": "^4.1.5",
49
49
  "rimraf": "^6.0.1",
50
50
  "typescript": "^5.9.2",
51
- "@aigne/test-utils": "^0.5.57-beta.4"
51
+ "@aigne/test-utils": "^0.5.57-beta.5"
52
52
  },
53
53
  "scripts": {
54
54
  "lint": "tsc --noEmit",