UNPKG

@n8n/n8n-nodes-langchain

Version:

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

287 lines 10.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.description = void 0; exports.execute = execute; const n8n_workflow_1 = require("n8n-workflow"); const zod_to_json_schema_1 = __importDefault(require("zod-to-json-schema")); const helpers_1 = require("../../../../../utils/helpers"); const transport_1 = require("../../transport"); const properties = [ { displayName: 'Model', name: 'modelId', type: 'options', options: [ { name: 'MiniMax-M2', value: 'MiniMax-M2' }, { name: 'MiniMax-M2.1', value: 'MiniMax-M2.1' }, { name: 'MiniMax-M2.1-Highspeed', value: 'MiniMax-M2.1-highspeed' }, { name: 'MiniMax-M2.5', value: 'MiniMax-M2.5' }, { name: 'MiniMax-M2.5-Highspeed', value: 'MiniMax-M2.5-highspeed' }, { name: 'MiniMax-M2.7', value: 'MiniMax-M2.7' }, { name: 'MiniMax-M2.7-Highspeed', value: 'MiniMax-M2.7-highspeed' }, ], default: 'MiniMax-M2.7', description: 'The model to use for generating the response', }, { displayName: 'Messages', name: 'messages', type: 'fixedCollection', typeOptions: { sortable: true, multipleValues: true, }, placeholder: 'Add Message', default: { values: [{ content: '', role: 'user' }] }, options: [ { displayName: 'Values', name: 'values', values: [ { displayName: 'Prompt', name: 'content', type: 'string', description: 'The content of the message to be sent', 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: 'Assistant', value: 'assistant', 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: 'Options', name: 'options', placeholder: 'Add Option', type: 'collection', default: {}, options: [ { displayName: 'Hide Thinking', name: 'hideThinking', type: 'boolean', default: true, description: 'Whether to strip chain-of-thought reasoning from the response, returning only the final answer', }, { displayName: 'Maximum Number of Tokens', name: 'maxTokens', default: 1024, description: 'The maximum number of tokens to generate in the completion', type: 'number', 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, }, }, { displayName: 'Output Randomness (Temperature)', name: 'temperature', default: 0.7, 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: 1, numberPrecision: 1, }, }, { displayName: 'Output Randomness (Top P)', name: 'topP', default: 0.95, description: 'The maximum cumulative probability of tokens to consider when sampling', type: 'number', typeOptions: { minValue: 0, maxValue: 1, numberPrecision: 2, }, }, { displayName: 'System Message', name: 'system', type: 'string', default: '', placeholder: 'e.g. You are a helpful assistant', }, ], }, ]; const displayOptions = { show: { operation: ['message'], resource: ['text'], }, }; exports.description = (0, n8n_workflow_1.updateDisplayOptions)(displayOptions, properties); async function execute(i) { const model = this.getNodeParameter('modelId', i); const rawMessages = this.getNodeParameter('messages.values', i, []); const simplify = this.getNodeParameter('simplify', i, true); const options = this.getNodeParameter('options', i, {}); const hideThinking = options.hideThinking ?? true; const messages = []; if (options.system) { messages.push({ role: 'system', content: options.system }); } for (const msg of rawMessages) { messages.push({ role: msg.role, content: msg.content }); } const { tools, connectedTools } = await getToolDefinitions.call(this); const body = { model, messages, max_tokens: options.maxTokens ?? 1024, }; if (hideThinking) { body.reasoning_split = true; } if (options.temperature !== undefined) body.temperature = options.temperature; if (options.topP !== undefined) body.top_p = options.topP; if (tools.length > 0) { body.tools = tools; } let response = (await transport_1.apiRequest.call(this, 'POST', '/chat/completions', { body, })); const captureUsage = () => { const usage = response.usage; if (usage) { (0, n8n_workflow_1.accumulateTokenUsage)(this, usage.prompt_tokens, usage.completion_tokens); } }; captureUsage(); const maxToolsIterations = this.getNodeParameter('options.maxToolsIterations', i, 15); const abortSignal = this.getExecutionCancelSignal(); let currentIteration = 0; while (true) { if (abortSignal?.aborted) { break; } const choice = response.choices?.[0]; if (choice?.finish_reason !== 'tool_calls' || !choice.message.tool_calls?.length) { break; } if (maxToolsIterations > 0 && currentIteration >= maxToolsIterations) { break; } const assistantMsg = { role: 'assistant', content: choice.message.content ?? '', tool_calls: choice.message.tool_calls, }; if (choice.message.reasoning_content) { assistantMsg.reasoning_content = choice.message.reasoning_content; } messages.push(assistantMsg); await handleToolUse.call(this, choice.message.tool_calls, messages, connectedTools); currentIteration++; response = (await transport_1.apiRequest.call(this, 'POST', '/chat/completions', { body, })); captureUsage(); } const finalMessage = response.choices?.[0]?.message; if (simplify) { const result = { content: finalMessage?.content ?? '', }; if (!hideThinking && finalMessage?.reasoning_content) { result.reasoning_content = finalMessage.reasoning_content; } return [ { json: result, pairedItem: { item: i }, }, ]; } return [ { json: { ...response }, pairedItem: { item: i }, }, ]; } async function getToolDefinitions() { let connectedTools = []; const nodeInputs = this.getNodeInputs(); if (nodeInputs.some((input) => input.type === 'ai_tool')) { connectedTools = await (0, helpers_1.getConnectedTools)(this, true); } const tools = connectedTools.map((t) => ({ type: 'function', function: { name: t.name, description: t.description, parameters: (0, zod_to_json_schema_1.default)(t.schema), }, })); return { tools, connectedTools }; } async function handleToolUse(toolCalls, messages, connectedTools) { for (const toolCall of toolCalls) { let toolResponse; for (const connectedTool of connectedTools) { if (connectedTool.name === toolCall.function.name) { const args = (0, n8n_workflow_1.jsonParse)(toolCall.function.arguments); toolResponse = await connectedTool.invoke(args); } } messages.push({ role: 'tool', content: typeof toolResponse === 'object' ? JSON.stringify(toolResponse) : (toolResponse ?? ''), tool_call_id: toolCall.id, }); } } //# sourceMappingURL=message.operation.js.map