Class: RubynCode::Tools::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/rubyn_code/tools/base.rb

Constant Summary collapse

TOOL_NAME =
''
DESCRIPTION =
''
PARAMETERS =
{}.freeze
RISK_LEVEL =
:read
REQUIRES_CONFIRMATION =
false

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(project_root:) ⇒ Base

Returns a new instance of Base.



57
58
59
# File 'lib/rubyn_code/tools/base.rb', line 57

def initialize(project_root:)
  @project_root = File.expand_path(project_root)
end

Instance Attribute Details

#project_rootObject (readonly)

Returns the value of attribute project_root.



55
56
57
# File 'lib/rubyn_code/tools/base.rb', line 55

def project_root
  @project_root
end

Class Method Details

.descriptionObject



17
18
19
# File 'lib/rubyn_code/tools/base.rb', line 17

def description
  const_get(:DESCRIPTION)
end

.parametersObject



21
22
23
# File 'lib/rubyn_code/tools/base.rb', line 21

def parameters
  const_get(:PARAMETERS)
end

.requires_confirmation?Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/rubyn_code/tools/base.rb', line 29

def requires_confirmation?
  const_get(:REQUIRES_CONFIRMATION)
end

.risk_levelObject



25
26
27
# File 'lib/rubyn_code/tools/base.rb', line 25

def risk_level
  const_get(:RISK_LEVEL)
end

.summarize(_output, _args) ⇒ String

One-line summary of a successful invocation, shown in the IDE’s chat card. Default is empty so the UI renders a clean “Done” indicator. Override in subclasses that have a useful one-liner (e.g. “Edited app.rb (1 replacement)”). The full output still goes to the conversation untouched — this only affects the UI.

Parameters:

  • output (String)

    what execute(**) returned

  • args (Hash)

    the tool arguments (string-keyed)

Returns:

  • (String)


50
51
52
# File 'lib/rubyn_code/tools/base.rb', line 50

def summarize(_output, _args)
  ''
end

.to_schemaObject



33
34
35
36
37
38
39
# File 'lib/rubyn_code/tools/base.rb', line 33

def to_schema
  {
    name: tool_name,
    description: description,
    input_schema: Schema.build(parameters)
  }
end

.tool_nameObject



13
14
15
# File 'lib/rubyn_code/tools/base.rb', line 13

def tool_name
  const_get(:TOOL_NAME)
end

Instance Method Details

#execute(**params) ⇒ Object

Raises:

  • (NotImplementedError)


61
62
63
# File 'lib/rubyn_code/tools/base.rb', line 61

def execute(**params)
  raise NotImplementedError, "#{self.class}#execute must be implemented"
end

#safe_path(path) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/rubyn_code/tools/base.rb', line 65

def safe_path(path)
  expanded = if Pathname.new(path).absolute?
               File.expand_path(path)
             else
               File.expand_path(path, project_root)
             end

  unless expanded.start_with?(project_root)
    raise PermissionDeniedError,
          "Path traversal denied: #{path} resolves outside project root"
  end

  expanded
end

#truncate(output, max: 10_000) ⇒ Object



80
81
82
83
84
85
86
# File 'lib/rubyn_code/tools/base.rb', line 80

def truncate(output, max: 10_000)
  return output if output.nil? || output.length <= max

  half = max / 2
  middle = "\n\n... [truncated #{output.length - max} characters] ...\n\n"
  "#{output[0, half]}#{middle}#{output[-half, half]}"
end