ask-ai 0.0.1 → 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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f66251ade1f9986ae077dc13cb177f5f651b5c3638115fb7b5a5ef54d9510972
4
- data.tar.gz: ec6673e17d5cdd7e6e202ad33d87f30b4e132afdbde347c67917aee6a7483291
3
+ metadata.gz: 6e70b8ddfd0f1ba54b83d117957361a9def1f96d33ed08e943db73c827bfdccc
4
+ data.tar.gz: 9e2b01982e324a6891e6dd32b4feee37f98087d0c455650458443503bf1fb8bd
5
5
  SHA512:
6
- metadata.gz: c4c71fbb474ebbea5684fc849007f04af964c105ae9a8827790da443a4c45168b59ba5c49b90644bdd8d3f46ca03d5ad31535bf244eace5b00d017f43aae36e1
7
- data.tar.gz: 69dea278d20a873ba3a91f93dd41e97d148e754cf654ac32c6ca3ad168bc57a66bd3816db23aa38362bf81a18be3453d08e2201d1ec134ed1230b5a792f70000
6
+ metadata.gz: 19abf77a6f7af9561c2d0b91c36558b68b60f8354e88e472b588ad6bc0f3b47278efd4b57dcd96593173302adf46129e8426a48785e1663ae30064c780ef2b23
7
+ data.tar.gz: 0be06de99164dace9991bc4097092607a71047b2606fccfd560ddc8a69ec5563ac6fd3dcfc2d6cbedb2b9bfe37bce41aa431fa56149eda8fc269a1e61f6c0ecd
data/config/config.yml CHANGED
@@ -1 +0,0 @@
1
-
data/lib/context.rb CHANGED
@@ -1,7 +1,10 @@
1
+ require_relative './files.rb'
2
+
1
3
  class Context
4
+ include Files
2
5
  def self.load_context()
3
- if File.exist?(CONTEXT_PATH)
4
- conversation = File.readlines(CONTEXT_PATH).map { |line| JSON.parse(line) }
6
+ if File.exist?(Files.context_path)
7
+ conversation = File.readlines(Files.context_path).map { |line| JSON.parse(line) }
5
8
  else
6
9
  conversation = []
7
10
  end
@@ -25,27 +28,27 @@ class Context
25
28
  ## Max 10 previous Q / A to save tokens.
26
29
  def self.save_context(context)
27
30
  tmp_arr = []
28
- unless File.exist?(CONTEXT_PATH)
29
- File.open(CONTEXT_PATH, "w") {}
31
+ unless File.exist?(Files.context_path)
32
+ File.open(Files.context_path, "w") {}
30
33
  end
31
- File.readlines(CONTEXT_PATH).map { |line| tmp_arr.push(JSON.parse(line)) }
34
+ File.readlines(Files.context_path).map { |line| tmp_arr.push(JSON.parse(line)) }
32
35
  if tmp_arr.length > 9
33
36
  tmp_arr.shift()
34
37
  end
35
- File.truncate(CONTEXT_PATH, 0)
36
- tmp_arr.each { |line| File.open(CONTEXT_PATH, "a") { |file| file.write("#{line.to_json}\n") } }
37
- File.open(CONTEXT_PATH, "a") { |file| file.write("#{context.to_json}\n") }
38
+ File.truncate(Files.context_path, 0)
39
+ tmp_arr.each { |line| File.open(Files.context_path, "a") { |file| file.write("#{line.to_json}\n") } }
40
+ File.open(Files.context_path, "a") { |file| file.write("#{context.to_json}\n") }
38
41
  end
39
42
 
40
43
  def self.delete_context()
41
- puts "Deleting previous context."
42
- File.truncate(CONTEXT_PATH, 0)
44
+ Logging.log("Deleting previous context.")
45
+ File.truncate(Files.context_path, 0)
43
46
  end
44
47
 
45
48
  def self.save_context_file(file_path)
46
49
  unless file_path.nil?
47
50
  file_in = File.open(file_path, 'r')
48
- file_out = File.open(CONTEXT_FILE_PATH, 'w')
51
+ file_out = File.open(Files.context_file_path, 'w')
49
52
  char_count = 0
50
53
  file_in.each do |line|
