anthropic 1.35.0 → 1.37.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 (191) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -0
  3. data/README.md +1 -1
  4. data/lib/anthropic/client.rb +186 -24
  5. data/lib/anthropic/credentials/access_token.rb +40 -0
  6. data/lib/anthropic/credentials/config.rb +74 -0
  7. data/lib/anthropic/credentials/config_provider.rb +427 -0
  8. data/lib/anthropic/credentials/constants.rb +197 -0
  9. data/lib/anthropic/credentials/credentials_file.rb +123 -0
  10. data/lib/anthropic/credentials/identity_token_file.rb +65 -0
  11. data/lib/anthropic/credentials/in_memory_config.rb +114 -0
  12. data/lib/anthropic/credentials/static_token.rb +25 -0
  13. data/lib/anthropic/credentials/token_cache.rb +159 -0
  14. data/lib/anthropic/credentials/workload_identity.rb +185 -0
  15. data/lib/anthropic/credentials.rb +156 -0
  16. data/lib/anthropic/errors.rb +3 -0
  17. data/lib/anthropic/helpers/aws/client.rb +18 -5
  18. data/lib/anthropic/helpers/bedrock/client.rb +11 -4
  19. data/lib/anthropic/helpers/bedrock/mantle_client.rb +10 -5
  20. data/lib/anthropic/internal/transport/base_client.rb +31 -3
  21. data/lib/anthropic/models/anthropic_beta.rb +3 -3
  22. data/lib/anthropic/models/beta/beta_environment.rb +1 -1
  23. data/lib/anthropic/models/beta/beta_managed_agents_deleted_memory_store.rb +44 -0
  24. data/lib/anthropic/models/beta/beta_managed_agents_memory_store.rb +100 -0
  25. data/lib/anthropic/models/beta/beta_managed_agents_memory_store_resource_param.rb +77 -0
  26. data/lib/anthropic/models/beta/beta_managed_agents_session.rb +2 -2
  27. data/lib/anthropic/models/beta/memory_store_archive_params.rb +31 -0
  28. data/lib/anthropic/models/beta/memory_store_create_params.rb +58 -0
  29. data/lib/anthropic/models/beta/memory_store_delete_params.rb +31 -0
  30. data/lib/anthropic/models/beta/memory_store_list_params.rb +72 -0
  31. data/lib/anthropic/models/beta/memory_store_retrieve_params.rb +31 -0
  32. data/lib/anthropic/models/beta/memory_store_update_params.rb +63 -0
  33. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_actor.rb +32 -0
  34. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_api_actor.rb +45 -0
  35. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_conflict_error.rb +35 -0
  36. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_content_sha256_precondition.rb +52 -0
  37. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_deleted_memory.rb +44 -0
  38. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_error.rb +44 -0
  39. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_memory.rb +125 -0
  40. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_memory_list_item.rb +29 -0
  41. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_memory_path_conflict_error.rb +47 -0
  42. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_memory_precondition_failed_error.rb +36 -0
  43. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_memory_prefix.rb +50 -0
  44. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_memory_version.rb +154 -0
  45. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_memory_version_operation.rb +22 -0
  46. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_memory_view.rb +24 -0
  47. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_precondition.rb +51 -0
  48. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_session_actor.rb +46 -0
  49. data/lib/anthropic/models/beta/memory_stores/beta_managed_agents_user_actor.rb +39 -0
  50. data/lib/anthropic/models/beta/memory_stores/memory_create_params.rb +64 -0
  51. data/lib/anthropic/models/beta/memory_stores/memory_delete_params.rb +48 -0
  52. data/lib/anthropic/models/beta/memory_stores/memory_list_params.rb +105 -0
  53. data/lib/anthropic/models/beta/memory_stores/memory_retrieve_params.rb +48 -0
  54. data/lib/anthropic/models/beta/memory_stores/memory_update_params.rb +85 -0
  55. data/lib/anthropic/models/beta/memory_stores/memory_version_list_params.rb +105 -0
  56. data/lib/anthropic/models/beta/memory_stores/memory_version_redact_params.rb +40 -0
  57. data/lib/anthropic/models/beta/memory_stores/memory_version_retrieve_params.rb +48 -0
  58. data/lib/anthropic/models/beta/message_create_params.rb +7 -6
  59. data/lib/anthropic/models/beta/messages/batch_create_params.rb +7 -6
  60. data/lib/anthropic/models/beta/session_create_params.rb +6 -3
  61. data/lib/anthropic/models/beta/session_list_params.rb +10 -1
  62. data/lib/anthropic/models/beta/sessions/beta_managed_agents_memory_store_resource.rb +104 -0
  63. data/lib/anthropic/models/beta/sessions/beta_managed_agents_session_resource.rb +6 -1
  64. data/lib/anthropic/models/beta/sessions/resource_retrieve_response.rb +4 -1
  65. data/lib/anthropic/models/beta/sessions/resource_update_response.rb +4 -1
  66. data/lib/anthropic/models/completion_create_params.rb +14 -6
  67. data/lib/anthropic/models/message_create_params.rb +7 -6
  68. data/lib/anthropic/models/messages/batch_create_params.rb +7 -6
  69. data/lib/anthropic/resources/beta/memory_stores/memories.rb +217 -0
  70. data/lib/anthropic/resources/beta/memory_stores/memory_versions.rb +151 -0
  71. data/lib/anthropic/resources/beta/memory_stores.rb +203 -0
  72. data/lib/anthropic/resources/beta/messages/batches.rb +7 -1
  73. data/lib/anthropic/resources/beta/messages.rb +1 -0
  74. data/lib/anthropic/resources/beta/sessions/events.rb +7 -1
  75. data/lib/anthropic/resources/beta/sessions/resources.rb +3 -3
  76. data/lib/anthropic/resources/beta/sessions.rb +5 -2
  77. data/lib/anthropic/resources/beta.rb +4 -0
  78. data/lib/anthropic/resources/completions.rb +4 -1
  79. data/lib/anthropic/resources/messages/batches.rb +1 -1
  80. data/lib/anthropic/version.rb +1 -1
  81. data/lib/anthropic.rb +50 -0
  82. data/rbi/anthropic/client.rbi +3 -0
  83. data/rbi/anthropic/credentials.rbi +259 -0
  84. data/rbi/anthropic/helpers/aws/client.rbi +3 -2
  85. data/rbi/anthropic/helpers/bedrock/mantle_client.rbi +3 -2
  86. data/rbi/anthropic/internal/transport/base_client.rbi +9 -0
  87. data/rbi/anthropic/models/anthropic_beta.rbi +4 -4
  88. data/rbi/anthropic/models/beta/beta_environment.rbi +1 -1
  89. data/rbi/anthropic/models/beta/beta_managed_agents_deleted_memory_store.rbi +89 -0
  90. data/rbi/anthropic/models/beta/beta_managed_agents_memory_store.rbi +152 -0
  91. data/rbi/anthropic/models/beta/beta_managed_agents_memory_store_resource_param.rbi +154 -0
  92. data/rbi/anthropic/models/beta/beta_managed_agents_session.rbi +2 -1
  93. data/rbi/anthropic/models/beta/memory_store_archive_params.rbi +68 -0
  94. data/rbi/anthropic/models/beta/memory_store_create_params.rbi +106 -0
  95. data/rbi/anthropic/models/beta/memory_store_delete_params.rbi +68 -0
  96. data/rbi/anthropic/models/beta/memory_store_list_params.rbi +127 -0
  97. data/rbi/anthropic/models/beta/memory_store_retrieve_params.rbi +68 -0
  98. data/rbi/anthropic/models/beta/memory_store_update_params.rbi +102 -0
  99. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_actor.rbi +37 -0
  100. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_api_actor.rbi +89 -0
  101. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_conflict_error.rbi +83 -0
  102. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_content_sha256_precondition.rbi +100 -0
  103. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_deleted_memory.rbi +90 -0
  104. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_error.rbi +41 -0
  105. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_memory.rbi +179 -0
  106. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_memory_list_item.rbi +34 -0
  107. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_memory_path_conflict_error.rbi +104 -0
  108. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_memory_precondition_failed_error.rbi +83 -0
  109. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_memory_prefix.rbi +95 -0
  110. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_memory_version.rbi +267 -0
  111. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_memory_version_operation.rbi +50 -0
  112. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_memory_view.rbi +48 -0
  113. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_precondition.rbi +100 -0
  114. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_session_actor.rbi +91 -0
  115. data/rbi/anthropic/models/beta/memory_stores/beta_managed_agents_user_actor.rbi +86 -0
  116. data/rbi/anthropic/models/beta/memory_stores/memory_create_params.rbi +119 -0
  117. data/rbi/anthropic/models/beta/memory_stores/memory_delete_params.rbi +88 -0
  118. data/rbi/anthropic/models/beta/memory_stores/memory_list_params.rbi +213 -0
  119. data/rbi/anthropic/models/beta/memory_stores/memory_retrieve_params.rbi +101 -0
  120. data/rbi/anthropic/models/beta/memory_stores/memory_update_params.rbi +161 -0
  121. data/rbi/anthropic/models/beta/memory_stores/memory_version_list_params.rbi +196 -0
  122. data/rbi/anthropic/models/beta/memory_stores/memory_version_redact_params.rbi +77 -0
  123. data/rbi/anthropic/models/beta/memory_stores/memory_version_retrieve_params.rbi +101 -0
  124. data/rbi/anthropic/models/beta/message_create_params.rbi +14 -12
  125. data/rbi/anthropic/models/beta/messages/batch_create_params.rbi +14 -12
  126. data/rbi/anthropic/models/beta/session_create_params.rbi +10 -5
  127. data/rbi/anthropic/models/beta/session_list_params.rbi +13 -0
  128. data/rbi/anthropic/models/beta/sessions/beta_managed_agents_memory_store_resource.rbi +186 -0
  129. data/rbi/anthropic/models/beta/sessions/beta_managed_agents_session_resource.rbi +3 -1
  130. data/rbi/anthropic/models/beta/sessions/resource_retrieve_response.rbi +2 -1
  131. data/rbi/anthropic/models/beta/sessions/resource_update_response.rbi +2 -1
  132. data/rbi/anthropic/models/completion_create_params.rbi +6 -12
  133. data/rbi/anthropic/models/message_create_params.rbi +14 -12
  134. data/rbi/anthropic/models/messages/batch_create_params.rbi +14 -12
  135. data/rbi/anthropic/resources/beta/memory_stores/memories.rbi +191 -0
  136. data/rbi/anthropic/resources/beta/memory_stores/memory_versions.rbi +117 -0
  137. data/rbi/anthropic/resources/beta/memory_stores.rbi +172 -0
  138. data/rbi/anthropic/resources/beta/messages.rbi +14 -12
  139. data/rbi/anthropic/resources/beta/sessions.rbi +6 -1
  140. data/rbi/anthropic/resources/beta.rbi +3 -0
  141. data/rbi/anthropic/resources/completions.rbi +6 -12
  142. data/rbi/anthropic/resources/messages.rbi +14 -12
  143. data/sig/anthropic/credentials.rbs +240 -0
  144. data/sig/anthropic/internal/transport/base_client.rbs +7 -1
  145. data/sig/anthropic/models/anthropic_beta.rbs +2 -2
  146. data/sig/anthropic/models/beta/beta_managed_agents_deleted_memory_store.rbs +39 -0
  147. data/sig/anthropic/models/beta/beta_managed_agents_memory_store.rbs +73 -0
  148. data/sig/anthropic/models/beta/beta_managed_agents_memory_store_resource_param.rbs +60 -0
  149. data/sig/anthropic/models/beta/memory_store_archive_params.rbs +37 -0
  150. data/sig/anthropic/models/beta/memory_store_create_params.rbs +51 -0
  151. data/sig/anthropic/models/beta/memory_store_delete_params.rbs +37 -0
  152. data/sig/anthropic/models/beta/memory_store_list_params.rbs +67 -0
  153. data/sig/anthropic/models/beta/memory_store_retrieve_params.rbs +37 -0
  154. data/sig/anthropic/models/beta/memory_store_update_params.rbs +52 -0
  155. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_actor.rbs +18 -0
  156. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_api_actor.rbs +39 -0
  157. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_conflict_error.rbs +41 -0
  158. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_content_sha256_precondition.rbs +41 -0
  159. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_deleted_memory.rbs +39 -0
  160. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_error.rbs +27 -0
  161. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_memory.rbs +79 -0
  162. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_memory_list_item.rbs +17 -0
  163. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_memory_path_conflict_error.rbs +55 -0
  164. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_memory_precondition_failed_error.rbs +41 -0
  165. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_memory_prefix.rbs +39 -0
  166. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_memory_version.rbs +102 -0
  167. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_memory_version_operation.rbs +20 -0
  168. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_memory_view.rbs +18 -0
  169. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_precondition.rbs +41 -0
  170. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_session_actor.rbs +39 -0
  171. data/sig/anthropic/models/beta/memory_stores/beta_managed_agents_user_actor.rbs +39 -0
  172. data/sig/anthropic/models/beta/memory_stores/memory_create_params.rbs +58 -0
  173. data/sig/anthropic/models/beta/memory_stores/memory_delete_params.rbs +51 -0
  174. data/sig/anthropic/models/beta/memory_stores/memory_list_params.rbs +103 -0
  175. data/sig/anthropic/models/beta/memory_stores/memory_retrieve_params.rbs +53 -0
  176. data/sig/anthropic/models/beta/memory_stores/memory_update_params.rbs +72 -0
  177. data/sig/anthropic/models/beta/memory_stores/memory_version_list_params.rbs +106 -0
  178. data/sig/anthropic/models/beta/memory_stores/memory_version_redact_params.rbs +44 -0
  179. data/sig/anthropic/models/beta/memory_stores/memory_version_retrieve_params.rbs +53 -0
  180. data/sig/anthropic/models/beta/session_create_params.rbs +1 -0
  181. data/sig/anthropic/models/beta/session_list_params.rbs +7 -0
  182. data/sig/anthropic/models/beta/sessions/beta_managed_agents_memory_store_resource.rbs +77 -0
  183. data/sig/anthropic/models/beta/sessions/beta_managed_agents_session_resource.rbs +1 -0
  184. data/sig/anthropic/models/beta/sessions/resource_retrieve_response.rbs +1 -0
  185. data/sig/anthropic/models/beta/sessions/resource_update_response.rbs +1 -0
  186. data/sig/anthropic/resources/beta/memory_stores/memories.rbs +60 -0
  187. data/sig/anthropic/resources/beta/memory_stores/memory_versions.rbs +41 -0
  188. data/sig/anthropic/resources/beta/memory_stores.rbs +58 -0
  189. data/sig/anthropic/resources/beta/sessions.rbs +1 -0
  190. data/sig/anthropic/resources/beta.rbs +2 -0
  191. metadata +129 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5db1f4f469b9a2e1aad1435777496f6d191945ff0017fdf8ff5a04522da40370
