UNPKG

@n8n/n8n-nodes-langchain

Version:

![Banner image](https://user-images.githubusercontent.com/10284570/173569848-c624317f-42b1-45a6-ab09-f0ea3c247648.png)

547 lines 17.8 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); var message_operation_exports = {}; __export(message_operation_exports, { description: () => description, execute: () => execute }); module.exports = __toCommonJS(message_operation_exports); var import_helpers = require("../../../../../utils/helpers"); var import_n8n_workflow = require("n8n-workflow"); var import_zod_to_json_schema = __toESM(require("zod-to-json-schema")); var import_transport = require("../../transport"); var import_descriptions = require("../descriptions"); const properties = [ (0, import_descriptions.modelRLC)("modelSearch"), { displayName: "Messages", name: "messages", type: "fixedCollection", typeOptions: { sortable: true, multipleValues: true }, placeholder: "Add Message", default: { values: [{ content: "" }] }, options: [ { displayName: "Values", name: "values", values: [ { displayName: "Prompt", name: "content", type: "string", description: "The content of the message to be send", default: "", placeholder: "e.g. Hello, how can you help me?", typeOptions: { rows: 2 } }, { displayName: "Role", name: "role", type: "options", description: "Role in shaping the model's response, it tells the model how it should behave and interact with the user", options: [ { name: "User", value: "user", description: "Send a message as a user and get a response from the model" }, { name: "Model", value: "model", description: "Tell the model to adopt a specific tone or personality" } ], default: "user" } ] } ] }, { displayName: "Simplify Output", name: "simplify", type: "boolean", default: true, description: "Whether to return a simplified version of the response instead of the raw data" }, { displayName: "Output Content as JSON", name: "jsonOutput", type: "boolean", description: "Whether to attempt to return the response in JSON format", default: false }, { displayName: "Built-in Tools", name: "builtInTools", placeholder: "Add Built-in Tool", type: "collection", default: {}, displayOptions: { show: { "@version": [{ _cnd: { gte: 1.1 } }] } }, options: [ { displayName: "Google Search", name: "googleSearch", type: "boolean", default: true, description: "Whether to allow the model to search the web using Google Search to get real-time information" }, { displayName: "Google Maps", name: "googleMaps", type: "collection", default: { latitude: "", longitude: "" }, options: [ { displayName: "Latitude", name: "latitude", type: "number", default: "", description: "The latitude coordinate for location-based queries", typeOptions: { numberPrecision: 6 } }, { displayName: "Longitude", name: "longitude", type: "number", default: "", description: "The longitude coordinate for location-based queries", typeOptions: { numberPrecision: 6 } } ] }, { displayName: "URL Context", name: "urlContext", type: "boolean", default: true, description: "Whether to allow the model to read and analyze content from specific URLs" }, { displayName: "File Search", name: "fileSearch", type: "collection", default: { fileSearchStoreNames: "[]" }, options: [ { displayName: "File Search Store Names", name: "fileSearchStoreNames", description: "The file search store names to use for the file search. File search stores are managed via Google AI Studio.", type: "json", default: "[]", required: true }, { displayName: "Metadata Filter", name: "metadataFilter", type: "string", default: "", description: 'Use metadata filter to search within a subset of documents. Example: author="Robert Graves".', placeholder: 'e.g. author="John Doe"' } ] }, { displayName: "Code Execution", name: "codeExecution", type: "boolean", default: true, description: "Whether to allow the model to execute code it generates to produce a response. Supported only by certain models." } ] }, { displayName: "Options", name: "options", placeholder: "Add Option", type: "collection", default: {}, options: [ { displayName: "Include Merged Response", name: "includeMergedResponse", type: "boolean", default: false, description: "Whether to include a single output string merging all text parts of the response", displayOptions: { show: { "@version": [{ _cnd: { gte: 1.1 } }] } } }, { displayName: "System Message", name: "systemMessage", type: "string", default: "", placeholder: "e.g. You are a helpful assistant" }, { displayName: "Code Execution", name: "codeExecution", type: "boolean", default: false, description: "Whether to allow the model to execute code it generates to produce a response. Supported only by certain models.", displayOptions: { show: { "@version": [{ _cnd: { eq: 1 } }] } } }, { displayName: "Frequency Penalty", name: "frequencyPenalty", default: 0, description: "Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim", type: "number", typeOptions: { minValue: -2, maxValue: 2, numberPrecision: 1 } }, { displayName: "Maximum Number of Tokens", name: "maxOutputTokens", default: 16, description: "The maximum number of tokens to generate in the completion", type: "number", typeOptions: { minValue: 1, numberPrecision: 0 } }, { displayName: "Number of Completions", name: "candidateCount", default: 1, description: "How many completions to generate for each prompt", type: "number", typeOptions: { minValue: 1, maxValue: 8, // Google Gemini supports up to 8 candidates numberPrecision: 0 } }, { displayName: "Presence Penalty", name: "presencePenalty", default: 0, description: "Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics", type: "number", typeOptions: { minValue: -2, maxValue: 2, numberPrecision: 1 } }, { displayName: "Output Randomness (Temperature)", name: "temperature", default: 1, description: "Controls the randomness of the output. Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive", type: "number", typeOptions: { minValue: 0, maxValue: 2, numberPrecision: 1 } }, { displayName: "Output Randomness (Top P)", name: "topP", default: 1, description: "The maximum cumulative probability of tokens to consider when sampling", type: "number", typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 1 } }, { displayName: "Output Randomness (Top K)", name: "topK", default: 1, description: "The maximum number of tokens to consider when sampling", type: "number", typeOptions: { minValue: 1, numberPrecision: 0 } }, { displayName: "Thinking Budget", name: "thinkingBudget", type: "number", default: void 0, description: "Controls reasoning tokens for thinking models. Set to 0 to disable automatic thinking. Set to -1 for dynamic thinking. Leave empty for auto mode.", typeOptions: { minValue: -1, numberPrecision: 0 } }, { displayName: "Max Tool Calls Iterations", name: "maxToolsIterations", type: "number", default: 15, description: "The maximum number of tool iteration cycles the LLM will run before stopping. A single iteration can contain multiple tool calls. Set to 0 for no limit", typeOptions: { minValue: 0, numberPrecision: 0 } } ] } ]; const displayOptions = { show: { operation: ["message"], resource: ["text"] } }; const description = (0, import_n8n_workflow.updateDisplayOptions)(displayOptions, properties); function getToolCalls(response) { return response.candidates.flatMap((c) => c.content.parts).filter((p) => "functionCall" in p); } async function execute(i) { const model = this.getNodeParameter("modelId", i, "", { extractValue: true }); const messages = this.getNodeParameter("messages.values", i, []); const simplify = this.getNodeParameter("simplify", i, true); const jsonOutput = this.getNodeParameter("jsonOutput", i, false); const options = this.getNodeParameter("options", i, {}); const builtInTools = this.getNodeParameter("builtInTools", i, {}); (0, import_n8n_workflow.validateNodeParameters)( options, { includeMergedResponse: { type: "boolean", required: false }, systemMessage: { type: "string", required: false }, codeExecution: { type: "boolean", required: false }, frequencyPenalty: { type: "number", required: false }, maxOutputTokens: { type: "number", required: false }, candidateCount: { type: "number", required: false }, presencePenalty: { type: "number", required: false }, temperature: { type: "number", required: false }, topP: { type: "number", required: false }, topK: { type: "number", required: false }, thinkingBudget: { type: "number", required: false }, maxToolsIterations: { type: "number", required: false } }, this.getNode() ); const generationConfig = { frequencyPenalty: options.frequencyPenalty, maxOutputTokens: options.maxOutputTokens, candidateCount: options.candidateCount, presencePenalty: options.presencePenalty, temperature: options.temperature, topP: options.topP, topK: options.topK, responseMimeType: jsonOutput ? "application/json" : void 0 }; if (options.thinkingBudget !== void 0) { generationConfig.thinkingConfig = { thinkingBudget: options.thinkingBudget }; } const nodeInputs = this.getNodeInputs(); const availableTools = nodeInputs.some((i2) => i2.type === "ai_tool") ? await (0, import_helpers.getConnectedTools)(this, true) : []; const tools = [ { functionDeclarations: availableTools.map((t) => ({ name: t.name, description: t.description, parameters: { ...(0, import_zod_to_json_schema.default)(t.schema, { target: "openApi3" }), // Google Gemini API throws an error if `additionalProperties` field is present additionalProperties: void 0 } })) } ]; if (!tools[0].functionDeclarations?.length) { tools.pop(); } if (this.getNode().typeVersion === 1) { if (options.codeExecution) { tools.push({ codeExecution: {} }); } } let toolConfig; if (this.getNode().typeVersion >= 1.1) { if (builtInTools) { if (builtInTools.googleSearch) { tools.push({ googleSearch: {} }); } const googleMapsOptions = builtInTools.googleMaps; if (googleMapsOptions) { tools.push({ googleMaps: {} }); const latitude = googleMapsOptions.latitude; const longitude = googleMapsOptions.longitude; if (latitude !== void 0 && latitude !== "" && longitude !== void 0 && longitude !== "") { toolConfig = { retrievalConfig: { latLng: { latitude: Number(latitude), longitude: Number(longitude) } } }; } } if (builtInTools.urlContext) { tools.push({ urlContext: {} }); } const fileSearchOptions = builtInTools.fileSearch; if (fileSearchOptions) { const fileSearchStoreNamesRaw = fileSearchOptions.fileSearchStoreNames; const metadataFilter = fileSearchOptions.metadataFilter; let fileSearchStoreNames; if (fileSearchStoreNamesRaw) { const parsed = (0, import_n8n_workflow.jsonParse)(fileSearchStoreNamesRaw, { errorMessage: "Failed to parse file search store names" }); if (Array.isArray(parsed)) { fileSearchStoreNames = parsed; } } tools.push({ fileSearch: { ...fileSearchStoreNames && { fileSearchStoreNames }, ...metadataFilter && { metadataFilter } } }); } if (builtInTools.codeExecution) { tools.push({ codeExecution: {} }); } } } const contents = messages.map((m) => ({ parts: [{ text: m.content }], role: m.role })); const body = { tools, contents, generationConfig, systemInstruction: options.systemMessage ? { parts: [{ text: options.systemMessage }] } : void 0, ...toolConfig && { toolConfig } }; let response = await import_transport.apiRequest.call(this, "POST", `/v1beta/${model}:generateContent`, { body }); const maxToolsIterations = this.getNodeParameter("options.maxToolsIterations", i, 15); const abortSignal = this.getExecutionCancelSignal(); let currentIteration = 1; let toolCalls = getToolCalls(response); while (toolCalls.length) { if (maxToolsIterations > 0 && currentIteration >= maxToolsIterations || abortSignal?.aborted) { break; } contents.push(...response.candidates.map((c) => c.content)); for (const { functionCall } of toolCalls) { let toolResponse; for (const availableTool of availableTools) { if (availableTool.name === functionCall.name) { toolResponse = await availableTool.invoke(functionCall.args); } } contents.push({ parts: [ { functionResponse: { id: functionCall.id, name: functionCall.name, response: { result: toolResponse } } } ], role: "tool" }); } response = await import_transport.apiRequest.call(this, "POST", `/v1beta/${model}:generateContent`, { body }); toolCalls = getToolCalls(response); currentIteration++; } const candidates = options.includeMergedResponse ? response.candidates.map((candidate) => ({ ...candidate, mergedResponse: candidate.content.parts.filter((part) => "text" in part).map((part) => part.text).join("") })) : response.candidates; if (simplify) { return candidates.map((candidate) => ({ json: candidate, pairedItem: { item: i } })); } return [ { json: { ...response, candidates }, pairedItem: { item: i } } ]; } // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { description, execute }); //# sourceMappingURL=message.operation.js.map