Replace Hero/Edit-source chrome with Photos role cards.

Inspector stills use plain-English roles and Mention phrases; Qwen Generate hides Photos entirely.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-09-26 16:00:37 -05:00
co-authored by Cursor
parent 58c5458c87
commit 5c2248a3fd
7 changed files with 690 additions and 105 deletions
+22 -5
View File
@@ -100,8 +100,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'}}),/Start still/)
assert.throws(()=>validateRequest({mode:'edit',engine:'qwen21',folderId:'f',identityStillId:'hero',promptSections:{action:'x'}}),/Start still/)
assert.throws(()=>validateRequest({mode:'edit',engine:'qwen21',folderId:'f',promptSections:{action:'x'}}),/Photo to change/)
assert.throws(()=>validateRequest({mode:'edit',engine:'qwen21',folderId:'f',identityStillId:'hero',promptSections:{action:'x'}}),/Photo to change/)
const qwenPhotos=validateRequest({mode:'edit',engine:'qwen21',folderId:'f',photos:[{stillId:'person',role:'change'},{stillId:'dress',role:'outfit'}],promptSections:{action:'Put her in that dress.'},settings:{aspect:'auto'}})
assert.equal(qwenPhotos.imageAId,'person')
assert.equal(qwenPhotos.imageBId,'dress')
assert.equal(qwenPhotos.identityStillId,'')
assert.match(qwenPhotos.compiledPrompt,/Put her in that dress/)
assert.doesNotMatch(String(qwenPhotos.promptSections.action),/<image1>/)
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`)
@@ -152,12 +158,23 @@ test('custom negative chips survive normalizeStyles and bench exposes Load actio
styles=toggleStyle(styles,'deformed',true)
assert.deepEqual(styles.negative,['blurry','my watermark','deformed'])
const src=readFileSync(new URL('../components/studio2/Bench.vue',import.meta.url),'utf8')
assert.match(src,/loadSelectedJob/);assert.match(src,/hydrateStudio2Job/);assert.match(src,/Edit source/)
const slot=readFileSync(new URL('../components/studio2/AssetSlot.vue',import.meta.url),'utf8')
assert.match(src,/loadSelectedJob/);assert.match(src,/hydrateStudio2Job/);assert.match(src,/Photos/)
assert.match(src,/photosPlanState\.emptyHint/)
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(slot,/Mention in prompt/);assert.match(slot,/This photo is/)
assert.doesNotMatch(src,/Hero still/)
assert.doesNotMatch(src,/Edit source/)
assert.doesNotMatch(src,/Identity \/ reference/)
assert.doesNotMatch(src,/Qwen Edit uses Start still/)
assert.doesNotMatch(src,/Hero is Klein-only/)
assert.doesNotMatch(slot,/<image1>/)
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 photosSrc=readFileSync(new URL('../shared/studio2/photos.mjs',import.meta.url),'utf8')
assert.match(photosSrc,/Photo to change/)
assert.match(photosSrc,/mentionPhrase/)
assert.match(photosSrc,/Add a photo, then say what it is/)
assert.match(readFileSync(new URL('../components/studio2/Details.vue',import.meta.url),'utf8'),/\bTyped\b/)
assert.match(readFileSync(new URL('../utils/libraryGeneration.ts',import.meta.url),'utf8'),/\bTyped\b/)
assert.match(readFileSync(new URL('../utils/libraryGeneration.ts',import.meta.url),'utf8'),/promptRaw/)