Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
136 commits
Select commit Hold shift + click to select a range
ffd1837
feat: create code segment parser by using existing tree sitter implem…
daniel-lxs Apr 3, 2025
6a3b7a5
feat: impl scanner to get the files to index
daniel-lxs Apr 3, 2025
7f077fc
test: create tests for both parser and scanner
daniel-lxs Apr 3, 2025
195bdfb
feat: export array of supported tree sitter extensions to use in parser
daniel-lxs Apr 3, 2025
38315eb
feat: extend openAI native provider functionality to allow embeddings…
daniel-lxs Apr 3, 2025
356753f
feat: install qdrant and implement qdrant client to save and search e…
daniel-lxs Apr 3, 2025
5b94461
feat: WIP implement embeddings creation and saving into qdrant
daniel-lxs Apr 3, 2025
4a7f516
Merge branch 'RooVetGit:main' into main
daniel-lxs Apr 3, 2025
534c37e
feat: create a collection for each workspace
daniel-lxs Apr 3, 2025
5516a2b
feat: save hashed data to update segments if the file changes
daniel-lxs Apr 3, 2025
4666926
feat: keep track of hashes to update existing files
daniel-lxs Apr 3, 2025
a01c2de
feat: implement a file watcher to watch for file events and update ou…
daniel-lxs Apr 3, 2025
b338a7b
feat: add a deletion method in case a file is deleted
daniel-lxs Apr 3, 2025
9dc527e
feat: add deletion detection to the file scanner
daniel-lxs Apr 3, 2025
d3ecf49
feat: normalize path used as identifier on qdrant
daniel-lxs Apr 3, 2025
532fd78
feat: normalize the path use as identifier on the scanner and file wa…
daniel-lxs Apr 3, 2025
3939303
feat: mock error types for the file watcher test
daniel-lxs Apr 3, 2025
e764afa
tests: create a test for the file watcher
daniel-lxs Apr 3, 2025
7efe60f
refactor: remove unused code
daniel-lxs Apr 4, 2025
b05951f
feat: add process reporting to the file watcher
daniel-lxs Apr 4, 2025
99ad4dc
feat: create a high level service to manage the codebase indexing ini…
daniel-lxs Apr 4, 2025
fcb7436
feat: add error handling to manager from indexing process
daniel-lxs Apr 4, 2025
c807f4b
feat: add batching to scanner with retry logic and error handling
daniel-lxs Apr 4, 2025
674994a
Merge branch 'RooVetGit:main' into main
daniel-lxs Apr 4, 2025
341aee5
feat: add the code index message types and setting properties
daniel-lxs Apr 4, 2025
3212d5b
feat: add code index handlers
daniel-lxs Apr 4, 2025
6c441a2
types: generate types
daniel-lxs Apr 4, 2025
bdc3b6a
feat: add clear index functionality
daniel-lxs Apr 4, 2025
7821022
feat: create code index settings component
daniel-lxs Apr 4, 2025
04dec0f
feat: add code index settings component to settings view
daniel-lxs Apr 4, 2025
77c3bd0
test: add missing properties to test
daniel-lxs Apr 4, 2025
3e70714
Merge branch 'RooVetGit:main' into main
daniel-lxs Apr 4, 2025
2ed6923
fix: add missing properties
daniel-lxs Apr 4, 2025
e4b4082
refator: move section to component
daniel-lxs Apr 4, 2025
3f3d014
refactor: handle config updates
daniel-lxs Apr 5, 2025
3ff7bc1
feat: add webview message handlers
daniel-lxs Apr 5, 2025
a80f2c4
Merge branch 'RooVetGit:main' into main
daniel-lxs Apr 5, 2025
2e6f2f3
Merge branch 'RooVetGit:main' into main
daniel-lxs Apr 5, 2025
70614bb
fix: update implementation to match new cline provider
daniel-lxs Apr 5, 2025
f16fb1e
deps: add uuid to create ids for the qdrant points
daniel-lxs Apr 5, 2025
c03a220
fix: use uuid for the points
daniel-lxs Apr 6, 2025
005f665
feat: initialize codebase indexing before webview
daniel-lxs Apr 6, 2025
641911d
feat: listen to status changes for code index in the webview provider
daniel-lxs Apr 6, 2025
5bd87c8
fix: handle status changes correctly
daniel-lxs Apr 6, 2025
525e98a
feat: add methods to check if a workspace has a collection
daniel-lxs Apr 6, 2025
3977143
feat: start file watcher if a workspace already has a collection and …
daniel-lxs Apr 6, 2025
4b577bd
fix: status indicator and add a status light
daniel-lxs Apr 6, 2025
eda7db3
Merge branch 'RooVetGit:main' into main
daniel-lxs Apr 6, 2025
e7261d7
Merge branch 'RooVetGit:main' into main
daniel-lxs Apr 6, 2025
5732a1c
refactor: pass already initialized embedder and qdrant client
daniel-lxs Apr 6, 2025
c128b1a
feat: impl search tool and move initialization of embedder and qdrant…
daniel-lxs Apr 6, 2025
b41ead9
feat: create types for the qdrant results
daniel-lxs Apr 6, 2025
69e76c6
feat: define codebase search tool and translations
daniel-lxs Apr 6, 2025
7b904d0
feat: add the tool definition and handler
daniel-lxs Apr 6, 2025
48346f4
tests: fix test due to updates made to file watcher
daniel-lxs Apr 6, 2025
6a1b5dc
feat: add the components to the chat view
daniel-lxs Apr 6, 2025
e049505
refator: make the tool return json so the parsing is simpler
daniel-lxs Apr 6, 2025
be4cb0c
feat: define tool in extension message
daniel-lxs Apr 6, 2025
658efd7
feat: add tool prompt and update tool groups
daniel-lxs Apr 6, 2025
7829c46
Merge branch 'RooVetGit:main' into main
daniel-lxs Apr 7, 2025
d0c41da
feat: remove tool prompt if disabled or not configured
daniel-lxs Apr 7, 2025
6404ea8
feat: pass context to getToolDescriptionsForMode to check if code ind…
daniel-lxs Apr 7, 2025
a4d34f2
refactor: pass only the code index manager
daniel-lxs Apr 7, 2025
fe7dc0c
feat: add public getters for configuration state
daniel-lxs Apr 7, 2025
f665c7a
fix: formatting issues and send results as a "say" message for rendering
daniel-lxs Apr 7, 2025
d35e976
feat: render approval prompt and results on chat row
daniel-lxs Apr 7, 2025
522942c
refactor: improve prompt
daniel-lxs Apr 7, 2025
6464782
feat: add the parameters for the new tool
daniel-lxs Apr 7, 2025
09632fd
refactor: remove unnecessary limit
daniel-lxs Apr 7, 2025
dd8b003
refactor: format results for the AI as XML
daniel-lxs Apr 7, 2025
2a453f9
refactor: combine line numbers properties
daniel-lxs Apr 7, 2025
a51ed1f
fix: use a different formatting to not interfere with the tool proces…
daniel-lxs Apr 8, 2025
2313dda
fix: stop logging unsupported files
daniel-lxs Apr 8, 2025
c5572cd
refactor: create a file watcher that only triggers for files with sup…
daniel-lxs Apr 8, 2025
236df68
fix: file watcher sending conflicting states to UI
daniel-lxs Apr 8, 2025
1b2da28
fix: updated changed properties
daniel-lxs Apr 8, 2025
08393be
fix: only initialize file watcher after the initial indexing is complete
daniel-lxs Apr 8, 2025
82979a8
refactor: use old method name
daniel-lxs Apr 8, 2025
dcf8871
fix: use uuid for the newly generated points
daniel-lxs Apr 8, 2025
432d5b6
fix: clear index file if collection doesn't exist
daniel-lxs Apr 9, 2025
f2ccedb
refactor: improve state machine to prevent conflicting states from sh…
daniel-lxs Apr 9, 2025
5ca93f0
refactor: always scan codebase when initializing
daniel-lxs Apr 9, 2025
b96acf8
refactor: use uuid5 to create a deterministic id and delete points of…
daniel-lxs Apr 9, 2025
298ca82
deps: replace uuid4 with uuid5
daniel-lxs Apr 9, 2025
bb18a5f
refactor: use updated property
daniel-lxs Apr 9, 2025
891a0fe
fix: create collection if it doesn't exist
daniel-lxs Apr 9, 2025
2e15e68
feat: use tree sitter queries and clear index file if collection is r…
daniel-lxs Apr 9, 2025
36a8c26
fix: stop blocking the ui while indexing process is running
daniel-lxs Apr 9, 2025
ff5d985
refactor: simplify state management
daniel-lxs Apr 10, 2025
42f172a
feat: recreate clients when configuration is updated
daniel-lxs Apr 10, 2025
dd65eef
refactor: save api key in secrets and improve the configuration loadi…
daniel-lxs Apr 10, 2025
3ed7879
refactor: unify configuration data
daniel-lxs Apr 11, 2025
592fd6d
feat: add qdrant api key to connect to cloud instances and use secret…
daniel-lxs Apr 11, 2025
f593529
refactor: remove logs
daniel-lxs Apr 11, 2025
2cfe5c6
refactor: initialize manger after context proxy is ready
daniel-lxs Apr 11, 2025
bd07035
refactor: flatten configuration object to pass api keys as api config…
daniel-lxs Apr 11, 2025
47f0c4f
refactor: use cached field and api config field for settings and api …
daniel-lxs Apr 11, 2025
f8cf9be
refactor: manually merge pr 1
daniel-lxs Apr 11, 2025
4eedda3
refactor: update and organize types
daniel-lxs Apr 14, 2025
8a5fde5
feat: add new embedder url and model id for local embedders
daniel-lxs Apr 14, 2025
f5839df
feat: add ollama embedding support and support unified config object
daniel-lxs Apr 15, 2025
e38c2d1
refactor: split main manager responsabilities
daniel-lxs Apr 15, 2025
3829f5e
fix: update config
daniel-lxs Apr 15, 2025
b229deb
fix: add default config object for when the extension is initialized …
daniel-lxs Apr 15, 2025
98ba6b1
refactor: rename embeder provider config parameter
daniel-lxs Apr 15, 2025
7a90283
feat: create model profiles to control qdrant vector size
daniel-lxs Apr 21, 2025
0f45be6
feat: add a list of embedder models to state and ui
daniel-lxs Apr 21, 2025
b5353cb
feat: add a method to completely delete the collection and use it whe…
daniel-lxs Apr 21, 2025
0a6e858
refactor: use singleton of code parser
daniel-lxs Apr 21, 2025
a54e5bf
refactor: update new tool name and params
daniel-lxs Apr 22, 2025
2a3b8fe
fix: add imports
daniel-lxs Apr 22, 2025
3eece49
fix: cache language parsers instead of loading a new one for every file
daniel-lxs Apr 22, 2025
e108472
fix: omit markdown files from the parser since it is necessary a more…
daniel-lxs Apr 22, 2025
2d5bda1
feat: split big chunks of text that exceed the max char cout
daniel-lxs Apr 24, 2025
6fe62ea
feat: implement batch splitting, token counting and rate limiting for…
daniel-lxs Apr 24, 2025
f774243
refactor: prevent points deletion operation for new files
daniel-lxs Apr 24, 2025
48a0c91
feat: add method to delete points from multiple files at the same time
daniel-lxs Apr 24, 2025
e6d504d
fix: avoid changing the state if one batch fails
daniel-lxs Apr 25, 2025
eae3e0a
refactor: use token aproximation
daniel-lxs Apr 25, 2025
efbddcc
feat: add file info when at least one valid block was added to the batch
daniel-lxs Apr 25, 2025
ddf7002
refactor: reduce size of batch
daniel-lxs Apr 25, 2025
e1122dc
feat: add mutex to parallelize the parsing process
daniel-lxs Apr 28, 2025
b6da74b
feat: add progress reporting of the indexing process
daniel-lxs Apr 28, 2025
32dae80
lint: remove unused variables and imports
daniel-lxs Apr 28, 2025
04a5c0d
fix: send progress numbers to webview
daniel-lxs Apr 28, 2025
792a8e5
fix: add codebase search tool to the read file tool group
daniel-lxs Apr 28, 2025
8ef23e2
fix: remove check for context proxy since is always initialized on cl…
daniel-lxs Apr 29, 2025
f25d1eb
fix: use shared extension list for all processors
daniel-lxs Apr 29, 2025
ba6483b
refactor: increase file list limit
daniel-lxs Apr 29, 2025
ee8ec12
feat: implement fallback parsing for supported files
daniel-lxs Apr 30, 2025
6b97ec4
feat: add soft max for code segment length
daniel-lxs Apr 30, 2025
83a8592
fix: types
daniel-lxs May 1, 2025
0e22fbe
remove stuff
daniel-lxs May 1, 2025
12151dc
refactor: qdrant api key field no longer required to start indexing
daniel-lxs May 2, 2025
b250340
refactor: make missing config message clearer
daniel-lxs May 2, 2025
35c4201
ui: use custom dropdown component
daniel-lxs May 2, 2025
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
281 changes: 267 additions & 14 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@
"@google/generative-ai": "^0.18.0",
"@mistralai/mistralai": "^1.3.6",
"@modelcontextprotocol/sdk": "^1.7.0",
"@qdrant/js-client-rest": "^1.13.0",
"@types/clone-deep": "^4.0.4",
"@types/pdf-parse": "^1.1.4",
"@types/tmp": "^0.2.6",
Expand Down Expand Up @@ -444,6 +445,8 @@
"tmp": "^0.2.3",
"tree-sitter-wasms": "^0.1.11",
"turndown": "^7.2.0",
"uuid": "^11.1.0",
"uuid5": "^1.0.2",
"web-tree-sitter": "^0.22.6",
"zod": "^3.23.8"
},
Expand All @@ -462,6 +465,7 @@
"@typescript-eslint/eslint-plugin": "^7.14.1",
"@typescript-eslint/parser": "^7.11.0",
"@vscode/vsce": "^3.3.2",
"async-mutex": "^0.5.0",
"esbuild": "^0.24.0",
"eslint": "^8.57.0",
"execa": "^9.5.2",
Expand All @@ -473,6 +477,7 @@
"lint-staged": "^15.2.11",
"mkdirp": "^3.0.1",
"npm-run-all": "^4.1.5",
"p-limit": "^6.2.0",
"prettier": "^3.4.2",
"rimraf": "^6.0.1",
"ts-jest": "^29.2.5",
Expand Down
19 changes: 19 additions & 0 deletions src/__mocks__/vscode.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,25 @@ const vscode = {
stat: jest.fn(),
},
},
FileSystemError: class FileSystemError extends Error {
constructor(message, code) {
super(message)
this.name = "FileSystemError"
this.code = code
}
static FileNotFound(uri) {
return new FileSystemError(`File not found: ${uri}`, "FileNotFound")
}
static FileExists(uri) {
return new FileSystemError(`File already exists: ${uri}`, "FileExists")
}
static FileNotADirectory(uri) {
return new FileSystemError(`Not a directory: ${uri}`, "FileNotADirectory")
}
static NoPermissions(uri) {
return new FileSystemError(`No permissions: ${uri}`, "NoPermissions")
}
},
Disposable: class {
dispose() {}
},
Expand Down
13 changes: 13 additions & 0 deletions src/core/Cline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ import { askFollowupQuestionTool } from "./tools/askFollowupQuestionTool"
import { switchModeTool } from "./tools/switchModeTool"
import { attemptCompletionTool } from "./tools/attemptCompletionTool"
import { newTaskTool } from "./tools/newTaskTool"
import { codebaseSearchTool } from "./tools/codebaseSearchTool"

