Class: ToolForge::ToolDefinition
- Inherits:
-
Object
- Object
- ToolForge::ToolDefinition
- Defined in:
- lib/tool_forge/tool_definition.rb
Overview
ToolDefinition is the core class for defining tools that can be converted to both RubyLLM and MCP tool formats. It provides a clean DSL for defining tool metadata, parameters, helper methods, and execution logic.
Instance Attribute Summary collapse
- #execute_block ⇒ Symbol, ... readonly
- #helper_methods ⇒ Symbol, ... readonly
- #name ⇒ Symbol, ... readonly
- #params ⇒ Symbol, ... readonly
Instance Method Summary collapse
-
#class_helper(method_name) {|*args| ... } ⇒ void
Defines a class helper method that can be called within the execute block.
-
#description(text = nil) ⇒ String?
Sets or returns the tool description.
-
#execute {|**args| ... } ⇒ void
Defines the execution logic for the tool.
-
#helper(method_name) {|*args| ... } ⇒ void
Defines an instance helper method that can be called within the execute block.
-
#initialize(name) { ... } ⇒ ToolDefinition
constructor
Creates a new tool definition with the given name.
-
#param(name, type: :string, description: nil, required: true, default: nil) ⇒ Object
Defines a parameter for the tool.
-
#to_mcp_tool ⇒ Class
Converts this tool definition to an MCP::Tool class.
-
#to_ruby_llm_tool ⇒ Class
Converts this tool definition to a RubyLLM::Tool class.
Constructor Details
#initialize(name) { ... } ⇒ ToolDefinition
Creates a new tool definition with the given name.
51 52 53 54 55 56 57 58 59 |
# File 'lib/tool_forge/tool_definition.rb', line 51 def initialize(name, &) @name = name @description = nil @params = [] @execute_block = nil @helper_methods = { instance: {}, class: {} } instance_eval(&) if block_given? end |
Instance Attribute Details
#execute_block ⇒ Symbol, ... (readonly)
38 39 40 |
# File 'lib/tool_forge/tool_definition.rb', line 38 def execute_block @execute_block end |
#helper_methods ⇒ Symbol, ... (readonly)
38 39 40 |
# File 'lib/tool_forge/tool_definition.rb', line 38 def helper_methods @helper_methods end |
#name ⇒ Symbol, ... (readonly)
38 39 40 |
# File 'lib/tool_forge/tool_definition.rb', line 38 def name @name end |
#params ⇒ Symbol, ... (readonly)
38 39 40 |
# File 'lib/tool_forge/tool_definition.rb', line 38 def params @params end |
Instance Method Details
#class_helper(method_name) {|*args| ... } ⇒ void
This method returns an undefined value.
Defines a class helper method that can be called within the execute block. Class helper methods are useful for utility functions that don’t depend on instance state. They are accessed via self.class.method_name in the execution context.
152 153 154 |
# File 'lib/tool_forge/tool_definition.rb', line 152 def class_helper(method_name, &block) @helper_methods[:class][method_name] = block end |
#description(text = nil) ⇒ String?
Sets or returns the tool description.
71 72 73 74 75 76 77 |
# File 'lib/tool_forge/tool_definition.rb', line 71 def description(text = nil) if text @description = text else @description end end |
#execute {|**args| ... } ⇒ void
This method returns an undefined value.
Defines the execution logic for the tool.
112 113 114 |
# File 'lib/tool_forge/tool_definition.rb', line 112 def execute(&block) @execute_block = block end |
#helper(method_name) {|*args| ... } ⇒ void
This method returns an undefined value.
Defines an instance helper method that can be called within the execute block. Instance helper methods are available as regular method calls in the execution context.
131 132 133 |
# File 'lib/tool_forge/tool_definition.rb', line 131 def helper(method_name, &block) @helper_methods[:instance][method_name] = block end |
#param(name, type: :string, description: nil, required: true, default: nil) ⇒ Object
Defines a parameter for the tool.
92 93 94 95 96 97 98 99 100 |
# File 'lib/tool_forge/tool_definition.rb', line 92 def param(name, type: :string, description: nil, required: true, default: nil) @params << { name: name, type: type, description: description, required: required, default: default } end |
#to_mcp_tool ⇒ Class
Converts this tool definition to an MCP::Tool class. The resulting class can be used with the Model Context Protocol framework.
Both instance and class helper methods are available in the execution context. Class helper methods are accessed via self.class.method_name.
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 |
# File 'lib/tool_forge/tool_definition.rb', line 211 def to_mcp_tool raise LoadError, 'MCP SDK is not loaded. Please require "mcp" first.' unless defined?(MCP::Tool) raise LoadError, 'MCP SDK is not loaded. Please require "mcp" first.' if MCP::Tool.nil? definition = self Class.new(MCP::Tool) do description definition.description # Build properties hash for input schema properties = {} required_params = [] definition.params.each do |param_def| prop = { type: param_def[:type].to_s } prop[:description] = param_def[:description] if param_def[:description] properties[param_def[:name].to_s] = prop required_params << param_def[:name].to_s if param_def[:required] end input_schema( properties: properties, required: required_params ) # Create a helper object that contains all the helper methods helper_class = Class.new do definition.helper_methods[:instance].each do |method_name, method_block| define_method(method_name, &method_block) end # Class methods are defined as singleton methods on the class itself definition.helper_methods[:class].each do |method_name, method_block| define_singleton_method(method_name, &method_block) end end define_singleton_method(:call) do |server_context:, **args| # Create an instance of the helper class to provide context for helper methods helper_instance = helper_class.new # Execute the block in the context of the helper instance so helper methods are available # For class methods, they'll be available on the helper_class itself result = helper_instance.instance_exec(**args, &definition.execute_block) # Smart formatting for different return types result_text = case result when String result when Hash, Array JSON.pretty_generate(result) else result.to_s end MCP::Tool::Response.new([{ type: 'text', text: result_text }]) end end end |
#to_ruby_llm_tool ⇒ Class
Converts this tool definition to a RubyLLM::Tool class. The resulting class can be instantiated and used with the RubyLLM framework.
Instance helper methods become instance methods on the generated class. Class helper methods become singleton methods on the generated class.
169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/tool_forge/tool_definition.rb', line 169 def to_ruby_llm_tool raise LoadError, 'RubyLLM is not loaded. Please require "ruby_llm" first.' unless defined?(RubyLLM::Tool) raise LoadError, 'RubyLLM is not loaded. Please require "ruby_llm" first.' if RubyLLM::Tool.nil? definition = self Class.new(RubyLLM::Tool) do description definition.description definition.params.each do |param_def| param param_def[:name], type: param_def[:type], desc: param_def[:description] end # Add instance helper methods definition.helper_methods[:instance].each do |method_name, method_block| define_method(method_name, &method_block) end # Add class helper methods definition.helper_methods[:class].each do |method_name, method_block| define_singleton_method(method_name, &method_block) end define_method(:execute) do |**args| # Execute the block in the context of this instance so helper methods are available instance_exec(**args, &definition.execute_block) end end end |