Class: DSPy::Module

Inherits:
Object
  • Object
show all
Extended by:
T::Generic, T::Sig
Includes:
Callbacks, Dry::Configurable
Defined in:
lib/dspy/module.rb

Direct Known Subclasses

Predict

Defined Under Namespace

Modules: ForwardOverrideHooks Classes: SubcriptionScope

Constant Summary collapse

DEFAULT_MODULE_SUBSCRIPTION_SCOPE =
SubcriptionScope::Descendants

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Callbacks

included

Class Method Details

.inherited(subclass) ⇒ Object



49
50
51
52
53
54
# File 'lib/dspy/module.rb', line 49

def inherited(subclass)
  super
  specs_copy = module_subscription_specs.map(&:dup)
  subclass.instance_variable_set(:@module_subscription_specs, specs_copy)
  subclass.extend(ForwardOverrideHooks)
end

.module_subscription_specsObject



68
69
70
# File 'lib/dspy/module.rb', line 68

def module_subscription_specs
  @module_subscription_specs ||= []
end

.subscribe(pattern, handler = nil, scope: DEFAULT_MODULE_SUBSCRIPTION_SCOPE, &block) ⇒ Object

Raises:

  • (ArgumentError)


56
57
58
59
60
61
62
63
64
65
66
# File 'lib/dspy/module.rb', line 56

def subscribe(pattern, handler = nil, scope: DEFAULT_MODULE_SUBSCRIPTION_SCOPE, &block)
  scope = normalize_scope(scope)
  raise ArgumentError, 'Provide a handler method or block' if handler.nil? && block.nil?

  module_subscription_specs << {
    pattern: pattern,
    handler: handler,
    block: block,
    scope: scope
  }
end

Instance Method Details

#call(**input_values) ⇒ Object



129
130
131
# File 'lib/dspy/module.rb', line 129

def call(**input_values)
  forward(**input_values)
end

#call_untyped(**input_values) ⇒ Object



135
136
137
# File 'lib/dspy/module.rb', line 135

def call_untyped(**input_values)
  forward_untyped(**input_values)
end

#configure(&block) ⇒ Object



196
197
198
199
200
# File 'lib/dspy/module.rb', line 196

def configure(&block)
  super(&block)
  propagate_lm_to_children(config.lm) if config.lm
  self
end

#configure_predictor(predictor_name, &block) ⇒ Object



213
214
215
216
217
218
219
220
221
# File 'lib/dspy/module.rb', line 213

def configure_predictor(predictor_name, &block)
  _, predictor = named_predictors.find { |name, _| name == predictor_name }
  unless predictor
    available = named_predictors.map(&:first).join(', ')
    raise ArgumentError, "Unknown predictor: #{predictor_name}. Available: #{available}"
  end
  predictor.configure(&block)
  self
end

#forward(**input_values) ⇒ Object



108
109
110
111
112
113
# File 'lib/dspy/module.rb', line 108

def forward(**input_values)
  instrument_forward_call([], input_values) do
    result = forward_untyped(**input_values)
    T.cast(result, T.type_parameter(:O))
  end
end

#forward_untyped(**input_values) ⇒ Object

Raises:

  • (NotImplementedError)


117
118
119
# File 'lib/dspy/module.rb', line 117

def forward_untyped(**input_values)
  raise NotImplementedError, "Subclasses must implement forward_untyped method"
end

#lmObject



141
142
143
# File 'lib/dspy/module.rb', line 141

def lm
  config.lm || DSPy.current_lm
end

#module_scope_idObject



271
272
273
# File 'lib/dspy/module.rb', line 271

def module_scope_id
  @module_scope_id ||= SecureRandom.uuid
end

#module_scope_labelObject



276
277
278
# File 'lib/dspy/module.rb', line 276

def module_scope_label
  @module_scope_label
end

#module_scope_label=(label) ⇒ Object



281
282
283
# File 'lib/dspy/module.rb', line 281

def module_scope_label=(label)
  @module_scope_label = label
end

#named_predictorsObject



173
174
175
# File 'lib/dspy/module.rb', line 173

def named_predictors
  []
end

#predictorsObject



178
179
180
# File 'lib/dspy/module.rb', line 178

def predictors
  named_predictors.map { |(_, predictor)| predictor }
end

#registered_module_subscriptionsObject



286
287
288
# File 'lib/dspy/module.rb', line 286

def registered_module_subscriptions
  Array(@module_subscription_ids).dup
end

#save(path) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
# File 'lib/dspy/module.rb', line 150

def save(path)
  require 'json'
  require 'fileutils'

  # Ensure parent directory exists
  dir = File.dirname(path)
  FileUtils.mkdir_p(dir) unless Dir.exist?(dir)

  # Serialize module to JSON
  File.write(path, JSON.pretty_generate(to_h))
end

#to_hObject



164
165
166
167
168
169
# File 'lib/dspy/module.rb', line 164

def to_h
  {
    class_name: self.class.name,
    state: {}
  }
end

#unsubscribe_module_eventsObject



291
292
293
294
295
# File 'lib/dspy/module.rb', line 291

def unsubscribe_module_events
  Array(@module_subscription_ids).each { |id| DSPy.events.unsubscribe(id) }
  @module_subscription_ids = []
  @module_subscriptions_registered = false
end