Bugfix/Get value with nested metadata filter (#3695)

add ability to get value with nested metadata filter
This commit is contained in:
Henry Heng
2024-12-12 14:57:38 +00:00
committed by GitHub
parent bfd677059e
commit 85abd157a2
2 changed files with 24 additions and 10 deletions
@@ -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<any>).vectorStore
vectorStore.filter = newMetadataFilter
+22
View File
@@ -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
}
}