新增: F-04c后端(provider池enabled/weight更新IPC+set_caps启动接入)
This commit is contained in:
@@ -926,23 +926,26 @@ pub async fn ai_save_provider(
|
||||
provider_type: String,
|
||||
) -> Result<String, String> {
|
||||
// 编辑已有提供商时保留原 created_at,避免被覆盖
|
||||
let created_at = match &id {
|
||||
Some(pid) => state.ai_providers.get_by_id(pid).await
|
||||
.map_err(err_str)?
|
||||
.map(|p| p.created_at)
|
||||
.unwrap_or_else(now_millis),
|
||||
None => now_millis(),
|
||||
// F-260614-04c: 编辑路径同时保留原 enabled/weight(负载均衡池可编辑层)。
|
||||
// 前端经此 IPC 改 enabled/weight 落库;新建走默认 enabled=true/weight=50。
|
||||
let existing = match &id {
|
||||
Some(pid) => state.ai_providers.get_by_id(pid).await.map_err(err_str)?,
|
||||
None => None,
|
||||
};
|
||||
let created_at = existing.as_ref().map(|p| p.created_at.clone()).unwrap_or_else(now_millis);
|
||||
// is_default:编辑保留原值;新建时若全表尚无默认则设为默认(首个自动默认,避免无默认可用)
|
||||
let is_default = match &id {
|
||||
Some(pid) => state.ai_providers.get_by_id(pid).await
|
||||
.map_err(err_str)?
|
||||
.map(|p| p.is_default)
|
||||
.unwrap_or(false),
|
||||
let is_default = match &existing {
|
||||
Some(p) => p.is_default,
|
||||
None => !state.ai_providers.list_all().await
|
||||
.map_err(err_str)?
|
||||
.iter().any(|p| p.is_default),
|
||||
};
|
||||
// F-260614-04c: enabled/weight 编辑保留原值(前端 Settings 改值经此落库);
|
||||
// 新建默认进池(enabled=true,weight=50)。
|
||||
let (enabled, weight) = match &existing {
|
||||
Some(p) => (p.enabled, p.weight),
|
||||
None => (true, 50),
|
||||
};
|
||||
// FR-S1:密钥存 OS keyring,DB api_key 列恒空(不入明文)。
|
||||
// api_key 非空 = 新/改密钥 → 写 keyring;空 = 编辑不改 → 保留原 keyring 密钥不动。
|
||||
let provider_id = id.clone().unwrap_or_else(new_id);
|
||||
@@ -993,10 +996,9 @@ pub async fn ai_save_provider(
|
||||
config: None,
|
||||
created_at,
|
||||
updated_at: now_millis(),
|
||||
// F-260614-04: 新建 provider 默认进入负载均衡池(enabled=true,weight=50)。
|
||||
// 单 provider 路径零变化(enabled=true 即与迁移前行为等价)。
|
||||
enabled: true,
|
||||
weight: 50,
|
||||
// F-260614-04c: enabled/weight 编辑保留原值(负载均衡池可编辑层),新建走默认。
|
||||
enabled,
|
||||
weight,
|
||||
};
|
||||
let id = record.id.clone();
|
||||
state
|
||||
@@ -1007,7 +1009,52 @@ pub async fn ai_save_provider(
|
||||
Ok(id)
|
||||
}
|
||||
|
||||
/// 设置活跃提供商(互斥落库:目标置默认、其余清默认,重启不丢)
|
||||
/// F-260614-04c: 轻量更新 provider 池配置(enabled/weight),不改其它字段、不触密钥迁移。
|
||||
///
|
||||
/// 与 `ai_save_provider` 的区别:
|
||||
/// - ai_save_provider 是全量保存(name/base_url/api_key/model...),编辑路径会走 R-PD-1 密钥
|
||||
/// 迁移 + INSERT OR REPLACE 全字段;前端 Settings「负载均衡池」开关/权重滑块仅需改这俩字段,
|
||||
/// 不应重发整张表(尤其避免空 api_key 触发密钥迁移分支)。
|
||||
/// - 本 IPC 仅 UPDATE enabled/weight(经 update_field 或 update_full),重建 caps 表。
|
||||
///
|
||||
/// 落库后立即重建 per_provider caps(set_provider_caps),保证开关/权重变更对 agentic loop
|
||||
/// 即时生效(下条消息即按新配置 acquire)。caps 重建非强一致(软收敛:已持 permit 不回收)。
|
||||
#[tauri::command]
|
||||
pub async fn ai_update_provider_pool(
|
||||
state: State<'_, AppState>,
|
||||
provider_id: String,
|
||||
enabled: bool,
|
||||
weight: u32,
|
||||
) -> Result<(), String> {
|
||||
// 验证 provider 存在(防前端传错 id 静默无操作)
|
||||
let mut record = state
|
||||
.ai_providers
|
||||
.get_by_id(&provider_id)
|
||||
.await
|
||||
.map_err(err_str)?
|
||||
.ok_or_else(|| format!("提供商不存在: {}", provider_id))?;
|
||||
// weight 落库前 clamp 到 [0,100](对齐 crud update 的 weight.min(100),防越界)。
|
||||
let weight = weight.min(100);
|
||||
if record.enabled == enabled && record.weight == weight {
|
||||
// 无变化:跳过 DB 写 + caps 重建(幂等,防前端重复点击触发不必要的 IO)。
|
||||
return Ok(());
|
||||
}
|
||||
record.enabled = enabled;
|
||||
record.weight = weight;
|
||||
record.updated_at = now_millis();
|
||||
// update_full 走 UPDATE 全字段(含 enabled/weight,波12已加);api_key 不变(DB 恒空)。
|
||||
state
|
||||
.ai_providers
|
||||
.update_full(&record)
|
||||
.await
|
||||
.map_err(err_str)?;
|
||||
// 重建 per_provider caps:本 provider 被禁用/weight=0 → 不入新表 → acquire_for_provider
|
||||
// 对其返 None(无限流,但 provider_pool::select 已把它移出候选,实际不会被 acquire)。
|
||||
// caps 重建逻辑收敛到 AppState::reload_provider_caps(单点真理,启动 + 变更共用)。
|
||||
state.reload_provider_caps().await;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn ai_set_provider(
|
||||
state: State<'_, AppState>,
|
||||
|
||||
Reference in New Issue
Block a user