/* Server-backed model management. Legacy browser drafts remain untouched. */ const Studio=(()=>{ let section='discover',category=''; const labels={chat:'Chat & Sprachmodelle',image:'Bildgenerierung',audio:'Sprachausgabe (TTS)',stt:'Spracherkennung (STT)',music:'Musikgenerierung',voice:'Stimmwerkzeuge',video:'Videogenerierung'}; const audioDescriptions={audio:'Geschriebenen Text vorlesen lassen. Die Suche zeigt Text-to-Speech-Modelle.',stt:'Gesprochene Sprache in Text umwandeln. Die Suche zeigt Spracherkennungsmodelle.',music:'Musik und Klänge aus Text erzeugen. Die Hub-Kategorie Text-to-Audio umfasst neben Musik auch Geräusche und andere Audioerzeugung.',voice:'Vorhandenes Audio bearbeiten: Stimmumwandlung, Audiotrennung und weitere Audio-to-Audio-Modelle. Eigenständige Studio-Oberflächen gehören unter Weitere Dienste.'}; function render(page,force=false,modelId=null){ if(page==='video'){VideoUI.runtime();return;} if(!force&&document.querySelector('#studio')?.dataset.page===page)return; if(category!==page){category=page;section='discover';} if(modelId)section='profiles'; const body=page==='stt-runtime'?STTUI.html(true):page==='tts-runtime'?TTSUI.html(true):['docker-runtime','services'].includes(page)?DockerUI.html(page==='services'):page==='runtimes'?runtimeOverview():page==='image-runtime'?imageRuntime():page==='runtime'?RuntimeUI.html():`
ATHENA / MODELLVERWALTUNG

${labels[page]}

${audioDescriptions[page]||'Modelle entdecken, herunterladen und mit gespeicherten Profilen konfigurieren.'}

${audioDescriptions[page]&&!['audio','stt','music'].includes(page)?'

Entdecken und Downloads sind verfügbar. Für diese Audio-Bereiche ist noch keine ausführbare Laufzeit in Deck angebunden. Gespeicherte Profile sind vorbereitend.

':''}
${[['discover','Entdecken'],['library','Bibliothek'],['downloads','Downloads'],['profiles','Profile'],...(['audio','stt'].includes(page)?[['setup','Einrichten']]:[]),...(['image','chat','audio','stt','music'].includes(page)?[['test','Testen'],...(page==='chat'?[['auto','Auto-Test']]:[])]:[])].map(([id,label])=>``).join('')}
${section==='setup'?(page==='stt'?STTUI.html(true):TTSUI.html(true)):['test','running'].includes(section)&&page==='music'?MusicUI.html():['test','running'].includes(section)&&page==='stt'?STTUI.html():['test','running'].includes(section)&&page==='audio'?TTSUI.html():section==='auto'?AutoTestUI.html():section==='test'?(page==='chat'?ChatTestUI.html():ImageTestUI.html()):section==='running'&&page==='image'?ImageTestUI.html(true):section==='profiles'?ProfilesUI.html():section==='running'&&page==='chat'?EndpointUI.runningHTML():section==='running'?'

Keine von Deck gestarteten Modelle

Profile werden auf Athena gespeichert. Für diesen Bereich ist noch kein Modellworker angebunden. Fehlende Komponenten stehen beim jeweiligen Profil.

llama.cpp-Builds verwalten →
':CatalogUI.html(section==='library',section==='downloads')}
`; document.querySelector('#view').innerHTML=`
${body}
`; if(['docker-runtime','services'].includes(page)){DockerUI.bind(page==='services');return;} if(page==='stt-runtime'){STTUI.bind(true);return;} if(page==='tts-runtime'){TTSUI.bind(true);return;} if(page==='runtime'){RuntimeUI.bind();return;} if(page==='image-runtime'){ImageTestUI.bind(true);ImageTestUI.bindInstaller();return;} if(page==='runtimes'){bindRuntimeOverview();return;} else if(section==='setup'){if(page==='stt')STTUI.bind(true);else TTSUI.bind(true);} else if(['test','running'].includes(section)&&page==='music')MusicUI.bind(); else if(['test','running'].includes(section)&&page==='stt')STTUI.bind(); else if(['test','running'].includes(section)&&page==='audio')TTSUI.bind(); else if(section==='auto')AutoTestUI.bind(); else if(section==='test'&&page==='chat')ChatTestUI.bind(); else if(section==='test'||(section==='running'&&page==='image'))ImageTestUI.bind(section==='running'); else if(section==='running'&&page==='chat')EndpointUI.bindRunning(); else if(section==='profiles')ProfilesUI.bind(page,modelId); else if(section!=='running')CatalogUI.bind(page,section==='library',section==='downloads'); document.querySelectorAll('[data-section]').forEach(b=>b.onclick=()=>{section=b.dataset.section;render(page,true);}); } const runtimeRows=[ ['llama.cpp','Chat & Sprachmodelle','runtime','/api/v1/runtime','Offizielle Releases prüfen, Änderungen lesen, CPU-/CUDA-Build erstellen und geprüften Standard auswählen.'], ['ComfyUI + GGUF','Bilder & Video','image-runtime','/api/v1/image-runtime','Einmal installieren und für unterstützte Bild- und Videomodelle wiederverwenden. Gepinnte Versionen werden mit Deck gepflegt.'], ['Qwen3-TTS','Sprachausgabe','tts-runtime','/api/v1/tts','CUDA-Laufzeit für unterstützte Qwen3-TTS-Modelle. Die Einrichtung lädt auch das vorgesehene Stimmenmodell.'], ['Qwen3-ASR','Spracherkennung','stt-runtime','/api/v1/stt','Verwendet llama.cpp. Modell und Audio-Projektor werden in der Einrichtung zugeordnet.'], ['audio.cpp','Musik & Audio','audio-cpp-runtime','/api/v1/audio-cpp-runtime','CUDA-Build einmal erstellen. YuE2 ist angebunden; andere Modellfamilien brauchen eine geprüfte Worker-Anbindung.'], ['LTX Original','Video','ltx-original-runtime','/api/v1/ltx-original-runtime','Originales LTX-Backend für LTX DeskWEB. Modelle und Zusatzdateien bleiben in der Bibliothek.'], ['Docker Engine','Weitere Dienste','docker-runtime','/api/v1/docker','Optionale Container-Umgebung. Erstinstallation über den Systemhelfer; vorhandenes Docker wird nicht automatisch aktualisiert.'], ['Audio Separator','Audiotrennung',null,null,'Für BS-RoFormer, MelBand RoFormer und weitere Trennmodelle vorgesehen. Installer und Deck-Worker sind noch nicht angebunden; ein Download der Gewichte genügt hier noch nicht.'] ]; const runtimeEscape=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); function runtimeOverview(){return `
EINSTELLUNGEN

Laufzeiten

Einmal einrichten, für passende Modelle wiederverwenden. Dieser Katalog zeigt die in Deck unterstützten und vorgesehenen Laufzeiten. Zusatzdateien findest du beim Modell unter Einrichtung & Komponenten.

Installationsstatus wird geprüft …

${runtimeRows.map(([name,category,route,path,description],i)=>`
${name}${category}${path?'Wird geprüft …':'Noch nicht angebunden'}

${description}

${route?`${i===0?'Installation, Build & Updates öffnen': 'Einrichtung öffnen'} →`:''}${i===0?'

':''}
`).join('')}
`;} function bindRuntimeOverview(){ const root=document.querySelector('#studio[data-page="runtimes"]');if(!root)return; const esc=runtimeEscape,message=root.querySelector('#runtime-catalog-message'); root.querySelector('#runtime-search').oninput=event=>{const query=event.target.value.trim().toLocaleLowerCase();root.querySelectorAll('[data-runtime-row]').forEach(row=>{const data=runtimeRows[Number(row.dataset.runtimeRow)];row.hidden=!data.slice(0,2).join(' ').toLocaleLowerCase().includes(query);});}; async function read(path){const response=await fetch(path);const data=await response.json();if(!response.ok)throw Error(data.error||'Status nicht erreichbar');return data;} async function refresh(){const results=await Promise.allSettled(runtimeRows.map(async(row,i)=>{if(!row[3])return;const response=await read(row[3]),data=i===2?response.runtime:response;if(!root.isConnected)return;const el=root.querySelector(`[data-runtime-row="${i}"]`),active=i===0?data.builds?.find(b=>b.id===data.active):null; const installed=i===0?Boolean(active):data.installed; el.querySelector('[data-runtime-status]').textContent=data.job?.state==='running'?'Einrichtung läuft':installed===true?'Installiert':installed===false?'Einrichtung erforderlich':'Nicht ermittelbar'; el.querySelector('[data-runtime-version]').textContent=[active?`${active.revision} · ${active.backend}`:data.version||data.comfy_revision||data.desktop_revision||data.revision||'',data.job?`${data.job.state} · ${data.job.phase||''}`:'',i===0?'Neue Versionen werden nur auf Knopfdruck geprüft.':''].filter(Boolean).join(' · '); }));if(!root.isConnected)return;results.forEach((result,i)=>{if(result.status==='rejected')root.querySelector(`[data-runtime-row="${i}"] [data-runtime-status]`).textContent='Status nicht erreichbar';});message.textContent=results.some(r=>r.status==='rejected')?'Einige Statusabfragen sind fehlgeschlagen. Einrichtung öffnen oder später erneut prüfen.':'Installationsstatus geprüft. Eine installierte Laufzeit benötigt weiterhin ein kompatibles Modell und vollständige Komponenten.';setTimeout(()=>{if(root.isConnected)refresh();},10000);} root.querySelector('#catalog-llama-updates').onclick=async event=>{const button=event.currentTarget;button.disabled=true;message.textContent='Offizielle llama.cpp-Releases werden geprüft …';try{const data=await read('/api/v1/runtime/releases');if(!root.isConnected)return;root.querySelector('#catalog-llama-releases').innerHTML=data.releases.map(release=>`

${esc(release.tag)} · ${release.prerelease?'Vorabversion':'Reguläres Release'}

${esc(release.published)}

Änderungen anzeigen
${esc(release.notes)}
`).join('');root.querySelectorAll('[data-catalog-release]').forEach(b=>b.onclick=()=>{RuntimeUI.prepareBuild(b.dataset.catalogRelease);location.hash='runtime';});message.textContent='Releases geprüft. Build vorbereiten übernimmt die Version; der Build startet erst auf deinen Klick.';}catch(error){if(root.isConnected)message.textContent=error.message;}finally{button.disabled=false;}}; refresh(); } function imageRuntime(){return `
EINSTELLUNGEN / LAUFZEITEN

Bildgenerierung

ComfyUI + ComfyUI-GGUF

Eigene Bildlaufzeit für Qwen-Image-2.1 GGUF und das unterstützte FLUX.2-Klein-9B-Modell. Die Umgebung kann über den Deck-Installer mitgeliefert oder hier separat installiert werden. Modelle laden erst bei einem Testauftrag.

Textencoder läuft auf der RTX 3060, Diffusionsmodell und VAE auf der RTX 5080. Bei großen FLUX-Gewichten wird zusätzlich System-RAM genutzt. Beide GPUs müssen frei sein. Pro Test wird ein eigener Prozess gestartet und anschließend beendet.

Installationsstatus wird geprüft …

Bildgenerierung → Testen öffnen
${ImageTestUI.html(true)}`;} function openProfile(page,modelId){render(page,true,modelId);} return {render,openProfile}; })();