31 lines
1.5 KiB
JavaScript
31 lines
1.5 KiB
JavaScript
export const CAPTION_STYLES = ['descriptive', 'klein_prompt', 'delta', 'tags']
|
|
|
|
export const DELTA_LOCKED_LOOK =
|
|
'short light-brown bob, pink tank, light blue shorts, open green Slytherin robe with red-gold trim, barefoot'
|
|
|
|
export function captionStylePrompt(style) {
|
|
switch (style) {
|
|
case 'klein_prompt':
|
|
return 'Write one self-contained image generation prompt for Flux Klein. Include subject, pose, clothing, setting, lighting, and camera. No preamble or quotes.'
|
|
case 'delta':
|
|
return `The character's locked baseline look is: ${DELTA_LOCKED_LOOK}. Describe ONLY what changed from that baseline in this image. Do not restate the locked look.`
|
|
case 'tags':
|
|
return 'List comma-separated descriptive tags for this image. Tags only, no sentences.'
|
|
case 'descriptive':
|
|
default:
|
|
return 'Describe this image in clear, detailed prose. Cover subject, appearance, clothing, pose, setting, and lighting.'
|
|
}
|
|
}
|
|
|
|
export function validateCaptionBody(raw) {
|
|
const fail = message => { throw Object.assign(new Error(message), { statusCode: 400 }) }
|
|
const body = raw || {}
|
|
const style = String(body.captionStyle || body.style || 'descriptive')
|
|
if (!CAPTION_STYLES.includes(style)) fail('Unknown caption style.')
|
|
const folderId = String(body.folderId || '')
|
|
if (!folderId) fail('Choose a folder.')
|
|
const stillId = String(body.stillId || body.sourcePath || '')
|
|
if (!stillId) fail('Choose a still to describe.')
|
|
return { folderId, stillId, captionStyle: style }
|
|
}
|