diff --git a/extensions/yarn.lock b/extensions/yarn.lock index 9196aa06f..f4a58c14f 100644 --- a/extensions/yarn.lock +++ b/extensions/yarn.lock @@ -342,41 +342,41 @@ __metadata: "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension": version: 0.1.10 - resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=8d4ec2&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension" + resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f15485&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension" dependencies: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/0d97a222894863621508d5a95d91bde17a370608d6f452b2335bcc336dab9ddd3c53f7458381909875324c61f3d63df041995d450744780ac6b57b53f5182551 + checksum: 10c0/257621cb56db31a4dd3a2b509ec4c61217022e74bbd39cf6a1a172073654b9a65eee94ef9c1b4d4f5d2231d159c8818cb02846f3d88fe14f102f43169ad3737c languageName: node linkType: hard "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension": version: 0.1.10 - resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=8d4ec2&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension" + resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f15485&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension" dependencies: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/0d97a222894863621508d5a95d91bde17a370608d6f452b2335bcc336dab9ddd3c53f7458381909875324c61f3d63df041995d450744780ac6b57b53f5182551 + checksum: 10c0/257621cb56db31a4dd3a2b509ec4c61217022e74bbd39cf6a1a172073654b9a65eee94ef9c1b4d4f5d2231d159c8818cb02846f3d88fe14f102f43169ad3737c languageName: node linkType: hard "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fdownload-extension%40workspace%3Adownload-extension": version: 0.1.10 - resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=8d4ec2&locator=%40janhq%2Fdownload-extension%40workspace%3Adownload-extension" + resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f15485&locator=%40janhq%2Fdownload-extension%40workspace%3Adownload-extension" dependencies: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/0d97a222894863621508d5a95d91bde17a370608d6f452b2335bcc336dab9ddd3c53f7458381909875324c61f3d63df041995d450744780ac6b57b53f5182551 + checksum: 10c0/257621cb56db31a4dd3a2b509ec4c61217022e74bbd39cf6a1a172073654b9a65eee94ef9c1b4d4f5d2231d159c8818cb02846f3d88fe14f102f43169ad3737c languageName: node linkType: hard "@janhq/core@file:../../core/package.tgz::locator=%40janhq%2Fllamacpp-extension%40workspace%3Allamacpp-extension": version: 0.1.10 - resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=8d4ec2&locator=%40janhq%2Fllamacpp-extension%40workspace%3Allamacpp-extension" + resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=f15485&locator=%40janhq%2Fllamacpp-extension%40workspace%3Allamacpp-extension" dependencies: rxjs: "npm:^7.8.1" ulidx: "npm:^2.3.0" - checksum: 10c0/0d97a222894863621508d5a95d91bde17a370608d6f452b2335bcc336dab9ddd3c53f7458381909875324c61f3d63df041995d450744780ac6b57b53f5182551 + checksum: 10c0/257621cb56db31a4dd3a2b509ec4c61217022e74bbd39cf6a1a172073654b9a65eee94ef9c1b4d4f5d2231d159c8818cb02846f3d88fe14f102f43169ad3737c languageName: node linkType: hard diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 4e9ef4185..da2ca059e 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -85,6 +85,19 @@ dependencies = [ "version_check", ] +[[package]] +name = "ahash" +version = "0.8.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75" +dependencies = [ + "cfg-if", + "getrandom 0.3.3", + "once_cell", + "version_check", + "zerocopy", +] + [[package]] name = "aho-corasick" version = "1.1.3" @@ -149,11 +162,11 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "ash" -version = "0.38.0+1.3.281" +version = "0.37.3+1.3.251" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bb44936d800fea8f016d7f2311c6a4f97aebd5dc86f09906139ec848cf3a46f" +checksum = "39e9c3835d686b0a6084ab4234fcd1b07dbf6e4767dce60874b12356a25ecd4a" dependencies = [ - "libloading 0.8.8", + "libloading 0.7.4", ] [[package]] @@ -166,7 +179,7 @@ dependencies = [ "futures-channel", "futures-util", "rand 0.9.2", - "raw-window-handle", + "raw-window-handle 0.6.2", "serde", "serde_repr", "tokio", @@ -510,6 +523,20 @@ name = "bytemuck" version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c76a5792e44e4abe34d3abf15636779261d45a7450612059293d1d2cfc63422" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f154e572231cb6ba2bd1176980827e3d5dc04cc183a75dea38109fbdd672d29" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.104", +] [[package]] name = "byteorder" @@ -802,11 +829,22 @@ checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ "bitflags 2.9.1", "core-foundation 0.10.1", - "core-graphics-types", + "core-graphics-types 0.2.0", "foreign-types 0.5.0", "libc", ] +[[package]] +name = "core-graphics-types" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" +dependencies = [ + "bitflags 1.3.2", + "core-foundation 0.9.4", + "libc", +] + [[package]] name = "core-graphics-types" version = "0.2.0" @@ -845,6 +883,15 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.21" @@ -1888,13 +1935,24 @@ dependencies = [ "tracing", ] +[[package]] +name = "half" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +dependencies = [ + "bytemuck", + "cfg-if", + "crunchy", +] + [[package]] name = "hashbrown" version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" dependencies = [ - "ahash", + "ahash 0.7.8", ] [[package]] @@ -2619,6 +2677,15 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "markup5ever" version = "0.14.1" @@ -2747,7 +2814,7 @@ dependencies = [ "log", "ndk-sys", "num_enum", - "raw-window-handle", + "raw-window-handle 0.6.2", "thiserror 1.0.69", ] @@ -2869,6 +2936,15 @@ dependencies = [ "libloading 0.8.8", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + [[package]] name = "objc-sys" version = "0.3.5" @@ -3910,6 +3986,12 @@ dependencies = [ "rand_core 0.5.1", ] +[[package]] +name = "raw-window-handle" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2ff9a1f06a88b01621b7ae906ef0211290d1c8a168a15542486a8f61c0833b9" + [[package]] name = "raw-window-handle" version = "0.6.2" @@ -4100,7 +4182,7 @@ dependencies = [ "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.1", - "raw-window-handle", + "raw-window-handle 0.6.2", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -4769,7 +4851,7 @@ dependencies = [ "objc2 0.5.2", "objc2-foundation 0.2.2", "objc2-quartz-core 0.2.2", - "raw-window-handle", + "raw-window-handle 0.6.2", "redox_syscall", "wasm-bindgen", "web-sys", @@ -5038,7 +5120,7 @@ dependencies = [ "objc2-foundation 0.3.1", "once_cell", "parking_lot", - "raw-window-handle", + "raw-window-handle 0.6.2", "scopeguard", "tao-macros", "unicode-segmentation", @@ -5113,7 +5195,7 @@ dependencies = [ "objc2-web-kit", "percent-encoding", "plist", - "raw-window-handle", + "raw-window-handle 0.6.2", "reqwest 0.12.22", "serde", "serde_json", @@ -5243,7 +5325,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37e5858cc7b455a73ab4ea2ebc08b5be33682c00ff1bf4cad5537d4fb62499d9" dependencies = [ "log", - "raw-window-handle", + "raw-window-handle 0.6.2", "rfd", "serde", "serde_json", @@ -5290,6 +5372,7 @@ dependencies = [ "sysinfo", "tauri", "tauri-plugin", + "vulkano", ] [[package]] @@ -5499,7 +5582,7 @@ dependencies = [ "objc2 0.6.1", "objc2-ui-kit", "objc2-web-kit", - "raw-window-handle", + "raw-window-handle 0.6.2", "serde", "serde_json", "tauri-utils", @@ -5525,7 +5608,7 @@ dependencies = [ "objc2-foundation 0.3.1", "once_cell", "percent-encoding", - "raw-window-handle", + "raw-window-handle 0.6.2", "softbuffer", "tao", "tauri-runtime", @@ -5649,6 +5732,15 @@ dependencies = [ "syn 2.0.104", ] +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + [[package]] name = "time" version = "0.3.41" @@ -6164,6 +6256,15 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "vk-parse" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81086c28be67a8759cd80cbb3c8f7b520e0874605fc5eb74d5a1c9c2d1878e79" +dependencies = [ + "xml-rs", +] + [[package]] name = "vswhom" version = "0.1.0" @@ -6193,6 +6294,48 @@ dependencies = [ "memchr", ] +[[package]] +name = "vulkano" +version = "0.34.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a26f2897a92a30931fceef3d6d1156a1089d9681fb2be73be92bbf24ae2ddf2" +dependencies = [ + "ahash 0.8.12", + "ash", + "bytemuck", + "core-graphics-types 0.1.3", + "crossbeam-queue", + "half", + "heck 0.4.1", + "indexmap 2.10.0", + "libloading 0.8.8", + "objc", + "once_cell", + "parking_lot", + "proc-macro2", + "quote", + "raw-window-handle 0.5.2", + "regex", + "serde", + "serde_json", + "smallvec", + "thread_local", + "vk-parse", + "vulkano-macros", +] + +[[package]] +name = "vulkano-macros" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52be622d364272fd77e298e7f68e8547ae66e7687cb86eb85335412cee7e3965" +dependencies = [ + "proc-macro-crate 1.3.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -6527,7 +6670,7 @@ dependencies = [ "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.1", - "raw-window-handle", + "raw-window-handle 0.6.2", "windows-sys 0.59.0", "windows-version", ] @@ -7099,7 +7242,7 @@ dependencies = [ "objc2-web-kit", "once_cell", "percent-encoding", - "raw-window-handle", + "raw-window-handle 0.6.2", "sha2", "soup3", "tao-macros", @@ -7154,6 +7297,12 @@ dependencies = [ "rustix", ] +[[package]] +name = "xml-rs" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7" + [[package]] name = "yoke" version = "0.8.0" diff --git a/src-tauri/plugins/tauri-plugin-hardware/Cargo.toml b/src-tauri/plugins/tauri-plugin-hardware/Cargo.toml index 7475fb353..5e6f983fc 100644 --- a/src-tauri/plugins/tauri-plugin-hardware/Cargo.toml +++ b/src-tauri/plugins/tauri-plugin-hardware/Cargo.toml @@ -11,15 +11,19 @@ exclude = ["/examples", "/dist-js", "/guest-js", "/node_modules"] links = "tauri-plugin-hardware" [dependencies] -vulkano = "0.34" libc = "0.2" log = "0.4" -nvml-wrapper = "0.10.0" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" sysinfo = "0.34.2" tauri = { version = "2.5.0", default-features = false, features = ["test"] } +# Desktop-only dependencies +[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies] +vulkano = "0.34" +ash = "0.37" +nvml-wrapper = "0.10.0" + # Windows-specific dependencies [target.'cfg(windows)'.dependencies] libloading = "0.8" diff --git a/src-tauri/plugins/tauri-plugin-hardware/src/commands.rs b/src-tauri/plugins/tauri-plugin-hardware/src/commands.rs index ac13eb7f2..841613a56 100644 --- a/src-tauri/plugins/tauri-plugin-hardware/src/commands.rs +++ b/src-tauri/plugins/tauri-plugin-hardware/src/commands.rs @@ -17,7 +17,7 @@ pub fn get_system_info() -> SystemInfo { gpu_map.insert(gpu.uuid.clone(), gpu); } - let vulkan_gpus = vulkan::get_vulkan_gpus(); + let vulkan_gpus = vulkan::get_vulkan_gpus(""); for gpu in vulkan_gpus { match gpu_map.get_mut(&gpu.uuid) { diff --git a/src-tauri/plugins/tauri-plugin-hardware/src/vendor/nvidia.rs b/src-tauri/plugins/tauri-plugin-hardware/src/vendor/nvidia.rs index 006ca66ba..083c0fdae 100644 --- a/src-tauri/plugins/tauri-plugin-hardware/src/vendor/nvidia.rs +++ b/src-tauri/plugins/tauri-plugin-hardware/src/vendor/nvidia.rs @@ -1,7 +1,13 @@ -use crate::types::{GpuInfo, GpuUsage, Vendor}; -use nvml_wrapper::{error::NvmlError, Nvml}; -use std::sync::OnceLock; +use crate::types::{GpuInfo, GpuUsage}; +#[cfg(not(any(target_os = "android", target_os = "ios")))] +use { + crate::types::Vendor, + nvml_wrapper::{error::NvmlError, Nvml}, + std::sync::OnceLock, +}; + +#[cfg(not(any(target_os = "android", target_os = "ios")))] static NVML: OnceLock> = OnceLock::new(); #[derive(Debug, Clone, serde::Serialize)] @@ -10,11 +16,13 @@ pub struct NvidiaInfo { pub compute_capability: String, } +#[cfg(not(any(target_os = "android", target_os = "ios")))] fn get_nvml() -> Option<&'static Nvml> { NVML.get_or_init(|| { + // Try to initialize NVML, with fallback for Linux let result = Nvml::init().or_else(|e| { - // fallback if cfg!(target_os = "linux") { + log::debug!("NVML init failed, trying Linux fallback: {}", e); let lib_path = std::ffi::OsStr::new("libnvidia-ml.so.1"); Nvml::builder().lib_path(lib_path).init() } else { @@ -22,11 +30,13 @@ fn get_nvml() -> Option<&'static Nvml> { } }); - // NvmlError doesn't implement Copy, so we have to store an Option in OnceLock match result { - Ok(nvml) => Some(nvml), + Ok(nvml) => { + log::debug!("NVML initialized successfully"); + Some(nvml) + } Err(e) => { - log::error!("Unable to initialize NVML: {}", e); + log::debug!("Unable to initialize NVML: {}", e); None } } @@ -36,70 +46,111 @@ fn get_nvml() -> Option<&'static Nvml> { impl GpuInfo { pub fn get_usage_nvidia(&self) -> GpuUsage { - let index = match self.nvidia_info { - Some(ref nvidia_info) => nvidia_info.index, - None => { - log::error!("get_usage_nvidia() called on non-NVIDIA GPU"); - return self.get_usage_unsupported(); - } - }; - let closure = || -> Result { - let nvml = get_nvml().ok_or(NvmlError::Unknown)?; - let device = nvml.device_by_index(index)?; - let mem_info = device.memory_info()?; - Ok(GpuUsage { - uuid: self.uuid.clone(), - used_memory: mem_info.used / 1024 / 1024, // bytes to MiB - total_memory: mem_info.total / 1024 / 1024, // bytes to MiB - }) - }; - closure().unwrap_or_else(|e| { - log::error!("Failed to get memory usage for NVIDIA GPU {}: {}", index, e); - self.get_usage_unsupported() + #[cfg(any(target_os = "android", target_os = "ios"))] + { + log::warn!("NVIDIA GPU usage detection is not supported on mobile platforms"); + return self.get_usage_unsupported(); + } + + #[cfg(not(any(target_os = "android", target_os = "ios")))] + { + let index = match &self.nvidia_info { + Some(nvidia_info) => nvidia_info.index, + None => { + log::error!("get_usage_nvidia() called on non-NVIDIA GPU"); + return self.get_usage_unsupported(); + } + }; + + self.get_nvidia_memory_usage(index) + .unwrap_or_else(|e| { + log::error!("Failed to get memory usage for NVIDIA GPU {}: {}", index, e); + self.get_usage_unsupported() + }) + } + } + + #[cfg(not(any(target_os = "android", target_os = "ios")))] + fn get_nvidia_memory_usage(&self, index: u32) -> Result { + let nvml = get_nvml().ok_or(NvmlError::Unknown)?; + let device = nvml.device_by_index(index)?; + let mem_info = device.memory_info()?; + + Ok(GpuUsage { + uuid: self.uuid.clone(), + used_memory: mem_info.used / (1024 * 1024), // bytes to MiB + total_memory: mem_info.total / (1024 * 1024), // bytes to MiB }) } } pub fn get_nvidia_gpus() -> Vec { - let closure = || -> Result, NvmlError> { - let nvml = get_nvml().ok_or(NvmlError::Unknown)?; - let num_gpus = nvml.device_count()?; - let driver_version = nvml.sys_driver_version()?; + #[cfg(any(target_os = "android", target_os = "ios"))] + { + // On mobile platforms, NVIDIA GPU detection is not supported + log::info!("NVIDIA GPU detection is not supported on mobile platforms"); + vec![] + } - let mut gpus = Vec::with_capacity(num_gpus as usize); - for i in 0..num_gpus { - let device = nvml.device_by_index(i)?; - gpus.push(GpuInfo { - name: device.name()?, - total_memory: device.memory_info()?.total / 1024 / 1024, // bytes to MiB - vendor: Vendor::NVIDIA, - uuid: { - let mut uuid = device.uuid()?; - if uuid.starts_with("GPU-") { - uuid = uuid[4..].to_string(); - } - uuid - }, - driver_version: driver_version.clone(), - nvidia_info: Some(NvidiaInfo { - index: i, - compute_capability: { - let cc = device.cuda_compute_capability()?; - format!("{}.{}", cc.major, cc.minor) - }, - }), - vulkan_info: None, - }); - } - - Ok(gpus) - }; - - match closure() { - Ok(gpus) => gpus, - Err(e) => { - log::error!("Failed to get NVIDIA GPUs: {}", e); - vec![] - } + #[cfg(not(any(target_os = "android", target_os = "ios")))] + { + get_nvidia_gpus_internal() } } + +#[cfg(not(any(target_os = "android", target_os = "ios")))] +fn get_nvidia_gpus_internal() -> Vec { + let nvml = match get_nvml() { + Some(nvml) => nvml, + None => { + log::debug!("NVML not available"); + return vec![]; + } + }; + + let (num_gpus, driver_version) = match (nvml.device_count(), nvml.sys_driver_version()) { + (Ok(count), Ok(version)) => (count, version), + (Err(e), _) | (_, Err(e)) => { + log::error!("Failed to get NVIDIA system info: {}", e); + return vec![]; + } + }; + + let mut gpus = Vec::with_capacity(num_gpus as usize); + + for i in 0..num_gpus { + match create_gpu_info(nvml, i, &driver_version) { + Ok(gpu_info) => gpus.push(gpu_info), + Err(e) => log::warn!("Failed to get info for NVIDIA GPU {}: {}", i, e), + } + } + + gpus +} + +#[cfg(not(any(target_os = "android", target_os = "ios")))] +fn create_gpu_info(nvml: &Nvml, index: u32, driver_version: &str) -> Result { + let device = nvml.device_by_index(index)?; + let memory_info = device.memory_info()?; + let compute_capability = device.cuda_compute_capability()?; + + let uuid = device.uuid()?; + let clean_uuid = if uuid.starts_with("GPU-") { + uuid[4..].to_string() + } else { + uuid + }; + + Ok(GpuInfo { + name: device.name()?, + total_memory: memory_info.total / (1024 * 1024), // bytes to MiB + vendor: Vendor::NVIDIA, + uuid: clean_uuid, + driver_version: driver_version.to_string(), + nvidia_info: Some(NvidiaInfo { + index, + compute_capability: format!("{}.{}", compute_capability.major, compute_capability.minor), + }), + vulkan_info: None, + }) +} diff --git a/src-tauri/plugins/tauri-plugin-hardware/src/vendor/vulkan.rs b/src-tauri/plugins/tauri-plugin-hardware/src/vendor/vulkan.rs index d911e7013..ed2d5d5b2 100644 --- a/src-tauri/plugins/tauri-plugin-hardware/src/vendor/vulkan.rs +++ b/src-tauri/plugins/tauri-plugin-hardware/src/vendor/vulkan.rs @@ -1,4 +1,9 @@ -use crate::types::{GpuInfo, Vendor}; +use crate::types::GpuInfo; + +#[cfg(not(any(target_os = "android", target_os = "ios")))] +use crate::types::Vendor; + +#[cfg(not(any(target_os = "android", target_os = "ios")))] use ash::{vk, Entry}; #[derive(Debug, Clone, serde::Serialize)] @@ -9,6 +14,7 @@ pub struct VulkanInfo { pub device_id: u32, } +#[cfg(not(any(target_os = "android", target_os = "ios")))] fn parse_uuid(bytes: &[u8; 16]) -> String { format!( "{:02x}{:02x}{:02x}{:02x}-\ @@ -35,51 +41,35 @@ fn parse_uuid(bytes: &[u8; 16]) -> String { ) } -pub fn get_vulkan_gpus(lib_path: &str) -> Vec { - match get_vulkan_gpus_internal(lib_path) { - Ok(gpus) => gpus, - Err(e) => { - log::error!("Failed to get Vulkan GPUs: {:?}", e); - vec![] +pub fn get_vulkan_gpus(_lib_path: &str) -> Vec { + #[cfg(any(target_os = "android", target_os = "ios"))] + { + // On mobile platforms, Vulkan GPU detection is not supported + log::info!("Vulkan GPU detection is not supported on mobile platforms"); + vec![] + } + + #[cfg(not(any(target_os = "android", target_os = "ios")))] + { + match get_vulkan_gpus_internal(_lib_path) { + Ok(gpus) => gpus, + Err(e) => { + log::error!("Failed to get Vulkan GPUs: {:?}", e); + vec![] + } } } } -fn parse_c_string_u8(buf: &[u8]) -> String { - unsafe { std::ffi::CStr::from_ptr(buf.as_ptr() as *const std::ffi::c_char) } +#[cfg(not(any(target_os = "android", target_os = "ios")))] +fn parse_c_string(buf: &[std::ffi::c_char]) -> String { + unsafe { std::ffi::CStr::from_ptr(buf.as_ptr()) } .to_str() .unwrap_or_default() .to_string() } -fn parse_c_string_i8(buf: &[i8]) -> String { - unsafe { std::ffi::CStr::from_ptr(buf.as_ptr() as *const std::ffi::c_char) } - .to_str() - .unwrap_or_default() - .to_string() -} - -fn parse_c_string_platform_specific(buf: &[std::ffi::c_char]) -> String { - #[cfg(target_os = "android")] - { - // Android typically uses i8 for c_char - let i8_buf = unsafe { std::slice::from_raw_parts(buf.as_ptr() as *const i8, buf.len()) }; - parse_c_string_i8(i8_buf) - } - #[cfg(target_os = "ios")] - { - // iOS typically uses i8 for c_char - let i8_buf = unsafe { std::slice::from_raw_parts(buf.as_ptr() as *const i8, buf.len()) }; - parse_c_string_i8(i8_buf) - } - #[cfg(not(any(target_os = "android", target_os = "ios")))] - { - // Desktop platforms typically use u8 for c_char - let u8_buf = unsafe { std::slice::from_raw_parts(buf.as_ptr() as *const u8, buf.len()) }; - parse_c_string_u8(u8_buf) - } -} - +#[cfg(not(any(target_os = "android", target_os = "ios")))] fn get_vulkan_gpus_internal(lib_path: &str) -> Result, Box> { let entry = if lib_path.is_empty() { unsafe { Entry::load()? } @@ -124,7 +114,7 @@ fn get_vulkan_gpus_internal(lib_path: &str) -> Result, Box Result, Box rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const LogsRoute = LogsRouteImport.update({ + +const LogsRoute = LogsImport.update({ id: '/logs', path: '/logs', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const AssistantRoute = AssistantRouteImport.update({ + +const AssistantRoute = AssistantImport.update({ id: '/assistant', path: '/assistant', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const IndexRoute = IndexRouteImport.update({ + +const IndexRoute = IndexImport.update({ id: '/', path: '/', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const ProjectIndexRoute = ProjectIndexRouteImport.update({ + +const ProjectIndexRoute = ProjectIndexImport.update({ id: '/project/', path: '/project/', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const HubIndexRoute = HubIndexRouteImport.update({ + +const HubIndexRoute = HubIndexImport.update({ id: '/hub/', path: '/hub/', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const ThreadsThreadIdRoute = ThreadsThreadIdRouteImport.update({ + +const ThreadsThreadIdRoute = ThreadsThreadIdImport.update({ id: '/threads/$threadId', path: '/threads/$threadId', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsShortcutsRoute = SettingsShortcutsRouteImport.update({ + +const SettingsShortcutsRoute = SettingsShortcutsImport.update({ id: '/settings/shortcuts', path: '/settings/shortcuts', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsPrivacyRoute = SettingsPrivacyRouteImport.update({ + +const SettingsPrivacyRoute = SettingsPrivacyImport.update({ id: '/settings/privacy', path: '/settings/privacy', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsMcpServersRoute = SettingsMcpServersRouteImport.update({ + +const SettingsMcpServersRoute = SettingsMcpServersImport.update({ id: '/settings/mcp-servers', path: '/settings/mcp-servers', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsLocalApiServerRoute = SettingsLocalApiServerRouteImport.update({ + +const SettingsLocalApiServerRoute = SettingsLocalApiServerImport.update({ id: '/settings/local-api-server', path: '/settings/local-api-server', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsHttpsProxyRoute = SettingsHttpsProxyRouteImport.update({ + +const SettingsHttpsProxyRoute = SettingsHttpsProxyImport.update({ id: '/settings/https-proxy', path: '/settings/https-proxy', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsHardwareRoute = SettingsHardwareRouteImport.update({ + +const SettingsHardwareRoute = SettingsHardwareImport.update({ id: '/settings/hardware', path: '/settings/hardware', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsGeneralRoute = SettingsGeneralRouteImport.update({ + +const SettingsGeneralRoute = SettingsGeneralImport.update({ id: '/settings/general', path: '/settings/general', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsExtensionsRoute = SettingsExtensionsRouteImport.update({ + +const SettingsExtensionsRoute = SettingsExtensionsImport.update({ id: '/settings/extensions', path: '/settings/extensions', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsAppearanceRoute = SettingsAppearanceRouteImport.update({ + +const SettingsAppearanceRoute = SettingsAppearanceImport.update({ id: '/settings/appearance', path: '/settings/appearance', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const ProjectProjectIdRoute = ProjectProjectIdRouteImport.update({ + +const ProjectProjectIdRoute = ProjectProjectIdImport.update({ id: '/project/$projectId', path: '/project/$projectId', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const LocalApiServerLogsRoute = LocalApiServerLogsRouteImport.update({ + +const LocalApiServerLogsRoute = LocalApiServerLogsImport.update({ id: '/local-api-server/logs', path: '/local-api-server/logs', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const HubModelIdRoute = HubModelIdRouteImport.update({ + +const HubModelIdRoute = HubModelIdImport.update({ id: '/hub/$modelId', path: '/hub/$modelId', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const SettingsProvidersIndexRoute = SettingsProvidersIndexRouteImport.update({ + +const SettingsProvidersIndexRoute = SettingsProvidersIndexImport.update({ id: '/settings/providers/', path: '/settings/providers/', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) + const SettingsProvidersProviderNameRoute = - SettingsProvidersProviderNameRouteImport.update({ + SettingsProvidersProviderNameImport.update({ id: '/settings/providers/$providerName', path: '/settings/providers/$providerName', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) -const AuthGoogleCallbackRoute = AuthGoogleCallbackRouteImport.update({ + +const AuthGoogleCallbackRoute = AuthGoogleCallbackImport.update({ id: '/auth/google/callback', path: '/auth/google/callback', - getParentRoute: () => rootRouteImport, + getParentRoute: () => rootRoute, } as any) +// Populate the FileRoutesByPath interface + +declare module '@tanstack/react-router' { + interface FileRoutesByPath { + '/': { + id: '/' + path: '/' + fullPath: '/' + preLoaderRoute: typeof IndexImport + parentRoute: typeof rootRoute + } + '/assistant': { + id: '/assistant' + path: '/assistant' + fullPath: '/assistant' + preLoaderRoute: typeof AssistantImport + parentRoute: typeof rootRoute + } + '/logs': { + id: '/logs' + path: '/logs' + fullPath: '/logs' + preLoaderRoute: typeof LogsImport + parentRoute: typeof rootRoute + } + '/system-monitor': { + id: '/system-monitor' + path: '/system-monitor' + fullPath: '/system-monitor' + preLoaderRoute: typeof SystemMonitorImport + parentRoute: typeof rootRoute + } + '/hub/$modelId': { + id: '/hub/$modelId' + path: '/hub/$modelId' + fullPath: '/hub/$modelId' + preLoaderRoute: typeof HubModelIdImport + parentRoute: typeof rootRoute + } + '/local-api-server/logs': { + id: '/local-api-server/logs' + path: '/local-api-server/logs' + fullPath: '/local-api-server/logs' + preLoaderRoute: typeof LocalApiServerLogsImport + parentRoute: typeof rootRoute + } + '/project/$projectId': { + id: '/project/$projectId' + path: '/project/$projectId' + fullPath: '/project/$projectId' + preLoaderRoute: typeof ProjectProjectIdImport + parentRoute: typeof rootRoute + } + '/settings/appearance': { + id: '/settings/appearance' + path: '/settings/appearance' + fullPath: '/settings/appearance' + preLoaderRoute: typeof SettingsAppearanceImport + parentRoute: typeof rootRoute + } + '/settings/extensions': { + id: '/settings/extensions' + path: '/settings/extensions' + fullPath: '/settings/extensions' + preLoaderRoute: typeof SettingsExtensionsImport + parentRoute: typeof rootRoute + } + '/settings/general': { + id: '/settings/general' + path: '/settings/general' + fullPath: '/settings/general' + preLoaderRoute: typeof SettingsGeneralImport + parentRoute: typeof rootRoute + } + '/settings/hardware': { + id: '/settings/hardware' + path: '/settings/hardware' + fullPath: '/settings/hardware' + preLoaderRoute: typeof SettingsHardwareImport + parentRoute: typeof rootRoute + } + '/settings/https-proxy': { + id: '/settings/https-proxy' + path: '/settings/https-proxy' + fullPath: '/settings/https-proxy' + preLoaderRoute: typeof SettingsHttpsProxyImport + parentRoute: typeof rootRoute + } + '/settings/local-api-server': { + id: '/settings/local-api-server' + path: '/settings/local-api-server' + fullPath: '/settings/local-api-server' + preLoaderRoute: typeof SettingsLocalApiServerImport + parentRoute: typeof rootRoute + } + '/settings/mcp-servers': { + id: '/settings/mcp-servers' + path: '/settings/mcp-servers' + fullPath: '/settings/mcp-servers' + preLoaderRoute: typeof SettingsMcpServersImport + parentRoute: typeof rootRoute + } + '/settings/privacy': { + id: '/settings/privacy' + path: '/settings/privacy' + fullPath: '/settings/privacy' + preLoaderRoute: typeof SettingsPrivacyImport + parentRoute: typeof rootRoute + } + '/settings/shortcuts': { + id: '/settings/shortcuts' + path: '/settings/shortcuts' + fullPath: '/settings/shortcuts' + preLoaderRoute: typeof SettingsShortcutsImport + parentRoute: typeof rootRoute + } + '/threads/$threadId': { + id: '/threads/$threadId' + path: '/threads/$threadId' + fullPath: '/threads/$threadId' + preLoaderRoute: typeof ThreadsThreadIdImport + parentRoute: typeof rootRoute + } + '/hub/': { + id: '/hub/' + path: '/hub' + fullPath: '/hub' + preLoaderRoute: typeof HubIndexImport + parentRoute: typeof rootRoute + } + '/project/': { + id: '/project/' + path: '/project' + fullPath: '/project' + preLoaderRoute: typeof ProjectIndexImport + parentRoute: typeof rootRoute + } + '/auth/google/callback': { + id: '/auth/google/callback' + path: '/auth/google/callback' + fullPath: '/auth/google/callback' + preLoaderRoute: typeof AuthGoogleCallbackImport + parentRoute: typeof rootRoute + } + '/settings/providers/$providerName': { + id: '/settings/providers/$providerName' + path: '/settings/providers/$providerName' + fullPath: '/settings/providers/$providerName' + preLoaderRoute: typeof SettingsProvidersProviderNameImport + parentRoute: typeof rootRoute + } + '/settings/providers/': { + id: '/settings/providers/' + path: '/settings/providers' + fullPath: '/settings/providers' + preLoaderRoute: typeof SettingsProvidersIndexImport + parentRoute: typeof rootRoute + } + } +} + +// Create and export the route tree + export interface FileRoutesByFullPath { '/': typeof IndexRoute '/assistant': typeof AssistantRoute @@ -168,6 +356,7 @@ export interface FileRoutesByFullPath { '/settings/providers/$providerName': typeof SettingsProvidersProviderNameRoute '/settings/providers': typeof SettingsProvidersIndexRoute } + export interface FileRoutesByTo { '/': typeof IndexRoute '/assistant': typeof AssistantRoute @@ -192,8 +381,9 @@ export interface FileRoutesByTo { '/settings/providers/$providerName': typeof SettingsProvidersProviderNameRoute '/settings/providers': typeof SettingsProvidersIndexRoute } + export interface FileRoutesById { - __root__: typeof rootRouteImport + __root__: typeof rootRoute '/': typeof IndexRoute '/assistant': typeof AssistantRoute '/logs': typeof LogsRoute @@ -217,6 +407,7 @@ export interface FileRoutesById { '/settings/providers/$providerName': typeof SettingsProvidersProviderNameRoute '/settings/providers/': typeof SettingsProvidersIndexRoute } + export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath fullPaths: @@ -292,6 +483,7 @@ export interface FileRouteTypes { | '/settings/providers/' fileRoutesById: FileRoutesById } + export interface RootRouteChildren { IndexRoute: typeof IndexRoute AssistantRoute: typeof AssistantRoute @@ -317,165 +509,6 @@ export interface RootRouteChildren { SettingsProvidersIndexRoute: typeof SettingsProvidersIndexRoute } -declare module '@tanstack/react-router' { - interface FileRoutesByPath { - '/system-monitor': { - id: '/system-monitor' - path: '/system-monitor' - fullPath: '/system-monitor' - preLoaderRoute: typeof SystemMonitorRouteImport - parentRoute: typeof rootRouteImport - } - '/logs': { - id: '/logs' - path: '/logs' - fullPath: '/logs' - preLoaderRoute: typeof LogsRouteImport - parentRoute: typeof rootRouteImport - } - '/assistant': { - id: '/assistant' - path: '/assistant' - fullPath: '/assistant' - preLoaderRoute: typeof AssistantRouteImport - parentRoute: typeof rootRouteImport - } - '/': { - id: '/' - path: '/' - fullPath: '/' - preLoaderRoute: typeof IndexRouteImport - parentRoute: typeof rootRouteImport - } - '/project/': { - id: '/project/' - path: '/project' - fullPath: '/project' - preLoaderRoute: typeof ProjectIndexRouteImport - parentRoute: typeof rootRouteImport - } - '/hub/': { - id: '/hub/' - path: '/hub' - fullPath: '/hub' - preLoaderRoute: typeof HubIndexRouteImport - parentRoute: typeof rootRouteImport - } - '/threads/$threadId': { - id: '/threads/$threadId' - path: '/threads/$threadId' - fullPath: '/threads/$threadId' - preLoaderRoute: typeof ThreadsThreadIdRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/shortcuts': { - id: '/settings/shortcuts' - path: '/settings/shortcuts' - fullPath: '/settings/shortcuts' - preLoaderRoute: typeof SettingsShortcutsRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/privacy': { - id: '/settings/privacy' - path: '/settings/privacy' - fullPath: '/settings/privacy' - preLoaderRoute: typeof SettingsPrivacyRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/mcp-servers': { - id: '/settings/mcp-servers' - path: '/settings/mcp-servers' - fullPath: '/settings/mcp-servers' - preLoaderRoute: typeof SettingsMcpServersRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/local-api-server': { - id: '/settings/local-api-server' - path: '/settings/local-api-server' - fullPath: '/settings/local-api-server' - preLoaderRoute: typeof SettingsLocalApiServerRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/https-proxy': { - id: '/settings/https-proxy' - path: '/settings/https-proxy' - fullPath: '/settings/https-proxy' - preLoaderRoute: typeof SettingsHttpsProxyRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/hardware': { - id: '/settings/hardware' - path: '/settings/hardware' - fullPath: '/settings/hardware' - preLoaderRoute: typeof SettingsHardwareRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/general': { - id: '/settings/general' - path: '/settings/general' - fullPath: '/settings/general' - preLoaderRoute: typeof SettingsGeneralRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/extensions': { - id: '/settings/extensions' - path: '/settings/extensions' - fullPath: '/settings/extensions' - preLoaderRoute: typeof SettingsExtensionsRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/appearance': { - id: '/settings/appearance' - path: '/settings/appearance' - fullPath: '/settings/appearance' - preLoaderRoute: typeof SettingsAppearanceRouteImport - parentRoute: typeof rootRouteImport - } - '/project/$projectId': { - id: '/project/$projectId' - path: '/project/$projectId' - fullPath: '/project/$projectId' - preLoaderRoute: typeof ProjectProjectIdRouteImport - parentRoute: typeof rootRouteImport - } - '/local-api-server/logs': { - id: '/local-api-server/logs' - path: '/local-api-server/logs' - fullPath: '/local-api-server/logs' - preLoaderRoute: typeof LocalApiServerLogsRouteImport - parentRoute: typeof rootRouteImport - } - '/hub/$modelId': { - id: '/hub/$modelId' - path: '/hub/$modelId' - fullPath: '/hub/$modelId' - preLoaderRoute: typeof HubModelIdRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/providers/': { - id: '/settings/providers/' - path: '/settings/providers' - fullPath: '/settings/providers' - preLoaderRoute: typeof SettingsProvidersIndexRouteImport - parentRoute: typeof rootRouteImport - } - '/settings/providers/$providerName': { - id: '/settings/providers/$providerName' - path: '/settings/providers/$providerName' - fullPath: '/settings/providers/$providerName' - preLoaderRoute: typeof SettingsProvidersProviderNameRouteImport - parentRoute: typeof rootRouteImport - } - '/auth/google/callback': { - id: '/auth/google/callback' - path: '/auth/google/callback' - fullPath: '/auth/google/callback' - preLoaderRoute: typeof AuthGoogleCallbackRouteImport - parentRoute: typeof rootRouteImport - } - } -} - const rootRouteChildren: RootRouteChildren = { IndexRoute: IndexRoute, AssistantRoute: AssistantRoute, @@ -500,6 +533,107 @@ const rootRouteChildren: RootRouteChildren = { SettingsProvidersProviderNameRoute: SettingsProvidersProviderNameRoute, SettingsProvidersIndexRoute: SettingsProvidersIndexRoute, } -export const routeTree = rootRouteImport + +export const routeTree = rootRoute ._addFileChildren(rootRouteChildren) ._addFileTypes() + +/* ROUTE_MANIFEST_START +{ + "routes": { + "__root__": { + "filePath": "__root.tsx", + "children": [ + "/", + "/assistant", + "/logs", + "/system-monitor", + "/hub/$modelId", + "/local-api-server/logs", + "/project/$projectId", + "/settings/appearance", + "/settings/extensions", + "/settings/general", + "/settings/hardware", + "/settings/https-proxy", + "/settings/local-api-server", + "/settings/mcp-servers", + "/settings/privacy", + "/settings/shortcuts", + "/threads/$threadId", + "/hub/", + "/project/", + "/auth/google/callback", + "/settings/providers/$providerName", + "/settings/providers/" + ] + }, + "/": { + "filePath": "index.tsx" + }, + "/assistant": { + "filePath": "assistant.tsx" + }, + "/logs": { + "filePath": "logs.tsx" + }, + "/system-monitor": { + "filePath": "system-monitor.tsx" + }, + "/hub/$modelId": { + "filePath": "hub/$modelId.tsx" + }, + "/local-api-server/logs": { + "filePath": "local-api-server/logs.tsx" + }, + "/project/$projectId": { + "filePath": "project/$projectId.tsx" + }, + "/settings/appearance": { + "filePath": "settings/appearance.tsx" + }, + "/settings/extensions": { + "filePath": "settings/extensions.tsx" + }, + "/settings/general": { + "filePath": "settings/general.tsx" + }, + "/settings/hardware": { + "filePath": "settings/hardware.tsx" + }, + "/settings/https-proxy": { + "filePath": "settings/https-proxy.tsx" + }, + "/settings/local-api-server": { + "filePath": "settings/local-api-server.tsx" + }, + "/settings/mcp-servers": { + "filePath": "settings/mcp-servers.tsx" + }, + "/settings/privacy": { + "filePath": "settings/privacy.tsx" + }, + "/settings/shortcuts": { + "filePath": "settings/shortcuts.tsx" + }, + "/threads/$threadId": { + "filePath": "threads/$threadId.tsx" + }, + "/hub/": { + "filePath": "hub/index.tsx" + }, + "/project/": { + "filePath": "project/index.tsx" + }, + "/auth/google/callback": { + "filePath": "auth.google.callback.tsx" + }, + "/settings/providers/$providerName": { + "filePath": "settings/providers/$providerName.tsx" + }, + "/settings/providers/": { + "filePath": "settings/providers/index.tsx" + } + } +} +ROUTE_MANIFEST_END */