From b4c1b37e294ce8dd11a2d153c04d35b435dba596 Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Thu, 4 May 2023 03:00:45 +0900 Subject: [PATCH 01/32] Custom colors for tags --- public/index.html | 3 ++- public/script.js | 32 ++++++++++++++++++++++---------- public/scripts/tags.js | 41 +++++++++++++++++++++++++++++++++++++---- public/style.css | 34 ++++++++++++++++++++++++++++------ 4 files changed, 89 insertions(+), 21 deletions(-) diff --git a/public/index.html b/public/index.html index c8920f70b..73bd5188c 100644 --- a/public/index.html +++ b/public/index.html @@ -1806,7 +1806,7 @@
-
+
@@ -1815,6 +1815,7 @@
+
 entries
diff --git a/public/script.js b/public/script.js index 96b2aa0e2..cff2194da 100644 --- a/public/script.js +++ b/public/script.js @@ -1055,14 +1055,14 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true const bias = messageFormating(mes.extra?.bias ?? ""); let params = { - mesId: count_view_mes, - characterName: characterName, - isUser: mes.is_user, - avatarImg: avatarImg, - bias: bias, - isSystem: isSystem, - title: title, - ...formatGenerationTimer(mes.gen_started, mes.gen_finished), + mesId: count_view_mes, + characterName: characterName, + isUser: mes.is_user, + avatarImg: avatarImg, + bias: bias, + isSystem: isSystem, + title: title, + ...formatGenerationTimer(mes.gen_started, mes.gen_finished), }; const HTMLForEachMes = getMessageFromTemplate(params); @@ -4313,7 +4313,11 @@ $(document).ready(function () { duration: 200, easing: animation_easing, }); - setTimeout(function () { $("#shadow_popup").css("display", "none"); }, 200); + setTimeout(function () { + $("#shadow_popup").css("display", "none"); + $("#dialogue_popup").removeClass('large_dialogue_popup'); + }, 200); + // $("#shadow_popup").css("opacity:", 0.0); if (popup_type == "del_bg") { delBackground(bg_file_for_del.attr("bgfile")); @@ -4421,13 +4425,16 @@ $(document).ready(function () { if (popup_type == 'input') { dialogueResolve($("#dialogue_popup_input").val()); $("#dialogue_popup_input").val(''); + } else { dialogueResolve(true); + } dialogueResolve = null; } + }); $("#dialogue_popup_cancel").click(function (e) { $("#shadow_popup").transition({ @@ -4435,7 +4442,11 @@ $(document).ready(function () { duration: 200, easing: animation_easing, }); - setTimeout(function () { $("#shadow_popup").css("display", "none"); }, 200); + setTimeout(function () { + $("#shadow_popup").css("display", "none"); + $("#dialogue_popup").removeClass('large_dialogue_popup'); + }, 200); + //$("#shadow_popup").css("opacity:", 0.0); popup_type = ""; @@ -4443,6 +4454,7 @@ $(document).ready(function () { dialogueResolve(false); dialogueResolve = null; } + }); $("#add_bg_button").change(function () { diff --git a/public/scripts/tags.js b/public/scripts/tags.js index eafd3f9db..a99e381af 100644 --- a/public/scripts/tags.js +++ b/public/scripts/tags.js @@ -153,6 +153,7 @@ function createNewTag(tagName) { const tag = { id: random_id(), name: tagName, + color: '', }; tags.push(tag); return tag; @@ -165,6 +166,10 @@ function appendTagToList(listElement, tag, { removable, editable, selectable }) let tagElement = $('#tag_template .tag').clone(); tagElement.attr('id', tag.id); + + tagElement.css('color', 'var(--SmartThemeBodyColor)'); + tagElement.css('background-color', tag.color); + tagElement.find('.tag_name').text(tag.name); const removeButton = tagElement.find(".tag_remove"); removable ? removeButton.show() : removeButton.hide(); @@ -278,7 +283,7 @@ function applyTagsOnGroupSelect() { function createTagInput(inputSelector, listSelector) { $(inputSelector) - .autocomplete({ + .autocomplete({ source: (i, o) => findTag(i, o, listSelector), select: (e, u) => selectTag(e, u, listSelector), minLength: 0, @@ -287,21 +292,37 @@ function createTagInput(inputSelector, listSelector) { } function onViewTagsListClick() { + $('#dialogue_popup').addClass('large_dialogue_popup'); const list = document.createElement('div'); const everything = Object.values(tag_map).flat(); - $(list).append('

Tags

Click on the tag name to edit it.') + $(list).append('

Tags

Click on the tag name to edit it.
'); + $(list).append('Click on color box to assign new color.

