mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Experimental ChromaDB performance improvement. Keep chat sync flags and only push new messages.
This commit is contained in:
@ -418,6 +418,7 @@ export const event_types = {
|
|||||||
MESSAGE_SENT: 'message_sent',
|
MESSAGE_SENT: 'message_sent',
|
||||||
MESSAGE_RECEIVED: 'message_received',
|
MESSAGE_RECEIVED: 'message_received',
|
||||||
MESSAGE_EDITED: 'message_edited',
|
MESSAGE_EDITED: 'message_edited',
|
||||||
|
MESSAGE_DELETED: 'message_deleted',
|
||||||
IMPERSONATE_READY: 'impersonate_ready',
|
IMPERSONATE_READY: 'impersonate_ready',
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1013,6 +1014,7 @@ function deleteLastMessage() {
|
|||||||
count_view_mes--;
|
count_view_mes--;
|
||||||
chat.length = chat.length - 1;
|
chat.length = chat.length - 1;
|
||||||
$('#chat').children('.mes').last().remove();
|
$('#chat').children('.mes').last().remove();
|
||||||
|
eventSource.emit(event_types.MESSAGE_DELETED, chat.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function reloadCurrentChat() {
|
export async function reloadCurrentChat() {
|
||||||
@ -1819,6 +1821,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
|
|||||||
$('#chat').children().last().hide(500, function () {
|
$('#chat').children().last().hide(500, function () {
|
||||||
$(this).remove();
|
$(this).remove();
|
||||||
});
|
});
|
||||||
|
eventSource.emit(event_types.MESSAGE_DELETED, chat.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4846,8 +4849,8 @@ function swipe_left() { // when we swipe left..but no generation.
|
|||||||
easing: animation_easing,
|
easing: animation_easing,
|
||||||
queue: false,
|
queue: false,
|
||||||
complete: function () {
|
complete: function () {
|
||||||
saveChatConditional();
|
|
||||||
eventSource.emit(event_types.MESSAGE_SWIPED, (chat.length - 1));
|
eventSource.emit(event_types.MESSAGE_SWIPED, (chat.length - 1));
|
||||||
|
saveChatConditional();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -5005,6 +5008,7 @@ const swipe_right = () => {
|
|||||||
easing: animation_easing,
|
easing: animation_easing,
|
||||||
queue: false,
|
queue: false,
|
||||||
complete: function () {
|
complete: function () {
|
||||||
|
eventSource.emit(event_types.MESSAGE_SWIPED, (chat.length - 1));
|
||||||
if (run_generate && !is_send_press && parseInt(chat[chat.length - 1]['swipe_id']) === chat[chat.length - 1]['swipes'].length) {
|
if (run_generate && !is_send_press && parseInt(chat[chat.length - 1]['swipe_id']) === chat[chat.length - 1]['swipes'].length) {
|
||||||
console.log('caught here 2');
|
console.log('caught here 2');
|
||||||
is_send_press = true;
|
is_send_press = true;
|
||||||
@ -5015,7 +5019,6 @@ const swipe_right = () => {
|
|||||||
saveChatConditional();
|
saveChatConditional();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
eventSource.emit(event_types.MESSAGE_SWIPED, (chat.length - 1));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -6113,6 +6116,7 @@ $(document).ready(function () {
|
|||||||
saveChatConditional();
|
saveChatConditional();
|
||||||
var $textchat = $("#chat");
|
var $textchat = $("#chat");
|
||||||
$textchat.scrollTop($textchat[0].scrollHeight);
|
$textchat.scrollTop($textchat[0].scrollHeight);
|
||||||
|
eventSource.emit(event_types.MESSAGE_DELETED, chat.length);
|
||||||
}
|
}
|
||||||
this_del_mes = 0;
|
this_del_mes = 0;
|
||||||
$('#chat .mes').last().addClass('last_mes');
|
$('#chat .mes').last().addClass('last_mes');
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { saveSettingsDebounced, getCurrentChatId, system_message_types } from "../../../script.js";
|
import { saveSettingsDebounced, getCurrentChatId, system_message_types, eventSource, event_types } from "../../../script.js";
|
||||||
import { humanizedDateTime } from "../../RossAscends-mods.js";
|
import { humanizedDateTime } from "../../RossAscends-mods.js";
|
||||||
import { getApiUrl, extension_settings, getContext } from "../../extensions.js";
|
import { getApiUrl, extension_settings, getContext } from "../../extensions.js";
|
||||||
import { getFileText, onlyUnique, splitRecursive } from "../../utils.js";
|
import { getFileText, onlyUnique, splitRecursive } from "../../utils.js";
|
||||||
@ -35,6 +35,33 @@ const postHeaders = {
|
|||||||
'Bypass-Tunnel-Reminder': 'bypass',
|
'Bypass-Tunnel-Reminder': 'bypass',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const chatStateFlags = {};
|
||||||
|
|
||||||
|
function invalidateMessageSyncState(messageId) {
|
||||||
|
console.log('CHROMADB: invalidating message sync state', messageId);
|
||||||
|
const state = getChatSyncState();
|
||||||
|
state[messageId] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChatSyncState() {
|
||||||
|
const currentChatId = getCurrentChatId();
|
||||||
|
if (!checkChatId(currentChatId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const context = getContext();
|
||||||
|
const chatState = chatStateFlags[currentChatId] || [];
|
||||||
|
chatState.length = context.chat.length;
|
||||||
|
for (let i = 0; i < chatState.length; i++) {
|
||||||
|
if (chatState[i] === undefined) {
|
||||||
|
chatState[i] = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
chatStateFlags[currentChatId] = chatState;
|
||||||
|
|
||||||
|
return chatState;
|
||||||
|
}
|
||||||
|
|
||||||
async function loadSettings() {
|
async function loadSettings() {
|
||||||
if (Object.keys(extension_settings.chromadb).length === 0) {
|
if (Object.keys(extension_settings.chromadb).length === 0) {
|
||||||
Object.assign(extension_settings.chromadb, defaultSettings);
|
Object.assign(extension_settings.chromadb, defaultSettings);
|
||||||
@ -96,20 +123,28 @@ async function addMessages(chat_id, messages) {
|
|||||||
url.pathname = '/api/chromadb';
|
url.pathname = '/api/chromadb';
|
||||||
|
|
||||||
const messagesDeepCopy = JSON.parse(JSON.stringify(messages));
|
const messagesDeepCopy = JSON.parse(JSON.stringify(messages));
|
||||||
const splittedMessages = [];
|
let splittedMessages = [];
|
||||||
|
|
||||||
let id = 0;
|
let id = 0;
|
||||||
messagesDeepCopy.forEach(m => {
|
messagesDeepCopy.forEach((m, index) => {
|
||||||
const split = splitRecursive(m.mes, extension_settings.chromadb.split_length);
|
const split = splitRecursive(m.mes, extension_settings.chromadb.split_length);
|
||||||
splittedMessages.push(...split.map(text => ({
|
splittedMessages.push(...split.map(text => ({
|
||||||
...m,
|
...m,
|
||||||
mes: text,
|
mes: text,
|
||||||
send_date: id,
|
send_date: id,
|
||||||
id: `msg-${id++}`,
|
id: `msg-${id++}`,
|
||||||
|
index: index,
|
||||||
extra: undefined,
|
extra: undefined,
|
||||||
})));
|
})));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
splittedMessages = filterSyncedMessages(splittedMessages);
|
||||||
|
|
||||||
|
// no messages to add
|
||||||
|
if (splittedMessages.length === 0) {
|
||||||
|
return { count: 0 };
|
||||||
|
}
|
||||||
|
|
||||||
const transformedMessages = splittedMessages.map((m) => ({
|
const transformedMessages = splittedMessages.map((m) => ({
|
||||||
id: m.id,
|
id: m.id,
|
||||||
role: m.is_user ? 'user' : 'assistant',
|
role: m.is_user ? 'user' : 'assistant',
|
||||||
@ -133,6 +168,37 @@ async function addMessages(chat_id, messages) {
|
|||||||
return { count: 0 };
|
return { count: 0 };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function filterSyncedMessages(splittedMessages) {
|
||||||
|
const syncState = getChatSyncState();
|
||||||
|
const removeIndices = [];
|
||||||
|
const syncedIndices = [];
|
||||||
|
for (let i = 0; i < splittedMessages.length; i++) {
|
||||||
|
const index = splittedMessages[i].index;
|
||||||
|
|
||||||
|
if (syncState[index]) {
|
||||||
|
removeIndices.push(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
syncedIndices.push(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const index of syncedIndices) {
|
||||||
|
syncState[index] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
logSyncState(syncState);
|
||||||
|
|
||||||
|
// remove messages that are already synced
|
||||||
|
return splittedMessages.filter((_, i) => !removeIndices.includes(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
function logSyncState(syncState) {
|
||||||
|
const chat = getContext().chat;
|
||||||
|
console.log('CHROMADB: sync state');
|
||||||
|
console.table(syncState.map((v, i) => ({ synced: v, name: chat[i].name, message: chat[i].mes })));
|
||||||
|
}
|
||||||
|
|
||||||
async function onPurgeClick() {
|
async function onPurgeClick() {
|
||||||
const chat_id = getCurrentChatId();
|
const chat_id = getCurrentChatId();
|
||||||
if (!checkChatId(chat_id)) {
|
if (!checkChatId(chat_id)) {
|
||||||
@ -148,6 +214,7 @@ async function onPurgeClick() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (purgeResult.ok) {
|
if (purgeResult.ok) {
|
||||||
|
delete chatStateFlags[chat_id];
|
||||||
toastr.success('ChromaDB context has been successfully cleared');
|
toastr.success('ChromaDB context has been successfully cleared');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,7 +235,7 @@ async function onExportClick() {
|
|||||||
|
|
||||||
if (exportResult.ok) {
|
if (exportResult.ok) {
|
||||||
const data = await exportResult.json();
|
const data = await exportResult.json();
|
||||||
const blob = new Blob([JSON.stringify(data, null, 2)], {type : 'application/json'});
|
const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
|
||||||
const href = URL.createObjectURL(blob);
|
const href = URL.createObjectURL(blob);
|
||||||
const link = document.createElement('a');
|
const link = document.createElement('a');
|
||||||
link.href = href;
|
link.href = href;
|
||||||
@ -198,12 +265,11 @@ async function onSelectImportFile(e) {
|
|||||||
const text = await getFileText(file);
|
const text = await getFileText(file);
|
||||||
const imported = JSON.parse(text);
|
const imported = JSON.parse(text);
|
||||||
|
|
||||||
|
|
||||||
imported.chat_id = currentChatId;
|
imported.chat_id = currentChatId;
|
||||||
|
|
||||||
const url = new URL(getApiUrl());
|
const url = new URL(getApiUrl());
|
||||||
url.pathname = '/api/chromadb/import';
|
url.pathname = '/api/chromadb/import';
|
||||||
|
|
||||||
const importResult = await fetch(url, {
|
const importResult = await fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: postHeaders,
|
headers: postHeaders,
|
||||||
@ -422,4 +488,13 @@ jQuery(async () => {
|
|||||||
$('#chromadb_purge').on('click', onPurgeClick);
|
$('#chromadb_purge').on('click', onPurgeClick);
|
||||||
$('#chromadb_export').on('click', onExportClick);
|
$('#chromadb_export').on('click', onExportClick);
|
||||||
await loadSettings();
|
await loadSettings();
|
||||||
|
|
||||||
|
// Not sure if this is needed, but it's here just in case
|
||||||
|
eventSource.on(event_types.MESSAGE_DELETED, getChatSyncState);
|
||||||
|
eventSource.on(event_types.MESSAGE_RECEIVED, getChatSyncState);
|
||||||
|
eventSource.on(event_types.MESSAGE_SENT, getChatSyncState);
|
||||||
|
// Will make the sync state update when a message is edited or swiped
|
||||||
|
eventSource.on(event_types.MESSAGE_EDITED, invalidateMessageSyncState);
|
||||||
|
eventSource.on(event_types.MESSAGE_SWIPED, invalidateMessageSyncState);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user