anthropic 1.9.0 → 1.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +28 -0
  3. data/README.md +12 -12
  4. data/lib/anthropic/errors.rb +25 -11
  5. data/lib/anthropic/internal/page.rb +1 -1
  6. data/lib/anthropic/internal/stream.rb +1 -0
  7. data/lib/anthropic/internal/transport/base_client.rb +11 -7
  8. data/lib/anthropic/internal/type/base_page.rb +1 -1
  9. data/lib/anthropic/internal/type/base_stream.rb +9 -1
  10. data/lib/anthropic/internal/util.rb +2 -1
  11. data/lib/anthropic/models/beta/beta_clear_tool_uses_20250919_edit.rb +98 -0
  12. data/lib/anthropic/models/beta/beta_clear_tool_uses_20250919_edit_response.rb +38 -0
  13. data/lib/anthropic/models/beta/beta_context_management_config.rb +22 -0
  14. data/lib/anthropic/models/beta/beta_context_management_response.rb +23 -0
  15. data/lib/anthropic/models/beta/beta_count_tokens_context_management_response.rb +20 -0
  16. data/lib/anthropic/models/beta/beta_input_tokens_clear_at_least.rb +25 -0
  17. data/lib/anthropic/models/beta/beta_input_tokens_trigger.rb +25 -0
  18. data/lib/anthropic/models/beta/beta_memory_tool_20250818.rb +40 -0
  19. data/lib/anthropic/models/beta/beta_memory_tool_20250818_command.rb +30 -0
  20. data/lib/anthropic/models/beta/beta_memory_tool_20250818_create_command.rb +36 -0
  21. data/lib/anthropic/models/beta/beta_memory_tool_20250818_delete_command.rb +28 -0
  22. data/lib/anthropic/models/beta/beta_memory_tool_20250818_insert_command.rb +44 -0
  23. data/lib/anthropic/models/beta/beta_memory_tool_20250818_rename_command.rb +36 -0
  24. data/lib/anthropic/models/beta/beta_memory_tool_20250818_str_replace_command.rb +44 -0
  25. data/lib/anthropic/models/beta/beta_memory_tool_20250818_view_command.rb +36 -0
  26. data/lib/anthropic/models/beta/beta_message.rb +9 -1
  27. data/lib/anthropic/models/beta/beta_message_tokens_count.rb +13 -1
  28. data/lib/anthropic/models/beta/beta_raw_message_delta_event.rb +9 -1
  29. data/lib/anthropic/models/beta/beta_stop_reason.rb +1 -0
  30. data/lib/anthropic/models/beta/beta_tool_union.rb +3 -1
  31. data/lib/anthropic/models/beta/beta_tool_uses_keep.rb +25 -0
  32. data/lib/anthropic/models/beta/beta_tool_uses_trigger.rb +25 -0
  33. data/lib/anthropic/models/beta/message_count_tokens_params.rb +14 -4
  34. data/lib/anthropic/models/beta/message_create_params.rb +11 -3
  35. data/lib/anthropic/models/beta/messages/batch_create_params.rb +11 -3
  36. data/lib/anthropic/models/model.rb +10 -0
  37. data/lib/anthropic/models/stop_reason.rb +1 -0
  38. data/lib/anthropic/resources/beta/messages.rb +12 -6
  39. data/lib/anthropic/version.rb +1 -1
  40. data/lib/anthropic.rb +17 -0
  41. data/rbi/anthropic/errors.rbi +29 -2
  42. data/rbi/anthropic/internal/transport/base_client.rbi +4 -5
  43. data/rbi/anthropic/internal/type/base_page.rbi +1 -1
  44. data/rbi/anthropic/internal/type/base_stream.rbi +16 -1
  45. data/rbi/anthropic/internal/util.rbi +1 -1
  46. data/rbi/anthropic/models/beta/beta_clear_tool_uses_20250919_edit.rbi +183 -0
  47. data/rbi/anthropic/models/beta/beta_clear_tool_uses_20250919_edit_response.rbi +62 -0
  48. data/rbi/anthropic/models/beta/beta_context_management_config.rbi +56 -0
  49. data/rbi/anthropic/models/beta/beta_context_management_response.rbi +53 -0
  50. data/rbi/anthropic/models/beta/beta_count_tokens_context_management_response.rbi +35 -0
  51. data/rbi/anthropic/models/beta/beta_input_tokens_clear_at_least.rbi +33 -0
  52. data/rbi/anthropic/models/beta/beta_input_tokens_trigger.rbi +33 -0
  53. data/rbi/anthropic/models/beta/beta_memory_tool_20250818.rbi +72 -0
  54. data/rbi/anthropic/models/beta/beta_memory_tool_20250818_command.rbi +33 -0
  55. data/rbi/anthropic/models/beta/beta_memory_tool_20250818_create_command.rbi +53 -0
  56. data/rbi/anthropic/models/beta/beta_memory_tool_20250818_delete_command.rbi +41 -0
  57. data/rbi/anthropic/models/beta/beta_memory_tool_20250818_insert_command.rbi +69 -0
  58. data/rbi/anthropic/models/beta/beta_memory_tool_20250818_rename_command.rbi +55 -0
  59. data/rbi/anthropic/models/beta/beta_memory_tool_20250818_str_replace_command.rbi +64 -0
  60. data/rbi/anthropic/models/beta/beta_memory_tool_20250818_view_command.rbi +59 -0
  61. data/rbi/anthropic/models/beta/beta_message.rbi +20 -0
  62. data/rbi/anthropic/models/beta/beta_message_tokens_count.rbi +40 -2
  63. data/rbi/anthropic/models/beta/beta_raw_message_delta_event.rbi +20 -0
  64. data/rbi/anthropic/models/beta/beta_stop_reason.rbi +5 -0
  65. data/rbi/anthropic/models/beta/beta_tool_union.rbi +1 -0
  66. data/rbi/anthropic/models/beta/beta_tool_uses_keep.rbi +33 -0
  67. data/rbi/anthropic/models/beta/beta_tool_uses_trigger.rbi +33 -0
  68. data/rbi/anthropic/models/beta/message_count_tokens_params.rbi +23 -0
  69. data/rbi/anthropic/models/beta/message_create_params.rbi +22 -0
  70. data/rbi/anthropic/models/beta/messages/batch_create_params.rbi +28 -0
  71. data/rbi/anthropic/models/model.rbi +8 -0
  72. data/rbi/anthropic/models/stop_reason.rbi +5 -0
  73. data/rbi/anthropic/resources/beta/messages.rbi +15 -0
  74. data/sig/anthropic/errors.rbs +7 -0
  75. data/sig/anthropic/internal/type/base_stream.rbs +5 -0
  76. data/sig/anthropic/models/beta/beta_clear_tool_uses_20250919_edit.rbs +77 -0
  77. data/sig/anthropic/models/beta/beta_clear_tool_uses_20250919_edit_response.rbs +34 -0
  78. data/sig/anthropic/models/beta/beta_context_management_config.rbs +26 -0
  79. data/sig/anthropic/models/beta/beta_context_management_response.rbs +24 -0
  80. data/sig/anthropic/models/beta/beta_count_tokens_context_management_response.rbs +18 -0
  81. data/sig/anthropic/models/beta/beta_input_tokens_clear_at_least.rbs +20 -0
  82. data/sig/anthropic/models/beta/beta_input_tokens_trigger.rbs +19 -0
  83. data/sig/anthropic/models/beta/beta_memory_tool_20250818.rbs +34 -0
  84. data/sig/anthropic/models/beta/beta_memory_tool_20250818_command.rbs +21 -0
  85. data/sig/anthropic/models/beta/beta_memory_tool_20250818_create_command.rbs +26 -0
  86. data/sig/anthropic/models/beta/beta_memory_tool_20250818_delete_command.rbs +20 -0
  87. data/sig/anthropic/models/beta/beta_memory_tool_20250818_insert_command.rbs +39 -0
  88. data/sig/anthropic/models/beta/beta_memory_tool_20250818_rename_command.rbs +26 -0
  89. data/sig/anthropic/models/beta/beta_memory_tool_20250818_str_replace_command.rbs +39 -0
  90. data/sig/anthropic/models/beta/beta_memory_tool_20250818_view_command.rbs +32 -0
  91. data/sig/anthropic/models/beta/beta_message.rbs +5 -0
  92. data/sig/anthropic/models/beta/beta_message_tokens_count.rbs +15 -3
  93. data/sig/anthropic/models/beta/beta_raw_message_delta_event.rbs +5 -0
  94. data/sig/anthropic/models/beta/beta_stop_reason.rbs +2 -0
  95. data/sig/anthropic/models/beta/beta_tool_union.rbs +1 -0
  96. data/sig/anthropic/models/beta/beta_tool_uses_keep.rbs +19 -0
  97. data/sig/anthropic/models/beta/beta_tool_uses_trigger.rbs +19 -0
  98. data/sig/anthropic/models/beta/message_count_tokens_params.rbs +6 -0
  99. data/sig/anthropic/models/beta/message_create_params.rbs +5 -0
  100. data/sig/anthropic/models/beta/messages/batch_create_params.rbs +5 -0
  101. data/sig/anthropic/models/model.rbs +8 -0
  102. data/sig/anthropic/models/stop_reason.rbs +2 -0
  103. data/sig/anthropic/resources/beta/messages.rbs +3 -0
  104. metadata +53 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9508f2174591353cfaa66f66d1ec7d72fbd3dced9f88e64aae101ad0b370ec51
