hypav2 working update

Everything works as intended.
when the first chat limit is reached, it succesfully summarize the previous chats according to the chunk size, and then returns the chat with summarized text as a system prompt, with other chats after that summarized point correctly appended.
Automatic sub-chunking also works perfectly.

Tested with sub-model.
This commit is contained in:
LightningHyperBlaze45654
2024-06-15 23:34:00 -07:00
parent 901d07bcf1
commit 4ef256dcf9
2 changed files with 52 additions and 68 deletions

View File

@@ -733,6 +733,7 @@ export async function sendChat(chatProcessIndex = -1,arg:{chatAdditonalTokens?:n
else if(db.hypav2){ //HypaV2 support needs to be changed like this. else if(db.hypav2){ //HypaV2 support needs to be changed like this.
const sp = await hypaMemoryV2(chats, currentTokens, maxContextTokens, currentChat, nowChatroom, tokenizer) const sp = await hypaMemoryV2(chats, currentTokens, maxContextTokens, currentChat, nowChatroom, tokenizer)
if(sp.error){ if(sp.error){
console.log(sp)
alertError(sp.error) alertError(sp.error)
return false return false
} }

View File

@@ -20,13 +20,8 @@ export interface HypaV2Data {
async function summary(stringlizedChat: string): Promise<{ success: boolean; data: string }> { async function summary(stringlizedChat: string): Promise<{ success: boolean; data: string }> {
const db = get(DataBase); const db = get(DataBase);
console.log("Summarizing with supa model: " + db.supaModelType); console.log(db.supaModelType, " is being used for Summarization task on HypaV2Memory");
/**
* Generates a summary of a given chat by using either the OpenAI API or a submodel or distilbart summarizer.
*
* @param {string} stringlizedChat - The chat to be summarized, represented as a string.
* @return {Promise<{ success: boolean; data: string }>} A promise that resolves to an object containing the success status and the generated summary.
*/
if (db.supaModelType === 'distilbart') { if (db.supaModelType === 'distilbart') {
try { try {
const sum = await runSummarizer(stringlizedChat); const sum = await runSummarizer(stringlizedChat);
@@ -46,28 +41,28 @@ async function summary(stringlizedChat: string): Promise<{ success: boolean; dat
if (db.supaModelType !== 'subModel') { if (db.supaModelType !== 'subModel') {
const promptbody = stringlizedChat + '\n\n' + supaPrompt + "\n\nOutput:"; const promptbody = stringlizedChat + '\n\n' + supaPrompt + "\n\nOutput:";
const da = await globalFetch("https://api.openai.com/v1/completions", { const da = await globalFetch("https://api.openai.com/v1/completions", {
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Authorization": "Bearer " + db.supaMemoryKey "Authorization": "Bearer " + db.supaMemoryKey
}, },
method: "POST", method: "POST",
body: { body: JSON.stringify({
"model": db.supaModelType === 'curie' ? "text-curie-001" "model": db.supaModelType === 'curie' ? "text-curie-001"
: db.supaModelType === 'instruct35' ? 'gpt-3.5-turbo-instruct' : db.supaModelType === 'instruct35' ? 'gpt-3.5-turbo-instruct' : "text-davinci-003",
: "text-davinci-003",
"prompt": promptbody, "prompt": promptbody,
"max_tokens": 600, "max_tokens": 600,
"temperature": 0 "temperature": 0
} })
}); });
console.log("Using openAI instruct 3.5 for SupaMemory") console.log("Using Chatgpt 3.5 instruct for SupaMemory");
try { try {
if (!da.ok) { if (!da.ok) {
return { return {
success: false, success: false,
data: "SupaMemory: HTTP: " + JSON.stringify(da.data) data: "SupaMemory: HTTP: " + JSON.stringify(da)
}; };
} }
@@ -76,7 +71,7 @@ async function summary(stringlizedChat: string): Promise<{ success: boolean; dat
if (!result) { if (!result) {
return { return {
success: false, success: false,
data: "SupaMemory: HTTP: " + JSON.stringify(da.data) data: "SupaMemory: HTTP: " + JSON.stringify(da)
}; };
} }
@@ -98,7 +93,7 @@ async function summary(stringlizedChat: string): Promise<{ success: boolean; dat
content: supaPrompt content: supaPrompt
} }
]; ];
console.log("Using submodel: ", db.subModel, "for supaMemory model") console.log("Using submodel: ", db.subModel, "for supaMemory model");
const da = await requestChatData({ const da = await requestChatData({
formated: promptbody, formated: promptbody,
bias: {}, bias: {},
@@ -127,10 +122,7 @@ export async function hypaMemoryV2(
): Promise<{ currentTokens: number; chats: OpenAIChat[]; error?: string; memory?: HypaV2Data; }> { ): Promise<{ currentTokens: number; chats: OpenAIChat[]; error?: string; memory?: HypaV2Data; }> {
const db = get(DataBase); const db = get(DataBase);
const data: HypaV2Data = room.hypaV2Data ?? { const data: HypaV2Data = room.hypaV2Data ?? { chunks: [], mainChunks: [] };
chunks: [],
mainChunks: []
};
let allocatedTokens = db.hypaAllocatedTokens; let allocatedTokens = db.hypaAllocatedTokens;
let chunkSize = db.hypaChunkSize; let chunkSize = db.hypaChunkSize;
@@ -138,23 +130,20 @@ export async function hypaMemoryV2(
let mainPrompt = ""; let mainPrompt = "";
// Processing mainChunks // Processing mainChunks
while(data.mainChunks.length > 0){ if (data.mainChunks.length > 0) {
const chunk = data.mainChunks[0] const chunk = data.mainChunks[0];
const ind = chats.findIndex(e => e.memo === chunk.targetId) const ind = chats.findIndex(e => e.memo === chunk.targetId);
if(ind === -1){ if (ind !== -1) {
data.mainChunks.shift() const removedChats = chats.splice(0, ind);
continue
}
const removedChats = chats.splice(0, ind)
for (const chat of removedChats) { for (const chat of removedChats) {
currentTokens -= await tokenizer.tokenizeChat(chat) currentTokens -= await tokenizer.tokenizeChat(chat);
} }
chats = chats.slice(ind) chats = chats.slice(ind);
mainPrompt = chunk.text mainPrompt = chunk.text;
const mpToken = await tokenizer.tokenizeChat({role:'system', content:mainPrompt}) const mpToken = await tokenizer.tokenizeChat({ role: 'system', content: mainPrompt });
allocatedTokens -= mpToken allocatedTokens -= mpToken;
break }
// Do not shift here; retain for continuity
} }
// Token management loop // Token management loop
@@ -170,7 +159,7 @@ export async function hypaMemoryV2(
halfData.push(chat); halfData.push(chat);
idx++; idx++;
targetId = chat.memo; targetId = chat.memo;
console.log("current target chat: ", chat) console.log("current target chat Id:", targetId);
} }
const stringlizedChat = halfData.map(e => `${e.role}: ${e.content}`).join('\n'); const stringlizedChat = halfData.map(e => `${e.role}: ${e.content}`).join('\n');
@@ -185,7 +174,7 @@ export async function hypaMemoryV2(
} }
const summaryDataToken = await tokenizer.tokenizeChat({ role: 'system', content: summaryData.data }); const summaryDataToken = await tokenizer.tokenizeChat({ role: 'system', content: summaryData.data });
mainPrompt = summaryData.data; // Ensure mainPrompt only contains the latest summary mainPrompt += `\n\n${summaryData.data}`;
currentTokens -= halfDataTokens; currentTokens -= halfDataTokens;
allocatedTokens -= summaryDataToken; allocatedTokens -= summaryDataToken;
@@ -196,9 +185,9 @@ export async function hypaMemoryV2(
if (allocatedTokens < 1000) { if (allocatedTokens < 1000) {
console.log("Currently allocatedTokens for HypaMemoryV2 is short, thus summarizing mainPrompt twice.", allocatedTokens); console.log("Currently allocatedTokens for HypaMemoryV2 is short, thus summarizing mainPrompt twice.", allocatedTokens);
console.log("This is mainPrompt(summarized data): ", mainPrompt) console.log("This is mainPrompt(summarized data): ", mainPrompt);
const summarizedMp = await summary(mainPrompt); const summarizedMp = await summary(mainPrompt);
console.log("Re-summarized, expected behavior: ", summarizedMp.data) console.log("Re-summarized, expected behavior: ", summarizedMp.data);
const mpToken = await tokenizer.tokenizeChat({ role: 'system', content: mainPrompt }); const mpToken = await tokenizer.tokenizeChat({ role: 'system', content: mainPrompt });
const summaryToken = await tokenizer.tokenizeChat({ role: 'system', content: summarizedMp.data }); const summaryToken = await tokenizer.tokenizeChat({ role: 'system', content: summarizedMp.data });
@@ -218,11 +207,7 @@ export async function hypaMemoryV2(
const processor = new HypaProcesser(db.hypaModel); const processor = new HypaProcesser(db.hypaModel);
processor.oaikey = db.supaMemoryKey; processor.oaikey = db.supaMemoryKey;
await processor.addText(data.chunks.filter(v => { await processor.addText(data.chunks.filter(v => v.text.trim().length > 0).map(v => "search_document: " + v.text.trim()));
return v.text.trim().length > 0
}).map((v) => {
return "search_document: " + v.text.trim()
}))
let scoredResults: { [key: string]: number } = {}; let scoredResults: { [key: string]: number } = {};
for (let i = 0; i < 3; i++) { for (let i = 0; i < 3; i++) {
@@ -230,39 +215,38 @@ export async function hypaMemoryV2(
if (!pop) break; if (!pop) break;
const searched = await processor.similaritySearchScored(`search_query: ${pop.content}`); const searched = await processor.similaritySearchScored(`search_query: ${pop.content}`);
for (const result of searched) { for (const result of searched) {
const score = result[1]/(i+1) const score = result[1] / (i + 1);
if(scoredResults[result[0]]){ scoredResults[result[0]] = (scoredResults[result[0]] || 0) + score;
scoredResults[result[0]] += score
}else{
scoredResults[result[0]] = score
} }
} }
const scoredArray = Object.entries(scoredResults).sort((a, b) => b[1] - a[1]); const scoredArray = Object.entries(scoredResults).sort((a, b) => b[1] - a[1]);
let chunkResultPrompts = ""; let chunkResultPrompts = "";
while(allocatedTokens > 0){ while (allocatedTokens > 0 && scoredArray.length > 0) {
const target = scoredArray.shift() const target = scoredArray.shift();
if(!target){ const tokenized = await tokenizer.tokenizeChat({ role: 'system', content: target[0].substring(14) });
break if (tokenized > allocatedTokens) break;
} chunkResultPrompts += target[0].substring(14) + '\n\n';
const tokenized = await tokenizer.tokenizeChat({ allocatedTokens -= tokenized;
role: 'system',
content: target[0].substring(14)
})
if(tokenized > allocatedTokens){
break
}
chunkResultPrompts += target[0].substring(14) + '\n\n'
allocatedTokens -= tokenized
} }
const fullResult = `<Past Events Summary>${mainPrompt}</Past Events Summary>\n<Past Events Details>${chunkResultPrompts}</Past Events Details>`; const fullResult = `<Past Events Summary>${mainPrompt}</Past Events Summary>\n<Past Events Details>${chunkResultPrompts}</Past Events Details>`;
chats.unshift({ chats.unshift({
role: "system", role: "system",
content: fullResult, content: fullResult,
memo: "supaMemory" memo: "supaMemory"
}); });
// Add the remaining chats after the last mainChunk's targetId
if (data.mainChunks.length > 0) {
const lastTargetId = data.mainChunks[0].targetId;
const lastIndex = chats.findIndex(chat => chat.memo === lastTargetId);
if (lastIndex !== -1) {
chats.push(...chats.slice(lastIndex + 1));
}
}
console.log("model being used: ", db.hypaModel, db.supaModelType, "\nCurrent session tokens: ", currentTokens, "\nAll chats, including memory system prompt: ", chats, "\nMemory data, with all the chunks: ", data); console.log("model being used: ", db.hypaModel, db.supaModelType, "\nCurrent session tokens: ", currentTokens, "\nAll chats, including memory system prompt: ", chats, "\nMemory data, with all the chunks: ", data);
return { return {
currentTokens: currentTokens, currentTokens: currentTokens,
@@ -270,4 +254,3 @@ export async function hypaMemoryV2(
memory: data memory: data
}; };
} }
}