mirror of
https://github.com/ParisNeo/lollms-webui.git
synced 2024-12-18 20:17:50 +00:00
Merge pull request #229 from andzejsp/model-entry-fixes
Model entry fixes and bunch more stuff
This commit is contained in:
commit
f4e177e948
BIN
docs/dev/assets/audio/chime/chime_aud.wav
Normal file
BIN
docs/dev/assets/audio/chime/chime_aud.wav
Normal file
Binary file not shown.
BIN
docs/dev/assets/audio/chime/dong.mmpz
Normal file
BIN
docs/dev/assets/audio/chime/dong.mmpz
Normal file
Binary file not shown.
BIN
docs/dev/assets/audio/chime/dong.wav
Normal file
BIN
docs/dev/assets/audio/chime/dong.wav
Normal file
Binary file not shown.
File diff suppressed because one or more lines are too long
1
web/dist/assets/index-99ba4d99.css
vendored
Normal file
1
web/dist/assets/index-99ba4d99.css
vendored
Normal file
File diff suppressed because one or more lines are too long
1
web/dist/assets/index-eacf4bd4.css
vendored
1
web/dist/assets/index-eacf4bd4.css
vendored
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-b192126f.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-eacf4bd4.css">
|
||||
<script type="module" crossorigin src="/assets/index-4ec4d9d4.js"></script>
|
||||
<link rel="stylesheet" href="/assets/index-99ba4d99.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
84
web/src/components/BindingEntry.vue
Normal file
84
web/src/components/BindingEntry.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<div class=" items-start p-4 hover:bg-primary-light rounded-lg mb-2 shadow-lg border-2 cursor-pointer"
|
||||
@click.stop="toggleSelected" :class="selected ? ' border-primary-light' : 'border-transparent'">
|
||||
|
||||
|
||||
<div class="flex flex-row items-center flex-shrink-0 gap-3">
|
||||
<img :src="getImgUrl()" @error="defaultImg($event)" class="w-10 h-10 rounded-full object-fill text-red-700">
|
||||
<h3 class="font-bold font-large text-lg line-clamp-3">
|
||||
{{ binding.name }}
|
||||
</h3>
|
||||
|
||||
|
||||
</div>
|
||||
<div class="">
|
||||
<div class="">
|
||||
|
||||
<div class="flex items-center">
|
||||
<i data-feather="user" class="w-5 m-1"></i>
|
||||
<b>Author: </b>
|
||||
|
||||
{{ binding.author }}
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<i data-feather="folder" class="w-5 m-1"></i>
|
||||
<b>Folder: </b>
|
||||
|
||||
{{ binding.folder }}
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<i data-feather="git-merge" class="w-5 m-1"></i>
|
||||
<b>Version: </b>
|
||||
{{ binding.version }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<i data-feather="info" class="w-5 m-1"></i>
|
||||
<b>Description: </b><br>
|
||||
</div>
|
||||
<p class="mx-1 opacity-80 line-clamp-3" :title="binding.description">{{ binding.description }}</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { nextTick } from 'vue'
|
||||
import feather from 'feather-icons'
|
||||
import botImgPlaceholder from "../assets/logo.svg"
|
||||
import userImgPlaceholder from "../assets/default_user.svg"
|
||||
const bUrl = import.meta.env.VITE_GPT4ALL_API_BASEURL
|
||||
export default {
|
||||
props: {
|
||||
binding: {},
|
||||
onSelected: Function,
|
||||
selected: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
nextTick(() => {
|
||||
feather.replace()
|
||||
|
||||
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
getImgUrl() {
|
||||
return bUrl + this.binding.icon
|
||||
},
|
||||
defaultImg(event) {
|
||||
event.target.src = botImgPlaceholder
|
||||
},
|
||||
toggleSelected() {
|
||||
this.onSelected(this)
|
||||
},
|
||||
|
||||
}
|
||||
};
|
||||
</script>
|
@ -120,7 +120,7 @@ export default {
|
||||
}, methods: {
|
||||
copyContentToClipboard() {
|
||||
this.$emit('copy', this.message.content)
|
||||
navigator.clipboard.writeText(this.message.content);
|
||||
|
||||
},
|
||||
deleteMsg() {
|
||||
this.$emit('delete', this.message.id)
|
||||
|
@ -13,37 +13,56 @@
|
||||
</div>
|
||||
<div class="flex-1" v-if="!model.isCustomModel">
|
||||
<div class="flex gap-3 items-center">
|
||||
<img :src="getImgUrl()" @error="defaultImg($event)" class="w-10 h-10 rounded-lg object-fill">
|
||||
<img :src="getImgUrl()" @error="defaultImg($event)" class="w-10 h-10 rounded-lg object-fill" :class="linkNotValid ? 'grayscale':''">
|
||||
<h3 class="font-bold font-large text-lg">
|
||||
{{ title }}
|
||||
</h3>
|
||||
</div>
|
||||
<div class="flex flex-shrink-0">
|
||||
<div class="flex flex-shrink-0 items-center ">
|
||||
<i data-feather="link" class="w-5 m-1" ></i>
|
||||
<b>Manual download: </b>
|
||||
<a :href="path" @click.stop class="flex hover:text-secondary duration-75 active:scale-90"
|
||||
|
||||
<a :href="path" @click.stop class="flex items-center hover:text-secondary duration-75 active:scale-90"
|
||||
title="Download this manually (faster) and put it in the models/<your binding> folder then refresh">
|
||||
<i data-feather="link" class="w-5 p-1"></i>
|
||||
|
||||
|
||||
{{ title }}
|
||||
|
||||
</a>
|
||||
</div>
|
||||
<div class="flex flex-shrink-0">
|
||||
<div class="flex flex-shrink-0 items-center">
|
||||
<div class="flex flex-shrink-0 items-center" :class="linkNotValid? 'text-red-600':''">
|
||||
<i data-feather="file" class="w-5 m-1"></i>
|
||||
|
||||
<b>File size: </b>
|
||||
|
||||
{{ fileSize }}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="flex flex-shrink-0 items-center">
|
||||
<i data-feather="key" class="w-5 m-1"></i>
|
||||
<b>License: </b>
|
||||
{{ license }}
|
||||
</div>
|
||||
<div class="flex flex-shrink-0">
|
||||
<div class="flex flex-shrink-0 items-center">
|
||||
<i data-feather="user" class="w-5 m-1"></i>
|
||||
<b>Owner: </b>
|
||||
<a :href="owner_link" target="_blank" @click.stop class="flex hover:text-secondary duration-75 active:scale-90"
|
||||
<a :href="owner_link" target="_blank" rel="noopener noreferrer" @click.stop class="flex hover:text-secondary duration-75 active:scale-90"
|
||||
title="Owner's profile">
|
||||
<i data-feather="link" class="w-5 p-1"></i>
|
||||
|
||||
{{ owner }}
|
||||
</a>
|
||||
</div>
|
||||
<b>Description: </b><br>
|
||||
<p class="opacity-80">{{ description }}</p>
|
||||
<div class="flex items-center">
|
||||
<i data-feather="info" class="w-5 m-1"></i>
|
||||
<b>Description: </b><br>
|
||||
</div>
|
||||
<p class="mx-1 opacity-80">{{ description }}</p>
|
||||
</div>
|
||||
<div class="flex-shrink-0" v-if="!model.isCustomModel">
|
||||
<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']"
|
||||
:class="[isInstalled ? 'bg-red-500 hover:bg-red-600' : linkNotValid ? 'bg-gray-500 hover:bg-gray-600' : 'bg-green-500 hover:bg-green-600']"
|
||||
:disabled="installing || uninstalling" @click.stop="toggleInstall">
|
||||
<template v-if="installing">
|
||||
<div class="flex items-center space-x-2">
|
||||
@ -62,7 +81,7 @@
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
{{ isInstalled ? 'Uninstall' : 'Install' }}
|
||||
{{ isInstalled ? model.isCustomModel ? 'Delete' : 'Uninstall' : linkNotValid ? 'Link is not valid':'Install' }}
|
||||
</template>
|
||||
</button>
|
||||
</div>
|
||||
@ -71,6 +90,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import { nextTick } from 'vue'
|
||||
import feather from 'feather-icons'
|
||||
import defaultImgPlaceholder from "../assets/default_model.png"
|
||||
@ -96,10 +116,14 @@ export default {
|
||||
progress: 0,
|
||||
installing: false,
|
||||
uninstalling: false,
|
||||
failedToLoad: false
|
||||
failedToLoad: false,
|
||||
fileSize: '',
|
||||
linkNotValid:false,
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
async mounted() {
|
||||
this.fileSize = await this.getFileSize(this.model.path)
|
||||
//console.log('model path', this.model.path)
|
||||
nextTick(() => {
|
||||
feather.replace()
|
||||
|
||||
@ -107,6 +131,88 @@ export default {
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
async getFileSize(url) {
|
||||
try {
|
||||
|
||||
const res = await axios.head(url)
|
||||
//console.log("addddd",url, res.headers)
|
||||
if (res) {
|
||||
|
||||
if (res.headers["content-length"]) {
|
||||
return this.humanFileSize(res.headers["content-length"])
|
||||
}
|
||||
if (this.model.filesize) {
|
||||
return this.humanFileSize(this.model.filesize)
|
||||
}
|
||||
return 'Could not be determined'
|
||||
|
||||
}
|
||||
if (this.model.filesize) {
|
||||
|
||||
return this.humanFileSize(this.model.filesize)
|
||||
}
|
||||
return 'Could not be determined'
|
||||
|
||||
// Example response
|
||||
// {
|
||||
// date: 'Tue, 03 Apr 2018 14:29:32 GMT',
|
||||
// 'content-type': 'application/javascript; charset=utf-8',
|
||||
// 'content-length': '9068',
|
||||
// connection: 'close',
|
||||
// 'last-modified': 'Wed, 28 Feb 2018 04:16:30 GMT',
|
||||
// etag: '"5a962d1e-236c"',
|
||||
// expires: 'Sun, 24 Mar 2019 14:29:32 GMT',
|
||||
// 'cache-control': 'public, max-age=30672000',
|
||||
// 'access-control-allow-origin': '*',
|
||||
// 'cf-cache-status': 'HIT',
|
||||
// 'accept-ranges': 'bytes',
|
||||
// 'strict-transport-security': 'max-age=15780000; includeSubDomains',
|
||||
// 'expect-ct': 'max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"',
|
||||
// server: 'cloudflare',
|
||||
// 'cf-ray': '405c3a5cba7a68ba-CDG'
|
||||
// }
|
||||
|
||||
|
||||
} catch (error) {
|
||||
console.log(error.message,'getFileSize')
|
||||
this.linkNotValid=true
|
||||
return 'Could not be determined'
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
/** From https://stackoverflow.com/a/14919494/14106028
|
||||
* Format bytes as human-readable text.
|
||||
*
|
||||
* @param bytes Number of bytes.
|
||||
* @param si True to use metric (SI) units, aka powers of 1000. False to use
|
||||
* binary (IEC), aka powers of 1024.
|
||||
* @param dp Number of decimal places to display.
|
||||
*
|
||||
* @return Formatted string.
|
||||
*/
|
||||
humanFileSize(bytes, si = false, dp = 1) {
|
||||
const thresh = si ? 1000 : 1024;
|
||||
|
||||
if (Math.abs(bytes) < thresh) {
|
||||
return bytes + ' B';
|
||||
}
|
||||
|
||||
const units = si
|
||||
? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
|
||||
: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
|
||||
let u = -1;
|
||||
const r = 10 ** dp;
|
||||
|
||||
do {
|
||||
bytes /= thresh;
|
||||
++u;
|
||||
} while (Math.round(Math.abs(bytes) * r) / r >= thresh && u < units.length - 1);
|
||||
|
||||
|
||||
return bytes.toFixed(dp) + ' ' + units[u];
|
||||
},
|
||||
|
||||
getImgUrl() {
|
||||
|
||||
if (this.icon === '/images/default_model.png') {
|
||||
@ -137,6 +243,15 @@ export default {
|
||||
this.onSelected(this);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch:{
|
||||
linkNotValid(){
|
||||
nextTick(() => {
|
||||
feather.replace()
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@ -14,8 +14,10 @@
|
||||
<div class="">
|
||||
<div class="">
|
||||
|
||||
<div class="">
|
||||
<b>Author: </b>
|
||||
<div class="flex items-center">
|
||||
<i data-feather="user" class="w-5 m-1"></i>
|
||||
<b>Author: </b>
|
||||
|
||||
{{ personality.author }}
|
||||
</div>
|
||||
<!-- <div class="">
|
||||
@ -27,9 +29,11 @@
|
||||
{{ personality.category }}
|
||||
</div> -->
|
||||
</div>
|
||||
<b>Description: </b><br>
|
||||
|
||||
<p class="opacity-80 line-clamp-3" :title="personality.description">{{ personality.description }}</p>
|
||||
<div class="flex items-center">
|
||||
<i data-feather="info" class="w-5 m-1"></i>
|
||||
<b>Description: </b><br>
|
||||
</div>
|
||||
<p class="mx-1 opacity-80 line-clamp-3" :title="personality.description">{{ personality.description }}</p>
|
||||
|
||||
|
||||
</div>
|
||||
|
@ -168,24 +168,7 @@
|
||||
|
||||
|
||||
<style scoped>
|
||||
.expand-enter-active,
|
||||
.expand-leave-active {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.expand-enter{
|
||||
transition: all 0.5s ease;
|
||||
opacity: 1;
|
||||
transform: translatey(30px);
|
||||
}
|
||||
.expand-leave-to {
|
||||
|
||||
transform: translatey(-30px);
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* THESE ARE FOR TransitionGroup components */
|
||||
.list-move, /* apply transition to moving elements */
|
||||
.list-enter-active,
|
||||
.list-leave-active {
|
||||
@ -241,7 +224,7 @@ export default {
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
console.log(error.message,'api_get_req')
|
||||
return
|
||||
}
|
||||
|
||||
@ -257,7 +240,7 @@ export default {
|
||||
return res.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error: Could not list discussions", error)
|
||||
console.log("Error: Could not list discussions", error.message)
|
||||
return []
|
||||
}
|
||||
},
|
||||
@ -278,7 +261,7 @@ export default {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
console.log(error.message,'load_discussion')
|
||||
this.loading = false
|
||||
this.setDiscussionLoading(id, this.loading)
|
||||
}
|
||||
@ -291,7 +274,7 @@ export default {
|
||||
return res.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error: Could not create new discussion", error)
|
||||
console.log("Error: Could not create new discussion", error.message)
|
||||
return {}
|
||||
}
|
||||
},
|
||||
@ -307,7 +290,7 @@ export default {
|
||||
this.setDiscussionLoading(id, this.loading)
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error: Could not delete discussion", error)
|
||||
console.log("Error: Could not delete discussion", error.message)
|
||||
this.loading = false
|
||||
this.setDiscussionLoading(id, this.loading)
|
||||
}
|
||||
@ -331,7 +314,7 @@ export default {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error: Could not edit title", error)
|
||||
console.log("Error: Could not edit title", error.message)
|
||||
this.loading = false
|
||||
this.setDiscussionLoading(id, this.loading)
|
||||
}
|
||||
@ -344,7 +327,7 @@ export default {
|
||||
return res.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error: Could delete message", error)
|
||||
console.log("Error: Could delete message", error.message)
|
||||
return {}
|
||||
}
|
||||
},
|
||||
@ -356,7 +339,7 @@ export default {
|
||||
return res.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error: Could not stop generating", error)
|
||||
console.log("Error: Could not stop generating", error.message)
|
||||
return {}
|
||||
}
|
||||
},
|
||||
@ -368,7 +351,7 @@ export default {
|
||||
return res.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error: Could not rank up message", error)
|
||||
console.log("Error: Could not rank up message", error.message)
|
||||
return {}
|
||||
}
|
||||
},
|
||||
@ -380,7 +363,7 @@ export default {
|
||||
return res.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error: Could not rank down message", error)
|
||||
console.log("Error: Could not rank down message", error.message)
|
||||
return {}
|
||||
}
|
||||
},
|
||||
@ -392,7 +375,7 @@ export default {
|
||||
return res.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error: Could not update message", error)
|
||||
console.log("Error: Could not update message", error.message)
|
||||
return {}
|
||||
}
|
||||
},
|
||||
@ -409,7 +392,7 @@ export default {
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.log("Error: Could not export multiple discussions", error)
|
||||
console.log("Error: Could not export multiple discussions", error.message)
|
||||
return {}
|
||||
}
|
||||
},
|
||||
@ -419,7 +402,12 @@ export default {
|
||||
if (!this.filterInProgress) {
|
||||
this.filterInProgress = true
|
||||
setTimeout(() => {
|
||||
this.list = this.tempList.filter((item) => item.title && item.title.includes(this.filterTitle))
|
||||
if(this.filterTitle){
|
||||
this.list = this.tempList.filter((item) => item.title && item.title.includes(this.filterTitle))
|
||||
|
||||
}else{
|
||||
this.list = this.tempList
|
||||
}
|
||||
this.filterInProgress = false
|
||||
}, 100)
|
||||
}
|
||||
@ -567,7 +555,7 @@ export default {
|
||||
sendMsg(msg) {
|
||||
// Sends message to binding
|
||||
if(!msg){
|
||||
this.$refs.toast.showToast("Message contains no centent!", 4, false)
|
||||
this.$refs.toast.showToast("Message contains no content!", 4, false)
|
||||
return
|
||||
}
|
||||
this.isGenerating = true;
|
||||
@ -599,11 +587,8 @@ export default {
|
||||
},
|
||||
streamMessageContent(msgObj) {
|
||||
// Streams response message content from binding
|
||||
//console.log("stream", JSON.stringify(content))
|
||||
const parent = msgObj.user_message_id
|
||||
const discussion_id = msgObj.discussion_id
|
||||
// next statement - incorrect comparison: was '=' and should be '=='
|
||||
|
||||
this.setDiscussionLoading(discussion_id, true);
|
||||
if (this.currentDiscussion.id == discussion_id) {
|
||||
|
||||
@ -612,14 +597,10 @@ export default {
|
||||
const messageItem = this.discussionArr[index]
|
||||
if (messageItem) {
|
||||
messageItem.content = msgObj.data
|
||||
//console.log("user-msg-id",parent, "ai-msg-id",msgObj.ai_message_id, index, discussion_id, msgObj.data)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//const lastMsg = this.discussionArr[this.discussionArr.length - 1]
|
||||
//lastMsg.content = content.data
|
||||
},
|
||||
async changeTitleUsingUserMSG(id, msg) {
|
||||
// If discussion is untitled or title is null then it sets the title to first user message.
|
||||
@ -649,7 +630,6 @@ export default {
|
||||
const selectedDisElement = document.getElementById('dis-' + res.id)
|
||||
this.scrollToElement(selectedDisElement)
|
||||
})
|
||||
//console.log("disc",JSON.stringify(discussionItem))
|
||||
},
|
||||
loadLastUsedDiscussion() {
|
||||
// Checks local storage for last selected discussion
|
||||
@ -665,9 +645,6 @@ export default {
|
||||
async deleteDiscussion(id) {
|
||||
// Deletes discussion from binding and frontend
|
||||
|
||||
//const index = this.list.findIndex((x) => x.id == id)
|
||||
//const discussionItem = this.list[index]
|
||||
//discussionItem.loading = true
|
||||
await this.delete_discussion(id)
|
||||
if (this.currentDiscussion.id == id) {
|
||||
this.currentDiscussion = {}
|
||||
@ -677,7 +654,6 @@ export default {
|
||||
this.list.splice(this.list.findIndex(item => item.id == id), 1)
|
||||
|
||||
this.createDiscussionList(this.list)
|
||||
//await this.list_discussions()
|
||||
},
|
||||
async deleteDiscussionMulti() {
|
||||
// Delete selected discussions
|
||||
@ -697,6 +673,8 @@ export default {
|
||||
}
|
||||
this.tempList = this.list
|
||||
this.isCheckbox = false
|
||||
this.$refs.toast.showToast("Removed ("+deleteList.length+") items", 4, true)
|
||||
|
||||
console.log("Multi delete done")
|
||||
},
|
||||
async deleteMessage(msgId) {
|
||||
@ -706,7 +684,7 @@ export default {
|
||||
this.discussionArr.splice(this.discussionArr.findIndex(item => item.id == msgId), 1)
|
||||
|
||||
}).catch(() => {
|
||||
|
||||
this.$refs.toast.showToast("Could not remove message", 4, false)
|
||||
console.log("Error: Could not delete message")
|
||||
})
|
||||
|
||||
@ -788,7 +766,7 @@ export default {
|
||||
const message = this.discussionArr[this.discussionArr.findIndex(item => item.id == msgId)]
|
||||
message.rank = res.new_rank
|
||||
}).catch(() => {
|
||||
|
||||
this.$refs.toast.showToast("Could not rank up message", 4, false)
|
||||
console.log("Error: Could not rank up message")
|
||||
})
|
||||
|
||||
@ -799,6 +777,7 @@ export default {
|
||||
const message = this.discussionArr[this.discussionArr.findIndex(item => item.id == msgId)]
|
||||
message.rank = res.new_rank
|
||||
}).catch(() => {
|
||||
this.$refs.toast.showToast("Could not rank down message", 4, false)
|
||||
|
||||
console.log("Error: Could not rank down message")
|
||||
})
|
||||
@ -811,6 +790,7 @@ export default {
|
||||
message.content = msg
|
||||
|
||||
}).catch(() => {
|
||||
this.$refs.toast.showToast("Could not update message", 4, false)
|
||||
|
||||
console.log("Error: Could not update message")
|
||||
})
|
||||
@ -861,8 +841,9 @@ export default {
|
||||
this.chime.play()
|
||||
},
|
||||
copyToClipBoard(content) {
|
||||
|
||||
this.$refs.toast.showToast("Copied to clipboard successfully")
|
||||
this.$refs.toast.showToast("Copied to clipboard successfully", 4, true)
|
||||
navigator.clipboard.writeText(content);
|
||||
|
||||
nextTick(() => {
|
||||
feather.replace()
|
||||
|
||||
@ -965,9 +946,7 @@ export default {
|
||||
}
|
||||
return newItem
|
||||
})
|
||||
// const index = personalities.findIndex((x) => x.name === sender)
|
||||
// const pers = personalities[index]
|
||||
// return pers.avatar
|
||||
|
||||
|
||||
},
|
||||
getAvatar(sender) {
|
||||
|
@ -65,7 +65,64 @@
|
||||
</div>
|
||||
|
||||
<div :class="isLoading ? 'pointer-events-none opacity-30' : ''">
|
||||
<!-- BINDING ZOO -->
|
||||
<div
|
||||
class="flex flex-col mb-2 rounded-lg bg-bg-light-tone dark:bg-bg-dark-tone hover:bg-bg-light-tone-panel hover:dark:bg-bg-dark-tone-panel duration-150 shadow-lg">
|
||||
<div class="flex flex-row p-3">
|
||||
<button @click.stop="bzc_collapsed = !bzc_collapsed"
|
||||
class="text-2xl hover:text-primary duration-75 p-2 -m-2 w-full text-left active:translate-y-1 flex flex-row items-center">
|
||||
<i data-feather="chevron-right" class="mr-2"></i>
|
||||
|
||||
<h3 class="text-lg font-semibold cursor-pointer select-none mr-2">
|
||||
Binding zoo</h3>
|
||||
<div v-if="configFile.binding" class="mr-2">|</div>
|
||||
|
||||
<div v-if="configFile.binding" class=" text-base font-semibold cursor-pointer select-none items-center">
|
||||
{{configFile.binding}} </div>
|
||||
</button>
|
||||
</div>
|
||||
<div :class="{ 'hidden': bzc_collapsed }" class="flex flex-col mb-2 px-3 pb-0">
|
||||
<!-- <div class="mx-2 mb-4">
|
||||
<label for="binding" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
|
||||
Bindings: ({{ bindingsArr.length }})
|
||||
</label>
|
||||
<select id="binding" @change="update_binding($event.target.value)"
|
||||
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 in bindingsArr" :selected="item.folder === configFile.binding"
|
||||
:value="item.folder">
|
||||
{{ item.name }} by ({{ item.author }})
|
||||
</option>
|
||||
</select>
|
||||
</div> -->
|
||||
<div v-if="bindings.length > 0" class="mb-2">
|
||||
<label for="binding" class="block ml-2 mb-2 text-sm font-medium text-gray-900 dark:text-white">
|
||||
Bindings: ({{ bindings.length }})
|
||||
</label>
|
||||
<div ref="bindingZoo" class="overflow-y-auto no-scrollbar p-2 pb-0 grid lg:grid-cols-3 md:grid-cols-2 gap-4"
|
||||
:class="bzl_collapsed ? '' : 'max-h-96'">
|
||||
<TransitionGroup name="list">
|
||||
<BindingEntry v-for="(binding, index) in bindings"
|
||||
:key="'index-' + index + '-' + binding.folder" :binding="binding" :on-selected="onSelectedBinding" :selected="binding.folder === configFile.binding"></BindingEntry>
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- EXPAND / COLLAPSE BUTTON -->
|
||||
<button v-if="bzl_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="bzl_collapsed = !bzl_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="bzl_collapsed = !bzl_collapsed">
|
||||
<i data-feather="chevron-down"></i>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- MODELS ZOO -->
|
||||
<div
|
||||
@ -74,37 +131,29 @@
|
||||
<button @click.stop="mzc_collapsed = !mzc_collapsed"
|
||||
class="text-2xl hover:text-primary duration-75 p-2 -m-2 w-full text-left active:translate-y-1 flex items-center">
|
||||
<i :data-feather="mzc_collapsed ? 'chevron-right' : 'chevron-down'" class="mr-2"></i>
|
||||
<h3 class="text-lg font-semibold cursor-pointer select-none">
|
||||
<h3 class="text-lg font-semibold cursor-pointer select-none mr-2">
|
||||
Models zoo</h3>
|
||||
<div v-if="configFile.model" class="mr-2">|</div>
|
||||
<div v-if="configFile.model" class=" text-base font-semibold cursor-pointer select-none items-center">
|
||||
{{configFile.model}} </div>
|
||||
</button>
|
||||
</div>
|
||||
<div :class="{ 'hidden': mzc_collapsed }" class="flex flex-col mb-2 px-3 pb-0">
|
||||
<div class="mx-2 mb-4">
|
||||
<label for="binding" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">
|
||||
Binding: ({{ bindingsArr.length }})
|
||||
</label>
|
||||
<select id="binding" @change="update_binding($event.target.value)"
|
||||
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 in bindingsArr" :selected="item.folder === configFile.binding" :value="item.folder">
|
||||
{{ item.name }} by ({{item.author}})
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div v-if="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">
|
||||
Models: ({{ models.length }})
|
||||
</label>
|
||||
<div ref="modelZoo" class="overflow-y-auto no-scrollbar p-2 pb-0 "
|
||||
:class="mzl_collapsed ? '' : 'max-h-96'">
|
||||
<TransitionGroup name="list" >
|
||||
<model-entry v-for="(model, index) in models" :key="index" :title="model.title"
|
||||
:icon="model.icon" :path="model.path" :owner="model.owner" :owner_link="model.owner_link"
|
||||
:license="model.license" :description="model.description" :is-installed="model.isInstalled"
|
||||
:on-install="onInstall" :on-uninstall="onUninstall" :on-selected="onSelected"
|
||||
:selected="model.title === configFile.model" :model="model" />
|
||||
<TransitionGroup name="list">
|
||||
<model-entry v-for="(model, index) in models" :key="'index-' + index + '-' + model.title"
|
||||
:title="model.title" :icon="model.icon" :path="model.path" :owner="model.owner"
|
||||
:owner_link="model.owner_link" :license="model.license" :description="model.description"
|
||||
:is-installed="model.isInstalled" :on-install="onInstall" :on-uninstall="onUninstall"
|
||||
:on-selected="onSelected" :selected="model.title === configFile.model" :model="model" />
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- EXPAND / COLLAPSE BUTTON -->
|
||||
<button v-if="mzl_collapsed"
|
||||
@ -130,8 +179,12 @@
|
||||
<button @click.stop="pzc_collapsed = !pzc_collapsed"
|
||||
class="text-2xl hover:text-primary duration-75 p-2 -m-2 w-full text-left active:translate-y-1 flex items-center">
|
||||
<i :data-feather="pzc_collapsed ? 'chevron-right' : 'chevron-down'" class="mr-2"></i>
|
||||
<h3 class="text-lg font-semibold cursor-pointer select-none">
|
||||
<h3 class="text-lg font-semibold cursor-pointer select-none mr-2">
|
||||
Personalities zoo</h3>
|
||||
<div v-if="configFile.personality" class="mr-2">|</div>
|
||||
|
||||
<div v-if="configFile.personality" class=" text-base font-semibold cursor-pointer select-none items-center">
|
||||
{{configFile.personality}} </div>
|
||||
</button>
|
||||
</div>
|
||||
<div :class="{ 'hidden': pzc_collapsed }" class="flex flex-col mb-2 px-3 pb-0">
|
||||
@ -183,11 +236,11 @@
|
||||
<div ref="personalitiesZoo"
|
||||
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" >
|
||||
<personality-entry v-for="(pers, index) in personalitiesFiltered" :key="index"
|
||||
:personality="pers"
|
||||
:selected="pers.name === configFile.personality && pers.category === configFile.personality_category && pers.language === configFile.personality_language"
|
||||
:on-selected="onPersonalitySelected" />
|
||||
<TransitionGroup name="bounce">
|
||||
<personality-entry v-for="(pers, index) in personalitiesFiltered"
|
||||
:key="'index-' + index + '-' + pers.name" :personality="pers"
|
||||
:selected="pers.name === configFile.personality && pers.category === configFile.personality_category && pers.language === configFile.personality_language"
|
||||
:on-selected="onPersonalitySelected" />
|
||||
</TransitionGroup>
|
||||
</div>
|
||||
</div>
|
||||
@ -224,7 +277,8 @@
|
||||
|
||||
<input id="override-model-parameters" type="checkbox"
|
||||
class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-700 dark:focus:ring-offset-gray-700 focus:ring-2 dark:bg-gray-600 dark:border-gray-500"
|
||||
@click.stop v-model="configFile.override_personality_model_parameters" @change="update_setting('override_personality_model_parameters', configFile.override_personality_model_parameters)">
|
||||
@click.stop v-model="configFile.override_personality_model_parameters"
|
||||
@change="update_setting('override_personality_model_parameters', configFile.override_personality_model_parameters)">
|
||||
<label for="override-model-parameters" class="block text-sm font-medium ">
|
||||
Override personality model parameters
|
||||
</label>
|
||||
@ -235,141 +289,141 @@
|
||||
<!-- DISABLE PARAMETER SELECTION -->
|
||||
<div :class="!configFile.override_personality_model_parameters ? 'pointer-events-none opacity-30' : ''">
|
||||
|
||||
|
||||
<div class="m-2">
|
||||
<label for="seed" class="block mb-2 text-sm font-medium ">
|
||||
Seed:
|
||||
</label>
|
||||
<input type="text" id="seed" v-model="configFile.seed"
|
||||
class="bg-gray-50 border border-gray-300 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:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="temperature" class=" text-sm font-medium">
|
||||
Temperature:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="temp-val" v-model="configFile.temperature"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
<div class="m-2">
|
||||
<label for="seed" class="block mb-2 text-sm font-medium ">
|
||||
Seed:
|
||||
</label>
|
||||
<input type="text" id="seed" v-model="configFile.seed"
|
||||
class="bg-gray-50 border border-gray-300 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:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="temperature" class=" text-sm font-medium">
|
||||
Temperature:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="temp-val" v-model="configFile.temperature"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="temperature" @change="update_setting('temperature', $event.target.value)"
|
||||
type="range" v-model="configFile.temperature" min="0" max="5" step="0.1"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="predict" class=" text-sm font-medium">
|
||||
N Predict:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input id="temperature" @change="update_setting('temperature', $event.target.value)"
|
||||
type="range" v-model="configFile.temperature" min="0" max="5" step="0.1"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
<input type="text" id="predict-val" v-model="configFile.n_predict"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="predict" @change="update_setting('n_predict', $event.target.value)" type="range"
|
||||
v-model="configFile.n_predict" min="0" max="2048" step="32"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="top_k" class=" text-sm font-medium">
|
||||
Top-K:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="top_k-val" v-model="configFile.top_k"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="top_k" @change="update_setting('top_k', $event.target.value)" type="range"
|
||||
v-model="configFile.top_k" min="0" max="100" step="1"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="top_p" class=" text-sm font-medium">
|
||||
Top-P:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="top_p-val" v-model="configFile.top_p"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="top_p" @change="update_setting('top_p', $event.target.value)" type="range"
|
||||
v-model="configFile.top_p" min="0" max="1" step="0.01"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="repeat_penalty" class=" text-sm font-medium">
|
||||
Repeat penalty:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="repeat_penalty-val" v-model="configFile.repeat_penalty"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="repeat_penalty" @change="update_setting('repeat_penalty', $event.target.value)"
|
||||
type="range" v-model="configFile.repeat_penalty" min="0" max="2" step="0.01"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="repeat_last_n" class=" text-sm font-medium">
|
||||
Repeat last N:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="repeat_last_n-val" v-model="configFile.repeat_last_n"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="repeat_last_n" @change="update_setting('repeat_last_n', $event.target.value)"
|
||||
type="range" v-model="configFile.repeat_last_n" min="0" max="100" step="1"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="predict" class=" text-sm font-medium">
|
||||
N Predict:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="predict-val" v-model="configFile.n_predict"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="predict" @change="update_setting('n_predict', $event.target.value)" type="range"
|
||||
v-model="configFile.n_predict" min="0" max="2048" step="32"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="top_k" class=" text-sm font-medium">
|
||||
Top-K:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="top_k-val" v-model="configFile.top_k"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="top_k" @change="update_setting('top_k', $event.target.value)" type="range"
|
||||
v-model="configFile.top_k" min="0" max="100" step="1"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="top_p" class=" text-sm font-medium">
|
||||
Top-P:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="top_p-val" v-model="configFile.top_p"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="top_p" @change="update_setting('top_p', $event.target.value)" type="range"
|
||||
v-model="configFile.top_p" min="0" max="1" step="0.01"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="repeat_penalty" class=" text-sm font-medium">
|
||||
Repeat penalty:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="repeat_penalty-val" v-model="configFile.repeat_penalty"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="repeat_penalty" @change="update_setting('repeat_penalty', $event.target.value)"
|
||||
type="range" v-model="configFile.repeat_penalty" min="0" max="2" step="0.01"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-2">
|
||||
<div class="flex flex-col align-bottom ">
|
||||
<div class="relative">
|
||||
<p class="absolute left-0 mt-6">
|
||||
<label for="repeat_last_n" class=" text-sm font-medium">
|
||||
Repeat last N:
|
||||
</label>
|
||||
</p>
|
||||
<p class="absolute right-0">
|
||||
|
||||
<input type="text" id="repeat_last_n-val" v-model="configFile.repeat_last_n"
|
||||
class="mt-2 w-16 text-right p-2 border border-gray-300 rounded-lg bg-gray-50 sm:text-xs focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
<input id="repeat_last_n" @change="update_setting('repeat_last_n', $event.target.value)"
|
||||
type="range" v-model="configFile.repeat_last_n" min="0" max="100" step="1"
|
||||
class="flex-none h-2 mt-14 mb-2 w-full bg-gray-200 rounded-lg appearance-none cursor-pointer dark:bg-gray-700 focus:ring-blue-500 focus:border-blue-500 dark:border-gray-600 dark:placeholder-gray-400 dark:focus:ring-blue-500 dark:focus:border-blue-500">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- sdasdas -->
|
||||
</div>
|
||||
</div>
|
||||
@ -380,57 +434,64 @@
|
||||
<YesNoDialog ref="yesNoDialog" />
|
||||
<MessageBox ref="messageBox" />
|
||||
<Toast ref="toast" />
|
||||
|
||||
|
||||
</template>
|
||||
<style scoped>
|
||||
.list-move, /* apply transition to moving elements */
|
||||
/* THESE ARE FOR TransitionGroup components */
|
||||
.list-move,
|
||||
/* apply transition to moving elements */
|
||||
.list-enter-active,
|
||||
.list-leave-active {
|
||||
transition: all 0.5s ease;
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
|
||||
.list-enter-from {
|
||||
transform: translatey(-30px);
|
||||
}
|
||||
|
||||
.list-leave-to {
|
||||
opacity: 0;
|
||||
transform: translatey(30px);
|
||||
opacity: 0;
|
||||
transform: translatey(30px);
|
||||
}
|
||||
|
||||
/* ensure leaving items are taken out of layout flow so that moving
|
||||
animations can be calculated correctly. */
|
||||
.list-leave-active {
|
||||
position: absolute;
|
||||
.list-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.bounce-enter-active {
|
||||
animation: bounce-in 0.5s;
|
||||
animation: bounce-in 0.5s;
|
||||
}
|
||||
|
||||
.bounce-leave-active {
|
||||
animation: bounce-in 0.5s reverse;
|
||||
animation: bounce-in 0.5s reverse;
|
||||
}
|
||||
|
||||
@keyframes bounce-in {
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
50% {
|
||||
transform: scale(1.25);
|
||||
}
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
0% {
|
||||
transform: scale(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: scale(1.25);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import feather from 'feather-icons'
|
||||
import { nextTick,TransitionGroup } from 'vue'
|
||||
import { nextTick, TransitionGroup } from 'vue'
|
||||
import MessageBox from "@/components/MessageBox.vue";
|
||||
import YesNoDialog from "@/components/YesNoDialog.vue";
|
||||
import Toast from '../components/Toast.vue'
|
||||
import ModelEntry from '@/components/ModelEntry.vue';
|
||||
import PersonalityViewer from '@/components/PersonalityViewer.vue';
|
||||
import PersonalityEntry from "../components/PersonalityEntry.vue";
|
||||
import BindingEntry from "../components/BindingEntry.vue";
|
||||
import socket from '@/services/websocket.js'
|
||||
|
||||
axios.defaults.baseURL = import.meta.env.VITE_GPT4ALL_API_BASEURL
|
||||
@ -443,25 +504,29 @@ export default {
|
||||
PersonalityViewer,
|
||||
Toast,
|
||||
PersonalityEntry,
|
||||
},
|
||||
BindingEntry,
|
||||
},
|
||||
data() {
|
||||
|
||||
return {
|
||||
// Models zoo installer stuff
|
||||
// Zoo stuff
|
||||
models: [],
|
||||
personalities: [],
|
||||
personalitiesFiltered: [],
|
||||
bindings: [],
|
||||
// Accordeon stuff
|
||||
collapsedArr: [],
|
||||
all_collapsed: true,
|
||||
bec_collapsed: true,
|
||||
mzc_collapsed: true, // models zoo
|
||||
pzc_collapsed: true, // personalities zoo
|
||||
bzc_collapsed: true, // binding zoo
|
||||
pc_collapsed: true,
|
||||
mc_collapsed: true,
|
||||
// Zoo accordeoon
|
||||
mzl_collapsed: false,
|
||||
pzl_collapsed: false,
|
||||
bzl_collapsed: false,
|
||||
// Settings stuff
|
||||
bindingsArr: [],
|
||||
modelsArr: [], // not used anymore but still have references in some methods
|
||||
@ -489,30 +554,30 @@ export default {
|
||||
this.mc_collapsed = val
|
||||
},
|
||||
fetchModels() {
|
||||
console.log("Fetching models")
|
||||
|
||||
axios.get('/get_available_models')
|
||||
.then(response => {
|
||||
//console.log(`Models list recovered successfuly: ${JSON.stringify(response.data)}`)
|
||||
console.log(" models", response.data.length)
|
||||
|
||||
this.models = response.data;
|
||||
this.fetchCustomModels()
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
console.log(error.message, 'fetchModels');
|
||||
});
|
||||
},
|
||||
fetchCustomModels() {
|
||||
console.log("Fetching Custom models")
|
||||
|
||||
axios.get('/list_models')
|
||||
.then(response => {
|
||||
// Returns array of model filenames which are = to title of models zoo entry
|
||||
for (let i = 0; i < response.data.length; i++) {
|
||||
const customModel = response.data[i]
|
||||
const index = this.models.findIndex(x => x.title == customModel)
|
||||
console.log("model-ccc", customModel, index)
|
||||
|
||||
if (index == -1) {
|
||||
let newModelEntry = {}
|
||||
newModelEntry.title = customModel
|
||||
newModelEntry.path = customModel
|
||||
newModelEntry.isCustomModel = true
|
||||
newModelEntry.isInstalled = true
|
||||
this.models.push(newModelEntry)
|
||||
@ -522,31 +587,25 @@ export default {
|
||||
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
console.log(error.message, 'fetchCustomModels');
|
||||
});
|
||||
},
|
||||
onPersonalitySelected(pers) {
|
||||
console.log("Selected personality")
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
if (this.isLoading) {
|
||||
this.$refs.toast.showToast("Loading... please wait", 4, false)
|
||||
}
|
||||
if (pers.personality) {
|
||||
// if (model_object.isInstalled) {
|
||||
|
||||
this.settingsChanged = true
|
||||
const res = this.update_setting('personality', pers.personality.name, () => {
|
||||
this.$refs.toast.showToast("Selected personality:\n" + pers.personality.name , 4, true)
|
||||
this.$refs.toast.showToast("Selected personality:\n" + pers.personality.name, 4, true)
|
||||
this.configFile.personality = pers.personality.name
|
||||
this.configFile.personality_category = pers.personality.category
|
||||
this.configFile.personality_language = pers.personality.language
|
||||
})
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
nextTick(() => {
|
||||
feather.replace()
|
||||
|
||||
@ -555,7 +614,7 @@ export default {
|
||||
|
||||
},
|
||||
onSelected(model_object) {
|
||||
console.log("Selected model")
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
if (this.isLoading) {
|
||||
this.$refs.toast.showToast("Loading... please wait", 4, false)
|
||||
@ -563,12 +622,10 @@ export default {
|
||||
if (model_object) {
|
||||
if (model_object.isInstalled) {
|
||||
|
||||
|
||||
|
||||
if (this.configFile.model != model_object.title) {
|
||||
this.update_model(model_object.title)
|
||||
this.configFile.model = model_object.title
|
||||
this.$refs.toast.showToast("Selected model:\n" + model_object.title , 4, true)
|
||||
this.$refs.toast.showToast("Selected model:\n" + model_object.title, 4, true)
|
||||
this.settingsChanged = true
|
||||
this.isModelSelected = true
|
||||
}
|
||||
@ -587,6 +644,11 @@ export default {
|
||||
// Model installation
|
||||
|
||||
onInstall(model_object) {
|
||||
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;
|
||||
@ -598,9 +660,12 @@ export default {
|
||||
if (response.status === 'progress') {
|
||||
console.log(`Progress = ${response.progress}`);
|
||||
model_object.progress = response.progress
|
||||
if(model_object.progress==100){
|
||||
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
|
||||
}
|
||||
} else if (response.status === 'succeeded') {
|
||||
console.log("Received succeeded")
|
||||
@ -610,18 +675,23 @@ export default {
|
||||
const index = this.models.findIndex((model) => model.path === path);
|
||||
this.models[index].isInstalled = true;
|
||||
this.showProgress = false;
|
||||
|
||||
model_object.installing = false
|
||||
this.$refs.toast.showToast("Model:\n" + model_object.title + "\ninstalled!", 4, true)
|
||||
} else if (response.status === 'failed') {
|
||||
socket.off('install_progress', progressListener);
|
||||
console.log("Install failed")
|
||||
// Installation failed or encountered an error
|
||||
model_object.installing = false;
|
||||
v
|
||||
this.showProgress = false;
|
||||
console.error('Installation failed:', response.error);
|
||||
this.$refs.toast.showToast("Model:\n" + model_object.title + "\nfailed to install!", 4, false)
|
||||
}
|
||||
};
|
||||
|
||||
socket.on('install_progress', progressListener);
|
||||
|
||||
|
||||
socket.emit('install_model', { path: path });
|
||||
console.log("Started installation, please wait");
|
||||
},
|
||||
@ -631,25 +701,35 @@ export default {
|
||||
if (response.status === 'progress') {
|
||||
this.progress = response.progress;
|
||||
} else if (response.status === 'succeeded') {
|
||||
console.log(model_object)
|
||||
// Installation completed
|
||||
model_object.uninstalling = false;
|
||||
socket.off('install_progress', progressListener);
|
||||
this.showProgress = false;
|
||||
const index = this.models.findIndex((model) => model.path === model_object.path);
|
||||
this.models[index].isInstalled = false;
|
||||
if (model_object.model.isCustomModel) {
|
||||
this.models = this.models.filter((model) => model.title !== model_object.title)
|
||||
}
|
||||
this.$refs.toast.showToast("Model:\n" + model_object.title + "\nwas uninstalled!", 4, true)
|
||||
} else if (response.status === 'failed') {
|
||||
// Installation failed or encountered an error
|
||||
model_object.uninstalling = false;
|
||||
this.showProgress = false;
|
||||
socket.off('install_progress', progressListener);
|
||||
// eslint-disable-next-line no-undef
|
||||
console.error('Installation failed:', message.error);
|
||||
console.error('Uninstallation failed:', message.error);
|
||||
this.$refs.toast.showToast("Model:\n" + model_object.title + "\nfailed to uninstall!", 4, false)
|
||||
}
|
||||
};
|
||||
|
||||
socket.on('install_progress', progressListener);
|
||||
|
||||
socket.emit('uninstall_model', { path: model_object.path });
|
||||
},
|
||||
onSelectedBinding(binding_object){
|
||||
this.update_binding(binding_object.binding.folder)
|
||||
//console.log('lol',binding_object)
|
||||
},
|
||||
// messagebox ok stuff
|
||||
onMessageBoxOk() {
|
||||
console.log("OK button clicked");
|
||||
@ -657,7 +737,7 @@ export default {
|
||||
// Refresh stuff
|
||||
refresh() {
|
||||
|
||||
console.log("Refreshing")
|
||||
|
||||
// No need to refresh all lists because they never change during using application.
|
||||
// On settings change only config file chnages.
|
||||
//
|
||||
@ -669,9 +749,9 @@ export default {
|
||||
//this.api_get_req("list_languages").then(response => { this.langArr = response })
|
||||
this.api_get_req("get_config").then(response => {
|
||||
this.configFile = response
|
||||
console.log("selecting model")
|
||||
|
||||
this.models.forEach(model => {
|
||||
console.log(`${model} -> ${response["model"]}`)
|
||||
|
||||
if (model.title == response["model"]) {
|
||||
model.selected = true;
|
||||
|
||||
@ -693,13 +773,13 @@ export default {
|
||||
setting_name: setting_name_val,
|
||||
setting_value: setting_value_val
|
||||
}
|
||||
console.log("change", setting_name_val, setting_value_val, obj)
|
||||
|
||||
axios.post('/update_setting', obj).then((res) => {
|
||||
console.log("Update setting done")
|
||||
|
||||
if (res) {
|
||||
console.log("res is ok")
|
||||
|
||||
if (next !== undefined) {
|
||||
console.log("Calling next")
|
||||
|
||||
next(res)
|
||||
}
|
||||
return res.data;
|
||||
@ -709,14 +789,12 @@ export default {
|
||||
.catch(error => { return { 'status': false } });
|
||||
},
|
||||
update_binding(value) {
|
||||
|
||||
console.log("Upgrading binding")
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
this.isLoading = true
|
||||
this.update_setting('binding', value, (res) => {
|
||||
this.refresh();
|
||||
console.log("Binding changed");
|
||||
console.log(res);
|
||||
|
||||
this.$refs.toast.showToast("Binding changed.", 4, true)
|
||||
this.settingsChanged = true
|
||||
this.isLoading = false
|
||||
@ -731,19 +809,17 @@ export default {
|
||||
},
|
||||
update_model(value) {
|
||||
if (!value) this.isModelSelected = false
|
||||
|
||||
console.log("Upgrading model")
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
this.isLoading = true
|
||||
this.update_setting('model', value, (res) => {
|
||||
console.log("Model changed");
|
||||
this.fetchModels();
|
||||
|
||||
//this.fetchModels();
|
||||
this.isLoading = false
|
||||
})
|
||||
},
|
||||
applyConfiguration() {
|
||||
if (!this.configFile.model) {
|
||||
console.log("applying configuration failed")
|
||||
|
||||
this.$refs.toast.showToast("Configuration changed failed.\nPlease select model first", 4, false)
|
||||
nextTick(() => {
|
||||
feather.replace()
|
||||
@ -753,14 +829,14 @@ export default {
|
||||
this.isLoading = true;
|
||||
axios.post('/apply_settings').then((res) => {
|
||||
this.isLoading = false;
|
||||
console.log(res.data)
|
||||
|
||||
if (res.data.status === "succeeded") {
|
||||
console.log("applying configuration succeeded")
|
||||
|
||||
this.$refs.toast.showToast("Configuration changed successfully.", 4, true)
|
||||
this.settingsChanged = false
|
||||
this.save_configuration()
|
||||
} else {
|
||||
console.log("applying configuration failed")
|
||||
|
||||
this.$refs.toast.showToast("Configuration change failed.", 4, false)
|
||||
|
||||
}
|
||||
@ -784,7 +860,7 @@ export default {
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
console.log(error.message, 'save_configuration')
|
||||
this.$refs.messageBox.showMessage("Couldn't save settings!")
|
||||
return { 'status': false }
|
||||
});
|
||||
@ -805,7 +881,7 @@ export default {
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error)
|
||||
console.log(error.message, 'reset_configuration')
|
||||
this.$refs.messageBox.showMessage("Couldn't reset settings!")
|
||||
return { 'status': false }
|
||||
});
|
||||
@ -827,7 +903,7 @@ export default {
|
||||
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
console.log(error.message, 'api_get_req - settings')
|
||||
return
|
||||
}
|
||||
|
||||
@ -889,6 +965,7 @@ export default {
|
||||
this.persArr = await this.api_get_req("list_personalities")
|
||||
this.langArr = await this.api_get_req("list_languages")
|
||||
await this.getPersonalitiesArr()
|
||||
this.bindings = await this.api_get_req("list_bindings")
|
||||
this.isLoading = false
|
||||
|
||||
},
|
||||
@ -931,8 +1008,15 @@ export default {
|
||||
|
||||
})
|
||||
},
|
||||
bzl_collapsed() {
|
||||
|
||||
nextTick(() => {
|
||||
feather.replace()
|
||||
|
||||
})
|
||||
},
|
||||
all_collapsed(val) {
|
||||
|
||||
|
||||
this.collapseAll(val)
|
||||
nextTick(() => {
|
||||
feather.replace()
|
||||
@ -951,12 +1035,6 @@ export default {
|
||||
|
||||
})
|
||||
},
|
||||
isModelSelected(val) {
|
||||
|
||||
console.log('iss selected:', val)
|
||||
},
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user