Update tool registration
| @@ -5,6 +5,7 @@ import { Popup } from './popup.js'; | ||
| 5 | 5 | /** |
| 6 | 6 | * @typedef {object} ToolInvocation |
| 7 | 7 | * @property {string} id - A unique identifier for the tool invocation. |
| 8 | + * @property {string} displayName - The display name of the tool. | |
| 8 | 9 | * @property {string} name - The name of the tool. |
| 9 | 10 | * @property {string} parameters - The parameters for the tool invocation. |
| 10 | 11 | * @property {string} result - The result of the tool invocation. |
| @@ -28,6 +29,12 @@ class ToolDefinition { | ||
| 28 | 29 | #name; |
| 29 | 30 | |
| 30 | 31 | /** |
| 32 | + * A user-friendly display name for the tool. | |
| 33 | + * @type {string} | |
| 34 | + */ | |
| 35 | + #displayName; | |
| 36 | + | |
| 37 | + /** | |
| 31 | 38 | * A description of what the tool does. |
| 32 | 39 | * @type {string} |
| 33 | 40 | */ |
| @@ -46,17 +53,27 @@ class ToolDefinition { | ||
| 46 | 53 | #action; |
| 47 | 54 | |
| 48 | 55 | /** |
| 56 | + * A function that will be called to format the tool call toast. | |
| 57 | + * @type {function} | |
| 58 | + */ | |
| 59 | + #formatMessage; | |
| 60 | + | |
| 61 | + /** | |
| 49 | 62 | * Creates a new ToolDefinition. |
| 50 | 63 | * @param {string} name A unique name for the tool. |
| 64 | + * @param {string} displayName A user-friendly display name for the tool. | |
| 51 | 65 | * @param {string} description A description of what the tool does. |
| 52 | 66 | * @param {object} parameters A JSON schema for the parameters that the tool accepts. |
| 53 | 67 | * @param {function} action A function that will be called when the tool is executed. |
| 68 | + * @param {function} formatMessage A function that will be called to format the tool call toast. | |
| 54 | 69 | */ |
| 55 | 70 | constructor(name, displayName, description, parameters, action, formatMessage) { |
| 56 | 71 | this.#name = name; |
| 72 | + this.#displayName = displayName; | |
| 57 | 73 | this.#description = description; |
| 58 | 74 | this.#parameters = parameters; |
| 59 | 75 | this.#action = action; |
| 76 | + this.#formatMessage = formatMessage; | |
| 60 | 77 | } |
| 61 | 78 | |
| 62 | 79 | /** |
| @@ -82,6 +99,21 @@ class ToolDefinition { | ||
| 82 | 99 | async invoke(parameters) { |
| 83 | 100 | return await this.#action(parameters); |
| 84 | 101 | } |
| 102 | + | |
| 103 | + /** | |
| 104 | + * Formats a message with the tool invocation. | |
| 105 | + * @param {object} parameters The parameters to pass to the tool. | |
| 106 | + * @returns {string} The formatted message. | |
| 107 | + */ | |
| 108 | + formatMessage(parameters) { | |
| 109 | + return typeof this.#formatMessage === 'function' | |
| 110 | + ? this.#formatMessage(parameters) | |
| 111 | + : `Invoking tool: ${this.#displayName || this.#name}`; | |
| 112 | + } | |
| 113 | + | |
| 114 | + get displayName() { | |
| 115 | + return this.#displayName; | |
| 116 | + } | |
| 85 | 117 | } |
| 86 | 118 | |
| 87 | 119 | /** |
| @@ -104,17 +136,25 @@ export class ToolManager { | ||
| 104 | 136 | |
| 105 | 137 | /** |
| 106 | 138 | * Registers a new tool with the tool registry. |
| 107 | 139 | * @param {stringobject} nametool The name oftool theto toolregister. |
| 108 | 140 | * @param {string} descriptiontool.name AThe descriptionname of what the tool does. |
| 109 | 141 | * @param {objectstring} parameterstool.displayName A JSON schema foruser-friendly thedisplay parametersname thatfor the tool accepts. |
| 110 | 142 | * @param {functionstring} actiontool.description A function that will bedescription calledof whenwhat the tool is executeddoes. |
| 143 | + * @param {object} tool.parameters A JSON schema for the parameters that the tool accepts. | |
| 144 | + * @param {function} tool.action A function that will be called when the tool is executed. | |
| 145 | + * @param {function} tool.formatMessage A function that will be called to format the tool call toast. | |
| 111 | 146 | */ |
| 112 | 147 | static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage }) { |
| 148 | + // Convert WIP arguments | |
| 149 | + if (typeof arguments[0] !== 'object') { | |
| 150 | + [name, description, parameters, action] = arguments; | |
| 151 | + } | |
| 152 | + | |
| 113 | 153 | if (this.#tools.has(name)) { |
| 114 | 154 | console.warn(`A tool with the name "${name}" has already been registered. The definition will be overwritten.`); |
| 115 | 155 | } |
| 116 | 156 | |
| 117 | 157 | const definition = new ToolDefinition(name, displayName, description, parameters, action, formatMessage); |
| 118 | 158 | this.#tools.set(name, definition); |
| 119 | 159 | console.log('[ToolManager] Registered function tool:', definition); |
| 120 | 160 | } |
| @@ -161,6 +201,35 @@ export class ToolManager { | ||
| 161 | 201 | } |
| 162 | 202 | } |
| 163 | 203 | |
| 204 | + static formatToolCallMessage(name, parameters) { | |
| 205 | + if (!this.#tools.has(name)) { | |
| 206 | + return `Invoked unknown tool: ${name}`; | |
| 207 | + } | |
| 208 | + | |
| 209 | + try { | |
| 210 | + const tool = this.#tools.get(name); | |
| 211 | + const formatParameters = typeof parameters === 'string' ? JSON.parse(parameters) : parameters; | |
| 212 | + return tool.formatMessage(formatParameters); | |
| 213 | + } catch (error) { | |
| 214 | + console.error(`An error occurred while formatting the tool call message for "${name}":`, error); | |
| 215 | + return `Invoking tool: ${name}`; | |
| 216 | + } | |
| 217 | + } | |
| 218 | + | |
| 219 | + /** | |
| 220 | + * Gets the display name of a tool by name. | |
| 221 | + * @param {string} name | |
| 222 | + * @returns {string} The display name of the tool. | |
| 223 | + */ | |
| 224 | + static getDisplayName(name) { | |
| 225 | + if (!this.#tools.has(name)) { | |
| 226 | + return name; | |
| 227 | + } | |
| 228 | + | |
| 229 | + const tool = this.#tools.get(name); | |
| 230 | + return tool.displayName || name; | |
| 231 | + } | |
| 232 | + | |
| 164 | 233 | /** |
| 165 | 234 | * Register function tools for the next chat completion request. |
| 166 | 235 | * @param {object} data Generation data |
| @@ -352,9 +421,11 @@ export class ToolManager { | ||
| 352 | 421 | const id = toolCall.id; |
| 353 | 422 | const parameters = toolCall.function.arguments; |
| 354 | 423 | const name = toolCall.function.name; |
| 424 | + const displayName = ToolManager.getDisplayName(name); | |
| 355 | 425 | result.hadToolCalls = true; |
| 356 | 426 | |
| 357 | 427 | const toastmessage = toastrToolManager.infoformatToolCallMessage(`Invoking function tool: ${name}`, parameters); |
| 428 | + const toast = message && toastr.info(message, 'Tool Calling', { timeOut: 0 }); | |
| 358 | 429 | const toolResult = await ToolManager.invokeFunctionTool(name, parameters); |
| 359 | 430 | toastr.clear(toast); |
| 360 | 431 | console.log('Function tool result:', result); |
| @@ -365,7 +436,14 @@ export class ToolManager { | ||
| 365 | 436 | continue; |
| 366 | 437 | } |
| 367 | 438 | |
| 368 | - result.invocations.push({ id, name, parameters, result: toolResult }); | |
| 439 | + const invocation = { | |
| 440 | + id, | |
| 441 | + displayName, | |
| 442 | + name, | |
| 443 | + parameters, | |
| 444 | + result: toolResult, | |
| 445 | + }; | |
| 446 | + result.invocations.push(invocation); | |
| 369 | 447 | } |
| 370 | 448 | } |
| 371 | 449 | |
| @@ -414,8 +492,8 @@ export class ToolManager { | ||
| 414 | 492 | codeElement.classList.add('language-json'); |
| 415 | 493 | data.forEach(i => i.parameters = tryParse(i.parameters)); |
| 416 | 494 | codeElement.textContent = JSON.stringify(data, null, 2); |
| 417 | 495 | const toolNames = data.map(i => i.displayName || i.name).join(', '); |
| 418 | 496 | summaryElement.textContent = `Performed toolTool calls: ${toolNames}`; |
| 419 | 497 | preElement.append(codeElement); |
| 420 | 498 | detailsElement.append(summaryElement, preElement); |
| 421 | 499 | return detailsElement.outerHTML; |