Tool Calling: add shouldRegister function to tool defintion
| @@ -32,6 +32,7 @@ import { slashCommandReturnHelper } from './slash-commands/SlashCommandReturnHel | ||
| 32 | 32 | * @property {object} parameters - The parameters for the tool. |
| 33 | 33 | * @property {function} action - The action to perform when the tool is invoked. |
| 34 | 34 | * @property {function} formatMessage - A function to format the tool call message. |
| 35 | + * @property {function} shouldRegister - A function to determine if the tool should be registered. | |
| 35 | 36 | */ |
| 36 | 37 | |
| 37 | 38 | /** |
| @@ -138,6 +139,12 @@ class ToolDefinition { | ||
| 138 | 139 | #formatMessage; |
| 139 | 140 | |
| 140 | 141 | /** |
| 142 | + * A function that will be called to determine if the tool should be registered. | |
| 143 | + * @type {function} | |
| 144 | + */ | |
| 145 | + #shouldRegister; | |
| 146 | + | |
| 147 | + /** | |
| 141 | 148 | * Creates a new ToolDefinition. |
| 142 | 149 | * @param {string} name A unique name for the tool. |
| 143 | 150 | * @param {string} displayName A user-friendly display name for the tool. |
| @@ -145,14 +152,16 @@ class ToolDefinition { | ||
| 145 | 152 | * @param {object} parameters A JSON schema for the parameters that the tool accepts. |
| 146 | 153 | * @param {function} action A function that will be called when the tool is executed. |
| 147 | 154 | * @param {function} formatMessage A function that will be called to format the tool call toast. |
| 155 | + * @param {function} shouldRegister A function that will be called to determine if the tool should be registered. | |
| 148 | 156 | */ |
| 149 | 157 | constructor(name, displayName, description, parameters, action, formatMessage, shouldRegister) { |
| 150 | 158 | this.#name = name; |
| 151 | 159 | this.#displayName = displayName; |
| 152 | 160 | this.#description = description; |
| 153 | 161 | this.#parameters = parameters; |
| 154 | 162 | this.#action = action; |
| 155 | 163 | this.#formatMessage = formatMessage; |
| 164 | + this.#shouldRegister = shouldRegister; | |
| 156 | 165 | } |
| 157 | 166 | |
| 158 | 167 | /** |
| @@ -193,6 +202,12 @@ class ToolDefinition { | ||
| 193 | 202 | : `Invoking tool: ${this.#displayName || this.#name}`; |
| 194 | 203 | } |
| 195 | 204 | |
| 205 | + async shouldRegister() { | |
| 206 | + return typeof this.#shouldRegister === 'function' | |
| 207 | + ? await this.#shouldRegister() | |
| 208 | + : true; | |
| 209 | + } | |
| 210 | + | |
| 196 | 211 | get displayName() { |
| 197 | 212 | return this.#displayName; |
| 198 | 213 | } |
| @@ -228,17 +243,17 @@ export class ToolManager { | ||
| 228 | 243 | * Registers a new tool with the tool registry. |
| 229 | 244 | * @param {ToolRegistration} tool The tool to register. |
| 230 | 245 | */ |
| 231 | 246 | static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage, shouldRegister }) { |
| 232 | 247 | // Convert WIP arguments |
| 233 | 248 | if (typeof arguments[0] !== 'object') { |
| 234 | 249 | [name, description, parameters, action] = arguments; |
| 235 | 250 | } |
| 236 | 251 | |
| 237 | 252 | if (this.#tools.has(name)) { |
| 238 | 253 | console.warn(`[ToolManager] A tool with the name "${name}" has already been registered. The definition will be overwritten.`); |
| 239 | 254 | } |
| 240 | 255 | |
| 241 | 256 | const definition = new ToolDefinition(name, displayName, description, parameters, action, formatMessage, shouldRegister); |
| 242 | 257 | this.#tools.set(name, definition); |
| 243 | 258 | console.log('[ToolManager] Registered function tool:', definition); |
| 244 | 259 | } |
| @@ -273,7 +288,7 @@ export class ToolManager { | ||
| 273 | 288 | const result = await tool.invoke(invokeParameters); |
| 274 | 289 | return typeof result === 'string' ? result : JSON.stringify(result); |
| 275 | 290 | } catch (error) { |
| 276 | 291 | console.error(`[ToolManager] An error occurred while invoking the tool "${name}":`, error); |
| 277 | 292 | |
| 278 | 293 | if (error instanceof Error) { |
| 279 | 294 | error.cause = name; |
| @@ -300,7 +315,7 @@ export class ToolManager { | ||
| 300 | 315 | const formatParameters = typeof parameters === 'string' ? JSON.parse(parameters) : parameters; |
| 301 | 316 | return tool.formatMessage(formatParameters); |
| 302 | 317 | } catch (error) { |
| 303 | 318 | console.error(`[ToolManager] An error occurred while formatting the tool call message for "${name}":`, error); |
| 304 | 319 | return `Invoking tool: ${name}`; |
| 305 | 320 | } |
| 306 | 321 | } |
| @@ -327,11 +342,16 @@ export class ToolManager { | ||
| 327 | 342 | const tools = []; |
| 328 | 343 | |
| 329 | 344 | for (const tool of ToolManager.tools) { |
| 345 | + const register = await tool.shouldRegister(); | |
| 346 | + if (!register) { | |
| 347 | + console.log('[ToolManager] Skipping tool registration:', tool); | |
| 348 | + continue; | |
| 349 | + } | |
| 330 | 350 | tools.push(tool.toFunctionOpenAI()); |
| 331 | 351 | } |
| 332 | 352 | |
| 333 | 353 | if (tools.length) { |
| 334 | 354 | console.log('[ToolManager] Registered function tools:', tools); |
| 335 | 355 | |
| 336 | 356 | data['tools'] = tools; |
| 337 | 357 | data['tool_choice'] = 'auto'; |
| @@ -422,7 +442,7 @@ export class ToolManager { | ||
| 422 | 442 | delete targetToolCall[this.#INPUT_DELTA_KEY]; |
| 423 | 443 | ToolManager.#applyToolCallDelta(targetToolCall, jsonDelta); |
| 424 | 444 | } catch (error) { |
| 425 | 445 | console.warn('[ToolManager] Failed to apply input JSON delta:', error); |
| 426 | 446 | } |
| 427 | 447 | } |
| 428 | 448 | } |
| @@ -564,7 +584,7 @@ export class ToolManager { | ||
| 564 | 584 | continue; |
| 565 | 585 | } |
| 566 | 586 | |
| 567 | 587 | console.log('[ToolManager] Function tool call:', toolCall); |
| 568 | 588 | const id = toolCall.id; |
| 569 | 589 | const parameters = toolCall.function.arguments; |
| 570 | 590 | const name = toolCall.function.name; |
| @@ -574,7 +594,7 @@ export class ToolManager { | ||
| 574 | 594 | const toast = message && toastr.info(message, 'Tool Calling', { timeOut: 0 }); |
| 575 | 595 | const toolResult = await ToolManager.invokeFunctionTool(name, parameters); |
| 576 | 596 | toastr.clear(toast); |
| 577 | 597 | console.log('[ToolManager] Function tool result:', result); |
| 578 | 598 | |
| 579 | 599 | // Save a successful invocation |
| 580 | 600 | if (toolResult instanceof Error) { |