dspy 0.16.0 → 0.18.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 +3 -3
- data/lib/dspy/chain_of_thought.rb +13 -16
- data/lib/dspy/code_act.rb +31 -37
- data/lib/dspy/context.rb +67 -0
- data/lib/dspy/evaluate.rb +20 -17
- data/lib/dspy/lm.rb +72 -37
- data/lib/dspy/memory/memory_compactor.rb +5 -6
- data/lib/dspy/memory/memory_manager.rb +5 -4
- data/lib/dspy/observability.rb +109 -0
- data/lib/dspy/predict.rb +18 -6
- data/lib/dspy/propose/grounded_proposer.rb +13 -12
- data/lib/dspy/re_act.rb +34 -41
- data/lib/dspy/registry/registry_manager.rb +8 -10
- data/lib/dspy/registry/signature_registry.rb +40 -52
- data/lib/dspy/storage/program_storage.rb +28 -37
- data/lib/dspy/storage/storage_manager.rb +3 -4
- data/lib/dspy/teleprompt/teleprompter.rb +11 -12
- data/lib/dspy/teleprompt/utils.rb +24 -22
- data/lib/dspy/version.rb +1 -1
- data/lib/dspy.rb +42 -82
- metadata +33 -26
- data/lib/dspy/instrumentation/event_payload_factory.rb +0 -282
- data/lib/dspy/instrumentation/event_payloads.rb +0 -476
- data/lib/dspy/instrumentation/token_tracker.rb +0 -70
- data/lib/dspy/instrumentation.rb +0 -341
- data/lib/dspy/mixins/instrumentation_helpers.rb +0 -120
- data/lib/dspy/subscribers/langfuse_subscriber.rb +0 -669
- data/lib/dspy/subscribers/logger_subscriber.rb +0 -480
- data/lib/dspy/subscribers/newrelic_subscriber.rb +0 -686
- data/lib/dspy/subscribers/otel_subscriber.rb +0 -537
@@ -1,282 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'sorbet-runtime'
|
4
|
-
require_relative 'event_payloads'
|
5
|
-
|
6
|
-
module DSPy
|
7
|
-
module Instrumentation
|
8
|
-
# Factory for creating typed event payloads from hash data
|
9
|
-
module EventPayloadFactory
|
10
|
-
extend T::Sig
|
11
|
-
extend self
|
12
|
-
|
13
|
-
# Create appropriate event struct based on event name
|
14
|
-
sig { params(event_name: String, payload: T::Hash[Symbol, T.untyped]).returns(T.untyped) }
|
15
|
-
def create_event(event_name, payload)
|
16
|
-
case event_name
|
17
|
-
when 'dspy.lm.request'
|
18
|
-
create_lm_request_event(payload)
|
19
|
-
when 'dspy.lm.tokens'
|
20
|
-
create_lm_tokens_event(payload)
|
21
|
-
when 'dspy.lm.response.parsed'
|
22
|
-
create_lm_response_parsed_event(payload)
|
23
|
-
when 'dspy.predict'
|
24
|
-
create_predict_event(payload)
|
25
|
-
when 'dspy.predict.validation_error'
|
26
|
-
create_predict_validation_error_event(payload)
|
27
|
-
when 'dspy.chain_of_thought'
|
28
|
-
create_chain_of_thought_event(payload)
|
29
|
-
when 'dspy.chain_of_thought.reasoning_complete'
|
30
|
-
create_chain_of_thought_reasoning_complete_event(payload)
|
31
|
-
when 'dspy.react.iteration'
|
32
|
-
create_react_iteration_event(payload)
|
33
|
-
when 'dspy.react.tool_call'
|
34
|
-
create_react_tool_call_event(payload)
|
35
|
-
when 'dspy.react.iteration_complete'
|
36
|
-
create_react_iteration_complete_event(payload)
|
37
|
-
when 'dspy.react.max_iterations'
|
38
|
-
create_react_max_iterations_event(payload)
|
39
|
-
when 'dspy.codeact.iteration'
|
40
|
-
create_codeact_iteration_event(payload)
|
41
|
-
when 'dspy.codeact.code_execution'
|
42
|
-
create_codeact_code_execution_event(payload)
|
43
|
-
else
|
44
|
-
# Return original payload for unhandled events
|
45
|
-
payload
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
private
|
50
|
-
|
51
|
-
# LM Request Event
|
52
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(LMRequestEvent) }
|
53
|
-
def create_lm_request_event(payload)
|
54
|
-
# Extract timestamp, handling both timestamp and timestamp_ns keys
|
55
|
-
timestamp = extract_timestamp(payload)
|
56
|
-
|
57
|
-
LMRequestEvent.new(
|
58
|
-
timestamp: timestamp,
|
59
|
-
duration_ms: payload[:duration_ms] || 0.0,
|
60
|
-
cpu_time_ms: payload[:cpu_time_ms] || 0.0,
|
61
|
-
status: payload[:status] || 'success',
|
62
|
-
gen_ai_operation_name: payload[:gen_ai_operation_name] || 'unknown',
|
63
|
-
gen_ai_system: payload[:gen_ai_system] || 'unknown',
|
64
|
-
gen_ai_request_model: payload[:gen_ai_request_model] || 'unknown',
|
65
|
-
signature_class: payload[:signature_class],
|
66
|
-
provider: payload[:provider] || 'unknown',
|
67
|
-
adapter_class: payload[:adapter_class] || 'unknown',
|
68
|
-
input_size: payload[:input_size] || 0,
|
69
|
-
error_type: payload[:error_type],
|
70
|
-
error_message: payload[:error_message]
|
71
|
-
)
|
72
|
-
end
|
73
|
-
|
74
|
-
# Helper to extract timestamp from various formats
|
75
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(String) }
|
76
|
-
def extract_timestamp(payload)
|
77
|
-
if payload[:timestamp]
|
78
|
-
payload[:timestamp]
|
79
|
-
elsif payload[:timestamp_ns]
|
80
|
-
# Convert nanoseconds to ISO8601 for storage in struct
|
81
|
-
Time.at(payload[:timestamp_ns] / 1_000_000_000.0).iso8601
|
82
|
-
else
|
83
|
-
Time.now.iso8601
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
# LM Tokens Event
|
88
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(LMTokensEvent) }
|
89
|
-
def create_lm_tokens_event(payload)
|
90
|
-
LMTokensEvent.new(
|
91
|
-
timestamp: extract_timestamp(payload),
|
92
|
-
status: payload[:status] || 'success',
|
93
|
-
input_tokens: payload[:input_tokens] || 0,
|
94
|
-
output_tokens: payload[:output_tokens] || 0,
|
95
|
-
total_tokens: payload[:total_tokens] || 0,
|
96
|
-
gen_ai_system: payload[:gen_ai_system] || 'unknown',
|
97
|
-
gen_ai_request_model: payload[:gen_ai_request_model] || 'unknown',
|
98
|
-
signature_class: payload[:signature_class]
|
99
|
-
)
|
100
|
-
end
|
101
|
-
|
102
|
-
# LM Response Parsed Event
|
103
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(LMResponseParsedEvent) }
|
104
|
-
def create_lm_response_parsed_event(payload)
|
105
|
-
LMResponseParsedEvent.new(
|
106
|
-
timestamp: extract_timestamp(payload),
|
107
|
-
duration_ms: payload[:duration_ms] || 0.0,
|
108
|
-
cpu_time_ms: payload[:cpu_time_ms] || 0.0,
|
109
|
-
status: payload[:status] || 'success',
|
110
|
-
signature_class: payload[:signature_class] || 'unknown',
|
111
|
-
provider: payload[:provider] || 'unknown',
|
112
|
-
success: payload[:success] || false,
|
113
|
-
response_length: payload[:response_length] || 0,
|
114
|
-
parse_type: payload[:parse_type],
|
115
|
-
error_type: payload[:error_type],
|
116
|
-
error_message: payload[:error_message]
|
117
|
-
)
|
118
|
-
end
|
119
|
-
|
120
|
-
# Predict Event
|
121
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(PredictEvent) }
|
122
|
-
def create_predict_event(payload)
|
123
|
-
PredictEvent.new(
|
124
|
-
timestamp: extract_timestamp(payload),
|
125
|
-
duration_ms: payload[:duration_ms] || 0.0,
|
126
|
-
cpu_time_ms: payload[:cpu_time_ms] || 0.0,
|
127
|
-
status: payload[:status] || 'success',
|
128
|
-
signature_class: payload[:signature_class] || 'unknown',
|
129
|
-
module_name: payload[:module_name] || 'unknown',
|
130
|
-
model: payload[:model] || 'unknown',
|
131
|
-
provider: payload[:provider] || 'unknown',
|
132
|
-
input_fields: payload[:input_fields] || [],
|
133
|
-
input_size: payload[:input_size],
|
134
|
-
output_size: payload[:output_size],
|
135
|
-
error_type: payload[:error_type],
|
136
|
-
error_message: payload[:error_message]
|
137
|
-
)
|
138
|
-
end
|
139
|
-
|
140
|
-
# Predict Validation Error Event
|
141
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(PredictValidationErrorEvent) }
|
142
|
-
def create_predict_validation_error_event(payload)
|
143
|
-
PredictValidationErrorEvent.new(
|
144
|
-
timestamp: payload[:timestamp] || Time.now.iso8601,
|
145
|
-
status: payload[:status] || 'error',
|
146
|
-
signature_class: payload[:signature_class] || 'unknown',
|
147
|
-
module_name: payload[:module_name] || 'unknown',
|
148
|
-
field_name: payload[:field_name] || 'unknown',
|
149
|
-
error_message: payload[:error_message] || 'unknown error',
|
150
|
-
retry_count: payload[:retry_count] || 0
|
151
|
-
)
|
152
|
-
end
|
153
|
-
|
154
|
-
# Chain of Thought Event
|
155
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(ChainOfThoughtEvent) }
|
156
|
-
def create_chain_of_thought_event(payload)
|
157
|
-
ChainOfThoughtEvent.new(
|
158
|
-
timestamp: extract_timestamp(payload),
|
159
|
-
duration_ms: payload[:duration_ms] || 0.0,
|
160
|
-
cpu_time_ms: payload[:cpu_time_ms] || 0.0,
|
161
|
-
status: payload[:status] || 'success',
|
162
|
-
signature_class: payload[:signature_class] || 'unknown',
|
163
|
-
module_name: payload[:module_name] || 'unknown',
|
164
|
-
model: payload[:model] || 'unknown',
|
165
|
-
provider: payload[:provider] || 'unknown',
|
166
|
-
reasoning_length: payload[:reasoning_length],
|
167
|
-
answer_length: payload[:answer_length],
|
168
|
-
error_type: payload[:error_type],
|
169
|
-
error_message: payload[:error_message]
|
170
|
-
)
|
171
|
-
end
|
172
|
-
|
173
|
-
# Chain of Thought Reasoning Complete Event
|
174
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(ChainOfThoughtReasoningCompleteEvent) }
|
175
|
-
def create_chain_of_thought_reasoning_complete_event(payload)
|
176
|
-
ChainOfThoughtReasoningCompleteEvent.new(
|
177
|
-
timestamp: payload[:timestamp] || Time.now.iso8601,
|
178
|
-
status: payload[:status] || 'success',
|
179
|
-
signature_class: payload[:signature_class] || 'unknown',
|
180
|
-
module_name: payload[:module_name] || 'unknown',
|
181
|
-
reasoning_length: payload[:reasoning_length] || 0,
|
182
|
-
answer_present: payload[:answer_present] || false
|
183
|
-
)
|
184
|
-
end
|
185
|
-
|
186
|
-
# ReAct Iteration Event
|
187
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(ReactIterationEvent) }
|
188
|
-
def create_react_iteration_event(payload)
|
189
|
-
ReactIterationEvent.new(
|
190
|
-
timestamp: payload[:timestamp] || Time.now.iso8601,
|
191
|
-
duration_ms: payload[:duration_ms] || 0.0,
|
192
|
-
cpu_time_ms: payload[:cpu_time_ms] || 0.0,
|
193
|
-
status: payload[:status] || 'success',
|
194
|
-
iteration: payload[:iteration] || 0,
|
195
|
-
max_iterations: payload[:max_iterations] || 5,
|
196
|
-
history_length: payload[:history_length] || 0,
|
197
|
-
tools_used_so_far: payload[:tools_used_so_far] || [],
|
198
|
-
error_type: payload[:error_type],
|
199
|
-
error_message: payload[:error_message]
|
200
|
-
)
|
201
|
-
end
|
202
|
-
|
203
|
-
# ReAct Tool Call Event
|
204
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(ReactToolCallEvent) }
|
205
|
-
def create_react_tool_call_event(payload)
|
206
|
-
ReactToolCallEvent.new(
|
207
|
-
timestamp: payload[:timestamp] || Time.now.iso8601,
|
208
|
-
duration_ms: payload[:duration_ms] || 0.0,
|
209
|
-
cpu_time_ms: payload[:cpu_time_ms] || 0.0,
|
210
|
-
status: payload[:status] || 'success',
|
211
|
-
iteration: payload[:iteration] || 0,
|
212
|
-
tool_name: payload[:tool_name] || 'unknown',
|
213
|
-
tool_input: payload[:tool_input],
|
214
|
-
error_type: payload[:error_type],
|
215
|
-
error_message: payload[:error_message]
|
216
|
-
)
|
217
|
-
end
|
218
|
-
|
219
|
-
# ReAct Iteration Complete Event
|
220
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(ReactIterationCompleteEvent) }
|
221
|
-
def create_react_iteration_complete_event(payload)
|
222
|
-
ReactIterationCompleteEvent.new(
|
223
|
-
timestamp: payload[:timestamp] || Time.now.iso8601,
|
224
|
-
status: payload[:status] || 'success',
|
225
|
-
iteration: payload[:iteration] || 0,
|
226
|
-
thought: payload[:thought] || '',
|
227
|
-
action: payload[:action] || '',
|
228
|
-
action_input: payload[:action_input],
|
229
|
-
observation: payload[:observation] || '',
|
230
|
-
tools_used: payload[:tools_used] || []
|
231
|
-
)
|
232
|
-
end
|
233
|
-
|
234
|
-
# ReAct Max Iterations Event
|
235
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(ReactMaxIterationsEvent) }
|
236
|
-
def create_react_max_iterations_event(payload)
|
237
|
-
ReactMaxIterationsEvent.new(
|
238
|
-
timestamp: payload[:timestamp] || Time.now.iso8601,
|
239
|
-
status: payload[:status] || 'warning',
|
240
|
-
iteration_count: payload[:iteration_count] || 0,
|
241
|
-
max_iterations: payload[:max_iterations] || 5,
|
242
|
-
tools_used: payload[:tools_used] || [],
|
243
|
-
final_history_length: payload[:final_history_length] || 0
|
244
|
-
)
|
245
|
-
end
|
246
|
-
|
247
|
-
# CodeAct Iteration Event
|
248
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(CodeActIterationEvent) }
|
249
|
-
def create_codeact_iteration_event(payload)
|
250
|
-
CodeActIterationEvent.new(
|
251
|
-
timestamp: payload[:timestamp] || Time.now.iso8601,
|
252
|
-
duration_ms: payload[:duration_ms] || 0.0,
|
253
|
-
cpu_time_ms: payload[:cpu_time_ms] || 0.0,
|
254
|
-
status: payload[:status] || 'success',
|
255
|
-
iteration: payload[:iteration] || 0,
|
256
|
-
max_iterations: payload[:max_iterations] || 5,
|
257
|
-
history_length: payload[:history_length] || 0,
|
258
|
-
code_blocks_executed: payload[:code_blocks_executed] || 0,
|
259
|
-
error_type: payload[:error_type],
|
260
|
-
error_message: payload[:error_message]
|
261
|
-
)
|
262
|
-
end
|
263
|
-
|
264
|
-
# CodeAct Code Execution Event
|
265
|
-
sig { params(payload: T::Hash[Symbol, T.untyped]).returns(CodeActCodeExecutionEvent) }
|
266
|
-
def create_codeact_code_execution_event(payload)
|
267
|
-
CodeActCodeExecutionEvent.new(
|
268
|
-
timestamp: payload[:timestamp] || Time.now.iso8601,
|
269
|
-
duration_ms: payload[:duration_ms] || 0.0,
|
270
|
-
cpu_time_ms: payload[:cpu_time_ms] || 0.0,
|
271
|
-
status: payload[:status] || 'success',
|
272
|
-
iteration: payload[:iteration] || 0,
|
273
|
-
code_type: payload[:code_type] || 'unknown',
|
274
|
-
code_length: payload[:code_length] || 0,
|
275
|
-
execution_success: payload[:execution_success] || false,
|
276
|
-
error_type: payload[:error_type],
|
277
|
-
error_message: payload[:error_message]
|
278
|
-
)
|
279
|
-
end
|
280
|
-
end
|
281
|
-
end
|
282
|
-
end
|