@workglow/google-gemini 0.2.33 → 0.2.35

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