feat: add option to show Hypa modal button in chat menu (#823)

# PR Checklist
- [ ] Have you checked if it works normally in all models? *Ignore this
if it doesn't use models.*
- [ ] Have you checked if it works normally in all web, local, and node
hosted versions? If it doesn't, have you blocked it in those versions?
- [ ] Have you added type definitions?

# Preview

![preview1](https://github.com/user-attachments/assets/daaafcb2-a533-4bf1-b38f-e9b9b54f6769)


![preview2](https://github.com/user-attachments/assets/a632a66d-fc74-4d92-909a-88d450cd41fb)

# Description
This PR introduces following:
- feat: add accessibility setting to control visibility of Hypa V2/V3
modal button in chat menu
- feat: add summarization condition tip to HypaV3 modal
This commit is contained in:
kwaroran
2025-04-28 15:43:06 +09:00
committed by GitHub
12 changed files with 66 additions and 15 deletions

View File

@@ -816,6 +816,7 @@ export const languageChinese = {
"nextSummarizationLabel": "HypaV3 将总结 [{0}]",
"nextSummarizationNoMessagesFoundLabel": "警告:未找到消息",
"nextSummarizationLoadingError": "加载下一个总结目标时出错:{0}",
"summarizationConditionLabel": "提示当输入标记超过最大上下文大小时HypaV3 将开始进行摘要处理。",
"emptySelectedFirstMessageLabel": "警告:所选的第一条消息为空"
},
}

View File

@@ -480,6 +480,7 @@ export const languageGerman = {
"nextSummarizationLabel": "HypaV3 wird [{0}] zusammenfassen",
"nextSummarizationNoMessagesFoundLabel": "WARNUNG: Keine Nachrichten gefunden",
"nextSummarizationLoadingError": "Fehler beim Laden des nächsten Zusammenfassungsziels: {0}",
"summarizationConditionLabel": "Hinweis: HypaV3 beginnt mit der Zusammenfassung, wenn die Eingabe-Tokens die maximale Kontextgröße überschreiten.",
"emptySelectedFirstMessageLabel": "WARNUNG: Ausgewählte erste Nachricht ist leer"
},
}

View File

@@ -1052,6 +1052,7 @@ export const languageEnglish = {
nextSummarizationLabel: "HypaV3 will summarize [{0}]",
nextSummarizationNoMessagesFoundLabel: "WARN: No messages found",
nextSummarizationLoadingError: "Error loading next summarization target: {0}",
summarizationConditionLabel: "Tip: HypaV3 begins summarization when input tokens exceed the maximum context size.",
emptySelectedFirstMessageLabel: "WARN: Selected first message is empty",
},
bulkEnabling: "Lorebook Bulk Enabling",
@@ -1116,5 +1117,8 @@ export const languageEnglish = {
doNotChangeFallbackModels: "Do Not Change Fallback Models on Preset Change",
customModels: "Custom Models",
igpPrompt: "IGP Prompt",
useTokenizerCaching: "Tokenizer Caching"
useTokenizerCaching: "Tokenizer Caching",
hypaMemoryV2Modal: "Hypa V2 Modal",
hypaMemoryV3Modal: "Hypa V3 Modal",
showMenuHypaMemoryModal: "Show Menu Hypa Modal",
}

View File

@@ -725,6 +725,7 @@ export const languageSpanish = {
"nextSummarizationLabel": "HypaV3 resumirá [{0}]",
"nextSummarizationNoMessagesFoundLabel": "ADVERTENCIA: No se encontraron mensajes",
"nextSummarizationLoadingError": "Error al cargar el siguiente objetivo de resumen: {0}",
"summarizationConditionLabel": "Consejo: HypaV3 comienza a resumir cuando los tokens de entrada superan el tamaño máximo de contexto.",
"emptySelectedFirstMessageLabel": "ADVERTENCIA: El primer mensaje seleccionado está vacío"
},
}

View File

