mirror of
https://github.com/Wx-2025/ST-Amily2-Chat-Optimisation.git
synced 2026-06-06 04:35:51 +00:00
Compare commits
4 Commits
0e11f85031
...
59c4adc1c0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59c4adc1c0 | ||
|
|
e66544f774 | ||
|
|
d6b3b00c86 | ||
|
|
a8c3ad9027 |
@@ -46,3 +46,31 @@
|
||||
- 修复自动归档失效问题
|
||||
- 修复归档管理器在同一事件中被三次触发的回归问题
|
||||
- 修复翰林院设置旧版迁移逻辑异常
|
||||
|
||||
---
|
||||
|
||||
## v2.2.4
|
||||
|
||||
### 新功能
|
||||
|
||||
- **Function Call 填表**:
|
||||
- FC 首次请求时对 DeepSeek 系模型自动附加 `thinking: { type: "disabled" }`,避免思考模式与 tool_choice 冲突
|
||||
- 操作列表为空时在日志面板输出原始响应 JSON,便于区分"AI 判断无需变更"、"格式校验全部不通过"和"JSON 解析失败"三种情况
|
||||
|
||||
### 修复
|
||||
|
||||
- **剧情优化**:移除剧情优化页面遗留的 Jqyh 直连配置字段(URL / Key / Model),统一走 API 连接配置功能分配槽位
|
||||
- **表格**:
|
||||
- 补全 `batch-filling-threshold` 批处理阈值的持久化绑定(页面刷新后不再还原为默认值 30)
|
||||
- 修复分步填表并发锁与 async/await 时序问题
|
||||
- 修复外层多余 `try...finally` 导致的插件加载报错
|
||||
- **Rerank**:
|
||||
- 修复选择连接配置后报"API Key 未配置"的问题(`apiMode` 现从设置读取而非硬编码 `custom`)
|
||||
- 补全 `hly-rerank-api-mode` 加载绑定及默认值
|
||||
- **翰林院 RAG**:补全 `priorityRetrieval.sources` 各来源条目的缺失键,修复设置面板回填 TypeError
|
||||
- **二次填表**:
|
||||
- 修复 `secondary-filler.js` 把哈希/重试次数写入非持久化的 `msg.metadata` 字段(ST 标准位是 `msg.extra`),导致刷新后去重与重试计数失效
|
||||
- 修复扫描深度重复计入 `bufferSize`(`contextLimit + buffer + batch + redundancy` → `contextLimit + batch + redundancy`),避免越过预期窗口
|
||||
- SWIPED 事件改走扫描路径,不再用 `targetMessage` bypass 强填最末条,`保留缓冲区(bufferSize)` 设置在滑动场景下正确生效(手动"回退重填"按钮仍保留 bypass,意图明确)
|
||||
- 修复 FC(Function Call)路径下成功填表与"AI 判断无需修改"两种结果均未写回 `amily2_process_hash` 与 `saveChat()` 的问题——之前导致 FC 模式去重完全失效,最旧的未处理楼层会被每次扫描重复发给 AI;现统一回写路径为 `markTargetsProcessed`
|
||||
- FC 空操作时同步输出原始响应 JSON 到控制台(与批量回填日志面板保持一致),便于区分"无需变更"/"格式校验失败"/"JSON 解析失败"
|
||||
|
||||
@@ -291,7 +291,17 @@ async function runBatchAttempt(batchNum, attemptNum) {
|
||||
if (!argsString) throw new Error('Function Call 返回为空。');
|
||||
const ops = parseToolCallArgs(argsString);
|
||||
if (ops.length === 0) {
|
||||
log(`批次 ${batchNum} 的 Function Call 返回操作列表为空,AI 判断此批次无需变更。`, 'warn');
|
||||
let parseHint = '';
|
||||
try {
|
||||
const rawParsed = JSON.parse(argsString);
|
||||
const rawOpsLen = rawParsed?.operations?.length ?? 0;
|
||||
if (rawOpsLen > 0) {
|
||||
parseHint = `(响应含 ${rawOpsLen} 条操作,但全部未通过格式校验)`;
|
||||
}
|
||||
} catch {
|
||||
parseHint = '(响应 JSON 解析失败)';
|
||||
}
|
||||
log(`批次 ${batchNum} FC 操作列表为空${parseHint},原始响应:\n${argsString}`, 'warn');
|
||||
toastr.info('AI 判断此批次无需修改。', `批次 ${batchNum}`);
|
||||
} else {
|
||||
await updateTableFromOps(ops, { immediateDelete: true });
|
||||
@@ -564,7 +574,17 @@ export async function startFloorRangeFilling(startFloor, endFloor) {
|
||||
if (!argsString) throw new Error('Function Call 返回为空。');
|
||||
const ops = parseToolCallArgs(argsString);
|
||||
if (ops.length === 0) {
|
||||
log(`楼层 ${startFloor}-${endFloor} Function Call 返回操作列表为空,无需变更。`, 'warn');
|
||||
let parseHint = '';
|
||||
try {
|
||||
const rawParsed = JSON.parse(argsString);
|
||||
const rawOpsLen = rawParsed?.operations?.length ?? 0;
|
||||
if (rawOpsLen > 0) {
|
||||
parseHint = `(响应含 ${rawOpsLen} 条操作,但全部未通过格式校验)`;
|
||||
}
|
||||
} catch {
|
||||
parseHint = '(响应 JSON 解析失败)';
|
||||
}
|
||||
log(`楼层 ${startFloor}-${endFloor} FC 操作列表为空${parseHint},原始响应:\n${argsString}`, 'warn');
|
||||
toastr.info('AI 判断此楼层范围无需修改。', `楼层 ${startFloor}-${endFloor}`);
|
||||
} else {
|
||||
await updateTableFromOps(ops, { immediateDelete: true });
|
||||
|
||||
@@ -1021,7 +1021,7 @@ export async function rollbackAndRefill() {
|
||||
const lastMessage = context.chat[context.chat.length - 1];
|
||||
|
||||
try {
|
||||
await fillWithSecondaryApi(lastMessage, true);
|
||||
await fillWithSecondaryApi(lastMessage, true, { targetMessage: lastMessage });
|
||||
log('回退并重新填表操作完成。', 'success');
|
||||
} catch (error) {
|
||||
log(`回退重填过程中发生错误: ${error.message}`, 'error');
|
||||
|
||||
@@ -18,6 +18,7 @@ import { showTableFillReviewModal } from '../../ui/page-window.js';
|
||||
const CONTINUE_PROMPT_SECONDARY = '上一条回复不完整或缺少 <Amily2Edit> 指令块。请直接从中断处继续生成剩余内容,不要重复已输出的文本,也不要添加任何解释或寒暄,确保最终输出中包含完整的 <Amily2Edit>...</Amily2Edit> 指令块。';
|
||||
|
||||
let secondaryFillerDebounceTimer = null;
|
||||
let secondaryFillerRunning = false;
|
||||
|
||||
async function callSecondaryModel(messages) {
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
@@ -38,23 +39,30 @@ async function requestSecondaryContinuation(baseMessages, partialResponse) {
|
||||
return `${partialResponse || ''}${continued}`;
|
||||
}
|
||||
|
||||
function commitSecondaryFillResult(rawContent, targetMessages) {
|
||||
updateTableFromText(rawContent);
|
||||
async function markTargetsProcessed(targetMessages, { skipTableSave = false } = {}) {
|
||||
if (!targetMessages || targetMessages.length === 0) return;
|
||||
|
||||
const memoryState = getMemoryState();
|
||||
const lastProcessedMsg = targetMessages[targetMessages.length - 1].msg;
|
||||
|
||||
for (const target of targetMessages) {
|
||||
if (!target.msg.metadata) target.msg.metadata = {};
|
||||
target.msg.metadata.Amily2_Process_Hash = target.hash;
|
||||
if (!target.msg.extra) target.msg.extra = {};
|
||||
target.msg.extra.amily2_process_hash = target.hash;
|
||||
}
|
||||
|
||||
if (saveStateToMessage(memoryState, lastProcessedMsg)) {
|
||||
renderTables();
|
||||
updateOrInsertTableInChat();
|
||||
if (!skipTableSave) {
|
||||
const memoryState = getMemoryState();
|
||||
if (saveStateToMessage(memoryState, lastProcessedMsg)) {
|
||||
renderTables();
|
||||
updateOrInsertTableInChat();
|
||||
}
|
||||
}
|
||||
|
||||
saveChat();
|
||||
await saveChat();
|
||||
}
|
||||
|
||||
async function commitSecondaryFillResult(rawContent, targetMessages) {
|
||||
await updateTableFromText(rawContent);
|
||||
await markTargetsProcessed(targetMessages);
|
||||
}
|
||||
|
||||
|
||||
@@ -110,7 +118,12 @@ async function getWorldBookContext() {
|
||||
return content.trim() ? `<世界书>\n${content.trim()}\n</世界书>` : '';
|
||||
}
|
||||
|
||||
export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
export async function fillWithSecondaryApi(latestMessage, forceRun = false, opts = {}) {
|
||||
if (secondaryFillerRunning) {
|
||||
log('分步填表正在进行中,跳过本次触发。', 'warn');
|
||||
return;
|
||||
}
|
||||
secondaryFillerRunning = true;
|
||||
const settings = extension_settings[extensionName] || {};
|
||||
|
||||
// 【V2.1.1】分步填表触发延迟 / 防抖:自动触发时若配置了延迟,则延后执行,
|
||||
@@ -122,7 +135,7 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
}
|
||||
secondaryFillerDebounceTimer = setTimeout(() => {
|
||||
secondaryFillerDebounceTimer = null;
|
||||
fillWithSecondaryApi(latestMessage, forceRun);
|
||||
fillWithSecondaryApi(latestMessage, forceRun, opts);
|
||||
}, delay);
|
||||
console.log(`[Amily2-副API] 分步填表已按防抖延迟 ${delay}ms 调度。`);
|
||||
return;
|
||||
@@ -164,26 +177,15 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
const contextLimit = parseInt(settings.secondary_filler_context || 2, 10);
|
||||
|
||||
// 【V1.7.7 修复】限制最大回溯深度,防止更新后无限填补旧历史
|
||||
// 响应用户反馈:扫描深度 = 上下文 + 填表批次 + 保留楼层 + 冗余量(10)
|
||||
// redundancy (冗余量): 额外扫描 10 层作为安全缓冲,防止因消息索引计算偏差导致漏掉边缘消息
|
||||
// 扫描深度 = 上下文 + 填表批次 + 冗余量(10)
|
||||
// bufferSize(保留楼层)仅用于限定尾部边界 validEndIndex,
|
||||
// 不再回流到扫描起点,避免重复影响范围
|
||||
const redundancy = 10;
|
||||
const maxScanDepth = contextLimit + batchSize + bufferSize + redundancy;
|
||||
const maxScanDepth = contextLimit + batchSize + redundancy;
|
||||
|
||||
const chat = context.chat;
|
||||
const totalMessages = chat.length;
|
||||
|
||||
const validEndIndex = totalMessages - 1 - bufferSize;
|
||||
// 计算扫描的起始索引(不小于0)
|
||||
const scanStartIndex = Math.max(0, validEndIndex - maxScanDepth);
|
||||
|
||||
if (validEndIndex < 0) {
|
||||
console.log(`[Amily2-副API] 消息数量不足以超出保留区(${bufferSize}),跳过。`);
|
||||
return;
|
||||
}
|
||||
|
||||
let targetMessages = [];
|
||||
let needsProcessing = false;
|
||||
|
||||
const getContentHash = (content) => {
|
||||
let hash = 0, i, chr;
|
||||
if (content.length === 0) return hash;
|
||||
@@ -195,40 +197,69 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
return hash;
|
||||
};
|
||||
|
||||
// 【修复】改为正向扫描,优先处理最老的未处理消息,防止遗留消息被挤出扫描区
|
||||
for (let i = scanStartIndex; i <= validEndIndex; i++) {
|
||||
const msg = chat[i];
|
||||
let targetMessages = [];
|
||||
|
||||
if (msg.is_user) continue;
|
||||
|
||||
const currentHash = getContentHash(msg.mes);
|
||||
const savedHash = msg.metadata?.Amily2_Process_Hash;
|
||||
|
||||
const isUnprocessed = !savedHash;
|
||||
const isChanged = savedHash && savedHash !== currentHash;
|
||||
|
||||
if (isUnprocessed || isChanged) {
|
||||
targetMessages.push({ index: i, msg: msg, hash: currentHash });
|
||||
|
||||
if (batchSize > 0 && targetMessages.length >= batchSize) {
|
||||
needsProcessing = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetMessages.length === 0) {
|
||||
console.log("[Amily2-副API] 没有发现需要处理的消息。");
|
||||
return;
|
||||
}
|
||||
|
||||
if (batchSize > 0) {
|
||||
if (targetMessages.length < batchSize) {
|
||||
console.log(`[Amily2-副API] 批量模式: 当前累积 ${targetMessages.length}/${batchSize} 条未处理消息,暂不触发。`);
|
||||
// 【SWIPED 旁路】swipe 后强制处理刚切出来的最新消息:
|
||||
// 跳过扫描 / bufferSize / batchSize 累积逻辑,直接锁定目标
|
||||
if (opts.targetMessage) {
|
||||
const targetIndex = chat.indexOf(opts.targetMessage);
|
||||
if (targetIndex < 0) {
|
||||
console.log("[Amily2-副API] 旁路目标消息不在聊天列表中,跳过。");
|
||||
return;
|
||||
}
|
||||
if (opts.targetMessage.is_user) {
|
||||
console.log("[Amily2-副API] 旁路目标是用户消息,跳过。");
|
||||
return;
|
||||
}
|
||||
targetMessages.push({
|
||||
index: targetIndex,
|
||||
msg: opts.targetMessage,
|
||||
hash: getContentHash(opts.targetMessage.mes),
|
||||
});
|
||||
} else {
|
||||
targetMessages = [targetMessages[targetMessages.length - 1]];
|
||||
// 常规扫描路径
|
||||
const validEndIndex = totalMessages - 1 - bufferSize;
|
||||
const scanStartIndex = Math.max(0, validEndIndex - maxScanDepth);
|
||||
|
||||
if (validEndIndex < 0) {
|
||||
console.log(`[Amily2-副API] 消息数量不足以超出保留区(${bufferSize}),跳过。`);
|
||||
return;
|
||||
}
|
||||
|
||||
// 【修复】改为正向扫描,优先处理最老的未处理消息,防止遗留消息被挤出扫描区
|
||||
for (let i = scanStartIndex; i <= validEndIndex; i++) {
|
||||
const msg = chat[i];
|
||||
|
||||
if (msg.is_user) continue;
|
||||
|
||||
const currentHash = getContentHash(msg.mes);
|
||||
const savedHash = msg.extra?.amily2_process_hash;
|
||||
|
||||
const isUnprocessed = !savedHash;
|
||||
const isChanged = savedHash && savedHash !== currentHash;
|
||||
|
||||
if (isUnprocessed || isChanged) {
|
||||
targetMessages.push({ index: i, msg: msg, hash: currentHash });
|
||||
|
||||
if (batchSize > 0 && targetMessages.length >= batchSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (targetMessages.length === 0) {
|
||||
console.log("[Amily2-副API] 没有发现需要处理的消息。");
|
||||
return;
|
||||
}
|
||||
|
||||
if (batchSize > 0) {
|
||||
if (targetMessages.length < batchSize) {
|
||||
console.log(`[Amily2-副API] 批量模式: 当前累积 ${targetMessages.length}/${batchSize} 条未处理消息,暂不触发。`);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
targetMessages = [targetMessages[targetMessages.length - 1]];
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`[Amily2-副API] 触发填表: 处理 ${targetMessages.length} 条消息。索引范围: ${targetMessages[0].index} - ${targetMessages[targetMessages.length-1].index}`);
|
||||
@@ -345,10 +376,20 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
}
|
||||
const ops = parseToolCallArgs(argsString);
|
||||
if (ops.length === 0) {
|
||||
console.warn('[Amily2-副API] Function Call 返回操作列表为空,无需变更。');
|
||||
let parseHint = '';
|
||||
try {
|
||||
const rawParsed = JSON.parse(argsString);
|
||||
const rawOpsLen = rawParsed?.operations?.length ?? 0;
|
||||
if (rawOpsLen > 0) parseHint = `(响应含 ${rawOpsLen} 条操作,但全部未通过格式校验)`;
|
||||
} catch {
|
||||
parseHint = '(响应 JSON 解析失败)';
|
||||
}
|
||||
console.warn(`[Amily2-副API] Function Call 返回操作列表为空${parseHint},原始响应:\n${argsString}`);
|
||||
toastr.info('AI 判断此范围无需修改。', 'Amily2-分步填表');
|
||||
await markTargetsProcessed(targetMessages, { skipTableSave: true });
|
||||
} else {
|
||||
await updateTableFromOps(ops);
|
||||
await markTargetsProcessed(targetMessages);
|
||||
toastr.success('分步填表(Function Call)执行完毕。', 'Amily2-分步填表');
|
||||
}
|
||||
} else {
|
||||
@@ -373,8 +414,8 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
const rangeLabel = `${targetMessages[0].index + 1} - ${targetMessages[targetMessages.length - 1].index + 1}`;
|
||||
console.warn(`[Amily2-副API] 响应未包含 <Amily2Edit> 指令块(楼层 ${rangeLabel}),弹出检查窗口等待用户处理。`);
|
||||
toastr.warning(`分步填表(楼层 ${rangeLabel})的响应缺少 <Amily2Edit> 指令块,请在弹窗中处理。`, 'Amily2-分步填表');
|
||||
if (latestMessage && latestMessage.metadata) {
|
||||
delete latestMessage.metadata.Amily2_Retry_Count;
|
||||
if (latestMessage && latestMessage.extra) {
|
||||
delete latestMessage.extra.amily2_retry_count;
|
||||
}
|
||||
showTableFillReviewModal(rawContent, {
|
||||
title: `分步填表响应检查 - 楼层 ${rangeLabel}`,
|
||||
@@ -389,12 +430,12 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
}
|
||||
return merged;
|
||||
},
|
||||
onApply: (editedText) => {
|
||||
onApply: async (editedText) => {
|
||||
if (!editedText || !editedText.includes('<Amily2Edit>')) {
|
||||
toastr.warning('应用的文本中未检测到 <Amily2Edit> 指令块,已按原文尝试写入。', '手动应用');
|
||||
}
|
||||
try {
|
||||
commitSecondaryFillResult(editedText, targetMessages);
|
||||
await commitSecondaryFillResult(editedText, targetMessages);
|
||||
toastr.success('分步填表已由用户手动处理完成。', 'Amily2-分步填表');
|
||||
} catch (err) {
|
||||
console.error('[Amily2-副API] 手动应用失败:', err);
|
||||
@@ -402,11 +443,11 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
}
|
||||
},
|
||||
onRetry: () => {
|
||||
if (latestMessage && latestMessage.metadata) {
|
||||
delete latestMessage.metadata.Amily2_Retry_Count;
|
||||
if (latestMessage && latestMessage.extra) {
|
||||
delete latestMessage.extra.amily2_retry_count;
|
||||
}
|
||||
toastr.info('将重新执行分步填表...', 'Amily2-分步填表');
|
||||
setTimeout(() => fillWithSecondaryApi(latestMessage, forceRun), 300);
|
||||
setTimeout(() => fillWithSecondaryApi(latestMessage, forceRun, opts), 300);
|
||||
},
|
||||
onCancel: () => {
|
||||
toastr.info('已取消本次分步填表。', 'Amily2-分步填表');
|
||||
@@ -415,7 +456,7 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
return;
|
||||
}
|
||||
|
||||
commitSecondaryFillResult(rawContent, targetMessages);
|
||||
await commitSecondaryFillResult(rawContent, targetMessages);
|
||||
}
|
||||
toastr.success("分步填表执行完毕。", "Amily2-分步填表");
|
||||
|
||||
@@ -424,32 +465,35 @@ export async function fillWithSecondaryApi(latestMessage, forceRun = false) {
|
||||
|
||||
// 【新增】自定义重试逻辑
|
||||
const maxRetries = parseInt(settings.secondary_filler_max_retries || 0, 10);
|
||||
const currentRetryCount = latestMessage?.metadata?.Amily2_Retry_Count || 0;
|
||||
const currentRetryCount = latestMessage?.extra?.amily2_retry_count || 0;
|
||||
|
||||
if (currentRetryCount < maxRetries) {
|
||||
const nextRetryCount = currentRetryCount + 1;
|
||||
console.log(`[Amily2-副API] 准备进行第 ${nextRetryCount}/${maxRetries} 次重试...`);
|
||||
toastr.warning(`副API填表失败: ${error.message}。将在3秒后进行第 ${nextRetryCount} 次重试...`, "自动重试");
|
||||
|
||||
// 记录重试次数到最新消息的 metadata 中,以便跨调用传递状态
|
||||
// 记录重试次数到最新消息的 extra 中,以便跨调用传递状态(跟 amily2_tables_data 一起持久化)
|
||||
if (latestMessage) {
|
||||
if (!latestMessage.metadata) latestMessage.metadata = {};
|
||||
latestMessage.metadata.Amily2_Retry_Count = nextRetryCount;
|
||||
if (!latestMessage.extra) latestMessage.extra = {};
|
||||
latestMessage.extra.amily2_retry_count = nextRetryCount;
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
fillWithSecondaryApi(latestMessage, forceRun);
|
||||
fillWithSecondaryApi(latestMessage, forceRun, opts);
|
||||
}, 3000);
|
||||
} else {
|
||||
console.log(`[Amily2-副API] 已达到最大重试次数 (${maxRetries}),放弃本次填表。`);
|
||||
toastr.error(`副API填表失败: ${error.message}。已达到最大重试次数,任务终止。`, "严重错误");
|
||||
|
||||
// 清除重试计数器
|
||||
if (latestMessage && latestMessage.metadata) {
|
||||
delete latestMessage.metadata.Amily2_Retry_Count;
|
||||
if (latestMessage && latestMessage.extra) {
|
||||
delete latestMessage.extra.amily2_retry_count;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
secondaryFillerRunning = false;
|
||||
}
|
||||
secondaryFillerRunning = false;
|
||||
}
|
||||
|
||||
async function getHistoryContext(messagesToFetch, historyEndIndex, tagsToExtract, exclusionRules) {
|
||||
|
||||
2
index.js
2
index.js
@@ -697,7 +697,7 @@ function registerEventListeners() {
|
||||
log(`【监察系统】主填表模式,回退后强制刷新消息ID: ${chat_id}。`, 'info');
|
||||
await handleTableUpdate(chat_id, true);
|
||||
} else if (fillingMode === 'secondary-api' || fillingMode === 'optimized') {
|
||||
log('【监察系统】分步/优化模式,回退后强制二次填表最新消息。', 'info');
|
||||
log('【监察系统】分步/优化模式,回退后触发二次填表扫描(受保留缓冲区限制)。', 'info');
|
||||
await fillWithSecondaryApi(latestMessage, true);
|
||||
} else {
|
||||
log('【监察系统】未配置填表模式,跳过填表。', 'info');
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Amily2号聊天优化助手",
|
||||
"display_name": "Amily2号助手",
|
||||
"version": "2.2.3",
|
||||
"version": "2.2.4",
|
||||
"author": "Wx-2025",
|
||||
"description": "一个拥有独立UI的智能引擎,正文优化、自动总结、记忆表格、rag向量、隐藏楼层、剧情推进等多功能整合。",
|
||||
"minSillyTavernVersion": "1.10.0",
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
const a0_0x4cb62a=a0_0x3f50;function a0_0x3f50(_0x14d0e6,_0x17dd7f){_0x14d0e6=_0x14d0e6-0x1d4;const _0x551c6b=a0_0x551c();let _0x3f502c=_0x551c6b[_0x14d0e6];if(a0_0x3f50['pTOOQF']===undefined){var _0x37daaf=function(_0x173e78){const _0x3e1089='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x4d1d5f='',_0x13b6ec='';for(let _0x1b7914=0x0,_0x2b9e6d,_0x4a898e,_0x47bef2=0x0;_0x4a898e=_0x173e78['charAt'](_0x47bef2++);~_0x4a898e&&(_0x2b9e6d=_0x1b7914%0x4?_0x2b9e6d*0x40+_0x4a898e:_0x4a898e,_0x1b7914++%0x4)?_0x4d1d5f+=String['fromCharCode'](0xff&_0x2b9e6d>>(-0x2*_0x1b7914&0x6)):0x0){_0x4a898e=_0x3e1089['indexOf'](_0x4a898e);}for(let _0x4f1def=0x0,_0x527d62=_0x4d1d5f['length'];_0x4f1def<_0x527d62;_0x4f1def++){_0x13b6ec+='%'+('00'+_0x4d1d5f['charCodeAt'](_0x4f1def)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x13b6ec);};const _0x7dd670=function(_0x4a592e,_0x2a6237){let _0x3dec80=[],_0x609e59=0x0,_0x539e59,_0x2e380d='';_0x4a592e=_0x37daaf(_0x4a592e);let _0x41c9ef;for(_0x41c9ef=0x0;_0x41c9ef<0x100;_0x41c9ef++){_0x3dec80[_0x41c9ef]=_0x41c9ef;}for(_0x41c9ef=0x0;_0x41c9ef<0x100;_0x41c9ef++){_0x609e59=(_0x609e59+_0x3dec80[_0x41c9ef]+_0x2a6237['charCodeAt'](_0x41c9ef%_0x2a6237['length']))%0x100,_0x539e59=_0x3dec80[_0x41c9ef],_0x3dec80[_0x41c9ef]=_0x3dec80[_0x609e59],_0x3dec80[_0x609e59]=_0x539e59;}_0x41c9ef=0x0,_0x609e59=0x0;for(let _0x2f60a7=0x0;_0x2f60a7<_0x4a592e['length'];_0x2f60a7++){_0x41c9ef=(_0x41c9ef+0x1)%0x100,_0x609e59=(_0x609e59+_0x3dec80[_0x41c9ef])%0x100,_0x539e59=_0x3dec80[_0x41c9ef],_0x3dec80[_0x41c9ef]=_0x3dec80[_0x609e59],_0x3dec80[_0x609e59]=_0x539e59,_0x2e380d+=String['fromCharCode'](_0x4a592e['charCodeAt'](_0x2f60a7)^_0x3dec80[(_0x3dec80[_0x41c9ef]+_0x3dec80[_0x609e59])%0x100]);}return _0x2e380d;};a0_0x3f50['XntrAq']=_0x7dd670,a0_0x3f50['hwQAen']={},a0_0x3f50['pTOOQF']=!![];}const _0x38372e=_0x551c6b[0x0],_0x2846dd=_0x14d0e6+_0x38372e,_0x229821=a0_0x3f50['hwQAen'][_0x2846dd];return!_0x229821?(a0_0x3f50['iFTWyz']===undefined&&(a0_0x3f50['iFTWyz']=!![]),_0x3f502c=a0_0x3f50['XntrAq'](_0x3f502c,_0x17dd7f),a0_0x3f50['hwQAen'][_0x2846dd]=_0x3f502c):_0x3f502c=_0x229821,_0x3f502c;}function a0_0x551c(){const _0x8707ca=['W7XsWP5EW47cMg0wdvio','WOqEWOJcV8oOvSoxoa','WPfgj2hdQXyYW54','nCkHWOhdVe7dTg8CmCoQ','nmkWnfBdVNRdNc7dK8oKW4/cRmob','s8kcW4L9W6JcOmk6ha','W54twNVcIaxdUwu','mCoyW43cHmoKW4in','B0FcUmoFW4tdRmkX','W7/dMvhcM0GSW6S','kSo/Dmk+m8kXAW','W6ddOCoaBSoCrcHZjmk0WQaR','k3lcVSoqW4hdVSk7WOxcLGy','W5/cP8oJeru8sdLPxWqKE33cT2tdJSkTEwy4wmohW4O','ttdcJwnFW4yyWQ4sybz9W7W','W5JcTYldMSofiuFcPCkrWQ/dGa','W7z4W6icgZ0','qXS6W4BcUmoCDmoPvmo7','d8oAW5rhW4hcS8k+kaldGSomkMWX','BSoMW4JcRt3cTdiZlSo6FLfR','WOtcKrhdSJ8hc8ocn8oX','iSk7l8oVEmoUdCoYoY18z8ol','FSovW4PVW4lcQmkKWQy','h0vNWOldI8kzF8o1ymogsSox','gvZcMCk6j1FcOsldTa4RqvG','W6tcVCkzmSkMeIW','uCkflSovtmkECCoddvZdLa','WQmObSo/WRtdTJfaWQNcJfNdIq','jcDMW6tcHSonBa','W6T4EtNdVSoxWQtdO8kmdmo2W5HI','pmoAwIRcJw3dTmorWQmYW7FcGhe','W4tdMxddUKxdTXpdKuVcHW3cSSkk','WQ92WO1isSkGB3C','zSoJW47cOd3cSfqXpCo8suC'];a0_0x551c=function(){return _0x8707ca;};return a0_0x551c();}(function(_0x35fae2,_0x13f5dd){const _0x564fc9=a0_0x3f50,_0x139e78=_0x35fae2();while(!![]){try{const _0x145c85=parseInt(_0x564fc9(0x1f0,'Gy85'))/0x1*(parseInt(_0x564fc9(0x1d8,'(cE3'))/0x2)+-parseInt(_0x564fc9(0x1ef,'teyb'))/0x3*(parseInt(_0x564fc9(0x1eb,'$a0d'))/0x4)+-parseInt(_0x564fc9(0x1ed,'@8aF'))/0x5*(parseInt(_0x564fc9(0x1d7,'c]fl'))/0x6)+-parseInt(_0x564fc9(0x1de,'JBGl'))/0x7*(parseInt(_0x564fc9(0x1f1,'svxN'))/0x8)+-parseInt(_0x564fc9(0x1e0,'$a0d'))/0x9*(-parseInt(_0x564fc9(0x1f4,'Kp%8'))/0xa)+parseInt(_0x564fc9(0x1d4,'yp[y'))/0xb*(parseInt(_0x564fc9(0x1e4,')!c@'))/0xc)+-parseInt(_0x564fc9(0x1f5,'QQoj'))/0xd;if(_0x145c85===_0x13f5dd)break;else _0x139e78['push'](_0x139e78['shift']());}catch(_0x44ee5c){_0x139e78['push'](_0x139e78['shift']());}}}(a0_0x551c,0xa7674));export const SENSITIVE_KEYS=new Set([a0_0x4cb62a(0x1e6,'GkY6'),a0_0x4cb62a(0x1e8,'D[Ub'),a0_0x4cb62a(0x1e3,'Nru@'),a0_0x4cb62a(0x1e7,'@8aF'),a0_0x4cb62a(0x1ea,'s5J%'),a0_0x4cb62a(0x1d9,'Fue3'),a0_0x4cb62a(0x1d6,'XQmS'),a0_0x4cb62a(0x1e2,'JBGl')]);
|
||||
function a0_0x271c(){const _0x4b7b23=['lhvoW4jRgSoQlXxcIW','EmojW7BcUdLKW4qDhIFcM8oH','WP7dM1RcQ8kAW5HNWOy','WQxcI0VdUCo9Ca','W7ldJHVcGSkSmg7cRexcNmojW7O','sZnjE8kcW7JdJCkTWQyOchm','kmkMWOZdTY5AWQ/cUdWN','W5lcSHLBF8odWQ3dRmk6l8kv','W7jspw7dQI8FpSkjha','WQKlf8kpWQGbW790','WOhcMmoZnx/dG8kJgcaODCk6DeKShmo1vmkzW5bZW6FdGWu','FSoRg2XIW6BcPs45WOj/W77dMq','WQ0gx8othedcGsVdRSkfWQPQWPjW','W5BcGNDMWOxdIGaBFsK','CmktCsNcH8kitH11rYq','WQj4sHTirmoMW7CbWOvopSkP','g3ddGCkLBmouA1BcJCkZW7a','n3dcOtqPWQusaxWo','tdjdECkgW7/cG8kLWPCJb3FcSq','WPFdUmo4W5/dT3XJd8oBoW','WPVcGeVcKCkhW5T/','WQOaw8ossGpdLxldQmkx','E8onW7ZcUtTPW70weZVcQCo3','W4FdQ1a6W5GHE8oebbG','W5urpfBdGCk1kvzIuSkOyCkouG','F8oiW7ZcUJ1JWOOvlYZcLmoLxa','E8k8tH8IWPZdJW','W6HJftmQW6SlWR1rgG','WO7dSmoJW5pdT3XJd8oBoW','stBcKSopomkxntZcO8kfW4XmFSke'];a0_0x271c=function(){return _0x4b7b23;};return a0_0x271c();}function a0_0x29d9(_0x5910a2,_0x31a139){_0x5910a2=_0x5910a2-0x10e;const _0x271c55=a0_0x271c();let _0x29d9db=_0x271c55[_0x5910a2];if(a0_0x29d9['vXrLbK']===undefined){var _0x1f4aa0=function(_0x419a5a){const _0x54ddf3='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let _0x1487a3='',_0x358070='';for(let _0x556c37=0x0,_0x38eb9b,_0x5849e9,_0x382ad5=0x0;_0x5849e9=_0x419a5a['charAt'](_0x382ad5++);~_0x5849e9&&(_0x38eb9b=_0x556c37%0x4?_0x38eb9b*0x40+_0x5849e9:_0x5849e9,_0x556c37++%0x4)?_0x1487a3+=String['fromCharCode'](0xff&_0x38eb9b>>(-0x2*_0x556c37&0x6)):0x0){_0x5849e9=_0x54ddf3['indexOf'](_0x5849e9);}for(let _0x3f032e=0x0,_0xb58a17=_0x1487a3['length'];_0x3f032e<_0xb58a17;_0x3f032e++){_0x358070+='%'+('00'+_0x1487a3['charCodeAt'](_0x3f032e)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(_0x358070);};const _0x34ec80=function(_0x164ca3,_0x4421d8){let _0xd7a592=[],_0x289d74=0x0,_0x21850c,_0x43a638='';_0x164ca3=_0x1f4aa0(_0x164ca3);let _0x17b6ca;for(_0x17b6ca=0x0;_0x17b6ca<0x100;_0x17b6ca++){_0xd7a592[_0x17b6ca]=_0x17b6ca;}for(_0x17b6ca=0x0;_0x17b6ca<0x100;_0x17b6ca++){_0x289d74=(_0x289d74+_0xd7a592[_0x17b6ca]+_0x4421d8['charCodeAt'](_0x17b6ca%_0x4421d8['length']))%0x100,_0x21850c=_0xd7a592[_0x17b6ca],_0xd7a592[_0x17b6ca]=_0xd7a592[_0x289d74],_0xd7a592[_0x289d74]=_0x21850c;}_0x17b6ca=0x0,_0x289d74=0x0;for(let _0x36b413=0x0;_0x36b413<_0x164ca3['length'];_0x36b413++){_0x17b6ca=(_0x17b6ca+0x1)%0x100,_0x289d74=(_0x289d74+_0xd7a592[_0x17b6ca])%0x100,_0x21850c=_0xd7a592[_0x17b6ca],_0xd7a592[_0x17b6ca]=_0xd7a592[_0x289d74],_0xd7a592[_0x289d74]=_0x21850c,_0x43a638+=String['fromCharCode'](_0x164ca3['charCodeAt'](_0x36b413)^_0xd7a592[(_0xd7a592[_0x17b6ca]+_0xd7a592[_0x289d74])%0x100]);}return _0x43a638;};a0_0x29d9['KgrlkL']=_0x34ec80,a0_0x29d9['kNssnt']={},a0_0x29d9['vXrLbK']=!![];}const _0x1b2a57=_0x271c55[0x0],_0x49c2f7=_0x5910a2+_0x1b2a57,_0x1a2216=a0_0x29d9['kNssnt'][_0x49c2f7];return!_0x1a2216?(a0_0x29d9['XDIAAg']===undefined&&(a0_0x29d9['XDIAAg']=!![]),_0x29d9db=a0_0x29d9['KgrlkL'](_0x29d9db,_0x31a139),a0_0x29d9['kNssnt'][_0x49c2f7]=_0x29d9db):_0x29d9db=_0x1a2216,_0x29d9db;}const a0_0x46b8d0=a0_0x29d9;(function(_0x37f9e6,_0xba7d17){const _0xcc4674=a0_0x29d9,_0x15f749=_0x37f9e6();while(!![]){try{const _0x741256=-parseInt(_0xcc4674(0x121,'bDll'))/0x1*(parseInt(_0xcc4674(0x112,'yhY8'))/0x2)+parseInt(_0xcc4674(0x114,'tp0g'))/0x3+-parseInt(_0xcc4674(0x127,'IWny'))/0x4*(-parseInt(_0xcc4674(0x125,'uN)a'))/0x5)+parseInt(_0xcc4674(0x117,'tp0g'))/0x6+-parseInt(_0xcc4674(0x11b,'F@y%'))/0x7+-parseInt(_0xcc4674(0x11c,'MFs7'))/0x8*(-parseInt(_0xcc4674(0x122,'V%T]'))/0x9)+-parseInt(_0xcc4674(0x12a,'vQuU'))/0xa*(-parseInt(_0xcc4674(0x115,'^vxs'))/0xb);if(_0x741256===_0xba7d17)break;else _0x15f749['push'](_0x15f749['shift']());}catch(_0x5665c9){_0x15f749['push'](_0x15f749['shift']());}}}(a0_0x271c,0xdbf20));export const SENSITIVE_KEYS=new Set([a0_0x46b8d0(0x11f,'k^Lf'),a0_0x46b8d0(0x116,'d7&G'),a0_0x46b8d0(0x126,'KWT3'),a0_0x46b8d0(0x119,'EVQd'),a0_0x46b8d0(0x10f,'$OoJ'),a0_0x46b8d0(0x11a,'7SNw'),a0_0x46b8d0(0x10e,'F@y%'),a0_0x46b8d0(0x111,'7SNw')]);
|
||||
Reference in New Issue
Block a user