openai 0.108.0 → 0.110.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: bbaffc5b480678a26851b73b6b49f9f63419801d8bbec633d6ed4f3765fe4717
4
- data.tar.gz: 127b19570f47781df5644f2217d9405e1ea0e82279b319a7683c59b567cbbd72
3
+ metadata.gz: 31d71682626485e6fb27ecd72cd1d35bb2a3eb279e37b59e1e372345227a1c99
4
+ data.tar.gz: bc386aa30fb3e76d27e51eaa4892d668c55d1a91491b6d2477d06943308a5040
5
5
  SHA512:
6
- metadata.gz: ffe2a7748064e0cb03c1eb2482670a4f581323b02a0275fd9654e1f97ecaf85f9128e064f22b5075af7d615d0e9d4fee73144d57f07ceaa9dcde25a419f7b066
7
- data.tar.gz: c531be809fb0b7dd69d4cb089eea59680a01dbcc258265e47ef6b16052ffd78eeba8f2ccf094ffaa694cdd2dca602b9ebceffa65e362de1427f51e04219a6192
6
+ metadata.gz: 8004eea7d6c06815daea855a26cca2160fea55de5034030b3faf2cb93e5ac2bcd3545c0528b8aaa5a541521d844756401e6b09e9f6ef41247cd0a7890ebd7328
7
+ data.tar.gz: cfdbe5bb232b0272a269e8179f74333f94296bb8fafc251a425536567910c3b3230a946d5e59162cc5e15ab99c28f74f29a9deaeda53363193b935231349f68b
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.110.0](https://github.com/openai/openai-ruby/compare/v0.109.0...v0.110.0) (2026-10-22)
4
+
5
+
6
+ ### Features
7
+
8
+ * **api:** add voice deletion ([#954](https://github.com/openai/openai-ruby/issues/954)) ([a6257f2](https://github.com/openai/openai-ruby/commit/a6257f2737b1b98d6bda684a4fed8e2726052a3a))
9
+
10
+
11
+ ### Chores
12
+
13
+ * **api:** clarify service-account API key deletion ([#956](https://github.com/openai/openai-ruby/issues/956)) ([fac910a](https://github.com/openai/openai-ruby/commit/fac910a671e53a7c5499e1cb323dffe23c9e247d))
14
+
15
+ ## [0.109.0](https://github.com/openai/openai-ruby/compare/v0.108.0...v0.109.0) (2026-10-21)
16
+
17
+
18
+ ### Features
19
+
20
+ * add Vertex AI support for the Responses API ([#952](https://github.com/openai/openai-ruby/issues/952)) ([98f5359](https://github.com/openai/openai-ruby/commit/98f5359e3ad2133abc5e914610fe7bbd2a058f8d))
21
+
3
22
  ## [0.108.0](https://github.com/openai/openai-ruby/compare/v0.107.0...v0.108.0) (2026-10-21)
4
23
 
5
24
 
data/README.md CHANGED
@@ -15,7 +15,7 @@ To use this gem, install via Bundler by adding the following to your application
15
15
  <!-- x-release-please-start-version -->
16
16
 
17
17
  ```ruby
18
- gem "openai", "~> 0.108.0"
18
+ gem "openai", "~> 0.110.0"
19
19
  ```
20
20
 
21
21
  <!-- x-release-please-end -->
@@ -556,6 +556,12 @@ client = OpenAI::Client.new(
556
556
 
557
557
  See [bedrock.md](bedrock.md) for authentication precedence, static and refreshable credentials, endpoint configuration, and SigV4 request constraints.
558
558
 
559
+ ## Google Vertex AI
560
+
561
+ Use `OpenAI::Providers.vertex` with the Responses API. See [vertex.md](vertex.md)
562
+ for setup with Google Application Default Credentials, a credentials object, or
563
+ an access-token callback.
564
+
559
565
  ## Workload Identity Authentication
560
566
 
561
567
  For secure, automated environments like cloud-managed Kubernetes, Azure, and GCP, you can use workload identity authentication with short-lived tokens from cloud identity providers instead of long-lived API keys.
@@ -101,6 +101,17 @@ module OpenAI
101
101
 
102
102
  # @api private
103
103
  private def send_request(request, redirect_count:, retry_count:, send_retry_header:)
104
+ if (wrapper = @provider_runtime&.wrap_request)
105
+ return wrapper.call(request, request_replayable?(request), retry_count) do |attempt, attempt_retry_count|
106
+ super(
107
+ attempt,
108
+ redirect_count: redirect_count,
109
+ retry_count: attempt_retry_count,
110
+ send_retry_header: send_retry_header
111
+ )
112
+ end
113
+ end
114
+
104
115
  if @workload_identity_auth && x509_transport?(@requester)
105
116
  canonical_headers = @requester.validate_api_request!(
106
117
  url: request.fetch(:url),
@@ -11,6 +11,7 @@ module OpenAI
11
11
  :name,
12
12
  :base_url,
13
13
  :prepare_request,
14
+ :wrap_request,
14
15
  :authentication_headers,
15
16
  keyword_init: true
16
17
  )
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenAI
4
+ module Models
5
+ module Audio
6
+ # @see OpenAI::Resources::Audio::Voices#delete
7
+ class VoiceDeleteParams < OpenAI::Internal::Type::BaseModel
8
+ extend OpenAI::Internal::Type::RequestParameters::Converter
9
+ include OpenAI::Internal::Type::RequestParameters
10
+
11
+ # @!attribute voice_id
12
+ #
13
+ # @return [String]
14
+ required :voice_id, String
15
+
16
+ # @!method initialize(voice_id:, request_options: {})
17
+ # @param voice_id [String]
18
+ # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}]
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenAI
4
+ module Models
5
+ module Audio
6
+ # @see OpenAI::Resources::Audio::Voices#delete
7
+ class VoiceDeleted < OpenAI::Internal::Type::BaseModel
8
+ # @!attribute id
9
+ # The voice identifier.
10
+ #
11
+ # @return [String]
12
+ required :id, String
13
+
14
+ # @!attribute deleted
15
+ # Whether the voice was deleted.
16
+ #
17
+ # @return [Boolean]
18
+ required :deleted, OpenAI::Internal::Type::Boolean
19
+
20
+ # @!attribute object
21
+ # The object type, which is always `audio.voice.deleted`.
22
+ #
23
+ # @return [Symbol, :"audio.voice.deleted"]
24
+ required :object, const: :"audio.voice.deleted"
25
+
26
+ # @!method initialize(id:, deleted:, object: :"audio.voice.deleted")
27
+ # @param id [String]
28
+ # The voice identifier.
29
+ #
30
+ # @param deleted [Boolean]
31
+ # Whether the voice was deleted.
32
+ #
33
+ # @param object [Symbol, :"audio.voice.deleted"]
34
+ # The object type, which is always `audio.voice.deleted`.
35
+ end
36
+ end
37
+ end
38
+ end
@@ -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
@@ -140,10 +140,12 @@ module OpenAI
140
140
  )
141
141
  end
142
142
 
143
- # Deletes an API key from the project.
143
+ # Deletes an API key from the project, including keys owned by service accounts.
144
144
  #
145
- # Returns confirmation of the key deletion, or an error if the key belonged to a
146
- # service account.
145
+ # Requires permission to write project API keys. Deleting a service-account key
146
+ # does not delete the service account or its other keys.
147
+ #
148
+ # Returns confirmation of the key deletion.
147
149
  #
148
150
  # @overload delete(api_key_id, project_id:, request_options: {})
149
151
  #
@@ -41,6 +41,35 @@ module OpenAI
41
41
  )
42
42
  end
43
43
 
44
+ # Deletes a voice created from a text prompt or an audio sample.
45
+ #
46
+ # Requires voice write permission and access to the voice's project. Access to
47
+ # voices created from recordings is limited to eligible customers. See the
48
+ # [custom voices guide](https://developers.openai.com/api/docs/guides/custom-voices).
49
+ #
50
+ # Deleting a voice does not delete its consent recording. Deleting an already
51
+ # deleted voice returns a 404 error.
52
+ #
53
+ # @overload delete(voice_id, request_options: {})
54
+ #
55
+ # @param voice_id [String]
56
+ # The ID of the voice to delete.
57
+ #
58
+ # @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
59
+ #
60
+ # @return [OpenAI::Models::Audio::VoiceDeleted]
61
+ #
62
+ # @see OpenAI::Models::Audio::VoiceDeleteParams
63
+ def delete(voice_id, params = {})
64
+ @client.request(
65
+ method: :delete,
66
+ path: ["audio/voices/%1$s", voice_id],
67
+ model: OpenAI::Audio::VoiceDeleted,
68
+ security: {bearer_auth: true},
69
+ options: params[:request_options]
70
+ )
71
+ end
72
+
44
73
  # @api private
45
74
  #
46
75
  # @param client [OpenAI::Client]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenAI
4
- VERSION = "0.108.0"
4
+ VERSION = "0.110.0"
5
5
  end
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"
@@ -470,6 +471,8 @@ require_relative "openai/models/audio/voice_consent_list_params"
470
471
  require_relative "openai/models/audio/voice_consent_retrieve_params"
471
472
  require_relative "openai/models/audio/voice_consent_update_params"
472
473
  require_relative "openai/models/audio/voice_create_params"
474
+ require_relative "openai/models/audio/voice_deleted"
475
+ require_relative "openai/models/audio/voice_delete_params"
473
476
  require_relative "openai/models/audio_model"
474
477
  require_relative "openai/models/audio_response_format"
475
478
  require_relative "openai/models/auto_file_chunking_strategy_param"
@@ -25,6 +25,9 @@ module OpenAI
25
25
 
26
26
  attr_accessor :prepare_request
27
27
 
28
+ sig { returns(T.nilable(Proc)) }
29
+ attr_accessor :wrap_request
30
+
28
31
  sig { returns(T::Array[String]) }
29
32
  attr_accessor :authentication_headers
30
33
  end
@@ -0,0 +1,53 @@
1
+ # typed: strong
2
+
3
+ module OpenAI
4
+ module Models
5
+
6
+ module Audio
7
+
8
+ class VoiceDeleteParams < OpenAI::Internal::Type::BaseModel
9
+
10
+ extend OpenAI::Internal::Type::RequestParameters::Converter
11
+ include OpenAI::Internal::Type::RequestParameters
12
+
13
+ OrHash = T.type_alias do
14
+ T.any(
15
+ OpenAI::Audio::VoiceDeleteParams,
16
+ OpenAI::Internal::AnyHash
17
+ )
18
+ end
19
+
20
+ sig { returns(String) }
21
+ attr_accessor :voice_id
22
+
23
+ sig do
24
+ params(
25
+
26
+ voice_id: String,
27
+
28
+ request_options: OpenAI::RequestOptions::OrHash
29
+ )
30
+ .returns(T.attached_class)
31
+ end
32
+ def self.new(
33
+
34
+ voice_id:,
35
+
36
+ request_options: {}
37
+ )
38
+ end
39
+
40
+ sig do
41
+ override.returns(
42
+ {voice_id: String, request_options: OpenAI::RequestOptions}
43
+ )
44
+ end
45
+ def to_hash
46
+ end
47
+
48
+ end
49
+
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,67 @@
1
+ # typed: strong
2
+
3
+ module OpenAI
4
+ module Models
5
+
6
+ module Audio
7
+
8
+ class VoiceDeleted < OpenAI::Internal::Type::BaseModel
9
+
10
+ OrHash = T.type_alias do
11
+ T.any(
12
+ OpenAI::Audio::VoiceDeleted,
13
+ OpenAI::Internal::AnyHash
14
+ )
15
+ end
16
+
17
+ # The voice identifier.
18
+ sig { returns(String) }
19
+ attr_accessor :id
20
+
21
+ # Whether the voice was deleted.
22
+ sig { returns(T::Boolean) }
23
+ attr_accessor :deleted
24
+
25
+ # The object type, which is always `audio.voice.deleted`.
26
+ sig { returns(Symbol) }
27
+ attr_accessor :object
28
+
29
+ sig do
30
+ params(
31
+
32
+ id: String,
33
+
34
+ deleted: T::Boolean,
35
+
36
+ object: Symbol
37
+ )
38
+ .returns(T.attached_class)
39
+ end
40
+ def self.new(
41
+
42
+ # The voice identifier.
43
+ id:,
44
+
45
+ # Whether the voice was deleted.
46
+ deleted:,
47
+
48
+ # The object type, which is always `audio.voice.deleted`.
49
+
50
+ object: :"audio.voice.deleted"
51
+ )
52
+ end
53
+
54
+ sig do
55
+ override.returns(
56
+ {id: String, deleted: T::Boolean, object: Symbol}
57
+ )
58
+ end
59
+ def to_hash
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+ end
@@ -14,6 +14,19 @@ module OpenAI
14
14
  def azure(endpoint: nil, api_key: nil, token_provider: nil)
15
15
  end
16
16
 
17
+ sig do
18
+ params(
19
+ project: T.nilable(String),
20
+ location: T.nilable(String),
21
+ base_url: T.nilable(String),
22
+ token_provider: T.nilable(T.proc.returns(String)),
23
+ credentials: T.untyped
24
+ )
25
+ .returns(OpenAI::Provider)
26
+ end
27
+ def vertex(project: nil, location: nil, base_url: nil, token_provider: nil, credentials: nil)
28
+ end
29
+
17
30
  sig do
18
31
  params(
19
32
  endpoint: T.nilable(T.any(String, Symbol)),
@@ -106,10 +106,12 @@ module OpenAI
106
106
  )
107
107
  end
108
108
 
109
- # Deletes an API key from the project.
109
+ # Deletes an API key from the project, including keys owned by service accounts.
110
110
  #
111
- # Returns confirmation of the key deletion, or an error if the key belonged to a
112
- # service account.
111
+ # Requires permission to write project API keys. Deleting a service-account key
112
+ # does not delete the service account or its other keys.
113
+ #
114
+ # Returns confirmation of the key deletion.
113
115
  sig {
114
116
  params(api_key_id: String, project_id: String, request_options: OpenAI::RequestOptions::OrHash).returns(
115
117
  OpenAI::Models::Admin::Organization::Projects::APIKeyDeleteResponse
@@ -37,6 +37,24 @@ module OpenAI
37
37
  )
38
38
  end
39
39
 
40
+ # Deletes a voice created from a text prompt or an audio sample.
41
+ #
42
+ # Requires voice write permission and access to the voice's project. Access to
43
+ # voices created from recordings is limited to eligible customers. See the
44
+ # [custom voices guide](https://developers.openai.com/api/docs/guides/custom-voices).
45
+ #
46
+ # Deleting a voice does not delete its consent recording. Deleting an already
47
+ # deleted voice returns a 404 error.
48
+ sig {
49
+ params(voice_id: String, request_options: OpenAI::RequestOptions::OrHash).returns(OpenAI::Audio::VoiceDeleted)
50
+ }
51
+ def delete(
52
+ # The ID of the voice to delete.
53
+ voice_id,
54
+ request_options: {}
55
+ )
56
+ end
57
+
40
58
  # @api private
41
59
  sig { params(client: OpenAI::Client).returns(T.attached_class) }
42
60
  def self.new(client:)
@@ -8,6 +8,7 @@ module OpenAI
8
8
  OpenAI::Internal::Transport::BaseClient::request_input
9
9
  ) -> OpenAI::Internal::Transport::BaseClient::request_input)?
10
10
  attr_accessor authentication_headers: Array[String]
11
+ attr_accessor wrap_request: Proc?
11
12
 
12
13
  def initialize: (
13
14
  name: String,
@@ -15,7 +16,8 @@ module OpenAI
15
16
  prepare_request: (^(
16
17
  OpenAI::Internal::Transport::BaseClient::request_input
17
18
  ) -> OpenAI::Internal::Transport::BaseClient::request_input)?,
18
- authentication_headers: Array[String]
19
+ authentication_headers: Array[String],
20
+ ?wrap_request: Proc?
19
21
  ) -> void
20
22
  end
21
23
 
@@ -0,0 +1,25 @@
1
+ module OpenAI
2
+ module Models
3
+ module Audio
4
+ type voice_delete_params =
5
+ { voice_id: String, ?request_options: OpenAI::request_opts }
6
+
7
+ class VoiceDeleteParams < OpenAI::Internal::Type::BaseModel
8
+ extend OpenAI::Internal::Type::RequestParameters::Converter
9
+ include OpenAI::Internal::Type::RequestParameters
10
+
11
+ attr_accessor voice_id: String
12
+
13
+ def initialize: (
14
+ voice_id: String,
15
+ ?request_options: OpenAI::request_opts
16
+ ) -> void
17
+
18
+ def to_hash: -> {
19
+ voice_id: String,
20
+ ?request_options: OpenAI::RequestOptions
21
+ }
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,37 @@
1
+ module OpenAI
2
+ module Models
3
+ module Audio
4
+ type voice_deleted =
5
+ { id: String, deleted: bool, ?object: :"audio.voice.deleted" }
6
+
7
+ class VoiceDeleted < OpenAI::Internal::Type::BaseModel
8
+ # The voice identifier.
9
+ attr_accessor id: String
10
+
11
+ # Whether the voice was deleted.
12
+ attr_accessor deleted: bool
13
+
14
+ # The object type, which is always `audio.voice.deleted`.
15
+ attr_accessor object: :"audio.voice.deleted"
16
+
17
+ # @param id
18
+ # The voice identifier.
19
+ # @param deleted
20
+ # Whether the voice was deleted.
21
+ # @param object
22
+ # The object type, which is always `audio.voice.deleted`.
23
+ def initialize: (
24
+ id: String,
25
+ deleted: bool,
26
+ ?object: :"audio.voice.deleted"
27
+ ) -> void
28
+
29
+ def to_hash: -> {
30
+ id: String,
31
+ deleted: bool,
32
+ ?object: :"audio.voice.deleted"
33
+ }
34
+ end
35
+ end
36
+ end
37
+ end
@@ -6,6 +6,14 @@ module OpenAI
6
6
  ?token_provider: (^-> String)?
7
7
  ) -> OpenAI::Provider
8
8
 
9
+ def self.vertex: (
10
+ ?project: String?,
11
+ ?location: String?,
12
+ ?base_url: String?,
13
+ ?token_provider: (^-> String)?,
14
+ ?credentials: untyped
15
+ ) -> OpenAI::Provider
16
+
9
17
  def self.bedrock: (
10
18
  ?endpoint: (:mantle | :runtime | "mantle" | "runtime")?,
11
19
  ?region: String?,
@@ -7,6 +7,11 @@ module OpenAI
7
7
  ?request_options: OpenAI::request_opts
8
8
  ) -> OpenAI::Audio::Voice
9
9
 
10
+ def delete: (
11
+ String voice_id,
12
+ ?request_options: OpenAI::request_opts
13
+ ) -> OpenAI::Audio::VoiceDeleted
14
+
10
15
  def initialize: (client: OpenAI::Client) -> void
11
16
  end
12
17
  end
data/vertex.md ADDED
@@ -0,0 +1,29 @@
1
+ # Google Vertex AI
2
+
3
+ Configure the standard `OpenAI::Client` to use the Responses API through Vertex AI. For Google Application Default Credentials (ADC), add the optional `googleauth` gem to your application's Gemfile and run `bundle install`:
4
+
5
+ ```ruby
6
+ gem "googleauth", "~> 1"
7
+ ```
8
+
9
+ Configure ADC in your environment, then create a client:
10
+
11
+ ```ruby
12
+ require "openai"
13
+
14
+ client = OpenAI::Client.new(
15
+ provider: OpenAI::Providers.vertex(
16
+ project: "your-project-id",
17
+ location: "your-vertex-location"
18
+ )
19
+ )
20
+
21
+ response = client.responses.create(model: "your-enabled-model", input: "Say hello!")
22
+ puts(response.output_text)
23
+ ```
24
+
25
+ Use a model enabled for your project and location. Vertex AI determines which Responses features are available.
26
+
27
+ To manage credentials in your application, pass either `credentials:` with a Google credentials object or `token_provider:` with a callback that returns a current access token. The callback runs once per request attempt, including retries; cache and refresh tokens as needed. The `googleauth` gem is not required when using `token_provider:`.
28
+
29
+ To use a test server or trusted gateway, set `base_url:` to the full API root before `/responses`. The configured origin receives your bearer token. HTTP test roots are supported; use HTTPS in production.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.108.0
4
+ version: 0.110.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OpenAI
@@ -49,6 +49,7 @@ extra_rdoc_files:
49
49
  - local-audio.md
50
50
  - realtime.md
51
51
  - responses-websocket.md
52
+ - vertex.md
52
53
  files:
53
54
  - ".ignore"
54
55
  - CHANGELOG.md
@@ -452,6 +453,8 @@ files:
452
453
  - lib/openai/models/audio/voice_consent_retrieve_params.rb
453
454
  - lib/openai/models/audio/voice_consent_update_params.rb
454
455
  - lib/openai/models/audio/voice_create_params.rb
456
+ - lib/openai/models/audio/voice_delete_params.rb
457
+ - lib/openai/models/audio/voice_deleted.rb
455
458
  - lib/openai/models/audio_model.rb
456
459
  - lib/openai/models/audio_response_format.rb
457
460
  - lib/openai/models/auto_file_chunking_strategy_param.rb
@@ -1648,6 +1651,7 @@ files:
1648
1651
  - lib/openai/provider.rb
1649
1652
  - lib/openai/providers/azure.rb
1650
1653
  - lib/openai/providers/bedrock.rb
1654
+ - lib/openai/providers/vertex.rb
1651
1655
  - lib/openai/request_options.rb
1652
1656
  - lib/openai/resources/admin.rb
1653
1657
  - lib/openai/resources/admin/organization.rb
@@ -2117,6 +2121,8 @@ files:
2117
2121
  - rbi/openai/models/audio/voice_consent_retrieve_params.rbi
2118
2122
  - rbi/openai/models/audio/voice_consent_update_params.rbi
2119
2123
  - rbi/openai/models/audio/voice_create_params.rbi
2124
+ - rbi/openai/models/audio/voice_delete_params.rbi
2125
+ - rbi/openai/models/audio/voice_deleted.rbi
2120
2126
  - rbi/openai/models/audio_model.rbi
2121
2127
  - rbi/openai/models/audio_response_format.rbi
2122
2128
  - rbi/openai/models/auto_file_chunking_strategy_param.rbi
@@ -3770,6 +3776,8 @@ files:
3770
3776
  - sig/openai/models/audio/voice_consent_retrieve_params.rbs
3771
3777
  - sig/openai/models/audio/voice_consent_update_params.rbs
3772
3778
  - sig/openai/models/audio/voice_create_params.rbs
3779
+ - sig/openai/models/audio/voice_delete_params.rbs
3780
+ - sig/openai/models/audio/voice_deleted.rbs
3773
3781
  - sig/openai/models/audio_model.rbs
3774
3782
  - sig/openai/models/audio_response_format.rbs
3775
3783
  - sig/openai/models/auto_file_chunking_strategy_param.rbs
@@ -5093,6 +5101,7 @@ files:
5093
5101
  - sig/openai/response_carrier.rbs
5094
5102
  - sig/openai/streaming.rbs
5095
5103
  - sig/openai/version.rbs
5104
+ - vertex.md
5096
5105
  homepage: https://gemdocs.org/gems/openai
5097
5106
  licenses:
5098
5107
  - Apache-2.0