import { getBase64Async, saveBase64AsFile } from "../../utils.js"; import { getContext, getApiUrl, doExtrasFetch, extension_settings, modules } from "../../extensions.js"; import { appendImageToMessage, callPopup, getRequestHeaders, saveSettingsDebounced, substituteParams } from "../../../script.js"; import { getMessageTimeStamp } from "../../RossAscends-mods.js"; import { SECRET_KEYS, secret_state } from "../../secrets.js"; import { isImageInliningSupported } from "../../openai.js"; import { getMultimodalCaption } from "../shared.js"; export { MODULE_NAME }; const MODULE_NAME = 'caption'; const PROMPT_DEFAULT = 'What’s in this image?'; const TEMPLATE_DEFAULT = '[{{user}} sends {{char}} a picture that contains: {{caption}}]'; /** * Migrates old extension settings to the new format. * Must keep this function for compatibility with old settings. */ function migrateSettings() { if (extension_settings.caption.local !== undefined) { extension_settings.caption.source = extension_settings.caption.local ? 'local' : 'extras'; } delete extension_settings.caption.local; if (!extension_settings.caption.source) { extension_settings.caption.source = 'extras'; } if (extension_settings.caption.source === 'openai') { extension_settings.caption.source = 'multimodal'; extension_settings.caption.multimodal_api = 'openai'; extension_settings.caption.multimodal_model = 'gpt-4-vision-preview'; } if (!extension_settings.caption.multimodal_api) { extension_settings.caption.multimodal_api = 'openai'; } if (!extension_settings.caption.multimodal_model) { extension_settings.caption.multimodal_model = 'gpt-4-vision-preview'; } if (!extension_settings.caption.prompt) { extension_settings.caption.prompt = PROMPT_DEFAULT; } if (!extension_settings.caption.template) { extension_settings.caption.template = TEMPLATE_DEFAULT; } } /** * Sets an image icon for the send button. */ async function setImageIcon() { try { const sendButton = $('#send_picture .extensionsMenuExtensionButton'); sendButton.addClass('fa-image'); sendButton.removeClass('fa-hourglass-half'); } catch (error) { console.log(error); } } /** * Sets a spinner icon for the send button. */ async function setSpinnerIcon() { try { const sendButton = $('#send_picture .extensionsMenuExtensionButton'); sendButton.removeClass('fa-image'); sendButton.addClass('fa-hourglass-half'); } catch (error) { console.log(error); } } /** * Sends a captioned message to the chat. * @param {string} caption Caption text * @param {string} image Image URL */ async function sendCaptionedMessage(caption, image) { const context = getContext(); let template = extension_settings.caption.template || TEMPLATE_DEFAULT; if (!/{{caption}}/i.test(template)) { console.warn('Poka-yoke: Caption template does not contain {{caption}}. Appending it.') template += ' {{caption}}'; } let messageText = substituteParams(template).replace(/{{caption}}/i, caption); if (extension_settings.caption.refine_mode) { messageText = await callPopup( '