143 lines
2.9 KiB
TypeScript
143 lines
2.9 KiB
TypeScript
// 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<string, any> | 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<string, any>)
|
|
: null
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|
|
|
|
return typeof metaRaw === 'object' && !Array.isArray(metaRaw)
|
|
? (metaRaw as Record<string, any>)
|
|
: null
|
|
}
|
|
|
|
export function parseFinishedTags(value?: unknown): string[] {
|
|
if (Array.isArray(value)) {
|
|
const seen = new Set<string>()
|
|
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<string>()
|
|
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<string>()
|
|
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<string, GalleryModelFlags>,
|
|
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],
|
|
}
|
|
} |