openai.rb 0.0.0 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +27 -0
- data/.rubocop.yml +18 -0
- data/.ruby-version +1 -1
- data/Gemfile +9 -5
- data/Gemfile.lock +29 -24
- data/README.md +401 -0
- data/bin/console +9 -4
- data/lib/openai/api/cache.rb +137 -0
- data/lib/openai/api/client.rb +86 -0
- data/lib/openai/api/resource.rb +232 -0
- data/lib/openai/api/response.rb +384 -0
- data/lib/openai/api.rb +75 -0
- data/lib/openai/chat.rb +125 -0
- data/lib/openai/tokenizer.rb +50 -0
- data/lib/openai/util.rb +47 -0
- data/lib/openai/version.rb +1 -1
- data/lib/openai.rb +38 -357
- data/openai.gemspec +9 -3
- data/spec/data/sample_french.mp3 +0 -0
- data/spec/data/sample_image.png +0 -0
- data/spec/data/sample_image_mask.png +0 -0
- data/spec/shared/api_resource_context.rb +22 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/unit/openai/api/audio_spec.rb +78 -0
- data/spec/unit/openai/api/cache_spec.rb +115 -0
- data/spec/unit/openai/api/chat_completions_spec.rb +130 -0
- data/spec/unit/openai/api/completions_spec.rb +125 -0
- data/spec/unit/openai/api/edits_spec.rb +40 -0
- data/spec/unit/openai/api/embeddings_spec.rb +45 -0
- data/spec/unit/openai/api/files_spec.rb +163 -0
- data/spec/unit/openai/api/fine_tunes_spec.rb +322 -0
- data/spec/unit/openai/api/images_spec.rb +137 -0
- data/spec/unit/openai/api/models_spec.rb +98 -0
- data/spec/unit/openai/api/moderations_spec.rb +63 -0
- data/spec/unit/openai/api/response_spec.rb +203 -0
- data/spec/unit/openai/chat_spec.rb +32 -0
- data/spec/unit/openai/tokenizer_spec.rb +45 -0
- data/spec/unit/openai_spec.rb +47 -736
- metadata +97 -7
- data/bin/codegen +0 -371
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f049bfa7ff5419acf81a7cabc6e34b6bd223b8f9fcb634008544d93d87170c2f
|
4
|
+
data.tar.gz: d614701b82eaf3ec84e9ddb432505bbbd786f71d75378534b23400446ddb8e7b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c321d0184079826648569ab13b04675d9cbfb04027fed85b191d462c6585cc375d9144dede8ecf6d9995e48be935bf6879dba969e17492cb9c4ffe100f468fea
|
7
|
+
data.tar.gz: 3fd0d70f0007e3900e6df1f39ef18dcbd618b7e3384de229b50936924bb4bf80e79d19bd7a531be6caade2b915c03581cccabc32f01b5921c79bd88e224c27a0
|
@@ -0,0 +1,27 @@
|
|
1
|
+
name: Ruby Gem CI
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
matrix:
|
10
|
+
http_version: ['~> 4.4', '~> 5.1']
|
11
|
+
ruby_version: ['2.7.8']
|
12
|
+
|
13
|
+
steps:
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
- name: Update .ruby-version
|
16
|
+
run: echo "${{ matrix.ruby_version }}" > .ruby-version
|
17
|
+
- name: Set up Ruby
|
18
|
+
uses: ruby/setup-ruby@v1
|
19
|
+
with:
|
20
|
+
ruby-version: ${{ matrix.ruby_version }}
|
21
|
+
bundler-cache: true
|
22
|
+
- name: Install dependencies
|
23
|
+
run: |
|
24
|
+
echo "gem 'http', '${{ matrix.http_version }}'" >> Gemfile.local
|
25
|
+
bundle install
|
26
|
+
- name: Run tests
|
27
|
+
run: bundle exec rspec
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
Metrics/AbcSize:
|
2
|
+
Enabled: false
|
3
|
+
|
4
|
+
Metrics/BlockLength:
|
5
|
+
Enabled: false
|
6
|
+
|
7
|
+
Metrics/MethodLength:
|
8
|
+
Enabled: false
|
9
|
+
|
10
|
+
Style/Documentation:
|
11
|
+
Enabled: false
|
12
|
+
|
13
|
+
Layout/LineLength:
|
14
|
+
Enabled: false
|
15
|
+
|
16
|
+
Style/FrozenStringLiteralComment:
|
17
|
+
SafeAutoCorrect: true
|
18
|
+
Enabled: true
|
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.
|
1
|
+
2.7.7
|
data/Gemfile
CHANGED
@@ -11,13 +11,17 @@ group :test do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
group :lint do
|
14
|
-
gem 'rubocop'
|
15
|
-
gem 'rubocop-rspec'
|
14
|
+
gem 'rubocop', '~> 1.31.1'
|
15
|
+
gem 'rubocop-rspec', '~> 2.11.1'
|
16
16
|
end
|
17
17
|
|
18
18
|
gem 'pry', '~> 0.13.1'
|
19
|
-
gem 'pry-byebug', '
|
19
|
+
gem 'pry-byebug', '3.9.0'
|
20
20
|
|
21
|
-
gem
|
21
|
+
gem 'dotenv', '~> 2.8'
|
22
22
|
|
23
|
-
gem
|
23
|
+
gem 'slop', '~> 4.10'
|
24
|
+
|
25
|
+
gem 'http', '~> 4.4' # For testing the older version of HTTP.rb
|
26
|
+
|
27
|
+
gem 'rb_sys', '~> 0.9.70'
|
data/Gemfile.lock
CHANGED
@@ -1,10 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
openai.rb (0.0.
|
4
|
+
openai.rb (0.0.3)
|
5
|
+
abstract_type (~> 0.0.7)
|
5
6
|
anima (~> 0.3)
|
6
7
|
concord (~> 0.1)
|
7
|
-
http (
|
8
|
+
http (>= 4.4, < 6.0)
|
9
|
+
ice_nine (~> 0.11.x)
|
10
|
+
memoizable (~> 0.4.2)
|
11
|
+
tiktoken_ruby (~> 0.0.3)
|
8
12
|
|
9
13
|
GEM
|
10
14
|
remote: https://rubygems.org/
|
@@ -13,7 +17,7 @@ GEM
|
|
13
17
|
adamantium (0.2.0)
|
14
18
|
ice_nine (~> 0.11.0)
|
15
19
|
memoizable (~> 0.4.0)
|
16
|
-
addressable (2.8.
|
20
|
+
addressable (2.8.2)
|
17
21
|
public_suffix (>= 2.0.2, < 6.0)
|
18
22
|
anima (0.3.2)
|
19
23
|
abstract_type (~> 0.0.7)
|
@@ -34,24 +38,23 @@ GEM
|
|
34
38
|
ffi-compiler (1.0.1)
|
35
39
|
ffi (>= 1.0.0)
|
36
40
|
rake
|
37
|
-
http (
|
38
|
-
addressable (~> 2.
|
41
|
+
http (4.4.1)
|
42
|
+
addressable (~> 2.3)
|
39
43
|
http-cookie (~> 1.0)
|
40
44
|
http-form_data (~> 2.2)
|
41
|
-
|
45
|
+
http-parser (~> 1.2.0)
|
42
46
|
http-cookie (1.0.5)
|
43
47
|
domain_name (~> 0.5)
|
44
48
|
http-form_data (2.3.0)
|
49
|
+
http-parser (1.2.3)
|
50
|
+
ffi-compiler (>= 1.0, < 2.0)
|
45
51
|
ice_nine (0.11.2)
|
46
52
|
json (2.6.3)
|
47
|
-
llhttp-ffi (0.4.0)
|
48
|
-
ffi-compiler (~> 1.0)
|
49
|
-
rake (~> 13.0)
|
50
53
|
memoizable (0.4.2)
|
51
54
|
thread_safe (~> 0.3, >= 0.3.1)
|
52
55
|
method_source (1.0.0)
|
53
56
|
parallel (1.22.1)
|
54
|
-
parser (3.2.
|
57
|
+
parser (3.2.2.0)
|
55
58
|
ast (~> 2.4.1)
|
56
59
|
pry (0.13.1)
|
57
60
|
coderay (~> 1.1)
|
@@ -62,6 +65,7 @@ GEM
|
|
62
65
|
public_suffix (5.0.1)
|
63
66
|
rainbow (3.1.1)
|
64
67
|
rake (13.0.6)
|
68
|
+
rb_sys (0.9.70)
|
65
69
|
regexp_parser (2.7.0)
|
66
70
|
rexml (3.2.5)
|
67
71
|
rspec (3.12.0)
|
@@ -73,30 +77,28 @@ GEM
|
|
73
77
|
rspec-expectations (3.12.2)
|
74
78
|
diff-lcs (>= 1.2.0, < 2.0)
|
75
79
|
rspec-support (~> 3.12.0)
|
76
|
-
rspec-mocks (3.12.
|
80
|
+
rspec-mocks (3.12.5)
|
77
81
|
diff-lcs (>= 1.2.0, < 2.0)
|
78
82
|
rspec-support (~> 3.12.0)
|
79
83
|
rspec-support (3.12.0)
|
80
|
-
rubocop (1.
|
84
|
+
rubocop (1.31.2)
|
81
85
|
json (~> 2.3)
|
82
86
|
parallel (~> 1.10)
|
83
|
-
parser (>= 3.
|
87
|
+
parser (>= 3.1.0.0)
|
84
88
|
rainbow (>= 2.2.2, < 4.0)
|
85
89
|
regexp_parser (>= 1.8, < 3.0)
|
86
90
|
rexml (>= 3.2.5, < 4.0)
|
87
|
-
rubocop-ast (>= 1.
|
91
|
+
rubocop-ast (>= 1.18.0, < 2.0)
|
88
92
|
ruby-progressbar (~> 1.7)
|
89
|
-
unicode-display_width (>=
|
93
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
90
94
|
rubocop-ast (1.28.0)
|
91
95
|
parser (>= 3.2.1.0)
|
92
|
-
rubocop-
|
93
|
-
rubocop (~> 1.
|
94
|
-
rubocop-rspec (2.19.0)
|
95
|
-
rubocop (~> 1.33)
|
96
|
-
rubocop-capybara (~> 2.17)
|
96
|
+
rubocop-rspec (2.11.1)
|
97
|
+
rubocop (~> 1.19)
|
97
98
|
ruby-progressbar (1.13.0)
|
98
99
|
slop (4.10.1)
|
99
100
|
thread_safe (0.3.6)
|
101
|
+
tiktoken_ruby (0.0.4)
|
100
102
|
unf (0.1.4)
|
101
103
|
unf_ext
|
102
104
|
unf_ext (0.0.8.2)
|
@@ -104,19 +106,22 @@ GEM
|
|
104
106
|
|
105
107
|
PLATFORMS
|
106
108
|
arm64-darwin-21
|
109
|
+
ruby
|
107
110
|
|
108
111
|
DEPENDENCIES
|
109
112
|
dotenv (~> 2.8)
|
113
|
+
http (~> 4.4)
|
110
114
|
openai.rb!
|
111
115
|
pry (~> 0.13.1)
|
112
|
-
pry-byebug (
|
116
|
+
pry-byebug (= 3.9.0)
|
117
|
+
rb_sys (~> 0.9.70)
|
113
118
|
rspec (~> 3.12)
|
114
|
-
rubocop
|
115
|
-
rubocop-rspec
|
119
|
+
rubocop (~> 1.31.1)
|
120
|
+
rubocop-rspec (~> 2.11.1)
|
116
121
|
slop (~> 4.10)
|
117
122
|
|
118
123
|
RUBY VERSION
|
119
|
-
ruby 2.
|
124
|
+
ruby 2.7.7p221
|
120
125
|
|
121
126
|
BUNDLED WITH
|
122
127
|
2.3.9
|
data/README.md
ADDED
@@ -0,0 +1,401 @@
|
|
1
|
+
# OpenAI.rb
|
2
|
+
|
3
|
+
A comprehensive (as of March 25th, 2023) OpenAI API wrapper with built-in support for:
|
4
|
+
|
5
|
+
* caching
|
6
|
+
* tokenization
|
7
|
+
* response streaming
|
8
|
+
* a simple chainable abstraction for chats
|
9
|
+
|
10
|
+
## Install and Setup
|
11
|
+
|
12
|
+
To install, you should be able to do:
|
13
|
+
|
14
|
+
```sh
|
15
|
+
$ gem install openai.rb
|
16
|
+
```
|
17
|
+
|
18
|
+
Usage:
|
19
|
+
|
20
|
+
```ruby
|
21
|
+
require 'openai'
|
22
|
+
|
23
|
+
openai = OpenAI.create(ENV.fetch('OPENAI_API_KEY'))
|
24
|
+
openai.api.chat_completions.create(...)
|
25
|
+
openai.api.embeddings.create(...)
|
26
|
+
openai.api.models.list
|
27
|
+
# etc
|
28
|
+
```
|
29
|
+
|
30
|
+
### Caching
|
31
|
+
|
32
|
+
Caching for requests is built-in. The supported caching strategy writes response files in a directory you
|
33
|
+
specify (I chose to write as separate files since I often want to dig around and see the raw data I'm getting
|
34
|
+
back).
|
35
|
+
|
36
|
+
To enable caching:
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
require 'openai'
|
40
|
+
|
41
|
+
# This directory should already exist
|
42
|
+
cache_dir = Pathname.new('~/.cache/openai')
|
43
|
+
|
44
|
+
openai = OpenAI.create(ENV.fetch('OPENAI_API_KEY'), cache: cache_dir)
|
45
|
+
|
46
|
+
# Will hit the API:
|
47
|
+
openai.api.completions.create(model: 'text-davinci-002', prompt: 'Say hi')
|
48
|
+
# Will reuse the cached response:
|
49
|
+
openai.api.completions.create(model: 'text-davinci-002', prompt: 'Say hi')
|
50
|
+
```
|
51
|
+
|
52
|
+
NOTE: Delete requests are not cached
|
53
|
+
|
54
|
+
### Tokens
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
# Get encoder for a model and encode
|
58
|
+
openai.tokens.for_model('gpt-4').encode('Hello world')
|
59
|
+
|
60
|
+
# Get encoder by name
|
61
|
+
openai.tokens.get('cl100k_base').encode('Hello world')
|
62
|
+
|
63
|
+
# Get number of tokens
|
64
|
+
openai.tokens.for_model('gpt-4').num_tokens('Hello, world!') # => 4
|
65
|
+
```
|
66
|
+
|
67
|
+
### Chat Abstraction
|
68
|
+
|
69
|
+
You can use `openai.chat` in order to create a simple chainable chat interface with a model:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
openai = OpenAI.create(ENV.fetch('OPENAI_API_KEY'))
|
73
|
+
|
74
|
+
chat = openai.chat(model: 'gpt-3.5-turbo')
|
75
|
+
|
76
|
+
chat =
|
77
|
+
chat
|
78
|
+
.system('You are a chatbot that talks and acts like scooby doo.')
|
79
|
+
.user('Hi how are you doing today?')
|
80
|
+
.submit # API call
|
81
|
+
.user('Nice. What kind of snacks do you like?')
|
82
|
+
.submit # API call
|
83
|
+
|
84
|
+
puts chat.to_log_format
|
85
|
+
```
|
86
|
+
|
87
|
+
Which results in this output:
|
88
|
+
|
89
|
+
> SYSTEM: You are a chatbot that talks and acts like scooby doo.
|
90
|
+
>
|
91
|
+
> USER: Hi how are you doing today?
|
92
|
+
>
|
93
|
+
> ASSISTANT: Ruh-roh! Hello there, buddy! Scooby-Dooby-Doo is doing great! How about you, pal?
|
94
|
+
>
|
95
|
+
> USER: Nice. What kind of snacks do you like?
|
96
|
+
>
|
97
|
+
> ASSISTANT: Ruh-roh! Scooby-Dooby-Doo loves all kinds of snacks, especially Scooby Snacks! They are my favorite! But I also love bones, pizza, hamburgers, and any kind of food that's tasty and yummy. How about you, buddy? Do you have a favorite snack?
|
98
|
+
|
99
|
+
## API
|
100
|
+
|
101
|
+
### Audio
|
102
|
+
|
103
|
+
Transcribing audio:
|
104
|
+
|
105
|
+
```ruby
|
106
|
+
transcription = openai.api.audio.transcribe(
|
107
|
+
file: '/path/to/sample.mp3',
|
108
|
+
model: 'model-id'
|
109
|
+
)
|
110
|
+
|
111
|
+
transcription.text # => "Imagine the wildest idea that you've ever had..."
|
112
|
+
```
|
113
|
+
|
114
|
+
Translating audio:
|
115
|
+
|
116
|
+
```ruby
|
117
|
+
translation = openai.api.audio.translate(
|
118
|
+
file: '/path/to/french/sample.mp3',
|
119
|
+
model: 'model-id',
|
120
|
+
)
|
121
|
+
|
122
|
+
translation.text # => "Hello, my name is Wolfgang and I come from Germany. Where are you heading today?"
|
123
|
+
```
|
124
|
+
|
125
|
+
### Chat completions
|
126
|
+
|
127
|
+
Generating a chat completion:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
completion = openai.api.chat_completions.create(
|
131
|
+
model: 'gpt-3.5-turbo',
|
132
|
+
messages: [
|
133
|
+
{ role: "user", content: "Hello" }
|
134
|
+
]
|
135
|
+
)
|
136
|
+
|
137
|
+
completion.choices.first.message.content # => "\n\nHello there, how may I assist you today?"
|
138
|
+
```
|
139
|
+
|
140
|
+
Streaming chat completion responses:
|
141
|
+
|
142
|
+
```ruby
|
143
|
+
completion = openai.api.chat_completions.create(
|
144
|
+
model: 'gpt-3.5-turbo',
|
145
|
+
messages: [{ role: "user", content: "Hello" }],
|
146
|
+
stream: true
|
147
|
+
) do |completion|
|
148
|
+
print completion.choices.first.delta.content
|
149
|
+
end
|
150
|
+
|
151
|
+
# >> "\n\nHello there, how may I assist you today?"
|
152
|
+
```
|
153
|
+
|
154
|
+
### Completions
|
155
|
+
|
156
|
+
Generating a completion:
|
157
|
+
|
158
|
+
```ruby
|
159
|
+
completion = openai.api.completions.create(
|
160
|
+
model: 'text-davinci-002',
|
161
|
+
prompt: 'Hello, world!'
|
162
|
+
)
|
163
|
+
|
164
|
+
completion.id # => "cmpl-uqkvlQyYK7bGYrRHQ0eXlWi7"
|
165
|
+
completion.model # => "text-davinci-003"
|
166
|
+
completion.choices.first.text # => "\n\nThis is indeed a test"
|
167
|
+
```
|
168
|
+
|
169
|
+
Streaming responses:
|
170
|
+
|
171
|
+
```ruby
|
172
|
+
completion = openai.api.completions.create(
|
173
|
+
model: 'text-davinci-002',
|
174
|
+
prompt: 'Say hello world',
|
175
|
+
stream: true
|
176
|
+
) do |completion|
|
177
|
+
puts completion.choices.first.text
|
178
|
+
end
|
179
|
+
|
180
|
+
# >> "He"
|
181
|
+
# >> "llo,"
|
182
|
+
# >> " world"
|
183
|
+
# >> "!"
|
184
|
+
```
|
185
|
+
|
186
|
+
### Edits
|
187
|
+
|
188
|
+
Creating an edit:
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
edit = openai.api.edits.create(
|
192
|
+
model: 'text-davinci-002',
|
193
|
+
input: "What day of the wek is it?",
|
194
|
+
instruction: "Fix the spelling mistake"
|
195
|
+
)
|
196
|
+
|
197
|
+
edit.object # => "edit"
|
198
|
+
edit.choices.first.text # => "What day of the week is it?"
|
199
|
+
```
|
200
|
+
|
201
|
+
### Embeddings
|
202
|
+
|
203
|
+
Creating an embedding vector for a given input text:
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
embedding = openai.api.embeddings.create(
|
207
|
+
model: 'text-embedding-ada-002',
|
208
|
+
input: 'Hello, world!'
|
209
|
+
)
|
210
|
+
|
211
|
+
embedding.object # => 'list'
|
212
|
+
embedding.data.first.object # => 'embedding'
|
213
|
+
embedding.data.first.embedding.size # => 1536
|
214
|
+
```
|
215
|
+
|
216
|
+
### Files
|
217
|
+
|
218
|
+
Upload a file:
|
219
|
+
|
220
|
+
```ruby
|
221
|
+
|
222
|
+
file = openai.api.files.create(
|
223
|
+
file: '/path/to/file.jsonl',
|
224
|
+
purpose: 'fine-tune'
|
225
|
+
)
|
226
|
+
|
227
|
+
file.id # => 'file-XjGxS3KTG0uNmNOK362iJua3'
|
228
|
+
file.filename # => 'sample.jsonl'
|
229
|
+
file.purpose # => 'fine-tune'
|
230
|
+
file.deleted? # => nil
|
231
|
+
```
|
232
|
+
|
233
|
+
Get a list of files:
|
234
|
+
|
235
|
+
```ruby
|
236
|
+
|
237
|
+
files = openai.api.files.list
|
238
|
+
|
239
|
+
files.data.size # => 2
|
240
|
+
files.data.first.filename # => 'train.jsonl'
|
241
|
+
```
|
242
|
+
|
243
|
+
Fetch a specific file’s information:
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
|
247
|
+
file = openai.api.files.fetch('file-XjGxS3KTG0uNmNOK362iJua3')
|
248
|
+
|
249
|
+
file.filename # => 'mydata.jsonl'
|
250
|
+
file.bytes # => 140
|
251
|
+
file.created_at # => 1613779657
|
252
|
+
file.purpose # => 'fine-tune'
|
253
|
+
file.object # => 'file'
|
254
|
+
```
|
255
|
+
|
256
|
+
Get the contents of a file:
|
257
|
+
|
258
|
+
```ruby
|
259
|
+
|
260
|
+
response = openai.api.files.get_content('file-XjGxS3KTG0uNmNOK362iJua3')
|
261
|
+
|
262
|
+
puts response # => (whatever you uploaded)
|
263
|
+
```
|
264
|
+
|
265
|
+
Delete a file:
|
266
|
+
|
267
|
+
```ruby
|
268
|
+
|
269
|
+
file = openai.api.files.delete('file-XjGxS3KTG0uNmNOK362iJua3')
|
270
|
+
|
271
|
+
file.deleted? # => true
|
272
|
+
```
|
273
|
+
|
274
|
+
### Fine-tunes
|
275
|
+
|
276
|
+
Creating a fine tune:
|
277
|
+
|
278
|
+
```ruby
|
279
|
+
fine_tune = openai.api.fine_tunes.create(training_file: 'file-XGinujblHPwGLSztz8cPS8XY')
|
280
|
+
|
281
|
+
details.id # => "ft-AF1WoRqd3aJAHsqc9NY7iL8F"
|
282
|
+
```
|
283
|
+
|
284
|
+
Listing fine tunes:
|
285
|
+
|
286
|
+
```ruby
|
287
|
+
fine_tunes = openai.api.fine_tunes.list
|
288
|
+
|
289
|
+
fine_tunes.data.first.id # => "ft-AF1WoRqd3aJAHsqc9NY7iL8F"
|
290
|
+
fine_tunes.data.first.status # => "pending"
|
291
|
+
```
|
292
|
+
|
293
|
+
|
294
|
+
Fetching a fine tune:
|
295
|
+
|
296
|
+
```ruby
|
297
|
+
fine_tune = openai.api.fine_tunes.fetch('ft-AF1WoRqd3aJAHsqc9NY7iL8F')
|
298
|
+
fine_tune.id # => "ft-AF1WoRqd3aJAHsqc9NY7iL8F"
|
299
|
+
```
|
300
|
+
|
301
|
+
Canceling a fine tune:
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
|
305
|
+
# Canceling a fine tune
|
306
|
+
fine_tune = openai.api.fine_tunes.cancel('ft-xhrpBbvVUzYGo8oUO1FY4nI7')
|
307
|
+
fine_tune.id # => "ft-xhrpBbvVUzYGo8oUO1FY4nI7"
|
308
|
+
fine_tune.status # => "cancelled"
|
309
|
+
```
|
310
|
+
|
311
|
+
Listing fine tune events:
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
events = openai.api.fine_tunes.list_events('fine-tune-id')
|
315
|
+
```
|
316
|
+
|
317
|
+
### Images
|
318
|
+
|
319
|
+
#### Generating Images
|
320
|
+
|
321
|
+
Create an image with the specified prompt and size:
|
322
|
+
|
323
|
+
```ruby
|
324
|
+
images = openai.api.images.create(prompt: 'a bird in the forest', size: '512x512')
|
325
|
+
|
326
|
+
images.data.first.url # => "https://example.com/image1.png"
|
327
|
+
```
|
328
|
+
|
329
|
+
#### Editing Images
|
330
|
+
|
331
|
+
Edit an image with the specified parameters:
|
332
|
+
|
333
|
+
```ruby
|
334
|
+
response = openai.api.images.edit(
|
335
|
+
image: '/path/to/some_rgba.png',
|
336
|
+
mask: '/path/to/some_rgba_mask.png',
|
337
|
+
prompt: 'Draw a red hat on the person in the image',
|
338
|
+
n: 1,
|
339
|
+
size: '512x512',
|
340
|
+
response_format: 'url',
|
341
|
+
user: 'user-123'
|
342
|
+
)
|
343
|
+
|
344
|
+
response.created # => 1589478378
|
345
|
+
response.data.first.url # => "https://..."
|
346
|
+
```
|
347
|
+
|
348
|
+
#### Creating Image Variations
|
349
|
+
|
350
|
+
Create image variations of the specified image with the specified parameters:
|
351
|
+
|
352
|
+
```ruby
|
353
|
+
image_variations = openai.api.images.create_variation(
|
354
|
+
image: '/path/to/some_rgba.png',
|
355
|
+
n: 2,
|
356
|
+
size: '512x512',
|
357
|
+
response_format: 'url',
|
358
|
+
user: 'user123'
|
359
|
+
)
|
360
|
+
|
361
|
+
image_variations.created # => 1589478378
|
362
|
+
image_variations.data.map(&:url) # => ["https://...", "https://..."]
|
363
|
+
```
|
364
|
+
|
365
|
+
### Models
|
366
|
+
|
367
|
+
Listing all models:
|
368
|
+
|
369
|
+
```ruby
|
370
|
+
models = api.models.list
|
371
|
+
|
372
|
+
models.data.first.id # => "model-id-0"
|
373
|
+
models.data.size # => 3
|
374
|
+
```
|
375
|
+
|
376
|
+
Retrieving a model:
|
377
|
+
|
378
|
+
```ruby
|
379
|
+
model = api.models.fetch('text-davinci-002')
|
380
|
+
|
381
|
+
model.id # => "text-davinci-002"
|
382
|
+
model.object # => "model"
|
383
|
+
model.owned_by # => "openai"
|
384
|
+
model.permission # => ["query", "completions", "models:read", "models:write", "engine:read", "engine:write"]
|
385
|
+
```
|
386
|
+
|
387
|
+
### Moderations
|
388
|
+
|
389
|
+
Moderate text:
|
390
|
+
|
391
|
+
```ruby
|
392
|
+
moderation = openai.api.moderations.create(
|
393
|
+
input: 'This is a test',
|
394
|
+
model: 'text-moderation-001'
|
395
|
+
)
|
396
|
+
|
397
|
+
moderation.id # => "modr-5MWoLO"
|
398
|
+
moderation.model # => "text-moderation-001"
|
399
|
+
moderation.results.first.categories.hate # => false
|
400
|
+
moderation.results.first.categories.hate_threatening # => true
|
401
|
+
```
|
data/bin/console
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
4
|
require 'bundler/setup'
|
4
5
|
require 'openai'
|
@@ -8,9 +9,13 @@ require 'pry-byebug'
|
|
8
9
|
|
9
10
|
Dotenv.load
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
cache_dir = Pathname.new(__dir__).parent.join('tmp/console_cache')
|
13
|
+
cache_dir.mkpath unless cache_dir.exist?
|
14
|
+
openai = OpenAI.create(
|
15
|
+
ENV.fetch('OPENAI_API_KEY'),
|
16
|
+
cache: cache_dir
|
17
|
+
)
|
18
|
+
|
19
|
+
Pry.start_without_pry_byebug(binding, quiet: true)
|
15
20
|
|
16
21
|
start_repl
|