UNPKG

n8n-nodes-gemini-grounding

Version:
908 lines 42.3 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.GeminiIAStudio = void 0; const n8n_workflow_1 = require("n8n-workflow"); const axios_1 = __importDefault(require("axios")); function prepareGenerationConfig(advancedParams) { const generationConfig = {}; if (advancedParams.temperature !== undefined) { generationConfig.temperature = advancedParams.temperature; } if (advancedParams.topP !== undefined) { generationConfig.topP = advancedParams.topP; } if (advancedParams.topK !== undefined) { generationConfig.topK = advancedParams.topK; } if (advancedParams.maxOutputTokens !== undefined) { generationConfig.maxOutputTokens = advancedParams.maxOutputTokens; } if (advancedParams.responseMimeType !== undefined && advancedParams.responseMimeType !== 'auto') { generationConfig.responseMimeType = advancedParams.responseMimeType; } if (advancedParams.stopSequences !== undefined && advancedParams.stopSequences !== '') { let stopSequences = []; if (typeof advancedParams.stopSequences === 'string') { stopSequences = advancedParams.stopSequences.split(',').map((s) => s.trim()); } else if (Array.isArray(advancedParams.stopSequences)) { stopSequences = advancedParams.stopSequences; } if (stopSequences.length > 0) { generationConfig.stopSequences = stopSequences; } } return generationConfig; } function prepareSafetySettings(advancedParams) { const safetySettings = []; if (advancedParams.safetySettings && advancedParams.safetySettings.values && Array.isArray(advancedParams.safetySettings.values)) { const safetyValues = advancedParams.safetySettings.values; safetyValues.forEach((setting) => { if (setting.category && setting.threshold) { safetySettings.push({ category: setting.category, threshold: setting.threshold, }); } }); } return safetySettings; } async function generateContent(apiKey, apiEndpoint, model, prompt, advancedParams) { const endpoint = `${apiEndpoint}/models/${model}:generateContent?key=${apiKey}`; const generationConfig = prepareGenerationConfig(advancedParams); const systemInstructions = advancedParams.systemPrompt ? { role: 'user', parts: [{ text: `SYSTEM: ${advancedParams.systemPrompt}` }] } : undefined; const safetySettings = prepareSafetySettings(advancedParams); const requestBody = { contents: [ ...(systemInstructions ? [systemInstructions] : []), { role: 'user', parts: [{ text: prompt }], }, ], generationConfig, }; if (advancedParams.toolSelection) { const toolSelection = advancedParams.toolSelection; if (toolSelection === 'structuredOutput') { if (!requestBody.generationConfig) { requestBody.generationConfig = {}; } requestBody.generationConfig.response_mime_type = 'application/json'; if (advancedParams.jsonSchema) { try { const schema = JSON.parse(advancedParams.jsonSchema); requestBody.generationConfig.response_schema = schema; } catch (error) { console.error('Invalid JSON schema provided:', error); } } } else if (toolSelection === 'codeExecution') { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-flash-lite' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-2.0-flash-thinking-exp-01-21' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "code_execution": {} }]; } } else if (toolSelection === 'googleSearch') { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "google_search": {} }]; } } } else { if (advancedParams.responseMimeType === 'application/json') { if (!requestBody.generationConfig) { requestBody.generationConfig = {}; } requestBody.generationConfig.response_mime_type = 'application/json'; } if (advancedParams.enableCodeExecution === true) { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-flash-lite' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-2.0-flash-thinking-exp-01-21' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "code_execution": {} }]; } } else if (advancedParams.enableGoogleSearch === true) { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "google_search": {} }]; } } } if (model === 'gemini-2.0-flash-exp-image-generation') { if (!requestBody.generationConfig) { requestBody.generationConfig = {}; } requestBody.generationConfig.responseModalities = ['Text', 'Image']; } if (safetySettings.length > 0) { requestBody.safetySettings = safetySettings; } return axios_1.default.post(endpoint, requestBody, { headers: { 'Content-Type': 'application/json', }, }).then((response) => response.data); } async function chatWithModel(apiKey, apiEndpoint, model, messages, advancedParams) { const endpoint = `${apiEndpoint}/models/${model}:generateContent?key=${apiKey}`; const generationConfig = prepareGenerationConfig(advancedParams); if (advancedParams.systemPrompt) { messages.unshift({ role: 'user', parts: [{ text: `SYSTEM: ${advancedParams.systemPrompt}` }], }); } const safetySettings = prepareSafetySettings(advancedParams); const requestBody = { contents: messages, generationConfig, }; if (advancedParams.toolSelection) { const toolSelection = advancedParams.toolSelection; if (toolSelection === 'structuredOutput') { if (!requestBody.generationConfig) { requestBody.generationConfig = {}; } requestBody.generationConfig.response_mime_type = 'application/json'; if (advancedParams.jsonSchema) { try { const schema = JSON.parse(advancedParams.jsonSchema); requestBody.generationConfig.response_schema = schema; } catch (error) { console.error('Invalid JSON schema provided:', error); } } } else if (toolSelection === 'codeExecution') { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-flash-lite' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-2.0-flash-thinking-exp-01-21' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "code_execution": {} }]; } } else if (toolSelection === 'googleSearch') { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "google_search": {} }]; } } } else { if (advancedParams.responseMimeType === 'application/json') { if (!requestBody.generationConfig) { requestBody.generationConfig = {}; } requestBody.generationConfig.response_mime_type = 'application/json'; } if (advancedParams.enableCodeExecution === true) { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-flash-lite' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-2.0-flash-thinking-exp-01-21' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "code_execution": {} }]; } } else if (advancedParams.enableGoogleSearch === true) { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "google_search": {} }]; } } } if (model === 'gemini-2.0-flash-exp-image-generation') { if (!requestBody.generationConfig) { requestBody.generationConfig = {}; } requestBody.generationConfig.responseModalities = ['Text', 'Image']; } if (safetySettings.length > 0) { requestBody.safetySettings = safetySettings; } const response = await axios_1.default.post(endpoint, requestBody, { headers: { 'Content-Type': 'application/json', }, }); return response.data; } async function analyzeImage(apiKey, apiEndpoint, model, imageUrl, mediaType, imagePrompt, advancedParams) { const endpoint = `${apiEndpoint}/models/${model}:generateContent?key=${apiKey}`; if (!model.includes('vision') && !model.includes('2.0')) { model = 'gemini-1.5-pro-vision'; } const generationConfig = prepareGenerationConfig(advancedParams); const safetySettings = prepareSafetySettings(advancedParams); let mimeType = 'image/jpeg'; if (mediaType === 'video') { mimeType = 'video/mp4'; } else if (mediaType === 'audio') { mimeType = 'audio/mp3'; } const requestBody = { contents: [ { role: 'user', parts: [ { text: imagePrompt }, { inline_data: { mime_type: mimeType, data: imageUrl, }, }, ], }, ], generationConfig, }; if (advancedParams.toolSelection) { const toolSelection = advancedParams.toolSelection; if (toolSelection === 'structuredOutput') { if (!requestBody.generationConfig) { requestBody.generationConfig = {}; } requestBody.generationConfig.response_mime_type = 'application/json'; if (advancedParams.jsonSchema) { try { const schema = JSON.parse(advancedParams.jsonSchema); requestBody.generationConfig.response_schema = schema; } catch (error) { console.error('Invalid JSON schema provided:', error); } } } else if (toolSelection === 'codeExecution') { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-flash-lite' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-2.0-flash-thinking-exp-01-21' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "code_execution": {} }]; } } else if (toolSelection === 'googleSearch') { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "google_search": {} }]; } } } else { if (advancedParams.responseMimeType === 'application/json') { if (!requestBody.generationConfig) { requestBody.generationConfig = {}; } requestBody.generationConfig.response_mime_type = 'application/json'; } if (advancedParams.enableCodeExecution === true) { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-flash-lite' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-2.0-flash-thinking-exp-01-21' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "code_execution": {} }]; } } else if (advancedParams.enableGoogleSearch === true) { if (model === 'gemini-2.0-flash' || model === 'gemini-2.0-pro-exp-02-05' || model === 'gemini-1.5-pro' || model === 'gemini-1.5-flash' || model === 'gemini-1.5-flash-8b') { requestBody.tools = [{ "google_search": {} }]; } } } if (model === 'gemini-2.0-flash-exp-image-generation') { if (!requestBody.generationConfig) { requestBody.generationConfig = {}; } requestBody.generationConfig.responseModalities = ['Text', 'Image']; } if (safetySettings.length > 0) { requestBody.safetySettings = safetySettings; } const response = await axios_1.default.post(endpoint, requestBody, { headers: { 'Content-Type': 'application/json', }, }); return response.data; } class GeminiIAStudio extends n8n_workflow_1.INodeType { constructor() { super(); this.description = { displayName: 'Gemini AI Studio', name: 'geminiIAStudio', icon: 'file:google-gemini-icon.svg', group: ['transform'], version: 1, subtitle: '={{$parameter["operation"] + ": " + $parameter["model"]}}', description: 'Generate content using Google Gemini API', defaults: { name: 'Gemini AI Studio', color: '#1A73E8', }, inputs: [{ type: 'main' }], outputs: [{ type: 'main' }], credentials: [ { name: 'geminiApi', required: true, }, ], properties: [ { displayName: 'Operation', name: 'operation', type: 'options', noDataExpression: true, options: [ { name: 'Generate Content', value: 'generateContent', description: 'Generate content with Gemini', action: 'Generate content with Gemini', }, { name: 'Chat', value: 'chat', description: 'Have a multi-turn conversation with Gemini', action: 'Chat with Gemini', }, { name: 'Analyze Media', value: 'analyzeImage', description: 'Analyze images, videos, or audio with Gemini', action: 'Analyze media with Gemini', }, ], default: 'generateContent', }, { displayName: 'Model', name: 'model', type: 'options', options: [ { name: 'Gemini 2.0 Flash', value: 'gemini-2.0-flash', description: 'Fast model with great balance of speed and capability, supports multimodal input/output', }, { name: 'Gemini 2.0 Flash-Lite', value: 'gemini-2.0-flash-lite', description: 'A Gemini 2.0 Flash model optimized for cost efficiency and low latency', }, { name: 'Gemini 2.0 Pro Experimental (02-05)', value: 'gemini-2.0-pro-exp-02-05', description: 'Experimental version with advanced capabilities', }, { name: 'Gemini 2.0 Flash Thinking Experimental (01-21)', value: 'gemini-2.0-flash-thinking-exp-01-21', description: 'Experimental version with enhanced reasoning capabilities', }, { name: 'Gemini 2.0 Flash Exp Image Generation', value: 'gemini-2.0-flash-exp-image-generation', description: 'Experimental version that can generate images', }, { name: 'Gemini 1.5 Flash', value: 'gemini-1.5-flash', description: 'Fast and versatile performance across a diverse variety of tasks', }, { name: 'Gemini 1.5 Flash-8B', value: 'gemini-1.5-flash-8b', description: 'High volume and lower intelligence tasks', }, { name: 'Gemini 1.5 Pro', value: 'gemini-1.5-pro', description: 'Complex reasoning tasks requiring more intelligence', }, { name: 'Gemma 3 27B', value: 'gemma-3-27b', description: 'Open model from Google with 27B parameters, great for various tasks', } ], default: 'gemini-2.0-flash', description: 'The AI model to use', }, { displayName: 'Prompt', name: 'prompt', type: 'string', typeOptions: { rows: 4, }, default: '', required: true, displayOptions: { show: { operation: ['generateContent', 'chat'], }, }, description: 'The text prompt to send to Gemini', }, { displayName: 'Include Previous Messages', name: 'includePreviousMessages', type: 'boolean', default: false, displayOptions: { show: { operation: ['chat'], }, }, description: 'Whether to include previous messages from input data', }, { displayName: 'Previous Messages Field', name: 'previousMessagesField', type: 'string', default: 'messages', displayOptions: { show: { operation: ['chat'], includePreviousMessages: [true], }, }, description: 'The name of the field in the input that contains previous messages', }, { displayName: 'Media URL Field', name: 'imageUrlField', type: 'string', default: 'mediaUrl', displayOptions: { show: { operation: ['analyzeImage'], }, }, description: 'The field in the input that contains the image, video, or audio URL to analyze', required: true, }, { displayName: 'Media Type', name: 'mediaType', type: 'options', options: [ { name: 'Image', value: 'image', description: 'Process an image file (JPEG, PNG, etc.)' }, { name: 'Video', value: 'video', description: 'Process a video file (MP4, etc.)' }, { name: 'Audio', value: 'audio', description: 'Process an audio file (MP3, etc.)' }, ], default: 'image', displayOptions: { show: { operation: ['analyzeImage'], }, }, description: 'The type of media to analyze', required: true, }, { displayName: 'Analysis Prompt', name: 'imagePrompt', type: 'string', typeOptions: { rows: 2, }, default: 'Analyze this content in detail.', displayOptions: { show: { operation: ['analyzeImage'], }, }, description: 'The prompt to send with the media', required: true, }, { displayName: 'Advanced Parameters', name: 'advancedParameters', type: 'collection', placeholder: 'Add Parameter', default: {}, options: [ { displayName: 'Temperature', name: 'temperature', type: 'number', typeOptions: { minValue: 0, maxValue: 2, numberPrecision: 2, }, default: 1, description: 'Controls randomness (0 = deterministic, 2 = maximum randomness)', }, { displayName: 'Top P', name: 'topP', type: 'number', typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2, }, default: 0.95, description: 'Nucleus sampling - considers tokens with top_p probability mass (0.95 = 95% probability mass)', }, { displayName: 'Top K', name: 'topK', type: 'number', typeOptions: { minValue: 1, maxValue: 100, }, default: 40, description: 'Consider only the top-k tokens (1 = greedy decoding)', }, { displayName: 'Maximum Output Tokens', name: 'maxOutputTokens', type: 'number', typeOptions: { minValue: 1, maxValue: 8192, }, default: 8192, description: 'Maximum number of tokens to generate', }, { displayName: 'Stop Sequences', name: 'stopSequences', type: 'string', typeOptions: { multipleValues: true, }, default: '', description: 'Sequences that will cause the model to stop generating (comma separated)', }, { displayName: 'Tool Selection (Choose One)', name: 'toolSelection', type: 'options', options: [ { name: 'None', value: 'none', description: 'No special tools enabled', }, { name: 'Structured Output (JSON)', value: 'structuredOutput', description: 'Force model to return valid JSON', }, { name: 'Code Execution', value: 'codeExecution', description: 'Enable code execution capabilities', }, { name: 'Google Search', value: 'googleSearch', description: 'Enable Google Search grounding for factual responses', }, ], default: 'none', description: 'Select one special capability for the model (only one can be enabled at a time)', displayOptions: { show: { '/model': [ 'gemini-2.0-flash', 'gemini-2.0-flash-lite', 'gemini-2.0-pro-exp-02-05', 'gemini-2.0-flash-thinking-exp-01-21', 'gemini-1.5-flash', 'gemini-1.5-flash-8b', 'gemini-1.5-pro' ], }, }, }, { displayName: 'JSON Schema Definition', name: 'jsonSchema', type: 'string', typeOptions: { rows: 10, }, default: '{\n "type": "object",\n "properties": {\n "response": {\n "type": "string"\n }\n }\n}', description: 'Enter an OpenAPI schema object to constrain the model output. See the <a href="https://spec.openapis.org/oas/v3.0.3#schema" target="_blank">OpenAPI specification</a> and <a href="https://ai.google.dev/gemini-api/docs/api-overview#json" target="_blank">Gemini API documentation</a> for examples.', displayOptions: { show: { toolSelection: ['structuredOutput'], }, }, }, { displayName: 'System Prompt', name: 'systemPrompt', type: 'string', typeOptions: { rows: 4, }, default: '', description: 'System prompt that helps set the behavior of the model', }, { displayName: 'Safety Settings', name: 'safetySettings', type: 'fixedCollection', typeOptions: { multipleValues: true, }, default: {}, options: [ { name: 'values', displayName: 'Safety Setting', values: [ { displayName: 'Category', name: 'category', type: 'options', options: [ { name: 'Harassment', value: 'HARM_CATEGORY_HARASSMENT' }, { name: 'Hate Speech', value: 'HARM_CATEGORY_HATE_SPEECH' }, { name: 'Sexually Explicit', value: 'HARM_CATEGORY_SEXUALLY_EXPLICIT' }, { name: 'Dangerous Content', value: 'HARM_CATEGORY_DANGEROUS_CONTENT' }, ], default: 'HARM_CATEGORY_HARASSMENT', }, { displayName: 'Threshold', name: 'threshold', type: 'options', options: [ { name: 'Block None', value: 'BLOCK_NONE' }, { name: 'Block Low and Above', value: 'BLOCK_LOW_AND_ABOVE' }, { name: 'Block Medium and Above', value: 'BLOCK_MEDIUM_AND_ABOVE' }, { name: 'Block High and Above', value: 'BLOCK_HIGH_AND_ABOVE' }, { name: 'Block All', value: 'BLOCK_ALL' }, ], default: 'BLOCK_MEDIUM_AND_ABOVE', }, ], }, ], }, { displayName: 'Response Format (Legacy)', name: 'responseMimeType', type: 'options', options: [ { name: 'Auto', value: 'auto', description: 'Let the model decide the appropriate format', }, { name: 'JSON', value: 'application/json', description: 'Force model to return valid JSON', }, { name: 'Text', value: 'text/plain', description: 'Plain text response', }, { name: 'Markdown', value: 'text/markdown', description: 'Markdown formatted text', }, ], default: 'auto', description: 'The desired format of the response', displayOptions: { show: { toolSelection: ['none'], }, }, }, { displayName: 'Enable Google Search Grounding (Legacy)', name: 'enableGoogleSearch', type: 'boolean', default: false, description: 'Whether to enable Google Search grounding. Note: Only available for certain models and cannot be combined with other tools.', displayOptions: { show: { toolSelection: ['none'], }, }, }, { displayName: 'Enable Code Execution (Legacy)', name: 'enableCodeExecution', type: 'boolean', default: false, description: 'Whether to enable code execution capabilities. Note: Only available for certain models and cannot be combined with other tools.', displayOptions: { show: { toolSelection: ['none'], }, }, }, ], }, ], }; } async execute() { var _a, _b, _c, _d; const items = this.getInputData(); const returnData = []; const credentials = await this.getCredentials('geminiApi'); const apiKey = credentials.apiKey; const apiEndpoint = credentials.apiEndpoint || 'https://generativelanguage.googleapis.com/v1beta'; for (let i = 0; i < items.length; i++) { try { const operation = this.getNodeParameter('operation', i); const model = this.getNodeParameter('model', i); const advancedParams = this.getNodeParameter('advancedParameters', i, {}); let responseData; if (operation === 'generateContent') { const prompt = this.getNodeParameter('prompt', i); responseData = await generateContent(apiKey, apiEndpoint, model, prompt, advancedParams); } else if (operation === 'chat') { const prompt = this.getNodeParameter('prompt', i); const includePreviousMessages = this.getNodeParameter('includePreviousMessages', i, false); let messages = [{ role: 'user', parts: [{ text: prompt }], }]; if (includePreviousMessages) { const previousMessagesField = this.getNodeParameter('previousMessagesField', i); const previousMessages = items[i].json[previousMessagesField] || []; if (Array.isArray(previousMessages) && previousMessages.length > 0) { const convertedMessages = previousMessages.map(msg => ({ role: msg.role === 'user' ? 'user' : 'model', parts: [{ text: msg.content }], })); messages = [...convertedMessages, ...messages]; } } responseData = await chatWithModel(apiKey, apiEndpoint, model, messages, advancedParams); } else if (operation === 'analyzeImage') { const imageUrlField = this.getNodeParameter('imageUrlField', i); const imageUrl = items[i].json[imageUrlField]; const mediaType = this.getNodeParameter('mediaType', i); const imagePrompt = this.getNodeParameter('imagePrompt', i); if (!imageUrl) { throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Image URL is required for image analysis', { itemIndex: i, }); } responseData = await analyzeImage(apiKey, apiEndpoint, model, imageUrl, mediaType, imagePrompt, advancedParams); } let outputData = { ...items[i].json, geminiResponse: responseData, }; if ((operation === 'generateContent' || operation === 'chat') && advancedParams.toolSelection === 'googleSearch') { let searchResultsSummary = 'Google Search Results:\n\n'; let foundResults = false; if (responseData && responseData.candidates && responseData.candidates.length > 0 && responseData.candidates[0].content && responseData.candidates[0].content.parts) { for (const part of responseData.candidates[0].content.parts) { if (part.tool_code && part.tool_code.tool_code_results && part.tool_code.tool_code_results.length > 0) { for (const result of part.tool_code.tool_code_results) { if (result.search_results && result.search_results.results && result.search_results.results.length > 0) { foundResults = true; for (const searchResult of result.search_results.results) { if (searchResult.title && searchResult.snippet && searchResult.link) { searchResultsSummary += `Title: ${searchResult.title}\n`; searchResultsSummary += `Snippet: ${searchResult.snippet}\n`; searchResultsSummary += `Link: ${searchResult.link}\n\n`; } } } } } } } if (foundResults) { outputData.googleSearchResultsSummary = searchResultsSummary; } else { outputData.googleSearchResultsSummary = 'No Google Search results found in the response.'; } } const executionData = this.helpers.constructExecutionMetaData(this.helpers.returnJsonArray(outputData), { itemData: { item: i } }); returnData.push(...executionData); } catch (error) { if (error.response) { const status = error.response.status; const message = ((_c = (_b = (_a = error.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.error) === null || _c === void 0 ? void 0 : _c.message) || 'Unknown API error'; throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Gemini API Error: ${status} - ${message}`, { itemIndex: i, description: JSON.stringify(((_d = error.response) === null || _d === void 0 ? void 0 : _d.data) || {}), }); } else { throw new n8n_workflow_1.NodeOperationError(this.getNode(), `Error: ${error.message}`, { itemIndex: i, }); } } } return [returnData]; } } exports.GeminiIAStudio = GeminiIAStudio; //# sourceMappingURL=GeminiGrounding.node.js.map