Character settings overrides UI (#4707) * + Implemented support for overrides of system prompt and example messages from chat metadata. This is needed for BYAF import parity. No UI for modifying these yet, but they're easily changeable in the chat files already. These metadata settings are already supported by BYAF import as of the last commit so this just enables them. * + Updated scenario overrides popup to now be a character settings overrides popup. + Updated the template to have a new section for example messages and system prompts + Updated the logic to handle all three overrides + Updated logic to only save when the popup is closed, instead of on every character input. * Preserve import, allow scrolling * Add confirmation on override removal. Always save pending changes. * Update dialog layout, add editor expand buttons * Fix mes examples override in group chats with Join mode * Update group chat button title * Specify that Prefer Char. Prompt is a requirement * Fix group join mode not replacing macros in overrides --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>
Signed| @@ -5698,7 +5698,7 @@ | |||
| 5698 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore Alt+Click to open the lorebook" data-i18n="[title]Chat Lore Alt+Click to open the lorebook"></div> | 5698 | <div class="chat_lorebook_button menu_button fa-solid fa-passport" title="Chat Lore Alt+Click to open the lorebook" data-i18n="[title]Chat Lore Alt+Click to open the lorebook"></div> |
| 5699 | <div id="char_connections_button" class="menu_button fa-solid fa-face-smile" title="Connected Personas" data-i18n="[title]Connected Personas"></div> | 5699 | <div id="char_connections_button" class="menu_button fa-solid fa-face-smile" title="Connected Personas" data-i18n="[title]Connected Personas"></div> |
| 5700 | <div id="export_button" class="menu_button fa-solid fa-file-export " title="Export and Download" data-i18n="[title]Export and Download"></div> | 5700 | <div id="export_button" class="menu_button fa-solid fa-file-export " title="Export and Download" data-i18n="[title]Export and Download"></div> |
| 5701 | <!-- <div id="set_chat_scenario" class="menu_button fa-solid fa-scroll" title="Set a chat scenario override"></div> --> | 5701 | <!-- <div id="set_chat_character_settings" class="menu_button fa-solid fa-scroll" title="Set a chat scenario override"></div> --> |
| 5702 | <!-- <div id="set_character_world" class="menu_button fa-solid fa-globe" title="Set a character World Info / Lorebook"></div> --> | 5702 | <!-- <div id="set_character_world" class="menu_button fa-solid fa-globe" title="Set a character World Info / Lorebook"></div> --> |
| 5703 | <div id="dupe_button" class="menu_button fa-solid fa-clone " title="Duplicate Character" data-i18n="[title]Duplicate Character"></div> | 5703 | <div id="dupe_button" class="menu_button fa-solid fa-clone " title="Duplicate Character" data-i18n="[title]Duplicate Character"></div> |
| 5704 | <label for="create_button" id="create_button_label" class="menu_button fa-solid fa-user-check" title="Create Character" data-i18n="[title]Create Character"> | 5704 | <label for="create_button" id="create_button_label" class="menu_button fa-solid fa-user-check" title="Create Character" data-i18n="[title]Create Character"> |
| @@ -5715,8 +5715,8 @@ | |||
| 5715 | <option id="import_character_info" data-i18n="Import Card Lore"> | 5715 | <option id="import_character_info" data-i18n="Import Card Lore"> |
| 5716 | Import Card Lore | 5716 | Import Card Lore |
| 5717 | </option> | 5717 | </option> |
| 5718 | <option id="set_chat_scenario" data-i18n="Scenario Override"> | 5718 | <option id="set_chat_character_settings" data-i18n="Character Settings Overrides"> |
| 5719 | Scenario Override | 5719 | Character Settings Overrides |
| 5720 | </option> | 5720 | </option> |
| 5721 | <option id="convert_to_persona" data-i18n="Convert to Persona"> | 5721 | <option id="convert_to_persona" data-i18n="Convert to Persona"> |
| 5722 | Convert to Persona | 5722 | Convert to Persona |
| @@ -5907,7 +5907,7 @@ | |||
| 5907 | </div> | 5907 | </div> |
| 5908 | <div id="GroupFavDelOkBack" class="flex-container flexGap5 spaceEvenly flex1"> | 5908 | <div id="GroupFavDelOkBack" class="flex-container flexGap5 spaceEvenly flex1"> |
| 5909 | <div id="rm_button_back_from_group" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-left-long"></div> | 5909 | <div id="rm_button_back_from_group" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-left-long"></div> |
| 5910 | <div id="rm_group_scenario" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-scroll" title="Set a group chat scenario" data-i18n="[title]Set a group chat scenario"></div> | 5910 | <div id="rm_group_scenario" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-scroll" title="Set group chat character settings overrides" data-i18n="[title]Set group chat character settings overrides"></div> |
| 5911 | <div id="group_favorite_button" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div> | 5911 | <div id="group_favorite_button" class="heightFitContent margin0 menu_button fa-solid fa-fw fa-star" title="Add to Favorites" data-i18n="[title]Add to Favorites"></div> |
| 5912 | <input id="rm_group_fav" type="hidden" /> | 5912 | <input id="rm_group_fav" type="hidden" /> |
| 5913 | <div id="group_open_media_overrides" class="heightFitContent margin0 menu_button menu_button_icon open_media_overrides" title="Click to allow/forbid the use of external media for this group." data-i18n="[title]Click to allow/forbid the use of external media for this group."> | 5913 | <div id="group_open_media_overrides" class="heightFitContent margin0 menu_button menu_button_icon open_media_overrides" title="Click to allow/forbid the use of external media for this group." data-i18n="[title]Click to allow/forbid the use of external media for this group."> |
| @@ -313,6 +313,7 @@ export { | |||
| 313 | getSystemMessageByType, | 313 | getSystemMessageByType, |
| 314 | event_types, | 314 | event_types, |
| 315 | eventSource, | 315 | eventSource, |
| 316 | setCharacterSettingsOverrides as setScenarioOverride, | ||
| 316 | }; | 317 | }; |
| 317 | 318 | ||
| 318 | /** | 319 | /** |
| @@ -2757,11 +2758,14 @@ export function getCharacterCardFields({ chid = null } = {}) { | |||
| 2757 | } | 2758 | } |
| 2758 | 2759 | ||
| 2759 | const scenarioText = chat_metadata['scenario'] || character.scenario || ''; | 2760 | const scenarioText = chat_metadata['scenario'] || character.scenario || ''; |
| 2761 | const exampleDialog = chat_metadata['mes_example'] || character.mes_example || ''; | ||
| 2762 | const systemPrompt = chat_metadata['system_prompt'] || character.data?.system_prompt || ''; | ||
| 2763 | |||
| 2760 | result.description = baseChatReplace(character.description?.trim(), name1, name2); | 2764 | result.description = baseChatReplace(character.description?.trim(), name1, name2); |
| 2761 | result.personality = baseChatReplace(character.personality?.trim(), name1, name2); | 2765 | result.personality = baseChatReplace(character.personality?.trim(), name1, name2); |
| 2762 | result.scenario = baseChatReplace(scenarioText.trim(), name1, name2); | 2766 | result.scenario = baseChatReplace(scenarioText.trim(), name1, name2); |
| 2763 | result.mesExamples = baseChatReplace(character.mes_example?.trim(), name1, name2); | 2767 | result.mesExamples = baseChatReplace(exampleDialog.trim(), name1, name2); |
| 2764 | result.system = power_user.prefer_character_prompt ? baseChatReplace(character.data?.system_prompt?.trim(), name1, name2) : ''; | 2768 | result.system = power_user.prefer_character_prompt ? baseChatReplace(systemPrompt.trim(), name1, name2) : ''; |
| 2765 | result.jailbreak = power_user.prefer_character_jailbreak ? baseChatReplace(character.data?.post_history_instructions?.trim(), name1, name2) : ''; | 2769 | result.jailbreak = power_user.prefer_character_jailbreak ? baseChatReplace(character.data?.post_history_instructions?.trim(), name1, name2) : ''; |
| 2766 | result.version = character.data?.character_version ?? ''; | 2770 | result.version = character.data?.character_version ?? ''; |
| 2767 | result.charDepthPrompt = baseChatReplace(character.data?.extensions?.depth_prompt?.prompt?.trim(), name1, name2); | 2771 | result.charDepthPrompt = baseChatReplace(character.data?.extensions?.depth_prompt?.prompt?.trim(), name1, name2); |
| @@ -7819,7 +7823,7 @@ export function select_selected_character(chid, { switchMenu = true } = {}) { | |||
| 7819 | $('#char_connections_button').show(); | 7823 | $('#char_connections_button').show(); |
| 7820 | 7824 | ||
| 7821 | // Hide the chat scenario button if we're peeking the group member defs | 7825 | // Hide the chat scenario button if we're peeking the group member defs |
| 7822 | $('#set_chat_scenario').toggle(!selected_group); | 7826 | $('#set_chat_character_settings').toggle(!selected_group); |
| 7823 | 7827 | ||
| 7824 | // Don't update the navbar name if we're peeking the group member defs | 7828 | // Don't update the navbar name if we're peeking the group member defs |
| 7825 | if (!selected_group) { | 7829 | if (!selected_group) { |
| @@ -7901,7 +7905,7 @@ function select_rm_create({ switchMenu = true } = {}) { | |||
| 7901 | 7905 | ||
| 7902 | switchMenu && selectRightMenuWithAnimation('rm_ch_create_block'); | 7906 | switchMenu && selectRightMenuWithAnimation('rm_ch_create_block'); |
| 7903 | 7907 | ||
| 7904 | $('#set_chat_scenario').hide(); | 7908 | $('#set_chat_character_settings').hide(); |
| 7905 | $('#delete_button_div').css('display', 'none'); | 7909 | $('#delete_button_div').css('display', 'none'); |
| 7906 | $('#delete_button').css('display', 'none'); | 7910 | $('#delete_button').css('display', 'none'); |
| 7907 | $('#export_button').css('display', 'none'); | 7911 | $('#export_button').css('display', 'none'); |
| @@ -8036,33 +8040,65 @@ function updateFavButtonState(state) { | |||
| 8036 | $('#favorite_button').toggleClass('fav_off', !state); | 8040 | $('#favorite_button').toggleClass('fav_off', !state); |
| 8037 | } | 8041 | } |
| 8038 | 8042 | ||
| 8039 | export async function setScenarioOverride() { | 8043 | export async function setCharacterSettingsOverrides() { |
| 8040 | if (!selected_group && (this_chid === undefined || !characters[this_chid])) { | 8044 | if (!selected_group && (this_chid === undefined || !characters[this_chid])) { |
| 8041 | console.warn('setScenarioOverride() -- no selected group or character'); | 8045 | console.warn('setCharacterSettingsOverrides() -- no selected group or character'); |
| 8042 | return; | 8046 | return; |
| 8043 | } | 8047 | } |
| 8044 | 8048 | ||
| 8045 | const metadataValue = chat_metadata['scenario'] || ''; | 8049 | const scenarioOverrideValue = chat_metadata['scenario'] || ''; |
| 8050 | const exampleMessagesValue = chat_metadata['mes_example'] || ''; | ||
| 8051 | const systemPromptValue = chat_metadata['system_prompt'] || ''; | ||
| 8046 | const isGroup = !!selected_group; | 8052 | const isGroup = !!selected_group; |
| 8047 | 8053 | ||
| 8048 | const $template = $(await renderTemplateAsync('scenarioOverride')); | 8054 | const $template = $(await renderTemplateAsync('scenarioOverride')); |
| 8049 | $template.find('[data-group="true"]').toggle(isGroup); | 8055 | $template.find('[data-group="true"]').toggle(isGroup); |
| 8050 | $template.find('[data-character="true"]').toggle(!isGroup); | 8056 | $template.find('[data-character="true"]').toggle(!isGroup); |
| 8051 | // TODO: Why does this save on every character input? Save on popup close | 8057 | const pendingChanges = { |
| 8052 | $template.find('.chat_scenario').val(metadataValue).on('input', onScenarioOverrideInput); | 8058 | scenario: scenarioOverrideValue, |
| 8053 | $template.find('.remove_scenario_override').on('click', onScenarioOverrideRemoveClick); | 8059 | examples: exampleMessagesValue, |
| 8060 | system_prompt: systemPromptValue, | ||
| 8061 | }; | ||
| 8054 | 8062 | ||
| 8055 | await callGenericPopup($template, POPUP_TYPE.TEXT, ''); | 8063 | // Keep edits local until the popup is closed/confirmed |
| 8056 | } | 8064 | const $scenario = $template.find('.chat_scenario'); |
| 8065 | $scenario.val(scenarioOverrideValue).on('input', function () { | ||
| 8066 | pendingChanges.scenario = String($(this).val()); | ||
| 8067 | }); | ||
| 8068 | const $examples = $template.find('.chat_examples'); | ||
| 8069 | $examples.val(exampleMessagesValue).on('input', function () { | ||
| 8070 | pendingChanges.examples = String($(this).val()); | ||
| 8071 | }); | ||
| 8072 | const $systemPrompt = $template.find('.chat_system_prompt'); | ||
| 8073 | $systemPrompt.val(systemPromptValue).on('input', function () { | ||
| 8074 | pendingChanges.system_prompt = String($(this).val()); | ||
| 8075 | }); | ||
| 8057 | 8076 | ||
| 8058 | function onScenarioOverrideInput() { | 8077 | $template.find('.remove_scenario_override').on('click', async function () { |
| 8059 | const value = String($(this).val()); | 8078 | const confirm = await Popup.show.confirm(t`Are you sure you want to remove all overrides?`, t`This action cannot be undone.`); |
| 8060 | chat_metadata['scenario'] = value; | 8079 | if (!confirm) { |
| 8061 | saveMetadataDebounced(); | 8080 | return; |
| 8062 | } | 8081 | } |
| 8082 | |||
| 8083 | $scenario.val(''); | ||
| 8084 | pendingChanges.scenario = ''; | ||
| 8085 | $examples.val(''); | ||
| 8086 | pendingChanges.examples = ''; | ||
| 8087 | $systemPrompt.val(''); | ||
| 8088 | pendingChanges.system_prompt = ''; | ||
| 8089 | }); | ||
| 8063 | 8090 | ||
| 8064 | function onScenarioOverrideRemoveClick() { | 8091 | // Wait for popup close/confirm. |
| 8065 | $(this).closest('.scenario_override').find('.chat_scenario').val('').trigger('input'); | 8092 | await callGenericPopup($template, POPUP_TYPE.TEXT, '', { |
| 8093 | wide: true, | ||
| 8094 | large: true, | ||
| 8095 | allowVerticalScrolling: true, | ||
| 8096 | }); | ||
| 8097 | |||
| 8098 | chat_metadata['scenario'] = pendingChanges.scenario; | ||
| 8099 | chat_metadata['mes_example'] = pendingChanges.examples; | ||
| 8100 | chat_metadata['system_prompt'] = pendingChanges.system_prompt; | ||
| 8101 | saveMetadataDebounced(); | ||
| 8066 | } | 8102 | } |
| 8067 | 8103 | ||
| 8068 | /** | 8104 | /** |
| @@ -10304,7 +10340,7 @@ jQuery(async function () { | |||
| 10304 | if (!isMouseOverButtonOrMenu()) { hideMenu(); } | 10340 | if (!isMouseOverButtonOrMenu()) { hideMenu(); } |
| 10305 | }); | 10341 | }); |
| 10306 | 10342 | ||
| 10307 | /* $('#set_chat_scenario').on('click', setScenarioOverride); */ | 10343 | /* $('#set_chat_character_settings').on('click', setScenarioOverride); */ |
| 10308 | 10344 | ||
| 10309 | ///////////// OPTIMIZED LISTENERS FOR LEFT SIDE OPTIONS POPUP MENU ////////////////////// | 10345 | ///////////// OPTIMIZED LISTENERS FOR LEFT SIDE OPTIONS POPUP MENU ////////////////////// |
| 10310 | $('#options [id]').on('click', async function (event, customData) { | 10346 | $('#options [id]').on('click', async function (event, customData) { |
| @@ -11085,8 +11121,8 @@ jQuery(async function () { | |||
| 11085 | case 'set_character_world': | 11121 | case 'set_character_world': |
| 11086 | await openCharacterWorldPopup(); | 11122 | await openCharacterWorldPopup(); |
| 11087 | break; | 11123 | break; |
| 11088 | case 'set_chat_scenario': | 11124 | case 'set_chat_character_settings': |
| 11089 | await setScenarioOverride(); | 11125 | await setCharacterSettingsOverrides(); |
| 11090 | break; | 11126 | break; |
| 11091 | case 'renameCharButton': | 11127 | case 'renameCharButton': |
| 11092 | await renameCharacter(); | 11128 | await renameCharacter(); |
| @@ -38,6 +38,7 @@ import { | |||
| 38 | setEditedMessageId, | 38 | setEditedMessageId, |
| 39 | is_send_press, | 39 | is_send_press, |
| 40 | name1, | 40 | name1, |
| 41 | name2, | ||
| 41 | resetChatState, | 42 | resetChatState, |
| 42 | setSendButtonState, | 43 | setSendButtonState, |
| 43 | getCharacters, | 44 | getCharacters, |
| @@ -65,7 +66,7 @@ import { | |||
| 65 | eventSource, | 66 | eventSource, |
| 66 | event_types, | 67 | event_types, |
| 67 | getCurrentChatId, | 68 | getCurrentChatId, |
| 68 | setScenarioOverride, | 69 | setCharacterSettingsOverrides, |
| 69 | system_avatar, | 70 | system_avatar, |
| 70 | isChatSaving, | 71 | isChatSaving, |
| 71 | setExternalAbortController, | 72 | setExternalAbortController, |
| @@ -490,7 +491,8 @@ export function getGroupCharacterCards(groupId, characterId) { | |||
| 490 | return `${prefix}${value}${suffix}`; | 491 | return `${prefix}${value}${suffix}`; |
| 491 | } | 492 | } |
| 492 | 493 | ||
| 493 | const scenarioOverride = chat_metadata['scenario']; | 494 | const scenarioOverride = String(chat_metadata['scenario'] || ''); |
| 495 | const mesExamplesOverride = String(chat_metadata['mes_example'] || ''); | ||
| 494 | 496 | ||
| 495 | let descriptions = []; | 497 | let descriptions = []; |
| 496 | let personalities = []; | 498 | let personalities = []; |
| @@ -518,8 +520,8 @@ export function getGroupCharacterCards(groupId, characterId) { | |||
| 518 | 520 | ||
| 519 | const description = descriptions.filter(x => x.length).join('\n'); | 521 | const description = descriptions.filter(x => x.length).join('\n'); |
| 520 | const personality = personalities.filter(x => x.length).join('\n'); | 522 | const personality = personalities.filter(x => x.length).join('\n'); |
| 521 | const scenario = scenarioOverride?.trim() || scenarios.filter(x => x.length).join('\n'); | 523 | const scenario = baseChatReplace(scenarioOverride?.trim(), name1, name2) || scenarios.filter(x => x.length).join('\n'); |
| 522 | const mesExamples = mesExamplesArray.filter(x => x.length).join('\n'); | 524 | const mesExamples = baseChatReplace(mesExamplesOverride?.trim(), name1, name2) || mesExamplesArray.filter(x => x.length).join('\n'); |
| 523 | 525 | ||
| 524 | return { description, personality, scenario, mesExamples }; | 526 | return { description, personality, scenario, mesExamples }; |
| 525 | } | 527 | } |
| @@ -2193,7 +2195,7 @@ jQuery(() => { | |||
| 2193 | }); | 2195 | }); |
| 2194 | $('#rm_group_filter').on('input', filterGroupMembers); | 2196 | $('#rm_group_filter').on('input', filterGroupMembers); |
| 2195 | $('#rm_group_submit').on('click', createGroup); | 2197 | $('#rm_group_submit').on('click', createGroup); |
| 2196 | $('#rm_group_scenario').on('click', setScenarioOverride); | 2198 | $('#rm_group_scenario').on('click', setCharacterSettingsOverrides); |
| 2197 | $('#rm_group_automode').on('input', function () { | 2199 | $('#rm_group_automode').on('input', function () { |
| 2198 | const value = $(this).prop('checked'); | 2200 | const value = $(this).prop('checked'); |
| 2199 | is_group_automode_enabled = value; | 2201 | is_group_automode_enabled = value; |
| @@ -1,17 +1,45 @@ | |||
| 1 | <div class="scenario_override range-block flexFlowColumn flex-container"> | 1 | <div class="scenario_override flexFlowColumn flex-container justifyLeft"> |
| 2 | <div class="range-block-title title_restorable"> | 2 | <div class="title_restorable alignItemsBaseline"> |
| 3 | <h3><span data-i18n="Chat Scenario Override" class="margin0">Chat Scenario Override</span></h3> | 3 | <h3><span data-i18n="Chat Character Settings Override" class="margin0">Chat Character Settings Override</span></h3> |
| 4 | <div title="Remove" data-i18n="[title]Remove" | 4 | <div class="menu_button menu_button_icon remove_scenario_override"> |
| 5 | class="menu_button fa-solid fa-trash-can remove_scenario_override"></div> | 5 | <i class="fa-solid fa-trash-can "></i> |
| 6 | <span data-i18n="Remove">Remove</span> | ||
| 7 | </div> | ||
| 6 | </div> | 8 | </div> |
| 7 | <div class="range-block-counter justifyLeft flex-container flexFlowColumn"> | 9 | <div> |
| 8 | <strong data-i18n="Unique to this chat.">Unique to this chat.</strong> | 10 | <strong data-i18n="Unique to this chat.">Unique to this chat.</strong> |
| 9 | <span data-group="true" data-i18n="All group members will use the following scenario text instead of what is specified in their character cards.">All group members will use the following scenario text instead of what is specified in their character cards.</span> | 11 | <span data-group="true" data-i18n="All group members will use the following values instead of what is specified in their character cards.">All group members will use the following values instead of what is specified in their character cards.</span> |
| 10 | <span data-character="true" data-i18n="The following scenario text will be used instead of the value set in the character card.">The following scenario text will be used instead of the value set in the character card.</span> | 12 | <span data-character="true" data-i18n="The following values will be used instead of the value set in the character card.">The following values will be used instead of the value set in the character card.</span> |
| 11 | <span data-i18n="Checkpoints inherit the scenario override from their parent, and can be changed individually after that.">Checkpoints inherit the scenario override from their parent, and can be changed individually after that.</span> | 13 | <span data-i18n="Checkpoints inherit the overrides from their parent, and can be changed individually after that.">Checkpoints inherit the overrides from their parent, and can be changed individually after that.</span> |
| 12 | </div> | 14 | </div> |
| 13 | <div class="range-block-range wide100p"> | 15 | <hr> |
| 14 | <textarea class="wide100p chat_scenario" class="text_pole" rows="15" data-i18n="[placeholder]Type here..." | 16 | <div class="wide100p flex-container flexFlowColumn"> |
| 15 | placeholder="Type here..."></textarea> | 17 | <h4 class="flex-container alignItemsBaseline"> |
| 18 | <span data-i18n="Scenario">Scenario</span> | ||
| 19 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" data-for="chat_scenario_override" title="Expand the editor" data-i18n="[title]Expand the editor"></i> | ||
| 20 | </h4> | ||
| 21 | <div> | ||
| 22 | <textarea id="chat_scenario_override" class="chat_scenario text_pole" rows="6" data-i18n="[placeholder]Type Scenario here..." placeholder="Type Scenario here..."></textarea> | ||
| 23 | </div> | ||
| 24 | <h4 class="flex-container alignItemsBaseline"> | ||
| 25 | <span data-i18n="Examples of dialogue">Examples of dialogue</span> | ||
| 26 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" data-for="chat_examples_override" title="Expand the editor" data-i18n="[title]Expand the editor"></i> | ||
| 27 | </h4> | ||
| 28 | <div> | ||
| 29 | <textarea id="chat_examples_override" class="chat_examples text_pole" rows="6" data-i18n="[placeholder]Type Example Messages here..." placeholder="Type Example Messages here..."></textarea> | ||
| 30 | </div> | ||
| 31 | <h4 class="flex-container alignItemsBaseline"> | ||
| 32 | <span data-i18n="Main Prompt">Main Prompt</span> | ||
| 33 | <small> | ||
| 34 | <small>—</small> | ||
| 35 | <i class="fa-solid fa-user-cog"></i> | ||
| 36 | <b data-i18n="Prefer Char. Prompt">Prefer Char. Prompt</b> | ||
| 37 | <span data-i18n="MUST be enabled!">MUST be enabled!</span> | ||
| 38 | </small> | ||
| 39 | <i class="editor_maximize fa-solid fa-maximize right_menu_button" data-for="chat_system_prompt_override" title="Expand the editor" data-i18n="[title]Expand the editor"></i> | ||
| 40 | </h4> | ||
| 41 | <div> | ||
| 42 | <textarea id="chat_system_prompt_override" class="chat_system_prompt text_pole" rows="6" data-i18n="[placeholder]Type System Prompt here..." placeholder="Type System Prompt here..."></textarea> | ||
| 43 | </div> | ||
| 16 | </div> | 44 | </div> |
| 17 | </div> | 45 | </div> |