ruby-openai 1.3.1 → 1.5.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: 2b8fe14b8e08b05f4743569e5c94f92552032802bf0eb4fd39fd8168ea6e1105
4
- data.tar.gz: 70933cec4140ffe73c52e0bc25e5afc2bb65d4348b1c8138f95acc8b7ccdb500
3
+ metadata.gz: eae2966d67581585125aac11431d33db3af2f472d0970dad242316783ded514e
4
+ data.tar.gz: 53f357b92d77a79c48539b69216c4b06c2f0fd0584be17dfbf54576ea02ffed4
5
5
  SHA512:
6
- metadata.gz: 58572f5ea0262e16d9b6a916e5a1ae04e786804cdb04771e443ce8c6010b4d6ba2956e1cb5c82a03d743d83e8511f91e9510b6ac5b36ab257435c5cd02dc41f2
7
- data.tar.gz: b655c9054c7d89c8dfb8b1f364acc7e70a8aece46bdaf4c365a693d81dc97db83f8e6fe325e8e7eabdec12c079aca9c12e402ac909fe485e721cf8613d46f403
6
+ metadata.gz: 67c875aa8dde9a199aead346a6b45af8aed00ddf81b2db667c055c1ef9e86dea2d43e5b3d23e1e659dbfb0468a40ab9c419b52115a61491217c8c1b0d65aff3c
7
+ data.tar.gz: 4d55769b42b9b295ff4c065c9f4abdbaaf5e96b998eb707e3a64f4161355d20c5e8ee0b417c80029b376e70fe9c69e0521c397ac82523aa05874e8ecbeaac7ce
data/.circleci/config.yml CHANGED
@@ -8,7 +8,7 @@ jobs:
8
8
  rubocop:
9
9
  parallelism: 1
10
10
  docker:
11
- - image: cimg/ruby:3.0-node
11
+ - image: cimg/ruby:3.1-node
12
12
  steps:
13
13
  - checkout
14
14
  - ruby/install-deps
@@ -37,4 +37,9 @@ workflows:
37
37
  - test:
38
38
  matrix:
39
39
  parameters:
40
- ruby-image: ['cimg/ruby:2.5-node', 'cimg/ruby:2.6-node', 'cimg/ruby:2.7-node', 'cimg/ruby:3.0-node']
40
+ ruby-image:
41
+ - cimg/ruby:2.5-node
42
+ - cimg/ruby:2.6-node
43
+ - cimg/ruby:2.7-node
44
+ - cimg/ruby:3.0-node
45
+ - cimg/ruby:3.1-node
data/CHANGELOG.md CHANGED
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.5.0] - 2022-09-18
9
+
10
+ ### Added
11
+
12
+ - Add Client#moderations endpoint to check OpenAI's Content Policy.
13
+ - Add Client#edits endpoints to transform inputs according to instructions.
14
+
15
+ ## [1.4.0] - 2021-12-11
16
+
17
+ ### Added
18
+
19
+ - Add Client#engines endpoints to list and query available engines.
20
+ - Add Client#finetunes endpoints to create and use fine-tuned models.
21
+ - Add Client#embeddings endpoint to get vector representations of inputs.
22
+ - Add tests and examples for more engines.
23
+
8
24
  ## [1.3.1] - 2021-07-14
9
25
 
10
26
  ### Changed
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ gemspec
5
5
 
6
6
  gem "byebug", "~> 11.1.3"
7
7
  gem "rake", "~> 13.0"
8
- gem "rspec", "~> 3.10"
9
- gem "rubocop", "~> 1.18.3"
8
+ gem "rspec", "~> 3.11"
9
+ gem "rubocop", "~> 1.28.2"
10
10
  gem "vcr", "~> 6.0.0"
11
- gem "webmock", "~> 3.13.0"
11
+ gem "webmock", "~> 3.18.1"
data/Gemfile.lock CHANGED
@@ -1,9 +1,9 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-openai (1.3.1)
5
- dotenv (~> 2.7.6)
6
- httparty (~> 0.18.1)
4
+ ruby-openai (1.5.0)
5
+ dotenv (>= 2.7.6, < 2.9.0)
6
+ httparty (>= 0.18.1, < 0.21.0)
7
7
 
8
8
  GEM
9
9
  remote: https://rubygems.org/
