Class: DSPy::Predict

Inherits:
Module show all
Extended by:
T::Sig
Includes:
Mixins::InstructionUpdatable, Mixins::StructBuilder, Mixins::TypeCoercion
Defined in:
lib/dspy/predict.rb

Direct Known Subclasses

ChainOfThought, ReAct

Constant Summary

Constants inherited from Module

Module::DEFAULT_MODULE_SUBSCRIPTION_SCOPE

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Module

#call, #call_untyped, #forward, inherited, #lm, #module_scope_id, #module_scope_label, #module_scope_label=, module_subscription_specs, #registered_module_subscriptions, #save, subscribe, #to_h, #unsubscribe_module_events

Methods included from Callbacks

included

Constructor Details

#initialize(signature_class) ⇒ Predict



63
64
65
66
67
68
69
70
# File 'lib/dspy/predict.rb', line 63

def initialize(signature_class)
  super()
  @signature_class = signature_class

  # Prompt will read schema_format from config automatically
  @prompt = Prompt.from_signature(signature_class)
  @demos = nil
end

Instance Attribute Details

#demosObject

Returns the value of attribute demos.



60
61
62
# File 'lib/dspy/predict.rb', line 60

def demos
  @demos
end

#promptObject (readonly)

Returns the value of attribute prompt.



56
57
58
# File 'lib/dspy/predict.rb', line 56

def prompt
  @prompt
end

#signature_classObject (readonly)

Returns the value of attribute signature_class.



53
54
55
# File 'lib/dspy/predict.rb', line 53

def signature_class
  @signature_class
end

Class Method Details

.from_h(data) ⇒ Object

Raises:

  • (ArgumentError)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/dspy/predict.rb', line 74

def self.from_h(data)
  state = data[:state]
  raise ArgumentError, "Missing state in serialized data" unless state

  signature_class_name = state[:signature_class]
  signature_class = Object.const_get(signature_class_name)
  program = new(signature_class)
  
  # Restore instruction if available
  if state[:instruction]
    program = program.with_instruction(state[:instruction])
  end
  
  # Restore examples if available
  few_shot_examples = state[:few_shot_examples]
  if few_shot_examples && !few_shot_examples.empty?
    # Convert hash examples back to FewShotExample objects
    examples = few_shot_examples.map do |ex|
      if ex.is_a?(Hash)
        DSPy::FewShotExample.new(
          input: ex[:input],
          output: ex[:output],
          reasoning: ex[:reasoning]
        )
      else
        ex
      end
    end
    program = program.with_examples(examples)
  end
  
  program
end

Instance Method Details

#add_examples(examples) ⇒ Object



142
143
144
145
146
147
# File 'lib/dspy/predict.rb', line 142

def add_examples(examples)
  instance = with_prompt(@prompt.add_examples(examples))
  combined = instance.prompt.few_shot_examples
  instance.demos = combined.map { |example| example }
  instance
end

#forward_untyped(**input_values) ⇒ Object



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

def forward_untyped(**input_values)
  # Module#forward handles span creation, we just do the prediction logic
  
  # Apply type coercion to input values first
  input_props = @signature_class.input_struct_class.props
  coerced_input_values = coerce_output_attributes(input_values, input_props)
  
  # Store coerced input values for optimization
  @last_input_values = coerced_input_values.clone
  
  # Validate input with coerced values
  validate_input_struct(coerced_input_values)
  
  # Check if LM is configured
  current_lm = lm
  if current_lm.nil?
    raise DSPy::ConfigurationError.missing_lm(self.class.name)
  end
  
  # Call LM and process response with coerced input values
  output_attributes = current_lm.chat(self, coerced_input_values)
  processed_output = process_lm_output(output_attributes)
  
  # Create combined result struct with coerced input values
  prediction_result = create_prediction_result(coerced_input_values, processed_output)
  
  prediction_result
end

#named_predictorsObject



150
151
152
# File 'lib/dspy/predict.rb', line 150

def named_predictors
  [["self", self]]
end

#predictorsObject



155
156
157
# File 'lib/dspy/predict.rb', line 155

def predictors
  [self]
end

#system_signatureObject



110
111
112
# File 'lib/dspy/predict.rb', line 110

def system_signature
  @prompt.render_system_prompt
end

#user_signature(input_values) ⇒ Object



115
116
117
# File 'lib/dspy/predict.rb', line 115

def user_signature(input_values)
  @prompt.render_user_prompt(input_values)
end

#with_examples(examples) ⇒ Object



135
136
137
138
139
# File 'lib/dspy/predict.rb', line 135

def with_examples(examples)
  instance = with_prompt(@prompt.with_examples(examples))
  instance.demos = examples.map { |example| example }
  instance
end

#with_instruction(instruction) ⇒ Object



130
131
132
# File 'lib/dspy/predict.rb', line 130

def with_instruction(instruction)
  with_prompt(@prompt.with_instruction(instruction))
end

#with_prompt(new_prompt) ⇒ Object



121
122
123
124
125
126
127
# File 'lib/dspy/predict.rb', line 121

def with_prompt(new_prompt)
  # Create a new instance with the same signature but updated prompt
  instance = self.class.new(@signature_class)
  instance.instance_variable_set(:@prompt, new_prompt)
  instance.instance_variable_set(:@demos, @demos&.map { |demo| demo })
  instance
end