Fix function calling integration and add system prompt instructions

- Add multiple registration methods to ensure function availability
- Try registering at multiple times during initialization lifecycle
- Create special function object formats for different AI models
- Add detailed instructions in UI for adding necessary system prompt
- Provide alternative direct markdown format as fallback
- Add more robust error handling and diagnostics

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Sven Olderaan 2025-03-14 21:26:07 +01:00
parent 247abbe91a
commit 3826b3ce84
2 changed files with 146 additions and 66 deletions

View File

@ -45,6 +45,19 @@
<li>"Include functions in context" is checked</li>
<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.
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")
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>
<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>![](image.php?q=Hello%20world)</pre>
</div>
</div>

199
index.js
View File

@ -95,60 +95,106 @@ function onTestButtonClick() {
// Register function tool
function registerFunctionTool() {
try {
// Check if ToolManager exists in global scope
if (!window.ToolManager) {
console.warn(`[${extensionName}] ToolManager not found. Will try alternative registration methods.`);
// Method 1: Register directly to window
window.generateChatBubbleImage = generateChatBubbleImage;
console.log(`[${extensionName}] Registered function to window object`);
// Method 2: Add to extensions_functions if it exists
if (window.extensions_functions) {
window.extensions_functions['generateChatBubbleImage'] = generateChatBubbleImage;
console.log(`[${extensionName}] Added to extensions_functions`);
}
return;
}
// Check if tool calling is supported
if (typeof window.ToolManager.isToolCallingSupported !== 'function' || !window.ToolManager.isToolCallingSupported()) {
console.warn(`[${extensionName}] Tool calling is not supported in the current configuration`);
return;
}
// Define the function parameters schema
const parameters = {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "The text to display in the chat bubble"
},
"style": {
"type": "string",
"description": "The visual style of the chat bubble (default, modern, retro, minimal)"
}
},
"required": ["text"]
};
// Register the tool
window.ToolManager.registerFunctionTool({
name: 'generateChatBubbleImage',
displayName: 'Generate Chat Bubble',
description: 'Creates a markdown image link with the text displayed as a chat bubble',
parameters: parameters,
action: async (params) => {
return generateChatBubbleImage(params.text, params.style);
},
formatMessage: async (params) => {
return `Generating chat bubble with text: "${params.text?.substring(0, 30)}${params.text?.length > 30 ? '...' : ''}"`;
}
});
// Register the function in the most direct way to the window
window.generateChatBubbleImage = generateChatBubbleImage;
console.log(`[${extensionName}] Registered function to window object`);
// Method 1: Try through window.SillyTavern API if it exists
if (window.SillyTavern?.getContext) {
try {
const api = window.SillyTavern;
const context = api.getContext();
// Add to context directly
context.generateChatBubbleImage = generateChatBubbleImage;
console.log(`[${extensionName}] Function added to SillyTavern context API`);
// If registerCustomFunction exists, use it
if (typeof api.registerCustomFunction === 'function') {
api.registerCustomFunction('generateChatBubbleImage', generateChatBubbleImage);
console.log(`[${extensionName}] Function registered via SillyTavern API`);
}
} catch (error) {
console.warn(`[${extensionName}] Error registering with SillyTavern API:`, error);
}
}
// Method 2: Try through extensions_functions if it exists
if (window.extensions_functions) {
window.extensions_functions['generateChatBubbleImage'] = generateChatBubbleImage;
console.log(`[${extensionName}] Added to extensions_functions`);
}
// Method 3: Try with ToolManager if it exists
if (window.ToolManager) {
try {
// Check if tool calling is supported
if (typeof window.ToolManager.isToolCallingSupported === 'function' &&
window.ToolManager.isToolCallingSupported()) {
// Define the function parameters schema
const parameters = {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "The text to display in the chat bubble"
},
"style": {
"type": "string",
"description": "The visual style of the chat bubble (default, modern, retro, minimal)"
}
},
"required": ["text"]
};
// Register the tool
window.ToolManager.registerFunctionTool({
name: 'generateChatBubbleImage',
displayName: 'Generate Chat Bubble',
description: 'Creates a markdown image link with the text displayed as a chat bubble',
parameters: parameters,
action: async (params) => {
return generateChatBubbleImage(params.text, params.style);
},
formatMessage: async (params) => {
return `Generating chat bubble with text: "${params.text?.substring(0, 30)}${params.text?.length > 30 ? '...' : ''}"`;
}
});
console.log(`[${extensionName}] Function tool registered via ToolManager`);
} else {
console.warn(`[${extensionName}] Tool calling is not supported in the current configuration`);
}
} catch (error) {
console.error(`[${extensionName}] Error registering with ToolManager:`, error);
}
}
// Method 4: Try to register globally as a function call format
// This creates a special object that some AI models might recognize
window.AI_FUNCTION_generateChatBubbleImage = {
name: 'generateChatBubbleImage',
description: 'Creates a markdown image link with the text displayed as a chat bubble',
parameters: {
type: 'object',
properties: {
text: {
type: 'string',
description: 'The text to display in the chat bubble'
},
style: {
type: 'string',
description: 'The visual style of the chat bubble (optional)'
}
},
required: ['text']
},
function: generateChatBubbleImage
};
console.log(`[${extensionName}] Created special AI function format object`);
console.log(`[${extensionName}] Function tool registered via ToolManager`);
} catch (error) {
console.error(`[${extensionName}] Error registering function tool:`, error);
}
@ -170,25 +216,46 @@ jQuery(async () => {
$("#sillybubble_default_style").on("input", onDefaultStyleInput);
$("#sillybubble_test_button").on("click", onTestButtonClick);
// Wait for the document to fully load before trying to register tools
// First registration attempt immediately
registerFunctionTool();
// Try to add to context immediately
try {
const context = getContext();
if (context) {
// Make the function available to the AI
context.generateChatBubbleImage = generateChatBubbleImage;
console.log(`[${extensionName}] Function added to context: generateChatBubbleImage`);
}
} catch (error) {
console.error(`[${extensionName}] Error adding function to context:`, error);
}
// Wait for the document to fully load before trying again
$(document).ready(() => {
// Try registration again after a short delay
setTimeout(() => {
// Try to register the function tool after a short delay
// to ensure all SillyTavern systems are initialized
registerFunctionTool();
// Also add the function to extension context
try {
const context = getContext();
if (context) {
// Make the function available to the AI
context.generateChatBubbleImage = generateChatBubbleImage;
console.log(`[${extensionName}] Function added to context: generateChatBubbleImage`);
// Add function to global window for direct accessibility
window.generateChatBubbleImage = generateChatBubbleImage;
// Also add explicit API function definition for direct calling
window.SILLYBUBBLE_FUNCTION = {
name: 'generateChatBubbleImage',
call: function(text, style) {
return generateChatBubbleImage(text, style);
}
} catch (error) {
console.error(`[${extensionName}] Error adding function to context:`, error);
}
};
console.log(`[${extensionName}] Function registration and context setup completed`);
}, 2000); // Wait 2 seconds for SillyTavern to initialize
// One final attempt after 10 seconds
setTimeout(() => {
registerFunctionTool();
console.log(`[${extensionName}] Final function registration attempt completed`);
}, 10000);
});
// Load settings