omniai-openai 1.1.0 → 1.2.0

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: f35b8f18f1fed4fc62a4d69d1ec9d94b7b93dfe6d7110e9f64369625cafd8702
4
- data.tar.gz: 746528fa3065f9f843bafb9b82946dda6d57bb121b81bbf6a8f4c43e72e1888e
3
+ metadata.gz: 01d9c9144c74769c3eed7d8ec37f4cab63885057d5f16b02727e8c26e94414a0
4
+ data.tar.gz: 98e56e503c8ba01d3822d448dab53c94fef16d08c3f7896884e381f0b10b54fb
5
5
  SHA512:
6
- metadata.gz: 4a11987f0c6dceeed121166820240c9c878ddc7f88b7c2cf2598c5f14ed5cdc1d6730d3463396f4c56b38f37d7ac4d983b7af461afd00c58db613a58b887d075
7
- data.tar.gz: 129bd67690492743d3945fc15da22d5b9f4ec1bc384c56d8dcd2d60d1fd0419f802c6b804cbf154efdd4828d5e42220a30f890d58c08f9aaa634c1c8ba8bfa20
6
+ metadata.gz: 652b78a11ffb57f7b884d39fd08222fd4a87a0105a32ec0304d7d09efde5988b7f6058d3fbed46b6b3b8e8d44fec5191ffe925804f953456502020ea9cc8ef6f
7
+ data.tar.gz: 41c3516078e9a9411eebea6a0eaf3424b6a756d8b714697e51817e02f7faa9c4f170dc38c2fadb21c325a7576c5ae615468e3fb5d1438014532ae1be4c43d37b
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # OmniAI::OpenAI
2
2
 
