feat: add memory selection metrics to HypaV3 (#861)
# PR Checklist - [ ] Have you checked if it works normally in all models? *Ignore this if it doesn't use models.* - [ ] Have you checked if it works normally in all web, local, and node hosted versions? If it doesn't, have you blocked it in those versions? - [ ] Have you added type definitions? # Preview  # Description This PR introduces following: - Add memory selection metrics to HypaV3
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
import {
|
import {
|
||||||
SearchIcon,
|
SearchIcon,
|
||||||
SettingsIcon,
|
SettingsIcon,
|
||||||
|
MoreVerticalIcon,
|
||||||
|
BarChartIcon,
|
||||||
Trash2Icon,
|
Trash2Icon,
|
||||||
XIcon,
|
XIcon,
|
||||||
ChevronUpIcon,
|
ChevronUpIcon,
|
||||||
@@ -88,6 +90,8 @@
|
|||||||
let expandedMessageUIState = $state<ExpandedMessageUI>(null);
|
let expandedMessageUIState = $state<ExpandedMessageUI>(null);
|
||||||
let searchUIState = $state<SearchUI>(null);
|
let searchUIState = $state<SearchUI>(null);
|
||||||
let showImportantOnly = $state(false);
|
let showImportantOnly = $state(false);
|
||||||
|
let showDropdown = $state(false);
|
||||||
|
let showMetrics = $state(false);
|
||||||
|
|
||||||
$effect.pre(() => {
|
$effect.pre(() => {
|
||||||
untrack(() => {
|
untrack(() => {
|
||||||
@@ -95,7 +99,6 @@
|
|||||||
DBState.db.characters[$selectedCharID].chatPage
|
DBState.db.characters[$selectedCharID].chatPage
|
||||||
].hypaV3Data ??= {
|
].hypaV3Data ??= {
|
||||||
summaries: [],
|
summaries: [],
|
||||||
lastSelectedSummaries: [],
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -187,15 +190,14 @@
|
|||||||
|
|
||||||
// Search summary index
|
// Search summary index
|
||||||
if (query.match(/^#\d+$/)) {
|
if (query.match(/^#\d+$/)) {
|
||||||
const summaryNumber = parseInt(query.substring(1)) - 1;
|
const summaryIndex = parseInt(query.substring(1)) - 1;
|
||||||
|
|
||||||
if (
|
if (
|
||||||
summaryNumber >= 0 &&
|
summaryIndex >= 0 &&
|
||||||
summaryNumber < hypaV3DataState.summaries.length &&
|
summaryIndex < hypaV3DataState.summaries.length &&
|
||||||
(!showImportantOnly ||
|
isSummaryVisible(summaryIndex)
|
||||||
hypaV3DataState.summaries[summaryNumber].isImportant)
|
|
||||||
) {
|
) {
|
||||||
results.push(new SummarySearchResult(summaryNumber, 0, 0));
|
results.push(new SummarySearchResult(summaryIndex, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
@@ -204,10 +206,7 @@
|
|||||||
if (isGuidLike(query)) {
|
if (isGuidLike(query)) {
|
||||||
// Search chatMemo
|
// Search chatMemo
|
||||||
summaryUIStates.forEach((summaryUI, summaryIndex) => {
|
summaryUIStates.forEach((summaryUI, summaryIndex) => {
|
||||||
if (
|
if (isSummaryVisible(summaryIndex)) {
|
||||||
!showImportantOnly ||
|
|
||||||
hypaV3DataState.summaries[summaryIndex].isImportant
|
|
||||||
) {
|
|
||||||
summaryUI.chatMemoRefs.forEach((buttonRef, memoIndex) => {
|
summaryUI.chatMemoRefs.forEach((buttonRef, memoIndex) => {
|
||||||
const buttonText = buttonRef.textContent?.toLowerCase() || "";
|
const buttonText = buttonRef.textContent?.toLowerCase() || "";
|
||||||
|
|
||||||
@@ -220,10 +219,7 @@
|
|||||||
} else {
|
} else {
|
||||||
// Search summary
|
// Search summary
|
||||||
summaryUIStates.forEach((summaryUI, summaryIndex) => {
|
summaryUIStates.forEach((summaryUI, summaryIndex) => {
|
||||||
if (
|
if (isSummaryVisible(summaryIndex)) {
|
||||||
!showImportantOnly ||
|
|
||||||
hypaV3DataState.summaries[summaryIndex].isImportant
|
|
||||||
) {
|
|
||||||
const textAreaText = summaryUI.originalRef.value?.toLowerCase();
|
const textAreaText = summaryUI.originalRef.value?.toLowerCase();
|
||||||
let pos = -1;
|
let pos = -1;
|
||||||
|
|
||||||
@@ -375,6 +371,23 @@
|
|||||||
textarea.scrollTop = selectionTop - textarea.clientHeight / 2;
|
textarea.scrollTop = selectionTop - textarea.clientHeight / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isSummaryVisible(index: number): boolean {
|
||||||
|
const summary = hypaV3DataState.summaries[index];
|
||||||
|
const metrics = hypaV3DataState.metrics;
|
||||||
|
|
||||||
|
const metricsFilter =
|
||||||
|
!showMetrics ||
|
||||||
|
!metrics ||
|
||||||
|
metrics.lastImportantSummaries.includes(index) ||
|
||||||
|
metrics.lastRecentSummaries.includes(index) ||
|
||||||
|
metrics.lastSimilarSummaries.includes(index) ||
|
||||||
|
metrics.lastRandomSummaries.includes(index);
|
||||||
|
|
||||||
|
const importantFilter = !showImportantOnly || summary.isImportant;
|
||||||
|
|
||||||
|
return metricsFilter && importantFilter;
|
||||||
|
}
|
||||||
|
|
||||||
async function toggleTranslate(
|
async function toggleTranslate(
|
||||||
summaryIndex: number,
|
summaryIndex: number,
|
||||||
regenerate?: boolean
|
regenerate?: boolean
|
||||||
@@ -730,7 +743,6 @@
|
|||||||
chatMemos: [...mainChunk.chatMemos],
|
chatMemos: [...mainChunk.chatMemos],
|
||||||
isImportant: false,
|
isImportant: false,
|
||||||
})),
|
})),
|
||||||
lastSelectedSummaries: [],
|
|
||||||
};
|
};
|
||||||
|
|
||||||
chat.hypaV3Data = newHypaV3Data;
|
chat.hypaV3Data = newHypaV3Data;
|
||||||
@@ -819,11 +831,17 @@
|
|||||||
<!-- Modal wrapper -->
|
<!-- Modal wrapper -->
|
||||||
<div class="flex justify-center w-full h-full">
|
<div class="flex justify-center w-full h-full">
|
||||||
<!-- Modal window -->
|
<!-- Modal window -->
|
||||||
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
<div
|
<div
|
||||||
class="flex flex-col p-3 sm:p-6 rounded-lg bg-zinc-900 w-full max-w-3xl {hypaV3DataState
|
class="flex flex-col p-3 sm:p-6 rounded-lg bg-zinc-900 w-full max-w-3xl {hypaV3DataState
|
||||||
.summaries.length === 0
|
.summaries.length === 0
|
||||||
? 'h-fit'
|
? 'h-fit'
|
||||||
: 'h-full'}"
|
: 'h-full'}"
|
||||||
|
onclick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
showDropdown = false;
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<!-- Header -->
|
<!-- Header -->
|
||||||
<div class="flex justify-between items-center mb-2 sm:mb-4">
|
<div class="flex justify-between items-center mb-2 sm:mb-4">
|
||||||
@@ -831,6 +849,7 @@
|
|||||||
<h1 class="text-lg sm:text-2xl font-semibold text-zinc-300">
|
<h1 class="text-lg sm:text-2xl font-semibold text-zinc-300">
|
||||||
{language.hypaV3Modal.titleLabel}
|
{language.hypaV3Modal.titleLabel}
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<!-- Buttons Container -->
|
<!-- Buttons Container -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<!-- Search Button -->
|
<!-- Search Button -->
|
||||||
@@ -874,28 +893,69 @@
|
|||||||
<SettingsIcon class="w-6 h-6" />
|
<SettingsIcon class="w-6 h-6" />
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<!-- Reset Button -->
|
<!-- Show Dropdown Button -->
|
||||||
<button
|
<div class="relative">
|
||||||
class="p-2 text-zinc-400 hover:text-rose-300 transition-colors"
|
<button
|
||||||
tabindex="-1"
|
class="p-2 text-zinc-400 hover:text-zinc-200 transition-colors"
|
||||||
onclick={async () => {
|
tabindex="-1"
|
||||||
if (
|
onclick={(e) => {
|
||||||
await alertConfirmTwice(
|
e.stopPropagation();
|
||||||
language.hypaV3Modal.resetConfirmMessage,
|
showDropdown = true;
|
||||||
language.hypaV3Modal.resetConfirmSecondMessage
|
}}
|
||||||
)
|
>
|
||||||
) {
|
<MoreVerticalIcon class="w-6 h-6" />
|
||||||
DBState.db.characters[$selectedCharID].chats[
|
</button>
|
||||||
DBState.db.characters[$selectedCharID].chatPage
|
|
||||||
].hypaV3Data = {
|
{#if showDropdown}
|
||||||
summaries: [],
|
<div
|
||||||
lastSelectedSummaries: [],
|
class="absolute z-10 right-0 mt-1 p-2 rounded-md shadow-lg border border-zinc-700 bg-zinc-800"
|
||||||
};
|
>
|
||||||
}
|
<!-- Buttons Container -->
|
||||||
}}
|
<div class="flex items-center gap-2">
|
||||||
>
|
<!-- Show Metrics Button -->
|
||||||
<Trash2Icon class="w-6 h-6" />
|
<button
|
||||||
</button>
|
class="p-2 transition-colors {showMetrics
|
||||||
|
? 'text-blue-400 hover:text-blue-300'
|
||||||
|
: 'text-zinc-400 hover:text-zinc-200'}"
|
||||||
|
tabindex="-1"
|
||||||
|
onclick={() => {
|
||||||
|
if (searchUIState) {
|
||||||
|
searchUIState.query = "";
|
||||||
|
searchUIState.results = [];
|
||||||
|
searchUIState.currentResultIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
showMetrics = !showMetrics;
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<BarChartIcon class="w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Reset Button -->
|
||||||
|
<button
|
||||||
|
class="p-2 text-zinc-400 hover:text-rose-300 transition-colors"
|
||||||
|
tabindex="-1"
|
||||||
|
onclick={async () => {
|
||||||
|
if (
|
||||||
|
await alertConfirmTwice(
|
||||||
|
language.hypaV3Modal.resetConfirmMessage,
|
||||||
|
language.hypaV3Modal.resetConfirmSecondMessage
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
DBState.db.characters[$selectedCharID].chats[
|
||||||
|
DBState.db.characters[$selectedCharID].chatPage
|
||||||
|
].hypaV3Data = {
|
||||||
|
summaries: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Trash2Icon class="w-6 h-6" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Close Button -->
|
<!-- Close Button -->
|
||||||
<button
|
<button
|
||||||
@@ -954,7 +1014,7 @@
|
|||||||
|
|
||||||
<!-- Search Bar -->
|
<!-- Search Bar -->
|
||||||
{:else if searchUIState}
|
{:else if searchUIState}
|
||||||
<div class="sticky top-0 z-40 p-2 sm:p-3 bg-zinc-800">
|
<div class="sticky top-0 p-2 sm:p-3 bg-zinc-800">
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<div class="relative flex flex-1 items-center">
|
<div class="relative flex flex-1 items-center">
|
||||||
<form
|
<form
|
||||||
@@ -1016,7 +1076,7 @@
|
|||||||
|
|
||||||
<!-- Summaries List -->
|
<!-- Summaries List -->
|
||||||
{#each hypaV3DataState.summaries as summary, i}
|
{#each hypaV3DataState.summaries as summary, i}
|
||||||
{#if !showImportantOnly || summary.isImportant}
|
{#if isSummaryVisible(i)}
|
||||||
{#if summaryUIStates[i]}
|
{#if summaryUIStates[i]}
|
||||||
<!-- Summary Item -->
|
<!-- Summary Item -->
|
||||||
<div
|
<div
|
||||||
@@ -1024,13 +1084,50 @@
|
|||||||
>
|
>
|
||||||
<!-- Original Summary Header -->
|
<!-- Original Summary Header -->
|
||||||
<div class="flex justify-between items-center">
|
<div class="flex justify-between items-center">
|
||||||
<span class="text-sm text-zinc-400"
|
<!-- Summary Number / Metrics Container -->
|
||||||
>{language.hypaV3Modal.summaryNumberLabel.replace(
|
<div class="flex items-center gap-2">
|
||||||
"{0}",
|
<span class="text-sm text-zinc-400"
|
||||||
(i + 1).toString()
|
>{language.hypaV3Modal.summaryNumberLabel.replace(
|
||||||
)}</span
|
"{0}",
|
||||||
>
|
(i + 1).toString()
|
||||||
|
)}</span
|
||||||
|
>
|
||||||
|
|
||||||
|
{#if showMetrics && hypaV3DataState.metrics}
|
||||||
|
<div class="flex flex-wrap gap-1">
|
||||||
|
{#if hypaV3DataState.metrics.lastImportantSummaries.includes(i)}
|
||||||
|
<span
|
||||||
|
class="px-1.5 py-0.5 rounded-full text-xs whitespace-nowrap text-purple-200 bg-purple-900/70"
|
||||||
|
>
|
||||||
|
Important
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
{#if hypaV3DataState.metrics.lastRecentSummaries.includes(i)}
|
||||||
|
<span
|
||||||
|
class="px-1.5 py-0.5 rounded-full text-xs whitespace-nowrap text-blue-200 bg-blue-900/70"
|
||||||
|
>
|
||||||
|
Recent
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
{#if hypaV3DataState.metrics.lastSimilarSummaries.includes(i)}
|
||||||
|
<span
|
||||||
|
class="px-1.5 py-0.5 rounded-full text-xs whitespace-nowrap text-green-200 bg-green-900/70"
|
||||||
|
>
|
||||||
|
Similar
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
{#if hypaV3DataState.metrics.lastRandomSummaries.includes(i)}
|
||||||
|
<span
|
||||||
|
class="px-1.5 py-0.5 rounded-full text-xs whitespace-nowrap text-yellow-200 bg-yellow-900/70"
|
||||||
|
>
|
||||||
|
Random
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Buttons Container -->
|
||||||
<div class="flex items-center gap-2">
|
<div class="flex items-center gap-2">
|
||||||
<!-- Translate Button -->
|
<!-- Translate Button -->
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -41,7 +41,13 @@ export interface HypaV3Settings {
|
|||||||
|
|
||||||
interface HypaV3Data {
|
interface HypaV3Data {
|
||||||
summaries: Summary[];
|
summaries: Summary[];
|
||||||
lastSelectedSummaries?: number[];
|
lastSelectedSummaries?: number[]; // legacy
|
||||||
|
metrics?: {
|
||||||
|
lastImportantSummaries: number[];
|
||||||
|
lastRecentSummaries: number[];
|
||||||
|
lastSimilarSummaries: number[];
|
||||||
|
lastRandomSummaries: number[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SerializableHypaV3Data {
|
export interface SerializableHypaV3Data {
|
||||||
@@ -50,7 +56,13 @@ export interface SerializableHypaV3Data {
|
|||||||
chatMemos: string[];
|
chatMemos: string[];
|
||||||
isImportant: boolean;
|
isImportant: boolean;
|
||||||
}[];
|
}[];
|
||||||
lastSelectedSummaries?: number[];
|
lastSelectedSummaries?: number[]; // legacy
|
||||||
|
metrics?: {
|
||||||
|
lastImportantSummaries: number[];
|
||||||
|
lastRecentSummaries: number[];
|
||||||
|
lastSimilarSummaries: number[];
|
||||||
|
lastRandomSummaries: number[];
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Summary {
|
interface Summary {
|
||||||
@@ -158,14 +170,11 @@ async function hypaMemoryV3MainExp(
|
|||||||
currentTokens -= db.maxResponse;
|
currentTokens -= db.maxResponse;
|
||||||
|
|
||||||
// Load existing hypa data if available
|
// Load existing hypa data if available
|
||||||
let data: HypaV3Data = {
|
const data: HypaV3Data = room.hypaV3Data
|
||||||
summaries: [],
|
? toHypaV3Data(room.hypaV3Data)
|
||||||
lastSelectedSummaries: [],
|
: {
|
||||||
};
|
summaries: [],
|
||||||
|
};
|
||||||
if (room.hypaV3Data) {
|
|
||||||
data = toHypaV3Data(room.hypaV3Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean orphaned summaries
|
// Clean orphaned summaries
|
||||||
if (!settings.preserveOrphanedMemory) {
|
if (!settings.preserveOrphanedMemory) {
|
||||||
@@ -464,11 +473,10 @@ async function hypaMemoryV3MainExp(
|
|||||||
const selectedSummaries: Summary[] = [];
|
const selectedSummaries: Summary[] = [];
|
||||||
const randomMemoryRatio =
|
const randomMemoryRatio =
|
||||||
1 - settings.recentMemoryRatio - settings.similarMemoryRatio;
|
1 - settings.recentMemoryRatio - settings.similarMemoryRatio;
|
||||||
|
const selectedImportantSummaries: Summary[] = [];
|
||||||
|
|
||||||
// Select important summaries
|
// Select important summaries
|
||||||
{
|
{
|
||||||
const selectedImportantSummaries: Summary[] = [];
|
|
||||||
|
|
||||||
for (const summary of data.summaries) {
|
for (const summary of data.summaries) {
|
||||||
if (summary.isImportant) {
|
if (summary.isImportant) {
|
||||||
const summaryTokens = await tokenizer.tokenizeChat({
|
const summaryTokens = await tokenizer.tokenizeChat({
|
||||||
@@ -505,10 +513,9 @@ async function hypaMemoryV3MainExp(
|
|||||||
availableMemoryTokens * settings.recentMemoryRatio
|
availableMemoryTokens * settings.recentMemoryRatio
|
||||||
);
|
);
|
||||||
let consumedRecentMemoryTokens = 0;
|
let consumedRecentMemoryTokens = 0;
|
||||||
|
const selectedRecentSummaries: Summary[] = [];
|
||||||
|
|
||||||
if (settings.recentMemoryRatio > 0) {
|
if (settings.recentMemoryRatio > 0) {
|
||||||
const selectedRecentSummaries: Summary[] = [];
|
|
||||||
|
|
||||||
// Target only summaries that haven't been selected yet
|
// Target only summaries that haven't been selected yet
|
||||||
const unusedSummaries = data.summaries.filter(
|
const unusedSummaries = data.summaries.filter(
|
||||||
(e) => !selectedSummaries.includes(e)
|
(e) => !selectedSummaries.includes(e)
|
||||||
@@ -554,10 +561,9 @@ async function hypaMemoryV3MainExp(
|
|||||||
availableMemoryTokens * settings.similarMemoryRatio
|
availableMemoryTokens * settings.similarMemoryRatio
|
||||||
);
|
);
|
||||||
let consumedSimilarMemoryTokens = 0;
|
let consumedSimilarMemoryTokens = 0;
|
||||||
|
const selectedSimilarSummaries: Summary[] = [];
|
||||||
|
|
||||||
if (settings.similarMemoryRatio > 0) {
|
if (settings.similarMemoryRatio > 0) {
|
||||||
const selectedSimilarSummaries: Summary[] = [];
|
|
||||||
|
|
||||||
// Utilize unused token space from recent selection
|
// Utilize unused token space from recent selection
|
||||||
if (randomMemoryRatio <= 0) {
|
if (randomMemoryRatio <= 0) {
|
||||||
const unusedRecentTokens =
|
const unusedRecentTokens =
|
||||||
@@ -769,10 +775,9 @@ async function hypaMemoryV3MainExp(
|
|||||||
availableMemoryTokens * randomMemoryRatio
|
availableMemoryTokens * randomMemoryRatio
|
||||||
);
|
);
|
||||||
let consumedRandomMemoryTokens = 0;
|
let consumedRandomMemoryTokens = 0;
|
||||||
|
const selectedRandomSummaries: Summary[] = [];
|
||||||
|
|
||||||
if (randomMemoryRatio > 0) {
|
if (randomMemoryRatio > 0) {
|
||||||
const selectedRandomSummaries: Summary[] = [];
|
|
||||||
|
|
||||||
// Utilize unused token space from recent and similar selection
|
// Utilize unused token space from recent and similar selection
|
||||||
const unusedRecentTokens =
|
const unusedRecentTokens =
|
||||||
reservedRecentMemoryTokens - consumedRecentMemoryTokens;
|
reservedRecentMemoryTokens - consumedRecentMemoryTokens;
|
||||||
@@ -872,9 +877,20 @@ async function hypaMemoryV3MainExp(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save last selected summaries
|
// Save last selected summaries
|
||||||
data.lastSelectedSummaries = selectedSummaries.map((selectedSummary) =>
|
data.metrics = {
|
||||||
data.summaries.findIndex((summary) => summary === selectedSummary)
|
lastImportantSummaries: selectedImportantSummaries.map((selected) =>
|
||||||
);
|
data.summaries.findIndex((sum) => sum === selected)
|
||||||
|
),
|
||||||
|
lastRecentSummaries: selectedRecentSummaries.map((selected) =>
|
||||||
|
data.summaries.findIndex((sum) => sum === selected)
|
||||||
|
),
|
||||||
|
lastSimilarSummaries: selectedSimilarSummaries.map((selected) =>
|
||||||
|
data.summaries.findIndex((sum) => sum === selected)
|
||||||
|
),
|
||||||
|
lastRandomSummaries: selectedRandomSummaries.map((selected) =>
|
||||||
|
data.summaries.findIndex((sum) => sum === selected)
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
const newChats: OpenAIChat[] = [
|
const newChats: OpenAIChat[] = [
|
||||||
{
|
{
|
||||||
@@ -927,14 +943,11 @@ async function hypaMemoryV3Main(
|
|||||||
currentTokens -= db.maxResponse;
|
currentTokens -= db.maxResponse;
|
||||||
|
|
||||||
// Load existing hypa data if available
|
// Load existing hypa data if available
|
||||||
let data: HypaV3Data = {
|
const data: HypaV3Data = room.hypaV3Data
|
||||||
summaries: [],
|
? toHypaV3Data(room.hypaV3Data)
|
||||||
lastSelectedSummaries: [],
|
: {
|
||||||
};
|
summaries: [],
|
||||||
|
};
|
||||||
if (room.hypaV3Data) {
|
|
||||||
data = toHypaV3Data(room.hypaV3Data);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clean orphaned summaries
|
// Clean orphaned summaries
|
||||||
if (!settings.preserveOrphanedMemory) {
|
if (!settings.preserveOrphanedMemory) {
|
||||||
@@ -1171,11 +1184,10 @@ async function hypaMemoryV3Main(
|
|||||||
const selectedSummaries: Summary[] = [];
|
const selectedSummaries: Summary[] = [];
|
||||||
const randomMemoryRatio =
|
const randomMemoryRatio =
|
||||||
1 - settings.recentMemoryRatio - settings.similarMemoryRatio;
|
1 - settings.recentMemoryRatio - settings.similarMemoryRatio;
|
||||||
|
const selectedImportantSummaries: Summary[] = [];
|
||||||
|
|
||||||
// Select important summaries
|
// Select important summaries
|
||||||
{
|
{
|
||||||
const selectedImportantSummaries: Summary[] = [];
|
|
||||||
|
|
||||||
for (const summary of data.summaries) {
|
for (const summary of data.summaries) {
|
||||||
if (summary.isImportant) {
|
if (summary.isImportant) {
|
||||||
const summaryTokens = await tokenizer.tokenizeChat({
|
const summaryTokens = await tokenizer.tokenizeChat({
|
||||||
@@ -1212,10 +1224,9 @@ async function hypaMemoryV3Main(
|
|||||||
availableMemoryTokens * settings.recentMemoryRatio
|
availableMemoryTokens * settings.recentMemoryRatio
|
||||||
);
|
);
|
||||||
let consumedRecentMemoryTokens = 0;
|
let consumedRecentMemoryTokens = 0;
|
||||||
|
const selectedRecentSummaries: Summary[] = [];
|
||||||
|
|
||||||
if (settings.recentMemoryRatio > 0) {
|
if (settings.recentMemoryRatio > 0) {
|
||||||
const selectedRecentSummaries: Summary[] = [];
|
|
||||||
|
|
||||||
// Target only summaries that haven't been selected yet
|
// Target only summaries that haven't been selected yet
|
||||||
const unusedSummaries = data.summaries.filter(
|
const unusedSummaries = data.summaries.filter(
|
||||||
(e) => !selectedSummaries.includes(e)
|
(e) => !selectedSummaries.includes(e)
|
||||||
@@ -1261,10 +1272,9 @@ async function hypaMemoryV3Main(
|
|||||||
availableMemoryTokens * settings.similarMemoryRatio
|
availableMemoryTokens * settings.similarMemoryRatio
|
||||||
);
|
);
|
||||||
let consumedSimilarMemoryTokens = 0;
|
let consumedSimilarMemoryTokens = 0;
|
||||||
|
const selectedSimilarSummaries: Summary[] = [];
|
||||||
|
|
||||||
if (settings.similarMemoryRatio > 0) {
|
if (settings.similarMemoryRatio > 0) {
|
||||||
const selectedSimilarSummaries: Summary[] = [];
|
|
||||||
|
|
||||||
// Utilize unused token space from recent selection
|
// Utilize unused token space from recent selection
|
||||||
if (randomMemoryRatio <= 0) {
|
if (randomMemoryRatio <= 0) {
|
||||||
const unusedRecentTokens =
|
const unusedRecentTokens =
|
||||||
@@ -1441,10 +1451,9 @@ async function hypaMemoryV3Main(
|
|||||||
availableMemoryTokens * randomMemoryRatio
|
availableMemoryTokens * randomMemoryRatio
|
||||||
);
|
);
|
||||||
let consumedRandomMemoryTokens = 0;
|
let consumedRandomMemoryTokens = 0;
|
||||||
|
const selectedRandomSummaries: Summary[] = [];
|
||||||
|
|
||||||
if (randomMemoryRatio > 0) {
|
if (randomMemoryRatio > 0) {
|
||||||
const selectedRandomSummaries: Summary[] = [];
|
|
||||||
|
|
||||||
// Utilize unused token space from recent and similar selection
|
// Utilize unused token space from recent and similar selection
|
||||||
const unusedRecentTokens =
|
const unusedRecentTokens =
|
||||||
reservedRecentMemoryTokens - consumedRecentMemoryTokens;
|
reservedRecentMemoryTokens - consumedRecentMemoryTokens;
|
||||||
@@ -1546,9 +1555,20 @@ async function hypaMemoryV3Main(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save last selected summaries
|
// Save last selected summaries
|
||||||
data.lastSelectedSummaries = selectedSummaries.map((selectedSummary) =>
|
data.metrics = {
|
||||||
data.summaries.findIndex((summary) => summary === selectedSummary)
|
lastImportantSummaries: selectedImportantSummaries.map((selected) =>
|
||||||
);
|
data.summaries.findIndex((sum) => sum === selected)
|
||||||
|
),
|
||||||
|
lastRecentSummaries: selectedRecentSummaries.map((selected) =>
|
||||||
|
data.summaries.findIndex((sum) => sum === selected)
|
||||||
|
),
|
||||||
|
lastSimilarSummaries: selectedSimilarSummaries.map((selected) =>
|
||||||
|
data.summaries.findIndex((sum) => sum === selected)
|
||||||
|
),
|
||||||
|
lastRandomSummaries: selectedRandomSummaries.map((selected) =>
|
||||||
|
data.summaries.findIndex((sum) => sum === selected)
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
const newChats: OpenAIChat[] = [
|
const newChats: OpenAIChat[] = [
|
||||||
{
|
{
|
||||||
@@ -1578,8 +1598,11 @@ async function hypaMemoryV3Main(
|
|||||||
}
|
}
|
||||||
|
|
||||||
function toHypaV3Data(serialData: SerializableHypaV3Data): HypaV3Data {
|
function toHypaV3Data(serialData: SerializableHypaV3Data): HypaV3Data {
|
||||||
|
// Remove legacy property
|
||||||
|
const { lastSelectedSummaries, ...restData } = serialData;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...serialData,
|
...restData,
|
||||||
summaries: serialData.summaries.map((summary) => ({
|
summaries: serialData.summaries.map((summary) => ({
|
||||||
...summary,
|
...summary,
|
||||||
// Convert null back to undefined (JSON serialization converts undefined to null)
|
// Convert null back to undefined (JSON serialization converts undefined to null)
|
||||||
|
|||||||
Reference in New Issue
Block a user