@@ -14,53 +14,53 @@ GEM
14
14
  byebug (11.1.3)
15
15
  crack (0.4.5)
16
16
  rexml
17
- diff-lcs (1.4.4)
18
- dotenv (2.7.6)
17
+ diff-lcs (1.5.0)
18
+ dotenv (2.8.1)
19
19
  hashdiff (1.0.1)
20
- httparty (0.18.1)
20
+ httparty (0.20.0)
21
21
  mime-types (~> 3.0)
22
22
  multi_xml (>= 0.5.2)
23
- mime-types (3.3.1)
23
+ mime-types (3.4.1)
24
24
  mime-types-data (~> 3.2015)
25
- mime-types-data (3.2021.0704)
25
+ mime-types-data (3.2022.0105)
26
26
  multi_xml (0.6.0)
27
- parallel (1.20.1)
28
- parser (3.0.1.1)
27
+ parallel (1.22.1)
28
+ parser (3.1.2.0)
29
29
  ast (~> 2.4.1)
30
- public_suffix (4.0.6)
31
- rainbow (3.0.0)
30
+ public_suffix (4.0.7)
31
+ rainbow (3.1.1)
32
32
  rake (13.0.6)
33
- regexp_parser (2.1.1)
33
+ regexp_parser (2.3.1)
34
34
  rexml (3.2.5)
35
- rspec (3.10.0)
36
- rspec-core (~> 3.10.0)
37
- rspec-expectations (~> 3.10.0)
38
- rspec-mocks (~> 3.10.0)
39
- rspec-core (3.10.1)
40
- rspec-support (~> 3.10.0)
41
- rspec-expectations (3.10.1)
35
+ rspec (3.11.0)
36
+ rspec-core (~> 3.11.0)
37
+ rspec-expectations (~> 3.11.0)
38
+ rspec-mocks (~> 3.11.0)
39
+ rspec-core (3.11.0)
40
+ rspec-support (~> 3.11.0)
41
+ rspec-expectations (3.11.0)
42
42
  diff-lcs (>= 1.2.0, < 2.0)
43
- rspec-support (~> 3.10.0)
44
- rspec-mocks (3.10.1)
43
+ rspec-support (~> 3.11.0)
44
+ rspec-mocks (3.11.0)
45
45
  diff-lcs (>= 1.2.0, < 2.0)
46
- rspec-support (~> 3.10.0)
47
- rspec-support (3.10.1)
48
- rubocop (1.18.3)
46
+ rspec-support (~> 3.11.0)
47
+ rspec-support (3.11.0)
48
+ rubocop (1.28.2)
49
49
  parallel (~> 1.10)
50
- parser (>= 3.0.0.0)
50
+ parser (>= 3.1.0.0)
51
51
  rainbow (>= 2.2.2, < 4.0)
52
52
  regexp_parser (>= 1.8, < 3.0)
53
53
  rexml
54
- rubocop-ast (>= 1.7.0, < 2.0)
54
+ rubocop-ast (>= 1.17.0, < 2.0)
55
55
  ruby-progressbar (~> 1.7)
56
56
  unicode-display_width (>= 1.4.0, < 3.0)
57
- rubocop-ast (1.7.0)
58
- parser (>= 3.0.1.1)
57
+ rubocop-ast (1.17.0)
58
+ parser (>= 3.1.1.0)
59
59
  ruby-progressbar (1.11.0)
60
- unicode-display_width (2.0.0)
60
+ unicode-display_width (2.1.0)
61
61
  vcr (6.0.0)
62
- webmock (3.13.0)
63
- addressable (>= 2.3.6)
62
+ webmock (3.18.1)
63
+ addressable (>= 2.8.0)
64
64
  crack (>= 0.3.2)
65
65
  hashdiff (>= 0.4.0, < 2.0.0)
66
66
 
@@ -70,11 +70,11 @@ PLATFORMS
70
70
  DEPENDENCIES
71
71
  byebug (~> 11.1.3)
72
72
  rake (~> 13.0)
73
- rspec (~> 3.10)
74
- rubocop (~> 1.18.3)
73
+ rspec (~> 3.11)
74
+ rubocop (~> 1.28.2)
75
75
  ruby-openai!
76
76
  vcr (~> 6.0.0)
77
- webmock (~> 3.13.0)
77
+ webmock (~> 3.18.1)
78
78
 
