diff --git a/src/etc/patchNote.ts b/src/etc/patchNote.ts index 79299735..1bba23c7 100644 --- a/src/etc/patchNote.ts +++ b/src/etc/patchNote.ts @@ -15,7 +15,7 @@ export function getPatchNote(version: string){ if(patchNote.version.split(".")[1] === version.split(".")[1] && patchNote.version.split(".")[0] === version.split(".")[0]){ return patchNote } - return { +return { version: version.split(".")[0] + "." + version.split(".")[1], content: "" } diff --git a/src/lang/en.ts b/src/lang/en.ts index 9e4a6a61..63c41511 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -516,4 +516,17 @@ export const languageEnglish = { licenseDesc: "You can choose license for the downloaders to limit the usages of your card's prompt.", passwordDesc: "You can set a password to protect your card from unauthorized access.", largePersonaPortrait: "Persona Portrait", + module: "Module", + modules: "Modules", + noModules: "No modules has been installed.", + createModule: "Create Module", + basicInfo: "Basic Info", + moduleContent: "Module Content", + confirmRemoveModuleFeature: "Do you really want to remove this feature? This action cannot be undone.", + editModule: "Edit Module", + importModule: "Import Module", + download: "Download", + edit: "Edit", + enableGlobal: "Enable Globally", + chatModulesInfo: "You can enable or disable modules for this chat.", } \ No newline at end of file diff --git a/src/lib/ChatScreens/ChatScreen.svelte b/src/lib/ChatScreens/ChatScreen.svelte index 01fe227f..c5500d79 100644 --- a/src/lib/ChatScreens/ChatScreen.svelte +++ b/src/lib/ChatScreens/ChatScreen.svelte @@ -10,7 +10,9 @@ import BackgroundDom from "./BackgroundDom.svelte"; import SideBarArrow from "../UI/GUI/SideBarArrow.svelte"; import VisualNovelMain from "../VisualNovel/VisualNovelMain.svelte"; + import ModuleChatMenu from "../Setting/Pages/Module/ModuleChatMenu.svelte"; let openChatList = false + let openModuleList = false const wallPaper = `background: url(${defaultWallpaper})` const externalStyles = @@ -40,7 +42,7 @@ {/if} {/if} - 2 ? `${externalStyles}`: ''} bind:openChatList/> + 2 ? `${externalStyles}`: ''} bind:openChatList bind:openModuleList/> {:else if $DataBase.theme === 'waifu'} @@ -55,7 +57,7 @@ {/if} {/if} = 0 && $CurrentCharacter.viewScreen !== 'none'}> - + {:else if $DataBase.theme === 'waifuMobile'} @@ -66,7 +68,7 @@ class:per33={$selectedCharID >= 0 && $CurrentCharacter.viewScreen !== 'none'} class:h-full={!($selectedCharID >= 0 && $CurrentCharacter.viewScreen !== 'none')} > - + {#if $selectedCharID >= 0} {#if $CurrentCharacter.viewScreen !== 'none'} @@ -79,6 +81,8 @@ {/if} {#if openChatList} {openChatList = false}}/> +{:else if openModuleList} + {openModuleList = false}}/> {/if} \ No newline at end of file diff --git a/src/lib/Setting/Pages/Module/ModuleMenu.svelte b/src/lib/Setting/Pages/Module/ModuleMenu.svelte new file mode 100644 index 00000000..f3d5e04e --- /dev/null +++ b/src/lib/Setting/Pages/Module/ModuleMenu.svelte @@ -0,0 +1,153 @@ + + +{language.basicInfo} + + +{language.moduleContent} + + + {language.loreBook} + + + {language.regexScript} + + + {language.triggerScript} + + + + + + +{#if (Array.isArray(currentModule.lorebook))} + {language.loreBook} + + {#each currentModule.lorebook as lore, i} + { + currentModule.lorebook.splice(i, 1) + currentModule.lorebook = currentModule.lorebook + }}/> + {/each} + + {addLorebook()}} class="hover:text-textcolor cursor-pointer"> + + +{/if} + +{#if (Array.isArray(currentModule.regex))} + {language.regexScript} + + {addRegex()}} class="hover:text-textcolor cursor-pointer"> + + +{/if} + +{#if (Array.isArray(currentModule.trigger))} + {language.triggerScript} + + {addTrigger()}} class="hover:text-textcolor cursor-pointer"> + + +{/if} \ No newline at end of file diff --git a/src/lib/Setting/Pages/Module/ModuleSettings.svelte b/src/lib/Setting/Pages/Module/ModuleSettings.svelte new file mode 100644 index 00000000..e3275f94 --- /dev/null +++ b/src/lib/Setting/Pages/Module/ModuleSettings.svelte @@ -0,0 +1,109 @@ + +{#if mode === 0} + {language.modules} + + + {#if $DataBase.modules.length === 0} + {language.noModules} + {:else} + {#each $DataBase.modules as rmodule, i} + {#if i !== 0} + + {/if} + + + {rmodule.name} + + { + e.stopPropagation() + if($DataBase.enabledModules.includes(rmodule.id)){ + $DataBase.enabledModules.splice($DataBase.enabledModules.indexOf(rmodule.id), 1) + } + else{ + $DataBase.enabledModules.push(rmodule.id) + } + $DataBase.enabledModules = $DataBase.enabledModules + }}> + + + { + e.stopPropagation() + exportModule(rmodule) + }}> + + + { + e.stopPropagation() + + tempModule = rmodule + editModuleIndex = i + mode = 2 + }}> + + + { + e.stopPropagation() + const d = await alertConfirm(`${language.removeConfirm}` + rmodule.name) + if(d){ + $DataBase.modules.splice(i, 1) + $DataBase.modules = $DataBase.modules + } + }}> + + + + + + {rmodule.description || 'No description provided'} + + {/each} + {/if} + + { + tempModule = { + name: '', + description: '', + id: v4(), + } + mode = 1 + }}>{language.createModule} + {language.importModule} +{:else if mode === 1} + {language.createModule} + + {#if tempModule.name !== ''} + { + $DataBase.modules.push(tempModule) + mode = 0 + }}>{language.editModule} + {/if} +{:else if mode === 2} + {language.editModule} + + {#if tempModule.name !== ''} + { + $DataBase.modules[editModuleIndex] = tempModule + mode = 0 + }}>{language.createModule} + {/if} +{/if} \ No newline at end of file diff --git a/src/lib/Setting/Settings.svelte b/src/lib/Setting/Settings.svelte index 619aef96..1d2578ec 100644 --- a/src/lib/Setting/Settings.svelte +++ b/src/lib/Setting/Settings.svelte @@ -1,5 +1,5 @@ - {#if window.innerWidth >= 700 || selected === -1} + {#if window.innerWidth >= 700 || $SettingsMenuIndex === -1} { - selected = 1 + $SettingsMenuIndex = 1 }}> {language.chatBot} { - selected = 12 + $SettingsMenuIndex = 12 }}> {language.persona} { - selected = 2 + $SettingsMenuIndex = 2 }}> {language.otherBots} { - selected = 3 + $SettingsMenuIndex = 3 }}> {language.display} { - selected = 10 + $SettingsMenuIndex = 10 }}> {language.language} { - selected = 11 + $SettingsMenuIndex = 11 }}> {language.accessibility} { - selected = 8 + $SettingsMenuIndex = 8 }}> {language.globalLoreBook} { - selected = 9 + $SettingsMenuIndex = 9 }}> {language.globalRegexScript} { - selected = 4 + $SettingsMenuIndex = 14 + }}> + + {language.modules} + + { + $SettingsMenuIndex = 4 }}> {language.plugin} { - selected = 0 + $SettingsMenuIndex = 0 }}> {language.account} & {language.files} { - selected = 6 + $SettingsMenuIndex = 6 }}> {language.advancedSettings} { - selected = 77 + $SettingsMenuIndex = 77 }}> {language.supporterThanks} @@ -149,42 +158,44 @@ {/if} {/if} - {#if window.innerWidth >= 700 || selected !== -1} - {#key selected} + {#if window.innerWidth >= 700 || $SettingsMenuIndex !== -1} + {#key $SettingsMenuIndex} - {#if selected === 0} + {#if $SettingsMenuIndex === 0} - {:else if selected === 1} + {:else if $SettingsMenuIndex === 1} { - selected = 13 + $SettingsMenuIndex = 13 }} /> - {:else if selected === 2} + {:else if $SettingsMenuIndex === 2} - {:else if selected === 3} + {:else if $SettingsMenuIndex === 3} - {:else if selected === 4} + {:else if $SettingsMenuIndex === 4} - {:else if selected === 5} + {:else if $SettingsMenuIndex === 5} - {:else if selected === 6} + {:else if $SettingsMenuIndex === 6} - {:else if selected === 7} + {:else if $SettingsMenuIndex === 7} - {:else if selected === 8} + {:else if $SettingsMenuIndex === 8} - {:else if selected === 9} + {:else if $SettingsMenuIndex === 9} - {:else if selected === 10} + {:else if $SettingsMenuIndex === 10} - {:else if selected === 11} + {:else if $SettingsMenuIndex === 11} - {:else if selected === 12} + {:else if $SettingsMenuIndex === 12} - {:else if selected === 13} + {:else if $SettingsMenuIndex === 14} + + {:else if $SettingsMenuIndex === 13} { - selected = 1 + $SettingsMenuIndex = 1 }}/> - {:else if selected === 77} + {:else if $SettingsMenuIndex === 77} {/if} @@ -194,7 +205,7 @@ settingsOpen.set(false) } else{ - selected = -1 + $SettingsMenuIndex = -1 } }}> diff --git a/src/lib/SideBars/Scripts/RegexList.svelte b/src/lib/SideBars/Scripts/RegexList.svelte index 6915dcea..78b79a35 100644 --- a/src/lib/SideBars/Scripts/RegexList.svelte +++ b/src/lib/SideBars/Scripts/RegexList.svelte @@ -51,7 +51,7 @@ }) - + {#if value.length === 0} No Scripts {/if} diff --git a/src/lib/SideBars/Scripts/TriggerList.svelte b/src/lib/SideBars/Scripts/TriggerList.svelte index 4a82ec09..80382b4b 100644 --- a/src/lib/SideBars/Scripts/TriggerList.svelte +++ b/src/lib/SideBars/Scripts/TriggerList.svelte @@ -7,7 +7,7 @@ - + {#if value.length === 0} No Scripts {/if} diff --git a/src/lib/UI/ModelList.svelte b/src/lib/UI/ModelList.svelte index 38a214db..074e06a1 100644 --- a/src/lib/UI/ModelList.svelte +++ b/src/lib/UI/ModelList.svelte @@ -126,10 +126,11 @@ {changeModel('gptvi4_1106')}}>GPT-4 Turbo 1106 Vision {#if showUnrec} {changeModel('gpt35_16k')}}>GPT-3.5 Turbo 16K - {changeModel('gpt4_0301')}}>GPT-4 0301 + {changeModel('gpt4_0314')}}>GPT-4 0314 {changeModel('gpt4_0613')}}>GPT-4 0613 {changeModel('gpt4_32k_0613')}}>GPT-4 32K 0613 {changeModel('gpt4_1106')}}>GPT-4 Turbo 1106 + {changeModel('gpt35_0125')}}>GPT-3.5 Turbo 0125 {changeModel('gpt35_1106')}}>GPT-3.5 Turbo 1106 {changeModel('gpt35_0613')}}>GPT-3.5 Turbo 0613 {changeModel('gpt35_16k_0613')}}>GPT-3.5 Turbo 16K 0613 diff --git a/src/ts/process/lorebook.ts b/src/ts/process/lorebook.ts index c1dd272e..08f4c262 100644 --- a/src/ts/process/lorebook.ts +++ b/src/ts/process/lorebook.ts @@ -7,6 +7,7 @@ import { alertError, alertNormal } from "../alert"; import { language } from "../../lang"; import { downloadFile } from "../storage/globalApi"; import { HypaProcesser } from "./memory/hypamemory"; +import { getModuleLorebooks } from "./modules"; export function addLorebook(type:number) { let selectedID = get(selectedCharID) @@ -71,12 +72,12 @@ export async function loadLoreBookPrompt(){ const characterLore = char.globalLore ?? [] const chatLore = char.chats[page].localLore ?? [] const globalLore = db.loreBook[db.loreBookPage]?.data ?? [] - const fullLore = characterLore.concat(chatLore.concat(globalLore)) + const moduleLorebook = getModuleLorebooks() + const fullLore = characterLore.concat(chatLore).concat(moduleLorebook).concat(globalLore) const currentChat = char.chats[page].message const loreDepth = char.loreSettings?.scanDepth ?? db.loreBookDepth const loreToken = char.loreSettings?.tokenBudget ?? db.loreBookToken const fullWordMatching = char.loreSettings?.fullWordMatching ?? false - if(char.lorePlus){ return await loadLoreBookPlusPrompt() } diff --git a/src/ts/process/modules.ts b/src/ts/process/modules.ts new file mode 100644 index 00000000..23c2d028 --- /dev/null +++ b/src/ts/process/modules.ts @@ -0,0 +1,120 @@ +import { language } from "src/lang" +import { alertError, alertNormal } from "../alert" +import { DataBase, type customscript, type loreBook, type triggerscript } from "../storage/database" +import { downloadFile } from "../storage/globalApi" +import { get } from "svelte/store" +import { CurrentChat } from "../stores" +import { selectSingleFile } from "../util" +import { v4 } from "uuid" + +export interface RisuModule{ + name: string + description: string + lorebook?: loreBook[] + regex?: customscript[] + cjs?: string + trigger?: triggerscript[] + id: string +} + +export async function exportModule(module:RisuModule){ + await downloadFile(module.name + '.json', JSON.stringify({ + ...module, + type: 'risuModule' + }, null, 2)) + alertNormal(language.successExport) +} + +export async function importModule(){ + const f = await selectSingleFile(['json']) + if(!f){ + return + } + const file = f.data + try { + const importedModule = JSON.parse(Buffer.from(file).toString()) + if(importedModule.type === 'risuModule'){ + const db = get(DataBase) + if( + (!importedModule.name) + || (!importedModule.description) + || (!importedModule.id) + ){ + alertError(language.errors.noData) + } + importedModule.id = v4() + db.modules.push(importedModule) + } + } catch (error) { + alertNormal(language.errors.noData) + } +} + +function getModuleById(id:string){ + const db = get(DataBase) + for(let i=0;i { let prefix = '' switch (v.role){ @@ -1437,13 +1439,18 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' prefix = "\n\nSystem: " break } + latestRole = v.role if(raiModel.startsWith('claude-2') && (!raiModel.startsWith('claude-2.0'))){ if(v.role === 'system' && i === 0){ prefix = '' } } return prefix + v.content - }).join('') + '\n\nAssistant: ' + }).join('') + + if(latestRole !== 'assistant'){ + requestPrompt += '\n\nAssistant: ' + } const bedrock = db.claudeAws diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts index 2cb731ff..1916f466 100644 --- a/src/ts/process/scripts.ts +++ b/src/ts/process/scripts.ts @@ -10,6 +10,7 @@ import { autoMarkPlugin } from "../plugins/automark"; import { runCharacterJS } from "../plugins/embedscript"; import { metricaPlugin } from "../plugins/metrica"; import { OaiFixKorean } from "../plugins/fixer"; +import { getModuleRegexScripts } from "./modules"; const dreg = /{{data}}/g const randomness = /\|\|\|/g @@ -60,7 +61,7 @@ export async function importRegex(){ export async function processScriptFull(char:character|groupChat|simpleCharacterArgument, data:string, mode:ScriptMode, chatID = -1){ let db = get(DataBase) let emoChanged = false - const scripts = (db.globalscript ?? []).concat(char.customscript) + const scripts = (db.globalscript ?? []).concat(char.customscript).concat(getModuleRegexScripts()) if(db.officialplugins.automark && mode === 'editdisplay'){ data = autoMarkPlugin(data) } diff --git a/src/ts/process/triggers.ts b/src/ts/process/triggers.ts index 6c944ead..d01af730 100644 --- a/src/ts/process/triggers.ts +++ b/src/ts/process/triggers.ts @@ -2,6 +2,7 @@ import { cloneDeep } from "lodash"; import { getVarChat, risuChatParser } from "../parser"; import type { Chat, character } from "../storage/database"; import { tokenize } from "../tokenizer"; +import { getModuleTriggers } from "./modules"; export interface triggerscript{ comment: string; @@ -68,7 +69,7 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{ historyend: '', promptend: '' } - const triggers = char.triggerscript + const triggers = char.triggerscript.concat(getModuleTriggers()) const chat = cloneDeep(arg.chat ?? char.chats[char.chatPage]) if((!triggers) || (triggers.length === 0)){ return null diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 36ec1279..0b12a4d1 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -366,6 +366,8 @@ export function setDatabase(data:Database){ data.openrouterMiddleOut ??= false data.removePunctuationHypa ??= true data.memoryLimitThickness ??= 1 + data.modules ??= [] + data.enabledModules ??= [] changeLanguage(data.language) DataBase.set(data) @@ -586,6 +588,8 @@ export interface Database{ lastPatchNoteCheckVersion?:string, removePunctuationHypa?:boolean memoryLimitThickness?:number + modules: RisuModule[] + enabledModules: string[] } export interface customscript{ @@ -838,6 +842,7 @@ export interface Chat{ suggestMessages?:string[] isStreaming?:boolean scriptstate?:{[key:string]:string|number|boolean} + modules?:string[] } export interface Message{ @@ -1119,6 +1124,7 @@ export function setPreset(db:Database, newPres: botPreset){ import { encode as encodeMsgpack, decode as decodeMsgpack } from "msgpackr"; import * as fflate from "fflate"; import type { OnnxModelFiles } from '../process/embedding/transformers'; +import type { RisuModule } from '../process/modules'; export async function downloadPreset(id:number){ saveCurrentPreset() diff --git a/src/ts/storage/globalApi.ts b/src/ts/storage/globalApi.ts index 5ca74af4..9f5c977b 100644 --- a/src/ts/storage/globalApi.ts +++ b/src/ts/storage/globalApi.ts @@ -44,7 +44,11 @@ interface fetchLog{ let fetchLog:fetchLog[] = [] -export async function downloadFile(name:string, data:Uint8Array|ArrayBuffer) { +export async function downloadFile(name:string, dat:Uint8Array|ArrayBuffer|string) { + if(typeof(dat) === 'string'){ + dat = Buffer.from(dat, 'utf-8') + } + const data = new Uint8Array(dat) const downloadURL = (data:string, fileName:string) => { const a = document.createElement('a') a.href = data diff --git a/src/ts/stores.ts b/src/ts/stores.ts index d6c5f4f2..126adb2f 100644 --- a/src/ts/stores.ts +++ b/src/ts/stores.ts @@ -37,6 +37,7 @@ export const CurrentUsername = writable(db.username) export const CurrentUserIcon = writable(db.userIcon) export const CurrentShowMemoryLimit = writable(db.showMemoryLimit) export const ShowVN = writable(false) +export const SettingsMenuIndex = writable(0) function createSimpleCharacter(char:character|groupChat){ if((!char) || char.type === 'group'){