[feat] global lorebook
This commit is contained in:
@@ -268,5 +268,7 @@ export const languageEnglish = {
|
|||||||
ttsReadOnlyQuoted: "Read Only Quoted",
|
ttsReadOnlyQuoted: "Read Only Quoted",
|
||||||
ttsStop: "Stop TTS",
|
ttsStop: "Stop TTS",
|
||||||
askRemoval:"Ask Removal",
|
askRemoval:"Ask Removal",
|
||||||
replaceGlobalNote: "Global Note Replacement"
|
replaceGlobalNote: "Global Note Replacement",
|
||||||
|
charLoreBook: 'Character Lorebook',
|
||||||
|
globalLoreBook: 'Global Lorebook',
|
||||||
}
|
}
|
||||||
11
src/lib/Setting/Pages/GlobalLoreBookSettings.svelte
Normal file
11
src/lib/Setting/Pages/GlobalLoreBookSettings.svelte
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { language } from "src/lang";
|
||||||
|
import Help from "src/lib/Others/Help.svelte";
|
||||||
|
import LoreBookSetting from "src/lib/SideBars/LoreBookSetting.svelte";
|
||||||
|
import { DataBase } from "src/ts/database";
|
||||||
|
export let openLoreList = false
|
||||||
|
</script>
|
||||||
|
<h2 class="mb-2 text-2xl font-bold mt-2">{language.globalLoreBook} <Help key="lorebook" /></h2>
|
||||||
|
<button on:click={() => {openLoreList = true}} class="mt-4 drop-shadow-lg p-3 flex justify-center items-center ml-2 mr-2 rounded-lg bg-selected mb-4">{$DataBase.loreBook[$DataBase.loreBookPage].name}</button>
|
||||||
|
|
||||||
|
<LoreBookSetting globalMode />
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { ActivityIcon, BotIcon, BoxIcon, CodeIcon, DiamondIcon, FolderIcon, MonitorIcon, Sailboat, UserIcon, XCircleIcon } from "lucide-svelte";
|
import { ActivityIcon, BookIcon, BotIcon, BoxIcon, CodeIcon, DiamondIcon, FolderIcon, MonitorIcon, Sailboat, UserIcon, XCircleIcon } from "lucide-svelte";
|
||||||
import { language } from "src/lang";
|
import { language } from "src/lang";
|
||||||
import DisplaySettings from "./Pages/DisplaySettings.svelte";
|
import DisplaySettings from "./Pages/DisplaySettings.svelte";
|
||||||
import UserSettings from "./Pages/UserSettings.svelte";
|
import UserSettings from "./Pages/UserSettings.svelte";
|
||||||
@@ -8,12 +8,14 @@
|
|||||||
import PluginSettings from "./Pages/PluginSettings.svelte";
|
import PluginSettings from "./Pages/PluginSettings.svelte";
|
||||||
import FilesSettings from "./Pages/FilesSettings.svelte";
|
import FilesSettings from "./Pages/FilesSettings.svelte";
|
||||||
import AdvancedSettings from "./Pages/AdvancedSettings.svelte";
|
import AdvancedSettings from "./Pages/AdvancedSettings.svelte";
|
||||||
import { SizeStore, settingsOpen } from "src/ts/stores";
|
import { settingsOpen } from "src/ts/stores";
|
||||||
import Botpreset from "./botpreset.svelte";
|
import Botpreset from "./botpreset.svelte";
|
||||||
import Communities from "./Pages/Communities.svelte";
|
import Communities from "./Pages/Communities.svelte";
|
||||||
import { openURL } from "src/ts/globalApi";
|
import GlobalLoreBookSettings from "./Pages/GlobalLoreBookSettings.svelte";
|
||||||
|
import Lorepreset from "./lorepreset.svelte";
|
||||||
let selected = -1
|
let selected = -1
|
||||||
let openPresetList = false
|
let openPresetList = false
|
||||||
|
let openLoreList = false
|
||||||
if(window.innerWidth >= 700){
|
if(window.innerWidth >= 700){
|
||||||
selected = 0
|
selected = 0
|
||||||
}
|
}
|
||||||
@@ -48,6 +50,12 @@
|
|||||||
<MonitorIcon />
|
<MonitorIcon />
|
||||||
<span>{language.display}</span>
|
<span>{language.display}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="text-gray-400 flex gap-2 items-center hover:text-gray-200" class:text-white={selected === 8} on:click={() => {
|
||||||
|
selected = 8
|
||||||
|
}}>
|
||||||
|
<BookIcon />
|
||||||
|
<span>{language.globalLoreBook}</span>
|
||||||
|
</button>
|
||||||
<button class="text-gray-400 flex gap-2 items-center hover:text-gray-200" class:text-white={selected === 4} on:click={() => {
|
<button class="text-gray-400 flex gap-2 items-center hover:text-gray-200" class:text-white={selected === 4} on:click={() => {
|
||||||
selected = 4
|
selected = 4
|
||||||
}}>
|
}}>
|
||||||
@@ -97,6 +105,8 @@
|
|||||||
<AdvancedSettings />
|
<AdvancedSettings />
|
||||||
{:else if selected === 7}
|
{:else if selected === 7}
|
||||||
<Communities />
|
<Communities />
|
||||||
|
{:else if selected === 8}
|
||||||
|
<GlobalLoreBookSettings bind:openLoreList />
|
||||||
{/if}
|
{/if}
|
||||||
<button class="absolute top-2 right-2 hover:text-green-500" on:click={() => {
|
<button class="absolute top-2 right-2 hover:text-green-500" on:click={() => {
|
||||||
if(window.innerWidth >= 700){
|
if(window.innerWidth >= 700){
|
||||||
@@ -115,6 +125,9 @@
|
|||||||
{#if openPresetList}
|
{#if openPresetList}
|
||||||
<Botpreset close={() => {openPresetList = false}} />
|
<Botpreset close={() => {openPresetList = false}} />
|
||||||
{/if}
|
{/if}
|
||||||
|
{#if openLoreList}
|
||||||
|
<Lorepreset close={() => {openLoreList = false}} />
|
||||||
|
{/if}
|
||||||
<style>
|
<style>
|
||||||
.setting-bg{
|
.setting-bg{
|
||||||
background: linear-gradient(to right, #21222C 50%, #282a36 50%);
|
background: linear-gradient(to right, #21222C 50%, #282a36 50%);
|
||||||
|
|||||||
77
src/lib/Setting/lorepreset.svelte
Normal file
77
src/lib/Setting/lorepreset.svelte
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<script>
|
||||||
|
import { alertConfirm, alertError } from "../../ts/alert";
|
||||||
|
import { language } from "../../lang";
|
||||||
|
import { DataBase } from "../../ts/database";
|
||||||
|
import { EditIcon, PlusIcon, TrashIcon, XIcon } from "lucide-svelte";
|
||||||
|
let editMode = false
|
||||||
|
export let close = () => {}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="absolute w-full h-full z-40 bg-black bg-opacity-50 flex justify-center items-center">
|
||||||
|
<div class="bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl w-96">
|
||||||
|
<div class="flex items-center text-neutral-200 mb-4">
|
||||||
|
<h2 class="mt-0 mb-0">{language.loreBook}</h2>
|
||||||
|
<div class="flex-grow flex justify-end">
|
||||||
|
<button class="text-gray-500 hover:text-green-500 mr-2 cursor-pointer items-center" on:click={close}>
|
||||||
|
<XIcon size={24}/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{#each $DataBase.loreBook as lore, ind}
|
||||||
|
<button on:click={() => {
|
||||||
|
if(!editMode){
|
||||||
|
$DataBase.loreBookPage = ind
|
||||||
|
}
|
||||||
|
}} class="flex items-center text-neutral-200 border-t-1 border-solid border-0 border-gray-600 p-2 cursor-pointer" class:bg-selected={ind === $DataBase.loreBookPage}>
|
||||||
|
{#if editMode}
|
||||||
|
<input class="text-neutral-200 p-2 bg-transparent input-text focus:bg-selected" bind:value={$DataBase.loreBook[ind].name} placeholder="string">
|
||||||
|
{:else}
|
||||||
|
<span>{lore.name}</span>
|
||||||
|
{/if}
|
||||||
|
<div class="flex-grow flex justify-end">
|
||||||
|
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={async (e) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
if($DataBase.loreBook.length === 1){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const d = await alertConfirm(`${language.removeConfirm}${lore.name}`)
|
||||||
|
if(d){
|
||||||
|
$DataBase.loreBookPage = 0
|
||||||
|
let loreBook = $DataBase.loreBook
|
||||||
|
loreBook.splice(ind, 1)
|
||||||
|
$DataBase.loreBook = loreBook
|
||||||
|
}
|
||||||
|
}}>
|
||||||
|
<TrashIcon size={18}/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
{/each}
|
||||||
|
<div class="flex mt-2 items-center">
|
||||||
|
<button class="text-gray-500 hover:text-green-500 cursor-pointer mr-1" on:click={() => {
|
||||||
|
let loreBooks = $DataBase.loreBook
|
||||||
|
let newLoreBook = {
|
||||||
|
name: `New LoreBook`,
|
||||||
|
data: []
|
||||||
|
}
|
||||||
|
loreBooks.push(newLoreBook)
|
||||||
|
|
||||||
|
$DataBase.loreBook = loreBooks
|
||||||
|
}}>
|
||||||
|
<PlusIcon/>
|
||||||
|
</button>
|
||||||
|
<button class="text-gray-500 hover:text-green-500 cursor-pointer" on:click={() => {
|
||||||
|
editMode = !editMode
|
||||||
|
}}>
|
||||||
|
<EditIcon size={18}/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.break-any{
|
||||||
|
word-break: normal;
|
||||||
|
overflow-wrap: anywhere;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
import LoreBookData from "./LoreBookData.svelte";
|
import LoreBookData from "./LoreBookData.svelte";
|
||||||
import Check from "../Others/Check.svelte";
|
import Check from "../Others/Check.svelte";
|
||||||
let submenu = 0
|
let submenu = 0
|
||||||
let globalMode = false
|
export let globalMode = false
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{#if !globalMode}
|
{#if !globalMode}
|
||||||
@@ -30,9 +30,26 @@
|
|||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
{#if submenu !== 2}
|
{#if submenu !== 2}
|
||||||
<span class="text-gray-500 mt-2 mb-6 text-sm">{submenu === 0 ? $DataBase.characters[$selectedCharID].type === 'group' ? language.groupLoreInfo : language.globalLoreInfo : language.localLoreInfo}</span>
|
{#if !globalMode}
|
||||||
|
<span class="text-gray-500 mt-2 mb-6 text-sm">{submenu === 0 ? $DataBase.characters[$selectedCharID].type === 'group' ? language.groupLoreInfo : language.globalLoreInfo : language.localLoreInfo}</span>
|
||||||
|
{/if}
|
||||||
<div class="border-solid border-borderc p-2 flex flex-col border-1">
|
<div class="border-solid border-borderc p-2 flex flex-col border-1">
|
||||||
{#if submenu === 0}
|
{#if globalMode}
|
||||||
|
{#if $DataBase.loreBook[$DataBase.loreBookPage].data.length === 0}
|
||||||
|
<span class="text-gray-500">No Lorebook</span>
|
||||||
|
{:else}
|
||||||
|
{#each $DataBase.loreBook[$DataBase.loreBookPage].data as book, i}
|
||||||
|
{#if i !== 0}
|
||||||
|
<div class="border-borderc mt-2 mb-2 w-full border-solid border-b-1 seperator"></div>
|
||||||
|
{/if}
|
||||||
|
<LoreBookData bind:value={$DataBase.loreBook[$DataBase.loreBookPage].data[i]} onRemove={() => {
|
||||||
|
let lore = $DataBase.loreBook[$DataBase.loreBookPage].data
|
||||||
|
lore.splice(i, 1)
|
||||||
|
$DataBase.loreBook[$DataBase.loreBookPage].data = lore
|
||||||
|
}}/>
|
||||||
|
{/each}
|
||||||
|
{/if}
|
||||||
|
{:else if submenu === 0}
|
||||||
{#if $DataBase.characters[$selectedCharID].globalLore.length === 0}
|
{#if $DataBase.characters[$selectedCharID].globalLore.length === 0}
|
||||||
<span class="text-gray-500">No Lorebook</span>
|
<span class="text-gray-500">No Lorebook</span>
|
||||||
{:else}
|
{:else}
|
||||||
@@ -96,16 +113,16 @@
|
|||||||
{#if submenu !== 2}
|
{#if submenu !== 2}
|
||||||
|
|
||||||
<div class="text-gray-500 mt-2 flex">
|
<div class="text-gray-500 mt-2 flex">
|
||||||
<button on:click={() => {addLorebook(submenu)}} class="hover:text-neutral-200 cursor-pointer">
|
<button on:click={() => {addLorebook(globalMode ? -1 : submenu)}} class="hover:text-neutral-200 cursor-pointer">
|
||||||
<PlusIcon />
|
<PlusIcon />
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => {
|
<button on:click={() => {
|
||||||
exportLoreBook(submenu === 0 ? 'global' : 'local')
|
exportLoreBook(globalMode ? 'sglobal' : submenu === 0 ? 'global' : 'local')
|
||||||
}} class="hover:text-neutral-200 ml-1 cursor-pointer">
|
}} class="hover:text-neutral-200 ml-1 cursor-pointer">
|
||||||
<DownloadIcon />
|
<DownloadIcon />
|
||||||
</button>
|
</button>
|
||||||
<button on:click={() => {
|
<button on:click={() => {
|
||||||
importLoreBook(submenu === 0 ? 'global' : 'local')
|
importLoreBook(globalMode ? 'sglobal' : submenu === 0 ? 'global' : 'local')
|
||||||
}} class="hover:text-neutral-200 ml-2 cursor-pointer">
|
}} class="hover:text-neutral-200 ml-2 cursor-pointer">
|
||||||
<FolderUpIcon />
|
<FolderUpIcon />
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -235,6 +235,13 @@ export function setDatabase(data:Database){
|
|||||||
model: "clio-v1",
|
model: "clio-v1",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(checkNullish(data.loreBook)){
|
||||||
|
data.loreBookPage = 0
|
||||||
|
data.loreBook = [{
|
||||||
|
name: "My First LoreBook",
|
||||||
|
data: []
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
changeLanguage(data.language)
|
changeLanguage(data.language)
|
||||||
@@ -382,6 +389,11 @@ export interface Database{
|
|||||||
jailbreakToggle:boolean
|
jailbreakToggle:boolean
|
||||||
loreBookDepth: number
|
loreBookDepth: number
|
||||||
loreBookToken: number,
|
loreBookToken: number,
|
||||||
|
loreBook: {
|
||||||
|
name:string
|
||||||
|
data:loreBook[]
|
||||||
|
}[]
|
||||||
|
loreBookPage: number
|
||||||
supaMemoryPrompt: string
|
supaMemoryPrompt: string
|
||||||
username: string
|
username: string
|
||||||
userIcon: string
|
userIcon: string
|
||||||
|
|||||||
@@ -10,7 +10,19 @@ import { downloadFile } from "../globalApi";
|
|||||||
export function addLorebook(type:number) {
|
export function addLorebook(type:number) {
|
||||||
let selectedID = get(selectedCharID)
|
let selectedID = get(selectedCharID)
|
||||||
let db = get(DataBase)
|
let db = get(DataBase)
|
||||||
if(type === 0){
|
if(type === -1){
|
||||||
|
db.loreBook[db.loreBookPage].data.push({
|
||||||
|
key: '',
|
||||||
|
comment: `New Lore ${db.loreBook[db.loreBookPage].data.length + 1}`,
|
||||||
|
content: '',
|
||||||
|
mode: 'normal',
|
||||||
|
insertorder: 100,
|
||||||
|
alwaysActive: false,
|
||||||
|
secondkey: "",
|
||||||
|
selective: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
else if(type === 0){
|
||||||
db.characters[selectedID].globalLore.push({
|
db.characters[selectedID].globalLore.push({
|
||||||
key: '',
|
key: '',
|
||||||
comment: `New Lore ${db.characters[selectedID].globalLore.length + 1}`,
|
comment: `New Lore ${db.characters[selectedID].globalLore.length + 1}`,
|
||||||
@@ -53,9 +65,10 @@ export async function loadLoreBookPrompt(){
|
|||||||
const db = get(DataBase)
|
const db = get(DataBase)
|
||||||
const char = db.characters[selectedID]
|
const char = db.characters[selectedID]
|
||||||
const page = char.chatPage
|
const page = char.chatPage
|
||||||
const globalLore = char.globalLore
|
const characterLore = char.globalLore
|
||||||
const charLore = char.chats[page].localLore
|
const chatLore = char.chats[page].localLore
|
||||||
const fullLore = globalLore.concat(charLore)
|
const globalLore = db.loreBook[db.loreBookPage].data
|
||||||
|
const fullLore = characterLore.concat(chatLore.concat(globalLore))
|
||||||
const currentChat = char.chats[page].message
|
const currentChat = char.chats[page].message
|
||||||
const loreDepth = char.loreSettings?.scanDepth ?? db.loreBookDepth
|
const loreDepth = char.loreSettings?.scanDepth ?? db.loreBookDepth
|
||||||
const loreToken = char.loreSettings?.tokenBudget ?? db.loreBookToken
|
const loreToken = char.loreSettings?.tokenBudget ?? db.loreBookToken
|
||||||
@@ -144,11 +157,14 @@ export async function loadLoreBookPrompt(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function importLoreBook(mode:'global'|'local'){
|
export async function importLoreBook(mode:'global'|'local'|'sglobal'){
|
||||||
const selectedID = get(selectedCharID)
|
const selectedID = get(selectedCharID)
|
||||||
let db = get(DataBase)
|
let db = get(DataBase)
|
||||||
const page = db.characters[selectedID].chatPage
|
const page = db.characters[selectedID].chatPage
|
||||||
let lore = mode === 'global' ? db.characters[selectedID].globalLore : db.characters[selectedID].chats[page].localLore
|
let lore =
|
||||||
|
mode === 'global' ? db.characters[selectedID].globalLore :
|
||||||
|
mode === 'sglobal' ? db.loreBook[db.loreBookPage].data :
|
||||||
|
db.characters[selectedID].chats[page].localLore
|
||||||
const lorebook = (await selectSingleFile(['json'])).data
|
const lorebook = (await selectSingleFile(['json'])).data
|
||||||
if(!lorebook){
|
if(!lorebook){
|
||||||
return
|
return
|
||||||
@@ -189,6 +205,9 @@ export async function importLoreBook(mode:'global'|'local'){
|
|||||||
if(mode === 'global'){
|
if(mode === 'global'){
|
||||||
db.characters[selectedID].globalLore = lore
|
db.characters[selectedID].globalLore = lore
|
||||||
}
|
}
|
||||||
|
if(mode === 'sglobal'){
|
||||||
|
db.loreBook[db.loreBookPage].data = lore
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
db.characters[selectedID].chats[page].localLore = lore
|
db.characters[selectedID].chats[page].localLore = lore
|
||||||
}
|
}
|
||||||
@@ -198,13 +217,15 @@ export async function importLoreBook(mode:'global'|'local'){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function exportLoreBook(mode:'global'|'local'){
|
export async function exportLoreBook(mode:'global'|'local'|'sglobal'){
|
||||||
try {
|
try {
|
||||||
const selectedID = get(selectedCharID)
|
const selectedID = get(selectedCharID)
|
||||||
const db = get(DataBase)
|
const db = get(DataBase)
|
||||||
const page = db.characters[selectedID].chatPage
|
const page = db.characters[selectedID].chatPage
|
||||||
const lore = mode === 'global' ? db.characters[selectedID].globalLore : db.characters[selectedID].chats[page].localLore
|
const lore =
|
||||||
|
mode === 'global' ? db.characters[selectedID].globalLore :
|
||||||
|
mode === 'sglobal' ? db.loreBook[db.loreBookPage].data :
|
||||||
|
db.characters[selectedID].chats[page].localLore
|
||||||
const stringl = Buffer.from(JSON.stringify({
|
const stringl = Buffer.from(JSON.stringify({
|
||||||
type: 'risu',
|
type: 'risu',
|
||||||
ver: 1,
|
ver: 1,
|
||||||
|
|||||||
Reference in New Issue
Block a user