/* Live catalogue/downloads; runtime and profile drafts remain previews. */
const Studio=(()=>{
const key='athena-deck-studio-v1';
const seed={profiles:[{id:'alltag',name:'qwen-alltag',model:'qwen-iq4',context:76800,slots:1,gpu:'both',split:'85,15',cache:'q8_0',batch:2048,ubatch:128,threads:8,unified:true,flash:true,vision:false},{id:'parallel',name:'qwen-parallel',model:'qwen-iq4',context:160000,slots:2,gpu:'both',split:'85,15',cache:'q8_0',batch:2048,ubatch:128,threads:8,unified:true,flash:true,vision:false},{id:'lang',name:'qwen-langkontext',model:'qwen-iq4',context:262144,slots:1,gpu:'both',split:'80,20',cache:'q8_0',batch:2048,ubatch:128,threads:8,unified:true,flash:true,vision:false}],runtime:{backend:'CUDA',revision:'',architectures:'auto',custom:'',jobs:4,toolkit:'auto',reserve:2048}};
let state=structuredClone(seed);try{const saved=JSON.parse(localStorage.getItem(key));if(saved?.profiles&&Array.isArray(saved.profiles)&&saved.runtime)state=saved;}catch{}
let section='discover',category='',editing=null;
const models=[{id:'qwen-iq4',kind:'chat',name:'Qwen 27B',variant:'IQ4_XS · GGUF',source:'Hugging Face',description:'Sprachmodell · Beispiel für mehrere Profile mit einer Modelldatei.'},{id:'qwen-q4',kind:'chat',name:'Qwen 27B',variant:'Q4_K_M · GGUF',source:'Hugging Face',description:'Alternative Quantisierung · eigener Bibliothekseintrag.'},{id:'image-example',kind:'image',name:'Bildmodell',variant:'Modellpaket · Beispiel',source:'Modellkatalog',description:'Textencoder, Diffusionsmodell und VAE als zusammengehöriges Paket.'},{id:'tts-example',kind:'audio',name:'Sprachausgabe',variant:'TTS · Beispiel',source:'Modellkatalog',description:'Sprachmodell und Stimmen mit passender Audio-Laufzeit.'},{id:'asr-example',kind:'audio',name:'Spracherkennung',variant:'ASR · Beispiel',source:'Modellkatalog',description:'Audio in Text umwandeln · CPU-/GPU-Eignung später prüfen.'},{id:'video-example',kind:'video',name:'Videomodell',variant:'Modellpaket · Beispiel',source:'Modellkatalog',description:'Auflösung, Bildanzahl und Zusatzkomponenten gemeinsam planen.'}];
const labels={chat:'Sprachmodelle / Chat',image:'Bildgenerierung',audio:'Audio',video:'Video'};
const e=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
const count=n=>Number(n).toLocaleString('de-DE');
const selected=(a,b)=>a===b?'selected':'';
const check=v=>v?'checked':'';
function save(){try{localStorage.setItem(key,JSON.stringify(state));return true;}catch{notice('Speichern im Browser nicht möglich. Entwurf bleibt nur für diese Ansicht erhalten.');return false;}}
function notice(message){const node=document.querySelector('#studio-notice');if(node)node.textContent=message;}
const banner=()=>'
GUI-VORSCHAUKatalog und Datei-Downloads sind live. Profile und Laufzeiten bleiben Entwürfe; keine Modellstarts.
';
function header(title,description){return `
ATHENA / MODELLVERWALTUNG
${title}
${description}
${banner()}`;}
function render(page,force=false){
if(!force&&document.querySelector('#studio')?.dataset.page===page)return;
if(category!==page){category=page;section='discover';editing=null;}
const view=document.querySelector('#view');
view.innerHTML=`
${page==='runtime'?runtime():workspace(page)}
`;
bind(page);
}
function workspace(page){
return header(labels[page], 'Modelle entdecken, als Bibliothek organisieren und über Profile bereitstellen.')+`
`;}
function discover(page){return CatalogUI.html(false);}
function library(page){return CatalogUI.html(true);}
function profiles(page){
if(page!=='chat')return `VORBEREITET
${page==='image'?'Auflösung und Generierung':page==='audio'?'Sprache, Stimmen und Verarbeitung':'Auflösung und Videolänge'}
${page==='image'?'':page==='audio'?'':''}
Eigene Worker-Adapter und Eignungsregeln folgen. LLM-Kontextparameter werden hier nicht übernommen.
`;
return `
Ein Modell. Mehrere Möglichkeiten.
API-Namen und Startparameter als lokale Profilentwürfe.
${state.profiles.map(p=>`
PROFILENTWURF
${e(p.name)}
${e(models.find(m=>m.id===p.model)?.variant||'Modell nicht zugeordnet')}
Kontextbudget${count(p.context)}
Slots${e(p.slots)}
ZustandNicht bereitgestellt
`).join('')||'Noch keine Profilentwürfe. Lege dein erstes Profil an.'}
Später wählt der Client den Profilnamen im Feld model. Deck verwaltet den passenden llama-server-Prozess.
`;
}
function running(page){return `○
Keine von Deck verwaltete Modelllaufzeit
${page==='chat'?'llama.cpp ist in dieser Vorschau nicht angebunden. Gespeicherte Profile starten keinen Prozess.':'Für diesen Bereich ist noch kein Worker angebunden.'}
Anfrage zuordnenProfil anhand des API-Namens auswählen.
Arbeit abschließenLaufende Anfragen beenden lassen; neue einreihen.
Prozess wechselnllama-server beenden und mit dem Zielprofil starten.
Bereitschaft prüfenErst danach wartende Anfragen weiterleiten.
Mehrere angebotene Profile sind nicht automatisch mehrere geladene Modelle. Produktive Athena-Prozesse werden in dieser Vorschau nicht gesteuert.
`;}
function detail(id){const m=models.find(m=>m.id===id);document.querySelector('#model-detail').innerHTML=`
${e(m.name)} · Eignungsprüfung
NOCH NICHT BERECHNET
Unterstützt?
Format und Laufzeit-Kompatibilität noch nicht geprüft.
Passt grundsätzlich?
Gewichte, Zusatzkomponenten und Arbeitsspeicherbedarf noch nicht ermittelt.
Kann jetzt starten?
Keine Ressourcenreservierung oder Prozesssteuerung angebunden.
${m.kind==='chat'?'Kontextlänge, KV-Cache, Slots und GPU-Aufteilung beeinflussen den Speicherbedarf. Die beiden GPUs werden nicht pauschal als ein gemeinsamer VRAM-Pool gerechnet.':'Die spätere Einschätzung berücksichtigt die zur Aufgabe passenden Parameter und den jeweiligen Worker.'} Es gibt in dieser Vorschau keine erfundenen Speicherwerte.
`;document.querySelector('#model-detail').scrollIntoView({behavior:'smooth',block:'nearest'});}
function field(label,name,value,type='number',attrs=''){return ``;}
function editor(id,model){editing=id||null;const p=id?state.profiles.find(p=>p.id===id):{...seed.profiles[0],name:'qwen-neues-profil',model:model||'qwen-iq4'};if(!p)return;
document.querySelector('#profile-editor').innerHTML=`
${id?'Profil bearbeiten':'Neues Profil'}
NUR ENTWURF
`;
document.querySelector('#profile-form').onsubmit=event=>{event.preventDefault();const data=new FormData(event.target),value=Object.fromEntries(data);for(const n of ['context','slots','batch','ubatch','threads'])value[n]=Number(value[n]);for(const n of ['unified','flash','vision'])value[n]=data.has(n);const out=document.querySelector('#profile-error');if(state.profiles.some(q=>q.id!==editing&&q.name===value.name)){out.textContent='Dieser API-Profilname ist bereits vergeben.';return;}if(value.ubatch>value.batch){out.textContent='Microbatch darf nicht größer als Batch sein.';return;}if(value.gpu==='both'&&!value.split.split(',').some(v=>Number(v)>0)){out.textContent='Mindestens eine GPU-Gewichtung muss größer als null sein.';return;}value.id=editing||crypto.randomUUID();const idx=state.profiles.findIndex(q=>q.id===editing);if(idx<0)state.profiles.push(value);else state.profiles[idx]=value;const stored=save();render(category,true);notice(stored?'Profilentwurf in diesem Browser gespeichert. Kein Modell gestartet.':'Entwurf nur im Speicher gehalten; Browser-Speicher nicht verfügbar.');};
document.querySelector('#cancel-edit').onclick=()=>document.querySelector('#profile-editor').replaceChildren();
if(id)document.querySelector('#delete-profile').onclick=()=>{state.profiles=state.profiles.filter(q=>q.id!==id);save();render(category,true);notice('Lokalen Profilentwurf entfernt. Modelldateien wurden nicht verändert.');};
document.querySelector('#profile-editor').scrollIntoView({behavior:'smooth',block:'start'});
}
function runtime(){const r=state.runtime;return header('llama.cpp-Laufzeit','Installation, GPU-Unterstützung und Versionen an einem Ort vorbereiten.')+`
INSTALLIERTE VERSION
Nicht angebunden
Kein Build erkannt oder ausgeführt.
UPDATE-STATUS
Noch nicht geprüft
Keine Live-Abfrage von Releases.
ZIELSYSTEM
Athena
Geplant: RTX 5080 + RTX 3060
Installation & Build
LOKALER ENTWURF
Updates & Änderungen
Vorgesehen: installierte Version mit verfügbaren Releases vergleichen, Fixes ansehen und einen neuen Build getrennt vorbereiten.
AKTUELL
Nicht ermittelt
→
VERFÜGBAR
Nicht abgefragt
Release-Notes & Fixes
Hier erscheinen später die tatsächlichen Änderungen mit Quelle und Veröffentlichungsdatum. Keine Beispieldaten werden als neue Version oder behobener Fehler ausgegeben.