@core-ai/google-genai 0.13.1 → 0.15.0
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/README.md +20 -0
- package/dist/index.d.ts +11 -3
- package/dist/index.js +127 -42
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,3 +26,23 @@ const result = await generate({
|
|
|
26
26
|
|
|
27
27
|
console.log(result.content);
|
|
28
28
|
```
|
|
29
|
+
|
|
30
|
+
## Image generation
|
|
31
|
+
|
|
32
|
+
`imageModel()` supports Gemini native image models and dedicated Imagen models:
|
|
33
|
+
|
|
34
|
+
```ts
|
|
35
|
+
import { generateImage } from '@core-ai/core-ai';
|
|
36
|
+
|
|
37
|
+
const result = await generateImage({
|
|
38
|
+
model: google.imageModel('gemini-2.5-flash-image'),
|
|
39
|
+
prompt: 'A watercolor robot in a mountain cabin at sunrise',
|
|
40
|
+
size: '1024x1024',
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
console.log(result.images[0]?.base64);
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Gemini model IDs use native multimodal generation and return base64 image
|
|
47
|
+
data. Imagen model IDs such as `imagen-4.0-generate-001` use the dedicated
|
|
48
|
+
Imagen API and also support generating multiple images with `n`.
|
package/dist/index.d.ts
CHANGED
|
@@ -2,17 +2,25 @@ import { GoogleGenAI } from '@google/genai';
|
|
|
2
2
|
import { ChatModel, EmbeddingModel, ImageModel, ModelCapabilities } from '@core-ai/core-ai';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
|
-
type
|
|
5
|
+
type GoogleGenAIClient = {
|
|
6
|
+
models: GoogleGenAI['models'];
|
|
7
|
+
};
|
|
8
|
+
type GoogleGenAIProviderBaseOptions = {
|
|
6
9
|
apiKey?: string;
|
|
7
10
|
apiVersion?: string;
|
|
8
11
|
baseUrl?: string;
|
|
9
|
-
client?:
|
|
12
|
+
client?: GoogleGenAIClient;
|
|
13
|
+
};
|
|
14
|
+
type GoogleGenAIProviderFactoryOptions = {
|
|
15
|
+
providerId?: string;
|
|
10
16
|
};
|
|
17
|
+
type GoogleGenAIProviderOptions = GoogleGenAIProviderBaseOptions;
|
|
11
18
|
type GoogleGenAIProvider = {
|
|
12
19
|
chatModel(modelId: string): ChatModel;
|
|
13
20
|
embeddingModel(modelId: string): EmbeddingModel;
|
|
14
21
|
imageModel(modelId: string): ImageModel;
|
|
15
22
|
};
|
|
23
|
+
declare function createGoogleGenAIProvider(options?: GoogleGenAIProviderBaseOptions, factoryOptions?: GoogleGenAIProviderFactoryOptions): GoogleGenAIProvider;
|
|
16
24
|
declare function createGoogleGenAI(options?: GoogleGenAIProviderOptions): GoogleGenAIProvider;
|
|
17
25
|
|
|
18
26
|
type GoogleReasoningMetadata = {
|
|
@@ -90,4 +98,4 @@ declare const googleProviderOptionsSchema: z.ZodObject<{
|
|
|
90
98
|
}, z.core.$strict>;
|
|
91
99
|
type GoogleProviderOptions = GoogleGenerateProviderOptions;
|
|
92
100
|
|
|
93
|
-
export { type GoogleEmbedProviderOptions, type GoogleGenAIProvider, type GoogleGenAIProviderOptions, type GoogleGenerateProviderOptions, type GoogleImageProviderOptions, type GoogleModelCapabilities, type GoogleProviderOptions as GoogleModelProviderOptions, type GoogleReasoningMetadata, createGoogleGenAI, getGoogleModelCapabilities, googleEmbedProviderOptionsSchema, googleGenerateProviderOptionsSchema, googleImageProviderOptionsSchema, googleProviderOptionsSchema };
|
|
101
|
+
export { type GoogleEmbedProviderOptions, type GoogleGenAIClient, type GoogleGenAIProvider, type GoogleGenAIProviderBaseOptions, type GoogleGenAIProviderFactoryOptions, type GoogleGenAIProviderOptions, type GoogleGenerateProviderOptions, type GoogleImageProviderOptions, type GoogleModelCapabilities, type GoogleProviderOptions as GoogleModelProviderOptions, type GoogleReasoningMetadata, createGoogleGenAI, createGoogleGenAIProvider, getGoogleModelCapabilities, googleEmbedProviderOptionsSchema, googleGenerateProviderOptionsSchema, googleImageProviderOptionsSchema, googleProviderOptionsSchema };
|
package/dist/index.js
CHANGED
|
@@ -439,6 +439,7 @@ async function* transformStream(stream) {
|
|
|
439
439
|
const bufferedToolCalls = /* @__PURE__ */ new Map();
|
|
440
440
|
let finishReason = "unknown";
|
|
441
441
|
let sawToolCalls = false;
|
|
442
|
+
let textOpen = false;
|
|
442
443
|
let reasoningOpen = false;
|
|
443
444
|
let usage = {
|
|
444
445
|
inputTokens: 0,
|
|
@@ -459,10 +460,25 @@ async function* transformStream(stream) {
|
|
|
459
460
|
providerMetadata: { google: {} }
|
|
460
461
|
};
|
|
461
462
|
};
|
|
463
|
+
const startText = function* () {
|
|
464
|
+
if (textOpen) {
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
textOpen = true;
|
|
468
|
+
yield { type: "text-start" };
|
|
469
|
+
};
|
|
470
|
+
const closeText = function* () {
|
|
471
|
+
if (!textOpen) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
textOpen = false;
|
|
475
|
+
yield { type: "text-end" };
|
|
476
|
+
};
|
|
462
477
|
for await (const chunk of stream) {
|
|
463
478
|
usage = mapUsage(chunk, usage);
|
|
464
479
|
const reasoningDeltas = extractReasoningDeltas(chunk);
|
|
465
480
|
if (reasoningDeltas.length > 0) {
|
|
481
|
+
yield* closeText();
|
|
466
482
|
if (!reasoningOpen) {
|
|
467
483
|
reasoningOpen = true;
|
|
468
484
|
yield {
|
|
@@ -481,6 +497,7 @@ async function* transformStream(stream) {
|
|
|
481
497
|
if (reasoningEnd2) {
|
|
482
498
|
yield reasoningEnd2;
|
|
483
499
|
}
|
|
500
|
+
yield* startText();
|
|
484
501
|
yield {
|
|
485
502
|
type: "text-delta",
|
|
486
503
|
text: chunk.text
|
|
@@ -488,6 +505,7 @@ async function* transformStream(stream) {
|
|
|
488
505
|
}
|
|
489
506
|
const functionCalls = chunk.functionCalls ?? [];
|
|
490
507
|
if (functionCalls.length > 0) {
|
|
508
|
+
yield* closeText();
|
|
491
509
|
const reasoningEnd2 = closeReasoning();
|
|
492
510
|
if (reasoningEnd2) {
|
|
493
511
|
yield reasoningEnd2;
|
|
@@ -538,6 +556,7 @@ async function* transformStream(stream) {
|
|
|
538
556
|
if (reasoningEnd) {
|
|
539
557
|
yield reasoningEnd;
|
|
540
558
|
}
|
|
559
|
+
yield* closeText();
|
|
541
560
|
for (const toolCall of bufferedToolCalls.values()) {
|
|
542
561
|
yield {
|
|
543
562
|
type: "tool-call-end",
|
|
@@ -665,33 +684,32 @@ function mapUsage(response, fallback) {
|
|
|
665
684
|
// src/google-error.ts
|
|
666
685
|
import { ApiError } from "@google/genai";
|
|
667
686
|
import { ProviderError } from "@core-ai/core-ai";
|
|
668
|
-
function wrapGoogleError(error) {
|
|
687
|
+
function wrapGoogleError(error, provider = "google") {
|
|
669
688
|
if (error instanceof ApiError) {
|
|
670
|
-
return new ProviderError(error.message,
|
|
689
|
+
return new ProviderError(error.message, provider, error.status, error);
|
|
671
690
|
}
|
|
672
691
|
return new ProviderError(
|
|
673
692
|
error instanceof Error ? error.message : String(error),
|
|
674
|
-
|
|
693
|
+
provider,
|
|
675
694
|
void 0,
|
|
676
695
|
error
|
|
677
696
|
);
|
|
678
697
|
}
|
|
679
698
|
|
|
680
699
|
// src/chat-model.ts
|
|
681
|
-
function createGoogleGenAIChatModel(client, modelId) {
|
|
682
|
-
const provider = "google";
|
|
700
|
+
function createGoogleGenAIChatModel(client, modelId, provider = "google") {
|
|
683
701
|
async function callGenerateContentApi(request) {
|
|
684
702
|
try {
|
|
685
703
|
return await client.models.generateContent(request);
|
|
686
704
|
} catch (error) {
|
|
687
|
-
throw wrapGoogleError(error);
|
|
705
|
+
throw wrapGoogleError(error, provider);
|
|
688
706
|
}
|
|
689
707
|
}
|
|
690
708
|
async function callGenerateContentStreamApi(request) {
|
|
691
709
|
try {
|
|
692
710
|
return await client.models.generateContentStream(request);
|
|
693
711
|
} catch (error) {
|
|
694
|
-
throw wrapGoogleError(error);
|
|
712
|
+
throw wrapGoogleError(error, provider);
|
|
695
713
|
}
|
|
696
714
|
}
|
|
697
715
|
async function generateChat(options) {
|
|
@@ -899,9 +917,9 @@ function formatZodIssues(issues) {
|
|
|
899
917
|
}
|
|
900
918
|
|
|
901
919
|
// src/embedding-model.ts
|
|
902
|
-
function createGoogleGenAIEmbeddingModel(client, modelId) {
|
|
920
|
+
function createGoogleGenAIEmbeddingModel(client, modelId, provider = "google") {
|
|
903
921
|
return {
|
|
904
|
-
provider
|
|
922
|
+
provider,
|
|
905
923
|
modelId,
|
|
906
924
|
async embed(options) {
|
|
907
925
|
try {
|
|
@@ -942,7 +960,7 @@ function createGoogleGenAIEmbeddingModel(client, modelId) {
|
|
|
942
960
|
usage
|
|
943
961
|
};
|
|
944
962
|
} catch (error) {
|
|
945
|
-
throw wrapGoogleError(error);
|
|
963
|
+
throw wrapGoogleError(error, provider);
|
|
946
964
|
}
|
|
947
965
|
}
|
|
948
966
|
};
|
|
@@ -957,46 +975,107 @@ function mapGoogleEmbedProviderOptionsToConfig(options) {
|
|
|
957
975
|
}
|
|
958
976
|
|
|
959
977
|
// src/image-model.ts
|
|
960
|
-
function createGoogleGenAIImageModel(client, modelId) {
|
|
978
|
+
function createGoogleGenAIImageModel(client, modelId, provider = "google") {
|
|
961
979
|
return {
|
|
962
|
-
provider
|
|
980
|
+
provider,
|
|
963
981
|
modelId,
|
|
964
982
|
async generate(options) {
|
|
965
983
|
try {
|
|
966
|
-
const baseRequest = {
|
|
967
|
-
model: modelId,
|
|
968
|
-
prompt: options.prompt,
|
|
969
|
-
config: {
|
|
970
|
-
...options.n !== void 0 ? { numberOfImages: options.n } : {},
|
|
971
|
-
...mapSizeToImageConfig(options.size)
|
|
972
|
-
}
|
|
973
|
-
};
|
|
974
984
|
const googleOptions = parseGoogleImageProviderOptions(
|
|
975
985
|
options.providerOptions
|
|
976
986
|
);
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
base64: image.image?.imageBytes ?? void 0,
|
|
989
|
-
url: image.image?.gcsUri ?? void 0,
|
|
990
|
-
revisedPrompt: image.enhancedPrompt ?? void 0
|
|
991
|
-
}))
|
|
992
|
-
};
|
|
987
|
+
return isGeminiImageModel(modelId) ? await generateGeminiImages(
|
|
988
|
+
client,
|
|
989
|
+
modelId,
|
|
990
|
+
options,
|
|
991
|
+
googleOptions
|
|
992
|
+
) : await generateImagenImages(
|
|
993
|
+
client,
|
|
994
|
+
modelId,
|
|
995
|
+
options,
|
|
996
|
+
googleOptions
|
|
997
|
+
);
|
|
993
998
|
} catch (error) {
|
|
994
|
-
throw wrapGoogleError(error);
|
|
999
|
+
throw wrapGoogleError(error, provider);
|
|
1000
|
+
}
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
}
|
|
1004
|
+
function isGeminiImageModel(modelId) {
|
|
1005
|
+
return modelId.startsWith("gemini-");
|
|
1006
|
+
}
|
|
1007
|
+
async function generateGeminiImages(client, modelId, options, googleOptions) {
|
|
1008
|
+
if (options.n !== void 0 && options.n > 1) {
|
|
1009
|
+
throw new Error(
|
|
1010
|
+
"Gemini image generation does not support n greater than 1."
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
const sizeConfig = mapSizeToImageConfig(options.size);
|
|
1014
|
+
const aspectRatio = googleOptions?.aspectRatio ?? sizeConfig["aspectRatio"];
|
|
1015
|
+
const imageSize = supportsGeminiImageSize(modelId) ? googleOptions?.imageSize ?? sizeConfig["imageSize"] : void 0;
|
|
1016
|
+
const imageConfig = {
|
|
1017
|
+
...aspectRatio ? { aspectRatio } : {},
|
|
1018
|
+
...imageSize ? { imageSize } : {}
|
|
1019
|
+
};
|
|
1020
|
+
const request = {
|
|
1021
|
+
model: modelId,
|
|
1022
|
+
contents: [
|
|
1023
|
+
{
|
|
1024
|
+
role: "user",
|
|
1025
|
+
parts: [{ text: options.prompt }]
|
|
1026
|
+
}
|
|
1027
|
+
],
|
|
1028
|
+
config: {
|
|
1029
|
+
responseModalities: ["IMAGE"],
|
|
1030
|
+
...Object.keys(imageConfig).length > 0 ? { imageConfig } : {},
|
|
1031
|
+
...googleOptions?.seed !== void 0 ? { seed: googleOptions.seed } : {}
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
1034
|
+
const response = await client.models.generateContent(request);
|
|
1035
|
+
return mapGeminiImageResponse(response);
|
|
1036
|
+
}
|
|
1037
|
+
function supportsGeminiImageSize(modelId) {
|
|
1038
|
+
return !modelId.startsWith("gemini-2.5-flash-image");
|
|
1039
|
+
}
|
|
1040
|
+
function mapGeminiImageResponse(response) {
|
|
1041
|
+
const parts = response.candidates?.[0]?.content?.parts ?? [];
|
|
1042
|
+
return {
|
|
1043
|
+
images: parts.flatMap((part) => {
|
|
1044
|
+
const inlineData = part.inlineData;
|
|
1045
|
+
if (!inlineData?.data || !inlineData.mimeType?.startsWith("image/")) {
|
|
1046
|
+
return [];
|
|
995
1047
|
}
|
|
1048
|
+
return [{ base64: inlineData.data }];
|
|
1049
|
+
})
|
|
1050
|
+
};
|
|
1051
|
+
}
|
|
1052
|
+
async function generateImagenImages(client, modelId, options, googleOptions) {
|
|
1053
|
+
const baseRequest = {
|
|
1054
|
+
model: modelId,
|
|
1055
|
+
prompt: options.prompt,
|
|
1056
|
+
config: {
|
|
1057
|
+
...options.n !== void 0 ? { numberOfImages: options.n } : {},
|
|
1058
|
+
...mapSizeToImageConfig(options.size)
|
|
996
1059
|
}
|
|
997
1060
|
};
|
|
1061
|
+
const providerConfig = mapImagenImageProviderOptionsToConfig(googleOptions);
|
|
1062
|
+
const request = Object.keys(providerConfig).length > 0 ? {
|
|
1063
|
+
...baseRequest,
|
|
1064
|
+
config: {
|
|
1065
|
+
...baseRequest.config,
|
|
1066
|
+
...providerConfig
|
|
1067
|
+
}
|
|
1068
|
+
} : baseRequest;
|
|
1069
|
+
const response = await client.models.generateImages(request);
|
|
1070
|
+
return {
|
|
1071
|
+
images: (response.generatedImages ?? []).map((image) => ({
|
|
1072
|
+
base64: image.image?.imageBytes ?? void 0,
|
|
1073
|
+
url: image.image?.gcsUri ?? void 0,
|
|
1074
|
+
revisedPrompt: image.enhancedPrompt ?? void 0
|
|
1075
|
+
}))
|
|
1076
|
+
};
|
|
998
1077
|
}
|
|
999
|
-
function
|
|
1078
|
+
function mapImagenImageProviderOptionsToConfig(options) {
|
|
1000
1079
|
return {
|
|
1001
1080
|
...options?.outputGcsUri !== void 0 ? { outputGcsUri: options.outputGcsUri } : {},
|
|
1002
1081
|
...options?.negativePrompt !== void 0 ? { negativePrompt: options.negativePrompt } : {},
|
|
@@ -1052,7 +1131,8 @@ function greatestCommonDivisor(a, b) {
|
|
|
1052
1131
|
}
|
|
1053
1132
|
|
|
1054
1133
|
// src/provider.ts
|
|
1055
|
-
|
|
1134
|
+
var DEFAULT_PROVIDER_ID = "google";
|
|
1135
|
+
function createGoogleGenAIProvider(options = {}, factoryOptions = {}) {
|
|
1056
1136
|
const client = options.client ?? new GoogleGenAI({
|
|
1057
1137
|
apiKey: options.apiKey,
|
|
1058
1138
|
...options.apiVersion ? { apiVersion: options.apiVersion } : {},
|
|
@@ -1062,14 +1142,19 @@ function createGoogleGenAI(options = {}) {
|
|
|
1062
1142
|
}
|
|
1063
1143
|
} : {}
|
|
1064
1144
|
});
|
|
1145
|
+
const providerId = factoryOptions.providerId ?? DEFAULT_PROVIDER_ID;
|
|
1065
1146
|
return {
|
|
1066
|
-
chatModel: (modelId) => createGoogleGenAIChatModel(client, modelId),
|
|
1067
|
-
embeddingModel: (modelId) => createGoogleGenAIEmbeddingModel(client, modelId),
|
|
1068
|
-
imageModel: (modelId) => createGoogleGenAIImageModel(client, modelId)
|
|
1147
|
+
chatModel: (modelId) => createGoogleGenAIChatModel(client, modelId, providerId),
|
|
1148
|
+
embeddingModel: (modelId) => createGoogleGenAIEmbeddingModel(client, modelId, providerId),
|
|
1149
|
+
imageModel: (modelId) => createGoogleGenAIImageModel(client, modelId, providerId)
|
|
1069
1150
|
};
|
|
1070
1151
|
}
|
|
1152
|
+
function createGoogleGenAI(options = {}) {
|
|
1153
|
+
return createGoogleGenAIProvider(options);
|
|
1154
|
+
}
|
|
1071
1155
|
export {
|
|
1072
1156
|
createGoogleGenAI,
|
|
1157
|
+
createGoogleGenAIProvider,
|
|
1073
1158
|
getGoogleModelCapabilities,
|
|
1074
1159
|
googleEmbedProviderOptionsSchema,
|
|
1075
1160
|
googleGenerateProviderOptionsSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@core-ai/google-genai",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Google GenAI provider package for @core-ai/core-ai",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Omnifact (https://omnifact.ai)",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"test:watch": "vitest"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@core-ai/core-ai": "^0.
|
|
48
|
+
"@core-ai/core-ai": "^0.15.0",
|
|
49
49
|
"@google/genai": "^1.42.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|