Last Updated: 2026-02-12 Version: v0.9.19+
Weave CLI is a command-line tool for managing vector databases with RAG (Retrieval-Augmented Generation) capabilities. It provides a unified interface across 10 different vector database systems with AI agent-based query execution.
┌─────────────────────────────────────────────────────────────┐
│ CLI Layer │
│ (Cobra Commands: vector-db, health, collections, etc.) │
└──────────────────┬──────────────────────────────────────────┘
│
┌──────────────────▼──────────────────────────────────────────┐
│ Agent Layer │
│ • WeaveAgent (orchestration) │
│ • QueryAgent, PlanningAgent, OutputAgent, etc. │
│ • LLM Integration (OpenAI, Claude) │
└──────────────────┬──────────────────────────────────────────┘
│
┌──────────────────▼──────────────────────────────────────────┐
│ Vector DB Abstraction Layer │
│ VectorDBClient Interface │
└──────────────────┬──────────────────────────────────────────┘
│
┌────────────┴────────────┬──────────────┬──────────────┐
│ │ │ │
┌─────▼─────┐ ┌────────▼───────┐ ┌────▼──────┐ ┌────▼──────┐
│ Weaviate │ │ Qdrant │ │ Milvus │ │ ... │
│ Adapter │ │ Adapter │ │ Adapter │ │ (10 VDBs) │
└───────────┘ └────────────────┘ └───────────┘ └───────────┘
Purpose: User interface and command orchestration
Structure:
src/cmd/
├── root.go # Root command and global flags
├── vectordb/ # VDB management commands
│ ├── health.go # Health check command
│ ├── collections.go # Collection CRUD
│ ├── documents.go # Document operations
│ └── search.go # Search operations
├── config/ # Configuration commands
└── version/ # Version command
Technology: Cobra CLI framework
Purpose: AI-powered query planning and execution
Key Agents:
- WeaveAgent: Main orchestrator, coordinates other agents
- QueryAgent: Translates natural language to VDB queries
- PlanningAgent: Creates execution plans for complex queries
- OutputAgent: Formats results for display
- BashAgent: Executes system commands
- EvalAgent: Evaluates query results
LLM Integration: OpenAI (GPT-4), Claude via src/pkg/llm/
Purpose: Unified interface across all vector databases
type VectorDBClient interface {
// Health & Connection
Health(ctx context.Context) error
Close() error
// Collections
CreateCollection(ctx, name string, schema *CollectionSchema) error
DeleteCollection(ctx, name string) error
ListCollections(ctx) ([]*Collection, error)
CollectionExists(ctx, name string) (bool, error)
GetCollectionCount(ctx, name string) (int64, error)
// Documents
CreateDocument(ctx, collection string, doc *Document) error
CreateDocuments(ctx, collection string, docs []*Document) error
GetDocument(ctx, collection, id string) (*Document, error)
UpdateDocument(ctx, collection string, doc *Document) error
DeleteDocument(ctx, collection, id string) error
DeleteDocuments(ctx, collection string, ids []string) error
DeleteDocumentsByMetadata(ctx, collection string, metadata map[string]interface{}) error
ListDocuments(ctx, collection string, limit, offset int) ([]*Document, error)
// Search
SearchSemantic(ctx, collection, query string, opts *QueryOptions) ([]*SearchResult, error)
SearchBM25(ctx, collection, query string, opts *QueryOptions) ([]*SearchResult, error)
SearchHybrid(ctx, collection, query string, opts *QueryOptions) ([]*SearchResult, error)
SearchByMetadata(ctx, collection string, metadata map[string]interface{}, opts *QueryOptions) ([]*SearchResult, error)
// Schema
GetSchema(ctx, collection string) (*CollectionSchema, error)
UpdateSchema(ctx, collection string, schema *CollectionSchema) error
GetDefaultSchema(schemaType SchemaType, collection string) *CollectionSchema
ValidateSchema(schema *CollectionSchema) error
}Each VDB implements the interface via adapter pattern:
src/pkg/vectordb/
├── interfaces.go # VectorDBClient interface
├── factory.go # Factory for creating clients
├── errors.go # Standard error types
├── timeout.go # Operation-specific timeouts
├── weaviate/
│ ├── adapter.go # Weaviate adapter (implements VectorDBClient)
│ ├── collections.go # Collection operations
│ ├── documents.go # Document operations
│ ├── queries.go # Search operations
│ ├── schema.go # Schema management
│ └── factory.go # Factory registration
├── qdrant/
│ ├── adapter.go # Qdrant adapter
│ ├── client.go # Qdrant client wrapper
│ ├── collection.go # Collection ops
│ ├── document.go # Document ops
│ ├── query.go # Search ops
│ └── factory.go # Factory registration
└── [8 more VDBs...]
Supported VDBs (10 total):
- ✅ Stable: Weaviate, Qdrant, Milvus, Chroma, Supabase, Neo4j, MongoDB
- 🟢 Beta: Pinecone, Elasticsearch, OpenSearch
Purpose: Manage VDB connection configurations
Configuration Sources (priority order):
- Command-line flags
- Environment variables
- Config files (
configs/config.*.yaml) - Defaults
Config Structure:
vector_db:
type: qdrant-cloud
url: https://xyz.qdrant.io
api_key: ${QDRANT_API_KEY}
timeout: 60
vector_dimensions: 1536
similarity_metric: cosinePurpose: Extract text and metadata from documents
Capabilities:
- PDF Processing: Text extraction, image extraction from PDFs
- Image Processing: OCR, EXIF metadata extraction
- Storage: Configurable paths for extracted images
Purpose: Model Context Protocol client for external integrations
Features:
- Connect to MCP servers
- Tool discovery and invocation
- Resource management
Purpose: Pluggable embedding model support for OSS and proprietary providers
The embedding provider architecture enables re-embedding collections with different models (OpenAI, sentence-transformers, Ollama) without re-processing source documents. This provides 20x performance improvement over full re-ingestion.
┌─────────────────────────────────────────────────────────────┐
│ Re-embedding Command Layer │
│ (src/cmd/collection/re_embed.go) │
└────────────────┬────────────────────────────────────────────┘
│
┌────────────────▼────────────────────────────────────────────┐
│ Embedding Pipeline │
│ (src/pkg/reembedding/pipeline.go) │
│ • Batch processing (100-500 docs/batch) │
│ • Progress tracking │
│ • Error handling │
└────────────────┬────────────────────────────────────────────┘
│
┌───────▼────────┐
│ Provider │
│ Factory │
│ CreateProvider()│
│ (providers/) │
└───────┬────────┘
│
┌───────────┼───────────┬─────────────┐
│ │ │ │
┌────▼────┐ ┌───▼────┐ ┌───▼────┐ ┌────▼────┐
│ OpenAI │ │sentence│ │ Ollama │ │ Future │
│Provider │ │transf. │ │Provider│ │Providers│
│ (API) │ │(Python)│ │ (HTTP) │ │ │
└────┬────┘ └───┬────┘ └───┬────┘ └─────────┘
│ │ │
└──────────┼───────────┘
│
┌──────▼──────┐
│ Document │
│ .Embedding │
│ []float64 │
│ .Text │
└──────┬──────┘
│
┌──────▼──────┐
│ VDB Adapter │
│Check first: │
│len(emb) > 0?│
│ Use/Skip │
└──────┬──────┘
│
┌──────▼──────┐
│Vector Database│
│ (any VDB) │
└──────────────┘
All embedding providers implement this interface:
type EmbeddingProvider interface {
GenerateEmbedding(ctx context.Context, text string) ([]float64, error)
GenerateEmbeddings(ctx context.Context, texts []string) ([][]float64, error)
IsAvailable(ctx context.Context) error
GetDimensions() int
GetProvider() string
}1. OpenAI Provider (providers/openai.go)
- Models: text-embedding-3-small (1536 dims), text-embedding-3-large (3072 dims)
- Protocol: REST API
- Requirements: OPENAI_API_KEY environment variable
- Performance: 200+ docs/min
- Cost: $0.02 per 1M tokens
2. Sentence-Transformers Provider (providers/sentence_transformers.go)
- Models:
- all-mpnet-base-v2 (768 dims) - highest quality
- all-MiniLM-L6-v2 (384 dims) - fastest
- Protocol: Python subprocess (sentence-transformers library)
- Requirements: Python 3.8+, sentence-transformers installed
- Performance: 150+ docs/min
- Cost: $0 (open-source)
- Quality: 92-95% of OpenAI quality (often better!)
3. Ollama Provider (providers/ollama.go)
- Models:
- nomic-embed-text (768 dims)
- mxbai-embed-large (1024 dims)
- Protocol: HTTP API (localhost:11434)
- Requirements: Ollama installed and running locally
- Performance: 180+ docs/min
- Cost: $0 (open-source, local)
- Quality: 90-93% of OpenAI quality
The factory pattern enables automatic provider selection based on model name:
// providers/factory.go
func CreateProvider(ctx context.Context, modelName string) (EmbeddingProvider, error) {
// Auto-detect provider from model name
if strings.HasPrefix(modelName, "text-embedding-") {
return NewOpenAIProvider(ctx, modelName)
}
if strings.HasPrefix(modelName, "sentence-transformers/") {
return NewSentenceTransformersProvider(ctx, modelName)
}
if modelName == "nomic-embed-text" || modelName == "mxbai-embed-large" {
return NewOllamaProvider(ctx, modelName)
}
return nil, fmt.Errorf("unknown model: %s", modelName)
}The pipeline orchestrates the re-embedding process:
// src/pkg/reembedding/pipeline.go
type EmbeddingPipeline struct {
provider EmbeddingProvider
dimensions int
}
func (p *EmbeddingPipeline) ProcessBatch(ctx context.Context, docs []*Document) error {
// Extract text from documents
texts := extractTexts(docs)
// Generate embeddings in batch
embeddings, err := p.provider.GenerateEmbeddings(ctx, texts)
if err != nil {
return err
}
// Attach embeddings to documents
for i, doc := range docs {
doc.Embedding = embeddings[i]
}
return nil
}Critical Performance Optimization: VDB adapters check for pre-generated embeddings and skip regeneration.
Example (src/pkg/vectordb/milvus/document.go:155):
func (a *Adapter) CreateDocuments(ctx context.Context, collection string, docs []*Document) error {
for _, doc := range docs {
// If document already has embedding, skip generation
if len(doc.Embedding) > 0 {
embeddings = append(embeddings, doc.Embedding)
continue
}
// Otherwise generate (legacy path for non-re-embedded docs)
embedding, err := a.llmClient.GenerateEmbedding(ctx, doc.Text, "")
embeddings = append(embeddings, embedding)
}
}This pattern enables:
- 20x faster re-embedding (vs full document re-ingestion)
- Batch processing efficiency (100-500 docs/batch)
- Provider independence (any embedding model works with any VDB)
Critical Fix: Queries now automatically use the collection's embedding model to ensure dimension matching.
Problem Solved: Previously, queries always used OpenAI (1536 dims), causing dimension mismatch errors when collections were re-embedded with OSS models (768 dims).
Solution (src/pkg/vectordb/milvus/query.go):
func (a *Adapter) SearchSemantic(ctx context.Context, collection, query string, ...) {
// Get collection's embedding model from metadata
schema, _ := a.Client.GetSchema(ctx, collection)
embeddingModel := schema.Vectorizer
// Use appropriate provider
if isOpenAI(embeddingModel) {
queryEmbedding = a.llmClient.GenerateEmbedding(ctx, query, "")
} else {
// Use provider factory for OSS models
provider := providers.CreateProvider(ctx, embeddingModel)
queryEmbedding = provider.GenerateEmbedding(ctx, query)
}
// Query with matching dimensions ✅
}Collection Metadata Storage: Vectorizer stored in collection description field:
// Format: "Collection X for vector search | vectorizer=MODEL_NAME"
description := fmt.Sprintf("%s | vectorizer=%s", baseDescription, schema.Vectorizer)Test Collection: 426 auction documents
| Metric | OpenAI | sentence-transformers | Winner |
|---|---|---|---|
| Re-embed Time | ~5+ hours | 85 seconds | ✅ OSS 240x |
| Re-embed Speed | N/A | 308 docs/min | ✅ OSS |
| Quality Score | 0.606 avg | 0.673 avg (+11%) | ✅ OSS |
| Dimensions | 1536 | 768 (50% smaller) | ✅ OSS |
| Cost per 1M tokens | $0.02 | $0.00 | ✅ OSS |
| Query Latency | 1.5s | 7.6s |
Key Finding: OSS embeddings provide better quality with zero cost, 20x faster re-embedding, and 50% smaller vectors. Query latency trade-off (5x slower) acceptable for most use cases.
# List available embedding models
weave embeddings list
# Re-embed with sentence-transformers (OSS)
weave collection re-embed MyCollection \
--new-embedding sentence-transformers/all-mpnet-base-v2 \
--output MyCollection_OSS \
--batch-size 100
# Result: 426/426 documents in 85 seconds ✅
# Query uses collection's embedding model automatically
weave query search MyCollection_OSS "vintage camera" --top-k 5
# Result: 5 results with 0.673 avg quality ✅Core Re-embedding:
src/pkg/reembedding/pipeline.go- Pipeline orchestrationsrc/pkg/reembedding/reader.go- Batch document readingsrc/pkg/reembedding/progress.go- Progress tracking
Provider Implementations:
src/pkg/reembedding/providers/factory.go- Provider factorysrc/pkg/reembedding/providers/openai.go- OpenAI providersrc/pkg/reembedding/providers/sentence_transformers.go- sentence-transformerssrc/pkg/reembedding/providers/ollama.go- Ollama providersrc/pkg/reembedding/providers/interfaces.go- Provider interface
VDB Integration:
src/pkg/vectordb/milvus/document.go- Pre-generated embedding checksrc/pkg/vectordb/milvus/query.go- Query embedding matchingsrc/pkg/vectordb/milvus/collection.go- Vectorizer metadata storage
Command Layer:
src/cmd/collection/re_embed.go- Re-embed commandsrc/cmd/embeddings/list.go- List models command
✅ Cost Savings: $240/year per million documents (OpenAI → OSS) ✅ Performance: 20x faster re-embedding vs full re-ingestion ✅ Quality: Often better than OpenAI (Client0: +11% improvement) ✅ Flexibility: Test different models quickly (minutes, not hours) ✅ Privacy: OSS models run locally, data never leaves infrastructure ✅ No Vendor Lock-in: Switch embedding models freely ✅ Provider Independence: Works with all 10 VDBs ✅ Automatic Query Matching: Queries use collection's model automatically
Each VDB has a dedicated adapter implementing VectorDBClient:
type Adapter struct {
client *nativeClient // VDB-specific SDK client
config *Config
llmClient *llm.OpenAIClient // For embeddings
}
func (a *Adapter) Health(ctx context.Context) error {
// VDB-specific health check
}VDB clients created via factory with automatic registration:
func CreateClient(config *Config) (VectorDBClient, error) {
factory, exists := factories[config.Type]
if !exists {
return nil, ErrUnsupportedVectorDB(config.Type)
}
return factory(config)
}Consistent error handling with context:
func (a *Adapter) CreateCollection(...) error {
if err := validateInput(); err != nil {
return ErrInvalidInput(err)
}
if err := client.Create(); err != nil {
return fmt.Errorf("Qdrant: failed to create collection: %w", err)
}
return nil
}Operation-specific timeouts based on deployment type:
func (a *Adapter) CreateDocument(ctx context.Context, ...) error {
ctx, cancel := context.WithTimeout(ctx,
a.getTimeoutFor(vectordb.OperationTypeDocument))
defer cancel()
// ... operation
}Timeout Values:
- Health: 10s (local) / 20s (cloud)
- Document: 15s / 30s
- Collection: 20s / 40s
- Query: 20s / 40s
- Bulk: 120s / 300s
User Command
↓
CLI Parser (Cobra)
↓
WeaveAgent
├→ QueryAgent (parse natural language)
├→ PlanningAgent (create execution plan)
└→ VectorDBClient
├→ Adapter (VDB-specific)
└→ Native VDB SDK
↓
Vector Database
↓
Results
↓
OutputAgent (format)
↓
Display to User
Document Upload
↓
PDF/Image Processor
├→ Text Extraction
├→ Image Extraction (if PDF)
└→ EXIF Metadata (if image)
↓
LLM Client (OpenAI)
└→ Generate Embeddings
↓
VectorDBClient
└→ CreateDocument(s)
↓
Vector Database
Located in tests/ directory:
- One file per VDB:
tests/weaviate_integration_test.go, etc. - Comprehensive test suites (10-16 tests each)
- Tests skip when VDB not available
- Coverage: Qdrant 50.6% (representative)
Test Categories:
- Health checks
- Collection CRUD
- Document CRUD
- Batch operations
- Semantic search
- BM25 search
- Hybrid search
- Metadata filtering
- Schema operations
- Minimal unit tests in package directories
- Most testing via integration tests with real VDBs
- See
docs/TEST_COVERAGE.mdfor detailed analysis
const (
VectorDBTypeWeaviateCloud = "weaviate-cloud"
VectorDBTypeWeaviateLocal = "weaviate-local"
VectorDBTypeQdrantCloud = "qdrant-cloud"
VectorDBTypeQdrantLocal = "qdrant-local"
VectorDBTypeMilvusCloud = "milvus-cloud"
VectorDBTypeMilvusLocal = "milvus-local"
// ... 20 total types (10 VDBs × 2 deployment types)
)# VDB Connection
WEAVIATE_URL=http://localhost:8080
WEAVIATE_API_KEY=secret
# LLM Integration
OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=sk-ant-...
# Opik Observability
OPIK_API_KEY=...
OPIK_WORKSPACE=default// Connection errors
func ErrConnectionFailed(msg string, err error) error
// Authentication errors
func ErrAuthenticationFailed(msg string) error
// Resource errors
func ErrNotFound(resource, id string) error
// Unsupported operations
func ErrUnsupported(operation string) error
// Configuration errors
func ErrInvalidConfig(msg string) errorAll 10 VDBs provide helpful error messages (v0.8.2):
func (a *Adapter) Health(ctx context.Context) error {
if err := a.client.Ping(); err != nil {
errMsg := err.Error()
if strings.Contains(errMsg, "connection refused") {
return fmt.Errorf("Qdrant: health check failed: %w\n\n"+
"Connection refused. Common causes:\n"+
" 1. Qdrant not running (docker run...)\n"+
" 2. Wrong URL/port in configuration\n"+
" 3. For Qdrant Cloud: verify API key\n"+
" → Check connection at https://cloud.qdrant.io", err)
}
return err
}
}- Operation-specific timeouts prevent false failures
- Cloud deployments get 2x timeout (network latency)
- Bulk operations get 5-10x timeout (large batches)
All VDBs support batch document creation:
CreateDocuments([]*Document)- Single API call- Tests verify actual batch creation (v0.8.2)
- Critical for pipelining workflows
- HTTP-based VDBs: Reuse http.Client
- gRPC-based VDBs: Connection pooling via SDK
- PostgreSQL-based (Supabase): sql.DB connection pool
The embedding pipeline uses a factory pattern to support multiple embedding providers, enabling flexible and cost-effective document vectorization. All providers generate embeddings independently, which are then stored in vector databases.
Key Benefit: Pre-generated embeddings enable 20x faster re-embedding without re-ingestion.
All embedding providers implement the EmbeddingProvider interface:
type EmbeddingProvider interface {
// GenerateEmbedding creates a vector for a single text
GenerateEmbedding(ctx context.Context, text string) ([]float64, error)
// GenerateEmbeddings creates vectors for multiple texts (batch)
GenerateEmbeddings(ctx context.Context, texts []string) ([][]float64, error)
// IsAvailable checks if provider dependencies are installed
IsAvailable(ctx context.Context) error
// GetDimensions returns the embedding vector size
GetDimensions() int
}Location: src/pkg/reembedding/providers/
┌──────────────────────────────────────────────────────────┐
│ Embedding Pipeline │
│ (reembedding/pipeline.go) │
│ • Loads documents from VDB │
│ • Batches for efficiency │
│ • Generates embeddings via provider │
│ • Updates documents with new vectors │
└────────────────────┬─────────────────────────────────────┘
│
┌───────────▼────────────┐
│ Provider Factory │
│ CreateProvider(model) │
│ • Auto-detects type │
│ • Validates available │
└───────────┬─────────────┘
│
┌───────────────┼───────────────┬──────────────┐
│ │ │ │
┌────▼─────┐ ┌─────▼──────┐ ┌────▼──────┐ ┌───▼─────┐
│ OpenAI │ │ sentence- │ │ Ollama │ │ Mock │
│ Provider │ │transformers│ │ Provider │ │Provider │
│ (API) │ │ (Python) │ │ (HTTP) │ │ (Test) │
└────┬─────┘ └─────┬──────┘ └────┬──────┘ └───┬─────┘
│ │ │ │
│ Generates embedding vectors ([]float64) │
│ │ │ │
└──────────────┴───────────────┴──────────────┘
│
┌───────────▼────────────┐
│ Document │
│ .Embedding field │
│ []float64 vector │
│ (384/768/1536 dims) │
└───────────┬────────────┘
│
┌───────────▼────────────┐
│ VDB Adapter │
│ Check: len(emb) > 0? │
│ YES: Use pre-generated│
│ NO: Generate new │
└────────────────────────┘
Models:
text-embedding-3-small(1536 dims) - Fast, cost-effectivetext-embedding-3-large(3072 dims) - Highest qualitytext-embedding-ada-002(1536 dims) - Legacy
Requirements:
OPENAI_API_KEYenvironment variable- Internet connection
Performance: ~200 docs/min, $0.02 per 1M tokens
Implementation: src/pkg/reembedding/providers/openai_provider.go
Models:
sentence-transformers/all-mpnet-base-v2(768 dims) - Best qualitysentence-transformers/all-MiniLM-L6-v2(384 dims) - Fast, lightweight
Requirements:
- Python 3.8+
pip install sentence-transformers
Performance: ~150 docs/min (CPU), faster with GPU
Cost: $0 (open source)
Implementation: src/pkg/reembedding/providers/sentence_transformers_provider.go
How it works:
- Spawns Python subprocess per batch
- Passes texts via stdin (JSON)
- Receives embeddings via stdout
- Handles errors gracefully
Models:
nomic-embed-text(768 dims) - Text embeddingsmxbai-embed-large(1024 dims) - High quality
Requirements:
- Ollama installed and running (
ollama serve) - Model pulled:
ollama pull nomic-embed-text
Performance: ~180 docs/min
Cost: $0 (runs locally)
Implementation: src/pkg/reembedding/providers/ollama_provider.go
How it works:
- HTTP POST to
http://localhost:11434/api/embeddings - Concurrent requests supported by Ollama
- Local processing, no external dependencies
Purpose: Unit testing without real embedding services
Implementation: Returns zero vectors or fixed test vectors
Key Innovation: Documents can carry pre-generated embeddings, enabling fast provider switching.
Example from Milvus (src/pkg/vectordb/milvus/document.go:155):
func (c *Client) CreateDocument(ctx context.Context, collectionName string, doc *vectordb.Document) error {
var embedding []float32
// Check for pre-generated embedding
if len(doc.Embedding) > 0 {
// Use pre-generated embedding
embedding = convertFloat64ToFloat32(doc.Embedding)
} else {
// Generate new embedding using collection's model
embedding64, err := c.generateEmbedding(ctx, collectionName, doc.Content)
if err != nil {
return err
}
embedding = convertFloat64ToFloat32(embedding64)
}
// Insert into Milvus with embedding
return c.insertDocument(ctx, collectionName, doc, embedding)
}All VDB adapters (Weaviate, Qdrant, Chroma, etc.) follow this pattern:
- Check
len(doc.Embedding) > 0 - If yes: Use pre-generated embedding
- If no: Generate using collection's configured model
Command: weave collection reembed
Process:
- Load all documents from collection
- Create embedding provider (new model)
- Generate embeddings in batches
- Update documents with new vectors
- Validate dimensions match
Performance: ~20x faster than re-ingestion (no PDF parsing, OCR, etc.)
Example:
# Re-embed collection with OSS model
weave collection reembed MyCollection \
--new-embedding sentence-transformers/all-mpnet-base-v2 \
--batch-size 100 \
--milvus-local
# Compare quality
weave collection compare MyCollection_OpenAI MyCollection_OSS \
--report comparison.mdFactory auto-detection (src/pkg/reembedding/providers/factory.go):
func CreateProvider(ctx context.Context, modelName string) (EmbeddingProvider, error) {
// OpenAI models
if strings.HasPrefix(modelName, "text-embedding-") {
return NewOpenAIProvider(modelName)
}
// sentence-transformers models
if strings.HasPrefix(modelName, "sentence-transformers/") {
return NewSentenceTransformersProvider(modelName)
}
// Ollama models (check if available)
if provider, err := NewOllamaProvider(modelName); err == nil {
return provider, nil
}
return nil, fmt.Errorf("unknown embedding model: %s", modelName)
}Graceful degradation:
- Python not installed → Clear error message with install instructions
- Ollama not running → Fallback to other providers or error
- API key missing → Helpful error with env var name
Example error messages:
❌ sentence-transformers provider not available
Python package 'sentence-transformers' not found
Install with: pip install sentence-transformers
Or use: --embedding text-embedding-3-small
Batch Processing:
- Default batch size: 100 documents
- sentence-transformers: Processes entire batch in one subprocess
- Ollama: Concurrent HTTP requests
- OpenAI: API batching with rate limiting
Memory Management:
- Streaming for large collections
- Garbage collection between batches
- Progress tracking with time estimates
Unit Tests: src/pkg/reembedding/providers/*_test.go
- Mock provider tests
- Factory creation tests
- Error handling tests
Integration Tests: Require actual providers installed
- Skip tests if provider unavailable
- Marked with build tags
Example test:
func TestSentenceTransformersProvider(t *testing.T) {
if !isSentenceTransformersAvailable() {
t.Skip("sentence-transformers not installed")
}
provider := NewSentenceTransformersProvider("sentence-transformers/all-MiniLM-L6-v2")
embedding, err := provider.GenerateEmbedding(context.Background(), "test text")
assert.NoError(t, err)
assert.Equal(t, 384, len(embedding)) // Correct dimensions
}1 Million Documents Re-embedded Monthly:
| Provider | Monthly Cost | Annual Cost | Quality vs OpenAI |
|---|---|---|---|
| OpenAI text-embedding-3-small | $20 | $240 | 100% (baseline) |
| sentence-transformers all-mpnet-base-v2 | $0 | $0 | 92-95% |
| Ollama nomic-embed-text | $0 | $0 | 90-93% |
Annual Savings: $240/year with 90%+ quality retention
- Hugging Face Inference API support
- Cohere embeddings integration
- Custom model fine-tuning
- Embedding caching layer
- Dimension reduction (PCA, UMAP)
- Create package:
src/pkg/vectordb/newvdb/ - Implement
VectorDBClientinterface via adapter - Register factory:
RegisterFactory("newvdb-local", NewAdapter) - Add config type constant
- Create integration tests
- Add documentation:
docs/newvdb/SETUP.md
Example: See Elasticsearch implementation (v0.8.0)
- Create
src/pkg/agents/new_agent.go - Implement agent interface
- Register with WeaveAgent
- Add prompts in agent file
- CLI:
github.com/spf13/cobra - Config:
github.com/spf13/viper - LLM: OpenAI, Anthropic SDKs
- VDB SDKs: 10 different SDKs (see go.mod)
- Pure Go implementation
- Exception: Chroma (CGO on some platforms, gracefully degrades)
- Weaviate GO-2025-4237: Path traversal vulnerability
- Impact: LOW (weave-cli doesn't use backup functionality)
- Status: Waiting for SDK compatibility with patched version
- Tracked: https://pkg.go.dev/vuln/GO-2025-4237
- Environment variables recommended
- Config files support
${ENV_VAR}syntax - Never commit API keys to git
See docs/TODO_AUDIT.md for planned improvements:
- AWS Signature V4 for OpenSearch
- Enhanced bulk operations
- Advanced query pagination
- Custom TLS configurations
- Main README:
/README.md - VDB Support Matrix:
/docs/VDB_SUPPORT_MATRIX.md - Test Coverage:
/docs/TEST_COVERAGE.md - TODO Audit:
/docs/TODO_AUDIT.md - Per-VDB Docs:
/docs/{vdb}/SETUP.md