79
79
  BUNDLED WITH
80
- 2.2.3
80
+ 2.2.20
data/README.md CHANGED
@@ -5,27 +5,37 @@
5
5
  [![CircleCI Build Status](https://circleci.com/gh/alexrudall/ruby-openai.svg?style=shield)](https://circleci.com/gh/alexrudall/ruby-openai)
6
6
  [![Maintainability](https://api.codeclimate.com/v1/badges/a99a88d28ad37a79dbf6/maintainability)](https://codeclimate.com/github/codeclimate/codeclimate/maintainability)
7
7
 
8
- A simple Ruby wrapper for the [OpenAI GPT-3 API](https://openai.com/blog/openai-api/).
8
+ Use the [OpenAI GPT-3 API](https://openai.com/blog/openai-api/) with Ruby! 🤖❤️
9
9
 
10
10
  ## Installation
11
11
 
12
+ ### Bundler
13
+
12
14
  Add this line to your application's Gemfile:
13
15
 
14
16
  ```ruby
15
- gem 'ruby-openai'
17
+ gem 'ruby-openai'
16
18
  ```
17
19
 
18
20
  And then execute:
19
21
 
20
- $ bundle install
22
+ $ bundle install
23
+
24
+ ### Gem install
21
25
 
22
- Or install it yourself as:
26
+ Or install with:
23
27
 
24
- $ gem install ruby-openai
28
+ $ gem install ruby-openai
29
+
30
+ and require with:
31
+
32
+ ```ruby
33
+ require "ruby/openai"
34
+ ```
25
35
 
26
36
  ## Usage
27
37
 
28
- Get your API key from [https://beta.openai.com/docs/developer-quickstart/your-api-keys](https://beta.openai.com/docs/developer-quickstart/your-api-keys)
38
+ Get your API key from [https://beta.openai.com/account/api-keys](https://beta.openai.com/account/api-keys)
29
39
 
30
40
  ### With dotenv
31
41
 
@@ -37,7 +47,7 @@ If you're using [dotenv](https://github.com/motdotla/dotenv), you can add your s
37
47
 
38
48
  And create a client:
39
49
 
40
- ```
50
+ ```ruby
41
51
  client = OpenAI::Client.new
42
52
  ```
43
53
 
@@ -45,85 +55,166 @@ And create a client:
45
55
 
46
56
  Alternatively you can pass your key directly to a new client:
47
57
 
48
- ```
58
+ ```ruby
49
59
  client = OpenAI::Client.new(access_token: "access_token_goes_here")
50
60
  ```
51
61
 
62
+ #### Examples
63
+
64
+ - [GPT-3](https://beta.openai.com/docs/engines/gpt-3)
65
+ - text-ada-001
66
+ - text-babbage-001
67
+ - text-curie-001
68
+ - text-davinci-001
69
+ - [Codex (private beta)](https://beta.openai.com/docs/engines/codex-series-private-beta)
70
+ - code-davinci-002
71
+ - code-cushman-001
72
+ - [Content Filter](https://beta.openai.com/docs/engines/content-filter)
73
+ - content-filter-alpha
74
+
52
75
  ### Completions
53
76
 
54
- The engine options are currently "ada", "babbage", "curie" and "davinci". Hit the OpenAI API for a completion:
77
+ Hit the OpenAI API for a completion:
55
78
 
56
- ```
57
- response = client.completions(engine: "davinci", parameters: { prompt: "Once upon a time", max_tokens: 5 })
79
+ ```ruby
80
+ response = client.completions(engine: "text-davinci-001", parameters: { prompt: "Once upon a time", max_tokens: 5 })
58
81
  puts response.parsed_response['choices'].map{ |c| c["text"] }
59
82
  => [", there lived a great"]
60
83
  ```
61
84
 
85
+ ### Edits
86
+
87
+ Send a string and some instructions for what to do to the string:
88
+
89
+ ```ruby
90
+ response = client.edits(
91
+ parameters: {
92
+ model: "text-davinci-edit-001",
93
+ input: "What day of the wek is it?",
94
+ instruction: "Fix the spelling mistakes"
95
+ }
96
+ )
97
+ puts response.dig("choices", 0, "text")
98
+ => What day of the week is it?
99
+ ```
100
+
101
+ ### Embeddings
102
+
103
+ You can use the embeddings endpoint to get a vector of numbers representing an input. You can then compare these vectors for different inputs to efficiently check how similar the inputs are.
104
+
105
+ ```ruby
106
+ client.embeddings(
107
+ engine: "babbage-similarity",
108
+ parameters: {
109
+ input: "The food was delicious and the waiter..."
110
+ }
111
+ )
112
+ ```
113
+
62
114
  ### Files
63
115
 
64
116
  Put your data in a `.jsonl` file like this:
65
117
 
66
- ```
118
+ ```json
67
119
  {"text": "puppy A is happy", "metadata": "emotional state of puppy A"}
68
120
  {"text": "puppy B is sad", "metadata": "emotional state of puppy B"}
69
121
  ```
70
122
 
71
123
  and pass the path to `client.files.upload` to upload it to OpenAI, and then interact with it:
72
124
 
73
- ```
125
+ ```ruby
74
126
  client.files.upload(parameters: { file: 'path/to/puppy.jsonl', purpose: 'search' })
75
127
  client.files.list
76
128
  client.files.retrieve(id: 123)
77
129
  client.files.delete(id: 123)
78
130
  ```
79
131
 
80
- ### Search
132
+ ### Fine-tunes
81
133
 
82
- Pass documents and a query string to get semantic search scores against each document:
134
+ Put your fine-tuning data in a `.jsonl` file like this:
83
135
 
136
+ ```json
137
+ {"prompt":"Overjoyed with my new phone! ->", "completion":" positive"}
138
+ {"prompt":"@lakers disappoint for a third straight night ->", "completion":" negative"}
84
139
  ```
85
- response = client.search(engine: "ada", parameters: { documents: %w[washington hospital school], query: "president" })
86
- puts response["data"].map { |d| d["score"] }
87
- => [202.0, 48.052, 19.247]
140
+
141
+ and pass the path to `client.files.upload` to upload it to OpenAI and get its ID:
142
+
143
+ ```ruby
144
+ response = client.files.upload(parameters: { file: 'path/to/sentiment.jsonl', purpose: 'fine-tune' })
145
+ file_id = JSON.parse(response.body)["id"]
88
146
  ```
89
147
 
90
- You can alternatively search using the ID of a file you've uploaded:
148
+ You can then use this file ID to create a fine-tune model:
91
149
 
150
+ ```ruby
151
+ response = client.finetunes.create(
152
+ parameters: {
153
+ training_file: file_id,
154
+ model: "text-ada-001"
155
+ })
156
+ fine_tune_id = JSON.parse(response.body)["id"]
92
157
  ```
93
- client.search(engine: "ada", parameters: { file: "abc123", query: "happy" })
158
+
159
+ That will give you the fine-tune ID. If you made a mistake you can cancel the fine-tune model before it is processed:
160
+
161
+ ```ruby
162
+ client.finetunes.cancel(id: fine_tune_id)
94
163
  ```
95
164
 
96
- ### Answers
165
+ You may need to wait a short time for processing to complete. Once processed, you can use list or retrieve to get the name of the fine-tuned model:
97
166
 
98
- Pass documents, a question string, and an example question/response to get an answer to a question:
167
+ ```ruby
168
+ client.finetunes.list
169
+ response = client.finetunes.retrieve(id: fine_tune_id)
170
+ fine_tuned_model = JSON.parse(response.body)["fine_tuned_model"]
171
+ ```
172
+
173
+ This fine-tuned model name can then be used in classifications:
99
174
 
175
+ ```ruby
176
+ response = client.completions(
177
+ parameters: {
178
+ model: fine_tuned_model,
179
+ prompt: "I love Mondays!"
180
+ }
181
+ )
182
+ JSON.parse(response.body)["choices"].map { |c| c["text"] }
100
183
  ```
101
- response = client.answers(parameters: {
102
- documents: ["Puppy A is happy.", "Puppy B is sad."],
103
- question: "which puppy is happy?",
104
- model: "curie",
105
- examples_context: "In 2017, U.S. life expectancy was 78.6 years.",
106
- examples: [["What is human life expectancy in the United States?","78 years."]],
107
- })
184
+
185
+ Do not pass the engine parameter when using a fine-tuned model.
186
+
187
+ ### Moderations
188
+
189
+ Pass a string to check if it violates OpenAI's Content Policy:
190
+
191
+ ```ruby
192
+ response = client.moderations(parameters: { input: "I'm worried about that." })
193
+ puts response.dig("results", 0, "category_scores", "hate")
194
+ => 5.505014632944949e-05
108
195
  ```
109
196
 
110
- Or use the ID of a file you've uploaded:
197
+ ### Searches
111
198
 
199
+ Pass documents and a query string to get semantic search scores against each document:
200
+
201
+ ```ruby
202
+ response = client.search(engine: "text-ada-001", parameters: { documents: %w[washington hospital school], query: "president" })
203
+ puts response["data"].map { |d| d["score"] }
204
+ => [202.0, 48.052, 19.247]
112
205
  ```
113
- response = client.answers(parameters: {
114
- file: "123abc",
115
- question: "which puppy is happy?",
116
- model: "curie",
117
- examples_context: "In 2017, U.S. life expectancy was 78.6 years.",
118
- examples: [["What is human life expectancy in the United States?","78 years."]],
119
- })
206
+
207
+ You can alternatively search using the ID of a file you've uploaded:
208
+
209
+ ```ruby
210
+ client.search(engine: "text-ada-001", parameters: { file: "abc123", query: "happy" })
120
211
  ```
121
212
 
122
213
  ### Classifications
123
214
 
124
215
  Pass examples and a query to predict the most likely labels:
125
216
 
126
- ```
217
+ ```ruby
127
218
  response = client.classifications(parameters: {
128
219
  examples: [
129
220
  ["A happy moment", "Positive"],
@@ -131,20 +222,55 @@ Pass examples and a query to predict the most likely labels:
131
222
  ["I am feeling awesome", "Positive"]
132
223
  ],
133
224
  query: "It is a raining day :(",
134
- model: "ada"
225
+ model: "text-ada-001"
135
226
  })
136
227
  ```
137
228
 
138
229
  Or use the ID of a file you've uploaded:
139
230
 
140
- ```
231
+ ```ruby
141
232
  response = client.classifications(parameters: {
142
233
  file: "123abc,
143
234
  query: "It is a raining day :(",
144
- model: "ada"
235
+ model: "text-ada-001"
236
+ })
237
+ ```
238
+
239
+ ### Answers
240
+
241
+ Pass documents, a question string, and an example question/response to get an answer to a question:
242
+
243
+ ```ruby
244
+ response = client.answers(parameters: {
245
+ documents: ["Puppy A is happy.", "Puppy B is sad."],
246
+ question: "which puppy is happy?",
247
+ model: "text-curie-001",
248
+ examples_context: "In 2017, U.S. life expectancy was 78.6 years.",
249
+ examples: [["What is human life expectancy in the United States?","78 years."]],
250
+ })
251
+ ```
252
+
253
+ Or use the ID of a file you've uploaded:
254
+
255
+ ```ruby
256
+ response = client.answers(parameters: {
257
+ file: "123abc",
258
+ question: "which puppy is happy?",
259
+ model: "text-curie-001",
260
+ examples_context: "In 2017, U.S. life expectancy was 78.6 years.",
261
+ examples: [["What is human life expectancy in the United States?","78 years."]],
145
262
  })
146
263
  ```
147
264
 
265
+ ### Engines
266
+
267
+ There are different engines that can be used to generate text. For a full list and to retrieve information about a single engine:
268
+
269
+ ```ruby
270
+ client.engines.list
271
+ client.engines.retrieve(id: 'text-ada-001')
272
+ ```
273
+
148
274
  ## Development
149
275
 
150
276
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -4,7 +4,7 @@ module OpenAI
4
4
  base_uri "https://api.openai.com"
5
5
 
6
6
  def initialize(access_token: nil)
7
- @access_token = access_token || ENV["OPENAI_ACCESS_TOKEN"]
7
+ @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
8
  end
9
9
 
10
10
  def answers(version: default_version, parameters: {})
@@ -15,14 +15,38 @@ module OpenAI
15
15
  post(url: "/#{version}/classifications", parameters: parameters)
16
16
  end
17
17
 
18
- def completions(engine:, version: default_version, parameters: {})
19
- post(url: "/#{version}/engines/#{engine}/completions", parameters: parameters)
18
+ def completions(engine: nil, version: default_version, parameters: {})
19
+ if engine
20
+ post(url: "/#{version}/engines/#{engine}/completions", parameters: parameters)
21
+ else
22
+ post(url: "/#{version}/completions", parameters: parameters)
23
+ end
24
+ end
25
+
26
+ def edits(version: default_version, parameters: {})
27
+ post(url: "/#{version}/edits", parameters: parameters)
28
+ end
29
+
30
+ def embeddings(engine:, version: default_version, parameters: {})
31
+ post(url: "/#{version}/engines/#{engine}/embeddings", parameters: parameters)
32
+ end
33
+
34
+ def engines
35
+ @engines ||= OpenAI::Engines.new(access_token: @access_token)
20
36
  end
21
37
 
22
38
  def files
23
39
  @files ||= OpenAI::Files.new(access_token: @access_token)
24
40
  end
25
41
 
42
+ def finetunes
43
+ @finetunes ||= OpenAI::Finetunes.new(access_token: @access_token)
44
+ end
45
+
46
+ def moderations(version: default_version, parameters: {})
47
+ post(url: "/#{version}/moderations", parameters: parameters)
48
+ end
49
+
26
50
  # rubocop:disable Layout/LineLength
27
51
  # rubocop:disable Metrics/ParameterLists
28
52
  def search(engine:, query: nil, documents: nil, file: nil, version: default_version, parameters: {})
@@ -0,0 +1,36 @@
1
+ module OpenAI
2
+ class Engines
3
+ include HTTParty
4
+ base_uri "https://api.openai.com"
5
+
6
+ def initialize(access_token: nil)
7
+ @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
+ end
9
+
10
+ def list(version: default_version)
11
+ self.class.get(
12
+ "/#{version}/engines",
13
+ headers: {
14
+ "Content-Type" => "application/json",
15
+ "Authorization" => "Bearer #{@access_token}"
16
+ }
17
+ )
18
+ end
19
+
20
+ def retrieve(id:, version: default_version)
21
+ self.class.get(
22
+ "/#{version}/engines/#{id}",
23
+ headers: {
24
+ "Content-Type" => "application/json",
25
+ "Authorization" => "Bearer #{@access_token}"
26
+ }
27
+ )
28
+ end
29
+
30
+ private
31
+
32
+ def default_version
33
+ "v1".freeze
34
+ end
35
+ end
36
+ end
@@ -4,7 +4,7 @@ module OpenAI
4
4
  base_uri "https://api.openai.com"
5
5
 
6
6
  def initialize(access_token: nil)
7
- @access_token = access_token || ENV["OPENAI_ACCESS_TOKEN"]
7
+ @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
8
  end
9
9
 
10
10
  def list(version: default_version)
@@ -0,0 +1,67 @@
1
+ module OpenAI
2
+ class Finetunes
3
+ include HTTParty
4
+ base_uri "https://api.openai.com"
5
+
6
+ def initialize(access_token: nil)
7
+ @access_token = access_token || ENV.fetch("OPENAI_ACCESS_TOKEN")
8
+ end
9
+
10
+ def list(version: default_version)
11
+ self.class.get(
12
+ "/#{version}/fine-tunes",
13
+ headers: {
14
+ "Content-Type" => "application/json",
15
+ "Authorization" => "Bearer #{@access_token}"
16
+ }
17
+ )
18
+ end
19
+
20
+ def create(version: default_version, parameters: {})
21
+ self.class.post(
22
+ "/#{version}/fine-tunes",
23
+ headers: {
24
+ "Content-Type" => "application/json",
25
+ "Authorization" => "Bearer #{@access_token}"
26
+ },
27
+ body: parameters.to_json
28
+ )
29
+ end
30
+
31
+ def retrieve(id:, version: default_version)
32
+ self.class.get(
33
+ "/#{version}/fine-tunes/#{id}",
34
+ headers: {
35
+ "Content-Type" => "application/json",
36
+ "Authorization" => "Bearer #{@access_token}"
37
+ }
38
+ )
39
+ end
40
+
41
+ def cancel(id:, version: default_version)
42
+ self.class.post(
43
+ "/#{version}/fine-tunes/#{id}/cancel",
44
+ headers: {
45
+ "Content-Type" => "application/json",
46
+ "Authorization" => "Bearer #{@access_token}"
47
+ }
48
+ )
49
+ end
50
+
51
+ def events(id:, version: default_version)
52
+ self.class.get(
53
+ "/#{version}/fine-tunes/#{id}/events",
54
+ headers: {
55
+ "Content-Type" => "application/json",
56
+ "Authorization" => "Bearer #{@access_token}"
57
+ }
58
+ )
59
+ end
60
+
61
+ private
62
+
63
+ def default_version
64
+ "v1".freeze
65
+ end
66
+ end
67
+ end
@@ -1,5 +1,5 @@
1
1
  module Ruby
2
2
  module OpenAI
3
- VERSION = "1.3.1".freeze
3
+ VERSION = "1.5.0".freeze
4
4
  end
5
5
  end
data/lib/ruby/openai.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "httparty"
2
+ require "ruby/openai/engines"
2
3
  require "ruby/openai/files"
4
+ require "ruby/openai/finetunes"
3
5
  require "ruby/openai/client"
4
6
  require "ruby/openai/version"
5
7
  require "dotenv/load"
data/ruby-openai.gemspec CHANGED
@@ -14,6 +14,7 @@ Gem::Specification.new do |spec|
14
14
  spec.metadata["homepage_uri"] = spec.homepage
15
15
  spec.metadata["source_code_uri"] = "https://github.com/alexrudall/ruby-openai"
16
16
  spec.metadata["changelog_uri"] = "https://github.com/alexrudall/ruby-openai/blob/main/CHANGELOG.md"
17
+ spec.metadata["rubygems_mfa_required"] = "true"
17
18
 
18
19
  # Specify which files should be added to the gem when it is released.
19
20
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -24,6 +25,6 @@ Gem::Specification.new do |spec|
24
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
25
26
  spec.require_paths = ["lib"]
26
27
 
27
- spec.add_dependency "dotenv", "~> 2.7.6"
28
- spec.add_dependency "httparty", "~> 0.18.1"
28
+ spec.add_dependency "dotenv", ">= 2.7.6", "< 2.9.0"
29
+ spec.add_dependency "httparty", ">= 0.18.1", "< 0.21.0"
29
30
  end
metadata CHANGED
@@ -1,43 +1,55 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-openai
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-07-14 00:00:00.000000000 Z
11
+ date: 2022-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: 2.7.6
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 2.9.0
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
29
  version: 2.7.6
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 2.9.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  name: httparty
29
35
  requirement: !ruby/object:Gem::Requirement
30
36
  requirements:
31
- - - "~>"
37
+ - - ">="
32
38
  - !ruby/object:Gem::Version
33
39
  version: 0.18.1
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: 0.21.0
34
43
  type: :runtime
35
44
  prerelease: false
36
45
  version_requirements: !ruby/object:Gem::Requirement
37
46
  requirements:
38
- - - "~>"
47
+ - - ">="
39
48
  - !ruby/object:Gem::Version
40
49
  version: 0.18.1
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: 0.21.0
41
53
  description:
42
54
  email:
43
55
  - alexrudall@users.noreply.github.com
@@ -65,7 +77,9 @@ files:
65
77
  - bin/setup
66
78
  - lib/ruby/openai.rb
67
79
  - lib/ruby/openai/client.rb
80
+ - lib/ruby/openai/engines.rb
68
81
  - lib/ruby/openai/files.rb
82
+ - lib/ruby/openai/finetunes.rb
69
83
  - lib/ruby/openai/version.rb
70
84
  - pull_request_template.md
71
85
  - ruby-openai.gemspec
@@ -76,6 +90,7 @@ metadata:
76
90
  homepage_uri: https://github.com/alexrudall/ruby-openai
77
91
  source_code_uri: https://github.com/alexrudall/ruby-openai
78
92
  changelog_uri: https://github.com/alexrudall/ruby-openai/blob/main/CHANGELOG.md
93
+ rubygems_mfa_required: 'true'
79
94
  post_install_message:
80
95
  rdoc_options: []
81
96
  require_paths:
@@ -91,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
91
106
  - !ruby/object:Gem::Version
92
107
  version: '0'
93
108
  requirements: []
94
- rubygems_version: 3.2.3
109
+ rubygems_version: 3.2.33
95
110
  signing_key:
96
111
  specification_version: 4
97
112
  summary: A Ruby gem for the OpenAI GPT-3 API