anthropic 1.26.0 → 1.27.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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +19 -0
  3. data/README.md +1 -1
  4. data/lib/anthropic/aws.rb +5 -0
  5. data/lib/anthropic/helpers/aws/client.rb +104 -0
  6. data/lib/anthropic/helpers/aws_auth.rb +217 -0
  7. data/lib/anthropic/helpers/bedrock/client.rb +50 -26
  8. data/lib/anthropic/internal/util.rb +17 -3
  9. data/lib/anthropic/models/beta/beta_message.rb +9 -1
  10. data/lib/anthropic/models/beta/beta_raw_message_delta_event.rb +9 -1
  11. data/lib/anthropic/models/beta/beta_refusal_stop_details.rb +60 -0
  12. data/lib/anthropic/models/message.rb +9 -1
  13. data/lib/anthropic/models/raw_message_delta_event.rb +9 -1
  14. data/lib/anthropic/models/refusal_stop_details.rb +56 -0
  15. data/lib/anthropic/models.rb +2 -0
  16. data/lib/anthropic/version.rb +1 -1
  17. data/lib/anthropic.rb +5 -0
  18. data/rbi/anthropic/aws.rbi +5 -0
  19. data/rbi/anthropic/helpers/aws/client.rbi +72 -0
  20. data/rbi/anthropic/internal/util.rbi +8 -0
  21. data/rbi/anthropic/models/beta/beta_message.rbi +17 -0
  22. data/rbi/anthropic/models/beta/beta_raw_message_delta_event.rbi +18 -0
  23. data/rbi/anthropic/models/beta/beta_refusal_stop_details.rbi +115 -0
  24. data/rbi/anthropic/models/message.rbi +15 -0
  25. data/rbi/anthropic/models/raw_message_delta_event.rbi +15 -0
  26. data/rbi/anthropic/models/refusal_stop_details.rbi +93 -0
  27. data/rbi/anthropic/models.rbi +2 -0
  28. data/sig/anthropic/internal/util.rbs +4 -0
  29. data/sig/anthropic/models/beta/beta_message.rbs +5 -0
  30. data/sig/anthropic/models/beta/beta_raw_message_delta_event.rbs +5 -0
  31. data/sig/anthropic/models/beta/beta_refusal_stop_details.rbs +45 -0
  32. data/sig/anthropic/models/message.rbs +5 -0
  33. data/sig/anthropic/models/raw_message_delta_event.rbs +5 -0
  34. data/sig/anthropic/models/refusal_stop_details.rbs +41 -0
  35. data/sig/anthropic/models.rbs +2 -0
  36. metadata +13 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8765d87a8f2c333c114221a23ca51b9562d6364e6585bb517660192974a193d4
4
- data.tar.gz: dfcba061b31eb9a056a0b0cbfe5a0f96b93277a52162d3945f2615d26eea81a4
3
+ metadata.gz: 72c6d580e9df64dc561e9dcd1b5ea9cd9ad18d46293c64dc25f8e6cd971ed8dc
4
+ data.tar.gz: a1124fb9148fc390060d8d9a6f333eb698fb65beaa5e81a7f57c5a02b95fcb16
5
5
  SHA512:
