pub mod database;
pub mod graph;
pub mod search;
#[allow(deprecated)]
pub use database::{
batch_cosine_similarity, cosine_similarity, dot_product, euclidean_distance, normalize_vector,
top_k_similar, VectorDatabase, VectorDatabaseStats, VectorSearchResult, DEFAULT_SEARCH_LIMIT,
DEFAULT_SIMILARITY_THRESHOLD,
};
pub use graph::{GraphNode, GraphNode as Node, GraphTree, NodeType, TreeNode, TreeStats};
pub use search::{SearchOptions, SearchResult, SemanticSearch};
use serde::{Deserialize, Serialize};
pub type Result<T> = std::result::Result<T, nexus_core::NexusError>;
pub const EMBEDDING_DIMENSION: usize = 384;
pub type Embedding = Vec<f32>;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct VectorEntry {
pub id: i64,
pub embedding: Embedding,
pub category: String,
pub memory_lane_type: Option<String>,
pub namespace_id: i64,
pub created_at: chrono::DateTime<chrono::Utc>,
}
impl VectorEntry {
pub fn new(id: i64, embedding: Embedding, category: String, namespace_id: i64) -> Self {
Self {
id,
embedding,
category,
memory_lane_type: None,
namespace_id,
created_at: chrono::Utc::now(),
}
}
pub fn with_memory_lane_type(mut self, memory_lane_type: impl Into<String>) -> Self {
self.memory_lane_type = Some(memory_lane_type.into());
self
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct SearchLatency {
pub total_ms: u64,
pub vector_comparison_ms: u64,
pub graph_traversal_ms: Option<u64>,
}
impl SearchLatency {
pub fn meets_target(&self) -> bool {
self.total_ms < 10
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_vector_entry_new() {
let embedding = vec![0.1; EMBEDDING_DIMENSION];
let entry = VectorEntry::new(1, embedding.clone(), "general".to_string(), 1);
assert_eq!(entry.id, 1);
assert_eq!(entry.embedding, embedding);
assert_eq!(entry.category, "general");
assert_eq!(entry.namespace_id, 1);
assert!(entry.memory_lane_type.is_none());
}
#[test]
fn test_vector_entry_with_memory_lane_type() {
let embedding = vec![0.1; EMBEDDING_DIMENSION];
let entry = VectorEntry::new(1, embedding, "general".to_string(), 1)
.with_memory_lane_type("correction");
assert_eq!(entry.memory_lane_type, Some("correction".to_string()));
}
#[test]
fn test_search_latency_meets_target() {
let good = SearchLatency {
total_ms: 5,
vector_comparison_ms: 3,
graph_traversal_ms: Some(1),
};
assert!(good.meets_target());
let bad = SearchLatency {
total_ms: 15,
vector_comparison_ms: 10,
graph_traversal_ms: Some(4),
};
assert!(!bad.meets_target());
}
}