anthropic 1.58.0 → 1.59.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 (72) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/README.md +1 -1
  4. data/lib/anthropic/helpers/messages.rb +12 -3
  5. data/lib/anthropic/helpers/refusal_fallback.rb +85 -14
  6. data/lib/anthropic/helpers/streaming/message_stream.rb +7 -2
  7. data/lib/anthropic/helpers/tools/runner.rb +98 -1
  8. data/lib/anthropic/internal/type/converter.rb +2 -0
  9. data/lib/anthropic/models/anthropic_beta.rb +6 -0
  10. data/lib/anthropic/models/beta/beta_content_block_param.rb +15 -1
  11. data/lib/anthropic/models/beta/beta_fallback_credit_not_applied.rb +75 -0
  12. data/lib/anthropic/models/beta/beta_fallback_credit_redeemed.rb +22 -0
  13. data/lib/anthropic/models/beta/beta_fallback_credit_token_param.rb +64 -0
  14. data/lib/anthropic/models/beta/beta_fallback_credit_usage.rb +54 -0
  15. data/lib/anthropic/models/beta/beta_fallbacks_param.rb +27 -0
  16. data/lib/anthropic/models/beta/beta_managed_agents_model.rb +10 -5
  17. data/lib/anthropic/models/beta/beta_message_delta_usage.rb +9 -1
  18. data/lib/anthropic/models/beta/beta_message_param.rb +3 -3
  19. data/lib/anthropic/models/beta/beta_mid_conversation_system_block_param.rb +33 -3
  20. data/lib/anthropic/models/beta/beta_request_tool_addition_block.rb +72 -0
  21. data/lib/anthropic/models/beta/beta_request_tool_removal_block.rb +72 -0
  22. data/lib/anthropic/models/beta/beta_tool_change_mcp_tool_reference.rb +34 -0
  23. data/lib/anthropic/models/beta/beta_tool_change_mcp_toolset_reference.rb +27 -0
  24. data/lib/anthropic/models/beta/beta_tool_change_tool_reference.rb +29 -0
  25. data/lib/anthropic/models/beta/beta_usage.rb +9 -1
  26. data/lib/anthropic/models/beta/message_create_params.rb +47 -9
  27. data/lib/anthropic/models/beta/messages/batch_create_params.rb +51 -9
  28. data/lib/anthropic/models/model.rb +12 -7
  29. data/lib/anthropic/resources/beta/messages.rb +4 -4
  30. data/lib/anthropic/version.rb +1 -1
  31. data/lib/anthropic.rb +10 -0
  32. data/rbi/anthropic/models/anthropic_beta.rbi +10 -0
  33. data/rbi/anthropic/models/beta/beta_content_block_param.rbi +2 -0
  34. data/rbi/anthropic/models/beta/beta_fallback_credit_not_applied.rbi +171 -0
  35. data/rbi/anthropic/models/beta/beta_fallback_credit_redeemed.rbi +32 -0
  36. data/rbi/anthropic/models/beta/beta_fallback_credit_token_param.rbi +124 -0
  37. data/rbi/anthropic/models/beta/beta_fallback_credit_usage.rbi +89 -0
  38. data/rbi/anthropic/models/beta/beta_fallbacks_param.rbi +38 -0
  39. data/rbi/anthropic/models/beta/beta_managed_agents_model.rbi +12 -5
  40. data/rbi/anthropic/models/beta/beta_message_delta_usage.rbi +18 -0
  41. data/rbi/anthropic/models/beta/beta_mid_conversation_system_block_param.rbi +54 -3
  42. data/rbi/anthropic/models/beta/beta_request_tool_addition_block.rbi +120 -0
  43. data/rbi/anthropic/models/beta/beta_request_tool_removal_block.rbi +120 -0
  44. data/rbi/anthropic/models/beta/beta_tool_change_mcp_tool_reference.rbi +44 -0
  45. data/rbi/anthropic/models/beta/beta_tool_change_mcp_toolset_reference.rbi +36 -0
  46. data/rbi/anthropic/models/beta/beta_tool_change_tool_reference.rbi +36 -0
  47. data/rbi/anthropic/models/beta/beta_usage.rbi +18 -0
  48. data/rbi/anthropic/models/beta/message_create_params.rbi +76 -8
  49. data/rbi/anthropic/models/beta/messages/batch_create_params.rbi +78 -8
  50. data/rbi/anthropic/models/model.rbi +10 -7
  51. data/rbi/anthropic/resources/beta/messages.rbi +30 -6
  52. data/sig/anthropic/models/anthropic_beta.rbs +4 -0
  53. data/sig/anthropic/models/beta/beta_content_block_param.rbs +2 -0
  54. data/sig/anthropic/models/beta/beta_fallback_credit_not_applied.rbs +67 -0
  55. data/sig/anthropic/models/beta/beta_fallback_credit_redeemed.rbs +17 -0
  56. data/sig/anthropic/models/beta/beta_fallback_credit_token_param.rbs +44 -0
  57. data/sig/anthropic/models/beta/beta_fallback_credit_usage.rbs +32 -0
  58. data/sig/anthropic/models/beta/beta_fallbacks_param.rbs +18 -0
  59. data/sig/anthropic/models/beta/beta_managed_agents_model.rbs +9 -5
  60. data/sig/anthropic/models/beta/beta_message_delta_usage.rbs +5 -0
  61. data/sig/anthropic/models/beta/beta_mid_conversation_system_block_param.rbs +15 -4
  62. data/sig/anthropic/models/beta/beta_request_tool_addition_block.rbs +45 -0
  63. data/sig/anthropic/models/beta/beta_request_tool_removal_block.rbs +45 -0
  64. data/sig/anthropic/models/beta/beta_tool_change_mcp_tool_reference.rbs +30 -0
  65. data/sig/anthropic/models/beta/beta_tool_change_mcp_toolset_reference.rbs +23 -0
  66. data/sig/anthropic/models/beta/beta_tool_change_tool_reference.rbs +20 -0
  67. data/sig/anthropic/models/beta/beta_usage.rbs +5 -0
  68. data/sig/anthropic/models/beta/message_create_params.rbs +17 -8
  69. data/sig/anthropic/models/beta/messages/batch_create_params.rbs +17 -8
  70. data/sig/anthropic/models/model.rbs +11 -7
  71. data/sig/anthropic/resources/beta/messages.rbs +4 -4
  72. metadata +32 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 48ab35bd8cf4f04042fe7c27121f1735ac8cad21809ced2a9dd9cafd220e5f6c
