@@ -605,6 +605,11 @@ export class OptionsComponent implements OnInit {
605605 if ( pending . request . queue_type ) {
606606 this . queueType = pending . request . queue_type ;
607607 }
608+ if ( Array . isArray ( pending . request . loras ) ) {
609+ this . selectedLoras = this . resolveHistoryLoras ( pending . request . loras ) ;
610+ this . generationRequest . loras = this . selectedLoras ;
611+ this . updateCreditCost ( ) ;
612+ }
608613 }
609614
610615 // Pending job restore can also carry stale/invalid model values.
@@ -1143,6 +1148,57 @@ export class OptionsComponent implements OnInit {
11431148 this . blobUrls = this . blobUrls . filter ( ( tracked ) => tracked !== url ) ;
11441149 }
11451150
1151+ private snapshotLoras ( loras ?: any [ ] ) : any [ ] {
1152+ if ( ! Array . isArray ( loras ) || loras . length === 0 ) {
1153+ return [ ] ;
1154+ }
1155+ return loras . map ( ( lora ) => ( {
1156+ ...lora ,
1157+ strength : typeof lora ?. strength === 'number' ? lora . strength : 1.0 ,
1158+ } ) ) ;
1159+ }
1160+
1161+ private getHistoryLorasSnapshot ( ) : any [ ] {
1162+ const pending = this . getPendingJob ( ) ;
1163+ if ( Array . isArray ( pending ?. request ?. loras ) ) {
1164+ return this . snapshotLoras ( pending . request . loras ) ;
1165+ }
1166+ if ( Array . isArray ( this . generationRequest ?. loras ) ) {
1167+ return this . snapshotLoras ( this . generationRequest . loras ) ;
1168+ }
1169+ return this . snapshotLoras ( this . selectedLoras ) ;
1170+ }
1171+
1172+ private resolveHistoryLoras ( historyLoras ?: any [ ] ) : any [ ] {
1173+ if ( ! Array . isArray ( historyLoras ) || historyLoras . length === 0 ) {
1174+ return [ ] ;
1175+ }
1176+ const availableLoras = Array . isArray ( this . loras ) ? this . loras : [ ] ;
1177+ const byVersionId = new Map (
1178+ availableLoras
1179+ . filter ( ( lora ) => lora ?. version_id != null )
1180+ . map ( ( lora ) => [ String ( lora . version_id ) , lora ] )
1181+ ) ;
1182+ const byNameVersion = new Map (
1183+ availableLoras . map ( ( lora ) => [ `${ lora ?. name ?? '' } ::${ lora ?. version ?? '' } ` , lora ] )
1184+ ) ;
1185+
1186+ const resolved = historyLoras . map ( ( historyLora ) => {
1187+ const versionKey = historyLora ?. version_id != null ? String ( historyLora . version_id ) : null ;
1188+ const nameVersionKey = `${ historyLora ?. name ?? '' } ::${ historyLora ?. version ?? '' } ` ;
1189+ const match = ( versionKey && byVersionId . get ( versionKey ) ) || byNameVersion . get ( nameVersionKey ) ;
1190+ const strength = typeof historyLora ?. strength === 'number' ? historyLora . strength : 1.0 ;
1191+
1192+ if ( match ) {
1193+ match . strength = strength ;
1194+ return match ;
1195+ }
1196+ return { ...historyLora , strength } ;
1197+ } ) ;
1198+
1199+ return resolved . slice ( 0 , this . maxLoras ) ;
1200+ }
1201+
11461202 // Send job to django api and retrieve job id.
11471203 async submitJob ( mode : 'generate' | 'upscale' | 'hires' = 'generate' ) {
11481204 const effectiveMode : 'generate' | 'upscale' | 'hires' = (
@@ -1281,7 +1337,8 @@ export class OptionsComponent implements OnInit {
12811337 job_type : requestToSend . job_type ,
12821338 model : requestToSend . model ,
12831339 client_id : requestToSend . client_id ,
1284- queue_type : requestToSend . queue_type
1340+ queue_type : requestToSend . queue_type ,
1341+ loras : this . snapshotLoras ( requestToSend . loras )
12851342 } ) ;
12861343
12871344 this . getJob ( response . job_id ) ;
@@ -1435,6 +1492,7 @@ export class OptionsComponent implements OnInit {
14351492 }
14361493 if ( jobComplete && lastResponse ) {
14371494 console . log ( lastResponse ) ;
1495+ const historyLoras = this . getHistoryLorasSnapshot ( ) ;
14381496 const generatedImages = lastResponse . result . map ( ( base64String : string ) => {
14391497 const blob = this . blobMigrationService . base64ToBlob ( base64String )
14401498 const blobUrl = URL . createObjectURL ( blob ) ;
@@ -1448,6 +1506,7 @@ export class OptionsComponent implements OnInit {
14481506 rated : false ,
14491507 timestamp : new Date ( ) ,
14501508 prompt : this . generationRequest . prompt ,
1509+ loras : historyLoras ,
14511510 promptSummary : this . generationRequest . prompt . slice ( 0 , 50 ) + '...' , // Truncate prompt summary
14521511 url : blobUrl // Generate URL
14531512 } as MobiansImage ;
@@ -1473,7 +1532,7 @@ export class OptionsComponent implements OnInit {
14731532
14741533 // Add the images to the image history metadata
14751534 this . imageHistoryMetadata . unshift ( ...generatedImages . map ( ( image : MobiansImage ) => {
1476- return { UUID : image . UUID , prompt : image . prompt ! , promptSummary : image . promptSummary , timestamp : image . timestamp ! , aspectRatio : image . aspectRatio , width : image . width , height : image . height , favorite : false } as MobiansImageMetadata ;
1535+ return { UUID : image . UUID , prompt : image . prompt ! , promptSummary : image . promptSummary , loras : image . loras , timestamp : image . timestamp ! , aspectRatio : image . aspectRatio , width : image . width , height : image . height , favorite : false } as MobiansImageMetadata ;
14771536 } ) ) ;
14781537
14791538 try {
@@ -1689,6 +1748,12 @@ export class OptionsComponent implements OnInit {
16891748 this . generationRequest . prompt = image . prompt ;
16901749 this . sharedService . setPrompt ( image . prompt ! ) ;
16911750 }
1751+
1752+ if ( image . loras !== undefined ) {
1753+ this . selectedLoras = this . resolveHistoryLoras ( image . loras ) ;
1754+ this . generationRequest . loras = this . selectedLoras ;
1755+ this . updateCreditCost ( ) ;
1756+ }
16921757 }
16931758
16941759 async downloadImage ( image : MobiansImage , event ?: Event ) {
@@ -1855,6 +1920,7 @@ export class OptionsComponent implements OnInit {
18551920 aspectRatio : item . aspectRatio ,
18561921 width : item . width ,
18571922 height : item . height ,
1923+ loras : item . loras ,
18581924 favorite : item . favorite
18591925 } ) ) ;
18601926 console . log ( 'Full-text search results:' , projectedResults ) ;
@@ -2550,6 +2616,7 @@ export class OptionsComponent implements OnInit {
25502616 aspectRatio : item . aspectRatio ,
25512617 width : item . width ,
25522618 height : item . height ,
2619+ loras : item . loras ,
25532620 favorite : item . favorite
25542621 } ) ) ;
25552622 } ;
@@ -2595,6 +2662,7 @@ export class OptionsComponent implements OnInit {
25952662 aspectRatio : image . aspectRatio ,
25962663 width : image . width ,
25972664 height : image . height ,
2665+ loras : image . loras ,
25982666 favorite : image . favorite
25992667 } ) ;
26002668 }
@@ -2631,6 +2699,7 @@ export class OptionsComponent implements OnInit {
26312699 aspectRatio : image . aspectRatio ,
26322700 width : image . width ,
26332701 height : image . height ,
2702+ loras : image . loras ,
26342703 favorite : image . favorite
26352704 } ) ;
26362705 }
@@ -2762,6 +2831,11 @@ export class OptionsComponent implements OnInit {
27622831 if ( pending . request ) {
27632832 this . generationRequest = { ...this . generationRequest , ...pending . request } ;
27642833 this . sharedService . setGenerationRequest ( this . generationRequest ) ;
2834+ if ( Array . isArray ( pending . request . loras ) ) {
2835+ this . selectedLoras = this . resolveHistoryLoras ( pending . request . loras ) ;
2836+ this . generationRequest . loras = this . selectedLoras ;
2837+ this . updateCreditCost ( ) ;
2838+ }
27652839 }
27662840 // Clear pending and release any lock just in case
27672841 this . removePendingJob ( ) ;
0 commit comments