anthropic 1.10.0 → 1.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a712fe41480aa96f93367ac509a0b8bc51e58939e1805b54dee7f9b4d78501d5
4
- data.tar.gz: 630a2cc4ebfb6bcecf08168c8dba0bd3d589c66a6931a96e11cd2cc12fe5e6f1
3
+ metadata.gz: 4749c4c57431c6592426ac4a7a7c5897c5f197accdc4974e52a3ee28c57bd44b
4
+ data.tar.gz: b8bf6c80d6b001ad703ff57684cee3eddbc45fdbb5afbcd74d1cabd3aa7b993c
5
5
  SHA512:
6
- metadata.gz: fa94a6b50849f5ef569dac4e21ea5b266505a6069714ab9b58d4c39d13c65cc50c8ce1753e475523740e954119bd980e1eb92909de08d0f33452ab1b72cb7a3b
7
- data.tar.gz: 0e577c3fb49d961d8ec9fe8f17d417d588a65545b905491329c378bd3e291e33d7c60abd08eeac3fa10e319c2df19f65f3f2771f8b916db172b790479dad514f
6
+ metadata.gz: a28ab8518fe39e5710cd7dc264c7a6e327b596095991a6818805bad0ba868bb37ca6f2a301310919a823084b1ebb34eafb87973f943818f808e2ad90556585d2
7
+ data.tar.gz: b7e39572bd1d841360ac7e28de3610c907526523fad8ccb7ea882e5a0945cad383ee7f47431707ff38e525649e82d516a39c9949b9e2393fe18562e13050faaa
data/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.10.1 (2025-10-06)
4
+
5
+ Full Changelog: [v1.10.0...v1.10.1](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.10.0...v1.10.1)
6
+
7
+ ### Bug Fixes
8
+
9
+ * always send `filename=...` for multipart requests where a file is expected ([0ffb017](https://github.com/anthropics/anthropic-sdk-ruby/commit/0ffb017c542b98891c6fcee76d7e3f3cb7ae5f26))
10
+ * bedrock signing issue with retried requests ([#719](https://github.com/anthropics/anthropic-sdk-ruby/issues/719)) ([69372ed](https://github.com/anthropics/anthropic-sdk-ruby/commit/69372edca8cca2529d04baafa58160890c7b95a4))
11
+ * coroutine leaks from connection pool ([7b9fb31](https://github.com/anthropics/anthropic-sdk-ruby/commit/7b9fb31c9d7d5407dee7203263001ba1050750b4))
12
+
13
+
14
+ ### Chores
15
+
16
+ * **client:** add context-management-2025-06-27 beta header ([067535d](https://github.com/anthropics/anthropic-sdk-ruby/commit/067535dbcc44cc244497faeca7943a435f09c49f))
17
+ * **client:** add model-context-window-exceeded-2025-08-26 beta header ([b12c86f](https://github.com/anthropics/anthropic-sdk-ruby/commit/b12c86f80f45b6dee023c2bfc14895bf93348105))
18
+
3
19
  ## 1.10.0 (2025-09-29)
4
20
 
5
21
  Full Changelog: [v1.9.0...v1.10.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.9.0...v1.10.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.10.0"
18
+ gem "anthropic", "~> 1.10.1"
19
19
  ```
20
20
 
21
21
  <!-- x-release-please-end -->
@@ -38,18 +38,21 @@ module Anthropic
38
38
  def to_yaml(*a) = read.to_yaml(*a)
39
39
 
40
40
  # @param content [Pathname, StringIO, IO, String]
41
- # @param filename [String, nil]
41
+ # @param filename [Pathname, String, nil]
42
42
  # @param content_type [String, nil]
43
43
  def initialize(content, filename: nil, content_type: nil)
44
- @content = content
44
+ @content_type = content_type
45
45
  @filename =
46
- case content
47
- in Pathname
48
- filename.nil? ? content.basename.to_path : ::File.basename(filename)
46
+ case [filename, (@content = content)]
47
+ in [String | Pathname, _]
48
+ ::File.basename(filename)
49
+ in [nil, Pathname]
50
+ content.basename.to_path
51
+ in [nil, IO]
52
+ content.to_path
49
53
  else
50
- filename.nil? ? nil : ::File.basename(filename)
54
+ filename
51
55
  end
52
- @content_type = content_type
53
56
  end
54
57
  end
55
58
  end
@@ -150,19 +150,10 @@ module Anthropic
150
150
  # @return [Hash{Symbol=>Object}]
151
151
  private def build_request(req, opts)
152
152
  fit_req_to_bedrock_specs!(req)
153
-
154
- request_input = super
155
-
156
- signed_request = @signer.sign_request(
157
- http_method: request_input[:method],
158
- url: request_input[:url],
159
- headers: request_input[:headers],
160
- body: request_input[:body]
161
- )
162
-
163
- request_input[:headers].merge!(signed_request.headers)
164
-
165
- request_input
153
+ req = super
154
+ body = req.fetch(:body)
155
+ req[:body] = StringIO.new(body.to_a.join) if body.is_a?(Enumerator)
156
+ req
166
157
  end
167
158
 
168
159
  # @api private
@@ -181,17 +172,10 @@ module Anthropic
181
172
  #
182
173
  # @return [Hash{Symbol, Object}]
183
174
  private def transform_request(request)
184
- sliced = super.slice(
185
- :method,
186
- :url,
187
- :headers,
188
- :body
189
- ).transform_keys(method: :http_method)
190
- body = StringIO.new(body.to_a.join) if (body = sliced.fetch(:body)).is_a?(Enumerator)
191
-
192
- signed = @signer.sign_request({**sliced, body: body})
193
-
194
- headers = Anthropic::Internal::Util.normalized_headers(request.fetch(:headers), signed.headers)
175
+ headers = request.fetch(:headers)
176
+ sliced = super.slice(:method, :url, :body).transform_keys(method: :http_method)
177
+ signed = @signer.sign_request({**sliced, headers: headers})
178
+ headers = Anthropic::Internal::Util.normalized_headers(headers, signed.headers)
195
179
  {**request, headers: headers}
196
180
  end
197
181
 
@@ -383,14 +383,14 @@ module Anthropic
383
383
  # @raise [Anthropic::Errors::APIError]
384
384
  # @return [Array(Integer, Net::HTTPResponse, Enumerable<String>)]
385
385
  def send_request(request, redirect_count:, retry_count:, send_retry_header:)
386
- request = transform_request(request)
387
- url, headers, max_retries, timeout = request.fetch_values(:url, :headers, :max_retries, :timeout)
388
- input = {**request.except(:timeout), deadline: Anthropic::Internal::Util.monotonic_secs + timeout}
389
-
390
386
  if send_retry_header
391
- headers["x-stainless-retry-count"] = retry_count.to_s
387
+ request.fetch(:headers)["x-stainless-retry-count"] = retry_count.to_s
392
388
  end
393
389
 
390
+ request = transform_request(request)
391
+ url, max_retries, timeout = request.fetch_values(:url, :max_retries, :timeout)
392
+ input = {**request.except(:timeout), deadline: Anthropic::Internal::Util.monotonic_secs + timeout}
393
+
394
394
  begin
395
395
  status, response, stream = @requester.execute(input)
396
396
  rescue Anthropic::Errors::APIConnectionError => e
@@ -134,9 +134,9 @@ module Anthropic
134
134
 
135
135
  # rubocop:disable Metrics/BlockLength
136
136
  enum = Enumerator.new do |y|
137
- with_pool(url, deadline: deadline) do |conn|
138
- next if finished
137
+ next if finished
139
138
 
139
+ with_pool(url, deadline: deadline) do |conn|
140
140
  req, closing = self.class.build_request(request) do
141
141
  self.class.calibrate_socket_timeout(conn, deadline)
142
142
  end
@@ -149,7 +149,7 @@ module Anthropic
149
149
 
150
150
  self.class.calibrate_socket_timeout(conn, deadline)
151
151
  conn.request(req) do |rsp|
152
- y << [conn, req, rsp]
152
+ y << [req, rsp]
153
153
  break if finished
154
154
 
155
155
  rsp.read_body do |bytes|
@@ -160,6 +160,8 @@ module Anthropic
160
160
  end
161
161
  eof = true
162
162
  end
163
+ ensure
164
+ conn.finish if !eof && conn&.started?
163
165
  end
164
166
  rescue Timeout::Error
165
167
  raise Anthropic::Errors::APITimeoutError.new(url: url, request: req)
@@ -168,16 +170,11 @@ module Anthropic
168
170
  end
169
171
  # rubocop:enable Metrics/BlockLength
170
172
 
171
- conn, _, response = enum.next
173
+ _, response = enum.next
172
174
  body = Anthropic::Internal::Util.fused_enum(enum, external: true) do
173
175
  finished = true
174
- tap do
175
- enum.next
176
- rescue StopIteration
177
- nil
178
- end
176
+ loop { enum.next }
179
177
  ensure
180
- conn.finish if !eof && conn&.started?
181
178
  closing&.call
182
179
  end
183
180
  [Integer(response.code), response, body]
@@ -13,21 +13,6 @@ module Anthropic
13
13
  module BaseStream
14
14
  include Enumerable
15
15
 
16
- class << self
17
- # Attempt to close the underlying transport when the stream itself is garbage
18
- # collected.
19
- #
20
- # This should not be relied upon for resource clean up, as the garbage collector
21
- # is not guaranteed to run.
22
- #
23
- # @param stream [Enumerable<Object>]
24
- #
25
- # @return [Proc]
26
- #
27
- # @see https://rubyapi.org/3.2/o/objectspace#method-c-define_finalizer
28
- def defer_closing(stream) = ->(_id) { Anthropic::Internal::Util.close_fused!(stream) }
29
- end
30
-
31
16
  # @return [Integer]
32
17
  attr_reader :status
33
18
 
@@ -82,8 +67,6 @@ module Anthropic
82
67
  @unwrap = unwrap
83
68
  @stream = stream
84
69
  @iterator = iterator
85
-
86
- ObjectSpace.define_finalizer(self, Anthropic::Internal::Type::BaseStream.defer_closing(@stream))
87
70
  end
88
71
 
89
72
  # @api private
@@ -82,17 +82,20 @@ module Anthropic
82
82
  #
83
83
  # @return [Pathname, StringIO, IO, String, Object]
84
84
  def dump(value, state:)
85
- # rubocop:disable Lint/DuplicateBranch
86
85
  case value
86
+ in StringIO | String
87
+ # https://datatracker.ietf.org/doc/html/rfc7578#section-4.2
88
+ # while not required, a filename is recommended, and in practice many servers do expect this
89
+ Anthropic::FilePart.new(value, filename: "upload")
87
90
  in IO
88
91
  state[:can_retry] = false
92
+ value.to_path.nil? ? Anthropic::FilePart.new(value, filename: "upload") : value
89
93
  in Anthropic::FilePart if value.content.is_a?(IO)
90
94
  state[:can_retry] = false
95
+ value
91
96
  else
97
+ value
92
98
  end
93
- # rubocop:enable Lint/DuplicateBranch
94
-
95
- value
96
99
  end
97
100
 
98
101
  # @api private
@@ -37,6 +37,10 @@ module Anthropic
37
37
 
38
38
  variant const: -> { Anthropic::Models::AnthropicBeta::CONTEXT_1M_2025_08_07 }
39
39
 
40
+ variant const: -> { Anthropic::Models::AnthropicBeta::CONTEXT_MANAGEMENT_2025_06_27 }
41
+
42
+ variant const: -> { Anthropic::Models::AnthropicBeta::MODEL_CONTEXT_WINDOW_EXCEEDED_2025_08_26 }
43
+
40
44
  # @!method self.variants
41
45
  # @return [Array(String, Symbol)]
42
46
 
@@ -61,6 +65,8 @@ module Anthropic
61
65
  CODE_EXECUTION_2025_05_22 = :"code-execution-2025-05-22"
62
66
  EXTENDED_CACHE_TTL_2025_04_11 = :"extended-cache-ttl-2025-04-11"
63
67
  CONTEXT_1M_2025_08_07 = :"context-1m-2025-08-07"
68
+ CONTEXT_MANAGEMENT_2025_06_27 = :"context-management-2025-06-27"
69
+ MODEL_CONTEXT_WINDOW_EXCEEDED_2025_08_26 = :"model-context-window-exceeded-2025-08-26"
64
70
 
65
71
  # @!endgroup
66
72
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Anthropic
4
- VERSION = "1.10.0"
4
+ VERSION = "1.10.1"
5
5
  end
@@ -27,7 +27,7 @@ module Anthropic
27
27
  sig do
28
28
  params(
29
29
  content: T.any(Pathname, StringIO, IO, String),
30
- filename: T.nilable(String),
30
+ filename: T.nilable(T.any(Pathname, String)),
31
31
  content_type: T.nilable(String)
32
32
  ).returns(T.attached_class)
33
33
  end
@@ -12,21 +12,6 @@ module Anthropic
12
12
  Message = type_member(:in)
13
13
  Elem = type_member(:out)
14
14
 
15
- class << self
16
- # Attempt to close the underlying transport when the stream itself is garbage
17
- # collected.
18
- #
19
- # This should not be relied upon for resource clean up, as the garbage collector
20
- # is not guaranteed to run.
21
- sig do
22
- params(stream: T::Enumerable[T.anything]).returns(
23
- T.proc.params(arg0: Integer).void
24
- )
25
- end
26
- def defer_closing(stream)
27
- end
28
- end
29
-
30
15
  sig { returns(Integer) }
31
16
  attr_reader :status
32
17
 
@@ -75,6 +75,16 @@ module Anthropic
75
75
  )
76
76
  CONTEXT_1M_2025_08_07 =
77
77
  T.let(:"context-1m-2025-08-07", Anthropic::AnthropicBeta::TaggedSymbol)
78
+ CONTEXT_MANAGEMENT_2025_06_27 =
79
+ T.let(
80
+ :"context-management-2025-06-27",
81
+ Anthropic::AnthropicBeta::TaggedSymbol
82
+ )
83
+ MODEL_CONTEXT_WINDOW_EXCEEDED_2025_08_26 =
84
+ T.let(
85
+ :"model-context-window-exceeded-2025-08-26",
86
+ Anthropic::AnthropicBeta::TaggedSymbol
87
+ )
78
88
  end
79
89
  end
80
90
  end
@@ -14,7 +14,7 @@ module Anthropic
14
14
 
15
15
  def initialize: (
16
16
  Pathname | StringIO | IO | String content,
17
- ?filename: String?,
17
+ ?filename: (Pathname | String)?,
18
18
  ?content_type: String?
19
19
  ) -> void
20
20
  end
@@ -4,10 +4,6 @@ module Anthropic
4
4
  module BaseStream[Message, Elem]
5
5
  include Enumerable[Elem]
6
6
 
7
- def self.defer_closing: (
8
- Enumerable[top] stream
9
- ) -> (^(Integer arg0) -> void)
10
-
11
7
  attr_reader status: Integer
12
8
 
13
9
  attr_reader headers: ::Hash[String, String]
@@ -17,6 +17,8 @@ module Anthropic
17
17
  | :"code-execution-2025-05-22"
18
18
  | :"extended-cache-ttl-2025-04-11"
19
19
  | :"context-1m-2025-08-07"
20
+ | :"context-management-2025-06-27"
21
+ | :"model-context-window-exceeded-2025-08-26"
20
22
 
21
23
  module AnthropicBeta
22
24
  extend Anthropic::Internal::Type::Union
@@ -38,6 +40,8 @@ module Anthropic
38
40
  CODE_EXECUTION_2025_05_22: :"code-execution-2025-05-22"
39
41
  EXTENDED_CACHE_TTL_2025_04_11: :"extended-cache-ttl-2025-04-11"
40
42
  CONTEXT_1M_2025_08_07: :"context-1m-2025-08-07"
43
+ CONTEXT_MANAGEMENT_2025_06_27: :"context-management-2025-06-27"
44
+ MODEL_CONTEXT_WINDOW_EXCEEDED_2025_08_26: :"model-context-window-exceeded-2025-08-26"
41
45
  end
42
46
  end
43
47
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: anthropic
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.10.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anthropic
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-09-29 00:00:00.000000000 Z
11
+ date: 2025-10-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: connection_pool