desiru 0.1.0 → 0.1.1

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.env.example +34 -0
  3. data/.rubocop.yml +7 -4
  4. data/.ruby-version +1 -0
  5. data/CLAUDE.md +4 -0
  6. data/Gemfile +21 -2
  7. data/Gemfile.lock +87 -12
  8. data/README.md +295 -2
  9. data/Rakefile +1 -0
  10. data/db/migrations/001_create_initial_tables.rb +96 -0
  11. data/db/migrations/002_create_job_results.rb +39 -0
  12. data/desiru.db +0 -0
  13. data/desiru.gemspec +2 -5
  14. data/docs/background_processing_roadmap.md +87 -0
  15. data/docs/job_scheduling.md +167 -0
  16. data/dspy-analysis-swarm.yml +60 -0
  17. data/dspy-feature-analysis.md +121 -0
  18. data/examples/README.md +69 -0
  19. data/examples/api_with_persistence.rb +122 -0
  20. data/examples/assertions_example.rb +232 -0
  21. data/examples/async_processing.rb +2 -0
  22. data/examples/few_shot_learning.rb +1 -2
  23. data/examples/graphql_api.rb +4 -2
  24. data/examples/graphql_integration.rb +3 -3
  25. data/examples/graphql_optimization_summary.md +143 -0
  26. data/examples/graphql_performance_benchmark.rb +247 -0
  27. data/examples/persistence_example.rb +102 -0
  28. data/examples/react_agent.rb +203 -0
  29. data/examples/rest_api.rb +173 -0
  30. data/examples/rest_api_advanced.rb +333 -0
  31. data/examples/scheduled_job_example.rb +116 -0
  32. data/examples/simple_qa.rb +1 -2
  33. data/examples/sinatra_api.rb +109 -0
  34. data/examples/typed_signatures.rb +1 -2
  35. data/graphql_optimization_summary.md +53 -0
  36. data/lib/desiru/api/grape_integration.rb +284 -0
  37. data/lib/desiru/api/persistence_middleware.rb +148 -0
  38. data/lib/desiru/api/sinatra_integration.rb +217 -0
  39. data/lib/desiru/api.rb +42 -0
  40. data/lib/desiru/assertions.rb +74 -0
  41. data/lib/desiru/async_status.rb +65 -0
  42. data/lib/desiru/cache.rb +1 -1
  43. data/lib/desiru/configuration.rb +2 -1
  44. data/lib/desiru/errors.rb +160 -0
  45. data/lib/desiru/field.rb +17 -14
  46. data/lib/desiru/graphql/batch_loader.rb +85 -0
  47. data/lib/desiru/graphql/data_loader.rb +242 -75
  48. data/lib/desiru/graphql/enum_builder.rb +75 -0
  49. data/lib/desiru/graphql/executor.rb +37 -4
  50. data/lib/desiru/graphql/schema_generator.rb +62 -158
  51. data/lib/desiru/graphql/type_builder.rb +138 -0
  52. data/lib/desiru/graphql/type_cache_warmer.rb +91 -0
  53. data/lib/desiru/jobs/async_predict.rb +1 -1
  54. data/lib/desiru/jobs/base.rb +67 -0
  55. data/lib/desiru/jobs/batch_processor.rb +6 -6
  56. data/lib/desiru/jobs/retriable.rb +119 -0
  57. data/lib/desiru/jobs/retry_strategies.rb +169 -0
  58. data/lib/desiru/jobs/scheduler.rb +219 -0
  59. data/lib/desiru/jobs/webhook_notifier.rb +242 -0
  60. data/lib/desiru/models/anthropic.rb +164 -0
  61. data/lib/desiru/models/base.rb +37 -3
  62. data/lib/desiru/models/open_ai.rb +151 -0
  63. data/lib/desiru/models/open_router.rb +161 -0
  64. data/lib/desiru/module.rb +59 -9
  65. data/lib/desiru/modules/chain_of_thought.rb +3 -3
  66. data/lib/desiru/modules/majority.rb +51 -0
  67. data/lib/desiru/modules/multi_chain_comparison.rb +204 -0
  68. data/lib/desiru/modules/predict.rb +8 -1
  69. data/lib/desiru/modules/program_of_thought.rb +139 -0
  70. data/lib/desiru/modules/react.rb +273 -0
  71. data/lib/desiru/modules/retrieve.rb +4 -2
  72. data/lib/desiru/optimizers/base.rb +2 -4
  73. data/lib/desiru/optimizers/bootstrap_few_shot.rb +2 -2
  74. data/lib/desiru/optimizers/copro.rb +268 -0
  75. data/lib/desiru/optimizers/knn_few_shot.rb +185 -0
  76. data/lib/desiru/persistence/database.rb +71 -0
  77. data/lib/desiru/persistence/models/api_request.rb +38 -0
  78. data/lib/desiru/persistence/models/job_result.rb +138 -0
  79. data/lib/desiru/persistence/models/module_execution.rb +37 -0
  80. data/lib/desiru/persistence/models/optimization_result.rb +28 -0
  81. data/lib/desiru/persistence/models/training_example.rb +25 -0
  82. data/lib/desiru/persistence/models.rb +11 -0
  83. data/lib/desiru/persistence/repositories/api_request_repository.rb +98 -0
  84. data/lib/desiru/persistence/repositories/base_repository.rb +77 -0
  85. data/lib/desiru/persistence/repositories/job_result_repository.rb +116 -0
  86. data/lib/desiru/persistence/repositories/module_execution_repository.rb +85 -0
  87. data/lib/desiru/persistence/repositories/optimization_result_repository.rb +67 -0
  88. data/lib/desiru/persistence/repositories/training_example_repository.rb +102 -0
  89. data/lib/desiru/persistence/repository.rb +29 -0
  90. data/lib/desiru/persistence/setup.rb +77 -0
  91. data/lib/desiru/persistence.rb +49 -0
  92. data/lib/desiru/registry.rb +3 -5
  93. data/lib/desiru/signature.rb +91 -24
  94. data/lib/desiru/version.rb +1 -1
  95. data/lib/desiru.rb +23 -8
  96. data/missing-features-analysis.md +192 -0
  97. metadata +63 -45
  98. data/lib/desiru/models/raix_adapter.rb +0 -210
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sequel'
4
+
5
+ module Desiru
6
+ module Persistence
7
+ # Setup and initialization for persistence layer
8
+ module Setup
9
+ @initialized = false
10
+
11
+ def self.initialized?
12
+ @initialized
13
+ end
14
+
15
+ def self.initialize!(db_connection)
16
+ # Always reinitialize if the database connection has changed
17
+ return if @initialized && Sequel::Model.db == db_connection
18
+
19
+ # Ensure we have a valid connection
20
+ raise 'Database connection required' unless db_connection
21
+
22
+ # Create the base model with a specific database
23
+ Sequel::Model.db = db_connection
24
+
25
+ # Define the base model class
26
+ base_class = Class.new(Sequel::Model) do
27
+ # This is an abstract model - no table
28
+ def self.inherited(subclass)
29
+ super
30
+ subclass.plugin :timestamps, update_on_create: true
31
+ subclass.plugin :json_serializer
32
+ subclass.plugin :validation_helpers
33
+ end
34
+
35
+ # Helper to create JSON columns that work across databases
36
+ def self.json_column(name)
37
+ case db.adapter_scheme
38
+ when :postgres
39
+ # PostgreSQL has native JSON support
40
+ nil # No special handling needed
41
+ when :sqlite, :mysql, :mysql2
42
+ # SQLite and MySQL store JSON as text
43
+ plugin :serialization
44
+ serialize_attributes :json, name
45
+ end
46
+ end
47
+ end
48
+
49
+ # Make it unrestricted so it doesn't look for a table
50
+ base_class.unrestrict_primary_key
51
+
52
+ # Set the Base constant
53
+ Models.send(:remove_const, :Base) if Models.const_defined?(:Base)
54
+ Models.const_set(:Base, base_class)
55
+
56
+ # Remove existing model constants to force reload
57
+ %i[ModuleExecution ApiRequest OptimizationResult TrainingExample JobResult].each do |model|
58
+ Models.send(:remove_const, model) if Models.const_defined?(model)
59
+ end
60
+
61
+ # Now load all model classes - use load instead of require to force re-execution
62
+ load File.expand_path('models/module_execution.rb', __dir__)
63
+ load File.expand_path('models/api_request.rb', __dir__)
64
+ load File.expand_path('models/optimization_result.rb', __dir__)
65
+ load File.expand_path('models/training_example.rb', __dir__)
66
+ load File.expand_path('models/job_result.rb', __dir__)
67
+
68
+ # Setup repositories
69
+ require_relative 'repository'
70
+ Repository.setup!
71
+
72
+ @initialized = true
73
+ true
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'persistence/database'
4
+ require_relative 'persistence/models'
5
+ require_relative 'persistence/repository'
6
+
7
+ module Desiru
8
+ # Database persistence layer for Desiru
9
+ module Persistence
10
+ class << self
11
+ attr_writer :database_url
12
+
13
+ def database_url
14
+ @database_url ||= ENV['DESIRU_DATABASE_URL'] || 'sqlite://desiru.db'
15
+ end
16
+
17
+ def connect!
18
+ Database.connect(database_url)
19
+ end
20
+
21
+ def disconnect!
22
+ Database.disconnect
23
+ end
24
+
25
+ def migrate!
26
+ Database.migrate!
27
+ Repository.setup!
28
+ end
29
+
30
+ def repositories
31
+ @repositories ||= {}
32
+ end
33
+
34
+ def register_repository(name, repository)
35
+ repositories[name] = repository
36
+ end
37
+
38
+ def [](name)
39
+ repositories[name] || raise("Repository #{name} not found")
40
+ end
41
+
42
+ def enabled?
43
+ !Database.connection.nil?
44
+ rescue StandardError
45
+ false
46
+ end
47
+ end
48
+ end
49
+ end
@@ -32,11 +32,9 @@ module Desiru
32
32
  def get(name, version: nil)
