Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions packages/types/src/codebase-index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export const codebaseIndexConfigSchema = z.object({
codebaseIndexBedrockProfile: z.string().optional(),
// OpenRouter specific fields
codebaseIndexOpenRouterSpecificProvider: z.string().optional(),
// Ollama specific timeout fields
codebaseIndexOllamaEmbeddingTimeoutMs: z.number().int().optional(),
codebaseIndexOllamaValidationTimeoutMs: z.number().int().optional(),
})

export type CodebaseIndexConfig = z.infer<typeof codebaseIndexConfigSchema>
Expand Down
2 changes: 2 additions & 0 deletions packages/types/src/provider-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,8 @@ const ollamaSchema = baseProviderSettingsSchema.extend({
ollamaModelId: z.string().optional(),
ollamaBaseUrl: z.string().optional(),
ollamaApiKey: z.string().optional(),
ollamaEmbeddingTimeoutMs: z.number().int().optional(),
ollamaValidationTimeoutMs: z.number().int().optional(),
ollamaNumCtx: z.number().int().min(128).optional(),
})

Expand Down
6 changes: 6 additions & 0 deletions src/core/webview/ClineProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2074,6 +2074,8 @@ export class ClineProvider
codebaseIndexEmbedderBaseUrl: codebaseIndexConfig?.codebaseIndexEmbedderBaseUrl ?? "",
codebaseIndexEmbedderModelId: codebaseIndexConfig?.codebaseIndexEmbedderModelId ?? "",
codebaseIndexEmbedderModelDimension: codebaseIndexConfig?.codebaseIndexEmbedderModelDimension ?? 1536,
codebaseIndexOllamaEmbeddingTimeoutMs: codebaseIndexConfig?.codebaseIndexOllamaEmbeddingTimeoutMs,
codebaseIndexOllamaValidationTimeoutMs: codebaseIndexConfig?.codebaseIndexOllamaValidationTimeoutMs,
codebaseIndexOpenAiCompatibleBaseUrl: codebaseIndexConfig?.codebaseIndexOpenAiCompatibleBaseUrl,
codebaseIndexSearchMaxResults: codebaseIndexConfig?.codebaseIndexSearchMaxResults,
codebaseIndexSearchMinScore: codebaseIndexConfig?.codebaseIndexSearchMinScore,
Expand Down Expand Up @@ -2305,6 +2307,10 @@ export class ClineProvider
codebaseIndexEmbedderModelId: stateValues.codebaseIndexConfig?.codebaseIndexEmbedderModelId ?? "",
codebaseIndexEmbedderModelDimension:
stateValues.codebaseIndexConfig?.codebaseIndexEmbedderModelDimension,
codebaseIndexOllamaEmbeddingTimeoutMs:
stateValues.codebaseIndexConfig?.codebaseIndexOllamaEmbeddingTimeoutMs,
codebaseIndexOllamaValidationTimeoutMs:
stateValues.codebaseIndexConfig?.codebaseIndexOllamaValidationTimeoutMs,
codebaseIndexOpenAiCompatibleBaseUrl:
stateValues.codebaseIndexConfig?.codebaseIndexOpenAiCompatibleBaseUrl,
codebaseIndexSearchMaxResults: stateValues.codebaseIndexConfig?.codebaseIndexSearchMaxResults,
Expand Down
2 changes: 2 additions & 0 deletions src/core/webview/webviewMessageHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2363,6 +2363,8 @@ export const webviewMessageHandler = async (
codebaseIndexEmbedderBaseUrl: settings.codebaseIndexEmbedderBaseUrl,
codebaseIndexEmbedderModelId: settings.codebaseIndexEmbedderModelId,
codebaseIndexEmbedderModelDimension: settings.codebaseIndexEmbedderModelDimension, // Generic dimension
codebaseIndexOllamaEmbeddingTimeoutMs: settings.codebaseIndexOllamaEmbeddingTimeoutMs,
codebaseIndexOllamaValidationTimeoutMs: settings.codebaseIndexOllamaValidationTimeoutMs,
codebaseIndexOpenAiCompatibleBaseUrl: settings.codebaseIndexOpenAiCompatibleBaseUrl,
codebaseIndexBedrockRegion: settings.codebaseIndexBedrockRegion,
codebaseIndexBedrockProfile: settings.codebaseIndexBedrockProfile,
Expand Down
42 changes: 35 additions & 7 deletions src/services/code-index/__tests__/config-manager.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ describe("CodeIndexConfigManager", () => {
embedderProvider: "openai",
modelId: undefined,
openAiOptions: { openAiNativeApiKey: "" },
ollamaOptions: { ollamaBaseUrl: "" },
ollamaOptions: {
ollamaBaseUrl: "",
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
bedrockOptions: { region: "us-east-1", profile: undefined },
qdrantUrl: "http://localhost:6333",
qdrantApiKey: "",
Expand Down Expand Up @@ -135,7 +139,11 @@ describe("CodeIndexConfigManager", () => {
embedderProvider: "openai",
modelId: "text-embedding-3-large",
openAiOptions: { openAiNativeApiKey: "test-openai-key" },
ollamaOptions: { ollamaBaseUrl: "" },
ollamaOptions: {
ollamaBaseUrl: "",
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
qdrantUrl: "http://qdrant.local",
qdrantApiKey: "test-qdrant-key",
searchMinScore: 0.4,
Expand Down Expand Up @@ -168,7 +176,11 @@ describe("CodeIndexConfigManager", () => {
embedderProvider: "openai-compatible",
modelId: "text-embedding-3-large",
openAiOptions: { openAiNativeApiKey: "" },
ollamaOptions: { ollamaBaseUrl: "" },
ollamaOptions: {
ollamaBaseUrl: "",
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
openAiCompatibleOptions: {
baseUrl: "https://api.example.com/v1",
apiKey: "test-openai-compatible-key",
Expand Down Expand Up @@ -206,7 +218,11 @@ describe("CodeIndexConfigManager", () => {
modelId: "custom-model",
modelDimension: 1024,
openAiOptions: { openAiNativeApiKey: "" },
ollamaOptions: { ollamaBaseUrl: "" },
ollamaOptions: {
ollamaBaseUrl: "",
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
openAiCompatibleOptions: {
baseUrl: "https://api.example.com/v1",
apiKey: "test-openai-compatible-key",
Expand Down Expand Up @@ -243,7 +259,11 @@ describe("CodeIndexConfigManager", () => {
embedderProvider: "openai-compatible",
modelId: "custom-model",
openAiOptions: { openAiNativeApiKey: "" },
ollamaOptions: { ollamaBaseUrl: "" },
ollamaOptions: {
ollamaBaseUrl: "",
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
openAiCompatibleOptions: {
baseUrl: "https://api.example.com/v1",
apiKey: "test-openai-compatible-key",
Expand Down Expand Up @@ -282,7 +302,11 @@ describe("CodeIndexConfigManager", () => {
modelId: "custom-model",
modelDimension: undefined, // Invalid dimension is converted to undefined
openAiOptions: { openAiNativeApiKey: "" },
ollamaOptions: { ollamaBaseUrl: "" },
ollamaOptions: {
ollamaBaseUrl: "",
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
openAiCompatibleOptions: {
baseUrl: "https://api.example.com/v1",
apiKey: "test-openai-compatible-key",
Expand Down Expand Up @@ -1292,7 +1316,11 @@ describe("CodeIndexConfigManager", () => {
embedderProvider: "openai",
modelId: "text-embedding-3-large",
openAiOptions: { openAiNativeApiKey: "test-openai-key" },
ollamaOptions: { ollamaBaseUrl: undefined },
ollamaOptions: {
ollamaBaseUrl: undefined,
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
geminiOptions: undefined,
openAiCompatibleOptions: undefined,
qdrantUrl: "http://qdrant.local",
Expand Down
8 changes: 8 additions & 0 deletions src/services/code-index/__tests__/service-factory.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ describe("CodeIndexServiceFactory", () => {
modelId: testModelId,
ollamaOptions: {
ollamaBaseUrl: "http://localhost:11434",
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
}
mockConfigManager.getConfig.mockReturnValue(testConfig as any)
Expand Down Expand Up @@ -129,6 +131,8 @@ describe("CodeIndexServiceFactory", () => {
modelId: undefined,
ollamaOptions: {
ollamaBaseUrl: "http://localhost:11434",
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
}
mockConfigManager.getConfig.mockReturnValue(testConfig as any)
Expand Down Expand Up @@ -165,6 +169,8 @@ describe("CodeIndexServiceFactory", () => {
modelId: "nomic-embed-text:latest",
ollamaOptions: {
ollamaBaseUrl: undefined,
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
}
mockConfigManager.getConfig.mockReturnValue(testConfig as any)
Expand Down Expand Up @@ -726,6 +732,8 @@ describe("CodeIndexServiceFactory", () => {
modelId: "nomic-embed-text",
ollamaOptions: {
ollamaBaseUrl: "http://localhost:11434",
ollamaEmbeddingTimeoutMs: undefined,
ollamaValidationTimeoutMs: undefined,
},
}
mockConfigManager.getConfig.mockReturnValue(testConfig as any)
Expand Down
16 changes: 16 additions & 0 deletions src/services/code-index/config-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ export class CodeIndexConfigManager {
codebaseIndexSearchMaxResults: undefined,
codebaseIndexBedrockRegion: "us-east-1",
codebaseIndexBedrockProfile: "",
codebaseIndexOllamaEmbeddingTimeoutMs: undefined,
codebaseIndexOllamaValidationTimeoutMs: undefined,
}

const {
Expand Down Expand Up @@ -128,6 +130,8 @@ export class CodeIndexConfigManager {

this.ollamaOptions = {
ollamaBaseUrl: codebaseIndexEmbedderBaseUrl,
ollamaEmbeddingTimeoutMs: codebaseIndexConfig.codebaseIndexOllamaEmbeddingTimeoutMs,
ollamaValidationTimeoutMs: codebaseIndexConfig.codebaseIndexOllamaValidationTimeoutMs,
}

this.openAiCompatibleOptions =
Expand Down Expand Up @@ -183,6 +187,8 @@ export class CodeIndexConfigManager {
modelDimension: this.modelDimension,
openAiKey: this.openAiOptions?.openAiNativeApiKey ?? "",
ollamaBaseUrl: this.ollamaOptions?.ollamaBaseUrl ?? "",
ollamaEmbeddingTimeoutMs: this.ollamaOptions?.ollamaEmbeddingTimeoutMs,
ollamaValidationTimeoutMs: this.ollamaOptions?.ollamaValidationTimeoutMs,
openAiCompatibleBaseUrl: this.openAiCompatibleOptions?.baseUrl ?? "",
openAiCompatibleApiKey: this.openAiCompatibleOptions?.apiKey ?? "",
geminiApiKey: this.geminiOptions?.apiKey ?? "",
Expand Down Expand Up @@ -301,6 +307,8 @@ export class CodeIndexConfigManager {
const prevProvider = prev?.embedderProvider ?? "openai"
const prevOpenAiKey = prev?.openAiKey ?? ""
const prevOllamaBaseUrl = prev?.ollamaBaseUrl ?? ""
const prevOllamaEmbeddingTimeoutMs = prev?.ollamaEmbeddingTimeoutMs
const prevOllamaValidationTimeoutMs = prev?.ollamaValidationTimeoutMs
const prevOpenAiCompatibleBaseUrl = prev?.openAiCompatibleBaseUrl ?? ""
const prevOpenAiCompatibleApiKey = prev?.openAiCompatibleApiKey ?? ""
const prevModelDimension = prev?.modelDimension
Expand Down Expand Up @@ -343,6 +351,8 @@ export class CodeIndexConfigManager {
// Authentication changes (API keys)
const currentOpenAiKey = this.openAiOptions?.openAiNativeApiKey ?? ""
const currentOllamaBaseUrl = this.ollamaOptions?.ollamaBaseUrl ?? ""
const currentOllamaEmbeddingTimeoutMs = this.ollamaOptions?.ollamaEmbeddingTimeoutMs
const currentOllamaValidationTimeoutMs = this.ollamaOptions?.ollamaValidationTimeoutMs
const currentOpenAiCompatibleBaseUrl = this.openAiCompatibleOptions?.baseUrl ?? ""
const currentOpenAiCompatibleApiKey = this.openAiCompatibleOptions?.apiKey ?? ""
const currentModelDimension = this.modelDimension
Expand All @@ -363,6 +373,12 @@ export class CodeIndexConfigManager {
if (prevOllamaBaseUrl !== currentOllamaBaseUrl) {
return true
}
if (
prevOllamaEmbeddingTimeoutMs !== currentOllamaEmbeddingTimeoutMs ||
prevOllamaValidationTimeoutMs !== currentOllamaValidationTimeoutMs
) {
return true
}

if (
prevOpenAiCompatibleBaseUrl !== currentOpenAiCompatibleBaseUrl ||
Expand Down
46 changes: 46 additions & 0 deletions src/services/code-index/embedders/__tests__/ollama.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,52 @@ describe("CodeIndexOllamaEmbedder", () => {
})
})

describe("timeout configuration", () => {
it("should use custom embedding timeout when provided", () => {
const embedderWithCustomTimeout = new CodeIndexOllamaEmbedder({
ollamaBaseUrl: "http://localhost:11434",
ollamaModelId: "nomic-embed-text",
ollamaEmbeddingTimeoutMs: 120000, // 2 minutes
})

// The timeout should be set to the custom value
expect(embedderWithCustomTimeout).toBeDefined()
})

it("should use custom validation timeout when provided", () => {
const embedderWithCustomTimeout = new CodeIndexOllamaEmbedder({
ollamaBaseUrl: "http://localhost:11434",
ollamaModelId: "nomic-embed-text",
ollamaValidationTimeoutMs: 60000, // 1 minute
})

// The timeout should be set to the custom value
expect(embedderWithCustomTimeout).toBeDefined()
})

it("should use default timeouts when not provided", () => {
const embedderWithDefaults = new CodeIndexOllamaEmbedder({
ollamaBaseUrl: "http://localhost:11434",
ollamaModelId: "nomic-embed-text",
})

// Should use default timeouts
expect(embedderWithDefaults).toBeDefined()
})

it("should handle -1 timeout to disable timeout", () => {
const embedderWithNoTimeout = new CodeIndexOllamaEmbedder({
ollamaBaseUrl: "http://localhost:11434",
ollamaModelId: "nomic-embed-text",
ollamaEmbeddingTimeoutMs: -1,
ollamaValidationTimeoutMs: -1,
})

// Should handle -1 as no timeout
expect(embedderWithNoTimeout).toBeDefined()
})
})

describe("validateConfiguration", () => {
it("should validate successfully when service is available and model exists", async () => {
// Mock successful /api/tags call
Expand Down
Loading
Loading