51
54
  char_count += line.length
@@ -53,17 +56,17 @@ class Context
53
56
  end
54
57
 
55
58
  if char_count > 10000
56
- puts "Warning: The file you are trying to feed to the API is #{char_count} characters long. This consumes a lot of tokens."
59
+ Logging.log("Warning: The file you are trying to feed to the API is #{char_count} characters long. This consumes a lot of tokens.")
57
60
  end
58
61
  else
59
- puts "No file path given."
62
+ Logging.log("No file path given.")
60
63
  end
61
64
  rescue Errno::ENOENT
62
- puts "No file at '#{file_path}' found."
65
+ Logging.log("No file at '#{file_path}' found.")
63
66
  end
64
67
 
65
68
  def self.load_context_file()
66
- file = File.open(CONTEXT_FILE_PATH, 'r')
69
+ file = File.open(Files.context_file_path, 'r')
67
70
  file_as_string = ""
68
71
  file.each do |line|
69
72
  file_as_string += line
@@ -71,8 +74,8 @@ class Context
71
74
 
72
75
  return file_as_string
73
76
  rescue Errno::ENOENT
74
- puts "No file at '#{CONTEXT_FILE_PATH}' found."
75
- puts "Load a file with 'aa -lf <file_path>'"
77
+ Logging.log("No file at '#{Files.context_file_path}' found.")
78
+ Logging.log("Load a file with 'aa -lf <file_path>'")
76
79
  return ""
77
80
  end
78
81
 
data/lib/files.rb ADDED
@@ -0,0 +1,21 @@
1
+ module Files
2
+ def self.root
3
+ File.expand_path("./../", __dir__)
4
+ end
5
+
6
+ def self.file_path
7
+ File.expand_path("./../files/", __dir__)
8
+ end
9
+
10
+ def self.context_path
11
+ File.expand_path("./../files/context.jsonl", __dir__)
12
+ end
13
+
14
+ def self.config_path
15
+ File.expand_path("./../config/config.yml", __dir__)
16
+ end
17
+
18
+ def self.context_file_path
19
+ File.expand_path("./../files/context_file.txt", __dir__)
20
+ end
21
+ end
data/lib/handle_args.rb CHANGED
@@ -1,4 +1,4 @@
1
- class HandleArgs
1
+ class HandleArgs
2
2
  def self.permitted_options()
3
3
  ## TODO: Add more options.
4
4
  ## -t --translate
@@ -32,18 +32,18 @@ end
32
32
 
33
33
  ## This handles args then called as ruby script.
34
34
  ARGV.each_with_index do |arg, i|
35
- #puts "Arg: #{arg}"
35
+ #Logging.log("Arg: #{arg}")
36
36
 
37
37
  if arg.start_with?('-')
38
38
  ## This is an option.
39
39
  if p_args.include?(arg)
40
40
  ## This is a permitted / available option.
41
- #puts "Option: #{arg}"
41
+ #Logging.log("Option: #{arg}")
42
42
  args_hash["option_#{i}"] = arg
43
43
  else
44
44
  ## This is an unknown option.
45
45
  ## TODO: Handle unknown option. display help? discard?
46
- puts "Unknown option: #{arg}"
46
+ Logging.log("Unknown option: #{arg}")
47
47
  args_hash["option_#{i}"] = arg
48
48
  end
49
49
  else
data/lib/help.rb CHANGED
@@ -2,27 +2,27 @@ require 'rubygems'
2
2
 
3
3
  class Help
4
4
  def self.display_help()
