diff --git a/public/script.js b/public/script.js index 61edb8658..2e5fca74d 100644 --- a/public/script.js +++ b/public/script.js @@ -3409,9 +3409,9 @@ function removeLastMessage() { * @param {GenerateOptions} options Generation options * @param {boolean} dryRun Whether to actually generate a message or just assemble the prompt * @returns {Promise} Returns a promise that resolves when the text is done generating. - * @typedef {{automatic_trigger?: boolean, force_name2?: boolean, quiet_prompt?: string, quietToLoud?: boolean, skipWIAN?: boolean, force_chid?: number, signal?: AbortSignal, quietImage?: string, quietName?: string }} GenerateOptions + * @typedef {{automatic_trigger?: boolean, force_name2?: boolean, quiet_prompt?: string, quietToLoud?: boolean, skipWIAN?: boolean, force_chid?: number, signal?: AbortSignal, quietImage?: string, quietName?: string, depth?: number }} GenerateOptions */ -export async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName } = {}, dryRun = false) { +export async function Generate(type, { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName, depth = 0 } = {}, dryRun = false) { console.log('Generate entered'); setGenerationProgress(0); generation_started = new Date(); @@ -3631,7 +3631,7 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro // Collect messages with usable content const canUseTools = ToolManager.isToolCallingSupported(); - const canPerformToolCalls = !dryRun && ToolManager.canPerformToolCalls(type); + const canPerformToolCalls = !dryRun && ToolManager.canPerformToolCalls(type) && depth < ToolManager.RECURSE_LIMIT; let coreChat = chat.filter(x => !x.is_system || (canUseTools && Array.isArray(x.extra?.tool_invocations))); if (type === 'swipe') { coreChat.pop(); @@ -4485,8 +4485,9 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro } streamingProcessor = null; + depth = depth + 1; await ToolManager.saveFunctionToolInvocations(invocationResult.invocations); - return Generate('normal', { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName }, dryRun); + return Generate('normal', { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName, depth }, dryRun); } } @@ -4577,8 +4578,9 @@ export async function Generate(type, { automatic_trigger, force_name2, quiet_pro return; } + depth = depth + 1; await ToolManager.saveFunctionToolInvocations(invocationResult.invocations); - return Generate('normal', { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName }, dryRun); + return Generate('normal', { automatic_trigger, force_name2, quiet_prompt, quietToLoud, skipWIAN, force_chid, signal, quietImage, quietName, depth }, dryRun); } } diff --git a/public/scripts/tool-calling.js b/public/scripts/tool-calling.js index bb6342620..b56ab2db6 100644 --- a/public/scripts/tool-calling.js +++ b/public/scripts/tool-calling.js @@ -210,6 +210,12 @@ export class ToolManager { static #INPUT_DELTA_KEY = '__input_json_delta'; + /** + * The maximum number of times to recurse when parsing tool calls. + * @type {number} + */ + static RECURSE_LIMIT = 5; + /** * Returns an Array of all tools that have been registered. * @type {ToolDefinition[]}