mirror of
https://github.com/perstarkse/minne.git
synced 2026-04-21 08:21:25 +02:00
feat: system prompt customisable
This commit is contained in:
@@ -22,7 +22,10 @@ use routes::{
|
||||
change_password, delete_account, set_api_key, show_account_page, show_change_password,
|
||||
update_timezone,
|
||||
},
|
||||
admin_panel::{show_admin_panel, toggle_registration_status},
|
||||
admin_panel::{
|
||||
patch_ingestion_prompt, patch_query_prompt, show_admin_panel, show_edit_ingestion_prompt,
|
||||
show_edit_system_prompt, toggle_registration_status, update_model_settings,
|
||||
},
|
||||
chat::{
|
||||
message_response_stream::get_response_stream, new_chat_user_message, new_user_message,
|
||||
references::show_reference_tooltip, show_chat_base, show_existing_chat,
|
||||
@@ -107,9 +110,16 @@ where
|
||||
"/knowledge-relationship/:id",
|
||||
delete(delete_knowledge_relationship),
|
||||
)
|
||||
.route("/account", get(show_account_page))
|
||||
// Admin page
|
||||
.route("/admin", get(show_admin_panel))
|
||||
.route("/toggle-registrations", patch(toggle_registration_status))
|
||||
.route("/update-model-settings", patch(update_model_settings))
|
||||
.route("/edit-query-prompt", get(show_edit_system_prompt))
|
||||
.route("/update-query-prompt", patch(patch_query_prompt))
|
||||
.route("/edit-ingestion-prompt", get(show_edit_ingestion_prompt))
|
||||
.route("/update-ingestion-prompt", patch(patch_ingestion_prompt))
|
||||
// User account page
|
||||
.route("/account", get(show_account_page))
|
||||
.route("/set-api-key", post(set_api_key))
|
||||
.route("/update-timezone", patch(update_timezone))
|
||||
.route(
|
||||
|
||||
@@ -5,7 +5,12 @@ use crate::{
|
||||
middleware_auth::RequireUser,
|
||||
template_response::{HtmlError, TemplateResponse},
|
||||
};
|
||||
use common::storage::types::{analytics::Analytics, system_settings::SystemSettings, user::User};
|
||||
use common::storage::types::{
|
||||
analytics::Analytics,
|
||||
system_prompts::{DEFAULT_INGRESS_ANALYSIS_SYSTEM_PROMPT, DEFAULT_QUERY_SYSTEM_PROMPT},
|
||||
system_settings::SystemSettings,
|
||||
user::User,
|
||||
};
|
||||
|
||||
use crate::html_state::HtmlState;
|
||||
|
||||
@@ -15,6 +20,7 @@ pub struct AdminPanelData {
|
||||
settings: SystemSettings,
|
||||
analytics: Analytics,
|
||||
users: i64,
|
||||
default_query_prompt: String,
|
||||
}
|
||||
|
||||
pub async fn show_admin_panel(
|
||||
@@ -32,6 +38,7 @@ pub async fn show_admin_panel(
|
||||
settings,
|
||||
analytics,
|
||||
users: users_count,
|
||||
default_query_prompt: DEFAULT_QUERY_SYSTEM_PROMPT.to_string(),
|
||||
},
|
||||
))
|
||||
}
|
||||
@@ -85,3 +92,166 @@ pub async fn toggle_registration_status(
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct ModelSettingsInput {
|
||||
query_model: String,
|
||||
processing_model: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ModelSettingsData {
|
||||
settings: SystemSettings,
|
||||
}
|
||||
|
||||
pub async fn update_model_settings(
|
||||
State(state): State<HtmlState>,
|
||||
RequireUser(user): RequireUser,
|
||||
Form(input): Form<ModelSettingsInput>,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
// Early return if the user is not admin
|
||||
if !user.admin {
|
||||
return Ok(TemplateResponse::redirect("/"));
|
||||
};
|
||||
|
||||
let current_settings = SystemSettings::get_current(&state.db).await?;
|
||||
|
||||
let new_settings = SystemSettings {
|
||||
query_model: input.query_model,
|
||||
processing_model: input.processing_model,
|
||||
..current_settings
|
||||
};
|
||||
|
||||
SystemSettings::update(&state.db, new_settings.clone()).await?;
|
||||
|
||||
Ok(TemplateResponse::new_partial(
|
||||
"auth/admin_panel.html",
|
||||
"model_settings_form",
|
||||
ModelSettingsData {
|
||||
settings: new_settings,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct SystemPromptEditData {
|
||||
settings: SystemSettings,
|
||||
default_query_prompt: String,
|
||||
}
|
||||
|
||||
pub async fn show_edit_system_prompt(
|
||||
State(state): State<HtmlState>,
|
||||
RequireUser(user): RequireUser,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
// Early return if the user is not admin
|
||||
if !user.admin {
|
||||
return Ok(TemplateResponse::redirect("/"));
|
||||
};
|
||||
|
||||
let settings = SystemSettings::get_current(&state.db).await?;
|
||||
|
||||
Ok(TemplateResponse::new_template(
|
||||
"admin/edit_query_prompt_modal.html",
|
||||
SystemPromptEditData {
|
||||
settings,
|
||||
default_query_prompt: DEFAULT_QUERY_SYSTEM_PROMPT.to_string(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct SystemPromptUpdateInput {
|
||||
query_system_prompt: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct SystemPromptSectionData {
|
||||
settings: SystemSettings,
|
||||
}
|
||||
|
||||
pub async fn patch_query_prompt(
|
||||
State(state): State<HtmlState>,
|
||||
RequireUser(user): RequireUser,
|
||||
Form(input): Form<SystemPromptUpdateInput>,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
// Early return if the user is not admin
|
||||
if !user.admin {
|
||||
return Ok(TemplateResponse::redirect("/"));
|
||||
};
|
||||
|
||||
let current_settings = SystemSettings::get_current(&state.db).await?;
|
||||
|
||||
let new_settings = SystemSettings {
|
||||
query_system_prompt: input.query_system_prompt,
|
||||
..current_settings.clone()
|
||||
};
|
||||
|
||||
SystemSettings::update(&state.db, new_settings.clone()).await?;
|
||||
|
||||
Ok(TemplateResponse::new_partial(
|
||||
"auth/admin_panel.html",
|
||||
"system_prompt_section",
|
||||
SystemPromptSectionData {
|
||||
settings: new_settings,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct IngestionPromptEditData {
|
||||
settings: SystemSettings,
|
||||
default_ingestion_prompt: String,
|
||||
}
|
||||
|
||||
pub async fn show_edit_ingestion_prompt(
|
||||
State(state): State<HtmlState>,
|
||||
RequireUser(user): RequireUser,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
// Early return if the user is not admin
|
||||
if !user.admin {
|
||||
return Ok(TemplateResponse::redirect("/"));
|
||||
};
|
||||
|
||||
let settings = SystemSettings::get_current(&state.db).await?;
|
||||
|
||||
Ok(TemplateResponse::new_template(
|
||||
"admin/edit_ingestion_prompt_modal.html",
|
||||
IngestionPromptEditData {
|
||||
settings,
|
||||
default_ingestion_prompt: DEFAULT_INGRESS_ANALYSIS_SYSTEM_PROMPT.to_string(),
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct IngestionPromptUpdateInput {
|
||||
ingestion_system_prompt: String,
|
||||
}
|
||||
|
||||
pub async fn patch_ingestion_prompt(
|
||||
State(state): State<HtmlState>,
|
||||
RequireUser(user): RequireUser,
|
||||
Form(input): Form<IngestionPromptUpdateInput>,
|
||||
) -> Result<impl IntoResponse, HtmlError> {
|
||||
// Early return if the user is not admin
|
||||
if !user.admin {
|
||||
return Ok(TemplateResponse::redirect("/"));
|
||||
};
|
||||
|
||||
let current_settings = SystemSettings::get_current(&state.db).await?;
|
||||
|
||||
let new_settings = SystemSettings {
|
||||
ingestion_system_prompt: input.ingestion_system_prompt,
|
||||
..current_settings.clone()
|
||||
};
|
||||
|
||||
SystemSettings::update(&state.db, new_settings.clone()).await?;
|
||||
|
||||
Ok(TemplateResponse::new_partial(
|
||||
"auth/admin_panel.html",
|
||||
"system_prompt_section",
|
||||
SystemPromptSectionData {
|
||||
settings: new_settings,
|
||||
},
|
||||
))
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@ use common::storage::{
|
||||
conversation::Conversation,
|
||||
message::{Message, MessageRole},
|
||||
user::User,
|
||||
system_settings::SystemSettings,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -139,7 +140,13 @@ pub async fn get_response_stream(
|
||||
let entities_json = format_entities_json(&entities);
|
||||
let formatted_user_message =
|
||||
create_user_message_with_history(&entities_json, &history, &user_message.content);
|
||||
let request = match create_chat_request(formatted_user_message) {
|
||||
let settings = match SystemSettings::get_current(&state.db).await {
|
||||
Ok(s) => s,
|
||||
Err(_) => {
|
||||
return Sse::new(create_error_stream("Failed to retrieve system settings"));
|
||||
}
|
||||
};
|
||||
let request = match create_chat_request(formatted_user_message, &settings) {
|
||||
Ok(req) => req,
|
||||
Err(..) => {
|
||||
return Sse::new(create_error_stream("Failed to create chat request"));
|
||||
|
||||
Reference in New Issue
Block a user