Class: OllamaAgent::Tools::FilesystemExplorer

Inherits:
Base
  • Object
show all
Defined in:
lib/ollama_agent/tools/filesystem_explorer.rb

Overview

Safe filesystem inspection tool.

Lists files and subdirectories inside the current workspace. All path arguments are resolved relative to the project root and rejected if they escape it, preventing directory traversal attacks.

Constant Summary

Constants inherited from Base

Base::RISK_LEVELS

Instance Attribute Summary

Attributes inherited from Base

#description, #input_schema, #name, #output_schema, #requires_approval, #risk_level

Instance Method Summary collapse

Methods inherited from Base

#initialize, #to_anthropic_schema, #to_ollama_schema, #to_s, tool_description, tool_name, tool_output_schema, tool_requires_approval, tool_risk, tool_schema

Constructor Details

This class inherits a constructor from OllamaAgent::Tools::Base

Instance Method Details

#call(args, context: {}) ⇒ Object



30
31
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
58
59
60
61
62
63
# File 'lib/ollama_agent/tools/filesystem_explorer.rb', line 30

def call(args, context: {})
  root     = context[:root] || ENV.fetch("OLLAMA_AGENT_ROOT", Dir.pwd)
  base_dir = File.expand_path(root)
  path     = args["path"].to_s
  path     = "." if path.strip.empty?

  requested = File.expand_path(path, base_dir)

  return access_denied(path, base_dir) unless allowed_path?(base_dir, requested)
  return "Error: Path #{path.inspect} does not exist." unless File.exist?(requested)
  return "Error: Path #{path.inspect} is not a directory." unless File.directory?(requested)

  entries = Dir.children(requested).sort
  return "The directory #{path.inspect} is empty." if entries.empty?

  lines = ["Contents of #{path.inspect} (#{entries.size} item(s)):"]
  entries.each do |name|
    full = File.join(requested, name)
    if File.directory?(full)
      lines << "  [DIR]  #{name}/"
    else
      size = begin
        File.size(full)
      rescue StandardError
        nil
      end
      lines << (size ? "  [FILE] #{name} (#{size} bytes)" : "  [FILE] #{name}")
    end
  end

  lines.join("\n")
rescue StandardError => e
  "Error: #{e.message}"
end