omniai 1.8.1 → 1.8.3

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: cca8dd5cc19989ca0a3fc89d1e8f2c5a56611378a202ea8da2fd49528454ea6c
4
- data.tar.gz: ee0abcf49b13df01ed5b63ed557de44d42d640fb966bcfb5c7592e19aff06f93
3
+ metadata.gz: 3aa80243c35a4c2b3ed765f36cc901778618686adba661bb807cd7bd5f698c62
4
+ data.tar.gz: a5b7a73edda5894f1461f50f6543f124fe628c800772a5b28cb28ecbe7ac2367
5
5
  SHA512:
6
- metadata.gz: eb48e8f76d7cd1836ad8dc0ceb577362a3f289026749e2cc49044e31d25758a625ff66fe8003be12dc09585d9ee571671dd4f6d0b8c355cc7962eb4c136ec9f0
7
- data.tar.gz: 41cf6419a3cf3c1662e2f6c5925ae5a05e991f6f2e8f81bcf3d5dfb62ad029bf3d6c32565892ef81acc651a43533dc3a7e9efb2c75922bbdddf28bb29e18b3c2
6
+ metadata.gz: f85926e78211149bd4d822e4685d0fda12fca80c54953f7a3c8ca18c404a9b97a64900f24f63401d5c81620d4f5867404486d41fd7390d674679044190198209
7
+ data.tar.gz: 9f85af9d52bf2d989332be7f0d81b9ca0fc15420de6ddfc1158787e9e2cebdff5d5c084b5135019e3588175d7392e884e2c41a02688317c628ea73b94ea5cdce
data/README.md CHANGED
@@ -2,14 +2,142 @@
2
2
 
