Tool Calling: add shouldRegister function to tool defintion

bc0f5bf4ceea7960ea574e291b576ea5115f42e6

Cohee <18619528+Cohee1207@users.noreply.github.com>

1 files changed, +30 -10Ignore whitespace
public/scripts/tool-calling.js+30 -10
@@ -32,6 +32,7 @@ import { slashCommandReturnHelper } from './slash-commands/SlashCommandReturnHel
32 * @property {object} parameters - The parameters for the tool.32 * @property {object} parameters - The parameters for the tool.
33 * @property {function} action - The action to perform when the tool is invoked.33 * @property {function} action - The action to perform when the tool is invoked.
34 * @property {function} formatMessage - A function to format the tool call message.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 */
3637
37/**38/**
@@ -138,6 +139,12 @@ class ToolDefinition {
138 #formatMessage;139 #formatMessage;
139140
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 * Creates a new ToolDefinition.148 * Creates a new ToolDefinition.
142 * @param {string} name A unique name for the tool.149 * @param {string} name A unique name for the tool.
143 * @param {string} displayName A user-friendly display name for the tool.150 * @param {string} displayName A user-friendly display name for the tool.
@@ -145,14 +152,16 @@ class ToolDefinition {
145 * @param {object} parameters A JSON schema for the parameters that the tool accepts.152 * @param {object} parameters A JSON schema for the parameters that the tool accepts.
146 * @param {function} action A function that will be called when the tool is executed.153 * @param {function} action A function that will be called when the tool is executed.
147 * @param {function} formatMessage A function that will be called to format the tool call toast.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 constructor(name, displayName, description, parameters, action, formatMessage) {157 constructor(name, displayName, description, parameters, action, formatMessage, shouldRegister) {
150 this.#name = name;158 this.#name = name;
151 this.#displayName = displayName;159 this.#displayName = displayName;
152 this.#description = description;160 this.#description = description;
153 this.#parameters = parameters;161 this.#parameters = parameters;
154 this.#action = action;162 this.#action = action;
155 this.#formatMessage = formatMessage;163 this.#formatMessage = formatMessage;
164 this.#shouldRegister = shouldRegister;
156 }165 }
157166
158 /**167 /**
@@ -193,6 +202,12 @@ class ToolDefinition {
193 : `Invoking tool: ${this.#displayName || this.#name}`;202 : `Invoking tool: ${this.#displayName || this.#name}`;
194 }203 }
195204
205 async shouldRegister() {
206 return typeof this.#shouldRegister === 'function'
207 ? await this.#shouldRegister()
208 : true;
209 }
210
196 get displayName() {211 get displayName() {
197 return this.#displayName;212 return this.#displayName;
198 }213 }
@@ -228,17 +243,17 @@ export class ToolManager {
228 * Registers a new tool with the tool registry.243 * Registers a new tool with the tool registry.
229 * @param {ToolRegistration} tool The tool to register.244 * @param {ToolRegistration} tool The tool to register.
230 */245 */
231 static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage }) {246 static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage, shouldRegister }) {
232 // Convert WIP arguments247 // Convert WIP arguments
233 if (typeof arguments[0] !== 'object') {248 if (typeof arguments[0] !== 'object') {
234 [name, description, parameters, action] = arguments;249 [name, description, parameters, action] = arguments;
235 }250 }
236251
237 if (this.#tools.has(name)) {252 if (this.#tools.has(name)) {
238 console.warn(`A tool with the name "${name}" has already been registered. The definition will be overwritten.`);253 console.warn(`[ToolManager] A tool with the name "${name}" has already been registered. The definition will be overwritten.`);
239 }254 }
240255
241 const definition = new ToolDefinition(name, displayName, description, parameters, action, formatMessage);256 const definition = new ToolDefinition(name, displayName, description, parameters, action, formatMessage, shouldRegister);
242 this.#tools.set(name, definition);257 this.#tools.set(name, definition);
243 console.log('[ToolManager] Registered function tool:', definition);258 console.log('[ToolManager] Registered function tool:', definition);
244 }259 }
@@ -273,7 +288,7 @@ export class ToolManager {
273 const result = await tool.invoke(invokeParameters);288 const result = await tool.invoke(invokeParameters);
274 return typeof result === 'string' ? result : JSON.stringify(result);289 return typeof result === 'string' ? result : JSON.stringify(result);
275 } catch (error) {290 } catch (error) {
276 console.error(`An error occurred while invoking the tool "${name}":`, error);291 console.error(`[ToolManager] An error occurred while invoking the tool "${name}":`, error);
277292
278 if (error instanceof Error) {293 if (error instanceof Error) {
279 error.cause = name;294 error.cause = name;
@@ -300,7 +315,7 @@ export class ToolManager {
300 const formatParameters = typeof parameters === 'string' ? JSON.parse(parameters) : parameters;315 const formatParameters = typeof parameters === 'string' ? JSON.parse(parameters) : parameters;
301 return tool.formatMessage(formatParameters);316 return tool.formatMessage(formatParameters);
302 } catch (error) {317 } catch (error) {
303 console.error(`An error occurred while formatting the tool call message for "${name}":`, error);318 console.error(`[ToolManager] An error occurred while formatting the tool call message for "${name}":`, error);
304 return `Invoking tool: ${name}`;319 return `Invoking tool: ${name}`;
305 }320 }
306 }321 }
@@ -327,11 +342,16 @@ export class ToolManager {
327 const tools = [];342 const tools = [];
328343
329 for (const tool of ToolManager.tools) {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 tools.push(tool.toFunctionOpenAI());350 tools.push(tool.toFunctionOpenAI());
331 }351 }
332352
333 if (tools.length) {353 if (tools.length) {
334 console.log('Registered function tools:', tools);354 console.log('[ToolManager] Registered function tools:', tools);
335355
336 data['tools'] = tools;356 data['tools'] = tools;
337 data['tool_choice'] = 'auto';357 data['tool_choice'] = 'auto';
@@ -422,7 +442,7 @@ export class ToolManager {
422 delete targetToolCall[this.#INPUT_DELTA_KEY];442 delete targetToolCall[this.#INPUT_DELTA_KEY];
423 ToolManager.#applyToolCallDelta(targetToolCall, jsonDelta);443 ToolManager.#applyToolCallDelta(targetToolCall, jsonDelta);
424 } catch (error) {444 } catch (error) {
425 console.warn('Failed to apply input JSON delta:', error);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 continue;584 continue;
565 }585 }
566586
567 console.log('Function tool call:', toolCall);587 console.log('[ToolManager] Function tool call:', toolCall);
568 const id = toolCall.id;588 const id = toolCall.id;
569 const parameters = toolCall.function.arguments;589 const parameters = toolCall.function.arguments;
570 const name = toolCall.function.name;590 const name = toolCall.function.name;
@@ -574,7 +594,7 @@ export class ToolManager {
574 const toast = message && toastr.info(message, 'Tool Calling', { timeOut: 0 });594 const toast = message && toastr.info(message, 'Tool Calling', { timeOut: 0 });
575 const toolResult = await ToolManager.invokeFunctionTool(name, parameters);595 const toolResult = await ToolManager.invokeFunctionTool(name, parameters);
576 toastr.clear(toast);596 toastr.clear(toast);
577 console.log('Function tool result:', result);597 console.log('[ToolManager] Function tool result:', result);
578598
579 // Save a successful invocation599 // Save a successful invocation
580 if (toolResult instanceof Error) {600 if (toolResult instanceof Error) {