execute method

Future<ToolResult> execute(
  1. ToolCall toolCall
)

Execute a tool call manually. Used when autoExecute: false is passed to generateWithTools.

Mirrors Swift RunAnywhere.executeTool(_:) semantics (RunAnywhere+ToolCalling.swift:158-203): unknown tools, argument parse failures, and executor errors all surface as success: false results — a parse failure must NOT silently execute the tool with empty arguments, which would make bad model output look like a successful empty-argument call.

Implementation

Future<ToolResult> execute(ToolCall toolCall) async {
  final executor = _toolExecutors[toolCall.name];
  if (executor == null) {
    return ToolResult(
      toolCallId: toolCall.id,
      name: toolCall.name,
      success: false,
      error: 'Tool not found: ${toolCall.name}',
    );
  }

  Map<String, dynamic> args = const {};
  if (toolCall.argumentsJson.isNotEmpty) {
    try {
      final decoded = jsonDecode(toolCall.argumentsJson);
      if (decoded is Map<String, dynamic>) {
        args = decoded;
      } else {
        return ToolResult(
          toolCallId: toolCall.id,
          name: toolCall.name,
          success: false,
          error:
              'Failed to parse tool arguments: expected a JSON object, '
              'got ${decoded.runtimeType}',
        );
      }
    } catch (e) {
      return ToolResult(
        toolCallId: toolCall.id,
        name: toolCall.name,
        success: false,
        error: 'Failed to parse tool arguments: $e',
      );
    }
  }

  try {
    _logger.debug('Executing tool: ${toolCall.name}');
    final result = await executor(args);
    _logger.debug('Tool ${toolCall.name} completed successfully');
    return ToolResult(
      toolCallId: toolCall.id,
      name: toolCall.name,
      success: true,
      resultJson: jsonEncode(result),
    );
  } catch (e) {
    _logger.error('Tool ${toolCall.name} failed: $e');
    return ToolResult(
      toolCallId: toolCall.id,
      name: toolCall.name,
      success: false,
      error: e.toString(),
    );
  }
}