@@ -971,7 +971,8 @@ export const languageKorean = {
"nextSummarizationLabel": "HypaV3가 [{0}]를 요약할 예정입니다",
"nextSummarizationNoMessagesFoundLabel": "경고: 메시지를 찾을 수 없습니다",
"nextSummarizationLoadingError": "다음 요약 대상을 불러오는 동안 오류 발생: {0}",
"emptySelectedFirstMessageLabel": "경고: 선택된 첫 메시지가 비어있습니다"
"summarizationConditionLabel": "팁: HypaV3는 입력 토큰이 최대 컨텍스트 크기를 넘으면 요약을 시작합니다.",
"emptySelectedFirstMessageLabel": "경고: 선택된 첫 메시지가 비어있습니다",
},
"bulkEnabling": "한번에 로어북 활성화 버튼",
"showTranslationLoading": "번역 로딩 보이기",
@@ -984,4 +985,7 @@ export const languageKorean = {
"childLoreDesc": "이것은 캐릭터 로어의 복사본이며, 삭제하거나 원본 로어에서 직접 비활성화하기 전에는 '언제나 활성화' 상태로 유지됩니다.",
"cachePoint": "캐시 포인트",
"all": "모두",
"hypaMemoryV2Modal": "하이파 V2 모달",
"hypaMemoryV3Modal": "하이파 V3 모달",
"showMenuHypaMemoryModal": "메뉴에서 하이파 모달 보이기",
}

View File

@@ -454,6 +454,7 @@ export const LanguageVietnamese = {
"nextSummarizationLabel": "HypaV3 sẽ tóm tắt [{0}]",
"nextSummarizationNoMessagesFoundLabel": "CẢNH BÁO: Không tìm thấy tin nhắn",
"nextSummarizationLoadingError": "Lỗi khi tải mục tiêu tóm tắt tiếp theo: {0}",
"summarizationConditionLabel": "Mẹo: HypaV3 bắt đầu tóm tắt khi số lượng token đầu vào vượt quá kích thước ngữ cảnh tối đa.",
"emptySelectedFirstMessageLabel": "CẢNH BÁO: Tin nhắn đầu tiên được chọn trống"
},
}

View File

@@ -849,6 +849,7 @@ export const languageChineseTraditional = {
"nextSummarizationLabel": "HypaV3 將摘要 [{0}]",
"nextSummarizationNoMessagesFoundLabel": "警告:找不到訊息",
"nextSummarizationLoadingError": "載入下一個摘要目標時出錯:{0}",
"summarizationConditionLabel": "提示當輸入標記超過最大上下文大小時HypaV3 將開始進行摘要處理。",
"emptySelectedFirstMessageLabel": "警告:選定的第一條訊息為空"
},
}

View File

