Merge branch 'kwaroran:main' into main

This commit is contained in:
aegkmq
2023-08-03 13:34:06 +09:00
committed by GitHub
66 changed files with 1062 additions and 509 deletions

160
src/ts/gui/colorscheme.ts Normal file
View File

@@ -0,0 +1,160 @@
import { get } from "svelte/store";
import { DataBase, setDatabase } from "../storage/database";
import { cloneDeep } from "lodash";
export interface ColorScheme{
bgcolor: string;
darkbg: string;
borderc: string;
selected: string;
draculared: string;
textcolor: string;
textcolor2: string;
darkBorderc: string;
darkbutton: string;
type:'light'|'dark';
}
export const defaultColorScheme: ColorScheme = {
bgcolor: "#282a36",
darkbg: "#21222c",
borderc: "#6272a4",
selected: "#44475a",
draculared: "#ff5555",
textcolor: "#f8f8f2",
textcolor2: "#64748b",
darkBorderc: "#4b5563",
darkbutton: "#374151",
type:'dark'
}
const colorShemes = {
"default": defaultColorScheme,
"light": {
bgcolor: "#f0f0f0",
darkbg: "#ffffff",
borderc: "#0f172a",
selected: "#e0e0e0",
draculared: "#ff5555",
textcolor: "#0f172a",
textcolor2: "#64748b",
darkBorderc: "#d1d5db",
darkbutton: "#e5e7eb",
type:'light'
},
"cherry": {
bgcolor: "#450a0a",
darkbg: "#7f1d1d",
borderc: "#ea580c",
selected: "#d97706",
draculared: "#ff5555",
textcolor: "#f8f8f2",
textcolor2: "#fca5a5",
darkBorderc: "#92400e",
darkbutton: "#b45309",
type:'dark'
},
"galaxy": {
bgcolor: "#0f172a",
darkbg: "#1f2a48",
borderc: "#8be9fd",
selected: "#457b9d",
draculared: "#ff5555",
textcolor: "#f8f8f2",
textcolor2: "#8be9fd",
darkBorderc: "#457b9d",
darkbutton: "#1f2a48",
type:'dark'
},
"nature": {
bgcolor: "#1b4332",
darkbg: "#2d6a4f",
borderc: "#a8dadc",
selected: "#4d908e",
draculared: "#ff5555",
textcolor: "#f8f8f2",
textcolor2: "#4d908e",
darkBorderc: "#457b9d",
darkbutton: "#2d6a4f",
type:'dark'
}
} as const
export const colorSchemeList = Object.keys(colorShemes) as (keyof typeof colorShemes)[]
export function changeColorScheme(colorScheme: string){
let db = get(DataBase)
db.colorScheme = cloneDeep(colorShemes[colorScheme])
db.colorSchemeName = colorScheme
setDatabase(db)
updateColorScheme()
}
export function updateColorScheme(){
let db = get(DataBase)
let colorScheme = db.colorScheme
if(colorScheme == null){
colorScheme = defaultColorScheme
}
//set css variables
document.documentElement.style.setProperty("--risu-theme-bgcolor", colorScheme.bgcolor);
document.documentElement.style.setProperty("--risu-theme-darkbg", colorScheme.darkbg);
document.documentElement.style.setProperty("--risu-theme-borderc", colorScheme.borderc);
document.documentElement.style.setProperty("--risu-theme-selected", colorScheme.selected);
document.documentElement.style.setProperty("--risu-theme-draculared", colorScheme.draculared);
document.documentElement.style.setProperty("--risu-theme-textcolor", colorScheme.textcolor);
document.documentElement.style.setProperty("--risu-theme-textcolor2", colorScheme.textcolor2);
document.documentElement.style.setProperty("--risu-theme-darkborderc", colorScheme.darkBorderc);
document.documentElement.style.setProperty("--risu-theme-darkbutton", colorScheme.darkbutton);
}
export function updateTextTheme(){
let db = get(DataBase)
const root = document.querySelector(':root') as HTMLElement;
if(!root){
return
}
switch(db.textTheme){
case "standard":{
if(db.colorScheme.type === 'dark'){
root.style.setProperty('--FontColorStandard', '#fafafa');
root.style.setProperty('--FontColorItalic', '#8C8D93');
root.style.setProperty('--FontColorBold', '#fafafa');
root.style.setProperty('--FontColorItalicBold', '#8C8D93');
}else{
root.style.setProperty('--FontColorStandard', '#0f172a');
root.style.setProperty('--FontColorItalic', '#8C8D93');
root.style.setProperty('--FontColorBold', '#0f172a');
root.style.setProperty('--FontColorItalicBold', '#8C8D93');
}
break
}
case "highcontrast":{
if(db.colorScheme.type === 'dark'){
root.style.setProperty('--FontColorStandard', '#f8f8f2');
root.style.setProperty('--FontColorItalic', '#F1FA8C');
root.style.setProperty('--FontColorBold', '#8BE9FD');
root.style.setProperty('--FontColorItalicBold', '#FFB86C');
}
else{
root.style.setProperty('--FontColorStandard', '#0f172a');
root.style.setProperty('--FontColorItalic', '#F1FA8C');
root.style.setProperty('--FontColorBold', '#8BE9FD');
root.style.setProperty('--FontColorItalicBold', '#FFB86C');
}
break
}
case "custom":{
root.style.setProperty('--FontColorStandard', db.customTextTheme.FontColorStandard);
root.style.setProperty('--FontColorItalic', db.customTextTheme.FontColorItalic);
root.style.setProperty('--FontColorBold', db.customTextTheme.FontColorBold);
root.style.setProperty('--FontColorItalicBold', db.customTextTheme.FontColorItalicBold);
break
}
}
}