5
- puts "Usage: aa [options] [input]"
6
- puts " -lf, --loadfile <path>: Load file into context"
7
- puts " -f, --file: Read from context file"
8
- puts " -c, --conversation: Append to conversation (max 10 Questions / Answers pairs saved)"
9
- puts " -d, --delete: Delete conversation"
10
- puts " -i, --interactive: Interactive mode, always a conversation. Clear context with 'clear' (exit with 'exit' or 'quit')"
11
- puts " -w, --whisper <path>: Transcribe audio file"
12
- puts " -t, --translate <path>: Translate audio file"
13
- puts "\n Options:"
14
- puts " --config: Edit config file"
15
- puts " -v, --version: Display version"
16
- puts " -h, --help: Display this help message"
5
+ Logging.log("Usage: aa [options] [input]")
6
+ Logging.log(" -lf, --loadfile <path>: Load file into context")
7
+ Logging.log(" -f, --file: Read from context file")
8
+ Logging.log(" -c, --conversation: Append to conversation (max 10 Questions / Answers pairs saved)")
9
+ Logging.log(" -d, --delete: Delete conversation")
10
+ Logging.log(" -i, --interactive: Interactive mode, always a conversation. Clear context with 'clear' (exit with 'exit' or 'quit')")
11
+ Logging.log(" -w, --whisper <path>: Transcribe audio file")
12
+ Logging.log(" -t, --translate <path>: Translate audio file")
13
+ Logging.log("\n Options:")
14
+ Logging.log(" --config: Edit config file")
15
+ Logging.log(" -v, --version: Display version")
16
+ Logging.log(" -h, --help: Display this help message")
17
17
 
18
18
  end
19
19
 
20
20
  def self.display_api_key()
21
- puts "You need to set your API key in the file: ./config/config.yml"
22
- puts "Create the file if it doesn't exist."
23
- puts "Add the following line to the file:"
24
- puts " OPENAI_API_KEY: <your API key>"
25
- puts "You can get your API key from: https://openai.com/"
21
+ Logging.log("You need to set your API key in the file: ./config/config.yml")
22
+ Logging.log("Create the file if it doesn't exist.")
23
+ Logging.log("Add the following line to the file:")
24
+ Logging.log(" OPENAI_API_KEY: <your API key>")
25
+ Logging.log("You can get your API key from: https://openai.com/")
26
26
  end
27
27
 
28
28
  ## This don't work yet. Need to rework the way we handle args.
@@ -36,13 +36,13 @@ class Help
36
36
  end
37
37
 
38
38
  def self.display_version()
39
- spec = Gem::Specification::load("aa.gemspec")
40
- puts "Version: #{spec.version}"
39
+ spec = Gem::Specification::load("ask-ai.gemspec")
40
+ Logging.log("Version: #{spec.version}")
41
41
  end
42
42
 
43
43
  def self.display_usage()
44
- puts "Usage: ./main.rb [options] [input]"
44
+ Logging.log("Usage: ./main.rb [options] [input]")
45
45
 
46
- puts "There are two types of options, flags and arguments."
46
+ Logging.log("There are two types of options, flags and arguments.")
47
47
  end
48
48
  end
data/lib/logging.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'logger'
2
+
3
+ module Logging
4
+ def self.log(msg)
5
+ logger = Logger.new(STDOUT)
6
+ logger.formatter = proc { |_severity, _datetime, _progname, msg| "#{msg}\n" }
7
+ logger.info(msg)
8
+ end
9
+ end
data/lib/main.rb CHANGED
@@ -4,39 +4,33 @@ require 'fileutils'
4
4
  require 'yaml'
5
5
  require 'readline'
6
6
  require 'io/console'
7
- [
8
- './prompt.rb',
9
- './handle_args.rb',
10
- './help.rb',
11
- './context.rb'
12
- ].each { |f| require_relative f }
7
+ require './lib/logging.rb'
8
+ require_relative './prompt.rb'
9
+ require_relative './handle_args.rb'
10
+ require_relative './help.rb'
11
+ require_relative './context.rb'
12
+ require_relative './files.rb'
13
13
 
14
- CONTEXT_PATH = File.expand_path("./../files/context.jsonl", __dir__)
15
- FILE_PATH = File.expand_path("./../files/", __dir__)
16
- CONFIG_PATH = File.expand_path("./../config/config.yml", __dir__)
17
- CONTEXT_FILE_PATH = File.expand_path("./../files/context_file.txt", __dir__)
18
14
  class Main
19
-
15
+ include Logging
16
+ include Files
20
17
  def self.run()
21
18
  config = load_env()
22
-
19
+
23
20
  ## This does not work. Need to fix this.
24
- if config.nil? || config['OPENAI_API_KEY'].nil?
25
- puts "No API key found."
21
+ if config == false
22
+ Logging.log("No API key found.")
26
23
  Help.display_api_key()
27
- puts 'If you want to set your API key now, type (y)es and press enter.'
28
- #puts "If you have an API key you can set it here."
29
- #puts "Enter API key: (or press enter to exit)"
30
-
24
+ Logging.log('If you want to set your API key now, type (y)es and press enter.')
31
25
  while input = Readline.readline("> ", true) do
32
26
  if input.empty?
33
- puts "Exiting."
27
+ Logging.log("Exiting.")
34
28
  exit
35
29
  elsif input == "y" || input == "yes" || input == "Y" || input == "Yes"
36
30
  set_key()
37
31
  exit
38
32
  else
39
- puts 'Invalid input (y)es or press enter to exit.'
33
+ Logging.log('Invalid input (y)es or press enter to exit.')
40
34
  end
41
35
  end
42
36
  end
@@ -80,7 +74,7 @@ class Main
80
74
  end
81
75
  Prompt.stream_prompt(input, file_as_string)
82
76
  when "-lf", "--loadfile"
83
- puts "Loading File #{input}"
77
+ Logging.log("Loading File #{input}")
84
78
  Context.save_context_file(input)
85
79
  when "-d", "--delete"
86
80
  if input.nil?
@@ -90,39 +84,57 @@ class Main
90
84
  Context.save_context(Prompt.stream_prompt(input, context))
91
85
  end
92
86
  when "-c", "--conversation"
93
- puts input
87
+ Logging.log(input)
94
88
  Context.save_context(Prompt.stream_prompt(input, context))
95
89
  when "-w", "--whisper"
96
- puts Prompt.whisper_transcribe(input)
90
+ Logging.log(Prompt.whisper_transcribe(input))
97
91
  when "-t", "--translate"
98
- puts Prompt.whisper_translate(input)
92
+ Logging.log(Prompt.whisper_translate(input))
99
93
  when "-i", "--interactive"
100
- puts "Interactive mode..."
101
- puts "Type 'exit' or 'quit' to exit."
102
- puts "Type 'clear' to clear context."
94
+ Logging.log("Interactive mode...")
95
+ Logging.log("Type 'exit' or 'quit' to exit.")
96
+ Logging.log("Type 'clear' to clear context.")
97
+ Logging.log("Type 'show' to show context.")
98
+ Logging.log("Type 'help' to show help.")
99
+ Logging.log("Type 'config' to change config.")
100
+ Logging.log("Type '-w' to whisper transcribe.")
101
+ Logging.log("Type '-t' to whisper translate.")
103
102
 
104
103
  while input = Readline.readline("\n> ", true) do
105
- if (input == "exit" || input == "quit")
106
- break
104
+ case input
105
+ when "exit", "quit"
106
+ break
107
+ when "clear"
108
+ Logging.log("Clearing context...")
109
+ Context.delete_context()
110
+ when "help"
111
+ #TODO: This should be a specific help for interactive.
112
+ Help.display_help()
113
+ when "show"
114
+ Logging.log("\n")
115
+ Logging.log(Context.load_context())
116
+ when /^-w/
117
+ stript_input = input.sub(/^-w/, "").strip
118
+ Logging.log(Prompt.whisper_transcribe(stript_input, interactive: true))
119
+ when /^-t/
120
+ stript_input = input.sub(/^-t/, "").strip
121
+ Logging.log(Prompt.whisper_translate(stript_input, interactive: true))
122
+ when "config"
123
+ set_key(api_key: nil)
124
+ else
125
+ #options_and_input = HandleArgs.handle_args()
126
+ context = Context.load_context()
127
+ Logging.log("")
128
+ Context.save_context(Prompt.stream_prompt(input, context))
129
+ Logging.log("")
107
130
  end
108
- if input == "clear"
109
- puts "Clearing context..."
110
- Context.delete_context()
111
- next
112
- end
113
- options_and_input = HandleArgs.handle_args()
114
- context = Context.load_context()
115
- puts "\n"
116
- Context.save_context(Prompt.stream_prompt(input, context))
117
- puts "\n"
118
131
  end
119
- puts "Exiting..."
120
- #Context.delete_context()
132
+ Logging.log("Exiting...")
121
133
  when "simple"
