From 027a59142442daf6db9b730151655e8cc8e3b227 Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Tue, 24 Dec 2024 23:14:49 +0900 Subject: [PATCH] Remove V1 Plugin --- public/pluginApi.js | 264 ---------------- public/pluginApi.ts | 192 ------------ src/etc/example-char.js | 115 ------- src/lang/en.ts | 1 + src/lib/Setting/Pages/PluginSettings.svelte | 6 +- src/ts/observer.ts | 8 - src/ts/plugins/embedscript.ts | 324 -------------------- src/ts/plugins/embedworker.ts | 202 ------------ src/ts/plugins/plugins.ts | 248 +-------------- src/ts/process/index.svelte.ts | 8 - src/ts/process/scripts.ts | 6 - 11 files changed, 21 insertions(+), 1353 deletions(-) delete mode 100644 public/pluginApi.js delete mode 100644 public/pluginApi.ts delete mode 100644 src/etc/example-char.js delete mode 100644 src/ts/plugins/embedscript.ts delete mode 100644 src/ts/plugins/embedworker.ts diff --git a/public/pluginApi.js b/public/pluginApi.js deleted file mode 100644 index 1c62fd59..00000000 --- a/public/pluginApi.js +++ /dev/null @@ -1,264 +0,0 @@ -var __assign = (this && this.__assign) || function () { - __assign = Object.assign || function(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); -}; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (g && (g = 0, op[0] && (_ = 0)), _) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; -(function () { - var __risuPlugin__ = { - providers: [], - fetchResponseQueue: [] - }; - var sleep = function (ms) { return new Promise(function (r) { return setTimeout(r, ms); }); }; - function transferDataAsync(type, body) { - return __awaiter(this, void 0, void 0, function () { - var id, i, q; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - id = "".concat(Date.now(), "_").concat(Math.random()); - postMessage({ - type: 'fetch', - body: __assign({ id: id }, body) - }); - _a.label = 1; - case 1: - if (!true) return [3 /*break*/, 3]; - return [4 /*yield*/, sleep(50)]; - case 2: - _a.sent(); - for (i = 0; i < __risuPlugin__.fetchResponseQueue.length; i++) { - q = __risuPlugin__.fetchResponseQueue[i]; - if (q.id === id) { - __risuPlugin__.fetchResponseQueue.splice(i, 1); - return [2 /*return*/, q.data]; - } - } - return [3 /*break*/, 1]; - case 3: return [2 /*return*/]; - } - }); - }); - } - function risuFetch(url, arg) { - return __awaiter(this, void 0, void 0, function () { - var id, i, q; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - id = "".concat(Date.now(), "_").concat(Math.random()); - postMessage({ - type: 'fetch', - body: { - id: id, - url: url, - arg: arg - } - }); - _a.label = 1; - case 1: - if (!true) return [3 /*break*/, 3]; - return [4 /*yield*/, sleep(50)]; - case 2: - _a.sent(); - for (i = 0; i < __risuPlugin__.fetchResponseQueue.length; i++) { - q = __risuPlugin__.fetchResponseQueue[i]; - if (q.id === id) { - __risuPlugin__.fetchResponseQueue.splice(i, 1); - return [2 /*return*/, q.data]; - } - } - return [3 /*break*/, 1]; - case 3: return [2 /*return*/]; - } - }); - }); - } - function getArg(arg) { - return __awaiter(this, void 0, void 0, function () { - var id, i, q; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - id = "".concat(Date.now(), "_").concat(Math.random()); - postMessage({ - type: 'getArg', - body: { - id: id, - arg: arg - } - }); - _a.label = 1; - case 1: - if (!true) return [3 /*break*/, 3]; - return [4 /*yield*/, sleep(50)]; - case 2: - _a.sent(); - for (i = 0; i < __risuPlugin__.fetchResponseQueue.length; i++) { - q = __risuPlugin__.fetchResponseQueue[i]; - if (q.id === id) { - __risuPlugin__.fetchResponseQueue.splice(i, 1); - return [2 /*return*/, q.data]; - } - } - return [3 /*break*/, 1]; - case 3: return [2 /*return*/]; - } - }); - }); - } - function addProvider(name, func) { - postMessage({ - type: 'addProvider', - body: name - }); - __risuPlugin__.providers.push({ - name: name, - func: func - }); - } - function printLog(data) { - postMessage({ - type: 'log', - body: data - }); - } - function getChar() { - return transferDataAsync('getChar', ''); - } - function setChar(char) { - postMessage({ - type: 'setChar', - body: char - }); - } - function addCharaJs(code, position) { - if (position === void 0) { position = 'back'; } - var codeString = code.toString().replace(/.+?\{/, '{'); - postMessage({ - type: 'addCharaJs', - body: { - code: codeString, - position: position - } - }); - } - function handleOnmessage(data) { - return __awaiter(this, void 0, void 0, function () { - var _a, body, providers, providerfunc, _i, providers_1, provider, _b, error_1; - var _c; - return __generator(this, function (_d) { - switch (_d.label) { - case 0: - if (!data.type) { - return [2 /*return*/]; - } - _a = data.type; - switch (_a) { - case "requestProvider": return [3 /*break*/, 1]; - case "fetchData": return [3 /*break*/, 6]; - } - return [3 /*break*/, 7]; - case 1: - body = data.body; - providers = __risuPlugin__.providers; - providerfunc = null; - for (_i = 0, providers_1 = providers; _i < providers_1.length; _i++) { - provider = providers_1[_i]; - if (provider.name === body.key) { - providerfunc = provider.func; - } - } - if (!!providerfunc) return [3 /*break*/, 2]; - postMessage({ - type: 'resProvider', - body: { - 'success': false, - 'content': 'unknown provider' - } - }); - return [3 /*break*/, 5]; - case 2: - _d.trys.push([2, 4, , 5]); - _b = postMessage; - _c = { - type: 'resProvider' - }; - return [4 /*yield*/, providerfunc(body.arg)]; - case 3: - _b.apply(void 0, [(_c.body = _d.sent(), - _c)]); - return [3 /*break*/, 5]; - case 4: - error_1 = _d.sent(); - postMessage({ - type: 'resProvider', - body: { - 'success': false, - 'content': "providerError: ".concat(error_1) - } - }); - return [3 /*break*/, 5]; - case 5: return [3 /*break*/, 7]; - case 6: - { - __risuPlugin__.fetchResponseQueue.push(data.body); - return [3 /*break*/, 7]; - } - _d.label = 7; - case 7: return [2 /*return*/]; - } - }); - }); - } - onmessage = function (ev) { - handleOnmessage(ev.data); - var data = ev.data; - }; - { - var __risuPlugin__1 = null; - var transferDataAsync_1 = null; - //{{placeholder}} - } -})(); diff --git a/public/pluginApi.ts b/public/pluginApi.ts deleted file mode 100644 index d2cd05c0..00000000 --- a/public/pluginApi.ts +++ /dev/null @@ -1,192 +0,0 @@ -(() => { - interface risuPlugin{ - providers: {name:string, func:(arg:providerArgument) => Promise<{success:boolean,content:string}>}[] - fetchResponseQueue:{id:string,data:any}[] - } - - let __risuPlugin__:risuPlugin = { - providers: [], - fetchResponseQueue: [] - } - - const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); - - interface OpenAIChat{ - role: 'system'|'user'|'assistant' - content: string - } - - interface providerArgument{ - prompt_chat?: OpenAIChat, - temperature?: number, - max_tokens?: number, - presence_penalty?: number - frequency_penalty?: number - bias?: {[key:string]:string} - } - - async function transferDataAsync(type:string,body:any) { - const id = `${Date.now()}_${Math.random()}` - postMessage({ - type: 'fetch', - body: {id: id, ...body} - }) - while(true){ - await sleep(50) - for(let i=0;i<__risuPlugin__.fetchResponseQueue.length;i++){ - const q = __risuPlugin__.fetchResponseQueue[i] - if(q.id === id){ - __risuPlugin__.fetchResponseQueue.splice(i, 1) - return q.data - } - } - } - } - - async function risuFetch(url:string, arg:{body:any,headers?:{[key:string]:string}}){ - const id = `${Date.now()}_${Math.random()}` - postMessage({ - type: 'fetch', - body: { - id: id, - url: url, - arg: arg - } - }) - while(true){ - await sleep(50) - for(let i=0;i<__risuPlugin__.fetchResponseQueue.length;i++){ - const q = __risuPlugin__.fetchResponseQueue[i] - if(q.id === id){ - - __risuPlugin__.fetchResponseQueue.splice(i, 1) - return q.data as { - ok: boolean; - data: any; - } - } - } - } - } - - async function getArg(arg:string){ - const id = `${Date.now()}_${Math.random()}` - postMessage({ - type: 'getArg', - body: { - id: id, - arg: arg - } - }) - while(true){ - await sleep(50) - for(let i=0;i<__risuPlugin__.fetchResponseQueue.length;i++){ - const q = __risuPlugin__.fetchResponseQueue[i] - if(q.id === id){ - __risuPlugin__.fetchResponseQueue.splice(i, 1) - return q.data as (string|number|null) - } - } - } - } - - function addProvider(name:string, func:(arg:providerArgument) => Promise<{success:boolean,content:string}>){ - postMessage({ - type: 'addProvider', - body: name - }) - __risuPlugin__.providers.push({ - name: name, - func: func - }) - } - - function printLog(data:any){ - postMessage({ - type: 'log', - body: data - }) - } - - - function getChar(){ - return transferDataAsync('getChar', '') - } - - function setChar(char:any){ - postMessage({ - type: 'setChar', - body: char - }) - } - - function addCharaJs(code:Function, position:'front'|'back' = 'back'){ - const codeString = code.toString().replace(/.+?\{/, '{') - postMessage({ - type: 'addCharaJs', - body: { - code: codeString, - position: position - } - }) - } - - async function handleOnmessage(data:{type:string,body:any}) { - if(!data.type){ - return - } - switch(data.type){ - case "requestProvider":{ - const body:{key:string,arg:providerArgument} = data.body - const providers = __risuPlugin__.providers - let providerfunc:((arg:providerArgument) => Promise<{success:boolean,content:string}>)|null= null - for(const provider of providers){ - if(provider.name === body.key){ - providerfunc = provider.func - } - } - if(!providerfunc){ - postMessage({ - type: 'resProvider', - body: { - 'success': false, - 'content': 'unknown provider' - } - }) - } - else{ - try { - postMessage({ - type: 'resProvider', - body: await providerfunc(body.arg) - }) - } catch (error) { - postMessage({ - type: 'resProvider', - body: { - 'success': false, - 'content': `providerError: ${error}` - } - }) - } - } - break - } - case "fetchData":{ - __risuPlugin__.fetchResponseQueue.push(data.body) - break - } - } - } - - onmessage = (ev) => { - handleOnmessage(ev.data) - const data:{type:string,body:any} = ev.data - } - - { - const __risuPlugin__ = null - const transferDataAsync = null - //{{placeholder}} - } -})() \ No newline at end of file diff --git a/src/etc/example-char.js b/src/etc/example-char.js deleted file mode 100644 index a73971fb..00000000 --- a/src/etc/example-char.js +++ /dev/null @@ -1,115 +0,0 @@ -//The @use comment tells the program what callable functions exist. If you omit this, the function will not be called. - -//@use editInput -//@use editOutput -//@use editProcess -//@use editDisplay -//@use onButtonClick -//@use modifyRequestChat - - -async function editInput(text){ - //editInput is a callable function that is called when the user inputs text into the input box. - //the first argument is the text that the user input. - //the text would replaced to return value, which would change the real value. - return text; -} - -async function editOutput(text){ - //editOutput is a callable function that is called when bot outputs text. - //the first argument is the text that the bot outputs. - //the text would replaced to return value, which would change the real value. - return text; -} - -async function editProcess(text){ - //editOutput is a callable function that is called when before request. - //the first argument is the original text. - //the text would replaced to return value and used in request, but it would not change the real value. - return text; -} - -async function editDisplay(text){ - //editDisplay is a callable function that is called when before display. - //the first argument is the original text. - //the text would replaced to return value and be displayed, but it would not change the real value. - return text -} - -async function onButtonClick(code){ - //onButtonClick is a callable function that is called when the user clicks the button. - //a button is a html element that has the attribute "risu-btn". - //the first argument is the code of the button. - //example: uses "example-char" as the code. - //return value is not used. - return -} - -async function modifyRequestChat(chat){ - //modifyRequestChat is a callable function that is called when before request. - //the first argument is the chat array. chat array is almost same as OpenAI's chat array. - //unlike editProcess, its called after other fixes is done, and its only called once, with the whole chat array. - //the chat array would replaced to return value and used in request. - return chat -} - - -async function showcase(){ - //this is a function for just introducing the apis. - - - //getChat() returns the chat object. - const chat = await getChat() - - //setChat(chat) sets the chat object. - //must be a valid chat object. - //returns true if success, false if failed. - await setChat(chat) - - //getName() returns the name of the character. - const name = await getName() - - //setName(name) sets the name of the character. - //must be a valid string. - //returns true if success, false if failed. - await setName(name) - - //getDescription() returns the description of the character. - const description = await getDescription() - - //setDescription(description) sets the description of the character. - //must be a valid string. - //returns true if success, false if failed. - await setDescription(description) - - //getCharacterFirstMessage() returns the first message of the character. - const firstMessage = await getCharacterFirstMessage() - - //setCharacterFirstMessage(firstMessage) sets the first message of the character. - //must be a valid string. - //returns true if success, false if failed. - await setCharacterFirstMessage(firstMessage) - - - - //setState(stateName, data) sets the states of the character. - //states are used to store data, because the data would be lost every time when function is called. - //if data is string, it must be less or equal to 100000 characters. - //stateName must be a valid string. - //data must be a valid string, number or boolean. - //returns true if success, false if failed. - await setState("somedata", "data") - await setState("anotherdata", 123) - - //getState(stateName) returns the state of the character. - //stateName must be a valid string. - //returns the data if success, null if failed. - const data = await getState("somedata") - const anotherdata = await getState("anotherdata") -} - - -// --- additional notes -// the code are parsed everytime, so complex codes would slow down the program. -// the function must be return in 400ms, or it would be timeout. -// for security reasons, you can only access limited apis. \ No newline at end of file diff --git a/src/lang/en.ts b/src/lang/en.ts index 7cb213a7..3dca20d2 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -834,4 +834,5 @@ export const languageEnglish = { menuSideBar: "Menu Side Bar", home: "Home", showSavingIcon: "Show Saving Icon", + pluginVersionWarn: "This is {{plugin_version}} version of the plugin. which is not compatible with this version of RisuAI. please update the plugin to {{required_version}} version.", } \ No newline at end of file diff --git a/src/lib/Setting/Pages/PluginSettings.svelte b/src/lib/Setting/Pages/PluginSettings.svelte index 24565fc2..b064c0ac 100644 --- a/src/lib/Setting/Pages/PluginSettings.svelte +++ b/src/lib/Setting/Pages/PluginSettings.svelte @@ -38,7 +38,11 @@ - {#if Object.keys(plugin.arguments).length > 0} + {#if plugin.version !== 2} + + {language.pluginVersionWarn.replace('{{plugin_version}}', 'API V1').replace('{{required_version}}', 'API V2')} + + {:else if Object.keys(plugin.arguments).length > 0}
{#each Object.keys(plugin.arguments) as arg} {arg} diff --git a/src/ts/observer.ts b/src/ts/observer.ts index b868cb9d..aa4ca1a7 100644 --- a/src/ts/observer.ts +++ b/src/ts/observer.ts @@ -1,5 +1,4 @@ import { runTrigger } from "./process/triggers"; -import { runCharacterJS } from "./plugins/embedscript"; import { sleep } from "./util"; import { getCurrentCharacter, getCurrentChat, setCurrentChat } from "./storage/database.svelte"; @@ -36,13 +35,6 @@ function nodeObserve(node:HTMLElement){ } if(btnEvent){ - node.addEventListener('click',async ()=>{ - await runCharacterJS({ - code: null, - mode: 'onButtonClick', - data: btnEvent - }) - }, {passive: true}) node.setAttribute('risu-observer', 'true'); return } diff --git a/src/ts/plugins/embedscript.ts b/src/ts/plugins/embedscript.ts deleted file mode 100644 index a2db413d..00000000 --- a/src/ts/plugins/embedscript.ts +++ /dev/null @@ -1,324 +0,0 @@ -import { get } from 'svelte/store' -import type { ScriptMode } from '../process/scripts' -//@ts-ignore -import WorkerUrl from './embedworker?worker&url' -import { getDatabase, type Message } from '../storage/database.svelte' -import { selectedCharID } from '../stores.svelte' -import { setDatabase } from '../storage/database.svelte' - -let worker = new Worker(WorkerUrl, {type: 'module'}) - -let additionalCharaJS:string[] = [] - -export function addAdditionalCharaJS(code:string, position:'front'|'back' = 'back'){ - if(position === 'front'){ - additionalCharaJS.unshift(code) - } - else{ - additionalCharaJS.push(code) - } -} - -let results:{ - id: string, - result: any -}[] = [] - -let workerFunctions: { - [key:string]: (...args:any[])=> Promise -} = {} - -worker.onmessage = ({data}) => { - if(data.type === 'api'){ - workerFunctions[data.name](...data.args).then((result)=>{ - worker.postMessage({ - type: 'result', - id: data.id, - result - }) - }) - } - else{ - results.push(data) - } -} - -function addWorkerFunction(name:string, func: (...args:any[])=> Promise){ - workerFunctions[name] = func - worker.postMessage({ - type: 'api', - name - }) -} - - -function runVirtualJS(code:string){ - const id = `id${Math.random()}`.replace('.','') - worker.postMessage({ - id,code - }) - let startTime = performance.now() - return new Promise((resolve,reject)=>{ - const interval = setInterval(()=>{ - const result = results.find(r=>r.id === id) - if(result){ - clearInterval(interval) - resolve(result.result) - } - else if(performance.now() - startTime > 800){ - clearInterval(interval) - //restart worker - worker.terminate() - worker = new Worker(WorkerUrl, {type: 'module'}) - reject('timeout') - } - },10) - }) -} - -addWorkerFunction('getChat', async () => { - const db = getDatabase({ - snapshot: true - }) - const selectedChar = get(selectedCharID) - const char = db.characters[selectedChar] - return safeStructuredClone(char.chats[char.chatPage].message) -}) - -addWorkerFunction('setChat', async (data:Message[]) => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - let newChat:Message[] = [] - for(const dat of data){ - if(dat.role !== 'char' && dat.role !== 'user'){ - return false - } - if(typeof dat.data !== 'string'){ - return false - } - if(typeof dat.saying !== 'string' && dat.saying !== null && dat.saying !== undefined){ - return false - } - if(typeof dat.time !== 'number' && dat.time !== null && dat.time !== undefined){ - return false - } - if(typeof dat.chatId !== 'string' && dat.chatId !== null && dat.chatId !== undefined){ - return false - } - newChat.push({ - role: dat.role, - data: dat.data, - saying: dat.saying, - time: dat.time, - chatId: dat.chatId - }) - } - db.characters[selectedChar].chats[db.characters[selectedChar].chatPage].message = newChat - setDatabase(db) - return true -}) - -addWorkerFunction('getName', async () => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - const char = db.characters[selectedChar] - return char.name -}) - -addWorkerFunction('setName', async (data:string) => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - if(typeof data !== 'string'){ - return false - } - db.characters[selectedChar].name = data - setDatabase(db) - return true -}) - -addWorkerFunction('getDescription', async () => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - const char = db.characters[selectedChar] - if(char.type === 'group'){ - return '' - } - return char.desc -}) - -addWorkerFunction('setDescription', async (data:string) => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - const char =db.characters[selectedChar] - if(typeof data !== 'string'){ - return false - } - if(char.type === 'group'){ - return false - } - char.desc = data - db.characters[selectedChar] = char - setDatabase(db) - return true -}) - -addWorkerFunction('getCharacterFirstMessage', async () => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - const char = db.characters[selectedChar] - return char.firstMessage -}) - -addWorkerFunction('setCharacterFirstMessage', async (data:string) => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - const char = db.characters[selectedChar] - if(typeof data !== 'string'){ - return false - } - char.firstMessage = data - db.characters[selectedChar] = char - setDatabase(db) - return true -}) - -addWorkerFunction('getBackgroundEmbedding', async () => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - const char = db.characters[selectedChar] - return char.backgroundHTML -}) - -addWorkerFunction('setBackgroundEmbedding', async (data:string) => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - if(typeof data !== 'string'){ - return false - } - db.characters[selectedChar].backgroundHTML = data - setDatabase(db) - return true -}) - - -addWorkerFunction('getState', async (statename) => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - const char = db.characters[selectedChar] - const chat = char.chats[char.chatPage] - return (chat.scriptstate ?? {})[statename] -}) - -addWorkerFunction('setState', async (statename, data) => { - const db = getDatabase() - const selectedChar = get(selectedCharID) - const char = db.characters[selectedChar] - const chat = char.chats[char.chatPage] - if(typeof statename !== 'string'){ - return false - } - if(typeof data !== 'string' && typeof data !== 'number' && typeof data !== 'boolean'){ - return false - } - if(typeof data === 'string' && data.length > 100000){ - return false - } - if(!chat.scriptstate){ - chat.scriptstate = {} - } - if(Object.keys(chat.scriptstate).length > 50){ - return false - } - chat.scriptstate[statename] = data - char.chats[char.chatPage] = chat - db.characters[selectedChar] = char - setDatabase(db) - return true -}) - - - -let compCode:{[key:string]:string[]} = {} - -export async function runCharacterJS(arg:{ - code: string|null, - mode: ScriptMode|'onButtonClick'|'modifyRequestChat' - data: any -}):Promise{ - const perf = performance.now() - try { - arg.code = arg.code ?? '' - const codes = { - "editinput": 'editInput', - "editoutput": 'editOutput', - "editprocess": 'editProcess', - "editdisplay": 'editDisplay', - 'onButtonClick': "onButtonClick", - 'modifyRequestChat': 'modifyRequestChat' - } as const - - let runCodes = [...additionalCharaJS, arg.code] - - let r = arg.data - - for(const code of runCodes){ - if(!code){ - continue - } - if(!compCode[code]){ - let modeList:string[] = [] - const codesplit = code.split('\n') - for(let i = 0; i < codesplit.length; i++){ - const line = codesplit[i].trim() - if(line.startsWith('//@use')){ - modeList.push(line.replace('//@use','').trim()) - } - } - compCode[code] = modeList - // compcode length max 100 - if(Object.keys(compCode).length > 100){ - delete compCode[Object.keys(compCode)[50]] - } - } - - const runCode = codes[arg.mode] - - if(!compCode[code].includes(runCode)){ - continue - } - const result = await runVirtualJS(`${code}\n${runCode}(${JSON.stringify(r)})`) - - if(!result){ - continue - } - - if(arg.mode !== 'modifyRequestChat'){ - if(typeof result !== 'string'){ - continue - } - } - else{ - if(!Array.isArray(result)){ - continue - } - } - - r = result - - if(runCode === 'onButtonClick'){ - return r - } - } - return r - - } catch (error) { - if(arg.mode !== 'editprocess'){ - return `Error: ${error}` - } - return arg.data - } - finally{ - console.log('runCharacterJS',performance.now() - perf) - } - -} \ No newline at end of file diff --git a/src/ts/plugins/embedworker.ts b/src/ts/plugins/embedworker.ts deleted file mode 100644 index 9765cbc8..00000000 --- a/src/ts/plugins/embedworker.ts +++ /dev/null @@ -1,202 +0,0 @@ -let globaly = globalThis - -const whitelist = [ - "Array", - "ArrayBuffer", - "BigInt", - "BigInt64Array", - "BigUint64Array", - "Boolean", - "DataView", - "Date", - "Error", - "EvalError", - "Float32Array", - "Float64Array", - "Function", - "Infinity", - "Int16Array", - "Int32Array", - "Int8Array", - "JSON", - "Map", - "Math", - "NaN", - "Number", - "Object", - "Promise", - "Proxy", - "RangeError", - "ReferenceError", - "Reflect", - "RegExp", - "Set", - "SharedArrayBuffer", - "String", - "Symbol", - "SyntaxError", - "TypeError", - "URIError", - "Uint16Array", - "Uint32Array", - "Uint8Array", - "Uint8ClampedArray", - "WeakMap", - "WeakSet", - "console", - "decodeURI", - "decodeURIComponent", - "encodeURI", - "encodeURIComponent", - "escape", - "globalThis", - "isFinite", - "isNaN", - "null", - "parseFloat", - "parseInt", - "undefined", - "unescape", - "queueMicrotask", - "setTimeout", - "clearTimeout", - "setInterval", - "clearInterval", - "setImmediate", - "clearImmediate", - "atob", - "btoa", - "Headers", - "Request", - "Response", - "Blob", - "postMessage", - "Node", - "Element", - "Text", - "Comment", - 'onmessage', - "DOMParser", - "XMLSerializer", - "TextEncoder", - "TextDecoder", - "AbortController", - "AbortSignal", - "Event", - "CustomEvent", - "EventTarget", - "OffscreenCanvas", - "ImageBitmap", - "ImageBitmapRenderingContext", - "createImageBitmap", - "OffScreenCanvasRenderingContext2D", - "WebGL2RenderingContext", - "WebGLRenderingContext", -] - -const evaluation = globaly.eval - -const propa = Object.getOwnPropertyNames( this ?? {} ) -const prop = Object.getOwnPropertyNames( globaly ).concat( propa) -prop.push( - //unsafe apis - 'open', - 'close', - 'alert', - 'confirm', - 'prompt', - 'print', - 'fetch', - 'navigator', - 'Worker', - 'WebSocket', - 'XMLHttpRequest', - 'localStorage', - 'sessionStorage', - 'importScripts', - 'indexedDB', - 'crypto', - 'WebAssembly', - 'WebSqlDatabase', -) - -prop.forEach( function( prop ) { - if( (!whitelist.includes(prop)) && (!prop.startsWith('HTML')) ) { - try { - Object.defineProperty( globaly, prop, { - get : function() { - throw "Security Exception: cannot access "+prop; - return 1; - }, - configurable : false - }); - } catch (error) { - } - try { - Object.defineProperty( this, prop, { - get : function() { - throw "Security Exception: cannot access "+prop; - return 1; - }, - configurable : false - }); - } catch (error) { - } - } - else{ - } -}); - -let workerResults:{ - id: string, - result: any -}[] = [] - - -self.onmessage = async (event) => { - const da = event.data - if(da.type === 'result'){ - workerResults.push(da) - return - } - if(da.type === 'api'){ - //add api - Object.defineProperty( globaly, da.name, { - get : function() { - return function (...args:any[]) { - return new Promise((resolve)=>{ - const functionCallID = `id${Math.random()}`.replace('.','') - self.postMessage({ - type: 'api', - name: da.name, - id: functionCallID, - args - }) - const interval = setInterval(()=>{ - const result = workerResults.find(r=>r.id === functionCallID) - if(result){ - clearInterval(interval) - resolve(result.result) - } - },10) - }) - } - } - }); - return - } - try{ - const d = await evaluation(da.code) - self.postMessage({ - id: da.id, - result: d - }) - } - catch(e){ - console.error(e) - self.postMessage({ - id: da.id, - result: e - }) - } -} \ No newline at end of file diff --git a/src/ts/plugins/plugins.ts b/src/ts/plugins/plugins.ts index 2eb65e0b..f65e9048 100644 --- a/src/ts/plugins/plugins.ts +++ b/src/ts/plugins/plugins.ts @@ -1,12 +1,11 @@ import { get, writable } from "svelte/store"; import { language } from "../../lang"; -import { alertError } from "../alert"; +import { alertError, alertMd } from "../alert"; import { getCurrentCharacter, getDatabase, setDatabaseLite } from "../storage/database.svelte"; import { checkNullish, selectSingleFile, sleep } from "../util"; import type { OpenAIChat } from "../process/index.svelte"; import { fetchNative, globalFetch } from "../globalApi.svelte"; import { selectedCharID } from "../stores.svelte"; -import { addAdditionalCharaJS } from "./embedscript"; import type { ScriptMode } from "../process/scripts"; export const customProviderStore = writable([] as string[]) @@ -33,40 +32,30 @@ export async function importPlugin(){ const jsFile = Buffer.from(f.data).toString('utf-8').replace(/^\uFEFF/gm, ""); const splitedJs = jsFile.split('\n') let name = '' - let version:1|2 = 1 let displayName:string = undefined let arg:{[key:string]:'int'|'string'|string[]} = {} let realArg:{[key:string]:number|string} = {} for(const line of splitedJs){ if(line.startsWith('//@risu-name')){ - const provied = line.slice(13) - if(provied === ''){ - alertError('plugin name must be longer than "", did you put it correctly?') - return - } - name = provied.trim() + alertMd('V1 plugin is not supported anymore, please use V2 plugin instead. for more information, please check the documentation. `https://github.com/kwaroran/RisuAI/blob/main/plugins.md`') + return + } + if(line.startsWith('//@risu-display-name')){ + alertMd('V1 plugin is not supported anymore, please use V2 plugin instead. for more information, please check the documentation. `https://github.com/kwaroran/RisuAI/blob/main/plugins.md`') + return } if(line.startsWith('//@name')){ const provied = line.slice(7) if(provied === ''){ - alertError('plugin name must be longer than "", did you put it correctly?') + alertError('plugin name must be longer than 0, did you put it correctly?') return } - version = 2 name = provied.trim() } - if(line.startsWith('//@risu-display-name')){ - const provied = line.slice('//@risu-display-name'.length + 1) - if(provied === ''){ - alertError('plugin display name must be longer than "", did you put it correctly?') - return - } - displayName = provied.trim() - } if(line.startsWith('//@display-name')){ const provied = line.slice('//@display-name'.length + 1) if(provied === ''){ - alertError('plugin display name must be longer than "", did you put it correctly?') + alertError('plugin display name must be longer than 0, did you put it correctly?') return } displayName = provied.trim() @@ -105,7 +94,7 @@ export async function importPlugin(){ realArg: realArg, arguments: arg, displayName: displayName, - version: version + version: 2 } db.plugins ??= [] @@ -119,174 +108,15 @@ export async function importPlugin(){ } } -export function getCurrentPluginMax(prov:string){ - return 12000 -} - -let pluginWorker:Worker = null -let providerRes:{success:boolean, content:string} = null -let translatorRes:{success:boolean, content:string} = null - -function postMsgPluginWorker(type:string, body:any){ - const bod = { - type: type, - body: body - } - pluginWorker.postMessage(bod) -} - let pluginTranslator = false export async function loadPlugins() { let db = getDatabase() - if(pluginWorker){ - pluginWorker.terminate() - pluginWorker = null - } - const plugins = safeStructuredClone(db.plugins).filter((a:RisuPlugin) => a.version === 1) const pluginV2 = safeStructuredClone(db.plugins).filter((a:RisuPlugin) => a.version === 2) await loadV2Plugin(pluginV2) - - if(plugins.length > 0){ - - const da = await fetch("/pluginApi.js") - const pluginApiString = await da.text() - let pluginjs = `${pluginApiString}\n` - let pluginLoadedJs = '' - - for(const plug of db.plugins){ - pluginLoadedJs += `\n(() => {${plug.script}})();\n` - } - pluginjs = pluginjs.replace('//{{placeholder}}',pluginLoadedJs) - - const blob = new Blob([pluginjs], {type: 'application/javascript'}); - pluginWorker = new Worker(URL.createObjectURL(blob)); - - pluginWorker.addEventListener('message', async (msg) => { - const data:{type:string,body:any} = msg.data - switch(data.type){ - case "addProvider":{ - let provs = get(customProviderStore) - provs.push(data.body) - customProviderStore.set(provs) - console.log(provs) - break - } - case "resProvider":{ - const provres:{success:boolean, content:string} = data.body - if(checkNullish(provres.success) || checkNullish(provres.content)){ - providerRes = { - success: false, - content :"provider didn't respond 'success' or 'content' in response object" - } - } - else if(typeof(provres.content) !== 'string'){ - providerRes = { - success: false, - content :"provider didn't respond 'content' in response object in string" - } - } - else{ - providerRes = { - success: !!provres.success, - content: provres.content - } - } - break - } - case "resTrans":{ - const provres:{success:boolean, content:string} = data.body - if(checkNullish(provres.success) || checkNullish(provres.content)){ - translatorRes = { - success: false, - content :"plugin didn't respond 'success' or 'content' in response object" - } - } - else if(typeof(provres.content) !== 'string'){ - translatorRes = { - success: false, - content :"plugin didn't respond 'content' in response object in string" - } - } - else{ - translatorRes = { - success: !!provres.success, - content: provres.content - } - } - break - } - case "useTranslator": { - pluginTranslator = true - break - } - case "fetch": { - postMsgPluginWorker('fetchData',{ - id: data.body.id, - data: await globalFetch(data.body.url, data.body.arg) - }) - break - } - case 'addCharaJs': { - let c:string = data.body.code - c.trim() - if(c.startsWith('{') && c.endsWith('}')){ - c = c.slice(1, -1) - } - addAdditionalCharaJS(c, data.body.position) - break - } - case "getArg":{ - try { - const db = getDatabase() - const arg:string[] = data.body.arg.split('::') - for(const plug of db.plugins){ - if(arg[0] === plug.name){ - postMsgPluginWorker('fetchData',{ - id: data.body.id, - data: plug.realArg[arg[1]] - }) - return - } - } - postMsgPluginWorker('fetchData',{ - id: data.body.id, - data: null - }) - } catch (error) { - postMsgPluginWorker('fetchData',{ - id: data.body.id, - data: null - }) - } - break - } - case "getChar":{ - const db = getDatabase() - const charid = get(selectedCharID) - const char = db.characters[charid] - postMsgPluginWorker('fetchData',{ - id: data.body.id, - data: char - }) - break - } - case "setChar":{ - const db = getDatabase() - const charid = get(selectedCharID) - db.characters[charid] = data.body - break - } - case "log":{ - console.log(data.body) - break - } - } - }) - } } type PluginV2ProviderArgument = { @@ -424,30 +254,7 @@ export async function loadV2Plugin(plugins:RisuPlugin[]){ } export async function translatorPlugin(text:string, from:string, to:string) { - if(!pluginTranslator){ - return false - } - else{ - try { - translatorRes = null - postMsgPluginWorker("requestTrans", {text, from, to}) - while(true){ - await sleep(50) - if(providerRes){ - break - } - } - return { - success: translatorRes.success, - content: translatorRes.content - } - } catch (error) { - return { - success: false, - content: "unknownError" - } - } - } + return false } export async function pluginProcess(arg:{ @@ -458,35 +265,10 @@ export async function pluginProcess(arg:{ frequency_penalty: number bias: {[key:string]:string} }|{}){ - try { - let db = getDatabase() - if(!pluginWorker){ - return { - success: false, - content: "plugin worker not found error" - } - } - postMsgPluginWorker("requestProvider", { - key: db.currentPluginProvider, - arg: arg - }) - providerRes = null - while(true){ - await sleep(50) - if(providerRes){ - break - } - } - return { - success: providerRes.success, - content: providerRes.content - } - } catch (error) { - return { - success: false, - content: "unknownError" - } - } + return { + success: false, + content: "Plugin V1 is not supported anymore, please use V2 plugin instead." + } } diff --git a/src/ts/process/index.svelte.ts b/src/ts/process/index.svelte.ts index f9c108c7..4694284d 100644 --- a/src/ts/process/index.svelte.ts +++ b/src/ts/process/index.svelte.ts @@ -22,7 +22,6 @@ import { getInlayAsset, supportsInlayImage } from "./files/inlays"; import { getGenerationModelString } from "./models/modelString"; import { connectionOpen, peerRevertChat, peerSafeCheck, peerSync } from "../sync/multiuser"; import { runInlayScreen } from "./inlayScreen"; -import { runCharacterJS } from "../plugins/embedscript"; import { addRerolls } from "./prereroll"; import { runImageEmbedding } from "./transformers"; import { hanuraiMemory } from "./memory/hanuraiMemory"; @@ -30,7 +29,6 @@ import { hypaMemoryV2 } from "./memory/hypav2"; import { runLuaEditTrigger } from "./lua"; import { parseChatML } from "../parser.svelte"; import { getModelInfo, LLMFlags } from "../model/modellist"; -import { pluginV2 } from "../plugins/plugins"; export interface OpenAIChat{ role: 'system'|'user'|'assistant'|'function' @@ -1114,12 +1112,6 @@ export async function sendChat(chatProcessIndex = -1,arg:{ }) } - formated = await runCharacterJS({ - code: null, - mode: 'modifyRequestChat', - data: formated - }) - formated = await runLuaEditTrigger(currentChar, 'editRequest', formated) //token rechecking diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts index 63ad29af..5505ea8d 100644 --- a/src/ts/process/scripts.ts +++ b/src/ts/process/scripts.ts @@ -6,7 +6,6 @@ import { alertError, alertNormal } from "../alert"; import { language } from "src/lang"; import { selectSingleFile } from "../util"; import { assetRegex, type CbsConditions, risuChatParser as risuChatParserOrg, type simpleCharacterArgument } from "../parser.svelte"; -import { runCharacterJS } from "../plugins/embedscript"; import { getModuleAssets, getModuleRegexScripts } from "./modules"; import { HypaProcesser } from "./memory/hypamemory"; import { runLuaEditTrigger } from "./lua"; @@ -104,11 +103,6 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter } let emoChanged = false const scripts = (db.globalscript ?? []).concat(char.customscript).concat(getModuleRegexScripts()) - data = await runCharacterJS({ - code: char.virtualscript ?? null, - mode, - data, - }) data = await runLuaEditTrigger(char, mode, data) if(pluginV2[mode].size > 0){ for(const plugin of pluginV2[mode]){