Add advanced vector controls

This commit is contained in:
Cohee 2023-09-09 21:26:04 +03:00
parent 4cf6a1f7da
commit 2fa038f91d
3 changed files with 98 additions and 16 deletions

View File

@ -1,18 +1,21 @@
import { eventSource, event_types, extension_prompt_types, getCurrentChatId, getRequestHeaders, saveSettingsDebounced, setExtensionPrompt } from "../../../script.js";
import { eventSource, event_types, extension_prompt_types, getCurrentChatId, getRequestHeaders, saveSettingsDebounced, setExtensionPrompt, substituteParams } from "../../../script.js";
import { ModuleWorkerWrapper, extension_settings, getContext, renderExtensionTemplate } from "../../extensions.js";
import { collapseNewlines } from "../../power-user.js";
import { collapseNewlines, power_user, ui_mode } from "../../power-user.js";
import { debounce, getStringHash as calculateHash } from "../../utils.js";
const MODULE_NAME = 'vectors';
const AMOUNT_TO_LEAVE = 5;
const INSERT_AMOUNT = 3;
const QUERY_TEXT_AMOUNT = 2;
export const EXTENSION_PROMPT_TAG = '3_vectors';
const settings = {
enabled: false,
source: 'local',
template: `Past events: {{text}}`,
depth: 2,
position: extension_prompt_types.IN_PROMPT,
protect: 5,
insert: 3,
query: 2,
};
const moduleWorker = new ModuleWorkerWrapper(synchronizeChat);
@ -138,8 +141,8 @@ async function rearrangeChat(chat) {
return;
}
if (chat.length < AMOUNT_TO_LEAVE) {
console.debug(`Vectors: Not enough messages to rearrange (less than ${AMOUNT_TO_LEAVE})`);
if (chat.length < settings.protect) {
console.debug(`Vectors: Not enough messages to rearrange (less than ${settings.protect})`);
return;
}
@ -151,9 +154,9 @@ async function rearrangeChat(chat) {
}
// Get the most relevant messages, excluding the last few
const queryHashes = await queryCollection(chatId, queryText, INSERT_AMOUNT);
const queryHashes = await queryCollection(chatId, queryText, settings.insert);
const queriedMessages = [];
const retainMessages = chat.slice(-AMOUNT_TO_LEAVE);
const retainMessages = chat.slice(-settings.protect);
for (const message of chat) {
if (retainMessages.includes(message)) {
@ -181,15 +184,23 @@ async function rearrangeChat(chat) {
}
// Format queried messages into a single string
const queriedText = queriedMessages.map(x => collapseNewlines(`${x.name}: ${x.mes}`).trim()).join('\n\n');
console.log('Vectors: relevant past messages found.\n', queriedText);
const insertedText = `Past events: ${queriedText}`;
setExtensionPrompt(EXTENSION_PROMPT_TAG, insertedText, extension_prompt_types.IN_PROMPT, 0);
const insertedText = getPromptText(queriedMessages);
setExtensionPrompt(EXTENSION_PROMPT_TAG, insertedText, settings.position, settings.depth);
} catch (error) {
console.error('Vectors: Failed to rearrange chat', error);
}
}
/**
* @param {any[]} queriedMessages
* @returns {string}
*/
function getPromptText(queriedMessages) {
const queriedText = queriedMessages.map(x => collapseNewlines(`${x.name}: ${x.mes}`).trim()).join('\n\n');
console.log('Vectors: relevant past messages found.\n', queriedText);
return substituteParams(settings.template.replace(/{{text}}/i, queriedText));
}
window['vectors_rearrangeChat'] = rearrangeChat;
const onChatEvent = debounce(async () => await moduleWorker.update(), 500);
@ -209,7 +220,7 @@ function getQueryText(chat) {
i++;
}
if (i === QUERY_TEXT_AMOUNT) {
if (i === settings.query) {
break;
}
}
@ -327,6 +338,39 @@ jQuery(async () => {
Object.assign(extension_settings.vectors, settings);
saveSettingsDebounced();
});
$('#vectors_template').val(settings.template).on('input', () => {
settings.template = String($('#vectors_template').val());
Object.assign(extension_settings.vectors, settings);
saveSettingsDebounced();
});
$('#vectors_depth').val(settings.depth).on('input', () => {
settings.depth = Number($('#vectors_depth').val());
Object.assign(extension_settings.vectors, settings);
saveSettingsDebounced();
});
$('#vectors_protect').val(settings.protect).on('input', () => {
settings.protect = Number($('#vectors_protect').val());
Object.assign(extension_settings.vectors, settings);
saveSettingsDebounced();
});
$('#vectors_insert').val(settings.insert).on('input', () => {
settings.insert = Number($('#vectors_insert').val());
Object.assign(extension_settings.vectors, settings);
saveSettingsDebounced();
});
$('#vectors_query').val(settings.query).on('input', () => {
settings.query = Number($('#vectors_query').val());
Object.assign(extension_settings.vectors, settings);
saveSettingsDebounced();
});
$(`input[name="vectors_position"][value="${settings.position}"]`).prop('checked', true);
$('input[name="vectors_position"]').on('change', () => {
settings.position = Number($('input[name="vectors_position"]:checked').val());
Object.assign(extension_settings.vectors, settings);
saveSettingsDebounced();
});
$('#vectors_advanced_settings').toggleClass('displayNone', power_user.ui_mode === ui_mode.SIMPLE);
$('#vectors_vectorize_all').on('click', onVectorizeAllClick);
eventSource.on(event_types.CHAT_CHANGED, onChatEvent);

View File

@ -16,10 +16,47 @@
<option value="local">Local</option>
<option value="openai">OpenAI</option>
</select>
<div>
<div id="vectors_advanced_settings" data-newbie-hidden>
<label for="vectors_template">
Insertion template:
</label>
<textarea id="vectors_template" class="text_pole textarea_compact" rows="2" placeholder="Use {{text}} macro to specify the position of retrieved text."></textarea>
<label for="vectors_position">Injection position:</label>
<div class="radio_group">
<label>
<input type="radio" name="vectors_position" value="0" />
After Main Prompt / Story String
</label>
<label>
<input type="radio" name="vectors_position" value="1" />
In-chat @ Depth <input id="vectors_depth" class="text_pole widthUnset" type="number" min="0" max="99" />
</label>
</div>
<div class="flex-container">
<div class="flex1" title="Prevents last N messages from being placed out of order.">
<label for="vectors_protect">
<small>Retain#</small>
</label>
<input type="number" id="vectors_protect" class="text_pole widthUnset" min="1" max="99" />
</div>
<div class="flex1" title="How many last messages will be matched for relevance.">
<label for="vectors_query">
<small>Query#</small>
</label>
<input type="number" id="vectors_query" class="text_pole widthUnset" min="1" max="99" />
</div>
<div class="flex1" title="How many past messages to insert as memories.">
<label for="vectors_insert">
<small>Insert#</small>
</label>
<input type="number" id="vectors_insert" class="text_pole widthUnset" min="1" max="99" />
</div>
</div>
</div>
<small>
Old messages are vectorized gradually as you chat.
To process all previous messages, click the button below.
</div>
</small>
<div id="vectors_vectorize_all" class="menu_button menu_button_icon">
Vectorize All
</div>

View File

@ -1209,6 +1209,7 @@ input[type="file"] {
.radio_group {
display: flex;
flex-direction: column;
margin-top: 5px;
}
#extension_floating_counter {