Class: SwarmSDK::V3::Tools::Read

Inherits:
Base
  • Object
show all
Defined in:
lib/swarm_sdk/v3/tools/read.rb

Overview

Read tool for reading file contents from the filesystem

Supports reading entire files or specific line ranges with line numbers. Tracks reads per agent for enforcing read-before-write/edit rules. Supports document formats (PDF, DOCX, XLSX) if gems installed.

Constant Summary collapse

CONVERTERS =

Document converters (optional gems)

[
  DocumentConverters::PdfConverter,
  DocumentConverters::DocxConverter,
  DocumentConverters::XlsxConverter,
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#name

Constructor Details

#initialize(agent_name:, directory:, read_tracker:) ⇒ Read

Returns a new instance of Read.

Parameters:

  • agent_name (Symbol, String)

    Agent identifier for read tracking

  • directory (String)

    Agent’s working directory

  • read_tracker (ReadTracker)

    Shared read tracker for cross-tool enforcement



55
56
57
58
59
60
# File 'lib/swarm_sdk/v3/tools/read.rb', line 55

def initialize(agent_name:, directory:, read_tracker:)
  super()
  @agent_name = agent_name.to_sym
  @directory = File.expand_path(directory)
  @read_tracker = read_tracker
end

Class Method Details

.creation_requirementsArray<Symbol>

Returns Constructor requirements.

Returns:

  • (Array<Symbol>)

    Constructor requirements



21
22
23
# File 'lib/swarm_sdk/v3/tools/read.rb', line 21

def creation_requirements
  [:agent_name, :directory, :read_tracker]
end

Instance Method Details

#execute(file_path:, offset: nil, limit: nil) ⇒ String, RubyLLM::Content

Execute file read

Parameters:

  • file_path (String)

    Path to the file

  • offset (Integer, nil) (defaults to: nil)

    Starting line number (1-indexed)

  • limit (Integer, nil) (defaults to: nil)

    Number of lines to read

Returns:

  • (String, RubyLLM::Content)

    File contents or error message



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/swarm_sdk/v3/tools/read.rb', line 76

def execute(file_path:, offset: nil, limit: nil)
  return validation_error("file_path is required") if file_path.nil? || file_path.to_s.strip.empty?

  resolved_path = resolve_path(file_path)

  return validation_error("File does not exist: #{file_path}") unless File.exist?(resolved_path)
  return validation_error("Path is a directory. Use Bash with ls to list directories.") if File.directory?(resolved_path)

  # Try document converter first
  converter_class = find_converter(resolved_path)
  if converter_class
    result = converter_class.new.convert(resolved_path)

    # Register read for successful conversions
    unless result.start_with?("<system-reminder>") || result.start_with?("Error:")
      @read_tracker.register_read(@agent_name, resolved_path)
    end

    return result
  end

  # Standard text file handling
  content = read_file_content(resolved_path)

  # Binary file — return as-is
  return content if content.is_a?(RubyLLM::Content)
  return content if content.start_with?("Error:")

  @read_tracker.register_read(@agent_name, resolved_path)

  return format_empty_file if content.empty?

  format_text_content(content, file_path, offset, limit)
rescue StandardError => e
  error("Unexpected error reading file: #{e.class.name} - #{e.message}")
end

#file_read?(path) ⇒ Boolean

Check if a file has been read by this agent

Parameters:

  • path (String)

    Resolved file path

Returns:

  • (Boolean)


66
67
68
# File 'lib/swarm_sdk/v3/tools/read.rb', line 66

def file_read?(path)
  @read_tracker.file_read?(@agent_name, path)
end