diff --git a/packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts b/packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts index e2d4c2679cf..0010bce9c50 100644 --- a/packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts +++ b/packages/components/nodes/tools/RetrieverTool/RetrieverTool.ts @@ -3,10 +3,9 @@ import { CallbackManager, CallbackManagerForToolRun, Callbacks, parseCallbackCon import { BaseDynamicToolInput, DynamicTool, StructuredTool, ToolInputParsingException } from '@langchain/core/tools' import { BaseRetriever } from '@langchain/core/retrievers' import { ICommonObject, INode, INodeData, INodeParams } from '../../../src/Interface' -import { getBaseClasses } from '../../../src/utils' +import { getBaseClasses, resolveFlowObjValue } from '../../../src/utils' import { SOURCE_DOCUMENTS_PREFIX } from '../../../src/agents' import { RunnableConfig } from '@langchain/core/runnables' -import { customGet } from '../../sequentialagents/commonUtils' import { VectorStoreRetriever } from '@langchain/core/vectorstores' const howToUse = `Add additional filters to vector store. You can also filter with flow config, including the current "state": @@ -199,14 +198,7 @@ class Retriever_Tools implements INode { const metadatafilter = typeof retrieverToolMetadataFilter === 'object' ? retrieverToolMetadataFilter : JSON.parse(retrieverToolMetadataFilter) - const newMetadataFilter: any = {} - for (const key in metadatafilter) { - let value = metadatafilter[key] - if (value.startsWith('$flow')) { - value = customGet(flowObj, value) - } - newMetadataFilter[key] = value - } + const newMetadataFilter = resolveFlowObjValue(metadatafilter, flowObj) const vectorStore = (retriever as VectorStoreRetriever).vectorStore vectorStore.filter = newMetadataFilter diff --git a/packages/components/src/utils.ts b/packages/components/src/utils.ts index 64b20a47f33..97d9dcfb26f 100644 --- a/packages/components/src/utils.ts +++ b/packages/components/src/utils.ts @@ -9,6 +9,7 @@ import { ICommonObject, IDatabaseEntity, IDocument, IMessage, INodeData, IVariab import { AES, enc } from 'crypto-js' import { AIMessage, HumanMessage, BaseMessage } from '@langchain/core/messages' import { getFileFromStorage } from './storageUtils' +import { customGet } from '../nodes/sequentialagents/commonUtils' export const numberOrExpressionRegex = '^(\\d+\\.?\\d*|{{.*}})$' //return true if string consists only numbers OR expression {{}} export const notEmptyRegex = '(.|\\s)*\\S(.|\\s)*' //return true if string is not empty or blank @@ -999,3 +1000,24 @@ export const mapMimeTypeToExt = (mimeType: string) => { export const removeInvalidImageMarkdown = (output: string): string => { return typeof output === 'string' ? output.replace(/!\[.*?\]\((?!https?:\/\/).*?\)/g, '') : output } + +/** + * Loop through the object and replace the key with the value + * @param {any} obj + * @param {any} sourceObj + * @returns {any} + */ +export const resolveFlowObjValue = (obj: any, sourceObj: any): any => { + if (typeof obj === 'object' && obj !== null) { + const resolved: any = Array.isArray(obj) ? [] : {} + for (const key in obj) { + const value = obj[key] + resolved[key] = resolveFlowObjValue(value, sourceObj) + } + return resolved + } else if (typeof obj === 'string' && obj.startsWith('$flow')) { + return customGet(sourceObj, obj) + } else { + return obj + } +}