ask_chatgpt 0.3.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +75 -0
- data/bin/ask_chatgpt +38 -4
- data/lib/ask_chatgpt/default_behavior.rb +2 -1
- data/lib/ask_chatgpt/executor.rb +9 -0
- data/lib/ask_chatgpt/prompts/with_code.rb +25 -0
- data/lib/ask_chatgpt/version.rb +1 -1
- data/lib/ask_chatgpt/voice.rb +176 -0
- data/lib/ask_chatgpt.rb +13 -0
- data/lib/generators/ask_chatgpt/templates/template.rb +5 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e8d16800c079df0252e84b7448b7633ed07b4bdf1580a06bb76ba4e27292764e
|
4
|
+
data.tar.gz: 9233fd8f8bbbcfd3cea1db3745be6633b710585d77eaf056ee6681c5b202d65c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9586b20bda0e6c3a485e1ac6e1eebf91a37ac8728a1e949c917a9ab972cdc1ee8a0b16aa8f76a700e5540ac15aa8f453d06315fdb1d418ba3de6b010504d9b07
|
7
|
+
data.tar.gz: 5516576d94f71d473545b77083990d005157138c97aba1e5992faf8215592b7c2025932b1d9ea74bfcea86b016370e8e00bd1502fb34934968f04f2395a97a84
|
data/README.md
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
|
6
6
|
AI-Powered Assistant Gem right in your Rails console.
|
7
7
|
|
8
|
+
NEW UPDATE: Voice input using your microphone, demo: https://youtu.be/uBR0wnQvKao
|
9
|
+
|
8
10
|
![AskChatGPT](docs/interactive.gif)
|
9
11
|
|
10
12
|
A Gem that leverages the power of AI to make your development experience more efficient and enjoyable. With this gem, you can streamline your coding process, effortlessly refactor and improve your code, and even generate tests on the fly.
|
@@ -18,6 +20,8 @@ Go to Rails console and run:
|
|
18
20
|
```ruby
|
19
21
|
gpt.ask("how to get max age of user with projects from Ukraine").with_model(User, Project, Country)
|
20
22
|
gpt.ask("convert json to xml")
|
23
|
+
gpt.with_code(User, Project).ask "make it better" # with_class alias for with_code
|
24
|
+
gpt.with_class(User).ask "make it better"
|
21
25
|
gpt.payload(json).ask("extract emails from json")
|
22
26
|
gpt.refactor("User.get_report")
|
23
27
|
gpt.improve("User.get_report")
|
@@ -31,6 +35,10 @@ Go to Rails console and run:
|
|
31
35
|
[first_name, last_name].join
|
32
36
|
end
|
33
37
|
}
|
38
|
+
#
|
39
|
+
# --- NEW ---
|
40
|
+
#
|
41
|
+
gpt.speak # or with alias gpt.s
|
34
42
|
```
|
35
43
|
|
36
44
|
OR with CLI tool:
|
@@ -46,6 +54,8 @@ aGVsbG8gd29ybGQ=
|
|
46
54
|
hello world
|
47
55
|
```
|
48
56
|
|
57
|
+
>ask_chatgpt -s 1 # start voice input with CLI
|
58
|
+
|
49
59
|
See some examples below. You can also create your own prompts with just few lines of code [here](#options--configurations).
|
50
60
|
|
51
61
|
Also you can use a CLI tool, [how to use it](#cli-tool).
|
@@ -113,6 +123,17 @@ And you can edit:
|
|
113
123
|
# config.max_tokens = 3000 # or nil by default
|
114
124
|
# config.included_prompts = []
|
115
125
|
|
126
|
+
# enable voice input with `gpt.speak` or `gpt.s`. Note, you also need to configure `audio_device_id`
|
127
|
+
# config.voice_enabled = true
|
128
|
+
|
129
|
+
# to get audio device ID (index in the input devices)
|
130
|
+
# install ffmpeg, and execute from the console
|
131
|
+
# `ffmpeg -f avfoundation -list_devices true -i ""`
|
132
|
+
# config.audio_device_id = 1
|
133
|
+
|
134
|
+
# after "voice_max_duration" seconds it will send audio to Open AI
|
135
|
+
# config.voice_max_duration = 10 # 10 seconds
|
136
|
+
|
116
137
|
# Examples of custom prompts:
|
117
138
|
# you can use them `gpt.extract_email("some string")`
|
118
139
|
|
@@ -182,8 +203,55 @@ end
|
|
182
203
|
|
183
204
|
or directly in console `gpt.debug!` (and finish `gpt.debug!(:off)`)
|
184
205
|
|
206
|
+
## Voice Input
|
207
|
+
|
208
|
+
Demo: https://youtu.be/uBR0wnQvKao
|
209
|
+
|
210
|
+
For now I consider this as an experimental and fun feature. Look forward seeing your feedback.
|
211
|
+
|
212
|
+
Works with command: `gpt.speak` or `gpt.s` (alias).
|
213
|
+
|
214
|
+
This command starts recording right away and it will stop after `voice_max_duration` seconds or if you press any key.
|
215
|
+
|
216
|
+
To exit recording mode press `Q`.
|
217
|
+
|
218
|
+
Voice is using `ffmpeg` tool, so you need to install it. Some instruction like this will work: https://www.hostinger.com/tutorials/how-to-install-ffmpeg.
|
219
|
+
|
220
|
+
Also, you need to configure `audio_device_id`. Run `ffmpeg -f avfoundation -list_devices true -i ""`
|
221
|
+
|
222
|
+
It will give you list of all devices, like this:
|
223
|
+
|
224
|
+
```s
|
225
|
+
ffmpeg -f avfoundation -list_devices true -i ""
|
226
|
+
ffmpeg version 6.0 Copyright (c) 2000-2023 the FFmpeg developers
|
227
|
+
built with Apple clang version 14.0.0 (clang-1400.0.29.202)
|
228
|
+
configuration: --prefix=/usr/local/Cellar/ffmpeg/6.0 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libaribb24 --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librist --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libsvtav1 --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-videotoolbox
|
229
|
+
libavutil 58. 2.100 / 58. 2.100
|
230
|
+
libavcodec 60. 3.100 / 60. 3.100
|
231
|
+
libavformat 60. 3.100 / 60. 3.100
|
232
|
+
libavdevice 60. 1.100 / 60. 1.100
|
233
|
+
libavfilter 9. 3.100 / 9. 3.100
|
234
|
+
libswscale 7. 1.100 / 7. 1.100
|
235
|
+
libswresample 4. 10.100 / 4. 10.100
|
236
|
+
libpostproc 57. 1.100 / 57. 1.100
|
237
|
+
[AVFoundation indev @ 0x7f7fd1a04380] AVFoundation video devices:
|
238
|
+
[AVFoundation indev @ 0x7f7fd1a04380] [0] FaceTime HD Camera
|
239
|
+
[AVFoundation indev @ 0x7f7fd1a04380] [1] USB Camera VID:1133 PID:2085
|
240
|
+
[AVFoundation indev @ 0x7f7fd1a04380] [2] Capture screen 0
|
241
|
+
[AVFoundation indev @ 0x7f7fd1a04380] [3] Capture screen 1
|
242
|
+
[AVFoundation indev @ 0x7f7fd1a04380] AVFoundation audio devices:
|
243
|
+
[AVFoundation indev @ 0x7f7fd1a04380] [0] Microsoft Teams Audio
|
244
|
+
[AVFoundation indev @ 0x7f7fd1a04380] [1] Built-in Microphone
|
245
|
+
[AVFoundation indev @ 0x7f7fd1a04380] [2] Unknown USB Audio Device
|
246
|
+
: Input/output error
|
247
|
+
```
|
248
|
+
|
249
|
+
In my case I used "1", because it's `Built-in Microphone`.
|
250
|
+
|
185
251
|
## CLI Tool
|
186
252
|
|
253
|
+
You can ask questions from cli or even start voice input.
|
254
|
+
|
187
255
|
Example 1:
|
188
256
|
![AskChatGPT](docs/unzip.gif)
|
189
257
|
|
@@ -197,6 +265,8 @@ How to use:
|
|
197
265
|
ask_chatgpt -f app/models/user.rb -q "find a bug in this Rails model"
|
198
266
|
ask_chatgpt -f app/models/user.rb -q "create RSpec spec for this model"
|
199
267
|
ask_chatgpt -f test/dummy/Gemfile -q "sort Ruby gems alphabetically"
|
268
|
+
ask_chatgpt -m 3.5 -q "How to parse JSON file in Ruby?"
|
269
|
+
ask_chatgpt -m 4 -q "Why Ruby is the best language?"
|
200
270
|
```
|
201
271
|
|
202
272
|
## Streaming (async vs sync mode)
|
@@ -232,6 +302,11 @@ end
|
|
232
302
|
- print tokens usage? `.with_usage`
|
233
303
|
- support org_id? in the configs
|
234
304
|
- use `gpt` in the code of the main app (e.g. model/controller)
|
305
|
+
- when voice is used add support for payloads, e.g. `gpt.with_payload(json).speak` (and it will send payload with my question)
|
306
|
+
- refactor voice input code :) as first version it's fine
|
307
|
+
- can we discover audio device ID?
|
308
|
+
- use tempfile for audio, instead of output.wav
|
309
|
+
- handle case when empty response is returned in CLI (when for example non-existing model is specified)
|
235
310
|
|
236
311
|
## Contributing
|
237
312
|
|
data/bin/ask_chatgpt
CHANGED
@@ -21,9 +21,13 @@ parser = OptionParser.new do |opts|
|
|
21
21
|
|
22
22
|
Examples:
|
23
23
|
ask_chatgpt -q "How to parse JSON file in Ruby?"
|
24
|
+
ask_chatgpt -m gpt-4 -q "How to parse JSON file in Ruby?"
|
24
25
|
ask_chatgpt -f app/models/user.rb -q "find a bug in this Rails model"
|
25
26
|
ask_chatgpt -f app/models/user.rb -q "create RSpec spec for this model"
|
26
27
|
ask_chatgpt -f test/dummy/Gemfile -q "sort Ruby gems alphabetically"
|
28
|
+
ask_chatgpt -s 1"
|
29
|
+
|
30
|
+
To specify model you can use shorter version: -m 4, -m 4.0, -m 3.5.
|
27
31
|
|
28
32
|
Version: #{AskChatGPT::VERSION}
|
29
33
|
|
@@ -33,10 +37,18 @@ parser = OptionParser.new do |opts|
|
|
33
37
|
options[:prompt] = prompt
|
34
38
|
end
|
35
39
|
|
40
|
+
opts.on("-s", "--speak AudioDeviceID", String, "Specify audio device ID") do |audio_device_id|
|
41
|
+
options[:audio_device_id] = audio_device_id
|
42
|
+
end
|
43
|
+
|
36
44
|
opts.on("-f", "--file FILE", String, "Specify file with prompt") do |file|
|
37
45
|
options[:file_path] = file
|
38
46
|
end
|
39
47
|
|
48
|
+
opts.on("-m", "--model MODEL", String, "Specify the ChatGPT model. Uses \"gpt-3.5-turbo\" by default") do |model|
|
49
|
+
options[:model] = model
|
50
|
+
end
|
51
|
+
|
40
52
|
opts.on("-d", "--debug", "Output request/response") do |debug|
|
41
53
|
options[:debug] = true
|
42
54
|
end
|
@@ -51,16 +63,38 @@ parser.parse!
|
|
51
63
|
|
52
64
|
AskChatGPT.debug = !!options[:debug]
|
53
65
|
|
66
|
+
if options[:model].present?
|
67
|
+
model = options[:model].to_s
|
68
|
+
disctionary = {
|
69
|
+
"4" => "gpt-4",
|
70
|
+
"4.0" => "gpt-4",
|
71
|
+
"40" => "gpt-4",
|
72
|
+
"3.5t" => "gpt-3.5-turbo",
|
73
|
+
"3.5" => "gpt-3.5-turbo",
|
74
|
+
"35" => "gpt-3.5-turbo",
|
75
|
+
}
|
76
|
+
model = disctionary[model.downcase] || model
|
77
|
+
AskChatGPT.model = model
|
78
|
+
end
|
79
|
+
|
54
80
|
options[:prompt] = ARGV.join(" ") if options[:prompt].blank?
|
55
81
|
|
56
|
-
if options[:prompt].blank?
|
82
|
+
if options[:prompt].blank? && options[:audio_device_id].blank?
|
57
83
|
puts parser
|
58
84
|
exit
|
59
85
|
end
|
60
86
|
|
61
87
|
include AskChatGPT::Console
|
62
88
|
|
63
|
-
|
64
|
-
|
89
|
+
if options[:audio_device_id].present?
|
90
|
+
AskChatGPT.voice_enabled = true
|
91
|
+
AskChatGPT.voice_max_duration = 20
|
92
|
+
AskChatGPT.audio_device_id = options[:audio_device_id]
|
65
93
|
|
66
|
-
|
94
|
+
instance = gpt.speak
|
95
|
+
else
|
96
|
+
instance = gpt.ask(options[:prompt])
|
97
|
+
instance = instance.payload(File.read(options[:file_path])) if options[:file_path].present?
|
98
|
+
|
99
|
+
puts instance.inspect
|
100
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module AskChatgpt
|
2
2
|
module DefaultBehavior
|
3
|
-
DEFAULT_PROMPTS = [:improve, :refactor, :question, :find_bug, :code_review, :rspec_test, :unit_test, :explain]
|
3
|
+
DEFAULT_PROMPTS = [:improve, :refactor, :question, :with_code, :find_bug, :code_review, :rspec_test, :unit_test, :explain]
|
4
4
|
|
5
5
|
def with_model(*models)
|
6
6
|
self.tap do
|
@@ -22,6 +22,7 @@ module AskChatgpt
|
|
22
22
|
alias :how :question
|
23
23
|
alias :find :question
|
24
24
|
alias :review :code_review
|
25
|
+
alias :with_class :with_code
|
25
26
|
|
26
27
|
def add_prompt(prompt)
|
27
28
|
scope << prompt
|
data/lib/ask_chatgpt/executor.rb
CHANGED
@@ -2,6 +2,7 @@ require_relative "sugar"
|
|
2
2
|
require_relative "prompts/base"
|
3
3
|
require_relative "prompts/improve"
|
4
4
|
require_relative "default_behavior"
|
5
|
+
require_relative "voice"
|
5
6
|
|
6
7
|
Dir[File.join(__dir__, "prompts", "*.rb")].each do |file|
|
7
8
|
require file
|
@@ -23,6 +24,14 @@ module AskChatgpt
|
|
23
24
|
AskChatgpt::Executor.new(client)
|
24
25
|
end
|
25
26
|
|
27
|
+
def speak
|
28
|
+
puts "Voice input is not enabled (docs: https://github.com/railsjazz/ask_chatgpt)" unless AskChatGPT.voice_enabled
|
29
|
+
puts "Audio device ID is not configured (docs: https://github.com/railsjazz/ask_chatgpt)" unless AskChatGPT.audio_device_id
|
30
|
+
|
31
|
+
AskChatgpt::VoiceFlow::Voice.new.run
|
32
|
+
end
|
33
|
+
alias_method :s, :speak
|
34
|
+
|
26
35
|
def initialize(client)
|
27
36
|
@scope = AskChatGPT.included_prompts.dup
|
28
37
|
@client = client
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module AskChatgpt
|
2
|
+
module Prompts
|
3
|
+
class WithCode < Base
|
4
|
+
|
5
|
+
attr_reader :args
|
6
|
+
|
7
|
+
def initialize(*args)
|
8
|
+
@args = args
|
9
|
+
end
|
10
|
+
|
11
|
+
def content
|
12
|
+
code_info.reject { |v| v.blank? }.join("\n")
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def code_info
|
18
|
+
args.compact.map do |arg|
|
19
|
+
AskChatGPT::Helpers.extract_source(arg)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/ask_chatgpt/version.rb
CHANGED
@@ -0,0 +1,176 @@
|
|
1
|
+
module StringExt
|
2
|
+
refine String do
|
3
|
+
def black; "\e[30m#{self}\e[0m" end
|
4
|
+
def red; "\e[31m#{self}\e[0m" end
|
5
|
+
def green; "\e[32m#{self}\e[0m" end
|
6
|
+
def brown; "\e[33m#{self}\e[0m" end
|
7
|
+
def blue; "\e[34m#{self}\e[0m" end
|
8
|
+
def magenta; "\e[35m#{self}\e[0m" end
|
9
|
+
def cyan; "\e[36m#{self}\e[0m" end
|
10
|
+
def gray; "\e[37m#{self}\e[0m" end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
using StringExt
|
15
|
+
|
16
|
+
module AskChatgpt
|
17
|
+
module VoiceFlow
|
18
|
+
require 'io/console'
|
19
|
+
require 'fileutils'
|
20
|
+
require 'timeout'
|
21
|
+
require 'open3'
|
22
|
+
|
23
|
+
class AudioRecorder
|
24
|
+
OUTPUT_FILE = "output.wav"
|
25
|
+
|
26
|
+
def initialize(duration)
|
27
|
+
@duration = duration
|
28
|
+
end
|
29
|
+
|
30
|
+
# ffmpeg -f avfoundation -list_devices true -i ""
|
31
|
+
def audio_device_id
|
32
|
+
AskChatGPT.audio_device_id
|
33
|
+
end
|
34
|
+
|
35
|
+
def start
|
36
|
+
delete_audio_file
|
37
|
+
ffmpeg_command = build_ffmpeg_command
|
38
|
+
@stdin, @stdout_and_stderr, @wait_thread = Open3.popen2e(ffmpeg_command)
|
39
|
+
end
|
40
|
+
|
41
|
+
def stop
|
42
|
+
@stdin.puts 'q'
|
43
|
+
@stdin.close
|
44
|
+
@stdout_and_stderr.close
|
45
|
+
sleep(0.2)
|
46
|
+
rescue Errno::EPIPE, IOError
|
47
|
+
end
|
48
|
+
|
49
|
+
def delete_audio_file
|
50
|
+
FileUtils.rm(OUTPUT_FILE) if File.exist?(OUTPUT_FILE)
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def build_ffmpeg_command
|
56
|
+
case RUBY_PLATFORM
|
57
|
+
when /darwin/
|
58
|
+
input_device = "-f avfoundation -i \":#{audio_device_id}\""
|
59
|
+
when /linux/
|
60
|
+
input_device = '-f alsa -i default'
|
61
|
+
when /mingw|mswin/
|
62
|
+
input_device = '-f dshow -i audio="Microphone (Realtek High Definition Audio)"'
|
63
|
+
else
|
64
|
+
raise "Unsupported platform: #{RUBY_PLATFORM}"
|
65
|
+
end
|
66
|
+
|
67
|
+
"ffmpeg -loglevel quiet #{input_device} -t #{@duration} #{OUTPUT_FILE}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Voice
|
72
|
+
def initialize
|
73
|
+
@messages = []
|
74
|
+
@wanna_quit = false
|
75
|
+
@duration = (AskChatGPT.voice_max_duration.presence || 10).to_i
|
76
|
+
@ffmpeg_wait_duration = 0.5
|
77
|
+
@executing = true
|
78
|
+
@spinner = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def run
|
82
|
+
while @executing
|
83
|
+
# Start the parallel process
|
84
|
+
audio_recorder = AudioRecorder.new(@duration)
|
85
|
+
audio_recorder.start
|
86
|
+
|
87
|
+
begin
|
88
|
+
Timeout.timeout(@duration + @ffmpeg_wait_duration) do
|
89
|
+
@spinner = TTY::Spinner.new("[Recording]".red + " / Press any key to stop recording or \"Esc\" / \"q\" to quit ... ".blue + ":spinner".red, format: :spin)
|
90
|
+
@spinner.auto_spin
|
91
|
+
sleep(@ffmpeg_wait_duration) # five some time for ffmpeg to start
|
92
|
+
# Listen for user input in the main process
|
93
|
+
begin
|
94
|
+
char = $stdin.getch
|
95
|
+
if char.ord == 27 || char.upcase == "Q"
|
96
|
+
audio_recorder.stop
|
97
|
+
@executing = false
|
98
|
+
@spinner.stop
|
99
|
+
puts "Bye...".brown
|
100
|
+
end
|
101
|
+
break
|
102
|
+
end while char.nil?
|
103
|
+
end
|
104
|
+
rescue Timeout::Error
|
105
|
+
ensure
|
106
|
+
audio_recorder.stop
|
107
|
+
@spinner.stop
|
108
|
+
break unless @executing
|
109
|
+
end
|
110
|
+
|
111
|
+
if !File.exist?("output.wav")
|
112
|
+
puts "No audio file found, please try again.".brown
|
113
|
+
sleep(0.5)
|
114
|
+
next
|
115
|
+
end
|
116
|
+
|
117
|
+
@spinner = TTY::Spinner.new("Thinking :spinner".cyan, format: :dots)
|
118
|
+
@spinner.auto_spin
|
119
|
+
response = client.transcribe(parameters: { model: "whisper-1", file: File.open("output.wav", "rb") })
|
120
|
+
@spinner.stop
|
121
|
+
|
122
|
+
if response["error"]
|
123
|
+
puts response["error"].inspect.brown
|
124
|
+
@executing = false
|
125
|
+
break
|
126
|
+
end
|
127
|
+
|
128
|
+
user_input = response["text"].to_s
|
129
|
+
puts "USER> ".green + user_input
|
130
|
+
@messages << { role: "user", content:user_input }
|
131
|
+
print "ASSISTANT> ".magenta
|
132
|
+
|
133
|
+
stop_stream = false
|
134
|
+
reply = []
|
135
|
+
|
136
|
+
keypresser = Thread.new do
|
137
|
+
loop { stop_stream = true if $stdin.getch }
|
138
|
+
end
|
139
|
+
|
140
|
+
begin
|
141
|
+
client.chat(
|
142
|
+
parameters: {
|
143
|
+
model: "gpt-3.5-turbo",
|
144
|
+
messages: @messages,
|
145
|
+
temperature: 0.7,
|
146
|
+
stream: proc do |chunk, _bytesize|
|
147
|
+
break if stop_stream
|
148
|
+
message = chunk.dig("choices", 0, "delta", "content")
|
149
|
+
next if message.to_s.empty?
|
150
|
+
|
151
|
+
message = message.gsub("\n", "\r\n")
|
152
|
+
|
153
|
+
print message
|
154
|
+
reply += [message]
|
155
|
+
end
|
156
|
+
})
|
157
|
+
rescue LocalJumpError
|
158
|
+
puts
|
159
|
+
ensure
|
160
|
+
Thread.kill(keypresser)
|
161
|
+
stop_stream = false
|
162
|
+
@messages << { role: "assistant", content: reply.join }
|
163
|
+
puts
|
164
|
+
end
|
165
|
+
|
166
|
+
audio_recorder.delete_audio_file
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def client
|
171
|
+
@client ||= OpenAI::Client.new(access_token: AskChatGPT.access_token)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
data/lib/ask_chatgpt.rb
CHANGED
@@ -49,6 +49,19 @@ module AskChatgpt
|
|
49
49
|
mattr_accessor :included_prompts
|
50
50
|
@@included_prompts = [AskChatGPT::Prompts::App.new]
|
51
51
|
|
52
|
+
# enable voice input, requires ffmpeg to be installed and also you need to configure audio_device_id
|
53
|
+
mattr_accessor :voice_enabled
|
54
|
+
@voice_enabled = false
|
55
|
+
|
56
|
+
# to get audio device ID (index in the input devices)
|
57
|
+
# ffmpeg -f avfoundation -list_devices true -i ""
|
58
|
+
mattr_accessor :audio_device_id
|
59
|
+
@@audio_device_id = nil
|
60
|
+
|
61
|
+
# max duration of audio to record
|
62
|
+
mattr_accessor :voice_max_duration
|
63
|
+
@@voice_max_duration = 10 # 10 seconds
|
64
|
+
|
52
65
|
def self.setup
|
53
66
|
yield(self)
|
54
67
|
end
|
@@ -10,6 +10,11 @@ AskChatGPT.setup do |config|
|
|
10
10
|
# config.temperature = 0.1
|
11
11
|
# config.included_prompts = []
|
12
12
|
|
13
|
+
# enable voice input, requires ffmpeg to be installed and also you need to configure audio_device_id
|
14
|
+
# config.voice_enabled = true
|
15
|
+
# config.audio_device_id = 1
|
16
|
+
# config.voice_max_duration = 10 # 10 seconds
|
17
|
+
|
13
18
|
# Examples of custom prompts:
|
14
19
|
# you can use them `gpt.ask(:extract_email, "some string")`
|
15
20
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ask_chatgpt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Igor Kasyanchuk
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-05-
|
12
|
+
date: 2023-05-13 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -95,6 +95,20 @@ dependencies:
|
|
95
95
|
- - ">="
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: 1.4.3
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: io-console
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
type: :runtime
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
98
112
|
- !ruby/object:Gem::Dependency
|
99
113
|
name: wrapped_print
|
100
114
|
requirement: !ruby/object:Gem::Requirement
|
@@ -153,9 +167,11 @@ files:
|
|
153
167
|
- lib/ask_chatgpt/prompts/refactor.rb
|
154
168
|
- lib/ask_chatgpt/prompts/rspec_test.rb
|
155
169
|
- lib/ask_chatgpt/prompts/unit_test.rb
|
170
|
+
- lib/ask_chatgpt/prompts/with_code.rb
|
156
171
|
- lib/ask_chatgpt/railtie.rb
|
157
172
|
- lib/ask_chatgpt/sugar.rb
|
158
173
|
- lib/ask_chatgpt/version.rb
|
174
|
+
- lib/ask_chatgpt/voice.rb
|
159
175
|
- lib/generators/ask_chatgpt/USAGE
|
160
176
|
- lib/generators/ask_chatgpt/ask_chatgpt_generator.rb
|
161
177
|
- lib/generators/ask_chatgpt/templates/template.rb
|