Make composite embedders experimental

This commit is contained in:
Louis Dureuil 2025-03-10 14:22:47 +01:00
parent 9a282be0a2
commit 54ee81bb09
No known key found for this signature in database
4 changed files with 50 additions and 1 deletions

View File

@ -118,6 +118,19 @@ impl RoFeatures {
.into()) .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 { impl FeatureData {

View File

@ -11,6 +11,7 @@ pub struct RuntimeTogglableFeatures {
pub contains_filter: bool, pub contains_filter: bool,
pub network: bool, pub network: bool,
pub get_task_documents_route: bool, pub get_task_documents_route: bool,
pub composite_embedders: bool,
} }
#[derive(Default, Debug, Clone, Copy)] #[derive(Default, Debug, Clone, Copy)]

View File

@ -52,6 +52,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
contains_filter: Some(false), contains_filter: Some(false),
network: Some(false), network: Some(false),
get_task_documents_route: 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!( (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<bool>, pub network: Option<bool>,
#[deserr(default)] #[deserr(default)]
pub get_task_documents_route: Option<bool>, pub get_task_documents_route: Option<bool>,
#[deserr(default)]
pub composite_embedders: Option<bool>,
} }
impl From<meilisearch_types::features::RuntimeTogglableFeatures> for RuntimeTogglableFeatures { impl From<meilisearch_types::features::RuntimeTogglableFeatures> for RuntimeTogglableFeatures {
@ -105,6 +108,7 @@ impl From<meilisearch_types::features::RuntimeTogglableFeatures> for RuntimeTogg
contains_filter, contains_filter,
network, network,
get_task_documents_route, get_task_documents_route,
composite_embedders,
} = value; } = value;
Self { Self {
@ -114,6 +118,7 @@ impl From<meilisearch_types::features::RuntimeTogglableFeatures> for RuntimeTogg
contains_filter: Some(contains_filter), contains_filter: Some(contains_filter),
network: Some(network), network: Some(network),
get_task_documents_route: Some(get_task_documents_route), get_task_documents_route: Some(get_task_documents_route),
composite_embedders: Some(composite_embedders),
} }
} }
} }
@ -202,6 +207,10 @@ async fn patch_features(
.0 .0
.get_task_documents_route .get_task_documents_route
.unwrap_or(old_features.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 // explicitly destructure for analytics rather than using the `Serialize` implementation, because
@ -214,6 +223,7 @@ async fn patch_features(
contains_filter, contains_filter,
network, network,
get_task_documents_route, get_task_documents_route,
composite_embedders,
} = new_features; } = new_features;
analytics.publish( analytics.publish(

View File

@ -716,7 +716,32 @@ pub async fn delete_all(
fn validate_settings( fn validate_settings(
settings: Settings<Unchecked>, settings: Settings<Unchecked>,
_index_scheduler: &IndexScheduler, index_scheduler: &IndexScheduler,
) -> Result<Settings<Unchecked>, ResponseError> { ) -> Result<Settings<Unchecked>, 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()?) Ok(settings.validate()?)
} }