Merge branch 'staging' into small-bookmark-updates

This commit is contained in:
Cohee
2024-09-12 23:10:33 +03:00
13 changed files with 833 additions and 216 deletions

View File

@ -7472,7 +7472,7 @@ export function showSwipeButtons() {
const currentMessage = $('#chat').children().filter(`[mesid="${chat.length - 1}"]`);
const swipeId = chat[chat.length - 1].swipe_id;
var swipesCounterHTML = (`${(swipeId + 1)}/${(chat[chat.length - 1].swipes.length)}`);
const swipeCounterText = (`${(swipeId + 1)}\u200B/\u200b${(chat[chat.length - 1].swipes.length)}`);
if (swipeId !== undefined && (chat[chat.length - 1].swipes.length > 1 || swipeId > 0)) {
currentMessage.children('.swipe_left').css('display', 'flex');
@ -7489,7 +7489,7 @@ export function showSwipeButtons() {
}
//console.log(swipesCounterHTML);
$('.swipes-counter').html(swipesCounterHTML);
$('.swipes-counter').text(swipeCounterText);
//console.log(swipeId);
//console.log(chat[chat.length - 1].swipes.length);
@ -7878,13 +7878,19 @@ async function createOrEditCharacter(e) {
formData.set('avatar', convertedFile);
}
if ($('#form_create').attr('actiontype') == 'createcharacter') {
if (String($('#character_name_pole').val()).length > 0) {
if (is_group_generating || is_send_press) {
toastr.error('Cannot create characters while generating. Stop the request and try again.', 'Creation aborted');
throw new Error('Cannot import character while generating');
}
const headers = getRequestHeaders();
delete headers['Content-Type'];
if ($('#form_create').attr('actiontype') == 'createcharacter') {
if (String($('#character_name_pole').val()).length === 0) {
toastr.error('Name is required');
return;
}
if (is_group_generating || is_send_press) {
toastr.error('Cannot create characters while generating. Stop the request and try again.', 'Creation aborted');
return;
}
try {
//if the character name text area isn't empty (only posible when creating a new character)
let url = '/api/characters/create';
@ -7899,142 +7905,133 @@ async function createOrEditCharacter(e) {
formData.append('extensions', JSON.stringify(create_save.extensions));
await jQuery.ajax({
type: 'POST',
url: url,
data: formData,
beforeSend: function () {
$('#create_button').attr('disabled', String(true));
$('#create_button').attr('value', '⏳');
},
cache: false,
contentType: false,
processData: false,
success: async function (html) {
$('#character_cross').trigger('click'); //closes the advanced character editing popup
const fields = [
{ id: '#character_name_pole', callback: value => create_save.name = value },
{ id: '#description_textarea', callback: value => create_save.description = value },
{ id: '#creator_notes_textarea', callback: value => create_save.creator_notes = value },
{ id: '#character_version_textarea', callback: value => create_save.character_version = value },
{ id: '#post_history_instructions_textarea', callback: value => create_save.post_history_instructions = value },
{ id: '#system_prompt_textarea', callback: value => create_save.system_prompt = value },
{ id: '#tags_textarea', callback: value => create_save.tags = value },
{ id: '#creator_textarea', callback: value => create_save.creator = value },
{ id: '#personality_textarea', callback: value => create_save.personality = value },
{ id: '#firstmessage_textarea', callback: value => create_save.first_message = value },
{ id: '#talkativeness_slider', callback: value => create_save.talkativeness = value, defaultValue: talkativeness_default },
{ id: '#scenario_pole', callback: value => create_save.scenario = value },
{ id: '#depth_prompt_prompt', callback: value => create_save.depth_prompt_prompt = value },
{ id: '#depth_prompt_depth', callback: value => create_save.depth_prompt_depth = value, defaultValue: depth_prompt_depth_default },
{ id: '#depth_prompt_role', callback: value => create_save.depth_prompt_role = value, defaultValue: depth_prompt_role_default },
{ id: '#mes_example_textarea', callback: value => create_save.mes_example = value },
{ id: '#character_json_data', callback: () => { } },
{ id: '#alternate_greetings_template', callback: value => create_save.alternate_greetings = value, defaultValue: [] },
{ id: '#character_world', callback: value => create_save.world = value },
{ id: '#_character_extensions_fake', callback: value => create_save.extensions = {} },
];
fields.forEach(field => {
const fieldValue = field.defaultValue !== undefined ? field.defaultValue : '';
$(field.id).val(fieldValue);
field.callback && field.callback(fieldValue);
});
$('#character_popup-button-h3').text('Create character');
create_save.avatar = '';
$('#create_button').removeAttr('disabled');
$('#add_avatar_button').replaceWith(
$('#add_avatar_button').val('').clone(true),
);
$('#create_button').attr('value', '✅');
let oldSelectedChar = null;
if (this_chid !== undefined) {
oldSelectedChar = characters[this_chid].avatar;
}
console.log(`new avatar id: ${html}`);
createTagMapFromList('#tagList', html);
await getCharacters();
select_rm_info('char_create', html, oldSelectedChar);
crop_data = undefined;
},
error: function (jqXHR, exception) {
$('#create_button').removeAttr('disabled');
},
const fetchResult = await fetch(url, {
method: 'POST',
headers: headers,
body: formData,
cache: 'no-cache',
});
} else {
toastr.error('Name is required');
if (!fetchResult.ok) {
throw new Error('Fetch result is not ok');
}
const avatarId = await fetchResult.text();
$('#character_cross').trigger('click'); //closes the advanced character editing popup
const fields = [
{ id: '#character_name_pole', callback: value => create_save.name = value },
{ id: '#description_textarea', callback: value => create_save.description = value },
{ id: '#creator_notes_textarea', callback: value => create_save.creator_notes = value },
{ id: '#character_version_textarea', callback: value => create_save.character_version = value },
{ id: '#post_history_instructions_textarea', callback: value => create_save.post_history_instructions = value },
{ id: '#system_prompt_textarea', callback: value => create_save.system_prompt = value },
{ id: '#tags_textarea', callback: value => create_save.tags = value },
{ id: '#creator_textarea', callback: value => create_save.creator = value },
{ id: '#personality_textarea', callback: value => create_save.personality = value },
{ id: '#firstmessage_textarea', callback: value => create_save.first_message = value },
{ id: '#talkativeness_slider', callback: value => create_save.talkativeness = value, defaultValue: talkativeness_default },
{ id: '#scenario_pole', callback: value => create_save.scenario = value },
{ id: '#depth_prompt_prompt', callback: value => create_save.depth_prompt_prompt = value },
{ id: '#depth_prompt_depth', callback: value => create_save.depth_prompt_depth = value, defaultValue: depth_prompt_depth_default },
{ id: '#depth_prompt_role', callback: value => create_save.depth_prompt_role = value, defaultValue: depth_prompt_role_default },
{ id: '#mes_example_textarea', callback: value => create_save.mes_example = value },
{ id: '#character_json_data', callback: () => { } },
{ id: '#alternate_greetings_template', callback: value => create_save.alternate_greetings = value, defaultValue: [] },
{ id: '#character_world', callback: value => create_save.world = value },
{ id: '#_character_extensions_fake', callback: value => create_save.extensions = {} },
];
fields.forEach(field => {
const fieldValue = field.defaultValue !== undefined ? field.defaultValue : '';
$(field.id).val(fieldValue);
field.callback && field.callback(fieldValue);
});
$('#character_popup-button-h3').text('Create character');
create_save.avatar = '';
$('#add_avatar_button').replaceWith(
$('#add_avatar_button').val('').clone(true),
);
let oldSelectedChar = null;
if (this_chid !== undefined) {
oldSelectedChar = characters[this_chid].avatar;
}
console.log(`new avatar id: ${avatarId}`);
createTagMapFromList('#tagList', avatarId);
await getCharacters();
select_rm_info('char_create', avatarId, oldSelectedChar);
crop_data = undefined;
} catch (error) {
console.error('Error creating character', error);
toastr.error('Failed to create character');
}
} else {
let url = '/api/characters/edit';
try {
let url = '/api/characters/edit';
if (crop_data != undefined) {
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
}
formData.delete('alternate_greetings');
const chid = $('.open_alternate_greetings').data('chid');
if (chid && Array.isArray(characters[chid]?.data?.alternate_greetings)) {
for (const value of characters[chid].data.alternate_greetings) {
formData.append('alternate_greetings', value);
if (crop_data != undefined) {
url += `?crop=${encodeURIComponent(JSON.stringify(crop_data))}`;
}
}
await jQuery.ajax({
type: 'POST',
url: url,
data: formData,
beforeSend: function () {
$('#create_button').attr('disabled', String(true));
$('#create_button').attr('value', 'Save');
},
cache: false,
contentType: false,
processData: false,
success: async function (html) {
$('#create_button').removeAttr('disabled');
await getOneCharacter(formData.get('avatar_url'));
favsToHotswap(); // Update fav state
$('#add_avatar_button').replaceWith(
$('#add_avatar_button').val('').clone(true),
);
$('#create_button').attr('value', 'Save');
crop_data = undefined;
eventSource.emit(event_types.CHARACTER_EDITED, { detail: { id: this_chid, character: characters[this_chid] } });
// Recreate the chat if it hasn't been used at least once (i.e. with continue).
const message = getFirstMessage();
const shouldRegenerateMessage =
!isNewChat &&
message.mes &&
!selected_group &&
!chat_metadata['tainted'] &&
(chat.length === 0 || (chat.length === 1 && !chat[0].is_user && !chat[0].is_system));
if (shouldRegenerateMessage) {
chat.splice(0, chat.length, message);
const messageId = (chat.length - 1);
await eventSource.emit(event_types.MESSAGE_RECEIVED, messageId);
await clearChat();
await printMessages();
await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, messageId);
await saveChatConditional();
formData.delete('alternate_greetings');
const chid = $('.open_alternate_greetings').data('chid');
if (chid && Array.isArray(characters[chid]?.data?.alternate_greetings)) {
for (const value of characters[chid].data.alternate_greetings) {
formData.append('alternate_greetings', value);
}
},
error: function (jqXHR, exception) {
$('#create_button').removeAttr('disabled');
console.log('Error! Either a file with the same name already existed, or the image file provided was in an invalid format. Double check that the image is not a webp.');
toastr.error('Something went wrong while saving the character, or the image file provided was in an invalid format. Double check that the image is not a webp.');
},
});
}
const fetchResult = await fetch(url, {
method: 'POST',
headers: headers,
body: formData,
cache: 'no-cache',
});
if (!fetchResult.ok) {
throw new Error('Fetch result is not ok');
}
await getOneCharacter(formData.get('avatar_url'));
favsToHotswap(); // Update fav state
$('#add_avatar_button').replaceWith(
$('#add_avatar_button').val('').clone(true),
);
$('#create_button').attr('value', 'Save');
crop_data = undefined;
await eventSource.emit(event_types.CHARACTER_EDITED, { detail: { id: this_chid, character: characters[this_chid] } });
// Recreate the chat if it hasn't been used at least once (i.e. with continue).
const message = getFirstMessage();
const shouldRegenerateMessage =
!isNewChat &&
message.mes &&
!selected_group &&
!chat_metadata['tainted'] &&
(chat.length === 0 || (chat.length === 1 && !chat[0].is_user && !chat[0].is_system));
if (shouldRegenerateMessage) {
chat.splice(0, chat.length, message);
const messageId = (chat.length - 1);
await eventSource.emit(event_types.MESSAGE_RECEIVED, messageId);
await clearChat();
await printMessages();
await eventSource.emit(event_types.CHARACTER_MESSAGE_RENDERED, messageId);
await saveChatConditional();
}
} catch (error) {
console.log(error);
toastr.error('Something went wrong while saving the character, or the image file provided was in an invalid format. Double check that the image is not a webp.');
}
}
}
@ -8526,7 +8523,7 @@ async function selectContextCallback(args, name) {
async function selectInstructCallback(args, name) {
if (!name) {
return power_user.instruct.preset;
return power_user.instruct.enabled || isTrueBoolean(args?.forceGet) ? power_user.instruct.preset : '';
}
const quiet = isTrueBoolean(args?.quiet);
@ -9227,6 +9224,13 @@ jQuery(async function () {
defaultValue: 'false',
enumList: commonEnumProviders.boolean('trueFalse')(),
}),
SlashCommandNamedArgument.fromProps({
name: 'forceGet',
description: 'Force getting a name even if instruct mode is disabled',
typeList: [ARGUMENT_TYPE.BOOLEAN],
defaultValue: 'false',
enumList: commonEnumProviders.boolean('trueFalse')(),
}),
],
unnamedArgumentList: [
SlashCommandArgument.fromProps({
@ -9237,7 +9241,8 @@ jQuery(async function () {
],
helpString: `
<div>
Selects instruct mode template by name. Gets the current instruct template if no name is provided.
Selects instruct mode template by name. Enables instruct mode if not already enabled.
Gets the current instruct template if no name is provided and instruct mode is enabled or <code>forceGet=true</code> is passed.
</div>
<div>
<strong>Example:</strong>