feat: inference-llamacpp-extension: backend implementation
This commit is contained in:
parent
c288e75407
commit
9016fbff68
@ -0,0 +1 @@
|
||||
pub mod server;
|
||||
@ -0,0 +1,127 @@
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use tauri::{AppHandle, Manager, State}; // Import Manager trait
|
||||
use tokio::process::{Child, Command};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use super::state::AppState;
|
||||
|
||||
// Error type for server commands
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ServerError {
|
||||
#[error("Server is already running")]
|
||||
AlreadyRunning,
|
||||
#[error("Server is not running")]
|
||||
NotRunning,
|
||||
#[error("Failed to locate server binary: {0}")]
|
||||
BinaryNotFound(String),
|
||||
#[error("Failed to determine resource path: {0}")]
|
||||
ResourcePathError(String),
|
||||
#[error("IO error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("Jan API error: {0}")]
|
||||
Tauri(#[from] tauri::Error),
|
||||
}
|
||||
|
||||
type ServerResult<T> = Result<T, ServerError>;
|
||||
|
||||
// --- Helper function to find the server binary ---
|
||||
// -- TODO: Adjust extension engine paths
|
||||
// engine: static llama-server build (CUDA, VULKAN, SYCL, etc)
|
||||
fn get_server_path(app_handle: &AppHandle) -> ServerResult<PathBuf> {
|
||||
let binary_name = if cfg!(windows) {
|
||||
"llama-server.exe"
|
||||
} else {
|
||||
"llama-server"
|
||||
};
|
||||
let relative_path = PathBuf::from("engines").join(binary_name); // TODO: ADJUST THIS PATH
|
||||
|
||||
app_handle
|
||||
.path()
|
||||
.resolve_resource(relative_path)
|
||||
.map_err(|e| ServerError::ResourcePathError(e.to_string()))?
|
||||
.ok_or_else(|| {
|
||||
ServerError::BinaryNotFound(format!(
|
||||
"Could not resolve resource path for '{}'",
|
||||
if cfg!(windows) {
|
||||
"engines/llama-server.exe"
|
||||
} else {
|
||||
"engines/llama-server"
|
||||
} // TODO: ADJUST THIS PATH
|
||||
))
|
||||
})
|
||||
}
|
||||
|
||||
// --- Load Command ---
|
||||
#[tauri::command]
|
||||
pub async fn load(
|
||||
app_handle: AppHandle, // Get the AppHandle
|
||||
state: State<'_, AppState>, // Access the shared state
|
||||
args: Vec<String>, // Arguments from the frontend
|
||||
) -> ServerResult<()> {
|
||||
let mut process_lock = state.llama_server_process.lock().await;
|
||||
|
||||
if process_lock.is_some() {
|
||||
log::warn!("Attempted to load server, but it's already running.");
|
||||
return Err(ServerError::AlreadyRunning);
|
||||
}
|
||||
|
||||
let server_path = get_server_path(&app_handle)?;
|
||||
log::info!("Attempting to launch server at path: {:?}", server_path);
|
||||
log::info!("Using arguments: {:?}", args);
|
||||
|
||||
if !server_path.exists() {
|
||||
log::error!("Server binary not found at expected path: {:?}", server_path);
|
||||
return Err(ServerError::BinaryNotFound(format!("Binary not found at {:?}", server_path)));
|
||||
}
|
||||
|
||||
// Configure the command to run the server
|
||||
let mut command = Command::new(server_path);
|
||||
command.args(args);
|
||||
|
||||
// Optional: Redirect stdio if needed (e.g., for logging within Jan)
|
||||
// command.stdout(Stdio::piped());
|
||||
// command.stderr(Stdio::piped());
|
||||
|
||||
// Spawn the child process
|
||||
let child = command.spawn().map_err(ServerError::Io)?;
|
||||
|
||||
log::info!("Server process started with PID: {:?}", child.id());
|
||||
|
||||
// Store the child process handle in the state
|
||||
*process_lock = Some(child);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// --- Unload Command ---
|
||||
#[tauri::command]
|
||||
pub async fn unload(state: State<'_, AppState>) -> ServerResult<()> {
|
||||
let mut process_lock = state.llama_server_process.lock().await;
|
||||
|
||||
// Take the child process out of the Option, leaving None in its place
|
||||
if let Some(mut child) = process_lock.take() {
|
||||
log::info!(
|
||||
"Attempting to terminate server process with PID: {:?}",
|
||||
child.id()
|
||||
);
|
||||
// Kill the process
|
||||
// `start_kill` is preferred in async contexts
|
||||
match child.start_kill() {
|
||||
Ok(_) => {
|
||||
log::info!("Server process termination signal sent.");
|
||||
Ok(())
|
||||
}
|
||||
Err(e) => {
|
||||
// For simplicity, we log and return error.
|
||||
log::error!("Failed to kill server process: {}", e);
|
||||
// Put it back? Maybe not useful if kill failed.
|
||||
// *process_lock = Some(child);
|
||||
Err(ServerError::Io(e))
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log::warn!("Attempted to unload server, but it was not running.");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
1
src-tauri/src/core/utils/extensions/mod.rs
Normal file
1
src-tauri/src/core/utils/extensions/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod inference_llamacpp_extension;
|
||||
@ -76,3 +76,4 @@ pub fn normalize_path(path: &Path) -> PathBuf {
|
||||
}
|
||||
ret
|
||||
}
|
||||
pub mod extensions;
|
||||
|
||||
@ -87,6 +87,9 @@ pub fn run() {
|
||||
// hardware
|
||||
core::hardware::get_system_info,
|
||||
core::hardware::get_system_usage,
|
||||
// llama-cpp extension
|
||||
core::utils::extensions::inference_llamacpp_extension::load,
|
||||
core::utils::extensions::inference_llamacpp_extension::unload
|
||||
])
|
||||
.manage(AppState {
|
||||
app_token: Some(generate_app_token()),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user