@aigne/gemini 0.14.16-beta.13 → 0.14.16-beta.16
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 +44 -0
- package/lib/cjs/gemini-chat-model.d.ts +3 -0
- package/lib/cjs/gemini-chat-model.js +48 -10
- package/lib/cjs/gemini-image-model.d.ts +1 -1
- package/lib/cjs/gemini-image-model.js +4 -4
- package/lib/cjs/gemini-video-model.js +3 -3
- package/lib/dts/gemini-chat-model.d.ts +3 -0
- package/lib/dts/gemini-image-model.d.ts +1 -1
- package/lib/esm/gemini-chat-model.d.ts +3 -0
- package/lib/esm/gemini-chat-model.js +49 -11
- package/lib/esm/gemini-image-model.d.ts +1 -1
- package/lib/esm/gemini-image-model.js +4 -4
- package/lib/esm/gemini-video-model.js +3 -3
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,49 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.14.16-beta.16](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.16-beta.15...gemini-v0.14.16-beta.16) (2026-01-10)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* **core:** simplify token-estimator logic for remaining characters ([45d43cc](https://github.com/AIGNE-io/aigne-framework/commit/45d43ccd3afd636cfb459eea2e6551e8f9c53765))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Dependencies
|
|
12
|
+
|
|
13
|
+
* The following workspace dependencies were updated
|
|
14
|
+
* dependencies
|
|
15
|
+
* @aigne/core bumped to 1.72.0-beta.15
|
|
16
|
+
* devDependencies
|
|
17
|
+
* @aigne/test-utils bumped to 0.5.69-beta.15
|
|
18
|
+
|
|
19
|
+
## [0.14.16-beta.15](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.16-beta.14...gemini-v0.14.16-beta.15) (2026-01-09)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
### Dependencies
|
|
23
|
+
|
|
24
|
+
* The following workspace dependencies were updated
|
|
25
|
+
* dependencies
|
|
26
|
+
* @aigne/core bumped to 1.72.0-beta.14
|
|
27
|
+
* devDependencies
|
|
28
|
+
* @aigne/test-utils bumped to 0.5.69-beta.14
|
|
29
|
+
|
|
30
|
+
## [0.14.16-beta.14](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.16-beta.13...gemini-v0.14.16-beta.14) (2026-01-08)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
### Bug Fixes
|
|
34
|
+
|
|
35
|
+
* bump version ([696560f](https://github.com/AIGNE-io/aigne-framework/commit/696560fa2673eddcb4d00ac0523fbbbde7273cb3))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### Dependencies
|
|
39
|
+
|
|
40
|
+
* The following workspace dependencies were updated
|
|
41
|
+
* dependencies
|
|
42
|
+
* @aigne/core bumped to 1.72.0-beta.13
|
|
43
|
+
* @aigne/platform-helpers bumped to 0.6.7-beta.1
|
|
44
|
+
* devDependencies
|
|
45
|
+
* @aigne/test-utils bumped to 0.5.69-beta.13
|
|
46
|
+
|
|
3
47
|
## [0.14.16-beta.13](https://github.com/AIGNE-io/aigne-framework/compare/gemini-v0.14.16-beta.12...gemini-v0.14.16-beta.13) (2026-01-07)
|
|
4
48
|
|
|
5
49
|
|
|
@@ -67,6 +67,8 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
67
67
|
$get: string;
|
|
68
68
|
} | undefined;
|
|
69
69
|
}> | undefined;
|
|
70
|
+
countTokens(input: ChatModelInput): Promise<number>;
|
|
71
|
+
private contentUnionToContent;
|
|
70
72
|
process(input: ChatModelInput, options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
71
73
|
protected thinkingBudgetModelMap: ({
|
|
72
74
|
pattern: RegExp;
|
|
@@ -104,6 +106,7 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
104
106
|
budget?: number;
|
|
105
107
|
level?: ThinkingLevel;
|
|
106
108
|
};
|
|
109
|
+
private getParameters;
|
|
107
110
|
private processInput;
|
|
108
111
|
private buildConfig;
|
|
109
112
|
private buildTools;
|
|
@@ -61,6 +61,40 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
61
61
|
get modelOptions() {
|
|
62
62
|
return this.options?.modelOptions;
|
|
63
63
|
}
|
|
64
|
+
async countTokens(input) {
|
|
65
|
+
const { model, ...request } = await this.getParameters(input);
|
|
66
|
+
const contents = [];
|
|
67
|
+
const { systemInstruction, tools } = request.config ?? {};
|
|
68
|
+
if (systemInstruction)
|
|
69
|
+
contents.push(this.contentUnionToContent(systemInstruction));
|
|
70
|
+
if (tools?.length)
|
|
71
|
+
contents.push({ role: "system", parts: [{ text: JSON.stringify(tools) }] });
|
|
72
|
+
contents.push(...[request.contents].flat().map(this.contentUnionToContent));
|
|
73
|
+
const tokens = (await this.googleClient.models.countTokens({
|
|
74
|
+
model,
|
|
75
|
+
contents,
|
|
76
|
+
})).totalTokens;
|
|
77
|
+
if (!(0, type_utils_js_1.isNil)(tokens))
|
|
78
|
+
return tokens;
|
|
79
|
+
return super.countTokens(input);
|
|
80
|
+
}
|
|
81
|
+
contentUnionToContent(content) {
|
|
82
|
+
if (typeof content === "object" && "parts" in content) {
|
|
83
|
+
return { role: "system", parts: content.parts };
|
|
84
|
+
}
|
|
85
|
+
else if (typeof content === "string") {
|
|
86
|
+
return { role: "system", parts: [{ text: content }] };
|
|
87
|
+
}
|
|
88
|
+
else if (Array.isArray(content)) {
|
|
89
|
+
return {
|
|
90
|
+
role: "system",
|
|
91
|
+
parts: content.map((i) => (typeof i === "string" ? { text: i } : i)),
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return { role: "system", parts: [content] };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
64
98
|
process(input, options) {
|
|
65
99
|
return this.processInput(input, options);
|
|
66
100
|
}
|
|
@@ -135,10 +169,10 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
135
169
|
budget = Math.min(m.max, budget);
|
|
136
170
|
return { support: true, budget };
|
|
137
171
|
}
|
|
138
|
-
async
|
|
172
|
+
async getParameters(input) {
|
|
139
173
|
const { modelOptions = {} } = input;
|
|
140
174
|
const model = modelOptions.model || this.credential.model;
|
|
141
|
-
const { contents, config } = await this.buildContents(input
|
|
175
|
+
const { contents, config } = await this.buildContents(input);
|
|
142
176
|
const thinkingBudget = this.getThinkingBudget(model, modelOptions.reasoningEffort);
|
|
143
177
|
const parameters = {
|
|
144
178
|
model,
|
|
@@ -160,6 +194,10 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
160
194
|
...(await this.buildConfig(input)),
|
|
161
195
|
},
|
|
162
196
|
};
|
|
197
|
+
return parameters;
|
|
198
|
+
}
|
|
199
|
+
async *processInput(input, options) {
|
|
200
|
+
const parameters = await this.getParameters(input);
|
|
163
201
|
const response = await this.googleClient.models.generateContentStream(parameters);
|
|
164
202
|
let usage = {
|
|
165
203
|
inputTokens: 0,
|
|
@@ -211,7 +249,7 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
211
249
|
},
|
|
212
250
|
};
|
|
213
251
|
// Preserve thought_signature for 3.x models
|
|
214
|
-
if (part.thoughtSignature && model.includes("gemini-3")) {
|
|
252
|
+
if (part.thoughtSignature && parameters.model.includes("gemini-3")) {
|
|
215
253
|
toolCall.metadata = {
|
|
216
254
|
thoughtSignature: part.thoughtSignature,
|
|
217
255
|
};
|
|
@@ -362,8 +400,8 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
362
400
|
};
|
|
363
401
|
return { tools, toolConfig: { functionCallingConfig } };
|
|
364
402
|
}
|
|
365
|
-
async buildVideoContentParts(media
|
|
366
|
-
const { path: filePath, mimeType: fileMimeType } = await this.transformFileType("local", media
|
|
403
|
+
async buildVideoContentParts(media) {
|
|
404
|
+
const { path: filePath, mimeType: fileMimeType } = await this.transformFileType("local", media);
|
|
367
405
|
if (filePath) {
|
|
368
406
|
const stats = await index_js_1.nodejs.fs.stat(filePath);
|
|
369
407
|
const fileSizeInBytes = stats.size;
|
|
@@ -394,7 +432,7 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
394
432
|
}
|
|
395
433
|
}
|
|
396
434
|
}
|
|
397
|
-
async buildContents(input
|
|
435
|
+
async buildContents(input) {
|
|
398
436
|
const result = {
|
|
399
437
|
contents: [],
|
|
400
438
|
};
|
|
@@ -472,12 +510,12 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
472
510
|
functionResponse.response = toolResult;
|
|
473
511
|
}
|
|
474
512
|
else {
|
|
475
|
-
functionResponse.parts = await this.contentToParts(msg.content
|
|
513
|
+
functionResponse.parts = await this.contentToParts(msg.content);
|
|
476
514
|
}
|
|
477
515
|
content.parts = [{ functionResponse }];
|
|
478
516
|
}
|
|
479
517
|
else if (msg.content) {
|
|
480
|
-
content.parts = await this.contentToParts(msg.content
|
|
518
|
+
content.parts = await this.contentToParts(msg.content);
|
|
481
519
|
}
|
|
482
520
|
return content;
|
|
483
521
|
}))).filter(type_utils_js_1.isNonNullable);
|
|
@@ -488,7 +526,7 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
488
526
|
}
|
|
489
527
|
return result;
|
|
490
528
|
}
|
|
491
|
-
async contentToParts(content
|
|
529
|
+
async contentToParts(content) {
|
|
492
530
|
if (typeof content === "string")
|
|
493
531
|
return [{ text: content }];
|
|
494
532
|
return Promise.all(content.map(async (item) => {
|
|
@@ -498,7 +536,7 @@ class GeminiChatModel extends core_1.ChatModel {
|
|
|
498
536
|
case "url":
|
|
499
537
|
return { fileData: { fileUri: item.url, mimeType: item.mimeType } };
|
|
500
538
|
case "file": {
|
|
501
|
-
const part = await this.buildVideoContentParts(item
|
|
539
|
+
const part = await this.buildVideoContentParts(item);
|
|
502
540
|
if (part)
|
|
503
541
|
return part;
|
|
504
542
|
return { inlineData: { data: item.data, mimeType: item.mimeType } };
|
|
@@ -28,7 +28,7 @@ export declare class GeminiImageModel extends ImageModel<GeminiImageModelInput,
|
|
|
28
28
|
* @param input The input to process
|
|
29
29
|
* @returns The generated response
|
|
30
30
|
*/
|
|
31
|
-
process(input: GeminiImageModelInput,
|
|
31
|
+
process(input: GeminiImageModelInput, _options: AgentInvokeOptions): Promise<ImageModelOutput>;
|
|
32
32
|
private generateImageByImagenModel;
|
|
33
33
|
private generateImageByGeminiModel;
|
|
34
34
|
}
|
|
@@ -52,7 +52,7 @@ class GeminiImageModel extends core_1.ImageModel {
|
|
|
52
52
|
* @param input The input to process
|
|
53
53
|
* @returns The generated response
|
|
54
54
|
*/
|
|
55
|
-
async process(input,
|
|
55
|
+
async process(input, _options) {
|
|
56
56
|
const model = input.modelOptions?.model || this.credential.model;
|
|
57
57
|
const responseFormat = input.responseFormat || "base64";
|
|
58
58
|
if (responseFormat === "url") {
|
|
@@ -61,7 +61,7 @@ class GeminiImageModel extends core_1.ImageModel {
|
|
|
61
61
|
if (model.includes("imagen")) {
|
|
62
62
|
return this.generateImageByImagenModel(input);
|
|
63
63
|
}
|
|
64
|
-
return this.generateImageByGeminiModel(input
|
|
64
|
+
return this.generateImageByGeminiModel(input);
|
|
65
65
|
}
|
|
66
66
|
async generateImageByImagenModel(input) {
|
|
67
67
|
const model = input.modelOptions?.model || this.credential.model;
|
|
@@ -100,7 +100,7 @@ class GeminiImageModel extends core_1.ImageModel {
|
|
|
100
100
|
model,
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
|
-
async generateImageByGeminiModel(input
|
|
103
|
+
async generateImageByGeminiModel(input) {
|
|
104
104
|
const model = input.modelOptions?.model || this.credential.model;
|
|
105
105
|
const mergedInput = { ...this.modelOptions, ...input.modelOptions, ...input };
|
|
106
106
|
const inputKeys = [
|
|
@@ -135,7 +135,7 @@ class GeminiImageModel extends core_1.ImageModel {
|
|
|
135
135
|
"imageConfig",
|
|
136
136
|
];
|
|
137
137
|
const images = await Promise.all((0, type_utils_js_1.flat)(input.image).map(async (image) => {
|
|
138
|
-
const { data, mimeType } = await this.transformFileType("file", image
|
|
138
|
+
const { data, mimeType } = await this.transformFileType("file", image);
|
|
139
139
|
return { inlineData: { data, mimeType } };
|
|
140
140
|
}));
|
|
141
141
|
const response = await this.client.models.generateContent({
|
|
@@ -88,7 +88,7 @@ class GeminiVideoModel extends core_1.VideoModel {
|
|
|
88
88
|
if (mergedInput.personGeneration)
|
|
89
89
|
config.personGeneration = mergedInput.personGeneration;
|
|
90
90
|
if (mergedInput.lastFrame) {
|
|
91
|
-
config.lastFrame = await this.transformFileType("file", mergedInput.lastFrame
|
|
91
|
+
config.lastFrame = await this.transformFileType("file", mergedInput.lastFrame).then((file) => {
|
|
92
92
|
return {
|
|
93
93
|
imageBytes: file.data,
|
|
94
94
|
mimeType: file.mimeType,
|
|
@@ -97,7 +97,7 @@ class GeminiVideoModel extends core_1.VideoModel {
|
|
|
97
97
|
}
|
|
98
98
|
if (mergedInput.referenceImages) {
|
|
99
99
|
config.referenceImages = await Promise.all(mergedInput.referenceImages.map(async (image) => {
|
|
100
|
-
return await this.transformFileType("file", image
|
|
100
|
+
return await this.transformFileType("file", image).then((file) => {
|
|
101
101
|
return {
|
|
102
102
|
image: {
|
|
103
103
|
imageBytes: file.data,
|
|
@@ -113,7 +113,7 @@ class GeminiVideoModel extends core_1.VideoModel {
|
|
|
113
113
|
config,
|
|
114
114
|
};
|
|
115
115
|
if (mergedInput.image) {
|
|
116
|
-
params.image = await this.transformFileType("file", mergedInput.image
|
|
116
|
+
params.image = await this.transformFileType("file", mergedInput.image).then((file) => {
|
|
117
117
|
return {
|
|
118
118
|
imageBytes: file.data,
|
|
119
119
|
mimeType: file.mimeType,
|
|
@@ -67,6 +67,8 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
67
67
|
$get: string;
|
|
68
68
|
} | undefined;
|
|
69
69
|
}> | undefined;
|
|
70
|
+
countTokens(input: ChatModelInput): Promise<number>;
|
|
71
|
+
private contentUnionToContent;
|
|
70
72
|
process(input: ChatModelInput, options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
71
73
|
protected thinkingBudgetModelMap: ({
|
|
72
74
|
pattern: RegExp;
|
|
@@ -104,6 +106,7 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
104
106
|
budget?: number;
|
|
105
107
|
level?: ThinkingLevel;
|
|
106
108
|
};
|
|
109
|
+
private getParameters;
|
|
107
110
|
private processInput;
|
|
108
111
|
private buildConfig;
|
|
109
112
|
private buildTools;
|
|
@@ -28,7 +28,7 @@ export declare class GeminiImageModel extends ImageModel<GeminiImageModelInput,
|
|
|
28
28
|
* @param input The input to process
|
|
29
29
|
* @returns The generated response
|
|
30
30
|
*/
|
|
31
|
-
process(input: GeminiImageModelInput,
|
|
31
|
+
process(input: GeminiImageModelInput, _options: AgentInvokeOptions): Promise<ImageModelOutput>;
|
|
32
32
|
private generateImageByImagenModel;
|
|
33
33
|
private generateImageByGeminiModel;
|
|
34
34
|
}
|
|
@@ -67,6 +67,8 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
67
67
|
$get: string;
|
|
68
68
|
} | undefined;
|
|
69
69
|
}> | undefined;
|
|
70
|
+
countTokens(input: ChatModelInput): Promise<number>;
|
|
71
|
+
private contentUnionToContent;
|
|
70
72
|
process(input: ChatModelInput, options: AgentInvokeOptions): PromiseOrValue<AgentProcessResult<ChatModelOutput>>;
|
|
71
73
|
protected thinkingBudgetModelMap: ({
|
|
72
74
|
pattern: RegExp;
|
|
@@ -104,6 +106,7 @@ export declare class GeminiChatModel extends ChatModel {
|
|
|
104
106
|
budget?: number;
|
|
105
107
|
level?: ThinkingLevel;
|
|
106
108
|
};
|
|
109
|
+
private getParameters;
|
|
107
110
|
private processInput;
|
|
108
111
|
private buildConfig;
|
|
109
112
|
private buildTools;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { agentProcessResultToObject, ChatModel, StructuredOutputError, safeParseJSON, } from "@aigne/core";
|
|
2
2
|
import { logger } from "@aigne/core/utils/logger.js";
|
|
3
3
|
import { mergeUsage } from "@aigne/core/utils/model-utils.js";
|
|
4
|
-
import { isNonNullable, isRecord } from "@aigne/core/utils/type-utils.js";
|
|
4
|
+
import { isNil, isNonNullable, isRecord, } from "@aigne/core/utils/type-utils.js";
|
|
5
5
|
import { nodejs } from "@aigne/platform-helpers/nodejs/index.js";
|
|
6
6
|
import { v7 } from "@aigne/uuid";
|
|
7
7
|
import { createPartFromUri, createUserContent, FunctionCallingConfigMode, GoogleGenAI, ThinkingLevel, } from "@google/genai";
|
|
@@ -58,6 +58,40 @@ export class GeminiChatModel extends ChatModel {
|
|
|
58
58
|
get modelOptions() {
|
|
59
59
|
return this.options?.modelOptions;
|
|
60
60
|
}
|
|
61
|
+
async countTokens(input) {
|
|
62
|
+
const { model, ...request } = await this.getParameters(input);
|
|
63
|
+
const contents = [];
|
|
64
|
+
const { systemInstruction, tools } = request.config ?? {};
|
|
65
|
+
if (systemInstruction)
|
|
66
|
+
contents.push(this.contentUnionToContent(systemInstruction));
|
|
67
|
+
if (tools?.length)
|
|
68
|
+
contents.push({ role: "system", parts: [{ text: JSON.stringify(tools) }] });
|
|
69
|
+
contents.push(...[request.contents].flat().map(this.contentUnionToContent));
|
|
70
|
+
const tokens = (await this.googleClient.models.countTokens({
|
|
71
|
+
model,
|
|
72
|
+
contents,
|
|
73
|
+
})).totalTokens;
|
|
74
|
+
if (!isNil(tokens))
|
|
75
|
+
return tokens;
|
|
76
|
+
return super.countTokens(input);
|
|
77
|
+
}
|
|
78
|
+
contentUnionToContent(content) {
|
|
79
|
+
if (typeof content === "object" && "parts" in content) {
|
|
80
|
+
return { role: "system", parts: content.parts };
|
|
81
|
+
}
|
|
82
|
+
else if (typeof content === "string") {
|
|
83
|
+
return { role: "system", parts: [{ text: content }] };
|
|
84
|
+
}
|
|
85
|
+
else if (Array.isArray(content)) {
|
|
86
|
+
return {
|
|
87
|
+
role: "system",
|
|
88
|
+
parts: content.map((i) => (typeof i === "string" ? { text: i } : i)),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return { role: "system", parts: [content] };
|
|
93
|
+
}
|
|
94
|
+
}
|
|
61
95
|
process(input, options) {
|
|
62
96
|
return this.processInput(input, options);
|
|
63
97
|
}
|
|
@@ -132,10 +166,10 @@ export class GeminiChatModel extends ChatModel {
|
|
|
132
166
|
budget = Math.min(m.max, budget);
|
|
133
167
|
return { support: true, budget };
|
|
134
168
|
}
|
|
135
|
-
async
|
|
169
|
+
async getParameters(input) {
|
|
136
170
|
const { modelOptions = {} } = input;
|
|
137
171
|
const model = modelOptions.model || this.credential.model;
|
|
138
|
-
const { contents, config } = await this.buildContents(input
|
|
172
|
+
const { contents, config } = await this.buildContents(input);
|
|
139
173
|
const thinkingBudget = this.getThinkingBudget(model, modelOptions.reasoningEffort);
|
|
140
174
|
const parameters = {
|
|
141
175
|
model,
|
|
@@ -157,6 +191,10 @@ export class GeminiChatModel extends ChatModel {
|
|
|
157
191
|
...(await this.buildConfig(input)),
|
|
158
192
|
},
|
|
159
193
|
};
|
|
194
|
+
return parameters;
|
|
195
|
+
}
|
|
196
|
+
async *processInput(input, options) {
|
|
197
|
+
const parameters = await this.getParameters(input);
|
|
160
198
|
const response = await this.googleClient.models.generateContentStream(parameters);
|
|
161
199
|
let usage = {
|
|
162
200
|
inputTokens: 0,
|
|
@@ -208,7 +246,7 @@ export class GeminiChatModel extends ChatModel {
|
|
|
208
246
|
},
|
|
209
247
|
};
|
|
210
248
|
// Preserve thought_signature for 3.x models
|
|
211
|
-
if (part.thoughtSignature && model.includes("gemini-3")) {
|
|
249
|
+
if (part.thoughtSignature && parameters.model.includes("gemini-3")) {
|
|
212
250
|
toolCall.metadata = {
|
|
213
251
|
thoughtSignature: part.thoughtSignature,
|
|
214
252
|
};
|
|
@@ -359,8 +397,8 @@ export class GeminiChatModel extends ChatModel {
|
|
|
359
397
|
};
|
|
360
398
|
return { tools, toolConfig: { functionCallingConfig } };
|
|
361
399
|
}
|
|
362
|
-
async buildVideoContentParts(media
|
|
363
|
-
const { path: filePath, mimeType: fileMimeType } = await this.transformFileType("local", media
|
|
400
|
+
async buildVideoContentParts(media) {
|
|
401
|
+
const { path: filePath, mimeType: fileMimeType } = await this.transformFileType("local", media);
|
|
364
402
|
if (filePath) {
|
|
365
403
|
const stats = await nodejs.fs.stat(filePath);
|
|
366
404
|
const fileSizeInBytes = stats.size;
|
|
@@ -391,7 +429,7 @@ export class GeminiChatModel extends ChatModel {
|
|
|
391
429
|
}
|
|
392
430
|
}
|
|
393
431
|
}
|
|
394
|
-
async buildContents(input
|
|
432
|
+
async buildContents(input) {
|
|
395
433
|
const result = {
|
|
396
434
|
contents: [],
|
|
397
435
|
};
|
|
@@ -469,12 +507,12 @@ export class GeminiChatModel extends ChatModel {
|
|
|
469
507
|
functionResponse.response = toolResult;
|
|
470
508
|
}
|
|
471
509
|
else {
|
|
472
|
-
functionResponse.parts = await this.contentToParts(msg.content
|
|
510
|
+
functionResponse.parts = await this.contentToParts(msg.content);
|
|
473
511
|
}
|
|
474
512
|
content.parts = [{ functionResponse }];
|
|
475
513
|
}
|
|
476
514
|
else if (msg.content) {
|
|
477
|
-
content.parts = await this.contentToParts(msg.content
|
|
515
|
+
content.parts = await this.contentToParts(msg.content);
|
|
478
516
|
}
|
|
479
517
|
return content;
|
|
480
518
|
}))).filter(isNonNullable);
|
|
@@ -485,7 +523,7 @@ export class GeminiChatModel extends ChatModel {
|
|
|
485
523
|
}
|
|
486
524
|
return result;
|
|
487
525
|
}
|
|
488
|
-
async contentToParts(content
|
|
526
|
+
async contentToParts(content) {
|
|
489
527
|
if (typeof content === "string")
|
|
490
528
|
return [{ text: content }];
|
|
491
529
|
return Promise.all(content.map(async (item) => {
|
|
@@ -495,7 +533,7 @@ export class GeminiChatModel extends ChatModel {
|
|
|
495
533
|
case "url":
|
|
496
534
|
return { fileData: { fileUri: item.url, mimeType: item.mimeType } };
|
|
497
535
|
case "file": {
|
|
498
|
-
const part = await this.buildVideoContentParts(item
|
|
536
|
+
const part = await this.buildVideoContentParts(item);
|
|
499
537
|
if (part)
|
|
500
538
|
return part;
|
|
501
539
|
return { inlineData: { data: item.data, mimeType: item.mimeType } };
|
|
@@ -28,7 +28,7 @@ export declare class GeminiImageModel extends ImageModel<GeminiImageModelInput,
|
|
|
28
28
|
* @param input The input to process
|
|
29
29
|
* @returns The generated response
|
|
30
30
|
*/
|
|
31
|
-
process(input: GeminiImageModelInput,
|
|
31
|
+
process(input: GeminiImageModelInput, _options: AgentInvokeOptions): Promise<ImageModelOutput>;
|
|
32
32
|
private generateImageByImagenModel;
|
|
33
33
|
private generateImageByGeminiModel;
|
|
34
34
|
}
|
|
@@ -49,7 +49,7 @@ export class GeminiImageModel extends ImageModel {
|
|
|
49
49
|
* @param input The input to process
|
|
50
50
|
* @returns The generated response
|
|
51
51
|
*/
|
|
52
|
-
async process(input,
|
|
52
|
+
async process(input, _options) {
|
|
53
53
|
const model = input.modelOptions?.model || this.credential.model;
|
|
54
54
|
const responseFormat = input.responseFormat || "base64";
|
|
55
55
|
if (responseFormat === "url") {
|
|
@@ -58,7 +58,7 @@ export class GeminiImageModel extends ImageModel {
|
|
|
58
58
|
if (model.includes("imagen")) {
|
|
59
59
|
return this.generateImageByImagenModel(input);
|
|
60
60
|
}
|
|
61
|
-
return this.generateImageByGeminiModel(input
|
|
61
|
+
return this.generateImageByGeminiModel(input);
|
|
62
62
|
}
|
|
63
63
|
async generateImageByImagenModel(input) {
|
|
64
64
|
const model = input.modelOptions?.model || this.credential.model;
|
|
@@ -97,7 +97,7 @@ export class GeminiImageModel extends ImageModel {
|
|
|
97
97
|
model,
|
|
98
98
|
};
|
|
99
99
|
}
|
|
100
|
-
async generateImageByGeminiModel(input
|
|
100
|
+
async generateImageByGeminiModel(input) {
|
|
101
101
|
const model = input.modelOptions?.model || this.credential.model;
|
|
102
102
|
const mergedInput = { ...this.modelOptions, ...input.modelOptions, ...input };
|
|
103
103
|
const inputKeys = [
|
|
@@ -132,7 +132,7 @@ export class GeminiImageModel extends ImageModel {
|
|
|
132
132
|
"imageConfig",
|
|
133
133
|
];
|
|
134
134
|
const images = await Promise.all(flat(input.image).map(async (image) => {
|
|
135
|
-
const { data, mimeType } = await this.transformFileType("file", image
|
|
135
|
+
const { data, mimeType } = await this.transformFileType("file", image);
|
|
136
136
|
return { inlineData: { data, mimeType } };
|
|
137
137
|
}));
|
|
138
138
|
const response = await this.client.models.generateContent({
|
|
@@ -85,7 +85,7 @@ export class GeminiVideoModel extends VideoModel {
|
|
|
85
85
|
if (mergedInput.personGeneration)
|
|
86
86
|
config.personGeneration = mergedInput.personGeneration;
|
|
87
87
|
if (mergedInput.lastFrame) {
|
|
88
|
-
config.lastFrame = await this.transformFileType("file", mergedInput.lastFrame
|
|
88
|
+
config.lastFrame = await this.transformFileType("file", mergedInput.lastFrame).then((file) => {
|
|
89
89
|
return {
|
|
90
90
|
imageBytes: file.data,
|
|
91
91
|
mimeType: file.mimeType,
|
|
@@ -94,7 +94,7 @@ export class GeminiVideoModel extends VideoModel {
|
|
|
94
94
|
}
|
|
95
95
|
if (mergedInput.referenceImages) {
|
|
96
96
|
config.referenceImages = await Promise.all(mergedInput.referenceImages.map(async (image) => {
|
|
97
|
-
return await this.transformFileType("file", image
|
|
97
|
+
return await this.transformFileType("file", image).then((file) => {
|
|
98
98
|
return {
|
|
99
99
|
image: {
|
|
100
100
|
imageBytes: file.data,
|
|
@@ -110,7 +110,7 @@ export class GeminiVideoModel extends VideoModel {
|
|
|
110
110
|
config,
|
|
111
111
|
};
|
|
112
112
|
if (mergedInput.image) {
|
|
113
|
-
params.image = await this.transformFileType("file", mergedInput.image
|
|
113
|
+
params.image = await this.transformFileType("file", mergedInput.image).then((file) => {
|
|
114
114
|
return {
|
|
115
115
|
imageBytes: file.data,
|
|
116
116
|
mimeType: file.mimeType,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aigne/gemini",
|
|
3
|
-
"version": "0.14.16-beta.
|
|
3
|
+
"version": "0.14.16-beta.16",
|
|
4
4
|
"description": "AIGNE Gemini SDK for integrating with Google's Gemini AI models",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -40,8 +40,8 @@
|
|
|
40
40
|
"yaml": "^2.8.1",
|
|
41
41
|
"zod": "^3.25.67",
|
|
42
42
|
"zod-to-json-schema": "^3.24.6",
|
|
43
|
-
"@aigne/core": "^1.72.0-beta.
|
|
44
|
-
"@aigne/platform-helpers": "^0.6.7-beta"
|
|
43
|
+
"@aigne/core": "^1.72.0-beta.15",
|
|
44
|
+
"@aigne/platform-helpers": "^0.6.7-beta.1"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
47
|
"@types/bun": "^1.2.22",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"npm-run-all": "^4.1.5",
|
|
50
50
|
"rimraf": "^6.0.1",
|
|
51
51
|
"typescript": "^5.9.2",
|
|
52
|
-
"@aigne/test-utils": "^0.5.69-beta.
|
|
52
|
+
"@aigne/test-utils": "^0.5.69-beta.15"
|
|
53
53
|
},
|
|
54
54
|
"scripts": {
|
|
55
55
|
"lint": "tsc --noEmit",
|