From d1fbf77d0da283fc1766826228b20a98c5dfe7da Mon Sep 17 00:00:00 2001 From: Saifeddine ALOUI Date: Sat, 15 Jul 2023 20:02:03 +0200 Subject: [PATCH] upgraded --- api/__init__.py | 32 +++++++++------ web/src/components/ChatBox.vue | 18 ++++++-- .../components/MountedPersonalitiesList.vue | 37 ++++++++++++++++- web/src/components/PersonalitiesCommands.vue | 6 ++- web/src/components/PersonalityEntry.vue | 15 ++++--- web/src/views/DiscussionsView.vue | 41 +++++++++++++++++-- 6 files changed, 122 insertions(+), 27 deletions(-) diff --git a/api/__init__.py b/api/__init__.py index 1f3b277d..37e61841 100644 --- a/api/__init__.py +++ b/api/__init__.py @@ -34,15 +34,16 @@ import ctypes from functools import partial def terminate_thread(thread): - if not thread.is_alive(): - return + if thread: + if not thread.is_alive(): + return - thread_id = thread.ident - exc = ctypes.py_object(SystemExit) - res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, exc) - if res > 1: - ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, None) - raise SystemError("Failed to terminate the thread.") + thread_id = thread.ident + exc = ctypes.py_object(SystemExit) + res = ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, exc) + if res > 1: + ctypes.pythonapi.PyThreadState_SetAsyncExc(thread_id, None) + raise SystemError("Failed to terminate the thread.") __author__ = "parisneo" __github__ = "https://github.com/ParisNeo/lollms-webui" @@ -150,7 +151,9 @@ class LoLLMsAPPI(LollmsApplication): "current_discussion":None, "generated_text":"", "cancel_generation": False, - "generation_thread": None + "generation_thread": None, + "current_discussion":None, + "current_message_id":0 } ASCIIColors.success(f'Client {request.sid} connected') @@ -388,6 +391,7 @@ class LoLLMsAPPI(LollmsApplication): client_id = request.sid self.connections[client_id]["generated_text"]="" self.connections[client_id]["cancel_generation"]=False + if self.is_ready: if self.current_discussion is None: @@ -441,7 +445,11 @@ class LoLLMsAPPI(LollmsApplication): def handle_connection(data): client_id = request.sid message_id = int(data['id']) - message = data["prompt"] + if message_id==-1: + message_id = self.message_id + message = "" + else: + message = data["prompt"] self.current_user_message_id = message_id self.connections[client_id]['generation_thread'] = threading.Thread(target=self.start_message_generation, args=(message, message_id, client_id)) self.connections[client_id]['generation_thread'].start() @@ -786,9 +794,7 @@ class LoLLMsAPPI(LollmsApplication): if self.personality.processor is not None: ASCIIColors.success("Running workflow") try: - output = self.personality.processor.run_workflow( prompt, full_prompt, callback) - if callback: - callback(output, MSG_TYPE.MSG_TYPE_FULL) + self.personality.processor.run_workflow( prompt, full_prompt, callback) except Exception as ex: # Catch the exception and get the traceback as a list of strings traceback_lines = traceback.format_exception(type(ex), ex, ex.__traceback__) diff --git a/web/src/components/ChatBox.vue b/web/src/components/ChatBox.vue index 2e81cb06..517d7a22 100644 --- a/web/src/components/ChatBox.vue +++ b/web/src/components/ChatBox.vue @@ -100,8 +100,11 @@
- +
@@ -114,6 +117,7 @@ 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" + :on-show-toast-message="onShowToastMessage" ref="personalityCMD" >
@@ -206,8 +210,10 @@ export default { name: 'ChatBox', emits: ["messageSentEvent", "stopGenerating"], props: { + onTalk: Function, discussionList: Array, - loading: false + loading: false, + onShowToastMessage: Function }, components: { @@ -255,6 +261,7 @@ export default { } }, methods: { + onPersonalitiesReadyFun(){ this.personalities_ready = true; }, @@ -262,6 +269,11 @@ export default { this.showPersonalities = !this.showPersonalities }, + handleOnTalk(pers){ + this.showPersonalities=false + this.onTalk(pers) + }, + onMountUnmountFun(comp) { console.log('Mounting/unmounting chat') this.$refs.mountedPers.constructor() diff --git a/web/src/components/MountedPersonalitiesList.vue b/web/src/components/MountedPersonalitiesList.vue index 709f2249..348f15d0 100644 --- a/web/src/components/MountedPersonalitiesList.vue +++ b/web/src/components/MountedPersonalitiesList.vue @@ -39,7 +39,9 @@ :key="'index-' + index + '-' + pers.name" :personality="pers" :full_path="pers.full_path" :selected="configFile.personalities[configFile.active_personality_id] === pers.full_path" :on-selected="onPersonalitySelected" :on-mounted="onPersonalityMounted" - :on-settings="onSettingsPersonality" :on-reinstall="onPersonalityReinstall"/> + :on-settings="onSettingsPersonality" :on-reinstall="onPersonalityReinstall" + :on-talk="handleOnTalk" + /> @@ -87,6 +89,7 @@ const bUrl = import.meta.env.VITE_GPT4ALL_API_BASEURL axios.defaults.baseURL = import.meta.env.VITE_GPT4ALL_API_BASEURL export default { props: { + onTalk:Function, onMountUnmount: Function, discussionPersonalities: Array, onShowPersList: Function, @@ -218,6 +221,38 @@ export default { } + }, + async handleOnTalk(pers){ + // eslint-disable-next-line no-unused-vars + feather.replace() + console.log('ppa', pers) + if (pers) { + + if (pers.selected) { + this.$refs.toast.showToast("Personality already selected", 4, true) + return + } + if (pers.isMounted) { + + const res = await this.select_personality(pers) + if (res) { + if (res.status) { + await this.constructor() + this.$refs.toast.showToast("Selected personality:\n" + pers.name, 4, true) + this.onTalk(pers) + } + } + + + } else { + this.onPersonalityMounted(pers) + + } + + + + } + }, async onPersonalitySelected(pers) { // eslint-disable-next-line no-unused-vars diff --git a/web/src/components/PersonalitiesCommands.vue b/web/src/components/PersonalitiesCommands.vue index 8cb8aecb..de869afa 100644 --- a/web/src/components/PersonalitiesCommands.vue +++ b/web/src/components/PersonalitiesCommands.vue @@ -79,7 +79,8 @@ props: { type: Array, required: true, }, - sendCommand:Function + sendCommand:Function, + onShowToastMessage:Function }, data() { return { @@ -106,6 +107,7 @@ methods: { input.accept = 'application/pdf'; // Specify the file type you want to accept input.onchange = (e) => { this.selectedFile = e.target.files[0]; + console.log("File selected") next() }; input.click(); @@ -113,11 +115,13 @@ methods: { uploadFile() { const formData = new FormData(); formData.append('file', this.selectedFile); + console.log("Uploading file") axios.post('/send_file', formData) .then(response => { // Handle the server response if needed console.log(response.data); + this.onShowToastMessage("File uploaded successfully") }) .catch(error => { // Handle any errors that occur during the upload diff --git a/web/src/components/PersonalityEntry.vue b/web/src/components/PersonalityEntry.vue index 39827e84..9b7bdcaf 100644 --- a/web/src/components/PersonalityEntry.vue +++ b/web/src/components/PersonalityEntry.vue @@ -13,12 +13,13 @@

{{ personality.name }}

- + + Talk + +
@@ -95,6 +96,7 @@ export default { personality: {}, selected: Boolean, full_path: String, + onTalk:Function, onSelected: Function, onMounted: Function, onReinstall: Function, @@ -128,6 +130,9 @@ selected_computed(){ defaultImg(event) { event.target.src = botImgPlaceholder }, + toggleTalk() { + this.onTalk(this) + }, toggleSelected() { this.onSelected(this) }, diff --git a/web/src/views/DiscussionsView.vue b/web/src/views/DiscussionsView.vue index 29cba877..53f0d704 100644 --- a/web/src/views/DiscussionsView.vue +++ b/web/src/views/DiscussionsView.vue @@ -210,7 +210,14 @@
- +
@@ -349,6 +356,10 @@ export default { } }, methods: { + showToastMessage(text){ + console.log("sending",text) + this.$refs.toast.showToast(text, 4, true) + }, togglePanel() { this.panelCollapsed = !this.panelCollapsed; }, @@ -780,6 +791,29 @@ export default { this.chime.play() } }, + talk(pers){ + this.isGenerating = true; + this.setDiscussionLoading(this.currentDiscussion.id, this.isGenerating); + axios.get('/get_generation_status', {}).then((res) => { + if (res) { + //console.log(res.data.status); + if (!res.data.status) { + socket.emit('generate_msg_from', { id: -1 }); + // Temp data + let lastmsgid =0 + if(this.discussionArr.length>0){ + lastmsgid= Number(this.discussionArr[this.discussionArr.length - 1].id) + 1 + } + + } + else { + console.log("Already generating"); + } + } + }).catch((error) => { + console.log("Error: Could not get generation status", error); + }); + }, sendMsg(msg) { // Sends message to binding if (!msg) { @@ -838,13 +872,14 @@ export default { messageItem.steps.push({"message":msgObj.data,"done":false}) } else if (msgObj.message_type == this.msgTypes.MSG_TYPE_STEP_END) { - // Find the step with the matching message and update its 'done' property to true const matchingStep = messageItem.steps.find(step => step.message === msgObj.data); if (matchingStep) { matchingStep.done = true; } + } else if (msgObj.message_type == this.msgTypes.MSG_TYPE_EXCEPTION) { + this.$refs.toast.showToast(msgObj.data, 4, true) } // // Disables as per request // nextTick(() => { @@ -1066,8 +1101,6 @@ export default { console.log(res); if (!res.data.status) { socket.emit('generate_msg_from', { prompt: msg, id: msgId }); - - } else { console.log("Already generating");