upgraded ui

This commit is contained in:
Saifeddine ALOUI 2023-07-15 02:12:43 +02:00
parent ee877a4b32
commit 2e431d2050
9 changed files with 156 additions and 62 deletions

18
app.py
View File

@ -880,9 +880,26 @@ class LoLLMsWebUI(LoLLMsAPPI):
print(f"Error occurred while parsing JSON: {e}") print(f"Error occurred while parsing JSON: {e}")
return jsonify({"status":False, 'error':str(e)}) return jsonify({"status":False, 'error':str(e)})
personality_path = lollms_paths.personalities_zoo_path / data['name']
ASCIIColors.info(f"- Reinstalling personality {data['name']}...") ASCIIColors.info(f"- Reinstalling personality {data['name']}...")
try: try:
ASCIIColors.info("Unmounting personality") ASCIIColors.info("Unmounting personality")
idx = self.config.personalities.index(data['name'])
print(f"index = {idx}")
self.mounted_personalities[idx] = None
gc.collect()
try:
self.mounted_personalities[idx] = AIPersonality(personality_path,
self.lollms_paths,
self.config,
model=self.model,
run_scripts=True,installation_option=InstallOption.FORCE_INSTALL)
return jsonify({"status":True})
except Exception as ex:
ASCIIColors.error(f"Personality file not found or is corrupted ({data['name']}).\nReturned the following exception:{ex}\nPlease verify that the personality you have selected exists or select another personality. Some updates may lead to change in personality name or category, so check the personality selection in settings to be sure.")
ASCIIColors.info("Trying to force reinstall")
return jsonify({"status":False, 'error':str(e)})
except Exception as e: except Exception as e:
return jsonify({"status":False, 'error':str(e)}) return jsonify({"status":False, 'error':str(e)})
@ -1159,6 +1176,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
def send_file(self): def send_file(self):
try: try:
ASCIIColors.info("Recovering file from front end")
file = request.files['file'] file = request.files['file']
file.save(self.lollms_paths.personal_uploads_path / file.filename) file.save(self.lollms_paths.personal_uploads_path / file.filename)
if self.personality.processor: if self.personality.processor:

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

8
web/dist/assets/index-bb3ba692.css vendored Normal file

File diff suppressed because one or more lines are too long

4
web/dist/index.html vendored
View File

