Updated to 0.7.0 (#8)
This commit is contained in:
@@ -1,143 +1,181 @@
|
|||||||
interface risuPlugin{
|
(() => {
|
||||||
providers: {name:string, func:(arg:providerArgument) => Promise<{success:boolean,content:string}>}[]
|
interface risuPlugin{
|
||||||
fetchResponseQueue:{id:string,data:any}[]
|
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}
|
||||||
|
}
|
||||||
|
|
||||||
let __risuPlugin__:risuPlugin = {
|
async function transferDataAsync(type:string,body:any) {
|
||||||
providers: [],
|
const id = `${Date.now()}_${Math.random()}`
|
||||||
fetchResponseQueue: []
|
postMessage({
|
||||||
}
|
type: 'fetch',
|
||||||
|
body: {id: id, ...body}
|
||||||
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
|
})
|
||||||
|
while(true){
|
||||||
interface OpenAIChat{
|
await sleep(50)
|
||||||
role: 'system'|'user'|'assistant'
|
for(let i=0;i<__risuPlugin__.fetchResponseQueue.length;i++){
|
||||||
content: string
|
const q = __risuPlugin__.fetchResponseQueue[i]
|
||||||
}
|
if(q.id === id){
|
||||||
|
__risuPlugin__.fetchResponseQueue.splice(i, 1)
|
||||||
interface providerArgument{
|
return q.data
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
async function risuFetch(url:string, arg:{body:any,headers?:{[key:string]:string}}){
|
||||||
async function getArg(arg:string){
|
const id = `${Date.now()}_${Math.random()}`
|
||||||
const id = `${Date.now()}_${Math.random()}`
|
postMessage({
|
||||||
postMessage({
|
type: 'fetch',
|
||||||
type: 'getArg',
|
body: {
|
||||||
body: {
|
id: id,
|
||||||
id: id,
|
url: url,
|
||||||
arg: arg
|
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)
|
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
while(true){
|
||||||
}
|
await sleep(50)
|
||||||
|
for(let i=0;i<__risuPlugin__.fetchResponseQueue.length;i++){
|
||||||
function addProvider(name:string, func:(arg:providerArgument) => Promise<{success:boolean,content:string}>){
|
const q = __risuPlugin__.fetchResponseQueue[i]
|
||||||
postMessage({
|
if(q.id === id){
|
||||||
type: 'addProvider',
|
|
||||||
body: name
|
__risuPlugin__.fetchResponseQueue.splice(i, 1)
|
||||||
})
|
return q.data as {
|
||||||
__risuPlugin__.providers.push({
|
ok: boolean;
|
||||||
name: name,
|
data: any;
|
||||||
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': 'unknown provider'
|
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
else{
|
}
|
||||||
try {
|
}
|
||||||
postMessage({
|
|
||||||
type: 'resProvider',
|
async function getArg(arg:string){
|
||||||
body: await providerfunc(body.arg)
|
const id = `${Date.now()}_${Math.random()}`
|
||||||
})
|
postMessage({
|
||||||
} catch (error) {
|
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
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
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({
|
postMessage({
|
||||||
type: 'resProvider',
|
type: 'resProvider',
|
||||||
body: {
|
body: {
|
||||||
'success': false,
|
'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 __risuPlugin__ = null
|
||||||
const data:{type:string,body:any} = ev.data
|
const transferDataAsync = null
|
||||||
}
|
//{{placeholder}}
|
||||||
|
}
|
||||||
|
})()
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
"productName": "RisuAI",
|
"productName": "RisuAI",
|
||||||
"version": "0.6.7"
|
"version": "0.7.0"
|
||||||
},
|
},
|
||||||
"tauri": {
|
"tauri": {
|
||||||
"allowlist": {
|
"allowlist": {
|
||||||
|
|||||||
@@ -50,6 +50,13 @@ export const languageEnglish = {
|
|||||||
+ "\n- if the key starts with **|**, the key's value will not change."
|
+ "\n- if the key starts with **|**, the key's value will not change."
|
||||||
+ "\n- if the key starts with **$**, the key's value will more likely to change."
|
+ "\n- if the key starts with **$**, the key's value will more likely to change."
|
||||||
+ "\n\nwhen the image is first generated, you can only change it by modifying 'Current Image Generation Data' in below.",
|
+ "\n\nwhen the image is first generated, you can only change it by modifying 'Current Image Generation Data' in below.",
|
||||||
|
|
||||||
|
regexScript: "Regex Script is a custom script that is embbedded to the character. it replaces string that matches IN to OUT.\n\nThere are three type options."
|
||||||
|
+ "- **Modify Input** modifys user's input"
|
||||||
|
+ "- **Modify Output** modifys character's output"
|
||||||
|
+ "- **Modify Request Data** modifys current chat data when sent.\n\nIN must be a regex without flags and *\\*.\n\nOUT is a normal string."
|
||||||
|
+ "\n\n If 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.",
|
||||||
experimental: "This is a experimental setting. it might be unstable."
|
experimental: "This is a experimental setting. it might be unstable."
|
||||||
},
|
},
|
||||||
setup: {
|
setup: {
|
||||||
@@ -199,6 +206,8 @@ export const languageEnglish = {
|
|||||||
type: "Type",
|
type: "Type",
|
||||||
editInput: "Modfiy Input",
|
editInput: "Modfiy Input",
|
||||||
editOutput: "Modfiy Output",
|
editOutput: "Modfiy Output",
|
||||||
editProcess: "Modfiy Request Data"
|
editProcess: "Modfiy Request Data",
|
||||||
|
loadLatest: "Load Latest Backup",
|
||||||
|
loadOthers: "Load Other Backups"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,7 +179,13 @@ export const languageKorean = {
|
|||||||
+ "\n- 키의 이름이 **|** 로 시작할 시, 값은 고정됩니다."
|
+ "\n- 키의 이름이 **|** 로 시작할 시, 값은 고정됩니다."
|
||||||
+ "\n- 키의 이름이 **$** 로 시작할 시, 값은 더 자주 변합니다."
|
+ "\n- 키의 이름이 **$** 로 시작할 시, 값은 더 자주 변합니다."
|
||||||
+ "\n\n이미지가 처음 생성된 이후부터는 '현재 이미지 생성 데이터'를 수정하여 변경할 수 있습니다.",
|
+ "\n\n이미지가 처음 생성된 이후부터는 '현재 이미지 생성 데이터'를 수정하여 변경할 수 있습니다.",
|
||||||
experimental: "실험적 기능입니다. 불안정할 수 있습니다."
|
experimental: "실험적 기능입니다. 불안정할 수 있습니다.",
|
||||||
|
regexScript: "정규식 스크립트는 캐릭터에 종속된 커스텀 스크립트입니다. IN의 조건에 맞는 문자열을 OUT으로 변경합니다.\n\n타입은 세가지가 있습니다."
|
||||||
|
+ "- **입력문 수정** 유저의 입력문을 수정합니다"
|
||||||
|
+ "- **출력문 수정** 캐릭터의 출력문을 수정합니다"
|
||||||
|
+ "- **리퀘스트 데이터 수정** 리퀘스트를 보낼 때 채팅 데이터를 수정합니다.\n\nIN은 flag와 *\\* 가 없는 Regex여야 합니다.\n\nOUT은 일반 문자열입니다."
|
||||||
|
+ "\n\n 만약 OUT이 @@로 시작된다면, 특수한 효과를 냅니다"
|
||||||
|
+ "\n\n- @@emo (emotion name)\n\n 감정 이미지 모드일 시 (emotion name)을 감정으로 정하고 감정 처리를 하지 않습니다.",
|
||||||
},
|
},
|
||||||
setup: {
|
setup: {
|
||||||
chooseProvider: "AI 제공자를 선택해 주세요",
|
chooseProvider: "AI 제공자를 선택해 주세요",
|
||||||
@@ -199,5 +205,7 @@ export const languageKorean = {
|
|||||||
type: "타입",
|
type: "타입",
|
||||||
editInput: "입력문 수정",
|
editInput: "입력문 수정",
|
||||||
editOutput: "출력문 수정",
|
editOutput: "출력문 수정",
|
||||||
editProcess: "리퀘스트 데이터 수정"
|
editProcess: "리퀘스트 데이터 수정",
|
||||||
|
loadLatest: "가장 최근 백업 불러오기",
|
||||||
|
loadOthers: "다른 백업 불러오기"
|
||||||
}
|
}
|
||||||
@@ -11,7 +11,8 @@
|
|||||||
import { alertError } from "../../ts/alert";
|
import { alertError } from "../../ts/alert";
|
||||||
import sendSound from '../../etc/send.mp3'
|
import sendSound from '../../etc/send.mp3'
|
||||||
import {cloneDeep} from 'lodash'
|
import {cloneDeep} from 'lodash'
|
||||||
import { processScript } from "src/ts/process/scripts";
|
import { processScript } from "src/ts/process/scripts";
|
||||||
|
import GithubStars from "../Others/GithubStars.svelte";
|
||||||
|
|
||||||
let messageInput = ''
|
let messageInput = ''
|
||||||
let openMenu = false
|
let openMenu = false
|
||||||
@@ -186,6 +187,7 @@
|
|||||||
<div class="h-full w-full flex flex-col overflow-y-auto items-center">
|
<div class="h-full w-full flex flex-col overflow-y-auto items-center">
|
||||||
<h2 class="text-4xl text-white mb-0 mt-6 font-black">RisuAI</h2>
|
<h2 class="text-4xl text-white mb-0 mt-6 font-black">RisuAI</h2>
|
||||||
<h3 class="text-gray-500 mt-1">Version {appVer}</h3>
|
<h3 class="text-gray-500 mt-1">Version {appVer}</h3>
|
||||||
|
<GithubStars />
|
||||||
</div>
|
</div>
|
||||||
{:else}
|
{:else}
|
||||||
<div class="h-full w-full flex flex-col-reverse overflow-y-auto relative" on:scroll={(e) => {
|
<div class="h-full w-full flex flex-col-reverse overflow-y-auto relative" on:scroll={(e) => {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
{#if $alertStore.type !== 'none' && $alertStore.type !== 'toast'}
|
{#if $alertStore.type !== 'none' && $alertStore.type !== 'toast'}
|
||||||
<div class="absolute w-full h-full z-50 bg-black bg-opacity-50 flex justify-center items-center" class:vis={ $alertStore.type === 'wait2'}>
|
<div class="absolute w-full h-full z-50 bg-black bg-opacity-50 flex justify-center items-center" class:vis={ $alertStore.type === 'wait2'}>
|
||||||
<div class="bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl max-h-11/12 overflow-y-auto">
|
<div class="bg-darkbg p-4 break-any rounded-md flex flex-col max-w-3xl max-h-full overflow-y-auto">
|
||||||
{#if $alertStore.type === 'error'}
|
{#if $alertStore.type === 'error'}
|
||||||
<h2 class="text-red-700 mt-0 mb-2 w-40 max-w-full">Error</h2>
|
<h2 class="text-red-700 mt-0 mb-2 w-40 max-w-full">Error</h2>
|
||||||
{:else if $alertStore.type === 'ask'}
|
{:else if $alertStore.type === 'ask'}
|
||||||
|
|||||||
11
src/lib/Others/GithubStars.svelte
Normal file
11
src/lib/Others/GithubStars.svelte
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { isTauri } from "src/ts/globalApi";
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<svelte:head>
|
||||||
|
<script async defer src="https://buttons.github.io/buttons.js"></script>
|
||||||
|
</svelte:head>
|
||||||
|
<!-- Place this tag where you want the button to render. -->
|
||||||
|
{#if !isTauri}
|
||||||
|
<a class="github-button mt-4" href="https://github.com/kwaroran/risuAI" data-color-scheme="no-preference: dark; light: dark; dark: dark;" data-size="large" data-show-count="true" aria-label="Star kwaroran/risuAI on GitHub">Star</a>
|
||||||
|
{/if}
|
||||||
@@ -396,7 +396,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{/each}
|
{/each}
|
||||||
</table>
|
</table>
|
||||||
<span class="text-neutral-200 mt-4">{language.regexScript} <Help key="experimental"/></span>
|
<span class="text-neutral-200 mt-4">{language.regexScript} <Help key="regexScript"/></span>
|
||||||
<table class="contain w-full max-w-full tabler mt-2 flex flex-col p-2 gap-2">
|
<table class="contain w-full max-w-full tabler mt-2 flex flex-col p-2 gap-2">
|
||||||
{#if currentChar.data.customscript.length === 0}
|
{#if currentChar.data.customscript.length === 0}
|
||||||
<div class="text-gray-500">No Scripts</div>
|
<div class="text-gray-500">No Scripts</div>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { saveImage as saveImageGlobal } from './globalApi';
|
|||||||
|
|
||||||
export const DataBase = writable({} as any as Database)
|
export const DataBase = writable({} as any as Database)
|
||||||
export const loadedStore = writable(false)
|
export const loadedStore = writable(false)
|
||||||
export let appVer = '0.6.7'
|
export let appVer = '0.7.0'
|
||||||
|
|
||||||
|
|
||||||
export function setDatabase(data:Database){
|
export function setDatabase(data:Database){
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { get } from "svelte/store";
|
import { get } from "svelte/store";
|
||||||
import { alertError, alertInput, alertNormal, alertStore } from "../alert";
|
import { alertError, alertInput, alertNormal, alertSelect, alertStore } from "../alert";
|
||||||
import { DataBase, setDatabase, type Database } from "../database";
|
import { DataBase, setDatabase, type Database } from "../database";
|
||||||
import { forageStorage, getUnpargeables, isTauri } from "../globalApi";
|
import { forageStorage, getUnpargeables, isTauri } from "../globalApi";
|
||||||
import pako from "pako";
|
import pako from "pako";
|
||||||
@@ -177,8 +177,8 @@ async function loadDrive(ACCESS_TOKEN:string) {
|
|||||||
return d.name
|
return d.name
|
||||||
})
|
})
|
||||||
|
|
||||||
let latestDb:DriveFile = null
|
|
||||||
let latestDbDate = 0
|
let dbs:[DriveFile,number][] = []
|
||||||
|
|
||||||
for(const f of files){
|
for(const f of files){
|
||||||
if(f.name.endsWith("-database.risudat")){
|
if(f.name.endsWith("-database.risudat")){
|
||||||
@@ -187,15 +187,26 @@ async function loadDrive(ACCESS_TOKEN:string) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if(tm > latestDbDate){
|
dbs.push([f,tm])
|
||||||
latestDb = f
|
|
||||||
latestDbDate = tm
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(latestDbDate !== 0){
|
dbs.sort((a,b) => {
|
||||||
const db:Database = JSON.parse(Buffer.from(pako.inflate(await getFileData(ACCESS_TOKEN, latestDb.id))).toString('utf-8'))
|
return b[1] - a[1]
|
||||||
|
})
|
||||||
|
|
||||||
|
if(dbs.length !== 0){
|
||||||
|
let selectables:string[] = []
|
||||||
|
for(let i=0;i<dbs.length;i++){
|
||||||
|
selectables.push(`Backup saved in ${(new Date(dbs[i][1] * 1000)).toLocaleString()}`)
|
||||||
|
if(selectables.length > 7){
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const selectedIndex = (await alertSelect([language.loadLatest, language.loadOthers]) === '0') ? 0 : parseInt(await alertSelect(selectables))
|
||||||
|
const selectedDb = dbs[selectedIndex][0]
|
||||||
|
|
||||||
|
const db:Database = JSON.parse(Buffer.from(pako.inflate(await getFileData(ACCESS_TOKEN, selectedDb.id))).toString('utf-8'))
|
||||||
const requiredImages = (getUnpargeables(db))
|
const requiredImages = (getUnpargeables(db))
|
||||||
let ind = 0;
|
let ind = 0;
|
||||||
for(const images of requiredImages){
|
for(const images of requiredImages){
|
||||||
@@ -253,6 +264,9 @@ async function loadDrive(ACCESS_TOKEN:string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
location.search = ''
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkImageExist(image:string){
|
function checkImageExist(image:string){
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { loadLoreBookPrompt } from "../lorebook";
|
|||||||
import { findCharacterbyId, replacePlaceholders } from "../util";
|
import { findCharacterbyId, replacePlaceholders } from "../util";
|
||||||
import { requestChatData } from "./request";
|
import { requestChatData } from "./request";
|
||||||
import { stableDiff } from "./stableDiff";
|
import { stableDiff } from "./stableDiff";
|
||||||
import { processScript } from "./scripts";
|
import { processScript, processScriptFull } from "./scripts";
|
||||||
|
|
||||||
export interface OpenAIChat{
|
export interface OpenAIChat{
|
||||||
role: 'system'|'user'|'assistant'
|
role: 'system'|'user'|'assistant'
|
||||||
@@ -282,23 +282,26 @@ export async function sendChat(chatProcessIndex = -1):Promise<boolean> {
|
|||||||
}, 'model')
|
}, 'model')
|
||||||
|
|
||||||
let result = ''
|
let result = ''
|
||||||
|
let emoChanged = false
|
||||||
|
|
||||||
if(req.type === 'fail'){
|
if(req.type === 'fail'){
|
||||||
alertError(req.result)
|
alertError(req.result)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
result = reformatContent(req.result)
|
const result2 = processScriptFull(currentChar, reformatContent(req.result), 'editoutput')
|
||||||
|
result = result2.data
|
||||||
|
emoChanged = result2.emoChanged
|
||||||
db.characters[selectedChar].chats[selectedChat].message.push({
|
db.characters[selectedChar].chats[selectedChat].message.push({
|
||||||
role: 'char',
|
role: 'char',
|
||||||
data: result,
|
data: result,
|
||||||
saying: processScript(currentChar,currentChar.chaId, 'editoutput')
|
saying: currentChar.chaId
|
||||||
})
|
})
|
||||||
setDatabase(db)
|
setDatabase(db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(currentChar.viewScreen === 'emotion'){
|
if(currentChar.viewScreen === 'emotion' && (!emoChanged)){
|
||||||
|
|
||||||
let currentEmotion = currentChar.emotionImages
|
let currentEmotion = currentChar.emotionImages
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { DataBase } from "../database";
|
|||||||
import { checkNullish, selectSingleFile, sleep } from "../util";
|
import { checkNullish, selectSingleFile, sleep } from "../util";
|
||||||
import type { OpenAIChat } from ".";
|
import type { OpenAIChat } from ".";
|
||||||
import { globalFetch } from "../globalApi";
|
import { globalFetch } from "../globalApi";
|
||||||
|
import { selectedCharID } from "../stores";
|
||||||
|
|
||||||
export const customProviderStore = writable([] as string[])
|
export const customProviderStore = writable([] as string[])
|
||||||
|
|
||||||
@@ -107,6 +108,7 @@ export function getCurrentPluginMax(prov:string){
|
|||||||
|
|
||||||
let pluginWorker:Worker = null
|
let pluginWorker:Worker = null
|
||||||
let providerRes:{success:boolean, content:string} = null
|
let providerRes:{success:boolean, content:string} = null
|
||||||
|
let translatorRes:{success:boolean, content:string} = null
|
||||||
|
|
||||||
function postMsgPluginWorker(type:string, body:any){
|
function postMsgPluginWorker(type:string, body:any){
|
||||||
const bod = {
|
const bod = {
|
||||||
@@ -116,6 +118,8 @@ function postMsgPluginWorker(type:string, body:any){
|
|||||||
pluginWorker.postMessage(bod)
|
pluginWorker.postMessage(bod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let pluginTranslator = false
|
||||||
|
|
||||||
export async function loadPlugins() {
|
export async function loadPlugins() {
|
||||||
let db = get(DataBase)
|
let db = get(DataBase)
|
||||||
if(pluginWorker){
|
if(pluginWorker){
|
||||||
@@ -127,10 +131,12 @@ export async function loadPlugins() {
|
|||||||
const da = await fetch("/pluginApi.js")
|
const da = await fetch("/pluginApi.js")
|
||||||
const pluginApiString = await da.text()
|
const pluginApiString = await da.text()
|
||||||
let pluginjs = `${pluginApiString}\n`
|
let pluginjs = `${pluginApiString}\n`
|
||||||
|
let pluginLoadedJs = ''
|
||||||
|
|
||||||
for(const plug of db.plugins){
|
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'});
|
const blob = new Blob([pluginjs], {type: 'application/javascript'});
|
||||||
pluginWorker = new Worker(URL.createObjectURL(blob));
|
pluginWorker = new Worker(URL.createObjectURL(blob));
|
||||||
@@ -167,6 +173,31 @@ export async function loadPlugins() {
|
|||||||
}
|
}
|
||||||
break
|
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": {
|
case "fetch": {
|
||||||
postMsgPluginWorker('fetchData',{
|
postMsgPluginWorker('fetchData',{
|
||||||
id: data.body.id,
|
id: data.body.id,
|
||||||
@@ -199,6 +230,20 @@ export async function loadPlugins() {
|
|||||||
}
|
}
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
case "getChar":{
|
||||||
|
const db = get(DataBase)
|
||||||
|
const charid = get(selectedCharID)
|
||||||
|
const char = db.characters[charid]
|
||||||
|
postMsgPluginWorker('fetchData',{
|
||||||
|
id: data.body.id,
|
||||||
|
data: char
|
||||||
|
})
|
||||||
|
}
|
||||||
|
case "setChar":{
|
||||||
|
const db = get(DataBase)
|
||||||
|
const charid = get(selectedCharID)
|
||||||
|
db.characters[charid] = data.body
|
||||||
|
}
|
||||||
case "log":{
|
case "log":{
|
||||||
console.log(data.body)
|
console.log(data.body)
|
||||||
break
|
break
|
||||||
@@ -208,6 +253,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:{
|
export async function pluginProcess(arg:{
|
||||||
prompt_chat: OpenAIChat,
|
prompt_chat: OpenAIChat,
|
||||||
temperature: number,
|
temperature: number,
|
||||||
|
|||||||
@@ -1,15 +1,52 @@
|
|||||||
|
import { get } from "svelte/store";
|
||||||
|
import { CharEmotion, selectedCharID } from "../stores";
|
||||||
import type { character } from "../database";
|
import type { character } from "../database";
|
||||||
|
|
||||||
const dreg = /{{data}}/g
|
const dreg = /{{data}}/g
|
||||||
|
|
||||||
export function processScript(char:character, data:string, mode:'editinput'|'editoutput'|'editprocess'){
|
type ScriptMode = 'editinput'|'editoutput'|'editprocess'
|
||||||
|
|
||||||
|
export function processScript(char:character, data:string, mode:ScriptMode){
|
||||||
|
return processScriptFull(char, data, mode).data
|
||||||
|
}
|
||||||
|
|
||||||
|
export function processScriptFull(char:character, data:string, mode:ScriptMode){
|
||||||
|
let emoChanged = false
|
||||||
for (const script of char.customscript){
|
for (const script of char.customscript){
|
||||||
if(script.type === mode){
|
if(script.type === mode){
|
||||||
const reg = new RegExp(script.in,'g')
|
const reg = new RegExp(script.in,'g')
|
||||||
data = data.replace(reg, (v) => {
|
data = data.replace(reg, (v) => {
|
||||||
|
if(script.out.startsWith('@@emo ')){
|
||||||
|
if(char.viewScreen !== 'emotion'){
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
if(emoChanged){
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
const emoName = script.out.substring(6).trim()
|
||||||
|
let charemotions = get(CharEmotion)
|
||||||
|
let tempEmotion = charemotions[char.chaId]
|
||||||
|
if(!tempEmotion){
|
||||||
|
tempEmotion = []
|
||||||
|
}
|
||||||
|
if(tempEmotion.length > 4){
|
||||||
|
tempEmotion.splice(0, 1)
|
||||||
|
}
|
||||||
|
for(const emo of char.emotionImages){
|
||||||
|
if(emo[0] === emoName){
|
||||||
|
const emos:[string, string,number] = [emo[0], emo[1], Date.now()]
|
||||||
|
tempEmotion.push(emos)
|
||||||
|
charemotions[char.chaId] = tempEmotion
|
||||||
|
CharEmotion.set(charemotions)
|
||||||
|
emoChanged = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return v
|
||||||
|
}
|
||||||
return script.out.replace(dreg, v)
|
return script.out.replace(dreg, v)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return data
|
return {data, emoChanged}
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,34 @@
|
|||||||
import { Body,fetch,ResponseType } from "@tauri-apps/api/http"
|
import { Body,fetch,ResponseType } from "@tauri-apps/api/http"
|
||||||
import { isTauri } from "../globalApi"
|
import { isTauri } from "../globalApi"
|
||||||
|
import { translatorPlugin } from "../process/plugins"
|
||||||
|
|
||||||
let cache={
|
let cache={
|
||||||
origin: [''],
|
origin: [''],
|
||||||
trans: ['']
|
trans: ['']
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function translate(params:string, reverse:boolean) {
|
export async function translate(text:string, reverse:boolean) {
|
||||||
if(!isTauri){
|
if(!isTauri){
|
||||||
return params
|
return text
|
||||||
|
}
|
||||||
|
const plug = await translatorPlugin(text, reverse ? 'ko' : 'en', reverse ? 'en' : 'ko')
|
||||||
|
if(plug){
|
||||||
|
return plug.content
|
||||||
}
|
}
|
||||||
if(!reverse){
|
if(!reverse){
|
||||||
const ind = cache.origin.indexOf(params)
|
const ind = cache.origin.indexOf(text)
|
||||||
if(ind !== -1){
|
if(ind !== -1){
|
||||||
return cache.trans[ind]
|
return cache.trans[ind]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
const ind = cache.trans.indexOf(params)
|
const ind = cache.trans.indexOf(text)
|
||||||
if(ind !== -1){
|
if(ind !== -1){
|
||||||
return cache.origin[ind]
|
return cache.origin[ind]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return googleTrans(params, reverse)
|
|
||||||
|
return googleTrans(text, reverse)
|
||||||
}
|
}
|
||||||
|
|
||||||
async function googleTrans(text:string, reverse:boolean) {
|
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}[]}
|
const res = f.data as {sentences:{trans?:string}[]}
|
||||||
|
if(typeof(f.data) === 'string'){
|
||||||
|
return res as unknown as string
|
||||||
|
}
|
||||||
return res.sentences.filter((s) => 'trans' in s).map((s) => s.trans).join('');
|
return res.sentences.filter((s) => 'trans' in s).map((s) => s.trans).join('');
|
||||||
}
|
}
|
||||||
@@ -1 +1 @@
|
|||||||
{"version":"0.6.7"}
|
{"version":"0.7.0"}
|
||||||
|
|||||||
Reference in New Issue
Block a user