anthropic-rb 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- data/.reek.yml +7 -0
- data/CHANGELOG.md +7 -0
- data/README.md +67 -1
- data/lib/anthropic/client.rb +108 -0
- data/lib/anthropic/completions.rb +54 -0
- data/lib/anthropic/version.rb +1 -1
- data/lib/anthropic.rb +37 -0
- metadata +34 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a00be2a4defb2218b159f10759e861f3f4d314909fb9205bb11cb79dd4460eec
|
4
|
+
data.tar.gz: 6cb65d16c68d5fc58094210ebd271908c58e1927366887d64ef59100aced49cf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f6c0aadeacd66bddd7ab58393cb86a3b50d1e99eb8df9d0e6fe076376c71ef0f2430f864666420af180f5da828d770ced1128dbeb59f77cf8d2f28df28b699c8
|
7
|
+
data.tar.gz: 4df1ea4f97c164bee7cbe1a2a7f92c57a1a507220a2ec62c4d9442978674b1d5b5197092ecba83f77a1ef302919b35357adcda22a4c41e9e90098ccd459e7497
|
data/.reek.yml
ADDED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,12 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
1
3
|
## [Unreleased]
|
2
4
|
|
3
5
|
## [0.1.0] - 2023-11-30
|
4
6
|
|
7
|
+
### Added
|
8
|
+
|
5
9
|
- Initial release
|
10
|
+
|
11
|
+
[Unreleased]: https://github.com/d3d1rty/event_logger_rails/compare/0.1.0...HEAD
|
12
|
+
[0.1.0]: https://github.com/d3d1rty/event_logger_rails/releases/tag/0.1.0
|
data/README.md
CHANGED
@@ -2,9 +2,75 @@
|
|
2
2
|
|
3
3
|
Ruby bindings for the Anthropic API. This library is unofficial and is not affiliated with Anthropic PBC.
|
4
4
|
|
5
|
+
The goal of this project is feature parity with Anthropic's Python SDK until an official Ruby SDK is available.
|
6
|
+
|
5
7
|
## Usage
|
6
8
|
|
7
|
-
|
9
|
+
anthropic-rb will default to the value of the `ANTHROPIC_API_KEY` environment variable. However, you may initialize the library with your API key:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
require 'anthropic-rb'
|
13
|
+
|
14
|
+
Anthropic.setup do |config|
|
15
|
+
config.api_key = 'YOUR_API_KEY'
|
16
|
+
end
|
17
|
+
```
|
18
|
+
|
19
|
+
You can also specify an API version to use by setting the `ANTHROPIC_API_VERSION` environment variable or during initialization:
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
require 'anthropic-rb'
|
23
|
+
|
24
|
+
Anthropic.setup do |config|
|
25
|
+
config.api_version = '2023-06-01'
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
The default API version is `2023-06-01`.
|
30
|
+
|
31
|
+
To make a request to the Completions API:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
Anthropic.completions.create(
|
35
|
+
model: 'claude-2',
|
36
|
+
max_tokens_to_sample: 200,
|
37
|
+
prompt: 'Human: Yo what up?\n\nAssistant:'
|
38
|
+
)
|
39
|
+
|
40
|
+
# Output =>
|
41
|
+
# {
|
42
|
+
# completion: "Hello! Not much going on with me, just chatting. How about you?",
|
43
|
+
# stop_reason: "stop_sequence",
|
44
|
+
# model: "claude-2.1",
|
45
|
+
# stop: "\n\nHuman:",
|
46
|
+
# log_id: "2496914137c520ec2b4ae8315864bcf3a4c6ce9f2e3c96e13be4c004587313ca"
|
47
|
+
# }
|
48
|
+
```
|
49
|
+
|
50
|
+
Alternatively, you can stream the response:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
Anthropic.completions.create(model: 'claude-2', max_tokens_to_sample: 200, prompt: 'Human: Yo what up?\n\nAssistant:') do |event|
|
54
|
+
puts event
|
55
|
+
end
|
56
|
+
|
57
|
+
# Output =>
|
58
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" Hello", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
59
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>"!", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
60
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" Not", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
61
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" much", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
62
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>",", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
63
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" just", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
64
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" chatting", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
65
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" with", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
66
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" people", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
67
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>".", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
68
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" How", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
69
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" about", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
70
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>" you", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
71
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>"?", :stop_reason=>nil, :model=>"claude-2.1", :stop=>nil, :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
72
|
+
# {:type=>"completion", :id=>"compl_01G6cEfdZtLEEJVRzwUShiDY", :completion=>"", :stop_reason=>"stop_sequence", :model=>"claude-2.1", :stop=>"\n\nHuman:", :log_id=>"compl_01G6cEfdZtLEEJVRzwUShiDY"}
|
73
|
+
```
|
8
74
|
|
9
75
|
## Installation
|
10
76
|
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'httpx'
|
4
|
+
|
5
|
+
module Anthropic
|
6
|
+
##
|
7
|
+
# Error when the request is malformed.
|
8
|
+
class BadRequestError < StandardError; end
|
9
|
+
##
|
10
|
+
# Error when the API key is invalid.
|
11
|
+
class AuthenticationError < StandardError; end
|
12
|
+
##
|
13
|
+
# Error when the account does not have permission for the operation.
|
14
|
+
class PermissionDeniedError < StandardError; end
|
15
|
+
##
|
16
|
+
# Error when the resource is not found.
|
17
|
+
class NotFoundError < StandardError; end
|
18
|
+
##
|
19
|
+
# Error when the resource already exists.
|
20
|
+
class ConflictError < StandardError; end
|
21
|
+
##
|
22
|
+
# Error when the resource cannot be processed.
|
23
|
+
class UnprocessableEntityError < StandardError; end
|
24
|
+
##
|
25
|
+
# Error when the request exceeds the rate limit.
|
26
|
+
class RateLimitError < StandardError; end
|
27
|
+
##
|
28
|
+
# Error when the server experienced an internal error.
|
29
|
+
class InternalServerError < StandardError; end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Provides a client for sending HTTP requests.
|
33
|
+
class Client
|
34
|
+
# rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
35
|
+
def self.post(url, data)
|
36
|
+
response = HTTPX.with(
|
37
|
+
headers: {
|
38
|
+
'Content-Type' => 'application/json',
|
39
|
+
'x-api-key' => Anthropic.api_key,
|
40
|
+
'anthropic-version' => Anthropic.api_version
|
41
|
+
}
|
42
|
+
).post(url, json: data)
|
43
|
+
|
44
|
+
response_body = JSON.parse(response.body, symbolize_names: true)
|
45
|
+
|
46
|
+
case response.status
|
47
|
+
when 200
|
48
|
+
response_body
|
49
|
+
when 400
|
50
|
+
raise Anthropic::BadRequestError, response_body
|
51
|
+
when 401
|
52
|
+
raise Anthropic::AuthenticationError, response_body
|
53
|
+
when 403
|
54
|
+
raise Anthropic::PermissionDeniedError, response_body
|
55
|
+
when 404
|
56
|
+
raise Anthropic::NotFoundError, response_body
|
57
|
+
when 409
|
58
|
+
raise Anthropic::ConflictError, response_body
|
59
|
+
when 422
|
60
|
+
raise Anthropic::UnprocessableEntityError, response_body
|
61
|
+
when 429
|
62
|
+
raise Anthropic::RateLimitError, response_body
|
63
|
+
when 500
|
64
|
+
raise Anthropic::InternalServerError, response_body
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.post_as_stream(url, data)
|
69
|
+
response = HTTPX.plugin(:stream).with(
|
70
|
+
headers: {
|
71
|
+
'Content-Type' => 'application/json',
|
72
|
+
'x-api-key' => Anthropic.api_key,
|
73
|
+
'anthropic-version' => Anthropic.api_version
|
74
|
+
}
|
75
|
+
).post(url, json: data, stream: true)
|
76
|
+
|
77
|
+
response.each_line do |line|
|
78
|
+
event, data = line.split(/(\w+\b:\s)/)[1..2]
|
79
|
+
next unless event && data
|
80
|
+
|
81
|
+
if event.start_with?('data')
|
82
|
+
formatted_data = JSON.parse(data, symbolize_names: true)
|
83
|
+
yield formatted_data unless %w[ping error].include?(formatted_data[:type])
|
84
|
+
end
|
85
|
+
end
|
86
|
+
rescue HTTPX::HTTPError => error
|
87
|
+
case error.response.status
|
88
|
+
when 400
|
89
|
+
raise Anthropic::BadRequestError
|
90
|
+
when 401
|
91
|
+
raise Anthropic::AuthenticationError
|
92
|
+
when 403
|
93
|
+
raise Anthropic::PermissionDeniedError
|
94
|
+
when 404
|
95
|
+
raise Anthropic::NotFoundError
|
96
|
+
when 409
|
97
|
+
raise Anthropic::ConflictError
|
98
|
+
when 422
|
99
|
+
raise Anthropic::UnprocessableEntityError
|
100
|
+
when 429
|
101
|
+
raise Anthropic::RateLimitError
|
102
|
+
when 500
|
103
|
+
raise Anthropic::InternalServerError
|
104
|
+
end
|
105
|
+
end
|
106
|
+
# rubocop:enable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
|
107
|
+
end
|
108
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Anthropic
|
4
|
+
##
|
5
|
+
# Provides bindings for the Anthropic completions API
|
6
|
+
class Completions
|
7
|
+
# Error for when the API version is not supported.
|
8
|
+
class UnsupportedApiVersionError < StandardError; end
|
9
|
+
|
10
|
+
V1_SCHEMA = {
|
11
|
+
type: 'object',
|
12
|
+
required: %w[model prompt max_tokens_to_sample],
|
13
|
+
properties: {
|
14
|
+
model: { type: 'string' },
|
15
|
+
prompt: { type: 'string' },
|
16
|
+
max_tokens_to_sample: { type: 'integer' },
|
17
|
+
stop_sequences: { type: 'array', items: { type: 'string' } },
|
18
|
+
temperature: { type: 'number' },
|
19
|
+
top_k: { type: 'integer' },
|
20
|
+
top_p: { type: 'number' },
|
21
|
+
metadata: { type: 'object' },
|
22
|
+
stream: { type: 'boolean' }
|
23
|
+
},
|
24
|
+
additionalProperties: false
|
25
|
+
}.freeze
|
26
|
+
|
27
|
+
def initialize
|
28
|
+
@endpoint = 'https://api.anthropic.com/v1/complete'
|
29
|
+
end
|
30
|
+
|
31
|
+
def create(**params, &)
|
32
|
+
JSON::Validator.validate!(schema_for_api_version, params)
|
33
|
+
return Anthropic::Client.post(endpoint, params) unless params[:stream]
|
34
|
+
|
35
|
+
Anthropic::Client.post_as_stream(endpoint, params, &)
|
36
|
+
rescue JSON::Schema::ValidationError => error
|
37
|
+
raise ArgumentError, error.message
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
attr_reader :endpoint
|
43
|
+
|
44
|
+
def schema_for_api_version
|
45
|
+
api_version = Anthropic.api_version
|
46
|
+
case api_version
|
47
|
+
when '2023-06-01'
|
48
|
+
V1_SCHEMA
|
49
|
+
else
|
50
|
+
raise UnsupportedApiVersionError, "Unsupported API version: #{api_version}"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/anthropic/version.rb
CHANGED
data/lib/anthropic.rb
CHANGED
@@ -1,9 +1,46 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'httpx'
|
4
|
+
require 'json'
|
5
|
+
require 'json-schema'
|
6
|
+
|
7
|
+
require_relative 'anthropic/client'
|
8
|
+
require_relative 'anthropic/completions'
|
3
9
|
require_relative 'anthropic/version'
|
4
10
|
|
11
|
+
##
|
12
|
+
# Namespace for anthropic-rb gem
|
5
13
|
module Anthropic
|
6
14
|
##
|
7
15
|
# Default error class
|
8
16
|
class Error < StandardError; end
|
17
|
+
|
18
|
+
def self.setup
|
19
|
+
yield self
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.reset
|
23
|
+
@api_key = nil
|
24
|
+
@api_version = nil
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.api_key
|
28
|
+
@api_key || ENV.fetch('ANTHROPIC_API_KEY', nil)
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.api_key=(api_key = nil)
|
32
|
+
@api_key = api_key
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.api_version
|
36
|
+
@api_version || ENV.fetch('ANTHROPIC_API_VERSION', '2023-06-01')
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.api_version=(api_version = nil)
|
40
|
+
@api_version = api_version
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.completions
|
44
|
+
Completions.new
|
45
|
+
end
|
9
46
|
end
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: anthropic-rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dick Davis
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-12-
|
12
|
-
dependencies:
|
11
|
+
date: 2023-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httpx
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.1.5
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.1.5
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: json-schema
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 4.1.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 4.1.1
|
13
41
|
description:
|
14
42
|
email:
|
15
43
|
- dick@hey.com
|
@@ -18,6 +46,7 @@ extensions: []
|
|
18
46
|
extra_rdoc_files: []
|
19
47
|
files:
|
20
48
|
- ".overcommit.yml"
|
49
|
+
- ".reek.yml"
|
21
50
|
- ".rspec"
|
22
51
|
- ".rubocop.yml"
|
23
52
|
- ".tool-versions"
|
@@ -26,6 +55,8 @@ files:
|
|
26
55
|
- README.md
|
27
56
|
- Rakefile
|
28
57
|
- lib/anthropic.rb
|
58
|
+
- lib/anthropic/client.rb
|
59
|
+
- lib/anthropic/completions.rb
|
29
60
|
- lib/anthropic/version.rb
|
30
61
|
- sig/anthropic/rb.rbs
|
31
62
|
homepage: https://github.com/dickdavis/anthropic-rb
|