mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2025-01-30 16:14:05 +00:00
enhanced code
This commit is contained in:
parent
f855b10a0d
commit
94b1e5ca2d
@ -172,16 +172,25 @@ class LoLLMsAPPI(LollmsApplication):
|
|||||||
|
|
||||||
@socketio.on('cancel_install')
|
@socketio.on('cancel_install')
|
||||||
def cancel_install(data):
|
def cancel_install(data):
|
||||||
model_name = data["model_name"]
|
try:
|
||||||
binding_folder = data["binding_folder"]
|
model_name = data["model_name"]
|
||||||
model_url = data["model_url"]
|
binding_folder = data["binding_folder"]
|
||||||
signature = f"{model_name}_{binding_folder}_{model_url}"
|
model_url = data["model_url"]
|
||||||
self.download_infos[signature]["cancel"]=True
|
signature = f"{model_name}_{binding_folder}_{model_url}"
|
||||||
self.socketio.emit('canceled', {
|
self.download_infos[signature]["cancel"]=True
|
||||||
'status': True
|
self.socketio.emit('canceled', {
|
||||||
},
|
'status': True
|
||||||
room=request.sid
|
},
|
||||||
)
|
room=request.sid
|
||||||
|
)
|
||||||
|
except Exception as ex:
|
||||||
|
trace_exception(ex)
|
||||||
|
self.socketio.emit('canceled', {
|
||||||
|
'status': False,
|
||||||
|
'error':str(ex)
|
||||||
|
},
|
||||||
|
room=request.sid
|
||||||
|
)
|
||||||
|
|
||||||
@socketio.on('install_model')
|
@socketio.on('install_model')
|
||||||
def install_model(data):
|
def install_model(data):
|
||||||
@ -395,6 +404,14 @@ class LoLLMsAPPI(LollmsApplication):
|
|||||||
self.connections[client_id]["generated_text"]=""
|
self.connections[client_id]["generated_text"]=""
|
||||||
self.connections[client_id]["cancel_generation"]=False
|
self.connections[client_id]["cancel_generation"]=False
|
||||||
|
|
||||||
|
if not self.model:
|
||||||
|
self.socketio.emit('model_not_selected',
|
||||||
|
{
|
||||||
|
"status":False,
|
||||||
|
"error":"Model not selected. Please select a model"
|
||||||
|
}, room=client_id
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
if self.is_ready:
|
if self.is_ready:
|
||||||
if self.current_discussion is None:
|
if self.current_discussion is None:
|
||||||
|
@ -300,7 +300,7 @@ class DiscussionsDB:
|
|||||||
|
|
||||||
# Insert message into the database
|
# Insert message into the database
|
||||||
self.insert("INSERT INTO message (sender, content, type, rank, parent, binding, model, personality, created_at, finished_generating_at, discussion_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
self.insert("INSERT INTO message (sender, content, type, rank, parent, binding, model, personality, created_at, finished_generating_at, discussion_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
|
||||||
(sender, content, content_type, rank, parent, model, personality, created_at, finished_generating_at, discussion_id))
|
(sender, content, content_type, rank, parent, binding, model, personality, created_at, finished_generating_at, discussion_id))
|
||||||
|
|
||||||
discussions.append(discussion)
|
discussions.append(discussion)
|
||||||
|
|
||||||
|
2
app.py
2
app.py
@ -1447,6 +1447,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
|||||||
try:
|
try:
|
||||||
filename = model.get('filename',"")
|
filename = model.get('filename',"")
|
||||||
server = model.get('server',"")
|
server = model.get('server',"")
|
||||||
|
variants = model.get('variants',[])
|
||||||
image_url = model.get("icon", '/images/default_model.png')
|
image_url = model.get("icon", '/images/default_model.png')
|
||||||
license = model.get("license", 'unknown')
|
license = model.get("license", 'unknown')
|
||||||
owner = model.get("owner", 'unknown')
|
owner = model.get("owner", 'unknown')
|
||||||
@ -1462,6 +1463,7 @@ class LoLLMsWebUI(LoLLMsAPPI):
|
|||||||
is_installed = local_path.exists() or model_type.lower()=="api"
|
is_installed = local_path.exists() or model_type.lower()=="api"
|
||||||
models.append({
|
models.append({
|
||||||
'title': filename,
|
'title': filename,
|
||||||
|
'variants': variants,
|
||||||
'icon': image_url, # Replace with the path to the model icon
|
'icon': image_url, # Replace with the path to the model icon
|
||||||
'license': license,
|
'license': license,
|
||||||
'owner': owner,
|
'owner': owner,
|
||||||
|
File diff suppressed because one or more lines are too long
8
web/dist/assets/index-4f9d4363.css
vendored
8
web/dist/assets/index-4f9d4363.css
vendored
File diff suppressed because one or more lines are too long
8
web/dist/assets/index-61c53820.css
vendored
Normal file
8
web/dist/assets/index-61c53820.css
vendored
Normal file
File diff suppressed because one or more lines are too long
4
web/dist/index.html
vendored
4
web/dist/index.html
vendored
@ -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-6e792e12.js"></script>
|
<script type="module" crossorigin src="/assets/index-12bf0526.js"></script>
|
||||||
<link rel="stylesheet" href="/assets/index-4f9d4363.css">
|
<link rel="stylesheet" href="/assets/index-61c53820.css">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
|
@ -1,80 +1,93 @@
|
|||||||
<!-- ChoiceDialog.vue -->
|
<!-- ChoiceDialog.vue -->
|
||||||
<template>
|
<template>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
<div v-if="show" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
|
<div v-if="show" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
|
||||||
<div class="bg-white dark:bg-gray-800 rounded-lg p-6 w-96">
|
<div class="bg-white dark:bg-gray-800 rounded-lg p-6 w-96">
|
||||||
<h2 class="text-xl font-semibold mb-4">{{ title }}</h2>
|
<h2 class="text-xl font-semibold mb-4">{{ title }}</h2>
|
||||||
<div class="h-48 overflow-y-auto">
|
<div class="h-48 overflow-y-auto">
|
||||||
<ul>
|
<ul>
|
||||||
<li
|
<li
|
||||||
v-for="(choice, index) in choices"
|
v-for="(choice, index) in choices"
|
||||||
:key="index"
|
:key="index"
|
||||||
@click="selectChoice(choice)"
|
@click="selectChoice(choice)"
|
||||||
class="py-2 px-4 cursor-pointer hover:bg-gray-200 dark:hover:bg-gray-700"
|
:class="{'selected-choice': choice === selectedChoice}"
|
||||||
>
|
class="py-2 px-4 cursor-pointer hover:bg-gray-200 dark:hover:bg-gray-700"
|
||||||
{{ choice }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-end mt-4">
|
|
||||||
<button
|
|
||||||
@click="closeDialog"
|
|
||||||
class="py-2 px-4 mr-2 bg-red-500 hover:bg-red-600 text-white rounded-lg transition duration-300"
|
|
||||||
>
|
>
|
||||||
Cancel
|
<span class="font-bold"> {{ choice.name }} </span><br>
|
||||||
</button>
|
<span class="text-xs text-gray-500"> {{ this.formatSize(choice.size) }}</span>
|
||||||
<button
|
</li>
|
||||||
@click="validateChoice"
|
</ul>
|
||||||
class="py-2 px-4 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition duration-300"
|
</div>
|
||||||
>
|
<div class="flex justify-end mt-4">
|
||||||
Validate
|
<button
|
||||||
</button>
|
@click="closeDialog"
|
||||||
</div>
|
class="py-2 px-4 mr-2 bg-red-500 hover:bg-red-600 text-white rounded-lg transition duration-300"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
@click="validateChoice"
|
||||||
|
class="py-2 px-4 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition duration-300"
|
||||||
|
>
|
||||||
|
Validate
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</div>
|
||||||
</template>
|
</transition>
|
||||||
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
show: {
|
show: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: "Select an option",
|
|
||||||
},
|
|
||||||
choices: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
methods: {
|
title: {
|
||||||
selectChoice(choice) {
|
type: String,
|
||||||
this.$emit("choice-selected", choice);
|
default: "Select an option",
|
||||||
},
|
|
||||||
closeDialog() {
|
|
||||||
this.$emit("close-dialog");
|
|
||||||
},
|
|
||||||
validateChoice() {
|
|
||||||
// Perform validation if needed
|
|
||||||
this.$emit("choice-validated");
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
};
|
choices: {
|
||||||
</script>
|
type: Array,
|
||||||
|
required: true,
|
||||||
<style>
|
},
|
||||||
.fade-enter-active,
|
},
|
||||||
.fade-leave-active {
|
data() {
|
||||||
transition: opacity 0.3s;
|
return {
|
||||||
}
|
selectedChoice: null,
|
||||||
|
};
|
||||||
.fade-enter-from,
|
},
|
||||||
.fade-leave-to {
|
methods: {
|
||||||
opacity: 0;
|
selectChoice(choice) {
|
||||||
}
|
this.selectedChoice = choice; // Update the selectedChoice when a choice is clicked
|
||||||
</style>
|
this.$emit("choice-selected", choice);
|
||||||
|
},
|
||||||
|
closeDialog() {
|
||||||
|
this.$emit("close-dialog");
|
||||||
|
},
|
||||||
|
validateChoice() {
|
||||||
|
// Perform validation if needed
|
||||||
|
this.$emit("choice-validated");
|
||||||
|
},
|
||||||
|
formatSize(size) {
|
||||||
|
if (size < 1024) {
|
||||||
|
return size + " bytes";
|
||||||
|
} else if (size < 1024 * 1024) {
|
||||||
|
return (size / 1024).toFixed(2) + " KB";
|
||||||
|
} else if (size < 1024 * 1024 * 1024) {
|
||||||
|
return (size / (1024 * 1024)).toFixed(2) + " MB";
|
||||||
|
} else {
|
||||||
|
return (size / (1024 * 1024 * 1024)).toFixed(2) + " GB";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* ... (unchanged) */
|
||||||
|
.selected-choice {
|
||||||
|
background-color: #bde4ff; /* Change this color as per your preference */
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -1,80 +0,0 @@
|
|||||||
<!-- ChoiceDialog.vue -->
|
|
||||||
<template>
|
|
||||||
<transition name="fade">
|
|
||||||
<div v-if="show" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50">
|
|
||||||
<div class="bg-white dark:bg-gray-800 rounded-lg p-6 w-96">
|
|
||||||
<h2 class="text-xl font-semibold mb-4">{{ title }}</h2>
|
|
||||||
<div class="h-48 overflow-y-auto">
|
|
||||||
<ul>
|
|
||||||
<li
|
|
||||||
v-for="(choice, index) in choices"
|
|
||||||
:key="index"
|
|
||||||
@click="selectChoice(choice)"
|
|
||||||
class="py-2 px-4 cursor-pointer hover:bg-gray-200 dark:hover:bg-gray-700"
|
|
||||||
>
|
|
||||||
{{ choice }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="flex justify-end mt-4">
|
|
||||||
<button
|
|
||||||
@click="closeDialog"
|
|
||||||
class="py-2 px-4 mr-2 bg-red-500 hover:bg-red-600 text-white rounded-lg transition duration-300"
|
|
||||||
>
|
|
||||||
Cancel
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
@click="validateChoice"
|
|
||||||
class="py-2 px-4 bg-blue-500 hover:bg-blue-600 text-white rounded-lg transition duration-300"
|
|
||||||
>
|
|
||||||
Validate
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</transition>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
export default {
|
|
||||||
props: {
|
|
||||||
show: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
type: String,
|
|
||||||
default: "Select an option",
|
|
||||||
},
|
|
||||||
choices: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
selectChoice(choice) {
|
|
||||||
this.$emit("choice-selected", choice);
|
|
||||||
},
|
|
||||||
closeDialog() {
|
|
||||||
this.$emit("close-dialog");
|
|
||||||
},
|
|
||||||
validateChoice() {
|
|
||||||
// Perform validation if needed
|
|
||||||
this.$emit("choice-validated");
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.fade-enter-active,
|
|
||||||
.fade-leave-active {
|
|
||||||
transition: opacity 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.fade-enter-from,
|
|
||||||
.fade-leave-to {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -198,8 +198,6 @@ export default {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}, mounted() {
|
}, mounted() {
|
||||||
console.log("Mounted message")
|
|
||||||
console.log(this.message)
|
|
||||||
this.new_message_content = this.message.content
|
this.new_message_content = this.message.content
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
feather.replace()
|
feather.replace()
|
||||||
|
@ -244,6 +244,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
@ -254,6 +255,7 @@ import axios from "axios";
|
|||||||
import { nextTick } from 'vue'
|
import { nextTick } from 'vue'
|
||||||
import feather from 'feather-icons'
|
import feather from 'feather-icons'
|
||||||
import defaultImgPlaceholder from "../assets/default_model.png"
|
import defaultImgPlaceholder from "../assets/default_model.png"
|
||||||
|
|
||||||
const bUrl = import.meta.env.VITE_LOLLMS_API_BASEURL
|
const bUrl = import.meta.env.VITE_LOLLMS_API_BASEURL
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@ -285,8 +287,8 @@ export default {
|
|||||||
installing: false,
|
installing: false,
|
||||||
uninstalling: false,
|
uninstalling: false,
|
||||||
failedToLoad: false,
|
failedToLoad: false,
|
||||||
fileSize: '',
|
|
||||||
linkNotValid: false,
|
linkNotValid: false,
|
||||||
|
selected_variant: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
@ -299,15 +301,24 @@ export default {
|
|||||||
})
|
})
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
formatFileSize(sizeInBytes) {
|
||||||
|
if (sizeInBytes < 1024) {
|
||||||
|
return sizeInBytes + " bytes";
|
||||||
|
} else if (sizeInBytes < 1024 * 1024) {
|
||||||
|
return (sizeInBytes / 1024).toFixed(2) + " KB";
|
||||||
|
} else if (sizeInBytes < 1024 * 1024 * 1024) {
|
||||||
|
return (sizeInBytes / (1024 * 1024)).toFixed(2) + " MB";
|
||||||
|
} else {
|
||||||
|
return (sizeInBytes / (1024 * 1024 * 1024)).toFixed(2) + " GB";
|
||||||
|
}
|
||||||
|
},
|
||||||
computedFileSize(size) {
|
computedFileSize(size) {
|
||||||
return filesize(size)
|
return filesize(size)
|
||||||
},
|
},
|
||||||
async getFileSize(url) {
|
async getFileSize(url) {
|
||||||
//console.log(this.model_type);
|
|
||||||
if (this.model_type != "api") {
|
if (this.model_type != "api") {
|
||||||
try {
|
try {
|
||||||
const res = await axios.head(url)
|
const res = await axios.head(url)
|
||||||
//console.log("addddd",url, res.headers)
|
|
||||||
if (res) {
|
if (res) {
|
||||||
|
|
||||||
if (res.headers["content-length"]) {
|
if (res.headers["content-length"]) {
|
||||||
@ -367,24 +378,17 @@ export default {
|
|||||||
event.target.src = defaultImgPlaceholder
|
event.target.src = defaultImgPlaceholder
|
||||||
},
|
},
|
||||||
toggleInstall() {
|
toggleInstall() {
|
||||||
this.getFileSize(this.model.path).then(data=>{
|
|
||||||
this.fileSize = data
|
|
||||||
})
|
|
||||||
|
|
||||||
if (this.isInstalled) {
|
if (this.isInstalled) {
|
||||||
this.uninstalling = true;
|
this.uninstalling = true;
|
||||||
// Simulate uninstallation delay (replace this with your WebSocket logic)
|
// Simulate uninstallation delay (replace this with your WebSocket logic)
|
||||||
this.onUninstall(this);
|
this.onUninstall(this);
|
||||||
} else {
|
} else {
|
||||||
this.installing = true;
|
//this.installing = true;
|
||||||
this.onInstall(this);
|
this.onInstall(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toggleSelected() {
|
toggleSelected() {
|
||||||
this.getFileSize(this.model.path).then(data=>{
|
|
||||||
this.fileSize = data
|
|
||||||
})
|
|
||||||
this.onSelected(this)
|
this.onSelected(this)
|
||||||
},
|
},
|
||||||
toggleCopy() {
|
toggleCopy() {
|
||||||
@ -405,12 +409,21 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
copyContentToClipboard() {
|
copyContentToClipboard() {
|
||||||
console.log('asdasdas')
|
|
||||||
this.$emit('copy', 'this.message.content')
|
this.$emit('copy', 'this.message.content')
|
||||||
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
fileSize: {
|
||||||
|
get() {
|
||||||
|
// console.log(this.model)
|
||||||
|
if (this.model && this.model.variants && this.model.variants.length > 0) {
|
||||||
|
const sizeInBytes = this.model.variants[0]["size"];
|
||||||
|
return this.formatFileSize(sizeInBytes);
|
||||||
|
}
|
||||||
|
return null; // Return null if the conditions are not met
|
||||||
|
},
|
||||||
|
},
|
||||||
speed_computed() {
|
speed_computed() {
|
||||||
return filesize(this.speed)
|
return filesize(this.speed)
|
||||||
},
|
},
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
fill="currentFill" />
|
fill="currentFill" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="content flex-1" :class="{'text-green-500': done, 'text-yellow-500': !done}">{{ message }}</div>
|
<div class="content flex-1 px-2" :class="{'text-green-500': done, 'text-yellow-500': !done}">{{ message }}</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -808,7 +808,8 @@ export default {
|
|||||||
// Create response message
|
// Create response message
|
||||||
|
|
||||||
let responseMessage = {
|
let responseMessage = {
|
||||||
content:msgObj.data, //content: "✍ please stand by ...",//msgObj.message,
|
//content:msgObj.data,
|
||||||
|
content: "✍ please stand by ...",//msgObj.message,
|
||||||
created_at:msgObj.created_at,
|
created_at:msgObj.created_at,
|
||||||
binding:msgObj.binding,
|
binding:msgObj.binding,
|
||||||
model:msgObj.model,
|
model:msgObj.model,
|
||||||
@ -834,7 +835,6 @@ export default {
|
|||||||
if (msgObj.type == "input_message_infos") {
|
if (msgObj.type == "input_message_infos") {
|
||||||
// This is a user input
|
// This is a user input
|
||||||
this.changeTitleUsingUserMSG(this.currentDiscussion.id, msgObj.message)
|
this.changeTitleUsingUserMSG(this.currentDiscussion.id, msgObj.message)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("infos", msgObj)
|
console.log("infos", msgObj)
|
||||||
@ -896,7 +896,7 @@ export default {
|
|||||||
message: msg,
|
message: msg,
|
||||||
id: lastmsgid,
|
id: lastmsgid,
|
||||||
rank: 0,
|
rank: 0,
|
||||||
user: "user",
|
user: this.$store.config.user_name,
|
||||||
created_at: new Date().toLocaleString(),
|
created_at: new Date().toLocaleString(),
|
||||||
|
|
||||||
};
|
};
|
||||||
@ -913,7 +913,7 @@ export default {
|
|||||||
},
|
},
|
||||||
streamMessageContent(msgObj) {
|
streamMessageContent(msgObj) {
|
||||||
// Streams response message content from binding
|
// Streams response message content from binding
|
||||||
console.log("Received message",msgObj)
|
//console.log("Received message",msgObj)
|
||||||
const parent = msgObj.user_message_id
|
const parent = msgObj.user_message_id
|
||||||
const discussion_id = msgObj.discussion_id
|
const discussion_id = msgObj.discussion_id
|
||||||
this.setDiscussionLoading(discussion_id, true);
|
this.setDiscussionLoading(discussion_id, true);
|
||||||
|
@ -866,7 +866,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="!searchModel">
|
<div v-if="!searchModel">
|
||||||
|
|
||||||
<div v-if="models.length > 0" class="mb-2">
|
<div v-if="models && models.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">
|
||||||
Models: ({{ models.length }})
|
Models: ({{ models.length }})
|
||||||
</label>
|
</label>
|
||||||
@ -1395,6 +1395,13 @@
|
|||||||
<MessageBox ref="messageBox" />
|
<MessageBox ref="messageBox" />
|
||||||
<Toast ref="toast" />
|
<Toast ref="toast" />
|
||||||
<UniversalForm ref="universalForm" class="z-20" />
|
<UniversalForm ref="universalForm" class="z-20" />
|
||||||
|
<ChoiceDialog class="z-20"
|
||||||
|
:show="variantSelectionDialogVisible"
|
||||||
|
:choices="variant_choices"
|
||||||
|
@choice-selected="onVariantChoiceSelected"
|
||||||
|
@close-dialog="oncloseVariantChoiceDialog"
|
||||||
|
@choice-validated="onvalidateVariantChoice"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
<style scoped>
|
<style scoped>
|
||||||
/* THESE ARE FOR TransitionGroup components */
|
/* THESE ARE FOR TransitionGroup components */
|
||||||
@ -1475,6 +1482,9 @@ import defaultImgPlaceholder from "../assets/default_model.png"
|
|||||||
|
|
||||||
import AddModelDialog from "@/components/AddModelDialog.vue";
|
import AddModelDialog from "@/components/AddModelDialog.vue";
|
||||||
import UniversalForm from '../components/UniversalForm.vue';
|
import UniversalForm from '../components/UniversalForm.vue';
|
||||||
|
|
||||||
|
import ChoiceDialog from "@/components/ChoiceDialog.vue";
|
||||||
|
|
||||||
const bUrl = import.meta.env.VITE_LOLLMS_API_BASEURL
|
const bUrl = import.meta.env.VITE_LOLLMS_API_BASEURL
|
||||||
axios.defaults.baseURL = import.meta.env.VITE_LOLLMS_API_BASEURL
|
axios.defaults.baseURL = import.meta.env.VITE_LOLLMS_API_BASEURL
|
||||||
export default {
|
export default {
|
||||||
@ -1488,11 +1498,17 @@ export default {
|
|||||||
Toast,
|
Toast,
|
||||||
PersonalityEntry,
|
PersonalityEntry,
|
||||||
BindingEntry,
|
BindingEntry,
|
||||||
UniversalForm
|
UniversalForm,
|
||||||
|
ChoiceDialog
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
// Variant selection
|
||||||
|
variant_choices:[],
|
||||||
|
variantSelectionDialogVisible:false,
|
||||||
|
currenModelToInstall:null,
|
||||||
|
// Loading text
|
||||||
loading_text:"",
|
loading_text:"",
|
||||||
// Current personality language
|
// Current personality language
|
||||||
personality_language:null,
|
personality_language:null,
|
||||||
@ -1551,8 +1567,75 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
||||||
|
onVariantChoiceSelected(choice){
|
||||||
|
this.selected_variant = choice
|
||||||
|
},
|
||||||
|
oncloseVariantChoiceDialog(){
|
||||||
|
this.variantSelectionDialogVisible=false;
|
||||||
|
},
|
||||||
|
onvalidateVariantChoice(){
|
||||||
|
this.variantSelectionDialogVisible=false;
|
||||||
|
this.currenModelToInstall.installing=true;
|
||||||
|
let model_object = this.currenModelToInstall;
|
||||||
|
if (model_object.linkNotValid) {
|
||||||
|
model_object.installing = false
|
||||||
|
this.$refs.toast.showToast("Link is not valid, file does not exist", 4, false)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let path = model_object.path;
|
||||||
|
this.showProgress = true;
|
||||||
|
this.progress = 0;
|
||||||
|
this.addModel = { model_name: this.selected_variant.name, binding_folder: this.configFile.binding_name, model_url: model_object.path }
|
||||||
|
console.log("installing...", this.addModel);
|
||||||
|
|
||||||
|
// Use an arrow function for progressListener
|
||||||
|
const progressListener = (response) => {
|
||||||
|
console.log("received something");
|
||||||
|
if (response.status && response.progress <= 100) {
|
||||||
|
this.addModel = response
|
||||||
|
console.log(`Progress`, response);
|
||||||
|
model_object.progress = response.progress
|
||||||
|
model_object.speed = response.speed
|
||||||
|
model_object.total_size = response.total_size
|
||||||
|
model_object.downloaded_size = response.downloaded_size
|
||||||
|
model_object.start_time = response.start_time
|
||||||
|
model_object.installing = true
|
||||||
|
if (model_object.progress == 100) {
|
||||||
|
const index = this.models.findIndex((model) => model.path === path);
|
||||||
|
this.models[index].isInstalled = true;
|
||||||
|
this.showProgress = false;
|
||||||
|
model_object.installing = false
|
||||||
|
|
||||||
|
console.log("Received succeeded")
|
||||||
|
socket.off('install_progress', progressListener);
|
||||||
|
console.log("Installed successfully")
|
||||||
|
// Update the isInstalled property of the corresponding model
|
||||||
|
|
||||||
|
this.$refs.toast.showToast("Model:\n" + model_object.title + "\ninstalled!", 4, true)
|
||||||
|
this.$store.dispatch('refreshDiskUsage');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
socket.off('install_progress', progressListener);
|
||||||
|
console.log("Install failed")
|
||||||
|
// Installation failed or encountered an error
|
||||||
|
model_object.installing = false;
|
||||||
|
|
||||||
|
this.showProgress = false;
|
||||||
|
console.error('Installation failed:', response.error);
|
||||||
|
this.$refs.toast.showToast("Model:\n" + model_object.title + "\nfailed to install!", 4, false)
|
||||||
|
this.$store.dispatch('refreshDiskUsage');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.on('install_progress', progressListener);
|
||||||
|
|
||||||
|
|
||||||
|
socket.emit('install_model', { path: path });
|
||||||
|
console.log("Started installation, please wait");
|
||||||
|
},
|
||||||
|
|
||||||
uploadAvatar(event){
|
uploadAvatar(event){
|
||||||
console.log("here")
|
|
||||||
const file = event.target.files[0]; // Get the selected file
|
const file = event.target.files[0]; // Get the selected file
|
||||||
const formData = new FormData(); // Create a FormData object
|
const formData = new FormData(); // Create a FormData object
|
||||||
formData.append('avatar', file); // Add the file to the form data with the key 'avatar'
|
formData.append('avatar', file); // Add the file to the form data with the key 'avatar'
|
||||||
@ -1870,61 +1953,10 @@ export default {
|
|||||||
// Model installation
|
// Model installation
|
||||||
|
|
||||||
onInstall(model_object) {
|
onInstall(model_object) {
|
||||||
if (model_object.linkNotValid) {
|
this.variant_choices = model_object.model.variants;
|
||||||
model_object.installing = false
|
this.currenModelToInstall = model_object;
|
||||||
this.$refs.toast.showToast("Link is not valid, file does not exist", 4, false)
|
console.log(this.variant_choices)
|
||||||
return
|
this.variantSelectionDialogVisible=true;
|
||||||
}
|
|
||||||
let path = model_object.path;
|
|
||||||
this.showProgress = true;
|
|
||||||
this.progress = 0;
|
|
||||||
this.addModel = { model_name: model_object.model.title, binding_folder: this.configFile.binding_name, model_url: model_object.path }
|
|
||||||
console.log("installing...", this.addModel);
|
|
||||||
|
|
||||||
// Use an arrow function for progressListener
|
|
||||||
const progressListener = (response) => {
|
|
||||||
console.log("received something");
|
|
||||||
if (response.status && response.progress <= 100) {
|
|
||||||
this.addModel = response
|
|
||||||
console.log(`Progress`, response);
|
|
||||||
model_object.progress = response.progress
|
|
||||||
model_object.speed = response.speed
|
|
||||||
model_object.total_size = response.total_size
|
|
||||||
model_object.downloaded_size = response.downloaded_size
|
|
||||||
model_object.start_time = response.start_time
|
|
||||||
model_object.installing = true
|
|
||||||
if (model_object.progress == 100) {
|
|
||||||
const index = this.models.findIndex((model) => model.path === path);
|
|
||||||
this.models[index].isInstalled = true;
|
|
||||||
this.showProgress = false;
|
|
||||||
model_object.installing = false
|
|
||||||
|
|
||||||
console.log("Received succeeded")
|
|
||||||
socket.off('install_progress', progressListener);
|
|
||||||
console.log("Installed successfully")
|
|
||||||
// Update the isInstalled property of the corresponding model
|
|
||||||
|
|
||||||
this.$refs.toast.showToast("Model:\n" + model_object.title + "\ninstalled!", 4, true)
|
|
||||||
this.$store.dispatch('refreshDiskUsage');
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
socket.off('install_progress', progressListener);
|
|
||||||
console.log("Install failed")
|
|
||||||
// Installation failed or encountered an error
|
|
||||||
model_object.installing = false;
|
|
||||||
|
|
||||||
this.showProgress = false;
|
|
||||||
console.error('Installation failed:', response.error);
|
|
||||||
this.$refs.toast.showToast("Model:\n" + model_object.title + "\nfailed to install!", 4, false)
|
|
||||||
this.$store.dispatch('refreshDiskUsage');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
socket.on('install_progress', progressListener);
|
|
||||||
|
|
||||||
|
|
||||||
socket.emit('install_model', { path: path });
|
|
||||||
console.log("Started installation, please wait");
|
|
||||||
},
|
},
|
||||||
onInstallAddModel() {
|
onInstallAddModel() {
|
||||||
|
|
||||||
@ -2371,7 +2403,6 @@ export default {
|
|||||||
|
|
||||||
},
|
},
|
||||||
async update_model(value) {
|
async update_model(value) {
|
||||||
console.log("hjsdfhksdjufkdshf")
|
|
||||||
if (!value) this.isModelSelected = false
|
if (!value) this.isModelSelected = false
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
this.isLoading = true
|
this.isLoading = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user