Skip to main content

mem7_vector/
lib.rs

1mod distance;
2mod filter;
3mod flat;
4mod upstash;
5
6pub use distance::DistanceMetric;
7pub use flat::FlatIndex;
8pub use upstash::UpstashVectorIndex;
9
10use std::sync::Arc;
11
12use async_trait::async_trait;
13use mem7_config::VectorConfig;
14use mem7_core::MemoryFilter;
15use mem7_error::{Mem7Error, Result};
16use tracing::info;
17use uuid::Uuid;
18
19/// A vector search result entry.
20#[derive(Debug, Clone)]
21pub struct VectorSearchResult {
22    pub id: Uuid,
23    pub score: f32,
24    pub payload: serde_json::Value,
25}
26
27/// Trait for vector index implementations.
28#[async_trait]
29pub trait VectorIndex: Send + Sync {
30    async fn insert(&self, id: Uuid, vector: &[f32], payload: serde_json::Value) -> Result<()>;
31    async fn search(
32        &self,
33        query: &[f32],
34        limit: usize,
35        filters: Option<&MemoryFilter>,
36    ) -> Result<Vec<VectorSearchResult>>;
37    async fn delete(&self, id: &Uuid) -> Result<()>;
38    async fn update(
39        &self,
40        id: &Uuid,
41        vector: Option<&[f32]>,
42        payload: Option<serde_json::Value>,
43    ) -> Result<()>;
44    async fn get(&self, id: &Uuid) -> Result<Option<(Vec<f32>, serde_json::Value)>>;
45    async fn list(
46        &self,
47        filters: Option<&MemoryFilter>,
48        limit: Option<usize>,
49    ) -> Result<Vec<(Uuid, serde_json::Value)>>;
50    async fn reset(&self) -> Result<()>;
51}
52
53/// Create a vector index from config.
54pub fn create_vector_index(config: &VectorConfig) -> Result<Arc<dyn VectorIndex>> {
55    match config.provider.as_str() {
56        "upstash" => {
57            let url = config
58                .upstash_url
59                .as_deref()
60                .ok_or_else(|| Mem7Error::Config("upstash_url is required".into()))?;
61            let token = config
62                .upstash_token
63                .as_deref()
64                .ok_or_else(|| Mem7Error::Config("upstash_token is required".into()))?;
65            info!(namespace = %config.collection_name, "using Upstash Vector");
66            Ok(Arc::new(UpstashVectorIndex::new(
67                url,
68                token,
69                &config.collection_name,
70            )))
71        }
72        "flat" | "" => {
73            info!("using in-memory FlatIndex");
74            Ok(Arc::new(FlatIndex::new(DistanceMetric::Cosine)))
75        }
76        other => Err(Mem7Error::Config(format!(
77            "unknown vector store provider: {other}"
78        ))),
79    }
80}