new version

This commit is contained in:
Saifeddine ALOUI 2023-12-09 23:43:02 +01:00
parent b35cc9be97
commit 423be7d120
15 changed files with 499 additions and 287 deletions

View File

@ -799,6 +799,7 @@ class LoLLMsAPI(LollmsApplication):
seed = parameters["seed"],
)
ASCIIColors.success(f"\ndone")
if client_id in self.connections:
if not self.connections[client_id]["requested_stop"]:
# Emit the generated text to the client
@ -898,10 +899,9 @@ class LoLLMsAPI(LollmsApplication):
self.start_time = datetime.now()
self.personality.processor.callback = partial(self.process_chunk, client_id=client_id)
self.personality.processor.execute_command(command, parameters)
self.close_message(client_id)
else:
self.notify("Non scripted personalities do not support commands",False,client_id)
self.close_message(client_id)
@socketio.on('generate_msg')
def generate_msg(data):
client_id = request.sid

61
app.py
View File

@ -501,6 +501,12 @@ try:
self.add_endpoint(
"/open_code_folder", "open_code_folder", self.open_code_folder, methods=["POST"]
)
self.add_endpoint(
"/open_code_folder_in_vs_code", "open_code_folder_in_vs_code", self.open_code_folder_in_vs_code, methods=["POST"]
)
self.add_endpoint(
"/open_code_in_vs_code", "open_code_in_vs_code", self.open_code_in_vs_code, methods=["POST"]
)
def get_model_status(self):
return jsonify({"status":self.model is not None})
@ -617,9 +623,37 @@ try:
elif language in ["bash","shell","cmd","powershell"]:
return self.execute_bash(code, discussion_id, message_id)
return {"output": "Unsupported language", "execution_time": 0}
def open_code_folder_in_vs_code(self):
"""Opens code folder in vs code."""
data = request.get_json()
discussion_id = data.get("discussion_id","unknown_discussion")
ASCIIColors.info("Opening folder:")
# Create a temporary file.
root_folder = self.lollms_paths.personal_outputs_path/"discussions"/f"d_{discussion_id}"
root_folder.mkdir(parents=True,exist_ok=True)
os.system('code ' + str(root_folder))
return {"output": "OK", "execution_time": 0}
def open_code_in_vs_code(self):
"""Opens code in vs code."""
data = request.get_json()
discussion_id = data.get("discussion_id","unknown_discussion")
message_id = data.get("message_id","")
ASCIIColors.info("Opening folder:")
# Create a temporary file.
root_folder = self.lollms_paths.personal_outputs_path/"discussions"/f"d_{discussion_id}"/f"{message_id}.py"
root_folder.mkdir(parents=True,exist_ok=True)
os.system('code ' + str(root_folder))
return {"output": "OK", "execution_time": 0}
def open_code_folder(self):
"""Executes Python code and returns the output."""
"""Opens code folder."""
data = request.get_json()
discussion_id = data.get("discussion_id","unknown_discussion")
@ -1125,8 +1159,7 @@ try:
print(f"Couldn't load backend card : {f}\n\t{ex}")
return jsonify(bindings)
def list_extensions(self):
def get_extensions(self):
ASCIIColors.yellow("Listing all extensions")
extensions_folder = self.lollms_paths.extensions_zoo_path
extensions = {}
@ -1194,7 +1227,10 @@ try:
except Exception as ex:
ASCIIColors.warning(f"Couldn't load personality from {extensions_folder} [{ex}]")
trace_exception(ex)
return json.dumps(extensions)
return extensions
def list_extensions(self):
return json.dumps(self.get_extensions())
@ -1976,7 +2012,21 @@ try:
ASCIIColors.yellow(f"Available personalities: {[p.name for p in self.mounted_personalities]}")
return jsonify({"status": False, "error":"Couldn't unmount personality"})
def get_extension_settings(self):
print("- Retreiving extension settings")
data = request.get_json()
extension:LOLLMSExtension = next((element for element in self.mounted_extensions if element.name == data["name"]), None)
return jsonify(extension.extension_config.config_template.template)
def set_extension_settings(self):
print("- Setting extension settings")
data = request.get_json()
extension:LOLLMSExtension = next((element for element in self.mounted_extensions if element.name == data["name"]), None)
extension.extension_config.update_template(data["config"])
return jsonify(extension.extension_config.config_template.template)
def get_active_personality_settings(self):
print("- Retreiving personality settings")
if self.personality.processor is not None:
@ -1986,6 +2036,7 @@ try:
return jsonify({})
else:
return jsonify({})
def get_active_binding_settings(self):
print("- Retreiving binding settings")

