tiny-army / web /imagen.js
polats's picture
Add Build Small recommended preset
de78f87
// Image facade — mirrors tts.js. Picks the active portrait engine (local Z-Image on your
// GPU, or cloud FLUX; in-browser SD-Turbo / Janus get added here later) and exposes one
// generatePortrait(). The persona panel + the Settings image bar import only from here.
import { engineLocal as zimagelocal, engineKleinZeroGpu as klein, engineCloud as flux, engineCloudDev as fluxdev } from '/web/imagenServer.js'
import { engine as bonsai } from '/web/imagenBonsai.js'
const ENGINES = [zimagelocal, klein, bonsai, flux, fluxdev]
// Default: local Z-Image on localhost (your GPU), Klein ZeroGPU in prod. Persisted across
// refreshes; a saved choice wins if it's still available.
const KEY = 'tinyarmy.imageEngine'
let activeId = (() => {
let saved = ''
try { saved = localStorage.getItem(KEY) || '' } catch { /* ignore */ }
const e = ENGINES.find((x) => x.id === saved)
return e && e.available() ? saved : 'klein-zerogpu'
})()
const eng = () => ENGINES.find((e) => e.id === activeId) || ENGINES.find((e) => e.available()) || ENGINES[0]
export const listImageEngines = () =>
ENGINES.map((e) => ({ id: e.id, label: e.label, available: e.available(), note: e.note || '' }))
export const getImageEngineId = () => activeId
const _listeners = new Set()
export function onImageEngineChange(fn) { _listeners.add(fn); return () => _listeners.delete(fn) }
export function setImageEngine(id) {
if (!ENGINES.some((e) => e.id === id) || id === activeId) return
activeId = id
try { localStorage.setItem(KEY, id) } catch { /* ignore */ }
for (const fn of _listeners) { try { fn(id) } catch { /* ignore */ } }
}
export const imageNeedsDownload = () => !!eng().needsDownload
export const imageBackendLabel = () => eng().backendLabel()
export const imageNetworked = () => !!eng().networked
export async function ensureImage(onProgress) { return eng().ensure(onProgress) }
// Generate a portrait → PNG Blob. `prompt` is the appearance description; `seed` keeps it
// reproducible where the engine supports it.
export async function generatePortrait(prompt, { seed } = {}) {
return eng().generate(prompt, { seed })
}