mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
fix(qdrant): add URL prefix handling for QdrantClient initialization (#5033)
This commit is contained in:
parent
1f05caa569
commit
3fda1efbd7
2 changed files with 161 additions and 0 deletions
|
|
@ -113,6 +113,7 @@ describe("QdrantVectorStore", () => {
|
|||
host: "qdrant.ashbyfam.com",
|
||||
https: true,
|
||||
port: 443,
|
||||
prefix: undefined, // No prefix for root path
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
|
|
@ -127,6 +128,7 @@ describe("QdrantVectorStore", () => {
|
|||
host: "example.com",
|
||||
https: true,
|
||||
port: 9000,
|
||||
prefix: undefined, // No prefix for root path
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
|
|
@ -145,6 +147,7 @@ describe("QdrantVectorStore", () => {
|
|||
host: "example.com",
|
||||
https: true,
|
||||
port: 443,
|
||||
prefix: "/api/v1", // Should have prefix
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
|
|
@ -161,6 +164,7 @@ describe("QdrantVectorStore", () => {
|
|||
host: "example.com",
|
||||
https: false,
|
||||
port: 80,
|
||||
prefix: undefined, // No prefix for root path
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
|
|
@ -175,6 +179,7 @@ describe("QdrantVectorStore", () => {
|
|||
host: "localhost",
|
||||
https: false,
|
||||
port: 8080,
|
||||
prefix: undefined, // No prefix for root path
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
|
|
@ -193,6 +198,7 @@ describe("QdrantVectorStore", () => {
|
|||
host: "example.com",
|
||||
https: false,
|
||||
port: 80,
|
||||
prefix: "/api/v1", // Should have prefix
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
|
|
@ -337,6 +343,159 @@ describe("QdrantVectorStore", () => {
|
|||
})
|
||||
})
|
||||
|
||||
describe("URL Prefix Handling", () => {
|
||||
it("should pass the URL pathname as prefix to QdrantClient if not root", () => {
|
||||
const vectorStoreWithPrefix = new QdrantVectorStore(
|
||||
mockWorkspacePath,
|
||||
"http://localhost:6333/some/path",
|
||||
mockVectorSize,
|
||||
)
|
||||
expect(QdrantClient).toHaveBeenLastCalledWith({
|
||||
host: "localhost",
|
||||
https: false,
|
||||
port: 6333,
|
||||
prefix: "/some/path",
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
},
|
||||
})
|
||||
expect((vectorStoreWithPrefix as any).qdrantUrl).toBe("http://localhost:6333/some/path")
|
||||
})
|
||||
|
||||
it("should not pass prefix if the URL pathname is root ('/')", () => {
|
||||
const vectorStoreWithoutPrefix = new QdrantVectorStore(
|
||||
mockWorkspacePath,
|
||||
"http://localhost:6333/",
|
||||
mockVectorSize,
|
||||
)
|
||||
expect(QdrantClient).toHaveBeenLastCalledWith({
|
||||
host: "localhost",
|
||||
https: false,
|
||||
port: 6333,
|
||||
prefix: undefined,
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
},
|
||||
})
|
||||
expect((vectorStoreWithoutPrefix as any).qdrantUrl).toBe("http://localhost:6333/")
|
||||
})
|
||||
|
||||
it("should handle HTTPS URL with path as prefix", () => {
|
||||
const vectorStoreWithHttpsPrefix = new QdrantVectorStore(
|
||||
mockWorkspacePath,
|
||||
"https://qdrant.ashbyfam.com/api",
|
||||
mockVectorSize,
|
||||
)
|
||||
expect(QdrantClient).toHaveBeenLastCalledWith({
|
||||
host: "qdrant.ashbyfam.com",
|
||||
https: true,
|
||||
port: 443,
|
||||
prefix: "/api",
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
},
|
||||
})
|
||||
expect((vectorStoreWithHttpsPrefix as any).qdrantUrl).toBe("https://qdrant.ashbyfam.com/api")
|
||||
})
|
||||
|
||||
it("should normalize URL pathname by removing trailing slash for prefix", () => {
|
||||
const vectorStoreWithTrailingSlash = new QdrantVectorStore(
|
||||
mockWorkspacePath,
|
||||
"http://localhost:6333/api/",
|
||||
mockVectorSize,
|
||||
)
|
||||
expect(QdrantClient).toHaveBeenLastCalledWith({
|
||||
host: "localhost",
|
||||
https: false,
|
||||
port: 6333,
|
||||
prefix: "/api", // Trailing slash should be removed
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
},
|
||||
})
|
||||
expect((vectorStoreWithTrailingSlash as any).qdrantUrl).toBe("http://localhost:6333/api/")
|
||||
})
|
||||
|
||||
it("should normalize URL pathname by removing multiple trailing slashes for prefix", () => {
|
||||
const vectorStoreWithMultipleTrailingSlashes = new QdrantVectorStore(
|
||||
mockWorkspacePath,
|
||||
"http://localhost:6333/api///",
|
||||
mockVectorSize,
|
||||
)
|
||||
expect(QdrantClient).toHaveBeenLastCalledWith({
|
||||
host: "localhost",
|
||||
https: false,
|
||||
port: 6333,
|
||||
prefix: "/api", // All trailing slashes should be removed
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
},
|
||||
})
|
||||
expect((vectorStoreWithMultipleTrailingSlashes as any).qdrantUrl).toBe("http://localhost:6333/api///")
|
||||
})
|
||||
|
||||
it("should handle multiple path segments correctly for prefix", () => {
|
||||
const vectorStoreWithMultiSegment = new QdrantVectorStore(
|
||||
mockWorkspacePath,
|
||||
"http://localhost:6333/api/v1/qdrant",
|
||||
mockVectorSize,
|
||||
)
|
||||
expect(QdrantClient).toHaveBeenLastCalledWith({
|
||||
host: "localhost",
|
||||
https: false,
|
||||
port: 6333,
|
||||
prefix: "/api/v1/qdrant",
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
},
|
||||
})
|
||||
expect((vectorStoreWithMultiSegment as any).qdrantUrl).toBe("http://localhost:6333/api/v1/qdrant")
|
||||
})
|
||||
|
||||
it("should handle complex URL with multiple segments, multiple trailing slashes, query params, and fragment", () => {
|
||||
const complexUrl = "https://example.com/ollama/api/v1///?key=value#pos"
|
||||
const vectorStoreComplex = new QdrantVectorStore(mockWorkspacePath, complexUrl, mockVectorSize)
|
||||
expect(QdrantClient).toHaveBeenLastCalledWith({
|
||||
host: "example.com",
|
||||
https: true,
|
||||
port: 443,
|
||||
prefix: "/ollama/api/v1", // Trailing slash removed, query/fragment ignored
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
},
|
||||
})
|
||||
expect((vectorStoreComplex as any).qdrantUrl).toBe(complexUrl)
|
||||
})
|
||||
|
||||
it("should ignore query parameters and fragments when determining prefix", () => {
|
||||
const vectorStoreWithQueryParams = new QdrantVectorStore(
|
||||
mockWorkspacePath,
|
||||
"http://localhost:6333/api/path?key=value#fragment",
|
||||
mockVectorSize,
|
||||
)
|
||||
expect(QdrantClient).toHaveBeenLastCalledWith({
|
||||
host: "localhost",
|
||||
https: false,
|
||||
port: 6333,
|
||||
prefix: "/api/path", // Query params and fragment should be ignored
|
||||
apiKey: undefined,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
},
|
||||
})
|
||||
expect((vectorStoreWithQueryParams as any).qdrantUrl).toBe(
|
||||
"http://localhost:6333/api/path?key=value#fragment",
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe("initialize", () => {
|
||||
it("should create a new collection if none exists and return true", async () => {
|
||||
// Mock getCollection to throw a 404-like error
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ export class QdrantVectorStore implements IVectorStore {
|
|||
host: urlObj.hostname,
|
||||
https: useHttps,
|
||||
port: port,
|
||||
prefix: urlObj.pathname === "/" ? undefined : urlObj.pathname.replace(/\/+$/, ""),
|
||||
apiKey,
|
||||
headers: {
|
||||
"User-Agent": "Roo-Code",
|
||||
|
|
@ -64,6 +65,7 @@ export class QdrantVectorStore implements IVectorStore {
|
|||
})
|
||||
} catch (urlError) {
|
||||
// If URL parsing fails, fall back to URL-based config
|
||||
// Note: This fallback won't correctly handle prefixes, but it's a last resort for malformed URLs.
|
||||
this.client = new QdrantClient({
|
||||
url: parsedUrl,
|
||||
apiKey,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue