Class: RubyLLM::Toolbox::Tools::Glob

Inherits:
Base
  • Object
show all
Defined in:
lib/ruby_llm/toolbox/tools/glob.rb

Overview

SAFE. Finds files matching a glob pattern within fs_root and returns their paths relative to the glob base. Each hit is re-checked through the path jail so a symlinked match that points outside the root is dropped.

Constant Summary collapse

MAX_RESULTS =
1_000

Instance Attribute Summary

Attributes inherited from Base

#config

Instance Method Summary collapse

Methods inherited from Base

#call, exec_tool!, exec_tool?, #initialize, #name

Constructor Details

This class inherits a constructor from RubyLLM::Toolbox::Base

Instance Method Details

#execute(pattern:, base: ".") ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/ruby_llm/toolbox/tools/glob.rb', line 28

def execute(pattern:, base: ".")
  return error("pattern must be provided", code: :bad_pattern) if pattern.to_s.empty?
  return error("pattern may not contain '..'", code: :bad_pattern) if pattern.include?("..")

  jail = Safety::PathJail.new(config.fs_root)
  root = jail.resolve(base)
  return error("not a directory: #{base}", code: :not_a_directory) unless File.directory?(root)

  base_pn = Pathname.new(root)
  results = Dir.glob(File.join(root, pattern), File::FNM_PATHNAME).sort.filter_map do |match|
    in_jail?(jail, match) ? Pathname.new(match).relative_path_from(base_pn).to_s : nil
  end

  capped = results.first(MAX_RESULTS)
  body = +"#{results.size} match#{results.size == 1 ? '' : 'es'}"
  body << " (showing first #{MAX_RESULTS})" if results.size > MAX_RESULTS
  body << " for #{pattern}:\n"
  capped.each { |rel| body << rel << "\n" }
  truncate(body)
rescue Safety::PathJail::Jailbreak => e
  error(e.message, code: :path_denied)
end