openai 0.9.0 → 0.10.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/CHANGELOG.md +20 -0
- data/README.md +1 -1
- data/lib/openai/errors.rb +22 -0
- data/lib/openai/internal/type/array_of.rb +6 -1
- data/lib/openai/internal/type/base_model.rb +76 -24
- data/lib/openai/internal/type/boolean.rb +7 -1
- data/lib/openai/internal/type/converter.rb +42 -34
- data/lib/openai/internal/type/enum.rb +10 -2
- data/lib/openai/internal/type/file_input.rb +6 -1
- data/lib/openai/internal/type/hash_of.rb +6 -1
- data/lib/openai/internal/type/union.rb +12 -7
- data/lib/openai/internal/type/unknown.rb +7 -1
- data/lib/openai/models/audio/speech_create_params.rb +23 -2
- data/lib/openai/models/audio/transcription.rb +118 -1
- data/lib/openai/models/audio/transcription_text_done_event.rb +80 -1
- data/lib/openai/models/audio/transcription_verbose.rb +31 -1
- data/lib/openai/models/fine_tuning/checkpoints/permission_retrieve_response.rb +60 -25
- data/lib/openai/models/responses/response_code_interpreter_call_code_delta_event.rb +17 -8
- data/lib/openai/models/responses/response_code_interpreter_call_code_done_event.rb +14 -10
- data/lib/openai/models/responses/response_code_interpreter_call_completed_event.rb +11 -10
- data/lib/openai/models/responses/response_code_interpreter_call_in_progress_event.rb +11 -10
- data/lib/openai/models/responses/response_code_interpreter_call_interpreting_event.rb +11 -10
- data/lib/openai/models/responses/response_code_interpreter_tool_call.rb +49 -78
- data/lib/openai/models/responses/response_create_params.rb +29 -29
- data/lib/openai/models/responses/response_output_text.rb +18 -2
- data/lib/openai/models/responses/response_stream_event.rb +2 -2
- data/lib/openai/resources/audio/speech.rb +3 -1
- data/lib/openai/resources/chat/completions.rb +8 -0
- data/lib/openai/resources/fine_tuning/checkpoints/permissions.rb +1 -2
- data/lib/openai/resources/responses.rb +12 -12
- data/lib/openai/version.rb +1 -1
- data/rbi/openai/errors.rbi +16 -0
- data/rbi/openai/internal/type/boolean.rbi +2 -0
- data/rbi/openai/internal/type/converter.rbi +15 -15
- data/rbi/openai/internal/type/union.rbi +5 -0
- data/rbi/openai/internal/type/unknown.rbi +2 -0
- data/rbi/openai/models/audio/speech_create_params.rbi +59 -2
- data/rbi/openai/models/audio/transcription.rbi +213 -3
- data/rbi/openai/models/audio/transcription_text_done_event.rbi +146 -1
- data/rbi/openai/models/audio/transcription_verbose.rbi +47 -0
- data/rbi/openai/models/fine_tuning/checkpoints/permission_retrieve_response.rbi +95 -26
- data/rbi/openai/models/responses/response_code_interpreter_call_code_delta_event.rbi +17 -7
- data/rbi/openai/models/responses/response_code_interpreter_call_code_done_event.rbi +13 -5
- data/rbi/openai/models/responses/response_code_interpreter_call_completed_event.rbi +13 -21
- data/rbi/openai/models/responses/response_code_interpreter_call_in_progress_event.rbi +13 -21
- data/rbi/openai/models/responses/response_code_interpreter_call_interpreting_event.rbi +13 -21
- data/rbi/openai/models/responses/response_code_interpreter_tool_call.rbi +83 -125
- data/rbi/openai/models/responses/response_create_params.rbi +83 -60
- data/rbi/openai/models/responses/response_output_text.rbi +26 -4
- data/rbi/openai/resources/audio/speech.rbi +6 -1
- data/rbi/openai/resources/fine_tuning/checkpoints/permissions.rbi +1 -3
- data/rbi/openai/resources/responses.rbi +46 -46
- data/sig/openai/errors.rbs +9 -0
- data/sig/openai/internal/type/converter.rbs +7 -1
- data/sig/openai/models/audio/speech_create_params.rbs +21 -1
- data/sig/openai/models/audio/transcription.rbs +95 -3
- data/sig/openai/models/audio/transcription_text_done_event.rbs +72 -2
- data/sig/openai/models/audio/transcription_verbose.rbs +21 -0
- data/sig/openai/models/fine_tuning/checkpoints/permission_retrieve_response.rbs +53 -16
- data/sig/openai/models/responses/response_code_interpreter_call_code_delta_event.rbs +5 -0
- data/sig/openai/models/responses/response_code_interpreter_call_code_done_event.rbs +5 -0
- data/sig/openai/models/responses/response_code_interpreter_call_completed_event.rbs +4 -4
- data/sig/openai/models/responses/response_code_interpreter_call_in_progress_event.rbs +4 -4
- data/sig/openai/models/responses/response_code_interpreter_call_interpreting_event.rbs +4 -4
- data/sig/openai/models/responses/response_code_interpreter_tool_call.rbs +31 -52
- data/sig/openai/models/responses/response_create_params.rbs +18 -10
- data/sig/openai/models/responses/response_output_text.rbs +15 -1
- data/sig/openai/resources/audio/speech.rbs +1 -0
- data/sig/openai/resources/fine_tuning/checkpoints/permissions.rbs +1 -1
- data/sig/openai/resources/responses.rbs +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d8ca71d5671f3a20cde2fda0eec819c5305ebd9e60aabcc55abf471f1de63b53
|
4
|
+
data.tar.gz: 1de944c9a0ee804f9d15567fec8038368458132183468c81ae42609c036e05ac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 822226e8ebc9b077c242ae0366ec3f5e4b0b413054cbc3e4d9e971347c79ccb9b64006a6af5cc5a88b25472103be1a5c9a2b3c9a5e25396951f454f9f15f2dc4
|
7
|
+
data.tar.gz: 6ed344972114e5c0f098d3e5619dc1548ac61557e7b3b23384d558e2f9ccbe1ee1dd00ee0ffa0f77b17027554c1c46d33bc6eb552695615bf0fd289cf0fb4dc1
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,25 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## 0.10.0 (2025-06-23)
|
4
|
+
|
5
|
+
Full Changelog: [v0.9.0...v0.10.0](https://github.com/openai/openai-ruby/compare/v0.9.0...v0.10.0)
|
6
|
+
|
7
|
+
### Features
|
8
|
+
|
9
|
+
* **api:** make model and inputs not required to create response ([2087fb5](https://github.com/openai/openai-ruby/commit/2087fb53d775f6481dd34737f6d554c5c35f65e7))
|
10
|
+
* **api:** update api shapes for usage and code interpreter ([733ebfb](https://github.com/openai/openai-ruby/commit/733ebfbafe14d9733149b174c99d41d471a42865))
|
11
|
+
|
12
|
+
|
13
|
+
### Bug Fixes
|
14
|
+
|
15
|
+
* **internal:** fix: should publish to ruby gems when a release is created ([aebd8eb](https://github.com/openai/openai-ruby/commit/aebd8eb2855d6a8f4fe685bdb5a458346d509e50))
|
16
|
+
* issue where we cannot mutate arrays on base model derivatives ([266d072](https://github.com/openai/openai-ruby/commit/266d072946c75f93abeff45eec9787ce4e7fea56))
|
17
|
+
|
18
|
+
|
19
|
+
### Chores
|
20
|
+
|
21
|
+
* allow more free formatted json response input ([#726](https://github.com/openai/openai-ruby/issues/726)) ([69fb0af](https://github.com/openai/openai-ruby/commit/69fb0afabf86ecc3d1ca469d9700c42447569f3b))
|
22
|
+
|
3
23
|
## 0.9.0 (2025-06-17)
|
4
24
|
|
5
25
|
Full Changelog: [v0.8.0...v0.9.0](https://github.com/openai/openai-ruby/compare/v0.8.0...v0.9.0)
|
data/README.md
CHANGED
data/lib/openai/errors.rb
CHANGED
@@ -9,6 +9,28 @@ module OpenAI
|
|
9
9
|
end
|
10
10
|
|
11
11
|
class ConversionError < OpenAI::Errors::Error
|
12
|
+
# @return [StandardError, nil]
|
13
|
+
def cause = @cause.nil? ? super : @cause
|
14
|
+
|
15
|
+
# @api private
|
16
|
+
#
|
17
|
+
# @param on [Class<StandardError>]
|
18
|
+
# @param method [Symbol]
|
19
|
+
# @param target [Object]
|
20
|
+
# @param value [Object]
|
21
|
+
# @param cause [StandardError, nil]
|
22
|
+
def initialize(on:, method:, target:, value:, cause: nil)
|
23
|
+
cls = on.name.split("::").last
|
24
|
+
|
25
|
+
message = [
|
26
|
+
"Failed to parse #{cls}.#{method} from #{value.class} to #{target.inspect}.",
|
27
|
+
"To get the unparsed API response, use #{cls}[#{method.inspect}].",
|
28
|
+
cause && "Cause: #{cause.message}"
|
29
|
+
].filter(&:itself).join(" ")
|
30
|
+
|
31
|
+
@cause = cause
|
32
|
+
super(message)
|
33
|
+
end
|
12
34
|
end
|
13
35
|
|
14
36
|
class APIError < OpenAI::Errors::Error
|
@@ -62,10 +62,14 @@ module OpenAI
|
|
62
62
|
#
|
63
63
|
# @param state [Hash{Symbol=>Object}] .
|
64
64
|
#
|
65
|
-
# @option state [Boolean
|
65
|
+
# @option state [Boolean] :translate_names
|
66
|
+
#
|
67
|
+
# @option state [Boolean] :strictness
|
66
68
|
#
|
67
69
|
# @option state [Hash{Symbol=>Object}] :exactness
|
68
70
|
#
|
71
|
+
# @option state [Class<StandardError>] :error
|
72
|
+
#
|
69
73
|
# @option state [Integer] :branched
|
70
74
|
#
|
71
75
|
# @return [Array<Object>, Object]
|
@@ -74,6 +78,7 @@ module OpenAI
|
|
74
78
|
|
75
79
|
unless value.is_a?(Array)
|
76
80
|
exactness[:no] += 1
|
81
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{Array}")
|
77
82
|
return value
|
78
83
|
end
|
79
84
|
|
@@ -60,7 +60,7 @@ module OpenAI
|
|
60
60
|
[OpenAI::Internal::Type::Converter.type_info(type_info), type_info]
|
61
61
|
end
|
62
62
|
|
63
|
-
setter = "#{name_sym}="
|
63
|
+
setter = :"#{name_sym}="
|
64
64
|
api_name = info.fetch(:api_name, name_sym)
|
65
65
|
nilable = info.fetch(:nil?, false)
|
66
66
|
const = required && !nilable ? info.fetch(:const, OpenAI::Internal::OMIT) : OpenAI::Internal::OMIT
|
@@ -77,30 +77,61 @@ module OpenAI
|
|
77
77
|
type_fn: type_fn
|
78
78
|
}
|
79
79
|
|
80
|
-
define_method(setter)
|
80
|
+
define_method(setter) do |value|
|
81
|
+
target = type_fn.call
|
82
|
+
state = OpenAI::Internal::Type::Converter.new_coerce_state(translate_names: false)
|
83
|
+
coerced = OpenAI::Internal::Type::Converter.coerce(target, value, state: state)
|
84
|
+
error = @coerced.store(name_sym, state.fetch(:error) || true)
|
85
|
+
stored =
|
86
|
+
case [target, error]
|
87
|
+
in [OpenAI::Internal::Type::Converter | Symbol, nil]
|
88
|
+
coerced
|
89
|
+
else
|
90
|
+
value
|
91
|
+
end
|
92
|
+
@data.store(name_sym, stored)
|
93
|
+
end
|
81
94
|
|
95
|
+
# rubocop:disable Style/CaseEquality
|
96
|
+
# rubocop:disable Metrics/BlockLength
|
82
97
|
define_method(name_sym) do
|
83
98
|
target = type_fn.call
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
OpenAI::
|
90
|
-
|
91
|
-
|
92
|
-
|
99
|
+
|
100
|
+
case @coerced[name_sym]
|
101
|
+
in true | false if OpenAI::Internal::Type::Converter === target
|
102
|
+
@data.fetch(name_sym)
|
103
|
+
in ::StandardError => e
|
104
|
+
raise OpenAI::Errors::ConversionError.new(
|
105
|
+
on: self.class,
|
106
|
+
method: __method__,
|
107
|
+
target: target,
|
108
|
+
value: @data.fetch(name_sym),
|
109
|
+
cause: e
|
93
110
|
)
|
111
|
+
else
|
112
|
+
Kernel.then do
|
113
|
+
value = @data.fetch(name_sym) { const == OpenAI::Internal::OMIT ? nil : const }
|
114
|
+
state = OpenAI::Internal::Type::Converter.new_coerce_state(translate_names: false)
|
115
|
+
if (nilable || !required) && value.nil?
|
116
|
+
nil
|
117
|
+
else
|
118
|
+
OpenAI::Internal::Type::Converter.coerce(
|
119
|
+
target, value, state: state
|
120
|
+
)
|
121
|
+
end
|
122
|
+
rescue StandardError => e
|
123
|
+
raise OpenAI::Errors::ConversionError.new(
|
124
|
+
on: self.class,
|
125
|
+
method: __method__,
|
126
|
+
target: target,
|
127
|
+
value: value,
|
128
|
+
cause: e
|
129
|
+
)
|
130
|
+
end
|
94
131
|
end
|
95
|
-
rescue StandardError => e
|
96
|
-
cls = self.class.name.split("::").last
|
97
|
-
message = [
|
98
|
-
"Failed to parse #{cls}.#{__method__} from #{value.class} to #{target.inspect}.",
|
99
|
-
"To get the unparsed API response, use #{cls}[#{__method__.inspect}].",
|
100
|
-
"Cause: #{e.message}"
|
101
|
-
].join(" ")
|
102
|
-
raise OpenAI::Errors::ConversionError.new(message)
|
103
132
|
end
|
133
|
+
# rubocop:enable Metrics/BlockLength
|
134
|
+
# rubocop:enable Style/CaseEquality
|
104
135
|
end
|
105
136
|
|
106
137
|
# @api private
|
@@ -200,10 +231,14 @@ module OpenAI
|
|
200
231
|
#
|
201
232
|
# @param state [Hash{Symbol=>Object}] .
|
202
233
|
#
|
203
|
-
# @option state [Boolean
|
234
|
+
# @option state [Boolean] :translate_names
|
235
|
+
#
|
236
|
+
# @option state [Boolean] :strictness
|
204
237
|
#
|
205
238
|
# @option state [Hash{Symbol=>Object}] :exactness
|
206
239
|
#
|
240
|
+
# @option state [Class<StandardError>] :error
|
241
|
+
#
|
207
242
|
# @option state [Integer] :branched
|
208
243
|
#
|
209
244
|
# @return [self, Object]
|
@@ -217,6 +252,7 @@ module OpenAI
|
|
217
252
|
|
218
253
|
unless (val = OpenAI::Internal::Util.coerce_hash(value)).is_a?(Hash)
|
219
254
|
exactness[:no] += 1
|
255
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{Hash}")
|
220
256
|
return value
|
221
257
|
end
|
222
258
|
exactness[:yes] += 1
|
@@ -224,13 +260,15 @@ module OpenAI
|
|
224
260
|
keys = val.keys.to_set
|
225
261
|
instance = new
|
226
262
|
data = instance.to_h
|
263
|
+
viability = instance.instance_variable_get(:@coerced)
|
227
264
|
|
228
265
|
# rubocop:disable Metrics/BlockLength
|
229
266
|
fields.each do |name, field|
|
230
267
|
mode, required, target = field.fetch_values(:mode, :required, :type)
|
231
268
|
api_name, nilable, const = field.fetch_values(:api_name, :nilable, :const)
|
269
|
+
src_name = state.fetch(:translate_names) ? api_name : name
|
232
270
|
|
233
|
-
unless val.key?(
|
271
|
+
unless val.key?(src_name)
|
234
272
|
if required && mode != :dump && const == OpenAI::Internal::OMIT
|
235
273
|
exactness[nilable ? :maybe : :no] += 1
|
236
274
|
else
|
@@ -239,9 +277,10 @@ module OpenAI
|
|
239
277
|
next
|
240
278
|
end
|
241
279
|
|
242
|
-
item = val.fetch(
|
243
|
-
keys.delete(
|
280
|
+
item = val.fetch(src_name)
|
281
|
+
keys.delete(src_name)
|
244
282
|
|
283
|
+
state[:error] = nil
|
245
284
|
converted =
|
246
285
|
if item.nil? && (nilable || !required)
|
247
286
|
exactness[nilable ? :yes : :maybe] += 1
|
@@ -255,6 +294,8 @@ module OpenAI
|
|
255
294
|
item
|
256
295
|
end
|
257
296
|
end
|
297
|
+
|
298
|
+
viability.store(name, state.fetch(:error) || true)
|
258
299
|
data.store(name, converted)
|
259
300
|
end
|
260
301
|
# rubocop:enable Metrics/BlockLength
|
@@ -430,7 +471,18 @@ module OpenAI
|
|
430
471
|
# Create a new instance of a model.
|
431
472
|
#
|
432
473
|
# @param data [Hash{Symbol=>Object}, self]
|
433
|
-
def initialize(data = {})
|
474
|
+
def initialize(data = {})
|
475
|
+
@data = {}
|
476
|
+
@coerced = {}
|
477
|
+
OpenAI::Internal::Util.coerce_hash!(data).each do
|
478
|
+
if self.class.known_fields.key?(_1)
|
479
|
+
public_send(:"#{_1}=", _2)
|
480
|
+
else
|
481
|
+
@data.store(_1, _2)
|
482
|
+
@coerced.store(_1, false)
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end
|
434
486
|
|
435
487
|
class << self
|
436
488
|
# @api private
|
@@ -31,14 +31,20 @@ module OpenAI
|
|
31
31
|
class << self
|
32
32
|
# @api private
|
33
33
|
#
|
34
|
+
# Coerce value to Boolean if possible, otherwise return the original value.
|
35
|
+
#
|
34
36
|
# @param value [Boolean, Object]
|
35
37
|
#
|
36
38
|
# @param state [Hash{Symbol=>Object}] .
|
37
39
|
#
|
38
|
-
# @option state [Boolean
|
40
|
+
# @option state [Boolean] :translate_names
|
41
|
+
#
|
42
|
+
# @option state [Boolean] :strictness
|
39
43
|
#
|
40
44
|
# @option state [Hash{Symbol=>Object}] :exactness
|
41
45
|
#
|
46
|
+
# @option state [Class<StandardError>] :error
|
47
|
+
#
|
42
48
|
# @option state [Integer] :branched
|
43
49
|
#
|
44
50
|
# @return [Boolean, Object]
|
@@ -15,10 +15,14 @@ module OpenAI
|
|
15
15
|
#
|
16
16
|
# @param state [Hash{Symbol=>Object}] .
|
17
17
|
#
|
18
|
-
# @option state [Boolean
|
18
|
+
# @option state [Boolean] :translate_names
|
19
|
+
#
|
20
|
+
# @option state [Boolean] :strictness
|
19
21
|
#
|
20
22
|
# @option state [Hash{Symbol=>Object}] :exactness
|
21
23
|
#
|
24
|
+
# @option state [Class<StandardError>] :error
|
25
|
+
#
|
22
26
|
# @option state [Integer] :branched
|
23
27
|
#
|
24
28
|
# @return [Object]
|
@@ -94,6 +98,21 @@ module OpenAI
|
|
94
98
|
end
|
95
99
|
end
|
96
100
|
|
101
|
+
# @api private
|
102
|
+
#
|
103
|
+
# @param translate_names [Boolean]
|
104
|
+
#
|
105
|
+
# @return [Hash{Symbol=>Object}]
|
106
|
+
def new_coerce_state(translate_names: true)
|
107
|
+
{
|
108
|
+
translate_names: translate_names,
|
109
|
+
strictness: true,
|
110
|
+
exactness: {yes: 0, no: 0, maybe: 0},
|
111
|
+
error: nil,
|
112
|
+
branched: 0
|
113
|
+
}
|
114
|
+
end
|
115
|
+
|
97
116
|
# @api private
|
98
117
|
#
|
99
118
|
# Based on `target`, transform `value` into `target`, to the extent possible:
|
@@ -110,14 +129,11 @@ module OpenAI
|
|
110
129
|
#
|
111
130
|
# @param value [Object]
|
112
131
|
#
|
113
|
-
# @param state [Hash{Symbol=>Object}] The `strictness` is one of `true`, `false
|
114
|
-
#
|
115
|
-
# targets:
|
132
|
+
# @param state [Hash{Symbol=>Object}] The `strictness` is one of `true`, `false`. This informs the coercion strategy
|
133
|
+
# when we have to decide between multiple possible conversion targets:
|
116
134
|
#
|
117
135
|
# - `true`: the conversion must be exact, with minimum coercion.
|
118
136
|
# - `false`: the conversion can be approximate, with some coercion.
|
119
|
-
# - `:strong`: the conversion must be exact, with no coercion, and raise an error
|
120
|
-
# if not possible.
|
121
137
|
#
|
122
138
|
# The `exactness` is `Hash` with keys being one of `yes`, `no`, or `maybe`. For
|
123
139
|
# any given conversion attempt, the exactness will be updated based on how closely
|
@@ -130,21 +146,20 @@ module OpenAI
|
|
130
146
|
#
|
131
147
|
# See implementation below for more details.
|
132
148
|
#
|
133
|
-
# @option state [Boolean
|
149
|
+
# @option state [Boolean] :translate_names
|
150
|
+
#
|
151
|
+
# @option state [Boolean] :strictness
|
134
152
|
#
|
135
153
|
# @option state [Hash{Symbol=>Object}] :exactness
|
136
154
|
#
|
155
|
+
# @option state [Class<StandardError>] :error
|
156
|
+
#
|
137
157
|
# @option state [Integer] :branched
|
138
158
|
#
|
139
159
|
# @return [Object]
|
140
|
-
def coerce(
|
141
|
-
target,
|
142
|
-
value,
|
143
|
-
state: {strictness: true, exactness: {yes: 0, no: 0, maybe: 0}, branched: 0}
|
144
|
-
)
|
145
|
-
# rubocop:disable Lint/SuppressedException
|
160
|
+
def coerce(target, value, state: OpenAI::Internal::Type::Converter.new_coerce_state)
|
146
161
|
# rubocop:disable Metrics/BlockNesting
|
147
|
-
|
162
|
+
exactness = state.fetch(:exactness)
|
148
163
|
|
149
164
|
case target
|
150
165
|
in OpenAI::Internal::Type::Converter
|
@@ -160,29 +175,26 @@ module OpenAI
|
|
160
175
|
exactness[value.nil? ? :yes : :maybe] += 1
|
161
176
|
return nil
|
162
177
|
in -> { _1 <= Integer }
|
163
|
-
|
178
|
+
case value
|
179
|
+
in Integer
|
164
180
|
exactness[:yes] += 1
|
165
181
|
return value
|
166
|
-
elsif strictness == :strong && Integer(value, exception: false) != value
|
167
|
-
message = "no implicit conversion of #{value.class} into #{target.inspect}"
|
168
|
-
raise value.is_a?(Numeric) ? ArgumentError.new(message) : TypeError.new(message)
|
169
182
|
else
|
170
183
|
Kernel.then do
|
171
184
|
return Integer(value).tap { exactness[:maybe] += 1 }
|
172
|
-
rescue ArgumentError, TypeError
|
185
|
+
rescue ArgumentError, TypeError => e
|
186
|
+
state[:error] = e
|
173
187
|
end
|
174
188
|
end
|
175
189
|
in -> { _1 <= Float }
|
176
190
|
if value.is_a?(Numeric)
|
177
191
|
exactness[:yes] += 1
|
178
192
|
return Float(value)
|
179
|
-
elsif strictness == :strong
|
180
|
-
message = "no implicit conversion of #{value.class} into #{target.inspect}"
|
181
|
-
raise TypeError.new(message)
|
182
193
|
else
|
183
194
|
Kernel.then do
|
184
195
|
return Float(value).tap { exactness[:maybe] += 1 }
|
185
|
-
rescue ArgumentError, TypeError
|
196
|
+
rescue ArgumentError, TypeError => e
|
197
|
+
state[:error] = e
|
186
198
|
end
|
187
199
|
end
|
188
200
|
in -> { _1 <= String }
|
@@ -194,16 +206,13 @@ module OpenAI
|
|
194
206
|
exactness[:yes] += 1
|
195
207
|
return value.string
|
196
208
|
else
|
197
|
-
|
198
|
-
message = "no implicit conversion of #{value.class} into #{target.inspect}"
|
199
|
-
raise TypeError.new(message)
|
200
|
-
end
|
209
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{String}")
|
201
210
|
end
|
202
211
|
in -> { _1 <= Date || _1 <= Time }
|
203
212
|
Kernel.then do
|
204
213
|
return target.parse(value).tap { exactness[:yes] += 1 }
|
205
214
|
rescue ArgumentError, TypeError => e
|
206
|
-
|
215
|
+
state[:error] = e
|
207
216
|
end
|
208
217
|
in -> { _1 <= StringIO } if value.is_a?(String)
|
209
218
|
exactness[:yes] += 1
|
@@ -221,10 +230,8 @@ module OpenAI
|
|
221
230
|
return value
|
222
231
|
end
|
223
232
|
else
|
224
|
-
|
225
|
-
|
226
|
-
raise ArgumentError.new(message)
|
227
|
-
end
|
233
|
+
message = "cannot convert non-matching #{value.class} into #{target.inspect}"
|
234
|
+
state[:error] = ArgumentError.new(message)
|
228
235
|
end
|
229
236
|
else
|
230
237
|
end
|
@@ -232,7 +239,6 @@ module OpenAI
|
|
232
239
|
exactness[:no] += 1
|
233
240
|
value
|
234
241
|
# rubocop:enable Metrics/BlockNesting
|
235
|
-
# rubocop:enable Lint/SuppressedException
|
236
242
|
end
|
237
243
|
|
238
244
|
# @api private
|
@@ -277,8 +283,10 @@ module OpenAI
|
|
277
283
|
define_sorbet_constant!(:CoerceState) do
|
278
284
|
T.type_alias do
|
279
285
|
{
|
280
|
-
|
286
|
+
translate_names: T::Boolean,
|
287
|
+
strictness: T::Boolean,
|
281
288
|
exactness: {yes: Integer, no: Integer, maybe: Integer},
|
289
|
+
error: T::Class[StandardError],
|
282
290
|
branched: Integer
|
283
291
|
}
|
284
292
|
end
|
@@ -81,10 +81,14 @@ module OpenAI
|
|
81
81
|
#
|
82
82
|
# @param state [Hash{Symbol=>Object}] .
|
83
83
|
#
|
84
|
-
# @option state [Boolean
|
84
|
+
# @option state [Boolean] :translate_names
|
85
|
+
#
|
86
|
+
# @option state [Boolean] :strictness
|
85
87
|
#
|
86
88
|
# @option state [Hash{Symbol=>Object}] :exactness
|
87
89
|
#
|
90
|
+
# @option state [Class<StandardError>] :error
|
91
|
+
#
|
88
92
|
# @option state [Integer] :branched
|
89
93
|
#
|
90
94
|
# @return [Symbol, Object]
|
@@ -95,8 +99,12 @@ module OpenAI
|
|
95
99
|
if values.include?(val)
|
96
100
|
exactness[:yes] += 1
|
97
101
|
val
|
102
|
+
elsif values.first&.class == val.class
|
103
|
+
exactness[:maybe] += 1
|
104
|
+
value
|
98
105
|
else
|
99
|
-
exactness[
|
106
|
+
exactness[:no] += 1
|
107
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{self}")
|
100
108
|
value
|
101
109
|
end
|
102
110
|
end
|
@@ -45,10 +45,14 @@ module OpenAI
|
|
45
45
|
#
|
46
46
|
# @param state [Hash{Symbol=>Object}] .
|
47
47
|
#
|
48
|
-
# @option state [Boolean
|
48
|
+
# @option state [Boolean] :translate_names
|
49
|
+
#
|
50
|
+
# @option state [Boolean] :strictness
|
49
51
|
#
|
50
52
|
# @option state [Hash{Symbol=>Object}] :exactness
|
51
53
|
#
|
54
|
+
# @option state [Class<StandardError>] :error
|
55
|
+
#
|
52
56
|
# @option state [Integer] :branched
|
53
57
|
#
|
54
58
|
# @return [StringIO, Object]
|
@@ -62,6 +66,7 @@ module OpenAI
|
|
62
66
|
exactness[:yes] += 1
|
63
67
|
value
|
64
68
|
else
|
69
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{StringIO}")
|
65
70
|
exactness[:no] += 1
|
66
71
|
value
|
67
72
|
end
|
@@ -77,10 +77,14 @@ module OpenAI
|
|
77
77
|
#
|
78
78
|
# @param state [Hash{Symbol=>Object}] .
|
79
79
|
#
|
80
|
-
# @option state [Boolean
|
80
|
+
# @option state [Boolean] :translate_names
|
81
|
+
#
|
82
|
+
# @option state [Boolean] :strictness
|
81
83
|
#
|
82
84
|
# @option state [Hash{Symbol=>Object}] :exactness
|
83
85
|
#
|
86
|
+
# @option state [Class<StandardError>] :error
|
87
|
+
#
|
84
88
|
# @option state [Integer] :branched
|
85
89
|
#
|
86
90
|
# @return [Hash{Symbol=>Object}, Object]
|
@@ -89,6 +93,7 @@ module OpenAI
|
|
89
93
|
|
90
94
|
unless value.is_a?(Hash)
|
91
95
|
exactness[:no] += 1
|
96
|
+
state[:error] = TypeError.new("#{value.class} can't be coerced into #{Hash}")
|
92
97
|
return value
|
93
98
|
end
|
94
99
|
|
@@ -140,14 +140,23 @@ module OpenAI
|
|
140
140
|
|
141
141
|
# @api private
|
142
142
|
#
|
143
|
+
# Tries to efficiently coerce the given value to one of the known variants.
|
144
|
+
#
|
145
|
+
# If the value cannot match any of the known variants, the coercion is considered
|
146
|
+
# non-viable and returns the original value.
|
147
|
+
#
|
143
148
|
# @param value [Object]
|
144
149
|
#
|
145
150
|
# @param state [Hash{Symbol=>Object}] .
|
146
151
|
#
|
147
|
-
# @option state [Boolean
|
152
|
+
# @option state [Boolean] :translate_names
|
153
|
+
#
|
154
|
+
# @option state [Boolean] :strictness
|
148
155
|
#
|
149
156
|
# @option state [Hash{Symbol=>Object}] :exactness
|
150
157
|
#
|
158
|
+
# @option state [Class<StandardError>] :error
|
159
|
+
#
|
151
160
|
# @option state [Integer] :branched
|
152
161
|
#
|
153
162
|
# @return [Object]
|
@@ -158,7 +167,6 @@ module OpenAI
|
|
158
167
|
|
159
168
|
strictness = state.fetch(:strictness)
|
160
169
|
exactness = state.fetch(:exactness)
|
161
|
-
state[:strictness] = strictness == :strong ? true : strictness
|
162
170
|
|
163
171
|
alternatives = []
|
164
172
|
known_variants.each do |_, variant_fn|
|
@@ -177,13 +185,10 @@ module OpenAI
|
|
177
185
|
end
|
178
186
|
end
|
179
187
|
|
180
|
-
case alternatives.sort_by(&:first)
|
188
|
+
case alternatives.sort_by!(&:first)
|
181
189
|
in []
|
182
190
|
exactness[:no] += 1
|
183
|
-
|
184
|
-
message = "no possible conversion of #{value.class} into a variant of #{target.inspect}"
|
185
|
-
raise ArgumentError.new(message)
|
186
|
-
end
|
191
|
+
state[:error] = ArgumentError.new("no matching variant for #{value.inspect}")
|
187
192
|
value
|
188
193
|
in [[_, exact, coerced], *]
|
189
194
|
exact.each { exactness[_1] += _2 }
|
@@ -33,14 +33,20 @@ module OpenAI
|
|
33
33
|
class << self
|
34
34
|
# @api private
|
35
35
|
#
|
36
|
+
# No coercion needed for Unknown type.
|
37
|
+
#
|
36
38
|
# @param value [Object]
|
37
39
|
#
|
38
40
|
# @param state [Hash{Symbol=>Object}] .
|
39
41
|
#
|
40
|
-
# @option state [Boolean
|
42
|
+
# @option state [Boolean] :translate_names
|
43
|
+
#
|
44
|
+
# @option state [Boolean] :strictness
|
41
45
|
#
|
42
46
|
# @option state [Hash{Symbol=>Object}] :exactness
|
43
47
|
#
|
48
|
+
# @option state [Class<StandardError>] :error
|
49
|
+
#
|
44
50
|
# @option state [Integer] :branched
|
45
51
|
#
|
46
52
|
# @return [Object]
|
@@ -46,12 +46,19 @@ module OpenAI
|
|
46
46
|
|
47
47
|
# @!attribute speed
|
48
48
|
# The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is
|
49
|
-
# the default.
|
49
|
+
# the default.
|
50
50
|
#
|
51
51
|
# @return [Float, nil]
|
52
52
|
optional :speed, Float
|
53
53
|
|
54
|
-
# @!
|
54
|
+
# @!attribute stream_format
|
55
|
+
# The format to stream the audio in. Supported formats are `sse` and `audio`.
|
56
|
+
# `sse` is not supported for `tts-1` or `tts-1-hd`.
|
57
|
+
#
|
58
|
+
# @return [Symbol, OpenAI::Models::Audio::SpeechCreateParams::StreamFormat, nil]
|
59
|
+
optional :stream_format, enum: -> { OpenAI::Audio::SpeechCreateParams::StreamFormat }
|
60
|
+
|
61
|
+
# @!method initialize(input:, model:, voice:, instructions: nil, response_format: nil, speed: nil, stream_format: nil, request_options: {})
|
55
62
|
# Some parameter documentations has been truncated, see
|
56
63
|
# {OpenAI::Models::Audio::SpeechCreateParams} for more details.
|
57
64
|
#
|
@@ -67,6 +74,8 @@ module OpenAI
|
|
67
74
|
#
|
68
75
|
# @param speed [Float] The speed of the generated audio. Select a value from `0.25` to `4.0`. `1.0` is
|
69
76
|
#
|
77
|
+
# @param stream_format [Symbol, OpenAI::Models::Audio::SpeechCreateParams::StreamFormat] The format to stream the audio in. Supported formats are `sse` and `audio`. `sse
|
78
|
+
#
|
70
79
|
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}]
|
71
80
|
|
72
81
|
# One of the available [TTS models](https://platform.openai.com/docs/models#tts):
|
@@ -153,6 +162,18 @@ module OpenAI
|
|
153
162
|
# @!method self.values
|
154
163
|
# @return [Array<Symbol>]
|
155
164
|
end
|
165
|
+
|
166
|
+
# The format to stream the audio in. Supported formats are `sse` and `audio`.
|
167
|
+
# `sse` is not supported for `tts-1` or `tts-1-hd`.
|
168
|
+
module StreamFormat
|
169
|
+
extend OpenAI::Internal::Type::Enum
|
170
|
+
|
171
|
+
SSE = :sse
|
172
|
+
AUDIO = :audio
|
173
|
+
|
174
|
+
# @!method self.values
|
175
|
+
# @return [Array<Symbol>]
|
176
|
+
end
|
156
177
|
end
|
157
178
|
end
|
158
179
|
end
|