From d2fce340bb6264d7f77109393cfbbd2794410a84 Mon Sep 17 00:00:00 2001 From: Kwaroran Date: Sat, 15 Feb 2025 21:29:37 +0900 Subject: [PATCH] Add TriggerV2 --- .gitignore | 2 +- src/lang/en.ts | 141 ++ src/lang/ko.ts | 136 ++ .../Setting/Pages/Module/ModuleMenu.svelte | 16 +- src/lib/SideBars/Scripts/TriggerList.svelte | 71 +- src/lib/SideBars/Scripts/TriggerList2.svelte | 1502 +++++++++++++++++ src/lib/UI/GUI/Portal.svelte | 24 + src/lib/UI/GUI/PortalConsumer.svelte | 7 + src/ts/characters.ts | 16 +- src/ts/process/lua.ts | 2 +- src/ts/process/scripts.ts | 21 +- src/ts/process/triggers.ts | 1182 ++++++++++++- src/ts/util.ts | 3 +- tailwind.config.js | 2 + 14 files changed, 3087 insertions(+), 38 deletions(-) create mode 100644 src/lib/SideBars/Scripts/TriggerList2.svelte create mode 100644 src/lib/UI/GUI/Portal.svelte create mode 100644 src/lib/UI/GUI/PortalConsumer.svelte diff --git a/.gitignore b/.gitignore index cb2329d5..e10fde5c 100644 --- a/.gitignore +++ b/.gitignore @@ -41,5 +41,5 @@ recc.md __pycache__/ .tauri/ dist.zip -scripts/ +/scripts/ .env \ No newline at end of file diff --git a/src/lang/en.ts b/src/lang/en.ts index a034db13..1f098789 100644 --- a/src/lang/en.ts +++ b/src/lang/en.ts @@ -240,6 +240,129 @@ export const languageEnglish = { finallyOption2: "No", finallyOption2Desc: "This will disable advanced tools, and make the UI more simple. Recommended for new users.", }, + triggerDesc: { + v2Header: "Header", + v2HeaderDesc: "Header", + v2If: "If", + v2IfDesc: "If {{source}} {{condition}} {{target}}", + v2Else: "Else", + v2ElseDesc: "Else", + v2EndIndent: "End Indent", + v2EndIndentDesc: "End Indent", + v2SetVar: "Set Variable", + v2SetVarDesc: "Set Variable {{var}} {{operator}} {{value}}", + v2Loop: "Loop Forever", + v2LoopDesc: "Loop Forever", + v2BreakLoop: "Break Loop", + v2BreakLoopDesc: "Break Loop", + v2RunTrigger: "Run Trigger", + v2RunTriggerDesc: "Run Trigger {{target}}", + v2ConsoleLog: "Console Log", + v2ConsoleLogDesc: "Console Log {{source}}", + v2StopTrigger: "Stop Trigger", + v2StopTriggerDesc: "Stop Trigger", + v2CutChat: "Cut Chat", + v2CutChatDesc: "Cut Chat from {{start}} to {{end}}", + v2ModifyChat: "Modify Chat", + v2ModifyChatDesc: "Modify Chat at index {{index}} with {{value}}", + v2SystemPrompt: "Add System Prompt", + v2SystemPromptDesc: "Add System Prompt at {{location}} with {{value}}", + v2Impersonate: "Send Chat", + v2ImpersonateDesc: "Send Chat as {{role}} with {{value}}", + v2Command: "Run Command", + v2CommandDesc: "Run command with {{value}}", + v2SendAIprompt: "Send AI Prompt", + v2SendAIpromptDesc: "Send AI Prompt", + v2ImgGen: "Image Generation", + v2ImgGenDesc: "Generate image from {{value}}, negative from {{negValue}} => {{outputVar}}", + v2CheckSimilarity: "Check Similarity", + v2CheckSimilarityDesc: "Check similarity between {{source}} and {{value}} => {{outputVar}}", + v2RunLLM: "Run Model", + v2RunLLMDesc: "Send request to model from {{value}} => {{outputVar}}", + v2ShowAlert: "Show Alert", + v2ShowAlertDesc: "Show alert with {{value}}", + v2ExtractRegex: "Extract Regex", + v2ExtractRegexDesc: "Extract text from {{value}} with regex {{regexType}} {{regex}} and flags {{flagsType}} {{flags}}, then store result as {{resultType}} {{result}} => {{outputVar}}", + v2GetLastMessage: "Get Last Message", + v2GetLastMessageDesc: "Get Last Message => {{outputVar}}", + v2GetMessageAtIndex: "Get Message at Index", + v2GetMessageAtIndexDesc: "Get Message at Index {{index}} => {{outputVar}}", + v2GetMessageCount: "Get Message Count", + v2GetMessageCountDesc: "Get Message Count => {{outputVar}}", + v2GetLorebook: "Get Lorebook", + v2GetLorebookDesc: "Get Lorebook named {{target}} => {{outputVar}}", + v2GetLorebookCount: "Get Lorebook Count", + v2GetLorebookCountDesc: "Get Lorebook Count => {{outputVar}}", + v2GetLorebookEntry: "Get Lorebook with index", + v2GetLorebookEntryDesc: "Get Lorebook with index {{index}} => {{outputVar}}", + v2SetLorebookActivation: "Set Lorebook Activation", + v2SetLorebookActivationDesc: "Set Lorebook with index {{index}}'s activation state to {{value}}", + v2GetLorebookIndexViaName: "Get Lorebook Index via Name", + v2GetLorebookIndexViaNameDesc: "Get Lorebook Index via Name {{name}} => {{outputVar}}", + v2ModifyLorebook: "Modify Lorebook", + v2ModifyLorebookDesc: "Modify Lorebook named {{target}} with {{value}}", + v2LoopNTimes: "Loop N Times", + v2LoopNTimesDesc: "Loop {{value}} Times", + v2Random: "Random", + v2RandomDesc: "Random from {{min}} to {{max}} => {{outputVar}}", + v2GetCharAt: "Get Character at Index", + v2GetCharAtDesc: "Get Character at Index {{index}} from {{source}} => {{outputVar}}", + v2GetCharCount: "Get Character Count", + v2GetCharCountDesc: "Get Character Count from {{source}} => {{outputVar}}", + v2ToLowerCase: "Convert to Lower Case", + v2ToLowerCaseDesc: "Convert {{source}} to Lower Case => {{outputVar}}", + v2ToUpperCase: "Convert to Upper Case", + v2ToUpperCaseDesc: "Convert {{source}} to Upper Case => {{outputVar}}", + v2SetCharAt: "Set Character at Index", + v2SetCharAtDesc: "Set Character at Index {{index}} in {{source}} to {{value}} => {{outputVar}}", + v2SplitString: "Split String", + v2SplitStringDesc: "Split {{source}} by {{delimiter}} => {{outputVar}}", + v2GetCharacterDesc: "Get Character Description", + v2GetCharacterDescDesc: "Get Character Description => {{outputVar}}", + v2SetCharacterDesc: "Set Character Description", + v2SetCharacterDescDesc: "Set Character Description to {{value}}", + v2MakeArrayVar: "Make Array Variable", + v2MakeArrayVarDesc: "Make Array Variable {{var}}", + v2GetArrayVarLength: "Get Array Variable Length", + v2GetArrayVarLengthDesc: "Get Length of Array Variable {{var}} => {{outputVar}}", + v2GetArrayVar: "Get Array Variable", + v2GetArrayVarDesc: "Get Value at Index {{index}} from Array Variable {{var}} => {{outputVar}}", + v2SetArrayVar: "Set Array Variable", + v2SetArrayVarDesc: "Set Value at Index {{index}} in Array Variable {{var}} to {{value}}", + v2PushArrayVar: "Add to Array Variable", + v2PushArrayVarDesc: "Add {{value}} to Array Variable {{var}}", + v2PopArrayVar: "Remove last value from Array Variable and get", + v2PopArrayVarDesc: "Remove last value from Array Variable {{var}} => {{outputVar}}", + v2ShiftArrayVar: "Remove first value from from Array Variable and get", + v2ShiftArrayVarDesc: "Remove first value from Array Variable {{var}} => {{outputVar}}", + v2UnshiftArrayVar: "Add to Array Variable as first value", + v2UnshiftArrayVarDesc: "Add {{value}} as first value of Array Variable {{var}}", + v2SpliceArrayVar: "Add to Array Variable in Index", + v2SpliceArrayVarDesc: "Add {{value}} as {{start}} value of Array Variable {{var}}", + v2SliceArrayVar: "Slice Array Variable", + v2SliceArrayVarDesc: "Slice Array Variable {{var}} from {{start}} to {{end}} => {{outputVar}}", + v2GetIndexOfValueInArrayVar: "Get Index of Value in Array Variable", + v2GetIndexOfValueInArrayVarDesc: "Get Index of {{value}} in Array Variable {{var}} => {{outputVar}}", + v2RemoveIndexFromArrayVar: "Remove Index from Array Variable", + v2RemoveIndexFromArrayVarDesc: "Remove Value at Index {{index}} from Array Variable {{var}}", + v2ConcatString: "Concatenate Strings", + v2ConcatStringDesc: "Concatenate {{source1}} and {{source2}} => {{outputVar}}", + v2GetLastUserMessage: "Get Last User Message", + v2GetLastUserMessageDesc: "Get Last User Message => {{outputVar}}", + v2GetLastCharMessage: "Get Last Character Message", + v2GetLastCharMessageDesc: "Get Last Character Message => {{outputVar}}", + v2GetFirstMessage: "Get First Message", + v2GetFirstMessageDesc: "Get First Message => {{outputVar}}", + v2GetAlertInput: "Get Alert Input", + v2GetAlertInputDesc: "Get Alert Input => {{outputVar}}", + v2UnsupportedTrigger: "Unsupported Trigger", + v2UnsupportedTriggerDesc: "Unsupported Trigger", + v2GetDisplayState: "Get Display State", + v2GetDisplayStateDesc: "Get Display State => {{outputVar}}", + v2SetDisplayState: "Set Display State", + v2SetDisplayStateDesc: "Set Display State to {{value}}", + }, + confirm: "Confirm", goback: "Go Back", botSettings:'Bot Settings', @@ -843,4 +966,22 @@ export const languageEnglish = { showPromptComparison: "Show Prompt Comparison", hypaV3Desc: "HypaMemory V3 is a long-term memory system that use both summarized data and vector search.", inlayErrorResponse: "Inlay Error Response", + triggerOn: "Trigger On", + noConfig: "No Config", + varName: "Variable Name", + var: "Variable", + condition: "Condition", + trigger: "Trigger", + outputVar: "Output Variable", + source: "Source", + cmd: "Command", + sysStart: "System Start", + sysHistoryEnd: "System History End", + sysPromptEnd: "System Prompt End", + target: "Target", + addElse: "Add Else", + min: "Min", + max: "Max", + delimiter: "Delimiter", + deleteCount: "Delete Count", } \ No newline at end of file diff --git a/src/lang/ko.ts b/src/lang/ko.ts index 9d3cfa0b..785f0b2b 100644 --- a/src/lang/ko.ts +++ b/src/lang/ko.ts @@ -191,6 +191,128 @@ export const languageKorean = { "finallyOption2Desc": "이것은 고급 도구를 비활성화하며, UI를 더 간단하게 만듭니다. 신규 사용자에게 추천합니다.", "openAIProvider": "OpenAI GPT는 가장 좋은 모델이지만, 유료고 검열이 있습니다." }, + "triggerDesc": { + "v2Header": "헤더", + "v2HeaderDesc": "헤더", + "v2If": "만약 ~이라면", + "v2IfDesc": "만약 {{source}} {{condition}} {{target}} 이라면", + "v2Else": "아닐 경우", + "v2ElseDesc": "아닐 경우", + "v2EndIndent": "들여쓰기 끝", + "v2EndIndentDesc": "들여쓰기 끝", + "v2SetVar": "변수 설정", + "v2SetVarDesc": "변수 {{var}} {{operator}} {{value}}", + "v2Loop": "계속 반복하기", + "v2LoopDesc": "계속 반복하기", + "v2BreakLoop": "반복 중단", + "v2BreakLoopDesc": "반복 중단", + "v2RunTrigger": "트리거 실행", + "v2RunTriggerDesc": "트리거 {{target}} 실행", + "v2ConsoleLog": "콘솔 로그", + "v2ConsoleLogDesc": "{{source}}를 로그에 출력", + "v2StopTrigger": "트리거 중단", + "v2StopTriggerDesc": "트리거 중단", + "v2CutChat": "대화 부분 잘라내기", + "v2CutChatDesc": "{{start}}에서 {{end}}까지 대화 잘라내기", + "v2ModifyChat": "대화 수정", + "v2ModifyChatDesc": "인덱스 {{index}}에 있는 대화를 {{value}}로 수정", + "v2SystemPrompt": "시스템 프롬프트 추가", + "v2SystemPromptDesc": "{{location}}에 시스템 프롬프트 {{value}} 추가", + "v2Impersonate": "대화 보내기", + "v2ImpersonateDesc": "{{role}} 대화 {{value}} 보내기", + "v2Command": "명령 실행", + "v2CommandDesc": "{{value}} 명령 실행", + "v2SendAIprompt": "AI 프롬프트 전송", + "v2SendAIpromptDesc": "AI 프롬프트 전송", + "v2ImgGen": "이미지 생성", + "v2ImgGenDesc": "{{value}} 프롬프트로 이미지 생성 => {{outputVar}}", + "v2CheckSimilarity": "유사도 확인", + "v2CheckSimilarityDesc": "{{source}}와 {{value}}의 유사도 확인 => {{outputVar}}", + "v2RunLLM": "모델 실행", + "v2RunLLMDesc": "{{value}}을 모델에 요청 => {{outputVar}}", + "v2ShowAlert": "알림 표시", + "v2ShowAlertDesc": "{{value}}로 알림 표시", + "v2ExtractRegex": "정규식 추출", + "v2ExtractRegexDesc": "{{value}}에서 정규식 {{regexType}} {{regex}} 및 플래그 {{flagsType}} {{flags}}를 사용하여 텍스트 추출, 결과를 {{resultType}} {{result}}로 저장 => {{outputVar}}", + "v2GetLastMessage": "마지막 메시지 가져오기", + "v2GetLastMessageDesc": "마지막 메시지 가져오기 => {{outputVar}}", + "v2GetMessageAtIndex": "인덱스에서 메시지 가져오기", + "v2GetMessageAtIndexDesc": "인덱스 {{index}}에서 메시지 가져오기 => {{outputVar}}", + "v2GetMessageCount": "메시지 개수 가져오기", + "v2GetMessageCountDesc": "메시지 개수 가져오기 => {{outputVar}}", + "v2GetLorebook": "로어북 가져오기", + "v2GetLorebookDesc": "로어북 {{target}} 가져오기 => {{outputVar}}", + "v2GetLorebookCount": "로어북 개수 가져오기", + "v2GetLorebookCountDesc": "로어북 개수 가져오기 => {{outputVar}}", + "v2GetLorebookEntry": "인덱스에서 로어북 가져오기", + "v2GetLorebookEntryDesc": "인덱스 {{index}}에 있는 로어북 가져오기 => {{outputVar}}", + "v2SetLorebookActivation": "로어북 활성화 설정", + "v2SetLorebookActivationDesc": "인덱스 {{index}}에 있는 로어북의 활성화 상태를 {{value}}로 설정", + "v2GetLorebookIndexViaName": "이름으로 로어북 인덱스 가져오기", + "v2GetLorebookIndexViaNameDesc": "이름 {{name}}인 로어북의 인덱스 가져오기 => {{outputVar}}", + "v2ModifyLorebook": "로어북 수정", + "v2ModifyLorebookDesc": "로어북 {{target}}을 {{value}}로 수정", + "v2LoopNTimes": "N번 반복하기", + "v2LoopNTimesDesc": "{{value}} 번 반복하기", + "v2Random": "랜덤", + "v2RandomDesc": "{{min}}에서 {{max}}까지의 랜덤 값 => {{outputVar}}", + "v2GetCharAt": "문자열에서 N번째 문자 가져오기", + "v2GetCharAtDesc": "{{source}}의 {{index}}번째 문자 가져오기 => {{outputVar}}", + "v2GetCharCount": "문자 개수 가져오기", + "v2GetCharCountDesc": "{{source}}의 문자 개수 가져오기 => {{outputVar}}", + "v2ToLowerCase": "소문자로 변환", + "v2ToLowerCaseDesc": "{{source}}를 소문자로 변환 => {{outputVar}}", + "v2ToUpperCase": "대문자로 변환", + "v2ToUpperCaseDesc": "{{source}}를 대문자로 변환 => {{outputVar}}", + "v2SetCharAt": "문자열의 N번째 문자 변경", + "v2SetCharAtDesc": "{{source}}의 {{index}}번째 문자를 {{value}}로 변경 => {{outputVar}}", + "v2SplitString": "문자열 분할", + "v2SplitStringDesc": "{{source}}를 {{delimiter}}로 분할 => {{outputVar}}", + "v2GetCharacterDesc": "캐릭터 설명 가져오기", + "v2GetCharacterDescDesc": "캐릭터 설명 가져오기 => {{outputVar}}", + "v2SetCharacterDesc": "캐릭터 설명 설정", + "v2SetCharacterDescDesc": "캐릭터 설명을 {{value}}로 설정", + "v2MakeArrayVar": "배열 변수 생성", + "v2MakeArrayVarDesc": "배열 변수 {{var}} 생성", + "v2GetArrayVarLength": "배열 변수 길이 가져오기", + "v2GetArrayVarLengthDesc": "배열 변수 {{var}}의 길이 가져오기 => {{outputVar}}", + "v2GetArrayVar": "배열 변수 가져오기", + "v2GetArrayVarDesc": "배열 변수 {{var}}의 {{index}}번째 값 가져오기 => {{outputVar}}", + "v2SetArrayVar": "배열 변수 설정", + "v2SetArrayVarDesc": "배열 변수 {{var}}의 {{index}}번째 값을 {{value}}로 설정", + "v2PushArrayVar": "배열 변수 가장 뒤에 값 추가", + "v2PushArrayVarDesc": "배열 변수 {{var}} 의 가장 뒤에 {{value}} 추가", + "v2PopArrayVar": "배열 변수에서 마지막 값 제거 후 가져오기", + "v2PopArrayVarDesc": "배열 변수 {{var}}에서 마지막 값 제거 => {{outputVar}}", + "v2ShiftArrayVar": "배열 변수에서 첫 값 제거 후 가져오기", + "v2ShiftArrayVarDesc": "배열 변수 {{var}}에서 첫 값 제거 => {{outputVar}}", + "v2UnshiftArrayVar": "배열 변수에 첫 값 추가", + "v2UnshiftArrayVarDesc": "배열 변수 {{var}}에 {{value}} 첫 값으로 추가", + "v2SpliceArrayVar": "배열 변수 가운데에 값 추가", + "v2SpliceArrayVarDesc": "배열 변수 {{var}}의 {{start}}에 {{item}} 추가", + "v2SliceArrayVar": "배열 변수 슬라이스", + "v2SliceArrayVarDesc": "배열 변수 {{var}}의 {{start}}부터 {{end}}까지 슬라이스 => {{outputVar}}", + "v2GetIndexOfValueInArrayVar": "배열 변수에서 값의 인덱스 가져오기", + "v2GetIndexOfValueInArrayVarDesc": "배열 변수 {{var}}에서 값 {{value}}의 인덱스 가져오기 => {{outputVar}}", + "v2RemoveIndexFromArrayVar": "배열 변수에서 인덱스에 있는 값 제거", + "v2RemoveIndexFromArrayVarDesc": "배열 변수 {{var}}에서 인덱스 {{index}} 에 있는 값 제거", + "v2ConcatString": "문자열 합치기", + "v2ConcatStringDesc": "{{source1}}와 {{source2}}를 합치기 => {{outputVar}}", + "v2GetLastUserMessage": "마지막 유저 메시지 가져오기", + "v2GetLastUserMessageDesc": "마지막 유저 메시지 가져오기 => {{outputVar}}", + "v2GetLastCharMessage": "마지막 캐릭터 메시지 가져오기", + "v2GetLastCharMessageDesc": "마지막 캐릭터 메시지 가져오기 => {{outputVar}}", + "v2GetFirstMessage": "첫 메시지 가져오기", + "v2GetFirstMessageDesc": "첫 메시지 가져오기 => {{outputVar}}", + "v2GetAlertInput": "알림 입력창", + "v2GetAlertInputDesc": "알림 입력창 => {{outputVar}}", + "v2UnsupportedTrigger": "미지원 트리거", + "v2UnsupportedTriggerDesc": "지원되지 않는 트리거", + "v2SetDisplayState": "디스플레이 바꾸기", + "v2SetDisplayStateDesc": "디스플레이 상태를 {{value}}로 설정", + "v2GetDisplayState": "현재 디스플레이 데이터 가져오기", + "v2GetDisplayStateDesc": "현재 디스플레이 테이터 가져오기 => {{outputVar}}", + }, "confirm": "확인", "goback": "뒤로", "botSettings": "봇 설정", @@ -767,4 +889,18 @@ export const languageKorean = { "translateBeforeHTMLFormatting": "HTML 포맷 전 번역", "retranslate": "다시 번역", "loading": "로딩중", + "triggerOn": "활성화 조건", + "noConfig": "설정 없음", + "varName": "변수 이름", + "var": "변수", + "condition": "조건", + "trigger": "트리거", + "outputVar": "출력 변수", + "source": "출처", + "cmd": "명령어", + "sysStart": "시스템 시작", + "sysHistoryEnd": "시스템 히스토리 끝", + "sysPromptEnd": "시스템 프롬프트 끝", + "target": "목표", + "addElse": "그 외에 경우 추가", } \ No newline at end of file diff --git a/src/lib/Setting/Pages/Module/ModuleMenu.svelte b/src/lib/Setting/Pages/Module/ModuleMenu.svelte index dfa58a8c..6aae6b97 100644 --- a/src/lib/Setting/Pages/Module/ModuleMenu.svelte +++ b/src/lib/Setting/Pages/Module/ModuleMenu.svelte @@ -103,7 +103,21 @@ {language.regexScript} + {/if} + })}>V2 +{:else if value?.[0]?.effect?.[0]?.type === 'v2Header'} + {:else} {#key sorted} -
+
{#if value.length === 0} -
No Scripts
+
No Scripts
{/if} - {#each value as triggerscript, i} - { - let triggerscript = value - triggerscript.splice(i, 1) - value = triggerscript - }}/> - {/each} + {#each value as triggerscript, i} + { + let triggerscript = value + triggerscript.splice(i, 1) + value = triggerscript + }}/> + {/each}
+
+ + + { + close() +}} /> + +{#if selectedIndex > 0} + + + +
+
e.stopPropagation()} class:w-7xl={menuMode === 0} class:w-3xl={menuMode !== 0} class:h-full={menuMode!==2}> + {#if menuMode === 0} +
+
+ {#each value as trigger, i} + {#if i === 0} + + {:else} + + {/if} + {/each} +
+
+ +
+ +
+ +
+
+
+ {language.name} + { + const comment = e.currentTarget.value + const prev = value[selectedIndex].comment + for(let i = 1; i < value.length; i++){ + for(let j = 0; j < value[i].effect.length; j++){ + const effect = value[i].effect[j] + if(effect.type === 'v2RunTrigger' && effect.target === prev){ + effect.target = comment + } + } + } + value[selectedIndex].comment = comment + }} /> +
+
+ {language.triggerOn} + + {language.triggerStart} + {language.triggerOutput} + {language.triggerInput} + {language.triggerManual} + {language.editDisplay} + + +
+
+
+ {#each value[selectedIndex].effect as effect, i} + {#if effect.type === 'v2EndIndent'} + + {:else} + + {/if} + {/each} + +
+
+ {:else if menuMode === 1} +
+ {#each effectV2Types.filter((e) => { + + return checkSupported(e) + }) as type} + + {/each} +
+ {:else if menuMode === 2 || menuMode === 3} +
+

+ {language.triggerDesc[editTrigger.type]} +

+ {#if editTrigger.type === 'v2SetVar'} + {language.varName} + + {language.operator} + + = + + + - + × + ÷ + % + + {language.value} + + {language.value} + {language.var} + + + {:else if editTrigger.type === 'v2If'} + + {language.varName} + + + {language.condition} + + = + + {">"} + {"<"} + {"≥"} + {"≤"} + + + {language.value} + + {language.value} + {language.var} + + + + + {:else if editTrigger.type === 'v2RunTrigger'} + {language.trigger} + + {#each value as trigger, i} + {#if i === 0} + + {:else} + {trigger.comment || 'Unnamed Trigger'} + {/if} + {/each} + + {:else if editTrigger.type === 'v2ConsoleLog'} + {language.value} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2ShowAlert'} + {language.value} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2RunLLM'} + {language.prompt} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2CheckSimilarity'} + {language.source} + + {language.value} + {language.var} + + + {language.value} + + {language.value} + {language.var} + + + {language.outputVar} + + {:else if editTrigger.type === 'v2CutChat'} + {language.start} + + {language.value} + {language.var} + + + {language.end} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2Command'} + {language.cmd} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2SystemPrompt'} + {language.location} + + {language.sysStart} + {language.sysHistoryEnd} + {language.sysPromptEnd} + + {language.value} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2Impersonate'} + {language.role} + + user + char + + {language.value} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2ModifyChat'} + {language.index} + + {language.value} + {language.var} + + + {language.value} + + {language.value} + {language.var} + + + {:else if editTrigger.type === 'v2LoopNTimes'} + {language.value} + + {language.value} + {language.var} + + + {:else if editTrigger.type === 'v2GetLastMessage'} + {language.outputVar} + + + {:else if editTrigger.type === 'v2GetMessageAtIndex'} + {language.index} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2GetMessageCount'} + {language.outputVar} + + + {:else if editTrigger.type === 'v2ModifyLorebook'} + {language.target} + + {language.value} + {language.var} + + + {language.value} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2GetLorebook'} + {language.target} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2GetLorebookCount'} + {language.outputVar} + + + {:else if editTrigger.type === 'v2GetLorebookEntry'} + {language.index} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2SetLorebookActivation'} + {language.index} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2GetLorebookIndexViaName'} + {language.name} + + {language.value} + {language.var} + + + {language.outputVar} + + {:else if editTrigger.type === 'v2Random'} + {language.min} + + {language.value} + {language.var} + + + {language.max} + + {language.value} + {language.var} + + + + {language.outputVar} + + {:else if editTrigger.type === 'v2GetCharAt'} + {language.source} + + {language.value} + {language.var} + + + {language.index} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2GetCharCount'} + {language.source} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2ToLowerCase'} + {language.source} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2ToUpperCase'} + {language.source} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2SetCharAt'} + {language.source} + + {language.value} + {language.var} + + + {language.index} + + {language.value} + {language.var} + + + {language.value} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2SplitString'} + {language.source} + + {language.value} + {language.var} + + + {language.delimiter} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2GetCharacterDesc'} + {language.outputVar} + + + {:else if editTrigger.type === 'v2SetCharacterDesc'} + {language.value} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2MakeArrayVar'} + {language.var} + + + {:else if editTrigger.type === 'v2GetArrayVarLength'} + {language.var} + + {language.outputVar} + + + {:else if editTrigger.type === 'v2GetArrayVar'} + {language.var} + + {language.index} + + {language.value} + {language.var} + + + {language.outputVar} + + + {:else if editTrigger.type === 'v2SetArrayVar'} + {language.var} + + {language.index} + + {language.value} + {language.var} + + + {language.value} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2PushArrayVar'} + {language.var} + + {language.value} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2PopArrayVar'} + {language.var} + + {language.outputVar} + + + {:else if editTrigger.type === 'v2ShiftArrayVar'} + {language.var} + + {language.outputVar} + + + {:else if editTrigger.type === 'v2UnshiftArrayVar'} + {language.var} + + {language.value} + + {language.value} + {language.var} + + + + {:else if editTrigger.type === 'v2SpliceArrayVar'} + {language.var} + + {language.start} + + {language.value} + {language.var} + + + {language.value} + + {language.value} + {language.var} + + + {:else if editTrigger.type === 'v2SliceArrayVar'} + {language.var} + + {language.start} + + {language.value} + {language.var} + + + {language.end} + + {language.value} + {language.var} + + + {language.outputVar} + + {:else if editTrigger.type === 'v2GetIndexOfValueInArrayVar'} + {language.var} + + + {language.value} + + {language.value} + {language.var} + + + + + {language.outputVar} + + {:else if editTrigger.type === 'v2RemoveIndexFromArrayVar'} + {language.var} + + + {language.index} + + {language.value} + {language.var} + + + {:else if editTrigger.type === 'v2ConcatString'} + A + + {language.value} + {language.var} + + + + B + + {language.value} + {language.var} + + + + {language.outputVar} + + {:else if editTrigger.type === 'v2GetLastUserMessage'} + {language.outputVar} + + {:else if editTrigger.type === 'v2GetLastCharMessage'} + {language.outputVar} + + {:else if editTrigger.type === 'v2GetFirstMessage'} + {language.outputVar} + + {:else if editTrigger.type === 'v2GetAlertInput'} + {language.value} + + {language.value} + {language.var} + + + + {language.outputVar} + + {:else if editTrigger.type === 'v2GetDisplayState'} + {language.outputVar} + + {:else if editTrigger.type === 'v2SetDisplayState'} + {language.value} + + {language.value} + {language.var} + + + {:else} + {language.noConfig} + {/if} + + + + {#if menuMode === 3} + + {/if} +
+ {/if} +
+
+
+{/if} \ No newline at end of file diff --git a/src/lib/UI/GUI/Portal.svelte b/src/lib/UI/GUI/Portal.svelte new file mode 100644 index 00000000..77710145 --- /dev/null +++ b/src/lib/UI/GUI/Portal.svelte @@ -0,0 +1,24 @@ + \ No newline at end of file diff --git a/src/lib/UI/GUI/PortalConsumer.svelte b/src/lib/UI/GUI/PortalConsumer.svelte new file mode 100644 index 00000000..528f76b9 --- /dev/null +++ b/src/lib/UI/GUI/PortalConsumer.svelte @@ -0,0 +1,7 @@ + + +{#if children} + {@render children()} +{/if} \ No newline at end of file diff --git a/src/ts/characters.ts b/src/ts/characters.ts index fd3c6c52..8f68dc2d 100644 --- a/src/ts/characters.ts +++ b/src/ts/characters.ts @@ -607,7 +607,21 @@ export function createBlankChar():character{ scenario:"", firstMsgIndex: -1, replaceGlobalNote: "", - triggerscript: [], + triggerscript: [{ + comment: "", + type: "manual", + conditions: [], + effect: [{ + type: "v2Header", + code: "", + indent: 0 + }] + }, { + comment: "New Event", + type: 'manual', + conditions: [], + effect: [] + }], additionalText: '' } } diff --git a/src/ts/process/lua.ts b/src/ts/process/lua.ts index c7e1f636..f4b27c32 100644 --- a/src/ts/process/lua.ts +++ b/src/ts/process/lua.ts @@ -684,7 +684,7 @@ export async function runLuaEditTrigger(char:character|groupChat| } } -export async function runLuaButtonTrigger(char:character|groupChat|simpleCharacterArgument, data:string):Promise{ +export async function runLuaButtonTrigger(char:character|groupChat|simpleCharacterArgument, data:string):Promise{ let runResult try { const triggers = char.type === 'group' ? getModuleTriggers() : char.triggerscript.concat(getModuleTriggers()) diff --git a/src/ts/process/scripts.ts b/src/ts/process/scripts.ts index 05d4f5c0..1555e779 100644 --- a/src/ts/process/scripts.ts +++ b/src/ts/process/scripts.ts @@ -1,15 +1,16 @@ import { get } from "svelte/store"; import { CharEmotion, selectedCharID } from "../stores.svelte"; -import { type character, type customscript, type groupChat, type Database, getDatabase } from "../storage/database.svelte"; +import { type character, type customscript, type groupChat, type Database, getDatabase, getCurrentCharacter, getCurrentChat } 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.svelte"; -import { getModuleAssets, getModuleRegexScripts } from "./modules"; +import { getModuleAssets, getModuleRegexScripts, getModuleTriggers } from "./modules"; import { HypaProcesser } from "./memory/hypamemory"; import { runLuaEditTrigger } from "./lua"; import { pluginV2 } from "../plugins/plugins"; +import { runTrigger } from "./triggers"; const dreg = /{{data}}/g const randomness = /\|\|\|/g @@ -104,6 +105,22 @@ export async function processScriptFull(char:character|groupChat|simpleCharacter let emoChanged = false const scripts = (db.presetRegex ?? []).concat(char.customscript).concat(getModuleRegexScripts()) data = await runLuaEditTrigger(char, mode, data) + + if(mode === 'editdisplay'){ + const currentChar = getCurrentCharacter() + if(currentChar.type !== 'group'){ + const perf = performance.now() + const d = await runTrigger(currentChar, 'display', { + chat: getCurrentChat(), + displayMode: true, + displayData: data + }) + + data = d.displayData + console.log('Trigger time', performance.now() - perf) + } + } + if(pluginV2[mode].size > 0){ for(const plugin of pluginV2[mode]){ const res = await plugin(data) diff --git a/src/ts/process/triggers.ts b/src/ts/process/triggers.ts index ac4d24a8..ec295dc7 100644 --- a/src/ts/process/triggers.ts +++ b/src/ts/process/triggers.ts @@ -1,11 +1,11 @@ import { parseChatML, risuChatParser } from "../parser.svelte"; -import { getCurrentCharacter, getCurrentChat, getDatabase, type Chat, type character } from "../storage/database.svelte"; +import { getCurrentCharacter, getCurrentChat, getDatabase, setCurrentCharacter, type Chat, type character } from "../storage/database.svelte"; import { tokenize } from "../tokenizer"; import { getModuleTriggers } from "./modules"; import { get } from "svelte/store"; import { ReloadGUIPointer, selectedCharID } from "../stores.svelte"; import { processMultiCommand } from "./command"; -import { parseKeyValue } from "../util"; +import { parseKeyValue, sleep } from "../util"; import { alertError, alertInput, alertNormal, alertSelect } from "../alert"; import type { OpenAIChat } from "./index.svelte"; import { HypaProcesser } from "./memory/hypamemory"; @@ -17,7 +17,7 @@ import { runLua } from "./lua"; export interface triggerscript{ comment: string; - type: 'start'|'manual'|'output'|'input' + type: 'start'|'manual'|'output'|'input'|'display' conditions: triggerCondition[] effect:triggerEffect[] lowLevelAccess?: boolean @@ -25,7 +25,19 @@ export interface triggerscript{ export type triggerCondition = triggerConditionsVar|triggerConditionsExists|triggerConditionsChatIndex -export type triggerEffect = triggerCode|triggerEffectCutChat|triggerEffectModifyChat|triggerEffectImgGen|triggerEffectRegex|triggerEffectRunLLM|triggerEffectCheckSimilarity|triggerEffectSendAIprompt|triggerEffectShowAlert|triggerEffectSetvar|triggerEffectSystemPrompt|triggerEffectImpersonate|triggerEffectCommand|triggerEffectStop|triggerEffectRunTrigger +export type triggerEffect = triggerEffectV1|triggerCode|triggerEffectV2 +export type triggerEffectV1 = triggerEffectCutChat|triggerEffectModifyChat|triggerEffectImgGen|triggerEffectRegex|triggerEffectRunLLM|triggerEffectCheckSimilarity|triggerEffectSendAIprompt|triggerEffectShowAlert|triggerEffectSetvar|triggerEffectSystemPrompt|triggerEffectImpersonate|triggerEffectCommand|triggerEffectStop|triggerEffectRunTrigger +export type triggerEffectV2 = triggerV2Header|triggerV2IfVar|triggerV2Else|triggerV2EndIndent|triggerV2SetVar|triggerV2Loop|triggerV2BreakLoop| + triggerV2RunTrigger|triggerV2ConsoleLog|triggerV2StopTrigger|triggerV2CutChat|triggerV2ModifyChat|triggerV2SystemPrompt|triggerV2Impersonate| + triggerV2Command|triggerV2SendAIprompt|triggerV2ImgGen|triggerV2CheckSimilarity|triggerV2RunLLM|triggerV2ShowAlert|triggerV2ExtractRegex| + triggerV2GetLastMessage|triggerV2GetMessageAtIndex|triggerV2GetMessageCount|triggerV2GetLastMessage|triggerV2GetMessageAtIndex| + triggerV2GetMessageCount|triggerV2ModifyLorebook|triggerV2GetLorebook|triggerV2GetLorebookCount|triggerV2GetLorebookEntry| + triggerV2SetLorebookActivation|triggerV2GetLorebookIndexViaName|triggerV2LoopNTimes|triggerV2Random|triggerV2GetCharAt| + triggerV2GetCharCount|triggerV2ToLowerCase|triggerV2ToUpperCase|triggerV2SetCharAt|triggerV2SplitString|triggerV2GetCharacterDesc| + triggerV2SetCharacterDesc|triggerV2MakeArrayVar|triggerV2GetArrayVarLength|triggerV2GetArrayVar|triggerV2SetArrayVar| + triggerV2PushArrayVar|triggerV2PopArrayVar|triggerV2ShiftArrayVar|triggerV2UnshiftArrayVar|triggerV2SpliceArrayVar|triggerV2GetFirstMessage| + triggerV2SliceArrayVar|triggerV2GetIndexOfValueInArrayVar|triggerV2RemoveIndexFromArrayVar|triggerV2ConcatString|triggerV2GetLastUserMessage| + triggerV2GetLastCharMessage|triggerV2GetAlertInput|triggerV2GetDisplayState|triggerV2SetDisplayState export type triggerConditionsVar = { type:'var'|'value' @@ -81,7 +93,9 @@ export interface triggerEffectImpersonate{ type: 'impersonate' role: 'user'|'char', value:string -}type triggerMode = 'start'|'manual'|'output'|'input' +} + +type triggerMode = 'start'|'manual'|'output'|'input'|'display' export interface triggerEffectCommand{ type: 'command', @@ -144,15 +158,512 @@ export type additonalSysPrompt = { promptend: string } +export type triggerV2Header = { + type: 'v2Header', + code?: string, + indent: number +} + +export type triggerV2IfVar = { + type: 'v2If', + condition: '='|'!='|'>'|'<'|'>='|'<='|'null'|'true'|'false', + targetType: 'var'|'value', + target: string, + source: string, + indent: number +} + +export type triggerV2Else = { + type: 'v2Else' + indent: number +} + +export type triggerV2EndIndent = { + type: 'v2EndIndent', + endOfLoop?: boolean, + indent: number +} + +export type triggerV2SetVar = { + type: 'v2SetVar', + operator: '='|'+='|'-='|'*='|'/='|'%=', + var: string, + valueType: 'var'|'value', + value: string, + indent: number +} + +export type triggerV2Loop = { + type: 'v2Loop', + indent: number +} + +export type triggerV2LoopNTimes = { + type: 'v2LoopNTimes', + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2BreakLoop = { + type: 'v2BreakLoop', + indent: number +} + +export type triggerV2RunTrigger = { + type: 'v2RunTrigger', + target: string, + indent: number +} + +export type triggerV2ConsoleLog = { + type: 'v2ConsoleLog', + sourceType: 'var'|'value', + source: string, + indent: number +} + +export type triggerV2StopTrigger = { + type: 'v2StopTrigger', + indent: number +} + +export type triggerV2CutChat = { + type: 'v2CutChat', + start: string, + startType: 'var'|'value', + end: string, + endType: 'var'|'value', + indent: number +} + +export type triggerV2ModifyChat = { + type: 'v2ModifyChat', + index: string, + indexType: 'var'|'value', + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2SystemPrompt = { + type: 'v2SystemPrompt', + location: 'start'|'historyend'|'promptend', + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2Impersonate = { + type: 'v2Impersonate', + role: 'user'|'char', + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2Command = { + type: 'v2Command', + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2SendAIprompt = { + type: 'v2SendAIprompt', + indent: number +} + +export type triggerV2ImgGen = { + type: 'v2ImgGen', + value: string, + valueType: 'var'|'value', + negValue: string, + negValueType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2CheckSimilarity = { + type: 'v2CheckSimilarity', + source: string, + sourceType: 'var'|'value', + value: string, + valueType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2RunLLM = { + type: 'v2RunLLM', + value: string, + valueType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2ShowAlert = { + type: 'v2ShowAlert', + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2ExtractRegex = { + type: 'v2ExtractRegex', + value: string, + valueType: 'var'|'value', + regex: string, + regexType: 'var'|'value', + flags: string, + flagsType: 'var'|'value', + result: string, + resultType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2GetLastMessage = { + type: 'v2GetLastMessage', + outputVar: string, + indent: number +} + +export type triggerV2GetMessageAtIndex = { + type: 'v2GetMessageAtIndex', + index: string, + indexType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2GetMessageCount = { + type: 'v2GetMessageCount', + outputVar: string, + indent: number +} + +export type triggerV2ModifyLorebook = { + type: 'v2ModifyLorebook', + target: string, + targetType: 'var'|'value', + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2GetLorebook = { + type: 'v2GetLorebook', + target: string, + targetType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2GetLorebookCount = { + type: 'v2GetLorebookCount', + outputVar: string, + indent: number +} + +export type triggerV2GetLorebookEntry = { + type: 'v2GetLorebookEntry', + index: string, + indexType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2SetLorebookActivation = { + type: 'v2SetLorebookActivation', + index: string, + indexType: 'var'|'value', + value: boolean, + indent: number +} + +export type triggerV2GetLorebookIndexViaName = { + type: 'v2GetLorebookIndexViaName', + name: string, + nameType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2Random = { + type: 'v2Random', + min: string, + minType: 'var'|'value', + max: string, + maxType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2GetCharAt = { + type: 'v2GetCharAt', + source: string, + sourceType: 'var'|'value', + index: string, + indexType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2GetCharCount = { + type: 'v2GetCharCount', + source: string, + sourceType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2ToLowerCase = { + type: 'v2ToLowerCase', + source: string, + sourceType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2ToUpperCase = { + type: 'v2ToUpperCase', + source: string, + sourceType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2SetCharAt = { + type: 'v2SetCharAt', + source: string, + sourceType: 'var'|'value', + index: string, + indexType: 'var'|'value', + value: string, + valueType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2SplitString = { + type: 'v2SplitString', + source: string, + sourceType: 'var'|'value', + delimiter: string, + delimiterType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2GetCharacterDesc = { + type: 'v2GetCharacterDesc', + outputVar: string, + indent: number +} + +export type triggerV2SetCharacterDesc = { + type: 'v2SetCharacterDesc', + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2MakeArrayVar = { + type: 'v2MakeArrayVar', + var: string, + indent: number +} + +export type triggerV2GetArrayVarLength = { + type: 'v2GetArrayVarLength', + var: string, + outputVar: string, + indent: number +} + +export type triggerV2GetArrayVar = { + type: 'v2GetArrayVar', + var: string, + index: string, + indexType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2SetArrayVar = { + type: 'v2SetArrayVar', + var: string, + index: string, + indexType: 'var'|'value', + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2PushArrayVar = { + type: 'v2PushArrayVar', + var: string, + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2PopArrayVar = { + type: 'v2PopArrayVar', + var: string, + outputVar: string, + indent: number +} + +export type triggerV2ShiftArrayVar = { + type: 'v2ShiftArrayVar', + var: string, + outputVar: string, + indent: number +} + +export type triggerV2UnshiftArrayVar = { + type: 'v2UnshiftArrayVar', + var: string, + value: string, + valueType: 'var'|'value', + indent: number +} + +export type triggerV2SpliceArrayVar = { + type: 'v2SpliceArrayVar', + var: string, + start: string, + startType: 'var'|'value', + item: string, + itemType: 'var'|'value', + indent: number +} + +export type triggerV2SliceArrayVar = { + type: 'v2SliceArrayVar', + var: string, + start: string, + startType: 'var'|'value', + end: string, + endType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2GetIndexOfValueInArrayVar = { + type: 'v2GetIndexOfValueInArrayVar', + var: string, + value: string, + valueType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2RemoveIndexFromArrayVar = { + type: 'v2RemoveIndexFromArrayVar', + var: string, + index: string, + indexType: 'var'|'value', + indent: number +} + +export type triggerV2ConcatString = { + type: 'v2ConcatString', + source1: string, + source1Type: 'var'|'value', + source2: string, + source2Type: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2GetLastUserMessage = { + type: 'v2GetLastUserMessage', + outputVar: string, + indent: number +} + +export type triggerV2GetLastCharMessage = { + type: 'v2GetLastCharMessage', + outputVar: string, + indent: number +} + +export type triggerV2GetFirstMessage = { + type: 'v2GetFirstMessage', + outputVar: string, + indent: number +} + +export type triggerV2GetAlertInput = { + type: 'v2GetAlertInput', + display: string, + displayType: 'var'|'value', + outputVar: string, + indent: number +} + +export type triggerV2GetDisplayState = { + type: 'v2GetDisplayState', + outputVar: string, + indent: number +} + +export type triggerV2SetDisplayState = { + type: 'v2SetDisplayState', + value: string, + valueType: 'var'|'value', + indent: number +} + +export const displayAllowList = [ + 'v2GetDisplayState', + 'v2SetDisplayState', + 'v2SetVar', + 'v2If', + 'v2Else', + 'v2EndIndent', + 'v2LoopNTimes', + 'v2BreakLoop', + 'v2ConsoleLog', + 'v2StopTrigger', + 'v2Random', + 'v2ExtractRegex', + 'v2GetCharAt', + 'v2GetCharCount', + 'v2ToLowerCase', + 'v2ToUpperCase', + 'v2SetCharAt', + 'v2SplitString', + 'v2ConcatString', + 'v2MakeArrayVar', + 'v2GetArrayVarLength', + 'v2GetArrayVar', + 'v2SetArrayVar', + 'v2PushArrayVar', + 'v2PopArrayVar', + 'v2ShiftArrayVar', + 'v2UnshiftArrayVar', + 'v2SpliceArrayVar', + 'v2SliceArrayVar', + 'v2GetIndexOfValueInArrayVar', + 'v2RemoveIndexFromArrayVar' +] + export async function runTrigger(char:character,mode:triggerMode, arg:{ chat: Chat, recursiveCount?: number additonalSysPrompt?: additonalSysPrompt stopSending?: boolean manualName?: string + displayMode?: boolean + displayData?: string + tempVars?: Record }){ arg.recursiveCount ??= 0 - char = safeStructuredClone(char) + char = arg.displayMode ? char : safeStructuredClone(char) let varChanged = false let stopSending = arg.stopSending ?? false const CharacterlowLevelAccess = char.lowLevelAccess ?? false @@ -169,11 +680,13 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{ }).concat(getModuleTriggers()) const db = getDatabase() const defaultVariables = parseKeyValue(char.defaultVariables).concat(parseKeyValue(db.templateDefaultVariables)) - let chat = safeStructuredClone(arg.chat ?? char.chats[char.chatPage]) + let chat = arg.displayMode ? arg.chat : safeStructuredClone(arg.chat ?? char.chats[char.chatPage]) if((!triggers) || (triggers.length === 0)){ return null } + let tempVars:Record = arg.tempVars ?? {} + function getVar(key:string){ const state = chat.scriptstate?.['$' + key] if(state === undefined || state === null){ @@ -183,12 +696,19 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{ if(findResult){ return findResult[1] } + if(arg.displayMode){ + return tempVars[key] ?? 'null' + } return 'null' } return state.toString() } function setVar(key:string, value:string){ + if(arg.displayMode){ + tempVars[key] = value + return + } const selectedCharId = get(selectedCharID) const currentCharacter = getCurrentCharacter() const db = getDatabase() @@ -198,12 +718,12 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{ currentChat.scriptstate = chat.scriptstate currentCharacter.chats[currentCharacter.chatPage].scriptstate = chat.scriptstate db.characters[selectedCharId].chats[currentCharacter.chatPage].scriptstate = chat.scriptstate - - } for(const trigger of triggers){ + let tempVars:Record = {} + if(trigger.effect[0]?.type === 'triggercode' || trigger.effect[0]?.type === 'triggerlua'){ // } @@ -296,7 +816,12 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{ if(!pass){ continue } - for(const effect of trigger.effect){ + + for(let index = 0; index < trigger.effect.length; index++){ + const effect = trigger.effect[index] + if(arg.displayMode && !displayAllowList.includes(effect.type)){ + continue + } switch(effect.type){ case'setvar': { const effectValue = risuChatParser(effect.value,{chara:char}) @@ -394,6 +919,10 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{ break } + if(arg.displayMode){ + return + } + const effectValue = risuChatParser(effect.value,{chara:char}) const inputVar = risuChatParser(effect.inputVar,{chara:char}) @@ -520,6 +1049,637 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{ chat = getCurrentChat() break } + + //V2 triggers + case 'v2Header':{ + //Header for V2 triggers to identify the start of a new trigger + break + } + case 'v2SetVar':{ + const effectValue = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + const varKey = risuChatParser(effect.var,{chara:char}) + let originalVar = Number(getVar(varKey)) + if(Number.isNaN(originalVar)){ + originalVar = 0 + } + let resultValue = '' + switch(effect.operator){ + case '=':{ + resultValue = effectValue + break + } + case '+=':{ + resultValue = (originalVar + Number(effectValue)).toString() + break + } + case '-=':{ + resultValue = (originalVar - Number(effectValue)).toString() + break + } + case '*=':{ + resultValue = (originalVar * Number(effectValue)).toString() + break + } + case '/=':{ + resultValue = (originalVar / Number(effectValue)).toString() + break + } + case '%=':{ + resultValue = (originalVar % Number(effectValue)).toString() + break + } + } + setVar(varKey, resultValue) + break + } + case 'v2If':{ + const sourceValue = getVar(risuChatParser(effect.source,{chara:char})) + const targetValue = effect.targetType === 'value' ? risuChatParser(effect.target,{chara:char}) : getVar(risuChatParser(effect.target,{chara:char})) + let pass = false + switch(effect.condition){ + case '=':{ + if(!isNaN(Number(sourceValue)) && !isNaN(Number(targetValue))){ //to check like 1.0 = 1 + pass = Number(sourceValue) === Number(targetValue) + } + else{ + pass = sourceValue === targetValue + } + break + } + case '!=':{ + if(!isNaN(Number(sourceValue)) && !isNaN(Number(targetValue))){ //to check like 1.0 = 1 + pass = Number(sourceValue) !== Number(targetValue) + } + else{ + pass = sourceValue !== targetValue + } + break + } + case '>':{ + pass = Number(sourceValue) > Number(targetValue) + break + } + case '<':{ + pass = Number(sourceValue) < Number(targetValue) + break + } + case '>=':{ + pass = Number(sourceValue) >= Number(targetValue) + break + } + case '<=':{ + pass = Number(sourceValue) <= Number(targetValue) + break + } + } + + + if(!pass){ + let indent = effect.indent + 1 + for(; index < trigger.effect.length; index++){ + const ef = trigger.effect[index] as triggerEffectV2 + if(ef.type === 'v2EndIndent' && indent === ef.indent){ + const nextEf = trigger.effect[index + 1] as triggerEffectV2 + indent-- + if(nextEf?.type === 'v2Else' && nextEf?.indent === indent){ + index++ + } + + break + } + } + } + break + } + case 'v2Else':{ + //since if handles the else if the if is false, we can skip the else + const indent = effect.indent + 1 + for(; index < trigger.effect.length; index++){ + const ef = trigger.effect[index] as triggerEffectV2 + if(ef.type === 'v2EndIndent' && indent === ef.indent){ + break + } + } + break + } + case 'v2EndIndent':{ + if(effect.endOfLoop){ + const indent = effect.indent - 1 + const originalIndex = index + for(; index >= 0; index--){ + const ef = trigger.effect[index] as triggerEffectV2 + if((ef.type === 'v2Loop' || ef.type === 'v2LoopNTimes') && indent === ef.indent){ + + if(ef.type === 'v2LoopNTimes'){ + let value = ef.valueType === 'value' ? risuChatParser(ef.value,{chara:char}) : getVar(risuChatParser(ef.value,{chara:char})) + let valueNum = Number(value) + if(Number.isNaN(valueNum)){ + valueNum = 0 + } + tempVars[index + 'LoopNTimes'] = (tempVars[index + 'LoopNTimes'] ?? 0) + 1 + if(tempVars[index + 'LoopNTimes'] >= valueNum){ + index = originalIndex + } + else{ + break + } + } + + break + } + } + + //this is for preventing lagging + tempVars['loopTimes'] = (tempVars['loopTimes'] ?? 0) + 1 + if(tempVars['loopTimes'] > 100){ + await sleep(1) + tempVars['loopTimes'] = 0 + } + } + break + } + case 'v2Loop': + case 'v2LoopNTimes':{ + //Looping is handled by the v2EndIndent + break + } + case 'v2BreakLoop':{ + for(; index < trigger.effect.length; index++){ + const ef = trigger.effect[index] as triggerEffectV2 + if(ef.type === 'v2EndIndent' && ef.endOfLoop){ + break + } + } + break + } + case 'v2RunTrigger':{ + if(arg.recursiveCount < 10 || trigger.lowLevelAccess){ + arg.recursiveCount++ + const r = await runTrigger(char,'manual',{ + chat, + recursiveCount: arg.recursiveCount, + additonalSysPrompt, + stopSending, + manualName: effect.target + }) + if(r){ + additonalSysPrompt = r.additonalSysPrompt + chat = r.chat + stopSending = r.stopSending + } + } + break + } + case 'v2ConsoleLog':{ + const sourceValue = effect.sourceType === 'value' ? risuChatParser(effect.source,{chara:char}) : getVar(risuChatParser(effect.source,{chara:char})) + console.log(sourceValue) + break + } + case 'v2StopTrigger':{ + index = trigger.effect.length + break + } + case 'v2CutChat':{ + let start = effect.startType === 'value' ? Number(risuChatParser(effect.start,{chara:char})) : Number(getVar(risuChatParser(effect.start,{chara:char}))) + let end = effect.endType === 'value' ? Number(risuChatParser(effect.end,{chara:char})) : Number(getVar(risuChatParser(effect.end,{chara:char}))) + if(isNaN(start)){ + start = 0 + } + if(isNaN(end)){ + end = chat.message.length + } + + chat.message = chat.message.slice(start,end) + break + } + case 'v2ModifyChat':{ + let index = effect.indexType === 'value' ? Number(risuChatParser(effect.index,{chara:char})) : Number(getVar(risuChatParser(effect.index,{chara:char}))) + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + if(chat.message[index]){ + chat.message[index].data = value + } + break + } + case 'v2SystemPrompt':{ + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + additonalSysPrompt[effect.location] += value + "\n\n" + break + } + case 'v2Impersonate':{ + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + if(effect.role === 'user'){ + chat.message.push({role: 'user', data: value}) + } + else if(effect.role === 'char'){ + chat.message.push({role: 'char', data: value}) + } + break + } + case 'v2Command':{ + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + await processMultiCommand(value) + break + } + case 'v2SendAIprompt':{ + if(!trigger.lowLevelAccess){ + break + } + sendAIprompt = true + break + } + case 'v2ImgGen':{ + if(!trigger.lowLevelAccess){ + break + } + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + let negValue = effect.negValueType === 'value' ? risuChatParser(effect.negValue,{chara:char}) : getVar(risuChatParser(effect.negValue,{chara:char})) + let gen = await generateAIImage(value, char, negValue, 'inlay') + if(!gen){ + setVar(effect.outputVar, 'null') + break + } + let imgHTML = new Image() + imgHTML.src = gen + let inlay = await writeInlayImage(imgHTML) + let res = `{{inlay::${inlay}}}` + setVar(effect.outputVar, res) + break + + } + case 'v2CheckSimilarity':{ + if(!trigger.lowLevelAccess){ + break + } + let source = effect.sourceType === 'value' ? risuChatParser(effect.source,{chara:char}) : getVar(risuChatParser(effect.source,{chara:char})) + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + let processer = new HypaProcesser() + await processer.addText(value.split('§')) + let val = await processer.similaritySearch(source) + setVar(effect.outputVar, val.join('§')) + break + } + case 'v2RunLLM':{ + if(!trigger.lowLevelAccess){ + break + } + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + let varName = effect.outputVar + let promptbody = parseChatML(value) + if(!promptbody){ + promptbody = [{role:'user', content:value}] + } + let result = await requestChatData({ + formated: promptbody, + bias: {}, + useStreaming: false, + noMultiGen: true, + }, 'model') + + if(result.type === 'fail' || result.type === 'streaming' || result.type === 'multiline'){ + setVar(varName, 'null') + } + else{ + setVar(varName, result.result) + } + break + } + case 'v2ShowAlert':{ + if(arg.displayMode){ + return + } + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + alertNormal(value) + break + } + case 'v2ExtractRegex':{ + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + let regex = new RegExp(effect.regex, effect.flags) + let regexResult = regex.exec(value) + let result = effect.result.replace(/\$[0-9]+/g, (match) => { + let index = Number(match.slice(1)) + return regexResult[index] + }).replace(/\$&/g, regexResult[0]).replace(/\$\$/g, '$') + + setVar(effect.outputVar, result) + break + } + case 'v2GetLastMessage':{ + setVar(effect.outputVar, chat.message[chat.message.length - 1]?.data ?? 'null') + break + } + case 'v2GetMessageAtIndex':{ + let index = effect.indexType === 'value' ? Number(risuChatParser(effect.index,{chara:char})) : Number(getVar(risuChatParser(effect.index,{chara:char}))) + setVar(effect.outputVar, chat.message[index]?.data ?? 'null') + break + } + case 'v2GetMessageCount':{ + setVar(effect.outputVar, chat.message.length.toString()) + break + } + case 'v2ModifyLorebook':{ + char.globalLore = char.globalLore ?? [] + const target = effect.targetType === 'value' ? risuChatParser(effect.target,{chara:char}) : getVar(risuChatParser(effect.target,{chara:char})) + const value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + + const index = char.globalLore.findIndex((v) => v[0] === target) + if(index !== -1){ + char.globalLore[index][1] = value + } + + const db = getDatabase() + const selectedCharId = get(selectedCharID) + db.characters[selectedCharId].globalLore = char.globalLore + setCurrentCharacter(db.characters[selectedCharId]) + break + } + case 'v2GetLorebook':{ + char.globalLore = char.globalLore ?? [] + const target = effect.targetType === 'value' ? risuChatParser(effect.target,{chara:char}) : getVar(risuChatParser(effect.target,{chara:char})) + const index = char.globalLore.findIndex((v) => v[0] === target) + setVar(effect.outputVar, index === -1 ? 'null' : char.globalLore[index][1]) + break + } + case 'v2GetLorebookCount':{ + char.globalLore = char.globalLore ?? [] + setVar(effect.outputVar, char.globalLore.length.toString()) + break + } + case 'v2GetLorebookEntry':{ + char.globalLore = char.globalLore ?? [] + let index = effect.indexType === 'value' ? Number(risuChatParser(effect.index,{chara:char})) : Number(getVar(risuChatParser(effect.index,{chara:char}))) + if(Number.isNaN(index)){ + index = 0 + } + setVar(effect.outputVar, char.globalLore[index]?.[1] ?? 'null') + break + } + case 'v2SetLorebookActivation':{ + char.globalLore = char.globalLore ?? [] + let index = effect.indexType === 'value' ? Number(risuChatParser(effect.index,{chara:char})) : Number(getVar(risuChatParser(effect.index,{chara:char}))) + let value = effect.value + char.globalLore[index][2] = value + + const selectedCharId = get(selectedCharID) + const db = getDatabase() + db.characters[selectedCharId].globalLore = char.globalLore + setCurrentCharacter(char) + + break + } + case 'v2GetLorebookIndexViaName':{ + char.globalLore = char.globalLore ?? [] + let name = effect.nameType === 'value' ? risuChatParser(effect.name,{chara:char}) : getVar(risuChatParser(effect.name,{chara:char})) + let index = char.globalLore.findIndex((v) => v[0] === name) + setVar(effect.outputVar, index.toString()) + break + } + case 'v2Random':{ + let min = effect.minType === 'value' ? Number(risuChatParser(effect.min,{chara:char})) : Number(getVar(risuChatParser(effect.min,{chara:char}))) + let max = effect.maxType === 'value' ? Number(risuChatParser(effect.max,{chara:char})) : Number(getVar(risuChatParser(effect.max,{chara:char}))) + + let output = Math.floor(Math.random() * (max - min + 1) + min) + setVar(effect.outputVar, output.toString()) + break + } + case 'v2GetCharAt':{ + let source = effect.sourceType === 'value' ? risuChatParser(effect.source,{chara:char}) : getVar(risuChatParser(effect.source,{chara:char})) + let index = effect.indexType === 'value' ? Number(risuChatParser(effect.index,{chara:char})) : Number(getVar(risuChatParser(effect.index,{chara:char}))) + setVar(effect.outputVar, source[index] ?? 'null') + break + } + case 'v2GetCharCount':{ + let source = effect.sourceType === 'value' ? risuChatParser(effect.source,{chara:char}) : getVar(risuChatParser(effect.source,{chara:char})) + setVar(effect.outputVar, source.length.toString()) + break + } + case 'v2GetCharCount':{ + let source = effect.sourceType === 'value' ? risuChatParser(effect.source,{chara:char}) : getVar(risuChatParser(effect.source,{chara:char})) + setVar(effect.outputVar, source.length.toString()) + break + } + case 'v2ToLowerCase':{ + let source = effect.sourceType === 'value' ? risuChatParser(effect.source,{chara:char}) : getVar(risuChatParser(effect.source,{chara:char})) + setVar(effect.outputVar, source.toLowerCase()) + break + } + case 'v2ToUpperCase':{ + let source = effect.sourceType === 'value' ? risuChatParser(effect.source,{chara:char}) : getVar(risuChatParser(effect.source,{chara:char})) + setVar(effect.outputVar, source.toUpperCase()) + break + } + case 'v2SetCharAt':{ + let source = effect.sourceType === 'value' ? risuChatParser(effect.source,{chara:char}) : getVar(risuChatParser(effect.source,{chara:char})) + let index = effect.indexType === 'value' ? Number(risuChatParser(effect.index,{chara:char})) : Number(getVar(risuChatParser(effect.index,{chara:char}))) + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + const source2 = source.split('') + source2[index] = value + setVar(effect.outputVar, source2.join('')) + break + } + case 'v2SplitString':{ + let source = effect.sourceType === 'value' ? risuChatParser(effect.source,{chara:char}) : getVar(risuChatParser(effect.source,{chara:char})) + let delimiter = effect.delimiterType === 'value' ? risuChatParser(effect.delimiter,{chara:char}) : getVar(risuChatParser(effect.delimiter,{chara:char})) + setVar(effect.outputVar, JSON.stringify(source.split(delimiter))) + break + } + case 'v2GetCharacterDesc':{ + setVar(effect.outputVar, char.desc) + break + } + case 'v2SetCharacterDesc':{ + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + char.desc = value + const selectedCharId = get(selectedCharID) + const db = getDatabase(); + (db.characters[selectedCharId] as character).desc = value + setCurrentCharacter(char) + break + } + case 'v2MakeArrayVar':{ + if(effect.var.startsWith('[') && effect.var.endsWith(']')){ + return + } + + setVar(effect.var, '[]') + break + } + case 'v2GetArrayVarLength':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + setVar(effect.outputVar, arr.length.toString()) + } catch (error) { + setVar(effect.outputVar, '0') + } + break + } + case 'v2GetArrayVar':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + let index = effect.indexType === 'value' ? Number(risuChatParser(effect.index,{chara:char})) : Number(getVar(risuChatParser(effect.index,{chara:char}))) + setVar(effect.outputVar, arr[index] ?? 'null') + } catch (error) { + setVar(effect.outputVar, 'null') + } + break + } + case 'v2PushArrayVar':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + arr.push(value) + setVar(effect.var, JSON.stringify(arr)) + } catch (error) { + setVar(effect.var, '[]') + } + break + } + case 'v2PopArrayVar':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + arr.pop() + setVar(effect.var, JSON.stringify(arr)) + } catch (error) { + setVar(effect.var, '[]') + } + break + } + case 'v2ShiftArrayVar':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + arr.shift() + setVar(effect.var, JSON.stringify(arr)) + } catch (error) { + setVar(effect.var, '[]') + } + break + } + case 'v2UnshiftArrayVar':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + arr.unshift(value) + setVar(effect.var, JSON.stringify(arr)) + } catch (error) { + setVar(effect.var, '[]') + } + break + } + case 'v2SpliceArrayVar':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + let start = effect.startType === 'value' ? Number(risuChatParser(effect.start,{chara:char})) : Number(getVar(risuChatParser(effect.start,{chara:char}))) + let value = effect.itemType === 'value' ? risuChatParser(effect.item,{chara:char}) : getVar(risuChatParser(effect.item,{chara:char})) + arr.splice(start, 0, value) + setVar(effect.var, JSON.stringify(arr)) + } catch (error) { + setVar(effect.var, '[]') + } + break + } + case 'v2SliceArrayVar':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + let start = effect.startType === 'value' ? Number(risuChatParser(effect.start,{chara:char})) : Number(getVar(risuChatParser(effect.start,{chara:char}))) + let end = effect.endType === 'value' ? Number(risuChatParser(effect.end,{chara:char})) : Number(getVar(risuChatParser(effect.end,{chara:char}))) + + setVar(effect.outputVar, JSON.stringify(arr.slice(start,end))) + } catch (error) { + setVar(effect.outputVar, '[]') + } + break + } + case 'v2GetIndexOfValueInArrayVar':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + let value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + setVar(effect.outputVar, arr.indexOf(value).toString()) + } catch (error) { + setVar(effect.outputVar, '-1') + } + break + } + case 'v2RemoveIndexFromArrayVar':{ + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + let index = effect.indexType === 'value' ? Number(risuChatParser(effect.index,{chara:char})) : Number(getVar(risuChatParser(effect.index,{chara:char}))) + arr.splice(index, 1) + setVar(effect.var, JSON.stringify(arr)) + } catch (error) { + setVar(effect.var, '[]') + } + break + } + case 'v2ConcatString':{ + let source1 = effect.source1Type === 'value' ? risuChatParser(effect.source1,{chara:char}) : getVar(risuChatParser(effect.source1,{chara:char})) + let source2 = effect.source2Type === 'value' ? risuChatParser(effect.source2,{chara:char}) : getVar(risuChatParser(effect.source2,{chara:char})) + setVar(effect.outputVar, source1 + source2) + break + } + case 'v2GetLastUserMessage':{ + let lastUserMessage = chat.message.slice().reverse().find((v) => v.role === 'user') + setVar(effect.outputVar, lastUserMessage?.data ?? 'null') + break + } + case 'v2GetLastCharMessage':{ + let lastCharMessage = chat.message.slice().reverse().find((v) => v.role === 'char') + setVar(effect.outputVar, lastCharMessage?.data ?? 'null') + break + } + case 'v2GetFirstMessage':{ + setVar(effect.outputVar, chat.fmIndex === -1 ? char.firstMessage : char.alternateGreetings[chat.fmIndex]) + break + } + case 'v2GetAlertInput':{ + if(arg.displayMode){ + return + } + let value = await alertInput( + effect.displayType === 'value' ? risuChatParser(effect.display,{chara:char}) : getVar(risuChatParser(effect.display,{chara:char})) + ) + setVar(effect.outputVar, value) + break + } + case 'v2SetArrayVar':{ + const value = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + const index = effect.indexType === 'value' ? Number(risuChatParser(effect.index,{chara:char})) : Number(getVar(risuChatParser(effect.index,{chara:char}))) + if(Number.isNaN(index)){ + break + } + try { + let varValue = getVar(effect.var) + let arr = JSON.parse(varValue) + arr[index] = value + setVar(effect.var, JSON.stringify(arr)) + } catch (error) { + + } + break + } + case 'v2GetDisplayState':{ + if(!arg.displayMode){ + return + } + + setVar(effect.outputVar, arg.displayData ?? 'null') + break + } + case 'v2SetDisplayState':{ + if(!arg.displayMode){ + return + } + arg.displayData = effect.valueType === 'value' ? risuChatParser(effect.value,{chara:char}) : getVar(risuChatParser(effect.value,{chara:char})) + break + } } } } @@ -540,6 +1700,6 @@ export async function runTrigger(char:character,mode:triggerMode, arg:{ ReloadGUIPointer.set(get(ReloadGUIPointer) + 1) } - return {additonalSysPrompt, chat, tokens:caculatedTokens, stopSending, sendAIprompt} + return {additonalSysPrompt, chat, tokens:caculatedTokens, stopSending, sendAIprompt, displayData: arg.displayData, tempVars: arg.tempVars} } \ No newline at end of file diff --git a/src/ts/util.ts b/src/ts/util.ts index 2f8d5fe8..865fdfde 100644 --- a/src/ts/util.ts +++ b/src/ts/util.ts @@ -1013,5 +1013,6 @@ export function parseKeyValue(template:string){ export const sortableOptions = { delay: 300, // time in milliseconds to define when the sorting should start - delayOnTouchOnly: true + delayOnTouchOnly: true, + filter: '.no-sort', } as const \ No newline at end of file diff --git a/tailwind.config.js b/tailwind.config.js index d623ea9b..992f28e0 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -46,6 +46,8 @@ export default { width: { '2xl': '48rem', '3xl': '72rem', + '4xl': 'var(--container-4xl);', + '7xl': '1280px', '110': '28rem', '124': '32rem', '138': '36rem',