Skip to content

Commit dac50c1

Browse files
committed
add: validateAndFixFmIndex function
1 parent cf259b0 commit dac50c1

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

src/ts/characters.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ export async function importChat(){
415415

416416
DBState.db.characters[selectedID].chats.unshift(newChat)
417417
changeChatTo(0)
418+
await validateAndFixFmIndex(selectedID, 0)
418419
alertNormal(language.successImport)
419420
}
420421
else if(dat.name.endsWith('json')){
@@ -445,6 +446,7 @@ export async function importChat(){
445446
chat.id = v4()
446447
})
447448
DBState.db.characters[selectedID].chats.unshift(...chats)
449+
await validateAndFixFmIndex(selectedID, 0)
448450
alertNormal(language.successImport)
449451
return
450452
}
@@ -461,6 +463,7 @@ export async function importChat(){
461463
v.fmIndex ??= -1
462464
return v
463465
})))
466+
await validateAndFixFmIndex(selectedID, 0)
464467
alertNormal(language.successImport)
465468
return
466469
} else {
@@ -474,6 +477,7 @@ export async function importChat(){
474477
das.fmIndex ??= -1
475478
das.id = v4()
476479
DBState.db.characters[selectedID].chats.unshift(das)
480+
await validateAndFixFmIndex(selectedID, 0)
477481
alertNormal(language.successImport)
478482
return
479483
}
@@ -493,6 +497,7 @@ export async function importChat(){
493497
const json = JSON.parse(chat)
494498
if(json.message && json.note && json.name && json.localLore){
495499
DBState.db.characters[selectedID].chats.unshift(json)
500+
await validateAndFixFmIndex(selectedID, 0)
496501
alertNormal(language.successImport)
497502
}
498503
else{
@@ -888,3 +893,53 @@ export async function changeChar(index: number, arg:{
888893
});
889894
selectedCharID.set(index);
890895
}
896+
897+
/**
898+
* Validates that the chat's fmIndex is within the character's alternateGreetings range.
899+
* If the fmIndex points to a non-existent alternate greeting, shows a popup asking
900+
* the user how to fix it.
901+
*
902+
* Option A: Set fmIndex to -1 (default firstMessage)
903+
* Option B: Find or create an empty string in alternateGreetings and use its index
904+
*
905+
* @returns true if fmIndex is valid or was fixed; false only on unexpected failure
906+
*/
907+
export async function validateAndFixFmIndex(charIndex: number, chatIndex: number): Promise<boolean> {
908+
const cha = DBState.db.characters[charIndex]
909+
if (cha.type === 'group') {
910+
return true
911+
}
912+
const chat = cha.chats[chatIndex]
913+
const fmIndex = chat.fmIndex ?? -1
914+
915+
if (fmIndex === -1 || (cha.alternateGreetings && fmIndex < cha.alternateGreetings.length)) {
916+
return true
917+
}
918+
919+
const altCount = cha.alternateGreetings?.length ?? 0
920+
const display = `The first message (index ${fmIndex}) selected for this chat does not exist.\nThis character only has ${altCount} alternate greeting(s).\n\nThe chat will automatically fall back to the default first message,\nwhich may not be what you intended.\n\nHow would you like to fix this?`
921+
922+
const choice = await alertSelect([
923+
'Use the default first message ',
924+
'Use an empty first message',
925+
], display)
926+
927+
if (choice === '0') {
928+
// Option A: use the default first message (character.firstMessage)
929+
chat.fmIndex = -1
930+
DBState.db.characters[charIndex].chats[chatIndex] = chat
931+
return true
932+
}
933+
934+
// Option B: find or create an empty first message
935+
const emptyIndex = (cha.alternateGreetings ?? []).indexOf('')
936+
if (emptyIndex !== -1) {
937+
chat.fmIndex = emptyIndex
938+
} else {
939+
cha.alternateGreetings ??= []
940+
cha.alternateGreetings.push('')
941+
chat.fmIndex = cha.alternateGreetings.length - 1
942+
}
943+
DBState.db.characters[charIndex].chats[chatIndex] = chat
944+
return true
945+
}

src/ts/process/index.svelte.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { getGenerationModelString } from "./models/modelString";
2424
import { connectionOpen, peerRevertChat, peerSafeCheck, peerSync } from "../sync/multiuser";
2525
import { runInlayScreen } from "./inlayScreen";
2626
import { addRerolls } from "./prereroll";
27+
import { validateAndFixFmIndex } from "../characters";
2728
import { runImageEmbedding } from "./transformers";
2829
import { hanuraiMemory } from "./memory/hanuraiMemory";
2930
import { hypaMemoryV2 } from "./memory/hypav2";
@@ -310,6 +311,18 @@ export async function sendChat(chatProcessIndex = -1,arg:{
310311
const tokenizer = new ChatTokenizer(chatAdditonalTokens, DBState.db.aiModel.startsWith('gpt') ? 'noName' : 'name')
311312
let currentChat = runCurrentChatFunction(nowChatroom.chats[selectedChat])
312313
nowChatroom.chats[selectedChat] = currentChat
314+
315+
// Validate fmIndex for non-group characters before sending.
316+
// If fmIndex points to a non-existent alternate greeting, show a popup
317+
// giving the user the option to fix it (use default firstMessage or empty message).
318+
if (nowChatroom.type !== 'group') {
319+
const fmValid = await validateAndFixFmIndex(selectedChar, selectedChat)
320+
if (!fmValid) {
321+
doingChat.set(false)
322+
return false
323+
}
324+
}
325+
313326
let maxContextTokens = DBState.db.maxContext
314327

315328
chatProcessStage.set(1)

0 commit comments

Comments
 (0)