Update SillyBubble extension to support new image features
- Add support for character-based bubble styling - Add support for speech and thought bubble types - Update function schema with new parameters - Add UI settings for character and bubble type selection - Update examples and documentation - Keep backward compatibility with style parameter 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e0d54bd1b6
commit
48610c7ba6
32
example.html
32
example.html
@ -21,7 +21,7 @@
|
||||
</div>
|
||||
|
||||
<div class="sillybubble_block flex-container">
|
||||
<label for="sillybubble_default_style">Default Bubble Style:</label>
|
||||
<label for="sillybubble_default_style">Default Bubble Style (Legacy):</label>
|
||||
<select id="sillybubble_default_style" class="text_pole">
|
||||
<option value="default">Default</option>
|
||||
<option value="modern">Modern</option>
|
||||
@ -30,6 +30,22 @@
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="sillybubble_block flex-container">
|
||||
<label for="sillybubble_default_character">Default Character:</label>
|
||||
<select id="sillybubble_default_character" class="text_pole">
|
||||
<option value="Example">Example</option>
|
||||
<option value="Bianca">Bianca</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="sillybubble_block flex-container">
|
||||
<label for="sillybubble_default_bubble_type">Default Bubble Type:</label>
|
||||
<select id="sillybubble_default_bubble_type" class="text_pole">
|
||||
<option value="speech">Speech</option>
|
||||
<option value="thought">Thought</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="sillybubble_block flex-container">
|
||||
<input id="sillybubble_test_button" class="menu_button" type="submit" value="Test Chat Bubble" />
|
||||
</div>
|
||||
@ -40,7 +56,9 @@
|
||||
<p>Parameters:</p>
|
||||
<ul>
|
||||
<li><code>text</code>: The text to display in the bubble</li>
|
||||
<li><code>style</code>: (Optional) Bubble style</li>
|
||||
<li><code>character</code>: (Optional) Character to use (Example, Bianca, etc.)</li>
|
||||
<li><code>bubble_type</code>: (Optional) Bubble type (speech, thought)</li>
|
||||
<li><code>style</code>: (Optional, Legacy) Bubble style</li>
|
||||
</ul>
|
||||
<div class="sillybubble_important">
|
||||
<p><strong>Important:</strong> Make sure function calling is enabled in SillyTavern's AI settings and the model you're using supports function calling.</p>
|
||||
@ -51,16 +69,20 @@
|
||||
<li>The function appears in the function list</li>
|
||||
</ol>
|
||||
<p><strong>🚨 REQUIRED SETUP:</strong> You MUST add the following to your system prompt or character card:</p>
|
||||
<pre>You have access to a function called generateChatBubbleImage(text, style) that creates chat bubbles with the given text.
|
||||
<pre>You have access to a function called generateChatBubbleImage(text, character, bubble_type, style) that creates character-styled chat bubbles.
|
||||
|
||||
The function parameters are:
|
||||
- text: The text to display in the chat bubble (required string)
|
||||
- style: Visual style of the bubble (optional string: "default", "modern", "retro", or "minimal")
|
||||
- character: The character to use for the bubble (optional string: "Example", "Bianca", etc.)
|
||||
- bubble_type: The type of bubble to use (optional string: "speech" or "thought")
|
||||
- style: Legacy parameter for visual style (optional string: "default", "modern", "retro", or "minimal")
|
||||
|
||||
When you want to create a chat bubble, call this function with the text you want to display.
|
||||
Example usage:
|
||||
generateChatBubbleImage("Hello world!")
|
||||
generateChatBubbleImage("Hello in retro style", "retro")</pre>
|
||||
generateChatBubbleImage("Hello from Bianca", "Bianca")
|
||||
generateChatBubbleImage("I'm thinking...", "Example", "thought")
|
||||
generateChatBubbleImage("Hello in retro style", null, null, "retro")</pre>
|
||||
<p><strong>ALTERNATIVE:</strong> If the AI can't call the function directly, you can instruct it to respond with Markdown formatted like this:</p>
|
||||
<pre></pre>
|
||||
</div>
|
||||
|
69
index.js
69
index.js
@ -10,6 +10,8 @@ const extensionFolderPath = `scripts/extensions/third-party/${extensionName}`;
|
||||
const defaultSettings = {
|
||||
image_service_url: "http://calista.the.sexiest.cat/image.php", // Use fully qualified URL by default
|
||||
default_style: "default",
|
||||
default_character: "Example",
|
||||
default_bubble_type: "speech",
|
||||
enabled: true,
|
||||
render_in_collapse: true // Setting to enable/disable rendering in collapsed tool calls
|
||||
};
|
||||
@ -33,13 +35,15 @@ if (extension_settings[extensionName].image_service_url &&
|
||||
}
|
||||
|
||||
// Function for AI to call - generates markdown image with URL-encoded text
|
||||
function generateChatBubbleImage(text, style) {
|
||||
function generateChatBubbleImage(text, style, character, bubble_type) {
|
||||
if (!extension_settings[extensionName].enabled) {
|
||||
return text;
|
||||
}
|
||||
|
||||
// Use default style if not specified
|
||||
// Use default values if parameters not specified
|
||||
const bubbleStyle = style || extension_settings[extensionName].default_style;
|
||||
const characterName = character || extension_settings[extensionName].default_character;
|
||||
const bubbleType = bubble_type || extension_settings[extensionName].default_bubble_type;
|
||||
|
||||
// URL encode the text parameter
|
||||
const encodedText = encodeURIComponent(text);
|
||||
@ -52,17 +56,26 @@ function generateChatBubbleImage(text, style) {
|
||||
}
|
||||
|
||||
// Construct the URL with the encoded text
|
||||
const imageUrl = `${serviceUrl}?q=${encodedText}`;
|
||||
let imageUrl = `${serviceUrl}?q=${encodedText}`;
|
||||
|
||||
// Add style parameter if specified
|
||||
const fullUrl = bubbleStyle !== "default"
|
||||
? `${imageUrl}&style=${bubbleStyle}`
|
||||
: imageUrl;
|
||||
// Add parameters if they differ from defaults
|
||||
if (characterName && characterName !== "Example") {
|
||||
imageUrl += `&character=${characterName}`;
|
||||
}
|
||||
|
||||
console.log(`[${extensionName}] Generated image URL: ${fullUrl}`);
|
||||
if (bubbleType && bubbleType !== "speech") {
|
||||
imageUrl += `&bubble_type=${bubbleType}`;
|
||||
}
|
||||
|
||||
// Add style parameter if specified (for backward compatibility)
|
||||
if (bubbleStyle && bubbleStyle !== "default" && !characterName) {
|
||||
imageUrl += `&style=${bubbleStyle}`;
|
||||
}
|
||||
|
||||
console.log(`[${extensionName}] Generated image URL: ${imageUrl}`);
|
||||
|
||||
// Return markdown image format
|
||||
return ``;
|
||||
return ``;
|
||||
}
|
||||
|
||||
// Load extension settings into UI
|
||||
@ -71,6 +84,8 @@ function loadSettings() {
|
||||
$("#sillybubble_enabled").prop("checked", extension_settings[extensionName].enabled).trigger("input");
|
||||
$("#sillybubble_image_url").val(extension_settings[extensionName].image_service_url).trigger("input");
|
||||
$("#sillybubble_default_style").val(extension_settings[extensionName].default_style).trigger("input");
|
||||
$("#sillybubble_default_character").val(extension_settings[extensionName].default_character).trigger("input");
|
||||
$("#sillybubble_default_bubble_type").val(extension_settings[extensionName].default_bubble_type).trigger("input");
|
||||
$("#sillybubble_render_in_collapse").prop("checked", extension_settings[extensionName].render_in_collapse).trigger("input");
|
||||
}
|
||||
|
||||
@ -103,6 +118,20 @@ function onDefaultStyleInput(event) {
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
// Handle default character changes
|
||||
function onDefaultCharacterInput(event) {
|
||||
const value = $(event.target).val();
|
||||
extension_settings[extensionName].default_character = value;
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
// Handle default bubble type changes
|
||||
function onDefaultBubbleTypeInput(event) {
|
||||
const value = $(event.target).val();
|
||||
extension_settings[extensionName].default_bubble_type = value;
|
||||
saveSettingsDebounced();
|
||||
}
|
||||
|
||||
// Handle render in collapse toggle
|
||||
function onRenderInCollapseInput(event) {
|
||||
const value = Boolean($(event.target).prop("checked"));
|
||||
@ -116,11 +145,15 @@ function onRenderInCollapseInput(event) {
|
||||
// Test function to visualize a bubble
|
||||
function onTestButtonClick() {
|
||||
const testText = "This is a test chat bubble generated by SillyBubble!";
|
||||
const markdown = generateChatBubbleImage(testText);
|
||||
const character = extension_settings[extensionName].default_character;
|
||||
const bubbleType = extension_settings[extensionName].default_bubble_type;
|
||||
|
||||
const markdown = generateChatBubbleImage(testText, null, character, bubbleType);
|
||||
const testPopup = `
|
||||
<div class="sillybubble-test">
|
||||
<p>Generated Markdown:</p>
|
||||
<pre>${markdown.replace(/</g, '<').replace(/>/g, '>')}</pre>
|
||||
<p>Using character: <strong>${character}</strong>, bubble type: <strong>${bubbleType}</strong></p>
|
||||
<p>Preview (if connected to image service):</p>
|
||||
<div>${markdown}</div>
|
||||
</div>
|
||||
@ -151,7 +184,15 @@ function registerFunctionTool() {
|
||||
},
|
||||
style: {
|
||||
type: 'string',
|
||||
description: 'The visual style of the chat bubble (default, modern, retro, minimal)'
|
||||
description: 'Legacy parameter: The visual style of the chat bubble (default, modern, retro, minimal). Prefer using character parameter instead.'
|
||||
},
|
||||
character: {
|
||||
type: 'string',
|
||||
description: 'The character to display (Example, Bianca, etc.). Each character has its own bubble style.'
|
||||
},
|
||||
bubble_type: {
|
||||
type: 'string',
|
||||
description: 'The type of bubble to use (speech, thought). Defaults to speech.'
|
||||
},
|
||||
},
|
||||
required: ['text']
|
||||
@ -161,11 +202,11 @@ function registerFunctionTool() {
|
||||
context.registerFunctionTool({
|
||||
name: 'generateChatBubbleImage',
|
||||
displayName: 'Chat Bubble Image',
|
||||
description: 'Creates a markdown image link with the text displayed as a styled chat bubble. Use when you want to visually style messages or display text in a speech bubble.',
|
||||
description: 'Creates a markdown image link with the text displayed as a character-styled chat bubble. Use when you want to visually style messages or display text in a speech or thought bubble.',
|
||||
parameters: bubbleSchema,
|
||||
action: async (args) => {
|
||||
if (!args?.text) return '';
|
||||
return generateChatBubbleImage(args.text, args.style);
|
||||
return generateChatBubbleImage(args.text, args.style, args.character, args.bubble_type);
|
||||
},
|
||||
formatMessage: () => '',
|
||||
});
|
||||
@ -395,6 +436,8 @@ jQuery(async () => {
|
||||
$("#sillybubble_enabled").on("input", onEnabledInput);
|
||||
$("#sillybubble_image_url").on("input", onImageUrlInput);
|
||||
$("#sillybubble_default_style").on("input", onDefaultStyleInput);
|
||||
$("#sillybubble_default_character").on("input", onDefaultCharacterInput);
|
||||
$("#sillybubble_default_bubble_type").on("input", onDefaultBubbleTypeInput);
|
||||
$("#sillybubble_render_in_collapse").on("input", onRenderInCollapseInput);
|
||||
$("#sillybubble_test_button").on("click", onTestButtonClick);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user