This commit is contained in:
RossAscends
2023-05-05 03:03:36 +09:00
6 changed files with 134 additions and 34 deletions

View File

@ -1257,19 +1257,50 @@
<div id="world_info_edit_button" class="menu_button fa-solid fa-pencil" title="Details"></div> <div id="world_info_edit_button" class="menu_button fa-solid fa-pencil" title="Details"></div>
</div> </div>
<div id="world_info_depth_block"> <div class="flex-container alignitemscenter">
<h4> <div class="flex1 range-block">
Scan Depth <a href="/notes#scandepth" class="notes-link" target="_blank"><span class="note-link-span">?</span></a> <div class="range-block-title">
</h4> Scan Depth <a href="/notes#scandepth" class="notes-link" target="_blank"><span class="note-link-span">?</span></a>
<label for="world_info_depth" id="world_info_depth_counter">depth</label> </div>
<input type="range" id="world_info_depth" name="volume" min="1" max="10" step="1"> <div class="range-block-range-and-counter">
</div> <div class="range-block-range">
<div id="world_info_budget_block"> <input type="range" id="world_info_depth" name="volume" min="1" max="10" step="1">
<h4> </div>
Token Budget <a href="/notes#budget" class="notes-link" target="_blank"><span class="note-link-span">?</span></a> <div class="range-block-counter">
</h4> <div contenteditable="true" data-for="world_info_depth" id="world_info_depth_counter">
<label for="world_info_budget" id="world_info_budget_counter">budget</label> depth
<input type="range" id="world_info_budget" name="volume" min="32" max="2048" step="16"> </div>
</div>
</div>
</div>
<div class="flex1 range-block">
<div class="range-block-title">
Token Budget <a href="/notes#budget" class="notes-link" target="_blank"><span class="note-link-span">?</span></a>
</div>
<div class="range-block-range-and-counter">
<div class="range-block-range">
<input type="range" id="world_info_budget" name="volume" min="32" max="2048" step="16">
</div>
<div class="range-block-counter">
<div contenteditable="true" data-for="world_info_budget" id="world_info_budget_counter">
budget
</div>
</div>
</div>
</div>
<div class="flex1 range-block">
<label title="Entries can activate other entries by mentioning their keywords" class="checkbox_label">
<input id="world_info_recursive" type="checkbox" />
<span>
Recursive scanning
<a href="/notes#recursivescanning" class="notes-link" target="_blank">
<span class="note-link-span">?</span>
</a>
</span>
</label>
</div>
</div> </div>
</div> </div>
<div id="softprompt_block"> <div id="softprompt_block">

View File

@ -213,6 +213,26 @@ Constant entries will be inserted first. Then entries with higher order numbers.
Entries inserted by direct mentioning of their keys have higher priority than those that were mentioned in other entries contents. Entries inserted by direct mentioning of their keys have higher priority than those that were mentioned in other entries contents.
### Recursive scanning
**Entries can activate other entries by mentioning their keywords in the content text.**
For example, if your World Info contains two entries:
```
Entry #1
Keyword: Bessie
Content: Bessie is a cow and is friend with Rufus.
```
```
Entry #2
Keyword: Rufus
Content: Rufus is a dog.
```
**Both** of them will be pulled into the context if the message text mentions **just Bessie**.
## KoboldAI ## KoboldAI
### Basic Settings ### Basic Settings

View File

