openai 0.107.0 → 0.109.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 +30 -0
- data/README.md +55 -1
- data/examples/chat/tool_runner.rb +33 -0
- data/lib/openai/client.rb +2 -2
- data/lib/openai/helpers/chat/tool_runner.rb +259 -0
- data/lib/openai/helpers/client_runtime.rb +11 -0
- data/lib/openai/helpers/realtime/recovery.rb +8 -2
- data/lib/openai/helpers/responses_websocket/incremental.rb +5 -1
- data/lib/openai/helpers/responses_websocket/session.rb +11 -4
- data/lib/openai/helpers/streaming/chat_completion_resource.rb +52 -0
- data/lib/openai/internal/provider.rb +1 -0
- data/lib/openai/models/admin/organization/usage_audio_speeches_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_audio_transcriptions_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_code_interpreter_sessions_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_completions_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_costs_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_decisions_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_embeddings_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_file_search_calls_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_images_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_moderations_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_vector_stores_response.rb +4 -4
- data/lib/openai/models/admin/organization/usage_web_search_calls_response.rb +4 -4
- data/lib/openai/models/audio/voice_consent.rb +58 -0
- data/lib/openai/models/audio/voice_consent_create_params.rb +57 -0
- data/lib/openai/models/audio/voice_consent_delete_params.rb +22 -0
- data/lib/openai/models/audio/voice_consent_deleted.rb +34 -0
- data/lib/openai/models/audio/voice_consent_list_params.rb +42 -0
- data/lib/openai/models/audio/voice_consent_retrieve_params.rb +22 -0
- data/lib/openai/models/audio/voice_consent_update_params.rb +32 -0
- data/lib/openai/providers/vertex.rb +229 -0
- data/lib/openai/resources/audio/voice_consents.rb +163 -0
- data/lib/openai/resources/audio.rb +5 -0
- data/lib/openai/version.rb +1 -1
- data/lib/openai.rb +9 -0
- data/rbi/openai/helpers/chat/tool_runner.rbi +74 -0
- data/rbi/openai/internal/provider.rbi +3 -0
- data/rbi/openai/models/admin/organization/usage_audio_speeches_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_audio_transcriptions_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_code_interpreter_sessions_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_completions_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_costs_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_decisions_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_embeddings_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_file_search_calls_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_images_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_moderations_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_vector_stores_response.rbi +4 -4
- data/rbi/openai/models/admin/organization/usage_web_search_calls_response.rbi +4 -4
- data/rbi/openai/models/audio/voice_consent.rbi +86 -0
- data/rbi/openai/models/audio/voice_consent_create_params.rbi +92 -0
- data/rbi/openai/models/audio/voice_consent_delete_params.rbi +53 -0
- data/rbi/openai/models/audio/voice_consent_deleted.rbi +62 -0
- data/rbi/openai/models/audio/voice_consent_list_params.rbi +78 -0
- data/rbi/openai/models/audio/voice_consent_retrieve_params.rbi +53 -0
- data/rbi/openai/models/audio/voice_consent_update_params.rbi +62 -0
- data/rbi/openai/models/response_format_json_schema.rbi +13 -11
- data/rbi/openai/providers.rbi +13 -0
- data/rbi/openai/resources/audio/voice_consents.rbi +108 -0
- data/rbi/openai/resources/audio.rbi +4 -0
- data/sig/openai/helpers/chat/tool_runner.rbs +48 -0
- data/sig/openai/internal/provider.rbs +3 -1
- data/sig/openai/models/admin/organization/usage_audio_speeches_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_audio_transcriptions_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_code_interpreter_sessions_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_completions_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_costs_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_decisions_response.rbs +4 -4
- data/sig/openai/models/admin/organization/usage_embeddings_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_file_search_calls_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_images_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_moderations_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_vector_stores_response.rbs +6 -6
- data/sig/openai/models/admin/organization/usage_web_search_calls_response.rbs +6 -6
- data/sig/openai/models/audio/voice_consent.rbs +57 -0
- data/sig/openai/models/audio/voice_consent_create_params.rbs +61 -0
- data/sig/openai/models/audio/voice_consent_delete_params.rbs +25 -0
- data/sig/openai/models/audio/voice_consent_deleted.rbs +31 -0
- data/sig/openai/models/audio/voice_consent_list_params.rbs +57 -0
- data/sig/openai/models/audio/voice_consent_retrieve_params.rbs +25 -0
- data/sig/openai/models/audio/voice_consent_update_params.rbs +36 -0
- data/sig/openai/providers.rbs +8 -0
- data/sig/openai/resources/audio/voice_consents.rbs +38 -0
- data/sig/openai/resources/audio.rbs +2 -0
- data/vertex.md +29 -0
- metadata +32 -1
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "timeout"
|
|
4
|
+
|
|
5
|
+
module OpenAI
|
|
6
|
+
module Providers
|
|
7
|
+
# @api private
|
|
8
|
+
module Vertex
|
|
9
|
+
SCOPE = "https://www.googleapis.com/auth/cloud-platform"
|
|
10
|
+
AUTH_MARKER = :openai_vertex_bearer
|
|
11
|
+
|
|
12
|
+
class Definition
|
|
13
|
+
def initialize(base_url:, token_provider:, credentials:)
|
|
14
|
+
@base_url = base_url.freeze
|
|
15
|
+
@token_provider = token_provider
|
|
16
|
+
@credentials = credentials
|
|
17
|
+
@credentials_mutex = Mutex.new
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def name = "vertex"
|
|
21
|
+
|
|
22
|
+
def configure
|
|
23
|
+
token_provider = @token_provider
|
|
24
|
+
credentials = @credentials
|
|
25
|
+
unless token_provider || credentials
|
|
26
|
+
begin
|
|
27
|
+
require "googleauth"
|
|
28
|
+
|
|
29
|
+
rescue LoadError => e
|
|
30
|
+
raise LoadError.new("Vertex ADC requires optional gem \"googleauth\"; add it to your Gemfile."), cause: e
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
begin
|
|
34
|
+
credentials = Google::Auth.get_application_default(SCOPE)
|
|
35
|
+
rescue StandardError => e
|
|
36
|
+
raise OpenAI::Errors::Error.new("Vertex could not load Google Application Default Credentials."), cause: e
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
if credentials
|
|
41
|
+
# googleauth apply! refreshes expired tokens. Serialize just this
|
|
42
|
+
# cache/refresh step across all clients using this provider.
|
|
43
|
+
mutex = @credentials_mutex
|
|
44
|
+
rejected_token = nil
|
|
45
|
+
token_provider = lambda do
|
|
46
|
+
headers = {}
|
|
47
|
+
mutex.synchronize do
|
|
48
|
+
credentials.apply!(headers)
|
|
49
|
+
token = headers.fetch(:authorization) { headers.fetch("authorization") }.delete_prefix("Bearer ")
|
|
50
|
+
if token == rejected_token && credentials.respond_to?(:fetch_access_token!)
|
|
51
|
+
credentials.fetch_access_token!
|
|
52
|
+
credentials.apply!(headers)
|
|
53
|
+
token = headers.fetch(:authorization) { headers.fetch("authorization") }.delete_prefix("Bearer ")
|
|
54
|
+
rejected_token = nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
token
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# Share the replay allowance and retry count, but reset the deadline
|
|
63
|
+
# for each ordinary transport retry. A 401 replay keeps its deadline.
|
|
64
|
+
# Refresh itself happens in prepare_request, under its timeout and mutex.
|
|
65
|
+
if credentials.respond_to?(:fetch_access_token!)
|
|
66
|
+
wrapper = lambda do |request, replayable, retry_count, &send_request|
|
|
67
|
+
context = request[:vertex_auth_context] || {replayed: false}
|
|
68
|
+
context[:retry_count] = retry_count
|
|
69
|
+
context[:deadline] = request[:timeout]&.then { OpenAI::Internal::Util.monotonic_secs + _1 }
|
|
70
|
+
request = request.merge(vertex_auth_context: context)
|
|
71
|
+
begin
|
|
72
|
+
send_request.call(request, context[:retry_count])
|
|
73
|
+
rescue OpenAI::Errors::AuthenticationError
|
|
74
|
+
remaining = context[:deadline] && (context[:deadline] - OpenAI::Internal::Util.monotonic_secs)
|
|
75
|
+
if remaining && remaining <= 0
|
|
76
|
+
raise OpenAI::Errors::APITimeoutError.new(url: request.fetch(:url))
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
begin
|
|
80
|
+
Timeout.timeout(remaining) { mutex.synchronize { rejected_token = context[:token] } }
|
|
81
|
+
rescue Timeout::Error
|
|
82
|
+
raise OpenAI::Errors::APITimeoutError.new(url: request.fetch(:url)), cause: nil
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
raise if context[:replayed] || !replayable || context[:retry_count] >= request.fetch(:max_retries)
|
|
86
|
+
|
|
87
|
+
context[:replayed] = true
|
|
88
|
+
context[:retry_count] += 1
|
|
89
|
+
retry
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
base = URI(@base_url)
|
|
95
|
+
OpenAI::Internal::Provider::Runtime.new(
|
|
96
|
+
name: name,
|
|
97
|
+
base_url: @base_url,
|
|
98
|
+
authentication_headers: %w[authorization],
|
|
99
|
+
wrap_request: wrapper,
|
|
100
|
+
prepare_request: lambda do |request|
|
|
101
|
+
url = request.fetch(:url)
|
|
102
|
+
unless OpenAI::Internal::Util.uri_origin(url) == OpenAI::Internal::Util.uri_origin(base)
|
|
103
|
+
raise OpenAI::Errors::Error, "Vertex refuses credentials for an origin other than the configured URL."
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
headers = request.fetch(:headers).dup
|
|
107
|
+
if request[:provider_auth] == AUTH_MARKER
|
|
108
|
+
headers.delete("authorization")
|
|
109
|
+
elsif headers.key?("authorization")
|
|
110
|
+
raise(
|
|
111
|
+
OpenAI::Errors::Error,
|
|
112
|
+
"Vertex authentication cannot be combined with a custom Authorization header."
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
if headers.key?("api-key")
|
|
117
|
+
raise OpenAI::Errors::Error, "Vertex authentication cannot be combined with a custom api-key header."
|
|
118
|
+
end
|
|
119
|
+
# The outer Google API version differs for stored Responses.
|
|
120
|
+
# Do not change other gateway layouts.
|
|
121
|
+
prefix = "#{base.path.delete_suffix("/")}/responses/"
|
|
122
|
+
if [:get, :delete].include?(request[:method]) &&
|
|
123
|
+
url.path.start_with?(prefix) &&
|
|
124
|
+
base.path.start_with?("/v1/projects/")
|
|
125
|
+
url = url.dup
|
|
126
|
+
url.path = url.path.sub(%r{\A/v1/}, "/v1beta1/")
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
headers.delete("openai-organization")
|
|
130
|
+
headers.delete("openai-project")
|
|
131
|
+
timeout = request[:timeout]
|
|
132
|
+
context = request[:vertex_auth_context]
|
|
133
|
+
timeout = context[:deadline] - OpenAI::Internal::Util.monotonic_secs if context&.dig(:deadline)
|
|
134
|
+
if timeout && timeout <= 0
|
|
135
|
+
raise OpenAI::Errors::APITimeoutError.new(url: url, message: "Vertex credential lookup timed out")
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
started = OpenAI::Internal::Util.monotonic_secs
|
|
139
|
+
token = begin
|
|
140
|
+
Timeout.timeout(timeout) { token_provider.call }
|
|
141
|
+
rescue Timeout::Error => e
|
|
142
|
+
raise(
|
|
143
|
+
OpenAI::Errors::APITimeoutError.new(url: url, message: "Vertex credential lookup timed out"),
|
|
144
|
+
cause: e
|
|
145
|
+
)
|
|
146
|
+
rescue StandardError => e
|
|
147
|
+
raise OpenAI::Errors::Error.new("Vertex failed to resolve Google credentials."), cause: e
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
remaining = timeout && (timeout - (OpenAI::Internal::Util.monotonic_secs - started))
|
|
151
|
+
if remaining && remaining <= 0
|
|
152
|
+
raise OpenAI::Errors::APITimeoutError.new(url: url, message: "Vertex credential lookup timed out")
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
if credentials.respond_to?(:quota_project_id) && (quota = credentials.quota_project_id)
|
|
156
|
+
headers["x-goog-user-project"] = quota
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
unless token.is_a?(String) && !token.strip.empty?
|
|
160
|
+
raise OpenAI::Errors::Error, "Vertex token_provider must return a non-empty access token string."
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
context[:token] = token if context
|
|
164
|
+
|
|
165
|
+
request.merge(
|
|
166
|
+
url: url,
|
|
167
|
+
timeout: remaining,
|
|
168
|
+
headers: headers.merge("authorization" => "Bearer #{token}"),
|
|
169
|
+
provider_auth: AUTH_MARKER,
|
|
170
|
+
follow_redirects: false
|
|
171
|
+
)
|
|
172
|
+
end
|
|
173
|
+
)
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
class << self
|
|
179
|
+
# Use Google Application Default Credentials with the regular Responses
|
|
180
|
+
# client. Supply token_provider: -> { ... } for application-managed credentials.
|
|
181
|
+
# It is called per attempt and should cache/refresh tokens as needed.
|
|
182
|
+
#
|
|
183
|
+
# Base URL is the complete trusted provider URL before /responses. When
|
|
184
|
+
# omitted, project and location are required. OpenAI environment defaults
|
|
185
|
+
# and top-level auth/base_url options are ignored/rejected by Client.
|
|
186
|
+
def vertex(project: nil, location: nil, base_url: nil, token_provider: nil, credentials: nil)
|
|
187
|
+
if credentials && token_provider
|
|
188
|
+
raise ArgumentError, "Vertex credentials and token_provider are mutually exclusive."
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
if credentials && !credentials.respond_to?(:apply!)
|
|
192
|
+
raise ArgumentError, "Vertex credentials must provide Google's apply! method."
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
unless token_provider.nil? || token_provider.respond_to?(:call)
|
|
196
|
+
raise ArgumentError, "Vertex token_provider must respond to call."
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
if base_url.nil?
|
|
200
|
+
project_segment = /\A[a-zA-Z0-9][a-zA-Z0-9_.:-]*\z/
|
|
201
|
+
location_segment = /\A[a-zA-Z0-9][a-zA-Z0-9_-]*\z/
|
|
202
|
+
unless project.is_a?(String) &&
|
|
203
|
+
location.is_a?(String) &&
|
|
204
|
+
project_segment.match?(project) &&
|
|
205
|
+
location_segment.match?(location)
|
|
206
|
+
raise ArgumentError, "Vertex project and location are required and must be single path segments."
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
host = location == "global" ? "aiplatform.googleapis.com" : "#{location}-aiplatform.googleapis.com"
|
|
210
|
+
base_url = "https://#{host}/v1/projects/#{project}/locations/#{location}/publishers/openai/v1"
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
begin
|
|
214
|
+
uri = URI(base_url.to_s)
|
|
215
|
+
unless %w[http https].include?(uri.scheme) && uri.host && !uri.userinfo && !uri.query && !uri.fragment
|
|
216
|
+
raise URI::InvalidURIError
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
rescue URI::InvalidURIError
|
|
220
|
+
raise ArgumentError, "Vertex base_url must be an absolute HTTP(S) URL without credentials, query or fragment."
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
OpenAI::Internal::Provider.create(
|
|
224
|
+
Vertex::Definition.new(base_url: uri.to_s, token_provider: token_provider, credentials: credentials)
|
|
225
|
+
)
|
|
226
|
+
end
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
end
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenAI
|
|
4
|
+
module Resources
|
|
5
|
+
class Audio
|
|
6
|
+
# Turn audio into text or text into audio.
|
|
7
|
+
class VoiceConsents
|
|
8
|
+
# Upload a voice consent recording.
|
|
9
|
+
#
|
|
10
|
+
# `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
|
|
11
|
+
# metadata. Use `OpenAI::FilePart` when you need to override the filename or
|
|
12
|
+
# content type.
|
|
13
|
+
#
|
|
14
|
+
# @overload create(language:, name:, recording:, request_options: {})
|
|
15
|
+
#
|
|
16
|
+
# @param language [String]
|
|
17
|
+
# The BCP 47 language tag for the consent phrase (for example, `en-US`).
|
|
18
|
+
#
|
|
19
|
+
# @param name [String]
|
|
20
|
+
# The label to use for this consent recording.
|
|
21
|
+
#
|
|
22
|
+
# @param recording [Pathname, StringIO, IO, String, OpenAI::FilePart]
|
|
23
|
+
# The consent audio recording file. Maximum size is 10 MiB.
|
|
24
|
+
#
|
|
25
|
+
# Supported MIME types: `audio/mpeg`, `audio/wav`, `audio/x-wav`, `audio/ogg`,
|
|
26
|
+
# `audio/aac`, `audio/flac`, `audio/webm`, `audio/mp4`.
|
|
27
|
+
#
|
|
28
|
+
# `String`, `StringIO`, and pathless `IO` inputs are sent with generic upload
|
|
29
|
+
# metadata. Use `OpenAI::FilePart` when you need to override the filename or
|
|
30
|
+
# content type.
|
|
31
|
+
#
|
|
32
|
+
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
33
|
+
#
|
|
34
|
+
# @return [OpenAI::Models::Audio::VoiceConsent]
|
|
35
|
+
#
|
|
36
|
+
# @see OpenAI::Models::Audio::VoiceConsentCreateParams
|
|
37
|
+
def create(params)
|
|
38
|
+
parsed, options = OpenAI::Audio::VoiceConsentCreateParams.dump_request(params)
|
|
39
|
+
@client.request(
|
|
40
|
+
method: :post,
|
|
41
|
+
path: "audio/voice_consents",
|
|
42
|
+
headers: {"content-type" => "multipart/form-data"},
|
|
43
|
+
body: parsed,
|
|
44
|
+
model: OpenAI::Audio::VoiceConsent,
|
|
45
|
+
security: {bearer_auth: true},
|
|
46
|
+
options: options
|
|
47
|
+
)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Retrieves a voice consent recording.
|
|
51
|
+
#
|
|
52
|
+
# @overload retrieve(consent_id, request_options: {})
|
|
53
|
+
#
|
|
54
|
+
# @param consent_id [String]
|
|
55
|
+
# The ID of the consent recording to retrieve.
|
|
56
|
+
#
|
|
57
|
+
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
58
|
+
#
|
|
59
|
+
# @return [OpenAI::Models::Audio::VoiceConsent]
|
|
60
|
+
#
|
|
61
|
+
# @see OpenAI::Models::Audio::VoiceConsentRetrieveParams
|
|
62
|
+
def retrieve(consent_id, params = {})
|
|
63
|
+
@client.request(
|
|
64
|
+
method: :get,
|
|
65
|
+
path: ["audio/voice_consents/%1$s", consent_id],
|
|
66
|
+
model: OpenAI::Audio::VoiceConsent,
|
|
67
|
+
security: {bearer_auth: true},
|
|
68
|
+
options: params[:request_options]
|
|
69
|
+
)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Updates a voice consent recording (metadata only).
|
|
73
|
+
#
|
|
74
|
+
# @overload update(consent_id, name:, request_options: {})
|
|
75
|
+
#
|
|
76
|
+
# @param consent_id [String]
|
|
77
|
+
# The ID of the consent recording to update.
|
|
78
|
+
#
|
|
79
|
+
# @param name [String]
|
|
80
|
+
# The updated label for this consent recording.
|
|
81
|
+
#
|
|
82
|
+
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
83
|
+
#
|
|
84
|
+
# @return [OpenAI::Models::Audio::VoiceConsent]
|
|
85
|
+
#
|
|
86
|
+
# @see OpenAI::Models::Audio::VoiceConsentUpdateParams
|
|
87
|
+
def update(consent_id, params)
|
|
88
|
+
parsed, options = OpenAI::Audio::VoiceConsentUpdateParams.dump_request(params)
|
|
89
|
+
@client.request(
|
|
90
|
+
method: :post,
|
|
91
|
+
path: ["audio/voice_consents/%1$s", consent_id],
|
|
92
|
+
body: parsed,
|
|
93
|
+
model: OpenAI::Audio::VoiceConsent,
|
|
94
|
+
security: {bearer_auth: true},
|
|
95
|
+
options: options
|
|
96
|
+
)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Returns a list of voice consent recordings.
|
|
100
|
+
#
|
|
101
|
+
# @overload list(after: nil, limit: nil, request_options: {})
|
|
102
|
+
#
|
|
103
|
+
# @param after [String]
|
|
104
|
+
# A cursor for use in pagination. `after` is an object ID that defines your place
|
|
105
|
+
# in the list. For instance, if you make a list request and receive 100 objects,
|
|
106
|
+
# ending with obj_foo, your subsequent call can include after=obj_foo in order to
|
|
107
|
+
# fetch the next page of the list.
|
|
108
|
+
#
|
|
109
|
+
# @param limit [Integer]
|
|
110
|
+
# A limit on the number of objects to be returned. Limit can range between 1 and
|
|
111
|
+
# 100, and the default is 20.
|
|
112
|
+
#
|
|
113
|
+
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
114
|
+
#
|
|
115
|
+
# @return [OpenAI::Internal::CursorPage<OpenAI::Models::Audio::VoiceConsent>]
|
|
116
|
+
#
|
|
117
|
+
# @see OpenAI::Models::Audio::VoiceConsentListParams
|
|
118
|
+
def list(params = {})
|
|
119
|
+
parsed, options = OpenAI::Audio::VoiceConsentListParams.dump_request(params)
|
|
120
|
+
query = OpenAI::Internal::Util.encode_query_params(parsed)
|
|
121
|
+
@client.request(
|
|
122
|
+
method: :get,
|
|
123
|
+
path: "audio/voice_consents",
|
|
124
|
+
query: query,
|
|
125
|
+
page: OpenAI::Internal::CursorPage,
|
|
126
|
+
model: OpenAI::Audio::VoiceConsent,
|
|
127
|
+
security: {bearer_auth: true},
|
|
128
|
+
options: options
|
|
129
|
+
)
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
# Deletes a voice consent recording.
|
|
133
|
+
#
|
|
134
|
+
# @overload delete(consent_id, request_options: {})
|
|
135
|
+
#
|
|
136
|
+
# @param consent_id [String]
|
|
137
|
+
# The ID of the consent recording to delete.
|
|
138
|
+
#
|
|
139
|
+
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
140
|
+
#
|
|
141
|
+
# @return [OpenAI::Models::Audio::VoiceConsentDeleted]
|
|
142
|
+
#
|
|
143
|
+
# @see OpenAI::Models::Audio::VoiceConsentDeleteParams
|
|
144
|
+
def delete(consent_id, params = {})
|
|
145
|
+
@client.request(
|
|
146
|
+
method: :delete,
|
|
147
|
+
path: ["audio/voice_consents/%1$s", consent_id],
|
|
148
|
+
model: OpenAI::Audio::VoiceConsentDeleted,
|
|
149
|
+
security: {bearer_auth: true},
|
|
150
|
+
options: params[:request_options]
|
|
151
|
+
)
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# @api private
|
|
155
|
+
#
|
|
156
|
+
# @param client [OpenAI::Client]
|
|
157
|
+
def initialize(client:)
|
|
158
|
+
@client = client
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
@@ -19,6 +19,10 @@ module OpenAI
|
|
|
19
19
|
# @return [OpenAI::Resources::Audio::Voices]
|
|
20
20
|
attr_reader :voices
|
|
21
21
|
|
|
22
|
+
# Turn audio into text or text into audio.
|
|
23
|
+
# @return [OpenAI::Resources::Audio::VoiceConsents]
|
|
24
|
+
attr_reader :voice_consents
|
|
25
|
+
|
|
22
26
|
# @api private
|
|
23
27
|
#
|
|
24
28
|
# @param client [OpenAI::Client]
|
|
@@ -28,6 +32,7 @@ module OpenAI
|
|
|
28
32
|
@translations = OpenAI::Resources::Audio::Translations.new(client: client)
|
|
29
33
|
@speech = OpenAI::Resources::Audio::Speech.new(client: client)
|
|
30
34
|
@voices = OpenAI::Resources::Audio::Voices.new(client: client)
|
|
35
|
+
@voice_consents = OpenAI::Resources::Audio::VoiceConsents.new(client: client)
|
|
31
36
|
end
|
|
32
37
|
end
|
|
33
38
|
end
|
data/lib/openai/version.rb
CHANGED
data/lib/openai.rb
CHANGED
|
@@ -69,6 +69,7 @@ require_relative "openai/provider"
|
|
|
69
69
|
require_relative "openai/internal/provider"
|
|
70
70
|
require_relative "openai/providers/azure"
|
|
71
71
|
require_relative "openai/providers/bedrock"
|
|
72
|
+
require_relative "openai/providers/vertex"
|
|
72
73
|
require_relative "openai/internal/transport/request_body_merge"
|
|
73
74
|
require_relative "openai/internal/transport/base_client"
|
|
74
75
|
require_relative "openai/helpers/client_options"
|
|
@@ -462,6 +463,13 @@ require_relative "openai/models/audio/translation_create_params"
|
|
|
462
463
|
require_relative "openai/models/audio/translation_create_response"
|
|
463
464
|
require_relative "openai/models/audio/translation_verbose"
|
|
464
465
|
require_relative "openai/models/audio/voice"
|
|
466
|
+
require_relative "openai/models/audio/voice_consent"
|
|
467
|
+
require_relative "openai/models/audio/voice_consent_create_params"
|
|
468
|
+
require_relative "openai/models/audio/voice_consent_deleted"
|
|
469
|
+
require_relative "openai/models/audio/voice_consent_delete_params"
|
|
470
|
+
require_relative "openai/models/audio/voice_consent_list_params"
|
|
471
|
+
require_relative "openai/models/audio/voice_consent_retrieve_params"
|
|
472
|
+
require_relative "openai/models/audio/voice_consent_update_params"
|
|
465
473
|
require_relative "openai/models/audio/voice_create_params"
|
|
466
474
|
require_relative "openai/models/audio_model"
|
|
467
475
|
require_relative "openai/models/audio_response_format"
|
|
@@ -1558,6 +1566,7 @@ require_relative "openai/resources/audio"
|
|
|
1558
1566
|
require_relative "openai/resources/audio/speech"
|
|
1559
1567
|
require_relative "openai/resources/audio/transcriptions"
|
|
1560
1568
|
require_relative "openai/resources/audio/translations"
|
|
1569
|
+
require_relative "openai/resources/audio/voice_consents"
|
|
1561
1570
|
require_relative "openai/resources/audio/voices"
|
|
1562
1571
|
require_relative "openai/resources/batches"
|
|
1563
1572
|
require_relative "openai/resources/beta"
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# typed: strong
|
|
2
|
+
|
|
3
|
+
module OpenAI
|
|
4
|
+
module Helpers
|
|
5
|
+
module Chat
|
|
6
|
+
class ToolRunner
|
|
7
|
+
Handler = T.type_alias { T.proc.params(arguments: T::Hash[String, T.untyped]).returns(T.untyped) }
|
|
8
|
+
|
|
9
|
+
class Error < StandardError
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
class MaxRoundsError < Error
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# @api private
|
|
16
|
+
sig do
|
|
17
|
+
params(
|
|
18
|
+
completions: OpenAI::Resources::Chat::Completions,
|
|
19
|
+
params: T::Hash[Symbol, T.untyped],
|
|
20
|
+
tool_handlers: T::Hash[String, Handler],
|
|
21
|
+
max_rounds: Integer
|
|
22
|
+
)
|
|
23
|
+
.void
|
|
24
|
+
end
|
|
25
|
+
def initialize(completions:, params:, tool_handlers:, max_rounds:)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @api private
|
|
29
|
+
sig { returns(OpenAI::Chat::ChatCompletion) }
|
|
30
|
+
def run
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
module Resources
|
|
37
|
+
class Chat
|
|
38
|
+
class Completions
|
|
39
|
+
# @api private
|
|
40
|
+
sig { params(params: T::Hash[Symbol, T.untyped]).returns(OpenAI::Chat::ChatCompletion) }
|
|
41
|
+
def create_for_tool_runner(params)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
sig do
|
|
45
|
+
params(
|
|
46
|
+
model: T.any(String, OpenAI::ChatModel::OrSymbol),
|
|
47
|
+
messages: T::Array[
|
|
48
|
+
T.any(
|
|
49
|
+
OpenAI::Chat::ChatCompletionDeveloperMessageParam::OrHash,
|
|
50
|
+
OpenAI::Chat::ChatCompletionSystemMessageParam::OrHash,
|
|
51
|
+
OpenAI::Chat::ChatCompletionUserMessageParam::OrHash,
|
|
52
|
+
OpenAI::Chat::ChatCompletionAssistantMessageParam::OrHash,
|
|
53
|
+
OpenAI::Chat::ChatCompletionToolMessageParam::OrHash,
|
|
54
|
+
OpenAI::Chat::ChatCompletionFunctionMessageParam::OrHash
|
|
55
|
+
)
|
|
56
|
+
],
|
|
57
|
+
tools: T::Array[
|
|
58
|
+
T.any(
|
|
59
|
+
OpenAI::StructuredOutput::JsonSchemaConverter,
|
|
60
|
+
OpenAI::Chat::ChatCompletionFunctionTool::OrHash
|
|
61
|
+
)
|
|
62
|
+
],
|
|
63
|
+
tool_handlers: T::Hash[String, OpenAI::Helpers::Chat::ToolRunner::Handler],
|
|
64
|
+
max_rounds: Integer,
|
|
65
|
+
params: T.untyped
|
|
66
|
+
)
|
|
67
|
+
.returns(OpenAI::Chat::ChatCompletion)
|
|
68
|
+
end
|
|
69
|
+
def run_tools(model:, messages:, tools:, tool_handlers:, max_rounds: 10, **params)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -232,8 +232,8 @@ module OpenAI
|
|
|
232
232
|
sig { returns(T.nilable(Integer)) }
|
|
233
233
|
attr_accessor :input_cache_write_30m_tokens
|
|
234
234
|
|
|
235
|
-
# The aggregated number of input tokens written to the cache
|
|
236
|
-
# retention
|
|
235
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
236
|
+
# 12-hour retention periods.
|
|
237
237
|
sig { returns(T.nilable(Integer)) }
|
|
238
238
|
attr_reader :input_cache_write_tokens
|
|
239
239
|
|
|
@@ -431,8 +431,8 @@ module OpenAI
|
|
|
431
431
|
# retention period. May be absent or null for older responses.
|
|
432
432
|
input_cache_write_30m_tokens: nil,
|
|
433
433
|
|
|
434
|
-
# The aggregated number of input tokens written to the cache
|
|
435
|
-
# retention
|
|
434
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
435
|
+
# 12-hour retention periods.
|
|
436
436
|
input_cache_write_tokens: nil,
|
|
437
437
|
|
|
438
438
|
# The aggregated number of cached audio input tokens used.
|
|
@@ -234,8 +234,8 @@ module OpenAI
|
|
|
234
234
|
sig { returns(T.nilable(Integer)) }
|
|
235
235
|
attr_accessor :input_cache_write_30m_tokens
|
|
236
236
|
|
|
237
|
-
# The aggregated number of input tokens written to the cache
|
|
238
|
-
# retention
|
|
237
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
238
|
+
# 12-hour retention periods.
|
|
239
239
|
sig { returns(T.nilable(Integer)) }
|
|
240
240
|
attr_reader :input_cache_write_tokens
|
|
241
241
|
|
|
@@ -433,8 +433,8 @@ module OpenAI
|
|
|
433
433
|
# retention period. May be absent or null for older responses.
|
|
434
434
|
input_cache_write_30m_tokens: nil,
|
|
435
435
|
|
|
436
|
-
# The aggregated number of input tokens written to the cache
|
|
437
|
-
# retention
|
|
436
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
437
|
+
# 12-hour retention periods.
|
|
438
438
|
input_cache_write_tokens: nil,
|
|
439
439
|
|
|
440
440
|
# The aggregated number of cached audio input tokens used.
|
|
@@ -236,8 +236,8 @@ module OpenAI
|
|
|
236
236
|
sig { returns(T.nilable(Integer)) }
|
|
237
237
|
attr_accessor :input_cache_write_30m_tokens
|
|
238
238
|
|
|
239
|
-
# The aggregated number of input tokens written to the cache
|
|
240
|
-
# retention
|
|
239
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
240
|
+
# 12-hour retention periods.
|
|
241
241
|
sig { returns(T.nilable(Integer)) }
|
|
242
242
|
attr_reader :input_cache_write_tokens
|
|
243
243
|
|
|
@@ -435,8 +435,8 @@ module OpenAI
|
|
|
435
435
|
# retention period. May be absent or null for older responses.
|
|
436
436
|
input_cache_write_30m_tokens: nil,
|
|
437
437
|
|
|
438
|
-
# The aggregated number of input tokens written to the cache
|
|
439
|
-
# retention
|
|
438
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
439
|
+
# 12-hour retention periods.
|
|
440
440
|
input_cache_write_tokens: nil,
|
|
441
441
|
|
|
442
442
|
# The aggregated number of cached audio input tokens used.
|
|
@@ -232,8 +232,8 @@ module OpenAI
|
|
|
232
232
|
sig { returns(T.nilable(Integer)) }
|
|
233
233
|
attr_accessor :input_cache_write_30m_tokens
|
|
234
234
|
|
|
235
|
-
# The aggregated number of input tokens written to the cache
|
|
236
|
-
# retention
|
|
235
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
236
|
+
# 12-hour retention periods.
|
|
237
237
|
sig { returns(T.nilable(Integer)) }
|
|
238
238
|
attr_reader :input_cache_write_tokens
|
|
239
239
|
|
|
@@ -431,8 +431,8 @@ module OpenAI
|
|
|
431
431
|
# retention period. May be absent or null for older responses.
|
|
432
432
|
input_cache_write_30m_tokens: nil,
|
|
433
433
|
|
|
434
|
-
# The aggregated number of input tokens written to the cache
|
|
435
|
-
# retention
|
|
434
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
435
|
+
# 12-hour retention periods.
|
|
436
436
|
input_cache_write_tokens: nil,
|
|
437
437
|
|
|
438
438
|
# The aggregated number of cached audio input tokens used.
|
|
@@ -228,8 +228,8 @@ module OpenAI
|
|
|
228
228
|
sig { returns(T.nilable(Integer)) }
|
|
229
229
|
attr_accessor :input_cache_write_30m_tokens
|
|
230
230
|
|
|
231
|
-
# The aggregated number of input tokens written to the cache
|
|
232
|
-
# retention
|
|
231
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
232
|
+
# 12-hour retention periods.
|
|
233
233
|
sig { returns(T.nilable(Integer)) }
|
|
234
234
|
attr_reader :input_cache_write_tokens
|
|
235
235
|
|
|
@@ -427,8 +427,8 @@ module OpenAI
|
|
|
427
427
|
# retention period. May be absent or null for older responses.
|
|
428
428
|
input_cache_write_30m_tokens: nil,
|
|
429
429
|
|
|
430
|
-
# The aggregated number of input tokens written to the cache
|
|
431
|
-
# retention
|
|
430
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
431
|
+
# 12-hour retention periods.
|
|
432
432
|
input_cache_write_tokens: nil,
|
|
433
433
|
|
|
434
434
|
# The aggregated number of cached audio input tokens used.
|
|
@@ -188,8 +188,8 @@ module OpenAI
|
|
|
188
188
|
sig { returns(T.nilable(Integer)) }
|
|
189
189
|
attr_accessor :input_cache_write_30m_tokens
|
|
190
190
|
|
|
191
|
-
# The aggregated number of input tokens written to the cache
|
|
192
|
-
# retention
|
|
191
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
192
|
+
# 12-hour retention periods.
|
|
193
193
|
sig { returns(T.nilable(Integer)) }
|
|
194
194
|
attr_accessor :input_cache_write_tokens
|
|
195
195
|
|
|
@@ -354,8 +354,8 @@ module OpenAI
|
|
|
354
354
|
# retention period.
|
|
355
355
|
input_cache_write_30m_tokens: nil,
|
|
356
356
|
|
|
357
|
-
# The aggregated number of input tokens written to the cache
|
|
358
|
-
# retention
|
|
357
|
+
# The aggregated number of input tokens written to the cache across 30-minute and
|
|
358
|
+
# 12-hour retention periods.
|
|
359
359
|
input_cache_write_tokens: nil,
|
|
360
360
|
|
|
361
361
|
# The aggregated number of cached audio input tokens used.
|