From 58804a1f7128da72603368d94e4d5385140dd2cd Mon Sep 17 00:00:00 2001 From: kiwina Date: Tue, 27 May 2025 00:12:32 +0800 Subject: [PATCH] Add LM Studio configuration handling to CodeIndexConfigManager tests --- .../__tests__/config-manager.spec.ts | 1 + .../__tests__/service-factory.spec.ts | 99 +++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/src/services/code-index/__tests__/config-manager.spec.ts b/src/services/code-index/__tests__/config-manager.spec.ts index 641abfa306..77c67c606d 100644 --- a/src/services/code-index/__tests__/config-manager.spec.ts +++ b/src/services/code-index/__tests__/config-manager.spec.ts @@ -50,6 +50,7 @@ describe("CodeIndexConfigManager", () => { modelId: undefined, openAiOptions: { openAiNativeApiKey: "" }, ollamaOptions: { ollamaBaseUrl: "" }, + lmStudioOptions: { lmStudioBaseUrl: "" }, qdrantUrl: "http://localhost:6333", qdrantApiKey: "", searchMinScore: 0.4, diff --git a/src/services/code-index/__tests__/service-factory.spec.ts b/src/services/code-index/__tests__/service-factory.spec.ts index 65932225eb..2f559e7800 100644 --- a/src/services/code-index/__tests__/service-factory.spec.ts +++ b/src/services/code-index/__tests__/service-factory.spec.ts @@ -4,6 +4,7 @@ import { OpenAiEmbedder } from "../embedders/openai" import { CodeIndexOllamaEmbedder } from "../embedders/ollama" import { OpenAICompatibleEmbedder } from "../embedders/openai-compatible" import { GeminiEmbedder } from "../embedders/gemini" +import { CodeIndexLmStudioEmbedder } from "../embedders/lmstudio" import { QdrantVectorStore } from "../vector-store/qdrant-client" // Mock the embedders and vector store @@ -11,6 +12,7 @@ vitest.mock("../embedders/openai") vitest.mock("../embedders/ollama") vitest.mock("../embedders/openai-compatible") vitest.mock("../embedders/gemini") +vitest.mock("../embedders/lmstudio") vitest.mock("../vector-store/qdrant-client") // Mock the embedding models module @@ -23,6 +25,7 @@ const MockedOpenAiEmbedder = OpenAiEmbedder as MockedClass const MockedOpenAICompatibleEmbedder = OpenAICompatibleEmbedder as MockedClass const MockedGeminiEmbedder = GeminiEmbedder as MockedClass +const MockedCodeIndexLmStudioEmbedder = CodeIndexLmStudioEmbedder as MockedClass const MockedQdrantVectorStore = QdrantVectorStore as MockedClass // Import the mocked functions @@ -299,6 +302,77 @@ describe("CodeIndexServiceFactory", () => { expect(() => factory.createEmbedder()).toThrow("serviceFactory.geminiConfigMissing") }) + it("should pass model ID to LM Studio embedder when using LM Studio provider", () => { + // Arrange + const testModelId = "nomic-embed-text-v1.5" + const testConfig = { + embedderProvider: "lmstudio", + modelId: testModelId, + lmStudioOptions: { + lmStudioBaseUrl: "http://localhost:1234", + }, + } + mockConfigManager.getConfig.mockReturnValue(testConfig as any) + + // Act + factory.createEmbedder() + + // Assert + expect(MockedCodeIndexLmStudioEmbedder).toHaveBeenCalledWith({ + lmStudioBaseUrl: "http://localhost:1234", + lmStudioModelId: testModelId, + }) + }) + + it("should handle undefined model ID for LM Studio embedder", () => { + // Arrange + const testConfig = { + embedderProvider: "lmstudio", + modelId: undefined, + lmStudioOptions: { + lmStudioBaseUrl: "http://localhost:1234", + }, + } + mockConfigManager.getConfig.mockReturnValue(testConfig as any) + + // Act + factory.createEmbedder() + + // Assert + expect(MockedCodeIndexLmStudioEmbedder).toHaveBeenCalledWith({ + lmStudioBaseUrl: "http://localhost:1234", + lmStudioModelId: undefined, + }) + }) + + it("should throw error when LM Studio base URL is missing", () => { + // Arrange + const testConfig = { + embedderProvider: "lmstudio", + modelId: "nomic-embed-text-v1.5", + lmStudioOptions: { + lmStudioBaseUrl: undefined, + }, + } + mockConfigManager.getConfig.mockReturnValue(testConfig as any) + + // Act & Assert + expect(() => factory.createEmbedder()).toThrow("LM Studio configuration missing for embedder creation") + }) + + it("should throw error when LM Studio options are missing", () => { + // Arrange + const testConfig = { + embedderProvider: "lmstudio", + modelId: "nomic-embed-text-v1.5", + lmStudioOptions: undefined, + } + mockConfigManager.getConfig.mockReturnValue(testConfig as any) + + // Act & Assert + expect(() => factory.createEmbedder()).toThrow("LM Studio configuration missing for embedder creation") + }) + it("should throw error for invalid embedder provider", () => { // Arrange const testConfig = { @@ -522,6 +596,31 @@ describe("CodeIndexServiceFactory", () => { ) }) + it("should use config.modelId for LM Studio provider", () => { + // Arrange + const testModelId = "nomic-embed-text-v1.5" + const testConfig = { + embedderProvider: "lmstudio", + modelId: testModelId, + qdrantUrl: "http://localhost:6333", + qdrantApiKey: "test-key", + } + mockConfigManager.getConfig.mockReturnValue(testConfig as any) + mockGetModelDimension.mockReturnValue(768) + + // Act + factory.createVectorStore() + + // Assert + expect(mockGetModelDimension).toHaveBeenCalledWith("lmstudio", testModelId) + expect(MockedQdrantVectorStore).toHaveBeenCalledWith( + "/test/workspace", + "http://localhost:6333", + 768, + "test-key", + ) + }) + it("should use default model when config.modelId is undefined", () => { // Arrange const testConfig = {