@ -24,6 +24,7 @@ import {
selectImportedWorldInfo, selectImportedWorldInfo,
setWorldInfoSettings, setWorldInfoSettings,
deleteWorldInfo, deleteWorldInfo,
world_info_recursive,
} from "./scripts/world-info.js"; } from "./scripts/world-info.js";
import { import {
@ -193,7 +194,7 @@ let converter;
reloadMarkdownProcessor(); reloadMarkdownProcessor();
/* let bg_menu_toggle = false; */ /* let bg_menu_toggle = false; */
const systemUserName = "SillyTavern System"; export const systemUserName = "SillyTavern System";
let default_user_name = "You"; let default_user_name = "You";
let name1 = default_user_name; let name1 = default_user_name;
let name2 = "SillyTavern System"; let name2 = "SillyTavern System";
@ -1191,8 +1192,7 @@ function getStoppingStrings(isImpersonate, addSpace) {
} }
} }
return addSpace ? result.map(x => `${result} `) : result; return addSpace ? result.map(x => `${x} `) : result;
} }
function processCommands(message, type) { function processCommands(message, type) {
@ -1540,7 +1540,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
} }
if (selected_group && !is_group_generating) { if (selected_group && !is_group_generating) {
generateGroupWrapper(false, type); generateGroupWrapper(false, type, null, { resolve, reject, quiet_prompt });
return; return;
} }
@ -2415,7 +2415,7 @@ function cleanUpMessage(getMessage, isImpersonate) {
// trailing invisible whitespace before every newlines, on a multiline string // trailing invisible whitespace before every newlines, on a multiline string
// "trailing whitespace on newlines \nevery line of the string \n?sample text" -> // "trailing whitespace on newlines \nevery line of the string \n?sample text" ->
// "trailing whitespace on newlines\nevery line of the string\nsample text" // "trailing whitespace on newlines\nevery line of the string\nsample text"
getMessage = getMessage.replace(/\s+$/gm, ""); getMessage = getMessage.replace(/[^\S\r\n]+$/gm, "");
if (is_pygmalion) { if (is_pygmalion) {
getMessage = getMessage.replace(/<USER>/g, name1); getMessage = getMessage.replace(/<USER>/g, name1);
getMessage = getMessage.replace(/<BOT>/g, name2); getMessage = getMessage.replace(/<BOT>/g, name2);
@ -3193,6 +3193,7 @@ async function saveSettings(type) {
world_info: world_info, world_info: world_info,
world_info_depth: world_info_depth, world_info_depth: world_info_depth,
world_info_budget: world_info_budget, world_info_budget: world_info_budget,
world_info_recursive: world_info_recursive,
textgenerationwebui_settings: textgenerationwebui_settings, textgenerationwebui_settings: textgenerationwebui_settings,
swipes: swipes, swipes: swipes,
horde_settings: horde_settings, horde_settings: horde_settings,

View File

@ -1,4 +1,10 @@
import { substituteParams, saveSettingsDebounced } from "../../../script.js"; import {
substituteParams,
saveSettingsDebounced,
systemUserName,
hideSwipeButtons,
showSwipeButtons
} from "../../../script.js";
import { getApiUrl, getContext, extension_settings, defaultRequestArgs } from "../../extensions.js"; import { getApiUrl, getContext, extension_settings, defaultRequestArgs } from "../../extensions.js";
import { stringFormat } from "../../utils.js"; import { stringFormat } from "../../utils.js";
@ -6,6 +12,8 @@ import { stringFormat } from "../../utils.js";
const m = x => `<span class="monospace">${x}</span>`; const m = x => `<span class="monospace">${x}</span>`;
// Joins an array of strings with ' / ' // Joins an array of strings with ' / '
const j = a => a.join(' / '); const j = a => a.join(' / ');
// Wraps a string into paragraph block
const p = a => `<p>${a}</p>`
const postHeaders = { const postHeaders = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
@ -26,10 +34,10 @@ const triggerWords = {
} }
const quietPrompts = { const quietPrompts = {
[generationMode.CHARACTER]: "Please provide a detailed description of {{char}}'s appearance", [generationMode.CHARACTER]: "[Please provide a detailed description of {{char}}'s appearance]",
[generationMode.USER]: "Please provide a detailed description of {{user}}'s appearance", [generationMode.USER]: "[Please provide a detailed description of {{user}}'s appearance]",
[generationMode.SCENARIO]: 'Please provide a detailed description of your surroundings and what you are doing right now', [generationMode.SCENARIO]: '[Please provide a detailed description of your surroundings and what you are doing right now]',
[generationMode.FREE]: 'Please provide a detailed and vivid description of {0}', [generationMode.FREE]: '[Please provide a detailed and vivid description of {0}]',
} }
const helpString = [ const helpString = [
@ -234,6 +242,7 @@ async function generatePicture(_, trigger) {
})); }));
context.deactivateSendButtons(); context.deactivateSendButtons();
hideSwipeButtons();
const url = new URL(getApiUrl()); const url = new URL(getApiUrl());
url.pathname = '/api/image'; url.pathname = '/api/image';
@ -258,11 +267,13 @@ async function generatePicture(_, trigger) {
const base64Image = `data:image/jpeg;base64,${data.image}`; const base64Image = `data:image/jpeg;base64,${data.image}`;
sendMessage(prompt, base64Image); sendMessage(prompt, base64Image);
} }
} catch { } catch (err) {
console.error(err);
throw new Error('SD prompt text generation failed.') throw new Error('SD prompt text generation failed.')
} }
finally { finally {
context.activateSendButtons(); context.activateSendButtons();
showSwipeButtons();
} }
} }
@ -270,11 +281,12 @@ async function sendMessage(prompt, image) {
const context = getContext(); const context = getContext();
const messageText = `[${context.name2} sends a picture that contains: ${prompt}]`; const messageText = `[${context.name2} sends a picture that contains: ${prompt}]`;
const message = { const message = {
name: context.name2, name: context.groupId ? systemUserName : context.name2,
is_system: context.groupId ? true : false,
is_user: false, is_user: false,
is_name: true, is_name: true,
send_date: Date.now(), send_date: Date.now(),
mes: messageText, mes: context.groupId ? p(messageText) : messageText,
extra: { extra: {
image: image, image: image,
title: prompt, title: prompt,

View File

@ -375,7 +375,7 @@ function getGroupAvatar(group) {
} }
async function generateGroupWrapper(by_auto_mode, type = null, force_chid = null) { async function generateGroupWrapper(by_auto_mode, type = null, force_chid = null, params = {}) {
if (online_status === "no_connection") { if (online_status === "no_connection") {
is_group_generating = false; is_group_generating = false;
setSendButtonState(false); setSendButtonState(false);
@ -423,6 +423,7 @@ async function generateGroupWrapper(by_auto_mode, type = null, force_chid = null
let lastMessageText = lastMessage.mes; let lastMessageText = lastMessage.mes;
let activationText = ""; let activationText = "";
let isUserInput = false; let isUserInput = false;
let isQuietGenDone = false;
if (userInput && userInput.length && !by_auto_mode) { if (userInput && userInput.length && !by_auto_mode) {
isUserInput = true; isUserInput = true;
@ -439,6 +440,23 @@ async function generateGroupWrapper(by_auto_mode, type = null, force_chid = null
if (typeof force_chid == 'number') { if (typeof force_chid == 'number') {
activatedMembers = [force_chid]; activatedMembers = [force_chid];
} else if (type === "quiet") {
activatedMembers = activateSwipe(group.members);
if (activatedMembers.length === 0) {
activatedMembers = activateListOrder(group.members.slice(0, 1));
}
const resolveOriginal = params.resolve;
const rejectOriginal = params.reject;
params.resolve = function() {
isQuietGenDone = true;
resolveOriginal.apply(this, arguments);
};
params.reject = function() {
isQuietGenDone = true;
rejectOriginal.apply(this, arguments);
}
} }
else if (type === "swipe") { else if (type === "swipe") {
activatedMembers = activateSwipe(group.members); activatedMembers = activateSwipe(group.members);
@ -461,11 +479,11 @@ async function generateGroupWrapper(by_auto_mode, type = null, force_chid = null
// now the real generation begins: cycle through every character // now the real generation begins: cycle through every character
for (const chId of activatedMembers) { for (const chId of activatedMembers) {
const generateType = type == "swipe" || type == "impersonate" ? type : "group_chat"; const generateType = type == "swipe" || type == "impersonate" || type == "quiet" ? type : "group_chat";
setCharacterId(chId); setCharacterId(chId);
setCharacterName(characters[chId].name) setCharacterName(characters[chId].name)
await Generate(generateType, { automatic_trigger: by_auto_mode }); await Generate(generateType, { automatic_trigger: by_auto_mode, ...(params || {}) });
if (type !== "swipe" && type !== "impersonate") { if (type !== "swipe" && type !== "impersonate") {
// update indicator and scroll down // update indicator and scroll down
@ -520,6 +538,13 @@ async function generateGroupWrapper(by_auto_mode, type = null, force_chid = null
} }
} }
} }
else if (type === 'quiet') {
if (isQuietGenDone) {
break;
} else {
await delay(100);
}
}
else { else {
messagesBefore++; messagesBefore++;
break; break;

View File

@ -6,6 +6,7 @@ export {
world_info_data, world_info_data,
world_info_budget, world_info_budget,
world_info_depth, world_info_depth,
world_info_recursive,
world_names, world_names,
imported_world_name, imported_world_name,
checkWorldInfo, checkWorldInfo,
@ -21,6 +22,7 @@ let world_info_data = null;
let world_info_depth = 2; let world_info_depth = 2;
let world_info_budget = 128; let world_info_budget = 128;
let is_world_edit_open = false; let is_world_edit_open = false;
let world_info_recursive = false;
let imported_world_name = ""; let imported_world_name = "";
const saveWorldDebounced = debounce(async () => await _save(), 500); const saveWorldDebounced = debounce(async () => await _save(), 500);
const saveSettingsDebounced = debounce(() => saveSettings(), 500); const saveSettingsDebounced = debounce(() => saveSettings(), 500);
@ -47,13 +49,17 @@ function setWorldInfoSettings(settings, data) {
world_info_depth = Number(settings.world_info_depth); world_info_depth = Number(settings.world_info_depth);
if (settings.world_info_budget !== undefined) if (settings.world_info_budget !== undefined)
world_info_budget = Number(settings.world_info_budget); world_info_budget = Number(settings.world_info_budget);
if (settings.world_info_recursive !== undefined)
world_info_recursive = Boolean(settings.world_info_recursive);
$("#world_info_depth_counter").html(`${world_info_depth} Messages`); $("#world_info_depth_counter").text(world_info_depth);
$("#world_info_depth").val(world_info_depth); $("#world_info_depth").val(world_info_depth);
$("#world_info_budget_counter").html(`${world_info_budget} Tokens`); $("#world_info_budget_counter").text(world_info_budget);
$("#world_info_budget").val(world_info_budget); $("#world_info_budget").val(world_info_budget);
$("#world_info_recursive").prop('checked', world_info_recursive);
world_names = data.world_names?.length ? data.world_names : []; world_names = data.world_names?.length ? data.world_names : [];
if (settings.world_info != undefined) { if (settings.world_info != undefined) {
@ -524,7 +530,7 @@ function checkWorldInfo(chat) {
} }
} }
needsToScan = activatedNow.size > 0; needsToScan = world_info_recursive && activatedNow.size > 0;
const newEntries = [...activatedNow] const newEntries = [...activatedNow]
.map((x) => world_info_data.entries[x]) .map((x) => world_info_data.entries[x])
.sort((a, b) => sortedEntries.indexOf(a) - sortedEntries.indexOf(b)); .sort((a, b) => sortedEntries.indexOf(a) - sortedEntries.indexOf(b));
@ -665,13 +671,18 @@ $(document).ready(() => {
$(document).on("input", "#world_info_depth", function () { $(document).on("input", "#world_info_depth", function () {
world_info_depth = Number($(this).val()); world_info_depth = Number($(this).val());
$("#world_info_depth_counter").html(`${$(this).val()} Messages`); $("#world_info_depth_counter").text($(this).val());
saveSettingsDebounced(); saveSettingsDebounced();
}); });
$(document).on("input", "#world_info_budget", function () { $(document).on("input", "#world_info_budget", function () {
world_info_budget = Number($(this).val()); world_info_budget = Number($(this).val());
$("#world_info_budget_counter").html(`${$(this).val()} Tokens`); $("#world_info_budget_counter").text($(this).val());
saveSettingsDebounced(); saveSettingsDebounced();
}); });
$(document).on("input", "#world_info_recursive", function () {
world_info_recursive = !!$(this).prop('checked');
saveSettingsDebounced();
})
}); });