omniai 1.2.0 → 1.2.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: d6114f0ef4a95633c3391eb421c23e8df99413c876b838053ddb89bde4e7d6f0
4
- data.tar.gz: fe2156f9db8802f44975cc1aab0a58f34cb568e1b34fe14e33bd34c52f4b6ff9
3
+ metadata.gz: 239eb058ae53afd3f28fe00a18af282a856ca842a4f81bcdf22413a02d8d44fc
4
+ data.tar.gz: e74ac69ab6435fd9da3d1602c9cce5e052f53bebf609d8815868b58be0897884
5
5
  SHA512:
6
- metadata.gz: 2e3a7b49bd65210142978e79ccb9ed88cd19b085c48334b16939c1401217913b951d474515d2ac3fedd1984cc1c7e31e9fa2af206ee04da3765eb1cfb8e2b393
7
- data.tar.gz: 7d966a598e0ec358785e25be08530f7f82898601030f703c78a728e31e7885841239d50c1c851ef3912060318df588050ddf7f35870f5f97254e9a23f412b045
6
+ metadata.gz: a6b18cae8b5aab610bf255860ccd514b794eda3021b2f9b3aa86020968e0f449b683b4db74291e71583698b61d7612a7e49b3ee0310c806a826f7b27c50c7d92
7
+ data.tar.gz: bd12b38f3c9a150fe09644aaf187aa05aa1063ee136196e11fcaa356f4fe5bdc2c93f6292a79025f301c6d35a1202186f6ad787787828dfd5af91f229a34b550
data/README.md CHANGED
@@ -60,6 +60,18 @@ require 'omniai/openai'
60
60
  client = OmniAI::OpenAI::Client.new