33
33
  name = name.to_sym
34
34
 
35
- if version
36
- @module_versions[name][version] || raise(ModuleError, "Module #{name} v#{version} not found")
37
- else
38
- @modules[name] || raise(ModuleError, "Module #{name} not found")
39
- end
35
+ return @module_versions[name][version] || raise(ModuleError, "Module #{name} v#{version} not found") if version
36
+
37
+ @modules[name] || raise(ModuleError, "Module #{name} not found")
40
38
  end
41
39
 
42
40
  def list
@@ -4,10 +4,46 @@ module Desiru
4
4
  # Represents input/output specifications for modules
5
5
  # Supports DSL-style signature strings like "question -> answer"
6
6
  class Signature
7
+ # FieldWrapper provides a test-compatible interface for Field objects
8
+ class FieldWrapper
9
+ def initialize(field)
10
+ @field = field
11
+ end
12
+
13
+ def type
14
+ @field.type
15
+ end
16
+
17
+ def description
18
+ @field.description
19
+ end
20
+
21
+ def optional
22
+ @field.optional
23
+ end
24
+
25
+ def optional?
26
+ @field.optional?
27
+ end
28
+
29
+ def name
30
+ @field.name
31
+ end
32
+
33
+ def method_missing(method, *, &)
34
+ @field.send(method, *, &)
35
+ end
36
+
37
+ def respond_to_missing?(method, include_private = false)
38
+ @field.respond_to?(method, include_private)
39
+ end
40
+ end
41
+
7
42
  # FieldHash allows access by both string and symbol keys
