Class: SwarmSDK::V3::Tools::Bash

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

Overview

Bash tool for executing shell commands

Executes commands in a subprocess with timeout support. Commands run in the agent’s working directory.

Constant Summary collapse

ALWAYS_BLOCKED_COMMANDS =

Commands that are always blocked for safety

[
  %r{^rm\s+-rf\s+/$},
].freeze

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#name

Constructor Details

#initialize(directory:) ⇒ Bash

Returns a new instance of Bash.

Parameters:

  • directory (String)

    Working directory for command execution



52
53
54
55
# File 'lib/swarm_sdk/v3/tools/bash.rb', line 52

def initialize(directory:)
  super()
  @directory = File.expand_path(directory)
end

Class Method Details

.creation_requirementsArray<Symbol>

Returns Constructor requirements.

Returns:

  • (Array<Symbol>)

    Constructor requirements



13
14
15
# File 'lib/swarm_sdk/v3/tools/bash.rb', line 13

def creation_requirements
  [:directory]
end

Instance Method Details

#execute(command:, description: nil, timeout: nil) ⇒ String

Execute a shell command

Parameters:

  • command (String)

    The command to run

  • description (String, nil) (defaults to: nil)

    Human-readable description

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

    Timeout in milliseconds

Returns:

  • (String)

    Command output or error



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/swarm_sdk/v3/tools/bash.rb', line 63

def execute(command:, description: nil, timeout: nil)
  return validation_error("command is required") if command.nil? || command.empty?

  blocked = ALWAYS_BLOCKED_COMMANDS.find { |pattern| pattern.match?(command) }
  return blocked_command_error(command) if blocked

  config = Configuration.instance
  timeout_ms = timeout || config.bash_command_timeout
  timeout_ms = [timeout_ms, config.bash_command_max_timeout].min
  timeout_seconds = timeout_ms / 1000.0

  stdout, stderr, exit_status = run_command(command, timeout_seconds)
  return stdout if stdout.start_with?("Error:") # Error from run_command

  output = format_output(command, description, stdout, stderr, exit_status)

  max_output = config.output_character_limit
  if output.length > max_output
    output = "#{output[0...max_output]}\n\n<system-reminder>Output truncated at #{max_output} characters.</system-reminder>"
  end

  output
rescue StandardError => e
  error("Unexpected error: #{e.class.name} - #{e.message}")
end