|
|
@@ -1260,9 +1260,9 @@ describe("QdrantVectorStore", () => {
|
|
|
const results = await vectorStore.search(queryVector)
|
|
|
|
|
|
expect(mockQdrantClientInstance.query).toHaveBeenCalledTimes(1)
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: undefined,
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1273,6 +1273,9 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs.filter).toEqual({
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ })
|
|
|
|
|
|
expect(results).toEqual(mockQdrantResults.points)
|
|
|
})
|
|
|
@@ -1300,29 +1303,20 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
const results = await vectorStore.search(queryVector, directoryPrefix)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs2 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs2).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: {
|
|
|
- must: [
|
|
|
- {
|
|
|
- key: "pathSegments.0",
|
|
|
- match: { value: "src" },
|
|
|
- },
|
|
|
- {
|
|
|
- key: "pathSegments.1",
|
|
|
- match: { value: "components" },
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
- params: {
|
|
|
- hnsw_ef: 128,
|
|
|
- exact: false,
|
|
|
- },
|
|
|
- with_payload: {
|
|
|
- include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
- },
|
|
|
+ params: { hnsw_ef: 128, exact: false },
|
|
|
+ with_payload: { include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"] },
|
|
|
+ })
|
|
|
+ expect(callArgs2.filter).toEqual({
|
|
|
+ must: [
|
|
|
+ { key: "pathSegments.0", match: { value: "src" } },
|
|
|
+ { key: "pathSegments.1", match: { value: "components" } },
|
|
|
+ ],
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
})
|
|
|
|
|
|
expect(results).toEqual(mockQdrantResults.points)
|
|
|
@@ -1337,9 +1331,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
await vectorStore.search(queryVector, undefined, customMinScore)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs3 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs3).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: undefined,
|
|
|
score_threshold: customMinScore,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1350,6 +1344,9 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs3.filter).toEqual({
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
it("should use custom maxResults when provided", async () => {
|
|
|
@@ -1361,9 +1358,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
await vectorStore.search(queryVector, undefined, undefined, customMaxResults)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs4 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs4).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: undefined,
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: customMaxResults,
|
|
|
params: {
|
|
|
@@ -1374,6 +1371,9 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs4.filter).toEqual({
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
it("should filter out results with invalid payloads", async () => {
|
|
|
@@ -1489,28 +1489,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
await vectorStore.search(queryVector, directoryPrefix)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs5 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs5).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: {
|
|
|
- must: [
|
|
|
- {
|
|
|
- key: "pathSegments.0",
|
|
|
- match: { value: "src" },
|
|
|
- },
|
|
|
- {
|
|
|
- key: "pathSegments.1",
|
|
|
- match: { value: "components" },
|
|
|
- },
|
|
|
- {
|
|
|
- key: "pathSegments.2",
|
|
|
- match: { value: "ui" },
|
|
|
- },
|
|
|
- {
|
|
|
- key: "pathSegments.3",
|
|
|
- match: { value: "forms" },
|
|
|
- },
|
|
|
- ],
|
|
|
- },
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1521,6 +1502,15 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs5.filter).toEqual({
|
|
|
+ must: [
|
|
|
+ { key: "pathSegments.0", match: { value: "src" } },
|
|
|
+ { key: "pathSegments.1", match: { value: "components" } },
|
|
|
+ { key: "pathSegments.2", match: { value: "ui" } },
|
|
|
+ { key: "pathSegments.3", match: { value: "forms" } },
|
|
|
+ ],
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
it("should handle error scenarios when qdrantClient.query fails", async () => {
|
|
|
@@ -1573,9 +1563,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
const results = await vectorStore.search(queryVector, directoryPrefix)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs7 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs7).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: undefined, // Should be undefined for current directory
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1586,6 +1576,9 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs7.filter).toEqual({
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ })
|
|
|
|
|
|
expect(results).toEqual(mockQdrantResults.points)
|
|
|
})
|
|
|
@@ -1599,9 +1592,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
await vectorStore.search(queryVector, directoryPrefix)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs6 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs6).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: undefined, // Should be undefined for current directory
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1612,6 +1605,9 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs6.filter).toEqual({
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
it("should not apply filter when directoryPrefix is empty string", async () => {
|
|
|
@@ -1623,9 +1619,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
await vectorStore.search(queryVector, directoryPrefix)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs8 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs8).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: undefined, // Should be undefined for empty string
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1636,6 +1632,9 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs8.filter).toEqual({
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
it("should not apply filter when directoryPrefix is '.\\' (Windows style)", async () => {
|
|
|
@@ -1647,9 +1646,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
await vectorStore.search(queryVector, directoryPrefix)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs9 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs9).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: undefined, // Should be undefined for Windows current directory
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1660,6 +1659,9 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs9.filter).toEqual({
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
it("should not apply filter when directoryPrefix has trailing slashes", async () => {
|
|
|
@@ -1671,9 +1673,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
await vectorStore.search(queryVector, directoryPrefix)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs10 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs10).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: undefined, // Should be undefined after normalizing trailing slashes
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1684,6 +1686,9 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs10.filter).toEqual({
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ })
|
|
|
})
|
|
|
|
|
|
it("should still apply filter for relative paths like './src'", async () => {
|
|
|
@@ -1695,16 +1700,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
await vectorStore.search(queryVector, directoryPrefix)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs11 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs11).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: {
|
|
|
- must: [
|
|
|
- {
|
|
|
- key: "pathSegments.0",
|
|
|
- match: { value: "src" },
|
|
|
- },
|
|
|
- ],
|
|
|
- }, // Should normalize "./src" to "src"
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1715,6 +1713,15 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs11.filter).toEqual({
|
|
|
+ must: [
|
|
|
+ {
|
|
|
+ key: "pathSegments.0",
|
|
|
+ match: { value: "src" },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ }) // Should normalize "./src" to "src"
|
|
|
})
|
|
|
|
|
|
it("should still apply filter for regular directory paths", async () => {
|
|
|
@@ -1726,16 +1733,9 @@ describe("QdrantVectorStore", () => {
|
|
|
|
|
|
await vectorStore.search(queryVector, directoryPrefix)
|
|
|
|
|
|
- expect(mockQdrantClientInstance.query).toHaveBeenCalledWith(expectedCollectionName, {
|
|
|
+ const callArgs12 = mockQdrantClientInstance.query.mock.calls[0][1]
|
|
|
+ expect(callArgs12).toMatchObject({
|
|
|
query: queryVector,
|
|
|
- filter: {
|
|
|
- must: [
|
|
|
- {
|
|
|
- key: "pathSegments.0",
|
|
|
- match: { value: "src" },
|
|
|
- },
|
|
|
- ],
|
|
|
- }, // Should still create filter for regular paths
|
|
|
score_threshold: DEFAULT_SEARCH_MIN_SCORE,
|
|
|
limit: DEFAULT_MAX_SEARCH_RESULTS,
|
|
|
params: {
|
|
|
@@ -1746,6 +1746,15 @@ describe("QdrantVectorStore", () => {
|
|
|
include: ["filePath", "codeChunk", "startLine", "endLine", "pathSegments"],
|
|
|
},
|
|
|
})
|
|
|
+ expect(callArgs12.filter).toEqual({
|
|
|
+ must: [
|
|
|
+ {
|
|
|
+ key: "pathSegments.0",
|
|
|
+ match: { value: "src" },
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ must_not: [{ key: "type", match: { value: "metadata" } }],
|
|
|
+ }) // Should still create filter for regular paths
|
|
|
})
|
|
|
})
|
|
|
})
|