forked from aikohanasaki/SillyTavern-MemoryBooks
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmemoryTierMacros.js
More file actions
105 lines (92 loc) · 4.04 KB
/
Copy pathmemoryTierMacros.js
File metadata and controls
105 lines (92 loc) · 4.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright (C) 2024–2026 Aiko Hanasaki
// SPDX-License-Identifier: AGPL-3.0-only
import { chat_metadata } from '../../../../script.js';
import { extension_settings } from '../../../extensions.js';
import { macros, MacroCategory, MacroValueType } from '../../../macros/macro-system.js';
import { METADATA_KEY, loadWorldInfo, world_names } from '../../../world-info.js';
import { getEntrySummaryTier, STMB_SUMMARY_TIERS } from './summaryTiers.js';
import { isClipEntryTitle } from './clipManager.js';
import { isSidePromptEntryTitle } from './sidePrompts.js';
import { getCurrentManualLorebookResolution } from './utils.js';
const EMPTY_TIER_COUNTS = Object.freeze(
Object.fromEntries(STMB_SUMMARY_TIERS.map(({ tier }) => [tier, 0])),
);
let tierCounts = { ...EMPTY_TIER_COUNTS };
let clipCount = 0;
let sidePromptCount = 0;
let refreshSequence = 0;
function getEffectiveLorebookNameNonInteractive() {
const moduleSettings = extension_settings.STMemoryBooks?.moduleSettings;
if (!moduleSettings?.manualModeEnabled) {
return chat_metadata?.[METADATA_KEY] || null;
}
const manualLorebook = getCurrentManualLorebookResolution().lorebookName;
return manualLorebook && world_names.includes(manualLorebook)
? manualLorebook
: null;
}
function countEntriesByTier(lorebookData) {
const counts = { ...EMPTY_TIER_COUNTS };
for (const entry of Object.values(lorebookData?.entries || {})) {
if (entry?.stmemorybooks !== true) continue;
const tier = getEntrySummaryTier(entry);
if (Object.hasOwn(counts, tier)) counts[tier]++;
}
return counts;
}
function updateCounts(lorebookData) {
const entries = Object.values(lorebookData?.entries || {});
tierCounts = countEntriesByTier(lorebookData);
clipCount = entries.filter((entry) => isClipEntryTitle(entry?.comment)).length;
sidePromptCount = entries.filter((entry) => isSidePromptEntryTitle(entry?.comment)).length;
}
function clearCounts() {
tierCounts = { ...EMPTY_TIER_COUNTS };
clipCount = 0;
sidePromptCount = 0;
}
export function updateMemoryTierMacroCache(lorebookName, lorebookData) {
if (lorebookName !== getEffectiveLorebookNameNonInteractive()) return;
refreshSequence++;
updateCounts(lorebookData);
}
export async function refreshMemoryTierMacroCache() {
const sequence = ++refreshSequence;
const lorebookName = getEffectiveLorebookNameNonInteractive();
clearCounts();
if (!lorebookName) return;
try {
const lorebookData = await loadWorldInfo(lorebookName);
if (sequence !== refreshSequence || lorebookName !== getEffectiveLorebookNameNonInteractive()) return;
updateCounts(lorebookData);
} catch (error) {
if (sequence === refreshSequence) {
console.warn(`STMemoryBooks: Failed to refresh memory tier macros for "${lorebookName}":`, error);
}
}
}
export function registerMemoryTierMacros() {
for (const { tier, label } of STMB_SUMMARY_TIERS) {
macros.registry.registerMacro(`memtier${tier}`, {
category: MacroCategory.CHAT,
description: `Number of STMemoryBooks ${label.toLowerCase()} entries in the effective Memory Book.`,
returns: `The total number of tier ${tier} entries as an integer.`,
returnType: MacroValueType.INTEGER,
handler: () => String(tierCounts[tier] ?? 0),
});
}
macros.registry.registerMacro('memclips', {
category: MacroCategory.CHAT,
description: 'Number of STMemoryBooks Clip entries in the effective Memory Book.',
returns: 'The total number of Clip entries as an integer.',
returnType: MacroValueType.INTEGER,
handler: () => String(clipCount),
});
macros.registry.registerMacro('memside', {
category: MacroCategory.CHAT,
description: 'Number of STMemoryBooks Side Prompt entries in the effective Memory Book.',
returns: 'The total number of Side Prompt entries as an integer.',
returnType: MacroValueType.INTEGER,
handler: () => String(sidePromptCount),
});
}