122
134
  if !input.nil?
123
135
  Prompt.stream_prompt(input)
124
136
  else
125
- puts "No input given."
137
+ Logging.log("No input given.")
126
138
  Help.display_help()
127
139
  end
128
140
  else
@@ -136,33 +148,33 @@ class Main
136
148
 
137
149
  def self.set_key(api_key: nil)
138
150
  if api_key.nil?
139
- puts "Setting API key..."
140
- puts "Enter API key: (or press enter to exit)"
151
+ Logging.log("Setting API key...")
152
+ Logging.log("Enter API key: (or press enter to exit)")
141
153
 
142
154
  while input = Readline.readline("> ", true) do
143
155
  if input.empty?
144
- puts "Exiting."
156
+ Logging.log("Exiting.")
145
157
  exit
146
158
  else
147
159
  api_key = input.strip
148
160
  break
149
161
  end
150
162
  end
151
- puts "Saving API key..."
163
+ Logging.log("Saving API key...")
152
164
  end
153
165
 
154
- FileUtils.mkdir_p(File.dirname(CONFIG_PATH))
155
- File.open(CONFIG_PATH, "w") do |f|
166
+ FileUtils.mkdir_p(File.dirname(Files.config_path))
167
+ File.open(Files.config_path, "w") do |f|
156
168
  f.write(YAML.dump({ "OPENAI_API_KEY" => api_key }))
157
169
  end
158
- puts "API key saved."
170
+ Logging.log("API key saved.")
159
171
  end
160
172
 
161
173
  def self.load_env()
162
- YAML.load(File.read(CONFIG_PATH))
174
+ YAML.load(File.read(Files.config_path))
163
175
 
164
176
  rescue Errno::ENOENT
165
- puts "No config.yml found."
177
+ Logging.log("No config.yml found.")
166
178
  end
167
179
  end
168
180
 
data/lib/paths.rb ADDED
@@ -0,0 +1,26 @@
1
+
2
+ module Files
3
+ def self.root
4
+ File.expand_path("./../", __dir__)
5
+ end
6
+
7
+ def self.context
8
+ File.expand_path("./../files/context.jsonl", __dir__)
9
+ end
10
+
11
+ def self.files
12
+ FILE_PATH
13
+ end
14
+
15
+ def self.config
16
+ CONFIG_PATH
17
+ end
18
+
19
+ def self.context_file
20
+ CONTEXT_FILE_PATH
21
+ end
22
+ end
23
+ CONTEXT_PATH = File.expand_path("./../files/context.jsonl", __dir__)
24
+ FILE_PATH = File.expand_path("./../files/", __dir__)
25
+ CONFIG_PATH = File.expand_path("./../config/config.yml", __dir__)
26
+ CONTEXT_FILE_PATH = File.expand_path("./../files/context_file.txt", __dir__)
data/lib/prompt.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  require "openai"
2
+ require_relative './files.rb'
2
3
 
3
4
  class Prompt
4
-
5
+ include Files
5
6
  ## Streams the response, VERY NICE
6
7
  def self.stream_prompt(input, conversation = '', temp = 0.7)
7
8
  if conversation.length == 0
@@ -9,7 +10,6 @@ class Prompt
9
10
  else
10
11
  conversation += "\n My question: #{input}"
11
12
  end
12
-
13
13
  response = ''