4
- data.tar.gz: e1fe6ba52bb7ebf74ca4c76c7aaec7a485ee44b9453f7978a44fe1bee8dc188d
3
+ metadata.gz: a5c7920c024b325266d16d26526490511c33ee3de9136b7a0314a6d7c28f8c0a
4
+ data.tar.gz: 21354f0f03146858812a863149f1c02b7f961cdbd3d7726b166530d628d340eb
5
5
  SHA512:
6
- metadata.gz: c7f72255a73f80441ee63badd6b98f72f6607b8a56e3c3fdfb6d33fa65938d8917702988b22c707c190952458087e2e24710b8b6f7867eb68c045357fd6aaf9e
7
- data.tar.gz: 6d7b44b71542c194de65cdffdd164ad1e4d25d4caf668b3f0b0f90977ae8bdeb7a1bae803dbaf698aeb1ac583c723de2ae1a0a517e8214a659e9535bc9b4eea1
6
+ metadata.gz: be751a0e2ddaf99238b87eefb9d67fb7479542f624d42490dc009eb1b1fcdd92159bea36526d41ab07d26687ab943911b94e27941b809f6322478ffaaa0baff2
7
+ data.tar.gz: da3afb6cf93ae7f9a4ab4fe2bca496f80eca4222ab80638677bca0eebd6cc9c0e556f980d2214a112aec585349193b8fcf73dde751b8a087c0da56a65647fd7f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.59.0 (2026-07-24)
4
+
5
+ Full Changelog: [v1.58.0...v1.59.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.58.0...v1.59.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** add claude-opus-5 model ([56d4632](https://github.com/anthropics/anthropic-sdk-ruby/commit/56d46324125672b08af378289727211500c73ae0))
10
+ * **api:** add tool addition/removal blocks and tool_change events ([56d4632](https://github.com/anthropics/anthropic-sdk-ruby/commit/56d46324125672b08af378289727211500c73ae0))
11
+ * **api:** expand client-side fallback credit token types and add server-side fallbacks default option ([56d4632](https://github.com/anthropics/anthropic-sdk-ruby/commit/56d46324125672b08af378289727211500c73ae0))
12
+
13
+
14
+ ### Chores
15
+
16
+ * **internal:** codegen related update ([4db7e95](https://github.com/anthropics/anthropic-sdk-ruby/commit/4db7e9578d2919891461cfca07303789a966d4d8))
17
+
3
18
  ## 1.58.0 (2026-07-23)
4
19
 
5
20
  Full Changelog: [v1.57.0...v1.58.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.57.0...v1.58.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.58.0"
18
+ gem "anthropic", "~> 1.59.0"
19
19
  ```
20
20
 
21
21
  <!-- x-release-please-end -->
@@ -40,7 +40,7 @@ module Anthropic
40
40
  case tool
41
41
  # BaseTool whose class declares an explicit `tool_name` (e.g. MCP-built tools):
42
42
  in Anthropic::Helpers::Tools::BaseTool if tool.class.tool_name
43
- name = tool.class.tool_name
43
+ name = tool_api_name(tool)
44
44
  description = tool.class.doc_string
45
45
  tools.store(name, tool)
46
46
  input_schema = Anthropic::Helpers::InputSchema::JsonSchemaConverter.to_json_schema(tool)
@@ -51,8 +51,8 @@ module Anthropic
51
51
  result
52
52
  # Direct tool class:
53
53
  in Anthropic::Helpers::InputSchema::JsonSchemaConverter
54
- classname = tool.is_a?(Anthropic::Helpers::Tools::BaseTool) ? tool.class.name : tool.name
55
- name = model_name(classname)
54
+ name =
55
+ tool.is_a?(Anthropic::Helpers::Tools::BaseTool) ? tool_api_name(tool) : model_name(tool.name)
56
56
 
57
57
  description =
58
58
  case tool
@@ -206,6 +206,15 @@ module Anthropic
206
206
  data[:betas] = data[:betas].to_a.dup.push("structured-outputs-2025-12-15").uniq
207
207
  end
208
208
 
209
+ # @api private
210
+ #
211
+ # The `name` a runnable tool is serialized under in `tools[]`.
212
+ #
213
+ # @param tool [Anthropic::Helpers::Tools::BaseTool]
214
+ #
215
+ # @return [String]
216
+ def tool_api_name(tool) = tool.class.tool_name || model_name(tool.class.name)
217
+
209
218
  # @api private
210
219
  #
211
220
  # @param classname [String]
@@ -22,9 +22,11 @@ module Anthropic
22
22
  # chain.
23
23
  #
24
24
  # Non-streaming: when a response comes back with `stop_reason: "refusal"`,
25
- # the request is retried with each entry of `fallbacks` merged over the
26
- # original params passing along the refusal's `fallback_credit_token`
27
- # until a model accepts or the chain is exhausted. A message served by a
25
+ # the request is retried with each entry of `fallbacks` applied as a patch
26
+ # against the original params (a set field overrides, an explicit `nil`
27
+ # unsets, an absent field keeps the original value) passing along the
28
+ # refusal's `fallback_credit_token` — until a model accepts or the chain is
29
+ # exhausted. A message served by a
28
30
  # fallback carries a `fallback` content block prepended at each model
29
31
  # boundary; an exhausted chain surfaces the final refusal verbatim.
30
32
  #
@@ -39,8 +41,11 @@ module Anthropic
39
41
  # path: the credit token is redeemable only against the refused request's
40
42
  # body, so the other per-entry overrides would be rejected.
41
43
  #
42
- # The fallback-credit beta the credit tokens require is sent by default on
43
- # every request the middleware handles; the `betas:` option controls this.
44
+ # Credit tokens are sent in the object form with `mode: :best_effort`, so a
45
+ # failing redemption never rejects the retry it proceeds at normal price
46
+ # and the outcome is reported on `usage.fallback_credit`. The fallback-credit
47
+ # beta this requires is sent by default on every request the middleware
48
+ # handles; the `betas:` option controls this.
44
49
  #
45
50
  # To keep later requests on the model that accepted, pass a
46
51
  # {BetaFallbackState} via the `fallback_state` request option; requests
@@ -57,17 +62,25 @@ module Anthropic
57
62
  include Anthropic::Middleware
58
63
 
59
64
  # Betas sent by default; override with the `betas:` option.
60
- DEFAULT_BETAS = ["fallback-credit-2026-06-01"].freeze
65
+ DEFAULT_BETAS = ["fallback-credit-2026-07-01"].freeze
61
66
 
62
67
  # @param fallbacks [Array<Hash, Anthropic::Models::Beta::BetaFallbackParam>]
63
68
  # the fallback chain, tried in order. Each entry must carry `model:`; on
64
69
  # the non-streaming path the remaining keys (`max_tokens:`, `thinking:`,
65
- # …) are merged over the original request body for that hop.
70
+ # …) patch the original request body for that hop — a value overrides
71
+ # the param, an explicit `nil` unsets it, an absent key keeps the
72
+ # original value.
66
73
  # @param betas [Array<String>] betas added to the `anthropic-beta` header
67
74
  # of every `/v1/messages` request this middleware handles. Defaults to
68
- # `["fallback-credit-2026-06-01"]`; pass `[]` to send none.
75
+ # `["fallback-credit-2026-07-01"]`; pass `[]` to send none.
69
76
  def initialize(fallbacks, betas: DEFAULT_BETAS)
70
- @fallbacks = fallbacks.map { _1.respond_to?(:to_h) ? _1.to_h : _1 }.freeze
77
+ # Entry keys are symbolized because they patch the symbol-keyed request
78
+ # body; a String key would never match, so its override/unset would
79
+ # silently miss.
80
+ @fallbacks = fallbacks.map do |entry|
81
+ entry = entry.to_h if entry.respond_to?(:to_h)
82
+ entry.is_a?(Hash) ? entry.transform_keys(&:to_sym) : entry
83
+ end.freeze
71
84
  @betas = betas.freeze
72
85
  @warned_missing_state = false
73
86
  end
@@ -82,7 +95,7 @@ module Anthropic
82
95
  raise Anthropic::Errors::Error,
83
96
  "Sending the `fallbacks:` request param is not supported when using " \
84
97
  "`BetaRefusalFallbackMiddleware`. Either remove the middleware and send " \
85
- "`fallbacks:` with the `server-side-fallback-2026-06-01` beta header to " \
98
+ "`fallbacks:` with the `server-side-fallback-2026-07-01` beta header to " \
86
99
  "let the API handle refusal fallbacks, or omit `fallbacks:` to let the " \
87
100
  "middleware handle them on the client side."
88
101
  end
@@ -122,7 +135,7 @@ module Anthropic
122
135
  # for the spliced hops.
123
136
  body.merge(model: @fallbacks.fetch(start_index).fetch(:model))
124
137
  else
125
- body.merge(@fallbacks.fetch(start_index))
138
+ apply_fallback(body, @fallbacks.fetch(start_index))
126
139
  end
127
140
  res = nxt.call(req.with(body: initial_body))
128
141
  return res unless res.status < 300
@@ -138,6 +151,54 @@ module Anthropic
138
151
 
139
152
  private
140
153
 
154
+ # Apply one fallback entry as a patch against the original request body:
155
+ # a key set to a value overrides that param, a key explicitly set to `nil`
156
+ # unsets it (the hop request omits the key rather than sending `null`),
157
+ # and an absent key leaves the original value. `output_config` patches
158
+ # one level deep — its subfields override/unset/keep individually against
159
+ # the original `output_config`. Entries always patch the original body,
160
+ # never an earlier hop's patched body, so overrides can't compound across
161
+ # hops.
162
+ #
163
+ # @param body [Hash{Symbol=>Object}]
164
+ # @param entry [Hash{Symbol=>Object}]
165
+ # @return [Hash{Symbol=>Object}]
166
+ def apply_fallback(body, entry)
167
+ patched = patch(body, entry)
168
+ override = entry[:output_config]
169
+ return patched if override.nil?
170
+
171
+ merged = patch(hash_of(body[:output_config]), hash_of(override))
172
+ merged.empty? ? patched.except(:output_config) : patched.merge(output_config: merged)
173
+ end
174
+
175
+ # @param base [Hash{Symbol=>Object}]
176
+ # @param overrides [Hash{Symbol=>Object}] a value sets the key, an
177
+ # explicit `nil` deletes it, an absent key keeps `base`'s value
178
+ # @return [Hash{Symbol=>Object}]
179
+ def patch(base, overrides)
180
+ overrides.each_with_object(base.dup) do |(key, value), out|
181
+ value.nil? ? out.delete(key) : out[key] = value
182
+ end
183
+ end
184
+
185
+ # Normalize a nested config to a symbol-keyed hash of API field names,
186
+ # preserving keys that were explicitly set to `nil`. A typed model is
187
+ # dumped (raw `to_h` uses internal names, e.g. `format_` for `format`).
188
+ #
189
+ # @param value [Hash, Anthropic::Internal::Type::BaseModel, nil]
190
+ # @return [Hash{Symbol=>Object}]
191
+ def hash_of(value)
192
+ case value
193
+ when Anthropic::Internal::Type::BaseModel
194
+ Anthropic::Internal::Type::Converter.dump(value.class, value)
195
+ when Hash
196
+ value.transform_keys(&:to_sym)
197
+ else
198
+ {}
199
+ end
200
+ end
201
+
141
202
  # @return [Boolean] whether `req` is a `client.beta.messages` create call
142
203
  # with a `Hash` body and a non-empty fallback chain.
143
204
  def applies?(req)
@@ -189,6 +250,16 @@ module Anthropic
189
250
  body.merge(messages: messages)
190
251
  end
191
252
 
253
+ # The object form of `fallback_credit_token` with `best_effort` redemption:
254
+ # a token-layer failure serves the retry at normal price instead of
255
+ # rejecting it, so a stale or already-spent credit can't fail the fallback.
256
+ #
257
+ # @param token [String]
258
+ # @return [Hash{Symbol=>Object}] shape of {Anthropic::Models::Beta::BetaFallbackCreditTokenParam}
259
+ def credit_token_param(token)
260
+ {token: token, mode: Anthropic::Models::Beta::BetaFallbackCreditTokenParam::Mode::BEST_EFFORT}
261
+ end
262
+
192
263
  # --- non-streaming ------------------------------------------------------
193
264
 
194
265
  # @param req [Anthropic::APIRequest]
@@ -212,8 +283,8 @@ module Anthropic
212
283
 
213
284
  index += 1
214
285
  entry = @fallbacks.fetch(index)
215
- hop_body = body.merge(entry)
216
- hop_body = hop_body.merge(fallback_credit_token: token) if token
286
+ hop_body = apply_fallback(body, entry)
287
+ hop_body = hop_body.merge(fallback_credit_token: credit_token_param(token)) if token
217
288
 
218
289
  begin
219
290
  hop_res = nxt.call(req.with(body: hop_body))
@@ -381,7 +452,7 @@ module Anthropic
381
452
  def issue_hop(req, nxt, body, model, token, base, partial)
382
453
  continuation = base + partial
383
454
  2.times do |attempt|
384
- hop_body = body.merge(model: model, fallback_credit_token: token)
455
+ hop_body = body.merge(model: model, fallback_credit_token: credit_token_param(token))
385
456
  unless continuation.empty?
386
457
  hop_body = hop_body.merge(
387
458
  messages: body.fetch(:messages) + [{role: :assistant, content: continuation}]
@@ -177,8 +177,13 @@ module Anthropic
177
177
  current_snapshot.usage.server_tool_use = event.usage.server_tool_use
178
178
  end
179
179
 
180
- if event.is_a?(Anthropic::Models::BetaRawMessageDeltaEvent) && !event.usage.iterations.nil?
181
- current_snapshot.usage.iterations = event.usage.iterations
180
+ if event.is_a?(Anthropic::Models::BetaRawMessageDeltaEvent)
181
+ unless event.usage.iterations.nil?
182
+ current_snapshot.usage.iterations = event.usage.iterations
183
+ end
184
+ unless event.usage.fallback_credit.nil?
185
+ current_snapshot.usage.fallback_credit = event.usage.fallback_credit
186
+ end
182
187
  end
183
188
  else
184
189
  end
@@ -92,6 +92,11 @@ module Anthropic
92
92
  next unless current_messages.equal?(messages)
93
93
  break if compacted
94
94
 
95
+ # A `tool_removal` block only hints the model, so a call to a withdrawn tool can still
96
+ # arrive; a name missing from this set routes down the same "not found" path as an
97
+ # undeclared tool.
98
+ available = available_tool_names(tools, messages)
99
+
95
100
  mapped =
96
101
  response
97
102
  .content
@@ -99,7 +104,8 @@ module Anthropic
99
104
  .grep(Anthropic::Beta::BetaToolUseBlock)
100
105
  .map do |tool_use|
101
106
  resp = {type: :tool_result, tool_use_id: tool_use.id}
102
- if (tool = tools.find { _1.class.model === tool_use.parsed })
107
+ if available.include?(tool_use.name) &&
108
+ (tool = tools.find { _1.class.model === tool_use.parsed })
103
109
  begin
104
110
  raw = tool.call(tool_use.parsed)
105
111
  is_error = false
@@ -142,6 +148,97 @@ module Anthropic
142
148
  # rubocop:enable Metrics/BlockLength
143
149
  end
144
150
 
151
+ # @api private
152
+ #
153
+ # Replays `tool_removal` / `tool_addition` blocks from `role: :system` messages to
154
+ # find which tool names are still offered to the model. MCP references are
155
+ # server-executed and never dispatched here, so they are ignored.
156
+ #
157
+ # @param tools [Array<Anthropic::Helpers::Tools::BaseTool>]
158
+ #
159
+ # @param messages [Array<Anthropic::Beta::BetaMessageParam, Hash{Symbol=>Object}>]
160
+ #
161
+ # @return [Set<String>]
162
+ private def available_tool_names(tools, messages)
163
+ available = Set.new(tools.map { Anthropic::Helpers::Messages.tool_api_name(_1) })
164
+ messages.each do |message|
165
+ next unless read_field(message, :role)&.to_sym == :system
166
+
167
+ Array(read_field(message, :content)).each { apply_tool_change(_1, available) }
168
+ end
169
+ available
170
+ end
171
+
172
+ # @api private
173
+ #
174
+ # @param block [Anthropic::Beta::BetaContentBlockParam, Hash{Symbol=>Object}]
175
+ #
176
+ # @param available [Set<String>]
177
+ private def apply_tool_change(block, available)
178
+ case read_field(block, :type)&.to_sym
179
+ in :tool_removal | :tool_addition
180
+ apply_tool_delta(block, available)
181
+ in :mid_conv_system
182
+ # `mid_conv_system` content is limited by the API schema to text / tool_addition /
183
+ # tool_removal blocks, so exactly one level is walked; anything else inside is a no-op.
184
+ Array(read_field(block, :content)).each { apply_tool_delta(_1, available) }
185
+ else
186
+ nil # other and unknown block types leave the set untouched (forward compatibility)
187
+ end
188
+ end
189
+
190
+ # @api private
191
+ #
192
+ # @param block [Anthropic::Beta::BetaContentBlockParam, Hash{Symbol=>Object}]
193
+ #
194
+ # @param available [Set<String>]
195
+ private def apply_tool_delta(block, available)
196
+ case read_field(block, :type)&.to_sym
197
+ in :tool_removal
198
+ name = referenced_tool_name(read_field(block, :tool))
199
+ available.delete(name) unless name.nil?
200
+ in :tool_addition
201
+ name = referenced_tool_name(read_field(block, :tool))
202
+ available.add(name) unless name.nil?
203
+ else
204
+ nil # non tool_removal / tool_addition blocks leave the set untouched
205
+ end
206
+ end
207
+
208
+ # @api private
209
+ #
210
+ # @param ref [Anthropic::Beta::BetaToolChangeToolReference, Hash{Symbol=>Object}, nil]
211
+ #
212
+ # @return [String, nil]
213
+ private def referenced_tool_name(ref)
214
+ case read_field(ref, :type)&.to_sym
215
+ in :tool_reference
216
+ read_field(ref, :name).to_s
217
+ else
218
+ nil # `mcp_*` references run server-side; unknown types ignored (forward compatibility)
219
+ end
220
+ end
221
+
222
+ # @api private
223
+ #
224
+ # Reads a field off either a plain hash (symbol or string keys) or a typed model.
225
+ #
226
+ # @param obj [Object]
227
+ #
228
+ # @param key [Symbol]
229
+ #
230
+ # @return [Object, nil]
231
+ private def read_field(obj, key)
232
+ case obj
233
+ in Hash
234
+ obj.fetch(key) { obj[key.to_s] }
235
+ in Anthropic::Internal::Type::BaseModel
236
+ obj.public_send(key) if obj.respond_to?(key)
237
+ else
238
+ nil
239
+ end
240
+ end
241
+
145
242
  # Check token usage and compact messages if threshold exceeded
146
243
  #
147
244
  # @return [Boolean] true if compaction occurred, false otherwise
@@ -53,6 +53,8 @@ module Anthropic
53
53
  in Anthropic::FilePart
54
54
  state[:can_retry] = false if value.content.is_a?(IO)
55
55
  value
56
+ in Time
57
+ value.iso8601
56
58
  else
57
59
  value
58
60
  end
@@ -63,8 +63,12 @@ module Anthropic
63
63
 
64
64
  variant const: -> { Anthropic::Models::AnthropicBeta::SERVER_SIDE_FALLBACK_2026_06_01 }
65
65
 
66
+ variant const: -> { Anthropic::Models::AnthropicBeta::SERVER_SIDE_FALLBACK_2026_07_01 }
67
+
66
68
  variant const: -> { Anthropic::Models::AnthropicBeta::FALLBACK_CREDIT_2026_06_01 }
67
69
 
70
+ variant const: -> { Anthropic::Models::AnthropicBeta::FALLBACK_CREDIT_2026_07_01 }
71
+
68
72
  variant const: -> { Anthropic::Models::AnthropicBeta::AGENT_MEMORY_2026_07_22 }
69
73
 
70
74
  # @!method self.variants
@@ -104,7 +108,9 @@ module Anthropic
104
108
  DREAMING_2026_04_21 = :"dreaming-2026-04-21"
105
109
  THINKING_TOKEN_COUNT_2026_05_13 = :"thinking-token-count-2026-05-13"
106
110
  SERVER_SIDE_FALLBACK_2026_06_01 = :"server-side-fallback-2026-06-01"
111
+ SERVER_SIDE_FALLBACK_2026_07_01 = :"server-side-fallback-2026-07-01"
107
112
  FALLBACK_CREDIT_2026_06_01 = :"fallback-credit-2026-06-01"
113
+ FALLBACK_CREDIT_2026_07_01 = :"fallback-credit-2026-07-01"
108
114
  AGENT_MEMORY_2026_07_22 = :"agent-memory-2026-07-22"
109
115
 
110
116
  # @!endgroup
@@ -74,6 +74,20 @@ module Anthropic
74
74
  # point in the conversation, rather than only via the top-level `system` parameter.
75
75
  variant :mid_conv_system, -> { Anthropic::Beta::BetaMidConversationSystemBlockParam }
76
76
 
77
+ # Mid-conversation directive to surface a declared tool.
78
+ #
79
+ # ``tool`` references a tool (or MCP toolset) by name from the request's
80
+ # ``tools``; it is offered to the model from this point in the
81
+ # conversation onward.
82
+ variant :tool_addition, -> { Anthropic::Beta::BetaRequestToolAdditionBlock }
83
+
84
+ # Mid-conversation directive to withdraw a tool.
85
+ #
86
+ # ``tool`` references a tool (or MCP toolset) by name from the request's
87
+ # ``tools``; it is no longer offered to the model from this point in the
88
+ # conversation onward.
89
+ variant :tool_removal, -> { Anthropic::Beta::BetaRequestToolRemovalBlock }
90
+
77
91
  # A `fallback` block echoed back from a prior response.
78
92
  #
79
93
  # Accepted in `messages[].content` and not rendered into the prompt; not
@@ -90,7 +104,7 @@ module Anthropic
90
104
  variant :fallback, -> { Anthropic::Beta::BetaFallbackBlockParam }
91
105
 
92
106
  # @!method self.variants
93
- # @return [Array(Anthropic::Models::Beta::BetaTextBlockParam, Anthropic::Models::Beta::BetaImageBlockParam, Anthropic::Models::Beta::BetaRequestDocumentBlock, Anthropic::Models::Beta::BetaSearchResultBlockParam, Anthropic::Models::Beta::BetaThinkingBlockParam, Anthropic::Models::Beta::BetaRedactedThinkingBlockParam, Anthropic::Models::Beta::BetaToolUseBlockParam, Anthropic::Models::Beta::BetaToolResultBlockParam, Anthropic::Models::Beta::BetaServerToolUseBlockParam, Anthropic::Models::Beta::BetaWebSearchToolResultBlockParam, Anthropic::Models::Beta::BetaWebFetchToolResultBlockParam, Anthropic::Models::Beta::BetaAdvisorToolResultBlockParam, Anthropic::Models::Beta::BetaCodeExecutionToolResultBlockParam, Anthropic::Models::Beta::BetaBashCodeExecutionToolResultBlockParam, Anthropic::Models::Beta::BetaTextEditorCodeExecutionToolResultBlockParam, Anthropic::Models::Beta::BetaToolSearchToolResultBlockParam, Anthropic::Models::Beta::BetaMCPToolUseBlockParam, Anthropic::Models::Beta::BetaRequestMCPToolResultBlockParam, Anthropic::Models::Beta::BetaContainerUploadBlockParam, Anthropic::Models::Beta::BetaCompactionBlockParam, Anthropic::Models::Beta::BetaMidConversationSystemBlockParam, Anthropic::Models::Beta::BetaFallbackBlockParam)]
107
+ # @return [Array(Anthropic::Models::Beta::BetaTextBlockParam, Anthropic::Models::Beta::BetaImageBlockParam, Anthropic::Models::Beta::BetaRequestDocumentBlock, Anthropic::Models::Beta::BetaSearchResultBlockParam, Anthropic::Models::Beta::BetaThinkingBlockParam, Anthropic::Models::Beta::BetaRedactedThinkingBlockParam, Anthropic::Models::Beta::BetaToolUseBlockParam, Anthropic::Models::Beta::BetaToolResultBlockParam, Anthropic::Models::Beta::BetaServerToolUseBlockParam, Anthropic::Models::Beta::BetaWebSearchToolResultBlockParam, Anthropic::Models::Beta::BetaWebFetchToolResultBlockParam, Anthropic::Models::Beta::BetaAdvisorToolResultBlockParam, Anthropic::Models::Beta::BetaCodeExecutionToolResultBlockParam, Anthropic::Models::Beta::BetaBashCodeExecutionToolResultBlockParam, Anthropic::Models::Beta::BetaTextEditorCodeExecutionToolResultBlockParam, Anthropic::Models::Beta::BetaToolSearchToolResultBlockParam, Anthropic::Models::Beta::BetaMCPToolUseBlockParam, Anthropic::Models::Beta::BetaRequestMCPToolResultBlockParam, Anthropic::Models::Beta::BetaContainerUploadBlockParam, Anthropic::Models::Beta::BetaCompactionBlockParam, Anthropic::Models::Beta::BetaMidConversationSystemBlockParam, Anthropic::Models::Beta::BetaRequestToolAdditionBlock, Anthropic::Models::Beta::BetaRequestToolRemovalBlock, Anthropic::Models::Beta::BetaFallbackBlockParam)]
94
108
  end
95
109
  end
96
110
 
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaFallbackCreditNotApplied < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute reason
8
+ # Why the reprice was not applied.
9
+ #
10
+ # A closed enum; additions to the redemption-check vocabulary arrive as deliberate
11
+ # schema updates.
12
+ #
13
+ # @return [Symbol, Anthropic::Models::Beta::BetaFallbackCreditNotApplied::Reason]
14
+ required :reason, enum: -> { Anthropic::Beta::BetaFallbackCreditNotApplied::Reason }
15
+
16
+ # @!attribute type
17
+ #
18
+ # @return [Symbol, :not_applied]
19
+ required :type, const: :not_applied
20
+
21
+ # @!attribute remove_to_redeem
22
+ # Request fields to remove before retrying, so the retry can redeem this token.
23
+ #
24
+ # Present exactly when `reason` is `variant_fields_present` — never null, never an
25
+ # empty array; absent otherwise. Fields are named only from your own request, and
26
+ # only after the sealed variant hash matched. A served best-effort retry has
27
+ # already been billed at normal price; nothing redeems retroactively, but a
28
+ # corrected re-send inside the token's five-minute window can still redeem.
29
+ #
30
+ # @return [Array<String>, nil]
31
+ optional :remove_to_redeem, Anthropic::Internal::Type::ArrayOf[String], nil?: true
32
+
33
+ # @!method initialize(reason:, remove_to_redeem: nil, type: :not_applied)
34
+ # Some parameter documentations has been truncated, see
35
+ # {Anthropic::Models::Beta::BetaFallbackCreditNotApplied} for more details.
36
+ #
37
+ # No reprice was applied; `reason` says why.
38
+ #
39
+ # @param reason [Symbol, Anthropic::Models::Beta::BetaFallbackCreditNotApplied::Reason] Why the reprice was not applied.
40
+ #
41
+ # @param remove_to_redeem [Array<String>, nil] Request fields to remove before retrying, so the retry can redeem this
42
+ #
43
+ # @param type [Symbol, :not_applied]
44
+
45
+ # Why the reprice was not applied.
46
+ #
47
+ # A closed enum; additions to the redemption-check vocabulary arrive as deliberate
48
+ # schema updates.
49
+ #
50
+ # @see Anthropic::Models::Beta::BetaFallbackCreditNotApplied#reason
51
+ module Reason
52
+ extend Anthropic::Internal::Type::Enum
53
+
54
+ BODY_MISMATCH = :body_mismatch
55
+ CONTINUATION_EXCLUDED = :continuation_excluded
56
+ CONTINUATION_ONLY = :continuation_only
57
+ EXPIRED = :expired
58
+ INVALID_TARGET_MODEL = :invalid_target_model
59
+ NOT_ENABLED = :not_enabled
60
+ REPRICE_UNAVAILABLE = :reprice_unavailable
61
+ TEMPORARILY_UNAVAILABLE = :temporarily_unavailable
62
+ VARIANT_FIELDS_PRESENT = :variant_fields_present
63
+ WRONG_ORGANIZATION = :wrong_organization
64
+ WRONG_PLATFORM = :wrong_platform
65
+ WRONG_WORKSPACE = :wrong_workspace
66
+
67
+ # @!method self.values
68
+ # @return [Array<Symbol>]
69
+ end
70
+ end
71
+ end
72
+
73
+ BetaFallbackCreditNotApplied = Beta::BetaFallbackCreditNotApplied
74
+ end
75
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaFallbackCreditRedeemed < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute type
8
+ #
9
+ # @return [Symbol, :redeemed]
10
+ required :type, const: :redeemed
11
+
12
+ # @!method initialize(type: :redeemed)
13
+ # The reprice was applied: the retry is billed as if the conversation had been on
14
+ # the retry model all along.
15
+ #
16
+ # @param type [Symbol, :redeemed]
17
+ end
18
+ end
19
+
20
+ BetaFallbackCreditRedeemed = Beta::BetaFallbackCreditRedeemed
21
+ end
22
+ end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Models
5
+ module Beta
6
+ class BetaFallbackCreditTokenParam < Anthropic::Internal::Type::BaseModel
7
+ # @!attribute token
8
+ # The opaque `fallback_credit_token` from a prior refusal's `stop_details` — the
9
+ # same string the bare-string form carries.
10
+ #
11
+ # @return [String]
12
+ required :token, String
13
+
14
+ # @!attribute mode
15
+ # How a failing token affects the retry. `strict` (the default, and the
16
+ # bare-string behavior): a failing redemption is a 400 and the retry is not
17
+ # served. `best_effort`: the retry is served either way — a token-layer failure no
18
+ # longer rejects the request; the retry proceeds at normal price and the outcome
19
+ # is reported on the response's `usage.fallback_credit`. Two failures stay hard in
20
+ # both modes: a malformed token, and combining `fallback_credit_token` with
21
+ # `fallbacks`.
22
+ #
23
+ # @return [Symbol, Anthropic::Models::Beta::BetaFallbackCreditTokenParam::Mode, nil]
24
+ optional :mode, enum: -> { Anthropic::Beta::BetaFallbackCreditTokenParam::Mode }
25
+
26
+ # @!method initialize(token:, mode: nil)
27
+ # Some parameter documentations has been truncated, see
28
+ # {Anthropic::Models::Beta::BetaFallbackCreditTokenParam} for more details.
29
+ #
30
+ # Object form of `fallback_credit_token`: the token plus a redemption mode.
31
+ #
32
+ # Requires `anthropic-beta: fallback-credit-2026-07-01`; without that header the
33
+ # field accepts the bare string only. The bare string and the mode-less object are
34
+ # equivalent (both select `strict`), so wrapping an existing token changes nothing
35
+ # by itself.
36
+ #
37
+ # @param token [String] The opaque `fallback_credit_token` from a prior refusal's `stop_details` — the s
38
+ #
39
+ # @param mode [Symbol, Anthropic::Models::Beta::BetaFallbackCreditTokenParam::Mode] How a failing token affects the retry. `strict` (the default, and the bare-strin
40
+
41
+ # How a failing token affects the retry. `strict` (the default, and the
42
+ # bare-string behavior): a failing redemption is a 400 and the retry is not
43
+ # served. `best_effort`: the retry is served either way — a token-layer failure no
44
+ # longer rejects the request; the retry proceeds at normal price and the outcome
45
+ # is reported on the response's `usage.fallback_credit`. Two failures stay hard in
46
+ # both modes: a malformed token, and combining `fallback_credit_token` with
47
+ # `fallbacks`.
48
+ #
49
+ # @see Anthropic::Models::Beta::BetaFallbackCreditTokenParam#mode
50
+ module Mode
51
+ extend Anthropic::Internal::Type::Enum
52
+
53
+ STRICT = :strict
54
+ BEST_EFFORT = :best_effort
55
+
56
+ # @!method self.values
57
+ # @return [Array<Symbol>]
58
+ end
59
+ end
60
+ end
61
+
62
+ BetaFallbackCreditTokenParam = Beta::BetaFallbackCreditTokenParam
63
+ end
64
+ end