Add advanced vector controls
This commit is contained in:
parent
4cf6a1f7da
commit
2fa038f91d
|
@ -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 { 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";
|
import { debounce, getStringHash as calculateHash } from "../../utils.js";
|
||||||
|
|
||||||
const MODULE_NAME = 'vectors';
|
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';
|
export const EXTENSION_PROMPT_TAG = '3_vectors';
|
||||||
|
|
||||||
const settings = {
|
const settings = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
source: 'local',
|
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);
|
const moduleWorker = new ModuleWorkerWrapper(synchronizeChat);
|
||||||
|
@ -138,8 +141,8 @@ async function rearrangeChat(chat) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chat.length < AMOUNT_TO_LEAVE) {
|
if (chat.length < settings.protect) {
|
||||||
console.debug(`Vectors: Not enough messages to rearrange (less than ${AMOUNT_TO_LEAVE})`);
|
console.debug(`Vectors: Not enough messages to rearrange (less than ${settings.protect})`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,9 +154,9 @@ async function rearrangeChat(chat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the most relevant messages, excluding the last few
|
// 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 queriedMessages = [];
|
||||||
const retainMessages = chat.slice(-AMOUNT_TO_LEAVE);
|
const retainMessages = chat.slice(-settings.protect);
|
||||||
|
|
||||||
for (const message of chat) {
|
for (const message of chat) {
|
||||||
if (retainMessages.includes(message)) {
|
if (retainMessages.includes(message)) {
|
||||||
|
@ -181,15 +184,23 @@ async function rearrangeChat(chat) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format queried messages into a single string
|
// Format queried messages into a single string
|
||||||
const queriedText = queriedMessages.map(x => collapseNewlines(`${x.name}: ${x.mes}`).trim()).join('\n\n');
|
const insertedText = getPromptText(queriedMessages);
|
||||||
console.log('Vectors: relevant past messages found.\n', queriedText);
|
setExtensionPrompt(EXTENSION_PROMPT_TAG, insertedText, settings.position, settings.depth);
|
||||||
const insertedText = `Past events: ${queriedText}`;
|
|
||||||
setExtensionPrompt(EXTENSION_PROMPT_TAG, insertedText, extension_prompt_types.IN_PROMPT, 0);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Vectors: Failed to rearrange chat', 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;
|
window['vectors_rearrangeChat'] = rearrangeChat;
|
||||||
|
|
||||||
const onChatEvent = debounce(async () => await moduleWorker.update(), 500);
|
const onChatEvent = debounce(async () => await moduleWorker.update(), 500);
|
||||||
|
@ -209,7 +220,7 @@ function getQueryText(chat) {
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i === QUERY_TEXT_AMOUNT) {
|
if (i === settings.query) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -327,6 +338,39 @@ jQuery(async () => {
|
||||||
Object.assign(extension_settings.vectors, settings);
|
Object.assign(extension_settings.vectors, settings);
|
||||||
saveSettingsDebounced();
|
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);
|
$('#vectors_vectorize_all').on('click', onVectorizeAllClick);
|
||||||
|
|
||||||
eventSource.on(event_types.CHAT_CHANGED, onChatEvent);
|
eventSource.on(event_types.CHAT_CHANGED, onChatEvent);
|
||||||
|
|
|
@ -16,10 +16,47 @@
|
||||||
<option value="local">Local</option>
|
<option value="local">Local</option>
|
||||||
<option value="openai">OpenAI</option>
|
<option value="openai">OpenAI</option>
|
||||||
</select>
|
</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.
|
Old messages are vectorized gradually as you chat.
|
||||||
To process all previous messages, click the button below.
|
To process all previous messages, click the button below.
|
||||||
</div>
|
</small>
|
||||||
<div id="vectors_vectorize_all" class="menu_button menu_button_icon">
|
<div id="vectors_vectorize_all" class="menu_button menu_button_icon">
|
||||||
Vectorize All
|
Vectorize All
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1209,6 +1209,7 @@ input[type="file"] {
|
||||||
.radio_group {
|
.radio_group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#extension_floating_counter {
|
#extension_floating_counter {
|
||||||
|
|
Loading…
Reference in New Issue