@ -1 +1 @@
Subproject commit 8322c381b0848ce94dfd7279682eda9ae0d2634c
Subproject commit 01ec6b724bcdcda84ca97dfb12ed4b886963ebc6

BIN
web/dist/assets/extension-59119348.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 235 KiB

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

File diff suppressed because one or more lines are too long

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">
<title>LoLLMS WebUI - Welcome</title>
<script type="module" crossorigin src="/assets/index-f492bce7.js"></script>
<link rel="stylesheet" href="/assets/index-98356d8a.css">
<script type="module" crossorigin src="/assets/index-89dc57b2.js"></script>
<link rel="stylesheet" href="/assets/index-864f3ca4.css">
</head>
<body>
<div id="app"></div>

View File

@ -7,7 +7,7 @@
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">
<i data-feather="copy"></i>
</button>
<button v-if="['python', 'shell', 'bash', 'cmd', 'powershell'].includes(language)" ref="btn_code_exec" @click="executeCode" title="execute"
<button v-if="['python', 'sh', 'shell', 'bash', 'cmd', 'powershell'].includes(language)" ref="btn_code_exec" @click="executeCode" title="execute"
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">
<i data-feather="play-circle"></i>
</button>
@ -15,6 +15,14 @@
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">
<i data-feather="folder"></i>
</button>
<button v-if="['python'].includes(language)" @click="openFolderVsCode" title="open code project folder in vscode"
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">
<i data-feather="briefcase"></i>
</button>
<button v-if="['python'].includes(language)" @click="openVsCode" title="open code project folder in vscode"
class="px-2 py-1 ml-2 text-left p-2 text-sm font-medium bg-bg-dark-tone-panel dark:bg-bg-dark-tone rounded-lg hover:bg-primary dark:hover:bg-primary text-white text-xs transition-colors duration-200">
<i data-feather="briefcase"></i>
</button>
</div>
<pre class="hljs p-1 rounded-md break-all grid grid-cols-1">
<div class="code-container">
@ -144,6 +152,46 @@ export default {
console.error('Fetch error:', error);
});
},
openFolderVsCode(){
const json = JSON.stringify({ 'discussion_id': this.discussion_id })
console.log(json)
fetch(`${this.host}/open_code_in_vs_code`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: json
}).then(response=>{
// Parse the JSON data from the response body
return response.json();
})
.then(jsonData => {
// Now you can work with the JSON data
console.log(jsonData);
})
.catch(error => {
// Handle any errors that occurred during the fetch process
console.error('Fetch error:', error);
});
},
openVsCode() {
const json = JSON.stringify({ 'discussion_id': this.discussion_id, 'message_id': this.message_id, 'language': this.language })
console.log(json)
fetch(`${this.host}/open_code_folder_in_vs_code`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: json
}).then(response=>{
// Parse the JSON data from the response body
return response.json();
})
.then(jsonData => {
// Now you can work with the JSON data
console.log(jsonData);
})
.catch(error => {
// Handle any errors that occurred during the fetch process
console.error('Fetch error:', error);
});
},
openFolder() {
const json = JSON.stringify({ 'discussion_id': this.discussion_id })
console.log(json)

View File

@ -130,9 +130,7 @@ export default {
if(this.isMounted){
main_menu.push({name:"remount", icon: "feather:refresh-ccw", is_file:false, value:this.reMount})
}
if(this.selected && this.extension.has_scripts){
main_menu.push({name:"settings", icon: "feather:settings", is_file:false, value:this.toggleSettings})
}
main_menu.push({name:"settings", icon: "feather:settings", is_file:false, value:this.toggleSettings})
return main_menu
},
selected_computed(){

View File

@ -1,14 +1,14 @@
<template>
<div class="floating-frame">
<img v-if="isVideoActive" :src="imageDataUrl" alt="Webcam Frame" width="300" height="300" />
<div class="controls">
<button @click="startVideoStream">Activate Video</button>
<button @click="stopVideoStream">Deactivate Video</button>
</div>
<div class="floating-frame">
<img v-if="isVideoActive" :src="imageDataUrl" alt="Webcam Frame" width="300" height="300" />
<div class="controls">
<button v-if="!isVideoActive" class="w-full bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded" @click="startVideoStream">Activate Video</button>
<button v-if="isVideoActive" class="w-full bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded" @click="stopVideoStream">Deactivate Video</button>
</div>
</template>
</div>
</template>
<script>
<script>
import socket from '@/services/websocket.js';
export default {

View File

@ -0,0 +1,65 @@
<template>
<div v-if="show" class="fixed top-0 left-0 right-0 bottom-0 flex items-center justify-center bg-black bg-opacity-50">
<div class="relative w-full max-w-md max-h-full ">
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700 ">
<button type="button" @click="hide(false)"
class="absolute top-3 right-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm p-1.5 ml-auto inline-flex items-center dark:hover:bg-gray-800 dark:hover:text-white">
<svg aria-hidden="true" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd"
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clip-rule="evenodd"></path>
</svg>
<span class="sr-only">Close modal</span>
</button>
<div class="p-4 text-center">
<svg aria-hidden="true" class="mx-auto mb-4 text-gray-400 w-14 h-14 dark:text-gray-200" fill="none"
stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
</svg>
<h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400 select-none break-all">{{ message }}</h3>
<button @click="hide(true)" type="button"
class="text-white bg-red-600 hover:bg-red-800 focus:ring-4 focus:outline-none focus:ring-red-300 dark:focus:ring-red-800 font-medium rounded-lg text-sm inline-flex items-center px-5 py-2.5 text-center mr-2">
{{ConfirmButtonText}}
</button>
<button @click="hide(false)" type="button"
class="text-gray-500 bg-white hover:bg-gray-100 focus:ring-4 focus:outline-none focus:ring-gray-200 rounded-lg border border-gray-200 text-sm font-medium px-5 py-2.5 hover:text-gray-900 focus:z-10 dark:bg-gray-700 dark:text-gray-300 dark:border-gray-500 dark:hover:text-white dark:hover:bg-gray-600 dark:focus:ring-gray-600">{{DenyButtonText}}</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
show: false,
message: "",
resolve: null,
ConfirmButtonText: "Yes, I'm sure",
DenyButtonText: "No, cancel",
};
},
methods: {
hide(response) {
this.show = false;
if (this.resolve) {
this.resolve(response);
this.resolve = null;
}
},
askQuestion(message, ConfirmButtonText, DenyButtonText) {
this.ConfirmButtonText =ConfirmButtonText || this.ConfirmButtonText
this.DenyButtonText =DenyButtonText || this.DenyButtonText
return new Promise((resolve) => {
this.message = message;
this.show = true;
this.resolve = resolve;
});
},
},
};
</script>