14
14
  client.chat(
15
15
  parameters: {
@@ -26,6 +26,7 @@ class Prompt
26
26
  "input" => input,
27
27
  "response" => response,
28
28
  }
29
+
29
30
  return context
30
31
  end
31
32
 
@@ -39,15 +40,19 @@ class Prompt
39
40
  client.files.delete(id: "file-123")
40
41
  end
41
42
 
42
- def self.whisper_translate(file_path)
43
+ def self.whisper_translate(file_path, interactive = false)
43
44
  if (file_path.nil? || !file_path.end_with?(*['.mp3', '.wav', '.m4a', '.webm', '.mpeg', '.mpga']))
44
- puts "No file given or wrong file type"
45
- exit
45
+ Logging.log("No file given or wrong file type")
46
+ unless interactive
47
+ exit
48
+ end
46
49
  else
47
50
  size = File.size(file_path).to_f / 2**20
48
51
  if size > 24
49
52
  warning("The file is above the maximum size of 25MB")
50
- exit
53
+ unless interactive
54
+ exit
55
+ end
51
56
  else
52
57
  response = client.audio.translate(
53
58
  parameters: {
@@ -55,25 +60,31 @@ class Prompt
55
60
  file: File.open(file_path, "rb"),
56
61
  })
57
62
  if (response["text"].nil? || response["text"].empty?)
58
- puts "No text found"
59
- exit
63
+ Logging.log("No text found")
64
+ unless interactive
65
+ exit
66
+ end
60
67
  end
61
- puts response["text"]
68
+ return response["text"]
62
69
  end
63
70
  end
64
71
  rescue Errno::ENOENT => e
65
- puts "File not found"
72
+ Logging.log(e)
66
73
  end
67
74
 
68
- def self.whisper_transcribe(file_path)
75
+ def self.whisper_transcribe(file_path, interactive = false)
69
76
  if (file_path.nil? || !file_path.end_with?(*['.mp3', '.wav', '.m4a', '.webm', '.mpeg', '.mpga']))
70
- puts "No file given"
71
- exit
77
+ Logging.log("No file given")
78
+ unless interactive
79
+ exit
80
+ end
72
81
  else
73
82
  size = File.size(file_path).to_f / 2**20
74
83
  if size > 24
75
- warning("The file is above the maximum size of 25MB, this may take")
76
- exit
84
+ warning("The file is above the maximum size of 25MB")
85
+ unless interactive
86
+ exit
87
+ end
77
88
  else
78
89
  response = client.audio.transcribe(
79
90
  parameters: {
@@ -81,20 +92,23 @@ class Prompt
81
92
  file: File.open(file_path, "rb"),
82
93
  })
83
94
  if (response["text"].nil? || response["text"].empty?)
84
- puts "No text found"
85
- exit
95
+ Logging.log("No text found")
96
+ unless interactive
97
+ exit
98
+ end
86
99
  end
87
- puts response["text"]
100
+ return response["text"]
88
101
  end
89
102
  end
90
103
  rescue Errno::ENOENT => e
91
- puts "File not found"
104
+ #Logging.log("File not found")
105
+ Logging.log(e)
92
106
  end
93
107
 
94
108
  private
95
109
 
96
110
  def self.client()
97
- conf = YAML.load(File.read(CONFIG_PATH))
111
+ conf = YAML.load(File.read(Files.config_path))
98
112
  key = conf["OPENAI_API_KEY"]
99
113
 
100
114
  OpenAI::Client.new(access_token: key)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ask-ai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Oskar Franck
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-22 00:00:00.000000000 Z
11
+ date: 2023-10-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ruby-openai
@@ -28,21 +28,25 @@ description: A CLI tool for using OpenAI's API. The idea is to make it easy to u
28
28
  the API with an option to pass files for help with diffrent tasks.
29
29
  email: contact.oskarfranck.se
30
30
  executables:
31
- - aa
31
+ - ask-ai
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
- - bin/aa
35
+ - bin/ask-ai
36
36
  - config/config.yml
37
37
  - files/context.jsonl
38
38
  - files/context_file.txt
39
39
  - lib/context.rb
40
+ - lib/files.rb
40
41
  - lib/handle_args.rb
41
42
  - lib/help.rb
43
+ - lib/logging.rb
42
44
  - lib/main.rb
45
+ - lib/paths.rb
43
46
  - lib/prompt.rb
44
- homepage:
45
- licenses: []
47
+ homepage: https://github.com/OskarFranck/terminal_chat
48
+ licenses:
49
+ - MIT
46
50
  metadata: {}
47
51
  post_install_message:
48
52
  rdoc_options: []
@@ -59,7 +63,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
59
63
  - !ruby/object:Gem::Version
60
64
  version: '0'
61
65
  requirements: []
62
- rubygems_version: 3.3.7
66
+ rubygems_version: 3.2.33
63
67
  signing_key:
64
68
  specification_version: 4
65
69
  summary: A simple CLI for OpenAI's GPT-3 API.
/data/bin/{aa → ask-ai} RENAMED
File without changes