voyageai 1.1.0 → 1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a2fc61d8673a96f88ae7e69d9cfb27f00c741f077fd05793ff921e27c0fd869a
4
- data.tar.gz: 4734e6ac573b6251ca1789a37fbf9a9db8294c5e82d63b51613b20bfea793e10
3
+ metadata.gz: 8d127480aae597e6c15b398061d16beded7be8961fd433372b2550ea1b643d37
4
+ data.tar.gz: 0a958352786d2994de9bdfbbb198850e15d245a9aed6971efae0f30518494878
5
5
  SHA512:
6
- metadata.gz: d403d37213b6f9666fbafb58fbc82fcbb9752be9e5d29a9e88d34ea6a198f43d860e809e2d890906bf0c298254d9054fcace76d3e5e8e3f70620abd8d27ec791
7
- data.tar.gz: f1ad0fcaf76b8a0a0296dc46507c46d6d9b7e2f47a21b6ca9e2d7e8140483c18ece161ff4570db71649c344679b7a92e80287648324a3700c720e00a7b6e2854
6
+ metadata.gz: 346dc805e9a46813198189b83805a6d2718cb1a4c244af08f8a1fb5cc4cc251f0fd7ff1b06104669b588da56b5d8fcda3f06795a64fac5a2ee7dc6e8e86faa1f
7
+ data.tar.gz: 9cf273cdbf521f0b13fc9b30a58517ae7ebdfce1cb23801e64630bcf4887f17d4ed61058d0eb72533fe801e221a7a1fe91df84b802cb5266d7a405af7b68981a
data/README.md CHANGED
@@ -44,3 +44,17 @@ embed.model # "..."
44
44
  embed.usage # "#<VoyageAI::Usage total_tokens=...>"
45
45
  embed.embeddings # [[0.0, ...], ...]
46
46
  ```
47
+
48
+ ## Configuration
49
+
50
+ ```ruby
51
+ require 'voyageai'
52
+
53
+ VoyageAI.configure do |config|
54
+ config.api_key = 'pa-...' # defaults to ENV['VOYAGEAI_API_KEY']
55
+ config.host = 'https://api.voyageai.com'
56
+ config.version = 'v1'
57
+ config.timeout = 15 # seconds
58
+ config.logger = Logger.new(STDOUT)
59
+ end
60
+ ```
@@ -3,8 +3,6 @@
3
3
  module VoyageAI
4
4
  # A client for interacting with the VoyageAI API.
5
5
  class Client
6
- BASE_URL = "https://api.voyageai.com/v1"
7
-
8
6
  # An error raised for any HTTP issues.
9
7
  class RequestError < StandardError
10
8
  attr_accessor :response
@@ -17,27 +15,35 @@ module VoyageAI
17
15
  end
18
16
 
19
17
  # @param api_key [String] optional if ENV['VOYAGEAI_API_KEY'] otherwise required
20
- def initialize(api_key: ENV.fetch("VOYAGEAI_API_KEY", nil))
18
+ # @param host [String] optional
19
+ # @param version [String] optional
20
+ # @param logger [Logger] optional
21
+ def initialize(
22
+ api_key: VoyageAI.config.api_key,
23
+ host: VoyageAI.config.host,
24
+ version: VoyageAI.config.version,
25
+ logger: VoyageAI.config.logger
26
+ )
21
27
  @api_key = api_key || raise(ArgumentError, "api_key is required or ENV['VOYAGEAI_API_KEY'] must be present")
28
+ @host = host
29
+ @version = version
30
+ @logger = logger
22
31
  end
23
32
 
24
33
  # @return [String]
25
34
  def inspect
26
35
  masked_api_key = "#{@api_key[..4]}***"
27
36
 
28
- "#<#{self.class.name} api_key=#{masked_api_key.inspect}>"
37
+ "#<#{self.class.name} api_key=#{masked_api_key.inspect} host=#{@host.inspect} version=#{@version.inspect}>"
29
38
  end
30
39
 
31
40
  # @param model [String] optional (e.g. VoyageAI::Model::VOYAGE or "voyage-3")
32
- # @param input [Array<String>] required (e.g. ["Sample 1", "Sample 2", ...])
41
+ # @param input [String, Array<String>] required (e.g. "Sample" or ["Sample 1", "Sample 2", ...])
33
42
  #
34
43
  # @return [Embedding]
35
44
  def embed(input, model: Model::VOYAGE)
36
45
  payload = { input: arrayify(input), model: model }
37
- response = HTTP
38
- .accept(:json)
39
- .auth("Bearer #{@api_key}")
40
- .post("#{BASE_URL}/embeddings", json: payload)
46
+ response = http.accept(:json).post("/#{@version}/embeddings", json: payload)
41
47
 
42
48
  raise RequestError.new(response:) unless response.status.ok?
43
49
 
@@ -46,6 +52,16 @@ module VoyageAI
46
52
 
47
53
  private
48
54
 
55
+ # @return [HTTP::Client]
56
+ def http
57
+ @http ||= begin
58
+ http = HTTP.auth("Bearer #{@api_key}").persistent(@host)
59
+ http = http.use(instrumentation: { instrumenter: Instrumentation.new(logger: @logger) }) if @logger
60
+ http = http.timeout(@timeout) if @timeout
61
+ http
62
+ end
63
+ end
64
+
49
65
  def arrayify(input)
50
66
  input.is_a?(Array) ? input : [input]
51
67
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VoyageAI
4
+ # A configuration for VoyageAI.
5
+ #
6
+ # @example:
7
+ # VoyageAI.configure do |config|
8
+ # config.api_key = '...'
9
+ # config.host = 'https://api.voyageai.com'
10
+ # config.version = 'v1'
11
+ # config.logger = Logger.new(STDOUT)
12
+ # config.timeout = 15
13
+ # end
14
+ class Config
15
+ DEFAULT_HOST = "https://api.voyageai.com"
16
+ DEFAULT_VERSION = "v1"
17
+
18
+ # @!attribute [rw] api_key
19
+ # @return [String, nil]
20
+ attr_accessor :api_key
21
+
22
+ # @!attribute [rw] host
23
+ # @return [String, nil]
24
+ attr_accessor :host
25
+
26
+ # @!attribute [rw] version
27
+ # @return [String, nil]
28
+ attr_accessor :version
29
+
30
+ # @!attribute [rw] logger
31
+ # @return [Logger, nil]
32
+ attr_accessor :logger
33
+
34
+ # @!attribute [rw] timeout
35
+ # @return [Integer, nil]
36
+ attr_accessor :timeout
37
+
38
+ # @param api_key [String] optional - defaults to `ENV['VOYAGE_API_KEY']`
39
+ # @param host [String] optional - defaults to `ENV['VOYAGEAI_HOST']`` w/ fallback to `https://api.voyageai.com`
40
+ # @param version [String] optional - defaults to `ENV['DEFAULT_VERSION']` w/ fallback to `v1`
41
+ # @param logger [Logger] optional
42
+ # @param timeout [Integer] optional
43
+ def initialize(
44
+ api_key: ENV.fetch("VOYAGEAI_API_KEY", nil),
45
+ host: ENV.fetch("VOYAGEAI_HOST", DEFAULT_HOST),
46
+ version: ENV.fetch("VOYAGEAI_VERSION", DEFAULT_VERSION),
47
+ logger: nil,
48
+ timeout: nil
49
+ )
50
+ @api_key = api_key
51
+ @host = host
52
+ @version = version
53
+ @logger = logger
54
+ @timeout = timeout
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module VoyageAI
4
+ # Used for logging via HTTP.
5
+ class Instrumentation
6
+ # @param logger [Logger]
7
+ def initialize(logger:)
8
+ @logger = logger
9
+ end
10
+
11
+ # @param name [String]
12
+ # @param payload [Hash]
13
+ # @option payload [Exception] :error
14
+ def instrument(name, payload = {})
15
+ error = payload[:error]
16
+ return unless error
17
+
18
+ @logger.error("#{name}: #{error.message}")
19
+ end
20
+
21
+ # @param payload [Hash]
22
+ # @option payload [HTTP::Request] :request
23
+ def start(_, payload)
24
+ request = payload[:request]
25
+ @logger.info("#{request.verb.upcase} #{request.uri}")
26
+ end
27
+
28
+ # @param payload [Hash]
29
+ # @option payload [HTTP::Response] :response
30
+ def finish(_, payload)
31
+ response = payload[:response]
32
+ @logger.info("#{response.status.code} #{response.status.reason}")
33
+ end
34
+ end
35
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module VoyageAI
4
- VERSION = "1.1.0"
4
+ VERSION = "1.2.0"
5
5
  end
