Make the chats settings and chat completions route experimental

This commit is contained in:
Kerollmops 2025-05-30 15:56:57 +02:00
parent 0f75ae9f25
commit 85c20447e0
No known key found for this signature in database
GPG Key ID: F250A4C4E3AE5F5F
7 changed files with 37 additions and 3 deletions

View File

@ -131,6 +131,19 @@ impl RoFeatures {
.into())
}
}
pub fn check_chat_completions(&self, disabled_action: &'static str) -> Result<()> {
if self.runtime.chat_completions {
Ok(())
} else {
Err(FeatureNotEnabledError {
disabled_action,
feature: "chat completions",
issue_link: "https://github.com/orgs/meilisearch/discussions/835",
}
.into())
}
}
}
impl FeatureData {

View File

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

View File

@ -197,6 +197,7 @@ struct Infos {
experimental_max_number_of_batched_tasks: usize,
experimental_limit_batched_tasks_total_size: u64,
experimental_network: bool,
experimental_chat_completions: bool,
experimental_get_task_documents_route: bool,
experimental_composite_embedders: bool,
experimental_embedding_cache_entries: usize,
@ -296,6 +297,7 @@ impl Infos {
network,
get_task_documents_route,
composite_embedders,
chat_completions,
} = features;
// We're going to override every sensible information.
@ -314,6 +316,7 @@ impl Infos {
experimental_enable_logs_route: experimental_enable_logs_route | logs_route,
experimental_reduce_indexing_memory_usage,
experimental_network: network,
experimental_chat_completions: chat_completions,
experimental_get_task_documents_route: get_task_documents_route,
experimental_composite_embedders: composite_embedders,
experimental_embedding_cache_entries,

View File

@ -74,9 +74,6 @@ async fn chat(
search_queue: web::Data<SearchQueue>,
web::Json(chat_completion): web::Json<CreateChatCompletionRequest>,
) -> impl Responder {
// To enable later on, when the feature will be experimental
// index_scheduler.features().check_chat("Using the /chat route")?;
let ChatsParam { workspace_uid } = chats_param.into_inner();
assert_eq!(
@ -317,6 +314,7 @@ async fn non_streamed_chat(
req: HttpRequest,
mut chat_completion: CreateChatCompletionRequest,
) -> Result<HttpResponse, ResponseError> {
index_scheduler.features().check_chat_completions("Using the /chats chat completions route")?;
let filters = index_scheduler.filters();
let rtxn = index_scheduler.read_txn()?;
@ -414,6 +412,7 @@ async fn streamed_chat(
req: HttpRequest,
mut chat_completion: CreateChatCompletionRequest,
) -> Result<impl Responder, ResponseError> {
index_scheduler.features().check_chat_completions("Using the /chats chat completions route")?;
let filters = index_scheduler.filters();
let rtxn = index_scheduler.read_txn()?;

View File

@ -70,6 +70,8 @@ pub async fn list_workspaces(
index_scheduler: GuardedData<ActionPolicy<{ actions::CHATS_GET }>, Data<IndexScheduler>>,
paginate: AwebQueryParameter<ListChats, DeserrQueryParamError>,
) -> Result<HttpResponse, ResponseError> {
index_scheduler.features().check_chat_completions("Using the /chats settings route")?;
debug!(parameters = ?paginate, "List chat workspaces");
let filters = index_scheduler.filters();
let (total, workspaces) = index_scheduler.paginated_chat_workspace_uids(

View File

@ -38,6 +38,8 @@ async fn get_settings(
>,
chats_param: web::Path<ChatsParam>,
) -> Result<HttpResponse, ResponseError> {
index_scheduler.features().check_chat_completions("Using the /chats settings route")?;
let ChatsParam { workspace_uid } = chats_param.into_inner();
// TODO do a spawn_blocking here ???
@ -63,6 +65,7 @@ async fn patch_settings(
chats_param: web::Path<ChatsParam>,
web::Json(new): web::Json<GlobalChatSettings>,
) -> Result<HttpResponse, ResponseError> {
index_scheduler.features().check_chat_completions("Using the /chats settings route")?;
let ChatsParam { workspace_uid } = chats_param.into_inner();
// TODO do a spawn_blocking here
@ -143,6 +146,8 @@ async fn delete_settings(
>,
chats_param: web::Path<ChatsParam>,
) -> Result<HttpResponse, ResponseError> {
index_scheduler.features().check_chat_completions("Using the /chats settings route")?;
let ChatsParam { workspace_uid } = chats_param.into_inner();
// TODO do a spawn_blocking here

View File

@ -53,6 +53,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
network: Some(false),
get_task_documents_route: Some(false),
composite_embedders: Some(false),
chat_completions: Some(false),
})),
(status = 401, description = "The authorization header is missing", body = ResponseError, content_type = "application/json", example = json!(
{
@ -97,6 +98,8 @@ pub struct RuntimeTogglableFeatures {
pub get_task_documents_route: Option<bool>,
#[deserr(default)]
pub composite_embedders: Option<bool>,
#[deserr(default)]
pub chat_completions: Option<bool>,
}
impl From<meilisearch_types::features::RuntimeTogglableFeatures> for RuntimeTogglableFeatures {
@ -109,6 +112,7 @@ impl From<meilisearch_types::features::RuntimeTogglableFeatures> for RuntimeTogg
network,
get_task_documents_route,
composite_embedders,
chat_completions,
} = value;
Self {
@ -119,6 +123,7 @@ impl From<meilisearch_types::features::RuntimeTogglableFeatures> for RuntimeTogg
network: Some(network),
get_task_documents_route: Some(get_task_documents_route),
composite_embedders: Some(composite_embedders),
chat_completions: Some(chat_completions),
}
}
}
@ -132,6 +137,7 @@ pub struct PatchExperimentalFeatureAnalytics {
network: bool,
get_task_documents_route: bool,
composite_embedders: bool,
chat_completions: bool,
}
impl Aggregate for PatchExperimentalFeatureAnalytics {
@ -148,6 +154,7 @@ impl Aggregate for PatchExperimentalFeatureAnalytics {
network: new.network,
get_task_documents_route: new.get_task_documents_route,
composite_embedders: new.composite_embedders,
chat_completions: new.chat_completions,
})
}
@ -173,6 +180,7 @@ impl Aggregate for PatchExperimentalFeatureAnalytics {
network: Some(false),
get_task_documents_route: Some(false),
composite_embedders: Some(false),
chat_completions: Some(false),
})),
(status = 401, description = "The authorization header is missing", body = ResponseError, content_type = "application/json", example = json!(
{
@ -214,6 +222,7 @@ async fn patch_features(
.0
.composite_embedders
.unwrap_or(old_features.composite_embedders),
chat_completions: new_features.0.chat_completions.unwrap_or(old_features.chat_completions),
};
// explicitly destructure for analytics rather than using the `Serialize` implementation, because
@ -227,6 +236,7 @@ async fn patch_features(
network,
get_task_documents_route,
composite_embedders,
chat_completions,
} = new_features;
analytics.publish(
@ -238,6 +248,7 @@ async fn patch_features(
network,
get_task_documents_route,
composite_embedders,
chat_completions,
},
&req,
);