8
43
  class FieldHash < Hash
9
44
  def [](key)
10
- super(key.to_sym)
45
+ field = super(key.to_sym)
46
+ field ? FieldWrapper.new(field) : nil
11
47
  end
12
48
 
13
49
  def []=(key, value)
@@ -18,12 +54,12 @@ module Desiru
18
54
  super.map(&:to_s)
19
55
  end
20
56
 
21
- def has_key?(key)
57
+ def key?(key)
22
58
  super(key.to_sym)
23
59
  end
24
60
 
25
- alias include? has_key?
26
- alias key? has_key?
61
+ alias include? key?
62
+ alias has_key? key?
27
63
  end
28
64
 
29
65
  attr_reader :raw_signature
@@ -51,7 +87,7 @@ module Desiru
51
87
  parse_signature!
52
88
  end
53
89
 
54
- def validate_inputs(inputs)
90
+ def valid_inputs?(inputs)
55
91
  missing = required_input_fields - inputs.keys.map(&:to_sym)
56
92
  raise SignatureError, "Missing required inputs: #{missing.join(', ')}" if missing.any?
57
93
 
@@ -60,13 +96,13 @@ module Desiru
60
96
  next unless field
61
97
 
62
98
  # Field.validate will raise ValidationError if validation fails
63
- field.validate(value)
99
+ field.valid?(value)
64
100
  end
65
101
 
66
102
  true
67
103
  end
68
104
 
