From 953fc383f5985969add029ead470324bf3b9f438 Mon Sep 17 00:00:00 2001 From: enzi221 Date: Tue, 13 May 2025 14:58:16 +0900 Subject: [PATCH 1/5] feat: Open read-only access to lorebooks from Lua --- src/ts/process/lua.ts | 68 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 3 deletions(-) diff --git a/src/ts/process/lua.ts b/src/ts/process/lua.ts index f8f45283..086120a3 100644 --- a/src/ts/process/lua.ts +++ b/src/ts/process/lua.ts @@ -1,6 +1,6 @@ -import { getChatVar, hasher, setChatVar, getGlobalChatVar, type simpleCharacterArgument } from "../parser.svelte"; +import { getChatVar, hasher, setChatVar, getGlobalChatVar, type simpleCharacterArgument, risuChatParser } from "../parser.svelte"; import { LuaEngine, LuaFactory } from "wasmoon"; -import { getCurrentCharacter, getCurrentChat, getDatabase, setCurrentChat, setDatabase, type Chat, type character, type groupChat } from "../storage/database.svelte"; +import { getCurrentCharacter, getCurrentChat, getDatabase, setDatabase, type Chat, type character, type groupChat, type loreBook } from "../storage/database.svelte"; import { get } from "svelte/store"; import { ReloadGUIPointer, selectedCharID } from "../stores.svelte"; import { alertSelect, alertError, alertInput, alertNormal } from "../alert"; @@ -10,10 +10,11 @@ import { writeInlayImage } from "./files/inlays"; import type { OpenAIChat } from "./index.svelte"; import { requestChatData } from "./request"; import { v4 } from "uuid"; -import { getModuleTriggers } from "./modules"; +import { getModuleLorebooks, getModuleTriggers } from "./modules"; import { Mutex } from "../mutex"; import { tokenize } from "../tokenizer"; import { fetchNative } from "../globalApi.svelte"; +import { loadLoreBookV3Prompt } from './lorebook.svelte'; let luaFactory:LuaFactory let LuaSafeIds = new Set() @@ -484,6 +485,58 @@ export async function runLua(code:string, arg:{ return true }) + // Lore books + luaEngine.global.set('getLoreBookMain', (id:string, search: string) => { + if (char.type !== 'character') { + return + } + + const loreBooks = [...char.chats[char.chatPage]?.localLore ?? [], ...char.globalLore, ...getModuleLorebooks()] + const found = loreBooks.find((b) => b.comment === search) + + return found ? JSON.stringify({ ...found, content: risuChatParser(found.content, { chara: char }) } satisfies loreBook) : false + }) + + luaEngine.global.set('loadLoreBooksMain', async (id:string, usedContext:number) => { + if(!LuaLowLevelIds.has(id)){ + return + } + + if (char.type !== 'character') { + return + } + + const db = getDatabase() + const fullLoreBooks = (await loadLoreBookV3Prompt()).actives + const maxContext = db.maxContext - usedContext + if (maxContext < 0) { + return + } + + let totalTokens = 0 + const loreBooks = [] + + for (const book of fullLoreBooks) { + const parsed = risuChatParser(book.prompt, { chara: char }).trim() + if (parsed.length === 0) { + continue + } + + const tokens = await tokenize(parsed) + + if (totalTokens + tokens > maxContext) { + break + } + totalTokens += tokens + loreBooks.push({ + data: parsed, + role: book.role === 'assistant' ? 'char' : book.role, + }) + } + + return JSON.stringify(loreBooks) + }) + luaEngine.global.set('axLLMMain', async (id:string, promptStr:string) => { let prompt:{ role: string, @@ -708,6 +761,15 @@ function log(value) logMain(json.encode(value)) end +function getLoreBook(id, search) + return json.decode(getLoreBookMain(id, search)) +end + + +function loadLoreBooks(id) + return json.decode(loadLoreBooksMain(id):await()) +end + function LLM(id, prompt) return json.decode(LLMMain(id, json.encode(prompt)):await()) end From 5a70dd15667bc45f99f0f964dcd58f86dfeace85 Mon Sep 17 00:00:00 2001 From: enzi221 Date: Tue, 13 May 2025 16:16:27 +0900 Subject: [PATCH 2/5] refactor: Get current character from db.characters like other functions --- src/ts/process/lua.ts | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/ts/process/lua.ts b/src/ts/process/lua.ts index 086120a3..1629f37a 100644 --- a/src/ts/process/lua.ts +++ b/src/ts/process/lua.ts @@ -487,14 +487,20 @@ export async function runLua(code:string, arg:{ // Lore books luaEngine.global.set('getLoreBookMain', (id:string, search: string) => { - if (char.type !== 'character') { + if(!LuaSafeIds.has(id)){ return } - const loreBooks = [...char.chats[char.chatPage]?.localLore ?? [], ...char.globalLore, ...getModuleLorebooks()] + const db = getDatabase() + const selectedChar = db.characters[get(selectedCharID)] + if (selectedChar.type !== 'character') { + return + } + + const loreBooks = [...selectedChar.chats[selectedChar.chatPage]?.localLore ?? [], ...selectedChar.globalLore, ...getModuleLorebooks()] const found = loreBooks.find((b) => b.comment === search) - return found ? JSON.stringify({ ...found, content: risuChatParser(found.content, { chara: char }) } satisfies loreBook) : false + return found ? JSON.stringify({ ...found, content: risuChatParser(found.content, { chara: selectedChar }) } satisfies loreBook) : false }) luaEngine.global.set('loadLoreBooksMain', async (id:string, usedContext:number) => { @@ -502,11 +508,14 @@ export async function runLua(code:string, arg:{ return } - if (char.type !== 'character') { + const db = getDatabase() + + const selectedChar = db.characters[get(selectedCharID)] + + if (selectedChar.type !== 'character') { return } - const db = getDatabase() const fullLoreBooks = (await loadLoreBookV3Prompt()).actives const maxContext = db.maxContext - usedContext if (maxContext < 0) { @@ -517,7 +526,7 @@ export async function runLua(code:string, arg:{ const loreBooks = [] for (const book of fullLoreBooks) { - const parsed = risuChatParser(book.prompt, { chara: char }).trim() + const parsed = risuChatParser(book.prompt, { chara: selectedChar }).trim() if (parsed.length === 0) { continue } From 1b8a0762b1e4c1d3e4f2a5e2ad1b3dd79d9e273e Mon Sep 17 00:00:00 2001 From: enzi221 Date: Tue, 13 May 2025 23:12:57 +0900 Subject: [PATCH 3/5] fix: Return stringified false instead of literal false --- src/ts/process/lua.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/ts/process/lua.ts b/src/ts/process/lua.ts index 1629f37a..080d1023 100644 --- a/src/ts/process/lua.ts +++ b/src/ts/process/lua.ts @@ -500,7 +500,11 @@ export async function runLua(code:string, arg:{ const loreBooks = [...selectedChar.chats[selectedChar.chatPage]?.localLore ?? [], ...selectedChar.globalLore, ...getModuleLorebooks()] const found = loreBooks.find((b) => b.comment === search) - return found ? JSON.stringify({ ...found, content: risuChatParser(found.content, { chara: selectedChar }) } satisfies loreBook) : false + if (found) { + return JSON.stringify({ ...found, content: risuChatParser(found.content, { chara: selectedChar }) } satisfies loreBook) + } else { + return JSON.stringify(false) + } }) luaEngine.global.set('loadLoreBooksMain', async (id:string, usedContext:number) => { From 40e91e59a73030fc68c2ae87ab4d245edf1a50de Mon Sep 17 00:00:00 2001 From: enzi221 Date: Fri, 16 May 2025 03:36:50 +0900 Subject: [PATCH 4/5] feat: Return all lore books of same name without sort --- src/ts/process/lua.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/ts/process/lua.ts b/src/ts/process/lua.ts index 080d1023..274833aa 100644 --- a/src/ts/process/lua.ts +++ b/src/ts/process/lua.ts @@ -498,13 +498,9 @@ export async function runLua(code:string, arg:{ } const loreBooks = [...selectedChar.chats[selectedChar.chatPage]?.localLore ?? [], ...selectedChar.globalLore, ...getModuleLorebooks()] - const found = loreBooks.find((b) => b.comment === search) + const found = loreBooks.filter((b) => b.comment === search) - if (found) { - return JSON.stringify({ ...found, content: risuChatParser(found.content, { chara: selectedChar }) } satisfies loreBook) - } else { - return JSON.stringify(false) - } + return JSON.stringify(found.map((b) => ({ ...b, content: risuChatParser(b.content, { chara: selectedChar }) }))) }) luaEngine.global.set('loadLoreBooksMain', async (id:string, usedContext:number) => { From a758b574f52ad174d4631f72350de263c935afe6 Mon Sep 17 00:00:00 2001 From: enzi221 Date: Fri, 16 May 2025 03:37:54 +0900 Subject: [PATCH 5/5] fix: Pluralize name --- src/ts/process/lua.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ts/process/lua.ts b/src/ts/process/lua.ts index 274833aa..602333b8 100644 --- a/src/ts/process/lua.ts +++ b/src/ts/process/lua.ts @@ -486,7 +486,7 @@ export async function runLua(code:string, arg:{ }) // Lore books - luaEngine.global.set('getLoreBookMain', (id:string, search: string) => { + luaEngine.global.set('getLoreBooksMain', (id:string, search: string) => { if(!LuaSafeIds.has(id)){ return } @@ -770,8 +770,8 @@ function log(value) logMain(json.encode(value)) end -function getLoreBook(id, search) - return json.decode(getLoreBookMain(id, search)) +function getLoreBooks(id, search) + return json.decode(getLoreBooksMain(id, search)) end