mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2025-01-29 15:44:12 +00:00
Added model listing and install (WIP)
This commit is contained in:
parent
91eaf1c786
commit
38a136e72f
57
app.py
57
app.py
@ -38,6 +38,7 @@ from pathlib import Path
|
||||
import gc
|
||||
from geventwebsocket.handler import WebSocketHandler
|
||||
from gevent.pywsgi import WSGIServer
|
||||
import requests
|
||||
|
||||
app = Flask("GPT4All-WebUI", static_url_path="/static", static_folder="static")
|
||||
socketio = SocketIO(app, cors_allowed_origins="*", async_mode='gevent', ping_timeout=30, ping_interval=15)
|
||||
@ -155,6 +156,16 @@ class Gpt4AllWebUI(GPT4AllAPI):
|
||||
self.add_endpoint(
|
||||
"/get_config", "get_config", self.get_config, methods=["GET"]
|
||||
)
|
||||
|
||||
self.add_endpoint(
|
||||
"/get_available_models", "get_available_models", self.get_available_models, methods=["GET"]
|
||||
)
|
||||
self.add_endpoint(
|
||||
"/install_model", "install_model", self.install_model, methods=["POST"]
|
||||
)
|
||||
self.add_endpoint(
|
||||
"/uninstall_model", "uninstall_model", self.uninstall_model, methods=["POST"]
|
||||
)
|
||||
|
||||
self.add_endpoint(
|
||||
"/extensions", "extensions", self.extensions, methods=["GET"]
|
||||
@ -687,6 +698,52 @@ class Gpt4AllWebUI(GPT4AllAPI):
|
||||
return jsonify({"status":"ok"})
|
||||
|
||||
|
||||
def get_available_models(self):
|
||||
response = requests.get(f' https://gpt4all.io/models/models.json')
|
||||
model_list = response.json()
|
||||
|
||||
models = []
|
||||
for model in model_list:
|
||||
filename = model['filename']
|
||||
filesize = model['filesize']
|
||||
path = f'https://gpt4all.io/models/{filename}'
|
||||
is_installed = Path(f'/models.llamacpp/{filename}').is_file()
|
||||
models.append({
|
||||
'title': model['filename'],
|
||||
'icon': '/icons/default.png', # Replace with the path to the model icon
|
||||
'description': model['description'],
|
||||
'isInstalled': is_installed,
|
||||
'path': path,
|
||||
'filesize': filesize,
|
||||
})
|
||||
return jsonify(models)
|
||||
|
||||
def install_model(self):
|
||||
model_path = request.json.get('path')
|
||||
installation_dir = Path('/models/llamacpp/')
|
||||
filename = Path(model_path).name
|
||||
installation_path = installation_dir / filename
|
||||
|
||||
if installation_path.exists():
|
||||
return jsonify({'status': 'Already installed'})
|
||||
|
||||
response = requests.get(model_path)
|
||||
with open(installation_path, 'wb') as f:
|
||||
f.write(response.content)
|
||||
return jsonify({'status':True})
|
||||
|
||||
def uninstall_model(self):
|
||||
model_path = request.json.get('path')
|
||||
installation_dir = Path('/models/llamacpp/')
|
||||
filename = Path(model_path).name
|
||||
installation_path = installation_dir / filename
|
||||
|
||||
if not installation_path.exists():
|
||||
return jsonify({'status':False})
|
||||
|
||||
installation_path.unlink()
|
||||
return jsonify({'status':True})
|
||||
|
||||
def get_config(self):
|
||||
return jsonify(self.config)
|
||||
|
||||
|
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
4
web/dist/index.html
vendored
@ -6,8 +6,8 @@
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>GPT4All - WEBUI</title>
|
||||
<script type="module" crossorigin src="/assets/index-9638e0a4.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-6cb502cf.css">
|
||||
<script type="module" crossorigin src="/assets/index-79091f1a.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-7089b32c.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
39
web/src/components/ModelEntry.vue
Normal file
39
web/src/components/ModelEntry.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="flex items-center space-x-4 py-4">
|
||||
<div class="flex-shrink-0">
|
||||
<i :class="`fas ${icon} text-xl`"></i>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<h3 class="font-bold text-lg">{{ title }}</h3>
|
||||
<p class="text-gray-600">{{ description }}</p>
|
||||
</div>
|
||||
<div class="flex-shrink-0">
|
||||
<button
|
||||
class="px-4 py-2 rounded-md text-white font-bold transition-colors duration-300"
|
||||
:class="[isInstalled ? 'bg-red-500 hover:bg-red-600' : 'bg-green-500 hover:bg-green-600']"
|
||||
@click="toggleInstall"
|
||||
>
|
||||
{{ isInstalled ? 'Uninstall' : 'Install' }}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
title: String,
|
||||
icon: String,
|
||||
path: String,
|
||||
description: String,
|
||||
isInstalled: Boolean,
|
||||
onToggleInstall: Function,
|
||||
},
|
||||
methods: {
|
||||
toggleInstall() {
|
||||
this.onToggleInstall(this.isInstalled, this.path);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -63,6 +63,18 @@
|
||||
|
||||
</select>
|
||||
</div>
|
||||
<div class="space-y-4">
|
||||
<model-entry
|
||||
v-for="(model, index) in models"
|
||||
:key="index"
|
||||
:title="model.title"
|
||||
:icon="model.icon"
|
||||
:path="model.path"
|
||||
:description="model.description"
|
||||
:is-installed="model.isInstalled"
|
||||
:on-toggle-install="toggleInstall"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -279,11 +291,13 @@ import feather from 'feather-icons'
|
||||
import { nextTick } from 'vue'
|
||||
import MessageBox from "@/components/MessageBox.vue";
|
||||
import YesNoDialog from "@/components/YesNoDialog.vue";
|
||||
import ModelEntry from '@/components/ModelEntry.vue';
|
||||
axios.defaults.baseURL = import.meta.env.VITE_GPT4ALL_API_BASEURL
|
||||
export default {
|
||||
components: {
|
||||
MessageBox,
|
||||
YesNoDialog
|
||||
YesNoDialog,
|
||||
ModelEntry
|
||||
},
|
||||
setup() {
|
||||
|
||||
@ -295,6 +309,8 @@ export default {
|
||||
data() {
|
||||
|
||||
return {
|
||||
// Models zoo installer stuff
|
||||
models: [],
|
||||
// Accordeon stuff
|
||||
bec_collapsed: false,
|
||||
pc_collapsed: false,
|
||||
@ -310,7 +326,33 @@ export default {
|
||||
showConfirmation:false
|
||||
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.fetchModels();
|
||||
}, methods: {
|
||||
fetchModels() {
|
||||
axios.get('/get_available_models')
|
||||
.then(response => {
|
||||
this.models = response.data;
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
});
|
||||
},
|
||||
// Model installation
|
||||
toggleInstall(isInstalled, path) {
|
||||
const endpoint = isInstalled ? '/uninstall_model' : '/install_model';
|
||||
axios.post(endpoint, { path })
|
||||
.then((response) => {
|
||||
console.log(response.data.status);
|
||||
// Update the isInstalled property of the corresponding model
|
||||
const index = this.models.findIndex((model) => model.path === path);
|
||||
this.$set(this.models[index], 'isInstalled', isInstalled);
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error(error);
|
||||
});
|
||||
},
|
||||
// messagebox ok stuff
|
||||
onMessageBoxOk() {
|
||||
console.log("OK button clicked");
|
||||
|
Loading…
x
Reference in New Issue
Block a user