@langchain/core
Version:
Core LangChain.js abstractions and schemas
1 lines • 11.7 kB
Source Map (JSON)
{"version":3,"file":"functional.cjs","names":["BaseTranslator","Operators","Comparators","castValue","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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"}