@workglow/google-gemini 0.2.28

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.
Files changed (59) hide show
  1. package/dist/ai-provider/GoogleGeminiProvider.d.ts +27 -0
  2. package/dist/ai-provider/GoogleGeminiProvider.d.ts.map +1 -0
  3. package/dist/ai-provider/GoogleGeminiQueuedProvider.d.ts +18 -0
  4. package/dist/ai-provider/GoogleGeminiQueuedProvider.d.ts.map +1 -0
  5. package/dist/ai-provider/common/Gemini_Chat.d.ts +10 -0
  6. package/dist/ai-provider/common/Gemini_Chat.d.ts.map +1 -0
  7. package/dist/ai-provider/common/Gemini_Client.d.ts +10 -0
  8. package/dist/ai-provider/common/Gemini_Client.d.ts.map +1 -0
  9. package/dist/ai-provider/common/Gemini_Constants.d.ts +7 -0
  10. package/dist/ai-provider/common/Gemini_Constants.d.ts.map +1 -0
  11. package/dist/ai-provider/common/Gemini_CountTokens.d.ts +10 -0
  12. package/dist/ai-provider/common/Gemini_CountTokens.d.ts.map +1 -0
  13. package/dist/ai-provider/common/Gemini_ImageEdit.d.ts +15 -0
  14. package/dist/ai-provider/common/Gemini_ImageEdit.d.ts.map +1 -0
  15. package/dist/ai-provider/common/Gemini_ImageGenerate.d.ts +16 -0
  16. package/dist/ai-provider/common/Gemini_ImageGenerate.d.ts.map +1 -0
  17. package/dist/ai-provider/common/Gemini_ImageValidation.d.ts +14 -0
  18. package/dist/ai-provider/common/Gemini_ImageValidation.d.ts.map +1 -0
  19. package/dist/ai-provider/common/Gemini_JobRunFns.d.ts +13 -0
  20. package/dist/ai-provider/common/Gemini_JobRunFns.d.ts.map +1 -0
  21. package/dist/ai-provider/common/Gemini_ModelInfo.d.ts +9 -0
  22. package/dist/ai-provider/common/Gemini_ModelInfo.d.ts.map +1 -0
  23. package/dist/ai-provider/common/Gemini_ModelSchema.d.ts +170 -0
  24. package/dist/ai-provider/common/Gemini_ModelSchema.d.ts.map +1 -0
  25. package/dist/ai-provider/common/Gemini_ModelSearch.d.ts +8 -0
  26. package/dist/ai-provider/common/Gemini_ModelSearch.d.ts.map +1 -0
  27. package/dist/ai-provider/common/Gemini_Schema.d.ts +11 -0
  28. package/dist/ai-provider/common/Gemini_Schema.d.ts.map +1 -0
  29. package/dist/ai-provider/common/Gemini_StructuredGeneration.d.ts +10 -0
  30. package/dist/ai-provider/common/Gemini_StructuredGeneration.d.ts.map +1 -0
  31. package/dist/ai-provider/common/Gemini_TextEmbedding.d.ts +9 -0
  32. package/dist/ai-provider/common/Gemini_TextEmbedding.d.ts.map +1 -0
  33. package/dist/ai-provider/common/Gemini_TextGeneration.d.ts +10 -0
  34. package/dist/ai-provider/common/Gemini_TextGeneration.d.ts.map +1 -0
  35. package/dist/ai-provider/common/Gemini_TextRewriter.d.ts +10 -0
  36. package/dist/ai-provider/common/Gemini_TextRewriter.d.ts.map +1 -0
  37. package/dist/ai-provider/common/Gemini_TextSummary.d.ts +10 -0
  38. package/dist/ai-provider/common/Gemini_TextSummary.d.ts.map +1 -0
  39. package/dist/ai-provider/common/Gemini_ToolCalling.d.ts +11 -0
  40. package/dist/ai-provider/common/Gemini_ToolCalling.d.ts.map +1 -0
  41. package/dist/ai-provider/index.d.ts +11 -0
  42. package/dist/ai-provider/index.d.ts.map +1 -0
  43. package/dist/ai-provider/registerGemini.d.ts +10 -0
  44. package/dist/ai-provider/registerGemini.d.ts.map +1 -0
  45. package/dist/ai-provider/registerGeminiInline.d.ts +8 -0
  46. package/dist/ai-provider/registerGeminiInline.d.ts.map +1 -0
  47. package/dist/ai-provider/registerGeminiWorker.d.ts +7 -0
  48. package/dist/ai-provider/registerGeminiWorker.d.ts.map +1 -0
  49. package/dist/ai-provider/runtime.d.ts +16 -0
  50. package/dist/ai-provider/runtime.d.ts.map +1 -0
  51. package/dist/ai-provider-runtime.d.ts +7 -0
  52. package/dist/ai-provider-runtime.d.ts.map +1 -0
  53. package/dist/ai-provider-runtime.js +871 -0
  54. package/dist/ai-provider-runtime.js.map +30 -0
  55. package/dist/ai-provider.d.ts +7 -0
  56. package/dist/ai-provider.d.ts.map +1 -0
  57. package/dist/ai-provider.js +233 -0
  58. package/dist/ai-provider.js.map +15 -0
  59. package/package.json +60 -0
