omniai 1.1.4 → 1.1.5

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: 62558072fec9583fe2df59e34498e31b449fc551a7d262a21ad45c1aa8bef721
4
- data.tar.gz: 2b410f4fdccea4fdae2d839c60f703cbf311c3ad9b43f4f87b862f719c5e2ca8
3
+ metadata.gz: a82c1b8f8724f5dd7f35239ca2454e4ec7631fa1b8b0544249a49f8b6c52962f
4
+ data.tar.gz: 85e9a9ee74f30ad4c4ba6ef8fbbaa88dc0d31fea6927774d5c7a421e2d38e341
5
5
  SHA512:
6
- metadata.gz: 5d975d4d7767392a20cab800bbcc17c988ae18adf0d6c31c816e99ab6b33cbeb9fac319d6e15bdbd425da3e00d2843c28004223f24c3471c1e2c60c55428fba4
7
- data.tar.gz: e9967f2302492db51c6af31c101a908bf19392d5eefe87829a2d146431ea6d17b6d3516493a92beeae780b75cfb0e61a7214ddfd52817df5199f6d1e9b36642e
6
+ metadata.gz: 42c6324488864562480cf898c8e087ac841d035468a0f4b4dbcd7c86f4239d61ca8361c80e8dcd06ddb9dc565c2e04faa047c2e1342bacf1ac8d2d3825d85b25
7
+ data.tar.gz: cbeef3a03122130ce8c2bf634700df52a2a44aa1c013e8d0f2862379940965326f693f4e87f2704d0dd0a197cddf136cc5cd440d4c36a5a573ba00910845d044
data/README.md CHANGED
@@ -96,7 +96,7 @@ client.chat('Tell me a joke.', stream:)
96
96
 
97
97
  ### Transcribe
98
98
 
99
- Clients that support chat (e.g. OpenAI w/ "Whisper", etc) convert recordings to text via the following calls:
99
+ Clients that support transcribe (e.g. OpenAI w/ "Whisper") convert recordings to text via the following calls:
100
100
 
101
101
  #### Transcriptions with Path
102
102
 
@@ -108,7 +108,30 @@ transcription.text # '...'
108
108
  #### Transcriptions with Files
109
109
 
110
110
  ```ruby
111
- file = File.open("example.ogg", "rb")
112
- transcription = client.transcribe(file)
113
- transcription.text # '...'
111
+ File.open("example.ogg", "rb") do |file|
112
+ transcription = client.transcribe(file)
113
+ transcription.text # '...'
114
+ end
115
+ ```
116
+
117
+ ### Speak
118
+
119
+ Clients that support speak (e.g. OpenAI w/ "Whisper") convert text to recordings via the following calls:
120
+
121
+ #### Speech with Stream
122
+
123
+ ```ruby
124
+ File.open('example.ogg', 'wb') do |file|
125
+ client.speak('The quick brown fox jumps over a lazy dog.', voice: 'HAL') do |chunk|
126
+ file << chunk
127
+ end
128
+ end
129
+ ```
130
+
131
+ #### Speech with File
132
+
133
+ ```ruby
134
+ tempfile = client.speak('The quick brown fox jumps over a lazy dog.', voice: 'HAL')
135
+ tempfile.close
136
+ tempfile.unlink
114
137
  ```
data/lib/omniai/chat.rb CHANGED
@@ -56,7 +56,7 @@ module OmniAI
56
56
  @format = format
57
57
  end
58
58
 
59
- # @raise [ExecutionError]
59
+ # @raise [HTTPError]
60
60
  def process!
61
61
  response = request!
62
62
  raise HTTPError, response.flush unless response.status.ok?
data/lib/omniai/client.rb CHANGED
@@ -59,5 +59,26 @@ module OmniAI
59
59
  def transcribe(io, model:, language: nil, prompt: nil, temperature: nil, format: nil)
60
60
  raise NotImplementedError, "#{self.class.name}#speak undefined"
61
61
  end
62
+
63
+ # @raise [OmniAI::Error]
64
+ #
65
+ # @param input [String] required
66
+ # @param model [String] required
67
+ # @param voice [String] required
68
+ # @param speed [Float] optional
69
+ # @param format [String] optional (default "aac"):
70
+ # - "aac"
71
+ # - "mp3"
72
+ # - "flac"
73
+ # - "opus"
74
+ # - "pcm"
75
+ # - "wav"
76
+ #
77
+ # @yield [output] optional
78
+ #
79
+ # @return [Tempfile``]
80
+ def speak(input, model:, voice:, speed: nil, format: nil, &stream)
81
+ raise NotImplementedError, "#{self.class.name}#speak undefined"
82
+ end
62
83
  end
63
84
  end
