mirror of
https://github.com/SillyTavern/SillyTavern.git
synced 2025-06-05 21:59:27 +02:00
Show an error when all tools fail
This commit is contained in:
@@ -4420,10 +4420,18 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
|
|||||||
const lastMessage = chat[chat.length - 1];
|
const lastMessage = chat[chat.length - 1];
|
||||||
const shouldDeleteMessage = ['', '...'].includes(lastMessage?.mes) && ['', '...'].includes(streamingProcessor.result);
|
const shouldDeleteMessage = ['', '...'].includes(lastMessage?.mes) && ['', '...'].includes(streamingProcessor.result);
|
||||||
shouldDeleteMessage && await deleteLastMessage();
|
shouldDeleteMessage && await deleteLastMessage();
|
||||||
const invocations = await ToolManager.invokeFunctionTools(streamingProcessor.toolCalls);
|
const invocationResult = await ToolManager.invokeFunctionTools(streamingProcessor.toolCalls);
|
||||||
if (Array.isArray(invocations) && invocations.length) {
|
if (invocationResult.hadToolCalls) {
|
||||||
|
if (!invocationResult.invocations.length && shouldDeleteMessage) {
|
||||||
|
ToolManager.showToolCallError(invocationResult.errors);
|
||||||
|
unblockGeneration(type);
|
||||||
|
generatedPromptCache = '';
|
||||||
|
streamingProcessor = null;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
streamingProcessor = null;
|
streamingProcessor = null;
|
||||||
ToolManager.saveFunctionToolInvocations(invocations);
|
ToolManager.saveFunctionToolInvocations(invocationResult.invocations);
|
||||||
return Generate(type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName }, dryRun);
|
return Generate(type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName }, dryRun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4505,9 +4513,16 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro
|
|||||||
if (canPerformToolCalls) {
|
if (canPerformToolCalls) {
|
||||||
const shouldDeleteMessage = ['', '...'].includes(getMessage);
|
const shouldDeleteMessage = ['', '...'].includes(getMessage);
|
||||||
shouldDeleteMessage && await deleteLastMessage();
|
shouldDeleteMessage && await deleteLastMessage();
|
||||||
const invocations = await ToolManager.invokeFunctionTools(data);
|
const invocationResult = await ToolManager.invokeFunctionTools(data);
|
||||||
if (Array.isArray(invocations) && invocations.length) {
|
if (invocationResult.hadToolCalls) {
|
||||||
ToolManager.saveFunctionToolInvocations(invocations);
|
if (!invocationResult.invocations.length && shouldDeleteMessage) {
|
||||||
|
ToolManager.showToolCallError(invocationResult.errors);
|
||||||
|
unblockGeneration(type);
|
||||||
|
generatedPromptCache = '';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolManager.saveFunctionToolInvocations(invocationResult.invocations);
|
||||||
return Generate(type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName }, dryRun);
|
return Generate(type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName }, dryRun);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import { addOneMessage, chat, main_api, system_avatar, systemUserName } from '../script.js';
|
import { addOneMessage, chat, main_api, system_avatar, systemUserName } from '../script.js';
|
||||||
import { chat_completion_sources, oai_settings } from './openai.js';
|
import { chat_completion_sources, oai_settings } from './openai.js';
|
||||||
|
import { Popup } from './popup.js';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @typedef {object} ToolInvocation
|
* @typedef {object} ToolInvocation
|
||||||
@@ -9,6 +10,13 @@ import { chat_completion_sources, oai_settings } from './openai.js';
|
|||||||
* @property {string} result - The result of the tool invocation.
|
* @property {string} result - The result of the tool invocation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} ToolInvocationResult
|
||||||
|
* @property {ToolInvocation[]} invocations Successful tool invocations
|
||||||
|
* @property {boolean} hadToolCalls Whether any tool calls were found
|
||||||
|
* @property {Error[]} errors Errors that occurred during tool invocation
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that represents a tool definition.
|
* A class that represents a tool definition.
|
||||||
*/
|
*/
|
||||||
@@ -129,7 +137,7 @@ export class ToolManager {
|
|||||||
* Invokes a tool by name. Returns the result of the tool's action function.
|
* Invokes a tool by name. Returns the result of the tool's action function.
|
||||||
* @param {string} name The name of the tool to invoke.
|
* @param {string} name The name of the tool to invoke.
|
||||||
* @param {object} parameters Function parameters. For example, if the tool requires a "name" parameter, you would pass {name: "value"}.
|
* @param {object} parameters Function parameters. For example, if the tool requires a "name" parameter, you would pass {name: "value"}.
|
||||||
* @returns {Promise<string|null>} The result of the tool's action function. If an error occurs, null is returned. Non-string results are JSON-stringified.
|
* @returns {Promise<string|Error>} The result of the tool's action function. If an error occurs, null is returned. Non-string results are JSON-stringified.
|
||||||
*/
|
*/
|
||||||
static async invokeFunctionTool(name, parameters) {
|
static async invokeFunctionTool(name, parameters) {
|
||||||
try {
|
try {
|
||||||
@@ -143,7 +151,13 @@ export class ToolManager {
|
|||||||
return typeof result === 'string' ? result : JSON.stringify(result);
|
return typeof result === 'string' ? result : JSON.stringify(result);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`An error occurred while invoking the tool "${name}":`, error);
|
console.error(`An error occurred while invoking the tool "${name}":`, error);
|
||||||
return null;
|
|
||||||
|
if (error instanceof Error) {
|
||||||
|
error.cause = name;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Error('Unknown error occurred while invoking the tool.', { cause: name });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,11 +320,15 @@ export class ToolManager {
|
|||||||
/**
|
/**
|
||||||
* Check for function tool calls in the response data and invoke them.
|
* Check for function tool calls in the response data and invoke them.
|
||||||
* @param {any} data Reply data
|
* @param {any} data Reply data
|
||||||
* @returns {Promise<ToolInvocation[]>} Successful tool invocations
|
* @returns {Promise<ToolInvocationResult>} Successful tool invocations
|
||||||
*/
|
*/
|
||||||
static async invokeFunctionTools(data) {
|
static async invokeFunctionTools(data) {
|
||||||
/** @type {ToolInvocation[]} */
|
/** @type {ToolInvocationResult} */
|
||||||
const invocations = [];
|
const result = {
|
||||||
|
invocations: [],
|
||||||
|
hadToolCalls: false,
|
||||||
|
errors: [],
|
||||||
|
};
|
||||||
const toolCalls = ToolManager.#getToolCallsFromData(data);
|
const toolCalls = ToolManager.#getToolCallsFromData(data);
|
||||||
const oaiCompatibleSources = [
|
const oaiCompatibleSources = [
|
||||||
chat_completion_sources.OPENAI,
|
chat_completion_sources.OPENAI,
|
||||||
@@ -322,7 +340,7 @@ export class ToolManager {
|
|||||||
|
|
||||||
if (oaiCompatibleSources.includes(oai_settings.chat_completion_source)) {
|
if (oaiCompatibleSources.includes(oai_settings.chat_completion_source)) {
|
||||||
if (!Array.isArray(toolCalls)) {
|
if (!Array.isArray(toolCalls)) {
|
||||||
return [];
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const toolCall of toolCalls) {
|
for (const toolCall of toolCalls) {
|
||||||
@@ -334,16 +352,20 @@ export class ToolManager {
|
|||||||
const id = toolCall.id;
|
const id = toolCall.id;
|
||||||
const parameters = toolCall.function.arguments;
|
const parameters = toolCall.function.arguments;
|
||||||
const name = toolCall.function.name;
|
const name = toolCall.function.name;
|
||||||
|
result.hadToolCalls = true;
|
||||||
|
|
||||||
const toast = toastr.info(`Invoking function tool: ${name}`);
|
const toast = toastr.info(`Invoking function tool: ${name}`);
|
||||||
const result = await ToolManager.invokeFunctionTool(name, parameters);
|
const toolResult = await ToolManager.invokeFunctionTool(name, parameters);
|
||||||
toastr.clear(toast);
|
toastr.clear(toast);
|
||||||
console.log('Function tool result:', result);
|
console.log('Function tool result:', result);
|
||||||
|
|
||||||
// Save a successful invocation
|
// Save a successful invocation
|
||||||
if (result) {
|
if (toolResult instanceof Error) {
|
||||||
invocations.push({ id, name, parameters, result });
|
result.errors.push(toolResult);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.invocations.push({ id, name, parameters, result: toolResult });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,7 +396,7 @@ export class ToolManager {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
return invocations;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -418,4 +440,16 @@ export class ToolManager {
|
|||||||
chat.push(message);
|
chat.push(message);
|
||||||
addOneMessage(message);
|
addOneMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows an error message for tool calls.
|
||||||
|
* @param {Error[]} errors Errors that occurred during tool invocation
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
static showToolCallError(errors) {
|
||||||
|
toastr.error('An error occurred while invoking function tools. Click here for more details.', 'Tool Calling', {
|
||||||
|
onclick: () => Popup.show.text('Tool Calling Errors', DOMPurify.sanitize(errors.map(e => `${e.cause}: ${e.message}`).join('<br>'))),
|
||||||
|
timeOut: 5000,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -421,6 +421,7 @@ small {
|
|||||||
.mes.smallSysMes pre {
|
.mes.smallSysMes pre {
|
||||||
text-align: initial;
|
text-align: initial;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
|
margin-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mes.smallSysMes summary {
|
.mes.smallSysMes summary {
|
||||||
|
Reference in New Issue
Block a user