'); for (const tag of tags) { const count = everything.filter(x => x == tag.id).length; const template = $('#tag_view_template .tag_view_item').clone(); - template.attr('id', tag.id); template.find('.tag_view_counter_value').text(count); template.find('.tag_view_name').text(tag.name); + template.find('.tag_view_name').addClass('tag'); + template.find('.tag_view_name').css('background-color', tag.color); + const colorPickerId = tag.name + "-tag-color"; + template.find('.tagColorPickerHolder').html( + `` + ); + template.find('.tag-color').attr('id', colorPickerId); list.appendChild(template.get(0)); - } + setTimeout(function () { + document.querySelector(`#${colorPickerId}`).addEventListener('change', (evt) => { + onTagColorize(evt); + }); + }, 100); + + $(colorPickerId).color = tag.color; + + } callPopup(list.outerHTML, 'text'); } @@ -330,6 +351,18 @@ function onTagRenameInput() { saveSettingsDebounced(); } +function onTagColorize(evt) { + console.log(evt); + const id = $(evt.target).closest('.tag_view_item').attr('id'); + const newColor = evt.detail.rgba; + $(evt.target).parent().parent().find('.tag_view_name').css('background-color', newColor); + $(`.tag[id="${id}"]`).css('background-color', newColor); + const tag = tags.find(x => x.id === id); + tag.color = newColor; + console.log(tag); + saveSettingsDebounced(); +} + $(document).ready(() => { createTagInput('#tagInput', '#tagList'); createTagInput('#groupTagInput', '#groupTagList'); diff --git a/public/style.css b/public/style.css index 060d405cc..be9ac9a3c 100644 --- a/public/style.css +++ b/public/style.css @@ -1355,6 +1355,7 @@ input[type=search]:focus::-webkit-search-cancel-button { #dialogue_popup { width: 500px; + max-width: 90svw; position: absolute; z-index: 9999; margin-left: auto; @@ -1376,6 +1377,16 @@ input[type=search]:focus::-webkit-search-cancel-button { overflow-y: hidden; } +.large_dialogue_popup { + height: 90svh; + max-width: 90svw; +} + +.height100pSpaceEvenly { + align-content: space-evenly; + height: 100%; +} + #dialogue_popup_holder { display: flex; flex-direction: column; @@ -2438,7 +2449,7 @@ h5 { .tag_view_name { text-align: left; - flex: 2; + /* flex: 2; */ } .tag_view_counter { @@ -2448,6 +2459,7 @@ h5 { .tag_delete { padding-right: 0; + color: var(--SmartThemeBodyColor) !important; } .tag { @@ -2455,9 +2467,9 @@ h5 { border-style: solid; border-width: 1px; box-sizing: border-box; - color: var(--SmartThemeQuoteColor); + color: var(--SmartThemeBodyColor); background-color: var(--black30a); - border-color: var(--white30a); + border-color: var(--white50a); padding: 0.2rem 0.3rem; font-size: calc(var(--mainFontSize) - 5%); display: flex; @@ -2467,11 +2479,10 @@ h5 { width: fit-content; min-width: 0; text-shadow: none !important; + } -.tag.selected { - border-color: var(--white70a); -} + .tag_remove { cursor: pointer; @@ -2490,6 +2501,10 @@ h5 { margin: 5px 0; } +#tagList .tag { + opacity: 0.6; +} + .tags.tags_inline { opacity: 0.6; column-gap: 0.2rem; @@ -2517,6 +2532,13 @@ h5 { #rm_tag_filter .tag { cursor: pointer; + opacity: 0.6; + filter: brightness(0.8); +} + +.tag.selected { + opacity: 1 !important; + filter: none !important; } body .ui-autocomplete { From e639666b34a8b3c53d221e5b2ef601c7c0d94edb Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 3 May 2023 21:02:23 +0300 Subject: [PATCH 02/32] Move chat renaming logic to server side. Add "quiet" reply generation mode. --- public/script.js | 122 +++++++++++++++++++++++----------- public/scripts/group-chats.js | 19 ++++++ public/scripts/openai.js | 13 ++-- public/scripts/poe.js | 5 +- server.js | 23 +++++++ 5 files changed, 138 insertions(+), 44 deletions(-) diff --git a/public/script.js b/public/script.js index 96b2aa0e2..0a0e7d067 100644 --- a/public/script.js +++ b/public/script.js @@ -47,6 +47,7 @@ import { openGroupChat, editGroup, deleteGroupChat, + renameGroupChat, } from "./scripts/group-chats.js"; import { @@ -102,7 +103,7 @@ import { import { debounce, delay } from "./scripts/utils.js"; import { extension_settings, loadExtensionSettings } from "./scripts/extensions.js"; -import { executeSlashCommands, getSlashCommandsHelp } from "./scripts/slash-commands.js"; +import { executeSlashCommands, getSlashCommandsHelp, registerSlashCommand } from "./scripts/slash-commands.js"; import { tag_map, tags, @@ -1169,7 +1170,7 @@ function getStoppingStrings(isImpersonate, addSpace) { } function processCommands(message, type) { - if (type == "regenerate" || type == "swipe") { + if (type == "regenerate" || type == "swipe" || type == 'quiet') { return null; } @@ -1477,7 +1478,7 @@ class StreamingProcessor { } } -async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_prompt } = {}) { +async function Generate(type, { automatic_trigger, force_name2, resolve, reject, quiet_prompt } = {}) { //console.log('Generate entered'); setGenerationProgress(0); tokens_already_generated = 0; @@ -1519,19 +1520,16 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro if (online_status != 'no_connection' && this_chid != undefined && this_chid !== 'invalid-safety-id') { let textareaText; - if (type !== 'regenerate' && type !== "swipe" && !isImpersonate) { + if (type !== 'regenerate' && type !== "swipe" && type !== 'quiet' && !isImpersonate) { is_send_press = true; textareaText = $("#send_textarea").val(); - //console.log('Not a Regenerate call, so posting normall with input of: ' +textareaText); $("#send_textarea").val('').trigger('input'); - } else { - //console.log('Regenerate call detected') textareaText = ""; if (chat.length && chat[chat.length - 1]['is_user']) {//If last message from You } - else if (type !== "swipe" && !isImpersonate) { + else if (type !== 'quiet' && type !== "swipe" && !isImpersonate) { chat.length = chat.length - 1; count_view_mes -= 1; $('#chat').children().last().hide(500, function () { @@ -1584,7 +1582,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro //********************************* //PRE FORMATING STRING //********************************* - if (textareaText != "" && !automatic_trigger) { + if (textareaText != "" && !automatic_trigger && type !== 'quiet') { chat[chat.length] = {}; chat[chat.length - 1]['name'] = name1; chat[chat.length - 1]['is_user'] = true; @@ -1633,7 +1631,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro console.log(`Core/all messages: ${coreChat.length}/${chat.length}`); if (main_api === 'openai') { - setOpenAIMessages(coreChat); + setOpenAIMessages(coreChat, quiet_prompt); setOpenAIMessageExamples(mesExamplesArray); } @@ -1726,7 +1724,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro // Extension added strings const allAnchors = getAllExtensionPrompts(); const afterScenarioAnchor = getExtensionPrompt(extension_prompt_types.AFTER_SCENARIO); - const zeroDepthAnchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, 0, ' '); + let zeroDepthAnchor = getExtensionPrompt(extension_prompt_types.IN_CHAT, 0, ' '); let { worldInfoString, worldInfoBefore, worldInfoAfter } = getWorldInfoPrompt(chat2); @@ -1747,7 +1745,8 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro anchorBottom, charPersonality, promptBias, - allAnchors + allAnchors, + quiet_prompt, ].join('').replace(/\r/gm, ''); return getTokenCount(encodeString, padding_tokens) < this_max_context; } @@ -1899,7 +1898,8 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro charPersonality, generatedPromtCache, promptBias, - allAnchors + allAnchors, + quiet_prompt, ].join('').replace(/\r/gm, ''); let thisPromtContextSize = getTokenCount(prompt, padding_tokens); @@ -1968,6 +1968,11 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro } } + // Add quiet generation prompt at depth 0 + if (quiet_prompt && quiet_prompt.length) { + finalPromt += `\n${quiet_prompt}`; + } + finalPromt = finalPromt.replace(/\r/gm, ''); if (power_user.collapse_newlines) { @@ -1977,7 +1982,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro let this_amount_gen = parseInt(amount_gen); // how many tokens the AI will be requested to generate let this_settings = koboldai_settings[koboldai_setting_names[preset_settings]]; - if (isMultigenEnabled()) { + if (isMultigenEnabled() && type !== 'quiet') { // if nothing has been generated yet.. if (tokens_already_generated === 0) { // if the max gen setting is > 50...( @@ -2041,25 +2046,25 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro let prompt = await prepareOpenAIMessages(name2, storyString, worldInfoBefore, worldInfoAfter, afterScenarioAnchor, promptBias, type); setInContextMessages(openai_messages_count, type); - if (isStreamingEnabled()) { - streamingProcessor.generator = await sendOpenAIRequest(prompt, streamingProcessor.abortController.signal); + if (isStreamingEnabled() && type !== 'quiet') { + streamingProcessor.generator = await sendOpenAIRequest(type, prompt, streamingProcessor.abortController.signal); } else { - sendOpenAIRequest(prompt).then(onSuccess).catch(onError); + sendOpenAIRequest(type, prompt).then(onSuccess).catch(onError); } } else if (main_api == 'kobold' && horde_settings.use_horde) { generateHorde(finalPromt, generate_data).then(onSuccess).catch(onError); } else if (main_api == 'poe') { - if (isStreamingEnabled()) { + if (isStreamingEnabled() && type !== 'quiet') { streamingProcessor.generator = await generatePoe(type, finalPromt, streamingProcessor.abortController.signal); } else { generatePoe(type, finalPromt).then(onSuccess).catch(onError); } } - else if (main_api == 'textgenerationwebui' && textgenerationwebui_settings.streaming) { + else if (main_api == 'textgenerationwebui' && textgenerationwebui_settings.streaming && type !== 'quiet') { streamingProcessor.generator = await generateTextGenWithStreaming(generate_data, streamingProcessor.abortController.signal); } else { @@ -2078,7 +2083,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro }); //end of "if not data error" } - if (isStreamingEnabled()) { + if (isStreamingEnabled() && type !== 'quiet') { hideSwipeButtons(); let getMessage = await streamingProcessor.generate(); @@ -2103,7 +2108,6 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro } function onSuccess(data) { - is_send_press = false; if (!data.error) { //const getData = await response.json(); @@ -2113,7 +2117,7 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro //Pygmalion run again // to make it continue generating so long as it's under max_amount and hasn't signaled // an end to the character's response via typing "You:" or adding "" - if (isMultigenEnabled()) { + if (isMultigenEnabled() && type !== 'quiet') { message_already_generated += getMessage; promptBias = ''; if (shouldContinueMultigen(getMessage)) { @@ -2147,6 +2151,9 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro if (isImpersonate) { $('#send_textarea').val(getMessage).trigger('input'); } + else if (type == 'quiet') { + resolve(getMessage); + } else { if (!isMultigenEnabled()) { ({ type, getMessage } = saveReply(type, getMessage, this_mes_is_name, title)); @@ -2156,7 +2163,11 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro } } activateSendButtons(); - playMessageSound(); + + if (type !== 'quiet') { + playMessageSound(); + } + generate_loop_counter = 0; } else { ++generate_loop_counter; @@ -2189,6 +2200,10 @@ async function Generate(type, { automatic_trigger, force_name2, quiet, quiet_pro }; function onError(jqXHR, exception) { + if (type == 'quiet') { + reject(exception); + } + $("#send_textarea").removeAttr('disabled'); is_send_press = false; activateSendButtons(); @@ -2648,7 +2663,7 @@ async function saveChat(chat_name, withMetadata) { }, ...chat, ]; - jQuery.ajax({ + return jQuery.ajax({ type: "POST", url: "/savechat", data: JSON.stringify({ @@ -3764,6 +3779,7 @@ window["SillyTavern"].getContext = function () { activateSendButtons, deactivateSendButtons, saveReply, + registerSlashCommand: registerSlashCommand, }; }; @@ -4647,34 +4663,64 @@ $(document).ready(function () { $("#renameCharButton").on('click', renameCharacter); $(document).on("click", ".renameChatButton", async function () { - var old_filenamefull = $(this).closest('.select_chat_block_wrapper').find('.select_chat_block_filename').text(); - - var old_filename = old_filenamefull.substring(0, old_filenamefull.length - 6); + const old_filenamefull = $(this).closest('.select_chat_block_wrapper').find('.select_chat_block_filename').text(); + const old_filename = old_filenamefull.replace('.jsonl', ''); const popupText = `

