omniai 1.2.0 → 1.2.2

Sign up to get free protection for your applications and to get access to all the features.
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