omniai 0.0.1 → 0.0.3

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: 54cb0309adb2c49473342a47f964d2ddb8035a42d8d8fe1d9fa6960ac0987cf4
4
- data.tar.gz: 5f6792e26172ad6383308cd98501d6b53f4607411efba7317d90c6525fbb2473
3
+ metadata.gz: 8d54c88d48becdd4c496114b93841cf6dd32ba294a5cbf9828a0d0d4d28a023e
4
+ data.tar.gz: 8f8bb67797a1fa993cd5dc202d60e78c041ec184cf8120eae170e1b821228c62
5
5
  SHA512:
6
- metadata.gz: f065076a409f5acc450eb020edbeb840d1f66ece51085b8493e2663132210e38cf02d12709e5932ecdeef88f50c8e61541c9b0d676281e7cd22e397ae9cb4f30
7
- data.tar.gz: c44b00b48485d903c9f44f63137367fc71a0bf97c38d1d80274f8a51073339125ddbfeb1a427bbd459b496e4fe1c8f7921c5e5c7534af1499a2471621c3be6d5
6
+ metadata.gz: 8f0a3651c5eb608d0aba74c8c8ae06d4def73fc519fc4cbef6c8b2a8c3434d00cd469e24eaafc8f07193cb028c93984e459c7ffc65e89e56bfc30e0ebc879a05
7
+ data.tar.gz: 21be334bdd435bfb7b9c449556cce86dde4e33dd0d84bcd285cb4b52e438ed93ca387356821f76bce3064f3bc31be3446f43773456156976d0f33fcdceb89243
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec
6
+
7
+ gem 'rake'
8
+
9
+ gem 'rspec'
10
+ gem 'rspec_junit_formatter'
11
+ gem 'rubocop'
12
+ gem 'rubocop-rake'
13
+ gem 'rubocop-rspec'
data/bin/console ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'omniai'
6
+
7
+ require 'irb'
8
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ class Chat
5
+ # A choice returned by the API.
6
+ class Choice
7
+ attr_accessor :index, :message, :role
8
+
9
+ # @param index [Integer]
10
+ # @param message [OmniAI::Chat::Message]
11
+ # @param role [String]
12
+ def initialize(index:, message:)
13
+ @index = index
14
+ @message = message
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ class Chat
5
+ # A message returned by the API.
6
+ class Message
7
+ attr_accessor :index, :message, :role
8
+
9
+ # @param content [Integer]
10
+ # @param role [String]
11
+ def initialize(content:, role:)
12
+ @content = content
13
+ @role = role
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ class Chat
5
+ # An abstract class that provides a consistent interface for processing chat requests.
6
+ #
7
+ # Usage:
8
+ #
9
+ # class OmniAI::OpenAI::ChatGPT::Completion < OmniAI::Chat::Completion
10
+ # module Model
11
+ # CHAT = "davinci"
12
+ # end
13
+ # def completion(messages, model:, temperature: 0.0, format: :text)
14
+ # end
15
+ # end
16
+ #
17
+ # Once defined, the subclass can be used to interface with the vendor's chat API as follows:
18
+ #
19
+ # client.chat.completion(messages, model: "...", temperature: 0.0, format: :text)
20
+ class Request
21
+ # @param client [OmniAI::Client] the client
22
+ # @param messages [String]
23
+ # @param model [String]
24
+ # @param temperature [Float]
25
+ # @param format [Symbol] either :text or :json
26
+ def initialize(client:, messages:, model:, temperature: 0.0, format: :text)
27
+ @client = client
28
+ @messages = messages
29
+ @model = model
30
+ @temperature = temperature
31
+ @format = format
32
+ end
33
+
34
+ # @param prompt [String, Message]
35
+ # @param model [String]
36
+ # @param format [Symbol] either :text or :json
37
+ # @param temperature [Float]
38
+ # @return [Hash]
39
+ # @raise [ExecutionError]
40
+ def process!
41
+ response = request!
42
+ raise HTTPError, response unless response.status.ok?
43
+
44
+ parse!(response:)
45
+ end
46
+
47
+ protected
48
+
49
+ # @param response [HTTP::Response]
50
+ # @return [OmniAI::Chat::Completion::Response]
51
+ def parse!(response:)
52
+ raise NotImplementedError, "#{self.class.name}#parse! undefined"
53
+ end
54
+
55
+ # @return [Hash]
56
+ def payload
57
+ raise NotImplementedError, "#{self.class.name}#payload undefined"
58
+ end
59
+
60
+ # @return [String]
61
+ def path
62
+ raise NotImplementedError, "#{self.class.name}#path undefined"
63
+ end
64
+
65
+ # @return [HTTP::Response]
66
+ def request!
67
+ @client
68
+ .connection
69
+ .accept(:json)
70
+ .post(path, json: payload)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ class Chat
5
+ # An abstract class that provides a consistent interface for processing chat responses.
6
+ #
7
+ # Usage:
8
+ #
9
+ # class OmniAI::OpenAI::Chat::Response < OmniAI::Chat::Response
10
+ # def choices
11
+ # # TODO: implement
12
+ # end
13
+ # end
14
+ class Response
15
+ attr_accessor :data
16
+
17
+ # @param data [Hash]
18
+ def initialize(data:)
19
+ @data = data
20
+ end
21
+
22
+ # @param [index] [Integer]
23
+ # @return [OmniAI::Chat::Choice]
24
+ def choice(index: 0)
25
+ choices[index]
26
+ end
27
+
28
+ # @return [Array<OmniAI::Chat::Choice>]
29
+ def choices
30
+ raise NotImplementedError, "#{self.class.name}#choices undefined"
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ # An abstract class that provides an interface for chatting for various vendors (e.g. OpenAI::ChatGPT).
5
+ #
6
+ # Usage:
7
+ #
8
+ # class OmniAI::OpenAI::Chat < OmniAI::Chat
9
+ # def completion(messages, model:, temperature: 0.0, format: :text)
10
+ # # TODO: implement
11
+ # end
12
+ # end
13
+ #
14
+ # Once defined, it can be used to interface with the vendor's chat API as follows:
15
+ #
16
+ # client.chat.completion("...", model: "...", temperature: 0.0, format: :text)
17
+ #
18
+ # @param client [OmniAI::Client] the client
19
+ class Chat
20
+ def initialize(client:)
21
+ @client = client
22
+ end
23
+
24
+ # @raise [OmniAI::Error]
25
+ #
26
+ # @param messages [String]
27
+ # @param model [String]
28
+ # @param format [Symbol] either :text or :json
29
+ # @param temperature [Float]
30
+ #
31
+ # @return [OmniAI::Chat::Request]
32
+ def completion(messages, model:, temperature: 0.0, format: :text)
33
+ raise NotImplementedError, "#{self.class.name}#completion undefined"
34
+ end
35
+ end
36
+ end
data/lib/omniai/client.rb CHANGED
@@ -1,27 +1,38 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Usage:
4
- #
5
- # require "omniai"
6
- # require "omniai-anthropic"
7
- # require "omniai-google"
8
- # require "omniai-mistral"
9
- # require "omniai-openai"
10
- #
11
- # anthropic = OmniAI::Anthropic.new(api_key: ENV.fetch("OPENAI_API_KEY"))
12
- # google = OmniAI::Google.new(api_key: ENV.fetch("OPENAI_API_KEY"))
13
- # mistral = OmniAI::Mistral.new(api_key: ENV.fetch("OPENAI_API_KEY"))
14
- # openai = OmniAI::OpenAI.new(api_key: ENV.fetch("OPENAI_API_KEY"))
3
+ module OmniAI
4
+ # An abstract class that must be subclassed (e.g. OmniAI::OpenAI::Client).
5
+ #
6
+ # Usage:
7
+ #
8
+ # class OmniAI::OpenAI::Client < OmniAI::Client
9
+ # def initialize(api_key: ENV.fetch('OPENAI_API_KEY'))
10
+ # super
11
+ # end
12
+ #
13
+ # @return [OmniAI::OpenAI::Chat]
14
+ # def chat
15
+ # # TODO: implement
16
+ # end
17
+ # end
18
+ class Client
19
+ class Error < StandardError; end
15
20
 
