mirror of
				https://github.com/SillyTavern/SillyTavern.git
				synced 2025-06-05 21:59:27 +02:00 
			
		
		
		
	Merge branch 'dev' of https://github.com/SillyLossy/TavernAI into dev
This commit is contained in:
		| @@ -2453,7 +2453,7 @@ | ||||
|     </div> | ||||
|  | ||||
|     <div id="message_template" class="template_element"> | ||||
|         <div class="mes" mesid="${count_view_mes}" ch_name="${characterName}" is_user="${mes.is_user}" is_system="${mes.is_system}"> | ||||
|         <div class="mes" mesid="" ch_name="" is_user="" is_system="" bookmark_link=""> | ||||
|             <div class="for_checkbox"></div><input type="checkbox" class="del_checkbox"> | ||||
|             <div class="mesAvatarWrapper"> | ||||
|                 <div class="avatar"> | ||||
| @@ -2468,6 +2468,7 @@ | ||||
|                     <span class="name_text">${characterName}</span> | ||||
|  | ||||
|                     <div class="mes_buttons"> | ||||
|                         <div title="Open bookmark chat" class="mes_bookmark fa-solid fa-bookmark"></div> | ||||
|                         <div title="Generate Image" class="sd_message_gen fa-solid fa-paintbrush"></div> | ||||
|                         <div title="Narrate" class="mes_narrate fa-solid fa-bullhorn"></div> | ||||
|                         <div title="Prompt" class="mes_prompt fa-solid fa-square-poll-horizontal "></div> | ||||
|   | ||||
| @@ -833,6 +833,13 @@ async function getCharacters() { | ||||
|             characters[i] = []; | ||||
|             characters[i] = getData[i]; | ||||
|             characters[i]['name'] = DOMPurify.sanitize(characters[i]['name']); | ||||
|  | ||||
|             // For dropped-in cards | ||||
|             if (!characters[i]['chat']) { | ||||
|                 characters[i]['chat'] = `${characters[i]['name']} - ${humanizedDateTime()}`; | ||||
|             } | ||||
|  | ||||
|             characters[i]['chat'] = String(characters[i]['chat']); | ||||
|         } | ||||
|         if (this_chid != undefined && this_chid != "invalid-safety-id") { | ||||
|             $("#avatar_url_pole").val(characters[this_chid].avatar); | ||||
| @@ -1062,9 +1069,15 @@ function messageFormatting(mes, ch_name, isSystem, isUser) { | ||||
|     return mes; | ||||
| } | ||||
|  | ||||
| function getMessageFromTemplate({ mesId, characterName, isUser, avatarImg, bias, isSystem, title, timerValue, timerTitle } = {}) { | ||||
| function getMessageFromTemplate({ mesId, characterName, isUser, avatarImg, bias, isSystem, title, timerValue, timerTitle, bookmarkLink } = {}) { | ||||
|     const mes = $('#message_template .mes').clone(); | ||||
|     mes.attr({ 'mesid': mesId, 'ch_name': characterName, 'is_user': isUser, 'is_system': !!isSystem }); | ||||
|     mes.attr({ | ||||
|         'mesid': mesId, | ||||
|         'ch_name': characterName, | ||||
|         'is_user': isUser, | ||||
|         'is_system': !!isSystem, | ||||
|         'bookmark_link': bookmarkLink, | ||||
|     }); | ||||
|     mes.find('.avatar img').attr('src', avatarImg); | ||||
|     mes.find('.ch_name .name_text').text(characterName); | ||||
|     mes.find('.mes_bias').html(bias); | ||||
| @@ -1098,15 +1111,7 @@ function addCopyToCodeBlocks(messageElement) { | ||||
|             codeBlocks.get(i).appendChild(copyButton); | ||||
|             copyButton.addEventListener('pointerup', function (event) { | ||||
|                 navigator.clipboard.writeText(codeBlocks.get(i).innerText); | ||||
|                 const copiedMsg = document.createElement("div"); | ||||
|                 copiedMsg.classList.add('code-copied'); | ||||
|                 copiedMsg.innerText = "Copied!"; | ||||
|                 copiedMsg.style.top = `${event.clientY - 55}px`; | ||||
|                 copiedMsg.style.left = `${event.clientX - 55}px`; | ||||
|                 document.body.append(copiedMsg); | ||||
|                 setTimeout(() => { | ||||
|                     document.body.removeChild(copiedMsg); | ||||
|                 }, 1000); | ||||
|                 toastr.info('Copied!', '', { timeOut: 2000 }); | ||||
|             }); | ||||
|         } | ||||
|     } | ||||
| @@ -1158,6 +1163,7 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true | ||||
|         mes.is_user, | ||||
|     ); | ||||
|     const bias = messageFormatting(mes.extra?.bias ?? ""); | ||||
|     const bookmarkLink = mes?.extra?.bookmark_link ?? ''; | ||||
|  | ||||
|     let params = { | ||||
|         mesId: count_view_mes, | ||||
| @@ -1167,6 +1173,7 @@ function addOneMessage(mes, { type = "normal", insertAfter = null, scroll = true | ||||
|         bias: bias, | ||||
|         isSystem: isSystem, | ||||
|         title: title, | ||||
|         bookmarkLink: bookmarkLink, | ||||
|         ...formatGenerationTimer(mes.gen_started, mes.gen_finished), | ||||
|     }; | ||||
|  | ||||
| @@ -1496,7 +1503,7 @@ class StreamingProcessor { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         $(`#chat .mes[mesid="${messageId}"] .mes_stop`).css({ 'display': 'block' }); | ||||
|         $(`#chat .mes[mesid="${messageId}"] .mes_stop`).css({ 'display': '' }); | ||||
|         $(`#chat .mes[mesid="${messageId}"] .mes_buttons`).css({ 'display': 'none' }); | ||||
|     } | ||||
|  | ||||
| @@ -1506,7 +1513,7 @@ class StreamingProcessor { | ||||
|         } | ||||
|  | ||||
|         $(`#chat .mes[mesid="${messageId}"] .mes_stop`).css({ 'display': 'none' }); | ||||
|         $(`#chat .mes[mesid="${messageId}"] .mes_buttons`).css({ 'display': 'block' }); | ||||
|         $(`#chat .mes[mesid="${messageId}"] .mes_buttons`).css({ 'display': '' }); | ||||
|     } | ||||
|  | ||||
|     onStartStreaming(text) { | ||||
| @@ -3990,7 +3997,7 @@ function messageEditDone(div) { | ||||
|  | ||||
|     mesBlock.find(".mes_text").empty(); | ||||
|     mesBlock.find(".mes_edit_buttons").css("display", "none"); | ||||
|     mesBlock.find(".mes_buttons").css("display", "inline-block"); | ||||
|     mesBlock.find(".mes_buttons").css("display", ""); | ||||
|     mesBlock.find(".mes_text").append( | ||||
|         messageFormatting( | ||||
|             text, | ||||
| @@ -6019,15 +6026,7 @@ $(document).ready(function () { | ||||
|                     var edit_mes_id = $(this).closest(".mes").attr("mesid"); | ||||
|                     var text = chat[edit_mes_id]["mes"]; | ||||
|                     navigator.clipboard.writeText(text); | ||||
|                     const copiedMsg = document.createElement("div"); | ||||
|                     copiedMsg.classList.add('code-copied'); | ||||
|                     copiedMsg.innerText = "Copied!"; | ||||
|                     copiedMsg.style.top = `${event.clientY - 55}px`; | ||||
|                     copiedMsg.style.left = `${event.clientX - 55}px`; | ||||
|                     document.body.append(copiedMsg); | ||||
|                     setTimeout(() => { | ||||
|                         document.body.removeChild(copiedMsg); | ||||
|                     }, 1000); | ||||
|                     toastr.info('Copied!', '', { timeOut: 2000 }); | ||||
|                 } catch (err) { | ||||
|                     console.error('Failed to copy: ', err); | ||||
|                 } | ||||
| @@ -6140,7 +6139,7 @@ $(document).ready(function () { | ||||
|  | ||||
|         $(this).closest(".mes_block").find(".mes_text").empty(); | ||||
|         $(this).closest(".mes_edit_buttons").css("display", "none"); | ||||
|         $(this).closest(".mes_block").find(".mes_buttons").css("display", "inline-block"); | ||||
|         $(this).closest(".mes_block").find(".mes_buttons").css("display", ""); | ||||
|         $(this) | ||||
|             .closest(".mes_block") | ||||
|             .find(".mes_text") | ||||
| @@ -6213,8 +6212,9 @@ $(document).ready(function () { | ||||
|         showSwipeButtons(); | ||||
|     }); | ||||
|  | ||||
|     $(document).on("click", ".mes_edit_copy", function () { | ||||
|         if (!confirm('Create a copy of this message?')) { | ||||
|     $(document).on("click", ".mes_edit_copy", async function () { | ||||
|         const confirmation = await callPopup('Create a copy of this message?', 'confirm'); | ||||
|         if (!confirmation) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
| @@ -6234,8 +6234,9 @@ $(document).ready(function () { | ||||
|     }); | ||||
|  | ||||
|  | ||||
|     $(document).on("click", ".mes_edit_delete", function () { | ||||
|         if (!confirm("Are you sure you want to delete this message?")) { | ||||
|     $(document).on("click", ".mes_edit_delete", async function () { | ||||
|         const confirmation = await callPopup("Are you sure you want to delete this message?", 'confirm'); | ||||
|         if (!confirmation) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
| @@ -6432,8 +6433,14 @@ $(document).ready(function () { | ||||
|         select_rm_characters(); | ||||
|     }); | ||||
|  | ||||
|     $(document).on("click", ".select_chat_block, .bookmark_link", async function () { | ||||
|         let file_name = $(this).attr("file_name").replace(".jsonl", ""); | ||||
|     $(document).on("click", ".select_chat_block, .bookmark_link, .mes_bookmark", async function () { | ||||
|         let file_name = $(this).hasClass('mes_bookmark') | ||||
|             ? $(this).closest('.mes').attr('bookmark_link') | ||||
|             : $(this).attr("file_name").replace(".jsonl", ""); | ||||
|  | ||||
|         if (!file_name) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (selected_group) { | ||||
|             await openGroupChat(selected_group, file_name); | ||||
| @@ -6598,10 +6605,6 @@ $(document).ready(function () { | ||||
|         }); | ||||
|     }); | ||||
|  | ||||
|     $('#chat').on('scroll', () => { | ||||
|         $('.code-copied').css({ 'display': 'none' }); | ||||
|     }); | ||||
|  | ||||
|     $(document).on('click', '.mes_img_enlarge', enlargeMessageImage); | ||||
|     $(document).on('click', '.mes_img_delete', deleteMessageImage); | ||||
|  | ||||
|   | ||||
| @@ -124,6 +124,26 @@ function showBookmarksButtons() { | ||||
| } | ||||
|  | ||||
| async function createNewBookmark() { | ||||
|     if (!chat.length) { | ||||
|         toastr.warning('The chat is empty.', 'Bookmark creation failed'); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
|     const mesId = chat.length - 1; | ||||
|     const lastMes = chat[mesId]; | ||||
|  | ||||
|     if (typeof lastMes.extra !== 'object') { | ||||
|         lastMes.extra = {}; | ||||
|     } | ||||
|  | ||||
|     if (lastMes.extra.bookmark_link) { | ||||
|         const confirm = await callPopup('Bookmark checkpoint for the last message already exists. Would you like to replace it?', 'confirm'); | ||||
|  | ||||
|         if (!confirm) { | ||||
|             return; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     let name = await getBookmarkName(); | ||||
|  | ||||
|     if (!name) { | ||||
| @@ -139,9 +159,11 @@ async function createNewBookmark() { | ||||
|         await saveChat(name, newMetadata); | ||||
|     } | ||||
|  | ||||
|     let mainMessage = stringFormat(system_messages[system_message_types.BOOKMARK_CREATED].mes, name, name); | ||||
|     sendSystemMessage(system_message_types.BOOKMARK_CREATED, mainMessage); | ||||
|     lastMes.extra['bookmark_link'] = name; | ||||
|     $(`.mes[mesid="${mesId}"]`).attr('bookmark_link', name); | ||||
|  | ||||
|     await saveChatConditional(); | ||||
|     toastr.success('Click the bookmark icon in the last message to open the checkpoint chat.', 'Bookmark created', { timeOut: 10000 }); | ||||
| } | ||||
|  | ||||
| async function backToMainChat() { | ||||
|   | ||||
| @@ -11,15 +11,7 @@ function openContextTemplateEditor() { | ||||
| function copyTemplateParameter(event) { | ||||
|     const text = $(event.target).text(); | ||||
|     navigator.clipboard.writeText(text); | ||||
|     const copiedMsg = document.createElement("div"); | ||||
|     copiedMsg.classList.add('code-copied'); | ||||
|     copiedMsg.innerText = "Copied!"; | ||||
|     copiedMsg.style.top = `${event.clientY - 55}px`; | ||||
|     copiedMsg.style.left = `${event.clientX - 55}px`; | ||||
|     document.body.append(copiedMsg); | ||||
|     setTimeout(() => { | ||||
|         document.body.removeChild(copiedMsg); | ||||
|     }, 1000); | ||||
|     toastr.info('Copied!', '', { timeOut: 2000 }); | ||||
| } | ||||
|  | ||||
| jQuery(() => { | ||||
|   | ||||
| @@ -174,6 +174,7 @@ function debugTtsPlayback() { | ||||
|             "audioQueueProcessorReady": audioQueueProcessorReady, | ||||
|             "ttsJobQueue": ttsJobQueue, | ||||
|             "currentTtsJob": currentTtsJob, | ||||
|             "ttsConfig": extension_settings.tts | ||||
|         } | ||||
|     )) | ||||
| } | ||||
| @@ -372,6 +373,7 @@ async function processTtsQueue() { | ||||
|     try { | ||||
|         if (!text) { | ||||
|             console.warn('Got empty text in TTS queue job.'); | ||||
|             completeTtsJob() | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|   | ||||
| @@ -2297,25 +2297,25 @@ input[type="range"]::-webkit-slider-thumb { | ||||
|     margin-right: 30px; | ||||
| } | ||||
|  | ||||
| .mes_prompt, | ||||
| .mes_narrate, | ||||
| .sd_message_gen, | ||||
| .mes_copy, | ||||
| .mes_edit { | ||||
| .mes_buttons>div { | ||||
|     cursor: pointer; | ||||
|     transition: 0.3s ease-in-out; | ||||
|     filter: drop-shadow(0px 0px 2px black); | ||||
|     opacity: 0.2; | ||||
| } | ||||
|  | ||||
| .mes_edit:hover, | ||||
| .mes_copy:hover, | ||||
| .sd_message_gen:hover, | ||||
| .mes_narrate:hover, | ||||
| .mes_stop:hover { | ||||
| .mes_buttons>div:hover { | ||||
|     opacity: 1; | ||||
| } | ||||
|  | ||||
| .mes_bookmark { | ||||
|     display: none; | ||||
| } | ||||
|  | ||||
| .mes:not([bookmark_link='']) .mes_bookmark { | ||||
|     display: inline-block; | ||||
| } | ||||
|  | ||||
| .mes_edit_buttons { | ||||
|     display: none; | ||||
|     flex-direction: row; | ||||
| @@ -3611,17 +3611,6 @@ label[for="extensions_autoconnect"] { | ||||
|     opacity: 0.8; | ||||
| } | ||||
|  | ||||
| .code-copied { | ||||
|     position: absolute; | ||||
|     z-index: 10000; | ||||
|     font-size: var(--mainFontSize); | ||||
|     color: var(--SmartThemeBodyColor); | ||||
|     background-color: var(--SmartThemeFastUIBGColor); | ||||
|     border-radius: 5px; | ||||
|     padding: 6px; | ||||
|     border: 1px solid var(--grey30a); | ||||
| } | ||||
|  | ||||
| .inline-drawer-icon { | ||||
|     display: block; | ||||
|     cursor: pointer; | ||||
|   | ||||
							
								
								
									
										76
									
								
								server.js
									
									
									
									
									
								
							
							
						
						
									
										76
									
								
								server.js
									
									
									
									
									
								
							| @@ -515,65 +515,51 @@ app.post("/generate_textgenerationwebui", jsonParser, async function (request, r | ||||
|  | ||||
|  | ||||
| app.post("/savechat", jsonParser, function (request, response) { | ||||
|     try { | ||||
|         var dir_name = String(request.body.avatar_url).replace('.png', ''); | ||||
|         let chat_data = request.body.chat; | ||||
|         let jsonlData = chat_data.map(JSON.stringify).join('\n'); | ||||
|     fs.writeFile(`${chatsPath + dir_name}/${sanitize(request.body.file_name)}.jsonl`, jsonlData, 'utf8', function (err) { | ||||
|         if (err) { | ||||
|             response.send(err); | ||||
|             return console.log(err); | ||||
|         } else { | ||||
|             response.send({ result: "ok" }); | ||||
|         fs.writeFileSync(`${chatsPath + dir_name}/${sanitize(String(request.body.file_name))}.jsonl`, jsonlData, 'utf8'); | ||||
|         return response.send({ result: "ok" }); | ||||
|     } catch (error) { | ||||
|         response.send(error); | ||||
|         return console.log(error); | ||||
|     } | ||||
| }); | ||||
|  | ||||
| }); | ||||
| app.post("/getchat", jsonParser, function (request, response) { | ||||
|     var dir_name = String(request.body.avatar_url).replace('.png', ''); | ||||
|     try { | ||||
|         const dirName = String(request.body.avatar_url).replace('.png', ''); | ||||
|         const chatDirExists = fs.existsSync(chatsPath + dirName); | ||||
|  | ||||
|     fs.stat(chatsPath + dir_name, function (err, stat) { | ||||
|  | ||||
|         if (stat === undefined) {		//if no chat dir for the character is found, make one with the character name | ||||
|  | ||||
|             fs.mkdirSync(chatsPath + dir_name); | ||||
|             response.send({}); | ||||
|             return; | ||||
|         } else { | ||||
|  | ||||
|             if (err === null) { //if there is a dir, then read the requested file from the JSON call | ||||
|  | ||||
|                 fs.stat(`${chatsPath + dir_name}/${sanitize(request.body.file_name)}.jsonl`, function (err, stat) { | ||||
|                     if (err === null) { //if no error (the file exists), read the file | ||||
|                         if (stat !== undefined) { | ||||
|                             fs.readFile(`${chatsPath + dir_name}/${sanitize(request.body.file_name)}.jsonl`, 'utf8', (err, data) => { | ||||
|                                 if (err) { | ||||
|                                     console.error(err); | ||||
|                                     response.send(err); | ||||
|                                     return; | ||||
|         //if no chat dir for the character is found, make one with the character name | ||||
|         if (!chatDirExists) { | ||||
|             fs.mkdirSync(chatsPath + dirName); | ||||
|             return response.send({}); | ||||
|         } | ||||
|                                 //console.log(data); | ||||
|  | ||||
|  | ||||
|         if (!request.body.file_name) { | ||||
|             return response.send({}); | ||||
|         } | ||||
|  | ||||
|         const fileName = `${chatsPath + dirName}/${sanitize(String(request.body.file_name))}.jsonl`; | ||||
|         const chatFileExists = fs.existsSync(fileName); | ||||
|  | ||||
|         if (!chatFileExists) { | ||||
|             return response.send({}); | ||||
|         } | ||||
|  | ||||
|         const data = fs.readFileSync(fileName, 'utf8'); | ||||
|         const lines = data.split('\n'); | ||||
|  | ||||
|         // Iterate through the array of strings and parse each line as JSON | ||||
|         const jsonData = lines.map(tryParse).filter(x => x); | ||||
|                                 response.send(jsonData); | ||||
|                                 //console.log('read the requested file') | ||||
|  | ||||
|                             }); | ||||
|         return response.send(jsonData); | ||||
|     } catch (error) { | ||||
|         console.error(error); | ||||
|         return response.send({}); | ||||
|     } | ||||
|                     } else { | ||||
|                         response.send({}); | ||||
|                         //return console.log(err); | ||||
|                         return; | ||||
|                     } | ||||
|                 }); | ||||
|             } else { | ||||
|                 console.error(err); | ||||
|                 response.send({}); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| }); | ||||
|  | ||||
| app.post("/getstatus", jsonParser, async function (request, response_getstatus = response) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user