diff --git a/src-tauri/src/core/setup.rs b/src-tauri/src/core/setup.rs index 22597a0ae..c04abc3f7 100644 --- a/src-tauri/src/core/setup.rs +++ b/src-tauri/src/core/setup.rs @@ -232,254 +232,3 @@ pub fn setup_mcp(app: &App) { .unwrap(); }); } - -pub fn setup_sidecar(app: &App) -> Result<(), String> { - clean_up(); - let app_handle = app.handle().clone(); - let app_handle_for_spawn = app_handle.clone(); - tauri::async_runtime::spawn(async move { - const MAX_RESTARTS: u32 = 5; - const RESTART_DELAY_MS: u64 = 5000; - - let app_state = app_handle_for_spawn.state::(); - let cortex_restart_count_state = app_state.cortex_restart_count.clone(); - let cortex_killed_intentionally_state = app_state.cortex_killed_intentionally.clone(); - let app_data_dir = get_jan_data_folder_path(app_handle_for_spawn.clone()); - - let sidecar_command_builder = || { - let mut cmd = app_handle_for_spawn - .shell() - .sidecar("cortex-server") - - .expect("Failed to get sidecar command") - .args([ - "--start-server", - "--port", - "39291", - "--config_file_path", - app_data_dir.join(".janrc").to_str().unwrap(), - "--data_folder_path", - app_data_dir.to_str().unwrap(), - "--cors", - "ON", - "--allowed_origins", - "http://localhost:3000,http://localhost:1420,tauri://localhost,http://tauri.localhost", - "config", - "--api_keys", - app_state.inner().app_token.as_deref().unwrap_or(""), - ]); - #[cfg(target_os = "windows")] - { - let mut resource_dir = app_handle_for_spawn.path().resource_dir().unwrap(); - // If debug - #[cfg(debug_assertions)] - { - resource_dir = resource_dir.join("binaries"); - } - let normalized_path = resource_dir.to_string_lossy().replace(r"\\?\", ""); - let normalized_pathbuf = PathBuf::from(normalized_path); - cmd = cmd.current_dir(normalized_pathbuf); - } - - #[cfg(not(target_os = "windows"))] - { - cmd = cmd.env("LD_LIBRARY_PATH", { - let mut resource_dir = app_handle_for_spawn.path().resource_dir().unwrap(); - #[cfg(not(debug_assertions))] - { - resource_dir = resource_dir.join("binaries"); - } - let dest = resource_dir.to_str().unwrap(); - let ld_path_env = std::env::var("LD_LIBRARY_PATH").unwrap_or_default(); - format!("{}{}{}", ld_path_env, ":", dest) - }); - } - cmd - }; - - let child_process: Arc>> = Arc::new(Mutex::new(None)); - - let child_process_clone_for_kill = child_process.clone(); - let app_handle_for_kill = app_handle.clone(); - app_handle.listen("kill-sidecar", move |_event| { - let app_handle = app_handle_for_kill.clone(); - let child_to_kill_arc = child_process_clone_for_kill.clone(); - tauri::async_runtime::spawn(async move { - let app_state = app_handle.state::(); - // Mark as intentionally killed to prevent restart - let mut killed_intentionally = app_state.cortex_killed_intentionally.lock().await; - *killed_intentionally = true; - drop(killed_intentionally); - - log::info!("Received kill-sidecar event (processing async)."); - if let Some(child) = child_to_kill_arc.lock().await.take() { - log::info!("Attempting to kill sidecar process..."); - if let Err(e) = child.kill() { - log::error!("Failed to kill sidecar process: {}", e); - } else { - log::info!("Sidecar process killed successfully via event."); - } - } else { - log::warn!("Kill event received, but no active sidecar process found to kill."); - } - clean_up() - }); - }); - - loop { - let current_restart_count = *cortex_restart_count_state.lock().await; - if current_restart_count >= MAX_RESTARTS { - log::error!( - "Cortex server reached maximum restart attempts ({}). Giving up.", - current_restart_count - ); - if let Err(e) = app_handle_for_spawn.emit("cortex_max_restarts_reached", ()) { - log::error!("Failed to emit cortex_max_restarts_reached event: {}", e); - } - break; - } - - log::info!( - "Spawning cortex-server (Attempt {}/{})", - current_restart_count + 1, - MAX_RESTARTS - ); - - let current_command = sidecar_command_builder(); - log::debug!("Sidecar command: {:?}", current_command); - match current_command.spawn() { - Ok((mut rx, child_instance)) => { - log::info!( - "Cortex server spawned successfully. PID: {:?}", - child_instance.pid() - ); - *child_process.lock().await = Some(child_instance); - - { - let mut count = cortex_restart_count_state.lock().await; - if *count > 0 { - log::info!( - "Cortex server started successfully, resetting restart count from {} to 0.", - *count - ); - *count = 0; - } - drop(count); - - // Only reset the intentionally killed flag if it wasn't set during spawn - // This prevents overriding a concurrent kill event - let mut killed_intentionally = - cortex_killed_intentionally_state.lock().await; - if !*killed_intentionally { - // Flag wasn't set during spawn, safe to reset for future cycles - *killed_intentionally = false; - } else { - log::info!("Kill intent detected during spawn, preserving kill flag"); - } - drop(killed_intentionally); - } - - let mut process_terminated_unexpectedly = false; - while let Some(event) = rx.recv().await { - match event { - CommandEvent::Stdout(line_bytes) => { - log::info!( - "[Cortex STDOUT]: {}", - String::from_utf8_lossy(&line_bytes) - ); - } - CommandEvent::Stderr(line_bytes) => { - log::error!( - "[Cortex STDERR]: {}", - String::from_utf8_lossy(&line_bytes) - ); - } - CommandEvent::Error(message) => { - log::error!("[Cortex ERROR]: {}", message); - process_terminated_unexpectedly = true; - break; - } - CommandEvent::Terminated(payload) => { - log::info!( - "[Cortex Terminated]: Signal {:?}, Code {:?}", - payload.signal, - payload.code - ); - if child_process.lock().await.is_some() { - if payload.code.map_or(true, |c| c != 0) { - process_terminated_unexpectedly = true; - } - } - break; - } - _ => {} - } - } - - if child_process.lock().await.is_some() { - *child_process.lock().await = None; - log::info!("Cleared child process lock after termination."); - } - - // Check if the process was killed intentionally - let killed_intentionally = *cortex_killed_intentionally_state.lock().await; - - if killed_intentionally { - log::info!("Cortex server was killed intentionally. Not restarting."); - break; - } else if process_terminated_unexpectedly { - log::warn!("Cortex server terminated unexpectedly."); - let mut count = cortex_restart_count_state.lock().await; - *count += 1; - log::info!( - "Waiting {}ms before attempting restart {}/{}...", - RESTART_DELAY_MS, - *count, - MAX_RESTARTS - ); - drop(count); - sleep(Duration::from_millis(RESTART_DELAY_MS)).await; - continue; - } else { - log::info!("Cortex server terminated normally. Not restarting."); - break; - } - } - Err(e) => { - log::error!("Failed to spawn cortex-server: {}", e); - let mut count = cortex_restart_count_state.lock().await; - *count += 1; - log::info!( - "Waiting {}ms before attempting restart {}/{} due to spawn failure...", - RESTART_DELAY_MS, - *count, - MAX_RESTARTS - ); - drop(count); - sleep(Duration::from_millis(RESTART_DELAY_MS)).await; - } - } - } - }); - Ok(()) -} - -//pub fn setup_engine_binaries(app: &App) -> Result<(), String> { -// // Copy engine binaries to app_data -// let app_data_dir = app.handle().path().app_data_dir().unwrap(); -// let binaries_dir = app.handle().path().resource_dir().unwrap().join("binaries"); -// let themes_dir = app -// .handle() -// .path() -// .resource_dir() -// .unwrap() -// .join("resources"); -// -// if let Err(e) = copy_dir_all(binaries_dir, app_data_dir.clone()) { -// log::error!("Failed to copy binaries: {}", e); -// } -// if let Err(e) = copy_dir_all(themes_dir, app_data_dir.clone()) { -// log::error!("Failed to copy themes: {}", e); -// } -// Ok(()) -//} diff --git a/web-app/src/containers/SettingsMenu.tsx b/web-app/src/containers/SettingsMenu.tsx index 16a2583fa..8aea3b501 100644 --- a/web-app/src/containers/SettingsMenu.tsx +++ b/web-app/src/containers/SettingsMenu.tsx @@ -18,10 +18,6 @@ import ProvidersAvatar from '@/containers/ProvidersAvatar' const SettingsMenu = () => { const { t } = useTranslation() - const { experimentalFeatures } = useGeneralSetting() - const { providers } = useModelProvider() - const firstItemProvider = - providers.length > 0 ? providers[0].provider : 'llamacpp' const [expandedProviders, setExpandedProviders] = useState(false) const [isMenuOpen, setIsMenuOpen] = useState(false) const matches = useMatches()