mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add extras summarization API, fix missing substitution of placeholders
This commit is contained in:
@ -26,6 +26,7 @@ const settings = {
|
|||||||
togetherai_model: 'togethercomputer/m2-bert-80M-32k-retrieval',
|
togetherai_model: 'togethercomputer/m2-bert-80M-32k-retrieval',
|
||||||
openai_model: 'text-embedding-ada-002',
|
openai_model: 'text-embedding-ada-002',
|
||||||
summarize: false,
|
summarize: false,
|
||||||
|
summary_source: 'main',
|
||||||
|
|
||||||
// For chats
|
// For chats
|
||||||
enabled_chats: false,
|
enabled_chats: false,
|
||||||
@ -125,6 +126,57 @@ function splitByChunks(items) {
|
|||||||
return chunkedItems;
|
return chunkedItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function summarizeExtra(hashedMessages) {
|
||||||
|
for (const element of hashedMessages) {
|
||||||
|
try {
|
||||||
|
const url = new URL(getApiUrl());
|
||||||
|
url.pathname = '/api/summarize';
|
||||||
|
|
||||||
|
const apiResult = await doExtrasFetch(url, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Bypass-Tunnel-Reminder': 'bypass',
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
text: element.text,
|
||||||
|
params: {},
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (apiResult.ok) {
|
||||||
|
const data = await apiResult.json();
|
||||||
|
element.text = data.summary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
console.log(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashedMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function summarizeMain(hashedMessages) {
|
||||||
|
const sysPrompt = 'Pause your roleplay. Summarize the most important parts of the message. Limit yourself to 250 words or less. Your response should include nothing but the summary.';
|
||||||
|
for (const element of hashedMessages) {
|
||||||
|
element.text = await generateRaw(element.text, '', false, false, sysPrompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashedMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function summarize(hashedMessages, endpoint = 'main') {
|
||||||
|
switch (endpoint) {
|
||||||
|
case 'main':
|
||||||
|
return await summarizeMain(hashedMessages);
|
||||||
|
case 'extras':
|
||||||
|
return await summarizeExtra(hashedMessages);
|
||||||
|
default:
|
||||||
|
console.error('Unsupported endpoint', endpoint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async function synchronizeChat(batchSize = 5) {
|
async function synchronizeChat(batchSize = 5) {
|
||||||
if (!settings.enabled_chats) {
|
if (!settings.enabled_chats) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -147,21 +199,20 @@ async function synchronizeChat(batchSize = 5) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const hashedMessages = context.chat.filter(x => !x.is_system).map(x => ({ text: String(x.mes), hash: getStringHash(x.mes), index: context.chat.indexOf(x) }));
|
let hashedMessages = context.chat.filter(x => !x.is_system).map(x => ({ text: String(substituteParams(x.mes)), hash: getStringHash(substituteParams(x.mes)), index: context.chat.indexOf(x) }));
|
||||||
const hashesInCollection = await getSavedHashes(chatId);
|
const hashesInCollection = await getSavedHashes(chatId);
|
||||||
|
|
||||||
|
if (settings.summarize) {
|
||||||
|
hashedMessages = await summarize(hashedMessages, settings.summary_source);
|
||||||
|
}
|
||||||
|
|
||||||
const newVectorItems = hashedMessages.filter(x => !hashesInCollection.includes(x.hash));
|
const newVectorItems = hashedMessages.filter(x => !hashesInCollection.includes(x.hash));
|
||||||
const deletedHashes = hashesInCollection.filter(x => !hashedMessages.some(y => y.hash === x));
|
const deletedHashes = hashesInCollection.filter(x => !hashedMessages.some(y => y.hash === x));
|
||||||
|
|
||||||
if (settings.summarize) {
|
|
||||||
const sysPrompt = 'Pause your roleplay. Summarize the most important parts of the message. Limit yourself to 250 words or less. Your response should include nothing but the summary.';
|
|
||||||
for (const element of hashedMessages) {
|
|
||||||
element.text = await generateRaw(element.text, '', false, false, sysPrompt);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newVectorItems.length > 0) {
|
if (newVectorItems.length > 0) {
|
||||||
const chunkedBatch = splitByChunks(newVectorItems.slice(0, batchSize));
|
const chunkedBatch = splitByChunks(newVectorItems.slice(0, batchSize));
|
||||||
|
|
||||||
console.log(`Vectors: Found ${newVectorItems.length} new items. Processing ${batchSize}...`);
|
console.log(`Vectors: Found ${newVectorItems.length} new items. Processing ${batchSize}...`);
|
||||||
await insertVectorItems(chatId, chunkedBatch);
|
await insertVectorItems(chatId, chunkedBatch);
|
||||||
}
|
}
|
||||||
@ -358,7 +409,7 @@ async function rearrangeChat(chat) {
|
|||||||
if (retainMessages.includes(message) || !message.mes) {
|
if (retainMessages.includes(message) || !message.mes) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const hash = getStringHash(message.mes);
|
const hash = getStringHash(substituteParams(message.mes));
|
||||||
if (queryHashes.includes(hash) && !insertedHashes.has(hash)) {
|
if (queryHashes.includes(hash) && !insertedHashes.has(hash)) {
|
||||||
queriedMessages.push(message);
|
queriedMessages.push(message);
|
||||||
insertedHashes.add(hash);
|
insertedHashes.add(hash);
|
||||||
@ -367,7 +418,7 @@ async function rearrangeChat(chat) {
|
|||||||
|
|
||||||
// Rearrange queried messages to match query order
|
// Rearrange queried messages to match query order
|
||||||
// Order is reversed because more relevant are at the lower indices
|
// Order is reversed because more relevant are at the lower indices
|
||||||
queriedMessages.sort((a, b) => queryHashes.indexOf(getStringHash(b.mes)) - queryHashes.indexOf(getStringHash(a.mes)));
|
queriedMessages.sort((a, b) => queryHashes.indexOf(getStringHash(substituteParams(b.mes))) - queryHashes.indexOf(getStringHash(substituteParams(a.mes))));
|
||||||
|
|
||||||
// Remove queried messages from the original chat array
|
// Remove queried messages from the original chat array
|
||||||
for (const message of chat) {
|
for (const message of chat) {
|
||||||
@ -408,13 +459,19 @@ const onChatEvent = debounce(async () => await moduleWorker.update(), 500);
|
|||||||
* @param {object[]} chat Chat messages
|
* @param {object[]} chat Chat messages
|
||||||
* @returns {string} Text to query
|
* @returns {string} Text to query
|
||||||
*/
|
*/
|
||||||
function getQueryText(chat) {
|
async function getQueryText(chat) {
|
||||||
let queryText = '';
|
let queryText = '';
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
|
||||||
for (const message of chat.slice().reverse()) {
|
let hashedMessages = chat.map(x => ({ text: String(substituteParams(x.mes)) }));
|
||||||
if (message.mes) {
|
|
||||||
queryText += message.mes + '\n';
|
if (settings.summarize) {
|
||||||
|
hashedMessages = await summarize(hashedMessages, settings.summary_source);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const message of hashedMessages.slice().reverse()) {
|
||||||
|
if (message.text) {
|
||||||
|
queryText += message.text + '\n';
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,7 +712,7 @@ async function onViewStatsClick() {
|
|||||||
|
|
||||||
const chat = getContext().chat;
|
const chat = getContext().chat;
|
||||||
for (const message of chat) {
|
for (const message of chat) {
|
||||||
if (hashesInCollection.includes(getStringHash(message.mes))) {
|
if (hashesInCollection.includes(getStringHash(substituteParams(message.mes)))) {
|
||||||
const messageElement = $(`.mes[mesid="${chat.indexOf(message)}"]`);
|
const messageElement = $(`.mes[mesid="${chat.indexOf(message)}"]`);
|
||||||
messageElement.addClass('vectorized');
|
messageElement.addClass('vectorized');
|
||||||
}
|
}
|
||||||
@ -782,6 +839,12 @@ jQuery(async () => {
|
|||||||
saveSettingsDebounced();
|
saveSettingsDebounced();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#vectors_summary_source').val(settings.togetherai_model).on('change', () => {
|
||||||
|
settings.summary_source = String($('#vectors_summary_source').val());
|
||||||
|
Object.assign(extension_settings.vectors, settings);
|
||||||
|
saveSettingsDebounced();
|
||||||
|
});
|
||||||
|
|
||||||
$('#vectors_message_chunk_size').val(settings.message_chunk_size).on('input', () => {
|
$('#vectors_message_chunk_size').val(settings.message_chunk_size).on('input', () => {
|
||||||
settings.message_chunk_size = Number($('#vectors_message_chunk_size').val());
|
settings.message_chunk_size = Number($('#vectors_message_chunk_size').val());
|
||||||
Object.assign(extension_settings.vectors, settings);
|
Object.assign(extension_settings.vectors, settings);
|
||||||
|
@ -78,10 +78,20 @@
|
|||||||
<input id="vectors_include_wi" type="checkbox" class="checkbox">
|
<input id="vectors_include_wi" type="checkbox" class="checkbox">
|
||||||
Include in World Info Scanning
|
Include in World Info Scanning
|
||||||
</label>
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<div class="flex-container flexFlowColumn">
|
||||||
<label class="checkbox_label expander" for="vectors_summarize" title="Summarize chat messages before generating embeddings.">
|
<label class="checkbox_label expander" for="vectors_summarize" title="Summarize chat messages before generating embeddings.">
|
||||||
<input id="vectors_summarize" type="checkbox" class="checkbox">
|
<input id="vectors_summarize" type="checkbox" class="checkbox">
|
||||||
Summarize chat messages
|
Summarize chat messages
|
||||||
</label>
|
</label>
|
||||||
|
<label for="vectors_summary_source">Summarize with:</label>
|
||||||
|
<select id="vectors_summary_source">
|
||||||
|
<option value="main">Main API</option>
|
||||||
|
<option value="extras">Extras API</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
|
Reference in New Issue
Block a user