dspy 0.20.1 → 0.21.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3324f833b373e826df1dcdf3f2c3f46011e192e9a30fdf38d7db1b9cc51a7950
4
- data.tar.gz: f6159081bc6429d0c57e6275111d2672bf984f8500be7756afbf8bb17599dd19
3
+ metadata.gz: 78e01258a3b9b5a1bccddad913a1d0aa45ecb145a65adb3e691986cadbea6e23
4
+ data.tar.gz: 9a778ea689150002e0766357dd4aa4af526be81979378b9996ba9067c2cdbd42
5
5
  SHA512:
6
- metadata.gz: cd81596af2ea0d734550b0827e18b71d4abdd1e3a4c92efb014af665d17bb2a37fb36b747757eb3ad4377d89a435b81bbaa4477ce0fd22b8ed88319ebc8b1f5b
7
- data.tar.gz: d65e68af35f7ced5e97524dd85f1c590900f33b720038f25bbc22995031d10cc5115bdb1b160b153e5fbaa5bf2cb3809dde0520f6bd99a7ac348c0231bf88afa
6
+ metadata.gz: 7ba1376b844e5c5e61215b961142a70f82d758db41e061bf2e7404f4ffdbae867197b0c38254a92b25892beb51922fb3c3b963ab2474494c9d490b83814bba5d
7
+ data.tar.gz: 4a543e0b954469f316f003f36c5a55b97b0794ef1cbf395180ac5197acf5d4091bfe3ea87e342473c190d96adf5761baff59532502a20778edea23a83a9e5253
data/README.md CHANGED
@@ -14,6 +14,10 @@ Traditional prompting is like writing code with string concatenation: it works u
14
14
  the programming approach pioneered by [dspy.ai](https://dspy.ai/): instead of crafting fragile prompts, you define modular
15
15
  signatures and let the framework handle the messy details.
16
16
 
17
+ DSPy.rb is an idiomatic Ruby port of Stanford's [DSPy framework](https://github.com/stanfordnlp/dspy). While implementing
18
+ the core concepts of signatures, predictors, and optimization from the original Python library, DSPy.rb embraces Ruby
19
+ conventions and adds Ruby-specific innovations like CodeAct agents and enhanced production instrumentation.
20
+
17
21
  The result? LLM applications that actually scale and don't break when you sneeze.
18
22
 
19
23
  ## Your First DSPy Program
@@ -114,24 +114,55 @@ module DSPy
114
114
 
115
115
  example = {}
116
116
  schema[:properties].each do |field_name, field_schema|
117
- example[field_name.to_s] = case field_schema[:type]
118
- when "string"
119
- field_schema[:description] || "example string"
120
- when "integer"
121
- 42
122
- when "number"
123
- 3.14
124
- when "boolean"
125
- true
126
- when "array"
117
+ example[field_name.to_s] = generate_example_value(field_schema)
118
+ end
119
+ example
120
+ end
121
+
122
+ sig { params(field_schema: T::Hash[Symbol, T.untyped]).returns(T.untyped) }
123
+ def generate_example_value(field_schema)
124
+ case field_schema[:type]
125
+ when "string"
126
+ field_schema[:description] || "example string"
127
+ when "integer"
128
+ 42
129
+ when "number"
130
+ 3.14
131
+ when "boolean"
132
+ true
133
+ when "array"
134
+ if field_schema[:items]
135
+ [generate_example_value(field_schema[:items])]
136
+ else
127
137
  ["example item"]
128
- when "object"
138
+ end
139
+ when "object"
140
+ if field_schema[:properties]
141
+ # Generate proper nested object example
142
+ nested_example = {}
143
+ field_schema[:properties].each do |prop_name, prop_schema|
144
+ nested_example[prop_name.to_s] = generate_example_value(prop_schema)
145
+ end
146
+ nested_example
147
+ else
129
148
  { "nested" => "object" }
149
+ end
150
+ when Array
151
+ # Handle union types like ["object", "null"]
152
+ if field_schema[:type].include?("object") && field_schema[:properties]
153
+ nested_example = {}
154
+ field_schema[:properties].each do |prop_name, prop_schema|
155
+ nested_example[prop_name.to_s] = generate_example_value(prop_schema)
156
+ end
157
+ nested_example
158
+ elsif field_schema[:type].include?("string")
159
+ "example string"
130
160
  else
131
161
  "example value"
132
162
  end
163
+ else
164
+ "example value"
133
165
  end
134
- example
135
166
  end
136
167
 
137
168
  sig { params(content: String).returns(T::Boolean) }
@@ -188,6 +188,11 @@ module DSPy
188
188
  return { type: "boolean" }
189
189
  end
190
190
 
191
+ # Handle type aliases by resolving to their underlying type
192
+ if type.is_a?(T::Private::Types::TypeAlias)
193
+ return type_to_json_schema(type.aliased_type)
194
+ end
195
+
191
196
  # Handle raw class types first
192
197
  if type.is_a?(Class)
193
198
  if type < T::Enum
@@ -257,6 +262,22 @@ module DSPy
257
262
  # Add a more explicit description of the expected structure
258
263
  description: "A mapping where keys are #{key_schema[:type]}s and values are #{value_schema[:description] || value_schema[:type]}s"
259
264
  }
265
+ elsif type.is_a?(T::Types::FixedHash)
266
+ # Handle fixed hashes (from type aliases like { "key" => Type })
267
+ properties = {}
268
+ required = []
269
+
270
+ type.types.each do |key, value_type|
271
+ properties[key] = type_to_json_schema(value_type)
272
+ required << key
273
+ end
274
+
275
+ {
276
+ type: "object",
277
+ properties: properties,
278
+ required: required,
279
+ additionalProperties: false
280
+ }
260
281
  elsif type.class.name == "T::Private::Types::SimplePairUnion"
261
282
  # Handle T.nilable types (T::Private::Types::SimplePairUnion)
262
283
  # This is the actual implementation of T.nilable(SomeType)
data/lib/dspy/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DSPy
4
- VERSION = "0.20.1"
4
+ VERSION = "0.21.0"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dspy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.1
4
+ version: 0.21.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vicente Reig Rincón de Arellano
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-08-27 00:00:00.000000000 Z
10
+ date: 2025-09-01 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: dry-configurable