New version

This commit is contained in:
Saifeddine ALOUI 2023-11-22 20:35:48 +01:00
parent 210e851ceb
commit 5c6005507b
13 changed files with 133 additions and 57 deletions

View File

@ -1466,6 +1466,7 @@ class LoLLMsAPPI(LollmsApplication):
"metadata": metadata, "metadata": metadata,
"ui": ui, "ui": ui,
"id": msg.id, "id": msg.id,
"discussion_id": self.connections[client_id]["current_discussion"].id,
"parent_message_id": msg.parent_message_id, "parent_message_id": msg.parent_message_id,
'binding': self.config["binding_name"], 'binding': self.config["binding_name"],
@ -2841,14 +2842,11 @@ class LoLLMsAPPI(LollmsApplication):
extension = ExtensionBuilder().build_extension(extension_path,self.lollms_paths, self) extension = ExtensionBuilder().build_extension(extension_path,self.lollms_paths, self)
mounted_extensions.append(extension) mounted_extensions.append(extension)
except Exception as ex: except Exception as ex:
ASCIIColors.error(f"Personality file not found or is corrupted ({extension_path}).\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.error(f"Extension file not found or is corrupted ({extension_path}).\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.")
trace_exception(ex)
ASCIIColors.info("Trying to force reinstall") ASCIIColors.info("Trying to force reinstall")
if self.config["debug"]: if self.config["debug"]:
print(ex) print(ex)
if self.config["active_personality_id"]>=0 and self.config["active_personality_id"]<len(self.config["personalities"]):
ASCIIColors.success(f'selected model : {self.config["personalities"][self.config["active_personality_id"]]}')
else:
ASCIIColors.warning('An error was encountered while trying to mount personality')
ASCIIColors.success(f" ╔══════════════════════════════════════════════════╗ ") ASCIIColors.success(f" ╔══════════════════════════════════════════════════╗ ")
ASCIIColors.success(f" ║ Done ║ ") ASCIIColors.success(f" ║ Done ║ ")
ASCIIColors.success(f" ╚══════════════════════════════════════════════════╝ ") ASCIIColors.success(f" ╚══════════════════════════════════════════════════╝ ")
@ -2859,11 +2857,9 @@ class LoLLMsAPPI(LollmsApplication):
for index in to_remove: for index in to_remove:
if 0 <= index < len(mounted_extensions): if 0 <= index < len(mounted_extensions):
mounted_extensions.pop(index) mounted_extensions.pop(index)
self.config["personalities"].pop(index) self.config["extensions"].pop(index)
ASCIIColors.info(f"removed personality {extension_path}") ASCIIColors.info(f"removed personality {extension_path}")
if self.config["active_personality_id"]>=len(self.config["personalities"]):
self.config["active_personality_id"]=0
return mounted_extensions return mounted_extensions
# ================================== LOLLMSApp # ================================== LOLLMSApp

40
app.py
View File

@ -64,6 +64,8 @@ try:
from lollms.personality import AIPersonality from lollms.personality import AIPersonality
from lollms.config import BaseConfig from lollms.config import BaseConfig
from lollms.paths import LollmsPaths, gptqlora_repo from lollms.paths import LollmsPaths, gptqlora_repo
from lollms.extension import LOLLMSExtension, ExtensionBuilder
from api.db import Discussion from api.db import Discussion
from flask import ( from flask import (
@ -253,6 +255,7 @@ try:
self.add_endpoint("/unInstall_binding", "unInstall_binding", self.unInstall_binding, methods=["POST"]) self.add_endpoint("/unInstall_binding", "unInstall_binding", self.unInstall_binding, methods=["POST"])
self.add_endpoint("/reinstall_binding", "reinstall_binding", self.reinstall_binding, methods=["POST"]) self.add_endpoint("/reinstall_binding", "reinstall_binding", self.reinstall_binding, methods=["POST"])
self.add_endpoint("/reinstall_personality", "reinstall_personality", self.reinstall_personality, methods=["POST"]) self.add_endpoint("/reinstall_personality", "reinstall_personality", self.reinstall_personality, methods=["POST"])
self.add_endpoint("/reinstall_extension", "reinstall_extension", self.reinstall_extension, methods=["POST"])
self.add_endpoint("/switch_personal_path", "switch_personal_path", self.switch_personal_path, methods=["POST"]) self.add_endpoint("/switch_personal_path", "switch_personal_path", self.switch_personal_path, methods=["POST"])
@ -1500,6 +1503,41 @@ try:
"status": True "status": True
}) })
def reinstall_extension(self):
try:
data = request.get_json()
# Further processing of the data
except Exception as e:
print(f"Error occurred while parsing JSON: {e}")
return jsonify({"status":False, 'error':str(e)})
if not 'name' in data.keys():
try:
data['name']=self.config.extensions[-1]
except Exception as ex:
self.notify(ex,False)
return
try:
extension_path = self.lollms_paths.extensions_zoo_path / data['name']
ASCIIColors.info(f"- Reinstalling extension {data['name']}...")
ASCIIColors.info("Unmounting extension")
if data['name'] in self.config.extensions:
idx = self.config.extensions.index(data['name'])
print(f"index = {idx}")
if len(self.mount_extensions)>idx:
del self.mounted_extensions[idx]
gc.collect()
try:
self.mounted_extensions.append(ExtensionBuilder().build_extension(extension_path,self.lollms_paths, self, InstallOption.FORCE_INSTALL))
return jsonify({"status":True})
except Exception as ex:
ASCIIColors.error(f"Extension 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.")
trace_exception(ex)
ASCIIColors.info("Trying to force reinstall")
return jsonify({"status":False, 'error':str(e)})
except Exception as e:
return jsonify({"status":False, 'error':str(e)})
def reinstall_personality(self): def reinstall_personality(self):
try: try:
data = request.get_json() data = request.get_json()
@ -1510,7 +1548,7 @@ try:
if not 'name' in data: if not 'name' in data:
data['name']=self.config.personalities[self.config["active_personality_id"]] data['name']=self.config.personalities[self.config["active_personality_id"]]
try: try:
personality_path = lollms_paths.personalities_zoo_path / data['name'] personality_path = self.lollms_paths.personalities_zoo_path / data['name']
ASCIIColors.info(f"- Reinstalling personality {data['name']}...") ASCIIColors.info(f"- Reinstalling personality {data['name']}...")
ASCIIColors.info("Unmounting personality") ASCIIColors.info("Unmounting personality")
idx = self.config.personalities.index(data['name']) idx = self.config.personalities.index(data['name'])