4
- data.tar.gz: 35dac1ad2c116e55ec90da2acd486c45c91ad1925181876600170a16e52b4ed1
3
+ metadata.gz: 9eacf10bf13feb1eb221fe82ee801d2754524985991959c858db721b5cfd825e
4
+ data.tar.gz: 6e70a7c6d4ee0dd18a892272017f73e524ace1a943579b9694c23c94331ad421
5
5
  SHA512:
6
- metadata.gz: dc6e88fb4aa8d98beabeb4755b6d7c45d1faf5e59daf133ae75b57922ebd21e86f4ff5d22f3ec0686efc1c2746fda89ba135b5510ed83360a3e215924bfc611d
7
- data.tar.gz: 5f3f2d032b2f67f5f04025048470ed175afc85705e8ea2f3faded5f44f13cdc43eda11cbaddbdb7078acbdb2c9beb61b150dd4f2abde8d4122ca7f965a3f094e
6
+ metadata.gz: '002489936b1fa9dda322c5dd604bea0eb371ef4a25a8e091e8a7204db4acca6d3dfa7e4840666a1042b0052271215abc18499a99ab5d9a5589401ad1df9626c1'
7
+ data.tar.gz: 95b904d78f29eb0b36f694c628c52c686775349ca3ba9cb6746ce33758558dc48a624ca925bc72661bf54b033272cf14d57babea6d86ffed7b6d37531fada262
data/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.37.0 (2026-05-04)
4
+
5
+ Full Changelog: [v1.36.0...v1.37.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.36.0...v1.37.0)
6
+
7
+ ### Features
8
+
9
+ * **api:** improve Managed Agents APIs ([34caf5b](https://github.com/anthropics/anthropic-sdk-ruby/commit/34caf5b0994bc818a7ee835832624853cc0a2abe))
10
+ * **client:** add Workload Identity Federation, interactive OAuth, and auth profiles ([4d394a4](https://github.com/anthropics/anthropic-sdk-ruby/commit/4d394a419f6219cf46ca459083510c89f44041a7))
11
+ * support setting headers via env ([08e8b38](https://github.com/anthropics/anthropic-sdk-ruby/commit/08e8b382e8795ebb008daea6769550374952b301))
12
+
13
+ ## 1.36.0 (2026-04-23)
14
+
15
+ Full Changelog: [v1.35.0...v1.36.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.35.0...v1.36.0)
16
+
17
+ ### Features
18
+
19
+ * **api:** CMA Memory public beta ([9fafd1a](https://github.com/anthropics/anthropic-sdk-ruby/commit/9fafd1abe16d0398c6e59be0717a9ef9cb014347))
20
+
21
+
22
+ ### Bug Fixes
23
+
24
+ * **api:** fix errors in api spec ([074fa8d](https://github.com/anthropics/anthropic-sdk-ruby/commit/074fa8dac4cdebc8eababcac95ca4fe9dc7970d3))
25
+ * **api:** restore missing features ([4496fac](https://github.com/anthropics/anthropic-sdk-ruby/commit/4496facb8130e48340a2c4107d3aaf412b5cf4eb))
26
+ * avoid gzip buffering during streaming ([307c594](https://github.com/anthropics/anthropic-sdk-ruby/commit/307c5944e27dd3eab5aa3c6f6e7ed02ca5b7cece))
27
+
28
+
29
+ ### Chores
30
+
31
+ * **internal:** more robust bootstrap script ([e8f157e](https://github.com/anthropics/anthropic-sdk-ruby/commit/e8f157e44e664c036c0b81584eee8919d55eb6db))
32
+ * **tests:** bump steady to v0.22.1 ([7f079ce](https://github.com/anthropics/anthropic-sdk-ruby/commit/7f079cee1a662245ce67c12b1b7790832dd931ad))
33
+
3
34
  ## 1.35.0 (2026-04-16)
4
35
 
5
36
  Full Changelog: [v1.34.0...v1.35.0](https://github.com/anthropics/anthropic-sdk-ruby/compare/v1.34.0...v1.35.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.35.0"
18
+ gem "anthropic", "~> 1.37.0"
19
19
  ```
20
20
 
21
21
  <!-- x-release-please-end -->
@@ -1,6 +1,32 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Anthropic
4
+ @warned_explicit_shadow = false
5
+ @warned_env_shadow = false
6
+
7
+ class << self
8
+ def warn_explicit_static_shadows_credentials(param)
9
+ return if @warned_explicit_shadow
10
+ @warned_explicit_shadow = true
11
+
12
+ warn(
13
+ "[anthropic-ruby] `#{param}:` was passed alongside `credentials:`; the static credential " \
14
+ "takes precedence and the credentials provider is silently disabled. " \
15
+ "Pass only one."
16
+ )
17
+ end
18
+
19
+ def warn_env_static_shadows_auto_discovery(env_var)
20
+ return if @warned_env_shadow
21
+ @warned_env_shadow = true
22
+
23
+ warn(
24
+ "[anthropic-ruby] #{env_var} is set and takes precedence over the SDK's profile / federation " \
25
+ "auto-discovery; unset #{env_var} to use the auto-discovered credential."
26
+ )
27
+ end
28
+ end
29
+
4
30
  class Client < Anthropic::Internal::Transport::BaseClient
5
31
  # Default max number of retries to attempt after a failed retryable request.
6
32
  DEFAULT_MAX_RETRIES = 2
@@ -33,6 +59,12 @@ module Anthropic
33
59
  # @return [String, nil]
34
60
  attr_reader :auth_token
35
61
 
62
+ # @return [Object, nil]
63
+ attr_reader :credentials
64
+
65
+ # @return [Anthropic::Credentials::TokenCache, nil]
66
+ attr_reader :token_cache
67
+
36
68
  # @return [Anthropic::Resources::Completions]
37
69
  attr_reader :completions
38
70
 
@@ -49,23 +81,19 @@ module Anthropic
49
81
  #
50
82
  # @return [Hash{String=>String}]
51
83
  private def auth_headers
52
- {**api_key_auth, **bearer_auth}
53
- end
84
+ headers = {}
54
85
 
55
- # @api private
56
- #
57
- # @return [Hash{String=>String}]
58
- private def api_key_auth
59
- {"x-api-key" => @api_key}
60
- end
61
-
62
- # @api private
63
- #
64
- # @return [Hash{String=>String}]
65
- private def bearer_auth
66
- return {} if @auth_token.nil?
86
+ if @api_key
87
+ headers["x-api-key"] = @api_key
88
+ elsif @auth_token
89
+ headers["authorization"] = "Bearer #{@auth_token}"
90
+ elsif @token_cache
91
+ token = @token_cache.get_token
92
+ headers["authorization"] = "Bearer #{token}"
93
+ headers["anthropic-beta"] = Anthropic::Credentials::OAUTH_API_BETA_HEADER
94
+ end
67
95
 
68
- {"authorization" => "Bearer #{@auth_token}"}
96
+ headers
69
97
  end
70
98
 
71
99
  # Calculate the timeout for non-streaming requests based on token count
@@ -91,12 +119,49 @@ module Anthropic
91
119
 
92
120
  # Creates and returns a new client for interacting with the API.
93
121
  #
94
- # @param api_key [String, nil] Defaults to `ENV["ANTHROPIC_API_KEY"]`
122
+ # Credential precedence, matching the credential-resolution spec and
123
+ # the Workload Identity Federation user guide:
124
+ #
125
+ # 1. Explicit constructor arguments — +api_key:+, +auth_token:+,
126
+ # +credentials:+, +config:+. If the caller passed any of these,
127
+ # the SDK uses it and does *not* read credential env vars.
128
+ # 2. +ANTHROPIC_API_KEY+ / +ANTHROPIC_AUTH_TOKEN+ env vars. Only
129
+ # consulted when no explicit credential argument was passed.
130
+ # 3. +ANTHROPIC_PROFILE+ — explicit profile selection.
131
+ # 4. Direct env-var federation (+ANTHROPIC_IDENTITY_TOKEN[_FILE]+ +
132
+ # +ANTHROPIC_FEDERATION_RULE_ID+ + +ANTHROPIC_ORGANIZATION_ID+).
133
+ # 5. Fallback active profile from disk (+active_config+ pointer or
134
+ # the literal +default+).
135
+ #
136
+ # A static env credential (step 2) *shadows* steps 3–5, silently
137
+ # disabling profile / federation auto-discovery.
138
+ #
139
+ # Passing an explicit +api_key:+ or +auth_token:+ *argument*
140
+ # alongside an explicit +credentials:+ is supported: the
141
+ # static credential takes precedence at the request-header level and
142
+ # the credentials provider is silently disabled.
95
143
  #
96
- # @param auth_token [String, nil] Defaults to `ENV["ANTHROPIC_AUTH_TOKEN"]`
144
+ # @param api_key [String, nil] Defaults to +ENV["ANTHROPIC_API_KEY"]+ when
145
+ # no explicit credential argument is passed.
146
+ #
147
+ # @param auth_token [String, nil] Defaults to +ENV["ANTHROPIC_AUTH_TOKEN"]+ when
148
+ # no explicit credential argument is passed.
149
+ #
150
+ # @param credentials [#call, nil] Credential provider — any callable returning
151
+ # +AccessToken.new(token:, expires_at:)+. The provider is wrapped in a
152
+ # +TokenCache+ for thread-safe caching and proactive refresh (120s advisory /
153
+ # 30s mandatory before expiry). Common providers: +WorkloadIdentity+,
154
+ # +CredentialsFile+, +StaticToken+, or a custom lambda.
155
+ #
156
+ # @param config [Hash, nil] In-memory configuration hash with the same shape
157
+ # as +configs/<profile>.json+. Must include an +authentication+ object with
158
+ # a +type+ field (+oidc_federation+ or +user_oauth+). Mutually exclusive
159
+ # with +credentials:+. For +user_oauth+, must also include
160
+ # +authentication.credentials_path+.
97
161
  #
98
162
  # @param base_url [String, nil] Override the default base URL for the API, e.g.,
99
- # `"https://api.example.com/v2/"`. Defaults to `ENV["ANTHROPIC_BASE_URL"]`
163
+ # +"https://api.example.com/v2/"+. Defaults to +ENV["ANTHROPIC_BASE_URL"]+,
164
+ # then to the profile's +base_url+ if present, then to +https://api.anthropic.com+.
100
165
  #
101
166
  # @param max_retries [Integer] Max number of retries to attempt after a failed retryable request.
102
167
  #
@@ -106,22 +171,86 @@ module Anthropic
106
171
  #
107
172
  # @param max_retry_delay [Float]
108
173
  def initialize(
109
- api_key: ENV["ANTHROPIC_API_KEY"],
110
- auth_token: ENV["ANTHROPIC_AUTH_TOKEN"],
111
- base_url: ENV["ANTHROPIC_BASE_URL"],
174
+ api_key: nil,
175
+ auth_token: nil,
176
+ credentials: nil,
177
+ config: nil,
178
+ base_url: nil,
112
179
  max_retries: self.class::DEFAULT_MAX_RETRIES,
113
180
  timeout: self.class::DEFAULT_TIMEOUT_IN_SECONDS,
114
181
  initial_retry_delay: self.class::DEFAULT_INITIAL_RETRY_DELAY,
115
182
  max_retry_delay: self.class::DEFAULT_MAX_RETRY_DELAY
116
183
  )
184
+ if config && credentials
185
+ raise ArgumentError, "Pass at most one of `credentials:` or `config:`."
186
+ end
187
+
188
+ has_explicit_credential = api_key || auth_token || credentials || config
189
+
190
+ unless has_explicit_credential
191
+ api_key = ENV["ANTHROPIC_API_KEY"]
192
+ auth_token = ENV["ANTHROPIC_AUTH_TOKEN"]
193
+ end
194
+
195
+ @api_key = api_key&.to_s
196
+ @auth_token = auth_token&.to_s
197
+ @credentials = nil
198
+ @token_cache = nil
199
+
200
+ base_url_is_explicit = base_url && !base_url.empty?
201
+ base_url ||= ENV["ANTHROPIC_BASE_URL"]
202
+
203
+ credential_headers = {}
204
+
205
+ if config
206
+ in_memory = Anthropic::Credentials::InMemoryConfig.new(config)
207
+ @credentials = in_memory
208
+ credential_headers = in_memory.extra_headers
209
+ if !base_url_is_explicit && in_memory.resolved_base_url
210
+ base_url = in_memory.resolved_base_url
211
+ end
212
+ else
213
+ @credentials = credentials
214
+ end
215
+
216
+ if @credentials.nil? && @api_key.nil? && @auth_token.nil?
217
+ default_base_url = base_url || "https://api.anthropic.com"
218
+ result = Anthropic::Credentials.default_credentials(base_url: default_base_url)
219
+ if result
220
+ @credentials = result.provider
221
+ credential_headers = result.extra_headers
222
+ base_url = result.base_url if !base_url_is_explicit && result.base_url
223
+ end
224
+ end
225
+
226
+ warn_explicit_shadow(api_key: api_key, auth_token: auth_token, credentials: credentials || config)
227
+ warn_env_shadow(api_key: api_key, auth_token: auth_token)
228
+
229
+ if @credentials
230
+ @token_cache = Anthropic::Credentials::TokenCache.new(@credentials)
231
+ end
232
+
117
233
  base_url ||= "https://api.anthropic.com"
118
234
 
235
+ if @credentials.respond_to?(:bind_base_url)
236
+ @credentials.bind_base_url(base_url)
237
+ end
238
+
119
239
  headers = {
120
240
  "anthropic-version" => "2023-06-01"
121
241
  }
122
-
123
- @api_key = api_key&.to_s
124
- @auth_token = auth_token&.to_s
242
+ custom_headers_env = ENV["ANTHROPIC_CUSTOM_HEADERS"]
243
+ unless custom_headers_env.nil?
244
+ parsed = {}
245
+ custom_headers_env.split("\n").each do |line|
246
+ colon = line.index(":")
247
+ unless colon.nil?
248
+ parsed[line[0...colon].strip] = line[(colon + 1)..].strip
249
+ end
250
+ end
251
+ headers = parsed.merge(headers)
252
+ end
253
+ headers = headers.merge(credential_headers)
125
254
 
126
255
  super(
127
256
  base_url: base_url,
@@ -137,5 +266,38 @@ module Anthropic
137
266
  @models = Anthropic::Resources::Models.new(client: self)
138
267
  @beta = Anthropic::Resources::Beta.new(client: self)
139
268
  end
269
+
270
+ # @api private
271
+ #
272
+ # @param status [Integer]
273
+ # @param headers [Hash{String=>String}]
274
+ #
275
+ # @return [Boolean]
276
+ def retry_request?(status, headers:)
277
+ if status == 401 && @token_cache
278
+ @token_cache.invalidate
279
+ return true
280
+ end
281
+ super
282
+ end
283
+
284
+ private
285
+
286
+ def warn_explicit_shadow(api_key:, auth_token:, credentials:)
287
+ return if credentials.nil?
288
+
289
+ Anthropic.warn_explicit_static_shadows_credentials("api_key") if api_key
290
+ Anthropic.warn_explicit_static_shadows_credentials("auth_token") if auth_token
291
+ end
292
+
293
+ def warn_env_shadow(api_key:, auth_token:)
294
+ return unless Anthropic::Credentials.auto_discoverable_credentials?
295
+
296
+ if api_key && ENV["ANTHROPIC_API_KEY"]
297
+ Anthropic.warn_env_static_shadows_auto_discovery("ANTHROPIC_API_KEY")
298
+ end
299
+ return unless auth_token && ENV["ANTHROPIC_AUTH_TOKEN"]
300
+ Anthropic.warn_env_static_shadows_auto_discovery("ANTHROPIC_AUTH_TOKEN")
301
+ end
140
302
  end
141
303
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Anthropic
4
+ module Credentials
5
+ # An Anthropic API access token with optional expiry.
6
+ #
7
+ # This is a frozen value object representing an access token and its
8
+ # expiration time. The +expires_at+ is a Unix timestamp in seconds;
9
+ # +nil+ means no expiry information (the token will be treated as
10
+ # never-expires by {TokenCache}).
11
+ class AccessToken
12
+ # @return [String] the access token string
13
+ attr_reader :token
14
+
15
+ # @return [Integer, nil] Unix timestamp in seconds when the token expires,
16
+ # or +nil+ if the token never expires
17
+ attr_reader :expires_at
18
+
19
+ # @param token [String] the access token string
20
+ # @param expires_at [Integer, nil] Unix timestamp in seconds, or +nil+ for no expiry
21
+ def initialize(token:, expires_at: nil)
22
+ @token = token
23
+ @expires_at = expires_at
24
+ freeze
25
+ end
26
+
27
+ # @return [Integer] hash code for the token
28
+ def hash
29
+ [token, expires_at].hash
30
+ end
31
+
32
+ def ==(other)
33
+ return false unless other.is_a?(AccessToken)
34
+ token == other.token && expires_at == other.expires_at
35
+ end
36
+
37
+ alias_method :eql?, :==
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require "uri"
5
+
6
+ module Anthropic
7
+ module Config
8
+ class << self
9
+ def config_file_path(profile)
10
+ validate_profile_name!(profile)
11
+ Anthropic::Credentials.config_file_path(profile)
12
+ end
13
+
14
+ def credentials_file_path(profile)
15
+ validate_profile_name!(profile)
16
+ Anthropic::Credentials.config_dir.join("credentials", "#{profile}.json")
17
+ end
18
+
19
+ def active_profile
20
+ profile = Anthropic::Credentials.active_profile
21
+ validate_profile_name!(profile)
22
+ profile
23
+ end
24
+
25
+ def active_profile_config?
26
+ config_file_path(active_profile).file?
27
+ rescue Anthropic::Errors::ConfigurationError
28
+ false
29
+ end
30
+
31
+ def validate_profile_name!(profile, source: "profile name")
32
+ if profile.nil? || profile.empty?
33
+ raise Anthropic::Errors::ConfigurationError,
34
+ "#{source} must not be empty"
35
+ end
36
+ if profile != profile.strip
37
+ raise Anthropic::Errors::ConfigurationError,
38
+ "#{source} '#{profile}' has leading/trailing whitespace"
39
+ end
40
+ if profile.start_with?(".")
41
+ raise Anthropic::Errors::ConfigurationError,
42
+ "#{source} '#{profile}' must not start with a dot"
43
+ end
44
+
45
+ ["/", "\\", File::SEPARATOR].each do |sep|
46
+ next if sep.empty?
47
+ if profile.include?(sep)
48
+ raise Anthropic::Errors::ConfigurationError,
49
+ "#{source} '#{profile}' must not contain path separators"
50
+ end
51
+ end
52
+
53
+ return unless profile.include?("\x00")
54
+ raise Anthropic::Errors::ConfigurationError, "#{source} '#{profile}' must not contain null bytes"
55
+ end
56
+
57
+ def require_https!(url, field:)
58
+ begin
59
+ uri = URI.parse(url.to_s)
60
+ rescue URI::InvalidURIError
61
+ raise Anthropic::Errors::ConfigurationError,
62
+ "#{field} is not a valid URL (got '#{url}')"
63
+ end
64
+
65
+ return if uri.scheme == "https"
66
+ return if uri.scheme == "http" && %w[localhost 127.0.0.1 ::1].include?(uri.hostname)
67
+
68
+ raise Anthropic::Errors::ConfigurationError,
69
+ "#{field} must use https (got '#{url}'); the token-exchange endpoint " \
70
+ "carries secret material and cannot be used over cleartext HTTP."
71
+ end
72
+ end
73
+ end
74
+ end