Class: Rubino::Tools::CustomToolLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/rubino/tools/custom_tool_loader.rb

Overview

Loads user-defined tools from .rubino/tools/ directories. Users can define tools using a simple Ruby DSL.

Example tool file (.rubino/tools/my_tool.rb):

Rubino.define_tool do
  name "my_custom_tool"
  description "Does something custom"
  input_schema type: "object", properties: { input: { type: "string" } }
  risk_level :low

  execute do |args|
    "Result: #{args['input']}"
  end
end

Constant Summary collapse

TOOL_GLOB =
"*.rb"

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(paths: nil) ⇒ CustomToolLoader

Returns a new instance of CustomToolLoader.



35
36
37
# File 'lib/rubino/tools/custom_tool_loader.rb', line 35

def initialize(paths: nil)
  @paths = paths || self.class.tool_paths
end

Class Method Details

.tool_pathsObject

HOME-only by design (#44). This loader ‘load`s arbitrary Ruby, so it must NEVER read from a project’s cwd ‘.rubino/tools` — that would let any directory you start rubino in execute code with zero prompt, the exact foot-gun the folder-trust model exists to prevent. The only allowed source is the user’s own config dir under RUBINO_HOME, which is not attacker-controllable by cd-ing into a repo. (Previously the path list led with the cwd ‘.rubino/tools`; that entry is removed.)



31
32
33
# File 'lib/rubino/tools/custom_tool_loader.rb', line 31

def self.tool_paths
  [File.join(Rubino.home_path, "tools")]
end

Instance Method Details

#load_all!Object

Loads all custom tools and registers them



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/rubino/tools/custom_tool_loader.rb', line 40

def load_all!
  loaded = 0

  @paths.each do |dir|
    expanded = File.expand_path(dir)
    next unless File.directory?(expanded)

    Dir.glob(File.join(expanded, TOOL_GLOB)).each do |path|
      load_tool_file(path)
      loaded += 1
    rescue StandardError => e
      Rubino.ui.warning("Failed to load tool #{path}: #{e.message}")
    end
  end

  loaded
end