Add LoRA stacks with per-item strengths and named video/image generation presets so setups survive reload without mixing Klein onto MiniMax. Keep LTX Pink Cherry and xAIGen LoRAs on xAIGen, and run Recommend on Beast.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-08-28 15:24:44 -05:00
co-authored by Cursor
parent 0af3cddb14
commit f8db0d626a
36 changed files with 1767 additions and 246 deletions
+12
View File
@@ -3,10 +3,14 @@ import workflowV1 from '../assets/workflow_minimax_video.json'
import workflowV2 from '../assets/workflow_minimax_video_v2.json'
import workflowLtx from '../assets/workflow_ltx_video.json'
import { buildIdentityPrompt } from '~/utils/identityPrompt'
import { applyUserLoraToGraph } from '~/server/utils/loras'
import type { LoraStackItem } from '~/utils/loras'
import {
isLtxWorkflow,
isTextToVideo,
LTX_DISABLED_MESSAGE,
LTX_NEGATIVE,
ltxWorkflowEnabled,
parseVideoWorkflow,
type VideoWorkflowId
} from '~/utils/videoModels'
@@ -33,6 +37,8 @@ export interface GenerateParams {
duration?: number
useIdentityRefs?: boolean
referenceImageNames?: string[]
loraName?: string
loraStack?: LoraStackItem[]
}
type WorkflowNode = { class_type: string; inputs: Record<string, unknown>; _meta?: { title?: string } }
@@ -74,6 +80,9 @@ function templateFor(id: VideoWorkflowId) {
export function buildWorkflow(params: GenerateParams) {
const version = parseVideoWorkflow(params.workflow)
if (isLtxWorkflow(version) && !ltxWorkflowEnabled()) {
throw new Error(LTX_DISABLED_MESSAGE)
}
if (isLtxWorkflow(version)) return buildLtxWorkflow(params, version)
const graph = structuredClone(templateFor(version === 't2v' ? 'v1' : version === 'v2' ? 'v2' : 'v1'))
@@ -216,6 +225,7 @@ export function buildWorkflow(params: GenerateParams) {
if (graph['105:104']?.inputs) delete graph['105:104'].inputs.audio_vae
}
applyUserLoraToGraph(graph, params.loraStack || params.loraName)
return graph
}
@@ -288,6 +298,7 @@ function buildLtxWorkflow(params: GenerateParams, version: VideoWorkflowId) {
if (graph['12']?.inputs) graph['12'].inputs.latent = ['8', 0]
if (graph['14']?.inputs) graph['14'].inputs.latent_image = ['8', 0]
}
applyUserLoraToGraph(graph, params.loraStack || params.loraName)
return graph
}
@@ -366,6 +377,7 @@ const LABEL_OVERRIDES: Record<string, string> = {
'105:104': 'Encoding prompt & latent',
'105:107': 'Computing duration',
'105:111': 'Setting duration',
'user:lora': 'Applying LoRA',
'105:121': 'Applying turbo LoRA',
'105:122': 'Selecting model path',
'105:123': 'Selecting steps',