getName(); Log::error( 'Tool execution failed', [ 'tool' => $name, 'type' => get_class( $e ), 'error' => $e->getMessage(), ] ); // The repeat guard means the model is looping. Steering it to answer is // the difference between a partial answer and no answer at all. if ( $e instanceof ToolRunsExceededException ) { return sprintf( 'You have already called `%s` the maximum number of times this turn, and it will not run again. Answer now using the results you already have, and say plainly which part you could not confirm. Do not call it again, and do not rephrase the same request into another tool call.', $name ); } // A bad argument is the model's own mistake, so the detail goes back to // it: that is exactly what lets the retry be correct. if ( $e instanceof \TypeError || $e instanceof \ArgumentCountError || $e instanceof \InvalidArgumentException ) { return sprintf( 'The call to `%s` had invalid arguments: %s. Fix the arguments and call it once more.', $name, $e->getMessage() ); } // Anything else is an internal fault. The message can carry queries, file // paths or credentials, so it stays in the log. return sprintf( 'The tool `%s` failed for an internal reason and did not return anything. Do not retry it. Continue with the information you already have and tell the user which step did not complete.', $name ); } }