61
61
  ```
62
62
 
63
+ #### Usage with LocalAI
64
+
65
+ LocalAI support is offered through [OmniAI::OpenAI](https://github.com/ksylvest/omniai-openai):
66
+
67
+ [Usage with LocalAI](https://github.com/ksylvest/omniai-openai#usage-with-localai)
68
+
69
+ #### Usage with Ollama
70
+
71
+ Ollama support is offered through [OmniAI::OpenAI](https://github.com/ksylvest/omniai-openai):
72
+
73
+ [Usage with Ollama](https://github.com/ksylvest/omniai-openai#usage-with-ollama)
74
+
63
75
  ### Chat
64
76
 
65
77
  Clients that support chat (e.g. Anthropic w/ "Claude", Google w/ "Gemini", Mistral w/ "LeChat", OpenAI w/ "ChatGPT", etc) generate completions using the following calls:
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ class Chat
5
+ module Content
6
+ # A file that is either audio / image / video.
7
+ class File < Media
8
+ attr_accessor :io
9
+
10
+ # @param io [IO, Pathname, String]
11
+ # @param type [Symbol, String] :image, :video, :audio, "audio/flac", "image/jpeg", "video/mpeg", etc.
12
+ def initialize(io, type)
13
+ super(type)
14
+ @io = io
15
+ end
16
+
17
+ # @return [String]
18
+ def fetch!
19
+ case @io
20
+ when IO then @io.read
21
+ else ::File.binread(@io)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ class Chat
5
+ module Content
6
+ # An abstract class that represents audio / image / video and is used for both files and urls.
7
+ class Media
8
+ attr_accessor :type
9
+
10
+ # @param type [String] "audio/flac", "image/jpeg", "video/mpeg", etc.
11
+ def initialize(type)
12
+ @type = type
13
+ end
14
+
15
+ # @return [Boolean]
16
+ def text?
17
+ @type.match?(%r{^text/})
18
+ end
19
+
20
+ # @return [Boolean]
21
+ def audio?
22
+ @type.match?(%r{^audio/})
23
+ end
24
+
25
+ # @return [Boolean]
26
+ def image?
27
+ @type.match?(%r{^image/})
28
+ end
29
+
30
+ # @return [Boolean]
31
+ def video?
32
+ @type.match?(%r{^video/})
33
+ end
34
+
35
+ # @yield [io]
36
+ def fetch!(&)
37
+ raise NotImplementedError, "#{self.class}#fetch! undefined"
38
+ end
39
+
40
+ # e.g. "Hello" -> "SGVsbG8h"
41
+ #
42
+ # @return [String]
43
+ def data
44
+ Base64.strict_encode64(fetch!)
45
+ end
46
+
47
+ # e.g. "data:text/html;base64,..."
48
+ #
49
+ # @return [String]
50
+ def data_uri
51
+ "data:#{@type};base64,#{data}"
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ class Chat
5
+ module Content
6
+ # Just some text.
7
+ class Text
8
+ attr_accessor :text
9
+
10
+ # @param text [text]
11
+ def initialize(text)
12
+ @text = text
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ class Chat
5
+ module Content
6
+ # A url that is either audio / image / video.
7
+ class URL < Media
8
+ attr_accessor :url, :type
9
+
10
+ class HTTPError < OmniAI::HTTPError; end
11
+
12
+ # @param url [URI, String]
13
+ # @param type [Symbol, String] "audio/flac", "image/jpeg", "video/mpeg", etc.
14
+ def initialize(url, type)
15
+ super(type)
16
+ @url = url
17
+ end
18
+
19
+ # @raise [HTTPError]
20
+ #
21
+ # @return [String]
22
+ def fetch!
23
+ response = request!
24
+ String(response.body)
25
+ end
26
+
27
+ private
28
+
29
+ # @raise [HTTPError]
30
+ #
31
+ # @return [HTTP::Response]
32
+ def request!
33
+ response = HTTP.get(@url)
34
+ raise HTTPError, response.flush unless response.status.success?
35
+
36
+ response
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
data/lib/omniai/client.rb CHANGED
@@ -13,19 +13,28 @@ module OmniAI
13
13
  class Client
14
14
  class Error < StandardError; end
15
15
 
16
- attr_accessor :api_key
16
+ attr_accessor :api_key, :logger, :host
17
17
 
18
- # @param api_key [String]
19
- # @param logger [Logger]
20
- def initialize(api_key:, logger: nil)
18
+ # @param api_key [String] optional
19
+ # @param host [String] optional - supports for customzing the host of the client (e.g. 'http://localhost:8080')
20
+ # @param logger [Logger] optional
21
+ def initialize(api_key: nil, logger: nil, host: nil)
21
22
  @api_key = api_key
23
+ @host = host
22
24
  @logger = logger
23
25
  end
24
26
 
25
27
  # @return [String]
26
28
  def inspect
27
- masked_api_key = "#{api_key[..2]}***" if api_key
28
- "#<#{self.class.name} api_key=#{masked_api_key.inspect}>"
29
+ props = []
30
+ props << "api_key=#{masked_api_key.inspect}" if @api_key
31
+ props << "host=#{@host.inspect}" if @host
32
+ "#<#{self.class.name} #{props.join(' ')}>"
33
+ end
34
+
35
+ # @return [String]
36
+ def masked_api_key
37
+ "#{api_key[..2]}***" if api_key
29
38
  end
30
39
 
31
40
  # @return [HTTP::Client]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OmniAI
4
- VERSION = '1.2.0'
4
+ VERSION = '1.2.2'
5
5
  end
data/lib/omniai.rb CHANGED
@@ -2,10 +2,12 @@
2
2
 
3
3
  require 'event_stream_parser'
4
4
  require 'http'
5
+ require 'uri'
5
6
  require 'zeitwerk'
6
7
 
7
8
  loader = Zeitwerk::Loader.for_gem
8
9
  loader.inflector.inflect 'omniai' => 'OmniAI'
10
+ loader.inflector.inflect 'url' => 'URL'
9
11
  loader.setup
10
12
 
11
13
  module OmniAI
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: 1.2.0
4
+ version: 1.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre
@@ -69,7 +69,10 @@ files:
69
69
  - lib/omniai/chat/choice.rb
70
70
  - lib/omniai/chat/chunk.rb
71
71
  - lib/omniai/chat/completion.rb
72
- - lib/omniai/chat/content.rb
72
+ - lib/omniai/chat/content/file.rb
73
+ - lib/omniai/chat/content/media.rb
74
+ - lib/omniai/chat/content/text.rb
75
+ - lib/omniai/chat/content/url.rb
73
76
  - lib/omniai/chat/delta.rb
74
77
  - lib/omniai/chat/message.rb
75
78
  - lib/omniai/chat/stream.rb
@@ -1,17 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module OmniAI
4
- class Chat
5
- # A file used for analysis.
6
- class Content
7
- attr_accessor :type, :value
8
-
9
- # @param value [String]
10
- # @param type [Symbol] :image / :video / :audio / :text
11
- def initialize(value, type: :text)
12
- @value = value
13
- @type = type
14
- end
15
- end
16
- end
17
- end