mirror of
https://github.com/meilisearch/MeiliSearch
synced 2025-07-03 11:57:07 +02:00
Improve the chat workspace REST endpoints
This commit is contained in:
parent
bc56087a17
commit
e654eddf56
5 changed files with 72 additions and 19 deletions
|
@ -55,7 +55,7 @@ use meilisearch_types::features::{
|
||||||
ChatCompletionSettings, InstanceTogglableFeatures, Network, RuntimeTogglableFeatures,
|
ChatCompletionSettings, InstanceTogglableFeatures, Network, RuntimeTogglableFeatures,
|
||||||
};
|
};
|
||||||
use meilisearch_types::heed::byteorder::BE;
|
use meilisearch_types::heed::byteorder::BE;
|
||||||
use meilisearch_types::heed::types::{SerdeJson, Str, I128};
|
use meilisearch_types::heed::types::{DecodeIgnore, SerdeJson, Str, I128};
|
||||||
use meilisearch_types::heed::{self, Database, Env, RoTxn, RwTxn, WithoutTls};
|
use meilisearch_types::heed::{self, Database, Env, RoTxn, RwTxn, WithoutTls};
|
||||||
use meilisearch_types::milli::index::IndexEmbeddingConfig;
|
use meilisearch_types::milli::index::IndexEmbeddingConfig;
|
||||||
use meilisearch_types::milli::update::IndexerConfig;
|
use meilisearch_types::milli::update::IndexerConfig;
|
||||||
|
@ -904,6 +904,12 @@ impl IndexScheduler {
|
||||||
self.chat_settings.get(rtxn, uid).map_err(Into::into)
|
self.chat_settings.get(rtxn, uid).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return true if chat workspace exists.
|
||||||
|
pub fn chat_workspace_exists(&self, name: &str) -> Result<bool> {
|
||||||
|
let rtxn = self.env.read_txn()?;
|
||||||
|
Ok(self.chat_settings.remap_data_type::<DecodeIgnore>().get(&rtxn, name)?.is_some())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn put_chat_settings(
|
pub fn put_chat_settings(
|
||||||
&self,
|
&self,
|
||||||
wtxn: &mut RwTxn,
|
wtxn: &mut RwTxn,
|
||||||
|
|
|
@ -125,12 +125,11 @@ impl HeedAuthStore {
|
||||||
Action::MetricsAll => {
|
Action::MetricsAll => {
|
||||||
actions.insert(Action::MetricsGet);
|
actions.insert(Action::MetricsGet);
|
||||||
}
|
}
|
||||||
|
Action::ChatsAll => {
|
||||||
|
actions.extend([Action::ChatsGet, Action::ChatsDelete]);
|
||||||
|
}
|
||||||
Action::ChatsSettingsAll => {
|
Action::ChatsSettingsAll => {
|
||||||
actions.extend([
|
actions.extend([Action::ChatsSettingsGet, Action::ChatsSettingsUpdate]);
|
||||||
Action::ChatsSettingsGet,
|
|
||||||
Action::ChatsSettingsUpdate,
|
|
||||||
Action::ChatsSettingsDelete,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
actions.insert(*other);
|
actions.insert(*other);
|
||||||
|
|
|
@ -326,9 +326,15 @@ pub enum Action {
|
||||||
#[serde(rename = "chatCompletions")]
|
#[serde(rename = "chatCompletions")]
|
||||||
#[deserr(rename = "chatCompletions")]
|
#[deserr(rename = "chatCompletions")]
|
||||||
ChatCompletions,
|
ChatCompletions,
|
||||||
|
#[serde(rename = "chats.*")]
|
||||||
|
#[deserr(rename = "chats.*")]
|
||||||
|
ChatsAll,
|
||||||
#[serde(rename = "chats.get")]
|
#[serde(rename = "chats.get")]
|
||||||
#[deserr(rename = "chats.get")]
|
#[deserr(rename = "chats.get")]
|
||||||
ChatsGet,
|
ChatsGet,
|
||||||
|
#[serde(rename = "chats.delete")]
|
||||||
|
#[deserr(rename = "chats.delete")]
|
||||||
|
ChatsDelete,
|
||||||
#[serde(rename = "chatsSettings.*")]
|
#[serde(rename = "chatsSettings.*")]
|
||||||
#[deserr(rename = "chatsSettings.*")]
|
#[deserr(rename = "chatsSettings.*")]
|
||||||
ChatsSettingsAll,
|
ChatsSettingsAll,
|
||||||
|
@ -338,9 +344,6 @@ pub enum Action {
|
||||||
#[serde(rename = "chatsSettings.update")]
|
#[serde(rename = "chatsSettings.update")]
|
||||||
#[deserr(rename = "chatsSettings.update")]
|
#[deserr(rename = "chatsSettings.update")]
|
||||||
ChatsSettingsUpdate,
|
ChatsSettingsUpdate,
|
||||||
#[serde(rename = "chatsSettings.delete")]
|
|
||||||
#[deserr(rename = "chatsSettings.delete")]
|
|
||||||
ChatsSettingsDelete,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Action {
|
impl Action {
|
||||||
|
@ -367,11 +370,12 @@ impl Action {
|
||||||
SETTINGS_GET => Some(Self::SettingsGet),
|
SETTINGS_GET => Some(Self::SettingsGet),
|
||||||
SETTINGS_UPDATE => Some(Self::SettingsUpdate),
|
SETTINGS_UPDATE => Some(Self::SettingsUpdate),
|
||||||
CHAT_COMPLETIONS => Some(Self::ChatCompletions),
|
CHAT_COMPLETIONS => Some(Self::ChatCompletions),
|
||||||
|
CHATS_ALL => Some(Self::ChatsAll),
|
||||||
CHATS_GET => Some(Self::ChatsGet),
|
CHATS_GET => Some(Self::ChatsGet),
|
||||||
|
CHATS_DELETE => Some(Self::ChatsDelete),
|
||||||
CHATS_SETTINGS_ALL => Some(Self::ChatsSettingsAll),
|
CHATS_SETTINGS_ALL => Some(Self::ChatsSettingsAll),
|
||||||
CHATS_SETTINGS_GET => Some(Self::ChatsSettingsGet),
|
CHATS_SETTINGS_GET => Some(Self::ChatsSettingsGet),
|
||||||
CHATS_SETTINGS_UPDATE => Some(Self::ChatsSettingsUpdate),
|
CHATS_SETTINGS_UPDATE => Some(Self::ChatsSettingsUpdate),
|
||||||
CHATS_SETTINGS_DELETE => Some(Self::ChatsSettingsDelete),
|
|
||||||
STATS_ALL => Some(Self::StatsAll),
|
STATS_ALL => Some(Self::StatsAll),
|
||||||
STATS_GET => Some(Self::StatsGet),
|
STATS_GET => Some(Self::StatsGet),
|
||||||
METRICS_ALL => Some(Self::MetricsAll),
|
METRICS_ALL => Some(Self::MetricsAll),
|
||||||
|
@ -438,9 +442,10 @@ pub mod actions {
|
||||||
pub const NETWORK_UPDATE: u8 = NetworkUpdate.repr();
|
pub const NETWORK_UPDATE: u8 = NetworkUpdate.repr();
|
||||||
|
|
||||||
pub const CHAT_COMPLETIONS: u8 = ChatCompletions.repr();
|
pub const CHAT_COMPLETIONS: u8 = ChatCompletions.repr();
|
||||||
|
pub const CHATS_ALL: u8 = ChatsAll.repr();
|
||||||
pub const CHATS_GET: u8 = ChatsGet.repr();
|
pub const CHATS_GET: u8 = ChatsGet.repr();
|
||||||
|
pub const CHATS_DELETE: u8 = ChatsDelete.repr();
|
||||||
pub const CHATS_SETTINGS_ALL: u8 = ChatsSettingsAll.repr();
|
pub const CHATS_SETTINGS_ALL: u8 = ChatsSettingsAll.repr();
|
||||||
pub const CHATS_SETTINGS_GET: u8 = ChatsSettingsGet.repr();
|
pub const CHATS_SETTINGS_GET: u8 = ChatsSettingsGet.repr();
|
||||||
pub const CHATS_SETTINGS_UPDATE: u8 = ChatsSettingsUpdate.repr();
|
pub const CHATS_SETTINGS_UPDATE: u8 = ChatsSettingsUpdate.repr();
|
||||||
pub const CHATS_SETTINGS_DELETE: u8 = ChatsSettingsDelete.repr();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,9 +6,11 @@ use index_scheduler::IndexScheduler;
|
||||||
use meilisearch_types::deserr::query_params::Param;
|
use meilisearch_types::deserr::query_params::Param;
|
||||||
use meilisearch_types::deserr::DeserrQueryParamError;
|
use meilisearch_types::deserr::DeserrQueryParamError;
|
||||||
use meilisearch_types::error::deserr_codes::{InvalidIndexLimit, InvalidIndexOffset};
|
use meilisearch_types::error::deserr_codes::{InvalidIndexLimit, InvalidIndexOffset};
|
||||||
use meilisearch_types::error::ResponseError;
|
use meilisearch_types::error::{Code, ResponseError};
|
||||||
|
use meilisearch_types::index_uid::IndexUid;
|
||||||
use meilisearch_types::keys::actions;
|
use meilisearch_types::keys::actions;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
use serde_json::json;
|
||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
use utoipa::{IntoParams, ToSchema};
|
use utoipa::{IntoParams, ToSchema};
|
||||||
|
|
||||||
|
@ -40,11 +42,52 @@ pub struct ChatsParam {
|
||||||
pub fn configure(cfg: &mut web::ServiceConfig) {
|
pub fn configure(cfg: &mut web::ServiceConfig) {
|
||||||
cfg.service(web::resource("").route(web::get().to(list_workspaces))).service(
|
cfg.service(web::resource("").route(web::get().to(list_workspaces))).service(
|
||||||
web::scope("/{workspace_uid}")
|
web::scope("/{workspace_uid}")
|
||||||
|
.service(
|
||||||
|
web::resource("")
|
||||||
|
.route(web::get().to(get_chat))
|
||||||
|
.route(web::delete().to(delete_chat)),
|
||||||
|
)
|
||||||
.service(web::scope("/chat/completions").configure(chat_completions::configure))
|
.service(web::scope("/chat/completions").configure(chat_completions::configure))
|
||||||
.service(web::scope("/settings").configure(settings::configure)),
|
.service(web::scope("/settings").configure(settings::configure)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_chat(
|
||||||
|
index_scheduler: GuardedData<ActionPolicy<{ actions::CHATS_GET }>, Data<IndexScheduler>>,
|
||||||
|
workspace_uid: web::Path<String>,
|
||||||
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
|
index_scheduler.features().check_chat_completions("displaying a chat")?;
|
||||||
|
|
||||||
|
let workspace_uid = IndexUid::try_from(workspace_uid.into_inner())?;
|
||||||
|
if index_scheduler.chat_workspace_exists(&workspace_uid)? {
|
||||||
|
Ok(HttpResponse::Ok().json(json!({ "uid": workspace_uid })))
|
||||||
|
} else {
|
||||||
|
Err(ResponseError::from_msg(
|
||||||
|
format!("chat {workspace_uid} not found"),
|
||||||
|
Code::ChatWorkspaceNotFound,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn delete_chat(
|
||||||
|
index_scheduler: GuardedData<ActionPolicy<{ actions::CHATS_DELETE }>, Data<IndexScheduler>>,
|
||||||
|
workspace_uid: web::Path<String>,
|
||||||
|
) -> Result<HttpResponse, ResponseError> {
|
||||||
|
index_scheduler.features().check_chat_completions("deleting a chat")?;
|
||||||
|
|
||||||
|
let mut wtxn = index_scheduler.write_txn()?;
|
||||||
|
let workspace_uid = workspace_uid.into_inner();
|
||||||
|
if index_scheduler.delete_chat_settings(&mut wtxn, &workspace_uid)? {
|
||||||
|
wtxn.commit()?;
|
||||||
|
Ok(HttpResponse::NoContent().finish())
|
||||||
|
} else {
|
||||||
|
Err(ResponseError::from_msg(
|
||||||
|
format!("chat {workspace_uid} not found"),
|
||||||
|
Code::ChatWorkspaceNotFound,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserr, Debug, Clone, Copy, IntoParams)]
|
#[derive(Deserr, Debug, Clone, Copy, IntoParams)]
|
||||||
#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)]
|
#[deserr(error = DeserrQueryParamError, rename_all = camelCase, deny_unknown_fields)]
|
||||||
#[into_params(rename_all = "camelCase", parameter_in = Query)]
|
#[into_params(rename_all = "camelCase", parameter_in = Query)]
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub fn configure(cfg: &mut web::ServiceConfig) {
|
||||||
web::resource("")
|
web::resource("")
|
||||||
.route(web::get().to(SeqHandler(get_settings)))
|
.route(web::get().to(SeqHandler(get_settings)))
|
||||||
.route(web::patch().to(SeqHandler(patch_settings)))
|
.route(web::patch().to(SeqHandler(patch_settings)))
|
||||||
.route(web::delete().to(SeqHandler(delete_settings))),
|
.route(web::delete().to(SeqHandler(reset_settings))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,9 +159,9 @@ async fn patch_settings(
|
||||||
Ok(HttpResponse::Ok().json(settings))
|
Ok(HttpResponse::Ok().json(settings))
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn delete_settings(
|
async fn reset_settings(
|
||||||
index_scheduler: GuardedData<
|
index_scheduler: GuardedData<
|
||||||
ActionPolicy<{ actions::CHATS_SETTINGS_DELETE }>,
|
ActionPolicy<{ actions::CHATS_SETTINGS_UPDATE }>,
|
||||||
Data<IndexScheduler>,
|
Data<IndexScheduler>,
|
||||||
>,
|
>,
|
||||||
chats_param: web::Path<ChatsParam>,
|
chats_param: web::Path<ChatsParam>,
|
||||||
|
@ -169,12 +169,12 @@ async fn delete_settings(
|
||||||
index_scheduler.features().check_chat_completions("using the /chats/settings route")?;
|
index_scheduler.features().check_chat_completions("using the /chats/settings route")?;
|
||||||
|
|
||||||
let ChatsParam { workspace_uid } = chats_param.into_inner();
|
let ChatsParam { workspace_uid } = chats_param.into_inner();
|
||||||
|
|
||||||
// TODO do a spawn_blocking here
|
|
||||||
let mut wtxn = index_scheduler.write_txn()?;
|
let mut wtxn = index_scheduler.write_txn()?;
|
||||||
if index_scheduler.delete_chat_settings(&mut wtxn, &workspace_uid)? {
|
if index_scheduler.chat_settings(&wtxn, &workspace_uid)?.is_some() {
|
||||||
|
let settings = Default::default();
|
||||||
|
index_scheduler.put_chat_settings(&mut wtxn, &workspace_uid, &settings)?;
|
||||||
wtxn.commit()?;
|
wtxn.commit()?;
|
||||||
Ok(HttpResponse::NoContent().finish())
|
Ok(HttpResponse::Ok().json(settings))
|
||||||
} else {
|
} else {
|
||||||
Err(ResponseError::from_msg(
|
Err(ResponseError::from_msg(
|
||||||
format!("Chat `{workspace_uid}` not found"),
|
format!("Chat `{workspace_uid}` not found"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue