From e8be39b8befb9acbe32e0799fa8cc8ba0abbef57 Mon Sep 17 00:00:00 2001 From: Vanalite Date: Fri, 28 Nov 2025 17:23:05 +0700 Subject: [PATCH] fix: dismiss validating model toast correctly on setupScreen --- extensions/download-extension/src/index.ts | 1 + extensions/llamacpp-extension/src/backend.ts | 8 ++- extensions/llamacpp-extension/src/index.ts | 2 + src-tauri/src/core/downloads/helpers.rs | 64 ++++++++++++++------ src-tauri/src/core/downloads/models.rs | 1 + 5 files changed, 56 insertions(+), 20 deletions(-) diff --git a/extensions/download-extension/src/index.ts b/extensions/download-extension/src/index.ts index 8045b5eeb..ade8784fb 100644 --- a/extensions/download-extension/src/index.ts +++ b/extensions/download-extension/src/index.ts @@ -12,6 +12,7 @@ interface DownloadItem { proxy?: Record sha256?: string size?: number + model_id?: string } type DownloadEvent = { diff --git a/extensions/llamacpp-extension/src/backend.ts b/extensions/llamacpp-extension/src/backend.ts index 71ca49363..6d5ad7657 100644 --- a/extensions/llamacpp-extension/src/backend.ts +++ b/extensions/llamacpp-extension/src/backend.ts @@ -278,11 +278,14 @@ export async function downloadBackend( ? `https://github.com/janhq/llama.cpp/releases/download/${version}/llama-${version}-bin-${backend}.tar.gz` : `https://catalog.jan.ai/llama.cpp/releases/${version}/llama-${version}-bin-${backend}.tar.gz` + const taskId = `llamacpp-${version}-${backend}`.replace(/\./g, '-') + const downloadItems = [ { url: backendUrl, save_path: await joinPath([backendDir, 'backend.tar.gz']), proxy: proxyConfig, + model_id: taskId, }, ] @@ -298,6 +301,7 @@ export async function downloadBackend( : `https://catalog.jan.ai/llama.cpp/releases/${version}/cudart-llama-bin-${platformName}-cu11.7-x64.tar.gz`, save_path: await joinPath([backendDir, 'build', 'bin', 'cuda11.tar.gz']), proxy: proxyConfig, + model_id: taskId, }) } else if ( (backend.includes('cu12.0') || backend.includes('cuda-12')) && @@ -310,6 +314,7 @@ export async function downloadBackend( : `https://catalog.jan.ai/llama.cpp/releases/${version}/cudart-llama-bin-${platformName}-cu12.0-x64.tar.gz`, save_path: await joinPath([backendDir, 'build', 'bin', 'cuda12.tar.gz']), proxy: proxyConfig, + model_id: taskId, }) } else if ( backend.includes('cuda-13') && @@ -322,10 +327,9 @@ export async function downloadBackend( : `https://catalog.jan.ai/llama.cpp/releases/${version}/cudart-llama-bin-${platformName}-cu13.0-x64.tar.gz`, save_path: await joinPath([backendDir, 'build', 'bin', 'cuda12.tar.gz']), proxy: proxyConfig, + model_id: taskId, }) } - - const taskId = `llamacpp-${version}-${backend}`.replace(/\./g, '-') const downloadType = 'Engine' console.log( diff --git a/extensions/llamacpp-extension/src/index.ts b/extensions/llamacpp-extension/src/index.ts index d46e796e9..6f2567ffd 100644 --- a/extensions/llamacpp-extension/src/index.ts +++ b/extensions/llamacpp-extension/src/index.ts @@ -102,6 +102,7 @@ interface DownloadItem { proxy?: Record sha256?: string size?: number + model_id?: string } interface ModelConfig { @@ -1436,6 +1437,7 @@ export default class llamacpp_extension extends AIEngine { sha256: saveName === 'model.gguf' ? opts.modelSha256 : opts.mmprojSha256, size: saveName === 'model.gguf' ? opts.modelSize : opts.mmprojSize, + model_id: modelId, }) return localPath } diff --git a/src-tauri/src/core/downloads/helpers.rs b/src-tauri/src/core/downloads/helpers.rs index c357ae6e1..948ddfa97 100644 --- a/src-tauri/src/core/downloads/helpers.rs +++ b/src-tauri/src/core/downloads/helpers.rs @@ -27,6 +27,7 @@ async fn validate_downloaded_file( save_path: &Path, app: &tauri::AppHandle, cancel_token: &CancellationToken, + emit_event: bool, ) -> Result<(), String> { // Skip validation if no verification data is provided if item.sha256.is_none() && item.size.is_none() { @@ -37,25 +38,27 @@ async fn validate_downloaded_file( return Ok(()); } - // Extract model ID from save path for validation events + // Use model_id from item if available, otherwise extract from save path // Path structure: llamacpp/models/{modelId}/model.gguf or llamacpp/models/{modelId}/mmproj.gguf - let model_id = save_path - .parent() // get parent directory (modelId folder) - .and_then(|p| p.file_name()) - .and_then(|n| n.to_str()) - .unwrap_or("unknown"); + let model_id = item.model_id.as_ref().map(|s| s.as_str()).unwrap_or_else(|| { + save_path + .parent() // get parent directory (modelId folder) + .and_then(|p| p.file_name()) + .and_then(|n| n.to_str()) + .unwrap_or("unknown") + }); - // Emit validation started event - app.emit( - "onModelValidationStarted", - serde_json::json!({ - "modelId": model_id, - "downloadType": "Model", - }), - ) - .unwrap(); - - log::info!("Starting validation for model: {model_id}"); + if emit_event { + app.emit( + "onModelValidationStarted", + serde_json::json!({ + "modelId": model_id, + "downloadType": "Model", + }), + ) + .unwrap(); + log::info!("Starting validation for model: {model_id}"); + } // Validate size if provided (fast check first) if let Some(expected_size) = &item.size { @@ -392,7 +395,7 @@ pub async fn _download_files_internal( let path_clone = downloaded_path.clone(); let cancel_token_clone = cancel_token.clone(); let validation_task = tokio::spawn(async move { - validate_downloaded_file(&item_clone, &path_clone, &app_clone, &cancel_token_clone).await + validate_downloaded_file(&item_clone, &path_clone, &app_clone, &cancel_token_clone, false).await }); validation_tasks.push((validation_task, downloaded_path, item.clone())); } @@ -400,6 +403,31 @@ pub async fn _download_files_internal( } } + let model_id = items.iter() + .find_map(|item| item.model_id.as_ref()) + .map(|s| s.as_str()) + .or_else(|| { + items.first().and_then(|item| { + std::path::Path::new(&item.save_path) + .parent() + .and_then(|p| p.file_name()) + .and_then(|n| n.to_str()) + }) + }) + .unwrap_or("unknown"); + + if !validation_tasks.is_empty() && items.iter().any(|item| item.sha256.is_some() || item.size.is_some()) { + app.emit( + "onModelValidationStarted", + serde_json::json!({ + "modelId": model_id, + "downloadType": "Model", + }), + ) + .unwrap(); + log::info!("Starting validation for model: {model_id}"); + } + // Wait for all validations to complete for (validation_task, save_path, _item) in validation_tasks { let validation_result = validation_task diff --git a/src-tauri/src/core/downloads/models.rs b/src-tauri/src/core/downloads/models.rs index 75a84e2b3..dd81b57b3 100644 --- a/src-tauri/src/core/downloads/models.rs +++ b/src-tauri/src/core/downloads/models.rs @@ -24,6 +24,7 @@ pub struct DownloadItem { pub proxy: Option, pub sha256: Option, pub size: Option, + pub model_id: Option, } #[derive(serde::Serialize, Clone, Debug)]