mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev
This commit is contained in:
@ -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">
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
})
|
||||||
});
|
});
|
Reference in New Issue
Block a user