From 54ee81bb09549ae5b41126c36e648fa635037348 Mon Sep 17 00:00:00 2001 From: Louis Dureuil Date: Mon, 10 Mar 2025 14:22:47 +0100 Subject: [PATCH] Make composite embedders experimental --- crates/index-scheduler/src/features.rs | 13 +++++++++ crates/meilisearch-types/src/features.rs | 1 + crates/meilisearch/src/routes/features.rs | 10 +++++++ .../src/routes/indexes/settings.rs | 27 ++++++++++++++++++- 4 files changed, 50 insertions(+), 1 deletion(-) diff --git a/crates/index-scheduler/src/features.rs b/crates/index-scheduler/src/features.rs index 394e6518f..b52b194e6 100644 --- a/crates/index-scheduler/src/features.rs +++ b/crates/index-scheduler/src/features.rs @@ -118,6 +118,19 @@ impl RoFeatures { .into()) } } + + pub fn check_composite_embedders(&self, disabled_action: &'static str) -> Result<()> { + if self.runtime.composite_embedders { + Ok(()) + } else { + Err(FeatureNotEnabledError { + disabled_action, + feature: "composite embedders", + issue_link: "https://github.com/orgs/meilisearch/discussions/816", + } + .into()) + } + } } impl FeatureData { diff --git a/crates/meilisearch-types/src/features.rs b/crates/meilisearch-types/src/features.rs index 37a504039..5db8775b6 100644 --- a/crates/meilisearch-types/src/features.rs +++ b/crates/meilisearch-types/src/features.rs @@ -11,6 +11,7 @@ pub struct RuntimeTogglableFeatures { pub contains_filter: bool, pub network: bool, pub get_task_documents_route: bool, + pub composite_embedders: bool, } #[derive(Default, Debug, Clone, Copy)] diff --git a/crates/meilisearch/src/routes/features.rs b/crates/meilisearch/src/routes/features.rs index 402bc11ae..6ddda7115 100644 --- a/crates/meilisearch/src/routes/features.rs +++ b/crates/meilisearch/src/routes/features.rs @@ -52,6 +52,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) { contains_filter: Some(false), network: Some(false), get_task_documents_route: Some(false), + composite_embedders: Some(false), })), (status = 401, description = "The authorization header is missing", body = ResponseError, content_type = "application/json", example = json!( { @@ -94,6 +95,8 @@ pub struct RuntimeTogglableFeatures { pub network: Option, #[deserr(default)] pub get_task_documents_route: Option, + #[deserr(default)] + pub composite_embedders: Option, } impl From for RuntimeTogglableFeatures { @@ -105,6 +108,7 @@ impl From for RuntimeTogg contains_filter, network, get_task_documents_route, + composite_embedders, } = value; Self { @@ -114,6 +118,7 @@ impl From for RuntimeTogg contains_filter: Some(contains_filter), network: Some(network), get_task_documents_route: Some(get_task_documents_route), + composite_embedders: Some(composite_embedders), } } } @@ -202,6 +207,10 @@ async fn patch_features( .0 .get_task_documents_route .unwrap_or(old_features.get_task_documents_route), + composite_embedders: new_features + .0 + .composite_embedders + .unwrap_or(old_features.composite_embedders), }; // explicitly destructure for analytics rather than using the `Serialize` implementation, because @@ -214,6 +223,7 @@ async fn patch_features( contains_filter, network, get_task_documents_route, + composite_embedders, } = new_features; analytics.publish( diff --git a/crates/meilisearch/src/routes/indexes/settings.rs b/crates/meilisearch/src/routes/indexes/settings.rs index ad76b3f42..369d71211 100644 --- a/crates/meilisearch/src/routes/indexes/settings.rs +++ b/crates/meilisearch/src/routes/indexes/settings.rs @@ -716,7 +716,32 @@ pub async fn delete_all( fn validate_settings( settings: Settings, - _index_scheduler: &IndexScheduler, + index_scheduler: &IndexScheduler, ) -> Result, ResponseError> { + use meilisearch_types::milli::update::Setting; + use meilisearch_types::milli::vector::settings::EmbedderSource; + + let features = index_scheduler.features(); + if let Setting::Set(embedders) = &settings.embedders { + for SettingEmbeddingSettings { inner: embedder } in embedders.values() { + let Setting::Set(embedder) = embedder else { + continue; + }; + if let Setting::Set(source) = embedder.source { + if source == EmbedderSource::Composite { + features.check_composite_embedders("using `\"composite\"` as source")?; + } + } + + if let Setting::Set(_) = &embedder.search_embedder { + features.check_composite_embedders("setting `searchEmbedder`")?; + } + + if let Setting::Set(_) = &embedder.indexing_embedder { + features.check_composite_embedders("setting `indexingEmbedder`")?; + } + } + } + Ok(settings.validate()?) }