Class: Providers::Anthropic
- Inherits:
-
Object
- Object
- Providers::Anthropic
show all
- Includes:
- HTTParty
- Defined in:
- lib/providers/anthropic.rb
Defined Under Namespace
Classes: AuthenticationError, Error, RateLimitError, ServerError, TokenFormatError, TransientError
Constant Summary
collapse
- TOKEN_PREFIX =
"sk-ant-oat01-"
- TOKEN_MIN_LENGTH =
80
- API_VERSION =
"2023-06-01"
- REQUIRED_BETA =
"oauth-2025-04-20"
- VALIDATION_MODEL =
"claude-sonnet-4-20250514"
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(token = nil) ⇒ Anthropic
Returns a new instance of Anthropic.
59
60
61
|
# File 'lib/providers/anthropic.rb', line 59
def initialize(token = nil)
@token = token || self.class.fetch_token
end
|
Instance Attribute Details
#token ⇒ Object
Returns the value of attribute token.
57
58
59
|
# File 'lib/providers/anthropic.rb', line 57
def token
@token
end
|
Class Method Details
.fetch_token ⇒ Object
28
29
30
31
32
33
34
35
|
# File 'lib/providers/anthropic.rb', line 28
def fetch_token
token = Rails.application.credentials.dig(:anthropic, :subscription_token)
raise AuthenticationError, <<~MSG.strip if token.blank?
No Anthropic subscription token found in credentials.
Use the TUI token setup (Ctrl+a → a) to configure your token.
MSG
token
end
|
.validate_token_api!(token) ⇒ Object
51
52
53
54
|
# File 'lib/providers/anthropic.rb', line 51
def validate_token_api!(token)
provider = new(token)
provider.validate_credentials!
end
|
Instance Method Details
#count_tokens(model:, messages:, **options) ⇒ Integer
Count tokens in a message payload without creating a message. Uses the free Anthropic token counting endpoint.
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
# File 'lib/providers/anthropic.rb', line 85
def count_tokens(model:, messages:, **options)
body = {model: model, messages: messages}.merge(options)
response = self.class.post(
"/v1/messages/count_tokens",
body: body.to_json,
headers:
)
result = handle_response(response)
result["input_tokens"]
rescue Errno::ECONNRESET, Net::ReadTimeout, Net::OpenTimeout, SocketError, EOFError => e
raise TransientError, "#{e.class}: #{e.message}"
end
|
#create_message(model:, messages:, max_tokens:, **options) ⇒ Object
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/providers/anthropic.rb', line 63
def create_message(model:, messages:, max_tokens:, **options)
body = {model: model, messages: messages, max_tokens: max_tokens}.merge(options)
response = self.class.post(
"/v1/messages",
body: body.to_json,
headers:
)
handle_response(response)
rescue Errno::ECONNRESET, Net::ReadTimeout, Net::OpenTimeout, SocketError, EOFError => e
raise TransientError, "#{e.class}: #{e.message}"
end
|
#validate_credentials! ⇒ Object
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/providers/anthropic.rb', line 100
def validate_credentials!
response = self.class.post(
"/v1/messages",
body: {
model: VALIDATION_MODEL,
messages: [{role: "user", content: "Hi"}],
max_tokens: 1
}.to_json,
headers:
)
case response.code
when 200
true
when 401
raise AuthenticationError,
"Token rejected by Anthropic API (401). Re-run `claude setup-token` and use the TUI token setup (Ctrl+a → a)."
when 403
raise AuthenticationError,
"Token not authorized for API access (403). This credential may be restricted to Claude Code only."
else
handle_response(response)
end
end
|