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}