Class: SharedTools::Tools::Eval::RubyEvalTool

Inherits:
RubyLLM::Tool
  • Object
show all
Defined in:
lib/shared_tools/tools/eval/ruby_eval_tool.rb

Overview

Examples:

tool = SharedTools::Tools::Eval::RubyEvalTool.new
tool.execute(code: "puts 'Hello'; 2 + 2")

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(logger: nil) ⇒ RubyEvalTool

Returns a new instance of RubyEvalTool.

Parameters:

  • (defaults to: nil)

    optional logger



28
29
30
# File 'lib/shared_tools/tools/eval/ruby_eval_tool.rb', line 28

def initialize(logger: nil)
  @logger = logger || RubyLLM.logger
end

Class Method Details

.nameObject



12
# File 'lib/shared_tools/tools/eval/ruby_eval_tool.rb', line 12

def self.name = 'eval_ruby'

Instance Method Details

#execute(code:) ⇒ Hash

Returns execution result.

Parameters:

  • Ruby code to execute

Returns:

  • execution result



35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/shared_tools/tools/eval/ruby_eval_tool.rb', line 35

def execute(code:)
  @logger.info("Requesting permission to execute Ruby code")

  if code.strip.empty?
    error_msg = "Ruby code cannot be empty"
    @logger.error(error_msg)
    return { error: error_msg }
  end

  # Show user the code and ask for confirmation
  allowed = SharedTools.execute?(tool: self.class.to_s, stuff: code)

  unless allowed
    @logger.warn("User declined to execute the Ruby code")
    return { error: "User declined to execute the Ruby code" }
  end

  @logger.info("Executing Ruby code")

  # Capture both stdout and the result of evaluation
  original_stdout = $stdout
  captured_output = StringIO.new
  $stdout = captured_output

  begin
    result = eval(code)
    output = captured_output.string

    @logger.debug("Ruby code execution completed successfully")

    response = {
      result: result,
      output: output.empty? ? nil : output,
      success: true
    }

    # Include both result and output in a readable format
    if output.empty?
      response[:display] = result.inspect
    else
      response[:display] = output + (result.nil? ? "" : "\n=> #{result.inspect}")
    end

    response
  rescue SyntaxError, StandardError => e
    @logger.error("Ruby code execution failed: #{e.message}")
    {
      error: e.message,
      backtrace: e.backtrace&.first(5),
      success: false
    }
  ensure
    $stdout = original_stdout
  end
end