@ -6,8 +6,8 @@
<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 - Welcome</title> <title>LoLLMS WebUI - Welcome</title>
<script type="module" crossorigin src="/assets/index-2d0d014f.js"></script> <script type="module" crossorigin src="/assets/index-0f224539.js"></script>
<link rel="stylesheet" href="/assets/index-0cf53f7d.css"> <link rel="stylesheet" href="/assets/index-bb3ba692.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@ -39,7 +39,7 @@
:key="'index-' + index + '-' + pers.name" :personality="pers" :full_path="pers.full_path" :key="'index-' + index + '-' + pers.name" :personality="pers" :full_path="pers.full_path"
:selected="configFile.personalities[configFile.active_personality_id] === pers.full_path" :selected="configFile.personalities[configFile.active_personality_id] === pers.full_path"
:on-selected="onPersonalitySelected" :on-mounted="onPersonalityMounted" :on-selected="onPersonalitySelected" :on-mounted="onPersonalityMounted"
:on-settings="onSettingsPersonality" /> :on-settings="onSettingsPersonality" :on-reinstall="onPersonalityReinstall"/>
</TransitionGroup> </TransitionGroup>
</div> </div>
</div> </div>
@ -173,6 +173,31 @@ export default {
personalityImgPlacehodler(event) { personalityImgPlacehodler(event) {
event.target.src = defaultPersonalityImgPlaceholder event.target.src = defaultPersonalityImgPlaceholder
}, },
onPersonalityReinstall(persItem){
console.log('on reinstall ', persItem)
this.isLoading = true
axios.post('/reinstall_personality', { name: persItem.personality.full_path }).then((res) => {
if (res) {
this.isLoading = false
console.log('reinstall_personality', res)
if (res.data.status) {
this.$refs.toast.showToast("Personality reinstalled successfully!", 4, true)
} else {
this.$refs.toast.showToast("Could not reinstall personality", 4, false)
}
return res.data;
}
this.isLoading = false
})
// eslint-disable-next-line no-unused-vars
.catch(error => {
this.isLoading = false
this.$refs.toast.showToast("Could not reinstall personality\n" + error.message, 4, false)
return { 'status': false }
});
},
onPersonalityMounted(persItem) { onPersonalityMounted(persItem) {
if (this.configFile.personalities.includes(persItem.full_path)) { if (this.configFile.personalities.includes(persItem.full_path)) {

View File

@ -1,19 +1,57 @@
<template> <template>
<div class="menu relative"> <div class="menu relative">
<div class="commands-menu-items-wrapper"> <div class="commands-menu-items-wrapper">
<button id="commands-menu" @click.prevent="toggleMenu" class="menu-button bg-blue-500 text-white dark:bg-blue-200 dark:text-gray-800 rounded-full flex items-center justify-center w-6 h-6 border-none cursor-pointer hover:bg-blue-400 w-8 h-8 rounded-full object-fill text-red-700 border-2 active:scale-90 hover:z-20 hover:-translate-y-2 duration-150 border-gray-300 border-secondary cursor-pointer"> <button
<i data-feather="command" class="w-5 h-5"></i> id="commands-menu"
@click.prevent="toggleMenu"
class="menu-button bg-blue-500 text-white dark:bg-blue-200 dark:text-gray-800 rounded-full flex items-center justify-center w-6 h-6 border-none cursor-pointer hover:bg-blue-400 w-8 h-8 rounded-full object-fill text-red-700 border-2 active:scale-90 hover:z-20 hover:-translate-y-2 duration-150 border-gray-300 border-secondary cursor-pointer"
>
<i data-feather="command" class="w-5 h-5"></i>
</button>
<div v-if="showMenu" id="commands-menu-items" class="absolute left-0 mt-4 bg-white border border-gray-300 z-10 w-48 overflow-y-auto custom-scrollbar" :style="{ top: '-200px', maxHeight: '200px' }">
<button
v-for="command in commands"
:key="command.value"
@click.prevent="execute_cmd(command)"
class="menu-button py-2 px-4 w-full text-left cursor-pointer bg-blue-500 text-white dark:bg-blue-200 dark:text-gray-800 hover:bg-blue-400"
:class="{ 'bg-blue-400 text-white': hoveredCommand === command.value }"
:title="command.help"
@mouseover="hoveredCommand = command.value"
@mouseout="hoveredCommand = null"
>
<div class="flex items-center">
<img v-if="command.icon" :src="command.icon" alt="Command Icon" class="w-4 h-4 mr-2" style="width: 25px; height: 25px;">
<div class="flex-grow">
{{ command.name }}
</div>
</div>
</button> </button>
<div v-if="showMenu" id="commands-menu-items" class="absolute mb-4 bg-white border border-gray-300 z-10 w-fit">
<button v-for="command in commands" :key="command.value" @click.prevent="execute_cmd(command)" class="menu-button py-2 px-4 cursor-pointer bg-blue-500 text-white dark:bg-blue-200 dark:text-gray-800 hover:bg-blue-400" :class="{ 'bg-blue-400 text-white': hoveredCommand === command.value }" :title="command.help" @mouseover="hoveredCommand = command.value" @mouseout="hoveredCommand = null">
{{ command.name }}
</button>
</div>
</div> </div>
</div> </div>
</div>
</template> </template>
<style scoped> <style scoped>
.custom-scrollbar::-webkit-scrollbar {
width: 8px;
}
.custom-scrollbar::-webkit-scrollbar-track {
background-color: #f1f1f1;
}
.custom-scrollbar::-webkit-scrollbar-thumb {
background-color: #888;
border-radius: 4px;
}
.custom-scrollbar::-webkit-scrollbar-thumb:hover {
background-color: #555;
}
.menu { .menu {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -45,6 +83,7 @@ props: {
}, },
data() { data() {
return { return {
selectedFile: null,
showMenu: false, showMenu: false,
showHelpText: false, showHelpText: false,
helpText: '', helpText: '',
@ -61,12 +100,13 @@ async mounted() {
}) })
}, },
methods: { methods: {
selectFile() { selectFile(next) {
const input = document.createElement('input'); const input = document.createElement('input');
input.type = 'file'; input.type = 'file';
input.accept = 'application/pdf'; // Specify the file type you want to accept input.accept = 'application/pdf'; // Specify the file type you want to accept
input.onchange = (e) => { input.onchange = (e) => {
this.selectedFile = e.target.files[0]; this.selectedFile = e.target.files[0];
next()
}; };
input.click(); input.click();
}, },
@ -96,8 +136,12 @@ methods: {
this.showMenu = !this.showMenu; this.showMenu = !this.showMenu;
if (cmd.hasOwnProperty('is_file')) { if (cmd.hasOwnProperty('is_file')) {
console.log("Need to send a file."); console.log("Need to send a file.");
this.selectFile() this.selectFile(()=>{
this.uploadFile() if(this.selectedFile!=null){
this.uploadFile()
}
});
} else { } else {
this.sendCommand(cmd); this.sendCommand(cmd);
} }

View File

@ -13,6 +13,12 @@
<h3 class="font-bold font-large text-lg line-clamp-3"> <h3 class="font-bold font-large text-lg line-clamp-3">
{{ personality.name }} {{ personality.name }}
</h3> </h3>
<button v-if="selected" type="button" title="Reload personality"
@click="toggleReloadBinding"
class="hover:text-secondary duration-75 active:scale-90 font-medium rounded-lg text-sm p-2 text-center inline-flex items-center " @click.stop="">
<i data-feather="refresh-cw" class="w-5"></i>
<span class="sr-only">Help</span>
</button>
</div> </div>
<div class="flex items-center flex-row-reverse gap-2 my-1"> <div class="flex items-center flex-row-reverse gap-2 my-1">
<!-- CONTROLS --> <!-- CONTROLS -->
@ -87,11 +93,11 @@ const bUrl = import.meta.env.VITE_GPT4ALL_API_BASEURL
export default { export default {
props: { props: {
personality: {}, personality: {},
onSelected: Function,
selected: Boolean, selected: Boolean,
full_path: String,
onSelected: Function,
onMounted: Function, onMounted: Function,
onReinstall: Function, onReinstall: Function,
full_path: String,
onSettings: Function onSettings: Function
}, },
data() { data() {

View File

@ -1025,7 +1025,7 @@
:key="'index-' + index + '-' + pers.name" :personality="pers" :key="'index-' + index + '-' + pers.name" :personality="pers"
:full_path="pers.full_path" :full_path="pers.full_path"
:selected="configFile.active_personality_id == configFile.personalities.findIndex(item => item === pers.full_path)" :selected="configFile.active_personality_id == configFile.personalities.findIndex(item => item === pers.full_path)"
:on-selected="onPersonalitySelected" :on-mounted="onPersonalityMounted" on-reinstall="onPersonalityReinstall" :on-selected="onPersonalitySelected" :on-mounted="onPersonalityMounted" :on-reinstall="onPersonalityReinstall"
:on-settings="onSettingsPersonality" /> :on-settings="onSettingsPersonality" />
</TransitionGroup> </TransitionGroup>
</div> </div>
@ -2530,15 +2530,15 @@ export default {
onPersonalityReinstall(persItem){ onPersonalityReinstall(persItem){
console.log('on reinstall ', persItem) console.log('on reinstall ', persItem)
this.isLoading = true this.isLoading = true
axios.post('/reinstall_binding', { name: binding_object.binding.folder }).then((res) => { axios.post('/reinstall_personality', { name: persItem.personality.path }).then((res) => {
if (res) { if (res) {
this.isLoading = false this.isLoading = false
console.log('reinstall_binding', res) console.log('reinstall_personality', res)
if (res.data.status) { if (res.data.status) {
this.$refs.toast.showToast("Reinstalled binding successfully!", 4, true) this.$refs.toast.showToast("Personality reinstalled successfully!", 4, true)
} else { } else {
this.$refs.toast.showToast("Could not reinstall binding", 4, false) this.$refs.toast.showToast("Could not reinstall personality", 4, false)
} }
return res.data; return res.data;
} }
@ -2548,7 +2548,7 @@ export default {
.catch(error => { .catch(error => {
this.isLoading = false this.isLoading = false
this.$refs.toast.showToast("Could not reinstall binding\n" + error.message, 4, false) this.$refs.toast.showToast("Could not reinstall personality\n" + error.message, 4, false)
return { 'status': false } return { 'status': false }
}); });
}, },