mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-10-07 02:58:15 +00:00
feat: add toggle to disable codebase indexing (#5623)
- Add toggle switch to CodeIndexPopover UI component - Add conditional rendering for setup/advanced settings sections - Update backend logic to respect codebaseIndexEnabled setting - Implement proper state caching for restart detection - Add comprehensive test coverage for enable/disable functionality - Add translation keys for toggle UI elements Fixes #5623
This commit is contained in:
parent
50e45a2bc6
commit
c6f32c1584
4 changed files with 672 additions and 502 deletions
|
|
@ -343,6 +343,89 @@ describe("CodeIndexConfigManager", () => {
|
|||
expect(result.requiresRestart).toBe(true)
|
||||
})
|
||||
|
||||
it("should detect restart requirement when feature is enabled", async () => {
|
||||
// Create a fresh config manager to ensure clean state
|
||||
const freshConfigManager = new CodeIndexConfigManager(mockContextProxy)
|
||||
|
||||
// Initial state - disabled
|
||||
mockContextProxy.getGlobalState.mockReturnValue({
|
||||
codebaseIndexEnabled: false,
|
||||
codebaseIndexQdrantUrl: "http://qdrant.local",
|
||||
codebaseIndexEmbedderProvider: "openai",
|
||||
codebaseIndexEmbedderModelId: "text-embedding-3-small",
|
||||
})
|
||||
setupSecretMocks({
|
||||
codeIndexOpenAiKey: "test-key",
|
||||
codeIndexQdrantApiKey: "test-key",
|
||||
})
|
||||
|
||||
await freshConfigManager.loadConfiguration()
|
||||
|
||||
// Enable the feature
|
||||
mockContextProxy.getGlobalState.mockReturnValue({
|
||||
codebaseIndexEnabled: true,
|
||||
codebaseIndexQdrantUrl: "http://qdrant.local",
|
||||
codebaseIndexEmbedderProvider: "openai",
|
||||
codebaseIndexEmbedderModelId: "text-embedding-3-small",
|
||||
})
|
||||
|
||||
const result = await freshConfigManager.loadConfiguration()
|
||||
expect(result.requiresRestart).toBe(true)
|
||||
})
|
||||
|
||||
it("should detect restart requirement when feature is disabled", async () => {
|
||||
// Create a fresh config manager to ensure clean state
|
||||
const freshConfigManager = new CodeIndexConfigManager(mockContextProxy)
|
||||
|
||||
// Initial state - enabled
|
||||
mockContextProxy.getGlobalState.mockReturnValue({
|
||||
codebaseIndexEnabled: true,
|
||||
codebaseIndexQdrantUrl: "http://qdrant.local",
|
||||
codebaseIndexEmbedderProvider: "openai",
|
||||
codebaseIndexEmbedderModelId: "text-embedding-3-small",
|
||||
})
|
||||
setupSecretMocks({
|
||||
codeIndexOpenAiKey: "test-key",
|
||||
codeIndexQdrantApiKey: "test-key",
|
||||
})
|
||||
|
||||
await freshConfigManager.loadConfiguration()
|
||||
|
||||
// Disable the feature
|
||||
mockContextProxy.getGlobalState.mockReturnValue({
|
||||
codebaseIndexEnabled: false,
|
||||
codebaseIndexQdrantUrl: "http://qdrant.local",
|
||||
codebaseIndexEmbedderProvider: "openai",
|
||||
codebaseIndexEmbedderModelId: "text-embedding-3-small",
|
||||
})
|
||||
|
||||
const result = await freshConfigManager.loadConfiguration()
|
||||
expect(result.requiresRestart).toBe(true)
|
||||
})
|
||||
|
||||
it("should not require restart when feature remains disabled", async () => {
|
||||
// Initial state - disabled
|
||||
mockContextProxy.getGlobalState.mockReturnValue({
|
||||
codebaseIndexEnabled: false,
|
||||
codebaseIndexQdrantUrl: "http://qdrant.local",
|
||||
codebaseIndexEmbedderProvider: "openai",
|
||||
codebaseIndexEmbedderModelId: "text-embedding-3-small",
|
||||
})
|
||||
|
||||
await configManager.loadConfiguration()
|
||||
|
||||
// Change other settings while keeping feature disabled
|
||||
mockContextProxy.getGlobalState.mockReturnValue({
|
||||
codebaseIndexEnabled: false,
|
||||
codebaseIndexQdrantUrl: "http://qdrant.local",
|
||||
codebaseIndexEmbedderProvider: "openai",
|
||||
codebaseIndexEmbedderModelId: "text-embedding-3-large", // Changed model
|
||||
})
|
||||
|
||||
const result = await configManager.loadConfiguration()
|
||||
expect(result.requiresRestart).toBe(false)
|
||||
})
|
||||
|
||||
describe("simplified restart detection", () => {
|
||||
it("should detect restart requirement for API key changes", async () => {
|
||||
// Initial state
|
||||
|
|
@ -1215,7 +1298,39 @@ describe("CodeIndexConfigManager", () => {
|
|||
})
|
||||
})
|
||||
|
||||
it("should return correct feature enabled state", () => {
|
||||
it("should return correct feature enabled state when enabled", () => {
|
||||
expect(configManager.isFeatureEnabled).toBe(true)
|
||||
})
|
||||
|
||||
it("should return false when codebaseIndexEnabled is false", async () => {
|
||||
mockContextProxy.getGlobalState.mockReturnValue({
|
||||
codebaseIndexEnabled: false,
|
||||
codebaseIndexQdrantUrl: "http://qdrant.local",
|
||||
codebaseIndexEmbedderProvider: "openai",
|
||||
codebaseIndexEmbedderModelId: "text-embedding-3-large",
|
||||
})
|
||||
setupSecretMocks({
|
||||
codeIndexOpenAiKey: "test-openai-key",
|
||||
codeIndexQdrantApiKey: "test-qdrant-key",
|
||||
})
|
||||
|
||||
await configManager.loadConfiguration()
|
||||
expect(configManager.isFeatureEnabled).toBe(false)
|
||||
})
|
||||
|
||||
it("should return true when codebaseIndexEnabled is undefined (default)", async () => {
|
||||
mockContextProxy.getGlobalState.mockReturnValue({
|
||||
// codebaseIndexEnabled is undefined, should default to true
|
||||
codebaseIndexQdrantUrl: "http://qdrant.local",
|
||||
codebaseIndexEmbedderProvider: "openai",
|
||||
codebaseIndexEmbedderModelId: "text-embedding-3-large",
|
||||
})
|
||||
setupSecretMocks({
|
||||
codeIndexOpenAiKey: "test-openai-key",
|
||||
codeIndexQdrantApiKey: "test-qdrant-key",
|
||||
})
|
||||
|
||||
await configManager.loadConfiguration()
|
||||
expect(configManager.isFeatureEnabled).toBe(true)
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ export class CodeIndexConfigManager {
|
|||
private qdrantApiKey?: string
|
||||
private searchMinScore?: number
|
||||
private searchMaxResults?: number
|
||||
private codebaseIndexEnabled?: boolean
|
||||
|
||||
constructor(private readonly contextProxy: ContextProxy) {
|
||||
// Initialize with current configuration to avoid false restart triggers
|
||||
|
|
@ -68,7 +69,7 @@ export class CodeIndexConfigManager {
|
|||
const geminiApiKey = this.contextProxy?.getSecret("codebaseIndexGeminiApiKey") ?? ""
|
||||
|
||||
// Update instance variables with configuration
|
||||
// Note: codebaseIndexEnabled is no longer used as the feature is always enabled
|
||||
this.codebaseIndexEnabled = codebaseIndexEnabled
|
||||
this.qdrantUrl = codebaseIndexQdrantUrl
|
||||
this.qdrantApiKey = qdrantApiKey ?? ""
|
||||
this.searchMinScore = codebaseIndexSearchMinScore
|
||||
|
|
@ -142,7 +143,7 @@ export class CodeIndexConfigManager {
|
|||
}> {
|
||||
// Capture the ACTUAL previous state before loading new configuration
|
||||
const previousConfigSnapshot: PreviousConfigSnapshot = {
|
||||
enabled: true, // Feature is always enabled
|
||||
enabled: this.isFeatureEnabled,
|
||||
configured: this.isConfigured(),
|
||||
embedderProvider: this.embedderProvider,
|
||||
modelId: this.modelId,
|
||||
|
|
@ -243,8 +244,13 @@ export class CodeIndexConfigManager {
|
|||
const prevQdrantUrl = prev?.qdrantUrl ?? ""
|
||||
const prevQdrantApiKey = prev?.qdrantApiKey ?? ""
|
||||
|
||||
// 1. Transition from unconfigured to configured
|
||||
// Since the feature is always enabled, we only check configuration status
|
||||
// 1. Check for enable/disable transitions
|
||||
const nowEnabled = this.isFeatureEnabled
|
||||
if (prevEnabled !== nowEnabled) {
|
||||
return true
|
||||
}
|
||||
|
||||
// 2. Transition from unconfigured to configured
|
||||
if (!prevConfigured && nowConfigured) {
|
||||
return true
|
||||
}
|
||||
|
|
@ -255,7 +261,6 @@ export class CodeIndexConfigManager {
|
|||
}
|
||||
|
||||
// 4. CRITICAL CHANGES - Always restart for these
|
||||
// Since feature is always enabled, we always check for critical changes
|
||||
|
||||
// Provider change
|
||||
if (prevProvider !== this.embedderProvider) {
|
||||
|
|
@ -354,7 +359,7 @@ export class CodeIndexConfigManager {
|
|||
* Gets whether the code indexing feature is enabled
|
||||
*/
|
||||
public get isFeatureEnabled(): boolean {
|
||||
return true
|
||||
return this.codebaseIndexEnabled ?? true
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -40,6 +40,8 @@
|
|||
"title": "Codebase Indexing",
|
||||
"description": "Configure codebase indexing settings to enable semantic search of your project. <0>Learn more</0>",
|
||||
"statusTitle": "Status",
|
||||
"enabledLabel": "Enable Codebase Indexing",
|
||||
"enabledDescription": "Toggle codebase indexing on or off. When disabled, the codebase_search tool will not be available.",
|
||||
"enableLabel": "Enable Codebase Indexing",
|
||||
"enableDescription": "<0>Codebase Indexing</0> is an experimental feature that creates a semantic search index of your project using AI embeddings. This enables Roo Code to better understand and navigate large codebases by finding relevant code based on meaning rather than just keywords.",
|
||||
"settingsTitle": "Indexing Settings",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue