diff --git a/public/css/mobile-styles.css b/public/css/mobile-styles.css
index a53758a8f..0a720b00d 100644
--- a/public/css/mobile-styles.css
+++ b/public/css/mobile-styles.css
@@ -91,7 +91,7 @@
#top-settings-holder,
#top-bar {
position: fixed;
- padding-top: 8px;
+ padding-top: 3px;
width: 100vw;
width: 100svw;
}
@@ -114,14 +114,14 @@
/* ,
#world_popup */
{
- max-height: calc(100vh - 40px);
- max-height: calc(100svh - 40px);
+ max-height: calc(100vh - 36px);
+ max-height: calc(100svh - 36px);
width: 100% !important;
margin: 0 auto;
max-width: 100%;
left: 0 !important;
resize: none !important;
- top: 40px;
+ top: 36px;
}
.wi-settings {
@@ -179,7 +179,7 @@
border-right: 1px solid var(--grey30);
border-bottom: 1px solid var(--grey30);
border-radius: 0 0 20px 20px;
- top: 40px !important;
+ top: 36px !important;
left: 0 !important;
backdrop-filter: blur(calc(var(--SmartThemeBlurStrength) * 2));
}
@@ -354,8 +354,8 @@
max-height: unset;
width: 100vw;
width: 100svw;
- height: calc(100vh - 40px);
- height: calc(100svh - 40px);
+ height: calc(100vh - 36px);
+ height: calc(100svh - 36px);
padding-right: max(env(safe-area-inset-right), 0px);
padding-left: max(env(safe-area-inset-left), 0px);
padding-bottom: 0;
@@ -396,7 +396,7 @@
#character_popup,
#world_popup,
.drawer-content {
- margin-top: 40px;
+ margin-top: 36px;
}
.scrollableInner {
@@ -407,4 +407,4 @@
#horde_model {
height: unset;
}
-}
+}
\ No newline at end of file
diff --git a/public/css/st-tailwind.css b/public/css/st-tailwind.css
index 5a0c1c52d..b505fccd6 100644
--- a/public/css/st-tailwind.css
+++ b/public/css/st-tailwind.css
@@ -349,7 +349,7 @@
}
.textarea_compact {
- font-size: calc(var(--mainFontSize) * 0.9);
+ font-size: calc(var(--mainFontSize) * 0.95);
line-height: 1.2;
}
@@ -416,4 +416,4 @@
.opacity1 {
opacity: 1 !important;
-}
\ No newline at end of file
+}
diff --git a/public/script.js b/public/script.js
index 3389cc096..dc26d9670 100644
--- a/public/script.js
+++ b/public/script.js
@@ -165,6 +165,7 @@ import {
formatInstructModeExamples,
getInstructStoppingSequences,
autoSelectInstructPreset,
+ formatInstructModeSystemPrompt,
} from "./scripts/instruct-mode.js";
import { applyLocale } from "./scripts/i18n.js";
import { getTokenCount, getTokenizerModel, saveTokenCache } from "./scripts/tokenizers.js";
@@ -322,6 +323,7 @@ let generatedPromtCache = "";
let generation_started = new Date();
let characters = [];
let this_chid;
+let saveCharactersPage = 0;
let backgrounds = [];
const default_avatar = "img/ai4.png";
export const system_avatar = "img/five.png";
@@ -893,6 +895,7 @@ async function printCharacters(fullRefresh = false) {
pageSize: Number(localStorage.getItem(storageKey)) || 50,
sizeChangerOptions: [10, 25, 50, 100, 250, 500, 1000],
pageRange: 1,
+ pageNumber: saveCharactersPage || 1,
position: 'top',
showPageNumbers: false,
showSizeChanger: true,
@@ -913,10 +916,14 @@ async function printCharacters(fullRefresh = false) {
},
afterSizeSelectorChange: function (e) {
localStorage.setItem(storageKey, e.target.value);
- }
+ },
+ afterPaging: function (e) {
+ saveCharactersPage = e;
+ },
});
favsToHotswap();
+ saveCharactersPage = 0;
if (fullRefresh) {
printTagFilters(tag_filter_types.character);
@@ -2354,6 +2361,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
if (isInstruct) {
systemPrompt = power_user.prefer_character_prompt && systemPrompt ? systemPrompt : baseChatReplace(power_user.instruct.system_prompt, name1, name2);
+ systemPrompt = formatInstructModeSystemPrompt(substituteParams(systemPrompt, name1, name2, power_user.instruct.system_prompt));
}
// Parse example messages
@@ -2733,6 +2741,12 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
// Fetches the combined prompt for both negative and positive prompts
const cfgGuidanceScale = getGuidanceScale();
function getCombinedPrompt(isNegative) {
+ // Only return if the guidance scale doesn't exist or the value is 1
+ // Also don't return if constructing the neutral prompt
+ if (isNegative && (!cfgGuidanceScale || cfgGuidanceScale?.value === 1)) {
+ return;
+ }
+
let finalMesSend = [...mesSend];
let cfgPrompt = {};
if (cfgGuidanceScale && cfgGuidanceScale?.value !== 1) {
@@ -2746,7 +2760,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
? cfgPrompt.value
: ` ${cfgPrompt.value}`;
} else {
- // TODO: Switch from splice method to insertion depth method
+ // TODO: Make all extension prompts use an array/splice method
finalMesSend.splice(mesSend.length - cfgPrompt.depth, 0, `${cfgPrompt.value}\n`);
}
}
@@ -2809,12 +2823,9 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
let finalPromt = getCombinedPrompt(false);
// Include the entire guidance scale object
- const cfgValues = {
- guidanceScale: cfgGuidanceScale,
- negativePrompt: negativePrompt
- };
+ const cfgValues = cfgGuidanceScale && cfgGuidanceScale?.value !== 1 ? ({guidanceScale: cfgGuidanceScale, negativePrompt: negativePrompt }) : null;
- let this_amount_gen = parseInt(amount_gen); // how many tokens the AI will be requested to generate
+ let this_amount_gen = Number(amount_gen); // how many tokens the AI will be requested to generate
let this_settings = koboldai_settings[koboldai_setting_names[preset_settings]];
if (isMultigenEnabled() && type !== 'quiet') {
@@ -2991,8 +3002,6 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
return;
}
- hideStopButton();
- is_send_press = false;
if (!data.error) {
//const getData = await response.json();
let getMessage = extractMessageFromData(data);
@@ -3113,6 +3122,7 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
}
if (generatedTextFiltered(getMessage)) {
console.debug('swiping right automatically');
+ is_send_press = false;
swipe_right();
return
}
@@ -3132,7 +3142,9 @@ async function Generate(type, { automatic_trigger, force_name2, resolve, reject,
}
console.debug('/savechat called by /Generate');
- saveChatConditional();
+ await saveChatConditional();
+ is_send_press = false;
+ hideStopButton();
activateSendButtons();
showSwipeButtons();
setGenerationProgress(0);
@@ -6113,7 +6125,7 @@ async function deleteMessageImage() {
delete message.extra.inline_image;
mesBlock.find('.mes_img_container').removeClass('img_extra');
mesBlock.find('.mes_img').attr('src', '');
- saveChatConditional();
+ await saveChatConditional();
}
function enlargeMessageImage() {
@@ -7908,7 +7920,7 @@ $(document).ready(function () {
});
//confirms message deletion with the "ok" button
- $("#dialogue_del_mes_ok").click(function () {
+ $("#dialogue_del_mes_ok").click(async function () {
$("#dialogue_del_mes").css("display", "none");
$("#send_form").css("display", css_send_form_display);
$(".del_checkbox").each(function () {
@@ -7924,7 +7936,7 @@ $(document).ready(function () {
$(".mes[mesid='" + this_del_mes + "']").remove();
chat.length = this_del_mes;
count_view_mes = this_del_mes;
- saveChatConditional();
+ await saveChatConditional();
var $textchat = $("#chat");
$textchat.scrollTop($textchat[0].scrollHeight);
eventSource.emit(event_types.MESSAGE_DELETED, chat.length);
@@ -8199,7 +8211,7 @@ $(document).ready(function () {
this_edit_mes_id = undefined;
});
- $(document).on("click", ".mes_edit_up", function () {
+ $(document).on("click", ".mes_edit_up", async function () {
if (is_send_press || this_edit_mes_id <= 0) {
return;
}
@@ -8224,11 +8236,11 @@ $(document).ready(function () {
this_edit_mes_id = targetId;
updateViewMessageIds();
- saveChatConditional();
+ await saveChatConditional();
showSwipeButtons();
});
- $(document).on("click", ".mes_edit_down", function () {
+ $(document).on("click", ".mes_edit_down", async function () {
if (is_send_press || this_edit_mes_id >= chat.length - 1) {
return;
}
@@ -8253,7 +8265,7 @@ $(document).ready(function () {
this_edit_mes_id = targetId;
updateViewMessageIds();
- saveChatConditional();
+ await saveChatConditional();
showSwipeButtons();
});
@@ -8277,14 +8289,14 @@ $(document).ready(function () {
addOneMessage(clone, { insertAfter: this_edit_mes_id });
updateViewMessageIds();
- saveChatConditional();
+ await saveChatConditional();
$('#chat')[0].scrollTop = oldScroll;
showSwipeButtons();
});
$(document).on("click", ".mes_edit_delete", async function (event, customData) {
const fromSlashCommand = customData?.fromSlashCommand || false;
- const swipeExists = (!chat[this_edit_mes_id].swipes || chat[this_edit_mes_id].swipes.length <= 1 || chat.is_user || parseInt(this_edit_mes_id) !== chat.length - 1);
+ const swipeExists = (!Array.isArray(chat[this_edit_mes_id].swipes) || chat[this_edit_mes_id].swipes.length <= 1 || chat[this_edit_mes_id].is_user || parseInt(this_edit_mes_id) !== chat.length - 1);
if (power_user.confirm_message_delete && fromSlashCommand !== true) {
const confirmation = swipeExists ? await callPopup("Are you sure you want to delete this message?", 'confirm')
: await callPopup("
Delete this...
", 'confirm')
@@ -8316,7 +8328,7 @@ $(document).ready(function () {
this_edit_mes_id = undefined;
updateViewMessageIds();
- saveChatConditional();
+ await saveChatConditional();
eventSource.emit(event_types.MESSAGE_DELETED, count_view_mes);
diff --git a/public/scripts/RossAscends-mods.js b/public/scripts/RossAscends-mods.js
index 1f7cdcfe9..1afb36030 100644
--- a/public/scripts/RossAscends-mods.js
+++ b/public/scripts/RossAscends-mods.js
@@ -521,7 +521,7 @@ export function dragElement(elmnt) {
}
//prevent resizing from top left into the top bar
- if (top < 40 && maxX >= topBarFirstX && left <= topBarFirstX
+ if (top < 35 && maxX >= topBarFirstX && left <= topBarFirstX
) {
console.debug('prevent topbar underlap resize')
elmnt.css('width', width - 1 + "px");
@@ -556,7 +556,7 @@ export function dragElement(elmnt) {
}
//prevent underlap with topbar div
- if (top < 40
+ if (top < 35
&& (maxX >= topBarFirstX && left <= topBarFirstX //elmnt is hitting topbar from left side
|| left <= topBarLastX && maxX >= topBarLastX //elmnt is hitting topbar from right side
|| left >= topBarFirstX && maxX <= topBarLastX) //elmnt hitting topbar in the middle
@@ -841,7 +841,7 @@ jQuery(async function () {
//this makes the chat input text area resize vertically to match the text size (limited by CSS at 50% window height)
$('#send_textarea').on('input', function () {
- this.style.height = '40px';
+ this.style.height = '30px';
this.style.height = (this.scrollHeight) + 'px';
});
diff --git a/public/scripts/extensions/cfg/index.js b/public/scripts/extensions/cfg/index.js
index c850ca6d6..f572d2c63 100644
--- a/public/scripts/extensions/cfg/index.js
+++ b/public/scripts/extensions/cfg/index.js
@@ -348,7 +348,7 @@ jQuery(async () => {
.filter(":checked")
.map(function() { return parseInt($(this).val()) })
.get()
- .filter((e) => e !== NaN) || [];
+ .filter((e) => !Number.isNaN(e)) || [];
chat_metadata[metadataKeys.prompt_combine] = values;
saveMetadataDebounced();
diff --git a/public/scripts/extensions/cfg/util.js b/public/scripts/extensions/cfg/util.js
index 850978884..6e156d5d9 100644
--- a/public/scripts/extensions/cfg/util.js
+++ b/public/scripts/extensions/cfg/util.js
@@ -39,10 +39,12 @@ export function getGuidanceScale() {
};
}
- return {
- type: cfgType.global,
- value: extension_settings.cfg.global.guidance_scale
- };
+ if (extension_settings.cfg.global && extension_settings.cfg.global?.guidance_scale !== 1) {
+ return {
+ type: cfgType.global,
+ value: extension_settings.cfg.global.guidance_scale
+ };
+ }
}
// Gets the CFG prompt
diff --git a/public/scripts/extensions/translate/index.js b/public/scripts/extensions/translate/index.js
index ac477ffe3..6a10b787d 100644
--- a/public/scripts/extensions/translate/index.js
+++ b/public/scripts/extensions/translate/index.js
@@ -217,6 +217,10 @@ async function translateProviderDeepl(text, lang) {
async function translate(text, lang) {
try {
+ if (text == '') {
+ return '';
+ }
+
switch (extension_settings.translate.provider) {
case 'google':
return await translateProviderGoogle(text, lang);
diff --git a/public/scripts/instruct-mode.js b/public/scripts/instruct-mode.js
index bc75e266d..d15274d2f 100644
--- a/public/scripts/instruct-mode.js
+++ b/public/scripts/instruct-mode.js
@@ -189,6 +189,20 @@ export function formatInstructModeChat(name, mes, isUser, isNarrator, forceAvata
return text;
}
+/**
+ * Formats instruct mode system prompt.
+ * @param {string} systemPrompt System prompt string.
+ * @returns {string} Formatted instruct mode system prompt.
+ */
+export function formatInstructModeSystemPrompt(systemPrompt){
+ if (power_user.instruct.system_sequence) {
+ const separator = power_user.instruct.wrap ? '\n' : '';
+ return power_user.instruct.system_sequence + separator + systemPrompt;
+ }
+
+ return systemPrompt;
+}
+
/**
* Formats example messages according to instruct mode settings.
* @param {string} mesExamples Example messages string.
diff --git a/public/scripts/nai-settings.js b/public/scripts/nai-settings.js
index 41fc87791..3ebc435e9 100644
--- a/public/scripts/nai-settings.js
+++ b/public/scripts/nai-settings.js
@@ -128,8 +128,8 @@ function loadNovelPreset(preset) {
function loadNovelSettings(settings) {
//load the rest of the Novel settings without any checks
nai_settings.model_novel = settings.model_novel;
- $(`#model_novel_select option[value=${nai_settings.model_novel}]`).attr("selected", true);
$('#model_novel_select').val(nai_settings.model_novel);
+ $(`#model_novel_select option[value=${nai_settings.model_novel}]`).attr("selected", true);
if (settings.nai_preamble !== undefined) {
nai_settings.preamble = settings.nai_preamble;
@@ -396,7 +396,7 @@ function getBadWordPermutations(text) {
}
export function getNovelGenerationData(finalPrompt, this_settings, this_amount_gen, isImpersonate, cfgValues) {
- if (cfgValues.guidanceScale && cfgValues.guidanceScale?.value !== 1) {
+ if (cfgValues && cfgValues.guidanceScale && cfgValues.guidanceScale?.value !== 1) {
cfgValues.negativePrompt = (getCfgPrompt(cfgValues.guidanceScale, true))?.value;
}
@@ -425,22 +425,22 @@ export function getNovelGenerationData(finalPrompt, this_settings, this_amount_g
"input": finalPrompt,
"model": nai_settings.model_novel,
"use_string": true,
- "temperature": parseFloat(nai_settings.temperature),
+ "temperature": Number(nai_settings.temperature),
"max_length": this_amount_gen < maximum_output_length ? this_amount_gen : maximum_output_length,
- "min_length": parseInt(nai_settings.min_length),
- "tail_free_sampling": parseFloat(nai_settings.tail_free_sampling),
- "repetition_penalty": parseFloat(nai_settings.repetition_penalty),
- "repetition_penalty_range": parseInt(nai_settings.repetition_penalty_range),
- "repetition_penalty_slope": parseFloat(nai_settings.repetition_penalty_slope),
- "repetition_penalty_frequency": parseFloat(nai_settings.repetition_penalty_frequency),
- "repetition_penalty_presence": parseFloat(nai_settings.repetition_penalty_presence),
- "top_a": parseFloat(nai_settings.top_a),
- "top_p": parseFloat(nai_settings.top_p),
- "top_k": parseInt(nai_settings.top_k),
- "typical_p": parseFloat(nai_settings.typical_p),
- "mirostat_lr": parseFloat(nai_settings.mirostat_lr),
- "mirostat_tau": parseFloat(nai_settings.mirostat_tau),
- "cfg_scale": cfgValues?.guidanceScale?.value ?? parseFloat(nai_settings.cfg_scale),
+ "min_length": Number(nai_settings.min_length),
+ "tail_free_sampling": Number(nai_settings.tail_free_sampling),
+ "repetition_penalty": Number(nai_settings.repetition_penalty),
+ "repetition_penalty_range": Number(nai_settings.repetition_penalty_range),
+ "repetition_penalty_slope": Number(nai_settings.repetition_penalty_slope),
+ "repetition_penalty_frequency": Number(nai_settings.repetition_penalty_frequency),
+ "repetition_penalty_presence": Number(nai_settings.repetition_penalty_presence),
+ "top_a": Number(nai_settings.top_a),
+ "top_p": Number(nai_settings.top_p),
+ "top_k": Number(nai_settings.top_k),
+ "typical_p": Number(nai_settings.typical_p),
+ "mirostat_lr": Number(nai_settings.mirostat_lr),
+ "mirostat_tau": Number(nai_settings.mirostat_tau),
+ "cfg_scale": cfgValues?.guidanceScale?.value ?? Number(nai_settings.cfg_scale),
"cfg_uc": cfgValues?.negativePrompt ?? nai_settings.cfg_uc ?? "",
"phrase_rep_pen": nai_settings.phrase_rep_pen,
"stop_sequences": stopSequences,
@@ -448,7 +448,6 @@ export function getNovelGenerationData(finalPrompt, this_settings, this_amount_g
"logit_bias_exp": logitBias,
"generate_until_sentence": true,
"use_cache": false,
- "use_string": true,
"return_full_text": false,
"prefix": prefix,
"order": nai_settings.order || this_settings.order || default_order,
@@ -640,7 +639,7 @@ export async function generateNovelWithStreaming(generate_data, signal) {
}
$("#nai_preamble_textarea").on('input', function () {
- nai_settings.preamble = $('#nai_preamble_textarea').val();
+ nai_settings.preamble = String($('#nai_preamble_textarea').val());
saveSettingsDebounced();
});
@@ -668,7 +667,7 @@ jQuery(function () {
});
$("#model_novel_select").change(function () {
- nai_settings.model_novel = $("#model_novel_select").find(":selected").val();
+ nai_settings.model_novel = String($("#model_novel_select").find(":selected").val());
saveSettingsDebounced();
// Update the selected preset to something appropriate
@@ -679,12 +678,12 @@ jQuery(function () {
});
$("#nai_prefix").on('change', function () {
- nai_settings.prefix = $("#nai_prefix").find(":selected").val();
+ nai_settings.prefix = String($("#nai_prefix").find(":selected").val());
saveSettingsDebounced();
});
$("#phrase_rep_pen_novel").on('change', function () {
- nai_settings.phrase_rep_pen = $("#phrase_rep_pen_novel").find(":selected").val();
+ nai_settings.phrase_rep_pen = String($("#phrase_rep_pen_novel").find(":selected").val());
saveSettingsDebounced();
});
diff --git a/public/scripts/openai.js b/public/scripts/openai.js
index aef41beb8..e85506649 100644
--- a/public/scripts/openai.js
+++ b/public/scripts/openai.js
@@ -165,6 +165,7 @@ const default_settings = {
new_group_chat_prompt: default_new_group_chat_prompt,
new_example_chat_prompt: default_new_example_chat_prompt,
continue_nudge_prompt: default_continue_nudge_prompt,
+ nsfw_avoidance_prompt: default_nsfw_avoidance_prompt,
bias_preset_selected: default_bias,
bias_presets: default_bias_presets,
wi_format: default_wi_format,
@@ -228,6 +229,7 @@ const oai_settings = {
use_ai21_tokenizer: false,
exclude_assistant: false,
use_alt_scale: false,
+ nsfw_avoidance_prompt: default_nsfw_avoidance_prompt,
};
let openai_setting_names;
@@ -772,6 +774,7 @@ function preparePromptsForChatCompletion(Scenario, charPersonality, name2, world
* @param {string} content.bias - The bias to be added in the conversation.
* @param {string} content.type - The type of the chat, can be 'impersonate'.
* @param {string} content.quietPrompt - The quiet prompt to be used in the conversation.
+ * @param {string} content.cyclePrompt - The last prompt used for chat message continuation.
* @param {Array} content.extensionPrompts - An array of additional prompts.
* @param dryRun - Whether this is a live call or not.
* @returns {(*[]|boolean)[]} An array where the first element is the prepared chat and the second element is a boolean flag.
@@ -882,7 +885,7 @@ async function sendWindowAIRequest(openai_msgs_tosend, signal, stream) {
let finished = false;
const currentModel = await window.ai.getCurrentModel();
- let temperature = parseFloat(oai_settings.temp_openai);
+ let temperature = Number(oai_settings.temp_openai);
if ((currentModel.includes('claude') || currentModel.includes('palm-2')) && temperature > claude_max_temp) {
console.warn(`Claude and PaLM models only supports temperature up to ${claude_max_temp}. Clamping ${temperature} to ${claude_max_temp}.`);
@@ -1014,7 +1017,7 @@ function saveModelList(data) {
$('#model_openrouter_select').empty();
$('#model_openrouter_select').append($('