Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
3 changes: 3 additions & 0 deletions packages/types/src/provider-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,9 @@ const ollamaSchema = baseProviderSettingsSchema.extend({
ollamaModelId: z.string().optional(),
ollamaBaseUrl: z.string().optional(),
ollamaApiKey: z.string().optional(),
ollamaEmbeddingTimeoutMs: z.number().int().optional(),
// Negative values disable the validation timeout. If set to a positive integer, it specifies the timeout in milliseconds.
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