data/lib/voyageai.rb CHANGED
@@ -7,6 +7,15 @@ loader = Zeitwerk::Loader.for_gem
7
7
  loader.inflector.inflect "voyageai" => "VoyageAI"
8
8
  loader.setup
9
9
 
10
+ # The main entrypoint for VoyageAI.
10
11
  module VoyageAI
11
- class Error < StandardError; end
12
+ # @return [VoyageAI::Config]
13
+ def self.config
14
+ @config ||= Config.new
15
+ end
16
+
17
+ # @yield [VoyageAI::Config]
18
+ def self.configure
19
+ yield config
20
+ end
12
21
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: voyageai
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-21 00:00:00.000000000 Z
11
+ date: 2024-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http
@@ -38,7 +38,7 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description: A library for generating embeddings with https://voyageai.com.
41
+ description: A library for generating embeddings with https://voyageai.com
42
42
  email:
43
43
  - kevin@ksylvest.com
44
44
  executables: []
@@ -51,16 +51,18 @@ files:
51
51
  - bin/setup
52
52
  - lib/voyageai.rb
53
53
  - lib/voyageai/client.rb
54
+ - lib/voyageai/config.rb
54
55
  - lib/voyageai/embed.rb
56
+ - lib/voyageai/instrumentation.rb
55
57
  - lib/voyageai/model.rb
56
58
  - lib/voyageai/usage.rb
57
59
  - lib/voyageai/version.rb
58
- homepage: https://github.com/ksylvest/voyageai.
60
+ homepage: https://github.com/ksylvest/voyageai
59
61
  licenses:
60
62
  - MIT
61
63
  metadata:
62
- homepage_uri: https://github.com/ksylvest/voyageai.
63
- changelog_uri: https://github.com/ksylvest/voyageai./releases
64
+ homepage_uri: https://github.com/ksylvest/voyageai
65
+ changelog_uri: https://github.com/ksylvest/voyageai/releases
64
66
  rubygems_mfa_required: 'true'
65
67
  post_install_message:
66
68
  rdoc_options: []