feat: support .zip archives for manual backend install (#6534)

* feat(llamacpp): support .zip archives for manual backend install

* Update Lock Files
This commit is contained in:
Roushan Kumar Singh 2025-09-23 18:02:06 +05:30 committed by GitHub
parent 7f09c36a92
commit 3f51c35229
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 224 additions and 28 deletions

View File

@ -74,7 +74,10 @@ async function fetchRemoteSupportedBackends(
if (!name.startsWith(prefix)) continue
const backend = name.replace(prefix, '').replace('.tar.gz', '')
const backend = name
.replace(prefix, '')
.replace('.tar.gz', '')
.replace('.zip', '')
if (supportedBackends.includes(backend)) {
remote.push({ version, backend })

View File

@ -1081,11 +1081,11 @@ export default class llamacpp_extension extends AIEngine {
*/
async installBackend(path: string): Promise<void> {
const platformName = IS_WINDOWS ? 'win' : 'linux'
const re = /^llama-(b\d+)-bin-(.+?)\.tar\.gz$/
const re = /^llama-(b\d+)-bin-(.+?)\.(?:tar\.gz|zip)$/
const archiveName = await basename(path)
logger.info(`Installing backend from path: ${path}`)
if (!(await fs.existsSync(path)) || !path.endsWith('tar.gz')) {
if (!(await fs.existsSync(path)) || (!path.endsWith('tar.gz') && !path.endsWith('zip'))) {
logger.error(`Invalid path or file ${path}`)
throw new Error(`Invalid path or file ${path}`)
}

View File

@ -517,41 +517,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=fcb200&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=63c6e9&locator=%40janhq%2Fassistant-extension%40workspace%3Aassistant-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/603e79794614f861a9cf5693a4bbc480a62242309a6cb94a97c81e31518032c7462b2edad93a4380a18110f817ab15d85dc91a7924fd6e103a3462f6915ee368
checksum: 10c0/417ea9bd3e5b53264596d2ee816c3e24299f8b721f6ea951d078342555da457ebca4d5b1e116bf187ac77ec0a9e3341211d464f4ffdbd2a3915139523688d41d
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=fcb200&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=63c6e9&locator=%40janhq%2Fconversational-extension%40workspace%3Aconversational-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/603e79794614f861a9cf5693a4bbc480a62242309a6cb94a97c81e31518032c7462b2edad93a4380a18110f817ab15d85dc91a7924fd6e103a3462f6915ee368
checksum: 10c0/417ea9bd3e5b53264596d2ee816c3e24299f8b721f6ea951d078342555da457ebca4d5b1e116bf187ac77ec0a9e3341211d464f4ffdbd2a3915139523688d41d
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=fcb200&locator=%40janhq%2Fdownload-extension%40workspace%3Adownload-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=63c6e9&locator=%40janhq%2Fdownload-extension%40workspace%3Adownload-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/603e79794614f861a9cf5693a4bbc480a62242309a6cb94a97c81e31518032c7462b2edad93a4380a18110f817ab15d85dc91a7924fd6e103a3462f6915ee368
checksum: 10c0/417ea9bd3e5b53264596d2ee816c3e24299f8b721f6ea951d078342555da457ebca4d5b1e116bf187ac77ec0a9e3341211d464f4ffdbd2a3915139523688d41d
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=fcb200&locator=%40janhq%2Fllamacpp-extension%40workspace%3Allamacpp-extension"
resolution: "@janhq/core@file:../../core/package.tgz#../../core/package.tgz::hash=63c6e9&locator=%40janhq%2Fllamacpp-extension%40workspace%3Allamacpp-extension"
dependencies:
rxjs: "npm:^7.8.1"
ulidx: "npm:^2.3.0"
checksum: 10c0/603e79794614f861a9cf5693a4bbc480a62242309a6cb94a97c81e31518032c7462b2edad93a4380a18110f817ab15d85dc91a7924fd6e103a3462f6915ee368
checksum: 10c0/417ea9bd3e5b53264596d2ee816c3e24299f8b721f6ea951d078342555da457ebca4d5b1e116bf187ac77ec0a9e3341211d464f4ffdbd2a3915139523688d41d
languageName: node
linkType: hard

160
src-tauri/Cargo.lock generated
View File

@ -45,6 +45,7 @@ dependencies = [
"url",
"uuid",
"windows-sys 0.60.2",
"zip 0.6.6",
]
[[package]]
@ -62,6 +63,17 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa"
[[package]]
name = "aes"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0"
dependencies = [
"cfg-if",
"cipher",
"cpufeatures",
]
[[package]]
name = "ahash"
version = "0.7.8"
@ -358,6 +370,12 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64ct"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55248b47b0caf0546f7988906588779981c43bb1bc9d0c44087278f80cdb44ba"
[[package]]
name = "bitflags"
version = "1.3.2"
@ -508,6 +526,26 @@ dependencies = [
"serde",
]
[[package]]
name = "bzip2"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
dependencies = [
"bzip2-sys",
"libc",
]
[[package]]
name = "bzip2-sys"
version = "0.1.13+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "cairo-rs"
version = "0.18.5"
@ -581,6 +619,8 @@ version = "1.2.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2"
dependencies = [
"jobserver",
"libc",
"shlex",
]
@ -638,6 +678,16 @@ dependencies = [
"windows-link",
]
[[package]]
name = "cipher"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
dependencies = [
"crypto-common",
"inout",
]
[[package]]
name = "combine"
version = "4.6.7"
@ -677,6 +727,12 @@ dependencies = [
"tiny-keccak",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "convert_case"
version = "0.4.0"
@ -2259,6 +2315,15 @@ dependencies = [
"cfb",
]
[[package]]
name = "inout"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01"
dependencies = [
"generic-array",
]
[[package]]
name = "io-uring"
version = "0.7.9"
@ -2373,6 +2438,16 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130"
[[package]]
name = "jobserver"
version = "0.1.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
dependencies = [
"getrandom 0.3.3",
"libc",
]
[[package]]
name = "js-sys"
version = "0.3.77"
@ -3230,6 +3305,17 @@ dependencies = [
"windows-targets 0.52.6",
]
[[package]]
name = "password-hash"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
dependencies = [
"base64ct",
"rand_core 0.6.4",
"subtle",
]
[[package]]
name = "paste"
version = "1.0.15"
@ -3242,6 +3328,18 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
[[package]]
name = "pbkdf2"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
dependencies = [
"digest",
"hmac",
"password-hash",
"sha2",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -4521,6 +4619,17 @@ dependencies = [
"stable_deref_trait",
]
[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures",
"digest",
]
[[package]]
name = "sha2"
version = "0.10.9"
@ -5362,7 +5471,7 @@ dependencies = [
"tokio",
"url",
"windows-sys 0.60.2",
"zip",
"zip 4.3.0",
]
[[package]]
@ -7199,6 +7308,26 @@ dependencies = [
"syn 2.0.104",
]
[[package]]
name = "zip"
version = "0.6.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
dependencies = [
"aes",
"byteorder",
"bzip2",
"constant_time_eq",
"crc32fast",
"crossbeam-utils",
"flate2",
"hmac",
"pbkdf2",
"sha1",
"time",
"zstd",
]
[[package]]
name = "zip"
version = "4.3.0"
@ -7211,6 +7340,35 @@ dependencies = [
"memchr",
]
[[package]]
name = "zstd"
version = "0.11.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "5.0.2+zstd.1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
dependencies = [
"libc",
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "2.0.16+zstd.1.5.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91e19ebc2adc8f83e43039e79776e3fda8ca919132d68a1fed6a5faca2683748"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "zvariant"
version = "5.6.0"

View File

@ -59,6 +59,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
serde_yaml = "0.9.34"
tar = "0.4"
zip = "0.6"
tauri-plugin-deep-link = { version = "2.3.4" }
tauri-plugin-dialog = "2.2.1"
tauri-plugin-hardware = { path = "./plugins/tauri-plugin-hardware" }

View File

@ -200,8 +200,35 @@ pub fn decompress(app: tauri::AppHandle, path: &str, output_dir: &str) -> Result
let tar = flate2::read::GzDecoder::new(file);
let mut archive = tar::Archive::new(tar);
archive.unpack(&output_dir_buf).map_err(|e| e.to_string())?;
} else if path.ends_with(".zip") {
let mut zip = zip::ZipArchive::new(file).map_err(|e| e.to_string())?;
for i in 0..zip.len() {
let mut entry = zip.by_index(i).map_err(|e| e.to_string())?;
let outpath = output_dir_buf.join(
entry
.enclosed_name()
.ok_or_else(|| "Invalid zip entry path".to_string())?,
);
if entry.name().ends_with('/') {
std::fs::create_dir_all(&outpath).map_err(|e| e.to_string())?;
} else {
if let Some(parent) = outpath.parent() {
std::fs::create_dir_all(parent).map_err(|e| e.to_string())?;
}
let mut outfile = std::fs::File::create(&outpath).map_err(|e| e.to_string())?;
std::io::copy(&mut entry, &mut outfile).map_err(|e| e.to_string())?;
#[cfg(unix)]
{
use std::os::unix::fs::PermissionsExt;
if let Some(mode) = entry.unix_mode() {
let _ = std::fs::set_permissions(&outpath, std::fs::Permissions::from_mode(mode));
}
}
}
}
} else {
return Err("Unsupported file format. Only .tar.gz is supported.".to_string());
return Err("Unsupported file format. Only .tar.gz and .zip are supported.".to_string());
}
Ok(())

View File

@ -375,14 +375,14 @@ function ProviderDetail() {
setIsInstallingBackend(true)
try {
// Open file dialog with filter for .tar.gz files
// Open file dialog with filter for .tar.gz and .zip files
const selectedFile = await serviceHub.dialog().open({
multiple: false,
directory: false,
filters: [
{
name: 'Backend Archives',
extensions: ['tar.gz'],
extensions: ['tar.gz', 'zip'],
},
],
})

View File

@ -3532,8 +3532,8 @@ __metadata:
"@tanstack/react-router-devtools": "npm:^1.121.34"
"@tanstack/react-virtual": "npm:^3.13.12"
"@tanstack/router-plugin": "npm:^1.116.1"
"@tauri-apps/api": "npm:^2.5.0"
"@tauri-apps/plugin-deep-link": "npm:~2"
"@tauri-apps/api": "npm:^2.8.0"
"@tauri-apps/plugin-deep-link": "npm:2.4.3"
"@tauri-apps/plugin-dialog": "npm:^2.2.1"
"@tauri-apps/plugin-http": "npm:^2.2.1"
"@tauri-apps/plugin-opener": "npm:^2.2.7"
@ -3600,7 +3600,7 @@ __metadata:
sonner: "npm:^2.0.3"
tailwind-merge: "npm:^3.3.1"
tailwindcss: "npm:^4.1.4"
token.js: "npm:token.js-fork@0.7.23"
token.js: "npm:token.js-fork@0.7.27"
tw-animate-css: "npm:^1.2.7"
typescript: "npm:~5.8.3"
typescript-eslint: "npm:^8.26.1"
@ -7374,7 +7374,7 @@ __metadata:
languageName: node
linkType: hard
"@tauri-apps/api@npm:^2.0.0, @tauri-apps/api@npm:^2.5.0":
"@tauri-apps/api@npm:^2.0.0":
version: 2.5.0
resolution: "@tauri-apps/api@npm:2.5.0"
checksum: 10c0/8eeb28049d48f5f89a5419cdf313bb159305204b193a5f27ebddbe0704ff43037c8b2e78518de831d7393e00178f0c0ac66cef1a57b99c632de71eca29f562c0
@ -7388,6 +7388,13 @@ __metadata:
languageName: node
linkType: hard
"@tauri-apps/api@npm:^2.8.0":
version: 2.8.0
resolution: "@tauri-apps/api@npm:2.8.0"
checksum: 10c0/fb111e4d7572372997b440ebe6879543fa8c4765151878e3fddfbfe809b18da29eed142ce83061d14a9ca6d896b3266dc8a4927c642d71cdc0b4277dc7e3aabf
languageName: node
linkType: hard
"@tauri-apps/cli-darwin-arm64@npm:2.8.4":
version: 2.8.4
resolution: "@tauri-apps/cli-darwin-arm64@npm:2.8.4"
@ -7509,12 +7516,12 @@ __metadata:
languageName: node
linkType: hard
"@tauri-apps/plugin-deep-link@npm:~2":
version: 2.3.0
resolution: "@tauri-apps/plugin-deep-link@npm:2.3.0"
"@tauri-apps/plugin-deep-link@npm:2.4.3":
version: 2.4.3
resolution: "@tauri-apps/plugin-deep-link@npm:2.4.3"
dependencies:
"@tauri-apps/api": "npm:^2.0.0"
checksum: 10c0/76a8f0d4d89b243f4d1d663f0677c86df1bb5a508e4bca4700ca71e347e3b38cbf2217fd51c71b4051cde3481a3a2575dd957aec84bf5d95551edab3aa8c0e72
"@tauri-apps/api": "npm:^2.8.0"
checksum: 10c0/948959e217241345edd3d866aa12ccfe97c72d96ab2844c1df156ead89a96b6a32106944a77f114e6027547c79556cd95f14c2d303a70b307222cce350c67988
languageName: node
linkType: hard
@ -19617,9 +19624,9 @@ __metadata:
languageName: node
linkType: hard
"token.js@npm:token.js-fork@0.7.23":
version: 0.7.23
resolution: "token.js-fork@npm:0.7.23"
"token.js@npm:token.js-fork@0.7.27":
version: 0.7.27
resolution: "token.js-fork@npm:0.7.27"
dependencies:
"@anthropic-ai/sdk": "npm:0.24.3"
"@aws-sdk/client-bedrock-runtime": "npm:3.609.0"
@ -19630,7 +19637,7 @@ __metadata:
mime-types: "npm:^2.1.35"
nanoid: "npm:^5.0.7"
openai: "npm:4.91.1"
checksum: 10c0/73653dbdd2217f16de7eb294a2ef90ac985367f2ca421a2952a52c24de57e0f98db3ef668d8f36c361d6546513f85a480d48bfa916f2c5d65ce1b9033d526027
checksum: 10c0/ec4e8e441b6747db29eed0d21e364eaf8d4636e3d8376bdd63d836499970de15357e8c0b2ef1e470027e7a2c8bc4924138a86f6d207469b6f0b6fb0f24f6d035
languageName: node
linkType: hard