From 03d8f49479b3446cf7f8ab9b6fdb2401584e3f12 Mon Sep 17 00:00:00 2001 From: Clawd Date: Thu, 5 Mar 2026 07:19:28 -0800 Subject: Add Ollama support as default provider, clean Embedder interface --- PLAN.md | 69 ++++++++++++++++++++++++++++++++++++----------------------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/PLAN.md b/PLAN.md index 88545b9..2c59e97 100644 --- a/PLAN.md +++ b/PLAN.md @@ -103,35 +103,55 @@ type Chunker interface { ## Phase 4: Embedding Generation -Generate embeddings via OpenAI-compatible API (internal endpoint). +Provider interface with Ollama (default) and OpenAI-compatible backends. **Input:** List of chunks **Output:** Chunks with embedding vectors ```go +// Provider interface — easy to swap type Embedder interface { Embed(ctx context.Context, texts []string) ([][]float32, error) + Dimensions() int } -type Embedder struct { - baseURL string // defaults to OpenAI, configurable for internal API +// Ollama provider (default) +type OllamaEmbedder struct { + baseURL string // default: http://localhost:11434 + model string // default: nomic-embed-text +} + +// OpenAI-compatible provider +type OpenAIEmbedder struct { + baseURL string // configurable for internal API apiKey string - model string // "text-embedding-3-small" + model string // text-embedding-3-small, etc. } ``` -**Batching:** Batch chunks to minimize API calls (~100 per request). +**Provider selection via flag:** +```bash +codevec index . --provider ollama --model nomic-embed-text +codevec index . --provider openai --model text-embedding-3-small +``` **Config:** -- `CODEVEC_API_KEY` — API key -- `CODEVEC_BASE_URL` — Embedding API endpoint -- `--model` flag for model selection +- `--provider` — `ollama` (default) or `openai` +- `--model` — model name (provider-specific defaults) +- `CODEVEC_API_KEY` — API key (OpenAI provider) +- `CODEVEC_BASE_URL` — Override endpoint (both providers) + +**Ollama models for embeddings:** +- `nomic-embed-text` — 768 dims, good general purpose +- `mxbai-embed-large` — 1024 dims, higher quality **Tasks:** -- [ ] Implement OpenAI-compatible embedding client (stdlib `net/http`) -- [ ] Support custom base URL for internal API -- [ ] Batch requests -- [ ] Handle rate limits with exponential backoff +- [ ] Define `Embedder` interface +- [ ] Implement `OllamaEmbedder` (POST to `/api/embeddings`) +- [ ] Implement `OpenAIEmbedder` (POST to `/v1/embeddings`) +- [ ] Provider factory based on `--provider` flag +- [ ] Batch requests where supported +- [ ] Handle errors gracefully (connection refused, model not found) --- @@ -159,9 +179,11 @@ CREATE TABLE files ( indexed_at INTEGER DEFAULT (unixepoch()) ); +-- Dimension set at index creation based on model +-- nomic-embed-text: 768, mxbai-embed-large: 1024, text-embedding-3-small: 1536 CREATE VIRTUAL TABLE vec_chunks USING vec0( id INTEGER PRIMARY KEY, - embedding FLOAT[1536] + embedding FLOAT[768] -- adjusted per model ); ``` @@ -247,7 +269,9 @@ Only re-index changed files. "indexed_at": 1709654400 } }, - "model": "text-embedding-3-small", + "provider": "ollama", + "model": "nomic-embed-text", + "dimensions": 768, "version": 1 } ``` @@ -280,7 +304,6 @@ Only re-index changed files. - TypeScript chunker (tree-sitter + TS grammar) - Python chunker -- Ollama embedder for local/offline use - `codevec serve` HTTP API - Watch mode (re-index on file change) - Import/export index @@ -300,22 +323,6 @@ require ( --- -## Estimated Effort - -| Phase | Effort | -|-------|--------| -| 1. Skeleton | 30 min | -| 2. Walker | 1 hr | -| 3. Chunker | 2 hr | -| 4. Embedder | 1 hr | -| 5. Storage | 2 hr | -| 6. CLI | 1 hr | -| 7. Incremental | 1 hr | -| 8. Polish | 30 min | -| **Total** | ~9 hr | - ---- - ## Decisions 1. **CLI framework:** Cobra -- cgit v1.2.3