Module: RobotLab::ScriptTool
- Defined in:
- lib/robot_lab/script_tool.rb
Overview
Factory module for wrapping AgentSkills scripts as RobotLab::Tool instances.
Given a path to an executable shell script, produces a Tool that shells out to the script and returns its combined stdout+stderr output. Non-executable scripts return nil with a logged warning.
Class Method Summary collapse
-
.derive_name(path) ⇒ String
Snake_case tool name derived from filename.
-
.extract_description(path) ⇒ String
Extract tool description from the first non-shebang comment line.
-
.from_path(script_path) ⇒ RobotLab::Tool?
Wrap a script file as a RobotLab::Tool.
Class Method Details
.derive_name(path) ⇒ String
Returns snake_case tool name derived from filename.
51 52 53 54 55 56 |
# File 'lib/robot_lab/script_tool.rb', line 51 def self.derive_name(path) path.basename.to_s .sub(/\.[^.]+$/, '') .gsub(/[^a-zA-Z0-9]+/, '_') .gsub(/^_+|_+$/, '') end |
.extract_description(path) ⇒ String
Extract tool description from the first non-shebang comment line.
62 63 64 65 66 67 68 69 70 71 72 73 74 |
# File 'lib/robot_lab/script_tool.rb', line 62 def self.extract_description(path) File.foreach(path) do |line| stripped = line.strip next unless stripped.start_with?('#') next if stripped.start_with?('#!') # skip shebang desc = stripped.sub(/^#+\s*/, '').strip return desc unless desc.empty? end derive_name(path) rescue StandardError derive_name(path) end |
.from_path(script_path) ⇒ RobotLab::Tool?
Wrap a script file as a RobotLab::Tool.
17 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 |
# File 'lib/robot_lab/script_tool.rb', line 17 def self.from_path(script_path) path = Pathname.new(script_path) unless path.executable? RobotLab.config.logger.warn( "ScriptTool: #{path.basename} is not executable, skipping" ) return nil end tool_name = derive_name(path) description = extract_description(path) script = path.to_s Tool.create( name: tool_name, description: description, parameters: { type: 'object', properties: { args: { type: 'string', description: 'Optional command-line arguments' } }, required: [] } ) do |tool_args| cli_args = tool_args[:args].to_s.strip cmd = cli_args.empty? ? ['bash', script] : ['bash', script, *Shellwords.split(cli_args)] output, status = Open3.capture2e(*cmd) status.success? ? output : "Error (exit #{status.exitstatus}):\n#{output}" end end |