Show Flux and Krea as Image v2 engine cards, and run Krea on edit, compose, and refine.
Krea image-to-image uses encode plus denoise graphs, not Klein reference latents, and still fails closed if the Krea models are missing. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+61
-53
@@ -711,29 +711,29 @@
|
||||
</div>
|
||||
<div v-else-if="studioMode === 'editv2'" class="space-y-3">
|
||||
<p class="text-xs text-zinc-500">Edit, Compose, Refine, and Generate are separate graphs. Shares the desktop GPU with video.</p>
|
||||
<p class="mb-2 text-xs uppercase tracking-wider text-zinc-500">Image engine</p>
|
||||
<div class="grid grid-cols-2 gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-xl border px-3 py-2 text-left text-sm"
|
||||
:class="v2Engine === 'flux' ? 'border-amber-300 bg-amber-400/10 text-amber-100' : 'border-white/10 hover:border-white/20'"
|
||||
@click="setV2Engine('flux')"
|
||||
>
|
||||
<span class="block font-semibold">Flux</span>
|
||||
<span class="text-xs text-zinc-400">Klein 9B. Edit, compose, refine, and generate.</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-xl border px-3 py-2 text-left text-sm"
|
||||
:class="v2Engine === 'krea' ? 'border-amber-300 bg-amber-400/10 text-amber-100' : 'border-white/10 hover:border-white/20'"
|
||||
@click="setV2Engine('krea')"
|
||||
>
|
||||
<span class="block font-semibold">Krea</span>
|
||||
<span class="text-xs text-zinc-400">Krea 2 Turbo. Photograph engine for stills.</span>
|
||||
</button>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-zinc-500">Flux is Klein 9B. Krea is Krea 2 Turbo. Video stays MiniMax or LTX.</p>
|
||||
<div v-if="v2Mode === 'generate'" class="space-y-3 rounded-2xl border border-white/10 bg-zinc-950/40 p-3">
|
||||
<div>
|
||||
<p class="text-xs text-zinc-400">Engine</p>
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-full border px-2.5 py-1 text-xs"
|
||||
:class="v2Engine === 'flux' ? 'border-amber-300/70 text-amber-100' : 'border-white/10 text-zinc-400'"
|
||||
@click="setV2Engine('flux')"
|
||||
>
|
||||
Flux
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-full border px-2.5 py-1 text-xs"
|
||||
:class="v2Engine === 'krea' ? 'border-amber-300/70 text-amber-100' : 'border-white/10 text-zinc-400'"
|
||||
@click="setV2Engine('krea')"
|
||||
>
|
||||
Krea
|
||||
</button>
|
||||
</div>
|
||||
<p class="mt-2 text-xs text-zinc-500">Flux is the current edit and compose engine. Krea is a separate photograph engine.</p>
|
||||
</div>
|
||||
<div>
|
||||
<p class="text-xs text-zinc-400">Size · near 1 MP</p>
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
@@ -750,7 +750,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="v2Mode === 'refine'" class="space-y-2 rounded-2xl border border-white/10 bg-zinc-950/40 p-3">
|
||||
<div v-if="v2Mode === 'refine' || (v2Engine === 'krea' && v2Mode !== 'generate')" class="space-y-2 rounded-2xl border border-white/10 bg-zinc-950/40 p-3">
|
||||
<label class="block text-sm">
|
||||
<span class="mb-1 block text-zinc-300">Strength (denoise)</span>
|
||||
<div class="flex items-center gap-3">
|
||||
@@ -765,7 +765,7 @@
|
||||
<span class="w-12 tabular-nums text-sm text-zinc-200">{{ v2Denoise }}</span>
|
||||
</div>
|
||||
</label>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<div v-if="v2Mode === 'refine'" class="flex flex-wrap gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-full border px-2.5 py-1 text-xs"
|
||||
@@ -1986,7 +1986,9 @@ import {
|
||||
IMAGE_V2_GENERATE_HEIGHT,
|
||||
IMAGE_V2_GENERATE_WIDTH,
|
||||
IMAGE_V2_KREA_CFG,
|
||||
IMAGE_V2_KREA_COMPOSE_DENOISE,
|
||||
IMAGE_V2_KREA_CONCEPT_LORA,
|
||||
IMAGE_V2_KREA_EDIT_DENOISE,
|
||||
IMAGE_V2_KREA_STEPS,
|
||||
IMAGE_V2_REFINE_FACE,
|
||||
IMAGE_V2_REFINE_FACE_PROMPT,
|
||||
@@ -3503,18 +3505,18 @@ function currentPresetSnapshot() {
|
||||
loraStack: [],
|
||||
settings: {
|
||||
mode: v2Mode.value,
|
||||
engine: v2Mode.value === 'generate' ? v2Engine.value : 'flux',
|
||||
engine: v2Engine.value,
|
||||
task: v2Mode.value === 'compose' ? v2Task.value : v2Mode.value === 'refine' ? 'refine' : v2Mode.value === 'generate' ? 't2i' : 'scene',
|
||||
negative: v2Negative.value,
|
||||
snofsModel: v2ConceptLoraEnabled.value ? clampImageV2Strength(v2SnofsModel.value, IMAGE_V2_SNOFS_MODEL) : 0,
|
||||
snofsClip: v2ConceptLoraEnabled.value ? clampImageV2Strength(v2SnofsClip.value, IMAGE_V2_SNOFS_CLIP) : 0,
|
||||
consistencyModel: v2Mode.value === 'generate' ? 0 : clampImageV2Strength(v2ConsistencyModel.value, IMAGE_V2_CONSISTENCY_MODEL),
|
||||
consistencyClip: v2Mode.value === 'generate' ? 0 : clampImageV2Strength(v2ConsistencyClip.value, IMAGE_V2_CONSISTENCY_CLIP),
|
||||
steps: clampImageSteps(v2Steps.value, IMAGE_V2_STEPS_DEFAULT),
|
||||
cfg: clampImageCfg(v2Cfg.value, IMAGE_V2_CFG_DEFAULT),
|
||||
consistencyModel: v2Mode.value === 'generate' || v2Engine.value === 'krea' ? 0 : clampImageV2Strength(v2ConsistencyModel.value, IMAGE_V2_CONSISTENCY_MODEL),
|
||||
consistencyClip: v2Mode.value === 'generate' || v2Engine.value === 'krea' ? 0 : clampImageV2Strength(v2ConsistencyClip.value, IMAGE_V2_CONSISTENCY_CLIP),
|
||||
steps: clampImageSteps(v2Steps.value, v2Engine.value === 'krea' ? IMAGE_V2_KREA_STEPS : IMAGE_V2_STEPS_DEFAULT),
|
||||
cfg: clampImageCfg(v2Cfg.value, v2Engine.value === 'krea' ? IMAGE_V2_KREA_CFG : IMAGE_V2_CFG_DEFAULT),
|
||||
megapixels: v2Mode.value === 'generate' ? undefined : clampImageScaleMegapixels(v2Megapixels.value, 1),
|
||||
turbo: v2Turbo.value === true,
|
||||
strength: v2Mode.value === 'refine' ? clampImageV2Denoise(v2Denoise.value) : undefined,
|
||||
strength: v2Mode.value === 'generate' || (v2Mode.value !== 'refine' && v2Engine.value !== 'krea') ? undefined : clampImageV2Denoise(v2Denoise.value),
|
||||
width: v2Mode.value === 'generate' ? v2Width.value : undefined,
|
||||
height: v2Mode.value === 'generate' ? v2Height.value : undefined
|
||||
}
|
||||
@@ -3556,18 +3558,18 @@ function applyGenerationPreset(preset: GenerationPreset) {
|
||||
if (preset.kind === 'imagev2') {
|
||||
const settings = preset.settings as ImageV2PresetSettings
|
||||
v2Mode.value = settings.mode === 'compose' ? 'compose' : settings.mode === 'refine' ? 'refine' : settings.mode === 'generate' ? 'generate' : 'edit'
|
||||
v2Engine.value = v2Mode.value === 'generate' ? parseImageV2Engine(settings.engine, 'flux') : 'flux'
|
||||
v2Engine.value = parseImageV2Engine(settings.engine, 'flux')
|
||||
v2Task.value = v2Mode.value === 'compose' ? (settings.task || 'scene') : v2Mode.value === 'refine' ? 'refine' : v2Mode.value === 'generate' ? 't2i' : 'scene'
|
||||
if (typeof settings.negative === 'string') v2Negative.value = settings.negative
|
||||
v2SnofsModel.value = v2ConceptLoraEnabled.value ? clampImageV2Strength(settings.snofsModel, IMAGE_V2_SNOFS_MODEL) : 0
|
||||
v2SnofsClip.value = v2ConceptLoraEnabled.value ? clampImageV2Strength(settings.snofsClip, IMAGE_V2_SNOFS_CLIP) : 0
|
||||
v2ConsistencyModel.value = v2Mode.value === 'generate' ? 0 : clampImageV2Strength(settings.consistencyModel, IMAGE_V2_CONSISTENCY_MODEL)
|
||||
v2ConsistencyClip.value = v2Mode.value === 'generate' ? 0 : clampImageV2Strength(settings.consistencyClip, IMAGE_V2_CONSISTENCY_CLIP)
|
||||
v2Steps.value = clampImageSteps(settings.steps, IMAGE_V2_STEPS_DEFAULT)
|
||||
v2Cfg.value = clampImageCfg(settings.cfg, IMAGE_V2_CFG_DEFAULT)
|
||||
v2ConsistencyModel.value = v2Mode.value === 'generate' || v2Engine.value === 'krea' ? 0 : clampImageV2Strength(settings.consistencyModel, IMAGE_V2_CONSISTENCY_MODEL)
|
||||
v2ConsistencyClip.value = v2Mode.value === 'generate' || v2Engine.value === 'krea' ? 0 : clampImageV2Strength(settings.consistencyClip, IMAGE_V2_CONSISTENCY_CLIP)
|
||||
v2Steps.value = clampImageSteps(settings.steps, v2Engine.value === 'krea' ? IMAGE_V2_KREA_STEPS : IMAGE_V2_STEPS_DEFAULT)
|
||||
v2Cfg.value = clampImageCfg(settings.cfg, v2Engine.value === 'krea' ? IMAGE_V2_KREA_CFG : IMAGE_V2_CFG_DEFAULT)
|
||||
v2Megapixels.value = clampImageScaleMegapixels(settings.megapixels, 1)
|
||||
v2Turbo.value = settings.turbo === true
|
||||
if (v2Mode.value === 'refine') v2Denoise.value = clampImageV2Denoise(settings.strength)
|
||||
if (v2Mode.value === 'refine' || (v2Engine.value === 'krea' && v2Mode.value !== 'generate')) v2Denoise.value = clampImageV2Denoise(settings.strength)
|
||||
if (v2Mode.value === 'generate') {
|
||||
const size = clampImageV2Size(settings.width, settings.height)
|
||||
v2Width.value = size.width
|
||||
@@ -4839,7 +4841,7 @@ function applyStillSettings(still: LibraryStill) {
|
||||
? settings.mode
|
||||
: 'edit'
|
||||
setV2Mode(mode)
|
||||
v2Engine.value = mode === 'generate' ? parseImageV2Engine(settings.engine, 'flux') : 'flux'
|
||||
v2Engine.value = parseImageV2Engine(settings?.engine, 'flux')
|
||||
if (!settings) return
|
||||
if (typeof settings.negative === 'string') v2Negative.value = settings.negative
|
||||
if (v2ConceptLoraEnabled.value) {
|
||||
@@ -4849,7 +4851,7 @@ function applyStillSettings(still: LibraryStill) {
|
||||
v2SnofsModel.value = 0
|
||||
v2SnofsClip.value = 0
|
||||
}
|
||||
if (mode !== 'generate') {
|
||||
if (mode !== 'generate' && v2Engine.value !== 'krea') {
|
||||
if (settings.consistencyModel != null) v2ConsistencyModel.value = clampImageV2Strength(settings.consistencyModel, IMAGE_V2_CONSISTENCY_MODEL)
|
||||
if (settings.consistencyClip != null) v2ConsistencyClip.value = clampImageV2Strength(settings.consistencyClip, IMAGE_V2_CONSISTENCY_CLIP)
|
||||
}
|
||||
@@ -4857,7 +4859,7 @@ function applyStillSettings(still: LibraryStill) {
|
||||
if (settings.cfg != null) v2Cfg.value = clampImageCfg(settings.cfg, IMAGE_V2_CFG_DEFAULT)
|
||||
if (settings.megapixels != null) v2Megapixels.value = clampImageScaleMegapixels(settings.megapixels, 1)
|
||||
v2Turbo.value = settings.turbo === true
|
||||
if (mode === 'refine' && settings.strength != null) v2Denoise.value = clampImageV2Denoise(settings.strength)
|
||||
if ((mode === 'refine' || (v2Engine.value === 'krea' && mode !== 'generate')) && settings.strength != null) v2Denoise.value = clampImageV2Denoise(settings.strength)
|
||||
if (mode === 'generate') {
|
||||
const size = clampImageV2Size(settings.width, settings.height)
|
||||
v2Width.value = size.width
|
||||
@@ -5466,17 +5468,15 @@ function setV2Mode(mode: ImageV2Mode) {
|
||||
v2Task.value = 't2i'
|
||||
v2ConsistencyModel.value = 0
|
||||
v2ConsistencyClip.value = 0
|
||||
} else {
|
||||
v2Engine.value = 'flux'
|
||||
if (previous === 'generate' && v2ConsistencyModel.value === 0 && v2ConsistencyClip.value === 0) {
|
||||
v2ConsistencyModel.value = IMAGE_V2_CONSISTENCY_MODEL
|
||||
v2ConsistencyClip.value = IMAGE_V2_CONSISTENCY_CLIP
|
||||
}
|
||||
} else if (previous === 'generate' && v2Engine.value === 'flux' && v2ConsistencyModel.value === 0 && v2ConsistencyClip.value === 0) {
|
||||
v2ConsistencyModel.value = IMAGE_V2_CONSISTENCY_MODEL
|
||||
v2ConsistencyClip.value = IMAGE_V2_CONSISTENCY_CLIP
|
||||
}
|
||||
if (v2Engine.value === 'krea' && mode === 'edit') v2Denoise.value = IMAGE_V2_KREA_EDIT_DENOISE
|
||||
if (v2Engine.value === 'krea' && mode === 'compose') v2Denoise.value = IMAGE_V2_KREA_COMPOSE_DENOISE
|
||||
}
|
||||
|
||||
function setV2Engine(engine: ImageV2Engine) {
|
||||
if (engine === 'krea' && v2Mode.value !== 'generate') return
|
||||
const previous = v2Engine.value
|
||||
v2Engine.value = engine
|
||||
if (engine === 'krea') {
|
||||
@@ -5487,6 +5487,8 @@ function setV2Engine(engine: ImageV2Engine) {
|
||||
v2ConsistencyModel.value = 0
|
||||
v2ConsistencyClip.value = 0
|
||||
v2Turbo.value = false
|
||||
if (v2Mode.value === 'edit') v2Denoise.value = IMAGE_V2_KREA_EDIT_DENOISE
|
||||
if (v2Mode.value === 'compose') v2Denoise.value = IMAGE_V2_KREA_COMPOSE_DENOISE
|
||||
return
|
||||
}
|
||||
if (previous === 'krea') {
|
||||
@@ -5494,6 +5496,10 @@ function setV2Engine(engine: ImageV2Engine) {
|
||||
v2Cfg.value = IMAGE_V2_CFG_DEFAULT
|
||||
v2SnofsModel.value = v2ConceptLoraEnabled.value ? IMAGE_V2_SNOFS_MODEL : 0
|
||||
v2SnofsClip.value = v2ConceptLoraEnabled.value ? IMAGE_V2_SNOFS_CLIP : 0
|
||||
if (v2Mode.value !== 'generate') {
|
||||
v2ConsistencyModel.value = IMAGE_V2_CONSISTENCY_MODEL
|
||||
v2ConsistencyClip.value = IMAGE_V2_CONSISTENCY_CLIP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5587,21 +5593,23 @@ async function editImageV2() {
|
||||
body.append('task', v2Mode.value === 'generate' ? 't2i' : v2Mode.value === 'refine' ? 'refine' : v2Mode.value === 'compose' ? v2Task.value : 'scene')
|
||||
if (v2Mode.value !== 'generate' && file.value) body.append('image_a', file.value)
|
||||
if (v2Mode.value === 'compose' && editRefFile.value) body.append('image_b', editRefFile.value)
|
||||
if (v2Mode.value === 'refine') {
|
||||
const maskBlob = await refinePainter.value?.exportPng()
|
||||
if (!maskBlob) {
|
||||
toast('Paint a mask on Still A first. Refine will not fall back to Edit.')
|
||||
return
|
||||
if (v2Mode.value === 'refine' || (v2Engine.value === 'krea' && v2Mode.value !== 'generate')) {
|
||||
if (v2Mode.value === 'refine') {
|
||||
const maskBlob = await refinePainter.value?.exportPng()
|
||||
if (!maskBlob) {
|
||||
toast('Paint a mask on Still A first. Refine will not fall back to Edit.')
|
||||
return
|
||||
}
|
||||
body.append('mask', new File([maskBlob], 'refine-mask.png', { type: 'image/png' }))
|
||||
}
|
||||
body.append('mask', new File([maskBlob], 'refine-mask.png', { type: 'image/png' }))
|
||||
body.append('strength', String(clampImageV2Denoise(v2Denoise.value)))
|
||||
}
|
||||
if (v2Mode.value === 'generate') {
|
||||
const size = clampImageV2Size(v2Width.value, v2Height.value)
|
||||
body.append('width', String(size.width))
|
||||
body.append('height', String(size.height))
|
||||
body.append('engine', v2Engine.value)
|
||||
}
|
||||
body.append('engine', v2Engine.value)
|
||||
body.append('prompt', prompt.value.trim())
|
||||
body.append('negative', v2Negative.value)
|
||||
body.append('snofs_model', String(v2ConceptLoraEnabled.value ? clampImageV2Strength(v2SnofsModel.value, v2Engine.value === 'krea' ? 0 : IMAGE_V2_SNOFS_MODEL) : 0))
|
||||
|
||||
Reference in New Issue
Block a user