moved to v 6.8 with discussion naming and other bunch of stuff

This commit is contained in:
Saifeddine ALOUI 2023-11-04 23:48:02 +01:00
parent 40fd42dace
commit 7604b06597
16 changed files with 335 additions and 154 deletions

View File

@ -885,6 +885,18 @@ class LoLLMsAPPI(LollmsApplication):
# Start the text generation task in a separate thread
task = self.socketio.start_background_task(target=generate_text)
@socketio.on('execute_command')
def execute_command(data):
client_id = request.sid
command = data["command"]
parameters = data["parameters"]
if self.personality.processor is not None:
self.start_time = datetime.now()
self.personality.processor.callback = partial(self.process_chunk, client_id=client_id)
self.personality.processor.execute_command(command, parameters)
else:
self.notify("Non scripted personalities do not support commands",False,client_id)
@socketio.on('generate_msg')
def generate_msg(data):
client_id = request.sid
@ -1194,6 +1206,64 @@ class LoLLMsAPPI(LollmsApplication):
cleaned_string = re.sub(pattern, '', cleaned_string)
return cleaned_string
def make_discussion_title(self, discussion, client_id=None):
"""
Builds a title for a discussion
"""
# Get the list of messages
messages = discussion.get_messages()
discussion_messages = "!@>instruction: Create a short title to this discussion\n"
discussion_title = "\n!@>Discussion title:"
available_space = self.config.ctx_size - 150 - len(self.model.tokenize(discussion_messages))- len(self.model.tokenize(discussion_title))
# Initialize a list to store the full messages
full_message_list = []
# Accumulate messages until the cumulative number of tokens exceeds available_space
tokens_accumulated = 0
# Accumulate messages starting from message_index
for message in messages:
# Check if the message content is not empty and visible to the AI
if message.content != '' and (
message.message_type <= MSG_TYPE.MSG_TYPE_FULL_INVISIBLE_TO_USER.value and message.message_type != MSG_TYPE.MSG_TYPE_FULL_INVISIBLE_TO_AI.value):
# Tokenize the message content
message_tokenized = self.model.tokenize(
"\n" + self.config.discussion_prompt_separator + message.sender + ": " + message.content.strip())
# Check if adding the message will exceed the available space
if tokens_accumulated + len(message_tokenized) > available_space:
break
# Add the tokenized message to the full_message_list
full_message_list.insert(0, message_tokenized)
# Update the cumulative number of tokens
tokens_accumulated += len(message_tokenized)
# Build the final discussion messages by detokenizing the full_message_list
for message_tokens in full_message_list:
discussion_messages += self.model.detokenize(message_tokens)
discussion_messages += discussion_title
title = [""]
def receive(
chunk:str,
message_type:MSG_TYPE
):
title[0] += chunk
antiprompt = self.personality.detect_antiprompt(title[0])
if antiprompt:
ASCIIColors.warning(f"\nDetected hallucination with antiprompt: {antiprompt}")
title[0] = self.remove_text_from_string(title[0],antiprompt)
return False
else:
return True
self._generate(discussion_messages, 150, client_id, receive)
ASCIIColors.info(title[0])
return title[0]
def prepare_query(self, client_id: str, message_id: int = -1, is_continue: bool = False, n_tokens: int = 0) -> Tuple[str, str, List[str]]:
"""

14
app.py
View File

@ -14,7 +14,7 @@ __github__ = "https://github.com/ParisNeo/lollms-webui"
__copyright__ = "Copyright 2023, "
__license__ = "Apache 2.0"
__version__ ="6.7"
__version__ ="6.8"
main_repo = "https://github.com/ParisNeo/lollms-webui.git"
import os
@ -362,6 +362,8 @@ class LoLLMsWebUI(LoLLMsAPPI):
self.add_endpoint("/rename", "rename", self.rename, methods=["POST"])
self.add_endpoint("/edit_title", "edit_title", self.edit_title, methods=["POST"])
self.add_endpoint("/make_title", "make_title", self.make_title, methods=["POST"])
self.add_endpoint(
"/delete_discussion",
@ -2234,6 +2236,16 @@ class LoLLMsWebUI(LoLLMsAPPI):
self.connections[client_id]["current_discussion"].rename(title)
return jsonify({'status':True})
def make_title(self):
ASCIIColors.info("Making title")
data = request.get_json()
discussion_id = data["id"]
discussion = Discussion(discussion_id, self.db)
title = self.make_discussion_title(discussion)
discussion.rename(title)
return jsonify({'status':True, 'title':title})
def delete_discussion(self):
data = request.get_json()
client_id = data["client_id"]

@ -1 +1 @@
Subproject commit 4ac0f7e3a20c98c88a42905295ad4078a84d9371
Subproject commit e3b3863df57085a3c94b43a68e798948a141d948

View File

@ -1,4 +1,16 @@
#!/bin/bash
echo " ___ ___ ___ ___ ___ ___ "
echo " /\__\ /\ \ /\__\ /\__\ /\__\ /\ \ "
echo " /:/ / /::\ \ /:/ / /:/ / /::| | /::\ \ "
echo " /:/ / /:/\:\ \ /:/ / /:/ / /:|:| | /:/\ \ \ "
echo " /:/ / /:/ \:\ \ /:/ / /:/ / /:/|:|__|__ _\:\~\ \ \ "
echo " /:/__/ /:/__/ \:\__\ /:/__/ /:/__/ /:/ |::::\__\ /\ \:\ \ \__\ "
echo " \:\ \ \:\ \ /:/ / \:\ \ \:\ \ \/__/~~/:/ / \:\ \:\ \/__/ "
echo " \:\ \ \:\ /:/ / \:\ \ \:\ \ /:/ / \:\ \:\__\ "
echo " \:\ \ \:\/:/ / \:\ \ \:\ \ /:/ / \:\/:/ / "
echo " \:\__\ \::/ / \:\__\ \:\__\ /:/ / \::/ / "
echo " \/__/ \/__/ \/__/ \/__/ \/__/ \/__/ "
echo " By ParisNeo"
# Update and upgrade packages
sudo apt update
@ -59,13 +71,39 @@ else
# CPU installation
echo "Using CPU for installation..."
fi
# Initilize all submodules and set them to main branch
echo "Initializing submodules"
git submodule update --init
cd zoos/bindings_zoo
git checkout main
cd ../personalities_zoo
git checkout main
cd ../extensions_zoo
git checkout main
cd ../models_zoo
git checkout main
cd ../..
cd lollms_core
git checkout main
cd ../utilities/safe_store
git checkout main
cd ../..
# Install requirements
pip install -r requirements.txt
python -m pip install -e lollms_core --upgrade
python -m pip install -e utilities/safe_store --upgrade
# by default ubuntu will start in lollms-webui path
echo 'cd ~/lollms-webui' >> ~/.bashrc
# Add automatic conda activate
echo 'conda activate ./env' >> ~/.bashrc
# Exit WSL
exit

View File

@ -2,7 +2,7 @@
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
#define MyAppName "lollms-with-petals"
#define MyAppVersion "6.5"
#define MyAppVersion "6.8"
#define MyAppPublisher "ParisNeo"
#define MyAppURL "https://www.lollms.com/"
#define MyAppExeName "lollms_petals_runner.bat"

View File

@ -38,7 +38,7 @@ def install_requirements():
try:
subprocess.check_call(["pip", "install", "--upgrade", "-r", "requirements.txt"])
subprocess.check_call(["pip", "install", "--upgrade", "-e", "lollms_core"])
subprocess.check_call(["pip", "install", "--upgrade", "-r", "utilities/safe_store"])
subprocess.check_call(["pip", "install", "--upgrade", "-e", "utilities/safe_store"])
except subprocess.CalledProcessError as e:
print(f"Error during pip install: {e}")

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-f06a4c0c.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">
<title>LoLLMS WebUI - Welcome</title>
<script type="module" crossorigin src="/assets/index-ddd279d2.js"></script>
<link rel="stylesheet" href="/assets/index-575b8ec5.css">
<script type="module" crossorigin src="/assets/index-5d95834b.js"></script>
<link rel="stylesheet" href="/assets/index-f06a4c0c.css">
</head>
<body>
<div id="app"></div>

View File

@ -203,7 +203,7 @@
<PersonalitiesCommands
v-if="personalities_ready && this.$store.state.mountedPersArr[this.$store.state.config.active_personality_id].commands!=''"
:commandsList="this.$store.state.mountedPersArr[this.$store.state.config.active_personality_id].commands"
:sendCommand="sendMessageEvent"
:sendCommand="sendCMDEvent"
:on-show-toast-message="onShowToastMessage"
ref="personalityCMD"
></PersonalitiesCommands>
@ -326,7 +326,7 @@ console.log("modelImgPlaceholder:",modelImgPlaceholder)
const bUrl = import.meta.env.VITE_LOLLMS_API_BASEURL
export default {
name: 'ChatBox',
emits: ["messageSentEvent", "stopGenerating", "loaded", "createEmptyUserMessage", "createEmptyAIMessage"],
emits: ["messageSentEvent", "sendCMDEvent", "stopGenerating", "loaded", "createEmptyUserMessage", "createEmptyAIMessage"],
props: {
onTalk: Function,
discussionList: Array,
@ -726,6 +726,9 @@ export default {
this.$emit('messageSentEvent', msg)
},
sendCMDEvent(cmd){
this.$emit('sendCMDEvent', cmd)
},
submitOnEnter(event) {
if (event.which === 13) {
event.preventDefault(); // Prevents the addition of a new line in the text field

View File

@ -30,38 +30,30 @@
<!-- CONTROL BUTTONS -->
<div class="flex items-center flex-1 max-h-6">
<!-- DELETE CONFIRM -->
<div v-if="showConfirmation && !editTitleMode" class="flex gap-3 flex-1 items-center justify-end duration-75">
<button class="text-2xl hover:text-secondary duration-75 active:scale-90" title="Confirm removal"
type="button" @click.stop="deleteEvent()">
<i data-feather="check"></i>
</button>
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 " title="Cancel removal"
type="button" @click.stop="showConfirmation = false">
<i data-feather="x"></i>
</button>
</div>
<!-- EDIT TITLE CONFIRM -->
<div v-if="showConfirmation && editTitleMode" class="flex gap-3 flex-1 items-center justify-end duration-75">
<div v-if="showConfirmation" class="flex gap-3 flex-1 items-center justify-end duration-75">
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 " title="Discard title changes"
type="button" @click.stop="editTitleMode = false">
type="button" @click.stop="cancel()">
<i data-feather="x"></i>
</button>
<button class="text-2xl hover:text-secondary duration-75 active:scale-90" title="Confirm title changes"
type="button" @click.stop="editTitleEvent()">
type="button" @click.stop="editTitleMode?editTitleEvent():deleteMode?deleteEvent():makeTitleEvent()">
<i data-feather="check"></i>
</button>
</div>
<!-- EDIT AND REMOVE -->
<div v-if="!showConfirmation"
class="flex gap-3 flex-1 items-center justify-end invisible group-hover:visible duration-75">
<button class="text-2xl hover:text-secondary duration-75 active:scale-90" title="Make a title" type="button"
@click.stop="makeTitleMode = true">
<i data-feather="type"></i>
</button>
<button class="text-2xl hover:text-secondary duration-75 active:scale-90" title="Edit title" type="button"
@click.stop="editTitleMode = true">
<i data-feather="edit-2"></i>
</button>
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 " title="Remove discussion"
type="button" @click.stop="showConfirmation = true">
<button class="text-2xl hover:text-red-600 duration-75 active:scale-90 " title="Remove discussion" type="button"
@click.stop="deleteMode = true">
<i data-feather="trash"></i>
</button>
</div>
@ -76,7 +68,7 @@ import feather from 'feather-icons'
export default {
name: 'Discussion',
emits: ['delete', 'select', 'editTitle', 'checked'],
emits: ['delete', 'select', 'editTitle', 'makeTitle', 'checked'],
props: {
id: Number,
title: String,
@ -92,12 +84,20 @@ export default {
return {
showConfirmation: false,
editTitleMode: false,
makeTitleMode: false,
deleteMode:false,
editTitle: false,
newTitle: String,
checkBoxValue_local: false
}
},
methods: {
cancel(){
this.editTitleMode = false
this.makeTitleMode = false
this.deleteMode = false
this.showConfirmation = false
},
deleteEvent() {
this.showConfirmation = false
this.$emit("delete")
@ -108,6 +108,8 @@ export default {
editTitleEvent() {
this.editTitle = false
this.editTitleMode = false
this.makeTitleMode = false
this.deleteMode = false
this.showConfirmation = false
this.$emit("editTitle",
{
@ -115,6 +117,13 @@ export default {
id: this.id
})
},
makeTitleEvent(){
this.$emit("makeTitle",
{
id: this.id
})
this.showConfirmation = false
},
chnageTitle(text) {
this.newTitle = text
},
@ -140,6 +149,19 @@ export default {
this.showConfirmation = newval
this.editTitle = newval
if (newval) {
nextTick(() => {
try{
this.$refs.titleBox.focus()
}catch{}
})
}
},
deleteMode(newval) {
this.showConfirmation = newval
if (newval) {
@ -150,6 +172,11 @@ export default {
}
},
makeTitleMode(newval) {
this.showConfirmation = newval
},
checkBoxValue(newval, oldval) {
this.checkBoxValue_local = newval

View File

@ -86,6 +86,14 @@ export default {
return this.$store.state.isConnected;
}
},
watch:{
isConnected(){
nextTick(() => {
feather.replace()
})
}
},
data() {
return {
codeBlockStylesheet:'',
@ -104,7 +112,6 @@ export default {
nextTick(() => {
feather.replace()
})

View File

@ -187,10 +187,6 @@
</div>
</div>
<div class="z-5">
<DragDrop ref="dragdropDiscussion" @panelDrop="setFileListDiscussion">Drop your discussion file here
</DragDrop>
</div>
<div class="relative flex flex-row flex-grow mb-10 z-0">
<!-- DISCUSSION LIST -->
@ -202,8 +198,11 @@
<TransitionGroup v-if="list.length > 0" name="list">
<Discussion v-for="(item, index) in list" :key="item.id" :id="item.id" :title="item.title"
:selected="currentDiscussion.id == item.id" :loading="item.loading" :isCheckbox="isCheckbox"
:checkBoxValue="item.checkBoxValue" @select="selectDiscussion(item)"
@delete="deleteDiscussion(item.id)" @editTitle="editTitle"
:checkBoxValue="item.checkBoxValue"
@select="selectDiscussion(item)"
@delete="deleteDiscussion(item.id)"
@editTitle="editTitle"
@makeTitle="makeTitle"
@checked="checkUncheckDiscussion" />
</TransitionGroup>
<div v-if="list.length < 1"
@ -223,11 +222,7 @@
</div>
</div>
</transition>
<div v-if="isReady" class="relative flex flex-col flex-grow " @dragover.stop.prevent="setDropZoneChat()">
<div class="z-20 h-max">
<DragDrop ref="dragdropChat" @panelDrop="setFileListChat"></DragDrop>
</div>
<div v-if="isReady" class="relative flex flex-col flex-grow " >
<div id="messages-list"
class=" z-0 flex flex-col flex-grow 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"
:class="isDragOverChat ? 'pointer-events-none' : ''">
@ -256,6 +251,7 @@
<div class=" bottom-0 container flex flex-row items-center justify-center " v-if="currentDiscussion.id">
<ChatBox ref="chatBox"
@messageSentEvent="sendMsg"
@sendCMDEvent="sendCmd"
@createEmptyUserMessage="createEmptyUserMessage"
@createEmptyAIMessage="createEmptyAIMessage"
:loading="isGenerating"
@ -271,7 +267,6 @@
</div>
</div>
<Toast ref="toast">
</Toast>
<MessageBox ref="messageBox" />
@ -658,6 +653,33 @@ export default {
this.setDiscussionLoading(id, this.loading)
}
},
async make_title(id) {
try {
if (id) {
this.loading = true
this.setDiscussionLoading(id, this.loading)
const res = await axios.post('/make_title', {
client_id: this.client_id,
id: id,
})
console.log("Making title:",res)
this.loading = false
this.setDiscussionLoading(id, this.loading)
if (res.status == 200) {
const index = this.list.findIndex((x) => x.id == id)
const discussionItem = this.list[index]
discussionItem.title = res.data.title
this.tempList = this.list
}
}
} catch (error) {
console.log("Error: Could not edit title", error.message)
this.loading = false
this.setDiscussionLoading(id, this.loading)
}
},
async delete_message(id) {
try {
const res = await axios.get('/delete_message', { params: { client_id: this.client_id, id: id } })
@ -1091,6 +1113,9 @@ export default {
console.log("Error: Could not get generation status", error);
});
},
sendCmd(cmd){
socket.emit('execute_command', { command: cmd, parameters: [] });
},
notify(notif){
self.isGenerating = false
this.setDiscussionLoading(this.currentDiscussion.id, this.isGenerating);
@ -1103,13 +1128,14 @@ export default {
},
streamMessageContent(msgObj) {
// Streams response message content from binding
//console.log("Received message",msgObj)
console.log("Received message",msgObj)
const discussion_id = msgObj.discussion_id
this.setDiscussionLoading(discussion_id, true);
if (this.currentDiscussion.id == discussion_id) {
this.isGenerating = true;
//this.isGenerating = true;
const index = this.discussionArr.findIndex((x) => x.id == msgObj.id)
const messageItem = this.discussionArr[index]
if (
messageItem && (msgObj.message_type==this.msgTypes.MSG_TYPE_FULL ||
msgObj.message_type==this.msgTypes.MSG_TYPE_FULL_INVISIBLE_TO_AI)
@ -1253,6 +1279,11 @@ export default {
await this.edit_title(newTitleObj.id, newTitleObj.title)
discussionItem.loading = false
},
async makeTitle(editTitleObj) {
const index = this.list.findIndex((x) => x.id == editTitleObj.id)
await this.make_title(editTitleObj.id)
},
checkUncheckDiscussion(event, id) {
// If checked = true and item is not in array then add item to list
const index = this.list.findIndex((x) => x.id == id)
@ -1607,12 +1638,6 @@ export default {
this.isDragOverChat = false
},
setDropZoneChat() {
this.isDragOverChat = true
this.$refs.dragdropChat.show = true
},
async setFileListDiscussion(files) {
@ -1633,15 +1658,6 @@ export default {
this.isDragOverDiscussion = false
},
setDropZoneDiscussion() {
this.isDragOverDiscussion = true
this.$refs.dragdropDiscussion.show = true
},
},
async created() {
this.$nextTick(() => {
@ -1652,6 +1668,16 @@ export default {
console.log('WebSocket connection closed:', event.code, event.reason);
this.socketIODisconnected();
};
socket.on("connect_error", (error) => {
if (error.message === "ERR_CONNECTION_REFUSED") {
this.$store.state.isConnected = false
console.error("Connection refused. The server is not available.");
// Handle the ERR_CONNECTION_REFUSED error here
} else {
console.error("Connection error:", error);
// Handle other connection errors here
}
});
socket.onerror = (event) => {
console.log('WebSocket connection error:', event.code, event.reason);
this.socketIODisconnected();
@ -1728,7 +1754,6 @@ export default {
ChatBox,
WelcomeComponent,
Toast,
DragDrop,
ChoiceDialog
},
watch: {
@ -1820,7 +1845,6 @@ import ChatBox from '../components/ChatBox.vue'
import WelcomeComponent from '../components/WelcomeComponent.vue'
import Toast from '../components/Toast.vue'
import MessageBox from "@/components/MessageBox.vue";
import DragDrop from '../components/DragDrop.vue'
import feather from 'feather-icons'
import axios from 'axios'

@ -1 +1 @@
Subproject commit d19610e0fba71785e4518ff566af31d48eea5eae
Subproject commit e0b1e8cb8525020e73839f374fbf6af6969a6a28

@ -1 +1 @@
Subproject commit 74ae4ddc3d62901c8a3d4f0a3379278c4ce3464e
Subproject commit 2f98a91615cf7b3d97b6ba27a7374292fc29b65d