Skip to main content

daimon_plugin_opensearch/
lib.rs

1//! # daimon-plugin-opensearch
2//!
3//! An OpenSearch k-NN backed [`VectorStore`](daimon_core::VectorStore) plugin
4//! for the [Daimon](https://docs.rs/daimon) AI agent framework.
5//!
6//! This crate provides [`OpenSearchVectorStore`], which stores document
7//! embeddings in [OpenSearch](https://opensearch.org/) using its native
8//! [k-NN plugin](https://opensearch.org/docs/latest/search-plugins/knn/index/).
9//! It supports cosine similarity, L2 (euclidean), and inner product distance
10//! metrics with HNSW indexing via nmslib, faiss, or lucene engines.
11//!
12//! ## Quick Start
13//!
14//! ```ignore
15//! use daimon_plugin_opensearch::{OpenSearchVectorStoreBuilder, SpaceType, Engine};
16//! use daimon::retriever::SimpleKnowledgeBase;
17//! use std::sync::Arc;
18//!
19//! let store = OpenSearchVectorStoreBuilder::new("http://localhost:9200", 1536)
20//!     .index("my_docs")
21//!     .space_type(SpaceType::CosineSimilarity)
22//!     .engine(Engine::Lucene)
23//!     .build()
24//!     .await?;
25//!
26//! // Compose with an embedding model for a full RAG pipeline:
27//! let kb = SimpleKnowledgeBase::new(embedding_model, store);
28//! ```
29//!
30//! ## Manual Index Setup
31//!
32//! If you prefer to manage index creation yourself, disable auto-creation
33//! and use the JSON from [`index_settings`]:
34//!
35//! ```ignore
36//! let store = OpenSearchVectorStoreBuilder::new(url, 1536)
37//!     .auto_create_index(false)
38//!     .build()
39//!     .await?;
40//! ```
41//!
42//! ## AWS OpenSearch Service
43//!
44//! Enable the `aws-auth` feature for SigV4 authentication:
45//!
46//! ```toml
47//! daimon-plugin-opensearch = { version = "0.17", features = ["aws-auth"] }
48//! ```
49
50mod builder;
51pub mod index_settings;
52mod store;
53
54pub use builder::OpenSearchVectorStoreBuilder;
55pub use store::OpenSearchVectorStore;
56
57/// Distance metric / space type for k-NN vector search.
58#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
59pub enum SpaceType {
60    /// Cosine similarity. Best for normalized embeddings.
61    #[default]
62    CosineSimilarity,
63    /// Euclidean (L2) distance. Best for absolute spatial similarity.
64    L2,
65    /// Inner product. Best for maximum inner product search (MIPS).
66    InnerProduct,
67}
68
69impl SpaceType {
70    /// Returns the OpenSearch space type string used in index mappings.
71    pub fn as_str(&self) -> &'static str {
72        match self {
73            Self::CosineSimilarity => "cosinesimil",
74            Self::L2 => "l2",
75            Self::InnerProduct => "innerproduct",
76        }
77    }
78}
79
80/// k-NN engine used for approximate nearest neighbor search.
81#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
82pub enum Engine {
83    /// Apache Lucene engine. Good default, supports all space types.
84    #[default]
85    Lucene,
86    /// NMSLIB engine. High performance for cosine and L2.
87    Nmslib,
88    /// FAISS engine. Supports IVF and HNSW, GPU-accelerated options.
89    Faiss,
90}
91
92impl Engine {
93    /// Returns the OpenSearch engine string used in index mappings.
94    pub fn as_str(&self) -> &'static str {
95        match self {
96            Self::Lucene => "lucene",
97            Self::Nmslib => "nmslib",
98            Self::Faiss => "faiss",
99        }
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    use super::*;
106
107    #[test]
108    fn test_space_type_as_str() {
109        assert_eq!(SpaceType::CosineSimilarity.as_str(), "cosinesimil");
110        assert_eq!(SpaceType::L2.as_str(), "l2");
111        assert_eq!(SpaceType::InnerProduct.as_str(), "innerproduct");
112    }
113
114    #[test]
115    fn test_space_type_default() {
116        assert_eq!(SpaceType::default(), SpaceType::CosineSimilarity);
117    }
118
119    #[test]
120    fn test_engine_as_str() {
121        assert_eq!(Engine::Lucene.as_str(), "lucene");
122        assert_eq!(Engine::Nmslib.as_str(), "nmslib");
123        assert_eq!(Engine::Faiss.as_str(), "faiss");
124    }
125
126    #[test]
127    fn test_engine_default() {
128        assert_eq!(Engine::default(), Engine::Lucene);
129    }
130}