mirror of
https://github.com/SilenceLurker/ST-Amily2-Chat-Optimisation.git
synced 2026-06-06 10:05:50 +00:00
Merge branch 'Wx-2025:main' into main
This commit is contained in:
@@ -7,8 +7,9 @@ import { extractBlocksByTags, applyExclusionRules } from '../../core/utils/rag-t
|
||||
import { getExtensionSettings } from '../../utils/settings.js';
|
||||
import { getPresetPrompts, getMixedOrder } from '../../PresetSettings/index.js';
|
||||
import { generateRandomSeed } from '../../core/api.js';
|
||||
import { getChatIdentifier } from '../../core/lore.js';
|
||||
|
||||
const { SillyTavern, TavernHelper, jQuery } = window;
|
||||
const { SillyTavern, TavernHelper, jQuery, characters } = window;
|
||||
|
||||
let isUpdatingCard = false;
|
||||
let isBatchUpdating = false;
|
||||
@@ -77,31 +78,34 @@ export async function updateCardUpdateStatusDisplay($panel) {
|
||||
}
|
||||
|
||||
async function loadAllChatMessages($panel) {
|
||||
logDebug('尝试加载所有聊天消息...');
|
||||
if (!TavernHelper || !SillyTavern) {
|
||||
logError('用于加载消息的API不可用。');
|
||||
logDebug('尝试使用 getContext() 加载所有聊天消息...');
|
||||
if (!SillyTavern) {
|
||||
logError('SillyTavern API 不可用。');
|
||||
state.allChatMessages = [];
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const context = SillyTavern.getContext();
|
||||
const chatLength = context?.chat?.length || 0;
|
||||
const chat = context?.chat || [];
|
||||
|
||||
if (chatLength === 0) {
|
||||
if (chat.length === 0) {
|
||||
logDebug('聊天为空,无需加载消息。');
|
||||
state.allChatMessages = [];
|
||||
} else {
|
||||
const lastMessageId = chatLength - 1;
|
||||
const messagesFromApi = await TavernHelper.getChatMessages(`0-${lastMessageId}`, { include_swipes: false });
|
||||
state.allChatMessages = Array.isArray(messagesFromApi) ? messagesFromApi.map((msg, idx) => ({ ...msg, id: idx })) : [];
|
||||
state.allChatMessages = chat.map((msg, idx) => ({
|
||||
...msg,
|
||||
message: msg.mes,
|
||||
id: idx
|
||||
}));
|
||||
}
|
||||
|
||||
logDebug(`成功为 ${state.currentChatFileIdentifier} 加载了 ${state.allChatMessages.length} 条消息。`);
|
||||
await updateCardUpdateStatusDisplay($panel);
|
||||
|
||||
} catch (error) {
|
||||
logError('获取聊天消息时发生严重错误:', error);
|
||||
logError('使用 getContext() 获取聊天消息时发生严重错误:', error);
|
||||
showToastr('error', '获取聊天记录时发生内部错误。');
|
||||
state.allChatMessages = [];
|
||||
}
|
||||
}
|
||||
@@ -376,21 +380,21 @@ async function triggerAutomaticUpdate($panel) {
|
||||
}
|
||||
|
||||
export async function getLatestChatName() {
|
||||
let newChatFileIdentifier = 'unknown_chat_fallback';
|
||||
try {
|
||||
let chatNameFromCommand = await TavernHelper.triggerSlash('/getchatname');
|
||||
if (chatNameFromCommand && typeof chatNameFromCommand === 'string' && chatNameFromCommand.trim() && !['null', 'undefined'].includes(chatNameFromCommand.trim())) {
|
||||
newChatFileIdentifier = cleanChatName(chatNameFromCommand.trim());
|
||||
} else {
|
||||
const contextFallback = SillyTavern.getContext();
|
||||
if (contextFallback && contextFallback.chat) {
|
||||
newChatFileIdentifier = cleanChatName(contextFallback.chat);
|
||||
}
|
||||
let attempts = 0;
|
||||
const maxAttempts = 50;
|
||||
const interval = 100;
|
||||
|
||||
while (attempts < maxAttempts) {
|
||||
const context = getContext();
|
||||
if (context && context.chatId) {
|
||||
return context.chatId;
|
||||
}
|
||||
} catch (error) {
|
||||
logError('获取最新聊天名称时出错:', error);
|
||||
await new Promise((resolve) => setTimeout(resolve, interval));
|
||||
attempts++;
|
||||
}
|
||||
return newChatFileIdentifier;
|
||||
|
||||
logError("[CWB] 长时间等待后,仍无法确定聊天ID。");
|
||||
return "unknown_chat_timeout";
|
||||
}
|
||||
|
||||
export async function handleMessageReceived($panel) {
|
||||
|
||||
@@ -317,3 +317,84 @@ export async function manageAutoCardUpdateLorebookEntry() {
|
||||
logError('管理世界书条目时出错:', error);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* (重构) 通用函数,用于同步小说处理生成的世界书条目。
|
||||
* @param {string} bookName - 目标世界书名称。
|
||||
* @param {Array<{title: string, content: string}>} entries - 从API回复中解析出的条目数组。
|
||||
*/
|
||||
export async function syncNovelLorebookEntries(bookName, entries) {
|
||||
if (!bookName || !Array.isArray(entries) || entries.length === 0) {
|
||||
logError('[CWB-NovelSync] 参数无效或条目为空');
|
||||
if (Array.isArray(entries) && entries.length === 0) {
|
||||
showToastr('warning', '[小说处理] API回复中未找到有效条目。');
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const allEntries = (await TavernHelper.getLorebookEntries(bookName)) || [];
|
||||
const managedEntries = allEntries.filter(e => e.comment?.startsWith(`[Amily2小说处理]`));
|
||||
|
||||
const entriesToUpdate = [];
|
||||
const entriesToCreate = [];
|
||||
|
||||
// 查找“章节内容概述”的最新部分编号
|
||||
let maxPart = 0;
|
||||
managedEntries.forEach(entry => {
|
||||
const match = entry.comment.match(/章节内容概述-第(\d+)部分/);
|
||||
if (match && parseInt(match[1], 10) > maxPart) {
|
||||
maxPart = parseInt(match[1], 10);
|
||||
}
|
||||
});
|
||||
let nextPart = maxPart + 1;
|
||||
|
||||
for (const entry of entries) {
|
||||
const { title, content } = entry;
|
||||
|
||||
if (title === '章节内容概述') {
|
||||
// “章节内容概述”条目总是新建
|
||||
const loreData = {
|
||||
keys: [`小说处理`, title, `第${nextPart}部分`],
|
||||
content: content,
|
||||
comment: `[Amily2小说处理] ${title}-第${nextPart}部分`,
|
||||
enabled: true,
|
||||
order: 100,
|
||||
position: 'before_char',
|
||||
};
|
||||
entriesToCreate.push(loreData);
|
||||
nextPart++; // 为同一批次中的下一个概述增加编号
|
||||
} else {
|
||||
// 其他条目(世界观、时间线等)是动态更新的
|
||||
const existingEntry = managedEntries.find(e => e.comment === `[Amily2小说处理] ${title}`);
|
||||
|
||||
const loreData = {
|
||||
keys: [`小说处理`, title],
|
||||
content: content,
|
||||
comment: `[Amily2小说处理] ${title}`,
|
||||
enabled: true,
|
||||
order: 100,
|
||||
position: 'before_char',
|
||||
};
|
||||
|
||||
if (existingEntry) {
|
||||
entriesToUpdate.push({ uid: existingEntry.uid, ...loreData });
|
||||
} else {
|
||||
entriesToCreate.push(loreData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (entriesToUpdate.length > 0) {
|
||||
await TavernHelper.setLorebookEntries(bookName, entriesToUpdate);
|
||||
showToastr('info', `[小说处理] 更新了 ${entriesToUpdate.length} 个世界书条目。`);
|
||||
}
|
||||
if (entriesToCreate.length > 0) {
|
||||
await TavernHelper.createLorebookEntries(bookName, entriesToCreate);
|
||||
showToastr('success', `[小说处理] 创建了 ${entriesToCreate.length} 个新世界书条目。`);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
logError('同步小说世界书条目时出错:', error);
|
||||
showToastr('error', '同步世界书失败,详情请查看控制台。');
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user