diff --git a/src/lang/en.ts b/src/lang/en.ts
index 85e33bcf..97cf7a56 100644
--- a/src/lang/en.ts
+++ b/src/lang/en.ts
@@ -359,10 +359,11 @@ export const languageEnglish = {
changeFolderColor: "Change Folder Color",
fullWordMatching: "Full Word Matching",
botSettingAtStart: "Bot Menu when Launch",
- triggerStart: "On start of a chat",
+ triggerStart: "On chat Send",
+ triggerInput: "On user's output",
triggerOutput: "On character's output",
- triggerManual: "Manual Trigger Only",
- triggerCondVar: "If Variable is",
+ triggerManual: "Manual trigger only",
+ triggerCondVar: "If Variable",
triggerCondExists: "If Text Exists on Chat",
triggerScript: "Trigger Script",
triggerMatchRegex: "Match with Regex",
@@ -376,7 +377,7 @@ export const languageEnglish = {
greaterEqual: "Greater or Equal to",
lessEqual: "Less or Equal to",
triggerEffSysPrompt: 'Add System Prompt',
- triggerEffSetVar: 'Set Variable',
+ triggerEffSetVar: 'Modify Variable',
triggerEffImperson: 'Send Chat',
varableName: "Variable Name",
role: "Role",
@@ -386,5 +387,14 @@ export const languageEnglish = {
historyend: "End of History",
always: "Always",
noEffect: "No Effect",
-
+ invaildTriggerEffect: "This effect doesn't works for this trigger type.",
+ operator: "Operator",
+ TriggerSetToVar: "Set to Variable",
+ TriggerAddToVar: "Add to Variable",
+ TriggerSubToVar: "Subtract from Variable",
+ TriggerMulToVar: "Multiply to Variable",
+ TriggerDivToVar: "Divide from Variable",
+ isNull: "is not set",
+ ifChatIndex: "If chat index",
+ ifRandom: "If random",
}
\ No newline at end of file
diff --git a/src/lib/ChatScreens/DefaultChatScreen.svelte b/src/lib/ChatScreens/DefaultChatScreen.svelte
index 161f38dc..bb175fce 100644
--- a/src/lib/ChatScreens/DefaultChatScreen.svelte
+++ b/src/lib/ChatScreens/DefaultChatScreen.svelte
@@ -19,6 +19,7 @@
import Help from '../Others/Help.svelte';
import AssetInput from './AssetInput.svelte';
import { downloadFile } from 'src/ts/storage/globalApi';
+ import { runTrigger } from 'src/ts/process/triggers';
let messageInput:string = ''
let messageInputTranslate:string = ''
@@ -61,6 +62,11 @@
else{
const char = $DataBase.characters[selectedChar]
if(char.type === 'character'){
+ let triggerResult = runTrigger(char,'input', {chat: char.chats[char.chatPage]})
+ if(triggerResult){
+ cha = triggerResult.chat.message
+ }
+
cha.push({
role: 'user',
data: processScript(char,messageInput,'editinput')
diff --git a/src/lib/SideBars/CharConfig.svelte b/src/lib/SideBars/CharConfig.svelte
index b1806729..9054a840 100644
--- a/src/lib/SideBars/CharConfig.svelte
+++ b/src/lib/SideBars/CharConfig.svelte
@@ -469,7 +469,7 @@
let script = currentChar.data.triggerscript
script.push({
comment: "",
- type: "output",
+ type: "start",
conditions: [],
effect: []
})
diff --git a/src/lib/SideBars/Scripts/TriggerData.svelte b/src/lib/SideBars/Scripts/TriggerData.svelte
index def3acfa..7de6a265 100644
--- a/src/lib/SideBars/Scripts/TriggerData.svelte
+++ b/src/lib/SideBars/Scripts/TriggerData.svelte
@@ -50,8 +50,9 @@
{language.type}
- {language.triggerOutput}
{language.triggerStart}
+ {language.triggerOutput}
+ {language.triggerInput}
{language.triggerManual}
@@ -100,9 +101,18 @@
operator: '='
}
}
+ if(cond.type === 'chatindex'){
+ cond = {
+ type: 'chatindex',
+ value: '',
+ operator: '='
+ }
+ }
+
}}>
{language.triggerCondExists}
{language.triggerCondVar}
+ {language.ifChatIndex}
{#if cond.type === 'exists'}
@@ -117,9 +127,11 @@
{language.searchDepth}
{/if}
- {#if cond.type === 'var'}
- {language.varableName}
-
+ {#if cond.type === 'var' || cond.type === 'chatindex'}
+ {#if cond.type === 'var'}
+ {language.varableName}
+
+ {/if}
{language.value}
{language.equal}
@@ -128,19 +140,33 @@
{language.less}
{language.greaterEqual}
{language.lessEqual}
+ {language.isNull}
+
-
+ {#if cond.operator !== 'null'}
+
+ {/if}
{/if}
{/each}
Effects
@@ -174,7 +200,8 @@
effect = {
type: 'setvar',
var: '',
- value: ''
+ value: '',
+ operator: '='
}
}
if(effect.type === 'impersonate'){
@@ -185,11 +212,16 @@
}
}
}}>
- {language.triggerEffSysPrompt}
+ {#if effect.type === 'systemprompt' || value.type === 'start'}
+ {language.triggerEffSysPrompt}
+ {/if}
{language.triggerEffSetVar}
{language.triggerEffImperson}
{#if effect.type === 'systemprompt'}
+ {#if value.type !== 'start'}
+ {language.invaildTriggerEffect}
+ {/if}
{language.location}
{language.promptstart}
@@ -202,6 +234,14 @@
{#if effect.type === 'setvar'}
{language.varableName}
+ {language.operator}
+
+ {language.TriggerSetToVar}
+ {language.TriggerAddToVar}
+ {language.TriggerSubToVar}
+ {language.TriggerMulToVar}
+ {language.TriggerDivToVar}
+
{language.value}
{/if}
diff --git a/src/ts/parser.ts b/src/ts/parser.ts
index 7b94ef40..c44a3a1e 100644
--- a/src/ts/parser.ts
+++ b/src/ts/parser.ts
@@ -305,7 +305,7 @@ function wppParser(data:string){
const rgx = /(?:{{|<)(.+?)(?:}}|>)/gm
-type matcherArg = {chatID:number,db:Database,chara:character|string,rmVar:boolean}
+type matcherArg = {chatID:number,db:Database,chara:character|string,rmVar:boolean,var?:{[key:string]:string}}
const matcher = (p1:string,matcherArg:matcherArg) => {
if(p1.length > 10000){
return ''
@@ -448,7 +448,7 @@ const matcher = (p1:string,matcherArg:matcherArg) => {
const v = arra[1]
switch(arra[0]){
case 'getvar':{
- const d =getVarChat(chatID)
+ const d = matcherArg.var ?? getVarChat(chatID)
return d[v] ?? "[Null]"
}
case 'calc':{
@@ -568,7 +568,8 @@ export function risuChatParser(da:string, arg:{
chatID?:number
db?:Database
chara?:string|character|groupChat
- rmVar?:boolean
+ rmVar?:boolean,
+ var?:{[key:string]:string}
} = {}):string{
const chatID = arg.chatID ?? -1
const db = arg.db ?? get(DataBase)
@@ -597,7 +598,8 @@ export function risuChatParser(da:string, arg:{
chatID: chatID,
chara: chara,
rmVar: arg.rmVar ?? false,
- db: db
+ db: db,
+ var: arg.var ?? null
}
while(pointer < da.length){
switch(da[pointer]){
diff --git a/src/ts/process/index.ts b/src/ts/process/index.ts
index 3d15223b..6ab037d7 100644
--- a/src/ts/process/index.ts
+++ b/src/ts/process/index.ts
@@ -15,6 +15,7 @@ import { supaMemory } from "./memory/supaMemory";
import { v4 } from "uuid";
import { cloneDeep } from "lodash";
import { groupOrder } from "./group";
+import { runTrigger, type additonalSysPrompt } from "./triggers";
export interface OpenAIChat{
role: 'system'|'user'|'assistant'|'function'
@@ -185,7 +186,6 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
chatObjects.push({ role, content });
}
- console.log(chatObjects)
return chatObjects;
}
@@ -288,7 +288,14 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
currentTokens += await tokenizer.tokenizeChat(chat)
}
- const ms = currentChat.message
+ let ms = currentChat.message
+
+ const triggerResult = runTrigger(currentChar, 'start', {chat: currentChat})
+ if(triggerResult){
+ currentChat = triggerResult.chat
+ ms = currentChat.message
+ }
+
for(const msg of ms){
let formedChat = processScript(nowChatroom,risuChatParser(msg.data, {chara: currentChar, rmVar: true}), 'editprocess')
let name = ''
@@ -368,6 +375,29 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
unformated.chats = chats
+
+ if(triggerResult){
+ if(triggerResult.additonalSysPrompt.promptend){
+ unformated.postEverything.push({
+ role: 'system',
+ content: triggerResult.additonalSysPrompt.promptend
+ })
+ }
+ if(triggerResult.additonalSysPrompt.historyend){
+ unformated.lastChat.push({
+ role: 'system',
+ content: triggerResult.additonalSysPrompt.historyend
+ })
+ }
+ if(triggerResult.additonalSysPrompt.start){
+ unformated.lastChat.unshift({
+ role: 'system',
+ content: triggerResult.additonalSysPrompt.start
+ })
+ }
+ }
+
+
//make into one
let formated:OpenAIChat[] = []
@@ -462,6 +492,11 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
}
}
+ const triggerResult = runTrigger(currentChar, 'output', {chat:currentChat})
+ if(triggerResult){
+ db.characters[selectedChar].chats[selectedChat] = triggerResult.chat
+ setDatabase(db)
+ }
await sayTTS(currentChar, result)
}
else{
@@ -477,6 +512,10 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
saying: currentChar.chaId
})
db.characters[selectedChar].reloadKeys += 1
+ const triggerResult = runTrigger(currentChar, 'output', {chat:currentChat})
+ if(triggerResult){
+ db.characters[selectedChar].chats[selectedChat] = triggerResult.chat
+ }
await sayTTS(currentChar, result)
setDatabase(db)
}
@@ -646,7 +685,6 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
const msgs = db.characters[selectedChar].chats[selectedChat].message
let msgStr = ''
for(let i = (msgs.length - 1);i>=0;i--){
- console.log(i,msgs.length,msgs[i])
if(msgs[i].role === 'char'){
msgStr = `character: ${msgs[i].data.replace(/\n/, ' ')} \n` + msgStr
}
@@ -663,5 +701,6 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
setDatabase(db)
}
}
+
return true
}
\ No newline at end of file
diff --git a/src/ts/process/triggers.ts b/src/ts/process/triggers.ts
index 2e7420a2..53b4a6e2 100644
--- a/src/ts/process/triggers.ts
+++ b/src/ts/process/triggers.ts
@@ -1,5 +1,6 @@
-import { getVarChat } from "../parser";
-import type { character } from "../storage/database";
+import { cloneDeep } from "lodash";
+import { getVarChat, risuChatParser } from "../parser";
+import type { Chat, character } from "../storage/database";
export interface triggerscript{
comment: string;
@@ -8,7 +9,7 @@ export interface triggerscript{
effect:triggerEffect[]
}
-export type triggerCondition = triggerConditionsVar|triggerConditionsExists
+export type triggerCondition = triggerConditionsVar|triggerConditionsExists|triggerConditionsChatIndex
export type triggerEffect = triggerEffectSetvar|triggerEffectSystemPrompt|triggerEffectImpersonate
@@ -16,7 +17,13 @@ export type triggerConditionsVar = {
type:'var'
var:string
value:string
- operator:'='|'!='|'>'|'<'|'>='|'<='
+ operator:'='|'!='|'>'|'<'|'>='|'<='|'null'
+}
+
+export type triggerConditionsChatIndex = {
+ type:'chatindex'
+ value:string
+ operator:'='|'!='|'>'|'<'|'>='|'<='|'null'
}
export type triggerConditionsExists ={
@@ -45,8 +52,17 @@ export interface triggerEffectImpersonate{
value:string
}type triggerMode = 'start'|'manual'|'output'|'input'
-export function runTrigger(char:character,mode:triggerMode){
- let additonalSysPrompt = {
+export type additonalSysPrompt = {
+ start:string,
+ historyend: string,
+ promptend: string
+}
+
+export function runTrigger(char:character,mode:triggerMode, arg:{
+ chat?: Chat
+} = {}){
+ char = cloneDeep(char)
+ let additonalSysPrompt:additonalSysPrompt = {
start:'',
historyend: '',
promptend: ''
@@ -54,9 +70,9 @@ export function runTrigger(char:character,mode:triggerMode){
let varValues = getVarChat(-1, char)
let varValuesChanged = false
const triggers = char.triggerscript
- const chat = char.chats[char.chatPage]
+ const chat = arg.chat ?? char.chats[char.chatPage]
if(!triggers){
- return {additonalSysPrompt, char}
+ return null
}
for(const trigger of triggers){
@@ -66,61 +82,63 @@ export function runTrigger(char:character,mode:triggerMode){
let pass = true
for(const condition of trigger.conditions){
- if(condition.type === 'var'){
- const varValue = varValues[condition.var]
+ if(condition.type === 'var' || condition.type === 'chatindex'){
+ const varValue = (condition.type === 'var') ? (varValues[condition.var] ?? '[Null]') : (chat.message.length)
if(varValue === undefined || varValue === null){
pass = false
break
}
else{
- if(condition.operator === '='){
- if(varValue !== condition.value){
- pass = false
+ switch(condition.operator){
+ case '=':
+ if(varValue !== condition.value){
+ pass = false
+ }
break
- }
- }
- else if(condition.operator === '!='){
- if(varValue === condition.value){
- pass = false
+ case '!=':
+ if(varValue === condition.value){
+ pass = false
+ }
break
- }
- }
- else if(condition.operator === '>'){
- if(Number(varValue) > Number(condition.value)){
- pass = false
+ case '>':
+ if(Number(varValue) > Number(condition.value)){
+ pass = false
+ }
break
- }
- }
- else if(condition.operator === '<'){
- if(Number(varValue) < Number(condition.value)){
- pass = false
+ case '<':
+ if(Number(varValue) < Number(condition.value)){
+ pass = false
+ }
break
- }
- }
- else if(condition.operator === '>='){
- if(Number(varValue) >= Number(condition.value)){
- pass = false
+ case '>=':
+ if(Number(varValue) >= Number(condition.value)){
+ pass = false
+ }
break
- }
- }
- else if(condition.operator === '<='){
- if(Number(varValue) <= Number(condition.value)){
- pass = false
+ case '<=':
+ if(Number(varValue) <= Number(condition.value)){
+ pass = false
+ }
+ break
+ case 'null':
+ if(varValue !== '[Null]'){
+ pass = false
+ }
break
- }
}
}
}
else if(condition.type === 'exists'){
+ const val = risuChatParser(condition.value,{chara:char, var:varValues})
let da = chat.message.slice(0-condition.depth).map((v)=>v.data).join(' ')
if(condition.type2 === 'strict'){
- pass = da.split(' ').includes(condition.value)
+ pass = da.split(' ').includes(val)
}
else if(condition.type2 === 'loose'){
- pass = da.toLowerCase().includes(condition.value.toLowerCase())
+ pass = da.toLowerCase().includes(val.toLowerCase())
}
else if(condition.type2 === 'regex'){
- pass = new RegExp(condition.value).test(da)
+ pass = new RegExp(val).test(da)
}
}
if(!pass){
@@ -169,8 +187,9 @@ export function runTrigger(char:character,mode:triggerMode){
chat.message[chat.message.length-1].data = chat.message.at(-1).data.replaceAll(/{{(setvar|getvar)::.+?}}/gis,'') + Object.keys(varValues).map((v)=>`{{setvar::${v}::${varValues[v]}}}`).join('')
}
- char.chats[char.chatPage] = chat
-
- return {additonalSysPrompt, char}
+ if(arg.chat !== undefined && arg.chat !== null){
+ char.chats[char.chatPage] = chat
+ }
+ return {additonalSysPrompt, chat}
}
\ No newline at end of file