Warp drive
1
.gitignore
vendored
@ -217,3 +217,4 @@ xtts_models
|
|||||||
models.txt
|
models.txt
|
||||||
logs
|
logs
|
||||||
*.pkl
|
*.pkl
|
||||||
|
lollms_apps_zoo
|
BIN
assets/logo.png
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 580 KiB |
@ -1,5 +1,5 @@
|
|||||||
# =================== Lord Of Large Language Multimodal Systems Configuration file ===========================
|
# =================== Lord Of Large Language Multimodal Systems Configuration file ===========================
|
||||||
version: 128
|
version: 129
|
||||||
binding_name: null
|
binding_name: null
|
||||||
model_name: null
|
model_name: null
|
||||||
model_variant: null
|
model_variant: null
|
||||||
@ -101,7 +101,7 @@ copy_to_clipboard_add_all_details: false
|
|||||||
|
|
||||||
# -------------------- Services global configurations --------------------------
|
# -------------------- Services global configurations --------------------------
|
||||||
# Select the active test to speach, text to image and speach to text services
|
# Select the active test to speach, text to image and speach to text services
|
||||||
active_tts_service: "None" # xtts (offline), openai_tts (API key required)
|
active_tts_service: "None" # xtts (offline), openai_tts (API key required), elevenlabs_tts (API key required)
|
||||||
active_tti_service: "None" # autosd (offline), dall-e (online)
|
active_tti_service: "None" # autosd (offline), dall-e (online)
|
||||||
active_stt_service: "None" # whisper (offline), asr (offline or online), openai_whiosper (API key required)
|
active_stt_service: "None" # whisper (offline), asr (offline or online), openai_whiosper (API key required)
|
||||||
active_ttm_service: "None" # musicgen (offline)
|
active_ttm_service: "None" # musicgen (offline)
|
||||||
@ -161,6 +161,12 @@ openai_tts_key: ""
|
|||||||
openai_tts_model: "tts-1"
|
openai_tts_model: "tts-1"
|
||||||
openai_tts_voice: "alloy"
|
openai_tts_voice: "alloy"
|
||||||
|
|
||||||
|
|
||||||
|
elevenlabs_tts_key: ""
|
||||||
|
elevenlabs_tts_model_id: "eleven_monolingual_v2"
|
||||||
|
elevenlabs_tts_voice_stability: 0.5
|
||||||
|
elevenlabs_tts_voice_boost: 0.5
|
||||||
|
elevenlabs_tts_voice_id: EXAVITQu4vr4xnSDxMaL
|
||||||
# ***************** TTI *****************
|
# ***************** TTI *****************
|
||||||
|
|
||||||
use_negative_prompt: true
|
use_negative_prompt: true
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
from fastapi import APIRouter, HTTPException
|
from fastapi import APIRouter, HTTPException, Query
|
||||||
from fastapi.responses import PlainTextResponse
|
from fastapi.responses import PlainTextResponse
|
||||||
from pydantic import BaseModel, Field
|
from pydantic import BaseModel, Field
|
||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
@ -72,7 +72,7 @@ async def list_apps():
|
|||||||
uid=uid,
|
uid=uid,
|
||||||
name=application_name,
|
name=application_name,
|
||||||
folder_name = app_name.name,
|
folder_name = app_name.name,
|
||||||
icon=f"/apps/{app_name.name}/icon",
|
icon=f"/apps/{app_name.name}/icon.png",
|
||||||
category=category,
|
category=category,
|
||||||
description=description,
|
description=description,
|
||||||
author=author,
|
author=author,
|
||||||
@ -133,11 +133,20 @@ async def open_folder_in_vscode(request: OpenFolderRequest):
|
|||||||
|
|
||||||
@router.post("/apps/{app_name}/code")
|
@router.post("/apps/{app_name}/code")
|
||||||
async def get_app_code(app_name: str, auth: AuthRequest):
|
async def get_app_code(app_name: str, auth: AuthRequest):
|
||||||
|
check_access(lollmsElfServer, auth.client_id)
|
||||||
app_path = lollmsElfServer.lollms_paths.apps_zoo_path / app_name / "index.html"
|
app_path = lollmsElfServer.lollms_paths.apps_zoo_path / app_name / "index.html"
|
||||||
if not app_path.exists():
|
if not app_path.exists():
|
||||||
raise HTTPException(status_code=404, detail="App not found")
|
raise HTTPException(status_code=404, detail="App not found")
|
||||||
return FileResponse(app_path)
|
return FileResponse(app_path)
|
||||||
|
|
||||||
|
@router.get("/apps/{app_name}/{file}")
|
||||||
|
async def get_app_file(app_name: str, file: str):
|
||||||
|
file=sanitize_path(file)
|
||||||
|
app_path = lollmsElfServer.lollms_paths.apps_zoo_path / app_name / file
|
||||||
|
if not app_path.exists():
|
||||||
|
raise HTTPException(status_code=404, detail="App file not found")
|
||||||
|
return FileResponse(app_path)
|
||||||
|
|
||||||
|
|
||||||
@router.post("/install/{app_name}")
|
@router.post("/install/{app_name}")
|
||||||
async def install_app(app_name: str, auth: AuthRequest):
|
async def install_app(app_name: str, auth: AuthRequest):
|
||||||
|
@ -1 +0,0 @@
|
|||||||
Subproject commit cdd6fc972c78e55c4135f2e0fb7f3236538d29b0
|
|
@ -1 +1 @@
|
|||||||
Subproject commit c68b687e7ce7a2dbb55570907ab2280e3f691a0b
|
Subproject commit 390d0d49dae0136400a1f60bb4fffc1c41ce8aad
|
@ -71,7 +71,7 @@ def terminate_thread(thread):
|
|||||||
else:
|
else:
|
||||||
ASCIIColors.yellow("Canceled successfully")# The current version of the webui
|
ASCIIColors.yellow("Canceled successfully")# The current version of the webui
|
||||||
|
|
||||||
lollms_webui_version="10 (Brainwaves)"
|
lollms_webui_version="10.1 (Warp Drive)"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
BIN
web/dist/assets/default_model-252b3424.png
vendored
Before Width: | Height: | Size: 799 KiB |
8
web/dist/assets/index-5b307d27.css
vendored
8
web/dist/assets/index-cac66727.css
vendored
Normal file
BIN
web/dist/assets/logo-e4c6fdd2.png
vendored
Before Width: | Height: | Size: 1.8 MiB |
BIN
web/dist/assets/logo-ec01a7c6.png
vendored
Normal file
After Width: | Height: | Size: 580 KiB |
4
web/dist/index.html
vendored
@ -6,8 +6,8 @@
|
|||||||
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
|
<script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-svg.js"></script>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>LoLLMS WebUI</title>
|
<title>LoLLMS WebUI</title>
|
||||||
<script type="module" crossorigin src="/assets/index-c4c0357a.js"></script>
|
<script type="module" crossorigin src="/assets/index-e43bf984.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index-5b307d27.css">
|
<link rel="stylesheet" href="/assets/index-cac66727.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
Before Width: | Height: | Size: 799 KiB After Width: | Height: | Size: 580 KiB |
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 580 KiB |
@ -1,95 +1,118 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="app-zoo w-full p-4 overflow-y-auto scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">
|
<div class="app-zoo w-full p-6 overflow-y-auto scrollbar-thin scrollbar-track-bg-light-tone scrollbar-thumb-bg-light-tone-panel hover:scrollbar-thumb-primary dark:scrollbar-track-bg-dark-tone dark:scrollbar-thumb-bg-dark-tone-panel dark:hover:scrollbar-thumb-primary active:scrollbar-thumb-secondary">
|
||||||
<div class="mb-6 flex flex-wrap justify-between items-center gap-4">
|
<nav class="bg-white shadow-lg rounded-lg p-4 max-w-4xl mx-auto">
|
||||||
<button
|
<div class="flex flex-wrap items-center justify-between gap-4">
|
||||||
@click="fetchGithubApps"
|
<div class="flex items-center space-x-4">
|
||||||
class="bg-green-500 hover:bg-green-600 focus:ring-2 focus:ring-green-300 text-white font-semibold px-6 py-2 rounded-lg transition duration-300 ease-in-out shadow-md"
|
<button
|
||||||
aria-label="Refresh apps from GitHub"
|
@click="fetchGithubApps"
|
||||||
>
|
class="btn btn-primary"
|
||||||
<span class="flex items-center">
|
aria-label="Refresh apps from GitHub"
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"></path>
|
||||||
|
</svg>
|
||||||
|
Refresh
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<button
|
||||||
|
@click="openAppsFolder"
|
||||||
|
class="btn btn-secondary"
|
||||||
|
aria-label="Open apps folder"
|
||||||
|
>
|
||||||
|
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 19a2 2 0 01-2-2V7a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1M5 19h14a2 2 0 002-2v-5a2 2 0 00-2-2H9a2 2 0 00-2 2v5a2 2 0 01-2 2z"></path>
|
||||||
|
</svg>
|
||||||
|
Open Folder
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="relative flex-grow max-w-md">
|
||||||
|
<input
|
||||||
|
v-model="searchQuery"
|
||||||
|
placeholder="Search apps..."
|
||||||
|
class="w-full border-b-2 border-gray-300 px-4 py-2 pl-10 focus:outline-none focus:border-blue-500 transition duration-300 ease-in-out"
|
||||||
|
aria-label="Search apps"
|
||||||
|
>
|
||||||
|
<svg class="w-5 h-5 text-gray-400 absolute left-3 top-1/2 transform -translate-y-1/2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
Refresh apps
|
</div>
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<button
|
|
||||||
@click="openAppsFolder"
|
|
||||||
class="bg-blue-500 hover:bg-blue-600 focus:ring-2 focus:ring-blue-300 text-white font-semibold px-6 py-2 rounded-lg transition duration-300 ease-in-out shadow-md"
|
|
||||||
aria-label="Open apps folder"
|
|
||||||
>
|
|
||||||
<span class="flex items-center">
|
|
||||||
<svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 19a2 2 0 01-2-2V7a2 2 0 012-2h4l2 2h4a2 2 0 012 2v1M5 19h14a2 2 0 002-2v-5a2 2 0 00-2-2H9a2 2 0 00-2 2v5a2 2 0 01-2 2z"></path>
|
|
||||||
</svg>
|
|
||||||
Open applications folder
|
|
||||||
</span>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="relative flex-grow max-w-md">
|
|
||||||
<input
|
|
||||||
v-model="searchQuery"
|
|
||||||
placeholder="Search apps..."
|
|
||||||
class="w-full border border-gray-300 rounded-lg px-4 py-2 pl-10 focus:outline-none focus:ring-2 focus:ring-blue-300 transition duration-300 ease-in-out"
|
|
||||||
aria-label="Search apps"
|
|
||||||
>
|
|
||||||
<svg class="w-5 h-5 text-gray-400 absolute left-3 top-1/2 transform -translate-y-1/2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
<div v-if="loading" class="flex justify-center items-center space-x-2 my-8" aria-live="polite">
|
<div v-if="loading" class="flex justify-center items-center space-x-2 my-8" aria-live="polite">
|
||||||
<div class="animate-spin rounded-full h-8 w-8 border-t-2 border-b-2 border-blue-500"></div>
|
<div class="animate-spin rounded-full h-10 w-10 border-t-2 border-b-2 border-blue-500"></div>
|
||||||
<span class="text-xl text-gray-700 font-semibold">Loading...</span>
|
<span class="text-xl text-gray-700 font-semibold">Loading...</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="category in categories" :key="category" class="mb-8">
|
<div v-for="category in categories" :key="category" class="mb-12">
|
||||||
<h2 class="text-2xl font-bold mb-4">{{ category }}</h2>
|
<h2 class="text-3xl font-bold mb-6 text-gray-800">{{ category }}</h2>
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||||
<div
|
<div
|
||||||
v-for="app in filteredApps.filter(a => a.category === category)"
|
v-for="app in filteredApps.filter(a => a.category === category)"
|
||||||
:key="app.uid"
|
:key="app.uid"
|
||||||
class="app-card bg-white border rounded-lg shadow-lg p-6 hover:shadow-xl transition w-full"
|
class="app-card bg-white border rounded-xl shadow-lg p-6 hover:shadow-xl transition duration-300 ease-in-out flex flex-col h-full"
|
||||||
>
|
>
|
||||||
<div class="flex items-center mb-4">
|
<div class="flex-grow">
|
||||||
<img :src="app.icon" alt="App Icon" class="w-16 h-16 rounded-full border border-gray-300 mr-4" />
|
<div class="flex items-center mb-4">
|
||||||
<div>
|
<img :src="app.icon" alt="App Icon" class="w-16 h-16 rounded-full border border-gray-300 mr-4" />
|
||||||
<h3 class="font-semibold text-lg">{{ app.name }}</h3>
|
<div>
|
||||||
<p class="text-sm text-gray-600">Author: {{ app.author }}</p>
|
<h3 class="font-bold text-xl text-gray-800">{{ app.name }}</h3>
|
||||||
<p class="text-sm text-gray-600">Version: {{ app.version }}</p>
|
<p class="text-sm text-gray-600">Author: {{ app.author }}</p>
|
||||||
|
<p class="text-sm text-gray-600">Version: {{ app.version }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mb-4">
|
||||||
|
<h4 class="font-semibold mb-1 text-gray-700">Description:</h4>
|
||||||
|
<p class="text-sm text-gray-600 h-20 overflow-y-auto">{{ app.description }}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="text-sm text-gray-600 mb-2">AI Model: {{ app.model_name }}</p>
|
||||||
|
|
||||||
|
<div v-if="app.disclaimer && app.disclaimer.trim() !== ''" class="mb-4">
|
||||||
|
<h4 class="font-semibold mb-1 text-gray-700">Disclaimer:</h4>
|
||||||
|
<p class="text-xs text-gray-500 italic h-16 overflow-y-auto">{{ app.disclaimer }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mb-4">
|
<div class="mt-auto pt-4 border-t">
|
||||||
<h4 class="font-semibold mb-1">Description:</h4>
|
<div class="flex justify-between">
|
||||||
<p class="text-sm text-gray-600 h-20 overflow-y-auto">{{ app.description }}</p>
|
<button v-if="app.installed" @click="uninstallApp(app.folder_name)" class="text-red-500 hover:text-red-600 transition duration-300 ease-in-out" title="Uninstall">
|
||||||
</div>
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||||
<p class="text-sm text-gray-600 mb-2">AI Model: {{ app.model_name }}</p>
|
</svg>
|
||||||
|
</button>
|
||||||
<div v-if="app.disclaimer && app.disclaimer.trim() !== ''" class="mb-4">
|
<button v-else-if="app.existsInFolder" @click="deleteApp(app.name)" class="text-yellow-500 hover:text-yellow-600 transition duration-300 ease-in-out" title="Delete">
|
||||||
<h4 class="font-semibold mb-1">Disclaimer:</h4>
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<p class="text-xs text-gray-500 italic h-16 overflow-y-auto">{{ app.disclaimer }}</p>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
|
||||||
</div>
|
</svg>
|
||||||
<div class="flex flex-wrap gap-2">
|
</button>
|
||||||
<button v-if="app.installed" @click="uninstallApp(app.folder_name)" class="bg-red-500 hover:bg-red-600 text-white px-2 py-1 rounded text-sm">
|
<button v-else @click="installApp(app.folder_name)" class="text-blue-500 hover:text-blue-600 transition duration-300 ease-in-out" title="Install">
|
||||||
Uninstall
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
</button>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
||||||
<button v-else-if="app.existsInFolder" @click="deleteApp(app.name)" class="bg-yellow-500 hover:bg-yellow-600 text-white px-2 py-1 rounded text-sm">
|
</svg>
|
||||||
Delete
|
</button>
|
||||||
</button>
|
<button v-if="app.installed" @click="editApp(app)" class="text-purple-500 hover:text-purple-600 transition duration-300 ease-in-out" title="Edit">
|
||||||
<button v-else @click="installApp(app.folder_name)" class="bg-blue-500 hover:bg-blue-600 text-white px-2 py-1 rounded text-sm">
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
Install
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
|
||||||
</button>
|
</svg>
|
||||||
<button v-if="app.installed" @click="editApp(app)" class="bg-purple-500 hover:bg-purple-600 text-white px-2 py-1 rounded text-sm">
|
</button>
|
||||||
Edit
|
<button @click="downloadApp(app.name)" class="text-green-500 hover:text-green-600 transition duration-300 ease-in-out" title="Download">
|
||||||
</button>
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
<button @click="downloadApp(app.name)" class="bg-green-500 hover:bg-green-600 text-white px-2 py-1 rounded text-sm">
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
|
||||||
Download
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<button @click="handleAppClick(app)" class="bg-gray-500 hover:bg-gray-600 text-white px-2 py-1 rounded text-sm">
|
<button @click="handleAppClick(app)" class="text-gray-500 hover:text-gray-600 transition duration-300 ease-in-out" title="View">
|
||||||
View
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
</button>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
<button @click="openApp(app)" class="text-indigo-500 hover:text-indigo-600 transition duration-300 ease-in-out" title="Open">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -99,14 +122,14 @@
|
|||||||
<div class="bg-white rounded-lg p-6 w-11/12 h-5/6 flex flex-col">
|
<div class="bg-white rounded-lg p-6 w-11/12 h-5/6 flex flex-col">
|
||||||
<div class="flex justify-between items-center mb-4">
|
<div class="flex justify-between items-center mb-4">
|
||||||
<h2 class="text-2xl font-bold">{{ selectedApp.name }}</h2>
|
<h2 class="text-2xl font-bold">{{ selectedApp.name }}</h2>
|
||||||
<button @click="backToZoo" class="bg-gray-300 hover:bg-gray-400 px-2 py-1 rounded">Close</button>
|
<button @click="backToZoo" class="bg-gray-300 hover:bg-gray-400 px-4 py-2 rounded-lg transition duration-300 ease-in-out">Close</button>
|
||||||
</div>
|
</div>
|
||||||
<iframe v-if="appCode" :srcdoc="appCode" class="flex-grow border-none"></iframe>
|
<iframe v-if="appCode" :srcdoc="appCode" class="flex-grow border-none"></iframe>
|
||||||
<p v-else class="text-center text-red-500">Please install this app to view its code.</p>
|
<p v-else class="text-center text-red-500">Please install this app to view its code.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="message" class="fixed bottom-4 right-4 px-4 py-2 rounded" :class="{ 'bg-green-100 text-green-800': successMessage, 'bg-red-100 text-red-800': !successMessage }">
|
<div v-if="message" class="fixed bottom-4 right-4 px-6 py-3 rounded-lg shadow-md" :class="{ 'bg-green-100 text-green-800': successMessage, 'bg-red-100 text-red-800': !successMessage }">
|
||||||
{{ message }}
|
{{ message }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -172,7 +195,7 @@ export default {
|
|||||||
client_id: this.$store.state.client_id
|
client_id: this.$store.state.client_id
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.showMessage('Failed to refresh GitHub apps.', false);
|
this.showMessage('Failed to open apps folder.', false);
|
||||||
} finally {
|
} finally {
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
}
|
}
|
||||||
@ -192,9 +215,7 @@ export default {
|
|||||||
async handleAppClick(app) {
|
async handleAppClick(app) {
|
||||||
if (app.installed) {
|
if (app.installed) {
|
||||||
this.selectedApp = app;
|
this.selectedApp = app;
|
||||||
const response = await axios.post(`/apps/${app.folder_name}/code`, {
|
const response = await axios.get(`/apps/${app.folder_name}/index.html`);
|
||||||
client_id: this.$store.state.client_id,
|
|
||||||
});
|
|
||||||
this.appCode = response.data;
|
this.appCode = response.data;
|
||||||
} else {
|
} else {
|
||||||
this.showMessage(`Please install ${app.folder_name} to view its code.`, false);
|
this.showMessage(`Please install ${app.folder_name} to view its code.`, false);
|
||||||
@ -278,6 +299,13 @@ export default {
|
|||||||
this.showMessage('Download failed.', false);
|
this.showMessage('Download failed.', false);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
openApp(app) {
|
||||||
|
if (app.installed) {
|
||||||
|
window.open(`/apps/${app.folder_name}/index.html?client_id=${this.$store.state.client_id}`, '_blank');
|
||||||
|
} else {
|
||||||
|
this.showMessage(`Please install ${app.name} before opening.`, false);
|
||||||
|
}
|
||||||
|
},
|
||||||
showMessage(msg, success) {
|
showMessage(msg, success) {
|
||||||
this.message = msg;
|
this.message = msg;
|
||||||
this.successMessage = success;
|
this.successMessage = success;
|
||||||
@ -293,5 +321,75 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* You can add any additional styles here if needed */
|
.app-card {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.app-card:hover {
|
||||||
|
transform: translateY(-5px);
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-thin::-webkit-scrollbar {
|
||||||
|
width: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-thin::-webkit-scrollbar-track {
|
||||||
|
background: #f1f1f1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-thin::-webkit-scrollbar-thumb {
|
||||||
|
background: #888;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scrollbar-thin::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: #555;
|
||||||
|
}
|
||||||
|
.btn {
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
transition: all 0.3s ease-in-out;
|
||||||
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.btn-primary {
|
||||||
|
background-color: #3b82f6;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
.btn-primary:hover {
|
||||||
|
background-color: #2563eb;
|
||||||
|
}
|
||||||
|
.btn-primary:focus {
|
||||||
|
box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.5);
|
||||||
|
}
|
||||||
|
.btn-secondary {
|
||||||
|
background-color: #e5e7eb;
|
||||||
|
color: #374151;
|
||||||
|
}
|
||||||
|
.btn-secondary:hover {
|
||||||
|
background-color: #d1d5db;
|
||||||
|
}
|
||||||
|
.btn-secondary:focus {
|
||||||
|
box-shadow: 0 0 0 3px rgba(107, 114, 128, 0.5);
|
||||||
|
}
|
||||||
|
.search-input {
|
||||||
|
width: 100%;
|
||||||
|
border-bottom: 2px solid #e5e7eb;
|
||||||
|
padding: 0.5rem 1rem 0.5rem 2.5rem;
|
||||||
|
transition: border-color 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
.search-input:focus {
|
||||||
|
outline: none;
|
||||||
|
border-color: #3b82f6;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -1607,6 +1607,7 @@
|
|||||||
<option value="browser">Use Browser TTS (doesn't work in realtime mode)</option>
|
<option value="browser">Use Browser TTS (doesn't work in realtime mode)</option>
|
||||||
<option value="xtts">XTTS</option>
|
<option value="xtts">XTTS</option>
|
||||||
<option value="openai_tts">Open AI TTS</option>
|
<option value="openai_tts">Open AI TTS</option>
|
||||||
|
<option value="eleven_labs_tts">ElevenLabs TTS</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
@ -2562,6 +2563,94 @@
|
|||||||
</table>
|
</table>
|
||||||
</Card>
|
</Card>
|
||||||
</Card>
|
</Card>
|
||||||
|
<Card title="Eleven Labs TTS service" :is_subcard="true" class="pb-2 m-2">
|
||||||
|
<table class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||||
|
<tr>
|
||||||
|
<td style="min-width: 200px;">
|
||||||
|
<label for="elevenlabs_tts_key" class="text-sm font-bold" style="margin-right: 1rem;">Eleven Labs key:</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="elevenlabs_tts_key"
|
||||||
|
required
|
||||||
|
v-model="configFile.elevenlabs_tts_key"
|
||||||
|
@change="settingsChanged=true"
|
||||||
|
class="mt-1 px-2 py-1 border border-gray-300 rounded dark:bg-gray-600"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="min-width: 200px;">
|
||||||
|
<label for="elevenlabs_tts_model_id" class="text-sm font-bold" style="margin-right: 1rem;">Eleven Labs TTS model ID:</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="elevenlabs_tts_model_id"
|
||||||
|
required
|
||||||
|
v-model="configFile.elevenlabs_tts_model_id"
|
||||||
|
@change="settingsChanged=true"
|
||||||
|
class="mt-1 px-2 py-1 border border-gray-300 rounded dark:bg-gray-600"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="min-width: 200px;">
|
||||||
|
<label for="elevenlabs_tts_voice_stability" class="text-sm font-bold" style="margin-right: 1rem;">Voice Stability:</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="elevenlabs_tts_voice_stability"
|
||||||
|
required
|
||||||
|
v-model="configFile.elevenlabs_tts_voice_stability"
|
||||||
|
@change="settingsChanged=true"
|
||||||
|
class="mt-1 px-2 py-1 border border-gray-300 rounded dark:bg-gray-600"
|
||||||
|
step="0.1"
|
||||||
|
min="0" max="1"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="min-width: 200px;">
|
||||||
|
<label for="elevenlabs_tts_voice_boost" class="text-sm font-bold" style="margin-right: 1rem;">Voice Boost:</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
id="elevenlabs_tts_voice_boost"
|
||||||
|
required
|
||||||
|
v-model="configFile.elevenlabs_tts_voice_boost"
|
||||||
|
@change="settingsChanged=true"
|
||||||
|
class="mt-1 px-2 py-1 border border-gray-300 rounded dark:bg-gray-600"
|
||||||
|
step="0.1"
|
||||||
|
min="0" max="1"
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td style="min-width: 200px;">
|
||||||
|
<label for="elevenlabs_tts_voice_id" class="text-sm font-bold" style="margin-right: 1rem;">Voice ID:</label>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="flex flex-row">
|
||||||
|
<select v-model="configFile.elevenlabs_tts_voice_id" @change="settingsChanged=true">
|
||||||
|
<option v-for="voice in voices" :key="voice.voice_id" :value="voice.voice_id">{{ voice.name }}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</Card>
|
||||||
<Card title="TTI services" :is_shrunk="true" :is_subcard="true" class="pb-2 m-2">
|
<Card title="TTI services" :is_shrunk="true" :is_subcard="true" class="pb-2 m-2">
|
||||||
<Card title="Stable diffusion service" :is_subcard="true" class="pb-2 m-2">
|
<Card title="Stable diffusion service" :is_subcard="true" class="pb-2 m-2">
|
||||||
<table class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
<table class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||||
@ -4156,6 +4245,14 @@ export default {
|
|||||||
//await socket.on('install_progress', this.progressListener);
|
//await socket.on('install_progress', this.progressListener);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
fetchElevenLabsVoices() {
|
||||||
|
fetch('https://api.elevenlabs.io/v1/voices')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
this.voices = data.voices;
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Error fetching voices:', error));
|
||||||
|
},
|
||||||
async refreshHardwareUsage(store) {
|
async refreshHardwareUsage(store) {
|
||||||
await store.dispatch('refreshDiskUsage');
|
await store.dispatch('refreshDiskUsage');
|
||||||
await store.dispatch('refreshRamUsage');
|
await store.dispatch('refreshRamUsage');
|
||||||
@ -6137,7 +6234,7 @@ export default {
|
|||||||
catch{
|
catch{
|
||||||
console.log("Couldin't list output devices")
|
console.log("Couldin't list output devices")
|
||||||
}
|
}
|
||||||
|
this.fetchElevenLabsVoices();
|
||||||
},
|
},
|
||||||
activated() {
|
activated() {
|
||||||
//this.load_everything()
|
//this.load_everything()
|
||||||
|