@@ -2,7 +2,7 @@
import Suggestion from './Suggestion.svelte';
import AdvancedChatEditor from './AdvancedChatEditor.svelte';
import { CameraIcon, DatabaseIcon, DicesIcon, GlobeIcon, ImagePlusIcon, LanguagesIcon, Laugh, MenuIcon, MicOffIcon, PackageIcon, Plus, RefreshCcwIcon, ReplyIcon, Send, StepForwardIcon, XIcon } from "lucide-svelte";
import { CameraIcon, DatabaseIcon, DicesIcon, GlobeIcon, ImagePlusIcon, LanguagesIcon, Laugh, MenuIcon, MicOffIcon, PackageIcon, Plus, RefreshCcwIcon, ReplyIcon, Send, StepForwardIcon, XIcon, BrainIcon } from "lucide-svelte";
import { selectedCharID, PlaygroundStore, createSimpleCharacter } from "../../ts/stores.svelte";
import Chat from "./Chat.svelte";
import { type Message, type character, type groupChat } from "../../ts/storage/database.svelte";
@@ -12,7 +12,7 @@
import { findCharacterbyId, getUserIconProtrait, messageForm, sleep } from "../../ts/util";
import { language } from "../../lang";
import { isExpTranslator, translate } from "../../ts/translator/translator";
import { alertError, alertNormal, alertWait } from "../../ts/alert";
import { alertError, alertNormal, alertWait, showHypaV2Alert, showHypaV3Alert } from "../../ts/alert";
import sendSound from '../../etc/send.mp3'
import { processScript } from "src/ts/process/scripts";
import CreatorQuote from "./CreatorQuote.svelte";
@@ -803,6 +803,30 @@
<span class="ml-2">{language.chatList}</span>
</div>
{/if}
{#if DBState.db.showMenuHypaMemoryModal}
{#if DBState.db.supaModelType !== 'none' && (DBState.db.hypav2 || DBState.db.hypaV3)}
<div class="flex items-center cursor-pointer hover:text-green-500 transition-colors" onclick={() => {
if (DBState.db.hypav2) {
DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].hypaV2Data ??= {
lastMainChunkID: 0,
mainChunks: [],
chunks: [],
}
showHypaV2Alert();
} else if (DBState.db.hypaV3) {
showHypaV3Alert();
}
openMenu = false
}}>
<BrainIcon />
<span class="ml-2">
{DBState.db.hypav2 ? language.hypaMemoryV2Modal : language.hypaMemoryV3Modal}
</span>
</div>
{/if}
{/if}
{#if DBState.db.translator !== ''}
<div class={"flex items-center cursor-pointer "+ (DBState.db.useAutoTranslateInput ? 'text-green-500':'lg:hover:text-green-500')} onclick={() => {

View File

@@ -91,6 +91,15 @@
let showImportantOnly = $state(false);
$effect.pre(() => {
untrack(() => {
DBState.db.characters[$selectedCharID].chats[
DBState.db.characters[$selectedCharID].chatPage
].hypaV3Data ??= {
summaries: [],
lastSelectedSummaries: [],
};
});
summaryUIStates = hypaV3DataState.summaries.map((summary) => ({
originalRef: null,
isTranslating: false,
@@ -1359,14 +1368,18 @@
{/await}
</div>
<!-- No First Message -->
{#if !getFirstMessage()}
<div class="mt-2 sm:mt-4">
<div class="mt-2 sm:mt-4">
<div class="mb-2 sm:mb-4 text-sm text-zinc-400">
{language.hypaV3Modal.summarizationConditionLabel}
</div>
<!-- No First Message -->
{#if !getFirstMessage()}
<span class="text-sm text-red-400"
>{language.hypaV3Modal.emptySelectedFirstMessageLabel}</span
>
</div>
{/if}
{/if}
</div>
</div>
</div>
</div>

View File

@@ -43,6 +43,10 @@
<Check bind:check={DBState.db.showMenuChatList} name={language.showMenuChatList}/>
</div>
<div class="flex items-center mt-2">
<Check bind:check={DBState.db.showMenuHypaMemoryModal} name={language.showMenuHypaMemoryModal}/>
</div>
<div class="flex items-center mt-2">
<Check bind:check={DBState.db.goCharacterOnImport} name={language.goCharacterOnImport}/>
</div>

View File

@@ -1101,20 +1101,16 @@
}}
className="mt-4"
>
{language.HypaMemory} V2 Data
{language.hypaMemoryV2Modal}
</Button>
{:else if DBState.db.supaModelType !== 'none' && DBState.db.hypaV3}
<Button
onclick={() => {
DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].hypaV3Data ??= {
summaries: [],
lastSelectedSummaries: [],
}
showHypaV3Alert()
}}
className="mt-4"
>
{language.HypaMemory} V3 Data
{language.hypaMemoryV3Modal}
</Button>
{:else if DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].supaMemoryData && DBState.db.characters[$selectedCharID].chats[DBState.db.characters[$selectedCharID].chatPage].supaMemoryData.length > 4 || DBState.db.characters[$selectedCharID].supaMemory}
<span class="text-textcolor mt-4">{language.SuperMemory}</span>

View File

@@ -1023,6 +1023,7 @@ export interface Database{
}[]
igpPrompt:string
useTokenizerCaching:boolean
showMenuHypaMemoryModal:boolean
}
interface SeparateParameters{