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 +4 -4
- data/config/config.yml +0 -1
- data/lib/context.rb +20 -17
- data/lib/files.rb +21 -0
- data/lib/handle_args.rb +4 -4
- data/lib/help.rb +21 -21
- data/lib/logging.rb +9 -0
- data/lib/main.rb +63 -51
- data/lib/paths.rb +26 -0
- data/lib/prompt.rb +34 -20
- metadata +11 -7
- /data/bin/{aa → ask-ai} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6e70b8ddfd0f1ba54b83d117957361a9def1f96d33ed08e943db73c827bfdccc
|
4
|
+
data.tar.gz: 9e2b01982e324a6891e6dd32b4feee37f98087d0c455650458443503bf1fb8bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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?(
|
4
|
-
conversation = File.readlines(
|
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?(
|
29
|
-
File.open(
|
31
|
+
unless File.exist?(Files.context_path)
|
32
|
+
File.open(Files.context_path, "w") {}
|
30
33
|
end
|
31
|
-
File.readlines(
|
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(
|
36
|
-
tmp_arr.each { |line| File.open(
|
37
|
-
File.open(
|
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
|
-
|
42
|
-
File.truncate(
|
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(
|
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
|
-
|
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
|
-
|
62
|
+
Logging.log("No file path given.")
|
60
63
|
end
|
61
64
|
rescue Errno::ENOENT
|
62
|
-
|
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(
|
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
|
-
|
75
|
-
|
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
|
-
#
|
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
|
-
#
|
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
|
-
|
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
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
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("
|
40
|
-
|
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
|
-
|
44
|
+
Logging.log("Usage: ./main.rb [options] [input]")
|
45
45
|
|
46
|
-
|
46
|
+
Logging.log("There are two types of options, flags and arguments.")
|
47
47
|
end
|
48
48
|
end
|
data/lib/logging.rb
ADDED
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
25
|
-
|
21
|
+
if config == false
|
22
|
+
Logging.log("No API key found.")
|
26
23
|
Help.display_api_key()
|
27
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
87
|
+
Logging.log(input)
|
94
88
|
Context.save_context(Prompt.stream_prompt(input, context))
|
95
89
|
when "-w", "--whisper"
|
96
|
-
|
90
|
+
Logging.log(Prompt.whisper_transcribe(input))
|
97
91
|
when "-t", "--translate"
|
98
|
-
|
92
|
+
Logging.log(Prompt.whisper_translate(input))
|
99
93
|
when "-i", "--interactive"
|
100
|
-
|
101
|
-
|
102
|
-
|
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
|
-
|
106
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
140
|
-
|
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
|
-
|
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
|
-
|
163
|
+
Logging.log("Saving API key...")
|
152
164
|
end
|
153
165
|
|
154
|
-
FileUtils.mkdir_p(File.dirname(
|
155
|
-
File.open(
|
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
|
-
|
170
|
+
Logging.log("API key saved.")
|
159
171
|
end
|
160
172
|
|
161
173
|
def self.load_env()
|
162
|
-
YAML.load(File.read(
|
174
|
+
YAML.load(File.read(Files.config_path))
|
163
175
|
|
164
176
|
rescue Errno::ENOENT
|
165
|
-
|
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
|
-
|
45
|
-
|
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
|
-
|
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
|
-
|
59
|
-
|
63
|
+
Logging.log("No text found")
|
64
|
+
unless interactive
|
65
|
+
exit
|
66
|
+
end
|
60
67
|
end
|
61
|
-
|
68
|
+
return response["text"]
|
62
69
|
end
|
63
70
|
end
|
64
71
|
rescue Errno::ENOENT => e
|
65
|
-
|
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
|
-
|
71
|
-
|
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
|
76
|
-
|
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
|
-
|
85
|
-
|
95
|
+
Logging.log("No text found")
|
96
|
+
unless interactive
|
97
|
+
exit
|
98
|
+
end
|
86
99
|
end
|
87
|
-
|
100
|
+
return response["text"]
|
88
101
|
end
|
89
102
|
end
|
90
103
|
rescue Errno::ENOENT => e
|
91
|
-
|
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(
|
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.
|
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-
|
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
|
-
-
|
31
|
+
- ask-ai
|
32
32
|
extensions: []
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
|
-
- bin/
|
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.
|
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
|