Class: DSPy::Tools::Toolset

Inherits:
Object
  • Object
show all
Extended by:
T::Helpers, T::Sig
Defined in:
lib/dspy/tools/toolset.rb

Overview

Base class for multi-method tool classes where each method can be exposed as an individual tool Similar to Rails controllers where each action is exposed as an endpoint

Defined Under Namespace

Classes: ToolProxy

Class Attribute Summary collapse

Class Method Summary collapse

Class Attribute Details

.exposed_toolsObject (readonly)

Returns the value of attribute exposed_tools.



20
21
22
# File 'lib/dspy/tools/toolset.rb', line 20

def exposed_tools
  @exposed_tools
end

Class Method Details

.schema_for_method(method_name) ⇒ Object



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
87
88
89
90
# File 'lib/dspy/tools/toolset.rb', line 53

def schema_for_method(method_name)
  method_obj = instance_method(method_name)
  sig_info = T::Utils.signature_for_method(method_obj)

  if sig_info.nil?
    # Fallback for methods without signatures
    return {
      type: :object,
      properties: {},
      required: []
    }
  end

  # Reuse the schema generation logic from Base
  properties = {}
  required = []

  # Handle keyword arguments (most common in Ruby)
  sig_info.kwarg_types.each do |param_name, param_type|
    next if param_name == :block

    schema = DSPy::TypeSystem::SorbetJsonSchema.type_to_json_schema(param_type)
    properties[param_name] = schema.merge({ description: "Parameter #{param_name}" })

    # Check if parameter is required
    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

.to_toolsObject



44
45
46
47
48
49
# File 'lib/dspy/tools/toolset.rb', line 44

def to_tools
  instance = new
  (@exposed_tools || {}).map do |method_name, config|
    ToolProxy.new(instance, method_name, config[:tool_name], config[:description])
  end
end

.tool(method_name, tool_name: nil, description: nil) ⇒ Object



24
25
26
27
28
29
30
# File 'lib/dspy/tools/toolset.rb', line 24

def tool(method_name, tool_name: nil, description: nil)
  @exposed_tools ||= {}
  @exposed_tools[method_name] = {
    tool_name: tool_name || "#{toolset_name}_#{method_name}",
    description: description || "#{method_name.to_s.tr('_', ' ').capitalize} operation"
  }
end

.toolset_name(name = nil) ⇒ Object



34
35
36
37
38
39
40
# File 'lib/dspy/tools/toolset.rb', line 34

def toolset_name(name = nil)
  if name
    @toolset_name = name
  else
    @toolset_name || self.name.split('::').last.gsub(/Toolset$/, '').downcase
  end
end