View File

@ -372,6 +372,7 @@ export default {
data() {
return {
currentDiscussion: {},
host:"",
progress_visibility_val : true,
progress_value : 0,
@ -891,8 +892,10 @@ export default {
}
else{
if (this.currentDiscussion.id != item.id) {
console.log("item",item)
console.log("this.currentDiscussion",this.currentDiscussion)
this.currentDiscussion = item
console.log("this.currentDiscussion",this.currentDiscussion)
this.setPageTitle(item)

View File

@ -8,10 +8,13 @@
Personality does not have an avatar.
</div>
<FloatingFrame />
<div class="floating-frame2">
<div v-html="htmlContent"></div>
</div>
</div>
<div ref="webglContainer">
</div>
</template>
</template>
<script>
import * as THREE from 'three';
@ -154,5 +157,16 @@
top: 0;
left: 0;
}
.floating-frame2 {
margin: 15px;
float: left;
width: 200px;
height: auto;
border: 1px solid #000;
border-radius: 4px;
overflow: hidden;
min-height: 200px;
z-index: 5000;
}
</style>

View File

@ -1322,14 +1322,13 @@
v-for="(item, index) in mountedExtensions" :key="index + '-' + item.name"
ref="mountedExtensions">
<div class="group items-center flex flex-row">
<button @click.stop="onExtensionSelected(item)">
<img :src="bUrl + item.avatar" @error="personalityImgPlacehodler"
<button>
<img :src="bUrl + item.avatar" @error="extensionImgPlacehodler"
class="w-8 h-8 rounded-full object-fill text-red-700 border-2 active:scale-90 group-hover:border-secondary "
:class="configFile.active_personality_id == configFile.extensions.indexOf(item.full_path) ? 'border-secondary' : 'border-transparent z-0'"
:class="'border-transparent z-0'"
:title="item.name">
</button>
<button @click.stop="unmountExtension (item)">
<span
class="hidden group-hover:block top-0 left-7 absolute active:scale-90 bg-bg-light dark:bg-bg-dark rounded-full border-2 border-transparent"
title="Unmount personality">
@ -1398,10 +1397,10 @@
</div>
<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="extCat" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
Extensions Category: ({{ extCatgArr.length }})
</label>
<select id="persCat" @change="update_extension_category($event.target.value, refresh)"
<select id="extCat" @change="update_extension_category($event.target.value, refresh)"
class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 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">
<option v-for="(item, index) in extCatgArr" :key="index"
@ -1421,32 +1420,30 @@
}})
</label>
<div class="overflow-y-auto no-scrollbar p-2 pb-0 grid lg:grid-cols-3 md:grid-cols-2 gap-4"
:class="pzl_collapsed ? '' : 'max-h-96'">
<TransitionGroup name="bounce">
:class="ezl_collapsed ? '' : 'max-h-96'">
<ExtensionEntry ref="extensionsZoo" v-for="(ext, index) in extensionsFiltererd"
:key="'index-' + index + '-' + ext.name" :extension="ext"
:key="'index-' + index + '-' + ext.name"
:extension="ext"
:select_language="true"
:full_path="ext.full_path"
:on-selected="onExtensionSelected"
:on-mount="mountExtension"
:on-un-mount="unmountExtension"
:on-remount="remountExtension"
:on-reinstall="onExtensionReinstall"
:on-settings="onSettingsExtension" />
</TransitionGroup>
</div>
</div>
</div>
<!-- EXPAND / COLLAPSE BUTTON -->
<button v-if="pzl_collapsed"
<button v-if="ezc_collapsed"
class="text-2xl hover:text-secondary duration-75 flex justify-center hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg "
title="Collapse" type="button" @click="pzl_collapsed = !pzl_collapsed">
title="Collapse" type="button" @click="ezl_collapsed = !ezl_collapsed">
<i data-feather="chevron-up"></i>
</button>
<button v-else
class="text-2xl hover:text-secondary duration-75 flex justify-center hover:bg-bg-light-tone hover:dark:bg-bg-dark-tone rounded-lg "
title="Expand" type="button" @click="pzl_collapsed = !pzl_collapsed">
title="Expand" type="button" @click="ezl_collapsed = !ezl_collapsed">
<i data-feather="chevron-down"></i>
</button>
</div>
@ -1762,7 +1759,8 @@ import BindingEntry from "../components/BindingEntry.vue";
import socket from '@/services/websocket.js'
import defaultModelImgPlaceholder from "../assets/default_model.png"
import defaultPersonalityImgPlaceholder from "../assets/logo.svg"
import defaultPersonalityImgPlaceholder from "../assets/logo.png"
import defaultExtensionImgPlaceholder from "../assets/extension.png"
import defaultImgPlaceholder from "../assets/default_model.png"
import AddModelDialog from "@/components/AddModelDialog.vue";
@ -1772,6 +1770,7 @@ import ChoiceDialog from "@/components/ChoiceDialog.vue";
import Card from "@/components/Card.vue"
import RadioOptions from '../components/RadioOptions.vue';
import ExtensionEntry from "@/components/ExtensionEntry.vue"
import {refreshHardwareUsage} from "../main"
import SVGGPU from '@/assets/gpu.svg';
@ -1854,6 +1853,7 @@ export default {
// Zoo accordeoon
mzl_collapsed: false,
pzl_collapsed: false,
ezl_collapsed: false,
bzl_collapsed: false,
// Settings stuff
extCatgArr: [],
@ -2098,6 +2098,7 @@ export default {
try{
this.extCatgArr = await this.api_get_req("list_extensions_categories")
this.extension_category = this.extCatgArr[0]
console.log(this.extCatgArr)
}
catch{
@ -2323,42 +2324,7 @@ export default {
}
},
async onExtensionSelected(ext) {
console.log('on ext', ext)
// eslint-disable-next-line no-unused-vars
if (this.isLoading) {
this.$refs.toast.showToast("Loading... please wait", 4, false)
}
this.isLoading = true
console.log('extension', ext)
if (ext) {
if (ext.selected) {
this.$refs.toast.showToast("Extension already selected", 4, true)
this.isLoading = false
return
}
//this.settingsChanged = true
if (ext.isMounted && this.configFile.extensions.includes(ext.full_path)) {
this.isLoading = false
} else {
console.log('mounting ext')
this.mountPersonality(ext)
}
nextTick(() => {
feather.replace()
})
}
},
onModelSelected(model_object, force=false) {
// eslint-disable-next-line no-unused-vars
if (this.isLoading) {
@ -2759,6 +2725,53 @@ export default {
this.$refs.toast.showToast("Could not open binding settings. Endpoint error: " + error.message, 4, false)
}
},
onSettingsExtension(extensionEntry){
try {
this.isLoading = true
axios.get('/get_extension_settings',{name:extensionEntry.name}).then(res => {
this.isLoading = false
if (res) {
console.log('ext sett', res)
if (res.data && Object.keys(res.data).length > 0) {
this.$refs.universalForm.showForm(res.data, "Extension settings - " + extensionEntry.extension.name, "Save changes", "Cancel").then(res => {
// send new data
try {
axios.post('/set_extension_settings', {"name":extensionEntry.name,"config":res}).then(response => {
if (response && response.data) {
console.log('extension set with new settings', response.data)
this.$refs.toast.showToast("Extension settings updated successfully!", 4, true)
} else {
this.$refs.toast.showToast("Did not get Extension settings responses.\n" + response, 4, false)
this.isLoading = false
}
})
} catch (error) {
this.$refs.toast.showToast("Did not get Extension settings responses.\n Endpoint error: " + error.message, 4, false)
this.isLoading = false
}
})
} else {
this.$refs.toast.showToast("Extension has no settings", 4, false)
this.isLoading = false
}
}
})
} catch (error) {
this.isLoading = false
this.$refs.toast.showToast("Could not open personality settings. Endpoint error: " + error.message, 4, false)
}
},
onSettingsBinding(bindingEntry) {
try {
this.isLoading = true
@ -2913,8 +2926,11 @@ export default {
this.api_get_req("list_extensions_categories").then((cats)=>{
console.log("cats",cats)
this.extCatgArr = cats
console.log("this.$store.state.extensionsZoo",this.$store.state.extensionsZoo)
console.log("this.extension_category", this.extension_category)
this.extensionsFiltererd = this.$store.state.extensionsZoo.filter((item) => item.category === this.extension_category)
this.extensionsFiltererd.sort()
console.log("this.extensionsFiltererd", this.extensionsFiltererd)
})
@ -3676,6 +3692,9 @@ export default {
personalityImgPlacehodler(event) {
event.target.src = defaultPersonalityImgPlaceholder
},
extensionImgPlacehodler(event){
event.target.src = defaultExtensionImgPlaceholder
},
searchPersonality_func() {
clearTimeout(this.searchPersonalityTimer)
@ -4092,6 +4111,13 @@ export default {
},
watch: {
watch: {
extensionsFiltered(newValue, oldValue) {
// Perform any necessary UI updates here
// newValue represents the new value of extensionsFiltered
// oldValue represents the previous value of extensionsFiltered
}
},
bec_collapsed() {
nextTick(() => {
feather.replace()
@ -4136,6 +4162,11 @@ export default {
})
},
ezl_collapsed() {
nextTick(() => {
feather.replace()
})
},
bzl_collapsed() {
nextTick(() => {