Merge branch 'main' of https://github.com/kwaroran/RisuAI
This commit is contained in:
@@ -170,7 +170,7 @@ export const languageEnglish = {
|
||||
summarizationPrompt: "The prompt that is used for summarization. if it is blank, it will use the default prompt. you can also use ChatML formating with {{slot}} for the chat data.",
|
||||
translatorPrompt: "The prompt that is used for translation. if it is blank, it will use the default prompt. you can also use ChatML formating with {{slot}} for the dest language, {{solt::content}} for the content, and {{slot::tnote}} for the translator note.",
|
||||
translateBeforeHTMLFormatting: "If enabled, it will translate the text before Regex scripts and HTML formatting. this could make the token lesser but could break the formatting.",
|
||||
autoTranslateCachedOnly: "If enabled, it will automatically translate only the text that the user has translated previously.",
|
||||
autoTranslateCachedOnly: "If enabled with Auto Translation option on, it will automatically translate only the text that the user has translated previously.",
|
||||
presetChain: "If it is not blank, the preset will be changed and applied randomly every time when user sends a message in the preset list in this input. preset list should be seperated by comma, for example, `preset1,preset2`.",
|
||||
legacyMediaFindings: "If enabled, it will use the old method to find media assets, without using the additional search algorithm.",
|
||||
comfyWorkflow: "Put the API workflow of comfy UI. you can get your API workflow in comfy UI by pressing the 'Workflow > Export (API)' button. you must also put {{risu_prompt}} in you workflow text. the {{risu_prompt}} will be replaced with the prompt provided by the Risu.",
|
||||
|
||||
@@ -130,6 +130,9 @@ export const languageChineseTraditional = {
|
||||
"translatorPrompt": "用於翻譯的提示詞。留空將使用默認提示。您還可以使用帶有 {{slot}} 的 ChatML 格式表示目標語言:用 {{slot::content}} 表示內容,用 {{slot::tnote}} 表示翻譯註釋。",
|
||||
"translateBeforeHTMLFormatting": "啟用後,將在正規表達式和 HTML 格式化之前翻譯文本。這可能減少 Token 數,但可能破壞格式。",
|
||||
"autoTranslateCachedOnly": "啟用後,僅會自動翻譯使用者之前已翻譯的內容。",
|
||||
"presetChain": "若欄位不為空,則每次使用者發送訊息時,系統會從此輸入中的預設列表中隨機變更並應用預設設定。預設列表應以逗號分隔,例如 `preset1,preset2`。",
|
||||
"legacyMediaFindings": "啟用後,將使用舊版方法尋找媒體資源,而不使用額外的搜尋演算法。",
|
||||
"comfyWorkflow": "請輸入 Comfy UI 的 API 工作流程。您可以在 Comfy UI 中點選「Workflow > Export (API)」按鈕以取得您的 API 工作流程。此外,您必須在工作流程文本中加入 {{risu_prompt}},該佔位符將被 Risu 提供的提示詞替換。",
|
||||
"APIPool": "啟用後,系統將連接到 RisuAI 的 API 資源池。已啟用的使用者可共享免費、速率受限模型的 API 金鑰,從而利用其他使用者未充分使用的金鑰,增加對速率受限模型的請求次數。"
|
||||
},
|
||||
"setup": {
|
||||
@@ -375,7 +378,7 @@ export const languageChineseTraditional = {
|
||||
"textScreenBorder": "文本視窗邊框",
|
||||
"ttsReadOnlyQuoted": "僅朗讀引號內容",
|
||||
"ttsStop": "停止語音合成",
|
||||
"askRemoval": "請求刪除",
|
||||
"askRemoval": "刪除訊息前進行確認",
|
||||
"replaceGlobalNote": "替換全域備註",
|
||||
"charLoreBook": "角色 Lorebook",
|
||||
"globalLoreBook": "全域 Lorebook",
|
||||
@@ -429,7 +432,7 @@ export const languageChineseTraditional = {
|
||||
"toggleConfirmRecommendedPreset": "模型變更時詢問是否使用建議設定",
|
||||
"recommendedPreset": "使用建議設定",
|
||||
"persona": "使用者資訊",
|
||||
"icon": "頭像",
|
||||
"icon": "圖示",
|
||||
"account": "帳號",
|
||||
"remove": "刪除",
|
||||
"creationSuccess": "創建成功",
|
||||
@@ -447,7 +450,8 @@ export const languageChineseTraditional = {
|
||||
"changeFolderName": "輸入新資料夾名稱(留空以取消)",
|
||||
"cancel": "取消",
|
||||
"renameFolder": "重新命名資料夾",
|
||||
"changeFolderColor": "更改資料夾顏色",
|
||||
"changeFolderColor": "變更資料夾顏色",
|
||||
"changeFolderImage": "變更資料夾圖片",
|
||||
"fullWordMatching": "完整單詞匹配",
|
||||
"botSettingAtStart": "啟動時顯示機器人選單",
|
||||
"triggerStart": "聊天發送時觸發",
|
||||
@@ -779,5 +783,26 @@ export const languageChineseTraditional = {
|
||||
"customFlags": "自定義修飾詞(Flags)",
|
||||
"enableCustomFlags": "啟用自定義修飾詞(Flags)",
|
||||
"googleCloudTokenization": "Google Cloud Tokenization",
|
||||
"presetChain": "預設鏈",
|
||||
"legacyMediaFindings": "舊版媒體發現",
|
||||
"staticsDisclaimer": "統計資料基於 2024 年 7 月之後的數據,可能不完全準確。",
|
||||
"subtitles": "字幕",
|
||||
"subtitlesWarning1": "您必須使用具有音訊/視訊輸入的模型才能使用此功能。",
|
||||
"subtitlesWarning2": "您必須使用具有即時串流傳輸功能的模型才能使用此功能。",
|
||||
"reset": "重置",
|
||||
"assetMaxDifference": "資源最大差異",
|
||||
"sourceLanguage": "原文語言",
|
||||
"destinationLanguage": "目標語言",
|
||||
"noWebGPU": "由於目前的瀏覽器或作業系統不支援 WebGPU,效能將大幅下降。",
|
||||
"menuSideBar": "選單側邊欄",
|
||||
"home": "首頁",
|
||||
"showSavingIcon": "顯示儲存圖示",
|
||||
"pluginVersionWarn": "這是 {{plugin_version}} 版本的外掛程式,與當前 RisuAI 版本不相容。請更新外掛至 {{required_version}} 版本。",
|
||||
"imageTranslation": "圖像翻譯",
|
||||
"banCharacterset": "自動重新生成字符集",
|
||||
"checkCorruption": "檢查損壞",
|
||||
"showPromptComparison": "顯示提示比較",
|
||||
"hypaV3Desc": "HypaMemory V3 是一個長期記憶系統,使用摘要資料和向量搜尋。",
|
||||
"inlayErrorResponse": "嵌入錯誤回應",
|
||||
"APIPool": "API 工具"
|
||||
}
|
||||
|
||||
@@ -143,7 +143,9 @@
|
||||
if(DBState.db.autoTranslateCachedOnly && DBState.db.translatorType === 'llm'){
|
||||
const cache = DBState.db.translateBeforeHTMLFormatting
|
||||
? await getLLMCache(data)
|
||||
: await getLLMCache(await ParseMarkdown(data, charArg, 'pretranslate', chatID, getCbsCondition()))
|
||||
: !DBState.db.legacyTranslation
|
||||
? await getLLMCache(await ParseMarkdown(data, charArg, 'pretranslate', chatID, getCbsCondition()))
|
||||
: await getLLMCache(await ParseMarkdown(data, charArg, mode, chatID, getCbsCondition()))
|
||||
|
||||
translateText = cache !== null
|
||||
}
|
||||
|
||||
@@ -871,19 +871,27 @@
|
||||
<div class="sticky top-0 z-50 p-2 sm:p-3 bg-zinc-800">
|
||||
<div class="flex items-center gap-2">
|
||||
<div class="relative flex flex-1 items-center">
|
||||
<input
|
||||
class="w-full px-2 sm:px-4 py-2 sm:py-3 rounded border border-zinc-700 focus:outline-none focus:ring-2 focus:ring-zinc-500 text-zinc-200 bg-zinc-900"
|
||||
placeholder="Enter #N, ID, or search query"
|
||||
bind:this={searchUIState.ref}
|
||||
bind:value={searchUIState.query}
|
||||
oninput={() => {
|
||||
if (searchUIState) {
|
||||
searchUIState.currentIndex = -1;
|
||||
searchUIState.results = [];
|
||||
}
|
||||
<form
|
||||
class="w-full"
|
||||
onsubmit={(e) => {
|
||||
e.preventDefault();
|
||||
onSearch({ key: "Enter" } as KeyboardEvent);
|
||||
}}
|
||||
onkeydown={(e) => onSearch(e)}
|
||||
/>
|
||||
>
|
||||
<input
|
||||
class="w-full px-2 sm:px-4 py-2 sm:py-3 rounded border border-zinc-700 focus:outline-none focus:ring-2 focus:ring-zinc-500 text-zinc-200 bg-zinc-900"
|
||||
placeholder="Enter #N, ID, or search query"
|
||||
bind:this={searchUIState.ref}
|
||||
bind:value={searchUIState.query}
|
||||
oninput={() => {
|
||||
if (searchUIState) {
|
||||
searchUIState.currentIndex = -1;
|
||||
searchUIState.results = [];
|
||||
}
|
||||
}}
|
||||
onkeydown={(e) => onSearch(e)}
|
||||
/>
|
||||
</form>
|
||||
|
||||
{#if searchUIState.results.length > 0}
|
||||
<span
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
import CheckInput from "src/lib/UI/GUI/CheckInput.svelte";
|
||||
import TextAreaInput from "src/lib/UI/GUI/TextAreaInput.svelte";
|
||||
import { untrack } from "svelte";
|
||||
import { tokenizePreset } from "src/ts/process/prompt";
|
||||
import { getCharToken } from "src/ts/tokenizer";
|
||||
import { selectedCharID } from "src/ts/stores.svelte";
|
||||
|
||||
$effect.pre(() => {
|
||||
DBState.db.NAIImgConfig ??= {
|
||||
@@ -53,7 +56,7 @@
|
||||
DBState.db.hypaV3Settings.similarMemoryRatio = 1 - newValue;
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
$effect(() => {
|
||||
const newValue = Math.min(DBState.db.hypaV3Settings.similarMemoryRatio, 1);
|
||||
@@ -66,6 +69,24 @@
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
async function getMaxMemoryRatio(): Promise<number> {
|
||||
const promptTemplateToken = await tokenizePreset(DBState.db.promptTemplate);
|
||||
const char = DBState.db.characters[$selectedCharID];
|
||||
const charToken = await getCharToken(char);
|
||||
const maxLoreToken = char.loreSettings?.tokenBudget ?? DBState.db.loreBookToken;
|
||||
const maxResponse = DBState.db.maxResponse;
|
||||
const requiredToken = promptTemplateToken + charToken.persistant + Math.min(charToken.dynamic, maxLoreToken) + maxResponse * 3;
|
||||
const maxContext = DBState.db.maxContext;
|
||||
|
||||
if (maxContext === 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const maxMemoryRatio = Math.max((maxContext - requiredToken) / maxContext, 0);
|
||||
|
||||
return parseFloat(maxMemoryRatio.toFixed(2));
|
||||
}
|
||||
// End HypaV3
|
||||
</script>
|
||||
<h2 class="mb-2 text-2xl font-bold mt-2">{language.otherBots}</h2>
|
||||
@@ -500,7 +521,13 @@
|
||||
<span class="text-textcolor">{language.summarizationPrompt} <Help key="summarizationPrompt"/></span>
|
||||
<div class="mb-2">
|
||||
<TextAreaInput size="sm" placeholder="Leave it blank to use default" bind:value={DBState.db.supaMemoryPrompt} />
|
||||
</div>
|
||||
</div>
|
||||
<span class="text-textcolor">Max Memory Tokens Ratio (Estimated)</span>
|
||||
{#await getMaxMemoryRatio() then maxMemoryRatio}
|
||||
<NumberInput marginBottom disabled size="sm" value={maxMemoryRatio} />
|
||||
{:catch error}
|
||||
<span class="text-textcolor">{error}</span>
|
||||
{/await}
|
||||
<span class="text-textcolor">Memory Tokens Ratio</span>
|
||||
<SliderInput marginBottom min={0} max={1} step={0.01} fixed={2} bind:value={DBState.db.hypaV3Settings.memoryTokensRatio} />
|
||||
<span class="text-textcolor">Extra Summarization Ratio</span>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { runTrigger } from "./process/triggers";
|
||||
import { sleep } from "./util";
|
||||
import { getCurrentCharacter, getCurrentChat, setCurrentChat } from "./storage/database.svelte";
|
||||
import { runLuaButtonTrigger } from "./process/lua";
|
||||
|
||||
|
||||
function nodeObserve(node:HTMLElement){
|
||||
@@ -35,6 +36,15 @@ function nodeObserve(node:HTMLElement){
|
||||
}
|
||||
|
||||
if(btnEvent){
|
||||
node.addEventListener('click', async () => {
|
||||
const currentChar = getCurrentCharacter()
|
||||
if(currentChar.type === 'group'){
|
||||
return;
|
||||
}
|
||||
await runLuaButtonTrigger(currentChar, btnEvent);
|
||||
}, {
|
||||
passive: true,
|
||||
});
|
||||
node.setAttribute('risu-observer', 'true');
|
||||
return
|
||||
}
|
||||
|
||||
@@ -457,6 +457,13 @@ export async function runLua(code:string, arg:{
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'onButtonClick':{
|
||||
const func = luaEngine.global.get('onButtonClick')
|
||||
if(func){
|
||||
res = await func(accessKey, data)
|
||||
}
|
||||
break
|
||||
}
|
||||
case 'editRequest':
|
||||
case 'editDisplay':
|
||||
case 'editInput':
|
||||
@@ -675,4 +682,25 @@ export async function runLuaEditTrigger<T extends any>(char:character|groupChat|
|
||||
} catch (error) {
|
||||
return content
|
||||
}
|
||||
}
|
||||
|
||||
export async function runLuaButtonTrigger(char:character|groupChat|simpleCharacterArgument, data:string):Promise<T>{
|
||||
let runResult
|
||||
try {
|
||||
const triggers = char.type === 'group' ? getModuleTriggers() : char.triggerscript.concat(getModuleTriggers())
|
||||
const lowLevelAccess = char.type !== 'simple' ? char.lowLevelAccess ?? false : false
|
||||
for(let trigger of triggers){
|
||||
if(trigger?.effect?.[0]?.type === 'triggerlua'){
|
||||
runResult = await runLua(trigger.effect[0].code, {
|
||||
char: char,
|
||||
lowLevelAccess: lowLevelAccess,
|
||||
mode: 'onButtonClick',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
throw(error)
|
||||
}
|
||||
return runResult
|
||||
}
|
||||
Reference in New Issue
Block a user