feat(memory): embedders vectoriels réels HTTP + ONNX derrière features (LOT C1)
Remplace les StubEmbedder pour les stratégies localServer/api/localOnnx par de vrais moteurs, chacun derrière une feature cargo off-by-default — la posture fondatrice « rien d'imposé, zéro dépendance » (défaut none → rappel naïf) reste byte-for-byte inchangée. C1a (feature vector-http, reqwest rustls optional): - HttpEmbedder couvrant localServer (Ollama/llama.cpp) et api (OpenAI/Voyage…), payload OpenAI-compatible /v1/embeddings, ordre restauré par index, bearer token lu via env var (jamais en clair), timeout client 30s. - detect_ollama() pour la détection de l'existant (C3). C1b (feature vector-onnx, fastembed v5 optional): - OnnxEmbedder en-process (e5-small, dim 384), init paresseuse + spawn_blocking, cache modèle sous <app_data>/embedders/onnx — aucun download au build ni au first-run, uniquement à la demande au 1er embed. - Catalogue RECOMMENDED_ONNX_MODELS + ONNX_CACHE_SUBDIR + onnx_model_is_cached exposés (sans feature) pour la config (C2) et la popup (C3). embedder_from_profile(profile, onnx_cache_dir) dispatche feature-gated ; sans la feature, retombe sur StubEmbedder (Unsupported) → fallback naïf via AdaptiveMemoryRecall. Composition root (build_memory_recall) propage le cache dir. Tests: 10 HTTP + 6 ONNX (dont 2 #[ignore] download réel) + 26 vectoriels, verts en défaut, --features vector-http et --features vector-onnx. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -31,6 +31,12 @@ serde_json = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
uuid = { workspace = true }
|
||||
|
||||
[features]
|
||||
# Passthrough toggles to enable the real embedders in an IDE build. OFF by default
|
||||
# (founding posture: `none` ⇒ naïve recall, zero dependency).
|
||||
vector-http = ["infrastructure/vector-http"]
|
||||
vector-onnx = ["infrastructure/vector-onnx"]
|
||||
|
||||
[dev-dependencies]
|
||||
uuid = { workspace = true }
|
||||
async-trait = { workspace = true }
|
||||
|
||||
@ -35,7 +35,7 @@ use infrastructure::{
|
||||
FsEmbedderProfileStore, FsMemoryStore, FsOrchestratorWatcher, FsProfileStore, FsProjectStore,
|
||||
FsSkillStore, FsTemplateStore, Git2Repository, IdeaiContextStore, LocalFileSystem,
|
||||
LocalProcessSpawner, NaiveMemoryRecall, OrchestratorWatchHandle, PortablePtyAdapter,
|
||||
SystemClock, TokioBroadcastEventBus, UuidGenerator, VectorMemoryRecall,
|
||||
SystemClock, TokioBroadcastEventBus, UuidGenerator, VectorMemoryRecall, ONNX_CACHE_SUBDIR,
|
||||
};
|
||||
|
||||
use crate::pty::PtyBridge;
|
||||
@ -393,10 +393,12 @@ impl AppState {
|
||||
.flatten()
|
||||
})
|
||||
.unwrap_or_else(EmbedderProfile::none);
|
||||
let onnx_cache_dir = app_data_dir.join(ONNX_CACHE_SUBDIR);
|
||||
let memory_recall_port = build_memory_recall(
|
||||
Arc::clone(&fs_port),
|
||||
Arc::clone(&memory_store_port),
|
||||
&embedder_profile,
|
||||
&onnx_cache_dir,
|
||||
);
|
||||
|
||||
let create_agent = Arc::new(CreateAgentFromScratch::new(
|
||||
@ -711,9 +713,10 @@ pub(crate) fn build_memory_recall(
|
||||
fs: Arc<dyn FileSystem>,
|
||||
store: Arc<dyn MemoryStore>,
|
||||
profile: &EmbedderProfile,
|
||||
onnx_cache_dir: &std::path::Path,
|
||||
) -> Arc<dyn MemoryRecall> {
|
||||
let naive = Arc::new(NaiveMemoryRecall::new(Arc::clone(&store))) as Arc<dyn MemoryRecall>;
|
||||
match embedder_from_profile(profile) {
|
||||
match embedder_from_profile(profile, onnx_cache_dir) {
|
||||
None => naive,
|
||||
Some(embedder) => {
|
||||
let embedder: Arc<dyn Embedder> = Arc::from(embedder);
|
||||
@ -839,7 +842,12 @@ mod tests {
|
||||
async fn build_memory_recall_none_profile_matches_naive_recall() {
|
||||
let (fs, store) = seed_store().await;
|
||||
|
||||
let wired = build_memory_recall(Arc::clone(&fs), Arc::clone(&store), &EmbedderProfile::none());
|
||||
let wired = build_memory_recall(
|
||||
Arc::clone(&fs),
|
||||
Arc::clone(&store),
|
||||
&EmbedderProfile::none(),
|
||||
std::path::Path::new("/unused-onnx-cache"),
|
||||
);
|
||||
let naive = NaiveMemoryRecall::new(Arc::clone(&store));
|
||||
|
||||
// 0 ⇒ empty; mid budgets ⇒ partial truncation; huge ⇒ full index order.
|
||||
|
||||
Reference in New Issue
Block a user