openai-please 0.1.2 → 0.1.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/.gitignore +1 -0
- data/.rubocop.yml +8 -1
- data/Gemfile.lock +1 -1
- data/docker-compose.yml +1 -0
- data/lib/please/cli.rb +27 -4
- data/lib/please/context.rb +59 -56
- data/lib/please/request.rb +2 -2
- data/lib/please/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: de7075efdfbec978dc13fa6621f80e9e146e81cffb9652b19c17577befb4258a
|
4
|
+
data.tar.gz: 22fcdec50244d7d02826e25a3f4fb7a5e542f151da749ab67d7d9a3de0e7d7cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7aa0a478868627ba84898ca812958f5c37a46bd0872fe4ddbba4d1c222d2700f0d887b0e7ba207683e3a4620e9a73c63e61d73f77e6bf76f8b422a9f54a2bbf6
|
7
|
+
data.tar.gz: 978bcfb2597c5b2f7c1157cedd755b6a058395c9d844472649524ddc9531d5f9a4fde7e6f7af5dd237ed4801274f3274d14753cfd6c25e65387ff16b38ee2250
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -19,8 +19,15 @@ Style/TrailingCommaInArguments:
|
|
19
19
|
Enabled: true
|
20
20
|
EnforcedStyleForMultiline: comma
|
21
21
|
|
22
|
+
Style/TrailingCommaInArrayLiteral:
|
23
|
+
Enabled: true
|
24
|
+
EnforcedStyleForMultiline: comma
|
25
|
+
|
22
26
|
Style/Documentation:
|
23
27
|
Enabled: false
|
24
28
|
|
29
|
+
Layout/MultilineMethodCallIndentation:
|
30
|
+
Enabled: false
|
31
|
+
|
25
32
|
Layout/LineLength:
|
26
|
-
|
33
|
+
Enabled: false
|
data/Gemfile.lock
CHANGED
data/docker-compose.yml
CHANGED
data/lib/please/cli.rb
CHANGED
@@ -2,10 +2,14 @@
|
|
2
2
|
|
3
3
|
require 'English'
|
4
4
|
require 'tty-prompt'
|
5
|
+
require 'yaml'
|
5
6
|
require 'optparse'
|
6
7
|
require 'please'
|
7
8
|
require 'tempfile'
|
8
9
|
|
10
|
+
USAGE = 'Usage: please [options] <instruction>'
|
11
|
+
CONFIG_FILE_PATH = File.expand_path('~/.config/please/config.yml')
|
12
|
+
|
9
13
|
begin
|
10
14
|
tty_prompt = TTY::Prompt.new
|
11
15
|
|
@@ -14,13 +18,27 @@ begin
|
|
14
18
|
send_pwd: true,
|
15
19
|
send_uname: true,
|
16
20
|
send_ls: true,
|
21
|
+
access_token: ENV.fetch('OPENAI_ACCESS_TOKEN', nil),
|
22
|
+
examples: [],
|
23
|
+
skip_default_examples: false,
|
17
24
|
}
|
18
25
|
|
19
|
-
|
26
|
+
if File.exist?(CONFIG_FILE_PATH)
|
27
|
+
begin
|
28
|
+
options.merge! YAML.load_file(CONFIG_FILE_PATH).transform_keys(&:to_sym)
|
29
|
+
options[:examples].each { |example| example.transform_keys!(&:to_sym) }
|
30
|
+
rescue StandardError
|
31
|
+
tty_prompt.warn 'Could not parse config file. Ignoring.'
|
32
|
+
end
|
33
|
+
end
|
20
34
|
|
21
35
|
OptionParser.new do |opts|
|
22
36
|
opts.banner = USAGE
|
23
37
|
|
38
|
+
opts.on('--show-config-path', 'Output the location of the config file, and then exit') do |v|
|
39
|
+
options[:show_config_path] = v
|
40
|
+
end
|
41
|
+
|
24
42
|
opts.on('--show-prompt', 'Output the prompt that would ordinarily be sent to OpenAI Codex, and then exit') do |v|
|
25
43
|
options[:show_prompt] = v
|
26
44
|
end
|
@@ -38,12 +56,17 @@ begin
|
|
38
56
|
end
|
39
57
|
end.parse!
|
40
58
|
|
41
|
-
|
42
|
-
tty_prompt.
|
59
|
+
if options[:show_config_path]
|
60
|
+
tty_prompt.say CONFIG_FILE_PATH
|
61
|
+
exit
|
62
|
+
end
|
63
|
+
|
64
|
+
if options[:access_token].nil?
|
65
|
+
tty_prompt.error "Access token not found. Set it in #{CONFIG_FILE_PATH} or $OPENAI_ACCESS_TOKEN."
|
43
66
|
exit 1
|
44
67
|
end
|
45
68
|
|
46
|
-
codex_service = Please::OpenAI::CodexService.new(access_token: access_token)
|
69
|
+
codex_service = Please::OpenAI::CodexService.new(access_token: options[:access_token])
|
47
70
|
|
48
71
|
instruction = ARGV.join(' ')
|
49
72
|
|
data/lib/please/context.rb
CHANGED
@@ -1,30 +1,69 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
DEFAULT_EXAMPLES = [
|
4
|
+
{
|
5
|
+
instruction: 'Find all files older than 1 week and open each of them in vim',
|
6
|
+
command: 'find . -type f -mtime +7 -exec vim {} \;',
|
7
|
+
},
|
8
|
+
|
9
|
+
{
|
10
|
+
instruction: 'Show a clock which updates every second on a single line',
|
11
|
+
command: 'printf \'import time\nwhile True:\n\tprint(time.strftime("%%H:%%M:%%S"), end="\\\\r")\n\ttime.sleep(1)\' > /tmp/program.py; python3 /tmp/program.py; rm /tmp/program.py',
|
12
|
+
},
|
13
|
+
|
14
|
+
{
|
15
|
+
instruction: 'Write a python program that prints out hello world with each letter on its own line',
|
16
|
+
command: 'printf \'print("\\\\n".join(list("Hello World"))\' > /tmp/program.py; python3 /tmp/program.py; rm /tmp/program.py',
|
17
|
+
},
|
18
|
+
|
19
|
+
{
|
20
|
+
instruction: 'Read from stdin until EOF, and then output the length of the string',
|
21
|
+
command: 'printf \'import sys\nprint(len(sys.stdin.read().strip()))\' > /tmp/program.py; python3 /tmp/program.py; rm /tmp/program.py',
|
22
|
+
},
|
23
|
+
|
24
|
+
{
|
25
|
+
instruction: 'Run the fortune command 5 times',
|
26
|
+
command: 'for i in $(seq 5); do fortune; done',
|
27
|
+
},
|
28
|
+
|
29
|
+
{
|
30
|
+
instruction: 'Repeadedly read a single line from the user, reverse it, and print it back',
|
31
|
+
command: 'printf \'while True:\n\tline = input()\n\tprint(line[::-1])\' > /tmp/program.py; python3 /tmp/program.py; rm /tmp/program.py',
|
32
|
+
},
|
33
|
+
].freeze
|
34
|
+
|
35
|
+
OPTIONAL_EXAMPLES = {
|
36
|
+
pwd: {
|
37
|
+
instruction: 'Print the current working directory',
|
38
|
+
command: 'pwd',
|
39
|
+
execute: true,
|
40
|
+
},
|
41
|
+
|
42
|
+
uname: {
|
43
|
+
instruction: 'Show information about the operating system',
|
44
|
+
command: 'uname -a',
|
45
|
+
execute: true,
|
46
|
+
},
|
47
|
+
|
48
|
+
ls: {
|
49
|
+
instruction: 'List all files in the current directory',
|
50
|
+
command: 'ls -a',
|
51
|
+
execute: true,
|
52
|
+
},
|
53
|
+
}.freeze
|
54
|
+
|
3
55
|
module Please
|
4
56
|
class Context
|
5
57
|
def initialize(options)
|
6
|
-
@examples =
|
58
|
+
@examples = []
|
7
59
|
|
8
|
-
|
9
|
-
@examples << {
|
10
|
-
instruction: 'Print the current working directory',
|
11
|
-
command: 'pwd',
|
12
|
-
}
|
13
|
-
end
|
60
|
+
@examples += DEFAULT_EXAMPLES unless options[:skip_default_examples]
|
14
61
|
|
15
|
-
if options[:
|
16
|
-
|
17
|
-
|
18
|
-
command: 'uname -a',
|
19
|
-
}
|
20
|
-
end
|
62
|
+
@examples << OPTIONAL_EXAMPLES[:pwd] if options[:send_pwd]
|
63
|
+
@examples << OPTIONAL_EXAMPLES[:uname] if options[:send_uname]
|
64
|
+
@examples << OPTIONAL_EXAMPLES[:ls] if options[:send_ls]
|
21
65
|
|
22
|
-
|
23
|
-
@examples << {
|
24
|
-
instruction: 'List all files in the current directory',
|
25
|
-
command: 'ls -a',
|
26
|
-
}
|
27
|
-
end
|
66
|
+
@examples += options[:examples]
|
28
67
|
end
|
29
68
|
|
30
69
|
def to_s
|
@@ -32,45 +71,9 @@ module Please
|
|
32
71
|
<<~EXAMPLE.chomp
|
33
72
|
# #{example[:instruction]}
|
34
73
|
$ #{example[:command]}
|
35
|
-
#{example
|
74
|
+
#{example[:execute] ? `#{example[:command]}` : ""}
|
36
75
|
EXAMPLE
|
37
76
|
end.join("\n")
|
38
77
|
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def default_examples
|
43
|
-
[
|
44
|
-
{
|
45
|
-
instruction: 'Find all files older than 1 week and open each of them in vim',
|
46
|
-
command: 'find . -type f -mtime +7 -exec vim {} \;',
|
47
|
-
result: '',
|
48
|
-
},
|
49
|
-
|
50
|
-
{
|
51
|
-
instruction: 'Download a random dog picture',
|
52
|
-
command: 'printf \'import urllib.request\nimport json\nimport subprocess\ndata = urllib.request.urlopen("https://dog.ceo/api/breeds/image/random").read()\nurl = json.loads(data)["message"]\nsubprocess.call(["curl", url, "-o", "dog.jpg"])\' > /tmp/program.py; python3 /tmp/program.py; rm /tmp/program.py',
|
53
|
-
result: '',
|
54
|
-
},
|
55
|
-
|
56
|
-
{
|
57
|
-
instruction: 'Read from stdin until EOF, and then output the length of the string',
|
58
|
-
command: 'printf \'import sys\nprint(len(sys.stdin.read().strip()))\' > /tmp/program.py; python3 /tmp/program.py; rm /tmp/program.py',
|
59
|
-
result: '',
|
60
|
-
},
|
61
|
-
|
62
|
-
{
|
63
|
-
instruction: 'Run the fortune command 5 times',
|
64
|
-
command: 'for i in $(seq 5); do fortune; done',
|
65
|
-
result: '',
|
66
|
-
},
|
67
|
-
|
68
|
-
{
|
69
|
-
instruction: 'Repeadedly read a single line from the user, reverse it, and print it back',
|
70
|
-
command: 'printf \'while True:\n\tline = input()\n\tprint(line[::-1])\' > /tmp/program.py; python3 /tmp/program.py; rm /tmp/program.py',
|
71
|
-
result: '',
|
72
|
-
},
|
73
|
-
]
|
74
|
-
end
|
75
78
|
end
|
76
79
|
end
|
data/lib/please/request.rb
CHANGED
@@ -8,7 +8,7 @@ module Please
|
|
8
8
|
# Collapse multiline commands into one line
|
9
9
|
.gsub(/\s*\\\n\s*/, ' ')
|
10
10
|
# Remove subsequent lines that do not contain commands
|
11
|
-
.gsub(/\n[
|
11
|
+
.gsub(/\n[^$][^\n]*$/, '')
|
12
12
|
# Collapse multiple commands into one line
|
13
13
|
.gsub(/\n\$ /, '; ')
|
14
14
|
# Remove multiple consecutive spaces
|
@@ -19,7 +19,7 @@ module Please
|
|
19
19
|
<<~PROMPT.chomp
|
20
20
|
Write a one-line bash command for each of the following tasks.
|
21
21
|
|
22
|
-
#{context
|
22
|
+
#{context}
|
23
23
|
|
24
24
|
# #{instruction.gsub(/\n/, " ")}
|
25
25
|
$
|
data/lib/please/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openai-please
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joe Anderson
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-09-
|
11
|
+
date: 2021-09-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: ruby-openai
|