diff --git a/public/pluginApi.ts b/public/pluginApi.ts index fb65827e..cb83f9d3 100644 --- a/public/pluginApi.ts +++ b/public/pluginApi.ts @@ -1,143 +1,147 @@ -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 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; - } - } - } +(() => { + interface risuPlugin{ + providers: {name:string, func:(arg:providerArgument) => Promise<{success:boolean,content:string}>}[] + fetchResponseQueue:{id:string,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) - } - } + + let __risuPlugin__:risuPlugin = { + providers: [], + fetchResponseQueue: [] } -} - -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 - }) -} - -async function handleOnmessage(data:{type:string,body:any}) { - if(!data.type){ - return + + const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms)); + + interface OpenAIChat{ + role: 'system'|'user'|'assistant' + content: string } - 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 - } + + interface providerArgument{ + prompt_chat?: OpenAIChat, + temperature?: number, + max_tokens?: number, + presence_penalty?: number + frequency_penalty?: number + bias?: {[key:string]:string} + } + + 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 } - if(!providerfunc){ - postMessage({ - type: 'resProvider', - body: { - 'success': false, - 'content': 'unknown provider' + }) + 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; } - }) + } } - else{ - try { - postMessage({ - type: 'resProvider', - body: await providerfunc(body.arg) - }) - } catch (error) { + } + } + + 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 + }) + } + + 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': `providerError: ${error}` + '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 } - break - } - case "fetchData":{ - __risuPlugin__.fetchResponseQueue.push(data.body) - break } } -} + + onmessage = (ev) => { + handleOnmessage(ev.data) + const data:{type:string,body:any} = ev.data + } -onmessage = (ev) => { - handleOnmessage(ev.data) - const data:{type:string,body:any} = ev.data -} \ No newline at end of file + //{{placeholder}} +})() \ No newline at end of file diff --git a/src/ts/process/plugins.ts b/src/ts/process/plugins.ts index 6679fc02..88604b1d 100644 --- a/src/ts/process/plugins.ts +++ b/src/ts/process/plugins.ts @@ -107,6 +107,7 @@ export function getCurrentPluginMax(prov:string){ 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 = { @@ -116,6 +117,8 @@ function postMsgPluginWorker(type:string, body:any){ pluginWorker.postMessage(bod) } +let pluginTranslator = false + export async function loadPlugins() { let db = get(DataBase) if(pluginWorker){ @@ -127,10 +130,12 @@ export async function loadPlugins() { const da = await fetch("/pluginApi.js") const pluginApiString = await da.text() let pluginjs = `${pluginApiString}\n` + let pluginLoadedJs = '' for(const plug of db.plugins){ - pluginjs += `(() => {${plug.script}})()` + pluginLoadedJs += `(() => {${plug.script}})()` } + pluginjs = pluginjs.replace('//{{placeholder}}',pluginLoadedJs) const blob = new Blob([pluginjs], {type: 'application/javascript'}); pluginWorker = new Worker(URL.createObjectURL(blob)); @@ -167,6 +172,31 @@ export async function loadPlugins() { } 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 + } case "fetch": { postMsgPluginWorker('fetchData',{ id: data.body.id, @@ -208,6 +238,33 @@ export async function loadPlugins() { } } +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" + } + } + } +} + export async function pluginProcess(arg:{ prompt_chat: OpenAIChat, temperature: number, diff --git a/src/ts/translator/translator.ts b/src/ts/translator/translator.ts index 73565774..3cf06f19 100644 --- a/src/ts/translator/translator.ts +++ b/src/ts/translator/translator.ts @@ -1,28 +1,34 @@ import { Body,fetch,ResponseType } from "@tauri-apps/api/http" import { isTauri } from "../globalApi" +import { translatorPlugin } from "../process/plugins" let cache={ origin: [''], trans: [''] } -export async function translate(params:string, reverse:boolean) { +export async function translate(text:string, reverse:boolean) { if(!isTauri){ - return params + return text + } + const plug = await translatorPlugin(text, reverse ? 'ko' : 'en', reverse ? 'en' : 'ko') + if(plug){ + return plug.content } if(!reverse){ - const ind = cache.origin.indexOf(params) + const ind = cache.origin.indexOf(text) if(ind !== -1){ return cache.trans[ind] } } else{ - const ind = cache.trans.indexOf(params) + const ind = cache.trans.indexOf(text) if(ind !== -1){ return cache.origin[ind] } } - return googleTrans(params, reverse) + + return googleTrans(text, reverse) } async function googleTrans(text:string, reverse:boolean) { @@ -45,5 +51,8 @@ async function googleTrans(text:string, reverse:boolean) { }) const res = f.data as {sentences:{trans?:string}[]} + if(typeof(f.data) === 'string'){ + return res + } return res.sentences.filter((s) => 'trans' in s).map((s) => s.trans).join(''); } \ No newline at end of file