Browse Source

Fix Ollama API URL normalization by removing trailing slashes (#6079)

Co-authored-by: Nahim El Atmani <[email protected]>
Nahim EL ATMANI 7 months ago
parent
commit
b1406342a8

+ 84 - 0
src/services/code-index/embedders/__tests__/ollama.spec.ts

@@ -80,6 +80,90 @@ describe("CodeIndexOllamaEmbedder", () => {
 			const embedderWithDefaults = new CodeIndexOllamaEmbedder({})
 			expect(embedderWithDefaults.embedderInfo.name).toBe("ollama")
 		})
+
+		it("should normalize URLs with trailing slashes", async () => {
+			// Create embedder with URL that has a trailing slash
+			const embedderWithTrailingSlash = new CodeIndexOllamaEmbedder({
+				ollamaBaseUrl: "http://localhost:11434/",
+				ollamaModelId: "nomic-embed-text",
+			})
+
+			// Mock successful /api/tags call to test the normalized URL
+			mockFetch.mockImplementationOnce(() =>
+				Promise.resolve({
+					ok: true,
+					status: 200,
+					json: () => Promise.resolve({ models: [{ name: "nomic-embed-text" }] }),
+				} as Response),
+			)
+
+			// Call a method that uses the baseUrl
+			await embedderWithTrailingSlash.validateConfiguration()
+
+			// Verify the URL used in the fetch call doesn't have a trailing slash
+			expect(mockFetch).toHaveBeenCalledWith(
+				"http://localhost:11434/api/tags",
+				expect.objectContaining({
+					method: "GET",
+				}),
+			)
+		})
+
+		it("should not modify URLs without trailing slashes", async () => {
+			// Create embedder with URL that doesn't have a trailing slash
+			const embedderWithoutTrailingSlash = new CodeIndexOllamaEmbedder({
+				ollamaBaseUrl: "http://localhost:11434",
+				ollamaModelId: "nomic-embed-text",
+			})
+
+			// Mock successful /api/tags call
+			mockFetch.mockImplementationOnce(() =>
+				Promise.resolve({
+					ok: true,
+					status: 200,
+					json: () => Promise.resolve({ models: [{ name: "nomic-embed-text" }] }),
+				} as Response),
+			)
+
+			// Call a method that uses the baseUrl
+			await embedderWithoutTrailingSlash.validateConfiguration()
+
+			// Verify the URL used in the fetch call is correct
+			expect(mockFetch).toHaveBeenCalledWith(
+				"http://localhost:11434/api/tags",
+				expect.objectContaining({
+					method: "GET",
+				}),
+			)
+		})
+
+		it("should handle multiple trailing slashes", async () => {
+			// Create embedder with URL that has multiple trailing slashes
+			const embedderWithMultipleTrailingSlashes = new CodeIndexOllamaEmbedder({
+				ollamaBaseUrl: "http://localhost:11434///",
+				ollamaModelId: "nomic-embed-text",
+			})
+
+			// Mock successful /api/tags call
+			mockFetch.mockImplementationOnce(() =>
+				Promise.resolve({
+					ok: true,
+					status: 200,
+					json: () => Promise.resolve({ models: [{ name: "nomic-embed-text" }] }),
+				} as Response),
+			)
+
+			// Call a method that uses the baseUrl
+			await embedderWithMultipleTrailingSlashes.validateConfiguration()
+
+			// Verify the URL used in the fetch call doesn't have trailing slashes
+			expect(mockFetch).toHaveBeenCalledWith(
+				"http://localhost:11434/api/tags",
+				expect.objectContaining({
+					method: "GET",
+				}),
+			)
+		})
 	})
 
 	describe("validateConfiguration", () => {

+ 6 - 1
src/services/code-index/embedders/ollama.ts

@@ -20,7 +20,12 @@ export class CodeIndexOllamaEmbedder implements IEmbedder {
 
 	constructor(options: ApiHandlerOptions) {
 		// Ensure ollamaBaseUrl and ollamaModelId exist on ApiHandlerOptions or add defaults
-		this.baseUrl = options.ollamaBaseUrl || "http://localhost:11434"
+		let baseUrl = options.ollamaBaseUrl || "http://localhost:11434"
+
+		// Normalize the baseUrl by removing all trailing slashes
+		baseUrl = baseUrl.replace(/\/+$/, "")
+
+		this.baseUrl = baseUrl
 		this.defaultModelId = options.ollamaModelId || "nomic-embed-text:latest"
 	}