@aigne/gemini 0.14.10-beta.1 → 0.14.10-beta.4
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,86 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.14.10-beta.4](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.10-beta.3...gemini-v0.14.10-beta.4) (2025-11-21)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **gemini:** properly handle thinking level for gemini 3.x models ([#763](https://github.com/AIGNE-io/aigne-framework/issues/763)) ([a5dc892](https://github.com/AIGNE-io/aigne-framework/commit/a5dc8921635811ed9ca2ff9e3e0699006f79cf22))
|
|
9
|
+
* **gemini:** return reasoningEffort in model options for gemini-3 ([#765](https://github.com/AIGNE-io/aigne-framework/issues/765)) ([682bfda](https://github.com/AIGNE-io/aigne-framework/commit/682bfda353b31fd432232baa57f8e0b0838eb76d))
|
|
10
|
+
|
|
11
|
+
## [0.14.10-beta.3](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.10-beta.2...gemini-v0.14.10-beta.3) (2025-11-19)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
### Features
|
|
15
|
+
|
|
16
|
+
* **models:** support gemini 3.x thinking level and thoughtSignature ([#760](https://github.com/AIGNE-io/aigne-framework/issues/760)) ([243f2d4](https://github.com/AIGNE-io/aigne-framework/commit/243f2d457792a20ba2b87378576092e6f88e319c))
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
### Dependencies
|
|
20
|
+
|
|
21
|
+
* The following workspace dependencies were updated
|
|
22
|
+
* dependencies
|
|
23
|
+
* @aigne/core bumped to 1.69.0-beta.2
|
|
24
|
+
* devDependencies
|
|
25
|
+
* @aigne/test-utils bumped to 0.5.63-beta.3
|
|
26
|
+
|
|
27
|
+
## [0.14.10-beta.2](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.10-beta.1...gemini-v0.14.10-beta.2) (2025-11-18)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
* add dynamic model options resolution with getter pattern ([#708](https://github.com/AIGNE-io/aigne-framework/issues/708)) ([5ed5085](https://github.com/AIGNE-io/aigne-framework/commit/5ed5085203763c70194853c56edc13acf56d81c6))
|
|
33
|
+
* add modalities support for chat model ([#454](https://github.com/AIGNE-io/aigne-framework/issues/454)) ([70d1bf6](https://github.com/AIGNE-io/aigne-framework/commit/70d1bf631f4e711235d89c6df8ee210a19179b30))
|
|
34
|
+
* 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))
|
|
35
|
+
* add thinking support to Gemini chat models ([#650](https://github.com/AIGNE-io/aigne-framework/issues/650)) ([09b828b](https://github.com/AIGNE-io/aigne-framework/commit/09b828ba668d90cc6aac68a5e8190adb146b5e45))
|
|
36
|
+
* **cli:** add retry functionality and improve error handling for AIGNE Hub ([#348](https://github.com/AIGNE-io/aigne-framework/issues/348)) ([672c93a](https://github.com/AIGNE-io/aigne-framework/commit/672c93abbba8b4b234f6d810536ff4b603a97e1e))
|
|
37
|
+
* improve image model architecture and file handling ([#527](https://github.com/AIGNE-io/aigne-framework/issues/527)) ([4db50aa](https://github.com/AIGNE-io/aigne-framework/commit/4db50aa0387a1a0f045ca11aaa61613e36ca7597))
|
|
38
|
+
* **memory:** support did space memory adapter ([#229](https://github.com/AIGNE-io/aigne-framework/issues/229)) ([6f69b64](https://github.com/AIGNE-io/aigne-framework/commit/6f69b64e98b963db9d6ab5357306b445385eaa68))
|
|
39
|
+
* **models:** support aigne hub models ([#416](https://github.com/AIGNE-io/aigne-framework/issues/416)) ([b4f014c](https://github.com/AIGNE-io/aigne-framework/commit/b4f014cf5ed08ef930d3ddfc278d3610e64c6af3))
|
|
40
|
+
* **models:** support gemini and ideogram images models ([#412](https://github.com/AIGNE-io/aigne-framework/issues/412)) ([6534fec](https://github.com/AIGNE-io/aigne-framework/commit/6534fecb0bdfb4b0a4440d44c0e563b9a029a68f))
|
|
41
|
+
* **models:** support gemini and ideogram images models ([#412](https://github.com/AIGNE-io/aigne-framework/issues/412)) ([6534fec](https://github.com/AIGNE-io/aigne-framework/commit/6534fecb0bdfb4b0a4440d44c0e563b9a029a68f))
|
|
42
|
+
* **model:** support video model ([#647](https://github.com/AIGNE-io/aigne-framework/issues/647)) ([de81742](https://github.com/AIGNE-io/aigne-framework/commit/de817421ef1dd3246d0d8c51ff12f0a855658f9f))
|
|
43
|
+
* support custom prefer input file type ([#469](https://github.com/AIGNE-io/aigne-framework/issues/469)) ([db0161b](https://github.com/AIGNE-io/aigne-framework/commit/db0161bbac52542c771ee2f40f361636b0668075))
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
### Bug Fixes
|
|
47
|
+
|
|
48
|
+
* add prefer input file type option for image model ([#536](https://github.com/AIGNE-io/aigne-framework/issues/536)) ([3cba8a5](https://github.com/AIGNE-io/aigne-framework/commit/3cba8a5562233a1567b49b6dd5c446c0760f5c4c))
|
|
49
|
+
* bump version ([93a1c10](https://github.com/AIGNE-io/aigne-framework/commit/93a1c10cf35f88eaafe91092481f5d087bd5b3a9))
|
|
50
|
+
* **core:** make getCredential async for aigne-hub mount point retrieval ([#372](https://github.com/AIGNE-io/aigne-framework/issues/372)) ([34ce7a6](https://github.com/AIGNE-io/aigne-framework/commit/34ce7a645fa83994d3dfe0f29ca70098cfecac9c))
|
|
51
|
+
* correct calculate token usage for gemini model ([7fd1328](https://github.com/AIGNE-io/aigne-framework/commit/7fd13289d3d0f8e062211f7c6dd5cb56e5318c1b))
|
|
52
|
+
* **docs:** update video mode docs ([#695](https://github.com/AIGNE-io/aigne-framework/issues/695)) ([d691001](https://github.com/AIGNE-io/aigne-framework/commit/d69100169457c16c14f2f3e2f7fcd6b2a99330f3))
|
|
53
|
+
* **gemini:** handle empty responses when files are present ([#648](https://github.com/AIGNE-io/aigne-framework/issues/648)) ([f4e259c](https://github.com/AIGNE-io/aigne-framework/commit/f4e259c5e5c687c347bb5cf29cbb0b5bf4d0d4a1))
|
|
54
|
+
* **gemini:** implement retry mechanism for empty responses with structured output fallback ([#638](https://github.com/AIGNE-io/aigne-framework/issues/638)) ([d33c8bb](https://github.com/AIGNE-io/aigne-framework/commit/d33c8bb9711aadddef9687d6cf472a179cd8ed9c))
|
|
55
|
+
* **gemini:** include thoughts token count in output token usage ([#669](https://github.com/AIGNE-io/aigne-framework/issues/669)) ([f6ff10c](https://github.com/AIGNE-io/aigne-framework/commit/f6ff10c33b0612a0bc416842c5a5bec3850a3fe6))
|
|
56
|
+
* **gemini:** should include at least one user message ([#521](https://github.com/AIGNE-io/aigne-framework/issues/521)) ([eb2752e](https://github.com/AIGNE-io/aigne-framework/commit/eb2752ed7d78f59c435ecc3ccb7227e804e3781e))
|
|
57
|
+
* **gemini:** use StructuredOutputError to trigger retry for missing JSON response ([#660](https://github.com/AIGNE-io/aigne-framework/issues/660)) ([e8826ed](https://github.com/AIGNE-io/aigne-framework/commit/e8826ed96db57bfcce0b577881bf0d2fd828c269))
|
|
58
|
+
* improve image model parameters ([#530](https://github.com/AIGNE-io/aigne-framework/issues/530)) ([d66b5ca](https://github.com/AIGNE-io/aigne-framework/commit/d66b5ca01e14baad2712cc1a84930cdb63703232))
|
|
59
|
+
* **models:** add image parameters support for video generation ([#684](https://github.com/AIGNE-io/aigne-framework/issues/684)) ([b048b7f](https://github.com/AIGNE-io/aigne-framework/commit/b048b7f92bd7a532dbdbeb6fb5fa5499bae6b953))
|
|
60
|
+
* **models:** add imageConfig to gemini image model ([#621](https://github.com/AIGNE-io/aigne-framework/issues/621)) ([252de7a](https://github.com/AIGNE-io/aigne-framework/commit/252de7a10701c4f5302c2fff977c88e5e833b7b1))
|
|
61
|
+
* **models:** add mineType for transform file ([#667](https://github.com/AIGNE-io/aigne-framework/issues/667)) ([155a173](https://github.com/AIGNE-io/aigne-framework/commit/155a173e75aff1dbe870a1305455a4300942e07a))
|
|
62
|
+
* **models:** aigne hub video params ([#665](https://github.com/AIGNE-io/aigne-framework/issues/665)) ([d00f836](https://github.com/AIGNE-io/aigne-framework/commit/d00f8368422d8e3707b974e1aff06714731ebb28))
|
|
63
|
+
* **models:** auto retry when got emtpy response from gemini ([#636](https://github.com/AIGNE-io/aigne-framework/issues/636)) ([9367cef](https://github.com/AIGNE-io/aigne-framework/commit/9367cef49ea4c0c87b8a36b454deb2efaee6886f))
|
|
64
|
+
* **models:** enhance gemini model tool use with status fields ([#634](https://github.com/AIGNE-io/aigne-framework/issues/634)) ([067b175](https://github.com/AIGNE-io/aigne-framework/commit/067b175c8e31bb5b1a6d0fc5a5cfb2d070d8d709))
|
|
65
|
+
* **models:** improve message structure handling and enable auto-message options ([#657](https://github.com/AIGNE-io/aigne-framework/issues/657)) ([233d70c](https://github.com/AIGNE-io/aigne-framework/commit/233d70cb292b937200fada8434f33d957d766ad6))
|
|
66
|
+
* **model:** transform local file to base64 before request llm ([#462](https://github.com/AIGNE-io/aigne-framework/issues/462)) ([58ef5d7](https://github.com/AIGNE-io/aigne-framework/commit/58ef5d77046c49f3c4eed15b7f0cc283cbbcd74a))
|
|
67
|
+
* **model:** updated default video duration settings for AI video models ([#663](https://github.com/AIGNE-io/aigne-framework/issues/663)) ([1203941](https://github.com/AIGNE-io/aigne-framework/commit/12039411aaef77ba665e8edfb0fe6f8097c43e39))
|
|
68
|
+
* should not return local path from aigne hub service ([#460](https://github.com/AIGNE-io/aigne-framework/issues/460)) ([c959717](https://github.com/AIGNE-io/aigne-framework/commit/c95971774f7e84dbeb3313f60b3e6464e2bb22e4))
|
|
69
|
+
* standardize file parameter naming across models ([#534](https://github.com/AIGNE-io/aigne-framework/issues/534)) ([f159a9d](https://github.com/AIGNE-io/aigne-framework/commit/f159a9d6af21ec0e99641996b150560929845845))
|
|
70
|
+
* support gemini-2.0-flash model for image model ([#429](https://github.com/AIGNE-io/aigne-framework/issues/429)) ([5a0bba1](https://github.com/AIGNE-io/aigne-framework/commit/5a0bba197cf8785384b70302f86cf702d04b7fc4))
|
|
71
|
+
* support optional field sturectured output for gemini ([#468](https://github.com/AIGNE-io/aigne-framework/issues/468)) ([70c6279](https://github.com/AIGNE-io/aigne-framework/commit/70c62795039a2862e3333f26707329489bf938de))
|
|
72
|
+
* **transport:** improve HTTP client option handling and error serialization ([#445](https://github.com/AIGNE-io/aigne-framework/issues/445)) ([d3bcdd2](https://github.com/AIGNE-io/aigne-framework/commit/d3bcdd23ab8011a7d40fc157fd61eb240494c7a5))
|
|
73
|
+
* update deps compatibility in CommonJS environment ([#580](https://github.com/AIGNE-io/aigne-framework/issues/580)) ([a1e35d0](https://github.com/AIGNE-io/aigne-framework/commit/a1e35d016405accb51c1aeb6a544503a1c78e912))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
### Dependencies
|
|
77
|
+
|
|
78
|
+
* The following workspace dependencies were updated
|
|
79
|
+
* dependencies
|
|
80
|
+
* @aigne/core bumped to 1.69.0-beta.1
|
|
81
|
+
* devDependencies
|
|
82
|
+
* @aigne/test-utils bumped to 0.5.63-beta.2
|
|
83
|
+
|
|
3
84
|
## [0.14.10-beta.1](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.10-beta...gemini-v0.14.10-beta.1) (2025-11-18)
|
|
4
85
|
|
|
5
86
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AgentInvokeOptions, 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
|
-
import { GoogleGenAI, type GoogleGenAIOptions } from "@google/genai";
|
|
3
|
+
import { GoogleGenAI, type GoogleGenAIOptions, ThinkingLevel } from "@google/genai";
|
|
4
4
|
export interface GeminiChatModelOptions extends ChatModelOptions {
|
|
5
5
|
/**
|
|
6
6
|
* API key for Gemini API
|
|
@@ -57,7 +57,7 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
57
57
|
modalities?: import("@aigne/core").Modality[] | {
|
|
58
58
|
$get: string;
|
|
59
59
|
} | undefined;
|
|
60
|
-
preferInputFileType?: "
|
|
60
|
+
preferInputFileType?: "url" | "file" | {
|
|
61
61
|
$get: string;
|
|
62
62
|
} | undefined;
|
|
63
63
|
reasoningEffort?: number | "minimal" | "low" | "medium" | "high" | {
|
|
@@ -66,13 +66,21 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
66
66
|
}> | undefined;
|
|
67
67
|
process(input: ChatModelInput, options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
68
68
|
protected thinkingBudgetModelMap: ({
|
|
69
|
+
pattern: RegExp;
|
|
70
|
+
support: boolean;
|
|
71
|
+
type: string;
|
|
72
|
+
min?: undefined;
|
|
73
|
+
max?: undefined;
|
|
74
|
+
} | {
|
|
69
75
|
pattern: RegExp;
|
|
70
76
|
support: boolean;
|
|
71
77
|
min: number;
|
|
72
78
|
max: number;
|
|
79
|
+
type?: undefined;
|
|
73
80
|
} | {
|
|
74
81
|
pattern: RegExp;
|
|
75
82
|
support: boolean;
|
|
83
|
+
type?: undefined;
|
|
76
84
|
min?: undefined;
|
|
77
85
|
max?: undefined;
|
|
78
86
|
})[];
|
|
@@ -82,9 +90,16 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
82
90
|
low: number;
|
|
83
91
|
minimal: number;
|
|
84
92
|
};
|
|
93
|
+
protected thinkingLevelMap: {
|
|
94
|
+
high: ThinkingLevel;
|
|
95
|
+
medium: ThinkingLevel;
|
|
96
|
+
low: ThinkingLevel;
|
|
97
|
+
minimal: ThinkingLevel;
|
|
98
|
+
};
|
|
85
99
|
protected getThinkingBudget(model: string, effort: ChatModelInputOptions["reasoningEffort"]): {
|
|
86
100
|
support: boolean;
|
|
87
101
|
budget?: number;
|
|
102
|
+
level?: ThinkingLevel;
|
|
88
103
|
};
|
|
89
104
|
private processInput;
|
|
90
105
|
private buildConfig;
|
|
@@ -63,6 +63,11 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
63
63
|
}
|
|
64
64
|
// References: https://ai.google.dev/gemini-api/docs/thinking#set-budget
|
|
65
65
|
thinkingBudgetModelMap = [
|
|
66
|
+
{
|
|
67
|
+
pattern: /gemini-3/,
|
|
68
|
+
support: true,
|
|
69
|
+
type: "level",
|
|
70
|
+
},
|
|
66
71
|
{
|
|
67
72
|
pattern: /gemini-2.5-pro/,
|
|
68
73
|
support: true,
|
|
@@ -92,10 +97,27 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
92
97
|
low: 5000,
|
|
93
98
|
minimal: 200,
|
|
94
99
|
};
|
|
100
|
+
thinkingLevelMap = {
|
|
101
|
+
high: genai_1.ThinkingLevel.HIGH,
|
|
102
|
+
medium: genai_1.ThinkingLevel.HIGH,
|
|
103
|
+
low: genai_1.ThinkingLevel.LOW,
|
|
104
|
+
minimal: genai_1.ThinkingLevel.LOW,
|
|
105
|
+
};
|
|
95
106
|
getThinkingBudget(model, effort) {
|
|
96
107
|
const m = this.thinkingBudgetModelMap.find((i) => i.pattern.test(model));
|
|
97
108
|
if (!m?.support)
|
|
98
109
|
return { support: false };
|
|
110
|
+
if (m.type === "level") {
|
|
111
|
+
let level = genai_1.ThinkingLevel.THINKING_LEVEL_UNSPECIFIED;
|
|
112
|
+
if (typeof effort === "string") {
|
|
113
|
+
level = this.thinkingLevelMap[effort];
|
|
114
|
+
}
|
|
115
|
+
else if (typeof effort === "number") {
|
|
116
|
+
level =
|
|
117
|
+
effort >= this.thinkingBudgetLevelMap["medium"] ? genai_1.ThinkingLevel.HIGH : genai_1.ThinkingLevel.LOW;
|
|
118
|
+
}
|
|
119
|
+
return { support: true, level };
|
|
120
|
+
}
|
|
99
121
|
let budget = typeof effort === "string" ? this.thinkingBudgetLevelMap[effort] || undefined : effort;
|
|
100
122
|
if (typeof budget === "undefined")
|
|
101
123
|
return { support: true };
|
|
@@ -118,6 +140,7 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
118
140
|
? {
|
|
119
141
|
includeThoughts: true,
|
|
120
142
|
thinkingBudget: thinkingBudget.budget,
|
|
143
|
+
thinkingLevel: thinkingBudget.level,
|
|
121
144
|
}
|
|
122
145
|
: undefined,
|
|
123
146
|
responseModalities: modelOptions.modalities,
|
|
@@ -171,14 +194,21 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
171
194
|
json = part.functionCall.args;
|
|
172
195
|
}
|
|
173
196
|
else {
|
|
174
|
-
|
|
197
|
+
const toolCall = {
|
|
175
198
|
id: part.functionCall.id || (0, uuid_1.v7)(),
|
|
176
199
|
type: "function",
|
|
177
200
|
function: {
|
|
178
201
|
name: part.functionCall.name,
|
|
179
202
|
arguments: part.functionCall.args || {},
|
|
180
203
|
},
|
|
181
|
-
}
|
|
204
|
+
};
|
|
205
|
+
// Preserve thought_signature for 3.x models
|
|
206
|
+
if (part.thoughtSignature && model.includes("gemini-3")) {
|
|
207
|
+
toolCall.metadata = {
|
|
208
|
+
thoughtSignature: part.thoughtSignature,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
toolCalls.push(toolCall);
|
|
182
212
|
yield { delta: { json: { toolCalls } } };
|
|
183
213
|
}
|
|
184
214
|
}
|
|
@@ -256,7 +286,8 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
256
286
|
usage,
|
|
257
287
|
files: files.length ? files : undefined,
|
|
258
288
|
modelOptions: {
|
|
259
|
-
reasoningEffort: parameters.config?.thinkingConfig?.
|
|
289
|
+
reasoningEffort: parameters.config?.thinkingConfig?.thinkingLevel ||
|
|
290
|
+
parameters.config?.thinkingConfig?.thinkingBudget,
|
|
260
291
|
},
|
|
261
292
|
},
|
|
262
293
|
},
|
|
@@ -340,13 +371,20 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
340
371
|
role: msg.role === "agent" ? "model" : msg.role === "user" ? "user" : undefined,
|
|
341
372
|
};
|
|
342
373
|
if (msg.toolCalls) {
|
|
343
|
-
content.parts = msg.toolCalls.map((call) =>
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
374
|
+
content.parts = msg.toolCalls.map((call) => {
|
|
375
|
+
const part = {
|
|
376
|
+
functionCall: {
|
|
377
|
+
id: call.id,
|
|
378
|
+
name: call.function.name,
|
|
379
|
+
args: call.function.arguments,
|
|
380
|
+
},
|
|
381
|
+
};
|
|
382
|
+
// Restore thought_signature for 3.x models
|
|
383
|
+
if (call.metadata?.thoughtSignature) {
|
|
384
|
+
part.thoughtSignature = call.metadata.thoughtSignature;
|
|
385
|
+
}
|
|
386
|
+
return part;
|
|
387
|
+
});
|
|
350
388
|
}
|
|
351
389
|
else if (msg.toolCallId) {
|
|
352
390
|
const call = input.messages
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AgentInvokeOptions, 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
|
-
import { GoogleGenAI, type GoogleGenAIOptions } from "@google/genai";
|
|
3
|
+
import { GoogleGenAI, type GoogleGenAIOptions, ThinkingLevel } from "@google/genai";
|
|
4
4
|
export interface GeminiChatModelOptions extends ChatModelOptions {
|
|
5
5
|
/**
|
|
6
6
|
* API key for Gemini API
|
|
@@ -57,7 +57,7 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
57
57
|
modalities?: import("@aigne/core").Modality[] | {
|
|
58
58
|
$get: string;
|
|
59
59
|
} | undefined;
|
|
60
|
-
preferInputFileType?: "
|
|
60
|
+
preferInputFileType?: "url" | "file" | {
|
|
61
61
|
$get: string;
|
|
62
62
|
} | undefined;
|
|
63
63
|
reasoningEffort?: number | "minimal" | "low" | "medium" | "high" | {
|
|
@@ -66,13 +66,21 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
66
66
|
}> | undefined;
|
|
67
67
|
process(input: ChatModelInput, options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
68
68
|
protected thinkingBudgetModelMap: ({
|
|
69
|
+
pattern: RegExp;
|
|
70
|
+
support: boolean;
|
|
71
|
+
type: string;
|
|
72
|
+
min?: undefined;
|
|
73
|
+
max?: undefined;
|
|
74
|
+
} | {
|
|
69
75
|
pattern: RegExp;
|
|
70
76
|
support: boolean;
|
|
71
77
|
min: number;
|
|
72
78
|
max: number;
|
|
79
|
+
type?: undefined;
|
|
73
80
|
} | {
|
|
74
81
|
pattern: RegExp;
|
|
75
82
|
support: boolean;
|
|
83
|
+
type?: undefined;
|
|
76
84
|
min?: undefined;
|
|
77
85
|
max?: undefined;
|
|
78
86
|
})[];
|
|
@@ -82,9 +90,16 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
82
90
|
low: number;
|
|
83
91
|
minimal: number;
|
|
84
92
|
};
|
|
93
|
+
protected thinkingLevelMap: {
|
|
94
|
+
high: ThinkingLevel;
|
|
95
|
+
medium: ThinkingLevel;
|
|
96
|
+
low: ThinkingLevel;
|
|
97
|
+
minimal: ThinkingLevel;
|
|
98
|
+
};
|
|
85
99
|
protected getThinkingBudget(model: string, effort: ChatModelInputOptions["reasoningEffort"]): {
|
|
86
100
|
support: boolean;
|
|
87
101
|
budget?: number;
|
|
102
|
+
level?: ThinkingLevel;
|
|
88
103
|
};
|
|
89
104
|
private processInput;
|
|
90
105
|
private buildConfig;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type AgentInvokeOptions, 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
|
-
import { GoogleGenAI, type GoogleGenAIOptions } from "@google/genai";
|
|
3
|
+
import { GoogleGenAI, type GoogleGenAIOptions, ThinkingLevel } from "@google/genai";
|
|
4
4
|
export interface GeminiChatModelOptions extends ChatModelOptions {
|
|
5
5
|
/**
|
|
6
6
|
* API key for Gemini API
|
|
@@ -57,7 +57,7 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
57
57
|
modalities?: import("@aigne/core").Modality[] | {
|
|
58
58
|
$get: string;
|
|
59
59
|
} | undefined;
|
|
60
|
-
preferInputFileType?: "
|
|
60
|
+
preferInputFileType?: "url" | "file" | {
|
|
61
61
|
$get: string;
|
|
62
62
|
} | undefined;
|
|
63
63
|
reasoningEffort?: number | "minimal" | "low" | "medium" | "high" | {
|
|
@@ -66,13 +66,21 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
66
66
|
}> | undefined;
|
|
67
67
|
process(input: ChatModelInput, options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
68
68
|
protected thinkingBudgetModelMap: ({
|
|
69
|
+
pattern: RegExp;
|
|
70
|
+
support: boolean;
|
|
71
|
+
type: string;
|
|
72
|
+
min?: undefined;
|
|
73
|
+
max?: undefined;
|
|
74
|
+
} | {
|
|
69
75
|
pattern: RegExp;
|
|
70
76
|
support: boolean;
|
|
71
77
|
min: number;
|
|
72
78
|
max: number;
|
|
79
|
+
type?: undefined;
|
|
73
80
|
} | {
|
|
74
81
|
pattern: RegExp;
|
|
75
82
|
support: boolean;
|
|
83
|
+
type?: undefined;
|
|
76
84
|
min?: undefined;
|
|
77
85
|
max?: undefined;
|
|
78
86
|
})[];
|
|
@@ -82,9 +90,16 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
82
90
|
low: number;
|
|
83
91
|
minimal: number;
|
|
84
92
|
};
|
|
93
|
+
protected thinkingLevelMap: {
|
|
94
|
+
high: ThinkingLevel;
|
|
95
|
+
medium: ThinkingLevel;
|
|
96
|
+
low: ThinkingLevel;
|
|
97
|
+
minimal: ThinkingLevel;
|
|
98
|
+
};
|
|
85
99
|
protected getThinkingBudget(model: string, effort: ChatModelInputOptions["reasoningEffort"]): {
|
|
86
100
|
support: boolean;
|
|
87
101
|
budget?: number;
|
|
102
|
+
level?: ThinkingLevel;
|
|
88
103
|
};
|
|
89
104
|
private processInput;
|
|
90
105
|
private buildConfig;
|
|
@@ -3,7 +3,7 @@ import { logger } from "@aigne/core/utils/logger.js";
|
|
|
3
3
|
import { mergeUsage } from "@aigne/core/utils/model-utils.js";
|
|
4
4
|
import { isNonNullable } from "@aigne/core/utils/type-utils.js";
|
|
5
5
|
import { v7 } from "@aigne/uuid";
|
|
6
|
-
import { FunctionCallingConfigMode, GoogleGenAI, } from "@google/genai";
|
|
6
|
+
import { FunctionCallingConfigMode, GoogleGenAI, ThinkingLevel, } from "@google/genai";
|
|
7
7
|
import { z } from "zod";
|
|
8
8
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
9
9
|
const GEMINI_DEFAULT_CHAT_MODEL = "gemini-2.0-flash";
|
|
@@ -60,6 +60,11 @@ export class GeminiChatModel extends ChatModel {
|
|
|
60
60
|
}
|
|
61
61
|
// References: https://ai.google.dev/gemini-api/docs/thinking#set-budget
|
|
62
62
|
thinkingBudgetModelMap = [
|
|
63
|
+
{
|
|
64
|
+
pattern: /gemini-3/,
|
|
65
|
+
support: true,
|
|
66
|
+
type: "level",
|
|
67
|
+
},
|
|
63
68
|
{
|
|
64
69
|
pattern: /gemini-2.5-pro/,
|
|
65
70
|
support: true,
|
|
@@ -89,10 +94,27 @@ export class GeminiChatModel extends ChatModel {
|
|
|
89
94
|
low: 5000,
|
|
90
95
|
minimal: 200,
|
|
91
96
|
};
|
|
97
|
+
thinkingLevelMap = {
|
|
98
|
+
high: ThinkingLevel.HIGH,
|
|
99
|
+
medium: ThinkingLevel.HIGH,
|
|
100
|
+
low: ThinkingLevel.LOW,
|
|
101
|
+
minimal: ThinkingLevel.LOW,
|
|
102
|
+
};
|
|
92
103
|
getThinkingBudget(model, effort) {
|
|
93
104
|
const m = this.thinkingBudgetModelMap.find((i) => i.pattern.test(model));
|
|
94
105
|
if (!m?.support)
|
|
95
106
|
return { support: false };
|
|
107
|
+
if (m.type === "level") {
|
|
108
|
+
let level = ThinkingLevel.THINKING_LEVEL_UNSPECIFIED;
|
|
109
|
+
if (typeof effort === "string") {
|
|
110
|
+
level = this.thinkingLevelMap[effort];
|
|
111
|
+
}
|
|
112
|
+
else if (typeof effort === "number") {
|
|
113
|
+
level =
|
|
114
|
+
effort >= this.thinkingBudgetLevelMap["medium"] ? ThinkingLevel.HIGH : ThinkingLevel.LOW;
|
|
115
|
+
}
|
|
116
|
+
return { support: true, level };
|
|
117
|
+
}
|
|
96
118
|
let budget = typeof effort === "string" ? this.thinkingBudgetLevelMap[effort] || undefined : effort;
|
|
97
119
|
if (typeof budget === "undefined")
|
|
98
120
|
return { support: true };
|
|
@@ -115,6 +137,7 @@ export class GeminiChatModel extends ChatModel {
|
|
|
115
137
|
? {
|
|
116
138
|
includeThoughts: true,
|
|
117
139
|
thinkingBudget: thinkingBudget.budget,
|
|
140
|
+
thinkingLevel: thinkingBudget.level,
|
|
118
141
|
}
|
|
119
142
|
: undefined,
|
|
120
143
|
responseModalities: modelOptions.modalities,
|
|
@@ -168,14 +191,21 @@ export class GeminiChatModel extends ChatModel {
|
|
|
168
191
|
json = part.functionCall.args;
|
|
169
192
|
}
|
|
170
193
|
else {
|
|
171
|
-
|
|
194
|
+
const toolCall = {
|
|
172
195
|
id: part.functionCall.id || v7(),
|
|
173
196
|
type: "function",
|
|
174
197
|
function: {
|
|
175
198
|
name: part.functionCall.name,
|
|
176
199
|
arguments: part.functionCall.args || {},
|
|
177
200
|
},
|
|
178
|
-
}
|
|
201
|
+
};
|
|
202
|
+
// Preserve thought_signature for 3.x models
|
|
203
|
+
if (part.thoughtSignature && model.includes("gemini-3")) {
|
|
204
|
+
toolCall.metadata = {
|
|
205
|
+
thoughtSignature: part.thoughtSignature,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
toolCalls.push(toolCall);
|
|
179
209
|
yield { delta: { json: { toolCalls } } };
|
|
180
210
|
}
|
|
181
211
|
}
|
|
@@ -253,7 +283,8 @@ export class GeminiChatModel extends ChatModel {
|
|
|
253
283
|
usage,
|
|
254
284
|
files: files.length ? files : undefined,
|
|
255
285
|
modelOptions: {
|
|
256
|
-
reasoningEffort: parameters.config?.thinkingConfig?.
|
|
286
|
+
reasoningEffort: parameters.config?.thinkingConfig?.thinkingLevel ||
|
|
287
|
+
parameters.config?.thinkingConfig?.thinkingBudget,
|
|
257
288
|
},
|
|
258
289
|
},
|
|
259
290
|
},
|
|
@@ -337,13 +368,20 @@ export class GeminiChatModel extends ChatModel {
|
|
|
337
368
|
role: msg.role === "agent" ? "model" : msg.role === "user" ? "user" : undefined,
|
|
338
369
|
};
|
|
339
370
|
if (msg.toolCalls) {
|
|
340
|
-
content.parts = msg.toolCalls.map((call) =>
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
371
|
+
content.parts = msg.toolCalls.map((call) => {
|
|
372
|
+
const part = {
|
|
373
|
+
functionCall: {
|
|
374
|
+
id: call.id,
|
|
375
|
+
name: call.function.name,
|
|
376
|
+
args: call.function.arguments,
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
// Restore thought_signature for 3.x models
|
|
380
|
+
if (call.metadata?.thoughtSignature) {
|
|
381
|
+
part.thoughtSignature = call.metadata.thoughtSignature;
|
|
382
|
+
}
|
|
383
|
+
return part;
|
|
384
|
+
});
|
|
347
385
|
}
|
|
348
386
|
else if (msg.toolCallId) {
|
|
349
387
|
const call = input.messages
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/gemini",
|
|
3
|
-
"version": "0.14.10-beta.
|
|
3
|
+
"version": "0.14.10-beta.4",
|
|
4
4
|
"description": "AIGNE Gemini SDK for integrating with Google's Gemini AI models",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -36,10 +36,10 @@
|
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@aigne/uuid": "^13.0.1",
|
|
39
|
-
"@google/genai": "^1.
|
|
39
|
+
"@google/genai": "^1.30.0",
|
|
40
40
|
"zod": "^3.25.67",
|
|
41
41
|
"zod-to-json-schema": "^3.24.6",
|
|
42
|
-
"@aigne/core": "^1.
|
|
42
|
+
"@aigne/core": "^1.69.0-beta.2",
|
|
43
43
|
"@aigne/platform-helpers": "^0.6.4"
|
|
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.63-beta.
|
|
51
|
+
"@aigne/test-utils": "^0.5.63-beta.3"
|
|
52
52
|
},
|
|
53
53
|
"scripts": {
|
|
54
54
|
"lint": "tsc --noEmit",
|