Fix tool registration using SillyTavern's native API
- Refactored registerFunctionTool to follow Dice extension's pattern - Now uses context.registerFunctionTool with proper JSON schema format - Simplified initialization with cleaner retry logic - Removed redundant registration methods - Added proper schema definition with Object.freeze pattern 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
3826b3ce84
commit
ffe901e1ff
182
index.js
182
index.js
@ -95,106 +95,51 @@ function onTestButtonClick() {
|
||||
// Register function tool
|
||||
function registerFunctionTool() {
|
||||
try {
|
||||
// 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)"
|
||||
}
|
||||
// Add function directly to context
|
||||
const context = getContext();
|
||||
if (context) {
|
||||
context.generateChatBubbleImage = generateChatBubbleImage;
|
||||
console.log(`[${extensionName}] Function added to context: generateChatBubbleImage`);
|
||||
|
||||
// Check if registerFunctionTool exists in context
|
||||
if (typeof context.registerFunctionTool === 'function') {
|
||||
// Define parameter schema following JSON schema format
|
||||
const bubbleSchema = Object.freeze({
|
||||
$schema: 'http://json-schema.org/draft-04/schema#',
|
||||
type: 'object',
|
||||
properties: {
|
||||
text: {
|
||||
type: 'string',
|
||||
description: 'The text to display in the chat bubble'
|
||||
},
|
||||
"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);
|
||||
style: {
|
||||
type: 'string',
|
||||
description: 'The visual style of the chat bubble (default, modern, retro, minimal)'
|
||||
},
|
||||
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`);
|
||||
|
||||
required: ['text']
|
||||
});
|
||||
|
||||
// Register the function tool using SillyTavern's own API
|
||||
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.',
|
||||
parameters: bubbleSchema,
|
||||
action: async (args) => {
|
||||
if (!args?.text) return '';
|
||||
return generateChatBubbleImage(args.text, args.style);
|
||||
},
|
||||
formatMessage: () => '',
|
||||
});
|
||||
|
||||
console.log(`[${extensionName}] Function tool registered via context.registerFunctionTool`);
|
||||
} else {
|
||||
console.warn(`[${extensionName}] registerFunctionTool not available in context`);
|
||||
}
|
||||
} else {
|
||||
console.warn(`[${extensionName}] Unable to get context for function registration`);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`[${extensionName}] Error registering function tool:`, error);
|
||||
}
|
||||
@ -216,46 +161,19 @@ jQuery(async () => {
|
||||
$("#sillybubble_default_style").on("input", onDefaultStyleInput);
|
||||
$("#sillybubble_test_button").on("click", onTestButtonClick);
|
||||
|
||||
// First registration attempt immediately
|
||||
// Initial attempt to register the function tool
|
||||
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);
|
||||
}
|
||||
// Make function globally accessible as fallback
|
||||
window.generateChatBubbleImage = generateChatBubbleImage;
|
||||
|
||||
// Wait for the document to fully load before trying again
|
||||
// Wait for SillyTavern to fully initialize, then register again
|
||||
$(document).ready(() => {
|
||||
// Try registration again after a short delay
|
||||
setTimeout(() => {
|
||||
registerFunctionTool();
|
||||
|
||||
// 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);
|
||||
}
|
||||
};
|
||||
|
||||
console.log(`[${extensionName}] Function registration and context setup completed`);
|
||||
}, 2000); // Wait 2 seconds for SillyTavern to initialize
|
||||
// Try again after a short delay
|
||||
setTimeout(() => registerFunctionTool(), 2000);
|
||||
|
||||
// One final attempt after 10 seconds
|
||||
setTimeout(() => {
|
||||
registerFunctionTool();
|
||||
console.log(`[${extensionName}] Final function registration attempt completed`);
|
||||
}, 10000);
|
||||
// Final attempt after SillyTavern is fully loaded
|
||||
setTimeout(() => registerFunctionTool(), 10000);
|
||||
});
|
||||
|
||||
// Load settings
|
||||
|
Loading…
x
Reference in New Issue
Block a user