diff --git a/src/lib/ChatScreens/Chat.svelte b/src/lib/ChatScreens/Chat.svelte
index 57103313..1342f104 100644
--- a/src/lib/ChatScreens/Chat.svelte
+++ b/src/lib/ChatScreens/Chat.svelte
@@ -7,7 +7,7 @@
import { DataBase, type character, type groupChat } from "../../ts/storage/database";
import { selectedCharID } from "../../ts/stores";
import { translate } from "../../ts/translator/translator";
- import { replacePlaceholders } from "../../ts/util";
+ import { risuChatParser } from "src/ts/process/scripts";
export let message = ''
export let name = ''
export let isLastMemory:boolean
@@ -56,13 +56,13 @@
async function displaya(message:string){
if($DataBase.autoTranslate && $DataBase.translator !== ''){
if(msgTranslated==='')
- msgDisplay = replacePlaceholders(message, name)
- msgDisplay = await translate(replacePlaceholders(message, name), false)
+ msgDisplay = risuChatParser(message, {chara: name, chatID: idx})
+ msgDisplay = await translate(risuChatParser(message, {chara: name, chatID: idx}), false)
msgTranslated = msgDisplay
translated = true;
}
else{
- msgDisplay = replacePlaceholders(message, name)
+ msgDisplay = risuChatParser(message, {chara: name, chatID: idx})
}
}
@@ -130,13 +130,13 @@
translated = true
return
}
- msgDisplay = (await translate(replacePlaceholders(message, name), false))
+ msgDisplay = (await translate(risuChatParser(message, {chara: name, chatID: idx}), false))
msgTranslated = msgDisplay
translating = false
translated = true
}
else{
- msgDisplay = replacePlaceholders(message, name)
+ msgDisplay = risuChatParser(message, {chara: name, chatID: idx})
translated = false
}
}}>
diff --git a/src/ts/process/exampleMessages.ts b/src/ts/process/exampleMessages.ts
index 970d7ff4..e27b1780 100644
--- a/src/ts/process/exampleMessages.ts
+++ b/src/ts/process/exampleMessages.ts
@@ -1,6 +1,6 @@
import type { OpenAIChat } from ".";
import type { character } from "../storage/database";
-import { replacePlaceholders } from "../util";
+import { risuChatParser } from "./scripts";
export function exampleMessage(char:character, userName:string):OpenAIChat[]{
if(char.exampleMessage === ''){
@@ -58,7 +58,7 @@ export function exampleMessage(char:character, userName:string):OpenAIChat[]{
result = result.map((r) => {
return {
role: r.role,
- content: replacePlaceholders(r.content, char.name)
+ content: risuChatParser(r.content, {chara: char})
}
})
diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts
index e8d7f5f5..ceb2dbd7 100644
--- a/src/ts/process/index.ts
+++ b/src/ts/process/index.ts
@@ -5,10 +5,10 @@ import { ChatTokenizer, tokenizeNum } from "../tokenizer";
import { language } from "../../lang";
import { alertError } from "../alert";
import { loadLoreBookPrompt } from "./lorebook";
-import { findCharacterbyId, replacePlaceholders } from "../util";
+import { findCharacterbyId } from "../util";
import { requestChatData } from "./request";
import { stableDiff } from "./stableDiff";
-import { processScript, processScriptFull } from "./scripts";
+import { processScript, processScriptFull, risuChatParser } from "./scripts";
import { exampleMessage } from "./exampleMessages";
import { sayTTS } from "./tts";
import { supaMemory } from "./memory/supaMemory";
@@ -183,31 +183,31 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
return chatObjects;
}
- unformated.main.push(...formatPrompt(replacePlaceholders(mainp + ((db.additionalPrompt === '' || (!db.promptPreprocess)) ? '' : `\n${db.additionalPrompt}`), currentChar.name)))
+ unformated.main.push(...formatPrompt(risuChatParser(mainp + ((db.additionalPrompt === '' || (!db.promptPreprocess)) ? '' : `\n${db.additionalPrompt}`), {chara: currentChar})))
if(db.jailbreakToggle){
- unformated.jailbreak.push(...formatPrompt(replacePlaceholders(db.jailbreak, currentChar.name)))
+ unformated.jailbreak.push(...formatPrompt(risuChatParser(db.jailbreak, {chara: currentChar})))
}
- unformated.globalNote.push(...formatPrompt(replacePlaceholders(currentChar.replaceGlobalNote?.replaceAll('{{original}}', db.globalNote) || db.globalNote, currentChar.name)))
+ unformated.globalNote.push(...formatPrompt(risuChatParser(currentChar.replaceGlobalNote?.replaceAll('{{original}}', db.globalNote) || db.globalNote, {chara:currentChar})))
}
if(currentChat.note){
unformated.authorNote.push({
role: 'system',
- content: replacePlaceholders(currentChat.note, currentChar.name)
+ content: risuChatParser(currentChat.note, {chara: currentChar})
})
}
{
- let description = replacePlaceholders((db.promptPreprocess ? db.descriptionPrefix: '') + currentChar.desc, currentChar.name)
+ let description = risuChatParser((db.promptPreprocess ? db.descriptionPrefix: '') + currentChar.desc, {chara: currentChar})
if(currentChar.personality){
- description += replacePlaceholders("\n\nDescription of {{char}}: " + currentChar.personality,currentChar.name)
+ description += risuChatParser("\n\nDescription of {{char}}: " + currentChar.personality, {chara: currentChar})
}
if(currentChar.scenario){
- description += replacePlaceholders("\n\nCircumstances and context of the dialogue: " + currentChar.scenario,currentChar.name)
+ description += risuChatParser("\n\nCircumstances and context of the dialogue: " + currentChar.scenario, {chara: currentChar})
}
unformated.description.push({
@@ -227,19 +227,19 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
const lorepmt = await loadLoreBookPrompt()
unformated.lorebook.push({
role: 'system',
- content: replacePlaceholders(lorepmt.act, currentChar.name)
+ content: risuChatParser(lorepmt.act, {chara: currentChar})
})
if(db.personaPrompt){
unformated.personaPrompt.push({
role: 'system',
- content: replacePlaceholders(db.personaPrompt, currentChar.name)
+ content: risuChatParser(db.personaPrompt, {chara: currentChar})
})
}
if(lorepmt.special_act){
unformated.postEverything.push({
role: 'system',
- content: replacePlaceholders(lorepmt.special_act, currentChar.name)
+ content: risuChatParser(lorepmt.special_act, {chara: currentChar})
})
}
@@ -275,7 +275,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
const chat:OpenAIChat = {
role: 'assistant',
content: processScript(nowChatroom,
- replacePlaceholders(firstMsg, currentChar.name),
+ risuChatParser(firstMsg, {chara: currentChar}),
'editprocess')
}
chats.push(chat)
@@ -284,7 +284,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
const ms = currentChat.message
for(const msg of ms){
- let formedChat = processScript(nowChatroom,replacePlaceholders(msg.data, currentChar.name), 'editprocess')
+ let formedChat = processScript(nowChatroom,risuChatParser(msg.data, {chara: currentChar}), 'editprocess')
let name = ''
if(msg.role === 'char'){
if(msg.saying){
diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts
index 32332d7c..b517c4ba 100644
--- a/src/ts/process/scripts.ts
+++ b/src/ts/process/scripts.ts
@@ -1,6 +1,6 @@
import { get } from "svelte/store";
import { CharEmotion, selectedCharID } from "../stores";
-import { DataBase, setDatabase, type character, type customscript, type groupChat } from "../storage/database";
+import { DataBase, setDatabase, type character, type customscript, type groupChat, type Database } from "../storage/database";
import { downloadFile } from "../storage/globalApi";
import { alertError, alertNormal } from "../alert";
import { language } from "src/lang";
@@ -130,56 +130,12 @@ export function processScriptFull(char:character|groupChat, data:string, mode:Sc
}
}
else{
-
- function skr(da:string){
- return da.replace(/{{(.+?)}}/g, (v, p1:string) => {
- if(p1 === 'previous_char_chat'){
- if(chatID !== -1){
- const selchar = db.characters[get(selectedCharID)]
- const chat = selchar.chats[selchar.chatPage]
- let pointer = chatID - 1
- while(pointer >= 0){
- if(chat.message[pointer].role === 'char'){
- return chat.message[pointer].data
- }
- pointer--
- }
- return selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
- }
- return
- }
- if(p1 === 'previous_user_chat'){
- if(chatID !== -1){
- const selchar = db.characters[get(selectedCharID)]
- const chat = selchar.chats[selchar.chatPage]
- let pointer = chatID - 1
- while(pointer >= 0){
- if(chat.message[pointer].role === 'user'){
- return chat.message[pointer].data
- }
- pointer--
- }
- return selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
- }
- }
- if(p1.startsWith('getvar')){
- const v = p1.split("::")[1]
- const d =getVarChat(chatID)
- return d[v] ?? "[Null]"
- }
- if(p1.startsWith('calc')){
- const v = p1.split("::")[1]
- return calcString(v).toString()
- }
- return v
- })
- }
- let mOut = skr(outScript.replace(dreg, "$&"))
+ let mOut = risuChatParser(outScript.replace(dreg, "$&"), {chatID: chatID, db:db})
if(randomness.test(data)){
const list = data.split('|||')
data = list[Math.floor(Math.random()*list.length)];
}
- data = skr(data.replace(reg, mOut))
+ data = risuChatParser(data.replace(reg, mOut), {chatID: chatID, db:db})
}
}
}
@@ -187,6 +143,134 @@ export function processScriptFull(char:character|groupChat, data:string, mode:Sc
}
+const rgx = /{{(.+?)}}/gm
+export function risuChatParser(da:string, arg:{
+ chatID?:number
+ db?:Database
+ chara?:string|character
+} = {}):string{
+ const chatID = arg.chatID ?? -1
+ const db = arg.db ?? get(DataBase)
+ return da.replace(rgx, (v, p1:string) => {
+ const lowerCased = p1.toLocaleLowerCase()
+ switch(lowerCased){
+ case 'previous_char_chat':{
+ if(chatID !== -1){
+ const selchar = db.characters[get(selectedCharID)]
+ const chat = selchar.chats[selchar.chatPage]
+ let pointer = chatID - 1
+ while(pointer >= 0){
+ if(chat.message[pointer].role === 'char'){
+ return chat.message[pointer].data
+ }
+ pointer--
+ }
+ return selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
+ }
+ return ''
+ }
+ case 'previous_user_chat':{
+ if(chatID !== -1){
+ const selchar = db.characters[get(selectedCharID)]
+ const chat = selchar.chats[selchar.chatPage]
+ let pointer = chatID - 1
+ while(pointer >= 0){
+ if(chat.message[pointer].role === 'user'){
+ return chat.message[pointer].data
+ }
+ pointer--
+ }
+ return selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
+ }
+ return ''
+ }
+ case 'char':
+ case 'bot':{
+ const chara = arg.chara
+ if(chara){
+ if(typeof(chara) === 'string'){
+ return chara
+ }
+ else{
+ return chara.name
+ }
+ }
+ let selectedChar = get(selectedCharID)
+ let currentChar = db.characters[selectedChar]
+ return currentChar.name
+ }
+ case 'user':{
+ return db.username
+ }
+ case 'personality':
+ case 'char_persona':{
+ const argChara = arg.chara
+ const chara = (argChara && typeof(argChara) !== 'string') ? argChara : (db.characters[get(selectedCharID)])
+ if(chara.type === 'group'){
+ return ""
+ }
+ return chara.personality
+ }
+ case 'persona':
+ case 'user_persona':{
+ const argChara = arg.chara
+ const chara = (argChara && typeof(argChara) !== 'string') ? argChara : (db.characters[get(selectedCharID)])
+ if(chara.type === 'group'){
+ return ""
+ }
+ return chara.personality
+ }
+ case 'ujb':
+ case 'global_note':{
+ return db.globalNote
+ }
+ case 'chat_index':{
+ return chatID.toString()
+ }
+ case 'blank':
+ case 'none':{
+ return ''
+ }
+ }
+ const arra = p1.split("::")
+ if(arra.length > 1){
+ const v = arra[1]
+ switch(arra[0]){
+ case 'getvar':{
+ const d =getVarChat(chatID)
+ return d[v] ?? "[Null]"
+ }
+ case 'calc':{
+ return calcString(v).toString()
+ }
+ case 'addvar':
+ case 'setvar':{
+ return ''
+ }
+ case 'button':{
+ return ``
+ }
+ case 'risu':{
+ return `
`
+ }
+ }
+ }
+ if(p1.startsWith('random')){
+ if(p1.startsWith('random::')){
+ const randomIndex = Math.floor(Math.random() * (arra.length - 1)) + 1
+ return arra[randomIndex]
+ }
+ else{
+ const arr = p1.split(/\:|\,/g)
+ const randomIndex = Math.floor(Math.random() * (arr.length - 1)) + 1
+ return arr[randomIndex]
+ }
+ }
+ return v
+ })
+}
+
+
export function getVarChat(targetIndex = -1){
const db = get(DataBase)
const selchar = db.characters[get(selectedCharID)]
@@ -196,10 +280,15 @@ export function getVarChat(targetIndex = -1){
targetIndex = chat.message.length - 1
}
let vars:{[key:string]:string} = {}
+ let rules:{
+ key:string
+ rule:string
+ arg:string
+ }[] = []
const fm = selchar.firstMsgIndex === -1 ? selchar.firstMessage : selchar.alternateGreetings[selchar.firstMsgIndex]
const rg = /(\{\{setvar::(.+?)::(.+?)\}\})/gu
const rg2 = /(\{\{addvar::(.+?)::(.+?)\}\})/gu
- const m = fm.matchAll(rg)
+ const rg3 = /(\{\{varrule_(.+?)::(.+?)::(.+?)\}\})/gu
function process(text:string){
const m = text.matchAll(rg)
for(const a of m){
@@ -213,11 +302,54 @@ export function getVarChat(targetIndex = -1){
vars[a[2]] = (parseInt(vars[a[2]]) + parseInt(a[3])).toString()
}
}
+ const m3 = text.matchAll(rg3)
+ for(const a of m3){
+ if(a.length === 5){
+ rules.push({
+ key: a[3],
+ rule: a[2],
+ arg: a[4]
+ })
+ }
+ }
}
process(fm)
while( i <= targetIndex ){
process(chat.message[i].data)
i += 1
}
+
+ for(const rule of rules){
+ if(vars[rule.key] === undefined){
+ continue
+ }
+ switch(rule.rule){
+ case "max":{
+ if(parseInt(vars[rule.key]) > parseInt(rule.arg)){
+ vars[rule.key] = rule.arg
+ }
+ break
+ }
+ case "min":{
+ if(parseInt(vars[rule.key]) > parseInt(rule.arg)){
+ vars[rule.key] = rule.arg
+ }
+ break
+ }
+ case 'overflow':{
+ const exArg = rule.arg.split("::")
+ let rv = parseInt(vars[rule.key])
+ const val = parseInt(exArg[0])
+ const tg = exArg[1]
+
+ if(isNaN(val) || isNaN(rv)){
+ break
+ }
+
+ vars[tg] = (Math.floor(rv / val)).toString()
+ vars[rule.key] = (Math.floor(rv % val)).toString()
+ }
+ }
+ }
return vars
}
\ No newline at end of file