openai 0.70.0 → 0.72.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 +51 -1
- data/lib/openai/client.rb +62 -8
- data/lib/openai/internal/provider.rb +31 -0
- data/lib/openai/internal/transport/base_client.rb +65 -21
- data/lib/openai/models/admin/organization/audit_log_list_params.rb +84 -0
- data/lib/openai/models/admin/organization/audit_log_list_response.rb +84 -0
- data/lib/openai/models/admin/organization/organization_spend_limit.rb +151 -0
- data/lib/openai/models/admin/organization/organization_spend_limit_deleted.rb +33 -0
- data/lib/openai/models/admin/organization/projects/project_service_account.rb +4 -3
- data/lib/openai/models/admin/organization/projects/project_spend_limit.rb +155 -0
- data/lib/openai/models/admin/organization/projects/project_spend_limit_deleted.rb +35 -0
- data/lib/openai/models/admin/organization/projects/service_account_create_params.rb +9 -1
- data/lib/openai/models/admin/organization/projects/service_account_create_response.rb +26 -6
- data/lib/openai/models/admin/organization/projects/service_accounts/api_key_create_params.rb +54 -0
- data/lib/openai/models/admin/organization/projects/service_accounts/api_key_create_response.rb +57 -0
- data/lib/openai/models/admin/organization/projects/spend_limit_delete_params.rb +26 -0
- data/lib/openai/models/admin/organization/projects/spend_limit_retrieve_params.rb +26 -0
- data/lib/openai/models/admin/organization/projects/spend_limit_update_params.rb +77 -0
- data/lib/openai/models/admin/organization/spend_limit_delete_params.rb +18 -0
- data/lib/openai/models/admin/organization/spend_limit_retrieve_params.rb +18 -0
- data/lib/openai/models/admin/organization/spend_limit_update_params.rb +67 -0
- data/lib/openai/models/admin/organization/usage_audio_speeches_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_audio_transcriptions_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_code_interpreter_sessions_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_completions_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_costs_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_embeddings_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_file_search_calls_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_images_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_moderations_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_vector_stores_response.rb +88 -13
- data/lib/openai/models/admin/organization/usage_web_search_calls_response.rb +88 -13
- data/lib/openai/models/beta/beta_response.rb +12 -6
- data/lib/openai/models/beta/beta_response_error.rb +1 -0
- data/lib/openai/models/beta/beta_response_input_item.rb +16 -32
- data/lib/openai/models/beta/beta_response_text_config.rb +4 -2
- data/lib/openai/models/beta/beta_responses_client_event.rb +12 -6
- data/lib/openai/models/beta/response_create_params.rb +12 -6
- data/lib/openai/models/beta/responses/input_token_count_params.rb +12 -4
- data/lib/openai/models/chat/completion_create_params.rb +8 -6
- data/lib/openai/models/reasoning.rb +8 -2
- data/lib/openai/models/responses/input_token_count_params.rb +4 -2
- data/lib/openai/models/responses/response.rb +4 -4
- data/lib/openai/models/responses/response_create_params.rb +4 -4
- data/lib/openai/models/responses/response_error.rb +1 -0
- data/lib/openai/models/responses/response_text_config.rb +4 -2
- data/lib/openai/models/responses/responses_client_event.rb +4 -4
- data/lib/openai/provider.rb +18 -0
- data/lib/openai/providers/bedrock.rb +489 -0
- data/lib/openai/resources/admin/organization/projects/service_accounts/api_keys.rb +60 -0
- data/lib/openai/resources/admin/organization/projects/service_accounts.rb +10 -3
- data/lib/openai/resources/admin/organization/projects/spend_limit.rb +95 -0
- data/lib/openai/resources/admin/organization/projects.rb +4 -0
- data/lib/openai/resources/admin/organization/spend_limit.rb +86 -0
- data/lib/openai/resources/admin/organization.rb +4 -0
- data/lib/openai/resources/beta/responses.rb +4 -4
- data/lib/openai/resources/chat/completions.rb +4 -4
- data/lib/openai/resources/responses.rb +4 -4
- data/lib/openai/version.rb +1 -1
- data/lib/openai.rb +18 -0
- data/rbi/openai/client.rbi +17 -0
- data/rbi/openai/internal/provider.rbi +51 -0
- data/rbi/openai/internal/transport/base_client.rbi +32 -0
- data/rbi/openai/models/admin/organization/audit_log_list_params.rbi +420 -0
- data/rbi/openai/models/admin/organization/audit_log_list_response.rbi +420 -0
- data/rbi/openai/models/admin/organization/organization_spend_limit.rbi +278 -0
- data/rbi/openai/models/admin/organization/organization_spend_limit_deleted.rbi +48 -0
- data/rbi/openai/models/admin/organization/projects/project_service_account.rbi +8 -3
- data/rbi/openai/models/admin/organization/projects/project_spend_limit.rbi +280 -0
- data/rbi/openai/models/admin/organization/projects/project_spend_limit_deleted.rbi +49 -0
- data/rbi/openai/models/admin/organization/projects/service_account_create_params.rbi +8 -0
- data/rbi/openai/models/admin/organization/projects/service_account_create_response.rbi +52 -8
- data/rbi/openai/models/admin/organization/projects/service_accounts/api_key_create_params.rbi +84 -0
- data/rbi/openai/models/admin/organization/projects/service_accounts/api_key_create_response.rbi +80 -0
- data/rbi/openai/models/admin/organization/projects/spend_limit_delete_params.rbi +44 -0
- data/rbi/openai/models/admin/organization/projects/spend_limit_retrieve_params.rbi +44 -0
- data/rbi/openai/models/admin/organization/projects/spend_limit_update_params.rbi +149 -0
- data/rbi/openai/models/admin/organization/spend_limit_delete_params.rbi +34 -0
- data/rbi/openai/models/admin/organization/spend_limit_retrieve_params.rbi +34 -0
- data/rbi/openai/models/admin/organization/spend_limit_update_params.rbi +141 -0
- data/rbi/openai/models/admin/organization/usage_audio_speeches_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_audio_transcriptions_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_code_interpreter_sessions_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_completions_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_costs_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_embeddings_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_file_search_calls_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_images_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_moderations_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_vector_stores_response.rbi +121 -16
- data/rbi/openai/models/admin/organization/usage_web_search_calls_response.rbi +121 -16
- data/rbi/openai/models/beta/beta_response.rbi +18 -15
- data/rbi/openai/models/beta/beta_response_error.rbi +5 -0
- data/rbi/openai/models/beta/beta_response_input_item.rbi +39 -46
- data/rbi/openai/models/beta/beta_response_text_config.rbi +6 -3
- data/rbi/openai/models/beta/beta_responses_client_event.rbi +18 -15
- data/rbi/openai/models/beta/response_create_params.rbi +18 -15
- data/rbi/openai/models/beta/responses/input_token_count_params.rbi +18 -6
- data/rbi/openai/models/chat/completion_create_params.rbi +12 -15
- data/rbi/openai/models/reasoning.rbi +12 -3
- data/rbi/openai/models/responses/input_token_count_params.rbi +6 -3
- data/rbi/openai/models/responses/response.rbi +6 -12
- data/rbi/openai/models/responses/response_create_params.rbi +6 -12
- data/rbi/openai/models/responses/response_error.rbi +5 -0
- data/rbi/openai/models/responses/response_text_config.rbi +6 -3
- data/rbi/openai/models/responses/responses_client_event.rbi +6 -12
- data/rbi/openai/provider.rbi +9 -0
- data/rbi/openai/providers.rbi +33 -0
- data/rbi/openai/resources/admin/organization/projects/service_accounts/api_keys.rbi +45 -0
- data/rbi/openai/resources/admin/organization/projects/service_accounts.rbi +12 -2
- data/rbi/openai/resources/admin/organization/projects/spend_limit.rbi +78 -0
- data/rbi/openai/resources/admin/organization/projects.rbi +7 -0
- data/rbi/openai/resources/admin/organization/spend_limit.rbi +57 -0
- data/rbi/openai/resources/admin/organization.rbi +3 -0
- data/rbi/openai/resources/beta/responses.rbi +4 -4
- data/rbi/openai/resources/chat/completions.rbi +8 -6
- data/rbi/openai/resources/responses.rbi +4 -4
- data/sig/openai/client.rbs +7 -0
- data/sig/openai/internal/provider.rbs +29 -0
- data/sig/openai/internal/transport/base_client.rbs +17 -1
- data/sig/openai/models/admin/organization/audit_log_list_params.rbs +168 -0
- data/sig/openai/models/admin/organization/audit_log_list_response.rbs +168 -0
- data/sig/openai/models/admin/organization/organization_spend_limit.rbs +94 -0
- data/sig/openai/models/admin/organization/organization_spend_limit_deleted.rbs +28 -0
- data/sig/openai/models/admin/organization/projects/project_service_account.rbs +2 -1
- data/sig/openai/models/admin/organization/projects/project_spend_limit.rbs +96 -0
- data/sig/openai/models/admin/organization/projects/project_spend_limit_deleted.rbs +30 -0
- data/sig/openai/models/admin/organization/projects/service_account_create_params.rbs +9 -1
- data/sig/openai/models/admin/organization/projects/service_account_create_response.rbs +16 -5
- data/sig/openai/models/admin/organization/projects/service_accounts/api_key_create_params.rbs +53 -0
- data/sig/openai/models/admin/organization/projects/service_accounts/api_key_create_response.rbs +48 -0
- data/sig/openai/models/admin/organization/projects/spend_limit_delete_params.rbs +29 -0
- data/sig/openai/models/admin/organization/projects/spend_limit_retrieve_params.rbs +29 -0
- data/sig/openai/models/admin/organization/projects/spend_limit_update_params.rbs +67 -0
- data/sig/openai/models/admin/organization/spend_limit_delete_params.rbs +19 -0
- data/sig/openai/models/admin/organization/spend_limit_retrieve_params.rbs +19 -0
- data/sig/openai/models/admin/organization/spend_limit_update_params.rbs +60 -0
- data/sig/openai/models/admin/organization/usage_audio_speeches_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_audio_transcriptions_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_code_interpreter_sessions_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_completions_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_costs_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_embeddings_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_file_search_calls_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_images_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_moderations_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_vector_stores_response.rbs +63 -0
- data/sig/openai/models/admin/organization/usage_web_search_calls_response.rbs +63 -0
- data/sig/openai/models/beta/beta_response.rbs +8 -12
- data/sig/openai/models/beta/beta_response_error.rbs +2 -0
- data/sig/openai/models/beta/beta_response_input_item.rbs +18 -24
- data/sig/openai/models/beta/beta_responses_client_event.rbs +8 -12
- data/sig/openai/models/beta/response_create_params.rbs +8 -12
- data/sig/openai/models/chat/completion_create_params.rbs +8 -12
- data/sig/openai/models/responses/response.rbs +8 -12
- data/sig/openai/models/responses/response_create_params.rbs +8 -12
- data/sig/openai/models/responses/response_error.rbs +2 -0
- data/sig/openai/models/responses/responses_client_event.rbs +8 -12
- data/sig/openai/provider.rbs +5 -0
- data/sig/openai/providers.rbs +15 -0
- data/sig/openai/resources/admin/organization/projects/service_accounts/api_keys.rbs +23 -0
- data/sig/openai/resources/admin/organization/projects/service_accounts.rbs +3 -0
- data/sig/openai/resources/admin/organization/projects/spend_limit.rbs +31 -0
- data/sig/openai/resources/admin/organization/projects.rbs +2 -0
- data/sig/openai/resources/admin/organization/spend_limit.rbs +26 -0
- data/sig/openai/resources/admin/organization.rbs +2 -0
- data/sig/openai/resources/beta/responses.rbs +4 -4
- data/sig/openai/resources/chat/completions.rbs +4 -4
- data/sig/openai/resources/responses.rbs +4 -4
- metadata +56 -2
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenAI
|
|
4
|
+
module Providers
|
|
5
|
+
# @api private
|
|
6
|
+
module Bedrock
|
|
7
|
+
SERVICE = "bedrock-mantle"
|
|
8
|
+
CANONICAL_HOST = /\Abedrock-mantle\.([a-z0-9-]+)\.api\.aws\z/i
|
|
9
|
+
SIGNING_HEADERS = %w[authorization x-amz-content-sha256 x-amz-date x-amz-security-token].freeze
|
|
10
|
+
BEARER_AUTH_MARKER = :openai_bedrock_bearer
|
|
11
|
+
SIGV4_AUTH_MARKER = :openai_bedrock_sigv4
|
|
12
|
+
MISSING_REGION_MESSAGE =
|
|
13
|
+
"Bedrock requires an AWS region. Pass `region` to `bedrock(...)`, or set `AWS_REGION` " \
|
|
14
|
+
"or `AWS_DEFAULT_REGION`."
|
|
15
|
+
MISSING_CREDENTIALS_MESSAGE =
|
|
16
|
+
"Could not find credentials for Bedrock. Pass a bearer credential or AWS credentials " \
|
|
17
|
+
"to `bedrock(...)`, set `AWS_BEARER_TOKEN_BEDROCK`, or configure the default AWS credential chain."
|
|
18
|
+
CREDENTIAL_RESOLUTION_MESSAGE =
|
|
19
|
+
"Failed to resolve AWS credentials for Bedrock. Verify your AWS profile, environment " \
|
|
20
|
+
"variables, or runtime identity configuration and try again."
|
|
21
|
+
NON_REPLAYABLE_BODY_MESSAGE =
|
|
22
|
+
"Bedrock SigV4 authentication requires a replayable request body. Buffer the body " \
|
|
23
|
+
"before sending or use bearer authentication."
|
|
24
|
+
MISSING_DEPENDENCY_MESSAGE =
|
|
25
|
+
"Bedrock AWS authentication requires optional AWS dependencies. Add `gem \"aws-sdk-core\"` " \
|
|
26
|
+
"to your Gemfile, run `bundle install`, and try again."
|
|
27
|
+
PARTIAL_STATIC_CREDENTIALS_MESSAGE =
|
|
28
|
+
"Static AWS credentials require both `access_key_id` and `secret_access_key`. " \
|
|
29
|
+
"A `session_token` may only be used with both."
|
|
30
|
+
AMBIGUOUS_AWS_AUTH_MESSAGE =
|
|
31
|
+
"Bedrock authentication is ambiguous. Configure exactly one explicit AWS mode: " \
|
|
32
|
+
"static credentials, profile, or credential provider."
|
|
33
|
+
AMBIGUOUS_AUTH_MESSAGE =
|
|
34
|
+
"Bedrock authentication is ambiguous. Configure exactly one explicit mode: bearer " \
|
|
35
|
+
"credential, static AWS credentials, profile, or credential provider."
|
|
36
|
+
|
|
37
|
+
class Definition
|
|
38
|
+
attr_reader :name
|
|
39
|
+
|
|
40
|
+
def initialize(
|
|
41
|
+
region:,
|
|
42
|
+
base_url:,
|
|
43
|
+
bearer_provider:,
|
|
44
|
+
profile:,
|
|
45
|
+
access_key_id:,
|
|
46
|
+
secret_access_key:,
|
|
47
|
+
session_token:,
|
|
48
|
+
credentials_provider:,
|
|
49
|
+
default_chain:
|
|
50
|
+
)
|
|
51
|
+
@name = "bedrock"
|
|
52
|
+
@region = region&.freeze
|
|
53
|
+
@base_url = base_url&.freeze
|
|
54
|
+
@bearer_provider = bearer_provider
|
|
55
|
+
@profile = profile&.freeze
|
|
56
|
+
@access_key_id = access_key_id&.freeze
|
|
57
|
+
@secret_access_key = secret_access_key&.freeze
|
|
58
|
+
@session_token = session_token&.freeze
|
|
59
|
+
@credentials_provider = credentials_provider
|
|
60
|
+
@default_chain = default_chain
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def configure
|
|
64
|
+
if @bearer_provider
|
|
65
|
+
base_url = Bedrock.resolve_base_url(@base_url, @region)
|
|
66
|
+
auth = BearerAuth.new(token_provider: @bearer_provider, base_url: base_url)
|
|
67
|
+
else
|
|
68
|
+
Bedrock.load_aws!
|
|
69
|
+
region = @region || Bedrock.profile_region(@profile)
|
|
70
|
+
raise ArgumentError, MISSING_REGION_MESSAGE if region.nil?
|
|
71
|
+
|
|
72
|
+
base_url = Bedrock.resolve_base_url(@base_url, region)
|
|
73
|
+
credentials =
|
|
74
|
+
if @access_key_id
|
|
75
|
+
Aws::Credentials.new(@access_key_id, @secret_access_key, @session_token)
|
|
76
|
+
elsif @credentials_provider
|
|
77
|
+
CustomCredentialsProvider.new(@credentials_provider)
|
|
78
|
+
elsif @profile
|
|
79
|
+
ProfileCredentialsProvider.new(@profile, region: region)
|
|
80
|
+
else
|
|
81
|
+
DefaultCredentialsProvider.new
|
|
82
|
+
end
|
|
83
|
+
auth = SigV4Auth.new(
|
|
84
|
+
region: region,
|
|
85
|
+
base_url: base_url,
|
|
86
|
+
credentials_provider: credentials,
|
|
87
|
+
default_chain: @default_chain
|
|
88
|
+
)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
OpenAI::Internal::Provider::Runtime.new(
|
|
92
|
+
name: name,
|
|
93
|
+
base_url: base_url,
|
|
94
|
+
prepare_request: auth.method(:prepare_request)
|
|
95
|
+
)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
class BearerAuth
|
|
100
|
+
def initialize(token_provider:, base_url:)
|
|
101
|
+
@token_provider = token_provider
|
|
102
|
+
@base_url = URI(base_url)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def prepare_request(request)
|
|
106
|
+
Bedrock.validate_origin!(request.fetch(:url), @base_url, action: "authenticate")
|
|
107
|
+
headers = Bedrock.provider_headers(request, marker: BEARER_AUTH_MARKER)
|
|
108
|
+
token = resolve_token
|
|
109
|
+
|
|
110
|
+
request.merge(
|
|
111
|
+
headers: headers.merge("authorization" => "Bearer #{token}"),
|
|
112
|
+
provider_auth: BEARER_AUTH_MARKER
|
|
113
|
+
)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
private def resolve_token
|
|
117
|
+
token = @token_provider.call
|
|
118
|
+
unless token.is_a?(String) && !token.strip.empty?
|
|
119
|
+
raise OpenAI::Errors::Error,
|
|
120
|
+
"The Bedrock bearer credential provider must return a non-empty string."
|
|
121
|
+
end
|
|
122
|
+
token
|
|
123
|
+
rescue OpenAI::Errors::Error
|
|
124
|
+
raise
|
|
125
|
+
rescue StandardError => e
|
|
126
|
+
raise OpenAI::Errors::Error.new("Failed to resolve a bearer credential for Bedrock."), cause: e
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
class SigV4Auth
|
|
131
|
+
def initialize(region:, base_url:, credentials_provider:, default_chain:)
|
|
132
|
+
@region = region
|
|
133
|
+
@base_url = URI(base_url)
|
|
134
|
+
@default_chain = default_chain
|
|
135
|
+
@signer = Aws::Sigv4::Signer.new(
|
|
136
|
+
service: SERVICE,
|
|
137
|
+
region: region,
|
|
138
|
+
credentials_provider: credentials_provider
|
|
139
|
+
)
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
def prepare_request(request)
|
|
143
|
+
url = request.fetch(:url)
|
|
144
|
+
Bedrock.validate_origin!(url, @base_url, action: "sign")
|
|
145
|
+
Bedrock.validate_endpoint_region!(url, @region)
|
|
146
|
+
body = request[:body]
|
|
147
|
+
unless body.nil? || body.is_a?(String)
|
|
148
|
+
raise OpenAI::Errors::Error, NON_REPLAYABLE_BODY_MESSAGE
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
headers = Bedrock.provider_headers(request, marker: SIGV4_AUTH_MARKER)
|
|
152
|
+
SIGNING_HEADERS.each { headers.delete(_1) }
|
|
153
|
+
signature = sign_request(
|
|
154
|
+
http_method: request.fetch(:method).to_s.upcase,
|
|
155
|
+
url: url.to_s,
|
|
156
|
+
headers: headers,
|
|
157
|
+
body: body
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
request.merge(
|
|
161
|
+
headers: OpenAI::Internal::Util.normalized_headers(headers, signature.headers),
|
|
162
|
+
follow_redirects: false,
|
|
163
|
+
provider_auth: SIGV4_AUTH_MARKER
|
|
164
|
+
)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
private def sign_request(**options)
|
|
168
|
+
@signer.sign_request(**options)
|
|
169
|
+
rescue OpenAI::Errors::Error
|
|
170
|
+
raise
|
|
171
|
+
rescue StandardError => e
|
|
172
|
+
message =
|
|
173
|
+
if @default_chain
|
|
174
|
+
MISSING_CREDENTIALS_MESSAGE
|
|
175
|
+
else
|
|
176
|
+
CREDENTIAL_RESOLUTION_MESSAGE
|
|
177
|
+
end
|
|
178
|
+
raise OpenAI::Errors::Error.new(message), cause: e
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
class CustomCredentialsProvider
|
|
183
|
+
def initialize(provider) = @provider = provider
|
|
184
|
+
|
|
185
|
+
def credentials
|
|
186
|
+
value = @provider.respond_to?(:call) ? @provider.call : @provider.credentials
|
|
187
|
+
value = value.credentials if !value.respond_to?(:access_key_id) && value.respond_to?(:credentials)
|
|
188
|
+
Bedrock.validate_credentials!(value)
|
|
189
|
+
rescue OpenAI::Errors::Error
|
|
190
|
+
raise
|
|
191
|
+
rescue StandardError => e
|
|
192
|
+
raise OpenAI::Errors::Error.new(CREDENTIAL_RESOLUTION_MESSAGE), cause: e
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
class DefaultCredentialsProvider
|
|
197
|
+
def initialize
|
|
198
|
+
@mutex = Mutex.new
|
|
199
|
+
@provider = nil
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
def credentials
|
|
203
|
+
provider = @mutex.synchronize { @provider ||= Aws::CredentialProviderChain.new.resolve }
|
|
204
|
+
raise OpenAI::Errors::Error, MISSING_CREDENTIALS_MESSAGE unless provider
|
|
205
|
+
Bedrock.validate_credentials!(provider.credentials)
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
class ProfileCredentialsProvider
|
|
210
|
+
def initialize(profile, region:)
|
|
211
|
+
@profile = profile
|
|
212
|
+
@region = region
|
|
213
|
+
@mutex = Mutex.new
|
|
214
|
+
@provider = nil
|
|
215
|
+
end
|
|
216
|
+
|
|
217
|
+
def credentials
|
|
218
|
+
provider = @mutex.synchronize { @provider ||= resolve }
|
|
219
|
+
Bedrock.validate_credentials!(provider.credentials)
|
|
220
|
+
rescue OpenAI::Errors::Error
|
|
221
|
+
raise
|
|
222
|
+
rescue StandardError => e
|
|
223
|
+
raise OpenAI::Errors::Error.new(CREDENTIAL_RESOLUTION_MESSAGE), cause: e
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
private def resolve
|
|
227
|
+
config = Aws.shared_config
|
|
228
|
+
providers = []
|
|
229
|
+
if config.config_enabled?
|
|
230
|
+
providers << config.assume_role_web_identity_credentials_from_config(
|
|
231
|
+
profile: @profile,
|
|
232
|
+
region: @region
|
|
233
|
+
)
|
|
234
|
+
providers << config.sso_credentials_from_config(profile: @profile)
|
|
235
|
+
providers << config.assume_role_credentials_from_config(profile: @profile, region: @region)
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
begin
|
|
239
|
+
providers << Aws::SharedCredentials.new(profile_name: @profile)
|
|
240
|
+
rescue Aws::Errors::NoSuchProfileError
|
|
241
|
+
nil
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
if config.config_enabled?
|
|
245
|
+
if config.respond_to?(:login_credentials_from_config)
|
|
246
|
+
providers << config.login_credentials_from_config(profile: @profile, region: @region)
|
|
247
|
+
end
|
|
248
|
+
process = config.credential_process(profile: @profile)
|
|
249
|
+
providers << Aws::ProcessCredentials.new([process]) if process
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
providers.compact.find(&:set?) || raise(OpenAI::Errors::Error, CREDENTIAL_RESOLUTION_MESSAGE)
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
class << self
|
|
257
|
+
def load_aws!
|
|
258
|
+
require("aws-sdk-core")
|
|
259
|
+
require("aws-sigv4")
|
|
260
|
+
rescue LoadError => e
|
|
261
|
+
raise OpenAI::Errors::Error.new(MISSING_DEPENDENCY_MESSAGE), cause: e
|
|
262
|
+
end
|
|
263
|
+
|
|
264
|
+
def resolve_base_url(base_url, region)
|
|
265
|
+
return base_url if base_url
|
|
266
|
+
raise ArgumentError, MISSING_REGION_MESSAGE if region.nil?
|
|
267
|
+
"https://bedrock-mantle.#{region}.api.aws/v1"
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
def normalize_base_url(base_url)
|
|
271
|
+
uri = URI(base_url)
|
|
272
|
+
unless uri.is_a?(URI::HTTP) && uri.host
|
|
273
|
+
raise ArgumentError, "The Bedrock `base_url` must be an absolute HTTP or HTTPS URL."
|
|
274
|
+
end
|
|
275
|
+
uri.path = uri.path.sub(%r{/responses(?:/.*)?\z}, "")
|
|
276
|
+
uri.path = "" if uri.path == "/"
|
|
277
|
+
uri.to_s.sub(%r{/\z}, "")
|
|
278
|
+
rescue URI::InvalidURIError => e
|
|
279
|
+
message = "The Bedrock `base_url` must be an absolute HTTP or HTTPS URL."
|
|
280
|
+
raise ArgumentError.new(message), cause: e
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
def profile_region(profile)
|
|
284
|
+
configured_profile = profile || ENV["AWS_PROFILE"] || ENV["AWS_DEFAULT_PROFILE"] || "default"
|
|
285
|
+
region = Aws.shared_config.region(profile: configured_profile)
|
|
286
|
+
normalize_optional_string(region)
|
|
287
|
+
rescue StandardError => e
|
|
288
|
+
raise OpenAI::Errors::Error.new(CREDENTIAL_RESOLUTION_MESSAGE), cause: e
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
def provider_headers(request, marker:)
|
|
292
|
+
headers = request.fetch(:headers).dup
|
|
293
|
+
if request[:provider_auth] == marker
|
|
294
|
+
headers.delete("authorization")
|
|
295
|
+
elsif headers.key?("authorization")
|
|
296
|
+
raise OpenAI::Errors::Error,
|
|
297
|
+
"Bedrock provider authentication cannot be combined with a custom `Authorization` header."
|
|
298
|
+
end
|
|
299
|
+
headers
|
|
300
|
+
end
|
|
301
|
+
|
|
302
|
+
def validate_origin!(url, base_url, action:)
|
|
303
|
+
return if OpenAI::Internal::Util.uri_origin(url) == OpenAI::Internal::Util.uri_origin(base_url)
|
|
304
|
+
message =
|
|
305
|
+
"Refusing to #{action} a Bedrock request for an origin other than the configured " \
|
|
306
|
+
"provider URL."
|
|
307
|
+
raise OpenAI::Errors::Error,
|
|
308
|
+
message
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
def validate_endpoint_region!(url, region)
|
|
312
|
+
endpoint_region = CANONICAL_HOST.match(url.host)&.[](1)
|
|
313
|
+
return if endpoint_region.nil? || endpoint_region == region
|
|
314
|
+
message =
|
|
315
|
+
"The Bedrock endpoint region `#{endpoint_region}` does not match the SigV4 " \
|
|
316
|
+
"region `#{region}`."
|
|
317
|
+
raise OpenAI::Errors::Error,
|
|
318
|
+
message
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def validate_credentials!(credentials)
|
|
322
|
+
access_key_id = credentials&.access_key_id
|
|
323
|
+
secret_access_key = credentials&.secret_access_key
|
|
324
|
+
session_token = credentials&.session_token if credentials.respond_to?(:session_token)
|
|
325
|
+
valid =
|
|
326
|
+
access_key_id.is_a?(String) && !access_key_id.strip.empty? &&
|
|
327
|
+
secret_access_key.is_a?(String) && !secret_access_key.strip.empty? &&
|
|
328
|
+
(session_token.nil? || (session_token.is_a?(String) && !session_token.strip.empty?))
|
|
329
|
+
return credentials if valid
|
|
330
|
+
raise OpenAI::Errors::Error, CREDENTIAL_RESOLUTION_MESSAGE
|
|
331
|
+
end
|
|
332
|
+
|
|
333
|
+
def normalize_optional_string(value)
|
|
334
|
+
return nil if value.nil?
|
|
335
|
+
return nil unless value.is_a?(String)
|
|
336
|
+
normalized = value.strip
|
|
337
|
+
normalized unless normalized.empty?
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
end
|
|
341
|
+
|
|
342
|
+
class << self
|
|
343
|
+
# Configure the standard OpenAI client for Amazon Bedrock Mantle.
|
|
344
|
+
#
|
|
345
|
+
# Authentication precedence is an explicit bearer or AWS mode, then
|
|
346
|
+
# AWS_BEARER_TOKEN_BEDROCK, then the standard AWS credential chain.
|
|
347
|
+
#
|
|
348
|
+
# @param region [String, nil] AWS signing region. Defaults to `AWS_REGION`,
|
|
349
|
+
# `AWS_DEFAULT_REGION`, or the selected profile's configured region.
|
|
350
|
+
#
|
|
351
|
+
# @param base_url [String, nil] Bedrock API root. Defaults to
|
|
352
|
+
# `AWS_BEDROCK_BASE_URL` or the regional Bedrock Mantle endpoint.
|
|
353
|
+
#
|
|
354
|
+
# @param api_key [String, nil] Explicit Bedrock bearer credential. Passing
|
|
355
|
+
# `nil` explicitly skips the `AWS_BEARER_TOKEN_BEDROCK` fallback.
|
|
356
|
+
#
|
|
357
|
+
# @param token_provider [#call, nil] Callable returning a fresh bearer
|
|
358
|
+
# credential before each request attempt.
|
|
359
|
+
#
|
|
360
|
+
# @param access_key_id [String, nil] Explicit AWS access key ID. Must be
|
|
361
|
+
# paired with `secret_access_key`.
|
|
362
|
+
#
|
|
363
|
+
# @param secret_access_key [String, nil] Explicit AWS secret access key.
|
|
364
|
+
#
|
|
365
|
+
# @param session_token [String, nil] Optional session token for explicit
|
|
366
|
+
# temporary AWS credentials.
|
|
367
|
+
#
|
|
368
|
+
# @param profile [String, nil] Explicit AWS shared-config profile.
|
|
369
|
+
#
|
|
370
|
+
# @param credentials_provider [#credentials, #call, nil] Refreshable AWS
|
|
371
|
+
# credentials provider. A callable must return an AWS credential identity.
|
|
372
|
+
#
|
|
373
|
+
# @return [OpenAI::Provider]
|
|
374
|
+
def bedrock(
|
|
375
|
+
region: nil,
|
|
376
|
+
base_url: OpenAI::Internal::OMIT,
|
|
377
|
+
api_key: OpenAI::Internal::OMIT,
|
|
378
|
+
token_provider: nil,
|
|
379
|
+
access_key_id: nil,
|
|
380
|
+
secret_access_key: nil,
|
|
381
|
+
session_token: nil,
|
|
382
|
+
profile: nil,
|
|
383
|
+
credentials_provider: nil
|
|
384
|
+
)
|
|
385
|
+
normalized_region = Bedrock.normalize_optional_string(region)
|
|
386
|
+
if !region.nil? && normalized_region.nil?
|
|
387
|
+
raise ArgumentError, "The Bedrock AWS `region` must not be empty."
|
|
388
|
+
end
|
|
389
|
+
normalized_region ||= Bedrock.normalize_optional_string(ENV["AWS_REGION"]) ||
|
|
390
|
+
Bedrock.normalize_optional_string(ENV["AWS_DEFAULT_REGION"])
|
|
391
|
+
|
|
392
|
+
normalized_profile = Bedrock.normalize_optional_string(profile)
|
|
393
|
+
if !profile.nil? && normalized_profile.nil?
|
|
394
|
+
raise ArgumentError, "The Bedrock AWS `profile` must not be empty."
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
configured_base_url =
|
|
398
|
+
if base_url.equal?(OpenAI::Internal::OMIT)
|
|
399
|
+
Bedrock.normalize_optional_string(ENV["AWS_BEDROCK_BASE_URL"])
|
|
400
|
+
elsif base_url.nil?
|
|
401
|
+
nil
|
|
402
|
+
else
|
|
403
|
+
normalized = Bedrock.normalize_optional_string(base_url)
|
|
404
|
+
raise(ArgumentError, "The Bedrock `base_url` must not be empty.") unless normalized
|
|
405
|
+
normalized
|
|
406
|
+
end
|
|
407
|
+
configured_base_url = Bedrock.normalize_base_url(configured_base_url) if configured_base_url
|
|
408
|
+
|
|
409
|
+
has_access_key = !access_key_id.nil?
|
|
410
|
+
has_secret_key = !secret_access_key.nil?
|
|
411
|
+
if has_access_key != has_secret_key || (!session_token.nil? && !has_access_key)
|
|
412
|
+
raise ArgumentError, Bedrock::PARTIAL_STATIC_CREDENTIALS_MESSAGE
|
|
413
|
+
end
|
|
414
|
+
normalized_access_key_id = Bedrock.normalize_optional_string(access_key_id)
|
|
415
|
+
normalized_secret_access_key = Bedrock.normalize_optional_string(secret_access_key)
|
|
416
|
+
normalized_session_token = Bedrock.normalize_optional_string(session_token)
|
|
417
|
+
if has_access_key && [normalized_access_key_id, normalized_secret_access_key].any?(&:nil?)
|
|
418
|
+
raise ArgumentError,
|
|
419
|
+
"Static AWS credentials require non-empty `access_key_id` and `secret_access_key` values."
|
|
420
|
+
end
|
|
421
|
+
if !session_token.nil? && normalized_session_token.nil?
|
|
422
|
+
raise ArgumentError, "A static AWS `session_token` must not be empty when provided."
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
explicit_api_key = !api_key.equal?(OpenAI::Internal::OMIT) && !api_key.nil?
|
|
426
|
+
normalized_api_key = Bedrock.normalize_optional_string(api_key)
|
|
427
|
+
if explicit_api_key && normalized_api_key.nil?
|
|
428
|
+
raise ArgumentError, "The Bedrock bearer credential must not be empty."
|
|
429
|
+
end
|
|
430
|
+
if explicit_api_key && !token_provider.nil?
|
|
431
|
+
raise ArgumentError,
|
|
432
|
+
"The `api_key` and `token_provider` options are mutually exclusive. Configure only one."
|
|
433
|
+
end
|
|
434
|
+
if !token_provider.nil? && !token_provider.respond_to?(:call)
|
|
435
|
+
raise ArgumentError, "The Bedrock `token_provider` must respond to `call`."
|
|
436
|
+
end
|
|
437
|
+
if !credentials_provider.nil? &&
|
|
438
|
+
!credentials_provider.respond_to?(:call) &&
|
|
439
|
+
!credentials_provider.respond_to?(:credentials)
|
|
440
|
+
raise ArgumentError,
|
|
441
|
+
"The Bedrock `credentials_provider` must respond to `call` or `credentials`."
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
explicit_bearer = explicit_api_key || !token_provider.nil?
|
|
445
|
+
aws_modes = [has_access_key, !normalized_profile.nil?, !credentials_provider.nil?].count(true)
|
|
446
|
+
if aws_modes > 1
|
|
447
|
+
raise ArgumentError, Bedrock::AMBIGUOUS_AWS_AUTH_MESSAGE
|
|
448
|
+
end
|
|
449
|
+
if explicit_bearer && aws_modes.positive?
|
|
450
|
+
raise ArgumentError, Bedrock::AMBIGUOUS_AUTH_MESSAGE
|
|
451
|
+
end
|
|
452
|
+
|
|
453
|
+
skip_environment_bearer = !api_key.equal?(OpenAI::Internal::OMIT) && api_key.nil?
|
|
454
|
+
environment_bearer =
|
|
455
|
+
!explicit_bearer && aws_modes.zero? && !skip_environment_bearer &&
|
|
456
|
+
!Bedrock.normalize_optional_string(ENV["AWS_BEARER_TOKEN_BEDROCK"]).nil?
|
|
457
|
+
bearer_provider =
|
|
458
|
+
if explicit_api_key
|
|
459
|
+
normalized_api_key.freeze
|
|
460
|
+
-> { normalized_api_key }
|
|
461
|
+
elsif !token_provider.nil?
|
|
462
|
+
token_provider
|
|
463
|
+
elsif environment_bearer
|
|
464
|
+
lambda do
|
|
465
|
+
ENV["AWS_BEARER_TOKEN_BEDROCK"] ||
|
|
466
|
+
raise(OpenAI::Errors::Error, Bedrock::MISSING_CREDENTIALS_MESSAGE)
|
|
467
|
+
end
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
if bearer_provider && configured_base_url.nil? && normalized_region.nil?
|
|
471
|
+
raise ArgumentError, Bedrock::MISSING_REGION_MESSAGE
|
|
472
|
+
end
|
|
473
|
+
|
|
474
|
+
definition = Bedrock::Definition.new(
|
|
475
|
+
region: normalized_region,
|
|
476
|
+
base_url: configured_base_url,
|
|
477
|
+
bearer_provider: bearer_provider,
|
|
478
|
+
profile: normalized_profile,
|
|
479
|
+
access_key_id: normalized_access_key_id,
|
|
480
|
+
secret_access_key: normalized_secret_access_key,
|
|
481
|
+
session_token: normalized_session_token,
|
|
482
|
+
credentials_provider: credentials_provider,
|
|
483
|
+
default_chain: aws_modes.zero?
|
|
484
|
+
)
|
|
485
|
+
OpenAI::Internal::Provider.create(definition)
|
|
486
|
+
end
|
|
487
|
+
end
|
|
488
|
+
end
|
|
489
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenAI
|
|
4
|
+
module Resources
|
|
5
|
+
class Admin
|
|
6
|
+
class Organization
|
|
7
|
+
class Projects
|
|
8
|
+
class ServiceAccounts
|
|
9
|
+
class APIKeys
|
|
10
|
+
# Creates an API key for a service account in the project.
|
|
11
|
+
#
|
|
12
|
+
# @overload create(service_account_id, project_id:, name: nil, scopes: nil, request_options: {})
|
|
13
|
+
#
|
|
14
|
+
# @param service_account_id [String] Path param: The ID of the service account.
|
|
15
|
+
#
|
|
16
|
+
# @param project_id [String] Path param: The ID of the project.
|
|
17
|
+
#
|
|
18
|
+
# @param name [String] Body param: API key name.
|
|
19
|
+
#
|
|
20
|
+
# @param scopes [Array<String>] Body param: API key scopes.
|
|
21
|
+
#
|
|
22
|
+
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
23
|
+
#
|
|
24
|
+
# @return [OpenAI::Models::Admin::Organization::Projects::ServiceAccounts::APIKeyCreateResponse]
|
|
25
|
+
#
|
|
26
|
+
# @see OpenAI::Models::Admin::Organization::Projects::ServiceAccounts::APIKeyCreateParams
|
|
27
|
+
def create(service_account_id, params)
|
|
28
|
+
parsed, options =
|
|
29
|
+
OpenAI::Admin::Organization::Projects::ServiceAccounts::APIKeyCreateParams.dump_request(params)
|
|
30
|
+
project_id =
|
|
31
|
+
parsed.delete(:project_id) do
|
|
32
|
+
raise ArgumentError.new("missing required path argument #{_1}")
|
|
33
|
+
end
|
|
34
|
+
@client.request(
|
|
35
|
+
method: :post,
|
|
36
|
+
path: [
|
|
37
|
+
"organization/projects/%1$s/service_accounts/%2$s/api_keys",
|
|
38
|
+
project_id,
|
|
39
|
+
service_account_id
|
|
40
|
+
],
|
|
41
|
+
body: parsed,
|
|
42
|
+
model: OpenAI::Models::Admin::Organization::Projects::ServiceAccounts::APIKeyCreateResponse,
|
|
43
|
+
security: {admin_api_key_auth: true},
|
|
44
|
+
options: options
|
|
45
|
+
)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# @api private
|
|
49
|
+
#
|
|
50
|
+
# @param client [OpenAI::Client]
|
|
51
|
+
def initialize(client:)
|
|
52
|
+
@client = client
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -6,15 +6,20 @@ module OpenAI
|
|
|
6
6
|
class Organization
|
|
7
7
|
class Projects
|
|
8
8
|
class ServiceAccounts
|
|
9
|
-
#
|
|
10
|
-
|
|
9
|
+
# @return [OpenAI::Resources::Admin::Organization::Projects::ServiceAccounts::APIKeys]
|
|
10
|
+
attr_reader :api_keys
|
|
11
|
+
|
|
12
|
+
# Creates a new service account in the project. By default, this also returns an
|
|
13
|
+
# unredacted API key for the service account.
|
|
11
14
|
#
|
|
12
|
-
# @overload create(project_id, name:, request_options: {})
|
|
15
|
+
# @overload create(project_id, name:, create_service_account_only: nil, request_options: {})
|
|
13
16
|
#
|
|
14
17
|
# @param project_id [String] The ID of the project.
|
|
15
18
|
#
|
|
16
19
|
# @param name [String] The name of the service account being created.
|
|
17
20
|
#
|
|
21
|
+
# @param create_service_account_only [Boolean, nil] Create the service account without default roles or an API key.
|
|
22
|
+
#
|
|
18
23
|
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
19
24
|
#
|
|
20
25
|
# @return [OpenAI::Models::Admin::Organization::Projects::ServiceAccountCreateResponse]
|
|
@@ -163,6 +168,8 @@ module OpenAI
|
|
|
163
168
|
# @param client [OpenAI::Client]
|
|
164
169
|
def initialize(client:)
|
|
165
170
|
@client = client
|
|
171
|
+
@api_keys =
|
|
172
|
+
OpenAI::Resources::Admin::Organization::Projects::ServiceAccounts::APIKeys.new(client: client)
|
|
166
173
|
end
|
|
167
174
|
end
|
|
168
175
|
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module OpenAI
|
|
4
|
+
module Resources
|
|
5
|
+
class Admin
|
|
6
|
+
class Organization
|
|
7
|
+
class Projects
|
|
8
|
+
class SpendLimit
|
|
9
|
+
# Get a project's hard spend limit.
|
|
10
|
+
#
|
|
11
|
+
# @overload retrieve(project_id, request_options: {})
|
|
12
|
+
#
|
|
13
|
+
# @param project_id [String] The ID of the project whose hard spend limit is being managed.
|
|
14
|
+
#
|
|
15
|
+
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
16
|
+
#
|
|
17
|
+
# @return [OpenAI::Models::Admin::Organization::Projects::ProjectSpendLimit]
|
|
18
|
+
#
|
|
19
|
+
# @see OpenAI::Models::Admin::Organization::Projects::SpendLimitRetrieveParams
|
|
20
|
+
def retrieve(project_id, params = {})
|
|
21
|
+
@client.request(
|
|
22
|
+
method: :get,
|
|
23
|
+
path: ["organization/projects/%1$s/spend_limit", project_id],
|
|
24
|
+
model: OpenAI::Admin::Organization::Projects::ProjectSpendLimit,
|
|
25
|
+
security: {admin_api_key_auth: true},
|
|
26
|
+
options: params[:request_options]
|
|
27
|
+
)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Some parameter documentations has been truncated, see
|
|
31
|
+
# {OpenAI::Models::Admin::Organization::Projects::SpendLimitUpdateParams} for more
|
|
32
|
+
# details.
|
|
33
|
+
#
|
|
34
|
+
# Create or replace a project's hard spend limit.
|
|
35
|
+
#
|
|
36
|
+
# @overload update(project_id, currency:, interval:, threshold_amount:, request_options: {})
|
|
37
|
+
#
|
|
38
|
+
# @param project_id [String] The ID of the project whose hard spend limit is being managed.
|
|
39
|
+
#
|
|
40
|
+
# @param currency [Symbol, OpenAI::Models::Admin::Organization::Projects::SpendLimitUpdateParams::Currency] The currency for the threshold amount. Currently, only `USD` is supported.
|
|
41
|
+
#
|
|
42
|
+
# @param interval [Symbol, OpenAI::Models::Admin::Organization::Projects::SpendLimitUpdateParams::Interval] The time interval for evaluating spend against the threshold. Currently, only `m
|
|
43
|
+
#
|
|
44
|
+
# @param threshold_amount [Integer] The hard spend limit amount, in cents.
|
|
45
|
+
#
|
|
46
|
+
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
47
|
+
#
|
|
48
|
+
# @return [OpenAI::Models::Admin::Organization::Projects::ProjectSpendLimit]
|
|
49
|
+
#
|
|
50
|
+
# @see OpenAI::Models::Admin::Organization::Projects::SpendLimitUpdateParams
|
|
51
|
+
def update(project_id, params)
|
|
52
|
+
parsed, options = OpenAI::Admin::Organization::Projects::SpendLimitUpdateParams.dump_request(params)
|
|
53
|
+
@client.request(
|
|
54
|
+
method: :post,
|
|
55
|
+
path: ["organization/projects/%1$s/spend_limit", project_id],
|
|
56
|
+
body: parsed,
|
|
57
|
+
model: OpenAI::Admin::Organization::Projects::ProjectSpendLimit,
|
|
58
|
+
security: {admin_api_key_auth: true},
|
|
59
|
+
options: options
|
|
60
|
+
)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Delete a project's hard spend limit.
|
|
64
|
+
#
|
|
65
|
+
# @overload delete(project_id, request_options: {})
|
|
66
|
+
#
|
|
67
|
+
# @param project_id [String] The ID of the project whose hard spend limit is being managed.
|
|
68
|
+
#
|
|
69
|
+
# @param request_options [OpenAI::RequestOptions, Hash{Symbol=>Object}, nil]
|
|
70
|
+
#
|
|
71
|
+
# @return [OpenAI::Models::Admin::Organization::Projects::ProjectSpendLimitDeleted]
|
|
72
|
+
#
|
|
73
|
+
# @see OpenAI::Models::Admin::Organization::Projects::SpendLimitDeleteParams
|
|
74
|
+
def delete(project_id, params = {})
|
|
75
|
+
@client.request(
|
|
76
|
+
method: :delete,
|
|
77
|
+
path: ["organization/projects/%1$s/spend_limit", project_id],
|
|
78
|
+
model: OpenAI::Admin::Organization::Projects::ProjectSpendLimitDeleted,
|
|
79
|
+
security: {admin_api_key_auth: true},
|
|
80
|
+
options: params[:request_options]
|
|
81
|
+
)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @api private
|
|
85
|
+
#
|
|
86
|
+
# @param client [OpenAI::Client]
|
|
87
|
+
def initialize(client:)
|
|
88
|
+
@client = client
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|