Wire Qwen Edit Start still to image_1 and PE-I2I identity keep.
Edit no longer invents strangers when the prompt omits <image1> or PE drops image tokens; Hero stays Klein-only. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import {toggleStyle,parseBatch,stylePrompt} from '../shared/studio2/styles.mjs'
|
||||
import {compilePrompt,validateRequest} from '../shared/studio2/contracts.mjs'
|
||||
import {cachedLoras} from '../shared/studio2/lora-cache.mjs'
|
||||
import {resolveQwen21Size} from '../shared/studio2/qwen21-size.mjs'
|
||||
import {ensureQwen21EditPrompt,stitchQwen21PeEditPrompt,QWEN21_EDIT_KEEP_CHANGE} from '../shared/studio2/qwen21-edit.mjs'
|
||||
|
||||
test('deleted library files never return from job outputs; selection falls back or clears',()=>{
|
||||
const deleted={id:'gone',folderId:'f'},keep={id:'keep',folderId:'f',createdAt:2};const jobs=[{request:{folderId:'f'},outputs:[deleted]}]
|
||||
@@ -98,9 +99,14 @@ test('qwen21 supports Generate and Edit with 25/1 defaults and no locks',()=>{
|
||||
const edit=validateRequest({mode:'edit',engine:'qwen21',folderId:'f',imageAId:'s',promptSections:{action:'change the sky'},settings:{aspect:'auto'}})
|
||||
assert.equal(edit.mode,'edit');assert.equal(edit.settings.steps,25);assert.equal(edit.settings.cfg,1)
|
||||
assert.equal(edit.lockFace,false);assert.deepEqual(edit.settings.loraStack,[])
|
||||
assert.throws(()=>validateRequest({mode:'edit',engine:'qwen21',folderId:'f',promptSections:{action:'x'}}),/source still/)
|
||||
assert.throws(()=>validateRequest({mode:'edit',engine:'qwen21',folderId:'f',promptSections:{action:'x'}}),/Start still/)
|
||||
assert.throws(()=>validateRequest({mode:'edit',engine:'qwen21',folderId:'f',identityStillId:'hero',promptSections:{action:'x'}}),/Start still/)
|
||||
assert.throws(()=>validateRequest({mode:'compose',engine:'qwen21',folderId:'f',imageAId:'s',imageBId:'b',promptSections:{action:'x'}}),/Generate and Edit/)
|
||||
assert.throws(()=>validateRequest({mode:'iterate',engine:'qwen21',folderId:'f',imageAId:'s',promptSections:{action:'x'}}),/Generate and Edit/)
|
||||
assert.equal(ensureQwen21EditPrompt('put her in a red leather jacket'),`${QWEN21_EDIT_KEEP_CHANGE} put her in a red leather jacket`)
|
||||
assert.equal(ensureQwen21EditPrompt('change <image1> outfit'),'change <image1> outfit')
|
||||
assert.match(stitchQwen21PeEditPrompt('a woman in a red jacket'),/<image1>/)
|
||||
assert.equal(stitchQwen21PeEditPrompt('keep <image1> add jacket'),'keep <image1> add jacket')
|
||||
})
|
||||
test('hydrateStudio2Job restores LoRA strengths, locked seed, and clears missing stills',()=>{
|
||||
const form={mode:'generate',engine:'flux',identityStillId:'',imageAId:'',promptSections:{action:''},imageStyles:{positive:[],negative:[]},settings:{aspect:'auto',seed:null,seedMode:'random',loraStack:[]},guides:[]}
|
||||
@@ -121,12 +127,24 @@ test('custom negative chips survive normalizeStyles and bench exposes Load actio
|
||||
assert.match(src,/aspect:'auto'/);assert.match(src,/strip-actions/);assert.match(src,/addNegative/)
|
||||
assert.match(src,/Enhance prompt/);assert.match(src,/enhancePrompt/)
|
||||
assert.match(src,/\bTurbo\b/);assert.match(src,/form\.turbo/)
|
||||
assert.match(src,/Qwen Edit uses Start still as/)
|
||||
assert.match(src,/Hero is Klein-only and is ignored/)
|
||||
const peT2i=readFileSync(new URL('../server/assets/studio2_qwen21_pe_t2i.json',import.meta.url),'utf8')
|
||||
const peEdit=readFileSync(new URL('../server/assets/studio2_qwen21_pe_edit.json',import.meta.url),'utf8')
|
||||
assert.match(peT2i,/QwenImage21_T2IPromptRewrite/);assert.match(peT2i,/pe_t2i\.int8_convrot/)
|
||||
assert.match(peEdit,/QwenImage21_EditPromptRewrite/);assert.match(peEdit,/pe_i2i\.int8_convrot/)
|
||||
assert.doesNotMatch(peT2i,/UnetLoader|KSampler|VAELoader/)
|
||||
assert.doesNotMatch(peEdit,/UnetLoader|KSampler|VAELoader/)
|
||||
assert.match(peEdit,/"image_1":\s*\["10",\s*0\]/)
|
||||
const editGraph=readFileSync(new URL('../server/assets/studio2_qwen21_edit.json',import.meta.url),'utf8')
|
||||
assert.match(editGraph,/"images\.image_1":\s*\["10",\s*0\]/)
|
||||
assert.match(editGraph,/"latent_image":\s*\["9",\s*2\]/)
|
||||
assert.doesNotMatch(editGraph,/EmptyLatentImage/)
|
||||
const runner=readFileSync(new URL('../server/utils/studio2/runner.ts',import.meta.url),'utf8')
|
||||
assert.match(runner,/ensureQwen21EditPrompt/)
|
||||
assert.match(runner,/stitchQwen21PeEditPrompt/)
|
||||
assert.match(runner,/images\.image_1/)
|
||||
assert.doesNotMatch(runner,/Keep the subject in <image1>/)
|
||||
const t2i=readFileSync(new URL('../server/assets/studio2_qwen21_t2i.json',import.meta.url),'utf8')
|
||||
assert.match(t2i,/EmptyLatentImage/);assert.match(t2i,/"latent_image":\s*\["16",\s*0\]/)
|
||||
const turboT2i=readFileSync(new URL('../server/assets/studio2_qwen21_t2i_turbo.json',import.meta.url),'utf8')
|
||||
|
||||
Reference in New Issue
Block a user