mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Neutral assistant chat space
This commit is contained in:
152
public/script.js
152
public/script.js
@ -485,6 +485,7 @@ export let itemizedPrompts = [];
|
|||||||
|
|
||||||
export const systemUserName = 'SillyTavern System';
|
export const systemUserName = 'SillyTavern System';
|
||||||
export const neutralCharacterName = 'Assistant';
|
export const neutralCharacterName = 'Assistant';
|
||||||
|
export const neutralCharacterAvatar = 'ST_your_ai_assistant.png';
|
||||||
let default_user_name = 'User';
|
let default_user_name = 'User';
|
||||||
export let name1 = default_user_name;
|
export let name1 = default_user_name;
|
||||||
export let name2 = systemUserName;
|
export let name2 = systemUserName;
|
||||||
@ -565,6 +566,7 @@ export const system_message_types = {
|
|||||||
HOTKEYS: 'hotkeys',
|
HOTKEYS: 'hotkeys',
|
||||||
MACROS: 'macros',
|
MACROS: 'macros',
|
||||||
WELCOME_PROMPT: 'welcome_prompt',
|
WELCOME_PROMPT: 'welcome_prompt',
|
||||||
|
PAST_CHAT_HINT: 'past_chat_hint',
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -692,6 +694,16 @@ async function getSystemMessages() {
|
|||||||
isSmallSys: true,
|
isSmallSys: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
past_chat_hint: {
|
||||||
|
name: neutralCharacterName,
|
||||||
|
force_avatar: system_avatar,
|
||||||
|
is_user: false,
|
||||||
|
is_system: true,
|
||||||
|
mes: await renderTemplateAsync('pastChatHint'),
|
||||||
|
extra: {
|
||||||
|
isSmallSys: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1698,13 +1710,13 @@ async function delChat(chatfile) {
|
|||||||
headers: getRequestHeaders(),
|
headers: getRequestHeaders(),
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
chatfile: chatfile,
|
chatfile: chatfile,
|
||||||
avatar_url: characters[this_chid].avatar,
|
avatar_url: characters[this_chid]?.avatar ?? neutralCharacterAvatar,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
if (response.ok === true) {
|
if (response.ok === true) {
|
||||||
// choose another chat if current was deleted
|
// choose another chat if current was deleted
|
||||||
const name = chatfile.replace('.jsonl', '');
|
const name = chatfile.replace('.jsonl', '');
|
||||||
if (name === characters[this_chid].chat) {
|
if (name === characters[this_chid]?.chat || name === chat_metadata?.chat_name) {
|
||||||
chat_metadata = {};
|
chat_metadata = {};
|
||||||
await replaceCurrentChat();
|
await replaceCurrentChat();
|
||||||
}
|
}
|
||||||
@ -1719,15 +1731,20 @@ export async function replaceCurrentChat() {
|
|||||||
const chatsResponse = await fetch('/api/characters/chats', {
|
const chatsResponse = await fetch('/api/characters/chats', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: getRequestHeaders(),
|
headers: getRequestHeaders(),
|
||||||
body: JSON.stringify({ avatar_url: characters[this_chid].avatar }),
|
body: JSON.stringify({ avatar_url: characters[this_chid]?.avatar ?? neutralCharacterAvatar }),
|
||||||
});
|
});
|
||||||
|
|
||||||
if (chatsResponse.ok) {
|
if (chatsResponse.ok) {
|
||||||
const chats = Object.values(await chatsResponse.json());
|
const chats = Object.values(await chatsResponse.json());
|
||||||
chats.sort((a, b) => sortMoments(timestampToMoment(a.last_mes), timestampToMoment(b.last_mes)));
|
chats.sort((a, b) => sortMoments(timestampToMoment(a.last_mes), timestampToMoment(b.last_mes)));
|
||||||
|
|
||||||
|
// Create a new chat for assistant
|
||||||
|
if (this_chid === undefined && name2 === neutralCharacterName) {
|
||||||
|
await openAssistantChat();
|
||||||
|
}
|
||||||
|
|
||||||
// pick existing chat
|
// pick existing chat
|
||||||
if (chats.length && typeof chats[0] === 'object') {
|
else if (chats.length && typeof chats[0] === 'object') {
|
||||||
characters[this_chid].chat = chats[0].file_name.replace('.jsonl', '');
|
characters[this_chid].chat = chats[0].file_name.replace('.jsonl', '');
|
||||||
$('#selected_chat_pole').val(characters[this_chid].chat);
|
$('#selected_chat_pole').val(characters[this_chid].chat);
|
||||||
saveCharacterDebounced();
|
saveCharacterDebounced();
|
||||||
@ -1845,7 +1862,7 @@ export async function reloadCurrentChat() {
|
|||||||
if (selected_group) {
|
if (selected_group) {
|
||||||
await getGroupChat(selected_group, true);
|
await getGroupChat(selected_group, true);
|
||||||
}
|
}
|
||||||
else if (this_chid !== undefined) {
|
else if (this_chid !== undefined || (this_chid === undefined && name2 === neutralCharacterName)) {
|
||||||
await getChat();
|
await getChat();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1862,7 +1879,7 @@ export async function reloadCurrentChat() {
|
|||||||
/**
|
/**
|
||||||
* Send the message currently typed into the chat box.
|
* Send the message currently typed into the chat box.
|
||||||
*/
|
*/
|
||||||
export function sendTextareaMessage() {
|
export async function sendTextareaMessage() {
|
||||||
if (is_send_press) return;
|
if (is_send_press) return;
|
||||||
if (isExecutingCommandsFromChatInput) return;
|
if (isExecutingCommandsFromChatInput) return;
|
||||||
|
|
||||||
@ -1880,6 +1897,10 @@ export function sendTextareaMessage() {
|
|||||||
generateType = 'continue';
|
generateType = 'continue';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (textareaText && this_chid === undefined) {
|
||||||
|
await openAssistantChat();
|
||||||
|
}
|
||||||
|
|
||||||
Generate(generateType);
|
Generate(generateType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5911,52 +5932,45 @@ export function saveChatDebounced() {
|
|||||||
|
|
||||||
export async function saveChat(chat_name, withMetadata, mesId) {
|
export async function saveChat(chat_name, withMetadata, mesId) {
|
||||||
const metadata = { ...chat_metadata, ...(withMetadata || {}) };
|
const metadata = { ...chat_metadata, ...(withMetadata || {}) };
|
||||||
let file_name = chat_name ?? characters[this_chid]?.chat;
|
let fileName = chat_name ?? characters[this_chid]?.chat ?? chat_metadata?.chat_name;
|
||||||
|
|
||||||
if (!file_name) {
|
if (!fileName) {
|
||||||
console.warn('saveChat called without chat_name and no chat file found');
|
console.warn('saveChat called without chat_name and no chat file found');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (characters[this_chid]) {
|
||||||
characters[this_chid]['date_last_chat'] = Date.now();
|
characters[this_chid]['date_last_chat'] = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
chat.forEach(function (item, i) {
|
chat.forEach(function (item, i) {
|
||||||
if (item['is_group']) {
|
if (item['is_group']) {
|
||||||
toastr.error('Trying to save group chat with regular saveChat function. Aborting to prevent corruption.');
|
toastr.error('Trying to save group chat with regular saveChat function. Aborting to prevent corruption.');
|
||||||
throw new Error('Group chat saved from saveChat');
|
throw new Error('Group chat saved from saveChat');
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (item.is_user) {
|
|
||||||
//var str = item.mes.replace(`${name1}:`, `${name1}:`);
|
|
||||||
//chat[i].mes = str;
|
|
||||||
//chat[i].name = name1;
|
|
||||||
} else if (i !== chat.length - 1 && chat[i].swipe_id !== undefined) {
|
|
||||||
// delete chat[i].swipes;
|
|
||||||
// delete chat[i].swipe_id;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const trimmed_chat = (mesId !== undefined && mesId >= 0 && mesId < chat.length)
|
const trimmedChat = (mesId !== undefined && mesId >= 0 && mesId < chat.length)
|
||||||
? chat.slice(0, parseInt(mesId) + 1)
|
? chat.slice(0, parseInt(mesId) + 1)
|
||||||
: chat;
|
: chat;
|
||||||
|
|
||||||
var save_chat = [
|
const saveChat = [
|
||||||
{
|
{
|
||||||
user_name: name1,
|
user_name: name1,
|
||||||
character_name: name2,
|
character_name: name2,
|
||||||
create_date: chat_create_date,
|
create_date: chat_create_date,
|
||||||
chat_metadata: metadata,
|
chat_metadata: metadata,
|
||||||
},
|
},
|
||||||
...trimmed_chat,
|
...trimmedChat,
|
||||||
];
|
];
|
||||||
return jQuery.ajax({
|
return jQuery.ajax({
|
||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/api/chats/save',
|
url: '/api/chats/save',
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
ch_name: characters[this_chid].name,
|
ch_name: characters[this_chid]?.name ?? neutralCharacterName,
|
||||||
file_name: file_name,
|
avatar_url: characters[this_chid]?.avatar ?? neutralCharacterAvatar,
|
||||||
chat: save_chat,
|
file_name: fileName,
|
||||||
avatar_url: characters[this_chid].avatar,
|
chat: saveChat,
|
||||||
}),
|
}),
|
||||||
beforeSend: function () {
|
beforeSend: function () {
|
||||||
|
|
||||||
@ -6091,9 +6105,9 @@ export async function getChat() {
|
|||||||
type: 'POST',
|
type: 'POST',
|
||||||
url: '/api/chats/get',
|
url: '/api/chats/get',
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
ch_name: characters[this_chid].name,
|
ch_name: characters[this_chid]?.name ?? neutralCharacterName,
|
||||||
file_name: characters[this_chid].chat,
|
file_name: characters[this_chid]?.chat ?? chat_metadata?.chat_name,
|
||||||
avatar_url: characters[this_chid].avatar,
|
avatar_url: characters[this_chid]?.avatar ?? neutralCharacterAvatar,
|
||||||
}),
|
}),
|
||||||
dataType: 'json',
|
dataType: 'json',
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
@ -6124,7 +6138,7 @@ export async function getChat() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function getChatResult() {
|
async function getChatResult() {
|
||||||
name2 = characters[this_chid].name;
|
name2 = characters[this_chid]?.name ?? neutralCharacterName;
|
||||||
let freshChat = false;
|
let freshChat = false;
|
||||||
if (chat.length === 0) {
|
if (chat.length === 0) {
|
||||||
const message = getFirstMessage();
|
const message = getFirstMessage();
|
||||||
@ -6150,7 +6164,7 @@ async function getChatResult() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getFirstMessage() {
|
function getFirstMessage() {
|
||||||
const firstMes = characters[this_chid].first_mes || '';
|
const firstMes = characters[this_chid]?.first_mes || '';
|
||||||
const alternateGreetings = characters[this_chid]?.data?.alternate_greetings;
|
const alternateGreetings = characters[this_chid]?.data?.alternate_greetings;
|
||||||
|
|
||||||
const message = {
|
const message = {
|
||||||
@ -6180,9 +6194,13 @@ function getFirstMessage() {
|
|||||||
|
|
||||||
export async function openCharacterChat(file_name) {
|
export async function openCharacterChat(file_name) {
|
||||||
await clearChat();
|
await clearChat();
|
||||||
characters[this_chid]['chat'] = file_name;
|
|
||||||
chat.length = 0;
|
chat.length = 0;
|
||||||
chat_metadata = {};
|
chat_metadata = {};
|
||||||
|
if (characters[this_chid]) {
|
||||||
|
characters[this_chid]['chat'] = file_name;
|
||||||
|
} else {
|
||||||
|
chat_metadata['chat_name'] = file_name;
|
||||||
|
}
|
||||||
await getChat();
|
await getChat();
|
||||||
$('#selected_chat_pole').val(file_name);
|
$('#selected_chat_pole').val(file_name);
|
||||||
await createOrEditCharacter(new CustomEvent('newChat'));
|
await createOrEditCharacter(new CustomEvent('newChat'));
|
||||||
@ -6756,9 +6774,9 @@ export async function getChatsFromFiles(data, isGroupChat) {
|
|||||||
const requestBody = isGroupChat
|
const requestBody = isGroupChat
|
||||||
? JSON.stringify({ id: file_name })
|
? JSON.stringify({ id: file_name })
|
||||||
: JSON.stringify({
|
: JSON.stringify({
|
||||||
ch_name: characters[context.characterId].name,
|
ch_name: characters[context.characterId]?.name ?? neutralCharacterName,
|
||||||
file_name: file_name.replace('.jsonl', ''),
|
file_name: file_name.replace('.jsonl', ''),
|
||||||
avatar_url: characters[context.characterId].avatar,
|
avatar_url: characters[context.characterId]?.avatar ?? neutralCharacterAvatar,
|
||||||
});
|
});
|
||||||
|
|
||||||
const chatResponse = await fetch(endpoint, {
|
const chatResponse = await fetch(endpoint, {
|
||||||
@ -6806,11 +6824,17 @@ export async function getChatsFromFiles(data, isGroupChat) {
|
|||||||
*/
|
*/
|
||||||
export async function getPastCharacterChats(characterId = null) {
|
export async function getPastCharacterChats(characterId = null) {
|
||||||
characterId = characterId ?? this_chid;
|
characterId = characterId ?? this_chid;
|
||||||
if (!characters[characterId]) return [];
|
let avatar = characters[characterId]?.avatar;
|
||||||
|
|
||||||
|
if (!avatar && this_chid === undefined && name2 === neutralCharacterName) {
|
||||||
|
avatar = neutralCharacterAvatar;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!avatar) return [];
|
||||||
|
|
||||||
const response = await fetch('/api/characters/chats', {
|
const response = await fetch('/api/characters/chats', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: JSON.stringify({ avatar_url: characters[characterId].avatar }),
|
body: JSON.stringify({ avatar_url: avatar }),
|
||||||
headers: getRequestHeaders(),
|
headers: getRequestHeaders(),
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -6831,6 +6855,15 @@ export async function getPastCharacterChats(characterId = null) {
|
|||||||
* Helper for `displayPastChats`, to make the same info consistently available for other functions
|
* Helper for `displayPastChats`, to make the same info consistently available for other functions
|
||||||
*/
|
*/
|
||||||
function getCurrentChatDetails() {
|
function getCurrentChatDetails() {
|
||||||
|
if (this_chid === undefined && name2 === neutralCharacterName) {
|
||||||
|
return {
|
||||||
|
sessionName: chat_metadata['chat_name'],
|
||||||
|
group: null,
|
||||||
|
characterName: neutralCharacterName,
|
||||||
|
avatarImgURL: neutralCharacterAvatar,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
if (!characters[this_chid] && !selected_group) {
|
if (!characters[this_chid] && !selected_group) {
|
||||||
return { sessionName: '', group: null, characterName: '', avatarImgURL: '' };
|
return { sessionName: '', group: null, characterName: '', avatarImgURL: '' };
|
||||||
}
|
}
|
||||||
@ -7089,6 +7122,10 @@ export function select_rm_info(type, charId, previousCharId = null) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function select_selected_character(chid) {
|
export function select_selected_character(chid) {
|
||||||
|
if (chid === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//character select
|
//character select
|
||||||
//console.log('select_selected_character() -- starting with input of -- ' + chid + ' (name:' + characters[chid].name + ')');
|
//console.log('select_selected_character() -- starting with input of -- ' + chid + ' (name:' + characters[chid].name + ')');
|
||||||
select_rm_create();
|
select_rm_create();
|
||||||
@ -7929,6 +7966,10 @@ async function createOrEditCharacter(e) {
|
|||||||
toastr.error('Name is required');
|
toastr.error('Name is required');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (this_chid === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let url = '/api/characters/edit';
|
let url = '/api/characters/edit';
|
||||||
|
|
||||||
if (crop_data != undefined) {
|
if (crop_data != undefined) {
|
||||||
@ -8762,7 +8803,23 @@ export async function doNewChat({ deleteCurrentChat = false } = {}) {
|
|||||||
await createOrEditCharacter(new CustomEvent('newChat'));
|
await createOrEditCharacter(new CustomEvent('newChat'));
|
||||||
if (deleteCurrentChat) await delChat(chat_file_for_del + '.jsonl');
|
if (deleteCurrentChat) await delChat(chat_file_for_del + '.jsonl');
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function openAssistantChat() {
|
||||||
|
resetSelectedGroup();
|
||||||
|
setCharacterId(undefined);
|
||||||
|
setCharacterName(neutralCharacterName);
|
||||||
|
setActiveCharacter(null);
|
||||||
|
setActiveGroup(null);
|
||||||
|
await clearChat();
|
||||||
|
chat.splice(0, chat.length);
|
||||||
|
this_edit_mes_id = undefined;
|
||||||
|
chat_metadata = { chat_name: humanizedDateTime() };
|
||||||
|
selected_button = 'characters';
|
||||||
|
$('#rm_button_selected_ch').children('h2').text('');
|
||||||
|
select_rm_characters();
|
||||||
|
sendSystemMessage(system_message_types.PAST_CHAT_HINT);
|
||||||
|
await eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId());
|
||||||
}
|
}
|
||||||
|
|
||||||
async function doDeleteChat() {
|
async function doDeleteChat() {
|
||||||
@ -8800,7 +8857,7 @@ async function doRenameChat(_, chatName) {
|
|||||||
export async function renameChat(oldFileName, newName) {
|
export async function renameChat(oldFileName, newName) {
|
||||||
const body = {
|
const body = {
|
||||||
is_group: !!selected_group,
|
is_group: !!selected_group,
|
||||||
avatar_url: characters[this_chid]?.avatar,
|
avatar_url: characters[this_chid]?.avatar ?? neutralCharacterAvatar,
|
||||||
original_file: `${oldFileName}.jsonl`,
|
original_file: `${oldFileName}.jsonl`,
|
||||||
renamed_file: `${newName}.jsonl`,
|
renamed_file: `${newName}.jsonl`,
|
||||||
};
|
};
|
||||||
@ -8827,7 +8884,7 @@ export async function renameChat(oldFileName, newName) {
|
|||||||
await renameGroupChat(selected_group, oldFileName, newName);
|
await renameGroupChat(selected_group, oldFileName, newName);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (characters[this_chid].chat == oldFileName) {
|
if (characters[this_chid]?.chat == oldFileName) {
|
||||||
characters[this_chid].chat = newName;
|
characters[this_chid].chat = newName;
|
||||||
$('#selected_chat_pole').val(characters[this_chid].chat);
|
$('#selected_chat_pole').val(characters[this_chid].chat);
|
||||||
await createOrEditCharacter();
|
await createOrEditCharacter();
|
||||||
@ -8835,7 +8892,8 @@ export async function renameChat(oldFileName, newName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
await reloadCurrentChat();
|
await reloadCurrentChat();
|
||||||
} catch {
|
} catch (error) {
|
||||||
|
console.log('Error renaming chat:', error);
|
||||||
hideLoader();
|
hideLoader();
|
||||||
await delay(500);
|
await delay(500);
|
||||||
await callPopup('An error has occurred. Chat was not renamed.', 'text');
|
await callPopup('An error has occurred. Chat was not renamed.', 'text');
|
||||||
@ -9612,7 +9670,7 @@ jQuery(async function () {
|
|||||||
const filename = filenamefull.replace('.jsonl', '');
|
const filename = filenamefull.replace('.jsonl', '');
|
||||||
const body = {
|
const body = {
|
||||||
is_group: !!selected_group,
|
is_group: !!selected_group,
|
||||||
avatar_url: characters[this_chid]?.avatar,
|
avatar_url: characters[this_chid]?.avatar ?? neutralCharacterAvatar,
|
||||||
file: `${filename}.jsonl`,
|
file: `${filename}.jsonl`,
|
||||||
exportfilename: `${filename}.${format}`,
|
exportfilename: `${filename}.${format}`,
|
||||||
format: format,
|
format: format,
|
||||||
@ -9775,7 +9833,12 @@ jQuery(async function () {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (id == 'option_select_chat') {
|
if (id == 'option_select_chat') {
|
||||||
if ((selected_group && !is_group_generating) || (this_chid !== undefined && !is_send_press) || fromSlashCommand) {
|
if ((selected_group && !is_group_generating) || (!is_send_press) || fromSlashCommand) {
|
||||||
|
// Must be in assistant mode to view chats.
|
||||||
|
if (this_chid === undefined && name2 !== neutralCharacterName) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await displayPastChats();
|
await displayPastChats();
|
||||||
//this is just to avoid the shadow for past chat view when using /delchat
|
//this is just to avoid the shadow for past chat view when using /delchat
|
||||||
//however, the dialog popup still gets one..
|
//however, the dialog popup still gets one..
|
||||||
@ -9793,7 +9856,7 @@ jQuery(async function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
else if (id == 'option_start_new_chat') {
|
else if (id == 'option_start_new_chat') {
|
||||||
if ((selected_group || this_chid !== undefined) && !is_send_press) {
|
if ((selected_group || this_chid !== undefined || name2 === neutralCharacterName) && !is_send_press) {
|
||||||
let deleteCurrentChat = false;
|
let deleteCurrentChat = false;
|
||||||
const result = await Popup.show.confirm(t`Start new chat?`, await renderTemplateAsync('newChatConfirm'), {
|
const result = await Popup.show.confirm(t`Start new chat?`, await renderTemplateAsync('newChatConfirm'), {
|
||||||
onClose: () => deleteCurrentChat = !!$('#del_chat_checkbox').prop('checked'),
|
onClose: () => deleteCurrentChat = !!$('#del_chat_checkbox').prop('checked'),
|
||||||
@ -9855,7 +9918,7 @@ jQuery(async function () {
|
|||||||
select_rm_characters();
|
select_rm_characters();
|
||||||
sendSystemMessage(system_message_types.WELCOME);
|
sendSystemMessage(system_message_types.WELCOME);
|
||||||
sendSystemMessage(system_message_types.WELCOME_PROMPT);
|
sendSystemMessage(system_message_types.WELCOME_PROMPT);
|
||||||
eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId());
|
await eventSource.emit(event_types.CHAT_CHANGED, getCurrentChatId());
|
||||||
await getClientVersion();
|
await getClientVersion();
|
||||||
} else {
|
} else {
|
||||||
toastr.info('Please stop the message generation first.');
|
toastr.info('Please stop the message generation first.');
|
||||||
@ -9886,6 +9949,11 @@ jQuery(async function () {
|
|||||||
}
|
}
|
||||||
//}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (id === 'option_ai_assistant') {
|
||||||
|
await openAssistantChat();
|
||||||
|
}
|
||||||
|
|
||||||
hideMenu();
|
hideMenu();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
8
public/scripts/templates/pastChatHint.html
Normal file
8
public/scripts/templates/pastChatHint.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<div>
|
||||||
|
<b>Hint:</b>
|
||||||
|
<span>to view past conversations, choose</span>
|
||||||
|
<code><i class="fa-solid fa-address-book"></i> <span data-i18n="Manage chat files">Manage chat files</span></code>
|
||||||
|
<span>from the</span>
|
||||||
|
<code><i class="fa-solid fa-bars"></i> <span data-i18n="Options">Options</span></code>
|
||||||
|
<span>menu.</span>
|
||||||
|
</div>
|
@ -1,6 +1,3 @@
|
|||||||
<strong data-i18n="Connect to an API and ask me anything!">
|
<strong data-i18n="Connect to an API and ask me anything!">
|
||||||
Connect to an API and ask me anything!
|
Connect to an API and ask me anything!
|
||||||
</strong>
|
</strong>
|
||||||
<div>
|
|
||||||
The conversation history here is ephemeral and will be lost when you refresh the page or change characters.
|
|
||||||
</div>
|
|
||||||
|
@ -145,7 +145,9 @@ router.post('/save', jsonParser, function (request, response) {
|
|||||||
const chatData = request.body.chat;
|
const chatData = request.body.chat;
|
||||||
const jsonlData = chatData.map(JSON.stringify).join('\n');
|
const jsonlData = chatData.map(JSON.stringify).join('\n');
|
||||||
const fileName = `${sanitize(String(request.body.file_name))}.jsonl`;
|
const fileName = `${sanitize(String(request.body.file_name))}.jsonl`;
|
||||||
const filePath = path.join(request.user.directories.chats, directoryName, fileName);
|
const directoryPath = path.join(request.user.directories.chats, directoryName);
|
||||||
|
if(!fs.existsSync(directoryPath)) fs.mkdirSync(directoryPath, { recursive: true });
|
||||||
|
const filePath = path.join(directoryPath, fileName);
|
||||||
writeFileAtomicSync(filePath, jsonlData, 'utf8');
|
writeFileAtomicSync(filePath, jsonlData, 'utf8');
|
||||||
backupChat(request.user.directories.backups, directoryName, jsonlData);
|
backupChat(request.user.directories.backups, directoryName, jsonlData);
|
||||||
return response.send({ result: 'ok' });
|
return response.send({ result: 'ok' });
|
||||||
|
Reference in New Issue
Block a user