Enter the new name for the chat:

- !!Using an existing filename will overwrite that file!!
+ !!Using an existing filename will produce an error!!
+ This will break the link between bookmark chats.
No need to add '.jsonl' at the end.
`; - let newName = await callPopup(popupText, 'input', old_filename); + const newName = await callPopup(popupText, 'input', old_filename); - if (!newName) { + if (!newName || newName == old_filename) { console.log('no new name found, aborting'); return; } - const newMetadata = { main_chat: characters[this_chid].chat }; - await saveChat(newName, newMetadata); - await saveChat(); //is this second save needed? - chat_file_for_del = old_filenamefull; - popup_type = 'del_chat'; + const body = { + is_group: !!selected_group, + avatar_url: characters[this_chid]?.avatar, + original_file: `${old_filename}.jsonl`, + renamed_file: `${newName}.jsonl`, + } - setTimeout(function () { - callPopup('Confirm Delete of Old File After Rename'); - }, 200); + try { + const response = await fetch('/renamechat', { + method: 'POST', + body: JSON.stringify(body), + headers: getRequestHeaders(), + }); + if (!response.ok) { + throw new Error('Unsuccessful request.'); + } + const data = response.json(); + if (data.error) { + throw new Error('Server returned an error.'); + } + if (selected_group) { + await renameGroupChat(selected_group, old_filename, newName); + } + else { + if (characters[this_chid].chat == old_filename) { + characters[this_chid].chat = newName; + saveCharacterDebounced(); + } + } + + reloadCurrentChat(); + + await delay(250); + $("#option_select_chat").trigger('click'); + $("#options").hide(); + } catch { + await delay(500); + await callPopup('An error has occurred. Chat was not renamed.', 'text'); + } }); $("#talkativeness_slider").on("input", function () { diff --git a/public/scripts/group-chats.js b/public/scripts/group-chats.js index f47859d2f..bac5a58e1 100644 --- a/public/scripts/group-chats.js +++ b/public/scripts/group-chats.js @@ -1159,6 +1159,25 @@ export async function openGroupChat(groupId, chatId) { await getGroupChat(groupId); } +export async function renameGroupChat(groupId, oldChatId, newChatId) { + const group = groups.find(x => x.id === groupId); + + if (!group || !group.chats.includes(oldChatId)) { + return; + } + + if (group.chat_id === oldChatId) { + group.chat_id = newChatId; + } + + group.chats.splice(group.chats.indexOf(oldChatId), 1); + group.chats.push(newChatId); + group.past_metadata[newChatId] = (group.past_metadata[oldChatId] || {}); + delete group.past_metadata[oldChatId]; + + await editGroup(groupId, true, true); +} + export async function deleteGroupChat(groupId, chatId) { const group = groups.find(x => x.id === groupId); diff --git a/public/scripts/openai.js b/public/scripts/openai.js index 617887654..92f4f0d50 100644 --- a/public/scripts/openai.js +++ b/public/scripts/openai.js @@ -144,7 +144,7 @@ function setOpenAIOnlineStatus(value) { is_get_status_openai = value; } -function setOpenAIMessages(chat) { +function setOpenAIMessages(chat, quietPrompt) { let j = 0; // clean openai msgs openai_msgs = []; @@ -176,6 +176,10 @@ function setOpenAIMessages(chat) { openai_msgs.splice(i, 0, { "role": 'system', 'content': anchor.trim() }) } } + + if (quietPrompt) { + openai_msgs.splice(0, 0, { role: 'system', content: quietPrompt }); + } } function setOpenAIMessageExamples(mesExamplesArray) { @@ -481,7 +485,7 @@ function checkQuotaError(data) { } } -async function sendOpenAIRequest(openai_msgs_tosend, signal) { +async function sendOpenAIRequest(type, openai_msgs_tosend, signal) { // Provide default abort signal if (!signal) { signal = new AbortController().signal; @@ -492,6 +496,7 @@ async function sendOpenAIRequest(openai_msgs_tosend, signal) { } let logit_bias = {}; + const stream = type !== 'quiet' && oai_settings.stream_openai; if (oai_settings.bias_preset_selected && Array.isArray(oai_settings.bias_presets[oai_settings.bias_preset_selected]) @@ -507,7 +512,7 @@ async function sendOpenAIRequest(openai_msgs_tosend, signal) { "frequency_penalty": parseFloat(oai_settings.freq_pen_openai), "presence_penalty": parseFloat(oai_settings.pres_pen_openai), "max_tokens": oai_settings.openai_max_tokens, - "stream": oai_settings.stream_openai, + "stream": stream, "reverse_proxy": oai_settings.reverse_proxy, "logit_bias": logit_bias, }; @@ -520,7 +525,7 @@ async function sendOpenAIRequest(openai_msgs_tosend, signal) { signal: signal, }); - if (oai_settings.stream_openai) { + if (stream) { return async function* streamData() { const decoder = new TextDecoder(); const reader = response.body.getReader(); diff --git a/public/scripts/poe.js b/public/scripts/poe.js index e676e06b2..41c4cb437 100644 --- a/public/scripts/poe.js +++ b/public/scripts/poe.js @@ -115,7 +115,8 @@ async function generatePoe(type, finalPrompt, signal) { console.log('Could not jailbreak the bot'); } - const isImpersonate = type == 'impersonate'; + const isImpersonate = type === 'impersonate'; + const isQuiet = type === 'quiet'; if (poe_settings.character_nudge && !isImpersonate) { let characterNudge = '\n' + substituteParams(poe_settings.character_nudge_message); @@ -136,7 +137,7 @@ async function generatePoe(type, finalPrompt, signal) { finalPrompt = sentences.join(''); } - const reply = await sendMessage(finalPrompt, true, signal); + const reply = await sendMessage(finalPrompt, !isQuiet, signal); got_reply = true; return reply; } diff --git a/server.js b/server.js index cf65b9b59..82bdab96f 100644 --- a/server.js +++ b/server.js @@ -666,6 +666,29 @@ app.post("/createcharacter", urlencodedParser, function (request, response) { } }); +app.post('/renamechat', jsonParser, async function (request, response) { + if (!request.body || !request.body.original_file || !request.body.renamed_file) { + return response.sendStatus(400); + } + + const pathToFolder = request.body.is_group + ? directories.groupChats + : path.join(directories.chats, String(request.body.avatar_url).replace('.png', '')); + const pathToOriginalFile = path.join(pathToFolder, request.body.original_file); + const pathToRenamedFile = path.join(pathToFolder, request.body.renamed_file); + console.log('Old chat name', pathToOriginalFile); + console.log('New chat name', pathToRenamedFile); + + if (!fs.existsSync(pathToOriginalFile) || fs.existsSync(pathToRenamedFile)) { + console.log('Either Source or Destination files are not available'); + return response.status(400).send({ error: true }); + } + + console.log('Successfully renamed.'); + fs.renameSync(pathToOriginalFile, pathToRenamedFile); + return response.send({ ok: true }); +}); + app.post("/renamecharacter", jsonParser, async function (request, response) { if (!request.body.avatar_url || !request.body.new_name) { return response.sendStatus(400); From 99e8d3612e35005d89664e6a24b6ae7c859df82a Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 3 May 2023 21:02:53 +0300 Subject: [PATCH 03/32] Add pre-alpha version of Stable Diffusion extension. --- .../extensions/stable-diffusion/index.js | 136 ++++++++++++++++++ .../extensions/stable-diffusion/manifest.json | 13 ++ .../extensions/stable-diffusion/style.css | 0 3 files changed, 149 insertions(+) create mode 100644 public/scripts/extensions/stable-diffusion/index.js create mode 100644 public/scripts/extensions/stable-diffusion/manifest.json create mode 100644 public/scripts/extensions/stable-diffusion/style.css diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js new file mode 100644 index 000000000..ea9719fcf --- /dev/null +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -0,0 +1,136 @@ +import { substituteParams } from "../../../script.js"; +import { getApiUrl, getContext } from "../../extensions.js"; +import { stringFormat } from "../../utils.js"; + +// Wraps a string into monospace font-face span +const m = x => `${x}`; +// Joins an array of strings with ' / ' +const j = a => a.join(' / '); + +const generationMode = { + CHARACTER: 0, + USER: 1, + SCENARIO: 2, + FREE: 3, +} + +const triggerWords = { + [generationMode.CHARACTER]: ['yourself', 'you', 'bot', 'AI', 'character'], + [generationMode.USER]: ['me', 'user', 'myself'], + [generationMode.SCENARIO]: ['scenario', 'world', 'surroundings', 'scenery'], +} + +const quietPrompts = { + [generationMode.CHARACTER]: "Please provide a detailed description of {{char}}'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.FREE]: 'Please provide a detailed and vivid description of {0}', +} + + +const helpString = [ + `${m('what')} – requests an SD generation. Supported "what" arguments:`, + '
    ', + `
  • ${m(j(triggerWords[generationMode.CHARACTER]))} – AI character image
  • `, + `
  • ${m(j(triggerWords[generationMode.USER]))} – user character image
  • `, + `
  • ${m(j(triggerWords[generationMode.SCENARIO]))} – world scenario image
  • `, + '
', + `Anything else would trigger a "free mode" with AI describing whatever you prompted.` +].join('
'); + +function getGenerationType(prompt) { + for (const [key, values] of Object.entries(triggerWords)) { + for (const value of values) { + if (value.toLowerCase() === prompt.toLowerCase().trim()) { + return key; + } + } + } + + return generationMode.FREE; +} + +function getQuietPrompt(mode, trigger) { + return substituteParams(stringFormat(quietPrompts[mode], trigger)); +} + +function processReply(str) { + str = str.replaceAll('"', '') + str = str.replaceAll('“', '') + str = str.replaceAll('\n', ' ') + str = str.trim(); + + return str; +} + +async function generatePicture(_, trigger) { + if (!trigger || trigger.trim().length === 0) { + console.log('Trigger word empty, aborting'); + return; + } + + trigger = trigger.trim(); + const generationMode = getGenerationType(trigger); + console.log('Generation mode', generationMode, 'triggered with', trigger); + const quiet_prompt = getQuietPrompt(generationMode, trigger); + const context = getContext(); + + try { + const prompt = processReply(await new Promise( + async function promptPromise(resolve, reject) { + try { + await context.generate('quiet', { resolve, reject, quiet_prompt }); + } + catch { + reject(); + } + })); + + context.deactivateSendButtons(); + + const url = new URL(getApiUrl()); + url.pathname = '/api/image'; + const result = await fetch(url, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + 'Bypass-Tunnel-Reminder': 'bypass', + }, + body: JSON.stringify({ prompt: prompt }) + }); + + if (result.ok) { + const data = await result.json(); + const base64Image = `data:image/jpeg;base64,${data.image}`; + sendMessage(prompt, base64Image); + } + } catch { + throw new Error('SD prompt text generation failed.') + } + finally { + context.activateSendButtons(); + } +} + +async function sendMessage(prompt, image) { + const context = getContext(); + const messageText = `[${context.name2} sends a picture that contains: ${prompt}]`; + const message = { + name: context.name2, + is_user: false, + is_name: true, + send_date: Date.now(), + mes: messageText, + extra: { + image: image, + title: prompt, + }, + }; + context.chat.push(message); + context.addOneMessage(message); + context.saveChat(); +} + +jQuery(() => { + getContext().registerSlashCommand('sd', generatePicture, ['picture', 'image'], helpString, true, true); +}); \ No newline at end of file diff --git a/public/scripts/extensions/stable-diffusion/manifest.json b/public/scripts/extensions/stable-diffusion/manifest.json new file mode 100644 index 000000000..13f8db021 --- /dev/null +++ b/public/scripts/extensions/stable-diffusion/manifest.json @@ -0,0 +1,13 @@ +{ + "display_name": "Stable Diffusion", + "loading_order": 10, + "requires": [ + "sd" + ], + "optional": [], + "js": "index.js", + "css": "style.css", + "author": "Cohee#1207", + "version": "1.0.0", + "homePage": "https://github.com/Cohee1207/SillyTavern" +} \ No newline at end of file diff --git a/public/scripts/extensions/stable-diffusion/style.css b/public/scripts/extensions/stable-diffusion/style.css new file mode 100644 index 000000000..e69de29bb From 437cf59a4841fa802453cfc8f447bdb37a7edf41 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 3 May 2023 23:49:57 +0300 Subject: [PATCH 04/32] Add more options to SD plugin --- public/scripts/extensions.js | 1 + .../scripts/extensions/expressions/index.js | 1 + .../extensions/stable-diffusion/index.js | 213 +++++++++++++++++- .../extensions/stable-diffusion/style.css | 3 + 4 files changed, 208 insertions(+), 10 deletions(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index a049c9319..51d412242 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -25,6 +25,7 @@ const extension_settings = { expressions: {}, dice: {}, tts: {}, + sd: {}, }; let modules = []; diff --git a/public/scripts/extensions/expressions/index.js b/public/scripts/extensions/expressions/index.js index 6e299bd21..89b789139 100644 --- a/public/scripts/extensions/expressions/index.js +++ b/public/scripts/extensions/expressions/index.js @@ -381,4 +381,5 @@ function onClickExpressionImage() { addExpressionImage(); addSettings(); setInterval(moduleWorkerWrapper, UPDATE_INTERVAL); + moduleWorkerWrapper(); })(); \ No newline at end of file diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index ea9719fcf..b17977e17 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -1,5 +1,5 @@ -import { substituteParams } from "../../../script.js"; -import { getApiUrl, getContext } from "../../extensions.js"; +import { substituteParams, saveSettingsDebounced } from "../../../script.js"; +import { getApiUrl, getContext, extension_settings, defaultRequestArgs } from "../../extensions.js"; import { stringFormat } from "../../utils.js"; // Wraps a string into monospace font-face span @@ -7,6 +7,11 @@ const m = x => `${x}`; // Joins an array of strings with ' / ' const j = a => a.join(' / '); +const postHeaders = { +'Content-Type': 'application/json', +'Bypass-Tunnel-Reminder': 'bypass', +}; + const generationMode = { CHARACTER: 0, USER: 1, @@ -27,7 +32,6 @@ const quietPrompts = { [generationMode.FREE]: 'Please provide a detailed and vivid description of {0}', } - const helpString = [ `${m('what')} – requests an SD generation. Supported "what" arguments:`, '
    ', @@ -35,9 +39,152 @@ const helpString = [ `
  • ${m(j(triggerWords[generationMode.USER]))} – user character image
  • `, `
  • ${m(j(triggerWords[generationMode.SCENARIO]))} – world scenario image
  • `, '
', - `Anything else would trigger a "free mode" with AI describing whatever you prompted.` + `Anything else would trigger a "free mode" with AI describing whatever you prompted.`, ].join('
'); +const defaultSettings = { + // CFG Scale + scale_min: 1, + scale_max: 30, + scale_step: 0.5, + scale: 7, + + // Sampler steps + steps_min: 1, + steps_max: 150, + steps_step: 1, + steps: 20, + + // Image dimensions (Width & Height) + dimension_min: 64, + dimension_max: 2048, + dimension_step: 64, + width: 512, + height: 512, + + prompt_prefix: 'best quality, absurdres, masterpiece, detailed, intricate, colorful,', + negative_prompt: 'lowres, bad anatomy, bad hands, text, error, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry', + sampler: 'DDIM', + model: '', +} + +async function loadSettings() { + if (Object.keys(extension_settings.sd).length === 0) { + Object.assign(extension_settings.sd, defaultSettings); + } + + $('#sd_scale').val(extension_settings.sd.scale).trigger('input'); + $('#sd_steps').val(extension_settings.sd.steps).trigger('input'); + $('#sd_prompt_prefix').val(extension_settings.sd.prompt_prefix).trigger('input'); + $('#sd_negative_prompt').val(extension_settings.sd.negative_prompt).trigger('input'); + $('#sd_width').val(extension_settings.sd.width).trigger('input'); + $('#sd_height').val(extension_settings.sd.height).trigger('input'); + + await Promise.all([loadSamplers, loadModels]); +} + +function onScaleInput() { + extension_settings.sd.scale = Number($('#sd_scale').val()); + $('#sd_scale_value').text(extension_settings.sd.scale.toFixed(1)); + saveSettingsDebounced(); +} + +function onStepsInput() { + extension_settings.sd.steps = Number($('#sd_steps').val()); + $('#sd_steps_value').text(extension_settings.sd.steps); + saveSettingsDebounced(); +} + +function onPromptPrefixInput() { + extension_settings.sd.prompt_prefix = $('#sd_prompt_prefix').val(); + saveSettingsDebounced(); +} + +function onNegativePromptInput() { + extension_settings.sd.negative_prompt = $('#sd_negative_prompt').val(); + saveSettingsDebounced(); +} + +function onSamplerChange() { + extension_settings.sd.sampler = $('#sd_sampler').find(':selected').val(); + saveSettingsDebounced(); +} + +function onWidthInput() { + extension_settings.sd.width = Number($('#sd_width').val()); + $('#sd_width_value').text(extension_settings.sd.width); + saveSettingsDebounced(); +} + +function onHeightInput() { + extension_settings.sd.height = Number($('#sd_height').val()); + $('#sd_height_value').text(extension_settings.sd.height); + saveSettingsDebounced(); +} + +async function onModelChange() { + extension_settings.sd.model = $('#sd_model').find(':selected').val(); + saveSettingsDebounced(); + + const url = new URL(getApiUrl()); + url.pathname = '/api/image/model'; + const getCurrentModelResult = await fetch(url, { + method: 'POST', + headers: postHeaders, + body: JSON.stringify({ model: extension_settings.sd.model }), + }); + + if (getCurrentModelResult.ok) { + console.log('Model successfully updated on SD remote.'); + } +} + +async function loadSamplers() { + const url = new URL(getApiUrl()); + url.pathname = '/api/image/samplers'; + const result = await fetch(url, defaultRequestArgs); + + if (result.ok) { + const data = await result.json(); + const samplers = data.samplers; + + for (const sampler of samplers) { + const option = document.createElement('option'); + option.innerText = sampler; + option.value = sampler; + option.selected = sampler === extension_settings.sd.sampler; + $('#sd_sampler').append(option); + } + } +} + +async function loadModels() { + const url = new URL(getApiUrl()); + url.pathname = '/api/image/model'; + const getCurrentModelResult = await fetch(url, defaultRequestArgs); + + if (getCurrentModelResult.ok) { + const data = await getCurrentModelResult.json(); + extension_settings.sd.model = data.model; + } + + url.pathname = '/api/image/models'; + const getModelsResult = await fetch(url, defaultRequestArgs); + + if (getModelsResult.ok) { + const data = await getModelsResult.json(); + const models = data.models; + + for (const model of models) { + const option = document.createElement('option'); + option.innerText = model; + option.value = model; + option.selected = model === extension_settings.sd.model; + $('#sd_model').append(option); + } + } +} + function getGenerationType(prompt) { for (const [key, values] of Object.entries(triggerWords)) { for (const value of values) { @@ -92,11 +239,18 @@ async function generatePicture(_, trigger) { url.pathname = '/api/image'; const result = await fetch(url, { method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Bypass-Tunnel-Reminder': 'bypass', - }, - body: JSON.stringify({ prompt: prompt }) + headers: postHeaders, + body: JSON.stringify({ + prompt: prompt, + sampler: extension_settings.sd.sampler, + steps: extension_settings.sd.steps, + scale: extension_settings.sd.scale, + model: extension_settings.sd.model, + width: extension_settings.sd.width, + height: extension_settings.sd.height, + prompt_prefix: extension_settings.sd.prompt_prefix, + negative_prompt: extension_settings.sd.negative_prompt, + }), }); if (result.ok) { @@ -131,6 +285,45 @@ async function sendMessage(prompt, image) { context.saveChat(); } -jQuery(() => { +jQuery(async () => { getContext().registerSlashCommand('sd', generatePicture, ['picture', 'image'], helpString, true, true); + + const settingsHtml = ` +
+
+
+ Stable Diffusion +
+
+
+ Use slash commands to generate images. Type /help in chat for more details + + + + + + + + + + + + + + + + +
+
`; + + $('#extensions_settings').append(settingsHtml); + $('#sd_scale').on('input', onScaleInput); + $('#sd_steps').on('input', onStepsInput); + $('#sd_model').on('change', onModelChange); + $('#sd_sampler').on('change', onSamplerChange); + $('#sd_prompt_prefix').on('input', onPromptPrefixInput); + $('#sd_negative_prompt').on('input', onNegativePromptInput); + $('#sd_width').on('input', onWidthInput); + $('#sd_height').on('input', onHeightInput); + await loadSettings(); }); \ No newline at end of file diff --git a/public/scripts/extensions/stable-diffusion/style.css b/public/scripts/extensions/stable-diffusion/style.css index e69de29bb..0fe6446f8 100644 --- a/public/scripts/extensions/stable-diffusion/style.css +++ b/public/scripts/extensions/stable-diffusion/style.css @@ -0,0 +1,3 @@ +.sd_settings label { + display: block; +} \ No newline at end of file From 9c62783e083985b4f77945b2f9253b3159a6a07e Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 4 May 2023 01:00:00 +0300 Subject: [PATCH 05/32] Editable slider labels --- public/index.html | 130 +++++++++++++++++++++-------- public/script.js | 43 +++++++++- public/scripts/RossAscends-mods.js | 2 +- public/scripts/utils.js | 53 +++++++++++- public/style.css | 7 +- 5 files changed, 197 insertions(+), 38 deletions(-) diff --git a/public/index.html b/public/index.html index 73bd5188c..3dc46a2e8 100644 --- a/public/index.html +++ b/public/index.html @@ -153,7 +153,9 @@
- select +
+ select +

@@ -164,7 +166,9 @@
- select +
+ select +
@@ -179,7 +183,9 @@
- select +
+ select +
@@ -190,7 +196,9 @@
- select +
+ select +
@@ -201,7 +209,9 @@
- select +
+ select +
@@ -216,7 +226,9 @@
- select +
+ select +
@@ -227,7 +239,9 @@
- select +
+ select +
@@ -238,7 +252,9 @@
- select +
+ select +
@@ -249,7 +265,9 @@
- select +
+ select +
@@ -260,7 +278,9 @@
- select +
+ select +
@@ -289,7 +309,9 @@
- select +
+ select +
@@ -309,7 +331,7 @@
- select +
select
@@ -321,7 +343,9 @@
- select +
+ select +
@@ -332,7 +356,9 @@
- select +
+ select +
@@ -388,7 +414,9 @@
- select +
+ select +
@@ -399,7 +427,9 @@
- select +
+ select +
@@ -410,7 +440,9 @@
- select +
+ select +
@@ -421,7 +453,9 @@
- select +
+ select +
@@ -432,7 +466,9 @@
- select +
+ select +
@@ -443,7 +479,9 @@
- select +
+ select +
@@ -472,7 +510,9 @@
- select +
+ select +
@@ -483,7 +523,9 @@
- select +
+ select +
@@ -494,7 +536,9 @@
- select +
+ select +
@@ -507,7 +551,9 @@
- select +
+ select +
@@ -518,7 +564,9 @@
- select +
+ select +
@@ -529,7 +577,9 @@
- select +
+ select +
@@ -578,7 +628,9 @@
- select +
+ select +
@@ -589,7 +641,9 @@
- select +
+ select +
@@ -608,7 +662,9 @@
- select +
+ select +
@@ -1149,14 +1205,14 @@

Scan Depth ?

- depth +

Token Budget ?

- budget +
@@ -1189,7 +1245,9 @@
- select +
+ select +
@@ -1200,7 +1258,9 @@
- select +
+ select +
@@ -1211,7 +1271,9 @@
- select +
+ select +
diff --git a/public/script.js b/public/script.js index 605365f21..ce3e50033 100644 --- a/public/script.js +++ b/public/script.js @@ -101,7 +101,7 @@ import { setPoeOnlineStatus, } from "./scripts/poe.js"; -import { debounce, delay } from "./scripts/utils.js"; +import { debounce, delay, restoreCaretPosition, saveCaretPosition } from "./scripts/utils.js"; import { extension_settings, loadExtensionSettings } from "./scripts/extensions.js"; import { executeSlashCommands, getSlashCommandsHelp, registerSlashCommand } from "./scripts/slash-commands.js"; import { @@ -5628,4 +5628,45 @@ $(document).ready(function () { streamingProcessor.abortController.abort(); } }); + + $(document).on('input', 'div[contenteditable="true"]', function() { + const caretPosition = saveCaretPosition($(this).get(0)); + const myText = $(this).text().trim(); + $(this).text(myText); // trim line breaks and spaces + const masterSelector = $(this).data('for'); + const masterElement = document.getElementById(masterSelector); + + if (masterElement == null) { + console.error('Master input element not found for the editable label', masterSelector); + return; + } + + const myValue = Number(myText); + + if (Number.isNaN(myValue)) { + console.warn('Label input is not a valid number. Resetting the value', myText); + $(masterElement).trigger('input'); + restoreCaretPosition($(this).get(0), caretPosition); + return; + } + + const masterMin = Number($(masterElement).attr('min')); + const masterMax = Number($(masterElement).attr('max')); + + if (myValue < masterMin) { + console.warn('Label input is less than minimum.', myText, '<', masterMin); + restoreCaretPosition($(this).get(0), caretPosition); + return; + } + + if (myValue > masterMax) { + console.warn('Label input is more than maximum.', myText, '>', masterMax); + restoreCaretPosition($(this).get(0), caretPosition); + return; + } + + console.log('Label value OK, setting to the master input control', myText); + $(masterElement).val(myValue).trigger('input'); + restoreCaretPosition($(this).get(0), caretPosition); + }); }) diff --git a/public/scripts/RossAscends-mods.js b/public/scripts/RossAscends-mods.js index 5cee16499..04b5845b0 100644 --- a/public/scripts/RossAscends-mods.js +++ b/public/scripts/RossAscends-mods.js @@ -698,7 +698,7 @@ $("document").ready(function () { function isInputElementInFocus() { //return $(document.activeElement).is(":input"); var focused = $(':focus'); - if (focused.is('input') || focused.is('textarea')) { + if (focused.is('input') || focused.is('textarea') || focused.attr('contenteditable') == 'true') { if (focused.attr('id') === 'send_textarea') { return false; } diff --git a/public/scripts/utils.js b/public/scripts/utils.js index 64bf900f2..469980ad8 100644 --- a/public/scripts/utils.js +++ b/public/scripts/utils.js @@ -110,4 +110,55 @@ export function stringFormat(format) { : match ; }); -}; \ No newline at end of file +}; + +// Save the caret position in a contenteditable element +export function saveCaretPosition(element) { + // Get the current selection + const selection = window.getSelection(); + + // If the selection is empty, return null + if (selection.rangeCount === 0) { + return null; + } + + // Get the range of the current selection + const range = selection.getRangeAt(0); + + // If the range is not within the specified element, return null + if (!element.contains(range.commonAncestorContainer)) { + return null; + } + + // Return an object with the start and end offsets of the range + const position = { + start: range.startOffset, + end: range.endOffset + }; + + console.log('Caret saved', position); + + return position; +} + +// Restore the caret position in a contenteditable element +export function restoreCaretPosition(element, position) { + // If the position is null, do nothing + if (!position) { + return; + } + + console.log('Caret restored', position); + + // Create a new range object + const range = new Range(); + + // Set the start and end positions of the range within the element + range.setStart(element.childNodes[0], position.start); + range.setEnd(element.childNodes[0], position.end); + + // Create a new selection object and set the range + const selection = window.getSelection(); + selection.removeAllRanges(); + selection.addRange(range); +} \ No newline at end of file diff --git a/public/style.css b/public/style.css index be9ac9a3c..5a7209e6c 100644 --- a/public/style.css +++ b/public/style.css @@ -1943,10 +1943,15 @@ input[type='checkbox']:not(#nav-toggle):not(#rm_button_panel_pin):not(#lm_button width: max-content; margin-left: 5px; margin-right: 15px; - font-size: calc(var(--mainFontSize) - 0.2rem); + font-size: calc(var(--mainFontSize) * 0.95); color: var(--SmartThemeBodyColor); } +.range-block-counter div[contenteditable="true"] { + display: block; + cursor: text; +} + .range-block-range { margin: 0; width: 80%; From b7e8d01694427495c5a02ec89de15d55f8df654b Mon Sep 17 00:00:00 2001 From: RossAscends <124905043+RossAscends@users.noreply.github.com> Date: Thu, 4 May 2023 16:26:49 +0900 Subject: [PATCH 06/32] AI config panel cleanup/styling - editable inputs styled - moved API model selectors from AIConfig to API Panel - nicer WI Entry footer spacing - corrected WI Entry textarea height calculations - centered send_textarea placeholder .mes_text now wraps anywhere to prevent long strings from overflowing-X - placeholders added to a few inputs --- .../NovelAI Settings/Classic-Krake.settings | 4 +- public/index.html | 594 ++++++++++-------- public/scripts/world-info.js | 2 +- public/style.css | 57 +- 4 files changed, 383 insertions(+), 274 deletions(-) diff --git a/public/NovelAI Settings/Classic-Krake.settings b/public/NovelAI Settings/Classic-Krake.settings index 8d9025b40..8ab90cdfe 100644 --- a/public/NovelAI Settings/Classic-Krake.settings +++ b/public/NovelAI Settings/Classic-Krake.settings @@ -6,8 +6,8 @@ "temperature": 1.7, "max_length": 90, "min_length": 1, - "tail_free_sampling": 0.6602, - "repetition_penalty": 1.0565, + "tail_free_sampling": 0.66, + "repetition_penalty": 1.06, "repetition_penalty_range": 340, "repetition_penalty_frequency": 0, "repetition_penalty_presence": 0 diff --git a/public/index.html b/public/index.html index 3dc46a2e8..5bc50771b 100644 --- a/public/index.html +++ b/public/index.html @@ -86,6 +86,9 @@
+
+ Click slider numbers to input manually. +
@@ -122,16 +125,6 @@
-
-

OpenAI Model

- -

Text Gen WebUI (ooba) presets

@@ -142,19 +135,25 @@

Poe.com API Settings

+
+
Response Length (tokens)
-
- -
-
-
- select +
+
+
+ +
+
+
+ select +
+
@@ -162,29 +161,37 @@
Context Size (tokens)
-
- -
-
-
- select +
+
+ +
+
+
+ select +
+
+ + +
Temperature
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -192,12 +199,14 @@
Rep. Pen.
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -205,28 +214,28 @@
Rep. Pen. Range
-
- -
-
-
- select +
+
+ +
+
+
+ select +
-
-
-
-
- Temperature -
+
+ Temperature +
+
- +
-
+
select
@@ -235,12 +244,46 @@
Rep. Pen.
-
- +
+
+ +
+
+
+ select +
+
-
-
- select +
+
+
+
+
+ Temperature +
+
+
+ +
+
+
+ select +
+
+
+
+
+
+ Rep. Pen. +
+
+
+ +
+
+
+ select +
@@ -248,12 +291,14 @@
Encoder Rep. Pen.
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -261,12 +306,14 @@
No Repeat Ngram Size
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -274,22 +321,24 @@
Min Length
-
- -
-
-
- select +
+
+ +
+
+
+ select +
-
+
OpenAI Reverse Proxy
-
+
Alternative server URL (leave empty to use the default value).
Remove your real OAI API Key from the API panel BEFORE typing anything into this box. @@ -305,12 +354,14 @@
Context Size (tokens)
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -327,24 +378,27 @@ Temperature
-
- -
-
-
select
+
+
+ +
+
+
select
+
Frequency Penalty
- -
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -352,12 +406,14 @@
Presence Penalty
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -368,7 +424,7 @@ Streaming -
+
Display bot response text chunks as they are generated.
@@ -377,7 +433,7 @@ Auto-purge API context (save JB) -
+
Delete non-JB messages from Poe context before sending a new prompt. Prevents auto-jailbreak message from being pushed out of context.
@@ -386,7 +442,7 @@ Auto-jailbreak -
+
Send the jailbreak message before first generation after page refresh.
@@ -395,14 +451,18 @@ Send character note -
+
Sent with every prompt to modify bot responses.
-
-
+
+
+
@@ -410,12 +470,14 @@
Top P
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -423,12 +485,14 @@
Top A
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -436,12 +500,14 @@
Top K
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -449,12 +515,14 @@
Typical Sampling
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -462,12 +530,14 @@
Tail Free Sampling
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -475,12 +545,14 @@
Rep. Pen. Slope
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -493,66 +565,20 @@
-

Novel AI Model - - ? - -

- -
-
- Temperature -
-
- -
-
-
- select -
-
-
-
-
- Rep. Pen. -
-
- -
-
-
- select -
-
-
-
-
- Rep. Pen. Range (tokens) -
-
- -
-
-
- select -
-
-
Top K
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -560,12 +586,14 @@
Top P
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -573,12 +601,14 @@
Typical P
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -599,7 +629,7 @@ Add BOS Token -
+
Add the bos_token to the beginning of prompts. Disabling this can make the replies more creative.
@@ -608,7 +638,7 @@ Ban EOS Token -
+
Ban the eos_token. This forces the model to never end the generation prematurely.
@@ -624,12 +654,14 @@
Number of Beams
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -637,12 +669,14 @@
Length Penalty
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -658,12 +692,14 @@
Penalty Alpha
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -687,28 +723,28 @@ NSFW first -
NSFW block goes first in the resulting prompt
+
NSFW block goes first in the resulting prompt
-
Inserts jailbreak as a last system message
+
Inserts jailbreak as a last system message
-
Enables OpenAI completion streaming
+
Enables OpenAI completion streaming
-
+
Use OAI knowledge base to enhance definitions for public figures and known fictional characters
@@ -717,7 +753,7 @@ Wrap in Quotes -
+
Wrap entire user message in quotes before sending. Leave off if you use quotes manually for speech.
@@ -731,7 +767,7 @@
-
+
The main prompt used to set the model behavior
@@ -745,7 +781,7 @@
-
+
Prompt that is used when the NSFW toggle is on
@@ -759,7 +795,7 @@
-
+
Prompt that is used when the Jailbreak toggle is on
@@ -773,7 +809,7 @@
-
+
Prompt that is used for Impersonation function
@@ -784,7 +820,7 @@
Logit Bias
-
+
Helps to ban or reenforce the usage of certain words
@@ -819,7 +855,7 @@
-
+
Message to send when auto-jailbreak is on.
@@ -833,7 +869,7 @@
-
+
Bot must send this back to confirm jailbreak
@@ -847,11 +883,11 @@
-
+
Influences bot behavior in its responses.
- +
@@ -861,11 +897,11 @@
-
+
Prompt that is used for Impersonation function
- +
@@ -875,6 +911,7 @@
+
@@ -903,7 +940,7 @@

API url

Example: http://127.0.0.1:5000/api
- +
@@ -956,6 +993,15 @@
+

Novel AI Model + + ? + +

+
@@ -1005,6 +1051,16 @@
No connection...
+
+

OpenAI Model

+ +
@@ -1241,12 +1297,14 @@
Font Scale
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -1254,12 +1312,14 @@
Blur Strength
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -1267,12 +1327,14 @@
Text Shadow Width
-
- -
-
-
- select +
+
+ +
+
+
+ select +
@@ -1436,7 +1498,7 @@

Name

- +
@@ -1930,7 +1992,7 @@
-