Select the single active video profile through endpoint publication
This commit is contained in:
+3
-4
@@ -2,14 +2,13 @@ window.VideoUI=(()=>{
|
||||
const e=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c]));
|
||||
async function api(path,data){const r=await fetch('/api/v1/'+path,data!==undefined?{method:'POST',headers:{'Content-Type':'application/json','X-Athena-Deck':'1'},body:JSON.stringify(data)}:{}),s=await r.json();if(!r.ok)throw Error(s.error||'Anfrage fehlgeschlagen');return s;}
|
||||
function mode(root,s,profiles){
|
||||
if(root.querySelector('#active-video')===document.activeElement||root.dataset.busy==='1')return;
|
||||
const html=`<section class="card"><h2>GPU-Modus</h2><div class="card-actions"><button data-mode="llm" ${s.mode==='llm'&&s.state!=='failed'||s.state==='switching'?'disabled':''}>LLM</button><button data-mode="video" ${s.mode==='video'&&s.state==='ready'||s.state==='switching'?'disabled':''}>Video</button></div><p>Modus: <strong>${e(s.mode.toUpperCase())}</strong> · ${e(s.state)} · ${e(s.error||'')}</p><label>Aktives Videoprofil<select id="active-video" ${s.mode!=='llm'||s.state==='switching'?'disabled':''}><option value="">Bitte auswählen</option>${profiles.filter(p=>p.kind==='video').map(p=>`<option value="${e(p.id)}" ${s.profile_id===p.id?'selected':''}>${e(p.name)}${p.runnable?'':' · Voraussetzungen fehlen'}</option>`).join('')}</select></label><p>${e(s.memory_policy)}</p><p>Video beendet laufende Deck-GPU-Aufträge und sperrt Chat, Bild und TTS (HTTP 503). CPU-STT bleibt verfügbar. Fremde Dienste werden nicht beendet.</p><p><a class="link" href="#video-runtime">Video-Laufzeit und Testauftrag →</a></p><p class="video-message" role="status"></p></section>`;
|
||||
if(root.dataset.busy==='1')return;
|
||||
const html=`<section class="card"><h2>GPU-Modus</h2><div class="card-actions"><button data-mode="llm" ${s.mode==='llm'&&s.state!=='failed'||s.state==='switching'?'disabled':''}>LLM</button><button data-mode="video" ${s.mode==='video'&&s.state==='ready'||s.state==='switching'?'disabled':''}>Video</button></div><p>Modus: <strong>${e(s.mode.toUpperCase())}</strong> · ${e(s.state)} · ${e(s.error||'')}</p><p>Freigegebenes Videoprofil: <strong>${e(profiles.find(p=>p.id===s.profile_id)?.name||'Keines')}</strong> · <a class="link" href="#video">Unter Video → Profile freigeben</a></p><p>${e(s.memory_policy)}</p><p>Video beendet laufende Deck-GPU-Aufträge und sperrt Chat, Bild und TTS (HTTP 503). CPU-STT bleibt verfügbar. Fremde Dienste werden nicht beendet.</p><p><a class="link" href="#video-runtime">Video-Laufzeit und Testauftrag →</a></p><p class="video-message" role="status"></p></section>`;
|
||||
if(root._html===html)return;root._html=html;root.innerHTML=html;
|
||||
async function act(path,data){root.dataset.busy='1';try{await api(path,data);root._html='';root.querySelector('.video-message').textContent='Übernommen; Status wird aktualisiert.';}catch(x){root.querySelector('.video-message').textContent=x.message;}finally{root.dataset.busy='0';}}
|
||||
root.querySelectorAll('[data-mode]').forEach(b=>b.onclick=()=>act('video/mode',{mode:b.dataset.mode}));
|
||||
root.querySelector('#active-video').onchange=ev=>{if(ev.target.value)act('video/profile',{id:ev.target.value});};
|
||||
}
|
||||
function html(testing=false){return `<section id="video-runtime-page">${testing?'<h2>Video testen</h2><p>Profil auswählen, Video-Modus aktivieren und einen kurzen Test starten.</p><div id="video-test-mode"></div>':'<h1>LTX-Video-Laufzeit</h1>'}<div ${testing?'hidden':''}><p>Eigene Python-Umgebung, gepinnte LTX-Pipelines, CUDA 12.8. Installation verändert keine Host-Treiber. Erster Ausführungsweg: Text → Video mit dem Distilled-BF16-Rezept und Disk-Streaming auf der RTX 5080.</p><p id="video-status"></p><button id="video-install">Laufzeit installieren</button><button id="video-cancel">Installation abbrechen</button><p><a href="#home">Modus und aktives Profil in der Übersicht auswählen →</a></p></div><p id="video-message" role="status"></p><section class="card"><h2>Video-Test</h2><p>Zuerst den Video-Modus aktivieren. Werte überschreiben die Profilstandards für diesen Auftrag. Distilled nutzt seine feste Schrittfolge. Noch kein Bild-/Audio-Upload.</p><form id="video-test"><label>Prompt<textarea name="prompt" required maxlength="8000"></textarea></label>${[['width','Breite',256],['height','Höhe',256],['frames','Bilder (8n+1)',9],['fps','FPS',24],['seed','Seed',42]].map(([n,l,v])=>`<label>${l}<input type="number" name="${n}" value="${v}" required></label>`).join('')}<button>Video erzeugen</button></form><p id="video-job"></p><div id="video-result"></div><p>API: POST /v1/videos · GET /v1/videos/{id} · GET /v1/videos/{id}/content. Gleicher Port und API-Token wie Chat; eigenständige Deck-Video-API.</p></section></section>`;}
|
||||
function html(testing=false){return `<section id="video-runtime-page">${testing?'<h2>Video testen</h2><p>Unter Video → Profile ein Profil freigeben, dann hier den Video-Modus aktivieren und einen kurzen Test starten.</p><div id="video-test-mode"></div>':'<h1>LTX-Video-Laufzeit</h1>'}<div ${testing?'hidden':''}><p>Eigene Python-Umgebung, gepinnte LTX-Pipelines, CUDA 12.8. Installation verändert keine Host-Treiber. Erster Ausführungsweg: Text → Video mit dem Distilled-BF16-Rezept und Disk-Streaming auf der RTX 5080.</p><p id="video-status"></p><button id="video-install">Laufzeit installieren</button><button id="video-cancel">Installation abbrechen</button><p><a href="#home">Modus und aktives Profil in der Übersicht auswählen →</a></p></div><p id="video-message" role="status"></p><section class="card"><h2>Video-Test</h2><p>Zuerst den Video-Modus aktivieren. Werte überschreiben die Profilstandards für diesen Auftrag. Distilled nutzt seine feste Schrittfolge. Noch kein Bild-/Audio-Upload.</p><form id="video-test"><label>Prompt<textarea name="prompt" required maxlength="8000"></textarea></label>${[['width','Breite',256],['height','Höhe',256],['frames','Bilder (8n+1)',9],['fps','FPS',24],['seed','Seed',42]].map(([n,l,v])=>`<label>${l}<input type="number" name="${n}" value="${v}" required></label>`).join('')}<button>Video erzeugen</button></form><p id="video-job"></p><div id="video-result"></div><p>API: POST /v1/videos · GET /v1/videos/{id} · GET /v1/videos/{id}/content. Gleicher Port und API-Token wie Chat; eigenständige Deck-Video-API.</p></section></section>`;}
|
||||
async function runtime(){
|
||||
const view=document.querySelector('#view');if(view.querySelector('#video-runtime-page'))return;
|
||||
view.innerHTML=html();bind(view.firstElementChild);
|
||||
|
||||
Reference in New Issue
Block a user