export type ToolResponse = string | Array<Anthropic.TextBlockParam | Anthropic.ImageBlockParam>
type UserContent = Array<Anthropic.Messages.ContentBlockParam>
Expand Down Expand Up @@ -1407,6 +1408,8 @@ export class Cline extends EventEmitter<ClineEvents> {
return `[${block.name}]`
case "switch_mode":
return `[${block.name} to '${block.params.mode_slug}'${block.params.reason ? ` because: ${block.params.reason}` : ""}]`
case "codebase_search": // Add case for the new tool
return `[${block.name} for '${block.params.query}']`
case "new_task": {
const mode = block.params.mode ?? defaultModeSlug
const message = block.params.message ?? "(no message)"
Expand Down Expand Up @@ -1592,6 +1595,16 @@ export class Cline extends EventEmitter<ClineEvents> {
case "list_files":
await listFilesTool(this, block, askApproval, handleError, pushToolResult, removeClosingTag)
break
case "codebase_search":
await codebaseSearchTool(
this,
block,
askApproval,
handleError,
pushToolResult,
removeClosingTag,
)
break
case "list_code_definition_names":
await listCodeDefinitionNamesTool(
this,
Expand Down
9 changes: 9 additions & 0 deletions src/core/assistant-message/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const toolUseNames = [
"switch_mode",
"new_task",
"fetch_instructions",
"codebase_search",
] as const

// Converts array of tool call names into a union type ("execute_command" | "read_file" | ...)
Expand Down Expand Up @@ -60,6 +61,8 @@ export const toolParamNames = [
"cwd",
"follow_up",
"task",
"query",
"limit",
] as const

export type ToolParamName = (typeof toolParamNames)[number]
Expand Down Expand Up @@ -147,3 +150,9 @@ export interface NewTaskToolUse extends ToolUse {
name: "new_task"
params: Partial<Pick<Record<ToolParamName, string>, "mode" | "message">>
}

// Added specific interface for codebase_search
export interface CodebaseSearchToolUse extends ToolUse {
name: "codebase_search"
params: Partial<Pick<Record<ToolParamName, string>, "query" | "limit">>
}
4 changes: 4 additions & 0 deletions src/core/prompts/system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
} from "./sections"
import { loadSystemPromptFile } from "./sections/custom-system-prompt"
import { formatLanguage } from "../../shared/language"
import { CodeIndexManager } from "../../services/code-index/manager"

async function generatePrompt(
context: vscode.ExtensionContext,
Expand Down Expand Up @@ -62,6 +63,8 @@ async function generatePrompt(
: Promise.resolve(""),
])

const codeIndexManager = CodeIndexManager.getInstance(context)

const basePrompt = `${roleDefinition}

${getSharedToolUseSection()}
Expand All @@ -70,6 +73,7 @@ ${getToolDescriptionsForMode(
mode,
cwd,
supportsComputerUse,
codeIndexManager,
effectiveDiffStrategy,
browserViewportSize,
mcpHub,
Expand Down
19 changes: 19 additions & 0 deletions src/core/prompts/tools/codebase-search.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
export function getCodebaseSearchDescription(): string {
return `## codebase_search
Description: Search the codebase for relevant files based on a query. Use this when the user asks a question about the codebase that requires finding specific files or code snippets.
Parameters:
- query: (required) The natural language query to search for.
- limit: (optional) The maximum number of search results to return. Defaults to 10.
Usage:
<codebase_search>
<query>Your natural language query here</query>
<limit>Number of results (optional)</limit>
</codebase_search>

Example: Searching for functions related to user authentication
<codebase_search>
<query>User login and password hashing</query>
<limit>5</limit>
</codebase_search>
`
}
10 changes: 10 additions & 0 deletions src/core/prompts/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ import { getUseMcpToolDescription } from "./use-mcp-tool"
import { getAccessMcpResourceDescription } from "./access-mcp-resource"
import { getSwitchModeDescription } from "./switch-mode"
import { getNewTaskDescription } from "./new-task"
import { getCodebaseSearchDescription } from "./codebase-search"
import { DiffStrategy } from "../../diff/DiffStrategy"
import { McpHub } from "../../../services/mcp/McpHub"
import { Mode, ModeConfig, getModeConfig, isToolAllowedForMode, getGroupName } from "../../../shared/modes"
import { ToolName, TOOL_GROUPS, ALWAYS_AVAILABLE_TOOLS } from "../../../shared/tool-groups"
import { ToolArgs } from "./types"
import { CodeIndexManager } from "../../../services/code-index/manager"

// Map of tool names to their description functions
const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined> = {
Expand All @@ -34,6 +36,7 @@ const toolDescriptionMap: Record<string, (args: ToolArgs) => string | undefined>
attempt_completion: () => getAttemptCompletionDescription(),
use_mcp_tool: (args) => getUseMcpToolDescription(args),
access_mcp_resource: (args) => getAccessMcpResourceDescription(args),
codebase_search: () => getCodebaseSearchDescription(),
switch_mode: () => getSwitchModeDescription(),
new_task: (args) => getNewTaskDescription(args),
insert_content: (args) => getInsertContentDescription(args),
Expand All @@ -46,6 +49,7 @@ export function getToolDescriptionsForMode(
mode: Mode,
cwd: string,
supportsComputerUse: boolean,
codeIndexManager: CodeIndexManager,
diffStrategy?: DiffStrategy,
browserViewportSize?: string,
mcpHub?: McpHub,
Expand Down Expand Up @@ -79,6 +83,11 @@ export function getToolDescriptionsForMode(
// Add always available tools
ALWAYS_AVAILABLE_TOOLS.forEach((tool) => tools.add(tool))

// Conditionally exclude codebase_search if feature is disabled or not configured
if (!(codeIndexManager.isFeatureEnabled && codeIndexManager.isFeatureConfigured)) {
tools.delete("codebase_search")
}

// Map tool descriptions for allowed tools
const descriptions = Array.from(tools).map((toolName) => {
const descriptionFn = toolDescriptionMap[toolName]
Expand Down Expand Up @@ -112,4 +121,5 @@ export {
getSwitchModeDescription,
getInsertContentDescription,
getSearchAndReplaceDescription,
getCodebaseSearchDescription,
}
155 changes: 155 additions & 0 deletions src/core/tools/codebaseSearchTool.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import * as vscode from "vscode"
import { Cline } from "../Cline"
import { ToolUse } from "../assistant-message"
import { CodeIndexManager } from "../../services/code-index/manager"
import { getWorkspacePath } from "../../utils/path"
import { formatResponse } from "../prompts/responses"
import { t } from "../../i18n"
import { VectorStoreSearchResult } from "../../services/code-index/interfaces"
import { AskApproval, HandleError, PushToolResult, RemoveClosingTag } from "./types"

export async function codebaseSearchTool(
cline: Cline,
block: ToolUse,
askApproval: AskApproval,
handleError: HandleError,
pushToolResult: PushToolResult,
removeClosingTag: RemoveClosingTag,
) {
const toolName = "codebase_search"
const workspacePath = getWorkspacePath()

if (!workspacePath) {
// This case should ideally not happen if Cline is initialized correctly
await handleError(toolName, new Error("Could not determine workspace path."))
return
}

// --- Parameter Extraction and Validation ---
let query: string | undefined = block.params.query
let limitStr: string | undefined = block.params.limit
let limit: number = 5 // Default limit

if (!query) {
cline.consecutiveMistakeCount++
pushToolResult(await cline.sayAndCreateMissingParamError(toolName, "query"))
return
}
query = removeClosingTag("query", query)

if (limitStr) {
limitStr = removeClosingTag("limit", limitStr)
limit = parseInt(limitStr, 10)
if (isNaN(limit) || limit <= 0) {
cline.consecutiveMistakeCount++
await cline.say("text", `Invalid limit value: "${limitStr}". Using default ${10}.`)
limit = 10
}
}

// Extract optional sendResultsToUI parameter

// --- Approval ---
const translationKey = "chat:codebaseSearch.wantsToSearch"
let approvalMessage: string

approvalMessage = t(translationKey, { query, limit })

const approvalPayload = {
tool: "codebase_search",
approvalPrompt: approvalMessage,
query: query,
limit: limit,
isOutsideWorkspace: false,
}

const didApprove = await askApproval("tool", JSON.stringify(approvalPayload))
if (!didApprove) {
pushToolResult(formatResponse.toolDenied())
return
}

cline.consecutiveMistakeCount = 0

// --- Core Logic ---
try {
const context = cline.providerRef.deref()?.context
if (!context) {
throw new Error("Extension context is not available.")
}

const manager = CodeIndexManager.getInstance(context)

// Check if indexing is enabled and configured (using assumed properties/methods)
// @ts-expect-error Accessing private member _isEnabled
const isEnabled = manager.isEnabled ?? true // Assume enabled if property doesn't exist
// @ts-expect-error Accessing private member _isConfigured
const isConfigured = manager.isConfigured ? manager.isConfigured() : true // Assume configured if method doesn't exist

if (!isEnabled) {
throw new Error("Code Indexing is disabled in the settings.")
}
if (!isConfigured) {
throw new Error("Code Indexing is not configured (Missing OpenAI Key or Qdrant URL).")
}

const searchResults: VectorStoreSearchResult[] = await manager.searchIndex(query, limit)

// 3. Format and push results
if (!searchResults || searchResults.length === 0) {
pushToolResult(`No relevant code snippets found for the query: "${query}"`) // Use simple string for no results
return
}

const jsonResult = {
query,
results: [],
} as {
query: string
results: Array<{
filePath: string
score: number
startLine: number
endLine: number
codeChunk: string
}>
}

searchResults.forEach((result) => {
if (!result.payload) return
if (!("filePath" in result.payload)) return

const relativePath = vscode.workspace.asRelativePath(result.payload.filePath, false)

jsonResult.results.push({
filePath: relativePath,
score: result.score,
startLine: result.payload.startLine,
endLine: result.payload.endLine,
codeChunk: result.payload.codeChunk.trim(),
})
})

// Send results to UI
const payload = { tool: toolName, content: jsonResult }
await cline.say("tool", JSON.stringify(payload))

// Push results to AI
const output = `Query: ${query}
Results:

${jsonResult.results
.map(
(result) => `File path: ${result.filePath}
Score: ${result.score}
Lines: ${result.startLine}-${result.endLine}
Code Chunk: ${result.codeChunk}
`,
)
.join("\n")}`

pushToolResult(output)
} catch (error: any) {
await handleError(toolName, error) // Use the standard error handler
}
}
Loading