@n8n/n8n-nodes-langchain 1.122.52 → 1.122.54

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.
@@ -25,6 +25,12 @@ var import_n8n_workflow = require("n8n-workflow");
25
25
  var import_helpers = require("./helpers");
26
26
  var import_N8nLlmTracing = require("../llms/N8nLlmTracing");
27
27
  var import_N8nNonEstimatingTracing = require("../llms/N8nNonEstimatingTracing");
28
+ var import_redact_headers = require("../llms/redact-headers");
29
+ function getDeclaredRedactedHeaders(tracer) {
30
+ if (!(0, import_redact_headers.isRecord)(tracer) || !(0, import_redact_headers.isRecord)(tracer.options)) return [];
31
+ const { redactedHeaders } = tracer.options;
32
+ return Array.isArray(redactedHeaders) ? redactedHeaders.filter((name) => typeof name === "string") : [];
33
+ }
28
34
  function getCallbacksArray(callbacks) {
29
35
  if (!callbacks) return [];
30
36
  if (Array.isArray(callbacks)) {
@@ -168,7 +174,8 @@ class ModelSelector {
168
174
  currentCallback.setParentRunIndex(this.getNextRunIndex());
169
175
  }
170
176
  }
171
- const modelSelectorTracing = new import_N8nNonEstimatingTracing.N8nNonEstimatingTracing(this);
177
+ const redactedHeaders = originalCallbacks.flatMap(getDeclaredRedactedHeaders);
178
+ const modelSelectorTracing = new import_N8nNonEstimatingTracing.N8nNonEstimatingTracing(this, { redactedHeaders });
172
179
  selectedModel.callbacks = [...originalCallbacks, modelSelectorTracing];
173
180
  return {
174
181
  response: selectedModel
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../nodes/ModelSelector/ModelSelector.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-param-description-wrong-for-dynamic-options */\n/* eslint-disable n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options */\nimport type { BaseCallbackHandler, CallbackHandlerMethods } from '@langchain/core/callbacks/base';\nimport type { Callbacks } from '@langchain/core/callbacks/manager';\nimport type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n\ttype ILoadOptionsFunctions,\n\tNodeOperationError,\n} from 'n8n-workflow';\n\nimport { numberInputsProperty, configuredInputs } from './helpers';\nimport { N8nLlmTracing } from '../llms/N8nLlmTracing';\nimport { N8nNonEstimatingTracing } from '../llms/N8nNonEstimatingTracing';\n\ninterface ModeleSelectionRule {\n\tmodelIndex: number;\n\tconditions: {\n\t\toptions: {\n\t\t\tcaseSensitive: boolean;\n\t\t\ttypeValidation: 'strict' | 'loose';\n\t\t\tleftValue: string;\n\t\t\tversion: 1 | 2;\n\t\t};\n\t\tconditions: Array<{\n\t\t\tid: string;\n\t\t\tleftValue: string;\n\t\t\trightValue: string;\n\t\t\toperator: {\n\t\t\t\ttype: string;\n\t\t\t\toperation: string;\n\t\t\t\tname: string;\n\t\t\t};\n\t\t}>;\n\t\tcombinator: 'and' | 'or';\n\t};\n}\n\nfunction getCallbacksArray(\n\tcallbacks: Callbacks | undefined,\n): Array<BaseCallbackHandler | CallbackHandlerMethods> {\n\tif (!callbacks) return [];\n\n\tif (Array.isArray(callbacks)) {\n\t\treturn callbacks;\n\t}\n\n\t// If it's a CallbackManager, extract its handlers\n\treturn callbacks.handlers || [];\n}\n\nexport class ModelSelector implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Model Selector',\n\t\tname: 'modelSelector',\n\t\ticon: 'fa:map-signs',\n\t\ticonColor: 'green',\n\t\tdefaults: {\n\t\t\tname: 'Model Selector',\n\t\t},\n\t\tversion: 1,\n\t\tgroup: ['transform'],\n\t\tdescription:\n\t\t\t'Use this node to select one of the connected models to this node based on workflow data',\n\t\tinputs: `={{\n\t\t\t\t((parameters) => {\n\t\t\t\t\t${configuredInputs.toString()};\n\t\t\t\t\treturn configuredInputs(parameters)\n\t\t\t\t})($parameter)\n\t\t\t}}`,\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Language Models'],\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.modelselector/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\toutputs: [NodeConnectionTypes.AiLanguageModel],\n\t\trequiredInputs: 1,\n\t\tproperties: [\n\t\t\tnumberInputsProperty,\n\t\t\t{\n\t\t\t\tdisplayName: 'Rules',\n\t\t\t\tname: 'rules',\n\t\t\t\tplaceholder: 'Add Rule',\n\t\t\t\ttype: 'fixedCollection',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tmultipleValues: true,\n\t\t\t\t\tsortable: true,\n\t\t\t\t},\n\t\t\t\tdescription: 'Rules to map workflow data to specific models',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Rule',\n\t\t\t\t\t\tname: 'rule',\n\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Model',\n\t\t\t\t\t\t\t\tname: 'modelIndex',\n\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\tdescription: 'Choose model input from the list',\n\t\t\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t\tplaceholder: 'Choose model input from the list',\n\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\tloadOptionsMethod: 'getModels',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Conditions',\n\t\t\t\t\t\t\t\tname: 'conditions',\n\t\t\t\t\t\t\t\tplaceholder: 'Add Condition',\n\t\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\t\tdefault: {},\n\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\tfilter: {\n\t\t\t\t\t\t\t\t\t\tcaseSensitive: true,\n\t\t\t\t\t\t\t\t\t\ttypeValidation: 'strict',\n\t\t\t\t\t\t\t\t\t\tversion: 2,\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\tdescription: 'Conditions that must be met to select this model',\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\tmethods = {\n\t\tloadOptions: {\n\t\t\tasync getModels(this: ILoadOptionsFunctions) {\n\t\t\t\tconst numberInputs = this.getCurrentNodeParameter('numberInputs') as number;\n\n\t\t\t\treturn Array.from({ length: numberInputs ?? 2 }, (_, i) => ({\n\t\t\t\t\tvalue: i + 1,\n\t\t\t\t\tname: `Model ${(i + 1).toString()}`,\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\tconst models = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\titemIndex,\n\t\t)) as unknown[];\n\n\t\tif (!models || models.length === 0) {\n\t\t\tthrow new NodeOperationError(this.getNode(), 'No models connected', {\n\t\t\t\titemIndex,\n\t\t\t\tdescription: 'No models found in input connections',\n\t\t\t});\n\t\t}\n\t\tmodels.reverse();\n\n\t\tconst rules = this.getNodeParameter('rules.rule', itemIndex, []) as ModeleSelectionRule[];\n\n\t\tif (!rules || rules.length === 0) {\n\t\t\tthrow new NodeOperationError(this.getNode(), 'No rules defined', {\n\t\t\t\titemIndex,\n\t\t\t\tdescription: 'At least one rule must be defined to select a model',\n\t\t\t});\n\t\t}\n\n\t\tfor (let i = 0; i < rules.length; i++) {\n\t\t\tconst rule = rules[i];\n\t\t\tconst modelIndex = rule.modelIndex;\n\n\t\t\tif (modelIndex <= 0 || modelIndex > models.length) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), `Invalid model index ${modelIndex}`, {\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription: `Model index must be between 1 and ${models.length}`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst conditionsMet = this.getNodeParameter(`rules.rule[${i}].conditions`, itemIndex, false, {\n\t\t\t\textractValue: true,\n\t\t\t}) as boolean;\n\n\t\t\tif (conditionsMet) {\n\t\t\t\tconst selectedModel = models[modelIndex - 1] as BaseChatModel;\n\n\t\t\t\tconst originalCallbacks = getCallbacksArray(selectedModel.callbacks);\n\n\t\t\t\tfor (const currentCallback of originalCallbacks) {\n\t\t\t\t\tif (currentCallback instanceof N8nLlmTracing) {\n\t\t\t\t\t\tcurrentCallback.setParentRunIndex(this.getNextRunIndex());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst modelSelectorTracing = new N8nNonEstimatingTracing(this);\n\t\t\t\tselectedModel.callbacks = [...originalCallbacks, modelSelectorTracing];\n\n\t\t\t\treturn {\n\t\t\t\t\tresponse: selectedModel,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tthrow new NodeOperationError(this.getNode(), 'No matching rule found', {\n\t\t\titemIndex,\n\t\t\tdescription: 'None of the defined rules matched the workflow data',\n\t\t});\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../nodes/ModelSelector/ModelSelector.node.ts"],"sourcesContent":["/* eslint-disable n8n-nodes-base/node-param-description-wrong-for-dynamic-options */\n/* eslint-disable n8n-nodes-base/node-param-display-name-wrong-for-dynamic-options */\nimport type { BaseCallbackHandler, CallbackHandlerMethods } from '@langchain/core/callbacks/base';\nimport type { Callbacks } from '@langchain/core/callbacks/manager';\nimport type { BaseChatModel } from '@langchain/core/language_models/chat_models';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n\ttype ILoadOptionsFunctions,\n\tNodeOperationError,\n} from 'n8n-workflow';\n\nimport { numberInputsProperty, configuredInputs } from './helpers';\nimport { N8nLlmTracing } from '../llms/N8nLlmTracing';\nimport { N8nNonEstimatingTracing } from '../llms/N8nNonEstimatingTracing';\nimport { isRecord } from '../llms/redact-headers';\n\ninterface ModeleSelectionRule {\n\tmodelIndex: number;\n\tconditions: {\n\t\toptions: {\n\t\t\tcaseSensitive: boolean;\n\t\t\ttypeValidation: 'strict' | 'loose';\n\t\t\tleftValue: string;\n\t\t\tversion: 1 | 2;\n\t\t};\n\t\tconditions: Array<{\n\t\t\tid: string;\n\t\t\tleftValue: string;\n\t\t\trightValue: string;\n\t\t\toperator: {\n\t\t\t\ttype: string;\n\t\t\t\toperation: string;\n\t\t\t\tname: string;\n\t\t\t};\n\t\t}>;\n\t\tcombinator: 'and' | 'or';\n\t};\n}\n\n/**\n * Read the header names a tracer declares as redacted. Duck-typed on purpose: a model may\n * attach any tracer implementation, so match on the declared list, not on a tracer class.\n */\nfunction getDeclaredRedactedHeaders(tracer: unknown): string[] {\n\tif (!isRecord(tracer) || !isRecord(tracer.options)) return [];\n\n\tconst { redactedHeaders } = tracer.options;\n\n\treturn Array.isArray(redactedHeaders)\n\t\t? redactedHeaders.filter((name) => typeof name === 'string')\n\t\t: [];\n}\n\nfunction getCallbacksArray(\n\tcallbacks: Callbacks | undefined,\n): Array<BaseCallbackHandler | CallbackHandlerMethods> {\n\tif (!callbacks) return [];\n\n\tif (Array.isArray(callbacks)) {\n\t\treturn callbacks;\n\t}\n\n\t// If it's a CallbackManager, extract its handlers\n\treturn callbacks.handlers || [];\n}\n\nexport class ModelSelector implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Model Selector',\n\t\tname: 'modelSelector',\n\t\ticon: 'fa:map-signs',\n\t\ticonColor: 'green',\n\t\tdefaults: {\n\t\t\tname: 'Model Selector',\n\t\t},\n\t\tversion: 1,\n\t\tgroup: ['transform'],\n\t\tdescription:\n\t\t\t'Use this node to select one of the connected models to this node based on workflow data',\n\t\tinputs: `={{\n\t\t\t\t((parameters) => {\n\t\t\t\t\t${configuredInputs.toString()};\n\t\t\t\t\treturn configuredInputs(parameters)\n\t\t\t\t})($parameter)\n\t\t\t}}`,\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Language Models'],\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.modelselector/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\toutputs: [NodeConnectionTypes.AiLanguageModel],\n\t\trequiredInputs: 1,\n\t\tproperties: [\n\t\t\tnumberInputsProperty,\n\t\t\t{\n\t\t\t\tdisplayName: 'Rules',\n\t\t\t\tname: 'rules',\n\t\t\t\tplaceholder: 'Add Rule',\n\t\t\t\ttype: 'fixedCollection',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\tmultipleValues: true,\n\t\t\t\t\tsortable: true,\n\t\t\t\t},\n\t\t\t\tdescription: 'Rules to map workflow data to specific models',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Rule',\n\t\t\t\t\t\tname: 'rule',\n\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Model',\n\t\t\t\t\t\t\t\tname: 'modelIndex',\n\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\tdescription: 'Choose model input from the list',\n\t\t\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t\tplaceholder: 'Choose model input from the list',\n\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\tloadOptionsMethod: 'getModels',\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Conditions',\n\t\t\t\t\t\t\t\tname: 'conditions',\n\t\t\t\t\t\t\t\tplaceholder: 'Add Condition',\n\t\t\t\t\t\t\t\ttype: 'filter',\n\t\t\t\t\t\t\t\tdefault: {},\n\t\t\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\t\t\tfilter: {\n\t\t\t\t\t\t\t\t\t\tcaseSensitive: true,\n\t\t\t\t\t\t\t\t\t\ttypeValidation: 'strict',\n\t\t\t\t\t\t\t\t\t\tversion: 2,\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\tdescription: 'Conditions that must be met to select this model',\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\tmethods = {\n\t\tloadOptions: {\n\t\t\tasync getModels(this: ILoadOptionsFunctions) {\n\t\t\t\tconst numberInputs = this.getCurrentNodeParameter('numberInputs') as number;\n\n\t\t\t\treturn Array.from({ length: numberInputs ?? 2 }, (_, i) => ({\n\t\t\t\t\tvalue: i + 1,\n\t\t\t\t\tname: `Model ${(i + 1).toString()}`,\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\tconst models = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiLanguageModel,\n\t\t\titemIndex,\n\t\t)) as unknown[];\n\n\t\tif (!models || models.length === 0) {\n\t\t\tthrow new NodeOperationError(this.getNode(), 'No models connected', {\n\t\t\t\titemIndex,\n\t\t\t\tdescription: 'No models found in input connections',\n\t\t\t});\n\t\t}\n\t\tmodels.reverse();\n\n\t\tconst rules = this.getNodeParameter('rules.rule', itemIndex, []) as ModeleSelectionRule[];\n\n\t\tif (!rules || rules.length === 0) {\n\t\t\tthrow new NodeOperationError(this.getNode(), 'No rules defined', {\n\t\t\t\titemIndex,\n\t\t\t\tdescription: 'At least one rule must be defined to select a model',\n\t\t\t});\n\t\t}\n\n\t\tfor (let i = 0; i < rules.length; i++) {\n\t\t\tconst rule = rules[i];\n\t\t\tconst modelIndex = rule.modelIndex;\n\n\t\t\tif (modelIndex <= 0 || modelIndex > models.length) {\n\t\t\t\tthrow new NodeOperationError(this.getNode(), `Invalid model index ${modelIndex}`, {\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription: `Model index must be between 1 and ${models.length}`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst conditionsMet = this.getNodeParameter(`rules.rule[${i}].conditions`, itemIndex, false, {\n\t\t\t\textractValue: true,\n\t\t\t}) as boolean;\n\n\t\t\tif (conditionsMet) {\n\t\t\t\tconst selectedModel = models[modelIndex - 1] as BaseChatModel;\n\n\t\t\t\tconst originalCallbacks = getCallbacksArray(selectedModel.callbacks);\n\n\t\t\t\tfor (const currentCallback of originalCallbacks) {\n\t\t\t\t\tif (currentCallback instanceof N8nLlmTracing) {\n\t\t\t\t\t\tcurrentCallback.setParentRunIndex(this.getNextRunIndex());\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// This node records the same serialized model as the model's own tracer,\n\t\t\t\t// so it masks whatever header names that tracer declares.\n\t\t\t\tconst redactedHeaders = originalCallbacks.flatMap(getDeclaredRedactedHeaders);\n\t\t\t\tconst modelSelectorTracing = new N8nNonEstimatingTracing(this, { redactedHeaders });\n\t\t\t\tselectedModel.callbacks = [...originalCallbacks, modelSelectorTracing];\n\n\t\t\t\treturn {\n\t\t\t\t\tresponse: selectedModel,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tthrow new NodeOperationError(this.getNode(), 'No matching rule found', {\n\t\t\titemIndex,\n\t\t\tdescription: 'None of the defined rules matched the workflow data',\n\t\t});\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -28,6 +28,7 @@ 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_credentials = require("../../vendors/OpenAi/helpers/credentials");
31
32
  class OpenAiAssistant {
32
33
  constructor() {
33
34
  this.description = {
@@ -337,6 +338,9 @@ class OpenAiAssistant {
337
338
  if (input === void 0) {
338
339
  throw new import_n8n_workflow.NodeOperationError(this.getNode(), "The \u2018text\u2018 parameter is empty.");
339
340
  }
341
+ if (options.baseURL) {
342
+ (0, import_credentials.assertOpenAiCredentialAllowsUrl)(this.getNode(), credentials, options.baseURL);
343
+ }
340
344
  const client = new import_openai.OpenAI({
341
345
  apiKey: credentials.apiKey,
342
346
  maxRetries: options.maxRetries ?? 2,
@@ -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 { assertOpenAiCredentialAllowsUrl } from '../../vendors/OpenAi/helpers/credentials';\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\tif (options.baseURL) {\n\t\t\t\t\tassertOpenAiCredentialAllowsUrl(this.getNode(), credentials, options.baseURL);\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"]}
@@ -26,6 +26,7 @@ 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_credentials = require("../../vendors/OpenAi/helpers/credentials");
29
30
  const modelParameter = {
30
31
  displayName: "Model",
31
32
  name: "model",
@@ -242,6 +243,7 @@ class EmbeddingsOpenAi {
242
243
  }
243
244
  const configuration = {};
244
245
  if (options.baseURL) {
246
+ (0, import_credentials.assertOpenAiCredentialAllowsUrl)(this.getNode(), credentials, options.baseURL);
245
247
  configuration.baseURL = options.baseURL;
246
248
  } else if (credentials.url) {
247
249
  configuration.baseURL = 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":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAiC;AACjC,0BAOO;AAGP,wBAA2B;AAE3B,4BAA8B;AAC9B,0BAA6C;AAE7C,MAAM,iBAAkC;AAAA,EACvC,aAAa;AAAA,EACb,MAAM;AAAA,EACN,MAAM;AAAA,EACN,aACC;AAAA,EACD,aAAa;AAAA,IACZ,aAAa;AAAA,MACZ,SAAS;AAAA,QACR,SAAS;AAAA,UACR,QAAQ;AAAA,UACR,KAAK;AAAA,QACN;AAAA,QACA,QAAQ;AAAA,UACP,aAAa;AAAA,YACZ;AAAA,cACC,MAAM;AAAA,cACN,YAAY;AAAA,gBACX,UAAU;AAAA,cACX;AAAA,YACD;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,YAAY;AAAA;AAAA,gBAEX,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA,cAKP;AAAA,YACD;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,YAAY;AAAA,gBACX,MAAM;AAAA,gBACN,OAAO;AAAA,cACR;AAAA,YACD;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,YAAY;AAAA,gBACX,KAAK;AAAA,cACN;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,EACD;AAAA,EACA,SAAS;AAAA,IACR,MAAM;AAAA,MACL,MAAM;AAAA,MACN,UAAU;AAAA,IACX;AAAA,EACD;AAAA,EACA,SAAS;AACV;AAEO,MAAM,iBAAsC;AAAA,EAA5C;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM,EAAE,OAAO,wBAAwB,MAAM,4BAA4B;AAAA,MACzE,aAAa;AAAA,QACZ;AAAA,UACC,MAAM;AAAA,UACN,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS,CAAC,GAAG,KAAK,GAAG;AAAA,MACrB,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MAEA,OAAO;AAAA,QACN,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,YAAY;AAAA,QAClB;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MAEA,QAAQ,CAAC;AAAA,MAET,SAAS,CAAC,wCAAoB,WAAW;AAAA,MACzC,aAAa,CAAC,YAAY;AAAA,MAC1B,iBAAiB;AAAA,QAChB,wBAAwB;AAAA,QACxB,SACC;AAAA,MACF;AAAA,MACA,YAAY;AAAA,YACX,kDAA6B,CAAC,wCAAoB,aAAa,CAAC;AAAA,QAChE;AAAA,UACC,GAAG;AAAA,UACH,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,CAAC;AAAA,YACf;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,GAAG;AAAA,UACH,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,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,aACC;AAAA,cACD,MAAM;AAAA,cACN,SAAS;AAAA,gBACR;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa;AAAA,cACb,MAAM;AAAA,cACN,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,gBACpC;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa,EAAE,UAAU,KAAK;AAAA,cAC9B,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,aACC;AAAA,cACD,MAAM;AAAA,YACP;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,SAAS;AAAA,cACT,SAAS;AAAA,gBACR;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,gBACR;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,WAAuC,WAAwC;AACpF,SAAK,OAAO,MAAM,4BAA4B;AAC9C,UAAM,cAAc,MAAM,KAAK,eAAe,WAAW;AAEzD,UAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAS9D,QAAI,QAAQ,YAAY,IAAI;AAC3B,cAAQ,UAAU;AAAA,IACnB;AAEA,UAAM,gBAA+B,CAAC;AACtC,QAAI,QAAQ,SAAS;AACpB,oBAAc,UAAU,QAAQ;AAAA,IACjC,WAAW,YAAY,KAAK;AAC3B,oBAAc,UAAU,YAAY;AAAA,IACrC;AAEA,QAAI,cAAc,SAAS;AAC1B,oBAAc,eAAe;AAAA,QAC5B,gBAAY,qCAAc,cAAc,WAAW,2BAA2B;AAAA,MAC/E;AAAA,IACD;AAEA,UAAM,aAAa,IAAI,+BAAiB;AAAA,MACvC,OAAO,KAAK,iBAAiB,SAAS,WAAW,wBAAwB;AAAA,MACzE,QAAQ,YAAY;AAAA,MACpB,GAAG;AAAA,MACH;AAAA,IACD,CAAC;AAED,WAAO;AAAA,MACN,cAAU,8BAAW,YAAY,IAAI;AAAA,IACtC;AAAA,EACD;AACD;","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';\n\nimport { assertOpenAiCredentialAllowsUrl } from '../../vendors/OpenAi/helpers/credentials';\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\tassertOpenAiCredentialAllowsUrl(this.getNode(), credentials, 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":[]}
@@ -36,6 +36,7 @@ var import_pick = __toESM(require("lodash/pick"));
36
36
  var import_n8n_workflow = require("n8n-workflow");
37
37
  var import_httpProxyAgent = require("../../../utils/httpProxyAgent");
38
38
  var import_sharedFields = require("../../../utils/sharedFields");
39
+ var import_credentials = require("../../vendors/OpenAi/helpers/credentials");
39
40
  var import_error_handling = require("../../vendors/OpenAi/helpers/error-handling");
40
41
  var import_n8nLlmFailedAttemptHandler = require("../n8nLlmFailedAttemptHandler");
41
42
  var import_N8nLlmTracing = require("../N8nLlmTracing");
@@ -724,6 +725,7 @@ class LmChatOpenAi {
724
725
  const options = this.getNodeParameter("options", itemIndex, {});
725
726
  const configuration = {};
726
727
  if (options.baseURL) {
728
+ (0, import_credentials.assertOpenAiCredentialAllowsUrl)(this.getNode(), credentials, options.baseURL);
727
729
  configuration.baseURL = options.baseURL;
728
730
  } else if (credentials.url) {
729
731
  configuration.baseURL = credentials.url;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/llms/LMChatOpenAi/LmChatOpenAi.node.ts"],"sourcesContent":["import { ChatOpenAI, type ChatOpenAIFields, type ClientOptions } from '@langchain/openai';\nimport pick from 'lodash/pick';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeProperties,\n\ttype IDataObject,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getProxyAgent } from '@utils/httpProxyAgent';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { openAiFailedAttemptHandler } from '../../vendors/OpenAi/helpers/error-handling';\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\nimport { formatBuiltInTools, prepareAdditionalResponsesParams } from './common';\nimport { searchModels } from './methods/loadModels';\nimport type { ModelOptions } from './types';\n\nconst INCLUDE_JSON_WARNING: INodeProperties = {\n\tdisplayName:\n\t\t'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.',\n\tname: 'notice',\n\ttype: 'notice',\n\tdefault: '',\n};\n\nconst completionsResponseFormat: INodeProperties = {\n\tdisplayName: 'Response Format',\n\tname: 'responseFormat',\n\tdefault: 'text',\n\ttype: 'options',\n\toptions: [\n\t\t{\n\t\t\tname: 'Text',\n\t\t\tvalue: 'text',\n\t\t\tdescription: 'Regular text response',\n\t\t},\n\t\t{\n\t\t\tname: 'JSON',\n\t\t\tvalue: 'json_object',\n\t\t\tdescription:\n\t\t\t\t'Enables JSON mode, which should guarantee the message the model generates is valid JSON',\n\t\t},\n\t],\n};\n\nconst jsonSchemaExample = `{\n \"type\": \"object\",\n \"properties\": {\n \"message\": {\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false,\n \"required\": [\"message\"]\n}`;\n\nexport class LmChatOpenAi implements INodeType {\n\tmethods = {\n\t\tlistSearch: {\n\t\t\tsearchModels,\n\t\t},\n\t};\n\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenAI Chat Model',\n\n\t\tname: 'lmChatOpenAi',\n\t\ticon: { light: 'file:openAiLight.svg', dark: 'file:openAiLight.dark.svg' },\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3],\n\t\tdescription: 'For advanced usage with an AI chain',\n\t\tdefaults: {\n\t\t\tname: 'OpenAI Chat Model',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Language Models', 'Root Nodes'],\n\t\t\t\t'Language Models': ['Chat Models (Recommended)'],\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.lmchatopenai/',\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.AiLanguageModel],\n\t\toutputNames: ['Model'],\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(\"/\") || $credentials?.url?.split(\"/\").slice(0,-1).join(\"/\") || \"https://api.openai.com\" }}',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\t...INCLUDE_JSON_WARNING,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.responseFormat': ['json_object'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...INCLUDE_JSON_WARNING,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.textFormat.textOptions.type': ['json_object'],\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 generate the completion. <a href=\"https://beta.openai.com/docs/models/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\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || $credentials?.url?.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\t// If the baseURL is not set or is set to api.openai.com, include only chat models\n\t\t\t\t\t\t\t\t\t\t\tpass: `={{\n\t\t\t\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\t\t\t($credentials?.url && !$credentials.url.startsWith('https://api.openai.com/')) ||\n\t\t\t\t\t\t\t\t\t\t\t\t$responseItem.id.startsWith('ft:') ||\n\t\t\t\t\t\t\t\t\t\t\t\t$responseItem.id.startsWith('o1') ||\n\t\t\t\t\t\t\t\t\t\t\t\t$responseItem.id.startsWith('o3') ||\n\t\t\t\t\t\t\t\t\t\t\t\t($responseItem.id.startsWith('gpt-') && !$responseItem.id.includes('instruct'))\n\t\t\t\t\t\t\t\t\t\t\t}}`,\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-4o-mini',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\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: 'resourceLocator',\n\t\t\t\tdefault: { mode: 'list', value: 'gpt-4.1-mini' },\n\t\t\t\trequired: true,\n\t\t\t\tmodes: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'From List',\n\t\t\t\t\t\tname: 'list',\n\t\t\t\t\t\ttype: 'list',\n\t\t\t\t\t\tplaceholder: 'Select a model...',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tsearchListMethod: 'searchModels',\n\t\t\t\t\t\t\tsearchable: true,\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: 'ID',\n\t\t\t\t\t\tname: 'id',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tplaceholder: 'gpt-4.1-mini',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdescription: 'The model. Choose from the list, or specify an ID.',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lte: 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:\n\t\t\t\t\t'When using non-OpenAI models via \"Base URL\" override, not all models might be chat-compatible or support other features, like tools calling or JSON response format',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.baseURL': [{ _cnd: { exists: true } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Use Responses API',\n\t\t\t\tname: 'responsesApiEnabled',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: true,\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether to use the Responses API to generate the response. <a href=\"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatopenai/#use-responses-api\">Learn more</a>.',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Built-in Tools',\n\t\t\t\tname: 'builtInTools',\n\t\t\t\tplaceholder: 'Add Built-in Tool',\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: 'Web Search',\n\t\t\t\t\t\tname: 'webSearch',\n\t\t\t\t\t\ttype: 'collection',\n\t\t\t\t\t\tdefault: { searchContextSize: 'medium' },\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Search Context Size',\n\t\t\t\t\t\t\t\tname: 'searchContextSize',\n\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\tdefault: 'medium',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'High level guidance for the amount of context window space to use for the search',\n\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t{ name: 'Low', value: 'low' },\n\t\t\t\t\t\t\t\t\t{ name: 'Medium', value: 'medium' },\n\t\t\t\t\t\t\t\t\t{ name: 'High', value: 'high' },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Web Search Allowed Domains',\n\t\t\t\t\t\t\t\tname: 'allowedDomains',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Comma-separated list of domains to search. Only domains in this list will be searched.',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. google.com, wikipedia.org',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Country',\n\t\t\t\t\t\t\t\tname: 'country',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. US, GB',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'City',\n\t\t\t\t\t\t\t\tname: 'city',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. New York, London',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Region',\n\t\t\t\t\t\t\t\tname: 'region',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. New York, London',\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: 'File Search',\n\t\t\t\t\t\tname: 'fileSearch',\n\t\t\t\t\t\ttype: 'collection',\n\t\t\t\t\t\tdefault: { vectorStoreIds: '[]' },\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Vector Store IDs',\n\t\t\t\t\t\t\t\tname: 'vectorStoreIds',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'The vector store IDs to use for the file search. Vector stores are managed via OpenAI Dashboard. <a href=\"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatopenai/#built-in-tools\">Learn more</a>.',\n\t\t\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\t\t\tdefault: '[]',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Filters',\n\t\t\t\t\t\t\t\tname: 'filters',\n\t\t\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\t\t\tdefault: '{}',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Max Results',\n\t\t\t\t\t\t\t\tname: 'maxResults',\n\t\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\t\t\ttypeOptions: { minValue: 1, maxValue: 50 },\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: 'Code Interpreter',\n\t\t\t\t\t\tname: 'codeInterpreter',\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescription: 'Whether to allow the model to execute code in a sandboxed environment',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: '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.1 } }],\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: 'Frequency Penalty',\n\t\t\t\t\t\tname: 'frequencyPenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim\",\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\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\t...completionsResponseFormat,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.3 } }],\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\t...completionsResponseFormat,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [false],\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: 'Response Format',\n\t\t\t\t\t\tname: 'textFormat',\n\t\t\t\t\t\ttype: 'fixedCollection',\n\t\t\t\t\t\tdefault: { textOptions: [{ type: 'text' }] },\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Text',\n\t\t\t\t\t\t\t\tname: 'textOptions',\n\t\t\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdisplayName: 'Type',\n\t\t\t\t\t\t\t\t\t\tname: 'type',\n\t\t\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'Text', value: 'text' },\n\t\t\t\t\t\t\t\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'JSON Schema (recommended)', value: 'json_schema' },\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'JSON Object', value: 'json_object' },\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\tdisplayName: 'Verbosity',\n\t\t\t\t\t\t\t\t\t\tname: 'verbosity',\n\t\t\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\t\t\tdefault: 'medium',\n\t\t\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'Low', value: 'low' },\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'Medium', value: 'medium' },\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'High', value: 'high' },\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\tdisplayName: 'Name',\n\t\t\t\t\t\t\t\t\t\tname: 'name',\n\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\tdefault: 'my_schema',\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t'The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: ['json_schema'],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayName:\n\t\t\t\t\t\t\t\t\t\t\t'All properties in the schema must be set to \"required\", when using \"strict\" mode.',\n\t\t\t\t\t\t\t\t\t\tname: 'requiredNotice',\n\t\t\t\t\t\t\t\t\t\ttype: 'notice',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\tstrict: [true],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayName: 'Schema',\n\t\t\t\t\t\t\t\t\t\tname: 'schema',\n\t\t\t\t\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\t\t\t\t\tdefault: jsonSchemaExample,\n\t\t\t\t\t\t\t\t\t\tdescription: 'The schema of the response format',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: ['json_schema'],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayName: 'Description',\n\t\t\t\t\t\t\t\t\t\tname: 'description',\n\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\tdescription: 'The description of the response format',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: ['json_schema'],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayName: 'Strict',\n\t\t\t\t\t\t\t\t\t\tname: 'strict',\n\t\t\t\t\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t'Whether to require that the AI will always generate responses that match the provided JSON Schema',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: ['json_schema'],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Presence Penalty',\n\t\t\t\t\t\tname: 'presencePenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics\",\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: 'Sampling Temperature',\n\t\t\t\t\t\tname: 'temperature',\n\t\t\t\t\t\tdefault: 0.7,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.',\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: 'Reasoning Effort',\n\t\t\t\t\t\tname: 'reasoningEffort',\n\t\t\t\t\t\tdefault: 'medium',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls the amount of reasoning tokens to use. A value of \"low\" will favor speed and economical token usage, \"high\" will favor more complete reasoning at the cost of more tokens generated and slower responses.',\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: 'Low',\n\t\t\t\t\t\t\t\tvalue: 'low',\n\t\t\t\t\t\t\t\tdescription: 'Favors speed and economical token usage',\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: 'Medium',\n\t\t\t\t\t\t\t\tvalue: 'medium',\n\t\t\t\t\t\t\t\tdescription: 'Balance between speed and reasoning accuracy',\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: 'High',\n\t\t\t\t\t\t\t\tvalue: 'high',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Favors more complete reasoning at the cost of more tokens generated and slower responses',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t// reasoning_effort is only available on o1, o1-versioned, or on o3-mini and beyond, and gpt-5 models. Not on o1-mini or other GPT-models.\n\t\t\t\t\t\t\t\t'/model': [{ _cnd: { regex: '(^o1([-\\\\d]+)?$)|(^o[3-9].*)|(^gpt-5.*)' } }],\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: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 60000,\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\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: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\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: 'Conversation ID',\n\t\t\t\t\t\tname: 'conversationId',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The conversation that this response belongs to. Input items and output items from this response are automatically added to this conversation after this response completes.',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Prompt Cache Key',\n\t\t\t\t\t\tname: 'promptCacheKey',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Used by OpenAI to cache responses for similar requests to optimize your cache hit rates',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Safety Identifier',\n\t\t\t\t\t\tname: 'safetyIdentifier',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"A stable identifier used to help detect users of your application that may be violating OpenAI's usage policies. The IDs should be a string that uniquely identifies each user.\",\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Service Tier',\n\t\t\t\t\t\tname: 'serviceTier',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\tdefault: 'auto',\n\t\t\t\t\t\tdescription: 'The service tier to use for the request',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{ name: 'Auto', value: 'auto' },\n\t\t\t\t\t\t\t{ name: 'Flex', value: 'flex' },\n\t\t\t\t\t\t\t{ name: 'Default', value: 'default' },\n\t\t\t\t\t\t\t{ name: 'Priority', value: 'priority' },\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Metadata',\n\t\t\t\t\t\tname: 'metadata',\n\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format, and querying for objects via API or the dashboard. Keys are strings with a maximum length of 64 characters. Values are strings with a maximum length of 512 characters.',\n\t\t\t\t\t\tdefault: '{}',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Top Logprobs',\n\t\t\t\t\t\tname: 'topLogprobs',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'An integer between 0 and 20 specifying the number of most likely tokens to return at each token position, each with an associated log probability',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tminValue: 0,\n\t\t\t\t\t\t\tmaxValue: 20,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Prompt',\n\t\t\t\t\t\tname: 'promptConfig',\n\t\t\t\t\t\ttype: 'fixedCollection',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Configure the reusable prompt template configured via OpenAI Dashboard. <a href=\"https://platform.openai.com/docs/guides/prompt-engineering#reusable-prompts\">Learn more</a>.',\n\t\t\t\t\t\tdefault: { promptOptions: [{ promptId: '' }] },\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Prompt',\n\t\t\t\t\t\t\t\tname: 'promptOptions',\n\t\t\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdisplayName: 'Prompt ID',\n\t\t\t\t\t\t\t\t\t\tname: 'promptId',\n\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\tdescription: 'The unique identifier of the prompt template to use',\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\tdisplayName: 'Version',\n\t\t\t\t\t\t\t\t\t\tname: 'version',\n\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\tdescription: 'Optional version of the prompt template',\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\tdisplayName: 'Variables',\n\t\t\t\t\t\t\t\t\t\tname: 'variables',\n\t\t\t\t\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\t\t\t\t\tdefault: '{}',\n\t\t\t\t\t\t\t\t\t\tdescription: 'Variables to be substituted into the prompt template',\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\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst version = this.getNode().typeVersion;\n\t\tconst modelName =\n\t\t\tversion >= 1.2\n\t\t\t\t? (this.getNodeParameter('model.value', itemIndex) as string)\n\t\t\t\t: (this.getNodeParameter('model', itemIndex) as string);\n\n\t\tconst responsesApiEnabled = this.getNodeParameter('responsesApiEnabled', itemIndex, false);\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as ModelOptions;\n\n\t\tconst configuration: ClientOptions = {};\n\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\t\tlet customHeaderName: string | undefined;\n\t\tif (\n\t\t\tcredentials.header &&\n\t\t\ttypeof credentials.headerName === 'string' &&\n\t\t\tcredentials.headerName &&\n\t\t\ttypeof credentials.headerValue === 'string'\n\t\t) {\n\t\t\tconfiguration.defaultHeaders = {\n\t\t\t\t[credentials.headerName]: credentials.headerValue,\n\t\t\t};\n\t\t\tcustomHeaderName = credentials.headerName;\n\t\t}\n\n\t\t// Extra options to send to OpenAI, that are not directly supported by LangChain\n\t\tconst modelKwargs: Record<string, unknown> = {};\n\t\tif (responsesApiEnabled) {\n\t\t\tconst kwargs = prepareAdditionalResponsesParams(options);\n\t\t\tObject.assign(modelKwargs, kwargs);\n\t\t} else {\n\t\t\tif (options.responseFormat) modelKwargs.response_format = { type: options.responseFormat };\n\t\t\tif (options.reasoningEffort && ['low', 'medium', 'high'].includes(options.reasoningEffort)) {\n\t\t\t\tmodelKwargs.reasoning_effort = options.reasoningEffort;\n\t\t\t}\n\t\t}\n\n\t\tconst includedOptions = pick(options, [\n\t\t\t'frequencyPenalty',\n\t\t\t'maxTokens',\n\t\t\t'presencePenalty',\n\t\t\t'temperature',\n\t\t\t'topP',\n\t\t\t'baseURL',\n\t\t]);\n\n\t\tconst fields: ChatOpenAIFields = {\n\t\t\tapiKey: credentials.apiKey as string,\n\t\t\tmodel: modelName,\n\t\t\t...includedOptions,\n\t\t\ttimeout: options.timeout ?? 60000,\n\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\tconfiguration,\n\t\t\tcallbacks: [\n\t\t\t\tnew N8nLlmTracing(this, { redactedHeaders: customHeaderName ? [customHeaderName] : [] }),\n\t\t\t],\n\t\t\tmodelKwargs,\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this, openAiFailedAttemptHandler),\n\t\t};\n\n\t\t// by default ChatOpenAI can switch to responses API automatically, so force it only on 1.3 and above to keep backwards compatibility\n\t\tif (responsesApiEnabled) {\n\t\t\tfields.useResponsesApi = true;\n\t\t}\n\n\t\tconst model = new ChatOpenAI(fields);\n\n\t\tif (responsesApiEnabled) {\n\t\t\tconst tools = formatBuiltInTools(\n\t\t\t\tthis.getNodeParameter('builtInTools', itemIndex, {}) as IDataObject,\n\t\t\t);\n\t\t\t// pass tools to the model metadata, ToolAgent will use it to create agent configuration\n\t\t\tif (tools.length) {\n\t\t\t\tmodel.metadata = {\n\t\t\t\t\t...model.metadata,\n\t\t\t\t\ttools,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: model,\n\t\t};\n\t}\n}\n"],"mappings":"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","names":["pick"]}
1
+ {"version":3,"sources":["../../../../nodes/llms/LMChatOpenAi/LmChatOpenAi.node.ts"],"sourcesContent":["import { ChatOpenAI, type ChatOpenAIFields, type ClientOptions } from '@langchain/openai';\nimport pick from 'lodash/pick';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeProperties,\n\ttype IDataObject,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n\ttype ISupplyDataFunctions,\n\ttype SupplyData,\n} from 'n8n-workflow';\n\nimport { getProxyAgent } from '@utils/httpProxyAgent';\nimport { getConnectionHintNoticeField } from '@utils/sharedFields';\n\nimport { assertOpenAiCredentialAllowsUrl } from '../../vendors/OpenAi/helpers/credentials';\nimport { openAiFailedAttemptHandler } from '../../vendors/OpenAi/helpers/error-handling';\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\nimport { formatBuiltInTools, prepareAdditionalResponsesParams } from './common';\nimport { searchModels } from './methods/loadModels';\nimport type { ModelOptions } from './types';\n\nconst INCLUDE_JSON_WARNING: INodeProperties = {\n\tdisplayName:\n\t\t'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.',\n\tname: 'notice',\n\ttype: 'notice',\n\tdefault: '',\n};\n\nconst completionsResponseFormat: INodeProperties = {\n\tdisplayName: 'Response Format',\n\tname: 'responseFormat',\n\tdefault: 'text',\n\ttype: 'options',\n\toptions: [\n\t\t{\n\t\t\tname: 'Text',\n\t\t\tvalue: 'text',\n\t\t\tdescription: 'Regular text response',\n\t\t},\n\t\t{\n\t\t\tname: 'JSON',\n\t\t\tvalue: 'json_object',\n\t\t\tdescription:\n\t\t\t\t'Enables JSON mode, which should guarantee the message the model generates is valid JSON',\n\t\t},\n\t],\n};\n\nconst jsonSchemaExample = `{\n \"type\": \"object\",\n \"properties\": {\n \"message\": {\n \"type\": \"string\"\n }\n },\n \"additionalProperties\": false,\n \"required\": [\"message\"]\n}`;\n\nexport class LmChatOpenAi implements INodeType {\n\tmethods = {\n\t\tlistSearch: {\n\t\t\tsearchModels,\n\t\t},\n\t};\n\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenAI Chat Model',\n\n\t\tname: 'lmChatOpenAi',\n\t\ticon: { light: 'file:openAiLight.svg', dark: 'file:openAiLight.dark.svg' },\n\t\tgroup: ['transform'],\n\t\tversion: [1, 1.1, 1.2, 1.3],\n\t\tdescription: 'For advanced usage with an AI chain',\n\t\tdefaults: {\n\t\t\tname: 'OpenAI Chat Model',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Language Models', 'Root Nodes'],\n\t\t\t\t'Language Models': ['Chat Models (Recommended)'],\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.lmchatopenai/',\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.AiLanguageModel],\n\t\toutputNames: ['Model'],\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(\"/\") || $credentials?.url?.split(\"/\").slice(0,-1).join(\"/\") || \"https://api.openai.com\" }}',\n\t\t},\n\t\tproperties: [\n\t\t\tgetConnectionHintNoticeField([NodeConnectionTypes.AiChain, NodeConnectionTypes.AiAgent]),\n\t\t\t{\n\t\t\t\t...INCLUDE_JSON_WARNING,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.responseFormat': ['json_object'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t...INCLUDE_JSON_WARNING,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.textFormat.textOptions.type': ['json_object'],\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 generate the completion. <a href=\"https://beta.openai.com/docs/models/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\turl: '={{ $parameter.options?.baseURL?.split(\"/\").slice(-1).pop() || $credentials?.url?.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\t// If the baseURL is not set or is set to api.openai.com, include only chat models\n\t\t\t\t\t\t\t\t\t\t\tpass: `={{\n\t\t\t\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\t\t\t($credentials?.url && !$credentials.url.startsWith('https://api.openai.com/')) ||\n\t\t\t\t\t\t\t\t\t\t\t\t$responseItem.id.startsWith('ft:') ||\n\t\t\t\t\t\t\t\t\t\t\t\t$responseItem.id.startsWith('o1') ||\n\t\t\t\t\t\t\t\t\t\t\t\t$responseItem.id.startsWith('o3') ||\n\t\t\t\t\t\t\t\t\t\t\t\t($responseItem.id.startsWith('gpt-') && !$responseItem.id.includes('instruct'))\n\t\t\t\t\t\t\t\t\t\t\t}}`,\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-4o-mini',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\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: 'resourceLocator',\n\t\t\t\tdefault: { mode: 'list', value: 'gpt-4.1-mini' },\n\t\t\t\trequired: true,\n\t\t\t\tmodes: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'From List',\n\t\t\t\t\t\tname: 'list',\n\t\t\t\t\t\ttype: 'list',\n\t\t\t\t\t\tplaceholder: 'Select a model...',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tsearchListMethod: 'searchModels',\n\t\t\t\t\t\t\tsearchable: true,\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: 'ID',\n\t\t\t\t\t\tname: 'id',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tplaceholder: 'gpt-4.1-mini',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdescription: 'The model. Choose from the list, or specify an ID.',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { lte: 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:\n\t\t\t\t\t'When using non-OpenAI models via \"Base URL\" override, not all models might be chat-compatible or support other features, like tools calling or JSON response format',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.baseURL': [{ _cnd: { exists: true } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Use Responses API',\n\t\t\t\tname: 'responsesApiEnabled',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: true,\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether to use the Responses API to generate the response. <a href=\"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatopenai/#use-responses-api\">Learn more</a>.',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Built-in Tools',\n\t\t\t\tname: 'builtInTools',\n\t\t\t\tplaceholder: 'Add Built-in Tool',\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: 'Web Search',\n\t\t\t\t\t\tname: 'webSearch',\n\t\t\t\t\t\ttype: 'collection',\n\t\t\t\t\t\tdefault: { searchContextSize: 'medium' },\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Search Context Size',\n\t\t\t\t\t\t\t\tname: 'searchContextSize',\n\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\tdefault: 'medium',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'High level guidance for the amount of context window space to use for the search',\n\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t{ name: 'Low', value: 'low' },\n\t\t\t\t\t\t\t\t\t{ name: 'Medium', value: 'medium' },\n\t\t\t\t\t\t\t\t\t{ name: 'High', value: 'high' },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Web Search Allowed Domains',\n\t\t\t\t\t\t\t\tname: 'allowedDomains',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Comma-separated list of domains to search. Only domains in this list will be searched.',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. google.com, wikipedia.org',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Country',\n\t\t\t\t\t\t\t\tname: 'country',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. US, GB',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'City',\n\t\t\t\t\t\t\t\tname: 'city',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. New York, London',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Region',\n\t\t\t\t\t\t\t\tname: 'region',\n\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\tplaceholder: 'e.g. New York, London',\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: 'File Search',\n\t\t\t\t\t\tname: 'fileSearch',\n\t\t\t\t\t\ttype: 'collection',\n\t\t\t\t\t\tdefault: { vectorStoreIds: '[]' },\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Vector Store IDs',\n\t\t\t\t\t\t\t\tname: 'vectorStoreIds',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'The vector store IDs to use for the file search. Vector stores are managed via OpenAI Dashboard. <a href=\"https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatopenai/#built-in-tools\">Learn more</a>.',\n\t\t\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\t\t\tdefault: '[]',\n\t\t\t\t\t\t\t\trequired: true,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Filters',\n\t\t\t\t\t\t\t\tname: 'filters',\n\t\t\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\t\t\tdefault: '{}',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Max Results',\n\t\t\t\t\t\t\t\tname: 'maxResults',\n\t\t\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\t\t\ttypeOptions: { minValue: 1, maxValue: 50 },\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: 'Code Interpreter',\n\t\t\t\t\t\tname: 'codeInterpreter',\n\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\tdefault: true,\n\t\t\t\t\t\tdescription: 'Whether to allow the model to execute code in a sandboxed environment',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: '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.1 } }],\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: 'Frequency Penalty',\n\t\t\t\t\t\tname: 'frequencyPenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim\",\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\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\t...completionsResponseFormat,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { lt: 1.3 } }],\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\t...completionsResponseFormat,\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [false],\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: 'Response Format',\n\t\t\t\t\t\tname: 'textFormat',\n\t\t\t\t\t\ttype: 'fixedCollection',\n\t\t\t\t\t\tdefault: { textOptions: [{ type: 'text' }] },\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Text',\n\t\t\t\t\t\t\t\tname: 'textOptions',\n\t\t\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdisplayName: 'Type',\n\t\t\t\t\t\t\t\t\t\tname: 'type',\n\t\t\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'Text', value: 'text' },\n\t\t\t\t\t\t\t\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'JSON Schema (recommended)', value: 'json_schema' },\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'JSON Object', value: 'json_object' },\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\tdisplayName: 'Verbosity',\n\t\t\t\t\t\t\t\t\t\tname: 'verbosity',\n\t\t\t\t\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\t\t\t\t\tdefault: 'medium',\n\t\t\t\t\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'Low', value: 'low' },\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'Medium', value: 'medium' },\n\t\t\t\t\t\t\t\t\t\t\t{ name: 'High', value: 'high' },\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\tdisplayName: 'Name',\n\t\t\t\t\t\t\t\t\t\tname: 'name',\n\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\tdefault: 'my_schema',\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t'The name of the response format. Must be a-z, A-Z, 0-9, or contain underscores and dashes, with a maximum length of 64.',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: ['json_schema'],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayName:\n\t\t\t\t\t\t\t\t\t\t\t'All properties in the schema must be set to \"required\", when using \"strict\" mode.',\n\t\t\t\t\t\t\t\t\t\tname: 'requiredNotice',\n\t\t\t\t\t\t\t\t\t\ttype: 'notice',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\tstrict: [true],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayName: 'Schema',\n\t\t\t\t\t\t\t\t\t\tname: 'schema',\n\t\t\t\t\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\t\t\t\t\tdefault: jsonSchemaExample,\n\t\t\t\t\t\t\t\t\t\tdescription: 'The schema of the response format',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: ['json_schema'],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayName: 'Description',\n\t\t\t\t\t\t\t\t\t\tname: 'description',\n\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\tdescription: 'The description of the response format',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: ['json_schema'],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayName: 'Strict',\n\t\t\t\t\t\t\t\t\t\tname: 'strict',\n\t\t\t\t\t\t\t\t\t\ttype: 'boolean',\n\t\t\t\t\t\t\t\t\t\tdefault: false,\n\t\t\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t\t\t'Whether to require that the AI will always generate responses that match the provided JSON Schema',\n\t\t\t\t\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t\t\t\t\ttype: ['json_schema'],\n\t\t\t\t\t\t\t\t\t\t\t},\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\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Presence Penalty',\n\t\t\t\t\t\tname: 'presencePenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics\",\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: 'Sampling Temperature',\n\t\t\t\t\t\tname: 'temperature',\n\t\t\t\t\t\tdefault: 0.7,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.',\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: 'Reasoning Effort',\n\t\t\t\t\t\tname: 'reasoningEffort',\n\t\t\t\t\t\tdefault: 'medium',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls the amount of reasoning tokens to use. A value of \"low\" will favor speed and economical token usage, \"high\" will favor more complete reasoning at the cost of more tokens generated and slower responses.',\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: 'Low',\n\t\t\t\t\t\t\t\tvalue: 'low',\n\t\t\t\t\t\t\t\tdescription: 'Favors speed and economical token usage',\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: 'Medium',\n\t\t\t\t\t\t\t\tvalue: 'medium',\n\t\t\t\t\t\t\t\tdescription: 'Balance between speed and reasoning accuracy',\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: 'High',\n\t\t\t\t\t\t\t\tvalue: 'high',\n\t\t\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\t\t'Favors more complete reasoning at the cost of more tokens generated and slower responses',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t// reasoning_effort is only available on o1, o1-versioned, or on o3-mini and beyond, and gpt-5 models. Not on o1-mini or other GPT-models.\n\t\t\t\t\t\t\t\t'/model': [{ _cnd: { regex: '(^o1([-\\\\d]+)?$)|(^o[3-9].*)|(^gpt-5.*)' } }],\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: 'Timeout',\n\t\t\t\t\t\tname: 'timeout',\n\t\t\t\t\t\tdefault: 60000,\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\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: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\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: 'Conversation ID',\n\t\t\t\t\t\tname: 'conversationId',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The conversation that this response belongs to. Input items and output items from this response are automatically added to this conversation after this response completes.',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Prompt Cache Key',\n\t\t\t\t\t\tname: 'promptCacheKey',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Used by OpenAI to cache responses for similar requests to optimize your cache hit rates',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Safety Identifier',\n\t\t\t\t\t\tname: 'safetyIdentifier',\n\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"A stable identifier used to help detect users of your application that may be violating OpenAI's usage policies. The IDs should be a string that uniquely identifies each user.\",\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Service Tier',\n\t\t\t\t\t\tname: 'serviceTier',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\tdefault: 'auto',\n\t\t\t\t\t\tdescription: 'The service tier to use for the request',\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{ name: 'Auto', value: 'auto' },\n\t\t\t\t\t\t\t{ name: 'Flex', value: 'flex' },\n\t\t\t\t\t\t\t{ name: 'Default', value: 'default' },\n\t\t\t\t\t\t\t{ name: 'Priority', value: 'priority' },\n\t\t\t\t\t\t],\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Metadata',\n\t\t\t\t\t\tname: 'metadata',\n\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Set of 16 key-value pairs that can be attached to an object. This can be useful for storing additional information about the object in a structured format, and querying for objects via API or the dashboard. Keys are strings with a maximum length of 64 characters. Values are strings with a maximum length of 512 characters.',\n\t\t\t\t\t\tdefault: '{}',\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Top Logprobs',\n\t\t\t\t\t\tname: 'topLogprobs',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'An integer between 0 and 20 specifying the number of most likely tokens to return at each token position, each with an associated log probability',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tminValue: 0,\n\t\t\t\t\t\t\tmaxValue: 20,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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: 'Prompt',\n\t\t\t\t\t\tname: 'promptConfig',\n\t\t\t\t\t\ttype: 'fixedCollection',\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Configure the reusable prompt template configured via OpenAI Dashboard. <a href=\"https://platform.openai.com/docs/guides/prompt-engineering#reusable-prompts\">Learn more</a>.',\n\t\t\t\t\t\tdefault: { promptOptions: [{ promptId: '' }] },\n\t\t\t\t\t\toptions: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tdisplayName: 'Prompt',\n\t\t\t\t\t\t\t\tname: 'promptOptions',\n\t\t\t\t\t\t\t\tvalues: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tdisplayName: 'Prompt ID',\n\t\t\t\t\t\t\t\t\t\tname: 'promptId',\n\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\tdescription: 'The unique identifier of the prompt template to use',\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\tdisplayName: 'Version',\n\t\t\t\t\t\t\t\t\t\tname: 'version',\n\t\t\t\t\t\t\t\t\t\ttype: 'string',\n\t\t\t\t\t\t\t\t\t\tdefault: '',\n\t\t\t\t\t\t\t\t\t\tdescription: 'Optional version of the prompt template',\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\tdisplayName: 'Variables',\n\t\t\t\t\t\t\t\t\t\tname: 'variables',\n\t\t\t\t\t\t\t\t\t\ttype: 'json',\n\t\t\t\t\t\t\t\t\t\tdefault: '{}',\n\t\t\t\t\t\t\t\t\t\tdescription: 'Variables to be substituted into the prompt template',\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\tdisplayOptions: {\n\t\t\t\t\t\t\tshow: {\n\t\t\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t\t\t\t'/responsesApiEnabled': [true],\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\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst version = this.getNode().typeVersion;\n\t\tconst modelName =\n\t\t\tversion >= 1.2\n\t\t\t\t? (this.getNodeParameter('model.value', itemIndex) as string)\n\t\t\t\t: (this.getNodeParameter('model', itemIndex) as string);\n\n\t\tconst responsesApiEnabled = this.getNodeParameter('responsesApiEnabled', itemIndex, false);\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as ModelOptions;\n\n\t\tconst configuration: ClientOptions = {};\n\n\t\tif (options.baseURL) {\n\t\t\tassertOpenAiCredentialAllowsUrl(this.getNode(), credentials, 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\t\tlet customHeaderName: string | undefined;\n\t\tif (\n\t\t\tcredentials.header &&\n\t\t\ttypeof credentials.headerName === 'string' &&\n\t\t\tcredentials.headerName &&\n\t\t\ttypeof credentials.headerValue === 'string'\n\t\t) {\n\t\t\tconfiguration.defaultHeaders = {\n\t\t\t\t[credentials.headerName]: credentials.headerValue,\n\t\t\t};\n\t\t\tcustomHeaderName = credentials.headerName;\n\t\t}\n\n\t\t// Extra options to send to OpenAI, that are not directly supported by LangChain\n\t\tconst modelKwargs: Record<string, unknown> = {};\n\t\tif (responsesApiEnabled) {\n\t\t\tconst kwargs = prepareAdditionalResponsesParams(options);\n\t\t\tObject.assign(modelKwargs, kwargs);\n\t\t} else {\n\t\t\tif (options.responseFormat) modelKwargs.response_format = { type: options.responseFormat };\n\t\t\tif (options.reasoningEffort && ['low', 'medium', 'high'].includes(options.reasoningEffort)) {\n\t\t\t\tmodelKwargs.reasoning_effort = options.reasoningEffort;\n\t\t\t}\n\t\t}\n\n\t\tconst includedOptions = pick(options, [\n\t\t\t'frequencyPenalty',\n\t\t\t'maxTokens',\n\t\t\t'presencePenalty',\n\t\t\t'temperature',\n\t\t\t'topP',\n\t\t\t'baseURL',\n\t\t]);\n\n\t\tconst fields: ChatOpenAIFields = {\n\t\t\tapiKey: credentials.apiKey as string,\n\t\t\tmodel: modelName,\n\t\t\t...includedOptions,\n\t\t\ttimeout: options.timeout ?? 60000,\n\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\tconfiguration,\n\t\t\tcallbacks: [\n\t\t\t\tnew N8nLlmTracing(this, { redactedHeaders: customHeaderName ? [customHeaderName] : [] }),\n\t\t\t],\n\t\t\tmodelKwargs,\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this, openAiFailedAttemptHandler),\n\t\t};\n\n\t\t// by default ChatOpenAI can switch to responses API automatically, so force it only on 1.3 and above to keep backwards compatibility\n\t\tif (responsesApiEnabled) {\n\t\t\tfields.useResponsesApi = true;\n\t\t}\n\n\t\tconst model = new ChatOpenAI(fields);\n\n\t\tif (responsesApiEnabled) {\n\t\t\tconst tools = formatBuiltInTools(\n\t\t\t\tthis.getNodeParameter('builtInTools', itemIndex, {}) as IDataObject,\n\t\t\t);\n\t\t\t// pass tools to the model metadata, ToolAgent will use it to create agent configuration\n\t\t\tif (tools.length) {\n\t\t\t\tmodel.metadata = {\n\t\t\t\t\t...model.metadata,\n\t\t\t\t\ttools,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\tresponse: model,\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,oBAAsE;AACtE,kBAAiB;AACjB,0BAQO;AAEP,4BAA8B;AAC9B,0BAA6C;AAE7C,yBAAgD;AAChD,4BAA2C;AAC3C,wCAA+C;AAC/C,2BAA8B;AAC9B,oBAAqE;AACrE,wBAA6B;AAG7B,MAAM,uBAAwC;AAAA,EAC7C,aACC;AAAA,EACD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AACV;AAEA,MAAM,4BAA6C;AAAA,EAClD,aAAa;AAAA,EACb,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS;AAAA,IACR;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aAAa;AAAA,IACd;AAAA,IACA;AAAA,MACC,MAAM;AAAA,MACN,OAAO;AAAA,MACP,aACC;AAAA,IACF;AAAA,EACD;AACD;AAEA,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWnB,MAAM,aAAkC;AAAA,EAAxC;AACN,mBAAU;AAAA,MACT,YAAY;AAAA,QACX;AAAA,MACD;AAAA,IACD;AAEA,uBAAoC;AAAA,MACnC,aAAa;AAAA,MAEb,MAAM;AAAA,MACN,MAAM,EAAE,OAAO,wBAAwB,MAAM,4BAA4B;AAAA,MACzE,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS,CAAC,GAAG,KAAK,KAAK,GAAG;AAAA,MAC1B,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACN,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,mBAAmB,YAAY;AAAA,UACpC,mBAAmB,CAAC,2BAA2B;AAAA,QAChD;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MAEA,QAAQ,CAAC;AAAA,MAET,SAAS,CAAC,wCAAoB,eAAe;AAAA,MAC7C,aAAa,CAAC,OAAO;AAAA,MACrB,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,YACX,kDAA6B,CAAC,wCAAoB,SAAS,wCAAoB,OAAO,CAAC;AAAA,QACvF;AAAA,UACC,GAAG;AAAA,UACH,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,2BAA2B,CAAC,aAAa;AAAA,YAC1C;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,GAAG;AAAA,UACH,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,wCAAwC,CAAC,aAAa;AAAA,YACvD;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aACC;AAAA,UACD,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;AAAA,wBAEX,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAQP;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,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,YACpC;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS,EAAE,MAAM,QAAQ,OAAO,eAAe;AAAA,UAC/C,UAAU;AAAA,UACV,OAAO;AAAA,YACN;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,aAAa;AAAA,gBACZ,kBAAkB;AAAA,gBAClB,YAAY;AAAA,cACb;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,YACd;AAAA,UACD;AAAA,UACA,aAAa;AAAA,UACb,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,YACpC;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aACC;AAAA,UACD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,oBAAoB,CAAC,EAAE,MAAM,EAAE,QAAQ,KAAK,EAAE,CAAC;AAAA,YAChD;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aACC;AAAA,UACD,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,YACpC;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,aAAa;AAAA,UACb,MAAM;AAAA,UACN,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,EAAE,mBAAmB,SAAS;AAAA,cACvC,SAAS;AAAA,gBACR;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,aACC;AAAA,kBACD,SAAS;AAAA,oBACR,EAAE,MAAM,OAAO,OAAO,MAAM;AAAA,oBAC5B,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,oBAClC,EAAE,MAAM,QAAQ,OAAO,OAAO;AAAA,kBAC/B;AAAA,gBACD;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,aACC;AAAA,kBACD,aAAa;AAAA,gBACd;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,aAAa;AAAA,gBACd;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,aAAa;AAAA,gBACd;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,aAAa;AAAA,gBACd;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,EAAE,gBAAgB,KAAK;AAAA,cAChC,SAAS;AAAA,gBACR;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,aACC;AAAA,kBACD,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,UAAU;AAAA,gBACX;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,gBACV;AAAA,gBACA;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,MAAM;AAAA,kBACN,SAAS;AAAA,kBACT,aAAa,EAAE,UAAU,GAAG,UAAU,GAAG;AAAA,gBAC1C;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa;AAAA,YACd;AAAA,UACD;AAAA,UACA,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,cACnC,wBAAwB,CAAC,IAAI;AAAA,YAC9B;AAAA,UACD;AAAA,QACD;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,cACN,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,gBACpC;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa,EAAE,UAAU,GAAG,UAAU,IAAI,iBAAiB,EAAE;AAAA,cAC7D,aACC;AAAA,cACD,MAAM;AAAA,YACP;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,cACD,MAAM;AAAA,cACN,aAAa;AAAA,gBACZ,UAAU;AAAA,cACX;AAAA,YACD;AAAA,YACA;AAAA,cACC,GAAG;AAAA,cACH,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;AAAA,gBACnC;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,GAAG;AAAA,cACH,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,kBACnC,wBAAwB,CAAC,KAAK;AAAA,gBAC/B;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,EAAE,aAAa,CAAC,EAAE,MAAM,OAAO,CAAC,EAAE;AAAA,cAC3C,SAAS;AAAA,gBACR;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,QAAQ;AAAA,oBACP;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,SAAS;AAAA,wBACR,EAAE,MAAM,QAAQ,OAAO,OAAO;AAAA;AAAA,wBAE9B,EAAE,MAAM,6BAA6B,OAAO,cAAc;AAAA,wBAC1D,EAAE,MAAM,eAAe,OAAO,cAAc;AAAA,sBAC7C;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,SAAS;AAAA,wBACR,EAAE,MAAM,OAAO,OAAO,MAAM;AAAA,wBAC5B,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,wBAClC,EAAE,MAAM,QAAQ,OAAO,OAAO;AAAA,sBAC/B;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,aACC;AAAA,sBACD,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,MAAM,CAAC,aAAa;AAAA,wBACrB;AAAA,sBACD;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aACC;AAAA,sBACD,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,QAAQ,CAAC,IAAI;AAAA,wBACd;AAAA,sBACD;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,aAAa;AAAA,sBACb,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,MAAM,CAAC,aAAa;AAAA,wBACrB;AAAA,sBACD;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,aAAa;AAAA,sBACb,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,MAAM,CAAC,aAAa;AAAA,wBACrB;AAAA,sBACD;AAAA,oBACD;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,aACC;AAAA,sBACD,gBAAgB;AAAA,wBACf,MAAM;AAAA,0BACL,MAAM,CAAC,aAAa;AAAA,wBACrB;AAAA,sBACD;AAAA,oBACD;AAAA,kBACD;AAAA,gBACD;AAAA,cACD;AAAA,cACA,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,kBACnC,wBAAwB,CAAC,IAAI;AAAA,gBAC9B;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa,EAAE,UAAU,GAAG,UAAU,IAAI,iBAAiB,EAAE;AAAA,cAC7D,aACC;AAAA,cACD,MAAM;AAAA,YACP;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa,EAAE,UAAU,GAAG,UAAU,GAAG,iBAAiB,EAAE;AAAA,cAC5D,aACC;AAAA,cACD,MAAM;AAAA,YACP;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,cACD,MAAM;AAAA,cACN,SAAS;AAAA,gBACR;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,aAAa;AAAA,gBACd;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,aAAa;AAAA,gBACd;AAAA,gBACA;AAAA,kBACC,MAAM;AAAA,kBACN,OAAO;AAAA,kBACP,aACC;AAAA,gBACF;AAAA,cACD;AAAA,cACA,gBAAgB;AAAA,gBACf,MAAM;AAAA;AAAA,kBAEL,UAAU,CAAC,EAAE,MAAM,EAAE,OAAO,0CAA0C,EAAE,CAAC;AAAA,gBAC1E;AAAA,cACD;AAAA,YACD;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,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa,EAAE,UAAU,GAAG,UAAU,GAAG,iBAAiB,EAAE;AAAA,cAC5D,aACC;AAAA,cACD,MAAM;AAAA,YACP;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,cACD,MAAM;AAAA,cACN,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,kBACnC,wBAAwB,CAAC,IAAI;AAAA,gBAC9B;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,cACD,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,kBACnC,wBAAwB,CAAC,IAAI;AAAA,gBAC9B;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,cACD,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,kBACnC,wBAAwB,CAAC,IAAI;AAAA,gBAC9B;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aAAa;AAAA,cACb,SAAS;AAAA,gBACR,EAAE,MAAM,QAAQ,OAAO,OAAO;AAAA,gBAC9B,EAAE,MAAM,QAAQ,OAAO,OAAO;AAAA,gBAC9B,EAAE,MAAM,WAAW,OAAO,UAAU;AAAA,gBACpC,EAAE,MAAM,YAAY,OAAO,WAAW;AAAA,cACvC;AAAA,cACA,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,kBACnC,wBAAwB,CAAC,IAAI;AAAA,gBAC9B;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aACC;AAAA,cACD,SAAS;AAAA,cACT,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,kBACnC,wBAAwB,CAAC,IAAI;AAAA,gBAC9B;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS;AAAA,cACT,aACC;AAAA,cACD,aAAa;AAAA,gBACZ,UAAU;AAAA,gBACV,UAAU;AAAA,cACX;AAAA,cACA,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,kBACnC,wBAAwB,CAAC,IAAI;AAAA,gBAC9B;AAAA,cACD;AAAA,YACD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,aACC;AAAA,cACD,SAAS,EAAE,eAAe,CAAC,EAAE,UAAU,GAAG,CAAC,EAAE;AAAA,cAC7C,SAAS;AAAA,gBACR;AAAA,kBACC,aAAa;AAAA,kBACb,MAAM;AAAA,kBACN,QAAQ;AAAA,oBACP;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,aAAa;AAAA,oBACd;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,aAAa;AAAA,oBACd;AAAA,oBACA;AAAA,sBACC,aAAa;AAAA,sBACb,MAAM;AAAA,sBACN,MAAM;AAAA,sBACN,SAAS;AAAA,sBACT,aAAa;AAAA,oBACd;AAAA,kBACD;AAAA,gBACD;AAAA,cACD;AAAA,cACA,gBAAgB;AAAA,gBACf,MAAM;AAAA,kBACL,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,kBACnC,wBAAwB,CAAC,IAAI;AAAA,gBAC9B;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,WAAuC,WAAwC;AACpF,UAAM,cAAc,MAAM,KAAK,eAAe,WAAW;AAEzD,UAAM,UAAU,KAAK,QAAQ,EAAE;AAC/B,UAAM,YACL,WAAW,MACP,KAAK,iBAAiB,eAAe,SAAS,IAC9C,KAAK,iBAAiB,SAAS,SAAS;AAE7C,UAAM,sBAAsB,KAAK,iBAAiB,uBAAuB,WAAW,KAAK;AAEzF,UAAM,UAAU,KAAK,iBAAiB,WAAW,WAAW,CAAC,CAAC;AAE9D,UAAM,gBAA+B,CAAC;AAEtC,QAAI,QAAQ,SAAS;AACpB,8DAAgC,KAAK,QAAQ,GAAG,aAAa,QAAQ,OAAO;AAC5E,oBAAc,UAAU,QAAQ;AAAA,IACjC,WAAW,YAAY,KAAK;AAC3B,oBAAc,UAAU,YAAY;AAAA,IACrC;AAEA,QAAI,cAAc,SAAS;AAC1B,oBAAc,eAAe;AAAA,QAC5B,gBAAY,qCAAc,cAAc,WAAW,2BAA2B;AAAA,MAC/E;AAAA,IACD;AACA,QAAI;AACJ,QACC,YAAY,UACZ,OAAO,YAAY,eAAe,YAClC,YAAY,cACZ,OAAO,YAAY,gBAAgB,UAClC;AACD,oBAAc,iBAAiB;AAAA,QAC9B,CAAC,YAAY,UAAU,GAAG,YAAY;AAAA,MACvC;AACA,yBAAmB,YAAY;AAAA,IAChC;AAGA,UAAM,cAAuC,CAAC;AAC9C,QAAI,qBAAqB;AACxB,YAAM,aAAS,gDAAiC,OAAO;AACvD,aAAO,OAAO,aAAa,MAAM;AAAA,IAClC,OAAO;AACN,UAAI,QAAQ,eAAgB,aAAY,kBAAkB,EAAE,MAAM,QAAQ,eAAe;AACzF,UAAI,QAAQ,mBAAmB,CAAC,OAAO,UAAU,MAAM,EAAE,SAAS,QAAQ,eAAe,GAAG;AAC3F,oBAAY,mBAAmB,QAAQ;AAAA,MACxC;AAAA,IACD;AAEA,UAAM,sBAAkB,YAAAA,SAAK,SAAS;AAAA,MACrC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACD,CAAC;AAED,UAAM,SAA2B;AAAA,MAChC,QAAQ,YAAY;AAAA,MACpB,OAAO;AAAA,MACP,GAAG;AAAA,MACH,SAAS,QAAQ,WAAW;AAAA,MAC5B,YAAY,QAAQ,cAAc;AAAA,MAClC;AAAA,MACA,WAAW;AAAA,QACV,IAAI,mCAAc,MAAM,EAAE,iBAAiB,mBAAmB,CAAC,gBAAgB,IAAI,CAAC,EAAE,CAAC;AAAA,MACxF;AAAA,MACA;AAAA,MACA,qBAAiB,kEAA+B,MAAM,gDAA0B;AAAA,IACjF;AAGA,QAAI,qBAAqB;AACxB,aAAO,kBAAkB;AAAA,IAC1B;AAEA,UAAM,QAAQ,IAAI,yBAAW,MAAM;AAEnC,QAAI,qBAAqB;AACxB,YAAM,YAAQ;AAAA,QACb,KAAK,iBAAiB,gBAAgB,WAAW,CAAC,CAAC;AAAA,MACpD;AAEA,UAAI,MAAM,QAAQ;AACjB,cAAM,WAAW;AAAA,UAChB,GAAG,MAAM;AAAA,UACT;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,MACN,UAAU;AAAA,IACX;AAAA,EACD;AACD;","names":["pick"]}
@@ -32,11 +32,16 @@ __export(loadModels_exports, {
32
32
  });
33
33
  module.exports = __toCommonJS(loadModels_exports);
34
34
  var import_openai = __toESM(require("openai"));
35
+ var import_credentials = require("../../../vendors/OpenAi/helpers/credentials");
35
36
  var import_modelFiltering = require("../../../vendors/OpenAi/helpers/modelFiltering");
36
37
  var import_httpProxyAgent = require("../../../../utils/httpProxyAgent");
37
38
  async function searchModels(filter) {
38
39
  const credentials = await this.getCredentials("openAiApi");
39
- const baseURL = this.getNodeParameter("options.baseURL", "") || credentials.url || "https://api.openai.com/v1";
40
+ const baseUrlOverride = this.getNodeParameter("options.baseURL", "");
41
+ if (baseUrlOverride) {
42
+ (0, import_credentials.assertOpenAiCredentialAllowsUrl)(this.getNode(), credentials, baseUrlOverride);
43
+ }
44
+ const baseURL = baseUrlOverride || credentials.url || "https://api.openai.com/v1";
40
45
  const openai = new import_openai.default({
41
46
  baseURL,
42
47
  apiKey: credentials.apiKey,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../nodes/llms/LMChatOpenAi/methods/loadModels.ts"],"sourcesContent":["import type { ILoadOptionsFunctions, INodeListSearchResult } from 'n8n-workflow';\nimport OpenAI from 'openai';\n\nimport { shouldIncludeModel } from '../../../vendors/OpenAi/helpers/modelFiltering';\nimport { getProxyAgent } from '@utils/httpProxyAgent';\n\nexport async function searchModels(\n\tthis: ILoadOptionsFunctions,\n\tfilter?: string,\n): Promise<INodeListSearchResult> {\n\tconst credentials = await this.getCredentials('openAiApi');\n\tconst baseURL =\n\t\t(this.getNodeParameter('options.baseURL', '') as string) ||\n\t\t(credentials.url as string) ||\n\t\t'https://api.openai.com/v1';\n\n\tconst openai = new OpenAI({\n\t\tbaseURL,\n\t\tapiKey: credentials.apiKey as string,\n\t\tfetchOptions: {\n\t\t\tdispatcher: getProxyAgent(baseURL),\n\t\t},\n\t});\n\tconst { data: models = [] } = await openai.models.list();\n\n\tconst url = baseURL && new URL(baseURL);\n\tconst isCustomAPI = !!(url && !['api.openai.com', 'ai-assistant.n8n.io'].includes(url.hostname));\n\n\tconst filteredModels = models.filter((model: { id: string }) => {\n\t\tconst includeModel = shouldIncludeModel(model.id, isCustomAPI);\n\n\t\tif (!filter) return includeModel;\n\n\t\treturn includeModel && model.id.toLowerCase().includes(filter.toLowerCase());\n\t});\n\n\tfilteredModels.sort((a, b) => a.id.localeCompare(b.id));\n\n\treturn {\n\t\tresults: filteredModels.map((model: { id: string }) => ({\n\t\t\tname: model.id,\n\t\t\tvalue: model.id,\n\t\t})),\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAAmB;AAEnB,4BAAmC;AACnC,4BAA8B;AAE9B,eAAsB,aAErB,QACiC;AACjC,QAAM,cAAc,MAAM,KAAK,eAAe,WAAW;AACzD,QAAM,UACJ,KAAK,iBAAiB,mBAAmB,EAAE,KAC3C,YAAY,OACb;AAED,QAAM,SAAS,IAAI,cAAAA,QAAO;AAAA,IACzB;AAAA,IACA,QAAQ,YAAY;AAAA,IACpB,cAAc;AAAA,MACb,gBAAY,qCAAc,OAAO;AAAA,IAClC;AAAA,EACD,CAAC;AACD,QAAM,EAAE,MAAM,SAAS,CAAC,EAAE,IAAI,MAAM,OAAO,OAAO,KAAK;AAEvD,QAAM,MAAM,WAAW,IAAI,IAAI,OAAO;AACtC,QAAM,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,kBAAkB,qBAAqB,EAAE,SAAS,IAAI,QAAQ;AAE9F,QAAM,iBAAiB,OAAO,OAAO,CAAC,UAA0B;AAC/D,UAAM,mBAAe,0CAAmB,MAAM,IAAI,WAAW;AAE7D,QAAI,CAAC,OAAQ,QAAO;AAEpB,WAAO,gBAAgB,MAAM,GAAG,YAAY,EAAE,SAAS,OAAO,YAAY,CAAC;AAAA,EAC5E,CAAC;AAED,iBAAe,KAAK,CAAC,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;AAEtD,SAAO;AAAA,IACN,SAAS,eAAe,IAAI,CAAC,WAA2B;AAAA,MACvD,MAAM,MAAM;AAAA,MACZ,OAAO,MAAM;AAAA,IACd,EAAE;AAAA,EACH;AACD;","names":["OpenAI"]}
1
+ {"version":3,"sources":["../../../../../nodes/llms/LMChatOpenAi/methods/loadModels.ts"],"sourcesContent":["import type { ILoadOptionsFunctions, INodeListSearchResult } from 'n8n-workflow';\nimport OpenAI from 'openai';\n\nimport { assertOpenAiCredentialAllowsUrl } from '../../../vendors/OpenAi/helpers/credentials';\nimport { shouldIncludeModel } from '../../../vendors/OpenAi/helpers/modelFiltering';\nimport { getProxyAgent } from '@utils/httpProxyAgent';\n\nexport async function searchModels(\n\tthis: ILoadOptionsFunctions,\n\tfilter?: string,\n): Promise<INodeListSearchResult> {\n\tconst credentials = await this.getCredentials('openAiApi');\n\tconst baseUrlOverride = this.getNodeParameter('options.baseURL', '') as string;\n\tif (baseUrlOverride) {\n\t\tassertOpenAiCredentialAllowsUrl(this.getNode(), credentials, baseUrlOverride);\n\t}\n\tconst baseURL = baseUrlOverride || (credentials.url as string) || 'https://api.openai.com/v1';\n\n\tconst openai = new OpenAI({\n\t\tbaseURL,\n\t\tapiKey: credentials.apiKey as string,\n\t\tfetchOptions: {\n\t\t\tdispatcher: getProxyAgent(baseURL),\n\t\t},\n\t});\n\tconst { data: models = [] } = await openai.models.list();\n\n\tconst url = baseURL && new URL(baseURL);\n\tconst isCustomAPI = !!(url && !['api.openai.com', 'ai-assistant.n8n.io'].includes(url.hostname));\n\n\tconst filteredModels = models.filter((model: { id: string }) => {\n\t\tconst includeModel = shouldIncludeModel(model.id, isCustomAPI);\n\n\t\tif (!filter) return includeModel;\n\n\t\treturn includeModel && model.id.toLowerCase().includes(filter.toLowerCase());\n\t});\n\n\tfilteredModels.sort((a, b) => a.id.localeCompare(b.id));\n\n\treturn {\n\t\tresults: filteredModels.map((model: { id: string }) => ({\n\t\t\tname: model.id,\n\t\t\tvalue: model.id,\n\t\t})),\n\t};\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,oBAAmB;AAEnB,yBAAgD;AAChD,4BAAmC;AACnC,4BAA8B;AAE9B,eAAsB,aAErB,QACiC;AACjC,QAAM,cAAc,MAAM,KAAK,eAAe,WAAW;AACzD,QAAM,kBAAkB,KAAK,iBAAiB,mBAAmB,EAAE;AACnE,MAAI,iBAAiB;AACpB,4DAAgC,KAAK,QAAQ,GAAG,aAAa,eAAe;AAAA,EAC7E;AACA,QAAM,UAAU,mBAAoB,YAAY,OAAkB;AAElE,QAAM,SAAS,IAAI,cAAAA,QAAO;AAAA,IACzB;AAAA,IACA,QAAQ,YAAY;AAAA,IACpB,cAAc;AAAA,MACb,gBAAY,qCAAc,OAAO;AAAA,IAClC;AAAA,EACD,CAAC;AACD,QAAM,EAAE,MAAM,SAAS,CAAC,EAAE,IAAI,MAAM,OAAO,OAAO,KAAK;AAEvD,QAAM,MAAM,WAAW,IAAI,IAAI,OAAO;AACtC,QAAM,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,kBAAkB,qBAAqB,EAAE,SAAS,IAAI,QAAQ;AAE9F,QAAM,iBAAiB,OAAO,OAAO,CAAC,UAA0B;AAC/D,UAAM,mBAAe,0CAAmB,MAAM,IAAI,WAAW;AAE7D,QAAI,CAAC,OAAQ,QAAO;AAEpB,WAAO,gBAAgB,MAAM,GAAG,YAAY,EAAE,SAAS,OAAO,YAAY,CAAC;AAAA,EAC5E,CAAC;AAED,iBAAe,KAAK,CAAC,GAAG,MAAM,EAAE,GAAG,cAAc,EAAE,EAAE,CAAC;AAEtD,SAAO;AAAA,IACN,SAAS,eAAe,IAAI,CAAC,WAA2B;AAAA,MACvD,MAAM,MAAM;AAAA,MACZ,OAAO,MAAM;AAAA,IACd,EAAE;AAAA,EACH;AACD;","names":["OpenAI"]}
@@ -26,6 +26,7 @@ var import_n8n_workflow = require("n8n-workflow");
26
26
  var import_httpProxyAgent = require("../../../utils/httpProxyAgent");
27
27
  var import_n8nLlmFailedAttemptHandler = require("../n8nLlmFailedAttemptHandler");
28
28
  var import_N8nLlmTracing = require("../N8nLlmTracing");
29
+ var import_credentials = require("../../vendors/OpenAi/helpers/credentials");
29
30
  class LmOpenAi {
30
31
  constructor() {
31
32
  this.description = {
@@ -195,13 +196,21 @@ class LmOpenAi {
195
196
  const results = [];
196
197
  const options = this.getNodeParameter("options", {});
197
198
  let uri = "https://api.openai.com/v1/models";
199
+ let allowedDomains;
198
200
  if (options.baseURL) {
201
+ const credentials = await this.getCredentials("openAiApi");
202
+ allowedDomains = (0, import_credentials.assertOpenAiCredentialAllowsUrl)(
203
+ this.getNode(),
204
+ credentials,
205
+ options.baseURL
206
+ );
199
207
  uri = `${options.baseURL}/models`;
200
208
  }
201
209
  const { data } = await this.helpers.requestWithAuthentication.call(this, "openAiApi", {
202
210
  method: "GET",
203
211
  uri,
204
- json: true
212
+ json: true,
213
+ allowedDomains
205
214
  });
206
215
  for (const model of data) {
207
216
  if (!options.baseURL && !model.owned_by?.startsWith("system")) continue;
@@ -227,6 +236,7 @@ class LmOpenAi {
227
236
  }
228
237
  };
229
238
  if (options.baseURL) {
239
+ (0, import_credentials.assertOpenAiCredentialAllowsUrl)(this.getNode(), credentials, options.baseURL);
230
240
  configuration.baseURL = options.baseURL;
231
241
  }
232
242
  const model = new import_openai.OpenAI({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../nodes/llms/LMOpenAi/LmOpenAi.node.ts"],"sourcesContent":["import { OpenAI, type ClientOptions } from '@langchain/openai';\nimport { NodeConnectionTypes } from 'n8n-workflow';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tILoadOptionsFunctions,\n} from 'n8n-workflow';\n\nimport { getProxyAgent } from '@utils/httpProxyAgent';\n\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\ntype LmOpenAiOptions = {\n\tbaseURL?: string;\n\tfrequencyPenalty?: number;\n\tmaxTokens?: number;\n\tpresencePenalty?: number;\n\ttemperature?: number;\n\ttimeout?: number;\n\tmaxRetries?: number;\n\ttopP?: number;\n};\n\nexport class LmOpenAi implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenAI Model',\n\n\t\tname: 'lmOpenAi',\n\t\thidden: true,\n\t\ticon: { light: 'file:openAiLight.svg', dark: 'file:openAiLight.dark.svg' },\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'For advanced usage with an AI chain',\n\t\tdefaults: {\n\t\t\tname: 'OpenAI Model',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Language Models', 'Root Nodes'],\n\t\t\t\t'Language Models': ['Text Completion Models'],\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.lmopenai/',\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.AiLanguageModel],\n\t\toutputNames: ['Model'],\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:\n\t\t\t\t\t'This node is using OpenAI completions which are now deprecated. Please use the OpenAI Chat Model node instead.',\n\t\t\t\tname: 'deprecated',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\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: 'resourceLocator',\n\t\t\t\tdefault: { mode: 'list', value: 'gpt-3.5-turbo-instruct' },\n\t\t\t\trequired: true,\n\t\t\t\tdescription:\n\t\t\t\t\t'The model which will generate the completion. <a href=\"https://beta.openai.com/docs/models/overview\">Learn more</a>.',\n\t\t\t\tmodes: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'From List',\n\t\t\t\t\t\tname: 'list',\n\t\t\t\t\t\ttype: 'list',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tsearchListMethod: 'openAiModelSearch',\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: 'ID',\n\t\t\t\t\t\tname: 'id',\n\t\t\t\t\t\ttype: 'string',\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\tvalue: '={{$parameter.model.value}}',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'When using non OpenAI models via Base URL override, not all models might be chat-compatible or support other features, like tools calling or JSON response format.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.baseURL': [{ _cnd: { exists: true } }],\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: '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: 'Frequency Penalty',\n\t\t\t\t\t\tname: 'frequencyPenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim\",\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\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: 'Presence Penalty',\n\t\t\t\t\t\tname: 'presencePenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics\",\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: 'Sampling Temperature',\n\t\t\t\t\t\tname: 'temperature',\n\t\t\t\t\t\tdefault: 0.7,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.',\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: 60000,\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\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: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\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\tmethods = {\n\t\tlistSearch: {\n\t\t\tasync openAiModelSearch(this: ILoadOptionsFunctions) {\n\t\t\t\tconst results = [];\n\n\t\t\t\tconst options = this.getNodeParameter('options', {}) as LmOpenAiOptions;\n\n\t\t\t\tlet uri = 'https://api.openai.com/v1/models';\n\n\t\t\t\tif (options.baseURL) {\n\t\t\t\t\turi = `${options.baseURL}/models`;\n\t\t\t\t}\n\n\t\t\t\tconst { data } = (await this.helpers.requestWithAuthentication.call(this, 'openAiApi', {\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\turi,\n\t\t\t\t\tjson: true,\n\t\t\t\t})) as { data: Array<{ owned_by: string; id: string }> };\n\n\t\t\t\tfor (const model of data) {\n\t\t\t\t\tif (!options.baseURL && !model.owned_by?.startsWith('system')) continue;\n\t\t\t\t\tresults.push({\n\t\t\t\t\t\tname: model.id,\n\t\t\t\t\t\tvalue: model.id,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn { results };\n\t\t\t},\n\t\t},\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst modelName = this.getNodeParameter('model', itemIndex, '', {\n\t\t\textractValue: true,\n\t\t}) as string;\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tbaseURL?: string;\n\t\t\tfrequencyPenalty?: number;\n\t\t\tmaxTokens?: number;\n\t\t\tpresencePenalty?: number;\n\t\t\ttemperature?: number;\n\t\t\ttimeout?: number;\n\t\t\tmaxRetries?: number;\n\t\t\ttopP?: number;\n\t\t};\n\n\t\tconst configuration: ClientOptions = {\n\t\t\tfetchOptions: {\n\t\t\t\tdispatcher: getProxyAgent(options.baseURL ?? 'https://api.openai.com/v1'),\n\t\t\t},\n\t\t};\n\n\t\tif (options.baseURL) {\n\t\t\tconfiguration.baseURL = options.baseURL;\n\t\t}\n\n\t\tconst model = new OpenAI({\n\t\t\tapiKey: credentials.apiKey as string,\n\t\t\tmodel: modelName,\n\t\t\t...options,\n\t\t\tconfiguration,\n\t\t\ttimeout: options.timeout ?? 60000,\n\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\tcallbacks: [new N8nLlmTracing(this)],\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this),\n\t\t});\n\n\t\treturn {\n\t\t\tresponse: model,\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../../nodes/llms/LMOpenAi/LmOpenAi.node.ts"],"sourcesContent":["import { OpenAI, type ClientOptions } from '@langchain/openai';\nimport { NodeConnectionTypes } from 'n8n-workflow';\nimport type {\n\tINodeType,\n\tINodeTypeDescription,\n\tISupplyDataFunctions,\n\tSupplyData,\n\tILoadOptionsFunctions,\n} from 'n8n-workflow';\n\nimport { getProxyAgent } from '@utils/httpProxyAgent';\n\nimport { makeN8nLlmFailedAttemptHandler } from '../n8nLlmFailedAttemptHandler';\nimport { N8nLlmTracing } from '../N8nLlmTracing';\n\nimport { assertOpenAiCredentialAllowsUrl } from '../../vendors/OpenAi/helpers/credentials';\n\ntype LmOpenAiOptions = {\n\tbaseURL?: string;\n\tfrequencyPenalty?: number;\n\tmaxTokens?: number;\n\tpresencePenalty?: number;\n\ttemperature?: number;\n\ttimeout?: number;\n\tmaxRetries?: number;\n\ttopP?: number;\n};\n\nexport class LmOpenAi implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'OpenAI Model',\n\n\t\tname: 'lmOpenAi',\n\t\thidden: true,\n\t\ticon: { light: 'file:openAiLight.svg', dark: 'file:openAiLight.dark.svg' },\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\tdescription: 'For advanced usage with an AI chain',\n\t\tdefaults: {\n\t\t\tname: 'OpenAI Model',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Language Models', 'Root Nodes'],\n\t\t\t\t'Language Models': ['Text Completion Models'],\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.lmopenai/',\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.AiLanguageModel],\n\t\toutputNames: ['Model'],\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:\n\t\t\t\t\t'This node is using OpenAI completions which are now deprecated. Please use the OpenAI Chat Model node instead.',\n\t\t\t\tname: 'deprecated',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\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: 'resourceLocator',\n\t\t\t\tdefault: { mode: 'list', value: 'gpt-3.5-turbo-instruct' },\n\t\t\t\trequired: true,\n\t\t\t\tdescription:\n\t\t\t\t\t'The model which will generate the completion. <a href=\"https://beta.openai.com/docs/models/overview\">Learn more</a>.',\n\t\t\t\tmodes: [\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'From List',\n\t\t\t\t\t\tname: 'list',\n\t\t\t\t\t\ttype: 'list',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tsearchListMethod: 'openAiModelSearch',\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: 'ID',\n\t\t\t\t\t\tname: 'id',\n\t\t\t\t\t\ttype: 'string',\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\tvalue: '={{$parameter.model.value}}',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'When using non OpenAI models via Base URL override, not all models might be chat-compatible or support other features, like tools calling or JSON response format.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'/options.baseURL': [{ _cnd: { exists: true } }],\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: '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: 'Frequency Penalty',\n\t\t\t\t\t\tname: 'frequencyPenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim\",\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: 'Maximum Number of Tokens',\n\t\t\t\t\t\tname: 'maxTokens',\n\t\t\t\t\t\tdefault: -1,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The maximum number of tokens to generate in the completion. Most models have a context length of 2048 tokens (except for the newest models, which support 32,768).',\n\t\t\t\t\t\ttype: 'number',\n\t\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\t\tmaxValue: 32768,\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: 'Presence Penalty',\n\t\t\t\t\t\tname: 'presencePenalty',\n\t\t\t\t\t\tdefault: 0,\n\t\t\t\t\t\ttypeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t\"Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics\",\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: 'Sampling Temperature',\n\t\t\t\t\t\tname: 'temperature',\n\t\t\t\t\t\tdefault: 0.7,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.',\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: 60000,\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\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: 'Top P',\n\t\t\t\t\t\tname: 'topP',\n\t\t\t\t\t\tdefault: 1,\n\t\t\t\t\t\ttypeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',\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\tmethods = {\n\t\tlistSearch: {\n\t\t\tasync openAiModelSearch(this: ILoadOptionsFunctions) {\n\t\t\t\tconst results = [];\n\n\t\t\t\tconst options = this.getNodeParameter('options', {}) as LmOpenAiOptions;\n\n\t\t\t\tlet uri = 'https://api.openai.com/v1/models';\n\t\t\t\tlet allowedDomains: string | undefined;\n\n\t\t\t\tif (options.baseURL) {\n\t\t\t\t\tconst credentials = await this.getCredentials('openAiApi');\n\t\t\t\t\tallowedDomains = assertOpenAiCredentialAllowsUrl(\n\t\t\t\t\t\tthis.getNode(),\n\t\t\t\t\t\tcredentials,\n\t\t\t\t\t\toptions.baseURL,\n\t\t\t\t\t);\n\t\t\t\t\turi = `${options.baseURL}/models`;\n\t\t\t\t}\n\n\t\t\t\tconst { data } = (await this.helpers.requestWithAuthentication.call(this, 'openAiApi', {\n\t\t\t\t\tmethod: 'GET',\n\t\t\t\t\turi,\n\t\t\t\t\tjson: true,\n\t\t\t\t\tallowedDomains,\n\t\t\t\t})) as { data: Array<{ owned_by: string; id: string }> };\n\n\t\t\t\tfor (const model of data) {\n\t\t\t\t\tif (!options.baseURL && !model.owned_by?.startsWith('system')) continue;\n\t\t\t\t\tresults.push({\n\t\t\t\t\t\tname: model.id,\n\t\t\t\t\t\tvalue: model.id,\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn { results };\n\t\t\t},\n\t\t},\n\t};\n\n\tasync supplyData(this: ISupplyDataFunctions, itemIndex: number): Promise<SupplyData> {\n\t\tconst credentials = await this.getCredentials('openAiApi');\n\n\t\tconst modelName = this.getNodeParameter('model', itemIndex, '', {\n\t\t\textractValue: true,\n\t\t}) as string;\n\n\t\tconst options = this.getNodeParameter('options', itemIndex, {}) as {\n\t\t\tbaseURL?: string;\n\t\t\tfrequencyPenalty?: number;\n\t\t\tmaxTokens?: number;\n\t\t\tpresencePenalty?: number;\n\t\t\ttemperature?: number;\n\t\t\ttimeout?: number;\n\t\t\tmaxRetries?: number;\n\t\t\ttopP?: number;\n\t\t};\n\n\t\tconst configuration: ClientOptions = {\n\t\t\tfetchOptions: {\n\t\t\t\tdispatcher: getProxyAgent(options.baseURL ?? 'https://api.openai.com/v1'),\n\t\t\t},\n\t\t};\n\n\t\tif (options.baseURL) {\n\t\t\tassertOpenAiCredentialAllowsUrl(this.getNode(), credentials, options.baseURL);\n\t\t\tconfiguration.baseURL = options.baseURL;\n\t\t}\n\n\t\tconst model = new OpenAI({\n\t\t\tapiKey: credentials.apiKey as string,\n\t\t\tmodel: modelName,\n\t\t\t...options,\n\t\t\tconfiguration,\n\t\t\ttimeout: options.timeout ?? 60000,\n\t\t\tmaxRetries: options.maxRetries ?? 2,\n\t\t\tcallbacks: [new N8nLlmTracing(this)],\n\t\t\tonFailedAttempt: makeN8nLlmFailedAttemptHandler(this),\n\t\t});\n\n\t\treturn {\n\t\t\tresponse: model,\n\t\t};\n\t}\n}\n"],"mappings":"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","names":[]}
@@ -42,6 +42,7 @@ var import_base = require("@langchain/core/callbacks/base");
42
42
  var import_pick = __toESM(require("lodash/pick"));
43
43
  var import_n8n_workflow = require("n8n-workflow");
44
44
  var import_helpers = require("../../utils/helpers");
45
+ var import_redact_headers = require("./redact-headers");
45
46
  var _parentRunIndex;
46
47
  class N8nNonEstimatingTracing extends import_base.BaseCallbackHandler {
47
48
  constructor(executionFunctions, options) {
@@ -62,7 +63,8 @@ class N8nNonEstimatingTracing extends import_base.BaseCallbackHandler {
62
63
  this.runsMap = {};
63
64
  this.options = {
64
65
  // Default(OpenAI format) parser
65
- errorDescriptionMapper: (error) => error.description
66
+ errorDescriptionMapper: (error) => error.description,
67
+ redactedHeaders: []
66
68
  };
67
69
  this.options = { ...this.options, ...options };
68
70
  }
@@ -102,7 +104,10 @@ class N8nNonEstimatingTracing extends import_base.BaseCallbackHandler {
102
104
  async handleLLMStart(llm, prompts, runId) {
103
105
  const estimatedTokens = 0;
104
106
  const sourceNodeRunIndex = __privateGet(this, _parentRunIndex) !== void 0 ? __privateGet(this, _parentRunIndex) + this.executionFunctions.getNextRunIndex() : void 0;
105
- const options = llm.type === "constructor" ? llm.kwargs : llm;
107
+ const options = (0, import_redact_headers.redactHeaderValues)(
108
+ llm.type === "constructor" ? llm.kwargs : llm,
109
+ this.options.redactedHeaders
110
+ );
106
111
  const { index } = this.executionFunctions.addInputData(
107
112
  this.connectionType,
108
113
  [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../nodes/llms/N8nNonEstimatingTracing.ts"],"sourcesContent":["import { BaseCallbackHandler } from '@langchain/core/callbacks/base';\nimport type { SerializedFields } from '@langchain/core/dist/load/map_keys';\nimport type {\n\tSerialized,\n\tSerializedNotImplemented,\n\tSerializedSecret,\n} from '@langchain/core/load/serializable';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type { LLMResult } from '@langchain/core/outputs';\nimport pick from 'lodash/pick';\nimport type { IDataObject, ISupplyDataFunctions, JsonObject } from 'n8n-workflow';\nimport { NodeConnectionTypes, NodeError, NodeOperationError } from 'n8n-workflow';\n\nimport { logAiEvent } from '@utils/helpers';\n\ntype RunDetail = {\n\tindex: number;\n\tmessages: BaseMessage[] | string[] | string;\n\toptions: SerializedSecret | SerializedNotImplemented | SerializedFields;\n};\n\nexport class N8nNonEstimatingTracing extends BaseCallbackHandler {\n\tname = 'N8nNonEstimatingTracing';\n\n\t// This flag makes sure that LangChain will wait for the handlers to finish before continuing\n\t// This is crucial for the handleLLMError handler to work correctly (it should be called before the error is propagated to the root node)\n\tawaitHandlers = true;\n\n\tconnectionType = NodeConnectionTypes.AiLanguageModel;\n\n\t#parentRunIndex?: number;\n\n\t/**\n\t * A map to associate LLM run IDs to run details.\n\t * Key: Unique identifier for each LLM run (run ID)\n\t * Value: RunDetails object\n\t *\n\t */\n\trunsMap: Record<string, RunDetail> = {};\n\n\toptions = {\n\t\t// Default(OpenAI format) parser\n\t\terrorDescriptionMapper: (error: NodeError) => error.description,\n\t};\n\n\tconstructor(\n\t\tprivate executionFunctions: ISupplyDataFunctions,\n\t\toptions?: {\n\t\t\terrorDescriptionMapper?: (error: NodeError) => string;\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis.options = { ...this.options, ...options };\n\t}\n\n\tasync handleLLMEnd(output: LLMResult, runId: string) {\n\t\t// The fallback should never happen since handleLLMStart should always set the run details\n\t\t// but just in case, we set the index to the length of the runsMap\n\t\tconst runDetails = this.runsMap[runId] ?? { index: Object.keys(this.runsMap).length };\n\n\t\toutput.generations = output.generations.map((gen) =>\n\t\t\tgen.map((g) => pick(g, ['text', 'generationInfo'])),\n\t\t);\n\n\t\tconst tokenUsageEstimate = {\n\t\t\tcompletionTokens: 0,\n\t\t\tpromptTokens: 0,\n\t\t\ttotalTokens: 0,\n\t\t};\n\t\tconst response: {\n\t\t\tresponse: { generations: LLMResult['generations'] };\n\t\t\ttokenUsageEstimate?: typeof tokenUsageEstimate;\n\t\t} = {\n\t\t\tresponse: { generations: output.generations },\n\t\t};\n\n\t\tresponse.tokenUsageEstimate = tokenUsageEstimate;\n\n\t\tconst parsedMessages =\n\t\t\ttypeof runDetails.messages === 'string'\n\t\t\t\t? runDetails.messages\n\t\t\t\t: runDetails.messages.map((message) => {\n\t\t\t\t\t\tif (typeof message === 'string') return message;\n\t\t\t\t\t\tif (typeof message?.toJSON === 'function') return message.toJSON();\n\n\t\t\t\t\t\treturn message;\n\t\t\t\t\t});\n\n\t\tconst sourceNodeRunIndex =\n\t\t\tthis.#parentRunIndex !== undefined ? this.#parentRunIndex + runDetails.index : undefined;\n\n\t\tthis.executionFunctions.addOutputData(\n\t\t\tthis.connectionType,\n\t\t\trunDetails.index,\n\t\t\t[[{ json: { ...response } }]],\n\t\t\tundefined,\n\t\t\tsourceNodeRunIndex,\n\t\t);\n\n\t\tlogAiEvent(this.executionFunctions, 'ai-llm-generated-output', {\n\t\t\tmessages: parsedMessages,\n\t\t\toptions: runDetails.options,\n\t\t\tresponse,\n\t\t});\n\t}\n\n\tasync handleLLMStart(llm: Serialized, prompts: string[], runId: string) {\n\t\tconst estimatedTokens = 0;\n\t\tconst sourceNodeRunIndex =\n\t\t\tthis.#parentRunIndex !== undefined\n\t\t\t\t? this.#parentRunIndex + this.executionFunctions.getNextRunIndex()\n\t\t\t\t: undefined;\n\n\t\tconst options = llm.type === 'constructor' ? llm.kwargs : llm;\n\t\tconst { index } = this.executionFunctions.addInputData(\n\t\t\tthis.connectionType,\n\t\t\t[\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\tmessages: prompts,\n\t\t\t\t\t\t\testimatedTokens,\n\t\t\t\t\t\t\toptions,\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\tsourceNodeRunIndex,\n\t\t);\n\n\t\t// Save the run details for later use when processing `handleLLMEnd` event\n\t\tthis.runsMap[runId] = {\n\t\t\tindex,\n\t\t\toptions,\n\t\t\tmessages: prompts,\n\t\t};\n\t}\n\n\tasync handleLLMError(error: IDataObject | Error, runId: string, parentRunId?: string) {\n\t\tconst runDetails = this.runsMap[runId] ?? { index: Object.keys(this.runsMap).length };\n\n\t\t// Filter out non-x- headers to avoid leaking sensitive information in logs\n\t\tif (typeof error === 'object' && error?.hasOwnProperty('headers')) {\n\t\t\tconst errorWithHeaders = error as { headers: Record<string, unknown> };\n\n\t\t\tObject.keys(errorWithHeaders.headers).forEach((key) => {\n\t\t\t\tif (!key.startsWith('x-')) {\n\t\t\t\t\tdelete errorWithHeaders.headers[key];\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (error instanceof NodeError) {\n\t\t\tif (this.options.errorDescriptionMapper) {\n\t\t\t\terror.description = this.options.errorDescriptionMapper(error);\n\t\t\t}\n\n\t\t\tthis.executionFunctions.addOutputData(this.connectionType, runDetails.index, error);\n\t\t} else {\n\t\t\t// If the error is not a NodeError, we wrap it in a NodeOperationError\n\t\t\tthis.executionFunctions.addOutputData(\n\t\t\t\tthis.connectionType,\n\t\t\t\trunDetails.index,\n\t\t\t\tnew NodeOperationError(this.executionFunctions.getNode(), error as JsonObject, {\n\t\t\t\t\tfunctionality: 'configuration-node',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tlogAiEvent(this.executionFunctions, 'ai-llm-errored', {\n\t\t\terror: Object.keys(error).length === 0 ? error.toString() : error,\n\t\t\trunId,\n\t\t\tparentRunId,\n\t\t});\n\t}\n\n\t// Used to associate subsequent runs with the correct parent run in subnodes of subnodes\n\tsetParentRunIndex(runIndex: number) {\n\t\tthis.#parentRunIndex = runIndex;\n\t}\n}\n"],"mappings":"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","names":["pick"]}
1
+ {"version":3,"sources":["../../../nodes/llms/N8nNonEstimatingTracing.ts"],"sourcesContent":["import { BaseCallbackHandler } from '@langchain/core/callbacks/base';\nimport type { SerializedFields } from '@langchain/core/dist/load/map_keys';\nimport type {\n\tSerialized,\n\tSerializedNotImplemented,\n\tSerializedSecret,\n} from '@langchain/core/load/serializable';\nimport type { BaseMessage } from '@langchain/core/messages';\nimport type { LLMResult } from '@langchain/core/outputs';\nimport pick from 'lodash/pick';\nimport type { IDataObject, ISupplyDataFunctions, JsonObject } from 'n8n-workflow';\nimport { NodeConnectionTypes, NodeError, NodeOperationError } from 'n8n-workflow';\n\nimport { logAiEvent } from '@utils/helpers';\n\nimport { redactHeaderValues } from './redact-headers';\n\ntype RunDetail = {\n\tindex: number;\n\tmessages: BaseMessage[] | string[] | string;\n\toptions: SerializedSecret | SerializedNotImplemented | SerializedFields;\n};\n\nexport class N8nNonEstimatingTracing extends BaseCallbackHandler {\n\tname = 'N8nNonEstimatingTracing';\n\n\t// This flag makes sure that LangChain will wait for the handlers to finish before continuing\n\t// This is crucial for the handleLLMError handler to work correctly (it should be called before the error is propagated to the root node)\n\tawaitHandlers = true;\n\n\tconnectionType = NodeConnectionTypes.AiLanguageModel;\n\n\t#parentRunIndex?: number;\n\n\t/**\n\t * A map to associate LLM run IDs to run details.\n\t * Key: Unique identifier for each LLM run (run ID)\n\t * Value: RunDetails object\n\t *\n\t */\n\trunsMap: Record<string, RunDetail> = {};\n\n\toptions = {\n\t\t// Default(OpenAI format) parser\n\t\terrorDescriptionMapper: (error: NodeError) => error.description,\n\t\tredactedHeaders: [] as string[],\n\t};\n\n\tconstructor(\n\t\tprivate executionFunctions: ISupplyDataFunctions,\n\t\toptions?: {\n\t\t\terrorDescriptionMapper?: (error: NodeError) => string;\n\t\t\tredactedHeaders?: string[];\n\t\t},\n\t) {\n\t\tsuper();\n\t\tthis.options = { ...this.options, ...options };\n\t}\n\n\tasync handleLLMEnd(output: LLMResult, runId: string) {\n\t\t// The fallback should never happen since handleLLMStart should always set the run details\n\t\t// but just in case, we set the index to the length of the runsMap\n\t\tconst runDetails = this.runsMap[runId] ?? { index: Object.keys(this.runsMap).length };\n\n\t\toutput.generations = output.generations.map((gen) =>\n\t\t\tgen.map((g) => pick(g, ['text', 'generationInfo'])),\n\t\t);\n\n\t\tconst tokenUsageEstimate = {\n\t\t\tcompletionTokens: 0,\n\t\t\tpromptTokens: 0,\n\t\t\ttotalTokens: 0,\n\t\t};\n\t\tconst response: {\n\t\t\tresponse: { generations: LLMResult['generations'] };\n\t\t\ttokenUsageEstimate?: typeof tokenUsageEstimate;\n\t\t} = {\n\t\t\tresponse: { generations: output.generations },\n\t\t};\n\n\t\tresponse.tokenUsageEstimate = tokenUsageEstimate;\n\n\t\tconst parsedMessages =\n\t\t\ttypeof runDetails.messages === 'string'\n\t\t\t\t? runDetails.messages\n\t\t\t\t: runDetails.messages.map((message) => {\n\t\t\t\t\t\tif (typeof message === 'string') return message;\n\t\t\t\t\t\tif (typeof message?.toJSON === 'function') return message.toJSON();\n\n\t\t\t\t\t\treturn message;\n\t\t\t\t\t});\n\n\t\tconst sourceNodeRunIndex =\n\t\t\tthis.#parentRunIndex !== undefined ? this.#parentRunIndex + runDetails.index : undefined;\n\n\t\tthis.executionFunctions.addOutputData(\n\t\t\tthis.connectionType,\n\t\t\trunDetails.index,\n\t\t\t[[{ json: { ...response } }]],\n\t\t\tundefined,\n\t\t\tsourceNodeRunIndex,\n\t\t);\n\n\t\tlogAiEvent(this.executionFunctions, 'ai-llm-generated-output', {\n\t\t\tmessages: parsedMessages,\n\t\t\toptions: runDetails.options,\n\t\t\tresponse,\n\t\t});\n\t}\n\n\tasync handleLLMStart(llm: Serialized, prompts: string[], runId: string) {\n\t\tconst estimatedTokens = 0;\n\t\tconst sourceNodeRunIndex =\n\t\t\tthis.#parentRunIndex !== undefined\n\t\t\t\t? this.#parentRunIndex + this.executionFunctions.getNextRunIndex()\n\t\t\t\t: undefined;\n\n\t\tconst options = redactHeaderValues(\n\t\t\tllm.type === 'constructor' ? llm.kwargs : llm,\n\t\t\tthis.options.redactedHeaders,\n\t\t);\n\t\tconst { index } = this.executionFunctions.addInputData(\n\t\t\tthis.connectionType,\n\t\t\t[\n\t\t\t\t[\n\t\t\t\t\t{\n\t\t\t\t\t\tjson: {\n\t\t\t\t\t\t\tmessages: prompts,\n\t\t\t\t\t\t\testimatedTokens,\n\t\t\t\t\t\t\toptions,\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\tsourceNodeRunIndex,\n\t\t);\n\n\t\t// Save the run details for later use when processing `handleLLMEnd` event\n\t\tthis.runsMap[runId] = {\n\t\t\tindex,\n\t\t\toptions,\n\t\t\tmessages: prompts,\n\t\t};\n\t}\n\n\tasync handleLLMError(error: IDataObject | Error, runId: string, parentRunId?: string) {\n\t\tconst runDetails = this.runsMap[runId] ?? { index: Object.keys(this.runsMap).length };\n\n\t\t// Filter out non-x- headers to avoid leaking sensitive information in logs\n\t\tif (typeof error === 'object' && error?.hasOwnProperty('headers')) {\n\t\t\tconst errorWithHeaders = error as { headers: Record<string, unknown> };\n\n\t\t\tObject.keys(errorWithHeaders.headers).forEach((key) => {\n\t\t\t\tif (!key.startsWith('x-')) {\n\t\t\t\t\tdelete errorWithHeaders.headers[key];\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tif (error instanceof NodeError) {\n\t\t\tif (this.options.errorDescriptionMapper) {\n\t\t\t\terror.description = this.options.errorDescriptionMapper(error);\n\t\t\t}\n\n\t\t\tthis.executionFunctions.addOutputData(this.connectionType, runDetails.index, error);\n\t\t} else {\n\t\t\t// If the error is not a NodeError, we wrap it in a NodeOperationError\n\t\t\tthis.executionFunctions.addOutputData(\n\t\t\t\tthis.connectionType,\n\t\t\t\trunDetails.index,\n\t\t\t\tnew NodeOperationError(this.executionFunctions.getNode(), error as JsonObject, {\n\t\t\t\t\tfunctionality: 'configuration-node',\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\tlogAiEvent(this.executionFunctions, 'ai-llm-errored', {\n\t\t\terror: Object.keys(error).length === 0 ? error.toString() : error,\n\t\t\trunId,\n\t\t\tparentRunId,\n\t\t});\n\t}\n\n\t// Used to associate subsequent runs with the correct parent run in subnodes of subnodes\n\tsetParentRunIndex(runIndex: number) {\n\t\tthis.#parentRunIndex = runIndex;\n\t}\n}\n"],"mappings":"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","names":["pick"]}
@@ -18,6 +18,7 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
  var redact_headers_exports = {};
20
20
  __export(redact_headers_exports, {
21
+ isRecord: () => isRecord,
21
22
  redactHeaderValues: () => redactHeaderValues
22
23
  });
23
24
  module.exports = __toCommonJS(redact_headers_exports);
@@ -71,6 +72,7 @@ function redactHeaderValues(options, headerNames) {
71
72
  }
72
73
  // Annotate the CommonJS export names for ESM import in node:
73
74
  0 && (module.exports = {
75
+ isRecord,
74
76
  redactHeaderValues
75
77
  });
76
78
  //# sourceMappingURL=redact-headers.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../nodes/llms/redact-headers.ts"],"sourcesContent":["import type { SerializedFields } from '@langchain/core/dist/load/map_keys';\nimport type { SerializedNotImplemented, SerializedSecret } from '@langchain/core/load/serializable';\n\ntype SerializedOptions = SerializedSecret | SerializedNotImplemented | SerializedFields;\n\nconst REDACTED_HEADER_VALUE = '**********';\n\nconst HEADER_CONTAINER_KEYS = ['defaultheaders', 'headers'];\n\nconst ALWAYS_REDACTED_HEADERS = ['authorization', 'x-api-key', 'api-key', 'cookie'];\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction maskHeaderContainer(\n\theaders: Record<string, unknown>,\n\tlowerHeaderNames: string[],\n): Record<string, unknown> {\n\tconst masked = { ...headers };\n\tlet changed = false;\n\tfor (const key of Object.keys(headers)) {\n\t\tconst lowerKey = key.toLowerCase();\n\t\tif (lowerHeaderNames.includes(lowerKey) || ALWAYS_REDACTED_HEADERS.includes(lowerKey)) {\n\t\t\tmasked[key] = REDACTED_HEADER_VALUE;\n\t\t\tchanged = true;\n\t\t}\n\t}\n\treturn changed ? masked : headers;\n}\n\nfunction redactValue(value: unknown, lowerHeaderNames: string[]): unknown {\n\tif (Array.isArray(value)) {\n\t\tlet result: unknown[] | undefined;\n\t\tvalue.forEach((item, index) => {\n\t\t\tconst masked = redactValue(item, lowerHeaderNames);\n\t\t\tif (masked !== item) {\n\t\t\t\tresult = result ?? [...value];\n\t\t\t\tresult[index] = masked;\n\t\t\t}\n\t\t});\n\t\treturn result ?? value;\n\t}\n\n\tif (!isRecord(value)) return value;\n\n\tlet result: Record<string, unknown> | undefined;\n\tfor (const [key, child] of Object.entries(value)) {\n\t\tconst masked =\n\t\t\tHEADER_CONTAINER_KEYS.includes(key.toLowerCase()) && isRecord(child)\n\t\t\t\t? maskHeaderContainer(child, lowerHeaderNames)\n\t\t\t\t: redactValue(child, lowerHeaderNames);\n\t\tif (masked !== child) {\n\t\t\tresult = result ?? { ...value };\n\t\t\tresult[key] = masked;\n\t\t}\n\t}\n\treturn result ?? value;\n}\n\nexport function redactHeaderValues(\n\toptions: SerializedOptions,\n\theaderNames: string[],\n): SerializedOptions {\n\tconst redacted = redactValue(\n\t\toptions,\n\t\theaderNames.map((name) => name.toLowerCase()),\n\t);\n\treturn isRecord(redacted) ? redacted : options;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,MAAM,wBAAwB;AAE9B,MAAM,wBAAwB,CAAC,kBAAkB,SAAS;AAE1D,MAAM,0BAA0B,CAAC,iBAAiB,aAAa,WAAW,QAAQ;AAElF,SAAS,SAAS,OAAkD;AACnE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAS,oBACR,SACA,kBAC0B;AAC1B,QAAM,SAAS,EAAE,GAAG,QAAQ;AAC5B,MAAI,UAAU;AACd,aAAW,OAAO,OAAO,KAAK,OAAO,GAAG;AACvC,UAAM,WAAW,IAAI,YAAY;AACjC,QAAI,iBAAiB,SAAS,QAAQ,KAAK,wBAAwB,SAAS,QAAQ,GAAG;AACtF,aAAO,GAAG,IAAI;AACd,gBAAU;AAAA,IACX;AAAA,EACD;AACA,SAAO,UAAU,SAAS;AAC3B;AAEA,SAAS,YAAY,OAAgB,kBAAqC;AACzE,MAAI,MAAM,QAAQ,KAAK,GAAG;AACzB,QAAIA;AACJ,UAAM,QAAQ,CAAC,MAAM,UAAU;AAC9B,YAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,UAAI,WAAW,MAAM;AACpB,QAAAA,UAASA,WAAU,CAAC,GAAG,KAAK;AAC5B,QAAAA,QAAO,KAAK,IAAI;AAAA,MACjB;AAAA,IACD,CAAC;AACD,WAAOA,WAAU;AAAA,EAClB;AAEA,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,MAAI;AACJ,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,UAAM,SACL,sBAAsB,SAAS,IAAI,YAAY,CAAC,KAAK,SAAS,KAAK,IAChE,oBAAoB,OAAO,gBAAgB,IAC3C,YAAY,OAAO,gBAAgB;AACvC,QAAI,WAAW,OAAO;AACrB,eAAS,UAAU,EAAE,GAAG,MAAM;AAC9B,aAAO,GAAG,IAAI;AAAA,IACf;AAAA,EACD;AACA,SAAO,UAAU;AAClB;AAEO,SAAS,mBACf,SACA,aACoB;AACpB,QAAM,WAAW;AAAA,IAChB;AAAA,IACA,YAAY,IAAI,CAAC,SAAS,KAAK,YAAY,CAAC;AAAA,EAC7C;AACA,SAAO,SAAS,QAAQ,IAAI,WAAW;AACxC;","names":["result"]}
1
+ {"version":3,"sources":["../../../nodes/llms/redact-headers.ts"],"sourcesContent":["import type { SerializedFields } from '@langchain/core/dist/load/map_keys';\nimport type { SerializedNotImplemented, SerializedSecret } from '@langchain/core/load/serializable';\n\ntype SerializedOptions = SerializedSecret | SerializedNotImplemented | SerializedFields;\n\nconst REDACTED_HEADER_VALUE = '**********';\n\nconst HEADER_CONTAINER_KEYS = ['defaultheaders', 'headers'];\n\nconst ALWAYS_REDACTED_HEADERS = ['authorization', 'x-api-key', 'api-key', 'cookie'];\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction maskHeaderContainer(\n\theaders: Record<string, unknown>,\n\tlowerHeaderNames: string[],\n): Record<string, unknown> {\n\tconst masked = { ...headers };\n\tlet changed = false;\n\tfor (const key of Object.keys(headers)) {\n\t\tconst lowerKey = key.toLowerCase();\n\t\tif (lowerHeaderNames.includes(lowerKey) || ALWAYS_REDACTED_HEADERS.includes(lowerKey)) {\n\t\t\tmasked[key] = REDACTED_HEADER_VALUE;\n\t\t\tchanged = true;\n\t\t}\n\t}\n\treturn changed ? masked : headers;\n}\n\nfunction redactValue(value: unknown, lowerHeaderNames: string[]): unknown {\n\tif (Array.isArray(value)) {\n\t\tlet result: unknown[] | undefined;\n\t\tvalue.forEach((item, index) => {\n\t\t\tconst masked = redactValue(item, lowerHeaderNames);\n\t\t\tif (masked !== item) {\n\t\t\t\tresult = result ?? [...value];\n\t\t\t\tresult[index] = masked;\n\t\t\t}\n\t\t});\n\t\treturn result ?? value;\n\t}\n\n\tif (!isRecord(value)) return value;\n\n\tlet result: Record<string, unknown> | undefined;\n\tfor (const [key, child] of Object.entries(value)) {\n\t\tconst masked =\n\t\t\tHEADER_CONTAINER_KEYS.includes(key.toLowerCase()) && isRecord(child)\n\t\t\t\t? maskHeaderContainer(child, lowerHeaderNames)\n\t\t\t\t: redactValue(child, lowerHeaderNames);\n\t\tif (masked !== child) {\n\t\t\tresult = result ?? { ...value };\n\t\t\tresult[key] = masked;\n\t\t}\n\t}\n\treturn result ?? value;\n}\n\nexport function redactHeaderValues(\n\toptions: SerializedOptions,\n\theaderNames: string[],\n): SerializedOptions {\n\tconst redacted = redactValue(\n\t\toptions,\n\t\theaderNames.map((name) => name.toLowerCase()),\n\t);\n\treturn isRecord(redacted) ? redacted : options;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,MAAM,wBAAwB;AAE9B,MAAM,wBAAwB,CAAC,kBAAkB,SAAS;AAE1D,MAAM,0BAA0B,CAAC,iBAAiB,aAAa,WAAW,QAAQ;AAE3E,SAAS,SAAS,OAAkD;AAC1E,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAS,oBACR,SACA,kBAC0B;AAC1B,QAAM,SAAS,EAAE,GAAG,QAAQ;AAC5B,MAAI,UAAU;AACd,aAAW,OAAO,OAAO,KAAK,OAAO,GAAG;AACvC,UAAM,WAAW,IAAI,YAAY;AACjC,QAAI,iBAAiB,SAAS,QAAQ,KAAK,wBAAwB,SAAS,QAAQ,GAAG;AACtF,aAAO,GAAG,IAAI;AACd,gBAAU;AAAA,IACX;AAAA,EACD;AACA,SAAO,UAAU,SAAS;AAC3B;AAEA,SAAS,YAAY,OAAgB,kBAAqC;AACzE,MAAI,MAAM,QAAQ,KAAK,GAAG;AACzB,QAAIA;AACJ,UAAM,QAAQ,CAAC,MAAM,UAAU;AAC9B,YAAM,SAAS,YAAY,MAAM,gBAAgB;AACjD,UAAI,WAAW,MAAM;AACpB,QAAAA,UAASA,WAAU,CAAC,GAAG,KAAK;AAC5B,QAAAA,QAAO,KAAK,IAAI;AAAA,MACjB;AAAA,IACD,CAAC;AACD,WAAOA,WAAU;AAAA,EAClB;AAEA,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAE7B,MAAI;AACJ,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,UAAM,SACL,sBAAsB,SAAS,IAAI,YAAY,CAAC,KAAK,SAAS,KAAK,IAChE,oBAAoB,OAAO,gBAAgB,IAC3C,YAAY,OAAO,gBAAgB;AACvC,QAAI,WAAW,OAAO;AACrB,eAAS,UAAU,EAAE,GAAG,MAAM;AAC9B,aAAO,GAAG,IAAI;AAAA,IACf;AAAA,EACD;AACA,SAAO,UAAU;AAClB;AAEO,SAAS,mBACf,SACA,aACoB;AACpB,QAAM,WAAW;AAAA,IAChB;AAAA,IACA,YAAY,IAAI,CAAC,SAAS,KAAK,YAAY,CAAC;AAAA,EAC7C;AACA,SAAO,SAAS,QAAQ,IAAI,WAAW;AACxC;","names":["result"]}
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var credentials_exports = {};
20
+ __export(credentials_exports, {
21
+ assertOpenAiCredentialAllowsUrl: () => assertOpenAiCredentialAllowsUrl
22
+ });
23
+ module.exports = __toCommonJS(credentials_exports);
24
+ var import_n8n_workflow = require("n8n-workflow");
25
+ const DEFAULT_BASE_URL = "https://api.openai.com/v1";
26
+ function assertOpenAiCredentialAllowsUrl(node, credentials, url) {
27
+ if (credentials.allowedHttpRequestDomains === "none") {
28
+ const credentialUrl = typeof credentials.url === "string" ? credentials.url : "";
29
+ const pinnedUrl = credentialUrl || DEFAULT_BASE_URL;
30
+ if (url !== pinnedUrl) {
31
+ throw new import_n8n_workflow.NodeOperationError(
32
+ node,
33
+ `Domain not allowed: This credential is restricted from accessing ${url}.`
34
+ );
35
+ }
36
+ return void 0;
37
+ }
38
+ if (credentials.allowedHttpRequestDomains !== "domains") return void 0;
39
+ const allowedDomains = typeof credentials.allowedDomains === "string" ? credentials.allowedDomains : "";
40
+ if (!allowedDomains || allowedDomains.trim() === "") {
41
+ throw new import_n8n_workflow.NodeOperationError(
42
+ node,
43
+ "No allowed domains specified. Configure allowed domains or change restriction setting."
44
+ );
45
+ }
46
+ if (!(0, import_n8n_workflow.isDomainAllowed)(url, { allowedDomains })) {
47
+ throw new import_n8n_workflow.NodeOperationError(
48
+ node,
49
+ `Domain not allowed: This credential is restricted from accessing ${url}. Only the following domains are allowed: ${allowedDomains}`
50
+ );
51
+ }
52
+ return allowedDomains;
53
+ }
54
+ // Annotate the CommonJS export names for ESM import in node:
55
+ 0 && (module.exports = {
56
+ assertOpenAiCredentialAllowsUrl
57
+ });
58
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../nodes/vendors/OpenAi/helpers/credentials.ts"],"sourcesContent":["import type { ICredentialDataDecryptedObject, INode } from 'n8n-workflow';\nimport { isDomainAllowed, NodeOperationError } from 'n8n-workflow';\n\n/** Mirrors the fallback every OpenAI call site applies when the credential has no URL. */\nconst DEFAULT_BASE_URL = 'https://api.openai.com/v1';\n\n/**\n * Enforces the credential's domain restrictions against a caller-supplied\n * OpenAI-compatible base URL, treating the credential's effective endpoint —\n * its own `url`, or the OpenAI default when that is unset — as the pinned URL\n * for `'none'` mode.\n *\n * @returns {string | undefined} the allowed-domains list for per-redirect-hop checks; `undefined` means allow-all\n * @throws {NodeOperationError} when the URL is outside the credential's allowed domains\n */\nexport function assertOpenAiCredentialAllowsUrl(\n\tnode: INode,\n\tcredentials: ICredentialDataDecryptedObject,\n\turl: string,\n): string | undefined {\n\tif (credentials.allowedHttpRequestDomains === 'none') {\n\t\tconst credentialUrl = typeof credentials.url === 'string' ? credentials.url : '';\n\t\tconst pinnedUrl = credentialUrl || DEFAULT_BASE_URL;\n\t\tif (url !== pinnedUrl) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tnode,\n\t\t\t\t`Domain not allowed: This credential is restricted from accessing ${url}.`,\n\t\t\t);\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tif (credentials.allowedHttpRequestDomains !== 'domains') return undefined;\n\n\tconst allowedDomains =\n\t\ttypeof credentials.allowedDomains === 'string' ? credentials.allowedDomains : '';\n\tif (!allowedDomains || allowedDomains.trim() === '') {\n\t\tthrow new NodeOperationError(\n\t\t\tnode,\n\t\t\t'No allowed domains specified. Configure allowed domains or change restriction setting.',\n\t\t);\n\t}\n\n\tif (!isDomainAllowed(url, { allowedDomains })) {\n\t\tthrow new NodeOperationError(\n\t\t\tnode,\n\t\t\t`Domain not allowed: This credential is restricted from accessing ${url}. Only the following domains are allowed: ${allowedDomains}`,\n\t\t);\n\t}\n\n\treturn allowedDomains;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,0BAAoD;AAGpD,MAAM,mBAAmB;AAWlB,SAAS,gCACf,MACA,aACA,KACqB;AACrB,MAAI,YAAY,8BAA8B,QAAQ;AACrD,UAAM,gBAAgB,OAAO,YAAY,QAAQ,WAAW,YAAY,MAAM;AAC9E,UAAM,YAAY,iBAAiB;AACnC,QAAI,QAAQ,WAAW;AACtB,YAAM,IAAI;AAAA,QACT;AAAA,QACA,oEAAoE,GAAG;AAAA,MACxE;AAAA,IACD;AACA,WAAO;AAAA,EACR;AAEA,MAAI,YAAY,8BAA8B,UAAW,QAAO;AAEhE,QAAM,iBACL,OAAO,YAAY,mBAAmB,WAAW,YAAY,iBAAiB;AAC/E,MAAI,CAAC,kBAAkB,eAAe,KAAK,MAAM,IAAI;AACpD,UAAM,IAAI;AAAA,MACT;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAEA,MAAI,KAAC,qCAAgB,KAAK,EAAE,eAAe,CAAC,GAAG;AAC9C,UAAM,IAAI;AAAA,MACT;AAAA,MACA,oEAAoE,GAAG,6CAA6C,cAAc;AAAA,IACnI;AAAA,EACD;AAEA,SAAO;AACR;","names":[]}
@@ -40,6 +40,7 @@ var import_openai = require("openai");
40
40
  var import_descriptions = require("../../../../../../utils/descriptions");
41
41
  var import_helpers = require("../../../../../../utils/helpers");
42
42
  var import_tracing = require("../../../../../../utils/tracing");
43
+ var import_credentials = require("../../../helpers/credentials");
43
44
  var import_utils = require("../../../helpers/utils");
44
45
  var import_descriptions2 = require("../descriptions");
45
46
  var import_httpProxyAgent = require("../../../../../../utils/httpProxyAgent");
@@ -180,6 +181,9 @@ async function execute(i) {
180
181
  });
181
182
  const assistantId = this.getNodeParameter("assistantId", i, "", { extractValue: true });
182
183
  const options = this.getNodeParameter("options", i, {});
184
+ if (options.baseURL) {
185
+ (0, import_credentials.assertOpenAiCredentialAllowsUrl)(this.getNode(), credentials, options.baseURL);
186
+ }
183
187
  const baseURL = options.baseURL ?? credentials.url;
184
188
  const client = new import_openai.OpenAI({
185
189
  apiKey: credentials.apiKey,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../nodes/vendors/OpenAi/v1/actions/assistant/message.operation.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport { 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 type { BufferWindowMemory } from '@langchain/classic/memory';\nimport omit from 'lodash/omit';\nimport type {\n\tIDataObject,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeProperties,\n} from 'n8n-workflow';\nimport {\n\tApplicationError,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\tupdateDisplayOptions,\n} from 'n8n-workflow';\nimport { OpenAI as OpenAIClient } from 'openai';\n\nimport { promptTypeOptions } from '@utils/descriptions';\nimport { getConnectedTools, getPromptInputByType } from '@utils/helpers';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { formatToOpenAIAssistantTool, getChatMessages } from '../../../helpers/utils';\nimport { assistantRLC } from '../descriptions';\nimport { getProxyAgent } from '@utils/httpProxyAgent';\n\nconst properties: INodeProperties[] = [\n\tassistantRLC,\n\t{\n\t\t...promptTypeOptions,\n\t\tname: 'prompt',\n\t},\n\t{\n\t\tdisplayName: 'Prompt (User Message)',\n\t\tname: 'text',\n\t\ttype: 'string',\n\t\tdefault: '',\n\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\ttypeOptions: {\n\t\t\trows: 2,\n\t\t},\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tprompt: ['define'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Memory',\n\t\tname: 'memory',\n\t\ttype: 'options',\n\t\toptions: [\n\t\t\t{\n\t\t\t\tname: 'Use memory connector',\n\t\t\t\tvalue: 'connector',\n\t\t\t\tdescription: 'Connect one of the supported memory nodes',\n\t\t\t},\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased\n\t\t\t\tname: 'Use thread ID',\n\t\t\t\tvalue: 'threadId',\n\t\t\t\tdescription: 'Specify the ID of the thread to continue',\n\t\t\t},\n\t\t],\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [{ _cnd: { gte: 1.6 } }],\n\t\t\t},\n\t\t},\n\t\tdefault: 'connector',\n\t},\n\t{\n\t\tdisplayName: 'Thread ID',\n\t\tname: 'threadId',\n\t\ttype: 'string',\n\t\tdefault: '',\n\t\tplaceholder: '',\n\t\tdescription: 'The ID of the thread to continue, a new thread will be created if not specified',\n\t\thint: 'If the thread ID is empty or undefined a new thread will be created and included in the response',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [{ _cnd: { gte: 1.6 } }],\n\t\t\t\tmemory: ['threadId'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Connect your own custom n8n tools to this node on the canvas',\n\t\tname: 'noticeTools',\n\t\ttype: 'notice',\n\t\tdefault: '',\n\t},\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\tplaceholder: 'Add Option',\n\t\tdescription: 'Additional options to add',\n\t\ttype: 'collection',\n\t\tdefault: {},\n\t\toptions: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Base URL',\n\t\t\t\tname: 'baseURL',\n\t\t\t\tdefault: 'https://api.openai.com/v1',\n\t\t\t\tdescription: 'Override the default base URL for the API',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.8 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\tname: 'maxRetries',\n\t\t\t\tdefault: 2,\n\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\ttype: 'number',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\tname: 'timeout',\n\t\t\t\tdefault: 10000,\n\t\t\t\tdescription: 'Maximum amount of time a request is allowed to take in milliseconds',\n\t\t\t\ttype: 'number',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Preserve Original Tools',\n\t\t\t\tname: 'preserveOriginalTools',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: true,\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether to preserve the original tools of the assistant after the execution of this node, otherwise the tools will be replaced with the connected tools, if any, default is true',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t},\n];\n\nconst displayOptions = {\n\tshow: {\n\t\toperation: ['message'],\n\t\tresource: ['assistant'],\n\t},\n};\n\nexport const description = updateDisplayOptions(displayOptions, properties);\nconst mapChatMessageToThreadMessage = (\n\tmessage: BaseMessage,\n): OpenAIClient.Beta.Threads.ThreadCreateParams.Message => ({\n\trole: message._getType() === 'ai' ? 'assistant' : 'user',\n\tcontent: message.content.toString(),\n});\n\nexport async function execute(this: IExecuteFunctions, i: number): Promise<INodeExecutionData[]> {\n\tconst credentials = await this.getCredentials('openAiApi');\n\tconst nodeVersion = this.getNode().typeVersion;\n\n\tconst input = getPromptInputByType({\n\t\tctx: this,\n\t\ti,\n\t\tinputKey: 'text',\n\t\tpromptTypeKey: 'prompt',\n\t});\n\n\tconst assistantId = this.getNodeParameter('assistantId', i, '', { extractValue: true }) as string;\n\n\tconst options = this.getNodeParameter('options', i, {}) as {\n\t\tbaseURL?: string;\n\t\tmaxRetries: number;\n\t\ttimeout: number;\n\t\tpreserveOriginalTools?: boolean;\n\t};\n\n\tconst baseURL = (options.baseURL ?? credentials.url) as string;\n\n\tconst client = new OpenAIClient({\n\t\tapiKey: credentials.apiKey as string,\n\t\tmaxRetries: options.maxRetries ?? 2,\n\t\ttimeout: options.timeout ?? 10000,\n\t\tbaseURL,\n\t\tfetchOptions: {\n\t\t\tdispatcher: getProxyAgent(baseURL),\n\t\t},\n\t});\n\n\tconst agent = new OpenAIAssistantRunnable({ assistantId, client, asAgent: true });\n\n\tconst tools = await getConnectedTools(this, nodeVersion > 1, false);\n\tlet assistantTools;\n\n\tif (tools.length) {\n\t\tconst transformedConnectedTools = tools?.map(formatToOpenAIAssistantTool) ?? [];\n\t\tconst nativeToolsParsed: OpenAIToolType = [];\n\n\t\tassistantTools = (await client.beta.assistants.retrieve(assistantId)).tools;\n\n\t\tconst useCodeInterpreter = assistantTools.some((tool) => tool.type === 'code_interpreter');\n\t\tif (useCodeInterpreter) {\n\t\t\tnativeToolsParsed.push({\n\t\t\t\ttype: 'code_interpreter',\n\t\t\t});\n\t\t}\n\n\t\tconst useRetrieval = assistantTools.some((tool) => tool.type === 'file_search');\n\t\tif (useRetrieval) {\n\t\t\tnativeToolsParsed.push({\n\t\t\t\ttype: 'file_search',\n\t\t\t});\n\t\t}\n\n\t\tawait client.beta.assistants.update(assistantId, {\n\t\t\ttools: [...nativeToolsParsed, ...transformedConnectedTools],\n\t\t});\n\t}\n\n\tconst agentExecutor = AgentExecutor.fromAgentAndTools({\n\t\tagent,\n\t\ttools: tools ?? [],\n\t});\n\n\tconst useMemoryConnector =\n\t\tnodeVersion >= 1.6 && this.getNodeParameter('memory', i) === 'connector';\n\tconst memory =\n\t\tuseMemoryConnector || nodeVersion < 1.6\n\t\t\t? ((await this.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t\t\t\t| BufferWindowMemory\n\t\t\t\t\t| undefined)\n\t\t\t: undefined;\n\n\tconst threadId =\n\t\tnodeVersion >= 1.6 && !useMemoryConnector\n\t\t\t? (this.getNodeParameter('threadId', i) as string)\n\t\t\t: undefined;\n\n\tconst chainValues: IDataObject = {\n\t\tcontent: input,\n\t\tsignal: this.getExecutionCancelSignal(),\n\t\ttimeout: options.timeout ?? 10000,\n\t};\n\tlet thread: OpenAIClient.Beta.Threads.Thread;\n\tif (memory) {\n\t\tconst chatMessages = await getChatMessages(memory);\n\n\t\t// Construct a new thread from the chat history to map the memory\n\t\tif (chatMessages.length) {\n\t\t\tconst first32Messages = chatMessages.slice(0, 32);\n\t\t\t// There is a undocumented limit of 32 messages per thread when creating a thread with messages\n\t\t\tconst mappedMessages: OpenAIClient.Beta.Threads.ThreadCreateParams.Message[] =\n\t\t\t\tfirst32Messages.map(mapChatMessageToThreadMessage);\n\n\t\t\tthread = await client.beta.threads.create({ messages: mappedMessages });\n\t\t\tconst overLimitMessages = chatMessages.slice(32).map(mapChatMessageToThreadMessage);\n\n\t\t\t// Send the remaining messages that exceed the limit of 32 sequentially\n\t\t\tfor (const message of overLimitMessages) {\n\t\t\t\tawait client.beta.threads.messages.create(thread.id, message);\n\t\t\t}\n\n\t\t\tchainValues.threadId = thread.id;\n\t\t}\n\t} else if (threadId) {\n\t\tchainValues.threadId = threadId;\n\t}\n\n\tlet filteredResponse: IDataObject = {};\n\ttry {\n\t\tconst response = await agentExecutor.withConfig(getTracingConfig(this)).invoke(chainValues);\n\t\tif (memory) {\n\t\t\tawait memory.saveContext({ input }, { output: response.output });\n\n\t\t\tif (response.threadId && response.runId) {\n\t\t\t\tconst threadRun = await client.beta.threads.runs.retrieve(response.runId, {\n\t\t\t\t\tthread_id: response.threadId,\n\t\t\t\t});\n\t\t\t\tresponse.usage = threadRun.usage;\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\toptions.preserveOriginalTools !== false &&\n\t\t\tnodeVersion >= 1.3 &&\n\t\t\t(assistantTools ?? [])?.length\n\t\t) {\n\t\t\tawait client.beta.assistants.update(assistantId, {\n\t\t\t\ttools: assistantTools,\n\t\t\t});\n\t\t}\n\t\t// Remove configuration properties and runId added by Langchain that are not relevant to the user\n\t\tfilteredResponse = omit(response, ['signal', 'timeout', 'content', 'runId']) as IDataObject;\n\t} catch (error) {\n\t\tif (!(error instanceof ApplicationError)) {\n\t\t\tthrow new NodeOperationError(this.getNode(), error.message, { itemIndex: i });\n\t\t}\n\t}\n\n\treturn [{ json: filteredResponse, pairedItem: { item: i } }];\n}\n"],"mappings":"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","names":["import_descriptions","OpenAIClient","omit"]}
1
+ {"version":3,"sources":["../../../../../../../nodes/vendors/OpenAi/v1/actions/assistant/message.operation.ts"],"sourcesContent":["import type { BaseMessage } from '@langchain/core/messages';\nimport { 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 type { BufferWindowMemory } from '@langchain/classic/memory';\nimport omit from 'lodash/omit';\nimport type {\n\tIDataObject,\n\tIExecuteFunctions,\n\tINodeExecutionData,\n\tINodeProperties,\n} from 'n8n-workflow';\nimport {\n\tApplicationError,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\tupdateDisplayOptions,\n} from 'n8n-workflow';\nimport { OpenAI as OpenAIClient } from 'openai';\n\nimport { promptTypeOptions } from '@utils/descriptions';\nimport { getConnectedTools, getPromptInputByType } from '@utils/helpers';\nimport { getTracingConfig } from '@utils/tracing';\n\nimport { assertOpenAiCredentialAllowsUrl } from '../../../helpers/credentials';\nimport { formatToOpenAIAssistantTool, getChatMessages } from '../../../helpers/utils';\nimport { assistantRLC } from '../descriptions';\nimport { getProxyAgent } from '@utils/httpProxyAgent';\n\nconst properties: INodeProperties[] = [\n\tassistantRLC,\n\t{\n\t\t...promptTypeOptions,\n\t\tname: 'prompt',\n\t},\n\t{\n\t\tdisplayName: 'Prompt (User Message)',\n\t\tname: 'text',\n\t\ttype: 'string',\n\t\tdefault: '',\n\t\tplaceholder: 'e.g. Hello, how can you help me?',\n\t\ttypeOptions: {\n\t\t\trows: 2,\n\t\t},\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tprompt: ['define'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Memory',\n\t\tname: 'memory',\n\t\ttype: 'options',\n\t\toptions: [\n\t\t\t{\n\t\t\t\tname: 'Use memory connector',\n\t\t\t\tvalue: 'connector',\n\t\t\t\tdescription: 'Connect one of the supported memory nodes',\n\t\t\t},\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased\n\t\t\t\tname: 'Use thread ID',\n\t\t\t\tvalue: 'threadId',\n\t\t\t\tdescription: 'Specify the ID of the thread to continue',\n\t\t\t},\n\t\t],\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [{ _cnd: { gte: 1.6 } }],\n\t\t\t},\n\t\t},\n\t\tdefault: 'connector',\n\t},\n\t{\n\t\tdisplayName: 'Thread ID',\n\t\tname: 'threadId',\n\t\ttype: 'string',\n\t\tdefault: '',\n\t\tplaceholder: '',\n\t\tdescription: 'The ID of the thread to continue, a new thread will be created if not specified',\n\t\thint: 'If the thread ID is empty or undefined a new thread will be created and included in the response',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'@version': [{ _cnd: { gte: 1.6 } }],\n\t\t\t\tmemory: ['threadId'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Connect your own custom n8n tools to this node on the canvas',\n\t\tname: 'noticeTools',\n\t\ttype: 'notice',\n\t\tdefault: '',\n\t},\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\tplaceholder: 'Add Option',\n\t\tdescription: 'Additional options to add',\n\t\ttype: 'collection',\n\t\tdefault: {},\n\t\toptions: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Base URL',\n\t\t\t\tname: 'baseURL',\n\t\t\t\tdefault: 'https://api.openai.com/v1',\n\t\t\t\tdescription: 'Override the default base URL for the API',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\thide: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.8 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Max Retries',\n\t\t\t\tname: 'maxRetries',\n\t\t\t\tdefault: 2,\n\t\t\t\tdescription: 'Maximum number of retries to attempt',\n\t\t\t\ttype: 'number',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Timeout',\n\t\t\t\tname: 'timeout',\n\t\t\t\tdefault: 10000,\n\t\t\t\tdescription: 'Maximum amount of time a request is allowed to take in milliseconds',\n\t\t\t\ttype: 'number',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Preserve Original Tools',\n\t\t\t\tname: 'preserveOriginalTools',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: true,\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether to preserve the original tools of the assistant after the execution of this node, otherwise the tools will be replaced with the connected tools, if any, default is true',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.3 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t},\n];\n\nconst displayOptions = {\n\tshow: {\n\t\toperation: ['message'],\n\t\tresource: ['assistant'],\n\t},\n};\n\nexport const description = updateDisplayOptions(displayOptions, properties);\nconst mapChatMessageToThreadMessage = (\n\tmessage: BaseMessage,\n): OpenAIClient.Beta.Threads.ThreadCreateParams.Message => ({\n\trole: message._getType() === 'ai' ? 'assistant' : 'user',\n\tcontent: message.content.toString(),\n});\n\nexport async function execute(this: IExecuteFunctions, i: number): Promise<INodeExecutionData[]> {\n\tconst credentials = await this.getCredentials('openAiApi');\n\tconst nodeVersion = this.getNode().typeVersion;\n\n\tconst input = getPromptInputByType({\n\t\tctx: this,\n\t\ti,\n\t\tinputKey: 'text',\n\t\tpromptTypeKey: 'prompt',\n\t});\n\n\tconst assistantId = this.getNodeParameter('assistantId', i, '', { extractValue: true }) as string;\n\n\tconst options = this.getNodeParameter('options', i, {}) as {\n\t\tbaseURL?: string;\n\t\tmaxRetries: number;\n\t\ttimeout: number;\n\t\tpreserveOriginalTools?: boolean;\n\t};\n\n\tif (options.baseURL) {\n\t\tassertOpenAiCredentialAllowsUrl(this.getNode(), credentials, options.baseURL);\n\t}\n\n\tconst baseURL = (options.baseURL ?? credentials.url) as string;\n\n\tconst client = new OpenAIClient({\n\t\tapiKey: credentials.apiKey as string,\n\t\tmaxRetries: options.maxRetries ?? 2,\n\t\ttimeout: options.timeout ?? 10000,\n\t\tbaseURL,\n\t\tfetchOptions: {\n\t\t\tdispatcher: getProxyAgent(baseURL),\n\t\t},\n\t});\n\n\tconst agent = new OpenAIAssistantRunnable({ assistantId, client, asAgent: true });\n\n\tconst tools = await getConnectedTools(this, nodeVersion > 1, false);\n\tlet assistantTools;\n\n\tif (tools.length) {\n\t\tconst transformedConnectedTools = tools?.map(formatToOpenAIAssistantTool) ?? [];\n\t\tconst nativeToolsParsed: OpenAIToolType = [];\n\n\t\tassistantTools = (await client.beta.assistants.retrieve(assistantId)).tools;\n\n\t\tconst useCodeInterpreter = assistantTools.some((tool) => tool.type === 'code_interpreter');\n\t\tif (useCodeInterpreter) {\n\t\t\tnativeToolsParsed.push({\n\t\t\t\ttype: 'code_interpreter',\n\t\t\t});\n\t\t}\n\n\t\tconst useRetrieval = assistantTools.some((tool) => tool.type === 'file_search');\n\t\tif (useRetrieval) {\n\t\t\tnativeToolsParsed.push({\n\t\t\t\ttype: 'file_search',\n\t\t\t});\n\t\t}\n\n\t\tawait client.beta.assistants.update(assistantId, {\n\t\t\ttools: [...nativeToolsParsed, ...transformedConnectedTools],\n\t\t});\n\t}\n\n\tconst agentExecutor = AgentExecutor.fromAgentAndTools({\n\t\tagent,\n\t\ttools: tools ?? [],\n\t});\n\n\tconst useMemoryConnector =\n\t\tnodeVersion >= 1.6 && this.getNodeParameter('memory', i) === 'connector';\n\tconst memory =\n\t\tuseMemoryConnector || nodeVersion < 1.6\n\t\t\t? ((await this.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t\t\t\t| BufferWindowMemory\n\t\t\t\t\t| undefined)\n\t\t\t: undefined;\n\n\tconst threadId =\n\t\tnodeVersion >= 1.6 && !useMemoryConnector\n\t\t\t? (this.getNodeParameter('threadId', i) as string)\n\t\t\t: undefined;\n\n\tconst chainValues: IDataObject = {\n\t\tcontent: input,\n\t\tsignal: this.getExecutionCancelSignal(),\n\t\ttimeout: options.timeout ?? 10000,\n\t};\n\tlet thread: OpenAIClient.Beta.Threads.Thread;\n\tif (memory) {\n\t\tconst chatMessages = await getChatMessages(memory);\n\n\t\t// Construct a new thread from the chat history to map the memory\n\t\tif (chatMessages.length) {\n\t\t\tconst first32Messages = chatMessages.slice(0, 32);\n\t\t\t// There is a undocumented limit of 32 messages per thread when creating a thread with messages\n\t\t\tconst mappedMessages: OpenAIClient.Beta.Threads.ThreadCreateParams.Message[] =\n\t\t\t\tfirst32Messages.map(mapChatMessageToThreadMessage);\n\n\t\t\tthread = await client.beta.threads.create({ messages: mappedMessages });\n\t\t\tconst overLimitMessages = chatMessages.slice(32).map(mapChatMessageToThreadMessage);\n\n\t\t\t// Send the remaining messages that exceed the limit of 32 sequentially\n\t\t\tfor (const message of overLimitMessages) {\n\t\t\t\tawait client.beta.threads.messages.create(thread.id, message);\n\t\t\t}\n\n\t\t\tchainValues.threadId = thread.id;\n\t\t}\n\t} else if (threadId) {\n\t\tchainValues.threadId = threadId;\n\t}\n\n\tlet filteredResponse: IDataObject = {};\n\ttry {\n\t\tconst response = await agentExecutor.withConfig(getTracingConfig(this)).invoke(chainValues);\n\t\tif (memory) {\n\t\t\tawait memory.saveContext({ input }, { output: response.output });\n\n\t\t\tif (response.threadId && response.runId) {\n\t\t\t\tconst threadRun = await client.beta.threads.runs.retrieve(response.runId, {\n\t\t\t\t\tthread_id: response.threadId,\n\t\t\t\t});\n\t\t\t\tresponse.usage = threadRun.usage;\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\toptions.preserveOriginalTools !== false &&\n\t\t\tnodeVersion >= 1.3 &&\n\t\t\t(assistantTools ?? [])?.length\n\t\t) {\n\t\t\tawait client.beta.assistants.update(assistantId, {\n\t\t\t\ttools: assistantTools,\n\t\t\t});\n\t\t}\n\t\t// Remove configuration properties and runId added by Langchain that are not relevant to the user\n\t\tfilteredResponse = omit(response, ['signal', 'timeout', 'content', 'runId']) as IDataObject;\n\t} catch (error) {\n\t\tif (!(error instanceof ApplicationError)) {\n\t\t\tthrow new NodeOperationError(this.getNode(), error.message, { itemIndex: i });\n\t\t}\n\t}\n\n\treturn [{ json: filteredResponse, pairedItem: { item: i } }];\n}\n"],"mappings":"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","names":["import_descriptions","OpenAIClient","omit"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@n8n/n8n-nodes-langchain",
3
- "version": "1.122.52",
3
+ "version": "1.122.54",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "files": [
@@ -159,8 +159,8 @@
159
159
  "fast-glob": "3.2.12",
160
160
  "jest-mock-extended": "^3.0.4",
161
161
  "tsup": "^8.5.1",
162
- "n8n-core": "1.122.44",
163
- "@n8n/eslint-plugin-community-nodes": "0.7.0"
162
+ "@n8n/eslint-plugin-community-nodes": "0.7.0",
163
+ "n8n-core": "1.122.46"
164
164
  },
165
165
  "dependencies": {
166
166
  "@aws-sdk/client-sso-oidc": "3.808.0",
@@ -229,14 +229,14 @@
229
229
  "weaviate-client": "3.6.2",
230
230
  "zod": "3.25.67",
231
231
  "zod-to-json-schema": "3.23.3",
232
+ "@n8n/config": "1.65.9",
232
233
  "@n8n/client-oauth2": "0.33.6",
233
234
  "@n8n/errors": "0.5.1",
234
- "@n8n/config": "1.65.7",
235
235
  "@n8n/di": "0.10.0",
236
236
  "@n8n/json-schema-to-zod": "1.6.0",
237
- "n8n-workflow": "1.120.27",
238
237
  "@n8n/typescript-config": "1.3.1",
239
- "n8n-nodes-base": "1.121.48"
238
+ "n8n-nodes-base": "1.121.50",
239
+ "n8n-workflow": "1.120.29"
240
240
  },
241
241
  "license": "SEE LICENSE IN LICENSE.md",
242
242
  "homepage": "https://n8n.io",