From 5bea179f3b72ad3e442fc7999fc4321d0b03f741 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 23 Feb 2023 15:07:05 +0200 Subject: [PATCH 01/56] Update GPT tokenizer Fixes being unable to tokenize words like constructor/toString/etc --- public/scripts/gpt-2-3-tokenizer/README.md | 6 +++--- public/scripts/gpt-2-3-tokenizer/mod.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/public/scripts/gpt-2-3-tokenizer/README.md b/public/scripts/gpt-2-3-tokenizer/README.md index f09949a58..616eba077 100644 --- a/public/scripts/gpt-2-3-tokenizer/README.md +++ b/public/scripts/gpt-2-3-tokenizer/README.md @@ -5,20 +5,20 @@ GPT-2/3 byte pair encoder/decoder/tokenizer based on [@latitudegames/GPT-3-Encod See also: [JS byte pair encoder for OpenAI's CLIP model](https://github.com/josephrocca/clip-bpe-js). ```js -import {encode, decode} from "https://deno.land/x/gpt_2_3_tokenizer@v0.0.1/mod.js"; +import {encode, decode} from "https://deno.land/x/gpt_2_3_tokenizer@v0.0.2/mod.js"; let text = "hello world"; console.log(encode(text)); // [258, 18798, 995] console.log(decode(encode(text))); // "hello world" ``` or: ```js -let mod = await import("https://deno.land/x/gpt_2_3_tokenizer@v0.0.1/mod.js"); +let mod = await import("https://deno.land/x/gpt_2_3_tokenizer@v0.0.2/mod.js"); mod.encode("hello world"); // [258, 18798, 995] ``` or to include it as a global variable in the browser: ```html ``` diff --git a/public/scripts/gpt-2-3-tokenizer/mod.js b/public/scripts/gpt-2-3-tokenizer/mod.js index 622f5ab61..c325ce3a2 100644 --- a/public/scripts/gpt-2-3-tokenizer/mod.js +++ b/public/scripts/gpt-2-3-tokenizer/mod.js @@ -81,7 +81,7 @@ const bpe_ranks = dictZip(bpe_merges, range(0, bpe_merges.length)) const cache = {} function bpe(token) { - if (token in cache) { + if (Object.hasOwn(cache, token)) { return cache[token] } @@ -107,7 +107,7 @@ function bpe(token) { } ))] - if (!(bigram in bpe_ranks)) { + if (!(Object.hasOwn(bpe_ranks, bigram))) { break } From 82566e1163cfc7d7f38dfb0859f9dd59bfe45f76 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Mon, 27 Feb 2023 01:57:10 +0200 Subject: [PATCH 02/56] Add group chats creation --- public/img/minus-solid.svg | 1 + public/img/plus-solid.svg | 1 + public/img/user-group-solid.svg | 1 + public/index.html | 361 +++++++++++++++++++++++++++++++- public/style.css | 154 +++++++++++++- server.js | 113 +++++++++- 6 files changed, 624 insertions(+), 7 deletions(-) create mode 100644 public/img/minus-solid.svg create mode 100644 public/img/plus-solid.svg create mode 100644 public/img/user-group-solid.svg diff --git a/public/img/minus-solid.svg b/public/img/minus-solid.svg new file mode 100644 index 000000000..f3a20d000 --- /dev/null +++ b/public/img/minus-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/plus-solid.svg b/public/img/plus-solid.svg new file mode 100644 index 000000000..637f19613 --- /dev/null +++ b/public/img/plus-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/img/user-group-solid.svg b/public/img/user-group-solid.svg new file mode 100644 index 000000000..b9c841345 --- /dev/null +++ b/public/img/user-group-solid.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/index.html b/public/index.html index 4d7d29f6f..508a5587b 100644 --- a/public/index.html +++ b/public/index.html @@ -62,6 +62,8 @@ var mesStr = ''; var generatedPromtCache = ''; var characters = []; + let groups = []; + let selected_group = null; var this_chid; var backgrounds = []; var default_avatar = 'img/fluffy.png'; @@ -72,6 +74,7 @@ const system_message_types = { HELP: 'help', WELCOME: 'welcome', + GROUP: 'group', }; const system_messages = { @@ -83,6 +86,14 @@ "is_name":true, "mes": "Hi there! The following chat formatting commands are supported in TavernAI:

Need more help? Visit our wiki – TavernAI Wiki!

" }, + 'group': { + "name": systemUserName, + "force_avatar": "img/chloe.png", + "is_user":false, + "is_system": true, + "is_name": true, + "mes": "Group chat created. Say 'Hi' to lovely people!" + } }; const world_info_position = { @@ -106,6 +117,7 @@ var timerSaveEdit; var timerWorldSave; + var timerGroupSave; var durationSaveEdit = 200; //animation right menu var animation_rm_duration = 200; @@ -433,11 +445,16 @@ $("#rm_print_characters_block").prepend('
'+item.name+'
'); //console.log(item.name); }); - - + for (let group of groups) { + const template = $('#group_list_template .group_select').clone(); + template.data('id', group.id); + template.find('.avatar img').attr('src', group.avatar_url); + template.find('.ch_name').html(group.name); + $('#rm_print_characters_block').prepend(template); + } } async function getCharacters() { - + await getGroups(); const response = await fetch("/getcharacters", { method: "POST", headers: { @@ -1491,7 +1508,7 @@ //maybe a way to simulate this would be to disable the eventListener for people iOS. $("#send_textarea").keydown(function (e) { - if(e.which === 13 && e.shiftKey && is_send_press == false) { + if(e.which === 13 && !e.shiftKey && is_send_press == false) { is_send_press = true; e.preventDefault(); Generate(); @@ -1520,6 +1537,7 @@ $( "#rm_ch_create_block" ).css("display", "none"); $( "#rm_info_block" ).css("display", "none"); + $("#rm_group_chats_block").css("display", "none"); $( "#rm_button_characters" ).children("h2").css(deselected_button_style); $( "#rm_button_settings" ).children("h2").css(selected_button_style); @@ -1541,6 +1559,280 @@ selected_button = 'character_edit'; select_selected_character(this_chid); }); + $(document).on('click', '.group_select', async function() { + const id = $(this).data('id'); + selected_button = 'group_chats'; + + if (selected_group !== id){ + if(!is_send_press){ + selected_group = id; + this_edit_mes_id = undefined; + clearChat(); + chat.length = 0; + await getGroupChat(id); + } + } + + select_group_chats(id); + }); + $("#rm_button_group_chats").click(function() { + selected_button = 'group_chats'; + select_group_chats(); + }); + $( "#rm_button_back_from_group" ).click(function() { + selected_button = 'characters'; + select_rm_characters(); + }); + $('#rm_group_filter').on('input', function() { + const searchValue = $(this).val().trim().toLowerCase(); + + if (!searchValue) { + $("#rm_group_add_members .group_member").show(); + } else { + $("#rm_group_add_members .group_member").each(function () { + $(this).children('.ch_name').text().toLowerCase().includes(searchValue) + ? $(this).show() + : $(this).hide(); + }); + } + }); + $('#rm_group_submit').click(async function() { + let name = $('#rm_group_chat_name').val(); + const members = $('#rm_group_members .group_member').map((_, x) => $(x).data('id')).toArray(); + + if (!name) { + name = `Chat with ${members.join(', ')}`; + } + + // placeholder + const avatar_url = '/img/five.png'; + + const createGroupResponse = await fetch('/creategroup', { + method: 'POST', + headers: { + "Content-Type": "application/json", + "X-CSRF-Token": token, + }, + body: JSON.stringify({ name: name, members: members, avatar_url: avatar_url }), + }); + + if (createGroupResponse.ok) { + const createGroupData = await createGroupResponse.json(); + const id = createGroupData.id; + + await getCharacters(); + $('#rm_info_avatar').html(''); + var avatar = $('#avatar_div_div').clone(); + avatar.find('img').attr('src', avatar_url); + $('#rm_info_avatar').append(avatar); + $('#rm_info_block').transition({ opacity: 0 ,duration: 0}); + select_rm_info("Group chat created"); + $('#rm_info_block').transition({ opacity: 1.0 ,duration: 2000}); + } + }); + async function getGroupChat(id) { + const response = await fetch('/getgroupchat', { + method: 'POST', + headers: { + "Content-Type": "application/json", + "X-CSRF-Token": token, + }, + body: JSON.stringify({ id: id }), + }); + + if (response.ok) { + const data = await response.json(); + if(Array.isArray(data) && data.length) { + for (let key of data) { + chat.push(key); + } + printMessages(); + } + else { + sendSystemMessage(system_message_types.GROUP); + } + + await saveGroupChat(id); + } + } + async function saveGroupChat(id) { + const response = await fetch('/savegroupchat', { + method: 'POST', + headers: { + "Content-Type": "application/json", + "X-CSRF-Token": token, + }, + body: JSON.stringify({id: id, chat: [...chat]}) + }); + } + async function getGroups() { + const response = await fetch('/getgroups', { + method: 'POST', + headers: { + "Content-Type": "application/json", + "X-CSRF-Token": token, + }, + }); + + if (response.ok) { + const data = await response.json(); + groups = data.sort((a,b) => a.id - b.id); + } + } + async function deleteGroup(id) { + const response = await fetch('/deletegroup', { + method: 'POST', + headers: { + "Content-Type": "application/json", + "X-CSRF-Token": token, + }, + body: JSON.stringify({id : id}), + }); + + if (response.ok) { + await getCharacters(); + $('#rm_info_avatar').html(''); + $('#rm_info_block').transition({ opacity: 0 ,duration: 0}); + select_rm_info("Group deleted!"); + $('#rm_info_block').transition({ opacity: 1.0 ,duration: 2000}); + } + + } + async function editGroup(id, immediately) { + const group = groups.find(x => x.id == id); + + if (!group) { + return; + } + + async function _save() { + const response = await fetch('/editgroup', { + method: 'POST', + headers: { + "Content-Type": "application/json", + "X-CSRF-Token": token, + }, + body: JSON.stringify(group), + }); + } + + if (immediately) { + return await _save(); + } + + clearTimeout(timerGroupSave); + timerGroupSave = setTimeout(async () => await _save(), durationSaveEdit); + } + + function select_group_chats(chat_id) { + menu_type = 'group_chats'; + const group = chat_id && groups.find(x => x.id == chat_id); + const groupName = group?.name ?? ''; + + $('#rm_group_chat_name').val(groupName); + $('#rm_group_chat_name').off(); + $('#rm_group_chat_name').on('input', async function() { + if (chat_id) { + group.name = $(this).val(); + await editGroup(chat_id); + } + }); + $('#rm_group_filter').val('').trigger('input'); + $("#rm_group_chats_block").css("display", "flex"); + $('#rm_group_chats_block').css('opacity', 0.0); + $('#rm_group_chats_block').transition({ + opacity: 1.0, + duration: animation_rm_duration, + easing: animation_rm_easing, + complete: function() { } + }); + + $("#rm_ch_create_block").css("display", "none"); + $("#rm_characters_block" ).css("display", "none"); + + async function memberClickHandler() { + const id = $(this).data('id'); + const isDelete = !!($(this).closest('#rm_group_members').length); + const template = $(this).clone(); + template.data('id', id); + template.click(memberClickHandler); + + if (isDelete) { + template.find('.plus').show(); + template.find('.minus').hide(); + $('#rm_group_add_members').prepend(template); + } else { + template.find('.plus').hide(); + template.find('.minus').show(); + $('#rm_group_members').prepend(template); + } + + if (group) { + if (isDelete) { + const index = group.members.findIndex(x => x === id); + if (index !== -1) { + group.members.splice(index, 1); + } + } else { + group.members.push(id); + } + await editGroup(chat_id); + } + + $(this).remove(); + const groupHasMembers = !!$('#rm_group_members').children().length; + $("#rm_group_submit").prop('disabled', !groupHasMembers); + } + + // render characters list + $('#rm_group_add_members').empty(); + $('#rm_group_members').empty(); + for (let character of characters) { + const avatar = character.avatar != 'none' ? `characters/${character.avatar}#${Date.now()}` : default_avatar; + const template = $('#group_member_template .group_member').clone(); + template.data('id', character.name); + template.find('.avatar img').attr('src', avatar); + template.find('.ch_name').html(character.name); + template.click(memberClickHandler); + + if (group && Array.isArray(group.members) && group.members.includes(character.name)) { + template.find('.plus').hide(); + template.find('.minus').show(); + $('#rm_group_members').append(template); + } else { + template.find('.plus').show(); + template.find('.minus').hide(); + $('#rm_group_add_members').append(template); + } + } + + const groupHasMembers = !!$('#rm_group_members').children().length; + $("#rm_group_submit").prop('disabled', !groupHasMembers); + + // bottom buttons + if (chat_id) { + $('#rm_group_submit').hide(); + $('#rm_group_delete').show(); + } else { + $('#rm_group_submit').show(); + $('#rm_group_delete').hide(); + } + + $('#rm_group_delete').off(); + $('#rm_group_delete').on('click', function() { + popup_type = 'del_group'; + $('#dialogue_popup').data('group_id', chat_id); + callPopup('

Delete the group?

'); + }); + + // top bar + if (group) { + var display_name = groupName; + $("#rm_button_selected_ch").children("h2").css(deselected_button_style); + $("#rm_button_selected_ch").children("h2").text(''); + } + } + function select_rm_create(){ menu_type = 'create'; if(selected_button == 'create'){ @@ -1553,6 +1845,7 @@ $( "#rm_characters_block" ).css("display", "none"); $( "#rm_api_block" ).css("display", "none"); $( "#rm_ch_create_block" ).css("display", "block"); + $("#rm_group_chats_block").css("display", "none"); $('#rm_ch_create_block').css('opacity',0.0); $('#rm_ch_create_block').transition({ @@ -1606,6 +1899,7 @@ $( "#rm_api_block" ).css("display", "none"); $( "#rm_ch_create_block" ).css("display", "none"); $( "#rm_info_block" ).css("display", "none"); + $("#rm_group_chats_block").css("display", "none"); $( "#rm_button_characters" ).children("h2").css(selected_button_style); $( "#rm_button_settings" ).children("h2").css(deselected_button_style); @@ -1615,6 +1909,7 @@ $( "#rm_characters_block" ).css("display", "none"); $( "#rm_api_block" ).css("display", "none"); $( "#rm_ch_create_block" ).css("display", "none"); + $("#rm_group_chats_block").css("display", "none"); $( "#rm_info_block" ).css("display", "flex"); $("#rm_info_text").html('

'+text+'

'); @@ -1671,6 +1966,7 @@ $("#form_create").attr("actiontype", "editcharacter"); } $(document).on('click', '.character_select', function(){ + selected_group = null; if(this_chid !== $(this).attr("chid")){ if(!is_send_press){ this_edit_mes_id = undefined; @@ -1869,6 +2165,13 @@ if (popup_type === 'del_world' && world_info) { deleteWorldInfo(world_info); } + if (popup_type === 'del_group') { + const groupId = $('#dialogue_popup').data('group_id'); + + if (groupId) { + deleteGroup(groupId); + } + } if(popup_type == 'new_chat' && this_chid != undefined && menu_type != "create"){//Fix it; New chat doesn't create while open create character menu clearChat(); chat.length = 0; @@ -1901,6 +2204,7 @@ $("#dialogue_popup_ok").text("Yes"); break; case 'del_world': + case 'del_group': default: $("#dialogue_popup_ok").css("background-color", "#791b31"); $("#dialogue_popup_ok").text("Delete"); @@ -4005,6 +4309,54 @@ +
+
+
+

+
+ +
+
+

Add Members

+ +
+ +
+

Members

+ +
+ +
+
+
+ +
+
+
+ + +
+
+
+ +
+
+
+ +
+
+ +
+
+
+
+ +
+ +
 
+ +
+

API

@@ -4162,6 +4514,7 @@

+New Character

+Import

+

+New Group

diff --git a/public/style.css b/public/style.css index 60205f39d..9b9ea9358 100644 --- a/public/style.css +++ b/public/style.css @@ -756,7 +756,7 @@ display: none; padding-left: 0.75em; } -#character_search_bar::-webkit-search-cancel-button { +input[type=search]::-webkit-search-cancel-button { -webkit-appearance: none; height: 1em; width: 1em; @@ -769,7 +769,7 @@ display: none; cursor: pointer; } -#character_search_bar:focus::-webkit-search-cancel-button { +input[type=search]:focus::-webkit-search-cancel-button { opacity: .3; pointer-events: all; } @@ -2486,3 +2486,153 @@ body { -webkit-transition: width 0s ease; transition: width 0s ease; } + +/* GROUP CHATS */ + +#rm_group_top_bar { + display: flex; + flex-direction: row; + align-items: flex-start; + width: 100%; +} +#rm_button_group_chats{ + cursor: pointer; + display: inline-block; +} +#rm_button_group_chats h2{ + margin-top: auto; + margin-bottom: auto; + font-size: 16px; + color: rgb(188, 193, 200, 1); + border: 1px solid #333; + background-color: rgba(0,0,0,0.3); + padding:6px; + border-radius: 10px; +} +#rm_group_chats_block { + display: none; + height: 100%; + flex-direction: column; + align-items: flex-start; +} +#rm_group_chat_name { + width: 90%; +} +#rm_group_buttons { + display: flex; + flex-direction: row; + width: 100%; +} +#rm_group_buttons > input { + font-size: 16px; + cursor: pointer; + user-select: none; +} +#rm_group_buttons > input:disabled { + filter: brightness(0.3); + cursor: unset; +} +#rm_group_members, #rm_group_add_members { + margin-top: 0.25rem; + margin-bottom: 0.25rem; + width: 100%; + flex: 1; + overflow: auto; +} +#rm_group_buttons_expander { + flex-grow: 1; +} +#rm_group_delete { + color: rgb(190, 0, 0); +} +#rm_group_members:empty { + width: 100%; +} +#rm_group_members:empty::before { + content: 'Group is empty'; + font-size: 1rem; + font-weight: bolder; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + opacity: 0.8; +} +#rm_group_add_members:empty { + width: 100%; +} +#rm_group_add_members_header { + display: flex; + flex-direction: row; + align-items: center; + width: 100%; +} +#rm_group_add_members_header input { + flex-grow: 1; + width: 100%; + margin-left: 1rem; +} +#rm_group_add_members:empty::before { + content: 'No characters available'; + font-size: 1rem; + font-weight: bolder; + width: 100%; + height: 100%; + display: flex; + justify-content: center; + align-items: center; + opacity: 0.8; +} +.group_member_icon { + width: 25px; + height: 25px; + margin: 0 10px; +} +.group_member_icon img { + filter: invert(1); +} +.group_member { + display: flex; + flex-direction: row; + align-items: center; + width: 100%; + padding: 5px; + border-radius: 10px; + cursor:pointer; +} +.group_member .ch_name { + flex-grow: 1; + margin-left: 10px; +} +.group_member:hover{ + background-color: #ffffff11; +} +#group_member_template { + display: none !important; +} +#group_list_template { + display: none !important; +} +.group_select { + display: flex; + flex-direction: row; + align-items: center; + padding: 5px; + border-radius: 10px; + cursor: pointer; +} +.group_select:hover { + background-color: #ffffff11; +} +.group_select .group_icon { + width: 20px; + height: 20px; + margin: 0 10px; +} +.group_select .ch_name { + flex-grow: 1; +} +.group_select .group_icon img { + filter: invert(1); +} \ No newline at end of file diff --git a/server.js b/server.js index ee7235886..4840eaf06 100644 --- a/server.js +++ b/server.js @@ -61,7 +61,12 @@ if (is_colab && process.env.googledrive == 2){ const jsonParser = express.json({limit: '100mb'}); const urlencodedParser = express.urlencoded({extended: true, limit: '100mb'}); const baseRequestArgs = { headers: { "Content-Type": "application/json" } }; -const directories = { worlds: 'public/worlds/', avatars: 'public/User Avatars' }; +const directories = { + worlds: 'public/worlds/', + avatars: 'public/User Avatars', + groups: 'public/groups/', + groupChats: 'public/group chats', +}; // CSRF Protection // const doubleCsrf = require('csrf-csrf').doubleCsrf; @@ -1294,6 +1299,112 @@ app.post('/uploaduseravatar', urlencodedParser, async (request, response) => { } }); +app.post('/getgroups', jsonParser, (_, response) => { + const groups = []; + + if (!fs.existsSync(directories.groups)) { + fs.mkdirSync(directories.groups); + } + + const files = fs.readdirSync(directories.groups); + files.forEach(function(file) { + const fileContents = fs.readFileSync(path.join(directories.groups, file), 'utf8'); + const group = JSON.parse(fileContents); + groups.push(group); + }); + + return response.send(groups); +}); + +app.post('/creategroup', jsonParser, (request, response) => { + if (!request.body) { + return response.sendStatus(400); + } + + const id = Date.now(); + const chatMetadata = { id: id, name: request.body.name ?? 'New Group', members: request.body.members ?? [], avatar_url: request.body.avatar_url }; + const pathToFile = path.join(directories.groups, `${id}.json`); + const fileData = JSON.stringify(chatMetadata); + + if (!fs.existsSync(directories.groups)) { + fs.mkdirSync(directories.groups); + } + + fs.writeFileSync(pathToFile, fileData); + return response.send(chatMetadata); +}); + +app.post('/editgroup', jsonParser, (request, response) => { + if (!request.body || !request.body.id) { + return response.sendStatus(400); + } + + const id = request.body.id; + const pathToFile = path.join(directories.groups, `${id}.json`); + const fileData = JSON.stringify(request.body); + + fs.writeFileSync(pathToFile, fileData); + return response.send({ok: true}); +}); + +app.post('/getgroupchat', jsonParser, (request, response) => { + if (!request.body || !request.body.id) { + return response.sendStatus(400); + } + + const id = request.body.id; + const pathToFile = path.join(directories.groupChats, `${id}.jsonl`); + + if (fs.existsSync(pathToFile)) { + const data = fs.readFileSync(pathToFile, 'utf8'); + const lines = data.split('\n'); + + // Iterate through the array of strings and parse each line as JSON + const jsonData = lines.map(JSON.parse); + return response.send(jsonData); + } else { + return response.send([]); + } +}); + +app.post('/savegroupchat', jsonParser, (request, response) => { + if (!request.body || !request.body.id) { + return response.sendStatus(400); + } + + const id = request.body.id; + const pathToFile = path.join(directories.groupChats, `${id}.jsonl`); + + if (!fs.existsSync(directories.groupChats)) { + fs.mkdirSync(directories.groupChats); + } + + let chat_data = request.body.chat; + let jsonlData = chat_data.map(JSON.stringify).join('\n'); + fs.writeFileSync(pathToFile, jsonlData, 'utf8'); + return response.send({ok: true}); +}); + +app.post('/deletegroup', jsonParser, async (request, response) => { + if (!request.body || !request.body.id) { + return response.sendStatus(400); + } + + const id = request.body.id; + const pathToGroup = path.join(directories.groups, `${id}.json`); + const pathToChat = path.join(directories.groupChats, `${id}.jsonl`); + + if (fs.existsSync(pathToGroup)) { + fs.rmSync(pathToGroup); + } + + if (fs.existsSync(pathToChat)) { + fs.rmSync(pathToChat); + } + + return response.send({ok: true}); +}); + // ** REST CLIENT ASYNC WRAPPERS ** function deleteAsync(url, args) { return new Promise((resolve, reject) => { From aa05749e9ba82e9191b7ab7caf433b5fe616f982 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Mon, 27 Feb 2023 18:48:01 +0200 Subject: [PATCH 03/56] Implement message sending in group chats --- public/index.html | 370 ++++++++++++++++++++++++++++++++++++++++++---- public/style.css | 175 +++++++++++++++++++++- server.js | 2 +- 3 files changed, 517 insertions(+), 30 deletions(-) diff --git a/public/index.html b/public/index.html index 508a5587b..7a718c487 100644 --- a/public/index.html +++ b/public/index.html @@ -41,13 +41,14 @@ const VERSION = '1.2.8'; var converter = new showdown.Converter(); var bg_menu_toggle = false; - const systemUserName = 'Chloe'; + const systemUserName = 'TavernAI'; + const systemCharName = 'Chloe'; var default_user_name = "You"; var name1 = default_user_name; - var name2 = systemUserName; + var name2 = systemCharName; // might want to migrate this to 'system message' code var chat = [{ - name: systemUserName, + name: systemCharName, is_user: false, is_name: true, create_date: 0, @@ -75,12 +76,13 @@ HELP: 'help', WELCOME: 'welcome', GROUP: 'group', + EMPTY: 'empty', }; const system_messages = { 'help': { "name": systemUserName, - "force_avatar": "img/chloe.png", + "force_avatar": "img/five.png", "is_user":false, "is_system": true, "is_name":true, @@ -88,11 +90,19 @@ }, 'group': { "name": systemUserName, - "force_avatar": "img/chloe.png", + "force_avatar": "img/five.png", "is_user":false, "is_system": true, "is_name": true, "mes": "Group chat created. Say 'Hi' to lovely people!" + }, + 'empty': { + "name": systemUserName, + "force_avatar": "img/five.png", + "is_user": false, + "is_system": true, + "is_name": true, + "mes": 'No one hears you. **Hint:** add more members to the group!' } }; @@ -100,6 +110,7 @@ 'before': 0, 'after': 1, } + const talkativeness_default = 0.5; var is_advanced_char_open = false; var is_world_edit_open = false; @@ -114,6 +125,7 @@ var create_save_avatar = ''; var create_save_scenario = ''; var create_save_mes_example = ''; + var create_save_talkativeness = talkativeness_default; var timerSaveEdit; var timerWorldSave; @@ -136,6 +148,7 @@ var is_api_button_press_novel = false; var is_send_press = false;//Send generation + let is_group_generating = false; // Group generation flag var add_mes_without_animation = false; var this_del_mes = 0; @@ -162,7 +175,7 @@ var max_context = 2048;//2048; var rep_pen = 1; var rep_pen_size = 100; - + var is_pygmalion = false; var tokens_already_generated = 0; var message_already_generated = ''; @@ -445,14 +458,82 @@ $("#rm_print_characters_block").prepend('
'+item.name+'
'); //console.log(item.name); }); + printGroups(); + } + + function printGroups() { for (let group of groups) { const template = $('#group_list_template .group_select').clone(); template.data('id', group.id); - template.find('.avatar img').attr('src', group.avatar_url); template.find('.ch_name').html(group.name); $('#rm_print_characters_block').prepend(template); + updateGroupAvatar(group); } } + + function updateGroupAvatar(group) { + $('#rm_print_characters_block .group_select').each(function() { + if ($(this).data('id') == group.id) { + const avatar = getGroupAvatar(group); + if (avatar) { + $(this).find('.avatar').replaceWith(avatar); + } + } + }) + } + + function getGroupAvatar(group) { + const memberAvatars = []; + if (group && Array.isArray(group.members) && group.members.length) { + for (const member of group.members) { + const charIndex = characters.findIndex(x => x.name === member); + if (charIndex !== -1 && characters[charIndex].avatar !== 'none') { + const this_avatar = `characters/${characters[charIndex].avatar}#${Date.now()}`; + memberAvatars.push(this_avatar); + } + if (memberAvatars.length === 4) { + break; + } + } + } + + // Cohee: there's probably a smarter way to do this.. + if (memberAvatars.length === 1) { + const groupAvatar = $('#group_avatars_template .collage_1').clone(); + groupAvatar.find('.img_1').attr('src', memberAvatars[0]); + return groupAvatar; + } + + if (memberAvatars.length === 2) { + const groupAvatar = $('#group_avatars_template .collage_2').clone(); + groupAvatar.find('.img_1').attr('src', memberAvatars[0]); + groupAvatar.find('.img_2').attr('src', memberAvatars[1]); + return groupAvatar; + } + + if (memberAvatars.length === 3) { + const groupAvatar = $('#group_avatars_template .collage_3').clone(); + groupAvatar.find('.img_1').attr('src', memberAvatars[0]); + groupAvatar.find('.img_2').attr('src', memberAvatars[1]); + groupAvatar.find('.img_3').attr('src', memberAvatars[2]); + return groupAvatar; + } + + if (memberAvatars.length === 4) { + const groupAvatar = $('#group_avatars_template .collage_4').clone(); + groupAvatar.find('.img_1').attr('src', memberAvatars[0]); + groupAvatar.find('.img_2').attr('src', memberAvatars[1]); + groupAvatar.find('.img_3').attr('src', memberAvatars[2]); + groupAvatar.find('.img_4').attr('src', memberAvatars[3]); + return groupAvatar; + } + + // default avatar + const groupAvatar = $('#group_avatars_template .collage_1').clone(); + groupAvatar.find('.img_1').attr('src', group.avatar_url); + return groupAvatar; + } + async function getCharacters() { await getGroups(); const response = await fetch("/getcharacters", { @@ -618,7 +699,7 @@ count_view_mes = 0; $('#chat').html(''); } - function messageFormating(mes, ch_name, isSystem){ + function messageFormating(mes, ch_name, isSystem, forceAvatar){ if(this_chid != undefined && !isSystem) mes = mes.replaceAll("<", "<").replaceAll(">", ">");//for Chloe if(this_chid === undefined){ mes = mes.replace(/\*\*(.+?)\*\*/g, '$1').replace(/\*(.+?)\*/g, '$1').replace(/\n/g, '
'); @@ -630,6 +711,9 @@ mes = mes.trim(); } + if (forceAvatar) { + mes = mes.replaceAll(ch_name+":", ""); + } if(ch_name !== name1){ mes = mes.replaceAll(name2+":", ""); @@ -681,7 +765,7 @@ messageText = messageText.replace(//gi, name1); messageText = messageText.replace(//gi, name2); } - messageText = messageFormating(messageText, characterName, isSystem); + messageText = messageFormating(messageText, characterName, isSystem, mes.force_avatar); const bias = messageFormating(mes.extra?.bias ?? ''); $("#chat").append( "
"+characterName+"
"+`
${bias}
` ); @@ -849,6 +933,18 @@ async function Generate(type) {//encode("dsfs").length tokens_already_generated = 0; message_already_generated = name2+': '; + + if (isHelpRequest($("#send_textarea").val())) { + sendSystemMessage(system_message_types.HELP); + $("#send_textarea").val('').trigger('input'); + return; + } + + if (selected_group && !is_group_generating) { + generateGroupWrapper(); + return; + } + if(online_status != 'no_connection' && this_chid != undefined){ if(type != 'regenerate'){ var textareaText = $("#send_textarea").val(); @@ -865,11 +961,6 @@ } } //$("#send_textarea").attr("disabled","disabled"); - - if (isHelpRequest(textareaText)) { - sendSystemMessage(system_message_types.HELP); - return; - } //$("#send_textarea").blur(); $( "#send_but" ).css("display", "none"); @@ -1348,6 +1439,24 @@ getMessage = getMessage.substr(0,getMessage.indexOf('<|endoftext|>')); } + // clean-up group message from excessive generations + if (type == 'group_chat' && selected_group) { + const group = groups.find(x => x.id == selected_group); + + if (group && Array.isArray(group.members) && group.members) { + for (let member of group.members) { + // Skip current speaker. + if (member === name2) { + continue; + } + + const indexOfMember = getMessage.indexOf(member+":"); + if (indexOfMember != -1) { + getMessage = getMessage.substr(0, indexOfMember); + } + } + } + } let this_mes_is_name = true; if(getMessage.indexOf(name2+":") === 0){ getMessage = getMessage.replace(name2+':', ''); @@ -1365,10 +1474,25 @@ chat[chat.length-1]['send_date'] = Date.now(); getMessage = $.trim(getMessage); chat[chat.length-1]['mes'] = getMessage; + + if (type === 'group_chat') { + let avatarImg = 'img/fluffy.png'; + if (characters[this_chid].avatar != 'none'){ + avatarImg = `characters/${characters[this_chid].avatar}`; + } + chat[chat.length-1]['is_name'] = true; + chat[chat.length-1]['force_avatar'] = avatarImg; + } + addOneMessage(chat[chat.length-1]); $( "#send_but" ).css("display", "inline"); $( "#loading_mes" ).css("display", "none"); - saveChat(); + + if (type == 'group_chat' && selected_group) { + saveGroupChat(selected_group); + } else { + saveChat(); + } }else{ //console.log('run force_name2 protocol'); Generate('force_name2'); @@ -1563,17 +1687,18 @@ const id = $(this).data('id'); selected_button = 'group_chats'; - if (selected_group !== id){ - if(!is_send_press){ - selected_group = id; - this_edit_mes_id = undefined; - clearChat(); - chat.length = 0; - await getGroupChat(id); - } - } + if(!is_send_press && !is_group_generating){ + if (selected_group !== id) { + selected_group = id; + this_chid = undefined; + this_edit_mes_id = undefined; + clearChat(); + chat.length = 0; + await getGroupChat(id); + } - select_group_chats(id); + select_group_chats(id); + } }); $("#rm_button_group_chats").click(function() { selected_button = 'group_chats'; @@ -1630,6 +1755,126 @@ $('#rm_info_block').transition({ opacity: 1.0 ,duration: 2000}); } }); + async function generateGroupWrapper() { + $('#chat .typing_indicator').remove(); + + if (online_status === 'no_connection') { + is_group_generating = false; + is_send_press = false; + return; + } + + const group = groups.find(x => x.id === selected_group); + + if (!group || !Array.isArray(group.members) || !group.members.length) { + sendSystemMessage(system_message_types.EMPTY); + return; + } + + try { + is_group_generating = true; + this_chid = undefined; + name2 = ''; + const userInput = $("#send_textarea").val(); + const activatedMembers = activateMembers(group.members, userInput); + let messagesBefore = chat.length; + + if (userInput && userInput.length) { + messagesBefore++; + } + + // now the real generation begins: cycle through every character + for (const chId of activatedMembers) { + this_chid = chId; + name2 = characters[chId].name; + + const typingIndicator = $('#typing_indicator_template .typing_indicator').clone(); + typingIndicator.find('.typing_indicator_name').text(characters[chId].name); + + await Generate('group_chat'); + + $('#chat').append(typingIndicator); + + while (true) { + // check if message generated already + if (chat.length == messagesBefore) { + await delay(10); + } else { + messagesBefore++; + break; + } + } + + $('#chat .typing_indicator').remove(); + } + + } finally { + is_group_generating = false; + is_send_press = false; + $('#chat .typing_indicator').remove(); + } + } + function activateMembers(members, input) { + let activatedNames = []; + + // find mentions + if (input && input.length) { + for (let inputWord of extractAllWords(input)) { + for (let member of members) { + if (extractAllWords(member).includes(inputWord)) { + activatedNames.push(member); + break; + } + } + } + } + + // activation by talkativeness + for (let member of members) { + const character = characters.find(x => x.name === member); + + if (!character) { + continue; + } + + const rollValue = Math.random(); + let talkativeness = Number(character.talkativeness); + talkativeness = Number.isNaN(talkativeness) ? talkativeness_default : talkativeness; + if (talkativeness > rollValue) { + activatedNames.push(member); + } + } + + // pick 1 at random if no one was activated + if (activatedNames.length === 0) { + const randomIndex = Math.floor(Math.random() * members.length); + activatedNames.push(members[randomIndex]); + } + + // de-duplicate array of names + function onlyUnique(value, index, array) { + return array.indexOf(value) === index; + } + activatedNames = activatedNames.filter(onlyUnique); + + console.log(activatedNames); + // map to character ids + const memberIds = activatedNames.map(x => characters.findIndex(y => y.name === x)).filter(x => x !== -1); + return memberIds; + } + function extractAllWords(value) { + const words = []; + + if (!value) { + return words; + } + + const matches = value.matchAll(/\b\w+\b/gmi); + for (let match of matches) { + words.push(match[0].toLowerCase()); + } + return words; + } async function getGroupChat(id) { const response = await fetch('/getgroupchat', { method: 'POST', @@ -1777,6 +2022,7 @@ group.members.push(id); } await editGroup(chat_id); + updateGroupAvatar(group); } $(this).remove(); @@ -1872,6 +2118,7 @@ $("#description_textarea").val(create_save_description); $("#personality_textarea").val(create_save_personality); $("#firstmessage_textarea").val(create_save_first_message); + $("#talkativeness_slider").val(create_save_talkativeness); $("#scenario_pole").val(create_save_scenario); if($.trim(create_save_mes_example).length == 0){ $("#mes_example_textarea").val(''); @@ -1949,6 +2196,7 @@ $("#personality_textarea").val(characters[chid].personality); $("#firstmessage_textarea").val(characters[chid].first_mes); $("#scenario_pole").val(characters[chid].scenario); + $("#talkativeness_slider").val(characters[chid].talkativeness ?? talkativeness_default); $("#mes_example_textarea").val(characters[chid].mes_example); $("#selected_chat_pole").val(characters[chid].chat); $("#create_date_pole").val(characters[chid].create_date); @@ -1966,9 +2214,10 @@ $("#form_create").attr("actiontype", "editcharacter"); } $(document).on('click', '.character_select', function(){ - selected_group = null; if(this_chid !== $(this).attr("chid")){ if(!is_send_press){ + selected_group = null; + is_group_generating = false; this_edit_mes_id = undefined; selected_button = 'character_edit'; this_chid = $(this).attr("chid"); @@ -2329,6 +2578,8 @@ create_save_personality = ''; $("#firstmessage_textarea").val(''); create_save_first_message = ''; + $("#talkativeness_slider").val(talkativeness_default); + create_save_talkativeness = talkativeness_default; $("#character_popup_text_h3").text('Create character'); @@ -2460,7 +2711,6 @@ }); $('#scenario_pole').on('keyup paste cut', function(){ if(menu_type == 'create'){ - create_save_scenario = $('#scenario_pole').val(); }else{ timerSaveEdit = setTimeout(() => {$("#create_button").click();},durationSaveEdit); @@ -2482,6 +2732,15 @@ timerSaveEdit = setTimeout(() => {$("#create_button").click();},durationSaveEdit); } }); + $('#talkativeness_slider').on('input', function() { + if (menu_type == 'create') { + create_save_talkativeness = $('#talkativeness_slider').val(); + } else { + timerSaveEdit = setTimeout(() => { + $('#create_button').click(); + }, durationSaveEdit); + } + }); $( "#api_button" ).click(function() { if($('#api_url_text').val() != ''){ $("#api_loading").css("display", 'inline-block'); @@ -2530,7 +2789,18 @@ }); } }); + function openNavToggle() { + if (!$('#nav-toggle').prop('checked')) { + $('#nav-toggle').trigger('click'); + } + } $( "#option_select_chat" ).click(function() { + if (selected_group) { + // will open a chat selection screen + openNavToggle(); + $("#rm_button_characters").trigger('click'); + return; + } if(this_chid != undefined && !is_send_press){ getAllCharaChats(); $('#shadow_select_chat_popup').css('display', 'block'); @@ -2539,6 +2809,12 @@ } }); $( "#option_start_new_chat" ).click(function() { + if (selected_group) { + // will open a group creation screen + openNavToggle(); + $("#rm_button_group_chats").trigger('click'); + return; + } if(this_chid != undefined && !is_send_press){ popup_type = 'new_chat'; callPopup('

Start new chat?

'); @@ -4052,6 +4328,17 @@
Circumstances and context of the dialogue (?)
+ +
+

Talkativeness

+
How often does the character speak randomly. Affects group chats only!
+ +
+ Shy + Normal + Chatty +
+

Examples of dialogue

@@ -4535,8 +4822,35 @@
+ +
+
CHAR is typing
+
+ +
+
+ img1 +
+
+ img1 + img2 +
+
+ img1 + img2 + img3 +
+
+ img1 + img2 + img3 + img4 +
+
+
-
+
+
diff --git a/public/style.css b/public/style.css index 9b9ea9358..a0353845c 100644 --- a/public/style.css +++ b/public/style.css @@ -1864,7 +1864,7 @@ label.checkbox :checked + span:after { background-color: rgba(0,0,0,0.3); backdrop-filter: blur(50px); -webkit-backdrop-filter: blur(50px); - grid-template-rows: 50px 100px 100px 40px auto 45px 45px; + grid-template-rows: 50px 100px 100px 110px 40px auto 45px 45px; max-width: 802px; /* 802 instead of 800 to cover #chat's scrollbars entirely */ height: 90vh; /* imperfect calculation designed to match the chat height, which is auto-set to (100% - form_sheld height) */ position: absolute; @@ -2635,4 +2635,177 @@ body { } .group_select .group_icon img { filter: invert(1); +} + +#typing_indicator_template { + display: none !important; +} + +.typing_indicator { + position: sticky; + bottom: 10px; + margin: 10px; + opacity: 0.6; + text-shadow: 2px 2px 2px rgba(0,0,0,0.6); +} + +.typing_indicator:after { + display: inline-block; + vertical-align: bottom; + animation: ellipsis steps(4,end) 1500ms infinite; + content: ""; /* ascii code for the ellipsis character */ + width: 0px; +} + +@keyframes ellipsis { + 0% { + content: "" + } + 25% { + content: "." + } + 50% { + content: ".." + } + 75% { + content: "..." + } +} + +#group_avatars_template { + display: none; +} + +.avatar_collage { + border-radius: 50%; + position: relative; + overflow: hidden; +} + +.avatar_collage img { + position: absolute; + overflow: hidden; + border-radius: 0% !important; +} + +.collage_2 .img_1 { + left: 0; + top: 0; + max-width: 50%; + max-height: 100%; + width: 50%; + height: 100%; +} + +.collage_2 .img_2 { + left: 50%; + top: 0; + max-width: 50%; + max-height: 100%; + width: 50%; + height: 100%; +} + +.collage_3 .img_1 { + left: 0; + top: 0; + max-width: 50%; + max-height: 50%; + width: 50%; + height: 50%; +} + +.collage_3 .img_2 { + left: 50%; + top: 0; + max-width: 50%; + max-height: 50%; + width: 50%; + height: 50%; +} + +.collage_3 .img_3 { + left: 0; + top: 50%; + max-width: 100%; + max-height: 50%; + width: 100%; + height: 50%; +} + +.collage_4 .img_1 { + left: 0; + top: 0; + max-width: 50%; + max-height: 50%; + width: 50%; + height: 50%; +} + +.collage_4 .img_2 { + left: 50%; + top: 0; + max-width: 50%; + max-height: 50%; + width: 50%; + height: 50%; +} + +.collage_4 .img_3 { + left: 0; + top: 50%; + max-width: 50%; + max-height: 50%; + width: 50%; + height: 50%; +} + +.collage_4 .img_4 { + left: 50%; + top: 50%; + max-width: 50%; + max-height: 50%; + width: 50%; + height: 50%; +} + +span.warning { + color:rgb(190, 0, 0); + font-weight: bolder; +} + +#talkativeness_hint { + display: flex; + flex-direction: row; + align-items: baseline; + justify-content: space-between; + width: 92%; +} + +#talkativeness_expander { + flex: 1; +} + +#talkativeness_div { + margin-left: 36px; + padding-top: 10px; +} + +#talkativeness_div input[type="range"] { + width: 92%; +} + +#talkativeness_hint span { + min-width: 10em; + font-size: small; +} + +#talkativeness_hint span:nth-child(1) { + text-align: left; +} +#talkativeness_hint span:nth-child(2) { + text-align: center; +} +#talkativeness_hint span:nth-child(3) { + text-align: right; } \ No newline at end of file diff --git a/server.js b/server.js index 4840eaf06..a0d727847 100644 --- a/server.js +++ b/server.js @@ -445,7 +445,7 @@ function checkServer(){ //***************** Main functions function charaFormatData(data){ - var char = {"name": data.ch_name, "description": data.description, "personality": data.personality, "first_mes": data.first_mes, "avatar": 'none', "chat": Date.now(), "mes_example": data.mes_example, "scenario": data.scenario, "create_date": Date.now()}; + var char = {"name": data.ch_name, "description": data.description, "personality": data.personality, "first_mes": data.first_mes, "avatar": 'none', "chat": Date.now(), "mes_example": data.mes_example, "scenario": data.scenario, "create_date": Date.now(), "talkativeness": data.talkativeness}; return char; } app.post("/createcharacter", urlencodedParser, function(request, response){ From f215ff664ebdaa58bed68795a407fd1e4d142cd6 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Mon, 27 Feb 2023 19:25:38 +0200 Subject: [PATCH 04/56] Shuffle randomly activated chars --- public/index.html | 27 ++++++++++++++++++++------- server.js | 6 +++--- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/public/index.html b/public/index.html index 7a718c487..f76de0483 100644 --- a/public/index.html +++ b/public/index.html @@ -1829,8 +1829,9 @@ } } - // activation by talkativeness - for (let member of members) { + // activation by talkativeness (in shuffled order) + const shuffledMembers = shuffle([...members]); + for (let member of shuffledMembers) { const character = characters.find(x => x.name === member); if (!character) { @@ -1840,7 +1841,7 @@ const rollValue = Math.random(); let talkativeness = Number(character.talkativeness); talkativeness = Number.isNaN(talkativeness) ? talkativeness_default : talkativeness; - if (talkativeness > rollValue) { + if (talkativeness >= rollValue) { activatedNames.push(member); } } @@ -1852,12 +1853,8 @@ } // de-duplicate array of names - function onlyUnique(value, index, array) { - return array.indexOf(value) === index; - } activatedNames = activatedNames.filter(onlyUnique); - console.log(activatedNames); // map to character ids const memberIds = activatedNames.map(x => characters.findIndex(y => y.name === x)).filter(x => x !== -1); return memberIds; @@ -4286,6 +4283,22 @@ $('#world_create_button').click(() => { createNewWorldInfo(); }); + + /// UTILS + function onlyUnique(value, index, array) { + return array.indexOf(value) === index; + } + + function shuffle(array) { + let currentIndex = array.length, randomIndex; + + while (currentIndex != 0) { + randomIndex = Math.floor(Math.random() * currentIndex); + currentIndex--; + [array[currentIndex], array[randomIndex]] = [array[randomIndex], array[currentIndex]]; + } + return array; + } });      Tavern.AI diff --git a/server.js b/server.js index a0d727847..d13fe5fd9 100644 --- a/server.js +++ b/server.js @@ -1077,12 +1077,12 @@ app.post("/importcharacter", urlencodedParser, async function(request, response) try { if(jsonData.name !== undefined){ png_name = getPngName(jsonData.name); - let char = {"name": jsonData.name, "description": jsonData.description ?? '', "personality": jsonData.personality ?? '', "first_mes": jsonData.first_mes ?? '', "avatar": 'none', "chat": Date.now(), "mes_example": jsonData.mes_example ?? '', "scenario": jsonData.scenario ?? '', "create_date": Date.now()}; + let char = {"name": jsonData.name, "description": jsonData.description ?? '', "personality": jsonData.personality ?? '', "first_mes": jsonData.first_mes ?? '', "avatar": 'none', "chat": Date.now(), "mes_example": jsonData.mes_example ?? '', "scenario": jsonData.scenario ?? '', "create_date": Date.now(), "talkativeness": jsonData.talkativeness ?? 0.5}; char = JSON.stringify(char); await charaWrite('./public/img/fluffy.png', char, png_name, response, {file_name: png_name}); }else if(jsonData.char_name !== undefined){//json Pygmalion notepad png_name = getPngName(jsonData.char_name); - let char = {"name": jsonData.char_name, "description": jsonData.char_persona ?? '', "personality": '', "first_mes": jsonData.char_greeting ?? '', "avatar": 'none', "chat": Date.now(), "mes_example": jsonData.example_dialogue ?? '', "scenario": jsonData.world_scenario ?? '', "create_date": Date.now()}; + let char = {"name": jsonData.char_name, "description": jsonData.char_persona ?? '', "personality": '', "first_mes": jsonData.char_greeting ?? '', "avatar": 'none', "chat": Date.now(), "mes_example": jsonData.example_dialogue ?? '', "scenario": jsonData.world_scenario ?? '', "create_date": Date.now(), "talkativeness": jsonData.talkativeness ?? 0.5}; char = JSON.stringify(char); await charaWrite('./public/img/fluffy.png', char, png_name, response, {file_name: png_name}); }else{ @@ -1101,7 +1101,7 @@ app.post("/importcharacter", urlencodedParser, async function(request, response) png_name = getPngName(jsonData.name); if(jsonData.name !== undefined){ - let char = {"name": jsonData.name, "description": jsonData.description ?? '', "personality": jsonData.personality ?? '', "first_mes": jsonData.first_mes ?? '', "avatar": 'none', "chat": Date.now(), "mes_example": jsonData.mes_example ?? '', "scenario": jsonData.scenario ?? '', "create_date": Date.now()}; + let char = {"name": jsonData.name, "description": jsonData.description ?? '', "personality": jsonData.personality ?? '', "first_mes": jsonData.first_mes ?? '', "avatar": 'none', "chat": Date.now(), "mes_example": jsonData.mes_example ?? '', "scenario": jsonData.scenario ?? '', "create_date": Date.now(), "talkativeness": jsonData.talkativeness ?? 0.5}; char = JSON.stringify(char); await charaWrite('./uploads/'+filedata.filename, char, png_name, response, {file_name: png_name}); /* From 1b8b8f0f370ad93d0830ebc295a438d34a120fd1 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Mon, 27 Feb 2023 21:15:35 +0200 Subject: [PATCH 05/56] Fix deletion and smooth indicator --- public/index.html | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/public/index.html b/public/index.html index f76de0483..0e9331d1c 100644 --- a/public/index.html +++ b/public/index.html @@ -1756,8 +1756,6 @@ } }); async function generateGroupWrapper() { - $('#chat .typing_indicator').remove(); - if (online_status === 'no_connection') { is_group_generating = false; is_send_press = false; @@ -1783,17 +1781,27 @@ messagesBefore++; } + let typingIndicator = $('#chat .typing_indicator'); + + if (typingIndicator.length === 0){ + typingIndicator = $('#typing_indicator_template .typing_indicator').clone(); + typingIndicator.hide(); + $('#chat').append(typingIndicator); + } + // now the real generation begins: cycle through every character for (const chId of activatedMembers) { this_chid = chId; name2 = characters[chId].name; - const typingIndicator = $('#typing_indicator_template .typing_indicator').clone(); - typingIndicator.find('.typing_indicator_name').text(characters[chId].name); - await Generate('group_chat'); + // update indicator and scroll down + typingIndicator.find('.typing_indicator_name').text(characters[chId].name); $('#chat').append(typingIndicator); + typingIndicator.fadeTo(250, 1, function() { + typingIndicator.get(0).scrollIntoView({behavior: 'smooth'}); + }); while (true) { // check if message generated already @@ -1805,13 +1813,14 @@ } } - $('#chat .typing_indicator').remove(); + // hide and reapply the indicator to the bottom of the list + typingIndicator.fadeTo(250, 0); + $('#chat').append(typingIndicator); } } finally { is_group_generating = false; is_send_press = false; - $('#chat .typing_indicator').remove(); } } function activateMembers(members, input) { @@ -2867,7 +2876,7 @@ }); // this function hides the input form, and shows the delete/cancel buttons fro deleting messages from chat $( "#option_delete_mes" ).click(function() { - if(this_chid != undefined && !is_send_press){ + if(this_chid != undefined && !is_send_press || (selected_group && !is_group_generating)){ $('#dialogue_del_mes').css('display','block'); $('#send_form').css('display','none'); $('.del_checkbox').each(function(){ @@ -2909,7 +2918,11 @@ $(".mes[mesid='"+this_del_mes+"']").remove(); chat.length = this_del_mes; count_view_mes = this_del_mes; - saveChat(); + if (selected_group) { + saveGroupChat(selected_group); + } else { + saveChat(); + } var $textchat = $('#chat'); $textchat.scrollTop($textchat[0].scrollHeight); } From a1c797fb131d50fbc52f083556e6a1de3a77cdd4 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Mon, 27 Feb 2023 21:19:04 +0200 Subject: [PATCH 06/56] Better scrolling (I hope) --- public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 0e9331d1c..5497f2662 100644 --- a/public/index.html +++ b/public/index.html @@ -1799,7 +1799,7 @@ // update indicator and scroll down typingIndicator.find('.typing_indicator_name').text(characters[chId].name); $('#chat').append(typingIndicator); - typingIndicator.fadeTo(250, 1, function() { + typingIndicator.show(250, function() { typingIndicator.get(0).scrollIntoView({behavior: 'smooth'}); }); @@ -1814,7 +1814,7 @@ } // hide and reapply the indicator to the bottom of the list - typingIndicator.fadeTo(250, 0); + typingIndicator.hide(250); $('#chat').append(typingIndicator); } From 0e59edf5e104d83e0c71b1dff867e4c0c849cee2 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Mon, 27 Feb 2023 22:54:00 +0200 Subject: [PATCH 07/56] Group chat auto-mode (broken & hidden) --- public/index.html | 58 +++++++++++++++++++++++++++++++++++++---------- public/style.css | 7 ++++++ 2 files changed, 53 insertions(+), 12 deletions(-) diff --git a/public/index.html b/public/index.html index 5497f2662..39c451a48 100644 --- a/public/index.html +++ b/public/index.html @@ -65,6 +65,7 @@ var characters = []; let groups = []; let selected_group = null; + let is_group_automode_enabled = false; var this_chid; var backgrounds = []; var default_avatar = 'img/fluffy.png'; @@ -142,6 +143,7 @@ var api_server = ""; //var interval_timer = setInterval(getStatus, 2000); var interval_timer_novel = setInterval(getStatusNovel, 3000); + const groupAutoModeInterval = setInterval(groupChatAutoModeWorker, 5000); var is_get_status = false; var is_get_status_novel = false; var is_api_button_press = false; @@ -930,7 +932,7 @@ Generate(); } }); - async function Generate(type) {//encode("dsfs").length + async function Generate(type, automatic_trigger) {//encode("dsfs").length tokens_already_generated = 0; message_already_generated = name2+': '; @@ -941,7 +943,7 @@ } if (selected_group && !is_group_generating) { - generateGroupWrapper(); + generateGroupWrapper(false); return; } @@ -1009,7 +1011,7 @@ //********************************* //PRE FORMATING STRING //********************************* - if(textareaText != ""){ + if(textareaText != "" && !automatic_trigger){ chat[chat.length] = {}; chat[chat.length-1]['name'] = name1; chat[chat.length-1]['is_user'] = true; @@ -1755,7 +1757,7 @@ $('#rm_info_block').transition({ opacity: 1.0 ,duration: 2000}); } }); - async function generateGroupWrapper() { + async function generateGroupWrapper(by_auto_mode) { if (online_status === 'no_connection') { is_group_generating = false; is_send_press = false; @@ -1774,12 +1776,6 @@ this_chid = undefined; name2 = ''; const userInput = $("#send_textarea").val(); - const activatedMembers = activateMembers(group.members, userInput); - let messagesBefore = chat.length; - - if (userInput && userInput.length) { - messagesBefore++; - } let typingIndicator = $('#chat .typing_indicator'); @@ -1789,12 +1785,25 @@ $('#chat').append(typingIndicator); } + let messagesBefore = chat.length; + let activationText = ''; + if (userInput && userInput.length && !by_auto_mode) { + activationText = userInput; + messagesBefore++; + } else { + const lastMessage = chat[chat.length - 1]; + if (lastMessage && !lastMessage.is_system) { + activationText = lastMessage.mes; + } + } + + const activatedMembers = activateMembers(group.members, activationText); // now the real generation begins: cycle through every character for (const chId of activatedMembers) { this_chid = chId; name2 = characters[chId].name; - await Generate('group_chat'); + await Generate('group_chat', by_auto_mode); // update indicator and scroll down typingIndicator.find('.typing_indicator_name').text(characters[chId].name); @@ -1821,6 +1830,7 @@ } finally { is_group_generating = false; is_send_press = false; + this_chid = undefined; } } function activateMembers(members, input) { @@ -1974,6 +1984,23 @@ clearTimeout(timerGroupSave); timerGroupSave = setTimeout(async () => await _save(), durationSaveEdit); } + async function groupChatAutoModeWorker() { + if (!is_group_automode_enabled || online_status === 'no_connection') { + return; + } + + if (!selected_group || is_send_press || is_group_generating) { + return; + } + + const group = groups.find(x => x.id === selected_group); + + if (!group || !Array.isArray(group.members) || !group.members.length) { + return; + } + + await generateGroupWrapper(true); + } function select_group_chats(chat_id) { menu_type = 'group_chats'; @@ -2084,7 +2111,10 @@ $("#rm_button_selected_ch").children("h2").text(''); } } - + $('#rm_group_automode').on('input', function() { + const value = $(this).prop('checked'); + is_group_automode_enabled = value; + }); function select_rm_create(){ menu_type = 'create'; if(selected_button == 'create'){ @@ -4665,6 +4695,10 @@
+
 
diff --git a/public/style.css b/public/style.css index a0353845c..722a9c982 100644 --- a/public/style.css +++ b/public/style.css @@ -2522,6 +2522,13 @@ body { display: flex; flex-direction: row; width: 100%; + align-items: flex-end; +} +#rm_group_buttons .checkbox { + display: flex; +} +#rm_group_buttons .checkbox h4 { + display: inline-block; } #rm_group_buttons > input { font-size: 16px; From a297962b99080b6d82b6598c03c2e62eeaa2a9d7 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 1 Mar 2023 19:55:29 +0200 Subject: [PATCH 08/56] Add extras to colab --- colab/GPU.ipynb | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index c1474e479..f786a2f86 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -55,8 +55,8 @@ "cell_type": "code", "execution_count": null, "metadata": { - "id": "hps3qtPLFNBb", - "cellView": "form" + "cellView": "form", + "id": "hps3qtPLFNBb" }, "outputs": [], "source": [ @@ -67,6 +67,7 @@ "Version = \"Official\" \n", "KoboldAI_Provider = \"Localtunnel\" #@param [\"Localtunnel\", \"Cloudflare\"]\n", "use_google_drive = True #@param {type:\"boolean\"}\n", + "extras_enable_captioning = False #@param {type:\"boolean\"}\n", "Provider = KoboldAI_Provider\n", "!nvidia-smi\n", "import subprocess\n", @@ -159,6 +160,37 @@ " if \"INIT\" in line and \"Transformers\" in line:\n", " print(\"Model loading... (It will take 2 - 5 minutes)\")\n", "\n", + "ShareParam = \"--share\" if Provider == \"Cloudflare\" else \"\"\n", + "ExtrasModules = []\n", + "\n", + "if (extras_enable_captioning):\n", + " ExtrasModules.append('caption')\n", + "\n", + "ModulesParam = f'--enable-modules={\",\".join(ExtrasModules)}'\n", + "\n", + "#TavernAI extras\n", + "%cd /\n", + "!git clone https://github.com/SillyLossy/TavernAI-extras\n", + "%cd TavernAI-extras\n", + "!pip install -r requirements.txt\n", + "extras_process = subprocess.Popen(['python', 'server.py', '--cpu', ShareParam], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n", + "\n", + "while True:\n", + " line = p.stdout.readline().decode().strip()\n", + " if \"Running on \" in line and Provider != \"Cloudflare\":\n", + " print(\"TavernAI Extras URL:\")\n", + " !lt --port 5100\n", + " print('')\n", + " break\n", + " if \"Running on \" in line and Provider == \"Cloudflare\" and \"trycloudflare.com\" in line:\n", + " print(\"TavernAI Extras URL:\")\n", + " extras_url = line.split(\"Running on \")[1]\n", + " print(extras_url)\n", + " print('')\n", + " break\n", + " if not line:\n", + " break\n", + " print(line)\n", "\n", "#TavernAI\n", "%cd /\n", @@ -166,7 +198,7 @@ "!nvm install 19.1.0\n", "!nvm use 19.1.0\n", "!node -v\n", - "!git clone https://github.com/TavernAI/TavernAIColab\n", + "!git clone -b dev https://github.com/SillyLossy/TavernAI\n", "copy_characters(use_google_drive)\n", "%cd TavernAIColab\n", "!npm install\n", @@ -186,6 +218,7 @@ } ], "metadata": { + "accelerator": "GPU", "colab": { "provenance": [] }, @@ -196,9 +229,8 @@ }, "language_info": { "name": "python" - }, - "accelerator": "GPU" + } }, "nbformat": 4, "nbformat_minor": 0 -} \ No newline at end of file +} From 327063f7fa0b6b418ac10212bf4b5fcfd13d32b8 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 1 Mar 2023 20:21:11 +0200 Subject: [PATCH 09/56] Update extras Colab --- colab/GPU.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index f786a2f86..4778d1e58 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -173,7 +173,7 @@ "!git clone https://github.com/SillyLossy/TavernAI-extras\n", "%cd TavernAI-extras\n", "!pip install -r requirements.txt\n", - "extras_process = subprocess.Popen(['python', 'server.py', '--cpu', ShareParam], stdout=subprocess.PIPE, stderr=subprocess.PIPE)\n", + "extras_process = subprocess.Popen(['python', '/TavernAI-extras/server.py', '--cpu', ShareParam], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd='/TavernAI-extras')\n", "\n", "while True:\n", " line = p.stdout.readline().decode().strip()\n", From 9950bdda31161a7be507de79c4e5b5864b61f82e Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 1 Mar 2023 20:28:59 +0200 Subject: [PATCH 10/56] Fix stupid bug --- colab/GPU.ipynb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index 4778d1e58..479b452e9 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -176,7 +176,7 @@ "extras_process = subprocess.Popen(['python', '/TavernAI-extras/server.py', '--cpu', ShareParam], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd='/TavernAI-extras')\n", "\n", "while True:\n", - " line = p.stdout.readline().decode().strip()\n", + " line = extras_process.stdout.readline().decode().strip()\n", " if \"Running on \" in line and Provider != \"Cloudflare\":\n", " print(\"TavernAI Extras URL:\")\n", " !lt --port 5100\n", From 71c02d0297754e672c7bacd9957b2975ca46ecf6 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 1 Mar 2023 20:51:13 +0200 Subject: [PATCH 11/56] Colab debugging --- colab/GPU.ipynb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index 479b452e9..635b89248 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -173,10 +173,14 @@ "!git clone https://github.com/SillyLossy/TavernAI-extras\n", "%cd TavernAI-extras\n", "!pip install -r requirements.txt\n", - "extras_process = subprocess.Popen(['python', '/TavernAI-extras/server.py', '--cpu', ShareParam], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd='/TavernAI-extras')\n", + "extras_process = subprocess.Popen(['python', '/TavernAI-extras/server.py', '--cpu', ShareParam, ModulesParam], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd='/TavernAI-extras')\n", + "print('processId:', extras_process.pid)\n", "\n", "while True:\n", " line = extras_process.stdout.readline().decode().strip()\n", + " err_line = extras_process.stderr.readline().decode().strip()\n", + " if err_line:\n", + " print(err_line)\n", " if \"Running on \" in line and Provider != \"Cloudflare\":\n", " print(\"TavernAI Extras URL:\")\n", " !lt --port 5100\n", @@ -189,6 +193,7 @@ " print('')\n", " break\n", " if not line:\n", + " print('breaking on line')\n", " break\n", " print(line)\n", "\n", From 569ae28e9e78bd6102d7523964ca7facf94300f2 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 1 Mar 2023 21:09:26 +0200 Subject: [PATCH 12/56] Add tensorflow to colab --- colab/GPU.ipynb | 1 + 1 file changed, 1 insertion(+) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index 635b89248..900060f55 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -173,6 +173,7 @@ "!git clone https://github.com/SillyLossy/TavernAI-extras\n", "%cd TavernAI-extras\n", "!pip install -r requirements.txt\n", + "!pip install -U tensorflow==2.9.2\n", "extras_process = subprocess.Popen(['python', '/TavernAI-extras/server.py', '--cpu', ShareParam, ModulesParam], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd='/TavernAI-extras')\n", "print('processId:', extras_process.pid)\n", "\n", From 496e5008b1631df0a68a5f8dcdc0a592a9ca62c2 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 1 Mar 2023 21:24:07 +0200 Subject: [PATCH 13/56] Colab debug --- colab/GPU.ipynb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index 900060f55..b0b412fe6 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -179,12 +179,11 @@ "\n", "while True:\n", " line = extras_process.stdout.readline().decode().strip()\n", - " err_line = extras_process.stderr.readline().decode().strip()\n", + " err_line = '\\n'.join([line.decode().strip() for line in extras_process.stderr.readlines()])\n", " if err_line:\n", " print(err_line)\n", " if \"Running on \" in line and Provider != \"Cloudflare\":\n", " print(\"TavernAI Extras URL:\")\n", - " !lt --port 5100\n", " print('')\n", " break\n", " if \"Running on \" in line and Provider == \"Cloudflare\" and \"trycloudflare.com\" in line:\n", @@ -198,6 +197,9 @@ " break\n", " print(line)\n", "\n", + "!lt --port 5100\n", + "print('')\n", + "\n", "#TavernAI\n", "%cd /\n", "!curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash\n", From 41437c777048769bd172dabbb02b1e8b002aabcd Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 1 Mar 2023 23:12:34 +0200 Subject: [PATCH 14/56] Add draft extensions loader --- public/index.html | 1 + public/scripts/extensions.js | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 public/scripts/extensions.js diff --git a/public/index.html b/public/index.html index 1e6fdefcd..913b15cd1 100644 --- a/public/index.html +++ b/public/index.html @@ -4936,5 +4936,6 @@
+ diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js new file mode 100644 index 000000000..c161c2577 --- /dev/null +++ b/public/scripts/extensions.js @@ -0,0 +1,21 @@ +const settings_html = ` +
+
+

Extensions

+ + +
+` +const urlKey = 'extensions_url'; +const defaultUrl = "http://localhost:5100"; + +$(document).ready(async function() { + const url = localStorage.getItem(urlKey) ?? defaultUrl; + $('#rm_api_block').append(settings_html); + $("#extensions_url").val(url); + $("#extensions_connect").on('click', function() { + const url = $("#extensions_url").val(); + localStorage.setItem(urlKey, url); + alert('click!'); + }); +}); \ No newline at end of file From faf850794a4baf986acb3f0540bf016f7afd518c Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 1 Mar 2023 23:35:43 +0200 Subject: [PATCH 15/56] Fix click propagation --- public/index.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index c8493f47a..fa9513519 100644 --- a/public/index.html +++ b/public/index.html @@ -2031,7 +2031,8 @@ $("#rm_ch_create_block").css("display", "none"); $("#rm_characters_block" ).css("display", "none"); - async function memberClickHandler() { + async function memberClickHandler(event) { + event.stopPropagation(); const id = $(this).data('id'); const isDelete = !!($(this).closest('#rm_group_members').length); const template = $(this).clone(); From f5635155b9e26708c409b33e98c8f2d2fcfd72e1 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 2 Mar 2023 01:32:33 +0200 Subject: [PATCH 16/56] Add extension loader --- public/index.html | 2 +- public/scripts/extensions.js | 183 ++++++++++++++++++++++++++++++++--- 2 files changed, 172 insertions(+), 13 deletions(-) diff --git a/public/index.html b/public/index.html index fa9513519..7f6368cee 100644 --- a/public/index.html +++ b/public/index.html @@ -4921,6 +4921,6 @@
- + diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index c161c2577..fd8820380 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -1,21 +1,180 @@ + const settings_html = ` -
-
+
+

Extensions

- +
+ +

Auto-connect

+
+
Not connected
+
+

Active extensions

+
    +
+
-` -const urlKey = 'extensions_url'; -const defaultUrl = "http://localhost:5100"; +`; -$(document).ready(async function() { +const settings_style = ` + +`; + +const urlKey = 'extensions_url'; +const autoConnectKey = 'extensions_autoconnect'; +const defaultUrl = "http://localhost:5100"; +let connectedToApi = false; +let extensions = []; + +async function connectClickHandler() { + const baseUrl = $("#extensions_url").val(); + localStorage.setItem(urlKey, baseUrl); + await connectToApi(baseUrl); +} + +function autoConnectInputHandler() { + const value = $(this).prop('checked'); + localStorage.setItem(autoConnectKey, value.toString()); + + if (value && !connectedToApi) { + $("#extensions_connect").trigger('click'); + } +} + +async function connectToApi(baseUrl) { + const url = new URL(baseUrl); + url.pathname = '/api/extensions'; + const getExtensionsResult = await fetch(url, { method: 'GET' }); + + if (getExtensionsResult.ok) { + const data = await getExtensionsResult.json(); + extensions = data.extensions; + applyExtensions(baseUrl); + } + + updateStatus(getExtensionsResult.ok); +} + +function updateStatus(success) { + connectedToApi = success; + const _text = success ? 'Connected to API' : 'Could not connect to API'; + const _class = success ? 'success' : 'failed'; + $('#extensions_status').text(_text); + $('#extensions_status').attr('class', _class); + + if (success && extensions.length) { + $('#extensions_loaded').show(200); + $('#extensions_list').empty(); + + for (let extension of extensions) { + $('#extensions_list').append(`
  • ${extension.metadata.display_name}
  • `); + } + } +} + +function applyExtensions(baseUrl) { + const url = new URL(baseUrl); + + if (!Array.isArray(extensions) || extensions.length === 0) { + return; + } + + for (let extension of extensions) { + if (extension.metadata.js) { + url.pathname = `/api/script/${extension.name}`; + const src = url.toString(); + + if ($(`script[src="${src}"]`).length === 0) { + const script = document.createElement('script'); + script.type = 'module'; + script.src = src; + $('body').append(script); + } + + } + + if (extension.metadata.css) { + url.pathname = `/api/style/${extension.name}`; + const href = url.toString(); + + if ($(`link[href="${href}"]`).length === 0) { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = href; + $('head').append(link); + } + } + } +} + +$(document).ready(async function () { const url = localStorage.getItem(urlKey) ?? defaultUrl; + const autoConnect = Boolean(localStorage.getItem(autoConnectKey)) ?? false; $('#rm_api_block').append(settings_html); + $('head').append(settings_style); $("#extensions_url").val(url); - $("#extensions_connect").on('click', function() { - const url = $("#extensions_url").val(); - localStorage.setItem(urlKey, url); - alert('click!'); - }); + $("#extensions_connect").on('click', connectClickHandler); + $("#extensions_autoconnect").on('input', autoConnectInputHandler); + $("#extensions_autoconnect").prop('checked', autoConnect).trigger('input'); }); \ No newline at end of file From da8ccbbcc1cec2013a3247f68b125b5212be953d Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 2 Mar 2023 01:42:00 +0200 Subject: [PATCH 17/56] Error handing for fetch and style fix --- public/scripts/extensions.js | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index fd8820380..7e32869cb 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -23,7 +23,7 @@ const settings_style = ` display: block; } -#extensions_active { +#extensions_loaded { display: none; } @@ -104,21 +104,27 @@ function autoConnectInputHandler() { async function connectToApi(baseUrl) { const url = new URL(baseUrl); url.pathname = '/api/extensions'; - const getExtensionsResult = await fetch(url, { method: 'GET' }); - if (getExtensionsResult.ok) { - const data = await getExtensionsResult.json(); - extensions = data.extensions; - applyExtensions(baseUrl); + try { + const getExtensionsResult = await fetch(url, { method: 'GET' }); + + if (getExtensionsResult.ok) { + const data = await getExtensionsResult.json(); + extensions = data.extensions; + applyExtensions(baseUrl); + } + + updateStatus(getExtensionsResult.ok); + } + catch { + updateStatus(false); } - - updateStatus(getExtensionsResult.ok); } function updateStatus(success) { connectedToApi = success; const _text = success ? 'Connected to API' : 'Could not connect to API'; - const _class = success ? 'success' : 'failed'; + const _class = success ? 'success' : 'failure'; $('#extensions_status').text(_text); $('#extensions_status').attr('class', _class); @@ -130,6 +136,10 @@ function updateStatus(success) { $('#extensions_list').append(`
  • ${extension.metadata.display_name}
  • `); } } + else { + $('#extensions_loaded').hide(200); + $('#extensions_list').empty(); + } } function applyExtensions(baseUrl) { From 36b3d4cac3682aacf5d8deea36815f057d3f975e Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 2 Mar 2023 17:05:27 +0200 Subject: [PATCH 18/56] Add support for external TAI API calls --- config.conf | 3 +- public/index.html | 36 +++- public/scripts/extensions.js | 343 ++++++++++++++++++----------------- server.js | 5 +- 4 files changed, 218 insertions(+), 169 deletions(-) diff --git a/config.conf b/config.conf index 25d278e14..e1882fbff 100644 --- a/config.conf +++ b/config.conf @@ -3,7 +3,8 @@ const port = 8000; const whitelist = ['127.0.0.1']; //Example for add several IP in whitelist: ['127.0.0.1', '192.168.0.10'] const whitelistMode = false; //Disabling enabling the ip whitelist mode. true/false const autorun = true; //Autorun in the browser. true/false +const enableExtensions = true; //Enables support for TavernAI-extras project module.exports = { - port, whitelist, whitelistMode, autorun + port, whitelist, whitelistMode, autorun, enableExtensions, }; diff --git a/public/index.html b/public/index.html index 7f6368cee..8fe7e122f 100644 --- a/public/index.html +++ b/public/index.html @@ -33,7 +33,9 @@ Tavern.AI @@ -4921,6 +4954,5 @@
    - diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 7e32869cb..4a1b73c98 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -1,190 +1,205 @@ -const settings_html = ` -
    -
    -

    Extensions

    - -
    - -

    Auto-connect

    -
    -
    Not connected
    -
    -

    Active extensions

    -
      -
    -
    -
    -`; - -const settings_style = ` - -`; - -const urlKey = 'extensions_url'; -const autoConnectKey = 'extensions_autoconnect'; -const defaultUrl = "http://localhost:5100"; -let connectedToApi = false; +const extensions_urlKey = 'extensions_url'; +const extensions_autoConnectKey = 'extensions_autoconnect'; let extensions = []; -async function connectClickHandler() { - const baseUrl = $("#extensions_url").val(); - localStorage.setItem(urlKey, baseUrl); - await connectToApi(baseUrl); -} +(function () { + const settings_html = ` +
    +
    +

    Extensions

    + +
    + + +

    Auto-connect

    +
    +
    Not connected
    +
    +

    Active extensions

    +
      +
    +
    +
    + `; -function autoConnectInputHandler() { - const value = $(this).prop('checked'); - localStorage.setItem(autoConnectKey, value.toString()); - - if (value && !connectedToApi) { - $("#extensions_connect").trigger('click'); + const settings_style = ` + + `; -async function connectToApi(baseUrl) { - const url = new URL(baseUrl); - url.pathname = '/api/extensions'; + const defaultUrl = "http://localhost:5100"; + let connectedToApi = false; - try { - const getExtensionsResult = await fetch(url, { method: 'GET' }); + async function connectClickHandler() { + const baseUrl = $("#extensions_url").val(); + localStorage.setItem(extensions_urlKey, baseUrl); + await connectToApi(baseUrl); + } - if (getExtensionsResult.ok) { - const data = await getExtensionsResult.json(); - extensions = data.extensions; - applyExtensions(baseUrl); + function autoConnectInputHandler() { + const value = $(this).prop('checked'); + localStorage.setItem(extensions_autoConnectKey, value.toString()); + + if (value && !connectedToApi) { + $("#extensions_connect").trigger('click'); } - - updateStatus(getExtensionsResult.ok); } - catch { - updateStatus(false); + + async function connectToApi(baseUrl) { + const url = new URL(baseUrl); + url.pathname = '/api/extensions'; + + try { + const getExtensionsResult = await fetch(url, { method: 'GET' }); + + if (getExtensionsResult.ok) { + const data = await getExtensionsResult.json(); + extensions = data.extensions; + applyExtensions(baseUrl); + } + + updateStatus(getExtensionsResult.ok); + } + catch { + updateStatus(false); + } } -} -function updateStatus(success) { - connectedToApi = success; - const _text = success ? 'Connected to API' : 'Could not connect to API'; - const _class = success ? 'success' : 'failure'; - $('#extensions_status').text(_text); - $('#extensions_status').attr('class', _class); + function updateStatus(success) { + connectedToApi = success; + const _text = success ? 'Connected to API' : 'Could not connect to API'; + const _class = success ? 'success' : 'failure'; + $('#extensions_status').text(_text); + $('#extensions_status').attr('class', _class); - if (success && extensions.length) { - $('#extensions_loaded').show(200); - $('#extensions_list').empty(); + if (success && extensions.length) { + $('#extensions_loaded').show(200); + $('#extensions_list').empty(); + + for (let extension of extensions) { + $('#extensions_list').append(`
  • ${extension.metadata.display_name}
  • `); + } + } + else { + $('#extensions_loaded').hide(200); + $('#extensions_list').empty(); + } + } + + function applyExtensions(baseUrl) { + const url = new URL(baseUrl); + + if (!Array.isArray(extensions) || extensions.length === 0) { + return; + } for (let extension of extensions) { - $('#extensions_list').append(`
  • ${extension.metadata.display_name}
  • `); + addExtensionStyle(extension); + addExtensionScript(extension); } - } - else { - $('#extensions_loaded').hide(200); - $('#extensions_list').empty(); - } -} -function applyExtensions(baseUrl) { - const url = new URL(baseUrl); + function addExtensionStyle(extension) { + if (extension.metadata.css) { + url.pathname = `/api/style/${extension.name}`; + const href = url.toString(); - if (!Array.isArray(extensions) || extensions.length === 0) { - return; - } - - for (let extension of extensions) { - if (extension.metadata.js) { - url.pathname = `/api/script/${extension.name}`; - const src = url.toString(); - - if ($(`script[src="${src}"]`).length === 0) { - const script = document.createElement('script'); - script.type = 'module'; - script.src = src; - $('body').append(script); + if ($(`link[href="${href}"]`).length === 0) { + const link = document.createElement('link'); + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.href = href; + $('head').append(link); + } } - } - if (extension.metadata.css) { - url.pathname = `/api/style/${extension.name}`; - const href = url.toString(); + function addExtensionScript(extension) { + if (extension.metadata.js) { + url.pathname = `/api/script/${extension.name}`; + const src = url.toString(); - if ($(`link[href="${href}"]`).length === 0) { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.type = 'text/css'; - link.href = href; - $('head').append(link); + if ($(`script[src="${src}"]`).length === 0) { + const script = document.createElement('script'); + script.type = 'module'; + script.src = src; + $('body').append(script); + } } } } -} -$(document).ready(async function () { - const url = localStorage.getItem(urlKey) ?? defaultUrl; - const autoConnect = Boolean(localStorage.getItem(autoConnectKey)) ?? false; - $('#rm_api_block').append(settings_html); - $('head').append(settings_style); - $("#extensions_url").val(url); - $("#extensions_connect").on('click', connectClickHandler); - $("#extensions_autoconnect").on('input', autoConnectInputHandler); - $("#extensions_autoconnect").prop('checked', autoConnect).trigger('input'); -}); \ No newline at end of file + $(document).ready(async function () { + const url = localStorage.getItem(extensions_urlKey) ?? defaultUrl; + const autoConnect = Boolean(localStorage.getItem(extensions_autoConnectKey)) ?? false; + $('#rm_api_block').append(settings_html); + $('head').append(settings_style); + $("#extensions_url").val(url); + $("#extensions_connect").on('click', connectClickHandler); + $("#extensions_autoconnect").on('input', autoConnectInputHandler); + $("#extensions_autoconnect").prop('checked', autoConnect).trigger('input'); + }); +})(); \ No newline at end of file diff --git a/server.js b/server.js index d13fe5fd9..8e89f6e69 100644 --- a/server.js +++ b/server.js @@ -25,7 +25,7 @@ const server_port = config.port; const whitelist = config.whitelist; const whitelistMode = config.whitelistMode; const autorun = config.autorun; - +const enableExtensions = config.enableExtensions; var Client = require('node-rest-client').Client; @@ -804,7 +804,8 @@ app.post('/getsettings', jsonParser, (request, response) => { //Wintermute's cod koboldai_setting_names, world_names, novelai_settings, - novelai_setting_names + novelai_setting_names, + enable_extensions: enableExtensions, }); }); From 7a3e62692c264217a0f58ebfb022c2170ee27af7 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 2 Mar 2023 21:15:25 +0200 Subject: [PATCH 19/56] Revert colab changes --- colab/GPU.ipynb | 52 ++++++------------------------------------------- 1 file changed, 6 insertions(+), 46 deletions(-) diff --git a/colab/GPU.ipynb b/colab/GPU.ipynb index b0b412fe6..c1474e479 100644 --- a/colab/GPU.ipynb +++ b/colab/GPU.ipynb @@ -55,8 +55,8 @@ "cell_type": "code", "execution_count": null, "metadata": { - "cellView": "form", - "id": "hps3qtPLFNBb" + "id": "hps3qtPLFNBb", + "cellView": "form" }, "outputs": [], "source": [ @@ -67,7 +67,6 @@ "Version = \"Official\" \n", "KoboldAI_Provider = \"Localtunnel\" #@param [\"Localtunnel\", \"Cloudflare\"]\n", "use_google_drive = True #@param {type:\"boolean\"}\n", - "extras_enable_captioning = False #@param {type:\"boolean\"}\n", "Provider = KoboldAI_Provider\n", "!nvidia-smi\n", "import subprocess\n", @@ -160,45 +159,6 @@ " if \"INIT\" in line and \"Transformers\" in line:\n", " print(\"Model loading... (It will take 2 - 5 minutes)\")\n", "\n", - "ShareParam = \"--share\" if Provider == \"Cloudflare\" else \"\"\n", - "ExtrasModules = []\n", - "\n", - "if (extras_enable_captioning):\n", - " ExtrasModules.append('caption')\n", - "\n", - "ModulesParam = f'--enable-modules={\",\".join(ExtrasModules)}'\n", - "\n", - "#TavernAI extras\n", - "%cd /\n", - "!git clone https://github.com/SillyLossy/TavernAI-extras\n", - "%cd TavernAI-extras\n", - "!pip install -r requirements.txt\n", - "!pip install -U tensorflow==2.9.2\n", - "extras_process = subprocess.Popen(['python', '/TavernAI-extras/server.py', '--cpu', ShareParam, ModulesParam], stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd='/TavernAI-extras')\n", - "print('processId:', extras_process.pid)\n", - "\n", - "while True:\n", - " line = extras_process.stdout.readline().decode().strip()\n", - " err_line = '\\n'.join([line.decode().strip() for line in extras_process.stderr.readlines()])\n", - " if err_line:\n", - " print(err_line)\n", - " if \"Running on \" in line and Provider != \"Cloudflare\":\n", - " print(\"TavernAI Extras URL:\")\n", - " print('')\n", - " break\n", - " if \"Running on \" in line and Provider == \"Cloudflare\" and \"trycloudflare.com\" in line:\n", - " print(\"TavernAI Extras URL:\")\n", - " extras_url = line.split(\"Running on \")[1]\n", - " print(extras_url)\n", - " print('')\n", - " break\n", - " if not line:\n", - " print('breaking on line')\n", - " break\n", - " print(line)\n", - "\n", - "!lt --port 5100\n", - "print('')\n", "\n", "#TavernAI\n", "%cd /\n", @@ -206,7 +166,7 @@ "!nvm install 19.1.0\n", "!nvm use 19.1.0\n", "!node -v\n", - "!git clone -b dev https://github.com/SillyLossy/TavernAI\n", + "!git clone https://github.com/TavernAI/TavernAIColab\n", "copy_characters(use_google_drive)\n", "%cd TavernAIColab\n", "!npm install\n", @@ -226,7 +186,6 @@ } ], "metadata": { - "accelerator": "GPU", "colab": { "provenance": [] }, @@ -237,8 +196,9 @@ }, "language_info": { "name": "python" - } + }, + "accelerator": "GPU" }, "nbformat": 4, "nbformat_minor": 0 -} +} \ No newline at end of file From 6b3bd1e6cf425fec059c4b8b84f3d8ef13250db8 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 2 Mar 2023 22:05:31 +0200 Subject: [PATCH 20/56] Fix message edit --- public/index.html | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/public/index.html b/public/index.html index 8fe7e122f..1190135b4 100644 --- a/public/index.html +++ b/public/index.html @@ -714,6 +714,14 @@ } return mes; } + function appendImageToMessage(mes, messageElement) { + if (mes.extra?.image) { + const image = document.createElement('img'); + image.src = mes.extra?.image; + image.classList.add('img_extra'); + messageElement.find('.mes_text').prepend(image); + } + } function addOneMessage(mes){ //var message = mes['mes']; //message = mes['mes'].replace(/^\s+/g, ''); @@ -767,13 +775,7 @@ const newMessage = $(`#chat [mesid="${count_view_mes}"]`); newMessage.data('isSystem', isSystem); - if (mes.extra?.image) { - const image = document.createElement('img'); - image.src = mes.extra?.image; - image.classList.add('img_extra'); - newMessage.find('.mes_text').css('font-size', '0px'); - newMessage.find('.mes_text').append(image); - } + appendImageToMessage(mes, newMessage); if (isSystem) { newMessage.find('.mes_edit').hide(); @@ -3559,6 +3561,7 @@ $(this).parent().children('.mes_edit_done').css('display','none'); $(this).parent().children('.mes_edit').css('display','inline-block'); $(this).parent().parent().children('.mes_text').append(messageFormating(text,this_edit_mes_chname)); + appendImageToMessage(chat[this_edit_mes_id], $(this).closest('.mes')); this_edit_mes_id = undefined; }); $(document).on('click', '.mes_edit_done', function(){ @@ -3586,6 +3589,7 @@ div.parent().parent().children('.mes_text').append(messageFormating(text,this_edit_mes_chname)); div.parent().parent().children('.mes_bias').empty(); div.parent().parent().children('.mes_bias').append(messageFormating(bias)); + appendImageToMessage(chat[this_edit_mes_id], div.closest('.mes')); this_edit_mes_id = undefined; saveChat(); } From 6c3984d4f4234a4b5b548f13a98c7644b607691b Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 2 Mar 2023 23:47:08 +0200 Subject: [PATCH 21/56] Move message styles --- public/style.css | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/public/style.css b/public/style.css index 745736375..24e311647 100644 --- a/public/style.css +++ b/public/style.css @@ -2546,3 +2546,20 @@ a { box-shadow: -5px 0 10px 0 rgba(0, 0, 0, 0.50); overflow-y: auto; } + +/* Message images */ +.mes img.img_extra { + max-width: 600px; + max-height: 300px; + border-radius: 10px; +} + +.mes img.img_extra ~ * { + display: none; +} + +@media (max-width: 768px) { + .mes img.img_extra { + max-width: 100%; + } +} From f5013d373dca10a65a88fc0370a7efdbafa23620 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 3 Mar 2023 01:44:06 +0200 Subject: [PATCH 22/56] Add more fields to the context --- public/index.html | 4 ++++ public/style.css | 9 +++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 0fa353918..22ce6a5ef 100644 --- a/public/index.html +++ b/public/index.html @@ -4383,12 +4383,16 @@ return { chat: chat, characters: characters, + groups: groups, + worldInfo: world_info_data, name1: name1, name2: name2, characterId: this_chid, + groupId: selected_group, onlineStatus: online_status, addOneMessage: addOneMessage, generate: Generate, + encode: encode, }; }; }); diff --git a/public/style.css b/public/style.css index bb11be698..bda9f18ac 100644 --- a/public/style.css +++ b/public/style.css @@ -728,6 +728,10 @@ display: none; /* visibility: hidden; */ } +#rm_characters_block .right_menu_button { + padding-right: 15px; +} + #rm_characters_topbar { display: flex; flex-direction: column; @@ -749,13 +753,14 @@ display: none; display: flex; flex-direction: row; align-items: center; - margin-bottom: 1rem; - margin-top: 1rem; + margin: 1rem auto; + width: 98%; } #character_search_bar { flex: 1; padding-left: 0.75em; + margin-left: 0; margin-right: 0.5rem; margin-bottom: 0; } From 939d1bf6631040d1dcfd03cb5b06a6a878228217 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 3 Mar 2023 20:36:24 +0200 Subject: [PATCH 23/56] Add extension API for external prompt additions --- public/index.html | 16 ++++++++++++---- public/scripts/extensions.js | 5 +++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index 22ce6a5ef..1e6d8587e 100644 --- a/public/index.html +++ b/public/index.html @@ -207,6 +207,7 @@ var anchor_order = 0; var style_anchor = true; var character_anchor = true; + let extension_prompt = ''; var main_api = 'kobold'; //novel settings @@ -710,6 +711,7 @@ } function clearChat(){ count_view_mes = 0; + extension_prompt = ''; $('#chat').html(''); } function messageFormating(mes, ch_name, isSystem, forceAvatar){ @@ -1189,7 +1191,7 @@ for (var item of chat2) {//console.log(encode("dsfs").length); chatString = item+chatString; - if(encode(JSON.stringify(worldInfoString+storyString+chatString+anchorTop+anchorBottom+charPersonality+promptBias)).length+120 < this_max_context){ //(The number of tokens in the entire promt) need fix, it must count correctly (added +120, so that the description of the character does not hide) + if(encode(JSON.stringify(worldInfoString+storyString+chatString+anchorTop+anchorBottom+charPersonality+promptBias+extension_prompt)).length+120 < this_max_context){ //(The number of tokens in the entire promt) need fix, it must count correctly (added +120, so that the description of the character does not hide) //if (is_pygmalion && i == chat2.length-1) item='\n'+item; @@ -1205,7 +1207,7 @@ let mesExmString = ''; for(let iii = 0; iii < mesExamplesArray.length; iii++){//mesExamplesArray It need to make from end to start mesExmString = mesExmString+mesExamplesArray[iii]; - if(encode(JSON.stringify(worldInfoString+storyString+mesExmString+chatString+anchorTop+anchorBottom+charPersonality+promptBias)).length+120 < this_max_context){ //example of dialogs + if(encode(JSON.stringify(worldInfoString+storyString+mesExmString+chatString+anchorTop+anchorBottom+charPersonality+promptBias+extension_prompt)).length+120 < this_max_context){ //example of dialogs if(!is_pygmalion){ mesExamplesArray[iii] = mesExamplesArray[iii].replace(//i, 'This is how '+name2+' should talk');//An example of how '+name2+' responds } @@ -1305,7 +1307,7 @@ } function checkPromtSize(){ setPromtString(); - let thisPromtContextSize = encode(JSON.stringify(worldInfoString+storyString+mesExmString+mesSendString+anchorTop+anchorBottom+charPersonality+generatedPromtCache+promptBias)).length+120; + let thisPromtContextSize = encode(JSON.stringify(worldInfoString+storyString+mesExmString+mesSendString+anchorTop+anchorBottom+charPersonality+generatedPromtCache+promptBias+extension_prompt)).length+120; if(thisPromtContextSize > this_max_context){ if(count_exm_add > 0){ //mesExamplesArray.length = mesExamplesArray.length-1; @@ -1334,7 +1336,7 @@ mesSendString = '\n'+mesSendString; //mesSendString = mesSendString; //This edit simply removes the first "" that is prepended to all context prompts } - finalPromt = worldInfoBefore+storyString+worldInfoAfter+mesExmString+mesSendString+generatedPromtCache+promptBias; + finalPromt = worldInfoBefore+storyString+worldInfoAfter+extension_prompt+mesExmString+mesSendString+generatedPromtCache+promptBias; var generate_data; if(main_api == 'kobold'){ @@ -4379,6 +4381,10 @@ return array; } + function setExtensionPrompt(value) { + extension_prompt = value; + } + window['TavernAI'].getContext = function() { return { chat: chat, @@ -4393,6 +4399,8 @@ addOneMessage: addOneMessage, generate: Generate, encode: encode, + extensionPrompt: extension_prompt, + setExtensionPrompt: setExtensionPrompt, }; }; }); diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 4a1b73c98..34245d936 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -15,6 +15,9 @@ let extensions = [];

    Auto-connect

    Not connected
    +
    +

    Extension settings

    +

    Active extensions

      @@ -138,6 +141,7 @@ let extensions = []; if (success && extensions.length) { $('#extensions_loaded').show(200); + $('#extensions_settings').show(200); $('#extensions_list').empty(); for (let extension of extensions) { @@ -146,6 +150,7 @@ let extensions = []; } else { $('#extensions_loaded').hide(200); + $('#extensions_settings').hide(200); $('#extensions_list').empty(); } } From 36168951904ca14334c922ce1f0767ffd13cbc9f Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 4 Mar 2023 00:25:39 +0200 Subject: [PATCH 24/56] Add chatId to external API --- public/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/public/index.html b/public/index.html index 1e6d8587e..fa36885c2 100644 --- a/public/index.html +++ b/public/index.html @@ -4395,6 +4395,7 @@ name2: name2, characterId: this_chid, groupId: selected_group, + chatId: (this_chid && characters[this_chid].chat), onlineStatus: online_status, addOneMessage: addOneMessage, generate: Generate, From f6aa6609cde81a4a12486d9c09d89b1057706eb9 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 4 Mar 2023 23:32:32 +0200 Subject: [PATCH 25/56] Fix for localtunnel --- public/scripts/extensions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 34245d936..e008273b7 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -117,7 +117,7 @@ let extensions = []; url.pathname = '/api/extensions'; try { - const getExtensionsResult = await fetch(url, { method: 'GET' }); + const getExtensionsResult = await fetch(url, { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': '' } }); if (getExtensionsResult.ok) { const data = await getExtensionsResult.json(); From f7f2c3078fd27afd3fd48691db98882bba1eee13 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sun, 5 Mar 2023 14:51:22 +0200 Subject: [PATCH 26/56] TEST: Supposed fix of "avatars infection" issue --- public/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/index.html b/public/index.html index fa36885c2..0df7c3cf0 100644 --- a/public/index.html +++ b/public/index.html @@ -466,7 +466,7 @@ characters.forEach(function(item, i, arr) { var this_avatar = default_avatar; if(item.avatar != 'none'){ - this_avatar = "characters/"+item.avatar+"#"+Date.now(); + this_avatar = "characters/"+item.avatar+"?"+Date.now(); } $("#rm_print_characters_block").prepend('
      '+item.name+'
      '); @@ -569,7 +569,7 @@ for(var i = 0; i < load_ch_count.length;i++){ - characters[i] = []; + //characters[i] = []; characters[i] = getData[i]; //console.log(characters[i]); @@ -765,7 +765,7 @@ if(characters[this_chid].avatar != 'none'){ avatarImg = "characters/"+characters[this_chid].avatar; if(is_mes_reload_avatar !== false){ - avatarImg+="#"+is_mes_reload_avatar; + avatarImg+="?"+is_mes_reload_avatar; //console.log(avatarImg); } }else{ From 1db21e1a13b95bb06d904db780ca3d5667b94fb9 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sun, 5 Mar 2023 14:52:29 +0200 Subject: [PATCH 27/56] Add value to Tunnel bypass header --- public/scripts/extensions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index e008273b7..8936980da 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -117,7 +117,7 @@ let extensions = []; url.pathname = '/api/extensions'; try { - const getExtensionsResult = await fetch(url, { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': '' } }); + const getExtensionsResult = await fetch(url, { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': 'bypass' } }); if (getExtensionsResult.ok) { const data = await getExtensionsResult.json(); From 4031a599acbad391d4ead68b77da11706b260cd7 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sun, 5 Mar 2023 15:43:28 +0200 Subject: [PATCH 28/56] Bypass localtunnel on loading extension files --- public/scripts/extensions.js | 50 ++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 17 deletions(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 8936980da..eabb0942a 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -167,31 +167,47 @@ let extensions = []; addExtensionScript(extension); } - function addExtensionStyle(extension) { + async function addExtensionStyle(extension) { if (extension.metadata.css) { - url.pathname = `/api/style/${extension.name}`; - const href = url.toString(); + try { + url.pathname = `/api/style/${extension.name}`; + const link = url.toString(); - if ($(`link[href="${href}"]`).length === 0) { - const link = document.createElement('link'); - link.rel = 'stylesheet'; - link.type = 'text/css'; - link.href = href; - $('head').append(link); + const result = await fetch(link, { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': 'bypass' } }); + const text = await result.text(); + + if ($(`style[id="${link}"]`).length === 0) { + const style = document.createElement('style'); + style.id = link; + style.innerHTML = text; + $('head').append(style); + } + } + catch (error) { + console.log(error); } } } - function addExtensionScript(extension) { + async function addExtensionScript(extension) { if (extension.metadata.js) { - url.pathname = `/api/script/${extension.name}`; - const src = url.toString(); + try { + url.pathname = `/api/script/${extension.name}`; + const link = url.toString(); - if ($(`script[src="${src}"]`).length === 0) { - const script = document.createElement('script'); - script.type = 'module'; - script.src = src; - $('body').append(script); + const result = await fetch(link, { method: 'GET', headers: { 'Bypass-Tunnel-Reminder': 'bypass' } }); + const text = await result.text(); + + if ($(`script[id="${link}"]`).length === 0) { + const script = document.createElement('script'); + script.id = link; + script.type = 'module'; + script.innerHTML = text; + $('body').append(script); + } + } + catch (error) { + console.log(error); } } } From 50743afaa99d397c28561bd90af6195456161bdd Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Mon, 6 Mar 2023 17:52:35 +0200 Subject: [PATCH 29/56] Remove debugger --- public/scripts/extensions.js | 1 - 1 file changed, 1 deletion(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 1b9f3d562..580ce4e96 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -214,7 +214,6 @@ let extensions = []; } $(document).ready(async function () { - debugger; const url = localStorage.getItem(extensions_urlKey) ?? defaultUrl; const autoConnect = localStorage.getItem(extensions_autoConnectKey) == 'true'; $('#rm_api_block').append(settings_html); From 427c21ee8c69036e8009f4b8621be0f743ee3733 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Mon, 6 Mar 2023 18:11:12 +0200 Subject: [PATCH 30/56] Better extensions style --- public/scripts/extensions.js | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 580ce4e96..455efe3f5 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -12,17 +12,17 @@ let extensions = [];
      -

      Auto-connect

      +
      Not connected
      -
      -

      Extension settings

      -

      Active extensions

      +
      +

      Extension settings

      +
    `; @@ -41,8 +41,7 @@ let extensions = []; } #extensions_status { - margin: 10px; - opacity: 0.85; + margin-bottom: 10px; font-weight: 700; } @@ -50,28 +49,24 @@ let extensions = []; background-color: green; } - .extensions_block input[type="submit"] { - cursor: pointer; - color: #fff; - opacity: 0.7; - padding: 10px; - font-size: 1rem; - height: 2.5rem; - transition: 0.3s; - } - .extensions_block input[type="checkbox"] { margin-left: 10px; + margin-right: 10px; } + label[for="extensions_autoconnect"] { + display: flex; + align-items: center; + margin: 0 !important; + } + .extensions_url_block { display: flex; align-items: center; - margin: 10px; - width: 90% + justify-content: space-between; } - .extensions_url_block- h4 { + .extensions_url_block h4 { display: inline; } From 67e94493cbd93670e421e7cff4a270630fdaa910 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Mon, 6 Mar 2023 18:47:44 +0200 Subject: [PATCH 31/56] Adjust styles --- public/style.css | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/public/style.css b/public/style.css index 249cc2752..08ddcf892 100644 --- a/public/style.css +++ b/public/style.css @@ -1639,7 +1639,7 @@ input[type="range"] { background-color: var(--black30a); backdrop-filter: blur(50px); -webkit-backdrop-filter: blur(50px); - grid-template-rows: 50px 100px 100px 110px auto; + grid-template-rows: 50px 100px 100px 100px auto; grid-gap: 10px; max-width: 800px; height: calc(100vh - 50px); @@ -2137,20 +2137,16 @@ span.warning { flex-direction: row; align-items: baseline; justify-content: space-between; - width: 92%; + width: 100%; } #talkativeness_expander { flex: 1; } -#talkativeness_div { - margin-left: 36px; - padding-top: 10px; -} #talkativeness_div input[type="range"] { - width: 92%; + width: 100%; } #talkativeness_hint span { From 1c9658c82a7269d6383e4059dbd6af3311348822 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Tue, 7 Mar 2023 15:04:29 +0200 Subject: [PATCH 32/56] WI replacement params --- public/index.html | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/public/index.html b/public/index.html index 913eb9679..863fc7677 100644 --- a/public/index.html +++ b/public/index.html @@ -889,6 +889,14 @@ } function checkWorldInfo(chat) { + function substituteParams(content) { + content = content.replace(/{{user}}/gi, name1); + content = content.replace(/{{char}}/gi, name2); + content = content.replace(//gi, name1); + content = content.replace(//gi, name2); + return content; + } + if (world_info_data.entries.length == 0) { return ''; } @@ -939,10 +947,10 @@ for (const entry of newEntries) { if (entry.position === world_info_position.after) { - worldInfoAfter = `${entry.content}\n${worldInfoAfter}`; + worldInfoAfter = `${substituteParams(entry.content)}\n${worldInfoAfter}`; } else { - worldInfoBefore = `${entry.content}\n${worldInfoBefore}`; + worldInfoBefore = `${substituteParams(entry.content)}\n${worldInfoBefore}`; } if (encode(worldInfoBefore + worldInfoAfter).length >= world_info_budget) { From 2a41834b3d28a002f2cdb73e8d41c1105168cd55 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Tue, 7 Mar 2023 15:10:19 +0200 Subject: [PATCH 33/56] Filter caret return symbols out of prompt --- public/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/public/index.html b/public/index.html index 863fc7677..9dde83a8e 100644 --- a/public/index.html +++ b/public/index.html @@ -1397,6 +1397,7 @@ //mesSendString = mesSendString; //This edit simply removes the first "" that is prepended to all context prompts } finalPromt = worldInfoBefore+storyString+worldInfoAfter+extension_prompt+mesExmString+mesSendString+generatedPromtCache+promptBias; + finalPromt = finalPromt.replace(/\r/gm, ''); var generate_data; if(main_api == 'kobold'){ From 837ecb636ac2479dbbe119c654f212f8ebc784fe Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Tue, 7 Mar 2023 16:38:41 +0200 Subject: [PATCH 34/56] Style adjust --- public/scripts/extensions.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 455efe3f5..6ed2678de 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -36,10 +36,6 @@ let extensions = []; display: none; } - .extensions_block h3 { - margin-bottom: 10px; - } - #extensions_status { margin-bottom: 10px; font-weight: 700; From 936cb32264ae01e358d7a4ce1d87f744ff871168 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Tue, 7 Mar 2023 17:18:53 +0200 Subject: [PATCH 35/56] Support multiple extension prompts --- public/index.html | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/public/index.html b/public/index.html index 9dde83a8e..ea13adafa 100644 --- a/public/index.html +++ b/public/index.html @@ -203,7 +203,7 @@ var anchor_order = 0; var style_anchor = true; var character_anchor = true; - let extension_prompt = ''; + let extension_prompts = {}; var auto_connect = false; var auto_load_chat = false; @@ -763,7 +763,7 @@ } function clearChat(){ count_view_mes = 0; - extension_prompt = ''; + extension_prompts = {}; $('#chat').html(''); } function messageFormating(mes, ch_name, isSystem, forceAvatar){ @@ -1247,6 +1247,8 @@ worldInfoString = worldInfoBefore + worldInfoAfter; } + let extension_prompt = Object.values(extension_prompts).filter(x => x).join('\n'); + var i = 0; for (var item of chat2) {//console.log(encode("dsfs").length); @@ -4494,8 +4496,8 @@ return array; } - function setExtensionPrompt(value) { - extension_prompt = value; + function setExtensionPrompt(key, value) { + extension_prompts[key] = value; } window['TavernAI'].getContext = function() { @@ -4513,8 +4515,9 @@ addOneMessage: addOneMessage, generate: Generate, encode: encode, - extensionPrompt: extension_prompt, + extensionPrompts: extension_prompts, setExtensionPrompt: setExtensionPrompt, + saveChat: saveChat, }; }; From 92109d9044316c0786b92d382e96487e53878201 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Tue, 7 Mar 2023 18:02:03 +0200 Subject: [PATCH 36/56] Search bar fixed --- public/index.html | 6 ------ 1 file changed, 6 deletions(-) diff --git a/public/index.html b/public/index.html index dc081978e..265344885 100644 --- a/public/index.html +++ b/public/index.html @@ -5150,12 +5150,6 @@ -
    - -
    - -
    -
    From 73d669628d46d30b674e5584de45214fd2ff7f67 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 8 Mar 2023 01:58:48 +0200 Subject: [PATCH 37/56] Sort extension prompts by key alphabetical order --- public/index.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index 265344885..9e5625eb1 100644 --- a/public/index.html +++ b/public/index.html @@ -1248,7 +1248,10 @@ worldInfoString = worldInfoBefore + worldInfoAfter; } - let extension_prompt = Object.values(extension_prompts).filter(x => x).join('\n'); + let extension_prompt = Object.keys(extension_prompts).sort().map(x => extension_prompts[x]).filter(x => x).join('\n'); + if (extension_prompt.length && !extension_prompt.endsWith('\n')) { + extension_prompt += '\n'; + } var i = 0; From 4676777d177056ade384f21cd3aee30f71bf8b01 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 8 Mar 2023 01:59:05 +0200 Subject: [PATCH 38/56] Un-hide Soft Prompts selector --- public/style.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/style.css b/public/style.css index 08ddcf892..1067ea9ed 100644 --- a/public/style.css +++ b/public/style.css @@ -1107,7 +1107,7 @@ width: 103px; /* hidden until we find out a way to handle it better */ #softprompt_block { - display: none !important; + display: none; } #world_info { From 62a6fa85194c545e1dd1c72e6761af93f2f1a5d1 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 8 Mar 2023 17:34:14 +0200 Subject: [PATCH 39/56] Add support for text generation UI (by @im-not-tom) --- public/index.html | 231 +++++++++++++++++++++++++++++++++++-------- public/settings.json | 2 +- public/style.css | 17 ++-- server.js | 73 +++++++++++--- 4 files changed, 263 insertions(+), 60 deletions(-) diff --git a/public/index.html b/public/index.html index 06596b583..bc81dc949 100644 --- a/public/index.html +++ b/public/index.html @@ -156,6 +156,7 @@ var online_status = 'no_connection'; var api_server = ""; + var api_server_textgenerationwebui = ""; //var interval_timer = setInterval(getStatus, 2000); var interval_timer_novel = setInterval(getStatusNovel, 3000); const groupAutoModeInterval = setInterval(groupChatAutoModeWorker, 5000); @@ -193,6 +194,16 @@ var rep_pen = 1; var rep_pen_size = 100; + var textgenerationwebui_settings = { + temp: 0.5, + top_p: 0.9, + top_k: 0, + typical_p: 1, + rep_pen: 1.1, + rep_pen_size: 0, + penalty_alpha: 0, + } + var is_pygmalion = false; var tokens_already_generated = 0; var message_already_generated = ''; @@ -353,6 +364,8 @@ $("#online_status_text2").html(online_status); $("#online_status_indicator3").css("background-color", "green"); $("#online_status_text3").html(online_status); + $("#online_status_indicator4").css("background-color", "green"); + $("#online_status_text4").html(online_status); } } async function getLastVersion(){ @@ -394,7 +407,8 @@ type: 'POST', // url: '/getstatus', // data: JSON.stringify({ -                      api_server: api_server +                      api_server: (main_api == "kobold" ? api_server : api_server_textgenerationwebui), +                      main_api: main_api,                  }), beforeSend: function(){ if(is_api_button_press){ @@ -446,6 +460,8 @@ checkOnlineStatus(); $("#api_loading").css("display", 'none'); $("#api_button").css("display", 'inline-block'); + $("#api_loading_textgenerationwebui").css("display", 'none'); + $("#api_button_textgenerationwebui").css("display", 'inline-block'); } async function getSoftPromptsList() { @@ -1433,38 +1449,36 @@ finalPromt = worldInfoBefore+storyString+worldInfoAfter+extension_prompt+mesExmString+mesSendString+generatedPromtCache+promptBias; finalPromt = finalPromt.replace(/\r/gm, ''); + //if we aren't using the kobold GUI settings... + if (main_api == 'textgenerationwebui' || main_api == 'kobold' && preset_settings != 'gui') { + var this_settings = koboldai_settings[koboldai_setting_names[preset_settings]]; + + var this_amount_gen = parseInt(amount_gen); // how many tokens the AI will be requested to generate + if(is_pygmalion){ // if we are using a pygmalion model... + if(tokens_already_generated === 0){ // if nothing has been generated yet.. + if(parseInt(amount_gen) >= 50){ // if the max gen setting is > 50...( + this_amount_gen = 50; // then only try to make 50 this cycle.. + } + else{ + this_amount_gen = parseInt(amount_gen); // otherwise, make as much as the max amount request. + } + } + else{ // if we already recieved some generated text... + if(parseInt(amount_gen) - tokens_already_generated < tokens_cycle_count){ // if the remaining tokens to be made is less than next potential cycle count + this_amount_gen = parseInt(amount_gen) - tokens_already_generated; // subtract already generated amount from the desired max gen amount + } + else{ + this_amount_gen = tokens_cycle_count; // otherwise make the standard cycle amont (frist 50, and 30 after that) + } + } + } + } + var generate_data; if(main_api == 'kobold'){ var generate_data = {prompt: finalPromt, gui_settings: true,max_length: amount_gen,temperature: temp, max_context_length: max_context}; - if(preset_settings != 'gui'){ //if we aren't using the kobold GUI settings... + if(preset_settings != 'gui'){ - var this_settings = koboldai_settings[koboldai_setting_names[preset_settings]]; - var this_amount_gen = parseInt(amount_gen); // how many tokens the AI will be requested to generate - - if(is_pygmalion){ // if we are using a pygmalion model... - if(tokens_already_generated === 0){ // if nothing has been generated yet.. - if(parseInt(amount_gen) >= 50){ // if the max gen setting is > 50...( - this_amount_gen = 50; // then only try to make 50 this cycle.. - }else{ - this_amount_gen = parseInt(amount_gen); // otherwise, make as much as the max amount request. - } - - //console.log('Max Gen Amount: '+parseInt(amount_gen)); - - }else{ // if we already recieved some generated text... - if(parseInt(amount_gen) - tokens_already_generated < tokens_cycle_count){ // if the remaining tokens to be made is less than next potential cycle count - this_amount_gen = parseInt(amount_gen) - tokens_already_generated; // subtract already generated amount from the desired max gen amount - //console.log('Remaining tokens to be requested: '+this_amount_gen); - }else{ - this_amount_gen = tokens_cycle_count; // otherwise make the standard cycle amont (frist 50, and 30 after that) - } - } - //console.log('Upcoming token request amt: '+this_amount_gen); - - }else{ - //console.log('non-pyg model or GUI Settings are being used -- skipping request split'); - } - generate_data = {prompt: finalPromt, gui_settings: false, sampler_order: this_settings.sampler_order, @@ -1490,6 +1504,35 @@ }; } } + + if(main_api == 'textgenerationwebui'){ + const doSample = textgenerationwebui_settings.penalty_alpha == 0; + var generate_data = { + data: [ + finalPromt, + this_amount_gen, // min_length + doSample, // do_sample + textgenerationwebui_settings.temp, // temperature + textgenerationwebui_settings.top_p, // top_p + textgenerationwebui_settings.typical_p, // typical_p + textgenerationwebui_settings.rep_pen, // repetition_penalty + textgenerationwebui_settings.top_k, // top_k + 0, // min_length + textgenerationwebui_settings.rep_pen_size, // no_repeat_ngram_size + 1, // num_beams + textgenerationwebui_settings.penalty_alpha, // penalty_alpha + 1, // length_penalty + false, // early_stopping + name1, // name1 + name2, // name2 + "", // Context + true, // stop at newline + 1300, // Maximum prompt size in tokens + 1, // num attempts + ] + }; + } + if(main_api == 'novel'){ var this_settings = novelai_settings[novelai_setting_names[preset_settings_novel]]; generate_data = {"input": finalPromt, @@ -1516,8 +1559,9 @@ var generate_url = ''; if(main_api == 'kobold'){ generate_url = '/generate'; - } - if(main_api == 'novel'){ + } else if(main_api == 'textgenerationwebui') { + generate_url = '/generate_textgenerationwebui'; + } else if(main_api == 'novel'){ generate_url = '/generate_novelai'; } jQuery.ajax({ @@ -1537,14 +1581,21 @@ //console.log('Tokens requested in total: '+tokens_already_generated); //$("#send_textarea").focus(); //$("#send_textarea").removeAttr('disabled'); - is_send_press = false; - if(data.error != true){ + is_send_press = false; + if(!data.error) { //const getData = await response.json(); + var getMessage = ""; if(main_api == 'kobold'){ - var getMessage = data.results[0].text; - } - if(main_api == 'novel'){ - var getMessage = data.output; + getMessage = data.results[0].text; + } else if (main_api == 'textgenerationwebui') { + getMessage = data.data[0]; + if (getMessage == null) { + runGenerate(""); + return; + } + getMessage = getMessage.substring(finalPromt.length); + } else if(main_api == 'novel'){ + getMessage = data.output; } //Pygmalion run again // to make it continue generating so long as it's under max_amount and hasn't signaled @@ -2970,6 +3021,7 @@ api_server = api_server+"/api"; } //console.log("2: "+api_server); + main_api = "kobold"; saveSettings(); is_get_status = true; is_api_button_press = true; @@ -2979,8 +3031,27 @@ } }); - - $(document).on('click', function(event) { // this makes the input bar's option menu disappear when clicked away from + + $( "#api_button_textgenerationwebui" ).click(function() { + if($('#textgenerationwebui_api_url_text').val() != ''){ + $("#api_loading_textgenerationwebui").css("display", 'inline-block'); + $("#api_button_textgenerationwebui").css("display", 'none'); + api_server_textgenerationwebui = $('#textgenerationwebui_api_url_text').val(); + api_server_textgenerationwebui = $.trim(api_server_textgenerationwebui); + if(api_server_textgenerationwebui.substr(api_server_textgenerationwebui.length-1,1) == "/"){ + api_server_textgenerationwebui = api_server_textgenerationwebui.substr(0,api_server_textgenerationwebui.length-1); + } + //console.log("2: "+api_server_textgenerationwebui); + main_api = "textgenerationwebui"; + saveSettings(); + is_get_status = true; + is_api_button_press = true; + getStatus(); + } + }); + + + $( "body" ).click(function() { if($("#options").css('opacity') == 1.0){ $('#options').transition({ opacity: 0.0, @@ -3231,14 +3302,26 @@ if($('#main_api').find(":selected").val() == 'kobold'){ $('#kobold_api').css("display", "block"); $('#novel_api').css("display", "none"); + $('#textgenerationwebui_api').css("display", "none"); main_api = 'kobold'; $('#max_context_block').css('display', 'block'); $('#amount_gen_block').css('display', 'block'); $('#softprompt_block').css('display', 'block'); } + if($('#main_api').find(":selected").val() == 'textgenerationwebui'){ + $('#kobold_api').css("display", "none"); + $('#novel_api').css("display", "none"); + $('#textgenerationwebui_api').css("display", "block"); + main_api = 'textgenerationwebui'; + $('#max_context_block').css('display', 'block'); + $('#amount_gen_block').css('display', 'block'); + $('#softprompt_block').css('display', 'block'); + } + if($('#main_api').find(":selected").val() == 'novel'){ $('#kobold_api').css("display", "none"); $('#novel_api').css("display", "block"); + $('#textgenerationwebui_api').css("display", "none"); main_api = 'novel'; $('#max_context_block').css('display', 'none'); $('#amount_gen_block').css('display', 'none'); @@ -3285,6 +3368,21 @@ highlightSelectedAvatar(); } + for (var i of ["temp", "rep_pen", "rep_pen_size", "top_k", "top_p", "typical_p", "penalty_alpha"]) { + $('#' + i + '_textgenerationwebui').attr('x-setting-id', i); + $(document).on('input', '#' + i + '_textgenerationwebui', function() { + var i = $(this).attr('x-setting-id'); + var val = $(this).val(); + if(isInt(val)){ + $('#' + i + '_counter_textgenerationwebui').html( $(this).val()+".00" ); + }else{ + $('#' + i + '_counter_textgenerationwebui').html( $(this).val() ); + } + textgenerationwebui_settings[i] = parseFloat(val); + setTimeout(saveSettings, 500); + }); + } + $(document).on('input', '#temp', function() { temp = $(this).val(); if(isInt(temp)){ @@ -3453,6 +3551,9 @@ preset_settings = settings.preset_settings; //Load AI model config settings (temp, context length, anchors, and anchor order) + + textgenerationwebui_settings = settings.textgenerationwebui_settings || textgenerationwebui_settings; + temp = settings.temp; amount_gen = settings.amount_gen; if(settings.max_context !== undefined) max_context = parseInt(settings.max_context); @@ -3589,8 +3690,18 @@ active_character = settings.active_character; } } - } + api_server_textgenerationwebui = settings.api_server_textgenerationwebui; + $("#textgenerationwebui_api_url_text").val(api_server_textgenerationwebui); + + + for (var i of ["temp", "rep_pen", "rep_pen_size", "top_k", "top_p", "typical_p", "penalty_alpha"]) { + $("#" + i + "_textgenerationwebui") + .val(textgenerationwebui_settings[i]); + $("#" + i + "_counter_textgenerationwebui") + .html(textgenerationwebui_settings[i]); + } + } if(!is_checked_colab) isColab(); }, error: function (jqXHR, exception) { @@ -3599,8 +3710,8 @@ } }); - } + async function saveSettings(type){ //console.log('saveSettings() -- pinging server to save settings.'); jQuery.ajax({ @@ -3609,6 +3720,7 @@ data: JSON.stringify({ username: name1,                      api_server: api_server, +                      api_server_textgenerationwebui: api_server_textgenerationwebui, preset_settings: preset_settings, preset_settings_novel: preset_settings_novel, user_avatar: user_avatar, @@ -3631,7 +3743,8 @@ world_info: world_info, world_info_depth: world_info_depth, world_info_budget: world_info_budget, - active_character: active_character + active_character: active_character, + textgenerationwebui_settings: textgenerationwebui_settings,                  }), beforeSend: function(){ //console.log('saveSettings() -- active_character -- '+active_character); @@ -5019,6 +5132,7 @@

    API

    @@ -5076,6 +5190,39 @@ + + From 5f4c9bf301c3fa26a91c6e6274d9d8f0071d4ed7 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Wed, 8 Mar 2023 17:59:39 +0200 Subject: [PATCH 41/56] Step pen.alpha return --- public/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/index.html b/public/index.html index f33c6024c..ef250a783 100644 --- a/public/index.html +++ b/public/index.html @@ -5219,7 +5219,7 @@

    Typical P

    select

    Penalty Alpha

    select
    - + From d804720357dfeb6f9933bd8c5b998c15caf035dc Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 9 Mar 2023 01:40:30 +0200 Subject: [PATCH 42/56] Improvements to group chats --- public/index.html | 55 ++++++++++++++++++++++++++++++++++------------- public/style.css | 2 +- 2 files changed, 41 insertions(+), 16 deletions(-) diff --git a/public/index.html b/public/index.html index ef250a783..dd824ef16 100644 --- a/public/index.html +++ b/public/index.html @@ -924,15 +924,15 @@ return name; } - function checkWorldInfo(chat) { - function substituteParams(content) { - content = content.replace(/{{user}}/gi, name1); - content = content.replace(/{{char}}/gi, name2); - content = content.replace(//gi, name1); - content = content.replace(//gi, name2); - return content; - } + function substituteParams(content) { + content = content.replace(/{{user}}/gi, name1); + content = content.replace(/{{char}}/gi, name2); + content = content.replace(//gi, name1); + content = content.replace(//gi, name2); + return content; + } + function checkWorldInfo(chat) { if (world_info_data.entries.length == 0) { return ''; } @@ -1017,7 +1017,7 @@ return; } - const newMessage = { ... systemMessage, 'send_date': Date.now() }; + const newMessage = { ... systemMessage, 'send_date': humanizedISO8601DateTime() }; chat.push(newMessage); addOneMessage(newMessage); is_send_press = false; @@ -1669,7 +1669,7 @@ if (type === 'group_chat') { let avatarImg = 'img/fluffy.png'; if (characters[this_chid].avatar != 'none'){ - avatarImg = `characters/${characters[this_chid].avatar}`; + avatarImg = `characters/${characters[this_chid].avatar}?${Date.now()}`; } chat[chat.length-1]['is_name'] = true; chat[chat.length-1]['force_avatar'] = avatarImg; @@ -2112,6 +2112,27 @@ } else { sendSystemMessage(system_message_types.GROUP); + const group = groups.find(x => x.id === id); + if (group && Array.isArray(group.members)) { + for (let name of group.members) { + const character = characters.find(x => x.name === name); + + if (!character) { + continue; + } + + const mes = {}; + mes['is_user'] = false; + mes['is_system'] = false; + mes['name'] = character.name; + mes['is_name'] = true; + mes['send_date'] = humanizedISO8601DateTime(); + mes['mes'] = character.first_mes ? substituteParams(character.first_mes.trim()) : mes['mes'] = default_ch_mes; + mes['force_avatar'] = character.avatar != 'none' ? `characters/${character.avatar}?${Date.now()}` : 'img/fluffy.png'; + chat.push(mes); + addOneMessage(mes); + } + } } await saveGroupChat(id); @@ -2453,7 +2474,7 @@ if(characters[chid].avatar != 'none'){ this_avatar = "characters/"+characters[chid].avatar; } - $("#avatar_load_preview").attr('src',this_avatar+"#"+Date.now()); + $("#avatar_load_preview").attr('src',this_avatar+"?"+Date.now()); $("#name_div").css("display", "none"); $("#form_create").attr("actiontype", "editcharacter"); @@ -3806,7 +3827,7 @@ //******************** //***Message Editor*** $(document).on('click', '.mes_edit', function(){ - if(this_chid !== undefined){ + if(this_chid !== undefined || selected_group){ const message = $(this).closest('.mes'); if (message.data('isSystem')) { @@ -3842,7 +3863,11 @@ var text = chat[edit_mes_id]['mes']; if(chat[edit_mes_id]['is_user']){ this_edit_mes_chname = name1; - }else{ + } + else if (chat[edit_mes_id]['forced_avatar']) { + this_edit_mes_chname = chat[edit_mes_id]['name']; + } + else{ this_edit_mes_chname = name2; } text = text.trim(); @@ -5121,9 +5146,9 @@

    Auto Mode

    - +
     
    - +
    diff --git a/public/style.css b/public/style.css index 42fde61dc..f3ae472ec 100644 --- a/public/style.css +++ b/public/style.css @@ -1861,7 +1861,7 @@ border-radius: 5px; #rm_group_top_bar { display: flex; flex-direction: row; - align-items: flex-start; + align-items: center; width: 100%; } #rm_button_group_chats{ From af7d30b2482a2b523ff7bcae0b023b536881a801 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Thu, 9 Mar 2023 01:54:52 +0200 Subject: [PATCH 43/56] Display Chloe on group chat deletion --- public/index.html | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/public/index.html b/public/index.html index dd824ef16..2b718ba46 100644 --- a/public/index.html +++ b/public/index.html @@ -48,7 +48,7 @@ var name2 = "Chloe"; // might want to migrate this to 'system message' code var chat = [{name: 'Chloe',is_user: false,is_name: true,create_date: 0,mes: '\n*You went inside. The air smelled of fried meat, tobacco and a hint of wine. A dim light was cast by candles, and a fire crackled in the fireplace. It seems to be a very pleasant place. Behind the wooden bar is an elf waitress, she is smiling. Her ears are very pointy, and there is a twinkle in her eye. She wears glasses and a white apron. As soon as she noticed you, she immediately came right up close to you.*\n\n' +' "Hello there! How is your evening going?"

    \n'+'\n'}]; - var safetychat = [{name: 'Chloe',is_user: false,is_name: true,create_date: 0,mes: '\n*You deleted a charcter and arrived back here for safety reasons! Pick another character!*\n\n'}]; + var safetychat = [{name: 'Chloe',is_user: false,is_name: true,create_date: 0,mes: '\n*You deleted a character/chat and arrived back here for safety reasons! Pick another character!*\n\n'}]; var chat_create_date = 0; //RossAscends: Added function to format dates used in files and chat timestamps to a humanized format. @@ -2173,7 +2173,14 @@ }); if (response.ok) { - await getCharacters(); + active_character = 'invalid-safety-id'; //unsets the chid in settings (this prevents AutoLoadChat from trying to load the wrong ChID + this_chid = 'invalid-safety-id'; //unsets expected chid before reloading (related to getCharacters/printCharacters from using old arrays) + selected_group = null; + characters.length = 0; // resets the characters array, forcing getcharacters to reset + name2 = "Chloe"; // replaces deleted charcter name with Chloe, since she wil be displayed next. + chat = [...safetychat]; // sets up chloe to tell user about having deleted a character + + QuickRefresh(); $('#rm_info_avatar').html(''); $('#rm_info_block').transition({ opacity: 0 ,duration: 0}); select_rm_info("Group deleted!"); @@ -2676,7 +2683,7 @@ this_chid = 'invalid-safety-id'; //unsets expected chid before reloading (related to getCharacters/printCharacters from using old arrays) characters.length = 0; // resets the characters array, forcing getcharacters to reset name2="Chloe"; // replaces deleted charcter name with Chloe, since she wil be displayed next. - chat = safetychat; // sets up chloe to tell user about having deleted a character + chat = [...safetychat]; // sets up chloe to tell user about having deleted a character saveSettings(); // saving settings to keep changes to variables QuickRefresh(); // call quick refresh of Char list, clears chat, and loads Chloe 'post-char-delete' message. //location.reload(); // this is Humi's original code @@ -3928,7 +3935,12 @@ div.parent().parent().children('.mes_bias').append(messageFormating(bias)); appendImageToMessage(chat[this_edit_mes_id], div.closest('.mes')); this_edit_mes_id = undefined; - saveChat(); + if (selected_group) { + saveGroupChat(selected_group); + } + else { + saveChat(); + } } $("#your_name_button").click(function() { if(!is_send_press){ From 216b251f3e0fb0aab23adaa300a8713319335c11 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 10 Mar 2023 22:01:16 +0200 Subject: [PATCH 44/56] Enable amount gen if switching API from Kobold with GUI preset --- public/index.html | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/index.html b/public/index.html index 749a9014e..d5637a492 100644 --- a/public/index.html +++ b/public/index.html @@ -3336,6 +3336,7 @@ $('#max_context_block').css('display', 'block'); $('#amount_gen_block').css('display', 'block'); $('#softprompt_block').css('display', 'block'); + $('#settings_perset').trigger('change'); } if($('#main_api').find(":selected").val() == 'textgenerationwebui'){ $('#kobold_api').css("display", "none"); @@ -3345,6 +3346,8 @@ $('#max_context_block').css('display', 'block'); $('#amount_gen_block').css('display', 'block'); $('#softprompt_block').css('display', 'block'); + $("#amount_gen_block").children().prop("disabled", false); + $("#amount_gen_block").css('opacity',1.0); } if($('#main_api').find(":selected").val() == 'novel'){ From 100c934f5ae82c5fc7556a26401327112a4e197d Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 10 Mar 2023 23:53:04 +0200 Subject: [PATCH 45/56] Hide character only if deleted --- public/index.html | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/public/index.html b/public/index.html index d5637a492..d597456b3 100644 --- a/public/index.html +++ b/public/index.html @@ -299,8 +299,12 @@ getUserAvatars(); //console.log(chat); printMessages(); - $( "#rm_button_selected_ch" ).css("class","deselected-right-tab"); - $( "#rm_button_selected_ch" ).children("h2").text(''); + + if (!this_chid || this_chid === 'invalid-safety-id') { + $( "#rm_button_selected_ch" ).css("class","deselected-right-tab"); + $( "#rm_button_selected_ch" ).children("h2").text(''); + } + if (NavToggle.checked === false) { document.getElementById('nav-toggle').click(); }; @@ -2405,7 +2409,7 @@ CountCharTokens(); } function select_rm_characters(){ - QuickRefresh(); + QuickRefresh(true); menu_type = 'characters'; $( "#rm_characters_block" ).css("display", "block"); $('#rm_characters_block').css('opacity',0.0); @@ -5235,6 +5239,7 @@
    + Make sure you run it with
    --no-stream
    option!

    API url

    Example: http://127.0.0.1:7860/
    From 439286b9465f46f6e30c6b9768c14ef6bf9727e7 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Fri, 10 Mar 2023 23:54:46 +0200 Subject: [PATCH 46/56] Fix notice style for ooba --- public/style.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/style.css b/public/style.css index f3ae472ec..226bb2928 100644 --- a/public/style.css +++ b/public/style.css @@ -644,6 +644,10 @@ select option:not(:checked) { /* works to color unselected items */ } +#textgenerationwebui_api pre { + display: inline; +} + #api_button:hover, #api_button_novel:hover{background-color:green;} #api_loading, #api_loading_textgenerationwebui{ From 28004e7616b67d035829306dd014ce8dbf12341b Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 11 Mar 2023 00:17:26 +0200 Subject: [PATCH 47/56] Autoconnect to ooba and novel --- public/index.html | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/public/index.html b/public/index.html index d597456b3..d417a5b81 100644 --- a/public/index.html +++ b/public/index.html @@ -4784,18 +4784,35 @@ success: function(data){ if(data.result != 'file not find'){ settings = JSON.parse(data.settings); - - //Load the API server URL from settings + + //Load the API server URL from settings api_server = settings.api_server; + api_server_textgenerationwebui = settings.api_server_textgenerationwebui; + api_key_novel = settings.api_key_novel; $('#api_url_text').val(api_server); + $('#textgenerationwebui_api_url_text').val(api_server_textgenerationwebui); + $('#api_key_novel').val(api_key_novel); } - console.log('api_server = '+ api_server ); - console.log('auto_connect = '+ auto_connect); - if(api_server !== ''&& auto_connect == true){ - $('#api_button').click(); - } - }, - error: function (jqXHR, exception) { + + console.log('api_server = ' + api_server ); + console.log('api_server_textgenerationwebui = ' + api_server_textgenerationwebui ); + console.log('api_key_novel = ' + api_key_novel); + console.log('auto_connect = '+ auto_connect); + changeMainAPI(); + + if(main_api === 'kobold' && api_server && auto_connect){ + $('#api_button').click(); + } + + if (main_api === 'textgenerationwebui' && api_server_textgenerationwebui && auto_connect) { + $('#api_button_textgenerationwebui').click(); + } + + if (main_api === 'novel' && api_key_novel && auto_connect) { + $('#api_button_novel').click(); + } + }, + error: function (jqXHR, exception) { console.log(exception); console.log(jqXHR); From 2b51a3348c7cee74a129026bebf22236c84d8559 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 11 Mar 2023 15:54:38 +0200 Subject: [PATCH 48/56] Better checkbox styles --- public/index.html | 20 +++++++++++++------- public/scripts/extensions.js | 2 +- public/style.css | 14 ++++++++------ 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/public/index.html b/public/index.html index d417a5b81..c23a7de81 100644 --- a/public/index.html +++ b/public/index.html @@ -2734,7 +2734,7 @@ function callPopup(text){ $("#dialogue_popup_cancel").css("display", "inline-block"); switch(popup_type){ - + case 'text': case 'char_not_selected': $("#dialogue_popup_ok").text("Ok"); @@ -4319,6 +4319,12 @@ // World Info Editor async function showWorldEditor() { + if (!world_info) { + popup_type = 'default'; + callPopup('

    Select a world info first!

    '); + return; + } + is_world_edit_open = true; $('#world_popup_name').val(world_info); $('#world_popup').css('display', 'flex'); @@ -5394,10 +5400,10 @@ -
    -

    Character Anchor

    -

    Style Anchor

    -
    +
    + + +
    @@ -5406,8 +5412,8 @@

    Power User Options

    -

    Auto-connects Last Server

    -

    Auto-load Last Chat

    + +
    diff --git a/public/scripts/extensions.js b/public/scripts/extensions.js index 6ed2678de..e2d03b5c2 100644 --- a/public/scripts/extensions.js +++ b/public/scripts/extensions.js @@ -7,7 +7,7 @@ let extensions = []; const settings_html = `

    -

    Extensions

    +

    Extensions: TavernAI-extras

    diff --git a/public/style.css b/public/style.css index 226bb2928..db01d892f 100644 --- a/public/style.css +++ b/public/style.css @@ -1634,13 +1634,15 @@ input[type="range"] { background-color: var(--black50a); } #anchor_checkbox, #power-user-option-checkboxes{ - + display: flex; + flex-direction: column; + row-gap: 5px; +} +#anchor_checkbox label, #power-user-option-checkboxes label { + display: flex; + flex-direction: row; + column-gap: 10px; align-items: center; - text-align: left; - display: grid; - grid-template-rows: 30px auto; - grid-template-columns: 30px auto; - grid-gap:5px; } #shadow_character_popup{ From 625f4fe8b4f181915140dcf1569b6abcca9f7e64 Mon Sep 17 00:00:00 2001 From: SillyLossy Date: Sat, 11 Mar 2023 16:13:29 +0200 Subject: [PATCH 49/56] WI editor styles adjustment --- public/index.html | 6 ++---- public/style.css | 10 +++------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/public/index.html b/public/index.html index c23a7de81..e05671a42 100644 --- a/public/index.html +++ b/public/index.html @@ -4971,14 +4971,12 @@
    -