From 77849d2a9afd487fc38a9f043b479a26373ebaf1 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 22 May 2024 14:52:08 +0900 Subject: [PATCH] feat: Enable dynamic assets for processing data and replace missing asset names with the closest match --- src/lang/en.ts | 2 + src/lib/Setting/Pages/AdvancedSettings.svelte | 5 ++ src/lib/SideBars/CharConfig.svelte | 4 +- src/ts/parser.ts | 2 +- src/ts/process/scripts.ts | 23 +++++++++- src/ts/realm.ts | 46 +++++++++++++++++++ src/ts/storage/database.ts | 1 + 7 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 src/ts/realm.ts diff --git a/src/lang/en.ts b/src/lang/en.ts index d8024442..a73f7c81 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -122,6 +122,7 @@ export const languageEnglish = { triggerScript: "Trigger Script is a custom script that runs when a condition is met. it can be used to modify the chat data, run a command, change variable, and etc. the type depends when it is triggered. it can also be run by buttons, which can be used with {{button::Display::TriggerName}}, or HTML buttons with `risu-trigger=\"\"` attribute.", autoContinueChat: "If enabled, it will try to continue the chat if it doesn't ends with a punctuation. DONT USE THIS WITH LANGUAGES THAT DOESN'T USE PUNCTUATION.", combineTranslation: "If enabled, text that is one sentence but separated by HTML tags will be combined together and translated, then Modify Display script will be reapplied to the translated output.\nThis helps the translator to make the correct translation.\nIf the UI becomes weird when you enable this option, please turn off the option and report it.", + dynamicAssets: "If enabled, if the asset name is not found when processing data, it will try to find the closest asset name by using vector search and replace it with the closest asset name.", }, setup: { chooseProvider: "Choose AI Provider", @@ -590,4 +591,5 @@ export const languageEnglish = { run: "Run", noMessage: "Type something to start the chat.", combineTranslation : "Combine Translation", + dynamicAssets: "Dynamic Assets", } \ No newline at end of file diff --git a/src/lib/Setting/Pages/AdvancedSettings.svelte b/src/lib/Setting/Pages/AdvancedSettings.svelte index a2ec9915..0558d1df 100644 --- a/src/lib/Setting/Pages/AdvancedSettings.svelte +++ b/src/lib/Setting/Pages/AdvancedSettings.svelte @@ -113,6 +113,11 @@ +
+ + + +
diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte index 94586c14..d52d8836 100644 --- a/src/lib/SideBars/CharConfig.svelte +++ b/src/lib/SideBars/CharConfig.svelte @@ -30,6 +30,7 @@ import { updateInlayScreen } from "src/ts/process/inlayScreen"; import { registerOnnxModel } from "src/ts/process/transformers"; import MultiLangInput from "../UI/GUI/MultiLangInput.svelte"; + import { shareRealmCard } from "src/ts/realm"; let subMenu = 0 @@ -835,7 +836,8 @@ return } if(await alertTOS()){ - openHubUpload = true + // openHubUpload = true + shareRealmCard() } }} className="mt-2"> {#if currentChar.data.realmId} diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 2163c5dc..babb2307 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -77,7 +77,7 @@ DOMPurify.addHook("uponSanitizeAttribute", (node, data) => { }) -const assetRegex = /{{(raw|img|video|audio|bg|emotion|asset|video-img)::(.+?)}}/g +export const assetRegex = /{{(raw|img|video|audio|bg|emotion|asset|video-img)::(.+?)}}/g async function parseAdditionalAssets(data:string, char:simpleCharacterArgument|character, mode:'normal'|'back', mode2:'unset'|'pre'|'post' = 'unset'){ const db = get(DataBase) diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts index 911e1764..c43731ff 100644 --- a/src/ts/process/scripts.ts +++ b/src/ts/process/scripts.ts @@ -5,12 +5,13 @@ import { downloadFile } from "../storage/globalApi"; import { alertError, alertNormal } from "../alert"; import { language } from "src/lang"; import { selectSingleFile } from "../util"; -import { risuChatParser as risuChatParserOrg, type simpleCharacterArgument } from "../parser"; +import { assetRegex, risuChatParser as risuChatParserOrg, type simpleCharacterArgument } from "../parser"; import { autoMarkPlugin } from "../plugins/automark"; import { runCharacterJS } from "../plugins/embedscript"; import { metricaPlugin } from "../plugins/metrica"; import { OaiFixKorean } from "../plugins/fixer"; import { getModuleRegexScripts } from "./modules"; +import { HypaProcesser } from "./memory/hypamemory"; const dreg = /{{data}}/g const randomness = /\|\|\|/g @@ -211,6 +212,26 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter } } } + + if(db.dynamicAssets && (char.type === 'simple' || char.type === 'character') && char.additionalAssets && char.additionalAssets.length > 0){ + const assetNames = char.additionalAssets.map((v) => v[0]) + const processer = new HypaProcesser('MiniLM') + await processer.addText(assetNames) + const matches = data.matchAll(assetRegex) + + for(const match of matches){ + const type = match[1] + const assetName = match[2] + if(!assetNames.includes(assetName)){ + const searched = await processer.similaritySearch(assetName) + const bestMatch = searched[0] + if(bestMatch){ + data = data.replaceAll(match[0], `{{${type}::${bestMatch}}}`) + } + } + } + } + return {data, emoChanged} } diff --git a/src/ts/realm.ts b/src/ts/realm.ts new file mode 100644 index 00000000..7befd51d --- /dev/null +++ b/src/ts/realm.ts @@ -0,0 +1,46 @@ +import { get } from "svelte/store"; +import { exportSpecV2 } from "./characterCards"; +import { VirtualWriter } from "./storage/globalApi"; +import { sleep } from "./util"; +import { CurrentCharacter } from "./stores"; +import { DataBase, type character } from "./storage/database"; +import { alertStore } from "./alert"; + +let pong = false; + +window.addEventListener("message", (event) => { + if (event.origin === "https://realm.risuai.net") { + if (event.data === "pong") { + pong = true; + } + } +}); + +export async function shareRealmCard() { + const char = structuredClone(get(CurrentCharacter)) as character + const writer = new VirtualWriter() + await exportSpecV2(char, 'png', {writer: writer}) + openRealm(char.name, writer.buf.buffer) +} + +export async function openRealm(name:string,data:ArrayBuffer) { + const tk = get(DataBase)?.account?.token; + const id = get(DataBase)?.account?.id + const win = window.open(`https://realm.risuai.net/upload?token=${tk}&token_id=${id}`, "_blank"); + pong = false; + while(true){ + if(pong){ + break; + } + win.postMessage("ping", "https://realm.risuai.net") + await sleep(500); + } + alertStore.set({ + type: 'none', + msg: '' + }) + + const nameBuf = new TextEncoder().encode(name); + + win.postMessage("filedata", "https://realm.risuai.net", [nameBuf,data]); +} \ No newline at end of file diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index fddc76c3..b98bdfaa 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -655,6 +655,7 @@ export interface Database{ sideBarSize:number textAreaTextSize:number combineTranslation:boolean + dynamicAssets:boolean } export interface customscript{