@@ -132,14 +132,11 @@ class LoraExtractorUtil {
132132 if ( outName . startsWith ( '/' ) ) {
133133 outName = outName . substring ( 1 ) ;
134134 }
135- if ( outName . endsWith ( '.safetensors' ) ) {
136- outName = outName . substring ( 0 , outName . length - '.safetensors' . length ) ;
137- }
138- if ( outName . endsWith ( '.sft' ) ) {
139- outName = outName . substring ( 0 , outName . length - '.sft' . length ) ;
140- }
141- if ( outName . endsWith ( '.ckpt' ) ) {
142- outName = outName . substring ( 0 , outName . length - '.ckpt' . length ) ;
135+ for ( let extension of [ '.safetensors' , '.sft' , '.gguf' , '.ckpt' ] ) {
136+ if ( outName . endsWith ( extension ) ) {
137+ outName = outName . substring ( 0 , outName . length - extension . length ) ;
138+ break ;
139+ }
143140 }
144141 if ( ! baseModel || ! otherModel || ! outName ) {
145142 this . textArea . innerText = "Missing required values, cannot extract." ;
@@ -276,17 +273,17 @@ class ModelDownloaderUtil {
276273 baseLoop:
277274 for ( let vers of rawData . modelVersions ) {
278275 for ( let vFile of vers . files ) {
279- if ( vFile . name . endsWith ( `.safetensors` ) || vFile . name . endsWith ( `.sft` ) ) {
276+ if ( vFile . name . endsWith ( `.safetensors` ) || vFile . name . endsWith ( `.sft` ) || vFile . name . endsWith ( `.gguf` ) ) {
280277 rawVersion = vers ;
281278 file = vFile ;
282279 break baseLoop;
283280 }
284281 }
285282 }
286283 }
287- if ( validateSafe && ! file . name . endsWith ( '.safetensors' ) && ! file . name . endsWith ( '.sft' ) ) {
284+ if ( validateSafe && ! file . name . endsWith ( '.safetensors' ) && ! file . name . endsWith ( '.sft' ) && ! file . name . endsWith ( '.gguf' ) ) {
288285 console . log ( `refuse civitai url because download url is ${ file . downloadUrl } / ${ file . name } / ${ identifier } ` ) ;
289- doError ( `Cannot download model from that URL because it is not a safetensors file. Filename is '${ file . name } '` ) ;
286+ doError ( `Cannot download model from that URL because it is not a safetensors or GGUF file. Filename is '${ file . name } '` ) ;
290287 return ;
291288 }
292289 if ( rawData . type == 'Checkpoint' ) { modelType = 'Stable-Diffusion' ; }
@@ -295,6 +292,10 @@ class ModelDownloaderUtil {
295292 if ( rawData . type == 'ControlNet' ) { modelType = 'ControlNet' ; }
296293 if ( rawData . type == 'VAE' ) { modelType = 'VAE' ; }
297294 let imgs = rawVersion . images ? rawVersion . images . filter ( img => img . type == 'image' ) : [ ] ;
295+ let downloadUrl = file . downloadUrl ;
296+ if ( file . name . endsWith ( '.gguf' ) ) {
297+ downloadUrl += `#.gguf` ;
298+ }
298299 let applyMetadata = ( img ) => {
299300 let url = versId ? `${ this . civitPrefix } models/${ id } ?modelVersionId=${ versId } ` : `${ this . civitPrefix } models/${ id } ` ;
300301 metadata = {
@@ -317,7 +318,7 @@ class ModelDownloaderUtil {
317318 if ( [ 'Illustrious' , 'Pony' ] . includes ( rawVersion . baseModel ) ) {
318319 metadata [ 'modelspec.usage_hint' ] = rawVersion . baseModel ;
319320 }
320- callback ( rawData , rawVersion , metadata , modelType , file . downloadUrl , img , imgs . map ( x => x . url ) , null ) ;
321+ callback ( rawData , rawVersion , metadata , modelType , downloadUrl , img , imgs . map ( x => x . url ) , null ) ;
321322 }
322323 if ( imgs . length > 0 ) {
323324 imageToData ( imgs [ 0 ] . url , img => applyMetadata ( img ) , true ) ;
@@ -398,8 +399,8 @@ class ModelDownloaderUtil {
398399 parts [ 4 ] = parts [ 4 ] . substring ( 0 , parts [ 4 ] . length - '?download=true' . length ) ;
399400 this . url . value = `${ this . hfPrefix } ${ parts . join ( '/' ) } ` ;
400401 }
401- if ( ! parts [ 4 ] . endsWith ( '.safetensors' ) && ! parts [ 4 ] . endsWith ( '.sft' ) ) {
402- this . urlStatusArea . innerText = "URL appears to be a huggingface link, but not a safetensors file. Only safetensors can be auto-downloaded." ;
402+ if ( ! parts [ 4 ] . endsWith ( '.safetensors' ) && ! parts [ 4 ] . endsWith ( '.sft' ) && ! parts [ 4 ] . endsWith ( '.gguf' ) ) {
403+ this . urlStatusArea . innerText = "URL appears to be a huggingface link, but not a safetensors file. Only safetensors and GGUF can be auto-downloaded." ;
403404 this . button . disabled = true ;
404405 return ;
405406 }
@@ -408,14 +409,14 @@ class ModelDownloaderUtil {
408409 this . url . value = `${ this . hfPrefix } ${ parts . join ( '/' ) } ` ;
409410 this . urlStatusArea . innerText = "URL appears to be a huggingface link, and has been autocorrected to a download link." ;
410411 this . button . disabled = false ;
411- this . name . value = parts . slice ( 4 ) . join ( '/' ) . replaceAll ( '.safetensors' , '' ) . replaceAll ( '.sft' , '' ) ;
412+ this . name . value = parts . slice ( 4 ) . join ( '/' ) . replaceAll ( '.safetensors' , '' ) . replaceAll ( '.sft' , '' ) . replaceAll ( '.gguf' , '' ) ;
412413 this . nameInput ( ) ;
413414 return ;
414415 }
415416 if ( parts [ 2 ] == 'resolve' ) {
416417 this . urlStatusArea . innerText = "URL appears to be a valid HuggingFace download link." ;
417418 this . button . disabled = false ;
418- this . name . value = parts . slice ( 4 ) . join ( '/' ) . replaceAll ( '.safetensors' , '' ) . replaceAll ( '.sft' , '' ) ;
419+ this . name . value = parts . slice ( 4 ) . join ( '/' ) . replaceAll ( '.safetensors' , '' ) . replaceAll ( '.sft' , '' ) . replaceAll ( '.gguf' , '' ) ;
419420 this . nameInput ( ) ;
420421 return ;
421422 }
0 commit comments