Skip to content

Advanced Features5 min read

Codebase Indexing & Semantic Search

Qdrant + embeddings for meaning-based code search

Regex search finds strings; semantic search finds meaning. With codebase indexing enabled, Nexgile Code embeds your code into vectors stored in a Qdrant database, and the agent gains the codebase_search tool: ask it about “where user sessions get invalidated” and it finds the relevant code even if no file contains the word “invalidated”. On any project too large to read end-to-end, this is the single biggest upgrade to the agent’s ability to find the right code fast — the agent is instructed to reach for semantic search first when exploring unfamiliar territory, before falling back to regex (search_files) or directory listings.

Two ingredients, both yours to choose:

  1. A Qdrant instance — the vector store. Run it locally with Docker in one line, or point at any hosted Qdrant (an API key field is provided, optional):

    Terminal window
    docker run -p 6333:6333 qdrant/qdrant

    The default URL is http://localhost:6333.

  2. An embedding provider — turns code into vectors. Pick one in the setup form:

    Provider Notes
    OpenAI API key + model pick; dimensions shown per model
    Ollama Fully local — base URL (default http://localhost:11434) + model name + dimension
    OpenAI Compatible Any OpenAI-shaped endpoint: base URL, API key, model, dimension
    Gemini API key + model pick
    Mistral API key + model pick
    Vercel AI Gateway API key + model pick
    Amazon Bedrock AWS region + AWS profile (from ~/.aws/credentials) + model
    OpenRouter API key + model pick, with optional provider routing

    Embedding calls are separate from (and much cheaper than) your chat model — indexing a codebase costs cents, not dollars. Ollama makes the whole pipeline local and free.

Indexing lives in a popover opened from the status badge in the chat area (a small database icon; its tooltip reads “Index ready”, “Indexing N%”, “Indexed”, or “Index error”). Click it to open the Codebase Indexing popover:

  1. Flip Enable Codebase Indexing on.
  2. Fill in Setup: embedder provider, its credentials, the model, and the Qdrant URL (plus optional Qdrant API key).
  3. Optionally expand Advanced Configuration (tunables below).
  4. Save, then press Start Indexing.

The Status section tracks progress: Standby → Indexing (with a progress percentage) → Indexed, or Error with a message. First-time indexing of a large repo takes a few minutes; you can keep working, and a Stop Indexing button is available mid-run.

Two workspace-level switches round it out: Enable indexing for this workspace (configuration can exist globally while individual workspaces opt in or out) and Auto-enable indexing for new workspaces.

Setting Default Range What it does
Search Score Threshold 0.4 0–1 Minimum similarity for a result to be returned. Lower = more, looser results; higher = fewer, stricter
Maximum Search Results 50 10–200 Cap on results per query
Embedding batch size (nexgile-code.codeIndex.embeddingBatchSize, VS Code settings) 60 Code blocks embedded per API batch; lower it if your provider rate-limits

Once the status shows Indexed, the agent gets codebase_search, taking a natural-language query and an optional path to scope the search to a subdirectory. Results come back as a ranked list — file path, similarity score, line range, and the code chunk — rendered in the chat as clickable results that open the file. The agent then reads the promising hits properly with read_file and gets to work.

codebase_search is part of the read tool group, so it’s covered by the read-only auto-approve toggle and available in every mode that can read files.

You can also steer it directly:

Search the codebase for "retry logic around outbound webhooks" and
summarize how failures are handled. Scope to src/services.
  • Files: code in the ~40 supported languages (JavaScript/TypeScript/JSX/TSX, Python, Rust, Go, C, C++, C#, Ruby, Java, PHP, Swift, Kotlin, Elixir, Lua, Scala, Vue, HTML, CSS, and more) plus Markdown, JSON, and TOML.
  • Chunking: files are parsed into semantically meaningful blocks (functions, classes, sections) rather than arbitrary windows, so results align with real code units.
  • Skipped: anything matched by your .gitignore, anything matched by .nexgileignore, dependency and build directories (node_modules, __pycache__, dist, out, vendor, and similar), hidden directories, files over 1 MB, and anything beyond a 50,000-file scan cap.

.nexgileignore is your lever here: exclude generated code, fixtures, and vendored bundles and the index gets smaller, cheaper, and more relevant all at once.

  • Automatic: a file watcher keeps the index current as you (or the agent) create, edit, and delete files. Content hashes ensure unchanged files are never re-embedded.
  • Manual rebuild: in the popover, Clear Index Data (confirmed by a dialog — it permanently deletes the index) followed by Start Indexing. Do this after changing embedding provider or model, since vectors from different models aren’t comparable, or whenever results feel stale.
  1. Check the badge. “Index error” or perpetual “Standby” means searches have nothing to search. Open the popover for the error message.
  2. Qdrant reachable? Verify the URL (is the Docker container running? docker ps), and the API key if hosted.
  3. Embedder working? An invalid API key or a deleted model shows up as an indexing error, not a search error.
  4. Threshold too strict? Drop the Search Score Threshold from 0.4 toward 0.2 and retry — sparse hits with low scores mean the match exists but was filtered.
  5. Excluded by ignore rules? If a known file never appears, check .gitignore/.nexgileignore — remember .nexgileignore must sit at the workspace root.
  6. Model changed? Rebuild the index (Clear Index Data → Start Indexing) after any provider/model switch.