Align separator navigation and server checks with four packages

This commit is contained in:
Mikei386 committed 2026-10-01 16:22:07 +02:00
1 parent 433e6709cf
commit 088f5f6f91
2 files changed
+5 -4

No files matched your search

+3 -3
View File
@@ -2,13 +2,13 @@
const Studio=(()=>{ const Studio=(()=>{
let section='discover',category=''; let section='discover',category='';
const labels={chat:'Chat & Sprachmodelle',image:'Bildgenerierung',audio:'Sprachausgabe (TTS)',stt:'Spracherkennung (STT)',music:'Musikgenerierung',voice:'Stimmwerkzeuge',video:'Videogenerierung'}; 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.'}; 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, Audio-Trennung und weitere Audio-to-Audio-Modelle. Eigenständige Studio-Oberflächen gehören unter Weitere Dienste.'};
function render(page,force=false,modelId=null){ function render(page,force=false,modelId=null){
if(page==='video'){VideoUI.runtime();return;} if(page==='video'){VideoUI.runtime();return;}
if(!force&&document.querySelector('#studio')?.dataset.page===page)return; if(!force&&document.querySelector('#studio')?.dataset.page===page)return;
if(category!==page){category=page;section='discover';} if(category!==page){category=page;section='discover';}
if(modelId)section='profiles'; 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():`<div class="kicker">ATHENA / MODELLVERWALTUNG</div><h1>${labels[page]}</h1><p>${audioDescriptions[page]||'Modelle entdecken, herunterladen und mit gespeicherten Profilen konfigurieren.'}</p>${page==='voice'?'<p><a class="link" href="#separator-runtime">Audio Separator einrichten →</a> · <a class="link" href="#separator-test">Audio trennen →</a></p><p class="note">Audiotrennung nutzt die unterstützten Pakete im Audio-Separator-Bereich. Andere Hub-Dateien und Voice-Profile benötigen weiterhin eine geprüfte Anbindung.</p>':''}${audioDescriptions[page]&&!['audio','stt','music','voice'].includes(page)?'<p class="note">Entdecken und Downloads sind verfügbar. Für diese Audio-Bereiche ist noch keine ausführbare Laufzeit in Deck angebunden. Gespeicherte Profile sind vorbereitend.</p>':''}<div class="studio-tabs" role="tablist" aria-label="Modellverwaltung">${[['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])=>`<button role="tab" aria-selected="${section===id}" class="${section===id?'chosen':'secondary'}" data-section="${id}">${label}</button>`).join('')}</div><div role="tabpanel">${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'?'<section class="card"><h2>Keine von Deck gestarteten Modelle</h2><p>Profile werden auf Athena gespeichert. Für diesen Bereich ist noch kein Modellworker angebunden. Fehlende Komponenten stehen beim jeweiligen Profil.</p><a class="link" href="#runtime">llama.cpp-Builds verwalten →</a></section>':CatalogUI.html(section==='library',section==='downloads')}</div>`; 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():`<div class="kicker">ATHENA / MODELLVERWALTUNG</div><h1>${labels[page]}</h1><p>${audioDescriptions[page]||'Modelle entdecken, herunterladen und mit gespeicherten Profilen konfigurieren.'}</p>${page==='voice'?'<p><a class="link" href="#separator-runtime">Audio Separator einrichten →</a> · <a class="link" href="#separation">Audio-Trennung →</a></p><p class="note">Audio-Trennung nutzt die unterstützten Pakete im Audio-Separator-Bereich. Andere Hub-Dateien und Voice-Profile benötigen weiterhin eine geprüfte Anbindung.</p>':''}${audioDescriptions[page]&&!['audio','stt','music','voice'].includes(page)?'<p class="note">Entdecken und Downloads sind verfügbar. Für diese Audio-Bereiche ist noch keine ausführbare Laufzeit in Deck angebunden. Gespeicherte Profile sind vorbereitend.</p>':''}<div class="studio-tabs" role="tablist" aria-label="Modellverwaltung">${[['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])=>`<button role="tab" aria-selected="${section===id}" class="${section===id?'chosen':'secondary'}" data-section="${id}">${label}</button>`).join('')}</div><div role="tabpanel">${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'?'<section class="card"><h2>Keine von Deck gestarteten Modelle</h2><p>Profile werden auf Athena gespeichert. Für diesen Bereich ist noch kein Modellworker angebunden. Fehlende Komponenten stehen beim jeweiligen Profil.</p><a class="link" href="#runtime">llama.cpp-Builds verwalten →</a></section>':CatalogUI.html(section==='library',section==='downloads')}</div>`;
document.querySelector('#view').innerHTML=`<div id="studio" data-page="${page}">${body}</div>`; document.querySelector('#view').innerHTML=`<div id="studio" data-page="${page}">${body}</div>`;
if(['docker-runtime','services'].includes(page)){DockerUI.bind(page==='services');return;} if(['docker-runtime','services'].includes(page)){DockerUI.bind(page==='services');return;}
if(page==='stt-runtime'){STTUI.bind(true);return;} if(page==='stt-runtime'){STTUI.bind(true);return;}
@@ -36,7 +36,7 @@ const Studio=(()=>{
['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.'], ['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.'], ['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.'], ['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','separator-runtime','/api/v1/separator-runtime','Native CUDA-Laufzeit für unterstützte BS- und MelBand-RoFormer-Pakete. Modelle samt YAML-Konfiguration herunterladen und einen kurzen WAV-Trenntest starten.'] ['Audio Separator','Audio-Trennung','separator-runtime','/api/v1/separator-runtime','Native CUDA-Laufzeit für BS-Roformer, MelBand und Demucs FT/6s. Vollständige Modellpakete mit überprüften Originalquellen und Prüfsummen.']
]; ];
const runtimeEscape=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c])); const runtimeEscape=v=>String(v??'').replace(/[&<>"']/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c]));
function runtimeOverview(){return `<div class="kicker">EINSTELLUNGEN</div><h1>Laufzeiten</h1><p>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.</p><label>Laufzeit suchen<input id="runtime-search" type="search" placeholder="Name oder Bereich"></label><p id="runtime-catalog-message" role="status">Installationsstatus wird geprüft …</p><div class="detail-list">${runtimeRows.map(([name,category,route,path,description],i)=>`<details class="detail-row" data-runtime-row="${i}"><summary class="detail-summary"><strong>${name}</strong><span>${category}</span><span data-runtime-status>${path?'Wird geprüft …':'Noch nicht angebunden'}</span></summary><div class="detail-body"><p>${description}</p><p data-runtime-version></p>${route?`<a class="link" href="#${route}">${i===0?'Installation, Build & Updates öffnen': 'Einrichtung öffnen'} →</a>`:''}${i===0?'<p><button id="catalog-llama-updates">llama.cpp-Updates prüfen</button></p><div id="catalog-llama-releases"></div>':''}</div></details>`).join('')}</div>`;} function runtimeOverview(){return `<div class="kicker">EINSTELLUNGEN</div><h1>Laufzeiten</h1><p>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.</p><label>Laufzeit suchen<input id="runtime-search" type="search" placeholder="Name oder Bereich"></label><p id="runtime-catalog-message" role="status">Installationsstatus wird geprüft …</p><div class="detail-list">${runtimeRows.map(([name,category,route,path,description],i)=>`<details class="detail-row" data-runtime-row="${i}"><summary class="detail-summary"><strong>${name}</strong><span>${category}</span><span data-runtime-status>${path?'Wird geprüft …':'Noch nicht angebunden'}</span></summary><div class="detail-body"><p>${description}</p><p data-runtime-version></p>${route?`<a class="link" href="#${route}">${i===0?'Installation, Build & Updates öffnen': 'Einrichtung öffnen'} →</a>`:''}${i===0?'<p><button id="catalog-llama-updates">llama.cpp-Updates prüfen</button></p><div id="catalog-llama-releases"></div>':''}</div></details>`).join('')}</div>`;}
+2 -1
View File
@@ -60,7 +60,8 @@ class Tests(unittest.TestCase):
def test_separator_runtime_is_admin_only_and_rejects_unknown_package(self): def test_separator_runtime_is_admin_only_and_rejects_unknown_package(self):
status=self.request('separator-runtime') status=self.request('separator-runtime')
self.assertFalse(status['installed']);self.assertEqual(len(status['models']),2) self.assertFalse(status['installed']);self.assertEqual(len(status['models']),4)
self.assertTrue(all(m['source']['files'] for m in status['models']))
req=urllib.request.Request(self.url+'/api/v1/separator-runtime/download',data=b'{"model":"unknown"}',headers={'Cookie':self.cookie,'X-Athena-Deck':'1','Content-Type':'application/json'}) req=urllib.request.Request(self.url+'/api/v1/separator-runtime/download',data=b'{"model":"unknown"}',headers={'Cookie':self.cookie,'X-Athena-Deck':'1','Content-Type':'application/json'})
with self.assertRaises(urllib.error.HTTPError) as error:urllib.request.urlopen(req) with self.assertRaises(urllib.error.HTTPError) as error:urllib.request.urlopen(req)
self.assertEqual(error.exception.code,400);error.exception.close() self.assertEqual(error.exception.code,400);error.exception.close()