From b9bb38addf11749ecc75a20c037fb8d83fbbc8e2 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 9 Jun 2023 14:00:37 +0900 Subject: [PATCH 01/50] [fix] changed to workflow_dispatch --- .github/workflows/github-actions-builder.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/github-actions-builder.yml b/.github/workflows/github-actions-builder.yml index 0ca13031..25805faf 100644 --- a/.github/workflows/github-actions-builder.yml +++ b/.github/workflows/github-actions-builder.yml @@ -1,8 +1,5 @@ name: 'publish' -on: - push: - branches: - - main +on: [workflow_dispatch] jobs: publish-tauri: From a387e0db620b1dbd1bb9c5dbaba635e914063f6c Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 9 Jun 2023 14:10:47 +0900 Subject: [PATCH 02/50] [chore] add windows --- .github/workflows/github-actions-builder.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/github-actions-builder.yml b/.github/workflows/github-actions-builder.yml index 25805faf..c1c46f6d 100644 --- a/.github/workflows/github-actions-builder.yml +++ b/.github/workflows/github-actions-builder.yml @@ -8,7 +8,7 @@ jobs: strategy: fail-fast: false matrix: - platform: [ubuntu-latest,macos-latest] + platform: [ubuntu-latest,macos-latest,windows-latest] runs-on: ${{ matrix.platform }} steps: @@ -17,7 +17,12 @@ jobs: uses: actions/setup-node@v3 with: node-version: 18 + - id: set_var_win + if: matrix.platform == 'windows-latest' + run: | + choco install jq -y - id: set_var + shell: bash run: | echo "VERSION_JSON=$(jq -c . < version.json)" >> $GITHUB_ENV - name: install pnpm From cfe20c968b1c99924a3fa5a0cc7aab9a039e9b54 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 9 Jun 2023 14:29:07 +0900 Subject: [PATCH 03/50] [chore] cache build --- .github/workflows/github-actions-builder.yml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/github-actions-builder.yml b/.github/workflows/github-actions-builder.yml index c1c46f6d..89e54ae3 100644 --- a/.github/workflows/github-actions-builder.yml +++ b/.github/workflows/github-actions-builder.yml @@ -38,6 +38,25 @@ jobs: run: | sudo apt-get update sudo apt-get install -y libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev librsvg2-dev patchelf + - name: Get pnpm store directory + id: pnpm-cache + shell: bash + run: | + echo "STORE_PATH=$(pnpm store path)" >> $GITHUB_OUTPUT + - uses: actions/cache@v3 + name: Setup pnpm cache + with: + path: ${{ steps.pnpm-cache.outputs.STORE_PATH }} + key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} + restore-keys: | + ${{ runner.os }}-pnpm-store- + - uses: actions/cache@v3 + name: Setup rust cache + with: + path: src-tauri/target/ + key: ${{ runner.os }}-rust-cache + restore-keys: | + ${{ runner.os }}-rust-cache - name: install frontend dependencies run: pnpm install --no-frozen-lockfile # change this to npm or pnpm depending on which one you use - if: matrix.platform == 'ubuntu-latest' From dbf5f6b25a4ea6f53c0b25580766f7b02ef4ad18 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 9 Jun 2023 22:27:34 +0900 Subject: [PATCH 04/50] [feat] new tokenizing --- src/ts/process/exampleMessages.ts | 8 +++--- src/ts/process/index.ts | 44 +++++++++++++------------------ src/ts/process/stringlize.ts | 11 -------- src/ts/process/supaMemory.ts | 15 +++++------ src/ts/tokenizer.ts | 20 ++++++++++++++ 5 files changed, 51 insertions(+), 47 deletions(-) diff --git a/src/ts/process/exampleMessages.ts b/src/ts/process/exampleMessages.ts index 19debb23..0aa86704 100644 --- a/src/ts/process/exampleMessages.ts +++ b/src/ts/process/exampleMessages.ts @@ -2,7 +2,7 @@ import type { OpenAIChat } from "."; import type { character } from "../storage/database"; import { replacePlaceholders } from "../util"; -export function exampleMessage(char:character):OpenAIChat[]{ +export function exampleMessage(char:character, userName:string):OpenAIChat[]{ if(char.exampleMessage === ''){ return [] } @@ -34,14 +34,16 @@ export function exampleMessage(char:character):OpenAIChat[]{ add() currentMessage = { role: "assistant", - content: trimed.split(':', 2)[1] + content: trimed.split(':', 2)[1], + name: 'example_' + char.name } } else if(lowered.startsWith('{{user}}:') || lowered.startsWith(':')){ add() currentMessage = { role: "user", - content: trimed.split(':', 2)[1] + content: trimed.split(':', 2)[1], + name: 'example_' + userName } } else{ diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index 5df79a20..cee85fea 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -1,7 +1,7 @@ import { get, writable } from "svelte/store"; import { DataBase, setDatabase, type character } from "../storage/database"; import { CharEmotion, selectedCharID } from "../stores"; -import { tokenize, tokenizeNum } from "../tokenizer"; +import { ChatTokenizer, tokenizeNum } from "../tokenizer"; import { language } from "../../lang"; import { alertError } from "../alert"; import { loadLoreBookPrompt } from "./lorebook"; @@ -15,7 +15,6 @@ import { supaMemory } from "./supaMemory"; import { v4 } from "uuid"; import { cloneDeep } from "lodash"; import { groupOrder } from "./group"; -import { getNameMaxTokens } from "./stringlize"; export interface OpenAIChat{ role: 'system'|'user'|'assistant' @@ -69,7 +68,6 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n if(nowChatroom.type === 'group'){ if(chatProcessIndex === -1){ const charNames =nowChatroom.characters.map((v) => findCharacterbyIdwithCache(v).name) - caculatedChatTokens += await getNameMaxTokens([...charNames, db.username]) const messages = nowChatroom.chats[nowChatroom.chatPage].message const lastMessage = messages[messages.length-1] @@ -110,14 +108,10 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n } else{ currentChar = nowChatroom - if(!db.aiModel.startsWith('gpt')){ - caculatedChatTokens += await getNameMaxTokens([currentChar.name, db.username]) - } - } let chatAdditonalTokens = arg.chatAdditonalTokens ?? caculatedChatTokens - + const tokenizer = new ChatTokenizer(chatAdditonalTokens, db.aiModel.startsWith('gpt') ? 'noName' : 'name') let selectedChat = nowChatroom.chatPage let currentChat = nowChatroom.chats[selectedChat] let maxContextTokens = db.maxContext @@ -205,17 +199,17 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n }) //await tokenize currernt - let currentTokens = (await tokenize(Object.keys(unformated).map((key) => { - return (unformated[key] as OpenAIChat[]).map((d) => { - return d.content - }).join('\n\n') - }).join('\n\n')) + db.maxResponse) + 130 + let currentTokens = 0 + + for(const key in unformated){ + currentTokens += await tokenizer.tokenizeChat(unformated[key]) + } - const examples = exampleMessage(currentChar) + const examples = exampleMessage(currentChar, db.username) for(const example of examples){ - currentTokens += await tokenize(example.content) + chatAdditonalTokens + currentTokens += await tokenizer.tokenizeChat(example) } let chats:OpenAIChat[] = examples @@ -230,15 +224,14 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n if(nowChatroom.type !== 'group'){ const firstMsg = nowChatroom.firstMsgIndex === -1 ? nowChatroom.firstMessage : nowChatroom.alternateGreetings[nowChatroom.firstMsgIndex] - chats.push({ + const chat:OpenAIChat = { role: 'assistant', content: processScript(currentChar, replacePlaceholders(firstMsg, currentChar.name), 'editprocess') - }) - currentTokens += await tokenize(processScript(currentChar, - replacePlaceholders(firstMsg, currentChar.name), - 'editprocess')) + } + chats.push(chat) + currentTokens += await tokenizer.tokenizeChat(chat) } const ms = currentChat.message @@ -259,17 +252,18 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n if(!msg.chatId){ msg.chatId = v4() } - chats.push({ + const chat:OpenAIChat = { role: msg.role === 'user' ? 'user' : 'assistant', content: formedChat, memo: msg.chatId, name: name - }) - currentTokens += (await tokenize(formedChat) + chatAdditonalTokens) + } + chats.push(chat) + currentTokens += await tokenizer.tokenizeChat(chat) } if(nowChatroom.supaMemory && db.supaMemoryType !== 'none'){ - const sp = await supaMemory(chats, currentTokens, maxContextTokens, currentChat, nowChatroom, chatAdditonalTokens) + const sp = await supaMemory(chats, currentTokens, maxContextTokens, currentChat, nowChatroom, tokenizer) if(sp.error){ alertError(sp.error) return false @@ -287,7 +281,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n return false } - currentTokens -= (await tokenize(chats[0].content) + chatAdditonalTokens) + currentTokens -= await tokenizer.tokenizeChat(chats[0]) chats.splice(0, 1) } currentChat.lastMemory = chats[0].memo diff --git a/src/ts/process/stringlize.ts b/src/ts/process/stringlize.ts index 140389b6..fe608a09 100644 --- a/src/ts/process/stringlize.ts +++ b/src/ts/process/stringlize.ts @@ -53,15 +53,4 @@ export function unstringlizeChat(text:string, formated:OpenAIChat[], char:string } return text -} - -export async function getNameMaxTokens(names:string[]){ - let maxCharNameTokens = 0 - for(const name of names){ - const tokens = await tokenize(name + ': ') + 1 - if(maxCharNameTokens < tokens){ - maxCharNameTokens = tokens - } - } - return maxCharNameTokens } \ No newline at end of file diff --git a/src/ts/process/supaMemory.ts b/src/ts/process/supaMemory.ts index d3b5748a..11862ce7 100644 --- a/src/ts/process/supaMemory.ts +++ b/src/ts/process/supaMemory.ts @@ -1,8 +1,7 @@ import { get } from "svelte/store"; import type { OpenAIChat } from "."; import { DataBase, type Chat, type character, type groupChat } from "../storage/database"; -import { tokenize } from "../tokenizer"; -import { findCharacterbyId } from "../util"; +import { tokenize, type ChatTokenizer } from "../tokenizer"; import { requestChatData } from "./request"; export async function supaMemory( @@ -11,7 +10,7 @@ export async function supaMemory( maxContextTokens:number, room:Chat, char:character|groupChat, - chatAdditonalTokens:number + tokenizer:ChatTokenizer ): Promise<{ currentTokens: number; chats: OpenAIChat[]; error?:string; memory?:string;lastId?:string}>{ const db = get(DataBase) @@ -27,7 +26,7 @@ export async function supaMemory( } if(coIndex !== -1){ for(let i=0;i maxChunkSize){ if(stringlizedChat === ''){ stringlizedChat += `${cont.role === 'assistant' ? char.type === 'group' ? '' : char.name : db.username}: ${cont.content}\n\n` @@ -201,7 +200,7 @@ export async function supaMemory( return result } - const tokenz = await tokenize(result + '\n\n') + chatAdditonalTokens + const tokenz = await tokenize(result + '\n\n') currentTokens += tokenz supaMemory += result.replace(/\n+/g,'\n') + '\n\n' } diff --git a/src/ts/tokenizer.ts b/src/ts/tokenizer.ts index 032a9460..1cd1280f 100644 --- a/src/ts/tokenizer.ts +++ b/src/ts/tokenizer.ts @@ -2,6 +2,7 @@ import type { Tiktoken } from "@dqbd/tiktoken"; import { DataBase, type character } from "./storage/database"; import { get } from "svelte/store"; import { tokenizeTransformers } from "./transformers/transformer"; +import type { OpenAIChat } from "./process"; async function encode(data:string):Promise<(number[]|Uint32Array)>{ let db = get(DataBase) @@ -37,6 +38,25 @@ export async function tokenize(data:string) { return encoded.length } + +export class ChatTokenizer { + + private chatAdditonalTokens:number + private useName:'name'|'noName' + + constructor(chatAdditonalTokens:number, useName:'name'|'noName'){ + this.chatAdditonalTokens = chatAdditonalTokens + this.useName = useName + } + async tokenizeChat(data:OpenAIChat) { + const encoded = (await encode(data.content)).length + + this.useName === 'name' ? (await encode(data.name)).length : 0 + this.chatAdditonalTokens + return encoded + } + + +} + export async function tokenizeNum(data:string) { const encoded = await encode(data) return encoded From e2b49b21dcbe80abb0f072991f3712f0574d27b8 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 10 Jun 2023 01:45:33 +0900 Subject: [PATCH 05/50] [fix] not working groupchat regex --- src/ts/process/index.ts | 4 ++-- src/ts/process/scripts.ts | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index cee85fea..21d1adbb 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -226,7 +226,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n const chat:OpenAIChat = { role: 'assistant', - content: processScript(currentChar, + content: processScript(nowChatroom, replacePlaceholders(firstMsg, currentChar.name), 'editprocess') } @@ -236,7 +236,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n const ms = currentChat.message for(const msg of ms){ - let formedChat = processScript(currentChar,replacePlaceholders(msg.data, currentChar.name), 'editprocess') + let formedChat = processScript(nowChatroom,replacePlaceholders(msg.data, currentChar.name), 'editprocess') let name = '' if(msg.role === 'char'){ if(msg.saying){ diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts index 105a171e..aa8084d7 100644 --- a/src/ts/process/scripts.ts +++ b/src/ts/process/scripts.ts @@ -1,6 +1,6 @@ import { get } from "svelte/store"; import { CharEmotion, selectedCharID } from "../stores"; -import { DataBase, setDatabase, type character, type customscript } from "../storage/database"; +import { DataBase, setDatabase, type character, type customscript, type groupChat } from "../storage/database"; import { downloadFile } from "../storage/globalApi"; import { alertError, alertNormal } from "../alert"; import { language } from "src/lang"; @@ -11,7 +11,7 @@ const randomness = /\|\|\|/g type ScriptMode = 'editinput'|'editoutput'|'editprocess'|'editdisplay' -export function processScript(char:character, data:string, mode:ScriptMode){ +export function processScript(char:character|groupChat, data:string, mode:ScriptMode){ return processScriptFull(char, data, mode).data } @@ -52,7 +52,7 @@ export async function importRegex(){ } } -export function processScriptFull(char:character, data:string, mode:ScriptMode){ +export function processScriptFull(char:character|groupChat, data:string, mode:ScriptMode){ let db = get(DataBase) let emoChanged = false const scripts = (db.globalscript ?? []).concat(char.customscript) From e88f95102bb6662447488c2bb46011bb0907ab55 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 10 Jun 2023 01:48:12 +0900 Subject: [PATCH 06/50] [fix] group chat cut not working --- src/ts/process/index.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index 21d1adbb..eac048aa 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -385,7 +385,9 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n const readed = (await reader.read()) if(readed.value){ result = readed.value - db.characters[selectedChar].chats[selectedChat].message[msgIndex].data = result + const result2 = processScriptFull(nowChatroom, reformatContent(result), 'editoutput') + db.characters[selectedChar].chats[selectedChat].message[msgIndex].data = result2.data + emoChanged = result2.emoChanged setDatabase(db) } if(readed.done){ @@ -395,7 +397,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n await sayTTS(currentChar, result) } else{ - const result2 = processScriptFull(currentChar, reformatContent(req.result), 'editoutput') + const result2 = processScriptFull(nowChatroom, reformatContent(req.result), 'editoutput') result = result2.data emoChanged = result2.emoChanged db.characters[selectedChar].chats[selectedChat].message.push({ From 6fc60805e6eadb6cc722e0929909e5107a704311 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 10 Jun 2023 02:27:54 +0900 Subject: [PATCH 07/50] [fix] tokenizer --- src/ts/tokenizer.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ts/tokenizer.ts b/src/ts/tokenizer.ts index 1cd1280f..52717d66 100644 --- a/src/ts/tokenizer.ts +++ b/src/ts/tokenizer.ts @@ -49,8 +49,10 @@ export class ChatTokenizer { this.useName = useName } async tokenizeChat(data:OpenAIChat) { - const encoded = (await encode(data.content)).length - + this.useName === 'name' ? (await encode(data.name)).length : 0 + this.chatAdditonalTokens + let encoded = (await encode(data.content)).length + this.chatAdditonalTokens + if(data.name && this.useName ==='name'){ + encoded += (await encode(data.name)).length + } return encoded } From 08cd214bcbd662fc41bee7e74c3798c033e219bd Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 10 Jun 2023 02:38:36 +0900 Subject: [PATCH 08/50] [fix] tokenizer problem 2 --- src/lib/ChatScreens/DefaultChatScreen.svelte | 1 + src/ts/process/index.ts | 5 ++++- src/ts/tokenizer.ts | 1 + 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/lib/ChatScreens/DefaultChatScreen.svelte b/src/lib/ChatScreens/DefaultChatScreen.svelte index 28afd787..30db6bee 100644 --- a/src/lib/ChatScreens/DefaultChatScreen.svelte +++ b/src/lib/ChatScreens/DefaultChatScreen.svelte @@ -144,6 +144,7 @@ try { await sendChat() } catch (error) { + console.error(error) alertError(`${error}`) } rerolls.push(cloneDeep($DataBase.characters[$selectedCharID].chats[$DataBase.characters[$selectedCharID].chatPage].message)) diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index eac048aa..f2447726 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -202,7 +202,10 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n let currentTokens = 0 for(const key in unformated){ - currentTokens += await tokenizer.tokenizeChat(unformated[key]) + const chats = unformated[key] as OpenAIChat[] + for(const chat of chats){ + currentTokens += await tokenizer.tokenizeChat(chat) + } } diff --git a/src/ts/tokenizer.ts b/src/ts/tokenizer.ts index 52717d66..2d162bd7 100644 --- a/src/ts/tokenizer.ts +++ b/src/ts/tokenizer.ts @@ -49,6 +49,7 @@ export class ChatTokenizer { this.useName = useName } async tokenizeChat(data:OpenAIChat) { + console.log(data.content) let encoded = (await encode(data.content)).length + this.chatAdditonalTokens if(data.name && this.useName ==='name'){ encoded += (await encode(data.name)).length From 42c013474416628672595874ebdb99417d3ff586 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 10 Jun 2023 02:41:51 +0900 Subject: [PATCH 09/50] bump version to 1.24.3 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 84f6bfc5..032dbf93 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.24.2" + "version": "1.24.3" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 74931499..deb9afa3 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -8,7 +8,7 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '. export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.24.2' +export let appVer = '1.24.3' export function setDatabase(data:Database){ if(checkNullish(data.characters)){ diff --git a/version.json b/version.json index bb93f1ee..5de17429 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.24.2"} \ No newline at end of file +{"version":"1.24.3"} \ No newline at end of file From 077623b23d0c8f2983796dd51ce8e3110118676f Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 10 Jun 2023 09:22:05 +0900 Subject: [PATCH 10/50] [fix] max response error --- src/ts/process/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index f2447726..690825a8 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -199,7 +199,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n }) //await tokenize currernt - let currentTokens = 0 + let currentTokens = db.maxResponse for(const key in unformated){ const chats = unformated[key] as OpenAIChat[] From a4eefa2c0dd6024e15e2b46edd1d89beea976f60 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 10 Jun 2023 09:23:06 +0900 Subject: [PATCH 11/50] bump version to 1.24.4 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 032dbf93..4349c47b 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.24.3" + "version": "1.24.4" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index deb9afa3..4798decb 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -8,7 +8,7 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '. export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.24.3' +export let appVer = '1.24.4' export function setDatabase(data:Database){ if(checkNullish(data.characters)){ diff --git a/version.json b/version.json index 5de17429..1394159b 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.24.3"} \ No newline at end of file +{"version":"1.24.4"} \ No newline at end of file From 32f58fef1d3e28652079943ba37b5c4da0e3fb56 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sat, 10 Jun 2023 10:32:52 +0900 Subject: [PATCH 12/50] examples --- src/ts/process/exampleMessages.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ts/process/exampleMessages.ts b/src/ts/process/exampleMessages.ts index 0aa86704..8802de1d 100644 --- a/src/ts/process/exampleMessages.ts +++ b/src/ts/process/exampleMessages.ts @@ -35,7 +35,7 @@ export function exampleMessage(char:character, userName:string):OpenAIChat[]{ currentMessage = { role: "assistant", content: trimed.split(':', 2)[1], - name: 'example_' + char.name + name: 'example_assistant' } } else if(lowered.startsWith('{{user}}:') || lowered.startsWith(':')){ @@ -43,7 +43,7 @@ export function exampleMessage(char:character, userName:string):OpenAIChat[]{ currentMessage = { role: "user", content: trimed.split(':', 2)[1], - name: 'example_' + userName + name: 'example_user' } } else{ From 49a01a0950054aeb6dc6756cb010bcbf2ca5f763 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 11 Jun 2023 11:04:11 +0900 Subject: [PATCH 13/50] [fix] image compression --- src/lang/cn.ts | 1 + src/lang/en.ts | 3 +- src/lang/ko.ts | 2 + src/lib/Setting/Pages/AdvancedSettings.svelte | 4 + src/ts/characterCards.ts | 9 +- src/ts/parser.ts | 104 +++++++++++++++++- src/ts/storage/database.ts | 4 + 7 files changed, 120 insertions(+), 7 deletions(-) diff --git a/src/lang/cn.ts b/src/lang/cn.ts index 1cf72cb1..46769e87 100644 --- a/src/lang/cn.ts +++ b/src/lang/cn.ts @@ -308,4 +308,5 @@ export const languageChinese = { recent: '最新', downloads: '下载量', trending: "热度", + imageCompression: "图像压缩" } \ No newline at end of file diff --git a/src/lang/en.ts b/src/lang/en.ts index 14a67f82..196d81fd 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -311,6 +311,7 @@ export const languageEnglish = { enterMessageForTranslateToEnglish: "Enter Message for Translate to English", recent: 'Recent', downloads: 'Downloads', - trending: "Trending" + trending: "Trending", + imageCompression: "Image Compression" } \ No newline at end of file diff --git a/src/lang/ko.ts b/src/lang/ko.ts index dd6aa543..a7c8d10e 100644 --- a/src/lang/ko.ts +++ b/src/lang/ko.ts @@ -281,4 +281,6 @@ export const languageKorean = { useChatCopy: "채팅 메시지 복사 사용", autoTranslateInput: "입력 자동 번역", enterMessageForTranslateToEnglish: "영어로 번역할 메시지를 입력해주세요", + imageCompression: "이미지 압축" + } \ No newline at end of file diff --git a/src/lib/Setting/Pages/AdvancedSettings.svelte b/src/lib/Setting/Pages/AdvancedSettings.svelte index 1c6fef69..33a9dbc0 100644 --- a/src/lib/Setting/Pages/AdvancedSettings.svelte +++ b/src/lib/Setting/Pages/AdvancedSettings.svelte @@ -53,6 +53,10 @@ {language.showUnrecommended} +
+ + {language.imageCompression} +
{language.useExperimental} diff --git a/src/ts/characterCards.ts b/src/ts/characterCards.ts index ef7603d6..f282e8d1 100644 --- a/src/ts/characterCards.ts +++ b/src/ts/characterCards.ts @@ -11,6 +11,7 @@ import { characterFormatUpdate } from "./characters" import { checkCharOrder, downloadFile, readImage, saveAsset } from "./storage/globalApi" import { cloneDeep } from "lodash" import { selectedCharID } from "./stores" +import { convertImage } from "./parser" export const hubURL = import.meta.env.DEV ? "http://127.0.0.1:8787" : "https://sv.risuai.xyz" @@ -532,7 +533,7 @@ export async function exportSpecV2(char:character) { msg: `Loading... (Adding Emotions ${i} / ${card.data.extensions.risuai.emotions.length})` }) const rData = await readImage(card.data.extensions.risuai.emotions[i][1]) - char.emotionImages[i][1] = Buffer.from(rData).toString('base64') + char.emotionImages[i][1] = Buffer.from(await convertImage(rData)).toString('base64') } } @@ -544,7 +545,7 @@ export async function exportSpecV2(char:character) { msg: `Loading... (Adding Additional Assets ${i} / ${card.data.extensions.risuai.additionalAssets.length})` }) const rData = await readImage(card.data.extensions.risuai.additionalAssets[i][1]) - char.additionalAssets[i][1] = Buffer.from(rData).toString('base64') + char.additionalAssets[i][1] = Buffer.from(await convertImage(rData)).toString('base64') } } @@ -611,7 +612,7 @@ export async function shareRisuHub(char:character, arg:{ }) const data = card.data.extensions.risuai.emotions[i][1] const rData = await readImage(data) - resources.push([data, Buffer.from(rData).toString('base64')]) + resources.push([data, Buffer.from(await convertImage(rData)).toString('base64')]) } } @@ -626,7 +627,7 @@ export async function shareRisuHub(char:character, arg:{ }) const data = card.data.extensions.risuai.additionalAssets[i][1] const rData = await readImage(data) - resources.push([data, Buffer.from(rData).toString('base64')]) + resources.push([data, Buffer.from(await convertImage(rData)).toString('base64')]) } } diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 25ef1dd7..00f8a971 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -1,8 +1,9 @@ import DOMPurify from 'isomorphic-dompurify'; import showdown from 'showdown'; -import type { character, groupChat } from './storage/database'; +import { DataBase, type character, type groupChat } from './storage/database'; import { getFileSrc } from './storage/globalApi'; import { processScript } from './process/scripts'; +import { get } from 'svelte/store'; const convertor = new showdown.Converter({ simpleLineBreaks: true, @@ -65,4 +66,103 @@ export function parseMarkdownSafe(data:string) { export async function hasher(data:Uint8Array){ return Buffer.from(await crypto.subtle.digest("SHA-256", data)).toString('hex'); -} \ No newline at end of file +} + +export async function convertImage(data:Uint8Array) { + if(!get(DataBase).imageCompression){ + return data + } + const type = checkImageType(data) + if(type !== 'Unknown' && type !== 'WEBP' && type !== 'AVIF'){ + if(type === 'PNG' && isAPNG(data)){ + return data + } + + console.log('converting') + return await resizeAndConvert(data) + } + return data +} + +async function resizeAndConvert(imageData: Uint8Array): Promise { + return new Promise((resolve, reject) => { + const base64Image = 'data:image/png;base64,' + Buffer.from(imageData).toString('base64'); + const image = new Image(); + image.onload = () => { + URL.revokeObjectURL(base64Image); + + // Create a canvas + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + if (!context) { + throw new Error('Unable to get 2D context'); + } + + // Compute the new dimensions while maintaining aspect ratio + let { width, height } = image; + if (width > 3000 || height > 3000) { + const aspectRatio = width / height; + if (width > height) { + width = 3000; + height = Math.round(width / aspectRatio); + } else { + height = 3000; + width = Math.round(height * aspectRatio); + } + } + + // Resize and draw the image to the canvas + canvas.width = width; + canvas.height = height; + context.drawImage(image, 0, 0, width, height); + + // Try to convert to WebP + let base64 = canvas.toDataURL('image/webp', 90); + + // If WebP is not supported, convert to JPEG + if (base64.indexOf('data:image/webp') != 0) { + base64 = canvas.toDataURL('image/jpeg', 90); + } + + // Convert it to Uint8Array + const array = Buffer.from(base64.split(',')[1], 'base64'); + resolve(array); + }; + image.src = base64Image; + }); +} + +type ImageType = 'JPEG' | 'PNG' | 'GIF' | 'BMP' | 'AVIF' | 'WEBP' | 'Unknown'; + +function checkImageType(arr:Uint8Array):ImageType { + const isJPEG = arr[0] === 0xFF && arr[1] === 0xD8 && arr[arr.length-2] === 0xFF && arr[arr.length-1] === 0xD9; + const isPNG = arr[0] === 0x89 && arr[1] === 0x50 && arr[2] === 0x4E && arr[3] === 0x47 && arr[4] === 0x0D && arr[5] === 0x0A && arr[6] === 0x1A && arr[7] === 0x0A; + const isGIF = arr[0] === 0x47 && arr[1] === 0x49 && arr[2] === 0x46 && arr[3] === 0x38 && (arr[4] === 0x37 || arr[4] === 0x39) && arr[5] === 0x61; + const isBMP = arr[0] === 0x42 && arr[1] === 0x4D; + const isAVIF = arr[4] === 0x66 && arr[5] === 0x74 && arr[6] === 0x79 && arr[7] === 0x70 && arr[8] === 0x61 && arr[9] === 0x76 && arr[10] === 0x69 && arr[11] === 0x66; + const isWEBP = arr[0] === 0x52 && arr[1] === 0x49 && arr[2] === 0x46 && arr[3] === 0x46 && arr[8] === 0x57 && arr[9] === 0x45 && arr[10] === 0x42 && arr[11] === 0x50; + + if (isJPEG) return "JPEG"; + if (isPNG) return "PNG"; + if (isGIF) return "GIF"; + if (isBMP) return "BMP"; + if (isAVIF) return "AVIF"; + if (isWEBP) return "WEBP"; + return "Unknown"; +} + +function isAPNG(pngData: Uint8Array): boolean { + const pngSignature = [0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A]; + const acTL = [0x61, 0x63, 0x54, 0x4C]; + + if (!pngData.slice(0, pngSignature.length).every((v, i) => v === pngSignature[i])) { + throw new Error('Invalid PNG data'); + } + + for (let i = pngSignature.length; i < pngData.length - 12; i += 4) { + if (pngData.slice(i + 4, i + 8).every((v, j) => v === acTL[j])) { + return true; + } + } + return false; +} \ No newline at end of file diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 4798decb..af82986e 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -257,6 +257,9 @@ export function setDatabase(data:Database){ if(checkNullish(data.autoSuggestPrompt)){ data.autoSuggestPrompt = defaultAutoSuggestPrompt } + if(checkNullish(data.imageCompression)){ + data.imageCompression = true + } changeLanguage(data.language) DataBase.set(data) @@ -505,6 +508,7 @@ export interface Database{ useChatCopy:boolean, novellistAPI:string, useAutoTranslateInput:boolean + imageCompression:boolean } interface hordeConfig{ From c829a539fc4c4a83139902ee96dd17f95dc466fe Mon Sep 17 00:00:00 2001 From: LL Date: Mon, 12 Jun 2023 07:20:42 +0900 Subject: [PATCH 14/50] Accessibility settings to the app Screen reader readable "Show Help" button. Also added a new checkbox for accessibility settings. --- src/lang/cn.ts | 1 + src/lang/en.ts | 1 + src/lang/ko.ts | 1 + src/lib/Others/Check.svelte | 15 +++++--- src/lib/Others/Help.svelte | 9 +++-- .../Pages/AccessibilitySettings.svelte | 15 +++----- src/lib/Setting/Pages/AdvancedSettings.svelte | 9 ++--- src/lib/Setting/Pages/BotSettings.svelte | 6 ++-- src/lib/Setting/Pages/DisplaySettings.svelte | 35 +++++++------------ src/lib/Setting/Pages/LanguageSettings.svelte | 8 ++--- src/lib/Setting/Pages/OtherBotSettings.svelte | 3 +- src/lib/SideBars/CharConfig.svelte | 20 +++++------ src/lib/SideBars/LoreBookData.svelte | 13 ++++--- src/lib/SideBars/LoreBookSetting.svelte | 13 +++---- 14 files changed, 65 insertions(+), 84 deletions(-) diff --git a/src/lang/cn.ts b/src/lang/cn.ts index 1cf72cb1..cb0c9c0f 100644 --- a/src/lang/cn.ts +++ b/src/lang/cn.ts @@ -19,6 +19,7 @@ export const languageChinese = { onlyOneChat: '必须至少有一次聊天', alreadyCharInGroup: "群组中已存在同名的角色。" }, + showHelp: "显示帮助", help:{ model: "模型选项是用于聊天的主要模型。", submodel: "辅助模型是用于分析情绪图像,自动建议等的模型。推荐使用gpt3.5。", diff --git a/src/lang/en.ts b/src/lang/en.ts index 14a67f82..5239e9a0 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -19,6 +19,7 @@ export const languageEnglish = { onlyOneChat: 'There must be least one chat', alreadyCharInGroup: "There is already a character with the same name in the group." }, + showHelp: "Show Help", help:{ model: "Model option is a main model used in chat.", submodel: "Auxiliary Model is a model that used in analizing emotion images and auto suggestions and etc. gpt3.5 is recommended.", diff --git a/src/lang/ko.ts b/src/lang/ko.ts index dd6aa543..2ce41086 100644 --- a/src/lang/ko.ts +++ b/src/lang/ko.ts @@ -149,6 +149,7 @@ export const languageKorean = { ShowLog: "리퀘스트 로그 보기", waifuWidth2: "Waifu 캐릭터 크기", sayNothing:"어떤 문자열도 입력되지 않을 시 'say nothing' 입력", + showHelp: "도움말 보기", help:{ model: "채팅에서 사용되는 모델입니다.", submodel: "보조 모델은 감정 이미지, 자동 제안등을 분석하는 데 사용되는 모델입니다. gpt3.5가 권장됩니다.", diff --git a/src/lib/Others/Check.svelte b/src/lib/Others/Check.svelte index f1d8c23e..59d053a5 100644 --- a/src/lib/Others/Check.svelte +++ b/src/lib/Others/Check.svelte @@ -4,17 +4,22 @@ export let check = false export let onChange = (check) => {} export let margin = true + export let name = '' + export let hiddenName = false -
{/if} {/if} From 2de284f4e918cf288de5b2c5e9c46d4da6a4b2b1 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 12 Jun 2023 12:27:01 +0900 Subject: [PATCH 15/50] [feat] data sync --- src/lang/en.ts | 6 +- src/lib/Setting/Pages/UserSettings.svelte | 73 ++++++++- src/ts/drive/accounter.ts | 53 +++++- src/ts/drive/drive.ts | 189 +++++++++++++++++----- src/ts/storage/database.ts | 9 ++ src/ts/storage/globalApi.ts | 9 +- src/ts/tokenizer.ts | 1 - 7 files changed, 296 insertions(+), 44 deletions(-) diff --git a/src/lang/en.ts b/src/lang/en.ts index 196d81fd..a0eaa200 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -312,6 +312,10 @@ export const languageEnglish = { recent: 'Recent', downloads: 'Downloads', trending: "Trending", - imageCompression: "Image Compression" + imageCompression: "Image Compression", + notLoggedIn: "Not Logged in to Risu Account", + googleDriveInfo: "Connect to google drive to sync your data.", + googleDriveConnection: "Google Drive Connection", + googleDriveConnected: "Google Drive Connected" } \ No newline at end of file diff --git a/src/lib/Setting/Pages/UserSettings.svelte b/src/lib/Setting/Pages/UserSettings.svelte index 09dbe862..163a767e 100644 --- a/src/lib/Setting/Pages/UserSettings.svelte +++ b/src/lib/Setting/Pages/UserSettings.svelte @@ -1,10 +1,40 @@ - + { + if(e.origin.startsWith("https://sv.risuai.xyz") || e.origin.startsWith("http://127.0.0.1")){ + if(e.data.msg.type === 'drive'){ + console.log(e.data.msg) + await loadRisuAccountData() + $DataBase.account.data.refresh_token = e.data.msg.data.refresh_token + $DataBase.account.data.access_token = e.data.msg.data.access_token + $DataBase.account.data.expires_in = (e.data.msg.data.expires_in * 700) + Date.now() + await saveRisuAccountData() + popup.close() + } + else if(e.data.msg.data.vaild){ + openIframe = false + $DataBase.account = { + id: e.data.msg.id, + token: e.data.msg.token, + data: e.data.msg.data + } + } + } +}}> +

{language.user}

+ {language.userIcon} {language.username} +{#if $DataBase.useExperimental} +
+
+

Risu Account{#if $DataBase.account} + + {/if}

+
+ {#if $DataBase.account} + ID: {$DataBase.account.id} +

{language.googleDriveConnection}

+ {#if !$DataBase.account.data.refresh_token} + {language.googleDriveInfo} + + {:else} + {language.googleDriveConnected} + {/if} + {:else} + {language.notLoggedIn} + + {/if} +
+{/if} +{#if openIframe} +
+ +
+{/if} \ No newline at end of file diff --git a/src/ts/drive/accounter.ts b/src/ts/drive/accounter.ts index 8772558c..4f4128c1 100644 --- a/src/ts/drive/accounter.ts +++ b/src/ts/drive/accounter.ts @@ -1,3 +1,52 @@ -async function loginWithGoogle() { - +import { get } from "svelte/store" +import { hubURL } from "../characterCards" +import { DataBase } from "../storage/database" +import { alertError } from "../alert" + +export async function risuLogin() { + const win = window.open(hubURL + '/hub/login') + window.addEventListener("message", (ev) => { + console.log(ev) + const data = JSON.parse(ev.data) + console.log(data) + win.close() + }) +} + +export async function saveRisuAccountData() { + const db = get(DataBase) + if(!db.account){ + alertError("Not logged in error") + return + } + const s = await fetch(hubURL + '/hub/account/save', { + method: "POST", + body: JSON.stringify({ + token: db.account.token, + save: db.account.data + }) + }) + if(s.status !== 200){ + alertError(await s.text()) + return + } +} + +export async function loadRisuAccountData() { + const db = get(DataBase) + if(!db.account){ + alertError("Not logged in error") + return + } + const s = await fetch(hubURL + '/hub/account/load', { + method: "POST", + body: JSON.stringify({ + token: db.account.token + }) + }) + if(s.status !== 200){ + alertError(await s.text()) + return + } + db.account.data = await s.json() } \ No newline at end of file diff --git a/src/ts/drive/drive.ts b/src/ts/drive/drive.ts index aa6fd430..451a26df 100644 --- a/src/ts/drive/drive.ts +++ b/src/ts/drive/drive.ts @@ -7,10 +7,13 @@ import { BaseDirectory, exists, readBinaryFile, readDir, writeBinaryFile } from import { language } from "../../lang"; import { relaunch } from '@tauri-apps/api/process'; import { open } from '@tauri-apps/api/shell'; +import { cloneDeep, isEqual, last } from "lodash"; +import { sleep } from "../util"; +import { hubURL } from "../characterCards"; export async function checkDriver(type:'save'|'load'|'loadtauri'|'savetauri'|'reftoken'){ const CLIENT_ID = '580075990041-l26k2d3c0nemmqiu3d3aag01npfrkn76.apps.googleusercontent.com'; - const REDIRECT_URI = (isTauri || isNodeServer) ? "https://risuai.xyz/" : `https://${location.host}/` + const REDIRECT_URI = 'reftoken' ? 'https://sv.risuai.xyz/drive' : ((isTauri || isNodeServer) ? "https://risuai.xyz/" : `https://${location.host}/`) const SCOPE = 'https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.appdata'; const encodedRedirectUri = encodeURIComponent(REDIRECT_URI); const authorizationUrl = `https://accounts.google.com/o/oauth2/auth?client_id=${CLIENT_ID}&redirect_uri=${encodedRedirectUri}&scope=${SCOPE}&response_type=code&state=${type}`; @@ -18,8 +21,7 @@ export async function checkDriver(type:'save'|'load'|'loadtauri'|'savetauri'|'re if(type === 'reftoken'){ const authorizationUrl = `https://accounts.google.com/o/oauth2/auth?client_id=${CLIENT_ID}&redirect_uri=${encodedRedirectUri}&scope=${SCOPE}&response_type=code&state=${"accesstauri"}&access_type=offline&prompt=consent`; - openURL(authorizationUrl) - return + return authorizationUrl } if(type === 'save' || type === 'load'){ @@ -39,7 +41,7 @@ export async function checkDriver(type:'save'|'load'|'loadtauri'|'savetauri'|'re code = code.substring(code.lastIndexOf(' ')).trim() } if(type === 'loadtauri'){ - await loadDrive(code) + await loadDrive(code, 'backup') } else{ await backupDrive(code) @@ -69,7 +71,7 @@ export async function checkDriverInit() { await backupDrive(json.access_token) } else if(da === 'load'){ - await loadDrive(json.access_token) + await loadDrive(json.access_token, 'backup') } else if(da === 'savetauri' || da === 'loadtauri'){ alertStore.set({ @@ -101,8 +103,79 @@ export async function checkDriverInit() { } } +let lastSaved:number = parseInt(localStorage.getItem('risu_lastsaved') ?? '-1') +let BackupDb:Database = null +export async function syncDrive() { + BackupDb = cloneDeep(get(DataBase)) + while(true){ + const maindb = get(DataBase) + if(maindb?.account?.data?.access_token && maindb?.account?.data?.refresh_token && maindb?.account?.data?.expires_in){ + if(maindb.account.data.expires_in < Date.now()){ + if(!maindb.account){ + alertError("Not logged in error") + return + } + const s = await fetch(hubURL + '/drive/refresh', { + method: "POST", + body: JSON.stringify({ + token: maindb.account.token + }) + }) + if(s.status !== 200){ + alertError(await s.text()) + return + } + maindb.account.data = await s.json() + } + const ACCESS_TOKEN = maindb.account.data.access_token + await loadDrive(ACCESS_TOKEN, 'sync') + if(!isEqual(maindb, BackupDb)){ + BackupDb = cloneDeep(maindb) + const files:DriveFile[] = await getFilesInFolder(ACCESS_TOKEN) + const fileNames = files.map((d) => { + return d.name + }) + if(isTauri){ + const assets = await readDir('assets', {dir: BaseDirectory.AppData}) + let i = 0; + for(let asset of assets){ + i += 1; + const key = asset.name + if(!key || !key.endsWith('.png')){ + continue + } + const formatedKey = formatKeys(key) + if(!fileNames.includes(formatedKey)){ + await createFileInFolder(ACCESS_TOKEN, formatedKey, await readBinaryFile(asset.path)) + } + } + } + else{ + const keys = await forageStorage.keys() + + for(let i=0;i { + return b[1] - a[1] + }) + } + else if(mode === 'sync'){ + for(const f of files){ + if(f.name.endsWith("-database.risudat2")){ + const tm = parseInt(f.name.split('-')[0]) + if(isNaN(tm)){ + continue + } + else if(tm > lastSaved){ + dbs.push([f,tm]) + } + } + } + dbs.sort((a,b) => { + return b[1] - a[1] + }) } - dbs.sort((a,b) => { - return b[1] - a[1] - }) if(dbs.length !== 0){ - let selectables:string[] = [] - for(let i=0;i 7){ - break - } + if(mode === 'sync'){ + alertStore.set({ + type: "wait", + msg: "Sync Data..." + }) } - 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')) + async function getDbFromList(){ + let selectables:string[] = [] + for(let i=0;i 7){ + break + } + } + const selectedIndex = (await alertSelect([language.loadLatest, language.loadOthers]) === '0') ? 0 : parseInt(await alertSelect(selectables)) + const selectedDb = dbs[selectedIndex][0] + const decompressedDb:Database = JSON.parse(Buffer.from(pako.inflate(await getFileData(ACCESS_TOKEN, selectedDb.id))).toString('utf-8')) + return decompressedDb + } + + const db:Database = mode === 'backup' ? await getDbFromList() : JSON.parse(Buffer.from(await getFileData(ACCESS_TOKEN, dbs[0][0].id)).toString('utf-8')) + lastSaved = Date.now() + localStorage.setItem('risu_lastsaved', `${lastSaved}`) const requiredImages = (getUnpargeables(db)) let ind = 0; for(const images of requiredImages){ ind += 1 const formatedImage = formatKeys(images) - alertStore.set({ - type: "wait", - msg: `Loading Backup... (${ind} / ${requiredImages.length})` - }) + if(mode === 'sync'){ + alertStore.set({ + type: "wait", + msg: `Sync Files... (${ind} / ${requiredImages.length})` + }) + } + else{ + alertStore.set({ + type: "wait", + msg: `Loading Backup... (${ind} / ${requiredImages.length})` + }) + } if(await checkImageExists(images)){ //skip process } @@ -276,7 +389,7 @@ async function loadDrive(ACCESS_TOKEN:string) { relaunch() alertStore.set({ type: "wait", - msg: "Success, Refresh your app." + msg: "Success, Refreshing your app." }) } else{ @@ -284,11 +397,11 @@ async function loadDrive(ACCESS_TOKEN:string) { location.search = '' alertStore.set({ type: "wait", - msg: "Success, Refresh your app." + msg: "Success, Refreshing your app." }) } } - else{ + else if(mode === 'backup'){ location.search = '' } } diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index af82986e..a6e47615 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -509,6 +509,15 @@ export interface Database{ novellistAPI:string, useAutoTranslateInput:boolean imageCompression:boolean + account?:{ + token:string + id:string, + data: { + refresh_token?:string, + access_token?:string + expires_in?: number + } + } } interface hordeConfig{ diff --git a/src/ts/storage/globalApi.ts b/src/ts/storage/globalApi.ts index 386d63cf..eaf307d6 100644 --- a/src/ts/storage/globalApi.ts +++ b/src/ts/storage/globalApi.ts @@ -14,12 +14,13 @@ import { selectedCharID } from "../stores"; import { Body, ResponseType, fetch as TauriFetch } from "@tauri-apps/api/http"; import { loadPlugins } from "../process/plugins"; import { alertError, alertStore } from "../alert"; -import { checkDriverInit } from "../drive/drive"; +import { checkDriverInit, syncDrive } from "../drive/drive"; import { hasher } from "../parser"; import { characterHubImport } from "../characterCards"; import { cloneDeep } from "lodash"; import { NodeStorage } from "./nodeStorage"; import { defaultJailbreak, defaultMainPrompt, oldJailbreak, oldMainPrompt } from "./defaultPrompts"; +import { loadRisuAccountData } from "../drive/accounter"; //@ts-ignore export const isTauri = !!window.__TAURI__ @@ -195,6 +196,7 @@ let lastSave = '' export async function saveDb(){ lastSave =JSON.stringify(get(DataBase)) + syncDrive() while(true){ const dbjson = JSON.stringify(get(DataBase)) if(dbjson !== lastSave){ @@ -358,6 +360,11 @@ export async function loadData() { } catch (error) {} await checkNewFormat() updateTextTheme() + if(get(DataBase).account){ + try { + await loadRisuAccountData() + } catch (error) {} + } loadedStore.set(true) selectedCharID.set(-1) saveDb() diff --git a/src/ts/tokenizer.ts b/src/ts/tokenizer.ts index 2d162bd7..52717d66 100644 --- a/src/ts/tokenizer.ts +++ b/src/ts/tokenizer.ts @@ -49,7 +49,6 @@ export class ChatTokenizer { this.useName = useName } async tokenizeChat(data:OpenAIChat) { - console.log(data.content) let encoded = (await encode(data.content)).length + this.chatAdditonalTokens if(data.name && this.useName ==='name'){ encoded += (await encode(data.name)).length From 5f93b88cca3262888a91a735e6413738d1d82268 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 12 Jun 2023 12:31:39 +0900 Subject: [PATCH 16/50] [feat] data sync first setup message --- src/ts/drive/drive.ts | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/ts/drive/drive.ts b/src/ts/drive/drive.ts index 451a26df..3ae41756 100644 --- a/src/ts/drive/drive.ts +++ b/src/ts/drive/drive.ts @@ -130,8 +130,9 @@ export async function syncDrive() { maindb.account.data = await s.json() } const ACCESS_TOKEN = maindb.account.data.access_token - await loadDrive(ACCESS_TOKEN, 'sync') - if(!isEqual(maindb, BackupDb)){ + const d = await loadDrive(ACCESS_TOKEN, 'sync') + const hadNoSync = d === 'noSync' + if((!isEqual(maindb, BackupDb)) || hadNoSync){ BackupDb = cloneDeep(maindb) const files:DriveFile[] = await getFilesInFolder(ACCESS_TOKEN) const fileNames = files.map((d) => { @@ -142,6 +143,12 @@ export async function syncDrive() { let i = 0; for(let asset of assets){ i += 1; + if(hadNoSync){ + alertStore.set({ + type: "wait", + msg: `Uploading Sync Files... (${i} / ${assets.length})` + }) + } const key = asset.name if(!key || !key.endsWith('.png')){ continue @@ -156,6 +163,12 @@ export async function syncDrive() { const keys = await forageStorage.keys() for(let i=0;i { if(mode === 'backup'){ alertStore.set({ type: "wait", @@ -278,6 +292,7 @@ async function loadDrive(ACCESS_TOKEN:string, mode: 'backup'|'sync') { let dbs:[DriveFile,number][] = [] + let noSyncData = true if(mode === 'backup'){ for(const f of files){ @@ -302,8 +317,11 @@ async function loadDrive(ACCESS_TOKEN:string, mode: 'backup'|'sync') { if(isNaN(tm)){ continue } - else if(tm > lastSaved){ - dbs.push([f,tm]) + else{ + if(tm > lastSaved){ + dbs.push([f,tm]) + } + noSyncData = false } } } @@ -312,6 +330,10 @@ async function loadDrive(ACCESS_TOKEN:string, mode: 'backup'|'sync') { }) } + if(noSyncData && mode === 'sync'){ + return 'noSync' + } + if(dbs.length !== 0){ if(mode === 'sync'){ alertStore.set({ From a715bb61345f28de04b0c647176d0b347155c09d Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 12 Jun 2023 12:33:20 +0900 Subject: [PATCH 17/50] bump version to 1.25.0 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 4349c47b..5b1b5d28 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.24.4" + "version": "1.25.0" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index a6e47615..f58e3cc7 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -8,7 +8,7 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '. export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.24.4' +export let appVer = '1.25.0' export function setDatabase(data:Database){ if(checkNullish(data.characters)){ diff --git a/version.json b/version.json index 1394159b..f211eb9f 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.24.4"} \ No newline at end of file +{"version":"1.25.0"} \ No newline at end of file From d59adc7ce76738aa18d36e70fede1540cf823033 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 12 Jun 2023 12:34:01 +0900 Subject: [PATCH 18/50] [chore] remove rust cache --- .github/workflows/github-actions-builder.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/workflows/github-actions-builder.yml b/.github/workflows/github-actions-builder.yml index 89e54ae3..4f5ac4df 100644 --- a/.github/workflows/github-actions-builder.yml +++ b/.github/workflows/github-actions-builder.yml @@ -50,13 +50,6 @@ jobs: key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }} restore-keys: | ${{ runner.os }}-pnpm-store- - - uses: actions/cache@v3 - name: Setup rust cache - with: - path: src-tauri/target/ - key: ${{ runner.os }}-rust-cache - restore-keys: | - ${{ runner.os }}-rust-cache - name: install frontend dependencies run: pnpm install --no-frozen-lockfile # change this to npm or pnpm depending on which one you use - if: matrix.platform == 'ubuntu-latest' From 134cb6a3befb10da6b8ea922de1b9403deee6a53 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 12 Jun 2023 12:52:46 +0900 Subject: [PATCH 19/50] [fix] first setup message appearing every time --- src/ts/drive/drive.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ts/drive/drive.ts b/src/ts/drive/drive.ts index 3ae41756..b4356ff9 100644 --- a/src/ts/drive/drive.ts +++ b/src/ts/drive/drive.ts @@ -183,7 +183,9 @@ export async function syncDrive() { lastSaved = Math.floor(Date.now() / 1000) localStorage.setItem('risu_lastsaved', `${lastSaved}`) await createFileInFolder(ACCESS_TOKEN, `${lastSaved}-database.risudat2`, Buffer.from(dbjson, 'utf-8')) - alertNormal("First Setup Success") + if(hadNoSync){ + alertNormal("First Setup Success") + } } } await sleep(3000) From 7b2a2dbbdb3426d1220fa2add8d3b7d04f5e3957 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 12 Jun 2023 12:53:07 +0900 Subject: [PATCH 20/50] bump version to 1.25.1 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 5b1b5d28..3ce1a29a 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.25.0" + "version": "1.25.1" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index f58e3cc7..2ff957ed 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -8,7 +8,7 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '. export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.25.0' +export let appVer = '1.25.1' export function setDatabase(data:Database){ if(checkNullish(data.characters)){ diff --git a/version.json b/version.json index f211eb9f..37be02f4 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.25.0"} \ No newline at end of file +{"version":"1.25.1"} \ No newline at end of file From 70caeea1696c75d584bc9329fee1bdcc2a717556 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 12 Jun 2023 13:30:00 +0900 Subject: [PATCH 21/50] [fix] backup not working --- src-tauri/tauri.conf.json | 2 +- src/ts/drive/drive.ts | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 3ce1a29a..147b0f52 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.25.1" + "version": "1.25.2" }, "tauri": { "allowlist": { diff --git a/src/ts/drive/drive.ts b/src/ts/drive/drive.ts index b4356ff9..6092caee 100644 --- a/src/ts/drive/drive.ts +++ b/src/ts/drive/drive.ts @@ -13,7 +13,7 @@ import { hubURL } from "../characterCards"; export async function checkDriver(type:'save'|'load'|'loadtauri'|'savetauri'|'reftoken'){ const CLIENT_ID = '580075990041-l26k2d3c0nemmqiu3d3aag01npfrkn76.apps.googleusercontent.com'; - const REDIRECT_URI = 'reftoken' ? 'https://sv.risuai.xyz/drive' : ((isTauri || isNodeServer) ? "https://risuai.xyz/" : `https://${location.host}/`) + const REDIRECT_URI = type === 'reftoken' ? 'https://sv.risuai.xyz/drive' : ((isTauri || isNodeServer) ? "https://risuai.xyz/" : `https://${location.host}/`) const SCOPE = 'https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.appdata'; const encodedRedirectUri = encodeURIComponent(REDIRECT_URI); const authorizationUrl = `https://accounts.google.com/o/oauth2/auth?client_id=${CLIENT_ID}&redirect_uri=${encodedRedirectUri}&scope=${SCOPE}&response_type=code&state=${type}`; diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 2ff957ed..775f3baa 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -8,7 +8,7 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '. export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.25.1' +export let appVer = '1.25.2' export function setDatabase(data:Database){ if(checkNullish(data.characters)){ diff --git a/version.json b/version.json index 37be02f4..c7167750 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.25.1"} \ No newline at end of file +{"version":"1.25.2"} \ No newline at end of file From 316d3be39776a9c371642ac2bd5e0b8a0232c3f6 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 12 Jun 2023 18:53:37 +0900 Subject: [PATCH 22/50] [feat] regex flags, fix display --- src/lib/SideBars/RegexData.svelte | 17 +++++++++++++++-- src/ts/parser.ts | 6 +++--- src/ts/process/group.ts | 6 ++++-- src/ts/process/scripts.ts | 2 +- src/ts/storage/database.ts | 10 ++++++---- 5 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/lib/SideBars/RegexData.svelte b/src/lib/SideBars/RegexData.svelte index 4bdc4392..4271a96b 100644 --- a/src/lib/SideBars/RegexData.svelte +++ b/src/lib/SideBars/RegexData.svelte @@ -3,6 +3,7 @@ import { language } from "src/lang"; import { alertConfirm } from "src/ts/alert"; import type { customscript } from "src/ts/storage/database"; + import Check from "../Others/Check.svelte"; export let value:customscript export let onRemove: () => void = () => {} @@ -26,10 +27,10 @@ {#if open} -
+
{language.name} - Type + Modification Type OUT: + {#if value.ableFlag} + FLAG: + + {/if} +
+ { + if(!value.flag){ + value.flag = 'g' + } + }}/> + Custom Flag +
{/if}
diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 00f8a971..6c114eb4 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -35,9 +35,6 @@ DOMPurify.addHook("uponSanitizeAttribute", (node, data) => { export async function ParseMarkdown(data:string, char:(character | groupChat) = null, mode:'normal'|'back' = 'normal') { if(char && char.type !== 'group'){ - if(char.customscript){ - data = processScript(char, data, 'editdisplay') - } if(char.additionalAssets){ for(const asset of char.additionalAssets){ const assetPath = await getFileSrc(asset[1]) @@ -51,6 +48,9 @@ export async function ParseMarkdown(data:string, char:(character | groupChat) = } } } + if(char){ + data = processScript(char, data, 'editdisplay') + } return DOMPurify.sanitize(convertor.makeHtml(data), { ADD_TAGS: ["iframe"], ADD_ATTR: ["allow", "allowfullscreen", "frameborder", "scrolling"], diff --git a/src/ts/process/group.ts b/src/ts/process/group.ts index 5af16c31..00706f45 100644 --- a/src/ts/process/group.ts +++ b/src/ts/process/group.ts @@ -63,7 +63,6 @@ export function groupOrder(chars:GroupOrder[], input:string):GroupOrder[] { for (const word of words) { for (let char of chars) { const charNameChunks = getWords(findCharacterbyId(char.id).name) - console.log(charNameChunks) if (charNameChunks.includes(word)) { order.push(char); @@ -96,8 +95,11 @@ export function groupOrder(chars:GroupOrder[], input:string):GroupOrder[] { } function getWords(data:string){ - const matches = data.match(/\b\w+\b/gmi) + const matches = data.split(/\n| /g) let words:string[] = [] + if(!matches){ + return [data] + } for(const match of matches){ words.push(match.toLocaleLowerCase()) } diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts index aa8084d7..827e6af6 100644 --- a/src/ts/process/scripts.ts +++ b/src/ts/process/scripts.ts @@ -58,7 +58,7 @@ export function processScriptFull(char:character|groupChat, data:string, mode:Sc const scripts = (db.globalscript ?? []).concat(char.customscript) for (const script of scripts){ if(script.type === mode){ - const reg = new RegExp(script.in,'g') + const reg = new RegExp(script.in, script.ableFlag ? script.flag : 'g') const outScript = script.out if(outScript.startsWith('@@') && reg.test(data)){ if(outScript.startsWith('@@emo ')){ diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 775f3baa..ac20313a 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -267,10 +267,12 @@ export function setDatabase(data:Database){ export interface customscript{ - comment: string; - in:string - out:string - type:string + comment: string; + in:string + out:string + type:string + flag?:string + ableFlag?:boolean } From 174594532c594c9da37a7db49a524aa84ebc35bc Mon Sep 17 00:00:00 2001 From: kwaroran Date: Mon, 12 Jun 2023 18:58:43 +0900 Subject: [PATCH 23/50] [feat] added gif in some selects --- src/lib/SideBars/CharConfig.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte index 5f3894b8..35d02629 100644 --- a/src/lib/SideBars/CharConfig.svelte +++ b/src/lib/SideBars/CharConfig.svelte @@ -611,7 +611,7 @@ + diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index 690825a8..b8366a49 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -121,6 +121,11 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n maxContextTokens = 4000 } } + if(db.aiModel === 'gpt35_16k'){ + if(maxContextTokens > 16000){ + maxContextTokens = 16000 + } + } if(db.aiModel === 'gpt4'){ if(maxContextTokens > 8000){ maxContextTokens = 8000 diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index e4ae002d..cea4dbb6 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -57,6 +57,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' switch(aiModel){ case 'gpt35': + case 'gpt35_16k': case 'gpt4': case 'gpt4_32k':{ @@ -69,6 +70,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' const body = ({ model: aiModel === 'gpt35' ? 'gpt-3.5-turbo' + : aiModel === 'gpt35_16k' ? 'gpt-3.5-turbo-16k' : aiModel === 'gpt4' ? 'gpt-4' : 'gpt-4-32k', messages: formated, temperature: temperature, From 3237ca234479467719b4fa63a0a83dc5f4e9eb27 Mon Sep 17 00:00:00 2001 From: LL Date: Wed, 14 Jun 2023 04:17:43 +0900 Subject: [PATCH 27/50] [feat] Update AI model settings for GPT-3.5 and add GPT-3.5 Turbo 16k option The commit updates AI model settings for GPT-3.5 by allowing up to 4000 tokens for context size. It also adds a new option for GPT-3.5 Turbo 16k with a maximum context of 16000 tokens. Additionally, the commit limits the context size when exceeding the maximum limit for each model. --- src/lib/Setting/Pages/BotSettings.svelte | 4 +++- src/lib/UI/ModelList.svelte | 6 ++++++ src/ts/process/index.ts | 5 +++++ src/ts/process/request.ts | 4 ++++ 4 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/lib/Setting/Pages/BotSettings.svelte b/src/lib/Setting/Pages/BotSettings.svelte index 4650f3fd..2cb2ab01 100644 --- a/src/lib/Setting/Pages/BotSettings.svelte +++ b/src/lib/Setting/Pages/BotSettings.svelte @@ -110,7 +110,7 @@ Claude {language.apiKey} {/if} -{#if $DataBase.aiModel === 'gpt35' || $DataBase.aiModel === 'gpt4' || $DataBase.subModel === 'gpt4' || $DataBase.subModel === 'gpt35'|| $DataBase.aiModel === 'gpt4_32k' || $DataBase.subModel === 'gpt4_32k'} +{#if $DataBase.aiModel === 'gpt35' || $DataBase.aiModel === 'gpt35_16k_0613' || $DataBase.subModel === 'gpt35_16k_0613' || $DataBase.aiModel === 'gpt35_16k' || $DataBase.subModel === 'gpt35_16k' || $DataBase.aiModel === 'gpt4' || $DataBase.subModel === 'gpt4' || $DataBase.subModel === 'gpt35'|| $DataBase.aiModel === 'gpt4_32k' || $DataBase.subModel === 'gpt4_32k'} OpenAI {language.apiKey}
@@ -166,6 +166,8 @@ {language.maxContextSize} {#if $DataBase.aiModel === 'gpt35'} +{:else if $DataBase.aiModel === 'gpt35_16k' || $DataBase.aiModel === 'gpt35_16k_0613'} + {:else if $DataBase.aiModel === 'gpt4' || $DataBase.aiModel === 'textgen_webui'} {:else if $DataBase.aiModel === 'custom'} diff --git a/src/lib/UI/ModelList.svelte b/src/lib/UI/ModelList.svelte index ddcd9d8a..09cb5114 100644 --- a/src/lib/UI/ModelList.svelte +++ b/src/lib/UI/ModelList.svelte @@ -13,6 +13,10 @@ switch(name){ case "gpt35": return "GPT-3.5 Turbo" + case "gpt35_16k": + return "GPT-3.5 Turbo 16k" + case "gpt35_16k_0613": + return "GPT-3.5 Turbo 16k 0613" case "gpt4": return "GPT-4" case "gpt4_32k": @@ -52,6 +56,8 @@
+ + diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index 690825a8..ee1a432e 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -121,6 +121,11 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n maxContextTokens = 4000 } } + if(db.aiModel === 'gpt35_16k' || db.aiModel === 'gpt35_16k_0613'){ + if(maxContextTokens > 16000){ + maxContextTokens = 16000 + } + } if(db.aiModel === 'gpt4'){ if(maxContextTokens > 8000){ maxContextTokens = 8000 diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index e4ae002d..3dbe86c2 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -57,6 +57,8 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' switch(aiModel){ case 'gpt35': + case 'gpt35_16k': + case 'gpt35_16k_0613': case 'gpt4': case 'gpt4_32k':{ @@ -69,6 +71,8 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' const body = ({ model: aiModel === 'gpt35' ? 'gpt-3.5-turbo' + : aiModel === 'gpt35_16k' ? 'gpt-3.5-turbo-16k' + : aiModel === 'gpt35_16k_0613' ? 'gpt-3.5-turbo-16k-0613' : aiModel === 'gpt4' ? 'gpt-4' : 'gpt-4-32k', messages: formated, temperature: temperature, From e45483a8c6fd2d4a30fc744ea0ed99e5e6e8b908 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 14 Jun 2023 10:24:00 +0900 Subject: [PATCH 28/50] bump version to 1.25.4 --- src-tauri/tauri.conf.json | 2 +- src/js/DragDropTouch.js | 486 ------------------------------------- src/ts/parser.ts | 3 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- vite.config.ts | 3 +- 6 files changed, 6 insertions(+), 492 deletions(-) delete mode 100644 src/js/DragDropTouch.js diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 270e3930..4b817ec2 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.25.3" + "version": "1.25.4" }, "tauri": { "allowlist": { diff --git a/src/js/DragDropTouch.js b/src/js/DragDropTouch.js deleted file mode 100644 index 96b458ae..00000000 --- a/src/js/DragDropTouch.js +++ /dev/null @@ -1,486 +0,0 @@ -// The MIT License (MIT) - -// Copyright (c) 2016 Bernardo Castilho - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -//@ts-nocheck -var DragDropTouch; -(function (DragDropTouch_1) { - 'use strict'; - /** - * Object used to hold the data that is being dragged during drag and drop operations. - * - * It may hold one or more data items of different types. For more information about - * drag and drop operations and data transfer objects, see - * HTML Drag and Drop API. - * - * This object is created automatically by the @see:DragDropTouch singleton and is - * accessible through the @see:dataTransfer property of all drag events. - */ - var DataTransfer = (function () { - function DataTransfer() { - this._dropEffect = 'move'; - this._effectAllowed = 'all'; - this._data = {}; - } - Object.defineProperty(DataTransfer.prototype, "dropEffect", { - /** - * Gets or sets the type of drag-and-drop operation currently selected. - * The value must be 'none', 'copy', 'link', or 'move'. - */ - get: function () { - return this._dropEffect; - }, - set: function (value) { - this._dropEffect = value; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(DataTransfer.prototype, "effectAllowed", { - /** - * Gets or sets the types of operations that are possible. - * Must be one of 'none', 'copy', 'copyLink', 'copyMove', 'link', - * 'linkMove', 'move', 'all' or 'uninitialized'. - */ - get: function () { - return this._effectAllowed; - }, - set: function (value) { - this._effectAllowed = value; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(DataTransfer.prototype, "types", { - /** - * Gets an array of strings giving the formats that were set in the @see:dragstart event. - */ - get: function () { - return Object.keys(this._data); - }, - enumerable: true, - configurable: true - }); - /** - * Removes the data associated with a given type. - * - * The type argument is optional. If the type is empty or not specified, the data - * associated with all types is removed. If data for the specified type does not exist, - * or the data transfer contains no data, this method will have no effect. - * - * @param type Type of data to remove. - */ - DataTransfer.prototype.clearData = function (type) { - if (type !== null) { - delete this._data[type.toLowerCase()]; - } - else { - this._data = {}; - } - }; - /** - * Retrieves the data for a given type, or an empty string if data for that type does - * not exist or the data transfer contains no data. - * - * @param type Type of data to retrieve. - */ - DataTransfer.prototype.getData = function (type) { - return this._data[type.toLowerCase()] || ''; - }; - /** - * Set the data for a given type. - * - * For a list of recommended drag types, please see - * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Recommended_Drag_Types. - * - * @param type Type of data to add. - * @param value Data to add. - */ - DataTransfer.prototype.setData = function (type, value) { - this._data[type.toLowerCase()] = value; - }; - /** - * Set the image to be used for dragging if a custom one is desired. - * - * @param img An image element to use as the drag feedback image. - * @param offsetX The horizontal offset within the image. - * @param offsetY The vertical offset within the image. - */ - DataTransfer.prototype.setDragImage = function (img, offsetX, offsetY) { - var ddt = DragDropTouch._instance; - ddt._imgCustom = img; - ddt._imgOffset = { x: offsetX, y: offsetY }; - }; - return DataTransfer; - }()); - DragDropTouch_1.DataTransfer = DataTransfer; - /** - * Defines a class that adds support for touch-based HTML5 drag/drop operations. - * - * The @see:DragDropTouch class listens to touch events and raises the - * appropriate HTML5 drag/drop events as if the events had been caused - * by mouse actions. - * - * The purpose of this class is to enable using existing, standard HTML5 - * drag/drop code on mobile devices running IOS or Android. - * - * To use, include the DragDropTouch.js file on the page. The class will - * automatically start monitoring touch events and will raise the HTML5 - * drag drop events (dragstart, dragenter, dragleave, drop, dragend) which - * should be handled by the application. - * - * For details and examples on HTML drag and drop, see - * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations. - */ - var DragDropTouch = (function () { - /** - * Initializes the single instance of the @see:DragDropTouch class. - */ - function DragDropTouch() { - this._lastClick = 0; - // enforce singleton pattern - if (DragDropTouch._instance) { - throw 'DragDropTouch instance already created.'; - } - // detect passive event support - // https://github.com/Modernizr/Modernizr/issues/1894 - var supportsPassive = false; - document.addEventListener('test', function () { }, { - get passive() { - supportsPassive = true; - return true; - } - }); - // listen to touch events - if (navigator.maxTouchPoints) { - var d = document, - ts = this._touchstart.bind(this), - tm = this._touchmove.bind(this), - te = this._touchend.bind(this), - opt = supportsPassive ? { passive: false, capture: false } : false; - d.addEventListener('touchstart', ts, opt); - d.addEventListener('touchmove', tm, opt); - d.addEventListener('touchend', te); - d.addEventListener('touchcancel', te); - } - } - /** - * Gets a reference to the @see:DragDropTouch singleton. - */ - DragDropTouch.getInstance = function () { - return DragDropTouch._instance; - }; - // ** event handlers - DragDropTouch.prototype._touchstart = function (e) { - var _this = this; - if (this._shouldHandle(e)) { - // clear all variables - this._reset(); - // get nearest draggable element - var src = this._closestDraggable(e.target); - if (src) { - // give caller a chance to handle the hover/move events - if (!this._dispatchEvent(e, 'mousemove', e.target) && - !this._dispatchEvent(e, 'mousedown', e.target)) { - // get ready to start dragging - this._dragSource = src; - this._ptDown = this._getPoint(e); - this._lastTouch = e; - e.preventDefault(); - // show context menu if the user hasn't started dragging after a while - setTimeout(function () { - if (_this._dragSource === src && _this._img === null) { - if (_this._dispatchEvent(e, 'contextmenu', src)) { - _this._reset(); - } - } - }, DragDropTouch._CTXMENU); - if (DragDropTouch._ISPRESSHOLDMODE) { - this._pressHoldInterval = setTimeout(function () { - _this._isDragEnabled = true; - _this._touchmove(e); - }, DragDropTouch._PRESSHOLDAWAIT); - } - } - } - } - }; - DragDropTouch.prototype._touchmove = function (e) { - if (this._shouldCancelPressHoldMove(e)) { - this._reset(); - return; - } - if (this._shouldHandleMove(e) || this._shouldHandlePressHoldMove(e)) { - // see if target wants to handle move - var target = this._getTarget(e); - if (this._dispatchEvent(e, 'mousemove', target)) { - this._lastTouch = e; - e.preventDefault(); - return; - } - // start dragging - if (this._dragSource && !this._img && this._shouldStartDragging(e)) { - if (this._dispatchEvent(this._lastTouch, 'dragstart', this._dragSource)) { - // target canceled the drag event - this._dragSource = null; - return; - } - this._createImage(e); - this._dispatchEvent(e, 'dragenter', target); - } - // continue dragging - if (this._img) { - this._lastTouch = e; - e.preventDefault(); // prevent scrolling - this._dispatchEvent(e, 'drag', this._dragSource); - if (target !== this._lastTarget) { - this._dispatchEvent(this._lastTouch, 'dragleave', this._lastTarget); - this._dispatchEvent(e, 'dragenter', target); - this._lastTarget = target; - } - this._moveImage(e); - this._isDropZone = this._dispatchEvent(e, 'dragover', target); - } - } - }; - DragDropTouch.prototype._touchend = function (e) { - if (this._shouldHandle(e)) { - // see if target wants to handle up - if (this._dispatchEvent(this._lastTouch, 'mouseup', e.target)) { - e.preventDefault(); - return; - } - // user clicked the element but didn't drag, so clear the source and simulate a click - if (!this._img) { - this._dragSource = null; - this._dispatchEvent(this._lastTouch, 'click', e.target); - this._lastClick = Date.now(); - } - // finish dragging - this._destroyImage(); - if (this._dragSource) { - if (e.type.indexOf('cancel') < 0 && this._isDropZone) { - this._dispatchEvent(this._lastTouch, 'drop', this._lastTarget); - } - this._dispatchEvent(this._lastTouch, 'dragend', this._dragSource); - this._reset(); - } - } - }; - // ** utilities - // ignore events that have been handled or that involve more than one touch - DragDropTouch.prototype._shouldHandle = function (e) { - return e && - !e.defaultPrevented && - e.touches && e.touches.length < 2; - }; - - // use regular condition outside of press & hold mode - DragDropTouch.prototype._shouldHandleMove = function (e) { - return !DragDropTouch._ISPRESSHOLDMODE && this._shouldHandle(e); - }; - - // allow to handle moves that involve many touches for press & hold - DragDropTouch.prototype._shouldHandlePressHoldMove = function (e) { - return DragDropTouch._ISPRESSHOLDMODE && - this._isDragEnabled && e && e.touches && e.touches.length; - }; - - // reset data if user drags without pressing & holding - DragDropTouch.prototype._shouldCancelPressHoldMove = function (e) { - return DragDropTouch._ISPRESSHOLDMODE && !this._isDragEnabled && - this._getDelta(e) > DragDropTouch._PRESSHOLDMARGIN; - }; - - // start dragging when specified delta is detected - DragDropTouch.prototype._shouldStartDragging = function (e) { - var delta = this._getDelta(e); - return delta > DragDropTouch._THRESHOLD || - (DragDropTouch._ISPRESSHOLDMODE && delta >= DragDropTouch._PRESSHOLDTHRESHOLD); - } - - // clear all members - DragDropTouch.prototype._reset = function () { - this._destroyImage(); - this._dragSource = null; - this._lastTouch = null; - this._lastTarget = null; - this._ptDown = null; - this._isDragEnabled = false; - this._isDropZone = false; - this._dataTransfer = new DataTransfer(); - clearInterval(this._pressHoldInterval); - }; - // get point for a touch event - DragDropTouch.prototype._getPoint = function (e, page) { - if (e && e.touches) { - e = e.touches[0]; - } - return { x: page ? e.pageX : e.clientX, y: page ? e.pageY : e.clientY }; - }; - // get distance between the current touch event and the first one - DragDropTouch.prototype._getDelta = function (e) { - if (DragDropTouch._ISPRESSHOLDMODE && !this._ptDown) { return 0; } - var p = this._getPoint(e); - return Math.abs(p.x - this._ptDown.x) + Math.abs(p.y - this._ptDown.y); - }; - // get the element at a given touch event - DragDropTouch.prototype._getTarget = function (e) { - var pt = this._getPoint(e), el = document.elementFromPoint(pt.x, pt.y); - while (el && getComputedStyle(el).pointerEvents == 'none') { - el = el.parentElement; - } - return el; - }; - // create drag image from source element - DragDropTouch.prototype._createImage = function (e) { - // just in case... - if (this._img) { - this._destroyImage(); - } - // create drag image from custom element or drag source - var src = this._imgCustom || this._dragSource; - this._img = src.cloneNode(true); - this._copyStyle(src, this._img); - this._img.style.top = this._img.style.left = '-9999px'; - // if creating from drag source, apply offset and opacity - if (!this._imgCustom) { - var rc = src.getBoundingClientRect(), pt = this._getPoint(e); - this._imgOffset = { x: pt.x - rc.left, y: pt.y - rc.top }; - this._img.style.opacity = DragDropTouch._OPACITY.toString(); - } - // add image to document - this._moveImage(e); - document.body.appendChild(this._img); - }; - // dispose of drag image element - DragDropTouch.prototype._destroyImage = function () { - if (this._img && this._img.parentElement) { - this._img.parentElement.removeChild(this._img); - } - this._img = null; - this._imgCustom = null; - }; - // move the drag image element - DragDropTouch.prototype._moveImage = function (e) { - var _this = this; - requestAnimationFrame(function () { - if (_this._img) { - var pt = _this._getPoint(e, true), s = _this._img.style; - s.position = 'absolute'; - s.pointerEvents = 'none'; - s.zIndex = '999999'; - s.left = Math.round(pt.x - _this._imgOffset.x) + 'px'; - s.top = Math.round(pt.y - _this._imgOffset.y) + 'px'; - } - }); - }; - // copy properties from an object to another - DragDropTouch.prototype._copyProps = function (dst, src, props) { - for (var i = 0; i < props.length; i++) { - var p = props[i]; - dst[p] = src[p]; - } - }; - DragDropTouch.prototype._copyStyle = function (src, dst) { - // remove potentially troublesome attributes - DragDropTouch._rmvAtts.forEach(function (att) { - dst.removeAttribute(att); - }); - // copy canvas content - if (src instanceof HTMLCanvasElement) { - var cSrc = src, cDst = dst; - cDst.width = cSrc.width; - cDst.height = cSrc.height; - cDst.getContext('2d').drawImage(cSrc, 0, 0); - } - // copy style (without transitions) - var cs = getComputedStyle(src); - for (var i = 0; i < cs.length; i++) { - var key = cs[i]; - if (key.indexOf('transition') < 0) { - dst.style[key] = cs[key]; - } - } - dst.style.pointerEvents = 'none'; - // and repeat for all children - for (var i = 0; i < src.children.length; i++) { - this._copyStyle(src.children[i], dst.children[i]); - } - }; - // compute missing offset or layer property for an event - DragDropTouch.prototype._setOffsetAndLayerProps = function (e, target) { - var rect = undefined; - if (e.offsetX === undefined) { - rect = target.getBoundingClientRect(); - e.offsetX = e.clientX - rect.x; - e.offsetY = e.clientY - rect.y; - } - if (e.layerX === undefined) { - rect = rect || target.getBoundingClientRect(); - e.layerX = e.pageX - rect.left; - e.layerY = e.pageY - rect.top; - } - } - DragDropTouch.prototype._dispatchEvent = function (e, type, target) { - if (e && target) { - var evt = document.createEvent('Event'), t = e.touches ? e.touches[0] : e; - evt.initEvent(type, true, true); - evt.button = 0; - evt.which = evt.buttons = 1; - this._copyProps(evt, e, DragDropTouch._kbdProps); - this._copyProps(evt, t, DragDropTouch._ptProps); - this._setOffsetAndLayerProps(evt, target); - evt.dataTransfer = this._dataTransfer; - target.dispatchEvent(evt); - return evt.defaultPrevented; - } - return false; - }; - // gets an element's closest draggable ancestor - DragDropTouch.prototype._closestDraggable = function (e) { - for (; e; e = e.parentElement) { - if (e.hasAttribute('draggable') && e.draggable) { - return e; - } - } - return null; - }; - return DragDropTouch; - }()); - /*private*/ DragDropTouch._instance = new DragDropTouch(); // singleton - // constants - DragDropTouch._THRESHOLD = 5; // pixels to move before drag starts - DragDropTouch._OPACITY = 0.5; // drag image opacity - DragDropTouch._DBLCLICK = 500; // max ms between clicks in a double click - DragDropTouch._CTXMENU = 900; // ms to hold before raising 'contextmenu' event - DragDropTouch._ISPRESSHOLDMODE = true; // decides of press & hold mode presence - DragDropTouch._PRESSHOLDAWAIT = 400; // ms to wait before press & hold is detected - DragDropTouch._PRESSHOLDMARGIN = 25; // pixels that finger might shiver while pressing - DragDropTouch._PRESSHOLDTHRESHOLD = 0; // pixels to move before drag starts - // copy styles/attributes from drag source to drag image element - DragDropTouch._rmvAtts = 'id,class,style,draggable'.split(','); - // synthesize and dispatch an event - // returns true if the event has been handled (e.preventDefault == true) - DragDropTouch._kbdProps = 'altKey,ctrlKey,metaKey,shiftKey'.split(','); - DragDropTouch._ptProps = 'pageX,pageY,clientX,clientY,screenX,screenY,offsetX,offsetY'.split(','); - DragDropTouch_1.DragDropTouch = DragDropTouch; -})(DragDropTouch || (DragDropTouch = {})); diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 6c114eb4..3258e4a7 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -18,6 +18,7 @@ const safeConvertor = new showdown.Converter({ backslashEscapesHTMLTags: true }) + DOMPurify.addHook("uponSanitizeElement", (node: HTMLElement, data) => { if (data.tagName === "iframe") { const src = node.getAttribute("src") || ""; @@ -77,8 +78,6 @@ export async function convertImage(data:Uint8Array) { if(type === 'PNG' && isAPNG(data)){ return data } - - console.log('converting') return await resizeAndConvert(data) } return data diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index adb0a596..502143dc 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -8,7 +8,7 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '. export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.25.3' +export let appVer = '1.25.4' export function setDatabase(data:Database){ if(checkNullish(data.characters)){ diff --git a/version.json b/version.json index 74e02fa5..6d72a0d9 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.25.3"} \ No newline at end of file +{"version":"1.25.4"} \ No newline at end of file diff --git a/vite.config.ts b/vite.config.ts index a9903d5c..f9e66f2d 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -58,7 +58,8 @@ export default defineConfig(async () => { resolve:{ alias:{ - 'src':'/src' + 'src':'/src', + 'modules': '/modules' } } }}); From 0b5c765da2c1170c703c77c521cf671a1d35b661 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 14 Jun 2023 13:31:41 +0900 Subject: [PATCH 29/50] [feat] better proxy resolve --- src/ts/process/request.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 3dbe86c2..73220b0c 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -88,9 +88,17 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' if(replacerURL.endsWith('v1')){ replacerURL += '/chat/completions' } - if(replacerURL.endsWith('v1/')){ + else if(replacerURL.endsWith('v1/')){ replacerURL += 'chat/completions' } + else if(!(replacerURL.endsWith('completions') || replacerURL.endsWith('completions/'))){ + if(replacerURL.endsWith('/')){ + replacerURL += 'v1/chat/completions' + } + else{ + replacerURL += '/v1/chat/completions' + } + } if(db.useStreaming && arg.useStreaming){ body.stream = true @@ -127,6 +135,8 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' control.enqueue(readed) return } + + console.log(rawChunk) const chunk = JSON.parse(rawChunk).choices[0].delta.content if(chunk){ readed += chunk From 415a8a07e493a24048116e21a227996b9989c8ee Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 14 Jun 2023 22:40:01 +0900 Subject: [PATCH 30/50] [test] oai function call --- src/ts/process/index.ts | 35 ++++++++++++++- src/ts/process/request.ts | 92 +++++++++++++++++++++++++++++++++++---- 2 files changed, 118 insertions(+), 9 deletions(-) diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index ee1a432e..c805f683 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -17,12 +17,20 @@ import { cloneDeep } from "lodash"; import { groupOrder } from "./group"; export interface OpenAIChat{ - role: 'system'|'user'|'assistant' + role: 'system'|'user'|'assistant'|'function' content: string memo?:string name?:string } +export interface OpenAIChatFull extends OpenAIChat{ + function_call?: { + name: string + arguments:string + } + +} + export const doingChat = writable(false) export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:number} = {}):Promise { @@ -417,6 +425,31 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n setDatabase(db) } + if(req.special){ + if(req.special.emotion){ + let charemotions = get(CharEmotion) + let currentEmotion = currentChar.emotionImages + + let tempEmotion = charemotions[currentChar.chaId] + if(!tempEmotion){ + tempEmotion = [] + } + if(tempEmotion.length > 4){ + tempEmotion.splice(0, 1) + } + + for(const emo of currentEmotion){ + if(emo[0] === req.special.emotion){ + const emos:[string, string,number] = [emo[0], emo[1], Date.now()] + tempEmotion.push(emos) + charemotions[currentChar.chaId] = tempEmotion + CharEmotion.set(charemotions) + emoChanged = true + break + } + } + } + } if(currentChar.viewScreen === 'emotion' && (!emoChanged)){ diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index 73220b0c..f261adaf 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -1,5 +1,5 @@ import { get } from "svelte/store"; -import type { OpenAIChat } from "."; +import type { OpenAIChat, OpenAIChatFull } from "."; import { DataBase, setDatabase, type character } from "../storage/database"; import { pluginProcess } from "./plugins"; import { language } from "../../lang"; @@ -17,15 +17,38 @@ interface requestDataArgument{ frequencyPenalty?: number, useStreaming?:boolean isGroupChat?:boolean + useEmotion?:boolean } type requestDataResponse = { type: 'success'|'fail' result: string - noRetry?: boolean + noRetry?: boolean, + special?: { + emotion?: string + } }|{ type: "streaming", - result: ReadableStream + result: ReadableStream, + noRetry?: boolean, + special?: { + emotion?: string + } +} + +interface OaiFunctions { + name: string; + description: string; + parameters: { + type: string; + properties: { + [key:string]: { + type: string; + enum: string[]; // replace 'string[]' with 'Emotion[]' if 'Emotion' is an enum type + }; + }; + required: string[]; + }; } export async function requestChatData(arg:requestDataArgument, model:'model'|'submodel', abortSignal:AbortSignal=null):Promise { @@ -44,6 +67,9 @@ export async function requestChatData(arg:requestDataArgument, model:'model'|'su } } + + + export async function requestChatDataMain(arg:requestDataArgument, model:'model'|'submodel', abortSignal:AbortSignal=null):Promise { const db = get(DataBase) let result = '' @@ -63,12 +89,46 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' case 'gpt4_32k':{ for(let i=0;i { + return a[0] + }) + + let oaiFunctions:OaiFunctions[] = [] + + + if(arg.useEmotion){ + oaiFunctions.push( + { + "name": "set_emotion", + "description": "sets a role playing character's emotion display. must be called one time at the end of response.", + "parameters": { + "type": "object", + "properties": { + "emotion": { + "type": "string", "enum": emotionList + }, + }, + "required": ["emotion"], + }, + } + ) + } + + if(oaiFunctions.length === 0){ + oaiFunctions = undefined + } + + + const oaiFunctionCall = oaiFunctions ? (arg.useEmotion ? {"name": "set_emotion"} : "auto") : undefined const body = ({ model: aiModel === 'gpt35' ? 'gpt-3.5-turbo' : aiModel === 'gpt35_16k' ? 'gpt-3.5-turbo-16k' @@ -80,7 +140,9 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' presence_penalty: arg.PresensePenalty ?? (db.PresensePenalty / 100), frequency_penalty: arg.frequencyPenalty ?? (db.frequencyPenalty / 100), logit_bias: bias, - stream: false + stream: false, + functions: oaiFunctions, + function_call: oaiFunctionCall }) let replacerURL = replacer === '' ? 'https://api.openai.com/v1/chat/completions' : replacer @@ -170,7 +232,21 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' const dat = res.data as any if(res.ok){ try { - const msg:OpenAIChat = (dat.choices[0].message) + const msg:OpenAIChatFull = (dat.choices[0].message) + if(msg.function_call){ + console.log(msg.function_call) + const functionarg = JSON.parse(msg.function_call.arguments) + arg.formated.push({ + "role": "function", + "name": 'set_emotion', + "content": "successfuly set to " + functionarg.emotion, + }) + arg.useEmotion = false + const d = await requestChatDataMain(arg, model, abortSignal) + d.special = d.special ?? {} + d.special.emotion = functionarg.emotion + return d + } return { type: 'success', result: msg.content From 1c170ef8a773fa1a97ec16c85873caaf2a1d6389 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 14 Jun 2023 23:00:13 +0900 Subject: [PATCH 31/50] [feat] prompt role formater --- src/ts/process/index.ts | 36 ++++++++++++++++++++++++------------ src/ts/process/request.ts | 19 ++----------------- 2 files changed, 26 insertions(+), 29 deletions(-) diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts index c805f683..2f0fb543 100644 --- a/src/ts/process/index.ts +++ b/src/ts/process/index.ts @@ -156,22 +156,34 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n if(!currentChar.utilityBot){ const mainp = currentChar.systemPrompt || db.mainPrompt - unformated.main.push({ - role: 'system', - content: replacePlaceholders(mainp + ((db.additionalPrompt === '' || (!db.promptPreprocess)) ? '' : `\n${db.additionalPrompt}`), currentChar.name) - }) + + function formatPrompt(data:string){ + if(!data.startsWith('@@@')){ + data = "@@@system\n" + data + } + const parts = data.split(/@@@(user|assistant|system)\n/); + + // Initialize empty array for the chat objects + const chatObjects: OpenAIChat[] = []; + + // Loop through the parts array two elements at a time + for (let i = 1; i < parts.length; i += 2) { + const role = parts[i] as 'user' | 'assistant' | 'system'; + const content = parts[i + 1]?.trim() || ''; + chatObjects.push({ role, content }); + } + + console.log(chatObjects) + return chatObjects; + } + + unformated.main.push(...formatPrompt(replacePlaceholders(mainp + ((db.additionalPrompt === '' || (!db.promptPreprocess)) ? '' : `\n${db.additionalPrompt}`), currentChar.name))) if(db.jailbreakToggle){ - unformated.jailbreak.push({ - role: 'system', - content: replacePlaceholders(db.jailbreak, currentChar.name) - }) + unformated.jailbreak.push(...formatPrompt(replacePlaceholders(db.jailbreak, currentChar.name))) } - unformated.globalNote.push({ - role: 'system', - content: replacePlaceholders(currentChar.replaceGlobalNote || db.globalNote, currentChar.name) - }) + unformated.globalNote.push(...formatPrompt(replacePlaceholders(currentChar.replaceGlobalNote || db.globalNote, currentChar.name))) } if(currentChat.note){ diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index f261adaf..db657bb2 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -140,9 +140,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' presence_penalty: arg.PresensePenalty ?? (db.PresensePenalty / 100), frequency_penalty: arg.frequencyPenalty ?? (db.frequencyPenalty / 100), logit_bias: bias, - stream: false, - functions: oaiFunctions, - function_call: oaiFunctionCall + stream: false }) let replacerURL = replacer === '' ? 'https://api.openai.com/v1/chat/completions' : replacer @@ -232,21 +230,8 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' const dat = res.data as any if(res.ok){ try { + console.log(dat) const msg:OpenAIChatFull = (dat.choices[0].message) - if(msg.function_call){ - console.log(msg.function_call) - const functionarg = JSON.parse(msg.function_call.arguments) - arg.formated.push({ - "role": "function", - "name": 'set_emotion', - "content": "successfuly set to " + functionarg.emotion, - }) - arg.useEmotion = false - const d = await requestChatDataMain(arg, model, abortSignal) - d.special = d.special ?? {} - d.special.emotion = functionarg.emotion - return d - } return { type: 'success', result: msg.content From 0884c445a07e5f50c447773550f155442b599999 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Wed, 14 Jun 2023 23:14:44 +0900 Subject: [PATCH 32/50] [feat] gpt 0613 additions, some fixes --- src/lib/Others/ChatList.svelte | 2 +- src/lib/Setting/Pages/BotSettings.svelte | 2 +- src/lib/UI/ModelList.svelte | 8 ++++++++ src/ts/process/request.ts | 20 +++++++++----------- 4 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/lib/Others/ChatList.svelte b/src/lib/Others/ChatList.svelte index 141b21e4..3b090c49 100644 --- a/src/lib/Others/ChatList.svelte +++ b/src/lib/Others/ChatList.svelte @@ -12,7 +12,7 @@
-
+

{language.chatList}

diff --git a/src/lib/Setting/Pages/BotSettings.svelte b/src/lib/Setting/Pages/BotSettings.svelte index 2cb2ab01..da658cda 100644 --- a/src/lib/Setting/Pages/BotSettings.svelte +++ b/src/lib/Setting/Pages/BotSettings.svelte @@ -110,7 +110,7 @@ Claude {language.apiKey} {/if} -{#if $DataBase.aiModel === 'gpt35' || $DataBase.aiModel === 'gpt35_16k_0613' || $DataBase.subModel === 'gpt35_16k_0613' || $DataBase.aiModel === 'gpt35_16k' || $DataBase.subModel === 'gpt35_16k' || $DataBase.aiModel === 'gpt4' || $DataBase.subModel === 'gpt4' || $DataBase.subModel === 'gpt35'|| $DataBase.aiModel === 'gpt4_32k' || $DataBase.subModel === 'gpt4_32k'} +{#if $DataBase.aiModel.startsWith('gpt')} OpenAI {language.apiKey}
diff --git a/src/lib/UI/ModelList.svelte b/src/lib/UI/ModelList.svelte index 09cb5114..9feecb1a 100644 --- a/src/lib/UI/ModelList.svelte +++ b/src/lib/UI/ModelList.svelte @@ -13,6 +13,8 @@ switch(name){ case "gpt35": return "GPT-3.5 Turbo" + case "gpt35_0613": + return "GPT-3.5 Turbo 0613" case "gpt35_16k": return "GPT-3.5 Turbo 16k" case "gpt35_16k_0613": @@ -21,6 +23,10 @@ return "GPT-4" case "gpt4_32k": return "GPT-4 32k" + case "gpt4_0613": + return "GPT-4 0613" + case "gpt4_32k_0613": + return "GPT-4 32k 0613" case "palm2": return "PaLM2" case "textgen_webui": @@ -59,7 +65,9 @@ + + diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index db657bb2..dc4edc78 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -83,10 +83,13 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' switch(aiModel){ case 'gpt35': + case 'gpt35_0613': case 'gpt35_16k': case 'gpt35_16k_0613': case 'gpt4': - case 'gpt4_32k':{ + case 'gpt4_32k': + case 'gpt4_0613': + case 'gpt4_32k_0613':{ for(let i=0;i Date: Wed, 14 Jun 2023 23:15:39 +0900 Subject: [PATCH 33/50] bump to 1.25.5 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 4b817ec2..ab30e482 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.25.4" + "version": "1.25.5" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 502143dc..e252eb47 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -8,7 +8,7 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '. export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.25.4' +export let appVer = '1.25.5' export function setDatabase(data:Database){ if(checkNullish(data.characters)){ diff --git a/version.json b/version.json index 6d72a0d9..b86a721b 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.25.4"} \ No newline at end of file +{"version":"1.25.5"} \ No newline at end of file From 10bd1fe2ad9e1db27cb77831ca34f6fade1a728f Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 15 Jun 2023 10:10:20 +0900 Subject: [PATCH 34/50] [fix] loads emotion when loading supamemory --- src/ts/process/request.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/ts/process/request.ts b/src/ts/process/request.ts index dc4edc78..3fe36380 100644 --- a/src/ts/process/request.ts +++ b/src/ts/process/request.ts @@ -44,7 +44,7 @@ interface OaiFunctions { properties: { [key:string]: { type: string; - enum: string[]; // replace 'string[]' with 'Emotion[]' if 'Emotion' is an enum type + enum: string[] }; }; required: string[]; @@ -100,10 +100,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' } } - let currentEmotion = currentChar.emotionImages - let emotionList = currentEmotion.map((a) => { - return a[0] - }) + let oaiFunctions:OaiFunctions[] = [] @@ -117,7 +114,7 @@ export async function requestChatDataMain(arg:requestDataArgument, model:'model' "type": "object", "properties": { "emotion": { - "type": "string", "enum": emotionList + "type": "string", "enum": [] }, }, "required": ["emotion"], From f2af588f871bad381828a8a0289495f46c6a6f31 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 15 Jun 2023 10:12:47 +0900 Subject: [PATCH 35/50] bump verison to 1.25.6 --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index ab30e482..fdbaec54 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.25.5" + "version": "1.25.6" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index e252eb47..02fb2acc 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -8,7 +8,7 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '. export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.25.5' +export let appVer = '1.25.6' export function setDatabase(data:Database){ if(checkNullish(data.characters)){ diff --git a/version.json b/version.json index b86a721b..8ee5473c 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.25.5"} \ No newline at end of file +{"version":"1.25.6"} \ No newline at end of file From 43cf7383245d0a2bf7a6bba80b2c6646e4213a2f Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 15 Jun 2023 12:11:49 +0900 Subject: [PATCH 36/50] [feat] sync improvements --- src/ts/drive/drive.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ts/drive/drive.ts b/src/ts/drive/drive.ts index 6092caee..e1278d7a 100644 --- a/src/ts/drive/drive.ts +++ b/src/ts/drive/drive.ts @@ -13,7 +13,7 @@ import { hubURL } from "../characterCards"; export async function checkDriver(type:'save'|'load'|'loadtauri'|'savetauri'|'reftoken'){ const CLIENT_ID = '580075990041-l26k2d3c0nemmqiu3d3aag01npfrkn76.apps.googleusercontent.com'; - const REDIRECT_URI = type === 'reftoken' ? 'https://sv.risuai.xyz/drive' : ((isTauri || isNodeServer) ? "https://risuai.xyz/" : `https://${location.host}/`) + const REDIRECT_URI = type === 'reftoken' ? 'https://sv.risuai.xyz/drive' : "https://risuai.xyz/" const SCOPE = 'https://www.googleapis.com/auth/drive.file https://www.googleapis.com/auth/drive.appdata'; const encodedRedirectUri = encodeURIComponent(REDIRECT_URI); const authorizationUrl = `https://accounts.google.com/o/oauth2/auth?client_id=${CLIENT_ID}&redirect_uri=${encodedRedirectUri}&scope=${SCOPE}&response_type=code&state=${type}`; @@ -131,6 +131,8 @@ export async function syncDrive() { } const ACCESS_TOKEN = maindb.account.data.access_token const d = await loadDrive(ACCESS_TOKEN, 'sync') + lastSaved = Math.floor(Date.now() / 1000) + localStorage.setItem('risu_lastsaved', `${lastSaved}`) const hadNoSync = d === 'noSync' if((!isEqual(maindb, BackupDb)) || hadNoSync){ BackupDb = cloneDeep(maindb) From ffcffad465f58a0e121655220027dd0358f5d1a8 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 15 Jun 2023 21:05:06 +0900 Subject: [PATCH 37/50] [feat] classic max width --- src/lib/ChatScreens/ChatScreen.svelte | 17 +++++++++-------- src/ts/storage/database.ts | 7 +++++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/lib/ChatScreens/ChatScreen.svelte b/src/lib/ChatScreens/ChatScreen.svelte index 808feacf..360741ea 100644 --- a/src/lib/ChatScreens/ChatScreen.svelte +++ b/src/lib/ChatScreens/ChatScreen.svelte @@ -27,15 +27,16 @@ })() {#if $DataBase.theme === ''} -
- - {#if $selectedCharID >= 0} - {#if $DataBase.characters[$selectedCharID].viewScreen !== 'none'} - - {/if} - {/if} +
- 2 ? `${externalStyles}`: ''} bind:openChatList/> +
+ {#if $selectedCharID >= 0} + {#if $DataBase.characters[$selectedCharID].viewScreen !== 'none'} + + {/if} + {/if} + 2 ? `${externalStyles}`: ''} bind:openChatList/> +
{:else if $DataBase.theme === 'waifu'}
diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 02fb2acc..2fa7a53c 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -260,7 +260,9 @@ export function setDatabase(data:Database){ if(checkNullish(data.imageCompression)){ data.imageCompression = true } - + if(checkNullish(data.classicMaxWidth)){ + data.classicMaxWidth = false + } changeLanguage(data.language) DataBase.set(data) } @@ -519,7 +521,8 @@ export interface Database{ access_token?:string expires_in?: number } - } + }, + classicMaxWidth: boolean } interface hordeConfig{ From 1ad286561e7bce38d74442f69c385d92c8de17c9 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Thu, 15 Jun 2023 21:05:31 +0900 Subject: [PATCH 38/50] bump to 1.25.7 & smol fix --- src-tauri/tauri.conf.json | 2 +- src/ts/storage/database.ts | 2 +- version.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index fdbaec54..e5b41fc3 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "RisuAI", - "version": "1.25.6" + "version": "1.25.7" }, "tauri": { "allowlist": { diff --git a/src/ts/storage/database.ts b/src/ts/storage/database.ts index 2fa7a53c..6dfcac69 100644 --- a/src/ts/storage/database.ts +++ b/src/ts/storage/database.ts @@ -8,7 +8,7 @@ import { defaultAutoSuggestPrompt, defaultJailbreak, defaultMainPrompt } from '. export const DataBase = writable({} as any as Database) export const loadedStore = writable(false) -export let appVer = '1.25.6' +export let appVer = '1.25.7' export function setDatabase(data:Database){ if(checkNullish(data.characters)){ diff --git a/version.json b/version.json index 8ee5473c..6d2c56e6 100644 --- a/version.json +++ b/version.json @@ -1 +1 @@ -{"version":"1.25.6"} \ No newline at end of file +{"version":"1.25.7"} \ No newline at end of file From f72380ef0c817a1210cde268b6d8af4e32ded54a Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 16 Jun 2023 10:38:11 +0900 Subject: [PATCH 39/50] [feat] comming soon to offical discord for temp --- .gitignore | 3 ++- src/lib/UI/MainMenu.svelte | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 3273f754..b4dd471d 100644 --- a/.gitignore +++ b/.gitignore @@ -28,4 +28,5 @@ xplugin/ /src-taurl/target/ /src-taurl/gen/ /build/ -pycache/ \ No newline at end of file +pycache/ +test.ts \ No newline at end of file diff --git a/src/lib/UI/MainMenu.svelte b/src/lib/UI/MainMenu.svelte index 101051bd..09e2dd8e 100644 --- a/src/lib/UI/MainMenu.svelte +++ b/src/lib/UI/MainMenu.svelte @@ -40,9 +40,9 @@ Characters made and shared by the community {:else} - {/if}
From ad5e3db0ae0a9c3635b818757e5c7a184415b5a8 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Fri, 16 Jun 2023 13:34:02 +0900 Subject: [PATCH 40/50] [feat] realm enchanments --- src/lib/ChatScreens/ChatScreen.svelte | 5 +- src/lib/UI/Hub.svelte | 66 ++++++------------- src/lib/UI/MainMenu.svelte | 37 +++++++---- src/lib/UI/RisuHubIcon.svelte | 36 +++++++++++ src/ts/characterCards.ts | 93 +++++++++++++++------------ src/ts/parser.ts | 1 + 6 files changed, 139 insertions(+), 99 deletions(-) create mode 100644 src/lib/UI/RisuHubIcon.svelte diff --git a/src/lib/ChatScreens/ChatScreen.svelte b/src/lib/ChatScreens/ChatScreen.svelte index 360741ea..24dd4149 100644 --- a/src/lib/ChatScreens/ChatScreen.svelte +++ b/src/lib/ChatScreens/ChatScreen.svelte @@ -55,7 +55,7 @@ {:else if $DataBase.theme === 'waifuMobile'}
-
+
= 0}>
{#if $selectedCharID >= 0} @@ -78,4 +78,7 @@ .halfwp{ max-width: calc(50% - 5rem); } + .per33{ + height: 33.333333%; + } \ No newline at end of file diff --git a/src/lib/UI/Hub.svelte b/src/lib/UI/Hub.svelte index 09c8db45..be8a7b8e 100644 --- a/src/lib/UI/Hub.svelte +++ b/src/lib/UI/Hub.svelte @@ -1,27 +1,14 @@
@@ -34,18 +36,31 @@

Your Characters

Opens your character list. you can open with pressing arrow button in top left corner too. - {#if $DataBase.useExperimental} - - {:else} - - {/if} +
+ {#await getRisuHub({ + search: '', + page: -10, + nsfw: false, + sort: '' + }) then charas} +
+

Recent Characters from {language.hub}

+ {#if charas.length > 0} +
+ {#each charas as chara} + {openHub = true}} chara={chara} /> + {/each} +
+ {:else} +
Failed to load {language.hub}...
+ {/if} + {/await} {:else}
+ {/if} + {#if chara.hasLore} + + {/if} +
+
+
\ No newline at end of file diff --git a/src/ts/characterCards.ts b/src/ts/characterCards.ts index f282e8d1..f97f51e8 100644 --- a/src/ts/characterCards.ts +++ b/src/ts/characterCards.ts @@ -653,58 +653,67 @@ export async function shareRisuHub(char:character, arg:{ } -export async function getRisuHub(arg?:{ - search?:string, - page?:number, - nsfw?:boolean - sort?:string -}):Promise<{ +export type hubType = { name:string desc: string download: number, id: string, img: string - tags: string[] -}[]> { - const da = await fetch(hubURL + '/hub/list', { - method: "POST", - body: JSON.stringify(arg ?? {}) - }) - if(da.status !== 200){ - return [] + tags: string[], + viewScreen: "none" | "emotion" | "imggen" + hasLore:boolean +} + +export async function getRisuHub(arg?:{ + search?:string, + page?:number, + nsfw?:boolean + sort?:string +}):Promise { + try { + const da = await fetch(hubURL + '/hub/list', { + method: "POST", + body: JSON.stringify(arg ?? {}) + }) + if(da.status !== 200){ + return [] + } + console.log(da) + return da.json() + } catch (error) { + return[] } - console.log(da) - return da.json() } export async function downloadRisuHub(id:string) { - alertStore.set({ - type: "wait", - msg: "Downloading..." - }) - const res = await fetch(hubURL + '/hub/get', { - method: "POST", - body: JSON.stringify({ - id: id + try { + alertStore.set({ + type: "wait", + msg: "Downloading..." }) - }) - if(res.status !== 200){ - alertError(await res.text()) - } - - const result = await res.json() - const data:CharacterCardV2 = result.card - const img:string = result.img - - await importSpecv2(data, await getHubResources(img), 'hub') - checkCharOrder() - let db = get(DataBase) - if(db.characters[db.characters.length-1]){ - const index = db.characters.length-1 - characterFormatUpdate(index); - selectedCharID.set(index); - } - + const res = await fetch(hubURL + '/hub/get', { + method: "POST", + body: JSON.stringify({ + id: id + }) + }) + if(res.status !== 200){ + alertError(await res.text()) + } + + const result = await res.json() + const data:CharacterCardV2 = result.card + const img:string = result.img + + await importSpecv2(data, await getHubResources(img), 'hub') + checkCharOrder() + let db = get(DataBase) + if(db.characters[db.characters.length-1]){ + const index = db.characters.length-1 + characterFormatUpdate(index); + selectedCharID.set(index); + } + } catch (error) {alertError("Error while importing")} } export async function getHubResources(id:string) { diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 3258e4a7..84d0a4d9 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -19,6 +19,7 @@ const safeConvertor = new showdown.Converter({ }) + DOMPurify.addHook("uponSanitizeElement", (node: HTMLElement, data) => { if (data.tagName === "iframe") { const src = node.getAttribute("src") || ""; From 6a9317cdd94c5bf1cef24ac362dc888f5cb80ca6 Mon Sep 17 00:00:00 2001 From: kwaroran <116663078+kwaroran@users.noreply.github.com> Date: Sat, 17 Jun 2023 19:40:59 +0900 Subject: [PATCH 41/50] Update README.md --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2eaf07d6..0dc944cf 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # RisuAI -![Screenshot_6](https://github.com/kwaroran/RisuAI/assets/116663078/cccb9b33-5dbd-47d7-9c85-61464790aafe) +|![Screenshot_6](https://github.com/kwaroran/RisuAI/assets/116663078/cccb9b33-5dbd-47d7-9c85-61464790aafe) | ![image](https://github.com/kwaroran/RisuAI/assets/116663078/30d29f85-1380-4c73-9b82-1a40f2c5d2ea) | +| --- | ----------- | -> A AIChat Frontend like Tavern, with great accessibility. Run in web or with installer. +> A AIChat Frontend, for both light and power users, with great accessibility. Run in web or with installer. Web version - Go to http://risuai.xyz/ From 5acc43362c1ddcf6c1b5be56c854761f99549b12 Mon Sep 17 00:00:00 2001 From: kwaroran <116663078+kwaroran@users.noreply.github.com> Date: Sun, 18 Jun 2023 19:15:02 +0900 Subject: [PATCH 42/50] Create FUNDING.yml --- .github/FUNDING.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/FUNDING.yml diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 00000000..82b2713f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +patreon: RisuAI From fb9bd8d342eb4362a8367c4bd9334d2b1e328ff0 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 18 Jun 2023 21:11:42 +0900 Subject: [PATCH 43/50] [feat] css full support --- package.json | 1 + pnpm-lock.yaml | 7 +++++++ src/lib/ChatScreens/ChatScreen.svelte | 2 +- src/lib/UI/MainMenu.svelte | 1 - src/ts/characterCards.ts | 3 ++- src/ts/parser.ts | 23 +++++++++++++++++++++++ 6 files changed, 34 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 1bdba617..fcf73bab 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "runserver": "node server/node/server.cjs" }, "dependencies": { + "@adobe/css-tools": "4.3.0-beta.2", "@dqbd/tiktoken": "^1.0.4", "@msgpack/msgpack": "3.0.0-beta2", "@tauri-apps/api": "1.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8e322b1e..670f657c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1,6 +1,9 @@ lockfileVersion: '6.0' dependencies: + '@adobe/css-tools': + specifier: 4.3.0-beta.2 + version: 4.3.0-beta.2 '@dqbd/tiktoken': specifier: ^1.0.4 version: 1.0.4 @@ -171,6 +174,10 @@ devDependencies: packages: + /@adobe/css-tools@4.3.0-beta.2: + resolution: {integrity: sha512-VzekSqtYB+8XX8W1gNRIa1TbTXjVw64I5yLrbBP13JhwecixQzrpXWIszo7FghS9cm6FEFhzIivzwjns35DMlQ==} + dev: false + /@dqbd/tiktoken@1.0.4: resolution: {integrity: sha512-C0HrJj2RNlsB3wslfNHGNH8xN7QQMki+y4JkUor/GE+oIfPvH7yVep9l1/2powam8AAH6+gdv5MggA5gsszweg==} dev: false diff --git a/src/lib/ChatScreens/ChatScreen.svelte b/src/lib/ChatScreens/ChatScreen.svelte index 24dd4149..c661e953 100644 --- a/src/lib/ChatScreens/ChatScreen.svelte +++ b/src/lib/ChatScreens/ChatScreen.svelte @@ -55,7 +55,7 @@ {:else if $DataBase.theme === 'waifuMobile'}
-
= 0}> +
= 0}>
{#if $selectedCharID >= 0} diff --git a/src/lib/UI/MainMenu.svelte b/src/lib/UI/MainMenu.svelte index 002ab1d8..4460fd5b 100644 --- a/src/lib/UI/MainMenu.svelte +++ b/src/lib/UI/MainMenu.svelte @@ -66,7 +66,6 @@ -

{language.hub}

{/if} diff --git a/src/ts/characterCards.ts b/src/ts/characterCards.ts index f97f51e8..bfdc14a9 100644 --- a/src/ts/characterCards.ts +++ b/src/ts/characterCards.ts @@ -636,7 +636,8 @@ export async function shareRisuHub(char:character, arg:{ body: JSON.stringify({ card: card, img: Buffer.from(img).toString('base64'), - resources: resources + resources: resources, + token: get(DataBase)?.account?.token }) }) diff --git a/src/ts/parser.ts b/src/ts/parser.ts index 84d0a4d9..d9a9a34c 100644 --- a/src/ts/parser.ts +++ b/src/ts/parser.ts @@ -4,6 +4,7 @@ import { DataBase, type character, type groupChat } from './storage/database'; import { getFileSrc } from './storage/globalApi'; import { processScript } from './process/scripts'; import { get } from 'svelte/store'; +import css from '@adobe/css-tools' const convertor = new showdown.Converter({ simpleLineBreaks: true, @@ -27,6 +28,28 @@ DOMPurify.addHook("uponSanitizeElement", (node: HTMLElement, data) => { return node.parentNode.removeChild(node); } } + if(data.tagName === 'style'){ + try { + const ast = css.parse(node.innerHTML) + const rules = ast?.stylesheet?.rules + if(rules){ + for(const rule of rules){ + if(rule.selectors){ + for(let i=0;i { From 1d838b4140f2e4a3f3adfbf267fa19e1e1bad384 Mon Sep 17 00:00:00 2001 From: kwaroran Date: Sun, 18 Jun 2023 21:58:12 +0900 Subject: [PATCH 44/50] [feat] download enchantments --- src/lib/Setting/Pages/UserSettings.svelte | 32 ++++++++++++----------- src/lib/SideBars/CharConfig.svelte | 9 +++---- src/lib/UI/Hub.svelte | 30 ++++++++++++++++++--- src/lib/UI/HubUpload.svelte | 13 ++++++++- src/lib/UI/MainMenu.svelte | 7 +++-- src/ts/characterCards.ts | 1 + 6 files changed, 62 insertions(+), 30 deletions(-) diff --git a/src/lib/Setting/Pages/UserSettings.svelte b/src/lib/Setting/Pages/UserSettings.svelte index 163a767e..12921c5c 100644 --- a/src/lib/Setting/Pages/UserSettings.svelte +++ b/src/lib/Setting/Pages/UserSettings.svelte @@ -49,10 +49,9 @@ {language.username} -{#if $DataBase.useExperimental}
-

Risu Account{#if $DataBase.account} +

Risu Account{#if $DataBase.account} @@ -60,19 +59,23 @@

{#if $DataBase.account} ID: {$DataBase.account.id} -

{language.googleDriveConnection}

- {#if !$DataBase.account.data.refresh_token} - {language.googleDriveInfo} - - {:else} - {language.googleDriveConnected} + {#if $DataBase.useExperimental} + +

{language.googleDriveConnection}

+ {#if !$DataBase.account.data.refresh_token} + {language.googleDriveInfo} + + {:else} + {language.googleDriveConnected} + {/if} {/if} + {:else} {language.notLoggedIn} {/if}
-{/if} {#if openIframe}