import { validateRequest } from '~/shared/studio2/contracts.mjs'; import { resolveRequestSize } from '../../utils/studio2/size'; import { parsePostedLoraStack, assertImageV2LoraStack } from '../../utils/loras'; import { saveRecord, readRecord } from '../../utils/studio2/store'; import { addStudioJob, kickStudioQueue, type StudioJobPayload } from '../../utils/studioQueue'; export default defineEventHandler(async (event) => { const { owner } = assertLibraryOwner(event), raw = await readBody(event); let request: any; try { request = validateRequest(raw, useRuntimeConfig().public.studio === 'xaigen'); } catch (e: any) { throw createError({ statusCode: e.statusCode || 400, statusMessage: e.message }); } const video = ['video', 'extend'].includes(request.mode); if (video && request.engine !== 'minimax') throw createError({ statusCode: 400, statusMessage: 'Use the existing xAIGen studio for LTX. Studio 2 video currently supports MiniMax.' }); request.settings.loraStack = parsePostedLoraStack(request.settings.loraStack, video ? 'video' : 'image'); if (!video) assertImageV2LoraStack(request.settings.loraStack, request.engine); assertFolderAccess(event, request.folderId); for (const id of [request.identityStillId, request.imageAId, request.imageBId, request.maskId, request.endStillId, ...request.guides.map((g: any) => g.stillId)].filter(Boolean)) assertFolderAccess(event, getStill(owner, id).folderId); if (request.startClipId) assertFolderAccess(event, getClip(owner, request.startClipId).folderId); await resolveRequestSize(owner,request); const id = crypto.randomUUID(), record = { id, owner, request, state: 'waiting', queuedAt: Date.now(), familyId: crypto.randomUUID(), outputs: [], purgeResult: 'Not yet saved' }; saveRecord(record); const row = await addStudioJob({ ownerKey: owner, kind: ['video', 'extend'].includes(request.mode) ? 'video' : 'edit', familyId: record.familyId, payload: { ...request.settings, studio2Id: id, prompt: request.compiledPrompt, folderId: request.folderId, extensions: [], referenceStillIds: [], useIdentityRefs: false, queueAutoRun: true } as StudioJobPayload }); saveRecord({ ...readRecord(owner, id), queueId: row.id }); kickStudioQueue(); return { id, seed:request.settings.seed, width:request.settings.width, height:request.settings.height }; });