feat(agent): export managed drivers for offline use

This commit is contained in:
Guoyu Su authored and GitHub committed 2026-08-22 15:41:21 +08:00
1 parent 6eb8b43701
commit 82e5756325
23 files changed
+3419 -40

No files matched your search

+68
View File
@@ -3,6 +3,11 @@ use std::sync::Arc;
use tauri::{Emitter, State};
use dbx_core::agent_manager::{AgentDriverInfo, DriverStoreUsage, JavaRuntimeConfig, JavaRuntimeMode, DEFAULT_JRE_KEY};
use dbx_core::agent_offline_export::{
export_agents_offline as export_agents_offline_core,
preview_agent_offline_export as preview_agent_offline_export_core, AgentOfflineExportPreview,
AgentOfflineExportResult,
};
use dbx_core::agent_service::{
batch_cancellation_key, build_agent_list, cancel_agent_batch_upgrade, cancel_agent_driver_install,
clear_agent_download_cache, fetch_registry_from, fetch_registry_from_claimed, import_agent_driver,
@@ -231,6 +236,38 @@ pub async fn import_agents_from_zip(
Ok(count)
}
#[tauri::command]
pub async fn preview_agent_offline_export(
state: State<'_, Arc<AppState>>,
) -> Result<AgentOfflineExportPreview, String> {
let state = Arc::clone(state.inner());
run_blocking_agent_task("Failed to prepare the offline Agent export preview", move || {
Ok(preview_agent_offline_export_core(&state.agent_manager))
})
.await
}
#[tauri::command]
pub async fn export_agents_offline(
state: State<'_, Arc<AppState>>,
path: String,
driver_keys: Vec<String>,
) -> Result<AgentOfflineExportResult, String> {
let state = Arc::clone(state.inner());
run_blocking_agent_task("Failed to run the offline Agent export task", move || {
export_agents_offline_core(&state.agent_manager, std::path::Path::new(&path), &driver_keys)
})
.await
}
async fn run_blocking_agent_task<T, F>(context: &'static str, task: F) -> Result<T, String>
where
T: Send + 'static,
F: FnOnce() -> Result<T, String> + Send + 'static,
{
tauri::async_runtime::spawn_blocking(task).await.map_err(|error| format!("{context}: {error}"))?
}
#[tauri::command]
pub async fn import_agent_driver_cmd(
state: State<'_, Arc<AppState>>,
@@ -317,3 +354,34 @@ fn update_blockers_from_keys(
blockers.sort_by(|left, right| left.label.cmp(&right.label));
blockers
}
#[cfg(test)]
mod tests {
use super::run_blocking_agent_task;
#[tokio::test]
async fn blocking_agent_task_returns_successful_value() {
let result = run_blocking_agent_task("agent task failed", || Ok::<_, String>(42)).await;
assert_eq!(result.unwrap(), 42);
}
#[tokio::test]
async fn blocking_agent_task_preserves_core_error() {
let result = run_blocking_agent_task("agent task failed", || Err::<(), _>("core failure".to_string())).await;
assert_eq!(result.unwrap_err(), "core failure");
}
#[tokio::test]
async fn blocking_agent_task_maps_join_error_with_context() {
let result = run_blocking_agent_task("agent task failed", || -> Result<(), String> {
panic!("worker panic");
})
.await;
let error = result.unwrap_err();
assert!(error.starts_with("agent task failed:"), "unexpected error: {error}");
assert!(error.contains("panicked"), "unexpected error: {error}");
}
}
+2
View File
@@ -2306,6 +2306,8 @@ pub fn run() {
commands::agents::reinstall_jre,
commands::agents::invalidate_agent_registry_cache,
commands::agents::import_agents_from_zip,
commands::agents::preview_agent_offline_export,
commands::agents::export_agents_offline,
commands::agents::import_agent_driver_cmd,
commands::agents::import_agent_jar_cmd,
commands::system_fonts::list_system_fonts,