16
- module OmniAI::Client
17
- class Error < StandardError; end
21
+ attr_accessor :api_key
18
22
 
19
- # @param api_key [String] The API key to use for requests
20
- def initialize(api_key:)
21
- @api_key = api_key
22
- end
23
+ # @param api_key [String]
24
+ def initialize(api_key:)
25
+ @api_key = api_key
26
+ end
27
+
28
+ # @return [HTTP::Client]
29
+ def connection
30
+ HTTP.auth("Bearer #{api_key}")
31
+ end
23
32
 
24
- def http
25
- HTTP.auth("Bearer #{@api_key}")
33
+ # @return [OmniAI::Chat] an instance of OmniAI::Chat
34
+ def chat
35
+ raise NotImplementedError, "#{self.class.name}#chat undefined"
36
+ end
26
37
  end
27
38
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OmniAI
4
- VERSION = "0.0.1"
4
+ VERSION = '0.0.3'
5
5
  end
data/lib/omniai.rb CHANGED
@@ -1,7 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "omniai/version"
3
+ require 'http'
4
+ require 'zeitwerk'
5
+
6
+ loader = Zeitwerk::Loader.for_gem
7
+ loader.inflector.inflect 'omniai' => 'OmniAI'
8
+ loader.setup
4
9
 
5
10
  module OmniAI
