Restore Studio 2 Load hydrate, sticky negatives, and strip actions.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import {restoreLoras,loraUse} from './lora-memory.mjs'
|
||||
import { restoreInput } from './contracts.mjs'
|
||||
import { restoreInput, sectionsFrom } from './contracts.mjs'
|
||||
import { normalizeStyles } from './styles.mjs'
|
||||
export const aspectOptions = [{id:'auto',label:'Automatic',hint:'Match start or hero still'},{id:'16:9',label:'16:9',hint:'1344 × 768 · padded'},{id:'9:16',label:'9:16',hint:'768 × 1344 · padded'},{id:'1:1',label:'1:1',hint:'960 × 960 · padded'}]
|
||||
export function resolveQwen21Size(aspect, source) {
|
||||
const presets = {'16:9':[1024,576],'9:16':[576,1024],'1:1':[1024,1024]}
|
||||
@@ -70,6 +71,70 @@ export function changeSource(form) {
|
||||
|
||||
export function useAsHero(form, item) { return {...form,identityStillId:item.id} }
|
||||
export function useAsSource(form, item) { return {...form,imageAId:item.id} }
|
||||
|
||||
/** Hydrate the live bench from a saved Studio 2 request (Load). Does not enqueue. */
|
||||
export function hydrateStudio2Job(form, saved, { stillIds = new Set(), clipIds = new Set(), xaigen = false, memory } = {}) {
|
||||
const src = structuredClone(saved?.studio2 || saved || {})
|
||||
const missing = []
|
||||
const keepStill = (id, label) => {
|
||||
const value = id || ''
|
||||
if (!value) return ''
|
||||
if (stillIds.has(value)) return value
|
||||
missing.push(`${label} missing from library`)
|
||||
return ''
|
||||
}
|
||||
const keepClip = (id, label) => {
|
||||
const value = id || ''
|
||||
if (!value) return ''
|
||||
if (clipIds.has(value)) return value
|
||||
missing.push(`${label} missing from library`)
|
||||
return ''
|
||||
}
|
||||
const modeRaw = src.mode === 'iterate' ? 'edit' : src.mode
|
||||
const mode = ['generate','edit','compose','refine','video','extend','music'].includes(modeRaw) ? modeRaw : 'edit'
|
||||
let engine = src.engine === 'qwen21' ? 'qwen21' : src.engine === 'krea' ? 'krea' : src.engine === 'ltx' ? 'ltx' : src.engine === 'minimax' ? 'minimax' : 'flux'
|
||||
if (['video','extend'].includes(mode)) engine = xaigen && engine === 'ltx' ? 'ltx' : 'minimax'
|
||||
else if (engine === 'minimax' || engine === 'ltx') engine = 'flux'
|
||||
const settings = structuredClone(src.settings || {})
|
||||
const aspect = ['auto','16:9','9:16','1:1'].includes(settings.aspect) ? settings.aspect : 'auto'
|
||||
const loraStack = Array.isArray(settings.loraStack) ? settings.loraStack.map(item => ({
|
||||
name: item.name,
|
||||
strengthModel: Number(item.strengthModel ?? item.strength ?? 1),
|
||||
strengthClip: Number(item.strengthClip ?? item.strengthModel ?? item.strength ?? 1)
|
||||
})) : []
|
||||
const guides = (Array.isArray(src.guides) ? src.guides : []).map(g => {
|
||||
const stillId = keepStill(g.stillId, 'guide still')
|
||||
return stillId ? { stillId, frame: g.frame } : null
|
||||
}).filter(Boolean)
|
||||
const next = {
|
||||
...form,
|
||||
mode,
|
||||
engine,
|
||||
lockFace: src.lockFace !== false,
|
||||
lockOutfit: src.lockOutfit !== false,
|
||||
hideInput: !!src.hideInput,
|
||||
folderId: src.folderId || form.folderId,
|
||||
identityStillId: keepStill(src.identityStillId, 'hero'),
|
||||
imageAId: keepStill(src.imageAId, 'start'),
|
||||
imageBId: keepStill(src.imageBId, 'second still'),
|
||||
maskId: keepStill(src.maskId, 'mask'),
|
||||
startClipId: keepClip(src.startClipId, 'start clip'),
|
||||
endStillId: keepStill(src.endStillId, 'end still'),
|
||||
guides,
|
||||
imageStyles: normalizeStyles(src.imageStyles || { positive: [], negative: [] }),
|
||||
promptSections: sectionsFrom(src.promptSections || { action: src.compiledPrompt || src.prompt || '' }),
|
||||
settings: {
|
||||
...form.settings,
|
||||
...settings,
|
||||
aspect,
|
||||
seed: settings.seed ?? form.settings?.seed ?? null,
|
||||
seedMode: 'locked',
|
||||
loraStack
|
||||
}
|
||||
}
|
||||
return { form: restoreLoras(next, loraStack, xaigen, memory), missing: missing[0] || '', warnings: missing }
|
||||
}
|
||||
|
||||
export function restoreAll(form,item,xaigen=false,memory) {
|
||||
const restored=restoreInput(item),next={...form,...restored,settings:{...form.settings,...restored.settings,seedMode:'random'}}
|
||||
if(item.kind==='clip') return {...bindClip(next,item,xaigen,memory),mode:'extend'}
|
||||
|
||||
Reference in New Issue
Block a user