Class: DSPy::Tools::Base
- Inherits:
-
Object
- Object
- DSPy::Tools::Base
- Extended by:
- T::Helpers, T::Sig
- Defined in:
- lib/dspy/tools/base.rb
Overview
Base class for all Sorbet-based tools with DSL support
Direct Known Subclasses
Class Attribute Summary collapse
-
.tool_description_value ⇒ Object
readonly
Returns the value of attribute tool_description_value.
-
.tool_name_value ⇒ Object
readonly
Returns the value of attribute tool_name_value.
Class Method Summary collapse
Instance Method Summary collapse
Class Attribute Details
.tool_description_value ⇒ Object (readonly)
Returns the value of attribute tool_description_value.
17 18 19 |
# File 'lib/dspy/tools/base.rb', line 17 def tool_description_value @tool_description_value end |
.tool_name_value ⇒ Object (readonly)
Returns the value of attribute tool_name_value.
17 18 19 |
# File 'lib/dspy/tools/base.rb', line 17 def tool_name_value @tool_name_value end |
Class Method Details
.call_schema ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/dspy/tools/base.rb', line 33 def call_schema method_obj = instance_method(:call) sig_info = T::Utils.signature_for_method(method_obj) if sig_info.nil? # Fallback for methods without signatures return { type: :object, properties: {}, required: [] } end properties = {} required = [] # Handle positional arguments sig_info.arg_types.each do |param_name, param_type| next if param_name == :block # Skip block parameters properties[param_name] = { type: sorbet_type_to_json_schema(param_type)[:type], description: "Parameter #{param_name}" } # Check if parameter is required (not nilable) unless param_type.class.name.include?('Union') && param_type.name.include?('NilClass') required << param_name.to_s end end # Handle keyword arguments (more common in Ruby) sig_info.kwarg_types.each do |param_name, param_type| next if param_name == :block # Skip block parameters properties[param_name] = { type: sorbet_type_to_json_schema(param_type)[:type], description: "Parameter #{param_name}" } # Check if parameter is required by looking at required kwarg names if sig_info.req_kwarg_names.include?(param_name) required << param_name.to_s else properties[param_name][:description] += " (optional)" end end { type: :object, properties: properties, required: required } end |
.tool_description(description) ⇒ Object
27 28 29 |
# File 'lib/dspy/tools/base.rb', line 27 def tool_description(description) @tool_description_value = description end |
.tool_name(name) ⇒ Object
21 22 23 |
# File 'lib/dspy/tools/base.rb', line 21 def tool_name(name) @tool_name_value = name end |
Instance Method Details
#description ⇒ Object
139 140 141 |
# File 'lib/dspy/tools/base.rb', line 139 def description self.class.tool_description_value || "Tool: #{name}" end |
#dynamic_call(args_json) ⇒ Object
157 158 159 160 161 162 163 164 165 166 167 168 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 |
# File 'lib/dspy/tools/base.rb', line 157 def dynamic_call(args_json) # Parse arguments based on the call schema schema = self.class.call_schema if schema[:properties].empty? # No parameters - call without arguments call else # Parse arguments and call with keyword arguments args = case args_json when Hash args_json when String begin JSON.parse(args_json) rescue JSON::ParserError return "Error: Invalid JSON input" end else return "Error: Expected Hash or JSON string" end # Convert string keys to symbols and validate types kwargs = {} schema[:properties].each do |param_name, param_schema| key = param_name.to_s if args.key?(key) kwargs[param_name] = convert_argument_type(args[key], param_schema) elsif schema[:required].include?(key) return "Error: Missing required parameter: #{key}" end end call(**kwargs) end rescue => e "Error: #{e.}" end |
#name ⇒ Object
134 135 136 |
# File 'lib/dspy/tools/base.rb', line 134 def name self.class.tool_name_value || self.class.name&.split('::')&.last&.downcase || 'unknown_tool' end |
#schema ⇒ Object
145 146 147 148 149 150 151 152 153 |
# File 'lib/dspy/tools/base.rb', line 145 def schema schema_obj = self.class.call_schema tool_info = { name: name, description: description, parameters: schema_obj } JSON.generate(tool_info) end |