Merge branch 'tool-calling' of https://github.com/SillyTavern/SillyTavern into tool-calling
| @@ -8180,6 +8180,8 @@ window['SillyTavern'].getContext = function () { | |||
| 8180 | unregisterMacro: MacrosParser.unregisterMacro.bind(MacrosParser), | 8180 | unregisterMacro: MacrosParser.unregisterMacro.bind(MacrosParser), |
| 8181 | registerFunctionTool: ToolManager.registerFunctionTool.bind(ToolManager), | 8181 | registerFunctionTool: ToolManager.registerFunctionTool.bind(ToolManager), |
| 8182 | unregisterFunctionTool: ToolManager.unregisterFunctionTool.bind(ToolManager), | 8182 | unregisterFunctionTool: ToolManager.unregisterFunctionTool.bind(ToolManager), |
| 8183 | isToolCallingSupported: ToolManager.isToolCallingSupported.bind(ToolManager), | ||
| 8184 | canPerformToolCalls: ToolManager.canPerformToolCalls.bind(ToolManager), | ||
| 8183 | registerDebugFunction: registerDebugFunction, | 8185 | registerDebugFunction: registerDebugFunction, |
| 8184 | /** @deprecated Use renderExtensionTemplateAsync instead. */ | 8186 | /** @deprecated Use renderExtensionTemplateAsync instead. */ |
| 8185 | renderExtensionTemplate: renderExtensionTemplate, | 8187 | renderExtensionTemplate: renderExtensionTemplate, |
| @@ -19,6 +19,16 @@ import { Popup } from './popup.js'; | |||
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | /** | 21 | /** |
| 22 | * @typedef {object} ToolRegistration | ||
| 23 | * @property {string} name - The name of the tool. | ||
| 24 | * @property {string} displayName - The display name of the tool. | ||
| 25 | * @property {string} description - A description of the tool. | ||
| 26 | * @property {object} parameters - The parameters for the tool. | ||
| 27 | * @property {function} action - The action to perform when the tool is invoked. | ||
| 28 | * @property {function} formatMessage - A function to format the tool call message. | ||
| 29 | */ | ||
| 30 | |||
| 31 | /** | ||
| 22 | * A class that represents a tool definition. | 32 | * A class that represents a tool definition. |
| 23 | */ | 33 | */ |
| 24 | class ToolDefinition { | 34 | class ToolDefinition { |
| @@ -136,13 +146,7 @@ export class ToolManager { | |||
| 136 | 146 | ||
| 137 | /** | 147 | /** |
| 138 | * Registers a new tool with the tool registry. | 148 | * Registers a new tool with the tool registry. |
| 139 | * @param {object} tool The tool to register. | 149 | * @param {ToolRegistration} tool The tool to register. |
| 140 | * @param {string} tool.name The name of the tool. | ||
| 141 | * @param {string} tool.displayName A user-friendly display name for the tool. | ||
| 142 | * @param {string} tool.description A description of what the tool does. | ||
| 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. | ||
| 146 | */ | 150 | */ |
| 147 | static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage }) { | 151 | static registerFunctionTool({ name, displayName, description, parameters, action, formatMessage }) { |
| 148 | // Convert WIP arguments | 152 | // Convert WIP arguments |
| @@ -201,6 +205,12 @@ export class ToolManager { | |||
| 201 | } | 205 | } |
| 202 | } | 206 | } |
| 203 | 207 | ||
| 208 | /** | ||
| 209 | * Formats a message for a tool call by name. | ||
| 210 | * @param {string} name The name of the tool to format the message for. | ||
| 211 | * @param {object} parameters Function tool call parameters. | ||
| 212 | * @returns {string} The formatted message for the tool call. | ||
| 213 | */ | ||
| 204 | static formatToolCallMessage(name, parameters) { | 214 | static formatToolCallMessage(name, parameters) { |
| 205 | if (!this.#tools.has(name)) { | 215 | if (!this.#tools.has(name)) { |
| 206 | return `Invoked unknown tool: ${name}`; | 216 | return `Invoked unknown tool: ${name}`; |
| @@ -312,9 +322,14 @@ export class ToolManager { | |||
| 312 | } | 322 | } |
| 313 | } | 323 | } |
| 314 | 324 | ||
| 325 | /** | ||
| 326 | * Apply a tool call delta to a target object. | ||
| 327 | * @param {object} target The target object to apply the delta to | ||
| 328 | * @param {object} delta The delta object to apply | ||
| 329 | */ | ||
| 315 | static #applyToolCallDelta(target, delta) { | 330 | static #applyToolCallDelta(target, delta) { |
| 316 | for (const key in delta) { | 331 | for (const key in delta) { |
| 317 | if (!delta.hasOwnProperty(key)) continue; | 332 | if (!Object.prototype.hasOwnProperty.call(delta, key)) continue; |
| 318 | if (key === '__proto__' || key === 'constructor') continue; | 333 | if (key === '__proto__' || key === 'constructor') continue; |
| 319 | 334 | ||
| 320 | const deltaValue = delta[key]; | 335 | const deltaValue = delta[key]; |
| @@ -426,13 +441,6 @@ export class ToolManager { | |||
| 426 | errors: [], | 441 | errors: [], |
| 427 | }; | 442 | }; |
| 428 | const toolCalls = ToolManager.#getToolCallsFromData(data); | 443 | const toolCalls = ToolManager.#getToolCallsFromData(data); |
| 429 | const oaiCompatibleSources = [ | ||
| 430 | chat_completion_sources.OPENAI, | ||
| 431 | chat_completion_sources.CUSTOM, | ||
| 432 | chat_completion_sources.MISTRALAI, | ||
| 433 | chat_completion_sources.OPENROUTER, | ||
| 434 | chat_completion_sources.GROQ, | ||
| 435 | ]; | ||
| 436 | 444 | ||
| 437 | if (!Array.isArray(toolCalls)) { | 445 | if (!Array.isArray(toolCalls)) { |
| 438 | return result; | 446 | return result; |
| @@ -480,7 +488,7 @@ export class ToolManager { | |||
| 480 | * @param {ToolInvocation[]} invocations Tool invocations. | 488 | * @param {ToolInvocation[]} invocations Tool invocations. |
| 481 | * @returns {string} Formatted message with tool invocations. | 489 | * @returns {string} Formatted message with tool invocations. |
| 482 | */ | 490 | */ |
| 483 | static #formatMessage(invocations) { | 491 | static #formatToolInvocationMessage(invocations) { |
| 484 | const tryParse = (x) => { try { return JSON.parse(x); } catch { return x; } }; | 492 | const tryParse = (x) => { try { return JSON.parse(x); } catch { return x; } }; |
| 485 | const data = structuredClone(invocations); | 493 | const data = structuredClone(invocations); |
| 486 | const detailsElement = document.createElement('details'); | 494 | const detailsElement = document.createElement('details'); |
| @@ -510,7 +518,7 @@ export class ToolManager { | |||
| 510 | force_avatar: system_avatar, | 518 | force_avatar: system_avatar, |
| 511 | is_system: true, | 519 | is_system: true, |
| 512 | is_user: false, | 520 | is_user: false, |
| 513 | mes: ToolManager.#formatMessage(invocations), | 521 | mes: ToolManager.#formatToolInvocationMessage(invocations), |
| 514 | extra: { | 522 | extra: { |
| 515 | isSmallSys: true, | 523 | isSmallSys: true, |
| 516 | tool_invocations: invocations, | 524 | tool_invocations: invocations, |