n8n-nodes-vercel-ai-sdk-universal-temp 0.1.68 → 0.1.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nodes/UniversalAI/UniversalAI.node.js +71 -403
- package/dist/nodes/UniversalAI/UniversalAI.node.js.map +1 -1
- package/dist/nodes/UniversalEmbedding/UniversalEmbedding.node.js +16 -68
- package/dist/nodes/UniversalEmbedding/UniversalEmbedding.node.js.map +1 -1
- package/dist/nodes/UniversalImageGen/UniversalImageGen.node.js +16 -66
- package/dist/nodes/UniversalImageGen/UniversalImageGen.node.js.map +1 -1
- package/dist/nodes/UniversalSpeechGen/UniversalSpeechGen.node.js +8 -32
- package/dist/nodes/UniversalSpeechGen/UniversalSpeechGen.node.js.map +1 -1
- package/dist/nodes/UniversalTranscription/UniversalTranscription.node.js +3 -8
- package/dist/nodes/UniversalTranscription/UniversalTranscription.node.js.map +1 -1
- package/dist/nodes/shared/constants.d.ts +45 -0
- package/dist/nodes/shared/constants.js +49 -0
- package/dist/nodes/shared/constants.js.map +1 -0
- package/dist/nodes/shared/helpers.d.ts +55 -1
- package/dist/nodes/shared/helpers.js +573 -2
- package/dist/nodes/shared/helpers.js.map +1 -1
- package/dist/nodes/shared/model-lists.d.ts +65 -0
- package/dist/nodes/shared/model-lists.js +280 -0
- package/dist/nodes/shared/model-lists.js.map +1 -0
- package/dist/nodes/shared/types.d.ts +68 -0
- package/dist/nodes/shared/types.js +3 -0
- package/dist/nodes/shared/types.js.map +1 -0
- package/dist/package.json +2 -2
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -42,135 +42,7 @@ const ai_1 = require("ai");
|
|
|
42
42
|
const zod_1 = require("zod");
|
|
43
43
|
const ajv_1 = __importDefault(require("ajv"));
|
|
44
44
|
const descriptions_1 = require("../shared/descriptions");
|
|
45
|
-
|
|
46
|
-
constructor(maxSize = 100, ttl = 5 * 60 * 1000) {
|
|
47
|
-
this.cache = new Map();
|
|
48
|
-
this.totalHits = 0;
|
|
49
|
-
this.totalMisses = 0;
|
|
50
|
-
this.totalEvictions = 0;
|
|
51
|
-
this.maxSize = maxSize;
|
|
52
|
-
this.ttl = ttl;
|
|
53
|
-
}
|
|
54
|
-
get(key) {
|
|
55
|
-
const item = this.cache.get(key);
|
|
56
|
-
if (!item) {
|
|
57
|
-
this.totalMisses++;
|
|
58
|
-
return undefined;
|
|
59
|
-
}
|
|
60
|
-
const now = Date.now();
|
|
61
|
-
if (item.expiresAt && now > item.expiresAt) {
|
|
62
|
-
this.cache.delete(key);
|
|
63
|
-
this.totalEvictions++;
|
|
64
|
-
this.totalMisses++;
|
|
65
|
-
return undefined;
|
|
66
|
-
}
|
|
67
|
-
item.hits++;
|
|
68
|
-
this.totalHits++;
|
|
69
|
-
return item.value;
|
|
70
|
-
}
|
|
71
|
-
set(key, value, customTTL) {
|
|
72
|
-
const now = Date.now();
|
|
73
|
-
const expiresAt = customTTL ? now + customTTL : (this.ttl > 0 ? now + this.ttl : undefined);
|
|
74
|
-
if (this.cache.size >= this.maxSize) {
|
|
75
|
-
let oldestKey;
|
|
76
|
-
let oldestTime = now;
|
|
77
|
-
for (const [k, v] of this.cache.entries()) {
|
|
78
|
-
if (v.timestamp < oldestTime) {
|
|
79
|
-
oldestTime = v.timestamp;
|
|
80
|
-
oldestKey = k;
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
if (oldestKey) {
|
|
84
|
-
this.cache.delete(oldestKey);
|
|
85
|
-
this.totalEvictions++;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
this.cache.set(key, { value, timestamp: now, hits: 0, expiresAt });
|
|
89
|
-
}
|
|
90
|
-
delete(key) {
|
|
91
|
-
return this.cache.delete(key);
|
|
92
|
-
}
|
|
93
|
-
clear() {
|
|
94
|
-
this.cache.clear();
|
|
95
|
-
this.totalHits = 0;
|
|
96
|
-
this.totalMisses = 0;
|
|
97
|
-
this.totalEvictions = 0;
|
|
98
|
-
}
|
|
99
|
-
getStats() {
|
|
100
|
-
return {
|
|
101
|
-
size: this.cache.size,
|
|
102
|
-
maxSize: this.maxSize,
|
|
103
|
-
hitRate: this.totalHits / (this.totalHits + this.totalMisses) || 0,
|
|
104
|
-
totalHits: this.totalHits,
|
|
105
|
-
totalMisses: this.totalMisses,
|
|
106
|
-
totalEvictions: this.totalEvictions,
|
|
107
|
-
ttl: this.ttl,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
const modelCache = new Cache(50);
|
|
112
|
-
const providerCache = new Cache(20);
|
|
113
|
-
const schemaCache = new Cache(30);
|
|
114
|
-
const googleCacheClients = new Cache(10, 60 * 60 * 1000);
|
|
115
|
-
const googleCachedContexts = new Cache(50, 55 * 60 * 1000);
|
|
116
|
-
async function getGoogleCacheManager(apiKey) {
|
|
117
|
-
let client = googleCacheClients.get(apiKey);
|
|
118
|
-
if (!client) {
|
|
119
|
-
const { GoogleGenAI } = await Promise.resolve().then(() => __importStar(require('@google/genai')));
|
|
120
|
-
client = new GoogleGenAI({ apiKey });
|
|
121
|
-
googleCacheClients.set(apiKey, client);
|
|
122
|
-
}
|
|
123
|
-
return client;
|
|
124
|
-
}
|
|
125
|
-
async function createGoogleCache(exec, index, apiKey, cacheableContent, modelId, thinkingBudgetValue, includeThoughts, tools, ttlSeconds) {
|
|
126
|
-
try {
|
|
127
|
-
if (!cacheableContent || cacheableContent.length === 0) {
|
|
128
|
-
return null;
|
|
129
|
-
}
|
|
130
|
-
const googleCacheManager = await getGoogleCacheManager(apiKey);
|
|
131
|
-
const cacheKeyData = {
|
|
132
|
-
content: JSON.stringify(cacheableContent),
|
|
133
|
-
tools: tools ? Object.keys(tools).sort() : [],
|
|
134
|
-
model: modelId,
|
|
135
|
-
};
|
|
136
|
-
const cacheKey = JSON.stringify(cacheKeyData, Object.keys(cacheKeyData).sort());
|
|
137
|
-
const existingCache = googleCachedContexts.get(cacheKey);
|
|
138
|
-
if (existingCache) {
|
|
139
|
-
console.log(`UniversalAI: Reusing existing cache: ${existingCache.name}`);
|
|
140
|
-
return existingCache.name;
|
|
141
|
-
}
|
|
142
|
-
const ttl = ttlSeconds || 3600;
|
|
143
|
-
const displayName = `universal_ai_cache_${Date.now()}`;
|
|
144
|
-
const cacheConfig = {
|
|
145
|
-
model: modelId,
|
|
146
|
-
config: {
|
|
147
|
-
displayName,
|
|
148
|
-
ttl: `${ttl}s`,
|
|
149
|
-
contents: cacheableContent,
|
|
150
|
-
},
|
|
151
|
-
};
|
|
152
|
-
if (tools && Object.keys(tools).length > 0) {
|
|
153
|
-
cacheConfig.config.tools = Object.values(tools);
|
|
154
|
-
}
|
|
155
|
-
console.log(`UniversalAI: Creating new cache...`);
|
|
156
|
-
const result = await googleCacheManager.caches.create(cacheConfig);
|
|
157
|
-
const cachedContentName = result === null || result === void 0 ? void 0 : result.name;
|
|
158
|
-
if (!cachedContentName) {
|
|
159
|
-
throw new Error('Cache creation returned no name identifier');
|
|
160
|
-
}
|
|
161
|
-
console.log(`UniversalAI: Cache created successfully: ${cachedContentName}`);
|
|
162
|
-
googleCachedContexts.set(cacheKey, { name: cachedContentName }, (ttl - 300) * 1000);
|
|
163
|
-
return cachedContentName;
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
167
|
-
console.error('UniversalAI: Google cache creation failed:', errorMessage);
|
|
168
|
-
if (errorMessage.includes('INVALID_ARGUMENT') || errorMessage.includes('content is too small')) {
|
|
169
|
-
console.warn('UniversalAI: Content may be below minimum token requirement (1,024 tokens (~4800 symbols) for 2.5 Flash and 2,048 tokens (~9600 symbols) for 2.5 Pro)');
|
|
170
|
-
}
|
|
171
|
-
return null;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
45
|
+
const helpers_1 = require("../shared/helpers");
|
|
174
46
|
const messageSchema = zod_1.z.object({
|
|
175
47
|
role: zod_1.z.enum(['system', 'user', 'assistant']),
|
|
176
48
|
content: zod_1.z.any(),
|
|
@@ -308,78 +180,75 @@ async function buildMessageWithAttachments(role, content, attachments, itemBinar
|
|
|
308
180
|
if (content) {
|
|
309
181
|
parts.push({ type: 'text', text: content });
|
|
310
182
|
}
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
const batchPromises = batch.map(attachment => processAttachment(attachment, itemBinary, exec, itemIndex, shouldCacheMessage, cacheableContent));
|
|
316
|
-
const batchResults = await Promise.all(batchPromises);
|
|
317
|
-
processedAttachments.push(...batchResults);
|
|
318
|
-
}
|
|
319
|
-
for (const attachment of processedAttachments) {
|
|
320
|
-
if (attachment) {
|
|
321
|
-
parts.push(attachment);
|
|
183
|
+
for (const attachment of attachments) {
|
|
184
|
+
const filePart = await processAttachment(attachment, itemBinary, exec, itemIndex, shouldCacheMessage, cacheableContent);
|
|
185
|
+
if (filePart) {
|
|
186
|
+
parts.push(filePart);
|
|
322
187
|
}
|
|
323
188
|
}
|
|
324
189
|
return parts.length > 0 ? { role, content: parts } : null;
|
|
325
190
|
}
|
|
326
191
|
async function processAttachment(attachment, itemBinary, exec, itemIndex, shouldCacheMessage, cacheableContent) {
|
|
327
|
-
const
|
|
328
|
-
if (!
|
|
192
|
+
const fileResult = await processFileData(attachment.fileContent, itemBinary, attachment, cacheableContent, exec, itemIndex);
|
|
193
|
+
if (!fileResult)
|
|
329
194
|
return null;
|
|
330
|
-
let mimeType = getMimeType(attachment);
|
|
331
|
-
let fileData;
|
|
332
|
-
if (isUrl(fileContentInput)) {
|
|
333
|
-
fileData = fileContentInput;
|
|
334
|
-
if (attachment.cacheAttachment === true) {
|
|
335
|
-
cacheableContent.push({
|
|
336
|
-
role: 'user',
|
|
337
|
-
parts: [{ fileUri: fileContentInput, mimeType: mimeType || 'application/octet-stream' }],
|
|
338
|
-
});
|
|
339
|
-
return null;
|
|
340
|
-
}
|
|
341
|
-
}
|
|
342
|
-
else {
|
|
343
|
-
const result = await getBinaryData(fileContentInput, itemBinary, exec, itemIndex);
|
|
344
|
-
fileData = result.data;
|
|
345
|
-
if (!mimeType && result.mimeType) {
|
|
346
|
-
mimeType = result.mimeType;
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
if (!fileData || (Buffer.isBuffer(fileData) && fileData.length === 0)) {
|
|
350
|
-
return null;
|
|
351
|
-
}
|
|
352
195
|
return {
|
|
353
196
|
type: 'file',
|
|
354
|
-
data:
|
|
355
|
-
mediaType: mimeType
|
|
197
|
+
data: fileResult.data,
|
|
198
|
+
mediaType: fileResult.mimeType,
|
|
356
199
|
};
|
|
357
200
|
}
|
|
358
|
-
function
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
: attachment.mimeType;
|
|
362
|
-
}
|
|
363
|
-
async function getBinaryData(fileContentInput, itemBinary, exec, itemIndex) {
|
|
364
|
-
if (itemBinary === null || itemBinary === void 0 ? void 0 : itemBinary[fileContentInput]) {
|
|
365
|
-
const binaryData = itemBinary[fileContentInput];
|
|
366
|
-
return {
|
|
367
|
-
data: Buffer.from(binaryData.data, 'base64'),
|
|
368
|
-
mimeType: binaryData.mimeType,
|
|
369
|
-
};
|
|
201
|
+
async function processFileData(fileContentInput, itemBinary, attachment, cacheableContent, exec, itemIndex) {
|
|
202
|
+
if (!fileContentInput || typeof fileContentInput !== 'string') {
|
|
203
|
+
return null;
|
|
370
204
|
}
|
|
205
|
+
let mimeType = attachment.mimeType === 'other' ? attachment.mimeTypeOther : attachment.mimeType;
|
|
206
|
+
let fileData;
|
|
207
|
+
let shouldCache = attachment.cacheAttachment === true;
|
|
371
208
|
try {
|
|
372
|
-
if (
|
|
373
|
-
|
|
374
|
-
if (
|
|
375
|
-
|
|
209
|
+
if (isUrl(fileContentInput)) {
|
|
210
|
+
fileData = fileContentInput;
|
|
211
|
+
if (shouldCache) {
|
|
212
|
+
cacheableContent.push({
|
|
213
|
+
role: 'user',
|
|
214
|
+
parts: [{ fileUri: fileContentInput, mimeType: mimeType || 'application/octet-stream' }],
|
|
215
|
+
});
|
|
216
|
+
return null;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
else if (fileContentInput.startsWith('data:')) {
|
|
220
|
+
const dataUriMatch = fileContentInput.match(/^data:([^;]+);base64,(.+)$/);
|
|
221
|
+
if (!dataUriMatch)
|
|
222
|
+
return null;
|
|
223
|
+
const [, extractedMimeType, base64Data] = dataUriMatch;
|
|
224
|
+
fileData = Buffer.from(base64Data, 'base64');
|
|
225
|
+
if (fileData.length > 20 * 1024 * 1024) {
|
|
226
|
+
throw new Error('Base64 data exceeds 20MB limit');
|
|
227
|
+
}
|
|
228
|
+
mimeType = mimeType || extractedMimeType;
|
|
229
|
+
}
|
|
230
|
+
else if (isLikelyBase64(fileContentInput)) {
|
|
231
|
+
fileData = Buffer.from(fileContentInput, 'base64');
|
|
232
|
+
if (fileData.length > 20 * 1024 * 1024) {
|
|
233
|
+
throw new Error('Base64 data exceeds 20MB limit');
|
|
376
234
|
}
|
|
377
235
|
}
|
|
236
|
+
else if (itemBinary === null || itemBinary === void 0 ? void 0 : itemBinary[fileContentInput]) {
|
|
237
|
+
const binaryData = itemBinary[fileContentInput];
|
|
238
|
+
fileData = Buffer.from(binaryData.data, 'base64');
|
|
239
|
+
mimeType = mimeType || binaryData.mimeType;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
if (!fileData || (Buffer.isBuffer(fileData) && fileData.length === 0)) {
|
|
245
|
+
return null;
|
|
246
|
+
}
|
|
247
|
+
return { data: fileData, mimeType: mimeType || 'application/octet-stream', shouldCache };
|
|
378
248
|
}
|
|
379
249
|
catch (error) {
|
|
380
250
|
throw new n8n_workflow_1.NodeOperationError(exec.getNode(), `Invalid file content for attachment: ${error.message}`);
|
|
381
251
|
}
|
|
382
|
-
return { data: null, mimeType: undefined };
|
|
383
252
|
}
|
|
384
253
|
function formatTextResult(result, includeRequestBody, provider) {
|
|
385
254
|
var _a, _b, _c, _d, _e;
|
|
@@ -511,52 +380,9 @@ function formatResponse(result) {
|
|
|
511
380
|
headers: (_d = result.response) === null || _d === void 0 ? void 0 : _d.headers,
|
|
512
381
|
};
|
|
513
382
|
}
|
|
514
|
-
async function getProvider(provider, apiKey, baseURL, customHeaders) {
|
|
515
|
-
const headersKey = customHeaders
|
|
516
|
-
? JSON.stringify(Object.keys(customHeaders)
|
|
517
|
-
.sort()
|
|
518
|
-
.map((key) => [key, customHeaders[key]]))
|
|
519
|
-
: '';
|
|
520
|
-
const cacheKey = `${provider}:${apiKey}:${baseURL || ''}:${headersKey}`;
|
|
521
|
-
const cached = providerCache.get(cacheKey);
|
|
522
|
-
if (cached)
|
|
523
|
-
return cached;
|
|
524
|
-
let providerInstance;
|
|
525
|
-
try {
|
|
526
|
-
switch (provider) {
|
|
527
|
-
case 'google':
|
|
528
|
-
const { createGoogleGenerativeAI } = await Promise.resolve().then(() => __importStar(require('@ai-sdk/google')));
|
|
529
|
-
providerInstance = createGoogleGenerativeAI({
|
|
530
|
-
apiKey,
|
|
531
|
-
...(baseURL && { baseURL }),
|
|
532
|
-
...(customHeaders && Object.keys(customHeaders).length > 0 && { headers: customHeaders }),
|
|
533
|
-
});
|
|
534
|
-
break;
|
|
535
|
-
case 'deepseek':
|
|
536
|
-
const { createDeepSeek } = await Promise.resolve().then(() => __importStar(require('@ai-sdk/deepseek')));
|
|
537
|
-
providerInstance = createDeepSeek({ apiKey, ...(baseURL && { baseURL }) });
|
|
538
|
-
break;
|
|
539
|
-
case 'groq':
|
|
540
|
-
const { createGroq } = await Promise.resolve().then(() => __importStar(require('@ai-sdk/groq')));
|
|
541
|
-
providerInstance = createGroq({ apiKey, ...(baseURL && { baseURL }) });
|
|
542
|
-
break;
|
|
543
|
-
case 'openrouter':
|
|
544
|
-
const { createOpenRouter } = await Promise.resolve().then(() => __importStar(require('@openrouter/ai-sdk-provider')));
|
|
545
|
-
providerInstance = createOpenRouter({ apiKey, ...(baseURL && { baseURL }) });
|
|
546
|
-
break;
|
|
547
|
-
default:
|
|
548
|
-
throw new Error(`Unsupported provider: ${provider}`);
|
|
549
|
-
}
|
|
550
|
-
providerCache.set(cacheKey, providerInstance);
|
|
551
|
-
return providerInstance;
|
|
552
|
-
}
|
|
553
|
-
catch (error) {
|
|
554
|
-
throw new Error(`Failed to initialize ${provider} provider: ${error.message}`);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
383
|
function parseAndValidateSchema(rawSchema, exec) {
|
|
558
384
|
const cacheKey = `schema:${Buffer.from(rawSchema).toString('base64').substring(0, 50)}`;
|
|
559
|
-
const cached = schemaCache.get(cacheKey);
|
|
385
|
+
const cached = helpers_1.schemaCache.get(cacheKey);
|
|
560
386
|
if (cached)
|
|
561
387
|
return cached;
|
|
562
388
|
let parsedSchema;
|
|
@@ -569,7 +395,7 @@ function parseAndValidateSchema(rawSchema, exec) {
|
|
|
569
395
|
if (!ajv.validateSchema(parsedSchema)) {
|
|
570
396
|
throw new n8n_workflow_1.NodeOperationError(exec.getNode(), `Invalid JSON Schema: ${ajv.errorsText(ajv.errors)}`);
|
|
571
397
|
}
|
|
572
|
-
schemaCache.set(cacheKey, parsedSchema);
|
|
398
|
+
helpers_1.schemaCache.set(cacheKey, parsedSchema);
|
|
573
399
|
return parsedSchema;
|
|
574
400
|
}
|
|
575
401
|
function parseStopSequences(stopSequencesStr) {
|
|
@@ -593,17 +419,17 @@ class UniversalAI {
|
|
|
593
419
|
async getModels() {
|
|
594
420
|
const provider = this.getCurrentNodeParameter('provider');
|
|
595
421
|
const cacheKey = `models:${provider}`;
|
|
596
|
-
const cached = modelCache.get(cacheKey);
|
|
422
|
+
const cached = helpers_1.modelCache.get(cacheKey);
|
|
597
423
|
if (cached)
|
|
598
424
|
return cached;
|
|
599
|
-
const { OPENROUTER_MODELS, GOOGLE_GEMINI_MODELS, DEEPSEEK_MODELS, GROQ_MODELS } = await Promise.resolve().then(() => __importStar(require('
|
|
425
|
+
const { OPENROUTER_MODELS, GOOGLE_GEMINI_MODELS, DEEPSEEK_MODELS, GROQ_MODELS } = await Promise.resolve().then(() => __importStar(require('../shared//model-lists')));
|
|
600
426
|
const models = {
|
|
601
427
|
google: GOOGLE_GEMINI_MODELS,
|
|
602
428
|
deepseek: DEEPSEEK_MODELS,
|
|
603
429
|
groq: GROQ_MODELS,
|
|
604
430
|
openrouter: OPENROUTER_MODELS,
|
|
605
431
|
}[provider] || [];
|
|
606
|
-
modelCache.set(cacheKey, models);
|
|
432
|
+
helpers_1.modelCache.set(cacheKey, models);
|
|
607
433
|
return models;
|
|
608
434
|
},
|
|
609
435
|
},
|
|
@@ -613,25 +439,13 @@ class UniversalAI {
|
|
|
613
439
|
const items = this.getInputData();
|
|
614
440
|
const returnData = [];
|
|
615
441
|
const provider = this.getNodeParameter('provider', 0);
|
|
616
|
-
const
|
|
617
|
-
google: 'googleGenerativeAIApi',
|
|
618
|
-
deepseek: 'deepSeekApi',
|
|
619
|
-
groq: 'groqApi',
|
|
620
|
-
openrouter: 'openRouterApi',
|
|
621
|
-
}[provider];
|
|
622
|
-
if (!credentialType) {
|
|
623
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Unsupported provider: ${provider}`);
|
|
624
|
-
}
|
|
625
|
-
const credentials = await this.getCredentials(credentialType);
|
|
626
|
-
if (!(credentials === null || credentials === void 0 ? void 0 : credentials.apiKey)) {
|
|
627
|
-
throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'No API key provided in credentials');
|
|
628
|
-
}
|
|
442
|
+
const { apiKey, baseUrl } = await (0, helpers_1.getCredentials)(this, provider);
|
|
629
443
|
const customHeaders = provider === 'google' ? getGoogleCustomHeaders(this, 0) : undefined;
|
|
630
|
-
const aiProvider = await getProvider(provider,
|
|
444
|
+
const aiProvider = await (0, helpers_1.getProvider)(this, provider, apiKey, baseUrl, customHeaders);
|
|
631
445
|
for (let i = 0; i < items.length; i++) {
|
|
632
446
|
if (this.continueOnFail()) {
|
|
633
447
|
try {
|
|
634
|
-
const result = await processItem(this, i, provider, aiProvider,
|
|
448
|
+
const result = await processItem(this, i, provider, aiProvider, apiKey);
|
|
635
449
|
returnData.push(...result);
|
|
636
450
|
}
|
|
637
451
|
catch (error) {
|
|
@@ -643,7 +457,7 @@ class UniversalAI {
|
|
|
643
457
|
}
|
|
644
458
|
}
|
|
645
459
|
else {
|
|
646
|
-
const result = await processItem(this, i, provider, aiProvider,
|
|
460
|
+
const result = await processItem(this, i, provider, aiProvider, apiKey);
|
|
647
461
|
returnData.push(...result);
|
|
648
462
|
}
|
|
649
463
|
}
|
|
@@ -683,21 +497,6 @@ function getModelSettings(exec, index, provider, operation, options) {
|
|
|
683
497
|
}
|
|
684
498
|
return settings;
|
|
685
499
|
}
|
|
686
|
-
function buildGoogleProviderOptions(exec, index, cachedContentName, thinkingBudgetOverride, includeThoughtsOverride) {
|
|
687
|
-
const thinkingBudgetValue = thinkingBudgetOverride !== null && thinkingBudgetOverride !== void 0 ? thinkingBudgetOverride : Number(exec.getNodeParameter('thinkingBudget', index, -1));
|
|
688
|
-
const includeThoughts = includeThoughtsOverride !== null && includeThoughtsOverride !== void 0 ? includeThoughtsOverride : exec.getNodeParameter('includeThoughts', index, false);
|
|
689
|
-
const options = {};
|
|
690
|
-
if (!Number.isNaN(thinkingBudgetValue) && thinkingBudgetValue > -1) {
|
|
691
|
-
options.thinkingConfig = {
|
|
692
|
-
thinkingBudget: Math.max(0, thinkingBudgetValue),
|
|
693
|
-
includeThoughts,
|
|
694
|
-
};
|
|
695
|
-
}
|
|
696
|
-
if (cachedContentName) {
|
|
697
|
-
options.cachedContent = cachedContentName;
|
|
698
|
-
}
|
|
699
|
-
return Object.keys(options).length > 0 ? options : undefined;
|
|
700
|
-
}
|
|
701
500
|
function getGoogleCustomHeaders(exec, index) {
|
|
702
501
|
var _a, _b;
|
|
703
502
|
const headersCollection = exec.getNodeParameter('customHeaders', index, {});
|
|
@@ -719,30 +518,9 @@ function getGoogleCustomHeaders(exec, index) {
|
|
|
719
518
|
async function generateTextOperation(exec, index, provider, aiProvider, model, modelSettings, input, options, apiKey) {
|
|
720
519
|
const enableStreaming = exec.getNodeParameter('enableStreaming', index, false);
|
|
721
520
|
const includeRequestBody = options.includeRequestBody;
|
|
722
|
-
const
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
let includeThoughts;
|
|
726
|
-
if (provider === 'google') {
|
|
727
|
-
thinkingBudgetValue = Number(exec.getNodeParameter('thinkingBudget', index, -1));
|
|
728
|
-
includeThoughts = exec.getNodeParameter('includeThoughts', index, false);
|
|
729
|
-
}
|
|
730
|
-
if (provider === 'google' &&
|
|
731
|
-
input.cacheableContent &&
|
|
732
|
-
input.cacheableContent.length > 0) {
|
|
733
|
-
const cacheTTL = exec.getNodeParameter('cacheTTL', index, 3600);
|
|
734
|
-
const cachedContentName = await createGoogleCache(exec, index, apiKey, input.cacheableContent, model, thinkingBudgetValue !== null && thinkingBudgetValue !== void 0 ? thinkingBudgetValue : -1, includeThoughts !== null && includeThoughts !== void 0 ? includeThoughts : false, tools, cacheTTL);
|
|
735
|
-
if (cachedContentName) {
|
|
736
|
-
googleProviderOptions = buildGoogleProviderOptions(exec, index, cachedContentName, thinkingBudgetValue, includeThoughts);
|
|
737
|
-
}
|
|
738
|
-
else {
|
|
739
|
-
googleProviderOptions = buildGoogleProviderOptions(exec, index, undefined, thinkingBudgetValue, includeThoughts);
|
|
740
|
-
console.log('UniversalAI: Cache creation failed, falling back to regular content');
|
|
741
|
-
}
|
|
742
|
-
}
|
|
743
|
-
else if (provider === 'google') {
|
|
744
|
-
googleProviderOptions = buildGoogleProviderOptions(exec, index, undefined, thinkingBudgetValue, includeThoughts);
|
|
745
|
-
}
|
|
521
|
+
const googleProviderOptions = provider === 'google'
|
|
522
|
+
? await (0, helpers_1.setupGoogleProviderOptions)(exec, index, input, model, apiKey)
|
|
523
|
+
: undefined;
|
|
746
524
|
const params = {
|
|
747
525
|
model: aiProvider(model, modelSettings),
|
|
748
526
|
};
|
|
@@ -752,50 +530,13 @@ async function generateTextOperation(exec, index, provider, aiProvider, model, m
|
|
|
752
530
|
params.system = input.system;
|
|
753
531
|
if (input.messages)
|
|
754
532
|
params.messages = input.messages;
|
|
755
|
-
if (tools && Object.keys(tools).length > 0) {
|
|
756
|
-
params.tools = tools;
|
|
757
|
-
}
|
|
758
533
|
if (provider === 'google' && googleProviderOptions) {
|
|
759
534
|
params.providerOptions = {
|
|
760
535
|
google: googleProviderOptions,
|
|
761
536
|
};
|
|
762
537
|
}
|
|
763
|
-
if (provider === 'google' &&
|
|
764
|
-
|
|
765
|
-
input.cacheableContent.length > 0 &&
|
|
766
|
-
!(googleProviderOptions === null || googleProviderOptions === void 0 ? void 0 : googleProviderOptions.cachedContent)) {
|
|
767
|
-
if (input.messages && input.messages.length > 0) {
|
|
768
|
-
const fallbackMessages = input.cacheableContent.map(content => {
|
|
769
|
-
const role = content.role === 'model' ? 'assistant' : (content.role === 'user' ? 'user' : 'system');
|
|
770
|
-
const textParts = content.parts
|
|
771
|
-
.filter(part => 'text' in part)
|
|
772
|
-
.map(part => part.text);
|
|
773
|
-
return {
|
|
774
|
-
role: role,
|
|
775
|
-
content: textParts.join('\n')
|
|
776
|
-
};
|
|
777
|
-
});
|
|
778
|
-
params.messages = [...fallbackMessages, ...(params.messages || [])];
|
|
779
|
-
}
|
|
780
|
-
else {
|
|
781
|
-
for (const content of input.cacheableContent) {
|
|
782
|
-
const textParts = content.parts
|
|
783
|
-
.filter(part => 'text' in part)
|
|
784
|
-
.map(part => part.text)
|
|
785
|
-
.join('\n');
|
|
786
|
-
if (textParts.trim()) {
|
|
787
|
-
if (!params.system) {
|
|
788
|
-
params.system = textParts.trim();
|
|
789
|
-
}
|
|
790
|
-
else if (!params.prompt) {
|
|
791
|
-
params.prompt = textParts.trim();
|
|
792
|
-
}
|
|
793
|
-
else {
|
|
794
|
-
params.prompt = params.prompt + '\n\n' + textParts.trim();
|
|
795
|
-
}
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
}
|
|
538
|
+
if (provider === 'google' && !(googleProviderOptions === null || googleProviderOptions === void 0 ? void 0 : googleProviderOptions.cachedContent)) {
|
|
539
|
+
(0, helpers_1.restoreCacheableContent)(params, input);
|
|
799
540
|
}
|
|
800
541
|
const textNumericKeys = [
|
|
801
542
|
'maxTokens',
|
|
@@ -814,25 +555,6 @@ async function generateTextOperation(exec, index, provider, aiProvider, model, m
|
|
|
814
555
|
const formattedResult = formatTextResult(result, includeRequestBody, provider);
|
|
815
556
|
return [{ json: formattedResult }];
|
|
816
557
|
}
|
|
817
|
-
async function buildGoogleTools(exec, index) {
|
|
818
|
-
const googleTools = exec.getNodeParameter('googleTools', index, []);
|
|
819
|
-
if (!googleTools || googleTools.length === 0) {
|
|
820
|
-
return undefined;
|
|
821
|
-
}
|
|
822
|
-
const tools = {};
|
|
823
|
-
const { google } = await Promise.resolve().then(() => __importStar(require('@ai-sdk/google')));
|
|
824
|
-
const toolSet = new Set(googleTools);
|
|
825
|
-
if (toolSet.has('google_search')) {
|
|
826
|
-
tools.google_search = google.tools.googleSearch({});
|
|
827
|
-
}
|
|
828
|
-
if (toolSet.has('url_context')) {
|
|
829
|
-
tools.url_context = google.tools.urlContext({});
|
|
830
|
-
}
|
|
831
|
-
if (toolSet.has('code_execution')) {
|
|
832
|
-
tools.code_execution = google.tools.codeExecution({});
|
|
833
|
-
}
|
|
834
|
-
return tools;
|
|
835
|
-
}
|
|
836
558
|
async function handleStreaming(params, provider, includeRequestBody) {
|
|
837
559
|
const stream = await (0, ai_1.streamText)(params);
|
|
838
560
|
const chunks = [];
|
|
@@ -877,29 +599,9 @@ async function generateObjectOperation(exec, index, provider, aiProvider, model,
|
|
|
877
599
|
const schemaDescription = exec.getNodeParameter('schemaDescription', index, '');
|
|
878
600
|
const rawSchema = exec.getNodeParameter('schema', index);
|
|
879
601
|
const parsedSchema = parseAndValidateSchema(rawSchema, exec);
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
if (provider === 'google') {
|
|
884
|
-
thinkingBudgetValue = Number(exec.getNodeParameter('thinkingBudget', index, -1));
|
|
885
|
-
includeThoughts = exec.getNodeParameter('includeThoughts', index, false);
|
|
886
|
-
}
|
|
887
|
-
if (provider === 'google' &&
|
|
888
|
-
input.cacheableContent &&
|
|
889
|
-
input.cacheableContent.length > 0) {
|
|
890
|
-
const cacheTTL = exec.getNodeParameter('cacheTTL', index, 3600);
|
|
891
|
-
const cachedContentName = await createGoogleCache(exec, index, apiKey, input.cacheableContent, model, thinkingBudgetValue !== null && thinkingBudgetValue !== void 0 ? thinkingBudgetValue : -1, includeThoughts !== null && includeThoughts !== void 0 ? includeThoughts : false, undefined, cacheTTL);
|
|
892
|
-
if (cachedContentName) {
|
|
893
|
-
googleProviderOptions = buildGoogleProviderOptions(exec, index, cachedContentName, thinkingBudgetValue, includeThoughts);
|
|
894
|
-
}
|
|
895
|
-
else {
|
|
896
|
-
googleProviderOptions = buildGoogleProviderOptions(exec, index, undefined, thinkingBudgetValue, includeThoughts);
|
|
897
|
-
console.log('UniversalAI: Cache creation failed, falling back to regular content');
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
else if (provider === 'google') {
|
|
901
|
-
googleProviderOptions = buildGoogleProviderOptions(exec, index, undefined, thinkingBudgetValue, includeThoughts);
|
|
902
|
-
}
|
|
602
|
+
const googleProviderOptions = provider === 'google'
|
|
603
|
+
? await (0, helpers_1.setupGoogleProviderOptions)(exec, index, input, model, apiKey)
|
|
604
|
+
: undefined;
|
|
903
605
|
const params = {
|
|
904
606
|
model: aiProvider(model, modelSettings),
|
|
905
607
|
schema: (0, ai_1.jsonSchema)(parsedSchema),
|
|
@@ -917,42 +619,8 @@ async function generateObjectOperation(exec, index, provider, aiProvider, model,
|
|
|
917
619
|
google: googleProviderOptions,
|
|
918
620
|
};
|
|
919
621
|
}
|
|
920
|
-
if (provider === 'google' &&
|
|
921
|
-
|
|
922
|
-
input.cacheableContent.length > 0 &&
|
|
923
|
-
!(googleProviderOptions === null || googleProviderOptions === void 0 ? void 0 : googleProviderOptions.cachedContent)) {
|
|
924
|
-
if (input.messages && input.messages.length > 0) {
|
|
925
|
-
const fallbackMessages = input.cacheableContent.map(content => {
|
|
926
|
-
const role = content.role === 'model' ? 'assistant' : (content.role === 'user' ? 'user' : 'system');
|
|
927
|
-
const textParts = content.parts
|
|
928
|
-
.filter(part => 'text' in part)
|
|
929
|
-
.map(part => part.text);
|
|
930
|
-
return {
|
|
931
|
-
role: role,
|
|
932
|
-
content: textParts.join('\n')
|
|
933
|
-
};
|
|
934
|
-
});
|
|
935
|
-
params.messages = [...fallbackMessages, ...(params.messages || [])];
|
|
936
|
-
}
|
|
937
|
-
else {
|
|
938
|
-
for (const content of input.cacheableContent) {
|
|
939
|
-
const textParts = content.parts
|
|
940
|
-
.filter(part => 'text' in part)
|
|
941
|
-
.map(part => part.text)
|
|
942
|
-
.join('\n');
|
|
943
|
-
if (textParts.trim()) {
|
|
944
|
-
if (!params.system) {
|
|
945
|
-
params.system = textParts.trim();
|
|
946
|
-
}
|
|
947
|
-
else if (!params.prompt) {
|
|
948
|
-
params.prompt = textParts.trim();
|
|
949
|
-
}
|
|
950
|
-
else {
|
|
951
|
-
params.prompt = params.prompt + '\n\n' + textParts.trim();
|
|
952
|
-
}
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
}
|
|
622
|
+
if (provider === 'google' && !(googleProviderOptions === null || googleProviderOptions === void 0 ? void 0 : googleProviderOptions.cachedContent)) {
|
|
623
|
+
(0, helpers_1.restoreCacheableContent)(params, input);
|
|
956
624
|
}
|
|
957
625
|
const objectNumericKeys = [
|
|
958
626
|
'temperature',
|