mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2024-12-19 20:37:51 +00:00
upgraded tool
This commit is contained in:
parent
bb43498c89
commit
0f6ed43fac
@ -20,7 +20,13 @@ from lollms.helpers import ASCIIColors, trace_exception
|
||||
from lollms.com import NotificationType, NotificationDisplayType, LoLLMsCom
|
||||
from lollms.app import LollmsApplication
|
||||
from lollms.utilities import File64BitsManager, PromptReshaper, PackageManager, find_first_available_file_index
|
||||
try:
|
||||
from lollms.media import WebcamImageSender, AudioRecorder
|
||||
Media_on=True
|
||||
except:
|
||||
ASCIIColors.warning("Couldn't load media library.\nYou will not be able to perform any of the media linked operations. please verify the logs and install any required installations")
|
||||
Media_on=False
|
||||
|
||||
from safe_store import TextVectorizer, VectorizationMethod, VisualizationMethod
|
||||
import threading
|
||||
from tqdm import tqdm
|
||||
@ -191,6 +197,7 @@ class LoLLMsAPI(LollmsApplication):
|
||||
"first_chunk": True,
|
||||
}
|
||||
}
|
||||
if Media_on:
|
||||
try:
|
||||
self.webcam = WebcamImageSender(socketio,lollmsCom=self)
|
||||
except:
|
||||
@ -201,7 +208,12 @@ class LoLLMsAPI(LollmsApplication):
|
||||
self.summoned = False
|
||||
self.audio_cap = AudioRecorder(socketio,self.rec_output_folder/"rt.wav", callback=self.audio_callback,lollmsCom=self)
|
||||
except:
|
||||
self.audio_cap = None
|
||||
self.rec_output_folder = None
|
||||
else:
|
||||
self.webcam = None
|
||||
self.rec_output_folder = None
|
||||
|
||||
# =========================================================================================
|
||||
# Socket IO stuff
|
||||
# =========================================================================================
|
||||
|
53
app.py
53
app.py
@ -16,6 +16,9 @@ __license__ = "Apache 2.0"
|
||||
__version__ ="8.0"
|
||||
|
||||
main_repo = "https://github.com/ParisNeo/lollms-webui.git"
|
||||
|
||||
|
||||
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
@ -26,8 +29,15 @@ import time
|
||||
import traceback
|
||||
import webbrowser
|
||||
from pathlib import Path
|
||||
from lollms.config import InstallOption
|
||||
from lollms.main_config import LOLLMSConfig
|
||||
from lollms.paths import LollmsPaths, gptqlora_repo
|
||||
from lollms.com import NotificationType, NotificationDisplayType
|
||||
from lollms.utilities import AdvancedGarbageCollector, reinstall_pytorch_with_cuda, convert_language_name
|
||||
lollms_paths = LollmsPaths.find_paths(force_local=True, custom_default_cfg_path="configs/config.yaml")
|
||||
# Configuration loading part
|
||||
config = LOLLMSConfig.autoload(lollms_paths)
|
||||
|
||||
def run_update_script(args=None):
|
||||
update_script = Path(__file__).parent/"update_script.py"
|
||||
|
||||
@ -59,11 +69,9 @@ try:
|
||||
import traceback
|
||||
import subprocess
|
||||
import signal
|
||||
from lollms.config import InstallOption
|
||||
from lollms.binding import LOLLMSConfig, BindingBuilder
|
||||
from lollms.binding import BindingBuilder
|
||||
from lollms.personality import AIPersonality
|
||||
from lollms.config import BaseConfig
|
||||
from lollms.paths import LollmsPaths, gptqlora_repo
|
||||
from lollms.extension import LOLLMSExtension, ExtensionBuilder
|
||||
|
||||
from flask_cors import CORS
|
||||
@ -484,6 +492,14 @@ try:
|
||||
"/import_multiple_discussions", "import_multiple_discussions", self.import_multiple_discussions, methods=["POST"]
|
||||
)
|
||||
|
||||
|
||||
self.add_endpoint(
|
||||
"/list_voices", "list_voices", self.list_voices, methods=["GET"]
|
||||
)
|
||||
self.add_endpoint(
|
||||
"/set_voice", "set_voice", self.set_voice, methods=["POST"]
|
||||
)
|
||||
|
||||
self.add_endpoint(
|
||||
"/read", "read", self.read, methods=["POST"]
|
||||
)
|
||||
@ -757,19 +773,42 @@ try:
|
||||
presets.append(preset)
|
||||
return jsonify(presets)
|
||||
|
||||
|
||||
def list_voices(self):
|
||||
voices=["main_voice"]
|
||||
voices_dir:Path=lollms_paths.custom_voices_path
|
||||
voices += [v.stem for v in voices_dir.iterdir() if v.suffix==".wav"]
|
||||
return jsonify({"voices":voices})
|
||||
|
||||
def set_voice(self):
|
||||
data = request.get_json()
|
||||
self.config.reading_voice=data["voice"]
|
||||
if self.config.auto_save:
|
||||
self.config.save_config()
|
||||
return jsonify({"status":true})
|
||||
|
||||
def read(self):
|
||||
# Get the JSON data from the POST request.
|
||||
data = request.get_json()
|
||||
voice=data.get("voice",self.config.reading_voice)
|
||||
if voice is None:
|
||||
voice = "main_voice"
|
||||
self.info("Starting to build voice")
|
||||
try:
|
||||
from lollms.audio_gen_modules.lollms_xtts import LollmsXTTS
|
||||
if self.tts is None:
|
||||
self.tts = LollmsXTTS(self, voice_samples_path=Path(__file__).parent/"voices")
|
||||
language = convert_language_name(self.personality.language)
|
||||
self.tts.set_speaker_folder(Path(__file__).parent/"voices")
|
||||
if voice!="main_voice":
|
||||
voices_folder = self.lollms_paths.custom_voices_path
|
||||
else:
|
||||
voices_folder = Path(__file__).parent/"voices"
|
||||
self.tts.set_speaker_folder(voices_folder)
|
||||
fn = self.personality.name.lower().replace(' ',"_").replace('.','')
|
||||
fn = f"playground_voice.wav"
|
||||
url = f"audio/{fn}"
|
||||
self.tts.tts_to_file(data['text'], "main_voice.wav", f"{fn}", language=language)
|
||||
self.tts.tts_to_file(data['text'], f"{voice}.wav", f"{fn}", language=language)
|
||||
self.info("Voice file ready")
|
||||
return jsonify({"url": url})
|
||||
except:
|
||||
return jsonify({"url": None})
|
||||
@ -2521,7 +2560,6 @@ try:
|
||||
return config, added_entries, removed_entries
|
||||
|
||||
if __name__ == "__main__":
|
||||
lollms_paths = LollmsPaths.find_paths(force_local=True, custom_default_cfg_path="configs/config.yaml")
|
||||
db_folder = lollms_paths.personal_path/"databases"
|
||||
db_folder.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
@ -2653,6 +2691,9 @@ try:
|
||||
|
||||
# if autoshow
|
||||
if config.auto_show_browser:
|
||||
if config['host']=="0.0.0.0":
|
||||
webbrowser.open(f"http://localhost:{config['port']}")
|
||||
else:
|
||||
webbrowser.open(f"http://{config['host']}:{config['port']}")
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# =================== Lord Of Large Language Models Configuration file ===========================
|
||||
version: 31
|
||||
version: 32
|
||||
binding_name: null
|
||||
model_name: null
|
||||
|
||||
@ -50,10 +50,12 @@ enable_gpu: true
|
||||
auto_show_browser: true
|
||||
|
||||
# Audio
|
||||
media_on: false
|
||||
audio_in_language: 'en-US'
|
||||
audio_out_voice: null
|
||||
auto_speak: false
|
||||
auto_read: false
|
||||
reading_voice: null
|
||||
audio_pitch: 1
|
||||
audio_auto_send_input: true
|
||||
audio_silenceTimer: 5000
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 2df38174ccfdd1bae63140f4cc1a7aa024f9a844
|
||||
Subproject commit 5f1365c3069b48c070cb53b69ae628c29479f532
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
4
web/dist/index.html
vendored
4
web/dist/index.html
vendored
@ -6,8 +6,8 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>LoLLMS WebUI - Welcome</title>
|
||||
<script type="module" crossorigin src="/assets/index-537a0c2f.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-ad8f7b32.css">
|
||||
<script type="module" crossorigin src="/assets/index-2ca0499e.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-5d2d92a4.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
@ -630,16 +630,17 @@ export default {
|
||||
},
|
||||
clear_files(){
|
||||
axios.get('/clear_personality_files_list').then(res=>{
|
||||
if(res.data.status){
|
||||
console.log(`Files removed`)
|
||||
console.log(res)
|
||||
if(res.data.state){
|
||||
this.$store.state.toast.showToast("File uploaded successfully",4,true);
|
||||
this.filesList.length = 0;
|
||||
this.isFileSentList.length = 0;
|
||||
}
|
||||
else{
|
||||
console.log(`Files couldn't be removed`)
|
||||
this.$store.state.toast.showToast("Files couldn't be removed",4,false);
|
||||
}
|
||||
})
|
||||
|
||||
this.filesList = []
|
||||
this.isFileSentList = []
|
||||
},
|
||||
send_file(file, next) {
|
||||
const fileReader = new FileReader();
|
||||
@ -767,7 +768,7 @@ export default {
|
||||
// console.log(this.filesList)
|
||||
},
|
||||
sendMessageEvent(msg) {
|
||||
this.filesList = []
|
||||
this.filesList.length = 0;
|
||||
this.$emit('messageSentEvent', msg)
|
||||
|
||||
},
|
||||
|
@ -133,6 +133,14 @@
|
||||
<i data-feather="volume-2"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-row items-center">
|
||||
<div class="text-lg hover:text-red-600 duration-75 active:scale-90 p-2"
|
||||
title="read"
|
||||
@click.stop="read()"
|
||||
:class="{ 'text-red-500': isTalking }">
|
||||
<i data-feather="voicemail"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -169,7 +177,10 @@
|
||||
</div>
|
||||
|
||||
<DynamicUIRenderer v-if="message.ui !== null && message.ui !== undefined && message.ui !== ''" class="w-full h-full" :code="message.ui"></DynamicUIRenderer>
|
||||
|
||||
<audio controls autoplay v-if="audio_url!=null">
|
||||
<source :src="audio_url" type="audio/wav">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
|
||||
</div>
|
||||
<!-- FOOTER -->
|
||||
@ -217,6 +228,8 @@ import MarkdownRenderer from './MarkdownRenderer.vue';
|
||||
import RenderHTMLJS from './RenderHTMLJS.vue';
|
||||
import JsonViewer from "./JsonViewer.vue";
|
||||
import Step from './Step.vue';
|
||||
import axios from 'axios'
|
||||
|
||||
import DynamicUIRenderer from "./DynamicUIRenderer.vue"
|
||||
export default {
|
||||
// eslint-disable-next-line vue/multi-word-component-names
|
||||
@ -240,6 +253,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
audio_url:null,
|
||||
audio:null,
|
||||
msg:null,
|
||||
isSpeaking:false,
|
||||
speechSynthesis: null,
|
||||
@ -296,6 +311,23 @@ export default {
|
||||
onVoicesChanged() {
|
||||
// This event will be triggered when the voices are loaded
|
||||
this.voices = this.speechSynthesis.getVoices();
|
||||
},
|
||||
read(){
|
||||
if(this.isSpeaking){
|
||||
this.audio.pause()
|
||||
}
|
||||
else{
|
||||
this.isSpeaking=true
|
||||
axios.post("./read",{text:this.message.content}).then(response => {
|
||||
let url = response.data.url
|
||||
console.log(url)
|
||||
this.audio_url = url
|
||||
}).catch(ex=>{
|
||||
this.$store.state.toast.showToast(`Error: ${ex}`,4,false)
|
||||
this.generating=false
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
speak() {
|
||||
if (this.msg) {
|
||||
|
@ -1,7 +1,9 @@
|
||||
<template>
|
||||
<div v-if="show" class="fixed top-0 left-0 right-0 bottom-0 flex items-center justify-center bg-black bg-opacity-50">
|
||||
<div class="bg-bg-light dark:bg-bg-dark p-8 rounded-lg shadow-lg">
|
||||
<h3 class="text-lg font-medium">{{ message }}</h3>
|
||||
<div v-if="show" class="fixed top-0 left-0 right-0 bottom-0 flex items-center justify-center bg-black bg-opacity-50 z-50">
|
||||
<div class="pl-10 pr-10 bg-bg-light dark:bg-bg-dark p-8 rounded-lg shadow-lg">
|
||||
<div class="container overflow-y-auto">
|
||||
<div class="text-lg font-medium">{{ message }}</div>
|
||||
</div>
|
||||
<div class="mt-4 flex justify-center">
|
||||
<button @click="hide" class="bg-primary hover:bg-primary-light active:scale-95 duration-150 text-white px-4 py-2 rounded-lg shadow-lg hover:bg-secondary-dark">
|
||||
OK
|
||||
|
@ -39,7 +39,7 @@
|
||||
<div v-if="personality.languages && select_language" class="flex items-center">
|
||||
<i data-feather="globe" class="w-5 m-1"></i>
|
||||
<b>Languages: </b>
|
||||
<select id="languages" v-model ="personality.language"
|
||||
<select v-if="!isMounted" id="languages" v-model ="personality.language"
|
||||
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">
|
||||
|
||||
<option v-for="(item, index) in personality.languages" :key="index"
|
||||
@ -185,6 +185,7 @@ export default {
|
||||
console.log("Unmounting")
|
||||
console.log(this.onUnMount)
|
||||
this.onUnMount(this)
|
||||
this.isMounted=false
|
||||
},
|
||||
toggleSettings() {
|
||||
this.onSettings(this)
|
||||
|
@ -37,6 +37,11 @@
|
||||
</div>
|
||||
<a href="#" @click="restartProgram">
|
||||
<div class="text-2xl hover:text-primary duration-150" title="restart program">
|
||||
<i data-feather="power"></i>
|
||||
</div>
|
||||
</a>
|
||||
<a href="#" @click="refreshPage">
|
||||
<div class="text-2xl hover:text-primary duration-150" title="refresh page">
|
||||
<i data-feather="refresh-ccw"></i>
|
||||
</div>
|
||||
</a>
|
||||
@ -195,6 +200,9 @@ export default {
|
||||
window.close();
|
||||
},2000)
|
||||
},
|
||||
refreshPage() {
|
||||
window.location.reload();
|
||||
},
|
||||
handleOk(inputText) {
|
||||
console.log("Input text:", inputText);
|
||||
},
|
||||
|
@ -61,6 +61,11 @@
|
||||
|
||||
<span>Cursor position {{ cursorPosition }}</span>
|
||||
</div>
|
||||
<audio controls autoplay v-if="audio_url!=null">
|
||||
<source :src="audio_url" type="audio/wav">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
|
||||
<div v-if="tab_id === 'render'">
|
||||
<MarkdownRenderer ref="mdRender" :markdown-text="text" class="mt-4 p-2 rounded shadow-lg dark:bg-bg-dark">
|
||||
</MarkdownRenderer>
|
||||
@ -161,7 +166,7 @@ import Toast from '../components/Toast.vue'
|
||||
import MarkdownRenderer from '../components/MarkdownRenderer.vue';
|
||||
import ClipBoardTextInput from "@/components/ClipBoardTextInput.vue";
|
||||
import Card from "@/components/Card.vue"
|
||||
|
||||
const bUrl = import.meta.env.VITE_LOLLMS_API_BASEURL
|
||||
|
||||
async function showInputPanel(name, default_value="", options=[]) {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -310,6 +315,7 @@ export default {
|
||||
name: 'PlayGroundView',
|
||||
data() {
|
||||
return {
|
||||
audio_url:null,
|
||||
mdRenderHeight:300,
|
||||
selecting_model:false,
|
||||
tab_id:"source",
|
||||
@ -490,7 +496,7 @@ export default {
|
||||
axios.post("./read",{text:this.text}).then(response => {
|
||||
console.log(response.data.url)
|
||||
let url = response.data.url
|
||||
this.text+=`\n<audio controls>\n<source src="${url}" type="audio/wav">\nYour browser does not support the audio element.\n</audio>`
|
||||
this.audio_url = bUrl+url
|
||||
this.generating=false
|
||||
}).catch(ex=>{
|
||||
this.$refs.toast.showToast(`Error: ${ex}`,4,false)
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit d52ca37fc1397766a5f0b186b5fc44eb807d9ef1
|
||||
Subproject commit 1020afe4b96cbdf3c8e6cd075c0be0d12290586b
|
@ -1 +1 @@
|
||||
Subproject commit a28e0559306b4af51d9c3369b5d1bb30365afd9b
|
||||
Subproject commit d4bb8f243945b8987d715868a2b81cebb75b553e
|
@ -1 +1 @@
|
||||
Subproject commit 1858bb6a1317cde54c683cac2e76853279b369bf
|
||||
Subproject commit 3b3a5d7f1bcdf0c987be9335dfb19c624907654a
|
Loading…
Reference in New Issue
Block a user