@n8n/n8n-nodes-langchain 1.121.1 → 1.122.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/nodes/Guardrails/Guardrails.node.js +29 -40
- package/dist/nodes/Guardrails/Guardrails.node.js.map +1 -1
- package/dist/nodes/Guardrails/actions/execute.js +68 -0
- package/dist/nodes/Guardrails/actions/execute.js.map +1 -0
- package/dist/nodes/Guardrails/actions/process.js +10 -7
- package/dist/nodes/Guardrails/actions/process.js.map +1 -1
- package/dist/nodes/Guardrails/description.js +326 -365
- package/dist/nodes/Guardrails/description.js.map +1 -1
- package/dist/nodes/Guardrails/helpers/configureNodeInputs.js +37 -3
- package/dist/nodes/Guardrails/helpers/configureNodeInputs.js.map +1 -1
- package/dist/nodes/Guardrails/helpers/model.js.map +1 -1
- package/dist/nodes/Guardrails/v1/GuardrailsV1.node.js +59 -0
- package/dist/nodes/Guardrails/v1/GuardrailsV1.node.js.map +1 -0
- package/dist/nodes/Guardrails/v2/GuardrailsV2.node.js +59 -0
- package/dist/nodes/Guardrails/v2/GuardrailsV2.node.js.map +1 -0
- package/dist/nodes/ToolExecutor/ToolExecutor.node.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ConversationalAgent/execute.js +1 -1
- package/dist/nodes/agents/Agent/agents/ConversationalAgent/execute.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/OpenAiFunctionsAgent/execute.js +3 -85
- package/dist/nodes/agents/Agent/agents/OpenAiFunctionsAgent/execute.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/PlanAndExecuteAgent/execute.js +1 -1
- package/dist/nodes/agents/Agent/agents/PlanAndExecuteAgent/execute.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ReActAgent/execute.js +1 -1
- package/dist/nodes/agents/Agent/agents/ReActAgent/execute.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/SqlAgent/execute.js +2 -2
- package/dist/nodes/agents/Agent/agents/SqlAgent/execute.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/execute.js +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V1/execute.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V2/execute.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/buildExecutionContext.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/createAgentSequence.js +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/createAgentSequence.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/executeBatch.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/finalizeResult.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/prepareItemContext.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.js +8 -16
- package/dist/nodes/agents/Agent/agents/ToolsAgent/V3/helpers/runAgent.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/common.js +1 -1
- package/dist/nodes/agents/Agent/agents/ToolsAgent/common.js.map +1 -1
- package/dist/nodes/agents/Agent/agents/utils.js.map +1 -1
- package/dist/nodes/agents/OpenAiAssistant/OpenAiAssistant.node.js +2 -2
- package/dist/nodes/agents/OpenAiAssistant/OpenAiAssistant.node.js.map +1 -1
- package/dist/nodes/chains/ChainRetrievalQA/processItem.js +2 -2
- package/dist/nodes/chains/ChainRetrievalQA/processItem.js.map +1 -1
- package/dist/nodes/chains/ChainSummarization/V1/ChainSummarizationV1.node.js +1 -1
- package/dist/nodes/chains/ChainSummarization/V1/ChainSummarizationV1.node.js.map +1 -1
- package/dist/nodes/chains/ChainSummarization/V2/processItem.js +1 -1
- package/dist/nodes/chains/ChainSummarization/V2/processItem.js.map +1 -1
- package/dist/nodes/chains/ChainSummarization/helpers.js.map +1 -1
- package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js +1 -1
- package/dist/nodes/chains/InformationExtractor/InformationExtractor.node.js.map +1 -1
- package/dist/nodes/chains/InformationExtractor/processItem.js.map +1 -1
- package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js +1 -1
- package/dist/nodes/chains/SentimentAnalysis/SentimentAnalysis.node.js.map +1 -1
- package/dist/nodes/chains/TextClassifier/TextClassifier.node.js +1 -1
- package/dist/nodes/chains/TextClassifier/TextClassifier.node.js.map +1 -1
- package/dist/nodes/chains/TextClassifier/processItem.js.map +1 -1
- package/dist/nodes/code/Code.node.js +66 -2
- package/dist/nodes/code/Code.node.js.map +1 -1
- package/dist/nodes/llms/LMOllama/LmOllama.node.js +1 -1
- package/dist/nodes/llms/LMOllama/LmOllama.node.js.map +1 -1
- package/dist/nodes/mcp/McpClientTool/utils.js +1 -1
- package/dist/nodes/mcp/McpClientTool/utils.js.map +1 -1
- package/dist/nodes/memory/MemoryBufferWindow/MemoryBufferWindow.node.js +1 -1
- package/dist/nodes/memory/MemoryBufferWindow/MemoryBufferWindow.node.js.map +1 -1
- package/dist/nodes/memory/MemoryMongoDbChat/MemoryMongoDbChat.node.js +1 -1
- package/dist/nodes/memory/MemoryMongoDbChat/MemoryMongoDbChat.node.js.map +1 -1
- package/dist/nodes/memory/MemoryPostgresChat/MemoryPostgresChat.node.js +1 -1
- package/dist/nodes/memory/MemoryPostgresChat/MemoryPostgresChat.node.js.map +1 -1
- package/dist/nodes/memory/MemoryRedisChat/MemoryRedisChat.node.js +1 -1
- package/dist/nodes/memory/MemoryRedisChat/MemoryRedisChat.node.js.map +1 -1
- package/dist/nodes/memory/MemoryXata/MemoryXata.node.js +1 -1
- package/dist/nodes/memory/MemoryXata/MemoryXata.node.js.map +1 -1
- package/dist/nodes/retrievers/RetrieverContextualCompression/RetrieverContextualCompression.node.js +2 -2
- package/dist/nodes/retrievers/RetrieverContextualCompression/RetrieverContextualCompression.node.js.map +1 -1
- package/dist/nodes/retrievers/RetrieverMultiQuery/RetrieverMultiQuery.node.js +1 -1
- package/dist/nodes/retrievers/RetrieverMultiQuery/RetrieverMultiQuery.node.js.map +1 -1
- package/dist/nodes/retrievers/RetrieverVectorStore/RetrieverVectorStore.node.js +1 -1
- package/dist/nodes/retrievers/RetrieverVectorStore/RetrieverVectorStore.node.js.map +1 -1
- package/dist/nodes/tools/ToolThink/ToolThink.node.js +1 -1
- package/dist/nodes/tools/ToolThink/ToolThink.node.js.map +1 -1
- package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js +2 -2
- package/dist/nodes/tools/ToolVectorStore/ToolVectorStore.node.js.map +1 -1
- package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js +5 -21
- package/dist/nodes/tools/ToolWorkflow/v2/utils/WorkflowToolService.js.map +1 -1
- package/dist/nodes/trigger/ChatTrigger/Chat.node.js +2 -2
- package/dist/nodes/trigger/ChatTrigger/Chat.node.js.map +1 -1
- package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js +1 -1
- package/dist/nodes/trigger/ChatTrigger/ChatTrigger.node.js.map +1 -1
- package/dist/nodes/vector_store/VectorStoreAzureAISearch/VectorStoreAzureAISearch.node.js +65 -17
- package/dist/nodes/vector_store/VectorStoreAzureAISearch/VectorStoreAzureAISearch.node.js.map +1 -1
- package/dist/nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.js.map +1 -1
- package/dist/nodes/vector_store/VectorStoreInMemoryInsert/VectorStoreInMemoryInsert.node.js.map +1 -1
- package/dist/nodes/vector_store/VectorStoreQdrant/qdrant.svg +23 -19
- package/dist/nodes/vector_store/shared/MemoryManager/MemoryCalculator.js.map +1 -1
- package/dist/nodes/vector_store/shared/MemoryManager/MemoryVectorStoreManager.js +1 -1
- package/dist/nodes/vector_store/shared/MemoryManager/MemoryVectorStoreManager.js.map +1 -1
- package/dist/nodes/vector_store/shared/MemoryManager/StoreCleanupService.js.map +1 -1
- package/dist/nodes/vector_store/shared/MemoryManager/types.js.map +1 -1
- package/dist/nodes/vector_store/shared/createVectorStoreNode/operations/retrieveAsToolOperation.js +18 -16
- package/dist/nodes/vector_store/shared/createVectorStoreNode/operations/retrieveAsToolOperation.js.map +1 -1
- package/dist/nodes/vendors/GoogleGemini/actions/image/edit.operation.js +6 -1
- package/dist/nodes/vendors/GoogleGemini/actions/image/edit.operation.js.map +1 -1
- package/dist/nodes/vendors/GoogleGemini/actions/image/generate.operation.js +1 -1
- package/dist/nodes/vendors/GoogleGemini/actions/image/generate.operation.js.map +1 -1
- package/dist/nodes/vendors/GoogleGemini/methods/listSearch.js +23 -8
- package/dist/nodes/vendors/GoogleGemini/methods/listSearch.js.map +1 -1
- package/dist/nodes/vendors/OpenAi/helpers/utils.js.map +1 -1
- package/dist/nodes/vendors/OpenAi/v1/actions/assistant/message.operation.js +2 -2
- package/dist/nodes/vendors/OpenAi/v1/actions/assistant/message.operation.js.map +1 -1
- package/dist/types/nodes.json +7 -6
- package/dist/utils/N8nBinaryLoader.js +2 -2
- package/dist/utils/N8nBinaryLoader.js.map +1 -1
- package/dist/utils/N8nJsonLoader.js +2 -2
- package/dist/utils/N8nJsonLoader.js.map +1 -1
- package/dist/utils/N8nTool.js +1 -1
- package/dist/utils/N8nTool.js.map +1 -1
- package/dist/utils/agent-execution/buildSteps.js +12 -8
- package/dist/utils/agent-execution/buildSteps.js.map +1 -1
- package/dist/utils/agent-execution/createEngineRequests.js +19 -1
- package/dist/utils/agent-execution/createEngineRequests.js.map +1 -1
- package/dist/utils/agent-execution/index.js +4 -4
- package/dist/utils/agent-execution/index.js.map +1 -1
- package/dist/utils/agent-execution/memoryManagement.js +15 -14
- package/dist/utils/agent-execution/memoryManagement.js.map +1 -1
- package/dist/utils/agent-execution/processEventStream.js +1 -47
- package/dist/utils/agent-execution/processEventStream.js.map +1 -1
- package/dist/utils/agent-execution/types.js.map +1 -1
- package/dist/utils/fromAIToolFactory.js +61 -0
- package/dist/utils/fromAIToolFactory.js.map +1 -0
- package/dist/utils/helpers.js +1 -1
- package/dist/utils/helpers.js.map +1 -1
- package/dist/utils/logWrapper.js.map +1 -1
- package/dist/utils/output_parsers/N8nStructuredOutputParser.js +1 -1
- package/dist/utils/output_parsers/N8nStructuredOutputParser.js.map +1 -1
- package/package.json +31 -30
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/trigger/ChatTrigger/ChatTrigger.node.ts"],"sourcesContent":["import type { BaseChatMemory } from '@langchain/community/memory/chat_memory';\nimport pick from 'lodash/pick';\nimport {\n\tNode,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\tassertParamIsBoolean,\n\tvalidateNodeParameters,\n\tassertParamIsString,\n} from 'n8n-workflow';\nimport type {\n\tIDataObject,\n\tIWebhookFunctions,\n\tIWebhookResponseData,\n\tINodeTypeDescription,\n\tMultiPartFormData,\n\tINodeExecutionData,\n\tIBinaryData,\n\tINodeProperties,\n} from 'n8n-workflow';\nimport * as a from 'node:assert';\n\nimport { cssVariables } from './constants';\nimport { validateAuth } from './GenericFunctions';\nimport { createPage } from './templates';\nimport { assertValidLoadPreviousSessionOption } from './types';\n\nconst CHAT_TRIGGER_PATH_IDENTIFIER = 'chat';\nconst allowFileUploadsOption: INodeProperties = {\n\tdisplayName: 'Allow File Uploads',\n\tname: 'allowFileUploads',\n\ttype: 'boolean',\n\tdefault: false,\n\tdescription: 'Whether to allow file uploads in the chat',\n};\nconst allowedFileMimeTypeOption: INodeProperties = {\n\tdisplayName: 'Allowed File Mime Types',\n\tname: 'allowedFilesMimeTypes',\n\ttype: 'string',\n\tdefault: '*',\n\tplaceholder: 'e.g. image/*, text/*, application/pdf',\n\tdescription:\n\t\t'Allowed file types for upload. Comma-separated list of <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\" target=\"_blank\">MIME types</a>.',\n};\n\nconst respondToWebhookResponseMode = {\n\tname: \"Using 'Respond to Webhook' Node\",\n\tvalue: 'responseNode',\n\tdescription: 'Response defined in that node',\n};\n\nconst lastNodeResponseMode = {\n\tname: 'When Last Node Finishes',\n\tvalue: 'lastNode',\n\tdescription: 'Returns data of the last-executed node',\n};\n\nconst streamingResponseMode = {\n\tname: 'Streaming',\n\tvalue: 'streaming',\n\tdescription: 'Streaming response from specified nodes (e.g. Agents)',\n};\n\nconst respondNodesResponseMode = {\n\tname: 'Using Response Nodes',\n\tvalue: 'responseNodes',\n\tdescription:\n\t\t\"Send responses to the chat by using 'Respond to Chat' or 'Respond to Webhook' nodes\",\n};\n\nconst commonOptionsFields: INodeProperties[] = [\n\t// CORS parameters are only valid for when chat is used in hosted or webhook mode\n\t{\n\t\tdisplayName: 'Allowed Origins (CORS)',\n\t\tname: 'allowedOrigins',\n\t\ttype: 'string',\n\t\tdefault: '*',\n\t\tdescription:\n\t\t\t'Comma-separated list of URLs allowed for cross-origin non-preflight requests. Use * (default) to allow all origins.',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat', 'webhook'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...allowFileUploadsOption,\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...allowedFileMimeTypeOption,\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Input Placeholder',\n\t\tname: 'inputPlaceholder',\n\t\ttype: 'string',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: 'Type your question..',\n\t\tplaceholder: 'e.g. Type your message here',\n\t\tdescription: 'Shown as placeholder text in the chat input field',\n\t},\n\t{\n\t\tdisplayName: 'Load Previous Session',\n\t\tname: 'loadPreviousSession',\n\t\ttype: 'options',\n\t\toptions: [\n\t\t\t{\n\t\t\t\tname: 'Off',\n\t\t\t\tvalue: 'notSupported',\n\t\t\t\tdescription: 'Loading messages of previous session is turned off',\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'From Memory',\n\t\t\t\tvalue: 'memory',\n\t\t\t\tdescription: 'Load session messages from memory',\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Manually',\n\t\t\t\tvalue: 'manually',\n\t\t\t\tdescription: 'Manually return messages of session',\n\t\t\t},\n\t\t],\n\t\tdefault: 'notSupported',\n\t\tdescription: 'If loading messages of a previous session should be enabled',\n\t},\n\t{\n\t\tdisplayName: 'Require Button Click to Start Chat',\n\t\tname: 'showWelcomeScreen',\n\t\ttype: 'boolean',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: false,\n\t\tdescription: 'Whether to show the welcome screen at the start of the chat',\n\t},\n\t{\n\t\tdisplayName: 'Start Conversation Button Text',\n\t\tname: 'getStarted',\n\t\ttype: 'string',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tshowWelcomeScreen: [true],\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: 'New Conversation',\n\t\tplaceholder: 'e.g. New Conversation',\n\t\tdescription: 'Shown as part of the welcome screen, in the middle of the chat window',\n\t},\n\t{\n\t\tdisplayName: 'Subtitle',\n\t\tname: 'subtitle',\n\t\ttype: 'string',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: \"Start a chat. We're here to help you 24/7.\",\n\t\tplaceholder: \"e.g. We're here for you\",\n\t\tdescription: 'Shown at the top of the chat, under the title',\n\t},\n\t{\n\t\tdisplayName: 'Title',\n\t\tname: 'title',\n\t\ttype: 'string',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: 'Hi there! 👋',\n\t\tplaceholder: 'e.g. Welcome',\n\t\tdescription: 'Shown at the top of the chat',\n\t},\n\t{\n\t\tdisplayName: 'Custom Chat Styling',\n\t\tname: 'customCss',\n\t\ttype: 'string',\n\t\ttypeOptions: {\n\t\t\trows: 10,\n\t\t\teditor: 'cssEditor',\n\t\t},\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: `\n${cssVariables}\n\n/* You can override any class styles, too. Right-click inspect in Chat UI to find class to override. */\n.chat-message {\n\tmax-width: 50%;\n}\n`.trim(),\n\t\tdescription: 'Override default styling of the public chat interface with CSS',\n\t},\n];\n\nexport class ChatTrigger extends Node {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Chat Trigger',\n\t\tname: 'chatTrigger',\n\t\ticon: 'fa:comments',\n\t\ticonColor: 'black',\n\t\tgroup: ['trigger'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4],\n\t\tdefaultVersion: 1.4,\n\t\tdescription: 'Runs the workflow when an n8n generated webchat is submitted',\n\t\tdefaults: {\n\t\t\tname: 'When chat message received',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['Core Nodes'],\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/core-nodes/n8n-nodes-langchain.chattrigger/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tmaxNodes: 1,\n\t\tinputs: `={{ (() => {\n\t\t\tif (!['hostedChat', 'webhook'].includes($parameter.mode)) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tif ($parameter.options?.loadPreviousSession !== 'memory') {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Memory',\n\t\t\t\t\tmaxConnections: 1,\n\t\t\t\t\ttype: '${NodeConnectionTypes.AiMemory}',\n\t\t\t\t\trequired: true,\n\t\t\t\t}\n\t\t\t];\n\t\t })() }}`,\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-credentials-name-unsuffixed\n\t\t\t\tname: 'httpBasicAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['basicAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\twebhooks: [\n\t\t\t{\n\t\t\t\tname: 'setup',\n\t\t\t\thttpMethod: 'GET',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tpath: CHAT_TRIGGER_PATH_IDENTIFIER,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'POST',\n\t\t\t\tresponseMode: '={{$parameter.options?.[\"responseMode\"] || \"lastNode\" }}',\n\t\t\t\tpath: CHAT_TRIGGER_PATH_IDENTIFIER,\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: '={{ !$parameter.public }}',\n\t\t\t},\n\t\t],\n\t\teventTriggerDescription: 'Waiting for you to submit the chat',\n\t\tactivationMessage: 'You can now make calls to your production chat URL.',\n\t\ttriggerPanel: false,\n\t\tproperties: [\n\t\t\t/**\n\t\t\t * @note If we change this property, also update it in ChatEmbedModal.vue\n\t\t\t */\n\t\t\t{\n\t\t\t\tdisplayName: 'Make Chat Publicly Available',\n\t\t\t\tname: 'public',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether the chat should be publicly available or only accessible through the manual chat interface',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Mode',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Hosted Chat',\n\t\t\t\t\t\tvalue: 'hostedChat',\n\t\t\t\t\t\tdescription: 'Chat on a page served by n8n',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Embedded Chat',\n\t\t\t\t\t\tvalue: 'webhook',\n\t\t\t\t\t\tdescription: 'Chat through a widget embedded in another page, or by calling a webhook',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'hostedChat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [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:\n\t\t\t\t\t'Chat will be live at the URL above once you activate this workflow. Live executions will show up in the ‘executions’ tab',\n\t\t\t\tname: 'hostedChatNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Follow the instructions <a href=\"https://www.npmjs.com/package/@n8n/chat\" target=\"_blank\">here</a> to embed chat in a webpage (or just call the webhook URL at the top of this section). Chat will be live once you activate this workflow',\n\t\t\t\tname: 'embeddedChatNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['webhook'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Basic Auth',\n\t\t\t\t\t\tvalue: 'basicAuth',\n\t\t\t\t\t\tdescription: 'Simple username and password (the same one for all users)',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased\n\t\t\t\t\t\tname: 'n8n User Auth',\n\t\t\t\t\t\tvalue: 'n8nUserAuth',\n\t\t\t\t\t\tdescription: 'Require user to be logged in with their n8n account',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Initial Message(s)',\n\t\t\t\tname: 'initialMessages',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t\tdefault: 'Hi there! 👋\\nMy name is Nathan. How can I assist you today?',\n\t\t\t\tdescription: 'Default messages shown at the start of the chat, one per line',\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\tdisplayName: 'Make Available in n8n Chat',\n\t\t\t\tname: 'availableInChat',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'Whether to make the agent available in n8n Chat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.4 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Agent Name',\n\t\t\t\tname: 'agentName',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'The name of the agent on n8n Chat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tavailableInChat: [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: 'Agent Description',\n\t\t\t\tname: 'agentDescription',\n\t\t\t\ttype: 'string',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t\tdefault: '',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'The description of the agent on n8n Chat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tavailableInChat: [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\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [false],\n\t\t\t\t\t\t'@version': [1, 1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [allowFileUploadsOption, allowedFileMimeTypeOption],\n\t\t\t},\n\t\t\t// Options for versions 1.0 and 1.1 (without streaming)\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat', 'webhook'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t\t'@version': [1, 1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t...commonOptionsFields,\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, respondToWebhookResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the webhook',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t// Options for version 1.2 (with streaming)\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat', 'webhook'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t\t'@version': [1.2],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t...commonOptionsFields,\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, respondToWebhookResponseMode, streamingResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the webhook',\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\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [false],\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\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\tallowFileUploadsOption,\n\t\t\t\t\tallowedFileMimeTypeOption,\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, respondNodesResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the chat',\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\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat', 'webhook'],\n\t\t\t\t\t\tpublic: [true],\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\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t...commonOptionsFields,\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, streamingResponseMode, respondToWebhookResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the chat',\n\t\t\t\t\t\tdisplayOptions: { show: { '/mode': ['webhook'] } },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, streamingResponseMode, respondNodesResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the webhook',\n\t\t\t\t\t\tdisplayOptions: { show: { '/mode': ['hostedChat'] } },\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tprivate async handleFormData(context: IWebhookFunctions) {\n\t\tconst req = context.getRequestObject() as MultiPartFormData.Request;\n\t\ta.ok(req.contentType === 'multipart/form-data', 'Expected multipart/form-data');\n\t\tconst options = context.getNodeParameter('options', {}) as IDataObject;\n\t\tconst { data, files } = req.body;\n\n\t\tconst returnItem: INodeExecutionData = {\n\t\t\tjson: data,\n\t\t};\n\n\t\tif (files && Object.keys(files).length) {\n\t\t\treturnItem.json.files = [] as Array<Omit<IBinaryData, 'data'>>;\n\t\t\treturnItem.binary = {};\n\n\t\t\tconst count = 0;\n\t\t\tfor (const fileKey of Object.keys(files)) {\n\t\t\t\tconst processedFiles: MultiPartFormData.File[] = [];\n\t\t\t\tif (Array.isArray(files[fileKey])) {\n\t\t\t\t\tprocessedFiles.push(...files[fileKey]);\n\t\t\t\t} else {\n\t\t\t\t\tprocessedFiles.push(files[fileKey]);\n\t\t\t\t}\n\n\t\t\t\tlet fileIndex = 0;\n\t\t\t\tfor (const file of processedFiles) {\n\t\t\t\t\tlet binaryPropertyName = 'data';\n\n\t\t\t\t\t// Remove the '[]' suffix from the binaryPropertyName if it exists\n\t\t\t\t\tif (binaryPropertyName.endsWith('[]')) {\n\t\t\t\t\t\tbinaryPropertyName = binaryPropertyName.slice(0, -2);\n\t\t\t\t\t}\n\t\t\t\t\tif (options.binaryPropertyName) {\n\t\t\t\t\t\tbinaryPropertyName = `${options.binaryPropertyName.toString()}${count}`;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst binaryFile = await context.nodeHelpers.copyBinaryFile(\n\t\t\t\t\t\tfile.filepath,\n\t\t\t\t\t\tfile.originalFilename ?? file.newFilename,\n\t\t\t\t\t\tfile.mimetype,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst binaryKey = `${binaryPropertyName}${fileIndex}`;\n\n\t\t\t\t\tconst binaryInfo = {\n\t\t\t\t\t\t...pick(binaryFile, ['fileName', 'fileSize', 'fileType', 'mimeType', 'fileExtension']),\n\t\t\t\t\t\tbinaryKey,\n\t\t\t\t\t};\n\n\t\t\t\t\treturnItem.binary = Object.assign(returnItem.binary ?? {}, {\n\t\t\t\t\t\t[`${binaryKey}`]: binaryFile,\n\t\t\t\t\t});\n\t\t\t\t\treturnItem.json.files = [\n\t\t\t\t\t\t...(returnItem.json.files as Array<Omit<IBinaryData, 'data'>>),\n\t\t\t\t\t\tbinaryInfo,\n\t\t\t\t\t];\n\t\t\t\t\tfileIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn returnItem;\n\t}\n\n\tasync webhook(ctx: IWebhookFunctions): Promise<IWebhookResponseData> {\n\t\tconst res = ctx.getResponseObject();\n\n\t\tconst isPublic = ctx.getNodeParameter('public', false);\n\t\tassertParamIsBoolean('public', isPublic, ctx.getNode());\n\n\t\tconst nodeMode = ctx.getNodeParameter('mode', 'hostedChat');\n\t\tassertParamIsString('mode', nodeMode, ctx.getNode());\n\n\t\tif (!isPublic) {\n\t\t\tres.status(404).end();\n\t\t\treturn {\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\n\t\tconst options = ctx.getNodeParameter('options', {});\n\t\tvalidateNodeParameters(\n\t\t\toptions,\n\t\t\t{\n\t\t\t\tgetStarted: { type: 'string' },\n\t\t\t\tinputPlaceholder: { type: 'string' },\n\t\t\t\tloadPreviousSession: { type: 'string' },\n\t\t\t\tshowWelcomeScreen: { type: 'boolean' },\n\t\t\t\tsubtitle: { type: 'string' },\n\t\t\t\ttitle: { type: 'string' },\n\t\t\t\tallowFileUploads: { type: 'boolean' },\n\t\t\t\tallowedFilesMimeTypes: { type: 'string' },\n\t\t\t\tcustomCss: { type: 'string' },\n\t\t\t\tresponseMode: { type: 'string' },\n\t\t\t},\n\t\t\tctx.getNode(),\n\t\t);\n\n\t\tconst loadPreviousSession = options.loadPreviousSession;\n\t\tassertValidLoadPreviousSessionOption(loadPreviousSession, ctx.getNode());\n\n\t\tconst enableStreaming = options.responseMode === 'streaming';\n\n\t\tconst req = ctx.getRequestObject();\n\t\tconst webhookName = ctx.getWebhookName();\n\t\tconst mode = ctx.getMode() === 'manual' ? 'test' : 'production';\n\t\tconst bodyData = ctx.getBodyData() ?? {};\n\n\t\ttry {\n\t\t\tawait validateAuth(ctx);\n\t\t} catch (error) {\n\t\t\tif (error) {\n\t\t\t\tres.writeHead((error as IDataObject).responseCode as number, {\n\t\t\t\t\t'www-authenticate': 'Basic realm=\"Webhook\"',\n\t\t\t\t});\n\t\t\t\tres.end((error as IDataObject).message as string);\n\t\t\t\treturn { noWebhookResponse: true };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tif (nodeMode === 'hostedChat') {\n\t\t\t// Show the chat on GET request\n\t\t\tif (webhookName === 'setup') {\n\t\t\t\tconst webhookUrlRaw = ctx.getNodeWebhookUrl('default');\n\t\t\t\tif (!webhookUrlRaw) {\n\t\t\t\t\tthrow new NodeOperationError(ctx.getNode(), 'Default webhook url not set');\n\t\t\t\t}\n\n\t\t\t\tconst webhookUrl =\n\t\t\t\t\tmode === 'test' ? webhookUrlRaw.replace('/webhook', '/webhook-test') : webhookUrlRaw;\n\t\t\t\tconst authentication = ctx.getNodeParameter('authentication') as\n\t\t\t\t\t| 'none'\n\t\t\t\t\t| 'basicAuth'\n\t\t\t\t\t| 'n8nUserAuth';\n\t\t\t\tconst initialMessagesRaw = ctx.getNodeParameter('initialMessages', '');\n\t\t\t\tassertParamIsString('initialMessage', initialMessagesRaw, ctx.getNode());\n\t\t\t\tconst instanceId = ctx.getInstanceId();\n\n\t\t\t\tconst i18nConfig: Record<string, string> = {};\n\t\t\t\tconst keys = ['getStarted', 'inputPlaceholder', 'subtitle', 'title'] as const;\n\t\t\t\tfor (const key of keys) {\n\t\t\t\t\tif (options[key] !== undefined) {\n\t\t\t\t\t\ti18nConfig[key] = options[key];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst page = createPage({\n\t\t\t\t\ti18n: {\n\t\t\t\t\t\ten: i18nConfig,\n\t\t\t\t\t},\n\t\t\t\t\tshowWelcomeScreen: options.showWelcomeScreen,\n\t\t\t\t\tloadPreviousSession,\n\t\t\t\t\tinitialMessages: initialMessagesRaw,\n\t\t\t\t\twebhookUrl,\n\t\t\t\t\tmode,\n\t\t\t\t\tinstanceId,\n\t\t\t\t\tauthentication,\n\t\t\t\t\tallowFileUploads: options.allowFileUploads,\n\t\t\t\t\tallowedFilesMimeTypes: options.allowedFilesMimeTypes,\n\t\t\t\t\tcustomCss: options.customCss,\n\t\t\t\t\tenableStreaming,\n\t\t\t\t});\n\n\t\t\t\tres.status(200).send(page).end();\n\t\t\t\treturn {\n\t\t\t\t\tnoWebhookResponse: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif (bodyData.action === 'loadPreviousSession') {\n\t\t\tif (options?.loadPreviousSession === 'memory') {\n\t\t\t\tconst memory = (await ctx.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t\t\t\t| BaseChatMemory\n\t\t\t\t\t| undefined;\n\t\t\t\tconst messages = ((await memory?.chatHistory.getMessages()) ?? [])\n\t\t\t\t\t.filter((message) => !message?.additional_kwargs?.hideFromUI)\n\t\t\t\t\t.map((message) => message?.toJSON());\n\t\t\t\treturn {\n\t\t\t\t\twebhookResponse: { data: messages },\n\t\t\t\t};\n\t\t\t} else if (!options?.loadPreviousSession || options?.loadPreviousSession === 'notSupported') {\n\t\t\t\t// If messages of a previous session should not be loaded, simply return an empty array\n\t\t\t\treturn {\n\t\t\t\t\twebhookResponse: { data: [] },\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tlet returnData: INodeExecutionData[];\n\t\tconst webhookResponse: IDataObject = { status: 200 };\n\n\t\t// Handle streaming responses\n\t\tif (enableStreaming) {\n\t\t\t// Set up streaming response headers\n\t\t\tres.writeHead(200, {\n\t\t\t\t'Content-Type': 'application/json; charset=utf-8',\n\t\t\t\t'Transfer-Encoding': 'chunked',\n\t\t\t\t'Cache-Control': 'no-cache',\n\t\t\t\tConnection: 'keep-alive',\n\t\t\t});\n\n\t\t\t// Flush headers immediately\n\t\t\tres.flushHeaders();\n\n\t\t\tif (req.contentType === 'multipart/form-data') {\n\t\t\t\treturnData = [await this.handleFormData(ctx)];\n\t\t\t} else {\n\t\t\t\treturnData = [{ json: bodyData }];\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tworkflowData: [ctx.helpers.returnJsonArray(returnData)],\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\n\t\tif (req.contentType === 'multipart/form-data') {\n\t\t\treturnData = [await this.handleFormData(ctx)];\n\t\t\treturn {\n\t\t\t\twebhookResponse,\n\t\t\t\tworkflowData: [returnData],\n\t\t\t};\n\t\t} else {\n\t\t\treturnData = [{ json: bodyData }];\n\t\t}\n\n\t\treturn {\n\t\t\twebhookResponse,\n\t\t\tworkflowData: [ctx.helpers.returnJsonArray(returnData)],\n\t\t};\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,kBAAiB;AACjB,0BAOO;AAWP,QAAmB;AAEnB,uBAA6B;AAC7B,8BAA6B;AAC7B,uBAA2B;AAC3B,mBAAqD;AAErD,MAAM,+BAA+B;AACrC,MAAM,yBAA0C;AAAA,EAC/C,aAAa;AAAA,EACb,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AACd;AACA,MAAM,4BAA6C;AAAA,EAClD,aAAa;AAAA,EACb,MAAM;AAAA,EACN,MAAM;AAAA,EACN,SAAS;AAAA,EACT,aAAa;AAAA,EACb,aACC;AACF;AAEA,MAAM,+BAA+B;AAAA,EACpC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AACd;AAEA,MAAM,uBAAuB;AAAA,EAC5B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AACd;AAEA,MAAM,wBAAwB;AAAA,EAC7B,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AACd;AAEA,MAAM,2BAA2B;AAAA,EAChC,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aACC;AACF;AAEA,MAAM,sBAAyC;AAAA;AAAA,EAE9C;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aACC;AAAA,IACD,gBAAgB;AAAA,MACf,MAAM;AAAA,QACL,SAAS,CAAC,cAAc,SAAS;AAAA,MAClC;AAAA,IACD;AAAA,EACD;AAAA,EACA;AAAA,IACC,GAAG;AAAA,IACH,gBAAgB;AAAA,MACf,MAAM;AAAA,QACL,SAAS,CAAC,YAAY;AAAA,MACvB;AAAA,IACD;AAAA,EACD;AAAA,EACA;AAAA,IACC,GAAG;AAAA,IACH,gBAAgB;AAAA,MACf,MAAM;AAAA,QACL,SAAS,CAAC,YAAY;AAAA,MACvB;AAAA,IACD;AAAA,EACD;AAAA,EACA;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,gBAAgB;AAAA,MACf,MAAM;AAAA,QACL,SAAS,CAAC,YAAY;AAAA,MACvB;AAAA,IACD;AAAA,IACA,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,EACd;AAAA,EACA;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,MACR;AAAA,QACC,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,MACd;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,MACd;AAAA,MACA;AAAA,QACC,MAAM;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,MACd;AAAA,IACD;AAAA,IACA,SAAS;AAAA,IACT,aAAa;AAAA,EACd;AAAA,EACA;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,gBAAgB;AAAA,MACf,MAAM;AAAA,QACL,SAAS,CAAC,YAAY;AAAA,MACvB;AAAA,IACD;AAAA,IACA,SAAS;AAAA,IACT,aAAa;AAAA,EACd;AAAA,EACA;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,gBAAgB;AAAA,MACf,MAAM;AAAA,QACL,mBAAmB,CAAC,IAAI;AAAA,QACxB,SAAS,CAAC,YAAY;AAAA,MACvB;AAAA,IACD;AAAA,IACA,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,EACd;AAAA,EACA;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,gBAAgB;AAAA,MACf,MAAM;AAAA,QACL,SAAS,CAAC,YAAY;AAAA,MACvB;AAAA,IACD;AAAA,IACA,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,EACd;AAAA,EACA;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,gBAAgB;AAAA,MACf,MAAM;AAAA,QACL,SAAS,CAAC,YAAY;AAAA,MACvB;AAAA,IACD;AAAA,IACA,SAAS;AAAA,IACT,aAAa;AAAA,IACb,aAAa;AAAA,EACd;AAAA,EACA;AAAA,IACC,aAAa;AAAA,IACb,MAAM;AAAA,IACN,MAAM;AAAA,IACN,aAAa;AAAA,MACZ,MAAM;AAAA,MACN,QAAQ;AAAA,IACT;AAAA,IACA,gBAAgB;AAAA,MACf,MAAM;AAAA,QACL,SAAS,CAAC,YAAY;AAAA,MACvB;AAAA,IACD;AAAA,IACA,SAAS;AAAA,EACT,6BAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,KAAK;AAAA,IACL,aAAa;AAAA,EACd;AACD;AAEO,MAAM,oBAAoB,yBAAK;AAAA,EAA/B;AAAA;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,WAAW;AAAA,MACX,OAAO,CAAC,SAAS;AAAA,MACjB,SAAS,CAAC,GAAG,KAAK,KAAK,KAAK,GAAG;AAAA,MAC/B,gBAAgB;AAAA,MAChB,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACN,YAAY,CAAC,YAAY;AAAA,QACzB,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MACA,UAAU;AAAA,MACV,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,cAYI,wCAAoB,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,MAKxC,SAAS,CAAC,wCAAoB,IAAI;AAAA,MAClC,aAAa;AAAA,QACZ;AAAA;AAAA,UAEC,MAAM;AAAA,UACN,UAAU;AAAA,UACV,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,gBAAgB,CAAC,WAAW;AAAA,YAC7B;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MACA,UAAU;AAAA,QACT;AAAA,UACC,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,cAAc;AAAA,UACd,MAAM;AAAA,UACN,YAAY;AAAA,QACb;AAAA,QACA;AAAA,UACC,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,cAAc;AAAA,UACd,MAAM;AAAA,UACN,eAAe;AAAA,UACf,YAAY;AAAA,QACb;AAAA,MACD;AAAA,MACA,yBAAyB;AAAA,MACzB,mBAAmB;AAAA,MACnB,cAAc;AAAA,MACd,YAAY;AAAA;AAAA;AAAA;AAAA,QAIX;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aACC;AAAA,QACF;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,UACD;AAAA,UACA,SAAS;AAAA,UACT,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,QAAQ,CAAC,IAAI;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aACC;AAAA,UACD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,MAAM,CAAC,YAAY;AAAA,cACnB,QAAQ,CAAC,IAAI;AAAA,YACd;AAAA,UACD;AAAA,UACA,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aACC;AAAA,UACD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,MAAM,CAAC,SAAS;AAAA,cAChB,QAAQ,CAAC,IAAI;AAAA,YACd;AAAA,UACD;AAAA,UACA,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,QAAQ,CAAC,IAAI;AAAA,YACd;AAAA,UACD;AAAA,UACA,SAAS;AAAA,YACR;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA;AAAA,cAEC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,aAAa;AAAA,YACd;AAAA,YACA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,YACR;AAAA,UACD;AAAA,UACA,SAAS;AAAA,UACT,aAAa;AAAA,QACd;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,MAAM,CAAC,YAAY;AAAA,cACnB,QAAQ,CAAC,IAAI;AAAA,YACd;AAAA,UACD;AAAA,UACA,aAAa;AAAA,YACZ,MAAM;AAAA,UACP;AAAA,UACA,SAAS;AAAA,UACT,aAAa;AAAA,QACd;AAAA,QACA;AAAA;AAAA,UAEC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,kBAAkB;AAAA,UAClB,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,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,kBAAkB;AAAA,UAClB,aAAa;AAAA,UACb,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,iBAAiB,CAAC,IAAI;AAAA,YACvB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,YACZ,MAAM;AAAA,UACP;AAAA,UACA,SAAS;AAAA,UACT,kBAAkB;AAAA,UAClB,aAAa;AAAA,UACb,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,iBAAiB,CAAC,IAAI;AAAA,YACvB;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,QAAQ,CAAC,KAAK;AAAA,cACd,YAAY,CAAC,GAAG,GAAG;AAAA,YACpB;AAAA,UACD;AAAA,UACA,aAAa;AAAA,UACb,SAAS,CAAC;AAAA,UACV,SAAS,CAAC,wBAAwB,yBAAyB;AAAA,QAC5D;AAAA;AAAA,QAEA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,MAAM,CAAC,cAAc,SAAS;AAAA,cAC9B,QAAQ,CAAC,IAAI;AAAA,cACb,YAAY,CAAC,GAAG,GAAG;AAAA,YACpB;AAAA,UACD;AAAA,UACA,aAAa;AAAA,UACb,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR,GAAG;AAAA,YACH;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,CAAC,sBAAsB,4BAA4B;AAAA,cAC5D,SAAS;AAAA,cACT,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA;AAAA,QAEA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,MAAM,CAAC,cAAc,SAAS;AAAA,cAC9B,QAAQ,CAAC,IAAI;AAAA,cACb,YAAY,CAAC,GAAG;AAAA,YACjB;AAAA,UACD;AAAA,UACA,aAAa;AAAA,UACb,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR,GAAG;AAAA,YACH;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,CAAC,sBAAsB,8BAA8B,qBAAqB;AAAA,cACnF,SAAS;AAAA,cACT,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,QAAQ,CAAC,KAAK;AAAA,cACd,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,YACpC;AAAA,UACD;AAAA,UACA,aAAa;AAAA,UACb,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,CAAC,sBAAsB,wBAAwB;AAAA,cACxD,SAAS;AAAA,cACT,aAAa;AAAA,YACd;AAAA,UACD;AAAA,QACD;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,gBAAgB;AAAA,YACf,MAAM;AAAA,cACL,MAAM,CAAC,cAAc,SAAS;AAAA,cAC9B,QAAQ,CAAC,IAAI;AAAA,cACb,YAAY,CAAC,EAAE,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC;AAAA,YACpC;AAAA,UACD;AAAA,UACA,aAAa;AAAA,UACb,SAAS,CAAC;AAAA,UACV,SAAS;AAAA,YACR,GAAG;AAAA,YACH;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,CAAC,sBAAsB,uBAAuB,4BAA4B;AAAA,cACnF,SAAS;AAAA,cACT,aAAa;AAAA,cACb,gBAAgB,EAAE,MAAM,EAAE,SAAS,CAAC,SAAS,EAAE,EAAE;AAAA,YAClD;AAAA,YACA;AAAA,cACC,aAAa;AAAA,cACb,MAAM;AAAA,cACN,MAAM;AAAA,cACN,SAAS,CAAC,sBAAsB,uBAAuB,wBAAwB;AAAA,cAC/E,SAAS;AAAA,cACT,aAAa;AAAA,cACb,gBAAgB,EAAE,MAAM,EAAE,SAAS,CAAC,YAAY,EAAE,EAAE;AAAA,YACrD;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAc,eAAe,SAA4B;AACxD,UAAM,MAAM,QAAQ,iBAAiB;AACrC,MAAE,GAAG,IAAI,gBAAgB,uBAAuB,8BAA8B;AAC9E,UAAM,UAAU,QAAQ,iBAAiB,WAAW,CAAC,CAAC;AACtD,UAAM,EAAE,MAAM,MAAM,IAAI,IAAI;AAE5B,UAAM,aAAiC;AAAA,MACtC,MAAM;AAAA,IACP;AAEA,QAAI,SAAS,OAAO,KAAK,KAAK,EAAE,QAAQ;AACvC,iBAAW,KAAK,QAAQ,CAAC;AACzB,iBAAW,SAAS,CAAC;AAErB,YAAM,QAAQ;AACd,iBAAW,WAAW,OAAO,KAAK,KAAK,GAAG;AACzC,cAAM,iBAA2C,CAAC;AAClD,YAAI,MAAM,QAAQ,MAAM,OAAO,CAAC,GAAG;AAClC,yBAAe,KAAK,GAAG,MAAM,OAAO,CAAC;AAAA,QACtC,OAAO;AACN,yBAAe,KAAK,MAAM,OAAO,CAAC;AAAA,QACnC;AAEA,YAAI,YAAY;AAChB,mBAAW,QAAQ,gBAAgB;AAClC,cAAI,qBAAqB;AAGzB,cAAI,mBAAmB,SAAS,IAAI,GAAG;AACtC,iCAAqB,mBAAmB,MAAM,GAAG,EAAE;AAAA,UACpD;AACA,cAAI,QAAQ,oBAAoB;AAC/B,iCAAqB,GAAG,QAAQ,mBAAmB,SAAS,CAAC,GAAG,KAAK;AAAA,UACtE;AAEA,gBAAM,aAAa,MAAM,QAAQ,YAAY;AAAA,YAC5C,KAAK;AAAA,YACL,KAAK,oBAAoB,KAAK;AAAA,YAC9B,KAAK;AAAA,UACN;AAEA,gBAAM,YAAY,GAAG,kBAAkB,GAAG,SAAS;AAEnD,gBAAM,aAAa;AAAA,YAClB,OAAG,YAAAA,SAAK,YAAY,CAAC,YAAY,YAAY,YAAY,YAAY,eAAe,CAAC;AAAA,YACrF;AAAA,UACD;AAEA,qBAAW,SAAS,OAAO,OAAO,WAAW,UAAU,CAAC,GAAG;AAAA,YAC1D,CAAC,GAAG,SAAS,EAAE,GAAG;AAAA,UACnB,CAAC;AACD,qBAAW,KAAK,QAAQ;AAAA,YACvB,GAAI,WAAW,KAAK;AAAA,YACpB;AAAA,UACD;AACA,uBAAa;AAAA,QACd;AAAA,MACD;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,MAAM,QAAQ,KAAuD;AACpE,UAAM,MAAM,IAAI,kBAAkB;AAElC,UAAM,WAAW,IAAI,iBAAiB,UAAU,KAAK;AACrD,kDAAqB,UAAU,UAAU,IAAI,QAAQ,CAAC;AAEtD,UAAM,WAAW,IAAI,iBAAiB,QAAQ,YAAY;AAC1D,iDAAoB,QAAQ,UAAU,IAAI,QAAQ,CAAC;AAEnD,QAAI,CAAC,UAAU;AACd,UAAI,OAAO,GAAG,EAAE,IAAI;AACpB,aAAO;AAAA,QACN,mBAAmB;AAAA,MACpB;AAAA,IACD;AAEA,UAAM,UAAU,IAAI,iBAAiB,WAAW,CAAC,CAAC;AAClD;AAAA,MACC;AAAA,MACA;AAAA,QACC,YAAY,EAAE,MAAM,SAAS;AAAA,QAC7B,kBAAkB,EAAE,MAAM,SAAS;AAAA,QACnC,qBAAqB,EAAE,MAAM,SAAS;AAAA,QACtC,mBAAmB,EAAE,MAAM,UAAU;AAAA,QACrC,UAAU,EAAE,MAAM,SAAS;AAAA,QAC3B,OAAO,EAAE,MAAM,SAAS;AAAA,QACxB,kBAAkB,EAAE,MAAM,UAAU;AAAA,QACpC,uBAAuB,EAAE,MAAM,SAAS;AAAA,QACxC,WAAW,EAAE,MAAM,SAAS;AAAA,QAC5B,cAAc,EAAE,MAAM,SAAS;AAAA,MAChC;AAAA,MACA,IAAI,QAAQ;AAAA,IACb;AAEA,UAAM,sBAAsB,QAAQ;AACpC,2DAAqC,qBAAqB,IAAI,QAAQ,CAAC;AAEvE,UAAM,kBAAkB,QAAQ,iBAAiB;AAEjD,UAAM,MAAM,IAAI,iBAAiB;AACjC,UAAM,cAAc,IAAI,eAAe;AACvC,UAAM,OAAO,IAAI,QAAQ,MAAM,WAAW,SAAS;AACnD,UAAM,WAAW,IAAI,YAAY,KAAK,CAAC;AAEvC,QAAI;AACH,gBAAM,sCAAa,GAAG;AAAA,IACvB,SAAS,OAAO;AACf,UAAI,OAAO;AACV,YAAI,UAAW,MAAsB,cAAwB;AAAA,UAC5D,oBAAoB;AAAA,QACrB,CAAC;AACD,YAAI,IAAK,MAAsB,OAAiB;AAChD,eAAO,EAAE,mBAAmB,KAAK;AAAA,MAClC;AACA,YAAM;AAAA,IACP;AACA,QAAI,aAAa,cAAc;AAE9B,UAAI,gBAAgB,SAAS;AAC5B,cAAM,gBAAgB,IAAI,kBAAkB,SAAS;AACrD,YAAI,CAAC,eAAe;AACnB,gBAAM,IAAI,uCAAmB,IAAI,QAAQ,GAAG,6BAA6B;AAAA,QAC1E;AAEA,cAAM,aACL,SAAS,SAAS,cAAc,QAAQ,YAAY,eAAe,IAAI;AACxE,cAAM,iBAAiB,IAAI,iBAAiB,gBAAgB;AAI5D,cAAM,qBAAqB,IAAI,iBAAiB,mBAAmB,EAAE;AACrE,qDAAoB,kBAAkB,oBAAoB,IAAI,QAAQ,CAAC;AACvE,cAAM,aAAa,IAAI,cAAc;AAErC,cAAM,aAAqC,CAAC;AAC5C,cAAM,OAAO,CAAC,cAAc,oBAAoB,YAAY,OAAO;AACnE,mBAAW,OAAO,MAAM;AACvB,cAAI,QAAQ,GAAG,MAAM,QAAW;AAC/B,uBAAW,GAAG,IAAI,QAAQ,GAAG;AAAA,UAC9B;AAAA,QACD;AAEA,cAAM,WAAO,6BAAW;AAAA,UACvB,MAAM;AAAA,YACL,IAAI;AAAA,UACL;AAAA,UACA,mBAAmB,QAAQ;AAAA,UAC3B;AAAA,UACA,iBAAiB;AAAA,UACjB;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,kBAAkB,QAAQ;AAAA,UAC1B,uBAAuB,QAAQ;AAAA,UAC/B,WAAW,QAAQ;AAAA,UACnB;AAAA,QACD,CAAC;AAED,YAAI,OAAO,GAAG,EAAE,KAAK,IAAI,EAAE,IAAI;AAC/B,eAAO;AAAA,UACN,mBAAmB;AAAA,QACpB;AAAA,MACD;AAAA,IACD;AAEA,QAAI,SAAS,WAAW,uBAAuB;AAC9C,UAAI,SAAS,wBAAwB,UAAU;AAC9C,cAAM,SAAU,MAAM,IAAI,uBAAuB,wCAAoB,UAAU,CAAC;AAGhF,cAAM,YAAa,MAAM,QAAQ,YAAY,YAAY,KAAM,CAAC,GAC9D,OAAO,CAAC,YAAY,CAAC,SAAS,mBAAmB,UAAU,EAC3D,IAAI,CAAC,YAAY,SAAS,OAAO,CAAC;AACpC,eAAO;AAAA,UACN,iBAAiB,EAAE,MAAM,SAAS;AAAA,QACnC;AAAA,MACD,WAAW,CAAC,SAAS,uBAAuB,SAAS,wBAAwB,gBAAgB;AAE5F,eAAO;AAAA,UACN,iBAAiB,EAAE,MAAM,CAAC,EAAE;AAAA,QAC7B;AAAA,MACD;AAAA,IACD;AAEA,QAAI;AACJ,UAAM,kBAA+B,EAAE,QAAQ,IAAI;AAGnD,QAAI,iBAAiB;AAEpB,UAAI,UAAU,KAAK;AAAA,QAClB,gBAAgB;AAAA,QAChB,qBAAqB;AAAA,QACrB,iBAAiB;AAAA,QACjB,YAAY;AAAA,MACb,CAAC;AAGD,UAAI,aAAa;AAEjB,UAAI,IAAI,gBAAgB,uBAAuB;AAC9C,qBAAa,CAAC,MAAM,KAAK,eAAe,GAAG,CAAC;AAAA,MAC7C,OAAO;AACN,qBAAa,CAAC,EAAE,MAAM,SAAS,CAAC;AAAA,MACjC;AAEA,aAAO;AAAA,QACN,cAAc,CAAC,IAAI,QAAQ,gBAAgB,UAAU,CAAC;AAAA,QACtD,mBAAmB;AAAA,MACpB;AAAA,IACD;AAEA,QAAI,IAAI,gBAAgB,uBAAuB;AAC9C,mBAAa,CAAC,MAAM,KAAK,eAAe,GAAG,CAAC;AAC5C,aAAO;AAAA,QACN;AAAA,QACA,cAAc,CAAC,UAAU;AAAA,MAC1B;AAAA,IACD,OAAO;AACN,mBAAa,CAAC,EAAE,MAAM,SAAS,CAAC;AAAA,IACjC;AAEA,WAAO;AAAA,MACN;AAAA,MACA,cAAc,CAAC,IAAI,QAAQ,gBAAgB,UAAU,CAAC;AAAA,IACvD;AAAA,EACD;AACD;","names":["pick"]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/trigger/ChatTrigger/ChatTrigger.node.ts"],"sourcesContent":["import type { BaseChatMemory } from '@langchain/community/memory/chat_memory';\nimport pick from 'lodash/pick';\nimport {\n\tNode,\n\tNodeConnectionTypes,\n\tNodeOperationError,\n\tassertParamIsBoolean,\n\tvalidateNodeParameters,\n\tassertParamIsString,\n} from 'n8n-workflow';\nimport type {\n\tIDataObject,\n\tIWebhookFunctions,\n\tIWebhookResponseData,\n\tINodeTypeDescription,\n\tMultiPartFormData,\n\tINodeExecutionData,\n\tIBinaryData,\n\tINodeProperties,\n} from 'n8n-workflow';\nimport * as a from 'node:assert';\n\nimport { cssVariables } from './constants';\nimport { validateAuth } from './GenericFunctions';\nimport { createPage } from './templates';\nimport { assertValidLoadPreviousSessionOption } from './types';\n\nconst CHAT_TRIGGER_PATH_IDENTIFIER = 'chat';\nconst allowFileUploadsOption: INodeProperties = {\n\tdisplayName: 'Allow File Uploads',\n\tname: 'allowFileUploads',\n\ttype: 'boolean',\n\tdefault: false,\n\tdescription: 'Whether to allow file uploads in the chat',\n};\nconst allowedFileMimeTypeOption: INodeProperties = {\n\tdisplayName: 'Allowed File Mime Types',\n\tname: 'allowedFilesMimeTypes',\n\ttype: 'string',\n\tdefault: '*',\n\tplaceholder: 'e.g. image/*, text/*, application/pdf',\n\tdescription:\n\t\t'Allowed file types for upload. Comma-separated list of <a href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types\" target=\"_blank\">MIME types</a>.',\n};\n\nconst respondToWebhookResponseMode = {\n\tname: \"Using 'Respond to Webhook' Node\",\n\tvalue: 'responseNode',\n\tdescription: 'Response defined in that node',\n};\n\nconst lastNodeResponseMode = {\n\tname: 'When Last Node Finishes',\n\tvalue: 'lastNode',\n\tdescription: 'Returns data of the last-executed node',\n};\n\nconst streamingResponseMode = {\n\tname: 'Streaming',\n\tvalue: 'streaming',\n\tdescription: 'Streaming response from specified nodes (e.g. Agents)',\n};\n\nconst respondNodesResponseMode = {\n\tname: 'Using Response Nodes',\n\tvalue: 'responseNodes',\n\tdescription: \"Send responses to the chat by using 'Respond to Chat' node\",\n};\n\nconst commonOptionsFields: INodeProperties[] = [\n\t// CORS parameters are only valid for when chat is used in hosted or webhook mode\n\t{\n\t\tdisplayName: 'Allowed Origins (CORS)',\n\t\tname: 'allowedOrigins',\n\t\ttype: 'string',\n\t\tdefault: '*',\n\t\tdescription:\n\t\t\t'Comma-separated list of URLs allowed for cross-origin non-preflight requests. Use * (default) to allow all origins.',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat', 'webhook'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...allowFileUploadsOption,\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\t...allowedFileMimeTypeOption,\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t},\n\t{\n\t\tdisplayName: 'Input Placeholder',\n\t\tname: 'inputPlaceholder',\n\t\ttype: 'string',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: 'Type your question..',\n\t\tplaceholder: 'e.g. Type your message here',\n\t\tdescription: 'Shown as placeholder text in the chat input field',\n\t},\n\t{\n\t\tdisplayName: 'Load Previous Session',\n\t\tname: 'loadPreviousSession',\n\t\ttype: 'options',\n\t\toptions: [\n\t\t\t{\n\t\t\t\tname: 'Off',\n\t\t\t\tvalue: 'notSupported',\n\t\t\t\tdescription: 'Loading messages of previous session is turned off',\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'From Memory',\n\t\t\t\tvalue: 'memory',\n\t\t\t\tdescription: 'Load session messages from memory',\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'Manually',\n\t\t\t\tvalue: 'manually',\n\t\t\t\tdescription: 'Manually return messages of session',\n\t\t\t},\n\t\t],\n\t\tdefault: 'notSupported',\n\t\tdescription: 'If loading messages of a previous session should be enabled',\n\t},\n\t{\n\t\tdisplayName: 'Require Button Click to Start Chat',\n\t\tname: 'showWelcomeScreen',\n\t\ttype: 'boolean',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: false,\n\t\tdescription: 'Whether to show the welcome screen at the start of the chat',\n\t},\n\t{\n\t\tdisplayName: 'Start Conversation Button Text',\n\t\tname: 'getStarted',\n\t\ttype: 'string',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\tshowWelcomeScreen: [true],\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: 'New Conversation',\n\t\tplaceholder: 'e.g. New Conversation',\n\t\tdescription: 'Shown as part of the welcome screen, in the middle of the chat window',\n\t},\n\t{\n\t\tdisplayName: 'Subtitle',\n\t\tname: 'subtitle',\n\t\ttype: 'string',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: \"Start a chat. We're here to help you 24/7.\",\n\t\tplaceholder: \"e.g. We're here for you\",\n\t\tdescription: 'Shown at the top of the chat, under the title',\n\t},\n\t{\n\t\tdisplayName: 'Title',\n\t\tname: 'title',\n\t\ttype: 'string',\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: 'Hi there! 👋',\n\t\tplaceholder: 'e.g. Welcome',\n\t\tdescription: 'Shown at the top of the chat',\n\t},\n\t{\n\t\tdisplayName: 'Custom Chat Styling',\n\t\tname: 'customCss',\n\t\ttype: 'string',\n\t\ttypeOptions: {\n\t\t\trows: 10,\n\t\t\teditor: 'cssEditor',\n\t\t},\n\t\tdisplayOptions: {\n\t\t\tshow: {\n\t\t\t\t'/mode': ['hostedChat'],\n\t\t\t},\n\t\t},\n\t\tdefault: `\n${cssVariables}\n\n/* You can override any class styles, too. Right-click inspect in Chat UI to find class to override. */\n.chat-message {\n\tmax-width: 50%;\n}\n`.trim(),\n\t\tdescription: 'Override default styling of the public chat interface with CSS',\n\t},\n];\n\nexport class ChatTrigger extends Node {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'Chat Trigger',\n\t\tname: 'chatTrigger',\n\t\ticon: 'fa:comments',\n\t\ticonColor: 'black',\n\t\tgroup: ['trigger'],\n\t\tversion: [1, 1.1, 1.2, 1.3, 1.4],\n\t\tdefaultVersion: 1.4,\n\t\tdescription: 'Runs the workflow when an n8n generated webchat is submitted',\n\t\tdefaults: {\n\t\t\tname: 'When chat message received',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['Core Nodes'],\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/core-nodes/n8n-nodes-langchain.chattrigger/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\t\tmaxNodes: 1,\n\t\tinputs: `={{ (() => {\n\t\t\tif (!['hostedChat', 'webhook'].includes($parameter.mode)) {\n\t\t\t\treturn [];\n\t\t\t}\n\t\t\tif ($parameter.options?.loadPreviousSession !== 'memory') {\n\t\t\t\treturn [];\n\t\t\t}\n\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Memory',\n\t\t\t\t\tmaxConnections: 1,\n\t\t\t\t\ttype: '${NodeConnectionTypes.AiMemory}',\n\t\t\t\t\trequired: true,\n\t\t\t\t}\n\t\t\t];\n\t\t })() }}`,\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-class-description-credentials-name-unsuffixed\n\t\t\t\tname: 'httpBasicAuth',\n\t\t\t\trequired: true,\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tauthentication: ['basicAuth'],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\twebhooks: [\n\t\t\t{\n\t\t\t\tname: 'setup',\n\t\t\t\thttpMethod: 'GET',\n\t\t\t\tresponseMode: 'onReceived',\n\t\t\t\tpath: CHAT_TRIGGER_PATH_IDENTIFIER,\n\t\t\t\tndvHideUrl: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tname: 'default',\n\t\t\t\thttpMethod: 'POST',\n\t\t\t\tresponseMode: '={{$parameter.options?.[\"responseMode\"] || \"lastNode\" }}',\n\t\t\t\tpath: CHAT_TRIGGER_PATH_IDENTIFIER,\n\t\t\t\tndvHideMethod: true,\n\t\t\t\tndvHideUrl: '={{ !$parameter.public }}',\n\t\t\t},\n\t\t],\n\t\teventTriggerDescription: 'Waiting for you to submit the chat',\n\t\tactivationMessage: 'You can now make calls to your production chat URL.',\n\t\ttriggerPanel: false,\n\t\tproperties: [\n\t\t\t/**\n\t\t\t * @note If we change this property, also update it in ChatEmbedModal.vue\n\t\t\t */\n\t\t\t{\n\t\t\t\tdisplayName: 'Make Chat Publicly Available',\n\t\t\t\tname: 'public',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether the chat should be publicly available or only accessible through the manual chat interface',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Mode',\n\t\t\t\tname: 'mode',\n\t\t\t\ttype: 'options',\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Hosted Chat',\n\t\t\t\t\t\tvalue: 'hostedChat',\n\t\t\t\t\t\tdescription: 'Chat on a page served by n8n',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Embedded Chat',\n\t\t\t\t\t\tvalue: 'webhook',\n\t\t\t\t\t\tdescription: 'Chat through a widget embedded in another page, or by calling a webhook',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'hostedChat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [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:\n\t\t\t\t\t'Chat will be live at the URL above once you activate this workflow. Live executions will show up in the ‘executions’ tab',\n\t\t\t\tname: 'hostedChatNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'Follow the instructions <a href=\"https://www.npmjs.com/package/@n8n/chat\" target=\"_blank\">here</a> to embed chat in a webpage (or just call the webhook URL at the top of this section). Chat will be live once you activate this workflow',\n\t\t\t\tname: 'embeddedChatNotice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['webhook'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Authentication',\n\t\t\t\tname: 'authentication',\n\t\t\t\ttype: 'options',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\toptions: [\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'Basic Auth',\n\t\t\t\t\t\tvalue: 'basicAuth',\n\t\t\t\t\t\tdescription: 'Simple username and password (the same one for all users)',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\t// eslint-disable-next-line n8n-nodes-base/node-param-display-name-miscased\n\t\t\t\t\t\tname: 'n8n User Auth',\n\t\t\t\t\t\tvalue: 'n8nUserAuth',\n\t\t\t\t\t\tdescription: 'Require user to be logged in with their n8n account',\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tname: 'None',\n\t\t\t\t\t\tvalue: 'none',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tdefault: 'none',\n\t\t\t\tdescription: 'The way to authenticate',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Initial Message(s)',\n\t\t\t\tname: 'initialMessages',\n\t\t\t\ttype: 'string',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 3,\n\t\t\t\t},\n\t\t\t\tdefault: 'Hi there! 👋\\nMy name is Nathan. How can I assist you today?',\n\t\t\t\tdescription: 'Default messages shown at the start of the chat, one per line',\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\tdisplayName: 'Make Available in n8n Chat',\n\t\t\t\tname: 'availableInChat',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'Whether to make the agent available in n8n Chat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\t'@version': [{ _cnd: { gte: 1.4 } }],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Agent Name',\n\t\t\t\tname: 'agentName',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: '',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'The name of the agent on n8n Chat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tavailableInChat: [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: 'Agent Description',\n\t\t\t\tname: 'agentDescription',\n\t\t\t\ttype: 'string',\n\t\t\t\ttypeOptions: {\n\t\t\t\t\trows: 2,\n\t\t\t\t},\n\t\t\t\tdefault: '',\n\t\t\t\tnoDataExpression: true,\n\t\t\t\tdescription: 'The description of the agent on n8n Chat',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tavailableInChat: [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\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [false],\n\t\t\t\t\t\t'@version': [1, 1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [allowFileUploadsOption, allowedFileMimeTypeOption],\n\t\t\t},\n\t\t\t// Options for versions 1.0 and 1.1 (without streaming)\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat', 'webhook'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t\t'@version': [1, 1.1],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t...commonOptionsFields,\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, respondToWebhookResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the webhook',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t\t// Options for version 1.2 (with streaming)\n\t\t\t{\n\t\t\t\tdisplayName: 'Options',\n\t\t\t\tname: 'options',\n\t\t\t\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat', 'webhook'],\n\t\t\t\t\t\tpublic: [true],\n\t\t\t\t\t\t'@version': [1.2],\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t...commonOptionsFields,\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, respondToWebhookResponseMode, streamingResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the webhook',\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\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tpublic: [false],\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\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\tallowFileUploadsOption,\n\t\t\t\t\tallowedFileMimeTypeOption,\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, respondNodesResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the chat',\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\ttype: 'collection',\n\t\t\t\tdisplayOptions: {\n\t\t\t\t\tshow: {\n\t\t\t\t\t\tmode: ['hostedChat', 'webhook'],\n\t\t\t\t\t\tpublic: [true],\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\tplaceholder: 'Add Field',\n\t\t\t\tdefault: {},\n\t\t\t\toptions: [\n\t\t\t\t\t...commonOptionsFields,\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, streamingResponseMode, respondToWebhookResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the chat',\n\t\t\t\t\t\tdisplayOptions: { show: { '/mode': ['webhook'] } },\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tdisplayName: 'Response Mode',\n\t\t\t\t\t\tname: 'responseMode',\n\t\t\t\t\t\ttype: 'options',\n\t\t\t\t\t\toptions: [lastNodeResponseMode, streamingResponseMode, respondNodesResponseMode],\n\t\t\t\t\t\tdefault: 'lastNode',\n\t\t\t\t\t\tdescription: 'When and how to respond to the webhook',\n\t\t\t\t\t\tdisplayOptions: { show: { '/mode': ['hostedChat'] } },\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t],\n\t};\n\n\tprivate async handleFormData(context: IWebhookFunctions) {\n\t\tconst req = context.getRequestObject() as MultiPartFormData.Request;\n\t\ta.ok(req.contentType === 'multipart/form-data', 'Expected multipart/form-data');\n\t\tconst options = context.getNodeParameter('options', {}) as IDataObject;\n\t\tconst { data, files } = req.body;\n\n\t\tconst returnItem: INodeExecutionData = {\n\t\t\tjson: data,\n\t\t};\n\n\t\tif (files && Object.keys(files).length) {\n\t\t\treturnItem.json.files = [] as Array<Omit<IBinaryData, 'data'>>;\n\t\t\treturnItem.binary = {};\n\n\t\t\tconst count = 0;\n\t\t\tfor (const fileKey of Object.keys(files)) {\n\t\t\t\tconst processedFiles: MultiPartFormData.File[] = [];\n\t\t\t\tif (Array.isArray(files[fileKey])) {\n\t\t\t\t\tprocessedFiles.push(...files[fileKey]);\n\t\t\t\t} else {\n\t\t\t\t\tprocessedFiles.push(files[fileKey]);\n\t\t\t\t}\n\n\t\t\t\tlet fileIndex = 0;\n\t\t\t\tfor (const file of processedFiles) {\n\t\t\t\t\tlet binaryPropertyName = 'data';\n\n\t\t\t\t\t// Remove the '[]' suffix from the binaryPropertyName if it exists\n\t\t\t\t\tif (binaryPropertyName.endsWith('[]')) {\n\t\t\t\t\t\tbinaryPropertyName = binaryPropertyName.slice(0, -2);\n\t\t\t\t\t}\n\t\t\t\t\tif (options.binaryPropertyName) {\n\t\t\t\t\t\tbinaryPropertyName = `${options.binaryPropertyName.toString()}${count}`;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst binaryFile = await context.nodeHelpers.copyBinaryFile(\n\t\t\t\t\t\tfile.filepath,\n\t\t\t\t\t\tfile.originalFilename ?? file.newFilename,\n\t\t\t\t\t\tfile.mimetype,\n\t\t\t\t\t);\n\n\t\t\t\t\tconst binaryKey = `${binaryPropertyName}${fileIndex}`;\n\n\t\t\t\t\tconst binaryInfo = {\n\t\t\t\t\t\t...pick(binaryFile, ['fileName', 'fileSize', 'fileType', 'mimeType', 'fileExtension']),\n\t\t\t\t\t\tbinaryKey,\n\t\t\t\t\t};\n\n\t\t\t\t\treturnItem.binary = Object.assign(returnItem.binary ?? {}, {\n\t\t\t\t\t\t[`${binaryKey}`]: binaryFile,\n\t\t\t\t\t});\n\t\t\t\t\treturnItem.json.files = [\n\t\t\t\t\t\t...(returnItem.json.files as Array<Omit<IBinaryData, 'data'>>),\n\t\t\t\t\t\tbinaryInfo,\n\t\t\t\t\t];\n\t\t\t\t\tfileIndex += 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn returnItem;\n\t}\n\n\tasync webhook(ctx: IWebhookFunctions): Promise<IWebhookResponseData> {\n\t\tconst res = ctx.getResponseObject();\n\n\t\tconst isPublic = ctx.getNodeParameter('public', false);\n\t\tassertParamIsBoolean('public', isPublic, ctx.getNode());\n\n\t\tconst nodeMode = ctx.getNodeParameter('mode', 'hostedChat');\n\t\tassertParamIsString('mode', nodeMode, ctx.getNode());\n\n\t\tif (!isPublic) {\n\t\t\tres.status(404).end();\n\t\t\treturn {\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\n\t\tconst options = ctx.getNodeParameter('options', {});\n\t\tvalidateNodeParameters(\n\t\t\toptions,\n\t\t\t{\n\t\t\t\tgetStarted: { type: 'string' },\n\t\t\t\tinputPlaceholder: { type: 'string' },\n\t\t\t\tloadPreviousSession: { type: 'string' },\n\t\t\t\tshowWelcomeScreen: { type: 'boolean' },\n\t\t\t\tsubtitle: { type: 'string' },\n\t\t\t\ttitle: { type: 'string' },\n\t\t\t\tallowFileUploads: { type: 'boolean' },\n\t\t\t\tallowedFilesMimeTypes: { type: 'string' },\n\t\t\t\tcustomCss: { type: 'string' },\n\t\t\t\tresponseMode: { type: 'string' },\n\t\t\t},\n\t\t\tctx.getNode(),\n\t\t);\n\n\t\tconst loadPreviousSession = options.loadPreviousSession;\n\t\tassertValidLoadPreviousSessionOption(loadPreviousSession, ctx.getNode());\n\n\t\tconst enableStreaming = options.responseMode === 'streaming';\n\n\t\tconst req = ctx.getRequestObject();\n\t\tconst webhookName = ctx.getWebhookName();\n\t\tconst mode = ctx.getMode() === 'manual' ? 'test' : 'production';\n\t\tconst bodyData = ctx.getBodyData() ?? {};\n\n\t\ttry {\n\t\t\tawait validateAuth(ctx);\n\t\t} catch (error) {\n\t\t\tif (error) {\n\t\t\t\tres.writeHead((error as IDataObject).responseCode as number, {\n\t\t\t\t\t'www-authenticate': 'Basic realm=\"Webhook\"',\n\t\t\t\t});\n\t\t\t\tres.end((error as IDataObject).message as string);\n\t\t\t\treturn { noWebhookResponse: true };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t\tif (nodeMode === 'hostedChat') {\n\t\t\t// Show the chat on GET request\n\t\t\tif (webhookName === 'setup') {\n\t\t\t\tconst webhookUrlRaw = ctx.getNodeWebhookUrl('default');\n\t\t\t\tif (!webhookUrlRaw) {\n\t\t\t\t\tthrow new NodeOperationError(ctx.getNode(), 'Default webhook url not set');\n\t\t\t\t}\n\n\t\t\t\tconst webhookUrl =\n\t\t\t\t\tmode === 'test' ? webhookUrlRaw.replace('/webhook', '/webhook-test') : webhookUrlRaw;\n\t\t\t\tconst authentication = ctx.getNodeParameter('authentication') as\n\t\t\t\t\t| 'none'\n\t\t\t\t\t| 'basicAuth'\n\t\t\t\t\t| 'n8nUserAuth';\n\t\t\t\tconst initialMessagesRaw = ctx.getNodeParameter('initialMessages', '');\n\t\t\t\tassertParamIsString('initialMessage', initialMessagesRaw, ctx.getNode());\n\t\t\t\tconst instanceId = ctx.getInstanceId();\n\n\t\t\t\tconst i18nConfig: Record<string, string> = {};\n\t\t\t\tconst keys = ['getStarted', 'inputPlaceholder', 'subtitle', 'title'] as const;\n\t\t\t\tfor (const key of keys) {\n\t\t\t\t\tif (options[key] !== undefined) {\n\t\t\t\t\t\ti18nConfig[key] = options[key];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tconst page = createPage({\n\t\t\t\t\ti18n: {\n\t\t\t\t\t\ten: i18nConfig,\n\t\t\t\t\t},\n\t\t\t\t\tshowWelcomeScreen: options.showWelcomeScreen,\n\t\t\t\t\tloadPreviousSession,\n\t\t\t\t\tinitialMessages: initialMessagesRaw,\n\t\t\t\t\twebhookUrl,\n\t\t\t\t\tmode,\n\t\t\t\t\tinstanceId,\n\t\t\t\t\tauthentication,\n\t\t\t\t\tallowFileUploads: options.allowFileUploads,\n\t\t\t\t\tallowedFilesMimeTypes: options.allowedFilesMimeTypes,\n\t\t\t\t\tcustomCss: options.customCss,\n\t\t\t\t\tenableStreaming,\n\t\t\t\t});\n\n\t\t\t\tres.status(200).send(page).end();\n\t\t\t\treturn {\n\t\t\t\t\tnoWebhookResponse: true,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif (bodyData.action === 'loadPreviousSession') {\n\t\t\tif (options?.loadPreviousSession === 'memory') {\n\t\t\t\tconst memory = (await ctx.getInputConnectionData(NodeConnectionTypes.AiMemory, 0)) as\n\t\t\t\t\t| BaseChatMemory\n\t\t\t\t\t| undefined;\n\t\t\t\tconst messages = ((await memory?.chatHistory.getMessages()) ?? [])\n\t\t\t\t\t.filter((message) => !message?.additional_kwargs?.hideFromUI)\n\t\t\t\t\t.map((message) => message?.toJSON());\n\t\t\t\treturn {\n\t\t\t\t\twebhookResponse: { data: messages },\n\t\t\t\t};\n\t\t\t} else if (!options?.loadPreviousSession || options?.loadPreviousSession === 'notSupported') {\n\t\t\t\t// If messages of a previous session should not be loaded, simply return an empty array\n\t\t\t\treturn {\n\t\t\t\t\twebhookResponse: { data: [] },\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tlet returnData: INodeExecutionData[];\n\t\tconst webhookResponse: IDataObject = { status: 200 };\n\n\t\t// Handle streaming responses\n\t\tif (enableStreaming) {\n\t\t\t// Set up streaming response headers\n\t\t\tres.writeHead(200, {\n\t\t\t\t'Content-Type': 'application/json; charset=utf-8',\n\t\t\t\t'Transfer-Encoding': 'chunked',\n\t\t\t\t'Cache-Control': 'no-cache',\n\t\t\t\tConnection: 'keep-alive',\n\t\t\t});\n\n\t\t\t// Flush headers immediately\n\t\t\tres.flushHeaders();\n\n\t\t\tif (req.contentType === 'multipart/form-data') {\n\t\t\t\treturnData = [await this.handleFormData(ctx)];\n\t\t\t} else {\n\t\t\t\treturnData = [{ json: bodyData }];\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tworkflowData: [ctx.helpers.returnJsonArray(returnData)],\n\t\t\t\tnoWebhookResponse: true,\n\t\t\t};\n\t\t}\n\n\t\tif (req.contentType === 'multipart/form-data') {\n\t\t\treturnData = [await this.handleFormData(ctx)];\n\t\t\treturn {\n\t\t\t\twebhookResponse,\n\t\t\t\tworkflowData: [returnData],\n\t\t\t};\n\t\t} else {\n\t\t\treturnData = [{ json: bodyData }];\n\t\t}\n\n\t\treturn {\n\t\t\twebhookResponse,\n\t\t\tworkflowData: [ctx.helpers.returnJsonArray(returnData)],\n\t\t};\n\t}\n}\n"],"mappings":"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","names":["pick"]}
|
|
@@ -24,11 +24,12 @@ __export(VectorStoreAzureAISearch_node_exports, {
|
|
|
24
24
|
QUERY_TYPE: () => QUERY_TYPE,
|
|
25
25
|
SEMANTIC_CONFIGURATION: () => SEMANTIC_CONFIGURATION,
|
|
26
26
|
VectorStoreAzureAISearch: () => VectorStoreAzureAISearch,
|
|
27
|
+
clearAzureSearchIndex: () => clearAzureSearchIndex,
|
|
27
28
|
getIndexName: () => getIndexName
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(VectorStoreAzureAISearch_node_exports);
|
|
30
|
-
var import_azure_aisearch = require("@langchain/community/vectorstores/azure_aisearch");
|
|
31
31
|
var import_search_documents = require("@azure/search-documents");
|
|
32
|
+
var import_azure_aisearch = require("@langchain/community/vectorstores/azure_aisearch");
|
|
32
33
|
var import_n8n_workflow = require("n8n-workflow");
|
|
33
34
|
var import_createVectorStoreNode = require("../shared/createVectorStoreNode/createVectorStoreNode");
|
|
34
35
|
const USER_AGENT_PREFIX = "n8n-azure-ai-search";
|
|
@@ -100,7 +101,24 @@ const retrieveFields = [
|
|
|
100
101
|
options: [queryTypeField, filterField, semanticConfigurationField]
|
|
101
102
|
}
|
|
102
103
|
];
|
|
103
|
-
const insertFields = [
|
|
104
|
+
const insertFields = [
|
|
105
|
+
{
|
|
106
|
+
displayName: "Options",
|
|
107
|
+
name: "options",
|
|
108
|
+
type: "collection",
|
|
109
|
+
placeholder: "Add Option",
|
|
110
|
+
default: {},
|
|
111
|
+
options: [
|
|
112
|
+
{
|
|
113
|
+
displayName: "Clear Index",
|
|
114
|
+
name: "clearIndex",
|
|
115
|
+
type: "boolean",
|
|
116
|
+
default: false,
|
|
117
|
+
description: "Whether to delete and recreate the index before inserting new data. Warning: This will reset any custom index configuration (semantic ranking, analyzers, etc.) to defaults."
|
|
118
|
+
}
|
|
119
|
+
]
|
|
120
|
+
}
|
|
121
|
+
];
|
|
104
122
|
function isExecutionContext(context) {
|
|
105
123
|
return "addInputData" in context;
|
|
106
124
|
}
|
|
@@ -121,26 +139,54 @@ function getOptionValue(name, context, itemIndex, defaultValue) {
|
|
|
121
139
|
const options = context.getNodeParameter("options", itemIndex, {});
|
|
122
140
|
return options[name] !== void 0 ? options[name] : defaultValue;
|
|
123
141
|
}
|
|
124
|
-
async function
|
|
142
|
+
async function getValidatedCredentials(context, itemIndex) {
|
|
125
143
|
const credentials = await context.getCredentials(AZURE_AI_SEARCH_CREDENTIALS);
|
|
144
|
+
if (!credentials.endpoint || typeof credentials.endpoint !== "string") {
|
|
145
|
+
throw new import_n8n_workflow.NodeOperationError(
|
|
146
|
+
context.getNode(),
|
|
147
|
+
"Azure AI Search endpoint is missing or invalid",
|
|
148
|
+
{ itemIndex }
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
if (!credentials.apiKey || typeof credentials.apiKey !== "string") {
|
|
152
|
+
throw new import_n8n_workflow.NodeOperationError(context.getNode(), "API Key is required for authentication", {
|
|
153
|
+
itemIndex
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return {
|
|
157
|
+
endpoint: credentials.endpoint,
|
|
158
|
+
apiKey: credentials.apiKey
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
async function clearAzureSearchIndex(context, itemIndex) {
|
|
162
|
+
const options = context.getNodeParameter("options", itemIndex, {});
|
|
163
|
+
if (!options.clearIndex) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
const credentials = await getValidatedCredentials(context, itemIndex);
|
|
167
|
+
const indexName = getIndexName(context, itemIndex);
|
|
168
|
+
try {
|
|
169
|
+
const indexClient = new import_search_documents.SearchIndexClient(
|
|
170
|
+
credentials.endpoint,
|
|
171
|
+
new import_search_documents.AzureKeyCredential(credentials.apiKey)
|
|
172
|
+
);
|
|
173
|
+
await indexClient.deleteIndex(indexName);
|
|
174
|
+
context.logger.debug(`Deleted Azure AI Search index: ${indexName}`);
|
|
175
|
+
return true;
|
|
176
|
+
} catch (deleteError) {
|
|
177
|
+
context.logger.debug("Error deleting index (may not exist):", {
|
|
178
|
+
message: deleteError instanceof Error ? deleteError.message : String(deleteError)
|
|
179
|
+
});
|
|
180
|
+
return false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
async function getAzureAISearchClient(context, embeddings, itemIndex) {
|
|
184
|
+
const credentials = await getValidatedCredentials(context, itemIndex);
|
|
126
185
|
try {
|
|
127
186
|
const indexName = getIndexName(context, itemIndex);
|
|
128
|
-
if (!credentials.endpoint || typeof credentials.endpoint !== "string") {
|
|
129
|
-
throw new import_n8n_workflow.NodeOperationError(
|
|
130
|
-
context.getNode(),
|
|
131
|
-
"Azure AI Search endpoint is missing or invalid",
|
|
132
|
-
{ itemIndex }
|
|
133
|
-
);
|
|
134
|
-
}
|
|
135
|
-
const endpoint = credentials.endpoint;
|
|
136
|
-
if (!credentials.apiKey || typeof credentials.apiKey !== "string") {
|
|
137
|
-
throw new import_n8n_workflow.NodeOperationError(context.getNode(), "API Key is required for authentication", {
|
|
138
|
-
itemIndex
|
|
139
|
-
});
|
|
140
|
-
}
|
|
141
187
|
const azureCredentials = new import_search_documents.AzureKeyCredential(credentials.apiKey);
|
|
142
188
|
const config = {
|
|
143
|
-
endpoint,
|
|
189
|
+
endpoint: credentials.endpoint,
|
|
144
190
|
indexName,
|
|
145
191
|
credentials: azureCredentials,
|
|
146
192
|
search: {},
|
|
@@ -267,6 +313,7 @@ class VectorStoreAzureAISearch extends (0, import_createVectorStoreNode.createVe
|
|
|
267
313
|
},
|
|
268
314
|
async populateVectorStore(context, embeddings, documents, itemIndex) {
|
|
269
315
|
try {
|
|
316
|
+
await clearAzureSearchIndex(context, itemIndex);
|
|
270
317
|
const vectorStore = await getAzureAISearchClient(context, embeddings, itemIndex);
|
|
271
318
|
await vectorStore.addDocuments(documents);
|
|
272
319
|
} catch (error) {
|
|
@@ -335,6 +382,7 @@ Check the console logs for detailed error information.`
|
|
|
335
382
|
QUERY_TYPE,
|
|
336
383
|
SEMANTIC_CONFIGURATION,
|
|
337
384
|
VectorStoreAzureAISearch,
|
|
385
|
+
clearAzureSearchIndex,
|
|
338
386
|
getIndexName
|
|
339
387
|
});
|
|
340
388
|
//# sourceMappingURL=VectorStoreAzureAISearch.node.js.map
|
package/dist/nodes/vector_store/VectorStoreAzureAISearch/VectorStoreAzureAISearch.node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/vector_store/VectorStoreAzureAISearch/VectorStoreAzureAISearch.node.ts"],"sourcesContent":["import type { EmbeddingsInterface } from '@langchain/core/embeddings';\nimport {\n\tAzureAISearchVectorStore,\n\tAzureAISearchQueryType,\n} from '@langchain/community/vectorstores/azure_aisearch';\nimport { AzureKeyCredential } from '@azure/search-documents';\nimport {\n\ttype IDataObject,\n\ttype ILoadOptionsFunctions,\n\tNodeOperationError,\n\ttype INodeProperties,\n\ttype IExecuteFunctions,\n\ttype ISupplyDataFunctions,\n} from 'n8n-workflow';\nimport { createVectorStoreNode } from '../shared/createVectorStoreNode/createVectorStoreNode';\n\n// User agent for usage tracking\nconst USER_AGENT_PREFIX = 'n8n-azure-ai-search';\n\nexport const AZURE_AI_SEARCH_CREDENTIALS = 'azureAiSearchApi';\nexport const INDEX_NAME = 'indexName';\nexport const QUERY_TYPE = 'queryType';\nexport const FILTER = 'filter';\nexport const SEMANTIC_CONFIGURATION = 'semanticConfiguration';\n\nconst indexNameField: INodeProperties = {\n\tdisplayName: 'Index Name',\n\tname: INDEX_NAME,\n\ttype: 'string',\n\tdefault: 'n8n-vectorstore',\n\tdescription:\n\t\t'The name of the Azure AI Search index. Will be created automatically if it does not exist.',\n\trequired: true,\n};\n\nconst queryTypeField: INodeProperties = {\n\tdisplayName: 'Query Type',\n\tname: QUERY_TYPE,\n\ttype: 'options',\n\tdefault: 'hybrid',\n\tdescription: 'The type of search query to perform',\n\toptions: [\n\t\t{\n\t\t\tname: 'Vector',\n\t\t\tvalue: 'vector',\n\t\t\tdescription: 'Vector similarity search only',\n\t\t},\n\t\t{\n\t\t\tname: 'Hybrid',\n\t\t\tvalue: 'hybrid',\n\t\t\tdescription: 'Combines vector and keyword search (recommended)',\n\t\t},\n\t\t{\n\t\t\tname: 'Semantic Hybrid',\n\t\t\tvalue: 'semanticHybrid',\n\t\t\tdescription: 'Hybrid search with semantic ranking (requires Basic tier or higher)',\n\t\t},\n\t],\n};\n\nconst filterField: INodeProperties = {\n\tdisplayName: 'Filter',\n\tname: FILTER,\n\ttype: 'string',\n\tdefault: '',\n\tdescription:\n\t\t'Filter results using OData syntax. Use metadata/fieldName for metadata fields. <a href=\"https://learn.microsoft.com/en-us/azure/search/search-query-odata-filter\" target=\"_blank\">Learn more</a>.',\n\tplaceholder: \"metadata/category eq 'technology' and metadata/author eq 'John'\",\n};\n\nconst semanticConfigurationField: INodeProperties = {\n\tdisplayName: 'Semantic Configuration',\n\tname: SEMANTIC_CONFIGURATION,\n\ttype: 'string',\n\tdefault: '',\n\tdescription: 'Name of the semantic configuration for semantic ranking (optional)',\n\tdisplayOptions: {\n\t\tshow: {\n\t\t\t[QUERY_TYPE]: ['semanticHybrid'],\n\t\t},\n\t},\n};\n\nconst sharedFields: INodeProperties[] = [indexNameField];\n\nconst retrieveFields: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\ttype: 'collection',\n\t\tplaceholder: 'Add Option',\n\t\tdefault: {},\n\t\toptions: [queryTypeField, filterField, semanticConfigurationField],\n\t},\n];\n\nconst insertFields: INodeProperties[] = [];\n\ntype IFunctionsContext = IExecuteFunctions | ISupplyDataFunctions | ILoadOptionsFunctions;\n\nfunction isExecutionContext(\n\tcontext: IFunctionsContext,\n): context is IExecuteFunctions | ISupplyDataFunctions {\n\t// IExecuteFunctions and ISupplyDataFunctions have addInputData method\n\t// ILoadOptionsFunctions does not\n\treturn 'addInputData' in context;\n}\n\nfunction getParameter(key: string, context: IFunctionsContext, itemIndex: number): string {\n\tlet value: unknown;\n\n\tif (isExecutionContext(context)) {\n\t\t// Execution context: includes itemIndex parameter\n\t\tvalue = context.getNodeParameter(key, itemIndex, '', { extractValue: true });\n\t} else {\n\t\t// Load options context: no itemIndex parameter\n\t\tvalue = context.getNodeParameter(key, '', { extractValue: true });\n\t}\n\n\tif (typeof value !== 'string') {\n\t\tthrow new NodeOperationError(context.getNode(), `Parameter ${key} must be a string`);\n\t}\n\treturn value;\n}\n\nexport const getIndexName = getParameter.bind(null, INDEX_NAME);\n\nfunction getOptionValue<T>(\n\tname: string,\n\tcontext: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n\tdefaultValue?: T,\n): T | undefined {\n\tconst options: IDataObject = context.getNodeParameter('options', itemIndex, {});\n\treturn options[name] !== undefined ? (options[name] as T) : defaultValue;\n}\n\nasync function getAzureAISearchClient(\n\tcontext: IFunctionsContext,\n\tembeddings: EmbeddingsInterface,\n\titemIndex: number,\n): Promise<AzureAISearchVectorStore> {\n\tconst credentials = await context.getCredentials(AZURE_AI_SEARCH_CREDENTIALS);\n\n\ttry {\n\t\tconst indexName = getIndexName(context, itemIndex);\n\n\t\tif (!credentials.endpoint || typeof credentials.endpoint !== 'string') {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tcontext.getNode(),\n\t\t\t\t'Azure AI Search endpoint is missing or invalid',\n\t\t\t\t{ itemIndex },\n\t\t\t);\n\t\t}\n\t\tconst endpoint = credentials.endpoint;\n\n\t\t// Validate API Key\n\t\tif (!credentials.apiKey || typeof credentials.apiKey !== 'string') {\n\t\t\tthrow new NodeOperationError(context.getNode(), 'API Key is required for authentication', {\n\t\t\t\titemIndex,\n\t\t\t});\n\t\t}\n\n\t\tconst azureCredentials = new AzureKeyCredential(credentials.apiKey);\n\n\t\t// Pass endpoint, indexName, and credentials to enable automatic index creation\n\t\t// LangChain will create the index automatically if it doesn't exist\n\t\tconst config: any = {\n\t\t\tendpoint,\n\t\t\tindexName,\n\t\t\tcredentials: azureCredentials,\n\t\t\tsearch: {},\n\t\t\t// Add custom user agent for usage tracking\n\t\t\tclientOptions: {\n\t\t\t\tuserAgentOptions: { userAgentPrefix: USER_AGENT_PREFIX },\n\t\t\t},\n\t\t};\n\n\t\t// Set search configuration options only for execution contexts\n\t\tif (isExecutionContext(context)) {\n\t\t\tconst queryType = getQueryType(context, itemIndex);\n\t\t\tconst semanticConfiguration = getOptionValue<string>(\n\t\t\t\t'semanticConfiguration',\n\t\t\t\tcontext,\n\t\t\t\titemIndex,\n\t\t\t);\n\t\t\tconst filter = getOptionValue<string>('filter', context, itemIndex);\n\n\t\t\tconfig.search.type = queryType;\n\n\t\t\tif (filter) {\n\t\t\t\tconfig.search.filter = filter;\n\t\t\t}\n\n\t\t\tif (queryType === AzureAISearchQueryType.SemanticHybrid && semanticConfiguration) {\n\t\t\t\tconfig.search.semanticConfigurationName = semanticConfiguration;\n\t\t\t}\n\t\t}\n\n\t\treturn new AzureAISearchVectorStore(embeddings, config);\n\t} catch (error) {\n\t\tif (error instanceof NodeOperationError) {\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Log the full error for debugging\n\t\tcontext.logger.debug('Azure AI Search connection error:', {\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\tcode: (error as any).code,\n\t\t\tstatusCode: (error as any).statusCode,\n\t\t\tdetails: (error as any).details,\n\t\t});\n\n\t\t// Check for authentication errors\n\t\tif (\n\t\t\terror.message?.includes('401') ||\n\t\t\terror.message?.includes('Unauthorized') ||\n\t\t\terror.message?.includes('authentication failed')\n\t\t) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tcontext.getNode(),\n\t\t\t\t'Authentication failed - invalid API key or endpoint.',\n\t\t\t\t{\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Please verify your API Key and Search Endpoint are correct in the credentials configuration.',\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\t// Check for authorization errors (403)\n\t\tif (error.message?.includes('403') || error.message?.includes('Forbidden')) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tcontext.getNode(),\n\t\t\t\t'Authorization failed - insufficient permissions.',\n\t\t\t\t{\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'The API Key does not have sufficient permissions. Ensure the key has the required access level for this operation.',\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new NodeOperationError(context.getNode(), `Error: ${errorMessage}`, {\n\t\t\titemIndex,\n\t\t\tdescription: 'Please check your Azure AI Search connection details',\n\t\t});\n\t}\n}\n\nfunction getQueryType(\n\tcontext: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n): AzureAISearchQueryType {\n\tconst queryType = getOptionValue<string>('queryType', context, itemIndex, 'hybrid');\n\n\tswitch (queryType) {\n\t\tcase 'vector':\n\t\t\treturn AzureAISearchQueryType.Similarity;\n\t\tcase 'hybrid':\n\t\t\treturn AzureAISearchQueryType.SimilarityHybrid;\n\t\tcase 'semanticHybrid':\n\t\t\treturn AzureAISearchQueryType.SemanticHybrid;\n\t\tdefault:\n\t\t\treturn AzureAISearchQueryType.SimilarityHybrid;\n\t}\n}\n\nexport class VectorStoreAzureAISearch extends createVectorStoreNode({\n\tmeta: {\n\t\tdisplayName: 'Azure AI Search Vector Store',\n\t\tname: 'vectorStoreAzureAISearch',\n\t\tdescription: 'Work with your data in Azure AI Search Vector Store',\n\t\ticon: { light: 'file:azure-aisearch.svg', dark: 'file:azure-aisearch.svg' },\n\t\tdocsUrl:\n\t\t\t'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreazureaisearch/',\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'azureAiSearchApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toperationModes: ['load', 'insert', 'retrieve', 'update', 'retrieve-as-tool'],\n\t},\n\tsharedFields,\n\tretrieveFields,\n\tloadFields: retrieveFields,\n\tinsertFields,\n\tasync getVectorStoreClient(context, _filter, embeddings, itemIndex) {\n\t\tconst vectorStore = await getAzureAISearchClient(context, embeddings, itemIndex);\n\n\t\t// Apply OData filter to search methods if specified in options\n\t\tif (isExecutionContext(context)) {\n\t\t\tconst filter = getOptionValue<string>('filter', context, itemIndex);\n\n\t\t\tif (filter) {\n\t\t\t\t// Per LangChain docs, pass filter as 3rd parameter with filterExpression\n\t\t\t\tconst filterObject = { filterExpression: filter };\n\n\t\t\t\t// Override similaritySearchVectorWithScore - this is the method called by n8n base node\n\t\t\t\tconst originalSearchVectorWithScore =\n\t\t\t\t\tvectorStore.similaritySearchVectorWithScore.bind(vectorStore);\n\t\t\t\tvectorStore.similaritySearchVectorWithScore = async (\n\t\t\t\t\tquery: number[],\n\t\t\t\t\tk: number,\n\t\t\t\t\tadditionalFilter?: any,\n\t\t\t\t) => {\n\t\t\t\t\t// Merge our OData filter with any additional filter passed by the caller\n\t\t\t\t\tconst mergedFilter = additionalFilter\n\t\t\t\t\t\t? { ...filterObject, ...additionalFilter }\n\t\t\t\t\t\t: filterObject;\n\t\t\t\t\treturn await originalSearchVectorWithScore(query, k, mergedFilter);\n\t\t\t\t};\n\n\t\t\t\t// Override similaritySearch to pass filter as 3rd parameter\n\t\t\t\tconst originalSearch = vectorStore.similaritySearch.bind(vectorStore);\n\t\t\t\tvectorStore.similaritySearch = async (query: string, k?: number) => {\n\t\t\t\t\treturn await originalSearch(query, k, filterObject);\n\t\t\t\t};\n\n\t\t\t\t// Override similaritySearchWithScore to pass filter as 3rd parameter\n\t\t\t\tconst originalSearchWithScore = vectorStore.similaritySearchWithScore.bind(vectorStore);\n\t\t\t\tvectorStore.similaritySearchWithScore = async (query: string, k?: number) => {\n\t\t\t\t\treturn await originalSearchWithScore(query, k, filterObject);\n\t\t\t\t};\n\n\t\t\t\t// Override asRetriever to inject filter into retriever options\n\t\t\t\tconst originalAsRetriever = vectorStore.asRetriever.bind(vectorStore);\n\t\t\t\tvectorStore.asRetriever = (kwargs?: any) => {\n\t\t\t\t\treturn originalAsRetriever({\n\t\t\t\t\t\t...kwargs,\n\t\t\t\t\t\tfilter: filterObject,\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn vectorStore;\n\t},\n\tasync populateVectorStore(context, embeddings, documents, itemIndex) {\n\t\ttry {\n\t\t\tconst vectorStore = await getAzureAISearchClient(context, embeddings, itemIndex);\n\n\t\t\t// Add documents to Azure AI Search (framework handles batching)\n\t\t\tawait vectorStore.addDocuments(documents);\n\t\t} catch (error) {\n\t\t\t// Log the full error for debugging\n\t\t\tcontext.logger.debug('Azure AI Search error details:', {\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcode: (error as any).code,\n\t\t\t\tstatusCode: (error as any).statusCode,\n\t\t\t\tdetails: (error as any).details,\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t});\n\n\t\t\t// Check for authentication errors\n\t\t\tif (\n\t\t\t\terror.message?.includes('401') ||\n\t\t\t\terror.message?.includes('Unauthorized') ||\n\t\t\t\terror.message?.includes('authentication failed')\n\t\t\t) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t'Authentication failed during document upload - invalid API key or endpoint.',\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Please verify your API Key and Search Endpoint are correct in the credentials configuration.',\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Check for authorization errors\n\t\t\tif (\n\t\t\t\terror.message?.includes('403') ||\n\t\t\t\terror.message?.includes('Forbidden') ||\n\t\t\t\t(error as any).statusCode === 403\n\t\t\t) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t'Authorization failed - insufficient permissions for document upload.',\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The API Key does not have sufficient permissions for write operations. Ensure the key has the required access level.',\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Check for RestError (common Azure SDK error)\n\t\t\tif ((error as any).name === 'RestError' || error.message?.includes('RestError')) {\n\t\t\t\tconst statusCode = (error as any).statusCode || 'unknown';\n\t\t\t\tconst errorCode = (error as any).code || 'unknown';\n\t\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t`Azure AI Search API error (${statusCode}): ${errorMessage}`,\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription: `Error code: ${errorCode}\\n\\nCommon causes:\\n- Invalid endpoint URL\\n- Index doesn't exist\\n- Authentication/authorization issues\\n- API version mismatch\\n\\nCheck the console logs for detailed error information.`,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new NodeOperationError(context.getNode(), `Error: ${errorMessage}`, {\n\t\t\t\titemIndex,\n\t\t\t\tdescription: 'Please check your Azure AI Search connection details and index configuration',\n\t\t\t});\n\t\t}\n\t},\n}) {}\n"],"mappings":"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","names":["errorMessage"]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/vector_store/VectorStoreAzureAISearch/VectorStoreAzureAISearch.node.ts"],"sourcesContent":["import { AzureKeyCredential, SearchIndexClient } from '@azure/search-documents';\nimport {\n\tAzureAISearchVectorStore,\n\tAzureAISearchQueryType,\n} from '@langchain/community/vectorstores/azure_aisearch';\nimport type { EmbeddingsInterface } from '@langchain/core/embeddings';\nimport {\n\tNodeOperationError,\n\ttype IDataObject,\n\ttype ILoadOptionsFunctions,\n\ttype INodeProperties,\n\ttype IExecuteFunctions,\n\ttype ISupplyDataFunctions,\n} from 'n8n-workflow';\n\nimport { createVectorStoreNode } from '../shared/createVectorStoreNode/createVectorStoreNode';\n\n// User agent for usage tracking\nconst USER_AGENT_PREFIX = 'n8n-azure-ai-search';\n\nexport const AZURE_AI_SEARCH_CREDENTIALS = 'azureAiSearchApi';\nexport const INDEX_NAME = 'indexName';\nexport const QUERY_TYPE = 'queryType';\nexport const FILTER = 'filter';\nexport const SEMANTIC_CONFIGURATION = 'semanticConfiguration';\n\nconst indexNameField: INodeProperties = {\n\tdisplayName: 'Index Name',\n\tname: INDEX_NAME,\n\ttype: 'string',\n\tdefault: 'n8n-vectorstore',\n\tdescription:\n\t\t'The name of the Azure AI Search index. Will be created automatically if it does not exist.',\n\trequired: true,\n};\n\nconst queryTypeField: INodeProperties = {\n\tdisplayName: 'Query Type',\n\tname: QUERY_TYPE,\n\ttype: 'options',\n\tdefault: 'hybrid',\n\tdescription: 'The type of search query to perform',\n\toptions: [\n\t\t{\n\t\t\tname: 'Vector',\n\t\t\tvalue: 'vector',\n\t\t\tdescription: 'Vector similarity search only',\n\t\t},\n\t\t{\n\t\t\tname: 'Hybrid',\n\t\t\tvalue: 'hybrid',\n\t\t\tdescription: 'Combines vector and keyword search (recommended)',\n\t\t},\n\t\t{\n\t\t\tname: 'Semantic Hybrid',\n\t\t\tvalue: 'semanticHybrid',\n\t\t\tdescription: 'Hybrid search with semantic ranking (requires Basic tier or higher)',\n\t\t},\n\t],\n};\n\nconst filterField: INodeProperties = {\n\tdisplayName: 'Filter',\n\tname: FILTER,\n\ttype: 'string',\n\tdefault: '',\n\tdescription:\n\t\t'Filter results using OData syntax. Use metadata/fieldName for metadata fields. <a href=\"https://learn.microsoft.com/en-us/azure/search/search-query-odata-filter\" target=\"_blank\">Learn more</a>.',\n\tplaceholder: \"metadata/category eq 'technology' and metadata/author eq 'John'\",\n};\n\nconst semanticConfigurationField: INodeProperties = {\n\tdisplayName: 'Semantic Configuration',\n\tname: SEMANTIC_CONFIGURATION,\n\ttype: 'string',\n\tdefault: '',\n\tdescription: 'Name of the semantic configuration for semantic ranking (optional)',\n\tdisplayOptions: {\n\t\tshow: {\n\t\t\t[QUERY_TYPE]: ['semanticHybrid'],\n\t\t},\n\t},\n};\n\nconst sharedFields: INodeProperties[] = [indexNameField];\n\nconst retrieveFields: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\ttype: 'collection',\n\t\tplaceholder: 'Add Option',\n\t\tdefault: {},\n\t\toptions: [queryTypeField, filterField, semanticConfigurationField],\n\t},\n];\n\nconst insertFields: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Options',\n\t\tname: 'options',\n\t\ttype: 'collection',\n\t\tplaceholder: 'Add Option',\n\t\tdefault: {},\n\t\toptions: [\n\t\t\t{\n\t\t\t\tdisplayName: 'Clear Index',\n\t\t\t\tname: 'clearIndex',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tdescription:\n\t\t\t\t\t'Whether to delete and recreate the index before inserting new data. Warning: This will reset any custom index configuration (semantic ranking, analyzers, etc.) to defaults.',\n\t\t\t},\n\t\t],\n\t},\n];\n\ntype IFunctionsContext = IExecuteFunctions | ISupplyDataFunctions | ILoadOptionsFunctions;\n\nfunction isExecutionContext(\n\tcontext: IFunctionsContext,\n): context is IExecuteFunctions | ISupplyDataFunctions {\n\t// IExecuteFunctions and ISupplyDataFunctions have addInputData method\n\t// ILoadOptionsFunctions does not\n\treturn 'addInputData' in context;\n}\n\nfunction getParameter(key: string, context: IFunctionsContext, itemIndex: number): string {\n\tlet value: unknown;\n\n\tif (isExecutionContext(context)) {\n\t\t// Execution context: includes itemIndex parameter\n\t\tvalue = context.getNodeParameter(key, itemIndex, '', { extractValue: true });\n\t} else {\n\t\t// Load options context: no itemIndex parameter\n\t\tvalue = context.getNodeParameter(key, '', { extractValue: true });\n\t}\n\n\tif (typeof value !== 'string') {\n\t\tthrow new NodeOperationError(context.getNode(), `Parameter ${key} must be a string`);\n\t}\n\treturn value;\n}\n\nexport const getIndexName = getParameter.bind(null, INDEX_NAME);\n\nfunction getOptionValue<T>(\n\tname: string,\n\tcontext: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n\tdefaultValue?: T,\n): T | undefined {\n\tconst options: IDataObject = context.getNodeParameter('options', itemIndex, {});\n\treturn options[name] !== undefined ? (options[name] as T) : defaultValue;\n}\n\ninterface ValidatedCredentials {\n\tendpoint: string;\n\tapiKey: string;\n}\n\nasync function getValidatedCredentials(\n\tcontext: IFunctionsContext,\n\titemIndex: number,\n): Promise<ValidatedCredentials> {\n\tconst credentials = await context.getCredentials(AZURE_AI_SEARCH_CREDENTIALS);\n\n\tif (!credentials.endpoint || typeof credentials.endpoint !== 'string') {\n\t\tthrow new NodeOperationError(\n\t\t\tcontext.getNode(),\n\t\t\t'Azure AI Search endpoint is missing or invalid',\n\t\t\t{ itemIndex },\n\t\t);\n\t}\n\n\tif (!credentials.apiKey || typeof credentials.apiKey !== 'string') {\n\t\tthrow new NodeOperationError(context.getNode(), 'API Key is required for authentication', {\n\t\t\titemIndex,\n\t\t});\n\t}\n\n\treturn {\n\t\tendpoint: credentials.endpoint,\n\t\tapiKey: credentials.apiKey,\n\t};\n}\n\n/**\n * Deletes an Azure AI Search index if clearIndex option is enabled.\n * Exported for testing purposes.\n */\nexport async function clearAzureSearchIndex(\n\tcontext: IFunctionsContext,\n\titemIndex: number,\n): Promise<boolean> {\n\tconst options = context.getNodeParameter('options', itemIndex, {}) as {\n\t\tclearIndex?: boolean;\n\t};\n\n\tif (!options.clearIndex) {\n\t\treturn false;\n\t}\n\n\tconst credentials = await getValidatedCredentials(context, itemIndex);\n\tconst indexName = getIndexName(context, itemIndex);\n\n\ttry {\n\t\tconst indexClient = new SearchIndexClient(\n\t\t\tcredentials.endpoint,\n\t\t\tnew AzureKeyCredential(credentials.apiKey),\n\t\t);\n\t\tawait indexClient.deleteIndex(indexName);\n\t\tcontext.logger.debug(`Deleted Azure AI Search index: ${indexName}`);\n\t\treturn true;\n\t} catch (deleteError) {\n\t\t// Log the error but don't fail - index might not exist yet\n\t\tcontext.logger.debug('Error deleting index (may not exist):', {\n\t\t\tmessage: deleteError instanceof Error ? deleteError.message : String(deleteError),\n\t\t});\n\t\treturn false;\n\t}\n}\n\nasync function getAzureAISearchClient(\n\tcontext: IFunctionsContext,\n\tembeddings: EmbeddingsInterface,\n\titemIndex: number,\n): Promise<AzureAISearchVectorStore> {\n\tconst credentials = await getValidatedCredentials(context, itemIndex);\n\n\ttry {\n\t\tconst indexName = getIndexName(context, itemIndex);\n\t\tconst azureCredentials = new AzureKeyCredential(credentials.apiKey);\n\n\t\t// Pass endpoint, indexName, and credentials to enable automatic index creation\n\t\t// LangChain will create the index automatically if it doesn't exist\n\t\tconst config: any = {\n\t\t\tendpoint: credentials.endpoint,\n\t\t\tindexName,\n\t\t\tcredentials: azureCredentials,\n\t\t\tsearch: {},\n\t\t\t// Add custom user agent for usage tracking\n\t\t\tclientOptions: {\n\t\t\t\tuserAgentOptions: { userAgentPrefix: USER_AGENT_PREFIX },\n\t\t\t},\n\t\t};\n\n\t\t// Set search configuration options only for execution contexts\n\t\tif (isExecutionContext(context)) {\n\t\t\tconst queryType = getQueryType(context, itemIndex);\n\t\t\tconst semanticConfiguration = getOptionValue<string>(\n\t\t\t\t'semanticConfiguration',\n\t\t\t\tcontext,\n\t\t\t\titemIndex,\n\t\t\t);\n\t\t\tconst filter = getOptionValue<string>('filter', context, itemIndex);\n\n\t\t\tconfig.search.type = queryType;\n\n\t\t\tif (filter) {\n\t\t\t\tconfig.search.filter = filter;\n\t\t\t}\n\n\t\t\tif (queryType === AzureAISearchQueryType.SemanticHybrid && semanticConfiguration) {\n\t\t\t\tconfig.search.semanticConfigurationName = semanticConfiguration;\n\t\t\t}\n\t\t}\n\n\t\treturn new AzureAISearchVectorStore(embeddings, config);\n\t} catch (error) {\n\t\tif (error instanceof NodeOperationError) {\n\t\t\tthrow error;\n\t\t}\n\n\t\t// Log the full error for debugging\n\t\tcontext.logger.debug('Azure AI Search connection error:', {\n\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\tcode: (error as any).code,\n\t\t\tstatusCode: (error as any).statusCode,\n\t\t\tdetails: (error as any).details,\n\t\t});\n\n\t\t// Check for authentication errors\n\t\tif (\n\t\t\terror.message?.includes('401') ||\n\t\t\terror.message?.includes('Unauthorized') ||\n\t\t\terror.message?.includes('authentication failed')\n\t\t) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tcontext.getNode(),\n\t\t\t\t'Authentication failed - invalid API key or endpoint.',\n\t\t\t\t{\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'Please verify your API Key and Search Endpoint are correct in the credentials configuration.',\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\t// Check for authorization errors (403)\n\t\tif (error.message?.includes('403') || error.message?.includes('Forbidden')) {\n\t\t\tthrow new NodeOperationError(\n\t\t\t\tcontext.getNode(),\n\t\t\t\t'Authorization failed - insufficient permissions.',\n\t\t\t\t{\n\t\t\t\t\titemIndex,\n\t\t\t\t\tdescription:\n\t\t\t\t\t\t'The API Key does not have sufficient permissions. Ensure the key has the required access level for this operation.',\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\n\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\tthrow new NodeOperationError(context.getNode(), `Error: ${errorMessage}`, {\n\t\t\titemIndex,\n\t\t\tdescription: 'Please check your Azure AI Search connection details',\n\t\t});\n\t}\n}\n\nfunction getQueryType(\n\tcontext: IExecuteFunctions | ISupplyDataFunctions,\n\titemIndex: number,\n): AzureAISearchQueryType {\n\tconst queryType = getOptionValue<string>('queryType', context, itemIndex, 'hybrid');\n\n\tswitch (queryType) {\n\t\tcase 'vector':\n\t\t\treturn AzureAISearchQueryType.Similarity;\n\t\tcase 'hybrid':\n\t\t\treturn AzureAISearchQueryType.SimilarityHybrid;\n\t\tcase 'semanticHybrid':\n\t\t\treturn AzureAISearchQueryType.SemanticHybrid;\n\t\tdefault:\n\t\t\treturn AzureAISearchQueryType.SimilarityHybrid;\n\t}\n}\n\nexport class VectorStoreAzureAISearch extends createVectorStoreNode({\n\tmeta: {\n\t\tdisplayName: 'Azure AI Search Vector Store',\n\t\tname: 'vectorStoreAzureAISearch',\n\t\tdescription: 'Work with your data in Azure AI Search Vector Store',\n\t\ticon: { light: 'file:azure-aisearch.svg', dark: 'file:azure-aisearch.svg' },\n\t\tdocsUrl:\n\t\t\t'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreazureaisearch/',\n\t\tcredentials: [\n\t\t\t{\n\t\t\t\tname: 'azureAiSearchApi',\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toperationModes: ['load', 'insert', 'retrieve', 'update', 'retrieve-as-tool'],\n\t},\n\tsharedFields,\n\tretrieveFields,\n\tloadFields: retrieveFields,\n\tinsertFields,\n\tasync getVectorStoreClient(context, _filter, embeddings, itemIndex) {\n\t\tconst vectorStore = await getAzureAISearchClient(context, embeddings, itemIndex);\n\n\t\t// Apply OData filter to search methods if specified in options\n\t\tif (isExecutionContext(context)) {\n\t\t\tconst filter = getOptionValue<string>('filter', context, itemIndex);\n\n\t\t\tif (filter) {\n\t\t\t\t// Per LangChain docs, pass filter as 3rd parameter with filterExpression\n\t\t\t\tconst filterObject = { filterExpression: filter };\n\n\t\t\t\t// Override similaritySearchVectorWithScore - this is the method called by n8n base node\n\t\t\t\tconst originalSearchVectorWithScore =\n\t\t\t\t\tvectorStore.similaritySearchVectorWithScore.bind(vectorStore);\n\t\t\t\tvectorStore.similaritySearchVectorWithScore = async (\n\t\t\t\t\tquery: number[],\n\t\t\t\t\tk: number,\n\t\t\t\t\tadditionalFilter?: any,\n\t\t\t\t) => {\n\t\t\t\t\t// Merge our OData filter with any additional filter passed by the caller\n\t\t\t\t\tconst mergedFilter = additionalFilter\n\t\t\t\t\t\t? { ...filterObject, ...additionalFilter }\n\t\t\t\t\t\t: filterObject;\n\t\t\t\t\treturn await originalSearchVectorWithScore(query, k, mergedFilter);\n\t\t\t\t};\n\n\t\t\t\t// Override similaritySearch to pass filter as 3rd parameter\n\t\t\t\tconst originalSearch = vectorStore.similaritySearch.bind(vectorStore);\n\t\t\t\tvectorStore.similaritySearch = async (query: string, k?: number) => {\n\t\t\t\t\treturn await originalSearch(query, k, filterObject);\n\t\t\t\t};\n\n\t\t\t\t// Override similaritySearchWithScore to pass filter as 3rd parameter\n\t\t\t\tconst originalSearchWithScore = vectorStore.similaritySearchWithScore.bind(vectorStore);\n\t\t\t\tvectorStore.similaritySearchWithScore = async (query: string, k?: number) => {\n\t\t\t\t\treturn await originalSearchWithScore(query, k, filterObject);\n\t\t\t\t};\n\n\t\t\t\t// Override asRetriever to inject filter into retriever options\n\t\t\t\tconst originalAsRetriever = vectorStore.asRetriever.bind(vectorStore);\n\t\t\t\tvectorStore.asRetriever = (kwargs?: any) => {\n\t\t\t\t\treturn originalAsRetriever({\n\t\t\t\t\t\t...kwargs,\n\t\t\t\t\t\tfilter: filterObject,\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\treturn vectorStore;\n\t},\n\tasync populateVectorStore(context, embeddings, documents, itemIndex) {\n\t\ttry {\n\t\t\t// Clear the index if requested (delete and recreate)\n\t\t\tawait clearAzureSearchIndex(context, itemIndex);\n\n\t\t\t// Get vector store client (will auto-create index if it doesn't exist)\n\t\t\tconst vectorStore = await getAzureAISearchClient(context, embeddings, itemIndex);\n\n\t\t\t// Add documents to Azure AI Search (framework handles batching)\n\t\t\tawait vectorStore.addDocuments(documents);\n\t\t} catch (error) {\n\t\t\t// Log the full error for debugging\n\t\t\tcontext.logger.debug('Azure AI Search error details:', {\n\t\t\t\tmessage: error instanceof Error ? error.message : String(error),\n\t\t\t\tcode: (error as any).code,\n\t\t\t\tstatusCode: (error as any).statusCode,\n\t\t\t\tdetails: (error as any).details,\n\t\t\t\tstack: error instanceof Error ? error.stack : undefined,\n\t\t\t});\n\n\t\t\t// Check for authentication errors\n\t\t\tif (\n\t\t\t\terror.message?.includes('401') ||\n\t\t\t\terror.message?.includes('Unauthorized') ||\n\t\t\t\terror.message?.includes('authentication failed')\n\t\t\t) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t'Authentication failed during document upload - invalid API key or endpoint.',\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'Please verify your API Key and Search Endpoint are correct in the credentials configuration.',\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Check for authorization errors\n\t\t\tif (\n\t\t\t\terror.message?.includes('403') ||\n\t\t\t\terror.message?.includes('Forbidden') ||\n\t\t\t\t(error as any).statusCode === 403\n\t\t\t) {\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t'Authorization failed - insufficient permissions for document upload.',\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription:\n\t\t\t\t\t\t\t'The API Key does not have sufficient permissions for write operations. Ensure the key has the required access level.',\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Check for RestError (common Azure SDK error)\n\t\t\tif ((error as any).name === 'RestError' || error.message?.includes('RestError')) {\n\t\t\t\tconst statusCode = (error as any).statusCode || 'unknown';\n\t\t\t\tconst errorCode = (error as any).code || 'unknown';\n\t\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\t\tthrow new NodeOperationError(\n\t\t\t\t\tcontext.getNode(),\n\t\t\t\t\t`Azure AI Search API error (${statusCode}): ${errorMessage}`,\n\t\t\t\t\t{\n\t\t\t\t\t\titemIndex,\n\t\t\t\t\t\tdescription: `Error code: ${errorCode}\\n\\nCommon causes:\\n- Invalid endpoint URL\\n- Index doesn't exist\\n- Authentication/authorization issues\\n- API version mismatch\\n\\nCheck the console logs for detailed error information.`,\n\t\t\t\t\t},\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst errorMessage = error instanceof Error ? error.message : String(error);\n\t\t\tthrow new NodeOperationError(context.getNode(), `Error: ${errorMessage}`, {\n\t\t\t\titemIndex,\n\t\t\t\tdescription: 'Please check your Azure AI Search connection details and index configuration',\n\t\t\t});\n\t\t}\n\t},\n}) {}\n"],"mappings":"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","names":["errorMessage"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.ts"],"sourcesContent":["import type { Embeddings } from '@langchain/core/embeddings';\nimport type { MemoryVectorStore } from 'langchain/vectorstores/memory';\nimport {\n\ttype INodeProperties,\n\ttype ILoadOptionsFunctions,\n\ttype INodeListSearchResult,\n\ttype IDataObject,\n\ttype NodeParameterValueType,\n\ttype IExecuteFunctions,\n\ttype ISupplyDataFunctions,\n\tApplicationError,\n} from 'n8n-workflow';\n\nimport { createVectorStoreNode } from '../shared/createVectorStoreNode/createVectorStoreNode';\nimport { MemoryVectorStoreManager } from '../shared/MemoryManager/MemoryVectorStoreManager';\n\nconst warningBanner: INodeProperties = {\n\tdisplayName:\n\t\t'<strong>For experimental use only</strong>: Data is stored in memory and will be lost if n8n restarts. Data may also be cleared if available memory gets low, and is accessible to all users of this instance. <a href=\"https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreinmemory/\">More info</a>',\n\tname: 'notice',\n\ttype: 'notice',\n\tdefault: '',\n};\n\nconst insertFields: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Clear Store',\n\t\tname: 'clearStore',\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t\tdescription: 'Whether to clear the store before inserting new data',\n\t},\n\twarningBanner,\n];\n\nconst DEFAULT_MEMORY_KEY = 'vector_store_key';\n\nfunction getMemoryKey(context: IExecuteFunctions | ISupplyDataFunctions, itemIndex: number) {\n\tconst node = context.getNode();\n\tif (node.typeVersion <= 1.1) {\n\t\tconst memoryKeyParam = context.getNodeParameter('memoryKey', itemIndex) as string;\n\t\tconst workflowId = context.getWorkflow().id;\n\n\t\treturn `${workflowId}__${memoryKeyParam}`;\n\t} else {\n\t\tconst memoryKeyParam = context.getNodeParameter('memoryKey', itemIndex) as {\n\t\t\tmode: string;\n\t\t\tvalue: string;\n\t\t};\n\n\t\treturn memoryKeyParam.value;\n\t}\n}\n\nexport class VectorStoreInMemory extends createVectorStoreNode<MemoryVectorStore>({\n\tmeta: {\n\t\tdisplayName: 'Simple Vector Store',\n\t\tname: 'vectorStoreInMemory',\n\t\tdescription: 'The easiest way to experiment with vector stores, without external setup.',\n\t\ticon: 'fa:database',\n\t\ticonColor: 'black',\n\t\tdocsUrl:\n\t\t\t'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreinmemory/',\n\t\tcategories: ['AI'],\n\t\tsubcategories: {\n\t\t\tAI: ['Vector Stores', 'Tools', 'Root Nodes'],\n\t\t\t'Vector Stores': ['For Beginners'],\n\t\t\tTools: ['Other Tools'],\n\t\t},\n\t},\n\tsharedFields: [\n\t\t{\n\t\t\tdisplayName: 'Memory Key',\n\t\t\tname: 'memoryKey',\n\t\t\ttype: 'string',\n\t\t\tdefault: DEFAULT_MEMORY_KEY,\n\t\t\tdescription:\n\t\t\t\t'The key to use to store the vector memory in the workflow data. The key will be prefixed with the workflow ID to avoid collisions.',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\t'@version': [{ _cnd: { lte: 1.1 } }],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Memory Key',\n\t\t\tname: 'memoryKey',\n\t\t\ttype: 'resourceLocator',\n\t\t\trequired: true,\n\t\t\tdefault: { mode: 'list', value: DEFAULT_MEMORY_KEY },\n\t\t\tdescription:\n\t\t\t\t'The key to use to store the vector memory in the workflow data. These keys are shared between workflows.',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\n\t\t\t\t},\n\t\t\t},\n\t\t\tmodes: [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'From List',\n\t\t\t\t\tname: 'list',\n\t\t\t\t\ttype: 'list',\n\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\tsearchListMethod: 'vectorStoresSearch',\n\t\t\t\t\t\tsearchable: true,\n\t\t\t\t\t\tallowNewResource: {\n\t\t\t\t\t\t\tlabel: 'resourceLocator.mode.list.addNewResource.vectorStoreInMemory',\n\t\t\t\t\t\t\tdefaultName: DEFAULT_MEMORY_KEY,\n\t\t\t\t\t\t\tmethod: 'createVectorStore',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Manual',\n\t\t\t\t\tname: 'id',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tplaceholder: DEFAULT_MEMORY_KEY,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t],\n\tmethods: {\n\t\tlistSearch: {\n\t\t\tasync vectorStoresSearch(\n\t\t\t\tthis: ILoadOptionsFunctions,\n\t\t\t\tfilter?: string,\n\t\t\t): Promise<INodeListSearchResult> {\n\t\t\t\tconst vectorStoreSingleton = MemoryVectorStoreManager.getInstance(\n\t\t\t\t\t{} as Embeddings, // Real Embeddings are provided when executing the node\n\t\t\t\t\tthis.logger,\n\t\t\t\t);\n\n\t\t\t\tconst searchOptions: INodeListSearchResult['results'] = vectorStoreSingleton\n\t\t\t\t\t.getMemoryKeysList()\n\t\t\t\t\t.map((key) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: key,\n\t\t\t\t\t\t\tvalue: key,\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\n\t\t\t\tlet results = searchOptions;\n\t\t\t\tif (filter) {\n\t\t\t\t\tresults = results.filter((option) => option.name.includes(filter));\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tresults,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t\tactionHandler: {\n\t\t\tasync createVectorStore(\n\t\t\t\tthis: ILoadOptionsFunctions,\n\t\t\t\tpayload: string | IDataObject | undefined,\n\t\t\t): Promise<NodeParameterValueType> {\n\t\t\t\tif (!payload || typeof payload === 'string') {\n\t\t\t\t\tthrow new ApplicationError('Invalid payload type');\n\t\t\t\t}\n\n\t\t\t\tconst { name } = payload;\n\n\t\t\t\tconst vectorStoreSingleton = MemoryVectorStoreManager.getInstance(\n\t\t\t\t\t{} as Embeddings, // Real Embeddings are provided when executing the node\n\t\t\t\t\tthis.logger,\n\t\t\t\t);\n\n\t\t\t\tconst memoryKey = name ? (name as string) : DEFAULT_MEMORY_KEY;\n\t\t\t\tawait vectorStoreSingleton.getVectorStore(memoryKey);\n\n\t\t\t\treturn memoryKey;\n\t\t\t},\n\t\t},\n\t},\n\tinsertFields,\n\tloadFields: [warningBanner],\n\tretrieveFields: [warningBanner],\n\tasync getVectorStoreClient(context, _filter, embeddings, itemIndex) {\n\t\tconst memoryKey = getMemoryKey(context, itemIndex);\n\t\tconst vectorStoreSingleton = MemoryVectorStoreManager.getInstance(embeddings, context.logger);\n\n\t\treturn await vectorStoreSingleton.getVectorStore(memoryKey);\n\t},\n\tasync populateVectorStore(context, embeddings, documents, itemIndex) {\n\t\tconst memoryKey = getMemoryKey(context, itemIndex);\n\t\tconst clearStore = context.getNodeParameter('clearStore', itemIndex) as boolean;\n\t\tconst vectorStoreInstance = MemoryVectorStoreManager.getInstance(embeddings, context.logger);\n\n\t\tawait vectorStoreInstance.addDocuments(memoryKey, documents, clearStore);\n\t},\n}) {}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/vector_store/VectorStoreInMemory/VectorStoreInMemory.node.ts"],"sourcesContent":["import type { Embeddings } from '@langchain/core/embeddings';\nimport type { MemoryVectorStore } from '@langchain/classic/vectorstores/memory';\nimport {\n\ttype INodeProperties,\n\ttype ILoadOptionsFunctions,\n\ttype INodeListSearchResult,\n\ttype IDataObject,\n\ttype NodeParameterValueType,\n\ttype IExecuteFunctions,\n\ttype ISupplyDataFunctions,\n\tApplicationError,\n} from 'n8n-workflow';\n\nimport { createVectorStoreNode } from '../shared/createVectorStoreNode/createVectorStoreNode';\nimport { MemoryVectorStoreManager } from '../shared/MemoryManager/MemoryVectorStoreManager';\n\nconst warningBanner: INodeProperties = {\n\tdisplayName:\n\t\t'<strong>For experimental use only</strong>: Data is stored in memory and will be lost if n8n restarts. Data may also be cleared if available memory gets low, and is accessible to all users of this instance. <a href=\"https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreinmemory/\">More info</a>',\n\tname: 'notice',\n\ttype: 'notice',\n\tdefault: '',\n};\n\nconst insertFields: INodeProperties[] = [\n\t{\n\t\tdisplayName: 'Clear Store',\n\t\tname: 'clearStore',\n\t\ttype: 'boolean',\n\t\tdefault: false,\n\t\tdescription: 'Whether to clear the store before inserting new data',\n\t},\n\twarningBanner,\n];\n\nconst DEFAULT_MEMORY_KEY = 'vector_store_key';\n\nfunction getMemoryKey(context: IExecuteFunctions | ISupplyDataFunctions, itemIndex: number) {\n\tconst node = context.getNode();\n\tif (node.typeVersion <= 1.1) {\n\t\tconst memoryKeyParam = context.getNodeParameter('memoryKey', itemIndex) as string;\n\t\tconst workflowId = context.getWorkflow().id;\n\n\t\treturn `${workflowId}__${memoryKeyParam}`;\n\t} else {\n\t\tconst memoryKeyParam = context.getNodeParameter('memoryKey', itemIndex) as {\n\t\t\tmode: string;\n\t\t\tvalue: string;\n\t\t};\n\n\t\treturn memoryKeyParam.value;\n\t}\n}\n\nexport class VectorStoreInMemory extends createVectorStoreNode<MemoryVectorStore>({\n\tmeta: {\n\t\tdisplayName: 'Simple Vector Store',\n\t\tname: 'vectorStoreInMemory',\n\t\tdescription: 'The easiest way to experiment with vector stores, without external setup.',\n\t\ticon: 'fa:database',\n\t\ticonColor: 'black',\n\t\tdocsUrl:\n\t\t\t'https://docs.n8n.io/integrations/builtin/cluster-nodes/root-nodes/n8n-nodes-langchain.vectorstoreinmemory/',\n\t\tcategories: ['AI'],\n\t\tsubcategories: {\n\t\t\tAI: ['Vector Stores', 'Tools', 'Root Nodes'],\n\t\t\t'Vector Stores': ['For Beginners'],\n\t\t\tTools: ['Other Tools'],\n\t\t},\n\t},\n\tsharedFields: [\n\t\t{\n\t\t\tdisplayName: 'Memory Key',\n\t\t\tname: 'memoryKey',\n\t\t\ttype: 'string',\n\t\t\tdefault: DEFAULT_MEMORY_KEY,\n\t\t\tdescription:\n\t\t\t\t'The key to use to store the vector memory in the workflow data. The key will be prefixed with the workflow ID to avoid collisions.',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\t'@version': [{ _cnd: { lte: 1.1 } }],\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\tdisplayName: 'Memory Key',\n\t\t\tname: 'memoryKey',\n\t\t\ttype: 'resourceLocator',\n\t\t\trequired: true,\n\t\t\tdefault: { mode: 'list', value: DEFAULT_MEMORY_KEY },\n\t\t\tdescription:\n\t\t\t\t'The key to use to store the vector memory in the workflow data. These keys are shared between workflows.',\n\t\t\tdisplayOptions: {\n\t\t\t\tshow: {\n\t\t\t\t\t'@version': [{ _cnd: { gte: 1.2 } }],\n\t\t\t\t},\n\t\t\t},\n\t\t\tmodes: [\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'From List',\n\t\t\t\t\tname: 'list',\n\t\t\t\t\ttype: 'list',\n\t\t\t\t\ttypeOptions: {\n\t\t\t\t\t\tsearchListMethod: 'vectorStoresSearch',\n\t\t\t\t\t\tsearchable: true,\n\t\t\t\t\t\tallowNewResource: {\n\t\t\t\t\t\t\tlabel: 'resourceLocator.mode.list.addNewResource.vectorStoreInMemory',\n\t\t\t\t\t\t\tdefaultName: DEFAULT_MEMORY_KEY,\n\t\t\t\t\t\t\tmethod: 'createVectorStore',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tdisplayName: 'Manual',\n\t\t\t\t\tname: 'id',\n\t\t\t\t\ttype: 'string',\n\t\t\t\t\tplaceholder: DEFAULT_MEMORY_KEY,\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t],\n\tmethods: {\n\t\tlistSearch: {\n\t\t\tasync vectorStoresSearch(\n\t\t\t\tthis: ILoadOptionsFunctions,\n\t\t\t\tfilter?: string,\n\t\t\t): Promise<INodeListSearchResult> {\n\t\t\t\tconst vectorStoreSingleton = MemoryVectorStoreManager.getInstance(\n\t\t\t\t\t{} as Embeddings, // Real Embeddings are provided when executing the node\n\t\t\t\t\tthis.logger,\n\t\t\t\t);\n\n\t\t\t\tconst searchOptions: INodeListSearchResult['results'] = vectorStoreSingleton\n\t\t\t\t\t.getMemoryKeysList()\n\t\t\t\t\t.map((key) => {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: key,\n\t\t\t\t\t\t\tvalue: key,\n\t\t\t\t\t\t};\n\t\t\t\t\t});\n\n\t\t\t\tlet results = searchOptions;\n\t\t\t\tif (filter) {\n\t\t\t\t\tresults = results.filter((option) => option.name.includes(filter));\n\t\t\t\t}\n\n\t\t\t\treturn {\n\t\t\t\t\tresults,\n\t\t\t\t};\n\t\t\t},\n\t\t},\n\t\tactionHandler: {\n\t\t\tasync createVectorStore(\n\t\t\t\tthis: ILoadOptionsFunctions,\n\t\t\t\tpayload: string | IDataObject | undefined,\n\t\t\t): Promise<NodeParameterValueType> {\n\t\t\t\tif (!payload || typeof payload === 'string') {\n\t\t\t\t\tthrow new ApplicationError('Invalid payload type');\n\t\t\t\t}\n\n\t\t\t\tconst { name } = payload;\n\n\t\t\t\tconst vectorStoreSingleton = MemoryVectorStoreManager.getInstance(\n\t\t\t\t\t{} as Embeddings, // Real Embeddings are provided when executing the node\n\t\t\t\t\tthis.logger,\n\t\t\t\t);\n\n\t\t\t\tconst memoryKey = name ? (name as string) : DEFAULT_MEMORY_KEY;\n\t\t\t\tawait vectorStoreSingleton.getVectorStore(memoryKey);\n\n\t\t\t\treturn memoryKey;\n\t\t\t},\n\t\t},\n\t},\n\tinsertFields,\n\tloadFields: [warningBanner],\n\tretrieveFields: [warningBanner],\n\tasync getVectorStoreClient(context, _filter, embeddings, itemIndex) {\n\t\tconst memoryKey = getMemoryKey(context, itemIndex);\n\t\tconst vectorStoreSingleton = MemoryVectorStoreManager.getInstance(embeddings, context.logger);\n\n\t\treturn await vectorStoreSingleton.getVectorStore(memoryKey);\n\t},\n\tasync populateVectorStore(context, embeddings, documents, itemIndex) {\n\t\tconst memoryKey = getMemoryKey(context, itemIndex);\n\t\tconst clearStore = context.getNodeParameter('clearStore', itemIndex) as boolean;\n\t\tconst vectorStoreInstance = MemoryVectorStoreManager.getInstance(embeddings, context.logger);\n\n\t\tawait vectorStoreInstance.addDocuments(memoryKey, documents, clearStore);\n\t},\n}) {}\n"],"mappings":"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","names":[]}
|
package/dist/nodes/vector_store/VectorStoreInMemoryInsert/VectorStoreInMemoryInsert.node.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../nodes/vector_store/VectorStoreInMemoryInsert/VectorStoreInMemoryInsert.node.ts"],"sourcesContent":["import type { Embeddings } from '@langchain/core/embeddings';\nimport type { Document } from 'langchain/document';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeExecutionData,\n\ttype IExecuteFunctions,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport type { N8nJsonLoader } from '@utils/N8nJsonLoader';\n\nimport { MemoryVectorStoreManager } from '../shared/MemoryManager/MemoryVectorStoreManager';\nimport { processDocuments } from '../shared/processDocuments';\n\n// This node is deprecated. Use VectorStoreInMemory instead.\nexport class VectorStoreInMemoryInsert implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'In Memory Vector Store Insert',\n\t\tname: 'vectorStoreInMemoryInsert',\n\t\ticon: 'fa:database',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\thidden: true,\n\t\tdescription: 'Insert data into an in-memory vector store',\n\t\tdefaults: {\n\t\t\tname: 'In Memory Vector Store Insert',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Vector Stores'],\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.vectorstoreinmemory/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\n\t\tinputs: [\n\t\t\tNodeConnectionTypes.Main,\n\t\t\t{\n\t\t\t\tdisplayName: 'Document',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiDocument,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Embedding',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiEmbedding,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'The embbded data are stored in the server memory, so they will be lost when the server is restarted. Additionally, if the amount of data is too large, it may cause the server to crash due to insufficient memory.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Clear Store',\n\t\t\t\tname: 'clearStore',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tdescription: 'Whether to clear the store before inserting new data',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Memory Key',\n\t\t\t\tname: 'memoryKey',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'vector_store_key',\n\t\t\t\tdescription:\n\t\t\t\t\t'The key to use to store the vector memory in the workflow data. The key will be prefixed with the workflow ID to avoid collisions.',\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData(0);\n\t\tconst embeddings = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiEmbedding,\n\t\t\t0,\n\t\t)) as Embeddings;\n\n\t\tconst memoryKey = this.getNodeParameter('memoryKey', 0) as string;\n\t\tconst clearStore = this.getNodeParameter('clearStore', 0) as boolean;\n\t\tconst documentInput = (await this.getInputConnectionData(NodeConnectionTypes.AiDocument, 0)) as\n\t\t\t| N8nJsonLoader\n\t\t\t| Array<Document<Record<string, unknown>>>;\n\n\t\tconst { processedDocuments, serializedDocuments } = await processDocuments(\n\t\t\tdocumentInput,\n\t\t\titems,\n\t\t);\n\n\t\tconst workflowId = this.getWorkflow().id;\n\n\t\tconst vectorStoreInstance = MemoryVectorStoreManager.getInstance(embeddings, this.logger);\n\t\tawait vectorStoreInstance.addDocuments(\n\t\t\t`${workflowId}__${memoryKey}`,\n\t\t\tprocessedDocuments,\n\t\t\tclearStore,\n\t\t);\n\n\t\treturn [serializedDocuments];\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,0BAMO;AAIP,sCAAyC;AACzC,8BAAiC;AAG1B,MAAM,0BAA+C;AAAA,EAArD;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACN,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,eAAe;AAAA,QACrB;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MAEA,QAAQ;AAAA,QACP,wCAAoB;AAAA,QACpB;AAAA,UACC,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,MAAM,wCAAoB;AAAA,UAC1B,UAAU;AAAA,QACX;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,MAAM,wCAAoB;AAAA,UAC1B,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,SAAS,CAAC,wCAAoB,IAAI;AAAA,MAClC,YAAY;AAAA,QACX;AAAA,UACC,aACC;AAAA,UACD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aAAa;AAAA,QACd;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aACC;AAAA,QACF;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,UAAkE;AACvE,UAAM,QAAQ,KAAK,aAAa,CAAC;AACjC,UAAM,aAAc,MAAM,KAAK;AAAA,MAC9B,wCAAoB;AAAA,MACpB;AAAA,IACD;AAEA,UAAM,YAAY,KAAK,iBAAiB,aAAa,CAAC;AACtD,UAAM,aAAa,KAAK,iBAAiB,cAAc,CAAC;AACxD,UAAM,gBAAiB,MAAM,KAAK,uBAAuB,wCAAoB,YAAY,CAAC;AAI1F,UAAM,EAAE,oBAAoB,oBAAoB,IAAI,UAAM;AAAA,MACzD;AAAA,MACA;AAAA,IACD;AAEA,UAAM,aAAa,KAAK,YAAY,EAAE;AAEtC,UAAM,sBAAsB,yDAAyB,YAAY,YAAY,KAAK,MAAM;AACxF,UAAM,oBAAoB;AAAA,MACzB,GAAG,UAAU,KAAK,SAAS;AAAA,MAC3B;AAAA,MACA;AAAA,IACD;AAEA,WAAO,CAAC,mBAAmB;AAAA,EAC5B;AACD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../nodes/vector_store/VectorStoreInMemoryInsert/VectorStoreInMemoryInsert.node.ts"],"sourcesContent":["import type { Embeddings } from '@langchain/core/embeddings';\nimport type { Document } from '@langchain/classic/document';\nimport {\n\tNodeConnectionTypes,\n\ttype INodeExecutionData,\n\ttype IExecuteFunctions,\n\ttype INodeType,\n\ttype INodeTypeDescription,\n} from 'n8n-workflow';\n\nimport type { N8nJsonLoader } from '@utils/N8nJsonLoader';\n\nimport { MemoryVectorStoreManager } from '../shared/MemoryManager/MemoryVectorStoreManager';\nimport { processDocuments } from '../shared/processDocuments';\n\n// This node is deprecated. Use VectorStoreInMemory instead.\nexport class VectorStoreInMemoryInsert implements INodeType {\n\tdescription: INodeTypeDescription = {\n\t\tdisplayName: 'In Memory Vector Store Insert',\n\t\tname: 'vectorStoreInMemoryInsert',\n\t\ticon: 'fa:database',\n\t\tgroup: ['transform'],\n\t\tversion: 1,\n\t\thidden: true,\n\t\tdescription: 'Insert data into an in-memory vector store',\n\t\tdefaults: {\n\t\t\tname: 'In Memory Vector Store Insert',\n\t\t},\n\t\tcodex: {\n\t\t\tcategories: ['AI'],\n\t\t\tsubcategories: {\n\t\t\t\tAI: ['Vector Stores'],\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.vectorstoreinmemory/',\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t},\n\t\t},\n\n\t\tinputs: [\n\t\t\tNodeConnectionTypes.Main,\n\t\t\t{\n\t\t\t\tdisplayName: 'Document',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiDocument,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Embedding',\n\t\t\t\tmaxConnections: 1,\n\t\t\t\ttype: NodeConnectionTypes.AiEmbedding,\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t],\n\t\toutputs: [NodeConnectionTypes.Main],\n\t\tproperties: [\n\t\t\t{\n\t\t\t\tdisplayName:\n\t\t\t\t\t'The embbded data are stored in the server memory, so they will be lost when the server is restarted. Additionally, if the amount of data is too large, it may cause the server to crash due to insufficient memory.',\n\t\t\t\tname: 'notice',\n\t\t\t\ttype: 'notice',\n\t\t\t\tdefault: '',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Clear Store',\n\t\t\t\tname: 'clearStore',\n\t\t\t\ttype: 'boolean',\n\t\t\t\tdefault: false,\n\t\t\t\tdescription: 'Whether to clear the store before inserting new data',\n\t\t\t},\n\t\t\t{\n\t\t\t\tdisplayName: 'Memory Key',\n\t\t\t\tname: 'memoryKey',\n\t\t\t\ttype: 'string',\n\t\t\t\tdefault: 'vector_store_key',\n\t\t\t\tdescription:\n\t\t\t\t\t'The key to use to store the vector memory in the workflow data. The key will be prefixed with the workflow ID to avoid collisions.',\n\t\t\t},\n\t\t],\n\t};\n\n\tasync execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {\n\t\tconst items = this.getInputData(0);\n\t\tconst embeddings = (await this.getInputConnectionData(\n\t\t\tNodeConnectionTypes.AiEmbedding,\n\t\t\t0,\n\t\t)) as Embeddings;\n\n\t\tconst memoryKey = this.getNodeParameter('memoryKey', 0) as string;\n\t\tconst clearStore = this.getNodeParameter('clearStore', 0) as boolean;\n\t\tconst documentInput = (await this.getInputConnectionData(NodeConnectionTypes.AiDocument, 0)) as\n\t\t\t| N8nJsonLoader\n\t\t\t| Array<Document<Record<string, unknown>>>;\n\n\t\tconst { processedDocuments, serializedDocuments } = await processDocuments(\n\t\t\tdocumentInput,\n\t\t\titems,\n\t\t);\n\n\t\tconst workflowId = this.getWorkflow().id;\n\n\t\tconst vectorStoreInstance = MemoryVectorStoreManager.getInstance(embeddings, this.logger);\n\t\tawait vectorStoreInstance.addDocuments(\n\t\t\t`${workflowId}__${memoryKey}`,\n\t\t\tprocessedDocuments,\n\t\t\tclearStore,\n\t\t);\n\n\t\treturn [serializedDocuments];\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,0BAMO;AAIP,sCAAyC;AACzC,8BAAiC;AAG1B,MAAM,0BAA+C;AAAA,EAArD;AACN,uBAAoC;AAAA,MACnC,aAAa;AAAA,MACb,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,CAAC,WAAW;AAAA,MACnB,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,aAAa;AAAA,MACb,UAAU;AAAA,QACT,MAAM;AAAA,MACP;AAAA,MACA,OAAO;AAAA,QACN,YAAY,CAAC,IAAI;AAAA,QACjB,eAAe;AAAA,UACd,IAAI,CAAC,eAAe;AAAA,QACrB;AAAA,QACA,WAAW;AAAA,UACV,sBAAsB;AAAA,YACrB;AAAA,cACC,KAAK;AAAA,YACN;AAAA,UACD;AAAA,QACD;AAAA,MACD;AAAA,MAEA,QAAQ;AAAA,QACP,wCAAoB;AAAA,QACpB;AAAA,UACC,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,MAAM,wCAAoB;AAAA,UAC1B,UAAU;AAAA,QACX;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB,MAAM,wCAAoB;AAAA,UAC1B,UAAU;AAAA,QACX;AAAA,MACD;AAAA,MACA,SAAS,CAAC,wCAAoB,IAAI;AAAA,MAClC,YAAY;AAAA,QACX;AAAA,UACC,aACC;AAAA,UACD,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACV;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aAAa;AAAA,QACd;AAAA,QACA;AAAA,UACC,aAAa;AAAA,UACb,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,aACC;AAAA,QACF;AAAA,MACD;AAAA,IACD;AAAA;AAAA,EAEA,MAAM,UAAkE;AACvE,UAAM,QAAQ,KAAK,aAAa,CAAC;AACjC,UAAM,aAAc,MAAM,KAAK;AAAA,MAC9B,wCAAoB;AAAA,MACpB;AAAA,IACD;AAEA,UAAM,YAAY,KAAK,iBAAiB,aAAa,CAAC;AACtD,UAAM,aAAa,KAAK,iBAAiB,cAAc,CAAC;AACxD,UAAM,gBAAiB,MAAM,KAAK,uBAAuB,wCAAoB,YAAY,CAAC;AAI1F,UAAM,EAAE,oBAAoB,oBAAoB,IAAI,UAAM;AAAA,MACzD;AAAA,MACA;AAAA,IACD;AAEA,UAAM,aAAa,KAAK,YAAY,EAAE;AAEtC,UAAM,sBAAsB,yDAAyB,YAAY,YAAY,KAAK,MAAM;AACxF,UAAM,oBAAoB;AAAA,MACzB,GAAG,UAAU,KAAK,SAAS;AAAA,MAC3B;AAAA,MACA;AAAA,IACD;AAEA,WAAO,CAAC,mBAAmB;AAAA,EAC5B;AACD;","names":[]}
|
|
@@ -1,21 +1,25 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<svg
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
2
|
+
<svg data-name="Capa 2" viewBox="0 0 346.42 400" xmlns="http://www.w3.org/2000/svg">
|
|
3
|
+
<defs>
|
|
4
|
+
<style>.cls-1 {
|
|
5
|
+
fill: #9e0d38;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.cls-2 {
|
|
9
|
+
fill: #dc244c;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.cls-3 {
|
|
13
|
+
fill: #ff516b;
|
|
14
|
+
}</style>
|
|
15
|
+
</defs>
|
|
16
|
+
<polygon class="cls-2" points="173.21 0 0 100 0 300 173.21 400 238.16 362.5 238.16 287.5 173.21 325 64.96 262.5 64.96 137.5 173.21 75 281.46 137.5 281.46 387.5 346.42 350 346.42 100"/>
|
|
17
|
+
<polygon class="cls-2" points="108.26 162.5 108.26 237.5 173.21 275 238.16 237.5 238.16 162.5 173.21 125"/>
|
|
18
|
+
<polygon class="cls-1" points="238.16 287.5 238.16 362.5 173.21 400 173.21 325"/>
|
|
19
|
+
<polygon class="cls-1" points="346.42 100 346.42 350 281.46 387.5 281.46 137.5"/>
|
|
20
|
+
<polygon class="cls-3" points="346.42 100 281.46 137.5 173.21 75 64.96 137.5 0 100 173.21 0"/>
|
|
21
|
+
<polygon class="cls-2" points="173.21 325 173.21 400 0 300 0 100 64.96 137.5 64.96 262.5"/>
|
|
22
|
+
<polygon class="cls-3" points="238.16 162.5 173.21 200 108.26 162.5 173.21 125"/>
|
|
23
|
+
<polygon class="cls-2" points="173.21 200 173.21 275 108.26 237.5 108.26 162.5"/>
|
|
24
|
+
<polygon class="cls-1" points="238.16 162.5 238.16 237.5 173.21 275 173.21 200"/>
|
|
21
25
|
</svg>
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../nodes/vector_store/shared/MemoryManager/MemoryCalculator.ts"],"sourcesContent":["import type { Document } from '@langchain/core/documents';\nimport type { MemoryVectorStore } from 'langchain/vectorstores/memory';\n\nimport type { IMemoryCalculator } from './types';\n\n// Memory estimation constants\nconst FLOAT_SIZE_BYTES = 8; // Size of a float64 in bytes\nconst CHAR_SIZE_BYTES = 2; // Size of a JavaScript character in bytes(2 bytes per character in UTF-16)\nconst VECTOR_OVERHEAD_BYTES = 200; // Estimated overhead per vector\nconst EMBEDDING_DIMENSIONS = 1536; // Fixed embedding dimensions\nconst EMBEDDING_SIZE_BYTES = EMBEDDING_DIMENSIONS * FLOAT_SIZE_BYTES;\nconst AVG_METADATA_SIZE_BYTES = 100; // Average size for simple metadata\n\n/**\n * Calculates memory usage for vector stores and documents\n */\nexport class MemoryCalculator implements IMemoryCalculator {\n\t/**\n\t * Fast batch size estimation for multiple documents\n\t */\n\testimateBatchSize(documents: Document[]): number {\n\t\tif (documents.length === 0) return 0;\n\n\t\tlet totalContentSize = 0;\n\t\tlet totalMetadataSize = 0;\n\n\t\t// Single pass through documents for content and metadata estimation\n\t\tfor (const doc of documents) {\n\t\t\tif (doc.pageContent) {\n\t\t\t\ttotalContentSize += doc.pageContent.length * CHAR_SIZE_BYTES;\n\t\t\t}\n\n\t\t\t// Metadata size estimation\n\t\t\tif (doc.metadata) {\n\t\t\t\t// For simple objects, estimate based on key count\n\t\t\t\tconst metadataKeys = Object.keys(doc.metadata).length;\n\t\t\t\tif (metadataKeys > 0) {\n\t\t\t\t\t// For each key, estimate the key name plus a typical value\n\t\t\t\t\t// plus some overhead for object structure\n\t\t\t\t\ttotalMetadataSize += metadataKeys * AVG_METADATA_SIZE_BYTES;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fixed size components (embedding vectors and overhead)\n\t\t// Each embedding is a fixed-size array of floating point numbers\n\t\tconst embeddingSize = documents.length * EMBEDDING_SIZE_BYTES;\n\n\t\t// Object overhead, each vector is stored with additional JS object structure\n\t\tconst overhead = documents.length * VECTOR_OVERHEAD_BYTES;\n\n\t\t// Calculate total batch size with a safety factor to avoid underestimation\n\t\tconst calculatedSize = totalContentSize + totalMetadataSize + embeddingSize + overhead;\n\n\t\treturn Math.ceil(calculatedSize);\n\t}\n\n\t/**\n\t * Calculate the size of a vector store by examining its contents\n\t */\n\tcalculateVectorStoreSize(vectorStore: MemoryVectorStore): number {\n\t\tif (!vectorStore.memoryVectors || vectorStore.memoryVectors.length === 0) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tlet storeSize = 0;\n\n\t\t// Calculate size of each vector\n\t\tfor (const vector of vectorStore.memoryVectors) {\n\t\t\t// Size of embedding (float64 array)\n\t\t\tstoreSize += vector.embedding.length * FLOAT_SIZE_BYTES;\n\n\t\t\t// Size of content string (2 bytes per character in JS)\n\t\t\tstoreSize += vector.content ? vector.content.length * CHAR_SIZE_BYTES : 0;\n\n\t\t\t// Estimate metadata size\n\t\t\tif (vector.metadata) {\n\t\t\t\t// Use a more accurate calculation for metadata\n\t\t\t\tconst metadataStr = JSON.stringify(vector.metadata);\n\t\t\t\tstoreSize += metadataStr.length * CHAR_SIZE_BYTES;\n\t\t\t}\n\n\t\t\t// Add overhead for object structure\n\t\t\tstoreSize += VECTOR_OVERHEAD_BYTES;\n\t\t}\n\n\t\treturn Math.ceil(storeSize);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,wBAAwB;AAC9B,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB,uBAAuB;AACpD,MAAM,0BAA0B;AAKzB,MAAM,iBAA8C;AAAA;AAAA;AAAA;AAAA,EAI1D,kBAAkB,WAA+B;AAChD,QAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,QAAI,mBAAmB;AACvB,QAAI,oBAAoB;AAGxB,eAAW,OAAO,WAAW;AAC5B,UAAI,IAAI,aAAa;AACpB,4BAAoB,IAAI,YAAY,SAAS;AAAA,MAC9C;AAGA,UAAI,IAAI,UAAU;AAEjB,cAAM,eAAe,OAAO,KAAK,IAAI,QAAQ,EAAE;AAC/C,YAAI,eAAe,GAAG;AAGrB,+BAAqB,eAAe;AAAA,QACrC;AAAA,MACD;AAAA,IACD;AAIA,UAAM,gBAAgB,UAAU,SAAS;AAGzC,UAAM,WAAW,UAAU,SAAS;AAGpC,UAAM,iBAAiB,mBAAmB,oBAAoB,gBAAgB;AAE9E,WAAO,KAAK,KAAK,cAAc;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAyB,aAAwC;AAChE,QAAI,CAAC,YAAY,iBAAiB,YAAY,cAAc,WAAW,GAAG;AACzE,aAAO;AAAA,IACR;AAEA,QAAI,YAAY;AAGhB,eAAW,UAAU,YAAY,eAAe;AAE/C,mBAAa,OAAO,UAAU,SAAS;AAGvC,mBAAa,OAAO,UAAU,OAAO,QAAQ,SAAS,kBAAkB;AAGxE,UAAI,OAAO,UAAU;AAEpB,cAAM,cAAc,KAAK,UAAU,OAAO,QAAQ;AAClD,qBAAa,YAAY,SAAS;AAAA,MACnC;AAGA,mBAAa;AAAA,IACd;AAEA,WAAO,KAAK,KAAK,SAAS;AAAA,EAC3B;AACD;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../../../nodes/vector_store/shared/MemoryManager/MemoryCalculator.ts"],"sourcesContent":["import type { Document } from '@langchain/core/documents';\nimport type { MemoryVectorStore } from '@langchain/classic/vectorstores/memory';\n\nimport type { IMemoryCalculator } from './types';\n\n// Memory estimation constants\nconst FLOAT_SIZE_BYTES = 8; // Size of a float64 in bytes\nconst CHAR_SIZE_BYTES = 2; // Size of a JavaScript character in bytes(2 bytes per character in UTF-16)\nconst VECTOR_OVERHEAD_BYTES = 200; // Estimated overhead per vector\nconst EMBEDDING_DIMENSIONS = 1536; // Fixed embedding dimensions\nconst EMBEDDING_SIZE_BYTES = EMBEDDING_DIMENSIONS * FLOAT_SIZE_BYTES;\nconst AVG_METADATA_SIZE_BYTES = 100; // Average size for simple metadata\n\n/**\n * Calculates memory usage for vector stores and documents\n */\nexport class MemoryCalculator implements IMemoryCalculator {\n\t/**\n\t * Fast batch size estimation for multiple documents\n\t */\n\testimateBatchSize(documents: Document[]): number {\n\t\tif (documents.length === 0) return 0;\n\n\t\tlet totalContentSize = 0;\n\t\tlet totalMetadataSize = 0;\n\n\t\t// Single pass through documents for content and metadata estimation\n\t\tfor (const doc of documents) {\n\t\t\tif (doc.pageContent) {\n\t\t\t\ttotalContentSize += doc.pageContent.length * CHAR_SIZE_BYTES;\n\t\t\t}\n\n\t\t\t// Metadata size estimation\n\t\t\tif (doc.metadata) {\n\t\t\t\t// For simple objects, estimate based on key count\n\t\t\t\tconst metadataKeys = Object.keys(doc.metadata).length;\n\t\t\t\tif (metadataKeys > 0) {\n\t\t\t\t\t// For each key, estimate the key name plus a typical value\n\t\t\t\t\t// plus some overhead for object structure\n\t\t\t\t\ttotalMetadataSize += metadataKeys * AVG_METADATA_SIZE_BYTES;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fixed size components (embedding vectors and overhead)\n\t\t// Each embedding is a fixed-size array of floating point numbers\n\t\tconst embeddingSize = documents.length * EMBEDDING_SIZE_BYTES;\n\n\t\t// Object overhead, each vector is stored with additional JS object structure\n\t\tconst overhead = documents.length * VECTOR_OVERHEAD_BYTES;\n\n\t\t// Calculate total batch size with a safety factor to avoid underestimation\n\t\tconst calculatedSize = totalContentSize + totalMetadataSize + embeddingSize + overhead;\n\n\t\treturn Math.ceil(calculatedSize);\n\t}\n\n\t/**\n\t * Calculate the size of a vector store by examining its contents\n\t */\n\tcalculateVectorStoreSize(vectorStore: MemoryVectorStore): number {\n\t\tif (!vectorStore.memoryVectors || vectorStore.memoryVectors.length === 0) {\n\t\t\treturn 0;\n\t\t}\n\n\t\tlet storeSize = 0;\n\n\t\t// Calculate size of each vector\n\t\tfor (const vector of vectorStore.memoryVectors) {\n\t\t\t// Size of embedding (float64 array)\n\t\t\tstoreSize += vector.embedding.length * FLOAT_SIZE_BYTES;\n\n\t\t\t// Size of content string (2 bytes per character in JS)\n\t\t\tstoreSize += vector.content ? vector.content.length * CHAR_SIZE_BYTES : 0;\n\n\t\t\t// Estimate metadata size\n\t\t\tif (vector.metadata) {\n\t\t\t\t// Use a more accurate calculation for metadata\n\t\t\t\tconst metadataStr = JSON.stringify(vector.metadata);\n\t\t\t\tstoreSize += metadataStr.length * CHAR_SIZE_BYTES;\n\t\t\t}\n\n\t\t\t// Add overhead for object structure\n\t\t\tstoreSize += VECTOR_OVERHEAD_BYTES;\n\t\t}\n\n\t\treturn Math.ceil(storeSize);\n\t}\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAMA,MAAM,mBAAmB;AACzB,MAAM,kBAAkB;AACxB,MAAM,wBAAwB;AAC9B,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB,uBAAuB;AACpD,MAAM,0BAA0B;AAKzB,MAAM,iBAA8C;AAAA;AAAA;AAAA;AAAA,EAI1D,kBAAkB,WAA+B;AAChD,QAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,QAAI,mBAAmB;AACvB,QAAI,oBAAoB;AAGxB,eAAW,OAAO,WAAW;AAC5B,UAAI,IAAI,aAAa;AACpB,4BAAoB,IAAI,YAAY,SAAS;AAAA,MAC9C;AAGA,UAAI,IAAI,UAAU;AAEjB,cAAM,eAAe,OAAO,KAAK,IAAI,QAAQ,EAAE;AAC/C,YAAI,eAAe,GAAG;AAGrB,+BAAqB,eAAe;AAAA,QACrC;AAAA,MACD;AAAA,IACD;AAIA,UAAM,gBAAgB,UAAU,SAAS;AAGzC,UAAM,WAAW,UAAU,SAAS;AAGpC,UAAM,iBAAiB,mBAAmB,oBAAoB,gBAAgB;AAE9E,WAAO,KAAK,KAAK,cAAc;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,yBAAyB,aAAwC;AAChE,QAAI,CAAC,YAAY,iBAAiB,YAAY,cAAc,WAAW,GAAG;AACzE,aAAO;AAAA,IACR;AAEA,QAAI,YAAY;AAGhB,eAAW,UAAU,YAAY,eAAe;AAE/C,mBAAa,OAAO,UAAU,SAAS;AAGvC,mBAAa,OAAO,UAAU,OAAO,QAAQ,SAAS,kBAAkB;AAGxE,UAAI,OAAO,UAAU;AAEpB,cAAM,cAAc,KAAK,UAAU,OAAO,QAAQ;AAClD,qBAAa,YAAY,SAAS;AAAA,MACnC;AAGA,mBAAa;AAAA,IACd;AAEA,WAAO,KAAK,KAAK,SAAS;AAAA,EAC3B;AACD;","names":[]}
|
|
@@ -21,7 +21,7 @@ __export(MemoryVectorStoreManager_exports, {
|
|
|
21
21
|
MemoryVectorStoreManager: () => MemoryVectorStoreManager
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(MemoryVectorStoreManager_exports);
|
|
24
|
-
var import_memory = require("langchain/vectorstores/memory");
|
|
24
|
+
var import_memory = require("@langchain/classic/vectorstores/memory");
|
|
25
25
|
var import_config = require("./config");
|
|
26
26
|
var import_MemoryCalculator = require("./MemoryCalculator");
|
|
27
27
|
var import_StoreCleanupService = require("./StoreCleanupService");
|