Spaces:
Running
Running
File size: 3,284 Bytes
de78f87 750ca83 de78f87 353687b 750ca83 260bf19 353687b 750ca83 de78f87 750ca83 de78f87 353687b de78f87 353687b 750ca83 de78f87 750ca83 de78f87 353687b 750ca83 de78f87 750ca83 de78f87 353687b | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 | // Recommended settings presets. Each preset can set the text engine/model, voice
// provider, and portrait model together. Manual changes move the picker to Custom.
import { setEngine, getEngineId, setModel, currentModelId, listModels, onModelChange } from '/web/runtime.js'
import { setTtsEngine, getTtsEngineId, onTtsEngineChange } from '/web/tts.js'
import { setImageEngine, getImageEngineId, onImageEngineChange } from '/web/imagen.js'
import { setCodingModel, getCodingModelId, onCodingModelChange } from '/web/codingModel.js'
export const PRESETS = [
{ id: 'build-small', label: 'BUILD SMALL', engine: 'server', model: 'tiny-aya-global-zerogpu', family: 'tiny-aya', voice: 'voxcpm', image: 'klein-zerogpu', coding: 'mellum2-zerogpu', sub: 'Tiny Aya - VoxCPM2 - FLUX.2 klein - Mellum2 (Nemotron NIM fallback)' },
{ id: 'high', label: 'High', engine: 'webllm', model: 'qwen3-0.6b', family: 'qwen3', voice: 'kokoro', image: '', coding: 'mellum2-zerogpu', sub: 'Qwen3 - Kokoro 82M' },
{ id: 'medium', label: 'Medium', engine: 'transformers', model: 'qwen2.5-0.5b', family: 'qwen2.5', voice: 'kitten', image: '', coding: 'mellum2-zerogpu', sub: 'Qwen2.5 - Kitten TTS' },
{ id: 'low', label: 'Low', engine: 'transformers', model: 'qwen2.5-0.5b', family: 'qwen2.5', voice: 'webspeech', image: '', coding: 'mellum2-zerogpu', sub: 'Qwen2.5 - Web Speech' },
]
const KEY = 'tinyarmy.qualityPreset'
const VALID = new Set([...PRESETS.map((p) => p.id), 'custom'])
const byId = (id) => PRESETS.find((p) => p.id === id)
function resolveModel(p) {
const ms = listModels()
const m = ms.find((x) => x.id === p.model) || ms.find((x) => x.id.startsWith(p.family))
return m ? m.id : ''
}
export function detectPreset() {
const eid = getEngineId()
const mid = currentModelId()
const voice = getTtsEngineId()
const image = getImageEngineId()
const coding = getCodingModelId()
const p = PRESETS.find((x) =>
(!x.engine || eid === x.engine) &&
(mid === x.model || mid.startsWith(x.family)) &&
voice === x.voice &&
(!x.image || image === x.image) &&
(!x.coding || coding === x.coding))
return p ? p.id : 'custom'
}
let _applying = false
let _current = (() => {
let saved = ''
try { saved = localStorage.getItem(KEY) || '' } catch { /* ignore */ }
if (!VALID.has(saved)) return detectPreset()
if (saved === 'custom') return 'custom'
return detectPreset() === saved ? saved : detectPreset()
})()
export const getActivePreset = () => _current
function commit(id) {
_current = id
try { localStorage.setItem(KEY, id) } catch { /* ignore */ }
for (const fn of _listeners) { try { fn(id) } catch { /* ignore */ } }
}
export function applyPreset(id) {
const p = byId(id)
if (!p) return
_applying = true
if (p.engine) setEngine(p.engine)
const mid = resolveModel(p)
if (mid) setModel(mid)
setTtsEngine(p.voice)
if (p.image) setImageEngine(p.image)
if (p.coding) setCodingModel(p.coding)
_applying = false
commit(id)
}
const _listeners = new Set()
export function onPresetChange(fn) { _listeners.add(fn); return () => _listeners.delete(fn) }
const _onManual = () => { if (!_applying) commit('custom') }
onModelChange(_onManual)
onTtsEngineChange(_onManual)
onImageEngineChange(_onManual)
onCodingModelChange(_onManual)
|