6
- metadata.gz: 04b8f406fe7f06a6d9bc6331030486a1283d099c0e19eb2975fd7a987f911280a7a6e13d277d4d412fd478fa98a3316c114a9ff3cf98c0fb4c028b9d218f8592
7
- data.tar.gz: 727738003e679d0fd5ca540fc918e85f8eccfb67a8f47d45996aaec6ddb58d14ec5ceed23df33197aafb7a779730019cdc27b2ec61aaacb4e549dcd9957905b9
6
+ metadata.gz: a687549d5a637357f3ffd5b8da67529da52410168e7cab51e4485c3c120a15f4dbba7b07d957f5920866f78db44f6bd790cab398a6d07b5a4da3298d0c8038f0
7
+ data.tar.gz: 19245fd17062f33dbc20dc2ba59e5f6c33be3605bd37d3b27af34813cee0e4b37feedcc217d3cb3b7ef354492220dd39dacb71009eb43f7fe90920762e11adda
data/CHANGELOG.md CHANGED
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.27.0 (2026-04-01)
4
+
5
+ Full Changelog: [v1.26.0...v1.27.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.26.0...v1.27.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** add structured stop_details to message responses ([5e636fd](https://github.com/anthropics/anthropic-sdk-ruby/commit/5e636fd9ce945bd52f92d99e21e6bb8b9c212238))
10
+ * bedrock api key auth ([#880](https://github.com/anthropics/anthropic-sdk-ruby/issues/880)) ([93f9b87](https://github.com/anthropics/anthropic-sdk-ruby/commit/93f9b870184a3519270cacec10ceeaa85e9f548c))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * align path encoding with RFC 3986 section 3.3 ([280f489](https://github.com/anthropics/anthropic-sdk-ruby/commit/280f4894bb96af3890cb142df1e6bd0fae53fbcd))
16
+
17
+
18
+ ### Chores
19
+
20
+ * **internal:** client updates ([151043a](https://github.com/anthropics/anthropic-sdk-ruby/commit/151043a45a4f332fb176038799f499be358db44a))
21
+
3
22
  ## 1.26.0 (2026-03-31)
4
23
 
5
24
  Full Changelog: [v1.25.0...v1.26.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.25.0...v1.26.0)
data/README.md CHANGED
@@ -15,7 +15,7 @@ Add to your application's Gemfile:
15
15
  <!-- x-release-please-start-version -->
16
16
 
17
17
  ```ruby
18
- gem "anthropic", "~> 1.26.0"
18
+ gem "anthropic", "~> 1.27.0"
19
19
  ```
20
20
 
21
21
  <!-- x-release-please-end -->
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ AWSClient = Anthropic::Helpers::AWS::Client
5
+ end
@@ -0,0 +1,104 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Helpers
5
+ module AWS
6
+ class Client < Anthropic::Client
7
+ include Anthropic::Helpers::AWSAuth
8
+
9
+ # @return [String, nil]
10
+ attr_reader :aws_region
11
+
12
+ # @return [String, nil]
13
+ attr_reader :workspace_id
14
+
15
+ # Creates and returns a new client for interacting with Anthropic models via the AWS gateway.
16
+ #
17
+ # AWS credentials are resolved in priority order:
18
+ # 1. `api_key` constructor arg → API key mode (x-api-key header, no SigV4)
19
+ # 2. `aws_access_key` + `aws_secret_access_key` args → SigV4 with explicit credentials
20
+ # 3. `aws_profile` arg → SigV4 with named AWS profile
21
+ # 4. `ANTHROPIC_AWS_API_KEY` env var → API key mode (only when no platform auth args given)
22
+ # 5. Default AWS credential chain (env vars → shared config → instance profile) → SigV4
23
+ #
24
+ # When `skip_auth` is true, all auth is skipped and workspace_id is not required.
25
+ #
26
+ # @param api_key [String, nil] Anthropic API key (bypasses SigV4, uses x-api-key header)
27
+ #
28
+ # @param aws_access_key [String, nil] AWS access key ID for SigV4 signing
29
+ #
30
+ # @param aws_secret_access_key [String, nil] AWS secret access key for SigV4 signing
31
+ #
32
+ # @param aws_session_token [String, nil] Optional AWS session token for temporary credentials
33
+ #
34
+ # @param aws_profile [String, nil] AWS profile name (uses SigV4 with named profile)
35
+ #
36
+ # @param aws_region [String, nil] AWS region for the gateway URL and SigV4 signing.
37
+ # Defaults to `ENV["AWS_REGION"]`, then `ENV["AWS_DEFAULT_REGION"]`. Required in SigV4 mode.
38
+ #
39
+ # @param workspace_id [String, nil] Anthropic workspace ID, sent as `anthropic-workspace-id` header.
40
+ # Defaults to `ENV["ANTHROPIC_AWS_WORKSPACE_ID"]`
41
+ #
42
+ # @param skip_auth [Boolean] When true, skip all auth (no SigV4, no API key) and do not
43
+ # require workspace_id. Useful for testing or when auth is handled externally.
44
+ #
45
+ # @param base_url [String, nil] Override the default base URL for the API.
46
+ # Defaults to `ENV["ANTHROPIC_AWS_BASE_URL"]`, then `https://aws-external-anthropic.{region}.api.aws`.
47
+ #
48
+ # @param max_retries [Integer] Max number of retries to attempt after a failed retryable request.
49
+ #
50
+ # @param timeout [Float]
51
+ #
52
+ # @param initial_retry_delay [Float]
53
+ #
54
+ # @param max_retry_delay [Float]
55
+ #
56
+ def initialize(
57
+ api_key: nil,
58
+ aws_access_key: nil,
59
+ aws_secret_access_key: nil,
60
+ aws_session_token: nil,
61
+ aws_profile: nil,
62
+ aws_region: ENV["AWS_REGION"] || ENV["AWS_DEFAULT_REGION"],
63
+ workspace_id: ENV["ANTHROPIC_AWS_WORKSPACE_ID"],
64
+ skip_auth: false,
65
+ base_url: ENV["ANTHROPIC_AWS_BASE_URL"],
66
+ max_retries: self.class::DEFAULT_MAX_RETRIES,
67
+ timeout: self.class::DEFAULT_TIMEOUT_IN_SECONDS,
68
+ initial_retry_delay: self.class::DEFAULT_INITIAL_RETRY_DELAY,
69
+ max_retry_delay: self.class::DEFAULT_MAX_RETRY_DELAY
70
+ )
71
+ effective_api_key, resolved_base_url = setup_aws_auth(
72
+ api_key: api_key,
73
+ aws_access_key: aws_access_key,
74
+ aws_secret_access_key: aws_secret_access_key,
75
+ aws_session_token: aws_session_token,
76
+ aws_profile: aws_profile,
77
+ aws_region: aws_region,
78
+ workspace_id: workspace_id,
79
+ skip_auth: skip_auth,
80
+ base_url: base_url,
81
+ service_name: "aws-external-anthropic",
82
+ env_api_key: "ANTHROPIC_AWS_API_KEY",
83
+ env_workspace_id: "ANTHROPIC_AWS_WORKSPACE_ID",
84
+ derive_base_url: ->(region) { "https://aws-external-anthropic.#{region}.api.aws" }
85
+ )
86
+
87
+ super(
88
+ api_key: effective_api_key,
89
+ base_url: resolved_base_url,
90
+ max_retries: max_retries,
91
+ timeout: timeout,
92
+ initial_retry_delay: initial_retry_delay,
93
+ max_retry_delay: max_retry_delay
94
+ )
95
+ end
96
+
97
+ # @api private
98
+ private def transform_request(request)
99
+ aws_auth_transform_request(request)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,217 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Helpers
5
+ # Shared AWS authentication module used by both the AWS gateway client and the
6
+ # Bedrock Mantle client. Provides SigV4 signing, credential resolution, and
7
+ # config handling parameterized by service name and environment variable names.
8
+ module AWSAuth
9
+ # Sets up AWS authentication state. Call from the including class's `initialize`.
10
+ #
11
+ # @param api_key [String, nil]
12
+ # @param aws_access_key [String, nil]
13
+ # @param aws_secret_access_key [String, nil]
14
+ # @param aws_session_token [String, nil]
15
+ # @param aws_profile [String, nil]
16
+ # @param aws_region [String, nil]
17
+ # @param workspace_id [String, nil]
18
+ # @param skip_auth [Boolean]
19
+ # @param base_url [String, nil]
20
+ # @param service_name [String] AWS service name for SigV4 signing
21
+ # @param env_api_key [String] Primary env var for API key
22
+ # @param env_api_key_fallback [String, nil] Fallback env var for API key
23
+ # @param env_workspace_id [String] Primary env var for workspace ID
24
+ # @param env_workspace_id_fallback [String, nil] Fallback env var for workspace ID
25
+ # @param derive_base_url [Proc] Lambda that takes region and returns default base URL
26
+ #
27
+ # @return [Array(String, String)] [effective_api_key, resolved_base_url]
28
+ private def setup_aws_auth(
29
+ api_key:,
30
+ aws_access_key:,
31
+ aws_secret_access_key:,
32
+ aws_session_token:,
33
+ aws_profile:,
34
+ aws_region:,
35
+ workspace_id:,
36
+ skip_auth:,
37
+ base_url:,
38
+ service_name:,
39
+ env_api_key:,
40
+ env_workspace_id:,
41
+ derive_base_url:,
42
+ env_api_key_fallback: nil,
43
+ env_workspace_id_fallback: nil
44
+ )
45
+ begin
46
+ require("aws-sdk-core")
47
+ rescue LoadError
48
+ message = <<~MSG
49
+
50
+ In order to use Anthropic AWS clients you must require the `aws-sdk-core` gem.
51
+ You can install it by adding the following to your Gemfile:
52
+
53
+ gem "aws-sdk-core"
54
+
55
+ and then running `bundle install`.
56
+
57
+ Alternatively, if you are not using Bundler, simply run:
58
+
59
+ gem install aws-sdk-core
60
+ MSG
61
+
62
+ raise RuntimeError.new(message)
63
+ end
64
+
65
+ if (aws_access_key && !aws_secret_access_key) || (!aws_access_key && aws_secret_access_key)
66
+ raise ArgumentError.new("Both aws_access_key and aws_secret_access_key must be provided together")
67
+ end
68
+
69
+ @skip_auth = skip_auth
70
+
71
+ if @skip_auth
72
+ effective_api_key = nil
73
+ @use_sig_v4 = false
74
+ else
75
+ # Resolve auth mode. Explicit platform auth args suppress the API key env var check.
76
+ has_platform_auth = aws_access_key || aws_secret_access_key || aws_profile
77
+ env_key = env_lookup(env_api_key, env_api_key_fallback)
78
+ effective_api_key = api_key || (has_platform_auth ? nil : env_key)
79
+ @use_sig_v4 = effective_api_key.nil?
80
+ end
81
+
82
+ if @use_sig_v4
83
+ if aws_region.to_s.empty?
84
+ # rubocop:disable Layout/LineLength
85
+ raise ArgumentError.new("No aws_region was given. Set the `aws_region` argument or the `AWS_REGION` / `AWS_DEFAULT_REGION` environment variable.")
86
+ # rubocop:enable Layout/LineLength
87
+ end
88
+
89
+ @aws_region = aws_region
90
+ credentials = resolve_credentials(
91
+ aws_access_key: aws_access_key,
92
+ aws_secret_access_key: aws_secret_access_key,
93
+ aws_session_token: aws_session_token,
94
+ aws_profile: aws_profile
95
+ )
96
+ @signer = Aws::Sigv4::Signer.new(
97
+ service: service_name,
98
+ region: @aws_region,
99
+ credentials_provider: credentials
100
+ )
101
+ end
102
+
103
+ # Workspace ID: constructor > primary env > fallback env
104
+ resolved_workspace_id = workspace_id
105
+ if resolved_workspace_id.to_s.empty?
106
+ resolved_workspace_id = env_lookup(env_workspace_id, env_workspace_id_fallback)
107
+ end
108
+ @workspace_id = resolved_workspace_id.to_s.empty? ? nil : resolved_workspace_id.to_s
109
+
110
+ unless @skip_auth
111
+ if @workspace_id.nil?
112
+ # rubocop:disable Layout/LineLength
113
+ raise ArgumentError.new("No workspace ID found. Set the `workspace_id` argument or the `#{env_workspace_id}` environment variable.")
114
+ # rubocop:enable Layout/LineLength
115
+ end
116
+ end
117
+
118
+ if base_url.nil? && !aws_region.to_s.empty?
119
+ @aws_region ||= aws_region
120
+ base_url = derive_base_url.call(aws_region)
121
+ end
122
+
123
+ if base_url.nil?
124
+ # rubocop:disable Layout/LineLength
125
+ raise ArgumentError.new("No base_url was given and no aws_region is available to derive one. Set the `base_url` argument or provide an `aws_region`.")
126
+ # rubocop:enable Layout/LineLength
127
+ end
128
+
129
+ [effective_api_key, base_url]
130
+ end
131
+
132
+ # Override the base client's auth_headers to prevent ANTHROPIC_API_KEY
133
+ # from leaking as an x-api-key header in SigV4 mode. The server rejects
134
+ # requests that contain both Authorization (SigV4) and x-api-key headers.
135
+ #
136
+ # @return [Hash{String=>String}]
137
+ private def auth_headers
138
+ return {} if @use_sig_v4
139
+ super
140
+ end
141
+
142
+ # Applies workspace-id header and SigV4 signing to the request.
143
+ # Call from the including class's `transform_request`.
144
+ #
145
+ # @param request [Hash{Symbol=>Object}]
146
+ # @return [Hash{Symbol=>Object}]
147
+ private def aws_auth_transform_request(request)
148
+ headers = request.fetch(:headers)
149
+
150
+ headers["anthropic-workspace-id"] = @workspace_id if @workspace_id
151
+
152
+ return request unless @use_sig_v4
153
+
154
+ sliced = request.slice(:method, :url, :body).transform_keys(method: :http_method)
155
+ signed = @signer.sign_request({**sliced, headers: headers})
156
+ headers = Anthropic::Internal::Util.normalized_headers(headers, signed.headers)
157
+ headers.delete("connection")
158
+ {**request, headers: headers}
159
+ end
160
+
161
+ # Resolves AWS credentials from explicit args, profile, env vars, or default chain.
162
+ #
163
+ # @param aws_access_key [String, nil]
164
+ # @param aws_secret_access_key [String, nil]
165
+ # @param aws_session_token [String, nil]
166
+ # @param aws_profile [String, nil]
167
+ #
168
+ # @return [Aws::Credentials, Aws::SharedCredentials, Aws::InstanceProfileCredentials]
169
+ private def resolve_credentials(
170
+ aws_access_key:,
171
+ aws_secret_access_key:,
172
+ aws_session_token:,
173
+ aws_profile:
174
+ )
175
+ if aws_access_key && aws_secret_access_key
176
+ return Aws::Credentials.new(aws_access_key, aws_secret_access_key, aws_session_token)
177
+ end
178
+
179
+ if aws_profile
180
+ return Aws::SharedCredentials.new(profile_name: aws_profile)
181
+ end
182
+
183
+ # Default credential chain: env vars → shared config file → instance profile
184
+ if ENV["AWS_ACCESS_KEY_ID"] && ENV["AWS_SECRET_ACCESS_KEY"]
185
+ return Aws::Credentials.new(
186
+ ENV["AWS_ACCESS_KEY_ID"],
187
+ ENV["AWS_SECRET_ACCESS_KEY"],
188
+ ENV["AWS_SESSION_TOKEN"]
189
+ )
190
+ end
191
+
192
+ begin
193
+ shared = Aws::SharedCredentials.new
194
+ return shared if shared.set?
195
+ rescue StandardError
196
+ nil
197
+ end
198
+
199
+ # Fall back to instance profile (EC2/ECS/Lambda metadata service)
200
+ Aws::InstanceProfileCredentials.new
201
+ end
202
+
203
+ # Returns the first non-empty value from the given env var names.
204
+ #
205
+ # @param names [Array<String, nil>]
206
+ # @return [String, nil]
207
+ private def env_lookup(*names)
208
+ names.each do |name|
209
+ next if name.nil?
210
+ val = ENV[name]
211
+ return val unless val.to_s.empty?
212
+ end
213
+ nil
214
+ end
215
+ end
216
+ end
217
+ end
@@ -21,6 +21,9 @@ module Anthropic
21
21
  # @return [Aws::Credentials]
22
22
  attr_reader :aws_credentials
23
23
 
24
+ # @return [String, nil]
25
+ def api_key = @auth_token
26
+
24
27
  # Creates and returns a new client for interacting with the AWS Bedrock API for Anthropic models.
25
28
  #
26
29
  # AWS credentials are resolved according to the AWS SDK's default resolution order, described at
@@ -37,6 +40,9 @@ module Anthropic
37
40
  #
38
41
  # @param aws_profile [String, nil] Optional AWS profile to use for authentication. Overrides the credential provider chain
39
42
  #
43
+ # @param api_key [String, nil] Optional API key for Bearer token authentication. Mutually exclusive with AWS
44
+ # credentials. Falls back to the `AWS_BEARER_TOKEN_BEDROCK` environment variable if not provided.
45
+ #
40
46
  # @param base_url [String, nil] Override the default base URL for the API, e.g., `"https://api.example.com/v2/"`
41
47
  #
42
48
  # @param max_retries [Integer] The maximum number of times to retry a request if it fails
@@ -57,41 +63,55 @@ module Anthropic
57
63
  aws_access_key: nil,
58
64
  aws_secret_key: nil,
59
65
  aws_session_token: nil,
60
- aws_profile: nil
66
+ aws_profile: nil,
67
+ api_key: nil
61
68
  )
62
- begin
63
- require("aws-sdk-bedrockruntime")
64
- rescue LoadError
65
- message = <<~MSG
69
+ api_key ||= ENV["AWS_BEARER_TOKEN_BEDROCK"]
66
70
 
67
- In order to access Anthropic models on Bedrock you must require the `aws-sdk-bedrockruntime` gem.
68
- You can install it by adding the following to your Gemfile:
71
+ has_aws_credentials = !aws_access_key.nil? || !aws_secret_key.nil? || !aws_session_token.nil? || !aws_profile.nil?
72
+ if !api_key.nil? && has_aws_credentials
73
+ raise ArgumentError.new(
74
+ "Cannot specify both `api_key` and AWS credentials (`aws_access_key`, `aws_secret_key`, `aws_session_token`, `aws_profile`)"
75
+ )
76
+ end
69
77
 
70
- gem "aws-sdk-bedrockruntime"
78
+ if api_key.nil?
79
+ begin
80
+ require("aws-sdk-bedrockruntime")
81
+ rescue LoadError
82
+ message = <<~MSG
71
83
 
72
- and then running `bundle install`.
84
+ In order to access Anthropic models on Bedrock you must require the `aws-sdk-bedrockruntime` gem.
85
+ You can install it by adding the following to your Gemfile:
73
86
 
74
- Alternatively, if you are not using Bundler, simply run:
87
+ gem "aws-sdk-bedrockruntime"
75
88
 
76
- gem install aws-sdk-bedrockruntime
77
- MSG
89
+ and then running `bundle install`.
78
90
 
79
- raise RuntimeError.new(message)
80
- end
91
+ Alternatively, if you are not using Bundler, simply run:
81
92
 
82
- @aws_region, @aws_credentials = resolve_region_and_credentials(
83
- aws_region: aws_region,
84
- aws_secret_key: aws_secret_key,
85
- aws_access_key: aws_access_key,
86
- aws_session_token: aws_session_token,
87
- aws_profile: aws_profile
88
- )
93
+ gem install aws-sdk-bedrockruntime
94
+ MSG
89
95
 
90
- @signer = Aws::Sigv4::Signer.new(
91
- service: "bedrock",
92
- region: @aws_region,
93
- credentials: @aws_credentials
94
- )
96
+ raise RuntimeError.new(message)
97
+ end
98
+
99
+ @aws_region, @aws_credentials = resolve_region_and_credentials(
100
+ aws_region: aws_region,
101
+ aws_secret_key: aws_secret_key,
102
+ aws_access_key: aws_access_key,
103
+ aws_session_token: aws_session_token,
104
+ aws_profile: aws_profile
105
+ )
106
+
107
+ @signer = Aws::Sigv4::Signer.new(
108
+ service: "bedrock",
109
+ region: @aws_region,
110
+ credentials: @aws_credentials
111
+ )
112
+ else
113
+ @aws_region = aws_region
114
+ end
95
115
 
96
116
  base_url ||= ENV.fetch(
97
117
  "ANTHROPIC_BEDROCK_BASE_URL",
@@ -99,6 +119,8 @@ module Anthropic
99
119
  )
100
120
 
101
121
  super(
122
+ api_key: nil,
123
+ auth_token: api_key,
102
124
  base_url: base_url,
103
125
  timeout: timeout,
104
126
  max_retries: max_retries,
@@ -172,6 +194,8 @@ module Anthropic
172
194
  #
173
195
  # @return [Hash{Symbol, Object}]
174
196
  private def transform_request(request)
197
+ return request if @auth_token
198
+
175
199
  headers = request.fetch(:headers)
176
200
  sliced = super.slice(:method, :url, :body).transform_keys(method: :http_method)
177
201
  signed = @signer.sign_request({**sliced, headers: headers})
@@ -237,6 +237,11 @@ module Anthropic
237
237
  end
238
238
  end
239
239
 
240
+ # @type [Regexp]
241
+ #
242
+ # https://www.rfc-editor.org/rfc/rfc3986.html#section-3.3
243
+ RFC_3986_NOT_PCHARS = /[^A-Za-z0-9\-._~!$&'()*+,;=:@]+/
244
+
240
245
  class << self
241
246
  # @api private
242
247
  #
@@ -247,6 +252,15 @@ module Anthropic
247
252
  "#{uri.scheme}://#{uri.host}#{":#{uri.port}" unless uri.port == uri.default_port}"
248
253
  end
249
254
 
255
+ # @api private
256
+ #
257
+ # @param path [String, Integer]
258
+ #
259
+ # @return [String]
260
+ def encode_path(path)
261
+ path.to_s.gsub(Anthropic::Internal::Util::RFC_3986_NOT_PCHARS) { ERB::Util.url_encode(_1) }
262
+ end
263
+
250
264
  # @api private
251
265
  #
252
266
  # @param path [String, Array<String>]
@@ -259,7 +273,7 @@ module Anthropic
259
273
  in []
260
274
  ""
261
275
  in [String => p, *interpolations]
262
- encoded = interpolations.map { ERB::Util.url_encode(_1) }
276
+ encoded = interpolations.map { encode_path(_1) }
263
277
  format(p, *encoded)
264
278
  end
265
279
  end
@@ -576,10 +590,10 @@ module Anthropic
576
590
 
577
591
  case val
578
592
  in Anthropic::FilePart unless val.filename.nil?
579
- filename = ERB::Util.url_encode(val.filename)
593
+ filename = encode_path(val.filename)
580
594
  y << "; filename=\"#{filename}\""
581
595
  in Pathname | IO
582
- filename = ERB::Util.url_encode(::File.basename(val.to_path))
596
+ filename = encode_path(::File.basename(val.to_path))
583
597
  y << "; filename=\"#{filename}\""
584
598
  else
585
599
  end
@@ -95,6 +95,12 @@ module Anthropic
95
95
  # @return [Symbol, :assistant]
96
96
  required :role, const: :assistant
97
97
 
98
+ # @!attribute stop_details
99
+ # Structured information about a refusal.
100
+ #
101
+ # @return [Anthropic::Models::Beta::BetaRefusalStopDetails, nil]
102
+ required :stop_details, -> { Anthropic::Beta::BetaRefusalStopDetails }, nil?: true
103
+
98
104
  # @!attribute stop_reason
99
105
  # The reason that we stopped.
100
106
  #
@@ -152,7 +158,7 @@ module Anthropic
152
158
  # @return [Anthropic::Models::Beta::BetaUsage]
153
159
  required :usage, -> { Anthropic::Beta::BetaUsage }
154
160
 
155
- # @!method initialize(id:, container:, content:, context_management:, model:, stop_reason:, stop_sequence:, usage:, role: :assistant, type: :message)
161
+ # @!method initialize(id:, container:, content:, context_management:, model:, stop_details:, stop_reason:, stop_sequence:, usage:, role: :assistant, type: :message)
156
162
  # Some parameter documentations has been truncated, see
157
163
  # {Anthropic::Models::Beta::BetaMessage} for more details.
158
164
  #
@@ -166,6 +172,8 @@ module Anthropic
166
172
  #
167
173
  # @param model [Symbol, String, Anthropic::Models::Model] The model that will complete your prompt.\n\nSee [models](https://docs.anthropic
168
174
  #
175
+ # @param stop_details [Anthropic::Models::Beta::BetaRefusalStopDetails, nil] Structured information about a refusal.
176
+ #
169
177
  # @param stop_reason [Symbol, Anthropic::Models::Beta::BetaStopReason, nil] The reason that we stopped.
170
178
  #
171
179
  # @param stop_sequence [String, nil] Which custom stop sequence was generated, if any.
@@ -61,6 +61,12 @@ module Anthropic
61
61
  # @return [Anthropic::Models::Beta::BetaContainer, nil]
62
62
  required :container, -> { Anthropic::Beta::BetaContainer }, nil?: true
63
63
 
64
+ # @!attribute stop_details
65
+ # Structured information about a refusal.
66
+ #
67
+ # @return [Anthropic::Models::Beta::BetaRefusalStopDetails, nil]
68
+ required :stop_details, -> { Anthropic::Beta::BetaRefusalStopDetails }, nil?: true
69
+
64
70
  # @!attribute stop_reason
65
71
  #
66
72
  # @return [Symbol, Anthropic::Models::Beta::BetaStopReason, nil]
@@ -71,12 +77,14 @@ module Anthropic
71
77
  # @return [String, nil]
72
78
  required :stop_sequence, String, nil?: true
73
79
 
74
- # @!method initialize(container:, stop_reason:, stop_sequence:)
80
+ # @!method initialize(container:, stop_details:, stop_reason:, stop_sequence:)
75
81
  # Some parameter documentations has been truncated, see
76
82
  # {Anthropic::Models::Beta::BetaRawMessageDeltaEvent::Delta} for more details.
77
83
  #
78
84
  # @param container [Anthropic::Models::Beta::BetaContainer, nil] Information about the container used in the request (for the code execution tool
79
85
  #
86
+ # @param stop_details [Anthropic::Models::Beta::BetaRefusalStopDetails, nil] Structured information about a refusal.
87
+ #
80
88
  # @param stop_reason [Symbol, Anthropic::Models::Beta::BetaStopReason, nil]
81
89
  #
82
90
  # @param stop_sequence [String, nil]
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaRefusalStopDetails < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute category
8
+ # The policy category that triggered the refusal.
9
+ #
10
+ # `null` when the refusal doesn't map to a named category.
11
+ #
12
+ # @return [Symbol, Anthropic::Models::Beta::BetaRefusalStopDetails::Category, nil]
13
+ required :category, enum: -> { Anthropic::Beta::BetaRefusalStopDetails::Category }, nil?: true
14
+
15
+ # @!attribute explanation
16
+ # Human-readable explanation of the refusal.
17
+ #
18
+ # This text is not guaranteed to be stable. `null` when no explanation is
19
+ # available for the category.
20
+ #
21
+ # @return [String, nil]
22
+ required :explanation, String, nil?: true
23
+
24
+ # @!attribute type
25
+ #
26
+ # @return [Symbol, :refusal]
27
+ required :type, const: :refusal
28
+
29
+ # @!method initialize(category:, explanation:, type: :refusal)
30
+ # Some parameter documentations has been truncated, see
31
+ # {Anthropic::Models::Beta::BetaRefusalStopDetails} for more details.
32
+ #
33
+ # Structured information about a refusal.
34
+ #
35
+ # @param category [Symbol, Anthropic::Models::Beta::BetaRefusalStopDetails::Category, nil] The policy category that triggered the refusal.
36
+ #
37
+ # @param explanation [String, nil] Human-readable explanation of the refusal.
38
+ #
39
+ # @param type [Symbol, :refusal]
40
+
41
+ # The policy category that triggered the refusal.
42
+ #
43
+ # `null` when the refusal doesn't map to a named category.
44
+ #
45
+ # @see Anthropic::Models::Beta::BetaRefusalStopDetails#category
46
+ module Category
47
+ extend Anthropic::Internal::Type::Enum
48
+
49
+ CYBER = :cyber
50
+ BIO = :bio
51
+
52
+ # @!method self.values
53
+ # @return [Array<Symbol>]
54
+ end
55
+ end
56
+ end
57
+
58
+ BetaRefusalStopDetails = Beta::BetaRefusalStopDetails
59
+ end
60
+ end