Class: Legate::Tool
- Inherits:
-
Object
- Object
- Legate::Tool
- Includes:
- MetadataDsl
- Defined in:
- lib/legate/tool.rb,
lib/legate/tool/metadata_dsl.rb
Overview
Base class for all tools that can be used by Agents.
Tools are the way agents interact with the outside world. To create a new tool, inherit from this class, use the DSL to define metadata, and implement the #perform_execution method.
Direct Known Subclasses
Mcp::ToolWrapper, Legate::Tools::AgentTool, Legate::Tools::BaseAsyncJobTool, Legate::Tools::Calculator, Legate::Tools::CatFacts, Legate::Tools::CheckJobStatusTool, Legate::Tools::CurrentTime, Legate::Tools::Echo, Legate::Tools::HttpRequest, Legate::Tools::RandomNumberTool, Legate::Tools::ReadWebpage, Legate::Tools::WebhookTool
Defined Under Namespace
Modules: MetadataDsl
Class Attribute Summary collapse
-
.description ⇒ Object
readonly
Keep old readers for define_metadata compatibility.
-
.parameters_definition ⇒ Object
readonly
Keep old readers for define_metadata compatibility.
-
.tool_name ⇒ Object
readonly
Keep old readers for define_metadata compatibility.
Instance Attribute Summary collapse
-
#description ⇒ Object
readonly
Instance readers.
-
#name ⇒ Object
readonly
Instance readers.
-
#parameters ⇒ Object
readonly
Instance readers.
Class Method Summary collapse
-
.define_metadata(name:, description:, parameters: {}) ⇒ Object
Define the tool’s static metadata.
-
.inherited(subclass) ⇒ Object
— Self-Registration Hook — NOTE: We intentionally do NOT auto-register tools in the inherited hook.
Instance Method Summary collapse
-
#execute(params = {}, context = nil) ⇒ Hash
Execute the tool.
-
#initialize(**_options) ⇒ Tool
constructor
Initialize - Sets instance vars from class metadata.
-
#validate_and_coerce_params(params) ⇒ Hash
Validate and coerce parameters based on metadata types.
-
#validate_params(params) ⇒ Object
Validate the parameters (Deprecated: Use validate_and_coerce_params) This method is kept for backward compatibility and wraps the new logic, but ignores the coerced return value.
Methods included from MetadataDsl
Constructor Details
#initialize(**_options) ⇒ Tool
Initialize - Sets instance vars from class metadata
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/legate/tool.rb', line 92 def initialize(**) # Fetch metadata using the primary tool_metadata method (defined by DSL) = self.class. @name = [:name] @description = [:description] @parameters = [:parameters] || {} # Lenient check for missing metadata return unless @name.nil? || @name == :'' || @description.nil? || @description.empty? is_anonymous = !self.class.name || self.class.name.empty? || self.class.name.start_with?('#<Class:') unless is_anonymous missing = [] missing << ':name' if @name.nil? || @name == :'' missing << ':description' if @description.nil? || @description.empty? Legate.logger.warn("Tool class #{self.class} initialized with missing metadata: [#{missing.join(', ')}] using #{self.class.}. Tool may not function correctly.") end @description ||= '' end |
Class Attribute Details
.description ⇒ Object (readonly)
Keep old readers for define_metadata compatibility
55 56 57 |
# File 'lib/legate/tool.rb', line 55 def description @description end |
.parameters_definition ⇒ Object (readonly)
Keep old readers for define_metadata compatibility
55 56 57 |
# File 'lib/legate/tool.rb', line 55 def parameters_definition @parameters_definition end |
.tool_name ⇒ Object (readonly)
Keep old readers for define_metadata compatibility
55 56 57 |
# File 'lib/legate/tool.rb', line 55 def tool_name @tool_name end |
Instance Attribute Details
#description ⇒ Object (readonly)
Instance readers
89 90 91 |
# File 'lib/legate/tool.rb', line 89 def description @description end |
#name ⇒ Object (readonly)
Instance readers
89 90 91 |
# File 'lib/legate/tool.rb', line 89 def name @name end |
#parameters ⇒ Object (readonly)
Instance readers
89 90 91 |
# File 'lib/legate/tool.rb', line 89 def parameters @parameters end |
Class Method Details
.define_metadata(name:, description:, parameters: {}) ⇒ Object
Define the tool’s static metadata. DEPRECATED: Use ‘tool_description`, `parameter`, and automatic name inference instead.
59 60 61 62 63 64 65 66 67 68 |
# File 'lib/legate/tool.rb', line 59 def (name:, description:, parameters: {}) warn "[DEPRECATION] `define_metadata` is deprecated. Use `tool_description`, `parameter`, and rely on class name inference (or `self.explicit_tool_name = :my_name`) instead. Called from #{caller_locations( 1, 1 )[0].label}" @tool_name = name.to_sym @description = description @parameters_definition = parameters @_tool_metadata_cache = nil # Invalidate cache end |
.inherited(subclass) ⇒ Object
— Self-Registration Hook — NOTE: We intentionally do NOT auto-register tools in the inherited hook. The reason is that ‘inherited` is called BEFORE the class body executes, so explicit_tool_name and other DSL methods haven’t run yet. This would cause tools to be registered under their inferred name (e.g., :random_number_tool) instead of their explicit name (e.g., :random_number).
Instead, built-in tools are explicitly registered in lib/legate.rb after their class definitions are complete. Custom tools should either:
-
Call ‘Legate::GlobalToolManager.register_tool(MyTool)` explicitly after definition
-
Be discovered via tool_paths when creating agents
82 83 84 85 |
# File 'lib/legate/tool.rb', line 82 def self.inherited(subclass) super # Call parent's inherited if necessary Legate.logger.debug("Tool subclass #{subclass} inherited. Tool will be registered when explicitly added to GlobalToolManager or an agent's tool registry.") end |
Instance Method Details
#execute(params = {}, context = nil) ⇒ Hash
Execute the tool
116 117 118 119 120 121 122 123 |
# File 'lib/legate/tool.rb', line 116 def execute(params = {}, context = nil) coerced_params = validate_and_coerce_params(params) Legate.logger.debug("Executing tool '#{@name}' with validated params: #{coerced_params.inspect} and context: #{context&.to_h.inspect}") result = perform_execution(coerced_params, context) # perform_execution may return a typed ToolResult or the canonical hash; # normalize to the hash here so everything downstream is unchanged. result.is_a?(Legate::ToolResult) ? result.to_h : result end |
#validate_and_coerce_params(params) ⇒ Hash
Validate and coerce parameters based on metadata types
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/legate/tool.rb', line 137 def validate_and_coerce_params(params) # 1. Normalize keys to symbols normalized_params = params.transform_keys(&:to_sym) current_parameters = @parameters || {} # 2. Check for missing required parameters # Use symbol keys for check required_param_names = current_parameters.select { |_, p| p[:required] }.keys present_keys = normalized_params.keys missing_params = required_param_names - present_keys unless missing_params.empty? msg = "Missing required parameters for tool '#{@name}': #{missing_params.join(', ')}." msg += " Provided: [#{present_keys.empty? ? 'None' : present_keys.join(', ')}]." Legate.logger.error("Validation failed: #{msg} Params: #{params.inspect}") raise Legate::ToolArgumentError, msg end # 3. Type Validation & Coercion coerced_params = normalized_params.dup current_parameters.each do |param_name, param_def| # Only process if present next unless coerced_params.key?(param_name) value = coerced_params[param_name] expected_type = param_def[:type] next unless expected_type begin coerced_value = coerce_value(value, expected_type) coerced_params[param_name] = coerced_value rescue Legate::ToolArgumentError => e # coerce_value raises ToolArgumentError (not ArgumentError/TypeError); # re-raise with the parameter/tool context the bare message lacks. raise Legate::ToolArgumentError, "Parameter '#{param_name}' for tool '#{@name}': #{e.}" end end coerced_params end |
#validate_params(params) ⇒ Object
Validate the parameters (Deprecated: Use validate_and_coerce_params) This method is kept for backward compatibility and wraps the new logic, but ignores the coerced return value.
128 129 130 131 |
# File 'lib/legate/tool.rb', line 128 def validate_params(params) validate_and_coerce_params(params) nil end |