diff --git a/openless-all/app/src-tauri/src/commands.rs b/openless-all/app/src-tauri/src/commands.rs index 9aaa6976..673fea99 100644 --- a/openless-all/app/src-tauri/src/commands.rs +++ b/openless-all/app/src-tauri/src/commands.rs @@ -155,12 +155,9 @@ pub async fn validate_provider_credentials(kind: String) -> Result validate_llm_provider() .await .map(|()| ProviderCheckResult { ok: true }), - "asr" => { - let config = read_openai_provider_config(&kind)?; - fetch_provider_models(&config) - .await - .map(|_| ProviderCheckResult { ok: true }) - } + "asr" => validate_asr_provider() + .await + .map(|()| ProviderCheckResult { ok: true }), _ => Err(format!("unknown provider kind: {kind}")), } } @@ -232,6 +229,24 @@ async fn validate_llm_provider() -> Result<(), String> { }) } +async fn validate_asr_provider() -> Result<(), String> { + let config = read_openai_provider_config("asr")?; + let model = CredentialsVault::get(CredentialAccount::AsrModel) + .map_err(|e| e.to_string())? + .filter(|s| !s.trim().is_empty()) + .ok_or_else(|| "asrModelMissing".to_string())?; + let models = fetch_provider_models(&config).await?; + if models.is_empty() { + return Err("modelsEmpty".to_string()); + } + let model = model.trim(); + if models.iter().any(|m| m == model) { + Ok(()) + } else { + Err("asrModelUnavailable".to_string()) + } +} + async fn fetch_provider_models(config: &ProviderConfig) -> Result, String> { let url = models_url(&config.base_url); log::info!("[provider-check] GET {url}"); diff --git a/openless-all/app/src/i18n/en.ts b/openless-all/app/src/i18n/en.ts index dda72c28..1097d6fe 100644 --- a/openless-all/app/src/i18n/en.ts +++ b/openless-all/app/src/i18n/en.ts @@ -322,6 +322,7 @@ export const en: typeof zhCN = { fetchModels: 'Fetch models', loadingModels: 'Fetching models…', modelMissing: 'No model is configured. Please enter a model ID first.', + asrModelUnavailable: 'Current ASR model is not in the provider model list. Please select or enter a valid model.', modelsEmpty: 'Credentials are valid, but no models were returned.', modelsLoaded: 'Fetched {{count}} models.', selectModel: 'Select a model to fill the field above', diff --git a/openless-all/app/src/i18n/zh-CN.ts b/openless-all/app/src/i18n/zh-CN.ts index c5bd4220..d55004ef 100644 --- a/openless-all/app/src/i18n/zh-CN.ts +++ b/openless-all/app/src/i18n/zh-CN.ts @@ -320,6 +320,7 @@ export const zhCN = { fetchModels: '拉取模型', loadingModels: '拉取模型中…', modelMissing: '未配置模型,请先填写模型 ID。', + asrModelUnavailable: '当前 ASR 模型不在供应商返回列表中,请选择或填写有效模型。', modelsEmpty: '鉴权成功,但没有返回可用模型。', modelsLoaded: '已拉取 {{count}} 个模型。', selectModel: '选择一个模型写入上方字段', diff --git a/openless-all/app/src/pages/Settings.tsx b/openless-all/app/src/pages/Settings.tsx index 88cf7d0a..618261f8 100644 --- a/openless-all/app/src/pages/Settings.tsx +++ b/openless-all/app/src/pages/Settings.tsx @@ -593,10 +593,18 @@ function ProviderTools({ kind, modelAccount, onModelSelected }: { kind: 'llm' | setResult(result.ok ? 'success' : 'error', t('settings.providers.validateSuccess')); } catch (error) { const message = error instanceof Error ? error.message : String(error); - if (kind === 'llm' && message === 'llmModelMissing') { + if ((kind === 'llm' && message === 'llmModelMissing') || (kind === 'asr' && message === 'asrModelMissing')) { setResult('empty', t('settings.providers.modelMissing')); return; } + if (kind === 'asr' && message === 'asrModelUnavailable') { + setResult('empty', t('settings.providers.asrModelUnavailable')); + return; + } + if (message === 'modelsEmpty') { + setResult('empty', t('settings.providers.modelsEmpty')); + return; + } setResult('error', providerErrorMessage(error, t)); } };