mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Add message bias and a system message support
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@ -1 +1,3 @@
|
|||||||
node_modules
|
node_modules
|
||||||
|
/uploads
|
||||||
|
.DS_Store
|
@ -38,11 +38,13 @@
|
|||||||
const VERSION = '1.2.7';
|
const VERSION = '1.2.7';
|
||||||
var converter = new showdown.Converter();
|
var converter = new showdown.Converter();
|
||||||
var bg_menu_toggle = false;
|
var bg_menu_toggle = false;
|
||||||
|
const systemUserName = 'Chloe';
|
||||||
var default_user_name = "You";
|
var default_user_name = "You";
|
||||||
var name1 = default_user_name;
|
var name1 = default_user_name;
|
||||||
var name2 = "Chloe";
|
var name2 = systemUserName;
|
||||||
|
// might want to migrate this to 'system message' code
|
||||||
var chat = [{
|
var chat = [{
|
||||||
name: 'Chloe',
|
name: systemUserName,
|
||||||
is_user: false,
|
is_user: false,
|
||||||
is_name: true,
|
is_name: true,
|
||||||
create_date: 0,
|
create_date: 0,
|
||||||
@ -64,6 +66,22 @@
|
|||||||
var is_checked_colab = false;
|
var is_checked_colab = false;
|
||||||
var is_mes_reload_avatar = false;
|
var is_mes_reload_avatar = false;
|
||||||
|
|
||||||
|
const system_message_types = {
|
||||||
|
HELP: 'help',
|
||||||
|
WELCOME: 'welcome',
|
||||||
|
};
|
||||||
|
|
||||||
|
const system_messages = {
|
||||||
|
'help': {
|
||||||
|
"name": systemUserName,
|
||||||
|
"force_avatar": "img/chloe.png",
|
||||||
|
"is_user":false,
|
||||||
|
"is_system": true,
|
||||||
|
"is_name":true,
|
||||||
|
"mes": "Hi there! The following chat formatting commands are supported in TavernAI:<br><ul><li><tt>*text*</tt> – format the actions that your character does</li><li><tt>{text}</tt> – set the behavioral bias for your character</li></ul><p>Need more help? Visit our wiki – <a href=\"https://github.com/TavernAI/TavernAI/wiki\">TavernAI Wiki</a>!</p>"
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
var is_advanced_char_open = false;
|
var is_advanced_char_open = false;
|
||||||
var is_world_edit_open = false;
|
var is_world_edit_open = false;
|
||||||
|
|
||||||
@ -524,14 +542,16 @@
|
|||||||
count_view_mes = 0;
|
count_view_mes = 0;
|
||||||
$('#chat').html('');
|
$('#chat').html('');
|
||||||
}
|
}
|
||||||
function messageFormating(mes, ch_name){
|
function messageFormating(mes, ch_name, isSystem){
|
||||||
if(this_chid != undefined) mes = mes.replaceAll("<", "<").replaceAll(">", ">");//for Chloe
|
if(this_chid != undefined && !isSystem) mes = mes.replaceAll("<", "<").replaceAll(">", ">");//for Chloe
|
||||||
if(this_chid === undefined){
|
if(this_chid === undefined){
|
||||||
mes = mes.replace(/\*\*(.+?)\*\*/g, '<b>$1</b>').replace(/\*(.+?)\*/g, '<i>$1</i>').replace(/\n/g, '<br/>');
|
mes = mes.replace(/\*\*(.+?)\*\*/g, '<b>$1</b>').replace(/\*(.+?)\*/g, '<i>$1</i>').replace(/\n/g, '<br/>');
|
||||||
|
|
||||||
}else{
|
}else if (!isSystem) {
|
||||||
mes = converter.makeHtml(mes);
|
mes = converter.makeHtml(mes);
|
||||||
|
mes = mes.replace(/{([^}]+)}/g, '');
|
||||||
mes = mes.replace(/\n/g, '<br/>');
|
mes = mes.replace(/\n/g, '<br/>');
|
||||||
|
mes = mes.trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -547,13 +567,18 @@
|
|||||||
var messageText = mes['mes'];
|
var messageText = mes['mes'];
|
||||||
var characterName = name1;
|
var characterName = name1;
|
||||||
var avatarImg = "User Avatars/"+user_avatar;
|
var avatarImg = "User Avatars/"+user_avatar;
|
||||||
|
const isSystem = mes.is_system;
|
||||||
generatedPromtCache = '';
|
generatedPromtCache = '';
|
||||||
//thisText = thisText.split("\n").join("<br>");
|
//thisText = thisText.split("\n").join("<br>");
|
||||||
var avatarImg = "User Avatars/"+user_avatar;
|
var avatarImg = "User Avatars/"+user_avatar;
|
||||||
if(!mes['is_user']){
|
if(!mes['is_user']){
|
||||||
if(this_chid == undefined){
|
if (mes.force_avatar) {
|
||||||
|
avatarImg = mes.force_avatar;
|
||||||
|
}
|
||||||
|
else if(this_chid == undefined){
|
||||||
avatarImg = "img/chloe.png";
|
avatarImg = "img/chloe.png";
|
||||||
}else{
|
}
|
||||||
|
else{
|
||||||
if(characters[this_chid].avatar != 'none'){
|
if(characters[this_chid].avatar != 'none'){
|
||||||
avatarImg = "characters/"+characters[this_chid].avatar;
|
avatarImg = "characters/"+characters[this_chid].avatar;
|
||||||
if(is_mes_reload_avatar !== false){
|
if(is_mes_reload_avatar !== false){
|
||||||
@ -564,7 +589,8 @@
|
|||||||
avatarImg = "img/fluffy.png";
|
avatarImg = "img/fluffy.png";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
characterName = name2;
|
|
||||||
|
characterName = mes.is_system || mes.force_avatar ? mes.name : name2;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Formating
|
//Formating
|
||||||
@ -579,10 +605,18 @@
|
|||||||
messageText = messageText.replace(/<USER>/gi, name1);
|
messageText = messageText.replace(/<USER>/gi, name1);
|
||||||
messageText = messageText.replace(/<BOT>/gi, name2);
|
messageText = messageText.replace(/<BOT>/gi, name2);
|
||||||
}
|
}
|
||||||
messageText = messageFormating(messageText, characterName);
|
messageText = messageFormating(messageText, characterName, isSystem);
|
||||||
|
const bias = messageFormating(mes.extra?.bias ?? '');
|
||||||
$("#chat").append( "<div class='mes' mesid="+count_view_mes+" ch_name="+characterName+"><div class='for_checkbox'></div><input type='checkbox' class='del_checkbox'><div class=avatar><img src='"+avatarImg+"'></div><div class=mes_block><div class=ch_name>"+characterName+"<div title=Edit class=mes_edit><img src=img/scroll.png style='width:20px;height:20px;'></div><div class=mes_edit_cancel><img src=img/cancel.png></div><div class=mes_edit_done><img src=img/done.png></div></div><div class=mes_text>"+"</div></div></div>" );
|
|
||||||
|
|
||||||
|
$("#chat").append( "<div class='mes' mesid="+count_view_mes+" ch_name="+characterName+"><div class='for_checkbox'></div><input type='checkbox' class='del_checkbox'><div class=avatar><img src='"+avatarImg+"'></div><div class=mes_block><div class=ch_name>"+characterName+"<div title=Edit class=mes_edit><img src=img/scroll.png style='width:20px;height:20px;'></div><div class=mes_edit_cancel><img src=img/cancel.png></div><div class=mes_edit_done><img src=img/done.png></div></div><div class=mes_text>"+`</div><div class='mes_bias'>${bias}</div></div></div>` );
|
||||||
|
|
||||||
|
const newMessage = $(`#chat [mesid="${count_view_mes}"]`);
|
||||||
|
newMessage.data('isSystem', isSystem);
|
||||||
|
|
||||||
|
if (isSystem) {
|
||||||
|
newMessage.find('.mes_edit').hide();
|
||||||
|
}
|
||||||
|
|
||||||
if(!if_typing_text){
|
if(!if_typing_text){
|
||||||
//console.log(messageText);
|
//console.log(messageText);
|
||||||
$("#chat").children().filter('[mesid="'+count_view_mes+'"]').children('.mes_block').children('.mes_text').append(messageText);
|
$("#chat").children().filter('[mesid="'+count_view_mes+'"]').children('.mes_block').children('.mes_text').append(messageText);
|
||||||
@ -617,6 +651,40 @@
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isHelpRequest(message) {
|
||||||
|
const helpTokens = ['/?', '/help'];
|
||||||
|
return helpTokens.includes(message.trim().toLowerCase());
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendSystemMessage(type) {
|
||||||
|
const systemMessage = system_messages[type];
|
||||||
|
|
||||||
|
if (!systemMessage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newMessage = { ... systemMessage, 'send_date': Date.now() };
|
||||||
|
chat.push(newMessage);
|
||||||
|
addOneMessage(newMessage);
|
||||||
|
is_send_press = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function extractMessageBias(message) {
|
||||||
|
if (!message) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const found = [];
|
||||||
|
const rxp = /{([^}]+)}/g;
|
||||||
|
let curMatch;
|
||||||
|
|
||||||
|
while( curMatch = rxp.exec(message) ) {
|
||||||
|
found.push(curMatch[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return found.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
$( "#send_but" ).click(function() {
|
$( "#send_but" ).click(function() {
|
||||||
//$( "#send_but" ).css({"background": "url('img/load.gif')","background-size": "100%, 100%", "background-position": "center center"});
|
//$( "#send_but" ).css({"background": "url('img/load.gif')","background-size": "100%, 100%", "background-position": "center center"});
|
||||||
if(is_send_press == false){
|
if(is_send_press == false){
|
||||||
@ -645,10 +713,27 @@
|
|||||||
}
|
}
|
||||||
//$("#send_textarea").attr("disabled","disabled");
|
//$("#send_textarea").attr("disabled","disabled");
|
||||||
|
|
||||||
|
if (isHelpRequest(textareaText)) {
|
||||||
|
sendSystemMessage(system_message_types.HELP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//$("#send_textarea").blur();
|
//$("#send_textarea").blur();
|
||||||
$( "#send_but" ).css("display", "none");
|
$( "#send_but" ).css("display", "none");
|
||||||
$( "#loading_mes" ).css("display", "inline-block");
|
$( "#loading_mes" ).css("display", "inline-block");
|
||||||
|
|
||||||
|
let promptBias = null;
|
||||||
|
let messageBias = extractMessageBias(textareaText);
|
||||||
|
|
||||||
|
// gets bias of the latest message where it was applied
|
||||||
|
for (let mes of chat) {
|
||||||
|
if (mes && mes.is_user && mes.extra && mes.extra.bias) {
|
||||||
|
promptBias = mes.extra.bias;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// bias from the latest message is top priority
|
||||||
|
promptBias = messageBias ?? promptBias ?? '';
|
||||||
|
|
||||||
var storyString = "";
|
var storyString = "";
|
||||||
var userSendString = "";
|
var userSendString = "";
|
||||||
@ -682,13 +767,18 @@
|
|||||||
//PRE FORMATING STRING
|
//PRE FORMATING STRING
|
||||||
//*********************************
|
//*********************************
|
||||||
if(textareaText != ""){
|
if(textareaText != ""){
|
||||||
|
|
||||||
chat[chat.length] = {};
|
chat[chat.length] = {};
|
||||||
chat[chat.length-1]['name'] = name1;
|
chat[chat.length-1]['name'] = name1;
|
||||||
chat[chat.length-1]['is_user'] = true;
|
chat[chat.length-1]['is_user'] = true;
|
||||||
chat[chat.length-1]['is_name'] = true;
|
chat[chat.length-1]['is_name'] = true;
|
||||||
chat[chat.length-1]['send_date'] = Date.now();
|
chat[chat.length-1]['send_date'] = Date.now();
|
||||||
chat[chat.length-1]['mes'] = textareaText;
|
chat[chat.length-1]['mes'] = textareaText;
|
||||||
|
chat[chat.length-1]['extra'] = {};
|
||||||
|
|
||||||
|
if (messageBias) {
|
||||||
|
chat[chat.length-1]['extra']['bias'] = messageBias;
|
||||||
|
}
|
||||||
|
|
||||||
addOneMessage(chat[chat.length-1]);
|
addOneMessage(chat[chat.length-1]);
|
||||||
}
|
}
|
||||||
var chatString = '';
|
var chatString = '';
|
||||||
@ -796,6 +886,12 @@
|
|||||||
}else{
|
}else{
|
||||||
chat2[i] = chat[j]['mes']+'\n';
|
chat2[i] = chat[j]['mes']+'\n';
|
||||||
}
|
}
|
||||||
|
// system messages produce no text
|
||||||
|
if (chat[j]['is_system']) {
|
||||||
|
chat2[i] = '';
|
||||||
|
}
|
||||||
|
// replace bias markup
|
||||||
|
chat2[i] = (chat2[i] ?? '').replace(/{([^}]+)}/g, '');
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
//chat2 = chat2.reverse();
|
//chat2 = chat2.reverse();
|
||||||
@ -816,7 +912,7 @@
|
|||||||
|
|
||||||
for (var item of chat2) {//console.log(encode("dsfs").length);
|
for (var item of chat2) {//console.log(encode("dsfs").length);
|
||||||
chatString = item+chatString;
|
chatString = item+chatString;
|
||||||
if(encode(JSON.stringify(storyString+chatString+anchorTop+anchorBottom+charPersonality)).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(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 (is_pygmalion && i == chat2.length-1) item='<START>\n'+item;
|
//if (is_pygmalion && i == chat2.length-1) item='<START>\n'+item;
|
||||||
@ -833,7 +929,7 @@
|
|||||||
for(let iii = 0; iii < mesExamplesArray.length; iii++){//mesExamplesArray It need to make from end to start
|
for(let iii = 0; iii < mesExamplesArray.length; iii++){//mesExamplesArray It need to make from end to start
|
||||||
|
|
||||||
mesExmString = mesExmString+mesExamplesArray[iii];
|
mesExmString = mesExmString+mesExamplesArray[iii];
|
||||||
if(encode(JSON.stringify(storyString+mesExmString+chatString+anchorTop+anchorBottom+charPersonality)).length+120 < this_max_context){ //example of dialogs
|
if(encode(JSON.stringify(storyString+mesExmString+chatString+anchorTop+anchorBottom+charPersonality+promptBias)).length+120 < this_max_context){ //example of dialogs
|
||||||
if(!is_pygmalion){
|
if(!is_pygmalion){
|
||||||
mesExamplesArray[iii] = mesExamplesArray[iii].replace(/<START>/i, 'This is how '+name2+' should talk');//An example of how '+name2+' responds
|
mesExamplesArray[iii] = mesExamplesArray[iii].replace(/<START>/i, 'This is how '+name2+' should talk');//An example of how '+name2+' responds
|
||||||
}
|
}
|
||||||
@ -933,7 +1029,7 @@
|
|||||||
}
|
}
|
||||||
function checkPromtSize(){
|
function checkPromtSize(){
|
||||||
setPromtString();
|
setPromtString();
|
||||||
let thisPromtContextSize = encode(JSON.stringify(storyString+mesExmString+mesSendString+anchorTop+anchorBottom+charPersonality+generatedPromtCache)).length+120;
|
let thisPromtContextSize = encode(JSON.stringify(storyString+mesExmString+mesSendString+anchorTop+anchorBottom+charPersonality+generatedPromtCache+promptBias)).length+120;
|
||||||
if(thisPromtContextSize > this_max_context){
|
if(thisPromtContextSize > this_max_context){
|
||||||
if(count_exm_add > 0){
|
if(count_exm_add > 0){
|
||||||
//mesExamplesArray.length = mesExamplesArray.length-1;
|
//mesExamplesArray.length = mesExamplesArray.length-1;
|
||||||
@ -961,7 +1057,7 @@
|
|||||||
}else{
|
}else{
|
||||||
mesSendString = '<START>\n'+mesSendString;
|
mesSendString = '<START>\n'+mesSendString;
|
||||||
}
|
}
|
||||||
finalPromt = storyString+mesExmString+mesSendString+generatedPromtCache;
|
finalPromt = storyString+mesExmString+mesSendString+generatedPromtCache+promptBias;
|
||||||
|
|
||||||
var generate_data;
|
var generate_data;
|
||||||
if(main_api == 'kobold'){
|
if(main_api == 'kobold'){
|
||||||
@ -2592,6 +2688,12 @@
|
|||||||
//***Message Editor***
|
//***Message Editor***
|
||||||
$(document).on('click', '.mes_edit', function(){
|
$(document).on('click', '.mes_edit', function(){
|
||||||
if(this_chid !== undefined){
|
if(this_chid !== undefined){
|
||||||
|
const message = $(this).closest('.mes');
|
||||||
|
|
||||||
|
if (message.data('isSystem')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let chatScrollPosition = $("#chat").scrollTop();
|
let chatScrollPosition = $("#chat").scrollTop();
|
||||||
if(this_edit_mes_id !== undefined){
|
if(this_edit_mes_id !== undefined){
|
||||||
let mes_edited = $('#chat').children().filter('[mesid="'+this_edit_mes_id+'"]').children('.mes_block').children('.ch_name').children('.mes_edit_done');
|
let mes_edited = $('#chat').children().filter('[mesid="'+this_edit_mes_id+'"]').children('.mes_block').children('.ch_name').children('.mes_edit_done');
|
||||||
@ -2662,12 +2764,23 @@
|
|||||||
var text = div.parent().parent().children('.mes_text').children('.edit_textarea').val();
|
var text = div.parent().parent().children('.mes_text').children('.edit_textarea').val();
|
||||||
//var text = chat[this_edit_mes_id];
|
//var text = chat[this_edit_mes_id];
|
||||||
text = text.trim();
|
text = text.trim();
|
||||||
|
const bias = extractMessageBias(text);
|
||||||
chat[this_edit_mes_id]['mes'] = text;
|
chat[this_edit_mes_id]['mes'] = text;
|
||||||
|
|
||||||
|
// editing old messages
|
||||||
|
if (!chat[this_edit_mes_id]['extra']) {
|
||||||
|
chat[this_edit_mes_id]['extra'] = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
chat[this_edit_mes_id]['extra']['bias'] = bias ?? null;
|
||||||
|
|
||||||
div.parent().parent().children('.mes_text').empty();
|
div.parent().parent().children('.mes_text').empty();
|
||||||
div.css('display','none');
|
div.css('display','none');
|
||||||
div.parent().children('.mes_edit_cancel').css('display','none');
|
div.parent().children('.mes_edit_cancel').css('display','none');
|
||||||
div.parent().children('.mes_edit').css('display','inline-block');
|
div.parent().children('.mes_edit').css('display','inline-block');
|
||||||
div.parent().parent().children('.mes_text').append(messageFormating(text,this_edit_mes_chname));
|
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));
|
||||||
this_edit_mes_id = undefined;
|
this_edit_mes_id = undefined;
|
||||||
saveChat();
|
saveChat();
|
||||||
}
|
}
|
||||||
@ -3807,7 +3920,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- <div contenteditable="true" id="send_textarea">Type a message...</div> -->
|
<!-- <div contenteditable="true" id="send_textarea">Type a message...</div> -->
|
||||||
<textarea id="send_textarea" placeholder="Type a message..." name="text"></textarea>
|
<textarea id="send_textarea" placeholder="Type a message. Send /? or /help to get help..." name="text"></textarea>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
$('#send_textarea').on('input', function () {
|
$('#send_textarea').on('input', function () {
|
||||||
|
@ -48,6 +48,12 @@ body {
|
|||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: rgb(229, 224, 216);
|
color: rgb(229, 224, 216);
|
||||||
}
|
}
|
||||||
|
.mes_bias {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
font-weight: 500;
|
||||||
|
color: darkgoldenrod;
|
||||||
|
}
|
||||||
code {
|
code {
|
||||||
background-color: #a8a8a8;
|
background-color: #a8a8a8;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
|
Reference in New Issue
Block a user