refactor: extract repeated summarization logic into retryableSummarize function
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
import { alertConfirm, showHypaV3Alert } from "../../ts/alert";
|
||||
import { DBState, alertStore, selectedCharID } from "src/ts/stores.svelte";
|
||||
import { summarize } from "src/ts/process/memory/hypav3";
|
||||
import { type OpenAIChat } from "src/ts/process/index.svelte";
|
||||
import { translateHTML } from "src/ts/translator/translator";
|
||||
|
||||
interface SummaryUI {
|
||||
@@ -131,19 +132,18 @@
|
||||
|
||||
try {
|
||||
const summary = hypaV3DataState.summaries[summaryIndex];
|
||||
const toSummarize = summary.chatMemos.map((chatMemo) => {
|
||||
const toSummarize: OpenAIChat[] = summary.chatMemos.map((chatMemo) => {
|
||||
const message = getMessageFromChatMemo(chatMemo);
|
||||
|
||||
return {
|
||||
...message,
|
||||
role: message.role === "char" ? "assistant" : message.role,
|
||||
role: (message.role === "char"
|
||||
? "assistant"
|
||||
: message.role) as OpenAIChat["role"],
|
||||
content: message.data,
|
||||
};
|
||||
});
|
||||
|
||||
const stringifiedChats = toSummarize
|
||||
.map((m) => `${m.role}: ${m.data}`)
|
||||
.join("\n");
|
||||
const summarizeResult = await summarize(stringifiedChats);
|
||||
const summarizeResult = await summarize(toSummarize);
|
||||
|
||||
if (summarizeResult.success) {
|
||||
summaryUIState.rerolledText = summarizeResult.data;
|
||||
|
||||
@@ -39,6 +39,10 @@ interface SummaryChunk {
|
||||
summary: Summary;
|
||||
}
|
||||
|
||||
const minChatsForSimilarity = 3;
|
||||
const maxSummarizationFailures = 3;
|
||||
const summarySeparator = "\n\n";
|
||||
|
||||
// Helper function to check if one Set is a subset of another
|
||||
function isSubset(subset: Set<string>, superset: Set<string>): boolean {
|
||||
for (const elem of subset) {
|
||||
@@ -92,9 +96,12 @@ function cleanOrphanedSummary(chats: OpenAIChat[], data: HypaV3Data): void {
|
||||
}
|
||||
|
||||
export async function summarize(
|
||||
stringifiedChats: string
|
||||
oaiChats: OpenAIChat[]
|
||||
): Promise<{ success: boolean; data: string }> {
|
||||
const db = getDatabase();
|
||||
const stringifiedChats = oaiChats
|
||||
.map((chat) => `${chat.role}: ${chat.content}`)
|
||||
.join("\n");
|
||||
|
||||
if (db.supaModelType === "distilbart") {
|
||||
try {
|
||||
@@ -216,6 +223,37 @@ export async function summarize(
|
||||
}
|
||||
}
|
||||
|
||||
async function retryableSummarize(
|
||||
oaiChats: OpenAIChat[]
|
||||
): Promise<{ success: boolean; data: string }> {
|
||||
let summarizationFailures = 0;
|
||||
|
||||
while (summarizationFailures < maxSummarizationFailures) {
|
||||
console.log(
|
||||
"[HypaV3] Attempting summarization:",
|
||||
"\nAttempt: ",
|
||||
summarizationFailures + 1,
|
||||
"\nTarget: ",
|
||||
oaiChats
|
||||
);
|
||||
|
||||
const summarizeResult = await summarize(oaiChats);
|
||||
|
||||
if (!summarizeResult.success) {
|
||||
console.log("[HypaV3] Summarization failed: ", summarizeResult.data);
|
||||
summarizationFailures++;
|
||||
|
||||
if (summarizationFailures >= maxSummarizationFailures) {
|
||||
return summarizeResult;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
return summarizeResult;
|
||||
}
|
||||
}
|
||||
|
||||
export async function hypaMemoryV3(
|
||||
chats: OpenAIChat[],
|
||||
currentTokens: number,
|
||||
@@ -229,9 +267,6 @@ export async function hypaMemoryV3(
|
||||
error?: string;
|
||||
memory?: SerializableHypaV3Data;
|
||||
}> {
|
||||
const minChatsForSimilarity = 3;
|
||||
const maxSummarizationFailures = 3;
|
||||
const summarySeparator = "\n\n";
|
||||
const db = getDatabase();
|
||||
|
||||
// Validate settings
|
||||
@@ -396,47 +431,23 @@ export async function hypaMemoryV3(
|
||||
}
|
||||
|
||||
// Attempt summarization
|
||||
let summarizationFailures = 0;
|
||||
const stringifiedChats = toSummarize
|
||||
.map((chat) => `${chat.role}: ${chat.content}`)
|
||||
.join("\n");
|
||||
const summarizeResult = await retryableSummarize(toSummarize);
|
||||
|
||||
while (summarizationFailures < maxSummarizationFailures) {
|
||||
console.log(
|
||||
"[HypaV3] Attempting summarization:",
|
||||
"\nAttempt: ",
|
||||
summarizationFailures + 1,
|
||||
"\nTarget: ",
|
||||
toSummarize
|
||||
);
|
||||
|
||||
const summarizeResult = await summarize(stringifiedChats);
|
||||
|
||||
if (!summarizeResult.success) {
|
||||
console.log("[HypaV3] Summarization failed: ", summarizeResult.data);
|
||||
summarizationFailures++;
|
||||
|
||||
if (summarizationFailures >= maxSummarizationFailures) {
|
||||
return {
|
||||
currentTokens,
|
||||
chats,
|
||||
error: `[HypaV3] Summarization failed after maximum retries: ${summarizeResult.data}`,
|
||||
memory: toSerializableHypaV3Data(data),
|
||||
};
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
data.summaries.push({
|
||||
text: summarizeResult.data,
|
||||
chatMemos: new Set(toSummarize.map((chat) => chat.memo)),
|
||||
isImportant: false,
|
||||
});
|
||||
|
||||
break;
|
||||
if (!summarizeResult.success) {
|
||||
return {
|
||||
currentTokens,
|
||||
chats,
|
||||
error: `[HypaV3] Summarization failed after maximum retries: ${summarizeResult.data}`,
|
||||
memory: toSerializableHypaV3Data(data),
|
||||
};
|
||||
}
|
||||
|
||||
data.summaries.push({
|
||||
text: summarizeResult.data,
|
||||
chatMemos: new Set(toSummarize.map((chat) => chat.memo)),
|
||||
isImportant: false,
|
||||
});
|
||||
|
||||
currentTokens -= toSummarizeTokens;
|
||||
startIdx = endIdx;
|
||||
}
|
||||
@@ -611,56 +622,33 @@ export async function hypaMemoryV3(
|
||||
|
||||
// (2) Summarized recent chat search
|
||||
if (db.hypaV3Settings.enableSimilarityCorrection) {
|
||||
let summarizationFailures = 0;
|
||||
// Attempt summarization
|
||||
const recentChats = chats.slice(-minChatsForSimilarity);
|
||||
const stringifiedRecentChats = recentChats
|
||||
.map((chat) => `${chat.role}: ${chat.content}`)
|
||||
.join("\n");
|
||||
const summarizeResult = await retryableSummarize(recentChats);
|
||||
|
||||
while (summarizationFailures < maxSummarizationFailures) {
|
||||
console.log(
|
||||
"[HypaV3] Attempting summarization:",
|
||||
"\nAttempt: ",
|
||||
summarizationFailures + 1,
|
||||
"\nTarget: ",
|
||||
recentChats
|
||||
);
|
||||
|
||||
const summarizeResult = await summarize(stringifiedRecentChats);
|
||||
|
||||
if (!summarizeResult.success) {
|
||||
console.log("[HypaV3] Summarization failed: ", summarizeResult.data);
|
||||
summarizationFailures++;
|
||||
|
||||
if (summarizationFailures >= maxSummarizationFailures) {
|
||||
return {
|
||||
currentTokens,
|
||||
chats,
|
||||
error: `[HypaV3] Summarization failed after maximum retries: ${summarizeResult.data}`,
|
||||
memory: toSerializableHypaV3Data(data),
|
||||
};
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const searched = await processor.similaritySearchScoredEx(
|
||||
summarizeResult.data
|
||||
);
|
||||
|
||||
for (const [chunk, similarity] of searched) {
|
||||
const summary = chunk.summary;
|
||||
|
||||
scoredSummaries.set(
|
||||
summary,
|
||||
(scoredSummaries.get(summary) || 0) + similarity
|
||||
);
|
||||
}
|
||||
|
||||
console.log("[HypaV3] Similarity corrected.");
|
||||
|
||||
break;
|
||||
if (!summarizeResult.success) {
|
||||
return {
|
||||
currentTokens,
|
||||
chats,
|
||||
error: `[HypaV3] Summarization failed after maximum retries: ${summarizeResult.data}`,
|
||||
memory: toSerializableHypaV3Data(data),
|
||||
};
|
||||
}
|
||||
|
||||
const searched = await processor.similaritySearchScoredEx(
|
||||
summarizeResult.data
|
||||
);
|
||||
|
||||
for (const [chunk, similarity] of searched) {
|
||||
const summary = chunk.summary;
|
||||
|
||||
scoredSummaries.set(
|
||||
summary,
|
||||
(scoredSummaries.get(summary) || 0) + similarity
|
||||
);
|
||||
}
|
||||
|
||||
console.log("[HypaV3] Similarity corrected.");
|
||||
}
|
||||
|
||||
// Sort in descending order
|
||||
|
||||
Reference in New Issue
Block a user