@n8n/n8n-nodes-langchain 2.1.2 → 2.2.0
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/Guardrails/actions/checks/keywords.js +25 -7
- package/dist/nodes/Guardrails/actions/checks/keywords.js.map +1 -1
- package/dist/nodes/agents/OpenAiAssistant/OpenAiAssistant.node.js +5 -1
- package/dist/nodes/agents/OpenAiAssistant/OpenAiAssistant.node.js.map +1 -1
- package/dist/nodes/chains/ChainLLM/ChainLlm.node.js +1 -1
- package/dist/nodes/chains/ChainLLM/ChainLlm.node.js.map +1 -1
- package/dist/nodes/chains/ChainLLM/methods/chainExecutor.js +27 -13
- package/dist/nodes/chains/ChainLLM/methods/chainExecutor.js.map +1 -1
- package/dist/nodes/chains/ChainLLM/methods/promptUtils.js +35 -2
- package/dist/nodes/chains/ChainLLM/methods/promptUtils.js.map +1 -1
- package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js +6 -1
- package/dist/nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.js.map +1 -1
- package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js +7 -1
- package/dist/nodes/llms/LMChatOpenAi/LmChatOpenAi.node.js.map +1 -1
- package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js +5 -1
- package/dist/nodes/llms/LMChatOpenAi/methods/loadModels.js.map +1 -1
- package/dist/nodes/llms/LMOpenAi/LmOpenAi.node.js +5 -1
- package/dist/nodes/llms/LMOpenAi/LmOpenAi.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js +13 -8
- package/dist/nodes/tools/ToolWorkflow/v2/ToolWorkflowV2.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js +2 -1
- package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js.map +1 -1
- package/dist/nodes/vendors/OpenAi/v1/actions/assistant/message.operation.js +5 -1
- package/dist/nodes/vendors/OpenAi/v1/actions/assistant/message.operation.js.map +1 -1
- package/dist/types/nodes.json +1 -1
- package/dist/utils/agent-execution/buildSteps.js +14 -1
- package/dist/utils/agent-execution/buildSteps.js.map +1 -1
- package/dist/utils/embeddings/embeddingInputValidation.js +55 -0
- package/dist/utils/embeddings/embeddingInputValidation.js.map +1 -0
- package/dist/utils/logWrapper.js +10 -4
- package/dist/utils/logWrapper.js.map +1 -1
- package/package.json +7 -7
|
@@ -21,11 +21,22 @@ __export(keywords_exports, {
|
|
|
21
21
|
createKeywordsCheckFn: () => createKeywordsCheckFn
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(keywords_exports);
|
|
24
|
+
const WORD_CHAR_CLASS = "[\\p{L}\\p{N}_]";
|
|
25
|
+
const isWordChar = (() => {
|
|
26
|
+
const wordCharRegex = new RegExp(WORD_CHAR_CLASS, "u");
|
|
27
|
+
return (char) => {
|
|
28
|
+
if (!char) return false;
|
|
29
|
+
return wordCharRegex.test(char);
|
|
30
|
+
};
|
|
31
|
+
})();
|
|
24
32
|
const keywordsCheck = (text, config) => {
|
|
25
33
|
const { keywords } = config;
|
|
26
34
|
const sanitizedKeywords = keywords.map((k) => k.replace(/[.,!?;:]+$/, ""));
|
|
27
|
-
const
|
|
28
|
-
|
|
35
|
+
const keywordEntries = sanitizedKeywords.map((sanitized) => ({
|
|
36
|
+
sanitized,
|
|
37
|
+
escaped: sanitized.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")
|
|
38
|
+
})).filter(({ sanitized }) => sanitized.length > 0);
|
|
39
|
+
if (keywordEntries.length === 0) {
|
|
29
40
|
return {
|
|
30
41
|
guardrailName: "keywords",
|
|
31
42
|
tripwireTriggered: false,
|
|
@@ -34,11 +45,18 @@ const keywordsCheck = (text, config) => {
|
|
|
34
45
|
}
|
|
35
46
|
};
|
|
36
47
|
}
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
48
|
+
const keywordPatterns = keywordEntries.map(({ sanitized, escaped }) => {
|
|
49
|
+
const keywordChars = Array.from(sanitized);
|
|
50
|
+
const firstChar = keywordChars[0];
|
|
51
|
+
const lastChar = keywordChars[keywordChars.length - 1];
|
|
52
|
+
const needsLeftBoundary = isWordChar(firstChar);
|
|
53
|
+
const needsRightBoundary = isWordChar(lastChar);
|
|
54
|
+
const leftBoundary = needsLeftBoundary ? `(?<!${WORD_CHAR_CLASS})` : "";
|
|
55
|
+
const rightBoundary = needsRightBoundary ? `(?!${WORD_CHAR_CLASS})` : "";
|
|
56
|
+
return `${leftBoundary}${escaped}${rightBoundary}`;
|
|
57
|
+
});
|
|
58
|
+
const patternText = `(?:${keywordPatterns.join("|")})`;
|
|
59
|
+
const pattern = new RegExp(patternText, "giu");
|
|
42
60
|
const matches = [];
|
|
43
61
|
let match;
|
|
44
62
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../nodes/Guardrails/actions/checks/keywords.ts"],"sourcesContent":["// Source: https://github.com/openai/openai-guardrails-js/blob/b9b99b4fb454f02a362c2836aec6285176ec40a8/src/checks/keywords.ts\nimport type { CreateCheckFn, GuardrailResult } from '../types';\n\ninterface KeywordsConfig {\n\tkeywords: string[];\n}\n\n/**\n * Keywords-based content filtering guardrail.\n *\n * Checks if any of the configured keywords appear in the input text.\n * Can be configured to trigger tripwires on matches or just report them.\n *\n * @param text Input text to check\n * @param config Configuration specifying keywords and behavior\n * @returns GuardrailResult indicating if tripwire was triggered\n */\nconst keywordsCheck = (text: string, config: KeywordsConfig): GuardrailResult => {\n\tconst { keywords } = config;\n\n\t// Sanitize keywords by stripping trailing punctuation\n\tconst sanitizedKeywords = keywords.map((k: string) => k.replace(/[.,!?;:]+$/, ''));\n\n\tconst
|
|
1
|
+
{"version":3,"sources":["../../../../../nodes/Guardrails/actions/checks/keywords.ts"],"sourcesContent":["// Source: https://github.com/openai/openai-guardrails-js/blob/b9b99b4fb454f02a362c2836aec6285176ec40a8/src/checks/keywords.ts\nimport type { CreateCheckFn, GuardrailResult } from '../types';\n\ninterface KeywordsConfig {\n\tkeywords: string[];\n}\n\n// \\p{L}|\\p{N}|_ - any unicode letter, number, or underscore. Alternative to \\b\nconst WORD_CHAR_CLASS = '[\\\\p{L}\\\\p{N}_]';\nconst isWordChar = (() => {\n\tconst wordCharRegex = new RegExp(WORD_CHAR_CLASS, 'u');\n\treturn (char: string | undefined): boolean => {\n\t\tif (!char) return false;\n\t\treturn wordCharRegex.test(char);\n\t};\n})();\n\n/**\n * Keywords-based content filtering guardrail.\n *\n * Checks if any of the configured keywords appear in the input text.\n * Can be configured to trigger tripwires on matches or just report them.\n *\n * @param text Input text to check\n * @param config Configuration specifying keywords and behavior\n * @returns GuardrailResult indicating if tripwire was triggered\n */\nconst keywordsCheck = (text: string, config: KeywordsConfig): GuardrailResult => {\n\tconst { keywords } = config;\n\n\t// Sanitize keywords by stripping trailing punctuation\n\tconst sanitizedKeywords = keywords.map((k: string) => k.replace(/[.,!?;:]+$/, ''));\n\n\tconst keywordEntries = sanitizedKeywords\n\t\t.map((sanitized) => ({\n\t\t\tsanitized,\n\t\t\tescaped: sanitized.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'),\n\t\t}))\n\t\t.filter(({ sanitized }) => sanitized.length > 0);\n\n\tif (keywordEntries.length === 0) {\n\t\treturn {\n\t\t\tguardrailName: 'keywords',\n\t\t\ttripwireTriggered: false,\n\t\t\tinfo: {\n\t\t\t\tmatchedKeywords: [],\n\t\t\t},\n\t\t};\n\t}\n\n\t// Apply unicode-aware word boundaries per keyword so tokens that start/end with punctuation still match.\n\tconst keywordPatterns = keywordEntries.map(({ sanitized, escaped }) => {\n\t\tconst keywordChars = Array.from(sanitized);\n\t\tconst firstChar = keywordChars[0];\n\t\tconst lastChar = keywordChars[keywordChars.length - 1];\n\t\tconst needsLeftBoundary = isWordChar(firstChar);\n\t\tconst needsRightBoundary = isWordChar(lastChar);\n\t\t// not preceded by a word character\n\t\tconst leftBoundary = needsLeftBoundary ? `(?<!${WORD_CHAR_CLASS})` : '';\n\t\t// not followed by a word character\n\t\tconst rightBoundary = needsRightBoundary ? `(?!${WORD_CHAR_CLASS})` : '';\n\t\treturn `${leftBoundary}${escaped}${rightBoundary}`;\n\t});\n\n\tconst patternText = `(?:${keywordPatterns.join('|')})`;\n\tconst pattern = new RegExp(patternText, 'giu'); // case-insensitive, global, unicode aware\n\n\tconst matches: string[] = [];\n\tlet match;\n\tconst seen = new Set<string>();\n\n\t// Find all matches and collect unique ones (case-insensitive)\n\twhile ((match = pattern.exec(text)) !== null) {\n\t\tconst matchedText = match[0];\n\t\tif (!seen.has(matchedText.toLowerCase())) {\n\t\t\tmatches.push(matchedText);\n\t\t\tseen.add(matchedText.toLowerCase());\n\t\t}\n\t}\n\n\tconst tripwireTriggered = matches.length > 0;\n\n\treturn {\n\t\tguardrailName: 'keywords',\n\t\ttripwireTriggered,\n\t\tinfo: {\n\t\t\tmatchedKeywords: matches,\n\t\t},\n\t};\n};\n\nexport const createKeywordsCheckFn: CreateCheckFn<KeywordsConfig> = (config) => (input: string) =>\n\tkeywordsCheck(input, config);\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,MAAM,kBAAkB;AACxB,MAAM,cAAc,MAAM;AACzB,QAAM,gBAAgB,IAAI,OAAO,iBAAiB,GAAG;AACrD,SAAO,CAAC,SAAsC;AAC7C,QAAI,CAAC,KAAM,QAAO;AAClB,WAAO,cAAc,KAAK,IAAI;AAAA,EAC/B;AACD,GAAG;AAYH,MAAM,gBAAgB,CAAC,MAAc,WAA4C;AAChF,QAAM,EAAE,SAAS,IAAI;AAGrB,QAAM,oBAAoB,SAAS,IAAI,CAAC,MAAc,EAAE,QAAQ,cAAc,EAAE,CAAC;AAEjF,QAAM,iBAAiB,kBACrB,IAAI,CAAC,eAAe;AAAA,IACpB;AAAA,IACA,SAAS,UAAU,QAAQ,uBAAuB,MAAM;AAAA,EACzD,EAAE,EACD,OAAO,CAAC,EAAE,UAAU,MAAM,UAAU,SAAS,CAAC;AAEhD,MAAI,eAAe,WAAW,GAAG;AAChC,WAAO;AAAA,MACN,eAAe;AAAA,MACf,mBAAmB;AAAA,MACnB,MAAM;AAAA,QACL,iBAAiB,CAAC;AAAA,MACnB;AAAA,IACD;AAAA,EACD;AAGA,QAAM,kBAAkB,eAAe,IAAI,CAAC,EAAE,WAAW,QAAQ,MAAM;AACtE,UAAM,eAAe,MAAM,KAAK,SAAS;AACzC,UAAM,YAAY,aAAa,CAAC;AAChC,UAAM,WAAW,aAAa,aAAa,SAAS,CAAC;AACrD,UAAM,oBAAoB,WAAW,SAAS;AAC9C,UAAM,qBAAqB,WAAW,QAAQ;AAE9C,UAAM,eAAe,oBAAoB,OAAO,eAAe,MAAM;AAErE,UAAM,gBAAgB,qBAAqB,MAAM,eAAe,MAAM;AACtE,WAAO,GAAG,YAAY,GAAG,OAAO,GAAG,aAAa;AAAA,EACjD,CAAC;AAED,QAAM,cAAc,MAAM,gBAAgB,KAAK,GAAG,CAAC;AACnD,QAAM,UAAU,IAAI,OAAO,aAAa,KAAK;AAE7C,QAAM,UAAoB,CAAC;AAC3B,MAAI;AACJ,QAAM,OAAO,oBAAI,IAAY;AAG7B,UAAQ,QAAQ,QAAQ,KAAK,IAAI,OAAO,MAAM;AAC7C,UAAM,cAAc,MAAM,CAAC;AAC3B,QAAI,CAAC,KAAK,IAAI,YAAY,YAAY,CAAC,GAAG;AACzC,cAAQ,KAAK,WAAW;AACxB,WAAK,IAAI,YAAY,YAAY,CAAC;AAAA,IACnC;AAAA,EACD;AAEA,QAAM,oBAAoB,QAAQ,SAAS;AAE3C,SAAO;AAAA,IACN,eAAe;AAAA,IACf;AAAA,IACA,MAAM;AAAA,MACL,iBAAiB;AAAA,IAClB;AAAA,EACD;AACD;AAEO,MAAM,wBAAuD,CAAC,WAAW,CAAC,UAChF,cAAc,OAAO,MAAM;","names":[]}
|
|
@@ -28,6 +28,8 @@ var import_openai = require("openai");
|
|
|
28
28
|
var import_helpers = require("../../../utils/helpers");
|
|
29
29
|
var import_tracing = require("../../../utils/tracing");
|
|
30
30
|
var import_utils = require("./utils");
|
|
31
|
+
var import_di = require("@n8n/di");
|
|
32
|
+
var import_config = require("@n8n/config");
|
|
31
33
|
class OpenAiAssistant {
|
|
32
34
|
constructor() {
|
|
33
35
|
this.description = {
|
|
@@ -337,11 +339,13 @@ class OpenAiAssistant {
|
|
|
337
339
|
if (input === void 0) {
|
|
338
340
|
throw new import_n8n_workflow.NodeOperationError(this.getNode(), "The \u2018text\u2018 parameter is empty.");
|
|
339
341
|
}
|
|
342
|
+
const { openAiDefaultHeaders: defaultHeaders } = import_di.Container.get(import_config.AiConfig);
|
|
340
343
|
const client = new import_openai.OpenAI({
|
|
341
344
|
apiKey: credentials.apiKey,
|
|
342
345
|
maxRetries: options.maxRetries ?? 2,
|
|
343
346
|
timeout: options.timeout ?? 1e4,
|
|
344
|
-
baseURL: options.baseURL
|
|
347
|
+
baseURL: options.baseURL,
|
|
348
|
+
defaultHeaders
|
|
345
349
|
});
|
|
346
350
|
let agent;
|
|
347
351
|
const nativeToolsParsed = nativeTools.map((tool) => ({ type: tool }));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/agents/OpenAiAssistant/OpenAiAssistant.node.ts"],"sourcesContent":["import { AgentExecutor } from '@langchain/classic/agents';\nimport type { OpenAIToolType } from '@langchain/classic/dist/experimental/openai_assistant/schema';\nimport { OpenAIAssistantRunnable } from '@langchain/classic/experimental/openai_assistant';\nimport { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { OpenAI as OpenAIClient } from 'openai';\n\nimport { getConnectedTools } from '@utils/helpers';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { formatToOpenAIAssistantTool } from './utils';\n\nexport class OpenAiAssistant implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenAI Assistant',\n\t\tname: 'openAiAssistant',\n\t\thidden: true,\n\t\ticon: 'fa:robot',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Utilizes Assistant API from Open AI.',\n\t\tsubtitle: 'Open AI Assistant',\n\t\tdefaults: {\n\t\t\tname: 'OpenAI Assistant',\n\t\t\tcolor: '#404040',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Agents', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.openaiassistant/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [\n\t\t\t{ type: NodeConnectionTypes.Main },\n\t\t\t{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' },\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'openAiApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\trequestDefaults: {\n\t\t\tignoreHttpStatusErrors: true,\n\t\t\tbaseURL:\n\t\t\t\t'={{ $parameter.options?.baseURL?.split(\"/\").slice(0,-1).join(\"/\") || \"https://api.openai.com\" }}',\n\t\t},\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Operation',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdefault: 'existing',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Use New Assistant',\n\t\t\t\t\t\tvalue: 'new',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Use Existing Assistant',\n\t\t\t\t\t\tvalue: 'existing',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Instructions',\n\t\t\t\tname: 'instructions',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'How the Assistant and model should behave or respond',\n\t\t\t\tdefault: '',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 5,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tname: 'model',\n\t\t\t\ttype: 'options',\n\t\t\t\tdescription:\n\t\t\t\t\t'The model which will be used to power the assistant. <a href=\"https://beta.openai.com/docs/models/overview\">Learn more</a>. The Retrieval tool requires gpt-3.5-turbo-1106 and gpt-4-1106-preview models.',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptions: {\n\t\t\t\t\t\trouting: {\n\t\t\t\t\t\t\trequest: {\n\t\t\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t\t\t\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || \"v1\" }}/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tpass: \"={{ $responseItem.id.startsWith('gpt-') && !$responseItem.id.includes('instruct') }}\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'model',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: 'gpt-3.5-turbo-1106',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Assistant',\n\t\t\t\tname: 'assistantId',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['existing'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdescription:\n\t\t\t\t\t'The assistant to use. <a href=\"https://beta.openai.com/docs/assistants/overview\">Learn more</a>.',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptions: {\n\t\t\t\t\t\trouting: {\n\t\t\t\t\t\t\trequest: {\n\t\t\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\t'OpenAI-Beta': 'assistants=v1',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || \"v1\" }}/assistants',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{$responseItem.name}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\n\t\t\t\t\t\t\t\t\t\t\tdescription: '={{$responseItem.model}}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'assistant',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'OpenAI Tools',\n\t\t\t\tname: 'nativeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Code Interpreter',\n\t\t\t\t\t\tvalue: 'code_interpreter',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Knowledge Retrieval',\n\t\t\t\t\t\tvalue: 'retrieval',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Connect your own custom tools to this node on the canvas',\n\t\t\t\tname: 'noticeTools',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Upload files for retrieval using the <a href=\"https://platform.openai.com/playground\" target=\"_blank\">OpenAI website<a/>',\n\t\t\t\tname: 'noticeTools',\n\t\t\t\ttype: 'notice',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tnoticeTheme: 'info',\n\t\t\t\t},\n\t\t\t\tdisplayOptions: { show: { '/nativeTools': ['retrieval'] } },\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Base URL',\n\t\t\t\t\t\tname: 'baseURL',\n\t\t\t\t\t\tdefault: 'https://api.openai.com/v1',\n\t\t\t\t\t\tdescription: 'Override the default base URL for the API',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\t\t\tname: 'maxRetries',\n\t\t\t\t\t\tdefault: 2,\n\t\t\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 10000,\n\t\t\t\t\t\tdescription: 'Maximum amount of time a request is allowed to take in milliseconds',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst nodeVersion = this.getNode().typeVersion;\n\t\tconst tools = await getConnectedTools(this, nodeVersion > 1, false);\n\t\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\ttry {\n\t\t\t\tconst input = this.getNodeParameter('text', itemIndex) as string;\n\t\t\t\tconst assistantId = this.getNodeParameter('assistantId', itemIndex, '') as string;\n\t\t\t\tconst nativeTools = this.getNodeParameter('nativeTools', itemIndex, []) as Array<\n\t\t\t\t\t'code_interpreter' | 'retrieval'\n\t\t\t\t>;\n\n\t\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\t\tbaseURL?: string;\n\t\t\t\t\tmaxRetries: number;\n\t\t\t\t\ttimeout: number;\n\t\t\t\t};\n\n\t\t\t\tif (input === undefined) {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘text‘ parameter is empty.');\n\t\t\t\t}\n\n\t\t\t\tconst client = new OpenAIClient({\n\t\t\t\t\tapiKey: credentials.apiKey as string,\n\t\t\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\t\t\ttimeout: options.timeout ?? 10000,\n\t\t\t\t\tbaseURL: options.baseURL,\n\t\t\t\t});\n\t\t\t\tlet agent;\n\t\t\t\tconst nativeToolsParsed: OpenAIToolType = nativeTools.map((tool) => ({ type: tool }));\n\t\t\t\tconst transformedConnectedTools = tools?.map(formatToOpenAIAssistantTool) ?? [];\n\t\t\t\tconst newTools = [...transformedConnectedTools, ...nativeToolsParsed];\n\n\t\t\t\t// Existing agent, update tools with currently assigned\n\t\t\t\tif (assistantId) {\n\t\t\t\t\tagent = new OpenAIAssistantRunnable({ assistantId, client, asAgent: true });\n\n\t\t\t\t\tawait client.beta.assistants.update(assistantId, {\n\t\t\t\t\t\ttools: newTools,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst name = this.getNodeParameter('name', itemIndex, '') as string;\n\t\t\t\t\tconst instructions = this.getNodeParameter('instructions', itemIndex, '') as string;\n\t\t\t\t\tconst model = this.getNodeParameter('model', itemIndex, 'gpt-3.5-turbo-1106') as string;\n\n\t\t\t\t\tagent = await OpenAIAssistantRunnable.createAssistant({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tinstructions,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttools: newTools,\n\t\t\t\t\t\tasAgent: true,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst agentExecutor = AgentExecutor.fromAgentAndTools({\n\t\t\t\t\tagent,\n\t\t\t\t\ttools,\n\t\t\t\t});\n\n\t\t\t\tconst response = await agentExecutor.withConfig(getTracingConfig(this)).invoke({\n\t\t\t\t\tcontent: input,\n\t\t\t\t\tsignal: this.getExecutionCancelSignal(),\n\t\t\t\t\ttimeout: options.timeout ?? 10000,\n\t\t\t\t});\n\n\t\t\t\treturnData.push({ json: response });\n\t\t\t} catch (error) {\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":["OpenAIClient"]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/agents/OpenAiAssistant/OpenAiAssistant.node.ts"],"sourcesContent":["import { AgentExecutor } from '@langchain/classic/agents';\nimport type { OpenAIToolType } from '@langchain/classic/dist/experimental/openai_assistant/schema';\nimport { OpenAIAssistantRunnable } from '@langchain/classic/experimental/openai_assistant';\nimport { NodeConnectionTypes, NodeOperationError } from 'n8n-workflow';\nimport type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { OpenAI as OpenAIClient } from 'openai';\n\nimport { getConnectedTools } from '@utils/helpers';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { formatToOpenAIAssistantTool } from './utils';\nimport { Container } from '@n8n/di';\nimport { AiConfig } from '@n8n/config';\n\nexport class OpenAiAssistant implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenAI Assistant',\n\t\tname: 'openAiAssistant',\n\t\thidden: true,\n\t\ticon: 'fa:robot',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1],\n\t\tdescription: 'Utilizes Assistant API from Open AI.',\n\t\tsubtitle: 'Open AI Assistant',\n\t\tdefaults: {\n\t\t\tname: 'OpenAI Assistant',\n\t\t\tcolor: '#404040',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Agents', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.openaiassistant/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: [\n\t\t\t{ type: NodeConnectionTypes.Main },\n\t\t\t{ type: NodeConnectionTypes.AiTool, displayName: 'Tools' },\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'openAiApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\trequestDefaults: {\n\t\t\tignoreHttpStatusErrors: true,\n\t\t\tbaseURL:\n\t\t\t\t'={{ $parameter.options?.baseURL?.split(\"/\").slice(0,-1).join(\"/\") || \"https://api.openai.com\" }}',\n\t\t},\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Operation',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdefault: 'existing',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Use New Assistant',\n\t\t\t\t\t\tvalue: 'new',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Use Existing Assistant',\n\t\t\t\t\t\tvalue: 'existing',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Name',\n\t\t\t\tname: 'name',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Instructions',\n\t\t\t\tname: 'instructions',\n\t\t\t\ttype: 'string',\n\t\t\t\tdescription: 'How the Assistant and model should behave or respond',\n\t\t\t\tdefault: '',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 5,\n\t\t\t\t},\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Model',\n\t\t\t\tname: 'model',\n\t\t\t\ttype: 'options',\n\t\t\t\tdescription:\n\t\t\t\t\t'The model which will be used to power the assistant. <a href=\"https://beta.openai.com/docs/models/overview\">Learn more</a>. The Retrieval tool requires gpt-3.5-turbo-1106 and gpt-4-1106-preview models.',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['new'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptions: {\n\t\t\t\t\t\trouting: {\n\t\t\t\t\t\t\trequest: {\n\t\t\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t\t\t\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || \"v1\" }}/models',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tpass: \"={{ $responseItem.id.startsWith('gpt-') && !$responseItem.id.includes('instruct') }}\",\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'model',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: 'gpt-3.5-turbo-1106',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Assistant',\n\t\t\t\tname: 'assistantId',\n\t\t\t\ttype: 'options',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/mode': ['existing'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdescription:\n\t\t\t\t\t'The assistant to use. <a href=\"https://beta.openai.com/docs/assistants/overview\">Learn more</a>.',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tloadOptions: {\n\t\t\t\t\t\trouting: {\n\t\t\t\t\t\t\trequest: {\n\t\t\t\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\t\t\t\theaders: {\n\t\t\t\t\t\t\t\t\t'OpenAI-Beta': 'assistants=v1',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || \"v1\" }}/assistants',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\toutput: {\n\t\t\t\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tname: '={{$responseItem.name}}',\n\t\t\t\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\n\t\t\t\t\t\t\t\t\t\t\tdescription: '={{$responseItem.model}}',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trouting: {\n\t\t\t\t\tsend: {\n\t\t\t\t\t\ttype: 'body',\n\t\t\t\t\t\tproperty: 'assistant',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chat_input }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Text',\n\t\t\t\tname: 'text',\n\t\t\t\ttype: 'string',\n\t\t\t\trequired: true,\n\t\t\t\tdefault: '={{ $json.chatInput }}',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'OpenAI Tools',\n\t\t\t\tname: 'nativeTools',\n\t\t\t\ttype: 'multiOptions',\n\t\t\t\tdefault: [],\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Code Interpreter',\n\t\t\t\t\t\tvalue: 'code_interpreter',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Knowledge Retrieval',\n\t\t\t\t\t\tvalue: 'retrieval',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Connect your own custom tools to this node on the canvas',\n\t\t\t\tname: 'noticeTools',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Upload files for retrieval using the <a href=\"https://platform.openai.com/playground\" target=\"_blank\">OpenAI website<a/>',\n\t\t\t\tname: 'noticeTools',\n\t\t\t\ttype: 'notice',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tnoticeTheme: 'info',\n\t\t\t\t},\n\t\t\t\tdisplayOptions: { show: { '/nativeTools': ['retrieval'] } },\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Base URL',\n\t\t\t\t\t\tname: 'baseURL',\n\t\t\t\t\t\tdefault: 'https://api.openai.com/v1',\n\t\t\t\t\t\tdescription: 'Override the default base URL for the API',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\t\t\tname: 'maxRetries',\n\t\t\t\t\t\tdefault: 2,\n\t\t\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 10000,\n\t\t\t\t\t\tdescription: 'Maximum amount of time a request is allowed to take in milliseconds',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst nodeVersion = this.getNode().typeVersion;\n\t\tconst tools = await getConnectedTools(this, nodeVersion > 1, false);\n\t\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\n\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\ttry {\n\t\t\t\tconst input = this.getNodeParameter('text', itemIndex) as string;\n\t\t\t\tconst assistantId = this.getNodeParameter('assistantId', itemIndex, '') as string;\n\t\t\t\tconst nativeTools = this.getNodeParameter('nativeTools', itemIndex, []) as Array<\n\t\t\t\t\t'code_interpreter' | 'retrieval'\n\t\t\t\t>;\n\n\t\t\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\t\t\tbaseURL?: string;\n\t\t\t\t\tmaxRetries: number;\n\t\t\t\t\ttimeout: number;\n\t\t\t\t};\n\n\t\t\t\tif (input === undefined) {\n\t\t\t\t\tthrow new NodeOperationError(this.getNode(), 'The ‘text‘ parameter is empty.');\n\t\t\t\t}\n\n\t\t\t\tconst { openAiDefaultHeaders: defaultHeaders } = Container.get(AiConfig);\n\n\t\t\t\tconst client = new OpenAIClient({\n\t\t\t\t\tapiKey: credentials.apiKey as string,\n\t\t\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\t\t\ttimeout: options.timeout ?? 10000,\n\t\t\t\t\tbaseURL: options.baseURL,\n\t\t\t\t\tdefaultHeaders,\n\t\t\t\t});\n\t\t\t\tlet agent;\n\t\t\t\tconst nativeToolsParsed: OpenAIToolType = nativeTools.map((tool) => ({ type: tool }));\n\t\t\t\tconst transformedConnectedTools = tools?.map(formatToOpenAIAssistantTool) ?? [];\n\t\t\t\tconst newTools = [...transformedConnectedTools, ...nativeToolsParsed];\n\n\t\t\t\t// Existing agent, update tools with currently assigned\n\t\t\t\tif (assistantId) {\n\t\t\t\t\tagent = new OpenAIAssistantRunnable({ assistantId, client, asAgent: true });\n\n\t\t\t\t\tawait client.beta.assistants.update(assistantId, {\n\t\t\t\t\t\ttools: newTools,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tconst name = this.getNodeParameter('name', itemIndex, '') as string;\n\t\t\t\t\tconst instructions = this.getNodeParameter('instructions', itemIndex, '') as string;\n\t\t\t\t\tconst model = this.getNodeParameter('model', itemIndex, 'gpt-3.5-turbo-1106') as string;\n\n\t\t\t\t\tagent = await OpenAIAssistantRunnable.createAssistant({\n\t\t\t\t\t\tmodel,\n\t\t\t\t\t\tclient,\n\t\t\t\t\t\tinstructions,\n\t\t\t\t\t\tname,\n\t\t\t\t\t\ttools: newTools,\n\t\t\t\t\t\tasAgent: true,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tconst agentExecutor = AgentExecutor.fromAgentAndTools({\n\t\t\t\t\tagent,\n\t\t\t\t\ttools,\n\t\t\t\t});\n\n\t\t\t\tconst response = await agentExecutor.withConfig(getTracingConfig(this)).invoke({\n\t\t\t\t\tcontent: input,\n\t\t\t\t\tsignal: this.getExecutionCancelSignal(),\n\t\t\t\t\ttimeout: options.timeout ?? 10000,\n\t\t\t\t});\n\n\t\t\t\treturnData.push({ json: response });\n\t\t\t} catch (error) {\n\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAA8B;AAE9B,8BAAwC;AACxC,0BAAwD;AAOxD,oBAAuC;AAEvC,qBAAkC;AAClC,qBAAiC;AAEjC,mBAA4C;AAC5C,gBAA0B;AAC1B,oBAAyB;AAElB,MAAM,gBAAqC;AAAA,EAA3C;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS,CAAC,GAAG,GAAG;AAAA,MAChB,aAAa;AAAA,MACb,UAAU;AAAA,MACV,UAAU;AAAA,QACT,MAAM;AAAA,QACN,OAAO;AAAA,MACR;AAAA,MACA,OAAO;AAAA,QACN,OAAO,CAAC,WAAW;AAAA,QACnB,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,UAAU,YAAY;AAAA,QAC5B;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MACA,QAAQ;AAAA,QACP,EAAE,MAAM,wCAAoB,KAAK;AAAA,QACjC,EAAE,MAAM,wCAAoB,QAAQ,aAAa,QAAQ;AAAA,MAC1D;AAAA,MACA,SAAS,CAAC,wCAAoB,IAAI;AAAA,MAClC,aAAa;AAAA,QACZ;AAAA,UACC,MAAM;AAAA,UACN,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,iBAAiB;AAAA,QAChB,wBAAwB;AAAA,QACxB,SACC;AAAA,MACF;AAAA,MACA,YAAY;AAAA,QACX;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,kBAAkB;AAAA,UAClB,SAAS;AAAA,UACT,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,UAAU;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,SAAS,CAAC,KAAK;AAAA,YAChB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,SAAS;AAAA,UACT,aAAa;AAAA,YACZ,MAAM;AAAA,UACP;AAAA,UACA,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,SAAS,CAAC,KAAK;AAAA,YAChB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aACC;AAAA,UACD,UAAU;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,SAAS,CAAC,KAAK;AAAA,YAChB;AAAA,UACD;AAAA,UACA,aAAa;AAAA,YACZ,aAAa;AAAA,cACZ,SAAS;AAAA,gBACR,SAAS;AAAA,kBACR,QAAQ;AAAA,kBACR,KAAK;AAAA,gBACN;AAAA,gBACA,QAAQ;AAAA,kBACP,aAAa;AAAA,oBACZ;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,UAAU;AAAA,sBACX;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,MAAM;AAAA,sBACP;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,MAAM;AAAA,wBACN,OAAO;AAAA,sBACR;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,KAAK;AAAA,sBACN;AAAA,oBACD;AAAA,kBACD;AAAA,gBACD;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,UACA,SAAS;AAAA,YACR,MAAM;AAAA,cACL,MAAM;AAAA,cACN,UAAU;AAAA,YACX;AAAA,UACD;AAAA,UACA,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,kBAAkB;AAAA,UAClB,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,SAAS,CAAC,UAAU;AAAA,YACrB;AAAA,UACD;AAAA,UACA,aACC;AAAA,UACD,aAAa;AAAA,YACZ,aAAa;AAAA,cACZ,SAAS;AAAA,gBACR,SAAS;AAAA,kBACR,QAAQ;AAAA,kBACR,SAAS;AAAA,oBACR,eAAe;AAAA,kBAChB;AAAA,kBACA,KAAK;AAAA,gBACN;AAAA,gBACA,QAAQ;AAAA,kBACP,aAAa;AAAA,oBACZ;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,UAAU;AAAA,sBACX;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,MAAM;AAAA,wBACN,OAAO;AAAA,wBAEP,aAAa;AAAA,sBACd;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,MAAM;AAAA,sBACN,YAAY;AAAA,wBACX,KAAK;AAAA,sBACN;AAAA,oBACD;AAAA,kBACD;AAAA,gBACD;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,UACA,SAAS;AAAA,YACR,MAAM;AAAA,cACL,MAAM;AAAA,cACN,UAAU;AAAA,YACX;AAAA,UACD;AAAA,UACA,UAAU;AAAA,UACV,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,CAAC;AAAA,YACf;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,UAAU;AAAA,UACV,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,GAAG;AAAA,YACjB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aACC;AAAA,UACD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,YACZ,aAAa;AAAA,UACd;AAAA,UACA,gBAAgB,EAAE,MAAM,EAAE,gBAAgB,CAAC,WAAW,EAAE,EAAE;AAAA,UAC1D,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,aAAa;AAAA,UACb,aAAa;AAAA,UACb,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa;AAAA,cACb,MAAM;AAAA,YACP;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa;AAAA,cACb,MAAM;AAAA,YACP;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa;AAAA,cACb,MAAM;AAAA,YACP;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,UAAkE;AACvE,UAAM,cAAc,KAAK,QAAQ,EAAE;AACnC,UAAM,QAAQ,UAAM,kCAAkB,MAAM,cAAc,GAAG,KAAK;AAClE,UAAM,cAAc,MAAM,KAAK,eAAe,WAAW;AAEzD,UAAM,QAAQ,KAAK,aAAa;AAChC,UAAM,aAAmC,CAAC;AAE1C,aAAS,YAAY,GAAG,YAAY,MAAM,QAAQ,aAAa;AAC9D,UAAI;AACH,cAAM,QAAQ,KAAK,iBAAiB,QAAQ,SAAS;AACrD,cAAM,cAAc,KAAK,iBAAiB,eAAe,WAAW,EAAE;AACtE,cAAM,cAAc,KAAK,iBAAiB,eAAe,WAAW,CAAC,CAAC;AAItE,cAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAM9D,YAAI,UAAU,QAAW;AACxB,gBAAM,IAAI,uCAAmB,KAAK,QAAQ,GAAG,0CAAgC;AAAA,QAC9E;AAEA,cAAM,EAAE,sBAAsB,eAAe,IAAI,oBAAU,IAAI,sBAAQ;AAEvE,cAAM,SAAS,IAAI,cAAAA,OAAa;AAAA,UAC/B,QAAQ,YAAY;AAAA,UACpB,YAAY,QAAQ,cAAc;AAAA,UAClC,SAAS,QAAQ,WAAW;AAAA,UAC5B,SAAS,QAAQ;AAAA,UACjB;AAAA,QACD,CAAC;AACD,YAAI;AACJ,cAAM,oBAAoC,YAAY,IAAI,CAAC,UAAU,EAAE,MAAM,KAAK,EAAE;AACpF,cAAM,4BAA4B,OAAO,IAAI,wCAA2B,KAAK,CAAC;AAC9E,cAAM,WAAW,CAAC,GAAG,2BAA2B,GAAG,iBAAiB;AAGpE,YAAI,aAAa;AAChB,kBAAQ,IAAI,gDAAwB,EAAE,aAAa,QAAQ,SAAS,KAAK,CAAC;AAE1E,gBAAM,OAAO,KAAK,WAAW,OAAO,aAAa;AAAA,YAChD,OAAO;AAAA,UACR,CAAC;AAAA,QACF,OAAO;AACN,gBAAM,OAAO,KAAK,iBAAiB,QAAQ,WAAW,EAAE;AACxD,gBAAM,eAAe,KAAK,iBAAiB,gBAAgB,WAAW,EAAE;AACxE,gBAAM,QAAQ,KAAK,iBAAiB,SAAS,WAAW,oBAAoB;AAE5E,kBAAQ,MAAM,gDAAwB,gBAAgB;AAAA,YACrD;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,OAAO;AAAA,YACP,SAAS;AAAA,UACV,CAAC;AAAA,QACF;AAEA,cAAM,gBAAgB,4BAAc,kBAAkB;AAAA,UACrD;AAAA,UACA;AAAA,QACD,CAAC;AAED,cAAM,WAAW,MAAM,cAAc,eAAW,iCAAiB,IAAI,CAAC,EAAE,OAAO;AAAA,UAC9E,SAAS;AAAA,UACT,QAAQ,KAAK,yBAAyB;AAAA,UACtC,SAAS,QAAQ,WAAW;AAAA,QAC7B,CAAC;AAED,mBAAW,KAAK,EAAE,MAAM,SAAS,CAAC;AAAA,MACnC,SAAS,OAAO;AACf,YAAI,KAAK,eAAe,GAAG;AAC1B,qBAAW,KAAK,EAAE,MAAM,EAAE,OAAO,MAAM,QAAQ,GAAG,YAAY,EAAE,MAAM,UAAU,EAAE,CAAC;AACnF;AAAA,QACD;AAEA,cAAM;AAAA,MACP;AAAA,IACD;AAEA,WAAO,CAAC,UAAU;AAAA,EACnB;AACD;","names":["OpenAIClient"]}
|
|
@@ -34,7 +34,7 @@ class ChainLlm {
|
|
|
34
34
|
icon: "fa:link",
|
|
35
35
|
iconColor: "black",
|
|
36
36
|
group: ["transform"],
|
|
37
|
-
version: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8],
|
|
37
|
+
version: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9],
|
|
38
38
|
description: "A simple chain to prompt a large language model",
|
|
39
39
|
defaults: {
|
|
40
40
|
name: "Basic LLM Chain",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/chains/ChainLLM/ChainLlm.node.ts"],"sourcesContent":["import type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { NodeApiError, NodeConnectionTypes, NodeOperationError, sleep } from 'n8n-workflow';\n\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\n// Import from centralized module\nimport { formatResponse, getInputs, nodeProperties } from './methods';\nimport { processItem } from './methods/processItem';\nimport {\n\tgetCustomErrorMessage as getCustomOpenAiErrorMessage,\n\tisOpenAiError,\n} from '../../vendors/OpenAi/helpers/error-handling';\n\n/**\n * Basic LLM Chain Node Implementation\n * Allows connecting to language models with optional structured output parsing\n */\nexport class ChainLlm implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Basic LLM Chain',\n\t\tname: 'chainLlm',\n\t\ticon: 'fa:link',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8],\n\t\tdescription: 'A simple chain to prompt a large language model',\n\t\tdefaults: {\n\t\t\tname: 'Basic LLM Chain',\n\t\t\tcolor: '#909298',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: `={{ ((parameter) => { ${getInputs.toString()}; return getInputs(parameter) })($parameter) }}`,\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [],\n\t\tproperties: nodeProperties,\n\t};\n\n\t/**\n\t * Main execution method for the node\n\t */\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Basic LLM Chain');\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\t\tconst outputParser = await getOptionalOutputParser(this);\n\t\t// If the node version is 1.6(and LLM is using `response_format: json_object`) or higher or an output parser is configured,\n\t\t// we unwrap the response and return the object directly as JSON\n\t\tconst shouldUnwrapObjects = this.getNode().typeVersion >= 1.6 || !!outputParser;\n\n\t\tconst batchSize = this.getNodeParameter('batching.batchSize', 0, 5) as number;\n\t\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t\t'batching.delayBetweenBatches',\n\t\t\t0,\n\t\t\t0,\n\t\t) as number;\n\n\t\tif (this.getNode().typeVersion >= 1.7 && batchSize > 1) {\n\t\t\t// Process items in batches\n\t\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\t\tconst batch = items.slice(i, i + batchSize);\n\t\t\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\t\t\treturn await processItem(this, i + batchItemIndex);\n\t\t\t\t});\n\n\t\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\t\tbatchResults.forEach((promiseResult, batchItemIndex) => {\n\t\t\t\t\tconst itemIndex = i + batchItemIndex;\n\t\t\t\t\tif (promiseResult.status === 'rejected') {\n\t\t\t\t\t\tconst error = promiseResult.reason as Error;\n\t\t\t\t\t\t// Handle OpenAI specific rate limit errors\n\t\t\t\t\t\tif (error instanceof NodeApiError && isOpenAiError(error.cause)) {\n\t\t\t\t\t\t\tconst openAiErrorCode: string | undefined = (error.cause as any).error?.code;\n\t\t\t\t\t\t\tif (openAiErrorCode) {\n\t\t\t\t\t\t\t\tconst customMessage = getCustomOpenAiErrorMessage(openAiErrorCode);\n\t\t\t\t\t\t\t\tif (customMessage) {\n\t\t\t\t\t\t\t\t\terror.message = customMessage;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst responses = promiseResult.value;\n\t\t\t\t\tresponses.forEach((response: unknown) => {\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: formatResponse(response, shouldUnwrapObjects),\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Process each input item\n\t\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\t\ttry {\n\t\t\t\t\tconst responses = await processItem(this, itemIndex);\n\n\t\t\t\t\t// Process each response and add to return data\n\t\t\t\t\tresponses.forEach((response) => {\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: formatResponse(response, shouldUnwrapObjects),\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Handle OpenAI specific rate limit errors\n\t\t\t\t\tif (error instanceof NodeApiError && isOpenAiError(error.cause)) {\n\t\t\t\t\t\tconst openAiErrorCode: string | undefined = (error.cause as any).error?.code;\n\t\t\t\t\t\tif (openAiErrorCode) {\n\t\t\t\t\t\t\tconst customMessage = getCustomOpenAiErrorMessage(openAiErrorCode);\n\t\t\t\t\t\t\tif (customMessage) {\n\t\t\t\t\t\t\t\terror.message = customMessage;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Continue on failure if configured\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,0BAA6E;AAE7E,6BAAwC;AAGxC,qBAA0D;AAC1D,yBAA4B;AAC5B,4BAGO;AAMA,MAAM,SAA8B;AAAA,EAApC;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS,CAAC,GAAG,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,GAAG;AAAA,
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/chains/ChainLLM/ChainLlm.node.ts"],"sourcesContent":["import type {\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeType,\n\tINodeTypeDescription,\n} from 'n8n-workflow';\nimport { NodeApiError, NodeConnectionTypes, NodeOperationError, sleep } from 'n8n-workflow';\n\nimport { getOptionalOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\n// Import from centralized module\nimport { formatResponse, getInputs, nodeProperties } from './methods';\nimport { processItem } from './methods/processItem';\nimport {\n\tgetCustomErrorMessage as getCustomOpenAiErrorMessage,\n\tisOpenAiError,\n} from '../../vendors/OpenAi/helpers/error-handling';\n\n/**\n * Basic LLM Chain Node Implementation\n * Allows connecting to language models with optional structured output parsing\n */\nexport class ChainLlm implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Basic LLM Chain',\n\t\tname: 'chainLlm',\n\t\ticon: 'fa:link',\n\t\ticonColor: 'black',\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9],\n\t\tdescription: 'A simple chain to prompt a large language model',\n\t\tdefaults: {\n\t\t\tname: 'Basic LLM Chain',\n\t\t\tcolor: '#909298',\n\t\t},\n\t\tcodex: {\n\t\t\talias: ['LangChain'],\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Chains', 'Root Nodes'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.chainllm/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tinputs: `={{ ((parameter) => { ${getInputs.toString()}; return getInputs(parameter) })($parameter) }}`,\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [],\n\t\tproperties: nodeProperties,\n\t};\n\n\t/**\n\t * Main execution method for the node\n\t */\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tthis.logger.debug('Executing Basic LLM Chain');\n\t\tconst items = this.getInputData();\n\t\tconst returnData: INodeExecutionData[] = [];\n\t\tconst outputParser = await getOptionalOutputParser(this);\n\t\t// If the node version is 1.6(and LLM is using `response_format: json_object`) or higher or an output parser is configured,\n\t\t// we unwrap the response and return the object directly as JSON\n\t\tconst shouldUnwrapObjects = this.getNode().typeVersion >= 1.6 || !!outputParser;\n\n\t\tconst batchSize = this.getNodeParameter('batching.batchSize', 0, 5) as number;\n\t\tconst delayBetweenBatches = this.getNodeParameter(\n\t\t\t'batching.delayBetweenBatches',\n\t\t\t0,\n\t\t\t0,\n\t\t) as number;\n\n\t\tif (this.getNode().typeVersion >= 1.7 && batchSize > 1) {\n\t\t\t// Process items in batches\n\t\t\tfor (let i = 0; i < items.length; i += batchSize) {\n\t\t\t\tconst batch = items.slice(i, i + batchSize);\n\t\t\t\tconst batchPromises = batch.map(async (_item, batchItemIndex) => {\n\t\t\t\t\treturn await processItem(this, i + batchItemIndex);\n\t\t\t\t});\n\n\t\t\t\tconst batchResults = await Promise.allSettled(batchPromises);\n\n\t\t\t\tbatchResults.forEach((promiseResult, batchItemIndex) => {\n\t\t\t\t\tconst itemIndex = i + batchItemIndex;\n\t\t\t\t\tif (promiseResult.status === 'rejected') {\n\t\t\t\t\t\tconst error = promiseResult.reason as Error;\n\t\t\t\t\t\t// Handle OpenAI specific rate limit errors\n\t\t\t\t\t\tif (error instanceof NodeApiError && isOpenAiError(error.cause)) {\n\t\t\t\t\t\t\tconst openAiErrorCode: string | undefined = (error.cause as any).error?.code;\n\t\t\t\t\t\t\tif (openAiErrorCode) {\n\t\t\t\t\t\t\t\tconst customMessage = getCustomOpenAiErrorMessage(openAiErrorCode);\n\t\t\t\t\t\t\t\tif (customMessage) {\n\t\t\t\t\t\t\t\t\terror.message = customMessage;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\t\tjson: { error: error.message },\n\t\t\t\t\t\t\t\tpairedItem: { item: itemIndex },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthrow new NodeOperationError(this.getNode(), error);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst responses = promiseResult.value;\n\t\t\t\t\tresponses.forEach((response: unknown) => {\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: formatResponse(response, shouldUnwrapObjects),\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tif (i + batchSize < items.length && delayBetweenBatches > 0) {\n\t\t\t\t\tawait sleep(delayBetweenBatches);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\t// Process each input item\n\t\t\tfor (let itemIndex = 0; itemIndex < items.length; itemIndex++) {\n\t\t\t\ttry {\n\t\t\t\t\tconst responses = await processItem(this, itemIndex);\n\n\t\t\t\t\t// Process each response and add to return data\n\t\t\t\t\tresponses.forEach((response) => {\n\t\t\t\t\t\treturnData.push({\n\t\t\t\t\t\t\tjson: formatResponse(response, shouldUnwrapObjects),\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t} catch (error) {\n\t\t\t\t\t// Handle OpenAI specific rate limit errors\n\t\t\t\t\tif (error instanceof NodeApiError && isOpenAiError(error.cause)) {\n\t\t\t\t\t\tconst openAiErrorCode: string | undefined = (error.cause as any).error?.code;\n\t\t\t\t\t\tif (openAiErrorCode) {\n\t\t\t\t\t\t\tconst customMessage = getCustomOpenAiErrorMessage(openAiErrorCode);\n\t\t\t\t\t\t\tif (customMessage) {\n\t\t\t\t\t\t\t\terror.message = customMessage;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Continue on failure if configured\n\t\t\t\t\tif (this.continueOnFail()) {\n\t\t\t\t\t\treturnData.push({ json: { error: error.message }, pairedItem: { item: itemIndex } });\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn [returnData];\n\t}\n}\n"],"mappings":"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","names":["getCustomOpenAiErrorMessage"]}
|
|
@@ -27,6 +27,7 @@ __export(chainExecutor_exports, {
|
|
|
27
27
|
});
|
|
28
28
|
module.exports = __toCommonJS(chainExecutor_exports);
|
|
29
29
|
var import_output_parsers = require("@langchain/core/output_parsers");
|
|
30
|
+
var import_helpers = require("../../../../utils/helpers");
|
|
30
31
|
var import_tracing = require("../../../../utils/tracing");
|
|
31
32
|
var import_promptUtils = require("./promptUtils");
|
|
32
33
|
class NaiveJsonOutputParser extends import_output_parsers.JsonOutputParser {
|
|
@@ -67,23 +68,30 @@ async function executeSimpleChain({
|
|
|
67
68
|
context,
|
|
68
69
|
llm,
|
|
69
70
|
query,
|
|
70
|
-
prompt
|
|
71
|
-
fallbackLlm
|
|
71
|
+
prompt
|
|
72
72
|
}) {
|
|
73
73
|
const outputParser = getOutputParserForLLM(llm);
|
|
74
|
-
|
|
75
|
-
if (fallbackLlm) {
|
|
76
|
-
model = llm.withFallbacks([fallbackLlm]);
|
|
77
|
-
} else {
|
|
78
|
-
model = llm;
|
|
79
|
-
}
|
|
80
|
-
const chain = prompt.pipe(model).pipe(outputParser).withConfig((0, import_tracing.getTracingConfig)(context));
|
|
74
|
+
const chain = prompt.pipe(llm).pipe(outputParser).withConfig((0, import_tracing.getTracingConfig)(context));
|
|
81
75
|
const response = await chain.invoke({
|
|
82
76
|
query,
|
|
83
77
|
signal: context.getExecutionCancelSignal()
|
|
84
78
|
});
|
|
85
79
|
return [response];
|
|
86
80
|
}
|
|
81
|
+
function withBuiltInTools(llm) {
|
|
82
|
+
const modelTools = llm.metadata?.tools ?? [];
|
|
83
|
+
if (modelTools.length && (0, import_helpers.isChatInstance)(llm) && llm.bindTools) {
|
|
84
|
+
return llm.bindTools(modelTools);
|
|
85
|
+
}
|
|
86
|
+
return llm;
|
|
87
|
+
}
|
|
88
|
+
function prepareLlm(llm, fallbackLlm) {
|
|
89
|
+
const mainLlm = withBuiltInTools(llm);
|
|
90
|
+
if (fallbackLlm) {
|
|
91
|
+
return mainLlm.withFallbacks([withBuiltInTools(fallbackLlm)]);
|
|
92
|
+
}
|
|
93
|
+
return mainLlm;
|
|
94
|
+
}
|
|
87
95
|
async function executeChain({
|
|
88
96
|
context,
|
|
89
97
|
itemIndex,
|
|
@@ -93,6 +101,8 @@ async function executeChain({
|
|
|
93
101
|
messages,
|
|
94
102
|
fallbackLlm
|
|
95
103
|
}) {
|
|
104
|
+
const version = context.getNode().typeVersion;
|
|
105
|
+
const model = prepareLlm(llm, fallbackLlm);
|
|
96
106
|
if (!outputParser) {
|
|
97
107
|
const promptTemplate = await (0, import_promptUtils.createPromptTemplate)({
|
|
98
108
|
context,
|
|
@@ -103,10 +113,9 @@ async function executeChain({
|
|
|
103
113
|
});
|
|
104
114
|
return await executeSimpleChain({
|
|
105
115
|
context,
|
|
106
|
-
llm,
|
|
116
|
+
llm: model,
|
|
107
117
|
query,
|
|
108
|
-
prompt: promptTemplate
|
|
109
|
-
fallbackLlm
|
|
118
|
+
prompt: promptTemplate
|
|
110
119
|
});
|
|
111
120
|
}
|
|
112
121
|
const formatInstructions = outputParser.getFormatInstructions();
|
|
@@ -118,7 +127,12 @@ async function executeChain({
|
|
|
118
127
|
formatInstructions,
|
|
119
128
|
query
|
|
120
129
|
});
|
|
121
|
-
|
|
130
|
+
let chain;
|
|
131
|
+
if (version >= 1.9) {
|
|
132
|
+
chain = promptWithInstructions.pipe(model).pipe((0, import_promptUtils.getAgentStepsParser)(outputParser)).withConfig((0, import_tracing.getTracingConfig)(context));
|
|
133
|
+
} else {
|
|
134
|
+
chain = promptWithInstructions.pipe(model).pipe(outputParser).withConfig((0, import_tracing.getTracingConfig)(context));
|
|
135
|
+
}
|
|
122
136
|
const response = await chain.invoke({ query }, { signal: context.getExecutionCancelSignal() });
|
|
123
137
|
return Array.isArray(response) ? response : [response];
|
|
124
138
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../nodes/chains/ChainLLM/methods/chainExecutor.ts"],"sourcesContent":["import type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { BaseLLMOutputParser } from '@langchain/core/output_parsers';\nimport { JsonOutputParser, StringOutputParser } from '@langchain/core/output_parsers';\nimport type { ChatPromptTemplate, PromptTemplate } from '@langchain/core/prompts';\nimport type { IExecuteFunctions } from 'n8n-workflow';\n\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { createPromptTemplate } from './promptUtils';\nimport type { ChainExecutionParams } from './types';\n\nexport class NaiveJsonOutputParser<\n\tT extends Record<string, any> = Record<string, any>,\n> extends JsonOutputParser<T> {\n\tasync parse(text: string): Promise<T> {\n\t\t// First try direct JSON parsing\n\t\ttry {\n\t\t\tconst directParsed = JSON.parse(text);\n\t\t\treturn directParsed as T;\n\t\t} catch (e) {\n\t\t\t// If fails, fall back to JsonOutputParser parser\n\t\t\treturn await super.parse(text);\n\t\t}\n\t}\n}\n\n/**\n * Type guard to check if the LLM has a modelKwargs property(OpenAI)\n */\nexport function isModelWithResponseFormat(\n\tllm: BaseLanguageModel,\n): llm is BaseLanguageModel & { modelKwargs: { response_format: { type: string } } } {\n\treturn (\n\t\t'modelKwargs' in llm &&\n\t\t!!llm.modelKwargs &&\n\t\ttypeof llm.modelKwargs === 'object' &&\n\t\t'response_format' in llm.modelKwargs\n\t);\n}\n\nexport function isModelInThinkingMode(\n\tllm: BaseLanguageModel,\n): llm is BaseLanguageModel & { lc_kwargs: { invocationKwargs: { thinking: { type: string } } } } {\n\treturn (\n\t\t'lc_kwargs' in llm &&\n\t\t'invocationKwargs' in llm.lc_kwargs &&\n\t\ttypeof llm.lc_kwargs.invocationKwargs === 'object' &&\n\t\t'thinking' in llm.lc_kwargs.invocationKwargs &&\n\t\tllm.lc_kwargs.invocationKwargs.thinking.type === 'enabled'\n\t);\n}\n\n/**\n * Type guard to check if the LLM has a format property(Ollama)\n */\nexport function isModelWithFormat(\n\tllm: BaseLanguageModel,\n): llm is BaseLanguageModel & { format: string } {\n\treturn 'format' in llm && typeof llm.format !== 'undefined';\n}\n\n/**\n * Determines if an LLM is configured to output JSON and returns the appropriate output parser\n */\nexport function getOutputParserForLLM(\n\tllm: BaseLanguageModel,\n): BaseLLMOutputParser<string | Record<string, unknown>> {\n\tif (isModelWithResponseFormat(llm) && llm.modelKwargs?.response_format?.type === 'json_object') {\n\t\treturn new NaiveJsonOutputParser();\n\t}\n\n\tif (isModelWithFormat(llm) && llm.format === 'json') {\n\t\treturn new NaiveJsonOutputParser();\n\t}\n\n\tif (isModelInThinkingMode(llm)) {\n\t\treturn new NaiveJsonOutputParser();\n\t}\n\n\t// For example Mistral's Magistral models (LmChatMistralCloud node)\n\tif (llm.metadata?.output_format === 'json') {\n\t\treturn new NaiveJsonOutputParser();\n\t}\n\n\treturn new StringOutputParser();\n}\n\n/**\n * Creates a simple chain for LLMs without output parsers\n */\nasync function executeSimpleChain({\n\tcontext,\n\tllm,\n\tquery,\n\tprompt,\n
|
|
1
|
+
{"version":3,"sources":["../../../../../nodes/chains/ChainLLM/methods/chainExecutor.ts"],"sourcesContent":["import type { Tool } from '@langchain/classic/tools';\nimport type { BaseLanguageModel } from '@langchain/core/language_models/base';\nimport type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport type { BaseLLMOutputParser } from '@langchain/core/output_parsers';\nimport { JsonOutputParser, StringOutputParser } from '@langchain/core/output_parsers';\nimport type { ChatPromptTemplate, PromptTemplate } from '@langchain/core/prompts';\nimport type { Runnable } from '@langchain/core/runnables';\nimport type { IExecuteFunctions } from 'n8n-workflow';\n\nimport { isChatInstance } from '@utils/helpers';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { createPromptTemplate, getAgentStepsParser } from './promptUtils';\nimport type { ChainExecutionParams } from './types';\n\nexport class NaiveJsonOutputParser<\n\tT extends Record<string, any> = Record<string, any>,\n> extends JsonOutputParser<T> {\n\tasync parse(text: string): Promise<T> {\n\t\t// First try direct JSON parsing\n\t\ttry {\n\t\t\tconst directParsed = JSON.parse(text);\n\t\t\treturn directParsed as T;\n\t\t} catch (e) {\n\t\t\t// If fails, fall back to JsonOutputParser parser\n\t\t\treturn await super.parse(text);\n\t\t}\n\t}\n}\n\n/**\n * Type guard to check if the LLM has a modelKwargs property(OpenAI)\n */\nexport function isModelWithResponseFormat(\n\tllm: BaseLanguageModel,\n): llm is BaseLanguageModel & { modelKwargs: { response_format: { type: string } } } {\n\treturn (\n\t\t'modelKwargs' in llm &&\n\t\t!!llm.modelKwargs &&\n\t\ttypeof llm.modelKwargs === 'object' &&\n\t\t'response_format' in llm.modelKwargs\n\t);\n}\n\nexport function isModelInThinkingMode(\n\tllm: BaseLanguageModel,\n): llm is BaseLanguageModel & { lc_kwargs: { invocationKwargs: { thinking: { type: string } } } } {\n\treturn (\n\t\t'lc_kwargs' in llm &&\n\t\t'invocationKwargs' in llm.lc_kwargs &&\n\t\ttypeof llm.lc_kwargs.invocationKwargs === 'object' &&\n\t\t'thinking' in llm.lc_kwargs.invocationKwargs &&\n\t\tllm.lc_kwargs.invocationKwargs.thinking.type === 'enabled'\n\t);\n}\n\n/**\n * Type guard to check if the LLM has a format property(Ollama)\n */\nexport function isModelWithFormat(\n\tllm: BaseLanguageModel,\n): llm is BaseLanguageModel & { format: string } {\n\treturn 'format' in llm && typeof llm.format !== 'undefined';\n}\n\n/**\n * Determines if an LLM is configured to output JSON and returns the appropriate output parser\n */\nexport function getOutputParserForLLM(\n\tllm: BaseChatModel | BaseLanguageModel,\n): BaseLLMOutputParser<string | Record<string, unknown>> {\n\tif (isModelWithResponseFormat(llm) && llm.modelKwargs?.response_format?.type === 'json_object') {\n\t\treturn new NaiveJsonOutputParser();\n\t}\n\n\tif (isModelWithFormat(llm) && llm.format === 'json') {\n\t\treturn new NaiveJsonOutputParser();\n\t}\n\n\tif (isModelInThinkingMode(llm)) {\n\t\treturn new NaiveJsonOutputParser();\n\t}\n\n\t// For example Mistral's Magistral models (LmChatMistralCloud node)\n\tif (llm.metadata?.output_format === 'json') {\n\t\treturn new NaiveJsonOutputParser();\n\t}\n\n\treturn new StringOutputParser();\n}\n\n/**\n * Creates a simple chain for LLMs without output parsers\n */\nasync function executeSimpleChain({\n\tcontext,\n\tllm,\n\tquery,\n\tprompt,\n}: {\n\tcontext: IExecuteFunctions;\n\tllm: BaseChatModel | BaseLanguageModel;\n\tquery: string;\n\tprompt: ChatPromptTemplate | PromptTemplate;\n}) {\n\tconst outputParser = getOutputParserForLLM(llm);\n\n\tconst chain = prompt.pipe(llm).pipe(outputParser).withConfig(getTracingConfig(context));\n\n\t// Execute the chain\n\tconst response = await chain.invoke({\n\t\tquery,\n\t\tsignal: context.getExecutionCancelSignal(),\n\t});\n\n\t// Ensure response is always returned as an array\n\treturn [response];\n}\n\n// Some models nodes, like OpenAI, can define built-in tools in their metadata\nfunction withBuiltInTools(llm: BaseChatModel | BaseLanguageModel) {\n\tconst modelTools = (llm.metadata?.tools as Tool[]) ?? [];\n\tif (modelTools.length && isChatInstance(llm) && llm.bindTools) {\n\t\treturn llm.bindTools(modelTools);\n\t}\n\treturn llm;\n}\n\nfunction prepareLlm(\n\tllm: BaseLanguageModel | BaseChatModel,\n\tfallbackLlm?: BaseLanguageModel | BaseChatModel | null,\n) {\n\tconst mainLlm = withBuiltInTools(llm);\n\tif (fallbackLlm) {\n\t\treturn mainLlm.withFallbacks([withBuiltInTools(fallbackLlm)]);\n\t}\n\treturn mainLlm;\n}\n\n/**\n * Creates and executes an LLM chain with the given prompt and optional output parsers\n */\nexport async function executeChain({\n\tcontext,\n\titemIndex,\n\tquery,\n\tllm,\n\toutputParser,\n\tmessages,\n\tfallbackLlm,\n}: ChainExecutionParams): Promise<unknown[]> {\n\tconst version = context.getNode().typeVersion;\n\tconst model = prepareLlm(llm, fallbackLlm) as BaseChatModel | BaseLanguageModel;\n\t// If no output parsers provided, use a simple chain with basic prompt template\n\tif (!outputParser) {\n\t\tconst promptTemplate = await createPromptTemplate({\n\t\t\tcontext,\n\t\t\titemIndex,\n\t\t\tllm,\n\t\t\tmessages,\n\t\t\tquery,\n\t\t});\n\n\t\treturn await executeSimpleChain({\n\t\t\tcontext,\n\t\t\tllm: model,\n\t\t\tquery,\n\t\t\tprompt: promptTemplate,\n\t\t});\n\t}\n\n\tconst formatInstructions = outputParser.getFormatInstructions();\n\n\t// Create a prompt template with format instructions\n\tconst promptWithInstructions = await createPromptTemplate({\n\t\tcontext,\n\t\titemIndex,\n\t\tllm,\n\t\tmessages,\n\t\tformatInstructions,\n\t\tquery,\n\t});\n\n\tlet chain: Runnable<{ query: string }>;\n\tif (version >= 1.9) {\n\t\t// use getAgentStepsParser to have more robust output parsing\n\t\tchain = promptWithInstructions\n\t\t\t.pipe(model)\n\t\t\t.pipe(getAgentStepsParser(outputParser))\n\t\t\t.withConfig(getTracingConfig(context));\n\t} else {\n\t\tchain = promptWithInstructions\n\t\t\t.pipe(model)\n\t\t\t.pipe(outputParser)\n\t\t\t.withConfig(getTracingConfig(context));\n\t}\n\n\tconst response = await chain.invoke({ query }, { signal: context.getExecutionCancelSignal() });\n\n\t// Ensure response is always returned as an array\n\t// eslint-disable-next-line @typescript-eslint/no-unsafe-return\n\treturn Array.isArray(response) ? response : [response];\n}\n"],"mappings":"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","names":[]}
|
|
@@ -18,7 +18,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
var promptUtils_exports = {};
|
|
20
20
|
__export(promptUtils_exports, {
|
|
21
|
-
createPromptTemplate: () => createPromptTemplate
|
|
21
|
+
createPromptTemplate: () => createPromptTemplate,
|
|
22
|
+
getAgentStepsParser: () => getAgentStepsParser
|
|
22
23
|
});
|
|
23
24
|
module.exports = __toCommonJS(promptUtils_exports);
|
|
24
25
|
var import_messages = require("@langchain/core/messages");
|
|
@@ -102,8 +103,40 @@ async function createPromptTemplate({
|
|
|
102
103
|
query
|
|
103
104
|
});
|
|
104
105
|
}
|
|
106
|
+
const isMessage = (message) => {
|
|
107
|
+
return message instanceof import_messages.BaseMessage;
|
|
108
|
+
};
|
|
109
|
+
const isAgentFinish = (value) => {
|
|
110
|
+
return typeof value === "object" && value !== null && "returnValues" in value;
|
|
111
|
+
};
|
|
112
|
+
const getAgentStepsParser = (outputParser) => async (steps) => {
|
|
113
|
+
if (typeof steps === "string") {
|
|
114
|
+
return await outputParser.parse(steps);
|
|
115
|
+
}
|
|
116
|
+
if (Array.isArray(steps)) {
|
|
117
|
+
const responseParserTool = steps.find((step) => step.tool === "format_final_json_response");
|
|
118
|
+
if (responseParserTool) {
|
|
119
|
+
const toolInput = responseParserTool.toolInput;
|
|
120
|
+
const parserInput = toolInput instanceof Object ? JSON.stringify(toolInput) : toolInput;
|
|
121
|
+
const parsedOutput = await outputParser.parse(parserInput);
|
|
122
|
+
return parsedOutput;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (typeof steps === "object" && isMessage(steps)) {
|
|
126
|
+
const output = steps.text;
|
|
127
|
+
const parsedOutput = await outputParser.parse(output);
|
|
128
|
+
return parsedOutput;
|
|
129
|
+
}
|
|
130
|
+
if (isAgentFinish(steps)) {
|
|
131
|
+
const returnValues = steps.returnValues;
|
|
132
|
+
const parsedOutput = await outputParser.parse(JSON.stringify(returnValues));
|
|
133
|
+
return parsedOutput;
|
|
134
|
+
}
|
|
135
|
+
throw new Error("Failed to parse agent steps");
|
|
136
|
+
};
|
|
105
137
|
// Annotate the CommonJS export names for ESM import in node:
|
|
106
138
|
0 && (module.exports = {
|
|
107
|
-
createPromptTemplate
|
|
139
|
+
createPromptTemplate,
|
|
140
|
+
getAgentStepsParser
|
|
108
141
|
});
|
|
109
142
|
//# sourceMappingURL=promptUtils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../nodes/chains/ChainLLM/methods/promptUtils.ts"],"sourcesContent":["import { HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessagePromptTemplateLike } from '@langchain/core/prompts';\nimport {\n\tAIMessagePromptTemplate,\n\
|
|
1
|
+
{"version":3,"sources":["../../../../../nodes/chains/ChainLLM/methods/promptUtils.ts"],"sourcesContent":["import type { AgentAction, AgentFinish } from '@langchain/core/agents';\nimport { BaseMessage, HumanMessage } from '@langchain/core/messages';\nimport type { BaseMessagePromptTemplateLike } from '@langchain/core/prompts';\nimport {\n\tAIMessagePromptTemplate,\n\tChatPromptTemplate,\n\tHumanMessagePromptTemplate,\n\tPromptTemplate,\n\tSystemMessagePromptTemplate,\n} from '@langchain/core/prompts';\nimport type { IExecuteFunctions } from 'n8n-workflow';\nimport { OperationalError } from 'n8n-workflow';\n\nimport { isChatInstance } from '@utils/helpers';\nimport type { N8nOutputParser } from '@utils/output_parsers/N8nOutputParser';\n\nimport { createImageMessage } from './imageUtils';\nimport type { MessageTemplate, PromptParams } from './types';\n\n/**\n * Creates a basic query template that may include format instructions\n */\nfunction buildQueryTemplate(formatInstructions?: string): PromptTemplate {\n\treturn new PromptTemplate({\n\t\ttemplate: `{query}${formatInstructions ? '\\n{formatInstructions}' : ''}`,\n\t\tinputVariables: ['query'],\n\t\tpartialVariables: formatInstructions ? { formatInstructions } : undefined,\n\t});\n}\n\n/**\n * Process an array of message templates into LangChain message objects\n */\nasync function processMessageTemplates({\n\tcontext,\n\titemIndex,\n\tmessages,\n}: {\n\tcontext: IExecuteFunctions;\n\titemIndex: number;\n\tmessages: MessageTemplate[];\n}): Promise<BaseMessagePromptTemplateLike[]> {\n\treturn await Promise.all(\n\t\tmessages.map(async (message) => {\n\t\t\t// Find the appropriate message class based on type\n\t\t\tconst messageClass = [\n\t\t\t\tSystemMessagePromptTemplate,\n\t\t\t\tAIMessagePromptTemplate,\n\t\t\t\tHumanMessagePromptTemplate,\n\t\t\t].find((m) => m.lc_name() === message.type);\n\n\t\t\tif (!messageClass) {\n\t\t\t\tthrow new OperationalError('Invalid message type', {\n\t\t\t\t\textra: { messageType: message.type },\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Handle image messages specially for human messages\n\t\t\tif (messageClass === HumanMessagePromptTemplate && message.messageType !== 'text') {\n\t\t\t\treturn await createImageMessage({ context, itemIndex, message });\n\t\t\t}\n\n\t\t\t// Process text messages\n\t\t\t// Escape curly braces in the message to prevent LangChain from treating them as variables\n\t\t\treturn messageClass.fromTemplate(\n\t\t\t\t(message.message || '').replace(/[{}]/g, (match) => match + match),\n\t\t\t);\n\t\t}),\n\t);\n}\n\n/**\n * Finalizes the prompt template by adding or updating the query in the message chain\n */\nasync function finalizePromptTemplate({\n\tparsedMessages,\n\tqueryTemplate,\n\tquery,\n}: {\n\tparsedMessages: BaseMessagePromptTemplateLike[];\n\tqueryTemplate: PromptTemplate;\n\tquery?: string;\n}): Promise<ChatPromptTemplate> {\n\t// Check if the last message is a human message with multi-content array\n\tconst lastMessage = parsedMessages[parsedMessages.length - 1];\n\n\tif (lastMessage instanceof HumanMessage && Array.isArray(lastMessage.content)) {\n\t\t// Add the query to the existing human message content\n\t\tconst humanMessage = new HumanMessagePromptTemplate(queryTemplate);\n\n\t\t// Format the message with the query and add the content synchronously\n\t\tconst formattedMessage = await humanMessage.format({ query });\n\n\t\t// Create a new array with the existing content plus the new item\n\t\tif (Array.isArray(lastMessage.content)) {\n\t\t\t// Clone the current content array and add the new item\n\t\t\tconst updatedContent = [\n\t\t\t\t...lastMessage.content,\n\t\t\t\t{\n\t\t\t\t\ttext: formattedMessage.content.toString(),\n\t\t\t\t\ttype: 'text',\n\t\t\t\t},\n\t\t\t];\n\n\t\t\t// Replace the content with the updated array\n\t\t\tlastMessage.content = updatedContent;\n\t\t}\n\t} else {\n\t\t// Otherwise, add a new human message with the query\n\t\tparsedMessages.push(new HumanMessagePromptTemplate(queryTemplate));\n\t}\n\n\treturn ChatPromptTemplate.fromMessages(parsedMessages);\n}\n\n/**\n * Builds the appropriate prompt template based on model type (chat vs completion)\n * and provided messages\n */\nexport async function createPromptTemplate({\n\tcontext,\n\titemIndex,\n\tllm,\n\tmessages,\n\tformatInstructions,\n\tquery,\n}: PromptParams) {\n\t// Create base query template\n\tconst queryTemplate = buildQueryTemplate(formatInstructions);\n\n\t// For non-chat models, just return the query template\n\tif (!isChatInstance(llm)) {\n\t\treturn queryTemplate;\n\t}\n\n\t// For chat models, process the messages if provided\n\tconst parsedMessages = messages?.length\n\t\t? await processMessageTemplates({ context, itemIndex, messages })\n\t\t: [];\n\n\t// Add or update the query in the message chain\n\treturn await finalizePromptTemplate({\n\t\tparsedMessages,\n\t\tqueryTemplate,\n\t\tquery,\n\t});\n}\n\nconst isMessage = (message: unknown): message is BaseMessage => {\n\treturn message instanceof BaseMessage;\n};\n\nconst isAgentFinish = (value: unknown): value is AgentFinish => {\n\treturn typeof value === 'object' && value !== null && 'returnValues' in value;\n};\n\nexport const getAgentStepsParser =\n\t(outputParser: N8nOutputParser) =>\n\tasync (\n\t\tsteps: AgentFinish | BaseMessage | AgentAction[] | string,\n\t): Promise<string | Record<string, unknown>> => {\n\t\tif (typeof steps === 'string') {\n\t\t\treturn (await outputParser.parse(steps)) as Record<string, unknown>;\n\t\t}\n\n\t\t// Check if the steps contain the 'format_final_json_response' tool invocation.\n\t\tif (Array.isArray(steps)) {\n\t\t\tconst responseParserTool = steps.find((step) => step.tool === 'format_final_json_response');\n\t\t\tif (responseParserTool) {\n\t\t\t\tconst toolInput = responseParserTool.toolInput;\n\t\t\t\t// Ensure the tool input is a string\n\t\t\t\tconst parserInput = toolInput instanceof Object ? JSON.stringify(toolInput) : toolInput;\n\t\t\t\tconst parsedOutput = (await outputParser.parse(parserInput)) as Record<string, unknown>;\n\t\t\t\treturn parsedOutput;\n\t\t\t}\n\t\t}\n\n\t\tif (typeof steps === 'object' && isMessage(steps)) {\n\t\t\tconst output = steps.text;\n\n\t\t\tconst parsedOutput = (await outputParser.parse(output)) as Record<string, unknown>;\n\t\t\treturn parsedOutput;\n\t\t}\n\n\t\tif (isAgentFinish(steps)) {\n\t\t\tconst returnValues = steps.returnValues;\n\t\t\tconst parsedOutput = (await outputParser.parse(JSON.stringify(returnValues))) as Record<\n\t\t\t\tstring,\n\t\t\t\tunknown\n\t\t\t>;\n\t\t\treturn parsedOutput;\n\t\t}\n\n\t\tthrow new Error('Failed to parse agent steps');\n\t};\n"],"mappings":"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","names":[]}
|
|
@@ -26,6 +26,8 @@ var import_n8n_workflow = require("n8n-workflow");
|
|
|
26
26
|
var import_logWrapper = require("../../../utils/logWrapper");
|
|
27
27
|
var import_httpProxyAgent = require("../../../utils/httpProxyAgent");
|
|
28
28
|
var import_sharedFields = require("../../../utils/sharedFields");
|
|
29
|
+
var import_di = require("@n8n/di");
|
|
30
|
+
var import_config = require("@n8n/config");
|
|
29
31
|
const modelParameter = {
|
|
30
32
|
displayName: "Model",
|
|
31
33
|
name: "model",
|
|
@@ -240,7 +242,10 @@ class EmbeddingsOpenAi {
|
|
|
240
242
|
if (options.timeout === -1) {
|
|
241
243
|
options.timeout = void 0;
|
|
242
244
|
}
|
|
243
|
-
const
|
|
245
|
+
const { openAiDefaultHeaders: defaultHeaders } = import_di.Container.get(import_config.AiConfig);
|
|
246
|
+
const configuration = {
|
|
247
|
+
defaultHeaders
|
|
248
|
+
};
|
|
244
249
|
if (options.baseURL) {
|
|
245
250
|
configuration.baseURL = options.baseURL;
|
|
246
251
|
} else if (credentials.url) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.ts"],"sourcesContent":["import { OpenAIEmbeddings } from '@langchain/openai';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype SupplyData,\n\ttype ISupplyDataFunctions,\n\ttype INodeProperties,\n} from 'n8n-workflow';\nimport type { ClientOptions } from 'openai';\n\nimport { logWrapper } from '@utils/logWrapper';\n\nimport { getProxyAgent } from '@utils/httpProxyAgent';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nconst modelParameter: INodeProperties = {\n\tdisplayName: 'Model',\n\tname: 'model',\n\ttype: 'options',\n\tdescription:\n\t\t'The model which will generate the embeddings. <a href=\"https://platform.openai.com/docs/models/overview\">Learn more</a>.',\n\ttypeOptions: {\n\t\tloadOptions: {\n\t\t\trouting: {\n\t\t\t\trequest: {\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || $credentials?.url?.split(\"/\").slice(-1).pop() || \"v1\" }}/models',\n\t\t\t\t},\n\t\t\t\toutput: {\n\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t// If the baseURL is not set or is set to api.openai.com, include only embedding models\n\t\t\t\t\t\t\t\tpass: `={{\n\t\t\t\t\t\t\t\t\t($parameter.options?.baseURL && !$parameter.options?.baseURL?.startsWith('https://api.openai.com/')) ||\n\t\t\t\t\t\t\t\t\t($credentials?.url && !$credentials.url.startsWith('https://api.openai.com/')) ||\n\t\t\t\t\t\t\t\t\t$responseItem.id.includes('embed')\n\t\t\t\t\t\t\t\t}}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\tname: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\trouting: {\n\t\tsend: {\n\t\t\ttype: 'body',\n\t\t\tproperty: 'model',\n\t\t},\n\t},\n\tdefault: 'text-embedding-3-small',\n};\n\nexport class EmbeddingsOpenAi implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Embeddings OpenAI',\n\t\tname: 'embeddingsOpenAi',\n\t\ticon: { light: 'file:openAiLight.svg', dark: 'file:openAiLight.dark.svg' },\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'openAiApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2],\n\t\tdescription: 'Use Embeddings OpenAI',\n\t\tdefaults: {\n\t\t\tname: 'Embeddings OpenAI',\n\t\t},\n\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Embeddings'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.embeddingsopenai/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\n\t\tinputs: [],\n\n\t\toutputs: [NodeConnectionTypes.AiEmbedding],\n\t\toutputNames: ['Embeddings'],\n\t\trequestDefaults: {\n\t\t\tignoreHttpStatusErrors: true,\n\t\t\tbaseURL:\n\t\t\t\t'={{ $parameter.options?.baseURL?.split(\"/\").slice(0,-1).join(\"/\") || $credentials.url?.split(\"/\").slice(0,-1).join(\"/\") || \"https://api.openai.com\" }}',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiVectorStore]),\n\t\t\t{\n\t\t\t\t...modelParameter,\n\t\t\t\tdefault: 'text-embedding-ada-002',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...modelParameter,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Dimensions',\n\t\t\t\t\t\tname: 'dimensions',\n\t\t\t\t\t\tdefault: undefined,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The number of dimensions the resulting output embeddings should have. Only supported in text-embedding-3 and later models.',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '256',\n\t\t\t\t\t\t\t\tvalue: 256,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '512',\n\t\t\t\t\t\t\t\tvalue: 512,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '1024',\n\t\t\t\t\t\t\t\tvalue: 1024,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '1536',\n\t\t\t\t\t\t\t\tvalue: 1536,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '3072',\n\t\t\t\t\t\t\t\tvalue: 3072,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Base URL',\n\t\t\t\t\t\tname: 'baseURL',\n\t\t\t\t\t\tdefault: 'https://api.openai.com/v1',\n\t\t\t\t\t\tdescription: 'Override the default base URL for the API',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Batch Size',\n\t\t\t\t\t\tname: 'batchSize',\n\t\t\t\t\t\tdefault: 512,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2048 },\n\t\t\t\t\t\tdescription: 'Maximum number of documents to send in each request',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Strip New Lines',\n\t\t\t\t\t\tname: 'stripNewLines',\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescription: 'Whether to strip new lines from the input text',\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Maximum amount of time a request is allowed to take in seconds. Set to -1 for no timeout.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Encoding Format',\n\t\t\t\t\t\tname: 'encodingFormat',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\tdescription: 'The format to return the embeddings in',\n\t\t\t\t\t\tdefault: undefined,\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Float',\n\t\t\t\t\t\t\t\tvalue: 'float',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Base64',\n\t\t\t\t\t\t\t\tvalue: 'base64',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tthis.logger.debug('Supply data for embeddings');\n\t\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tbaseURL?: string;\n\t\t\tbatchSize?: number;\n\t\t\tstripNewLines?: boolean;\n\t\t\ttimeout?: number;\n\t\t\tdimensions?: number | undefined;\n\t\t\tencodingFormat?: 'float' | 'base64' | undefined;\n\t\t};\n\n\t\tif (options.timeout === -1) {\n\t\t\toptions.timeout = undefined;\n\t\t}\n\n\t\tconst configuration: ClientOptions = {};\n\t\tif (options.baseURL) {\n\t\t\tconfiguration.baseURL = options.baseURL;\n\t\t} else if (credentials.url) {\n\t\t\tconfiguration.baseURL = credentials.url as string;\n\t\t}\n\n\t\tif (configuration.baseURL) {\n\t\t\tconfiguration.fetchOptions = {\n\t\t\t\tdispatcher: getProxyAgent(configuration.baseURL ?? 'https://api.openai.com/v1'),\n\t\t\t};\n\t\t}\n\n\t\tconst embeddings = new OpenAIEmbeddings({\n\t\t\tmodel: this.getNodeParameter('model', itemIndex, 'text-embedding-3-small') as string,\n\t\t\tapiKey: credentials.apiKey as string,\n\t\t\t...options,\n\t\t\tconfiguration,\n\t\t});\n\n\t\treturn {\n\t\t\tresponse: logWrapper(embeddings, this),\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/embeddings/EmbeddingsOpenAI/EmbeddingsOpenAi.node.ts"],"sourcesContent":["import { OpenAIEmbeddings } from '@langchain/openai';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype SupplyData,\n\ttype ISupplyDataFunctions,\n\ttype INodeProperties,\n} from 'n8n-workflow';\nimport type { ClientOptions } from 'openai';\n\nimport { logWrapper } from '@utils/logWrapper';\n\nimport { getProxyAgent } from '@utils/httpProxyAgent';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\nimport { Container } from '@n8n/di';\nimport { AiConfig } from '@n8n/config';\n\nconst modelParameter: INodeProperties = {\n\tdisplayName: 'Model',\n\tname: 'model',\n\ttype: 'options',\n\tdescription:\n\t\t'The model which will generate the embeddings. <a href=\"https://platform.openai.com/docs/models/overview\">Learn more</a>.',\n\ttypeOptions: {\n\t\tloadOptions: {\n\t\t\trouting: {\n\t\t\t\trequest: {\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || $credentials?.url?.split(\"/\").slice(-1).pop() || \"v1\" }}/models',\n\t\t\t\t},\n\t\t\t\toutput: {\n\t\t\t\t\tpostReceive: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'rootProperty',\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\tproperty: 'data',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\t// If the baseURL is not set or is set to api.openai.com, include only embedding models\n\t\t\t\t\t\t\t\tpass: `={{\n\t\t\t\t\t\t\t\t\t($parameter.options?.baseURL && !$parameter.options?.baseURL?.startsWith('https://api.openai.com/')) ||\n\t\t\t\t\t\t\t\t\t($credentials?.url && !$credentials.url.startsWith('https://api.openai.com/')) ||\n\t\t\t\t\t\t\t\t\t$responseItem.id.includes('embed')\n\t\t\t\t\t\t\t\t}}`,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'setKeyValue',\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\tname: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t\tvalue: '={{$responseItem.id}}',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttype: 'sort',\n\t\t\t\t\t\t\tproperties: {\n\t\t\t\t\t\t\t\tkey: 'name',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t},\n\trouting: {\n\t\tsend: {\n\t\t\ttype: 'body',\n\t\t\tproperty: 'model',\n\t\t},\n\t},\n\tdefault: 'text-embedding-3-small',\n};\n\nexport class EmbeddingsOpenAi implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Embeddings OpenAI',\n\t\tname: 'embeddingsOpenAi',\n\t\ticon: { light: 'file:openAiLight.svg', dark: 'file:openAiLight.dark.svg' },\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'openAiApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2],\n\t\tdescription: 'Use Embeddings OpenAI',\n\t\tdefaults: {\n\t\t\tname: 'Embeddings OpenAI',\n\t\t},\n\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Embeddings'],\n\t\t\t},\n\t\t\tresources: {\n\t\t\t\tprimaryDocumentation: [\n\t\t\t\t\t{\n\t\t\t\t\t\turl: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.embeddingsopenai/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\n\t\tinputs: [],\n\n\t\toutputs: [NodeConnectionTypes.AiEmbedding],\n\t\toutputNames: ['Embeddings'],\n\t\trequestDefaults: {\n\t\t\tignoreHttpStatusErrors: true,\n\t\t\tbaseURL:\n\t\t\t\t'={{ $parameter.options?.baseURL?.split(\"/\").slice(0,-1).join(\"/\") || $credentials.url?.split(\"/\").slice(0,-1).join(\"/\") || \"https://api.openai.com\" }}',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiVectorStore]),\n\t\t\t{\n\t\t\t\t...modelParameter,\n\t\t\t\tdefault: 'text-embedding-ada-002',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...modelParameter,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\tplaceholder: 'Add Option',\n\t\t\t\tdescription: 'Additional options to add',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Dimensions',\n\t\t\t\t\t\tname: 'dimensions',\n\t\t\t\t\t\tdefault: undefined,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The number of dimensions the resulting output embeddings should have. Only supported in text-embedding-3 and later models.',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '256',\n\t\t\t\t\t\t\t\tvalue: 256,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '512',\n\t\t\t\t\t\t\t\tvalue: 512,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '1024',\n\t\t\t\t\t\t\t\tvalue: 1024,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '1536',\n\t\t\t\t\t\t\t\tvalue: 1536,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: '3072',\n\t\t\t\t\t\t\t\tvalue: 3072,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Base URL',\n\t\t\t\t\t\tname: 'baseURL',\n\t\t\t\t\t\tdefault: 'https://api.openai.com/v1',\n\t\t\t\t\t\tdescription: 'Override the default base URL for the API',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\thide: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Batch Size',\n\t\t\t\t\t\tname: 'batchSize',\n\t\t\t\t\t\tdefault: 512,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2048 },\n\t\t\t\t\t\tdescription: 'Maximum number of documents to send in each request',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Strip New Lines',\n\t\t\t\t\t\tname: 'stripNewLines',\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescription: 'Whether to strip new lines from the input text',\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Maximum amount of time a request is allowed to take in seconds. Set to -1 for no timeout.',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Encoding Format',\n\t\t\t\t\t\tname: 'encodingFormat',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\tdescription: 'The format to return the embeddings in',\n\t\t\t\t\t\tdefault: undefined,\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Float',\n\t\t\t\t\t\t\t\tvalue: 'float',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tname: 'Base64',\n\t\t\t\t\t\t\t\tvalue: 'base64',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tthis.logger.debug('Supply data for embeddings');\n\t\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tbaseURL?: string;\n\t\t\tbatchSize?: number;\n\t\t\tstripNewLines?: boolean;\n\t\t\ttimeout?: number;\n\t\t\tdimensions?: number | undefined;\n\t\t\tencodingFormat?: 'float' | 'base64' | undefined;\n\t\t};\n\n\t\tif (options.timeout === -1) {\n\t\t\toptions.timeout = undefined;\n\t\t}\n\n\t\tconst { openAiDefaultHeaders: defaultHeaders } = Container.get(AiConfig);\n\n\t\tconst configuration: ClientOptions = {\n\t\t\tdefaultHeaders,\n\t\t};\n\t\tif (options.baseURL) {\n\t\t\tconfiguration.baseURL = options.baseURL;\n\t\t} else if (credentials.url) {\n\t\t\tconfiguration.baseURL = credentials.url as string;\n\t\t}\n\n\t\tif (configuration.baseURL) {\n\t\t\tconfiguration.fetchOptions = {\n\t\t\t\tdispatcher: getProxyAgent(configuration.baseURL ?? 'https://api.openai.com/v1'),\n\t\t\t};\n\t\t}\n\n\t\tconst embeddings = new OpenAIEmbeddings({\n\t\t\tmodel: this.getNodeParameter('model', itemIndex, 'text-embedding-3-small') as string,\n\t\t\tapiKey: credentials.apiKey as string,\n\t\t\t...options,\n\t\t\tconfiguration,\n\t\t});\n\n\t\treturn {\n\t\t\tresponse: logWrapper(embeddings, this),\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
|
|
@@ -41,6 +41,8 @@ var import_n8nLlmFailedAttemptHandler = require("../n8nLlmFailedAttemptHandler")
|
|
|
41
41
|
var import_N8nLlmTracing = require("../N8nLlmTracing");
|
|
42
42
|
var import_common = require("./common");
|
|
43
43
|
var import_loadModels = require("./methods/loadModels");
|
|
44
|
+
var import_di = require("@n8n/di");
|
|
45
|
+
var import_config = require("@n8n/config");
|
|
44
46
|
const INCLUDE_JSON_WARNING = {
|
|
45
47
|
displayName: 'If using JSON response format, you must include word "json" in the prompt in your chain or agent. Also, make sure to select latest models released post November 2023.',
|
|
46
48
|
name: "notice",
|
|
@@ -722,7 +724,10 @@ class LmChatOpenAi {
|
|
|
722
724
|
const modelName = version >= 1.2 ? this.getNodeParameter("model.value", itemIndex) : this.getNodeParameter("model", itemIndex);
|
|
723
725
|
const responsesApiEnabled = this.getNodeParameter("responsesApiEnabled", itemIndex, false);
|
|
724
726
|
const options = this.getNodeParameter("options", itemIndex, {});
|
|
725
|
-
const
|
|
727
|
+
const { openAiDefaultHeaders: defaultHeaders } = import_di.Container.get(import_config.AiConfig);
|
|
728
|
+
const configuration = {
|
|
729
|
+
defaultHeaders
|
|
730
|
+
};
|
|
726
731
|
if (options.baseURL) {
|
|
727
732
|
configuration.baseURL = options.baseURL;
|
|
728
733
|
} else if (credentials.url) {
|
|
@@ -735,6 +740,7 @@ class LmChatOpenAi {
|
|
|
735
740
|
}
|
|
736
741
|
if (credentials.header && typeof credentials.headerName === "string" && credentials.headerName && typeof credentials.headerValue === "string") {
|
|
737
742
|
configuration.defaultHeaders = {
|
|
743
|
+
...configuration.defaultHeaders,
|
|
738
744
|
[credentials.headerName]: credentials.headerValue
|
|
739
745
|
};
|
|
740
746
|
}
|