优化: Provider 配置体验(测试读表单值 + 保存反馈 + 报错友好 + 厂商预设,部分完成)

This commit is contained in:
lxy
2026-08-01 16:35:49 +08:00
parent 1a5d543fa1
commit 0e0c6862ba
8 changed files with 168 additions and 18 deletions
@@ -365,6 +365,53 @@ pub async fn ai_fetch_models(
Ok(merged)
}
/// 一次性测试连接(P0-1):用**表单当前值**而非 DB 值测试,不写库。
///
/// 解决:`ai_fetch_models` 从 DB 读 provider,用户改了表单未保存就点「测试连接」时
/// 测的是旧值(base_url/api_key 已改但 DB 未落),给出误导性「成功/失败」。
///
/// 行为:
/// - api_key 非空 → 直接用表单值(base_url + api_key)测,完全不读 DB。
/// - api_key 空 + provider_id 给出 → 编辑态用户没重填密钥(留空=不改),
/// 从 DB 取该 provider 记录经 FR-S1 内存解析出真实 key,base_url 仍用表单值
/// (用户可能改了 URL,密钥沿用旧)。
/// - api_key 空 + provider_id 空 → 新建态没填 key,直接报错(无来源可解析)。
///
/// 一次性:不写回 model_configs(测试≠落库);成功后用户可继续编辑或保存。
/// 保留 `ai_fetch_models`(从 DB 读 + 写回,用于「已保存配置重测」场景),本 IPC 不破坏它。
#[tauri::command]
pub async fn ai_test_connection(
state: State<'_, AppState>,
provider_type: String,
base_url: String,
api_key: String,
provider_id: Option<String>,
) -> Result<Vec<ModelConfig>, String> {
// 解析测试用 api_key:表单非空用表单;空则从 DB provider 沿用旧密钥(编辑不改 key 场景)
let api_key = if !api_key.is_empty() {
api_key
} else {
let pid = provider_id.ok_or_else(|| {
"测试连接失败:api_key 为空且无已保存配置可沿用,请填写 api_key".to_string()
})?;
let provider = state
.ai_providers
.get_by_id(&pid)
.await
.map_err(err_str)?
.ok_or_else(|| format!("提供商不存在: {}", pid))?;
// FR-S1:内存解析,绝不外泄(不入日志/返回值/错误信息)
df_storage::secret::resolve_provider_secret(&provider)
};
let fetch_type = normalize_provider_type_for_fetch(&provider_type);
let probed = df_ai::model_fetch::fetch_and_probe(&fetch_type, &base_url, &api_key)
.await
.map_err(err_str)?;
Ok(probed)
}
/// 单模型探测(F-01 阶段5):纯 CPU 启发式 + 预设表,无网络。
///
/// 用途:拉取后用户手动补一个模型名、或想重探某模型的能力维度。
+2
View File
@@ -442,6 +442,8 @@ pub fn run() {
// F-01 阶段5:测试连接拉取模型列表 + 单模型探测
commands::ai::ai_fetch_models,
commands::ai::ai_probe_model,
// P0-1:用表单当前值一次性测试连接(不写库,新建/编辑未保存均可测)
commands::ai::ai_test_connection,
// AI 对话管理
commands::ai::ai_conversation_create,
commands::ai::ai_conversation_list,