UNPKG

@langchain/core

Version:
1 lines 12.1 kB
{"version":3,"file":"functional.cjs","names":["BaseTranslator","Operators","Comparators","inputType: string","comparator: Comparator","a: string | number","b: ValueType[C]","operator: Operator","operation: Operation","document: Document","comparison: Comparison<string | number | boolean>","castValue","query: StructuredQuery","defaultFilter: FunctionFilter","generatedFilter: FunctionFilter","isFilterEmpty"],"sources":["../../src/structured_query/functional.ts"],"sourcesContent":["import { Document } from \"../documents/document.js\";\nimport {\n Comparator,\n Comparators,\n Comparison,\n Operation,\n Operator,\n Operators,\n StructuredQuery,\n} from \"./ir.js\";\nimport { BaseTranslator } from \"./base.js\";\nimport { castValue, isFilterEmpty } from \"./utils.js\";\n\n/**\n * A type alias for an object that maps comparison operators to string or\n * number values. This is used in the comparison functions to determine\n * the result of a comparison operation.\n */\ntype ValueType = {\n eq: string | number | boolean;\n ne: string | number | boolean;\n lt: string | number;\n lte: string | number;\n gt: string | number;\n gte: string | number;\n};\n\n/**\n * A type alias for a function that takes a `Document` as an argument and\n * returns a boolean. This function is used as a filter for documents.\n */\nexport type FunctionFilter = (document: Document) => boolean;\n\n/**\n * A class that extends `BaseTranslator` to translate structured queries\n * into functional filters.\n * @example\n * ```typescript\n * const functionalTranslator = new FunctionalTranslator();\n * const relevantDocuments = await functionalTranslator.getRelevantDocuments(\n * \"Which movies are rated higher than 8.5?\",\n * );\n * ```\n */\nexport class FunctionalTranslator extends BaseTranslator {\n declare VisitOperationOutput: FunctionFilter;\n\n declare VisitComparisonOutput: FunctionFilter;\n\n declare VisitStructuredQueryOutput:\n | { filter: FunctionFilter }\n | { [k: string]: never };\n\n allowedOperators: Operator[] = [Operators.and, Operators.or];\n\n allowedComparators: Comparator[] = [\n Comparators.eq,\n Comparators.ne,\n Comparators.gt,\n Comparators.gte,\n Comparators.lt,\n Comparators.lte,\n ];\n\n formatFunction(): string {\n throw new Error(\"Not implemented\");\n }\n\n /**\n * Returns the allowed comparators for a given data type.\n * @param input The input value to get the allowed comparators for.\n * @returns An array of allowed comparators for the input data type.\n */\n getAllowedComparatorsForType(inputType: string): Comparator[] {\n switch (inputType) {\n case \"string\": {\n return [\n Comparators.eq,\n Comparators.ne,\n Comparators.gt,\n Comparators.gte,\n Comparators.lt,\n Comparators.lte,\n ];\n }\n case \"number\": {\n return [\n Comparators.eq,\n Comparators.ne,\n Comparators.gt,\n Comparators.gte,\n Comparators.lt,\n Comparators.lte,\n ];\n }\n case \"boolean\": {\n return [Comparators.eq, Comparators.ne];\n }\n default: {\n throw new Error(`Unsupported data type: ${inputType}`);\n }\n }\n }\n\n /**\n * Returns a function that performs a comparison based on the provided\n * comparator.\n * @param comparator The comparator to base the comparison function on.\n * @returns A function that takes two arguments and returns a boolean based on the comparison.\n */\n getComparatorFunction<C extends Comparator>(\n comparator: Comparator\n ): (a: string | number, b: ValueType[C]) => boolean {\n switch (comparator) {\n case Comparators.eq: {\n return (a: string | number, b: ValueType[C]) => a === b;\n }\n case Comparators.ne: {\n return (a: string | number, b: ValueType[C]) => a !== b;\n }\n case Comparators.gt: {\n return (a: string | number, b: ValueType[C]) => a > b;\n }\n case Comparators.gte: {\n return (a: string | number, b: ValueType[C]) => a >= b;\n }\n case Comparators.lt: {\n return (a: string | number, b: ValueType[C]) => a < b;\n }\n case Comparators.lte: {\n return (a: string | number, b: ValueType[C]) => a <= b;\n }\n default: {\n throw new Error(\"Unknown comparator\");\n }\n }\n }\n\n /**\n * Returns a function that performs an operation based on the provided\n * operator.\n * @param operator The operator to base the operation function on.\n * @returns A function that takes two boolean arguments and returns a boolean based on the operation.\n */\n getOperatorFunction(operator: Operator): (a: boolean, b: boolean) => boolean {\n switch (operator) {\n case Operators.and: {\n return (a, b) => a && b;\n }\n case Operators.or: {\n return (a, b) => a || b;\n }\n default: {\n throw new Error(\"Unknown operator\");\n }\n }\n }\n\n /**\n * Visits the operation part of a structured query and translates it into\n * a functional filter.\n * @param operation The operation part of a structured query.\n * @returns A function that takes a `Document` as an argument and returns a boolean based on the operation.\n */\n visitOperation(operation: Operation): this[\"VisitOperationOutput\"] {\n const { operator, args } = operation;\n if (this.allowedOperators.includes(operator)) {\n const operatorFunction = this.getOperatorFunction(operator);\n return (document: Document) => {\n if (!args) {\n return true;\n }\n\n return args.reduce((acc, arg) => {\n const result = arg.accept(this);\n if (typeof result === \"function\") {\n return operatorFunction(acc, result(document));\n } else {\n throw new Error(\"Filter is not a function\");\n }\n }, true);\n };\n } else {\n throw new Error(\"Operator not allowed\");\n }\n }\n\n /**\n * Visits the comparison part of a structured query and translates it into\n * a functional filter.\n * @param comparison The comparison part of a structured query.\n * @returns A function that takes a `Document` as an argument and returns a boolean based on the comparison.\n */\n visitComparison(\n comparison: Comparison<string | number | boolean>\n ): this[\"VisitComparisonOutput\"] {\n const { comparator, attribute, value } = comparison;\n const undefinedTrue = [Comparators.ne];\n if (this.allowedComparators.includes(comparator)) {\n if (\n !this.getAllowedComparatorsForType(typeof value).includes(comparator)\n ) {\n throw new Error(\n `'${comparator}' comparator not allowed to be used with ${typeof value}`\n );\n }\n const comparatorFunction = this.getComparatorFunction(comparator);\n return (document: Document) => {\n const documentValue = document.metadata[attribute];\n if (documentValue === undefined) {\n if (undefinedTrue.includes(comparator)) {\n return true;\n }\n return false;\n }\n return comparatorFunction(documentValue, castValue(value));\n };\n } else {\n throw new Error(\"Comparator not allowed\");\n }\n }\n\n /**\n * Visits a structured query and translates it into a functional filter.\n * @param query The structured query to translate.\n * @returns An object containing a `filter` property, which is a function that takes a `Document` as an argument and returns a boolean based on the structured query.\n */\n visitStructuredQuery(\n query: StructuredQuery\n ): this[\"VisitStructuredQueryOutput\"] {\n if (!query.filter) {\n return {};\n }\n const filterFunction = query.filter?.accept(this);\n if (typeof filterFunction !== \"function\") {\n throw new Error(\"Structured query filter is not a function\");\n }\n return { filter: filterFunction as FunctionFilter };\n }\n\n /**\n * Merges two filters into one, based on the specified merge type.\n * @param defaultFilter The default filter function.\n * @param generatedFilter The generated filter function.\n * @param mergeType The type of merge to perform. Can be 'and', 'or', or 'replace'. Default is 'and'.\n * @returns A function that takes a `Document` as an argument and returns a boolean based on the merged filters, or `undefined` if both filters are empty.\n */\n mergeFilters(\n defaultFilter: FunctionFilter,\n generatedFilter: FunctionFilter,\n mergeType = \"and\"\n ): FunctionFilter | undefined {\n if (isFilterEmpty(defaultFilter) && isFilterEmpty(generatedFilter)) {\n return undefined;\n }\n if (isFilterEmpty(defaultFilter) || mergeType === \"replace\") {\n if (isFilterEmpty(generatedFilter)) {\n return undefined;\n }\n return generatedFilter;\n }\n if (isFilterEmpty(generatedFilter)) {\n if (mergeType === \"and\") {\n return undefined;\n }\n return defaultFilter;\n }\n\n if (mergeType === \"and\") {\n return (document: Document) =>\n defaultFilter(document) && generatedFilter(document);\n } else if (mergeType === \"or\") {\n return (document: Document) =>\n defaultFilter(document) || generatedFilter(document);\n } else {\n throw new Error(\"Unknown merge type\");\n }\n }\n}\n"],"mappings":"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"}