4
- data.tar.gz: 4e10f3b7dcdfe9e1fc2bf5efec9bb8578d63f2d49a0ed36b08db2153109a0ada
3
+ metadata.gz: a712fe41480aa96f93367ac509a0b8bc51e58939e1805b54dee7f9b4d78501d5
4
+ data.tar.gz: 630a2cc4ebfb6bcecf08168c8dba0bd3d589c66a6931a96e11cd2cc12fe5e6f1
5
5
  SHA512:
6
- metadata.gz: b5eeb2c0701c8ab45b86c58f28c4fd49344ae4b9ac1539486ba282ce3b9154cd3b7e8466fb933b61206f18ef2024f50de8366d5aa89336e86307e2ab22a8f1c2
7
- data.tar.gz: c6f369c9cd95b5501e4416dd8c46ba936f2b09134ccb1a7fec65e7a7948b0e734db46bc3836dee43deac948c4fd216162a5395301c71b837e6277cdbabbbc7a9
6
+ metadata.gz: fa94a6b50849f5ef569dac4e21ea5b266505a6069714ab9b58d4c39d13c65cc50c8ce1753e475523740e954119bd980e1eb92909de08d0f33452ab1b72cb7a3b
7
+ data.tar.gz: 0e577c3fb49d961d8ec9fe8f17d417d588a65545b905491329c378bd3e291e33d7c60abd08eeac3fa10e319c2df19f65f3f2771f8b916db172b790479dad514f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,33 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.10.0 (2025-09-29)
4
+
5
+ Full Changelog: [v1.9.0...v1.10.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.9.0...v1.10.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** adds support for Claude Sonnet 4.5 and context management features ([3a3cad6](https://github.com/anthropics/anthropic-sdk-ruby/commit/3a3cad636f05c4e395e6078aa7b429c464ad66aa))
10
+ * expose response headers for both streams and errors ([9bfbae1](https://github.com/anthropics/anthropic-sdk-ruby/commit/9bfbae1483ce10852f7d89f1a598ed41a3f057e5))
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * always send filename in content-disposition headers ([#126](https://github.com/anthropics/anthropic-sdk-ruby/issues/126)) ([0e665f3](https://github.com/anthropics/anthropic-sdk-ruby/commit/0e665f34f0d736a400e0ab8b82cad7ccaf0845b1))
16
+ * **internal:** use null byte as file separator in the fast formatting script ([beae717](https://github.com/anthropics/anthropic-sdk-ruby/commit/beae717a7ce89349456e6a50b261c606ffce7759))
17
+ * shorten multipart boundary sep to less than RFC specificed max length ([40226f9](https://github.com/anthropics/anthropic-sdk-ruby/commit/40226f94c36291e84b0aef86a9058080ba94640b))
18
+
19
+
20
+ ### Performance Improvements
21
+
22
+ * faster code formatting ([47de8dd](https://github.com/anthropics/anthropic-sdk-ruby/commit/47de8dd9fc0f10dcd623cbe394d802c5e2dc00af))
23
+
24
+
25
+ ### Chores
26
+
27
+ * allow fast-format to use bsd sed as well ([ea0324c](https://github.com/anthropics/anthropic-sdk-ruby/commit/ea0324c0f1aadfc870b0ddc6438728fed44b12f2))
28
+ * do not install brew dependencies in ./scripts/bootstrap by default ([2091081](https://github.com/anthropics/anthropic-sdk-ruby/commit/209108181b9ab99ff224cf15910af674451ed477))
29
+ * **internal:** fix tests ([59ce934](https://github.com/anthropics/anthropic-sdk-ruby/commit/59ce9348b0d17c9ecd8ccb83fd16c8aff743dc8b))
30
+
3
31
  ## 1.9.0 (2025-09-10)
4
32
 
5
33
  Full Changelog: [v1.8.0...v1.9.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.8.0...v1.9.0)
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 "anthropic", "~> 1.9.0"
18
+ gem "anthropic", "~> 1.10.0"
19
19
  ```
20
20
 
21
21
  <!-- x-release-please-end -->
@@ -39,7 +39,7 @@ anthropic = Anthropic::Client.new(
39
39
  message = anthropic.messages.create(
40
40
  max_tokens: 1024,
41
41
  messages: [{role: "user", content: "Hello, Claude"}],
42
- model: :"claude-sonnet-4-20250514"
42
+ model: :"claude-sonnet-4-5-20250929"
43
43
  )
44
44
 
45
45
  puts(message.content)
@@ -53,7 +53,7 @@ We provide support for streaming responses using Server-Sent Events (SSE).
53
53
  stream = anthropic.messages.stream(
54
54
  max_tokens: 1024,
55
55
  messages: [{role: "user", content: "Hello, Claude"}],
56
- model: :"claude-sonnet-4-20250514"
56
+ model: :"claude-sonnet-4-5-20250929"
57
57
  )
58
58
 
59
59
  stream.each do |message|
@@ -69,7 +69,7 @@ This library provides several conveniences for streaming messages, for example:
69
69
  stream = anthropic.messages.stream(
70
70
  max_tokens: 1024,
71
71
  messages: [{role: :user, content: "Say hello there!"}],
72
- model: :"claude-sonnet-4-20250514"
72
+ model: :"claude-sonnet-4-5-20250929"
73
73
  )
74
74
 
75
75
  stream.text.each do |text|
@@ -138,7 +138,7 @@ begin
138
138
  message = anthropic.messages.create(
139
139
  max_tokens: 1024,
140
140
  messages: [{role: "user", content: "Hello, Claude"}],
141
- model: :"claude-sonnet-4-20250514"
141
+ model: :"claude-sonnet-4-5-20250929"
142
142
  )
143
143
  rescue Anthropic::Errors::APIConnectionError => e
144
144
  puts("The server could not be reached")
@@ -185,7 +185,7 @@ anthropic = Anthropic::Client.new(
185
185
  anthropic.messages.create(
186
186
  max_tokens: 1024,
187
187
  messages: [{role: "user", content: "Hello, Claude"}],
188
- model: :"claude-sonnet-4-20250514",
188
+ model: :"claude-sonnet-4-5-20250929",
189
189
  request_options: {max_retries: 5}
190
190
  )
191
191
  ```
@@ -204,7 +204,7 @@ anthropic = Anthropic::Client.new(
204
204
  anthropic.messages.create(
205
205
  max_tokens: 1024,
206
206
  messages: [{role: "user", content: "Hello, Claude"}],
207
- model: :"claude-sonnet-4-20250514",
207
+ model: :"claude-sonnet-4-5-20250929",
208
208
  request_options: {timeout: 5}
209
209
  )
210
210
  ```
@@ -235,7 +235,7 @@ message = anthropic.messages.create(
235
235
  content: "Hello, Claude"
236
236
  }
237
237
  ],
238
- model: "anthropic.claude-sonnet-4-20250514-v2:0"
238
+ model: "anthropic.claude-sonnet-4-5-20250929-v2:0"
239
239
  )
240
240
 
241
241
  puts(message)
@@ -300,7 +300,7 @@ message =
300
300
  anthropic.messages.create(
301
301
  max_tokens: 1024,
302
302
  messages: [{role: "user", content: "Hello, Claude"}],
303
- model: :"claude-sonnet-4-20250514",
303
+ model: :"claude-sonnet-4-5-20250929",
304
304
  request_options: {
305
305
  extra_query: {my_query_parameter: value},
306
306
  extra_body: {my_body_parameter: value},
@@ -349,7 +349,7 @@ You can provide typesafe request parameters like so:
349
349
  anthropic.messages.create(
350
350
  max_tokens: 1024,
351
351
  messages: [Anthropic::MessageParam.new(role: "user", content: "Hello, Claude")],
352
- model: :"claude-sonnet-4-20250514"
352
+ model: :"claude-sonnet-4-5-20250929"
353
353
  )
354
354
  ```
355
355
 
@@ -360,14 +360,14 @@ Or, equivalently:
360
360
  anthropic.messages.create(
361
361
  max_tokens: 1024,
362
362
  messages: [{role: "user", content: "Hello, Claude"}],
363
- model: :"claude-sonnet-4-20250514"
363
+ model: :"claude-sonnet-4-5-20250929"
364
364
  )
365
365
 
366
366
  # You can also splat a full Params class:
367
367
  params = Anthropic::MessageCreateParams.new(
368
368
  max_tokens: 1024,
369
369
  messages: [Anthropic::MessageParam.new(role: "user", content: "Hello, Claude")],
370
- model: :"claude-sonnet-4-20250514"
370
+ model: :"claude-sonnet-4-5-20250929"
371
371
  )
372
372
  anthropic.messages.create(**params)
373
373
  ```
@@ -40,6 +40,9 @@ module Anthropic
40
40
  # @return [Integer, nil]
41
41
  attr_accessor :status
42
42
 
43
+ # @return [Hash{String=>String}, nil]
44
+ attr_accessor :headers
45
+
43
46
  # @return [Object, nil]
44
47
  attr_accessor :body
45
48
 
@@ -47,13 +50,15 @@ module Anthropic
47
50
  #
48
51
  # @param url [URI::Generic]
49
52
  # @param status [Integer, nil]
53
+ # @param headers [Hash{String=>String}, nil]
50
54
  # @param body [Object, nil]
51
55
  # @param request [nil]
52
56
  # @param response [nil]
53
57
  # @param message [String, nil]
54
- def initialize(url:, status: nil, body: nil, request: nil, response: nil, message: nil)
58
+ def initialize(url:, status: nil, headers: nil, body: nil, request: nil, response: nil, message: nil)
55
59
  @url = url
56
60
  @status = status
61
+ @headers = headers
57
62
  @body = body
58
63
  @request = request
59
64
  @response = response
@@ -74,6 +79,7 @@ module Anthropic
74
79
  #
75
80
  # @param url [URI::Generic]
76
81
  # @param status [nil]
82
+ # @param headers [Hash{String=>String}, nil]
77
83
  # @param body [nil]
78
84
  # @param request [nil]
79
85
  # @param response [nil]
@@ -81,6 +87,7 @@ module Anthropic
81
87
  def initialize(
82
88
  url:,
83
89
  status: nil,
90
+ headers: nil,
84
91
  body: nil,
85
92
  request: nil,
86
93
  response: nil,
@@ -95,6 +102,7 @@ module Anthropic
95
102
  #
96
103
  # @param url [URI::Generic]
97
104
  # @param status [nil]
105
+ # @param headers [Hash{String=>String}, nil]
98
106
  # @param body [nil]
99
107
  # @param request [nil]
100
108
  # @param response [nil]
@@ -102,6 +110,7 @@ module Anthropic
102
110
  def initialize(
103
111
  url:,
104
112
  status: nil,
113
+ headers: nil,
105
114
  body: nil,
106
115
  request: nil,
107
116
  response: nil,
@@ -116,21 +125,24 @@ module Anthropic
116
125
  #
117
126
  # @param url [URI::Generic]
118
127
  # @param status [Integer]
128
+ # @param headers [Hash{String=>String}, nil]
119
129
  # @param body [Object, nil]
120
130
  # @param request [nil]
121
131
  # @param response [nil]
122
132
  # @param message [String, nil]
123
133
  #
124
134
  # @return [self]
125
- def self.for(url:, status:, body:, request:, response:, message: nil)
126
- kwargs = {
127
- url: url,
128
- status: status,
129
- body: body,
130
- request: request,
131
- response: response,
132
- message: message
133
- }
135
+ def self.for(url:, status:, headers:, body:, request:, response:, message: nil)
136
+ kwargs =
137
+ {
138
+ url: url,
139
+ status: status,
140
+ headers: headers,
141
+ body: body,
142
+ request: request,
143
+ response: response,
144
+ message: message
145
+ }
134
146
 
135
147
  case status
136
148
  in 400
@@ -162,15 +174,17 @@ module Anthropic
162
174
  #
163
175
  # @param url [URI::Generic]
164
176
  # @param status [Integer]
177
+ # @param headers [Hash{String=>String}, nil]
165
178
  # @param body [Object, nil]
166
179
  # @param request [nil]
167
180
  # @param response [nil]
168
181
  # @param message [String, nil]
169
- def initialize(url:, status:, body:, request:, response:, message: nil)
182
+ def initialize(url:, status:, headers:, body:, request:, response:, message: nil)
170
183
  message ||= {url: url.to_s, status: status, body: body}
171
184
  super(
172
185
  url: url,
173
186
  status: status,
187
+ headers: headers,
174
188
  body: body,
175
189
  request: request,
176
190
  response: response,
@@ -69,7 +69,7 @@ module Anthropic
69
69
  #
70
70
  # @param client [Anthropic::Internal::Transport::BaseClient]
71
71
  # @param req [Hash{Symbol=>Object}]
72
- # @param headers [Hash{String=>String}, Net::HTTPHeader]
72
+ # @param headers [Hash{String=>String}]
73
73
  # @param page_data [Hash{Symbol=>Object}]
74
74
  def initialize(client:, req:, headers:, page_data:)
75
75
  super
@@ -43,6 +43,7 @@ module Anthropic
43
43
  err = Anthropic::Errors::APIStatusError.for(
44
44
  url: @url,
45
45
  status: @status,
46
+ headers: @headers,
46
47
  body: decoded,
47
48
  request: nil,
48
49
  response: @response
@@ -47,7 +47,7 @@ module Anthropic
47
47
  # @api private
48
48
  #
49
49
  # @param status [Integer]
50
- # @param headers [Hash{String=>String}, Net::HTTPHeader]
50
+ # @param headers [Hash{String=>String}]
51
51
  #
52
52
  # @return [Boolean]
53
53
  def should_retry?(status, headers:)
@@ -85,7 +85,7 @@ module Anthropic
85
85
  #
86
86
  # @param status [Integer]
87
87
  #
88
- # @param response_headers [Hash{String=>String}, Net::HTTPHeader]
88
+ # @param response_headers [Hash{String=>String}]
89
89
  #
90
90
  # @return [Hash{Symbol=>Object}]
91
91
  def follow_redirect(request, status:, response_headers:)
@@ -396,6 +396,7 @@ module Anthropic
396
396
  rescue Anthropic::Errors::APIConnectionError => e
397
397
  status = e
398
398
  end
399
+ headers = Anthropic::Internal::Util.normalized_headers(response&.each_header&.to_h)
399
400
 
400
401
  case status
401
402
  in ..299
@@ -408,7 +409,7 @@ module Anthropic
408
409
  in 300..399
409
410
  self.class.reap_connection!(status, stream: stream)
410
411
 
411
- request = self.class.follow_redirect(request, status: status, response_headers: response)
412
+ request = self.class.follow_redirect(request, status: status, response_headers: headers)
412
413
  send_request(
413
414
  request,
414
415
  redirect_count: redirect_count + 1,
@@ -417,9 +418,9 @@ module Anthropic
417
418
  )
418
419
  in Anthropic::Errors::APIConnectionError if retry_count >= max_retries
419
420
  raise status
420
- in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: response)
421
+ in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: headers)
421
422
  decoded = Kernel.then do
422
- Anthropic::Internal::Util.decode_content(response, stream: stream, suppress_error: true)
423
+ Anthropic::Internal::Util.decode_content(headers, stream: stream, suppress_error: true)
423
424
  ensure
424
425
  self.class.reap_connection!(status, stream: stream)
425
426
  end
@@ -427,6 +428,7 @@ module Anthropic
427
428
  raise Anthropic::Errors::APIStatusError.for(
428
429
  url: url,
429
430
  status: status,
431
+ headers: headers,
430
432
  body: decoded,
431
433
  request: nil,
432
434
  response: response
@@ -503,19 +505,21 @@ module Anthropic
503
505
  send_retry_header: send_retry_header
504
506
  )
505
507
 
506
- decoded = Anthropic::Internal::Util.decode_content(response, stream: stream)
508
+ headers = Anthropic::Internal::Util.normalized_headers(response.each_header.to_h)
509
+ decoded = Anthropic::Internal::Util.decode_content(headers, stream: stream)
507
510
  case req
508
511
  in {stream: Class => st}
509
512
  st.new(
510
513
  model: model,
511
514
  url: url,
512
515
  status: status,
516
+ headers: headers,
513
517
  response: response,
514
518
  unwrap: unwrap,
515
519
  stream: decoded
516
520
  )
517
521
  in {page: Class => page}
518
- page.new(client: self, req: req, headers: response, page_data: decoded)
522
+ page.new(client: self, req: req, headers: headers, page_data: decoded)
519
523
  else
520
524
  unwrapped = Anthropic::Internal::Util.dig(decoded, unwrap)
521
525
  Anthropic::Internal::Type::Converter.coerce(model, unwrapped)
@@ -39,7 +39,7 @@ module Anthropic
39
39
  #
40
40
  # @param client [Anthropic::Internal::Transport::BaseClient]
41
41
  # @param req [Hash{Symbol=>Object}]
42
- # @param headers [Hash{String=>String}, Net::HTTPHeader]
42
+ # @param headers [Hash{String=>String}]
43
43
  # @param page_data [Object]
44
44
  def initialize(client:, req:, headers:, page_data:)
45
45
  @client = client
@@ -28,6 +28,12 @@ module Anthropic
28
28
  def defer_closing(stream) = ->(_id) { Anthropic::Internal::Util.close_fused!(stream) }
29
29
  end
30
30
 
31
+ # @return [Integer]
32
+ attr_reader :status
33
+
34
+ # @return [Hash{String=>String}]
35
+ attr_reader :headers
36
+
31
37
  # @api public
32
38
  #
33
39
  # @return [void]
@@ -63,13 +69,15 @@ module Anthropic
63
69
  # @param model [Class, Anthropic::Internal::Type::Converter]
64
70
  # @param url [URI::Generic]
65
71
  # @param status [Integer]
72
+ # @param headers [Hash{String=>String}]
66
73
  # @param response [Net::HTTPResponse]
67
74
  # @param unwrap [Symbol, Integer, Array<Symbol, Integer>, Proc]
68
75
  # @param stream [Enumerable<Object>]
69
- def initialize(model:, url:, status:, response:, unwrap:, stream:)
76
+ def initialize(model:, url:, status:, headers:, response:, unwrap:, stream:)
70
77
  @model = model
71
78
  @url = url
72
79
  @status = status
80
+ @headers = headers
73
81
  @response = response
74
82
  @unwrap = unwrap
75
83
  @stream = stream
@@ -566,6 +566,7 @@ module Anthropic
566
566
  #
567
567
  # @return [Array(String, Enumerable<String>)]
568
568
  private def encode_multipart_streaming(body)
569
+ # RFC 1521 Section 7.2.1 says we should have 70 char maximum for boundary length
569
570
  boundary = SecureRandom.urlsafe_base64(30)
570
571
 
571
572
  closing = []
@@ -647,7 +648,7 @@ module Anthropic
647
648
  #
648
649
  # Assumes each chunk in stream has `Encoding::BINARY`.
649
650
  #
650
- # @param headers [Hash{String=>String}, Net::HTTPHeader]
651
+ # @param headers [Hash{String=>String}]
651
652
  # @param stream [Enumerable<String>]
652
653
  # @param suppress_error [Boolean]
653
654
  #
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaClearToolUses20250919Edit < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute type
8
+ #
9
+ # @return [Symbol, :clear_tool_uses_20250919]
10
+ required :type, const: :clear_tool_uses_20250919
11
+
12
+ # @!attribute clear_at_least
13
+ # Minimum number of tokens that must be cleared when triggered. Context will only
14
+ # be modified if at least this many tokens can be removed.
15
+ #
16
+ # @return [Anthropic::Models::Beta::BetaInputTokensClearAtLeast, nil]
17
+ optional :clear_at_least, -> { Anthropic::Beta::BetaInputTokensClearAtLeast }, nil?: true
18
+
19
+ # @!attribute clear_tool_inputs
20
+ # Whether to clear all tool inputs (bool) or specific tool inputs to clear (list)
21
+ #
22
+ # @return [Boolean, Array<String>, nil]
23
+ optional :clear_tool_inputs,
24
+ union: -> { Anthropic::Beta::BetaClearToolUses20250919Edit::ClearToolInputs },
25
+ nil?: true
26
+
27
+ # @!attribute exclude_tools
28
+ # Tool names whose uses are preserved from clearing
29
+ #
30
+ # @return [Array<String>, nil]
31
+ optional :exclude_tools, Anthropic::Internal::Type::ArrayOf[String], nil?: true
32
+
33
+ # @!attribute keep
34
+ # Number of tool uses to retain in the conversation
35
+ #
36
+ # @return [Anthropic::Models::Beta::BetaToolUsesKeep, nil]
37
+ optional :keep, -> { Anthropic::Beta::BetaToolUsesKeep }
38
+
39
+ # @!attribute trigger
40
+ # Condition that triggers the context management strategy
41
+ #
42
+ # @return [Anthropic::Models::Beta::BetaInputTokensTrigger, Anthropic::Models::Beta::BetaToolUsesTrigger, nil]
43
+ optional :trigger, union: -> { Anthropic::Beta::BetaClearToolUses20250919Edit::Trigger }
44
+
45
+ # @!method initialize(clear_at_least: nil, clear_tool_inputs: nil, exclude_tools: nil, keep: nil, trigger: nil, type: :clear_tool_uses_20250919)
46
+ # Some parameter documentations has been truncated, see
47
+ # {Anthropic::Models::Beta::BetaClearToolUses20250919Edit} for more details.
48
+ #
49
+ # @param clear_at_least [Anthropic::Models::Beta::BetaInputTokensClearAtLeast, nil] Minimum number of tokens that must be cleared when triggered. Context will only
50
+ #
51
+ # @param clear_tool_inputs [Boolean, Array<String>, nil] Whether to clear all tool inputs (bool) or specific tool inputs to clear (list)
52
+ #
53
+ # @param exclude_tools [Array<String>, nil] Tool names whose uses are preserved from clearing
54
+ #
55
+ # @param keep [Anthropic::Models::Beta::BetaToolUsesKeep] Number of tool uses to retain in the conversation
56
+ #
57
+ # @param trigger [Anthropic::Models::Beta::BetaInputTokensTrigger, Anthropic::Models::Beta::BetaToolUsesTrigger] Condition that triggers the context management strategy
58
+ #
59
+ # @param type [Symbol, :clear_tool_uses_20250919]
60
+
61
+ # Whether to clear all tool inputs (bool) or specific tool inputs to clear (list)
62
+ #
63
+ # @see Anthropic::Models::Beta::BetaClearToolUses20250919Edit#clear_tool_inputs
64
+ module ClearToolInputs
65
+ extend Anthropic::Internal::Type::Union
66
+
67
+ variant Anthropic::Internal::Type::Boolean
68
+
69
+ variant -> { Anthropic::Models::Beta::BetaClearToolUses20250919Edit::ClearToolInputs::StringArray }
70
+
71
+ # @!method self.variants
72
+ # @return [Array(Boolean, Array<String>)]
73
+
74
+ # @type [Anthropic::Internal::Type::Converter]
75
+ StringArray = Anthropic::Internal::Type::ArrayOf[String]
76
+ end
77
+
78
+ # Condition that triggers the context management strategy
79
+ #
80
+ # @see Anthropic::Models::Beta::BetaClearToolUses20250919Edit#trigger
81
+ module Trigger
82
+ extend Anthropic::Internal::Type::Union
83
+
84
+ discriminator :type
85
+
86
+ variant :input_tokens, -> { Anthropic::Beta::BetaInputTokensTrigger }
87
+
88
+ variant :tool_uses, -> { Anthropic::Beta::BetaToolUsesTrigger }
89
+
90
+ # @!method self.variants
91
+ # @return [Array(Anthropic::Models::Beta::BetaInputTokensTrigger, Anthropic::Models::Beta::BetaToolUsesTrigger)]
92
+ end
93
+ end
94
+ end
95
+
96
+ BetaClearToolUses20250919Edit = Beta::BetaClearToolUses20250919Edit
97
+ end
98
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaClearToolUses20250919EditResponse < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute cleared_input_tokens
8
+ # Number of input tokens cleared by this edit.
9
+ #
10
+ # @return [Integer]
11
+ required :cleared_input_tokens, Integer
12
+
13
+ # @!attribute cleared_tool_uses
14
+ # Number of tool uses that were cleared.
15
+ #
16
+ # @return [Integer]
17
+ required :cleared_tool_uses, Integer
18
+
19
+ # @!attribute type
20
+ # The type of context management edit applied.
21
+ #
22
+ # @return [Symbol, :clear_tool_uses_20250919]
23
+ required :type, const: :clear_tool_uses_20250919
24
+
25
+ # @!method initialize(cleared_input_tokens:, cleared_tool_uses:, type: :clear_tool_uses_20250919)
26
+ # Results for clear_tool_uses_20250919 edit.
27
+ #
28
+ # @param cleared_input_tokens [Integer] Number of input tokens cleared by this edit.
29
+ #
30
+ # @param cleared_tool_uses [Integer] Number of tool uses that were cleared.
31
+ #
32
+ # @param type [Symbol, :clear_tool_uses_20250919] The type of context management edit applied.
33
+ end
34
+ end
35
+
36
+ BetaClearToolUses20250919EditResponse = Beta::BetaClearToolUses20250919EditResponse
37
+ end
38
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaContextManagementConfig < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute edits
8
+ # List of context management edits to apply
9
+ #
10
+ # @return [Array<Anthropic::Models::Beta::BetaClearToolUses20250919Edit>, nil]
11
+ optional :edits, -> { Anthropic::Internal::Type::ArrayOf[Anthropic::Beta::BetaClearToolUses20250919Edit] }
12
+
13
+ # @!method initialize(edits: nil)
14
+ # Configuration for context management operations.
15
+ #
16
+ # @param edits [Array<Anthropic::Models::Beta::BetaClearToolUses20250919Edit>] List of context management edits to apply
17
+ end
18
+ end
19
+
20
+ BetaContextManagementConfig = Beta::BetaContextManagementConfig
21
+ end
22
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaContextManagementResponse < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute applied_edits
8
+ # List of context management edits that were applied.
9
+ #
10
+ # @return [Array<Anthropic::Models::Beta::BetaClearToolUses20250919EditResponse>]
11
+ required :applied_edits,
12
+ -> { Anthropic::Internal::Type::ArrayOf[Anthropic::Beta::BetaClearToolUses20250919EditResponse] }
13
+
14
+ # @!method initialize(applied_edits:)
15
+ # Information about context management operations applied during the request.
16
+ #
17
+ # @param applied_edits [Array<Anthropic::Models::Beta::BetaClearToolUses20250919EditResponse>] List of context management edits that were applied.
18
+ end
19
+ end
20
+
21
+ BetaContextManagementResponse = Beta::BetaContextManagementResponse
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaCountTokensContextManagementResponse < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute original_input_tokens
8
+ # The original token count before context management was applied
9
+ #
10
+ # @return [Integer]
11
+ required :original_input_tokens, Integer
12
+
13
+ # @!method initialize(original_input_tokens:)
14
+ # @param original_input_tokens [Integer] The original token count before context management was applied
15
+ end
16
+ end
17
+
18
+ BetaCountTokensContextManagementResponse = Beta::BetaCountTokensContextManagementResponse
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaInputTokensClearAtLeast < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute type
8
+ #
9
+ # @return [Symbol, :input_tokens]
10
+ required :type, const: :input_tokens
11
+
12
+ # @!attribute value
13
+ #
14
+ # @return [Integer]
15
+ required :value, Integer
16
+
17
+ # @!method initialize(value:, type: :input_tokens)
18
+ # @param value [Integer]
19
+ # @param type [Symbol, :input_tokens]
20
+ end
21
+ end
22
+
23
+ BetaInputTokensClearAtLeast = Beta::BetaInputTokensClearAtLeast
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaInputTokensTrigger < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute type
8
+ #
9
+ # @return [Symbol, :input_tokens]
10
+ required :type, const: :input_tokens
11
+
12
+ # @!attribute value
13
+ #
14
+ # @return [Integer]
15
+ required :value, Integer
16
+
17
+ # @!method initialize(value:, type: :input_tokens)
18
+ # @param value [Integer]
19
+ # @param type [Symbol, :input_tokens]
20
+ end
21
+ end
22
+
23
+ BetaInputTokensTrigger = Beta::BetaInputTokensTrigger
24
+ end
25
+ end