From c853547b11a8d219fb9c3c04bd05737dc56678e7 Mon Sep 17 00:00:00 2001 From: Cohee <18619528+Cohee1207@users.noreply.github.com> Date: Fri, 4 Oct 2024 13:04:19 +0000 Subject: [PATCH] Add a function tool for image generation --- .../extensions/stable-diffusion/index.js | 54 +++++++++++++++++++ .../extensions/stable-diffusion/settings.html | 4 ++ 2 files changed, 58 insertions(+) diff --git a/public/scripts/extensions/stable-diffusion/index.js b/public/scripts/extensions/stable-diffusion/index.js index e96575d56..0289ff807 100644 --- a/public/scripts/extensions/stable-diffusion/index.js +++ b/public/scripts/extensions/stable-diffusion/index.js @@ -32,6 +32,7 @@ import { debounce_timeout } from '../../constants.js'; import { SlashCommandEnumValue } from '../../slash-commands/SlashCommandEnumValue.js'; import { POPUP_RESULT, POPUP_TYPE, Popup, callGenericPopup } from '../../popup.js'; import { commonEnumProviders } from '../../slash-commands/SlashCommandCommonEnumsProvider.js'; +import { ToolManager } from '../../tool-calling.js'; export { MODULE_NAME }; const MODULE_NAME = 'sd'; @@ -62,6 +63,7 @@ const initiators = { interactive: 'interactive', wand: 'wand', swipe: 'swipe', + tool: 'tool', }; const generationMode = { @@ -226,6 +228,7 @@ const defaultSettings = { multimodal_captioning: false, snap: false, free_extend: false, + function_tool: false, prompts: promptTemplates, @@ -291,6 +294,10 @@ const defaultSettings = { const writePromptFieldsDebounced = debounce(writePromptFields, debounce_timeout.relaxed); function processTriggers(chat, _, abort) { + if (extension_settings.sd.function_tool && ToolManager.isToolCallingSupported()) { + return; + } + if (!extension_settings.sd.interactive_mode) { return; } @@ -447,6 +454,7 @@ async function loadSettings() { $('#sd_interactive_visible').prop('checked', extension_settings.sd.interactive_visible); $('#sd_stability_style_preset').val(extension_settings.sd.stability_style_preset); $('#sd_huggingface_model_id').val(extension_settings.sd.huggingface_model_id); + $('#sd_function_tool').prop('checked', extension_settings.sd.function_tool); for (const style of extension_settings.sd.styles) { const option = document.createElement('option'); @@ -461,6 +469,7 @@ async function loadSettings() { toggleSourceControls(); addPromptTemplates(); + registerFunctionTool(); await loadSettingOptions(); } @@ -910,6 +919,12 @@ async function onSourceChange() { await loadSettingOptions(); } +function onFunctionToolInput() { + extension_settings.sd.function_tool = !!$(this).prop('checked'); + saveSettingsDebounced(); + registerFunctionTool(); +} + async function onOpenAiStyleSelect() { extension_settings.sd.openai_style = String($('#sd_openai_style').find(':selected').val()); saveSettingsDebounced(); @@ -3822,6 +3837,44 @@ function applyCommandArguments(args) { return currentSettings; } +function registerFunctionTool() { + if (!extension_settings.sd.function_tool) { + return ToolManager.unregisterFunctionTool('GenerateImage'); + } + + ToolManager.registerFunctionTool({ + name: 'GenerateImage', + displayName: 'Generate Image', + description: [ + 'Generate an image from a given text prompt.', + 'Use when a user asks for an image, a selfie, to picture a scene, etc.', + ].join(' '), + parameters: Object.freeze({ + $schema: 'http://json-schema.org/draft-04/schema#', + type: 'object', + properties: { + prompt: { + type: 'string', + description: [ + 'The text prompt used to generate the image.', + 'Must represent an exhaustive description of the desired image that will allow an artist or a photographer to perfectly recreate it.', + ], + }, + }, + required: [ + 'prompt', + ], + }), + action: async (args) => { + if (!isValidState()) throw new Error('Image generation is not configured.'); + if (!args) throw new Error('Missing arguments'); + if (!args.prompt) throw new Error('Missing prompt'); + return generatePicture(initiators.tool, {}, args.prompt); + }, + formatMessage: () => 'Generating an image...', + }); +} + jQuery(async () => { await addSDGenButtons(); @@ -4175,6 +4228,7 @@ jQuery(async () => { $('#sd_stability_key').on('click', onStabilityKeyClick); $('#sd_stability_style_preset').on('change', onStabilityStylePresetChange); $('#sd_huggingface_model_id').on('input', onHFModelInput); + $('#sd_function_tool').on('input', onFunctionToolInput); if (!CSS.supports('field-sizing', 'content')) { $('.sd_settings .inline-drawer-toggle').on('click', function () { diff --git a/public/scripts/extensions/stable-diffusion/settings.html b/public/scripts/extensions/stable-diffusion/settings.html index 2efa74d83..6870facd2 100644 --- a/public/scripts/extensions/stable-diffusion/settings.html +++ b/public/scripts/extensions/stable-diffusion/settings.html @@ -18,6 +18,10 @@ Interactive mode +