3
3
  [![CircleCI](https://circleci.com/gh/ksylvest/omniai.svg?style=svg)](https://circleci.com/gh/ksylvest/omniai)
4
4
 
5
- OmniAI is a flexible AI library that standardizes the APIs of many different AIs:
5
+ OmniAI standardizes the APIs of various AI / LLM companies such as Anthropic, Google, Mistral and OpenAI for the generation of text, the conversion of text-to-speech, the conversion of speech-to-text, the generation of embeddings, and more. It offers a unified API regardless of the provider and task.
6
6
 
7
7
  - [OmniAI::Anthropic](https://github.com/ksylvest/omniai-anthropic)
8
8
  - [OmniAI::Google](https://github.com/ksylvest/omniai-google)
9
9
  - [OmniAI::Mistral](https://github.com/ksylvest/omniai-mistral)
10
10
  - [OmniAI::OpenAI](https://github.com/ksylvest/omniai-openai)
11
11
 
12
- All libraries are community maintained.
12
+ ## Examples
13
+
14
+ ### Example #1: [Chat](https://github.com/ksylvest/omniai/blob/main/examples/chat)
15
+
16
+ ```ruby
17
+ require 'omniai/anthropic'
18
+
19
+ CLIENT = OmniAI::Anthropic::Client.new
20
+
21
+ CAT_URL = 'https://images.unsplash.com/photo-1472491235688-bdc81a63246e?q=80&w=1024&h=1024&fit=crop&fm=jpg'
22
+ DOG_URL = 'https://images.unsplash.com/photo-1517849845537-4d257902454a?q=80&w=1024&h=1024&fit=crop&fm=jpg'
23
+
24
+ CLIENT.chat(stream: $stdout) do |prompt|
25
+ prompt.system('You are a helpful biologist with an expertise in animals that responds with the latin names.')
26
+ prompt.user do |message|
27
+ message.text('What animals are in the attached photos?')
28
+ message.url(CAT_URL, 'image/jpeg')
29
+ message.url(DOG_URL, 'image/jpeg')
30
+ end
31
+ end
32
+ ```
33
+
34
+ ```
35
+ The animals in the photos are:
36
+
37
+ 1. A cat (*Felis catus*).
38
+ 2. A dog (*Canis familiaris*).
39
+ ```
40
+
41
+ ### Example #2: [Text-to-Speech](https://github.com/ksylvest/omniai/blob/main/examples/text_to_speech)
42
+
43
+ ```ruby
44
+ require 'omniai/openai'
45
+
46
+ CLIENT = OmniAI::OpenAI::Client.new
47
+
48
+ File.open(File.join(__dir__, 'audio.wav'), 'wb') do |file|
49
+ CLIENT.speak('Sally sells seashells by the seashore.', format: OmniAI::Speak::Format::WAV) do |chunk|
50
+ file << chunk
51
+ end
52
+ end
53
+ ```
54
+
55
+ ### Example #3: [Speech-to-Text](https://github.com/ksylvest/omniai/blob/main/examples/speech_to_text)
56
+
57
+ ```ruby
58
+ require 'omniai/openai'
59
+
60
+ CLIENT = OmniAI::OpenAI::Client.new
61
+
62
+ File.open(File.join(__dir__, 'audio.wav'), 'rb') do |file|
63
+ transcription = CLIENT.transcribe(file)
64
+ puts(transcription.text)
65
+ end
66
+ ```
67
+
68
+ ### Example #4: [Tools](https://github.com/ksylvest/omniai/blob/main/examples/tools)
69
+
70
+ ```ruby
71
+ require 'omniai/google'
72
+
73
+ CLIENT = OmniAI::Google::Client.new
74
+
75
+ TOOL = OmniAI::Tool.new(
76
+ proc { |location:, unit: 'celsius'| "#{rand(20..50)}° #{unit} in #{location}" },
77
+ name: 'Weather',
78
+ description: 'Lookup the weather in a location',
79
+ parameters: OmniAI::Tool::Parameters.new(
80
+ properties: {
81
+ location: OmniAI::Tool::Property.string(description: 'e.g. Toronto'),
82
+ unit: OmniAI::Tool::Property.string(enum: %w[celcius fahrenheit]),
83
+ },
84
+ required: %i[location]
85
+ )
86
+ )
87
+
88
+ completion = CLIENT.chat(tools: [TOOL]) do |prompt|
89
+ prompt.user do |message|
90
+ message.text('What is the weather in "London" in celcius and "Seattle" in fahrenheit?')
91
+ end
92
+ end
93
+
94
+ puts(completion.text)
95
+ ```
96
+
97
+ ```
98
+ The weather is 24° celcius in London and 42° fahrenheit in Seattle.
99
+ ```
100
+
101
+ ### Example #5: [Embeddings](https://github.com/ksylvest/omniai/blob/main/examples/embeddings)
102
+
103
+ ```ruby
104
+ require 'omniai/mistral'
105
+
106
+ CLIENT = OmniAI::Mistral::Client.new
107
+
108
+ Entry = Data.define(:text, :embedding) do
109
+ def initialize(text:)
110
+ super(text:, embedding: CLIENT.embed(text).embedding)
111
+ end
112
+ end
113
+
114
+ ENTRIES = [
115
+ Entry.new(text: 'John is a musician.'),
116
+ Entry.new(text: 'Paul is a plumber.'),
117
+ Entry.new(text: 'George is a teacher.'),
118
+ Entry.new(text: 'Ringo is a doctor.'),
119
+ ].freeze
120
+
121
+ def search(query)
122
+ embedding = CLIENT.embed(query).embedding
123
+
124
+ results = ENTRIES.sort_by do |data|
125
+ Math.sqrt(data.embedding.zip(embedding).map { |a, b| (a - b)**2 }.reduce(:+))
126
+ end
127
+
128
+ puts "'#{query}': '#{results.first.text}'"
129
+ end
130
+
131
+ search('What does George do?')
132
+ search('Who is a doctor?')
133
+ search('Who do you call to fix a toilet?')
134
+ ```
135
+
136
+ ```
137
+ 'What does George do?': 'George is a teacher.'
138
+ 'Who is a doctor?': 'Ringo is a doctor.'
139
+ 'Who do you call to fix a toilet?': 'Paul is a plumber.'
140
+ ```
13
141
 
14
142
  ## Installation
15
143
 
@@ -83,7 +211,7 @@ require 'omniai/openai'
83
211
  require 'logger'
84
212
 
85
213
  logger = Logger.new(STDOUT)
86
- client = OmniAI::Example::Client.new(logger:)
214
+ client = OmniAI::OpenAI::Client.new(logger:)
87
215
  ```
88
216
 
89
217
  ```
@@ -2,7 +2,8 @@
2
2
 
3
3
  module OmniAI
4
4
  class Chat
5
- # For for.
5
+ # A choice wraps a message and index returned by an LLM. The default is to generate a single choice. Some LLMs
6
+ # support generating multiple choices at once (e.g. giving you multiple options to choose from).
6
7
  class Choice
7
8
  # @return [Integer]
8
9
  attr_accessor :index
@@ -12,7 +13,6 @@ module OmniAI
12
13
 
13
14
  # @param message [Message]
14
15
  # @param index [Integer]
15
- # @param tool_call_list [Array<ToolCall>]
16
16
  def initialize(message:, index: 0)
17
17
  @message = message
18
18
  @index = index
@@ -59,7 +59,7 @@ module OmniAI
59
59
  message.content
60
60
  end
61
61
 
62
- # @return [Array<ToolCall, nil]
62
+ # @return [Array<ToolCall>, nil]
63
63
  def tool_call_list
64
64
  message.tool_call_list
65
65
  end
@@ -144,6 +144,24 @@ module OmniAI
144
144
  def user(content = nil, &)
145
145
  message(content, role: Role::USER, &)
146
146
  end
147
+
148
+ # @example
149
+ # prompt.agent('the capital of Canada is Ottawa.')
150
+ #
151
+ # @example
152
+ # prompt.agent do |message|
153
+ # message.text 'the capital of Canada is Ottawa.'
154
+ # end
155
+ #
156
+ # @param content [String, nil]
157
+ #
158
+ # @yield [builder]
159
+ # @yieldparam builder [Message::Builder]
160
+ #
161
+ # @return [Message]
162
+ def agent(content = nil, &)
163
+ message(content, role: Role::AGENT, &)
164
+ end
147
165
  end
148
166
  end
149
167
  end
@@ -11,7 +11,7 @@ module OmniAI
11
11
  attr_accessor :tool_call_id
12
12
 
13
13
  # @param content [Object]
14
- # @param tool_call [ToolCall]
14
+ # @param tool_call_id [String]
15
15
  def initialize(content:, tool_call_id:)
16
16
  @content = content
17
17
  @tool_call_id = tool_call_id
data/lib/omniai/client.rb CHANGED
@@ -75,15 +75,15 @@ module OmniAI
75
75
  # Initialize a client by provider (e.g. 'openai'). This method attempts to require the provider.
76
76
  #
77
77
  # @raise [OmniAI::Error] if the provider is not defined and the gem is not installed
78
- # @param provider [String] required (e.g. 'anthropic', 'google', 'mistral', 'openai', etc)
78
+ # @param provider [String, Symbol] required (e.g. 'anthropic', 'google', 'mistral', 'openai', etc)
79
79
  # @return [OmniAI::Client]
80
80
  def self.find(provider:, **)
81
81
  klass =
82
82
  case provider
83
- when 'anthropic' then anthropic
84
- when 'google' then google
85
- when 'mistral' then mistral
86
- when 'openai' then openai
83
+ when :anthropic, 'anthropic' then anthropic
84
+ when :google, 'google' then google
85
+ when :mistral, 'mistral' then mistral
86
+ when :openai, 'openai' then openai
87
87
  else raise Error, "unknown provider=#{provider.inspect}"
88
88
  end
89
89
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OmniAI
4
- VERSION = '1.8.1'
4
+ VERSION = '1.8.3'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniai
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.1
4
+ version: 1.8.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-17 00:00:00.000000000 Z
11
+ date: 2024-10-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: event_stream_parser
@@ -125,7 +125,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  requirements: []
128
- rubygems_version: 3.5.14
128
+ rubygems_version: 3.5.18
129
129
  signing_key:
130
130
  specification_version: 4
131
131
  summary: A generalized framework for interacting with many AI services