Files
aigen/utils/generationPresets.ts
T

71 lines
2.0 KiB
TypeScript

import type { LoraStackItem } from '~/utils/loras'
import type { VideoWorkflowId } from '~/utils/videoModels'
export type GenerationPresetKind = 'video' | 'image'
export type VideoPresetSettings = {
workflow?: VideoWorkflowId
turbo?: boolean
cfg?: number
fps?: number
samplerName?: string
scheduler?: string
duration?: number
aspect?: string
sound?: boolean
}
export type ImagePresetSettings = {
steps?: number
cfg?: number
negative?: string
}
export const IMAGE_STEPS_MIN = 1
export const IMAGE_STEPS_MAX = 50
export const IMAGE_CFG_MIN = 0
export const IMAGE_CFG_MAX = 20
export const IMAGE_CFG_STEP = 0.1
export const VIDEO_CFG_MIN = 0
export const VIDEO_CFG_MAX = 20
export const VIDEO_CFG_STEP = 0.1
export function clampImageSteps(raw: unknown, fallback = 20) {
const value = Number(raw)
if (!Number.isFinite(value)) return fallback
return Math.min(IMAGE_STEPS_MAX, Math.max(IMAGE_STEPS_MIN, Math.round(value)))
}
export function clampImageCfg(raw: unknown, fallback = 1) {
const value = Number(raw)
if (!Number.isFinite(value)) return fallback
const snapped = Math.round(value / IMAGE_CFG_STEP) * IMAGE_CFG_STEP
return Math.min(IMAGE_CFG_MAX, Math.max(IMAGE_CFG_MIN, Math.round(snapped * 10) / 10))
}
export function clampVideoCfg(raw: unknown, fallback = 1.5) {
const value = Number(raw)
if (!Number.isFinite(value)) return fallback
const snapped = Math.round(value / VIDEO_CFG_STEP) * VIDEO_CFG_STEP
return Math.min(VIDEO_CFG_MAX, Math.max(VIDEO_CFG_MIN, Math.round(snapped * 10) / 10))
}
export type GenerationPreset = {
id: string
name: string
kind: GenerationPresetKind
createdAt: number
updatedAt: number
loraStack: LoraStackItem[]
settings: VideoPresetSettings | ImagePresetSettings
}
export function parseGenerationPresetKind(raw: unknown): GenerationPresetKind {
return raw === 'image' ? 'image' : 'video'
}
export function normalizePresetName(raw: unknown) {
return String(raw || '').trim().replace(/\s+/g, ' ').slice(0, 80)
}