chore: checkpoint admin editor and perf work
This commit is contained in:
@@ -44,6 +44,8 @@ pub struct AiProviderConfig {
|
||||
pub api_key: Option<String>,
|
||||
#[serde(default, alias = "chatModel")]
|
||||
pub chat_model: Option<String>,
|
||||
#[serde(default, alias = "imageModel")]
|
||||
pub image_model: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
@@ -94,6 +96,14 @@ pub struct SiteSettingsPayload {
|
||||
pub ai_api_key: Option<String>,
|
||||
#[serde(default, alias = "aiChatModel")]
|
||||
pub ai_chat_model: Option<String>,
|
||||
#[serde(default, alias = "aiImageProvider")]
|
||||
pub ai_image_provider: Option<String>,
|
||||
#[serde(default, alias = "aiImageApiBase")]
|
||||
pub ai_image_api_base: Option<String>,
|
||||
#[serde(default, alias = "aiImageApiKey")]
|
||||
pub ai_image_api_key: Option<String>,
|
||||
#[serde(default, alias = "aiImageModel")]
|
||||
pub ai_image_model: Option<String>,
|
||||
#[serde(default, alias = "aiProviders")]
|
||||
pub ai_providers: Option<Vec<AiProviderConfig>>,
|
||||
#[serde(default, alias = "aiActiveProviderId")]
|
||||
@@ -106,6 +116,18 @@ pub struct SiteSettingsPayload {
|
||||
pub ai_top_k: Option<i32>,
|
||||
#[serde(default, alias = "aiChunkSize")]
|
||||
pub ai_chunk_size: Option<i32>,
|
||||
#[serde(default, alias = "mediaR2AccountId")]
|
||||
pub media_r2_account_id: Option<String>,
|
||||
#[serde(default, alias = "mediaStorageProvider")]
|
||||
pub media_storage_provider: Option<String>,
|
||||
#[serde(default, alias = "mediaR2Bucket")]
|
||||
pub media_r2_bucket: Option<String>,
|
||||
#[serde(default, alias = "mediaR2PublicBaseUrl")]
|
||||
pub media_r2_public_base_url: Option<String>,
|
||||
#[serde(default, alias = "mediaR2AccessKeyId")]
|
||||
pub media_r2_access_key_id: Option<String>,
|
||||
#[serde(default, alias = "mediaR2SecretAccessKey")]
|
||||
pub media_r2_secret_access_key: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize)]
|
||||
@@ -152,13 +174,16 @@ fn create_ai_provider_id() -> String {
|
||||
}
|
||||
|
||||
fn default_ai_provider_config() -> AiProviderConfig {
|
||||
let provider = ai::provider_name(None);
|
||||
|
||||
AiProviderConfig {
|
||||
id: "default".to_string(),
|
||||
name: "默认提供商".to_string(),
|
||||
provider: ai::provider_name(None),
|
||||
provider: provider.clone(),
|
||||
api_base: Some(ai::default_api_base().to_string()),
|
||||
api_key: Some(ai::default_api_key().to_string()),
|
||||
chat_model: Some(ai::default_chat_model().to_string()),
|
||||
image_model: Some(ai::default_image_model_for_provider(&provider).to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,11 +199,13 @@ fn normalize_ai_provider_configs(items: Vec<AiProviderConfig>) -> Vec<AiProvider
|
||||
let api_base = normalize_optional_string(item.api_base);
|
||||
let api_key = normalize_optional_string(item.api_key);
|
||||
let chat_model = normalize_optional_string(item.chat_model);
|
||||
let image_model = normalize_optional_string(item.image_model);
|
||||
let has_content = !item.name.trim().is_empty()
|
||||
|| !provider.trim().is_empty()
|
||||
|| api_base.is_some()
|
||||
|| api_key.is_some()
|
||||
|| chat_model.is_some();
|
||||
|| chat_model.is_some()
|
||||
|| image_model.is_some();
|
||||
|
||||
if !has_content {
|
||||
return None;
|
||||
@@ -201,6 +228,7 @@ fn normalize_ai_provider_configs(items: Vec<AiProviderConfig>) -> Vec<AiProvider
|
||||
api_base,
|
||||
api_key,
|
||||
chat_model,
|
||||
image_model,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
@@ -216,13 +244,16 @@ fn legacy_ai_provider_config(model: &Model) -> Option<AiProviderConfig> {
|
||||
return None;
|
||||
}
|
||||
|
||||
let normalized_provider = provider.unwrap_or_else(|| ai::provider_name(None));
|
||||
|
||||
Some(AiProviderConfig {
|
||||
id: "default".to_string(),
|
||||
name: "当前提供商".to_string(),
|
||||
provider: provider.unwrap_or_else(|| ai::provider_name(None)),
|
||||
provider: normalized_provider.clone(),
|
||||
api_base,
|
||||
api_key,
|
||||
chat_model,
|
||||
image_model: Some(ai::default_image_model_for_provider(&normalized_provider).to_string()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -301,6 +332,8 @@ fn update_active_provider_from_legacy_fields(model: &mut Model) {
|
||||
config.api_base = api_base;
|
||||
config.api_key = api_key;
|
||||
config.chat_model = chat_model;
|
||||
config.image_model =
|
||||
Some(ai::default_image_model_for_provider(&config.provider).to_string());
|
||||
write_ai_provider_state(
|
||||
model,
|
||||
vec![config],
|
||||
@@ -322,6 +355,10 @@ fn update_active_provider_from_legacy_fields(model: &mut Model) {
|
||||
config.api_base = api_base.clone();
|
||||
config.api_key = api_key.clone();
|
||||
config.chat_model = chat_model.clone();
|
||||
if config.image_model.is_none() {
|
||||
config.image_model =
|
||||
Some(ai::default_image_model_for_provider(&config.provider).to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -425,6 +462,18 @@ impl SiteSettingsPayload {
|
||||
if let Some(ai_chat_model) = self.ai_chat_model {
|
||||
item.ai_chat_model = normalize_optional_string(Some(ai_chat_model));
|
||||
}
|
||||
if let Some(ai_image_provider) = self.ai_image_provider {
|
||||
item.ai_image_provider = normalize_optional_string(Some(ai_image_provider));
|
||||
}
|
||||
if let Some(ai_image_api_base) = self.ai_image_api_base {
|
||||
item.ai_image_api_base = normalize_optional_string(Some(ai_image_api_base));
|
||||
}
|
||||
if let Some(ai_image_api_key) = self.ai_image_api_key {
|
||||
item.ai_image_api_key = normalize_optional_string(Some(ai_image_api_key));
|
||||
}
|
||||
if let Some(ai_image_model) = self.ai_image_model {
|
||||
item.ai_image_model = normalize_optional_string(Some(ai_image_model));
|
||||
}
|
||||
if let Some(ai_embedding_model) = self.ai_embedding_model {
|
||||
item.ai_embedding_model = normalize_optional_string(Some(ai_embedding_model));
|
||||
}
|
||||
@@ -437,6 +486,26 @@ impl SiteSettingsPayload {
|
||||
if self.ai_chunk_size.is_some() {
|
||||
item.ai_chunk_size = normalize_optional_int(self.ai_chunk_size, 400, 4000);
|
||||
}
|
||||
if let Some(media_r2_account_id) = self.media_r2_account_id {
|
||||
item.media_r2_account_id = normalize_optional_string(Some(media_r2_account_id));
|
||||
}
|
||||
if let Some(media_storage_provider) = self.media_storage_provider {
|
||||
item.media_storage_provider = normalize_optional_string(Some(media_storage_provider));
|
||||
}
|
||||
if let Some(media_r2_bucket) = self.media_r2_bucket {
|
||||
item.media_r2_bucket = normalize_optional_string(Some(media_r2_bucket));
|
||||
}
|
||||
if let Some(media_r2_public_base_url) = self.media_r2_public_base_url {
|
||||
item.media_r2_public_base_url =
|
||||
normalize_optional_string(Some(media_r2_public_base_url));
|
||||
}
|
||||
if let Some(media_r2_access_key_id) = self.media_r2_access_key_id {
|
||||
item.media_r2_access_key_id = normalize_optional_string(Some(media_r2_access_key_id));
|
||||
}
|
||||
if let Some(media_r2_secret_access_key) = self.media_r2_secret_access_key {
|
||||
item.media_r2_secret_access_key =
|
||||
normalize_optional_string(Some(media_r2_secret_access_key));
|
||||
}
|
||||
|
||||
if provider_list_supplied {
|
||||
write_ai_provider_state(
|
||||
@@ -524,6 +593,10 @@ fn default_payload() -> SiteSettingsPayload {
|
||||
ai_api_base: Some(ai::default_api_base().to_string()),
|
||||
ai_api_key: Some(ai::default_api_key().to_string()),
|
||||
ai_chat_model: Some(ai::default_chat_model().to_string()),
|
||||
ai_image_provider: None,
|
||||
ai_image_api_base: None,
|
||||
ai_image_api_key: None,
|
||||
ai_image_model: None,
|
||||
ai_providers: Some(vec![default_ai_provider_config()]),
|
||||
ai_active_provider_id: Some("default".to_string()),
|
||||
ai_embedding_model: Some(ai::local_embedding_label().to_string()),
|
||||
@@ -533,6 +606,12 @@ fn default_payload() -> SiteSettingsPayload {
|
||||
),
|
||||
ai_top_k: Some(4),
|
||||
ai_chunk_size: Some(1200),
|
||||
media_storage_provider: None,
|
||||
media_r2_account_id: None,
|
||||
media_r2_bucket: None,
|
||||
media_r2_public_base_url: None,
|
||||
media_r2_access_key_id: None,
|
||||
media_r2_secret_access_key: None,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -553,7 +632,11 @@ pub(crate) async fn load_current(ctx: &AppContext) -> Result<Model> {
|
||||
.await?;
|
||||
let mut model = inserted;
|
||||
default_payload().apply(&mut model);
|
||||
Ok(model.into_active_model().update(&ctx.db).await?)
|
||||
Ok(model
|
||||
.into_active_model()
|
||||
.reset_all()
|
||||
.update(&ctx.db)
|
||||
.await?)
|
||||
}
|
||||
|
||||
fn public_response(model: Model) -> PublicSiteSettingsResponse {
|
||||
@@ -596,7 +679,7 @@ pub async fn update(
|
||||
let current = load_current(&ctx).await?;
|
||||
let mut item = current;
|
||||
params.apply(&mut item);
|
||||
let item = item.into_active_model();
|
||||
let item = item.into_active_model().reset_all();
|
||||
let updated = item.update(&ctx.db).await?;
|
||||
format::json(public_response(updated))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user