From 41c21a2baacd772f03027a341e60bfce5092535d Mon Sep 17 00:00:00 2001 From: Rugved Somwanshi Date: Fri, 12 Sep 2025 13:44:39 -0400 Subject: [PATCH] Allow --mlx, --gguf and @quant in owner/name format for lms get --- src/subcommands/get.ts | 56 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/subcommands/get.ts b/src/subcommands/get.ts index bdebb736..b136af7a 100644 --- a/src/subcommands/get.ts +++ b/src/subcommands/get.ts @@ -109,14 +109,6 @@ export const get = addLogLevelOptions( if (modelName !== undefined && modelName.split("/").length === 2) { // New lms get behavior: download artifact - if (mlx) { - logger.error("You cannot use the --mlx flag when an exact artifact is specified."); - process.exit(1); - } - if (gguf) { - logger.error("You cannot use the --gguf flag when an exact artifact is specified."); - process.exit(1); - } if (limit !== undefined) { logger.error("You cannot use the --limit flag when an exact artifact is specified."); process.exit(1); @@ -133,7 +125,31 @@ export const get = addLogLevelOptions( `; process.exit(1); } - const [owner, name] = modelName.toLowerCase().split("/"); + + let owner: string, name: string, quant: string | undefined; + // Parse owner/name@quant format + if (modelName.includes("@")) { + const parts = modelName.toLowerCase().split("@"); + if (parts.length !== 2) { + logger.error("Invalid model format. Use: owner/name or owner/name@quant"); + process.exit(1); + } + const [ownerName, quantPart] = parts; + const ownerNameParts = ownerName.split("/"); + if (ownerNameParts.length !== 2) { + logger.error("Invalid model format. Use: owner/name or owner/name@quant"); + process.exit(1); + } + [owner, name] = ownerNameParts; + quant = quantPart; + } else { + const parts = modelName.toLowerCase().split("/"); + if (parts.length !== 2) { + logger.error("Invalid model format. Use: owner/name or owner/name@quant"); + process.exit(1); + } + [owner, name] = parts; + } if (!kebabCaseRegex.test(owner)) { logger.error("Invalid artifact owner:", owner); process.exit(1); @@ -142,7 +158,11 @@ export const get = addLogLevelOptions( logger.error("Invalid artifact name:", name); process.exit(1); } - await downloadArtifact(client, logger, owner, name, yes); + await downloadArtifact(client, logger, owner, name, yes, { + mlx, + gguf, + quant, + }); return; } @@ -608,12 +628,19 @@ async function artifactDownloadPlanToString( } } +interface DownloadArtifactOpts { + mlx?: boolean; + gguf?: boolean; + quant?: string; +} + export async function downloadArtifact( client: LMStudioClient, logger: SimpleLogger, owner: string, name: string, yes: boolean, + { mlx, gguf, quant }: DownloadArtifactOpts = {}, ) { console.info(); let downloadPlan: ArtifactDownloadPlan = { @@ -680,6 +707,13 @@ export async function downloadArtifact( } }; process.stdout.write("\x1B[?25l"); + const types: Array = []; + if (mlx === true) { + types.push("safetensors"); + } + if (gguf === true) { + types.push("gguf"); + } using downloadPlanner = client.repository.createArtifactDownloadPlanner({ owner, name, @@ -687,6 +721,8 @@ export async function downloadArtifact( downloadPlan = newPlan; reprintDownloadPlan(false); }, + compatibilityTypeFilter: types.length > 0 ? types : undefined, + quantizationFilter: quant !== undefined ? [quant] : undefined, }); reprintDownloadPlan(false); const autoReprintInterval = setInterval(() => {