@@ -0,0 +1,138 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OmniAI
4
+ # An abstract class that provides a consistent interface for processing speak requests.
5
+ #
6
+ # Usage:
7
+ #
8
+ # class OmniAI::OpenAI::Speak < OmniAI::Speakw
9
+ # module Model
10
+ # WHISPER_1 = "whisper-1"
11
+ # end
12
+ #
13
+ # protected
14
+ #
15
+ # # @return [Hash]
16
+ # def payload
17
+ # raise NotImplementedError, "#{self.class.name}#payload undefined"
18
+ # end
19
+ #
20
+ # # @return [String]
21
+ # def path
22
+ # raise NotImplementedError, "#{self.class.name}#path undefined"
23
+ # end
24
+ # end
25
+ #
26
+ # client.transcribe(File.open("..."), model: "...", format: :json)
27
+ class Speak
28
+ module Format
29
+ AAC = 'aac'
30
+ FLAC = 'flac'
31
+ MP3 = 'mp3'
32
+ OPUS = 'opus'
33
+ PCM = 'pcm'
34
+ WAV = 'wav'
35
+ end
36
+
37
+ # @raise [HTTPError]
38
+ #
39
+ # @param client [OmniAI::Client] required
40
+ # @param input [String] required
41
+ # @param model [String] required
42
+ # @param voice [String] required
43
+ # @param speed [Float] optional
44
+ # @param format [String] optional (default "aac"):
45
+ # - "aac"
46
+ # - "mp3"
47
+ # - "flac"
48
+ # - "opus"
49
+ # - "pcm"
50
+ # - "wav"
51
+ #
52
+ # @yield [chunk]
53
+ #
54
+ # @return [Tempfile]
55
+ def self.process!(input, client:, model:, voice:, speed: nil, format: nil, &)
56
+ new(input, client:, model:, voice:, speed:, format:).process!(&)
57
+ end
58
+
59
+ # @param client [OmniAI::Client] required
60
+ # @param input [String] required
61
+ # @param model [String] required
62
+ # @param voice [String] required
63
+ # @param speed [Float] optional
64
+ # @param format [String] optional (default "aac"):
65
+ # - "aac"
66
+ # - "mp3"
67
+ # - "flac"
68
+ # - "opus"
69
+ # - "pcm"
70
+ # - "wav"
71
+ def initialize(input, client:, model:, voice:, speed: nil, format: nil)
72
+ @input = input
73
+ @client = client
74
+ @model = model
75
+ @voice = voice
76
+ @speed = speed
77
+ @format = format
78
+ end
79
+
80
+ # @raise [HTTPError]
81
+ #
82
+ # @yield [chunk]
83
+ #
84
+ # @return [Tempfile]
85
+ def process!(&block)
86
+ response = request!
87
+ raise HTTPError, response.flush unless response.status.ok?
88
+
89
+ if block
90
+ stream!(response:, &block)
91
+ else
92
+ fetch!(response:)
93
+ end
94
+ end
95
+
96
+ protected
97
+
98
+ # @param response [HTTP::Response]
99
+ #
100
+ # @yield [chunk]
101
+ def stream!(response:, &block)
102
+ response.body.each { |chunk| block.call(chunk) }
103
+ end
104
+
105
+ # @param response [HTTP::Response]
106
+ #
107
+ # @return [Tempfile]
108
+ def fetch!(response:)
109
+ tempfile = Tempfile.new(['', ".#{@format}"])
110
+ tempfile.binmode
111
+ response.body.each { |chunk| tempfile << chunk }
112
+ tempfile.rewind
113
+ tempfile
114
+ end
115
+
116
+ # @return [Hash]
117
+ def payload
118
+ {
119
+ model: @model,
120
+ voice: @voice,
121
+ input: @input,
122
+ speed: @speed,
123
+ }.compact
124
+ end
125
+
126
+ # @return [String]
127
+ def path
128
+ raise NotImplementedError, "#{self.class.name}#path undefined"
129
+ end
130
+
131
+ # @return [HTTP::Response]
132
+ def request!
133
+ @client
134
+ .connection
135
+ .post(path, json: payload)
136
+ end
137
+ end
138
+ end
@@ -113,8 +113,8 @@ module OmniAI
113
113
  @client = client
114
114
  end
115
115
 
116
+ # @raise [HTTPError]
116
117
  # @return [OmniAI::Transcribe::Transcription]
117
- # @raise [ExecutionError]
118
118
  def process!
119
119
  response = request!
120
120
  raise HTTPError, response.flush unless response.status.ok?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module OmniAI
4
- VERSION = '1.1.4'
4
+ VERSION = '1.1.5'
5
5
  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: 1.1.4
4
+ version: 1.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin Sylvestre
@@ -76,6 +76,7 @@ files:
76
76
  - lib/omniai/chat/usage.rb
77
77
  - lib/omniai/client.rb
78
78
  - lib/omniai/config.rb
79
+ - lib/omniai/speak.rb
79
80
  - lib/omniai/transcribe.rb
80
81
  - lib/omniai/transcribe/transcription.rb
81
82
  - lib/omniai/version.rb