From 3d4b4eb7c41ab09d1dcf7e1082391def10c754be Mon Sep 17 00:00:00 2001
From: Wx-2025 <351320169@qq.com>
Date: Sun, 30 Nov 2025 23:02:51 +0800
Subject: [PATCH] Delete super-memory directory
---
super-memory/bindings.js | 89 -------------
super-memory/index.html | 85 ------------
super-memory/lorebook-bridge.js | 228 --------------------------------
super-memory/manager.js | 203 ----------------------------
super-memory/smart-indexer.js | 77 -----------
5 files changed, 682 deletions(-)
delete mode 100644 super-memory/bindings.js
delete mode 100644 super-memory/index.html
delete mode 100644 super-memory/lorebook-bridge.js
delete mode 100644 super-memory/manager.js
delete mode 100644 super-memory/smart-indexer.js
diff --git a/super-memory/bindings.js b/super-memory/bindings.js
deleted file mode 100644
index 591de3f..0000000
--- a/super-memory/bindings.js
+++ /dev/null
@@ -1,89 +0,0 @@
-import { extensionName } from "../../utils/settings.js";
-import { extension_settings } from "/scripts/extensions.js";
-import { saveSettingsDebounced } from "/script.js";
-import { initializeSuperMemory } from "./manager.js";
-
-export function bindSuperMemoryEvents() {
- const panel = $('#amily2_super_memory_panel');
- if (panel.length === 0) return;
-
- panel.on('click', '.sm-nav-item', function() {
- const tab = $(this).data('tab');
-
- panel.find('.sm-nav-item').removeClass('active');
- $(this).addClass('active');
-
- panel.find('.sm-tab-pane').removeClass('active');
- panel.find(`#sm-${tab}-tab`).addClass('active');
- });
-
- panel.on('change', 'input[type="checkbox"]', function() {
- if (!extension_settings[extensionName]) extension_settings[extensionName] = {};
-
- const id = this.id;
- let key = null;
-
- if (id === 'sm-system-enabled') key = 'super_memory_enabled';
- if (id === 'sm-bridge-enabled') key = 'superMemory_bridgeEnabled';
-
- if (key) {
- extension_settings[extensionName][key] = this.checked;
- saveSettingsDebounced();
- console.log(`[Amily2-SuperMemory] Setting updated: ${key} = ${this.checked}`);
- }
- });
-
- panel.on('change', 'input[type="number"], input[type="text"]', function() {
- if (!extension_settings[extensionName]) extension_settings[extensionName] = {};
-
- const id = this.id;
- let key = null;
-
- if (id === 'sm-index-depth') key = 'superMemory_indexDepth';
- if (id === 'sm-detail-depth') key = 'superMemory_detailDepth';
-
- if (key) {
- let value = this.value;
- if (this.type === 'number') value = parseInt(value, 10);
-
- extension_settings[extensionName][key] = value;
- saveSettingsDebounced();
- console.log(`[Amily2-SuperMemory] Setting updated: ${key} = ${value}`);
- }
- });
-
- loadSuperMemorySettings();
-
- console.log('[Amily2-SuperMemory] Events bound successfully.');
-}
-
-function loadSuperMemorySettings() {
- const settings = extension_settings[extensionName] || {};
-
- $('#sm-system-enabled').prop('checked', settings.super_memory_enabled ?? false);
- $('#sm-bridge-enabled').prop('checked', settings.superMemory_bridgeEnabled ?? false);
-
- $('#sm-index-depth').val(settings.superMemory_indexDepth ?? 0);
- $('#sm-detail-depth').val(settings.superMemory_detailDepth ?? 2);
-}
-
-window.sm_initializeSystem = async function() {
- toastr.info('超级记忆系统正在初始化...');
- $('#sm-system-status').text('初始化中...').css('color', 'yellow');
-
- try {
- await initializeSuperMemory();
- toastr.success('超级记忆系统初始化完成。');
- } catch (error) {
- console.error(error);
- toastr.error('初始化失败,请检查控制台。');
- $('#sm-system-status').text('错误').css('color', 'red');
- }
-};
-
-window.sm_purgeMemory = function() {
- if (confirm('您确定要清空所有超级记忆数据吗?')) {
- toastr.warning('记忆已清空。');
- $('#sm-system-status').text('未初始化').css('color', '#ffc107');
- }
-};
diff --git a/super-memory/index.html b/super-memory/index.html
deleted file mode 100644
index dcb5240..0000000
--- a/super-memory/index.html
+++ /dev/null
@@ -1,85 +0,0 @@
-
-
-
-
-
-
究极长期记忆 (Super Memory)
-
欢迎来到 Amily2 的核心记忆中枢。这里掌管着世界的记忆,连接着每一个角色、每一个物品与每一段传说。
-
通过“三级金字塔”注入策略,我们将实现极致的 Token 节省与无限的记忆深度。
-
-
-
-
-
-
-
-
-
-
diff --git a/super-memory/lorebook-bridge.js b/super-memory/lorebook-bridge.js
deleted file mode 100644
index dfdcfcf..0000000
--- a/super-memory/lorebook-bridge.js
+++ /dev/null
@@ -1,228 +0,0 @@
-import { amilyHelper } from "../tavern-helper/main.js";
-import { extension_settings, getContext } from "/scripts/extensions.js";
-import { extensionName } from "../../utils/settings.js";
-import { this_chid, characters } from "/script.js";
-
-function getMemoryBookName() {
- let charName = "Global";
- const context = getContext();
-
- if (this_chid !== undefined && characters[this_chid]) {
- charName = characters[this_chid].name;
- } else if (context.characterId !== undefined && characters[context.characterId]) {
- charName = characters[context.characterId].name;
- }
-
- const safeCharName = charName.replace(/[<>:"/\\|?*]/g, '_');
- return `Amily2_Memory_${safeCharName}`;
-}
-
-export async function syncToLorebook(tableName, data, indexText, role, headers, rowStatuses, depth = 100) {
- console.log(`[Amily2-Bridge] 开始同步表格: ${tableName} (Depth: ${depth})`);
-
- await ensureMemoryBook();
-
- const bookName = getMemoryBookName();
-
- let entries = await amilyHelper.getLorebookEntries(bookName);
- if (!entries) entries = [];
-
- const entriesToUpdate = [];
- const entriesToCreate = [];
-
- const processEntry = (comment, keys, content, type = 'selective', enabled = true) => {
- const existingEntry = entries.find(e => e.comment === comment);
- if (existingEntry) {
- existingEntry.content = content;
- existingEntry.key = keys;
- existingEntry.order = depth;
-
- if (type === 'constant') {
- existingEntry.constant = true;
- } else {
- existingEntry.constant = false;
- }
- if (existingEntry.enabled !== undefined) {
- existingEntry.enabled = enabled;
- } else {
- existingEntry.disable = !enabled;
- }
- entriesToUpdate.push(existingEntry);
- } else {
- entriesToCreate.push({
- comment: comment,
- keys: keys,
- content: content,
- type: type,
- position: 1,
- order: depth,
- enabled: enabled
- });
- }
- };
-
- if (role === 'database') {
- const indexKey = [`Amily_Index_${tableName}`];
- const indexComment = `[Amily2] Index for ${tableName}`;
- let indexContent = `【${tableName} 索引】\n${indexText.trim()}`;
-
- if (tableName.includes("大纲")) {
- indexContent += `\n\n【Amily2-前瞻性预测指令】\n为了实现“提前一轮触发绿灯世界书”的高级记忆回流,请在生成本轮回复时,根据当前剧情走向,**大胆预测并自然提及**下一轮可能出现的索引编码。可自行增加一个标签并使用html注释掉该编码。这将激活系统的预加载机制,确保剧情发展的连贯性。\n`;
- }
-
- processEntry(indexComment, indexKey, indexContent, 'constant');
- }
-
- data.forEach((row, index) => {
- if (!row || row.length === 0) return;
-
- const primaryVal = row[0];
-
- if (!primaryVal) return;
-
- const isPendingDeletion = rowStatuses && rowStatuses[index] === 'pending-deletion';
- const isEnabled = !isPendingDeletion;
-
- const triggerKeys = [primaryVal];
- const entryComment = `[Amily2] Detail: ${tableName} - ${primaryVal}`;
-
- let finalHeaders = headers;
- if (!finalHeaders || finalHeaders.length < row.length) {
- finalHeaders = [];
- for(let i=0; i 0) {
- console.log(`[Amily2-Bridge] 清理 ${entriesToDelete.length} 个废弃条目...`);
- await amilyHelper.deleteLorebookEntries(bookName, entriesToDelete);
- }
-
- if (entriesToUpdate.length > 0) {
- console.log(`[Amily2-Bridge] 更新 ${entriesToUpdate.length} 个条目...`);
- await amilyHelper.setLorebookEntries(bookName, entriesToUpdate);
- }
-
- if (entriesToCreate.length > 0) {
- console.log(`[Amily2-Bridge] 创建 ${entriesToCreate.length} 个新条目...`);
- await amilyHelper.createLorebookEntries(bookName, entriesToCreate);
- }
- console.log(`[Amily2-Bridge] 同步完成: ${tableName}`);
-}
-
-export async function ensureMemoryBook() {
- const bookName = getMemoryBookName();
- const books = await amilyHelper.getLorebooks();
-
- if (!books.includes(bookName)) {
- console.log(`[Amily2-Bridge] 创建角色专用世界书: ${bookName}`);
- await amilyHelper.createLorebook(bookName);
- }
-
- const settings = extension_settings[extensionName] || {};
- const shouldBind = settings.superMemory_autoBind === true;
-
- if (shouldBind && bookName.startsWith("Amily2_Memory_") && bookName !== "Amily2_Memory_Global") {
- console.log(`[Amily2-Bridge] 自动绑定世界书到当前角色...`);
- await amilyHelper.bindLorebookToCharacter(bookName);
- } else if (!shouldBind) {
- console.log(`[Amily2-Bridge] 跳过自动绑定 (设置已禁用)。请手动在世界书管理中激活: ${bookName}`);
- }
-}
-
-function createEntryTemplate() {
- return {
- uid: Date.now() + Math.floor(Math.random() * 1000),
- key: [],
- keysecondary: [],
- comment: "",
- content: "",
- constant: false,
- selective: true,
- order: 100,
- position: 1,
- enabled: true
- };
-}
-
-export async function updateTransientHint(hint) {
- console.log('[Amily2-Bridge] 更新瞬时记忆提示...');
- await ensureMemoryBook();
- const bookName = getMemoryBookName();
-
- const comment = "[Amily2] Active Memory Hint";
- const content = hint ? `\n\n【重要记忆回响】\n${hint}\n\n` : "";
- const enabled = !!hint;
-
- let entries = await amilyHelper.getLorebookEntries(bookName);
- if (!entries) entries = [];
-
- const existingEntry = entries.find(e => e.comment === comment);
-
- if (existingEntry) {
- existingEntry.content = content;
- existingEntry.enabled = enabled;
- existingEntry.order = 0;
- existingEntry.constant = true;
-
- await amilyHelper.setLorebookEntries(bookName, [existingEntry]);
- } else if (hint) {
- const newEntry = {
- comment: comment,
- keys: [],
- content: content,
- constant: true,
- selective: false,
- order: 0,
- position: 0,
- enabled: true
- };
- await amilyHelper.createLorebookEntries(bookName, [newEntry]);
- }
-
- console.log(`[Amily2-Bridge] 瞬时记忆提示已${enabled ? '启用' : '清除'}。`);
-}
diff --git a/super-memory/manager.js b/super-memory/manager.js
deleted file mode 100644
index 38f633d..0000000
--- a/super-memory/manager.js
+++ /dev/null
@@ -1,203 +0,0 @@
-import { extension_settings, getContext } from "/scripts/extensions.js";
-import { extensionName } from "../../utils/settings.js";
-import { amilyHelper } from "../tavern-helper/main.js";
-import { generateIndex } from "./smart-indexer.js";
-import { syncToLorebook, ensureMemoryBook, updateTransientHint } from "./lorebook-bridge.js";
-import { getMemoryState, loadMemoryState, saveMemoryState } from "../table-system/manager.js";
-import { eventSource, event_types } from "/script.js";
-
-let isInitialized = false;
-let updateQueue = [];
-let isProcessing = false;
-let lastChatId = null;
-
-const METADATA_KEY = 'Amily2_Memory_Data';
-
-export async function initializeSuperMemory() {
- const settings = extension_settings[extensionName] || {};
- if (settings.super_memory_enabled === false) {
- console.log('[Amily2-SuperMemory] 功能已禁用 (super_memory_enabled = false)。');
- if (window.$) $('#sm-system-status').text('已禁用').css('color', 'gray');
- return;
- }
-
- if (isInitialized) return;
- console.log('[Amily2-SuperMemory] 初始化核心管理器...');
-
- if (!amilyHelper) {
- console.error('[Amily2-SuperMemory] 致命错误:AmilyHelper 未就绪。');
- return;
- }
-
- document.addEventListener('AMILY2_TABLE_UPDATED', handleTableUpdate);
-
- eventSource.on(event_types.CHAT_CHANGED, async () => {
- const settings = extension_settings[extensionName] || {};
- if (settings.super_memory_enabled === false) return;
-
- console.log('[Amily2-SuperMemory] 检测到聊天切换,正在刷新记忆状态...');
- await checkWorldBookStatus();
-
- await tryRestoreStateFromMetadata();
-
- await forceSyncAll();
- });
-
- await checkWorldBookStatus();
-
- await tryRestoreStateFromMetadata();
-
- await forceSyncAll();
-
- isInitialized = true;
- console.log('[Amily2-SuperMemory] 核心管理器初始化完成。');
-
- if (window.$) {
- $('#sm-system-status').text('运行中').css('color', '#4caf50');
- }
-}
-
-async function checkWorldBookStatus() {
- try {
- await ensureMemoryBook();
- } catch (error) {
- console.error('[Amily2-SuperMemory] 检查世界书状态失败:', error);
- }
-}
-
-function handleTableUpdate(event) {
- const settings = extension_settings[extensionName] || {};
- if (settings.super_memory_enabled === false) return;
-
- const { tableName, data, role, hint, headers, rowStatuses } = event.detail;
- console.log(`[Amily2-SuperMemory] 检测到表格更新: ${tableName} (Role: ${role})`);
-
- updateQueue.push({ tableName, data, role, hint, headers, rowStatuses });
- processQueue();
-}
-
-async function processQueue() {
- if (isProcessing || updateQueue.length === 0) return;
- isProcessing = true;
-
- try {
- while (updateQueue.length > 0) {
- const task = updateQueue.shift();
- await processUpdateTask(task);
- }
-
- await saveStateToMetadata();
-
- } catch (error) {
- console.error('[Amily2-SuperMemory] 处理更新队列失败:', error);
- } finally {
- isProcessing = false;
- }
-}
-
-async function processUpdateTask(task) {
- const { tableName, data, role, hint, headers, rowStatuses } = task;
-
- const activeData = data.filter((_, i) => !rowStatuses || rowStatuses[i] !== 'pending-deletion');
- const indexText = generateIndex(activeData, role, tableName);
-
- const allTables = getMemoryState();
- const tableIndex = allTables.findIndex(t => t.name === tableName);
- const depth = 8001 + (tableIndex >= 0 ? tableIndex : 99);
-
- await syncToLorebook(tableName, data, indexText, role, headers, rowStatuses, depth);
-
- if (hint) {
- console.log(`[Amily2-SuperMemory] 应用主动记忆提示: ${hint}`);
- await updateTransientHint(hint);
- }
-
- console.log(`[Amily2-SuperMemory] 任务完成: ${tableName}`);
-
- updateDashboardCounters();
-}
-
-async function saveStateToMetadata() {
- const context = getContext();
- if (!context.chat || context.chat.length === 0) return;
-
- const lastMsgIndex = context.chat.length - 1;
- const lastMsg = context.chat[lastMsgIndex];
-
- const currentState = getMemoryState();
-
- if (!lastMsg.metadata) lastMsg.metadata = {};
-
- lastMsg.metadata[METADATA_KEY] = JSON.parse(JSON.stringify(currentState));
-
- if (context.saveChat) {
- await context.saveChat();
- }
-
- console.log(`[Amily2-SuperMemory] 状态已保存至消息 #${lastMsgIndex}`);
-}
-
-export async function tryRestoreStateFromMetadata() {
- const context = getContext();
- if (!context.chat || context.chat.length === 0) return;
-
- let foundState = null;
- let foundIndex = -1;
-
- for (let i = context.chat.length - 1; i >= 0; i--) {
- const msg = context.chat[i];
- if (msg.metadata && msg.metadata[METADATA_KEY]) {
- foundState = msg.metadata[METADATA_KEY];
- foundIndex = i;
- break;
- }
- }
-
- if (foundState) {
- console.log(`[Amily2-SuperMemory] 发现历史状态 (Msg #${foundIndex}),正在恢复...`);
- if (typeof loadMemoryState === 'function') {
- loadMemoryState(foundState);
- await forceSyncAll();
- } else {
- console.warn('[Amily2-SuperMemory] table-system 缺少 loadMemoryState 方法,无法恢复状态。');
- }
- } else {
- console.log('[Amily2-SuperMemory] 未在聊天记录中发现历史状态,使用默认/当前状态。');
- }
-}
-
-function updateDashboardCounters() {
- const tables = getMemoryState();
- if (tables && window.$) {
- $('#sm-index-count').text(`${tables.length} 个索引`);
- const totalRows = tables.reduce((acc, t) => acc + (t.rows ? t.rows.length : 0), 0);
- $('#sm-detail-count').text(`${totalRows} 个详情`);
- }
-}
-
-export async function forceSyncAll() {
- console.log('[Amily2-SuperMemory] 正在执行全量同步...');
- const tables = getMemoryState();
-
- if (!tables || tables.length === 0) {
- console.warn('[Amily2-SuperMemory] 没有可同步的表格数据。');
- return;
- }
-
- for (const table of tables) {
- let role = 'database';
- if (table.name.includes('时空') || table.name.includes('世界钟')) role = 'anchor';
- if (table.name.includes('日志') || table.name.includes('Log')) role = 'log';
-
- updateQueue.push({
- tableName: table.name,
- data: table.rows,
- headers: table.headers,
- rowStatuses: table.rowStatuses || [],
- role: role
- });
- }
-
- await processQueue();
- console.log('[Amily2-SuperMemory] 全量同步完成。');
-}
diff --git a/super-memory/smart-indexer.js b/super-memory/smart-indexer.js
deleted file mode 100644
index 57cd6a7..0000000
--- a/super-memory/smart-indexer.js
+++ /dev/null
@@ -1,77 +0,0 @@
-export function generateIndex(data, role, tableName = "") {
- if (!Array.isArray(data) || data.length === 0) {
- return "";
- }
-
- const headers = Object.keys(data[0]);
- if (headers.length === 0) return "";
-
- const indexColumns = identifyIndexColumns(data, headers);
-
- let indexLines = [];
- indexLines.push(`| ${indexColumns.join(' | ')} |`);
- indexLines.push(`| ${indexColumns.map(() => '---').join(' | ')} |`);
-
- let processedData = [...data];
-
- const firstColKey = headers[0];
- const firstColVal = data[0] ? data[0][firstColKey] : '';
- const isIndexCol = (firstColKey && (firstColKey.includes('索引') || firstColKey.includes('Index'))) ||
- (typeof firstColVal === 'string' && /^\s*M\d+/.test(firstColVal)) ||
- (tableName && (tableName.includes('总结') || tableName.includes('大纲')));
-
- if (isIndexCol) {
- processedData.sort((a, b) => {
- const valA = String(a[firstColKey] || '');
- const valB = String(b[firstColKey] || '');
- return valA.localeCompare(valB, undefined, { numeric: true });
- });
- }
-
- for (const row of processedData) {
- const lineParts = indexColumns.map(col => {
- let val = row[col];
- if (val === undefined || val === null) return "";
- val = String(val).trim();
- if (val.length > 15) val = val.substring(0, 12) + "...";
- return val;
- });
- indexLines.push(`| ${lineParts.join(' | ')} |`);
- }
-
- return indexLines.join('\n');
-}
-
-function identifyIndexColumns(data, headers) {
- if (headers.length <= 2) return headers;
-
- const candidates = [];
- const maxColumns = 3;
-
- for (const header of headers) {
- if (candidates.length >= maxColumns) break;
-
- let totalLen = 0;
- let count = 0;
- for (const row of data) {
- if (row[header]) {
- totalLen += String(row[header]).length;
- count++;
- }
- }
- const avgLen = count > 0 ? totalLen / count : 0;
-
- const isLongText = avgLen > 20;
- const isBlacklisted = /desc|bio|detail|history|经历|描述|详情/i.test(header);
-
- if (!isLongText && !isBlacklisted) {
- candidates.push(header);
- }
- }
-
- if (candidates.length === 0) {
- return headers.slice(0, Math.min(headers.length, maxColumns));
- }
-
- return candidates;
-}