6
11
  class Error < StandardError; end
12
+
13
+ # An error that wraps an HTTP::Response for non-OK requests.
14
+ class HTTPError < Error
15
+ attr_accessor :response
16
+
17
+ # @param response [HTTP::Response]
18
+ def initialize(response)
19
+ super("status=#{response.status} headers=#{response.headers} body=#{response.body}")
20
+ @response = response
21
+ end
22
+ end
7
23
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre
@@ -25,52 +25,45 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rspec
28
+ name: zeitwerk
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0'
34
- type: :development
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - ">="
39
- - !ruby/object:Gem::Version
40
- version: '0'
41
- - !ruby/object:Gem::Dependency
42
- name: rubocop
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
34
+ type: :runtime
49
35
  prerelease: false
50
36
  version_requirements: !ruby/object:Gem::Requirement
51
37
  requirements:
52
38
  - - ">="
53
39
  - !ruby/object:Gem::Version
54
40
  version: '0'
55
- description: Gives a consistent interface for interacting with OpenAI's ChatGPT, Google's
56
- Gemini, Anthropic's Claude, Mistral's LeChat, and more.
41
+ description: An interface for OpenAI's ChatGPT, Google's Gemini, Anthropic's Claude,
42
+ Mistral's LeChat, etc.
57
43
  email:
58
44
  - kevin@ksylvest.com
59
45
  executables: []
60
46
  extensions: []
61
47
  extra_rdoc_files: []
62
48
  files:
63
- - ".rspec"
64
- - ".rubocop.yml"
49
+ - Gemfile
65
50
  - README.md
66
- - Rakefile
51
+ - bin/console
52
+ - bin/setup
67
53
  - lib/omniai.rb
54
+ - lib/omniai/chat.rb
55
+ - lib/omniai/chat/choice.rb
56
+ - lib/omniai/chat/message.rb
57
+ - lib/omniai/chat/request.rb
58
+ - lib/omniai/chat/response.rb
68
59
  - lib/omniai/client.rb
69
60
  - lib/omniai/version.rb
70
- - sig/omniai.rbs
71
61
  homepage: https://github.com/ksylvest/omniai
72
62
  licenses: []
73
- metadata: {}
63
+ metadata:
64
+ homepage_uri: https://github.com/ksylvest/omniai
65
+ changelog_uri: https://github.com/ksylvest/omniai/releases
66
+ rubygems_mfa_required: 'true'
74
67
  post_install_message:
75
68
  rdoc_options: []
76
69
  require_paths:
@@ -79,7 +72,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
79
72
  requirements:
80
73
  - - ">="
81
74
  - !ruby/object:Gem::Version
82
- version: 3.0.0
75
+ version: 3.3.0
83
76
  required_rubygems_version: !ruby/object:Gem::Requirement
84
77
  requirements:
85
78
  - - ">="
data/.rspec DELETED
@@ -1,3 +0,0 @@
1
- --format documentation
2
- --color
3
- --require spec_helper
data/.rubocop.yml DELETED
@@ -1,2 +0,0 @@
1
- AllCops:
2
- TargetRubyVersion: 3.0
data/Rakefile DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bundler/gem_tasks"
4
- require "rspec/core/rake_task"
5
-
6
- RSpec::Core::RakeTask.new(:spec)
7
-
8
- require "rubocop/rake_task"
9
-
10
- RuboCop::RakeTask.new
11
-
12
- task default: %i[spec rubocop]
data/sig/omniai.rbs DELETED
@@ -1,3 +0,0 @@
1
- module OmniAI
2
- VERSION: String
3
- end