Merge branch 'main' of https://github.com/LightningHyperBlaze45654/RisuAI
This commit is contained in:
@@ -1,11 +1,11 @@
|
||||
import { get } from "svelte/store";
|
||||
import { DataBase, setDatabase } from "../storage/database";
|
||||
import { CurrentCharacter, CurrentChat, selectedCharID } from "../stores";
|
||||
import { getCurrentCharacter, getCurrentChat, getDatabase, setCurrentChat, setDatabase } from "../storage/database.svelte";
|
||||
import { selectedCharID } from "../stores.svelte";
|
||||
import { alertInput, alertMd, alertNormal, alertSelect, alertToast } from "../alert";
|
||||
import { sayTTS } from "./tts";
|
||||
import { risuChatParser } from "../parser";
|
||||
import { sendChat } from ".";
|
||||
import { loadLoreBookV3Prompt } from "./lorebook";
|
||||
import { risuChatParser } from "../parser.svelte";
|
||||
import { sendChat } from "./index.svelte";
|
||||
import { loadLoreBookV3Prompt } from "./lorebook.svelte";
|
||||
import { runTrigger } from "./triggers";
|
||||
|
||||
export async function processMultiCommand(command:string) {
|
||||
@@ -40,7 +40,7 @@ export async function processMultiCommand(command:string) {
|
||||
|
||||
|
||||
async function processCommand(command:string, pipe:string):Promise<false | string>{
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const currentChar = db.characters[get(selectedCharID)]
|
||||
const currentChat = currentChar.chats[currentChar.chatPage]
|
||||
let {commandName, arg, namedArg} = commandParser(command, pipe)
|
||||
@@ -180,7 +180,7 @@ async function processCommand(command:string, pipe:string):Promise<false | strin
|
||||
}
|
||||
case 'setvar':{
|
||||
console.log(namedArg, arg)
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
const char = db.characters[selectedChar]
|
||||
const chat = char.chats[char.chatPage]
|
||||
@@ -194,7 +194,7 @@ async function processCommand(command:string, pipe:string):Promise<false | strin
|
||||
return ''
|
||||
}
|
||||
case 'addvar':{
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
const char = db.characters[selectedChar]
|
||||
const chat = char.chats[char.chatPage]
|
||||
@@ -207,7 +207,7 @@ async function processCommand(command:string, pipe:string):Promise<false | strin
|
||||
return ''
|
||||
}
|
||||
case 'getvar':{
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
const char = db.characters[selectedChar]
|
||||
const chat = char.chats[char.chatPage]
|
||||
@@ -222,17 +222,17 @@ async function processCommand(command:string, pipe:string):Promise<false | strin
|
||||
return JSON.stringify(p)
|
||||
}
|
||||
case 'trigger':{
|
||||
const currentChar = get(CurrentCharacter)
|
||||
const currentChar = getCurrentCharacter()
|
||||
if(currentChar.type === 'group'){
|
||||
return;
|
||||
}
|
||||
const triggerResult = await runTrigger(currentChar, 'manual', {
|
||||
chat: get(CurrentChat),
|
||||
chat: getCurrentChat(),
|
||||
manualName: arg
|
||||
});
|
||||
|
||||
if(triggerResult){
|
||||
CurrentChat.set(triggerResult.chat);
|
||||
setCurrentChat(triggerResult.chat);
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
import { DataBase, type Chat, type character } from "src/ts/storage/database";
|
||||
import { getDatabase, type Chat, type character } from "src/ts/storage/database.svelte";
|
||||
import { HypaProcesser } from '../memory/hypamemory'
|
||||
import type { OpenAIChat } from "..";
|
||||
import { stringlizeChat } from "../stringlize";
|
||||
import { get } from "svelte/store";
|
||||
import { getUserName } from "src/ts/util";
|
||||
|
||||
export async function additionalInformations(char: character,chats:Chat,){
|
||||
const processer = new HypaProcesser('MiniLM')
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
|
||||
const info = char.additionalText
|
||||
if(info){
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { OpenAIChat } from ".";
|
||||
import type { character } from "../storage/database";
|
||||
import type { OpenAIChat } from "./index.svelte";
|
||||
import type { character } from "../storage/database.svelte";
|
||||
import { risuChatParser } from "./scripts";
|
||||
|
||||
export function exampleMessage(char:character, userName:string):OpenAIChat[]{
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import localforage from "localforage";
|
||||
import { selectSingleFile } from "../../util";
|
||||
import { v4 } from "uuid";
|
||||
import { DataBase } from "../../storage/database";
|
||||
import { get } from "svelte/store";
|
||||
import { checkImageType } from "../../parser";
|
||||
import { getDatabase } from "../../storage/database.svelte";
|
||||
import { checkImageType } from "../../parser.svelte";
|
||||
|
||||
const inlayStorage = localforage.createInstance({
|
||||
name: 'inlay',
|
||||
@@ -85,7 +83,7 @@ export async function getInlayImage(id: string){
|
||||
}
|
||||
|
||||
export function supportsInlayImage(){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
return db.aiModel.startsWith('gptv') || db.aiModel === 'gemini-pro-vision' || db.aiModel.startsWith('claude-3') || db.aiModel.startsWith('gpt4_turbo') || db.aiModel.startsWith('gpt5') || db.aiModel.startsWith('gpt4o') ||
|
||||
(db.aiModel === 'reverse_proxy' && (
|
||||
db.proxyRequestModel?.startsWith('gptv') || db.proxyRequestModel === 'gemini-pro-vision' || db.proxyRequestModel?.startsWith('claude-3') || db.proxyRequestModel.startsWith('gpt4_turbo') ||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { DataBase, setDatabase } from 'src/ts/storage/database';
|
||||
import { selectedCharID } from 'src/ts/stores';
|
||||
import { getDatabase, setDatabase } from 'src/ts/storage/database.svelte';
|
||||
import { selectedCharID } from 'src/ts/stores.svelte';
|
||||
import { get } from 'svelte/store';
|
||||
import { doingChat, sendChat } from '..';
|
||||
import { downloadFile, isTauri } from 'src/ts/storage/globalApi';
|
||||
import { doingChat, sendChat } from '../index.svelte';
|
||||
import { downloadFile, isTauri } from 'src/ts/globalApi.svelte';
|
||||
import { HypaProcesser } from '../memory/hypamemory';
|
||||
import { BufferToText as BufferToText, selectSingleFile, sleep } from 'src/ts/util';
|
||||
import { postInlayImage } from './image';
|
||||
@@ -19,7 +19,7 @@ async function sendPofile(arg:sendFileArg){
|
||||
let note = ''
|
||||
let speaker = ''
|
||||
let parseMode = 0
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
let currentChar = db.characters[get(selectedCharID)]
|
||||
let currentChat = currentChar.chats[currentChar.chatPage]
|
||||
const lines = arg.file.split('\n')
|
||||
|
||||
@@ -3,11 +3,11 @@ import { findCharacterbyId } from "../util";
|
||||
import { alertConfirm, alertError, alertSelectChar } from "../alert";
|
||||
import { language } from "src/lang";
|
||||
import { get } from "svelte/store";
|
||||
import { DataBase, setDatabase } from "../storage/database";
|
||||
import { selectedCharID } from "../stores";
|
||||
import { getDatabase, setDatabase } from "../storage/database.svelte";
|
||||
import { selectedCharID } from "../stores.svelte";
|
||||
|
||||
export async function addGroupChar(){
|
||||
let db = get(DataBase)
|
||||
let db = getDatabase()
|
||||
let selectedId = get(selectedCharID)
|
||||
let group = db.characters[selectedId]
|
||||
if(group.type === 'group'){
|
||||
@@ -36,7 +36,7 @@ export async function addGroupChar(){
|
||||
|
||||
|
||||
export function rmCharFromGroup(index:number){
|
||||
let db = get(DataBase)
|
||||
let db = getDatabase()
|
||||
let selectedId = get(selectedCharID)
|
||||
let group = db.characters[selectedId]
|
||||
if(group.type === 'group'){
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { get, writable } from "svelte/store";
|
||||
import { DataBase, setDatabase, type character, type MessageGenerationInfo, type Chat } from "../storage/database";
|
||||
import { CharEmotion, selectedCharID } from "../stores";
|
||||
import { type character, type MessageGenerationInfo, type Chat } from "../storage/database.svelte";
|
||||
import { DBState } from '../stores.svelte';
|
||||
import { CharEmotion, selectedCharID } from "../stores.svelte";
|
||||
import { ChatTokenizer, tokenize, tokenizeNum } from "../tokenizer";
|
||||
import { language } from "../../lang";
|
||||
import { alertError } from "../alert";
|
||||
import { loadLoreBookPrompt, loadLoreBookV3Prompt } from "./lorebook";
|
||||
import { loadLoreBookV3Prompt } from "./lorebook.svelte";
|
||||
import { findCharacterbyId, getAuthorNoteDefaultText, getPersonaPrompt, getUserName, isLastCharPunctuation, trimUntilPunctuation } from "../util";
|
||||
import { requestChatData } from "./request";
|
||||
import { stableDiff } from "./stableDiff";
|
||||
@@ -120,10 +121,9 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
chatProcessStage.set(0)
|
||||
}
|
||||
|
||||
let db = get(DataBase)
|
||||
db.statics.messages += 1
|
||||
DBState.db.statics.messages += 1
|
||||
let selectedChar = get(selectedCharID)
|
||||
const nowChatroom = db.characters[selectedChar]
|
||||
const nowChatroom = DBState.db.characters[selectedChar]
|
||||
nowChatroom.lastInteraction = Date.now()
|
||||
let selectedChat = nowChatroom.chatPage
|
||||
nowChatroom.chats[nowChatroom.chatPage].message = nowChatroom.chats[nowChatroom.chatPage].message.map((v) => {
|
||||
@@ -134,7 +134,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
|
||||
let currentChar:character
|
||||
let caculatedChatTokens = 0
|
||||
if(db.aiModel.startsWith('gpt')){
|
||||
if(DBState.db.aiModel.startsWith('gpt')){
|
||||
caculatedChatTokens += 5
|
||||
}
|
||||
else{
|
||||
@@ -188,27 +188,27 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
|
||||
let chatAdditonalTokens = arg.chatAdditonalTokens ?? caculatedChatTokens
|
||||
const tokenizer = new ChatTokenizer(chatAdditonalTokens, db.aiModel.startsWith('gpt') ? 'noName' : 'name')
|
||||
const tokenizer = new ChatTokenizer(chatAdditonalTokens, DBState.db.aiModel.startsWith('gpt') ? 'noName' : 'name')
|
||||
let currentChat = runCurrentChatFunction(nowChatroom.chats[selectedChat])
|
||||
nowChatroom.chats[selectedChat] = currentChat
|
||||
let maxContextTokens = db.maxContext
|
||||
let maxContextTokens = DBState.db.maxContext
|
||||
|
||||
if(db.aiModel === 'gpt35'){
|
||||
if(DBState.db.aiModel === 'gpt35'){
|
||||
if(maxContextTokens > 4000){
|
||||
maxContextTokens = 4000
|
||||
}
|
||||
}
|
||||
if(db.aiModel === 'gpt35_16k' || db.aiModel === 'gpt35_16k_0613'){
|
||||
if(DBState.db.aiModel === 'gpt35_16k' || DBState.db.aiModel === 'gpt35_16k_0613'){
|
||||
if(maxContextTokens > 16000){
|
||||
maxContextTokens = 16000
|
||||
}
|
||||
}
|
||||
if(db.aiModel === 'gpt4'){
|
||||
if(DBState.db.aiModel === 'gpt4'){
|
||||
if(maxContextTokens > 8000){
|
||||
maxContextTokens = 8000
|
||||
}
|
||||
}
|
||||
if(db.aiModel === 'deepai'){
|
||||
if(DBState.db.aiModel === 'deepai'){
|
||||
if(maxContextTokens > 3000){
|
||||
maxContextTokens = 3000
|
||||
}
|
||||
@@ -229,7 +229,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
'personaPrompt':([] as OpenAIChat[])
|
||||
}
|
||||
|
||||
let promptTemplate = structuredClone(db.promptTemplate)
|
||||
let promptTemplate = safeStructuredClone(DBState.db.promptTemplate)
|
||||
const usingPromptTemplate = !!promptTemplate
|
||||
if(promptTemplate){
|
||||
let hasPostEverything = false
|
||||
@@ -246,7 +246,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
})
|
||||
}
|
||||
}
|
||||
if(currentChar.utilityBot && (!(usingPromptTemplate && db.promptSettings.utilOverride))){
|
||||
if(currentChar.utilityBot && (!(usingPromptTemplate && DBState.db.promptSettings.utilOverride))){
|
||||
promptTemplate = [
|
||||
{
|
||||
"type": "plain",
|
||||
@@ -278,7 +278,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
|
||||
if((!currentChar.utilityBot) && (!promptTemplate)){
|
||||
const mainp = currentChar.systemPrompt?.replaceAll('{{original}}', db.mainPrompt) || db.mainPrompt
|
||||
const mainp = currentChar.systemPrompt?.replaceAll('{{original}}', DBState.db.mainPrompt) || DBState.db.mainPrompt
|
||||
|
||||
|
||||
function formatPrompt(data:string){
|
||||
@@ -300,13 +300,13 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
return chatObjects;
|
||||
}
|
||||
|
||||
unformated.main.push(...formatPrompt(risuChatParser(mainp + ((db.additionalPrompt === '' || (!db.promptPreprocess)) ? '' : `\n${db.additionalPrompt}`), {chara: currentChar})))
|
||||
unformated.main.push(...formatPrompt(risuChatParser(mainp + ((DBState.db.additionalPrompt === '' || (!DBState.db.promptPreprocess)) ? '' : `\n${DBState.db.additionalPrompt}`), {chara: currentChar})))
|
||||
|
||||
if(db.jailbreakToggle){
|
||||
unformated.jailbreak.push(...formatPrompt(risuChatParser(db.jailbreak, {chara: currentChar})))
|
||||
if(DBState.db.jailbreakToggle){
|
||||
unformated.jailbreak.push(...formatPrompt(risuChatParser(DBState.db.jailbreak, {chara: currentChar})))
|
||||
}
|
||||
|
||||
unformated.globalNote.push(...formatPrompt(risuChatParser(currentChar.replaceGlobalNote?.replaceAll('{{original}}', db.globalNote) || db.globalNote, {chara:currentChar})))
|
||||
unformated.globalNote.push(...formatPrompt(risuChatParser(currentChar.replaceGlobalNote?.replaceAll('{{original}}', DBState.db.globalNote) || DBState.db.globalNote, {chara:currentChar})))
|
||||
}
|
||||
|
||||
if(currentChat.note){
|
||||
@@ -322,7 +322,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
})
|
||||
}
|
||||
|
||||
if(db.chainOfThought && (!(usingPromptTemplate && db.promptSettings.customChainOfThought))){
|
||||
if(DBState.db.chainOfThought && (!(usingPromptTemplate && DBState.db.promptSettings.customChainOfThought))){
|
||||
unformated.postEverything.push({
|
||||
role: 'system',
|
||||
content: `<instruction> - before respond everything, Think step by step as a ai assistant how would you respond inside <Thoughts> xml tag. this must be less than 5 paragraphs.</instruction>`
|
||||
@@ -330,7 +330,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
|
||||
{
|
||||
let description = risuChatParser((db.promptPreprocess ? db.descriptionPrefix: '') + currentChar.desc, {chara: currentChar})
|
||||
let description = risuChatParser((DBState.db.promptPreprocess ? DBState.db.descriptionPrefix: '') + currentChar.desc, {chara: currentChar})
|
||||
|
||||
const additionalInfo = await additionalInformations(currentChar, currentChat)
|
||||
|
||||
@@ -390,7 +390,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
}
|
||||
|
||||
if(db.personaPrompt){
|
||||
if(DBState.db.personaPrompt){
|
||||
unformated.personaPrompt.push({
|
||||
role: 'system',
|
||||
content: risuChatParser(getPersonaPrompt(), {chara: currentChar})
|
||||
@@ -434,7 +434,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
|
||||
//await tokenize currernt
|
||||
let currentTokens = db.maxResponse
|
||||
let currentTokens = DBState.db.maxResponse
|
||||
let supaMemoryCardUsed = false
|
||||
|
||||
//for unexpected error
|
||||
@@ -466,7 +466,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
for(const card of template){
|
||||
switch(card.type){
|
||||
case 'persona':{
|
||||
let pmt = structuredClone(unformated.personaPrompt)
|
||||
let pmt = safeStructuredClone(unformated.personaPrompt)
|
||||
if(card.innerFormat && pmt.length > 0){
|
||||
for(let i=0;i<pmt.length;i++){
|
||||
pmt[i].content = risuChatParser(positionParser(card.innerFormat), {chara: currentChar}).replace('{{slot}}', pmt[i].content)
|
||||
@@ -477,7 +477,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
break
|
||||
}
|
||||
case 'description':{
|
||||
let pmt = structuredClone(unformated.description)
|
||||
let pmt = safeStructuredClone(unformated.description)
|
||||
if(card.innerFormat && pmt.length > 0){
|
||||
for(let i=0;i<pmt.length;i++){
|
||||
pmt[i].content = risuChatParser(positionParser(card.innerFormat), {chara: currentChar}).replace('{{slot}}', pmt[i].content)
|
||||
@@ -488,7 +488,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
break
|
||||
}
|
||||
case 'authornote':{
|
||||
let pmt = structuredClone(unformated.authorNote)
|
||||
let pmt = safeStructuredClone(unformated.authorNote)
|
||||
if(card.innerFormat && pmt.length > 0){
|
||||
for(let i=0;i<pmt.length;i++){
|
||||
pmt[i].content = risuChatParser(positionParser(card.innerFormat), {chara: currentChar}).replace('{{slot}}', pmt[i].content || card.defaultText || '')
|
||||
@@ -504,10 +504,10 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
case 'postEverything':{
|
||||
await tokenizeChatArray(unformated.postEverything)
|
||||
if(usingPromptTemplate && db.promptSettings.postEndInnerFormat){
|
||||
if(usingPromptTemplate && DBState.db.promptSettings.postEndInnerFormat){
|
||||
await tokenizeChatArray([{
|
||||
role: 'system',
|
||||
content: db.promptSettings.postEndInnerFormat
|
||||
content: DBState.db.promptSettings.postEndInnerFormat
|
||||
}])
|
||||
}
|
||||
break
|
||||
@@ -515,10 +515,10 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
case 'plain':
|
||||
case 'jailbreak':
|
||||
case 'cot':{
|
||||
if((!db.jailbreakToggle) && (card.type === 'jailbreak')){
|
||||
if((!DBState.db.jailbreakToggle) && (card.type === 'jailbreak')){
|
||||
continue
|
||||
}
|
||||
if((!db.chainOfThought) && (card.type === 'cot')){
|
||||
if((!DBState.db.chainOfThought) && (card.type === 'cot')){
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -573,7 +573,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
let chats = unformated.chats.slice(start, end)
|
||||
|
||||
if(usingPromptTemplate && db.promptSettings.sendChatAsSystem && (!card.chatAsOriginalOnSystem)){
|
||||
if(usingPromptTemplate && DBState.db.promptSettings.sendChatAsSystem && (!card.chatAsOriginalOnSystem)){
|
||||
chats = systemizeChat(chats)
|
||||
}
|
||||
await tokenizeChatArray(chats)
|
||||
@@ -603,7 +603,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
|
||||
let chats:OpenAIChat[] = examples
|
||||
|
||||
if(!db.aiModel.startsWith('novelai')){
|
||||
if(!DBState.db.aiModel.startsWith('novelai')){
|
||||
chats.push({
|
||||
role: 'system',
|
||||
content: '[Start a new chat]',
|
||||
@@ -621,7 +621,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
'editprocess'))
|
||||
}
|
||||
|
||||
if(usingPromptTemplate && db.promptSettings.sendName){
|
||||
if(usingPromptTemplate && DBState.db.promptSettings.sendName){
|
||||
chat.content = `${currentChar.name}: ${chat.content}`
|
||||
chat.attr = ['nameAdded']
|
||||
}
|
||||
@@ -699,20 +699,35 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
|
||||
let attr:string[] = []
|
||||
let role:'user'|'assistant'|'system' = msg.role === 'user' ? 'user' : 'assistant'
|
||||
|
||||
if(nowChatroom.type === 'group' || (usingPromptTemplate && db.promptSettings.sendName)){
|
||||
formatedChat = name + ': ' + formatedChat
|
||||
attr.push('nameAdded')
|
||||
if(
|
||||
(nowChatroom.type === 'group' && findCharacterbyIdwithCache(msg.saying).chaId !== currentChar.chaId) ||
|
||||
(nowChatroom.type === 'group' && DBState.db.groupOtherBotRole === 'assistant') ||
|
||||
(usingPromptTemplate && DBState.db.promptSettings.sendName)
|
||||
){
|
||||
const form = DBState.db.groupTemplate || `<{{char}}\'s Message>\n{{slot}}\n</{{char}}\'s Message>`
|
||||
formatedChat = risuChatParser(form, {chara: findCharacterbyIdwithCache(msg.saying).name}).replace('{{slot}}', formatedChat)
|
||||
switch(DBState.db.groupOtherBotRole){
|
||||
case 'user':
|
||||
case 'assistant':
|
||||
case 'system':
|
||||
role = DBState.db.groupOtherBotRole
|
||||
break
|
||||
default:
|
||||
role = 'assistant'
|
||||
break
|
||||
}
|
||||
}
|
||||
if(usingPromptTemplate && db.promptSettings.maxThoughtTagDepth !== -1){
|
||||
if(usingPromptTemplate && DBState.db.promptSettings.maxThoughtTagDepth !== -1){
|
||||
const depth = ms.length - index
|
||||
if(depth >= db.promptSettings.maxThoughtTagDepth){
|
||||
if(depth >= DBState.db.promptSettings.maxThoughtTagDepth){
|
||||
formatedChat = formatedChat.replace(/<Thoughts>(.+?)<\/Thoughts>/gm, '')
|
||||
}
|
||||
}
|
||||
|
||||
const chat:OpenAIChat = {
|
||||
role: msg.role === 'user' ? 'user' : 'assistant',
|
||||
role: role,
|
||||
content: formatedChat,
|
||||
memo: msg.chatId,
|
||||
attr: attr,
|
||||
@@ -725,6 +740,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
currentTokens += await tokenizer.tokenizeChat(chat)
|
||||
index++
|
||||
}
|
||||
console.log(JSON.stringify(chats, null, 2))
|
||||
|
||||
const depthPrompts = lorepmt.actives.filter(v => {
|
||||
return (v.pos === 'depth' && v.depth > 0) || v.pos === 'reverse_depth'
|
||||
@@ -738,9 +754,9 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
currentTokens += await tokenizer.tokenizeChat(chat)
|
||||
}
|
||||
|
||||
if(nowChatroom.supaMemory && (db.supaModelType !== 'none' || db.hanuraiEnable || db.hypav2)){
|
||||
if(nowChatroom.supaMemory && (DBState.db.supaModelType !== 'none' || DBState.db.hanuraiEnable || DBState.db.hypav2)){
|
||||
chatProcessStage.set(2)
|
||||
if(db.hanuraiEnable){
|
||||
if(DBState.db.hanuraiEnable){
|
||||
const hn = await hanuraiMemory(chats, {
|
||||
currentTokens,
|
||||
maxContextTokens,
|
||||
@@ -754,7 +770,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
chats = hn.chats
|
||||
currentTokens = hn.tokens
|
||||
}
|
||||
else if(db.hypav2){ //HypaV2 support needs to be changed like this.
|
||||
else if(DBState.db.hypav2){ //HypaV2 support needs to be changed like this.
|
||||
const sp = await hypaMemoryV2(chats, currentTokens, maxContextTokens, currentChat, nowChatroom, tokenizer)
|
||||
console.log("All chats: ", chats)
|
||||
if(sp.error){
|
||||
@@ -765,13 +781,12 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
chats = sp.chats
|
||||
currentTokens = sp.currentTokens
|
||||
currentChat.hypaV2Data = sp.memory ?? currentChat.hypaV2Data
|
||||
db.characters[selectedChar].chats[selectedChat].hypaV2Data = currentChat.hypaV2Data
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].hypaV2Data = currentChat.hypaV2Data
|
||||
console.log(currentChat.hypaV2Data)
|
||||
DataBase.set(db)
|
||||
}
|
||||
else{
|
||||
const sp = await supaMemory(chats, currentTokens, maxContextTokens, currentChat, nowChatroom, tokenizer, {
|
||||
asHyper: db.hypaMemory
|
||||
asHyper: DBState.db.hypaMemory
|
||||
})
|
||||
if(sp.error){
|
||||
alertError(sp.error)
|
||||
@@ -780,9 +795,8 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
chats = sp.chats
|
||||
currentTokens = sp.currentTokens
|
||||
currentChat.supaMemoryData = sp.memory ?? currentChat.supaMemoryData
|
||||
db.characters[selectedChar].chats[selectedChat].supaMemoryData = currentChat.supaMemoryData
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].supaMemoryData = currentChat.supaMemoryData
|
||||
console.log(currentChat.supaMemoryData)
|
||||
DataBase.set(db)
|
||||
currentChat.lastMemory = sp.lastId ?? currentChat.lastMemory;
|
||||
}
|
||||
chatProcessStage.set(1)
|
||||
@@ -801,7 +815,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
currentChat.lastMemory = chats[0].memo
|
||||
}
|
||||
|
||||
let biases:[string,number][] = db.bias.concat(currentChar.bias).map((v) => {
|
||||
let biases:[string,number][] = DBState.db.bias.concat(currentChar.bias).map((v) => {
|
||||
return [risuChatParser(v[0].replaceAll("\\n","\n").replaceAll("\\r","\r").replaceAll("\\\\","\\"), {chara: currentChar}),v[1]]
|
||||
})
|
||||
|
||||
@@ -867,13 +881,13 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
//make into one
|
||||
|
||||
let formated:OpenAIChat[] = []
|
||||
const formatOrder = structuredClone(db.formatingOrder)
|
||||
const formatOrder = safeStructuredClone(DBState.db.formatingOrder)
|
||||
if(formatOrder){
|
||||
formatOrder.push('postEverything')
|
||||
}
|
||||
|
||||
//continue chat model
|
||||
if(arg.continue && (db.aiModel.startsWith('claude') || db.aiModel.startsWith('gpt') || db.aiModel.startsWith('openrouter') || db.aiModel.startsWith('reverse_proxy'))){
|
||||
if(arg.continue && (DBState.db.aiModel.startsWith('claude') || DBState.db.aiModel.startsWith('gpt') || DBState.db.aiModel.startsWith('openrouter') || DBState.db.aiModel.startsWith('reverse_proxy'))){
|
||||
unformated.postEverything.push({
|
||||
role: 'system',
|
||||
content: '[Continue the last response]'
|
||||
@@ -885,7 +899,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
if(!chat.content.trim()){
|
||||
continue
|
||||
}
|
||||
if(!(db.aiModel.startsWith('gpt') || db.aiModel.startsWith('claude') || db.aiModel === 'openrouter' || db.aiModel === 'reverse_proxy')){
|
||||
if(!(DBState.db.aiModel.startsWith('gpt') || DBState.db.aiModel.startsWith('claude') || DBState.db.aiModel === 'openrouter' || DBState.db.aiModel === 'reverse_proxy')){
|
||||
formated.push(chat)
|
||||
continue
|
||||
}
|
||||
@@ -911,7 +925,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
for(const card of template){
|
||||
switch(card.type){
|
||||
case 'persona':{
|
||||
let pmt = structuredClone(unformated.personaPrompt)
|
||||
let pmt = safeStructuredClone(unformated.personaPrompt)
|
||||
if(card.innerFormat && pmt.length > 0){
|
||||
for(let i=0;i<pmt.length;i++){
|
||||
pmt[i].content = risuChatParser(positionParser(card.innerFormat), {chara: currentChar}).replace('{{slot}}', pmt[i].content)
|
||||
@@ -922,7 +936,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
break
|
||||
}
|
||||
case 'description':{
|
||||
let pmt = structuredClone(unformated.description)
|
||||
let pmt = safeStructuredClone(unformated.description)
|
||||
if(card.innerFormat && pmt.length > 0){
|
||||
for(let i=0;i<pmt.length;i++){
|
||||
pmt[i].content = risuChatParser(positionParser(card.innerFormat), {chara: currentChar}).replace('{{slot}}', pmt[i].content)
|
||||
@@ -933,7 +947,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
break
|
||||
}
|
||||
case 'authornote':{
|
||||
let pmt = structuredClone(unformated.authorNote)
|
||||
let pmt = safeStructuredClone(unformated.authorNote)
|
||||
if(card.innerFormat && pmt.length > 0){
|
||||
for(let i=0;i<pmt.length;i++){
|
||||
pmt[i].content = risuChatParser(positionParser(card.innerFormat), {chara: currentChar}).replace('{{slot}}', pmt[i].content || card.defaultText || '')
|
||||
@@ -949,10 +963,10 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
case 'postEverything':{
|
||||
pushPrompts(unformated.postEverything)
|
||||
if(usingPromptTemplate && db.promptSettings.postEndInnerFormat){
|
||||
if(usingPromptTemplate && DBState.db.promptSettings.postEndInnerFormat){
|
||||
pushPrompts([{
|
||||
role: 'system',
|
||||
content: db.promptSettings.postEndInnerFormat
|
||||
content: DBState.db.promptSettings.postEndInnerFormat
|
||||
}])
|
||||
}
|
||||
break
|
||||
@@ -960,10 +974,10 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
case 'plain':
|
||||
case 'jailbreak':
|
||||
case 'cot':{
|
||||
if((!db.jailbreakToggle) && (card.type === 'jailbreak')){
|
||||
if((!DBState.db.jailbreakToggle) && (card.type === 'jailbreak')){
|
||||
continue
|
||||
}
|
||||
if((!db.chainOfThought) && (card.type === 'cot')){
|
||||
if((!DBState.db.chainOfThought) && (card.type === 'cot')){
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -1018,14 +1032,14 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
|
||||
let chats = unformated.chats.slice(start, end)
|
||||
if(usingPromptTemplate && db.promptSettings.sendChatAsSystem && (!card.chatAsOriginalOnSystem)){
|
||||
if(usingPromptTemplate && DBState.db.promptSettings.sendChatAsSystem && (!card.chatAsOriginalOnSystem)){
|
||||
chats = systemizeChat(chats)
|
||||
}
|
||||
pushPrompts(chats)
|
||||
break
|
||||
}
|
||||
case 'memory':{
|
||||
let pmt = structuredClone(memories)
|
||||
let pmt = safeStructuredClone(memories)
|
||||
if(card.innerFormat && pmt.length > 0){
|
||||
for(let i=0;i<pmt.length;i++){
|
||||
pmt[i].content = risuChatParser(card.innerFormat, {chara: currentChar}).replace('{{slot}}', pmt[i].content)
|
||||
@@ -1094,7 +1108,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
|
||||
//estimate tokens
|
||||
let outputTokens = db.maxResponse
|
||||
let outputTokens = DBState.db.maxResponse
|
||||
if(inputTokens + outputTokens > maxContextTokens){
|
||||
outputTokens = maxContextTokens - inputTokens
|
||||
}
|
||||
@@ -1138,14 +1152,14 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
else if(req.type === 'streaming'){
|
||||
const reader = req.result.getReader()
|
||||
let msgIndex = db.characters[selectedChar].chats[selectedChat].message.length
|
||||
let msgIndex = DBState.db.characters[selectedChar].chats[selectedChat].message.length
|
||||
let prefix = ''
|
||||
if(arg.continue){
|
||||
msgIndex -= 1
|
||||
prefix = db.characters[selectedChar].chats[selectedChat].message[msgIndex].data
|
||||
prefix = DBState.db.characters[selectedChar].chats[selectedChat].message[msgIndex].data
|
||||
}
|
||||
else{
|
||||
db.characters[selectedChar].chats[selectedChat].message.push({
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].message.push({
|
||||
role: 'char',
|
||||
data: "",
|
||||
saying: currentChar.chaId,
|
||||
@@ -1153,7 +1167,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
generationInfo,
|
||||
})
|
||||
}
|
||||
db.characters[selectedChar].chats[selectedChat].isStreaming = true
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].isStreaming = true
|
||||
let lastResponseChunk:{[key:string]:string} = {}
|
||||
while(abortSignal.aborted === false){
|
||||
const readed = (await reader.read())
|
||||
@@ -1164,27 +1178,25 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
if(!result){
|
||||
result = ''
|
||||
}
|
||||
if(db.removeIncompleteResponse){
|
||||
if(DBState.db.removeIncompleteResponse){
|
||||
result = trimUntilPunctuation(result)
|
||||
}
|
||||
let result2 = await processScriptFull(nowChatroom, reformatContent(prefix + result), 'editoutput', msgIndex)
|
||||
db.characters[selectedChar].chats[selectedChat].message[msgIndex].data = result2.data
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].message[msgIndex].data = result2.data
|
||||
emoChanged = result2.emoChanged
|
||||
db.characters[selectedChar].reloadKeys += 1
|
||||
setDatabase(db)
|
||||
DBState.db.characters[selectedChar].reloadKeys += 1
|
||||
}
|
||||
if(readed.done){
|
||||
db.characters[selectedChar].chats[selectedChat].isStreaming = false
|
||||
db.characters[selectedChar].reloadKeys += 1
|
||||
setDatabase(db)
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].isStreaming = false
|
||||
DBState.db.characters[selectedChar].reloadKeys += 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
addRerolls(generationId, Object.values(lastResponseChunk))
|
||||
|
||||
db.characters[selectedChar].chats[selectedChat] = runCurrentChatFunction(db.characters[selectedChar].chats[selectedChat])
|
||||
currentChat = db.characters[selectedChar].chats[selectedChat]
|
||||
DBState.db.characters[selectedChar].chats[selectedChat] = runCurrentChatFunction(DBState.db.characters[selectedChar].chats[selectedChat])
|
||||
currentChat = DBState.db.characters[selectedChar].chats[selectedChat]
|
||||
const triggerResult = await runTrigger(currentChar, 'output', {chat:currentChat})
|
||||
if(triggerResult && triggerResult.chat){
|
||||
currentChat = triggerResult.chat
|
||||
@@ -1194,15 +1206,13 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
const inlayr = runInlayScreen(currentChar, currentChat.message[msgIndex].data)
|
||||
currentChat.message[msgIndex].data = inlayr.text
|
||||
db.characters[selectedChar].chats[selectedChat] = currentChat
|
||||
setDatabase(db)
|
||||
DBState.db.characters[selectedChar].chats[selectedChat] = currentChat
|
||||
if(inlayr.promise){
|
||||
const t = await inlayr.promise
|
||||
currentChat.message[msgIndex].data = t
|
||||
db.characters[selectedChar].chats[selectedChat] = currentChat
|
||||
setDatabase(db)
|
||||
DBState.db.characters[selectedChar].chats[selectedChat] = currentChat
|
||||
}
|
||||
if(db.ttsAutoSpeech){
|
||||
if(DBState.db.ttsAutoSpeech){
|
||||
await sayTTS(currentChar, result)
|
||||
}
|
||||
}
|
||||
@@ -1214,14 +1224,14 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
for(let i=0;i<msgs.length;i++){
|
||||
let msg = msgs[i]
|
||||
let mess = msg[1]
|
||||
let msgIndex = db.characters[selectedChar].chats[selectedChat].message.length
|
||||
let msgIndex = DBState.db.characters[selectedChar].chats[selectedChat].message.length
|
||||
let result2 = await processScriptFull(nowChatroom, reformatContent(mess), 'editoutput', msgIndex)
|
||||
if(i === 0 && arg.continue){
|
||||
msgIndex -= 1
|
||||
let beforeChat = db.characters[selectedChar].chats[selectedChat].message[msgIndex]
|
||||
let beforeChat = DBState.db.characters[selectedChar].chats[selectedChat].message[msgIndex]
|
||||
result2 = await processScriptFull(nowChatroom, reformatContent(beforeChat.data + mess), 'editoutput', msgIndex)
|
||||
}
|
||||
if(db.removeIncompleteResponse){
|
||||
if(DBState.db.removeIncompleteResponse){
|
||||
result2.data = trimUntilPunctuation(result2.data)
|
||||
}
|
||||
result = result2.data
|
||||
@@ -1229,7 +1239,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
result = inlayResult.text
|
||||
emoChanged = result2.emoChanged
|
||||
if(i === 0 && arg.continue){
|
||||
db.characters[selectedChar].chats[selectedChat].message[msgIndex] = {
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].message[msgIndex] = {
|
||||
role: 'char',
|
||||
data: result,
|
||||
saying: currentChar.chaId,
|
||||
@@ -1238,45 +1248,43 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
}
|
||||
if(inlayResult.promise){
|
||||
const p = await inlayResult.promise
|
||||
db.characters[selectedChar].chats[selectedChat].message[msgIndex].data = p
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].message[msgIndex].data = p
|
||||
}
|
||||
}
|
||||
else if(i===0){
|
||||
db.characters[selectedChar].chats[selectedChat].message.push({
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].message.push({
|
||||
role: msg[0],
|
||||
data: result,
|
||||
saying: currentChar.chaId,
|
||||
time: Date.now(),
|
||||
generationInfo
|
||||
})
|
||||
const ind = db.characters[selectedChar].chats[selectedChat].message.length - 1
|
||||
const ind = DBState.db.characters[selectedChar].chats[selectedChat].message.length - 1
|
||||
if(inlayResult.promise){
|
||||
const p = await inlayResult.promise
|
||||
db.characters[selectedChar].chats[selectedChat].message[ind].data = p
|
||||
DBState.db.characters[selectedChar].chats[selectedChat].message[ind].data = p
|
||||
}
|
||||
mrerolls.push(result)
|
||||
}
|
||||
else{
|
||||
mrerolls.push(result)
|
||||
}
|
||||
db.characters[selectedChar].reloadKeys += 1
|
||||
if(db.ttsAutoSpeech){
|
||||
DBState.db.characters[selectedChar].reloadKeys += 1
|
||||
if(DBState.db.ttsAutoSpeech){
|
||||
await sayTTS(currentChar, result)
|
||||
}
|
||||
setDatabase(db)
|
||||
}
|
||||
|
||||
if(mrerolls.length >1){
|
||||
addRerolls(generationId, mrerolls)
|
||||
}
|
||||
|
||||
db.characters[selectedChar].chats[selectedChat] = runCurrentChatFunction(db.characters[selectedChar].chats[selectedChat])
|
||||
currentChat = db.characters[selectedChar].chats[selectedChat]
|
||||
DBState.db.characters[selectedChar].chats[selectedChat] = runCurrentChatFunction(DBState.db.characters[selectedChar].chats[selectedChat])
|
||||
currentChat = DBState.db.characters[selectedChar].chats[selectedChat]
|
||||
|
||||
const triggerResult = await runTrigger(currentChar, 'output', {chat:currentChat})
|
||||
if(triggerResult && triggerResult.chat){
|
||||
db.characters[selectedChar].chats[selectedChat] = triggerResult.chat
|
||||
setDatabase(db)
|
||||
DBState.db.characters[selectedChar].chats[selectedChat] = triggerResult.chat
|
||||
}
|
||||
if(triggerResult && triggerResult.sendAIprompt){
|
||||
resendChat = true
|
||||
@@ -1285,11 +1293,11 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
|
||||
let needsAutoContinue = false
|
||||
const resultTokens = await tokenize(result) + (arg.usedContinueTokens || 0)
|
||||
if(db.autoContinueMinTokens > 0 && resultTokens < db.autoContinueMinTokens){
|
||||
if(DBState.db.autoContinueMinTokens > 0 && resultTokens < DBState.db.autoContinueMinTokens){
|
||||
needsAutoContinue = true
|
||||
}
|
||||
|
||||
if(db.autoContinueChat && (!isLastCharPunctuation(result))){
|
||||
if(DBState.db.autoContinueChat && (!isLastCharPunctuation(result))){
|
||||
//if result doesn't end with punctuation or special characters, auto continue
|
||||
needsAutoContinue = true
|
||||
}
|
||||
@@ -1358,7 +1366,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
tempEmotion.splice(0, 1)
|
||||
}
|
||||
|
||||
if(db.emotionProcesser === 'embedding'){
|
||||
if(DBState.db.emotionProcesser === 'embedding'){
|
||||
const hypaProcesser = new HypaProcesser('MiniLM')
|
||||
await hypaProcesser.addText(emotionList.map((v) => 'emotion:' + v))
|
||||
let searched = (await hypaProcesser.similaritySearchScored(result)).map((v) => {
|
||||
@@ -1437,7 +1445,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
const promptbody:OpenAIChat[] = [
|
||||
{
|
||||
role:'system',
|
||||
content: `${db.emotionPrompt2 || "From the list below, choose a word that best represents a character's outfit description, action, or emotion in their dialogue. Prioritize selecting words related to outfit first, then action, and lastly emotion. Print out the chosen word."}\n\n list: ${shuffleArray(emotionList).join(', ')} \noutput only one word.`
|
||||
content: `${DBState.db.emotionPrompt2 || "From the list below, choose a word that best represents a character's outfit description, action, or emotion in their dialogue. Prioritize selecting words related to outfit first, then action, and lastly emotion. Print out the chosen word."}\n\n list: ${shuffleArray(emotionList).join(', ')} \noutput only one word.`
|
||||
},
|
||||
{
|
||||
role: 'user',
|
||||
@@ -1457,9 +1465,8 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
formated: promptbody,
|
||||
bias: emobias,
|
||||
currentChar: currentChar,
|
||||
temperature: 0.4,
|
||||
maxTokens: 30,
|
||||
}, 'submodel', abortSignal)
|
||||
}, 'emotion', abortSignal)
|
||||
|
||||
if(rq.type === 'fail' || rq.type === 'streaming' || rq.type === 'multiline'){
|
||||
if(abortSignal.aborted){
|
||||
@@ -1520,7 +1527,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{
|
||||
alertError("Stable diffusion in group chat is not supported")
|
||||
}
|
||||
|
||||
const msgs = db.characters[selectedChar].chats[selectedChat].message
|
||||
const msgs = DBState.db.characters[selectedChar].chats[selectedChat].message
|
||||
let msgStr = ''
|
||||
for(let i = (msgs.length - 1);i>=0;i--){
|
||||
if(msgs[i].role === 'char'){
|
||||
@@ -1,4 +1,4 @@
|
||||
import { getChatVar, getGlobalChatVar } from "../parser";
|
||||
import { getChatVar, getGlobalChatVar } from "../parser.svelte";
|
||||
|
||||
function toRPN(expression:string) {
|
||||
let outputQueue = '';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { writeInlayImage } from "./files/image";
|
||||
import type { character } from "../storage/database";
|
||||
import type { character } from "../storage/database.svelte";
|
||||
import { generateAIImage } from "./stableDiff";
|
||||
|
||||
const imggenRegex = [/<ImgGen="(.+?)">/gi, /{{ImgGen="(.+?)"}}/gi] as const
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
import { get } from "svelte/store";
|
||||
import {selectedCharID} from '../stores'
|
||||
import { DataBase, setDatabase, type Message, type loreBook } from "../storage/database";
|
||||
import {selectedCharID} from '../stores.svelte'
|
||||
import { type Message, type loreBook } from "../storage/database.svelte";
|
||||
import { DBState } from '../stores.svelte';
|
||||
import { tokenize } from "../tokenizer";
|
||||
import { checkNullish, selectSingleFile } from "../util";
|
||||
import { checkNullish, findCharacterbyId, selectSingleFile } from "../util";
|
||||
import { alertError, alertNormal } from "../alert";
|
||||
import { language } from "../../lang";
|
||||
import { downloadFile } from "../storage/globalApi";
|
||||
import { HypaProcesser } from "./memory/hypamemory";
|
||||
import { downloadFile } from "../globalApi.svelte";
|
||||
import { getModuleLorebooks } from "./modules";
|
||||
import { CCardLib } from "@risuai/ccardlib";
|
||||
|
||||
export function addLorebook(type:number) {
|
||||
let selectedID = get(selectedCharID)
|
||||
let db = get(DataBase)
|
||||
const selectedID = get(selectedCharID)
|
||||
if(type === 0){
|
||||
db.characters[selectedID].globalLore.push({
|
||||
DBState.db.characters[selectedID].globalLore.push({
|
||||
key: '',
|
||||
comment: `New Lore ${db.characters[selectedID].globalLore.length + 1}`,
|
||||
comment: `New Lore ${DBState.db.characters[selectedID].globalLore.length + 1}`,
|
||||
content: '',
|
||||
mode: 'normal',
|
||||
insertorder: 100,
|
||||
@@ -26,10 +25,10 @@ export function addLorebook(type:number) {
|
||||
})
|
||||
}
|
||||
else{
|
||||
const page = db.characters[selectedID].chatPage
|
||||
db.characters[selectedID].chats[page].localLore.push({
|
||||
const page = DBState.db.characters[selectedID].chatPage
|
||||
DBState.db.characters[selectedID].chats[page].localLore.push({
|
||||
key: '',
|
||||
comment: `New Lore ${db.characters[selectedID].chats[page].localLore.length + 1}`,
|
||||
comment: `New Lore ${DBState.db.characters[selectedID].chats[page].localLore.length + 1}`,
|
||||
content: '',
|
||||
mode: 'normal',
|
||||
insertorder: 100,
|
||||
@@ -38,245 +37,145 @@ export function addLorebook(type:number) {
|
||||
selective: false
|
||||
})
|
||||
}
|
||||
setDatabase(db)
|
||||
}
|
||||
|
||||
interface formatedLore{
|
||||
keys:string[]|'always'|{type:'regex',regex:string},
|
||||
secondKey:string[]|{type:'regex',regex:string}
|
||||
content: string
|
||||
order: number
|
||||
activatied: boolean
|
||||
}
|
||||
|
||||
const rmRegex = / |\n/g
|
||||
|
||||
export async function loadLoreBookPrompt(){
|
||||
|
||||
const selectedID = get(selectedCharID)
|
||||
const db = get(DataBase)
|
||||
const char = db.characters[selectedID]
|
||||
const page = char.chatPage
|
||||
const characterLore = char.globalLore ?? []
|
||||
const chatLore = char.chats[page].localLore ?? []
|
||||
const moduleLorebook = getModuleLorebooks()
|
||||
const fullLore = characterLore.concat(chatLore).concat(moduleLorebook)
|
||||
const currentChat = char.chats[page].message
|
||||
const loreDepth = char.loreSettings?.scanDepth ?? db.loreBookDepth
|
||||
const loreToken = char.loreSettings?.tokenBudget ?? db.loreBookToken
|
||||
const fullWordMatching = char.loreSettings?.fullWordMatching ?? false
|
||||
|
||||
let activatiedPrompt: string[] = []
|
||||
|
||||
let formatedLore:formatedLore[] = []
|
||||
|
||||
for (const lore of fullLore){
|
||||
if(lore){
|
||||
if(lore.key.length > 1 || lore.alwaysActive){
|
||||
if(!checkNullish(lore.activationPercent)){
|
||||
let activationPercent = lore.activationPercent
|
||||
if(isNaN(activationPercent) || !activationPercent || activationPercent < 0){
|
||||
activationPercent = 0
|
||||
}
|
||||
if(activationPercent < (Math.random() * 100)){
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if(lore.key?.startsWith('@@@')){
|
||||
lore.key = lore.key.replace('@@@','@@')
|
||||
}
|
||||
formatedLore.push({
|
||||
keys: lore.alwaysActive ? 'always' : (lore.key?.startsWith("@@regex ")) ? ({type:'regex',regex:lore.key.replace('@@regex ','')}) :
|
||||
(lore.key ?? '').replace(rmRegex, '').toLocaleLowerCase().split(',').filter((a) => {
|
||||
return a.length > 1
|
||||
}),
|
||||
secondKey: lore.selective ? ((lore.secondkey?.startsWith("@@regex ")) ? ({type:'regex',regex:lore.secondkey.replace('@@regex ','')}) :
|
||||
(lore.secondkey ?? '').replace(rmRegex, '').toLocaleLowerCase().split(',').filter((a) => {
|
||||
return a.length > 1
|
||||
})) : [],
|
||||
content: lore.content,
|
||||
order: lore.insertorder,
|
||||
activatied: false
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
formatedLore.sort((a, b) => {
|
||||
return b.order - a.order
|
||||
})
|
||||
|
||||
const formatedChatMain = currentChat.slice(currentChat.length - loreDepth,currentChat.length).map((msg) => {
|
||||
return msg.data
|
||||
}).join('||').replace(rmRegex,'').toLocaleLowerCase()
|
||||
|
||||
let loreListUpdated = true
|
||||
|
||||
while(loreListUpdated){
|
||||
loreListUpdated = false
|
||||
const formatedChat = formatedChatMain + activatiedPrompt.join('').replace(rmRegex,'').toLocaleLowerCase()
|
||||
const formatedChatList = fullWordMatching ? formatedChat.split(' ') : formatedChat
|
||||
for(let i=0;i<formatedLore.length;i++){
|
||||
const lore = formatedLore[i]
|
||||
if(lore.activatied){
|
||||
continue
|
||||
}
|
||||
const totalTokens = await tokenize(activatiedPrompt.concat([lore.content]).join('\n\n'))
|
||||
if(totalTokens > loreToken){
|
||||
break
|
||||
}
|
||||
|
||||
if(lore.keys === 'always'){
|
||||
activatiedPrompt.push(lore.content)
|
||||
lore.activatied = true
|
||||
loreListUpdated = true
|
||||
continue
|
||||
}
|
||||
|
||||
let firstKeyActivation = false
|
||||
if(Array.isArray(lore.keys)){
|
||||
for(const key of lore.keys){
|
||||
if(key){
|
||||
if(formatedChatList.includes(key)){
|
||||
firstKeyActivation = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(formatedChat.match(new RegExp(lore.keys.regex,'g'))){
|
||||
firstKeyActivation = true
|
||||
}
|
||||
}
|
||||
|
||||
if(firstKeyActivation){
|
||||
if(Array.isArray(lore.secondKey)){
|
||||
if(lore.secondKey.length === 0){
|
||||
activatiedPrompt.push(lore.content)
|
||||
lore.activatied = true
|
||||
loreListUpdated = true
|
||||
continue
|
||||
}
|
||||
for(const key of lore.secondKey){
|
||||
if(formatedChatList.includes(key)){
|
||||
activatiedPrompt.push(lore.content)
|
||||
lore.activatied = true
|
||||
loreListUpdated = true
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(formatedChat.match(new RegExp(lore.secondKey.regex,'g'))){
|
||||
firstKeyActivation = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!(char.loreSettings?.recursiveScanning)){
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let sactivated:string[] = []
|
||||
let decoratedArray:{
|
||||
depth:number,
|
||||
pos:string,
|
||||
prompt:string
|
||||
}[] = []
|
||||
activatiedPrompt = activatiedPrompt.filter((v) => {
|
||||
if(v.startsWith("@@@end")){
|
||||
sactivated.push(v.replace('@@@end','').trim())
|
||||
return false
|
||||
}
|
||||
if(v.startsWith('@@end')){
|
||||
sactivated.push(v.replace('@@end','').trim())
|
||||
return false
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
return {
|
||||
act: activatiedPrompt.reverse().join('\n\n'),
|
||||
special_act: sactivated.reverse().join('\n\n'),
|
||||
decorated: decoratedArray
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export async function loadLoreBookV3Prompt(){
|
||||
const selectedID = get(selectedCharID)
|
||||
const db = get(DataBase)
|
||||
const char = db.characters[selectedID]
|
||||
const char = DBState.db.characters[selectedID]
|
||||
const page = char.chatPage
|
||||
const characterLore = char.globalLore ?? []
|
||||
const chatLore = char.chats[page].localLore ?? []
|
||||
const moduleLorebook = getModuleLorebooks()
|
||||
const fullLore = structuredClone(characterLore.concat(chatLore).concat(moduleLorebook))
|
||||
const fullLore = safeStructuredClone(characterLore.concat(chatLore).concat(moduleLorebook))
|
||||
const currentChat = char.chats[page].message
|
||||
const loreDepth = char.loreSettings?.scanDepth ?? db.loreBookDepth
|
||||
const loreToken = char.loreSettings?.tokenBudget ?? db.loreBookToken
|
||||
const fullWordMatching = char.loreSettings?.fullWordMatching ?? false
|
||||
const loreDepth = char.loreSettings?.scanDepth ?? DBState.db.loreBookDepth
|
||||
const loreToken = char.loreSettings?.tokenBudget ?? DBState.db.loreBookToken
|
||||
const fullWordMatchingSetting = char.loreSettings?.fullWordMatching ?? false
|
||||
const chatLength = currentChat.length + 1 //includes first message
|
||||
const recursiveScanning = char.loreSettings?.recursiveScanning ?? false
|
||||
let recursiveAdditionalPrompt = ''
|
||||
const recursiveScanning = char.loreSettings?.recursiveScanning ?? true
|
||||
let recursivePrompt:{
|
||||
prompt: string,
|
||||
source: string
|
||||
}[] = []
|
||||
let matchLog:{
|
||||
prompt: string,
|
||||
source: string
|
||||
activated: string
|
||||
}[] = []
|
||||
|
||||
const searchMatch = (messages:Message[],arg:{
|
||||
keys:string[],
|
||||
searchDepth:number,
|
||||
regex:boolean
|
||||
fullWordMatching:boolean
|
||||
recursiveAdditionalPrompt:string
|
||||
all?:boolean
|
||||
}) => {
|
||||
const sliced = messages.slice(messages.length - arg.searchDepth,messages.length)
|
||||
arg.keys = arg.keys.map(key => key.trim()).filter(key => key.length > 0)
|
||||
let mText = sliced.map((msg) => {
|
||||
return msg.data
|
||||
}).join('||')
|
||||
if(arg.recursiveAdditionalPrompt){
|
||||
mText += arg.recursiveAdditionalPrompt
|
||||
}
|
||||
if(arg.regex){
|
||||
for(const regexString of arg.keys){
|
||||
if(!regexString.startsWith('/')){
|
||||
return false
|
||||
let mList:{
|
||||
source:string
|
||||
prompt:string
|
||||
}[] = sliced.map((msg, i) => {
|
||||
if(msg.role === 'user'){
|
||||
return {
|
||||
source: `message ${i} by user`,
|
||||
prompt: `\x01{{${DBState.db.username}}}:` + msg.data + '\x01'
|
||||
}
|
||||
const regexFlag = regexString.split('/').pop()
|
||||
if(regexFlag){
|
||||
arg.keys[0] = regexString.replace('/'+regexFlag,'')
|
||||
try {
|
||||
const regex = new RegExp(arg.keys[0],regexFlag)
|
||||
return regex.test(mText)
|
||||
} catch (error) {
|
||||
}
|
||||
else{
|
||||
return {
|
||||
source: `message ${i} by char`,
|
||||
prompt: `\x01{{${msg.name ?? (msg.saying ? findCharacterbyId(msg.saying)?.name : null) ?? char.name}}}:` + msg.data + '\x01'
|
||||
}
|
||||
}
|
||||
}).concat(recursivePrompt.map((msg) => {
|
||||
return {
|
||||
source: 'lorebook ' + msg.source,
|
||||
prompt: msg.prompt
|
||||
}
|
||||
}))
|
||||
|
||||
if(arg.regex){
|
||||
for(const mText of mList){
|
||||
for(const regexString of arg.keys){
|
||||
if(!regexString.startsWith('/')){
|
||||
return false
|
||||
}
|
||||
const regexFlag = regexString.split('/').pop()
|
||||
if(regexFlag){
|
||||
arg.keys[0] = regexString.replace('/'+regexFlag,'')
|
||||
try {
|
||||
const regex = new RegExp(arg.keys[0],regexFlag)
|
||||
const d = regex.test(mText.prompt)
|
||||
if(d){
|
||||
matchLog.push({
|
||||
prompt: mText.prompt,
|
||||
source: mText.source,
|
||||
activated: regexString
|
||||
})
|
||||
return true
|
||||
}
|
||||
} catch (error) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
mText = mText.toLocaleLowerCase()
|
||||
mText = mText.replace(/\{\{\/\/(.+?)\}\}/g,'').replace(/\{\{comment:(.+?)\}\}/g,'')
|
||||
mList = mList.map((m) => {
|
||||
return {
|
||||
source: m.source,
|
||||
prompt: m.prompt.toLocaleLowerCase().replace(/\{\{\/\/(.+?)\}\}/g,'').replace(/\{\{comment:(.+?)\}\}/g,'')
|
||||
}
|
||||
})
|
||||
|
||||
if(arg.fullWordMatching){
|
||||
const splited = mText.split(' ')
|
||||
for(const key of arg.keys){
|
||||
if(splited.includes(key.toLocaleLowerCase())){
|
||||
return true
|
||||
let allMode = arg.all ?? false
|
||||
let allModeMatched = true
|
||||
|
||||
for(const m of mList){
|
||||
let mText = m.prompt
|
||||
if(arg.fullWordMatching){
|
||||
const splited = mText.split(' ')
|
||||
for(const key of arg.keys){
|
||||
if(splited.includes(key.toLocaleLowerCase())){
|
||||
matchLog.push({
|
||||
prompt: m.prompt,
|
||||
source: m.source,
|
||||
activated: key
|
||||
})
|
||||
if(!allMode){
|
||||
return true
|
||||
}
|
||||
}
|
||||
else if(allMode){
|
||||
allModeMatched = false
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
mText = mText.replace(/ /g,'')
|
||||
for(const key of arg.keys){
|
||||
const realKey = key.toLocaleLowerCase().replace(/ /g,'')
|
||||
if(mText.includes(realKey)){
|
||||
matchLog.push({
|
||||
prompt: m.prompt,
|
||||
source: m.source,
|
||||
activated: key
|
||||
})
|
||||
if(!allMode){
|
||||
return true
|
||||
}
|
||||
}
|
||||
else if(allMode){
|
||||
allModeMatched = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
mText = mText.replace(/ /g,'')
|
||||
for(const key of arg.keys){
|
||||
const realKey = key.toLocaleLowerCase().replace(/ /g,'')
|
||||
if(mText.includes(realKey)){
|
||||
return true
|
||||
}
|
||||
}
|
||||
if(allMode && allModeMatched){
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -291,6 +190,7 @@ export async function loadLoreBookV3Prompt(){
|
||||
order:number
|
||||
tokens:number
|
||||
priority:number
|
||||
source:string
|
||||
}[] = []
|
||||
let activatedIndexes:number[] = []
|
||||
let disabledUIPrompts:string[] = []
|
||||
@@ -314,8 +214,10 @@ export async function loadLoreBookV3Prompt(){
|
||||
let role:'system'|'user'|'assistant' = 'system'
|
||||
let searchQueries:{
|
||||
keys:string[],
|
||||
negative:boolean
|
||||
negative:boolean,
|
||||
all?:boolean
|
||||
}[] = []
|
||||
let fullWordMatching = fullWordMatchingSetting
|
||||
const content = CCardLib.decorator.parse(fullLore[i].content, (name, arg) => {
|
||||
switch(name){
|
||||
case 'end':{
|
||||
@@ -412,6 +314,22 @@ export async function loadLoreBookV3Prompt(){
|
||||
})
|
||||
return
|
||||
}
|
||||
case 'exclude_keys_all':{
|
||||
searchQueries.push({
|
||||
keys: arg,
|
||||
negative: true,
|
||||
all: true
|
||||
})
|
||||
return
|
||||
}
|
||||
case 'match_full_word':{
|
||||
fullWordMatching = true
|
||||
return
|
||||
}
|
||||
case 'match_partial_word':{
|
||||
fullWordMatching = false
|
||||
return
|
||||
}
|
||||
case 'is_user_icon':{
|
||||
//TODO
|
||||
return false
|
||||
@@ -455,6 +373,13 @@ export async function loadLoreBookV3Prompt(){
|
||||
keys: fullLore[i].key.split(','),
|
||||
negative: false
|
||||
})
|
||||
|
||||
if(fullLore[i].secondkey && fullLore[i].selective){
|
||||
searchQueries.push({
|
||||
keys: fullLore[i].secondkey.split(','),
|
||||
negative: false
|
||||
})
|
||||
}
|
||||
|
||||
for(const query of searchQueries){
|
||||
const result = searchMatch(currentChat, {
|
||||
@@ -462,7 +387,7 @@ export async function loadLoreBookV3Prompt(){
|
||||
searchDepth: scanDepth,
|
||||
regex: fullLore[i].useRegex,
|
||||
fullWordMatching: fullWordMatching,
|
||||
recursiveAdditionalPrompt: recursiveAdditionalPrompt
|
||||
all: query.all
|
||||
})
|
||||
if(query.negative){
|
||||
if(result){
|
||||
@@ -494,12 +419,16 @@ export async function loadLoreBookV3Prompt(){
|
||||
role: role,
|
||||
order: order,
|
||||
tokens: await tokenize(content),
|
||||
priority: priority
|
||||
priority: priority,
|
||||
source: fullLore[i].comment || `lorebook ${i}`
|
||||
})
|
||||
activatedIndexes.push(i)
|
||||
if(recursiveScanning){
|
||||
matching = true
|
||||
recursiveAdditionalPrompt += content + '\n\n'
|
||||
recursivePrompt.push({
|
||||
prompt: content,
|
||||
source: fullLore[i].comment || `lorebook ${i}`
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -524,18 +453,18 @@ export async function loadLoreBookV3Prompt(){
|
||||
})
|
||||
|
||||
return {
|
||||
actives: activesResorted.reverse()
|
||||
actives: activesResorted.reverse(),
|
||||
matchLog: matchLog,
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export async function importLoreBook(mode:'global'|'local'|'sglobal'){
|
||||
const selectedID = get(selectedCharID)
|
||||
let db = get(DataBase)
|
||||
const page = mode === 'sglobal' ? -1 : db.characters[selectedID].chatPage
|
||||
const page = mode === 'sglobal' ? -1 : DBState.db.characters[selectedID].chatPage
|
||||
let lore =
|
||||
mode === 'global' ? db.characters[selectedID].globalLore :
|
||||
db.characters[selectedID].chats[page].localLore
|
||||
mode === 'global' ? DBState.db.characters[selectedID].globalLore :
|
||||
DBState.db.characters[selectedID].chats[page].localLore
|
||||
const lorebook = (await selectSingleFile(['json', 'lorebook'])).data
|
||||
if(!lorebook){
|
||||
return
|
||||
@@ -556,12 +485,11 @@ export async function importLoreBook(mode:'global'|'local'|'sglobal'){
|
||||
lore.push(...convertExternalLorebook(entries))
|
||||
}
|
||||
if(mode === 'global'){
|
||||
db.characters[selectedID].globalLore = lore
|
||||
DBState.db.characters[selectedID].globalLore = lore
|
||||
}
|
||||
else{
|
||||
db.characters[selectedID].chats[page].localLore = lore
|
||||
DBState.db.characters[selectedID].chats[page].localLore = lore
|
||||
}
|
||||
setDatabase(db)
|
||||
} catch (error) {
|
||||
alertError(`${error}`)
|
||||
}
|
||||
@@ -613,11 +541,10 @@ export function convertExternalLorebook(entries:{[key:string]:CCLorebook}){
|
||||
export async function exportLoreBook(mode:'global'|'local'|'sglobal'){
|
||||
try {
|
||||
const selectedID = get(selectedCharID)
|
||||
const db = get(DataBase)
|
||||
const page = mode === 'sglobal' ? -1 : db.characters[selectedID].chatPage
|
||||
const page = mode === 'sglobal' ? -1 : DBState.db.characters[selectedID].chatPage
|
||||
const lore =
|
||||
mode === 'global' ? db.characters[selectedID].globalLore :
|
||||
db.characters[selectedID].chats[page].localLore
|
||||
mode === 'global' ? DBState.db.characters[selectedID].globalLore :
|
||||
DBState.db.characters[selectedID].chats[page].localLore
|
||||
const stringl = Buffer.from(JSON.stringify({
|
||||
type: 'risu',
|
||||
ver: 1,
|
||||
@@ -1,13 +1,13 @@
|
||||
import { getChatVar, hasher, risuChatParser, setChatVar, type simpleCharacterArgument } from "../parser";
|
||||
import { getChatVar, hasher, setChatVar, type simpleCharacterArgument } from "../parser.svelte";
|
||||
import { LuaEngine, LuaFactory } from "wasmoon";
|
||||
import { DataBase, setDatabase, type Chat, type character, type groupChat } from "../storage/database";
|
||||
import { getCurrentCharacter, getCurrentChat, getDatabase, setCurrentChat, setDatabase, type Chat, type character, type groupChat } from "../storage/database.svelte";
|
||||
import { get } from "svelte/store";
|
||||
import { CurrentCharacter, CurrentChat, ReloadGUIPointer, selectedCharID } from "../stores";
|
||||
import { ReloadGUIPointer, selectedCharID } from "../stores.svelte";
|
||||
import { alertError, alertInput, alertNormal } from "../alert";
|
||||
import { HypaProcesser } from "./memory/hypamemory";
|
||||
import { generateAIImage } from "./stableDiff";
|
||||
import { writeInlayImage } from "./files/image";
|
||||
import type { OpenAIChat } from ".";
|
||||
import type { OpenAIChat } from "./index.svelte";
|
||||
import { requestChatData } from "./request";
|
||||
import { v4 } from "uuid";
|
||||
import { getModuleTriggers } from "./modules";
|
||||
@@ -35,12 +35,12 @@ export async function runLua(code:string, arg:{
|
||||
mode?: string,
|
||||
data?: any
|
||||
}){
|
||||
const char = arg.char ?? get(CurrentCharacter)
|
||||
const char = arg.char ?? getCurrentCharacter()
|
||||
const setVar = arg.setVar ?? setChatVar
|
||||
const getVar = arg.getVar ?? getChatVar
|
||||
const mode = arg.mode ?? 'manual'
|
||||
const data = arg.data ?? {}
|
||||
let chat = arg.chat ?? get(CurrentChat)
|
||||
let chat = arg.chat ?? getCurrentChat()
|
||||
let stopSending = false
|
||||
let lowLevelAccess = arg.lowLevelAccess ?? false
|
||||
|
||||
@@ -104,66 +104,75 @@ export async function runLua(code:string, arg:{
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
chat = getCurrentChat()
|
||||
const message = chat.message?.at(index)
|
||||
if(message){
|
||||
message.data = value
|
||||
}
|
||||
CurrentChat.set(chat)
|
||||
setCurrentChat(chat)
|
||||
})
|
||||
luaEngine.global.set('setChatRole', (id:string, index:number, value:string) => {
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
chat = getCurrentChat()
|
||||
const message = chat.message?.at(index)
|
||||
if(message){
|
||||
message.role = value === 'user' ? 'user' : 'char'
|
||||
}
|
||||
CurrentChat.set(chat)
|
||||
setCurrentChat(chat)
|
||||
})
|
||||
luaEngine.global.set('cutChat', (id:string, start:number, end:number) => {
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
chat = getCurrentChat()
|
||||
chat.message = chat.message.slice(start,end)
|
||||
CurrentChat.set(chat)
|
||||
setCurrentChat(chat)
|
||||
})
|
||||
luaEngine.global.set('removeChat', (id:string, index:number) => {
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
chat = getCurrentChat()
|
||||
chat.message.splice(index, 1)
|
||||
CurrentChat.set(chat)
|
||||
setCurrentChat(chat)
|
||||
})
|
||||
luaEngine.global.set('addChat', (id:string, role:string, value:string) => {
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
chat = getCurrentChat()
|
||||
let roleData:'user'|'char' = role === 'user' ? 'user' : 'char'
|
||||
chat.message.push({role: roleData, data: value})
|
||||
CurrentChat.set(chat)
|
||||
setCurrentChat(chat)
|
||||
})
|
||||
luaEngine.global.set('insertChat', (id:string, index:number, role:string, value:string) => {
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
chat = getCurrentChat()
|
||||
let roleData:'user'|'char' = role === 'user' ? 'user' : 'char'
|
||||
chat.message.splice(index, 0, {role: roleData, data: value})
|
||||
CurrentChat.set(chat)
|
||||
setCurrentChat(chat)
|
||||
})
|
||||
luaEngine.global.set('removeChat', (id:string, index:number) => {
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
chat = getCurrentChat()
|
||||
chat.message.splice(index, 1)
|
||||
CurrentChat.set(chat)
|
||||
setCurrentChat(chat)
|
||||
})
|
||||
luaEngine.global.set('getChatLength', (id:string) => {
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
chat = getCurrentChat()
|
||||
return chat.message.length
|
||||
})
|
||||
luaEngine.global.set('getFullChatMain', (id:string) => {
|
||||
chat = getCurrentChat()
|
||||
const data = JSON.stringify(chat.message.map((v) => {
|
||||
return {
|
||||
role: v.role,
|
||||
@@ -178,13 +187,14 @@ export async function runLua(code:string, arg:{
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
chat = getCurrentChat()
|
||||
chat.message = realValue.map((v) => {
|
||||
return {
|
||||
role: v.role,
|
||||
data: v.data
|
||||
}
|
||||
})
|
||||
CurrentChat.set(chat)
|
||||
setCurrentChat(chat)
|
||||
})
|
||||
|
||||
luaEngine.global.set('logMain', (value:string) => {
|
||||
@@ -322,7 +332,7 @@ export async function runLua(code:string, arg:{
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
const char = db.characters[selectedChar]
|
||||
return char.name
|
||||
@@ -332,7 +342,7 @@ export async function runLua(code:string, arg:{
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
if(typeof name !== 'string'){
|
||||
throw('Invalid data type')
|
||||
@@ -345,7 +355,7 @@ export async function runLua(code:string, arg:{
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
const char =db.characters[selectedChar]
|
||||
if(typeof data !== 'string'){
|
||||
@@ -363,7 +373,7 @@ export async function runLua(code:string, arg:{
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
const char = db.characters[selectedChar]
|
||||
if(typeof data !== 'string'){
|
||||
@@ -379,7 +389,7 @@ export async function runLua(code:string, arg:{
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
const char = db.characters[selectedChar]
|
||||
return char.firstMessage
|
||||
@@ -389,7 +399,7 @@ export async function runLua(code:string, arg:{
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
const char = db.characters[selectedChar]
|
||||
return char.backgroundHTML
|
||||
@@ -399,7 +409,7 @@ export async function runLua(code:string, arg:{
|
||||
if(!LuaSafeIds.has(id)){
|
||||
return
|
||||
}
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const selectedChar = get(selectedCharID)
|
||||
if(typeof data !== 'string'){
|
||||
return false
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { alertError } from "src/ts/alert";
|
||||
import type { OpenAIChat } from "..";
|
||||
import type { OpenAIChat } from "../index.svelte";
|
||||
import { HypaProcesser } from "./hypamemory";
|
||||
import { language } from "src/lang";
|
||||
import type { ChatTokenizer } from "src/ts/tokenizer";
|
||||
import { get } from "svelte/store";
|
||||
import { DataBase } from "src/ts/storage/database";
|
||||
import { getDatabase } from "src/ts/storage/database.svelte";
|
||||
|
||||
const maxRecentChatQuery = 4;
|
||||
export async function hanuraiMemory(chats:OpenAIChat[],arg:{
|
||||
@@ -12,7 +11,7 @@ export async function hanuraiMemory(chats:OpenAIChat[],arg:{
|
||||
maxContextTokens:number,
|
||||
tokenizer:ChatTokenizer
|
||||
}){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const tokenizer = arg.tokenizer
|
||||
const processer = new HypaProcesser('MiniLM')
|
||||
let addTexts:string[] = []
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import localforage from "localforage";
|
||||
import { globalFetch } from "src/ts/storage/globalApi";
|
||||
import { globalFetch } from "src/ts/globalApi.svelte";
|
||||
import { runEmbedding } from "../transformers";
|
||||
import { alertError } from "src/ts/alert";
|
||||
import { appendLastPath } from "src/ts/util";
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { DataBase, type Chat, type character, type groupChat } from "src/ts/storage/database";
|
||||
import type { OpenAIChat } from "..";
|
||||
import { getDatabase, type Chat, type character, type groupChat } from "src/ts/storage/database.svelte";
|
||||
import type { OpenAIChat } from "../index.svelte";
|
||||
import type { ChatTokenizer } from "src/ts/tokenizer";
|
||||
import { get } from "svelte/store";
|
||||
import { requestChatData } from "../request";
|
||||
import { HypaProcesser } from "./hypamemory";
|
||||
import { globalFetch } from "src/ts/storage/globalApi";
|
||||
import { globalFetch } from "src/ts/globalApi.svelte";
|
||||
import { runSummarizer } from "../transformers";
|
||||
import { last, remove } from "lodash";
|
||||
import { parseChatML } from "src/ts/parser.svelte";
|
||||
|
||||
export interface HypaV2Data {
|
||||
chunks: {
|
||||
@@ -20,7 +19,7 @@ export interface HypaV2Data {
|
||||
}
|
||||
|
||||
async function summary(stringlizedChat: string): Promise<{ success: boolean; data: string }> {
|
||||
const db = get(DataBase);
|
||||
const db = getDatabase();
|
||||
console.log("Summarizing");
|
||||
|
||||
if (db.supaModelType === 'distilbart') {
|
||||
@@ -85,7 +84,10 @@ async function summary(stringlizedChat: string): Promise<{ success: boolean; dat
|
||||
};
|
||||
}
|
||||
} else {
|
||||
const promptbody: OpenAIChat[] = [
|
||||
|
||||
let parsedPrompt = parseChatML(supaPrompt.replaceAll('{{slot}}', stringlizedChat))
|
||||
|
||||
const promptbody: OpenAIChat[] = parsedPrompt ?? [
|
||||
{
|
||||
role: "user",
|
||||
content: stringlizedChat
|
||||
@@ -101,7 +103,7 @@ async function summary(stringlizedChat: string): Promise<{ success: boolean; dat
|
||||
bias: {},
|
||||
useStreaming: false,
|
||||
noMultiGen: true
|
||||
}, 'submodel');
|
||||
}, 'memory');
|
||||
if (da.type === 'fail' || da.type === 'streaming' || da.type === 'multiline') {
|
||||
return {
|
||||
success: false,
|
||||
@@ -123,7 +125,7 @@ export async function hypaMemoryV2(
|
||||
arg: { asHyper?: boolean, summaryModel?: string, summaryPrompt?: string, hypaModel?: string } = {}
|
||||
): Promise<{ currentTokens: number; chats: OpenAIChat[]; error?: string; memory?: HypaV2Data; }> {
|
||||
|
||||
const db = get(DataBase);
|
||||
const db = getDatabase();
|
||||
const data: HypaV2Data = room.hypaV2Data ?? { chunks: [], mainChunks: [] };
|
||||
|
||||
let allocatedTokens = db.hypaAllocatedTokens;
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { get } from "svelte/store";
|
||||
import type { OpenAIChat } from "..";
|
||||
import { DataBase, type Chat, type character, type groupChat } from "../../storage/database";
|
||||
import type { OpenAIChat } from "../index.svelte";
|
||||
import { getDatabase, type Chat, type character, type groupChat } from "../../storage/database.svelte";
|
||||
import { tokenize, type ChatTokenizer } from "../../tokenizer";
|
||||
import { requestChatData } from "../request";
|
||||
import { HypaProcesser } from "./hypamemory";
|
||||
import { stringlizeChat } from "../stringlize";
|
||||
import { globalFetch } from "src/ts/storage/globalApi";
|
||||
import { globalFetch } from "src/ts/globalApi.svelte";
|
||||
import { runSummarizer } from "../transformers";
|
||||
import { getUserName } from "src/ts/util";
|
||||
import { parseChatML } from "src/ts/parser.svelte";
|
||||
|
||||
export async function supaMemory(
|
||||
chats:OpenAIChat[],
|
||||
@@ -18,7 +18,7 @@ export async function supaMemory(
|
||||
tokenizer:ChatTokenizer,
|
||||
arg:{asHyper?:boolean} = {}
|
||||
): Promise<{ currentTokens: number; chats: OpenAIChat[]; error?:string; memory?:string;lastId?:string}>{
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
|
||||
currentTokens += 10
|
||||
|
||||
@@ -74,7 +74,7 @@ export async function supaMemory(
|
||||
for(let j=0;j<HypaData.length;j++){
|
||||
let i =0;
|
||||
let countTokens = currentTokens
|
||||
let countChats = structuredClone(chats)
|
||||
let countChats = safeStructuredClone(chats)
|
||||
while(true){
|
||||
if(countChats.length === 0){
|
||||
break
|
||||
@@ -253,7 +253,8 @@ export async function supaMemory(
|
||||
}
|
||||
}
|
||||
else {
|
||||
const promptbody:OpenAIChat[] = [
|
||||
let parsedPrompt = parseChatML(supaPrompt.replaceAll('{{slot}}', stringlizedChat))
|
||||
const promptbody:OpenAIChat[] = parsedPrompt ?? [
|
||||
{
|
||||
role: "user",
|
||||
content: stringlizedChat
|
||||
@@ -268,7 +269,7 @@ export async function supaMemory(
|
||||
bias: {},
|
||||
useStreaming: false,
|
||||
noMultiGen: true
|
||||
}, 'submodel')
|
||||
}, 'memory')
|
||||
if(da.type === 'fail' || da.type === 'streaming' || da.type === 'multiline'){
|
||||
return {
|
||||
currentTokens: currentTokens,
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { invoke } from "@tauri-apps/api/tauri";
|
||||
import { globalFetch } from "src/ts/storage/globalApi";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { globalFetch } from "src/ts/globalApi.svelte";
|
||||
import { sleep } from "src/ts/util";
|
||||
import * as path from "@tauri-apps/api/path";
|
||||
import { exists, readTextFile } from "@tauri-apps/api/fs";
|
||||
import { exists, readTextFile } from "@tauri-apps/plugin-fs";
|
||||
import { alertClear, alertError, alertMd, alertWait } from "src/ts/alert";
|
||||
import { get } from "svelte/store";
|
||||
import { DataBase } from "src/ts/storage/database";
|
||||
import { resolveResource } from '@tauri-apps/api/path'
|
||||
import { getDatabase } from "src/ts/storage/database.svelte";
|
||||
let serverRunning = false;
|
||||
|
||||
export function checkLocalModel():Promise<string>{
|
||||
@@ -131,7 +129,7 @@ export async function loadExllamaFull(){
|
||||
|
||||
|
||||
async function runLocalModelOld(prompt:string){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
|
||||
if(!serverRunning){
|
||||
await loadExllamaFull()
|
||||
@@ -274,7 +272,7 @@ export async function runGGUFModel(arg:{
|
||||
|
||||
export async function tokenizeGGUFModel(prompt:string):Promise<number[]> {
|
||||
const key = await getLocalKey()
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const modelPath = db.aiModel.replace('local_', '')
|
||||
const b = await fetch("http://localhost:10026/llamacpp/tokenize", {
|
||||
method: "POST",
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { DataBase } from "src/ts/storage/database";
|
||||
import { get } from "svelte/store";
|
||||
import { getDatabase } from "src/ts/storage/database.svelte";
|
||||
|
||||
export function getGenerationModelString(){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
switch (db.aiModel){
|
||||
case 'reverse_proxy':
|
||||
return 'reverse_proxy-' + (db.reverseProxyOobaMode ? 'ooba' : db.proxyRequestModel)
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { DataBase, setDatabase } from "src/ts/storage/database"
|
||||
import type { OpenAIChat } from ".."
|
||||
import { get } from "svelte/store"
|
||||
import { globalFetch } from "src/ts/storage/globalApi"
|
||||
import { getDatabase, setDatabase } from "src/ts/storage/database.svelte"
|
||||
import type { OpenAIChat } from "../index.svelte"
|
||||
import { globalFetch } from "src/ts/globalApi.svelte"
|
||||
import { alertError, alertInput, alertNormal, alertWait } from "src/ts/alert"
|
||||
import { getUserName, sleep } from "src/ts/util"
|
||||
|
||||
export function stringlizeNAIChat(formated:OpenAIChat[], char:string, continued: boolean){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
let seperator = db.NAIsettings.seperator.replaceAll("\\n","\n") || '\n'
|
||||
let starter = db.NAIsettings.starter.replaceAll("\\n","\n") || '⁂'
|
||||
let resultString:string[] = []
|
||||
@@ -109,7 +108,7 @@ export const novelLogin = async () => {
|
||||
|
||||
const data = r.data?.accessToken
|
||||
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
db.novelai.token = data
|
||||
|
||||
alertNormal('Logged in to NovelAI')
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
import { language } from "src/lang"
|
||||
import { alertConfirm, alertError, alertModuleSelect, alertNormal, alertStore } from "../alert"
|
||||
import { DataBase, setDatabase, type customscript, type loreBook, type triggerscript } from "../storage/database"
|
||||
import { AppendableBuffer, downloadFile, isNodeServer, isTauri, readImage, saveAsset } from "../storage/globalApi"
|
||||
import { get } from "svelte/store"
|
||||
import { CurrentCharacter, CurrentChat } from "../stores"
|
||||
import { getCurrentCharacter, getCurrentChat, getDatabase, setCurrentCharacter, setDatabase, type customscript, type loreBook, type triggerscript } from "../storage/database.svelte"
|
||||
import { AppendableBuffer, downloadFile, isNodeServer, isTauri, readImage, saveAsset } from "../globalApi.svelte"
|
||||
import { selectSingleFile, sleep } from "../util"
|
||||
import { v4 } from "uuid"
|
||||
import { convertExternalLorebook } from "./lorebook"
|
||||
import { encode } from "msgpackr"
|
||||
import { convertExternalLorebook } from "./lorebook.svelte"
|
||||
import { decodeRPack, encodeRPack } from "../rpack/rpack_bg"
|
||||
import { convertImage } from "../parser"
|
||||
import { convertImage } from "../parser.svelte"
|
||||
import { Capacitor } from "@capacitor/core"
|
||||
import { HideIconStore, moduleBackgroundEmbedding, ReloadGUIPointer } from "../stores.svelte"
|
||||
import {get} from "svelte/store"
|
||||
|
||||
export interface RisuModule{
|
||||
name: string
|
||||
@@ -47,7 +46,7 @@ export async function exportModule(module:RisuModule, arg:{
|
||||
}
|
||||
|
||||
const assets = module.assets ?? []
|
||||
module = structuredClone(module)
|
||||
module = safeStructuredClone(module)
|
||||
module.assets ??= []
|
||||
module.assets = module.assets.map((asset) => {
|
||||
return [asset[0], '', asset[2]] as [string,string,string]
|
||||
@@ -173,7 +172,7 @@ export async function importModule(){
|
||||
return
|
||||
}
|
||||
let fileData = f.data
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
if(f.name.endsWith('.risum')){
|
||||
try {
|
||||
const buf = Buffer.from(fileData)
|
||||
@@ -250,7 +249,7 @@ export async function importModule(){
|
||||
}
|
||||
|
||||
function getModuleById(id:string){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
for(let i=0;i<db.modules.length;i++){
|
||||
if(db.modules[i].id === id){
|
||||
return db.modules[i]
|
||||
@@ -261,7 +260,7 @@ function getModuleById(id:string){
|
||||
|
||||
function getModuleByIds(ids:string[]){
|
||||
let modules:RisuModule[] = []
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
for(let i=0;i<ids.length;i++){
|
||||
const module = db.modules.find((m) => m.id === ids[i] || (m.namespace === ids[i] && m.namespace))
|
||||
if(module){
|
||||
@@ -274,8 +273,8 @@ function getModuleByIds(ids:string[]){
|
||||
let lastModules = ''
|
||||
let lastModuleData:RisuModule[] = []
|
||||
export function getModules(){
|
||||
const currentChat = get(CurrentChat)
|
||||
const db = get(DataBase)
|
||||
const currentChat = getCurrentChat()
|
||||
const db = getDatabase()
|
||||
let ids = db.enabledModules ?? []
|
||||
if (currentChat){
|
||||
ids = ids.concat(currentChat.modules ?? [])
|
||||
@@ -363,12 +362,12 @@ export async function applyModule() {
|
||||
return
|
||||
}
|
||||
|
||||
const module = structuredClone(getModuleById(sel))
|
||||
const module = safeStructuredClone(getModuleById(sel))
|
||||
if (!module) {
|
||||
return
|
||||
}
|
||||
|
||||
const currentChar = get(CurrentCharacter)
|
||||
const currentChar = getCurrentCharacter()
|
||||
if (!currentChar) {
|
||||
return
|
||||
}
|
||||
@@ -392,7 +391,42 @@ export async function applyModule() {
|
||||
}
|
||||
}
|
||||
|
||||
CurrentCharacter.set(currentChar)
|
||||
setCurrentCharacter(currentChar)
|
||||
|
||||
alertNormal(language.successApplyModule)
|
||||
}
|
||||
|
||||
let lastModuleIds:string = ''
|
||||
|
||||
export function moduleUpdate(){
|
||||
|
||||
|
||||
const m = getModules()
|
||||
|
||||
const ids = m.map((m) => m.id).join('-')
|
||||
|
||||
let moduleHideIcon = false
|
||||
let backgroundEmbedding = ''
|
||||
m.forEach((module) => {
|
||||
if(!module){
|
||||
return
|
||||
}
|
||||
|
||||
if(module.hideIcon){
|
||||
moduleHideIcon = true
|
||||
}
|
||||
if(module.backgroundEmbedding){
|
||||
backgroundEmbedding += '\n' + module.backgroundEmbedding + '\n'
|
||||
}
|
||||
})
|
||||
|
||||
if(backgroundEmbedding){
|
||||
moduleBackgroundEmbedding.set(backgroundEmbedding)
|
||||
}
|
||||
HideIconStore.set(getCurrentCharacter()?.hideChatIcon || moduleHideIcon)
|
||||
|
||||
if(lastModuleIds !== ids){
|
||||
ReloadGUIPointer.set(get(ReloadGUIPointer) + 1)
|
||||
lastModuleIds = ids
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AppendableBuffer, isNodeServer, isTauri, saveAsset, type LocalWriter, type VirtualWriter } from "../storage/globalApi";
|
||||
import { AppendableBuffer, isNodeServer, isTauri, saveAsset, type LocalWriter, type VirtualWriter } from "../globalApi.svelte";
|
||||
import * as fflate from "fflate";
|
||||
import { sleep } from "../util";
|
||||
import { alertStore } from "../alert";
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { get } from "svelte/store";
|
||||
import { tokenizeAccurate } from "../tokenizer";
|
||||
import { DataBase, presetTemplate, setDatabase, type Database } from "../storage/database";
|
||||
import { getDatabase, presetTemplate, setDatabase, type Database } from "../storage/database.svelte";
|
||||
import { alertError, alertNormal } from "../alert";
|
||||
import type { OobaChatCompletionRequestParams } from "../model/ooba";
|
||||
|
||||
@@ -256,7 +256,7 @@ export const OobaParams = [
|
||||
]
|
||||
|
||||
export function promptConvertion(files:{ name: string, content: string, type:string }[]){
|
||||
let preset = structuredClone(presetTemplate)
|
||||
let preset = safeStructuredClone(presetTemplate)
|
||||
let instData = {
|
||||
"system_prompt": "",
|
||||
"input_sequence": "",
|
||||
@@ -383,7 +383,7 @@ export function promptConvertion(files:{ name: string, content: string, type:str
|
||||
if(type === 'STCHAT'){
|
||||
preset.aiModel = 'openrouter'
|
||||
preset.subModel = 'openrouter'
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
db.botPresets.push(preset)
|
||||
setDatabase(db)
|
||||
|
||||
@@ -461,7 +461,7 @@ export function promptConvertion(files:{ name: string, content: string, type:str
|
||||
preset.name ||= 'Converted from JSON'
|
||||
|
||||
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
db.botPresets.push(preset)
|
||||
setDatabase(db)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,11 +1,11 @@
|
||||
import { get } from "svelte/store";
|
||||
import { CharEmotion, selectedCharID } from "../stores";
|
||||
import { DataBase, setDatabase, type character, type customscript, type groupChat, type Database } from "../storage/database";
|
||||
import { downloadFile } from "../storage/globalApi";
|
||||
import { CharEmotion, selectedCharID } from "../stores.svelte";
|
||||
import { type character, type customscript, type groupChat, type Database, getDatabase } from "../storage/database.svelte";
|
||||
import { downloadFile } from "../globalApi.svelte";
|
||||
import { alertError, alertNormal } from "../alert";
|
||||
import { language } from "src/lang";
|
||||
import { selectSingleFile } from "../util";
|
||||
import { assetRegex, type CbsConditions, risuChatParser as risuChatParserOrg, type simpleCharacterArgument } from "../parser";
|
||||
import { assetRegex, type CbsConditions, risuChatParser as risuChatParserOrg, type simpleCharacterArgument } from "../parser.svelte";
|
||||
import { runCharacterJS } from "../plugins/embedscript";
|
||||
import { getModuleAssets, getModuleRegexScripts } from "./modules";
|
||||
import { HypaProcesser } from "./memory/hypamemory";
|
||||
@@ -27,7 +27,7 @@ export async function processScript(char:character|groupChat, data:string, mode:
|
||||
}
|
||||
|
||||
export function exportRegex(s?:customscript[]){
|
||||
let db = get(DataBase)
|
||||
let db = getDatabase()
|
||||
const script = s ?? db.globalscript
|
||||
const data = Buffer.from(JSON.stringify({
|
||||
type: 'regex',
|
||||
@@ -43,7 +43,7 @@ export async function importRegex(o?:customscript[]):Promise<customscript[]>{
|
||||
if(!filedata){
|
||||
return o
|
||||
}
|
||||
let db = get(DataBase)
|
||||
let db = getDatabase()
|
||||
try {
|
||||
const imported= JSON.parse(Buffer.from(filedata).toString('utf-8'))
|
||||
if(imported.type === 'regex' && imported.data){
|
||||
@@ -65,9 +65,42 @@ export async function importRegex(o?:customscript[]):Promise<customscript[]>{
|
||||
}
|
||||
|
||||
let bestMatchCache = new Map<string, string>()
|
||||
let processScriptCache = new Map<string, string>()
|
||||
|
||||
function cacheScript(scripts:customscript[], data:string, result:string, mode:ScriptMode){
|
||||
let hash = data + '|||' + mode + '|||'
|
||||
for(const script of scripts){
|
||||
hash += `${script.in}|||${script.out}|||${script.flag}|||${script.ableFlag}|||${script.type}`
|
||||
}
|
||||
|
||||
processScriptCache.set(hash, result)
|
||||
|
||||
if(processScriptCache.size > 500){
|
||||
processScriptCache.delete(processScriptCache.keys().next().value)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function getScriptCache(scripts:customscript[], data:string, mode:ScriptMode){
|
||||
let hash = data + '|||' + mode + '|||'
|
||||
for(const script of scripts){
|
||||
hash += `${script.in}|||${script.out}|||${script.flag}|||${script.ableFlag}|||${script.type}`
|
||||
}
|
||||
|
||||
return processScriptCache.get(hash)
|
||||
}
|
||||
|
||||
export function resetScriptCache(){
|
||||
processScriptCache = new Map()
|
||||
}
|
||||
|
||||
export async function processScriptFull(char:character|groupChat|simpleCharacterArgument, data:string, mode:ScriptMode, chatID = -1, cbsConditions:CbsConditions = {}){
|
||||
let db = get(DataBase)
|
||||
let db = getDatabase()
|
||||
const originalData = data
|
||||
const cached = getScriptCache((db.globalscript ?? []).concat(char.customscript), originalData, mode)
|
||||
if(cached){
|
||||
return {data: cached, emoChanged: false}
|
||||
}
|
||||
let emoChanged = false
|
||||
const scripts = (db.globalscript ?? []).concat(char.customscript).concat(getModuleRegexScripts())
|
||||
data = await runCharacterJS({
|
||||
@@ -77,6 +110,7 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter
|
||||
})
|
||||
data = await runLuaEditTrigger(char, mode, data)
|
||||
if(scripts.length === 0){
|
||||
cacheScript(scripts, originalData, data, mode)
|
||||
return {data, emoChanged}
|
||||
}
|
||||
function executeScript(pscript:pScript){
|
||||
@@ -231,7 +265,7 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter
|
||||
for (const script of scripts){
|
||||
if(script.ableFlag && script.flag?.includes('<')){
|
||||
const rregex = /<(.+?)>/g
|
||||
const scriptData = structuredClone(script)
|
||||
const scriptData = safeStructuredClone(script)
|
||||
let order = 0
|
||||
const actions:string[] = []
|
||||
scriptData.flag = scriptData.flag?.replace(rregex, (v:string, p1:string) => {
|
||||
@@ -311,6 +345,8 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter
|
||||
}
|
||||
}
|
||||
|
||||
cacheScript(scripts, originalData, data, mode)
|
||||
|
||||
return {data, emoChanged}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { get } from "svelte/store"
|
||||
import { DataBase, type character } from "../storage/database"
|
||||
import { getDatabase, type character } from "../storage/database.svelte"
|
||||
import { requestChatData } from "./request"
|
||||
import { alertError } from "../alert"
|
||||
import { globalFetch, readImage } from "../storage/globalApi"
|
||||
import { CharEmotion } from "../stores"
|
||||
import type { OpenAIChat } from "."
|
||||
import { globalFetch, readImage } from "../globalApi.svelte"
|
||||
import { CharEmotion } from "../stores.svelte"
|
||||
import type { OpenAIChat } from "./index.svelte"
|
||||
import { processZip } from "./processzip"
|
||||
import { keiServerURL } from "../kei/kei"
|
||||
export async function stableDiff(currentChar:character,prompt:string){
|
||||
let db = get(DataBase)
|
||||
let db = getDatabase()
|
||||
|
||||
if(db.sdProvider === ''){
|
||||
alertError("Stable diffusion is not set in settings.")
|
||||
@@ -56,7 +56,7 @@ export async function stableDiff(currentChar:character,prompt:string){
|
||||
}
|
||||
|
||||
export async function generateAIImage(genPrompt:string, currentChar:character, neg:string, returnSdData:string):Promise<string|false>{
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
console.log(db.sdProvider)
|
||||
if(db.sdProvider === 'webui'){
|
||||
|
||||
@@ -490,7 +490,7 @@ export async function generateAIImage(genPrompt:string, currentChar:character, n
|
||||
}
|
||||
}
|
||||
if(db.sdProvider === 'kei'){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
let auth = db?.account?.token
|
||||
if(!auth){
|
||||
db.account = JSON.parse(localStorage.getItem("fallbackRisuToken"))
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { get } from "svelte/store";
|
||||
import type { OpenAIChat } from ".";
|
||||
import { DataBase } from "../storage/database";
|
||||
import type { OpenAIChat } from "./index.svelte";
|
||||
import { getDatabase } from "../storage/database.svelte";
|
||||
import { getUserName } from "../util";
|
||||
|
||||
export function multiChatReplacer(){
|
||||
@@ -41,7 +40,7 @@ function appendWhitespace(prefix:string, seperator:string=" ") {
|
||||
return prefix
|
||||
}
|
||||
export function stringlizeChatOba(formated:OpenAIChat[], characterName:string, suggesting:boolean, continued:boolean){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
let resultString:string[] = []
|
||||
let { systemPrefix, userPrefix, assistantPrefix, seperator } = db.ooba.formating;
|
||||
systemPrefix = systemPrefix ?? ""
|
||||
@@ -103,7 +102,7 @@ function toTitleCase(s:string){
|
||||
return s[0].toUpperCase() + s.slice(1).toLowerCase()
|
||||
}
|
||||
export function getStopStrings(suggesting:boolean=false){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
let { userPrefix, seperator } = db.ooba.formating;
|
||||
if(!seperator){
|
||||
seperator = "\n"
|
||||
@@ -160,7 +159,7 @@ export function unstringlizeChat(text:string, formated:OpenAIChat[], char:string
|
||||
export function getUnstringlizerChunks(formated:OpenAIChat[], char:string, mode:'ain'|'normal' = 'normal'){
|
||||
let chunks:string[] = ["system note:", "system:","system note:", "system:"]
|
||||
let charNames:string[] = []
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
if(char){
|
||||
charNames.push(char)
|
||||
if(mode === 'ain'){
|
||||
@@ -212,7 +211,7 @@ export function getUnstringlizerChunks(formated:OpenAIChat[], char:string, mode:
|
||||
|
||||
export function stringlizeAINChat(formated:OpenAIChat[], char:string, continued: boolean){
|
||||
let resultString:string[] = []
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
|
||||
for(const form of formated){
|
||||
console.log(form)
|
||||
@@ -292,7 +291,7 @@ function extractAINOutputStrings(inputString:string, characters:string[]) {
|
||||
|
||||
export function unstringlizeAIN(data:string,formated:OpenAIChat[], char:string = ''){
|
||||
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const chunksResult = getUnstringlizerChunks(formated, char ,'ain')
|
||||
const chunks = chunksResult.chunks
|
||||
let result:['char'|'user',string][] = []
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
import { Template } from '@huggingface/jinja';
|
||||
import type { OpenAIChat } from '..';
|
||||
import { get } from 'svelte/store';
|
||||
import { DataBase } from 'src/ts/storage/database';
|
||||
import { CurrentCharacter } from 'src/ts/stores';
|
||||
import type { OpenAIChat } from '../index.svelte';
|
||||
import { getCurrentCharacter, getDatabase } from 'src/ts/storage/database.svelte';
|
||||
import { getUserName } from 'src/ts/util';
|
||||
|
||||
export const chatTemplates = {
|
||||
@@ -30,13 +28,13 @@ export const applyChatTemplate = (messages:OpenAIChat[], arg:{
|
||||
type?: string
|
||||
custom?: string
|
||||
} = {}) => {
|
||||
const db = get(DataBase)
|
||||
const currentChar = get(CurrentCharacter)
|
||||
const db = getDatabase()
|
||||
const currentChar = getCurrentCharacter()
|
||||
const type = arg.type ?? db.instructChatTemplate
|
||||
if(!type){
|
||||
throw new Error('Template type is not set')
|
||||
}
|
||||
let clonedMessages = structuredClone(messages)
|
||||
let clonedMessages = safeStructuredClone(messages)
|
||||
const template = type === 'jinja' ? (new Template(arg.custom ?? db.JinjaTemplate)) :(new Template(chatTemplates[type]))
|
||||
let formatedMessages:{
|
||||
"role": 'user'|'assistant'|'system',
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
import { DataBase, setPreset, type botPreset, setDatabase } from "src/ts/storage/database";
|
||||
import { setPreset, type botPreset, setDatabase, getDatabase } from "src/ts/storage/database.svelte";
|
||||
import { defaultAutoSuggestPrefixOoba, defaultAutoSuggestPrompt, defaultAutoSuggestPromptOoba } from "src/ts/storage/defaultPrompts";
|
||||
import { get } from "svelte/store";
|
||||
import { prebuiltNAIpresets, prebuiltPresets } from "./templates";
|
||||
import { prebuiltPresets } from "./templates";
|
||||
import { alertConfirm, alertSelect } from "src/ts/alert";
|
||||
import { language } from "src/lang";
|
||||
|
||||
export async function setRecommended(model: string, ask:'ask'|'force') {
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
if(!(recommendedPresetExist(model))){
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { risuChatParser } from "src/ts/parser"
|
||||
import { DataBase } from "src/ts/storage/database"
|
||||
import { get } from "svelte/store"
|
||||
import { risuChatParser } from "src/ts/parser.svelte"
|
||||
import { getDatabase } from "src/ts/storage/database.svelte"
|
||||
|
||||
export function convertInterfaceToSchema(int:string){
|
||||
if(!int.startsWith('interface ') && !int.startsWith('export interface ')){
|
||||
@@ -122,7 +121,7 @@ export function convertInterfaceToSchema(int:string){
|
||||
}
|
||||
|
||||
export function getOpenAIJSONSchema(){
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const schema = {
|
||||
"name": "format",
|
||||
"strict": db.strictJsonSchema,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Database } from 'src/ts/storage/database'
|
||||
import type { Database } from 'src/ts/storage/database.svelte'
|
||||
|
||||
export function templateCheck(db:Database){
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { botPreset } from "../../storage/database";
|
||||
import type { botPreset } from "../../storage/database.svelte";
|
||||
import type { NAISettings } from "../models/nai";
|
||||
|
||||
|
||||
@@ -757,7 +757,7 @@ export const prebuiltPresets:{OAI:botPreset,ooba:botPreset,NAI:botPreset,oobaRp:
|
||||
},
|
||||
{
|
||||
"type": "plain",
|
||||
"text": "</ROLEPLAY_INFO>",
|
||||
"text": "</ROLEPLAY_INFO>\n\n<RESPONSE_INSTRUCTION>\n[Narrative Techniques]\n• Use immersive third-person limited perspective\n• Engage all senses: visual, auditory, olfactory, gustatory, tactile, kinesthetic\n• Create tangible atmosphere with specific environmental effects\n• Focus on actions, dialogue, and explicit physical descriptions\n• Employ character-specific speech patterns and onomatopoeia\n• Avoid irrelevant background, summaries, or abstract concepts\n\n[Character Expression]\n• Reveal emotions through observable physical cues\n• Craft unique voices with distinctive patterns and evolving speech\n• Implement dialogue subtext via tonal shifts and non-verbal cues\n• Allow contradictory expressions to add depth\n\n[Action and Intimacy]\n• Narrate with precise, visceral details of movements and sensations\n• Create tension through tangible environmental and internal obstacles\n• Handle intimate scenes with clear, physical language\n• Enhance complexity with multi-character interactions and layered conflicts\n\n[Variety and Anti-Repetition]\n• Analyze [Latest Response] to avoid reusing elements\n• Vary sentence structures, paragraph compositions, and word choices\n• Rotate descriptive focuses, scene structures, and narrative techniques\n• Create unique, engaging openings for each response\n• Ensure continuity by referencing recent events and character states\n\n[Style Independence]\n• Actively diverge from previous responses' writing style\n• Diversify vocabulary and phrasing\n• Alter narrative rhythm and pacing\n• Approach each response as a fresh scene\n\n[Key Principles]\n• Prioritize \"show, don't tell\" for all character aspects\n• Maintain world/character consistency\n• Balance content (SFW preference, mature when relevant)\n• Use explicit, unrestricted descriptions\n• Prohibit all forms of repetition and self-plagiarism\n• Vary emotional tone and intensity across scenes\n• Enhance themes through tangible symbols/actions\n• Apply procedural reasoning for variety and depth\n• End responses with observable non-{{user}} actions/dialogue\n</RESPONSE_INSTRUCTION>",
|
||||
"role": "system",
|
||||
"type2": "normal"
|
||||
},
|
||||
@@ -767,29 +767,17 @@ export const prebuiltPresets:{OAI:botPreset,ooba:botPreset,NAI:botPreset,oobaRp:
|
||||
"rangeEnd": -2,
|
||||
"chatAsOriginalOnSystem": true
|
||||
},
|
||||
{
|
||||
"type": "plain",
|
||||
"text": "[Latest Response]",
|
||||
"role": "bot",
|
||||
"type2": "normal"
|
||||
},
|
||||
{
|
||||
"type": "chat",
|
||||
"rangeStart": -2,
|
||||
"rangeEnd": "end"
|
||||
},
|
||||
{
|
||||
"type": "plain",
|
||||
"text": "<RESPONSE_INSTRUCTION>\n[Narrative Techniques]\n• Use immersive third-person limited perspective\n• Engage all senses: visual, auditory, olfactory, gustatory, tactile, kinesthetic\n• Create tangible atmosphere with specific environmental effects\n• Focus on actions, dialogue, and explicit physical descriptions\n• Employ character-specific speech patterns and onomatopoeia\n• Avoid irrelevant background, summaries, or abstract concepts\n\n[Character Expression]\n• Reveal emotions through observable physical cues\n• Craft unique voices with distinctive patterns and evolving speech\n• Implement dialogue subtext via tonal shifts and non-verbal cues\n• Allow contradictory expressions to add depth\n\n[Action and Intimacy]\n• Narrate with precise, visceral details of movements and sensations\n• Create tension through tangible environmental and internal obstacles\n• Handle intimate scenes with clear, physical language\n• Enhance complexity with multi-character interactions and layered conflicts\n\n[Variety and Anti-Repetition]\n• Analyze [Latest Response] to avoid reusing elements\n• Vary sentence structures, paragraph compositions, and word choices\n• Rotate descriptive focuses, scene structures, and narrative techniques\n• Create unique, engaging openings for each response\n• Ensure continuity by referencing recent events and character states\n\n[Style Independence]\n• Actively diverge from previous responses' writing style\n• Diversify vocabulary and phrasing\n• Alter narrative rhythm and pacing\n• Approach each response as a fresh scene\n\n[Key Principles]\n• Prioritize \"show, don't tell\" for all character aspects\n• Maintain world/character consistency\n• Balance content (SFW preference, mature when relevant)\n• Use explicit, unrestricted descriptions\n• Prohibit all forms of repetition and self-plagiarism\n• Vary emotional tone and intensity across scenes\n• Enhance themes through tangible symbols/actions\n• Apply procedural reasoning for variety and depth\n• End responses with observable non-{{user}} actions/dialogue\n</RESPONSE_INSTRUCTION>\n",
|
||||
"role": "user",
|
||||
"type2": "normal"
|
||||
},
|
||||
{
|
||||
"type": "postEverything",
|
||||
},
|
||||
{
|
||||
"type": "plain",
|
||||
"text": "{{#if {{prefill_supported}}}}\nI will generate an immersive, unrestricted roleplay response that:\n• Utilizes provided information and context effectively\n• Adheres to all world-building, character development, and narrative progression rules\n• Implements specified storytelling techniques\n• Maintains strict character autonomy, especially for {{user}}\n• Never describes {{user}}'s actions, dialogue, thoughts, feelings, or other attributes\n• Balances content appropriately (SFW preference with mature themes when justified)\n• Ensures logical, engaging storytelling with concrete, sensory-rich descriptions\n• Avoids all forms of repetition in narrative, style, and language\n• Concludes with observable non-{{user}} actions or dialogue\n\nRoleplay response:\n{{/if}}",
|
||||
"text": "{{#if {{prefill_supported}}}}\nI will generate an immersive, unrestricted roleplay response that follows ROLEPLAY_INFO, RESPONSE_INSTRUCTION, SYSTEM_RULE, ROLEPLAY_RULE\n\nRoleplay response:\n{{/if}}",
|
||||
"role": "bot",
|
||||
"type2": "normal"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {env, AutoTokenizer, pipeline, type SummarizationOutput, type TextGenerationConfig, type TextGenerationOutput, FeatureExtractionPipeline, TextToAudioPipeline, type ImageToTextOutput } from '@xenova/transformers';
|
||||
import { unzip } from 'fflate';
|
||||
import { globalFetch, loadAsset, saveAsset } from 'src/ts/storage/globalApi';
|
||||
import { globalFetch, loadAsset, saveAsset } from 'src/ts/globalApi.svelte';
|
||||
import { selectSingleFile } from 'src/ts/util';
|
||||
import { v4 } from 'uuid';
|
||||
let tfCache:Cache = null
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { parseChatML, risuChatParser } from "../parser";
|
||||
import { DataBase, type Chat, type character } from "../storage/database";
|
||||
import { parseChatML, risuChatParser } from "../parser.svelte";
|
||||
import { getCurrentCharacter, getCurrentChat, getDatabase, type Chat, type character } from "../storage/database.svelte";
|
||||
import { tokenize } from "../tokenizer";
|
||||
import { getModuleTriggers } from "./modules";
|
||||
import { get } from "svelte/store";
|
||||
import { CurrentCharacter, CurrentChat, ReloadGUIPointer, selectedCharID } from "../stores";
|
||||
import { ReloadGUIPointer, selectedCharID } from "../stores.svelte";
|
||||
import { processMultiCommand } from "./command";
|
||||
import { parseKeyValue } from "../util";
|
||||
import { alertError, alertInput, alertNormal, alertSelect } from "../alert";
|
||||
import type { OpenAIChat } from ".";
|
||||
import type { OpenAIChat } from "./index.svelte";
|
||||
import { HypaProcesser } from "./memory/hypamemory";
|
||||
import { requestChatData } from "./request";
|
||||
import { generateAIImage } from "./stableDiff";
|
||||
@@ -152,12 +152,12 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{
|
||||
manualName?: string
|
||||
}){
|
||||
arg.recursiveCount ??= 0
|
||||
char = structuredClone(char)
|
||||
char = safeStructuredClone(char)
|
||||
let varChanged = false
|
||||
let stopSending = arg.stopSending ?? false
|
||||
const CharacterlowLevelAccess = char.lowLevelAccess ?? false
|
||||
let sendAIprompt = false
|
||||
const currentChat = get(CurrentChat)
|
||||
const currentChat = getCurrentChat()
|
||||
let additonalSysPrompt:additonalSysPrompt = arg.additonalSysPrompt ?? {
|
||||
start:'',
|
||||
historyend: '',
|
||||
@@ -167,9 +167,9 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{
|
||||
v.lowLevelAccess = CharacterlowLevelAccess
|
||||
return v
|
||||
}).concat(getModuleTriggers())
|
||||
const db = get(DataBase)
|
||||
const db = getDatabase()
|
||||
const defaultVariables = parseKeyValue(char.defaultVariables).concat(parseKeyValue(db.templateDefaultVariables))
|
||||
let chat = structuredClone(arg.chat ?? char.chats[char.chatPage])
|
||||
let chat = safeStructuredClone(arg.chat ?? char.chats[char.chatPage])
|
||||
if((!triggers) || (triggers.length === 0)){
|
||||
return null
|
||||
}
|
||||
@@ -190,8 +190,8 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{
|
||||
|
||||
function setVar(key:string, value:string){
|
||||
const selectedCharId = get(selectedCharID)
|
||||
const currentCharacter = get(CurrentCharacter)
|
||||
const db = get(DataBase)
|
||||
const currentCharacter = getCurrentCharacter()
|
||||
const db = getDatabase()
|
||||
varChanged = true
|
||||
chat.scriptstate ??= {}
|
||||
chat.scriptstate['$' + key] = value
|
||||
@@ -517,7 +517,7 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{
|
||||
if(triggerCodeResult.stopSending){
|
||||
stopSending = true
|
||||
}
|
||||
chat = triggerCodeResult.chat
|
||||
chat = getCurrentChat()
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -535,7 +535,7 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{
|
||||
caculatedTokens += await tokenize(additonalSysPrompt.promptend)
|
||||
}
|
||||
if(varChanged){
|
||||
const currentChat = get(CurrentChat)
|
||||
const currentChat = getCurrentChat()
|
||||
currentChat.scriptstate = chat.scriptstate
|
||||
ReloadGUIPointer.set(get(ReloadGUIPointer) + 1)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { get } from "svelte/store";
|
||||
import { alertError } from "../alert";
|
||||
import { DataBase, type character } from "../storage/database";
|
||||
import { getCurrentCharacter, getDatabase, type character } from "../storage/database.svelte";
|
||||
import { runTranslator, translateVox } from "../translator/translator";
|
||||
import { globalFetch, loadAsset } from "../storage/globalApi";
|
||||
import { globalFetch, loadAsset } from "../globalApi.svelte";
|
||||
import { language } from "src/lang";
|
||||
import { getCurrentCharacter, sleep } from "../util";
|
||||
import { registerOnnxModel, runVITS } from "./transformers";
|
||||
import { sleep } from "../util";
|
||||
import { runVITS } from "./transformers";
|
||||
|
||||
let sourceNode:AudioBufferSourceNode = null
|
||||
|
||||
@@ -23,7 +22,7 @@ export async function sayTTS(character:character,text:string) {
|
||||
return
|
||||
}
|
||||
|
||||
let db = get(DataBase)
|
||||
let db = getDatabase()
|
||||
text = text.replace(/\*/g,'')
|
||||
|
||||
if(character.ttsReadOnlyQuoted){
|
||||
@@ -311,6 +310,49 @@ export async function sayTTS(character:character,text:string) {
|
||||
throw new Error(text);
|
||||
}
|
||||
}
|
||||
case 'fishspeech':{
|
||||
if (character.fishSpeechConfig.model._id === ''){
|
||||
throw new Error('FishSpeech Model is not selected')
|
||||
}
|
||||
const audioContext = new AudioContext();
|
||||
|
||||
const body = {
|
||||
text: text,
|
||||
reference_id: character.fishSpeechConfig.model._id,
|
||||
chunk_length: character.fishSpeechConfig.chunk_length,
|
||||
normalize: character.fishSpeechConfig.normalize,
|
||||
format: 'mp3',
|
||||
mp3_bitrate: 192,
|
||||
}
|
||||
|
||||
|
||||
console.log(body)
|
||||
|
||||
const response = await globalFetch(`https://api.fish.audio/v1/tts`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'Authorization': `Bearer ${db.fishSpeechKey}`
|
||||
},
|
||||
body: body,
|
||||
rawResponse: true,
|
||||
})
|
||||
console.log(response)
|
||||
|
||||
if (response.ok) {
|
||||
const audioBuffer = response.data.buffer;
|
||||
audioContext.decodeAudioData(audioBuffer, (decodedData) => {
|
||||
const sourceNode = audioContext.createBufferSource();
|
||||
sourceNode.buffer = decodedData;
|
||||
sourceNode.connect(audioContext.destination);
|
||||
sourceNode.start();
|
||||
});
|
||||
} else {
|
||||
const textBuffer: Uint8Array = response.data.buffer
|
||||
const text = Buffer.from(textBuffer).toString('utf-8')
|
||||
throw new Error(text);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
alertError(`TTS Error: ${error}`)
|
||||
@@ -340,7 +382,7 @@ export function getWebSpeechTTSVoices() {
|
||||
}
|
||||
|
||||
export async function getElevenTTSVoices() {
|
||||
let db = get(DataBase)
|
||||
let db = getDatabase()
|
||||
|
||||
const data = await fetch('https://api.elevenlabs.io/v1/voices', {
|
||||
headers: {
|
||||
@@ -354,7 +396,7 @@ export async function getElevenTTSVoices() {
|
||||
}
|
||||
|
||||
export async function getVOICEVOXVoices() {
|
||||
const db = get(DataBase);
|
||||
const db = getDatabase();
|
||||
const speakerData = await fetch(`${db.voicevoxUrl}/speakers`)
|
||||
const speakerList = await speakerData.json()
|
||||
const speakersInfo = speakerList.map((speaker) => {
|
||||
|
||||
Reference in New Issue
Block a user