dspy 0.6.0 → 0.6.2

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: e82dded62b8c11ca1ac69c75d0cdffd04e9e58daa5dcb16e66d794dbc37ee49e
4
- data.tar.gz: 3d58da2a9ff3d76b9e0d5960e9e6df3dc0ac120ef97c99c640f05129d9990a77
3
+ metadata.gz: 73a87d28dcc9a384a305f0c5c5b4f00ea342ab08a6b7d23f7d5025c605dd70ea
4
+ data.tar.gz: 9d827a96ed854bd4a3659498c2b6df3999ed446a3325eb95dd630bf9b69db9aa
5
5
  SHA512:
6
- metadata.gz: e25cecdaaf81a6985a1e6cf5bd7a709efc568c89cb687a8e9bd3e593c6e41e352ffe07798275bfca44bf0f61f9b7cc8483c57978b8c56099bf0739f00573f587
7
- data.tar.gz: c465fb9231b2596b155ff839047b4b1e7a92ad2e40f98f7faabbc5eaa2b632fbd566c8d3e3c0005e0196f46ca3a0b4927fc9f64aa7bd6db262b2ae0c823e4aad
6
+ metadata.gz: b3c115f33dfc97b3f2f2bda84118e1411e000ac4412b94542e927fe4e75397963a662e86326f456405660739859d57487177fb9975b13fd031a2d0f4404c884b
7
+ data.tar.gz: 888e352139cbb6d3ad055c054a70bc3eaef0d719bc8dadefae6d2b27b67f90249002662454312fc0dedbcc1d00eaa785fbd3a965bec2f8e8c49456fd5e11e779
data/README.md CHANGED
@@ -113,7 +113,7 @@ puts result.confidence # => 0.85
113
113
  - **[Observability](docs/production/observability.md)** - Multi-platform monitoring and metrics
114
114
 
115
115
  ### Advanced Usage
116
- - **[Complex Types](docs/advanced/complex-types.md)** - Basic Sorbet type integration
116
+ - **[Complex Types](docs/advanced/complex-types.md)** - Sorbet type integration with automatic coercion for structs, enums, and arrays
117
117
  - **[Manual Pipelines](docs/advanced/pipelines.md)** - Manual module composition patterns
118
118
  - **[RAG Patterns](docs/advanced/rag.md)** - Manual RAG implementation with external services
119
119
  - **[Custom Metrics](docs/advanced/custom-metrics.md)** - Proc-based evaluation logic
@@ -30,12 +30,16 @@ module DSPy
30
30
  return value if value.nil?
31
31
 
32
32
  case prop_type
33
+ when ->(type) { array_type?(type) }
34
+ coerce_array_value(value, prop_type)
33
35
  when ->(type) { enum_type?(type) }
34
36
  extract_enum_class(prop_type).deserialize(value)
35
37
  when Float, ->(type) { simple_type_match?(type, Float) }
36
38
  value.to_f
37
39
  when Integer, ->(type) { simple_type_match?(type, Integer) }
38
40
  value.to_i
41
+ when ->(type) { struct_type?(type) }
42
+ coerce_struct_value(value, prop_type)
39
43
  else
40
44
  value
41
45
  end
@@ -44,8 +48,17 @@ module DSPy
44
48
  # Checks if a type is an enum type
45
49
  sig { params(type: T.untyped).returns(T::Boolean) }
46
50
  def enum_type?(type)
47
- (type.is_a?(Class) && type < T::Enum) ||
48
- (type.is_a?(T::Types::Simple) && type.raw_type < T::Enum)
51
+ return false unless type
52
+
53
+ if type.is_a?(Class)
54
+ !!(type < T::Enum)
55
+ elsif type.is_a?(T::Types::Simple)
56
+ !!(type.raw_type < T::Enum)
57
+ else
58
+ false
59
+ end
60
+ rescue StandardError
61
+ false
49
62
  end
50
63
 
51
64
  # Extracts the enum class from a type
@@ -65,6 +78,61 @@ module DSPy
65
78
  def simple_type_match?(type, target_type)
66
79
  type.is_a?(T::Types::Simple) && type.raw_type == target_type
67
80
  end
81
+
82
+ # Checks if a type is an array type
83
+ sig { params(type: T.untyped).returns(T::Boolean) }
84
+ def array_type?(type)
85
+ return false unless type.is_a?(T::Types::TypedArray)
86
+ true
87
+ end
88
+
89
+ # Checks if a type is a struct type
90
+ sig { params(type: T.untyped).returns(T::Boolean) }
91
+ def struct_type?(type)
92
+ if type.is_a?(Class)
93
+ !!(type < T::Struct)
94
+ elsif type.is_a?(T::Types::Simple)
95
+ !!(type.raw_type < T::Struct)
96
+ else
97
+ false
98
+ end
99
+ rescue StandardError
100
+ false
101
+ end
102
+
103
+ # Coerces an array value, converting each element as needed
104
+ sig { params(value: T.untyped, prop_type: T.untyped).returns(T.untyped) }
105
+ def coerce_array_value(value, prop_type)
106
+ return value unless value.is_a?(Array)
107
+ return value unless prop_type.is_a?(T::Types::TypedArray)
108
+
109
+ element_type = prop_type.type
110
+ value.map { |element| coerce_value_to_type(element, element_type) }
111
+ end
112
+
113
+ # Coerces a struct value from a hash
114
+ sig { params(value: T.untyped, prop_type: T.untyped).returns(T.untyped) }
115
+ def coerce_struct_value(value, prop_type)
116
+ return value unless value.is_a?(Hash)
117
+
118
+ struct_class = if prop_type.is_a?(Class)
119
+ prop_type
120
+ elsif prop_type.is_a?(T::Types::Simple)
121
+ prop_type.raw_type
122
+ else
123
+ return value
124
+ end
125
+
126
+ # Convert string keys to symbols
127
+ symbolized_hash = value.transform_keys(&:to_sym)
128
+
129
+ # Create the struct instance
130
+ struct_class.new(**symbolized_hash)
131
+ rescue ArgumentError => e
132
+ # If struct creation fails, return the original value
133
+ DSPy.logger.debug("Failed to coerce to struct #{struct_class}: #{e.message}")
134
+ value
135
+ end
68
136
  end
69
137
  end
70
138
  end
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.6.0"
4
+ VERSION = "0.6.2"
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.6.0
4
+ version: 0.6.2
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-07-05 00:00:00.000000000 Z
10
+ date: 2025-07-08 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: dry-configurable