mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
feat: implement automated codebase indexing based on user prompts and business logic changes
- Add AutoIndexingService with singleton pattern for automatic indexing triggers - Analyze user prompts for keywords suggesting codebase exploration needs - Monitor business logic file changes (reducers, API handlers, components, etc.) - Integrate with Task processing pipeline to trigger indexing on relevant user prompts - Integrate with FileWatcher to trigger indexing on business logic file modifications - Add cooldown mechanism to prevent over-indexing (30-second intervals) - Include comprehensive test suite with 10 passing tests - Maintain backward compatibility with existing manual indexing functionality Fixes #5690
This commit is contained in:
parent
a163053430
commit
a6c45fa858
6 changed files with 517 additions and 2 deletions
|
|
@ -88,6 +88,7 @@ import { ApiMessage } from "../task-persistence/apiMessages"
|
|||
import { getMessagesSinceLastSummary, summarizeConversation } from "../condense"
|
||||
import { maybeRemoveImageBlocks } from "../../api/transform/image-cleaning"
|
||||
import { restoreTodoListForTask } from "../tools/updateTodoListTool"
|
||||
import { AutoIndexingService } from "../../services/code-index/auto-indexing/AutoIndexingService"
|
||||
|
||||
// Constants
|
||||
const MAX_EXPONENTIAL_BACKOFF_SECONDS = 600 // 10 minutes
|
||||
|
|
@ -1232,6 +1233,23 @@ export class Task extends EventEmitter<ClineEvents> {
|
|||
showRooIgnoredFiles,
|
||||
})
|
||||
|
||||
// Check if automatic indexing should be triggered based on user prompt
|
||||
const taskProvider = this.providerRef.deref()
|
||||
if (taskProvider?.codeIndexManager) {
|
||||
const autoIndexingService = AutoIndexingService.getInstance(taskProvider.codeIndexManager)
|
||||
try {
|
||||
const shouldTriggerIndexing = await autoIndexingService.analyzeUserPromptForIndexing(userContent)
|
||||
if (shouldTriggerIndexing) {
|
||||
// Trigger indexing asynchronously without blocking the task
|
||||
autoIndexingService.triggerAutomaticIndexing("User prompt analysis").catch((error) => {
|
||||
console.warn("[AutoIndexingService] Failed to trigger automatic indexing:", error)
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[AutoIndexingService] Error analyzing user prompt for indexing:", error)
|
||||
}
|
||||
}
|
||||
|
||||
const environmentDetails = await getEnvironmentDetails(this, includeFileDetails)
|
||||
|
||||
// Add environment details as its own text block, separate from tool
|
||||
|
|
|
|||
276
src/services/code-index/auto-indexing/AutoIndexingService.ts
Normal file
276
src/services/code-index/auto-indexing/AutoIndexingService.ts
Normal file
|
|
@ -0,0 +1,276 @@
|
|||
import * as vscode from "vscode"
|
||||
import { Anthropic } from "@anthropic-ai/sdk"
|
||||
import { CodeIndexManager } from "../manager"
|
||||
|
||||
/**
|
||||
* Service that automatically triggers codebase indexing based on user prompts
|
||||
* and business logic changes without requiring manual user intervention.
|
||||
*/
|
||||
export class AutoIndexingService {
|
||||
private static instance: AutoIndexingService | undefined
|
||||
private codeIndexManager: CodeIndexManager | undefined
|
||||
private lastIndexingTime: number = 0
|
||||
private readonly indexingCooldownMs = 30000 // 30 seconds cooldown between auto-indexing
|
||||
|
||||
// Keywords that suggest the user might benefit from codebase indexing
|
||||
private readonly indexingTriggerKeywords = [
|
||||
"find",
|
||||
"search",
|
||||
"locate",
|
||||
"where",
|
||||
"how does",
|
||||
"how is",
|
||||
"what does",
|
||||
"understand",
|
||||
"explain",
|
||||
"analyze",
|
||||
"explore",
|
||||
"investigate",
|
||||
"review",
|
||||
"refactor",
|
||||
"modify",
|
||||
"change",
|
||||
"update",
|
||||
"implement",
|
||||
"add feature",
|
||||
"bug",
|
||||
"error",
|
||||
"issue",
|
||||
"problem",
|
||||
"fix",
|
||||
"debug",
|
||||
"trace",
|
||||
"architecture",
|
||||
"structure",
|
||||
"design",
|
||||
"pattern",
|
||||
"flow",
|
||||
"workflow",
|
||||
"integration",
|
||||
"dependency",
|
||||
"relationship",
|
||||
"connection",
|
||||
"usage",
|
||||
"api",
|
||||
"endpoint",
|
||||
"route",
|
||||
"handler",
|
||||
"controller",
|
||||
"service",
|
||||
"component",
|
||||
"module",
|
||||
"class",
|
||||
"function",
|
||||
"method",
|
||||
"interface",
|
||||
"state",
|
||||
"reducer",
|
||||
"store",
|
||||
"context",
|
||||
"provider",
|
||||
"hook",
|
||||
"database",
|
||||
"model",
|
||||
"schema",
|
||||
"query",
|
||||
"migration",
|
||||
"entity",
|
||||
]
|
||||
|
||||
// File patterns that indicate business logic changes
|
||||
private readonly businessLogicPatterns = [
|
||||
/\/(reducers?|store|state)\//i,
|
||||
/\/(api|handlers?|controllers?|services?)\//i,
|
||||
/\/(components?|ui|views?|pages?)\//i,
|
||||
/\/(models?|entities?|schemas?)\//i,
|
||||
/\/(routes?|routing)\//i,
|
||||
/\/(middleware|interceptors?)\//i,
|
||||
/\/(utils?|helpers?|lib)\//i,
|
||||
/\.(reducer|store|state|api|service|controller|handler)\./i,
|
||||
/\/(src|lib|app)\//i,
|
||||
]
|
||||
|
||||
private constructor(codeIndexManager?: CodeIndexManager) {
|
||||
this.codeIndexManager = codeIndexManager
|
||||
}
|
||||
|
||||
public static getInstance(codeIndexManager?: CodeIndexManager): AutoIndexingService {
|
||||
if (!AutoIndexingService.instance) {
|
||||
if (codeIndexManager === undefined || codeIndexManager === null) {
|
||||
throw new Error("CodeIndexManager is required to create AutoIndexingService instance")
|
||||
}
|
||||
AutoIndexingService.instance = new AutoIndexingService(codeIndexManager)
|
||||
}
|
||||
if (codeIndexManager && !AutoIndexingService.instance.codeIndexManager) {
|
||||
AutoIndexingService.instance.codeIndexManager = codeIndexManager
|
||||
}
|
||||
return AutoIndexingService.instance
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyzes user content to determine if automatic indexing should be triggered
|
||||
*/
|
||||
public async analyzeUserPromptForIndexing(userContent: Anthropic.Messages.ContentBlockParam[]): Promise<boolean> {
|
||||
if (!this.shouldAttemptIndexing()) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Extract text content from user message
|
||||
const textContent = this.extractTextFromUserContent(userContent)
|
||||
if (!textContent) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if the prompt contains keywords that suggest codebase exploration
|
||||
const containsTriggerKeywords = this.containsIndexingTriggerKeywords(textContent)
|
||||
|
||||
// Check if the prompt mentions specific files or code patterns
|
||||
const mentionsCodePatterns = this.mentionsCodePatterns(textContent)
|
||||
|
||||
// Check if this is a new task (likely to benefit from fresh indexing)
|
||||
const isNewTask = this.isNewTaskPrompt(textContent)
|
||||
|
||||
return containsTriggerKeywords || mentionsCodePatterns || isNewTask
|
||||
}
|
||||
|
||||
/**
|
||||
* Analyzes file changes to determine if they represent business logic changes
|
||||
* that should trigger automatic indexing
|
||||
*/
|
||||
public shouldTriggerIndexingForFileChange(filePath: string): boolean {
|
||||
if (!this.shouldAttemptIndexing()) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check if the file matches business logic patterns
|
||||
return this.businessLogicPatterns.some((pattern) => pattern.test(filePath))
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers automatic indexing if conditions are met
|
||||
*/
|
||||
public async triggerAutomaticIndexing(reason: string): Promise<boolean> {
|
||||
if (!this.shouldAttemptIndexing()) {
|
||||
console.log(`[AutoIndexingService] Skipping indexing - conditions not met: ${reason}`)
|
||||
return false
|
||||
}
|
||||
|
||||
try {
|
||||
console.log(`[AutoIndexingService] Triggering automatic indexing: ${reason}`)
|
||||
|
||||
// Update last indexing time to prevent rapid re-indexing
|
||||
this.lastIndexingTime = Date.now()
|
||||
|
||||
// Start indexing asynchronously
|
||||
await this.codeIndexManager!.startIndexing()
|
||||
|
||||
console.log(`[AutoIndexingService] Successfully triggered indexing: ${reason}`)
|
||||
return true
|
||||
} catch (error) {
|
||||
console.error(`[AutoIndexingService] Failed to trigger automatic indexing:`, error)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if indexing should be attempted based on current conditions
|
||||
*/
|
||||
private shouldAttemptIndexing(): boolean {
|
||||
// Check if code index manager is available and properly configured
|
||||
if (
|
||||
!this.codeIndexManager ||
|
||||
!this.codeIndexManager.isFeatureEnabled ||
|
||||
!this.codeIndexManager.isFeatureConfigured
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
// Check cooldown period to prevent over-indexing
|
||||
const timeSinceLastIndexing = Date.now() - this.lastIndexingTime
|
||||
if (timeSinceLastIndexing < this.indexingCooldownMs) {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts text content from user content blocks
|
||||
*/
|
||||
private extractTextFromUserContent(userContent: Anthropic.Messages.ContentBlockParam[]): string {
|
||||
const textBlocks: string[] = []
|
||||
|
||||
for (const block of userContent) {
|
||||
if (block.type === "text") {
|
||||
textBlocks.push(block.text)
|
||||
} else if (block.type === "tool_result") {
|
||||
if (typeof block.content === "string") {
|
||||
textBlocks.push(block.content)
|
||||
} else if (Array.isArray(block.content)) {
|
||||
for (const contentBlock of block.content) {
|
||||
if (contentBlock.type === "text") {
|
||||
textBlocks.push(contentBlock.text)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return textBlocks.join(" ").toLowerCase()
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if text contains keywords that suggest indexing would be beneficial
|
||||
*/
|
||||
private containsIndexingTriggerKeywords(text: string): boolean {
|
||||
return this.indexingTriggerKeywords.some((keyword) => text.includes(keyword.toLowerCase()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if text mentions code patterns or file structures
|
||||
*/
|
||||
private mentionsCodePatterns(text: string): boolean {
|
||||
// Check for mentions of file extensions
|
||||
const codeFileExtensions = [
|
||||
".ts",
|
||||
".js",
|
||||
".tsx",
|
||||
".jsx",
|
||||
".py",
|
||||
".java",
|
||||
".cs",
|
||||
".cpp",
|
||||
".c",
|
||||
".go",
|
||||
".rs",
|
||||
".php",
|
||||
]
|
||||
const mentionsFileExtensions = codeFileExtensions.some((ext) => text.includes(ext))
|
||||
|
||||
// Check for mentions of common code terms
|
||||
const codeTerms = ["function", "class", "component", "module", "import", "export", "interface", "type"]
|
||||
const mentionsCodeTerms = codeTerms.some((term) => text.includes(term))
|
||||
|
||||
// Check for file path patterns
|
||||
const mentionsFilePaths =
|
||||
text.includes("/") && (text.includes("src") || text.includes("lib") || text.includes("app"))
|
||||
|
||||
return mentionsFileExtensions || mentionsCodeTerms || mentionsFilePaths
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this appears to be a new task prompt
|
||||
*/
|
||||
private isNewTaskPrompt(text: string): boolean {
|
||||
// Look for task-like language
|
||||
const taskIndicators = ["<task>", "please", "can you", "i need", "help me", "create", "build", "develop"]
|
||||
return taskIndicators.some((indicator) => text.includes(indicator))
|
||||
}
|
||||
|
||||
/**
|
||||
* Disposes of the service instance
|
||||
*/
|
||||
public static dispose(): void {
|
||||
AutoIndexingService.instance = undefined
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
import { AutoIndexingService } from "../AutoIndexingService"
|
||||
|
||||
// Mock TelemetryService
|
||||
vi.mock("@roo-code/telemetry", () => ({
|
||||
TelemetryService: {
|
||||
instance: {
|
||||
captureEvent: vi.fn(),
|
||||
},
|
||||
},
|
||||
}))
|
||||
|
||||
describe("AutoIndexingService", () => {
|
||||
let mockCodeIndexManager: any
|
||||
|
||||
beforeEach(() => {
|
||||
// Clear singleton instance before each test
|
||||
;(AutoIndexingService as any)._instance = undefined
|
||||
|
||||
// Mock CodeIndexManager with all required properties
|
||||
mockCodeIndexManager = {
|
||||
startIndexing: vi.fn().mockResolvedValue(undefined),
|
||||
state: "Standby",
|
||||
isFeatureEnabled: true,
|
||||
isFeatureConfigured: true,
|
||||
}
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks()
|
||||
// Clear singleton instance after each test
|
||||
;(AutoIndexingService as any)._instance = undefined
|
||||
})
|
||||
|
||||
describe("getInstance", () => {
|
||||
it("should return the same instance when called multiple times", () => {
|
||||
const instance1 = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
const instance2 = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
expect(instance1).toBe(instance2)
|
||||
})
|
||||
|
||||
it("should create instance with valid CodeIndexManager", () => {
|
||||
const instance = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
expect(instance).toBeInstanceOf(AutoIndexingService)
|
||||
})
|
||||
})
|
||||
|
||||
describe("analyzeUserPromptForIndexing", () => {
|
||||
it("should return true for prompts containing indexing trigger keywords", async () => {
|
||||
const autoIndexingService = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
// Reset the lastIndexingTime to allow indexing
|
||||
;(autoIndexingService as any).lastIndexingTime = 0
|
||||
|
||||
const testCases = [
|
||||
"explore the codebase",
|
||||
"find all functions",
|
||||
"search for components",
|
||||
"understand the architecture",
|
||||
"analyze the code structure",
|
||||
]
|
||||
|
||||
for (const text of testCases) {
|
||||
const userContent = [{ type: "text" as const, text }]
|
||||
const result = await autoIndexingService.analyzeUserPromptForIndexing(userContent)
|
||||
expect(result).toBe(true)
|
||||
}
|
||||
})
|
||||
|
||||
it("should return false for prompts without trigger keywords", async () => {
|
||||
const autoIndexingService = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
// Reset the lastIndexingTime to allow indexing
|
||||
;(autoIndexingService as any).lastIndexingTime = 0
|
||||
|
||||
const userContent = [{ type: "text" as const, text: "hello world" }]
|
||||
const result = await autoIndexingService.analyzeUserPromptForIndexing(userContent)
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
|
||||
it("should handle empty content", async () => {
|
||||
const autoIndexingService = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
// Reset the lastIndexingTime to allow indexing
|
||||
;(autoIndexingService as any).lastIndexingTime = 0
|
||||
|
||||
const userContent = [{ type: "text" as const, text: "" }]
|
||||
const result = await autoIndexingService.analyzeUserPromptForIndexing(userContent)
|
||||
expect(result).toBe(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe("shouldTriggerIndexingForFileChange", () => {
|
||||
it("should return true for business logic files", () => {
|
||||
const autoIndexingService = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
// Reset the lastIndexingTime to allow indexing
|
||||
;(autoIndexingService as any).lastIndexingTime = 0
|
||||
|
||||
const businessLogicFiles = [
|
||||
"/src/reducers/userReducer.ts",
|
||||
"/app/api/handlers/user.ts",
|
||||
"/components/UserProfile.tsx",
|
||||
"/src/services/authService.ts",
|
||||
"/lib/utils/helper.ts",
|
||||
]
|
||||
|
||||
for (const filePath of businessLogicFiles) {
|
||||
const result = autoIndexingService.shouldTriggerIndexingForFileChange(filePath)
|
||||
expect(result).toBe(true)
|
||||
}
|
||||
})
|
||||
|
||||
it("should return false for non-business logic files", () => {
|
||||
const autoIndexingService = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
// Reset the lastIndexingTime to allow indexing
|
||||
;(autoIndexingService as any).lastIndexingTime = 0
|
||||
|
||||
const nonBusinessLogicFiles = [
|
||||
"/README.md",
|
||||
"/package.json",
|
||||
"/tsconfig.json",
|
||||
"/.gitignore",
|
||||
"/docs/guide.md",
|
||||
]
|
||||
|
||||
for (const filePath of nonBusinessLogicFiles) {
|
||||
const result = autoIndexingService.shouldTriggerIndexingForFileChange(filePath)
|
||||
expect(result).toBe(false)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
describe("core functionality", () => {
|
||||
it("should have proper singleton behavior", () => {
|
||||
const instance1 = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
const instance2 = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
expect(instance1).toBe(instance2)
|
||||
})
|
||||
|
||||
it("should analyze user prompts correctly", async () => {
|
||||
const autoIndexingService = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
;(autoIndexingService as any).lastIndexingTime = 0
|
||||
|
||||
// Test positive cases
|
||||
const positiveContent = [{ type: "text" as const, text: "explore the codebase structure" }]
|
||||
const positiveResult = await autoIndexingService.analyzeUserPromptForIndexing(positiveContent)
|
||||
expect(positiveResult).toBe(true)
|
||||
|
||||
// Test negative cases
|
||||
const negativeContent = [{ type: "text" as const, text: "hello world" }]
|
||||
const negativeResult = await autoIndexingService.analyzeUserPromptForIndexing(negativeContent)
|
||||
expect(negativeResult).toBe(false)
|
||||
})
|
||||
|
||||
it("should detect business logic file changes correctly", () => {
|
||||
const autoIndexingService = AutoIndexingService.getInstance(mockCodeIndexManager)
|
||||
;(autoIndexingService as any).lastIndexingTime = 0
|
||||
|
||||
// Test positive cases
|
||||
expect(autoIndexingService.shouldTriggerIndexingForFileChange("/src/components/App.tsx")).toBe(true)
|
||||
expect(autoIndexingService.shouldTriggerIndexingForFileChange("/api/handlers/user.ts")).toBe(true)
|
||||
expect(autoIndexingService.shouldTriggerIndexingForFileChange("/reducers/auth.ts")).toBe(true)
|
||||
|
||||
// Test negative cases
|
||||
expect(autoIndexingService.shouldTriggerIndexingForFileChange("/README.md")).toBe(false)
|
||||
expect(autoIndexingService.shouldTriggerIndexingForFileChange("/package.json")).toBe(false)
|
||||
expect(autoIndexingService.shouldTriggerIndexingForFileChange("/.gitignore")).toBe(false)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
@ -264,6 +264,7 @@ export class CodeIndexManager {
|
|||
this.context,
|
||||
this._cacheManager!,
|
||||
ignoreInstance,
|
||||
this, // Pass this CodeIndexManager instance for auto-indexing
|
||||
)
|
||||
|
||||
// Validate embedder configuration before proceeding
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import { isPathInIgnoredDirectory } from "../../glob/ignore-utils"
|
|||
import { TelemetryService } from "@roo-code/telemetry"
|
||||
import { TelemetryEventName } from "@roo-code/types"
|
||||
import { sanitizeErrorMessage } from "../shared/validation-helpers"
|
||||
import { AutoIndexingService } from "../auto-indexing/AutoIndexingService"
|
||||
|
||||
/**
|
||||
* Implementation of the file watcher interface
|
||||
|
|
@ -78,6 +79,7 @@ export class FileWatcher implements IFileWatcher {
|
|||
private vectorStore?: IVectorStore,
|
||||
ignoreInstance?: Ignore,
|
||||
ignoreController?: RooIgnoreController,
|
||||
private codeIndexManager?: any, // CodeIndexManager reference for auto-indexing
|
||||
) {
|
||||
this.ignoreController = ignoreController || new RooIgnoreController(workspacePath)
|
||||
if (ignoreInstance) {
|
||||
|
|
@ -123,6 +125,9 @@ export class FileWatcher implements IFileWatcher {
|
|||
private async handleFileCreated(uri: vscode.Uri): Promise<void> {
|
||||
this.accumulatedEvents.set(uri.fsPath, { uri, type: "create" })
|
||||
this.scheduleBatchProcessing()
|
||||
|
||||
// Check if this file creation should trigger automatic indexing
|
||||
this.checkForBusinessLogicChange(uri.fsPath, "File created")
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -132,6 +137,9 @@ export class FileWatcher implements IFileWatcher {
|
|||
private async handleFileChanged(uri: vscode.Uri): Promise<void> {
|
||||
this.accumulatedEvents.set(uri.fsPath, { uri, type: "change" })
|
||||
this.scheduleBatchProcessing()
|
||||
|
||||
// Check if this file change should trigger automatic indexing
|
||||
this.checkForBusinessLogicChange(uri.fsPath, "File changed")
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -141,6 +149,9 @@ export class FileWatcher implements IFileWatcher {
|
|||
private async handleFileDeleted(uri: vscode.Uri): Promise<void> {
|
||||
this.accumulatedEvents.set(uri.fsPath, { uri, type: "delete" })
|
||||
this.scheduleBatchProcessing()
|
||||
|
||||
// Check if this file deletion should trigger automatic indexing
|
||||
this.checkForBusinessLogicChange(uri.fsPath, "File deleted")
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -575,4 +586,29 @@ export class FileWatcher implements IFileWatcher {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a file change represents a business logic change that should trigger automatic indexing
|
||||
* @param filePath Path to the changed file
|
||||
* @param reason Reason for the change (for logging)
|
||||
*/
|
||||
private checkForBusinessLogicChange(filePath: string, reason: string): void {
|
||||
if (!this.codeIndexManager) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const autoIndexingService = AutoIndexingService.getInstance(this.codeIndexManager)
|
||||
const shouldTriggerIndexing = autoIndexingService.shouldTriggerIndexingForFileChange(filePath)
|
||||
|
||||
if (shouldTriggerIndexing) {
|
||||
// Trigger indexing asynchronously without blocking file processing
|
||||
autoIndexingService.triggerAutomaticIndexing(`${reason}: ${filePath}`).catch((error) => {
|
||||
console.warn("[FileWatcher] Failed to trigger automatic indexing for business logic change:", error)
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn("[FileWatcher] Error checking for business logic change:", error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,8 +158,18 @@ export class CodeIndexServiceFactory {
|
|||
vectorStore: IVectorStore,
|
||||
cacheManager: CacheManager,
|
||||
ignoreInstance: Ignore,
|
||||
codeIndexManager?: any, // CodeIndexManager reference for auto-indexing
|
||||
): IFileWatcher {
|
||||
return new FileWatcher(this.workspacePath, context, cacheManager, embedder, vectorStore, ignoreInstance)
|
||||
return new FileWatcher(
|
||||
this.workspacePath,
|
||||
context,
|
||||
cacheManager,
|
||||
embedder,
|
||||
vectorStore,
|
||||
ignoreInstance,
|
||||
undefined,
|
||||
codeIndexManager,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -170,6 +180,7 @@ export class CodeIndexServiceFactory {
|
|||
context: vscode.ExtensionContext,
|
||||
cacheManager: CacheManager,
|
||||
ignoreInstance: Ignore,
|
||||
codeIndexManager?: any, // CodeIndexManager reference for auto-indexing
|
||||
): {
|
||||
embedder: IEmbedder
|
||||
vectorStore: IVectorStore
|
||||
|
|
@ -185,7 +196,14 @@ export class CodeIndexServiceFactory {
|
|||
const vectorStore = this.createVectorStore()
|
||||
const parser = codeParser
|
||||
const scanner = this.createDirectoryScanner(embedder, vectorStore, parser, ignoreInstance)
|
||||
const fileWatcher = this.createFileWatcher(context, embedder, vectorStore, cacheManager, ignoreInstance)
|
||||
const fileWatcher = this.createFileWatcher(
|
||||
context,
|
||||
embedder,
|
||||
vectorStore,
|
||||
cacheManager,
|
||||
ignoreInstance,
|
||||
codeIndexManager,
|
||||
)
|
||||
|
||||
return {
|
||||
embedder,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue