dspy 0.3.1 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +69 -382
- data/lib/dspy/chain_of_thought.rb +57 -0
- data/lib/dspy/evaluate.rb +554 -0
- data/lib/dspy/example.rb +203 -0
- data/lib/dspy/few_shot_example.rb +81 -0
- data/lib/dspy/instrumentation.rb +97 -8
- data/lib/dspy/lm/adapter_factory.rb +6 -8
- data/lib/dspy/lm.rb +5 -7
- data/lib/dspy/predict.rb +32 -34
- data/lib/dspy/prompt.rb +222 -0
- data/lib/dspy/propose/grounded_proposer.rb +560 -0
- data/lib/dspy/registry/registry_manager.rb +504 -0
- data/lib/dspy/registry/signature_registry.rb +725 -0
- data/lib/dspy/storage/program_storage.rb +442 -0
- data/lib/dspy/storage/storage_manager.rb +331 -0
- data/lib/dspy/subscribers/langfuse_subscriber.rb +669 -0
- data/lib/dspy/subscribers/logger_subscriber.rb +120 -0
- data/lib/dspy/subscribers/newrelic_subscriber.rb +686 -0
- data/lib/dspy/subscribers/otel_subscriber.rb +538 -0
- data/lib/dspy/teleprompt/data_handler.rb +107 -0
- data/lib/dspy/teleprompt/mipro_v2.rb +790 -0
- data/lib/dspy/teleprompt/simple_optimizer.rb +497 -0
- data/lib/dspy/teleprompt/teleprompter.rb +336 -0
- data/lib/dspy/teleprompt/utils.rb +380 -0
- data/lib/dspy/version.rb +5 -0
- data/lib/dspy.rb +16 -0
- metadata +29 -12
- data/lib/dspy/lm/adapters/ruby_llm_adapter.rb +0 -81
|
@@ -47,6 +47,27 @@ module DSPy
|
|
|
47
47
|
DSPy::Instrumentation.subscribe('dspy.react.tool_call') do |event|
|
|
48
48
|
log_react_tool_call(event)
|
|
49
49
|
end
|
|
50
|
+
|
|
51
|
+
# Subscribe to optimization events
|
|
52
|
+
DSPy::Instrumentation.subscribe('dspy.optimization.start') do |event|
|
|
53
|
+
log_optimization_start(event)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
DSPy::Instrumentation.subscribe('dspy.optimization.complete') do |event|
|
|
57
|
+
log_optimization_complete(event)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
DSPy::Instrumentation.subscribe('dspy.optimization.trial_start') do |event|
|
|
61
|
+
log_optimization_trial_start(event)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
DSPy::Instrumentation.subscribe('dspy.optimization.trial_complete') do |event|
|
|
65
|
+
log_optimization_trial_complete(event)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
DSPy::Instrumentation.subscribe('dspy.optimization.error') do |event|
|
|
69
|
+
log_optimization_error(event)
|
|
70
|
+
end
|
|
50
71
|
end
|
|
51
72
|
|
|
52
73
|
# Callback methods for different event types
|
|
@@ -210,6 +231,105 @@ module DSPy
|
|
|
210
231
|
|
|
211
232
|
logger.info(log_parts.join(' '))
|
|
212
233
|
end
|
|
234
|
+
|
|
235
|
+
# Optimization event logging methods
|
|
236
|
+
sig { params(event: T.untyped).void }
|
|
237
|
+
def log_optimization_start(event)
|
|
238
|
+
payload = event.payload
|
|
239
|
+
optimization_id = payload[:optimization_id]
|
|
240
|
+
optimizer = payload[:optimizer]
|
|
241
|
+
trainset_size = payload[:trainset_size]
|
|
242
|
+
valset_size = payload[:valset_size]
|
|
243
|
+
|
|
244
|
+
log_parts = [
|
|
245
|
+
"event=optimization_start",
|
|
246
|
+
"optimization_id=#{optimization_id}",
|
|
247
|
+
"optimizer=#{optimizer}",
|
|
248
|
+
"trainset_size=#{trainset_size}"
|
|
249
|
+
]
|
|
250
|
+
log_parts << "valset_size=#{valset_size}" if valset_size
|
|
251
|
+
|
|
252
|
+
logger.info(log_parts.join(' '))
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
sig { params(event: T.untyped).void }
|
|
256
|
+
def log_optimization_complete(event)
|
|
257
|
+
payload = event.payload
|
|
258
|
+
optimization_id = payload[:optimization_id]
|
|
259
|
+
optimizer = payload[:optimizer]
|
|
260
|
+
duration = payload[:duration_ms]&.round(2)
|
|
261
|
+
best_score = payload[:best_score]
|
|
262
|
+
trials_count = payload[:trials_count]
|
|
263
|
+
|
|
264
|
+
log_parts = [
|
|
265
|
+
"event=optimization_complete",
|
|
266
|
+
"optimization_id=#{optimization_id}",
|
|
267
|
+
"optimizer=#{optimizer}",
|
|
268
|
+
"duration_ms=#{duration}"
|
|
269
|
+
]
|
|
270
|
+
log_parts << "best_score=#{best_score}" if best_score
|
|
271
|
+
log_parts << "trials_count=#{trials_count}" if trials_count
|
|
272
|
+
|
|
273
|
+
logger.info(log_parts.join(' '))
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
sig { params(event: T.untyped).void }
|
|
277
|
+
def log_optimization_trial_start(event)
|
|
278
|
+
payload = event.payload
|
|
279
|
+
optimization_id = payload[:optimization_id]
|
|
280
|
+
trial_number = payload[:trial_number]
|
|
281
|
+
instruction = payload[:instruction]
|
|
282
|
+
|
|
283
|
+
log_parts = [
|
|
284
|
+
"event=optimization_trial_start",
|
|
285
|
+
"optimization_id=#{optimization_id}",
|
|
286
|
+
"trial_number=#{trial_number}"
|
|
287
|
+
]
|
|
288
|
+
log_parts << "instruction=\"#{instruction&.slice(0, 100)}\"" if instruction
|
|
289
|
+
|
|
290
|
+
logger.info(log_parts.join(' '))
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
sig { params(event: T.untyped).void }
|
|
294
|
+
def log_optimization_trial_complete(event)
|
|
295
|
+
payload = event.payload
|
|
296
|
+
optimization_id = payload[:optimization_id]
|
|
297
|
+
trial_number = payload[:trial_number]
|
|
298
|
+
duration = payload[:duration_ms]&.round(2)
|
|
299
|
+
score = payload[:score]
|
|
300
|
+
status = payload[:status]
|
|
301
|
+
|
|
302
|
+
log_parts = [
|
|
303
|
+
"event=optimization_trial_complete",
|
|
304
|
+
"optimization_id=#{optimization_id}",
|
|
305
|
+
"trial_number=#{trial_number}",
|
|
306
|
+
"status=#{status}",
|
|
307
|
+
"duration_ms=#{duration}"
|
|
308
|
+
]
|
|
309
|
+
log_parts << "score=#{score}" if score
|
|
310
|
+
log_parts << "error=\"#{payload[:error_message]}\"" if status == 'error' && payload[:error_message]
|
|
311
|
+
|
|
312
|
+
logger.info(log_parts.join(' '))
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
sig { params(event: T.untyped).void }
|
|
316
|
+
def log_optimization_error(event)
|
|
317
|
+
payload = event.payload
|
|
318
|
+
optimization_id = payload[:optimization_id]
|
|
319
|
+
optimizer = payload[:optimizer]
|
|
320
|
+
error_message = payload[:error_message]
|
|
321
|
+
error_type = payload[:error_type]
|
|
322
|
+
|
|
323
|
+
log_parts = [
|
|
324
|
+
"event=optimization_error",
|
|
325
|
+
"optimization_id=#{optimization_id}",
|
|
326
|
+
"optimizer=#{optimizer}",
|
|
327
|
+
"error_type=#{error_type}"
|
|
328
|
+
]
|
|
329
|
+
log_parts << "error=\"#{error_message}\"" if error_message
|
|
330
|
+
|
|
331
|
+
logger.info(log_parts.join(' '))
|
|
332
|
+
end
|
|
213
333
|
end
|
|
214
334
|
end
|
|
215
335
|
end
|