Class: Rubino::Tools::GrepTool

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

Overview

Tool for searching file contents using regex patterns. Backed by ripgrep (rg) if available, falls back to Ruby grep.

Instance Attribute Summary

Attributes inherited from Base

#cancel_token, #read_tracker, #stream_chunk

Instance Method Summary collapse

Methods inherited from Base

#cancellation_requested?, #config_key, #emit_chunk, #risky?, #to_tool_definition, workspace_root, workspace_roots

Instance Method Details

#call(arguments) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/rubino/tools/grep_tool.rb', line 59

def call(arguments)
  pattern = arguments["pattern"] || arguments[:pattern]
  path = arguments["path"] || arguments[:path] || "."
  include_pattern = arguments["include"] || arguments[:include]
  max_results = arguments["max_results"] || arguments[:max_results] || 50

  # -A/-B/-C semantics, mirroring ripgrep: `context` (-C) overrides
  # both halves; otherwise each side defaults to 0. Clamp at 50 lines
  # per side so a runaway model can't ask for 10_000 lines of context
  # per match and overrun the output budget.
  ctx     = arguments["context"] || arguments[:context]
  before  = (ctx || arguments["before"] || arguments[:before] || 0).to_i.clamp(0, 50)
  after   = (ctx || arguments["after"]  || arguments[:after]  || 0).to_i.clamp(0, 50)

  expanded_path = File.expand_path(path)
  return "Error: Path not found: #{path}" unless File.exist?(expanded_path)

  if ripgrep_available?
    search_with_ripgrep(pattern, expanded_path, include_pattern, max_results, before, after)
  else
    search_with_ruby(pattern, expanded_path, include_pattern, max_results, before, after)
  end
end

#descriptionObject



12
13
14
15
16
# File 'lib/rubino/tools/grep_tool.rb', line 12

def description
  "Search file contents using regular expressions. " \
    "Returns matching file paths and line numbers. " \
    "Supports include patterns to filter by file type."
end

#input_schemaObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/rubino/tools/grep_tool.rb', line 18

def input_schema
  {
    type: "object",
    properties: {
      pattern: {
        type: "string",
        description: "The regex pattern to search for"
      },
      path: {
        type: "string",
        description: "Directory to search in (defaults to current directory)"
      },
      include: {
        type: "string",
        description: "File pattern to include (e.g., '*.rb', '*.{ts,tsx}')"
      },
      max_results: {
        type: "integer",
        description: "Maximum number of results to return (default: 50)"
      },
      before: {
        type: "integer",
        description: "Lines of leading context to include before each match (-B). Default 0."
      },
      after: {
        type: "integer",
        description: "Lines of trailing context to include after each match (-A). Default 0."
      },
      context: {
        type: "integer",
        description: "Symmetric context (-C): sets both before and after. Wins over before/after when given."
      }
    },
    required: %w[pattern]
  }
end

#nameObject



8
9
10
# File 'lib/rubino/tools/grep_tool.rb', line 8

def name
  "grep"
end

#risk_levelObject



55
56
57
# File 'lib/rubino/tools/grep_tool.rb', line 55

def risk_level
  :low
end