@ -1 +1 @@
Subproject commit 3a3dab0a6c50532f24b1421111d4484df7fac661 Subproject commit 8b7690d0d73015a8054cb077cdc9dbe81ab6dd16

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
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-38b7eb57.js"></script> <script type="module" crossorigin src="/assets/index-8d00ac76.js"></script>
<link rel="stylesheet" href="/assets/index-b4658214.css"> <link rel="stylesheet" href="/assets/index-c14230cd.css">
</head> </head>
<body> <body>
<div id="app"></div> <div id="app"></div>

View File

@ -144,7 +144,7 @@
</div> </div>
</div> </div>
<MarkdownRenderer ref="mdRender" v-if="!editMsgMode" :host="host" :markdown-text="message.content" :message_id="message.id"> <MarkdownRenderer ref="mdRender" v-if="!editMsgMode" :host="host" :markdown-text="message.content" :message_id="message.id" :discussion_id="message.discussion_id">
</MarkdownRenderer> </MarkdownRenderer>
<div > <div >
<textarea v-if="message.open" ref="mdTextarea" @keydown.tab.prevent="insertTab" <textarea v-if="message.open" ref="mdTextarea" @keydown.tab.prevent="insertTab"

View File

@ -427,7 +427,8 @@ export default {
isDragOverDiscussion: false, isDragOverDiscussion: false,
isDragOverChat: false, isDragOverChat: false,
panelCollapsed: false, // left panel collapse panelCollapsed: false, // left panel collapse
isOpen: false isOpen: false,
discussion_id: 0,
} }
}, },
methods: { methods: {
@ -1037,6 +1038,7 @@ export default {
sender_type: msgObj.sender_type, sender_type: msgObj.sender_type,
content: msgObj.content,//" please stand by ...", content: msgObj.content,//" please stand by ...",
id: msgObj.id, id: msgObj.id,
discussion_id: msgObj.discussion_id,
parent_id: msgObj.parent_id, parent_id: msgObj.parent_id,
binding: msgObj.binding, binding: msgObj.binding,
@ -1142,6 +1144,7 @@ export default {
sender_type: this.senderTypes.SENDER_TYPES_USER, sender_type: this.senderTypes.SENDER_TYPES_USER,
content: msg, content: msg,
id: lastmsgid, id: lastmsgid,
discussion_id: this.discussion_id,
parent_id: lastmsgid, parent_id: lastmsgid,
binding: "", binding: "",
@ -1170,6 +1173,7 @@ export default {
}); });
}, },
sendCmd(cmd){ sendCmd(cmd){
this.isGenerating = true;
socket.emit('execute_command', { command: cmd, parameters: [] }); socket.emit('execute_command', { command: cmd, parameters: [] });
}, },
notify(notif){ notify(notif){
@ -1184,9 +1188,9 @@ export default {
}, },
streamMessageContent(msgObj) { streamMessageContent(msgObj) {
// Streams response message content from binding // Streams response message content from binding
const discussion_id = msgObj.discussion_id this.discussion_id = msgObj.discussion_id
this.setDiscussionLoading(discussion_id, true); this.setDiscussionLoading(this.discussion_id, true);
if (this.currentDiscussion.id == discussion_id) { if (this.currentDiscussion.id == this.discussion_id) {
//this.isGenerating = true; //this.isGenerating = true;
const index = this.discussionArr.findIndex((x) => x.id == msgObj.id) const index = this.discussionArr.findIndex((x) => x.id == msgObj.id)
const messageItem = this.discussionArr[index] const messageItem = this.discussionArr[index]
@ -1496,8 +1500,8 @@ export default {
// Last message contains halucination suppression so we need to update the message content too // Last message contains halucination suppression so we need to update the message content too
const parent_id = msgObj.parent_id const parent_id = msgObj.parent_id
const discussion_id = msgObj.discussion_id this.discussion_id = msgObj.discussion_id
if (this.currentDiscussion.id == discussion_id) { if (this.currentDiscussion.id == this.discussion_id) {
const index = this.discussionArr.findIndex((x) => x.id == msgObj.id) const index = this.discussionArr.findIndex((x) => x.id == msgObj.id)
this.discussionArr[index].content = msgObj.content this.discussionArr[index].content = msgObj.content
this.discussionArr[index].finished_generating_at = msgObj.finished_generating_at this.discussionArr[index].finished_generating_at = msgObj.finished_generating_at

View File

@ -1378,9 +1378,9 @@
</div> </div>
<input type="search" id="personality-search" <input type="search" id="personality-search"
class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 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" class="block w-full p-4 pl-10 text-sm text-gray-900 border border-gray-300 rounded-lg bg-gray-50 focus:ring-blue-500 focus:border-blue-500 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"
placeholder="Search personality..." required v-model="searchPersonality" placeholder="Search extension..." required v-model="searchExtension"
@keyup.stop="searchPersonality_func"> @keyup.stop="searchExtension_func">
<button v-if="searchPersonality" @click.stop="searchPersonality = ''" type="button" <button v-if="searchExtension" @click.stop="searchExtension = ''" type="button"
class="text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"> class="text-white absolute right-2.5 bottom-2.5 bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-4 py-2 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
Clear search</button> Clear search</button>
@ -1389,7 +1389,7 @@
</div> </div>
</div> </div>
<div class="mx-2 mb-4" v-if="!searchPersonality"> <div class="mx-2 mb-4" v-if="!searchExtension">
<label for="persCat" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white"> <label for="persCat" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Extensions Category: ({{ extCatgArr.length }}) Extensions Category: ({{ extCatgArr.length }})
</label> </label>
@ -1408,7 +1408,7 @@
<div> <div>
<div v-if="extensionsFiltererd.length > 0" class="mb-2"> <div v-if="extensionsFiltererd.length > 0" class="mb-2">
<label for="model" class="block ml-2 mb-2 text-sm font-medium text-gray-900 dark:text-white"> <label for="model" class="block ml-2 mb-2 text-sm font-medium text-gray-900 dark:text-white">
{{ searchPersonality ? 'Search results' : 'Personalities' }}: ({{ {{ searchExtension ? 'Search results' : 'Personalities' }}: ({{
extensionsFiltererd.length extensionsFiltererd.length
}}) }})
</label> </label>
@ -2048,6 +2048,9 @@ export default {
while (this.isReady === false) { while (this.isReady === false) {
await new Promise((resolve) => setTimeout(resolve, 100)); // Wait for 100ms await new Promise((resolve) => setTimeout(resolve, 100)); // Wait for 100ms
} }
this.refresh();
console.log("Ready") console.log("Ready")
if (this.configFile.model_name) { if (this.configFile.model_name) {
this.isModelSelected = true this.isModelSelected = true
@ -2066,7 +2069,9 @@ export default {
this.extCatgArr = [] this.extCatgArr = []
} }
try{ try{
console.log("Loading extension category content")
this.extArr = await this.api_get_req("list_extensions?category="+this.extension_category) this.extArr = await this.api_get_req("list_extensions?category="+this.extension_category)
console.log(this.extArr)
} }
catch{ catch{
console.log("Couldn't list extensions") console.log("Couldn't list extensions")
@ -2307,7 +2312,6 @@ export default {
} }
nextTick(() => { nextTick(() => {
feather.replace() feather.replace()
@ -3493,26 +3497,26 @@ export default {
this.isLoading = true this.isLoading = true
if (!ext) { return } if (!ext) { return }
const res = await this.unmount_personality(ext.personality || ext) const res = await this.p_unmount_extension(ext.extension || ext)
if (res.status) { if (res.status) {
this.configFile.personalities = res.personalities this.configFile.extensions = res.extensions
this.$refs.toast.showToast("Extension unmounted", 4, true) this.$refs.toast.showToast("Extension unmounted", 4, true)
const persId = this.personalities.findIndex(item => item.full_path == ext.full_path) const extId = this.extensions.findIndex(item => item.full_path == ext.full_path)
const persFilteredId = this.personalitiesFiltered.findIndex(item => item.full_path == ext.full_path) const persFilteredId = this.extensionsFiltered.findIndex(item => item.full_path == ext.full_path)
const persIdZoo = this.$refs.personalitiesZoo.findIndex(item => item.full_path == ext.full_path) const extIdZoo = this.$refs.extensionsZoo.findIndex(item => item.full_path == ext.full_path)
console.log('ppp', this.personalities[persId]) console.log('ext', this.extensions[extId])
this.personalities[persId].isMounted = false this.extensions[extId].isMounted = false
if (persFilteredId > -1) { if (persFilteredId > -1) {
this.personalitiesFiltered[persFilteredId].isMounted = false this.extensionsFiltered[persFilteredId].isMounted = false
} }
if (persIdZoo > -1) { if (extIdZoo > -1) {
this.$refs.personalitiesZoo[persIdZoo].isMounted = false this.$refs.extensionsZoo[extIdZoo].isMounted = false
} }
@ -3520,9 +3524,9 @@ export default {
//ext.isMounted = false //ext.isMounted = false
this.$store.dispatch('refreshMountedPersonalities'); this.$store.dispatch('refreshMountedPersonalities');
// Select some other personality // Select some other personality
const lastPers = this.mountedPersArr[this.mountedPersArr.length - 1] const lastPers = this.mountedExtensions[this.mountedExtensions.length - 1]
console.log(lastPers, this.mountedPersArr.length) console.log(lastPers, this.mountedExtensions.length)
} else { } else {
@ -3535,6 +3539,32 @@ export default {
await this.unmountExtension(ext); await this.unmountExtension(ext);
await this.mountExtension(ext); await this.mountExtension(ext);
}, },
onExtensionReinstall(extItem){
console.log('on reinstall ', extItem)
this.isLoading = true
console.log(extItem)
axios.post('/reinstall_extension', { name: extItem.extension.full_path }).then((res) => {
if (res) {
this.isLoading = false
console.log('reinstall_extension', res)
if (res.data.status) {
this.$refs.toast.showToast("Extension reinstalled successfully!", 4, true)
} else {
this.$refs.toast.showToast("Could not reinstall extension", 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 }
});
},
onPersonalityReinstall(persItem){ onPersonalityReinstall(persItem){
console.log('on reinstall ', persItem) console.log('on reinstall ', persItem)
@ -3775,6 +3805,7 @@ export default {
}, },
mountedExtensions:{ mountedExtensions:{
get() { get() {
console.log("this.$store.state.mountedExtensions:",this.$store.state.mountedExtensions)
return this.$store.state.mountedExtensions; return this.$store.state.mountedExtensions;
}, },
set(value) { set(value) {

View File

@ -24,9 +24,15 @@ export default async ({ mode }) => {
return process.env.VITE_LOLLMS_API return process.env.VITE_LOLLMS_API
} }
} }
let serverURL = undefined;
const serverURL = await getFlaskServerURL() try{
serverURL = await getFlaskServerURL()
console.log(serverURL) console.log(serverURL)
}catch{
serverURL = process.env.VITE_LOLLMS_API
console.log(`Server address: ${serverAddress}`)
}
// Load app-level env vars to node-level env vars. // Load app-level env vars to node-level env vars.
process.env = {...process.env, ...loadEnv(mode, process.cwd())}; process.env = {...process.env, ...loadEnv(mode, process.cwd())};

@ -1 +1 @@
Subproject commit 76d971abf330ceff8603386d9f7fd55cf8e3c0b4 Subproject commit 23e4c917ec9d3d315aa8b15eb05c761febe8df12

@ -1 +1 @@
Subproject commit 961ff4bad2a1e60f3b9013d737cb516381258d1b Subproject commit 051539ba6bd5b6c853cae2edb1bc40ebb272523a

@ -1 +1 @@
Subproject commit 1ed229af3443fc9d8bc9a19c1ae33e32cb67aa50 Subproject commit 477129191bf97222a10eedb46723a8f22a2d2ab0