desiru 0.1.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 +7 -0
- data/.rspec +1 -0
- data/.rubocop.yml +55 -0
- data/CLAUDE.md +22 -0
- data/Gemfile +36 -0
- data/Gemfile.lock +255 -0
- data/LICENSE +21 -0
- data/README.md +343 -0
- data/Rakefile +18 -0
- data/desiru.gemspec +44 -0
- data/examples/README.md +55 -0
- data/examples/async_processing.rb +135 -0
- data/examples/few_shot_learning.rb +66 -0
- data/examples/graphql_api.rb +190 -0
- data/examples/graphql_integration.rb +114 -0
- data/examples/rag_retrieval.rb +80 -0
- data/examples/simple_qa.rb +31 -0
- data/examples/typed_signatures.rb +45 -0
- data/lib/desiru/async_capable.rb +170 -0
- data/lib/desiru/cache.rb +116 -0
- data/lib/desiru/configuration.rb +40 -0
- data/lib/desiru/field.rb +171 -0
- data/lib/desiru/graphql/data_loader.rb +210 -0
- data/lib/desiru/graphql/executor.rb +115 -0
- data/lib/desiru/graphql/schema_generator.rb +301 -0
- data/lib/desiru/jobs/async_predict.rb +52 -0
- data/lib/desiru/jobs/base.rb +53 -0
- data/lib/desiru/jobs/batch_processor.rb +71 -0
- data/lib/desiru/jobs/optimizer_job.rb +45 -0
- data/lib/desiru/models/base.rb +112 -0
- data/lib/desiru/models/raix_adapter.rb +210 -0
- data/lib/desiru/module.rb +204 -0
- data/lib/desiru/modules/chain_of_thought.rb +106 -0
- data/lib/desiru/modules/predict.rb +142 -0
- data/lib/desiru/modules/retrieve.rb +199 -0
- data/lib/desiru/optimizers/base.rb +130 -0
- data/lib/desiru/optimizers/bootstrap_few_shot.rb +212 -0
- data/lib/desiru/program.rb +106 -0
- data/lib/desiru/registry.rb +74 -0
- data/lib/desiru/signature.rb +322 -0
- data/lib/desiru/version.rb +5 -0
- data/lib/desiru.rb +67 -0
- metadata +184 -0
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'singleton'
|
4
|
+
|
5
|
+
module Desiru
|
6
|
+
# Module registry for managing and discovering Desiru modules
|
7
|
+
# Implements service locator pattern for module management
|
8
|
+
class Registry
|
9
|
+
include Singleton
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@modules = {}
|
13
|
+
@module_versions = Hash.new { |h, k| h[k] = {} }
|
14
|
+
@module_metadata = {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def register(name, klass, version: '1.0.0', metadata: {})
|
18
|
+
validate_module!(klass)
|
19
|
+
|
20
|
+
name = name.to_sym
|
21
|
+
@modules[name] = klass
|
22
|
+
@module_versions[name][version] = klass
|
23
|
+
@module_metadata[name] = metadata.merge(
|
24
|
+
registered_at: Time.now,
|
25
|
+
version: version,
|
26
|
+
class: klass.name
|
27
|
+
)
|
28
|
+
|
29
|
+
Desiru.configuration.logger&.info("Registered module: #{name} v#{version}")
|
30
|
+
end
|
31
|
+
|
32
|
+
def get(name, version: nil)
|
33
|
+
name = name.to_sym
|
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
|
40
|
+
end
|
41
|
+
|
42
|
+
def list
|
43
|
+
@modules.keys
|
44
|
+
end
|
45
|
+
|
46
|
+
def metadata(name)
|
47
|
+
@module_metadata[name.to_sym]
|
48
|
+
end
|
49
|
+
|
50
|
+
def unregister(name)
|
51
|
+
name = name.to_sym
|
52
|
+
@modules.delete(name)
|
53
|
+
@module_versions.delete(name)
|
54
|
+
@module_metadata.delete(name)
|
55
|
+
end
|
56
|
+
|
57
|
+
def clear!
|
58
|
+
@modules.clear
|
59
|
+
@module_versions.clear
|
60
|
+
@module_metadata.clear
|
61
|
+
end
|
62
|
+
|
63
|
+
private
|
64
|
+
|
65
|
+
def validate_module!(klass)
|
66
|
+
raise ModuleError, 'Module must be a class' unless klass.respond_to?(:new)
|
67
|
+
|
68
|
+
# Check if it's a Desiru module
|
69
|
+
return if klass.ancestors.include?(Desiru::Module)
|
70
|
+
|
71
|
+
raise ModuleError, 'Module must inherit from Desiru::Module'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,322 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Desiru
|
4
|
+
# Represents input/output specifications for modules
|
5
|
+
# Supports DSL-style signature strings like "question -> answer"
|
6
|
+
class Signature
|
7
|
+
# FieldHash allows access by both string and symbol keys
|
8
|
+
class FieldHash < Hash
|
9
|
+
def [](key)
|
10
|
+
super(key.to_sym)
|
11
|
+
end
|
12
|
+
|
13
|
+
def []=(key, value)
|
14
|
+
super(key.to_sym, value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def keys
|
18
|
+
super.map(&:to_s)
|
19
|
+
end
|
20
|
+
|
21
|
+
def has_key?(key)
|
22
|
+
super(key.to_sym)
|
23
|
+
end
|
24
|
+
|
25
|
+
alias include? has_key?
|
26
|
+
alias key? has_key?
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :raw_signature
|
30
|
+
|
31
|
+
def input_fields
|
32
|
+
@input_fields_wrapper
|
33
|
+
end
|
34
|
+
|
35
|
+
def output_fields
|
36
|
+
@output_fields_wrapper
|
37
|
+
end
|
38
|
+
|
39
|
+
# Aliases for test compatibility
|
40
|
+
alias inputs input_fields
|
41
|
+
alias outputs output_fields
|
42
|
+
|
43
|
+
def initialize(signature_string, descriptions: {})
|
44
|
+
@raw_signature = signature_string
|
45
|
+
@descriptions = descriptions
|
46
|
+
@input_fields = {}
|
47
|
+
@output_fields = {}
|
48
|
+
@input_fields_wrapper = FieldHash.new
|
49
|
+
@output_fields_wrapper = FieldHash.new
|
50
|
+
|
51
|
+
parse_signature!
|
52
|
+
end
|
53
|
+
|
54
|
+
def validate_inputs(inputs)
|
55
|
+
missing = required_input_fields - inputs.keys.map(&:to_sym)
|
56
|
+
raise SignatureError, "Missing required inputs: #{missing.join(', ')}" if missing.any?
|
57
|
+
|
58
|
+
inputs.each do |name, value|
|
59
|
+
field = @input_fields[name.to_sym]
|
60
|
+
next unless field
|
61
|
+
|
62
|
+
# Field.validate will raise ValidationError if validation fails
|
63
|
+
field.validate(value)
|
64
|
+
end
|
65
|
+
|
66
|
+
true
|
67
|
+
end
|
68
|
+
|
69
|
+
def validate_outputs(outputs)
|
70
|
+
missing = required_output_fields - outputs.keys.map(&:to_sym)
|
71
|
+
raise ValidationError, "Missing required outputs: #{missing.join(', ')}" if missing.any?
|
72
|
+
|
73
|
+
outputs.each do |name, value|
|
74
|
+
field = @output_fields[name.to_sym]
|
75
|
+
next unless field
|
76
|
+
|
77
|
+
# Field.validate will raise ValidationError if validation fails
|
78
|
+
field.validate(value)
|
79
|
+
end
|
80
|
+
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
def coerce_inputs(inputs)
|
85
|
+
result = {}
|
86
|
+
|
87
|
+
@input_fields.each do |name, field|
|
88
|
+
value = inputs[name] || inputs[name.to_s]
|
89
|
+
result[name] = field.coerce(value)
|
90
|
+
end
|
91
|
+
|
92
|
+
result
|
93
|
+
end
|
94
|
+
|
95
|
+
def coerce_outputs(outputs)
|
96
|
+
result = {}
|
97
|
+
|
98
|
+
@output_fields.each do |name, field|
|
99
|
+
value = outputs[name] || outputs[name.to_s]
|
100
|
+
result[name] = field.coerce(value)
|
101
|
+
end
|
102
|
+
|
103
|
+
result
|
104
|
+
end
|
105
|
+
|
106
|
+
def to_h
|
107
|
+
{
|
108
|
+
signature: raw_signature,
|
109
|
+
inputs: @input_fields.transform_values(&:to_h),
|
110
|
+
outputs: @output_fields.transform_values(&:to_h)
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_s
|
115
|
+
raw_signature
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
def parse_signature!
|
121
|
+
parts = raw_signature.split('->').map(&:strip)
|
122
|
+
raise ArgumentError, "Invalid signature format: #{raw_signature}" unless parts.size == 2
|
123
|
+
|
124
|
+
parse_fields(parts[0], @input_fields)
|
125
|
+
parse_fields(parts[1], @output_fields)
|
126
|
+
end
|
127
|
+
|
128
|
+
def parse_fields(fields_string, target_hash)
|
129
|
+
return if fields_string.empty?
|
130
|
+
|
131
|
+
# Split fields properly, handling commas inside brackets
|
132
|
+
fields = []
|
133
|
+
current_field = String.new
|
134
|
+
bracket_count = 0
|
135
|
+
|
136
|
+
fields_string.chars.each do |char|
|
137
|
+
if char == '['
|
138
|
+
bracket_count += 1
|
139
|
+
elsif char == ']'
|
140
|
+
bracket_count -= 1
|
141
|
+
elsif char == ',' && bracket_count == 0
|
142
|
+
fields << current_field.strip
|
143
|
+
current_field = String.new
|
144
|
+
next
|
145
|
+
end
|
146
|
+
current_field << char
|
147
|
+
end
|
148
|
+
fields << current_field.strip unless current_field.empty?
|
149
|
+
|
150
|
+
fields.each do |field_str|
|
151
|
+
# Parse field with type annotation
|
152
|
+
if field_str.include?(':')
|
153
|
+
name, type_info = field_str.split(':', 2).map(&:strip)
|
154
|
+
# Check for optional marker on field name or type
|
155
|
+
optional = name.end_with?('?') || type_info.include?('?')
|
156
|
+
# Clean field name by removing trailing ?
|
157
|
+
name = name.gsub(/\?$/, '')
|
158
|
+
# Remove optional marker before parsing type
|
159
|
+
clean_type_info = type_info.gsub('?', '').strip
|
160
|
+
type_data = parse_type(clean_type_info)
|
161
|
+
else
|
162
|
+
name = field_str
|
163
|
+
# Check if field name ends with ?
|
164
|
+
optional = name.end_with?('?')
|
165
|
+
name = name.gsub(/\?$/, '')
|
166
|
+
type_data = { type: :string }
|
167
|
+
end
|
168
|
+
|
169
|
+
description = @descriptions[name.to_sym] || @descriptions[name.to_s]
|
170
|
+
|
171
|
+
# Create field with parsed type data
|
172
|
+
field_args = {
|
173
|
+
description: description,
|
174
|
+
optional: optional
|
175
|
+
}
|
176
|
+
|
177
|
+
# Add literal values if present
|
178
|
+
field_args[:literal_values] = type_data[:literal_values] if type_data[:literal_values]
|
179
|
+
|
180
|
+
# Add element type for typed arrays
|
181
|
+
field_args[:element_type] = type_data[:element_type] if type_data[:element_type]
|
182
|
+
|
183
|
+
field = Field.new(
|
184
|
+
name,
|
185
|
+
type_data[:type],
|
186
|
+
**field_args
|
187
|
+
)
|
188
|
+
|
189
|
+
target_hash[name.to_sym] = field
|
190
|
+
|
191
|
+
# Also add to wrapper for dual access
|
192
|
+
if target_hash == @input_fields
|
193
|
+
@input_fields_wrapper[name.to_sym] = field
|
194
|
+
elsif target_hash == @output_fields
|
195
|
+
@output_fields_wrapper[name.to_sym] = field
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
def parse_type(type_string)
|
201
|
+
# Handle Literal types - need to match balanced brackets
|
202
|
+
if type_string.start_with?('Literal[')
|
203
|
+
# Find the matching closing bracket
|
204
|
+
bracket_count = 0
|
205
|
+
end_index = 0
|
206
|
+
|
207
|
+
type_string.chars.each_with_index do |char, index|
|
208
|
+
if char == '['
|
209
|
+
bracket_count += 1
|
210
|
+
elsif char == ']'
|
211
|
+
bracket_count -= 1
|
212
|
+
if bracket_count == 0
|
213
|
+
end_index = index
|
214
|
+
break
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
if end_index > 0
|
220
|
+
literal_content = type_string[8...end_index] # Extract content between 'Literal[' and ']'
|
221
|
+
values = parse_literal_values(literal_content)
|
222
|
+
return { type: :literal, literal_values: values }
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# Handle List/Array types with element types
|
227
|
+
if type_string.start_with?('List[', 'Array[')
|
228
|
+
# Find the matching closing bracket
|
229
|
+
bracket_count = 0
|
230
|
+
end_index = 0
|
231
|
+
start_index = type_string.index('[')
|
232
|
+
|
233
|
+
type_string.chars.each_with_index do |char, index|
|
234
|
+
next if index < start_index
|
235
|
+
|
236
|
+
if char == '['
|
237
|
+
bracket_count += 1
|
238
|
+
elsif char == ']'
|
239
|
+
bracket_count -= 1
|
240
|
+
if bracket_count == 0
|
241
|
+
end_index = index
|
242
|
+
break
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
if end_index > 0
|
248
|
+
element_type_str = type_string[(start_index + 1)...end_index]
|
249
|
+
element_type_data = parse_type(element_type_str) # Recursive for nested types
|
250
|
+
return { type: :list, element_type: element_type_data }
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
254
|
+
# Handle Union types (for future implementation)
|
255
|
+
if type_string.start_with?('Union[')
|
256
|
+
# Placeholder for union type parsing
|
257
|
+
return { type: :union, union_types: [] } # To be implemented
|
258
|
+
end
|
259
|
+
|
260
|
+
# Handle basic types
|
261
|
+
# First check if it's a list/array with simple element type (e.g., list[str])
|
262
|
+
if type_string.downcase.start_with?('list[', 'array[')
|
263
|
+
# Even if we couldn't parse the brackets properly above, it's still a list
|
264
|
+
return { type: :list }
|
265
|
+
end
|
266
|
+
|
267
|
+
clean_type = type_string.gsub(/[?\[\]]/, '').downcase
|
268
|
+
type_sym = case clean_type
|
269
|
+
when 'str', 'string' then :string
|
270
|
+
when 'int', 'integer' then :int
|
271
|
+
when 'float', 'number', 'double' then :float
|
272
|
+
when 'bool', 'boolean' then :bool
|
273
|
+
when 'list', 'array' then :list
|
274
|
+
when 'hash', 'dict', 'dictionary' then :hash
|
275
|
+
else clean_type.to_sym
|
276
|
+
end
|
277
|
+
|
278
|
+
{ type: type_sym }
|
279
|
+
end
|
280
|
+
|
281
|
+
def parse_literal_values(literal_content)
|
282
|
+
# Parse comma-separated values, handling quoted strings
|
283
|
+
values = []
|
284
|
+
current_value = String.new
|
285
|
+
in_quotes = false
|
286
|
+
quote_char = nil
|
287
|
+
|
288
|
+
literal_content.each_char.with_index do |char, index|
|
289
|
+
if !in_quotes && ['"', "'"].include?(char)
|
290
|
+
in_quotes = true
|
291
|
+
quote_char = char
|
292
|
+
elsif in_quotes && char == quote_char
|
293
|
+
# Check if it's escaped
|
294
|
+
if index > 0 && literal_content[index - 1] != '\\'
|
295
|
+
in_quotes = false
|
296
|
+
quote_char = nil
|
297
|
+
else
|
298
|
+
current_value << char
|
299
|
+
end
|
300
|
+
elsif !in_quotes && char == ','
|
301
|
+
values << current_value.strip.gsub(/^['"]|['"]$/, '')
|
302
|
+
current_value = String.new
|
303
|
+
else
|
304
|
+
current_value << char
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
# Add the last value
|
309
|
+
values << current_value.strip.gsub(/^['"]|['"]$/, '') unless current_value.empty?
|
310
|
+
|
311
|
+
values
|
312
|
+
end
|
313
|
+
|
314
|
+
def required_input_fields
|
315
|
+
@input_fields.reject { |_, field| field.optional }.keys
|
316
|
+
end
|
317
|
+
|
318
|
+
def required_output_fields
|
319
|
+
@output_fields.reject { |_, field| field.optional }.keys
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
data/lib/desiru.rb
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'forwardable'
|
4
|
+
require 'singleton'
|
5
|
+
|
6
|
+
# Main namespace for Desiru - Declarative Self-Improving Ruby
|
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
|
+
class << self
|
16
|
+
attr_writer :configuration
|
17
|
+
|
18
|
+
def configuration
|
19
|
+
@configuration ||= Configuration.new
|
20
|
+
end
|
21
|
+
|
22
|
+
def configure
|
23
|
+
yield(configuration)
|
24
|
+
end
|
25
|
+
|
26
|
+
def reset_configuration!
|
27
|
+
@configuration = Configuration.new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Core components
|
33
|
+
require_relative 'desiru/version'
|
34
|
+
require_relative 'desiru/configuration'
|
35
|
+
require_relative 'desiru/field'
|
36
|
+
require_relative 'desiru/signature'
|
37
|
+
require_relative 'desiru/module'
|
38
|
+
require_relative 'desiru/program'
|
39
|
+
require_relative 'desiru/registry'
|
40
|
+
require_relative 'desiru/cache'
|
41
|
+
|
42
|
+
# Model adapters
|
43
|
+
require_relative 'desiru/models/base'
|
44
|
+
require_relative 'desiru/models/raix_adapter'
|
45
|
+
|
46
|
+
# Built-in modules
|
47
|
+
require_relative 'desiru/modules/predict'
|
48
|
+
require_relative 'desiru/modules/chain_of_thought'
|
49
|
+
require_relative 'desiru/modules/retrieve'
|
50
|
+
|
51
|
+
# Optimizers
|
52
|
+
require_relative 'desiru/optimizers/base'
|
53
|
+
require_relative 'desiru/optimizers/bootstrap_few_shot'
|
54
|
+
|
55
|
+
# Background jobs
|
56
|
+
require_relative 'desiru/jobs/base'
|
57
|
+
require_relative 'desiru/jobs/async_predict'
|
58
|
+
require_relative 'desiru/jobs/batch_processor'
|
59
|
+
require_relative 'desiru/jobs/optimizer_job'
|
60
|
+
|
61
|
+
# GraphQL integration (optional, requires 'graphql' gem)
|
62
|
+
begin
|
63
|
+
require 'graphql'
|
64
|
+
require_relative 'desiru/graphql/schema_generator'
|
65
|
+
rescue LoadError
|
66
|
+
# GraphQL integration is optional
|
67
|
+
end
|
metadata
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: desiru
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Obie Fernandez
|
8
|
+
bindir: exe
|
9
|
+
cert_chain: []
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
|
+
dependencies:
|
12
|
+
- !ruby/object:Gem::Dependency
|
13
|
+
name: forwardable
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - "~>"
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '1.3'
|
19
|
+
type: :runtime
|
20
|
+
prerelease: false
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
22
|
+
requirements:
|
23
|
+
- - "~>"
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '1.3'
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: redis
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - "~>"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5.0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '5.0'
|
40
|
+
- !ruby/object:Gem::Dependency
|
41
|
+
name: sidekiq
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - "~>"
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '7.2'
|
47
|
+
type: :runtime
|
48
|
+
prerelease: false
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '7.2'
|
54
|
+
- !ruby/object:Gem::Dependency
|
55
|
+
name: singleton
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - "~>"
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0.1'
|
61
|
+
type: :runtime
|
62
|
+
prerelease: false
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0.1'
|
68
|
+
- !ruby/object:Gem::Dependency
|
69
|
+
name: bundler
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '2.0'
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '2.0'
|
82
|
+
- !ruby/object:Gem::Dependency
|
83
|
+
name: rake
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '13.0'
|
89
|
+
type: :development
|
90
|
+
prerelease: false
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - "~>"
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '13.0'
|
96
|
+
- !ruby/object:Gem::Dependency
|
97
|
+
name: rspec
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - "~>"
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '3.0'
|
103
|
+
type: :development
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '3.0'
|
110
|
+
description: Desiru brings DSPy's declarative programming paradigm for language models
|
111
|
+
to Ruby, enabling reliable, maintainable, and portable AI programming.
|
112
|
+
email:
|
113
|
+
- obiefernandez@gmail.com
|
114
|
+
executables: []
|
115
|
+
extensions: []
|
116
|
+
extra_rdoc_files: []
|
117
|
+
files:
|
118
|
+
- ".rspec"
|
119
|
+
- ".rubocop.yml"
|
120
|
+
- CLAUDE.md
|
121
|
+
- Gemfile
|
122
|
+
- Gemfile.lock
|
123
|
+
- LICENSE
|
124
|
+
- README.md
|
125
|
+
- Rakefile
|
126
|
+
- desiru.gemspec
|
127
|
+
- examples/README.md
|
128
|
+
- examples/async_processing.rb
|
129
|
+
- examples/few_shot_learning.rb
|
130
|
+
- examples/graphql_api.rb
|
131
|
+
- examples/graphql_integration.rb
|
132
|
+
- examples/rag_retrieval.rb
|
133
|
+
- examples/simple_qa.rb
|
134
|
+
- examples/typed_signatures.rb
|
135
|
+
- lib/desiru.rb
|
136
|
+
- lib/desiru/async_capable.rb
|
137
|
+
- lib/desiru/cache.rb
|
138
|
+
- lib/desiru/configuration.rb
|
139
|
+
- lib/desiru/field.rb
|
140
|
+
- lib/desiru/graphql/data_loader.rb
|
141
|
+
- lib/desiru/graphql/executor.rb
|
142
|
+
- lib/desiru/graphql/schema_generator.rb
|
143
|
+
- lib/desiru/jobs/async_predict.rb
|
144
|
+
- lib/desiru/jobs/base.rb
|
145
|
+
- lib/desiru/jobs/batch_processor.rb
|
146
|
+
- lib/desiru/jobs/optimizer_job.rb
|
147
|
+
- lib/desiru/models/base.rb
|
148
|
+
- lib/desiru/models/raix_adapter.rb
|
149
|
+
- lib/desiru/module.rb
|
150
|
+
- lib/desiru/modules/chain_of_thought.rb
|
151
|
+
- lib/desiru/modules/predict.rb
|
152
|
+
- lib/desiru/modules/retrieve.rb
|
153
|
+
- lib/desiru/optimizers/base.rb
|
154
|
+
- lib/desiru/optimizers/bootstrap_few_shot.rb
|
155
|
+
- lib/desiru/program.rb
|
156
|
+
- lib/desiru/registry.rb
|
157
|
+
- lib/desiru/signature.rb
|
158
|
+
- lib/desiru/version.rb
|
159
|
+
homepage: https://github.com/obie/desiru
|
160
|
+
licenses:
|
161
|
+
- MIT
|
162
|
+
metadata:
|
163
|
+
homepage_uri: https://github.com/obie/desiru
|
164
|
+
source_code_uri: https://github.com/obie/desiru
|
165
|
+
changelog_uri: https://github.com/obie/desiru/blob/main/CHANGELOG.md
|
166
|
+
rubygems_mfa_required: 'false'
|
167
|
+
rdoc_options: []
|
168
|
+
require_paths:
|
169
|
+
- lib
|
170
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
171
|
+
requirements:
|
172
|
+
- - ">="
|
173
|
+
- !ruby/object:Gem::Version
|
174
|
+
version: 3.4.2
|
175
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
requirements: []
|
181
|
+
rubygems_version: 3.6.8
|
182
|
+
specification_version: 4
|
183
|
+
summary: Declarative Self-Improving Ruby - A Ruby port of DSPy
|
184
|
+
test_files: []
|