feat: nav reorder, model deploy button with background loading
This commit is contained in:
@@ -62,6 +62,14 @@ pub struct ChatErrorEvent {
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone)]
|
||||
pub struct EngineDeployEvent {
|
||||
pub model_id: String,
|
||||
pub file_name: String,
|
||||
pub state: String,
|
||||
pub message: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone)]
|
||||
pub struct DownloadPayload {
|
||||
pub url: String,
|
||||
@@ -196,6 +204,7 @@ pub fn get_messages(state: State<'_, App>, conversation_id: String) -> Result<Ve
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn engine_start(
|
||||
app: AppHandle,
|
||||
state: State<'_, App>,
|
||||
model_id: String,
|
||||
params: ChatParams,
|
||||
@@ -237,13 +246,16 @@ pub async fn engine_start(
|
||||
};
|
||||
engine.start(cfg).await.map_err(|e| e.to_string())?;
|
||||
*base.write().await = engine.base_url().await;
|
||||
Ok(engine.status().await)
|
||||
let status = engine.status().await;
|
||||
let _ = app.emit("engine://status", status.clone());
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn engine_stop(state: State<'_, App>) -> Result<(), String> {
|
||||
pub async fn engine_stop(app: AppHandle, state: State<'_, App>) -> Result<(), String> {
|
||||
state.engine.stop().await.map_err(|e| e.to_string())?;
|
||||
*state.engine_base.write().await = None;
|
||||
let _ = app.emit("engine://status", state.engine.status().await);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -254,6 +266,117 @@ pub async fn engine_status(
|
||||
Ok(state.engine.status().await)
|
||||
}
|
||||
|
||||
/// 后台部署(加载)本地模型:启动 llama-server 并等待就绪,通过事件广播进度。
|
||||
#[tauri::command]
|
||||
pub async fn deploy_model(
|
||||
app: AppHandle,
|
||||
state: State<'_, App>,
|
||||
model_id: String,
|
||||
params: ChatParams,
|
||||
) -> Result<(), String> {
|
||||
let core = state.core.clone();
|
||||
let engine = state.engine.clone();
|
||||
let base = state.engine_base.clone();
|
||||
|
||||
let (model, engine_bin) = {
|
||||
let db = core.db.lock().unwrap();
|
||||
let model = models_db::get(&db, &model_id)
|
||||
.map_err(|e| e.to_string())?
|
||||
.ok_or_else(|| "model not found".to_string())?;
|
||||
if model.kind != "local" {
|
||||
return Err("在线 API 模型无需部署".into());
|
||||
}
|
||||
let bin = settings_db::get(&db, "engine_bin")
|
||||
.map_err(|e| e.to_string())?
|
||||
.unwrap_or_default();
|
||||
(model, bin)
|
||||
};
|
||||
|
||||
let file_name = model.file_name.clone();
|
||||
let emit_deploy = |state_name: &str, message: Option<String>| {
|
||||
let _ = app.emit(
|
||||
"engine://deploy",
|
||||
EngineDeployEvent {
|
||||
model_id: model_id.clone(),
|
||||
file_name: file_name.clone(),
|
||||
state: state_name.into(),
|
||||
message,
|
||||
},
|
||||
);
|
||||
};
|
||||
|
||||
let current = engine.status().await;
|
||||
if current.running {
|
||||
if current.model.as_deref() == Some(file_name.as_str()) {
|
||||
emit_deploy("ready", None);
|
||||
return Ok(());
|
||||
}
|
||||
// 部署另一个模型前,先停掉当前引擎
|
||||
let _ = engine.stop().await;
|
||||
*base.write().await = None;
|
||||
let _ = app.emit("engine://status", engine.status().await);
|
||||
}
|
||||
|
||||
let bin = PathBuf::from(engine_bin);
|
||||
if !bin.exists() {
|
||||
emit_deploy(
|
||||
"error",
|
||||
Some(format!(
|
||||
"引擎文件不存在:{},请到设置页配置 llama-server 路径",
|
||||
bin.display()
|
||||
)),
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
emit_deploy("loading", None);
|
||||
let app2 = app.clone();
|
||||
let core2 = core.clone();
|
||||
let engine2 = engine.clone();
|
||||
let base2 = base.clone();
|
||||
let model_id2 = model_id.clone();
|
||||
let file_name2 = file_name.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
let cfg = EngineConfig {
|
||||
binary_path: bin,
|
||||
model_path: PathBuf::from(model.file_path),
|
||||
host: "127.0.0.1".into(),
|
||||
ctx_size: params.ctx_size,
|
||||
ngl: params.ngl,
|
||||
threads: None,
|
||||
log_file: core2.logs_dir.join(format!("engine-{}.log", model.file_name)),
|
||||
};
|
||||
match engine2.start(cfg).await {
|
||||
Ok(()) => {
|
||||
*base2.write().await = engine2.base_url().await;
|
||||
let _ = app2.emit(
|
||||
"engine://deploy",
|
||||
EngineDeployEvent {
|
||||
model_id: model_id2,
|
||||
file_name: file_name2,
|
||||
state: "ready".into(),
|
||||
message: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
Err(e) => {
|
||||
let _ = app2.emit(
|
||||
"engine://deploy",
|
||||
EngineDeployEvent {
|
||||
model_id: model_id2,
|
||||
file_name: file_name2,
|
||||
state: "error".into(),
|
||||
message: Some(e.to_string()),
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
let _ = app2.emit("engine://status", engine2.status().await);
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn chat_send(
|
||||
app: AppHandle,
|
||||
|
||||
@@ -81,6 +81,7 @@ pub fn run() {
|
||||
commands::engine_start,
|
||||
commands::engine_stop,
|
||||
commands::engine_status,
|
||||
commands::deploy_model,
|
||||
commands::chat_send,
|
||||
commands::download_enqueue,
|
||||
commands::server_start,
|
||||
|
||||
Reference in New Issue
Block a user