openrouter_client 0.1.1 → 0.1.2

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: 1dfa50003cbe411f1e237d47c2872e053bbe649253abe52df64da017071bf791
4
- data.tar.gz: 6279dcb4868bf470016c0df6cfe45fd3c5ebc19284cb7eb54d8d8d6c6ca78bb1
3
+ metadata.gz: f98e5959581fadc509a596c15ef862b8432d5355605e3c36c0fdefb0cb4dcf28
4
+ data.tar.gz: 04e7534567aa13c34c26a159a2df648a69cd13e1233f7c3e8ecb137f56935986
5
5
  SHA512:
6
- metadata.gz: 20fa68b2374b7be8f14b0833fa794d3f2d52f0aea344a2707ab9d3330a6a8c43da36e2f7d27681af2a8a2a8ecfeb926bdb70b7f86819e904b38b76aa1c4f2156
7
- data.tar.gz: ecc2aecf1224b2c5ddc1207780ebbc9014a07fd568969d2fda199cdfeaa46ea93ec8badbdacfca74cb6357c3f98ed171e144f584aef2782bfdf50c811ddab100
6
+ metadata.gz: d4d992b00d394aefb85553611fbce0e3d516f3ae93c35aeb243e171bf0f5493672fae79a8ee79666145a691a3aef14f68a40bda609a115bec058a48d86348e31
7
+ data.tar.gz: 164ee4e2f29f5991c872ad79cfeadd3496744f6c729d911eb3e42e7430a009a33b6fd8adaf8a6abe21aa87647d8fc8fe664a395a287fcbb523070c2341bc6d50
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- openrouter_client (0.1.1)
4
+ openrouter_client (0.1.2)
5
5
  faraday (>= 1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -215,6 +215,16 @@ model = OpenRouter::Model.find_by!(id: "openai/gpt-4")
215
215
  puts model.name # => "GPT-4"
216
216
  puts model.context_length # => 8192
217
217
  puts model.input_price # => 0.00003 (per token)
218
+
219
+ # Endpoints (available providers for this model)
220
+ model.endpoints.each do |endpoint|
221
+ puts endpoint.provider_name # => "OpenAI"
222
+ puts endpoint.context_length # => 8192
223
+ puts endpoint.prompt_price # => 0.00003
224
+ puts endpoint.completion_price # => 0.00006
225
+ puts endpoint.available? # => true
226
+ puts endpoint.supports?(:tools) # => true
227
+ end
218
228
  puts model.output_price # => 0.00006 (per token)
219
229
  puts model.free? # => false
220
230
 
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OpenRouter
4
+ # Represents a specific endpoint/provider for a model.
5
+ # Models can have multiple endpoints from different providers with different pricing and capabilities.
6
+ class Endpoint
7
+ # @return [String] Endpoint name
8
+ attr_reader :name
9
+ # @return [String] Model name
10
+ attr_reader :model_name
11
+ # @return [Integer] Context length in tokens
12
+ attr_reader :context_length
13
+ # @return [Hash] Pricing information
14
+ attr_reader :pricing
15
+ # @return [String] Provider name (e.g., "OpenAI", "Azure")
16
+ attr_reader :provider_name
17
+ # @return [String, nil] Tag
18
+ attr_reader :tag
19
+ # @return [Hash, nil] Quantization info
20
+ attr_reader :quantization
21
+ # @return [Integer, nil] Maximum completion tokens
22
+ attr_reader :max_completion_tokens
23
+ # @return [Integer, nil] Maximum prompt tokens
24
+ attr_reader :max_prompt_tokens
25
+ # @return [Array<String>] Supported parameters
26
+ attr_reader :supported_parameters
27
+ # @return [String, nil] Endpoint status
28
+ attr_reader :status
29
+ # @return [Float, nil] Uptime in the last 30 minutes
30
+ attr_reader :uptime_last_30m
31
+ # @return [Boolean] Whether the endpoint supports implicit caching
32
+ attr_reader :supports_implicit_caching
33
+
34
+ # @param attributes [Hash] Raw attributes from OpenRouter API
35
+ def initialize(attributes)
36
+ @name = attributes["name"]
37
+ @model_name = attributes["model_name"]
38
+ @context_length = attributes["context_length"]
39
+ @pricing = attributes["pricing"]
40
+ @provider_name = attributes["provider_name"]
41
+ @tag = attributes["tag"]
42
+ @quantization = attributes["quantization"]
43
+ @max_completion_tokens = attributes["max_completion_tokens"]
44
+ @max_prompt_tokens = attributes["max_prompt_tokens"]
45
+ @supported_parameters = attributes["supported_parameters"] || []
46
+ @status = attributes["status"]
47
+ @uptime_last_30m = attributes["uptime_last_30m"]
48
+ @supports_implicit_caching = attributes["supports_implicit_caching"] || false
49
+ end
50
+
51
+ # Get the prompt/input price per token.
52
+ # @return [Float, nil]
53
+ def prompt_price
54
+ @pricing&.dig("prompt")&.to_f
55
+ end
56
+
57
+ # Get the completion/output price per token.
58
+ # @return [Float, nil]
59
+ def completion_price
60
+ @pricing&.dig("completion")&.to_f
61
+ end
62
+
63
+ # Get the image price.
64
+ # @return [Float, nil]
65
+ def image_price
66
+ @pricing&.dig("image")&.to_f
67
+ end
68
+
69
+ # Get any discount percentage.
70
+ # @return [Float, nil]
71
+ def discount
72
+ @pricing&.dig("discount")&.to_f
73
+ end
74
+
75
+ # Check if this endpoint is free.
76
+ # @return [Boolean]
77
+ def free?
78
+ prompt_price&.zero? && completion_price&.zero?
79
+ end
80
+
81
+ # Check if this endpoint is currently available.
82
+ # Status "0" indicates the endpoint is healthy.
83
+ # @return [Boolean]
84
+ def available?
85
+ @status == "0"
86
+ end
87
+
88
+ # Check if this endpoint supports a specific parameter.
89
+ # @param parameter [String, Symbol] The parameter to check
90
+ # @return [Boolean]
91
+ def supports?(parameter)
92
+ @supported_parameters.include?(parameter.to_s)
93
+ end
94
+ end
95
+ end
@@ -18,7 +18,7 @@ module OpenRouter
18
18
  attr_reader :pricing
19
19
  # @return [Integer, nil] Top provider information
20
20
  attr_reader :top_provider
21
- # @return [String, nil] Model architecture
21
+ # @return [Hash, nil] Model architecture
22
22
  attr_reader :architecture
23
23
  # @return [Array<String>, nil] Supported parameters
24
24
  attr_reader :supported_parameters
@@ -26,6 +26,8 @@ module OpenRouter
26
26
  attr_reader :per_request_limits
27
27
  # @return [String, nil] Created timestamp
28
28
  attr_reader :created
29
+ # @return [Array<OpenRouter::Endpoint>, nil] Available endpoints for this model
30
+ attr_reader :endpoints
29
31
 
30
32
  # @param attributes [Hash] Raw attributes from OpenRouter API
31
33
  # @param client [OpenRouter::Client] HTTP client
@@ -68,26 +70,32 @@ module OpenRouter
68
70
 
69
71
  class << self
70
72
  # Find a specific model by ID. Raises NotFoundError if not found.
71
- # @param id [String] The model identifier
73
+ # @param id [String] The model identifier (e.g., "openai/gpt-4")
72
74
  # @param client [OpenRouter::Client] HTTP client
73
75
  # @return [OpenRouter::Model]
74
76
  # @raise [OpenRouter::NotFoundError] if model not found
75
77
  def find(id, client: OpenRouter.client)
76
- model = find_by(id: id, client: client)
77
- raise NotFoundError, "Model not found: #{id}" unless model
78
+ author, slug = parse_model_id(id)
79
+ path = "#{MODELS_PATH}/#{author}/#{slug}/endpoints"
80
+
81
+ response = client.get(path)
82
+ return new(response["data"], client: client) if response && response["data"]
78
83
 
79
- model
84
+ raise NotFoundError, "Model not found: #{id}"
85
+ rescue NotFoundError
86
+ raise
87
+ rescue OpenRouter::Error
88
+ raise NotFoundError, "Model not found: #{id}"
80
89
  end
81
90
 
82
91
  # Find a specific model by ID. Returns nil if not found.
83
- # @param id [String] The model identifier
92
+ # @param id [String] The model identifier (e.g., "openai/gpt-4")
84
93
  # @param client [OpenRouter::Client] HTTP client
85
94
  # @return [OpenRouter::Model, nil]
86
95
  def find_by(id:, client: OpenRouter.client)
87
- response = client.get(MODELS_PATH)
88
- models = Array(response && response["data"])
89
- entry = models.find { |model| model["id"] == id }
90
- entry ? new(entry, client: client) : nil
96
+ find(id, client: client)
97
+ rescue NotFoundError
98
+ nil
91
99
  end
92
100
 
93
101
  # Find a specific model by ID. Raises NotFoundError if not found.
@@ -144,6 +152,19 @@ module OpenRouter
144
152
  def free(client: OpenRouter.client)
145
153
  all(client: client).select(&:free?)
146
154
  end
155
+
156
+ private
157
+
158
+ # Parse a model ID into author and slug components.
159
+ # @param id [String] The model identifier (e.g., "openai/gpt-4")
160
+ # @return [Array<String>] [author, slug]
161
+ # @raise [ArgumentError] if the ID format is invalid
162
+ def parse_model_id(id)
163
+ parts = id.to_s.split("/", 2)
164
+ raise ArgumentError, "Invalid model ID format: #{id}. Expected 'author/slug'" if parts.length != 2
165
+
166
+ parts
167
+ end
147
168
  end
148
169
 
149
170
  private
@@ -159,6 +180,13 @@ module OpenRouter
159
180
  @supported_parameters = attributes["supported_parameters"]
160
181
  @per_request_limits = attributes["per_request_limits"]
161
182
  @created = attributes["created"]
183
+ @endpoints = build_endpoints(attributes["endpoints"])
184
+ end
185
+
186
+ def build_endpoints(endpoints_data)
187
+ return nil unless endpoints_data
188
+
189
+ endpoints_data.map { |attrs| OpenRouter::Endpoint.new(attrs) }
162
190
  end
163
191
  end
164
192
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OpenRouter
4
- VERSION = "0.1.1"
4
+ VERSION = "0.1.2"
5
5
  end
data/lib/openrouter.rb CHANGED
@@ -113,6 +113,7 @@ end
113
113
  require_relative "openrouter/client"
114
114
  require_relative "openrouter/completion"
115
115
  require_relative "openrouter/stream"
116
+ require_relative "openrouter/endpoint"
116
117
  require_relative "openrouter/model"
117
118
  require_relative "openrouter/generation"
118
119
  require_relative "openrouter/credit"
@@ -0,0 +1,69 @@
1
+ # typed: strict
2
+ # frozen_string_literal: true
3
+
4
+ module OpenRouter
5
+ class Endpoint
6
+ sig { returns(String) }
7
+ def name; end
8
+
9
+ sig { returns(String) }
10
+ def model_name; end
11
+
12
+ sig { returns(Integer) }
13
+ def context_length; end
14
+
15
+ sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
16
+ def pricing; end
17
+
18
+ sig { returns(String) }
19
+ def provider_name; end
20
+
21
+ sig { returns(T.nilable(String)) }
22
+ def tag; end
23
+
24
+ sig { returns(T.nilable(T::Hash[T.untyped, T.untyped])) }
25
+ def quantization; end
26
+
27
+ sig { returns(T.nilable(Integer)) }
28
+ def max_completion_tokens; end
29
+
30
+ sig { returns(T.nilable(Integer)) }
31
+ def max_prompt_tokens; end
32
+
33
+ sig { returns(T::Array[String]) }
34
+ def supported_parameters; end
35
+
36
+ sig { returns(T.nilable(String)) }
37
+ def status; end
38
+
39
+ sig { returns(T.nilable(Float)) }
40
+ def uptime_last_30m; end
41
+
42
+ sig { returns(T::Boolean) }
43
+ def supports_implicit_caching; end
44
+
45
+ sig { params(attributes: T.untyped).void }
46
+ def initialize(attributes); end
47
+
48
+ sig { returns(T.nilable(Float)) }
49
+ def prompt_price; end
50
+
51
+ sig { returns(T.nilable(Float)) }
52
+ def completion_price; end
53
+
54
+ sig { returns(T.nilable(Float)) }
55
+ def image_price; end
56
+
57
+ sig { returns(T.nilable(Float)) }
58
+ def discount; end
59
+
60
+ sig { returns(T::Boolean) }
61
+ def free?; end
62
+
63
+ sig { returns(T::Boolean) }
64
+ def available?; end
65
+
66
+ sig { params(parameter: T.any(String, Symbol)).returns(T::Boolean) }
67
+ def supports?(parameter); end
68
+ end
69
+ end
@@ -35,6 +35,9 @@ module OpenRouter
35
35
  sig { returns(T.nilable(String)) }
36
36
  def created; end
37
37
 
38
+ sig { returns(T.nilable(T::Array[OpenRouter::Endpoint])) }
39
+ def endpoints; end
40
+
38
41
  sig { params(attributes: T.untyped, client: OpenRouter::Client).void }
39
42
  def initialize(attributes, client: OpenRouter.client); end
40
43
 
@@ -82,11 +85,19 @@ module OpenRouter
82
85
 
83
86
  sig { params(client: OpenRouter::Client).returns(T::Array[OpenRouter::Model]) }
84
87
  def free(client: OpenRouter.client); end
88
+
89
+ private
90
+
91
+ sig { params(id: String).returns([String, String]) }
92
+ def parse_model_id(id); end
85
93
  end
86
94
 
87
95
  private
88
96
 
89
97
  sig { params(attributes: T.untyped).void }
90
98
  def reset_attributes(attributes); end
99
+
100
+ sig { params(endpoints_data: T.nilable(T::Array[T::Hash[T.untyped, T.untyped]])).returns(T.nilable(T::Array[OpenRouter::Endpoint])) }
101
+ def build_endpoints(endpoints_data); end
91
102
  end
92
103
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openrouter_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dylan Player
@@ -44,6 +44,7 @@ files:
44
44
  - lib/openrouter/client.rb
45
45
  - lib/openrouter/completion.rb
46
46
  - lib/openrouter/credit.rb
47
+ - lib/openrouter/endpoint.rb
47
48
  - lib/openrouter/generation.rb
48
49
  - lib/openrouter/model.rb
49
50
  - lib/openrouter/stream.rb
@@ -53,6 +54,7 @@ files:
53
54
  - rbi/openrouter/client.rbi
54
55
  - rbi/openrouter/completion.rbi
55
56
  - rbi/openrouter/credit.rbi
57
+ - rbi/openrouter/endpoint.rbi
56
58
  - rbi/openrouter/generation.rbi
57
59
  - rbi/openrouter/model.rbi
58
60
  - rbi/openrouter/openrouter.rbi