diff --git a/example.html b/example.html
index 625d706..86e924c 100644
--- a/example.html
+++ b/example.html
@@ -21,7 +21,7 @@
Important: Make sure function calling is enabled in SillyTavern's AI settings and the model you're using supports function calling.
@@ -51,16 +69,20 @@
The function appears in the function list
🚨 REQUIRED SETUP: You MUST add the following to your system prompt or character card:
-
You have access to a function called generateChatBubbleImage(text, style) that creates chat bubbles with the given text.
+ 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")
+generateChatBubbleImage("Hello from Bianca", "Bianca")
+generateChatBubbleImage("I'm thinking...", "Example", "thought")
+generateChatBubbleImage("Hello in retro style", null, null, "retro")
ALTERNATIVE: If the AI can't call the function directly, you can instruct it to respond with Markdown formatted like this:

diff --git a/index.js b/index.js
index ba8f392..146b90c 100644
--- a/index.js
+++ b/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 = `
Generated Markdown:
${markdown.replace(//g, '>')}
+
Using character: ${character}, bubble type: ${bubbleType}
Preview (if connected to image service):
${markdown}
@@ -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);