Skip to content

Commit

Permalink
Raises ServerError on errors. Accepts multiple models for fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
obie authored Mar 28, 2024
1 parent fe7d800 commit 1976bc4
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
26 changes: 25 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,27 @@ puts response["choices"][0]["message"]["content"]

### Models

Fetch the list of available models from the OpenRouter API:
Pass an array to the `model` parameter to enable [explicit model routing](https://openrouter.ai/docs#model-routing).

```ruby
OpenRouter::Client.new.chat_completion(
[
{ role: "system", content: SYSTEM_PROMPT },
{ role: "user", content: "Provide analysis of the data formatted as JSON:" }
],
model: [
"mistralai/mixtral-8x7b-instruct:nitro",
"mistralai/mixtral-8x7b-instruct"
],
extras: {
response_format: {
type: "json_object"
}
}
)
```

[Browse full list of models available](https://openrouter.ai/models) or fetch from the OpenRouter API:

```ruby
models = client.models
Expand All @@ -110,6 +130,10 @@ puts stats
# => {"id"=>"generation-abcdefg", "object"=>"generation", "created"=>1684195200, "model"=>"openrouter/auto", "usage"=>{"prompt_tokens"=>10, "completion_tokens"=>50, "total_tokens"=>60}, "cost"=>0.0006}
```

## Errors

The client will raise an `OpenRouter::ServerError` in the case of an error returned from a completion (or empty response).

## Contributing

Bug reports and pull requests are welcome on GitHub at <https://github.com/OlympiaAI/open_router>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/OlympiaAI/open_router/blob/main/CODE_OF_CONDUCT.md).
Expand Down
24 changes: 19 additions & 5 deletions lib/open_router/client.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# frozen_string_literal: true

require_relative "http"
require_relative 'http'

module OpenRouter
class ServerError < StandardError; end

class Client
include OpenRouter::HTTP

Expand All @@ -13,19 +15,31 @@ def initialize

# Performs a chat completion request to the OpenRouter API.
# @param messages [Array<Hash>] Array of message hashes with role and content, like [{role: "user", content: "What is the meaning of life?"}]
# @param model [String] Model identifier, defaults to 'openrouter/auto'
# @param model [String|Array] Model identifier, or array of model identifiers if you want to fallback to the next model in case of failure
# @param providers [Array<String>] Optional array of provider identifiers, ordered by priority
# @param transforms [Array<String>] Optional array of strings that tell OpenRouter to apply a series of transformations to the prompt before sending it to the model. Transformations are applied in-order
# @param extras [Hash] Optional hash of model-specific parameters to send to the OpenRouter API
# @param stream [Proc, nil] Optional callable object for streaming
# @return [Hash] The completion response.
def complete(messages, model: "openrouter/auto", providers: [], transforms: [], extras: {}, stream: nil) # rubocop:disable Metrics/ParameterLists
parameters = { model:, messages: }
def chat_completion(messages, model: 'openrouter/auto', providers: [], transforms: [], extras: {}, stream: nil)
parameters = { messages: }
if model.is_a?(String)
parameters[:model] = model
elsif model.is_a?(Array)
parameters[:models] = model
parameters[:route] = "fallback"
end
parameters[:provider] = { provider: { order: providers } } if providers.any?
parameters[:transforms] = transforms if transforms.any?
parameters[:stream] = stream if stream
parameters.merge!(extras)
json_post(path: "/chat/completions", parameters:)

puts parameters if Rails.env.local?

json_post(path: "/chat/completions", parameters:).tap do |response|
raise ServerError, "Empty response from OpenRouter. Might be worth retrying once or twice." if response.blank?
raise ServerError, response.dig("error", "message") if response.dig("error", "message").present?
end
end

# Fetches the list of available models from the OpenRouter API.
Expand Down

0 comments on commit 1976bc4

Please sign in to comment.