3
+ [![CircleCI](https://circleci.com/gh/ksylvest/omniai-openai.svg?style=svg)](https://circleci.com/gh/ksylvest/omniai-openai)
4
+
3
5
  An OpenAI implementation of the [OmniAI](https://github.com/ksylvest/omniai) APIs.
4
6
 
5
7
  ## Installation
@@ -43,12 +45,12 @@ end
43
45
  A chat completion is generated by passing in prompts using any a variety of formats:
44
46
 
45
47
  ```ruby
46
- completion = client.chat.completion('Tell me a joke!')
48
+ completion = client.chat('Tell me a joke!')
47
49
  completion.choice.message.content # 'Why did the chicken cross the road? To get to the other side.'
48
50
  ```
49
51
 
50
52
  ```ruby
51
- completion = client.chat.completion({
53
+ completion = client.chat({
52
54
  role: OmniAI::Chat::Role::USER,
53
55
  content: 'Is it wise to jump off a bridge?'
54
56
  })
@@ -56,7 +58,7 @@ completion.choice.message.content # 'No.'
56
58
  ```
57
59
 
58
60
  ```ruby
59
- completion = client.chat.completion([
61
+ completion = client.chat([
60
62
  {
61
63
  role: OmniAI::Chat::Role::SYSTEM,
62
64
  content: 'You are a helpful assistant.'
@@ -71,7 +73,7 @@ completion.choice.message.content # 'The capital of Canada is Ottawa.'
71
73
  `model` takes an optional string (default is `gtp-4o`):
72
74
 
73
75
  ```ruby
74
- completion = client.chat.completion('How fast is a cheetah?', model: OmniAI::OpenAI::Chat::Model::GPT_3_5_TURBO)
76
+ completion = client.chat('How fast is a cheetah?', model: OmniAI::OpenAI::Chat::Model::GPT_3_5_TURBO)
75
77
  completion.choice.message.content # 'A cheetah can reach speeds over 100 km/h.'
76
78
  ```
77
79
 
@@ -82,7 +84,7 @@ completion.choice.message.content # 'A cheetah can reach speeds over 100 km/h.'
82
84
  `temperature` takes an optional float between `0.0` and `2.0` (defaults is `0.7`):
83
85
 
84
86
  ```ruby
85
- completion = client.chat.completion('Pick a number between 1 and 5', temperature: 2.0)
87
+ completion = client.chat('Pick a number between 1 and 5', temperature: 2.0)
86
88
  completion.choice.message.content # '3'
87
89
  ```
88
90
 
@@ -96,7 +98,7 @@ completion.choice.message.content # '3'
96
98
  stream = proc do |chunk|
97
99
  print(chunk.choice.delta.content) # 'Better', 'three', 'hours', ...
98
100
  end
99
- client.chat.completion('Be poetic.', stream:)
101
+ client.chat('Be poetic.', stream:)
100
102
  ```
101
103
 
102
104
  [OpenAI API Reference `stream`](https://platform.openai.com/docs/api-reference/chat/create#chat-create-stream)
@@ -106,7 +108,7 @@ client.chat.completion('Be poetic.', stream:)
106
108
  `format` takes an optional symbol (`:json`) and that setes the `response_format` to `json_object`:
107
109
 
108
110
  ```ruby
109
- completion = client.chat.completion([
111
+ completion = client.chat([
110
112
  { role: OmniAI::Chat::Role::SYSTEM, content: OmniAI::Chat::JSON_PROMPT },
111
113
  { role: OmniAI::Chat::Role::USER, content: 'What is the name of the drummer for the Beatles?' }
112
114
  ], format: :json)
@@ -169,3 +171,63 @@ transcription.text
169
171
  ```
170
172
 
171
173
  [OpenAI API Reference `temperature`](https://platform.openai.com/docs/api-reference/audio/createTranscription#audio-createtranscription-temperature)
174
+
175
+ ### Speak
176
+
177
+ Speech can be generated by passing text with a block:
178
+
179
+ ```ruby
180
+ File.open('example.ogg', 'wb') do |file|
181
+ client.speak('How can a clam cram in a clean cream can?') do |chunk|
182
+ file << chunk
183
+ end
184
+ end
185
+ ```
186
+
187
+ If a block is not provided then a tempfile is returned:
188
+
189
+ ```ruby
190
+ tempfile = client.speak('Can you can a can as a canner can can a can?')
191
+ tempfile.close
192
+ tempfile.unlink
193
+ ```
194
+
195
+ #### Voice
196
+
197
+ `voice` is optional and must be one of the supported voices:
198
+
199
+ ```ruby
200
+ client.speak('She sells seashells by the seashore.', voice: OmniAI::OpenAI::Speak::Voice::SHIMMER)
201
+ ```
202
+
203
+ [OpenAI API Reference `voice`](https://platform.openai.com/docs/api-reference/audio/createSpeech#audio-createspeech-voice)
204
+
205
+ #### Model
206
+
207
+ `model` is optional and must be either `tts-1` or `tts-1-hd` (default):
208
+
209
+ ```ruby
210
+ client.speak('I saw a kitten eating chicken in the kitchen.', format: OmniAI::OpenAI::Speak::Model::TTS_1)
211
+ ```
212
+
213
+ [OpenAI API Refernce `model`](https://platform.openai.com/docs/api-reference/audio/createSpeech#audio-createspeech-model)
214
+
215
+ #### Speed
216
+
217
+ `speed` is optional and must be between 0.25 and 0.40:
218
+
219
+ ```ruby
220
+ client.speak('How much wood would a woodchuck chuck if a woodchuck could chuck wood?', speed: 4.0)
221
+ ```
222
+
223
+ [OmniAI API Reference `speed`](https://platform.openai.com/docs/api-reference/audio/createSpeech#audio-createspeech-speed)
224
+
225
+ #### Format
226
+
227
+ `format` is optional and supports `MP3` (default), `OPUS`, `AAC`, `FLAC`, `WAV` or `PCM`:
228
+
229
+ ```ruby
230
+ client.speak('A pessemistic pest exists amidst us.', format: OmniAI::OpenAI::Speak::Format::FLAC)
231
+ ```
232
+
233
+ [OpenAI API Reference `format`](https://platform.openai.com/docs/api-reference/audio/createSpeech#audio-createspeech-response_format)
@@ -78,6 +78,27 @@ module OmniAI
78
78
  def transcribe(path, model: Transcribe::Model::WHISPER, language: nil, prompt: nil, temperature: nil, format: nil)
79
79
  Transcribe.process!(path, model:, language:, prompt:, temperature:, format:, client: self)
80
80
  end
81
+
82
+ # @raise [OmniAI::Error]
83
+ #
84
+ # @param input [String] required
85
+ # @param model [String] optional
86
+ # @param voice [String] optional
87
+ # @param speed [Float] optional
88
+ # @param format [String] optional (default "aac"):
89
+ # - "aac"
90
+ # - "mp3"
91
+ # - "flac"
92
+ # - "opus"
93
+ # - "pcm"
94
+ # - "wav"
95
+ #
96
+ # @yield [output] optional
97
+ #
98
+ # @return [Tempfile``]
99
+ def speak(input, model: Speak::Model::TTS_1_HD, voice: Speak::Voice::ALLOY, speed: nil, format: nil, &)
100
+ Speak.process!(input, model:, voice:, speed:, format:, client: self, &)
101
+ end
81
102
  end
82
103
  end
83
104
  end
@@ -4,7 +4,7 @@ module OmniAI
4
4
  module OpenAI
5
5
  # Configuration for managing the OpenAI `api_key` / `organization` / `project` / `logger`.
6
6
  class Config < OmniAI::Config
7
- attr_accessor :organization, :project, :chat_options, :transcribe_options
7
+ attr_accessor :organization, :project, :chat_options, :transcribe_options, :speak_options
8
8
 
9
9
  def initialize
10
10
  super
@@ -14,6 +14,7 @@ module OmniAI
14
14
  @host = ENV.fetch('OPENAI_HOST', 'https://api.openai.com')
15
15
  @chat_options = {}
16
16
  @transcribe_options = {}
17
+ @speak_options = {}
17
18
  end
18
19
  end
19
20
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ module OpenAI
5
+ # An OpenAI transcribe implementation.
6
+ class Speak < OmniAI::Speak
7
+ module Model
8
+ TTS_1 = 'tts-1'
9
+ TTS_1_HD = 'tts-1-hd'
10
+ end
11
+
12
+ module Voice
13
+ ALLOY = 'alloy' # https://platform.openai.com/docs/guides/text-to-speech/alloy
14
+ ECHO = 'echo' # https://platform.openai.com/docs/guides/text-to-speech/echo
15
+ FABLE = 'fable' # https://platform.openai.com/docs/guides/text-to-speech/fable
16
+ NOVA = 'nova' # https://platform.openai.com/docs/guides/text-to-speech/nova
17
+ ONYX = 'onyx' # https://platform.openai.com/docs/guides/text-to-speech/onyx
18
+ SHIMMER = 'shimmer' # https://platform.openai.com/docs/guides/text-to-speech/shimmer
19
+ end
20
+
21
+ protected
22
+
23
+ # @return [Hash]
24
+ def payload
25
+ OmniAI::OpenAI
26
+ .config.speak_options
27
+ .merge(super)
28
+ .merge({ response_format: @format }.compact)
29
+ end
30
+
31
+ # @return [String]
32
+ def path
33
+ "/#{OmniAI::OpenAI::Client::VERSION}/audio/speech"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module OmniAI
4
4
  module OpenAI
5
- VERSION = '1.1.0'
5
+ VERSION = '1.2.0'
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: omniai-openai
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.2.0
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-06-17 00:00:00.000000000 Z
11
+ date: 2024-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: event_stream_parser
@@ -65,10 +65,12 @@ files:
65
65
  - lib/omniai/openai/chat.rb
66
66
  - lib/omniai/openai/client.rb
67
67
  - lib/omniai/openai/config.rb
68
+ - lib/omniai/openai/speak.rb
68
69
  - lib/omniai/openai/transcribe.rb
69
70
  - lib/omniai/openai/version.rb
70
71
  homepage: https://github.com/ksylvest/omniai-openai
71
- licenses: []
72
+ licenses:
73
+ - MIT
72
74
  metadata:
73
75
  homepage_uri: https://github.com/ksylvest/omniai-openai
74
76
  changelog_uri: https://github.com/ksylvest/omniai-openai/releases