@@ -0,0 +1,871 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined")
5
+ return require.apply(this, arguments);
6
+ throw Error('Dynamic require of "' + x + '" is not supported');
7
+ });
8
+
9
+ // src/ai-provider/common/Gemini_Client.ts
10
+ var _sdk;
11
+ async function loadGeminiSDK() {
12
+ if (!_sdk) {
13
+ try {
14
+ _sdk = await import("@google/generative-ai");
15
+ } catch {
16
+ throw new Error("@google/generative-ai is required for Gemini tasks. Install it with: bun add @google/generative-ai");
17
+ }
18
+ }
19
+ return _sdk.GoogleGenerativeAI;
20
+ }
21
+ function getApiKey(model) {
22
+ const config = model?.provider_config;
23
+ const apiKey = config?.credential_key || config?.api_key || (typeof process !== "undefined" ? process.env?.GOOGLE_API_KEY || process.env?.GEMINI_API_KEY : undefined);
24
+ if (!apiKey) {
25
+ throw new Error("Missing Google API key: set provider_config.credential_key or the GOOGLE_API_KEY / GEMINI_API_KEY environment variable.");
26
+ }
27
+ return apiKey;
28
+ }
29
+ function getModelName(model) {
30
+ const name = model?.provider_config?.model_name;
31
+ if (!name) {
32
+ throw new Error("Missing model name in provider_config.model_name.");
33
+ }
34
+ return name;
35
+ }
36
+
37
+ // src/ai-provider/registerGeminiInline.ts
38
+ import { registerProviderInline } from "@workglow/ai-provider/common";
39
+
40
+ // src/ai-provider/common/Gemini_ModelSearch.ts
41
+ import { normalizedModelSearchQuery } from "@workglow/ai-provider/common";
42
+
43
+ // src/ai-provider/common/Gemini_Constants.ts
44
+ var GOOGLE_GEMINI = "GOOGLE_GEMINI";
45
+
46
+ // src/ai-provider/common/Gemini_ModelSearch.ts
47
+ var GEMINI_MODELS = [
48
+ { label: "gemini-3.1-pro-preview", value: "gemini-3.1-pro-preview" },
49
+ { label: "gemini-3-flash-preview", value: "gemini-3-flash-preview" },
50
+ { label: "gemini-3.1-flash-lite-preview", value: "gemini-3.1-flash-lite-preview" },
51
+ { label: "gemini-2.5-flash", value: "gemini-2.5-flash" },
52
+ { label: "gemini-2.5-pro", value: "gemini-2.5-pro" },
53
+ {
54
+ label: "gemini-embedding-2",
55
+ value: "gemini-embedding-2",
56
+ tasks: ["TextEmbeddingTask"]
57
+ },
58
+ {
59
+ label: "gemini-embedding-001",
60
+ value: "gemini-embedding-001",
61
+ tasks: ["TextEmbeddingTask"]
62
+ },
63
+ {
64
+ label: "gemini-3.1-flash-image-preview",
65
+ value: "gemini-3.1-flash-image-preview",
66
+ tasks: ["ImageGenerateTask", "ImageEditTask"]
67
+ },
68
+ {
69
+ label: "gemini-3-pro-image-preview",
70
+ value: "gemini-3-pro-image-preview",
71
+ tasks: ["ImageGenerateTask", "ImageEditTask"]
72
+ },
73
+ {
74
+ label: "imagen-4.0-generate-001",
75
+ value: "imagen-4.0-generate-001",
76
+ tasks: ["ImageGenerateTask"]
77
+ }
78
+ ];
79
+ function tasksForGeminiApiModel(model, id) {
80
+ const staticEntry = GEMINI_MODELS.find((m) => m.value === id);
81
+ if (staticEntry?.tasks)
82
+ return [...staticEntry.tasks];
83
+ const methods = model.supportedGenerationMethods ?? [];
84
+ if (methods.some((method) => method.toLowerCase().includes("embed"))) {
85
+ return ["TextEmbeddingTask"];
86
+ }
87
+ return [];
88
+ }
89
+ function mapGeminiModel(model) {
90
+ const id = model.name.startsWith("models/") ? model.name.slice("models/".length) : model.name;
91
+ const title = model.displayName || id;
92
+ return {
93
+ id,
94
+ label: model.displayName ? `${id} ${model.displayName}` : id,
95
+ description: model.description ?? "",
96
+ record: {
97
+ model_id: id,
98
+ provider: GOOGLE_GEMINI,
99
+ title,
100
+ description: model.description ?? "",
101
+ tasks: tasksForGeminiApiModel(model, id),
102
+ provider_config: { model_name: id },
103
+ metadata: {}
104
+ },
105
+ raw: model
106
+ };
107
+ }
108
+ async function listGeminiModels(credentialKey, signal) {
109
+ const params = new URLSearchParams({ key: credentialKey });
110
+ const response = await fetch(`https://generativelanguage.googleapis.com/v1beta/models?${params}`, {
111
+ signal
112
+ });
113
+ if (!response.ok)
114
+ throw new Error(`Gemini API returned ${response.status}`);
115
+ const body = await response.json();
116
+ return (body.models ?? []).map(mapGeminiModel);
117
+ }
118
+ var Gemini_ModelSearch = async (input, _model, _onProgress, signal) => {
119
+ const q = normalizedModelSearchQuery(input.query);
120
+ if (input.credential_key) {
121
+ const models = await listGeminiModels(input.credential_key, signal);
122
+ const results2 = q ? models.filter((m) => m.id.toLowerCase().includes(q) || m.label.toLowerCase().includes(q)) : models;
123
+ return { results: results2 };
124
+ }
125
+ const filtered = q ? GEMINI_MODELS.filter((m) => m.value.toLowerCase().includes(q) || m.label.toLowerCase().includes(q)) : GEMINI_MODELS;
126
+ const results = filtered.map((m) => ({
127
+ id: m.value,
128
+ label: m.label,
129
+ description: "",
130
+ record: {
131
+ model_id: m.value,
132
+ provider: GOOGLE_GEMINI,
133
+ title: m.value,
134
+ description: "",
135
+ tasks: m.tasks ? [...m.tasks] : [],
136
+ provider_config: { model_name: m.value },
137
+ metadata: {}
138
+ },
139
+ raw: m
140
+ }));
141
+ return { results };
142
+ };
143
+
144
+ // src/ai-provider/common/Gemini_Schema.ts
145
+ function sanitizeSchemaForGemini(schema) {
146
+ const result = {};
147
+ for (const [key, value] of Object.entries(schema)) {
148
+ if (key === "additionalProperties")
149
+ continue;
150
+ if (value && typeof value === "object" && !Array.isArray(value)) {
151
+ result[key] = sanitizeSchemaForGemini(value);
152
+ } else {
153
+ result[key] = value;
154
+ }
155
+ }
156
+ return result;
157
+ }
158
+
159
+ // src/ai-provider/common/Gemini_ToolCalling.ts
160
+ import { buildToolDescription, filterValidToolCalls } from "@workglow/ai/worker";
161
+ function buildGeminiContents(messages, prompt) {
162
+ if (!messages || messages.length === 0) {
163
+ return [{ role: "user", parts: [{ text: prompt }] }];
164
+ }
165
+ const toolUseNames = new Map;
166
+ for (const msg of messages) {
167
+ if (msg.role !== "assistant")
168
+ continue;
169
+ for (const block of msg.content) {
170
+ if (block.type === "tool_use") {
171
+ toolUseNames.set(block.id, block.name);
172
+ }
173
+ }
174
+ }
175
+ const contents = [];
176
+ for (const msg of messages) {
177
+ if (msg.role === "user") {
178
+ const parts = [];
179
+ for (const block of msg.content) {
180
+ if (block.type === "text") {
181
+ parts.push({ text: block.text });
182
+ } else if (block.type === "image") {
183
+ parts.push({ inlineData: { mimeType: block.mimeType, data: block.data } });
184
+ }
185
+ }
186
+ contents.push({ role: "user", parts });
187
+ } else if (msg.role === "assistant") {
188
+ const parts = [];
189
+ for (const block of msg.content) {
190
+ if (block.type === "text" && block.text) {
191
+ parts.push({ text: block.text });
192
+ } else if (block.type === "tool_use") {
193
+ parts.push({ functionCall: { name: block.name, args: block.input } });
194
+ }
195
+ }
196
+ if (parts.length > 0)
197
+ contents.push({ role: "model", parts });
198
+ } else if (msg.role === "tool") {
199
+ const parts = [];
200
+ for (const block of msg.content) {
201
+ if (block.type !== "tool_result")
202
+ continue;
203
+ const name = toolUseNames.get(block.tool_use_id) ?? "unknown";
204
+ const textContent = block.content.filter((b) => b.type === "text").map((b) => b.text).join("");
205
+ let response;
206
+ try {
207
+ response = JSON.parse(textContent);
208
+ } catch {
209
+ response = { result: textContent };
210
+ }
211
+ parts.push({ functionResponse: { name, response } });
212
+ }
213
+ if (parts.length > 0)
214
+ contents.push({ role: "user", parts });
215
+ }
216
+ }
217
+ return contents;
218
+ }
219
+ function mapGeminiToolConfig(toolChoice) {
220
+ if (!toolChoice || toolChoice === "auto") {
221
+ return { functionCallingConfig: { mode: "AUTO" } };
222
+ }
223
+ if (toolChoice === "none") {
224
+ return { functionCallingConfig: { mode: "NONE" } };
225
+ }
226
+ if (toolChoice === "required") {
227
+ return { functionCallingConfig: { mode: "ANY" } };
228
+ }
229
+ return {
230
+ functionCallingConfig: {
231
+ mode: "ANY",
232
+ allowedFunctionNames: [toolChoice]
233
+ }
234
+ };
235
+ }
236
+ var Gemini_ToolCalling = async (input, model, update_progress, signal) => {
237
+ update_progress(0, "Starting Gemini tool calling");
238
+ const GoogleGenerativeAI = await loadGeminiSDK();
239
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
240
+ const functionDeclarations = input.tools.map((t) => ({
241
+ name: t.name,
242
+ description: buildToolDescription(t),
243
+ parameters: sanitizeSchemaForGemini(t.inputSchema)
244
+ }));
245
+ const toolConfig = mapGeminiToolConfig(input.toolChoice);
246
+ const genModel = genAI.getGenerativeModel({
247
+ model: getModelName(model),
248
+ tools: [{ functionDeclarations }],
249
+ toolConfig,
250
+ systemInstruction: input.systemPrompt || undefined,
251
+ generationConfig: {
252
+ maxOutputTokens: input.maxTokens,
253
+ temperature: input.temperature
254
+ }
255
+ });
256
+ const contents = buildGeminiContents(input.messages, input.prompt);
257
+ const result = await genModel.generateContent({ contents });
258
+ const parts = result.response.candidates?.[0]?.content?.parts ?? [];
259
+ const textParts = [];
260
+ const toolCalls = [];
261
+ let callIndex = 0;
262
+ for (const part of parts) {
263
+ if ("text" in part && part.text) {
264
+ textParts.push(part.text);
265
+ }
266
+ if ("functionCall" in part && part.functionCall) {
267
+ const id = `call_${callIndex++}`;
268
+ toolCalls.push({
269
+ id,
270
+ name: part.functionCall.name,
271
+ input: part.functionCall.args ?? {}
272
+ });
273
+ }
274
+ }
275
+ update_progress(100, "Completed Gemini tool calling");
276
+ return { text: textParts.join(""), toolCalls: filterValidToolCalls(toolCalls, input.tools) };
277
+ };
278
+ var Gemini_ToolCalling_Stream = async function* (input, model, signal) {
279
+ const GoogleGenerativeAI = await loadGeminiSDK();
280
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
281
+ const functionDeclarations = input.tools.map((t) => ({
282
+ name: t.name,
283
+ description: buildToolDescription(t),
284
+ parameters: sanitizeSchemaForGemini(t.inputSchema)
285
+ }));
286
+ const toolConfig = mapGeminiToolConfig(input.toolChoice);
287
+ const genModel = genAI.getGenerativeModel({
288
+ model: getModelName(model),
289
+ tools: [{ functionDeclarations }],
290
+ toolConfig,
291
+ systemInstruction: input.systemPrompt || undefined,
292
+ generationConfig: {
293
+ maxOutputTokens: input.maxTokens,
294
+ temperature: input.temperature
295
+ }
296
+ });
297
+ const contents = buildGeminiContents(input.messages, input.prompt);
298
+ const result = await genModel.generateContentStream({ contents }, { signal });
299
+ let callIndex = 0;
300
+ for await (const chunk of result.stream) {
301
+ const parts = chunk.candidates?.[0]?.content?.parts ?? [];
302
+ for (const part of parts) {
303
+ if ("text" in part && part.text) {
304
+ yield { type: "text-delta", port: "text", textDelta: part.text };
305
+ }
306
+ if ("functionCall" in part && part.functionCall) {
307
+ const id = `call_${callIndex++}`;
308
+ yield {
309
+ type: "object-delta",
310
+ port: "toolCalls",
311
+ objectDelta: [
312
+ {
313
+ id,
314
+ name: part.functionCall.name,
315
+ input: part.functionCall.args ?? {}
316
+ }
317
+ ]
318
+ };
319
+ }
320
+ }
321
+ }
322
+ yield { type: "finish", data: { text: "", toolCalls: [] } };
323
+ };
324
+
325
+ // src/ai-provider/common/Gemini_Chat.ts
326
+ var Gemini_Chat = async (input, model, update_progress, signal) => {
327
+ update_progress(0, "Gemini chat turn");
328
+ const GoogleGenerativeAI = await loadGeminiSDK();
329
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
330
+ const genModel = genAI.getGenerativeModel({
331
+ model: getModelName(model),
332
+ systemInstruction: input.systemPrompt || undefined,
333
+ generationConfig: {
334
+ maxOutputTokens: input.maxTokens,
335
+ temperature: input.temperature
336
+ }
337
+ });
338
+ const contents = buildGeminiContents(input.messages, input.prompt);
339
+ const result = await genModel.generateContent({ contents });
340
+ const text = result.response.text() ?? "";
341
+ update_progress(100, "Turn complete");
342
+ return { text };
343
+ };
344
+ var Gemini_Chat_Stream = async function* (input, model, signal) {
345
+ const GoogleGenerativeAI = await loadGeminiSDK();
346
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
347
+ const genModel = genAI.getGenerativeModel({
348
+ model: getModelName(model),
349
+ systemInstruction: input.systemPrompt || undefined,
350
+ generationConfig: {
351
+ maxOutputTokens: input.maxTokens,
352
+ temperature: input.temperature
353
+ }
354
+ });
355
+ const contents = buildGeminiContents(input.messages, input.prompt);
356
+ const result = await genModel.generateContentStream({ contents }, { signal });
357
+ for await (const chunk of result.stream) {
358
+ const text = chunk.text();
359
+ if (text) {
360
+ yield { type: "text-delta", port: "text", textDelta: text };
361
+ }
362
+ }
363
+ yield { type: "finish", data: {} };
364
+ };
365
+
366
+ // src/ai-provider/common/Gemini_CountTokens.ts
367
+ var Gemini_CountTokens = async (input, model, onProgress, signal) => {
368
+ const GoogleGenerativeAI = await loadGeminiSDK();
369
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
370
+ const genModel = genAI.getGenerativeModel({ model: getModelName(model) });
371
+ const result = await genModel.countTokens(input.text);
372
+ return { count: result.totalTokens };
373
+ };
374
+ var Gemini_CountTokens_Preview = async (input, _model) => {
375
+ return { count: Math.ceil(input.text.length / 4) };
376
+ };
377
+
378
+ // src/ai-provider/common/Gemini_ImageEdit.ts
379
+ import { ImageGenerationContentPolicyError, ImageGenerationProviderError } from "@workglow/ai";
380
+ import { getLogger } from "@workglow/util/worker";
381
+ import { dataUriToImageValue, imageValueToPngBytes } from "@workglow/ai-provider/common";
382
+ function modelIdOf(model) {
383
+ return model?.model_id ?? model?.provider_config?.model_name ?? "gemini";
384
+ }
385
+ async function decodeInlineImage(mimeType, data) {
386
+ return dataUriToImageValue(`data:${mimeType};base64,${data}`);
387
+ }
388
+ async function gpuImageToInlinePart(image) {
389
+ if (typeof image === "string" && image.startsWith("data:")) {
390
+ const base642 = image.replace(/^data:[^;]+;base64,/, "");
391
+ return { inlineData: { mimeType: "image/png", data: base642 } };
392
+ }
393
+ const bytes = await imageValueToPngBytes(image);
394
+ let base64;
395
+ if (typeof Buffer !== "undefined") {
396
+ base64 = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString("base64");
397
+ } else {
398
+ let binary = "";
399
+ for (let i = 0;i < bytes.byteLength; i++) {
400
+ binary += String.fromCharCode(bytes[i]);
401
+ }
402
+ base64 = btoa(binary);
403
+ }
404
+ return { inlineData: { mimeType: "image/png", data: base64 } };
405
+ }
406
+ var Gemini_ImageEdit = async (input, model, update_progress, signal) => {
407
+ const logger = getLogger();
408
+ const timer = `gemini:ImageEdit:${modelIdOf(model)}`;
409
+ logger.time(timer, { model: modelIdOf(model) });
410
+ update_progress(0, "Starting Gemini image edit");
411
+ const GoogleGenerativeAI = await loadGeminiSDK();
412
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
413
+ const modelName = getModelName(model);
414
+ const genModel = genAI.getGenerativeModel({ model: modelName });
415
+ const primaryPart = await gpuImageToInlinePart(input.image);
416
+ const additionalParts = input.additionalImages && input.additionalImages.length > 0 ? await Promise.all(input.additionalImages.map((g) => gpuImageToInlinePart(g))) : [];
417
+ const parts = [{ text: input.prompt }, primaryPart, ...additionalParts];
418
+ try {
419
+ const result = await genModel.generateContent({ contents: [{ role: "user", parts }] }, {
420
+ signal
421
+ });
422
+ const response = result.response;
423
+ if (!response.candidates || response.candidates.length === 0 || response.promptFeedback?.blockReason) {
424
+ const reason = response.promptFeedback?.blockReason ?? "SAFETY";
425
+ throw new ImageGenerationContentPolicyError(modelIdOf(model), `Blocked: ${reason}`);
426
+ }
427
+ const candidateParts = response.candidates[0]?.content?.parts ?? [];
428
+ const imagePart = candidateParts.find((p) => p.inlineData && p.inlineData.mimeType && p.inlineData.data);
429
+ if (!imagePart) {
430
+ throw new ImageGenerationProviderError(modelIdOf(model), "No image part in response (Gemini did not return an inline image)");
431
+ }
432
+ const image = await decodeInlineImage(imagePart.inlineData.mimeType, imagePart.inlineData.data);
433
+ update_progress(100, "Completed Gemini image edit");
434
+ logger.timeEnd(timer, { model: modelIdOf(model) });
435
+ return { image };
436
+ } catch (err) {
437
+ if (err instanceof ImageGenerationProviderError || err instanceof ImageGenerationContentPolicyError) {
438
+ throw err;
439
+ }
440
+ const msg = err instanceof Error ? err.message : "unknown error";
441
+ if (/safety|policy|moderation|blocked|SAFETY|PROHIBITED/i.test(msg)) {
442
+ throw new ImageGenerationContentPolicyError(modelIdOf(model), msg);
443
+ }
444
+ throw new ImageGenerationProviderError(modelIdOf(model), msg, { cause: err });
445
+ }
446
+ };
447
+ var Gemini_ImageEdit_Stream = async function* (input, model, signal) {
448
+ const noop = () => {};
449
+ const result = await Gemini_ImageEdit(input, model, noop, signal);
450
+ yield { type: "snapshot", data: result };
451
+ yield { type: "finish", data: {} };
452
+ };
453
+
454
+ // src/ai-provider/common/Gemini_ImageGenerate.ts
455
+ import { ImageGenerationContentPolicyError as ImageGenerationContentPolicyError2, ImageGenerationProviderError as ImageGenerationProviderError2 } from "@workglow/ai";
456
+ import { getLogger as getLogger2 } from "@workglow/util/worker";
457
+ import { dataUriToImageValue as dataUriToImageValue2 } from "@workglow/ai-provider/common";
458
+ function modelIdOf2(model) {
459
+ return model?.model_id ?? model?.provider_config?.model_name ?? "gemini";
460
+ }
461
+ async function decodeInlineImage2(mimeType, data) {
462
+ return dataUriToImageValue2(`data:${mimeType};base64,${data}`);
463
+ }
464
+ var Gemini_ImageGenerate = async (input, model, update_progress, signal) => {
465
+ const logger = getLogger2();
466
+ const timer = `gemini:ImageGenerate:${modelIdOf2(model)}`;
467
+ logger.time(timer, { model: modelIdOf2(model) });
468
+ update_progress(0, "Starting Gemini image generation");
469
+ const GoogleGenerativeAI = await loadGeminiSDK();
470
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
471
+ const modelName = getModelName(model);
472
+ const genModel = genAI.getGenerativeModel({ model: modelName });
473
+ const parts = [{ text: input.prompt }];
474
+ try {
475
+ const result = await genModel.generateContent({ contents: [{ role: "user", parts }] }, {
476
+ signal
477
+ });
478
+ const response = result.response;
479
+ if (!response.candidates || response.candidates.length === 0 || response.promptFeedback?.blockReason) {
480
+ const reason = response.promptFeedback?.blockReason ?? "SAFETY";
481
+ throw new ImageGenerationContentPolicyError2(modelIdOf2(model), `Blocked: ${reason}`);
482
+ }
483
+ const candidateParts = response.candidates[0]?.content?.parts ?? [];
484
+ const imagePart = candidateParts.find((p) => p.inlineData && p.inlineData.mimeType && p.inlineData.data);
485
+ if (!imagePart) {
486
+ throw new ImageGenerationProviderError2(modelIdOf2(model), "No image part in response (Gemini did not return an inline image)");
487
+ }
488
+ const image = await decodeInlineImage2(imagePart.inlineData.mimeType, imagePart.inlineData.data);
489
+ update_progress(100, "Completed Gemini image generation");
490
+ logger.timeEnd(timer, { model: modelIdOf2(model) });
491
+ return { image };
492
+ } catch (err) {
493
+ if (err instanceof ImageGenerationProviderError2 || err instanceof ImageGenerationContentPolicyError2) {
494
+ throw err;
495
+ }
496
+ const msg = err instanceof Error ? err.message : "unknown error";
497
+ if (/safety|policy|moderation|blocked|SAFETY|PROHIBITED/i.test(msg)) {
498
+ throw new ImageGenerationContentPolicyError2(modelIdOf2(model), msg);
499
+ }
500
+ throw new ImageGenerationProviderError2(modelIdOf2(model), msg, { cause: err });
501
+ }
502
+ };
503
+ var Gemini_ImageGenerate_Stream = async function* (input, model, signal) {
504
+ const noop = () => {};
505
+ const result = await Gemini_ImageGenerate(input, model, noop, signal);
506
+ yield { type: "snapshot", data: result };
507
+ yield { type: "finish", data: {} };
508
+ };
509
+
510
+ // src/ai-provider/common/Gemini_ModelInfo.ts
511
+ var GEMINI_EMBEDDING_DIMENSIONS = {
512
+ "text-embedding-004": { native_dimensions: 768, mrl: true },
513
+ "embedding-001": { native_dimensions: 768, mrl: false }
514
+ };
515
+ var Gemini_ModelInfo = async (input, model) => {
516
+ if (input.detail === "dimensions") {
517
+ const pc = model?.provider_config;
518
+ let native_dimensions = typeof pc?.native_dimensions === "number" ? pc.native_dimensions : undefined;
519
+ let mrl = typeof pc?.mrl === "boolean" ? pc.mrl : undefined;
520
+ if (native_dimensions === undefined) {
521
+ const modelName = pc?.model_name ?? "";
522
+ const known = GEMINI_EMBEDDING_DIMENSIONS[modelName];
523
+ if (known) {
524
+ native_dimensions = known.native_dimensions;
525
+ mrl = mrl ?? known.mrl;
526
+ }
527
+ }
528
+ return {
529
+ model: input.model,
530
+ is_local: false,
531
+ is_remote: true,
532
+ supports_browser: true,
533
+ supports_node: true,
534
+ is_cached: false,
535
+ is_loaded: false,
536
+ file_sizes: null,
537
+ ...native_dimensions !== undefined ? { native_dimensions } : {},
538
+ ...mrl !== undefined ? { mrl } : {}
539
+ };
540
+ }
541
+ return {
542
+ model: input.model,
543
+ is_local: false,
544
+ is_remote: true,
545
+ supports_browser: true,
546
+ supports_node: true,
547
+ is_cached: false,
548
+ is_loaded: false,
549
+ file_sizes: null
550
+ };
551
+ };
552
+
553
+ // src/ai-provider/common/Gemini_StructuredGeneration.ts
554
+ import { parsePartialJson } from "@workglow/util/worker";
555
+ var Gemini_StructuredGeneration = async (input, model, update_progress, signal, outputSchema) => {
556
+ update_progress(0, "Starting Gemini structured generation");
557
+ const GoogleGenerativeAI = await loadGeminiSDK();
558
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
559
+ const schema = input.outputSchema ?? outputSchema;
560
+ const sanitizedSchema = sanitizeSchemaForGemini(schema);
561
+ const genModel = genAI.getGenerativeModel({
562
+ model: getModelName(model),
563
+ generationConfig: {
564
+ responseMimeType: "application/json",
565
+ responseSchema: sanitizedSchema,
566
+ maxOutputTokens: input.maxTokens,
567
+ temperature: input.temperature
568
+ }
569
+ });
570
+ const result = await genModel.generateContent({
571
+ contents: [{ role: "user", parts: [{ text: input.prompt }] }]
572
+ });
573
+ const text = result.response.text();
574
+ update_progress(100, "Completed Gemini structured generation");
575
+ return { object: JSON.parse(text) };
576
+ };
577
+ var Gemini_StructuredGeneration_Stream = async function* (input, model, signal, outputSchema) {
578
+ const GoogleGenerativeAI = await loadGeminiSDK();
579
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
580
+ const schema = input.outputSchema ?? outputSchema;
581
+ const sanitizedSchema = sanitizeSchemaForGemini(schema);
582
+ const genModel = genAI.getGenerativeModel({
583
+ model: getModelName(model),
584
+ generationConfig: {
585
+ responseMimeType: "application/json",
586
+ responseSchema: sanitizedSchema,
587
+ maxOutputTokens: input.maxTokens,
588
+ temperature: input.temperature
589
+ }
590
+ });
591
+ const result = await genModel.generateContentStream({ contents: [{ role: "user", parts: [{ text: input.prompt }] }] }, { signal });
592
+ let accumulatedJson = "";
593
+ for await (const chunk of result.stream) {
594
+ const text = chunk.text();
595
+ if (text) {
596
+ accumulatedJson += text;
597
+ const partial = parsePartialJson(accumulatedJson);
598
+ if (partial !== undefined) {
599
+ yield { type: "object-delta", port: "object", objectDelta: partial };
600
+ }
601
+ }
602
+ }
603
+ let finalObject;
604
+ try {
605
+ finalObject = JSON.parse(accumulatedJson);
606
+ } catch {
607
+ finalObject = parsePartialJson(accumulatedJson) ?? {};
608
+ }
609
+ yield { type: "finish", data: { object: finalObject } };
610
+ };
611
+
612
+ // src/ai-provider/common/Gemini_TextEmbedding.ts
613
+ import { getLogger as getLogger3 } from "@workglow/util/worker";
614
+ var Gemini_TextEmbedding = async (input, model, update_progress, signal) => {
615
+ const logger = getLogger3();
616
+ const timerLabel = `gemini:TextEmbedding:${model?.provider_config?.model_name}`;
617
+ logger.time(timerLabel, { model: model?.provider_config?.model_name });
618
+ update_progress(0, "Starting Gemini text embedding");
619
+ const GoogleGenerativeAI = await loadGeminiSDK();
620
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
621
+ const embeddingModel = genAI.getGenerativeModel({
622
+ model: getModelName(model)
623
+ });
624
+ const taskType = model?.provider_config?.embedding_task_type || "RETRIEVAL_DOCUMENT";
625
+ if (Array.isArray(input.text)) {
626
+ const result2 = await embeddingModel.batchEmbedContents({
627
+ requests: input.text.map((t) => ({
628
+ content: { role: "user", parts: [{ text: t }] },
629
+ taskType
630
+ }))
631
+ });
632
+ update_progress(100, "Completed Gemini text embedding");
633
+ logger.timeEnd(timerLabel, { model: model?.provider_config?.model_name, batch: true });
634
+ return {
635
+ vector: result2.embeddings.map((e) => new Float32Array(e.values))
636
+ };
637
+ }
638
+ const result = await embeddingModel.embedContent({
639
+ content: { role: "user", parts: [{ text: input.text }] },
640
+ taskType
641
+ });
642
+ update_progress(100, "Completed Gemini text embedding");
643
+ logger.timeEnd(timerLabel, { model: model?.provider_config?.model_name });
644
+ return { vector: new Float32Array(result.embedding.values) };
645
+ };
646
+
647
+ // src/ai-provider/common/Gemini_TextGeneration.ts
648
+ import { getLogger as getLogger4 } from "@workglow/util/worker";
649
+ var Gemini_TextGeneration = async (input, model, update_progress, signal) => {
650
+ const logger = getLogger4();
651
+ const timerLabel = `gemini:TextGeneration:${model?.provider_config?.model_name}`;
652
+ logger.time(timerLabel, { model: model?.provider_config?.model_name });
653
+ update_progress(0, "Starting Gemini text generation");
654
+ const GoogleGenerativeAI = await loadGeminiSDK();
655
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
656
+ const genModel = genAI.getGenerativeModel({
657
+ model: getModelName(model),
658
+ generationConfig: {
659
+ maxOutputTokens: input.maxTokens,
660
+ temperature: input.temperature,
661
+ topP: input.topP
662
+ }
663
+ });
664
+ const result = await genModel.generateContent({
665
+ contents: [{ role: "user", parts: [{ text: input.prompt }] }]
666
+ });
667
+ const text = result.response.text();
668
+ update_progress(100, "Completed Gemini text generation");
669
+ logger.timeEnd(timerLabel, { model: model?.provider_config?.model_name });
670
+ return { text };
671
+ };
672
+ var Gemini_TextGeneration_Stream = async function* (input, model, signal) {
673
+ const GoogleGenerativeAI = await loadGeminiSDK();
674
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
675
+ const genModel = genAI.getGenerativeModel({
676
+ model: getModelName(model),
677
+ generationConfig: {
678
+ maxOutputTokens: input.maxTokens,
679
+ temperature: input.temperature,
680
+ topP: input.topP
681
+ }
682
+ });
683
+ const result = await genModel.generateContentStream({ contents: [{ role: "user", parts: [{ text: input.prompt }] }] }, { signal });
684
+ for await (const chunk of result.stream) {
685
+ const text = chunk.text();
686
+ if (text) {
687
+ yield { type: "text-delta", port: "text", textDelta: text };
688
+ }
689
+ }
690
+ yield { type: "finish", data: {} };
691
+ };
692
+
693
+ // src/ai-provider/common/Gemini_TextRewriter.ts
694
+ var Gemini_TextRewriter = async (input, model, update_progress, signal) => {
695
+ update_progress(0, "Starting Gemini text rewriting");
696
+ const GoogleGenerativeAI = await loadGeminiSDK();
697
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
698
+ const genModel = genAI.getGenerativeModel({
699
+ model: getModelName(model),
700
+ systemInstruction: input.prompt
701
+ });
702
+ const result = await genModel.generateContent({
703
+ contents: [{ role: "user", parts: [{ text: input.text }] }]
704
+ });
705
+ const text = result.response.text();
706
+ update_progress(100, "Completed Gemini text rewriting");
707
+ return { text };
708
+ };
709
+ var Gemini_TextRewriter_Stream = async function* (input, model, signal) {
710
+ const GoogleGenerativeAI = await loadGeminiSDK();
711
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
712
+ const genModel = genAI.getGenerativeModel({
713
+ model: getModelName(model),
714
+ systemInstruction: input.prompt
715
+ });
716
+ const result = await genModel.generateContentStream({ contents: [{ role: "user", parts: [{ text: input.text }] }] }, { signal });
717
+ for await (const chunk of result.stream) {
718
+ const text = chunk.text();
719
+ if (text) {
720
+ yield { type: "text-delta", port: "text", textDelta: text };
721
+ }
722
+ }
723
+ yield { type: "finish", data: {} };
724
+ };
725
+
726
+ // src/ai-provider/common/Gemini_TextSummary.ts
727
+ var Gemini_TextSummary = async (input, model, update_progress, signal) => {
728
+ update_progress(0, "Starting Gemini text summarization");
729
+ const GoogleGenerativeAI = await loadGeminiSDK();
730
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
731
+ const genModel = genAI.getGenerativeModel({
732
+ model: getModelName(model),
733
+ systemInstruction: "Summarize the following text concisely."
734
+ });
735
+ const result = await genModel.generateContent({
736
+ contents: [{ role: "user", parts: [{ text: input.text }] }]
737
+ });
738
+ const text = result.response.text();
739
+ update_progress(100, "Completed Gemini text summarization");
740
+ return { text };
741
+ };
742
+ var Gemini_TextSummary_Stream = async function* (input, model, signal) {
743
+ const GoogleGenerativeAI = await loadGeminiSDK();
744
+ const genAI = new GoogleGenerativeAI(getApiKey(model));
745
+ const genModel = genAI.getGenerativeModel({
746
+ model: getModelName(model),
747
+ systemInstruction: "Summarize the following text concisely."
748
+ });
749
+ const result = await genModel.generateContentStream({ contents: [{ role: "user", parts: [{ text: input.text }] }] }, { signal });
750
+ for await (const chunk of result.stream) {
751
+ const text = chunk.text();
752
+ if (text) {
753
+ yield { type: "text-delta", port: "text", textDelta: text };
754
+ }
755
+ }
756
+ yield { type: "finish", data: {} };
757
+ };
758
+
759
+ // src/ai-provider/common/Gemini_JobRunFns.ts
760
+ var GEMINI_TASKS = {
761
+ AiChatTask: Gemini_Chat,
762
+ CountTokensTask: Gemini_CountTokens,
763
+ ModelInfoTask: Gemini_ModelInfo,
764
+ TextGenerationTask: Gemini_TextGeneration,
765
+ TextEmbeddingTask: Gemini_TextEmbedding,
766
+ TextRewriterTask: Gemini_TextRewriter,
767
+ TextSummaryTask: Gemini_TextSummary,
768
+ StructuredGenerationTask: Gemini_StructuredGeneration,
769
+ ToolCallingTask: Gemini_ToolCalling,
770
+ ModelSearchTask: Gemini_ModelSearch,
771
+ ImageGenerateTask: Gemini_ImageGenerate,
772
+ ImageEditTask: Gemini_ImageEdit
773
+ };
774
+ var GEMINI_STREAM_TASKS = {
775
+ AiChatTask: Gemini_Chat_Stream,
776
+ TextGenerationTask: Gemini_TextGeneration_Stream,
777
+ TextRewriterTask: Gemini_TextRewriter_Stream,
778
+ TextSummaryTask: Gemini_TextSummary_Stream,
779
+ StructuredGenerationTask: Gemini_StructuredGeneration_Stream,
780
+ ToolCallingTask: Gemini_ToolCalling_Stream,
781
+ ImageGenerateTask: Gemini_ImageGenerate_Stream,
782
+ ImageEditTask: Gemini_ImageEdit_Stream
783
+ };
784
+ var GEMINI_PREVIEW_TASKS = {
785
+ CountTokensTask: Gemini_CountTokens_Preview
786
+ };
787
+
788
+ // src/ai-provider/GoogleGeminiQueuedProvider.ts
789
+ import { AiProvider } from "@workglow/ai";
790
+ class GoogleGeminiQueuedProvider extends AiProvider {
791
+ name = GOOGLE_GEMINI;
792
+ displayName = "Google Gemini";
793
+ isLocal = false;
794
+ supportsBrowser = true;
795
+ taskTypes = [
796
+ "CountTokensTask",
797
+ "ModelInfoTask",
798
+ "TextGenerationTask",
799
+ "TextEmbeddingTask",
800
+ "TextRewriterTask",
801
+ "TextSummaryTask",
802
+ "StructuredGenerationTask",
803
+ "ToolCallingTask",
804
+ "ModelSearchTask",
805
+ "ImageGenerateTask",
806
+ "ImageEditTask"
807
+ ];
808
+ constructor(tasks, streamTasks, previewTasks) {
809
+ super(tasks, streamTasks, previewTasks);
810
+ }
811
+ }
812
+
813
+ // src/ai-provider/common/Gemini_ImageValidation.ts
814
+ import { AiImageOutputTask, ProviderUnsupportedFeatureError } from "@workglow/ai";
815
+ function registerGeminiImageValidator() {
816
+ AiImageOutputTask.registerProviderImageValidator(GOOGLE_GEMINI, (taskType, input, model) => {
817
+ if (taskType !== "ImageEditTask")
818
+ return;
819
+ if (input["mask"] !== undefined && input["mask"] !== null) {
820
+ throw new ProviderUnsupportedFeatureError("mask", model.model_id ?? "gemini", "Gemini does not support mask-based inpainting; remove the mask or use OpenAI gpt-image-2");
821
+ }
822
+ });
823
+ }
824
+
825
+ // src/ai-provider/registerGeminiInline.ts
826
+ async function registerGeminiInline(options) {
827
+ registerGeminiImageValidator();
828
+ await registerProviderInline(new GoogleGeminiQueuedProvider(GEMINI_TASKS, GEMINI_STREAM_TASKS, GEMINI_PREVIEW_TASKS), "Google Gemini", options);
829
+ }
830
+
831
+ // src/ai-provider/registerGeminiWorker.ts
832
+ import { registerProviderWorker } from "@workglow/ai-provider/common";
833
+
834
+ // src/ai-provider/GoogleGeminiProvider.ts
835
+ import { AiProvider as AiProvider2 } from "@workglow/ai/worker";
836
+ class GoogleGeminiProvider extends AiProvider2 {
837
+ name = GOOGLE_GEMINI;
838
+ displayName = "Google Gemini";
839
+ isLocal = false;
840
+ supportsBrowser = true;
841
+ taskTypes = [
842
+ "CountTokensTask",
843
+ "ModelInfoTask",
844
+ "TextGenerationTask",
845
+ "TextEmbeddingTask",
846
+ "TextRewriterTask",
847
+ "TextSummaryTask",
848
+ "StructuredGenerationTask",
849
+ "ToolCallingTask",
850
+ "ModelSearchTask",
851
+ "ImageGenerateTask",
852
+ "ImageEditTask"
853
+ ];
854
+ constructor(tasks, streamTasks, previewTasks) {
855
+ super(tasks, streamTasks, previewTasks);
856
+ }
857
+ }
858
+
859
+ // src/ai-provider/registerGeminiWorker.ts
860
+ async function registerGeminiWorker() {
861
+ await registerProviderWorker((ws) => new GoogleGeminiProvider(GEMINI_TASKS, GEMINI_STREAM_TASKS, GEMINI_PREVIEW_TASKS).registerOnWorkerServer(ws), "Google Gemini");
862
+ }
863
+ export {
864
+ registerGeminiWorker,
865
+ registerGeminiInline,
866
+ loadGeminiSDK,
867
+ getModelName,
868
+ getApiKey
869
+ };
870
+
871
+ //# debugId=77A1873DA035E57D64756E2164756E21