View File

@@ -1,7 +1,7 @@
import { get, writable } from "svelte/store";
import { DataBase, setDatabase, type character } from "../storage/database";
import { CharEmotion, selectedCharID } from "../stores";
import { ChatTokenizer, tokenizeNum } from "../tokenizer";
import { ChatTokenizer, tokenize, tokenizeNum } from "../tokenizer";
import { language } from "../../lang";
import { alertError } from "../alert";
import { loadLoreBookPrompt } from "./lorebook";
@@ -169,7 +169,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
'personaPrompt':([] as OpenAIChat[])
}
if(!currentChar.utilityBot){
if((!currentChar.utilityBot) && (!db.promptTemplate)){
const mainp = currentChar.systemPrompt?.replaceAll('{{original}}', db.mainPrompt) || db.mainPrompt
@@ -255,10 +255,84 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
//await tokenize currernt
let currentTokens = db.maxResponse
for(const key in unformated){
const chats = unformated[key] as OpenAIChat[]
for(const chat of chats){
currentTokens += await tokenizer.tokenizeChat(chat)
if(db.promptTemplate){
const template = db.promptTemplate
async function tokenizeChatArray(chats:OpenAIChat[]){
for(const chat of chats){
const tokens = await tokenizer.tokenizeChat(chat)
currentTokens += tokens
}
}
for(const card of template){
switch(card.type){
case 'persona':{
await tokenizeChatArray(unformated.personaPrompt)
break
}
case 'description':{
await tokenizeChatArray(unformated.description)
break
}
case 'authornote':{
await tokenizeChatArray(unformated.authorNote)
break
}
case 'lorebook':{
await tokenizeChatArray(unformated.lorebook)
break
}
case 'plain':
case 'jailbreak':{
if((!db.jailbreakToggle) && (card.type === 'jailbreak')){
continue
}
const convertRole = {
"system": "system",
"user": "user",
"bot": "assistant"
} as const
let content = card.text
if(card.type2 === 'globalNote'){
content = (risuChatParser(currentChar.replaceGlobalNote?.replaceAll('{{original}}', content) || content, {chara:currentChar}))
}
else if(card.type2 === 'main'){
content = (risuChatParser(content, {chara: currentChar}))
}
else{
content = risuChatParser(content, {chara: currentChar})
}
const prompt:OpenAIChat ={
role: convertRole[card.role],
content: content
}
await tokenizeChatArray([prompt])
break
}
case 'chat':{
const start = card.rangeStart
const end = (card.rangeEnd === 'end') ? unformated.chats.length : card.rangeEnd
const chats = unformated.chats.slice(start, end)
await tokenizeChatArray(chats)
break
}
}
}
}
else{
for(const key in unformated){
const chats = unformated[key] as OpenAIChat[]
for(const chat of chats){
currentTokens += await tokenizer.tokenizeChat(chat)
}
}
}
@@ -293,10 +367,11 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
let ms = currentChat.message
const triggerResult = runTrigger(currentChar, 'start', {chat: currentChat})
const triggerResult = await runTrigger(currentChar, 'start', {chat: currentChat})
if(triggerResult){
currentChat = triggerResult.chat
ms = currentChat.message
currentTokens += triggerResult.tokens
}
for(const msg of ms){
@@ -406,42 +481,97 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
let formated:OpenAIChat[] = []
const formatOrder = cloneDeep(db.formatingOrder)
formatOrder.push('postEverything')
let sysPrompts:string[] = []
for(let i=0;i<formatOrder.length;i++){
const cha = unformated[formatOrder[i]]
if(cha.length === 1 && cha[0].content.length === 0){
continue
}
else if(cha.length === 1 && cha[0].role === 'system'){
sysPrompts.push(cha[0].content)
}
else if(sysPrompts.length > 0){
const prompt = sysPrompts.join('\n')
if(prompt.replace(/\n/g,'').length > 3){
formated.push({
role: 'system',
content: prompt
})
function pushPrompts(cha:OpenAIChat[]){
for(const chat of cha){
if(!chat.content){
continue
}
if(chat.role === 'system'){
const endf = formated.at(-1)
if(endf && endf.role === 'system' && endf.memo === chat.memo && endf.name === chat.name){
formated[formated.length - 1].content += '\n\n' + chat.content
}
else{
formated.push(chat)
}
formated.at(-1).content += ''
}
else{
formated.push(chat)
}
sysPrompts = []
formated = formated.concat(cha)
}
else{
formated = formated.concat(cha)
}
}
if(sysPrompts.length > 0){
const prompt = sysPrompts.join('\n')
if(db.promptTemplate){
const template = db.promptTemplate
if(prompt.replace(/\n/g,'').length > 3){
formated.push({
role: 'system',
content: prompt
})
for(const card of template){
switch(card.type){
case 'persona':{
pushPrompts(unformated.personaPrompt)
break
}
case 'description':{
pushPrompts(unformated.description)
break
}
case 'authornote':{
pushPrompts(unformated.authorNote)
break
}
case 'lorebook':{
pushPrompts(unformated.lorebook)
break
}
case 'plain':
case 'jailbreak':{
if((!db.jailbreakToggle) && (card.type === 'jailbreak')){
continue
}
const convertRole = {
"system": "system",
"user": "user",
"bot": "assistant"
} as const
let content = card.text
if(card.type2 === 'globalNote'){
content = (risuChatParser(currentChar.replaceGlobalNote?.replaceAll('{{original}}', content) || content, {chara:currentChar}))
}
else if(card.type2 === 'main'){
content = (risuChatParser(content, {chara: currentChar}))
}
else{
content = risuChatParser(content, {chara: currentChar})
}
const prompt:OpenAIChat ={
role: convertRole[card.role],
content: content
}
pushPrompts([prompt])
break
}
case 'chat':{
const start = card.rangeStart
const end = (card.rangeEnd === 'end') ? unformated.chats.length : card.rangeEnd
const chats = unformated.chats.slice(start, end)
pushPrompts(chats)
break
}
}
}
}
else{
for(let i=0;i<formatOrder.length;i++){
const cha = unformated[formatOrder[i]]
pushPrompts(cha)
}
sysPrompts = []
}
@@ -495,7 +625,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
}
}
const triggerResult = runTrigger(currentChar, 'output', {chat:currentChat})
const triggerResult = await runTrigger(currentChar, 'output', {chat:currentChat})
if(triggerResult){
db.characters[selectedChar].chats[selectedChat] = triggerResult.chat
setDatabase(db)
@@ -517,7 +647,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
saying: currentChar.chaId
})
db.characters[selectedChar].reloadKeys += 1
const triggerResult = runTrigger(currentChar, 'output', {chat:currentChat})
const triggerResult = await runTrigger(currentChar, 'output', {chat:currentChat})
if(triggerResult){
db.characters[selectedChar].chats[selectedChat] = triggerResult.chat
}

View File

@@ -205,6 +205,7 @@ export async function supaMemory(
const hypa = new HypaProcesser()
hypa.oaikey = db.supaMemoryKey
hypa.vectors = []
hypaChunks = hypaChunks.filter((value) => value.length > 1)
await hypa.addText(hypaChunks.filter((value, index, self) => {
return self.indexOf(value) === index;
}))

19
src/ts/process/proompt.ts Normal file
View File

@@ -0,0 +1,19 @@
export type Proompt = ProomptPlain|ProomptTyped|ProomptChat;
export interface ProomptPlain {
type: 'plain'|'jailbreak';
type2: 'normal'|'globalNote'|'main'
text: string;
role: 'user'|'bot'|'system';
}
export interface ProomptTyped {
type: 'persona'|'description'|'authornote'|'lorebook'
}
export interface ProomptChat {
type: 'chat';
rangeStart: number;
rangeEnd: number|'end';
}

View File

@@ -4,7 +4,7 @@ import { DataBase, setDatabase, type character } from "../storage/database";
import { pluginProcess } from "../plugins/plugins";
import { language } from "../../lang";
import { stringlizeAINChat, stringlizeChat, stringlizeChatOba, getStopStrings, unstringlizeAIN, unstringlizeChat } from "./stringlize";
import { globalFetch, isNodeServer, isTauri } from "../storage/globalApi";
import { addFetchLog, globalFetch, isNodeServer, isTauri } from "../storage/globalApi";
import { sleep } from "../util";
import { createDeep } from "./deepai";
import { hubURL } from "../characterCards";
@@ -213,6 +213,15 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model'
let throughProxi = (!isTauri) && (!isNodeServer) && (!db.usePlainFetch)
if(db.useStreaming && arg.useStreaming){
body.stream = true
let urlHost = new URL(replacerURL).host
if(urlHost.includes("localhost") || urlHost.includes("172.0.0.1") || urlHost.includes("0.0.0.0")){
if(!isTauri){
return {
type: 'fail',
result: 'You are trying local request on streaming. this is not allowed dude to browser/os security policy. turn off streaming.',
}
}
}
const da = (throughProxi)
? await fetch(hubURL + `/proxy2`, {
body: JSON.stringify(body),
@@ -246,6 +255,13 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model'
}
}
addFetchLog({
body: body,
response: "Streaming",
success: true,
url: replacerURL,
})
let dataUint = new Uint8Array([])
const transtream = new TransformStream<Uint8Array, string>( {

View File

@@ -1,6 +1,7 @@
import { cloneDeep } from "lodash";
import { getVarChat, risuChatParser } from "../parser";
import type { Chat, character } from "../storage/database";
import { tokenize } from "../tokenizer";
export interface triggerscript{
comment: string;
@@ -58,7 +59,7 @@ export type additonalSysPrompt = {
promptend: string
}
export function runTrigger(char:character,mode:triggerMode, arg:{
export async function runTrigger(char:character,mode:triggerMode, arg:{
chat?: Chat
} = {}){
char = cloneDeep(char)
@@ -189,6 +190,17 @@ export function runTrigger(char:character,mode:triggerMode, arg:{
if(arg.chat !== undefined && arg.chat !== null){
char.chats[char.chatPage] = chat
}
return {additonalSysPrompt, chat}
let caculatedTokens = 0
if(additonalSysPrompt.start){
caculatedTokens += await tokenize(additonalSysPrompt.start)
}
if(additonalSysPrompt.historyend){
caculatedTokens += await tokenize(additonalSysPrompt.historyend)
}
if(additonalSysPrompt.promptend){
caculatedTokens += await tokenize(additonalSysPrompt.promptend)
}
return {additonalSysPrompt, chat, tokens:caculatedTokens}
}

View File

@@ -9,10 +9,12 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '.
import { alertNormal } from '../alert';
import type { NAISettings } from '../process/models/nai';
import { prebuiltNAIpresets } from '../process/templates/templates';
import { defaultColorScheme, type ColorScheme } from '../gui/colorscheme';
import type { Proompt } from '../process/proompt';
export const DataBase = writable({} as any as Database)
export const loadedStore = writable(false)
export let appVer = '1.44.2'
export let appVer = '1.45.0'
export let webAppSubVer = ''
export function setDatabase(data:Database){
@@ -294,6 +296,8 @@ export function setDatabase(data:Database){
data.NAIsettings ??= cloneDeep(prebuiltNAIpresets)
data.assetWidth ??= -1
data.animationSpeed ??= 0.4
data.colorScheme ??= cloneDeep(defaultColorScheme)
data.colorSchemeName ??= 'default'
changeLanguage(data.language)
DataBase.set(data)
@@ -604,6 +608,9 @@ export interface Database{
botSettingAtStart:false
NAIsettings:NAISettings
hideRealm:boolean
colorScheme:ColorScheme
colorSchemeName:string
promptTemplate?:Proompt[]
}
interface hordeConfig{
@@ -789,37 +796,6 @@ export const defaultSdDataFunc = () =>{
return cloneDeep(defaultSdData)
}
export function updateTextTheme(){
let db = get(DataBase)
const root = document.querySelector(':root') as HTMLElement;
if(!root){
return
}
switch(db.textTheme){
case "standard":{
root.style.setProperty('--FontColorStandard', '#fafafa');
root.style.setProperty('--FontColorItalic', '#8C8D93');
root.style.setProperty('--FontColorBold', '#fafafa');
root.style.setProperty('--FontColorItalicBold', '#8C8D93');
break
}
case "highcontrast":{
root.style.setProperty('--FontColorStandard', '#f8f8f2');
root.style.setProperty('--FontColorItalic', '#F1FA8C');
root.style.setProperty('--FontColorBold', '#8BE9FD');
root.style.setProperty('--FontColorItalicBold', '#FFB86C');
break
}
case "custom":{
root.style.setProperty('--FontColorStandard', db.customTextTheme.FontColorStandard);
root.style.setProperty('--FontColorItalic', db.customTextTheme.FontColorItalic);
root.style.setProperty('--FontColorBold', db.customTextTheme.FontColorBold);
root.style.setProperty('--FontColorItalicBold', db.customTextTheme.FontColorItalicBold);
break
}
}
}
export function saveCurrentPreset(){
let db = get(DataBase)
let pres = db.botPresets

View File

@@ -5,7 +5,7 @@ import { v4 as uuidv4 } from 'uuid';
import { appDataDir, join } from "@tauri-apps/api/path";
import { get } from "svelte/store";
import {open} from '@tauri-apps/api/shell'
import { DataBase, loadedStore, setDatabase, type Database, updateTextTheme, defaultSdDataFunc } from "./database";
import { DataBase, loadedStore, setDatabase, type Database, defaultSdDataFunc } from "./database";
import { appWindow } from "@tauri-apps/api/window";
import { checkOldDomain, checkUpdate } from "../update";
import { botMakerMode, selectedCharID } from "../stores";
@@ -21,6 +21,7 @@ import { loadRisuAccountData } from "../drive/accounter";
import { decodeRisuSave, encodeRisuSave } from "./risuSave";
import { AutoStorage } from "./autoStorage";
import { updateAnimationSpeed } from "../gui/animation";
import { updateColorScheme, updateTextTheme } from "../gui/colorscheme";
//@ts-ignore
export const isTauri = !!window.__TAURI__
@@ -425,6 +426,7 @@ export async function loadData() {
}
await checkNewFormat()
const db = get(DataBase);
updateColorScheme()
updateTextTheme()
updateAnimationSpeed()
if(db.botSettingAtStart){
@@ -441,6 +443,23 @@ export async function loadData() {
const knownHostes = ["localhost","127.0.0.1"]
export function addFetchLog(arg:{
body:any,
headers?:{[key:string]:string},
response:any,
success:boolean,
url:string
}){
fetchLog.unshift({
body: JSON.stringify(arg.body, null, 2),
header: JSON.stringify(arg.headers ?? {}, null, 2),
response: JSON.stringify(arg.response, null, 2),
success: arg.success,
date: (new Date()).toLocaleTimeString(),
url: arg.url
})
}
export async function globalFetch(url:string, arg:{
plainFetchForce?:boolean,
body?:any,
@@ -492,6 +511,17 @@ export async function globalFetch(url:string, arg:{
const urlHost = (new URL(url)).hostname
let forcePlainFetch = (knownHostes.includes(urlHost) && (!isTauri)) || db.usePlainFetch || arg.plainFetchForce
console.log(urlHost)
//check if the url is a local url like localhost
if(urlHost.includes("localhost") || urlHost.includes("172.0.0.1") || urlHost.includes("0.0.0.0")){
return {
ok: false,
data: 'You are trying local request on web version. this is not allowed dude to browser security policy. use the desktop version instead, or use tunneling service like ngrok and set the cors to allow all.',
headers: {}
}
}
if(forcePlainFetch){
try {
let headers = arg.headers ?? {}