Skip to main content

coding_agent_search/search/
fastembed_reranker.rs

1//! FastEmbed-based cross-encoder reranker (ms-marco-MiniLM-L-6-v2).
2//!
3//! Re-exports [`FastEmbedReranker`] from `frankensearch::rerank::fastembed_reranker`.
4//! The implementation lives in the `frankensearch-rerank` crate.
5//!
6//! # `semantic` feature gate (cass#256)
7//!
8//! When the `semantic` Cargo feature is **disabled** (i.e. baseline build), the
9//! upstream `frankensearch::FastEmbedReranker` is not available because
10//! `frankensearch/fastembed-reranker` is the feature path that drags in
11//! `fastembed` and the prebuilt Microsoft ONNX Runtime binary. In that build a
12//! local stub `FastEmbedReranker` is exposed: it has the same public surface
13//! the rest of the crate relies on (`default_model_dir`, `load_from_dir`,
14//! `reranker_id_static`) but the loader returns a stable
15//! `RerankerError::RerankerUnavailable` and the reranker cannot be
16//! instantiated. Lexical search remains fully available.
17
18#[cfg(feature = "semantic")]
19pub use frankensearch::FastEmbedReranker;
20
21#[cfg(not(feature = "semantic"))]
22pub use stub::FastEmbedReranker;
23
24#[cfg(not(feature = "semantic"))]
25mod stub {
26    use std::path::{Path, PathBuf};
27
28    use crate::search::reranker::{Reranker, RerankerError, RerankerResult};
29    use frankensearch::{RerankDocument, RerankScore};
30
31    const MS_MARCO_RERANKER_ID: &str = "ms-marco-minilm-l6-v2";
32    const MS_MARCO_DIR_NAME: &str = "ms-marco-MiniLM-L-6-v2";
33
34    /// Baseline-build stub for the cross-encoder reranker.
35    ///
36    /// `FastEmbedReranker` cannot actually be instantiated in this build -
37    /// [`load_from_dir`] always returns `RerankerError::RerankerUnavailable`.
38    /// The struct and `Reranker` impl exist purely so existing
39    /// `Arc<dyn Reranker>` plumbing (`reranker_registry`, `daemon::models`, etc.)
40    /// keeps compiling.
41    pub struct FastEmbedReranker {
42        _private: (),
43    }
44
45    impl FastEmbedReranker {
46        /// Stable reranker identifier (matches the upstream constant so
47        /// metadata/JSON contracts remain stable across baseline and full
48        /// builds).
49        pub fn reranker_id_static() -> &'static str {
50            MS_MARCO_RERANKER_ID
51        }
52
53        /// Default model directory relative to the cass data dir. Mirrors
54        /// the layout used by the full build so the model_manager's
55        /// "is this on disk?" probes return the same answer either way.
56        pub fn default_model_dir(data_dir: &Path) -> PathBuf {
57            data_dir.join("models").join(MS_MARCO_DIR_NAME)
58        }
59
60        /// Baseline-build stub: see the module-level note on cass#256.
61        pub fn load_from_dir(_model_dir: &Path) -> RerankerResult<Self> {
62            Err(RerankerError::RerankerUnavailable {
63                model: MS_MARCO_RERANKER_ID.to_string(),
64            })
65        }
66    }
67
68    impl Reranker for FastEmbedReranker {
69        fn rerank_sync(
70            &self,
71            _query: &str,
72            _documents: &[RerankDocument],
73        ) -> RerankerResult<Vec<RerankScore>> {
74            Err(RerankerError::RerankerUnavailable {
75                model: MS_MARCO_RERANKER_ID.to_string(),
76            })
77        }
78
79        fn id(&self) -> &str {
80            MS_MARCO_RERANKER_ID
81        }
82
83        fn model_name(&self) -> &str {
84            MS_MARCO_DIR_NAME
85        }
86
87        fn is_available(&self) -> bool {
88            false
89        }
90    }
91}