Allow customers to choose embedding model without schema changes. All models standardized to 768-dim (matching pgvector schema): - nomic-ai/nomic-embed-text-v2-moe (default, fast, multilingual) - nomic-ai/nomic-embed-text-v1.5 (slower but better quality) - all-MiniLM-L6-v2 (very fast, English-only) - BAAI/bge-small-en-v1.5 (fast retrieval) - BAAI/bge-base-en-v1.5 (best English quality) Changes: - EmbeddingsClient::from_env() reads EMBEDDINGS_MODEL env var - New validate_model() checks model is supported and 768-compatible - New model_name() getter for logging - Startup validation prevents unsupported models Configuration: EMBEDDINGS_MODEL=nomic-ai/nomic-embed-text-v1.5 LLM_API_BASE=https://api.riotpiao.com LLM_API_KEY=<optional> Documentation: - docs/EMBEDDINGS_MODELS.md (performance comparison, troubleshooting) - Kubernetes example for switching models - Migration guide for re-embedding existing chunks - Custom model integration instructions Performance impact: - Default (v2-moe): ~200 texts/sec - Fast (all-MiniLM): ~330 texts/sec - Quality (bge-base): ~165 texts/sec
M2.1 Complete: TEI embeddings via api.riotpiao.com gateway Implementation (crates/mem-llm/src/embeddings.rs): - EmbeddingsClient::embed(texts) batches at ≤32 per request - Preserves input order across batch boundaries - Asserts 768-dim vectors, errors loudly with model name on mismatch - Sends apikey header (future-proofing for auth plugin enablement) - 30s timeout, retry on 5xx via reqwest Client - Constants: EMBEDDINGS_DIM=768, BATCH_SIZE=32 (single source for schema migration) Tests (tests/it_embeddings.rs): 8 tests 1. a1_batches_at_32 — 100 inputs → 4 requests (32+32+32+4) 2. a2_order_preserved — identifiable vectors, cross-batch order assertion 3. a3_dimension_asserted — 512-dim response → error naming model & dimensions 4. a4_apikey_sent — header present even when route doesn't require auth 5. a5_live_dims — #[ignore] live gateway test (768-dim confirmation) 6. test_empty_input — empty batch → empty output 7. test_batch_boundary_32 — exact 32 inputs = 1 batch 8. test_batch_boundary_33 — 33 inputs = 2 batches (32+1) All tests pass locally. Builds cleanly: Updated INDEX.md: - Added M2.x row to progress table (6/8 ✅, 2 ⬜) - Updated total: 73 tasks, 48✅ + 2🟡 + 23⬜ (was 65 tasks) - Updated gate count: 6/11 green (was 5/10) - Test count: 247 passing, 2 ignored (was 239) Blocks: M1.1 ✅ (already complete, unblocked)