This commit is contained in:
Saifeddine ALOUI 2023-07-15 20:02:03 +02:00
parent 967b9dc416
commit d1fbf77d0d
6 changed files with 122 additions and 27 deletions

View File

@ -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__)

View File

@ -100,8 +100,11 @@
</button>
</div>
<div v-if="showPersonalities" class="mx-1">
<MountedPersonalitiesList ref="mountedPersList" :onShowPersList="onShowPersListFun"
:on-mount-unmount="onMountUnmountFun" :discussionPersonalities="allDiscussionPersonalities" />
<MountedPersonalitiesList ref="mountedPersList"
:onShowPersList="onShowPersListFun"
:on-mount-unmount="onMountUnmountFun"
:on-talk="handleOnTalk"
:discussionPersonalities="allDiscussionPersonalities" />
</div>
<!-- CHAT BOX -->
<div class="flex flex-row flex-grow items-center gap-2 overflow-visible">
@ -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"
></PersonalitiesCommands>
</div>
@ -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()

View File

@ -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"
/>
</TransitionGroup>
</div>
</div>
@ -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

View File

@ -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

View File

@ -13,12 +13,13 @@
<h3 class="font-bold font-large text-lg line-clamp-3">
{{ personality.name }}
</h3>
<button v-if="selected" type="button" title="Reload personality"
@click="toggleReloadBinding"
<button type="button" title="Talk"
@click="toggleTalk"
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>
<i data-feather="send" class="w-5"></i>
<span class="sr-only">Talk</span>
</button>
</div>
<div class="flex items-center flex-row-reverse gap-2 my-1">
<!-- CONTROLS -->
@ -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)
},

View File

@ -210,7 +210,14 @@
</div>
<div class=" bottom-0 container flex flex-row items-center justify-center " v-if="currentDiscussion.id">
<ChatBox ref="chatBox" @messageSentEvent="sendMsg" :loading="isGenerating" :discussionList="discussionArr" @stopGenerating="stopGenerating">
<ChatBox ref="chatBox"
@messageSentEvent="sendMsg"
:loading="isGenerating"
:discussionList="discussionArr"
@stopGenerating="stopGenerating"
:on-show-toast-message="showToastMessage"
:on-talk="talk"
>
</ChatBox>
</div>
<!-- CAN ADD FOOTER PANEL HERE -->
@ -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");