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} +
+ + + + +
+ +{#if (Array.isArray(currentModule.lorebook))} + {language.loreBook} +
+ {#each currentModule.lorebook as lore, i} + { + currentModule.lorebook.splice(i, 1) + currentModule.lorebook = currentModule.lorebook + }}/> + {/each} +
+ +{/if} + +{#if (Array.isArray(currentModule.regex))} + {language.regexScript} + + +{/if} + +{#if (Array.isArray(currentModule.trigger))} + {language.triggerScript} + + +{/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} +
+ + + + +
+
+
+ {rmodule.description || 'No description provided'} +
+ {/each} + {/if} +
+ + +{:else if mode === 1} +

{language.createModule}

+ + {#if tempModule.name !== ''} + + {/if} +{:else if mode === 2} +

{language.editModule}

+ + {#if tempModule.name !== ''} + + {/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}
+
{/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 @@ {#if showUnrec} - + + 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'){