// frontend\src\components\ui\finishedSelectionStore.ts 'use client' import type { RecordJob, GalleryModelFlags, } from '../../types' function cleanString(value: unknown): string { return String(value ?? '').trim() } function parseMetaObject(metaRaw: unknown): Record | null { if (!metaRaw) return null if (typeof metaRaw === 'string') { try { const parsed = JSON.parse(metaRaw) return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? (parsed as Record) : null } catch { return null } } return typeof metaRaw === 'object' && !Array.isArray(metaRaw) ? (metaRaw as Record) : null } export function parseFinishedTags(value?: unknown): string[] { if (Array.isArray(value)) { const seen = new Set() const out: string[] = [] for (const item of value) { const s = cleanString(item) if (!s) continue const key = s.toLowerCase() if (seen.has(key)) continue seen.add(key) out.push(s) } return out } const raw = cleanString(value) if (!raw) return [] const parts = raw .split(/[\n,;|]+/g) .map((p) => p.trim()) .filter(Boolean) const seen = new Set() const out: string[] = [] for (const part of parts) { const key = part.toLowerCase() if (seen.has(key)) continue seen.add(key) out.push(part) } return out } function candidateModelNames( job: RecordJob, modelNameFromOutput: (output?: string) => string ): string[] { const anyJob = job as any const meta = parseMetaObject(anyJob?.meta) const rawCandidates = [ modelNameFromOutput(job.output), anyJob?.model, anyJob?.modelName, anyJob?.performer, anyJob?.creator, meta?.model?.name, meta?.modelName, meta?.performer, meta?.creator, meta?.source?.modelName, ] const seen = new Set() const out: string[] = [] for (const value of rawCandidates) { const s = cleanString(value) if (!s) continue const key = s.toLowerCase() if (seen.has(key)) continue seen.add(key) out.push(s) } return out } export function resolveFinishedModelFlags( job: RecordJob, modelsByKey: Record, modelNameFromOutput: (output?: string) => string, lower: (s: string) => string ): { model: string modelKey: string flags?: GalleryModelFlags } { const candidates = candidateModelNames(job, modelNameFromOutput) for (const candidate of candidates) { const key = lower(candidate) const flags = modelsByKey[key] if (flags) { return { model: candidate, modelKey: key, flags, } } } const fallbackModel = candidates[0] ?? modelNameFromOutput(job.output) ?? '—' const fallbackKey = lower(cleanString(fallbackModel)) return { model: fallbackModel, modelKey: fallbackKey, flags: modelsByKey[fallbackKey], } }