From 1e3ddebf4b644c171d73b5c5800ae8a80625c78c Mon Sep 17 00:00:00 2001 From: sub-hub Date: Tue, 20 Aug 2024 15:04:26 +0900 Subject: [PATCH 001/174] Remove db.advancedBotSettings in request.ts --- src/ts/process/request.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index e139b6fe..e4010fab 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -131,7 +131,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' let useStreaming = db.useStreaming && arg.useStreaming arg.continue = arg.continue ?? false let biasString = arg.biasString ?? [] - const aiModel = (model === 'model' || (!db.advancedBotSettings)) ? db.aiModel : db.subModel + const aiModel = model === 'model' ? db.aiModel : db.subModel const multiGen = (db.genTime > 1 && aiModel.startsWith('gpt') && (!arg.continue)) && (!arg.noMultiGen) let raiModel = aiModel From 410d0ecb8054f18bae54d0010aa63eb1c508e63d Mon Sep 17 00:00:00 2001 From: Junha Heo Date: Sat, 24 Aug 2024 12:56:01 +0900 Subject: [PATCH 002/174] feat: Add gptSoVitsConfig to character interface --- src/ts/storage/database.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index f0c80c32..b4f80b2b 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -802,6 +802,18 @@ export interface character{ voice?: string version?: string } + gptSoVitsConfig?:{ + ref_audio_data?:string + text_lang?: "auto" | "auto_yue" | "en" | "zh" | "ja" | "yue" | "ko" | "all_zh" | "all_ja" | "all_yue" | "all_ko" + text?:string + prompt?:string | null + prompt_lang?:string + top_p?:number + temperature?:number + speed?:number + top_k?:number + text_split_method?:string + } supaMemory?:boolean additionalAssets?:[string, string, string][] ttsReadOnlyQuoted?:boolean From d5837e51a676b4ba3b6e4d836e9467ad1bc18b4a Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 24 Aug 2024 15:14:54 +0900 Subject: [PATCH 003/174] Add claude plain fetch header --- src/ts/process/request.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index e139b6fe..277a8a0b 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -1997,6 +1997,10 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' headers['anthropic-beta'] = 'prompt-caching-2024-07-31' } + if(db.usePlainFetch){ + headers['anthropic-dangerous-direct-browser-access'] = 'true' + } + if(useStreaming){ const res = await fetchNative(replacerURL, { From d51e168590232815cd76c064aff1c10fd03af060 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 24 Aug 2024 15:16:33 +0900 Subject: [PATCH 004/174] Add gemini pro exp 0801 --- src/lib/UI/ModelList.svelte | 1 + src/ts/model/names.ts | 2 ++ src/ts/process/request.ts | 1 + 3 files changed, 4 insertions(+) diff --git a/src/lib/UI/ModelList.svelte b/src/lib/UI/ModelList.svelte index 38f452f3..a519f447 100644 --- a/src/lib/UI/ModelList.svelte +++ b/src/lib/UI/ModelList.svelte @@ -104,6 +104,7 @@ + diff --git a/src/ts/model/names.ts b/src/ts/model/names.ts index ffc08d98..701e232a 100644 --- a/src/ts/model/names.ts +++ b/src/ts/model/names.ts @@ -109,6 +109,8 @@ export function getModelName(name:string){ return 'GPT-4o Mini (2024-07-18)' case 'gemini-1.5-pro-latest': return 'Gemini 1.5 Pro' + case 'gemini-1.5-pro-exp-0801': + return 'Gemini 1.5 Pro Exp (0801)' case 'gemini-1.5-flash': return 'Gemini 1.5 Flash' case 'ollama-hosted': diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 277a8a0b..24cc1d2c 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -1153,6 +1153,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' case 'gemini-pro': case 'gemini-pro-vision': case 'gemini-1.5-pro-latest': + case 'gemini-1.5-pro-exp-0801': case 'gemini-1.5-flash': case 'gemini-ultra': case 'gemini-ultra-vision':{ From 83e1b8705f16d7cdc6dd490e8eeedaf7c200c0ba Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 24 Aug 2024 15:17:31 +0900 Subject: [PATCH 005/174] Remove unnessesery imports --- src/lib/Setting/Pages/UserSettings.svelte | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/lib/Setting/Pages/UserSettings.svelte b/src/lib/Setting/Pages/UserSettings.svelte index 7418e4d5..6130a87c 100644 --- a/src/lib/Setting/Pages/UserSettings.svelte +++ b/src/lib/Setting/Pages/UserSettings.svelte @@ -1,10 +1,10 @@
diff --git a/src/ts/gui/colorscheme.ts b/src/ts/gui/colorscheme.ts index 790147e9..32783836 100644 --- a/src/ts/gui/colorscheme.ts +++ b/src/ts/gui/colorscheme.ts @@ -230,8 +230,8 @@ export function updateTextTheme(){ root.style.setProperty('--FontColorItalic', db.customTextTheme.FontColorItalic); root.style.setProperty('--FontColorBold', db.customTextTheme.FontColorBold); root.style.setProperty('--FontColorItalicBold', db.customTextTheme.FontColorItalicBold); - root.style.setProperty('--FontColorQuote1', db.customTextTheme.FontColorQuote1); - root.style.setProperty('--FontColorQuote2', db.customTextTheme.FontColorQuote2); + root.style.setProperty('--FontColorQuote1', db.customTextTheme.FontColorQuote1 ?? '#8BE9FD'); + root.style.setProperty('--FontColorQuote2', db.customTextTheme.FontColorQuote2 ?? '#FFB86C'); break } } diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 3d4ff799..86907784 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -79,11 +79,19 @@ DOMPurify.addHook("uponSanitizeAttribute", (node, data) => { function renderMarkdown(md:markdownit, data:string){ - return md.render(data.replace(/“|”/g, '"').replace(/‘|’/g, "'")) - .replace(/\uE9b0/gu, '“') - .replace(/\uE9b1/gu, '”') - .replace(/\uE9b2/gu, '‘') - .replace(/\uE9b3/gu, '’') + const db = get(DataBase) + let text = md.render(data.replace(/“|”/g, '"').replace(/‘|’/g, "'")) + + if(db?.unformatQuotes){ + text = text.replace(/\uE9b0/gu, '“').replace(/\uE9b1/gu, '”') + text = text.replace(/\uE9b2/gu, '‘').replace(/\uE9b3/gu, '’') + } + else{ + text = text.replace(/\uE9b0/gu, '“').replace(/\uE9b1/gu, '”') + text = text.replace(/\uE9b2/gu, '‘').replace(/\uE9b3/gu, '’') + } + + return text } async function renderHighlightableMarkdown(data:string) { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index d007f8ec..8ee858fd 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -429,6 +429,7 @@ export function setDatabase(data:Database){ timeout: 30 } data.hideApiKey ??= true + data.unformatQuotes ??= false changeLanguage(data.language) DataBase.set(data) @@ -712,6 +713,7 @@ export interface Database{ useLegacyGUI: boolean claudeCachingExperimental: boolean hideApiKey: boolean + unformatQuotes: boolean } export interface customscript{ From 14fb2267c316efaddf8ad716c4c25db372e39856 Mon Sep 17 00:00:00 2001 From: Junha Heo Date: Sat, 24 Aug 2024 17:37:27 +0900 Subject: [PATCH 011/174] feat: Add support for gptSoVitsConfig in TTS processing --- src/lib/SideBars/CharConfig.svelte | 137 +++++++++++++++++++++++++++-- src/ts/process/tts.ts | 63 ++++++++++++- src/ts/storage/database.ts | 13 ++- 3 files changed, 199 insertions(+), 14 deletions(-) diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte index 554beb21..914cc8b4 100644 --- a/src/lib/SideBars/CharConfig.svelte +++ b/src/lib/SideBars/CharConfig.svelte @@ -9,7 +9,7 @@ import LoreBook from "./LoreBook/LoreBookSetting.svelte"; import { alertConfirm, alertMd, alertNormal, alertSelectChar, alertTOS, showHypaV2Alert } from "../../ts/alert"; import BarIcon from "./BarIcon.svelte"; - import { findCharacterbyId, getAuthorNoteDefaultText, parseKeyValue, selectMultipleFile } from "../../ts/util"; + import { findCharacterbyId, getAuthorNoteDefaultText, parseKeyValue, selectMultipleFile, selectSingleFile } from "../../ts/util"; import { onDestroy } from "svelte"; import {isEqual} from 'lodash' import Help from "../Others/Help.svelte"; @@ -29,7 +29,8 @@ import { updateInlayScreen } from "src/ts/process/inlayScreen"; import { registerOnnxModel } from "src/ts/process/transformers"; import MultiLangInput from "../UI/GUI/MultiLangInput.svelte"; - import { applyModule } from "src/ts/process/modules"; + import { applyModule } from "src/ts/process/modules"; + import SliderInput from "../UI/GUI/SliderInput.svelte"; let subMenu = 0 @@ -103,6 +104,12 @@ } emos = currentChar.data.emotionImages currentChar = currentChar + + if (currentChar.data.ttsMode === 'gptsovits' && (currentChar.data as character).gptSoVitsConfig) { + if (!(currentChar.data as character).gptSoVitsConfig.use_prompt) { + (currentChar.data as character).gptSoVitsConfig.prompt = undefined + } + } }) let assetFileExtensions:string[] = [] @@ -147,6 +154,27 @@ version: 'v2' }; } + $: if (currentChar.data.ttsMode === 'gptsovits' && (currentChar.data as character).gptSoVitsConfig === undefined) { + (currentChar.data as character).gptSoVitsConfig = { + url: '', + ref_audio_path: 'C:/Users/user/Downloads/GPT-SoVITS-v2-240821', + ref_audio_data: { + fileName: '', + assetId: '' + }, + volume: 1.0, + text_lang: 'auto', + text: 'en', + use_prompt: false, + prompt_lang: 'en', + top_p: 1, + temperature: 0.7, + speed: 1, + top_k: 5, + text_split_method: 'cut0', + }; + } + {#if licensed !== 'private'} @@ -668,7 +696,7 @@ {#if currentChar.type === 'character'}

TTS

{language.provider} - { + { if(currentChar.type === 'character'){ currentChar.data.ttsSpeech = '' } @@ -681,6 +709,7 @@ NovelAI Huggingface VITS + GPT-SoVITS @@ -764,23 +793,20 @@ v1 v2 - {/if} - {#if currentChar.data.ttsMode === 'openai'} + {:else if currentChar.data.ttsMode === 'openai'} Unset {#each oaiVoices as voice} {voice} {/each} - {/if} - {#if currentChar.data.ttsMode === 'huggingface'} + {:else if currentChar.data.ttsMode === 'huggingface'} Model Language - {/if} - {#if currentChar.data.ttsMode === 'vits'} + {:else if currentChar.data.ttsMode === 'vits'} {#if currentChar.data.vits} {currentChar.data.vits.name ?? 'Unnamed VitsModel'} {:else} @@ -792,6 +818,99 @@ currentChar.data.vits = model } }}>{language.selectModel} + {:else if currentChar.data.ttsMode === 'gptsovits'} + Volume + + URL + + + Reference Audio Path (e.g. C:/Users/user/Downloads/GPT-SoVITS-v2-240821) + + + Reference Audio Data (3~10s audio file) + + Text Language + + Auto + Auto (Cantonese) + English + Chinese + Japanese + Cantonese + Korean + All Chinese + All Japanese + All Cantonese + All Korean + + + Use Reference Audio Script + + + {#if currentChar.data.gptSoVitsConfig.use_prompt} + Reference Audio Script + + {/if} + + Reference Audio Language + + Auto + Auto (Cantonese) + English + Chinese + Japanese + Cantonese + Korean + English And Chinese + English And Japanese + English And Cantonese + English And Korean + + Top P + + + Temperature + + + Speed + + + Top K + + + Text Split Method + + Cut 0 (No splitting) + Cut 1 (Split every 4 sentences) + Cut 2 (Split every 50 characters) + Cut 3 (Split by Chinese periods) + Cut 4 (Split by English periods) + Cut 5 (Split by various punctuation marks) + {/if} {#if currentChar.data.ttsMode}
diff --git a/src/ts/process/tts.ts b/src/ts/process/tts.ts index db3e32c2..6ecbb755 100644 --- a/src/ts/process/tts.ts +++ b/src/ts/process/tts.ts @@ -2,7 +2,7 @@ import { get } from "svelte/store"; import { alertError } from "../alert"; import { DataBase, type character } from "../storage/database"; import { runTranslator, translateVox } from "../translator/translator"; -import { globalFetch } from "../storage/globalApi"; +import { globalFetch, loadAsset } from "../storage/globalApi"; import { language } from "src/lang"; import { getCurrentCharacter, sleep } from "../util"; import { registerOnnxModel, runVITS } from "./transformers"; @@ -27,7 +27,7 @@ export async function sayTTS(character:character,text:string) { text = text.replace(/\*/g,'') if(character.ttsReadOnlyQuoted){ - const matches = text.match(/"(.*?)"/g) + const matches = text.match(/["「](.*?)["」]/g) if(matches && matches.length > 0){ text = matches.map(match => match.slice(1, -1)).join(""); } @@ -231,12 +231,71 @@ export async function sayTTS(character:character,text:string) { case 'vits':{ await runVITS(text, character.vits) } + case 'gptsovits':{ + const audioContext = new AudioContext(); + + const audio: Uint8Array = await loadAsset(character.gptSoVitsConfig.ref_audio_data.assetId); + const base64Audio = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), '')); + + const body = { + text: text, + text_lang: character.gptSoVitsConfig.text_lang, + ref_audio_path: character.gptSoVitsConfig.ref_audio_path + '/public/audio/' + character.gptSoVitsConfig.ref_audio_data.fileName, + ref_audio_name: character.gptSoVitsConfig.ref_audio_data.fileName, + ref_audio_data: base64Audio, + prompt_text: undefined, + prompt_lang: character.gptSoVitsConfig.prompt_lang, + top_p: character.gptSoVitsConfig.top_p, + temperature: character.gptSoVitsConfig.temperature, + speed_factor: character.gptSoVitsConfig.speed, + top_k: character.gptSoVitsConfig.top_k, + text_split_method: character.gptSoVitsConfig.text_split_method, + parallel_infer: false, + } + + if (character.gptSoVitsConfig.use_prompt){ + body.prompt_text = character.gptSoVitsConfig.prompt + } + console.log(body) + + const response = await globalFetch(`${character.gptSoVitsConfig.url}/tts`, { + method: 'POST', + headers: { + "Content-Type": "application/json", + }, + body: body, + rawResponse: true, + }) + console.log(response) + + if (response.ok) { + const audioBuffer = response.data.buffer; + audioContext.decodeAudioData(audioBuffer, (decodedData) => { + const sourceNode = audioContext.createBufferSource(); + sourceNode.buffer = decodedData; + + const gainNode = audioContext.createGain(); + gainNode.gain.value = character.gptSoVitsConfig.volume || 1.0; + + sourceNode.connect(gainNode); + gainNode.connect(audioContext.destination); + + sourceNode.start(); + }); + } else { + const textBuffer: Uint8Array = response.data.buffer + const text = Buffer.from(textBuffer).toString('utf-8') + throw new Error(text); + } + } } } catch (error) { alertError(`TTS Error: ${error}`) } } + + export const oaiVoices = [ 'alloy', 'echo', 'fable', 'onyx', 'nova', 'shimmer' ] diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index b4f80b2b..1f5f8b26 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -803,16 +803,23 @@ export interface character{ version?: string } gptSoVitsConfig?:{ - ref_audio_data?:string + url?:string + ref_audio_path?:string + ref_audio_data?: { + fileName:string + assetId:string + } + volume?:number text_lang?: "auto" | "auto_yue" | "en" | "zh" | "ja" | "yue" | "ko" | "all_zh" | "all_ja" | "all_yue" | "all_ko" text?:string + use_prompt?:boolean prompt?:string | null - prompt_lang?:string + prompt_lang?: "auto" | "auto_yue" | "en" | "zh" | "ja" | "yue" | "ko" | "all_zh" | "all_ja" | "all_yue" | "all_ko" top_p?:number temperature?:number speed?:number top_k?:number - text_split_method?:string + text_split_method?: "cut0" | "cut1" | "cut2" | "cut3" | "cut4" | "cut5" } supaMemory?:boolean additionalAssets?:[string, string, string][] From c14503625f04c1b2012a3accc5bcabfc33672d9d Mon Sep 17 00:00:00 2001 From: Junha Heo Date: Sat, 24 Aug 2024 17:57:34 +0900 Subject: [PATCH 012/174] refactor: Update translator.ts to include auto language detection --- src/ts/translator/translator.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/translator/translator.ts b/src/ts/translator/translator.ts index 7640249b..f7f447ec 100644 --- a/src/ts/translator/translator.ts +++ b/src/ts/translator/translator.ts @@ -165,7 +165,7 @@ async function translateMain(text:string, arg:{from:string, to:string, host:stri } - const url = `https://${arg.host}/translate_a/single?client=gtx&dt=t&sl=${arg.from}&tl=${arg.to}&q=` + encodeURIComponent(text) + const url = `https://${arg.host}/translate_a/single?client=gtx&dt=t&sl=auto&tl=${arg.to}&q=` + encodeURIComponent(text) From b1d98741e838ccf8e0275a6c878fb39199807e60 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 24 Aug 2024 18:46:49 +0900 Subject: [PATCH 013/174] Add persona and preset hotkey --- src/App.svelte | 10 ++++++- src/lib/Setting/Pages/BotSettings.svelte | 6 ++-- src/lib/Setting/Settings.svelte | 6 +--- src/lib/Setting/listedPersona.svelte | 38 ++++++++++++++++++++++++ src/lib/SideBars/Sidebar.svelte | 9 ------ src/ts/hotkey.ts | 14 ++++++++- src/ts/stores.ts | 3 +- 7 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 src/lib/Setting/listedPersona.svelte diff --git a/src/App.svelte b/src/App.svelte index 9efe1fb5..3f718658 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -1,6 +1,6 @@ + +
+
+
+

{language.persona}

+
+ +
+
+ {#each $DataBase.personas as persona, i} + + {/each} +
+
+ + \ No newline at end of file diff --git a/src/lib/SideBars/Sidebar.svelte b/src/lib/SideBars/Sidebar.svelte index 47322209..e3a73290 100644 --- a/src/lib/SideBars/Sidebar.svelte +++ b/src/lib/SideBars/Sidebar.svelte @@ -52,7 +52,6 @@ import SideChatList from "./SideChatList.svelte"; import { joinMultiuserRoom } from "src/ts/sync/multiuser"; import { sideBarSize } from "src/ts/gui/guisize"; - let openPresetList = false; let sideBarMode = 0; let editMode = false; let menuMode = 0; @@ -703,14 +702,6 @@ {/if}
-{#if openPresetList} - { - openPresetList = false; - }} - /> -{/if} - {#if $DynamicGUI}
{ if($sideBarClosing){ diff --git a/src/ts/hotkey.ts b/src/ts/hotkey.ts index c58b9086..a6681556 100644 --- a/src/ts/hotkey.ts +++ b/src/ts/hotkey.ts @@ -1,7 +1,7 @@ import { get } from "svelte/store" import { alertToast, doingAlert } from "./alert" import { DataBase, changeToPreset as changeToPreset2 } from "./storage/database" -import { selectedCharID, settingsOpen } from "./stores" +import { openPersonaList, openPresetList, selectedCharID, settingsOpen } from "./stores" export function initHotkey(){ document.addEventListener('keydown', (ev) => { @@ -73,6 +73,18 @@ export function initHotkey(){ ev.stopPropagation() break } + case 'p':{ + openPresetList.set(!get(openPresetList)) + ev.preventDefault() + ev.stopPropagation() + break + } + case 'e':{ + openPersonaList.set(!get(openPersonaList)) + ev.preventDefault() + ev.stopPropagation() + break + } } } if(ev.key === 'Escape'){ diff --git a/src/ts/stores.ts b/src/ts/stores.ts index 2b3a6f2d..0bfeb59a 100644 --- a/src/ts/stores.ts +++ b/src/ts/stores.ts @@ -26,7 +26,8 @@ export const ViewBoxsize = writable({ width: 12 * 16, height: 12 * 16 }); // Def export const settingsOpen = writable(false) export const botMakerMode = writable(false) export const moduleBackgroundEmbedding = writable('') - +export const openPresetList = writable(false) +export const openPersonaList = writable(false) //optimization export const CurrentCharacter = writable(null) as Writable From 9d82b1dbd6343c3be846c5db63962db5cfd6ff44 Mon Sep 17 00:00:00 2001 From: Junha Heo Date: Sat, 24 Aug 2024 19:01:52 +0900 Subject: [PATCH 014/174] feat: Add support for AAC audio files in CharConfig.svelte --- src/lib/SideBars/CharConfig.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte index 914cc8b4..00441f7f 100644 --- a/src/lib/SideBars/CharConfig.svelte +++ b/src/lib/SideBars/CharConfig.svelte @@ -830,9 +830,9 @@ Reference Audio Data (3~10s audio file)
+
+ + +
diff --git a/src/lib/SideBars/DevTool.svelte b/src/lib/SideBars/DevTool.svelte new file mode 100644 index 00000000..1cb7a567 --- /dev/null +++ b/src/lib/SideBars/DevTool.svelte @@ -0,0 +1,25 @@ + + +Variables +
+ {#if $CurrentChat.scriptstate && Object.keys($CurrentChat.scriptstate).length > 0} + {#each Object.keys($CurrentChat.scriptstate) as key} + {key} + {#if typeof $CurrentChat.scriptstate[key] === "object"} +
Object
+ {:else if typeof $CurrentChat.scriptstate[key] === "string"} + + {:else if typeof $CurrentChat.scriptstate[key] === "number"} + + {/if} + {/each} + {:else} +
No variables
+ {/if} +
\ No newline at end of file diff --git a/src/lib/SideBars/Sidebar.svelte b/src/lib/SideBars/Sidebar.svelte index e3a73290..30d4b39c 100644 --- a/src/lib/SideBars/Sidebar.svelte +++ b/src/lib/SideBars/Sidebar.svelte @@ -52,9 +52,11 @@ import SideChatList from "./SideChatList.svelte"; import { joinMultiuserRoom } from "src/ts/sync/multiuser"; import { sideBarSize } from "src/ts/gui/guisize"; + import DevTool from "./DevTool.svelte"; let sideBarMode = 0; let editMode = false; let menuMode = 0; + let devTool = false export let openGrid = () => {}; function createScratch() { @@ -658,10 +660,23 @@ {:else}
- - + + + {#if $DataBase.enableDevTools} + + {/if}
- {#if $botMakerMode} + {#if devTool} + + {:else if $botMakerMode} {:else} diff --git a/src/lib/UI/GUI/TextInput.svelte b/src/lib/UI/GUI/TextInput.svelte index acb6605d..c8f95016 100644 --- a/src/lib/UI/GUI/TextInput.svelte +++ b/src/lib/UI/GUI/TextInput.svelte @@ -60,7 +60,9 @@ type="text" bind:value disabled={disabled} - on:input={onInput} + on:input={(e) => { + onInput(e) + }} /> {/if} @@ -73,7 +75,9 @@ export let padding = true export let marginBottom = false export let marginTop = false - export let onInput = () => {} + export let onInput = (e:Event & { + currentTarget: EventTarget & HTMLInputElement; + }) => {} export let fullwidth = false export let fullh = false export let className = '' diff --git a/src/ts/hotkey.ts b/src/ts/hotkey.ts index a6681556..2ffe0007 100644 --- a/src/ts/hotkey.ts +++ b/src/ts/hotkey.ts @@ -1,7 +1,8 @@ import { get } from "svelte/store" -import { alertToast, doingAlert } from "./alert" +import { alertSelect, alertToast, doingAlert } from "./alert" import { DataBase, changeToPreset as changeToPreset2 } from "./storage/database" import { openPersonaList, openPresetList, selectedCharID, settingsOpen } from "./stores" +import { language } from "src/lang" export function initHotkey(){ document.addEventListener('keydown', (ev) => { @@ -97,6 +98,35 @@ export function initHotkey(){ ev.preventDefault() } }) + + + let touchs = 0 + //check for triple touch + document.addEventListener('touchstart', async (ev) => { + touchs++ + if(touchs > 2){ + touchs = 0 + if(doingAlert()){ + return + } + const selStr = await alertSelect([ + language.presets, + language.persona + ]) + const sel = parseInt(selStr) + if(sel === 0){ + openPresetList.set(!get(openPresetList)) + } + if(sel === 1){ + openPersonaList.set(!get(openPersonaList)) + } + + + } + }) + document.addEventListener('touchend', (ev) => { + touchs = 0 + }) } function changeToPreset(num:number){ diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 8ee858fd..ae562422 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -714,6 +714,7 @@ export interface Database{ claudeCachingExperimental: boolean hideApiKey: boolean unformatQuotes: boolean + enableDevTools: boolean } export interface customscript{ From 721fda615143f8909a92e2fd68b4050b7dfbcf56 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 24 Aug 2024 19:54:10 +0900 Subject: [PATCH 016/174] Add request log in devtool --- src/lib/SideBars/DevTool.svelte | 43 ++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/lib/SideBars/DevTool.svelte b/src/lib/SideBars/DevTool.svelte index 1cb7a567..085dadcb 100644 --- a/src/lib/SideBars/DevTool.svelte +++ b/src/lib/SideBars/DevTool.svelte @@ -2,24 +2,33 @@ import { CurrentChat } from "src/ts/stores"; import TextInput from "../UI/GUI/TextInput.svelte"; import NumberInput from "../UI/GUI/NumberInput.svelte"; + import Button from "../UI/GUI/Button.svelte"; + import { getRequestLog } from "src/ts/storage/globalApi"; + import { alertMd } from "src/ts/alert"; + import Arcodion from "../UI/Arcodion.svelte"; -Variables -
- {#if $CurrentChat.scriptstate && Object.keys($CurrentChat.scriptstate).length > 0} - {#each Object.keys($CurrentChat.scriptstate) as key} - {key} - {#if typeof $CurrentChat.scriptstate[key] === "object"} -
Object
- {:else if typeof $CurrentChat.scriptstate[key] === "string"} - - {:else if typeof $CurrentChat.scriptstate[key] === "number"} - - {/if} - {/each} - {:else} -
No variables
- {/if} -
\ No newline at end of file + +
+ {#if $CurrentChat.scriptstate && Object.keys($CurrentChat.scriptstate).length > 0} + {#each Object.keys($CurrentChat.scriptstate) as key} + {key} + {#if typeof $CurrentChat.scriptstate[key] === "object"} +
Object
+ {:else if typeof $CurrentChat.scriptstate[key] === "string"} + + {:else if typeof $CurrentChat.scriptstate[key] === "number"} + + {/if} + {/each} + {:else} +
No variables
+ {/if} +
+
+ + \ No newline at end of file From 40779e030c878f38052d19ae3c47c3a6ac737e50 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 24 Aug 2024 19:54:42 +0900 Subject: [PATCH 017/174] chore: Bump version to 125.0.0 --- android/app/build.gradle | 2 +- android/app/release/output-metadata.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index d48fc088..493050d7 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -8,7 +8,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 2 - versionName "124.2.2" + versionName "125.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json index ef625ab2..6e912f3b 100644 --- a/android/app/release/output-metadata.json +++ b/android/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 2, - "versionName": "124.2.2", + "versionName": "125.0.0", "outputFile": "app-release.apk" } ], diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index ba8da883..70e21ef6 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "124.2.2" + "version": "125.0.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index ae562422..8209b5c6 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "124.2.2" +export let appVer = "125.0.0" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index 9c14a55a..f9868436 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"124.2.2"} \ No newline at end of file +{"version":"125.0.0"} \ No newline at end of file From b9721b80c50a1f2b6f1ad93ca6c670b553ad8a91 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 24 Aug 2024 21:17:48 +0900 Subject: [PATCH 018/174] Add touchstarttimer --- src/ts/hotkey.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ts/hotkey.ts b/src/ts/hotkey.ts index 2ffe0007..8af7e5e7 100644 --- a/src/ts/hotkey.ts +++ b/src/ts/hotkey.ts @@ -101,17 +101,22 @@ export function initHotkey(){ let touchs = 0 + let touchStartTime = 0 //check for triple touch document.addEventListener('touchstart', async (ev) => { touchs++ if(touchs > 2){ + if(Date.now() - touchStartTime > 300){ + return + } touchs = 0 if(doingAlert()){ return } const selStr = await alertSelect([ language.presets, - language.persona + language.persona, + language.cancel ]) const sel = parseInt(selStr) if(sel === 0){ @@ -120,8 +125,9 @@ export function initHotkey(){ if(sel === 1){ openPersonaList.set(!get(openPersonaList)) } - - + } + if(touchs === 1){ + touchStartTime = Date.now() } }) document.addEventListener('touchend', (ev) => { From fff99d134e74feae7783ccdac1711df83912e8f6 Mon Sep 17 00:00:00 2001 From: Junha Heo Date: Sun, 25 Aug 2024 21:00:47 +0900 Subject: [PATCH 019/174] refactor: Update server.js to use express.json and express.raw for request parsing --- server/node/server.cjs | 56 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/server/node/server.cjs b/server/node/server.cjs index 00c9de80..abf88d98 100644 --- a/server/node/server.cjs +++ b/server/node/server.cjs @@ -3,12 +3,11 @@ const app = express(); const path = require('path'); const htmlparser = require('node-html-parser'); const { existsSync, mkdirSync, readFileSync, writeFileSync } = require('fs'); -const bodyParser = require('body-parser'); const fs = require('fs/promises') const crypto = require('crypto') app.use(express.static(path.join(process.cwd(), 'dist'), {index: false})); -app.use(bodyParser.raw({ limit: 100000000 })); -app.use(bodyParser.json()) +app.use(express.json({ limit: '50mb' })); +app.use(express.raw({ type: 'application/octet-stream', limit: '50mb' })); const {pipeline} = require('stream/promises') let password = '' @@ -90,6 +89,55 @@ const reverseProxyFunc = async (req, res, next) => { } } +const reverseProxyFunc_get = async (req, res, next) => { + const urlParam = req.headers['risu-url'] ? decodeURIComponent(req.headers['risu-url']) : req.query.url; + + if (!urlParam) { + res.status(400).send({ + error:'URL has no param' + }); + return; + } + const header = req.headers['risu-header'] ? JSON.parse(decodeURIComponent(req.headers['risu-header'])) : req.headers; + if(!header['x-forwarded-for']){ + header['x-forwarded-for'] = req.ip + } + let originalResponse; + try { + // make request to original server + originalResponse = await fetch(urlParam, { + method: 'GET', + headers: header + }); + // get response body as stream + const originalBody = originalResponse.body; + // get response headers + const head = new Headers(originalResponse.headers); + head.delete('content-security-policy'); + head.delete('content-security-policy-report-only'); + head.delete('clear-site-data'); + head.delete('Cache-Control'); + head.delete('Content-Encoding'); + const headObj = {}; + for (let [k, v] of head) { + headObj[k] = v; + } + // send response headers to client + res.header(headObj); + // send response status to client + res.status(originalResponse.status); + // send response body to client + await pipeline(originalResponse.body, res); + } + catch (err) { + next(err); + return; + } +} + +app.get('/proxy', reverseProxyFunc_get); +app.get('/proxy2', reverseProxyFunc_get); + app.post('/proxy', reverseProxyFunc); app.post('/proxy2', reverseProxyFunc); @@ -248,4 +296,4 @@ app.post('/api/write', async (req, res, next) => { app.listen(6001, () => { console.log("Server is listening on http://localhost:6001/"); -}); +}); \ No newline at end of file From 7fa5289c45c0f5ddc5ff5cbca26596e16b2a02e4 Mon Sep 17 00:00:00 2001 From: Junha Heo Date: Sun, 25 Aug 2024 21:01:22 +0900 Subject: [PATCH 020/174] feat: Add translator input language selection in LanguageSettings.svelte --- src/lib/Setting/Pages/LanguageSettings.svelte | 15 +++++++++++++++ src/ts/storage/database.ts | 7 ++++++- src/ts/translator/translator.ts | 2 +- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/lib/Setting/Pages/LanguageSettings.svelte b/src/lib/Setting/Pages/LanguageSettings.svelte index 23cdfe32..3ffafe78 100644 --- a/src/lib/Setting/Pages/LanguageSettings.svelte +++ b/src/lib/Setting/Pages/LanguageSettings.svelte @@ -117,6 +117,21 @@ {/if} + {#if $DataBase.translatorType === 'google'} + Translator Input Language + + Auto + English + Chinese + Japanese + Korean + French + Spanish + German + Russian + + {/if} +
diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index af44f990..67f85949 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -430,7 +430,8 @@ export function setDatabase(data:Database){ } data.hideApiKey ??= true data.unformatQuotes ??= false - + data.ttsAutoSpeech ??= false + data.translatorInputLanguage ??= 'auto' changeLanguage(data.language) DataBase.set(data) } @@ -510,6 +511,7 @@ export interface Database{ NAII2I:boolean NAIREF:boolean NAIImgConfig:NAIImgConfig + ttsAutoSpeech?:boolean runpodKey:string promptPreprocess:boolean bias: [string, number][] @@ -614,6 +616,7 @@ export interface Database{ emotionProcesser:'submodel'|'embedding', showMenuChatList?:boolean, translatorType:'google'|'deepl'|'none'|'llm'|'deeplX', + translatorInputLanguage?:string NAIadventure?:boolean, NAIappendName?:boolean, deeplOptions:{ @@ -809,7 +812,9 @@ export interface character{ } gptSoVitsConfig?:{ url?:string + use_auto_path?:boolean ref_audio_path?:string + use_long_audio?:boolean ref_audio_data?: { fileName:string assetId:string diff --git a/src/ts/translator/translator.ts b/src/ts/translator/translator.ts index f7f447ec..90d7f321 100644 --- a/src/ts/translator/translator.ts +++ b/src/ts/translator/translator.ts @@ -165,7 +165,7 @@ async function translateMain(text:string, arg:{from:string, to:string, host:stri } - const url = `https://${arg.host}/translate_a/single?client=gtx&dt=t&sl=auto&tl=${arg.to}&q=` + encodeURIComponent(text) + const url = `https://${arg.host}/translate_a/single?client=gtx&dt=t&sl=${db.translatorInputLanguage}&tl=${arg.to}&q=` + encodeURIComponent(text) From 80bfc12461d7ef49fe58a0120b3eefcb7acd1ffa Mon Sep 17 00:00:00 2001 From: Junha Heo Date: Sun, 25 Aug 2024 21:02:07 +0900 Subject: [PATCH 021/174] feat: Add auto speech option in OtherBotSettings.svelte --- src/lib/Setting/Pages/OtherBotSettings.svelte | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/lib/Setting/Pages/OtherBotSettings.svelte b/src/lib/Setting/Pages/OtherBotSettings.svelte index 2efd6801..94b665e5 100644 --- a/src/lib/Setting/Pages/OtherBotSettings.svelte +++ b/src/lib/Setting/Pages/OtherBotSettings.svelte @@ -13,6 +13,7 @@ import Button from "src/lib/UI/GUI/Button.svelte"; import { getCharImage } from "src/ts/characters"; import Arcodion from "src/lib/UI/Arcodion.svelte"; + import CheckInput from "src/lib/UI/GUI/CheckInput.svelte"; $:{ $DataBase.NAIImgConfig ??= { width: 512, @@ -299,6 +300,9 @@ {#if submenu === 1 || submenu === -1} + Auto Speech + + ElevenLabs API key From bcb352942eab692e6a092fea182e2ffe4248d8dd Mon Sep 17 00:00:00 2001 From: Junha Heo Date: Sun, 25 Aug 2024 21:02:31 +0900 Subject: [PATCH 022/174] refactor: Update TTS function to handle auto audio path --- src/lib/SideBars/CharConfig.svelte | 74 +++++++++++++++++++----------- src/ts/process/tts.ts | 31 +++++++++++-- 2 files changed, 74 insertions(+), 31 deletions(-) diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte index 2da312a0..a35b1b5f 100644 --- a/src/lib/SideBars/CharConfig.svelte +++ b/src/lib/SideBars/CharConfig.svelte @@ -112,6 +112,13 @@ if (!(currentChar.data as character).gptSoVitsConfig.use_prompt) { (currentChar.data as character).gptSoVitsConfig.prompt = undefined } + if((currentChar.data as character).gptSoVitsConfig.use_auto_path){ + (currentChar.data as character).gptSoVitsConfig.ref_audio_path = undefined; + + (currentChar.data as character).gptSoVitsConfig.use_prompt = false; + (currentChar.data as character).gptSoVitsConfig.prompt = undefined; + + } } }) @@ -160,7 +167,9 @@ $: if (currentChar.data.ttsMode === 'gptsovits' && (currentChar.data as character).gptSoVitsConfig === undefined) { (currentChar.data as character).gptSoVitsConfig = { url: '', - ref_audio_path: 'C:/Users/user/Downloads/GPT-SoVITS-v2-240821', + use_auto_path: false, + ref_audio_path: '', + use_long_audio: false, ref_audio_data: { fileName: '', assetId: '' @@ -835,15 +844,24 @@ URL - Reference Audio Path (e.g. C:/Users/user/Downloads/GPT-SoVITS-v2-240821) - + Use Auto Path + + + {#if !currentChar.data.gptSoVitsConfig.use_auto_path} + Reference Audio Path (e.g. C:/Users/user/Downloads/GPT-SoVITS-v2-240821) + + {/if} + + Use Long Audio + Reference Audio Data (3~10s audio file) Text Language - Auto - Auto (Cantonese) + Multi-language Mixed + Multi-language Mixed (Cantonese) English - Chinese - Japanese - Cantonese - Korean - All Chinese - All Japanese - All Cantonese - All Korean + Chinese-English Mixed + Japanese-English Mixed + Cantonese-English Mixed + Korean-English Mixed + Chinese + Japanese + Cantonese + Korean - Use Reference Audio Script - + {#if !currentChar.data.gptSoVitsConfig.use_long_audio} + Use Reference Audio Script + + {/if} - {#if currentChar.data.gptSoVitsConfig.use_prompt} + {#if currentChar.data.gptSoVitsConfig.use_prompt && !currentChar.data.gptSoVitsConfig.use_long_audio} Reference Audio Script {/if} Reference Audio Language - Auto - Auto (Cantonese) + Multi-language Mixed + Multi-language Mixed (Cantonese) English - Chinese - Japanese - Cantonese - Korean - English And Chinese - English And Japanese - English And Cantonese - English And Korean + Chinese-English Mixed + Japanese-English Mixed + Cantonese-English Mixed + Korean-English Mixed + Chinese + Japanese + Cantonese + Korean Top P diff --git a/src/ts/process/tts.ts b/src/ts/process/tts.ts index 6ecbb755..57a4dbfe 100644 --- a/src/ts/process/tts.ts +++ b/src/ts/process/tts.ts @@ -235,12 +235,12 @@ export async function sayTTS(character:character,text:string) { const audioContext = new AudioContext(); const audio: Uint8Array = await loadAsset(character.gptSoVitsConfig.ref_audio_data.assetId); - const base64Audio = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), '')); + const base64Audio = btoa(new Uint8Array(audio).reduce((data, byte) => data + String.fromCharCode(byte), '')); const body = { text: text, text_lang: character.gptSoVitsConfig.text_lang, - ref_audio_path: character.gptSoVitsConfig.ref_audio_path + '/public/audio/' + character.gptSoVitsConfig.ref_audio_data.fileName, + ref_audio_path: undefined, ref_audio_name: character.gptSoVitsConfig.ref_audio_data.fileName, ref_audio_data: base64Audio, prompt_text: undefined, @@ -250,18 +250,41 @@ export async function sayTTS(character:character,text:string) { speed_factor: character.gptSoVitsConfig.speed, top_k: character.gptSoVitsConfig.top_k, text_split_method: character.gptSoVitsConfig.text_split_method, - parallel_infer: false, + parallel_infer: true, + // media_type: character.gptSoVitsConfig.ref_audio_data.fileName.split('.')[1], + ref_free: character.gptSoVitsConfig.use_long_audio || !character.gptSoVitsConfig.use_prompt, } if (character.gptSoVitsConfig.use_prompt){ body.prompt_text = character.gptSoVitsConfig.prompt } + + if (character.gptSoVitsConfig.use_auto_path){ + console.log('auto') + const path = await globalFetch(`${character.gptSoVitsConfig.url}/get_path`, { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + }, + rawResponse: false, + + }) + console.log(path) + if(path.ok){ + body.ref_audio_path = path.data.message + '/public/audio/' + character.gptSoVitsConfig.ref_audio_data.fileName + } + else{ + throw new Error('Failed to Auto get path') + } + } else { + body.ref_audio_path = character.gptSoVitsConfig.ref_audio_path + '/public/audio/' + character.gptSoVitsConfig.ref_audio_data.fileName + } console.log(body) const response = await globalFetch(`${character.gptSoVitsConfig.url}/tts`, { method: 'POST', headers: { - "Content-Type": "application/json", + 'Content-Type': 'application/json' }, body: body, rawResponse: true, From c5bd829aff79d145ae890eb1faf138492bbcd313 Mon Sep 17 00:00:00 2001 From: Junha Heo Date: Sun, 25 Aug 2024 21:02:37 +0900 Subject: [PATCH 023/174] refactor: Update TTS function to handle auto audio path --- src/ts/process/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index 483da9a8..86312035 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -1181,7 +1181,9 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n db.characters[selectedChar].chats[selectedChat] = currentChat setDatabase(db) } - await sayTTS(currentChar, result) + if(db.ttsAutoSpeech){ + await sayTTS(currentChar, result) + } } else{ const msgs = (req.type === 'success') ? [['char',req.result]] as const @@ -1240,7 +1242,9 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n mrerolls.push(result) } db.characters[selectedChar].reloadKeys += 1 - await sayTTS(currentChar, result) + if(db.ttsAutoSpeech){ + await sayTTS(currentChar, result) + } setDatabase(db) } From f7ddc092770bc31e66b7b6b3b8687c759cf50926 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 26 Aug 2024 17:20:54 +0900 Subject: [PATCH 024/174] Add TOS alert --- src/lib/Others/AlertComp.svelte | 4 ++-- src/ts/alert.ts | 4 ++-- src/ts/storage/globalApi.ts | 11 +++++++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/lib/Others/AlertComp.svelte b/src/lib/Others/AlertComp.svelte index c6eae299..69f481b7 100644 --- a/src/lib/Others/AlertComp.svelte +++ b/src/lib/Others/AlertComp.svelte @@ -80,7 +80,7 @@ {:else if $alertStore.type === 'tos'} -
You should accept RisuRealm's { + {:else if $alertStore.type !== 'select' && $alertStore.type !== 'requestdata' && $alertStore.type !== 'addchar' && $alertStore.type !== 'hypaV2' && $alertStore.type !== 'chatOptions'} @@ -112,7 +112,7 @@ msg: 'yes' }) }}>Accept - - {:else if $alertStore.submsg === 'module'} - + {:else} - - - + +
-{#if (Array.isArray(currentModule.lorebook))} - {language.loreBook} +{#if submenu === 0} + + +
+ +
+{/if} +{#if submenu === 1 && (Array.isArray(currentModule.lorebook))}
{#each currentModule.lorebook as lore, i} { @@ -151,8 +141,7 @@ {/if} -{#if (Array.isArray(currentModule.regex))} - {language.regexScript} +{#if submenu === 2 && (Array.isArray(currentModule.regex))}
{/if} -{#if typeof(currentModule.backgroundEmbedding) === 'string'} - {language.backgroundHTML} +{#if submenu === 4 && typeof(currentModule.backgroundEmbedding) === 'string'} {/if} -{#if (Array.isArray(currentModule.trigger))} - {language.triggerScript} +{#if submenu === 5 && (Array.isArray(currentModule.assets))} +
+ + + + + + {#if (!currentModule.assets) || currentModule.assets.length === 0} + +
No Assets
+ + {:else} + {#each currentModule.assets as assets, i} + + + + + + {/each} + {/if} +
{language.value} + +
+ {#if assetFilePath[i] && $DataBase.useAdditionalAssetsPreview} + {#if assetFileExtensions[i] === 'mp4'} + + + {:else if assetFileExtensions[i] === 'mp3'} + + {:else} + {assets[0]}/ + {/if} + {/if} + + + +
+
+{/if} + +{#if submenu === 3 && (Array.isArray(currentModule.trigger))}
-{/if} - -
- -
\ No newline at end of file +{/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 index 74e80420..f9186613 100644 --- a/src/lib/Setting/Pages/Module/ModuleSettings.svelte +++ b/src/lib/Setting/Pages/Module/ModuleSettings.svelte @@ -27,14 +27,6 @@ }).sort((a, b) => { let score = a.name.toLowerCase().localeCompare(b.name.toLowerCase()) - - if(db.enabledModules.includes(a.id)){ - score += 1000 - } - if(db.enabledModules.includes(b.id)){ - score -= 1000 - } - return score }) } diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 86907784..47f4860e 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -9,7 +9,7 @@ import { CurrentCharacter, CurrentChat, SizeStore, selectedCharID } from './stor import { calcString } from './process/infunctions'; import { findCharacterbyId, getPersonaPrompt, getUserIcon, getUserName, parseKeyValue, sfc32, sleep, uuidtoNumber } from './util'; import { getInlayImage, writeInlayImage } from './process/files/image'; -import { getModuleLorebooks } from './process/modules'; +import { getModuleAssets, getModuleLorebooks } from './process/modules'; import { HypaProcesser } from './process/memory/hypamemory'; import { generateAIImage } from './process/stableDiff'; import { requestChatData } from './process/request'; @@ -281,6 +281,16 @@ async function parseAdditionalAssets(data:string, char:simpleCharacterArgument|c } } } + const moduleAssets = getModuleAssets() + if(moduleAssets.length > 0){ + for(const asset of moduleAssets){ + const assetPath = await getFileSrc(asset[1]) + assetPaths[asset[0].toLocaleLowerCase()] = { + path: assetPath, + ext: asset[2] + } + } + } const videoExtention = ['mp4', 'webm', 'avi', 'm4p', 'm4v'] let needsSourceAccess = false data = data.replaceAll(assetRegex, (full:string, type:string, name:string) => { diff --git a/src/ts/process/modules.ts b/src/ts/process/modules.ts index 37ea7165..c366df6b 100644 --- a/src/ts/process/modules.ts +++ b/src/ts/process/modules.ts @@ -1,14 +1,16 @@ import { language } from "src/lang" -import { alertConfirm, alertError, alertModuleSelect, alertNormal } from "../alert" +import { alertConfirm, alertError, alertModuleSelect, alertNormal, alertStore } from "../alert" import { DataBase, setDatabase, type customscript, type loreBook, type triggerscript } from "../storage/database" -import { downloadFile } from "../storage/globalApi" +import { AppendableBuffer, downloadFile, isNodeServer, isTauri, readImage, saveAsset } from "../storage/globalApi" import { get } from "svelte/store" import { CurrentCharacter, CurrentChat } from "../stores" -import { selectSingleFile } from "../util" +import { selectSingleFile, sleep } from "../util" import { v4 } from "uuid" import { convertExternalLorebook } from "./lorebook" import { encode } from "msgpackr" import { decodeRPack, encodeRPack } from "../rpack/rpack_bg" +import { convertImage } from "../parser" +import { Capacitor } from "@capacitor/core" export interface RisuModule{ name: string @@ -21,15 +23,58 @@ export interface RisuModule{ lowLevelAccess?: boolean hideIcon?: boolean backgroundEmbedding?:string + assets?:[string,string,string][] } export async function exportModule(module:RisuModule){ - const dat = await encodeRPack(Buffer.from(JSON.stringify({ - ...module, + const apb = new AppendableBuffer() + const writeLength = (len:number) => { + const lenbuf = Buffer.alloc(4) + lenbuf.writeUInt32LE(len, 0) + apb.append(lenbuf) + } + const writeByte = (byte:number) => { + //byte is 0-255 + const buf = Buffer.alloc(1) + buf.writeUInt8(byte, 0) + apb.append(buf) + } + + const assets = module.assets ?? [] + module = structuredClone(module) + module.assets = module.assets.map((asset) => { + return [asset[0], '', asset[2]] as [string,string,string] + }) + + const mainbuf = await encodeRPack(Buffer.from(JSON.stringify({ + module: module, type: 'risuModule' }, null, 2), 'utf-8')) - await downloadFile(module.name + '.risum', dat) + writeByte(111) //magic number + writeByte(0) //version + writeLength(mainbuf.length) + apb.append(mainbuf) + + for(let i=0;i { + const len = buf.readUInt32LE(pos) + pos += 4 + return len + } + const readByte = () => { + const byte = buf.readUInt8(pos) + pos += 1 + return byte + } + const readData = (len:number) => { + const data = buf.subarray(pos, pos + len) + pos += len + return data + } + + if(readByte() !== 111){ + console.error("Invalid magic number") + alertError(language.errors.noData) + return + } + if(readByte() !== 0){ //Version check + console.error("Invalid version") + alertError(language.errors.noData) + return + } + + const mainLen = readLength() + const mainData = readData(mainLen) + const main:{ + type:'risuModule' + module:RisuModule + } = JSON.parse(Buffer.from(await decodeRPack(mainData)).toString()) + + if(main.type !== 'risuModule'){ + console.error("Invalid module type") + alertError(language.errors.noData) + return + } + + let module = main.module + + let i = 0 + while(true){ + const mark = readByte() + if(mark === 0){ + break + } + if(mark !== 1){ + alertError(language.errors.noData) + return + } + const len = readLength() + const data = readData(len) + module.assets[i][1] = await saveAsset(Buffer.from(await decodeRPack(data))) + alertStore.set({ + type: 'wait', + msg: `Loading... (Adding Assets ${i} / ${module.assets.length})` + }) + if(!isTauri && !Capacitor.isNativePlatform() &&!isNodeServer){ + await sleep(100) + } + i++ + } + alertStore.set({ + type: 'none', + msg: '' + }) + + db.modules.push(module) + setDatabase(db) + return + } catch (error) { + console.error(error) + alertError(language.errors.noData) } + } + try { const importData = JSON.parse(Buffer.from(fileData).toString()) if(importData.type === 'risuModule'){ if( @@ -155,6 +279,25 @@ export function getModuleLorebooks() { return lorebooks } +export function getModuleAssets() { + const currentChat = get(CurrentChat) + const db = get(DataBase) + if (!currentChat) return [] + let moduleIds = currentChat.modules ?? [] + moduleIds = moduleIds.concat(db.enabledModules) + const modules = getModules(moduleIds) + let assets: [string,string,string][] = [] + for (const module of modules) { + if(!module){ + continue + } + if (module.assets) { + assets = assets.concat(module.assets) + } + } + return assets +} + export function getModuleTriggers() { const currentChat = get(CurrentChat) diff --git a/src/ts/storage/globalApi.ts b/src/ts/storage/globalApi.ts index 1c0c85a5..20c37e1c 100644 --- a/src/ts/storage/globalApi.ts +++ b/src/ts/storage/globalApi.ts @@ -847,6 +847,17 @@ export function getUnpargeables(db:Database, uptype:'basename'|'pure' = 'basenam } } + if(db.modules){ + for(const module of db.modules){ + const assets = module.assets + if(assets){ + for(const asset of assets){ + addUnparge(asset[1]) + } + } + } + } + if(db.personas){ db.personas.map((v) => { addUnparge(v.icon) From 2ae5106453142997ccbe270cfb60ed71802fde66 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Tue, 27 Aug 2024 22:03:17 +0900 Subject: [PATCH 030/174] Update version to 126.0.0 --- android/app/build.gradle | 2 +- android/app/release/output-metadata.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 62372249..26a53f7d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -8,7 +8,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 2 - versionName "125.0.1" + versionName "126.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json index 7b9ef376..acd83362 100644 --- a/android/app/release/output-metadata.json +++ b/android/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 2, - "versionName": "125.0.1", + "versionName": "126.0.0", "outputFile": "app-release.apk" } ], diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 494a6654..477c5f9d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "125.0.1" + "version": "126.0.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index cfc69e52..7373238e 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "125.0.1" +export let appVer = "126.0.0" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index d814fdd1..3b093f1f 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"125.0.1"} \ No newline at end of file +{"version":"126.0.0"} \ No newline at end of file From 3b1d0f7f35809f5926d9191367bb677c8109986c Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 28 Aug 2024 20:11:15 +0900 Subject: [PATCH 031/174] Add gemini pro 0827 --- src/lib/UI/ModelList.svelte | 2 +- src/ts/model/names.ts | 2 ++ src/ts/process/request.ts | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/lib/UI/ModelList.svelte b/src/lib/UI/ModelList.svelte index a519f447..88762456 100644 --- a/src/lib/UI/ModelList.svelte +++ b/src/lib/UI/ModelList.svelte @@ -104,7 +104,7 @@ - + diff --git a/src/ts/model/names.ts b/src/ts/model/names.ts index 701e232a..41b19540 100644 --- a/src/ts/model/names.ts +++ b/src/ts/model/names.ts @@ -111,6 +111,8 @@ export function getModelName(name:string){ return 'Gemini 1.5 Pro' case 'gemini-1.5-pro-exp-0801': return 'Gemini 1.5 Pro Exp (0801)' + case 'gemini-1.5-pro-exp-0827': + return 'Gemini 1.5 Pro Exp (0827)' case 'gemini-1.5-flash': return 'Gemini 1.5 Flash' case 'ollama-hosted': diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index cdca17f8..fbda6d0d 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -1154,6 +1154,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' case 'gemini-pro-vision': case 'gemini-1.5-pro-latest': case 'gemini-1.5-pro-exp-0801': + case 'gemini-1.5-pro-exp-0827': case 'gemini-1.5-flash': case 'gemini-ultra': case 'gemini-ultra-vision':{ From 6b642e5fe5e85860710c960bfc6f7454cc93973d Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 28 Aug 2024 20:12:46 +0900 Subject: [PATCH 032/174] Update version to 126.0.1 --- android/app/build.gradle | 2 +- android/app/release/output-metadata.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 26a53f7d..d420ae2f 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -8,7 +8,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 2 - versionName "126.0.0" + versionName "126.0.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json index acd83362..5a1e1779 100644 --- a/android/app/release/output-metadata.json +++ b/android/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 2, - "versionName": "126.0.0", + "versionName": "126.0.1", "outputFile": "app-release.apk" } ], diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 477c5f9d..13609d72 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "126.0.0" + "version": "126.0.1" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 7373238e..92b02236 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "126.0.0" +export let appVer = "126.0.1" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index 3b093f1f..b0ad7340 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"126.0.0"} \ No newline at end of file +{"version":"126.0.1"} \ No newline at end of file From 2dbfa9db6c16c1fe59a32b05cf5e3dba265c5571 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 28 Aug 2024 23:57:02 +0900 Subject: [PATCH 033/174] Remove module realm option --- src/lib/Setting/Pages/Module/ModuleSettings.svelte | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/src/lib/Setting/Pages/Module/ModuleSettings.svelte b/src/lib/Setting/Pages/Module/ModuleSettings.svelte index f9186613..48b86ab5 100644 --- a/src/lib/Setting/Pages/Module/ModuleSettings.svelte +++ b/src/lib/Setting/Pages/Module/ModuleSettings.svelte @@ -65,14 +65,7 @@ From 4ca51d62b074b3a62c86c2e45b7547cd99318f72 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 28 Aug 2024 23:57:22 +0900 Subject: [PATCH 034/174] Update version to 126.0.2 --- android/app/build.gradle | 2 +- android/app/release/output-metadata.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index d420ae2f..ba4997e3 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -8,7 +8,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 2 - versionName "126.0.1" + versionName "126.0.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json index 5a1e1779..dbb8252b 100644 --- a/android/app/release/output-metadata.json +++ b/android/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 2, - "versionName": "126.0.1", + "versionName": "126.0.2", "outputFile": "app-release.apk" } ], diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 13609d72..64feb56d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "126.0.1" + "version": "126.0.2" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 92b02236..c0395757 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "126.0.1" +export let appVer = "126.0.2" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index b0ad7340..20be716c 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"126.0.1"} \ No newline at end of file +{"version":"126.0.2"} \ No newline at end of file From cc03297a382b3556310b44f4963962b1613851f3 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 28 Aug 2024 23:58:00 +0900 Subject: [PATCH 035/174] Add module comment --- src/lib/Setting/Pages/Module/ModuleSettings.svelte | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/lib/Setting/Pages/Module/ModuleSettings.svelte b/src/lib/Setting/Pages/Module/ModuleSettings.svelte index 48b86ab5..3f1c33c4 100644 --- a/src/lib/Setting/Pages/Module/ModuleSettings.svelte +++ b/src/lib/Setting/Pages/Module/ModuleSettings.svelte @@ -66,6 +66,14 @@ From 1473aeefcd20b43ec9a469f1be7c418a573042bf Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 29 Aug 2024 00:02:56 +0900 Subject: [PATCH 036/174] fix module assets on export --- src/ts/process/modules.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ts/process/modules.ts b/src/ts/process/modules.ts index c366df6b..854a8196 100644 --- a/src/ts/process/modules.ts +++ b/src/ts/process/modules.ts @@ -42,6 +42,7 @@ export async function exportModule(module:RisuModule){ const assets = module.assets ?? [] module = structuredClone(module) + module.assets ??= [] module.assets = module.assets.map((asset) => { return [asset[0], '', asset[2]] as [string,string,string] }) From 71bff6b02e92945bfdc520536a00c50dbfd15a43 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 29 Aug 2024 00:03:14 +0900 Subject: [PATCH 037/174] Update version to 126.0.3 --- android/app/build.gradle | 2 +- android/app/release/output-metadata.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index ba4997e3..d2cb20ca 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -8,7 +8,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 2 - versionName "126.0.2" + versionName "126.0.3" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json index dbb8252b..5f14ac15 100644 --- a/android/app/release/output-metadata.json +++ b/android/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 2, - "versionName": "126.0.2", + "versionName": "126.0.3", "outputFile": "app-release.apk" } ], diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 64feb56d..840f4151 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "126.0.2" + "version": "126.0.3" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index c0395757..aefc7686 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "126.0.2" +export let appVer = "126.0.3" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index 20be716c..ac0b3bf3 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"126.0.2"} \ No newline at end of file +{"version":"126.0.3"} \ No newline at end of file From a5061a3b3ea1f12976c8f68c20c44555e2644042 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 29 Aug 2024 00:07:14 +0900 Subject: [PATCH 038/174] Fix module menu --- src/lib/Setting/Pages/Module/ModuleMenu.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Setting/Pages/Module/ModuleMenu.svelte b/src/lib/Setting/Pages/Module/ModuleMenu.svelte index 2f022c4a..48847e5b 100644 --- a/src/lib/Setting/Pages/Module/ModuleMenu.svelte +++ b/src/lib/Setting/Pages/Module/ModuleMenu.svelte @@ -82,7 +82,7 @@ } -
+
- + + + + +
+ +
+ \ No newline at end of file diff --git a/src/ts/tokenizer.ts b/src/ts/tokenizer.ts index 7afe4fa0..1a8cf376 100644 --- a/src/ts/tokenizer.ts +++ b/src/ts/tokenizer.ts @@ -1,12 +1,13 @@ import type { Tiktoken } from "@dqbd/tiktoken"; import type { Tokenizer } from "@mlc-ai/web-tokenizers"; -import { DataBase, type character } from "./storage/database"; +import { DataBase, type groupChat, type character, type Chat } from "./storage/database"; import { get } from "svelte/store"; import type { MultiModal, OpenAIChat } from "./process"; import { supportsInlayImage } from "./process/files/image"; import { risuChatParser } from "./parser"; import { tokenizeGGUFModel } from "./process/models/local"; import { globalFetch } from "./storage/globalApi"; +import { CurrentCharacter } from "./stores"; export const tokenizerList = [ @@ -342,4 +343,57 @@ export async function strongBan(data:string, bias:{[key:number]:number}) { } localStorage.setItem('strongBan_' + data, JSON.stringify(bias)) return bias +} + +export async function getCharToken(char?:character|groupChat|null){ + let persistant = 0 + let dynamic = 0 + + if(!char){ + const c = get(CurrentCharacter) + char = c + } + if(char.type === 'group'){ + return {persistant:0, dynamic:0} + } + + const basicTokenize = async (data:string) => { + data = data.replace(/{{char}}/g, char.name).replace(//g, char.name) + return await tokenize(data) + } + + persistant += await basicTokenize(char.desc) + persistant += await basicTokenize(char.personality ?? '') + persistant += await basicTokenize(char.scenario ?? '') + for(const lore of char.globalLore){ + let cont = lore.content.split('\n').filter((line) => { + if(line.startsWith('@@')){ + return false + } + if(line === ''){ + return false + } + return true + }).join('\n') + dynamic += await basicTokenize(cont) + } + + return {persistant, dynamic} +} + +export async function getChatToken(chat:Chat) { + let persistant = 0 + + const chatTokenizer = new ChatTokenizer(0, 'name') + const chatf = chat.message.map((d) => { + return { + role: d.role === 'user' ? 'user' : 'assistant', + content: d.data, + } as OpenAIChat + }) + for(const chat of chatf){ + persistant += await chatTokenizer.tokenizeChat(chat) + } + + return persistant } \ No newline at end of file From aea0dd4088dedcfa38610c9209f07983c4dbd81f Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 1 Sep 2024 19:34:41 +0900 Subject: [PATCH 041/174] Add cohere models --- src/lib/UI/ModelList.svelte | 4 ++++ src/ts/process/request.ts | 6 +++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/lib/UI/ModelList.svelte b/src/lib/UI/ModelList.svelte index 88762456..2f6b4deb 100644 --- a/src/lib/UI/ModelList.svelte +++ b/src/lib/UI/ModelList.svelte @@ -126,6 +126,10 @@ + + + + diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index fbda6d0d..f58fcf84 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -1537,7 +1537,11 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' } } case 'cohere-command-r': - case 'cohere-command-r-plus':{ + case 'cohere-command-r-plus': + case 'cohere-command-r-08-2024': + case 'cohere-command-r-03-2024': + case 'cohere-command-r-plus-04-2024': + case 'cohere-command-r-plus-08-2024':{ const modelName = aiModel.replace('cohere-', '') let lastChatPrompt = '' let preamble = '' From 61b662ebf1a72e2c319df795d949030be65adbd3 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 1 Sep 2024 19:35:01 +0900 Subject: [PATCH 042/174] Update version to 127.0.0 --- android/app/build.gradle | 2 +- android/app/release/output-metadata.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index d2cb20ca..c43f04f4 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -8,7 +8,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode 2 - versionName "126.0.3" + versionName "127.0.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" aaptOptions { // Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps. diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json index 5f14ac15..96dc72d2 100644 --- a/android/app/release/output-metadata.json +++ b/android/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 2, - "versionName": "126.0.3", + "versionName": "127.0.0", "outputFile": "app-release.apk" } ], diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 840f4151..430733dd 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "126.0.3" + "version": "127.0.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index b277f7bc..18742a46 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "126.0.3" +export let appVer = "127.0.0" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index ac0b3bf3..4959e63c 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"126.0.3"} \ No newline at end of file +{"version":"127.0.0"} \ No newline at end of file From 7ba6a81ff0789578011fe8eb04549655b0052be5 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 1 Sep 2024 19:38:54 +0900 Subject: [PATCH 043/174] fix nai issue --- src/ts/process/request.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index f58fcf84..8324087c 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -814,7 +814,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' "parameters":payload } - const da = await globalFetch("https://api.novelai.net/ai/generate", { + const da = await globalFetch(aiModel === 'novelai_kayra' ? "https://text.novelai.net/ai/generate" : "https://api.novelai.net/ai/generate", { body: body, headers: { "Authorization": "Bearer " + db.novelai.token From 5948aa89660acef878647612eea9d5a4c46387ff Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 5 Sep 2024 16:31:36 +0900 Subject: [PATCH 044/174] Add related links --- src/lib/UI/MainMenu.svelte | 43 +++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/lib/UI/MainMenu.svelte b/src/lib/UI/MainMenu.svelte index b4a26674..33f425bf 100644 --- a/src/lib/UI/MainMenu.svelte +++ b/src/lib/UI/MainMenu.svelte @@ -3,7 +3,7 @@ import Hub from "./Realm/RealmMain.svelte"; import { OpenRealmStore } from "src/ts/stores"; import { ArrowLeft } from "lucide-svelte"; - import { isNodeServer, isTauri } from "src/ts/storage/globalApi"; + import { isNodeServer, isTauri, openURL } from "src/ts/storage/globalApi"; import { language } from "src/lang"; import { getRisuHub, hubAdditionalHTML } from "src/ts/characterCards"; import RisuHubIcon from "./Realm/RealmHubIcon.svelte"; @@ -46,6 +46,47 @@ {:else}
{language.hideRealm}
{/if} +
+

+ Related Links +

+
+ + + + +
+ {:else}
{/if} diff --git a/src/lib/Setting/Pages/Module/ModuleMenu.svelte b/src/lib/Setting/Pages/Module/ModuleMenu.svelte index 48847e5b..19642ff5 100644 --- a/src/lib/Setting/Pages/Module/ModuleMenu.svelte +++ b/src/lib/Setting/Pages/Module/ModuleMenu.svelte @@ -121,8 +121,12 @@
{#if submenu === 0} - - + {language.name} + + {language.description} + + {language.namespace} +
diff --git a/src/ts/process/modules.ts b/src/ts/process/modules.ts index 8c3b5e95..8eb274d1 100644 --- a/src/ts/process/modules.ts +++ b/src/ts/process/modules.ts @@ -24,6 +24,7 @@ export interface RisuModule{ hideIcon?: boolean backgroundEmbedding?:string assets?:[string,string,string][] + namespace?:string } export async function exportModule(module:RisuModule){ @@ -242,19 +243,39 @@ function getModuleById(id:string){ return null } +function getModuleByIds(ids:string[]){ + let modules:RisuModule[] = [] + const db = get(DataBase) + for(let i=0;i s.trim()) + ids = ids.concat(intList) + } const idsJoined = ids.join('-') if(lastModules === idsJoined){ return lastModuleData } - let modules:RisuModule[] = [] - for(const id of ids){ - const module = getModuleById(id) - modules.push(module) - } + let modules:RisuModule[] = getModuleByIds(ids) lastModules = idsJoined lastModuleData = modules return modules @@ -263,12 +284,7 @@ export function getModules(ids:string[]){ export function getModuleLorebooks() { - const currentChat = get(CurrentChat) - const db = get(DataBase) - if (!currentChat) return [] - let moduleIds = currentChat.modules ?? [] - moduleIds = moduleIds.concat(db.enabledModules) - const modules = getModules(moduleIds) + const modules = getModules() let lorebooks: loreBook[] = [] for (const module of modules) { if(!module){ @@ -282,12 +298,7 @@ export function getModuleLorebooks() { } export function getModuleAssets() { - const currentChat = get(CurrentChat) - const db = get(DataBase) - if (!currentChat) return [] - let moduleIds = currentChat.modules ?? [] - moduleIds = moduleIds.concat(db.enabledModules) - const modules = getModules(moduleIds) + const modules = getModules() let assets: [string,string,string][] = [] for (const module of modules) { if(!module){ @@ -302,12 +313,7 @@ export function getModuleAssets() { export function getModuleTriggers() { - const currentChat = get(CurrentChat) - const db = get(DataBase) - if (!currentChat) return [] - let moduleIds = currentChat.modules ?? [] - moduleIds = moduleIds.concat(db.enabledModules) - const modules = getModules(moduleIds) + const modules = getModules() let triggers: triggerscript[] = [] for (const module of modules) { if(!module){ @@ -324,12 +330,7 @@ export function getModuleTriggers() { } export function getModuleRegexScripts() { - const currentChat = get(CurrentChat) - const db = get(DataBase) - if (!currentChat) return [] - let moduleIds = currentChat.modules ?? [] - moduleIds = moduleIds.concat(db.enabledModules) - const modules = getModules(moduleIds) + const modules = getModules() let customscripts: customscript[] = [] for (const module of modules) { if(!module){ diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 18742a46..83d4ddbe 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -725,6 +725,7 @@ export interface Database{ falLora: string falLoraName: string falLoraScale: number + moduleIntergration: string } export interface customscript{ @@ -975,6 +976,7 @@ export interface botPreset{ useInstructPrompt?:boolean customPromptTemplateToggle?:string templateDefaultVariables?:string + moduleIntergration?:string } @@ -1254,6 +1256,7 @@ export function saveCurrentPreset(){ useInstructPrompt: db.useInstructPrompt, customPromptTemplateToggle: db.customPromptTemplateToggle ?? "", templateDefaultVariables: db.templateDefaultVariables ?? "", + moduleIntergration: db.moduleIntergration ?? "", } db.botPresets = pres setDatabase(db) @@ -1338,6 +1341,7 @@ export function setPreset(db:Database, newPres: botPreset){ db.useInstructPrompt = newPres.useInstructPrompt ?? false db.customPromptTemplateToggle = newPres.customPromptTemplateToggle ?? '' db.templateDefaultVariables = newPres.templateDefaultVariables ?? '' + db.moduleIntergration = newPres.moduleIntergration ?? '' return db } From d511089090a066c2948b540317f7f146d5a84b06 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 5 Sep 2024 21:45:51 +0900 Subject: [PATCH 047/174] Add regex risu flags --- src/lang/cn.ts | 2 +- src/lang/de.ts | 2 +- src/lang/en.ts | 15 +++-- src/lang/es.ts | 2 +- src/lang/ko.ts | 2 +- src/lib/Setting/Pages/BotSettings.svelte | 3 +- src/ts/parser.ts | 50 +++++++++------ src/ts/process/scripts.ts | 81 +++++++++++++++++++++--- 8 files changed, 120 insertions(+), 37 deletions(-) diff --git a/src/lang/cn.ts b/src/lang/cn.ts index 75365930..bf88199b 100644 --- a/src/lang/cn.ts +++ b/src/lang/cn.ts @@ -68,7 +68,7 @@ export const languageChinese = { "utilityBot": "启用后,它将忽略主要提示词、越狱和其他提示词。用于实用程序机器人,而不是用于角色扮演。", "loreSelective": "如果切换选择性的,则激活键和次要键都应有匹配项才能激活lorebook。", "loreRandomActivation": "如果启用了概率条件,那么当lorebook的其他条件都已满足时,每次发送聊天时lorebook将以“概率”设置的概率被激活。", - "additionalAssets": "在你的聊天中显示的额外资源。\n\n - 使用`{{raw::}}`作为路径\n - 使用`{{img::}}`作为图片\n - 使用`{{video::}}`作为视频\n - 使用`{{audio::}}` 作为音频\n - 建议放在背景 HTML中", + "additionalAssets": "在你的聊天中显示的额外资源。\n\n - 使用`{{raw::}}`作为路径\n - 使用`{{image::}}`作为图片\n - 使用`{{video::}}`作为视频\n - 使用`{{audio::}}` 作为音频\n - 建议放在背景 HTML中", "superMemory": "超级记忆通过给 AI 提供总结数据使你的角色记忆更多信息\n\n超级记忆模型是一个总结文本的模型。推荐使用Davinci,除非是具有超过2000个token数的高度总结能力的未经过滤模型,否则不推荐使用辅助模型。\n\n超级记忆提示决定了应发送什么提示词进行总结。如果你留空,它将使用默认提示词。建议留空。\n\n在所有设置都完成后,你可以在角色的设置中启用它。", "replaceGlobalNote": "如果不为空,则将当前全局注释替换为此。", "backgroundHTML": "将被注入聊天荧幕背景的Markdown/HTML数据。\n\n你也可以使用其他资源。例如,你可以使用`{{audio::}}`: 将背景注入资源", diff --git a/src/lang/de.ts b/src/lang/de.ts index 55d51942..8cf4e451 100644 --- a/src/lang/de.ts +++ b/src/lang/de.ts @@ -83,7 +83,7 @@ export const languageGerman = { scenario: "Eine kurze Beschreibung des Szenarios des Charakters. \n\n**Es wird nicht empfohlen, diese Option zu nutzen. Beschreiben Sie das Szenario stattdessen in der Charakterbeschreibung.**", loreSelective: "Wenn der selektive Modus aktiviert ist, müssen sowohl Trigger-Wort als auch auch das Co-Trigger-Wort übereinstimmen, um den Kontext zu aktivieren", loreRandomActivation: "Wenn die Bedingung 'Wahrscheinlichkeit verwenden' aktiviert ist, wird der Kontext mit einer festgelegten Wahrscheinlichkeit, die durch 'Wahrscheinlichkeit' festgelegt wird, jedes Mal aktiviert, wenn eine Chat-Nachricht gesendet wird und die anderen Bedingungen der Überlieferung alle erfüllt sind", - additionalAssets: "Zusätzliche Assets, die in Ihrem Chat angezeigt werden sollen. \n\n - verwenden Sie `{{raw::}}` um als Pfad zu verwenden.\n – verwenden Sie `{{img::}}` um als Bild zu verwenden\n - verwenden Sie `{{video::}}` um als Video zu verwenden\n – verwenden Sie `{{audio::}}` um als Audio zu verwenden\n – es wird empfohlen, dies im HTML Backend einzufügen", + additionalAssets: "Zusätzliche Assets, die in Ihrem Chat angezeigt werden sollen. \n\n - verwenden Sie `{{raw::}}` um als Pfad zu verwenden.\n – verwenden Sie `{{image::}}` um als Bild zu verwenden\n - verwenden Sie `{{video::}}` um als Video zu verwenden\n – verwenden Sie `{{audio::}}` um als Audio zu verwenden\n – es wird empfohlen, dies im HTML Backend einzufügen", superMemory: "SupaMemory ermöglicht es Ihrem Charakter, sich mehr Informationen zu 'merken', indem der KI zusammengefasste Daten zugeführt werden.\n\n" + "Das SupaMemory-Modell ist ein Modell, das die Zusammenfassung für einen Text erstellt. Davinci oder GPT-3.5-16k werden empfohlen. Hilfsmodelle hingegen werden nicht empfohlen, es sei denn, es handelt sich um ein ungefiltertes Modell mit mindestens 2000 Tokens Kontextgröße und einer ausgereiften Fähigkeiten, Texte zusammenfassen zu können.\n\n" + "Die SupaMemory-Anweisung entscheidet darüber, welche Anweisung konkret zur Zusammenfassung gesendet werden soll. Wenn Sie das Feld leer lassen, wird die Standard-Anweisung verwendet. Es wird empfohlen, es leer zu lassen.\n\n" diff --git a/src/lang/en.ts b/src/lang/en.ts index 73be9cb1..0c3c6685 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -58,7 +58,7 @@ export const languageEnglish = { bias:"bias is a key-value data which modifies the likelihood of string appearing.\nit can be -100 to 100, higher values will be more likely to appear, and lower values will be more unlikely to appear. \nAdditionaly, if its set to -101, it would work as 'strong ban word' for some models. \nWarning: if the tokenizer is wrong, it not work properly.", emotion: "Emotion Images option shows image depending at character's emotion which is analized by character's response. you must input emotion name as words *(like joy, happy, fear and etc.)* .emotion named **neutral** will be default emotion if it exists. must be more then 3 images to work properly.", imggen: "After analyzing the chat, apply the prompt to {{slot}}.", - regexScript: "Regex Script is a custom script that replaces string that matches IN to OUT.\n\nThere four type options." + regexScript: "Regex Script is a custom regex that replaces string that matches IN to OUT.\n\nThere four type options." + "\n\n- **Modify Input** modifys user's input" + "\n\n- **Modify Output** modifys character's output" + "\n\n- **Modify Request Data** modifys current chat data when sent." @@ -69,8 +69,14 @@ export const languageEnglish = { + "\n\n- $`\n\n - inserts the portion of the string that precedes the matched substring." + "\n\n- $1\n\n - inserts the first matching group. works with other number like 2, 3..." + "\n\n- $(name)\n\n - inserts the named group" - + "\n\nIf OUT starts with **@@**, it doesn't replaces the string, but instead does a special effect if matching string founds." - + "\n\n- @@emo (emotion name)\n\n - if character is Emotion Images mode, sets (emotion name) as emotion and prevents default.", + + "\n\nFor flags, you can not only use native supported flags, but also use these flags, which are designed for advanced users:" + + "\n\n- `` - injects the result to the current string." + + "\n- `` - moves the result to the top of the string." + + "\n- `` - moves the result to the bottom of the string." + + "\n- `` - if the match is not found, it carries the result from the previous match." + + "\n- `` - sets the order of the result. higher order will be shown first. `n` is a number. (like ``) if this flag is not set, it will be set to 0." + + "\n- `` - parses curly braced synatxes in IN." + + "\n\nTo use with native flags, you can use like `gi`.", experimental: "This is a experimental feature. it might be unstable.", oogaboogaURL: "If your WebUI supports older version of api, your url should look *like https:.../run/textgen*\n\n" + "If your WebUI supports newVersion of api, your url should look like *https://.../api/v1/generate* and use the api server as host, and add --api to arguments.", @@ -86,7 +92,7 @@ export const languageEnglish = { utilityBot: "When activated, it ignores main prompt, jailbreak and other prompts. used for bot made for utility, not for roleplay.", loreSelective: "If Selective mode is toggled, both Activation Key and Secondary key should have a match to activate the lore.", loreRandomActivation: "If Use Probability Condition is abled, if the lore's other conditions are all met, the lore will be activated with a set probability which is set by 'Probability' each time a chat is sent.", - additionalAssets: "Additional assets to display in your chat. \n\n - use `{{raw::}}` to use as path.\n - use `{{img::}}` to use as image\n - use `{{video::}}` to use as video\n - use `{{audio::}}` to use as audio\n - recommended to put in Background HTML", + additionalAssets: "Additional assets to display in your chat. \n\n - use `{{raw::}}` to use as path.\n - use `{{image::}}` to use as image\n - use `{{video::}}` to use as video\n - use `{{audio::}}` to use as audio\n - recommended to put in Background HTML", superMemory: "SuperMemory makes your character memorize more by giving summarized data to AI.\n\n" + "SuperMemory model is a model that summarizes that text. davinci is recommended, and Auxiliary models are not recommended unless it is an unfiltered model with over 2000 tokens with great summarizing skill.\n\n" + "SuperMemory Prompt decides what prompt should be sent to summarize. if you leave it blank, it will use the default prompt. leaving blank is recommended.\n\n" @@ -136,6 +142,7 @@ export const languageEnglish = { claudeCachingExperimental: "Caching in Claude is experimental feature that can reduce the cost of the model, but it can also increase the cost if you use it without reroll. since this is a experimental feature, it can be unstable and behavior can be changed in the future.", urllora: "You can use direct download link of the model file. you can make direct url from google drive like website like https://sites.google.com/site/gdocs2direct/ , or use civitai URL, copy the the AIR (looks like `urn:air:flux1:lora:civitai:180891@776656` or just `civitai:180891@776656`) and paste it.", namespace: "Namespace is a unique identifier for the module. it is used to prevent conflicts between modules, and for interaction of presets, other modules and etc. if you are not sure what to put, leave it blank.", + moduleIntergration: "You can enable modules by putting the module namespace in the module intergartion sections. if you want to enable multiple modules, you can seperate them by comma. for example, `module1,module2,module3`. this is for advanced users, who wants to vary the use of modules by presets.", }, setup: { chooseProvider: "Choose AI Provider", diff --git a/src/lang/es.ts b/src/lang/es.ts index 432d2bff..5d351e62 100644 --- a/src/lang/es.ts +++ b/src/lang/es.ts @@ -86,7 +86,7 @@ export const languageSpanish = { utilityBot: "Cuando está activado, ignora el prompt principal, jailbreak y otros prompts. Se utiliza para bots diseñados para utilidades, no para juegos de rol.", loreSelective: "Si el modo Selectivo está activado, tanto la Clave de Activación como la Clave Secundaria deben coincidir para activar el lore.", loreRandomActivation: "Si la Condición de Probabilidad está habilitada, si se cumplen todas las demás condiciones del lore, el lore se activará con una probabilidad establecida por 'Probabilidad' cada vez que se envíe un chat.", - additionalAssets: "Activos adicionales para mostrar en tu chat. \n\n - usa `{{raw::}}` para usar como ruta.\n - usa `{{img::}}` para usar como imagen\n - usa `{{video::}}` para usar como video\n - usa `{{audio::}}` para usar como audio\n - se recomienda poner en HTML de Fondo", + additionalAssets: "Activos adicionales para mostrar en tu chat. \n\n - usa `{{raw::}}` para usar como ruta.\n - usa `{{image::}}` para usar como imagen\n - usa `{{video::}}` para usar como video\n - usa `{{audio::}}` para usar como audio\n - se recomienda poner en HTML de Fondo", superMemory: "SuperMemoria hace que tu personaje memorice más dando datos resumidos a la IA.\n\n" + "El modelo de SuperMemoria es un modelo que resume ese texto. Se recomienda Davinci, y no se recomienda usar modelos auxiliares a menos que sea un modelo no filtrado con más de 2000 tokens y con una gran habilidad de resumen.\n\n" + "El Prompt de SuperMemoria decide qué prompt se debe enviar para resumir. Si lo dejas en blanco, usará el prompt predeterminado. Se recomienda dejarlo en blanco.\n\n" diff --git a/src/lang/ko.ts b/src/lang/ko.ts index c8bece83..7ce33eee 100644 --- a/src/lang/ko.ts +++ b/src/lang/ko.ts @@ -68,7 +68,7 @@ export const languageKorean = { "utilityBot": "활성화되면 메인 프롬프트, jailbreak 및 기타 프롬프트를 무시합니다. 역할극이 아닌 유틸리티용 봇에 사용됩니다.", "loreSelective": "선택 모드가 토글되면 활성화 키와 보조 키 모두 일치해야 로어가 활성화됩니다.", "loreRandomActivation": "확률 조건 사용이 활성화된 경우, 로어의 다른 조건이 모두 충족되면 로어가 활성화되며, 각 채팅을 보낼 때마다 설정된 확률에 따라 활성화됩니다.", - "additionalAssets": "채팅에 표시할 추가 에셋입니다.\n\n- `{{raw::<에셋 이름>}}`을 경로로 사용하려면\n- `{{img::<에셋 이름>}}`을 이미지로 사용하려면\n- `{{video::<에셋 이름>}}`을 비디오로 사용하려면\n- `{{audio::<에셋 이름>}}`을 오디오로 사용하려면\n - 배경 HTML에 넣는 것이 좋습니다.", + "additionalAssets": "채팅에 표시할 추가 에셋입니다.\n\n- 경로로 사용하려면 `{{raw::<에셋 이름>}}`을\n- 이미지로 사용하려면 `{{image::<에셋 이름>}}`을\n- 비디오로 사용하려면 `{{video::<에셋 이름>}}`을\n- 오디오로 사용하려면 `{{audio::<에셋 이름>}}`을 사용하세요.\n", "superMemory": "SuperMemory는 AI에게 요약된 데이터를 제공하여 캐릭터가 더 많이 기억하도록합니다.\n\nSuperMemory 모델은 해당 텍스트를 요약하는 모델입니다. 보조 모델은 2000개 이상의 토큰을 가진 필터되지 않은 모델이 아닌 경우 권장되지 않습니다.\n\nSuperMemory 프롬프트는 요약을 보내기 위해 어떤 프롬프트를 보내야 하는지 결정합니다. 비워두면 기본 프롬프트를 사용합니다. 비워두는 것이 권장됩니다.\n\n모두 설정한 후 캐릭터의 설정에서 활성화할 수 있습니다.", "replaceGlobalNote": "비어 있지 않으면 현재 글로벌 노트를 이로 대체합니다.", "backgroundHTML": "채팅 화면의 배경에 삽입 될 마크다운/HTML 데이터입니다.\n\n추가 에셋을 사용할 수도 있습니다. 예를 들어, 배경 음악에 `{{audio::<에셋 이름>}}`을 사용할 수 있습니다.\n\n또한 다음과 같은 추가 에셋을 사용할 수 있습니다:\n - `{{bg::<에셋 이름>}}`: 에셋으로 배경을 삽입합니다.", diff --git a/src/lib/Setting/Pages/BotSettings.svelte b/src/lib/Setting/Pages/BotSettings.svelte index fea7aa2f..85ca4464 100644 --- a/src/lib/Setting/Pages/BotSettings.svelte +++ b/src/lib/Setting/Pages/BotSettings.svelte @@ -563,7 +563,8 @@ }}/> {/if}
- + + {#if submenu !== -1} diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 47f4860e..432f781b 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -4,7 +4,7 @@ import { DataBase, setDatabase, type Database, type Message, type character, typ import { getFileSrc } from './storage/globalApi'; import { processScriptFull } from './process/scripts'; import { get } from 'svelte/store'; -import css from '@adobe/css-tools' +import css, { type CssAtRuleAST } from '@adobe/css-tools' import { CurrentCharacter, CurrentChat, SizeStore, selectedCharID } from './stores'; import { calcString } from './process/infunctions'; import { findCharacterbyId, getPersonaPrompt, getUserIcon, getUserName, parseKeyValue, sfc32, sleep, uuidtoNumber } from './util'; @@ -439,6 +439,32 @@ function encodeStyle(txt:string){ } const styleDecodeRegex = /\(.+?)\<\/risu-style\>/gms +function decodeStyleRule(rule:CssAtRuleAST){ + if(rule.type === 'rule'){ + if(rule.selectors){ + for(let i=0;i { + if(v.startsWith('.')){ + return ".x-risu-" + v.substring(1) + } + return v + }).join(' ') + + rule.selectors[i] = ".chattext " + selectors + } + } + } + } + if(rule.type === 'media' || rule.type === 'supports' || rule.type === 'document' || rule.type === 'host' || rule.type === 'container' ){ + for(let i=0;i { @@ -446,26 +472,10 @@ function decodeStyle(text:string){ const ast = css.parse(Buffer.from(txt, 'hex').toString('utf-8')) const rules = ast?.stylesheet?.rules if(rules){ - for(const rule of rules){ - - if(rule.type === 'rule'){ - if(rule.selectors){ - for(let i=0;i { - if(v.startsWith('.')){ - return ".x-risu-" + v.substring(1) - } - return v - }).join(' ') - - rule.selectors[i] = ".chattext " + selectors - } - } - } - } + for(let i=0;i${css.stringify(ast)}` diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts index e3fe865b..93ea4875 100644 --- a/src/ts/process/scripts.ts +++ b/src/ts/process/scripts.ts @@ -16,6 +16,12 @@ const randomness = /\|\|\|/g export type ScriptMode = 'editinput'|'editoutput'|'editprocess'|'editdisplay' +type pScript = { + script: customscript, + order: number + actions: string[] +} + export async function processScript(char:character|groupChat, data:string, mode:ScriptMode){ return (await processScriptFull(char, data, mode)).data } @@ -73,7 +79,9 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter if(scripts.length === 0){ return {data, emoChanged} } - for (const script of scripts){ + function executeScript(pscript:pScript){ + const script = pscript.script + if(script.type === mode){ let outScript2 = script.out.replaceAll("$n", "\n") @@ -82,7 +90,7 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter if(script.ableFlag){ flag = script.flag || 'g' } - if(outScript.startsWith('@@move_top') || outScript.startsWith('@@move_bottom')){ + if(outScript.startsWith('@@move_top') || outScript.startsWith('@@move_bottom') || pscript.actions.includes('move_top') || pscript.actions.includes('move_bottom')){ flag = flag.replace('g', '') //temperary fix } //remove unsupported flag @@ -92,8 +100,13 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter flag = 'u' } - const reg = new RegExp(script.in, flag) - if(outScript.startsWith('@@')){ + let input = script.in + if(pscript.actions.includes('cbs')){ + input = risuChatParser(input, { chatID: chatID }) + } + + const reg = new RegExp(input, flag) + if(outScript.startsWith('@@') || pscript.actions.length > 0){ if(reg.test(data)){ if(outScript.startsWith('@@emo ')){ const emoName = script.out.substring(6).trim() @@ -118,12 +131,15 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter } } } - if(outScript.startsWith('@@inject') && chatID !== -1){ + else if((outScript.startsWith('@@inject') || pscript.actions.includes('inject')) && chatID !== -1){ const selchar = db.characters[get(selectedCharID)] selchar.chats[selchar.chatPage].message[chatID].data = data data = data.replace(reg, "") } - if(outScript.startsWith('@@move_top') || outScript.startsWith('@@move_bottom')){ + else if( + outScript.startsWith('@@move_top') || outScript.startsWith('@@move_bottom') || + pscript.actions.includes('move_top') || pscript.actions.includes('move_bottom') + ){ const isGlobal = flag.includes('g') const matchAll = isGlobal ? data.matchAll(reg) : [data.match(reg)] data = data.replace(reg, "") @@ -148,7 +164,7 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter return v }) console.log(out) - if(outScript.startsWith('@@move_top')){ + if(outScript.startsWith('@@move_top') || pscript.actions.includes('move_top')){ data = out + '\n' +data } else{ @@ -157,9 +173,12 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter } } } + else{ + data = risuChatParser(data.replace(reg, outScript), { chatID: chatID }) + } } else{ - if(outScript.startsWith('@@repeat_back') && chatID !== -1){ + if((outScript.startsWith('@@repeat_back') || pscript.actions.includes('repeat_back')) && chatID !== -1){ const v = outScript.split(' ', 2)[1] const selchar = db.characters[get(selectedCharID)] const chat = selchar.chats[selchar.chatPage] @@ -203,6 +222,52 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter } } + let parsedScripts:pScript[] = [] + let orderChanged = false + for (const script of scripts){ + if(script.ableFlag && script.flag?.includes('<')){ + const rregex = /<(.+?)>/g + const scriptData = structuredClone(script) + let order = 0 + const actions:string[] = [] + scriptData.flag = scriptData.flag?.replace(rregex, (v:string, p1:string) => { + const meta = p1.split(',').map((v) => v.trim()) + for(const m of meta){ + if(m.startsWith('order ')){ + order = parseInt(m.substring(6)) + } + else{ + actions.push(m) + } + } + + return '' + }) + parsedScripts.push({ + script: scriptData, + order, + actions + }) + continue + } + parsedScripts.push({ + script, + order: 0, + actions: [] + }) + } + + console.log(parsedScripts) + + if(orderChanged){ + parsedScripts.sort((a, b) => b.order - a.order) //sort by order + } + for (const script of parsedScripts){ + executeScript(script) + } + + + if(db.dynamicAssets && (char.type === 'simple' || char.type === 'character') && char.additionalAssets && char.additionalAssets.length > 0){ if(!db.dynamicAssetsEditDisplay && mode === 'editdisplay'){ return {data, emoChanged} From 72e6c807602d8dfc1be75752c555c5ea8072fcca Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 5 Sep 2024 21:52:48 +0900 Subject: [PATCH 048/174] Add image cbs --- src/styles.css | 8 ++++++++ src/ts/parser.ts | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/styles.css b/src/styles.css index 97e87ca7..555b20bf 100644 --- a/src/styles.css +++ b/src/styles.css @@ -242,4 +242,12 @@ html, body{ background-color: var(--tw-prose-pre-bg); padding: 0.125rem 0.25rem; border-radius: 0.25rem; +} + +.x-risu-risu-inlay-image{ + @apply w-full flex justify-center +} + +.x-risu-risu-inlay-image > img{ + @apply rounded-lg focus:outline-none max-w-80 w-full } \ No newline at end of file diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 432f781b..b4a4e222 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -250,7 +250,7 @@ async function renderHighlightableMarkdown(data:string) { } -export const assetRegex = /{{(raw|img|video|audio|bg|emotion|asset|video-img|source)::(.+?)}}/g +export const assetRegex = /{{(raw|img|image|video|audio|bg|emotion|asset|video-img|source)::(.+?)}}/g async function parseAdditionalAssets(data:string, char:simpleCharacterArgument|character, mode:'normal'|'back', mode2:'unset'|'pre'|'post' = 'unset'){ const db = get(DataBase) @@ -322,6 +322,8 @@ async function parseAdditionalAssets(data:string, char:simpleCharacterArgument|c return path.path case 'img': return `${path.path}` + case 'image': + return `
${path.path}
` case 'video': return `` case 'video-img': From f9810bed78652a339d26fcea84d16bd0c245568b Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 5 Sep 2024 21:56:57 +0900 Subject: [PATCH 049/174] Update version to 128.0.0 --- android/app/release/output-metadata.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 4 ++-- version.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json index 96dc72d2..f67e331f 100644 --- a/android/app/release/output-metadata.json +++ b/android/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 2, - "versionName": "127.0.0", + "versionName": "128.0.0", "outputFile": "app-release.apk" } ], diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 430733dd..28bc64ce 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "127.0.0" + "version": "128.0.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 83d4ddbe..184447a2 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "127.0.0" +export let appVer = "128.0.0" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; @@ -168,7 +168,7 @@ export function setDatabase(data:Database){ data.runpodKey = '' } if(checkNullish(data.webUiUrl)){ - data.webUiUrl = 'http://127.0.0.1:7860/' + data.webUiUrl = 'http://128.0.0.1:7860/' } if(checkNullish(data.sdSteps)){ data.sdSteps = 30 diff --git a/version.json b/version.json index 4959e63c..f06dfeaf 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"127.0.0"} \ No newline at end of file +{"version":"128.0.0"} \ No newline at end of file From 519da8b9421f7921461b6e4e51c5cabe08608386 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 5 Sep 2024 21:57:59 +0900 Subject: [PATCH 050/174] Fix webui url --- src/ts/storage/database.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 184447a2..e5b6cb95 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -168,7 +168,7 @@ export function setDatabase(data:Database){ data.runpodKey = '' } if(checkNullish(data.webUiUrl)){ - data.webUiUrl = 'http://128.0.0.1:7860/' + data.webUiUrl = 'http://127.0.0.1:7860/' } if(checkNullish(data.sdSteps)){ data.sdSteps = 30 From a16a9c7e8b764ee7be57c8b88ae4d9740bde9bfe Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 6 Sep 2024 00:11:07 +0900 Subject: [PATCH 051/174] Add backslash in image --- src/ts/parser.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/parser.ts b/src/ts/parser.ts index b4a4e222..a4b35d8a 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -323,7 +323,7 @@ async function parseAdditionalAssets(data:string, char:simpleCharacterArgument|c case 'img': return `${path.path}` case 'image': - return `
${path.path}
` + return `
${path.path}
\n` case 'video': return `` case 'video-img': From cd83867d21421093bd41975acbdeceacc1470205 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 6 Sep 2024 00:16:52 +0900 Subject: [PATCH 052/174] Add beforeunload --- src/preload.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/preload.ts b/src/preload.ts index 53b9190e..b0bcb56b 100644 --- a/src/preload.ts +++ b/src/preload.ts @@ -19,6 +19,15 @@ export function preLoadCheck(){ else if(searchParams.has('mainpage')) { localStorage.setItem('mainpage', searchParams.get('mainpage')); } + + if(isWeb) { + //Add beforeunload event listener to prevent the user from leaving the page + window.addEventListener('beforeunload', (e) => { + e.preventDefault() + //legacy browser + e.returnValue = true + }) + } // Redirect to the main page if the user has not visited the main page From 5779de9d92ec11c8f8a1ba11817d41ba181ff468 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 6 Sep 2024 00:21:11 +0900 Subject: [PATCH 053/174] feat: Add 'image' to displayRelatedCBS array in highlight.ts --- src/ts/gui/highlight.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/gui/highlight.ts b/src/ts/gui/highlight.ts index 63ae71cd..68189858 100644 --- a/src/ts/gui/highlight.ts +++ b/src/ts/gui/highlight.ts @@ -101,7 +101,7 @@ const normalCBSwithParams = [ ] const displayRelatedCBS = [ - 'raw', 'img', 'video', 'audio', 'bg', 'emotion', 'asset', 'video-img', 'comment' + 'raw', 'img', 'video', 'audio', 'bg', 'emotion', 'asset', 'video-img', 'comment', 'image' ]; const specialCBS = [ From 4108f84bfb981d3e27674154a33757b7fe8aa8ec Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 6 Sep 2024 02:45:31 +0900 Subject: [PATCH 054/174] revert module loading --- src/ts/process/modules.ts | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/ts/process/modules.ts b/src/ts/process/modules.ts index 8eb274d1..0d4800a2 100644 --- a/src/ts/process/modules.ts +++ b/src/ts/process/modules.ts @@ -246,12 +246,10 @@ function getModuleById(id:string){ function getModuleByIds(ids:string[]){ let modules:RisuModule[] = [] const db = get(DataBase) - for(let i=0;i m.id === ids[i] || (m.namespace === ids[i] && m.namespace)) + if(module){ + modules.push(module) } } return modules From f79324ba0cefe7838a71967d10fb5b3dc5c65e0a Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 6 Sep 2024 02:45:49 +0900 Subject: [PATCH 055/174] chore: Update version to 128.0.1 --- android/app/release/output-metadata.json | 2 +- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/android/app/release/output-metadata.json b/android/app/release/output-metadata.json index f67e331f..ae7fd1bb 100644 --- a/android/app/release/output-metadata.json +++ b/android/app/release/output-metadata.json @@ -12,7 +12,7 @@ "filters": [], "attributes": [], "versionCode": 2, - "versionName": "128.0.0", + "versionName": "128.0.1", "outputFile": "app-release.apk" } ], diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 28bc64ce..d171b86a 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "128.0.0" + "version": "128.0.1" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index e5b6cb95..1aea5ca9 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "128.0.0" +export let appVer = "128.0.1" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index f06dfeaf..df36b40b 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"128.0.0"} \ No newline at end of file +{"version":"128.0.1"} \ No newline at end of file From 1e3574754e4d1629b85566d8139647653f2e1713 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 8 Sep 2024 18:22:13 +0900 Subject: [PATCH 056/174] Add prompt preview --- src/lang/en.ts | 1 + src/lib/SideBars/DevTool.svelte | 38 ++++++++++++++++++++++++++++++--- src/ts/process/index.ts | 14 +++++++++++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/lang/en.ts b/src/lang/en.ts index 0c3c6685..1a82b1d2 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -699,4 +699,5 @@ export const languageEnglish = { selectFile: "Select File", namespace: "Namespace", moduleIntergration: "Module Integration", + previewInfo: "This preview shows prompt before model-specific processing.", } \ No newline at end of file diff --git a/src/lib/SideBars/DevTool.svelte b/src/lib/SideBars/DevTool.svelte index 74f05a78..3f995e22 100644 --- a/src/lib/SideBars/DevTool.svelte +++ b/src/lib/SideBars/DevTool.svelte @@ -4,7 +4,7 @@ import NumberInput from "../UI/GUI/NumberInput.svelte"; import Button from "../UI/GUI/Button.svelte"; import { getRequestLog } from "src/ts/storage/globalApi"; - import { alertMd } from "src/ts/alert"; + import { alertMd, alertWait } from "src/ts/alert"; import Arcodion from "../UI/Arcodion.svelte"; import { getCharToken, getChatToken } from "src/ts/tokenizer"; import { tokenizePreset } from "src/ts/process/prompt"; @@ -13,7 +13,7 @@ import { FolderUpIcon, PlusIcon, TrashIcon } from "lucide-svelte"; import { selectSingleFile } from "src/ts/util"; import { file } from "jszip"; - import { doingChat, sendChat } from "src/ts/process"; + import { doingChat, previewFormated, sendChat } from "src/ts/process"; let autopilot = [] @@ -148,6 +148,38 @@ doingChat.set(false) }}>Run
+ \ No newline at end of file +}}>Request Log + + \ No newline at end of file diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index 86312035..e4a94e19 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -56,8 +56,15 @@ export interface OpenAIChatFull extends OpenAIChat{ export const doingChat = writable(false) export const chatProcessStage = writable(0) export const abortChat = writable(false) +export let previewFormated:OpenAIChat[] = [] -export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:number,signal?:AbortSignal,continue?:boolean,usedContinueTokens?:number} = {}):Promise { +export async function sendChat(chatProcessIndex = -1,arg:{ + chatAdditonalTokens?:number, + signal?:AbortSignal, + continue?:boolean, + usedContinueTokens?:number, + preview?:boolean +} = {}):Promise { chatProcessStage.set(0) const abortSignal = arg.signal ?? (new AbortController()).signal @@ -1090,6 +1097,11 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n maxContext: maxContextTokens, } chatProcessStage.set(3) + if(arg.preview){ + previewFormated = formated + return true + } + const req = await requestChatData({ formated: formated, biasString: biases, From b6006741cfcd10f6561f881428bc4ee0ac644797 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 8 Sep 2024 18:36:32 +0900 Subject: [PATCH 057/174] Fix lore depth and tokens --- src/ts/process/lorebook.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ts/process/lorebook.ts b/src/ts/process/lorebook.ts index 0815e77a..4a8e5409 100644 --- a/src/ts/process/lorebook.ts +++ b/src/ts/process/lorebook.ts @@ -62,8 +62,8 @@ export async function loadLoreBookPrompt(){ const moduleLorebook = getModuleLorebooks() const fullLore = characterLore.concat(chatLore).concat(moduleLorebook) const currentChat = char.chats[page].message - const loreDepth = char.loreSettings?.scanDepth ?? db.loreBookDepth - const loreToken = char.loreSettings?.tokenBudget ?? db.loreBookToken + const loreDepth = char.loreSettings?.scanDepth || db.loreBookDepth + const loreToken = char.loreSettings?.tokenBudget || db.loreBookToken const fullWordMatching = char.loreSettings?.fullWordMatching ?? false let activatiedPrompt: string[] = [] @@ -230,7 +230,11 @@ export async function loadLoreBookV3Prompt(){ regex:boolean fullWordMatching:boolean }) => { - const sliced = messages.slice(messages.length - arg.searchDepth,messages.length) + let start = messages.length - arg.searchDepth + if(start < 0){ + start = 0 + } + const sliced = messages.slice(start) arg.keys = arg.keys.map(key => key.trim()).filter(key => key.length > 0) let mText = sliced.map((msg) => { return msg.data From c9b763fc98b97a948aa5840b7dafa823b9719db4 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 8 Sep 2024 19:08:48 +0900 Subject: [PATCH 058/174] Add parameter disabling --- src/lib/Setting/Pages/BotSettings.svelte | 20 +++++++------- src/lib/UI/GUI/SliderInput.svelte | 34 ++++++++++++++++++------ 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/lib/Setting/Pages/BotSettings.svelte b/src/lib/Setting/Pages/BotSettings.svelte index 85ca4464..b398ec03 100644 --- a/src/lib/Setting/Pages/BotSettings.svelte +++ b/src/lib/Setting/Pages/BotSettings.svelte @@ -303,23 +303,23 @@ {language.temperature} {#if $DataBase.aiModel.startsWith("novelai")} - + {:else} - + {/if} {#if $DataBase.aiModel.startsWith('openrouter') || $DataBase.aiModel.startsWith('claude-3') || $DataBase.aiModel.startsWith('cohere-')} Top K - + {/if} {#if $DataBase.aiModel.startsWith('openrouter')} Repetition penalty - + Min P - + Top A - + {/if} {#if $DataBase.aiModel === 'textgen_webui' || $DataBase.aiModel === 'mancer' || $DataBase.aiModel.startsWith('local_') || $DataBase.aiModel.startsWith('hf:::')} Repetition Penalty @@ -439,17 +439,17 @@ {:else if $DataBase.aiModel.startsWith('claude')} Top P - + {:else} Top P - + {language.frequencyPenalty} - + {language.presensePenalty} - + {/if} {#if ($DataBase.reverseProxyOobaMode && $DataBase.aiModel === 'reverse_proxy') || ($DataBase.aiModel === 'ooba')} diff --git a/src/lib/UI/GUI/SliderInput.svelte b/src/lib/UI/GUI/SliderInput.svelte index 594d9d87..9601a1a3 100644 --- a/src/lib/UI/GUI/SliderInput.svelte +++ b/src/lib/UI/GUI/SliderInput.svelte @@ -9,28 +9,42 @@ on:change > --> -
+
+ {#if disableable} + +
+ { + if(c) { + value = min; + } else { + value = -1000; + } + }}> +
+ {/if}
{ + on:pointerdown={(event) => { mouseDown = true; changeValue(event); }} - on:mousemove={(event) => { + on:pointermove={(event) => { if (mouseDown) { changeValue(event); } }} - on:mouseup={() => { - mouseDown = false; - }} - on:mouseleave={() => { + on:pointerup={() => { + mouseDown = false; + }} + + on:pointerleave={() => { mouseDown = false; }} bind:this={slider} @@ -43,13 +57,16 @@ - {customText === undefined ? (value * multiple).toFixed(fixed) : customText} + {customText === undefined ? (value === -1000 ? language.disabled : (value * multiple).toFixed(fixed)) : customText}
@@ -149,37 +218,34 @@ }}>Run + + + Type + + Chat + Instruct + + {#if previewMode === 'instruct'} + Instruction Type + + {#each Object.keys(chatTemplates) as template} + {template} + {/each} + Custom Jinja + + {#if instructType === 'jinja'} + Custom Jinja + + {/if} + {/if} + Join + + With Join + Without Join + + + + - - \ No newline at end of file +}}>Request Log \ No newline at end of file diff --git a/src/ts/process/templates/chatTemplate.ts b/src/ts/process/templates/chatTemplate.ts index a12886bd..f1ff328d 100644 --- a/src/ts/process/templates/chatTemplate.ts +++ b/src/ts/process/templates/chatTemplate.ts @@ -26,15 +26,18 @@ export const templateEffect = { ], } as {[key:string]:TemplateEffect[]} -export const applyChatTemplate = (messages:OpenAIChat[]) => { +export const applyChatTemplate = (messages:OpenAIChat[], arg:{ + type?: string + custom?: string +} = {}) => { const db = get(DataBase) const currentChar = get(CurrentCharacter) - const type = db.instructChatTemplate + const type = arg.type ?? db.instructChatTemplate if(!type){ throw new Error('Template type is not set') } let clonedMessages = structuredClone(messages) - const template = type === 'jinja' ? (new Template(db.JinjaTemplate)) :(new Template(chatTemplates[type])) + const template = type === 'jinja' ? (new Template(arg.custom ?? db.JinjaTemplate)) :(new Template(chatTemplates[type])) let formatedMessages:{ "role": 'user'|'assistant'|'system', "content": string From 7c69a461708baa78b65fece5a38e5c422cd9a408 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 9 Sep 2024 03:09:36 +0900 Subject: [PATCH 062/174] Add convertion tool --- src/lang/en.ts | 3 + src/lib/Playground/PlaygroundMenu.svelte | 28 +- src/lib/Playground/ToolConvertion.svelte | 49 ++++ src/ts/process/prompt.ts | 350 ++++++++++++++++++++++- src/ts/storage/database.ts | 9 + 5 files changed, 436 insertions(+), 3 deletions(-) create mode 100644 src/lib/Playground/ToolConvertion.svelte diff --git a/src/lang/en.ts b/src/lang/en.ts index 1a82b1d2..cb866e62 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -700,4 +700,7 @@ export const languageEnglish = { namespace: "Namespace", moduleIntergration: "Module Integration", previewInfo: "This preview shows prompt before model-specific processing.", + miscTools: "Misc Tools", + promptConvertion: "Prompt Convertion", + convertionStep1: "Select all file related to the prompt (Context, Instruct and Sampler JSON is supported)", } \ No newline at end of file diff --git a/src/lib/Playground/PlaygroundMenu.svelte b/src/lib/Playground/PlaygroundMenu.svelte index 84f9a699..9359c1fb 100644 --- a/src/lib/Playground/PlaygroundMenu.svelte +++ b/src/lib/Playground/PlaygroundMenu.svelte @@ -10,8 +10,11 @@ import { characterFormatUpdate, createBlankChar } from "src/ts/characters"; import { get } from "svelte/store"; import { DataBase, setDatabase, type character } from "src/ts/storage/database"; - import PlaygroundImageGen from "./PlaygroundImageGen.svelte"; - import PlaygroundParser from "./PlaygroundParser.svelte"; + import PlaygroundImageGen from "./PlaygroundImageGen.svelte"; + import PlaygroundParser from "./PlaygroundParser.svelte"; + import ToolConvertion from "./ToolConvertion.svelte"; + + let easterEggTouch = 0 const playgroundChat = () => { let db = get(DataBase) @@ -81,6 +84,24 @@ }}>

Parser

+ +
{:else} {#if $SizeStore.w < 1024} @@ -114,6 +135,9 @@ {#if $PlaygroundStore === 8} {/if} + {#if $PlaygroundStore === 101} + + {/if}
{/if}
\ No newline at end of file diff --git a/src/lib/Playground/ToolConvertion.svelte b/src/lib/Playground/ToolConvertion.svelte new file mode 100644 index 00000000..58f46d2f --- /dev/null +++ b/src/lib/Playground/ToolConvertion.svelte @@ -0,0 +1,49 @@ + + +

{language.promptConvertion}

+{language.convertionStep1} + +
+ {#each files as file, i} +
+
+ {#if file.type !== 'NOTSUPPORTED'} + {file.type} + {:else} + NOTSUPPORTED + {/if} + {file.name} +
+ +
+ {/each} + +
+ \ No newline at end of file diff --git a/src/ts/process/prompt.ts b/src/ts/process/prompt.ts index 1b5b1aea..7a73a109 100644 --- a/src/ts/process/prompt.ts +++ b/src/ts/process/prompt.ts @@ -1,6 +1,7 @@ import { get } from "svelte/store"; import { tokenizeAccurate } from "../tokenizer"; -import type { Database } from "../storage/database"; +import { DataBase, presetTemplate, setDatabase, type Database } from "../storage/database"; +import { alertError, alertNormal } from "../alert"; export type PromptItem = PromptItemPlain|PromptItemTyped|PromptItemChat|PromptItemAuthorNote; export type PromptType = PromptItem['type']; @@ -64,3 +65,350 @@ export async function tokenizePreset(prompts:PromptItem[], consti:boolean = fals } return total } + +export function detectPromptJSONType(text:string){ + + function notNull(x:T|null):x is T{ + return x !== null && x !== undefined + } + + try { + const parsed = JSON.parse(text) + if(notNull(parsed.chat_completion_source) && Array.isArray(parsed.prompts)&& Array.isArray(parsed.prompt_order)){ + return "STCHAT" + } + else if(notNull(parsed.temp) && notNull(parsed.rep_pen) && notNull(parsed.min_length)){ + return "PARAMETERS" + } + else if(notNull(parsed.story_string) && notNull(parsed.chat_start)){ + return "STCONTEXT" + } + else if(notNull(parsed.input_sequence) && notNull(parsed.output_sequence)){ + return "STINST" + } + } catch (e) {} + return 'NOTSUPPORTED' +} + +const typePriority = [ + 'STINST', + 'PARAMETERS', + 'STCONTEXT', + 'STCHAT', +] + + +type InstData = { + "system_prompt": string, + "input_sequence": string, + "output_sequence": string, + "last_output_sequence": string, + "system_sequence": string, + "stop_sequence": string, + "system_sequence_prefix": string, + "system_sequence_suffix": string, + "first_output_sequence": string, + "output_suffix": string, + "input_suffix": string, + "system_suffix": string, + "user_alignment_message": string, + "system_same_as_user": boolean, + "last_system_sequence": string, + "first_input_sequence": string, + "last_input_sequence": string, + "name": string +} + +export function stChatConvert(pre:any){ + //ST preset + let promptTemplate = [] + + function findPrompt(identifier:number){ + return pre.prompts.find((p:any) => p.identifier === identifier) + } + + for(const prompt of pre?.prompt_order?.[0]?.order){ + if(!prompt?.enabled){ + continue + } + const p = findPrompt(prompt?.identifier ?? '') + if(p){ + switch(p.identifier){ + case 'main':{ + promptTemplate.push({ + type: 'plain', + type2: 'main', + text: p.content ?? "", + role: p.role ?? "system" + }) + break + } + case 'jailbreak': + case 'nsfw':{ + promptTemplate.push({ + type: 'jailbreak', + type2: 'normal', + text: p.content ?? "", + role: p.role ?? "system" + }) + break + } + case 'dialogueExamples': + case 'charPersonality': + case 'scenario':{ + break //ignore + } + case 'chatHistory':{ + promptTemplate.push({ + type: 'chat', + rangeEnd: 'end', + rangeStart: 0 + }) + break + } + case 'worldInfoBefore':{ + promptTemplate.push({ + type: 'lorebook' + }) + break + } + case 'worldInfoAfter':{ + break + } + case 'charDescription':{ + promptTemplate.push({ + type: 'description' + }) + break + } + case 'personaDescription':{ + promptTemplate.push({ + type: 'persona' + }) + break + } + default:{ + console.log(p) + promptTemplate.push({ + type: 'plain', + type2: 'normal', + text: p.content ?? "", + role: p.role ?? "system" + }) + } + } + } + else{ + console.log("Prompt not found", prompt) + + } + } + if(pre?.assistant_prefill){ + promptTemplate.push({ + type: 'postEverything' + }) + promptTemplate.push({ + type: 'plain', + type2: 'main', + text: `{{#if {{prefill_supported}}}}${pre?.assistant_prefill}{{/if}}`, + role: 'bot' + }) + } + + return promptTemplate +} + +export function promptConvertion(files:{ name: string, content: string, type:string }[]){ + let preset = structuredClone(presetTemplate) + let instData = { + "system_prompt": "", + "input_sequence": "", + "output_sequence": "", + "last_output_sequence": "", + "system_sequence": "", + "stop_sequence": "", + "system_sequence_prefix": "", + "system_sequence_suffix": "", + "first_output_sequence": "", + "output_suffix": "", + "input_suffix": "", + "system_suffix": "", + "user_alignment_message": "", + "system_same_as_user": false, + "last_system_sequence": "", + "first_input_sequence": "", + "last_input_sequence": "", + "name": "" + } + let story_string = '' + let chat_start = '' + preset.name = '' + + let type = '' + + files = files.filter(x=>x.type !== 'NOTSUPPORTED').sort((a,b)=>{ + return typePriority.indexOf(a.type) - typePriority.indexOf(b.type) + }) + + + if(files.findIndex(x=>x.type === 'STINST') !== -1){ + type = 'STINST' + } + if(files.findIndex(x=>x.type === 'STCHAT') !== -1){ + if(type !== ''){ + alertError(`Both ${type} and STCHAT are not supported together.`) + return + } + type = 'STCHAT' + } + + let samplers:string[] = [] + const getParam = (setname:keyof(typeof preset), getname:string = '', arg:{ + multiplier?: number + }={}) => { + if(getname === ''){ + getname = setname + } + let multiplier = arg.multiplier ?? 1 + if(samplers.includes(getname)){ + // @ts-ignore + preset[setname] = data[getname] * multiplier + } + else{ + // @ts-ignore + preset[setname] = -1000 + } + } + + for(let i=0;i Date: Mon, 9 Sep 2024 03:13:32 +0900 Subject: [PATCH 063/174] Add extentions to additional assets --- src/lib/SideBars/CharConfig.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte index 162787cf..e3ea261a 100644 --- a/src/lib/SideBars/CharConfig.svelte +++ b/src/lib/SideBars/CharConfig.svelte @@ -1051,7 +1051,7 @@ From b18f85bf67f68e9eb693eefee249026e7f1a7a4c Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 9 Sep 2024 03:18:56 +0900 Subject: [PATCH 066/174] Apply ex. asset changes to module too --- src/lib/Setting/Pages/Module/ModuleMenu.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Setting/Pages/Module/ModuleMenu.svelte b/src/lib/Setting/Pages/Module/ModuleMenu.svelte index 19642ff5..7ba381eb 100644 --- a/src/lib/Setting/Pages/Module/ModuleMenu.svelte +++ b/src/lib/Setting/Pages/Module/ModuleMenu.svelte @@ -171,7 +171,7 @@ {language.value} - - + + From 611f3e4b946c61a78b2f70d9ee25ff45f200205c Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 9 Sep 2024 18:17:26 +0900 Subject: [PATCH 074/174] Add ooba convertion --- src/ts/process/prompt.ts | 85 +++++++++++++++++++++++++++++++------- src/ts/process/request.ts | 3 +- src/ts/storage/database.ts | 2 +- 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/src/ts/process/prompt.ts b/src/ts/process/prompt.ts index 7a73a109..84614498 100644 --- a/src/ts/process/prompt.ts +++ b/src/ts/process/prompt.ts @@ -2,6 +2,7 @@ import { get } from "svelte/store"; import { tokenizeAccurate } from "../tokenizer"; import { DataBase, presetTemplate, setDatabase, type Database } from "../storage/database"; import { alertError, alertNormal } from "../alert"; +import type { OobaChatCompletionRequestParams } from "../model/ooba"; export type PromptItem = PromptItemPlain|PromptItemTyped|PromptItemChat|PromptItemAuthorNote; export type PromptType = PromptItem['type']; @@ -218,6 +219,42 @@ export function stChatConvert(pre:any){ return promptTemplate } +export const OobaParams = [ + "tokenizer", + "min_p", + "top_k", + "repetition_penalty", + "repetition_penalty_range", + "typical_p", + "tfs", + "top_a", + "epsilon_cutoff", + "eta_cutoff", + "guidance_scale", + "negative_prompt", + "penalty_alpha", + "mirostat_mode", + "mirostat_tau", + "mirostat_eta", + "temperature_last", + "do_sample", + "seed", + "encoder_repetition_penalty", + "no_repeat_ngram_size", + "min_length", + "num_beams", + "length_penalty", + "early_stopping", + "truncation_length", + "max_tokens_second", + "custom_token_bans", + "auto_max_new_tokens", + "ban_eos_token", + "add_bos_token", + "skip_special_tokens", + "grammar_string" +] + export function promptConvertion(files:{ name: string, content: string, type:string }[]){ let preset = structuredClone(presetTemplate) let instData = { @@ -263,26 +300,37 @@ export function promptConvertion(files:{ name: string, content: string, type:str } let samplers:string[] = [] - const getParam = (setname:keyof(typeof preset), getname:string = '', arg:{ - multiplier?: number - }={}) => { - if(getname === ''){ - getname = setname - } - let multiplier = arg.multiplier ?? 1 - if(samplers.includes(getname)){ - // @ts-ignore - preset[setname] = data[getname] * multiplier - } - else{ - // @ts-ignore - preset[setname] = -1000 - } + + let oobaData:OobaChatCompletionRequestParams = { + mode: 'instruct', } + for(let i=0;i { + if(getname === ''){ + getname = setname + } + let multiplier = arg.multiplier ?? 1 + if(samplers.includes(getname)){ + //@ts-ignore + preset[setname] = data[getname] * multiplier + } + else{ + // @ts-ignore + preset[setname] = -1000 + } + + if(OobaParams.includes(getname)){ + oobaData[getname] = data[getname] + } + } + preset.name ||= instData.name ?? '' switch(file.type){ case 'STINST':{ @@ -304,6 +352,11 @@ export function promptConvertion(files:{ name: string, content: string, type:str getParam('repetition_penalty', 'rep_pen') getParam('frequencyPenalty', 'freq_pen', {multiplier: 100}) getParam('PresensePenalty', 'presence_penalty', {multiplier: 100}) + for(const key of OobaParams){ + if(samplers.includes(key) && (data[key] !== undefined) && (data[key] !== null)){ + oobaData[key] = data[key] + } + } break } case 'STCONTEXT':{ @@ -338,6 +391,8 @@ export function promptConvertion(files:{ name: string, content: string, type:str return } + preset.reverseProxyOobaArgs = oobaData + preset.promptTemplate = [{ type: 'plain', type2: 'main', diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 8ad4aced..c14a0a76 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -21,6 +21,7 @@ import { runTransformers } from "./transformers"; import {createParser} from 'eventsource-parser' import {Ollama} from 'ollama/dist/browser.mjs' import { applyChatTemplate } from "./templates/chatTemplate"; +import { OobaParams } from "./prompt"; @@ -1076,7 +1077,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' const OobaBodyTemplate = db.reverseProxyOobaArgs const keys = Object.keys(OobaBodyTemplate) for(const key of keys){ - if(OobaBodyTemplate[key] !== undefined && OobaBodyTemplate[key] !== null){ + if(OobaBodyTemplate[key] !== undefined && OobaBodyTemplate[key] !== null && OobaParams.includes(key)){ bodyTemplate[key] = OobaBodyTemplate[key] } else if(bodyTemplate[key]){ diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index ec81992a..8713f9fe 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1081,7 +1081,7 @@ interface AINsettings{ top_k:number } -interface OobaSettings{ +export interface OobaSettings{ max_new_tokens: number, do_sample: boolean, temperature: number, From eb8e1d31c8eec049e96a909d1ec2fb396d086b71 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 9 Sep 2024 18:47:30 +0900 Subject: [PATCH 075/174] Add custom css and rs classes for it --- src/lang/en.ts | 2 ++ src/lib/Others/WelcomeRisu.svelte | 4 +-- src/lib/Setting/Pages/DisplaySettings.svelte | 28 ++++++++++++-------- src/lib/Setting/Settings.svelte | 8 +++--- src/lib/SideBars/Sidebar.svelte | 2 +- src/ts/gui/colorscheme.ts | 11 +++++++- src/ts/hotkey.ts | 10 ++++++- src/ts/storage/database.ts | 2 ++ src/ts/storage/globalApi.ts | 4 +-- src/ts/stores.ts | 18 +++++++++++++ 10 files changed, 67 insertions(+), 22 deletions(-) diff --git a/src/lang/en.ts b/src/lang/en.ts index cb866e62..76144415 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -143,6 +143,7 @@ export const languageEnglish = { urllora: "You can use direct download link of the model file. you can make direct url from google drive like website like https://sites.google.com/site/gdocs2direct/ , or use civitai URL, copy the the AIR (looks like `urn:air:flux1:lora:civitai:180891@776656` or just `civitai:180891@776656`) and paste it.", namespace: "Namespace is a unique identifier for the module. it is used to prevent conflicts between modules, and for interaction of presets, other modules and etc. if you are not sure what to put, leave it blank.", moduleIntergration: "You can enable modules by putting the module namespace in the module intergartion sections. if you want to enable multiple modules, you can seperate them by comma. for example, `module1,module2,module3`. this is for advanced users, who wants to vary the use of modules by presets.", + customCSS: "Custom CSS for styling. you can also disable/enable it by pressing (Ctrl + .) if something goes wrong.", }, setup: { chooseProvider: "Choose AI Provider", @@ -703,4 +704,5 @@ export const languageEnglish = { miscTools: "Misc Tools", promptConvertion: "Prompt Convertion", convertionStep1: "Select all file related to the prompt (Context, Instruct and Sampler JSON is supported)", + customCSS: "Custom CSS", } \ No newline at end of file diff --git a/src/lib/Others/WelcomeRisu.svelte b/src/lib/Others/WelcomeRisu.svelte index 89e09b19..5d0902fb 100644 --- a/src/lib/Others/WelcomeRisu.svelte +++ b/src/lib/Others/WelcomeRisu.svelte @@ -5,7 +5,7 @@ import { DataBase, setPreset } from "src/ts/storage/database"; import Chat from "../ChatScreens/Chat.svelte"; import { prebuiltPresets } from "src/ts/process/templates/templates"; - import { updateTextTheme } from "src/ts/gui/colorscheme"; + import { updateTextThemeAndCSS } from "src/ts/gui/colorscheme"; let step = 0 let provider = '' @@ -65,7 +65,7 @@ setTimeout(() => { $DataBase = setPreset($DataBase, prebuiltPresets.OAI2) $DataBase.textTheme = 'highcontrast' - updateTextTheme() + updateTextThemeAndCSS() if(provider === 'openrouter'){ $DataBase.aiModel = 'openrouter' $DataBase.subModel = 'openrouter' diff --git a/src/lib/Setting/Pages/DisplaySettings.svelte b/src/lib/Setting/Pages/DisplaySettings.svelte index dac10c73..a425b60e 100644 --- a/src/lib/Setting/Pages/DisplaySettings.svelte +++ b/src/lib/Setting/Pages/DisplaySettings.svelte @@ -8,11 +8,12 @@ import SelectInput from "src/lib/UI/GUI/SelectInput.svelte"; import OptionInput from "src/lib/UI/GUI/OptionInput.svelte"; import { updateAnimationSpeed } from "src/ts/gui/animation"; - import { changeColorScheme, colorSchemeList, exportColorScheme, importColorScheme, updateColorScheme, updateTextTheme } from "src/ts/gui/colorscheme"; + import { changeColorScheme, colorSchemeList, exportColorScheme, importColorScheme, updateColorScheme, updateTextThemeAndCSS } from "src/ts/gui/colorscheme"; import { DownloadIcon, FolderUpIcon } from "lucide-svelte"; import { guiSizeText, updateGuisize } from "src/ts/gui/guisize"; import TextInput from "src/lib/UI/GUI/TextInput.svelte"; import ColorInput from "src/lib/UI/GUI/ColorInput.svelte"; + import TextAreaInput from "src/lib/UI/GUI/TextAreaInput.svelte"; const onSchemeInputChange = (e:Event) => { changeColorScheme((e.target as HTMLInputElement).value) @@ -24,7 +25,7 @@

{language.display}

{#if submenu !== -1} -
+
{/if} + {language.customCSS} + { + updateTextThemeAndCSS() + }} /> + {/if} \ No newline at end of file diff --git a/src/lib/Setting/Settings.svelte b/src/lib/Setting/Settings.svelte index a90e9f2f..a847a0cd 100644 --- a/src/lib/Setting/Settings.svelte +++ b/src/lib/Setting/Settings.svelte @@ -27,10 +27,10 @@ } -
-
+
+
{#if window.innerWidth >= 700 || $SettingsMenuIndex === -1} -
+ + +
+{/if} +
+ {#if $MobileSideBar} +
+ {#if sbt === 0} + + {:else if sbt === 1} + + {:else if sbt === 2} + + {/if} +
+ {:else if $selectedCharID !== -1} + + {:else if $MobileGUIStack === 0} + + {:else if $MobileGUIStack === 1} + + {:else if $MobileGUIStack === 3} + + {/if} +
\ No newline at end of file diff --git a/src/lib/Mobile/MobileCharacters.svelte b/src/lib/Mobile/MobileCharacters.svelte new file mode 100644 index 00000000..7b0c2234 --- /dev/null +++ b/src/lib/Mobile/MobileCharacters.svelte @@ -0,0 +1,29 @@ + +
+ {#each $DataBase.characters as char, i} + {#if char.name.toLocaleLowerCase().includes($MobileSearch.toLocaleLowerCase())} + + {/if} + {/each} +
\ No newline at end of file diff --git a/src/lib/Mobile/MobileFooter.svelte b/src/lib/Mobile/MobileFooter.svelte new file mode 100644 index 00000000..744af049 --- /dev/null +++ b/src/lib/Mobile/MobileFooter.svelte @@ -0,0 +1,31 @@ + +{#if $selectedCharID === -1} + +
+ + + +
+ +{/if} \ No newline at end of file diff --git a/src/lib/Mobile/MobileHeader.svelte b/src/lib/Mobile/MobileHeader.svelte new file mode 100644 index 00000000..7baedd96 --- /dev/null +++ b/src/lib/Mobile/MobileHeader.svelte @@ -0,0 +1,44 @@ + +
+ {#if $selectedCharID !== -1 && $MobileSideBar} + + {language.menu} + {:else if $selectedCharID !== -1} + + {$CurrentCharacter.name} +
+ +
+ {:else if $MobileGUIStack === 3 && $SettingsMenuIndex > -1} + + RisuAI + {:else if $MobileGUIStack === 1} +
+ +
+ {:else} + RisuAI + + {/if} +
\ No newline at end of file diff --git a/src/lib/Setting/Pages/DisplaySettings.svelte b/src/lib/Setting/Pages/DisplaySettings.svelte index a425b60e..c9d13ad3 100644 --- a/src/lib/Setting/Pages/DisplaySettings.svelte +++ b/src/lib/Setting/Pages/DisplaySettings.svelte @@ -319,6 +319,11 @@
+
+ + +
+ {#if $DataBase.useExperimental}
diff --git a/src/lib/Setting/Settings.svelte b/src/lib/Setting/Settings.svelte index a847a0cd..7090aea9 100644 --- a/src/lib/Setting/Settings.svelte +++ b/src/lib/Setting/Settings.svelte @@ -8,7 +8,7 @@ import PluginSettings from "./Pages/PluginSettings.svelte"; import FilesSettings from "./Pages/FilesSettings.svelte"; import AdvancedSettings from "./Pages/AdvancedSettings.svelte"; - import { SettingsMenuIndex, settingsOpen } from "src/ts/stores"; + import { MobileGUI, SettingsMenuIndex, settingsOpen } from "src/ts/stores"; import Botpreset from "./botpreset.svelte"; import Communities from "./Pages/Communities.svelte"; import GlobalLoreBookSettings from "./Pages/GlobalLoreBookSettings.svelte"; @@ -29,7 +29,7 @@
- {#if window.innerWidth >= 700 || $SettingsMenuIndex === -1} + {#if (window.innerWidth >= 700 && !$MobileGUI) || $SettingsMenuIndex === -1}
- {#if window.innerWidth < 700} + {#if window.innerWidth < 700 && !$MobileGUI} {/if}
{/if} - {#if window.innerWidth >= 700 || $SettingsMenuIndex !== -1} + {#if (window.innerWidth >= 700 && !$MobileGUI) || $SettingsMenuIndex !== -1} {#key $SettingsMenuIndex}
{#if $SettingsMenuIndex === 0} @@ -181,16 +181,18 @@ {/if}
{/key} - + {#if !$MobileGUI} + + {/if} {/if}
diff --git a/src/lib/UI/GUI/SideBarArrow.svelte b/src/lib/UI/GUI/SideBarArrow.svelte index ccf2d300..4320932c 100644 --- a/src/lib/UI/GUI/SideBarArrow.svelte +++ b/src/lib/UI/GUI/SideBarArrow.svelte @@ -1,18 +1,20 @@ -{#if $sideBarStore && !$DynamicGUI} - -{:else} - +{#if !MobileGUI} + {#if $sideBarStore && !$DynamicGUI} + + {:else} + + {/if} {/if} \ No newline at end of file diff --git a/src/lib/UI/Realm/RealmMain.svelte b/src/lib/UI/Realm/RealmMain.svelte index 2e8d0f30..53fa4d91 100644 --- a/src/lib/UI/Realm/RealmMain.svelte +++ b/src/lib/UI/Realm/RealmMain.svelte @@ -5,7 +5,7 @@ import { language } from "src/lang"; import RisuHubIcon from "./RealmHubIcon.svelte"; import TextInput from "../GUI/TextInput.svelte"; - import { SizeStore } from "src/ts/stores"; + import { MobileGUI, SizeStore } from "src/ts/stores"; import { Capacitor } from "@capacitor/core"; import RealmPopUp from "./RealmPopUp.svelte"; import { googleBuild } from "src/ts/storage/globalApi"; @@ -35,29 +35,66 @@ -
-
- {#if $SizeStore.w < 768} - - {:else} - - - {/if} - -
-
- {#if !googleBuild} +{#if $MobileGUI} +
+
+ +
+ +
+
+{:else} +
- {/if} - - - - -
+ + + + +
+{/if} {@html hubAdditionalHTML}
{#key charas} diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 86963af3..846b79e1 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -728,6 +728,7 @@ export interface Database{ falLoraScale: number moduleIntergration: string customCSS: string + betaMobileGUI:boolean } export interface customscript{ diff --git a/src/ts/storage/globalApi.ts b/src/ts/storage/globalApi.ts index 3458ac37..8f335943 100644 --- a/src/ts/storage/globalApi.ts +++ b/src/ts/storage/globalApi.ts @@ -9,7 +9,7 @@ import {open} from '@tauri-apps/api/shell' import { DataBase, loadedStore, setDatabase, type Database, defaultSdDataFunc } from "./database"; import { appWindow } from "@tauri-apps/api/window"; import { checkRisuUpdate } from "../update"; -import { botMakerMode, selectedCharID } from "../stores"; +import { MobileGUI, botMakerMode, selectedCharID } from "../stores"; import { Body, ResponseType, fetch as TauriFetch } from "@tauri-apps/api/http"; import { loadPlugins } from "../plugins/plugins"; import { alertConfirm, alertError, alertNormal, alertNormalWait, alertSelect, alertTOS } from "../alert"; @@ -533,6 +533,9 @@ export async function loadData() { if(db.botSettingAtStart){ botMakerMode.set(true) } + if(db.betaMobileGUI && window.innerWidth <= 800){ + MobileGUI.set(true) + } loadedStore.set(true) selectedCharID.set(-1) startObserveDom() diff --git a/src/ts/stores.ts b/src/ts/stores.ts index 3fe6d4ca..2dcec66a 100644 --- a/src/ts/stores.ts +++ b/src/ts/stores.ts @@ -28,8 +28,10 @@ export const botMakerMode = writable(false) export const moduleBackgroundEmbedding = writable('') export const openPresetList = writable(false) export const openPersonaList = writable(false) +export const MobileGUI = writable(false) +export const MobileGUIStack = writable(0) +export const MobileSideBar = writable(false) //optimization - export const CurrentCharacter = writable(null) as Writable export const CurrentSimpleCharacter = writable(null) as Writable export const CurrentChat = writable(null) as Writable @@ -47,6 +49,7 @@ export const HideIconStore = writable(false) export const UserIconProtrait = writable(false) export const CustomCSSStore = writable('') export const SafeModeStore = writable(false) +export const MobileSearch = writable('') let lastGlobalEnabledModules: string[] = [] let lastChatEnabledModules: string[] = [] From 5c3541737e9eedd7617a7492d6bd03a9f2a70449 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 9 Sep 2024 21:26:54 +0900 Subject: [PATCH 077/174] Update version to 129.0.0 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index d171b86a..42fc8cda 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "128.0.1" + "version": "129.0.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 846b79e1..1e9932d0 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "128.0.1" +export let appVer = "129.0.0" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index df36b40b..fc9194a9 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"128.0.1"} \ No newline at end of file +{"version":"129.0.0"} \ No newline at end of file From c552ebfa1bac2cdc3ecbdcbe64c4f840868e00a4 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 9 Sep 2024 21:56:55 +0900 Subject: [PATCH 078/174] Fix sidebar arrow disappearing --- src/lib/UI/GUI/SideBarArrow.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/UI/GUI/SideBarArrow.svelte b/src/lib/UI/GUI/SideBarArrow.svelte index 4320932c..4916e399 100644 --- a/src/lib/UI/GUI/SideBarArrow.svelte +++ b/src/lib/UI/GUI/SideBarArrow.svelte @@ -4,7 +4,7 @@ -{#if !MobileGUI} +{#if !$MobileGUI} {#if $sideBarStore && !$DynamicGUI} {/if} - - + {#if !$ConnectionOpenStore} + + + {/if} {/if} {#if $DataBase.translator !== '' && !blankMessage}
+ {#if $DataBase.useExperimental} + + {/if} +
{:else if $CurrentCharacter?.chaId === '§playground'} + {:else if $ConnectionOpenStore} +
+

{language.connectionOpen}

+ {language.connectionOpenInfo} +
+ ID: + {$RoomIdStore} +
+
+ {#if $ConnectionIsHost} + {language.connectionHost} + {:else} + {language.connectionGuest} + {/if} +
+
{:else}
-
- -
- {#if $DataBase.textScreenColor}
{ @@ -324,11 +320,16 @@
- {#if $DataBase.useExperimental} + {#if $DataBase.showUnrecommended}
- - + +
+ +
+ + +
{/if} {language.customCSS} diff --git a/src/lib/SideBars/LoreBook/LoreBookSetting.svelte b/src/lib/SideBars/LoreBook/LoreBookSetting.svelte index c53ed8a0..b8d8d133 100644 --- a/src/lib/SideBars/LoreBook/LoreBookSetting.svelte +++ b/src/lib/SideBars/LoreBook/LoreBookSetting.svelte @@ -70,9 +70,12 @@
{/if}
- + {#if $DataBase.useExperimental} + + {/if} +
{/if} {#if submenu !== 2} From 323566bfddfe000c3f7b97f9258cb55163fba46e Mon Sep 17 00:00:00 2001 From: kwaroran Date: Tue, 10 Sep 2024 05:52:05 +0900 Subject: [PATCH 085/174] Fix typo --- src/lib/Setting/Pages/DisplaySettings.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/Setting/Pages/DisplaySettings.svelte b/src/lib/Setting/Pages/DisplaySettings.svelte index 4f4be483..c2541e64 100644 --- a/src/lib/Setting/Pages/DisplaySettings.svelte +++ b/src/lib/Setting/Pages/DisplaySettings.svelte @@ -322,7 +322,7 @@ {#if $DataBase.showUnrecommended}
- +
From 145d06e198c8c9da4f130c71239f1f8c4304c727 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Tue, 10 Sep 2024 17:45:35 +0900 Subject: [PATCH 086/174] Add missing break statements in SideChatList.svelte --- src/lib/SideBars/SideChatList.svelte | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/lib/SideBars/SideChatList.svelte b/src/lib/SideBars/SideChatList.svelte index 0f230e4b..260db69e 100644 --- a/src/lib/SideBars/SideChatList.svelte +++ b/src/lib/SideBars/SideChatList.svelte @@ -105,6 +105,7 @@ chara.chats.unshift(newChat) chara.chatPage = 0 chara.chats = chara.chats + break } case 1:{ const chat = chara.chats[i] @@ -126,6 +127,7 @@ alertNormal(language.personaBindedSuccess) } } + break } case 2:{ chara.chatPage = i From 17af14b1ee345fe02fbd2bd3e765f03922ac1317 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Tue, 10 Sep 2024 17:46:06 +0900 Subject: [PATCH 087/174] Update version to 129.1.0 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 7db76d2a..e51e4857 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "129.0.1" + "version": "129.1.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 42d99ed7..7c95b89e 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "129.0.1" +export let appVer = "129.1.0" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index 7ec3b6fd..4d8d43e5 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"129.0.1"} \ No newline at end of file +{"version":"129.1.0"} \ No newline at end of file From 3ae2c11ca465196ef35dd02d8ae10baadf02be78 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Tue, 10 Sep 2024 22:09:58 +0900 Subject: [PATCH 088/174] Add PWA support --- index.html | 1 + manifest.json | 63 +++++++++++++ public/logo_192.png | Bin 0 -> 5459 bytes public/logo_512.png | Bin 0 -> 21113 bytes public/sw.js | 30 +++++++ src/ts/characterCards.ts | 120 +++++++++++++++++++++++-- src/ts/process/modules.ts | 166 +++++++++++++++++++---------------- src/ts/process/processzip.ts | 4 + 8 files changed, 300 insertions(+), 84 deletions(-) create mode 100644 manifest.json create mode 100644 public/logo_192.png create mode 100644 public/logo_512.png diff --git a/index.html b/index.html index 0459e154..972d7f37 100644 --- a/index.html +++ b/index.html @@ -5,6 +5,7 @@ + diff --git a/manifest.json b/manifest.json new file mode 100644 index 00000000..be6e8ca5 --- /dev/null +++ b/manifest.json @@ -0,0 +1,63 @@ +{ + "name": "RisuAI", + "icons": [ + { + "src": "logo_512.png", + "type": "image/png", + "sizes": "512x512" + }, + { + "src": "logo_192.png", + "type": "image/png", + "sizes": "192x192" + }, + { + "src": "logo_16.png", + "type": "image/png", + "sizes": "16x16" + }, + { + "src": "logo_32.png", + "type": "image/png", + "sizes": "32x32" + }, + { + "src": "logo_256.png", + "type": "image/png", + "sizes": "256x256" + } + ], + "start_url": "/", + "display": "standalone", + "theme_color": "#4682B4", + "share_target": { + "action": "/receive-files/", + "method": "POST", + "enctype": "multipart/form-data", + "params": { + "files": [ + { + "name": "character", + "accept": [".charx"] + }, + { + "name": "preset", + "accept": [".risup"] + }, + { + "name": "module", + "accept": [".risum"] + } + ] + } + }, + "file_handlers": [ + { + "action": "/", + "accept": { + "application/octet-stream": [".charx", ".risup", ".risum"] + } + } + ] + +} \ No newline at end of file diff --git a/public/logo_192.png b/public/logo_192.png new file mode 100644 index 0000000000000000000000000000000000000000..17db294ebbeda36be7bfca84920237c70c5708d0 GIT binary patch literal 5459 zcmcIoXIB$Uu!hh=O(+t&fzXuRLPrQlkx--;MLJ0D9Si}aNtY^JktQG@D4j?zBGM5- z5eU*t==J8kzv12wvvc%4Fugu^vm*pe3>TQ{H{;oC7 zy@+Agn`k4er0_**}xzMv%a>}uCg zqpHP^w~S}%4Ef{V2|sWLK<+FLeuOX+A$V3ajI)>_x02R9&ke;IkSsd#}o8P zb?{+*P${huplkRYov6qhGt23jN}^y%@8IA?DvBvpyKzN9vfviu3$jVqikaLJD-)b) zI0H$vq*YFmxTGyc5%>PnfvzH-D0JoPR{d)Kb&k-|jDqVVJ+=O@YS8jYJ)4n)8|rA~ zsN!)jbJ~!sXcj{O!y@a7sIqRX*1Vdq7`ANjg>~ZPhCOF_jckORO0h0 z@n`T{)SRjPm1XifIb)lC{fYoojb>HaGv87@!^IT08TBXHtVv($ zoJTECadwbGuH7?VO7cD6FLwI;#Ll-oMQ_)^D!jL$%p&V^`>r`7Gc%J0At(FGV9uKJ zgU`AjhrSgzNV~=4rq}Nrf~>5?GYt4}auaXKvgow>B>|X5s|TTou%V`uVDgUu0F_DM zJud3a*5|YuOw1E7390w$@Bn}a?V6l(m)nNF_v~uE^3c!*;h@aN37FGrW9R*H=Goa*H#wcFo$}4iepuRHmoTn!G%i zr|(0ie{LsL`W5zV2%StF*vj!fC+*IJ^PDP@2*N_ruc_=+-IV2j@*@|*ksEA1;>v1v z$2|g;nIAa0QXaIe&+>n^2%=Ei z9!f4sOG-lV+OjX4S9=yztR6+>&hpwuoj>9&bJvR^Myf6@87aAQ=ccvzz8y0IYUa%1 zQbvmpNciMZgO6$Rs<9K(AA~)2=E&{e@_%>;?`|rK1BVlm{tN2NL3Jy4t@1&L8_mIr7q*F{S(e3C{r-=|_9i<%{iM=fr;≈$lro%^Xu% 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 E0I=i+`v3p{ literal 0 HcmV?d00001 diff --git a/public/logo_512.png b/public/logo_512.png new file mode 100644 index 0000000000000000000000000000000000000000..76306c27e2ea2fb9f00978a6a910180e32064e42 GIT binary patch literal 21113 zcmeEt@8Eg@ZBIt8S=yUye9bN-8S zUhKlYn7wE3nYregcp{V)r7%#5Q9&ROhK#hhDhLDt{)K>$|NZeH7OMdMfL&CjL_w9~ zr2D`JcuNrl5fG>*7VXIx0r-sKD6Q=R0%3Oldx4wdZH_@8RZJOi5p_?4;|{CD70Hw$ zl7%MWqj;u7neRyq5e3p8XbTxjWPR*P8;ZMDayW#{{9t5tY;6{H9$CxoU87eGjoE*S zmWxW;N?S|oP2p?2}!=fz=KB_Se(bpOVN_ z1>ULKhN8$+Z-XGhzqcbxg62^=F@$ zmMIjH05woUM4YS$m@>JSGm3V^_=4Z9Y7M!y=9FJEWmonsatSsbNcDr!wwlvzwB%mT z6-mf{$Sdw!+M#J2sFeSli!nIQ+COyjN}Z+Ew-vYbhIfp4dauub!}T2l18P6G;FB^) zT7y-?=9G7gX5xNGuGs(XuTH{SZ57xFQst_RXSV4M7dLVuDxkt_?yt0>_?_PjLk9l# z`&lDpHmlxyI?@vtJ)G8VYx{HG!r?XFDN`0efUkU4EpK)A`_Q%OC8*3s_0fS)?ihO* zik!<}-Du@b;~r z`yzPgTM@HPK%W)_x)o*H*eT7ej+dj0>tce9r7{bHn&arfV=mtj_UZDt&!Svb*f9ca zy0?M@Q}JLf=qMW=h`kBso*{|R`NTTZ>0`WqELWCNdr^JeniFf2##AxbG)6n3a2+Qc zKa#^6M=m0%paHJ}9()o7Q@WsyeoJ|~Nz1=l@w$Fc!hz<5xn|fC=!`U-6eAq4YqpR} z4ua9agRw*HSA*CoB^t5Wiwsk&UpJ_4dnz`&xVR8zjZ_U2M1x4UJRjW6W}2 z`WxG2act$en?V;4G9LOW&0yn9zOgkLl?x&Qbd+k?fP{bZNS*#^HoA@}OPc=V{=!=1 zWjSTh0Y2Wc%mO4c-zE%a^w3sgcuO`1iT46Ej^*|t!FDju;W-P`KmSqCy`++rwjAku=(-HYcM@jFWbVg~~~ zzPialbp*_*>(4&FhRJ1)e*0D77$NOndCk9!GzzfjEg#JkQX^Z}%*zW8`U-<7FN4(o z&PUNEFJ)77)Vpu)OC&#m=JgA^cOENO9pLk9dOPJV1RuXsg8jtkA=Q zR>?&koJ=~>;WO$pk?Y`HNQv33#e(_c1 zs}%dU_VPb0xWS{efIXIB*oWP#-0le+Xy^PtzRW+e^@02zntWb-NsjWOy?AbPSx?yU z;|3%Cc(Yg;z@DYBm2Z!uIz)%`0Cnr4xqC`$nr?0iXHN~ZdKk+uo5&xRaymMwC$z0Y zv=lC%M8*)k0#=XwdYe9onFXnU(wu+*ZmeNWJMu^}V-cG5*=%{2HX_mg`gQFC5B)lDQXHVRY+~&JleC|d_bXGAQb-Jfo!gV zSbv&Aheme2*SeZXTiw$m5d0DzC_)}mNsViW8fmcb^)aX(SaW$&%2ia zaaMrySfG18SC4OUh84bSMB4mN@<^r?Xt^dx`U$n~4N^N@NKro$_%1M^zkI~=BrGTz zMeq(fiVt{?X=)K$(vY8xgP}o(pC7oa)yJ>pJ^~ija2@*nidbaTV~V-=i-5RVwFCx* zozbrSYGPhk!G3C-b|7#jik8{_y&9e+!C%8ayvrqzUf@GRdqMP46z%pG`y)3KhsB>=lJgQa|2;+Q#ua@yPdTE9riV&1+|#XOi&+O_2B z-{KQ@qQCI~*~I8mlAOI#k+@ALUT3lgk0Jv)ll(#@GG!enU2b=;e0@n)YkZf_Ls5IN z`_Y;3o&_?AURWrS=FxB*unxBX_n#<@I0LZw=y9D3aX#7A{+rK(-xzw9U9J&!IWHs=rxkFBz)kQV2RtZ;3m*mTAKOcW@Ee zg6cG9V!ia#)9OfZWtO2Zb*4QE3Z2y}f?c!Nnzl7k9I2HNZ)(5UT>%yDi0ffzVKHX* zRSORLzj#}!Q6T#JVeGOPf0Lra*Siq6n~jHF%*@+OO~emNjIbCLLy;1Z{7td zYd`CdQ!PO+&e3t_WZ6MHF)*cCv^jB*%E8i(oYM7LTW#npGfO$m=!d8f`(6i$ z%JR>ifz^*NgS)SqGwJd3m2Hh7Y9DxT*s}lwUqKST`|I{@EzZs<8R*2q?cc+h3f#B8 z>fd0Jw$7jk&v;! zTH1l2P}7X(?ggVQn`X^E!{bZRI>~x{Mp4ZIs&0Ikrx@BqcQ?+I9%AIlTt}0jkBBXz(Gf$Jos4a6Ee4-chr(WZGf=(dq{;3kdo*NT}vl_fxP(e`EIS_0dM7u{oZq|7!&fK(Dl~4dNtPk znTr?lIqa7NVk9P+mwIa4`+q_Rgwk4GBdpv=QU8UWQl380#mu9r&y8GehISFaxG-ALRbtaYWF%yme-nTkZR@}vB1g%C(0jF(+m5kGeOm+udPY*OH&==9&2LCiov8ybi(~1h!3fYyfhF;n zDccsZ=fyJ1FKsw)lztxgQ>-_zG>9&9=j4*z8C>Xqr`IAoT3KA8lS_g#8Sp^PJ+NWj z&=x*8#i|@w5jtNJUKuPDoL1I>-Z)w~>kW;4O>a{-F zh&L`3J>W%|0%zgV^`7Upr^WMgHKo?eO652HSea1nsSkh~2}8e_Cko@QzJ$wgDG=o1=@V$24X(leO>k{kp_6reP(5 zdN%Sk4xeNo5h(*BpQ!bCP$D;o*XaAlRCRPfYa*lTi+1SanjL&stCM?$VHhopT``S| z^NIuZyx<_wSv$|V<~^NgLa42>Py}$r{75P&T7AX^4sf8Kcl zr3OE*P21HULw-u_YrA4l)(=fR(t_EV);(152L(F(7dm;xwExZo17|h|ur;8Ynp*l= zJpwDlR*k8N#oO_U!Rajuing1EA9SVpu1%fT+t=(q7 z_RiAWZMLD;=DqoXS}%7vD><31_hSC2jQ7^X~FD*!k@( zC!|T=!$}&a$EpLv>>~h$n{fS@+#koB@7jer8eg7tNFs3AilmSf?M{y#YSz#Nxh%3W z-O{{~9r0GM=eZx9usykBMsTPHoq!r>KtiQX!IX8FdHQK%7O3v@3x?uyrfpy3hL_Up zk33AV=yX3?h^`y)rd%N>pzJ9Kf(5At;1HmsxJ6b`X2|t_dt?s>SaR%xD@)H)QEV)~ z`m9y>0NA3Y>CH-oF)77ioi%8KSc#f2{2`c>3vfkwVGwuNkSu-Rwa|2IJiDOjivXnL z1P9}*%)I8o4l>IHFr7d+iG39J zL)L-=Jf;b4dCD>}AHYkuenIyGE7pkVvO;f1zD!iQA4q3v+!|_Iu3}CicZ3vS*(DND z(|`ML7uc@pVux!&97E4a>8Nei9}BS+l!L< zY;93g^mpz49d0S_2dwr6MCdP$@-zPw!&S4QL-iT zuzN^GSZ2)U7~K8&Z7$W%lN|xhp@1X$EecQhwG3a!i}vm-GlzY~9Mobj`F}L$C!nVI z`|sVnf=x3|zpptCtlpy_@8sQB612QA58g=jAn7zuXJ`LKONzqF&I!5&@n8)4x@MZ;Qq{geZI$%XoE$;GaLYlV>Bg&)VDnS5^k z^^nsM=LFfvk+=bkBU*k+i8qxfCeVT-#kY&-FHu)}x=Oy@o&Uu6Uus?Bn!|Kb3s^LK z?Y{=NHHij9pO{652hT4Pv&p*1UM7IES1+XS5n2{$x1Epnc;x7#>XZBjYu9*QgZnu8 zt9wr_YgCnASxgK~%DWp|&HTc=Kh=FJB}n2235u5}AnnM|%PCveV1Ko{=2g0e?E2Ri z&ZYd@i~XvD#K#mz+!(5Ll{J$q6QP?d)9_D&E5OYtg*WG4tW>q|NgE~n>13|^My3Dh zWuoe_E37i0fFa?<*p0|7PNl12xv|J(1MKEAaT ze=Y7Jd0cH}QQDQ|X#V3azfMB7Y%66?<60>8aR8Y*_FpE%)AITXW00Yl@H_l_0Q7`t zaBjMO&Kb`4{z4exe8A{B;g>132p6!x7`&WJtSQkS35Ha&K}ksgg2a&WK3OQA^Km@n zHvqPJm{K%J{OWP5@p(2K7L%oIGIX=712^J?FrJMsP(&U`F`18+FsU#CB@#f+FoUgz zFQu@dzb)>%nJmYd`&vp*a!dYulWP-DU0&K3^Ok{?6UIH}M@osuFrx+uCWS`@d2v?L zrx@GEs!r7SJx!%&ACP5Rm^1mGfIWomMR{)U(>u+F(BlV~!FS%i6b1p7*TkKcy4opq zMu|Z%Us3XCbHYvWZ0FYIxtGNT4t72}a}vK(u|{j?}AJ5 z%c%PM=^C4N*jxVrcBO%S2ohN&jG2GD&gpcP#JXeF7b;u4z0BCt1x-iZy00E``>sme z+>uB+B5JF+*p{i?5(gxfT2sD=ZfyYay->0s9HN-Q-3cJZy*KaQr8bqP?%o@a6SUx% z*xER)f8>JGdd0O0nO#dYmss^^t+_((vHEpMy%q3JI?mvogq=^)A5V+(u}G#ytDaw! z)00nYk(G8OJ~t*zuD1J;UerYdmMSqgc)a0o1+se!IdYVB2tedvYrQhFNLqESp!$1W z&(xKD(Bj^|k;%VMz^2<67w@d24uUKWUw=+x^n|xy*SfL~f;W@)t97QKx&^=jtB*Ze zC84{>_v~W7%+h=`r+m=rsS86k{^q_dS~zw%H#=^UBsN3uH${NWt;t%vCD&bIJQBdm z9^np!)O-R-8HH?T$s&y4XhoAl|vwNORTIGpLQ*ehj? z5dkeypaQRj_$=er8B~9#=TU3=1U!xB{HBC&HFhp77;md-A-q&&WnFLIfNr};eBw_j zk(I52SAayig2jxy(%;Px?fW=uiT|gw-FoCw;pp~Wd8Q*^On*PvZ7mdGT&aLcE6=}} zlf`6hU%b+Egu#t5I?e$g+_!Kn6!>O7Nu8dJx0^rANp;7sZiJ8h-Tjs@_Bx*?&y9H$r8I~HZjcASs5aQA_2fa%gx`-}6jzniI^;smW2SFVg$<0Kk(LQd+p=A@hF6 zJyXDBgLFjxawT|L8Z%r=ldW>KHEeyziJ2&Mqkw55iFpVe?6lWNGtrlB z0bZ>C>Aj@P%}U7}OJz>Lz35N%mq|rZ!WNCTrn337O_+?@Ecms+fx44C5BU!jsA6)K zORXG*8VV6k%Bz}Pf2nfq@%UJwrxky1;CkHkCx8@h-1#+4^+6yFL)|>@u0GBJQT#NikAx>{!W{tg$>+qjPbrc<)D9Cc9hd! z*8BPpzYBYbgqI(CW}c|nK&t$W4OIp)M%$(F=g-uP{$nb~J=B_fTf4^b0UUkx)W~~W zzVATv-0XYb)@ciFx)}Znd&8H+7@$KKF%WWF!}$i$nqQSZ^aI6d;|V{j-qe{Km>1sp zG|7gn^~RY$nAA+$SWyW%cO0|Jktd}j2nU-L^A|fF^g9ICNV~t^sC@==t+Uo!izkDUBi9jOul>}ZFE1G`Gqem>ms!r=uNfK(?2y%9^6ItHrnTM?_UoE$UN3qv1^ z4JnpNW3a{det+uqKYzy&D?6rQW*BUp9g2_VL{o_KrYn3($-e4bMUZmfL5Bl+FnK7p z{cYmf9a}GfX1>K<3FaX(+Ak0;C`2}6#-P_>UQjL?#$k8M&Ey;mZI!|v*AS|gFGWPi zbxtk1k|QeiT5a;bn_Akw#*BJ9{JG+_4;HQd(QRD^m{`=5<7QG_bQ5|RT#~xv5qUO- z2;_1`s-vL_Z&%B!Dcw9iM~=)-una$iNW`QVD5?UHJ|fNNEA94_`qqRn+DP zYgpcjG`@>Pm?Txlc=MRu1)Nq{i{fRZu@$uH~e+qCJ&KAN&;!$UuLpRNPTTk=F zTWfoomk5pdvq6B3+o9i{&LH|WqACUh=q;r455t(ziJ^Dt>&q;c73z-qsZ@w7JOr4N z_6M9Ul$08!_4r`q1J6n7v_T05lXgsqN0s2o=R>WS;~7h6QwjUuD1x% zIGanHecmENi1QK)(iUFdw=MFLwbzzc+ts~o8JkQj#xJUxX5^!003{2Tw_iOC9b{jQ zqm@W_TlSkLKJI!@J+(s(ku(SN z3PXdW2rH9t9BVhcPGSbqC4z#VX2}4$M3;}Yn&Wow-~EwJ(cT^t7%grd!~hxyXr3)4 zqr_bKtr^~C&#^SCx-p$0Af8-8Y@Gz3sfY-Fo5_Pnmda@zJu80v}rdC2z1@F8?h515U za(3={$L78N!!pp*JssFqhG!lch$__@SSz|hKy`e)&V2OVbPcQ%!-jem&Y#gth@vhB z?fw(}x#U-f{(80aP*+yE8(aF6_bg;_!#VF#zOBg6BVf)UeuBn{Rs~~w9D}*ZkK?me zDT8*fN7zF*(GhM!uE*P0GOa^D{`4H#a`?u+$LK%bsQJlweJQ-J=v78H)rYLPp8Cr* zvZ~9{o}F1tu1cy{RC+~?b>Hrh?zgquYA|V)6LMsAxxk-zGPH6jWPrB9MN*7|;ixQsOtpwP2K*ts# zz=nRYz6tI$&!&txZ@I!pEAgm+C$0qwVHJXnN!_oI7Z*QXH?dS@>RK}lB;NSzz)q`Y zFli=aRQF?bixhcy<@%T^?c5IxwwB}ItYHEo;8Y4D!*!j%1kb?YL{*NV@OS4|%f2b~ zphC@sC_N3Tfzs95h`R<7!`M8>y>^T2tg5_}pAp66u2=tXR@k%+|fMhdj?hKG#RG z^rC@R4>@m1I8N6+CNYJc_Uw=DV?G?i7{AfMT6P+G8l!-+rV~SO@`soO87fQwNEdSq z5#M&NEq`>n7%$eyFA&^3r7@nFe$8Ku4RT*4DX#ui{aSZUGNg_FrlBujI!1tqMp_Ub zM#_Dt46-0U|M>e^iKWWJ&*`|l@c1*6e-YL(kH-P|(^oFOQTf*Ylv&!< zti7=8U;mLsjb)uL`aR7R&R&NQh9YFAb1@~O&E}ImqK$#h(*&?Ii^kBc3_N2HFv=bq zuTZj10*(i107zhMJ(4l4vTAp^pYg~^9_R$Ai?GD)iv;Ufxzjk}>jb2yNmWeX{ke7|_Cs=%$a0P&D3SEC+w})!22)}pork3EbVlw32n9Xn7 zh8dWFSsEuxgIE=j_eBBK0CKuH1E>zQT;Qq7iSe@IX|ZfKTgNtO{{buQ^H#CSi}Mk` zTm|xuVQf2#3`g*=r{m`b46jmc9Z2e~1wJaQ+$3XXj`f`Ea4Zt&bh&RN6_$SdwIW~i zh725>-7$lyAUD>)ZbKQie{<+<FG;c%KfJ)S;=~ z_r|<(1o+V|G>-muUpONx7lX4nv7Dwyf9-X#6_ivi3XZyW*vSQr5-tsWnMR%a<7t0? zJW{3=f|GZigK}18mD7dO`fTx)#3E(8KPp8u&9ycBTQS9BN}e}-yf)x@a=F1JegqB2 zA`cfWFC-Hz^MX>$;ad2NFx%X*0vjSGAa{?6TZCs0nS`Sw4Xo9VTI@B>B74*h+w!Ub zu7gtZB4L-gJvR8fzJ1MP*(x2pUwoazccxaFmv`O#iQ|ZW*Xv{nXzn`Owj>ax9)zv{ za4EM?#70`2qV2PLF??P8$Y3>f88+u%6sJRZjXvPaG*fX~r|S`z`9rMR+Ip^f0a%Tw z;~0Jq25uGH?Uuf)ot>lq_37`!qQ#!ftdOeq9}Cn~OmuIIF8y1|gF3<13;W})>`z*> z#unG*fq;&PBb+?$3BNV(@(JeW9@$jCx92_zx%@Jew=K9ruttbK9URQ%(2We6?*DBj zvC(2de)+8A}XOF#*#CR1G;#&04jUPA_w_8wA+#m&GB zefG8ljUzvf3GsePKdTWPU=EPurAj|H(opjCiO(0sknEtpA=Hw${*v7jMIX$%h+Gd| z?3rNbuj#zk%s;qG-M1PKvZJuN14J#ssIYoCCMT(CR{9}W$RsfwMVwh?Au>EtiwnzgGkTp&3XBe4o2d0k)OuGfUSg81K ztX?e%pWLV1QC+OuNV3sOigXk$A9#MZL`D%c47$v;53qkAbJtJE~L>v+2lh;@sN(lt!g_ zAbFM)EA;*}(+n2DS)bbw4PAw61I2r}9niI$C@4jT%1_g3Aq~w#o0IZKcg#{e(-?_Y znj$c3g(XqDJz3bYDKdy8X$DsimQY zDLMCIQlL)L3Rh|k{m(v$y#m;?G{^+A6+YX9B7ATQz?7C%KQ|brPfSbHvzw#Of4O4a zCSQD?BXu=#AOc##@pGEREDsD^L?WR3@zV#M%Qu`faLJkE-^6q}q!7{9U4FBWql04b z7Z&&TXo*9i;yrhxr@hFET%2a?U|U4Xa9`}f#+HP7&AmoyrPi9U$o4S|Jm`DKyEV?J z3S)1Jyz>zfOOn!Er3z?eQ|dMY7?}K6#_I0B-dFHQ@I&H zYT)6BRIlj;Qo8UTYXBx~y9mA)@G{n}f4PjcOCLF&^spr&a*e?gHbf!yhX-Y~QZ%Pr zp{^>>(_|OzmZ4vN|1f*H( zyCde1P2dTti>UkYog zC(-``wR7t5>Wr5NH3<%PKG6`N2(p)XX0tO59~%RRJ}N2TCpWPr)A89_$IVQMy*~Za zW7Qk;LQj?(em9m6NYANlq{`CALh}ARH|yJbb4Jd!${@uzcuoMQg_+)o18Y9M$C*+0 zi57gQ5q|>I;a5K{MRXYSesOoktf28F)>BU*h(8tHh5U#O%@V+a;z~5!MNdEdc6p}g za3w}zxU;6^1?p;s%?|f17EUEl2q3@%BO!Lm-aql*<`K0k_d24_B&} z6_HFftF7*jT91ZYNqqV+^3@@#GdyCwqX)ushbB*X3of& z#)Jx7HmOzzPSqn7TfBf>L4)VoDp7T$oqt%Was*c+-{BwxhU8v|cXq5`k}X4j=+TYQ zvx|XNa{Z>U1f?2$evtedTk?XLr&oySYIfV*thNspE3YEP7cYws_E0JM0-27nPg%oN z`6`>n$eKTvAP+|ly0rb@;jkhI73KtV8N38XzVFU2b$MSie{WTs(Uoyi2@=_GkP^hm zy&NLlMf(rr_4c@R{`(c7h&LMFXP`boy5N!JB7NrP&o9RRds~^QV=pBw&X+U4^V!*v z7Ks53Imf7kjG8*hBF}4ruvJQ#KB4<3hXz((f@7vKCWRYbk_= z#Qq~>(z7aj-Hm4U(AHBJ-hpf$AL5tHp}{W}Vq?UJ-D+Zp@uqDt#K0VK%>n>HbSJ6#pOi5+ueVkP_fQ zH(|9=PK*kA1e!YkiaTY31ejlrnUL(QN6otiVHw6_m_~JI>qQr?&)B5M5cbA2$)E~g zO=o3qoEZnqgjvO_|51R8g)ifch8M~JC@@{sqPsi3*oeEz2SG ze{#dR$*G)D0i0cwS&n=MC?Wi4fR&gMVAk+vR@T^}i0;wFVQ#Pgv%GP71ifDTi%Ih! zGn3vx;GIk?B~E~~-aQI%t)lBYu?1pc=P${#HoNAHEPEnc=~shPtnRwvhi~A`K3SAY z7IkYJ*Z_RdnopT=bf-ic8;>f zu0VB+ySh3@h7#w&dB~tp^1T6mVu(4RZf`w-&%ZULrD)m+LH|LpF!_Hi1w^fK6_X9+ z0`nNX8sPcwOzw7dy0neu{6gGDuON4aHElsFg%Tz~lSBuKAQksddM&gx<>u$4>xW0i;h)0EX(O*Lw9 z=pP|3^rVqByNOs2*O1u{%uQ;)+eEM#ujhpGjE%Pi>{famp0)kOOZa8sh zyafXL2~aDyp4S7t$|E0`LyLi~OS1BhvebZaim;-I|Kt%s6d&ZZiy(X}VQFyb#v!xUcQgpTw* z9#qC;E~=Z?27bKCUck+-Bp?YDUxyuMo%8FDt}=`8dJHex=D=)tb?n>jx~qI+_mnc> z40&W!SYP!AQ=cU7MlXdOAMM5u9Amt*{9dB!oj53GWHvQ#hbf1w&6H&--!z+es<1vP zaG6HsBSn7XN$3>?r=kzWpIv)M?sJTc6?(yw>&RmXs zXze&a=F{_dLP3-^8tfiJTypQU#_G(2(bsD3^cFVqK%}V4oJgCa+|eXTx4_UD9q2#p z-x=D|Z8^gF_UU2Xr5wMm;47@*L6p9&HxxPxF#_UnL~Ys>n5eMC{HJP@)B>B1hnz0= z%D3L1Y7$7C@7_(avUiinjY^EvnudpgIh1fK4toY2CPp?_b% z*hDnwRei@Z&hm6u$TiK(Z;Qu zJV4IzGJY3W6beb+;b$pl<}@FrFcZCbqQbRgkt?C3gn}I9IrYA!5BZ`1J2&uCG~v-; zB}9bv8j;UI6;dxQc9--lRfdAgKhy!N8=S-hK;(xGj%;};LaBgtsq{q6!bt9(FW-ZakW-(j^11;V)8fNxp?HSCF2Dkhx-#0e>$M>l%Ff!21*7z)+1 zx*prFUar6XO~HT9M7ziT-qR0$cR}2%PE}=-VPD*v{Oou<+s2X7Duv+oy07 zs$$gB%gGsmUo`Pz>>6kYa8yGng$3VBVnPtsg}?F$4LPsX7(I90KCx?Ra51|O^I^u# z8eNc~L9l;!!o5<&GjObtdu1O|T{=cOH^x&CqQbxo1qT#!{=AA^k4IC76UlYo^6qLL z!bq`vxS~5k)2XJCB5L;hzB-az=-J1g-~?;wlcTMV@qzH5Ql{yWz%wIIpib^)I<&+$ z>02AL8#UhI{m<=lrQOGd9#{h|ml*A(Q3Tank+V^3c=7BHJdr9eFyL{-atb$*)VKL% zHUvsT&PYk{ z@rTka3HZ(8bz&y+)TS_B!?VSt-CdCt^&4}^_E>qhl;at}J8L3M_4jmGfsksUGg70i zbKKEzTK>)W!KC~?24R-E9lXMg%$DH=A&+$02I8Ho6_1r4h~JyHtcae3 zHQM^enXd0xO4wOuc06450116vQ@T|ZK~ymXSYV@0qf*u8*%@qGH`qI;O3%AO7KLbf zg^|M}82R@->`El;L@K;Wv1E5vPX*Eh==IqXY?%ef{ToOhbA7uW#ciQT`j3-^boq$u zY4UBC!YW5C79RAQuziiZX{y;ziHO& z0!%Rpm$LdT4|Eh{M;zqzJ>eRdF#sKh2I{n^44Te(TqI5O7VM&m6aL5wm`->U~R9f&_cD0|vi_5VAvlPIcAZFLVYM&`+HMhx?)`!IPhu>GU;thgFxLrsQT z;GB?lN%A$VZ_J6gO!xMnb1d)YZ3yHHqpz3UI*2wT?0Shq&cRTpoAL2m!oCRmPj+*5 zA$g`?d^4hs#BY-xv`iPgj@U@Q$VC__MMU?Cd&^UP_jZ3FchmYFFSQ94NiS5dFEE!uHADfr919B>9FFNO_+vD1#E~VlUv7 z=Q;;#15JC6(Gb=@(`LHc;hwzidbpp^{bxg|28W)O$6jEX&U8HJGD$O!Do zFe5Ucjz@%p0+Z}JM3cSQb~*mdtLZ9t?#2-v%Go#agRaKu{i^)Gd}0nZ2bo*3kfYXL zViWYJL5MPI0M`~`kW8_np7y=C9(NF08&s!ImIRr##=WO1Brj2%nxQ>}C7Gz>^OO()`sr0GBj~u>)2ywhU&T zq0_Nn{Zb2-9(M)*iF}5op$hnz#yzc`I{eXW5MJ7#Hj`D}k#{bzB1TgvL6B9w7G~97 z(RXBWzt zUs1OR5B{AGL2l*C0Wah*Pf&qUtX_I4Iv)=GpG`6?VhTe; zjJT<%Mfa!NO}pl=KA^EN`IMnFBQdnxwXqR8pubspD}Dw@i-H#@hCWJ;)kM*by;S+% zomKf=-rIlTc$0>z?$&js6jVIra2IdcyRoWJ^{FUoFZ&zHWzLSXn5Pms2ng;t<8`GC zLCh6Hf8R%;*G(yk)upM~@V}Ng>{c!zK)HFBy8i4E$6S3dBZ2veE)f}Xy_38I{$j{_2M)P zm2NIBcN8xd^Zxg1LXtl#J|U>U4WiWXh?yNV(NLgit4I^1em9maeqEYly}v87>pNt9 zVSQ!Jj17jIeT}P8<)T*JTc+@DxCFj~$N!wiU%XX-te+Q}$zZahj)<=B(?TXok{sou zN3~1v!=W_d2^jAI*ZqfBw#vU?WE$hP>&W1;eLn{V}RYk9{ttR1=oI_gXu&0 zcf@e%UybylF=RE+Qo6mH@x53>`NVDV&TB`dF zgxRKr+AnLbS8v%3g)mc=soGhc+RSLUprkaa&op&eyp18Ss}cU7dWKxEixuj%#J+cS zmdeBad=SeCI=fp3gM0l;EC639Y}SYZm}bqfT}v<515Hv^H!~)1rBFO^l-e|Q;TVK1 zj;&8yJdQRlXa9X!)(ujx{kxJTrhlAI;c;hebG1Lu?}3O?nP7a23nX(<*G3mRjw4ewgCO&`u^LN@$6jhs;aDpKVlpD32VPA+aRV3+jye zkGHLb?dfRT$dpxb*nW{Z48UV8*AwQgb2&J_SB4?~%b{ccyIuwOQn_Qw8+{FQx6A4z znQJOhx`=Vj2eR%xsisB`Gh%+HjCWRu|D}*|lYjQ3CKDXU@#}b=y;*yxxE1z{HbwDYdtqCMUEKjtX#zyTe$Akxf2bnxuYMawu3A zp{CVKYu5rW8SN(|DjKgwgtq&(i4#imhdPb4*JPVm(Eth0=jHsZxt+bp=#Aqnr&^nb z*%-4PprM5tACSJ$h7SoG6SUXF%*!>!)&W?*UAi zS8|9|BkFd1s7u!JkBBm_>^N5O2BLTI7%cCfvKwBo{brbKXbY(1kXpNz#(AH62{Qa& z!*sjux5kY!8xIY(_*6wP#2PT9r74-V!;rlM;@n*EiHjF=?CoSGTlnqo>+>!?9d*uJ z_x90iyIa!Vo0y($XHm5m;u&-$!KZ}Kgh3ohDR~al6}D{6u9P~LUREthx}LAbe~^fo zIWYuO;`N{@Drf)5F?penMZ3UsR!Jc+{6pmHYD4mVng+y+_Kl8LY~;-kcrGSngV{SlJf_Vypks9>IV&4@0!#New$(0yEOHy zwLj!*ON1EKu^UUNuAor^>hr zQIF=onVSJ~W1~nlR^!)jgrhr>N_FCdI|HWPt+d%QWQ%^!MdZ{tx? ztM%Pl<@7*a5H@{c|ylKGw6m43fR=Rufl;I+KSdNW>n; zBH|smarthTuDQXT-O6Q974$BnQ=?yP%t}~SP5J#FVZbeMp;2%ux@ZPxJ5N&G@|$5i z383XOc8AdiD`yYu;|BoFz|4P$tAW>4t1|#81k>=mrmMg%|4#{BgX0iiv0l zlHDhZGwOz{bcPn#q|gK9dJJS!eDmKt^q-w@1)2ewA!midX3p*Ty;(|7+uc>AbDI5boe=HAIm=q{ zoItRHjq}uKewBj44{XZg;ZF2CGqU3&cA&Sj;1k*;t`by4wJqq!8+7Ysgn=VvHVR8i zZz$wI*8*rfYj*g(B|s(ix=e^l=RZJCO(Sp=4yjDm^wTb<*Y8QF8^u4)3?Qk0F`^GfoJ80SOks5DHcTM9)~RPxZ}1JcY~xQNw0K zzPkfIyk43~wCqcVRP?mqmNM^Xs^+k+ZDJ>fc9%U+jPLk^HT3hXAUQw03KKP#QM?iU z9EN1c1FeDPY9Pv~5UFy_jd6is=-0Z0=jBW7OI}zXD7AM@blYA{2$-Rt5^jO>xY?=+ z_eq=+TFFL=)p*N5!r8UCMno2AZBIT*>at5Lc*&C!hhktQEsK#=*!aLmVI&gN2Z4*Z zceMb*aq@V_{FqA2*T*_`YE?|$`KG1Sh+#@%>A5)|Z`C;i06O4-m{eS2?L|Y%Ko~OY zXa2d%K+pKB_N5_qT!-HoeeTk81K zZ?pktDwX|BFyw;-bmDk3N$N-neQ^G8WR1ryjiAzCdDMB~PO_Afr$~nQr9lLZBd*nW z`}Jaw0_*t7N)^;B9x4S`mDm*Xu_l$Niop_U0P9+#%x1v=F%N~7gIZ$wGfAB=T>CFR z5eJ6r<)xnX=PQ^8DEX7JsyAG2oX8}oX3qp=h)RR_>en%8nd!At?MYQG70 zXoW9c>Fz(Oh;^>bEd%VHH~j#UQ{0U^$Ie}b>EZO?xhr}i3)Q#(TvSea!oS<%8TbQX zicYDT@KEgQP7$wV&|I`l8gJM)5jX7^6nZ6@B*FMHc?ePiYLj}>G*KDHzpC}sP1EQL z-Ed@dIOLEB!&lOGlPuGxZ2Z zS6{UD&e|S0RNsy6jq|B9O{)TQ#|ZjpzytV|F&dD=aLe4!oiW>XS6=Lg&-@iHgY$*D z8I2zWs}TW1Zp;U9Sq^Nga*}he#f{<=yg6BThpqDk8(;l+x6;R@Oze{^ppwYP!vddF#Y+ zxmLtHo+LpgrOK%LdiTk-=sm=nHXS5&>0vH(p4)QL#U-wPXD^ zOy1~?o94~vYZF%!sWtUBtm~~5RdsD&H zCSwOHA+_PwK+wjRl=nMCUCDw4Nwg_Xs2{SeZ*LkTlG3BMRIx0^82qwmPB`&F zQQj?1S;<}U&)0wfPO&M?AU58&y!R|lHb`JQR||L};%!cH7j9`&)^(nbJBLJ7k$>;h zg=qO-+i1tBKHh;WP*@lhmDW0f&QI+_J~UV196rw|AH40Xl}bQ#-y>XxJW3L5StGUI zXI{PC>Ek+0<@ATHzrOfcGCay_(!1#{2Mf;8XP35IXYV@7a-A}%05eZV-iQ4t_+zv4 z$Wdj!-KY#8cjWmfUtq8^5jNSzu`%GJRJKwnf7@$?{}lYPvbFa{4ltWN`Cc|#k^#!9 z7Z|#3^4`IMJ1b5uKPmY7&m=+74dp_iSS3qJ#uc*DNWN9?=uzx7 ztV7By)@jGWoA}J?V>@(I2}6M5jB&n;c*rU&_Ys)CYCu!4JKC<2dynE&?hHo3;~Vm& z?MfK)7gZ(+LKZaY>lY^fqw{xoCf){(UrE^KXL#bCqMRtfMASej1dBe`;J1qA&0M?G zhH-czK+ReR9fIXV;!)=MD(T9uJxz+e=jS@8Qp_$D@ZjOwM`L90JhiP$&>t`j^tC?5 zU%J`)xQ&RI#2fVS$lU~@waz07@au51-9qQd8`3fX0DdN*tHk~9{_hF=-=2U`^$wJI XP`~=Sr?A0kCSV!qo879>MMVAwxj|BG literal 0 HcmV?d00001 diff --git a/public/sw.js b/public/sw.js index a94ac67d..ed1172cb 100644 --- a/public/sw.js +++ b/public/sw.js @@ -35,6 +35,36 @@ self.addEventListener('fetch', (event) => { } case "init":{ event.respondWith(new Response("v2")) + break + } + case 'share':{ + event.respondWith((async () => { + const formData = await event.request.formData(); + /** + * @type {File} + */ + const character = formData.get('character') + const preset = formData.get('preset') + const module = formData.get('module') + if(character){ + const buf = await character.arrayBuffer() + await registerCache(`/sw/share/character`, buf, true) + return Response.redirect("/#share_character", 303) + } + if(preset){ + const buf = await preset.arrayBuffer() + await registerCache(`/sw/share/preset`, buf, true) + return Response.redirect("/#share_preset", 303) + } + if(module){ + const buf = await module.arrayBuffer() + await registerCache(`/sw/share/module`, buf, true) + return Response.redirect("/#share_module", 303) + } + return Response.redirect("/", 303) + + })()) + break } default: { event.respondWith(new Response( diff --git a/src/ts/characterCards.ts b/src/ts/characterCards.ts index ffe37d8e..cffde8a4 100644 --- a/src/ts/characterCards.ts +++ b/src/ts/characterCards.ts @@ -14,6 +14,7 @@ import { PngChunk } from "./pngChunk" import type { OnnxModelFiles } from "./process/transformers" import { CharXReader, CharXWriter } from "./process/processzip" import { Capacitor } from "@capacitor/core" +import { exportModule, readModule, type RisuModule } from "./process/modules" export const hubURL = "https://sv.risuai.xyz" @@ -65,6 +66,7 @@ async function importCharacterProcess(f:{ } } + if(f.name.endsWith('charx')){ console.log('reading charx') alertStore.set({ @@ -80,11 +82,18 @@ async function importCharacterProcess(f:{ alertError(language.errors.noData) return } - const card = JSON.parse(cardData) + const card:CharacterCardV3 = JSON.parse(cardData) if(CCardLib.character.check(card) !== 'v3'){ alertError(language.errors.noData) return } + if(reader.moduleData){ + const md = await readModule(Buffer.from(reader.moduleData)) + card.data.extensions ??= {} + card.data.extensions.risuai ??= {} + card.data.extensions.risuai.triggerscript = md.trigger ?? [] + card.data.extensions.risuai.customScripts = md.regex ?? [] + } await importCharacterCardSpec(card, undefined, 'normal', reader.assets) let db = get(DataBase) return db.characters.length - 1 @@ -133,7 +142,7 @@ async function importCharacterProcess(f:{ continue } if(chunk.key.startsWith('chara-ext-asset_')){ - const assetIndex = (chunk.key.replace('chara-ext-asset_', '')) + const assetIndex = chunk.key.replace('chara-ext-asset_:', '').replace('chara-ext-asset_', '') alertWait('Loading... (Reading Asset ' + assetIndex + ')' ) const assetData = Buffer.from(chunk.value, 'base64') const assetId = await saveAsset(assetData) @@ -304,7 +313,7 @@ export async function characterURLImport() { db.modules.push(importData) setDatabase(db) alertNormal(language.successImport) - SettingsMenuIndex.set(1) + SettingsMenuIndex.set(14) settingsOpen.set(true) return } @@ -315,11 +324,90 @@ export async function characterURLImport() { name: 'imported.risupreset', data: importData }) - SettingsMenuIndex.set(14) + SettingsMenuIndex.set(1) settingsOpen.set(true) return - } + if(hash.startsWith('#share_character')){ + const data = await fetch("/sw/share/character") + if(data.status !== 200){ + return + } + const charx = new Uint8Array(await data.arrayBuffer()) + await importCharacterProcess({ + name: 'shared.charx', + data: charx + }) + } + if(hash.startsWith('#share_module')){ + const data = await fetch("/sw/share/module") + if(data.status !== 200){ + return + } + const module = new Uint8Array(await data.arrayBuffer()) + const md = await readModule(Buffer.from(module)) + md.id = v4() + const db = get(DataBase) + db.modules.push(md) + setDatabase(db) + alertNormal(language.successImport) + SettingsMenuIndex.set(14) + settingsOpen.set(true) + } + if(hash.startsWith('#share_preset')){ + const data = await fetch("/sw/share/preset") + if(data.status !== 200){ + return + } + const preset = new Uint8Array(await data.arrayBuffer()) + await importPreset({ + name: 'shared.risup', + data: preset + }) + SettingsMenuIndex.set(1) + settingsOpen.set(true) + } + if ("launchQueue" in window) { + const handleFiles = async (files:FileSystemFileHandle[]) => { + for(const f of files){ + const file = await f.getFile() + const data = new Uint8Array(await file.arrayBuffer()) + if(f.name.endsWith('.charx')){ + await importCharacterProcess({ + name: f.name, + data: data + }) + } + if(f.name.endsWith('.risupreset') || f.name.endsWith('.risup')){ + await importPreset({ + name: f.name, + data: data + }) + SettingsMenuIndex.set(1) + settingsOpen.set(true) + alertNormal(language.successImport) + } + if(f.name.endsWith('risum')){ + const md = await readModule(Buffer.from(data)) + md.id = v4() + const db = get(DataBase) + db.modules.push(md) + setDatabase(db) + alertNormal(language.successImport) + SettingsMenuIndex.set(14) + settingsOpen.set(true) + } + } + } + //@ts-ignore + window.launchQueue.setConsumer((launchParams) => { + if (launchParams.files && launchParams.files.length) { + const files = launchParams.files as FileSystemFileHandle[] + handleFiles(files) + } + }); + } + } @@ -850,7 +938,7 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha const b64encoded = Buffer.from(await convertImage(rData)).toString('base64') assetIndex++ card.data.extensions.risuai.emotions[i][1] = `__asset:${assetIndex}` - await writer.write("chara-ext-asset_" + assetIndex, b64encoded) + await writer.write("chara-ext-asset_:" + assetIndex, b64encoded) } } @@ -866,7 +954,7 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha const b64encoded = Buffer.from(await convertImage(rData)).toString('base64') assetIndex++ card.data.extensions.risuai.additionalAssets[i][1] = `__asset:${assetIndex}` - await writer.write("chara-ext-asset_" + assetIndex, b64encoded) + await writer.write("chara-ext-asset_:" + assetIndex, b64encoded) } } @@ -882,7 +970,7 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha const b64encoded = Buffer.from(rData).toString('base64') assetIndex++ card.data.extensions.risuai.vits[key] = `__asset:${assetIndex}` - await writer.write("chara-ext-asset_" + assetIndex, b64encoded) + await writer.write("chara-ext-asset_:" + assetIndex, b64encoded) } } if(type === 'json'){ @@ -923,7 +1011,7 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha if(type === 'png'){ const b64encoded = Buffer.from(await convertImage(rData)).toString('base64') card.data.assets[i].uri = `__asset:${assetIndex}` - await writer.write("chara-ext-asset_" + assetIndex, b64encoded) + await writer.write("chara-ext-asset_:" + assetIndex, b64encoded) } else if(type === 'json'){ const b64encoded = Buffer.from(await convertImage(rData)).toString('base64') @@ -1015,6 +1103,20 @@ export async function exportCharacterCard(char:character, type:'png'|'json'|'cha }) if(type === 'charx'){ + const md:RisuModule = { + name: `${char.name} Module`, + description: "Module for " + char.name, + id: v4(), + trigger: card.data.extensions.risuai.triggerscript ?? [], + regex: card.data.extensions.risuai.customScripts ?? [], + lorebook: char.globalLore ?? [], + } + delete card.data.extensions.risuai.triggerscript + delete card.data.extensions.risuai.customScripts + await writer.write("module.risum", await exportModule(md, { + alertEnd: false, + saveData: false + })) await writer.write("card.json", Buffer.from(JSON.stringify(card, null, 4))) } else{ diff --git a/src/ts/process/modules.ts b/src/ts/process/modules.ts index 0d4800a2..a7b9c198 100644 --- a/src/ts/process/modules.ts +++ b/src/ts/process/modules.ts @@ -27,7 +27,12 @@ export interface RisuModule{ namespace?:string } -export async function exportModule(module:RisuModule){ +export async function exportModule(module:RisuModule, arg:{ + alertEnd?:boolean + saveData?:boolean +} = {}){ + const alertEnd = arg.alertEnd ?? true + const saveData = arg.saveData ?? true const apb = new AppendableBuffer() const writeLength = (len:number) => { const lenbuf = Buffer.alloc(4) @@ -76,8 +81,90 @@ export async function exportModule(module:RisuModule){ writeByte(0) //end of file - await downloadFile(module.name + '.risum', apb.buffer) - alertNormal(language.successExport) + if(saveData){ + await downloadFile(module.name + '.risum', apb.buffer) + } + if(alertEnd){ + alertNormal(language.successExport) + } + + return apb.buffer +} + +export async function readModule(buf:Buffer):Promise { + let pos = 0 + + const readLength = () => { + const len = buf.readUInt32LE(pos) + pos += 4 + return len + } + const readByte = () => { + const byte = buf.readUInt8(pos) + pos += 1 + return byte + } + const readData = (len:number) => { + const data = buf.subarray(pos, pos + len) + pos += len + return data + } + + if(readByte() !== 111){ + console.error("Invalid magic number") + alertError(language.errors.noData) + return + } + if(readByte() !== 0){ //Version check + console.error("Invalid version") + alertError(language.errors.noData) + return + } + + const mainLen = readLength() + const mainData = readData(mainLen) + const main:{ + type:'risuModule' + module:RisuModule + } = JSON.parse(Buffer.from(await decodeRPack(mainData)).toString()) + + if(main.type !== 'risuModule'){ + console.error("Invalid module type") + alertError(language.errors.noData) + return + } + + let module = main.module + + let i = 0 + while(true){ + const mark = readByte() + if(mark === 0){ + break + } + if(mark !== 1){ + alertError(language.errors.noData) + return + } + const len = readLength() + const data = readData(len) + module.assets[i][1] = await saveAsset(Buffer.from(await decodeRPack(data))) + alertStore.set({ + type: 'wait', + msg: `Loading... (Adding Assets ${i} / ${module.assets.length})` + }) + if(!isTauri && !Capacitor.isNativePlatform() &&!isNodeServer){ + await sleep(100) + } + i++ + } + alertStore.set({ + type: 'none', + msg: '' + }) + + module.id = v4() + return module } export async function importModule(){ @@ -90,78 +177,7 @@ export async function importModule(){ if(f.name.endsWith('.risum')){ try { const buf = Buffer.from(fileData) - let pos = 0 - - const readLength = () => { - const len = buf.readUInt32LE(pos) - pos += 4 - return len - } - const readByte = () => { - const byte = buf.readUInt8(pos) - pos += 1 - return byte - } - const readData = (len:number) => { - const data = buf.subarray(pos, pos + len) - pos += len - return data - } - - if(readByte() !== 111){ - console.error("Invalid magic number") - alertError(language.errors.noData) - return - } - if(readByte() !== 0){ //Version check - console.error("Invalid version") - alertError(language.errors.noData) - return - } - - const mainLen = readLength() - const mainData = readData(mainLen) - const main:{ - type:'risuModule' - module:RisuModule - } = JSON.parse(Buffer.from(await decodeRPack(mainData)).toString()) - - if(main.type !== 'risuModule'){ - console.error("Invalid module type") - alertError(language.errors.noData) - return - } - - let module = main.module - - let i = 0 - while(true){ - const mark = readByte() - if(mark === 0){ - break - } - if(mark !== 1){ - alertError(language.errors.noData) - return - } - const len = readLength() - const data = readData(len) - module.assets[i][1] = await saveAsset(Buffer.from(await decodeRPack(data))) - alertStore.set({ - type: 'wait', - msg: `Loading... (Adding Assets ${i} / ${module.assets.length})` - }) - if(!isTauri && !Capacitor.isNativePlatform() &&!isNodeServer){ - await sleep(100) - } - i++ - } - alertStore.set({ - type: 'none', - msg: '' - }) - - module.id = v4() + const module = await readModule(buf) db.modules.push(module) setDatabase(db) return diff --git a/src/ts/process/processzip.ts b/src/ts/process/processzip.ts index a74d0c5f..a3f85f6d 100644 --- a/src/ts/process/processzip.ts +++ b/src/ts/process/processzip.ts @@ -81,6 +81,7 @@ export class CharXReader{ assetPromises:Promise[] = [] excludedFiles:string[] = [] cardData:string|undefined + moduleData:Uint8Array|undefined constructor(){ this.unzip = new fflate.Unzip() this.unzip.register(fflate.UnzipInflate) @@ -98,6 +99,9 @@ export class CharXReader{ else if(file.name === 'card.json'){ this.cardData = new TextDecoder().decode(assetData) } + else if(file.name === 'module.risum'){ + this.moduleData = assetData + } else{ this.assetPromises.push((async () => { const assetId = await saveAsset(assetData) From 4e36d602fecf3839fe58054044d12955488fc5f6 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Tue, 10 Sep 2024 22:10:20 +0900 Subject: [PATCH 089/174] Update version to 130.0.0 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index e51e4857..9c62b55a 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "129.1.0" + "version": "130.0.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 7c95b89e..365946c5 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "129.1.0" +export let appVer = "130.0.0" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index 4d8d43e5..c7e8b44e 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"129.1.0"} \ No newline at end of file +{"version":"130.0.0"} \ No newline at end of file From 09b38590062db072fa2d68e880793f76fab1a2fc Mon Sep 17 00:00:00 2001 From: kwaroran Date: Tue, 10 Sep 2024 22:51:37 +0900 Subject: [PATCH 090/174] Add persistant --- src/ts/storage/globalApi.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/ts/storage/globalApi.ts b/src/ts/storage/globalApi.ts index 8f335943..1645d5b8 100644 --- a/src/ts/storage/globalApi.ts +++ b/src/ts/storage/globalApi.ts @@ -521,6 +521,15 @@ export async function loadData() { try { await loadRisuAccountData() } catch (error) {} + } + try { + //@ts-ignore + const isInStandaloneMode = (window.matchMedia('(display-mode: standalone)').matches) || (window.navigator.standalone) || document.referrer.includes('android-app://'); + if(isInStandaloneMode){ + await navigator.storage.persist() + } + } catch (error) { + } await checkNewFormat() const db = get(DataBase); From 5b6c3e0d045a047a5d2cfa3296bd52ff12c2a7fa Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 11 Sep 2024 06:08:21 +0900 Subject: [PATCH 091/174] Add JSON Schema --- src/lang/en.ts | 19 +++ src/lib/Setting/Pages/PromptSettings.svelte | 9 + src/ts/process/request.ts | 74 ++++++++- src/ts/process/scripts.ts | 4 - src/ts/process/templates/jsonSchema.ts | 172 ++++++++++++++++++++ src/ts/storage/database.ts | 5 + 6 files changed, 273 insertions(+), 10 deletions(-) create mode 100644 src/ts/process/templates/jsonSchema.ts diff --git a/src/lang/en.ts b/src/lang/en.ts index b6685bd0..6f327568 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -146,6 +146,21 @@ export const languageEnglish = { customCSS: "Custom CSS for styling. you can also disable/enable it by pressing (Ctrl + .) if something goes wrong.", betaMobileGUI: "If enabled, it will use beta mobile GUI on small (less than 800px) screens. requires refresh.", unrecommended: "This is a unrecommended setting. it is not recommended to use this setting.", + jsonSchema: "This is a JSON Schema that will be sent to the AI model if AI model supports JSON Schema.\n\nHowever, since JSON Schema is hard to learn, In RisuAI, you can use subset of TypeScript interface instead of JSON Schema. RisuAI will convert it in runtime." + + "For example, if you want to send a JSON like this:\n\n```js\n{\n \"name\": \"RisuAI\", //name must be RisuAI,\n \"age\": 1, //age must be number,\n \"icon\": \"slim\", //icon must be \'slim\' or 'rounded'\n \"thoughts\": [\"Good View!\", \"Lorem\"] //thoughts must be array of strings\n}\n```\n\n" + + "You can put this TypeScript interface:\n\n```typescript\ninterface Schema {\n name: string;\n age: number;\n icon: \'slim\'|\'rounded\'\n thoughts: string[]\n}\n```\n\n" + + "Name of the interface doesn't matter. for more information, see the typescript documentation. (https://www.typescriptlang.org/docs/handbook/interfaces.html), and to Check what subset of TypeScript is supported, see the below." + + "
Supported TypeScript Subset\n\n" + + `Supported types are \`boolean\`, \`number\`, \`string\`, \`Array\`. Advanced typing like unit types, intersection types, union types, optional, literal types, and etc. are not supported except for these cases:\n + - Array of primitive types: (ex. \`string[]\`, \`Array)\` + - Unit types between strings: (ex. \`'slim'|'rounded'\`). + + Properties must be one in a line. if there is multiple properties in a line, it will throw an error. Properties and name of the interface must be only in latin characters, in ASCII range. name of the properties must not be surrounded by quotes or double quotes. Nesting inside the interface is not supported. it is not allowed to put \`{\` or \`}\` in the line that properties are defined. If you want to use more advanced types, use JSON Schema instead. + ` + + "
" + , + strictJsonSchema: "If enabled, it will strictly follow the Provided Schema for JSON on some models. if it is disabled, it may ignore the JSON Schema.", + extractJson: "If it is not blank, it will extract specific JSON data from the response. for example, if you want to extract `response.text[0]` in response `{\"response\": {\"text\": [\"hello\"]}}`, you can put `response.text.0`.", }, setup: { chooseProvider: "Choose AI Provider", @@ -715,4 +730,8 @@ export const languageEnglish = { connectionHost: "You are the host of the room.", connectionGuest: "You are the guest of the room.", otherUserRequesting: "Other user is already requesting. try again later.", + jsonSchema: "JSON Schema", + enableJsonSchema: "Enable Schema", + strictJsonSchema: "Strict Schema", + extractJson: "Extract JSON", } \ No newline at end of file diff --git a/src/lib/Setting/Pages/PromptSettings.svelte b/src/lib/Setting/Pages/PromptSettings.svelte index c9656b47..8e594476 100644 --- a/src/lib/Setting/Pages/PromptSettings.svelte +++ b/src/lib/Setting/Pages/PromptSettings.svelte @@ -114,6 +114,9 @@ + + + {#if $DataBase.showUnrecommended} @@ -125,4 +128,10 @@ {language.defaultVariables} + {#if $DataBase.jsonSchemaEnabled} + {language.jsonSchema} + + {language.extractJson} + + {/if} {/if} \ No newline at end of file diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index c14a0a76..0ada4266 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -22,6 +22,7 @@ import {createParser} from 'eventsource-parser' import {Ollama} from 'ollama/dist/browser.mjs' import { applyChatTemplate } from "./templates/chatTemplate"; import { OobaParams } from "./prompt"; +import { extractJSON, getOpenAIJSONSchema } from "./templates/jsonSchema"; @@ -485,13 +486,9 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' : (!requestModel) ? 'gpt-3.5-turbo' : requestModel, messages: formatedChat, - // temperature: temperature, max_tokens: maxTokens, - // presence_penalty: arg.PresensePenalty || (db.PresensePenalty / 100), - // frequency_penalty: arg.frequencyPenalty || (db.frequencyPenalty / 100), logit_bias: bias, stream: false, - // top_p: db.top_p, }) @@ -503,6 +500,13 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' body.user = getOpenUserString() } + if(db.jsonSchemaEnabled){ + body.response_format = { + "type": "json_schema", + "json_schema": getOpenAIJSONSchema() + } + } + if(aiModel === 'openrouter'){ if(db.openrouterFallback){ body.route = "fallback" @@ -641,6 +645,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' const transtream = new TransformStream( { async transform(chunk, control) { dataUint = Buffer.from(new Uint8Array([...dataUint, ...chunk])) + let JSONreaded:{[key:string]:string} = {} try { const datas = dataUint.toString().split('\n') let readed:{[key:string]:string} = {} @@ -649,7 +654,17 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' try { const rawChunk = data.replace("data: ", "") if(rawChunk === "[DONE]"){ - control.enqueue(readed) + if(db.extractJson && db.jsonSchemaEnabled){ + for(const key in readed){ + const extracted = extractJSON(readed[key], db.extractJson) + JSONreaded[key] = extracted + } + console.log(JSONreaded) + control.enqueue(JSONreaded) + } + else{ + control.enqueue(readed) + } return } const choices = JSON.parse(rawChunk).choices @@ -674,7 +689,17 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' } catch (error) {} } } - control.enqueue(readed) + if(db.extractJson && db.jsonSchemaEnabled){ + for(const key in readed){ + const extracted = extractJSON(readed[key], db.extractJson) + JSONreaded[key] = extracted + } + console.log(JSONreaded) + control.enqueue(JSONreaded) + } + else{ + control.enqueue(readed) + } } catch (error) { } @@ -741,6 +766,21 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' if(res.ok){ try { if(multiGen && dat.choices){ + if(db.extractJson && db.jsonSchemaEnabled){ + + const c = dat.choices.map((v:{ + message:{content:string} + }) => { + const extracted = extractJSON(v.message.content, db.extractJson) + return ["char",extracted] + }) + + return { + type: 'multiline', + result: c + } + + } return { type: 'multiline', result: dat.choices.map((v) => { @@ -751,11 +791,33 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' } if(dat?.choices[0]?.text){ + if(db.extractJson && db.jsonSchemaEnabled){ + try { + const parsed = JSON.parse(dat.choices[0].text) + const extracted = extractJSON(parsed, db.extractJson) + return { + type: 'success', + result: extracted + } + } catch (error) { + console.log(error) + return { + type: 'success', + result: dat.choices[0].text + } + } + } return { type: 'success', result: dat.choices[0].text } } + if(db.extractJson && db.jsonSchemaEnabled){ + return { + type: 'success', + result: extractJSON(dat.choices[0].message.content, db.extractJson) + } + } const msg:OpenAIChatFull = (dat.choices[0].message) return { type: 'success', diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts index c91e03e0..2566c337 100644 --- a/src/ts/process/scripts.ts +++ b/src/ts/process/scripts.ts @@ -144,7 +144,6 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter const matchAll = isGlobal ? data.matchAll(reg) : [data.match(reg)] data = data.replace(reg, "") for(const matched of matchAll){ - console.log(matched) if(matched){ const inData = matched[0] let out = outScript.replace('@@move_top ', '').replace('@@move_bottom ', '') @@ -163,7 +162,6 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter } return v }) - console.log(out) if(outScript.startsWith('@@move_top') || pscript.actions.includes('move_top')){ data = out + '\n' +data } @@ -257,8 +255,6 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter }) } - console.log(parsedScripts) - if(orderChanged){ parsedScripts.sort((a, b) => b.order - a.order) //sort by order } diff --git a/src/ts/process/templates/jsonSchema.ts b/src/ts/process/templates/jsonSchema.ts new file mode 100644 index 00000000..1b162640 --- /dev/null +++ b/src/ts/process/templates/jsonSchema.ts @@ -0,0 +1,172 @@ +import { risuChatParser } from "src/ts/parser" +import { DataBase } from "src/ts/storage/database" +import { get } from "svelte/store" + +export function convertInterfaceToSchema(int:string){ + if(!int.startsWith('interface ') && !int.startsWith('export interface ')){ + return JSON.parse(int) + } + + int = risuChatParser(int) + + type SchemaProp = { + "type": "array"|"string"|"number"|"boolean", + "items"?:SchemaProp + "enum"?:string[] + "const"?:string + } + + const lines = int.split('\n') + let schema = { + "$schema": "https://json-schema.org/draft/2020-12/schema", + "type": "object", + "additionalProperties": false, + "properties": {} as {[key:string]:SchemaProp}, + "required": [] as string[], + } + for(let i = 1; i < lines.length; i++){ + let content = lines[i].trim() + if(content === '{'){ + continue + } + if(content === '}'){ + continue + } + if(content === ''){ + continue + } + + let placeHolders:string[] = [] + + content = content + .replace(/\\"/gu, '\uE9b4a') + .replace(/\\'/gu, '\uE9b4b') + .replace(/"(.+?)"/gu, function(match, p1){ + placeHolders.push(match) + return `\uE9b4d${placeHolders.length - 1}` + }) + .replace(/'(.+?)'/gu, function(match, p1){ + placeHolders.push(`"${p1}"`) + return `\uE9b4d${placeHolders.length - 1}` + }) + + .split('//')[0].trim() //remove comments + + .replace(/((number)|(string)|(boolean))\[\]/gu, 'Array<$1>') + + if(content.endsWith(',') || content.endsWith(';')){ + content = content.slice(0, -1) + } + + let spData = content.replace(/ /g, '').split(':') + + if(spData.length !== 2){ + throw "SyntaxError Found" + } + + let [property,typeData] = spData + + switch(typeData){ + case 'string': + case 'number': + case 'boolean':{ + schema.properties[property] = { + type: typeData + } + break + } + case 'Array': + case 'Array': + case 'Array':{ + const ogType = typeData.slice(6,-1) + + schema.properties[property] = { + type: 'array', + items: { + type: ogType as 'string'|'number'|'boolean' + } + } + break + } + default:{ + const types = typeData.split("|") + const strings:string[] = [] + for(const t of types){ + if(!t.startsWith('\uE9b4d')){ + throw "Unsupported Type Detected" + } + const textIndex = t.replace('\uE9b4d','') + const text = placeHolders[parseInt(textIndex)] + const textParsed = JSON.parse(text.replace(/\uE9b4a/gu, '\\"').replace(/\uE9b4b/gu, "\\'")) + strings.push(textParsed) + } + if(strings.length === 1){ + schema.properties[property] = { + type: 'string', + const: strings[0] + } + } + else{ + schema.properties[property] = { + type: 'string', + enum: strings + } + } + } + } + + schema.required.push(property) + + } + return schema +} + +export function getOpenAIJSONSchema(){ + const db = get(DataBase) + const schema = { + "name": "format", + "strict": db.strictJsonSchema, + "schema": convertInterfaceToSchema(db.jsonSchema) + } + return schema +} + +export function extractJSON(data:string, format:string){ + const extract = (data:any, format:string) => { + try { + if(data === undefined || data === null){ + return '' + } + + const fp = format.split('.') + const current = data[fp[0]] + + if(current === undefined){ + return '' + } + else if(fp.length === 1){ + return `${current ?? ''}` + } + else if(typeof current === 'object'){ + return extractJSON(current, fp.slice(1).join('.')) + } + else if(Array.isArray(current)){ + const index = parseInt(fp[1]) + return extractJSON(current[index], fp.slice(1).join('.')) + } + else{ + return `${current ?? ''}` + } + } catch (error) { + return '' + } + } + try { + format = risuChatParser(format) + data = data.trim() + if(data.startsWith('{')){ + return extract(JSON.parse(data), format) + } + } catch (error) {} + return data +} \ No newline at end of file diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 365946c5..e4722a70 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -435,6 +435,7 @@ export function setDatabase(data:Database){ data.falModel ??= 'fal-ai/flux/dev' data.falLoraScale ??= 1 data.customCSS ??= '' + data.strictJsonSchema ??= true changeLanguage(data.language) DataBase.set(data) } @@ -729,6 +730,10 @@ export interface Database{ moduleIntergration: string customCSS: string betaMobileGUI:boolean + jsonSchemaEnabled:boolean + jsonSchema:string + strictJsonSchema:boolean + extractJson:string } export interface customscript{ From f66ae59d70449ba4a7ddac65ae2f245ed0e79d75 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 11 Sep 2024 09:25:49 +0900 Subject: [PATCH 092/174] Improve beta mobile accessibility --- src/App.svelte | 2 - src/lib/Mobile/MobileBody.svelte | 31 ++--- src/lib/Mobile/MobileCharacters.svelte | 68 ++++++++- src/lib/Mobile/MobileFooter.svelte | 49 ++++++- src/lib/Mobile/MobileHeader.svelte | 8 +- src/lib/Setting/Settings.svelte | 182 +++++++++++++------------ src/lib/SideBars/CharConfig.svelte | 115 +++++++++------- src/lib/SideBars/SideChatList.svelte | 8 +- src/lib/SideBars/Sidebar.svelte | 4 +- src/lib/UI/GUI/CheckInput.svelte | 6 +- src/ts/characterCards.ts | 3 +- src/ts/characters.ts | 5 +- src/ts/gui/colorscheme.ts | 4 +- src/ts/hotkey.ts | 46 ++++++- src/ts/process/index.ts | 2 + src/ts/storage/database.ts | 10 ++ src/ts/storage/globalApi.ts | 4 +- src/ts/stores.ts | 3 +- 18 files changed, 370 insertions(+), 180 deletions(-) diff --git a/src/App.svelte b/src/App.svelte index d0e641bf..7bbcae25 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -44,8 +44,6 @@
{:else if !didFirstSetup} - {:else if $isLite} - {:else if $settingsOpen} {:else if $MobileGUI} diff --git a/src/lib/Mobile/MobileBody.svelte b/src/lib/Mobile/MobileBody.svelte index 3396fcd2..5d1fa725 100644 --- a/src/lib/Mobile/MobileBody.svelte +++ b/src/lib/Mobile/MobileBody.svelte @@ -7,38 +7,37 @@ import CharConfig from "../SideBars/CharConfig.svelte"; import { WrenchIcon } from "lucide-svelte"; import { language } from "src/lang"; - import SideChatList from "../SideBars/SideChatList.svelte"; - import DevTool from "../SideBars/DevTool.svelte"; - let sbt = 0 + import SideChatList from "../SideBars/SideChatList.svelte"; + import DevTool from "../SideBars/DevTool.svelte"; -{#if $MobileSideBar} +{#if $MobileSideBar > 0}
- - -
{/if} -
- {#if $MobileSideBar} +
+ {#if $MobileSideBar > 0}
- {#if sbt === 0} + {#if $MobileSideBar === 1} - {:else if sbt === 1} + {:else if $MobileSideBar === 2} - {:else if sbt === 2} + {:else if $MobileSideBar === 3} {/if}
@@ -48,7 +47,7 @@ {:else if $MobileGUIStack === 1} - {:else if $MobileGUIStack === 3} + {:else if $MobileGUIStack === 2} {/if}
\ No newline at end of file diff --git a/src/lib/Mobile/MobileCharacters.svelte b/src/lib/Mobile/MobileCharacters.svelte index 7b0c2234..ee05794a 100644 --- a/src/lib/Mobile/MobileCharacters.svelte +++ b/src/lib/Mobile/MobileCharacters.svelte @@ -1,27 +1,85 @@
- {#each $DataBase.characters as char, i} + {#each sortChar($DataBase.characters) as char, i} {#if char.name.toLocaleLowerCase().includes($MobileSearch.toLocaleLowerCase())} {/if} diff --git a/src/lib/Mobile/MobileFooter.svelte b/src/lib/Mobile/MobileFooter.svelte index 744af049..3ec34c57 100644 --- a/src/lib/Mobile/MobileFooter.svelte +++ b/src/lib/Mobile/MobileFooter.svelte @@ -1,8 +1,8 @@ {#if $selectedCharID === -1} @@ -20,12 +20,53 @@ {language.character} -
+{/if} + +{#if $selectedCharID !== -1 && $MobileSideBar === 2} +
+ + + + + + +
{/if} \ No newline at end of file diff --git a/src/lib/Mobile/MobileHeader.svelte b/src/lib/Mobile/MobileHeader.svelte index 7baedd96..6a4c33f3 100644 --- a/src/lib/Mobile/MobileHeader.svelte +++ b/src/lib/Mobile/MobileHeader.svelte @@ -5,9 +5,9 @@
- {#if $selectedCharID !== -1 && $MobileSideBar} + {#if $selectedCharID !== -1 && $MobileSideBar > 0} @@ -21,12 +21,12 @@ {$CurrentCharacter.name}
- {:else if $MobileGUIStack === 3 && $SettingsMenuIndex > -1} + {:else if $MobileGUIStack === 2 && $SettingsMenuIndex > -1} - - - +
+ + {#if !$isLite} + + + + + {/if} - - - + {#if !$isLite} + + + + {/if} - - + {#if !$isLite} + + + {/if} {#if window.innerWidth < 700 && !$MobileGUI} - - {#if currentChar.type === 'character'} - - {/if} -
{/if} -{#if subMenu === 0} +{#if $CharConfigSubMenu === 0} {#if currentChar.type !== 'group' && licensed !== 'private'} {language.description} @@ -283,41 +286,44 @@ highlight placeholder={getAuthorNoteDefaultText()} /> - {tokens.localNote} {language.tokens} -
- -
+ {tokens.localNote} {language.tokens} - {#each parseKeyValue($DataBase.customPromptTemplateToggle) as toggle} -
- { - $DataBase.globalChatVariables[`toggle_${toggle[0]}`] = $DataBase.globalChatVariables[`toggle_${toggle[0]}`] === '1' ? '0' : '1' - }} /> + {#if !$MobileGUI} +
+
- {/each} - - {#if $DataBase.supaModelType !== 'none' || $DataBase.hanuraiEnable} - {#if $DataBase.hanuraiEnable} + {#each parseKeyValue($DataBase.customPromptTemplateToggle) as toggle}
- + { + $DataBase.globalChatVariables[`toggle_${toggle[0]}`] = $DataBase.globalChatVariables[`toggle_${toggle[0]}`] === '1' ? '0' : '1' + }} />
- {:else if $DataBase.hypaMemory} + {/each} + + + {#if $DataBase.supaModelType !== 'none' || $DataBase.hanuraiEnable} + {#if $DataBase.hanuraiEnable} +
+ +
+ {:else if $DataBase.hypaMemory} +
+ +
+ {:else} +
+ +
+ {/if} + {/if} + + {#if currentChar.type === 'group'}
- -
- {:else} -
- +
{/if} {/if} - - {#if currentChar.type === 'group'} -
- -
- {/if} {#if licensed === 'private'}
{/if} -
+
{#if $MobileSideBar > 0}
{#if $MobileSideBar === 1} diff --git a/src/lib/Mobile/MobileCharacters.svelte b/src/lib/Mobile/MobileCharacters.svelte index ee05794a..ced66a86 100644 --- a/src/lib/Mobile/MobileCharacters.svelte +++ b/src/lib/Mobile/MobileCharacters.svelte @@ -1,20 +1,9 @@ -
+
{#each sortChar($DataBase.characters) as char, i} {#if char.name.toLocaleLowerCase().includes($MobileSearch.toLocaleLowerCase())} {/if} {/each} -
\ No newline at end of file +
+ + \ No newline at end of file diff --git a/src/lib/Others/AlertComp.svelte b/src/lib/Others/AlertComp.svelte index 3274d1eb..12c2af51 100644 --- a/src/lib/Others/AlertComp.svelte +++ b/src/lib/Others/AlertComp.svelte @@ -305,7 +305,7 @@ {:else if $alertStore.type === 'addchar'}
-
-
-
-
- + + {/if} diff --git a/src/ts/model/names.ts b/src/ts/model/names.ts index 41b19540..c0d1f72c 100644 --- a/src/ts/model/names.ts +++ b/src/ts/model/names.ts @@ -105,6 +105,10 @@ export function getModelName(name:string){ return 'GPT-4o ChatGPT' case 'gpt4om': return 'GPT-4o Mini' + case 'gpt4o1-preview': + return 'o1 Preview' + case 'gpt4o1-mini': + return 'o1 Mini' case 'gpt4om-2024-07-18': return 'GPT-4o Mini (2024-07-18)' case 'gemini-1.5-pro-latest': diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 0ada4266..7c890d97 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -236,6 +236,8 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' case 'gpt4om-2024-07-18': case 'gpt4o-2024-08-06': case 'gpt4o-chatgpt': + case 'gpt4o1-preview': + case 'gpt4o1-mini': case 'reverse_proxy':{ let formatedChat:OpenAIChatExtra[] = [] for(let i=0;i${formatedChat[i].content}` + formatedChat[i].role = 'user' + } + } + } + for(let i=0;i Date: Fri, 13 Sep 2024 08:16:25 +0900 Subject: [PATCH 100/174] Update version to 131.0.2 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 8e3c912e..0caf3e0d 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "131.0.1" + "version": "131.0.2" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 14c0b4e6..7feda433 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "131.0.1" +export let appVer = "131.0.2" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index 6f0fd217..9667d4ff 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"131.0.1"} \ No newline at end of file +{"version":"131.0.2"} \ No newline at end of file From 567a6e3dea8a2886d3a7314ff46103c9528d433c Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 13 Sep 2024 08:25:34 +0900 Subject: [PATCH 101/174] Fix max tokens --- src/ts/process/request.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 7c890d97..f2e5815b 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -505,6 +505,11 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' }) + if(aiModel.startsWith('gpt4o1')){ + body.max_completion_tokens = body.max_tokens + delete body.max_tokens + } + if(db.generationSeed > 0){ body.seed = db.generationSeed } From a9ddf660018f3961bcf93d9ea5338a89263904b6 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 13 Sep 2024 08:54:29 +0900 Subject: [PATCH 102/174] Add Jamba Support --- src/lib/Setting/Pages/BotSettings.svelte | 4 ++++ src/lib/UI/ModelList.svelte | 4 ++++ src/ts/process/request.ts | 6 ++++++ src/ts/storage/database.ts | 1 + 4 files changed, 15 insertions(+) diff --git a/src/lib/Setting/Pages/BotSettings.svelte b/src/lib/Setting/Pages/BotSettings.svelte index f0ab8bbf..2626bbf3 100644 --- a/src/lib/Setting/Pages/BotSettings.svelte +++ b/src/lib/Setting/Pages/BotSettings.svelte @@ -96,6 +96,10 @@ {/if} {/if} + {#if $DataBase.aiModel.startsWith('jamba') || $DataBase.subModel.startsWith('jamba')} + AI21 {language.apiKey} + + {/if} {#if $DataBase.aiModel.startsWith('novellist') || $DataBase.subModel.startsWith('novellist')} NovelList {language.apiKey} diff --git a/src/lib/UI/ModelList.svelte b/src/lib/UI/ModelList.svelte index 6d9c31c8..005f8337 100644 --- a/src/lib/UI/ModelList.svelte +++ b/src/lib/UI/ModelList.svelte @@ -137,6 +137,10 @@ + + + + {#await getHordeModels()} diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index f2e5815b..44513621 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -238,6 +238,8 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' case 'gpt4o-chatgpt': case 'gpt4o1-preview': case 'gpt4o1-mini': + case 'jamba-1.5-large': + case 'jamba-1.5-medium': case 'reverse_proxy':{ let formatedChat:OpenAIChatExtra[] = [] for(let i=0;i Date: Sat, 14 Sep 2024 02:30:39 +0900 Subject: [PATCH 103/174] fix recursive scanning not working sometimes --- src/ts/process/lorebook.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/ts/process/lorebook.ts b/src/ts/process/lorebook.ts index 0815e77a..e4a2b207 100644 --- a/src/ts/process/lorebook.ts +++ b/src/ts/process/lorebook.ts @@ -229,12 +229,16 @@ export async function loadLoreBookV3Prompt(){ searchDepth:number, regex:boolean fullWordMatching:boolean + recursiveAdditionalPrompt:string }) => { const sliced = messages.slice(messages.length - arg.searchDepth,messages.length) arg.keys = arg.keys.map(key => key.trim()).filter(key => key.length > 0) let mText = sliced.map((msg) => { return msg.data }).join('||') + if(arg.recursiveAdditionalPrompt){ + mText += arg.recursiveAdditionalPrompt + } if(arg.regex){ for(const regexString of arg.keys){ if(!regexString.startsWith('/')){ @@ -289,6 +293,7 @@ export async function loadLoreBookV3Prompt(){ }[] = [] let activatedIndexes:number[] = [] let disabledUIPrompts:string[] = [] + let matchTimes = 0 while(matching){ matching = false for(let i=0;i Date: Sat, 14 Sep 2024 02:31:12 +0900 Subject: [PATCH 104/174] Remove cipherChat.ts file and related functions --- src/ts/process/cipherChat.ts | 91 ------------------------------------ 1 file changed, 91 deletions(-) delete mode 100644 src/ts/process/cipherChat.ts diff --git a/src/ts/process/cipherChat.ts b/src/ts/process/cipherChat.ts deleted file mode 100644 index ad37eaf9..00000000 --- a/src/ts/process/cipherChat.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type { OpenAIChat } from "."; - - -let lastShift = 0 - -const cipher:'caesar'|'base64' = 'caesar' - -export function cipherChat(chat: OpenAIChat[]): OpenAIChat[] { - - const shift = Math.floor(Math.random() * 26) + 1 - lastShift = shift - - for(let i = 0; i < chat.length; i++){ - chat[i].content = ciphers[cipher].encode(chat[i].content, shift) - } - - chat.unshift({ - content: ciphers[cipher].prompt.replace("${shift}", shift.toString()), - role: 'system' - }) - return chat - -} - - -export function decipherChat(chat: string): string { - return ciphers[cipher].decode(chat, lastShift) -} - -//Caesar Chiper -const caesarCipher = (text: string, shift: number) => { - return text - .split('') - .map(char => { - const code = char.charCodeAt(0) - if ((code >= 65) && (code <= 90)) { - return String.fromCharCode(((code - 65 + shift) % 26) + 65) - } else if ((code >= 97) && (code <= 122)) { - return String.fromCharCode(((code - 97 + shift) % 26) + 97) - } else { - return char - } - }) - .join('') -} - -const caesarDecipher = (text: string, shift: number) => { - return text - .split('') - .map(char => { - const code = char.charCodeAt(0) - if ((code >= 65) && (code <= 90)) { - const shifted = (code - 65 - shift) - if(shifted < 0){ - return String.fromCharCode(((code - 65 - shift + 26) % 26) + 65) - } - return String.fromCharCode(((code - 65 - shift) % 26) + 65) - } else if ((code >= 97) && (code <= 122)) { - const shifted = (code - 97 - shift) - if(shifted < 0){ - return String.fromCharCode(((code - 97 - shift + 26) % 26) + 97) - } - return String.fromCharCode(((code - 97 - shift) % 26) + 97) - } else { - return char - } - }) - .join('') -} - -const base64Encode = (text: string) => { - return Buffer.from(text).toString('base64') -} - -const base64Decode = (text: string) => { - return Buffer.from(text, 'base64').toString('ascii') -} - - -const ciphers = { - caesar: { - encode: caesarCipher, - decode: caesarDecipher, - prompt: "You are an expert on The Caesar Cipher. We will communicate in Caesar Cipher. Do not be a translator. We are using shift ${shift}" - }, - base64: { - encode: base64Encode, - decode: base64Decode, - prompt: "You are an expert on The Base64 Cipher. We will communicate in Base64. Do not be a translator." - } -} \ No newline at end of file From 47226662ecff67406ad54b737fce48a30370e488 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 14 Sep 2024 02:33:47 +0900 Subject: [PATCH 105/174] Remove Cipher --- src/ts/process/index.ts | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index e77fe4dd..8d8be93d 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -17,7 +17,6 @@ import { groupOrder } from "./group"; import { runTrigger } from "./triggers"; import { HypaProcesser } from "./memory/hypamemory"; import { additionalInformations } from "./embedding/addinfo"; -import { cipherChat, decipherChat } from "./cipherChat"; import { getInlayImage, supportsInlayImage } from "./files/image"; import { getGenerationModelString } from "./models/modelString"; import { connectionOpen, peerRevertChat, peerSafeCheck, peerSync } from "../sync/multiuser"; @@ -1049,10 +1048,6 @@ export async function sendChat(chatProcessIndex = -1,arg:{ return v }) - if(db.cipherChat){ - formated = cipherChat(formated) - } - if(currentChar.depth_prompt && currentChar.depth_prompt.prompt && currentChar.depth_prompt.prompt.length > 0){ //depth_prompt @@ -1167,9 +1162,6 @@ export async function sendChat(chatProcessIndex = -1,arg:{ if(!result){ result = '' } - if(db.cipherChat){ - result = decipherChat(result) - } if(db.removeIncompleteResponse){ result = trimUntilPunctuation(result) } @@ -1220,9 +1212,6 @@ export async function sendChat(chatProcessIndex = -1,arg:{ for(let i=0;i Date: Sat, 14 Sep 2024 02:40:26 +0900 Subject: [PATCH 106/174] Fix thanks page --- src/lib/Setting/Pages/ThanksPage.svelte | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/lib/Setting/Pages/ThanksPage.svelte b/src/lib/Setting/Pages/ThanksPage.svelte index 94a91e6b..07264880 100644 --- a/src/lib/Setting/Pages/ThanksPage.svelte +++ b/src/lib/Setting/Pages/ThanksPage.svelte @@ -21,7 +21,7 @@ const supp = await fetch("https://sv.risuai.xyz/patreon/list") const list = await supp.json() as supporterL[] - const dummy:supporters = { + const thanks:supporters = { //random names I: list.filter((v) => v.amount < 5).map((v) => v.name), II: list.filter((v) => v.amount >= 5 && v.amount < 10).map((v) => v.name), @@ -29,9 +29,10 @@ IV: list.filter((v) => v.amount >= 20 && v.amount < 50).map((v) => v.name), V: list.filter((v) => v.amount >= 50).map((v) => v.name), } - return dummy + return thanks } +

{language.supporterThanks}

{language.supporterThanksDesc} @@ -56,7 +57,7 @@ {:then supporter}

Supporter V

-
+
{#each supporter.V as support}
@@ -66,7 +67,7 @@ {/each}

Supporter IV

-
+
{#each supporter.IV as support}
@@ -76,7 +77,7 @@ {/each}

Supporter III

-
+
{#each supporter.III as support}
@@ -87,7 +88,7 @@ {/each}

Supporter II

-
+
{#each supporter.II as support}
@@ -98,7 +99,7 @@ {/each}

Supporter I

-
+
{#each supporter.I as support}
From b334ef9fffb751ac1da4a53627ea41554fbf124d Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 14 Sep 2024 02:44:12 +0900 Subject: [PATCH 107/174] Fix swipe to not apply at specific elements --- src/ts/hotkey.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ts/hotkey.ts b/src/ts/hotkey.ts index 724855f8..a39f8de3 100644 --- a/src/ts/hotkey.ts +++ b/src/ts/hotkey.ts @@ -149,6 +149,10 @@ export function initMobileGesture(){ document.addEventListener('touchstart', (ev) => { for(const touch of ev.changedTouches){ + const ele = touch.target as HTMLElement + if(ele.tagName === 'BUTTON' || ele.tagName === 'INPUT' || ele.tagName === 'SELECT' || ele.tagName === 'TEXTAREA'){ + return + } pressingPointers.set(touch.identifier, {x: touch.clientX, y: touch.clientY}) } }, { From 97812c969cb835811cc0b2b81e48a7f30e0b3c0d Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 15 Sep 2024 00:36:43 +0900 Subject: [PATCH 108/174] Update version to 131.1.0 in tauri.conf.json, database.ts, and version.json --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 0caf3e0d..74ffdc8c 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "131.0.2" + "version": "131.1.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index c667953d..fe1064f5 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "131.0.2" +export let appVer = "131.1.0" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index 9667d4ff..5bd90bd4 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"131.0.2"} \ No newline at end of file +{"version":"131.1.0"} \ No newline at end of file From c8f516b5216c29c6e931ebfff0110fdaac26b957 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 15 Sep 2024 18:01:11 +0900 Subject: [PATCH 109/174] Add bias import | export --- src/lib/Setting/Pages/BotSettings.svelte | 25 ++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/lib/Setting/Pages/BotSettings.svelte b/src/lib/Setting/Pages/BotSettings.svelte index 2626bbf3..ac569e72 100644 --- a/src/lib/Setting/Pages/BotSettings.svelte +++ b/src/lib/Setting/Pages/BotSettings.svelte @@ -4,13 +4,11 @@ import Help from "src/lib/Others/Help.svelte"; import { DataBase } from "src/ts/storage/database"; import { customProviderStore } from "src/ts/plugins/plugins"; - import { getModelMaxContext, isTauri } from "src/ts/storage/globalApi"; + import { downloadFile, getModelMaxContext, isTauri } from "src/ts/storage/globalApi"; import { tokenizeAccurate, tokenizerList } from "src/ts/tokenizer"; import ModelList from "src/lib/UI/ModelList.svelte"; import DropList from "src/lib/SideBars/DropList.svelte"; - import { PlusIcon, TrashIcon } from "lucide-svelte"; - import { onDestroy } from "svelte"; - import { setRecommended } from "src/ts/process/templates/getRecomended"; + import { PlusIcon, TrashIcon, FolderUpIcon, DownloadIcon } from "lucide-svelte"; import TextInput from "src/lib/UI/GUI/TextInput.svelte"; import NumberInput from "src/lib/UI/GUI/NumberInput.svelte"; import SliderInput from "src/lib/UI/GUI/SliderInput.svelte"; @@ -24,8 +22,10 @@ import Arcodion from "src/lib/UI/Arcodion.svelte"; import OpenrouterSettings from "./OpenrouterSettings.svelte"; import ChatFormatSettings from "./ChatFormatSettings.svelte"; - import PromptSettings from "./PromptSettings.svelte"; - import { openPresetList } from "src/ts/stores"; + import PromptSettings from "./PromptSettings.svelte"; + import { openPresetList } from "src/ts/stores"; + import { selectSingleFile } from "src/ts/util"; + import { isArray } from "lodash"; let tokens = { mainPrompt: 0, @@ -509,6 +509,19 @@ {/each} +
+ + +
{#if $DataBase.aiModel === 'reverse_proxy'} From e8c482e5e62384984f9926829d50e4ac55c7fd8a Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 15 Sep 2024 18:01:36 +0900 Subject: [PATCH 110/174] Update version to 131.2.0 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 74ffdc8c..38932306 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "131.1.0" + "version": "131.2.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index fe1064f5..3f571e13 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -1,6 +1,6 @@ export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = "131.1.0" +export let appVer = "131.2.0" export let webAppSubVer = '' import { get, writable } from 'svelte/store'; diff --git a/version.json b/version.json index 5bd90bd4..03999b23 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"131.1.0"} \ No newline at end of file +{"version":"131.2.0"} \ No newline at end of file From 19b3e176197c31d056672da0c5f2415600bedf0b Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 15 Sep 2024 18:18:44 +0900 Subject: [PATCH 111/174] Add bias escapes --- src/ts/process/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index 8d8be93d..da56a4a1 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -800,7 +800,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{ } let biases:[string,number][] = db.bias.concat(currentChar.bias).map((v) => { - return [risuChatParser(v[0].replaceAll("\\n","\n"), {chara: currentChar}),v[1]] + return [risuChatParser(v[0].replaceAll("\\n","\n").replaceAll("\\r","\r").replaceAll("\\\\","\\"), {chara: currentChar}),v[1]] }) let memories:OpenAIChat[] = [] From 12f9c8636686307591c9d10886446d76c076f35b Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 16 Sep 2024 03:17:53 +0900 Subject: [PATCH 112/174] Remove trigger code mode --- src/lib/SideBars/CharConfig.svelte | 19 ------------------- src/ts/process/triggers.ts | 13 ------------- 2 files changed, 32 deletions(-) diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte index 4c15d818..1704d5e3 100644 --- a/src/lib/SideBars/CharConfig.svelte +++ b/src/lib/SideBars/CharConfig.svelte @@ -656,25 +656,6 @@ } } }}>{language.blockMode} - - -
- {#if currentModule?.trigger?.[0]?.effect?.[0]?.type === 'triggerlua'} - - - {:else} - - - {/if} +
diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte index 1704d5e3..627b4ca1 100644 --- a/src/lib/SideBars/CharConfig.svelte +++ b/src/lib/SideBars/CharConfig.svelte @@ -637,67 +637,8 @@
{language.triggerScript} -
- - -
- {#if currentChar.data?.triggerscript?.[0]?.effect?.[0]?.type === 'triggercode'} - - {:else if currentChar.data?.triggerscript?.[0]?.effect?.[0]?.type === 'triggerlua'} - - - {:else} - - {/if} - + + {#if currentChar.data.virtualscript || $DataBase.showUnrecommended} {language.charjs} diff --git a/src/lib/SideBars/Scripts/TriggerList.svelte b/src/lib/SideBars/Scripts/TriggerList.svelte index 9c4c63b7..b546fddd 100644 --- a/src/lib/SideBars/Scripts/TriggerList.svelte +++ b/src/lib/SideBars/Scripts/TriggerList.svelte @@ -6,6 +6,13 @@ import Sortable from "sortablejs"; import { sleep, sortableOptions } from "src/ts/util"; import { onDestroy, onMount } from "svelte"; + import { language } from "src/lang"; + import { alertConfirm } from "src/ts/alert"; + import TextAreaInput from "src/lib/UI/GUI/TextAreaInput.svelte"; + import Button from "src/lib/UI/GUI/Button.svelte"; + import { openURL } from "src/ts/storage/globalApi"; + import { hubURL } from "src/ts/characterCards"; + import { PlusIcon } from "lucide-svelte"; let stb: Sortable = null let ele: HTMLDivElement let sorted = 0 @@ -60,17 +67,70 @@ -
- {#if value.length === 0} -
No Scripts
- {/if} - {#key sorted} - {#each value as triggerscript, i} - { - let triggerscript = value - triggerscript.splice(i, 1) - value = triggerscript - }}/> - {/each} - {/key} -
\ No newline at end of file +
+ + +
+{#if value?.[0]?.effect?.[0]?.type === 'triggerlua'} + + +{:else} +
+ {#if value.length === 0} +
No Scripts
+ {/if} + {#key sorted} + {#each value as triggerscript, i} + { + let triggerscript = value + triggerscript.splice(i, 1) + value = triggerscript + }}/> + {/each} + {/key} +
+ +{/if} \ No newline at end of file From 321c21cea9b5d452f221dfdac136e57f9956319e Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 18 Sep 2024 22:25:09 +0900 Subject: [PATCH 116/174] Improve account and Add priority --- src/lang/en.ts | 1 + src/ts/process/lorebook.ts | 19 +++++++++++++++---- src/ts/storage/accountStorage.ts | 12 ++++++++++-- src/ts/storage/globalApi.ts | 6 +++--- 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/lang/en.ts b/src/lang/en.ts index 6f327568..e177cda7 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -734,4 +734,5 @@ export const languageEnglish = { enableJsonSchema: "Enable Schema", strictJsonSchema: "Strict Schema", extractJson: "Extract JSON", + reloadSession: "Newer version of save data is found. reloading the session...", } \ No newline at end of file diff --git a/src/ts/process/lorebook.ts b/src/ts/process/lorebook.ts index e4a2b207..f2e8ace9 100644 --- a/src/ts/process/lorebook.ts +++ b/src/ts/process/lorebook.ts @@ -288,8 +288,9 @@ export async function loadLoreBookV3Prompt(){ pos:string, prompt:string role:'system'|'user'|'assistant' - priority:number + order:number tokens:number + priority:number }[] = [] let activatedIndexes:number[] = [] let disabledUIPrompts:string[] = [] @@ -307,6 +308,7 @@ export async function loadLoreBookV3Prompt(){ let pos = '' let depth = 0 let scanDepth = loreDepth + let order = fullLore[i].insertorder let priority = fullLore[i].insertorder let forceState:string = 'none' let role:'system'|'user'|'assistant' = 'system' @@ -434,6 +436,10 @@ export async function loadLoreBookV3Prompt(){ activated = false } } + case 'priority':{ + priority = parseInt(arg[0]) + return + } default:{ return false } @@ -486,8 +492,9 @@ export async function loadLoreBookV3Prompt(){ pos: pos, prompt: content, role: role, - priority: priority, - tokens: await tokenize(content) + order: order, + tokens: await tokenize(content), + priority: priority }) activatedIndexes.push(i) if(recursiveScanning){ @@ -512,8 +519,12 @@ export async function loadLoreBookV3Prompt(){ return false }) + const activesResorted = activesFiltered.sort((a,b) => { + return b.order - a.order + }) + return { - actives: activesFiltered.reverse() + actives: activesResorted.reverse() } } diff --git a/src/ts/storage/accountStorage.ts b/src/ts/storage/accountStorage.ts index 41d1fd00..5ac66973 100644 --- a/src/ts/storage/accountStorage.ts +++ b/src/ts/storage/accountStorage.ts @@ -2,12 +2,14 @@ import { get, writable } from "svelte/store" import { DataBase } from "./database" import { hubURL } from "../characterCards" import localforage from "localforage" -import { alertLogin, alertStore } from "../alert" +import { alertError, alertLogin, alertStore, alertWait } from "../alert" import { forageStorage, getUnpargeables, replaceDbResources } from "./globalApi" import { encodeRisuSave } from "./risuSave" import { v4 } from "uuid" +import { language } from "src/lang" export const AccountWarning = writable('') +const risuSession = Date.now().toFixed(0) let seenWarnings:string[] = [] @@ -26,7 +28,8 @@ export class AccountStorage{ 'content-type': 'application/json', 'x-risu-key': key, 'x-risu-auth': this.auth, - 'X-Format': 'nocheck' + 'X-Format': 'nocheck', + 'x-risu-session': risuSession } }) if(da.headers.get('Content-Type') === 'application/json'){ @@ -37,6 +40,11 @@ export class AccountStorage{ AccountWarning.set(json.warning) } } + if(json?.reloadSession){ + alertWait(language.reloadSession) + location.reload() + return + } } if(da.status === 304){ diff --git a/src/ts/storage/globalApi.ts b/src/ts/storage/globalApi.ts index 2b3baa51..eb86236e 100644 --- a/src/ts/storage/globalApi.ts +++ b/src/ts/storage/globalApi.ts @@ -12,7 +12,7 @@ import { checkRisuUpdate } from "../update"; import { MobileGUI, botMakerMode, selectedCharID } from "../stores"; import { Body, ResponseType, fetch as TauriFetch } from "@tauri-apps/api/http"; import { loadPlugins } from "../plugins/plugins"; -import { alertConfirm, alertError, alertNormal, alertNormalWait, alertSelect, alertTOS } from "../alert"; +import { alertConfirm, alertError, alertNormal, alertNormalWait, alertSelect, alertTOS, alertWait } from "../alert"; import { checkDriverInit, syncDrive } from "../drive/drive"; import { hasher } from "../parser"; import { characterURLImport, hubURL } from "../characterCards"; @@ -299,8 +299,8 @@ export async function saveDb(){ } if(!gotChannel){ gotChannel = true - await alertNormalWait(language.activeTabChange) - gotChannel = false + alertWait(language.activeTabChange) + location.reload() } } } From 32d6c0213018b036eeac09131f3c29e50106fb83 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 18 Sep 2024 22:30:37 +0900 Subject: [PATCH 117/174] fix chara meta replacing ccv3 --- src/ts/characterCards.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/characterCards.ts b/src/ts/characterCards.ts index f09e8ae4..3b8a45b7 100644 --- a/src/ts/characterCards.ts +++ b/src/ts/characterCards.ts @@ -156,7 +156,7 @@ async function importCharacterProcess(f:{ return } - if(!readedChara){ + if(readedCCv3){ readedChara = readedCCv3 } From 6ad841e931cc1c6fccff4198f66d7cf08004d7a1 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 18 Sep 2024 22:51:22 +0900 Subject: [PATCH 118/174] Fix trigger updating --- src/lib/ChatScreens/Chat.svelte | 53 +++++++++++++++++++++------------ src/ts/process/triggers.ts | 3 +- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/src/lib/ChatScreens/Chat.svelte b/src/lib/ChatScreens/Chat.svelte index 72d8da0b..4f6f41b0 100644 --- a/src/lib/ChatScreens/Chat.svelte +++ b/src/lib/ChatScreens/Chat.svelte @@ -8,14 +8,15 @@ import { CurrentCharacter, CurrentChat, CurrentVariablePointer, HideIconStore, ReloadGUIPointer } from "../../ts/stores"; import { translateHTML } from "../../ts/translator/translator"; import { risuChatParser } from "src/ts/process/scripts"; - import { get } from "svelte/store"; + import { get, type Unsubscriber } from "svelte/store"; import { isEqual } from "lodash"; import { sayTTS } from "src/ts/process/tts"; import { getModelShortName } from "src/ts/model/names"; import { capitalize } from "src/ts/util"; - import { longpress } from "src/ts/gui/longtouch"; - import { ColorSchemeTypeStore } from "src/ts/gui/colorscheme"; - import { ConnectionOpenStore } from "src/ts/sync/multiuser"; + import { longpress } from "src/ts/gui/longtouch"; + import { ColorSchemeTypeStore } from "src/ts/gui/colorscheme"; + import { ConnectionOpenStore } from "src/ts/sync/multiuser"; + import { onDestroy, onMount } from "svelte"; export let message = '' export let name = '' export let largePortrait = false @@ -72,7 +73,7 @@ $CurrentChat.message = msg } - function displaya(message:string, chatPointer?:any){ + function displaya(message:string){ msgDisplay = risuChatParser(message, {chara: name, chatID: idx, rmVar: true, visualize: true}) } @@ -91,23 +92,22 @@ $: blankMessage = (message === '{{none}}' || message === '{{blank}}' || message === '') && idx === -1 const markParsing = async (data: string, charArg?: string | simpleCharacterArgument, mode?: "normal" | "back", chatID?: number, translateText?:boolean, tries?:number) => { try { - if((!isEqual(lastCharArg, charArg)) || (chatID !== lastChatId)){ - lastParsed = '' - lastCharArg = charArg - lastChatId = chatID - translateText = false - try { - translated = get(DataBase).autoTranslate - if(translated){ - translateText = true - } - } catch (error) {} - } + if((!isEqual(lastCharArg, charArg)) || (chatID !== lastChatId)){ + lastParsed = '' + lastCharArg = charArg + lastChatId = chatID + translateText = false + try { + translated = get(DataBase).autoTranslate + if(translated){ + translateText = true + } + } catch (error) {} + } if(translateText){ if(!$DataBase.legacyTranslation){ const marked = await ParseMarkdown(data, charArg, 'pretranslate', chatID) translating = true - console.log(marked) const translated = await postTranslationParse(await translateHTML(marked, false, charArg, chatID)) translating = false lastParsed = translated @@ -141,7 +141,22 @@ } } - $: displaya(message, $CurrentVariablePointer) + $: displaya(message) + + const unsubscribers:Unsubscriber[] = [] + + onMount(()=>{ + unsubscribers.push(CurrentVariablePointer.subscribe((v) => { + displaya(message) + })) + unsubscribers.push(ReloadGUIPointer.subscribe((v) => { + displaya(message) + })) + }) + + onDestroy(()=>{ + unsubscribers.forEach(u => u()) + })
diff --git a/src/ts/process/triggers.ts b/src/ts/process/triggers.ts index 19a68cf5..e959e758 100644 --- a/src/ts/process/triggers.ts +++ b/src/ts/process/triggers.ts @@ -3,7 +3,7 @@ import { DataBase, type Chat, type character } from "../storage/database"; import { tokenize } from "../tokenizer"; import { getModuleTriggers } from "./modules"; import { get } from "svelte/store"; -import { CurrentCharacter, CurrentChat, selectedCharID } from "../stores"; +import { CurrentCharacter, CurrentChat, ReloadGUIPointer, selectedCharID } from "../stores"; import { processMultiCommand } from "./command"; import { parseKeyValue } from "../util"; import { alertError, alertInput, alertNormal, alertSelect } from "../alert"; @@ -531,6 +531,7 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{ if(varChanged){ const currentChat = get(CurrentChat) currentChat.scriptstate = chat.scriptstate + ReloadGUIPointer.set(get(ReloadGUIPointer) + 1) } return {additonalSysPrompt, chat, tokens:caculatedTokens, stopSending, sendAIprompt} From 85609e890e313ade1b1dac73a94f0166fdd18d8d Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 18 Sep 2024 23:25:02 +0900 Subject: [PATCH 119/174] Change first message to chat dependent --- src/lib/ChatScreens/BackgroundDom.svelte | 16 +++++++--------- src/lib/ChatScreens/Chat.svelte | 17 ++++++----------- src/lib/ChatScreens/DefaultChatScreen.svelte | 20 +++++++++++--------- src/lib/ChatScreens/Suggestion.svelte | 9 --------- src/lib/Others/ChatList.svelte | 5 +++-- src/lib/SideBars/CharConfig.svelte | 6 +++--- src/lib/SideBars/SideChatList.svelte | 8 ++++++-- src/ts/characters.ts | 6 +++++- src/ts/parser.ts | 7 ++++--- src/ts/process/index.ts | 2 +- src/ts/process/lorebook.ts | 2 +- src/ts/process/lua.ts | 2 +- src/ts/process/scripts.ts | 2 +- src/ts/storage/database.ts | 1 + src/ts/stores.ts | 8 -------- 15 files changed, 50 insertions(+), 61 deletions(-) diff --git a/src/lib/ChatScreens/BackgroundDom.svelte b/src/lib/ChatScreens/BackgroundDom.svelte index 11de4f56..7e18a48e 100644 --- a/src/lib/ChatScreens/BackgroundDom.svelte +++ b/src/lib/ChatScreens/BackgroundDom.svelte @@ -1,7 +1,7 @@ @@ -60,8 +112,32 @@ OUT: {#if value.ableFlag} - FLAG: - + + + Normal Flag +
+ {#each flags as flag, i} + + {/each} +
+ + Order Flag + { + changeOrder(parseInt(e.currentTarget.value)) + }} /> + +
{/if}
{ diff --git a/src/lib/UI/GUI/NumberInput.svelte b/src/lib/UI/GUI/NumberInput.svelte index 59629803..4e83a944 100644 --- a/src/lib/UI/GUI/NumberInput.svelte +++ b/src/lib/UI/GUI/NumberInput.svelte @@ -24,6 +24,7 @@ /> From e676623a4ee809a618acbbb424b7f8242851533d Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 23 Sep 2024 23:53:03 +0900 Subject: [PATCH 133/174] Add autocomplete --- src/lib/UI/GUI/TextAreaInput.svelte | 121 +++++++++++++++++++++++++++- src/styles.css | 4 + src/ts/gui/highlight.ts | 15 +++- src/ts/storage/globalApi.ts | 1 + 4 files changed, 135 insertions(+), 6 deletions(-) diff --git a/src/lib/UI/GUI/TextAreaInput.svelte b/src/lib/UI/GUI/TextAreaInput.svelte index 6169d9a2..646dc77c 100644 --- a/src/lib/UI/GUI/TextAreaInput.svelte +++ b/src/lib/UI/GUI/TextAreaInput.svelte @@ -1,5 +1,5 @@
{ + hideAutoComplete() + }} > {#if !highlight || !CSS.highlights || isFirefox}