agsamantha/node_modules/@langchain/community/dist/structured_query/qdrant.cjs

164 lines
5.9 KiB
JavaScript
Raw Normal View History

2024-10-02 20:15:21 +00:00
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.QdrantTranslator = void 0;
const structured_query_1 = require("@langchain/core/structured_query");
/**
* A class that translates or converts `StructuredQuery` to equivalent Qdrant filters.
* @example
* ```typescript
* const selfQueryRetriever = new SelfQueryRetriever({
* llm: new ChatOpenAI(),
* vectorStore: new QdrantVectorStore(...),
* documentContents: "Brief summary of a movie",
* attributeInfo: [],
* structuredQueryTranslator: new QdrantTranslator(),
* });
*
* const relevantDocuments = await selfQueryRetriever.getRelevantDocuments(
* "Which movies are rated higher than 8.5?",
* );
* ```
*/
class QdrantTranslator extends structured_query_1.BaseTranslator {
constructor() {
super(...arguments);
Object.defineProperty(this, "allowedOperators", {
enumerable: true,
configurable: true,
writable: true,
value: [structured_query_1.Operators.and, structured_query_1.Operators.or, structured_query_1.Operators.not]
});
Object.defineProperty(this, "allowedComparators", {
enumerable: true,
configurable: true,
writable: true,
value: [
structured_query_1.Comparators.eq,
structured_query_1.Comparators.ne,
structured_query_1.Comparators.lt,
structured_query_1.Comparators.lte,
structured_query_1.Comparators.gt,
structured_query_1.Comparators.gte,
]
});
}
/**
* Visits an operation and returns a QdrantFilter.
* @param operation The operation to visit.
* @returns A QdrantFilter.
*/
visitOperation(operation) {
const args = operation.args?.map((arg) => arg.accept(this));
const operator = {
[structured_query_1.Operators.and]: "must",
[structured_query_1.Operators.or]: "should",
[structured_query_1.Operators.not]: "must_not",
}[operation.operator];
return {
[operator]: args,
};
}
/**
* Visits a comparison and returns a QdrantCondition.
* The value is casted to the correct type.
* The attribute is prefixed with "metadata.",
* since metadata is nested in the Qdrant payload.
* @param comparison The comparison to visit.
* @returns A QdrantCondition.
*/
visitComparison(comparison) {
const attribute = `metadata.${comparison.attribute}`;
const value = (0, structured_query_1.castValue)(comparison.value);
if (comparison.comparator === "eq") {
return {
key: attribute,
match: {
value,
},
};
}
else if (comparison.comparator === "ne") {
return {
key: attribute,
match: {
except: [value],
},
};
}
if (!(0, structured_query_1.isInt)(value) && !(0, structured_query_1.isFloat)(value)) {
throw new Error("Value for gt, gte, lt, lte must be a number");
}
// For gt, gte, lt, lte, we need to use the range filter
return {
key: attribute,
range: {
[comparison.comparator]: value,
},
};
}
/**
* Visits a structured query and returns a VisitStructuredQueryOutput.
* If the query has a filter, it is visited.
* @param query The structured query to visit.
* @returns An instance of VisitStructuredQueryOutput.
*/
visitStructuredQuery(query) {
let nextArg = {};
if (query.filter) {
nextArg = {
filter: { must: [query.filter.accept(this)] },
};
}
return nextArg;
}
/**
* Merges two filters into one. If both filters are empty, returns
* undefined. If one filter is empty or the merge type is 'replace',
* returns the other filter. If the merge type is 'and' or 'or', returns a
* new filter with the merged results. Throws an error for unknown merge
* types.
* @param defaultFilter The default filter to merge.
* @param generatedFilter The generated filter to merge.
* @param mergeType The type of merge to perform. Can be 'and', 'or', or 'replace'. Defaults to 'and'.
* @param forceDefaultFilter If true, the default filter is always returned if the generated filter is empty. Defaults to false.
* @returns A merged QdrantFilter, or undefined if both filters are empty.
*/
mergeFilters(defaultFilter, generatedFilter, mergeType = "and", forceDefaultFilter = false) {
if ((0, structured_query_1.isFilterEmpty)(defaultFilter) && (0, structured_query_1.isFilterEmpty)(generatedFilter)) {
return undefined;
}
if ((0, structured_query_1.isFilterEmpty)(defaultFilter) || mergeType === "replace") {
if ((0, structured_query_1.isFilterEmpty)(generatedFilter)) {
return undefined;
}
return generatedFilter;
}
if ((0, structured_query_1.isFilterEmpty)(generatedFilter)) {
if (forceDefaultFilter) {
return defaultFilter;
}
if (mergeType === "and") {
return undefined;
}
return defaultFilter;
}
if (mergeType === "and") {
return {
must: [defaultFilter, generatedFilter],
};
}
else if (mergeType === "or") {
return {
should: [defaultFilter, generatedFilter],
};
}
else {
throw new Error("Unknown merge type");
}
}
formatFunction() {
throw new Error("Not implemented");
}
}
exports.QdrantTranslator = QdrantTranslator;