Class: SharedTools::Tools::SearchCodebaseTool

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

Overview

Search for a term across files using ripgrep (rg) with grep as fallback. Read-only — no authorization prompt required.

Examples:

tool = SharedTools::Tools::SearchCodebaseTool.new
tool.execute(term: "def execute")
tool.execute(term: "RubyLLM", extension: "rb", max_results: 20)

Constant Summary collapse

MAX_RESULTS_CAP =
500

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(logger: nil) ⇒ SearchCodebaseTool

Returns a new instance of SearchCodebaseTool.



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

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

Class Method Details

.nameObject



17
# File 'lib/shared_tools/tools/search_codebase_tool.rb', line 17

def self.name = 'search_codebase'

Instance Method Details

#execute(term:, path: ".", extension: nil, max_results: 50) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/shared_tools/tools/search_codebase_tool.rb', line 32

def execute(term:, path: ".", extension: nil, max_results: 50)
  @logger.info("SearchCodebaseTool#execute term=#{term.inspect} path=#{path} extension=#{extension.inspect}")

  return { error: "Search term cannot be empty" } if term.strip.empty?

  max_results = [[max_results.to_i, 1].max, MAX_RESULTS_CAP].min
  search_path = File.expand_path(path)

  return { error: "Path not found: #{path}" } unless File.exist?(search_path)

  stdout, _stderr, _status = run_search(term: term, path: search_path, extension: extension)

  all_lines  = stdout.lines.map(&:chomp).reject(&:empty?)
  matches    = all_lines.first(max_results)
  truncated  = all_lines.size > max_results

  {
    matches:   matches,
    count:     matches.size,
    truncated: truncated,
    tool:      ripgrep_available? ? "rg" : "grep"
  }
rescue => e
  @logger.error("SearchCodebaseTool error: #{e.message}")
  { error: e.message }
end