69
- def validate_outputs(outputs)
105
+ def valid_outputs?(outputs)
70
106
  missing = required_output_fields - outputs.keys.map(&:to_sym)
71
107
  raise ValidationError, "Missing required outputs: #{missing.join(', ')}" if missing.any?
72
108
 
@@ -75,7 +111,7 @@ module Desiru
75
111
  next unless field
76
112
 
77
113
  # Field.validate will raise ValidationError if validation fails
78
- field.validate(value)
114
+ field.valid?(value)
79
115
  end
80
116
 
81
117
  true
@@ -138,7 +174,7 @@ module Desiru
138
174
  bracket_count += 1
139
175
  elsif char == ']'
140
176
  bracket_count -= 1
141
- elsif char == ',' && bracket_count == 0
177
+ elsif char == ',' && bracket_count.zero?
142
178
  fields << current_field.strip
143
179
  current_field = String.new
144
180
  next
@@ -155,23 +191,37 @@ module Desiru
155
191
  optional = name.end_with?('?') || type_info.include?('?')
156
192
  # Clean field name by removing trailing ?
157
193
  name = name.gsub(/\?$/, '')
194
+
195
+ # Extract description if present (in quotes at the end)
196
+ description = nil
197
+ # Look for description only after the type definition, not within brackets
198
+ if type_info =~ /^([^"]+?)\s+"([^"]+)"$/
199
+ type_info = ::Regexp.last_match(1).strip
200
+ description = ::Regexp.last_match(2)
201
+ end
202
+
158
203
  # Remove optional marker before parsing type
159
204
  clean_type_info = type_info.gsub('?', '').strip
160
205
  type_data = parse_type(clean_type_info)
206
+ # Store the original type string for tests
207
+ type_data[:original_type] = clean_type_info
161
208
  else
162
209
  name = field_str
163
210
  # Check if field name ends with ?
164
211
  optional = name.end_with?('?')
165
212
  name = name.gsub(/\?$/, '')
166
- type_data = { type: :string }
213
+ type_data = { type: :string, original_type: 'string' }
214
+ description = nil
167
215
  end
168
216
 
169
- description = @descriptions[name.to_sym] || @descriptions[name.to_s]
217
+ # Use extracted description or fallback to descriptions hash
218
+ description ||= @descriptions[name.to_sym] || @descriptions[name.to_s]
170
219
 
171
220
  # Create field with parsed type data
172
221
  field_args = {
173
222
  description: description,
174
- optional: optional
223
+ optional: optional,
224
+ original_type: type_data[:original_type]
175
225
  }
176
226
 
177
227
  # Add literal values if present
@@ -209,17 +259,17 @@ module Desiru
209
259
  bracket_count += 1
210
260
  elsif char == ']'
211
261
  bracket_count -= 1
212
- if bracket_count == 0
262
+ if bracket_count.zero?
213
263
  end_index = index
214
264
  break
215
265
  end
216
266
  end
217
267
  end
218
268
 
219
- if end_index > 0
269
+ if end_index.positive?
220
270
  literal_content = type_string[8...end_index] # Extract content between 'Literal[' and ']'
221
271
  values = parse_literal_values(literal_content)
222
- return { type: :literal, literal_values: values }
272
+ return { type: :literal, literal_values: values, original_type: type_string }
223
273
  end
224
274
  end
225
275
 
@@ -237,33 +287,36 @@ module Desiru
237
287
  bracket_count += 1
238
288
  elsif char == ']'
239
289
  bracket_count -= 1
240
- if bracket_count == 0
290
+ if bracket_count.zero?
241
291
  end_index = index
242
292
  break
243
293
  end
244
294
  end
245
295
  end
246
296
 
247
- if end_index > 0
297
+ if end_index.positive?
248
298
  element_type_str = type_string[(start_index + 1)...end_index]
249
299
  element_type_data = parse_type(element_type_str) # Recursive for nested types
250
- return { type: :list, element_type: element_type_data }
300
+ return { type: :list, element_type: element_type_data, original_type: type_string }
251
301
  end
252
302
  end
253
303
 
254
304
  # Handle Union types (for future implementation)
255
305
  if type_string.start_with?('Union[')
256
306
  # Placeholder for union type parsing
257
- return { type: :union, union_types: [] } # To be implemented
307
+ return { type: :union, union_types: [], original_type: type_string } # To be implemented
258
308
  end
259
309
 
260
310
  # Handle basic types
261
311
  # First check if it's a list/array with simple element type (e.g., list[str])
262
312
  if type_string.downcase.start_with?('list[', 'array[')
263
313
  # Even if we couldn't parse the brackets properly above, it's still a list
264
- return { type: :list }
314
+ return { type: :list, original_type: type_string }
265
315
  end
266
316
 
317
+ # Handle dict/dictionary types with special parsing
318
+ return { type: :hash, original_type: type_string } if type_string.downcase.start_with?('dict[', 'dictionary[')
319
+
267
320
  clean_type = type_string.gsub(/[?\[\]]/, '').downcase
268
321
  type_sym = case clean_type
269
322
  when 'str', 'string' then :string
@@ -275,7 +328,7 @@ module Desiru
275
328
  else clean_type.to_sym
276
329
  end
277
330
 
278
- { type: type_sym }
331
+ { type: type_sym, original_type: type_string }
279
332
  end
280
333
 
281
334
  def parse_literal_values(literal_content)
@@ -289,16 +342,23 @@ module Desiru
289
342
  if !in_quotes && ['"', "'"].include?(char)
290
343
  in_quotes = true
291
344
  quote_char = char
345
+ current_value << char # Include the quote in the value
292
346
  elsif in_quotes && char == quote_char
293
347
  # Check if it's escaped
294
- if index > 0 && literal_content[index - 1] != '\\'
348
+ if index.positive? && literal_content[index - 1] != '\\'
295
349
  in_quotes = false
350
+ current_value << char # Include the closing quote
296
351
  quote_char = nil
297
352
  else
298
353
  current_value << char
299
354
  end
300
355
  elsif !in_quotes && char == ','
301
- values << current_value.strip.gsub(/^['"]|['"]$/, '')
356
+ val = current_value.strip
357
+ # Remove outer quotes if present
358
+ if (val.start_with?('"') && val.end_with?('"')) || (val.start_with?("'") && val.end_with?("'"))
359
+ val = val[1...-1]
360
+ end
361
+ values << val
302
362
  current_value = String.new
303
363
  else
304
364
  current_value << char
@@ -306,7 +366,14 @@ module Desiru
306
366
  end
307
367
 
308
368
  # Add the last value
309
- values << current_value.strip.gsub(/^['"]|['"]$/, '') unless current_value.empty?
369
+ unless current_value.empty?
370
+ val = current_value.strip
371
+ # Remove outer quotes if present
372
+ if (val.start_with?('"') && val.end_with?('"')) || (val.start_with?("'") && val.end_with?("'"))
373
+ val = val[1...-1]
374
+ end
375
+ values << val
376
+ end
310
377
 
311
378
  values
312
379
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Desiru
4
- VERSION = '0.1.0'
4
+ VERSION = '0.1.1'
5
5
  end
data/lib/desiru.rb CHANGED
@@ -5,13 +5,6 @@ require 'singleton'
5
5
 
6
6
  # Main namespace for Desiru - Declarative Self-Improving Ruby
7
7
  module Desiru
8
- class Error < StandardError; end
9
- class ConfigurationError < Error; end
10
- class SignatureError < Error; end
11
- class ModuleError < Error; end
12
- class ValidationError < Error; end
13
- class TimeoutError < Error; end
14
-
15
8
  class << self
16
9
  attr_writer :configuration
17
10
 
@@ -26,14 +19,20 @@ module Desiru
26
19
  def reset_configuration!
27
20
  @configuration = Configuration.new
28
21
  end
22
+
23
+ def logger
24
+ configuration.logger
25
+ end
29
26
  end
30
27
  end
31
28
 
32
29
  # Core components
33
30
  require_relative 'desiru/version'
31
+ require_relative 'desiru/errors'
34
32
  require_relative 'desiru/configuration'
35
33
  require_relative 'desiru/field'
36
34
  require_relative 'desiru/signature'
35
+ require_relative 'desiru/assertions'
37
36
  require_relative 'desiru/module'
38
37
  require_relative 'desiru/program'
39
38
  require_relative 'desiru/registry'
@@ -41,23 +40,39 @@ require_relative 'desiru/cache'
41
40
 
42
41
  # Model adapters
43
42
  require_relative 'desiru/models/base'
44
- require_relative 'desiru/models/raix_adapter'
43
+ require_relative 'desiru/models/anthropic'
44
+ require_relative 'desiru/models/open_ai'
45
+ require_relative 'desiru/models/open_router'
45
46
 
46
47
  # Built-in modules
47
48
  require_relative 'desiru/modules/predict'
48
49
  require_relative 'desiru/modules/chain_of_thought'
49
50
  require_relative 'desiru/modules/retrieve'
51
+ require_relative 'desiru/modules/react'
52
+ require_relative 'desiru/modules/program_of_thought'
53
+ require_relative 'desiru/modules/multi_chain_comparison'
54
+ require_relative 'desiru/modules/majority'
50
55
 
51
56
  # Optimizers
52
57
  require_relative 'desiru/optimizers/base'
53
58
  require_relative 'desiru/optimizers/bootstrap_few_shot'
59
+ require_relative 'desiru/optimizers/knn_few_shot'
60
+ require_relative 'desiru/optimizers/copro'
54
61
 
55
62
  # Background jobs
63
+ require_relative 'desiru/async_capable'
64
+ require_relative 'desiru/async_status'
56
65
  require_relative 'desiru/jobs/base'
57
66
  require_relative 'desiru/jobs/async_predict'
58
67
  require_relative 'desiru/jobs/batch_processor'
68
+
69
+ # API integrations
70
+ require_relative 'desiru/api'
59
71
  require_relative 'desiru/jobs/optimizer_job'
60
72
 
73
+ # Persistence layer
74
+ require_relative 'desiru/persistence'
75
+
61
76
  # GraphQL integration (optional, requires 'graphql' gem)
62
77
  begin
63
78
  require 'graphql'
@@ -0,0 +1,192 @@
1
+ # Missing DSPy Features in Desiru
2
+
3
+ Based on analysis of Python DSPy vs current Desiru implementation.
4
+
5
+ ## Missing Modules
6
+
7
+ ### 1. **ProgramOfThought**
8
+ - Generates executable code instead of natural language
9
+ - Critical for math/logic problems requiring computation
10
+ - Uses code execution environment
11
+
12
+ ### 2. **MultiChainComparison**
13
+ - Runs multiple ChainOfThought instances
14
+ - Compares and selects best reasoning path
15
+ - Useful for complex reasoning tasks
16
+
17
+ ### 3. **BestOfN**
18
+ - Samples N outputs from any module
19
+ - Selects best based on metric/scoring
20
+ - Simple but effective ensemble technique
21
+
22
+ ### 4. **Refine**
23
+ - Iterative refinement of outputs
24
+ - Takes initial output and improves it
25
+ - Works with constraints and feedback
26
+
27
+ ### 5. **ChainOfThoughtWithHint**
28
+ - ChainOfThought variant with guided hints
29
+ - Provides additional context for reasoning
30
+ - Better control over reasoning direction
31
+
32
+ ## Missing Optimizers
33
+
34
+ ### 1. **MIPROv2**
35
+ - Most advanced DSPy optimizer
36
+ - Uses Bayesian optimization
37
+ - Optimizes both instructions and demonstrations
38
+ - Significantly better than BootstrapFewShot
39
+
40
+ ### 2. **COPRO (Collaborative Prompt Optimization)**
41
+ - Coordinates multiple optimization strategies
42
+ - Collaborative approach to prompt engineering
43
+ - Handles complex multi-module programs
44
+
45
+ ### 3. **BootstrapFewShotWithRandomSearch**
46
+ - Enhanced version of BootstrapFewShot
47
+ - Adds hyperparameter random search
48
+ - Better exploration of optimization space
49
+
50
+ ### 4. **LabeledFewShot**
51
+ - Simple optimizer using provided examples
52
+ - No bootstrapping, just uses given labels
53
+ - Good baseline optimizer
54
+
55
+ ### 5. **KNNFewShot**
56
+ - K-nearest neighbor example selection
57
+ - Dynamic example selection based on input
58
+ - Better than static few-shot examples
59
+
60
+ ### 6. **BootstrapFinetune**
61
+ - Generates training data for model finetuning
62
+ - Alternative to prompt optimization
63
+ - For when you can modify the model
64
+
65
+ ### 7. **Ensemble**
66
+ - Combines multiple optimized programs
67
+ - Voting or weighted combination
68
+ - Improved robustness
69
+
70
+ ### 8. **SignatureOptimizer**
71
+ - Optimizes signature descriptions themselves
72
+ - Rewrites field descriptions for clarity
73
+ - Meta-optimization approach
74
+
75
+ ### 9. **BayesianSignatureOptimizer**
76
+ - Bayesian approach to signature optimization
77
+ - More sophisticated than SignatureOptimizer
78
+ - Better exploration of description space
79
+
80
+ ## Missing Core Features
81
+
82
+ ### 1. **Example and Prediction Classes**
83
+ - Special data containers with utilities
84
+ - Flexible field access (dot notation)
85
+ - Completion tracking for Predictions
86
+ - Integration with trace system
87
+
88
+ ### 2. **Typed Predictors**
89
+ - Type-safe field handling
90
+ - Pydantic integration in Python
91
+ - Automatic validation and parsing
92
+ - Better IDE support
93
+
94
+ ### 3. **Suggestions (Soft Constraints)**
95
+ - Unlike Assertions (hard constraints)
96
+ - Guide optimization without failing
97
+ - Used during compilation phase
98
+
99
+ ### 4. **Trace Collection System**
100
+ - Detailed execution tracking
101
+ - Records all LLM calls and transformations
102
+ - Critical for optimization
103
+ - Enables debugging and analysis
104
+
105
+ ### 5. **Compilation Infrastructure**
106
+ - Full compilation pipeline
107
+ - Trace filtering and selection
108
+ - Demonstration ranking
109
+ - Parameter update mechanism
110
+
111
+ ### 6. **Instruction Generation**
112
+ - Some optimizers generate custom instructions
113
+ - Not just examples but rewritten prompts
114
+ - Adaptive to task requirements
115
+
116
+ ## Missing Utilities & Capabilities
117
+
118
+ ### 1. **Data Loaders**
119
+ - HuggingFace dataset integration
120
+ - CSV/JSON loaders with DSPy formatting
121
+ - Train/dev/test split utilities
122
+ - Batch processing support
123
+
124
+ ### 2. **LLM Provider Abstractions**
125
+ - Unified interface for multiple providers
126
+ - Beyond just OpenAI (Anthropic, Cohere, etc.)
127
+ - Local model support (Ollama, etc.)
128
+ - Token counting and cost tracking
129
+
130
+ ### 3. **Advanced Metrics**
131
+ - F1, BLEU, ROUGE scores
132
+ - LLM-as-Judge implementations
133
+ - Composite metric builders
134
+ - Batch evaluation utilities
135
+
136
+ ### 4. **Streaming Support**
137
+ - Token-by-token streaming
138
+ - Progressive output display
139
+ - Useful for long generations
140
+
141
+ ### 5. **Serialization**
142
+ - Save/load compiled programs
143
+ - Export optimized parameters
144
+ - Model versioning support
145
+
146
+ ### 6. **Settings Management**
147
+ - Global configuration system
148
+ - Provider-specific settings
149
+ - Experiment tracking
150
+
151
+ ### 7. **Advanced Caching**
152
+ - Request deduplication
153
+ - Semantic caching options
154
+ - Cache invalidation strategies
155
+
156
+ ### 8. **Parallel/Async Execution**
157
+ - Batch processing optimizations
158
+ - Concurrent module execution
159
+ - Async compilation runs
160
+
161
+ ### 9. **ColBERTv2 Integration**
162
+ - Advanced retrieval model
163
+ - Better than basic vector search
164
+ - Optimized for retrieval tasks
165
+
166
+ ### 10. **Logging and Debugging**
167
+ - Detailed trace visualization
168
+ - Cost tracking and reporting
169
+ - Performance profiling
170
+
171
+ ## Priority Recommendations
172
+
173
+ ### High Priority (Core Functionality)
174
+ 1. Example/Prediction classes
175
+ 2. Trace collection system
176
+ 3. MIPROv2 optimizer
177
+ 4. ProgramOfThought module
178
+ 5. Compilation infrastructure
179
+
180
+ ### Medium Priority (Enhanced Capabilities)
181
+ 1. MultiChainComparison
182
+ 2. BestOfN module
183
+ 3. Typed predictors
184
+ 4. Additional optimizers (COPRO, KNNFewShot)
185
+ 5. Data loaders
186
+
187
+ ### Low Priority (Nice to Have)
188
+ 1. Advanced metrics
189
+ 2. Streaming support
190
+ 3. ColBERTv2 integration
191
+ 4. Ensemble optimizer
192
+ 5. Signature optimizers