Indicate welcome page assistant in the list
| @@ -6383,6 +6383,9 @@ | |||
| 6383 | <div class="wide100p character_name_block"> | 6383 | <div class="wide100p character_name_block"> |
| 6384 | <span class="ch_name"></span> | 6384 | <span class="ch_name"></span> |
| 6385 | <small class="ch_additional_info ch_add_placeholder">+++</small> | 6385 | <small class="ch_additional_info ch_add_placeholder">+++</small> |
| 6386 | <small class="ch_assistant" title="This character will be used as a welcome page assistant." data-i18n="[title]This character will be used as a welcome page assistant."> | ||
| 6387 | <i class="fa-solid fa-sm fa-user-graduate"></i> | ||
| 6388 | </small> | ||
| 6386 | <small class="ch_additional_info character_version"></small> | 6389 | <small class="ch_additional_info character_version"></small> |
| 6387 | <small class="ch_additional_info ch_avatar_url"></small> | 6390 | <small class="ch_additional_info ch_avatar_url"></small> |
| 6388 | </div> | 6391 | </div> |
| @@ -282,7 +282,7 @@ import { deriveTemplatesFromChatTemplate } from './scripts/chat-templates.js'; | |||
| 282 | import { getContext } from './scripts/st-context.js'; | 282 | import { getContext } from './scripts/st-context.js'; |
| 283 | import { extractReasoningFromData, initReasoning, parseReasoningInSwipes, PromptReasoning, ReasoningHandler, removeReasoningFromString, updateReasoningUI } from './scripts/reasoning.js'; | 283 | import { extractReasoningFromData, initReasoning, parseReasoningInSwipes, PromptReasoning, ReasoningHandler, removeReasoningFromString, updateReasoningUI } from './scripts/reasoning.js'; |
| 284 | import { accountStorage } from './scripts/util/AccountStorage.js'; | 284 | import { accountStorage } from './scripts/util/AccountStorage.js'; |
| 285 | import { initWelcomeScreen, openPermanentAssistantChat, openPermanentAssistantCard } from './scripts/welcome-screen.js'; | 285 | import { initWelcomeScreen, openPermanentAssistantChat, openPermanentAssistantCard, getPermanentAssistantAvatar } from './scripts/welcome-screen.js'; |
| 286 | 286 | ||
| 287 | // API OBJECT FOR EXTERNAL WIRING | 287 | // API OBJECT FOR EXTERNAL WIRING |
| 288 | globalThis.SillyTavern = { | 288 | globalThis.SillyTavern = { |
| @@ -1473,6 +1473,11 @@ function getCharacterBlock(item, id) { | |||
| 1473 | template.toggleClass('is_fav', item.fav || item.fav == 'true'); | 1473 | template.toggleClass('is_fav', item.fav || item.fav == 'true'); |
| 1474 | template.find('.ch_fav').val(item.fav); | 1474 | template.find('.ch_fav').val(item.fav); |
| 1475 | 1475 | ||
| 1476 | const isAssistant = item.avatar === getPermanentAssistantAvatar(); | ||
| 1477 | if (!isAssistant) { | ||
| 1478 | template.find('.ch_assistant').remove(); | ||
| 1479 | } | ||
| 1480 | |||
| 1476 | const description = item.data?.creator_notes || ''; | 1481 | const description = item.data?.creator_notes || ''; |
| 1477 | if (description) { | 1482 | if (description) { |
| 1478 | template.find('.ch_description').text(description); | 1483 | template.find('.ch_description').text(description); |
| @@ -19,9 +19,26 @@ import { | |||
| 19 | import { is_group_generating } from './group-chats.js'; | 19 | import { is_group_generating } from './group-chats.js'; |
| 20 | import { t } from './i18n.js'; | 20 | import { t } from './i18n.js'; |
| 21 | import { renderTemplateAsync } from './templates.js'; | 21 | import { renderTemplateAsync } from './templates.js'; |
| 22 | import { accountStorage } from './util/AccountStorage.js'; | ||
| 22 | import { timestampToMoment } from './utils.js'; | 23 | import { timestampToMoment } from './utils.js'; |
| 23 | 24 | ||
| 24 | const permanentAssistantAvatar = 'default_Assistant.png'; | 25 | const assistantAvatarKey = 'assistant'; |
| 26 | const defaultAssistantAvatar = 'default_Assistant.png'; | ||
| 27 | |||
| 28 | export function getPermanentAssistantAvatar() { | ||
| 29 | const assistantAvatar = accountStorage.getItem(assistantAvatarKey); | ||
| 30 | if (assistantAvatar === null) { | ||
| 31 | return defaultAssistantAvatar; | ||
| 32 | } | ||
| 33 | |||
| 34 | const character = characters.find(x => x.avatar === assistantAvatar); | ||
| 35 | if (character === undefined) { | ||
| 36 | accountStorage.removeItem(assistantAvatarKey); | ||
| 37 | return defaultAssistantAvatar; | ||
| 38 | } | ||
| 39 | |||
| 40 | return assistantAvatar; | ||
| 41 | } | ||
| 25 | 42 | ||
| 26 | export async function openWelcomeScreen() { | 43 | export async function openWelcomeScreen() { |
| 27 | const currentChatId = getCurrentChatId(); | 44 | const currentChatId = getCurrentChatId(); |
| @@ -121,35 +138,32 @@ async function getRecentChats() { | |||
| 121 | /** @type {RecentChat[]} */ | 138 | /** @type {RecentChat[]} */ |
| 122 | const data = await response.json(); | 139 | const data = await response.json(); |
| 123 | 140 | ||
| 124 | data.sort((a, b) => b.last_mes - a.last_mes).forEach((chat, index) => { | 141 | data.sort((a, b) => b.last_mes - a.last_mes) |
| 125 | const character = characters.find(x => x.avatar === chat.avatar); | 142 | .map(chat => ({ chat, character: characters.find(x => x.avatar === chat.avatar) })) |
| 126 | if (!character) { | 143 | .filter(t => t.character) |
| 127 | console.warn(`Character not found for chat: ${chat.file_name}`); | 144 | .forEach(({ chat, character }) => { |
| 128 | data.splice(index, 1); | 145 | const chatTimestamp = timestampToMoment(chat.last_mes); |
| 129 | return; | 146 | chat.char_name = character.name; |
| 130 | } | 147 | chat.date_short = chatTimestamp.format('l'); |
| 131 | 148 | chat.date_long = chatTimestamp.format('LL LT'); | |
| 132 | const chatTimestamp = timestampToMoment(chat.last_mes); | 149 | chat.chat_name = chat.file_name.replace('.jsonl', ''); |
| 133 | chat.char_name = character.name; | 150 | chat.char_thumbnail = getThumbnailUrl('avatar', character.avatar); |
| 134 | chat.date_short = chatTimestamp.format('l'); | 151 | }); |
| 135 | chat.date_long = chatTimestamp.format('LL LT'); | ||
| 136 | chat.chat_name = chat.file_name.replace('.jsonl', ''); | ||
| 137 | chat.char_thumbnail = getThumbnailUrl('avatar', character.avatar); | ||
| 138 | }); | ||
| 139 | 152 | ||
| 140 | return data; | 153 | return data; |
| 141 | } | 154 | } |
| 142 | 155 | ||
| 143 | export async function openPermanentAssistantChat({ tryCreate = true } = {}) { | 156 | export async function openPermanentAssistantChat({ tryCreate = true } = {}) { |
| 144 | const characterId = characters.findIndex(x => x.avatar === permanentAssistantAvatar); | 157 | const avatar = getPermanentAssistantAvatar(); |
| 158 | const characterId = characters.findIndex(x => x.avatar === avatar); | ||
| 145 | if (characterId === -1) { | 159 | if (characterId === -1) { |
| 146 | if (!tryCreate) { | 160 | if (!tryCreate) { |
| 147 | console.error(`Character not found for avatar ID: ${permanentAssistantAvatar}. Cannot create.`); | 161 | console.error(`Character not found for avatar ID: ${avatar}. Cannot create.`); |
| 148 | return; | 162 | return; |
| 149 | } | 163 | } |
| 150 | 164 | ||
| 151 | try { | 165 | try { |
| 152 | console.log(`Character not found for avatar ID: ${permanentAssistantAvatar}. Creating new assistant.`); | 166 | console.log(`Character not found for avatar ID: ${avatar}. Creating new assistant.`); |
| 153 | await createPermanentAssistant(); | 167 | await createPermanentAssistant(); |
| 154 | return openPermanentAssistantChat({ tryCreate: false }); | 168 | return openPermanentAssistantChat({ tryCreate: false }); |
| 155 | } | 169 | } |
| @@ -177,7 +191,7 @@ async function createPermanentAssistant() { | |||
| 177 | 191 | ||
| 178 | const formData = new FormData(); | 192 | const formData = new FormData(); |
| 179 | formData.append('ch_name', neutralCharacterName); | 193 | formData.append('ch_name', neutralCharacterName); |
| 180 | formData.append('file_name', permanentAssistantAvatar.replace('.png', '')); | 194 | formData.append('file_name', defaultAssistantAvatar.replace('.png', '')); |
| 181 | 195 | ||
| 182 | const headers = getRequestHeaders(); | 196 | const headers = getRequestHeaders(); |
| 183 | delete headers['Content-Type']; | 197 | delete headers['Content-Type']; |
| @@ -197,7 +211,8 @@ async function createPermanentAssistant() { | |||
| 197 | } | 211 | } |
| 198 | 212 | ||
| 199 | export async function openPermanentAssistantCard() { | 213 | export async function openPermanentAssistantCard() { |
| 200 | const characterId = characters.findIndex(x => x.avatar === permanentAssistantAvatar); | 214 | const avatar = getPermanentAssistantAvatar(); |
| 215 | const characterId = characters.findIndex(x => x.avatar === avatar); | ||
| 201 | if (characterId === -1) { | 216 | if (characterId === -1) { |
| 202 | toastr.info(t`Assistant not found. Try sending a chat message.`); | 217 | toastr.info(t`Assistant not found. Try sending a chat message.`); |
| 203 | return; | 218 | return; |