Semantic (meaning-based) code search. Files are chunked and embedded into
vectors; a query is embedded the same way and ranked by cosine similarity. The
plugin contributes a "Semantic Results" section to the project search screen
via ProjectSearchExtension.
Embeddings come from the backend you selected in AI settings, resolved at runtime through
ai-core(no compile-time dependency). That backend has to be one that embeds, which today meansai-agent-openaiorai-agent-gemini. With none selected, this plugin contributes no results at all — it has no lexical fallback, because word matches presented as semantic ones look like the feature working badly rather than not running.
Preferences → Configuration → Semantic Search shows which backend that is,
whether it supports Vector Search (and how to fix it if not), and picks its
embedding model through the backend's EmbeddingModelSelectable. It also names
where indexing sends the code, reports the open project's index, and clears the
index after confirmation. It needs CoGo 26.41+.
┌──────────────────────────┐
│ vector-search (this) │ ← chunk, batch, cosine-similarity ranking, project search
└────────────┬─────────────┘
│ SharedServices (runtime) → LlmInferenceService
▼
┌──────────────────────────┐
│ ai-core │ ← resolves the backend the user selected
└────────────┬─────────────┘
│ LlmInferenceService.EmbeddingBackend (a host type, from plugin-api)
▼
┌──────────────────────────┐
│ ai-agent-openai │ ← POST /v1/embeddings
│ ai-agent-gemini │ ← models/{model}:batchEmbedContents
└──────────────────────────┘
- Semantic search over the current project via
ProjectSearchExtension - Embeds through whichever backend the user selected; names no provider itself
- Batched indexing, so a project costs a handful of calls rather than one per chunk
- Provenance per vector (backend, model, width); a search only ranks vectors of the same origin, and changing either builds the index again
- Chunk-level results with file, line range, and a preview snippet
- Local SQLite embedding store, scoped per project and kept across restarts, so a project is embedded — and paid for — once rather than on every launch
Declared in plugin.permissions:
| Permission | Why |
|---|---|
filesystem.read |
read project files to chunk and embed |
project.structure |
enumerate the project's source roots |
No network.access: this plugin opens no sockets. The HTTP call belongs to the
backend plugin, which declares it. Indexing reads files in the current project
only and the index is a local database, but the chunk text is sent to the
selected backend to be embedded — which is why nothing is indexed until a
backend has been chosen.
Prerequisites: Android SDK (API 33+), JDK 17. Create local.properties with
sdk.dir=.... No NDK or native toolchain.
cd plugins/Vector-Search
../../gradlew assemblePlugin # release -> build/plugin/vector-search.cgp
../../gradlew assemblePluginDebug # debug variant
../../gradlew testDebugUnitTest # ranking, indexing, SQL and settings-screen logicThe build resolves plugin-api.jar from the repo-root ../../libs/.
- Install
ai-coreand an agent plugin whose backend embeds (ai-agent-openaiorai-agent-gemini), select it in AI settings and give it a key. - Build this plugin, install
build/plugin/vector-search.cgpvia Code on the Go's Plugin Manager, and restart the IDE. - Run a query from the project search screen; look for the Semantic Results section. The first query on a project builds the index.
VectorSearchPlugin.kt— lifecycle,ProjectSearchExtension,SettingsExtension, search flowIndexCoordinator.kt— builds, reuses and clears the index, one operation at a timeVectorSearchHelp.kt— tooltip tags and entries for the in-app helpBackendWatch.kt— keeps aBackendChangeListeneron AI Core across its restartssettings/BackendCompatibility.kt— what the screen can say about the selected backendsettings/SemanticSearchSource.kt— what the screen reads and resets, apart from the pluginsettings/SemanticSearchSettingsFragment.kt/…ViewModel.kt— the Semantic Search screenEmbedderResolver.kt— which embedder may be used, and why not when notEmbedderIdentity.kt— the provenance stamped onto every stored vectorReindexDecision.kt— whether the existing index can answer the queryEmbeddingBatches.kt— how many chunks go into one callEmbeddingIndexingService.kt— file collection and embedding storage (SQLite)EmbeddingsSql.kt— the schema and every SQL statement, values bound only through?CodeChunker.kt— splits files into embeddable chunksVectorSearchService.kt/VectorMath.kt— similarity ranking
GPL-3.0 — same as AndroidIDE / Code on the Go.