fix: return Error objects from invokeFunctionTool and create error invocations (#5351) * fix: return Error objects from invokeFunctionTool and create error invocations invokeFunctionTool previously called .toString() on caught errors, converting them to plain strings. This made the instanceof Error check in invokeFunctionTools dead code. Changes: - Return Error objects directly from invokeFunctionTool - Create error invocations with error: true flag when tools fail - Record failed stealth tools in stealthCalls - Preserve signature/reasoning on error invocations - Add error field to ToolInvocation typedef * fix: use Error.toString to avoid behavioral changes --------- Co-authored-by: Cohee <18619528+Cohee1207@users.noreply.github.com>

b89293418d085f0e1522892dd65a9ca7da218177

Xiangzhe <32761048+xz-dev@users.noreply.github.com>

Signed
1 files changed, +20 -4Showing whitespace changes
public/scripts/tool-calling.js+20 -4
@@ -21,11 +21,12 @@ import { isTrueBoolean } from './utils.js';
21 * @property {string} result - The result of the tool invocation.21 * @property {string} result - The result of the tool invocation.
22 * @property {string?} signature - The thought signature associated with the tool invocation.22 * @property {string?} signature - The thought signature associated with the tool invocation.
23 * @property {string?} reasoning - The plaintext reasoning associated with this tool call turn.23 * @property {string?} reasoning - The plaintext reasoning associated with this tool call turn.
24 * @property {boolean} [error] - Whether the tool invocation failed.
24 */25 */
2526
26/**27/**
27 * @typedef {object} ToolInvocationResult28 * @typedef {object} ToolInvocationResult
28 * @property {ToolInvocation[]} invocations Successful tool invocations29 * @property {ToolInvocation[]} invocations Tool invocations (both successful and failed)
29 * @property {Error[]} errors Errors that occurred during tool invocation30 * @property {Error[]} errors Errors that occurred during tool invocation
30 * @property {string[]} stealthCalls Names of stealth tools that were invoked31 * @property {string[]} stealthCalls Names of stealth tools that were invoked
31 */32 */
@@ -336,10 +337,10 @@ export class ToolManager {
336337
337 if (error instanceof Error) {338 if (error instanceof Error) {
338 error.cause = name;339 error.cause = name;
339 return error.toString();340 return error;
340 }341 }
341342
342 return new Error('Unknown error occurred while invoking the tool.', { cause: name }).toString();343 return new Error('Unknown error occurred while invoking the tool.', { cause: name });
343 }344 }
344 }345 }
345346
@@ -796,9 +797,23 @@ export class ToolManager {
796 toastr.clear(toast);797 toastr.clear(toast);
797 console.log('[ToolManager] Function tool result:', result);798 console.log('[ToolManager] Function tool result:', result);
798799
799 // Save a successful invocation800 // Handle tool errors — still create an invocation so the LLM sees the failure
800 if (toolResult instanceof Error) {801 if (toolResult instanceof Error) {
801 result.errors.push(toolResult);802 result.errors.push(toolResult);
803 if (isStealth) {
804 result.stealthCalls.push(name);
805 } else {
806 result.invocations.push({
807 id,
808 displayName,
809 name,
810 parameters: stringify(parameters),
811 result: toolResult.toString(),
812 error: true,
813 signature: toolCall.signature || null,
814 reasoning: reasoningText || null,
815 });
816 }
802 continue;817 continue;
803 }818 }
804819
@@ -814,6 +829,7 @@ export class ToolManager {
814 name,829 name,
815 parameters: stringify(parameters),830 parameters: stringify(parameters),
816 result: toolResult,831 result: toolResult,
832 error: false,
817 signature: toolCall.signature || null,833 signature: toolCall.signature || null,
818 reasoning: reasoningText || null,834 reasoning: reasoningText || null,
819 };835 };