Add selectable native LTX Original runtime and DeskWEB API integration

This commit is contained in:
Mikei386
2026-09-30 15:32:19 +02:00
parent e7a1deaab0
commit a6b7ab93ab
20 changed files with 507 additions and 25 deletions
+17 -5
View File
@@ -113,8 +113,10 @@ class Server(ThreadingHTTPServer):
self.auto_tests=AutoTests(self.catalog.root.parent/'auto-tests.json',self.profiles,self.worker,self.scheduler)
def stop_gpu_work():
self.auto_tests.stop();self.chat_tests.stop();self.image_tests.stop();self.prompt_enhancer.stop_preview();self.tts_tests.stop();self.worker.stop()
from video_comfy import VideoComfy
self.video=VideoComfy(self.scheduler,stop_gpu_work,self.docker,self.catalog.root.parent/'video',self.catalog,self.profiles,self.image_runtime)
from video_original import VideoRuntimes
from ltx_original_runtime import LTXOriginalRuntime
self.ltx_original_runtime=LTXOriginalRuntime(self.catalog.root.parent/'ltx-original-runtime',self.image_runtime)
self.video=VideoRuntimes(self.scheduler,stop_gpu_work,self.docker,self.catalog.root.parent/'video',self.catalog,self.profiles,self.image_runtime,original_runtime=self.ltx_original_runtime)
self.endpoint.video=self.video
self.profiles.video_runtime_ready=lambda:self.image_runtime.status().get("installed",False)
from dashboard_data import Dashboard
@@ -276,7 +278,7 @@ class Handler(BaseHTTPRequestHandler):
return self.headers.get('Host') in allowed
def execution_setup(self, model, profile=None):
installed={'stt':bool(self.server.runtime.status().get('active')),'chat':bool(self.server.runtime.status().get('active')),'image':self.server.image_runtime.status().get('installed',False),'audio':self.server.tts_runtime.status().get('installed',False),'video':self.server.image_runtime.status().get('installed',False)}
installed={'stt':bool(self.server.runtime.status().get('active')),'chat':bool(self.server.runtime.status().get('active')),'image':self.server.image_runtime.status().get('installed',False),'audio':self.server.tts_runtime.status().get('installed',False),'video':self.server.video.status()['runtime']['installed']}
return execution_assess(model,installed,profile)
def do_GET(self):
@@ -290,7 +292,7 @@ class Handler(BaseHTTPRequestHandler):
return self.respond({'error':'Anmeldung erforderlich.'},401)
if not self.authenticated() and self.path == '/':
return self.respond((ROOT/'login.html').read_bytes(), mime='text/html; charset=utf-8')
routes = {'/backup-ui.js':('backup-ui.js','text/javascript'),'/dashboard-ui.js':('dashboard-ui.js','text/javascript'),'/dashboard.css':('dashboard.css','text/css'),'/themes.css':('themes.css','text/css'),'/video-ui.js':('video-ui.js','text/javascript'),'/stt-ui.js':('stt-ui.js','text/javascript'),'/tts-ui.js':('tts-ui.js','text/javascript'),'/auto-test-ui.js':('auto-test-ui.js','text/javascript'),'/chat-test-ui.js':('chat-test-ui.js','text/javascript'),'/endpoint-ui.js':('endpoint-ui.js','text/javascript'),'/docker-ui.js': ('docker-ui.js','text/javascript'), '/': ('index.html', 'text/html; charset=utf-8'), '/app.js': ('app.js', 'text/javascript'), '/style.css': ('style.css', 'text/css'), '/network-ui.js': ('network-ui.js', 'text/javascript'), '/access-ui.js': ('access-ui.js', 'text/javascript'), '/studio.js': ('studio.js', 'text/javascript'), '/catalog-ui.js': ('catalog-ui.js','text/javascript'), '/runtime-ui.js': ('runtime-ui.js','text/javascript'), '/profiles-ui.js': ('profiles-ui.js','text/javascript'), '/image-test-ui.js': ('image-test-ui.js','text/javascript')}
routes = {'/ltx-original-ui.js':('ltx-original-ui.js','text/javascript'),'/backup-ui.js':('backup-ui.js','text/javascript'),'/dashboard-ui.js':('dashboard-ui.js','text/javascript'),'/dashboard.css':('dashboard.css','text/css'),'/themes.css':('themes.css','text/css'),'/video-ui.js':('video-ui.js','text/javascript'),'/stt-ui.js':('stt-ui.js','text/javascript'),'/tts-ui.js':('tts-ui.js','text/javascript'),'/auto-test-ui.js':('auto-test-ui.js','text/javascript'),'/chat-test-ui.js':('chat-test-ui.js','text/javascript'),'/endpoint-ui.js':('endpoint-ui.js','text/javascript'),'/docker-ui.js': ('docker-ui.js','text/javascript'), '/': ('index.html', 'text/html; charset=utf-8'), '/app.js': ('app.js', 'text/javascript'), '/style.css': ('style.css', 'text/css'), '/network-ui.js': ('network-ui.js', 'text/javascript'), '/access-ui.js': ('access-ui.js', 'text/javascript'), '/studio.js': ('studio.js', 'text/javascript'), '/catalog-ui.js': ('catalog-ui.js','text/javascript'), '/runtime-ui.js': ('runtime-ui.js','text/javascript'), '/profiles-ui.js': ('profiles-ui.js','text/javascript'), '/image-test-ui.js': ('image-test-ui.js','text/javascript')}
if self.path in routes:
name, mime = routes[self.path]
return self.respond((ROOT/name).read_bytes(), mime=mime)
@@ -309,6 +311,8 @@ class Handler(BaseHTTPRequestHandler):
if urlsplit(self.path).path == '/api/v1/tts/audio':
try:return self.respond(self.server.tts_tests.audio(parse_qs(urlsplit(self.path).query).get('id',[''])[0]),mime='audio/wav')
except (OSError,ValueError):return self.respond({'error':'Audio nicht verfügbar.'},404)
if self.path == '/api/v1/ltx-original-runtime':return self.respond(self.server.ltx_original_runtime.status())
if self.path == '/api/v1/ltx-original-runtime/log':return self.respond(self.server.ltx_original_runtime.log())
if self.path == '/api/v1/video':return self.respond(self.server.video.status())
if self.path == '/api/v1/image-runtime':return self.respond(self.server.image_runtime.status())
if self.path == '/api/v1/image-tests':return self.respond(self.server.image_tests.status())
@@ -478,9 +482,16 @@ class Handler(BaseHTTPRequestHandler):
if data:raise ValueError('Keine Parameter erwartet.')
return self.respond(self.server.chat_tests.stop() if self.path.endswith('/cancel') else self.server.chat_tests.unload())
except ValueError as exc:return self.respond({'error':str(exc)},400)
if self.path in ('/api/v1/video/mode','/api/v1/video/service'):
if self.path in ('/api/v1/ltx-original-runtime/install','/api/v1/ltx-original-runtime/cancel'):
try:
if self.read_json():raise ValueError('Keine Installationsparameter erwartet.')
if self.path.endswith('/cancel'):return self.respond(self.server.ltx_original_runtime.stop())
return self.respond(self.server.ltx_original_runtime.start())
except (OSError,ValueError) as exc:return self.respond({'error':str(exc)},400)
if self.path in ('/api/v1/video/mode','/api/v1/video/service','/api/v1/video/runtime'):
try:
data=self.read_json()
if self.path.endswith('/runtime') and set(data)=={'runtime'}:return self.respond(self.server.video.select_runtime(data['runtime']))
if self.path.endswith('/service') and set(data)=={'id'}:return self.respond(self.server.video.select(data['id']))
if set(data)!={'mode'}:raise ValueError('Nur Modus llm oder video erwartet.')
return self.respond(self.server.video.switch(data['mode']))
@@ -646,6 +657,7 @@ def main():
server.tts_tests.stop()
server.tts_runtime.stop()
server.image_runtime.stop()
server.ltx_original_runtime.stop()
server.prompt_enhancer.stop()
server.image_tests.stop()
server.runtime.stop()