Class: DSPy::Example

Inherits:
Object
  • Object
show all
Extended by:
T::Sig
Defined in:
lib/dspy/example.rb

Overview

Represents a typed training/evaluation example with Signature validation Provides early validation and type safety for evaluation workflows

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(signature_class:, input:, expected:, id: nil, metadata: nil) ⇒ Example

Returns a new instance of Example.



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/dspy/example.rb', line 36

def initialize(signature_class:, input:, expected:, id: nil, metadata: nil)
  @signature_class = signature_class
  @id = id
  @metadata = &.freeze

  # Validate and create input struct
  begin
    @input = signature_class.input_struct_class.new(**input)
  rescue ArgumentError => e
    raise ArgumentError, "Invalid input for #{signature_class.name}: #{e.message}"
  rescue TypeError => e
    raise TypeError, "Type error in input for #{signature_class.name}: #{e.message}"
  end

  # Validate and create expected output struct
  begin
    @expected = signature_class.output_struct_class.new(**expected)
  rescue ArgumentError => e
    raise ArgumentError, "Invalid expected output for #{signature_class.name}: #{e.message}"
  rescue TypeError => e
    raise TypeError, "Type error in expected output for #{signature_class.name}: #{e.message}"
  end
end

Instance Attribute Details

#expectedObject (readonly)

Returns the value of attribute expected.



19
20
21
# File 'lib/dspy/example.rb', line 19

def expected
  @expected
end

#idObject (readonly)

Returns the value of attribute id.



22
23
24
# File 'lib/dspy/example.rb', line 22

def id
  @id
end

#inputObject (readonly)

Returns the value of attribute input.



16
17
18
# File 'lib/dspy/example.rb', line 16

def input
  @input
end

#metadataObject (readonly)

Returns the value of attribute metadata.



25
26
27
# File 'lib/dspy/example.rb', line 25

def 
  @metadata
end

#signature_classObject (readonly)

Returns the value of attribute signature_class.



13
14
15
# File 'lib/dspy/example.rb', line 13

def signature_class
  @signature_class
end

Class Method Details

.from_h(hash, signature_registry: nil) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/dspy/example.rb', line 135

def self.from_h(hash, signature_registry: nil)
  signature_class_name = hash[:signature_class]
  
  # Resolve signature class
  signature_class = if signature_registry && signature_registry[signature_class_name]
                     signature_registry[signature_class_name]
                   else
                     # Try to resolve from constant
                     Object.const_get(signature_class_name)
                   end
  
  new(
    signature_class: signature_class,
    input: hash[:input] || {},
    expected: hash[:expected] || {},
    id: hash[:id],
    metadata: hash[:metadata]
  )
end

.validate_batch(signature_class, examples_data) ⇒ Object



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
# File 'lib/dspy/example.rb', line 163

def self.validate_batch(signature_class, examples_data)
  errors = []
  examples = []
  
  examples_data.each_with_index do |example_data, index|
    begin
      # Only support structured format with :input and :expected keys
      unless example_data.key?(:input) && example_data.key?(:expected)
        raise ArgumentError, "Example must have :input and :expected keys. Legacy flat format is no longer supported."
      end
      
      example = new(
        signature_class: signature_class,
        input: example_data[:input],
        expected: example_data[:expected],
        id: example_data[:id] || "example_#{index}"
      )
      examples << example
    rescue => e
      errors << "Example #{index}: #{e.message}"
    end
  end
  
  unless errors.empty?
    raise ArgumentError, "Validation errors:\n#{errors.join("\n")}"
  end
  
  examples
end

Instance Method Details

#==(other) ⇒ Object



82
83
84
85
86
87
88
# File 'lib/dspy/example.rb', line 82

def ==(other)
  return false unless other.is_a?(Example)
  
  @signature_class == other.signature_class &&
    input_values == other.input_values &&
    expected_values == other.expected_values
end

#expected_valuesObject



72
73
74
75
76
77
78
# File 'lib/dspy/example.rb', line 72

def expected_values
  expected_hash = {}
  @expected.class.props.keys.each do |key|
    expected_hash[key] = @expected.send(key)
  end
  expected_hash
end

#input_valuesObject



62
63
64
65
66
67
68
# File 'lib/dspy/example.rb', line 62

def input_values
  input_hash = {}
  @input.class.props.keys.each do |key|
    input_hash[key] = @input.send(key)
  end
  input_hash
end

#inspectObject



221
222
223
# File 'lib/dspy/example.rb', line 221

def inspect
  to_s
end

#matches_prediction?(prediction) ⇒ Boolean

Returns:

  • (Boolean)


93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/dspy/example.rb', line 93

def matches_prediction?(prediction)
  return false unless prediction

  # Compare each expected field with prediction
  @expected.class.props.keys.all? do |key|
    expected_value = @expected.send(key)
    
    # Extract prediction value
    prediction_value = case prediction
                      when T::Struct
                        prediction.respond_to?(key) ? prediction.send(key) : nil
                      when Hash
                        prediction[key] || prediction[key.to_s]
                      else
                        prediction.respond_to?(key) ? prediction.send(key) : nil
                      end
    
    expected_value == prediction_value
  end
end

#to_hObject



116
117
118
119
120
121
122
123
124
125
126
# File 'lib/dspy/example.rb', line 116

def to_h
  result = {
    signature_class: @signature_class.name,
    input: input_values,
    expected: expected_values
  }
  
  result[:id] = @id if @id
  result[:metadata] = @metadata if @metadata
  result
end

#to_sObject



196
197
198
# File 'lib/dspy/example.rb', line 196

def to_s
  "DSPy::Example(#{@signature_class.name}) input=#{format_hash(input_values)} expected=#{format_hash(expected_values)}"
end